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 "app/gui/core/style.h"
13#include "imgui/imgui.h"
14
15namespace yaze {
16namespace editor {
17
19 // Initialize with sensible defaults
20 thumbnail_scale_ = 2.0f;
21 columns_ = 2;
22}
23
24void SheetBrowserPanel::Draw(bool* p_open) {
25 // EditorPanel interface - delegate to existing Update() logic
27 ImGui::Separator();
29 ImGui::Separator();
31}
32
35 ImGui::Separator();
37 ImGui::Separator();
39 return absl::OkStatus();
40}
41
43 ImGui::Text("Search:");
44 ImGui::SameLine();
45 ImGui::SetNextItemWidth(gui::LayoutHelpers::GetHexInputWidth());
46 if (ImGui::InputText("##SheetSearch", search_buffer_, sizeof(search_buffer_),
47 ImGuiInputTextFlags_CharsHexadecimal)) {
48 // Parse hex input for sheet number
49 if (strlen(search_buffer_) > 0) {
50 int value = static_cast<int>(strtol(search_buffer_, nullptr, 16));
51 if (value >= 0 && value <= 222) {
52 state_->SelectSheet(static_cast<uint16_t>(value));
53 }
54 }
55 }
56 HOVER_HINT("Enter hex sheet number (00-DE)");
57
58 ImGui::SameLine();
59 ImGui::SetNextItemWidth(gui::LayoutHelpers::GetCompactInputWidth());
60 ImGui::DragInt("##FilterMin", &filter_min_, 1.0f, 0, 222, "%02X");
61 ImGui::SameLine();
62 ImGui::Text("-");
63 ImGui::SameLine();
64 ImGui::SetNextItemWidth(gui::LayoutHelpers::GetCompactInputWidth());
65 ImGui::DragInt("##FilterMax", &filter_max_, 1.0f, 0, 222, "%02X");
66
67 ImGui::SameLine();
68 ImGui::Checkbox("Modified", &show_only_modified_);
69 HOVER_HINT("Show only modified sheets");
70}
71
73 if (ImGui::Button(ICON_MD_SELECT_ALL " Select All")) {
74 for (int i = filter_min_; i <= filter_max_; i++) {
75 state_->selected_sheets.insert(static_cast<uint16_t>(i));
76 }
77 }
78 ImGui::SameLine();
79 if (ImGui::Button(ICON_MD_DESELECT " Clear")) {
80 state_->selected_sheets.clear();
81 }
82
83 if (!state_->selected_sheets.empty()) {
84 ImGui::SameLine();
85 ImGui::Text("(%zu selected)", state_->selected_sheets.size());
86 }
87
88 // Thumbnail size slider
89 ImGui::SameLine();
90 ImGui::SetNextItemWidth(gui::LayoutHelpers::GetSliderWidth());
91 ImGui::SliderFloat("##Scale", &thumbnail_scale_, 1.0f, 4.0f, "%.1fx");
92}
93
95 ImGui::BeginChild("##SheetGridChild", ImVec2(0, 0), true,
96 ImGuiWindowFlags_AlwaysVerticalScrollbar);
97
98 auto& sheets = gfx::Arena::Get().gfx_sheets();
99
100 // Calculate thumbnail size
101 const float thumb_width = 128 * thumbnail_scale_;
102 const float thumb_height = 32 * thumbnail_scale_;
103 const float padding = 4.0f;
104
105 // Calculate columns based on available width
106 float available_width = ImGui::GetContentRegionAvail().x;
107 columns_ = std::max(
108 1, static_cast<int>(available_width / (thumb_width + padding * 2)));
109
110 int col = 0;
111 for (int i = filter_min_; i <= filter_max_ && i < zelda3::kNumGfxSheets;
112 i++) {
113 // Filter by modification state if enabled
115 state_->modified_sheets.find(static_cast<uint16_t>(i)) ==
116 state_->modified_sheets.end()) {
117 continue;
118 }
119
120 if (col > 0) {
121 ImGui::SameLine();
122 }
123
124 ImGui::PushID(i);
125 DrawSheetThumbnail(i, sheets[i]);
126 ImGui::PopID();
127
128 col++;
129 if (col >= columns_) {
130 col = 0;
131 }
132 }
133
134 ImGui::EndChild();
135}
136
138 const float thumb_width = 128 * thumbnail_scale_;
139 const float thumb_height = 32 * thumbnail_scale_;
140
141 bool is_selected =
142 state_->current_sheet_id == static_cast<uint16_t>(sheet_id);
143 bool is_multi_selected =
144 state_->selected_sheets.count(static_cast<uint16_t>(sheet_id)) > 0;
145 bool is_modified =
146 state_->modified_sheets.count(static_cast<uint16_t>(sheet_id)) > 0;
147
148 // Selection highlight
149 std::optional<gui::StyleColorGuard> sel_bg_guard;
150 if (is_selected) {
151 ImVec4 sel_bg = gui::GetSelectedColor();
152 sel_bg.w = 0.3f;
153 sel_bg_guard.emplace(ImGuiCol_ChildBg, sel_bg);
154 } else if (is_multi_selected) {
155 ImVec4 multi_bg = gui::GetModifiedColor();
156 multi_bg.w = 0.3f;
157 sel_bg_guard.emplace(ImGuiCol_ChildBg, multi_bg);
158 }
159
160 ImGui::BeginChild(absl::StrFormat("##Sheet%02X", sheet_id).c_str(),
161 ImVec2(thumb_width + 8, thumb_height + 24), true,
162 ImGuiWindowFlags_NoScrollbar);
163
164 gui::BitmapPreviewOptions preview_opts;
165 preview_opts.canvas_size = ImVec2(thumb_width + 1, thumb_height + 1);
166 preview_opts.dest_pos = ImVec2(2, 2);
167 preview_opts.dest_size = ImVec2(thumb_width - 2, thumb_height - 2);
168 preview_opts.grid_step = 8.0f * thumbnail_scale_;
169 preview_opts.draw_context_menu = false;
170 preview_opts.ensure_texture = true;
171
172 gui::CanvasFrameOptions frame_opts;
173 frame_opts.canvas_size = preview_opts.canvas_size;
174 frame_opts.draw_context_menu = preview_opts.draw_context_menu;
175 frame_opts.draw_grid = preview_opts.draw_grid;
176 frame_opts.grid_step = preview_opts.grid_step;
177 frame_opts.draw_overlay = preview_opts.draw_overlay;
178 frame_opts.render_popups = preview_opts.render_popups;
179
180 {
181 auto rt = gui::BeginCanvas(thumbnail_canvas_, frame_opts);
182 gui::DrawBitmapPreview(rt, bitmap, preview_opts);
183
184 // Sheet label with modification indicator
185 std::string label = absl::StrFormat("%02X", sheet_id);
186 if (is_modified) {
187 label += "*";
188 }
189
190 // Draw label with background
191 ImVec2 text_pos = ImGui::GetCursorScreenPos();
192 ImVec2 text_size = ImGui::CalcTextSize(label.c_str());
194 ImVec2(2, 2), ImVec2(text_size.x + 4, text_size.y + 2),
195 is_modified ? IM_COL32(180, 100, 0, 200) : IM_COL32(0, 100, 0, 180));
196
197 thumbnail_canvas_.AddTextAt(ImVec2(4, 2), label,
198 is_modified ? IM_COL32(255, 200, 100, 255)
199 : IM_COL32(150, 255, 150, 255));
200 gui::EndCanvas(thumbnail_canvas_, rt, frame_opts);
201 }
202
203 // Click handling
204 if (ImGui::IsItemClicked(ImGuiMouseButton_Left)) {
205 if (ImGui::GetIO().KeyCtrl) {
206 // Ctrl+click for multi-select
207 if (is_multi_selected) {
208 state_->selected_sheets.erase(static_cast<uint16_t>(sheet_id));
209 } else {
210 state_->selected_sheets.insert(static_cast<uint16_t>(sheet_id));
211 }
212 } else {
213 // Normal click to select
214 state_->SelectSheet(static_cast<uint16_t>(sheet_id));
215 }
216 }
217
218 // Double-click to open in new tab
219 if (ImGui::IsItemHovered() &&
220 ImGui::IsMouseDoubleClicked(ImGuiMouseButton_Left)) {
221 state_->open_sheets.insert(static_cast<uint16_t>(sheet_id));
222 }
223
224 ImGui::EndChild();
225
226 sel_bg_guard.reset();
227
228 // Tooltip with sheet info
229 if (ImGui::IsItemHovered()) {
230 ImGui::BeginTooltip();
231 ImGui::Text("Sheet: 0x%02X (%d)", sheet_id, sheet_id);
232 if (bitmap.is_active()) {
233 ImGui::Text("Size: %dx%d", bitmap.width(), bitmap.height());
234 ImGui::Text("Depth: %d bpp", bitmap.depth());
235 } else {
236 ImGui::Text("(Inactive)");
237 }
238 if (is_modified) {
239 ImGui::TextColored(gui::GetModifiedColor(), "Modified");
240 }
241 ImGui::EndTooltip();
242 }
243}
244
245} // namespace editor
246} // 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:152
static Arena & Get()
Definition arena.cc:21
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:2507
void AddRectFilledAt(ImVec2 local_top_left, ImVec2 size, uint32_t color)
Definition canvas.cc:2498
static float GetHexInputWidth()
static float GetSliderWidth()
static float GetCompactInputWidth()
#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:1591
void DrawBitmapPreview(const CanvasRuntime &rt, gfx::Bitmap &bitmap, const BitmapPreviewOptions &options)
Definition canvas.cc:2217
void BeginCanvas(Canvas &canvas, ImVec2 child_size)
Definition canvas.cc:1568
ImVec4 GetSelectedColor()
Definition ui_helpers.cc:98
ImVec4 GetModifiedColor()
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