6#include "absl/strings/str_format.h"
10#include "imgui/imgui.h"
26 ImVec4 rgb_255 = color.
rgb();
27 return ImVec4(rgb_255.x / 255.0f, rgb_255.y / 255.0f, rgb_255.z / 255.0f,
43 return absl::StrFormat(
"$%04X", color.
snes());
48 const auto rgb = color.
rgb();
49 return absl::StrFormat(
"(%d,%d,%d)",
static_cast<int>(rgb.x),
50 static_cast<int>(rgb.y),
static_cast<int>(rgb.z));
54 const auto rgb = color.
rgb();
55 return absl::StrFormat(
"#%02X%02X%02X",
static_cast<int>(rgb.x),
56 static_cast<int>(rgb.y),
static_cast<int>(rgb.z));
63 const std::string snes_label =
65 if (ImGui::MenuItem(snes_label.c_str(), snes.c_str())) {
66 ImGui::SetClipboardText(snes.c_str());
68 const std::string rgb_label =
70 if (ImGui::MenuItem(rgb_label.c_str(), rgb.c_str())) {
71 ImGui::SetClipboardText(rgb.c_str());
73 const std::string hex_label =
75 if (ImGui::MenuItem(hex_label.c_str(), hex.c_str())) {
76 ImGui::SetClipboardText(hex.c_str());
81 ImGuiColorEditFlags flags,
82 const ImVec2& size_arg) {
87 bool pressed = ImGui::ColorButton(
id.data(), displayColor, flags, size_arg);
89 if (ImGui::IsItemHovered()) {
90 ImGui::BeginTooltip();
91 ImGui::Text(tr(
"SNES: $%04X"), color.
snes());
98 ImGuiColorEditFlags flags) {
104 ImGui::ColorEdit4(label.data(), (
float*)&displayColor.x, flags);
122 int* selected_index) {
123 bool selection_made =
false;
124 int colors_to_show = std::min(num_colors,
static_cast<int>(palette.
size()));
127 for (
int n = 0; n < colors_to_show; n++) {
129 if (n > 0 && (n % 8) != 0) {
130 ImGui::SameLine(0.0f, ImGui::GetStyle().ItemSpacing.y);
133 bool is_selected = selected_index && (*selected_index == n);
135 ImGui::PushStyleColor(ImGuiCol_Border, ImVec4(1.0f, 1.0f, 0.0f, 1.0f));
136 ImGui::PushStyleVar(ImGuiStyleVar_FrameBorderSize, 2.0f);
140 "##palettesel", palette[n],
141 ImGuiColorEditFlags_NoAlpha | ImGuiColorEditFlags_NoPicker,
143 if (selected_index) {
145 selection_made =
true;
150 ImGui::PopStyleVar();
151 ImGui::PopStyleColor();
158 return selection_made;
162 const std::string& title,
163 ImGuiColorEditFlags flags) {
164 if (!title.empty()) {
165 ImGui::Text(
"%s", title.c_str());
168 static int selected_color = 0;
169 static ImVec4 current_color = ImVec4(0, 0, 0, 1.0f);
173 if (ImGui::ColorPicker4(
"##colorpicker", (
float*)¤t_color,
174 ImGuiColorEditFlags_NoSidePreview |
175 ImGuiColorEditFlags_NoSmallPreview)) {
184 for (
int n = 0; n < palette.
size(); n++) {
187 ImGui::SameLine(0.0f, ImGui::GetStyle().ItemSpacing.y);
191 flags = ImGuiColorEditFlags_NoAlpha | ImGuiColorEditFlags_NoPicker;
194 if (
SnesColorButton(
"##palettedit", palette[n], flags, ImVec2(20, 20))) {
200 if (ImGui::BeginPopupContextItem()) {
209 return absl::OkStatus();
214 ImGuiColorEditFlags flags) {
215 bool modified =
false;
217 if (ImGui::BeginPopup(popup_id)) {
218 static int selected_color = 0;
219 static ImVec4 current_color = ImVec4(0, 0, 0, 1.0f);
222 if (ImGui::ColorPicker4(
"##popuppicker", (
float*)¤t_color,
223 ImGuiColorEditFlags_NoSidePreview |
224 ImGuiColorEditFlags_NoSmallPreview)) {
234 for (
int n = 0; n < palette.
size() && n < 64;
238 ImGui::SameLine(0.0f, ImGui::GetStyle().ItemSpacing.y);
242 "##popuppal", palette[n],
243 ImGuiColorEditFlags_NoAlpha | ImGuiColorEditFlags_NoPicker,
264 static ImVec4 color = ImVec4(0, 0, 0, 1.0f);
265 ImGuiColorEditFlags misc_flags = ImGuiColorEditFlags_AlphaPreview |
266 ImGuiColorEditFlags_NoDragDrop |
267 ImGuiColorEditFlags_NoOptions;
270 static ImVec4 saved_palette[32] = {};
271 const int max_colors =
272 std::min<int>(
static_cast<int>(palette.
size()),
273 static_cast<int>(IM_ARRAYSIZE(saved_palette)));
275 for (
int n = 0; n < max_colors; n++) {
276 auto color = palette[n];
277 saved_palette[n].x = color.rgb().x / 255.0f;
278 saved_palette[n].y = color.rgb().y / 255.0f;
279 saved_palette[n].z = color.rgb().z / 255.0f;
280 saved_palette[n].w = 1.0f;
284 static ImVec4 backup_color;
285 ImGui::Text(tr(
"Current ==>"));
287 ImGui::Text(tr(
"Previous"));
291 ImGuiColorEditFlags_NoPicker | ImGuiColorEditFlags_AlphaPreviewHalf,
295 if (ImGui::ColorButton(
296 "##previous", backup_color,
297 ImGuiColorEditFlags_NoPicker | ImGuiColorEditFlags_AlphaPreviewHalf,
299 color = backup_color;
303 ImGui::Text(tr(
"Palette"));
304 for (
int n = 0; n < max_colors; n++) {
307 ImGui::SameLine(0.0f, ImGui::GetStyle().ItemSpacing.y);
309 ImGuiColorEditFlags palette_button_flags = ImGuiColorEditFlags_NoAlpha |
310 ImGuiColorEditFlags_NoPicker |
311 ImGuiColorEditFlags_NoTooltip;
312 if (ImGui::ColorButton(
"##palette", saved_palette[n], palette_button_flags,
314 color = ImVec4(saved_palette[n].x, saved_palette[n].y, saved_palette[n].z,
317 if (ImGui::BeginDragDropTarget()) {
318 if (
const ImGuiPayload* payload =
319 ImGui::AcceptDragDropPayload(IMGUI_PAYLOAD_TYPE_COLOR_3F))
320 memcpy((
float*)&saved_palette[n], payload->Data,
sizeof(
float) * 3);
321 if (
const ImGuiPayload* payload =
322 ImGui::AcceptDragDropPayload(IMGUI_PAYLOAD_TYPE_COLOR_4F))
323 memcpy((
float*)&saved_palette[n], payload->Data,
sizeof(
float) * 4);
324 ImGui::EndDragDropTarget();
332 ImGui::ColorPicker4(
"##picker", (
float*)&color,
333 misc_flags | ImGuiColorEditFlags_NoSidePreview |
334 ImGuiColorEditFlags_NoSmallPreview);
340 const auto palette_row_size = 7;
341 if (ImGuiID child_id = ImGui::GetID((
void*)(intptr_t)100);
342 ImGui::BeginChild(child_id, ImGui::GetContentRegionAvail(),
true,
343 ImGuiWindowFlags_AlwaysVerticalScrollbar)) {
345 ImGui::Text(tr(
"Palette"));
346 for (
int n = 0; n < palette.
size(); n++) {
348 if ((n % palette_row_size) != 0)
349 ImGui::SameLine(0.0f, ImGui::GetStyle().ItemSpacing.y);
352 bool is_selected = (palette_id == n / palette_row_size);
356 ImGui::PushStyleColor(ImGuiCol_Border, ImVec4(1.0f, 1.0f, 0.0f, 1.0f));
357 ImGui::PushStyleVar(ImGuiStyleVar_FrameBorderSize, 2.0f);
361 ImGuiColorEditFlags_NoAlpha |
362 ImGuiColorEditFlags_NoPicker |
363 ImGuiColorEditFlags_NoTooltip,
365 palette_id = n / palette_row_size;
366 refresh_graphics =
true;
370 ImGui::PopStyleColor();
371 ImGui::PopStyleVar();
382 const std::string& title,
383 bool show_color_picker,
int colors_per_row,
384 ImGuiColorEditFlags flags) {
387 flags = ImGuiColorEditFlags_NoAlpha | ImGuiColorEditFlags_NoPicker |
388 ImGuiColorEditFlags_NoTooltip;
392 if (!title.empty()) {
393 ImGui::Text(
"%s", title.c_str());
395 static int selected_color = 0;
397 if (show_color_picker) {
399 static ImVec4 current_color = ImVec4(0, 0, 0, 1.0f);
401 if (ImGui::ColorPicker4(
"Color Picker", (
float*)¤t_color,
402 ImGuiColorEditFlags_NoSidePreview |
403 ImGuiColorEditFlags_NoSmallPreview)) {
412 for (
int n = 0; n < palette.
size(); n++) {
414 if ((n % colors_per_row) != 0) {
415 ImGui::SameLine(0.0f, ImGui::GetStyle().ItemSpacing.y);
419 std::string button_id =
"##palette_" + std::to_string(n);
429 bool open_edit_color =
false;
430 if (ImGui::BeginPopupContextItem()) {
431 if (ImGui::MenuItem(tr(
"Edit Color..."))) {
432 open_edit_color =
true;
438 if (open_edit_color) {
439 ImGui::OpenPopup((
"Edit Color##" + std::to_string(n)).c_str());
443 if (ImGui::BeginPopup((
"Edit Color##" + std::to_string(n)).c_str())) {
444 ImGuiColorEditFlags picker_flags = ImGuiColorEditFlags_NoSidePreview |
445 ImGuiColorEditFlags_NoSmallPreview;
448 if (ImGui::ColorPicker4(
"##picker", (
float*)&color, picker_flags)) {
460 return absl::OkStatus();
464 bool is_selected,
bool is_modified,
466 ImGuiColorEditFlags flags) {
474 ImGui::PushStyleColor(ImGuiCol_Border, ImVec4(1.0f, 0.8f, 0.0f, 1.0f));
475 ImGui::PushStyleVar(ImGuiStyleVar_FrameBorderSize, 2.0f);
478 bool clicked = ImGui::ColorButton(
id, display_color, flags, size);
481 ImGui::PopStyleVar();
482 ImGui::PopStyleColor();
487 ImVec2 pos = ImGui::GetItemRectMin();
488 ImVec2 dot_pos = ImVec2(pos.x + size.x - 6, pos.y + 2);
489 ImGui::GetWindowDrawList()->AddCircleFilled(dot_pos, 3.0f,
490 IM_COL32(255, 128, 0, 255));
494 if (ImGui::IsItemHovered()) {
495 ImGui::BeginTooltip();
496 ImGui::Text(tr(
"SNES: $%04X"), color.
snes());
497 auto rgb = color.
rgb();
498 ImGui::Text(tr(
"RGB: (%d, %d, %d)"),
static_cast<int>(rgb.x),
499 static_cast<int>(rgb.y),
static_cast<int>(rgb.z));
501 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)
#define ICON_MD_CONTENT_COPY
std::string SnesColorToRgbString(const gfx::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.
void SnesColorCopyMenuItems(const gfx::SnesColor &color)
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.
std::string SnesColorToHexString(const gfx::SnesColor &color)
absl::Status DisplayEditablePalette(gfx::SnesPalette &palette, const std::string &title, bool show_color_picker, int colors_per_row, ImGuiColorEditFlags flags)
std::string SnesColorToSnesString(const gfx::SnesColor &color)
SNES color in 15-bit RGB format (BGR555)
struct snes_color snes_color
SNES color in 15-bit RGB format (BGR555)