3#include "absl/strings/str_format.h"
9#include "imgui/imgui.h"
16 : state_(state), rom_(rom) {}
28 ImGui::TextColored(ImVec4(1.0f, 0.3f, 0.3f, 1.0f),
29 "Failed to load Link sheets: %s",
30 status.message().data());
39 float panel_width = ImGui::GetContentRegionAvail().x;
40 float grid_width = std::min(300.0f, panel_width * 0.4f);
43 ImGui::BeginChild(
"##LinkSheetGrid", ImVec2(grid_width, 0),
true);
50 ImGui::BeginChild(
"##LinkPreviewArea", ImVec2(0, 0),
true);
64 ImGui::TextColored(ImVec4(1.0f, 0.3f, 0.3f, 1.0f),
65 "Failed to load Link sheets: %s",
66 status.message().data());
75 float panel_width = ImGui::GetContentRegionAvail().x;
76 float grid_width = std::min(300.0f, panel_width * 0.4f);
79 ImGui::BeginChild(
"##LinkSheetGrid", ImVec2(grid_width, 0),
true);
86 ImGui::BeginChild(
"##LinkPreviewArea", ImVec2(0, 0),
true);
94 return absl::OkStatus();
101 HOVER_HINT(
"Import a .zspr Link sprite file");
107 HOVER_HINT(
"Reset Link graphics to vanilla ROM data");
112 ImGui::TextColored(ImVec4(0.5f, 1.0f, 0.5f, 1.0f),
120 ImGui::TextColored(ImVec4(1.0f, 0.6f, 0.2f, 1.0f),
"[Unsaved]");
125 ImGui::Text(
"Link Sheets (14)");
153 ImGui::PushStyleColor(ImGuiCol_ChildBg, ImVec4(0.3f, 0.5f, 0.8f, 0.4f));
156 ImGui::BeginChild(absl::StrFormat(
"##LinkSheet%d", sheet_index).c_str(),
159 true, ImGuiWindowFlags_NoScrollbar);
163 if (sheet.is_active()) {
165 if (!sheet.texture() && sheet.surface()) {
171 if (sheet.texture()) {
172 ImVec2 cursor_pos = ImGui::GetCursorScreenPos();
173 ImGui::GetWindowDrawList()->AddImage(
174 (ImTextureID)(intptr_t)sheet.texture(),
182 if (ImGui::IsWindowHovered() && ImGui::IsMouseClicked(ImGuiMouseButton_Left)) {
187 if (ImGui::IsWindowHovered() && ImGui::IsMouseDoubleClicked(ImGuiMouseButton_Left)) {
192 ImGui::SetCursorPosY(ImGui::GetCursorPosY() +
kThumbnailSize / 4 + 2);
193 ImGui::Text(
"%d", sheet_index);
198 ImGui::PopStyleColor();
202 if (ImGui::IsItemHovered()) {
203 ImGui::BeginTooltip();
204 ImGui::Text(
"Link Sheet %d", sheet_index);
205 ImGui::Text(
"Double-click to edit");
214 float canvas_width = ImGui::GetContentRegionAvail().x - 16;
215 float canvas_height = canvas_width / 4;
218 const float grid_step = 8.0f * (canvas_width / 128.0f);
221 frame_opts.
canvas_size = ImVec2(canvas_width, canvas_height);
229 if (sheet.is_active() && sheet.texture()) {
232 draw_opts.
dest_size = ImVec2(canvas_width, canvas_height);
243 if (ImGui::Button(
ICON_MD_EDIT " Open in Pixel Editor")) {
246 HOVER_HINT(
"Open this sheet in the main pixel editor");
250 ImGui::SetNextItemWidth(100);
251 ImGui::SliderFloat(
"Zoom", &
preview_zoom_, 1.0f, 8.0f,
"%.1fx");
255 ImGui::Text(
"Display Palette:");
258 const char* palette_names[] = {
"Green Mail",
"Blue Mail",
"Red Mail",
"Bunny"};
261 ImGui::SetNextItemWidth(120);
262 if (ImGui::Combo(
"##PaletteSelect", ¤t, palette_names, 4)) {
266 HOVER_HINT(
"Change the display palette for preview");
270 ImGui::Text(
"Info:");
271 ImGui::BulletText(
"896 total tiles (8x8 each)");
272 ImGui::BulletText(
"14 graphics sheets");
273 ImGui::BulletText(
"4BPP format");
277 ImGui::Text(
"Loaded ZSPR:");
278 ImGui::BulletText(
"Name: %s",
loaded_zspr_->metadata.display_name.c_str());
279 ImGui::BulletText(
"Author: %s",
loaded_zspr_->metadata.author.c_str());
280 ImGui::BulletText(
"Tiles: %zu",
loaded_zspr_->tile_count());
287 if (file_path.empty()) {
291 LOG_INFO(
"LinkSpritePanel",
"Importing ZSPR: %s", file_path.c_str());
295 if (!zspr_result.ok()) {
296 LOG_ERROR(
"LinkSpritePanel",
"Failed to load ZSPR: %s",
297 zspr_result.status().message().data());
305 LOG_ERROR(
"LinkSpritePanel",
"ZSPR is not a Link sprite (type=%d)",
315 LOG_ERROR(
"LinkSpritePanel",
"Failed to apply ZSPR to ROM: %s",
316 status.message().data());
323 LOG_WARN(
"LinkSpritePanel",
"Failed to apply ZSPR palette: %s",
324 status.message().data());
331 LOG_INFO(
"LinkSpritePanel",
"ZSPR '%s' imported successfully",
340 LOG_WARN(
"LinkSpritePanel",
"Reset to vanilla not yet implemented");
350 LOG_INFO(
"LinkSpritePanel",
"Request to open Link sheet %d in pixel editor",
359 return absl::FailedPreconditionError(
"ROM not loaded");
365 return result.status();
376 return absl::OkStatus();
411 if (default_palette.
empty()) {
413 default_palette.
Resize(16);
426 palette = &default_palette;
430 if (sheet.is_active() && sheet.surface()) {
432 sheet.SetPaletteWithTransparent(*palette, 0);
440 LOG_INFO(
"LinkSpritePanel",
"Applied palette %s to %zu sheets",
450 default:
return "Unknown";
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.
static constexpr float kThumbnailPadding
PaletteType
Link sprite palette types.
bool has_unsaved_changes_
absl::Status LoadLinkSheets()
Load Link graphics sheets from ROM.
void Draw(bool *p_open) override
Draw the panel UI (EditorPanel interface)
void Initialize()
Initialize the panel and load Link sheets.
PaletteType selected_palette_
void OpenSheetInPixelEditor()
Open selected sheet in the main pixel editor.
absl::Status Update()
Legacy Update method for backward compatibility.
std::optional< gfx::ZsprData > loaded_zspr_
void ApplySelectedPalette()
Apply the selected palette to Link sheets for display.
void ImportZspr()
Handle ZSPR file import.
void DrawSheetGrid()
Draw the 4x4 sheet selection grid.
static constexpr int kNumLinkSheets
void DrawPreviewCanvas()
Draw the preview canvas for selected sheet.
void DrawInfoPanel()
Draw info panel with stats.
gui::Canvas preview_canvas_
static const char * GetPaletteName(PaletteType type)
Get the name of a palette type.
void DrawPaletteSelector()
Draw the palette selector dropdown.
std::array< gfx::Bitmap, kNumLinkSheets > link_sheets_
LinkSpritePanel(GraphicsEditorState *state, Rom *rom)
void DrawToolbar()
Draw the toolbar with Import/Reset buttons.
void ResetToVanilla()
Reset Link sheets to vanilla ROM data.
void DrawSheetThumbnail(int sheet_index)
Draw a single Link sheet thumbnail.
static constexpr float kThumbnailSize
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 std::string ShowOpenFileDialog()
ShowOpenFileDialog opens a file dialog and returns the selected filepath. Uses global feature flag to...
#define ICON_MD_FILE_UPLOAD
#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