@witchcraft/layout 0.4.3 → 0.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/module.json +1 -1
- package/dist/runtime/components/FrameDragHandle.vue +3 -3
- package/dist/runtime/components/LayoutDragEdgeGrabbed.vue +3 -3
- package/dist/runtime/components/LayoutDragEdgeHandle.d.vue.ts +2 -2
- package/dist/runtime/components/LayoutDragEdgeHandle.vue +2 -2
- package/dist/runtime/components/LayoutDragEdgeHandle.vue.d.ts +2 -2
- package/dist/runtime/components/LayoutDragEdges.vue +5 -5
- package/dist/runtime/components/LayoutEdgesActiveFrame.vue +2 -2
- package/dist/runtime/components/LayoutFrame.vue +2 -2
- package/dist/runtime/components/LayoutIntersectionHandle.d.vue.ts +2 -2
- package/dist/runtime/components/LayoutIntersectionHandle.vue +2 -2
- package/dist/runtime/components/LayoutIntersectionHandle.vue.d.ts +2 -2
- package/dist/runtime/components/LayoutIntersections.vue +4 -4
- package/dist/runtime/components/LayoutWindow.d.vue.ts +54 -45
- package/dist/runtime/components/LayoutWindow.vue +29 -29
- package/dist/runtime/components/LayoutWindow.vue.d.ts +54 -45
- package/dist/runtime/composables/useFrames.d.ts +142 -129
- package/dist/runtime/composables/useFrames.js +122 -94
- package/dist/runtime/demo/App.vue +16 -16
- package/dist/runtime/demo/DemoControls.d.vue.ts +2 -2
- package/dist/runtime/demo/DemoControls.vue +4 -4
- package/dist/runtime/demo/DemoControls.vue.d.ts +2 -2
- package/dist/runtime/demo/tailwind.css +1 -1
- package/dist/runtime/helpers/createZoneSideClipPath.d.ts +2 -2
- package/dist/runtime/helpers/findEdgesTouchingWindow.d.ts +7 -0
- package/dist/runtime/helpers/findEdgesTouchingWindow.js +20 -0
- package/dist/runtime/helpers/{findFrameDraggableEdges.d.ts → findFrameMoveableEdges.d.ts} +2 -2
- package/dist/runtime/helpers/{findFrameDraggableEdges.js → findFrameMoveableEdges.js} +3 -3
- package/dist/runtime/helpers/{findDraggableEdge.d.ts → findMoveableEdge.d.ts} +1 -1
- package/dist/runtime/helpers/{findDraggableEdge.js → findMoveableEdge.js} +1 -1
- package/dist/runtime/helpers/index.d.ts +10 -3
- package/dist/runtime/helpers/index.js +10 -3
- package/dist/runtime/layout/createSplitDecoFromDrag.d.ts +1 -1
- package/dist/runtime/layout/createSplitDecoFromDrag.js +2 -2
- package/dist/runtime/layout/debugFrame.js +5 -1
- package/dist/runtime/layout/findSafeSplitEdge.d.ts +1 -1
- package/dist/runtime/layout/findSafeSplitEdge.js +2 -2
- package/dist/runtime/layout/getCloseFrameInfo.js +4 -4
- package/dist/runtime/layout/getFrameCollapseInfo.d.ts +1 -1
- package/dist/runtime/layout/getFrameCollapseInfo.js +9 -29
- package/dist/runtime/layout/getFrameDockInfo.d.ts +1 -1
- package/dist/runtime/layout/getFrameDockInfo.js +61 -44
- package/dist/runtime/layout/getFrameExpandInfo.d.ts +11 -0
- package/dist/runtime/layout/getFrameExpandInfo.js +49 -0
- package/dist/runtime/layout/getFrameRearrangeInfo.d.ts +2 -2
- package/dist/runtime/layout/getFrameRearrangeInfo.js +8 -8
- package/dist/runtime/layout/getFrameShrinkInfo.d.ts +14 -0
- package/dist/runtime/layout/getFrameShrinkInfo.js +48 -0
- package/dist/runtime/layout/getFrameSplitInfo.d.ts +1 -1
- package/dist/runtime/layout/getFrameSplitInfo.js +2 -2
- package/dist/runtime/layout/getFrameUncollapseInfo.d.ts +1 -1
- package/dist/runtime/layout/getFrameUncollapseInfo.js +6 -20
- package/dist/runtime/layout/{getFrameDragZones.d.ts → getFrameZones.d.ts} +3 -3
- package/dist/runtime/layout/{getFrameDragZones.js → getFrameZones.js} +1 -1
- package/dist/runtime/layout/getUpdateWindowSizeInfo.js +10 -12
- package/dist/runtime/layout/{getWindowDragZones.d.ts → getWindowZones.d.ts} +1 -1
- package/dist/runtime/layout/{getWindowDragZones.js → getWindowZones.js} +1 -1
- package/dist/runtime/layout/getZones.d.ts +8 -0
- package/dist/runtime/layout/getZones.js +32 -0
- package/dist/runtime/layout/index.d.ts +6 -3
- package/dist/runtime/layout/index.js +6 -3
- package/dist/runtime/{drag/DragActionHandler.d.ts → move/ActionHandler.d.ts} +18 -18
- package/dist/runtime/{drag/DragActionHandler.js → move/ActionHandler.js} +19 -19
- package/dist/runtime/{drag → move}/CloseAction.d.ts +8 -8
- package/dist/runtime/{drag → move}/CloseAction.js +29 -26
- package/dist/runtime/{drag → move}/FrameDragAction.d.ts +8 -8
- package/dist/runtime/{drag → move}/FrameDragAction.js +23 -21
- package/dist/runtime/{drag/DragDirectionStore.d.ts → move/MoveDirectionStore.d.ts} +4 -4
- package/dist/runtime/{drag/DragDirectionStore.js → move/MoveDirectionStore.js} +9 -9
- package/dist/runtime/{drag → move}/SplitAction.d.ts +9 -9
- package/dist/runtime/{drag → move}/SplitAction.js +46 -43
- package/dist/runtime/{drag → move}/createDefaultHandlers.d.ts +2 -2
- package/dist/runtime/types/index.d.ts +242 -158
- package/dist/runtime/types/index.js +4 -3
- package/dist/runtime/types/vue.d.ts +25 -18
- package/dist/runtime/types/vue.js +1 -1
- package/package.json +3 -2
- package/src/runtime/components/FrameDragHandle.vue +3 -3
- package/src/runtime/components/LayoutDragEdgeGrabbed.vue +3 -3
- package/src/runtime/components/LayoutDragEdgeHandle.vue +4 -4
- package/src/runtime/components/LayoutDragEdges.vue +5 -5
- package/src/runtime/components/LayoutEdgesActiveFrame.vue +2 -2
- package/src/runtime/components/LayoutFrame.vue +2 -2
- package/src/runtime/components/LayoutIntersectionHandle.vue +4 -4
- package/src/runtime/components/LayoutIntersections.vue +4 -4
- package/src/runtime/components/LayoutWindow.vue +35 -35
- package/src/runtime/composables/useFrames.ts +141 -121
- package/src/runtime/demo/App.vue +18 -18
- package/src/runtime/demo/DemoControls.vue +5 -5
- package/src/runtime/demo/tailwind.css +4 -0
- package/src/runtime/helpers/createZoneSideClipPath.ts +2 -2
- package/src/runtime/helpers/findEdgesTouchingWindow.ts +30 -0
- package/src/runtime/helpers/{findFrameDraggableEdges.ts → findFrameMoveableEdges.ts} +4 -4
- package/src/runtime/helpers/{findDraggableEdge.ts → findMoveableEdge.ts} +1 -1
- package/src/runtime/helpers/index.ts +10 -3
- package/src/runtime/layout/createSplitDecoFromDrag.ts +2 -2
- package/src/runtime/layout/debugFrame.ts +6 -1
- package/src/runtime/layout/findSafeSplitEdge.ts +4 -4
- package/src/runtime/layout/getCloseFrameInfo.ts +4 -4
- package/src/runtime/layout/getFrameCollapseInfo.ts +12 -41
- package/src/runtime/layout/getFrameDockInfo.ts +77 -57
- package/src/runtime/layout/getFrameExpandInfo.ts +84 -0
- package/src/runtime/layout/getFrameRearrangeInfo.ts +10 -10
- package/src/runtime/layout/getFrameShrinkInfo.ts +87 -0
- package/src/runtime/layout/getFrameSplitInfo.ts +5 -5
- package/src/runtime/layout/getFrameUncollapseInfo.ts +8 -30
- package/src/runtime/layout/{getFrameDragZones.ts → getFrameZones.ts} +4 -4
- package/src/runtime/layout/getUpdateWindowSizeInfo.ts +16 -22
- package/src/runtime/layout/{getWindowDragZones.ts → getWindowZones.ts} +1 -1
- package/src/runtime/layout/getZones.ts +48 -0
- package/src/runtime/layout/index.ts +6 -3
- package/src/runtime/{drag/DragActionHandler.ts → move/ActionHandler.ts} +44 -42
- package/src/runtime/{drag → move}/CloseAction.ts +39 -36
- package/src/runtime/{drag → move}/FrameDragAction.ts +36 -35
- package/src/runtime/{drag/DragDirectionStore.ts → move/MoveDirectionStore.ts} +10 -10
- package/src/runtime/{drag → move}/SplitAction.ts +56 -53
- package/src/runtime/{drag/defaultDragActions.ts → move/createDefaultHandlers.ts} +2 -2
- package/src/runtime/types/index.ts +104 -55
- package/src/runtime/types/vue.ts +18 -16
- package/dist/runtime/drag/defaultDragActions.d.ts +0 -9
- package/dist/runtime/drag/defaultDragActions.js +0 -10
- package/dist/runtime/layout/getDragZones.d.ts +0 -8
- package/dist/runtime/layout/getDragZones.js +0 -32
- package/src/runtime/drag/createDefaultHandlers.ts +0 -20
- package/src/runtime/layout/getDragZones.ts +0 -48
- /package/dist/runtime/{drag → move}/createDefaultHandlers.js +0 -0
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { Zone } from "../types/index.js";
|
|
2
2
|
/**
|
|
3
3
|
* Returns frame drag zones (in **unrounded** scaled coordinate space).
|
|
4
4
|
*
|
|
@@ -8,9 +8,9 @@ import type { DragZone } from "../types/index.js";
|
|
|
8
8
|
*
|
|
9
9
|
* Unrounded because these are for display purposes only.
|
|
10
10
|
*/
|
|
11
|
-
export declare function
|
|
11
|
+
export declare function getFrameZones(frame: {
|
|
12
12
|
x: number;
|
|
13
13
|
y: number;
|
|
14
14
|
width: number;
|
|
15
15
|
height: number;
|
|
16
|
-
}, thresholdPx: number, windowPxWidth: number, windowPxHeight: number):
|
|
16
|
+
}, thresholdPx: number, windowPxWidth: number, windowPxHeight: number): Zone[];
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { settings } from "../settings.js";
|
|
2
|
-
export function
|
|
2
|
+
export function getFrameZones(frame, thresholdPx, windowPxWidth, windowPxHeight) {
|
|
3
3
|
const thX = thresholdPx / windowPxWidth * settings.maxInt;
|
|
4
4
|
const thY = thresholdPx / windowPxHeight * settings.maxInt;
|
|
5
5
|
const pxWidth = frame.width / settings.maxInt * windowPxWidth;
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { pushIfNotIn } from "@alanscodelog/utils/pushIfNotIn";
|
|
2
2
|
import { walk } from "@alanscodelog/utils/walk";
|
|
3
3
|
import { applyFrameChanges } from "../layout/applyFrameChanges.js";
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
4
|
+
import { getFrameExpandInfo } from "../layout/getFrameExpandInfo.js";
|
|
5
|
+
import { getFrameShrinkInfo } from "../layout/getFrameShrinkInfo.js";
|
|
6
6
|
import { getRelaxFramesInfo } from "../layout/getRelaxFramesInfo.js";
|
|
7
7
|
import { settings } from "../settings.js";
|
|
8
8
|
import { KnownError } from "../utils/KnownError.js";
|
|
@@ -30,23 +30,21 @@ export function getUpdateWindowSizeInfo(win, event, { relaxPasses = 2 } = {}) {
|
|
|
30
30
|
const targetScaled = Math.round(targetPxSize / (orientation === "horizontal" ? win.pxWidth : win.pxHeight) * maxInt);
|
|
31
31
|
if (frame[sizeKey] === targetScaled) continue;
|
|
32
32
|
if (frame[sizeKey] === 0) continue;
|
|
33
|
+
const side = frame.docked;
|
|
34
|
+
const diff = targetScaled - frame[sizeKey];
|
|
33
35
|
let result;
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
settings.minSize = 1;
|
|
37
|
-
if (targetScaled < frame[sizeKey]) {
|
|
38
|
-
frame.collapsed = void 0;
|
|
39
|
-
result = getFrameCollapseInfo(win, frame.id, { collapseSizeScaled: { width: targetScaled, height: targetScaled } });
|
|
36
|
+
if (diff < 0) {
|
|
37
|
+
result = getFrameShrinkInfo(win, frame.id, -diff, side, { allowOutOfBounds: true });
|
|
40
38
|
} else {
|
|
41
|
-
|
|
42
|
-
|
|
39
|
+
const wasMinSize = { ...settings.minSize };
|
|
40
|
+
settings.minSize = 1;
|
|
41
|
+
result = getFrameExpandInfo(win, frame.id, diff, side);
|
|
42
|
+
settings.minSize = wasMinSize;
|
|
43
43
|
}
|
|
44
44
|
if (!(result instanceof KnownError)) {
|
|
45
45
|
applyFrameChanges(win, result);
|
|
46
46
|
pushIfNotIn(toExtract, result.modified.map((f) => f.id));
|
|
47
47
|
}
|
|
48
|
-
frame.collapsed = wasCollapsed;
|
|
49
|
-
settings.minSize = wasMinSize;
|
|
50
48
|
const result2 = getRelaxFramesInfo(win, relaxPasses);
|
|
51
49
|
if (!(result2 instanceof KnownError)) {
|
|
52
50
|
applyFrameChanges(win, result2);
|
|
@@ -3,4 +3,4 @@ import type { LayoutWindow, WindowEdgeZone } from "../types/index.js";
|
|
|
3
3
|
* Returns window edge drag zones (in scaled coordinates)
|
|
4
4
|
*
|
|
5
5
|
*/
|
|
6
|
-
export declare function
|
|
6
|
+
export declare function getWindowZones(win: LayoutWindow, thresholdPx: number): WindowEdgeZone[];
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { numberToScaledPercent } from "../helpers/numberToScaledPercent.js";
|
|
2
2
|
import { settings } from "../settings.js";
|
|
3
|
-
export function
|
|
3
|
+
export function getWindowZones(win, thresholdPx) {
|
|
4
4
|
const thX = numberToScaledPercent(thresholdPx, win.pxWidth);
|
|
5
5
|
const thY = numberToScaledPercent(thresholdPx, win.pxHeight);
|
|
6
6
|
const maxInt = settings.maxInt;
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { MoveState, Zone } from "../types/index.js";
|
|
2
|
+
/**
|
|
3
|
+
* Find the drag zone under the drag point.
|
|
4
|
+
*/
|
|
5
|
+
export declare function getZones(state: Pick<MoveState, "movePoint" | "moveHoveredFrame" | "frames" | "win">, { frameEdgePx, windowEdgePx }: {
|
|
6
|
+
frameEdgePx: number;
|
|
7
|
+
windowEdgePx: number;
|
|
8
|
+
}): Zone | undefined;
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { getFrameZones } from "./getFrameZones.js";
|
|
2
|
+
import { getWindowZones } from "./getWindowZones.js";
|
|
3
|
+
import { isPointInRect } from "./isPointInRect.js";
|
|
4
|
+
export function getZones(state, { frameEdgePx, windowEdgePx }) {
|
|
5
|
+
const { movePoint, win } = state;
|
|
6
|
+
const frameId = state.moveHoveredFrame?.id;
|
|
7
|
+
if (!frameId) return;
|
|
8
|
+
const frame = state.frames[frameId];
|
|
9
|
+
if (!frame || !movePoint) return;
|
|
10
|
+
const frameZones = getFrameZones(frame, frameEdgePx, win.pxWidth, win.pxHeight);
|
|
11
|
+
const windowZones = getWindowZones(win, windowEdgePx);
|
|
12
|
+
let matchedZone;
|
|
13
|
+
for (const zone of windowZones) {
|
|
14
|
+
if (isPointInRect(zone, movePoint)) {
|
|
15
|
+
matchedZone = {
|
|
16
|
+
...zone,
|
|
17
|
+
type: "window"
|
|
18
|
+
};
|
|
19
|
+
break;
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
if (!matchedZone) {
|
|
23
|
+
for (const zone of frameZones) {
|
|
24
|
+
if (isPointInRect(zone, movePoint)) {
|
|
25
|
+
matchedZone = zone;
|
|
26
|
+
break;
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
if (!matchedZone) return void 0;
|
|
31
|
+
return matchedZone;
|
|
32
|
+
}
|
|
@@ -7,20 +7,23 @@ export { findSafeSplitEdgeAndPosition } from "./findSafeSplitEdge.js";
|
|
|
7
7
|
export { findVisualEdge } from "./findVisualEdge.js";
|
|
8
8
|
export { frameCreate } from "./frameCreate.js";
|
|
9
9
|
export { getCloseFrameInfo } from "./getCloseFrameInfo.js";
|
|
10
|
-
export {
|
|
10
|
+
export { getZones } from "./getZones.js";
|
|
11
11
|
export { getFillEmptySpaceInfo } from "./getFillEmptySpaceInfo.js";
|
|
12
12
|
export { getFrameCollapseInfo } from "./getFrameCollapseInfo.js";
|
|
13
13
|
export { getFrameDockInfo } from "./getFrameDockInfo.js";
|
|
14
|
-
export {
|
|
14
|
+
export { getFrameZones } from "./getFrameZones.js";
|
|
15
|
+
export { getFrameExpandInfo } from "./getFrameExpandInfo.js";
|
|
15
16
|
export { getFrameRearrangeInfo } from "./getFrameRearrangeInfo.js";
|
|
17
|
+
export { getFrameShrinkInfo } from "./getFrameShrinkInfo.js";
|
|
16
18
|
export { getFrameSplitInfo } from "./getFrameSplitInfo.js";
|
|
17
19
|
export { getFramesRedistributeInfo } from "./getFramesRedistributeInfo.js";
|
|
18
20
|
export { getFrameSwapInfo } from "./getFrameSwapInfo.js";
|
|
19
21
|
export { getFrameTo } from "./getFrameTo.js";
|
|
20
22
|
export { getFrameUncollapseInfo } from "./getFrameUncollapseInfo.js";
|
|
21
23
|
export { getFrameUndockInfo } from "./getFrameUndockInfo.js";
|
|
24
|
+
export { getRelaxFramesInfo } from "./getRelaxFramesInfo.js";
|
|
22
25
|
export { getUpdateWindowSizeInfo } from "./getUpdateWindowSizeInfo.js";
|
|
23
|
-
export {
|
|
26
|
+
export { getWindowZones } from "./getWindowZones.js";
|
|
24
27
|
export { isPointInRect } from "./isPointInRect.js";
|
|
25
28
|
export { layoutAddWindow } from "./layoutAddWindow.js";
|
|
26
29
|
export { layoutCreate } from "./layoutCreate.js";
|
|
@@ -7,20 +7,23 @@ export { findSafeSplitEdgeAndPosition } from "./findSafeSplitEdge.js";
|
|
|
7
7
|
export { findVisualEdge } from "./findVisualEdge.js";
|
|
8
8
|
export { frameCreate } from "./frameCreate.js";
|
|
9
9
|
export { getCloseFrameInfo } from "./getCloseFrameInfo.js";
|
|
10
|
-
export {
|
|
10
|
+
export { getZones } from "./getZones.js";
|
|
11
11
|
export { getFillEmptySpaceInfo } from "./getFillEmptySpaceInfo.js";
|
|
12
12
|
export { getFrameCollapseInfo } from "./getFrameCollapseInfo.js";
|
|
13
13
|
export { getFrameDockInfo } from "./getFrameDockInfo.js";
|
|
14
|
-
export {
|
|
14
|
+
export { getFrameZones } from "./getFrameZones.js";
|
|
15
|
+
export { getFrameExpandInfo } from "./getFrameExpandInfo.js";
|
|
15
16
|
export { getFrameRearrangeInfo } from "./getFrameRearrangeInfo.js";
|
|
17
|
+
export { getFrameShrinkInfo } from "./getFrameShrinkInfo.js";
|
|
16
18
|
export { getFrameSplitInfo } from "./getFrameSplitInfo.js";
|
|
17
19
|
export { getFramesRedistributeInfo } from "./getFramesRedistributeInfo.js";
|
|
18
20
|
export { getFrameSwapInfo } from "./getFrameSwapInfo.js";
|
|
19
21
|
export { getFrameTo } from "./getFrameTo.js";
|
|
20
22
|
export { getFrameUncollapseInfo } from "./getFrameUncollapseInfo.js";
|
|
21
23
|
export { getFrameUndockInfo } from "./getFrameUndockInfo.js";
|
|
24
|
+
export { getRelaxFramesInfo } from "./getRelaxFramesInfo.js";
|
|
22
25
|
export { getUpdateWindowSizeInfo } from "./getUpdateWindowSizeInfo.js";
|
|
23
|
-
export {
|
|
26
|
+
export { getWindowZones } from "./getWindowZones.js";
|
|
24
27
|
export { isPointInRect } from "./isPointInRect.js";
|
|
25
28
|
export { layoutAddWindow } from "./layoutAddWindow.js";
|
|
26
29
|
export { layoutCreate } from "./layoutCreate.js";
|
|
@@ -1,16 +1,16 @@
|
|
|
1
1
|
import { type RecordFromArray } from "@alanscodelog/utils";
|
|
2
|
-
import type {
|
|
2
|
+
import type { ActionHandlerApplyResult, Edge, IAction, LayoutFrame, LayoutShape, MoveChangeHandler, MoveChangeResult, MoveState } from "../types/index.js";
|
|
3
3
|
/**
|
|
4
|
-
* Handles the lifecycle of a drag actions {@link
|
|
4
|
+
* Handles the lifecycle of a drag actions {@link IAction} and provides additional hooks.
|
|
5
5
|
*
|
|
6
6
|
* The first action instance that can handle the request is passed control of the event handlers until the request changes.
|
|
7
7
|
*/
|
|
8
|
-
export declare class
|
|
9
|
-
activeAction?: keyof
|
|
10
|
-
actions:
|
|
11
|
-
eventCanceller: ((e: PointerEvent | KeyboardEvent | undefined, state:
|
|
12
|
-
boundCancel: (e: PointerEvent | KeyboardEvent | undefined, state:
|
|
13
|
-
|
|
8
|
+
export declare class ActionHandler<TRawActions extends IAction[], TActions extends RecordFromArray<TRawActions, "name"> = RecordFromArray<TRawActions, "name">> {
|
|
9
|
+
activeAction?: keyof TActions;
|
|
10
|
+
actions: TActions;
|
|
11
|
+
eventCanceller: ((e: PointerEvent | KeyboardEvent | undefined, state: MoveState) => void) | undefined;
|
|
12
|
+
boundCancel: (e: PointerEvent | KeyboardEvent | undefined, state: MoveState) => void;
|
|
13
|
+
defaultOnMoveChange: MoveChangeHandler;
|
|
14
14
|
hooks: {
|
|
15
15
|
/** Called while dragging during dragChange events. You can use this to update the dragging edges. */
|
|
16
16
|
onRecalculate?: () => void;
|
|
@@ -21,7 +21,7 @@ export declare class DragActionHandler<TRawDragActions extends IDragAction[], TD
|
|
|
21
21
|
*/
|
|
22
22
|
onEvent?: (e: PointerEvent | KeyboardEvent | undefined, cancel: () => void) => void;
|
|
23
23
|
/** Called when the action requested changes. */
|
|
24
|
-
onRequestChange?: (type: keyof
|
|
24
|
+
onRequestChange?: (type: keyof TActions | undefined) => void;
|
|
25
25
|
/** Called when the drag action ends either because it was completed or cancelled. */
|
|
26
26
|
onEnd?: (context: {
|
|
27
27
|
cancelled: boolean;
|
|
@@ -30,27 +30,27 @@ export declare class DragActionHandler<TRawDragActions extends IDragAction[], TD
|
|
|
30
30
|
};
|
|
31
31
|
/** All action shapes merged into a single array. If using vue you can set this to a reactive array for reactivity. */
|
|
32
32
|
shapes: LayoutShape[];
|
|
33
|
-
/** All hint/error text from all actions, updated on every
|
|
33
|
+
/** All hint/error text from all actions, updated on every onMoveChange. If using vue you can set this to a reactive object for reactivity. */
|
|
34
34
|
textHints: {
|
|
35
35
|
actions: string[];
|
|
36
36
|
errors: string[];
|
|
37
37
|
};
|
|
38
|
-
constructor(actions:
|
|
38
|
+
constructor(actions: TRawActions, hooks?: ActionHandler<TRawActions, TActions>["hooks"],
|
|
39
39
|
/**
|
|
40
|
-
* Default
|
|
40
|
+
* Default onMoveChange handler for when no action can handle the request.
|
|
41
41
|
*
|
|
42
42
|
* Should return true to allow the edges to be moved, or false to prevent it.
|
|
43
43
|
*
|
|
44
44
|
* The default prevents movement when the edge is a window edge and when the edge is touching a collapsed frame.
|
|
45
45
|
*/
|
|
46
|
-
|
|
47
|
-
eventHandler(e: KeyboardEvent | PointerEvent, state:
|
|
48
|
-
|
|
46
|
+
defaultOnMoveChange?: MoveChangeHandler);
|
|
47
|
+
eventHandler(e: KeyboardEvent | PointerEvent, state: MoveState, forceRecalculateEdges: () => void): undefined;
|
|
48
|
+
onMoveChange<T extends "start" | "move" | "end">(type: T, e: T extends "end" ? PointerEvent | undefined : PointerEvent, state: MoveState, forceRecalculateEdges: () => void, cancel: T extends "end" ? undefined : (e: PointerEvent | KeyboardEvent | undefined, state: MoveState) => void, resolve: T extends "end" ? undefined : (opts: ActionHandlerApplyResult) => void): MoveChangeResult;
|
|
49
49
|
setTextHints(type: "start" | "move" | "end"): void;
|
|
50
50
|
annotateEdges(edges: Edge[], frames: LayoutFrame[]): void;
|
|
51
|
-
|
|
52
|
-
cancel(e: PointerEvent | KeyboardEvent | undefined, state:
|
|
53
|
-
static debugState(pluginName: string, type: "before" | "after" | string, state:
|
|
51
|
+
onMoveApply(state: MoveState, forceRecalculateEdges: () => void): ActionHandlerApplyResult;
|
|
52
|
+
cancel(e: PointerEvent | KeyboardEvent | undefined, state: MoveState): void;
|
|
53
|
+
static debugState(pluginName: string, type: "before" | "after" | string, state: MoveState, pluginState?: Record<string, any>,
|
|
54
54
|
/** Object key to filter the state by, e.g. state.win.frames. If false is ignored. The idea is you pass this.debug and users can set this.debug to a string to filter. */
|
|
55
55
|
key?: string | boolean): void;
|
|
56
56
|
}
|
|
@@ -3,30 +3,30 @@ import { isWindowEdge } from "../helpers/isWindowEdge.js";
|
|
|
3
3
|
import { findFramesTouchingEdge } from "../layout/findFramesTouchingEdge.js";
|
|
4
4
|
import { LAYOUT_ERROR } from "../types/index.js";
|
|
5
5
|
import { KnownError } from "../utils/KnownError.js";
|
|
6
|
-
export class
|
|
6
|
+
export class ActionHandler {
|
|
7
7
|
activeAction;
|
|
8
8
|
actions;
|
|
9
9
|
eventCanceller = void 0;
|
|
10
10
|
boundCancel;
|
|
11
|
-
|
|
12
|
-
const isTouchingCollapsedFrameEdge = type === "move" && state.
|
|
11
|
+
defaultOnMoveChange = (type, _e, state, _forceRecalculateEdges, _cancel) => {
|
|
12
|
+
const isTouchingCollapsedFrameEdge = type === "move" && state.isMoving === "edge" && state.touchingFramesArrays.some(
|
|
13
13
|
(frames) => (
|
|
14
14
|
// we check with a falsy check on PURPOSE, frames collapsed to 0 aren't an issue, they are ignored anyways
|
|
15
15
|
Object.values(frames).some((f) => f.collapsed)
|
|
16
16
|
)
|
|
17
17
|
);
|
|
18
18
|
return {
|
|
19
|
-
updateEdges: type === "move" ? !(state.
|
|
19
|
+
updateEdges: type === "move" ? !(state.isMovingFromWindowEdge || isTouchingCollapsedFrameEdge) : true,
|
|
20
20
|
shapes: []
|
|
21
21
|
};
|
|
22
22
|
};
|
|
23
23
|
hooks;
|
|
24
24
|
/** All action shapes merged into a single array. If using vue you can set this to a reactive array for reactivity. */
|
|
25
25
|
shapes = [];
|
|
26
|
-
/** All hint/error text from all actions, updated on every
|
|
26
|
+
/** All hint/error text from all actions, updated on every onMoveChange. If using vue you can set this to a reactive object for reactivity. */
|
|
27
27
|
textHints = { actions: [], errors: [] };
|
|
28
|
-
constructor(actions, hooks = {},
|
|
29
|
-
if (
|
|
28
|
+
constructor(actions, hooks = {}, defaultOnMoveChange) {
|
|
29
|
+
if (defaultOnMoveChange) this.defaultOnMoveChange = defaultOnMoveChange;
|
|
30
30
|
this.hooks = hooks;
|
|
31
31
|
this.actions = {};
|
|
32
32
|
for (const action of actions) {
|
|
@@ -35,7 +35,7 @@ export class DragActionHandler {
|
|
|
35
35
|
this.boundCancel = this.cancel.bind(this);
|
|
36
36
|
}
|
|
37
37
|
eventHandler(e, state, forceRecalculateEdges) {
|
|
38
|
-
if (state.
|
|
38
|
+
if (state.isMoving) {
|
|
39
39
|
e.preventDefault();
|
|
40
40
|
}
|
|
41
41
|
let cancelled = false;
|
|
@@ -62,29 +62,29 @@ export class DragActionHandler {
|
|
|
62
62
|
}
|
|
63
63
|
this.hooks.onRequestChange?.(this.activeAction);
|
|
64
64
|
}
|
|
65
|
-
if (state.
|
|
65
|
+
if (state.isMoving) {
|
|
66
66
|
forceRecalculateEdges();
|
|
67
67
|
this.hooks.onRecalculate?.();
|
|
68
68
|
}
|
|
69
69
|
return void 0;
|
|
70
70
|
}
|
|
71
|
-
|
|
71
|
+
onMoveChange(type, e, state, forceRecalculateEdges, cancel, resolve) {
|
|
72
72
|
if (type === "start") {
|
|
73
73
|
this.eventCanceller = cancel;
|
|
74
74
|
this.eventHandler(e, state, forceRecalculateEdges);
|
|
75
75
|
}
|
|
76
|
-
if (type === "end") {
|
|
77
|
-
this.activeAction = void 0;
|
|
78
|
-
}
|
|
79
76
|
if (this.activeAction) {
|
|
80
|
-
const res2 = this.actions[this.activeAction].
|
|
77
|
+
const res2 = this.actions[this.activeAction].onMoveChange(type, e, state, forceRecalculateEdges, this.boundCancel, resolve);
|
|
81
78
|
this.shapes.splice(0, this.shapes.length, ...res2.shapes);
|
|
82
79
|
this.setTextHints(type);
|
|
83
80
|
return res2;
|
|
84
81
|
}
|
|
85
82
|
this.setTextHints(type);
|
|
86
|
-
const res = this.
|
|
83
|
+
const res = this.defaultOnMoveChange(type, e, state, forceRecalculateEdges, this.boundCancel, resolve);
|
|
87
84
|
this.shapes.splice(0, this.shapes.length, ...res.shapes);
|
|
85
|
+
if (type === "end") {
|
|
86
|
+
this.activeAction = void 0;
|
|
87
|
+
}
|
|
88
88
|
return res;
|
|
89
89
|
}
|
|
90
90
|
setTextHints(type) {
|
|
@@ -118,14 +118,14 @@ export class DragActionHandler {
|
|
|
118
118
|
}
|
|
119
119
|
}
|
|
120
120
|
}
|
|
121
|
-
|
|
121
|
+
onMoveApply(state, forceRecalculateEdges) {
|
|
122
122
|
if (this.activeAction) {
|
|
123
|
-
const res = this.actions[this.activeAction].
|
|
123
|
+
const res = this.actions[this.activeAction].onMoveApply(state, forceRecalculateEdges);
|
|
124
124
|
this.hooks.onEnd?.({ cancelled: false, applied: res });
|
|
125
|
-
return
|
|
125
|
+
return { apply: res, result: void 0 };
|
|
126
126
|
}
|
|
127
127
|
this.hooks.onEnd?.({ cancelled: false, applied: false });
|
|
128
|
-
return true;
|
|
128
|
+
return { apply: true, result: void 0 };
|
|
129
129
|
}
|
|
130
130
|
cancel(e, state) {
|
|
131
131
|
if (this.activeAction) {
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { getCloseFrameInfo } from "../layout/getCloseFrameInfo.js";
|
|
2
|
-
import type {
|
|
2
|
+
import type { ActionChangeResult, CloseDeco, IAction, MoveState } from "../types/index.js";
|
|
3
3
|
import type { KnownError } from "../utils/KnownError.js";
|
|
4
4
|
export type CloseInfo = Exclude<ReturnType<typeof getCloseFrameInfo>, KnownError>;
|
|
5
|
-
export declare class CloseAction implements
|
|
5
|
+
export declare class CloseAction implements IAction {
|
|
6
6
|
name: "close";
|
|
7
7
|
minDragDistance: number;
|
|
8
8
|
state: {
|
|
@@ -10,13 +10,13 @@ export declare class CloseAction implements IDragAction {
|
|
|
10
10
|
force: boolean;
|
|
11
11
|
res: CloseInfo;
|
|
12
12
|
cacheKey: string | undefined;
|
|
13
|
-
lastReturn:
|
|
13
|
+
lastReturn: ActionChangeResult;
|
|
14
14
|
} | {
|
|
15
15
|
allowed: false;
|
|
16
16
|
force: boolean;
|
|
17
17
|
res: CloseInfo | undefined;
|
|
18
18
|
cacheKey: string | undefined;
|
|
19
|
-
lastReturn:
|
|
19
|
+
lastReturn: ActionChangeResult | undefined;
|
|
20
20
|
};
|
|
21
21
|
debug: boolean | string;
|
|
22
22
|
textHints: {
|
|
@@ -29,7 +29,7 @@ export declare class CloseAction implements IDragAction {
|
|
|
29
29
|
}) => string[]);
|
|
30
30
|
transformError: (e: KnownError) => string;
|
|
31
31
|
};
|
|
32
|
-
handleEvent: (e: PointerEvent | KeyboardEvent, state:
|
|
32
|
+
handleEvent: (e: PointerEvent | KeyboardEvent, state: MoveState) => boolean | "force";
|
|
33
33
|
modifyDecos: (shapes: CloseDeco[]) => void;
|
|
34
34
|
hooks: {
|
|
35
35
|
onStart?: (active: boolean) => void;
|
|
@@ -51,8 +51,8 @@ export declare class CloseAction implements IDragAction {
|
|
|
51
51
|
actions: string[];
|
|
52
52
|
errors: string[];
|
|
53
53
|
};
|
|
54
|
-
canHandleRequest(e: PointerEvent | KeyboardEvent, state:
|
|
55
|
-
|
|
56
|
-
|
|
54
|
+
canHandleRequest(e: PointerEvent | KeyboardEvent, state: MoveState): boolean;
|
|
55
|
+
onMoveChange(type: "start" | "end" | "move", _e: PointerEvent | undefined, state: MoveState): ActionChangeResult;
|
|
56
|
+
onMoveApply(state: MoveState): boolean;
|
|
57
57
|
cancel(): void;
|
|
58
58
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { ActionHandler } from "./ActionHandler.js";
|
|
2
2
|
import { dirToOrientation } from "../helpers/dirToOrientation.js";
|
|
3
3
|
import { getEdgeOrientation } from "../helpers/getEdgeOrientation.js";
|
|
4
4
|
import { oppositeSide } from "../helpers/oppositeSide.js";
|
|
@@ -46,8 +46,8 @@ export class CloseAction {
|
|
|
46
46
|
}
|
|
47
47
|
_getDecos(state) {
|
|
48
48
|
let decos = [];
|
|
49
|
-
const {
|
|
50
|
-
if (
|
|
49
|
+
const { isMoving } = state;
|
|
50
|
+
if (isMoving && this.state.allowed && this.state.res) {
|
|
51
51
|
const { force } = this.state;
|
|
52
52
|
decos = this.state.res.deleted.map((_) => ({
|
|
53
53
|
id: _.id,
|
|
@@ -86,11 +86,11 @@ export class CloseAction {
|
|
|
86
86
|
return this.textHints;
|
|
87
87
|
}
|
|
88
88
|
canHandleRequest(e, state) {
|
|
89
|
-
const {
|
|
90
|
-
if (
|
|
89
|
+
const { movingEdges } = state;
|
|
90
|
+
if (movingEdges.length !== 1) return false;
|
|
91
91
|
const res = this.handleEvent(e, state);
|
|
92
92
|
this.state.force = res === "force";
|
|
93
|
-
this.setTextHints(state.
|
|
93
|
+
this.setTextHints(state.isMoving === "edge" ? true : void 0);
|
|
94
94
|
if (res) {
|
|
95
95
|
this.hooks.onStart?.(true);
|
|
96
96
|
return true;
|
|
@@ -98,42 +98,46 @@ export class CloseAction {
|
|
|
98
98
|
this.reset();
|
|
99
99
|
return false;
|
|
100
100
|
}
|
|
101
|
-
|
|
102
|
-
if (
|
|
101
|
+
onMoveChange(type, _e, state) {
|
|
102
|
+
if (type === "end") {
|
|
103
|
+
this.reset();
|
|
104
|
+
return { shapes: [] };
|
|
105
|
+
}
|
|
106
|
+
if (state.moveDistance <= this.minDragDistance) {
|
|
103
107
|
return { updateEdges: false, shapes: [] };
|
|
104
108
|
}
|
|
105
109
|
const {
|
|
106
110
|
touchingFramesArrays,
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
111
|
+
moveDirections,
|
|
112
|
+
isMoving,
|
|
113
|
+
movingEdges,
|
|
110
114
|
visualEdges,
|
|
111
115
|
frames,
|
|
112
|
-
|
|
113
|
-
|
|
116
|
+
isMovingFromWindowEdge,
|
|
117
|
+
movePoint
|
|
114
118
|
} = state;
|
|
115
|
-
const oppositeOrientation = oppositeSide(getEdgeOrientation(
|
|
116
|
-
const cacheKey = `${
|
|
119
|
+
const oppositeOrientation = oppositeSide(getEdgeOrientation(movingEdges[0]));
|
|
120
|
+
const cacheKey = `${movePoint?.x}-${movePoint?.y}-${moveDirections[oppositeOrientation]}-${this.state.force}`;
|
|
117
121
|
if (this.state.allowed) {
|
|
118
122
|
if (this.state.cacheKey === cacheKey) {
|
|
119
123
|
return this.state.lastReturn;
|
|
120
124
|
}
|
|
121
125
|
}
|
|
122
|
-
if (
|
|
126
|
+
if (isMoving && movingEdges.length === 1) {
|
|
123
127
|
const res = findFramesTouchingEdge(
|
|
124
|
-
|
|
128
|
+
movingEdges[0],
|
|
125
129
|
touchingFramesArrays[0],
|
|
126
130
|
{
|
|
127
|
-
// referencePoint:
|
|
128
|
-
searchDirections: [
|
|
131
|
+
// referencePoint: movePoint.value, // if force pick smallest frame?
|
|
132
|
+
searchDirections: [moveDirections[oppositeOrientation]]
|
|
129
133
|
}
|
|
130
134
|
);
|
|
131
135
|
if (res.length > 0) {
|
|
132
|
-
const orientation = dirToOrientation(
|
|
136
|
+
const orientation = dirToOrientation(moveDirections[oppositeOrientation]);
|
|
133
137
|
const sizeKey = orientation === "horizontal" ? "width" : "height";
|
|
134
138
|
const smallestFrameSize = Math.min(...res.map((_) => _.frame[sizeKey]));
|
|
135
139
|
const frame = res.find((_) => _.frame[sizeKey] === smallestFrameSize).frame;
|
|
136
|
-
const closeInfo = getCloseFrameInfo(Object.values(frames), visualEdges, frame,
|
|
140
|
+
const closeInfo = getCloseFrameInfo(Object.values(frames), visualEdges, frame, moveDirections[oppositeOrientation], "dir", this.state.force);
|
|
137
141
|
this.state.cacheKey = cacheKey;
|
|
138
142
|
this.setTextHints(closeInfo);
|
|
139
143
|
if (!(closeInfo instanceof Error)) {
|
|
@@ -148,20 +152,19 @@ export class CloseAction {
|
|
|
148
152
|
}
|
|
149
153
|
}
|
|
150
154
|
const decos = this._getDecos(state);
|
|
151
|
-
this.state.lastReturn = { updateEdges: !
|
|
155
|
+
this.state.lastReturn = { updateEdges: !isMovingFromWindowEdge, shapes: decos.flatMap((_) => _.shapes) };
|
|
152
156
|
return this.state.lastReturn;
|
|
153
157
|
}
|
|
154
|
-
|
|
158
|
+
onMoveApply(state) {
|
|
155
159
|
if (this.state.res) {
|
|
156
160
|
const win = state.win;
|
|
157
161
|
if (this.debug) {
|
|
158
|
-
|
|
162
|
+
ActionHandler.debugState(this.name, "before", state, this.state, this.debug);
|
|
159
163
|
}
|
|
160
164
|
applyFrameChanges(win, this.state.res);
|
|
161
165
|
if (this.debug) {
|
|
162
|
-
|
|
166
|
+
ActionHandler.debugState(this.name, "after", state, this.state, this.debug);
|
|
163
167
|
}
|
|
164
|
-
this.reset();
|
|
165
168
|
return true;
|
|
166
169
|
}
|
|
167
170
|
return false;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { ActionChangeResult, FrameDeco, IAction, LayoutChange, MoveState, Zone } from "../types/index.js";
|
|
2
2
|
import type { KnownError } from "../utils/KnownError.js";
|
|
3
|
-
export declare class FrameDragAction implements
|
|
3
|
+
export declare class FrameDragAction implements IAction {
|
|
4
4
|
name: "frameDrag";
|
|
5
5
|
minDragDistance: number;
|
|
6
6
|
state: {
|
|
@@ -11,7 +11,7 @@ export declare class FrameDragAction implements IDragAction {
|
|
|
11
11
|
actions: string[];
|
|
12
12
|
errors: string[];
|
|
13
13
|
};
|
|
14
|
-
handleEvent: (e: PointerEvent | KeyboardEvent, state:
|
|
14
|
+
handleEvent: (e: PointerEvent | KeyboardEvent, state: MoveState) => boolean;
|
|
15
15
|
dragHints: {
|
|
16
16
|
actions: {
|
|
17
17
|
split?: string;
|
|
@@ -23,7 +23,7 @@ export declare class FrameDragAction implements IDragAction {
|
|
|
23
23
|
}) => string[]);
|
|
24
24
|
transformError: (e: KnownError) => string;
|
|
25
25
|
};
|
|
26
|
-
modifyDecos: (shapes:
|
|
26
|
+
modifyDecos: (shapes: FrameDeco[]) => void;
|
|
27
27
|
hooks: {
|
|
28
28
|
onStart?: () => void;
|
|
29
29
|
onCancel?: () => void;
|
|
@@ -42,9 +42,9 @@ export declare class FrameDragAction implements IDragAction {
|
|
|
42
42
|
actions: string[];
|
|
43
43
|
errors: string[];
|
|
44
44
|
};
|
|
45
|
-
getDecos(matchedZone:
|
|
46
|
-
canHandleRequest(e: PointerEvent | KeyboardEvent, state:
|
|
47
|
-
|
|
48
|
-
|
|
45
|
+
getDecos(matchedZone: Zone | undefined, state: MoveState, result: LayoutChange<"split" | "swap" | "rearrange" | "dock"> | KnownError | undefined): FrameDeco[];
|
|
46
|
+
canHandleRequest(e: PointerEvent | KeyboardEvent, state: MoveState): boolean;
|
|
47
|
+
onMoveChange<T extends "start" | "move" | "end">(type: T, _e: PointerEvent | undefined, state: MoveState): ActionChangeResult;
|
|
48
|
+
onMoveApply(state: MoveState): boolean;
|
|
49
49
|
cancel(): void;
|
|
50
50
|
}
|