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 <array>
5#include <cstdint>
6#include <functional>
7#include <map>
8#include <optional>
9#include <set>
10#include <string>
11#include <vector>
12
14#include "app/gfx/core/bitmap.h"
16#include "imgui/imgui.h"
17
18namespace yaze {
19namespace zelda3 {
20struct GameData;
21} // namespace zelda3
22
23namespace editor {
24
28enum class PixelTool {
29 kSelect, // Rectangle selection
30 kLasso, // Freeform selection
31 kPencil, // Single pixel drawing
32 kBrush, // Multi-pixel brush
33 kEraser, // Set pixels to transparent (index 0)
34 kFill, // Flood fill
35 kLine, // Line drawing
36 kRectangle, // Rectangle outline/fill
37 kEyedropper, // Color picker from canvas
38 kHand, // Pan the canvas
39};
40
45 std::vector<uint8_t> pixel_data; // Copied pixel indices
46 gfx::SnesPalette palette; // Associated palette
47 int x = 0; // Selection origin X
48 int y = 0; // Selection origin Y
49 int width = 0; // Selection width
50 int height = 0; // Selection height
51 bool is_active = false; // Whether selection exists
52 bool is_floating = false; // Floating vs committed
53
54 void Clear() {
55 pixel_data.clear();
56 x = y = width = height = 0;
57 is_active = false;
58 is_floating = false;
59 }
60};
61
66 uint16_t sheet_id = 0;
67 uint16_t tile_index = 0;
68 double start_time = 0.0;
69 double duration = 0.0;
70 bool active = false;
71 std::string label;
72
73 void Clear() {
74 active = false;
75 label.clear();
76 duration = 0.0;
77 start_time = 0.0;
78 }
79};
80
81// A display choice, never an authored palette or a graphics-save operation.
83 std::string group;
84 int palette = 0;
85 int row = 0;
86};
87
97 public:
98 // --- Current Selection ---
99 uint16_t current_sheet_id = 0;
100 std::set<uint16_t> open_sheets;
101 std::set<uint16_t> selected_sheets; // Multi-select support
102
103 // --- Editing State ---
105 uint8_t current_color_index = 1; // Palette index (0 = transparent)
106 uint8_t brush_size = 1; // 1-8 pixel brush
107 bool fill_contiguous = true; // Fill tool: contiguous only
108
109 // --- View State ---
110 float zoom_level = 4.0f; // 1x to 16x
111 bool show_grid = true; // 8x8 tile grid
112 bool show_pixel_grid = false; // 1-pixel grid (drawn at 6x and up)
113 bool show_tile_boundaries = true; // 16x16 tile boundaries
114 ImVec2 pan_offset = {0, 0}; // Canvas pan offset
115
116 // --- Overlay State (for enhanced UX) ---
117 bool show_cursor_crosshair = true; // Crosshair at cursor position
118 bool show_brush_preview = true; // Preview circle for brush/eraser
119 bool show_transparency_grid = true; // Checkerboard for transparent pixels
120 bool show_pixel_info_tooltip = true; // Tooltip with pixel info on hover
121
122 // No entry means the sheet's loaded colors. This editor state belongs to one
123 // session; choices survive sheet/session navigation, not a ROM replacement.
124 std::map<uint16_t, GraphicsPaletteSelection> preview_palettes;
125
126 const GraphicsPaletteSelection* PreviewPalette(uint16_t sheet) const {
127 const auto found = preview_palettes.find(sheet);
128 return found == preview_palettes.end() ? nullptr : &found->second;
129 }
130
131 // --- Selection State ---
133 ImVec2 selection_start; // Drag start point
134 bool is_selecting = false; // Currently drawing selection
135 TileHighlight tile_highlight; // Active tile focus hint
136
137 // --- Modified Sheets Tracking ---
138 std::set<uint16_t> modified_sheets;
139
140 // --- Sheet store (graphics_sheet_sync.h) ---
141 // The session whose GraphicsSheetStore holds the pixels; pixel writes go
142 // there, and the Arena's bitmaps are display copies.
144 std::optional<GraphicsEditContext> source_context;
146 // Set once when navigating to an existing pixel-editor tab.
147 std::optional<uint16_t> requested_sheet_tab;
148
150 if (!source_context || source_context->owner != game_data ||
151 source_context->selected_target >= source_context->targets.size()) {
152 return nullptr;
153 }
154 const auto& target =
155 source_context->targets[source_context->selected_target];
156 return target.sheet_id == current_sheet_id ? &target : nullptr;
157 }
158
159 void SelectSourceTarget(size_t index) {
160 if (!source_context || index >= source_context->targets.size()) {
161 return;
162 }
165 source_context->selected_target = index;
166 const auto& target = source_context->targets[index];
167 SelectSheet(target.sheet_id);
168 requested_sheet_tab = target.sheet_id;
170 HighlightTile(target.sheet_id, target.tile_index, target.label, 8.0);
171 }
172
177 // Store revision each Arena sheet was last refreshed from.
178 std::array<uint64_t, 223> arena_revisions{};
179
180 // --- Callbacks for cross-panel communication ---
181 std::function<void()> on_before_sheet_selected;
182 std::function<void(uint16_t)> on_sheet_selected;
183 std::function<void()> on_tool_changed;
184 std::function<void(uint16_t)> on_sheet_modified;
185
186 // --- Methods ---
187
191 void MarkSheetModified(uint16_t sheet_id) {
192 modified_sheets.insert(sheet_id);
193 if (on_sheet_modified) {
194 on_sheet_modified(sheet_id);
195 }
196 }
197
202
206 void ClearModifiedSheets(const std::set<uint16_t>& sheet_ids) {
207 for (auto sheet_id : sheet_ids) {
208 modified_sheets.erase(sheet_id);
209 }
210 }
211
215 bool HasUnsavedChanges() const { return !modified_sheets.empty(); }
216
220 void SelectSheet(uint16_t sheet_id) {
223 current_sheet_id = sheet_id;
224 open_sheets.insert(sheet_id);
225 if (on_sheet_selected) {
226 on_sheet_selected(sheet_id);
227 }
228 }
229
233 void HighlightTile(uint16_t sheet_id, uint16_t tile_index,
234 const std::string& label = "",
235 double duration_secs = 3.0) {
236 tile_highlight.sheet_id = sheet_id;
237 tile_highlight.tile_index = tile_index;
238 tile_highlight.label = label;
239 tile_highlight.start_time = ImGui::GetTime();
240 tile_highlight.duration = duration_secs;
241 tile_highlight.active = true;
242 }
243
247 void CloseSheet(uint16_t sheet_id) { open_sheets.erase(sheet_id); }
248
252 void SetTool(PixelTool tool) {
253 current_tool = tool;
254 if (on_tool_changed) {
256 }
257 }
258
262 void SetZoom(float zoom) { zoom_level = std::clamp(zoom, 1.0f, 16.0f); }
263
264 void ZoomIn() { SetZoom(zoom_level + 1.0f); }
265 void ZoomOut() { SetZoom(zoom_level - 1.0f); }
266
270 const char* GetToolName() const {
271 switch (current_tool) {
273 return "Select";
275 return "Lasso";
277 return "Pencil";
279 return "Brush";
281 return "Eraser";
282 case PixelTool::kFill:
283 return "Fill";
284 case PixelTool::kLine:
285 return "Line";
287 return "Rectangle";
289 return "Eyedropper";
290 case PixelTool::kHand:
291 return "Hand";
292 default:
293 return "Unknown";
294 }
295 }
296};
297
298} // namespace editor
299} // namespace yaze
300
301#endif // YAZE_APP_EDITOR_GRAPHICS_GRAPHICS_EDITOR_STATE_H
Shared state between GraphicsEditor panel components.
std::function< void(uint16_t)> on_sheet_modified
void MarkSheetModified(uint16_t sheet_id)
Mark a sheet as modified for save tracking.
std::map< uint16_t, GraphicsPaletteSelection > preview_palettes
std::optional< GraphicsEditContext > source_context
std::optional< uint16_t > requested_sheet_tab
void HighlightTile(uint16_t sheet_id, uint16_t tile_index, const std::string &label="", double duration_secs=3.0)
Highlight a tile in the current sheet for quick visual focus.
void SetZoom(float zoom)
Set zoom level with clamping.
std::function< void(uint16_t)> on_sheet_selected
std::function< void()> on_before_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.
const GraphicsEditTarget * SourceTarget() const
void SetTool(PixelTool tool)
Set the current editing tool.
void ClearModifiedSheets()
Clear modification tracking (after save)
std::array< uint64_t, 223 > arena_revisions
void ClearModifiedSheets(const std::set< uint16_t > &sheet_ids)
Clear specific sheets from modification tracking.
const GraphicsPaletteSelection * PreviewPalette(uint16_t sheet) const
Represents a palette of colors for the Super Nintendo Entertainment System (SNES).
PixelTool
Pixel editing tool types for the graphics editor.
Selection data for copy/paste operations.
std::vector< uint8_t > pixel_data
Transient highlight for focusing a tile in the pixel editor.