5#include "imgui/imgui.h"
21 ImVec4 rgb_255 = color.
rgb();
22 return ImVec4(rgb_255.x / 255.0f, rgb_255.y / 255.0f,
23 rgb_255.z / 255.0f, 1.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 ImGuiColorEditFlags_NoAlpha | ImGuiColorEditFlags_NoPicker,
101 selection_made =
true;
106 ImGui::PopStyleVar();
107 ImGui::PopStyleColor();
114 return selection_made;
118 const std::string &title,
119 ImGuiColorEditFlags flags) {
120 if (!title.empty()) {
121 ImGui::Text(
"%s", title.c_str());
124 static int selected_color = 0;
125 static ImVec4 current_color = ImVec4(0, 0, 0, 1.0f);
129 if (ImGui::ColorPicker4(
"##colorpicker", (
float*)¤t_color,
130 ImGuiColorEditFlags_NoSidePreview |
131 ImGuiColorEditFlags_NoSmallPreview)) {
140 for (
int n = 0; n < palette.
size(); n++) {
143 ImGui::SameLine(0.0f, ImGui::GetStyle().ItemSpacing.y);
147 flags = ImGuiColorEditFlags_NoAlpha | ImGuiColorEditFlags_NoPicker;
150 if (
SnesColorButton(
"##palettedit", palette[n], flags, ImVec2(20, 20))) {
156 if (ImGui::BeginPopupContextItem()) {
157 if (ImGui::MenuItem(
"Copy as SNES")) {
158 std::string clipboard = absl::StrFormat(
"$%04X", palette[n].snes());
159 ImGui::SetClipboardText(clipboard.c_str());
161 if (ImGui::MenuItem(
"Copy as RGB")) {
162 auto rgb = palette[n].rgb();
163 std::string clipboard = absl::StrFormat(
"(%d,%d,%d)",
164 (
int)rgb.x, (
int)rgb.y, (
int)rgb.z);
165 ImGui::SetClipboardText(clipboard.c_str());
167 if (ImGui::MenuItem(
"Copy as Hex")) {
168 auto rgb = palette[n].rgb();
169 std::string clipboard = absl::StrFormat(
"#%02X%02X%02X",
170 (
int)rgb.x, (
int)rgb.y, (
int)rgb.z);
171 ImGui::SetClipboardText(clipboard.c_str());
180 return absl::OkStatus();
185 ImGuiColorEditFlags flags) {
186 bool modified =
false;
188 if (ImGui::BeginPopup(popup_id)) {
189 static int selected_color = 0;
190 static ImVec4 current_color = ImVec4(0, 0, 0, 1.0f);
193 if (ImGui::ColorPicker4(
"##popuppicker", (
float*)¤t_color,
194 ImGuiColorEditFlags_NoSidePreview |
195 ImGuiColorEditFlags_NoSmallPreview)) {
205 for (
int n = 0; n < palette.
size() && n < 64; n++) {
208 ImGui::SameLine(0.0f, ImGui::GetStyle().ItemSpacing.y);
212 ImGuiColorEditFlags_NoAlpha | ImGuiColorEditFlags_NoPicker,
233 static ImVec4 color = ImVec4(0, 0, 0, 255.f);
234 ImGuiColorEditFlags misc_flags = ImGuiColorEditFlags_AlphaPreview |
235 ImGuiColorEditFlags_NoDragDrop |
236 ImGuiColorEditFlags_NoOptions;
239 static bool init =
false;
240 static ImVec4 saved_palette[32] = {};
241 if (loaded && !init) {
242 for (
int n = 0; n < palette.
size(); n++) {
243 auto color = palette[n];
244 saved_palette[n].x = color.rgb().x / 255;
245 saved_palette[n].y = color.rgb().y / 255;
246 saved_palette[n].z = color.rgb().z / 255;
247 saved_palette[n].w = 255;
252 static ImVec4 backup_color;
253 ImGui::Text(
"Current ==>");
255 ImGui::Text(
"Previous");
259 ImGuiColorEditFlags_NoPicker | ImGuiColorEditFlags_AlphaPreviewHalf,
263 if (ImGui::ColorButton(
264 "##previous", backup_color,
265 ImGuiColorEditFlags_NoPicker | ImGuiColorEditFlags_AlphaPreviewHalf,
267 color = backup_color;
271 ImGui::Text(
"Palette");
272 for (
int n = 0; n < IM_ARRAYSIZE(saved_palette); n++) {
274 if ((n % 4) != 0) ImGui::SameLine(0.0f, ImGui::GetStyle().ItemSpacing.y);
276 ImGuiColorEditFlags palette_button_flags = ImGuiColorEditFlags_NoAlpha |
277 ImGuiColorEditFlags_NoPicker |
278 ImGuiColorEditFlags_NoTooltip;
279 if (ImGui::ColorButton(
"##palette", saved_palette[n], palette_button_flags,
281 color = ImVec4(saved_palette[n].x, saved_palette[n].y, saved_palette[n].z,
284 if (ImGui::BeginDragDropTarget()) {
285 if (
const ImGuiPayload* payload =
286 ImGui::AcceptDragDropPayload(IMGUI_PAYLOAD_TYPE_COLOR_3F))
287 memcpy((
float*)&saved_palette[n], payload->Data,
sizeof(
float) * 3);
288 if (
const ImGuiPayload* payload =
289 ImGui::AcceptDragDropPayload(IMGUI_PAYLOAD_TYPE_COLOR_4F))
290 memcpy((
float*)&saved_palette[n], payload->Data,
sizeof(
float) * 4);
291 ImGui::EndDragDropTarget();
299 ImGui::ColorPicker4(
"##picker", (
float*)&color,
300 misc_flags | ImGuiColorEditFlags_NoSidePreview |
301 ImGuiColorEditFlags_NoSmallPreview);
307 const auto palette_row_size = 7;
308 if (ImGuiID child_id = ImGui::GetID((
void*)(intptr_t)100);
309 ImGui::BeginChild(child_id, ImGui::GetContentRegionAvail(),
true,
310 ImGuiWindowFlags_AlwaysVerticalScrollbar)) {
312 ImGui::Text(
"Palette");
313 for (
int n = 0; n < palette.
size(); n++) {
315 if ((n % palette_row_size) != 0)
316 ImGui::SameLine(0.0f, ImGui::GetStyle().ItemSpacing.y);
319 bool is_selected = (palette_id == n / palette_row_size);
323 ImGui::PushStyleColor(ImGuiCol_Border, ImVec4(1.0f, 1.0f, 0.0f, 1.0f));
324 ImGui::PushStyleVar(ImGuiStyleVar_FrameBorderSize, 2.0f);
328 ImGuiColorEditFlags_NoAlpha |
329 ImGuiColorEditFlags_NoPicker |
330 ImGuiColorEditFlags_NoTooltip,
332 palette_id = n / palette_row_size;
333 refresh_graphics =
true;
337 ImGui::PopStyleColor();
338 ImGui::PopStyleVar();
349 const std::string& title,
350 bool show_color_picker,
int colors_per_row,
351 ImGuiColorEditFlags flags) {
354 flags = ImGuiColorEditFlags_NoAlpha | ImGuiColorEditFlags_NoPicker |
355 ImGuiColorEditFlags_NoTooltip;
359 if (!title.empty()) {
360 ImGui::Text(
"%s", title.c_str());
362 static int selected_color = 0;
364 if (show_color_picker) {
366 static ImVec4 current_color = ImVec4(0, 0, 0, 1.0f);
368 if (ImGui::ColorPicker4(
"Color Picker", (
float*)¤t_color,
369 ImGuiColorEditFlags_NoSidePreview |
370 ImGuiColorEditFlags_NoSmallPreview)) {
379 for (
int n = 0; n < palette.
size(); n++) {
381 if ((n % colors_per_row) != 0) {
382 ImGui::SameLine(0.0f, ImGui::GetStyle().ItemSpacing.y);
386 std::string button_id =
"##palette_" + std::to_string(n);
394 if (ImGui::BeginPopupContextItem()) {
395 if (ImGui::MenuItem(
"Edit Color")) {
397 ImGui::OpenPopup((
"Edit Color##" + std::to_string(n)).c_str());
400 if (ImGui::MenuItem(
"Copy as SNES Value")) {
401 std::string clipboard = absl::StrFormat(
"$%04X", palette[n].snes());
402 ImGui::SetClipboardText(clipboard.c_str());
405 if (ImGui::MenuItem(
"Copy as RGB")) {
406 auto rgb = palette[n].rgb();
408 std::string clipboard =
409 absl::StrFormat(
"(%d,%d,%d)", (
int)rgb.x, (
int)rgb.y, (
int)rgb.z);
410 ImGui::SetClipboardText(clipboard.c_str());
413 if (ImGui::MenuItem(
"Copy as Hex")) {
414 auto rgb = palette[n].rgb();
416 std::string clipboard =
417 absl::StrFormat(
"#%02X%02X%02X", (
int)rgb.x, (
int)rgb.y, (
int)rgb.z);
418 ImGui::SetClipboardText(clipboard.c_str());
425 if (ImGui::BeginPopup((
"Edit Color##" + std::to_string(n)).c_str())) {
426 ImGuiColorEditFlags picker_flags = ImGuiColorEditFlags_NoSidePreview |
427 ImGuiColorEditFlags_NoSmallPreview;
430 if (ImGui::ColorPicker4(
"##picker", (
float*)&color, picker_flags)) {
442 return absl::OkStatus();
446 bool is_selected,
bool is_modified,
448 ImGuiColorEditFlags flags) {
456 ImGui::PushStyleColor(ImGuiCol_Border, ImVec4(1.0f, 0.8f, 0.0f, 1.0f));
457 ImGui::PushStyleVar(ImGuiStyleVar_FrameBorderSize, 2.0f);
460 bool clicked = ImGui::ColorButton(
id, display_color, flags, size);
463 ImGui::PopStyleVar();
464 ImGui::PopStyleColor();
469 ImVec2 pos = ImGui::GetItemRectMin();
470 ImVec2 dot_pos = ImVec2(pos.x + size.x - 6, pos.y + 2);
471 ImGui::GetWindowDrawList()->AddCircleFilled(dot_pos, 3.0f,
472 IM_COL32(255, 128, 0, 255));
476 if (ImGui::IsItemHovered()) {
477 ImGui::BeginTooltip();
478 ImGui::Text(
"SNES: $%04X", color.
snes());
479 auto rgb = color.
rgb();
480 ImGui::Text(
"RGB: (%d, %d, %d)",
481 static_cast<int>(rgb.x),
482 static_cast<int>(rgb.y),
483 static_cast<int>(rgb.z));
485 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)
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)
Main namespace for the application.
SNES color in 15-bit RGB format (BGR555)