diff --git a/assets/themes/yaze_tre.theme b/assets/themes/yaze_tre.theme index 0168aae8..a35103df 100644 --- a/assets/themes/yaze_tre.theme +++ b/assets/themes/yaze_tre.theme @@ -82,6 +82,26 @@ table_row_bg_alt=255,255,255,25 # Slightly more visible alternating rows # Link colors (high contrast for better visibility) text_link=120,200,255,255 # Bright blue for links - high contrast against dark backgrounds +# Navigation and special elements +input_text_cursor=245,245,245,255 +nav_cursor=110,145,110,255 +nav_windowing_highlight=110,145,110,255 +nav_windowing_dim_bg=0,0,0,128 +modal_window_dim_bg=0,0,0,89 +text_selected_bg=89,119,89,89 +drag_drop_target=110,145,110,255 +docking_preview=92,115,92,180 +docking_empty_bg=46,66,46,255 + +# Tree lines +tree_lines=127,127,127,153 + +# Tab variations for unfocused windows +tab_dimmed=37,52,37,255 +tab_dimmed_selected=62,83,62,255 +tab_dimmed_selected_overline=110,145,110,255 +tab_selected_overline=110,145,110,255 + [style] window_rounding=0.0 frame_rounding=5.0 diff --git a/src/app/gui/style.cc b/src/app/gui/style.cc index 686ff0e3..3646f583 100644 --- a/src/app/gui/style.cc +++ b/src/app/gui/style.cc @@ -398,6 +398,50 @@ void BeginChildBothScrollbars(int id) { ImGuiWindowFlags_AlwaysHorizontalScrollbar); } +// Helper functions for table canvas management +void BeginTableCanvas(const char* table_id, int columns, ImVec2 canvas_size) { + // Use proper sizing for tables containing canvas elements + ImGuiTableFlags flags = ImGuiTableFlags_Resizable | ImGuiTableFlags_SizingStretchProp; + + // If canvas size is specified, use it as minimum size + ImVec2 outer_size = ImVec2(0, 0); + if (canvas_size.x > 0 || canvas_size.y > 0) { + outer_size = canvas_size; + flags |= ImGuiTableFlags_NoHostExtendY; // Prevent auto-extending past canvas size + } + + ImGui::BeginTable(table_id, columns, flags, outer_size); +} + +void EndTableCanvas() { + ImGui::EndTable(); +} + +void SetupCanvasTableColumn(const char* label, float width_ratio) { + if (width_ratio > 0) { + ImGui::TableSetupColumn(label, ImGuiTableColumnFlags_WidthStretch, width_ratio); + } else { + ImGui::TableSetupColumn(label, ImGuiTableColumnFlags_WidthStretch); + } +} + +void BeginCanvasTableCell(ImVec2 min_size) { + ImGui::TableNextColumn(); + + // Ensure minimum size for canvas cells + if (min_size.x > 0 || min_size.y > 0) { + ImVec2 avail = ImGui::GetContentRegionAvail(); + ImVec2 actual_size = ImVec2( + std::max(avail.x, min_size.x), + std::max(avail.y, min_size.y) + ); + + // Reserve space for the canvas + ImGui::Dummy(actual_size); + ImGui::SetCursorPos(ImGui::GetCursorPos() - actual_size); // Reset cursor for drawing + } +} + void DrawDisplaySettings(ImGuiStyle *ref) { // You can pass in a reference ImGuiStyle structure to compare to, revert to // and save to (without a reference style pointer, we will use one compared @@ -413,66 +457,121 @@ void DrawDisplaySettings(ImGuiStyle *ref) { ImGui::PushItemWidth(ImGui::GetWindowWidth() * 0.50f); - // Enhanced theme selector - auto& theme_manager = ThemeManager::Get(); - static bool show_theme_selector = false; - - ImGui::Text("Theme Selection:"); - - // Classic YAZE button - std::string current_theme_name = theme_manager.GetCurrentThemeName(); - bool is_classic_active = (current_theme_name == "Classic YAZE"); - - if (is_classic_active) { - ImGui::PushStyleColor(ImGuiCol_Button, ImVec4(0.2f, 0.6f, 0.2f, 1.0f)); - } - - if (ImGui::Button("Classic YAZE")) { - theme_manager.ApplyClassicYazeTheme(); - ref_saved_style = style; - } - - if (ImGui::Button("ColorsYaze")) { - gui::ColorsYaze(); - } - - if (is_classic_active) { - ImGui::PopStyleColor(); - } - - ImGui::SameLine(); - ImGui::Text(" | "); - ImGui::SameLine(); - - // File themes dropdown - just the raw list, no sorting - auto available_themes = theme_manager.GetAvailableThemes(); - const char* current_file_theme = ""; - - // Find current file theme for display - for (const auto& theme_name : available_themes) { - if (theme_name == current_theme_name) { - current_file_theme = theme_name.c_str(); - break; + // Enhanced theme management section + if (ImGui::CollapsingHeader("Theme Management", ImGuiTreeNodeFlags_DefaultOpen)) { + auto& theme_manager = ThemeManager::Get(); + static bool show_theme_selector = false; + static bool show_theme_editor = false; + + ImGui::Text("%s Current Theme:", ICON_MD_PALETTE); + ImGui::SameLine(); + + std::string current_theme_name = theme_manager.GetCurrentThemeName(); + bool is_classic_active = (current_theme_name == "Classic YAZE"); + + // Current theme display with color preview + if (is_classic_active) { + ImGui::TextColored(ImVec4(0.2f, 0.8f, 0.2f, 1.0f), "%s", current_theme_name.c_str()); + } else { + ImGui::Text("%s", current_theme_name.c_str()); } - } - - if (ImGui::BeginCombo("File Themes", current_file_theme)) { - for (const auto& theme_name : available_themes) { - if (ImGui::Selectable(theme_name.c_str())) { - theme_manager.LoadTheme(theme_name); + + // Theme color preview + auto current_theme = theme_manager.GetCurrentTheme(); + ImGui::SameLine(); + ImGui::ColorButton("##primary_preview", gui::ConvertColorToImVec4(current_theme.primary), + ImGuiColorEditFlags_NoTooltip, ImVec2(20, 20)); + ImGui::SameLine(); + ImGui::ColorButton("##secondary_preview", gui::ConvertColorToImVec4(current_theme.secondary), + ImGuiColorEditFlags_NoTooltip, ImVec2(20, 20)); + ImGui::SameLine(); + ImGui::ColorButton("##accent_preview", gui::ConvertColorToImVec4(current_theme.accent), + ImGuiColorEditFlags_NoTooltip, ImVec2(20, 20)); + + ImGui::Spacing(); + + // Theme selection table for better organization + if (ImGui::BeginTable("ThemeSelectionTable", 3, + ImGuiTableFlags_SizingStretchProp | ImGuiTableFlags_NoHostExtendY, + ImVec2(0, 80))) { + + ImGui::TableSetupColumn("Built-in", ImGuiTableColumnFlags_WidthStretch, 0.3f); + ImGui::TableSetupColumn("File Themes", ImGuiTableColumnFlags_WidthStretch, 0.4f); + ImGui::TableSetupColumn("Actions", ImGuiTableColumnFlags_WidthStretch, 0.3f); + ImGui::TableHeadersRow(); + + ImGui::TableNextRow(); + + // Built-in themes column + ImGui::TableNextColumn(); + if (is_classic_active) { + ImGui::PushStyleColor(ImGuiCol_Button, ImVec4(0.2f, 0.6f, 0.2f, 1.0f)); + } + + if (ImGui::Button("Classic YAZE", ImVec2(-1, 30))) { + theme_manager.ApplyClassicYazeTheme(); ref_saved_style = style; } + + if (is_classic_active) { + ImGui::PopStyleColor(); + } + + if (ImGui::Button("Reset ColorsYaze", ImVec2(-1, 30))) { + gui::ColorsYaze(); + ref_saved_style = style; + } + + // File themes column + ImGui::TableNextColumn(); + auto available_themes = theme_manager.GetAvailableThemes(); + const char* current_file_theme = ""; + + // Find current file theme for display + for (const auto& theme_name : available_themes) { + if (theme_name == current_theme_name) { + current_file_theme = theme_name.c_str(); + break; + } + } + + ImGui::SetNextItemWidth(-1); + if (ImGui::BeginCombo("##FileThemes", current_file_theme)) { + for (const auto& theme_name : available_themes) { + bool is_selected = (theme_name == current_theme_name); + if (ImGui::Selectable(theme_name.c_str(), is_selected)) { + theme_manager.LoadTheme(theme_name); + ref_saved_style = style; + } + } + ImGui::EndCombo(); + } + + if (ImGui::Button("Refresh Themes", ImVec2(-1, 30))) { + theme_manager.RefreshAvailableThemes(); + } + + // Actions column + ImGui::TableNextColumn(); + if (ImGui::Button("Theme Selector", ImVec2(-1, 30))) { + show_theme_selector = true; + } + + if (ImGui::Button("Theme Editor", ImVec2(-1, 30))) { + show_theme_editor = true; + } + + ImGui::EndTable(); + } + + // Show theme dialogs + if (show_theme_selector) { + theme_manager.ShowThemeSelector(&show_theme_selector); + } + + if (show_theme_editor) { + theme_manager.ShowSimpleThemeEditor(&show_theme_editor); } - ImGui::EndCombo(); - } - - ImGui::SameLine(); - if (ImGui::Button("Theme Settings")) { - show_theme_selector = true; - } - - if (show_theme_selector) { - theme_manager.ShowThemeSelector(&show_theme_selector); } ImGui::Separator(); diff --git a/src/app/gui/style.h b/src/app/gui/style.h index afdc72b7..00f75ea7 100644 --- a/src/app/gui/style.h +++ b/src/app/gui/style.h @@ -66,6 +66,12 @@ void BeginChildWithScrollbar(const char *str_id); void BeginChildBothScrollbars(int id); +// Table canvas management helpers for GUI elements that need proper sizing +void BeginTableCanvas(const char* table_id, int columns, ImVec2 canvas_size = ImVec2(0, 0)); +void EndTableCanvas(); +void SetupCanvasTableColumn(const char* label, float width_ratio = 0.0f); +void BeginCanvasTableCell(ImVec2 min_size = ImVec2(0, 0)); + void DrawDisplaySettings(ImGuiStyle *ref = nullptr); void TextWithSeparators(const absl::string_view &text); diff --git a/src/app/gui/theme_manager.cc b/src/app/gui/theme_manager.cc index 0edce8e1..1961657c 100644 --- a/src/app/gui/theme_manager.cc +++ b/src/app/gui/theme_manager.cc @@ -88,6 +88,13 @@ void EnhancedTheme::ApplyToImGui() const { colors[ImGuiCol_PlotLinesHovered] = ConvertColorToImVec4(plot_lines_hovered); colors[ImGuiCol_PlotHistogram] = ConvertColorToImVec4(plot_histogram); colors[ImGuiCol_PlotHistogramHovered] = ConvertColorToImVec4(plot_histogram_hovered); + colors[ImGuiCol_TreeLines] = ConvertColorToImVec4(tree_lines); + + // Additional ImGui colors for complete coverage + colors[ImGuiCol_TabDimmed] = ConvertColorToImVec4(tab_dimmed); + colors[ImGuiCol_TabDimmedSelected] = ConvertColorToImVec4(tab_dimmed_selected); + colors[ImGuiCol_TabDimmedSelectedOverline] = ConvertColorToImVec4(tab_dimmed_selected_overline); + colors[ImGuiCol_TabSelectedOverline] = ConvertColorToImVec4(tab_selected_overline); // Apply style parameters style->WindowRounding = window_rounding; @@ -166,6 +173,15 @@ void ThemeManager::CreateFallbackYazeClassic() { theme.title_bg_active = RGBA(46, 66, 46); // alttpDarkGreen theme.title_bg_collapsed = RGBA(71, 92, 71); // alttpMidGreen + // Initialize missing fields that were added to the struct + theme.surface = theme.background; + theme.error = RGBA(220, 50, 50); + theme.warning = RGBA(255, 200, 50); + theme.success = theme.primary; + theme.info = RGBA(70, 170, 255); + theme.text_secondary = RGBA(200, 200, 200); + theme.modal_bg = theme.popup_bg; + // Borders and separators theme.border = RGBA(92, 115, 92); // allttpLightGreen theme.border_shadow = RGBA(0, 0, 0, 0); // Transparent @@ -537,8 +553,33 @@ absl::Status ThemeManager::ParseThemeFile(const std::string& content, EnhancedTh else if (key == "resize_grip") theme.resize_grip = color; else if (key == "resize_grip_hovered") theme.resize_grip_hovered = color; else if (key == "resize_grip_active") theme.resize_grip_active = color; - // Note: Additional colors like check_mark, slider_grab, table colors - // are handled by the fallback or can be added to EnhancedTheme struct as needed + else if (key == "check_mark") theme.check_mark = color; + else if (key == "slider_grab") theme.slider_grab = color; + else if (key == "slider_grab_active") theme.slider_grab_active = color; + else if (key == "input_text_cursor") theme.input_text_cursor = color; + else if (key == "nav_cursor") theme.nav_cursor = color; + else if (key == "nav_windowing_highlight") theme.nav_windowing_highlight = color; + else if (key == "nav_windowing_dim_bg") theme.nav_windowing_dim_bg = color; + else if (key == "modal_window_dim_bg") theme.modal_window_dim_bg = color; + else if (key == "text_selected_bg") theme.text_selected_bg = color; + else if (key == "drag_drop_target") theme.drag_drop_target = color; + else if (key == "table_header_bg") theme.table_header_bg = color; + else if (key == "table_border_strong") theme.table_border_strong = color; + else if (key == "table_border_light") theme.table_border_light = color; + else if (key == "table_row_bg") theme.table_row_bg = color; + else if (key == "table_row_bg_alt") theme.table_row_bg_alt = color; + else if (key == "text_link") theme.text_link = color; + else if (key == "plot_lines") theme.plot_lines = color; + else if (key == "plot_lines_hovered") theme.plot_lines_hovered = color; + else if (key == "plot_histogram") theme.plot_histogram = color; + else if (key == "plot_histogram_hovered") theme.plot_histogram_hovered = color; + else if (key == "tree_lines") theme.tree_lines = color; + else if (key == "tab_dimmed") theme.tab_dimmed = color; + else if (key == "tab_dimmed_selected") theme.tab_dimmed_selected = color; + else if (key == "tab_dimmed_selected_overline") theme.tab_dimmed_selected_overline = color; + else if (key == "tab_selected_overline") theme.tab_selected_overline = color; + else if (key == "docking_preview") theme.docking_preview = color; + else if (key == "docking_empty_bg") theme.docking_empty_bg = color; } else if (current_section == "style") { if (key == "window_rounding") theme.window_rounding = std::stof(value); @@ -664,12 +705,58 @@ std::string ThemeManager::SerializeTheme(const EnhancedTheme& theme) const { ss << "separator_active=" << colorToString(theme.separator_active) << "\n"; ss << "\n"; - // Scrollbars - ss << "# Scrollbars\n"; + // Scrollbars and controls + ss << "# Scrollbars and controls\n"; ss << "scrollbar_bg=" << colorToString(theme.scrollbar_bg) << "\n"; ss << "scrollbar_grab=" << colorToString(theme.scrollbar_grab) << "\n"; ss << "scrollbar_grab_hovered=" << colorToString(theme.scrollbar_grab_hovered) << "\n"; ss << "scrollbar_grab_active=" << colorToString(theme.scrollbar_grab_active) << "\n"; + ss << "resize_grip=" << colorToString(theme.resize_grip) << "\n"; + ss << "resize_grip_hovered=" << colorToString(theme.resize_grip_hovered) << "\n"; + ss << "resize_grip_active=" << colorToString(theme.resize_grip_active) << "\n"; + ss << "check_mark=" << colorToString(theme.check_mark) << "\n"; + ss << "slider_grab=" << colorToString(theme.slider_grab) << "\n"; + ss << "slider_grab_active=" << colorToString(theme.slider_grab_active) << "\n"; + ss << "\n"; + + // Navigation and special elements + ss << "# Navigation and special elements\n"; + ss << "input_text_cursor=" << colorToString(theme.input_text_cursor) << "\n"; + ss << "nav_cursor=" << colorToString(theme.nav_cursor) << "\n"; + ss << "nav_windowing_highlight=" << colorToString(theme.nav_windowing_highlight) << "\n"; + ss << "nav_windowing_dim_bg=" << colorToString(theme.nav_windowing_dim_bg) << "\n"; + ss << "modal_window_dim_bg=" << colorToString(theme.modal_window_dim_bg) << "\n"; + ss << "text_selected_bg=" << colorToString(theme.text_selected_bg) << "\n"; + ss << "drag_drop_target=" << colorToString(theme.drag_drop_target) << "\n"; + ss << "docking_preview=" << colorToString(theme.docking_preview) << "\n"; + ss << "docking_empty_bg=" << colorToString(theme.docking_empty_bg) << "\n"; + ss << "\n"; + + // Table colors + ss << "# Table colors\n"; + ss << "table_header_bg=" << colorToString(theme.table_header_bg) << "\n"; + ss << "table_border_strong=" << colorToString(theme.table_border_strong) << "\n"; + ss << "table_border_light=" << colorToString(theme.table_border_light) << "\n"; + ss << "table_row_bg=" << colorToString(theme.table_row_bg) << "\n"; + ss << "table_row_bg_alt=" << colorToString(theme.table_row_bg_alt) << "\n"; + ss << "\n"; + + // Links and plots + ss << "# Links and plots\n"; + ss << "text_link=" << colorToString(theme.text_link) << "\n"; + ss << "plot_lines=" << colorToString(theme.plot_lines) << "\n"; + ss << "plot_lines_hovered=" << colorToString(theme.plot_lines_hovered) << "\n"; + ss << "plot_histogram=" << colorToString(theme.plot_histogram) << "\n"; + ss << "plot_histogram_hovered=" << colorToString(theme.plot_histogram_hovered) << "\n"; + ss << "tree_lines=" << colorToString(theme.tree_lines) << "\n"; + ss << "\n"; + + // Tab variations + ss << "# Tab variations\n"; + ss << "tab_dimmed=" << colorToString(theme.tab_dimmed) << "\n"; + ss << "tab_dimmed_selected=" << colorToString(theme.tab_dimmed_selected) << "\n"; + ss << "tab_dimmed_selected_overline=" << colorToString(theme.tab_dimmed_selected_overline) << "\n"; + ss << "tab_selected_overline=" << colorToString(theme.tab_selected_overline) << "\n"; ss << "\n"; // Style settings @@ -786,6 +873,13 @@ void ThemeManager::ApplyClassicYazeTheme() { classic_theme.plot_histogram_hovered = RGBA(255, 153, 0); classic_theme.docking_preview = RGBA(92, 115, 92, 180); classic_theme.docking_empty_bg = RGBA(46, 66, 46, 255); + classic_theme.tree_lines = classic_theme.separator; // Use separator color for tree lines + + // Tab dimmed colors (for unfocused tabs) + classic_theme.tab_dimmed = RGBA(37, 52, 37); // Darker version of tab + classic_theme.tab_dimmed_selected = RGBA(62, 83, 62); // Darker version of tab_active + classic_theme.tab_dimmed_selected_overline = classic_theme.accent; + classic_theme.tab_selected_overline = classic_theme.accent; // Apply original style settings classic_theme.window_rounding = 0.0f; diff --git a/src/app/gui/theme_manager.h b/src/app/gui/theme_manager.h index 73346329..6d7ab2f7 100644 --- a/src/app/gui/theme_manager.h +++ b/src/app/gui/theme_manager.h @@ -105,6 +105,13 @@ struct EnhancedTheme { Color plot_lines_hovered; Color plot_histogram; Color plot_histogram_hovered; + Color tree_lines; + + // Additional ImGui colors for complete coverage + Color tab_dimmed; + Color tab_dimmed_selected; + Color tab_dimmed_selected_overline; + Color tab_selected_overline; // Style parameters float window_rounding = 0.0f;