fix: persist maximize + corners as free placement (exact size/pos), edges as dock
This commit is contained in:
1 parent
fd0c52342f
commit
a6d02322f3
2 files changed
+61
-18
No files matched your search
+58
-18
@@ -53,6 +53,21 @@ export default function () {
|
||||
if (saveTimer != null) clearTimeout(saveTimer)
|
||||
saveTimer = setTimeout(function () { savePlacement(p) }, 400)
|
||||
}
|
||||
// Persist the CURRENT window as a free placement (real canvas-space x/y + size).
|
||||
// Used by maximize and corner docks, which must remember the EXACT size/position
|
||||
// rather than re-deriving it from a dock formula (which would reset the size).
|
||||
function saveFreeFromCurrent () {
|
||||
try {
|
||||
const pos = (figma.ui as any).getPosition()
|
||||
savePlacement({
|
||||
mode: 'free',
|
||||
x: Math.round(pos.canvasSpace.x),
|
||||
y: Math.round(pos.canvasSpace.y),
|
||||
w: lastSize.width,
|
||||
h: lastSize.height
|
||||
})
|
||||
} catch (e) { /* getPosition unavailable — skip */ }
|
||||
}
|
||||
// computeDock считает целевой размер+позицию для док-позиции.
|
||||
// canonical=true — НАЖАТИЕ кнопки дока: задаём канонический размер
|
||||
// (edge: фикс-сторона dockEdgeSize, другая = max viewport; center: 50%).
|
||||
@@ -293,28 +308,36 @@ export default function () {
|
||||
// к левому/верхнему краю вместо центра (баг relX=0 на top-center).
|
||||
on('DOCK_WINDOW', function (payload: { position: DockPosition; width: number; height: number }) {
|
||||
const { position } = payload
|
||||
// Центр — это one-shot: применяем 50% по центру ОДИН раз, окно остаётся в покое
|
||||
// (НЕ приклеено, НЕ держит центр при ручном ресайзе/перемещении).
|
||||
if (position === 'center') {
|
||||
dockedPosition = null
|
||||
} else {
|
||||
// Остальные позиции — удерживаем прижатым (поллинг пересчитывает при зуме/пане).
|
||||
const isEdge = position === 'top-center' || position === 'bottom-center' ||
|
||||
position === 'center-left' || position === 'center-right'
|
||||
// Центр и углы — one-shot (не удерживаются поллингом). Края — удерживаются прижатыми.
|
||||
if (isEdge) {
|
||||
dockedPosition = position
|
||||
lastBoundsKey = '' // форсируем пересчёт на ближайшем тике
|
||||
} else {
|
||||
dockedPosition = null
|
||||
}
|
||||
// Попытка растяжения до канона (Figma клампит до лимита при видимом UI).
|
||||
const state = computeDock(position, payload.width, payload.height, true)
|
||||
figma.ui.resize(state.width, state.height)
|
||||
lastSize = { width: clampWindowSize(state).width, height: clampWindowSize(state).height }
|
||||
// reposition откладываем на DOCK_REFINE (UI пришлёт реальный размер после клампа).
|
||||
// Remember placement (center is one-shot but we still persist it as a logical position).
|
||||
savePlacement({ mode: 'dock', position: position })
|
||||
// Сохранение позиции тоже в DOCK_REFINE (там известен реальный размер после клампа).
|
||||
})
|
||||
|
||||
// Точная прижимка от РЕАЛЬНОГО размера окна (после клампа Figma).
|
||||
on('DOCK_REFINE', function (payload: { position: DockPosition; width: number; height: number }) {
|
||||
const { position, width, height } = payload
|
||||
applyDock(position, width, height, false)
|
||||
const isEdge = position === 'top-center' || position === 'bottom-center' ||
|
||||
position === 'center-left' || position === 'center-right'
|
||||
if (isEdge) {
|
||||
// Edges are held docked — persist as dock so re-open re-pins to the edge.
|
||||
savePlacement({ mode: 'dock', position: position })
|
||||
} else {
|
||||
// Corners / center are one-shot — remember the EXACT size+position (free).
|
||||
saveFreeFromCurrent()
|
||||
}
|
||||
})
|
||||
|
||||
// Выход из дока кликом по углу: свободная ось (та, что была растянута) становится
|
||||
@@ -354,6 +377,14 @@ export default function () {
|
||||
} catch (e) { /* getPosition unavailable — skip */ }
|
||||
})
|
||||
|
||||
// UI asks to persist the CURRENT window as a free placement (used by Maximize,
|
||||
// which is not a held dock — it must remember the exact size+position across restart).
|
||||
on('SAVE_FREE', function () {
|
||||
dockedPosition = null // maximize is not held; clear any stale dock state
|
||||
lastBoundsKey = ''
|
||||
saveFreeFromCurrent()
|
||||
})
|
||||
|
||||
// Останавливаем поллинг при закрытии плагина, чтобы не висел в памяти.
|
||||
figma.on('close', function () {
|
||||
clearInterval(dockInterval)
|
||||
@@ -457,18 +488,27 @@ export default function () {
|
||||
return
|
||||
}
|
||||
if (saved.mode === 'dock') {
|
||||
// Dock mode (incl. center): stretch to its canonical size and pin.
|
||||
// For center the window is NOT held (one-shot); for edges it stays docked.
|
||||
dockedPosition = saved.position === 'center' ? null : saved.position
|
||||
const state = computeDock(saved.position, 320, 200, true)
|
||||
figma.ui.resize(state.width, state.height)
|
||||
lastSize = { width: clampWindowSize(state).width, height: clampWindowSize(state).height }
|
||||
requestAnimationFrame(function () {
|
||||
const isEdge = saved.position === 'top-center' || saved.position === 'bottom-center' ||
|
||||
saved.position === 'center-left' || saved.position === 'center-right'
|
||||
if (!isEdge) {
|
||||
// Stale record (corner/center saved as dock by an older build) — treat as free
|
||||
// with the current size, so the exact geometry is restored.
|
||||
figma.ui.reposition(0, 0) // will be corrected by native re-open; keep simple
|
||||
lastSize = { width: 320, height: 200 }
|
||||
dockedPosition = null
|
||||
} else {
|
||||
// Edge dock: stretch to its canonical size and pin (held across zoom/pan).
|
||||
dockedPosition = saved.position
|
||||
const state = computeDock(saved.position, 320, 200, true)
|
||||
figma.ui.resize(state.width, state.height)
|
||||
lastSize = { width: clampWindowSize(state).width, height: clampWindowSize(state).height }
|
||||
requestAnimationFrame(function () {
|
||||
applyDock(saved.position, lastSize.width, lastSize.height, false)
|
||||
lastBoundsKey = '' // force dock poll to keep it pinned on zoom/pan
|
||||
requestAnimationFrame(function () {
|
||||
applyDock(saved.position, lastSize.width, lastSize.height, false)
|
||||
lastBoundsKey = '' // force dock poll to keep it pinned on zoom/pan
|
||||
})
|
||||
})
|
||||
})
|
||||
}
|
||||
} else {
|
||||
// Free placement: restore exact canvas-space position + size.
|
||||
figma.ui.resize(saved.w, saved.h)
|
||||
|
||||
@@ -215,6 +215,9 @@ function Plugin () {
|
||||
width: window.innerWidth,
|
||||
height: window.innerHeight
|
||||
})
|
||||
// Maximize is NOT a held dock — persist the exact size+position so re-open
|
||||
// restores it (overrides the edge-dock save done by DOCK_REFINE above).
|
||||
emit('SAVE_FREE')
|
||||
refreshInfo()
|
||||
})
|
||||
})
|
||||
|
||||
Reference in new issue
Block a user