123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252 |
- #include "GuiUtils.h"
- void HelpMarker(const char* description) {
- ImGui::TextDisabled("(?)");
- if (ImGui::IsItemHovered(ImGuiHoveredFlags_DelayShort)) {
- ImGui::BeginTooltip();
- ImGui::PushTextWrapPos(ImGui::GetFontSize() * 35.0f);
- ImGui::TextUnformatted(description);
- ImGui::PopTextWrapPos();
- ImGui::EndTooltip();
- }
- }
- void AddUnderLine(ImColor color) {
- ImVec2 min = ImGui::GetItemRectMin();
- ImVec2 max = ImGui::GetItemRectMax();
- min.y = max.y;
- ImGui::GetWindowDrawList()->AddLine(min, max, color, 1.0f);
- }
- void TextURL(const char* name_, const char* URL_, bool SameLineBefore_, bool SameLineAfter_) {
- if (SameLineBefore_)
- ImGui::SameLine(0.0f, ImGui::GetStyle().ItemInnerSpacing.x);
- ImGui::PushStyleColor(ImGuiCol_Text, ImGui::GetStyle().Colors[ImGuiCol_ButtonHovered]);
- ImGui::Text(name_);
- ImGui::PopStyleColor();
- if (ImGui::IsItemHovered()) {
- if (ImGui::IsMouseClicked(0))
- ShellExecuteA(0, 0, URL_, 0, 0, SW_SHOW);
- AddUnderLine(ImGui::GetStyle().Colors[ImGuiCol_ButtonHovered]);
- ImGui::SetTooltip("Open in browser\n%s", URL_);
- }
- else
- AddUnderLine(ImGui::GetStyle().Colors[ImGuiCol_Button]);
- if (SameLineAfter_)
- ImGui::SameLine(0.0f, ImGui::GetStyle().ItemInnerSpacing.x);
- }
- struct GroupPanelHeaderBounds
- {
- ImRect left;
- ImRect right;
- bool collapsed;
- };
- static ImVector<GroupPanelHeaderBounds> _groupPanelStack;
- static bool GroupPanelIsOpen(ImGuiID id)
- {
- ImGuiContext& g = *GImGui;
- ImGuiWindow* window = g.CurrentWindow;
- ImGuiStorage* storage = window->DC.StateStorage;
- return storage->GetInt(id, 1) != 0;
- }
- static void GroupPanelSetOpen(ImGuiID id, bool open)
- {
- ImGuiContext& g = *GImGui;
- ImGuiWindow* window = g.CurrentWindow;
- ImGuiStorage* storage = window->DC.StateStorage;
- storage->SetInt(id, open ? 1 : 0);
- }
- bool BeginGroupPanel(const char* label, bool node, const ImVec2& size)
- {
- ImGuiContext& g = *GImGui;
- ImGuiWindow* window = g.CurrentWindow;
- const ImGuiID id = window->GetID(label);
- ImGui::PushID(id);
- auto groupPanelPos = window->DC.CursorPos;
- auto itemSpacing = ImGui::GetStyle().ItemSpacing;
- ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(0.0f, 0.0f));
- ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(0.0f, 0.0f));
- ImGui::BeginGroup(); // Outer group
- ImVec2 effectiveSize = size;
- if (size.x < 0.0f)
- effectiveSize.x = ImGui::GetContentRegionAvail().x;
- else
- effectiveSize.x = size.x;
- ImGui::Dummy(ImVec2(effectiveSize.x, 0.0f)); // Adjusting group x size
- auto frameHeight = ImGui::GetFrameHeight();
- ImGui::Dummy(ImVec2(frameHeight * 0.5f, 0.0f)); ImGui::SameLine(0.0f, 0.0f); // Inner group spacing
- ImGui::BeginGroup(); // Inner group
- ImGui::Dummy(ImVec2(frameHeight * 0.5f, 0.0f)); ImGui::SameLine(0.0f, 0.0f); // Name text spacing
- ImGui::TextUnformatted(label);
- ImRect leftRect = { ImGui::GetItemRectMin(), ImGui::GetItemRectMax() };
- ImVec2 rightMax = ImVec2(groupPanelPos.x + effectiveSize.x - frameHeight, leftRect.Max.y);
- ImRect rightRect = { { rightMax.x, leftRect.Min.x }, rightMax };
- ImGui::SameLine(0.0f, 0.0f);
- ImGui::Dummy(ImVec2(0.0, frameHeight + itemSpacing.y));
- if (node)
- {
- leftRect.Min.x = groupPanelPos.x;
- const ImVec2 text_size = ImGui::CalcTextSize(label);
- bool isOpen = GroupPanelIsOpen(id);
- bool hovered;
- bool toggled = ImGui::ButtonBehavior(leftRect, id, &hovered, nullptr, ImGuiButtonFlags_PressedOnClick);
- if (toggled)
- {
- isOpen = !isOpen;
- GroupPanelSetOpen(id, isOpen);
- }
- const ImU32 text_col = ImGui::GetColorU32(ImGuiCol_Text);
- ImGui::RenderArrow(window->DrawList, { groupPanelPos.x, groupPanelPos.y + text_size.y * 0.15f }, text_col,
- isOpen ? ImGuiDir_Down : ImGuiDir_Right, 0.7f);
- if (!isOpen)
- {
- ImGui::PopStyleVar(2);
- ImGui::EndGroup();
- ImGui::EndGroup();
- ImGui::PopID();
- _groupPanelStack.push_back({ leftRect, rightRect, true });
- return false;
- }
- }
- ImGui::PopStyleVar(2);
- ImGui::GetCurrentWindow()->ContentRegionRect.Max.x -= frameHeight * 0.5f;
- ImGui::GetCurrentWindow()->WorkRect.Max.x -= frameHeight * 0.5f;
- ImGui::GetCurrentWindow()->InnerRect.Max.x -= frameHeight * 0.5f;
- ImGui::GetCurrentWindow()->Size.x -= frameHeight;
- auto itemWidth = ImGui::CalcItemWidth();
- ImGui::PushItemWidth(ImMax(0.0f, itemWidth - frameHeight));
- _groupPanelStack.push_back({ leftRect, rightRect, false });
- return true;
- }
- const char* languages[] = { "English", "Russian", "Chinese",
- "Indonesian/Not supported at this time", "Romanian"
- };
- void ConfigComboLanguage(ConfigField<int>& f_Language) {
- int currentLanguage = f_Language.getValue();
- if (ImGui::Combo(_("LANGUAGE_SELECT"), ¤tLanguage, languages, IM_ARRAYSIZE(languages))) {
- f_Language.setValue(currentLanguage);
- config::setValue(f_Language, currentLanguage);
- }
- }
- void EndGroupPanel() {
- IM_ASSERT(_groupPanelStack.Size > 0); // Mismatched BeginGroupPanel()/EndGroupPanel() calls
- auto& info = _groupPanelStack.back();
- _groupPanelStack.pop_back();
- if (info.collapsed)
- return;
- ImGui::PopItemWidth();
- auto itemSpacing = ImGui::GetStyle().ItemSpacing;
- ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(0.0f, 0.0f));
- ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(0.0f, 0.0f));
- ImGui::EndGroup(); // Inner group
- auto frameHeight = ImGui::GetFrameHeight();
- ImGui::SameLine(0.0f, 0.0f);
- ImGui::Dummy(ImVec2(frameHeight * 0.5f, 0.0f));
- ImGui::Dummy(ImVec2(0.0, frameHeight - frameHeight * 0.5f - itemSpacing.y));
- ImGui::EndGroup(); // Outer group
- // Outer group rect
- auto itemMin = ImGui::GetItemRectMin();
- auto itemMax = ImGui::GetItemRectMax();
- ImVec2 halfFrame = ImVec2(frameHeight * 0.25f, frameHeight) * 0.5f;
- ImRect frameRect = ImRect(itemMin + halfFrame, itemMax - ImVec2(halfFrame.x, 0.0f));
- auto& leftRect = info.left;
- leftRect.Min.x -= itemSpacing.x;
- leftRect.Max.x += itemSpacing.x;
- bool hasRightPart = info.right.Min.x != info.right.Max.x;
- auto& rightRect = info.right;
- if (hasRightPart) {
- rightRect.Min.x -= itemSpacing.x;
- rightRect.Max.x += itemSpacing.x;
- }
- // Drawing rectangle
- for (int i = 0; i < (hasRightPart ? 5 : 3); ++i) {
- switch (i) {
- case 0: // left half-plane
- ImGui::PushClipRect(ImVec2(-FLT_MAX, -FLT_MAX), ImVec2(leftRect.Min.x, FLT_MAX), true);
- break;
- case 1: // right half-plane
- ImGui::PushClipRect(ImVec2(leftRect.Max.x, -FLT_MAX), ImVec2(hasRightPart ? rightRect.Min.x : FLT_MAX, FLT_MAX), true);
- break;
- case 2: // bottom
- ImGui::PushClipRect(ImVec2(leftRect.Min.x, leftRect.Max.y), ImVec2(leftRect.Max.x, FLT_MAX), true);
- break;
- case 3: // bottom select
- ImGui::PushClipRect(ImVec2(rightRect.Min.x, rightRect.Max.y), ImVec2(rightRect.Max.x, FLT_MAX), true);
- break;
- case 4: // right hand-plane
- ImGui::PushClipRect(ImVec2(rightRect.Max.x, -FLT_MAX), ImVec2(FLT_MAX, FLT_MAX), true);
- break;
- }
- ImGui::GetWindowDrawList()->AddRect(frameRect.Min, frameRect.Max,
- ImColor(ImGui::GetStyleColorVec4(ImGuiCol_Border)), halfFrame.x);
- ImGui::PopClipRect();
- }
- ImGui::PopStyleVar(2);
- // Restore content region
- ImGui::GetCurrentWindow()->ContentRegionRect.Max.x += frameHeight * 0.5f;
- ImGui::GetCurrentWindow()->WorkRect.Max.x += frameHeight * 0.5f;
- ImGui::GetCurrentWindow()->InnerRect.Max.x += frameHeight * 0.5f;
- ImGui::GetCurrentWindow()->Size.x += frameHeight;
- // Add vertical spacing
- ImGui::Dummy(ImVec2(0.0f, 0.0f));
- ImGui::PopID();
- }
|