4#include "absl/strings/str_format.h"
11#include "imgui/imgui.h"
20 : state_(state), rom_(rom) {}
34 tr(
"Failed to load Link sheets: %s"),
35 status.message().data());
44 float panel_width = ImGui::GetContentRegionAvail().x;
45 float grid_width = std::min(300.0f, panel_width * 0.4f);
48 ImGui::BeginChild(
"##LinkSheetGrid", ImVec2(grid_width, 0),
true);
55 ImGui::BeginChild(
"##LinkPreviewArea", ImVec2(0, 0),
true);
70 tr(
"Failed to load Link sheets: %s"),
71 status.message().data());
80 float panel_width = ImGui::GetContentRegionAvail().x;
81 float grid_width = std::min(300.0f, panel_width * 0.4f);
84 ImGui::BeginChild(
"##LinkSheetGrid", ImVec2(grid_width, 0),
true);
91 ImGui::BeginChild(
"##LinkPreviewArea", ImVec2(0, 0),
true);
99 return absl::OkStatus();
106 HOVER_HINT(
"Import a .zspr Link sprite file");
112 HOVER_HINT(
"Reset Link graphics to vanilla ROM data");
130 ImGui::Text(tr(
"Link Sheets (14)"));
157 std::optional<gui::StyleColorGuard> sel_bg_guard;
159 sel_bg_guard.emplace(ImGuiCol_ChildBg, ImVec4(0.3f, 0.5f, 0.8f, 0.4f));
162 ImGui::BeginChild(absl::StrFormat(
"##LinkSheet%d", sheet_index).c_str(),
165 true, ImGuiWindowFlags_NoScrollbar);
169 if (sheet.is_active()) {
171 if (!sheet.texture() && sheet.surface()) {
177 if (sheet.texture()) {
178 ImVec2 cursor_pos = ImGui::GetCursorScreenPos();
179 ImGui::GetWindowDrawList()->AddImage(
180 (ImTextureID)(intptr_t)sheet.texture(), cursor_pos,
187 if (ImGui::IsWindowHovered() &&
188 ImGui::IsMouseClicked(ImGuiMouseButton_Left)) {
193 if (ImGui::IsWindowHovered() &&
194 ImGui::IsMouseDoubleClicked(ImGuiMouseButton_Left)) {
199 ImGui::SetCursorPosY(ImGui::GetCursorPosY() +
kThumbnailSize / 4 + 2);
200 ImGui::Text(
"%d", sheet_index);
204 sel_bg_guard.reset();
207 if (ImGui::IsItemHovered()) {
208 ImGui::BeginTooltip();
209 ImGui::Text(tr(
"Link Sheet %d"), sheet_index);
210 ImGui::Text(tr(
"Double-click to edit"));
219 float canvas_width = ImGui::GetContentRegionAvail().x - 16;
220 float canvas_height = canvas_width / 4;
223 const float grid_step = 8.0f * (canvas_width / 128.0f);
226 frame_opts.
canvas_size = ImVec2(canvas_width, canvas_height);
235 if (sheet.is_active() && sheet.texture()) {
238 draw_opts.
dest_size = ImVec2(canvas_width, canvas_height);
249 if (ImGui::Button(
ICON_MD_EDIT " Open in Pixel Editor")) {
252 HOVER_HINT(
"Open this sheet in the main pixel editor");
257 ImGui::SliderFloat(tr(
"Zoom"), &
preview_zoom_, 1.0f, 8.0f,
"%.1fx");
261 ImGui::Text(tr(
"Display Palette:"));
264 const char* palette_names[] = {
"Green Mail",
"Blue Mail",
"Red Mail",
269 if (ImGui::Combo(
"##PaletteSelect", ¤t, palette_names, 4)) {
273 HOVER_HINT(
"Change the display palette for preview");
277 ImGui::Text(tr(
"Info:"));
278 ImGui::BulletText(tr(
"896 total tiles (8x8 each)"));
279 ImGui::BulletText(tr(
"14 graphics sheets"));
280 ImGui::BulletText(tr(
"4BPP format"));
284 ImGui::Text(tr(
"Loaded ZSPR:"));
285 ImGui::BulletText(tr(
"Name: %s"),
287 ImGui::BulletText(tr(
"Author: %s"),
loaded_zspr_->metadata.author.c_str());
288 ImGui::BulletText(tr(
"Tiles: %zu"),
loaded_zspr_->tile_count());
295 if (file_path.empty()) {
299 LOG_INFO(
"LinkSpriteView",
"Importing ZSPR: %s", file_path.c_str());
303 if (!zspr_result.ok()) {
304 LOG_ERROR(
"LinkSpriteView",
"Failed to load ZSPR: %s",
305 zspr_result.status().message().data());
313 LOG_ERROR(
"LinkSpriteView",
"ZSPR is not a Link sprite (type=%d)",
323 LOG_ERROR(
"LinkSpriteView",
"Failed to apply ZSPR to ROM: %s",
324 status.message().data());
331 LOG_WARN(
"LinkSpriteView",
"Failed to apply ZSPR palette: %s",
332 status.message().data());
339 LOG_INFO(
"LinkSpriteView",
"ZSPR '%s' imported successfully",
348 LOG_WARN(
"LinkSpriteView",
"Reset to vanilla not yet implemented");
358 LOG_INFO(
"LinkSpriteView",
"Request to open Link sheet %d in pixel editor",
367 return absl::FailedPreconditionError(
"ROM not loaded");
373 return result.status();
379 LOG_INFO(
"LinkSpriteView",
"Loaded %d Link graphics sheets",
385 return absl::OkStatus();
421 if (default_palette.
empty()) {
423 default_palette.
Resize(16);
436 palette = &default_palette;
440 if (sheet.is_active() && sheet.surface()) {
442 sheet.SetPaletteWithTransparent(*palette, 0);
450 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)
CanvasConfig & GetConfig()
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=2, float scale=1.0f)
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