6#include "absl/strings/str_format.h"
9#include "imgui/imgui.h"
25 ImVec4 rgb_255 = color.
rgb();
26 return ImVec4(rgb_255.x / 255.0f, rgb_255.y / 255.0f, rgb_255.z / 255.0f,
42 ImGuiColorEditFlags flags,
43 const ImVec2& size_arg) {
48 bool pressed = ImGui::ColorButton(
id.data(), displayColor, flags, size_arg);
50 if (ImGui::IsItemHovered()) {
51 ImGui::BeginTooltip();
52 ImGui::Text(tr(
"SNES: $%04X"), color.
snes());
59 ImGuiColorEditFlags flags) {
65 ImGui::ColorEdit4(label.data(), (
float*)&displayColor.x, flags);
83 int* selected_index) {
84 bool selection_made =
false;
85 int colors_to_show = std::min(num_colors,
static_cast<int>(palette.
size()));
88 for (
int n = 0; n < colors_to_show; n++) {
90 if (n > 0 && (n % 8) != 0) {
91 ImGui::SameLine(0.0f, ImGui::GetStyle().ItemSpacing.y);
94 bool is_selected = selected_index && (*selected_index == n);
96 ImGui::PushStyleColor(ImGuiCol_Border, ImVec4(1.0f, 1.0f, 0.0f, 1.0f));
97 ImGui::PushStyleVar(ImGuiStyleVar_FrameBorderSize, 2.0f);
101 "##palettesel", palette[n],
102 ImGuiColorEditFlags_NoAlpha | ImGuiColorEditFlags_NoPicker,
104 if (selected_index) {
106 selection_made =
true;
111 ImGui::PopStyleVar();
112 ImGui::PopStyleColor();
119 return selection_made;
123 const std::string& title,
124 ImGuiColorEditFlags flags) {
125 if (!title.empty()) {
126 ImGui::Text(
"%s", title.c_str());
129 static int selected_color = 0;
130 static ImVec4 current_color = ImVec4(0, 0, 0, 1.0f);
134 if (ImGui::ColorPicker4(
"##colorpicker", (
float*)¤t_color,
135 ImGuiColorEditFlags_NoSidePreview |
136 ImGuiColorEditFlags_NoSmallPreview)) {
145 for (
int n = 0; n < palette.
size(); n++) {
148 ImGui::SameLine(0.0f, ImGui::GetStyle().ItemSpacing.y);
152 flags = ImGuiColorEditFlags_NoAlpha | ImGuiColorEditFlags_NoPicker;
155 if (
SnesColorButton(
"##palettedit", palette[n], flags, ImVec2(20, 20))) {
161 if (ImGui::BeginPopupContextItem()) {
162 if (ImGui::MenuItem(tr(
"Copy as SNES"))) {
163 std::string clipboard = absl::StrFormat(
"$%04X", palette[n].snes());
164 ImGui::SetClipboardText(clipboard.c_str());
166 if (ImGui::MenuItem(tr(
"Copy as RGB"))) {
167 auto rgb = palette[n].rgb();
168 std::string clipboard =
169 absl::StrFormat(
"(%d,%d,%d)", (
int)rgb.x, (
int)rgb.y, (
int)rgb.z);
170 ImGui::SetClipboardText(clipboard.c_str());
172 if (ImGui::MenuItem(tr(
"Copy as Hex"))) {
173 auto rgb = palette[n].rgb();
174 std::string clipboard = absl::StrFormat(
"#%02X%02X%02X", (
int)rgb.x,
175 (
int)rgb.y, (
int)rgb.z);
176 ImGui::SetClipboardText(clipboard.c_str());
185 return absl::OkStatus();
190 ImGuiColorEditFlags flags) {
191 bool modified =
false;
193 if (ImGui::BeginPopup(popup_id)) {
194 static int selected_color = 0;
195 static ImVec4 current_color = ImVec4(0, 0, 0, 1.0f);
198 if (ImGui::ColorPicker4(
"##popuppicker", (
float*)¤t_color,
199 ImGuiColorEditFlags_NoSidePreview |
200 ImGuiColorEditFlags_NoSmallPreview)) {
210 for (
int n = 0; n < palette.
size() && n < 64;
214 ImGui::SameLine(0.0f, ImGui::GetStyle().ItemSpacing.y);
218 "##popuppal", palette[n],
219 ImGuiColorEditFlags_NoAlpha | ImGuiColorEditFlags_NoPicker,
240 static ImVec4 color = ImVec4(0, 0, 0, 1.0f);
241 ImGuiColorEditFlags misc_flags = ImGuiColorEditFlags_AlphaPreview |
242 ImGuiColorEditFlags_NoDragDrop |
243 ImGuiColorEditFlags_NoOptions;
246 static ImVec4 saved_palette[32] = {};
247 const int max_colors =
248 std::min<int>(
static_cast<int>(palette.
size()),
249 static_cast<int>(IM_ARRAYSIZE(saved_palette)));
251 for (
int n = 0; n < max_colors; n++) {
252 auto color = palette[n];
253 saved_palette[n].x = color.rgb().x / 255.0f;
254 saved_palette[n].y = color.rgb().y / 255.0f;
255 saved_palette[n].z = color.rgb().z / 255.0f;
256 saved_palette[n].w = 1.0f;
260 static ImVec4 backup_color;
261 ImGui::Text(tr(
"Current ==>"));
263 ImGui::Text(tr(
"Previous"));
267 ImGuiColorEditFlags_NoPicker | ImGuiColorEditFlags_AlphaPreviewHalf,
271 if (ImGui::ColorButton(
272 "##previous", backup_color,
273 ImGuiColorEditFlags_NoPicker | ImGuiColorEditFlags_AlphaPreviewHalf,
275 color = backup_color;
279 ImGui::Text(tr(
"Palette"));
280 for (
int n = 0; n < max_colors; n++) {
283 ImGui::SameLine(0.0f, ImGui::GetStyle().ItemSpacing.y);
285 ImGuiColorEditFlags palette_button_flags = ImGuiColorEditFlags_NoAlpha |
286 ImGuiColorEditFlags_NoPicker |
287 ImGuiColorEditFlags_NoTooltip;
288 if (ImGui::ColorButton(
"##palette", saved_palette[n], palette_button_flags,
290 color = ImVec4(saved_palette[n].x, saved_palette[n].y, saved_palette[n].z,
293 if (ImGui::BeginDragDropTarget()) {
294 if (
const ImGuiPayload* payload =
295 ImGui::AcceptDragDropPayload(IMGUI_PAYLOAD_TYPE_COLOR_3F))
296 memcpy((
float*)&saved_palette[n], payload->Data,
sizeof(
float) * 3);
297 if (
const ImGuiPayload* payload =
298 ImGui::AcceptDragDropPayload(IMGUI_PAYLOAD_TYPE_COLOR_4F))
299 memcpy((
float*)&saved_palette[n], payload->Data,
sizeof(
float) * 4);
300 ImGui::EndDragDropTarget();
308 ImGui::ColorPicker4(
"##picker", (
float*)&color,
309 misc_flags | ImGuiColorEditFlags_NoSidePreview |
310 ImGuiColorEditFlags_NoSmallPreview);
316 const auto palette_row_size = 7;
317 if (ImGuiID child_id = ImGui::GetID((
void*)(intptr_t)100);
318 ImGui::BeginChild(child_id, ImGui::GetContentRegionAvail(),
true,
319 ImGuiWindowFlags_AlwaysVerticalScrollbar)) {
321 ImGui::Text(tr(
"Palette"));
322 for (
int n = 0; n < palette.
size(); n++) {
324 if ((n % palette_row_size) != 0)
325 ImGui::SameLine(0.0f, ImGui::GetStyle().ItemSpacing.y);
328 bool is_selected = (palette_id == n / palette_row_size);
332 ImGui::PushStyleColor(ImGuiCol_Border, ImVec4(1.0f, 1.0f, 0.0f, 1.0f));
333 ImGui::PushStyleVar(ImGuiStyleVar_FrameBorderSize, 2.0f);
337 ImGuiColorEditFlags_NoAlpha |
338 ImGuiColorEditFlags_NoPicker |
339 ImGuiColorEditFlags_NoTooltip,
341 palette_id = n / palette_row_size;
342 refresh_graphics =
true;
346 ImGui::PopStyleColor();
347 ImGui::PopStyleVar();
358 const std::string& title,
359 bool show_color_picker,
int colors_per_row,
360 ImGuiColorEditFlags flags) {
363 flags = ImGuiColorEditFlags_NoAlpha | ImGuiColorEditFlags_NoPicker |
364 ImGuiColorEditFlags_NoTooltip;
368 if (!title.empty()) {
369 ImGui::Text(
"%s", title.c_str());
371 static int selected_color = 0;
373 if (show_color_picker) {
375 static ImVec4 current_color = ImVec4(0, 0, 0, 1.0f);
377 if (ImGui::ColorPicker4(
"Color Picker", (
float*)¤t_color,
378 ImGuiColorEditFlags_NoSidePreview |
379 ImGuiColorEditFlags_NoSmallPreview)) {
388 for (
int n = 0; n < palette.
size(); n++) {
390 if ((n % colors_per_row) != 0) {
391 ImGui::SameLine(0.0f, ImGui::GetStyle().ItemSpacing.y);
395 std::string button_id =
"##palette_" + std::to_string(n);
403 if (ImGui::BeginPopupContextItem()) {
404 if (ImGui::MenuItem(tr(
"Edit Color"))) {
406 ImGui::OpenPopup((
"Edit Color##" + std::to_string(n)).c_str());
409 if (ImGui::MenuItem(tr(
"Copy as SNES Value"))) {
410 std::string clipboard = absl::StrFormat(
"$%04X", palette[n].snes());
411 ImGui::SetClipboardText(clipboard.c_str());
414 if (ImGui::MenuItem(tr(
"Copy as RGB"))) {
415 auto rgb = palette[n].rgb();
417 std::string clipboard =
418 absl::StrFormat(
"(%d,%d,%d)", (
int)rgb.x, (
int)rgb.y, (
int)rgb.z);
419 ImGui::SetClipboardText(clipboard.c_str());
422 if (ImGui::MenuItem(tr(
"Copy as Hex"))) {
423 auto rgb = palette[n].rgb();
425 std::string clipboard = absl::StrFormat(
"#%02X%02X%02X", (
int)rgb.x,
426 (
int)rgb.y, (
int)rgb.z);
427 ImGui::SetClipboardText(clipboard.c_str());
434 if (ImGui::BeginPopup((
"Edit Color##" + std::to_string(n)).c_str())) {
435 ImGuiColorEditFlags picker_flags = ImGuiColorEditFlags_NoSidePreview |
436 ImGuiColorEditFlags_NoSmallPreview;
439 if (ImGui::ColorPicker4(
"##picker", (
float*)&color, picker_flags)) {
451 return absl::OkStatus();
455 bool is_selected,
bool is_modified,
457 ImGuiColorEditFlags flags) {
465 ImGui::PushStyleColor(ImGuiCol_Border, ImVec4(1.0f, 0.8f, 0.0f, 1.0f));
466 ImGui::PushStyleVar(ImGuiStyleVar_FrameBorderSize, 2.0f);
469 bool clicked = ImGui::ColorButton(
id, display_color, flags, size);
472 ImGui::PopStyleVar();
473 ImGui::PopStyleColor();
478 ImVec2 pos = ImGui::GetItemRectMin();
479 ImVec2 dot_pos = ImVec2(pos.x + size.x - 6, pos.y + 2);
480 ImGui::GetWindowDrawList()->AddCircleFilled(dot_pos, 3.0f,
481 IM_COL32(255, 128, 0, 255));
485 if (ImGui::IsItemHovered()) {
486 ImGui::BeginTooltip();
487 ImGui::Text(tr(
"SNES: $%04X"), color.
snes());
488 auto rgb = color.
rgb();
489 ImGui::Text(tr(
"RGB: (%d, %d, %d)"),
static_cast<int>(rgb.x),
490 static_cast<int>(rgb.y),
static_cast<int>(rgb.z));
492 ImGui::TextColored(ImVec4(1.0f, 0.6f, 0.0f, 1.0f), tr(
"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)
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)
struct snes_color snes_color
SNES color in 15-bit RGB format (BGR555)