@witchcraft/layout 0.1.3 → 0.2.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/README.md +27 -24
- package/dist/module.json +1 -1
- package/dist/runtime/components/FrameDragHandle.d.vue.ts +15 -0
- package/dist/runtime/components/FrameDragHandle.vue +28 -0
- package/dist/runtime/components/FrameDragHandle.vue.d.ts +15 -0
- package/dist/runtime/components/LayoutDecos.d.vue.ts +2 -4
- package/dist/runtime/components/LayoutDecos.vue +10 -29
- package/dist/runtime/components/LayoutDecos.vue.d.ts +2 -4
- package/dist/runtime/components/LayoutEdges.d.vue.ts +3 -3
- package/dist/runtime/components/LayoutEdges.vue +8 -8
- package/dist/runtime/components/LayoutEdges.vue.d.ts +3 -3
- package/dist/runtime/components/LayoutFrame.d.vue.ts +1 -1
- package/dist/runtime/components/LayoutFrame.vue +0 -1
- package/dist/runtime/components/LayoutFrame.vue.d.ts +1 -1
- package/dist/runtime/components/LayoutShapeSquare.d.vue.ts +3 -1
- package/dist/runtime/components/LayoutShapeSquare.vue.d.ts +3 -1
- package/dist/runtime/components/LayoutWindow.d.vue.ts +26 -12
- package/dist/runtime/components/LayoutWindow.vue +95 -84
- package/dist/runtime/components/LayoutWindow.vue.d.ts +26 -12
- package/dist/runtime/composables/useFrames.d.ts +15 -13
- package/dist/runtime/composables/useFrames.js +59 -39
- package/dist/runtime/demo/App.vue +116 -30
- package/dist/runtime/demo/DemoControls.d.vue.ts +4 -1
- package/dist/runtime/demo/DemoControls.vue +98 -4
- package/dist/runtime/demo/DemoControls.vue.d.ts +4 -1
- package/dist/runtime/drag/CloseAction.d.ts +26 -5
- package/dist/runtime/drag/CloseAction.js +87 -40
- package/dist/runtime/drag/DragActionHandler.d.ts +20 -8
- package/dist/runtime/drag/DragActionHandler.js +47 -12
- package/dist/runtime/drag/FrameDragAction.d.ts +45 -0
- package/dist/runtime/drag/FrameDragAction.js +143 -0
- package/dist/runtime/drag/SplitAction.d.ts +32 -11
- package/dist/runtime/drag/SplitAction.js +82 -24
- package/dist/runtime/drag/createDefaultHandlers.d.ts +9 -0
- package/dist/runtime/drag/createDefaultHandlers.js +10 -0
- package/dist/runtime/drag/defaultDragActions.d.ts +9 -0
- package/dist/runtime/drag/defaultDragActions.js +10 -0
- package/dist/runtime/drag/types.d.ts +82 -13
- package/dist/runtime/drag/types.js +1 -0
- package/dist/runtime/helpers/createZoneSideClipPath.d.ts +12 -0
- package/dist/runtime/helpers/createZoneSideClipPath.js +17 -0
- package/dist/runtime/helpers/doEdgesOverlap.d.ts +3 -1
- package/dist/runtime/helpers/doEdgesOverlap.js +5 -5
- package/dist/runtime/helpers/getDockBoundaries.d.ts +19 -0
- package/dist/runtime/helpers/getDockBoundaries.js +14 -0
- package/dist/runtime/helpers/getEdgeLength.d.ts +2 -0
- package/dist/runtime/helpers/getEdgeLength.js +5 -0
- package/dist/runtime/helpers/getIntersections.js +2 -2
- package/dist/runtime/helpers/getIntersectionsCss.js +2 -2
- package/dist/runtime/helpers/getMoveEdgeInfo.js +2 -2
- package/dist/runtime/helpers/getResizeLimit.js +2 -2
- package/dist/runtime/helpers/getShapeSquareCss.js +2 -2
- package/dist/runtime/helpers/getVisualEdgeCss.js +2 -2
- package/dist/runtime/helpers/getVisualEdges.d.ts +1 -1
- package/dist/runtime/helpers/getVisualEdges.js +4 -3
- package/dist/runtime/helpers/index.d.ts +4 -0
- package/dist/runtime/helpers/index.js +4 -0
- package/dist/runtime/helpers/isEdgeEqual.js +2 -4
- package/dist/runtime/helpers/isWindowEdge.js +2 -2
- package/dist/runtime/helpers/isWindowEdgePoint.js +2 -2
- package/dist/runtime/helpers/moveEdge.js +2 -2
- package/dist/runtime/helpers/numberToScaledPercent.d.ts +1 -1
- package/dist/runtime/helpers/numberToScaledPercent.js +2 -2
- package/dist/runtime/helpers/numberToScaledSize.js +2 -2
- package/dist/runtime/helpers/rotateFrames.d.ts +7 -0
- package/dist/runtime/helpers/rotateFrames.js +36 -0
- package/dist/runtime/helpers/scaledPointToPx.d.ts +13 -0
- package/dist/runtime/helpers/scaledPointToPx.js +7 -0
- package/dist/runtime/helpers/toWindowCoord.js +2 -2
- package/dist/runtime/layout/applyFrameChanges.d.ts +10 -0
- package/dist/runtime/layout/applyFrameChanges.js +29 -0
- package/dist/runtime/layout/createSplitDecoFromDrag.d.ts +6 -1
- package/dist/runtime/layout/createSplitDecoFromDrag.js +4 -4
- package/dist/runtime/layout/createSplitDecoShapes.d.ts +7 -0
- package/dist/runtime/layout/{createSplitDecoEdge.js → createSplitDecoShapes.js} +6 -3
- package/dist/runtime/layout/debugFrame.js +2 -1
- package/dist/runtime/layout/findSafeSplitEdge.js +2 -2
- package/dist/runtime/layout/frameCreate.js +2 -2
- package/dist/runtime/layout/getCloseFrameInfo.d.ts +7 -6
- package/dist/runtime/layout/getCloseFrameInfo.js +10 -3
- package/dist/runtime/layout/getDragZones.d.ts +8 -0
- package/dist/runtime/layout/getDragZones.js +32 -0
- package/dist/runtime/layout/getFillEmptySpaceInfo.d.ts +65 -0
- package/dist/runtime/layout/getFillEmptySpaceInfo.js +69 -0
- package/dist/runtime/layout/getFrameCollapseInfo.d.ts +13 -0
- package/dist/runtime/layout/getFrameCollapseInfo.js +93 -0
- package/dist/runtime/layout/getFrameDockInfo.d.ts +9 -0
- package/dist/runtime/layout/getFrameDockInfo.js +82 -0
- package/dist/runtime/layout/getFrameDragZones.d.ts +16 -0
- package/dist/runtime/layout/getFrameDragZones.js +74 -0
- package/dist/runtime/layout/getFrameRearrangeInfo.d.ts +139 -0
- package/dist/runtime/layout/getFrameRearrangeInfo.js +87 -0
- package/dist/runtime/layout/getFrameSplitInfo.d.ts +7 -5
- package/dist/runtime/layout/getFrameSplitInfo.js +10 -3
- package/dist/runtime/layout/getFrameSwapInfo.d.ts +9 -0
- package/dist/runtime/layout/getFrameSwapInfo.js +27 -0
- package/dist/runtime/layout/getFrameTo.js +2 -2
- package/dist/runtime/layout/getFrameUncollapseInfo.d.ts +12 -0
- package/dist/runtime/layout/getFrameUncollapseInfo.js +88 -0
- package/dist/runtime/layout/getFrameUndockInfo.d.ts +13 -0
- package/dist/runtime/layout/getFrameUndockInfo.js +51 -0
- package/dist/runtime/layout/getFramesRedistributeInfo.d.ts +29 -0
- package/dist/runtime/layout/getFramesRedistributeInfo.js +53 -0
- package/dist/runtime/layout/getWindowDragZones.d.ts +6 -0
- package/dist/runtime/layout/getWindowDragZones.js +49 -0
- package/dist/runtime/layout/index.d.ts +14 -5
- package/dist/runtime/layout/index.js +14 -5
- package/dist/runtime/layout/isPointInRect.d.ts +7 -0
- package/dist/runtime/layout/{isPointInFrame.js → isPointInRect.js} +1 -1
- package/dist/runtime/layout/resizeFrame.js +2 -2
- package/dist/runtime/settings.d.ts +41 -16
- package/dist/runtime/settings.js +95 -53
- package/dist/runtime/types/index.d.ts +324 -54
- package/dist/runtime/types/index.js +54 -20
- package/package.json +28 -29
- package/src/runtime/components/FrameDragHandle.vue +30 -0
- package/src/runtime/components/LayoutDecos.vue +12 -36
- package/src/runtime/components/LayoutEdges.vue +27 -23
- package/src/runtime/components/LayoutFrame.vue +6 -5
- package/src/runtime/components/LayoutShapeSquare.vue +9 -3
- package/src/runtime/components/LayoutWindow.vue +110 -101
- package/src/runtime/composables/useFrames.ts +80 -50
- package/src/runtime/demo/App.vue +126 -36
- package/src/runtime/demo/DemoControls.vue +115 -6
- package/src/runtime/drag/CloseAction.ts +106 -44
- package/src/runtime/drag/DragActionHandler.ts +71 -20
- package/src/runtime/drag/FrameDragAction.ts +202 -0
- package/src/runtime/drag/SplitAction.ts +106 -34
- package/src/runtime/drag/createDefaultHandlers.ts +19 -0
- package/src/runtime/drag/defaultDragActions.ts +19 -0
- package/src/runtime/drag/types.ts +90 -20
- package/src/runtime/helpers/createZoneSideClipPath.ts +41 -0
- package/src/runtime/helpers/doEdgesOverlap.ts +11 -5
- package/src/runtime/helpers/getDockBoundaries.ts +36 -0
- package/src/runtime/helpers/getEdgeLength.ts +10 -0
- package/src/runtime/helpers/getIntersections.ts +2 -2
- package/src/runtime/helpers/getIntersectionsCss.ts +2 -2
- package/src/runtime/helpers/getMoveEdgeInfo.ts +2 -2
- package/src/runtime/helpers/getResizeLimit.ts +2 -2
- package/src/runtime/helpers/getShapeSquareCss.ts +2 -2
- package/src/runtime/helpers/getVisualEdgeCss.ts +2 -2
- package/src/runtime/helpers/getVisualEdges.ts +5 -4
- package/src/runtime/helpers/index.ts +4 -0
- package/src/runtime/helpers/isEdgeEqual.ts +2 -4
- package/src/runtime/helpers/isWindowEdge.ts +2 -2
- package/src/runtime/helpers/isWindowEdgePoint.ts +2 -2
- package/src/runtime/helpers/moveEdge.ts +2 -2
- package/src/runtime/helpers/numberToScaledPercent.ts +3 -3
- package/src/runtime/helpers/numberToScaledSize.ts +2 -2
- package/src/runtime/helpers/rotateFrames.ts +45 -0
- package/src/runtime/helpers/scaledPointToPx.ts +13 -0
- package/src/runtime/helpers/toWindowCoord.ts +2 -2
- package/src/runtime/layout/applyFrameChanges.ts +39 -0
- package/src/runtime/layout/createSplitDecoFromDrag.ts +12 -6
- package/src/runtime/layout/{createSplitDecoEdge.ts → createSplitDecoShapes.ts} +17 -7
- package/src/runtime/layout/debugFrame.ts +1 -1
- package/src/runtime/layout/findSafeSplitEdge.ts +3 -3
- package/src/runtime/layout/frameCreate.ts +2 -2
- package/src/runtime/layout/getCloseFrameInfo.ts +21 -8
- package/src/runtime/layout/getDragZones.ts +48 -0
- package/src/runtime/layout/getFillEmptySpaceInfo.ts +177 -0
- package/src/runtime/layout/getFrameCollapseInfo.ts +164 -0
- package/src/runtime/layout/getFrameDockInfo.ts +126 -0
- package/src/runtime/layout/getFrameDragZones.ts +100 -0
- package/src/runtime/layout/getFrameRearrangeInfo.ts +261 -0
- package/src/runtime/layout/getFrameSplitInfo.ts +21 -8
- package/src/runtime/layout/getFrameSwapInfo.ts +45 -0
- package/src/runtime/layout/getFrameTo.ts +2 -2
- package/src/runtime/layout/getFrameUncollapseInfo.ts +160 -0
- package/src/runtime/layout/getFrameUndockInfo.ts +97 -0
- package/src/runtime/layout/getFramesRedistributeInfo.ts +98 -0
- package/src/runtime/layout/getWindowDragZones.ts +59 -0
- package/src/runtime/layout/index.ts +14 -5
- package/src/runtime/layout/isPointInRect.ts +7 -0
- package/src/runtime/layout/resizeFrame.ts +2 -2
- package/src/runtime/settings.ts +69 -49
- package/src/runtime/types/index.ts +143 -28
- package/dist/runtime/layout/closeFrame.d.ts +0 -5
- package/dist/runtime/layout/closeFrame.js +0 -13
- package/dist/runtime/layout/closeFrames.d.ts +0 -2
- package/dist/runtime/layout/closeFrames.js +0 -8
- package/dist/runtime/layout/createSplitDecoEdge.d.ts +0 -2
- package/dist/runtime/layout/frameSplit.d.ts +0 -16
- package/dist/runtime/layout/frameSplit.js +0 -9
- package/dist/runtime/layout/isPointInFrame.d.ts +0 -2
- package/src/runtime/layout/closeFrame.ts +0 -33
- package/src/runtime/layout/closeFrames.ts +0 -14
- package/src/runtime/layout/frameSplit.ts +0 -31
- package/src/runtime/layout/isPointInFrame.ts +0 -7
|
@@ -1,11 +1,16 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { ComputedRef, InjectionKey, Ref } from "vue";
|
|
2
|
+
import type { Direction, Edge, FrameId, IntersectionEntry, LayoutFrame, LayoutShape, LayoutWindow, Orientation, Point } from "../types/index.js";
|
|
2
3
|
export type DragState = {
|
|
3
4
|
/** The current directions in the corresponding orientations that the user is dragging in. */
|
|
4
5
|
dragDirections: Record<Orientation, Direction | undefined>;
|
|
5
6
|
/** The curren point (in scaled window coordinates) the user is dragging at. */
|
|
6
7
|
dragPoint?: Point;
|
|
7
|
-
/** Whether the user is currently dragging. Is
|
|
8
|
-
isDragging: boolean;
|
|
8
|
+
/** Whether the user is currently dragging and what type of drag. Is truthy string during all drag events. */
|
|
9
|
+
isDragging: boolean | "frame" | "edge";
|
|
10
|
+
/** Whether to show the moved frames while dragging. */
|
|
11
|
+
showDragging: boolean;
|
|
12
|
+
/** The frame being dragged during a frame drag. Only set when isDragging is "frame". */
|
|
13
|
+
draggingFrameId?: FrameId;
|
|
9
14
|
/**
|
|
10
15
|
* The edges that are currently being dragged. There are multiple edges if they drag an intersection since what's actually happening is we're just dragging the closest horizontal and vertical edges.
|
|
11
16
|
*/
|
|
@@ -44,12 +49,23 @@ export type DragState = {
|
|
|
44
49
|
isDraggingFromWindowEdge: boolean;
|
|
45
50
|
win: LayoutWindow;
|
|
46
51
|
};
|
|
52
|
+
export interface ActionDragChangeResult {
|
|
53
|
+
/** Whether the drag should update the edges. Defaults to false. */
|
|
54
|
+
updateEdges?: boolean;
|
|
55
|
+
/** Deco shapes produced by this action during this drag step. */
|
|
56
|
+
shapes: LayoutShape[];
|
|
57
|
+
/** Whether to show the moved edges while dragging. Defaults to true. */
|
|
58
|
+
showDragging?: boolean;
|
|
59
|
+
}
|
|
60
|
+
export type DragChangeResult = Omit<ActionDragChangeResult, "shapes">;
|
|
47
61
|
/**
|
|
48
|
-
*
|
|
62
|
+
* Called when the drag coordinates change (during any event).
|
|
63
|
+
*
|
|
64
|
+
* Should return `{ allowed: true/false, shapes: LayoutShape[] }` to control whether the action is allowed and edges update and what deco shapes to render.
|
|
65
|
+
*
|
|
66
|
+
* Note that the allowed return type only affect the `move` event but is also typed as `boolean` for other events for ease of use.
|
|
49
67
|
*/
|
|
50
|
-
export
|
|
51
|
-
<T extends "start" | "move" | "end">(type: T, e: T extends "end" ? PointerEvent | undefined : PointerEvent, state: DragState, forceRecalculateEdges: () => void, cancel: () => void): boolean | undefined;
|
|
52
|
-
}
|
|
68
|
+
export type DragChangeHandler = <T extends "start" | "move" | "end">(type: T, e: T extends "end" ? PointerEvent | undefined : PointerEvent, state: DragState, forceRecalculateEdges: () => void, cancel: (e: PointerEvent | KeyboardEvent | undefined, state: DragState) => void) => ActionDragChangeResult;
|
|
53
69
|
/**
|
|
54
70
|
* A drag action describes when and how to handle a drag event.
|
|
55
71
|
*
|
|
@@ -60,11 +76,6 @@ export interface DragChangeHandler {
|
|
|
60
76
|
export interface IDragAction {
|
|
61
77
|
/** A unique name for your action. */
|
|
62
78
|
name: string;
|
|
63
|
-
/**
|
|
64
|
-
* Called when the drag coordinates change (during any event). Should return true to allow the edges to be moved, or false to prevent it.
|
|
65
|
-
*
|
|
66
|
-
* Can be used to save some context/info to later apply safely during onDragApply.
|
|
67
|
-
*/
|
|
68
79
|
onDragChange: DragChangeHandler;
|
|
69
80
|
/**
|
|
70
81
|
*
|
|
@@ -88,5 +99,63 @@ export interface IDragAction {
|
|
|
88
99
|
*
|
|
89
100
|
* You should reset your state here.
|
|
90
101
|
*/
|
|
91
|
-
cancel(): void;
|
|
102
|
+
cancel(e: PointerEvent | KeyboardEvent | undefined, state: DragState): void;
|
|
103
|
+
/**
|
|
104
|
+
* Plugins should implement some basic debug logs by calling {@link DragActionHandler.debugState } at least before and after applying actions in onDragApply. Debug can be a string because it can be an object key to filter on (see the debugState function).
|
|
105
|
+
*
|
|
106
|
+
*
|
|
107
|
+
* Calls look like this usually, where this.state is the plugin state:
|
|
108
|
+
* ```ts
|
|
109
|
+
* DragActionHandler.debugState(this.name, "before", state, this.state, this.debug)
|
|
110
|
+
* ```
|
|
111
|
+
*/
|
|
112
|
+
debug: boolean | string;
|
|
113
|
+
/**
|
|
114
|
+
* The action handler will call this regardless of whether the action is active or not.
|
|
115
|
+
*
|
|
116
|
+
* Can be used by actions to return display hints.
|
|
117
|
+
*
|
|
118
|
+
* Actions should keep the state of the hints locally and update them in canHandlerRequest/onDrag*, etc. and only use this to return the state of the actions, not update them as that could become expensive.
|
|
119
|
+
*/
|
|
120
|
+
getTextHints(type: "start" | "move" | "end"): {
|
|
121
|
+
/** Hint texts to display regarding the action state/usage. Undefined means no hint. */
|
|
122
|
+
actions?: string[];
|
|
123
|
+
/** Error texts/hints to display when the action produces an error. */
|
|
124
|
+
errors?: string[];
|
|
125
|
+
};
|
|
126
|
+
}
|
|
127
|
+
export type EdgeDragStartData = {
|
|
128
|
+
edge?: Edge;
|
|
129
|
+
intersection?: IntersectionEntry;
|
|
130
|
+
};
|
|
131
|
+
export type FrameDragStartData = {
|
|
132
|
+
frameId: FrameId;
|
|
133
|
+
};
|
|
134
|
+
export type DragStartFn = {
|
|
135
|
+
(e: PointerEvent, type: "edge", data: EdgeDragStartData): void;
|
|
136
|
+
(e: PointerEvent, type: "frame", data: FrameDragStartData): void;
|
|
137
|
+
};
|
|
138
|
+
export interface UseFramesContext {
|
|
139
|
+
dragStart: DragStartFn;
|
|
140
|
+
dragMove: (e: PointerEvent) => void;
|
|
141
|
+
dragEnd: (e?: PointerEvent, options?: {
|
|
142
|
+
apply?: boolean;
|
|
143
|
+
}) => void;
|
|
144
|
+
cancel: () => void;
|
|
145
|
+
dragDirections: Ref<Record<Orientation, Direction | undefined>>;
|
|
146
|
+
dragPoint: Ref<Point | undefined>;
|
|
147
|
+
isDragging: Ref<false | "frame" | "edge">;
|
|
148
|
+
draggingEdges: Ref<Edge[]>;
|
|
149
|
+
draggingIntersection: Ref<IntersectionEntry | undefined>;
|
|
150
|
+
visualEdges: Ref<Edge[]>;
|
|
151
|
+
touchingFrames: Ref<Record<string, LayoutFrame>[]>;
|
|
152
|
+
touchingFramesArrays: Ref<LayoutFrame[][]>;
|
|
153
|
+
frames: ComputedRef<Record<string, LayoutFrame>>;
|
|
154
|
+
dragHoveredFrame: ComputedRef<LayoutFrame | undefined>;
|
|
155
|
+
intersections: ComputedRef<IntersectionEntry[]>;
|
|
156
|
+
isDraggingFromWindowEdge: Ref<boolean>;
|
|
157
|
+
forceRecalculateEdges: () => void;
|
|
158
|
+
state: ComputedRef<DragState>;
|
|
159
|
+
frameDragFrameId: Ref<FrameId | undefined>;
|
|
92
160
|
}
|
|
161
|
+
export declare const dragContextInjectionKey: InjectionKey<UseFramesContext>;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export const dragContextInjectionKey = Symbol("dragContext");
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Get the clip-path polygon for a zone's side. Ends the shape at a 45° angle.
|
|
3
|
+
*
|
|
4
|
+
* e.g. for a right zone, it looks like it's cutting the top and bottom left corners.
|
|
5
|
+
*
|
|
6
|
+
* Accepts scaled coordinates.
|
|
7
|
+
*/
|
|
8
|
+
import type { DragZone } from "../types/index.js";
|
|
9
|
+
export declare function createZoneSideClipPath(zone: DragZone, { frameEdgePx, windowEdgePx }: {
|
|
10
|
+
frameEdgePx: number;
|
|
11
|
+
windowEdgePx: number;
|
|
12
|
+
}): string | undefined;
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
export function createZoneSideClipPath(zone, { frameEdgePx, windowEdgePx }) {
|
|
2
|
+
const side = zone.side;
|
|
3
|
+
const thicknessPx = zone.type === "window" ? windowEdgePx : frameEdgePx;
|
|
4
|
+
const pxLength = zone.side === "center" ? 0 : zone.side === "right" || zone.side === "left" ? zone.pxHeight : zone.pxWidth;
|
|
5
|
+
if (side === "center") return void 0;
|
|
6
|
+
const t = thicknessPx;
|
|
7
|
+
const l = pxLength;
|
|
8
|
+
if (side === "bottom")
|
|
9
|
+
return `polygon(${t}px 0px, ${l - t}px 0px, ${l}px ${t}px, 0px ${t}px)`;
|
|
10
|
+
if (side === "left")
|
|
11
|
+
return `polygon(0px 0px, ${t}px ${t}px, ${t}px ${l - t}px, 0px ${l}px)`;
|
|
12
|
+
if (side === "top")
|
|
13
|
+
return `polygon(0px 0px, ${t}px ${t}px, ${l - t}px ${t}px, ${l}px 0px)`;
|
|
14
|
+
if (side === "right")
|
|
15
|
+
return `polygon(${t}px 0px, 0px ${t}px, 0px ${l - t}px, ${t}px ${l}px)`;
|
|
16
|
+
return void 0;
|
|
17
|
+
}
|
|
@@ -1,2 +1,4 @@
|
|
|
1
1
|
import type { Edge, Orientation } from "../types/index.js";
|
|
2
|
-
export declare function doEdgesOverlap(edgeA: Edge, edgeB: Edge, dir?: Orientation
|
|
2
|
+
export declare function doEdgesOverlap(edgeA: Edge, edgeB: Edge, dir?: Orientation,
|
|
3
|
+
/** If you pass inclusive true it will also match edges that start where the other edge ends or vice versa. */
|
|
4
|
+
inclusive?: boolean): boolean;
|
|
@@ -1,22 +1,22 @@
|
|
|
1
1
|
import { getEdgeOrientation } from "./getEdgeOrientation.js";
|
|
2
2
|
import { inRange } from "./inRange.js";
|
|
3
3
|
import { isEdgeParallel } from "./isEdgeParallel.js";
|
|
4
|
-
export function doEdgesOverlap(edgeA, edgeB, dir) {
|
|
4
|
+
export function doEdgesOverlap(edgeA, edgeB, dir, inclusive = false) {
|
|
5
5
|
dir ??= getEdgeOrientation(edgeA);
|
|
6
6
|
if (!isEdgeParallel(edgeA, edgeB)) return false;
|
|
7
7
|
if (dir === "horizontal") {
|
|
8
8
|
if (edgeA.startY !== edgeB.startY) return false;
|
|
9
9
|
const leftMost = edgeA.startX <= edgeB.startX ? edgeA : edgeB;
|
|
10
10
|
const rightMost = edgeB === leftMost ? edgeA : edgeB;
|
|
11
|
-
const startOverlaps = inRange(leftMost.endX, rightMost.startX, rightMost.endX);
|
|
12
|
-
const endOverlaps = inRange(rightMost.startX, leftMost.startX, leftMost.endX);
|
|
11
|
+
const startOverlaps = inRange(leftMost.endX, rightMost.startX, rightMost.endX, inclusive);
|
|
12
|
+
const endOverlaps = inRange(rightMost.startX, leftMost.startX, leftMost.endX, inclusive);
|
|
13
13
|
return startOverlaps || endOverlaps;
|
|
14
14
|
} else {
|
|
15
15
|
if (edgeA.startX !== edgeB.startX) return false;
|
|
16
16
|
const topMost = edgeA.startY <= edgeB.startY ? edgeA : edgeB;
|
|
17
17
|
const bottomMost = edgeB === topMost ? edgeA : edgeB;
|
|
18
|
-
const startOverlaps = inRange(topMost.endY, bottomMost.startY, bottomMost.endY);
|
|
19
|
-
const endOverlaps = inRange(bottomMost.startY, topMost.startY, topMost.endY);
|
|
18
|
+
const startOverlaps = inRange(topMost.endY, bottomMost.startY, bottomMost.endY, inclusive);
|
|
19
|
+
const endOverlaps = inRange(bottomMost.startY, topMost.startY, topMost.endY, inclusive);
|
|
20
20
|
return startOverlaps || endOverlaps;
|
|
21
21
|
}
|
|
22
22
|
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import type { LayoutWindow } from "../types/index.js";
|
|
2
|
+
/**
|
|
3
|
+
* Compute the inner boundaries of a docked region by looking at already docked frames.
|
|
4
|
+
*
|
|
5
|
+
* For example, if A, B, and C are docked, this returns the area of C.
|
|
6
|
+
* ┌─────────┐
|
|
7
|
+
* │A* │
|
|
8
|
+
* ├────┬────┤
|
|
9
|
+
* │B* │C │
|
|
10
|
+
* ├────┴────┤
|
|
11
|
+
* │D* │
|
|
12
|
+
* └─────────┘
|
|
13
|
+
*/
|
|
14
|
+
export declare function getDockBoundaries(win: LayoutWindow): {
|
|
15
|
+
minX: number;
|
|
16
|
+
maxX: number;
|
|
17
|
+
minY: number;
|
|
18
|
+
maxY: number;
|
|
19
|
+
};
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { settings } from "../settings.js";
|
|
2
|
+
export function getDockBoundaries(win) {
|
|
3
|
+
let minX = 0;
|
|
4
|
+
let maxX = settings.maxInt;
|
|
5
|
+
let minY = 0;
|
|
6
|
+
let maxY = settings.maxInt;
|
|
7
|
+
for (const f of Object.values(win.frames)) {
|
|
8
|
+
if (f.docked === "left") minX = Math.max(minX, f.x + f.width);
|
|
9
|
+
if (f.docked === "right") maxX = Math.min(maxX, f.x);
|
|
10
|
+
if (f.docked === "top") minY = Math.max(minY, f.y + f.height);
|
|
11
|
+
if (f.docked === "bottom") maxY = Math.min(maxY, f.y);
|
|
12
|
+
}
|
|
13
|
+
return { minX, maxX, minY, maxY };
|
|
14
|
+
}
|
|
@@ -4,7 +4,7 @@ import { addPointsToIntersection } from "./addPointsToIntersection.js";
|
|
|
4
4
|
import { edgeToPoints } from "./edgeToPoints.js";
|
|
5
5
|
import { getEdgeOrientation } from "./getEdgeOrientation.js";
|
|
6
6
|
import { inRange } from "./inRange.js";
|
|
7
|
-
import {
|
|
7
|
+
import { settings } from "../settings.js";
|
|
8
8
|
export function getIntersections(visualEdges) {
|
|
9
9
|
const intersections = {
|
|
10
10
|
// x: {y: count}
|
|
@@ -13,7 +13,7 @@ export function getIntersections(visualEdges) {
|
|
|
13
13
|
addPointsToIntersection(intersections, Object.values(edgeToPoints(edge)));
|
|
14
14
|
}
|
|
15
15
|
const points = [];
|
|
16
|
-
const maxInt =
|
|
16
|
+
const maxInt = settings.maxInt;
|
|
17
17
|
for (const x of keys(intersections)) {
|
|
18
18
|
for (const y of keys(intersections[x])) {
|
|
19
19
|
castType(x);
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { settings } from "../settings.js";
|
|
2
2
|
export function getIntersectionsCss(entries, {
|
|
3
3
|
intersectionWidth = `var(--layoutIntersectionWidth, 8px)`,
|
|
4
4
|
/** How much to shift the intersections by when it's not on a four corner intersection. Otherwise it tends to look ugly because it overlaps one of the frame edges, this shifts it away from it. */
|
|
5
5
|
shiftAmount = `var(--layoutIntersectionShiftAmount, 2px)`
|
|
6
6
|
} = {}) {
|
|
7
|
-
const unscale =
|
|
7
|
+
const unscale = settings.maxInt / 100;
|
|
8
8
|
return entries.map((entry) => {
|
|
9
9
|
const point = entry.point;
|
|
10
10
|
const css = {
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { clampNumber } from "./clampNumber.js";
|
|
2
2
|
import { getEdgeOrientation } from "./getEdgeOrientation.js";
|
|
3
3
|
import { getResizeLimit } from "./getResizeLimit.js";
|
|
4
|
-
import {
|
|
5
|
-
export function getMoveEdgeInfo(touchingFrames, edge, position, margin =
|
|
4
|
+
import { settings } from "../settings.js";
|
|
5
|
+
export function getMoveEdgeInfo(touchingFrames, edge, position, margin = settings.minSizeScaled, clamp = true) {
|
|
6
6
|
const { x: posX, y: posY } = position;
|
|
7
7
|
const edgeDirection = getEdgeOrientation(edge);
|
|
8
8
|
const dir = edgeDirection === "horizontal" ? posY < edge.startY ? "up" : "down" : posX < edge.startX ? "left" : "right";
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { castType } from "@alanscodelog/utils/castType";
|
|
2
2
|
import { keys } from "@alanscodelog/utils/keys";
|
|
3
|
-
import {
|
|
3
|
+
import { settings } from "../settings.js";
|
|
4
4
|
export function getResizeLimit(edge, touchingFrames, dir, amount, margin) {
|
|
5
5
|
const limits = dir === "horizontal" ? { left: -Infinity, right: Infinity } : dir === "vertical" ? { up: -Infinity, down: Infinity } : { [dir]: dir === "up" || dir === "left" ? -Infinity : Infinity };
|
|
6
6
|
if (amount === 0) {
|
|
@@ -31,7 +31,7 @@ export function getResizeLimit(edge, touchingFrames, dir, amount, margin) {
|
|
|
31
31
|
}
|
|
32
32
|
for (const key of keys(limits)) {
|
|
33
33
|
if (limits[key] === -Infinity) limits[key] = 0;
|
|
34
|
-
if (limits[key] === Infinity) limits[key] =
|
|
34
|
+
if (limits[key] === Infinity) limits[key] = settings.maxInt;
|
|
35
35
|
limits[key] += dir === "left" || dir === "up" ? margin : -margin;
|
|
36
36
|
}
|
|
37
37
|
if (dir === "horizontal" || dir === "vertical") return limits;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { settings } from "../settings.js";
|
|
2
2
|
export function getShapeSquareCss(obj, pad) {
|
|
3
|
-
const unscale =
|
|
3
|
+
const unscale = settings.maxInt / 100;
|
|
4
4
|
const css = {
|
|
5
5
|
x: `${obj.x / unscale}%`,
|
|
6
6
|
y: `${obj.y / unscale}%`,
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { getEdgeOrientation } from "./getEdgeOrientation.js";
|
|
2
|
-
import {
|
|
2
|
+
import { settings } from "../settings.js";
|
|
3
3
|
export function getVisualEdgeCss(edge, {
|
|
4
4
|
translate = true,
|
|
5
5
|
edgeWidth = `var(--layoutEdgeWidth, 2px)`,
|
|
@@ -7,7 +7,7 @@ export function getVisualEdgeCss(edge, {
|
|
|
7
7
|
padShortAxis
|
|
8
8
|
} = {}) {
|
|
9
9
|
const dir = getEdgeOrientation(edge);
|
|
10
|
-
const unscale =
|
|
10
|
+
const unscale = settings.maxInt / 100;
|
|
11
11
|
const w = (edge.endX - edge.startX) / unscale;
|
|
12
12
|
const h = (edge.endY - edge.startY) / unscale;
|
|
13
13
|
const width = dir === "vertical" ? edgeWidth : `${w}%`;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { Edge, LayoutFrame, Orientation } from "../types/index.js";
|
|
2
2
|
/**
|
|
3
|
-
* Returns the "visual" edges that can be dragged.
|
|
3
|
+
* Returns the "visual" edges that can be dragged (so will not return edges for collapsed frames without some area).
|
|
4
4
|
*
|
|
5
5
|
* Visual edges are a combination of all edges shared by frames that must be moved together.
|
|
6
6
|
*
|
|
@@ -8,7 +8,7 @@ import { frameToPoints } from "./frameToPoints.js";
|
|
|
8
8
|
import { inRange } from "./inRange.js";
|
|
9
9
|
import { splitEdge } from "./splitEdge.js";
|
|
10
10
|
import { unionEdges } from "./unionEdges.js";
|
|
11
|
-
import {
|
|
11
|
+
import { settings } from "../settings.js";
|
|
12
12
|
export function getVisualEdges(frames, {
|
|
13
13
|
separateByDir = false,
|
|
14
14
|
includeWindowEdges = false
|
|
@@ -18,8 +18,9 @@ export function getVisualEdges(frames, {
|
|
|
18
18
|
const intersections = {
|
|
19
19
|
// x: {y: count}
|
|
20
20
|
};
|
|
21
|
-
const max =
|
|
21
|
+
const max = settings.maxInt;
|
|
22
22
|
for (const frame of frames) {
|
|
23
|
+
if (frame.collapsed && (frame.width === 0 || frame.height === 0)) continue;
|
|
23
24
|
const frameEdges = frameToEdges(frame);
|
|
24
25
|
addPointsToIntersection(intersections, Object.values(frameToPoints(frame)));
|
|
25
26
|
secondlabel: for (const edge of Object.values(frameEdges)) {
|
|
@@ -33,7 +34,7 @@ export function getVisualEdges(frames, {
|
|
|
33
34
|
if (containsEdge(edge, e, dir)) {
|
|
34
35
|
continue secondlabel;
|
|
35
36
|
}
|
|
36
|
-
if (doEdgesOverlap(e, edge, dir)) {
|
|
37
|
+
if (doEdgesOverlap(e, edge, dir, true)) {
|
|
37
38
|
indexes.push(i);
|
|
38
39
|
edges.push(e);
|
|
39
40
|
}
|
|
@@ -13,6 +13,7 @@ export { containsEdge } from "./containsEdge.js";
|
|
|
13
13
|
export { convertLayoutWindowToWorkspace } from "./convertLayoutWindowToWorkspace.js";
|
|
14
14
|
export { copySize } from "./copySize.js";
|
|
15
15
|
export { createEdge } from "./createEdge.js";
|
|
16
|
+
export { createZoneSideClipPath } from "./createZoneSideClipPath.js";
|
|
16
17
|
export { dirToOrientation } from "./dirToOrientation.js";
|
|
17
18
|
export { dirToSide } from "./dirToSide.js";
|
|
18
19
|
export { doEdgesOverlap } from "./doEdgesOverlap.js";
|
|
@@ -22,6 +23,7 @@ export { findDraggableEdge } from "./findDraggableEdge.js";
|
|
|
22
23
|
export { findFrameDraggableEdges } from "./findFrameDraggableEdges.js";
|
|
23
24
|
export { frameToEdges } from "./frameToEdges.js";
|
|
24
25
|
export { frameToPoints } from "./frameToPoints.js";
|
|
26
|
+
export { getEdgeLength } from "./getEdgeLength.js";
|
|
25
27
|
export { getEdgeOrientation } from "./getEdgeOrientation.js";
|
|
26
28
|
export { getEdgeSharedDirection } from "./getEdgeSharedDirection.js";
|
|
27
29
|
export { getEdgeSide } from "./getEdgeSide.js";
|
|
@@ -53,6 +55,7 @@ export { numberToScaledPercent } from "./numberToScaledPercent.js";
|
|
|
53
55
|
export { numberToScaledSize } from "./numberToScaledSize.js";
|
|
54
56
|
export { oppositeSide } from "./oppositeSide.js";
|
|
55
57
|
export { resizeByEdge } from "./resizeByEdge.js";
|
|
58
|
+
export { scaledPointToPx } from "./scaledPointToPx.js";
|
|
56
59
|
export { sideToDirection } from "./sideToDirection.js";
|
|
57
60
|
export { sideToOrientation } from "./sideToOrientation.js";
|
|
58
61
|
export { splitEdge } from "./splitEdge.js";
|
|
@@ -60,3 +63,4 @@ export { toCoord } from "./toCoord.js";
|
|
|
60
63
|
export { toId } from "./toId.js";
|
|
61
64
|
export { toWindowCoord } from "./toWindowCoord.js";
|
|
62
65
|
export { unionEdges } from "./unionEdges.js";
|
|
66
|
+
export { updateWindowWithEvent } from "./updateWindowSizeWithEvent.js";
|
|
@@ -13,6 +13,7 @@ export { containsEdge } from "./containsEdge.js";
|
|
|
13
13
|
export { convertLayoutWindowToWorkspace } from "./convertLayoutWindowToWorkspace.js";
|
|
14
14
|
export { copySize } from "./copySize.js";
|
|
15
15
|
export { createEdge } from "./createEdge.js";
|
|
16
|
+
export { createZoneSideClipPath } from "./createZoneSideClipPath.js";
|
|
16
17
|
export { dirToOrientation } from "./dirToOrientation.js";
|
|
17
18
|
export { dirToSide } from "./dirToSide.js";
|
|
18
19
|
export { doEdgesOverlap } from "./doEdgesOverlap.js";
|
|
@@ -22,6 +23,7 @@ export { findDraggableEdge } from "./findDraggableEdge.js";
|
|
|
22
23
|
export { findFrameDraggableEdges } from "./findFrameDraggableEdges.js";
|
|
23
24
|
export { frameToEdges } from "./frameToEdges.js";
|
|
24
25
|
export { frameToPoints } from "./frameToPoints.js";
|
|
26
|
+
export { getEdgeLength } from "./getEdgeLength.js";
|
|
25
27
|
export { getEdgeOrientation } from "./getEdgeOrientation.js";
|
|
26
28
|
export { getEdgeSharedDirection } from "./getEdgeSharedDirection.js";
|
|
27
29
|
export { getEdgeSide } from "./getEdgeSide.js";
|
|
@@ -53,6 +55,7 @@ export { numberToScaledPercent } from "./numberToScaledPercent.js";
|
|
|
53
55
|
export { numberToScaledSize } from "./numberToScaledSize.js";
|
|
54
56
|
export { oppositeSide } from "./oppositeSide.js";
|
|
55
57
|
export { resizeByEdge } from "./resizeByEdge.js";
|
|
58
|
+
export { scaledPointToPx } from "./scaledPointToPx.js";
|
|
56
59
|
export { sideToDirection } from "./sideToDirection.js";
|
|
57
60
|
export { sideToOrientation } from "./sideToOrientation.js";
|
|
58
61
|
export { splitEdge } from "./splitEdge.js";
|
|
@@ -60,3 +63,4 @@ export { toCoord } from "./toCoord.js";
|
|
|
60
63
|
export { toId } from "./toId.js";
|
|
61
64
|
export { toWindowCoord } from "./toWindowCoord.js";
|
|
62
65
|
export { unionEdges } from "./unionEdges.js";
|
|
66
|
+
export { updateWindowWithEvent } from "./updateWindowSizeWithEvent.js";
|
|
@@ -1,11 +1,9 @@
|
|
|
1
1
|
import { getEdgeOrientation } from "./getEdgeOrientation.js";
|
|
2
|
-
import { isEdgeParallel } from "./isEdgeParallel.js";
|
|
3
2
|
export function isEdgeEqual(edgeA, edgeB, orientation) {
|
|
4
3
|
orientation ??= getEdgeOrientation(edgeA);
|
|
5
|
-
if (!isEdgeParallel(edgeA, edgeB)) return false;
|
|
6
4
|
if (orientation === "horizontal") {
|
|
7
|
-
return edgeA.startY === edgeB.startY && edgeB.endY === edgeA.endY;
|
|
5
|
+
return edgeA.startX === edgeB.startX && edgeB.endX === edgeA.endX && edgeA.startY === edgeB.startY && edgeB.endY === edgeA.endY;
|
|
8
6
|
} else {
|
|
9
|
-
return edgeA.startX === edgeB.startX && edgeB.endX === edgeA.endX;
|
|
7
|
+
return edgeA.startX === edgeB.startX && edgeB.endX === edgeA.endX && edgeA.startY === edgeB.startY && edgeB.endY === edgeA.endY;
|
|
10
8
|
}
|
|
11
9
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { getEdgeOrientation } from "./getEdgeOrientation.js";
|
|
2
|
-
import {
|
|
2
|
+
import { settings } from "../settings.js";
|
|
3
3
|
export function isWindowEdge(edge, edgeDirection) {
|
|
4
4
|
edgeDirection ??= getEdgeOrientation(edge);
|
|
5
|
-
const max =
|
|
5
|
+
const max = settings.maxInt;
|
|
6
6
|
return edgeDirection === "vertical" && (edge.startX === 0 || edge.startX === max) || edgeDirection === "horizontal" && (edge.startY === 0 || edge.startY === max);
|
|
7
7
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { settings } from "../settings.js";
|
|
2
2
|
export function isWindowEdgePoint(point) {
|
|
3
|
-
const max =
|
|
3
|
+
const max = settings.maxInt;
|
|
4
4
|
return point.x === 0 || point.x === max || (point.y === 0 || point.y === max);
|
|
5
5
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { getMoveEdgeInfo } from "./getMoveEdgeInfo.js";
|
|
2
2
|
import { resizeByEdge } from "./resizeByEdge.js";
|
|
3
|
-
import {
|
|
4
|
-
export function moveEdge(touchingFrames, edge, position, margin =
|
|
3
|
+
import { settings } from "../settings.js";
|
|
4
|
+
export function moveEdge(touchingFrames, edge, position, margin = settings.minSizeScaled) {
|
|
5
5
|
if (!edge || !touchingFrames) return;
|
|
6
6
|
const { pos, dir, distance } = getMoveEdgeInfo(touchingFrames, edge, position, margin);
|
|
7
7
|
resizeByEdge(touchingFrames, edge, dir, pos, distance);
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Given a number (e.g. the x coordinate in px), and the max value it could be (e.g. the max width of it's container in px), returns it's position as a scaled percentage.
|
|
2
|
+
* Given a number (e.g. the x coordinate in px), and the max value it could be (e.g. the max width of it's container in px), returns it's position as a rounded scaled percentage.
|
|
3
3
|
*
|
|
4
4
|
* ```
|
|
5
5
|
* -----------
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { snapNumber } from "@alanscodelog/utils/snapNumber";
|
|
2
|
-
import {
|
|
3
|
-
export function numberToScaledPercent(num, max, scale =
|
|
2
|
+
import { settings } from "../settings.js";
|
|
3
|
+
export function numberToScaledPercent(num, max, scale = settings.maxInt) {
|
|
4
4
|
return snapNumber(num / max * scale, 1);
|
|
5
5
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { unreachable } from "@alanscodelog/utils/unreachable";
|
|
2
2
|
import { numberToScaledPercent } from "./numberToScaledPercent.js";
|
|
3
|
-
import {
|
|
4
|
-
export function numberToScaledSize(win, size, scale =
|
|
3
|
+
import { settings } from "../settings.js";
|
|
4
|
+
export function numberToScaledSize(win, size, scale = settings.maxInt) {
|
|
5
5
|
const scaledSize = {
|
|
6
6
|
width: numberToScaledPercent(
|
|
7
7
|
typeof size === "number" ? size : size.pxWidth,
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { LayoutFrame } from "../types/index.js";
|
|
2
|
+
/**
|
|
3
|
+
* Rotates the list of frames given by 90, 180, or 270 degrees around the 50% center.
|
|
4
|
+
*
|
|
5
|
+
* Used mainly in testing to catch issues with incorrect handling of the same scenario in different orientations.
|
|
6
|
+
*/
|
|
7
|
+
export declare function rotateLayout(frames: LayoutFrame[], rotation: 90 | 180 | 270): void;
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { settings } from "../settings.js";
|
|
2
|
+
export function rotateLayout(frames, rotation) {
|
|
3
|
+
const sides = ["top", "right", "bottom", "left"];
|
|
4
|
+
const shift = rotation / 90;
|
|
5
|
+
for (const frame of frames) {
|
|
6
|
+
const { x, y, width, height, docked } = frame;
|
|
7
|
+
if (docked) {
|
|
8
|
+
const currentIndex = sides.indexOf(docked);
|
|
9
|
+
if (currentIndex !== -1) {
|
|
10
|
+
frame.docked = sides[(currentIndex + shift) % 4];
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
switch (rotation) {
|
|
14
|
+
case 90:
|
|
15
|
+
frame.x = settings.maxInt - (y + height);
|
|
16
|
+
frame.y = x;
|
|
17
|
+
frame.width = height;
|
|
18
|
+
frame.height = width;
|
|
19
|
+
break;
|
|
20
|
+
case 180:
|
|
21
|
+
frame.x = settings.maxInt - (x + width);
|
|
22
|
+
frame.y = settings.maxInt - (y + height);
|
|
23
|
+
frame.width = width;
|
|
24
|
+
frame.height = height;
|
|
25
|
+
break;
|
|
26
|
+
case 270:
|
|
27
|
+
frame.x = y;
|
|
28
|
+
frame.y = settings.maxInt - (x + width);
|
|
29
|
+
frame.width = height;
|
|
30
|
+
frame.height = width;
|
|
31
|
+
break;
|
|
32
|
+
default:
|
|
33
|
+
throw new Error(`Unknown rotation ${rotation}`);
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/** Convert a scaled point to pixel coords for a given window. */
|
|
2
|
+
export declare function scaledPointToPx(point: {
|
|
3
|
+
x: number;
|
|
4
|
+
y: number;
|
|
5
|
+
}, win: {
|
|
6
|
+
pxWidth: number;
|
|
7
|
+
pxHeight: number;
|
|
8
|
+
pxX: number;
|
|
9
|
+
pxY: number;
|
|
10
|
+
}, scale?: number): {
|
|
11
|
+
x: number;
|
|
12
|
+
y: number;
|
|
13
|
+
};
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { snapNumber } from "@alanscodelog/utils/snapNumber";
|
|
2
2
|
import { numberToScaledPercent } from "./numberToScaledPercent.js";
|
|
3
|
-
import {
|
|
4
|
-
export function toWindowCoord(win, e, snapAmount =
|
|
3
|
+
import { settings } from "../settings.js";
|
|
4
|
+
export function toWindowCoord(win, e, snapAmount = settings.snapPointScaled) {
|
|
5
5
|
const x = numberToScaledPercent(e.clientX - win.pxX, win.pxWidth);
|
|
6
6
|
const y = numberToScaledPercent(e.clientY - win.pxY, win.pxHeight);
|
|
7
7
|
if (snapAmount) {
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { type LayoutChange, type LayoutWindow } from "../types/index.js";
|
|
2
|
+
/**
|
|
3
|
+
*
|
|
4
|
+
* Most actions that change the layout will return a LayoutChange object without mutating the window.
|
|
5
|
+
*
|
|
6
|
+
* This function applies the changes returned by them.
|
|
7
|
+
*
|
|
8
|
+
* Mutates the frame positions in the window given.
|
|
9
|
+
*/
|
|
10
|
+
export declare function applyFrameChanges(win: LayoutWindow, change: LayoutChange<any>): void;
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { LAYOUT_ERROR } from "../types/index.js";
|
|
2
|
+
import { KnownError } from "../utils/KnownError.js";
|
|
3
|
+
export function applyFrameChanges(win, change) {
|
|
4
|
+
for (const frame of change.modified) {
|
|
5
|
+
const target = win.frames[frame.id];
|
|
6
|
+
if (!target) {
|
|
7
|
+
throw new KnownError(LAYOUT_ERROR.INVALID_ID, `Frame ${frame.id} not found in window ${win.id}`, { id: frame.id });
|
|
8
|
+
}
|
|
9
|
+
if ("docked" in frame) {
|
|
10
|
+
target.docked = frame.docked;
|
|
11
|
+
}
|
|
12
|
+
if ("collapsed" in frame) {
|
|
13
|
+
target.collapsed = frame.collapsed;
|
|
14
|
+
}
|
|
15
|
+
target.x = frame.x;
|
|
16
|
+
target.y = frame.y;
|
|
17
|
+
target.width = frame.width;
|
|
18
|
+
target.height = frame.height;
|
|
19
|
+
}
|
|
20
|
+
for (const frame of change.created) {
|
|
21
|
+
if (win.frames[frame.id]) {
|
|
22
|
+
throw new KnownError(LAYOUT_ERROR.ID_ALREADY_EXISTS, `Frame ${frame.id} already exists in window ${win.id}`, { id: frame.id });
|
|
23
|
+
}
|
|
24
|
+
win.frames[frame.id] = frame;
|
|
25
|
+
}
|
|
26
|
+
for (const frame of change.deleted) {
|
|
27
|
+
delete win.frames[frame.id];
|
|
28
|
+
}
|
|
29
|
+
}
|
|
@@ -1,2 +1,7 @@
|
|
|
1
1
|
import type { Direction, LayoutFrame, Point, Size, SplitDeco } from "../types/index.js";
|
|
2
|
-
export declare function createSplitDecoFromDrag(frames: Record<string, LayoutFrame>, frame: LayoutFrame, dragDirection: Direction, dragPoint: Point, snapAmount?: Point, minSize?: Size
|
|
2
|
+
export declare function createSplitDecoFromDrag(frames: Record<string, LayoutFrame>, frame: LayoutFrame, dragDirection: Direction, dragPoint: Point, snapAmount?: Point, minSize?: Size, classes?: {
|
|
3
|
+
/** @default "deco-split-edge bg-red-500" */
|
|
4
|
+
splitEdge?: string;
|
|
5
|
+
/** @default "deco-split-new-frame bg-blue-500/50" */
|
|
6
|
+
splitNewFrame?: string;
|
|
7
|
+
}): SplitDeco;
|