Resize fra nord/vest: juster posisjon slik at motstående kant forblir fast

Når man drar toppen eller venstre kant av et panel, ble bare størrelsen
endret mens posisjon sto fast — som ga inntrykk av at feil kant beveget
seg. Nå beregner BlockShell posisjons-delta (dx, dy) og parent justerer
x/y tilsvarende, slik at den kanten du drar i følger musepekeren.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
vegard 2026-03-19 05:52:00 +00:00
parent da88bfcb1f
commit b8be448908
4 changed files with 31 additions and 11 deletions

View file

@ -230,10 +230,16 @@
if (resizeDir.includes('n')) newH = resizeStartH - dy; if (resizeDir.includes('n')) newH = resizeStartH - dy;
// Clamp // Clamp
newW = Math.min(constraints.maxWidth, Math.max(constraints.minWidth, newW)); const clampedW = Math.min(constraints.maxWidth, Math.max(constraints.minWidth, newW));
newH = Math.min(constraints.maxHeight, Math.max(constraints.minHeight, newH)); const clampedH = Math.min(constraints.maxHeight, Math.max(constraints.minHeight, newH));
onResize?.(newW, newH); // Position delta for n/w dragging: move origin to keep the opposite edge fixed
let posDx = 0;
let posDy = 0;
if (resizeDir.includes('w')) posDx = resizeStartW - clampedW;
if (resizeDir.includes('n')) posDy = resizeStartH - clampedH;
onResize?.(clampedW, clampedH, posDx, posDy);
} }
function handleResizeEnd() { function handleResizeEnd() {

View file

@ -70,8 +70,8 @@ export interface BlockShellEvents {
onClose?: () => void; onClose?: () => void;
/** Panel drag-moved (delta in world coords) */ /** Panel drag-moved (delta in world coords) */
onDragMove?: (dx: number, dy: number) => void; onDragMove?: (dx: number, dy: number) => void;
/** Panel resized */ /** Panel resized. dx/dy are position offsets for n/w edge dragging. */
onResize?: (width: number, height: number) => void; onResize?: (width: number, height: number, dx?: number, dy?: number) => void;
/** Panel fullscreen state changed */ /** Panel fullscreen state changed */
onFullscreenChange?: (isFullscreen: boolean) => void; onFullscreenChange?: (isFullscreen: boolean) => void;
/** Panel minimize state changed (double-click header to toggle) */ /** Panel minimize state changed (double-click header to toggle) */

View file

@ -165,10 +165,17 @@
} }
} }
function handlePanelResize(trait: string, width: number, height: number) { function handlePanelResize(trait: string, width: number, height: number, dx?: number, dy?: number) {
const idx = layout.panels.findIndex(p => p.trait === trait); const idx = layout.panels.findIndex(p => p.trait === trait);
if (idx >= 0) { if (idx >= 0) {
layout.panels[idx] = { ...layout.panels[idx], width, height }; const panel = layout.panels[idx];
layout.panels[idx] = {
...panel,
width,
height,
x: panel.x + (dx ?? 0),
y: panel.y + (dy ?? 0),
};
layout = { ...layout }; layout = { ...layout };
persistLayout(); persistLayout();
} }
@ -783,7 +790,7 @@
height={panel?.height ?? obj.height} height={panel?.height ?? obj.height}
minimized={panel?.minimized ?? false} minimized={panel?.minimized ?? false}
receiver={getReceiverForTrait(trait)} receiver={getReceiverForTrait(trait)}
onResize={(w, h) => handlePanelResize(trait, w, h)} onResize={(w, h, dx, dy) => handlePanelResize(trait, w, h, dx, dy)}
onClose={() => handlePanelClose(trait)} onClose={() => handlePanelClose(trait)}
onMinimizeChange={(m) => handlePanelMinimize(trait, m)} onMinimizeChange={(m) => handlePanelMinimize(trait, m)}
onDrop={(payload, shiftKey) => handlePanelDrop(trait, payload, shiftKey)} onDrop={(payload, shiftKey) => handlePanelDrop(trait, payload, shiftKey)}

View file

@ -182,10 +182,17 @@
} }
/** Handle panel resize via BlockShell */ /** Handle panel resize via BlockShell */
function handlePanelResize(trait: string, width: number, height: number) { function handlePanelResize(trait: string, width: number, height: number, dx?: number, dy?: number) {
const idx = layout.panels.findIndex(p => p.trait === trait); const idx = layout.panels.findIndex(p => p.trait === trait);
if (idx >= 0) { if (idx >= 0) {
layout.panels[idx] = { ...layout.panels[idx], width, height }; const panel = layout.panels[idx];
layout.panels[idx] = {
...panel,
width,
height,
x: panel.x + (dx ?? 0),
y: panel.y + (dy ?? 0),
};
layout = { ...layout }; layout = { ...layout };
persistLayout(); persistLayout();
} }
@ -386,7 +393,7 @@
width={panel?.width ?? obj.width} width={panel?.width ?? obj.width}
height={panel?.height ?? obj.height} height={panel?.height ?? obj.height}
minimized={panel?.minimized ?? false} minimized={panel?.minimized ?? false}
onResize={(w, h) => handlePanelResize(trait, w, h)} onResize={(w, h, dx, dy) => handlePanelResize(trait, w, h, dx, dy)}
onClose={() => handlePanelClose(trait)} onClose={() => handlePanelClose(trait)}
onMinimizeChange={(m) => handlePanelMinimize(trait, m)} onMinimizeChange={(m) => handlePanelMinimize(trait, m)}
> >