yaze 0.3.2
Link to the Past ROM Editor
 
Loading...
Searching...
No Matches
sheet_browser_panel.cc
Go to the documentation of this file.
2
3#include <cstdlib>
4#include <cstring>
5
6#include "absl/strings/str_format.h"
10#include "imgui/imgui.h"
11
12namespace yaze {
13namespace editor {
14
16 // Initialize with sensible defaults
17 thumbnail_scale_ = 2.0f;
18 columns_ = 2;
19}
20
21void SheetBrowserPanel::Draw(bool* p_open) {
22 // EditorPanel interface - delegate to existing Update() logic
24 ImGui::Separator();
26 ImGui::Separator();
28}
29
32 ImGui::Separator();
34 ImGui::Separator();
36 return absl::OkStatus();
37}
38
40 ImGui::Text("Search:");
41 ImGui::SameLine();
42 ImGui::SetNextItemWidth(80);
43 if (ImGui::InputText("##SheetSearch", search_buffer_, sizeof(search_buffer_),
44 ImGuiInputTextFlags_CharsHexadecimal)) {
45 // Parse hex input for sheet number
46 if (strlen(search_buffer_) > 0) {
47 int value = static_cast<int>(strtol(search_buffer_, nullptr, 16));
48 if (value >= 0 && value <= 222) {
49 state_->SelectSheet(static_cast<uint16_t>(value));
50 }
51 }
52 }
53 HOVER_HINT("Enter hex sheet number (00-DE)");
54
55 ImGui::SameLine();
56 ImGui::SetNextItemWidth(60);
57 ImGui::DragInt("##FilterMin", &filter_min_, 1.0f, 0, 222, "%02X");
58 ImGui::SameLine();
59 ImGui::Text("-");
60 ImGui::SameLine();
61 ImGui::SetNextItemWidth(60);
62 ImGui::DragInt("##FilterMax", &filter_max_, 1.0f, 0, 222, "%02X");
63
64 ImGui::SameLine();
65 ImGui::Checkbox("Modified", &show_only_modified_);
66 HOVER_HINT("Show only modified sheets");
67}
68
70 if (ImGui::Button(ICON_MD_SELECT_ALL " Select All")) {
71 for (int i = filter_min_; i <= filter_max_; i++) {
72 state_->selected_sheets.insert(static_cast<uint16_t>(i));
73 }
74 }
75 ImGui::SameLine();
76 if (ImGui::Button(ICON_MD_DESELECT " Clear")) {
77 state_->selected_sheets.clear();
78 }
79
80 if (!state_->selected_sheets.empty()) {
81 ImGui::SameLine();
82 ImGui::Text("(%zu selected)", state_->selected_sheets.size());
83 }
84
85 // Thumbnail size slider
86 ImGui::SameLine();
87 ImGui::SetNextItemWidth(100);
88 ImGui::SliderFloat("##Scale", &thumbnail_scale_, 1.0f, 4.0f, "%.1fx");
89}
90
92 ImGui::BeginChild("##SheetGridChild", ImVec2(0, 0), true,
93 ImGuiWindowFlags_AlwaysVerticalScrollbar);
94
95 auto& sheets = gfx::Arena::Get().gfx_sheets();
96
97 // Calculate thumbnail size
98 const float thumb_width = 128 * thumbnail_scale_;
99 const float thumb_height = 32 * thumbnail_scale_;
100 const float padding = 4.0f;
101
102 // Calculate columns based on available width
103 float available_width = ImGui::GetContentRegionAvail().x;
104 columns_ = std::max(
105 1, static_cast<int>(available_width / (thumb_width + padding * 2)));
106
107 int col = 0;
108 for (int i = filter_min_; i <= filter_max_ && i < zelda3::kNumGfxSheets;
109 i++) {
110 // Filter by modification state if enabled
112 state_->modified_sheets.find(static_cast<uint16_t>(i)) ==
113 state_->modified_sheets.end()) {
114 continue;
115 }
116
117 if (col > 0) {
118 ImGui::SameLine();
119 }
120
121 ImGui::PushID(i);
122 DrawSheetThumbnail(i, sheets[i]);
123 ImGui::PopID();
124
125 col++;
126 if (col >= columns_) {
127 col = 0;
128 }
129 }
130
131 ImGui::EndChild();
132}
133
135 const float thumb_width = 128 * thumbnail_scale_;
136 const float thumb_height = 32 * thumbnail_scale_;
137
138 bool is_selected =
139 state_->current_sheet_id == static_cast<uint16_t>(sheet_id);
140 bool is_multi_selected =
141 state_->selected_sheets.count(static_cast<uint16_t>(sheet_id)) > 0;
142 bool is_modified =
143 state_->modified_sheets.count(static_cast<uint16_t>(sheet_id)) > 0;
144
145 // Selection highlight
146 if (is_selected) {
147 ImGui::PushStyleColor(ImGuiCol_ChildBg, ImVec4(0.3f, 0.5f, 0.8f, 0.3f));
148 } else if (is_multi_selected) {
149 ImGui::PushStyleColor(ImGuiCol_ChildBg, ImVec4(0.5f, 0.5f, 0.2f, 0.3f));
150 }
151
152 ImGui::BeginChild(absl::StrFormat("##Sheet%02X", sheet_id).c_str(),
153 ImVec2(thumb_width + 8, thumb_height + 24), true,
154 ImGuiWindowFlags_NoScrollbar);
155
156 gui::BitmapPreviewOptions preview_opts;
157 preview_opts.canvas_size = ImVec2(thumb_width + 1, thumb_height + 1);
158 preview_opts.dest_pos = ImVec2(2, 2);
159 preview_opts.dest_size = ImVec2(thumb_width - 2, thumb_height - 2);
160 preview_opts.grid_step = 8.0f * thumbnail_scale_;
161 preview_opts.draw_context_menu = false;
162 preview_opts.ensure_texture = true;
163
164 gui::CanvasFrameOptions frame_opts;
165 frame_opts.canvas_size = preview_opts.canvas_size;
166 frame_opts.draw_context_menu = preview_opts.draw_context_menu;
167 frame_opts.draw_grid = preview_opts.draw_grid;
168 frame_opts.grid_step = preview_opts.grid_step;
169 frame_opts.draw_overlay = preview_opts.draw_overlay;
170 frame_opts.render_popups = preview_opts.render_popups;
171
172 {
173 auto rt = gui::BeginCanvas(thumbnail_canvas_, frame_opts);
174 gui::DrawBitmapPreview(rt, bitmap, preview_opts);
175
176 // Sheet label with modification indicator
177 std::string label = absl::StrFormat("%02X", sheet_id);
178 if (is_modified) {
179 label += "*";
180 }
181
182 // Draw label with background
183 ImVec2 text_pos = ImGui::GetCursorScreenPos();
184 ImVec2 text_size = ImGui::CalcTextSize(label.c_str());
186 ImVec2(2, 2), ImVec2(text_size.x + 4, text_size.y + 2),
187 is_modified ? IM_COL32(180, 100, 0, 200) : IM_COL32(0, 100, 0, 180));
188
189 thumbnail_canvas_.AddTextAt(ImVec2(4, 2), label,
190 is_modified ? IM_COL32(255, 200, 100, 255)
191 : IM_COL32(150, 255, 150, 255));
192 gui::EndCanvas(thumbnail_canvas_, rt, frame_opts);
193 }
194
195 // Click handling
196 if (ImGui::IsItemClicked(ImGuiMouseButton_Left)) {
197 if (ImGui::GetIO().KeyCtrl) {
198 // Ctrl+click for multi-select
199 if (is_multi_selected) {
200 state_->selected_sheets.erase(static_cast<uint16_t>(sheet_id));
201 } else {
202 state_->selected_sheets.insert(static_cast<uint16_t>(sheet_id));
203 }
204 } else {
205 // Normal click to select
206 state_->SelectSheet(static_cast<uint16_t>(sheet_id));
207 }
208 }
209
210 // Double-click to open in new tab
211 if (ImGui::IsItemHovered() &&
212 ImGui::IsMouseDoubleClicked(ImGuiMouseButton_Left)) {
213 state_->open_sheets.insert(static_cast<uint16_t>(sheet_id));
214 }
215
216 ImGui::EndChild();
217
218 if (is_selected || is_multi_selected) {
219 ImGui::PopStyleColor();
220 }
221
222 // Tooltip with sheet info
223 if (ImGui::IsItemHovered()) {
224 ImGui::BeginTooltip();
225 ImGui::Text("Sheet: 0x%02X (%d)", sheet_id, sheet_id);
226 if (bitmap.is_active()) {
227 ImGui::Text("Size: %dx%d", bitmap.width(), bitmap.height());
228 ImGui::Text("Depth: %d bpp", bitmap.depth());
229 } else {
230 ImGui::Text("(Inactive)");
231 }
232 if (is_modified) {
233 ImGui::TextColored(ImVec4(1.0f, 0.6f, 0.2f, 1.0f), "Modified");
234 }
235 ImGui::EndTooltip();
236 }
237}
238
239} // namespace editor
240} // namespace yaze
void SelectSheet(uint16_t sheet_id)
Select a sheet for editing.
void DrawBatchOperations()
Draw batch operation buttons.
void Draw(bool *p_open) override
Draw the sheet browser UI.
void DrawSearchBar()
Draw the search/filter bar.
void Initialize()
Initialize the panel.
void DrawSheetThumbnail(int sheet_id, gfx::Bitmap &bitmap)
Draw a single sheet thumbnail.
void DrawSheetGrid()
Draw the sheet grid view.
absl::Status Update()
Legacy Update method for backward compatibility.
std::array< gfx::Bitmap, 223 > & gfx_sheets()
Get reference to all graphics sheets.
Definition arena.h:102
static Arena & Get()
Definition arena.cc:20
Represents a bitmap image optimized for SNES ROM hacking.
Definition bitmap.h:67
bool is_active() const
Definition bitmap.h:384
int height() const
Definition bitmap.h:374
int width() const
Definition bitmap.h:373
int depth() const
Definition bitmap.h:375
void AddTextAt(ImVec2 local_pos, const std::string &text, uint32_t color)
Definition canvas.cc:2425
void AddRectFilledAt(ImVec2 local_top_left, ImVec2 size, uint32_t color)
Definition canvas.cc:2416
#define ICON_MD_SELECT_ALL
Definition icons.h:1680
#define ICON_MD_DESELECT
Definition icons.h:540
#define HOVER_HINT(string)
Definition macro.h:24
void EndCanvas(Canvas &canvas)
Definition canvas.cc:1509
void DrawBitmapPreview(const CanvasRuntime &rt, gfx::Bitmap &bitmap, const BitmapPreviewOptions &options)
Definition canvas.cc:2135
void BeginCanvas(Canvas &canvas, ImVec2 child_size)
Definition canvas.cc:1486
constexpr uint32_t kNumGfxSheets
Definition game_data.h:25
std::optional< float > grid_step
Definition canvas.h:90
std::optional< float > grid_step
Definition canvas.h:70