diff --git a/aniphallow.lua b/aniphallow.lua index f71d7bf..134ce58 100644 --- a/aniphallow.lua +++ b/aniphallow.lua @@ -37,7 +37,8 @@ local S = { tileW = DEFAULT_TILE_W, tileH = DEFAULT_TILE_H, animSpeed = DEFAULT_ANIM_SPEED, - previewZoom = DEFAULT_PREVIEW_ZOOM, + previewZoomAll = DEFAULT_PREVIEW_ZOOM, + previewZoomOne = DEFAULT_PREVIEW_ZOOM, sourceZoom = DEFAULT_SOURCE_ZOOM, animFrame = 0, currentAnim = 1, -- index into animNames @@ -192,7 +193,14 @@ local function loadPrefs() if k == "tileW" then S.tileW = tonumber(v) or DEFAULT_TILE_W end if k == "tileH" then S.tileH = tonumber(v) or DEFAULT_TILE_H end if k == "animSpeed" then S.animSpeed = tonumber(v) or DEFAULT_ANIM_SPEED end - if k == "previewZoom" then S.previewZoom = tonumber(v) or DEFAULT_PREVIEW_ZOOM end + if k == "previewZoom" then + -- Legacy: load into both + local pz = tonumber(v) or DEFAULT_PREVIEW_ZOOM + S.previewZoomAll = pz + S.previewZoomOne = pz + end + if k == "previewZoomAll" then S.previewZoomAll = tonumber(v) or DEFAULT_PREVIEW_ZOOM end + if k == "previewZoomOne" then S.previewZoomOne = tonumber(v) or DEFAULT_PREVIEW_ZOOM end if k == "sourceZoom" then S.sourceZoom = tonumber(v) or DEFAULT_SOURCE_ZOOM end -- Legacy: currentAnim as index (for migration) if k == "currentAnim" then S.currentAnim = tonumber(v) or 1 end @@ -284,7 +292,8 @@ local function savePrefs() f:write("tileW=" .. S.tileW .. "\n") f:write("tileH=" .. S.tileH .. "\n") f:write("animSpeed=" .. S.animSpeed .. "\n") - f:write("previewZoom=" .. S.previewZoom .. "\n") + f:write("previewZoomAll=" .. S.previewZoomAll .. "\n") + f:write("previewZoomOne=" .. S.previewZoomOne .. "\n") f:write("sourceZoom=" .. S.sourceZoom .. "\n") -- Save current animation name for robust resolution after sort local curName = "" @@ -445,6 +454,12 @@ local function getPreviewGrid(numAnims) end end +-- Get current preview zoom based on mode +local function pvZoom() + if S.previewMode == "single" then return S.previewZoomOne end + return S.previewZoomAll +end + ---------------------------------------------------------------------- -- Module-level refreshSource ---------------------------------------------------------------------- @@ -982,12 +997,13 @@ openPreviewWindow = function() -- calcPreviewSize helper local function calcPreviewSize() - local ptw = S.tileW * S.previewZoom - local pth = S.tileH * S.previewZoom + local z = pvZoom() + local ptw = S.tileW * z + local pth = S.tileH * z local cellW = ptw + PV_MARGIN * 2 local cellH = pth + PV_MARGIN * 2 if S.previewMode == "single" then - return cellW, cellH + return cellW, cellH + 14 -- extra space for name label else local numAnims = #S.animNames local cols, rows = getPreviewGrid(numAnims) @@ -1010,7 +1026,6 @@ openPreviewWindow = function() previewDlg = nil S.previewWindowOpen = false savePrefs() - -- Update main dialog button if open if mainDlg then pcall(function() mainDlg:modify{ id = "tabPreview", text = " Preview " } end) end @@ -1027,11 +1042,10 @@ openPreviewWindow = function() previewDlg:button{ id = "pvToggleMode", - text = S.previewMode == "all" and "Single" or "Show All", + text = S.previewMode == "all" and "Show One" or "Show All", onclick = function() if S.previewMode == "all" then S.previewMode = "single" - -- Clamp if #S.animNames > 0 then if S.previewSingleIdx < 1 then S.previewSingleIdx = 1 end if S.previewSingleIdx > #S.animNames then S.previewSingleIdx = #S.animNames end @@ -1039,18 +1053,20 @@ openPreviewWindow = function() previewDlg:modify{ id = "pvToggleMode", text = "Show All" } previewDlg:modify{ id = "pvPrev", visible = true } previewDlg:modify{ id = "pvNext", visible = true } + previewDlg:modify{ id = "pvAnimName", visible = true } else S.previewMode = "all" - previewDlg:modify{ id = "pvToggleMode", text = "Single" } + previewDlg:modify{ id = "pvToggleMode", text = "Show One" } previewDlg:modify{ id = "pvPrev", visible = false } previewDlg:modify{ id = "pvNext", visible = false } + previewDlg:modify{ id = "pvAnimName", visible = false } end - -- Resize canvas to fit new content - local pw, ph = calcPreviewSize() - previewDlg:modify{ id = "pvCanvas", width = math.max(pw, 120), height = math.max(ph, 40) } previewDlg:repaint() end } + + -- Navigation buttons on a new row, only in single mode + previewDlg:newrow() previewDlg:button{ id = "pvPrev", text = "<-", @@ -1059,6 +1075,10 @@ openPreviewWindow = function() if #S.animNames > 0 then S.previewSingleIdx = S.previewSingleIdx - 1 if S.previewSingleIdx < 1 then S.previewSingleIdx = #S.animNames end + -- Update name label + pcall(function() + previewDlg:modify{ id = "pvAnimName", text = S.animNames[S.previewSingleIdx] or "" } + end) previewDlg:repaint() end end @@ -1071,6 +1091,9 @@ openPreviewWindow = function() if #S.animNames > 0 then S.previewSingleIdx = S.previewSingleIdx + 1 if S.previewSingleIdx > #S.animNames then S.previewSingleIdx = 1 end + pcall(function() + previewDlg:modify{ id = "pvAnimName", text = S.animNames[S.previewSingleIdx] or "" } + end) previewDlg:repaint() end end @@ -1086,31 +1109,29 @@ openPreviewWindow = function() local na = #S.animNames if na == 0 then return end - local pw = S.tileW * S.previewZoom - local ph = S.tileH * S.previewZoom + local z = pvZoom() + local pw = S.tileW * z + local ph = S.tileH * z local cW = pw + PV_MARGIN * 2 local cH = ph + PV_MARGIN * 2 local af = pvAnimFrame.value - if S.previewMode == "single" and S.previewSingleIdx >= 1 and S.previewSingleIdx <= #S.animNames then - -- Single mode: draw only one animation centered + if S.previewMode == "single" and S.previewSingleIdx >= 1 and S.previewSingleIdx <= na then local name = S.animNames[S.previewSingleIdx] local frames = S.anims[name] or {} - -- Draw background if S.useBgColor then gc.color = S.bgColor gc:fillRect(Rectangle(PV_MARGIN, PV_MARGIN, pw, ph)) else - drawCheckerboard(gc, pw, ph, S.previewZoom, PV_MARGIN, PV_MARGIN) + drawCheckerboard(gc, pw, ph, z, PV_MARGIN, PV_MARGIN) end - -- Draw frame with offset local totalFrames = #frames if totalFrames > 0 then local idx = (af % totalFrames) + 1 local fimg = getFrameImageGlobal(name, idx) local f = frames[idx] - local offX = (f.offX or 0) * S.previewZoom - local offY = (f.offY or 0) * S.previewZoom + local offX = (f.offX or 0) * z + local offY = (f.offY or 0) * z if fimg then gc:drawImage(fimg, Rectangle(0, 0, S.tileW, S.tileH), @@ -1118,9 +1139,7 @@ openPreviewWindow = function() end end else - -- All mode: draw all animations using grid local cols, rows = getPreviewGrid(na) - for i, name in ipairs(S.animNames) do local col = (i - 1) % cols local row = math.floor((i - 1) / cols) @@ -1131,7 +1150,7 @@ openPreviewWindow = function() gc.color = S.bgColor gc:fillRect(Rectangle(ox + PV_MARGIN, oy + PV_MARGIN, pw, ph)) else - drawCheckerboard(gc, pw, ph, S.previewZoom, + drawCheckerboard(gc, pw, ph, z, ox + PV_MARGIN, oy + PV_MARGIN) end @@ -1142,13 +1161,11 @@ openPreviewWindow = function() local fimg = getFrameImageGlobal(name, idx) if fimg then local f = frames[idx] - local fOffX = (f.offX or 0) * S.previewZoom - local fOffY = (f.offY or 0) * S.previewZoom - gc:drawImage( - fimg, + local fOffX = (f.offX or 0) * z + local fOffY = (f.offY or 0) * z + gc:drawImage(fimg, Rectangle(0, 0, S.tileW, S.tileH), - Rectangle(ox + PV_MARGIN + fOffX, oy + PV_MARGIN + fOffY, pw, ph) - ) + Rectangle(ox + PV_MARGIN + fOffX, oy + PV_MARGIN + fOffY, pw, ph)) end end end @@ -1156,13 +1173,38 @@ openPreviewWindow = function() end, onwheel = function(ev) local dz = ev.deltaY < 0 and 1 or -1 - S.previewZoom = math.max(1, math.min(MAX_PREVIEW_ZOOM, S.previewZoom + dz)) - local pw, ph = calcPreviewSize() - previewDlg:modify{ id = "pvCanvas", width = math.max(pw, 120), height = math.max(ph, 40) } + if S.previewMode == "single" then + S.previewZoomOne = math.max(1, math.min(MAX_PREVIEW_ZOOM, S.previewZoomOne + dz)) + else + S.previewZoomAll = math.max(1, math.min(MAX_PREVIEW_ZOOM, S.previewZoomAll + dz)) + end previewDlg:repaint() end } + -- Animation name label (only in single mode) + local singleName = "" + if S.previewSingleIdx >= 1 and S.previewSingleIdx <= #S.animNames then + singleName = S.animNames[S.previewSingleIdx] + end + previewDlg:label{ + id = "pvAnimName", + text = singleName, + visible = (S.previewMode == "single") + } + + -- Adjust button: re-fits window to content by closing and reopening + previewDlg:newrow() + previewDlg:button{ + id = "pvAdjust", + text = "Adjust", + onclick = function() + -- Close and reopen to refit + pcall(function() previewDlg:close() end) + openPreviewWindow() + end + } + previewTimer = Timer{ interval = S.animSpeed / 1000.0, ontick = function()