yaze 0.2.2
Link to the Past ROM Editor
 
Loading...
Searching...
No Matches
color.cc
Go to the documentation of this file.
1#include "color.h"
2
5#include "imgui/imgui.h"
6
7namespace yaze {
8namespace gui {
9
11 return ImVec4(color.rgb().x / 255.0f, color.rgb().y / 255.0f,
12 color.rgb().z / 255.0f, 1.0f);
13}
14
16 return gfx::SnesColor(color.x, color.y, color.z);
17}
18
19IMGUI_API bool SnesColorButton(absl::string_view id, gfx::SnesColor& color,
20 ImGuiColorEditFlags flags,
21 const ImVec2& size_arg) {
22 // Convert the SNES color values to ImGui color values
23 ImVec4 displayColor = ConvertSnesColorToImVec4(color);
24
25 // Call the original ImGui::ColorButton with the converted color
26 bool pressed = ImGui::ColorButton(id.data(), displayColor, flags, size_arg);
27 // Add the SNES color representation to the tooltip
28 if (ImGui::IsItemHovered()) {
29 ImGui::BeginTooltip();
30 ImGui::Text("SNES: $%04X", color.snes());
31 ImGui::EndTooltip();
32 }
33 return pressed;
34}
35
36IMGUI_API bool SnesColorEdit4(absl::string_view label, gfx::SnesColor* color,
37 ImGuiColorEditFlags flags) {
38 ImVec4 displayColor = ConvertSnesColorToImVec4(*color);
39
40 // Call the original ImGui::ColorEdit4 with the converted color
41 bool pressed =
42 ImGui::ColorEdit4(label.data(), (float*)&displayColor.x, flags);
43
44 color->set_rgb(displayColor);
45 color->set_snes(gfx::ConvertRgbToSnes(displayColor));
46
47 return pressed;
48}
49
50IMGUI_API bool DisplayPalette(gfx::SnesPalette& palette, bool loaded) {
51 static ImVec4 color = ImVec4(0, 0, 0, 255.f);
52 ImGuiColorEditFlags misc_flags = ImGuiColorEditFlags_AlphaPreview |
53 ImGuiColorEditFlags_NoDragDrop |
54 ImGuiColorEditFlags_NoOptions;
55
56 // Generate a default palette. The palette will persist and can be edited.
57 static bool init = false;
58 static ImVec4 saved_palette[32] = {};
59 if (loaded && !init) {
60 for (int n = 0; n < palette.size(); n++) {
61 auto color = palette[n];
62 saved_palette[n].x = color.rgb().x / 255;
63 saved_palette[n].y = color.rgb().y / 255;
64 saved_palette[n].z = color.rgb().z / 255;
65 saved_palette[n].w = 255; // Alpha
66 }
67 init = true;
68 }
69
70 static ImVec4 backup_color;
71 ImGui::Text("Current ==>");
72 ImGui::SameLine();
73 ImGui::Text("Previous");
74
75 ImGui::ColorButton(
76 "##current", color,
77 ImGuiColorEditFlags_NoPicker | ImGuiColorEditFlags_AlphaPreviewHalf,
78 ImVec2(60, 40));
79 ImGui::SameLine();
80
81 if (ImGui::ColorButton(
82 "##previous", backup_color,
83 ImGuiColorEditFlags_NoPicker | ImGuiColorEditFlags_AlphaPreviewHalf,
84 ImVec2(60, 40)))
85 color = backup_color;
86 ImGui::Separator();
87
88 ImGui::BeginGroup(); // Lock X position
89 ImGui::Text("Palette");
90 for (int n = 0; n < IM_ARRAYSIZE(saved_palette); n++) {
91 ImGui::PushID(n);
92 if ((n % 4) != 0) ImGui::SameLine(0.0f, ImGui::GetStyle().ItemSpacing.y);
93
94 ImGuiColorEditFlags palette_button_flags = ImGuiColorEditFlags_NoAlpha |
95 ImGuiColorEditFlags_NoPicker |
96 ImGuiColorEditFlags_NoTooltip;
97 if (ImGui::ColorButton("##palette", saved_palette[n], palette_button_flags,
98 ImVec2(20, 20)))
99 color = ImVec4(saved_palette[n].x, saved_palette[n].y, saved_palette[n].z,
100 color.w); // Preserve alpha!
101
102 if (ImGui::BeginDragDropTarget()) {
103 if (const ImGuiPayload* payload =
104 ImGui::AcceptDragDropPayload(IMGUI_PAYLOAD_TYPE_COLOR_3F))
105 memcpy((float*)&saved_palette[n], payload->Data, sizeof(float) * 3);
106 if (const ImGuiPayload* payload =
107 ImGui::AcceptDragDropPayload(IMGUI_PAYLOAD_TYPE_COLOR_4F))
108 memcpy((float*)&saved_palette[n], payload->Data, sizeof(float) * 4);
109 ImGui::EndDragDropTarget();
110 }
111
112 ImGui::PopID();
113 }
114 ImGui::EndGroup();
115 ImGui::SameLine();
116
117 ImGui::ColorPicker4("##picker", (float*)&color,
118 misc_flags | ImGuiColorEditFlags_NoSidePreview |
119 ImGuiColorEditFlags_NoSmallPreview);
120 return true;
121}
122
123void SelectablePalettePipeline(uint64_t& palette_id, bool& refresh_graphics,
124 gfx::SnesPalette& palette) {
125 const auto palette_row_size = 7;
126 if (ImGuiID child_id = ImGui::GetID((void*)(intptr_t)100);
127 ImGui::BeginChild(child_id, ImGui::GetContentRegionAvail(), true,
128 ImGuiWindowFlags_AlwaysVerticalScrollbar)) {
129 ImGui::BeginGroup(); // Lock X position
130 ImGui::Text("Palette");
131 for (int n = 0; n < palette.size(); n++) {
132 ImGui::PushID(n);
133 if ((n % palette_row_size) != 0)
134 ImGui::SameLine(0.0f, ImGui::GetStyle().ItemSpacing.y);
135
136 // Check if the current row is selected
137 bool is_selected = (palette_id == n / palette_row_size);
138
139 // Add outline rectangle to the selected row
140 if (is_selected) {
141 ImGui::PushStyleColor(ImGuiCol_Border, ImVec4(1.0f, 1.0f, 0.0f, 1.0f));
142 ImGui::PushStyleVar(ImGuiStyleVar_FrameBorderSize, 2.0f);
143 }
144
145 if (gui::SnesColorButton("##palette", palette[n],
146 ImGuiColorEditFlags_NoAlpha |
147 ImGuiColorEditFlags_NoPicker |
148 ImGuiColorEditFlags_NoTooltip,
149 ImVec2(20, 20))) {
150 palette_id = n / palette_row_size;
151 refresh_graphics = true;
152 }
153
154 if (is_selected) {
155 ImGui::PopStyleColor();
156 ImGui::PopStyleVar();
157 }
158
159 ImGui::PopID();
160 }
161 ImGui::EndGroup();
162 }
163 ImGui::EndChild();
164}
165
167 const std::string& title,
168 bool show_color_picker, int colors_per_row,
169 ImGuiColorEditFlags flags) {
170 // Default flags if none provided
171 if (flags == 0) {
172 flags = ImGuiColorEditFlags_NoAlpha | ImGuiColorEditFlags_NoPicker |
173 ImGuiColorEditFlags_NoTooltip;
174 }
175
176 // Display title if provided
177 if (!title.empty()) {
178 ImGui::Text("%s", title.c_str());
179 }
180 static int selected_color = 0;
181
182 if (show_color_picker) {
183 ImGui::Separator();
184 static ImVec4 current_color = ImVec4(0, 0, 0, 1.0f);
185
186 if (ImGui::ColorPicker4("Color Picker", (float*)&current_color,
187 ImGuiColorEditFlags_NoSidePreview |
188 ImGuiColorEditFlags_NoSmallPreview)) {
189 // Convert the selected color to SNES format and add it to the palette
190 gfx::SnesColor snes_color(current_color);
191 palette.UpdateColor(selected_color, snes_color);
192 }
193 }
194
195 // Display the palette colors in a grid
196 ImGui::BeginGroup(); // Lock X position
197 for (int n = 0; n < palette.size(); n++) {
198 ImGui::PushID(n);
199 if ((n % colors_per_row) != 0) {
200 ImGui::SameLine(0.0f, ImGui::GetStyle().ItemSpacing.y);
201 }
202
203 // Create a unique ID for this color button
204 std::string button_id = "##palette_" + std::to_string(n);
205
206 // Display the color button
207 if (SnesColorButton(button_id, palette[n], flags, ImVec2(20, 20))) {
208 // Color was clicked, could be used to select this color
209 selected_color = n;
210 }
211
212 if (ImGui::BeginPopupContextItem()) {
213 if (ImGui::MenuItem("Edit Color")) {
214 // Open color picker for this color
215 ImGui::OpenPopup(("Edit Color##" + std::to_string(n)).c_str());
216 }
217
218 if (ImGui::MenuItem("Copy as SNES Value")) {
219 std::string clipboard = absl::StrFormat("$%04X", palette[n].snes());
220 ImGui::SetClipboardText(clipboard.c_str());
221 }
222
223 if (ImGui::MenuItem("Copy as RGB")) {
224 auto rgb = palette[n].rgb();
225 std::string clipboard =
226 absl::StrFormat("(%d,%d,%d)", (int)(rgb.x * 255),
227 (int)(rgb.y * 255), (int)(rgb.z * 255));
228 ImGui::SetClipboardText(clipboard.c_str());
229 }
230
231 if (ImGui::MenuItem("Copy as Hex")) {
232 auto rgb = palette[n].rgb();
233 std::string clipboard =
234 absl::StrFormat("#%02X%02X%02X", (int)(rgb.x * 255),
235 (int)(rgb.y * 255), (int)(rgb.z * 255));
236 ImGui::SetClipboardText(clipboard.c_str());
237 }
238
239 ImGui::EndPopup();
240 }
241
242 // Color picker popup
243 if (ImGui::BeginPopup(("Edit Color##" + std::to_string(n)).c_str())) {
244 ImGuiColorEditFlags picker_flags = ImGuiColorEditFlags_NoSidePreview |
245 ImGuiColorEditFlags_NoSmallPreview;
246
247 ImVec4 color = ConvertSnesColorToImVec4(palette[n]);
248 if (ImGui::ColorPicker4("##picker", (float*)&color, picker_flags)) {
249 // Update the SNES color when the picker changes
250 palette[n] = ConvertImVec4ToSnesColor(color);
251 }
252
253 ImGui::EndPopup();
254 }
255
256 ImGui::PopID();
257 }
258 ImGui::EndGroup();
259
260 return absl::OkStatus();
261}
262
263} // namespace gui
264} // namespace yaze
SNES Color container.
Definition snes_color.h:38
constexpr ImVec4 rgb() const
Definition snes_color.h:74
void set_snes(uint16_t val)
constexpr uint16_t snes() const
Definition snes_color.h:76
void set_rgb(const ImVec4 val)
Represents a palette of colors for the Super Nintendo Entertainment System (SNES).
void UpdateColor(size_t index, const SnesColor &color)
uint16_t ConvertRgbToSnes(const snes_color &color)
Definition snes_color.cc:33
Graphical User Interface (GUI) components for the application.
Definition canvas.cc:13
IMGUI_API bool SnesColorButton(absl::string_view id, gfx::SnesColor &color, ImGuiColorEditFlags flags, const ImVec2 &size_arg)
Definition color.cc:19
ImVec4 ConvertSnesColorToImVec4(const gfx::SnesColor &color)
Definition color.cc:10
void SelectablePalettePipeline(uint64_t &palette_id, bool &refresh_graphics, gfx::SnesPalette &palette)
Definition color.cc:123
IMGUI_API bool SnesColorEdit4(absl::string_view label, gfx::SnesColor *color, ImGuiColorEditFlags flags)
Definition color.cc:36
IMGUI_API bool DisplayPalette(gfx::SnesPalette &palette, bool loaded)
Definition color.cc:50
gfx::SnesColor ConvertImVec4ToSnesColor(const ImVec4 &color)
Definition color.cc:15
absl::Status DisplayEditablePalette(gfx::SnesPalette &palette, const std::string &title, bool show_color_picker, int colors_per_row, ImGuiColorEditFlags flags)
Definition color.cc:166
Main namespace for the application.
Definition controller.cc:12
Primitive of 16-bit RGB SNES color.
Definition yaze.h:43
struct snes_color snes_color
Primitive of 16-bit RGB SNES color.