diff --git a/ImguiMapEditor/Application.cpp b/ImguiMapEditor/Application.cpp index ede5a4d..4b14b97 100644 --- a/ImguiMapEditor/Application.cpp +++ b/ImguiMapEditor/Application.cpp @@ -66,6 +66,8 @@ bool Application::initialize() { &settings_registry_->getHotkeyRegistry()); dialogs_.preferences.setOtbmSettings( &settings_registry_->getOtbmSettings()); + dialogs_.preferences.setThemePtr( + &settings_registry_->getAppSettings().theme); dialogs_.preferences.setApplySettingsCallback([this]() { settings_registry_->save(); }); diff --git a/ImguiMapEditor/Presentation/MainWindow.cpp b/ImguiMapEditor/Presentation/MainWindow.cpp index 96ab3d8..ab63ebf 100644 --- a/ImguiMapEditor/Presentation/MainWindow.cpp +++ b/ImguiMapEditor/Presentation/MainWindow.cpp @@ -1,12 +1,16 @@ #include "MainWindow.h" #include "Rendering/Frame/RenderingManager.h" #include "Services/ClipboardService.h" +#include "UI/Core/Theme.h" +#include #include #include namespace MapEditor { namespace Presentation { +namespace SC = SemanticColors; + MainWindow::MainWindow(Services::ViewSettings &view_settings, Services::ClientVersionRegistry &version_registry, UI::MapPanel &map_panel, @@ -96,8 +100,8 @@ void MainWindow::renderEditor(Domain::ChunkedMap *current_map, if (is_active) { // Pulsate between Green and Yellow for Active + Modified float t = (sinf((float)ImGui::GetTime() * 5.0f) * 0.5f) + 0.5f; - ImVec4 color_green = ImVec4(0.0f, 0.5f, 0.0f, 0.7f); - ImVec4 color_yellow = ImVec4(1.0f, 0.8f, 0.0f, 0.7f); + ImVec4 color_green = ImVec4(SC::SAVED.x, SC::SAVED.y, SC::SAVED.z, 0.7f); + ImVec4 color_yellow = ImVec4(SC::MODIFIED.x, SC::MODIFIED.y, SC::MODIFIED.z, 0.7f); tab_color.x = color_green.x + (color_yellow.x - color_green.x) * t; tab_color.y = color_green.y + (color_yellow.y - color_green.y) * t; @@ -105,11 +109,11 @@ void MainWindow::renderEditor(Domain::ChunkedMap *current_map, tab_color.w = 0.7f; } else { // Static yellow/gold for Modified - tab_color = ImVec4(0.8f, 0.65f, 0.0f, 0.7f); + tab_color = ImVec4(SC::GOLD.x, SC::GOLD.y, SC::GOLD.z, 0.7f); } } else { // Static green for Active - tab_color = ImVec4(0.0f, 0.5f, 0.0f, 0.7f); + tab_color = ImVec4(SC::SAVED.x, SC::SAVED.y, SC::SAVED.z, 0.7f); } ImGui::PushStyleColor(ImGuiCol_Tab, tab_color); @@ -145,7 +149,7 @@ void MainWindow::renderEditor(Domain::ChunkedMap *current_map, } else { spdlog::error("Error: RenderState not found for session {}", static_cast(session->getID())); - ImGui::TextColored(ImVec4(1, 0, 0, 1), + ImGui::TextColored(SC::DANGER, "Error: RenderState not found for session %d", static_cast(session->getID())); } diff --git a/ImguiMapEditor/UI/Core/Theme.h b/ImguiMapEditor/UI/Core/Theme.h index 09ab25f..05ea86a 100644 --- a/ImguiMapEditor/UI/Core/Theme.h +++ b/ImguiMapEditor/UI/Core/Theme.h @@ -1,25 +1,61 @@ #pragma once -#include // for ranges +#include #include #include -#include "imgui_internal.h" #include #include +// ============================================================================ +// Semantic Colors — universal across all themes +// ============================================================================ +namespace SemanticColors { + // State indicators + inline constexpr ImVec4 MODIFIED { 1.00f, 0.80f, 0.00f, 1.00f }; + inline constexpr ImVec4 SAVED { 0.20f, 0.80f, 0.20f, 1.00f }; + inline constexpr ImVec4 DANGER { 0.90f, 0.30f, 0.30f, 1.00f }; + inline constexpr ImVec4 WARNING { 0.90f, 0.70f, 0.20f, 1.00f }; + inline constexpr ImVec4 INFO { 0.20f, 0.50f, 0.90f, 1.00f }; + inline constexpr ImVec4 GOLD { 1.00f, 0.80f, 0.00f, 1.00f }; + + // Text roles + inline constexpr ImVec4 LABEL { 0.55f, 0.58f, 0.62f, 1.00f }; + inline constexpr ImVec4 VALUE { 0.95f, 0.95f, 0.95f, 1.00f }; + inline constexpr ImVec4 EMPTY { 0.40f, 0.42f, 0.45f, 1.00f }; + inline constexpr ImVec4 HEADER_TEXT { 0.85f, 0.88f, 0.92f, 1.00f }; + inline constexpr ImVec4 MUTED { 0.67f, 0.70f, 0.75f, 1.00f }; + + // Pulse/Glow base + inline constexpr ImVec4 PULSE_BASE { 0.60f, 0.50f, 0.00f, 1.00f }; + + // Misc + inline constexpr float DISABLED_ALPHA = 0.5f; + + // Theme-adaptive text colors (samples from current ImGui style) + inline ImVec4 TextPrimary() { return ImGui::GetStyleColorVec4(ImGuiCol_Text); } + inline ImVec4 TextDim() { return ImGui::GetStyleColorVec4(ImGuiCol_TextDisabled); } + + // Helpers for deriving hover/active variants + constexpr ImVec4 Lighten(const ImVec4& c, float amount = 0.12f) { + return ImVec4(std::clamp(c.x + amount, 0.0f, 1.0f), + std::clamp(c.y + amount, 0.0f, 1.0f), + std::clamp(c.z + amount, 0.0f, 1.0f), c.w); + } + constexpr ImVec4 Darken(const ImVec4& c, float amount = 0.12f) { + return ImVec4(std::clamp(c.x - amount, 0.0f, 1.0f), + std::clamp(c.y - amount, 0.0f, 1.0f), + std::clamp(c.z - amount, 0.0f, 1.0f), c.w); + } +} // namespace SemanticColors -// Theme selection enum +// ============================================================================ +// Theme selection +// ============================================================================ enum class ThemeType { - TibiaRPG = 0, - ModernDark, - ForestGreen, - SunsetOrange, - MidnightPurple, - ClassicLight, - OtclientTheme + ModernDark = 0, + DocumentLight }; -// Theme information for UI display struct ThemeInfo { ThemeType type; const char* name; @@ -27,21 +63,13 @@ struct ThemeInfo { ImVec4 preview_color; }; -// Available themes constexpr ThemeInfo AVAILABLE_THEMES[] = { - { ThemeType::TibiaRPG, "Tibia RPG", "Warm parchment with wood and gold accents", {0.8f, 0.8f, 0.7f, 1.0f} }, { ThemeType::ModernDark, "Modern Dark", "Sleek dark blue with professional look", {0.1f, 0.1f, 0.1f, 1.0f} }, - { ThemeType::ForestGreen, "Forest Green", "Nature-inspired dark green theme", {0.1f, 0.3f, 0.1f, 1.0f} }, - { ThemeType::SunsetOrange, "Sunset Orange", "Warm orange and brown tones", {0.9f, 0.6f, 0.2f, 1.0f} }, - { ThemeType::MidnightPurple, "Midnight Purple", "Deep purple with magenta accents", {0.2f, 0.1f, 0.3f, 1.0f} }, - { ThemeType::ClassicLight, "Classic Light", "Clean light gray theme", {0.9f, 0.9f, 0.9f, 1.0f} }, - { ThemeType::OtclientTheme, "Otclient", "Inspired by otclient", {0.2f, 0.2f, 0.2f, 1.0f} }, + { ThemeType::DocumentLight, "Document Light", "Warm parchment and ink", {0.96f, 0.94f, 0.89f, 1.0f} }, }; -// Kept for backward compatibility, but calculation is now constexpr constexpr size_t THEME_COUNT = std::size(AVAILABLE_THEMES); -// Convert theme enum to string inline const char* GetThemeName(ThemeType type) { const auto it = std::ranges::find(AVAILABLE_THEMES, type, &ThemeInfo::type); if (it != std::end(AVAILABLE_THEMES)) { @@ -50,137 +78,9 @@ inline const char* GetThemeName(ThemeType type) { return "Unknown"; } -// Theme 1: Tibia RPG - Warm parchment aesthetic -inline void ApplyTibiaRPGTheme() { -ImGuiStyle& style = ImGui::GetStyle(); - ImVec4* colors = style.Colors; - - // === GEOMETRIC STYLING === - // Apply slight rounding to mimic worn paper edges, keep scrollbars square for retro feel - style.WindowRounding = 3.0f; // Slightly rounded window corners - style.FrameRounding = 2.0f; // Subtle rounding for input frames - style.GrabRounding = 1.0f; // Minimal rounding for grab handles - style.PopupRounding = 3.0f; // Match window rounding for consistency - style.ScrollbarRounding = 0.0f; // Square scrollbars for retro aesthetic - style.TabRounding = 2.0f; // Gentle tab rounding - style.WindowBorderSize = 1.0f; // Distinct 1px borders for definition - style.FrameBorderSize = 1.0f; // Frame borders for clear input boundaries - style.PopupBorderSize = 1.0f; // Consistent popup borders - - // === COLOR DEFINITIONS === - // Converted from hex to normalized RGB (0.0-1.0) format - - // Primary Colors - ImVec4 color_parchment = ImVec4(0.949f, 0.886f, 0.807f, 1.000f); // #F2E2CE - ImVec4 color_parchment_dark = ImVec4(0.847f, 0.792f, 0.718f, 1.000f); // #D8C8B7 - ImVec4 color_ink = ImVec4(0.102f, 0.094f, 0.086f, 1.000f); // #1A1816 - ImVec4 color_ink_faded = ImVec4(0.400f, 0.400f, 0.400f, 1.000f); // #666666 - ImVec4 color_stone = ImVec4(0.400f, 0.400f, 0.400f, 1.000f); // #666666 - ImVec4 color_stone_dark = ImVec4(0.300f, 0.300f, 0.300f, 1.000f); // #4D4D4D - - // Biome Accents - ImVec4 color_desert_sand = ImVec4(0.949f, 0.753f, 0.580f, 1.000f); // #F2C094 - ImVec4 color_desert_hover = ImVec4(0.965f, 0.827f, 0.655f, 1.000f); // #F6D3A7 - ImVec4 color_desert_active = ImVec4(0.878f, 0.690f, 0.502f, 1.000f); // #E0B080 - ImVec4 color_forest = ImVec4(0.608f, 0.749f, 0.584f, 1.000f); // #9BBF95 - ImVec4 color_forest_hover = ImVec4(0.675f, 0.820f, 0.651f, 1.000f); // #ACD1A6 - ImVec4 color_forest_active = ImVec4(0.541f, 0.678f, 0.518f, 1.000f); // #8AAD84 - ImVec4 color_lime = ImVec4(0.773f, 0.795f, 0.322f, 1.000f); // #C5CB52 - ImVec4 color_lime_hover = ImVec4(0.835f, 0.855f, 0.384f, 1.000f); // #D5D962 - ImVec4 color_lime_active = ImVec4(0.710f, 0.737f, 0.260f, 1.000f); // #B5BC42 - - // Special Elements - ImVec4 color_input_bg = ImVec4(1.000f, 1.000f, 1.000f, 0.400f); // Semi-transparent white - ImVec4 color_input_focus = ImVec4(1.000f, 1.000f, 1.000f, 0.800f); // More opaque when focused - ImVec4 color_selection = ImVec4(0.608f, 0.749f, 0.584f, 0.500f); // Forest green with transparency - ImVec4 color_border = ImVec4(0.400f, 0.400f, 0.400f, 0.600f); // Semi-transparent stone - - // === TEXT COLORS === - colors[ImGuiCol_Text] = color_ink; // Primary text - dark ink - colors[ImGuiCol_TextDisabled] = color_ink_faded; // Disabled text - faded ink - colors[ImGuiCol_TextSelectedBg] = color_selection; // Text selection highlight - - // === WINDOW & CONTAINER BACKGROUNDS === - colors[ImGuiCol_WindowBg] = color_parchment; // Main window background - colors[ImGuiCol_ChildBg] = color_parchment; // Child window background - colors[ImGuiCol_PopupBg] = color_parchment; // Popup background - colors[ImGuiCol_MenuBarBg] = color_parchment_dark; // Menu bar background - - // === BORDERS & SHADOWS === - colors[ImGuiCol_Border] = color_border; // Standard borders - colors[ImGuiCol_BorderShadow] = ImVec4(0.0f, 0.0f, 0.0f, 0.0f); // No shadow - - // === TITLE BARS & HEADERS === - colors[ImGuiCol_TitleBg] = ImVec4(0.400f, 0.400f, 0.400f, 0.600f); // Stone with transparency - colors[ImGuiCol_TitleBgActive] = color_stone; // Active title bar - solid stone - colors[ImGuiCol_TitleBgCollapsed] = ImVec4(0.400f, 0.400f, 0.400f, 0.400f); // Collapsed - more transparent - - // Header elements (for tree nodes, collapsible headers) - colors[ImGuiCol_Header] = color_forest; // Header background - colors[ImGuiCol_HeaderHovered] = color_forest_hover; // Header hover - colors[ImGuiCol_HeaderActive] = color_forest_active; // Header active/clicked - - // === TABS === - colors[ImGuiCol_Tab] = ImVec4(0.949f, 0.753f, 0.580f, 0.600f); // Desert sand with transparency - colors[ImGuiCol_TabHovered] = color_forest_hover; // Tab hover - forest green - colors[ImGuiCol_TabActive] = color_forest; // Active tab - forest green - colors[ImGuiCol_TabUnfocused] = ImVec4(0.949f, 0.753f, 0.580f, 0.400f); // Unfocused tab - more transparent - colors[ImGuiCol_TabUnfocusedActive] = color_parchment_dark; // Unfocused but active tab - - // === BUTTONS === - colors[ImGuiCol_Button] = color_desert_sand; // Primary buttons - desert sand - colors[ImGuiCol_ButtonHovered] = color_desert_hover; // Button hover - lighter sand - colors[ImGuiCol_ButtonActive] = color_desert_active; // Button active - darker sand - - // === INPUT CONTROLS === - colors[ImGuiCol_FrameBg] = color_input_bg; // Input frame background - colors[ImGuiCol_FrameBgHovered] = ImVec4(1.0f, 1.0f, 1.0f, 0.600f); // Frame hover - colors[ImGuiCol_FrameBgActive] = color_input_focus; // Frame focused - - // Checkmarks and radio buttons - colors[ImGuiCol_CheckMark] = color_ink; // Checkmark - dark ink (also used for radio buttons) - - // Sliders and progress bars - colors[ImGuiCol_SliderGrab] = color_stone; // Slider grab - stone grey - colors[ImGuiCol_SliderGrabActive] = color_forest; // Slider grab active - forest green - // Progress bars use FrameBg for background and CheckMark for fill - // Note: ProgressBarBg and ProgressBar don't exist in standard ImGui - - // === SCROLLBARS === - colors[ImGuiCol_ScrollbarBg] = color_parchment_dark; // Scrollbar background - colors[ImGuiCol_ScrollbarGrab] = color_stone; // Scrollbar grab - colors[ImGuiCol_ScrollbarGrabHovered] = color_stone_dark; // Scrollbar grab hover - colors[ImGuiCol_ScrollbarGrabActive] = color_ink_faded; // Scrollbar grab active - - // === RESIZE & SEPARATION === - colors[ImGuiCol_ResizeGrip] = color_stone; // Window resize grip - colors[ImGuiCol_ResizeGripHovered] = color_lime_hover; // Resize grip hover - lime - colors[ImGuiCol_ResizeGripActive] = color_lime_active; // Resize grip active - lime - - // Separators - colors[ImGuiCol_Separator] = color_border; // Separator lines - colors[ImGuiCol_SeparatorHovered] = color_forest_hover; // Separator hover - colors[ImGuiCol_SeparatorActive] = color_forest; // Separator active - - // === PLOTS & GRAPHS === - colors[ImGuiCol_PlotLines] = color_ink_faded; // Graph lines - faded ink - colors[ImGuiCol_PlotLinesHovered] = color_lime; // Graph lines hover - lime - colors[ImGuiCol_PlotHistogram] = color_forest; // Histogram bars - forest green - colors[ImGuiCol_PlotHistogramHovered] = color_lime; // Histogram hover - lime - - // === NAVIGATION & DRAG&DROP === - colors[ImGuiCol_NavHighlight] = color_lime; // Navigation highlight - lime - colors[ImGuiCol_NavWindowingHighlight] = ImVec4(1.0f, 1.0f, 1.0f, 0.700f); // Windowing highlight - colors[ImGuiCol_NavWindowingDimBg] = ImVec4(0.0f, 0.0f, 0.0f, 0.450f); // Windowing dim - - colors[ImGuiCol_DragDropTarget] = color_forest; // Drag & drop target -} - -// Theme 2: Modern Dark - Sleek dark blue theme inline void ApplyModernDarkTheme() { ImGuiStyle& style = ImGui::GetStyle(); - // Geometry style.WindowRounding = 6.0f; style.FrameRounding = 4.0f; style.GrabRounding = 4.0f; @@ -196,7 +96,6 @@ inline void ApplyModernDarkTheme() { ImVec4* colors = style.Colors; - // Color palette - Deep navy and steel blue ImVec4 bg_dark = ImVec4(0.12f, 0.14f, 0.18f, 1.00f); ImVec4 bg_medium = ImVec4(0.18f, 0.20f, 0.25f, 1.00f); ImVec4 bg_light = ImVec4(0.24f, 0.26f, 0.30f, 1.00f); @@ -258,175 +157,12 @@ inline void ApplyModernDarkTheme() { colors[ImGuiCol_ModalWindowDimBg] = ImVec4(0.10f, 0.10f, 0.10f, 0.35f); } -// Theme 3: Forest Green - Nature-inspired dark theme -inline void ApplyForestGreenTheme() { - ImGuiStyle& style = ImGui::GetStyle(); - - // Geometry - style.WindowRounding = 5.0f; - style.FrameRounding = 3.0f; - style.GrabRounding = 3.0f; - style.PopupRounding = 3.0f; - style.ScrollbarRounding = 3.0f; - style.TabRounding = 3.0f; - style.WindowBorderSize = 1.0f; - style.FrameBorderSize = 1.0f; - style.WindowPadding = ImVec2(8.0f, 8.0f); - style.FramePadding = ImVec2(6.0f, 4.0f); - style.ItemSpacing = ImVec2(8.0f, 4.0f); - style.ItemInnerSpacing = ImVec2(4.0f, 4.0f); - - ImVec4* colors = style.Colors; - - // Color palette - Dark forest and moss green - ImVec4 bg_forest = ImVec4(0.10f, 0.15f, 0.12f, 1.00f); - ImVec4 bg_moss = ImVec4(0.15f, 0.22f, 0.18f, 1.00f); - ImVec4 bg_lichen = ImVec4(0.20f, 0.28f, 0.24f, 1.00f); - ImVec4 bg_leaf = ImVec4(0.25f, 0.35f, 0.30f, 1.00f); - ImVec4 accent_lime = ImVec4(0.60f, 0.85f, 0.20f, 1.00f); - ImVec4 accent_hover = ImVec4(0.70f, 0.95f, 0.30f, 1.00f); - ImVec4 accent_active = ImVec4(0.50f, 0.75f, 0.10f, 1.00f); - ImVec4 text_light = ImVec4(0.90f, 0.95f, 0.90f, 1.00f); - ImVec4 text_dim = ImVec4(0.55f, 0.65f, 0.55f, 1.00f); - - colors[ImGuiCol_Text] = text_light; - colors[ImGuiCol_TextDisabled] = text_dim; - colors[ImGuiCol_TextSelectedBg] = ImVec4(0.60f, 0.85f, 0.20f, 0.35f); - colors[ImGuiCol_WindowBg] = bg_forest; - colors[ImGuiCol_ChildBg] = bg_forest; - colors[ImGuiCol_PopupBg] = bg_moss; - colors[ImGuiCol_Border] = ImVec4(0.30f, 0.42f, 0.35f, 0.80f); - colors[ImGuiCol_BorderShadow] = ImVec4(0.00f, 0.00f, 0.00f, 0.00f); - colors[ImGuiCol_TitleBg] = bg_moss; - colors[ImGuiCol_TitleBgActive] = bg_lichen; - colors[ImGuiCol_TitleBgCollapsed] = bg_moss; - colors[ImGuiCol_FrameBg] = bg_moss; - colors[ImGuiCol_FrameBgHovered] = bg_lichen; - colors[ImGuiCol_FrameBgActive] = bg_leaf; - colors[ImGuiCol_Button] = bg_moss; - colors[ImGuiCol_ButtonHovered] = bg_lichen; - colors[ImGuiCol_ButtonActive] = bg_leaf; - colors[ImGuiCol_ScrollbarBg] = bg_forest; - colors[ImGuiCol_ScrollbarGrab] = bg_lichen; - colors[ImGuiCol_ScrollbarGrabHovered] = bg_leaf; - colors[ImGuiCol_ScrollbarGrabActive] = accent_lime; - colors[ImGuiCol_CheckMark] = accent_lime; - colors[ImGuiCol_SliderGrab] = accent_lime; - colors[ImGuiCol_SliderGrabActive] = accent_active; - colors[ImGuiCol_Separator] = ImVec4(0.30f, 0.42f, 0.35f, 0.60f); - colors[ImGuiCol_SeparatorHovered] = accent_hover; - colors[ImGuiCol_SeparatorActive] = accent_active; - colors[ImGuiCol_ResizeGrip] = accent_lime; - colors[ImGuiCol_ResizeGripHovered] = accent_hover; - colors[ImGuiCol_ResizeGripActive] = accent_active; - colors[ImGuiCol_Tab] = bg_moss; - colors[ImGuiCol_TabHovered] = bg_lichen; - colors[ImGuiCol_TabActive] = bg_leaf; - colors[ImGuiCol_TabUnfocused] = bg_moss; - colors[ImGuiCol_TabUnfocusedActive] = bg_lichen; - colors[ImGuiCol_MenuBarBg] = bg_moss; - colors[ImGuiCol_Header] = bg_moss; - colors[ImGuiCol_HeaderHovered] = bg_lichen; - colors[ImGuiCol_HeaderActive] = bg_leaf; - colors[ImGuiCol_TableHeaderBg] = bg_moss; - colors[ImGuiCol_TableBorderStrong] = ImVec4(0.30f, 0.42f, 0.35f, 0.80f); - colors[ImGuiCol_TableBorderLight] = ImVec4(0.20f, 0.32f, 0.25f, 0.50f); - colors[ImGuiCol_TableRowBg] = ImVec4(0.00f, 0.00f, 0.00f, 0.00f); - colors[ImGuiCol_TableRowBgAlt] = ImVec4(0.25f, 0.35f, 0.30f, 0.15f); - colors[ImGuiCol_DragDropTarget] = ImVec4(0.60f, 0.85f, 0.20f, 0.90f); - colors[ImGuiCol_NavHighlight] = accent_lime; - colors[ImGuiCol_NavWindowingHighlight] = accent_hover; - colors[ImGuiCol_NavWindowingDimBg] = ImVec4(0.05f, 0.10f, 0.05f, 0.20f); - colors[ImGuiCol_ModalWindowDimBg] = ImVec4(0.05f, 0.10f, 0.05f, 0.35f); -} - -// Theme 4: Sunset Orange - Warm orange and brown theme -inline void ApplySunsetOrangeTheme() { +// ============================================================================ +// Document Light Theme +// ============================================================================ +inline void ApplyDocumentLightTheme() { ImGuiStyle& style = ImGui::GetStyle(); - // Geometry - style.WindowRounding = 5.0f; - style.FrameRounding = 3.0f; - style.GrabRounding = 3.0f; - style.PopupRounding = 3.0f; - style.ScrollbarRounding = 3.0f; - style.TabRounding = 3.0f; - style.WindowBorderSize = 1.0f; - style.FrameBorderSize = 1.0f; - style.WindowPadding = ImVec2(8.0f, 8.0f); - style.FramePadding = ImVec2(6.0f, 4.0f); - style.ItemSpacing = ImVec2(8.0f, 4.0f); - style.ItemInnerSpacing = ImVec2(4.0f, 4.0f); - - ImVec4* colors = style.Colors; - - // Color palette - Warm sunset colors - ImVec4 bg_dusk = ImVec4(0.18f, 0.12f, 0.10f, 1.00f); - ImVec4 bg_terracotta = ImVec4(0.28f, 0.18f, 0.14f, 1.00f); - ImVec4 bg_clay = ImVec4(0.38f, 0.24f, 0.18f, 1.00f); - ImVec4 bg_sand = ImVec4(0.48f, 0.32f, 0.24f, 1.00f); - ImVec4 accent_orange = ImVec4(1.00f, 0.55f, 0.20f, 1.00f); - ImVec4 accent_hover = ImVec4(1.00f, 0.65f, 0.30f, 1.00f); - ImVec4 accent_active = ImVec4(0.90f, 0.45f, 0.10f, 1.00f); - ImVec4 text_cream = ImVec4(0.95f, 0.92f, 0.88f, 1.00f); - ImVec4 text_dim = ImVec4(0.65f, 0.58f, 0.52f, 1.00f); - - colors[ImGuiCol_Text] = text_cream; - colors[ImGuiCol_TextDisabled] = text_dim; - colors[ImGuiCol_TextSelectedBg] = ImVec4(1.00f, 0.55f, 0.20f, 0.35f); - colors[ImGuiCol_WindowBg] = bg_dusk; - colors[ImGuiCol_ChildBg] = bg_dusk; - colors[ImGuiCol_PopupBg] = bg_terracotta; - colors[ImGuiCol_Border] = ImVec4(0.48f, 0.32f, 0.24f, 0.80f); - colors[ImGuiCol_BorderShadow] = ImVec4(0.00f, 0.00f, 0.00f, 0.00f); - colors[ImGuiCol_TitleBg] = bg_terracotta; - colors[ImGuiCol_TitleBgActive] = bg_clay; - colors[ImGuiCol_TitleBgCollapsed] = bg_terracotta; - colors[ImGuiCol_FrameBg] = bg_terracotta; - colors[ImGuiCol_FrameBgHovered] = bg_clay; - colors[ImGuiCol_FrameBgActive] = bg_sand; - colors[ImGuiCol_Button] = bg_terracotta; - colors[ImGuiCol_ButtonHovered] = bg_clay; - colors[ImGuiCol_ButtonActive] = bg_sand; - colors[ImGuiCol_ScrollbarBg] = bg_dusk; - colors[ImGuiCol_ScrollbarGrab] = bg_clay; - colors[ImGuiCol_ScrollbarGrabHovered] = bg_sand; - colors[ImGuiCol_ScrollbarGrabActive] = accent_orange; - colors[ImGuiCol_CheckMark] = accent_orange; - colors[ImGuiCol_SliderGrab] = accent_orange; - colors[ImGuiCol_SliderGrabActive] = accent_active; - colors[ImGuiCol_Separator] = ImVec4(0.48f, 0.32f, 0.24f, 0.60f); - colors[ImGuiCol_SeparatorHovered] = accent_hover; - colors[ImGuiCol_SeparatorActive] = accent_active; - colors[ImGuiCol_ResizeGrip] = accent_orange; - colors[ImGuiCol_ResizeGripHovered] = accent_hover; - colors[ImGuiCol_ResizeGripActive] = accent_active; - colors[ImGuiCol_Tab] = bg_terracotta; - colors[ImGuiCol_TabHovered] = bg_clay; - colors[ImGuiCol_TabActive] = bg_sand; - colors[ImGuiCol_TabUnfocused] = bg_terracotta; - colors[ImGuiCol_TabUnfocusedActive] = bg_clay; - colors[ImGuiCol_MenuBarBg] = bg_terracotta; - colors[ImGuiCol_Header] = bg_terracotta; - colors[ImGuiCol_HeaderHovered] = bg_clay; - colors[ImGuiCol_HeaderActive] = bg_sand; - colors[ImGuiCol_TableHeaderBg] = bg_terracotta; - colors[ImGuiCol_TableBorderStrong] = ImVec4(0.48f, 0.32f, 0.24f, 0.80f); - colors[ImGuiCol_TableBorderLight] = ImVec4(0.38f, 0.24f, 0.18f, 0.50f); - colors[ImGuiCol_TableRowBg] = ImVec4(0.00f, 0.00f, 0.00f, 0.00f); - colors[ImGuiCol_TableRowBgAlt] = ImVec4(0.38f, 0.24f, 0.18f, 0.15f); - colors[ImGuiCol_DragDropTarget] = ImVec4(1.00f, 0.55f, 0.20f, 0.90f); - colors[ImGuiCol_NavHighlight] = accent_orange; - colors[ImGuiCol_NavWindowingHighlight] = accent_hover; - colors[ImGuiCol_NavWindowingDimBg] = ImVec4(0.18f, 0.10f, 0.08f, 0.20f); - colors[ImGuiCol_ModalWindowDimBg] = ImVec4(0.10f, 0.06f, 0.04f, 0.35f); -} - -// Theme 5: Midnight Purple - Deep purple with magenta accents -inline void ApplyMidnightPurpleTheme() { - ImGuiStyle& style = ImGui::GetStyle(); - - // Geometry style.WindowRounding = 6.0f; style.FrameRounding = 4.0f; style.GrabRounding = 4.0f; @@ -442,278 +178,70 @@ inline void ApplyMidnightPurpleTheme() { ImVec4* colors = style.Colors; - // Color palette - Deep purple and magenta - ImVec4 bg_midnight = ImVec4(0.12f, 0.10f, 0.18f, 1.00f); - ImVec4 bg_violet = ImVec4(0.18f, 0.14f, 0.26f, 1.00f); - ImVec4 bg_plum = ImVec4(0.24f, 0.18f, 0.34f, 1.00f); - ImVec4 bg_lavender = ImVec4(0.32f, 0.24f, 0.42f, 1.00f); - ImVec4 accent_magenta = ImVec4(0.90f, 0.35f, 0.85f, 1.00f); - ImVec4 accent_hover = ImVec4(1.00f, 0.45f, 0.95f, 1.00f); - ImVec4 accent_active = ImVec4(0.80f, 0.25f, 0.75f, 1.00f); - ImVec4 text_pearl = ImVec4(0.95f, 0.93f, 0.98f, 1.00f); - ImVec4 text_dim = ImVec4(0.62f, 0.58f, 0.70f, 1.00f); - - colors[ImGuiCol_Text] = text_pearl; - colors[ImGuiCol_TextDisabled] = text_dim; - colors[ImGuiCol_TextSelectedBg] = ImVec4(0.90f, 0.35f, 0.85f, 0.35f); - colors[ImGuiCol_WindowBg] = bg_midnight; - colors[ImGuiCol_ChildBg] = bg_midnight; - colors[ImGuiCol_PopupBg] = bg_violet; - colors[ImGuiCol_Border] = ImVec4(0.42f, 0.34f, 0.52f, 0.80f); - colors[ImGuiCol_BorderShadow] = ImVec4(0.00f, 0.00f, 0.00f, 0.00f); - colors[ImGuiCol_TitleBg] = bg_violet; - colors[ImGuiCol_TitleBgActive] = bg_plum; - colors[ImGuiCol_TitleBgCollapsed] = bg_violet; - colors[ImGuiCol_FrameBg] = bg_violet; - colors[ImGuiCol_FrameBgHovered] = bg_plum; - colors[ImGuiCol_FrameBgActive] = bg_lavender; - colors[ImGuiCol_Button] = bg_violet; - colors[ImGuiCol_ButtonHovered] = bg_plum; - colors[ImGuiCol_ButtonActive] = bg_lavender; - colors[ImGuiCol_ScrollbarBg] = bg_midnight; - colors[ImGuiCol_ScrollbarGrab] = bg_plum; - colors[ImGuiCol_ScrollbarGrabHovered] = bg_lavender; - colors[ImGuiCol_ScrollbarGrabActive] = accent_magenta; - colors[ImGuiCol_CheckMark] = accent_magenta; - colors[ImGuiCol_SliderGrab] = accent_magenta; - colors[ImGuiCol_SliderGrabActive] = accent_active; - colors[ImGuiCol_Separator] = ImVec4(0.42f, 0.34f, 0.52f, 0.60f); - colors[ImGuiCol_SeparatorHovered] = accent_hover; - colors[ImGuiCol_SeparatorActive] = accent_active; - colors[ImGuiCol_ResizeGrip] = accent_magenta; - colors[ImGuiCol_ResizeGripHovered] = accent_hover; - colors[ImGuiCol_ResizeGripActive] = accent_active; - colors[ImGuiCol_Tab] = bg_violet; - colors[ImGuiCol_TabHovered] = bg_plum; - colors[ImGuiCol_TabActive] = bg_lavender; - colors[ImGuiCol_TabUnfocused] = bg_violet; - colors[ImGuiCol_TabUnfocusedActive] = bg_plum; - colors[ImGuiCol_MenuBarBg] = bg_violet; - colors[ImGuiCol_Header] = bg_violet; - colors[ImGuiCol_HeaderHovered] = bg_plum; - colors[ImGuiCol_HeaderActive] = bg_lavender; - colors[ImGuiCol_TableHeaderBg] = bg_violet; - colors[ImGuiCol_TableBorderStrong] = ImVec4(0.42f, 0.34f, 0.52f, 0.80f); - colors[ImGuiCol_TableBorderLight] = ImVec4(0.32f, 0.24f, 0.42f, 0.50f); - colors[ImGuiCol_TableRowBg] = ImVec4(0.00f, 0.00f, 0.00f, 0.00f); - colors[ImGuiCol_TableRowBgAlt] = ImVec4(0.24f, 0.18f, 0.34f, 0.15f); - colors[ImGuiCol_DragDropTarget] = ImVec4(0.90f, 0.35f, 0.85f, 0.90f); - colors[ImGuiCol_NavHighlight] = accent_magenta; - colors[ImGuiCol_NavWindowingHighlight] = accent_hover; - colors[ImGuiCol_NavWindowingDimBg] = ImVec4(0.12f, 0.08f, 0.18f, 0.20f); - colors[ImGuiCol_ModalWindowDimBg] = ImVec4(0.08f, 0.06f, 0.12f, 0.35f); -} - -// Theme 6: Classic Light - Clean light gray theme -inline void ApplyClassicLightTheme() { - ImGuiStyle& style = ImGui::GetStyle(); - - // Geometry - style.WindowRounding = 4.0f; - style.FrameRounding = 3.0f; - style.GrabRounding = 3.0f; - style.PopupRounding = 3.0f; - style.ScrollbarRounding = 3.0f; - style.TabRounding = 3.0f; - style.WindowBorderSize = 1.0f; - style.FrameBorderSize = 1.0f; - style.WindowPadding = ImVec2(8.0f, 8.0f); - style.FramePadding = ImVec2(6.0f, 4.0f); - style.ItemSpacing = ImVec2(8.0f, 4.0f); - style.ItemInnerSpacing = ImVec2(4.0f, 4.0f); - - ImVec4* colors = style.Colors; - - // Color palette - Clean light grays and blue accent - ImVec4 bg_white = ImVec4(0.96f, 0.97f, 0.98f, 1.00f); - ImVec4 bg_light = ImVec4(0.90f, 0.91f, 0.92f, 1.00f); - ImVec4 bg_medium = ImVec4(0.82f, 0.84f, 0.85f, 1.00f); - ImVec4 bg_dark = ImVec4(0.72f, 0.74f, 0.76f, 1.00f); - ImVec4 accent_blue = ImVec4(0.26f, 0.59f, 0.98f, 1.00f); - ImVec4 accent_hover = ImVec4(0.36f, 0.69f, 1.00f, 1.00f); - ImVec4 accent_active = ImVec4(0.16f, 0.49f, 0.88f, 1.00f); - ImVec4 text_dark = ImVec4(0.10f, 0.12f, 0.14f, 1.00f); - ImVec4 text_dim = ImVec4(0.50f, 0.52f, 0.54f, 1.00f); - - colors[ImGuiCol_Text] = text_dark; + ImVec4 bg_paper = ImVec4(0.96f, 0.94f, 0.89f, 1.00f); + ImVec4 bg_medium = ImVec4(0.90f, 0.88f, 0.83f, 1.00f); + ImVec4 bg_light = ImVec4(0.84f, 0.82f, 0.77f, 1.00f); + ImVec4 bg_lighter = ImVec4(0.77f, 0.75f, 0.70f, 1.00f); + ImVec4 accent_ink = ImVec4(0.18f, 0.32f, 0.62f, 1.00f); + ImVec4 accent_hover = ImVec4(0.24f, 0.42f, 0.78f, 1.00f); + ImVec4 accent_active = ImVec4(0.12f, 0.22f, 0.50f, 1.00f); + ImVec4 text_ink = ImVec4(0.10f, 0.10f, 0.13f, 1.00f); + ImVec4 text_dim = ImVec4(0.42f, 0.42f, 0.46f, 1.00f); + + colors[ImGuiCol_Text] = text_ink; colors[ImGuiCol_TextDisabled] = text_dim; - colors[ImGuiCol_TextSelectedBg] = ImVec4(0.26f, 0.59f, 0.98f, 0.35f); - colors[ImGuiCol_WindowBg] = bg_white; - colors[ImGuiCol_ChildBg] = bg_white; - colors[ImGuiCol_PopupBg] = bg_white; - colors[ImGuiCol_Border] = ImVec4(0.72f, 0.74f, 0.76f, 0.80f); + colors[ImGuiCol_TextSelectedBg] = ImVec4(0.18f, 0.32f, 0.62f, 0.25f); + colors[ImGuiCol_WindowBg] = bg_paper; + colors[ImGuiCol_ChildBg] = bg_paper; + colors[ImGuiCol_PopupBg] = bg_medium; + colors[ImGuiCol_Border] = ImVec4(0.62f, 0.60f, 0.55f, 0.80f); colors[ImGuiCol_BorderShadow] = ImVec4(0.00f, 0.00f, 0.00f, 0.00f); - colors[ImGuiCol_TitleBg] = bg_light; - colors[ImGuiCol_TitleBgActive] = bg_medium; - colors[ImGuiCol_TitleBgCollapsed] = bg_light; - colors[ImGuiCol_FrameBg] = bg_light; - colors[ImGuiCol_FrameBgHovered] = bg_medium; - colors[ImGuiCol_FrameBgActive] = bg_dark; - colors[ImGuiCol_Button] = bg_light; - colors[ImGuiCol_ButtonHovered] = bg_medium; - colors[ImGuiCol_ButtonActive] = bg_dark; - colors[ImGuiCol_ScrollbarBg] = bg_white; - colors[ImGuiCol_ScrollbarGrab] = bg_medium; - colors[ImGuiCol_ScrollbarGrabHovered] = bg_dark; - colors[ImGuiCol_ScrollbarGrabActive] = accent_blue; - colors[ImGuiCol_CheckMark] = accent_blue; - colors[ImGuiCol_SliderGrab] = accent_blue; + colors[ImGuiCol_TitleBg] = bg_medium; + colors[ImGuiCol_TitleBgActive] = bg_light; + colors[ImGuiCol_TitleBgCollapsed] = bg_medium; + colors[ImGuiCol_FrameBg] = bg_medium; + colors[ImGuiCol_FrameBgHovered] = bg_light; + colors[ImGuiCol_FrameBgActive] = bg_lighter; + colors[ImGuiCol_Button] = bg_medium; + colors[ImGuiCol_ButtonHovered] = bg_light; + colors[ImGuiCol_ButtonActive] = bg_lighter; + colors[ImGuiCol_ScrollbarBg] = bg_paper; + colors[ImGuiCol_ScrollbarGrab] = bg_light; + colors[ImGuiCol_ScrollbarGrabHovered] = bg_lighter; + colors[ImGuiCol_ScrollbarGrabActive] = accent_ink; + colors[ImGuiCol_CheckMark] = accent_ink; + colors[ImGuiCol_SliderGrab] = accent_ink; colors[ImGuiCol_SliderGrabActive] = accent_active; - colors[ImGuiCol_Separator] = ImVec4(0.72f, 0.74f, 0.76f, 0.60f); + colors[ImGuiCol_Separator] = ImVec4(0.62f, 0.60f, 0.55f, 0.60f); colors[ImGuiCol_SeparatorHovered] = accent_hover; colors[ImGuiCol_SeparatorActive] = accent_active; - colors[ImGuiCol_ResizeGrip] = accent_blue; + colors[ImGuiCol_ResizeGrip] = accent_ink; colors[ImGuiCol_ResizeGripHovered] = accent_hover; colors[ImGuiCol_ResizeGripActive] = accent_active; - colors[ImGuiCol_Tab] = bg_light; - colors[ImGuiCol_TabHovered] = bg_medium; - colors[ImGuiCol_TabActive] = bg_dark; - colors[ImGuiCol_TabUnfocused] = bg_light; - colors[ImGuiCol_TabUnfocusedActive] = bg_medium; - colors[ImGuiCol_MenuBarBg] = bg_light; - colors[ImGuiCol_Header] = bg_light; - colors[ImGuiCol_HeaderHovered] = bg_medium; - colors[ImGuiCol_HeaderActive] = bg_dark; - colors[ImGuiCol_TableHeaderBg] = bg_light; - colors[ImGuiCol_TableBorderStrong] = ImVec4(0.72f, 0.74f, 0.76f, 0.80f); - colors[ImGuiCol_TableBorderLight] = ImVec4(0.82f, 0.84f, 0.85f, 0.50f); + colors[ImGuiCol_Tab] = bg_medium; + colors[ImGuiCol_TabHovered] = bg_light; + colors[ImGuiCol_TabActive] = bg_lighter; + colors[ImGuiCol_TabUnfocused] = bg_medium; + colors[ImGuiCol_TabUnfocusedActive] = bg_light; + colors[ImGuiCol_MenuBarBg] = bg_medium; + colors[ImGuiCol_Header] = bg_medium; + colors[ImGuiCol_HeaderHovered] = bg_light; + colors[ImGuiCol_HeaderActive] = bg_lighter; + colors[ImGuiCol_TableHeaderBg] = bg_medium; + colors[ImGuiCol_TableBorderStrong] = ImVec4(0.62f, 0.60f, 0.55f, 0.80f); + colors[ImGuiCol_TableBorderLight] = ImVec4(0.75f, 0.73f, 0.68f, 0.50f); colors[ImGuiCol_TableRowBg] = ImVec4(0.00f, 0.00f, 0.00f, 0.00f); - colors[ImGuiCol_TableRowBgAlt] = ImVec4(0.90f, 0.91f, 0.92f, 0.30f); - colors[ImGuiCol_DragDropTarget] = ImVec4(0.26f, 0.59f, 0.98f, 0.90f); - colors[ImGuiCol_NavHighlight] = accent_blue; + colors[ImGuiCol_TableRowBgAlt] = ImVec4(0.60f, 0.58f, 0.53f, 0.12f); + colors[ImGuiCol_DragDropTarget] = ImVec4(0.18f, 0.32f, 0.62f, 0.90f); + colors[ImGuiCol_NavHighlight] = accent_ink; colors[ImGuiCol_NavWindowingHighlight] = accent_hover; colors[ImGuiCol_NavWindowingDimBg] = ImVec4(0.80f, 0.80f, 0.80f, 0.20f); - colors[ImGuiCol_ModalWindowDimBg] = ImVec4(0.60f, 0.60f, 0.60f, 0.35f); + colors[ImGuiCol_ModalWindowDimBg] = ImVec4(0.70f, 0.70f, 0.70f, 0.35f); } -// Forward declaration -inline void ApplyOtclientTheme(); - -// Main function to apply theme by type inline void ApplyTheme(ThemeType type) { switch (type) { - case ThemeType::TibiaRPG: - ApplyTibiaRPGTheme(); - break; - case ThemeType::ModernDark: - ApplyModernDarkTheme(); - break; - case ThemeType::ForestGreen: - ApplyForestGreenTheme(); - break; - case ThemeType::SunsetOrange: - ApplySunsetOrangeTheme(); - break; - case ThemeType::MidnightPurple: - ApplyMidnightPurpleTheme(); - break; - case ThemeType::ClassicLight: - ApplyClassicLightTheme(); - break; - default: - ApplyOtclientTheme(); // - break; + case ThemeType::DocumentLight: ApplyDocumentLightTheme(); break; + default: ApplyModernDarkTheme(); break; } } - -inline void ApplyOtclientTheme() - { - ImGuiStyle& style = ImGui::GetStyle(); - ImVec4* colors = style.Colors; - - // === Style variables (rounding, spacing, etc.) === - style.WindowPadding = ImVec2(8, 8); - style.FramePadding = ImVec2(6, 4); - style.CellPadding = ImVec2(4, 2); - style.ItemSpacing = ImVec2(8, 6); - style.ItemInnerSpacing = ImVec2(4, 4); - style.TouchExtraPadding = ImVec2(0, 0); - style.IndentSpacing = 21.0f; - style.ScrollbarSize = 14.0f; - style.GrabMinSize = 10.0f; - - style.WindowRounding = 5.0f; - style.ChildRounding = 5.0f; - style.FrameRounding = 4.0f; - style.PopupRounding = 4.0f; - style.ScrollbarRounding = 9.0f; - style.GrabRounding = 3.0f; - style.TabRounding = 4.0f; - style.WindowTitleAlign = ImVec2(0.0f, 0.5f); - style.WindowMenuButtonPosition = ImGuiDir_None; - style.WindowBorderSize = 1.0f; - style.ChildBorderSize = 1.0f; - style.PopupBorderSize = 1.0f; - style.FrameBorderSize = 0.0f; - style.TabBorderSize = 0.0f; - - // === All 56+ colors — nothing is left default === - colors[ImGuiCol_Text] = ImVec4(1.00f, 1.00f, 1.00f, 1.00f); - colors[ImGuiCol_TextDisabled] = ImVec4(0.60f, 0.60f, 0.60f, 1.00f); - colors[ImGuiCol_WindowBg] = ImVec4(0.200f, 0.200f, 0.200f, 1.00f); // #333333 - colors[ImGuiCol_ChildBg] = ImVec4(0.165f, 0.165f, 0.165f, 1.00f); - colors[ImGuiCol_PopupBg] = ImVec4(0.180f, 0.180f, 0.180f, 1.00f); - colors[ImGuiCol_Border] = ImVec4(0.400f, 0.400f, 0.400f, 1.00f); // #666666 - colors[ImGuiCol_BorderShadow] = ImVec4(0.00f, 0.00f, 0.00f, 0.00f); - - colors[ImGuiCol_FrameBg] = ImVec4(0.165f, 0.165f, 0.165f, 1.00f); - colors[ImGuiCol_FrameBgHovered] = ImVec4(0.240f, 0.240f, 0.240f, 1.00f); - colors[ImGuiCol_FrameBgActive] = ImVec4(0.300f, 0.300f, 0.300f, 1.00f); - - colors[ImGuiCol_TitleBg] = ImVec4(0.180f, 0.180f, 0.180f, 1.00f); - colors[ImGuiCol_TitleBgActive] = ImVec4(0.200f, 0.200f, 0.200f, 1.00f); - colors[ImGuiCol_TitleBgCollapsed] = ImVec4(0.000f, 0.000f, 0.000f, 0.510f); - - colors[ImGuiCol_MenuBarBg] = ImVec4(0.160f, 0.160f, 0.160f, 1.00f); - colors[ImGuiCol_ScrollbarBg] = ImVec4(0.100f, 0.100f, 0.100f, 0.53f); - colors[ImGuiCol_ScrollbarGrab] = ImVec4(0.31f, 0.31f, 0.31f, 1.00f); - colors[ImGuiCol_ScrollbarGrabHovered] = ImVec4(0.41f, 0.41f, 0.41f, 1.00f); - colors[ImGuiCol_ScrollbarGrabActive] = ImVec4(0.51f, 0.51f, 0.51f, 1.00f); - - colors[ImGuiCol_CheckMark] = ImVec4(1.00f, 1.00f, 1.00f, 1.00f); - colors[ImGuiCol_SliderGrab] = ImVec4(0.52f, 0.52f, 0.52f, 1.00f); - colors[ImGuiCol_SliderGrabActive] = ImVec4(0.70f, 0.70f, 0.70f, 1.00f); - - colors[ImGuiCol_Button] = ImVec4(0.250f, 0.250f, 0.250f, 1.00f); - colors[ImGuiCol_ButtonHovered] = ImVec4(0.330f, 0.330f, 0.330f, 1.00f); - colors[ImGuiCol_ButtonActive] = ImVec4(0.400f, 0.400f, 0.400f, 1.00f); - - colors[ImGuiCol_Header] = ImVec4(0.250f, 0.250f, 0.250f, 1.00f); - colors[ImGuiCol_HeaderHovered] = ImVec4(0.350f, 0.350f, 0.350f, 1.00f); - colors[ImGuiCol_HeaderActive] = ImVec4(0.420f, 0.420f, 0.420f, 1.00f); - - colors[ImGuiCol_Separator] = ImVec4(0.400f, 0.400f, 0.400f, 1.00f); - colors[ImGuiCol_SeparatorHovered] = ImVec4(0.50f, 0.50f, 0.50f, 1.00f); - colors[ImGuiCol_SeparatorActive] = ImVec4(0.70f, 0.70f, 0.70f, 1.00f); - - colors[ImGuiCol_ResizeGrip] = ImVec4(0.26f, 0.26f, 0.26f, 0.40f); - colors[ImGuiCol_ResizeGripHovered] = ImVec4(0.45f, 0.45f, 0.45f, 0.67f); - colors[ImGuiCol_ResizeGripActive] = ImVec4(0.65f, 0.65f, 0.65f, 0.95f); - - colors[ImGuiCol_Tab] = ImVec4(0.180f, 0.180f, 0.180f, 1.00f); - colors[ImGuiCol_TabHovered] = ImVec4(0.38f, 0.38f, 0.38f, 1.00f); - colors[ImGuiCol_TabActive] = ImVec4(0.30f, 0.30f, 0.30f, 1.00f); - colors[ImGuiCol_TabUnfocused] = ImVec4(0.16f, 0.16f, 0.16f, 1.00f); - colors[ImGuiCol_TabUnfocusedActive] = ImVec4(0.24f, 0.24f, 0.24f, 1.00f); - - colors[ImGuiCol_DockingPreview] = ImVec4(0.26f, 0.59f, 0.98f, 0.70f); - colors[ImGuiCol_DockingEmptyBg] = ImVec4(0.20f, 0.20f, 0.20f, 1.00f); - - colors[ImGuiCol_PlotLines] = ImVec4(0.61f, 0.61f, 0.61f, 1.00f); - colors[ImGuiCol_PlotLinesHovered] = ImVec4(1.00f, 0.80f, 0.00f, 1.00f); - colors[ImGuiCol_PlotHistogram] = ImVec4(0.80f, 0.70f, 0.00f, 1.00f); - colors[ImGuiCol_PlotHistogramHovered] = ImVec4(1.00f, 0.90f, 0.00f, 1.00f); - - colors[ImGuiCol_TableHeaderBg] = ImVec4(0.19f, 0.19f, 0.20f, 1.00f); - colors[ImGuiCol_TableBorderStrong] = ImVec4(0.40f, 0.40f, 0.40f, 1.00f); - colors[ImGuiCol_TableBorderLight] = ImVec4(0.35f, 0.35f, 0.35f, 1.00f); - colors[ImGuiCol_TableRowBg] = ImVec4(0.00f, 0.00f, 0.00f, 0.00f); - colors[ImGuiCol_TableRowBgAlt] = ImVec4(1.00f, 1.00f, 1.00f, 0.06f); - - colors[ImGuiCol_TextSelectedBg] = ImVec4(0.26f, 0.59f, 0.98f, 0.35f); - colors[ImGuiCol_DragDropTarget] = ImVec4(1.00f, 1.00f, 0.00f, 0.90f); - colors[ImGuiCol_NavHighlight] = ImVec4(0.60f, 0.60f, 0.60f, 1.00f); - colors[ImGuiCol_NavWindowingHighlight] = ImVec4(1.00f, 1.00f, 1.00f, 0.70f); - colors[ImGuiCol_NavWindowingDimBg] = ImVec4(0.80f, 0.80f, 0.80f, 0.20f); - colors[ImGuiCol_ModalWindowDimBg] = ImVec4(0.10f, 0.10f, 0.10f, 0.60f); - } diff --git a/ImguiMapEditor/UI/Dialogs/ClientConfiguration/ClientConfigurationDialog.cpp b/ImguiMapEditor/UI/Dialogs/ClientConfiguration/ClientConfigurationDialog.cpp index b21975b..0bd97ec 100644 --- a/ImguiMapEditor/UI/Dialogs/ClientConfiguration/ClientConfigurationDialog.cpp +++ b/ImguiMapEditor/UI/Dialogs/ClientConfiguration/ClientConfigurationDialog.cpp @@ -1,4 +1,5 @@ #include "UI/Dialogs/ClientConfiguration/ClientConfigurationDialog.h" +#include "UI/Core/Theme.h" #include "UI/Dialogs/ClientConfiguration/ClientPropertyEditor.h" #include "Presentation/Dialogs/ClientConfigurationController.h" #include "Domain/ClientVersion.h" @@ -26,14 +27,14 @@ void pushCompactStyle() { } void popCompactStyle() { ImGui::PopStyleVar(5); } -constexpr ImVec4 kBlueAccent = ImVec4(0.19f, 0.44f, 0.84f, 1.0f); -constexpr ImVec4 kBlueHover = ImVec4(0.25f, 0.50f, 0.92f, 1.0f); -constexpr ImVec4 kBlueActive = ImVec4(0.15f, 0.38f, 0.76f, 1.0f); -constexpr ImVec4 kRedDelete = ImVec4(0.78f, 0.14f, 0.20f, 1.0f); -constexpr ImVec4 kRedHover = ImVec4(0.86f, 0.20f, 0.27f, 1.0f); -constexpr ImVec4 kGreenStatus = ImVec4(0.43f, 0.82f, 0.43f, 1.0f); -constexpr ImVec4 kTextOffWhite = ImVec4(0.85f, 0.87f, 0.91f, 1.0f); -constexpr ImVec4 kTextMuted = ImVec4(0.67f, 0.70f, 0.75f, 1.0f); +constexpr ImVec4 kBlueAccent = SemanticColors::INFO; +constexpr ImVec4 kBlueHover = SemanticColors::Lighten(SemanticColors::INFO); +constexpr ImVec4 kBlueActive = SemanticColors::Darken(SemanticColors::INFO); +constexpr ImVec4 kRedDelete = SemanticColors::DANGER; +constexpr ImVec4 kRedHover = SemanticColors::Lighten(SemanticColors::DANGER); +constexpr ImVec4 kGreenStatus = SemanticColors::SAVED; +constexpr ImVec4 kTextOffWhite = SemanticColors::HEADER_TEXT; +constexpr ImVec4 kTextMuted = SemanticColors::MUTED; } // namespace diff --git a/ImguiMapEditor/UI/Dialogs/ClientConfiguration/ClientPropertyEditor.cpp b/ImguiMapEditor/UI/Dialogs/ClientConfiguration/ClientPropertyEditor.cpp index 09ca20b..3078b6c 100644 --- a/ImguiMapEditor/UI/Dialogs/ClientConfiguration/ClientPropertyEditor.cpp +++ b/ImguiMapEditor/UI/Dialogs/ClientConfiguration/ClientPropertyEditor.cpp @@ -1,4 +1,5 @@ #include "UI/Dialogs/ClientConfiguration/ClientPropertyEditor.h" +#include "UI/Core/Theme.h" #include "Presentation/Dialogs/ClientConfigurationController.h" #include "Services/ClientVersionRegistry.h" #include @@ -36,13 +37,13 @@ ImVec4 blend(const ImVec4& a, const ImVec4& b, float t) { a.z + (b.z - a.z) * t, a.w + (b.w - a.w) * t); } -constexpr ImVec4 kRed = ImVec4(0.6f, 0.15f, 0.15f, 1.0f); -constexpr ImVec4 kYellow = ImVec4(0.6f, 0.5f, 0.0f, 1.0f); -constexpr ImVec4 kGreen = ImVec4(0.15f, 0.55f, 0.15f, 1.0f); -constexpr ImVec4 kTextMuted = ImVec4(0.67f, 0.70f, 0.75f, 1.0f); -constexpr ImVec4 kGreenStatus = ImVec4(0.43f, 0.82f, 0.43f, 1.0f); -constexpr ImVec4 kBlueAccent = ImVec4(0.19f, 0.44f, 0.84f, 1.0f); -constexpr ImVec4 kBlueHover = ImVec4(0.25f, 0.50f, 0.92f, 1.0f); +constexpr ImVec4 kRed = SemanticColors::DANGER; +constexpr ImVec4 kYellow = SemanticColors::PULSE_BASE; +constexpr ImVec4 kGreen = SemanticColors::SAVED; +constexpr ImVec4 kTextMuted = SemanticColors::MUTED; +constexpr ImVec4 kGreenStatus = SemanticColors::SAVED; +constexpr ImVec4 kBlueAccent = SemanticColors::INFO; +constexpr ImVec4 kBlueHover = SemanticColors::Lighten(SemanticColors::INFO); float labelColumn() { return 195.0f; } diff --git a/ImguiMapEditor/UI/Dialogs/ConfirmationDialog.cpp b/ImguiMapEditor/UI/Dialogs/ConfirmationDialog.cpp index 5ac3a9e..368172e 100644 --- a/ImguiMapEditor/UI/Dialogs/ConfirmationDialog.cpp +++ b/ImguiMapEditor/UI/Dialogs/ConfirmationDialog.cpp @@ -1,4 +1,5 @@ #include "ConfirmationDialog.h" +#include "UI/Core/Theme.h" #include #include diff --git a/ImguiMapEditor/UI/Dialogs/EditTownsDialog.cpp b/ImguiMapEditor/UI/Dialogs/EditTownsDialog.cpp index bafb666..fb32b6d 100644 --- a/ImguiMapEditor/UI/Dialogs/EditTownsDialog.cpp +++ b/ImguiMapEditor/UI/Dialogs/EditTownsDialog.cpp @@ -2,6 +2,7 @@ #include "Application/MapTabManager.h" #include "Application/EditorSession.h" #include "Domain/MapInstance.h" +#include "UI/Core/Theme.h" #include #include #include @@ -10,13 +11,9 @@ namespace MapEditor { namespace UI { +namespace SC = SemanticColors; + static constexpr ImVec4 kModifiedYellow{0.50f, 0.42f, 0.14f, 1.0f}; -static constexpr ImVec4 kDangerRed{0.70f, 0.18f, 0.18f, 1.0f}; -static constexpr ImVec4 kDangerRedHover{0.80f, 0.25f, 0.25f, 1.0f}; -static constexpr ImVec4 kDangerRedActive{0.60f, 0.12f, 0.12f, 1.0f}; -static constexpr ImVec4 kGoToBlue{0.18f, 0.40f, 0.65f, 1.0f}; -static constexpr ImVec4 kGoToBlueHover{0.22f, 0.48f, 0.75f, 1.0f}; -static constexpr ImVec4 kGoToBlueActive{0.14f, 0.35f, 0.58f, 1.0f}; static float bounceOffset() { return std::sin(static_cast(ImGui::GetTime()) * 3.0f) * 3.0f; @@ -160,9 +157,9 @@ EditTownsDialog::Result EditTownsDialog::render() { ImGui::TextDisabled("ID %u: %s", towns_[selected_index_].id, towns_[selected_index_].name.c_str()); ImGui::Spacing(); - ImGui::PushStyleColor(ImGuiCol_Button, ImVec4(0.8f, 0.2f, 0.2f, 1.0f)); - ImGui::PushStyleColor(ImGuiCol_ButtonHovered, ImVec4(0.9f, 0.3f, 0.3f, 1.0f)); - ImGui::PushStyleColor(ImGuiCol_ButtonActive, ImVec4(0.7f, 0.1f, 0.1f, 1.0f)); + ImGui::PushStyleColor(ImGuiCol_Button, SC::DANGER); + ImGui::PushStyleColor(ImGuiCol_ButtonHovered, SC::Lighten(SC::DANGER)); + ImGui::PushStyleColor(ImGuiCol_ButtonActive, SC::Darken(SC::DANGER)); if (ImGui::Button(ICON_FA_TRASH " Yes, Remove", ImVec2(120, 0))) { uint32_t removed_id = towns_[selected_index_].id; @@ -332,9 +329,9 @@ EditTownsDialog::Result EditTownsDialog::render() { ImGui::Spacing(); - ImGui::PushStyleColor(ImGuiCol_Button, kDangerRed); - ImGui::PushStyleColor(ImGuiCol_ButtonHovered, kDangerRedHover); - ImGui::PushStyleColor(ImGuiCol_ButtonActive, kDangerRedActive); + ImGui::PushStyleColor(ImGuiCol_Button, SC::DANGER); + ImGui::PushStyleColor(ImGuiCol_ButtonHovered, SC::Lighten(SC::DANGER)); + ImGui::PushStyleColor(ImGuiCol_ButtonActive, SC::Darken(SC::DANGER)); if (ImGui::Button(ICON_FA_CROSSHAIRS " Change Temple Position", ImVec2(-1, 0))) { if (on_pick_position_ && on_pick_position_()) { is_picking_position_ = true; @@ -345,9 +342,9 @@ EditTownsDialog::Result EditTownsDialog::render() { ImGui::SetTooltip("Click on map to set temple position"); } - ImGui::PushStyleColor(ImGuiCol_Button, kGoToBlue); - ImGui::PushStyleColor(ImGuiCol_ButtonHovered, kGoToBlueHover); - ImGui::PushStyleColor(ImGuiCol_ButtonActive, kGoToBlueActive); + ImGui::PushStyleColor(ImGuiCol_Button, SC::INFO); + ImGui::PushStyleColor(ImGuiCol_ButtonHovered, SC::Lighten(SC::INFO)); + ImGui::PushStyleColor(ImGuiCol_ButtonActive, SC::Darken(SC::INFO)); if (ImGui::Button(ICON_FA_LOCATION_DOT " Go To Position", ImVec2(-1, 0))) { if (has_selection && on_go_to_) { on_go_to_(towns_[selected_index_].temple_position); @@ -359,7 +356,7 @@ EditTownsDialog::Result EditTownsDialog::render() { } if (is_picking_position_) { - ImGui::TextColored(ImVec4(1.0f, 0.8f, 0.0f, 1.0f), + ImGui::TextColored(SC::GOLD, ICON_FA_CROSSHAIRS " Click on map to select..."); } @@ -386,9 +383,9 @@ EditTownsDialog::Result EditTownsDialog::render() { bool flash_active = flash_age < 1.0f && flash_age > 0.0f; if (flash_active) { - ImGui::PushStyleColor(ImGuiCol_Button, ImVec4(0.15f, 0.55f, 0.15f, 1.0f)); - ImGui::PushStyleColor(ImGuiCol_ButtonHovered, ImVec4(0.18f, 0.65f, 0.18f, 1.0f)); - ImGui::PushStyleColor(ImGuiCol_ButtonActive, ImVec4(0.12f, 0.50f, 0.12f, 1.0f)); + ImGui::PushStyleColor(ImGuiCol_Button, SC::SAVED); + ImGui::PushStyleColor(ImGuiCol_ButtonHovered, SC::Lighten(SC::SAVED)); + ImGui::PushStyleColor(ImGuiCol_ButtonActive, SC::Darken(SC::SAVED)); } if (ImGui::Button(ICON_FA_FLOPPY_DISK " Apply", ImVec2(button_w, 0))) { @@ -403,9 +400,9 @@ EditTownsDialog::Result EditTownsDialog::render() { ImGui::SameLine(); - ImGui::PushStyleColor(ImGuiCol_Button, ImVec4(0.20f, 0.45f, 0.70f, 1.0f)); - ImGui::PushStyleColor(ImGuiCol_ButtonHovered, ImVec4(0.25f, 0.55f, 0.80f, 1.0f)); - ImGui::PushStyleColor(ImGuiCol_ButtonActive, ImVec4(0.15f, 0.40f, 0.65f, 1.0f)); + ImGui::PushStyleColor(ImGuiCol_Button, SC::INFO); + ImGui::PushStyleColor(ImGuiCol_ButtonHovered, SC::Lighten(SC::INFO)); + ImGui::PushStyleColor(ImGuiCol_ButtonActive, SC::Darken(SC::INFO)); if (ImGui::Button(ICON_FA_CHECK " OK", ImVec2(button_w, 0))) { applyChangesToMap(); diff --git a/ImguiMapEditor/UI/Dialogs/MapCompatibilityPopup.cpp b/ImguiMapEditor/UI/Dialogs/MapCompatibilityPopup.cpp index 344be7e..bccb557 100644 --- a/ImguiMapEditor/UI/Dialogs/MapCompatibilityPopup.cpp +++ b/ImguiMapEditor/UI/Dialogs/MapCompatibilityPopup.cpp @@ -1,4 +1,5 @@ #include "MapCompatibilityPopup.h" +#include "UI/Core/Theme.h" #include "ext/fontawesome6/IconsFontAwesome6.h" #include @@ -6,6 +7,8 @@ namespace MapEditor { namespace UI { +namespace SC = SemanticColors; + void MapCompatibilityPopup::show(const MapCompatibilityResult &compat, const std::filesystem::path &map_path) { compat_info_ = compat; @@ -33,7 +36,7 @@ void MapCompatibilityPopup::render() { if (ImGui::BeginPopupModal("Map Compatibility Warning", &is_open_, ImGuiWindowFlags_AlwaysAutoResize)) { // Warning icon and title - ImGui::TextColored(ImVec4(1.0f, 0.7f, 0.0f, 1.0f), + ImGui::TextColored(SC::WARNING, ICON_FA_TRIANGLE_EXCLAMATION " Version Mismatch"); ImGui::Separator(); ImGui::Spacing(); @@ -79,11 +82,9 @@ void MapCompatibilityPopup::render() { ImGui::SameLine(); // Force load button - warning color - ImGui::PushStyleColor(ImGuiCol_Button, ImVec4(0.7f, 0.4f, 0.0f, 1.0f)); - ImGui::PushStyleColor(ImGuiCol_ButtonHovered, - ImVec4(0.8f, 0.5f, 0.0f, 1.0f)); - ImGui::PushStyleColor(ImGuiCol_ButtonActive, - ImVec4(0.6f, 0.3f, 0.0f, 1.0f)); + ImGui::PushStyleColor(ImGuiCol_Button, SC::WARNING); + ImGui::PushStyleColor(ImGuiCol_ButtonHovered, SC::Lighten(SC::WARNING)); + ImGui::PushStyleColor(ImGuiCol_ButtonActive, SC::Darken(SC::WARNING)); if (ImGui::Button(ICON_FA_BOLT " Force Load", ImVec2(button_width, 0))) { result_ = Result::ForceLoad; is_open_ = false; diff --git a/ImguiMapEditor/UI/Dialogs/NewMapDialog.cpp b/ImguiMapEditor/UI/Dialogs/NewMapDialog.cpp index c147b35..63e0fc7 100644 --- a/ImguiMapEditor/UI/Dialogs/NewMapDialog.cpp +++ b/ImguiMapEditor/UI/Dialogs/NewMapDialog.cpp @@ -1,11 +1,14 @@ #include "NewMapDialog.h" #include "Core/Config.h" +#include "UI/Core/Theme.h" #include "ext/fontawesome6/IconsFontAwesome6.h" #include namespace MapEditor { namespace UI { +namespace SC = SemanticColors; + void NewMapDialog::initialize(Services::ClientVersionRegistry *registry) { panel_.initialize(registry); } @@ -49,10 +52,10 @@ void NewMapDialog::render() { if (ImGui::BeginTabItem("SEC")) { ImGui::Spacing(); - ImGui::TextColored(ImVec4(0.55f, 0.58f, 0.62f, 1.0f), + ImGui::TextColored(SC::LABEL, ICON_FA_CLOCK " Coming soon"); ImGui::Spacing(); - ImGui::TextColored(ImVec4(0.4f, 0.42f, 0.45f, 1.0f), + ImGui::TextColored(SC::EMPTY, "SEC format support is not yet implemented."); ImGui::EndTabItem(); } @@ -81,12 +84,11 @@ void NewMapDialog::render() { !state_.map_name.empty() && state_.selected_template_index >= 0; if (!can_create) { - ImGui::PushStyleVar(ImGuiStyleVar_Alpha, 0.5f); + ImGui::PushStyleVar(ImGuiStyleVar_Alpha, SC::DISABLED_ALPHA); } - ImGui::PushStyleColor(ImGuiCol_Button, ImVec4(0.20f, 0.45f, 0.70f, 1.0f)); - ImGui::PushStyleColor(ImGuiCol_ButtonHovered, - ImVec4(0.28f, 0.55f, 0.80f, 1.0f)); + ImGui::PushStyleColor(ImGuiCol_Button, SC::INFO); + ImGui::PushStyleColor(ImGuiCol_ButtonHovered, SC::Lighten(SC::INFO)); if (ImGui::Button(ICON_FA_CHECK " Create Map", ImVec2(button_width, 0)) && can_create) { diff --git a/ImguiMapEditor/UI/Dialogs/Properties/ItemPropertiesDialog.cpp b/ImguiMapEditor/UI/Dialogs/Properties/ItemPropertiesDialog.cpp index bb84777..0cff322 100644 --- a/ImguiMapEditor/UI/Dialogs/Properties/ItemPropertiesDialog.cpp +++ b/ImguiMapEditor/UI/Dialogs/Properties/ItemPropertiesDialog.cpp @@ -1,4 +1,5 @@ #include "ItemPropertiesDialog.h" +#include "UI/Core/Theme.h" #include "Core/Config.h" #include "Domain/ItemType.h" #include "Domain/Position.h" diff --git a/ImguiMapEditor/UI/Dialogs/Startup/AvailableClientsPanel.cpp b/ImguiMapEditor/UI/Dialogs/Startup/AvailableClientsPanel.cpp index b4ff7bb..296b95a 100644 --- a/ImguiMapEditor/UI/Dialogs/Startup/AvailableClientsPanel.cpp +++ b/ImguiMapEditor/UI/Dialogs/Startup/AvailableClientsPanel.cpp @@ -1,4 +1,5 @@ #include "AvailableClientsPanel.h" +#include "UI/Core/Theme.h" #include #include #include @@ -6,8 +7,10 @@ namespace MapEditor { namespace UI { +namespace SC = SemanticColors; + void AvailableClientsPanel::render() { - ImGui::TextColored(ImVec4(0.85f, 0.88f, 0.92f, 1.0f), "Available Clients"); + ImGui::TextColored(SC::TextPrimary(), "Available Clients"); ImGui::Spacing(); ImGui::Separator(); ImGui::Spacing(); @@ -34,13 +37,11 @@ void AvailableClientsPanel::render() { ImGui::PushID(static_cast(index)); if (is_selected) { - ImGui::PushStyleColor(ImGuiCol_Header, ImVec4(0.25f, 0.45f, 0.70f, 0.9f)); - ImGui::PushStyleColor(ImGuiCol_HeaderHovered, - ImVec4(0.30f, 0.50f, 0.75f, 1.0f)); + ImGui::PushStyleColor(ImGuiCol_Header, ImGui::GetStyleColorVec4(ImGuiCol_HeaderActive)); + ImGui::PushStyleColor(ImGuiCol_HeaderHovered, ImGui::GetStyleColorVec4(ImGuiCol_HeaderHovered)); } else { - ImGui::PushStyleColor(ImGuiCol_Header, ImVec4(0.18f, 0.20f, 0.24f, 0.6f)); - ImGui::PushStyleColor(ImGuiCol_HeaderHovered, - ImVec4(0.22f, 0.25f, 0.30f, 0.8f)); + ImGui::PushStyleColor(ImGuiCol_Header, ImGui::GetStyleColorVec4(ImGuiCol_Header)); + ImGui::PushStyleColor(ImGuiCol_HeaderHovered, ImGui::GetStyleColorVec4(ImGuiCol_HeaderHovered)); } float item_height = 60.0f; @@ -60,7 +61,7 @@ void AvailableClientsPanel::render() { // Bookmark icon ImGui::BeginGroup(); ImGui::SetCursorPosY(ImGui::GetCursorPosY() + 12.0f); - ImGui::PushStyleColor(ImGuiCol_Text, ImVec4(0.85f, 0.65f, 0.30f, 1.0f)); + ImGui::PushStyleColor(ImGuiCol_Text, SC::GOLD); ImGui::Text(ICON_FA_BOOKMARK); ImGui::PopStyleColor(); ImGui::EndGroup(); @@ -70,7 +71,7 @@ void AvailableClientsPanel::render() { // Client name and version info ImGui::BeginGroup(); ImGui::SetCursorPosY(ImGui::GetCursorPosY() + 4.0f); - ImGui::TextColored(ImVec4(0.43f, 0.82f, 0.43f, 1.0f), "%s", + ImGui::TextColored(SC::TextPrimary(), "%s", client->getName().c_str()); const char* type_str = "???"; @@ -79,7 +80,7 @@ void AvailableClientsPanel::render() { case Domain::ItemDataSource::SRV: type_str = "SRV"; break; case Domain::ItemDataSource::DAT: type_str = "DAT"; break; } - ImGui::TextColored(ImVec4(0.55f, 0.58f, 0.62f, 1.0f), "%u | %s", + ImGui::TextColored(SC::TextDim(), "%u | %s", client->getVersion(), type_str); ImGui::EndGroup(); @@ -94,8 +95,8 @@ void AvailableClientsPanel::render() { if (total_count == 0) { ImGui::Spacing(); - ImGui::TextColored(ImVec4(0.5f, 0.52f, 0.55f, 1.0f), "No clients in database."); - ImGui::TextColored(ImVec4(0.4f, 0.42f, 0.45f, 1.0f), + ImGui::TextColored(SC::TextDim(), "No clients in database."); + ImGui::TextColored(SC::TextDim(), "Use 'Client Config' to add clients."); } diff --git a/ImguiMapEditor/UI/Dialogs/Startup/ClientInfoPanel.cpp b/ImguiMapEditor/UI/Dialogs/Startup/ClientInfoPanel.cpp index 30a54be..a133e67 100644 --- a/ImguiMapEditor/UI/Dialogs/Startup/ClientInfoPanel.cpp +++ b/ImguiMapEditor/UI/Dialogs/Startup/ClientInfoPanel.cpp @@ -1,46 +1,43 @@ #include "ClientInfoPanel.h" +#include "UI/Core/Theme.h" #include #include namespace MapEditor { namespace UI { +namespace SC = SemanticColors; + void ClientInfoPanel::render() { // Panel header - ImGui::TextColored(ImVec4(0.85f, 0.88f, 0.92f, 1.0f), "Client information"); + ImGui::TextColored(SC::TextPrimary(), "Client information"); ImGui::Spacing(); ImGui::Separator(); ImGui::Spacing(); if (client_info_.version > 0) { - const ImVec4 match_color(0.3f, 0.85f, 0.5f, 1.0f); - const ImVec4 mismatch_color(0.9f, 0.4f, 0.4f, 1.0f); - const ImVec4 label_color(0.55f, 0.58f, 0.62f, 1.0f); - const ImVec4 value_color(0.95f, 0.95f, 0.95f, 1.0f); - const ImVec4 empty_color(0.4f, 0.42f, 0.45f, 1.0f); - // Client Name - ImGui::TextColored(label_color, ICON_FA_TAG " Client Name"); + ImGui::TextColored(SC::TextDim(), ICON_FA_TAG " Client Name"); if (!client_info_.client_name.empty()) { - ImGui::TextColored(value_color, "%s", client_info_.client_name.c_str()); + ImGui::TextColored(SC::TextPrimary(), "%s", client_info_.client_name.c_str()); } else { - ImGui::TextColored(value_color, "%s", + ImGui::TextColored(SC::TextPrimary(), "%s", client_info_.version_string.c_str()); } ImGui::Spacing(); // Client Version - ImGui::TextColored(label_color, ICON_FA_CODE_BRANCH " Client Version"); - ImGui::TextColored(value_color, "%s", client_info_.version_string.c_str()); + ImGui::TextColored(SC::TextDim(), ICON_FA_CODE_BRANCH " Client Version"); + ImGui::TextColored(SC::TextPrimary(), "%s", client_info_.version_string.c_str()); ImGui::Spacing(); // Data Directory - ImGui::TextColored(label_color, ICON_FA_FOLDER " Data Directory"); + ImGui::TextColored(SC::TextDim(), ICON_FA_FOLDER " Data Directory"); if (!client_info_.data_directory.empty()) { - ImGui::TextColored(value_color, "%s", + ImGui::TextColored(SC::TextPrimary(), "%s", client_info_.data_directory.c_str()); } else { - ImGui::TextColored(empty_color, "(Not set)"); + ImGui::TextColored(SC::TextDim(), "(Not set)"); } ImGui::Spacing(); ImGui::Separator(); @@ -48,71 +45,71 @@ void ClientInfoPanel::render() { // OTBM Version (compare with map) bool otbm_match = (client_info_.otbm_version == map_info_.otbm_version); - ImGui::TextColored(label_color, ICON_FA_FILE_CODE " OTBM Version"); - ImGui::TextColored(otbm_match ? match_color : mismatch_color, "%u", + ImGui::TextColored(SC::TextDim(), ICON_FA_FILE_CODE " OTBM Version"); + ImGui::TextColored(otbm_match ? SC::SAVED : SC::DANGER, "%u", client_info_.otbm_version); ImGui::Spacing(); // Items Major Version bool major_match = (client_info_.items_major_version == map_info_.items_major_version); - ImGui::TextColored(label_color, ICON_FA_CUBES " Items Major Version"); - ImGui::TextColored(major_match ? match_color : mismatch_color, "%u", + ImGui::TextColored(SC::TextDim(), ICON_FA_CUBES " Items Major Version"); + ImGui::TextColored(major_match ? SC::SAVED : SC::DANGER, "%u", client_info_.items_major_version); ImGui::Spacing(); // Items Minor Version bool minor_match = (client_info_.items_minor_version == map_info_.items_minor_version); - ImGui::TextColored(label_color, ICON_FA_CUBE " Items Minor Version"); - ImGui::TextColored(minor_match ? match_color : mismatch_color, "%u", + ImGui::TextColored(SC::TextDim(), ICON_FA_CUBE " Items Minor Version"); + ImGui::TextColored(minor_match ? SC::SAVED : SC::DANGER, "%u", client_info_.items_minor_version); ImGui::Spacing(); ImGui::Separator(); ImGui::Spacing(); // DAT Signature - ImGui::TextColored(label_color, ICON_FA_FINGERPRINT " DAT Signature"); + ImGui::TextColored(SC::TextDim(), ICON_FA_FINGERPRINT " DAT Signature"); if (!client_info_.dat_signature.empty()) { - ImGui::TextColored(value_color, "%s", client_info_.dat_signature.c_str()); + ImGui::TextColored(SC::TextPrimary(), "%s", client_info_.dat_signature.c_str()); } else { - ImGui::TextColored(empty_color, "(Unknown)"); + ImGui::TextColored(SC::TextDim(), "(Unknown)"); } ImGui::Spacing(); // SPR Signature - ImGui::TextColored(label_color, ICON_FA_IMAGE " SPR Signature"); + ImGui::TextColored(SC::TextDim(), ICON_FA_IMAGE " SPR Signature"); if (!client_info_.spr_signature.empty()) { - ImGui::TextColored(value_color, "%s", client_info_.spr_signature.c_str()); + ImGui::TextColored(SC::TextPrimary(), "%s", client_info_.spr_signature.c_str()); } else { - ImGui::TextColored(empty_color, "(Unknown)"); + ImGui::TextColored(SC::TextDim(), "(Unknown)"); } ImGui::Spacing(); // Description - ImGui::TextColored(label_color, ICON_FA_FILE_LINES " Description"); + ImGui::TextColored(SC::TextDim(), ICON_FA_FILE_LINES " Description"); if (!client_info_.description.empty()) { ImGui::TextWrapped("%s", client_info_.description.c_str()); } else { - ImGui::TextColored(empty_color, "(No description)"); + ImGui::TextColored(SC::TextDim(), "(No description)"); } ImGui::Spacing(); ImGui::Separator(); ImGui::Spacing(); // Status - ImGui::TextColored(label_color, ICON_FA_CIRCLE_CHECK " Status"); + ImGui::TextColored(SC::TextDim(), ICON_FA_CIRCLE_CHECK " Status"); if (client_info_.signatures_match) { - ImGui::TextColored(match_color, "%s", client_info_.status.c_str()); + ImGui::TextColored(SC::SAVED, "%s", client_info_.status.c_str()); } else { - ImGui::TextColored(ImVec4(0.9f, 0.65f, 0.3f, 1.0f), "%s", + ImGui::TextColored(SC::WARNING, "%s", client_info_.status.c_str()); } // Signature mismatch warning if (signature_mismatch_) { ImGui::Spacing(); - ImGui::PushStyleColor(ImGuiCol_Text, ImVec4(1.0f, 0.65f, 0.3f, 1.0f)); + ImGui::PushStyleColor(ImGuiCol_Text, SC::WARNING); ImGui::TextWrapped(ICON_FA_TRIANGLE_EXCLAMATION " %s", signature_mismatch_message_.c_str()); ImGui::PopStyleColor(); @@ -121,7 +118,7 @@ void ClientInfoPanel::render() { // Client not configured warning if (client_not_configured_) { ImGui::Spacing(); - ImGui::PushStyleColor(ImGuiCol_Text, ImVec4(0.9f, 0.4f, 0.4f, 1.0f)); + ImGui::PushStyleColor(ImGuiCol_Text, SC::DANGER); ImGui::TextWrapped( ICON_FA_TRIANGLE_EXCLAMATION " Client not configured. Use 'Client Configuration' to add the " @@ -130,7 +127,7 @@ void ClientInfoPanel::render() { } } else { ImGui::Spacing(); - ImGui::TextColored(ImVec4(0.5f, 0.52f, 0.55f, 1.0f), + ImGui::TextColored(SC::LABEL, "Select a client to view info"); } } diff --git a/ImguiMapEditor/UI/Dialogs/Startup/RecentMapsPanel.cpp b/ImguiMapEditor/UI/Dialogs/Startup/RecentMapsPanel.cpp index 16048de..9f40843 100644 --- a/ImguiMapEditor/UI/Dialogs/Startup/RecentMapsPanel.cpp +++ b/ImguiMapEditor/UI/Dialogs/Startup/RecentMapsPanel.cpp @@ -1,13 +1,16 @@ #include "RecentMapsPanel.h" +#include "UI/Core/Theme.h" #include #include namespace MapEditor { namespace UI { +namespace SC = SemanticColors; + void RecentMapsPanel::render(const std::vector &entries) { // Panel header - ImGui::TextColored(ImVec4(0.85f, 0.88f, 0.92f, 1.0f), "Recent Maps List"); + ImGui::TextColored(SC::TextPrimary(), "Recent Maps List"); ImGui::Spacing(); ImGui::Separator(); ImGui::Spacing(); @@ -26,18 +29,16 @@ void RecentMapsPanel::render(const std::vector &entries) { // Style for selected/hover if (is_selected) { - ImGui::PushStyleColor(ImGuiCol_Header, ImVec4(0.25f, 0.45f, 0.70f, 0.9f)); - ImGui::PushStyleColor(ImGuiCol_HeaderHovered, - ImVec4(0.30f, 0.50f, 0.75f, 1.0f)); + ImGui::PushStyleColor(ImGuiCol_Header, ImGui::GetStyleColorVec4(ImGuiCol_HeaderActive)); + ImGui::PushStyleColor(ImGuiCol_HeaderHovered, ImGui::GetStyleColorVec4(ImGuiCol_HeaderHovered)); } else { - ImGui::PushStyleColor(ImGuiCol_Header, ImVec4(0.18f, 0.20f, 0.24f, 0.6f)); - ImGui::PushStyleColor(ImGuiCol_HeaderHovered, - ImVec4(0.22f, 0.25f, 0.30f, 0.8f)); + ImGui::PushStyleColor(ImGuiCol_Header, ImGui::GetStyleColorVec4(ImGuiCol_Header)); + ImGui::PushStyleColor(ImGuiCol_HeaderHovered, ImGui::GetStyleColorVec4(ImGuiCol_HeaderHovered)); } // Grayed out if file doesn't exist if (!entry.exists) { - ImGui::PushStyleVar(ImGuiStyleVar_Alpha, 0.5f); + ImGui::PushStyleVar(ImGuiStyleVar_Alpha, SC::DISABLED_ALPHA); } // Make selectable span full width @@ -57,6 +58,10 @@ void RecentMapsPanel::render(const std::vector &entries) { } } + if (ImGui::IsItemHovered()) { + ImGui::SetTooltip("%s", entry.path.string().c_str()); + } + // Draw content over the selectable (rewind cursor) ImGui::SetCursorPosY(ImGui::GetCursorPosY() - item_height); ImGui::Indent(8.0f); @@ -64,7 +69,7 @@ void RecentMapsPanel::render(const std::vector &entries) { // Map icon (standard size) ImGui::BeginGroup(); ImGui::SetCursorPosY(ImGui::GetCursorPosY() + 12.0f); - ImGui::PushStyleColor(ImGuiCol_Text, ImVec4(0.5f, 0.65f, 0.85f, 1.0f)); + ImGui::PushStyleColor(ImGuiCol_Text, SC::INFO); ImGui::Text(ICON_FA_MAP); ImGui::PopStyleColor(); ImGui::EndGroup(); @@ -74,9 +79,9 @@ void RecentMapsPanel::render(const std::vector &entries) { // Map name and date ImGui::BeginGroup(); ImGui::SetCursorPosY(ImGui::GetCursorPosY() + 4.0f); - ImGui::TextColored(ImVec4(0.95f, 0.95f, 0.95f, 1.0f), "%s", + ImGui::TextColored(SC::TextPrimary(), "%s", entry.filename.c_str()); - ImGui::TextColored(ImVec4(0.55f, 0.58f, 0.62f, 1.0f), "%s", + ImGui::TextColored(SC::TextDim(), "%s", entry.last_modified.c_str()); ImGui::EndGroup(); @@ -94,7 +99,7 @@ void RecentMapsPanel::render(const std::vector &entries) { if (entries.empty()) { ImGui::Spacing(); - ImGui::TextColored(ImVec4(0.5f, 0.52f, 0.55f, 1.0f), "No recent maps"); + ImGui::TextColored(SC::TextDim(), "No recent maps"); } ImGui::EndChild(); diff --git a/ImguiMapEditor/UI/Dialogs/Startup/SelectedMapPanel.cpp b/ImguiMapEditor/UI/Dialogs/Startup/SelectedMapPanel.cpp index daec14f..26bea35 100644 --- a/ImguiMapEditor/UI/Dialogs/Startup/SelectedMapPanel.cpp +++ b/ImguiMapEditor/UI/Dialogs/Startup/SelectedMapPanel.cpp @@ -1,93 +1,92 @@ #include "SelectedMapPanel.h" +#include "UI/Core/Theme.h" #include #include namespace MapEditor { namespace UI { +namespace SC = SemanticColors; + void SelectedMapPanel::render() { // Panel header - ImGui::TextColored(ImVec4(0.85f, 0.88f, 0.92f, 1.0f), + ImGui::TextColored(SC::TextPrimary(), ICON_FA_CIRCLE_INFO " Selected map information"); ImGui::Spacing(); ImGui::Separator(); ImGui::Spacing(); if (map_info_.valid) { - const ImVec4 label_color(0.55f, 0.58f, 0.62f, 1.0f); - const ImVec4 value_color(0.95f, 0.95f, 0.95f, 1.0f); - const ImVec4 empty_color(0.4f, 0.42f, 0.45f, 1.0f); - // Map Name - ImGui::TextColored(label_color, ICON_FA_FILE " Map Name"); - ImGui::TextColored(value_color, "%s", map_info_.name.c_str()); + ImGui::TextColored(SC::TextDim(), ICON_FA_FILE " Map Name"); + ImGui::TextColored(SC::TextPrimary(), "%s", map_info_.name.c_str()); ImGui::Spacing(); // Client Version - ImGui::TextColored(label_color, ICON_FA_CODE_BRANCH " Client Version"); + ImGui::TextColored(SC::TextDim(), ICON_FA_CODE_BRANCH " Client Version"); if (map_info_.client_version >= 700) { - ImGui::TextColored(value_color, "%u.%02u", map_info_.client_version / 100, + ImGui::TextColored(SC::TextPrimary(), "%u.%02u", map_info_.client_version / 100, map_info_.client_version % 100); } else if (map_info_.client_version > 0) { - ImGui::TextColored(value_color, "%u", map_info_.client_version); + ImGui::TextColored(SC::TextPrimary(), "%u", map_info_.client_version); } else { - ImGui::TextColored(empty_color, "Unknown"); + ImGui::TextColored(SC::TextDim(), "Unknown"); } ImGui::Spacing(); // Dimensions - ImGui::TextColored(label_color, ICON_FA_RULER_COMBINED " Dimensions"); - ImGui::TextColored(value_color, "%u x %u tiles", map_info_.width, + ImGui::TextColored(SC::TextDim(), ICON_FA_RULER_COMBINED " Dimensions"); + ImGui::TextColored(SC::TextPrimary(), "%u x %u tiles", map_info_.width, map_info_.height); ImGui::Spacing(); ImGui::Separator(); ImGui::Spacing(); // OTBM Version - ImGui::TextColored(label_color, ICON_FA_FILE_CODE " OTBM Version"); - ImGui::TextColored(value_color, "%u", map_info_.otbm_version); + ImGui::TextColored(SC::TextDim(), ICON_FA_FILE_CODE " OTBM Version"); + ImGui::TextColored(SC::TextPrimary(), "%u", map_info_.otbm_version); ImGui::Spacing(); // Items Major Version - ImGui::TextColored(label_color, ICON_FA_CUBES " Items Major Version"); - ImGui::TextColored(value_color, "%u", map_info_.items_major_version); + ImGui::TextColored(SC::TextDim(), ICON_FA_CUBES " Items Major Version"); + ImGui::TextColored(SC::TextPrimary(), "%u", map_info_.items_major_version); ImGui::Spacing(); // Items Minor Version - ImGui::TextColored(label_color, ICON_FA_CUBE " Items Minor Version"); - ImGui::TextColored(value_color, "%u", map_info_.items_minor_version); + ImGui::TextColored(SC::TextDim(), ICON_FA_CUBE " Items Minor Version"); + ImGui::TextColored(SC::TextPrimary(), "%u", map_info_.items_minor_version); ImGui::Spacing(); ImGui::Separator(); ImGui::Spacing(); // House File - ImGui::TextColored(label_color, ICON_FA_HOUSE " House File"); + ImGui::TextColored(SC::TextDim(), ICON_FA_HOUSE " House File"); if (!map_info_.house_file.empty()) { - ImGui::TextColored(value_color, "%s", map_info_.house_file.c_str()); + ImGui::TextColored(SC::TextPrimary(), "%s", map_info_.house_file.c_str()); } else { - ImGui::TextColored(empty_color, "(Not set)"); + ImGui::TextColored(SC::TextDim(), "(Not set)"); } ImGui::Spacing(); // Spawn File - ImGui::TextColored(label_color, ICON_FA_SKULL " Spawn File"); + ImGui::TextColored(SC::TextDim(), ICON_FA_SKULL " Spawn File"); if (!map_info_.spawn_file.empty()) { - ImGui::TextColored(value_color, "%s", map_info_.spawn_file.c_str()); + ImGui::TextColored(SC::TextPrimary(), "%s", map_info_.spawn_file.c_str()); } else { - ImGui::TextColored(empty_color, "(Not set)"); + ImGui::TextColored(SC::TextDim(), "(Not set)"); } ImGui::Spacing(); // Description - ImGui::TextColored(label_color, ICON_FA_FILE_LINES " Description"); + ImGui::TextColored(SC::TextDim(), ICON_FA_FILE_LINES " Description"); if (!map_info_.description.empty()) { ImGui::TextWrapped("%s", map_info_.description.c_str()); } else { - ImGui::TextColored(empty_color, "(No description)"); + ImGui::TextColored(SC::TextDim(), "(No description)"); } } else { ImGui::Spacing(); - ImGui::TextColored(ImVec4(0.5f, 0.52f, 0.55f, 1.0f), + ImGui::TextColored(SC::TextDim(), "Select a map to view details"); } } diff --git a/ImguiMapEditor/UI/Dialogs/Startup/StartupDialog.cpp b/ImguiMapEditor/UI/Dialogs/Startup/StartupDialog.cpp index 345adb5..a0d37c4 100644 --- a/ImguiMapEditor/UI/Dialogs/Startup/StartupDialog.cpp +++ b/ImguiMapEditor/UI/Dialogs/Startup/StartupDialog.cpp @@ -1,4 +1,5 @@ #include "StartupDialog.h" +#include "UI/Core/Theme.h" #include "Utils/FormatUtils.h" #include #include @@ -8,6 +9,8 @@ namespace MapEditor { namespace UI { +namespace SC = SemanticColors; + void StartupDialog::initialize(Services::ClientVersionRegistry *registry, Services::ConfigService *config) { registry_ = registry; @@ -91,9 +94,7 @@ void StartupDialog::render(const std::vector &recent_maps, ImGui::SetNextWindowSizeConstraints(ImVec2(900, 550), ImVec2(FLT_MAX, FLT_MAX)); - // Dark modern styling - ImGui::PushStyleColor(ImGuiCol_WindowBg, ImVec4(0.10f, 0.12f, 0.14f, 1.0f)); - ImGui::PushStyleColor(ImGuiCol_ChildBg, ImVec4(0.12f, 0.14f, 0.16f, 1.0f)); + // Theme-aware styling — dark overlay removed, uses active theme ImGui::PushStyleVar(ImGuiStyleVar_WindowRounding, 8.0f); ImGui::PushStyleVar(ImGuiStyleVar_ChildRounding, 6.0f); ImGui::PushStyleVar(ImGuiStyleVar_FrameRounding, 4.0f); @@ -164,7 +165,6 @@ void StartupDialog::render(const std::vector &recent_maps, ImGui::End(); ImGui::PopStyleVar(4); - ImGui::PopStyleColor(2); // ===== RENDER MODALS (using standalone dialogs - DRY) ===== @@ -189,13 +189,13 @@ void StartupDialog::renderHeader() { const float header_height = 60.0f; // Card-style header background (no scrolling) - ImGui::PushStyleColor(ImGuiCol_ChildBg, ImVec4(0.14f, 0.16f, 0.18f, 1.0f)); + ImGui::PushStyleColor(ImGuiCol_ChildBg, ImGui::GetStyleColorVec4(ImGuiCol_Header)); ImGui::BeginChild("##HeaderCard", ImVec2(0, header_height), true, ImGuiWindowFlags_NoScrollbar | ImGuiWindowFlags_NoScrollWithMouse); // Title with larger text - ImGui::PushStyleColor(ImGuiCol_Text, ImVec4(1.0f, 1.0f, 1.0f, 1.0f)); + ImGui::PushStyleColor(ImGuiCol_Text, SC::TextPrimary()); ImGui::SetWindowFontScale(1.4f); ImGui::Text("Tibia Map Editor"); ImGui::SetWindowFontScale(1.0f); @@ -203,7 +203,7 @@ void StartupDialog::renderHeader() { // Subtitle ImGui::TextColored( - ImVec4(0.6f, 0.65f, 0.7f, 1.0f), + SC::TextDim(), "Welcome! Start a new project or continue where you left off."); // Header buttons on the right (Preferences + Client Configuration) @@ -217,26 +217,17 @@ void StartupDialog::renderHeader() { right_padding); ImGui::SetCursorPosY(button_y); - ImGui::PushStyleColor(ImGuiCol_Button, ImVec4(0.25f, 0.28f, 0.32f, 1.0f)); - ImGui::PushStyleColor(ImGuiCol_ButtonHovered, - ImVec4(0.35f, 0.38f, 0.42f, 1.0f)); if (ImGui::Button(ICON_FA_GEAR " Preferences", kUniformButtonSize)) { pending_result_.action = Action::Preferences; } - ImGui::PopStyleColor(2); // Position second button at same Y level ImGui::SameLine(0, button_spacing); ImGui::SetCursorPosY(button_y); - // Client Configuration button (moved from footer) - ImGui::PushStyleColor(ImGuiCol_Button, ImVec4(0.25f, 0.28f, 0.32f, 1.0f)); - ImGui::PushStyleColor(ImGuiCol_ButtonHovered, - ImVec4(0.35f, 0.38f, 0.42f, 1.0f)); if (ImGui::Button(ICON_FA_SLIDERS " Client Config", kUniformButtonSize)) { pending_result_.action = Action::ClientConfiguration; } - ImGui::PopStyleColor(2); ImGui::EndChild(); ImGui::PopStyleColor(); // ChildBg @@ -248,12 +239,10 @@ void StartupDialog::renderSidebar() { ImGui::Spacing(); - // New Map button (primary action - blue) - ImGui::PushStyleColor(ImGuiCol_Button, ImVec4(0.20f, 0.45f, 0.70f, 1.0f)); - ImGui::PushStyleColor(ImGuiCol_ButtonHovered, - ImVec4(0.25f, 0.55f, 0.80f, 1.0f)); - ImGui::PushStyleColor(ImGuiCol_ButtonActive, - ImVec4(0.15f, 0.40f, 0.65f, 1.0f)); + // New Map button (primary action) + ImGui::PushStyleColor(ImGuiCol_Button, SC::INFO); + ImGui::PushStyleColor(ImGuiCol_ButtonHovered, SC::Lighten(SC::INFO)); + ImGui::PushStyleColor(ImGuiCol_ButtonActive, SC::Darken(SC::INFO)); if (ImGui::Button(ICON_FA_FILE " New map", kUniformButtonSize)) { pending_result_.action = Action::NewMap; } @@ -262,31 +251,19 @@ void StartupDialog::renderSidebar() { ImGui::Spacing(); ImGui::Spacing(); - // Browse Map button (secondary - dark gray) - ImGui::PushStyleColor(ImGuiCol_Button, ImVec4(0.20f, 0.22f, 0.25f, 1.0f)); - ImGui::PushStyleColor(ImGuiCol_ButtonHovered, - ImVec4(0.28f, 0.30f, 0.34f, 1.0f)); - ImGui::PushStyleColor(ImGuiCol_ButtonActive, - ImVec4(0.16f, 0.18f, 0.20f, 1.0f)); + // Browse Map button if (ImGui::Button(ICON_FA_FOLDER_OPEN " Browse Map", kUniformButtonSize)) { pending_result_.action = Action::BrowseMap; } - ImGui::PopStyleColor(3); ImGui::Spacing(); ImGui::Spacing(); - // Browse .sec MAP button (secondary - dark gray) - ImGui::PushStyleColor(ImGuiCol_Button, ImVec4(0.20f, 0.22f, 0.25f, 1.0f)); - ImGui::PushStyleColor(ImGuiCol_ButtonHovered, - ImVec4(0.28f, 0.30f, 0.34f, 1.0f)); - ImGui::PushStyleColor(ImGuiCol_ButtonActive, - ImVec4(0.16f, 0.18f, 0.20f, 1.0f)); + // Browse .sec MAP button if (ImGui::Button(ICON_FA_MAGNIFYING_GLASS " Browse .sec", kUniformButtonSize)) { pending_result_.action = Action::BrowseSecMap; } - ImGui::PopStyleColor(3); } void StartupDialog::renderRecentMapsPanel( @@ -339,17 +316,13 @@ void StartupDialog::renderFooter() { // Exit button (left) ImGui::SetCursorPosY(button_y); - ImGui::PushStyleColor(ImGuiCol_Button, ImVec4(0.25f, 0.28f, 0.32f, 1.0f)); - ImGui::PushStyleColor(ImGuiCol_ButtonHovered, - ImVec4(0.35f, 0.38f, 0.42f, 1.0f)); if (ImGui::Button(ICON_FA_POWER_OFF " Exit", kUniformButtonSize)) { pending_result_.action = Action::Exit; } - ImGui::PopStyleColor(2); ImGui::SameLine(); ImGui::SetCursorPosY(button_y + 8.0f); - ImGui::TextColored(ImVec4(0.5f, 0.52f, 0.55f, 1.0f), "Version 2.4.1"); + ImGui::TextColored(SC::TextDim(), "Version 2.4.1"); // Right side buttons: Ignore Signatures toggle + Load Map float button_spacing = 8.0f; @@ -359,21 +332,12 @@ void StartupDialog::renderFooter() { ImGui::SameLine(region.x - right_buttons_width - right_padding); ImGui::SetCursorPosY(button_y); - // Ignore signatures toggle button (converted from checkbox) - if (ignore_signatures_) { - // Active state - more prominent color - ImGui::PushStyleColor(ImGuiCol_Button, ImVec4(0.35f, 0.50f, 0.65f, 1.0f)); - ImGui::PushStyleColor(ImGuiCol_ButtonHovered, - ImVec4(0.40f, 0.55f, 0.70f, 1.0f)); - ImGui::PushStyleColor(ImGuiCol_ButtonActive, - ImVec4(0.30f, 0.45f, 0.60f, 1.0f)); - } else { - // Inactive state - standard gray - ImGui::PushStyleColor(ImGuiCol_Button, ImVec4(0.25f, 0.28f, 0.32f, 1.0f)); - ImGui::PushStyleColor(ImGuiCol_ButtonHovered, - ImVec4(0.35f, 0.38f, 0.42f, 1.0f)); - ImGui::PushStyleColor(ImGuiCol_ButtonActive, - ImVec4(0.20f, 0.22f, 0.26f, 1.0f)); + // Ignore signatures toggle button + const bool pushed_color = ignore_signatures_; + if (pushed_color) { + ImGui::PushStyleColor(ImGuiCol_Button, SC::INFO); + ImGui::PushStyleColor(ImGuiCol_ButtonHovered, SC::Lighten(SC::INFO)); + ImGui::PushStyleColor(ImGuiCol_ButtonActive, SC::Darken(SC::INFO)); } const char *sig_label = ignore_signatures_ ? ICON_FA_CHECK " Ignore Sigs" @@ -381,21 +345,22 @@ void StartupDialog::renderFooter() { if (ImGui::Button(sig_label, kUniformButtonSize)) { ignore_signatures_ = !ignore_signatures_; } - ImGui::PopStyleColor(3); + + if (pushed_color) { + ImGui::PopStyleColor(3); + } ImGui::SameLine(0, button_spacing); - // Load Map button (primary - blue) + // Load Map button (primary) bool can_load = load_enabled_ || ignore_signatures_; - ImGui::PushStyleColor(ImGuiCol_Button, ImVec4(0.20f, 0.50f, 0.85f, 1.0f)); - ImGui::PushStyleColor(ImGuiCol_ButtonHovered, - ImVec4(0.25f, 0.55f, 0.90f, 1.0f)); - ImGui::PushStyleColor(ImGuiCol_ButtonActive, - ImVec4(0.15f, 0.45f, 0.80f, 1.0f)); + ImGui::PushStyleColor(ImGuiCol_Button, SC::INFO); + ImGui::PushStyleColor(ImGuiCol_ButtonHovered, SC::Lighten(SC::INFO)); + ImGui::PushStyleColor(ImGuiCol_ButtonActive, SC::Darken(SC::INFO)); if (!can_load) { - ImGui::PushStyleVar(ImGuiStyleVar_Alpha, 0.5f); + ImGui::PushStyleVar(ImGuiStyleVar_Alpha, SC::DISABLED_ALPHA); } if (ImGui::Button(ICON_FA_UPLOAD " Load Map", kUniformButtonSize) && diff --git a/ImguiMapEditor/UI/Dialogs/UnsavedChangesModal.cpp b/ImguiMapEditor/UI/Dialogs/UnsavedChangesModal.cpp index 554f37b..7f84597 100644 --- a/ImguiMapEditor/UI/Dialogs/UnsavedChangesModal.cpp +++ b/ImguiMapEditor/UI/Dialogs/UnsavedChangesModal.cpp @@ -1,4 +1,5 @@ #include "UnsavedChangesModal.h" +#include "UI/Core/Theme.h" #include #include "ext/fontawesome6/IconsFontAwesome6.h" diff --git a/ImguiMapEditor/UI/Panels/BrushSizePanel.cpp b/ImguiMapEditor/UI/Panels/BrushSizePanel.cpp index eb11079..4bb6809 100644 --- a/ImguiMapEditor/UI/Panels/BrushSizePanel.cpp +++ b/ImguiMapEditor/UI/Panels/BrushSizePanel.cpp @@ -1,6 +1,7 @@ #include "BrushSizePanel.h" #include "Services/BrushSettingsService.h" +#include "UI/Core/Theme.h" #include "UI/Utils/UIUtils.hpp" #include "ext/fontawesome6/IconsFontAwesome6.h" #include @@ -11,8 +12,9 @@ namespace MapEditor { namespace UI { namespace Panels { -// Green highlight color for active toggles -static const ImVec4 ACTIVE_TOGGLE_COLOR = ImVec4(0.2f, 0.7f, 0.3f, 1.0f); +namespace SC = SemanticColors; + +static const ImVec4 ACTIVE_TOGGLE_COLOR = SC::SAVED; BrushSizePanel::BrushSizePanel(Services::BrushSettingsService *brushService, SaveCallback onSave) diff --git a/ImguiMapEditor/UI/Panels/NewMapPanel.cpp b/ImguiMapEditor/UI/Panels/NewMapPanel.cpp index 951e685..5d278a5 100644 --- a/ImguiMapEditor/UI/Panels/NewMapPanel.cpp +++ b/ImguiMapEditor/UI/Panels/NewMapPanel.cpp @@ -1,5 +1,6 @@ #include "UI/Panels/NewMapPanel.h" #include "Core/Config.h" +#include "UI/Core/Theme.h" #include "ext/fontawesome6/IconsFontAwesome6.h" #include #include @@ -9,6 +10,8 @@ namespace MapEditor { namespace UI { +namespace SC = SemanticColors; + void NewMapPanel::initialize(Services::ClientVersionRegistry *registry) { registry_ = registry; } @@ -31,13 +34,13 @@ bool NewMapPanel::render(State &state) { auto applyGlow = [&](bool cond) { if (cond) { - ImGui::PushStyleColor(ImGuiCol_FrameBg, ImVec4(0.6f, 0.5f, 0.0f, 0.3f + pulse * 0.5f)); - ImGui::PushStyleColor(ImGuiCol_Border, ImVec4(0.9f, 0.8f, 0.2f, 0.5f + pulse * 0.5f)); + ImGui::PushStyleColor(ImGuiCol_FrameBg, ImVec4(SC::PULSE_BASE.x, SC::PULSE_BASE.y, SC::PULSE_BASE.z, 0.3f + pulse * 0.5f)); + ImGui::PushStyleColor(ImGuiCol_Border, ImVec4(SC::GOLD.x, SC::GOLD.y, SC::GOLD.z, 0.5f + pulse * 0.5f)); } }; auto popGlow = [](bool cond) { if (cond) ImGui::PopStyleColor(2); }; - constexpr ImVec4 label(0.55f, 0.58f, 0.62f, 1.0f); + constexpr ImVec4 label = SC::LABEL; // ========================================================= // LEFT COLUMN diff --git a/ImguiMapEditor/UI/PreferencesDialog.cpp b/ImguiMapEditor/UI/PreferencesDialog.cpp index ec63fe3..95b3bb9 100644 --- a/ImguiMapEditor/UI/PreferencesDialog.cpp +++ b/ImguiMapEditor/UI/PreferencesDialog.cpp @@ -1,6 +1,7 @@ // Prevent GLFW from including OpenGL headers (glad provides them) #define GLFW_INCLUDE_NONE #include "PreferencesDialog.h" +#include "UI/Core/Theme.h" #include "../ext/imhotkey/imHotKey.h" #include "IO/HotkeyJsonReader.h" #include "Presentation/NotificationHelper.h" @@ -9,6 +10,7 @@ #include "Services/OtbmSettings.h" #include "Services/SecondaryClientData.h" #include "ext/fontawesome6/IconsFontAwesome6.h" +#include #include #include #include @@ -18,6 +20,8 @@ namespace MapEditor { namespace UI { +namespace SC = SemanticColors; + namespace { bool saveHotkeysToFile(const Domain::HotkeyBindingMap& bindings) { @@ -119,7 +123,64 @@ PreferencesDialog::Result PreferencesDialog::render() { void PreferencesDialog::renderEditorTab() { ImGui::Spacing(); - ImGui::TextDisabled("General editor settings will be added here."); + + // === Theme === + if (ImGui::CollapsingHeader(ICON_FA_PALETTE " Theme", ImGuiTreeNodeFlags_DefaultOpen)) { + ImGui::Spacing(); + + float combo_width = 220.0f; + ImGui::TextUnformatted("Select Theme"); + + const char* current_name = "Select Theme"; + if (theme_ptr_) { + current_name = GetThemeName(*theme_ptr_); + } + + ImGui::SetNextItemWidth(combo_width); + if (ImGui::BeginCombo("##ThemeCombo", current_name)) { + for (const auto& theme : AVAILABLE_THEMES) { + bool is_selected = theme_ptr_ && (*theme_ptr_ == theme.type); + + const char* theme_icon = ICON_FA_CIRCLE; + switch (theme.type) { + case ThemeType::ModernDark: theme_icon = ICON_FA_MOON; break; + case ThemeType::DocumentLight: theme_icon = ICON_FA_SUN; break; + } + + ImGui::PushStyleColor(ImGuiCol_Text, theme.preview_color); + ImGui::Text("%s", ICON_FA_SQUARE); + ImGui::PopStyleColor(); + ImGui::SameLine(); + + std::string label = std::string(theme_icon) + " " + theme.name; + + if (ImGui::Selectable(label.c_str(), is_selected)) { + ApplyTheme(theme.type); + if (theme_ptr_) { + *theme_ptr_ = theme.type; + } + if (on_apply_settings_) { + on_apply_settings_(); + } + } + if (ImGui::IsItemHovered() && theme.description) { + ImGui::SetTooltip("%s", theme.description); + } + } + ImGui::EndCombo(); + } + + if (theme_ptr_) { + ImGui::SameLine(); + auto it = std::ranges::find_if( + AVAILABLE_THEMES, [this](const ThemeInfo& ti) { return ti.type == *theme_ptr_; }); + if (it != std::end(AVAILABLE_THEMES)) { + ImGui::TextUnformatted(it->description); + } + } + + ImGui::Spacing(); + } } void PreferencesDialog::renderSecondaryClientTab() { @@ -144,10 +205,10 @@ void PreferencesDialog::renderSecondaryClientTab() { bool is_active = sec_client->isActive(); if (is_active) { - ImGui::TextColored(ImVec4(0.2f, 0.8f, 0.2f, 1.0f), + ImGui::TextColored(SC::SAVED, ICON_FA_CHECK " Secondary Client Active"); } else { - ImGui::TextColored(ImVec4(0.8f, 0.6f, 0.2f, 1.0f), + ImGui::TextColored(SC::WARNING, ICON_FA_PAUSE " Secondary Client Loaded (Inactive)"); } @@ -230,7 +291,7 @@ void PreferencesDialog::renderSecondaryClientTab() { // Error display if (!secondary_error_.empty()) { - ImGui::TextColored(ImVec4(1.0f, 0.3f, 0.3f, 1.0f), + ImGui::TextColored(SC::DANGER, ICON_FA_TRIANGLE_EXCLAMATION " %s", secondary_error_.c_str()); ImGui::Spacing(); @@ -372,7 +433,7 @@ void PreferencesDialog::renderHotkeysTab() { ImGui::TableNextColumn(); char shortcut[64]; ImHotKey::GetHotKeyLib(hotkeys[i], shortcut, sizeof(shortcut)); - ImGui::TextColored(ImVec4(0.5f, 0.8f, 1.0f, 1.0f), "%s", + ImGui::TextColored(SC::INFO, "%s", shortcut[0] ? shortcut : "(none)"); ImGui::TableNextColumn(); diff --git a/ImguiMapEditor/UI/PreferencesDialog.h b/ImguiMapEditor/UI/PreferencesDialog.h index 58a04ee..256d428 100644 --- a/ImguiMapEditor/UI/PreferencesDialog.h +++ b/ImguiMapEditor/UI/PreferencesDialog.h @@ -1,6 +1,7 @@ #pragma once #include "Domain/OtbmDataTypes.h" #include "Services/SecondaryClientConstants.h" +#include "UI/Core/Theme.h" #include #include #include @@ -73,6 +74,10 @@ class PreferencesDialog { otbm_settings_ = settings; } + void setThemePtr(ThemeType* theme_ptr) { + theme_ptr_ = theme_ptr; + } + using ApplySettingsCallback = std::function; void setApplySettingsCallback(ApplySettingsCallback callback) { on_apply_settings_ = std::move(callback); @@ -97,6 +102,9 @@ class PreferencesDialog { int selected_otbm_type_ = 0; bool otbm_tab_active_ = false; + // Theme + ThemeType* theme_ptr_ = nullptr; + // Callbacks LoadSecondaryCallback on_load_secondary_; UnloadSecondaryCallback on_unload_secondary_; diff --git a/ImguiMapEditor/UI/Ribbon/Panels/ThemePanel.cpp b/ImguiMapEditor/UI/Ribbon/Panels/ThemePanel.cpp index 39939d2..e0684ce 100644 --- a/ImguiMapEditor/UI/Ribbon/Panels/ThemePanel.cpp +++ b/ImguiMapEditor/UI/Ribbon/Panels/ThemePanel.cpp @@ -28,18 +28,11 @@ void ThemePanel::Render() { switch (theme.type) { case ThemeType::ModernDark: - case ThemeType::MidnightPurple: - case ThemeType::ForestGreen: theme_icon = ICON_FA_MOON; break; - case ThemeType::ClassicLight: - case ThemeType::SunsetOrange: - case ThemeType::TibiaRPG: + case ThemeType::DocumentLight: theme_icon = ICON_FA_SUN; break; - case ThemeType::OtclientTheme: - theme_icon = ICON_FA_GAMEPAD; - break; } // Draw colored rectangle for preview diff --git a/ImguiMapEditor/UI/Ribbon/Utils/RibbonUtils.h b/ImguiMapEditor/UI/Ribbon/Utils/RibbonUtils.h index e02b3e9..876bcff 100644 --- a/ImguiMapEditor/UI/Ribbon/Utils/RibbonUtils.h +++ b/ImguiMapEditor/UI/Ribbon/Utils/RibbonUtils.h @@ -1,6 +1,8 @@ #pragma once +#include "UI/Core/Theme.h" #include +#include #include #include @@ -119,7 +121,7 @@ inline void RenderRadioButton(const char *icon, bool selected, * Renders a vertical separator customized for the ribbon. */ inline void RenderSeparator() { - ImGui::PushStyleColor(ImGuiCol_Text, ImVec4(0.5f, 0.5f, 0.5f, 0.5f)); + ImGui::PushStyleColor(ImGuiCol_Text, ImVec4(SemanticColors::MUTED.x, SemanticColors::MUTED.y, SemanticColors::MUTED.z, 0.5f)); ImGui::Text("|"); ImGui::PopStyleColor(); } diff --git a/ImguiMapEditor/UI/Widgets/TilesetGridWidget.cpp b/ImguiMapEditor/UI/Widgets/TilesetGridWidget.cpp index 34884a6..ed8e971 100644 --- a/ImguiMapEditor/UI/Widgets/TilesetGridWidget.cpp +++ b/ImguiMapEditor/UI/Widgets/TilesetGridWidget.cpp @@ -1,5 +1,7 @@ #include "TilesetGridWidget.h" +#include "UI/Core/Theme.h" + #include #include #include diff --git a/ImguiMapEditor/UI/Windows/BrowseTile/BrowseTileWindow.cpp b/ImguiMapEditor/UI/Windows/BrowseTile/BrowseTileWindow.cpp index 42cb36d..c514635 100644 --- a/ImguiMapEditor/UI/Windows/BrowseTile/BrowseTileWindow.cpp +++ b/ImguiMapEditor/UI/Windows/BrowseTile/BrowseTileWindow.cpp @@ -1,4 +1,5 @@ #include "BrowseTileWindow.h" +#include "UI/Core/Theme.h" #include "Application/EditorSession.h" #include "Domain/ChunkedMap.h" #include "Domain/Creature.h" @@ -20,6 +21,8 @@ #include #include +namespace SC = SemanticColors; + namespace MapEditor::UI { BrowseTileWindow::BrowseTileWindow() = default; @@ -334,8 +337,8 @@ void BrowseTileWindow::renderTileProperties() { bool no_logout = Domain::hasFlag(flags, Domain::TileFlag::NoLogout); bool pvp_zone = Domain::hasFlag(flags, Domain::TileFlag::PvpZone); - ImVec4 green(0.2f, 0.8f, 0.2f, 1.0f); - ImVec4 red(0.5f, 0.3f, 0.3f, 1.0f); + ImVec4 green = SC::SAVED; + ImVec4 red = SC::DANGER; ImGui::Spacing(); diff --git a/ImguiMapEditor/UI/Windows/BrowseTile/SpawnCreatureRenderer.cpp b/ImguiMapEditor/UI/Windows/BrowseTile/SpawnCreatureRenderer.cpp index cab4535..a3077e8 100644 --- a/ImguiMapEditor/UI/Windows/BrowseTile/SpawnCreatureRenderer.cpp +++ b/ImguiMapEditor/UI/Windows/BrowseTile/SpawnCreatureRenderer.cpp @@ -1,4 +1,5 @@ #include "SpawnCreatureRenderer.h" +#include "UI/Core/Theme.h" #include "Domain/Creature.h" #include "Domain/Spawn.h" #include "Rendering/Core/Texture.h" @@ -7,6 +8,8 @@ #include "UI/Utils/PreviewUtils.hpp" namespace MapEditor::UI::BrowseTile { +namespace SC = SemanticColors; + SpawnCreatureRenderer::SpawnCreatureRenderer( Services::SpriteManager *spriteManager, Services::ClientDataService *clientData) diff --git a/ImguiMapEditor/UI/Windows/IngameBoxWindow.cpp b/ImguiMapEditor/UI/Windows/IngameBoxWindow.cpp index 2932654..21d641b 100644 --- a/ImguiMapEditor/UI/Windows/IngameBoxWindow.cpp +++ b/ImguiMapEditor/UI/Windows/IngameBoxWindow.cpp @@ -3,6 +3,7 @@ #include #include #include +#include "UI/Core/Theme.h" #include "ext/fontawesome6/IconsFontAwesome6.h" #include "Application/EditorSession.h" #include "Core/Config.h" @@ -14,6 +15,8 @@ namespace MapEditor { namespace UI { +namespace SC = SemanticColors; + IngameBoxWindow::IngameBoxWindow() = default; void IngameBoxWindow::render(Domain::ChunkedMap* map, @@ -45,7 +48,7 @@ void IngameBoxWindow::render(Domain::ChunkedMap* map, // === Toggle Buttons Row === // Follow Selection toggle button (crosshairs icon) - ImVec4 follow_color = follow_cursor_ ? ImVec4(0.2f, 0.8f, 0.2f, 1.0f) : ImVec4(0.5f, 0.5f, 0.5f, 1.0f); + ImVec4 follow_color = follow_cursor_ ? SC::SAVED : ImGui::GetStyleColorVec4(ImGuiCol_TextDisabled); ImGui::PushStyleColor(ImGuiCol_Text, follow_color); if (ImGui::Button(ICON_FA_CROSSHAIRS "##follow")) { follow_cursor_ = !follow_cursor_; @@ -58,7 +61,7 @@ void IngameBoxWindow::render(Domain::ChunkedMap* map, ImGui::SameLine(); // Enable Lighting toggle button (lightbulb icon) - ImVec4 light_color = settings.preview_lighting_enabled ? ImVec4(1.0f, 0.85f, 0.2f, 1.0f) : ImVec4(0.5f, 0.5f, 0.5f, 1.0f); + ImVec4 light_color = settings.preview_lighting_enabled ? SC::GOLD : ImGui::GetStyleColorVec4(ImGuiCol_TextDisabled); ImGui::PushStyleColor(ImGuiCol_Text, light_color); if (ImGui::Button(ICON_FA_LIGHTBULB "##lighting")) { settings.preview_lighting_enabled = !settings.preview_lighting_enabled; @@ -168,10 +171,10 @@ void IngameBoxWindow::render(Domain::ChunkedMap* map, ImVec2(0, 1), ImVec2(1, 0) ); } else { - ImGui::TextColored(ImVec4(1, 0.5f, 0, 1), "Initializing preview..."); + ImGui::TextColored(SC::WARNING, "Initializing preview..."); } } else { - ImGui::TextColored(ImVec4(0.5f, 0.5f, 0.5f, 1), "No map loaded"); + ImGui::TextColored(SC::LABEL, "No map loaded"); } ImGui::End();