3#include "absl/strings/str_format.h"
6#include "imgui/imgui.h"
22 ImVec4 rgb_255 = color.
rgb();
23 return ImVec4(rgb_255.x / 255.0f, rgb_255.y / 255.0f, rgb_255.z / 255.0f,
39 ImGuiColorEditFlags flags,
40 const ImVec2& size_arg) {
45 bool pressed = ImGui::ColorButton(
id.data(), displayColor, flags, size_arg);
47 if (ImGui::IsItemHovered()) {
48 ImGui::BeginTooltip();
49 ImGui::Text(
"SNES: $%04X", color.
snes());
56 ImGuiColorEditFlags flags) {
62 ImGui::ColorEdit4(label.data(), (
float*)&displayColor.x, flags);
80 int* selected_index) {
81 bool selection_made =
false;
82 int colors_to_show = std::min(num_colors,
static_cast<int>(palette.
size()));
85 for (
int n = 0; n < colors_to_show; n++) {
87 if (n > 0 && (n % 8) != 0) {
88 ImGui::SameLine(0.0f, ImGui::GetStyle().ItemSpacing.y);
91 bool is_selected = selected_index && (*selected_index == n);
93 ImGui::PushStyleColor(ImGuiCol_Border, ImVec4(1.0f, 1.0f, 0.0f, 1.0f));
94 ImGui::PushStyleVar(ImGuiStyleVar_FrameBorderSize, 2.0f);
98 "##palettesel", palette[n],
99 ImGuiColorEditFlags_NoAlpha | ImGuiColorEditFlags_NoPicker,
101 if (selected_index) {
103 selection_made =
true;
108 ImGui::PopStyleVar();
109 ImGui::PopStyleColor();
116 return selection_made;
120 const std::string& title,
121 ImGuiColorEditFlags flags) {
122 if (!title.empty()) {
123 ImGui::Text(
"%s", title.c_str());
126 static int selected_color = 0;
127 static ImVec4 current_color = ImVec4(0, 0, 0, 1.0f);
131 if (ImGui::ColorPicker4(
"##colorpicker", (
float*)¤t_color,
132 ImGuiColorEditFlags_NoSidePreview |
133 ImGuiColorEditFlags_NoSmallPreview)) {
142 for (
int n = 0; n < palette.
size(); n++) {
145 ImGui::SameLine(0.0f, ImGui::GetStyle().ItemSpacing.y);
149 flags = ImGuiColorEditFlags_NoAlpha | ImGuiColorEditFlags_NoPicker;
152 if (
SnesColorButton(
"##palettedit", palette[n], flags, ImVec2(20, 20))) {
158 if (ImGui::BeginPopupContextItem()) {
159 if (ImGui::MenuItem(
"Copy as SNES")) {
160 std::string clipboard = absl::StrFormat(
"$%04X", palette[n].snes());
161 ImGui::SetClipboardText(clipboard.c_str());
163 if (ImGui::MenuItem(
"Copy as RGB")) {
164 auto rgb = palette[n].rgb();
165 std::string clipboard =
166 absl::StrFormat(
"(%d,%d,%d)", (
int)rgb.x, (
int)rgb.y, (
int)rgb.z);
167 ImGui::SetClipboardText(clipboard.c_str());
169 if (ImGui::MenuItem(
"Copy as Hex")) {
170 auto rgb = palette[n].rgb();
171 std::string clipboard = absl::StrFormat(
"#%02X%02X%02X", (
int)rgb.x,
172 (
int)rgb.y, (
int)rgb.z);
173 ImGui::SetClipboardText(clipboard.c_str());
182 return absl::OkStatus();
187 ImGuiColorEditFlags flags) {
188 bool modified =
false;
190 if (ImGui::BeginPopup(popup_id)) {
191 static int selected_color = 0;
192 static ImVec4 current_color = ImVec4(0, 0, 0, 1.0f);
195 if (ImGui::ColorPicker4(
"##popuppicker", (
float*)¤t_color,
196 ImGuiColorEditFlags_NoSidePreview |
197 ImGuiColorEditFlags_NoSmallPreview)) {
207 for (
int n = 0; n < palette.
size() && n < 64;
211 ImGui::SameLine(0.0f, ImGui::GetStyle().ItemSpacing.y);
215 "##popuppal", palette[n],
216 ImGuiColorEditFlags_NoAlpha | ImGuiColorEditFlags_NoPicker,
237 static ImVec4 color = ImVec4(0, 0, 0, 255.f);
238 ImGuiColorEditFlags misc_flags = ImGuiColorEditFlags_AlphaPreview |
239 ImGuiColorEditFlags_NoDragDrop |
240 ImGuiColorEditFlags_NoOptions;
243 static bool init =
false;
244 static ImVec4 saved_palette[32] = {};
245 if (loaded && !init) {
246 for (
int n = 0; n < palette.
size(); n++) {
247 auto color = palette[n];
248 saved_palette[n].x = color.rgb().x / 255;
249 saved_palette[n].y = color.rgb().y / 255;
250 saved_palette[n].z = color.rgb().z / 255;
251 saved_palette[n].w = 255;
256 static ImVec4 backup_color;
257 ImGui::Text(
"Current ==>");
259 ImGui::Text(
"Previous");
263 ImGuiColorEditFlags_NoPicker | ImGuiColorEditFlags_AlphaPreviewHalf,
267 if (ImGui::ColorButton(
268 "##previous", backup_color,
269 ImGuiColorEditFlags_NoPicker | ImGuiColorEditFlags_AlphaPreviewHalf,
271 color = backup_color;
275 ImGui::Text(
"Palette");
276 for (
int n = 0; n < IM_ARRAYSIZE(saved_palette); n++) {
279 ImGui::SameLine(0.0f, ImGui::GetStyle().ItemSpacing.y);
281 ImGuiColorEditFlags palette_button_flags = ImGuiColorEditFlags_NoAlpha |
282 ImGuiColorEditFlags_NoPicker |
283 ImGuiColorEditFlags_NoTooltip;
284 if (ImGui::ColorButton(
"##palette", saved_palette[n], palette_button_flags,
286 color = ImVec4(saved_palette[n].x, saved_palette[n].y, saved_palette[n].z,
289 if (ImGui::BeginDragDropTarget()) {
290 if (
const ImGuiPayload* payload =
291 ImGui::AcceptDragDropPayload(IMGUI_PAYLOAD_TYPE_COLOR_3F))
292 memcpy((
float*)&saved_palette[n], payload->Data,
sizeof(
float) * 3);
293 if (
const ImGuiPayload* payload =
294 ImGui::AcceptDragDropPayload(IMGUI_PAYLOAD_TYPE_COLOR_4F))
295 memcpy((
float*)&saved_palette[n], payload->Data,
sizeof(
float) * 4);
296 ImGui::EndDragDropTarget();
304 ImGui::ColorPicker4(
"##picker", (
float*)&color,
305 misc_flags | ImGuiColorEditFlags_NoSidePreview |
306 ImGuiColorEditFlags_NoSmallPreview);
312 const auto palette_row_size = 7;
313 if (ImGuiID child_id = ImGui::GetID((
void*)(intptr_t)100);
314 ImGui::BeginChild(child_id, ImGui::GetContentRegionAvail(),
true,
315 ImGuiWindowFlags_AlwaysVerticalScrollbar)) {
317 ImGui::Text(
"Palette");
318 for (
int n = 0; n < palette.
size(); n++) {
320 if ((n % palette_row_size) != 0)
321 ImGui::SameLine(0.0f, ImGui::GetStyle().ItemSpacing.y);
324 bool is_selected = (palette_id == n / palette_row_size);
328 ImGui::PushStyleColor(ImGuiCol_Border, ImVec4(1.0f, 1.0f, 0.0f, 1.0f));
329 ImGui::PushStyleVar(ImGuiStyleVar_FrameBorderSize, 2.0f);
333 ImGuiColorEditFlags_NoAlpha |
334 ImGuiColorEditFlags_NoPicker |
335 ImGuiColorEditFlags_NoTooltip,
337 palette_id = n / palette_row_size;
338 refresh_graphics =
true;
342 ImGui::PopStyleColor();
343 ImGui::PopStyleVar();
354 const std::string& title,
355 bool show_color_picker,
int colors_per_row,
356 ImGuiColorEditFlags flags) {
359 flags = ImGuiColorEditFlags_NoAlpha | ImGuiColorEditFlags_NoPicker |
360 ImGuiColorEditFlags_NoTooltip;
364 if (!title.empty()) {
365 ImGui::Text(
"%s", title.c_str());
367 static int selected_color = 0;
369 if (show_color_picker) {
371 static ImVec4 current_color = ImVec4(0, 0, 0, 1.0f);
373 if (ImGui::ColorPicker4(
"Color Picker", (
float*)¤t_color,
374 ImGuiColorEditFlags_NoSidePreview |
375 ImGuiColorEditFlags_NoSmallPreview)) {
384 for (
int n = 0; n < palette.
size(); n++) {
386 if ((n % colors_per_row) != 0) {
387 ImGui::SameLine(0.0f, ImGui::GetStyle().ItemSpacing.y);
391 std::string button_id =
"##palette_" + std::to_string(n);
399 if (ImGui::BeginPopupContextItem()) {
400 if (ImGui::MenuItem(
"Edit Color")) {
402 ImGui::OpenPopup((
"Edit Color##" + std::to_string(n)).c_str());
405 if (ImGui::MenuItem(
"Copy as SNES Value")) {
406 std::string clipboard = absl::StrFormat(
"$%04X", palette[n].snes());
407 ImGui::SetClipboardText(clipboard.c_str());
410 if (ImGui::MenuItem(
"Copy as RGB")) {
411 auto rgb = palette[n].rgb();
413 std::string clipboard =
414 absl::StrFormat(
"(%d,%d,%d)", (
int)rgb.x, (
int)rgb.y, (
int)rgb.z);
415 ImGui::SetClipboardText(clipboard.c_str());
418 if (ImGui::MenuItem(
"Copy as Hex")) {
419 auto rgb = palette[n].rgb();
421 std::string clipboard = absl::StrFormat(
"#%02X%02X%02X", (
int)rgb.x,
422 (
int)rgb.y, (
int)rgb.z);
423 ImGui::SetClipboardText(clipboard.c_str());
430 if (ImGui::BeginPopup((
"Edit Color##" + std::to_string(n)).c_str())) {
431 ImGuiColorEditFlags picker_flags = ImGuiColorEditFlags_NoSidePreview |
432 ImGuiColorEditFlags_NoSmallPreview;
435 if (ImGui::ColorPicker4(
"##picker", (
float*)&color, picker_flags)) {
447 return absl::OkStatus();
451 bool is_selected,
bool is_modified,
453 ImGuiColorEditFlags flags) {
461 ImGui::PushStyleColor(ImGuiCol_Border, ImVec4(1.0f, 0.8f, 0.0f, 1.0f));
462 ImGui::PushStyleVar(ImGuiStyleVar_FrameBorderSize, 2.0f);
465 bool clicked = ImGui::ColorButton(
id, display_color, flags, size);
468 ImGui::PopStyleVar();
469 ImGui::PopStyleColor();
474 ImVec2 pos = ImGui::GetItemRectMin();
475 ImVec2 dot_pos = ImVec2(pos.x + size.x - 6, pos.y + 2);
476 ImGui::GetWindowDrawList()->AddCircleFilled(dot_pos, 3.0f,
477 IM_COL32(255, 128, 0, 255));
481 if (ImGui::IsItemHovered()) {
482 ImGui::BeginTooltip();
483 ImGui::Text(
"SNES: $%04X", color.
snes());
484 auto rgb = color.
rgb();
485 ImGui::Text(
"RGB: (%d, %d, %d)",
static_cast<int>(rgb.x),
486 static_cast<int>(rgb.y),
static_cast<int>(rgb.z));
488 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)