예제 #1
0
        private void DrawItemList(List <GenericItem> itemList, Vector2 listSize, ref bool isOpen)
        {
            var fontPushed   = false;
            var stylesPushed = 0;
            var colorsPushed = 0;

            try {
                if (itemList.Count != lastItemCount)
                {
                    lastItemCount = itemList.Count;
                    ImGui.SetScrollY(0);
                }

                var   itemSize   = Vector2.Zero;
                float cursorPosY = 0;
                var   scrollY    = ImGui.GetScrollY();
                var   style      = ImGui.GetStyle();
                var   j          = 0;

                var rowSize = Vector2.Zero;

                for (var i = 0; i < itemList.Count; i++)
                {
                    if (i == 0 && itemSize == Vector2.Zero)
                    {
                        itemSize = ImGui.CalcTextSize(itemList[i].Name);
                        rowSize  = new Vector2(ImGui.GetWindowContentRegionWidth() - 20 * ImGui.GetIO().FontGlobalScale, itemSize.Y);
                        if (!doSearchScroll)
                        {
                            var sizePerItem = itemSize.Y + style.ItemSpacing.Y;
                            var skipItems   = (int)Math.Floor(scrollY / sizePerItem);
                            cursorPosY = skipItems * sizePerItem;
                            ImGui.SetCursorPosY(5 + cursorPosY + style.ItemSpacing.X);
                            i = skipItems;
                        }
                    }

                    if (!(doSearchScroll && selectedItemIndex == i) && (cursorPosY < scrollY - itemSize.Y || cursorPosY > scrollY + listSize.Y))
                    {
                        ImGui.SetCursorPosY(cursorPosY + itemSize.Y + style.ItemSpacing.Y);
                    }
                    else
                    {
                        ImGui.PushFont(UiBuilder.IconFont);
                        fontPushed = true;

                        var starText        = $"{(char)FontAwesomeIcon.Heart}";
                        var starTextSize    = ImGui.CalcTextSize(starText);
                        var starTextHovered = ImGui.IsMouseHoveringRect(ImGui.GetCursorScreenPos(), ImGui.GetCursorScreenPos() + starTextSize);

                        uint starTextCol = pluginConfig.Favorites.Contains(itemList[i].RowId) ? 0xCC0000AA : 0U;;

                        if (starTextHovered)
                        {
                            starTextCol = pluginConfig.Favorites.Contains(itemList[i].RowId) ? 0xAA777777 : 0xAA0000AAU;
                            ImGui.SetMouseCursor(ImGuiMouseCursor.Hand);
                        }

                        ImGui.PushStyleColor(ImGuiCol.Text, starTextCol); colorsPushed++;

                        ImGui.Text(starText);
                        if (ImGui.IsItemClicked())
                        {
                            if (pluginConfig.Favorites.Contains(itemList[i].RowId))
                            {
                                pluginConfig.Favorites.Remove(itemList[i].RowId);
                            }
                            else
                            {
                                pluginConfig.Favorites.Add(itemList[i].RowId);
                            }
                            pluginConfig.Save();
                        }

                        ImGui.PopStyleColor(); colorsPushed--;

                        ImGui.PopFont();
                        fontPushed = false;
                        ImGui.SameLine();

                        var hovered = ImGui.IsMouseHoveringRect(ImGui.GetCursorScreenPos(), ImGui.GetCursorScreenPos() + rowSize);
                        var bgCol   = selectedItem == itemList[i] ? (hovered ? 0x88888888 : 0x88444444) : (hovered ? 0x66666666 : 0U);
                        ImGui.PushStyleColor(ImGuiCol.ChildBg, bgCol); colorsPushed++;
                        ImGui.PushStyleVar(ImGuiStyleVar.WindowPadding, Vector2.Zero); stylesPushed++;
                        ImGui.BeginGroup();
                        ImGui.BeginChild($"###ItemContainer{j++}", rowSize, false);


                        ImGui.Text($" {itemList[i].Name}");
                        if (itemList[i].GenericItemType == GenericItem.ItemType.EventItem)
                        {
                            ImGui.SameLine();
                            ImGui.TextDisabled(" [Key Item]");
                        }
                        var textClick = ImGui.IsItemClicked();
                        ImGui.EndChild();
                        var childClicked = ImGui.IsItemClicked();
                        ImGui.EndGroup();
                        var groupHovered = ImGui.IsItemHovered();
                        var groupClicked = ImGui.IsItemClicked();
                        ImGui.PopStyleColor(); colorsPushed--;


                        if (textClick || childClicked || groupClicked)
                        {
                            this.selectedItem      = itemList[i];
                            this.selectedItemIndex = i;

                            if (ImGui.IsMouseDoubleClicked(ImGuiMouseButton.Left))
                            {
                                if (this.selectedItem != null && selectedItem.Icon < 65000)
                                {
                                    try {
                                        plugin.LinkItem(selectedItem);
                                        if (pluginConfig.CloseOnChoose)
                                        {
                                            isOpen = false;
                                        }
                                    } catch (Exception ex) {
                                        PluginLog.LogError(ex.ToString());
                                    }
                                }
                            }

                            if (selectedItem.GenericItemType == GenericItem.ItemType.Item)
                            {
                                if ((autoTryOn = autoTryOn && pluginConfig.ShowTryOn) && plugin.FittingRoomUI.CanUseTryOn && pluginInterface.ClientState.LocalContentId != 0)
                                {
                                    if (selectedItem.ClassJobCategory.Row != 0)
                                    {
                                        plugin.FittingRoomUI.TryOnItem((Item)selectedItem, selectedStain?.RowId ?? 0);
                                    }
                                }
                            }
                        }

                        ImGui.PopStyleVar(); stylesPushed--;
                    }



                    if (doSearchScroll && selectedItemIndex == i)
                    {
                        doSearchScroll = false;
                        ImGui.SetScrollHereY(0.5f);
                    }

                    cursorPosY = ImGui.GetCursorPosY();

                    if (cursorPosY > scrollY + listSize.Y && !doSearchScroll)
                    {
                        var c = itemList.Count - i;
                        ImGui.BeginChild("###scrollFillerBottom", new Vector2(0, c * (itemSize.Y + style.ItemSpacing.Y)), false);
                        ImGui.EndChild();
                        break;
                    }
                }

                var keyStateDown = ImGui.GetIO().KeysDown[0x28] || pluginInterface.ClientState.KeyState[0x28];
                var keyStateUp   = ImGui.GetIO().KeysDown[0x26] || pluginInterface.ClientState.KeyState[0x26];

#if DEBUG
                // Random up/down if both are pressed
                if (keyStateUp && keyStateDown)
                {
                    debounceKeyPress = 0;

                    var r = new Random().Next(0, 5);

                    switch (r)
                    {
                    case 1:
                        keyStateUp   = true;
                        keyStateDown = false;
                        break;

                    case 0:
                        keyStateUp   = false;
                        keyStateDown = false;
                        break;

                    default:
                        keyStateUp   = false;
                        keyStateDown = true;
                        break;
                    }
                }
#endif

                var hotkeyUsed = false;
                if (keyStateUp && !keyStateDown)
                {
                    if (debounceKeyPress == 0)
                    {
                        debounceKeyPress = 5;
                        if (selectedItemIndex > 0)
                        {
                            hotkeyUsed         = true;
                            selectedItemIndex -= 1;
                        }
                    }
                }
                else if (keyStateDown && !keyStateUp)
                {
                    if (debounceKeyPress == 0)
                    {
                        debounceKeyPress = 5;
                        if (selectedItemIndex < itemList.Count - 1)
                        {
                            selectedItemIndex += 1;
                            hotkeyUsed         = true;
                        }
                    }
                }
                else if (debounceKeyPress > 0)
                {
                    debounceKeyPress -= 1;
                    if (debounceKeyPress < 0)
                    {
                        debounceKeyPress = 5;
                    }
                }

                if (hotkeyUsed)
                {
                    doSearchScroll    = true;
                    this.selectedItem = itemList[selectedItemIndex];
                    if (selectedItem.GenericItemType == GenericItem.ItemType.Item)
                    {
                        if ((autoTryOn = autoTryOn && pluginConfig.ShowTryOn) && plugin.FittingRoomUI.CanUseTryOn && pluginInterface.ClientState.LocalContentId != 0)
                        {
                            if (selectedItem.ClassJobCategory.Row != 0)
                            {
                                plugin.FittingRoomUI.TryOnItem((Item)selectedItem, selectedStain?.RowId ?? 0);
                            }
                        }
                    }
                }
            } catch (Exception ex) {
                PluginLog.LogError($"{ex}");
                ImGui.SetScrollY(0);
            }

            if (fontPushed)
            {
                ImGui.PopFont();
            }
            if (colorsPushed > 0)
            {
                ImGui.PopStyleColor(colorsPushed);
            }
            if (stylesPushed > 0)
            {
                ImGui.PopStyleColor(stylesPushed);
            }
        }
예제 #2
0
        public bool Draw()
        {
            var isOpen = true;

            try {
                var isSearch = false;
                if (triedLoadingItems == false || pluginConfig.SelectedClientLanguage != plugin.LuminaItemsClientLanguage)
                {
                    UpdateItemList(1000);
                }

                if ((selectedItemIndex < 0 && selectedItem != null) || (selectedItemIndex >= 0 && selectedItem == null))
                {
                    // Should never happen, but just incase
                    selectedItemIndex = -1;
                    selectedItem      = null;
                    return(true);
                }

                ImGui.SetNextWindowSize(new Vector2(500, 500), ImGuiCond.FirstUseEver);

                PushStyle(ImGuiStyleVar.WindowMinSize, new Vector2(350, 400));

                if (!ImGui.Begin(Loc.Localize("ItemSearchPlguinMainWindowHeader", $"Item Search") + "###itemSearchPluginMainWindow", ref isOpen, ImGuiWindowFlags.NoCollapse))
                {
                    ResetStyle();
                    ImGui.End();
                    return(false);
                }

                if (ImGui.IsWindowAppearing())
                {
                    SearchFilters.ForEach(f => f._ForceVisible = false);
                }

                PopStyle();

                // Main window
                ImGui.AlignTextToFramePadding();

                if (selectedItem != null)
                {
                    var icon = selectedItem.Icon;

                    plugin.DrawIcon(icon, new Vector2(45 * ImGui.GetIO().FontGlobalScale));


                    ImGui.SameLine();
                    ImGui.BeginGroup();

                    if (selectedItem.GenericItemType == GenericItem.ItemType.EventItem)
                    {
                        ImGui.TextDisabled("[Key Item]");
                        ImGui.SameLine();
                    }

                    ImGui.Text(selectedItem.Name);

                    if (pluginConfig.ShowItemID)
                    {
                        ImGui.SameLine();
                        ImGui.Text($"(ID: {selectedItem.RowId}) (Rarity: {selectedItem.Rarity})");
                    }

                    var imGuiStyle    = ImGui.GetStyle();
                    var windowVisible = ImGui.GetWindowPos().X + ImGui.GetWindowContentRegionMax().X;

                    IActionButton[] buttons = this.ActionButtons.Where(ab => ab.ButtonPosition == ActionButtonPosition.TOP).ToArray();

                    for (var i = 0; i < buttons.Length; i++)
                    {
                        var button = buttons[i];

                        if (button.GetShowButton(selectedItem))
                        {
                            var buttonText = button.GetButtonText(selectedItem);
                            ImGui.PushID($"TopActionButton{i}");
                            if (ImGui.Button(buttonText))
                            {
                                button.OnButtonClicked(selectedItem);
                            }

                            if (i < buttons.Length - 1)
                            {
                                var lX2 = ImGui.GetItemRectMax().X;
                                var nbw = ImGui.CalcTextSize(buttons[i + 1].GetButtonText(selectedItem)).X + imGuiStyle.ItemInnerSpacing.X * 2;
                                var nX2 = lX2 + (imGuiStyle.ItemSpacing.X * 2) + nbw;
                                if (nX2 < windowVisible)
                                {
                                    ImGui.SameLine();
                                }
                            }

                            ImGui.PopID();
                        }
                    }

                    ImGui.EndGroup();
                }
                else
                {
                    ImGui.BeginChild("NoSelectedItemBox", new Vector2(-1, 45) * ImGui.GetIO().FontGlobalScale);
                    ImGui.Text(Loc.Localize("ItemSearchSelectItem", "Please select an item."));


                    if (!pluginConfig.HideKofi)
                    {
                        ImGui.PushStyleColor(ImGuiCol.Button, 0xFF5E5BFF);
                        ImGui.PushStyleColor(ImGuiCol.ButtonActive, 0xFF5E5BAA);
                        ImGui.PushStyleColor(ImGuiCol.ButtonHovered, 0xFF5E5BDD);
                        ImGui.SameLine(ImGui.GetWindowWidth() - ImGui.CalcTextSize("Support on Ko-fi").X - ImGui.GetStyle().FramePadding.X * 3);
                        if (ImGui.Button("Support on Ko-Fi"))
                        {
                            Process.Start("https://ko-fi.com/Caraxi");
                        }
                        ImGui.PopStyleColor(3);
                    }

                    ImGui.EndChild();
                }

                ImGui.Separator();

                ImGui.Columns(2);
                var filterNameMax = SearchFilters.Where(x => x.IsEnabled && x.ShowFilter).Select(x => {
                    x._LocalizedName      = Loc.Localize(x.NameLocalizationKey, x.Name);
                    x._LocalizedNameWidth = ImGui.CalcTextSize($"{x._LocalizedName}").X;
                    return(x._LocalizedNameWidth);
                }).Max();

                ImGui.SetColumnWidth(0, filterNameMax + ImGui.GetStyle().ItemSpacing.X * 2);
                var filterInUseColour    = new Vector4(0, 1, 0, 1);
                var filterUsingTagColour = new Vector4(0.4f, 0.7f, 1, 1);

                foreach (var filter in SearchFilters.Where(x => x.IsEnabled && x.ShowFilter))
                {
                    if (!extraFiltersExpanded && filter.CanBeDisabled && !filter.IsSet && !filter._ForceVisible)
                    {
                        continue;
                    }
                    ImGui.SetCursorPosX((filterNameMax + ImGui.GetStyle().ItemSpacing.X) - filter._LocalizedNameWidth);
                    ImGui.SetCursorPosY(ImGui.GetCursorPosY() + 3);
                    if (filter.IsSet)
                    {
                        ImGui.TextColored(filter.IsFromTag ? filterUsingTagColour : filterInUseColour, $"{filter._LocalizedName}: ");
                    }
                    else
                    {
                        ImGui.Text($"{filter._LocalizedName}: ");
                    }

                    ImGui.NextColumn();
                    ImGui.BeginGroup();
                    if (filter.IsFromTag && filter.GreyWithTags)
                    {
                        ImGui.PushStyleColor(ImGuiCol.Text, 0xFF888888);
                    }
                    filter.DrawEditor();
                    if (filter.IsFromTag && filter.GreyWithTags)
                    {
                        ImGui.PopStyleColor();
                    }
                    ImGui.EndGroup();
                    while (ImGui.GetColumnIndex() != 0)
                    {
                        ImGui.NextColumn();
                    }
                }
                ImGui.Columns(1);

                ImGui.PushFont(UiBuilder.IconFont);
                ImGui.PushStyleVar(ImGuiStyleVar.FramePadding, new Vector2(0, -5 * ImGui.GetIO().FontGlobalScale));
                ImGui.PushStyleVar(ImGuiStyleVar.WindowPadding, Vector2.Zero);
                if (ImGui.Button($"{(extraFiltersExpanded ? (char) FontAwesomeIcon.CaretUp : (char) FontAwesomeIcon.CaretDown)}", new Vector2(-1, 10 * ImGui.GetIO().FontGlobalScale)))
                {
                    extraFiltersExpanded = !extraFiltersExpanded;
                    SearchFilters.ForEach(f => f._ForceVisible = f.IsEnabled && f.ShowFilter && f.IsSet);
                    pluginConfig.ExpandedFilters = extraFiltersExpanded;
                    pluginConfig.Save();
                }
                ImGui.PopStyleVar(2);
                ImGui.PopFont();

                var windowSize = ImGui.GetWindowSize();
                var childSize  = new Vector2(0, Math.Max(100 * ImGui.GetIO().FontGlobalScale, windowSize.Y - ImGui.GetCursorPosY() - 45 * ImGui.GetIO().FontGlobalScale));
                ImGui.BeginChild("scrolling", childSize, true, ImGuiWindowFlags.HorizontalScrollbar);

                PushStyle(ImGuiStyleVar.ItemSpacing, new Vector2(0, 0));

                if (errorLoadingItems)
                {
                    ImGui.TextColored(new Vector4(1f, 0.1f, 0.1f, 1.00f), Loc.Localize("ItemSearchListLoadFailed", "Error loading item list."));
                    if (ImGui.SmallButton("Retry"))
                    {
                        UpdateItemList();
                    }
                }
                else if (plugin.LuminaItems != null)
                {
                    if (SearchFilters.Any(x => x.IsEnabled && x.ShowFilter && x.IsSet))
                    {
                        showingFavourites = false;
                        isSearch          = true;
                        var scrollTop = false;
                        if (SearchFilters.Any(x => x.IsEnabled && x.ShowFilter && x.HasChanged) || forceReload)
                        {
                            forceReload = false;
                            this.searchCancelTokenSource?.Cancel();
                            this.searchCancelTokenSource = new CancellationTokenSource();
                            var asyncEnum = plugin.LuminaItems.ToAsyncEnumerable();

                            if (!pluginConfig.ShowLegacyItems)
                            {
                                asyncEnum = asyncEnum.Where(x => x.RowId < 100 || x.RowId > 1600);
                            }

                            asyncEnum = SearchFilters.Where(filter => filter.IsEnabled && filter.ShowFilter && filter.IsSet).Aggregate(asyncEnum, (current, filter) => current.Where(filter.CheckFilter));
                            this.selectedItemIndex = -1;
                            selectedItem           = null;
                            this.searchTask        = asyncEnum.ToListAsync(this.searchCancelTokenSource.Token);
                        }

                        if (this.searchTask.IsCompletedSuccessfully)
                        {
                            DrawItemList(this.searchTask.Result, childSize, ref isOpen);
                        }
                    }
                    else
                    {
                        if (pluginConfig.Favorites.Count > 0)
                        {
                            if (!showingFavourites || favouritesList.Count != pluginConfig.Favorites.Count)
                            {
                                showingFavourites      = true;
                                this.selectedItemIndex = -1;
                                selectedItem           = null;
                                favouritesList         = plugin.LuminaItems.Where(i => pluginConfig.Favorites.Contains(i.RowId)).ToList();
                            }

                            DrawItemList(favouritesList, childSize, ref isOpen);
                        }
                        else
                        {
                            ImGui.TextColored(new Vector4(0.86f, 0.86f, 0.86f, 1.00f), Loc.Localize("DalamudItemSelectHint", "Type to start searching..."));
                        }
                    }
                }
                else
                {
                    ImGui.TextColored(new Vector4(0.86f, 0.86f, 0.86f, 1.00f), Loc.Localize("DalamudItemSelectLoading", "Loading item list..."));
                }

                PopStyle();

                ImGui.EndChild();

                // Darken choose button if it shouldn't be clickable
                PushStyle(ImGuiStyleVar.Alpha, this.selectedItemIndex < 0 || selectedItem == null || selectedItem.Icon >= 65000 ? 0.25f : 1);

                if (ImGui.Button(Loc.Localize("Choose", "Choose")))
                {
                    try {
                        if (selectedItem != null && selectedItem.Icon < 65000)
                        {
                            plugin.LinkItem(selectedItem);
                            if (pluginConfig.CloseOnChoose)
                            {
                                isOpen = false;
                            }
                        }
                    } catch (Exception ex) {
                        Log.Error($"Exception in Choose: {ex.Message}");
                    }
                }

                PopStyle();

                if (!pluginConfig.CloseOnChoose)
                {
                    ImGui.SameLine();
                    if (ImGui.Button(Loc.Localize("Close", "Close")))
                    {
                        selectedItem = null;
                        isOpen       = false;
                    }
                }

                if (this.selectedItemIndex >= 0 && this.selectedItem != null && selectedItem.Icon >= 65000)
                {
                    ImGui.SameLine();
                    ImGui.Text(Loc.Localize("DalamudItemNotLinkable", "This item is not linkable."));
                }

                if (pluginConfig.ShowTryOn && pluginInterface.ClientState?.LocalContentId != 0)
                {
                    ImGui.SameLine();
                    if (ImGui.Checkbox(Loc.Localize("ItemSearchTryOnButton", "Try On"), ref autoTryOn))
                    {
                        pluginConfig.TryOnEnabled = autoTryOn;
                        pluginConfig.Save();
                    }

                    ImGui.SameLine();


                    ImGui.PushStyleColor(ImGuiCol.Border, selectedStain != null && selectedStain.Unknown4 ? new Vector4(1, 1, 0, 1) : new Vector4(1, 1, 1, 1));
                    PushStyle(ImGuiStyleVar.FrameBorderSize, 2f);
                    if (ImGui.ColorButton("X", selectedStainColor, ImGuiColorEditFlags.NoTooltip))
                    {
                        showStainSelector = true;
                    }

                    if (ImGui.IsItemClicked(1))
                    {
                        selectedStainColor         = Vector4.Zero;
                        selectedStain              = null;
                        pluginConfig.SelectedStain = 0;
                        pluginConfig.Save();
                    }

                    PopStyle();

                    ImGui.PopStyleColor();

                    if (ImGui.IsItemHovered())
                    {
                        ImGui.SetMouseCursor(ImGuiMouseCursor.Hand);
                        ImGui.BeginTooltip();
                        ImGui.Text(selectedStain == null ? "No Dye Selected" : selectedStain.Name);
                        if (selectedStain != null)
                        {
                            ImGui.TextDisabled("Right click to clear selection.");
                        }
                        ImGui.EndTooltip();
                    }
                }
                ImGui.PushFont(UiBuilder.IconFont);
                var configText     = $"{(char)FontAwesomeIcon.Cog}";
                var configTextSize = ImGui.CalcTextSize(configText);
                ImGui.PopFont();
                var itemCountText = isSearch ? string.Format(Loc.Localize("ItemCount", "{0} Items"), this.searchTask.Result.Count) : $"v{plugin.Version}";
                ImGui.SameLine(ImGui.GetWindowWidth() - (configTextSize.X + ImGui.GetStyle().ItemSpacing.X) - (ImGui.CalcTextSize(itemCountText).X + ImGui.GetStyle().ItemSpacing.X *(isSearch ? 3 : 2)));
                if (isSearch)
                {
                    if (ImGui.Button(itemCountText))
                    {
                        PluginLog.Log("Copying results to Clipboard");

                        var sb = new StringBuilder();

                        if (pluginConfig.PrependFilterListWithCopy)
                        {
                            foreach (var f in SearchFilters.Where(f => f.IsSet))
                            {
                                sb.AppendLine($"{f.Name}: {f}");
                            }

                            sb.AppendLine();
                        }

                        foreach (var i in this.searchTask.Result)
                        {
                            sb.AppendLine(i.Name);
                        }
                        ImGui.SetClipboardText(sb.ToString());
                    }

                    if (ImGui.IsItemHovered())
                    {
                        ImGui.SetTooltip("Copy results to clipboard");
                    }
                }
                else
                {
                    ImGui.Text(itemCountText);
                }

                ImGui.SameLine(ImGui.GetWindowWidth() - (configTextSize.X + ImGui.GetStyle().ItemSpacing.X * 2));
                ImGui.PushFont(UiBuilder.IconFont);
                if (ImGui.Button(configText))
                {
                    plugin.ToggleConfigWindow();
                }
                ImGui.PopFont();

                var mainWindowPos  = ImGui.GetWindowPos();
                var mainWindowSize = ImGui.GetWindowSize();

                ImGui.End();


                if (showStainSelector)
                {
                    ImGui.SetNextWindowSize(new Vector2(210, 180));
                    ImGui.SetNextWindowPos(mainWindowPos + mainWindowSize - new Vector2(0, 180));
                    ImGui.Begin("Select Dye", ref showStainSelector, ImGuiWindowFlags.NoCollapse | ImGuiWindowFlags.NoResize | ImGuiWindowFlags.NoMove);

                    ImGui.BeginTabBar("stainShadeTabs");

                    var unselectedModifier = new Vector4(0, 0, 0, 0.7f);

                    foreach (var shade in stainShadeHeaders)
                    {
                        ImGui.PushStyleColor(ImGuiCol.TabActive, shade.Value);
                        ImGui.PushStyleColor(ImGuiCol.TabHovered, shade.Value);
                        ImGui.PushStyleColor(ImGuiCol.TabUnfocused, shade.Value);
                        ImGui.PushStyleColor(ImGuiCol.TabUnfocusedActive, shade.Value);
                        ImGui.PushStyleColor(ImGuiCol.Tab, shade.Value - unselectedModifier);

                        if (ImGui.BeginTabItem($"    ###StainShade{shade.Key}"))
                        {
                            var c = 0;

                            PushStyle(ImGuiStyleVar.FrameBorderSize, 2f);
                            foreach (var stain in stains.Where(s => s.Shade == shade.Key && !string.IsNullOrEmpty(s.Name)))
                            {
                                var b = stain.Color & 255;
                                var g = (stain.Color >> 8) & 255;
                                var r = (stain.Color >> 16) & 255;

                                var stainColor = new Vector4(r / 255f, g / 255f, b / 255f, 1f);

                                ImGui.PushStyleColor(ImGuiCol.Border, stain.Unknown4 ? new Vector4(1, 1, 0, 1) : new Vector4(1, 1, 1, 1));

                                if (ImGui.ColorButton($"###stain{stain.RowId}", stainColor, ImGuiColorEditFlags.NoTooltip))
                                {
                                    selectedStain              = stain;
                                    selectedStainColor         = stainColor;
                                    showStainSelector          = false;
                                    pluginConfig.SelectedStain = stain.RowId;
                                    pluginConfig.Save();
                                }

                                ImGui.PopStyleColor(1);

                                if (ImGui.IsItemHovered())
                                {
                                    ImGui.SetMouseCursor(ImGuiMouseCursor.Hand);
                                    ImGui.SetTooltip(stain.Name);
                                }

                                if (c++ < 5)
                                {
                                    ImGui.SameLine();
                                }
                                else
                                {
                                    c = 0;
                                }
                            }

                            PopStyle(1);

                            ImGui.EndTabItem();
                        }

                        ImGui.PopStyleColor(5);
                    }

                    ImGui.EndTabBar();
                    ImGui.End();
                }


                return(isOpen);
            } catch (Exception ex) {
                ResetStyle();
                PluginLog.LogError(ex.ToString());
                selectedItem      = null;
                selectedItemIndex = -1;
                return(isOpen);
            }
        }