| 95 | return ret; |
| 96 | } |
| 97 | bool PathBox(const char* label, std::filesystem::path& path, char* pathBuffer, ImVec2 size_arg) { |
| 98 | ImGuiWindow* window = ImGui::GetCurrentWindow(); |
| 99 | if (window->SkipItems) |
| 100 | return false; |
| 101 | |
| 102 | bool ret = false; |
| 103 | const ImGuiID id = window->GetID(label); |
| 104 | int* state = window->StateStorage.GetIntRef(id, 0); |
| 105 | |
| 106 | ImGui::SameLine(); |
| 107 | |
| 108 | ImGuiContext& g = *GImGui; |
| 109 | const ImGuiStyle& style = g.Style; |
| 110 | ImVec2 pos = window->DC.CursorPos; |
| 111 | ImVec2 uiPos = ImGui::GetCursorPos(); |
| 112 | ImVec2 size = ImGui::CalcItemSize(size_arg, 200, GUI_ELEMENT_SIZE); |
| 113 | const ImRect bb(pos, pos + size); |
| 114 | |
| 115 | // buttons |
| 116 | if (!(*state & 0b001)) { |
| 117 | ImGui::PushClipRect(bb.Min, bb.Max, false); |
| 118 | |
| 119 | // background |
| 120 | bool hovered = g.IO.MousePos.x >= bb.Min.x && g.IO.MousePos.x <= bb.Max.x && |
| 121 | g.IO.MousePos.y >= bb.Min.y && g.IO.MousePos.y <= bb.Max.y; |
| 122 | bool clicked = hovered && ImGui::IsMouseReleased(ImGuiMouseButton_Left); |
| 123 | bool anyOtherHC = false; // are any other items hovered or clicked? |
| 124 | window->DrawList->AddRectFilled(pos, pos + size, ImGui::ColorConvertFloat4ToU32(ImGui::GetStyle().Colors[(*state & 0b10) ? ImGuiCol_FrameBgHovered : ImGuiCol_FrameBg])); |
| 125 | |
| 126 | // fetch the buttons (so that we can throw some away if needed) |
| 127 | std::vector<std::string> btnList; |
| 128 | float totalWidth = 0.0f; |
| 129 | for (auto comp : path) { |
| 130 | std::string section = comp.u8string(); |
| 131 | if (section.size() == 1 && (section[0] == '\\' || section[0] == '/')) |
| 132 | continue; |
| 133 | |
| 134 | totalWidth += ImGui::CalcTextSize(section.c_str()).x + style.FramePadding.x * 2.0f + GUI_ELEMENT_SIZE; |
| 135 | btnList.push_back(section); |
| 136 | } |
| 137 | totalWidth -= GUI_ELEMENT_SIZE; |
| 138 | |
| 139 | // UI buttons |
| 140 | ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(0.0f, ImGui::GetStyle().ItemSpacing.y)); |
| 141 | ImGui::PushStyleVar(ImGuiStyleVar_FrameBorderSize, 0.0f); |
| 142 | bool isFirstElement = true; |
| 143 | for (size_t i = 0; i < btnList.size(); i++) { |
| 144 | if (totalWidth > size.x - 30 && i != btnList.size() - 1) { // trim some buttons if there's not enough space |
| 145 | float elSize = ImGui::CalcTextSize(btnList[i].c_str()).x + style.FramePadding.x * 2.0f + GUI_ELEMENT_SIZE; |
| 146 | totalWidth -= elSize; |
| 147 | continue; |
| 148 | } |
| 149 | |
| 150 | ImGui::PushID(static_cast<int>(i)); |
| 151 | if (!isFirstElement) { |
| 152 | ImGui::ArrowButtonEx("##dir_dropdown", ImGuiDir_Right, ImVec2(GUI_ELEMENT_SIZE, GUI_ELEMENT_SIZE)); |
| 153 | anyOtherHC |= ImGui::IsItemHovered() | ImGui::IsItemClicked(); |
| 154 | ImGui::SameLine(); |