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