yaze 0.3.2
Link to the Past ROM Editor
 
Loading...
Searching...
No Matches
theme_manager.h
Go to the documentation of this file.
1#ifndef YAZE_APP_GUI_THEME_MANAGER_H
2#define YAZE_APP_GUI_THEME_MANAGER_H
3
4#include <functional>
5#include <map>
6#include <string>
7#include <utility>
8#include <vector>
9
10#include "absl/status/status.h"
11#include "absl/status/statusor.h"
12#include "app/gui/core/color.h"
13#include "imgui/imgui.h"
14
15namespace yaze {
16namespace gui {
17
22enum class DensityPreset {
23 kCompact, // 0.75x - Dense UI, more content visible
24 kNormal, // 1.0x - Default balanced spacing
25 kComfortable // 1.25x - Spacious, easier to click
26};
27
32struct Theme {
33 std::string name;
34 std::string description;
35 std::string author;
36
37 // Primary colors
47
48 // Text colors
52
53 // Window colors
58
59 // Interactive elements
66
67 // Navigation and selection
78
79 // Borders and separators
85
86 // Scrollbars and controls
91
92 // Special elements
98
99 // Complete ImGui color support
121
122 // Additional ImGui colors for complete coverage
129
130 // Enhanced theme system - semantic colors
131 Color text_highlight; // For selected text, highlighted items
132 Color link_hover; // For hover state of links
133 Color code_background; // For code blocks, monospace text backgrounds
134 Color success_light; // Lighter variant of success color
135 Color warning_light; // Lighter variant of warning color
136 Color error_light; // Lighter variant of error color
137 Color info_light; // Lighter variant of info color
138
139 // UI state colors
140 Color active_selection; // For active/selected UI elements
141 Color hover_highlight; // General hover state
142 Color focus_border; // For focused input elements
143 Color disabled_overlay; // Semi-transparent overlay for disabled elements
144
145 // Editor-specific colors
146 Color editor_background; // Main editor canvas background
147 Color editor_grid; // Grid lines in editors
148 Color editor_cursor; // Cursor/selection in editors
149 Color editor_selection; // Selected area in editors
150
151 // Unified selection and interaction colors (replacing hardcoded values)
152 Color selection_primary; // Primary selection (typically gold/yellow)
153 Color selection_secondary; // Secondary selection (typically cyan/blue)
154 Color selection_hover; // Hover highlight color
155 Color selection_pulsing; // Pulsing animation color
156 Color selection_handle; // Corner handles for resizing/moving
157 Color drag_preview; // Ghost preview when dragging
158 Color drag_preview_outline; // Outline for drag preview
159
160 // Common entity colors
168
169 // Nested struct for dungeon editor colors
198
199 // Nested struct for chat/agent colors
238
239 // Style parameters
240 float window_rounding = 0.0f;
241 float frame_rounding = 5.0f;
242 float scrollbar_rounding = 5.0f;
243 float grab_rounding = 3.0f;
244 float tab_rounding = 0.0f;
245 float window_border_size = 0.0f;
246 float frame_border_size = 0.0f;
247
248 // Animation and effects
249 bool enable_animations = true;
250 float animation_speed = 1.0f;
252
253 // Theme-aware sizing system (relative to font size)
254 // compact_factor: 0.8 = very compact, 1.0 = normal, 1.2 = spacious
255 float compact_factor = 1.0f;
257
258 // Semantic sizing multipliers (applied on top of compact_factor)
259 float widget_height_multiplier = 1.0f; // Standard widget height
260 float spacing_multiplier = 1.0f; // Padding/margins between elements
261 float toolbar_height_multiplier = 0.8f; // Compact toolbars
262 float panel_padding_multiplier = 1.0f; // Panel interior padding
263 float input_width_multiplier = 1.0f; // Standard input field width
264 float button_padding_multiplier = 1.0f; // Button interior padding
265 float table_row_height_multiplier = 1.0f; // Table row height
266 float canvas_toolbar_multiplier = 0.75f; // Canvas overlay toolbars
267
268 // Helper methods
269 void ApplyToImGui() const;
271};
272
278 public:
279 static ThemeManager& Get();
280
281 // Theme management
282 absl::Status LoadTheme(const std::string& theme_name);
283 absl::Status SaveTheme(const Theme& theme, const std::string& filename);
284 absl::Status LoadThemeFromFile(const std::string& filepath);
285 // Non-const: records the chosen filepath in theme_file_paths_ on success so
286 // subsequent GetCurrentThemeFilePath calls round-trip for themes created or
287 // renamed via the save dialog (not just ones that were loaded from disk).
288 absl::Status SaveThemeToFile(const Theme& theme, const std::string& filepath);
289
290 // Dynamic theme discovery - replaces hardcoded theme lists with automatic
291 // discovery This works across development builds, macOS app bundles, and
292 // other deployment scenarios
293 std::vector<std::string> DiscoverAvailableThemeFiles() const;
294 absl::Status LoadAllAvailableThemes();
295 absl::Status RefreshAvailableThemes(); // Public method to refresh at runtime
296
297 // Built-in themes
299 std::vector<std::string> GetAvailableThemes() const;
300 const Theme* GetTheme(const std::string& name) const;
301 const Theme& GetCurrentTheme() const { return current_theme_; }
302 const std::string& GetCurrentThemeName() const { return current_theme_name_; }
303
304 // Filesystem path the current theme was loaded from (or last saved to via
305 // SaveThemeToFile). Returns empty string for Classic YAZE (no file) or when
306 // no file association exists; "Save Over Current" uses this to decide
307 // whether the overwrite action is available.
308 std::string GetCurrentThemeFilePath() const;
309
310 // Theme application
311 void ApplyTheme(const std::string& theme_name);
312 void ApplyTheme(const Theme& theme);
313 void ApplyClassicYazeTheme(); // Apply original ColorsYaze() function
314
315 // Theme-changed callback. Fired after any successful theme application with
316 // the current theme name. Keeps persistence decoupled from ThemeManager —
317 // the editor wires this to UserSettings so the selection survives restart.
318 using ThemeChangedCallback = std::function<void(const std::string&)>;
320 on_theme_changed_ = std::move(callback);
321 }
322
323 // Theme preview (for hover preview in selector)
324 void StartPreview(const std::string& theme_name);
325 void EndPreview();
326 bool IsPreviewActive() const;
327
328 // Smooth theme transitions
329 void UpdateTransition();
330 bool IsTransitioning() const { return transitioning_; }
331
332 // Theme creation and editing
333 Theme CreateCustomTheme(const std::string& name);
334 void ShowThemeEditor(bool* p_open);
335 void ShowThemeSelector(bool* p_open);
336 void ShowSimpleThemeEditor(bool* p_open);
337
338 // Accent color derivation - generate harmonious theme from single color
339 Theme GenerateThemeFromAccent(const Color& accent, bool dark_mode = true);
340 void ApplyAccentColor(const Color& accent, bool dark_mode = true);
341
342 // Integration with welcome screen
346
347 // Export current theme as JSON string for Web/WASM sync
348 std::string ExportCurrentThemeJson() const;
349
350 // Convenient theme color access interface
351 Color GetThemeColor(const std::string& color_name) const;
352 ImVec4 GetThemeColorVec4(const std::string& color_name) const;
353
354 // Material Design color accessors
373
374 private:
376
377 std::map<std::string, Theme> themes_;
378 // Display name → filesystem path captured at LoadThemeFromFile time. Lets
379 // GetCurrentThemeFilePath return a path that survives display names with
380 // spaces/apostrophes (e.g., "Majora's Moon" → majoras_moon.theme).
381 std::map<std::string, std::string> theme_file_paths_;
383 std::string current_theme_name_ = "Classic YAZE";
384
385 // Preview state for hover preview in theme selector
386 bool preview_active_ = false;
389
390 // True while InitializeBuiltInThemes is constructing the singleton. Guards
391 // ApplyClassicYazeTheme from calling AgentUI::RefreshTheme, which would
392 // recursively re-enter ThemeManager::Get() and abort on __cxa_guard_acquire.
394
395 // Smooth transition state (lerps ImGui colors per-frame)
396 bool transitioning_ = false;
398 ImVec4 transition_from_[ImGuiCol_COUNT] = {};
399 ImVec4 transition_to_[ImGuiCol_COUNT] = {};
400
401 // Fires on_theme_changed_ with current_theme_name_. Safe to call when no
402 // callback is set (becomes a no-op).
403 void NotifyThemeChanged();
404
406
408 absl::Status ParseThemeFile(const std::string& content, Theme& theme);
410 Theme& theme); // Fill missing properties from primary colors
411 Color ParseColorFromString(const std::string& color_str) const;
412 std::string SerializeTheme(const Theme& theme) const;
413
414 // Helper methods for path resolution
415 std::vector<std::string> GetThemeSearchPaths() const;
416 std::string GetThemesDirectory() const;
417 std::string GetUserThemesDirectory() const; // Returns ~/.yaze/themes/
418};
419
420// Global convenience functions for easy theme color access
421// Material Design color accessors - global convenience functions
422inline Color GetThemeColor(const std::string& color_name) {
423 return ThemeManager::Get().GetThemeColor(color_name);
424}
425
426inline ImVec4 GetThemeColorVec4(const std::string& color_name) {
427 return ThemeManager::Get().GetThemeColorVec4(color_name);
428}
429
430// Material Design color accessors
432 return ThemeManager::Get().GetPrimary();
433}
442}
444 return ThemeManager::Get().GetSurface();
445}
460}
466}
468 return ThemeManager::Get().GetOutline();
469}
476inline Color GetShadow() {
477 return ThemeManager::Get().GetShadow();
478}
479
480// ImVec4 versions for direct ImGui usage
481inline ImVec4 GetPrimaryVec4() {
483}
484inline ImVec4 GetPrimaryHoverVec4() {
486}
487inline ImVec4 GetPrimaryActiveVec4() {
489}
490inline ImVec4 GetSurfaceVec4() {
492}
505inline ImVec4 GetOnSurfaceVec4() {
507}
511inline ImVec4 GetOnPrimaryVec4() {
513}
514inline ImVec4 GetOutlineVec4() {
516}
517inline ImVec4 GetTextSecondaryVec4() {
519}
520inline ImVec4 GetTextDisabledVec4() {
522}
523inline ImVec4 GetShadowVec4() {
525}
526} // namespace gui
527
528} // namespace yaze
529
530#endif // YAZE_APP_GUI_THEME_MANAGER_H
Manages themes, loading, saving, and switching.
Color GetSurfaceContainerHigh() const
Color ParseColorFromString(const std::string &color_str) const
Color GetSurfaceVariant() const
std::string preview_original_name_
Color GetTextSecondary() const
void ShowThemeEditor(bool *p_open)
Color GetWelcomeScreenBackground() const
ImVec4 GetThemeColorVec4(const std::string &color_name) const
void StartPreview(const std::string &theme_name)
ThemeChangedCallback on_theme_changed_
absl::Status SaveTheme(const Theme &theme, const std::string &filename)
std::string GetCurrentThemeFilePath() const
std::function< void(const std::string &)> ThemeChangedCallback
std::map< std::string, Theme > themes_
absl::Status LoadTheme(const std::string &theme_name)
const Theme & GetCurrentTheme() const
Color GetPrimaryHover() const
absl::Status LoadThemeFromFile(const std::string &filepath)
std::map< std::string, std::string > theme_file_paths_
void ApplyTheme(const std::string &theme_name)
std::string GetThemesDirectory() const
std::string current_theme_name_
ImVec4 transition_to_[ImGuiCol_COUNT]
Color GetWelcomeScreenAccent() const
void ApplyAccentColor(const Color &accent, bool dark_mode=true)
std::vector< std::string > DiscoverAvailableThemeFiles() const
std::string GetUserThemesDirectory() const
Theme CreateCustomTheme(const std::string &name)
absl::Status LoadAllAvailableThemes()
Color GetSurfaceContainer() const
Color GetOnSurfaceVariant() const
std::vector< std::string > GetThemeSearchPaths() const
void SetOnThemeChangedCallback(ThemeChangedCallback callback)
absl::Status ParseThemeFile(const std::string &content, Theme &theme)
static ThemeManager & Get()
Color GetThemeColor(const std::string &color_name) const
const std::string & GetCurrentThemeName() const
void ShowThemeSelector(bool *p_open)
Theme GenerateThemeFromAccent(const Color &accent, bool dark_mode=true)
const Theme * GetTheme(const std::string &name) const
std::string SerializeTheme(const Theme &theme) const
absl::Status RefreshAvailableThemes()
Color GetTextDisabled() const
std::string ExportCurrentThemeJson() const
absl::Status SaveThemeToFile(const Theme &theme, const std::string &filepath)
void ApplySmartDefaults(Theme &theme)
Color GetSurfaceContainerHighest() const
Color GetWelcomeScreenBorder() const
void ShowSimpleThemeEditor(bool *p_open)
Color GetPrimaryActive() const
ImVec4 transition_from_[ImGuiCol_COUNT]
std::vector< std::string > GetAvailableThemes() const
ImVec4 ConvertColorToImVec4(const Color &color)
Definition color.h:134
ImVec4 GetSurfaceContainerHighestVec4()
Color GetPrimaryHover()
Color GetOnPrimary()
ImVec4 GetThemeColorVec4(const std::string &color_name)
Color GetOnSurfaceVariant()
ImVec4 GetOnPrimaryVec4()
Color GetTextDisabled()
ImVec4 GetPrimaryActiveVec4()
Color GetSurfaceContainerHighest()
Color GetOnSurface()
ImVec4 GetPrimaryVec4()
Color GetSecondary()
Color GetSurfaceContainer()
ImVec4 GetSurfaceVariantVec4()
ImVec4 GetSurfaceVec4()
DensityPreset
Typography and spacing density presets.
ImVec4 GetTextDisabledVec4()
Color GetTextSecondary()
Color GetOutline()
Color GetShadow()
ImVec4 GetTextSecondaryVec4()
ImVec4 GetShadowVec4()
ImVec4 GetSurfaceContainerHighVec4()
ImVec4 GetPrimaryHoverVec4()
Color GetPrimaryActive()
Color GetPrimary()
Color GetSurface()
ImVec4 GetOutlineVec4()
Color GetThemeColor(const std::string &color_name)
Color GetSurfaceContainerHigh()
ImVec4 GetOnSurfaceVariantVec4()
ImVec4 GetOnSurfaceVec4()
ImVec4 GetSurfaceContainerVec4()
Color GetSurfaceVariant()
Comprehensive theme structure for YAZE.
Color tab_dimmed_selected_overline
std::string description
std::string name
Color scrollbar_grab_hovered
Color scrollbar_grab_active
Color nav_windowing_highlight
float panel_padding_multiplier
float widget_height_multiplier
struct yaze::gui::Theme::DungeonColors dungeon
struct yaze::gui::Theme::AgentTheme agent
void ApplyToImGui() const
float button_padding_multiplier
float table_row_height_multiplier
float toolbar_height_multiplier
DensityPreset density_preset
void ApplyDensityPreset(DensityPreset preset)
std::string author
float canvas_toolbar_multiplier