yaze 0.3.2
Link to the Past ROM Editor
 
Loading...
Searching...
No Matches
graphics_editor_state.h
Go to the documentation of this file.
1#ifndef YAZE_APP_EDITOR_GRAPHICS_GRAPHICS_EDITOR_STATE_H
2#define YAZE_APP_EDITOR_GRAPHICS_GRAPHICS_EDITOR_STATE_H
3
4#include <cstdint>
5#include <functional>
6#include <set>
7#include <stack>
8#include <vector>
9
10#include "app/gfx/core/bitmap.h"
12#include "imgui/imgui.h"
13
14namespace yaze {
15namespace editor {
16
20enum class PixelTool {
21 kSelect, // Rectangle selection
22 kLasso, // Freeform selection
23 kPencil, // Single pixel drawing
24 kBrush, // Multi-pixel brush
25 kEraser, // Set pixels to transparent (index 0)
26 kFill, // Flood fill
27 kLine, // Line drawing
28 kRectangle, // Rectangle outline/fill
29 kEyedropper, // Color picker from canvas
30};
31
36 std::vector<uint8_t> pixel_data; // Copied pixel indices
37 gfx::SnesPalette palette; // Associated palette
38 int x = 0; // Selection origin X
39 int y = 0; // Selection origin Y
40 int width = 0; // Selection width
41 int height = 0; // Selection height
42 bool is_active = false; // Whether selection exists
43 bool is_floating = false; // Floating vs committed
44
45 void Clear() {
46 pixel_data.clear();
47 x = y = width = height = 0;
48 is_active = false;
49 is_floating = false;
50 }
51};
52
57 uint16_t sheet_id;
58 std::vector<uint8_t> pixel_data;
60
61 bool operator==(const PixelEditorSnapshot& other) const {
62 return sheet_id == other.sheet_id && pixel_data == other.pixel_data;
63 }
64};
65
75 public:
76 // --- Current Selection ---
77 uint16_t current_sheet_id = 0;
78 std::set<uint16_t> open_sheets;
79 std::set<uint16_t> selected_sheets; // Multi-select support
80
81 // --- Editing State ---
83 uint8_t current_color_index = 1; // Palette index (0 = transparent)
84 ImVec4 current_color; // RGBA for display
85 uint8_t brush_size = 1; // 1-8 pixel brush
86 bool fill_contiguous = true; // Fill tool: contiguous only
87
88 // --- View State ---
89 float zoom_level = 4.0f; // 1x to 16x
90 bool show_grid = true; // 8x8 tile grid
91 bool show_tile_boundaries = true; // 16x16 tile boundaries
92 ImVec2 pan_offset = {0, 0}; // Canvas pan offset
93
94 // --- Overlay State (for enhanced UX) ---
95 bool show_cursor_crosshair = true; // Crosshair at cursor position
96 bool show_brush_preview = true; // Preview circle for brush/eraser
97 bool show_transparency_grid = true; // Checkerboard for transparent pixels
98 bool show_pixel_info_tooltip = true; // Tooltip with pixel info on hover
99
100 // --- Palette State ---
102 uint64_t palette_index = 0;
103 uint64_t sub_palette_index = 0;
104 bool refresh_graphics = false;
105
106 // --- Selection State ---
108 ImVec2 selection_start; // Drag start point
109 bool is_selecting = false; // Currently drawing selection
110
111 // --- Undo/Redo ---
112 std::vector<PixelEditorSnapshot> undo_stack;
113 std::vector<PixelEditorSnapshot> redo_stack;
114 static constexpr size_t kMaxUndoHistory = 50;
115
116 // --- Modified Sheets Tracking ---
117 std::set<uint16_t> modified_sheets;
118
119 // --- Callbacks for cross-panel communication ---
120 std::function<void(uint16_t)> on_sheet_selected;
121 std::function<void()> on_palette_changed;
122 std::function<void()> on_tool_changed;
123 std::function<void(uint16_t)> on_sheet_modified;
124
125 // --- Methods ---
126
130 void MarkSheetModified(uint16_t sheet_id) {
131 modified_sheets.insert(sheet_id);
132 if (on_sheet_modified) {
133 on_sheet_modified(sheet_id);
134 }
135 }
136
141
145 bool HasUnsavedChanges() const { return !modified_sheets.empty(); }
146
150 void PushUndoState(uint16_t sheet_id, const std::vector<uint8_t>& pixel_data,
151 const gfx::SnesPalette& palette) {
152 // Clear redo stack on new action
153 redo_stack.clear();
154
155 // Add to undo stack
156 undo_stack.push_back({sheet_id, pixel_data, palette});
157
158 // Limit stack size
159 if (undo_stack.size() > kMaxUndoHistory) {
160 undo_stack.erase(undo_stack.begin());
161 }
162 }
163
168 if (undo_stack.empty()) return false;
169 out = undo_stack.back();
170 redo_stack.push_back(out);
171 undo_stack.pop_back();
172 return true;
173 }
174
179 if (redo_stack.empty()) return false;
180 out = redo_stack.back();
181 undo_stack.push_back(out);
182 redo_stack.pop_back();
183 return true;
184 }
185
186 bool CanUndo() const { return !undo_stack.empty(); }
187 bool CanRedo() const { return !redo_stack.empty(); }
188
192 void SelectSheet(uint16_t sheet_id) {
193 current_sheet_id = sheet_id;
194 open_sheets.insert(sheet_id);
195 if (on_sheet_selected) {
196 on_sheet_selected(sheet_id);
197 }
198 }
199
203 void CloseSheet(uint16_t sheet_id) { open_sheets.erase(sheet_id); }
204
208 void SetTool(PixelTool tool) {
209 current_tool = tool;
210 if (on_tool_changed) {
212 }
213 }
214
218 void SetZoom(float zoom) {
219 zoom_level = std::clamp(zoom, 1.0f, 16.0f);
220 }
221
222 void ZoomIn() { SetZoom(zoom_level + 1.0f); }
223 void ZoomOut() { SetZoom(zoom_level - 1.0f); }
224
228 const char* GetToolName() const {
229 switch (current_tool) {
230 case PixelTool::kSelect: return "Select";
231 case PixelTool::kLasso: return "Lasso";
232 case PixelTool::kPencil: return "Pencil";
233 case PixelTool::kBrush: return "Brush";
234 case PixelTool::kEraser: return "Eraser";
235 case PixelTool::kFill: return "Fill";
236 case PixelTool::kLine: return "Line";
237 case PixelTool::kRectangle: return "Rectangle";
238 case PixelTool::kEyedropper: return "Eyedropper";
239 default: return "Unknown";
240 }
241 }
242};
243
244} // namespace editor
245} // namespace yaze
246
247#endif // YAZE_APP_EDITOR_GRAPHICS_GRAPHICS_EDITOR_STATE_H
Shared state between GraphicsEditor panel components.
bool PopRedoState(PixelEditorSnapshot &out)
Pop and return the last redo state.
std::function< void(uint16_t)> on_sheet_modified
void MarkSheetModified(uint16_t sheet_id)
Mark a sheet as modified for save tracking.
void PushUndoState(uint16_t sheet_id, const std::vector< uint8_t > &pixel_data, const gfx::SnesPalette &palette)
Push current state to undo stack before modification.
bool PopUndoState(PixelEditorSnapshot &out)
Pop and return the last undo state.
std::vector< PixelEditorSnapshot > redo_stack
std::vector< PixelEditorSnapshot > undo_stack
void SetZoom(float zoom)
Set zoom level with clamping.
std::function< void(uint16_t)> on_sheet_selected
const char * GetToolName() const
Get tool name for status display.
bool HasUnsavedChanges() const
Check if any sheets have unsaved changes.
void SelectSheet(uint16_t sheet_id)
Select a sheet for editing.
void CloseSheet(uint16_t sheet_id)
Close a sheet tab.
void SetTool(PixelTool tool)
Set the current editing tool.
void ClearModifiedSheets()
Clear modification tracking (after save)
Represents a palette of colors for the Super Nintendo Entertainment System (SNES).
PixelTool
Pixel editing tool types for the graphics editor.
Snapshot for undo/redo operations.
bool operator==(const PixelEditorSnapshot &other) const
Selection data for copy/paste operations.
std::vector< uint8_t > pixel_data