5#include "imgui/imgui.h"
21 ImVec4 rgb_255 = color.
rgb();
22 return ImVec4(rgb_255.x / 255.0f, rgb_255.y / 255.0f, rgb_255.z / 255.0f,
38 ImGuiColorEditFlags flags,
39 const ImVec2& size_arg) {
44 bool pressed = ImGui::ColorButton(
id.data(), displayColor, flags, size_arg);
46 if (ImGui::IsItemHovered()) {
47 ImGui::BeginTooltip();
48 ImGui::Text(
"SNES: $%04X", color.
snes());
55 ImGuiColorEditFlags flags) {
61 ImGui::ColorEdit4(label.data(), (
float*)&displayColor.x, flags);
79 int* selected_index) {
80 bool selection_made =
false;
81 int colors_to_show = std::min(num_colors,
static_cast<int>(palette.
size()));
84 for (
int n = 0; n < colors_to_show; n++) {
86 if (n > 0 && (n % 8) != 0) {
87 ImGui::SameLine(0.0f, ImGui::GetStyle().ItemSpacing.y);
90 bool is_selected = selected_index && (*selected_index == n);
92 ImGui::PushStyleColor(ImGuiCol_Border, ImVec4(1.0f, 1.0f, 0.0f, 1.0f));
93 ImGui::PushStyleVar(ImGuiStyleVar_FrameBorderSize, 2.0f);
97 "##palettesel", palette[n],
98 ImGuiColorEditFlags_NoAlpha | ImGuiColorEditFlags_NoPicker,
100 if (selected_index) {
102 selection_made =
true;
107 ImGui::PopStyleVar();
108 ImGui::PopStyleColor();
115 return selection_made;
119 const std::string& title,
120 ImGuiColorEditFlags flags) {
121 if (!title.empty()) {
122 ImGui::Text(
"%s", title.c_str());
125 static int selected_color = 0;
126 static ImVec4 current_color = ImVec4(0, 0, 0, 1.0f);
130 if (ImGui::ColorPicker4(
"##colorpicker", (
float*)¤t_color,
131 ImGuiColorEditFlags_NoSidePreview |
132 ImGuiColorEditFlags_NoSmallPreview)) {
141 for (
int n = 0; n < palette.
size(); n++) {
144 ImGui::SameLine(0.0f, ImGui::GetStyle().ItemSpacing.y);
148 flags = ImGuiColorEditFlags_NoAlpha | ImGuiColorEditFlags_NoPicker;
151 if (
SnesColorButton(
"##palettedit", palette[n], flags, ImVec2(20, 20))) {
157 if (ImGui::BeginPopupContextItem()) {
158 if (ImGui::MenuItem(
"Copy as SNES")) {
159 std::string clipboard = absl::StrFormat(
"$%04X", palette[n].snes());
160 ImGui::SetClipboardText(clipboard.c_str());
162 if (ImGui::MenuItem(
"Copy as RGB")) {
163 auto rgb = palette[n].rgb();
164 std::string clipboard =
165 absl::StrFormat(
"(%d,%d,%d)", (
int)rgb.x, (
int)rgb.y, (
int)rgb.z);
166 ImGui::SetClipboardText(clipboard.c_str());
168 if (ImGui::MenuItem(
"Copy as Hex")) {
169 auto rgb = palette[n].rgb();
170 std::string clipboard = absl::StrFormat(
"#%02X%02X%02X", (
int)rgb.x,
171 (
int)rgb.y, (
int)rgb.z);
172 ImGui::SetClipboardText(clipboard.c_str());
181 return absl::OkStatus();
186 ImGuiColorEditFlags flags) {
187 bool modified =
false;
189 if (ImGui::BeginPopup(popup_id)) {
190 static int selected_color = 0;
191 static ImVec4 current_color = ImVec4(0, 0, 0, 1.0f);
194 if (ImGui::ColorPicker4(
"##popuppicker", (
float*)¤t_color,
195 ImGuiColorEditFlags_NoSidePreview |
196 ImGuiColorEditFlags_NoSmallPreview)) {
206 for (
int n = 0; n < palette.
size() && n < 64;
210 ImGui::SameLine(0.0f, ImGui::GetStyle().ItemSpacing.y);
214 "##popuppal", palette[n],
215 ImGuiColorEditFlags_NoAlpha | ImGuiColorEditFlags_NoPicker,
236 static ImVec4 color = ImVec4(0, 0, 0, 255.f);
237 ImGuiColorEditFlags misc_flags = ImGuiColorEditFlags_AlphaPreview |
238 ImGuiColorEditFlags_NoDragDrop |
239 ImGuiColorEditFlags_NoOptions;
242 static bool init =
false;
243 static ImVec4 saved_palette[32] = {};
244 if (loaded && !init) {
245 for (
int n = 0; n < palette.
size(); n++) {
246 auto color = palette[n];
247 saved_palette[n].x = color.rgb().x / 255;
248 saved_palette[n].y = color.rgb().y / 255;
249 saved_palette[n].z = color.rgb().z / 255;
250 saved_palette[n].w = 255;
255 static ImVec4 backup_color;
256 ImGui::Text(
"Current ==>");
258 ImGui::Text(
"Previous");
262 ImGuiColorEditFlags_NoPicker | ImGuiColorEditFlags_AlphaPreviewHalf,
266 if (ImGui::ColorButton(
267 "##previous", backup_color,
268 ImGuiColorEditFlags_NoPicker | ImGuiColorEditFlags_AlphaPreviewHalf,
270 color = backup_color;
274 ImGui::Text(
"Palette");
275 for (
int n = 0; n < IM_ARRAYSIZE(saved_palette); n++) {
278 ImGui::SameLine(0.0f, ImGui::GetStyle().ItemSpacing.y);
280 ImGuiColorEditFlags palette_button_flags = ImGuiColorEditFlags_NoAlpha |
281 ImGuiColorEditFlags_NoPicker |
282 ImGuiColorEditFlags_NoTooltip;
283 if (ImGui::ColorButton(
"##palette", saved_palette[n], palette_button_flags,
285 color = ImVec4(saved_palette[n].x, saved_palette[n].y, saved_palette[n].z,
288 if (ImGui::BeginDragDropTarget()) {
289 if (
const ImGuiPayload* payload =
290 ImGui::AcceptDragDropPayload(IMGUI_PAYLOAD_TYPE_COLOR_3F))
291 memcpy((
float*)&saved_palette[n], payload->Data,
sizeof(
float) * 3);
292 if (
const ImGuiPayload* payload =
293 ImGui::AcceptDragDropPayload(IMGUI_PAYLOAD_TYPE_COLOR_4F))
294 memcpy((
float*)&saved_palette[n], payload->Data,
sizeof(
float) * 4);
295 ImGui::EndDragDropTarget();
303 ImGui::ColorPicker4(
"##picker", (
float*)&color,
304 misc_flags | ImGuiColorEditFlags_NoSidePreview |
305 ImGuiColorEditFlags_NoSmallPreview);
311 const auto palette_row_size = 7;
312 if (ImGuiID child_id = ImGui::GetID((
void*)(intptr_t)100);
313 ImGui::BeginChild(child_id, ImGui::GetContentRegionAvail(),
true,
314 ImGuiWindowFlags_AlwaysVerticalScrollbar)) {
316 ImGui::Text(
"Palette");
317 for (
int n = 0; n < palette.
size(); n++) {
319 if ((n % palette_row_size) != 0)
320 ImGui::SameLine(0.0f, ImGui::GetStyle().ItemSpacing.y);
323 bool is_selected = (palette_id == n / palette_row_size);
327 ImGui::PushStyleColor(ImGuiCol_Border, ImVec4(1.0f, 1.0f, 0.0f, 1.0f));
328 ImGui::PushStyleVar(ImGuiStyleVar_FrameBorderSize, 2.0f);
332 ImGuiColorEditFlags_NoAlpha |
333 ImGuiColorEditFlags_NoPicker |
334 ImGuiColorEditFlags_NoTooltip,
336 palette_id = n / palette_row_size;
337 refresh_graphics =
true;
341 ImGui::PopStyleColor();
342 ImGui::PopStyleVar();
353 const std::string& title,
354 bool show_color_picker,
int colors_per_row,
355 ImGuiColorEditFlags flags) {
358 flags = ImGuiColorEditFlags_NoAlpha | ImGuiColorEditFlags_NoPicker |
359 ImGuiColorEditFlags_NoTooltip;
363 if (!title.empty()) {
364 ImGui::Text(
"%s", title.c_str());
366 static int selected_color = 0;
368 if (show_color_picker) {
370 static ImVec4 current_color = ImVec4(0, 0, 0, 1.0f);
372 if (ImGui::ColorPicker4(
"Color Picker", (
float*)¤t_color,
373 ImGuiColorEditFlags_NoSidePreview |
374 ImGuiColorEditFlags_NoSmallPreview)) {
383 for (
int n = 0; n < palette.
size(); n++) {
385 if ((n % colors_per_row) != 0) {
386 ImGui::SameLine(0.0f, ImGui::GetStyle().ItemSpacing.y);
390 std::string button_id =
"##palette_" + std::to_string(n);
398 if (ImGui::BeginPopupContextItem()) {
399 if (ImGui::MenuItem(
"Edit Color")) {
401 ImGui::OpenPopup((
"Edit Color##" + std::to_string(n)).c_str());
404 if (ImGui::MenuItem(
"Copy as SNES Value")) {
405 std::string clipboard = absl::StrFormat(
"$%04X", palette[n].snes());
406 ImGui::SetClipboardText(clipboard.c_str());
409 if (ImGui::MenuItem(
"Copy as RGB")) {
410 auto rgb = palette[n].rgb();
412 std::string clipboard =
413 absl::StrFormat(
"(%d,%d,%d)", (
int)rgb.x, (
int)rgb.y, (
int)rgb.z);
414 ImGui::SetClipboardText(clipboard.c_str());
417 if (ImGui::MenuItem(
"Copy as Hex")) {
418 auto rgb = palette[n].rgb();
420 std::string clipboard = absl::StrFormat(
"#%02X%02X%02X", (
int)rgb.x,
421 (
int)rgb.y, (
int)rgb.z);
422 ImGui::SetClipboardText(clipboard.c_str());
429 if (ImGui::BeginPopup((
"Edit Color##" + std::to_string(n)).c_str())) {
430 ImGuiColorEditFlags picker_flags = ImGuiColorEditFlags_NoSidePreview |
431 ImGuiColorEditFlags_NoSmallPreview;
434 if (ImGui::ColorPicker4(
"##picker", (
float*)&color, picker_flags)) {
446 return absl::OkStatus();
450 bool is_selected,
bool is_modified,
452 ImGuiColorEditFlags flags) {
460 ImGui::PushStyleColor(ImGuiCol_Border, ImVec4(1.0f, 0.8f, 0.0f, 1.0f));
461 ImGui::PushStyleVar(ImGuiStyleVar_FrameBorderSize, 2.0f);
464 bool clicked = ImGui::ColorButton(
id, display_color, flags, size);
467 ImGui::PopStyleVar();
468 ImGui::PopStyleColor();
473 ImVec2 pos = ImGui::GetItemRectMin();
474 ImVec2 dot_pos = ImVec2(pos.x + size.x - 6, pos.y + 2);
475 ImGui::GetWindowDrawList()->AddCircleFilled(dot_pos, 3.0f,
476 IM_COL32(255, 128, 0, 255));
480 if (ImGui::IsItemHovered()) {
481 ImGui::BeginTooltip();
482 ImGui::Text(
"SNES: $%04X", color.
snes());
483 auto rgb = color.
rgb();
484 ImGui::Text(
"RGB: (%d, %d, %d)",
static_cast<int>(rgb.x),
485 static_cast<int>(rgb.y),
static_cast<int>(rgb.z));
487 ImGui::TextColored(ImVec4(1.0f, 0.6f, 0.0f, 1.0f),
"Modified");
constexpr ImVec4 rgb() const
Get RGB values (WARNING: stored as 0-255 in ImVec4)
constexpr uint16_t snes() const
Get SNES 15-bit color.
void set_rgb(const ImVec4 val)
Set color from ImVec4 (0.0-1.0 range)
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
SNES color in 15-bit RGB format (BGR555)
IMGUI_API bool InlinePaletteSelector(gfx::SnesPalette &palette, int num_colors, int *selected_index)
Small inline palette selector - just color buttons for selection.
IMGUI_API bool SnesColorButton(absl::string_view id, gfx::SnesColor &color, ImGuiColorEditFlags flags, const ImVec2 &size_arg)
IMGUI_API bool PopupPaletteEditor(const char *popup_id, gfx::SnesPalette &palette, ImGuiColorEditFlags flags)
Popup palette editor - same as inline but in a popup.
IMGUI_API absl::Status InlinePaletteEditor(gfx::SnesPalette &palette, const std::string &title, ImGuiColorEditFlags flags)
Full inline palette editor with color picker and copy options.
IMGUI_API bool PaletteColorButton(const char *id, const gfx::SnesColor &color, bool is_selected, bool is_modified, const ImVec2 &size, ImGuiColorEditFlags flags)
ImVec4 ConvertSnesColorToImVec4(const gfx::SnesColor &color)
Convert SnesColor to standard ImVec4 for display.
void SelectablePalettePipeline(uint64_t &palette_id, bool &refresh_graphics, gfx::SnesPalette &palette)
IMGUI_API bool SnesColorEdit4(absl::string_view label, gfx::SnesColor *color, ImGuiColorEditFlags flags)
IMGUI_API bool DisplayPalette(gfx::SnesPalette &palette, bool loaded)
gfx::SnesColor ConvertImVec4ToSnesColor(const ImVec4 &color)
Convert standard ImVec4 to SnesColor.
absl::Status DisplayEditablePalette(gfx::SnesPalette &palette, const std::string &title, bool show_color_picker, int colors_per_row, ImGuiColorEditFlags flags)
SNES color in 15-bit RGB format (BGR555)