50 const ImGuiViewport* viewport = ImGui::GetMainViewport();
51 ImVec2 max_window_size(1600.0f, 1000.0f);
52 ImVec2 default_window_size(1080.0f, 700.0f);
54 max_window_size = ImVec2(std::max(760.0f, viewport->WorkSize.x * 0.95f),
55 std::max(520.0f, viewport->WorkSize.y * 0.95f));
56 default_window_size = ImVec2(
57 std::clamp(viewport->WorkSize.x * 0.72f, 880.0f, max_window_size.x),
58 std::clamp(viewport->WorkSize.y * 0.76f, 600.0f, max_window_size.y));
59 const ImVec2 center(viewport->WorkPos.x + viewport->WorkSize.x * 0.5f,
60 viewport->WorkPos.y + viewport->WorkSize.y * 0.5f);
61 ImGui::SetNextWindowPos(center, ImGuiCond_Appearing, ImVec2(0.5f, 0.5f));
64 ImGui::SetNextWindowSize(default_window_size, ImGuiCond_Appearing);
65 ImGui::SetNextWindowSizeConstraints(ImVec2(780, 520), max_window_size);
69 p_open, ImGuiWindowFlags_NoDocking)) {
70 std::vector<std::string> categories =
72 std::sort(categories.begin(), categories.end());
80 auto count_windows = [&](
const std::string& category,
81 bool visible_only) ->
int {
83 for (
const auto& window_id : all_windows) {
89 if (!window->IsListedInWindowBrowser()) {
92 if (category !=
"All" && window->category != category) {
97 if (!visible_only || visible) {
103 auto set_filtered_windows_visible = [&](
const std::string& category,
105 for (
const auto& window_id : all_windows) {
111 if (!window->IsListedInWindowBrowser()) {
114 if (category !=
"All" && window->category != category) {
125 ImGui::SetNextItemWidth(
126 std::max(280.0f, ImGui::GetContentRegionAvail().x * 0.45f));
127 ImGui::InputTextWithHint(
138 set_filtered_windows_visible(
"All",
true);
142 set_filtered_windows_visible(
"All",
false);
156 const float content_height = ImGui::GetContentRegionAvail().y;
157 const float max_sidebar_width =
158 std::max(220.0f, ImGui::GetContentRegionAvail().x * 0.50f);
159 float category_sidebar_width =
163 if (ImGui::BeginChild(
"##WindowBrowserCategories",
164 ImVec2(category_sidebar_width, content_height),
166 const int visible_total = count_windows(
"All",
true);
167 const int filtered_total = count_windows(
"All",
false);
168 std::string all_label =
170 visible_total, filtered_total);
176 for (
const auto& category : categories) {
177 const int category_total = count_windows(category,
false);
178 if (category_total <= 0) {
181 const int visible_in_category = count_windows(category,
true);
182 const std::string icon =
185 absl::StrFormat(
"%s %s (%d/%d)", icon.c_str(), category.c_str(),
186 visible_in_category, category_total);
194 ImGui::SameLine(0.0f, 0.0f);
196 const float splitter_width = 6.0f;
197 const ImVec2 splitter_pos = ImGui::GetCursorScreenPos();
198 ImGui::InvisibleButton(
"##WindowBrowserSplitter",
199 ImVec2(splitter_width, content_height));
200 const bool splitter_hovered = ImGui::IsItemHovered();
201 const bool splitter_active = ImGui::IsItemActive();
202 if (splitter_hovered || splitter_active) {
203 ImGui::SetMouseCursor(ImGuiMouseCursor_ResizeEW);
205 if (splitter_hovered &&
206 ImGui::IsMouseDoubleClicked(ImGuiMouseButton_Left)) {
209 category_sidebar_width =
213 if (splitter_active) {
214 category_sidebar_width =
215 std::clamp(category_sidebar_width + ImGui::GetIO().MouseDelta.x,
216 220.0f, max_sidebar_width);
218 ImGui::SetTooltip(tr(
"Width: %.0f px"), category_sidebar_width);
223 splitter_active ? 0.95f : (splitter_hovered ? 0.72f : 0.35f);
224 ImGui::GetWindowDrawList()->AddLine(
225 ImVec2(splitter_pos.x + splitter_width * 0.5f, splitter_pos.y),
226 ImVec2(splitter_pos.x + splitter_width * 0.5f,
227 splitter_pos.y + content_height),
228 ImGui::GetColorU32(splitter_color), splitter_active ? 2.0f : 1.0f);
230 ImGui::SameLine(0.0f, 0.0f);
232 if (ImGui::BeginChild(
"##WindowBrowserTable", ImVec2(0, content_height),
234 if (ImGui::BeginTable(
"##WindowTable", 5,
235 ImGuiTableFlags_ScrollY | ImGuiTableFlags_RowBg |
236 ImGuiTableFlags_Borders |
237 ImGuiTableFlags_Resizable)) {
238 ImGui::TableSetupColumn(
"Visible", ImGuiTableColumnFlags_WidthFixed,
240 ImGui::TableSetupColumn(
"Pin", ImGuiTableColumnFlags_WidthFixed,
242 ImGui::TableSetupColumn(
"Name", ImGuiTableColumnFlags_WidthStretch);
243 ImGui::TableSetupColumn(
"Category", ImGuiTableColumnFlags_WidthFixed,
245 ImGui::TableSetupColumn(
"Shortcut", ImGuiTableColumnFlags_WidthFixed,
247 ImGui::TableHeadersRow();
250 : std::vector<std::string>{};
254 windows.reserve(category_windows.size());
255 for (
const auto& window : category_windows) {
256 if (!window.IsListedInWindowBrowser()) {
259 windows.push_back(window.card_id);
263 for (
const auto& window_id : windows) {
269 if (!window->IsListedInWindowBrowser()) {
277 ImGui::TableNextRow();
279 ImGui::TableNextColumn();
280 if (window->visibility_flag) {
281 bool visible = *window->visibility_flag;
283 absl::StrFormat(
"##vis_%s", window->card_id).c_str(),
289 ImGui::TableNextColumn();
290 const bool is_pinned =
295 pin_color.w *= 0.72f;
299 absl::StrFormat(
"browser_pin_%s", window->card_id).c_str());
302 is_pinned ?
"Unpin window" :
"Pin window", is_pinned,
303 pin_color,
"window_browser", window->card_id.c_str())) {
309 ImGui::TableNextColumn();
310 ImGui::Text(
"%s %s", window->icon.c_str(),
311 window->display_name.c_str());
312 if (ImGui::IsItemHovered() &&
313 ImGui::IsMouseDoubleClicked(ImGuiMouseButton_Left)) {
315 const std::string window_name =
317 if (!window_name.empty()) {
318 ImGui::SetWindowFocus(window_name.c_str());
322 ImGui::TableNextColumn();
323 ImGui::TextUnformatted(window->category.c_str());
325 ImGui::TableNextColumn();
326 if (window->shortcut_hint.empty()) {
327 ImGui::TextDisabled(
"-");
329 ImGui::TextDisabled(
"%s", window->shortcut_hint.c_str());