feat(editor): reorganize palette editor structure and enhance linking
- Moved palette_editor and palette_group_card files to a dedicated palette directory for better organization. - Updated CMake configuration to link the new palette editor files and added support for the yaze_agent library when not in minimal build. - Refactored include paths in various editor files to reflect the new structure, ensuring proper linkage and modularity. Benefits: - Improved code organization and maintainability by grouping related files. - Enhanced functionality with the integration of AI features through the yaze_agent library.
This commit is contained in:
@@ -23,8 +23,9 @@ set(
|
||||
app/editor/editor_manager.cc
|
||||
app/editor/graphics/gfx_group_editor.cc
|
||||
app/editor/graphics/graphics_editor.cc
|
||||
app/editor/graphics/palette_editor.cc
|
||||
app/editor/graphics/screen_editor.cc
|
||||
app/editor/palette/palette_editor.cc
|
||||
app/editor/palette/palette_group_card.cc
|
||||
app/editor/message/message_data.cc
|
||||
app/editor/message/message_editor.cc
|
||||
app/editor/message/message_preview.cc
|
||||
@@ -101,11 +102,20 @@ target_link_libraries(yaze_editor PUBLIC
|
||||
yaze_gfx
|
||||
yaze_gui
|
||||
yaze_zelda3
|
||||
yaze_emulator # Needed for emulator integration (APU, PPU, SNES)
|
||||
yaze_util
|
||||
yaze_common
|
||||
ImGui
|
||||
)
|
||||
|
||||
# Link agent library for AI features (always available when not in minimal build)
|
||||
if(NOT YAZE_MINIMAL_BUILD)
|
||||
if(TARGET yaze_agent)
|
||||
target_link_libraries(yaze_editor PUBLIC yaze_agent)
|
||||
message(STATUS "✓ yaze_editor linked to yaze_agent")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# Note: yaze_test_support linking is deferred to test.cmake to ensure proper ordering
|
||||
|
||||
if(YAZE_WITH_JSON)
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
#include "app/editor/code/assembly_editor.h"
|
||||
#include "app/editor/dungeon/dungeon_editor_v2.h"
|
||||
#include "app/editor/graphics/graphics_editor.h"
|
||||
#include "app/editor/graphics/palette_editor.h"
|
||||
#include "app/editor/palette/palette_editor.h"
|
||||
#include "app/editor/graphics/screen_editor.h"
|
||||
#include "app/editor/music/music_editor.h"
|
||||
#include "app/editor/overworld/overworld_editor.h"
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
#include "app/editor/code/project_file_editor.h"
|
||||
#include "app/editor/dungeon/dungeon_editor_v2.h"
|
||||
#include "app/editor/graphics/graphics_editor.h"
|
||||
#include "app/editor/graphics/palette_editor.h"
|
||||
#include "app/editor/palette/palette_editor.h"
|
||||
#include "app/editor/graphics/screen_editor.h"
|
||||
#include "app/editor/message/message_editor.h"
|
||||
#include "app/editor/music/music_editor.h"
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
|
||||
#include "absl/status/status.h"
|
||||
#include "app/editor/editor.h"
|
||||
#include "app/editor/graphics/palette_editor.h"
|
||||
#include "app/editor/palette/palette_editor.h"
|
||||
#include "app/gfx/bitmap.h"
|
||||
#include "app/gui/editor_card_manager.h"
|
||||
#include "app/gfx/snes_tile.h"
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
#include "absl/status/status.h"
|
||||
#include "app/editor/editor.h"
|
||||
#include "app/editor/graphics/gfx_group_editor.h"
|
||||
#include "app/editor/graphics/palette_editor.h"
|
||||
#include "app/editor/palette/palette_editor.h"
|
||||
#include "app/gui/editor_card_manager.h"
|
||||
#include "app/editor/overworld/tile16_editor.h"
|
||||
#include "app/editor/overworld/map_properties.h"
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
#include <vector>
|
||||
|
||||
#include "absl/status/status.h"
|
||||
#include "app/editor/graphics/palette_editor.h"
|
||||
#include "app/editor/palette/palette_editor.h"
|
||||
#include "app/gfx/bitmap.h"
|
||||
#include "app/gfx/snes_palette.h"
|
||||
#include "app/gfx/snes_tile.h"
|
||||
|
||||
@@ -187,6 +187,14 @@ absl::Status DisplayPalette(gfx::SnesPalette& palette, bool loaded) {
|
||||
}
|
||||
|
||||
void PaletteEditor::Initialize() {
|
||||
// Initialize palette cards
|
||||
if (rom_ && rom_->is_loaded()) {
|
||||
ow_main_card_ = std::make_unique<OverworldMainPaletteCard>(rom_);
|
||||
ow_animated_card_ = std::make_unique<OverworldAnimatedPaletteCard>(rom_);
|
||||
dungeon_main_card_ = std::make_unique<DungeonMainPaletteCard>(rom_);
|
||||
sprite_card_ = std::make_unique<SpritePaletteCard>(rom_);
|
||||
equipment_card_ = std::make_unique<EquipmentPaletteCard>(rom_);
|
||||
}
|
||||
}
|
||||
|
||||
absl::Status PaletteEditor::Load() {
|
||||
@@ -206,48 +214,88 @@ absl::Status PaletteEditor::Load() {
|
||||
}
|
||||
|
||||
absl::Status PaletteEditor::Update() {
|
||||
static int current_palette_group = 0;
|
||||
if (BeginTable("paletteGroupsTable", 3, kPaletteTableFlags)) {
|
||||
TableSetupColumn("Categories", ImGuiTableColumnFlags_WidthFixed, 200);
|
||||
TableSetupColumn("Palette Editor", ImGuiTableColumnFlags_WidthStretch);
|
||||
TableSetupColumn("Quick Access", ImGuiTableColumnFlags_WidthStretch);
|
||||
TableHeadersRow();
|
||||
static bool use_legacy_view = false;
|
||||
|
||||
TableNextRow();
|
||||
TableNextColumn();
|
||||
|
||||
static int selected_category = 0;
|
||||
BeginChild("CategoryList", ImVec2(0, GetContentRegionAvail().y), true);
|
||||
|
||||
for (int i = 0; i < kNumPalettes; i++) {
|
||||
const bool is_selected = (selected_category == i);
|
||||
if (Selectable(std::string(kPaletteCategoryNames[i]).c_str(),
|
||||
is_selected)) {
|
||||
selected_category = i;
|
||||
}
|
||||
}
|
||||
|
||||
EndChild();
|
||||
|
||||
TableNextColumn();
|
||||
BeginChild("PaletteEditor", ImVec2(0, 0), true);
|
||||
|
||||
Text("%s", std::string(kPaletteCategoryNames[selected_category]).c_str());
|
||||
|
||||
Separator();
|
||||
|
||||
if (rom()->is_loaded()) {
|
||||
status_ = DrawPaletteGroup(selected_category, true);
|
||||
}
|
||||
|
||||
EndChild();
|
||||
|
||||
TableNextColumn();
|
||||
DrawQuickAccessTab();
|
||||
|
||||
EndTable();
|
||||
// Toolbar with view selector
|
||||
if (ImGui::Button(use_legacy_view ? "Switch to Card View" : "Switch to Legacy View")) {
|
||||
use_legacy_view = !use_legacy_view;
|
||||
}
|
||||
|
||||
ImGui::SameLine();
|
||||
ImGui::TextDisabled("|");
|
||||
ImGui::SameLine();
|
||||
|
||||
if (use_legacy_view) {
|
||||
// Original table-based view
|
||||
static int current_palette_group = 0;
|
||||
if (BeginTable("paletteGroupsTable", 3, kPaletteTableFlags)) {
|
||||
TableSetupColumn("Categories", ImGuiTableColumnFlags_WidthFixed, 200);
|
||||
TableSetupColumn("Palette Editor", ImGuiTableColumnFlags_WidthStretch);
|
||||
TableSetupColumn("Quick Access", ImGuiTableColumnFlags_WidthStretch);
|
||||
TableHeadersRow();
|
||||
|
||||
TableNextRow();
|
||||
TableNextColumn();
|
||||
|
||||
static int selected_category = 0;
|
||||
BeginChild("CategoryList", ImVec2(0, GetContentRegionAvail().y), true);
|
||||
|
||||
for (int i = 0; i < kNumPalettes; i++) {
|
||||
const bool is_selected = (selected_category == i);
|
||||
if (Selectable(std::string(kPaletteCategoryNames[i]).c_str(),
|
||||
is_selected)) {
|
||||
selected_category = i;
|
||||
}
|
||||
}
|
||||
|
||||
EndChild();
|
||||
|
||||
TableNextColumn();
|
||||
BeginChild("PaletteEditor", ImVec2(0, 0), true);
|
||||
|
||||
Text("%s", std::string(kPaletteCategoryNames[selected_category]).c_str());
|
||||
|
||||
Separator();
|
||||
|
||||
if (rom()->is_loaded()) {
|
||||
status_ = DrawPaletteGroup(selected_category, true);
|
||||
}
|
||||
|
||||
EndChild();
|
||||
|
||||
TableNextColumn();
|
||||
DrawQuickAccessTab();
|
||||
|
||||
EndTable();
|
||||
}
|
||||
} else {
|
||||
// New card-based view with quick access sidebar
|
||||
if (BeginTable("paletteCardsTable", 2, kPaletteTableFlags)) {
|
||||
TableSetupColumn("Palette Cards", ImGuiTableColumnFlags_WidthStretch);
|
||||
TableSetupColumn("Quick Access", ImGuiTableColumnFlags_WidthFixed, 300);
|
||||
TableHeadersRow();
|
||||
|
||||
TableNextRow();
|
||||
TableNextColumn();
|
||||
|
||||
BeginChild("PaletteCardsView", ImVec2(0, 0), true);
|
||||
DrawPaletteCards();
|
||||
EndChild();
|
||||
|
||||
TableNextColumn();
|
||||
DrawQuickAccessTab();
|
||||
|
||||
EndTable();
|
||||
}
|
||||
}
|
||||
|
||||
// Draw palette card windows (dockable/floating)
|
||||
if (ow_main_card_) ow_main_card_->Draw();
|
||||
if (ow_animated_card_) ow_animated_card_->Draw();
|
||||
if (dungeon_main_card_) dungeon_main_card_->Draw();
|
||||
if (sprite_card_) sprite_card_->Draw();
|
||||
if (equipment_card_) equipment_card_->Draw();
|
||||
|
||||
return absl::OkStatus();
|
||||
}
|
||||
|
||||
@@ -559,5 +607,71 @@ absl::Status PaletteEditor::ResetColorToOriginal(
|
||||
return absl::OkStatus();
|
||||
}
|
||||
|
||||
void PaletteEditor::DrawPaletteCards() {
|
||||
ImGui::TextWrapped(
|
||||
"Click a palette card below to open it as a dockable/floating window. "
|
||||
"Each card provides full editing capabilities with undo/redo, "
|
||||
"save/discard workflow, and detailed metadata.");
|
||||
|
||||
ImGui::Separator();
|
||||
|
||||
// Draw card launcher buttons
|
||||
ImGui::Text("Overworld Palettes");
|
||||
if (ImGui::Button("Open Overworld Main", ImVec2(-1, 0))) {
|
||||
if (ow_main_card_) ow_main_card_->Show();
|
||||
}
|
||||
if (ImGui::Button("Open Overworld Animated", ImVec2(-1, 0))) {
|
||||
if (ow_animated_card_) ow_animated_card_->Show();
|
||||
}
|
||||
|
||||
ImGui::Separator();
|
||||
|
||||
ImGui::Text("Dungeon Palettes");
|
||||
if (ImGui::Button("Open Dungeon Main", ImVec2(-1, 0))) {
|
||||
if (dungeon_main_card_) dungeon_main_card_->Show();
|
||||
}
|
||||
|
||||
ImGui::Separator();
|
||||
|
||||
ImGui::Text("Sprite & Equipment Palettes");
|
||||
if (ImGui::Button("Open Sprite Palettes", ImVec2(-1, 0))) {
|
||||
if (sprite_card_) sprite_card_->Show();
|
||||
}
|
||||
if (ImGui::Button("Open Equipment Palettes", ImVec2(-1, 0))) {
|
||||
if (equipment_card_) equipment_card_->Show();
|
||||
}
|
||||
|
||||
ImGui::Separator();
|
||||
|
||||
// Show modified status for each card
|
||||
ImGui::TextColored(ImVec4(1.0f, 0.6f, 0.0f, 1.0f), "Modified Cards:");
|
||||
bool any_modified = false;
|
||||
|
||||
if (ow_main_card_ && ow_main_card_->HasUnsavedChanges()) {
|
||||
ImGui::BulletText("Overworld Main");
|
||||
any_modified = true;
|
||||
}
|
||||
if (ow_animated_card_ && ow_animated_card_->HasUnsavedChanges()) {
|
||||
ImGui::BulletText("Overworld Animated");
|
||||
any_modified = true;
|
||||
}
|
||||
if (dungeon_main_card_ && dungeon_main_card_->HasUnsavedChanges()) {
|
||||
ImGui::BulletText("Dungeon Main");
|
||||
any_modified = true;
|
||||
}
|
||||
if (sprite_card_ && sprite_card_->HasUnsavedChanges()) {
|
||||
ImGui::BulletText("Sprite Palettes");
|
||||
any_modified = true;
|
||||
}
|
||||
if (equipment_card_ && equipment_card_->HasUnsavedChanges()) {
|
||||
ImGui::BulletText("Equipment Palettes");
|
||||
any_modified = true;
|
||||
}
|
||||
|
||||
if (!any_modified) {
|
||||
ImGui::TextDisabled("No unsaved changes");
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace editor
|
||||
} // namespace yaze
|
||||
@@ -8,6 +8,7 @@
|
||||
#include "absl/status/status.h"
|
||||
#include "app/editor/editor.h"
|
||||
#include "app/editor/graphics/gfx_group_editor.h"
|
||||
#include "app/editor/palette/palette_group_card.h"
|
||||
#include "app/gfx/snes_color.h"
|
||||
#include "app/gui/editor_card_manager.h"
|
||||
#include "app/gfx/snes_palette.h"
|
||||
@@ -112,6 +113,8 @@ class PaletteEditor : public Editor {
|
||||
private:
|
||||
absl::Status HandleColorPopup(gfx::SnesPalette& palette, int i, int j, int n);
|
||||
|
||||
void DrawPaletteCards();
|
||||
|
||||
absl::Status status_;
|
||||
gfx::SnesColor current_color_;
|
||||
|
||||
@@ -127,6 +130,13 @@ class PaletteEditor : public Editor {
|
||||
palette_internal::PaletteEditorHistory history_;
|
||||
|
||||
Rom* rom_;
|
||||
|
||||
// Palette card instances
|
||||
std::unique_ptr<OverworldMainPaletteCard> ow_main_card_;
|
||||
std::unique_ptr<OverworldAnimatedPaletteCard> ow_animated_card_;
|
||||
std::unique_ptr<DungeonMainPaletteCard> dungeon_main_card_;
|
||||
std::unique_ptr<SpritePaletteCard> sprite_card_;
|
||||
std::unique_ptr<EquipmentPaletteCard> equipment_card_;
|
||||
};
|
||||
|
||||
} // namespace editor
|
||||
1014
src/app/editor/palette/palette_group_card.cc
Normal file
1014
src/app/editor/palette/palette_group_card.cc
Normal file
File diff suppressed because it is too large
Load Diff
403
src/app/editor/palette/palette_group_card.h
Normal file
403
src/app/editor/palette/palette_group_card.h
Normal file
@@ -0,0 +1,403 @@
|
||||
#ifndef YAZE_APP_EDITOR_GRAPHICS_PALETTE_GROUP_CARD_H
|
||||
#define YAZE_APP_EDITOR_GRAPHICS_PALETTE_GROUP_CARD_H
|
||||
|
||||
#include <functional>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <unordered_map>
|
||||
#include <unordered_set>
|
||||
#include <vector>
|
||||
|
||||
#include "absl/status/status.h"
|
||||
#include "app/gfx/snes_color.h"
|
||||
#include "app/gfx/snes_palette.h"
|
||||
#include "app/gui/editor_card_manager.h"
|
||||
#include "app/rom.h"
|
||||
#include "imgui/imgui.h"
|
||||
|
||||
namespace yaze {
|
||||
namespace editor {
|
||||
|
||||
/**
|
||||
* @brief Represents a single color change for undo/redo
|
||||
*/
|
||||
struct ColorChange {
|
||||
int palette_index;
|
||||
int color_index;
|
||||
gfx::SnesColor original_color;
|
||||
gfx::SnesColor new_color;
|
||||
uint64_t timestamp; // For history ordering
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Metadata for a single palette in a group
|
||||
*/
|
||||
struct PaletteMetadata {
|
||||
int palette_id; // Palette ID in ROM
|
||||
std::string name; // Display name (e.g., "Light World Main")
|
||||
std::string description; // Usage description
|
||||
uint32_t rom_address; // Base ROM address for this palette
|
||||
uint32_t vram_address; // VRAM address (for sprite palettes, 0 if N/A)
|
||||
std::string usage_notes; // Additional usage information
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Metadata for an entire palette group
|
||||
*/
|
||||
struct PaletteGroupMetadata {
|
||||
std::string group_name; // Internal group name
|
||||
std::string display_name; // Display name for UI
|
||||
std::vector<PaletteMetadata> palettes; // Metadata for each palette
|
||||
int colors_per_palette; // Number of colors per palette (usually 8 or 16)
|
||||
int colors_per_row; // Colors per row for grid layout
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Base class for palette group editing cards
|
||||
*
|
||||
* Provides common functionality for all palette group editors:
|
||||
* - ROM persistence with transaction-based writes
|
||||
* - Undo/redo history management
|
||||
* - Modified state tracking with visual indicators
|
||||
* - Save/discard workflow
|
||||
* - Common toolbar and color picker UI
|
||||
* - EditorCardManager integration
|
||||
*
|
||||
* Derived classes implement specific grid layouts and palette access.
|
||||
*/
|
||||
class PaletteGroupCard {
|
||||
public:
|
||||
/**
|
||||
* @brief Construct a new Palette Group Card
|
||||
* @param group_name Internal palette group name (e.g., "ow_main", "dungeon_main")
|
||||
* @param display_name Human-readable name for UI
|
||||
* @param rom ROM instance for reading/writing palettes
|
||||
*/
|
||||
PaletteGroupCard(const std::string& group_name,
|
||||
const std::string& display_name,
|
||||
Rom* rom);
|
||||
|
||||
virtual ~PaletteGroupCard() = default;
|
||||
|
||||
// ========== Main Rendering ==========
|
||||
|
||||
/**
|
||||
* @brief Draw the card's ImGui UI
|
||||
*/
|
||||
void Draw();
|
||||
|
||||
// ========== Card Control ==========
|
||||
|
||||
void Show() { show_ = true; }
|
||||
void Hide() { show_ = false; }
|
||||
bool IsVisible() const { return show_; }
|
||||
bool* visibility_flag() { return &show_; }
|
||||
|
||||
// ========== Palette Operations ==========
|
||||
|
||||
/**
|
||||
* @brief Save all modified palettes to ROM
|
||||
*/
|
||||
absl::Status SaveToRom();
|
||||
|
||||
/**
|
||||
* @brief Discard all unsaved changes
|
||||
*/
|
||||
void DiscardChanges();
|
||||
|
||||
/**
|
||||
* @brief Reset a specific palette to original ROM values
|
||||
*/
|
||||
void ResetPalette(int palette_index);
|
||||
|
||||
/**
|
||||
* @brief Reset a specific color to original ROM value
|
||||
*/
|
||||
void ResetColor(int palette_index, int color_index);
|
||||
|
||||
/**
|
||||
* @brief Set a color value (records change for undo)
|
||||
*/
|
||||
void SetColor(int palette_index, int color_index, const gfx::SnesColor& new_color);
|
||||
|
||||
// ========== History Management ==========
|
||||
|
||||
void Undo();
|
||||
void Redo();
|
||||
bool CanUndo() const { return !undo_stack_.empty(); }
|
||||
bool CanRedo() const { return !redo_stack_.empty(); }
|
||||
void ClearHistory();
|
||||
|
||||
// ========== State Queries ==========
|
||||
|
||||
bool HasUnsavedChanges() const { return !modified_palettes_.empty(); }
|
||||
bool IsPaletteModified(int palette_index) const;
|
||||
bool IsColorModified(int palette_index, int color_index) const;
|
||||
|
||||
int GetSelectedPaletteIndex() const { return selected_palette_; }
|
||||
void SetSelectedPaletteIndex(int index) { selected_palette_ = index; }
|
||||
|
||||
int GetSelectedColorIndex() const { return selected_color_; }
|
||||
void SetSelectedColorIndex(int index) { selected_color_ = index; }
|
||||
|
||||
// ========== Export/Import ==========
|
||||
|
||||
std::string ExportToJson() const;
|
||||
absl::Status ImportFromJson(const std::string& json);
|
||||
|
||||
std::string ExportToClipboard() const;
|
||||
absl::Status ImportFromClipboard();
|
||||
|
||||
protected:
|
||||
// ========== Pure Virtual Methods (Implemented by Derived Classes) ==========
|
||||
|
||||
/**
|
||||
* @brief Get the palette group for this card
|
||||
*/
|
||||
virtual gfx::PaletteGroup* GetPaletteGroup() = 0;
|
||||
virtual const gfx::PaletteGroup* GetPaletteGroup() const = 0;
|
||||
|
||||
/**
|
||||
* @brief Get metadata for this palette group
|
||||
*/
|
||||
virtual const PaletteGroupMetadata& GetMetadata() const = 0;
|
||||
|
||||
/**
|
||||
* @brief Draw the palette grid specific to this palette type
|
||||
*/
|
||||
virtual void DrawPaletteGrid() = 0;
|
||||
|
||||
/**
|
||||
* @brief Get the number of colors per row for grid layout
|
||||
*/
|
||||
virtual int GetColorsPerRow() const = 0;
|
||||
|
||||
// ========== Optional Overrides ==========
|
||||
|
||||
/**
|
||||
* @brief Draw additional toolbar buttons (called after standard buttons)
|
||||
*/
|
||||
virtual void DrawCustomToolbarButtons() {}
|
||||
|
||||
/**
|
||||
* @brief Draw additional panels (called after main content)
|
||||
*/
|
||||
virtual void DrawCustomPanels() {}
|
||||
|
||||
// ========== Common UI Components ==========
|
||||
|
||||
/**
|
||||
* @brief Draw standard toolbar with save/discard/undo/redo
|
||||
*/
|
||||
void DrawToolbar();
|
||||
|
||||
/**
|
||||
* @brief Draw palette selector dropdown
|
||||
*/
|
||||
void DrawPaletteSelector();
|
||||
|
||||
/**
|
||||
* @brief Draw color picker for selected color
|
||||
*/
|
||||
void DrawColorPicker();
|
||||
|
||||
/**
|
||||
* @brief Draw color info panel with RGB/SNES/Hex values
|
||||
*/
|
||||
void DrawColorInfo();
|
||||
|
||||
/**
|
||||
* @brief Draw palette metadata info panel
|
||||
*/
|
||||
void DrawMetadataInfo();
|
||||
|
||||
/**
|
||||
* @brief Draw batch operations popup
|
||||
*/
|
||||
void DrawBatchOperationsPopup();
|
||||
|
||||
// ========== Helper Methods ==========
|
||||
|
||||
/**
|
||||
* @brief Get mutable palette by index
|
||||
*/
|
||||
gfx::SnesPalette* GetMutablePalette(int index);
|
||||
|
||||
/**
|
||||
* @brief Get original color from ROM (for reset/comparison)
|
||||
*/
|
||||
gfx::SnesColor GetOriginalColor(int palette_index, int color_index) const;
|
||||
|
||||
/**
|
||||
* @brief Write a single color to ROM
|
||||
*/
|
||||
absl::Status WriteColorToRom(int palette_index, int color_index,
|
||||
const gfx::SnesColor& color);
|
||||
|
||||
/**
|
||||
* @brief Mark palette as modified
|
||||
*/
|
||||
void MarkModified(int palette_index, int color_index);
|
||||
|
||||
/**
|
||||
* @brief Clear modified flags for palette
|
||||
*/
|
||||
void ClearModified(int palette_index);
|
||||
|
||||
// ========== Member Variables ==========
|
||||
|
||||
std::string group_name_; // Internal name (e.g., "ow_main")
|
||||
std::string display_name_; // Display name (e.g., "Overworld Main")
|
||||
Rom* rom_; // ROM instance
|
||||
bool show_ = false; // Visibility flag
|
||||
|
||||
// Selection state
|
||||
int selected_palette_ = 0; // Currently selected palette index
|
||||
int selected_color_ = -1; // Currently selected color (-1 = none)
|
||||
gfx::SnesColor editing_color_; // Color being edited in picker
|
||||
|
||||
// Modified tracking
|
||||
std::unordered_set<int> modified_palettes_;
|
||||
std::unordered_map<int, std::unordered_set<int>> modified_colors_;
|
||||
|
||||
// Undo/Redo
|
||||
std::vector<ColorChange> undo_stack_;
|
||||
std::vector<ColorChange> redo_stack_;
|
||||
static constexpr size_t kMaxUndoHistory = 100;
|
||||
|
||||
// Settings
|
||||
bool auto_save_enabled_ = false; // Auto-save to ROM on every change
|
||||
bool show_snes_format_ = true; // Show SNES $xxxx format in info
|
||||
bool show_hex_format_ = true; // Show #xxxxxx hex in info
|
||||
|
||||
// Original palettes (loaded from ROM for reset/comparison)
|
||||
std::vector<gfx::SnesPalette> original_palettes_;
|
||||
|
||||
// Card registration
|
||||
gui::CardRegistration card_registration_;
|
||||
};
|
||||
|
||||
// ============================================================================
|
||||
// Concrete Palette Card Implementations
|
||||
// ============================================================================
|
||||
|
||||
/**
|
||||
* @brief Overworld Main palette group card
|
||||
*
|
||||
* Manages palettes used for overworld rendering:
|
||||
* - Light World palettes (0-19)
|
||||
* - Dark World palettes (20-39)
|
||||
* - Special World palettes (40-59)
|
||||
*/
|
||||
class OverworldMainPaletteCard : public PaletteGroupCard {
|
||||
public:
|
||||
explicit OverworldMainPaletteCard(Rom* rom);
|
||||
~OverworldMainPaletteCard() override = default;
|
||||
|
||||
protected:
|
||||
gfx::PaletteGroup* GetPaletteGroup() override;
|
||||
const gfx::PaletteGroup* GetPaletteGroup() const override;
|
||||
const PaletteGroupMetadata& GetMetadata() const override { return metadata_; }
|
||||
void DrawPaletteGrid() override;
|
||||
int GetColorsPerRow() const override { return 8; }
|
||||
|
||||
private:
|
||||
static PaletteGroupMetadata InitializeMetadata();
|
||||
static const PaletteGroupMetadata metadata_;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Overworld Animated palette group card
|
||||
*
|
||||
* Manages animated palettes for water, lava, and other effects
|
||||
*/
|
||||
class OverworldAnimatedPaletteCard : public PaletteGroupCard {
|
||||
public:
|
||||
explicit OverworldAnimatedPaletteCard(Rom* rom);
|
||||
~OverworldAnimatedPaletteCard() override = default;
|
||||
|
||||
protected:
|
||||
gfx::PaletteGroup* GetPaletteGroup() override;
|
||||
const gfx::PaletteGroup* GetPaletteGroup() const override;
|
||||
const PaletteGroupMetadata& GetMetadata() const override { return metadata_; }
|
||||
void DrawPaletteGrid() override;
|
||||
int GetColorsPerRow() const override { return 8; }
|
||||
|
||||
private:
|
||||
static PaletteGroupMetadata InitializeMetadata();
|
||||
static const PaletteGroupMetadata metadata_;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Dungeon Main palette group card
|
||||
*
|
||||
* Manages palettes for dungeon rooms (0-19)
|
||||
*/
|
||||
class DungeonMainPaletteCard : public PaletteGroupCard {
|
||||
public:
|
||||
explicit DungeonMainPaletteCard(Rom* rom);
|
||||
~DungeonMainPaletteCard() override = default;
|
||||
|
||||
protected:
|
||||
gfx::PaletteGroup* GetPaletteGroup() override;
|
||||
const gfx::PaletteGroup* GetPaletteGroup() const override;
|
||||
const PaletteGroupMetadata& GetMetadata() const override { return metadata_; }
|
||||
void DrawPaletteGrid() override;
|
||||
int GetColorsPerRow() const override { return 16; }
|
||||
|
||||
private:
|
||||
static PaletteGroupMetadata InitializeMetadata();
|
||||
static const PaletteGroupMetadata metadata_;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Sprite palette group card
|
||||
*
|
||||
* Manages sprite palettes with VRAM locations
|
||||
* - Global sprites (palettes 0-3)
|
||||
* - Auxiliary sprites (palettes 4-5)
|
||||
*/
|
||||
class SpritePaletteCard : public PaletteGroupCard {
|
||||
public:
|
||||
explicit SpritePaletteCard(Rom* rom);
|
||||
~SpritePaletteCard() override = default;
|
||||
|
||||
protected:
|
||||
gfx::PaletteGroup* GetPaletteGroup() override;
|
||||
const gfx::PaletteGroup* GetPaletteGroup() const override;
|
||||
const PaletteGroupMetadata& GetMetadata() const override { return metadata_; }
|
||||
void DrawPaletteGrid() override;
|
||||
int GetColorsPerRow() const override { return 8; }
|
||||
void DrawCustomPanels() override; // Show VRAM info
|
||||
|
||||
private:
|
||||
static PaletteGroupMetadata InitializeMetadata();
|
||||
static const PaletteGroupMetadata metadata_;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Equipment/Armor palette group card
|
||||
*
|
||||
* Manages Link's equipment color palettes (green, blue, red tunics)
|
||||
*/
|
||||
class EquipmentPaletteCard : public PaletteGroupCard {
|
||||
public:
|
||||
explicit EquipmentPaletteCard(Rom* rom);
|
||||
~EquipmentPaletteCard() override = default;
|
||||
|
||||
protected:
|
||||
gfx::PaletteGroup* GetPaletteGroup() override;
|
||||
const gfx::PaletteGroup* GetPaletteGroup() const override;
|
||||
const PaletteGroupMetadata& GetMetadata() const override { return metadata_; }
|
||||
void DrawPaletteGrid() override;
|
||||
int GetColorsPerRow() const override { return 8; }
|
||||
|
||||
private:
|
||||
static PaletteGroupMetadata InitializeMetadata();
|
||||
static const PaletteGroupMetadata metadata_;
|
||||
};
|
||||
|
||||
} // namespace editor
|
||||
} // namespace yaze
|
||||
|
||||
#endif // YAZE_APP_EDITOR_GRAPHICS_PALETTE_GROUP_CARD_H
|
||||
@@ -1,14 +1,16 @@
|
||||
#include "app/gui/themed_widgets.h"
|
||||
|
||||
#include "app/gui/color.h"
|
||||
#include "app/gfx/snes_color.h"
|
||||
|
||||
namespace yaze {
|
||||
namespace gui {
|
||||
namespace themed {
|
||||
|
||||
// ============================================================================
|
||||
// Buttons
|
||||
// ============================================================================
|
||||
|
||||
bool Button(const char* label, const ImVec2& size) {
|
||||
bool ThemedButton(const char* label, const ImVec2& size) {
|
||||
const auto& theme = GetTheme();
|
||||
ImGui::PushStyleColor(ImGuiCol_Button, ConvertColorToImVec4(theme.button));
|
||||
ImGui::PushStyleColor(ImGuiCol_ButtonHovered, ConvertColorToImVec4(theme.button_hovered));
|
||||
@@ -20,13 +22,13 @@ bool Button(const char* label, const ImVec2& size) {
|
||||
return result;
|
||||
}
|
||||
|
||||
bool IconButton(const char* icon, const char* tooltip) {
|
||||
bool result = Button(icon, ImVec2(LayoutHelpers::GetStandardWidgetHeight(),
|
||||
LayoutHelpers::GetStandardWidgetHeight()));
|
||||
bool ThemedIconButton(const char* icon, const char* tooltip) {
|
||||
bool result = ThemedButton(icon, ImVec2(LayoutHelpers::GetStandardWidgetHeight(),
|
||||
LayoutHelpers::GetStandardWidgetHeight()));
|
||||
if (tooltip && ImGui::IsItemHovered()) {
|
||||
BeginTooltip();
|
||||
BeginThemedTooltip();
|
||||
ImGui::Text("%s", tooltip);
|
||||
EndTooltip();
|
||||
EndThemedTooltip();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
@@ -67,11 +69,11 @@ bool DangerButton(const char* label, const ImVec2& size) {
|
||||
// Headers & Sections
|
||||
// ============================================================================
|
||||
|
||||
void Header(const char* label) {
|
||||
void SectionHeader(const char* label) {
|
||||
LayoutHelpers::SectionHeader(label);
|
||||
}
|
||||
|
||||
bool CollapsingHeader(const char* label, ImGuiTreeNodeFlags flags) {
|
||||
bool ThemedCollapsingHeader(const char* label, ImGuiTreeNodeFlags flags) {
|
||||
const auto& theme = GetTheme();
|
||||
ImGui::PushStyleColor(ImGuiCol_Header, ConvertColorToImVec4(theme.header));
|
||||
ImGui::PushStyleColor(ImGuiCol_HeaderHovered, ConvertColorToImVec4(theme.header_hovered));
|
||||
@@ -87,13 +89,13 @@ bool CollapsingHeader(const char* label, ImGuiTreeNodeFlags flags) {
|
||||
// Cards & Panels
|
||||
// ============================================================================
|
||||
|
||||
void Card(const char* label, std::function<void()> content, const ImVec2& size) {
|
||||
BeginPanel(label, size);
|
||||
void ThemedCard(const char* label, std::function<void()> content, const ImVec2& size) {
|
||||
BeginThemedPanel(label, size);
|
||||
content();
|
||||
EndPanel();
|
||||
EndThemedPanel();
|
||||
}
|
||||
|
||||
void BeginPanel(const char* label, const ImVec2& size) {
|
||||
void BeginThemedPanel(const char* label, const ImVec2& size) {
|
||||
const auto& theme = GetTheme();
|
||||
|
||||
ImGui::PushStyleColor(ImGuiCol_ChildBg, ConvertColorToImVec4(theme.surface));
|
||||
@@ -105,7 +107,7 @@ void BeginPanel(const char* label, const ImVec2& size) {
|
||||
ImGui::BeginChild(label, size, true);
|
||||
}
|
||||
|
||||
void EndPanel() {
|
||||
void EndThemedPanel() {
|
||||
ImGui::EndChild();
|
||||
ImGui::PopStyleVar(2);
|
||||
ImGui::PopStyleColor(1);
|
||||
@@ -115,8 +117,8 @@ void EndPanel() {
|
||||
// Inputs
|
||||
// ============================================================================
|
||||
|
||||
bool InputText(const char* label, char* buf, size_t buf_size,
|
||||
ImGuiInputTextFlags flags) {
|
||||
bool ThemedInputText(const char* label, char* buf, size_t buf_size,
|
||||
ImGuiInputTextFlags flags) {
|
||||
const auto& theme = GetTheme();
|
||||
ImGui::PushStyleColor(ImGuiCol_FrameBg, ConvertColorToImVec4(theme.frame_bg));
|
||||
ImGui::PushStyleColor(ImGuiCol_FrameBgHovered, ConvertColorToImVec4(theme.frame_bg_hovered));
|
||||
@@ -129,8 +131,8 @@ bool InputText(const char* label, char* buf, size_t buf_size,
|
||||
return result;
|
||||
}
|
||||
|
||||
bool InputInt(const char* label, int* v, int step, int step_fast,
|
||||
ImGuiInputTextFlags flags) {
|
||||
bool ThemedInputInt(const char* label, int* v, int step, int step_fast,
|
||||
ImGuiInputTextFlags flags) {
|
||||
const auto& theme = GetTheme();
|
||||
ImGui::PushStyleColor(ImGuiCol_FrameBg, ConvertColorToImVec4(theme.frame_bg));
|
||||
ImGui::PushStyleColor(ImGuiCol_FrameBgHovered, ConvertColorToImVec4(theme.frame_bg_hovered));
|
||||
@@ -143,8 +145,8 @@ bool InputInt(const char* label, int* v, int step, int step_fast,
|
||||
return result;
|
||||
}
|
||||
|
||||
bool InputFloat(const char* label, float* v, float step, float step_fast,
|
||||
const char* format, ImGuiInputTextFlags flags) {
|
||||
bool ThemedInputFloat(const char* label, float* v, float step, float step_fast,
|
||||
const char* format, ImGuiInputTextFlags flags) {
|
||||
const auto& theme = GetTheme();
|
||||
ImGui::PushStyleColor(ImGuiCol_FrameBg, ConvertColorToImVec4(theme.frame_bg));
|
||||
ImGui::PushStyleColor(ImGuiCol_FrameBgHovered, ConvertColorToImVec4(theme.frame_bg_hovered));
|
||||
@@ -157,7 +159,7 @@ bool InputFloat(const char* label, float* v, float step, float step_fast,
|
||||
return result;
|
||||
}
|
||||
|
||||
bool Checkbox(const char* label, bool* v) {
|
||||
bool ThemedCheckbox(const char* label, bool* v) {
|
||||
const auto& theme = GetTheme();
|
||||
ImGui::PushStyleColor(ImGuiCol_CheckMark, ConvertColorToImVec4(theme.check_mark));
|
||||
|
||||
@@ -167,8 +169,8 @@ bool Checkbox(const char* label, bool* v) {
|
||||
return result;
|
||||
}
|
||||
|
||||
bool Combo(const char* label, int* current_item, const char* const items[],
|
||||
int items_count, int popup_max_height_in_items) {
|
||||
bool ThemedCombo(const char* label, int* current_item, const char* const items[],
|
||||
int items_count, int popup_max_height_in_items) {
|
||||
const auto& theme = GetTheme();
|
||||
ImGui::PushStyleColor(ImGuiCol_FrameBg, ConvertColorToImVec4(theme.frame_bg));
|
||||
ImGui::PushStyleColor(ImGuiCol_FrameBgHovered, ConvertColorToImVec4(theme.frame_bg_hovered));
|
||||
@@ -186,12 +188,12 @@ bool Combo(const char* label, int* current_item, const char* const items[],
|
||||
// Tables
|
||||
// ============================================================================
|
||||
|
||||
bool BeginTable(const char* str_id, int columns, ImGuiTableFlags flags,
|
||||
const ImVec2& outer_size, float inner_width) {
|
||||
bool BeginThemedTable(const char* str_id, int columns, ImGuiTableFlags flags,
|
||||
const ImVec2& outer_size, float inner_width) {
|
||||
return LayoutHelpers::BeginTableWithTheming(str_id, columns, flags, outer_size, inner_width);
|
||||
}
|
||||
|
||||
void EndTable() {
|
||||
void EndThemedTable() {
|
||||
LayoutHelpers::EndTable();
|
||||
}
|
||||
|
||||
@@ -199,17 +201,17 @@ void EndTable() {
|
||||
// Tooltips & Help
|
||||
// ============================================================================
|
||||
|
||||
void HelpMarker(const char* desc) {
|
||||
void ThemedHelpMarker(const char* desc) {
|
||||
LayoutHelpers::HelpMarker(desc);
|
||||
}
|
||||
|
||||
void BeginTooltip() {
|
||||
void BeginThemedTooltip() {
|
||||
const auto& theme = GetTheme();
|
||||
ImGui::PushStyleColor(ImGuiCol_PopupBg, ConvertColorToImVec4(theme.popup_bg));
|
||||
ImGui::BeginTooltip();
|
||||
}
|
||||
|
||||
void EndTooltip() {
|
||||
void EndThemedTooltip() {
|
||||
ImGui::EndTooltip();
|
||||
ImGui::PopStyleColor(1);
|
||||
}
|
||||
@@ -218,7 +220,7 @@ void EndTooltip() {
|
||||
// Status & Feedback
|
||||
// ============================================================================
|
||||
|
||||
void StatusText(const char* text, StatusType type) {
|
||||
void ThemedStatusText(const char* text, StatusType type) {
|
||||
const auto& theme = GetTheme();
|
||||
ImVec4 color;
|
||||
|
||||
@@ -240,7 +242,7 @@ void StatusText(const char* text, StatusType type) {
|
||||
ImGui::TextColored(color, "%s", text);
|
||||
}
|
||||
|
||||
void ProgressBar(float fraction, const ImVec2& size, const char* overlay) {
|
||||
void ThemedProgressBar(float fraction, const ImVec2& size, const char* overlay) {
|
||||
const auto& theme = GetTheme();
|
||||
ImGui::PushStyleColor(ImGuiCol_PlotHistogram, ConvertColorToImVec4(theme.accent));
|
||||
|
||||
@@ -249,11 +251,117 @@ void ProgressBar(float fraction, const ImVec2& size, const char* overlay) {
|
||||
ImGui::PopStyleColor(1);
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// Palette Editor Widgets
|
||||
// ============================================================================
|
||||
|
||||
bool PaletteColorButton(const char* label, const yaze::gfx::SnesColor& color,
|
||||
bool is_selected, bool is_modified,
|
||||
const ImVec2& size) {
|
||||
const auto& theme = GetTheme();
|
||||
|
||||
int style_count = 0;
|
||||
|
||||
// Draw modified indicator with warning border
|
||||
if (is_modified) {
|
||||
ImGui::PushStyleColor(ImGuiCol_Border, ConvertColorToImVec4(theme.warning));
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_FrameBorderSize, 2.0f);
|
||||
style_count++;
|
||||
}
|
||||
|
||||
// Draw selection border (overrides modified if both)
|
||||
if (is_selected) {
|
||||
ImGui::PushStyleColor(ImGuiCol_Border, ConvertColorToImVec4(theme.accent));
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_FrameBorderSize, 3.0f);
|
||||
if (is_modified) {
|
||||
ImGui::PopStyleVar(); // Remove modified border style
|
||||
ImGui::PopStyleColor(); // Remove modified border color
|
||||
}
|
||||
style_count = 1; // Override count
|
||||
}
|
||||
|
||||
// Convert SNES color to ImGui format
|
||||
ImVec4 col = ConvertSnesColorToImVec4(color);
|
||||
|
||||
// Draw color button
|
||||
bool clicked = ImGui::ColorButton(label, col,
|
||||
ImGuiColorEditFlags_NoAlpha |
|
||||
ImGuiColorEditFlags_NoPicker |
|
||||
ImGuiColorEditFlags_NoTooltip,
|
||||
size);
|
||||
|
||||
// Cleanup styles
|
||||
if (style_count > 0) {
|
||||
ImGui::PopStyleVar();
|
||||
ImGui::PopStyleColor();
|
||||
}
|
||||
|
||||
return clicked;
|
||||
}
|
||||
|
||||
void ColorInfoPanel(const yaze::gfx::SnesColor& color,
|
||||
bool show_snes_format,
|
||||
bool show_hex_format) {
|
||||
auto col = color.rgb();
|
||||
int r = static_cast<int>(col.x);
|
||||
int g = static_cast<int>(col.y);
|
||||
int b = static_cast<int>(col.z);
|
||||
|
||||
// RGB values
|
||||
ImGui::Text("RGB (0-255):");
|
||||
ImGui::SameLine();
|
||||
ImGui::Text("(%d, %d, %d)", r, g, b);
|
||||
if (ImGui::IsItemClicked()) {
|
||||
char buf[64];
|
||||
snprintf(buf, sizeof(buf), "(%d, %d, %d)", r, g, b);
|
||||
ImGui::SetClipboardText(buf);
|
||||
}
|
||||
|
||||
// SNES BGR555 value
|
||||
if (show_snes_format) {
|
||||
ImGui::Text("SNES BGR555:");
|
||||
ImGui::SameLine();
|
||||
ImGui::Text("$%04X", color.snes());
|
||||
if (ImGui::IsItemClicked()) {
|
||||
char buf[16];
|
||||
snprintf(buf, sizeof(buf), "$%04X", color.snes());
|
||||
ImGui::SetClipboardText(buf);
|
||||
}
|
||||
}
|
||||
|
||||
// Hex value
|
||||
if (show_hex_format) {
|
||||
ImGui::Text("Hex:");
|
||||
ImGui::SameLine();
|
||||
ImGui::Text("#%02X%02X%02X", r, g, b);
|
||||
if (ImGui::IsItemClicked()) {
|
||||
char buf[16];
|
||||
snprintf(buf, sizeof(buf), "#%02X%02X%02X", r, g, b);
|
||||
ImGui::SetClipboardText(buf);
|
||||
}
|
||||
}
|
||||
|
||||
ImGui::TextDisabled("(Click any value to copy)");
|
||||
}
|
||||
|
||||
void ModifiedBadge(bool is_modified, const char* text) {
|
||||
if (!is_modified) return;
|
||||
|
||||
const auto& theme = GetTheme();
|
||||
ImVec4 color = ConvertColorToImVec4(theme.warning);
|
||||
|
||||
if (text) {
|
||||
ImGui::TextColored(color, "%s", text);
|
||||
} else {
|
||||
ImGui::TextColored(color, "Modified");
|
||||
}
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// Utility
|
||||
// ============================================================================
|
||||
|
||||
void PushWidgetColors() {
|
||||
void PushThemedWidgetColors() {
|
||||
const auto& theme = GetTheme();
|
||||
ImGui::PushStyleColor(ImGuiCol_FrameBg, ConvertColorToImVec4(theme.frame_bg));
|
||||
ImGui::PushStyleColor(ImGuiCol_FrameBgHovered, ConvertColorToImVec4(theme.frame_bg_hovered));
|
||||
@@ -263,10 +371,9 @@ void PushWidgetColors() {
|
||||
ImGui::PushStyleColor(ImGuiCol_ButtonActive, ConvertColorToImVec4(theme.button_active));
|
||||
}
|
||||
|
||||
void PopWidgetColors() {
|
||||
void PopThemedWidgetColors() {
|
||||
ImGui::PopStyleColor(6);
|
||||
}
|
||||
|
||||
} // namespace themed
|
||||
} // namespace gui
|
||||
} // namespace yaze
|
||||
|
||||
@@ -10,27 +10,26 @@ namespace yaze {
|
||||
namespace gui {
|
||||
|
||||
/**
|
||||
* @brief Opt-in themed widget library for gradual migration
|
||||
* @brief Theme-aware widget library
|
||||
*
|
||||
* All widgets automatically use the current theme from ThemeManager.
|
||||
* Editors can opt-in by using these widgets instead of raw ImGui calls.
|
||||
* All widgets in this file automatically use the current theme from ThemeManager.
|
||||
* These are drop-in replacements for standard ImGui widgets with automatic theming.
|
||||
*
|
||||
* Usage:
|
||||
* ```cpp
|
||||
* using namespace yaze::gui::themed;
|
||||
* using namespace yaze::gui;
|
||||
*
|
||||
* if (Button("Save")) {
|
||||
* if (ThemedButton("Save")) {
|
||||
* // Button uses theme colors automatically
|
||||
* }
|
||||
*
|
||||
* Header("Settings"); // Themed section header
|
||||
* SectionHeader("Settings"); // Themed section header
|
||||
*
|
||||
* Card("Properties", [&]() {
|
||||
* ThemedCard("Properties", [&]() {
|
||||
* // Content inside themed card
|
||||
* });
|
||||
* ```
|
||||
*/
|
||||
namespace themed {
|
||||
|
||||
// ============================================================================
|
||||
// Buttons
|
||||
@@ -39,12 +38,12 @@ namespace themed {
|
||||
/**
|
||||
* @brief Themed button with automatic color application
|
||||
*/
|
||||
bool Button(const char* label, const ImVec2& size = ImVec2(0, 0));
|
||||
bool ThemedButton(const char* label, const ImVec2& size = ImVec2(0, 0));
|
||||
|
||||
/**
|
||||
* @brief Themed button with icon (Material Design Icons)
|
||||
*/
|
||||
bool IconButton(const char* icon, const char* tooltip = nullptr);
|
||||
bool ThemedIconButton(const char* icon, const char* tooltip = nullptr);
|
||||
|
||||
/**
|
||||
* @brief Primary action button (uses accent color)
|
||||
@@ -63,12 +62,12 @@ bool DangerButton(const char* label, const ImVec2& size = ImVec2(0, 0));
|
||||
/**
|
||||
* @brief Themed section header with accent color
|
||||
*/
|
||||
void Header(const char* label);
|
||||
void SectionHeader(const char* label);
|
||||
|
||||
/**
|
||||
* @brief Collapsible section with themed header
|
||||
*/
|
||||
bool CollapsingHeader(const char* label, ImGuiTreeNodeFlags flags = 0);
|
||||
bool ThemedCollapsingHeader(const char* label, ImGuiTreeNodeFlags flags = 0);
|
||||
|
||||
// ============================================================================
|
||||
// Cards & Panels
|
||||
@@ -80,18 +79,18 @@ bool CollapsingHeader(const char* label, ImGuiTreeNodeFlags flags = 0);
|
||||
* @param content Callback function to render card content
|
||||
* @param size Card size (0, 0 for auto-size)
|
||||
*/
|
||||
void Card(const char* label, std::function<void()> content,
|
||||
const ImVec2& size = ImVec2(0, 0));
|
||||
void ThemedCard(const char* label, std::function<void()> content,
|
||||
const ImVec2& size = ImVec2(0, 0));
|
||||
|
||||
/**
|
||||
* @brief Begin themed panel (manual version of Card)
|
||||
* @brief Begin themed panel (manual version of ThemedCard)
|
||||
*/
|
||||
void BeginPanel(const char* label, const ImVec2& size = ImVec2(0, 0));
|
||||
void BeginThemedPanel(const char* label, const ImVec2& size = ImVec2(0, 0));
|
||||
|
||||
/**
|
||||
* @brief End themed panel
|
||||
*/
|
||||
void EndPanel();
|
||||
void EndThemedPanel();
|
||||
|
||||
// ============================================================================
|
||||
// Inputs
|
||||
@@ -100,32 +99,32 @@ void EndPanel();
|
||||
/**
|
||||
* @brief Themed text input
|
||||
*/
|
||||
bool InputText(const char* label, char* buf, size_t buf_size,
|
||||
ImGuiInputTextFlags flags = 0);
|
||||
bool ThemedInputText(const char* label, char* buf, size_t buf_size,
|
||||
ImGuiInputTextFlags flags = 0);
|
||||
|
||||
/**
|
||||
* @brief Themed integer input
|
||||
*/
|
||||
bool InputInt(const char* label, int* v, int step = 1, int step_fast = 100,
|
||||
ImGuiInputTextFlags flags = 0);
|
||||
bool ThemedInputInt(const char* label, int* v, int step = 1, int step_fast = 100,
|
||||
ImGuiInputTextFlags flags = 0);
|
||||
|
||||
/**
|
||||
* @brief Themed float input
|
||||
*/
|
||||
bool InputFloat(const char* label, float* v, float step = 0.0f,
|
||||
float step_fast = 0.0f, const char* format = "%.3f",
|
||||
ImGuiInputTextFlags flags = 0);
|
||||
bool ThemedInputFloat(const char* label, float* v, float step = 0.0f,
|
||||
float step_fast = 0.0f, const char* format = "%.3f",
|
||||
ImGuiInputTextFlags flags = 0);
|
||||
|
||||
/**
|
||||
* @brief Themed checkbox
|
||||
*/
|
||||
bool Checkbox(const char* label, bool* v);
|
||||
bool ThemedCheckbox(const char* label, bool* v);
|
||||
|
||||
/**
|
||||
* @brief Themed combo box
|
||||
*/
|
||||
bool Combo(const char* label, int* current_item, const char* const items[],
|
||||
int items_count, int popup_max_height_in_items = -1);
|
||||
bool ThemedCombo(const char* label, int* current_item, const char* const items[],
|
||||
int items_count, int popup_max_height_in_items = -1);
|
||||
|
||||
// ============================================================================
|
||||
// Tables
|
||||
@@ -134,14 +133,14 @@ bool Combo(const char* label, int* current_item, const char* const items[],
|
||||
/**
|
||||
* @brief Begin themed table with automatic styling
|
||||
*/
|
||||
bool BeginTable(const char* str_id, int columns, ImGuiTableFlags flags = 0,
|
||||
const ImVec2& outer_size = ImVec2(0, 0),
|
||||
float inner_width = 0.0f);
|
||||
bool BeginThemedTable(const char* str_id, int columns, ImGuiTableFlags flags = 0,
|
||||
const ImVec2& outer_size = ImVec2(0, 0),
|
||||
float inner_width = 0.0f);
|
||||
|
||||
/**
|
||||
* @brief End themed table
|
||||
*/
|
||||
void EndTable();
|
||||
void EndThemedTable();
|
||||
|
||||
// ============================================================================
|
||||
// Tooltips & Help
|
||||
@@ -150,17 +149,17 @@ void EndTable();
|
||||
/**
|
||||
* @brief Themed help marker with tooltip
|
||||
*/
|
||||
void HelpMarker(const char* desc);
|
||||
void ThemedHelpMarker(const char* desc);
|
||||
|
||||
/**
|
||||
* @brief Begin themed tooltip
|
||||
*/
|
||||
void BeginTooltip();
|
||||
void BeginThemedTooltip();
|
||||
|
||||
/**
|
||||
* @brief End themed tooltip
|
||||
*/
|
||||
void EndTooltip();
|
||||
void EndThemedTooltip();
|
||||
|
||||
// ============================================================================
|
||||
// Status & Feedback
|
||||
@@ -170,13 +169,47 @@ enum class StatusType { kSuccess, kWarning, kError, kInfo };
|
||||
/**
|
||||
* @brief Themed status text (success, warning, error, info)
|
||||
*/
|
||||
void StatusText(const char* text, StatusType type);
|
||||
void ThemedStatusText(const char* text, StatusType type);
|
||||
|
||||
/**
|
||||
* @brief Themed progress bar
|
||||
*/
|
||||
void ProgressBar(float fraction, const ImVec2& size = ImVec2(-1, 0),
|
||||
const char* overlay = nullptr);
|
||||
void ThemedProgressBar(float fraction, const ImVec2& size = ImVec2(-1, 0),
|
||||
const char* overlay = nullptr);
|
||||
|
||||
// ============================================================================
|
||||
// Palette Editor Widgets
|
||||
// ============================================================================
|
||||
|
||||
/**
|
||||
* @brief Palette color button with modified and selection indicators
|
||||
* @param label Widget ID
|
||||
* @param color SNES color to display
|
||||
* @param is_selected Whether this color is currently selected
|
||||
* @param is_modified Whether this color has unsaved changes
|
||||
* @param size Button size (default 24x24)
|
||||
* @return true if clicked
|
||||
*/
|
||||
bool PaletteColorButton(const char* label, const yaze::gfx::SnesColor& color,
|
||||
bool is_selected, bool is_modified,
|
||||
const ImVec2& size = ImVec2(24, 24));
|
||||
|
||||
/**
|
||||
* @brief Display color information with copy-to-clipboard functionality
|
||||
* @param color SNES color to display info for
|
||||
* @param show_snes_format Show SNES $xxxx format
|
||||
* @param show_hex_format Show #xxxxxx hex format
|
||||
*/
|
||||
void ColorInfoPanel(const yaze::gfx::SnesColor& color,
|
||||
bool show_snes_format = true,
|
||||
bool show_hex_format = true);
|
||||
|
||||
/**
|
||||
* @brief Modified indicator badge (displayed as text with icon)
|
||||
* @param is_modified Whether to show the badge
|
||||
* @param text Optional text to display after badge
|
||||
*/
|
||||
void ModifiedBadge(bool is_modified, const char* text = nullptr);
|
||||
|
||||
// ============================================================================
|
||||
// Utility
|
||||
@@ -192,14 +225,13 @@ inline const EnhancedTheme& GetTheme() {
|
||||
/**
|
||||
* @brief Apply theme colors to next widget
|
||||
*/
|
||||
void PushWidgetColors();
|
||||
void PushThemedWidgetColors();
|
||||
|
||||
/**
|
||||
* @brief Restore previous colors
|
||||
*/
|
||||
void PopWidgetColors();
|
||||
void PopThemedWidgetColors();
|
||||
|
||||
} // namespace themed
|
||||
} // namespace gui
|
||||
} // namespace yaze
|
||||
|
||||
|
||||
Reference in New Issue
Block a user