yaze 0.3.2
Link to the Past ROM Editor
 
Loading...
Searching...
No Matches
color.h
Go to the documentation of this file.
1#ifndef YAZE_GUI_COLOR_H
2#define YAZE_GUI_COLOR_H
3
4#include <algorithm>
5#include <cmath>
6#include <string>
7
8#include "absl/status/status.h"
9#include "absl/strings/str_format.h"
11#include "imgui/imgui.h"
12
13namespace yaze {
14namespace gui {
15
16struct Color {
17 float red = 0.0f;
18 float green = 0.0f;
19 float blue = 0.0f;
20 float alpha = 1.0f;
21
22 operator ImVec4() const { return ImVec4(red, green, blue, alpha); }
23
24 // HSL conversion utilities for theme generation
25 struct HSL {
26 float h = 0.0f; // 0-360
27 float s = 0.0f; // 0-1
28 float l = 0.0f; // 0-1
29 };
30
31 HSL ToHSL() const {
32 float max_val = std::max({red, green, blue});
33 float min_val = std::min({red, green, blue});
34 float delta = max_val - min_val;
35
36 HSL hsl;
37 hsl.l = (max_val + min_val) / 2.0f;
38
39 if (delta < 0.00001f) {
40 hsl.h = 0.0f;
41 hsl.s = 0.0f;
42 } else {
43 hsl.s = hsl.l > 0.5f ? delta / (2.0f - max_val - min_val)
44 : delta / (max_val + min_val);
45
46 if (max_val == red) {
47 hsl.h = 60.0f * fmodf((green - blue) / delta, 6.0f);
48 } else if (max_val == green) {
49 hsl.h = 60.0f * ((blue - red) / delta + 2.0f);
50 } else {
51 hsl.h = 60.0f * ((red - green) / delta + 4.0f);
52 }
53 if (hsl.h < 0.0f) {
54 hsl.h += 360.0f;
55 }
56 }
57 return hsl;
58 }
59
60 static Color FromHSL(float h, float s, float l, float a = 1.0f) {
61 auto hue_to_rgb = [](float p, float q, float t) {
62 if (t < 0.0f)
63 t += 1.0f;
64 if (t > 1.0f)
65 t -= 1.0f;
66 if (t < 1.0f / 6.0f)
67 return p + (q - p) * 6.0f * t;
68 if (t < 1.0f / 2.0f)
69 return q;
70 if (t < 2.0f / 3.0f)
71 return p + (q - p) * (2.0f / 3.0f - t) * 6.0f;
72 return p;
73 };
74
75 Color result;
76 result.alpha = a;
77
78 if (s < 0.00001f) {
79 result.red = result.green = result.blue = l;
80 } else {
81 float h_norm = h / 360.0f;
82 float q = l < 0.5f ? l * (1.0f + s) : l + s - l * s;
83 float p = 2.0f * l - q;
84 result.red = hue_to_rgb(p, q, h_norm + 1.0f / 3.0f);
85 result.green = hue_to_rgb(p, q, h_norm);
86 result.blue = hue_to_rgb(p, q, h_norm - 1.0f / 3.0f);
87 }
88 return result;
89 }
90
91 // Derive a new color by adjusting HSL components
92 Color WithHue(float new_hue) const {
93 HSL hsl = ToHSL();
94 return FromHSL(new_hue, hsl.s, hsl.l, alpha);
95 }
96
97 Color WithSaturation(float new_sat) const {
98 HSL hsl = ToHSL();
99 return FromHSL(hsl.h, std::clamp(new_sat, 0.0f, 1.0f), hsl.l, alpha);
100 }
101
102 Color WithLightness(float new_light) const {
103 HSL hsl = ToHSL();
104 return FromHSL(hsl.h, hsl.s, std::clamp(new_light, 0.0f, 1.0f), alpha);
105 }
106
107 Color Lighter(float amount) const {
108 HSL hsl = ToHSL();
109 return FromHSL(hsl.h, hsl.s, std::clamp(hsl.l + amount, 0.0f, 1.0f), alpha);
110 }
111
112 Color Darker(float amount) const {
113 HSL hsl = ToHSL();
114 return FromHSL(hsl.h, hsl.s, std::clamp(hsl.l - amount, 0.0f, 1.0f), alpha);
115 }
116
117 Color Saturate(float amount) const {
118 HSL hsl = ToHSL();
119 return FromHSL(hsl.h, std::clamp(hsl.s + amount, 0.0f, 1.0f), hsl.l, alpha);
120 }
121
122 Color Desaturate(float amount) const {
123 HSL hsl = ToHSL();
124 return FromHSL(hsl.h, std::clamp(hsl.s - amount, 0.0f, 1.0f), hsl.l, alpha);
125 }
126
127 Color ShiftHue(float degrees) const {
128 HSL hsl = ToHSL();
129 float new_hue = fmodf(hsl.h + degrees, 360.0f);
130 if (new_hue < 0.0f)
131 new_hue += 360.0f;
132 return FromHSL(new_hue, hsl.s, hsl.l, alpha);
133 }
134
135 Color WithAlpha(float new_alpha) const {
136 return Color{red, green, blue, std::clamp(new_alpha, 0.0f, 1.0f)};
137 }
138};
139
140inline ImVec4 ConvertColorToImVec4(const Color& color) {
141 return ImVec4(color.red, color.green, color.blue, color.alpha);
142}
143
144inline std::string ColorToHexString(const Color& color) {
145 return absl::StrFormat("%02X%02X%02X%02X", static_cast<int>(color.red * 255),
146 static_cast<int>(color.green * 255),
147 static_cast<int>(color.blue * 255),
148 static_cast<int>(color.alpha * 255));
149}
150
151// A utility function to convert an SnesColor object to an ImVec4 with
152// normalized color values
153ImVec4 ConvertSnesColorToImVec4(const gfx::SnesColor& color);
154
155// A utility function to convert an ImVec4 to an SnesColor object
156gfx::SnesColor ConvertImVec4ToSnesColor(const ImVec4& color);
157
158// Clipboard formats for a SNES color, shared by every "Copy as" menu.
159std::string SnesColorToSnesString(const gfx::SnesColor& color); // "$7FFF"
160std::string SnesColorToRgbString(const gfx::SnesColor& color); // "(r,g,b)"
161std::string SnesColorToHexString(const gfx::SnesColor& color); // "#RRGGBB"
162
163// Renders "Copy as SNES / RGB / Hex" menu items, each showing the value it
164// copies in the shortcut column. Call inside an open popup or menu.
165void SnesColorCopyMenuItems(const gfx::SnesColor& color);
166
167// The wrapper function for ImGui::ColorButton that takes a SnesColor reference
168IMGUI_API bool SnesColorButton(absl::string_view id, gfx::SnesColor& color,
169 ImGuiColorEditFlags flags = 0,
170 const ImVec2& size_arg = ImVec2(0, 0));
171
172IMGUI_API bool SnesColorEdit4(absl::string_view label, gfx::SnesColor* color,
173 ImGuiColorEditFlags flags = 0);
174
175// ============================================================================
176// Palette Widget Functions
177// ============================================================================
178
186IMGUI_API bool InlinePaletteSelector(gfx::SnesPalette& palette,
187 int num_colors = 8,
188 int* selected_index = nullptr);
189
197IMGUI_API absl::Status InlinePaletteEditor(gfx::SnesPalette& palette,
198 const std::string& title = "",
199 ImGuiColorEditFlags flags = 0);
200
208IMGUI_API bool PopupPaletteEditor(const char* popup_id,
209 gfx::SnesPalette& palette,
210 ImGuiColorEditFlags flags = 0);
211
212// Legacy functions (kept for compatibility, will be deprecated)
213IMGUI_API bool DisplayPalette(gfx::SnesPalette& palette, bool loaded);
214
215IMGUI_API absl::Status DisplayEditablePalette(gfx::SnesPalette& palette,
216 const std::string& title = "",
217 bool show_color_picker = false,
218 int colors_per_row = 8,
219 ImGuiColorEditFlags flags = 0);
220
221void SelectablePalettePipeline(uint64_t& palette_id, bool& refresh_graphics,
222 gfx::SnesPalette& palette);
223
224// Palette color button with selection and modification indicators
225IMGUI_API bool PaletteColorButton(const char* id, const gfx::SnesColor& color,
226 bool is_selected, bool is_modified,
227 const ImVec2& size = ImVec2(28, 28),
228 ImGuiColorEditFlags flags = 0);
229
230} // namespace gui
231} // namespace yaze
232
233#endif
SNES Color container.
Definition snes_color.h:110
Represents a palette of colors for the Super Nintendo Entertainment System (SNES).
std::string SnesColorToRgbString(const gfx::SnesColor &color)
Definition color.cc:46
ImVec4 ConvertColorToImVec4(const Color &color)
Definition color.h:140
IMGUI_API bool InlinePaletteSelector(gfx::SnesPalette &palette, int num_colors, int *selected_index)
Small inline palette selector - just color buttons for selection.
Definition color.cc:121
IMGUI_API bool SnesColorButton(absl::string_view id, gfx::SnesColor &color, ImGuiColorEditFlags flags, const ImVec2 &size_arg)
Definition color.cc:80
IMGUI_API bool PopupPaletteEditor(const char *popup_id, gfx::SnesPalette &palette, ImGuiColorEditFlags flags)
Popup palette editor - same as inline but in a popup.
Definition color.cc:212
IMGUI_API absl::Status InlinePaletteEditor(gfx::SnesPalette &palette, const std::string &title, ImGuiColorEditFlags flags)
Full inline palette editor with color picker and copy options.
Definition color.cc:161
void SnesColorCopyMenuItems(const gfx::SnesColor &color)
Definition color.cc:59
IMGUI_API bool PaletteColorButton(const char *id, const gfx::SnesColor &color, bool is_selected, bool is_modified, const ImVec2 &size, ImGuiColorEditFlags flags)
Definition color.cc:463
ImVec4 ConvertSnesColorToImVec4(const gfx::SnesColor &color)
Convert SnesColor to standard ImVec4 for display.
Definition color.cc:24
void SelectablePalettePipeline(uint64_t &palette_id, bool &refresh_graphics, gfx::SnesPalette &palette)
Definition color.cc:338
IMGUI_API bool SnesColorEdit4(absl::string_view label, gfx::SnesColor *color, ImGuiColorEditFlags flags)
Definition color.cc:97
std::string ColorToHexString(const Color &color)
Definition color.h:144
IMGUI_API bool DisplayPalette(gfx::SnesPalette &palette, bool loaded)
Definition color.cc:263
gfx::SnesColor ConvertImVec4ToSnesColor(const ImVec4 &color)
Convert standard ImVec4 to SnesColor.
Definition color.cc:37
std::string SnesColorToHexString(const gfx::SnesColor &color)
Definition color.cc:53
absl::Status DisplayEditablePalette(gfx::SnesPalette &palette, const std::string &title, bool show_color_picker, int colors_per_row, ImGuiColorEditFlags flags)
Definition color.cc:381
std::string SnesColorToSnesString(const gfx::SnesColor &color)
Definition color.cc:42
Color WithHue(float new_hue) const
Definition color.h:92
HSL ToHSL() const
Definition color.h:31
Color Darker(float amount) const
Definition color.h:112
Color WithLightness(float new_light) const
Definition color.h:102
Color WithAlpha(float new_alpha) const
Definition color.h:135
Color WithSaturation(float new_sat) const
Definition color.h:97
static Color FromHSL(float h, float s, float l, float a=1.0f)
Definition color.h:60
Color Lighter(float amount) const
Definition color.h:107
Color Desaturate(float amount) const
Definition color.h:122
Color ShiftHue(float degrees) const
Definition color.h:127
Color Saturate(float amount) const
Definition color.h:117
float alpha
Definition color.h:20
float green
Definition color.h:18