Add color conversion utility and editable palette display functionality; implement color picker and context menu options for palette colors in the GUI.

This commit is contained in:
scawful
2025-04-17 21:50:01 -04:00
parent 9ad41f9f8b
commit afab5900f7
2 changed files with 111 additions and 2 deletions

View File

@@ -16,6 +16,10 @@ ImVec4 ConvertSnesColorToImVec4(const gfx::SnesColor& color) {
);
}
gfx::SnesColor ConvertImVec4ToSnesColor(const ImVec4& color) {
return gfx::SnesColor(color.x, color.y, color.z);
}
IMGUI_API bool SnesColorButton(absl::string_view id, gfx::SnesColor& color,
ImGuiColorEditFlags flags,
const ImVec2& size_arg) {
@@ -58,7 +62,7 @@ absl::Status DisplayPalette(gfx::SnesPalette& palette, bool loaded) {
static ImVec4 saved_palette[32] = {};
if (loaded && !init) {
for (int n = 0; n < palette.size(); n++) {
ASSIGN_OR_RETURN(auto color, palette.GetColor(n));
auto color = palette[n];
saved_palette[n].x = color.rgb().x / 255;
saved_palette[n].y = color.rgb().y / 255;
saved_palette[n].z = color.rgb().z / 255;
@@ -163,5 +167,102 @@ void SelectablePalettePipeline(uint64_t& palette_id, bool& refresh_graphics,
ImGui::EndChild();
}
absl::Status DisplayEditablePalette(gfx::SnesPalette& palette,
const std::string& title,
bool show_color_picker, int colors_per_row,
ImGuiColorEditFlags flags) {
// Default flags if none provided
if (flags == 0) {
flags = ImGuiColorEditFlags_NoAlpha | ImGuiColorEditFlags_NoPicker |
ImGuiColorEditFlags_NoTooltip;
}
// Display title if provided
if (!title.empty()) {
ImGui::Text("%s", title.c_str());
}
static int selected_color = 0;
if (show_color_picker) {
ImGui::Separator();
static ImVec4 current_color = ImVec4(0, 0, 0, 1.0f);
if (ImGui::ColorPicker4("Color Picker", (float*)&current_color,
ImGuiColorEditFlags_NoSidePreview |
ImGuiColorEditFlags_NoSmallPreview)) {
// Convert the selected color to SNES format and add it to the palette
gfx::SnesColor snes_color(current_color);
palette.UpdateColor(selected_color, snes_color);
}
}
// Display the palette colors in a grid
ImGui::BeginGroup(); // Lock X position
for (int n = 0; n < palette.size(); n++) {
ImGui::PushID(n);
if ((n % colors_per_row) != 0) {
ImGui::SameLine(0.0f, ImGui::GetStyle().ItemSpacing.y);
}
// Create a unique ID for this color button
std::string button_id = "##palette_" + std::to_string(n);
// Display the color button
if (SnesColorButton(button_id, palette[n], flags, ImVec2(20, 20))) {
// Color was clicked, could be used to select this color
selected_color = n;
}
if (ImGui::BeginPopupContextItem()) {
if (ImGui::MenuItem("Edit Color")) {
// Open color picker for this color
ImGui::OpenPopup(("Edit Color##" + std::to_string(n)).c_str());
}
if (ImGui::MenuItem("Copy as SNES Value")) {
std::string clipboard = absl::StrFormat("$%04X", palette[n].snes());
ImGui::SetClipboardText(clipboard.c_str());
}
if (ImGui::MenuItem("Copy as RGB")) {
auto rgb = palette[n].rgb();
std::string clipboard =
absl::StrFormat("(%d,%d,%d)", (int)(rgb.x * 255),
(int)(rgb.y * 255), (int)(rgb.z * 255));
ImGui::SetClipboardText(clipboard.c_str());
}
if (ImGui::MenuItem("Copy as Hex")) {
auto rgb = palette[n].rgb();
std::string clipboard =
absl::StrFormat("#%02X%02X%02X", (int)(rgb.x * 255),
(int)(rgb.y * 255), (int)(rgb.z * 255));
ImGui::SetClipboardText(clipboard.c_str());
}
ImGui::EndPopup();
}
// Color picker popup
if (ImGui::BeginPopup(("Edit Color##" + std::to_string(n)).c_str())) {
ImGuiColorEditFlags picker_flags = ImGuiColorEditFlags_NoSidePreview |
ImGuiColorEditFlags_NoSmallPreview;
ImVec4 color = ConvertSnesColorToImVec4(palette[n]);
if (ImGui::ColorPicker4("##picker", (float*)&color, picker_flags)) {
// Update the SNES color when the picker changes
palette[n] = ConvertImVec4ToSnesColor(color);
}
ImGui::EndPopup();
}
ImGui::PopID();
}
ImGui::EndGroup();
return absl::OkStatus();
}
} // namespace gui
} // namespace yaze

View File

@@ -7,7 +7,6 @@
#include <string>
#include "absl/status/status.h"
#include "absl/strings/str_format.h"
#include "app/gfx/snes_palette.h"
#include "imgui/imgui.h"
@@ -43,6 +42,9 @@ inline std::string ColorToHexString(const Color &color) {
// normalized color values
ImVec4 ConvertSnesColorToImVec4(const gfx::SnesColor &color);
// A utility function to convert an ImVec4 to an SnesColor object
gfx::SnesColor ConvertImVec4ToSnesColor(const ImVec4 &color);
// The wrapper function for ImGui::ColorButton that takes a SnesColor reference
IMGUI_API bool SnesColorButton(absl::string_view id, gfx::SnesColor &color,
ImGuiColorEditFlags flags = 0,
@@ -53,6 +55,12 @@ IMGUI_API bool SnesColorEdit4(absl::string_view label, gfx::SnesColor *color,
absl::Status DisplayPalette(gfx::SnesPalette &palette, bool loaded);
absl::Status DisplayEditablePalette(gfx::SnesPalette &palette,
const std::string &title = "",
bool show_color_picker = false,
int colors_per_row = 8,
ImGuiColorEditFlags flags = 0);
void SelectablePalettePipeline(uint64_t &palette_id, bool &refresh_graphics,
gfx::SnesPalette &palette);