3#include "absl/strings/str_format.h"
10#include "imgui/imgui.h"
19 : state_(state), rom_(rom) {}
33 status.message().data());
42 float panel_width = ImGui::GetContentRegionAvail().x;
43 float grid_width = std::min(300.0f, panel_width * 0.4f);
46 ImGui::BeginChild(
"##LinkSheetGrid", ImVec2(grid_width, 0),
true);
53 ImGui::BeginChild(
"##LinkPreviewArea", ImVec2(0, 0),
true);
68 status.message().data());
77 float panel_width = ImGui::GetContentRegionAvail().x;
78 float grid_width = std::min(300.0f, panel_width * 0.4f);
81 ImGui::BeginChild(
"##LinkSheetGrid", ImVec2(grid_width, 0),
true);
88 ImGui::BeginChild(
"##LinkPreviewArea", ImVec2(0, 0),
true);
96 return absl::OkStatus();
103 HOVER_HINT(
"Import a .zspr Link sprite file");
109 HOVER_HINT(
"Reset Link graphics to vanilla ROM data");
127 ImGui::Text(
"Link Sheets (14)");
154 std::optional<gui::StyleColorGuard> sel_bg_guard;
156 sel_bg_guard.emplace(ImGuiCol_ChildBg, ImVec4(0.3f, 0.5f, 0.8f, 0.4f));
159 ImGui::BeginChild(absl::StrFormat(
"##LinkSheet%d", sheet_index).c_str(),
162 true, ImGuiWindowFlags_NoScrollbar);
166 if (sheet.is_active()) {
168 if (!sheet.texture() && sheet.surface()) {
174 if (sheet.texture()) {
175 ImVec2 cursor_pos = ImGui::GetCursorScreenPos();
176 ImGui::GetWindowDrawList()->AddImage(
177 (ImTextureID)(intptr_t)sheet.texture(), cursor_pos,
184 if (ImGui::IsWindowHovered() &&
185 ImGui::IsMouseClicked(ImGuiMouseButton_Left)) {
190 if (ImGui::IsWindowHovered() &&
191 ImGui::IsMouseDoubleClicked(ImGuiMouseButton_Left)) {
196 ImGui::SetCursorPosY(ImGui::GetCursorPosY() +
kThumbnailSize / 4 + 2);
197 ImGui::Text(
"%d", sheet_index);
201 sel_bg_guard.reset();
204 if (ImGui::IsItemHovered()) {
205 ImGui::BeginTooltip();
206 ImGui::Text(
"Link Sheet %d", sheet_index);
207 ImGui::Text(
"Double-click to edit");
216 float canvas_width = ImGui::GetContentRegionAvail().x - 16;
217 float canvas_height = canvas_width / 4;
220 const float grid_step = 8.0f * (canvas_width / 128.0f);
223 frame_opts.
canvas_size = ImVec2(canvas_width, canvas_height);
231 if (sheet.is_active() && sheet.texture()) {
234 draw_opts.
dest_size = ImVec2(canvas_width, canvas_height);
245 if (ImGui::Button(
ICON_MD_EDIT " Open in Pixel Editor")) {
248 HOVER_HINT(
"Open this sheet in the main pixel editor");
253 ImGui::SliderFloat(
"Zoom", &
preview_zoom_, 1.0f, 8.0f,
"%.1fx");
257 ImGui::Text(
"Display Palette:");
260 const char* palette_names[] = {
"Green Mail",
"Blue Mail",
"Red Mail",
265 if (ImGui::Combo(
"##PaletteSelect", ¤t, palette_names, 4)) {
269 HOVER_HINT(
"Change the display palette for preview");
273 ImGui::Text(
"Info:");
274 ImGui::BulletText(
"896 total tiles (8x8 each)");
275 ImGui::BulletText(
"14 graphics sheets");
276 ImGui::BulletText(
"4BPP format");
280 ImGui::Text(
"Loaded ZSPR:");
281 ImGui::BulletText(
"Name: %s",
loaded_zspr_->metadata.display_name.c_str());
282 ImGui::BulletText(
"Author: %s",
loaded_zspr_->metadata.author.c_str());
283 ImGui::BulletText(
"Tiles: %zu",
loaded_zspr_->tile_count());
290 if (file_path.empty()) {
294 LOG_INFO(
"LinkSpriteView",
"Importing ZSPR: %s", file_path.c_str());
298 if (!zspr_result.ok()) {
299 LOG_ERROR(
"LinkSpriteView",
"Failed to load ZSPR: %s",
300 zspr_result.status().message().data());
308 LOG_ERROR(
"LinkSpriteView",
"ZSPR is not a Link sprite (type=%d)",
318 LOG_ERROR(
"LinkSpriteView",
"Failed to apply ZSPR to ROM: %s",
319 status.message().data());
326 LOG_WARN(
"LinkSpriteView",
"Failed to apply ZSPR palette: %s",
327 status.message().data());
334 LOG_INFO(
"LinkSpriteView",
"ZSPR '%s' imported successfully",
343 LOG_WARN(
"LinkSpriteView",
"Reset to vanilla not yet implemented");
353 LOG_INFO(
"LinkSpriteView",
"Request to open Link sheet %d in pixel editor",
362 return absl::FailedPreconditionError(
"ROM not loaded");
368 return result.status();
374 LOG_INFO(
"LinkSpriteView",
"Loaded %d Link graphics sheets",
380 return absl::OkStatus();
416 if (default_palette.
empty()) {
418 default_palette.
Resize(16);
431 palette = &default_palette;
435 if (sheet.is_active() && sheet.surface()) {
437 sheet.SetPaletteWithTransparent(*palette, 0);
445 LOG_INFO(
"LinkSpriteView",
"Applied palette %s to %zu sheets",
The Rom class is used to load, save, and modify Rom data. This is a generic SNES ROM container and do...
Shared state between GraphicsEditor panel components.
void ApplySelectedPalette()
Apply the selected palette to Link sheets for display.
void ResetToVanilla()
Reset Link sheets to vanilla ROM data.
static constexpr float kThumbnailPadding
static const char * GetPaletteName(PaletteType type)
Get the name of a palette type.
std::array< gfx::Bitmap, kNumLinkSheets > link_sheets_
void Draw(bool *p_open) override
Draw the view UI (WindowContent interface)
LinkSpriteView(GraphicsEditorState *state, Rom *rom)
bool has_unsaved_changes_
void DrawPreviewCanvas()
Draw the preview canvas for selected sheet.
gui::Canvas preview_canvas_
void DrawPaletteSelector()
Draw the palette selector dropdown.
void ImportZspr()
Handle ZSPR file import.
std::optional< gfx::ZsprData > loaded_zspr_
PaletteType selected_palette_
absl::Status LoadLinkSheets()
Load Link graphics sheets from ROM.
void DrawSheetGrid()
Draw the 4x4 sheet selection grid.
void Initialize()
Initialize the view and load Link sheets.
void DrawToolbar()
Draw the toolbar with Import/Reset buttons.
void DrawSheetThumbnail(int sheet_index)
Draw a single Link sheet thumbnail.
void DrawInfoPanel()
Draw info panel with stats.
void OpenSheetInPixelEditor()
Open selected sheet in the main pixel editor.
static constexpr float kThumbnailSize
PaletteType
Link sprite palette types.
static constexpr int kNumLinkSheets
absl::Status Update()
Legacy Update method for backward compatibility.
void QueueTextureCommand(TextureCommandType type, Bitmap *bitmap)
Represents a bitmap image optimized for SNES ROM hacking.
Represents a palette of colors for the Super Nintendo Entertainment System (SNES).
static absl::Status ApplyToRom(Rom &rom, const ZsprData &zspr)
Apply loaded ZSPR sprite data to ROM's Link graphics.
static absl::Status ApplyPaletteToRom(Rom &rom, const ZsprData &zspr)
Apply ZSPR palette data to ROM.
static absl::StatusOr< ZsprData > LoadFromFile(const std::string &path)
Load ZSPR data from a file path.
void SetCanvasSize(ImVec2 canvas_size)
static float GetSliderWidth()
static float GetComboWidth()
static std::string ShowOpenFileDialog()
ShowOpenFileDialog opens a file dialog and returns the selected filepath. Uses global feature flag to...
#define ICON_MD_FILE_UPLOAD
#define ICON_MD_CHECK_CIRCLE
#define LOG_ERROR(category, format,...)
#define LOG_WARN(category, format,...)
#define LOG_INFO(category, format,...)
#define HOVER_HINT(string)
void EndCanvas(Canvas &canvas)
void BeginCanvas(Canvas &canvas, ImVec2 child_size)
void DrawBitmap(const CanvasRuntime &rt, gfx::Bitmap &bitmap, int border_offset, float scale)
absl::StatusOr< std::array< gfx::Bitmap, kNumLinkSheets > > LoadLinkGraphics(const Rom &rom)
Loads Link's graphics sheets from ROM.
constexpr uint32_t kNumLinkSheets
std::optional< float > grid_step