@witchcraft/layout 0.4.2 → 0.4.3
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/LayoutDragEdgeGrabbed.vue +1 -1
- package/dist/runtime/components/LayoutDragEdgeHandle.vue +1 -2
- package/dist/runtime/components/LayoutWindow.d.vue.ts +3 -0
- package/dist/runtime/components/LayoutWindow.vue +3 -2
- package/dist/runtime/components/LayoutWindow.vue.d.ts +3 -0
- package/dist/runtime/composables/useFrames.d.ts +1 -0
- package/dist/runtime/composables/useFrames.js +12 -0
- package/dist/runtime/drag/CloseAction.d.ts +3 -0
- package/dist/runtime/drag/CloseAction.js +5 -0
- package/dist/runtime/drag/FrameDragAction.d.ts +3 -0
- package/dist/runtime/drag/FrameDragAction.js +5 -0
- package/dist/runtime/drag/SplitAction.d.ts +3 -0
- package/dist/runtime/drag/SplitAction.js +8 -3
- package/dist/runtime/settings.js +1 -1
- package/dist/runtime/types/index.d.ts +2 -0
- package/package.json +1 -1
- package/src/runtime/components/LayoutDragEdgeGrabbed.vue +1 -1
- package/src/runtime/components/LayoutDragEdgeHandle.vue +1 -2
- package/src/runtime/components/LayoutWindow.vue +6 -4
- package/src/runtime/composables/useFrames.ts +15 -0
- package/src/runtime/drag/CloseAction.ts +7 -0
- package/src/runtime/drag/FrameDragAction.ts +9 -0
- package/src/runtime/drag/SplitAction.ts +11 -3
- package/src/runtime/settings.ts +1 -1
- package/src/runtime/types/index.ts +2 -0
package/dist/module.json
CHANGED
|
@@ -3,6 +3,8 @@ import { type DragState, type IDragAction } from "../types/index.js";
|
|
|
3
3
|
import { getUpdateWindowSizeInfo } from "../layout/getUpdateWindowSizeInfo.js";
|
|
4
4
|
import { type LayoutWindow } from "../types/index.js";
|
|
5
5
|
type __VLS_Props = {
|
|
6
|
+
/** If you really need it, you can provide your own drag action handler, note the actionHandler's prop will no longer have any effect.*/
|
|
7
|
+
dragActionHandler?: DragActionHandler<any, any>;
|
|
6
8
|
/** Custom drag action handlers. Falls back to default split/close/frame handlers if not provided. */
|
|
7
9
|
actionHandlers?: IDragAction[];
|
|
8
10
|
textHints?: {
|
|
@@ -41,6 +43,7 @@ declare const __VLS_component: import("vue").DefineComponent<__VLS_PublicProps,
|
|
|
41
43
|
x: number;
|
|
42
44
|
y: number;
|
|
43
45
|
} | undefined;
|
|
46
|
+
dragDistance: number;
|
|
44
47
|
isDragging: false | "edge" | "frame";
|
|
45
48
|
showDragging: boolean;
|
|
46
49
|
draggingFrameId: string | undefined;
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
flex
|
|
8
8
|
flex-col
|
|
9
9
|
`,
|
|
10
|
-
isDragging && `dragging cursor-pointer`,
|
|
10
|
+
isDragging && `dragging cursor-pointer user-select-none`,
|
|
11
11
|
requestType && `request-${requestType}`,
|
|
12
12
|
$attrs.class
|
|
13
13
|
)"
|
|
@@ -82,6 +82,7 @@ import { applyFrameChanges } from "../layout/applyFrameChanges.js";
|
|
|
82
82
|
const $attrs = useAttrs();
|
|
83
83
|
const win = defineModel("win", { type: Object, ...{ required: true } });
|
|
84
84
|
const props = defineProps({
|
|
85
|
+
dragActionHandler: { type: Object, required: false },
|
|
85
86
|
actionHandlers: { type: Array, required: false, default: void 0 },
|
|
86
87
|
textHints: { type: Array, required: false, default: () => [] },
|
|
87
88
|
textHintsTeleportTo: { type: null, required: true, default: void 0 },
|
|
@@ -91,7 +92,7 @@ const props = defineProps({
|
|
|
91
92
|
const emit = defineEmits(["isShowingDrag", "dragState"]);
|
|
92
93
|
const windowEl = ref(null);
|
|
93
94
|
const requestType = ref();
|
|
94
|
-
const dragActionHandler = new DragActionHandler(
|
|
95
|
+
const dragActionHandler = props.dragActionHandler ?? new DragActionHandler(
|
|
95
96
|
[
|
|
96
97
|
...props.actionHandlers ?? createDefaultHandlers()
|
|
97
98
|
],
|
|
@@ -3,6 +3,8 @@ import { type DragState, type IDragAction } from "../types/index.js";
|
|
|
3
3
|
import { getUpdateWindowSizeInfo } from "../layout/getUpdateWindowSizeInfo.js";
|
|
4
4
|
import { type LayoutWindow } from "../types/index.js";
|
|
5
5
|
type __VLS_Props = {
|
|
6
|
+
/** If you really need it, you can provide your own drag action handler, note the actionHandler's prop will no longer have any effect.*/
|
|
7
|
+
dragActionHandler?: DragActionHandler<any, any>;
|
|
6
8
|
/** Custom drag action handlers. Falls back to default split/close/frame handlers if not provided. */
|
|
7
9
|
actionHandlers?: IDragAction[];
|
|
8
10
|
textHints?: {
|
|
@@ -41,6 +43,7 @@ declare const __VLS_component: import("vue").DefineComponent<__VLS_PublicProps,
|
|
|
41
43
|
x: number;
|
|
42
44
|
y: number;
|
|
43
45
|
} | undefined;
|
|
46
|
+
dragDistance: number;
|
|
44
47
|
isDragging: false | "edge" | "frame";
|
|
45
48
|
showDragging: boolean;
|
|
46
49
|
draggingFrameId: string | undefined;
|
|
@@ -27,6 +27,8 @@ export function useFrames(win, handler) {
|
|
|
27
27
|
const showDragging = ref(false);
|
|
28
28
|
const dragPoint = ref();
|
|
29
29
|
const dragDirections = ref({});
|
|
30
|
+
let dragStartPoint;
|
|
31
|
+
const dragDistance = ref(-1);
|
|
30
32
|
const draggingIntersection = ref(void 0);
|
|
31
33
|
const isDraggingFromWindowEdge = ref(false);
|
|
32
34
|
const frameDragFrameId = ref();
|
|
@@ -64,6 +66,7 @@ export function useFrames(win, handler) {
|
|
|
64
66
|
const state = computed(() => ({
|
|
65
67
|
dragDirections: dragDirections.value,
|
|
66
68
|
dragPoint: dragPoint.value,
|
|
69
|
+
dragDistance: dragDistance.value,
|
|
67
70
|
isDragging: isDragging.value,
|
|
68
71
|
showDragging: showDragging.value,
|
|
69
72
|
draggingFrameId: frameDragFrameId.value,
|
|
@@ -80,10 +83,12 @@ export function useFrames(win, handler) {
|
|
|
80
83
|
}));
|
|
81
84
|
let controller;
|
|
82
85
|
function resetState() {
|
|
86
|
+
dragStartPoint = void 0;
|
|
83
87
|
draggingEdges.value = [];
|
|
84
88
|
draggingIntersection.value = void 0;
|
|
85
89
|
isDragging.value = false;
|
|
86
90
|
dragPoint.value = void 0;
|
|
91
|
+
dragDistance.value = -1;
|
|
87
92
|
touchingFrames.value = [];
|
|
88
93
|
frameDragFrameId.value = void 0;
|
|
89
94
|
dragDirStore.reset();
|
|
@@ -98,6 +103,7 @@ export function useFrames(win, handler) {
|
|
|
98
103
|
window.addEventListener("pointerup", dragEnd, { signal: controller.signal });
|
|
99
104
|
const point = toWindowCoord(win.value, e);
|
|
100
105
|
dragPoint.value = point;
|
|
106
|
+
dragStartPoint = { ...point };
|
|
101
107
|
dragDirStore.update(point);
|
|
102
108
|
isDragging.value = type;
|
|
103
109
|
showDragging.value = true;
|
|
@@ -136,6 +142,12 @@ export function useFrames(win, handler) {
|
|
|
136
142
|
const point = toWindowCoord(win.value, e);
|
|
137
143
|
const didChange = dragDirStore.update(point);
|
|
138
144
|
dragPoint.value = point;
|
|
145
|
+
dragDistance.value = 0;
|
|
146
|
+
if (dragStartPoint) {
|
|
147
|
+
dragDistance.value = Math.sqrt(
|
|
148
|
+
Math.pow(point.x - dragStartPoint.x, 2) + Math.pow(point.y - dragStartPoint.y, 2)
|
|
149
|
+
);
|
|
150
|
+
}
|
|
139
151
|
if (!didChange) return;
|
|
140
152
|
const res = handler.onDragChange("move", e, state.value, forceRecalculateEdges, cancel);
|
|
141
153
|
showDragging.value = res.showDragging ?? true;
|
|
@@ -4,6 +4,7 @@ import type { KnownError } from "../utils/KnownError.js";
|
|
|
4
4
|
export type CloseInfo = Exclude<ReturnType<typeof getCloseFrameInfo>, KnownError>;
|
|
5
5
|
export declare class CloseAction implements IDragAction {
|
|
6
6
|
name: "close";
|
|
7
|
+
minDragDistance: number;
|
|
7
8
|
state: {
|
|
8
9
|
allowed: true;
|
|
9
10
|
force: boolean;
|
|
@@ -40,6 +41,8 @@ export declare class CloseAction implements IDragAction {
|
|
|
40
41
|
modifyDecos?: CloseAction["modifyDecos"], hooks?: CloseAction["hooks"], config?: {
|
|
41
42
|
debug?: boolean | string;
|
|
42
43
|
closeHints?: Partial<CloseAction["closeHints"]>;
|
|
44
|
+
/** Minimum pixel distance the user must drag before the action is allowed (decos shown and action applied). Defaults to 5. */
|
|
45
|
+
minDragDistance?: number;
|
|
43
46
|
});
|
|
44
47
|
reset(): void;
|
|
45
48
|
private _getDecos;
|
|
@@ -7,6 +7,7 @@ import { findFramesTouchingEdge } from "../layout/findFramesTouchingEdge.js";
|
|
|
7
7
|
import { getCloseFrameInfo } from "../layout/getCloseFrameInfo.js";
|
|
8
8
|
export class CloseAction {
|
|
9
9
|
name = "close";
|
|
10
|
+
minDragDistance = 5;
|
|
10
11
|
state = {};
|
|
11
12
|
// this is initialized by this.reset()
|
|
12
13
|
debug = false;
|
|
@@ -30,6 +31,7 @@ export class CloseAction {
|
|
|
30
31
|
if (modifyDecos !== void 0) this.modifyDecos = modifyDecos;
|
|
31
32
|
this.hooks = hooks;
|
|
32
33
|
if (config?.debug) this.debug = true;
|
|
34
|
+
if (config?.minDragDistance !== void 0) this.minDragDistance = config.minDragDistance;
|
|
33
35
|
this.reset();
|
|
34
36
|
}
|
|
35
37
|
reset() {
|
|
@@ -97,6 +99,9 @@ export class CloseAction {
|
|
|
97
99
|
return false;
|
|
98
100
|
}
|
|
99
101
|
onDragChange(_type, _e, state) {
|
|
102
|
+
if (state.dragDistance <= this.minDragDistance) {
|
|
103
|
+
return { updateEdges: false, shapes: [] };
|
|
104
|
+
}
|
|
100
105
|
const {
|
|
101
106
|
touchingFramesArrays,
|
|
102
107
|
dragDirections,
|
|
@@ -2,6 +2,7 @@ import type { ActionDragChangeResult, DragState, DragZone, FrameDragDeco, IDragA
|
|
|
2
2
|
import type { KnownError } from "../utils/KnownError.js";
|
|
3
3
|
export declare class FrameDragAction implements IDragAction {
|
|
4
4
|
name: "frameDrag";
|
|
5
|
+
minDragDistance: number;
|
|
5
6
|
state: {
|
|
6
7
|
lastReturn?: LayoutChange<"split" | "swap" | "rearrange" | "dock"> | KnownError;
|
|
7
8
|
};
|
|
@@ -32,6 +33,8 @@ export declare class FrameDragAction implements IDragAction {
|
|
|
32
33
|
/** Modify the created decos before they are rendered. */
|
|
33
34
|
modifyDecos?: FrameDragAction["modifyDecos"], hooks?: FrameDragAction["hooks"], config?: {
|
|
34
35
|
debug?: boolean | string;
|
|
36
|
+
/** Minimum pixel distance the user must drag before the action is allowed (decos shown and action applied). Defaults to 5. */
|
|
37
|
+
minDragDistance?: number;
|
|
35
38
|
});
|
|
36
39
|
reset(): void;
|
|
37
40
|
setTextHints(result: LayoutChange<"split" | "swap" | "rearrange" | "dock"> | KnownError | undefined): void;
|
|
@@ -8,6 +8,7 @@ import { getFrameSwapInfo } from "../layout/getFrameSwapInfo.js";
|
|
|
8
8
|
import { settings } from "../settings.js";
|
|
9
9
|
export class FrameDragAction {
|
|
10
10
|
name = "frameDrag";
|
|
11
|
+
minDragDistance = 5;
|
|
11
12
|
state = {
|
|
12
13
|
lastReturn: void 0
|
|
13
14
|
};
|
|
@@ -31,6 +32,7 @@ export class FrameDragAction {
|
|
|
31
32
|
if (modifyDecos !== void 0) this.modifyDecos = modifyDecos;
|
|
32
33
|
this.hooks = hooks;
|
|
33
34
|
if (config?.debug) this.debug = true;
|
|
35
|
+
if (config?.minDragDistance !== void 0) this.minDragDistance = config.minDragDistance;
|
|
34
36
|
this.reset();
|
|
35
37
|
}
|
|
36
38
|
reset() {
|
|
@@ -92,6 +94,9 @@ export class FrameDragAction {
|
|
|
92
94
|
return false;
|
|
93
95
|
}
|
|
94
96
|
onDragChange(_type, _e, state) {
|
|
97
|
+
if (state.dragDistance <= this.minDragDistance) {
|
|
98
|
+
return { updateEdges: false, shapes: [], showDragging: false };
|
|
99
|
+
}
|
|
95
100
|
const { win, draggingFrameId, dragHoveredFrame } = state;
|
|
96
101
|
const matchedZone = getDragZones(state, settings.zoneSizes);
|
|
97
102
|
if (!matchedZone) {
|
|
@@ -5,6 +5,7 @@ export type SplitInfo = Exclude<ReturnType<typeof getFrameSplitInfo>, KnownError
|
|
|
5
5
|
export type DragChangeType = "start" | "move" | "end";
|
|
6
6
|
export declare class SplitAction implements IDragAction {
|
|
7
7
|
name: "split";
|
|
8
|
+
minDragDistance: number;
|
|
8
9
|
state: {
|
|
9
10
|
allowed: true;
|
|
10
11
|
res: SplitInfo;
|
|
@@ -37,6 +38,8 @@ export declare class SplitAction implements IDragAction {
|
|
|
37
38
|
modifyDecos?: SplitAction["modifyDecos"], hooks?: SplitAction["hooks"], config?: {
|
|
38
39
|
debug?: boolean | string;
|
|
39
40
|
splitHints?: Partial<SplitAction["splitHints"]>;
|
|
41
|
+
/** Minimum pixel distance the user must drag before the action is allowed (decos shown and action applied). Defaults to 5. */
|
|
42
|
+
minDragDistance?: number;
|
|
40
43
|
});
|
|
41
44
|
reset(): void;
|
|
42
45
|
getDecos(state: DragState): SplitDeco[];
|
|
@@ -6,6 +6,7 @@ import { createSplitDecoFromDrag } from "../layout/createSplitDecoFromDrag.js";
|
|
|
6
6
|
import { getFrameSplitInfo } from "../layout/getFrameSplitInfo.js";
|
|
7
7
|
export class SplitAction {
|
|
8
8
|
name = "split";
|
|
9
|
+
minDragDistance = 5;
|
|
9
10
|
state = {};
|
|
10
11
|
// this is initialized by `this.reset()`
|
|
11
12
|
debug = false;
|
|
@@ -24,6 +25,7 @@ export class SplitAction {
|
|
|
24
25
|
this.hooks = hooks;
|
|
25
26
|
this.reset();
|
|
26
27
|
if (config?.debug) this.debug = true;
|
|
28
|
+
if (config?.minDragDistance !== void 0) this.minDragDistance = config.minDragDistance;
|
|
27
29
|
if (config?.splitHints?.actions) this.splitHints.actions = config.splitHints.actions;
|
|
28
30
|
if (config?.splitHints?.transformError) this.splitHints.transformError = config.splitHints.transformError;
|
|
29
31
|
}
|
|
@@ -62,7 +64,7 @@ export class SplitAction {
|
|
|
62
64
|
canHandleRequest(e, state) {
|
|
63
65
|
const { draggingEdges } = state;
|
|
64
66
|
if (draggingEdges.length !== 1) return false;
|
|
65
|
-
this.setTextHints(state.isDragging === "edge" ? true : void 0);
|
|
67
|
+
this.setTextHints(state.isDragging === "edge" && !state.isDraggingFromWindowEdge ? true : void 0);
|
|
66
68
|
if (this.handleEvent(e, state)) {
|
|
67
69
|
this.hooks.onStart?.();
|
|
68
70
|
return true;
|
|
@@ -103,7 +105,7 @@ export class SplitAction {
|
|
|
103
105
|
dragDirections[oppositeOrientation],
|
|
104
106
|
dragPoint
|
|
105
107
|
);
|
|
106
|
-
this.setTextHints(canSplit);
|
|
108
|
+
this.setTextHints(state.isDragging === "edge" && !state.isDraggingFromWindowEdge ? canSplit : void 0);
|
|
107
109
|
if (!(canSplit instanceof Error)) {
|
|
108
110
|
this.state.allowed = true;
|
|
109
111
|
this.state.res = canSplit;
|
|
@@ -117,7 +119,10 @@ export class SplitAction {
|
|
|
117
119
|
}
|
|
118
120
|
}
|
|
119
121
|
onDragChange(_type, _e, state) {
|
|
120
|
-
const { dragHoveredFrame } = state;
|
|
122
|
+
const { dragHoveredFrame, dragDistance } = state;
|
|
123
|
+
if (dragDistance <= this.minDragDistance) {
|
|
124
|
+
return { updateEdges: false, shapes: [], showDragging: false };
|
|
125
|
+
}
|
|
121
126
|
let ok = false;
|
|
122
127
|
if (dragHoveredFrame) {
|
|
123
128
|
if (this.state.lastPoint?.x === state.dragPoint?.x && this.state.lastPoint?.y === state.dragPoint?.y && this.state.lastReturn) {
|
package/dist/runtime/settings.js
CHANGED
|
@@ -1808,6 +1808,8 @@ export type DragState = {
|
|
|
1808
1808
|
dragDirections: Record<Orientation, Direction | undefined>;
|
|
1809
1809
|
/** The curren point (in scaled window coordinates) the user is dragging at. */
|
|
1810
1810
|
dragPoint?: Point;
|
|
1811
|
+
/** Cumulative pixel distance the user has dragged from the initial click point. 0 on start, increases on each move. */
|
|
1812
|
+
dragDistance: number;
|
|
1811
1813
|
/** Whether the user is currently dragging and what type of drag. Is truthy string during all drag events. */
|
|
1812
1814
|
isDragging: boolean | "frame" | "edge";
|
|
1813
1815
|
/** Whether to show the moved frames while dragging. */
|
package/package.json
CHANGED
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
flex
|
|
8
8
|
flex-col
|
|
9
9
|
`,
|
|
10
|
-
isDragging && `dragging cursor-pointer`,
|
|
10
|
+
isDragging && `dragging cursor-pointer user-select-none`,
|
|
11
11
|
requestType && `request-${requestType}`,
|
|
12
12
|
($attrs as any).class
|
|
13
13
|
)"
|
|
@@ -90,6 +90,8 @@ const $attrs = useAttrs()
|
|
|
90
90
|
const win = defineModel<LayoutWindow>("win", { required: true })
|
|
91
91
|
|
|
92
92
|
const props = withDefaults(defineProps<{
|
|
93
|
+
/** If you really need it, you can provide your own drag action handler, note the actionHandler's prop will no longer have any effect.*/
|
|
94
|
+
dragActionHandler?: DragActionHandler<any, any>
|
|
93
95
|
/** Custom drag action handlers. Falls back to default split/close/frame handlers if not provided. */
|
|
94
96
|
actionHandlers?: IDragAction[]
|
|
95
97
|
textHints?: {text:string, classes?:string}[]
|
|
@@ -120,9 +122,9 @@ const windowEl = ref<HTMLElement | null>(null)
|
|
|
120
122
|
|
|
121
123
|
const requestType = ref<string | undefined | string>()
|
|
122
124
|
|
|
123
|
-
const dragActionHandler = new DragActionHandler(
|
|
125
|
+
const dragActionHandler = props.dragActionHandler ?? new DragActionHandler(
|
|
124
126
|
[
|
|
125
|
-
...(props.actionHandlers ?? createDefaultHandlers())
|
|
127
|
+
...(props.actionHandlers ?? createDefaultHandlers())
|
|
126
128
|
],
|
|
127
129
|
{
|
|
128
130
|
onEvent: (e, cancel) => {
|
|
@@ -132,7 +134,7 @@ const dragActionHandler = new DragActionHandler(
|
|
|
132
134
|
}
|
|
133
135
|
},
|
|
134
136
|
onRequestChange: type => {
|
|
135
|
-
requestType.value = type
|
|
137
|
+
requestType.value = type as any
|
|
136
138
|
},
|
|
137
139
|
onEnd: () => {
|
|
138
140
|
requestType.value = undefined
|
|
@@ -59,6 +59,9 @@ export function useFrames(
|
|
|
59
59
|
|
|
60
60
|
const dragDirections = ref<Record<Orientation, Direction | undefined>>({} as any)
|
|
61
61
|
|
|
62
|
+
let dragStartPoint: Point | undefined
|
|
63
|
+
const dragDistance = ref(-1)
|
|
64
|
+
|
|
62
65
|
const draggingIntersection = ref<IntersectionEntry | undefined>(undefined)
|
|
63
66
|
const isDraggingFromWindowEdge = ref<boolean>(false)
|
|
64
67
|
|
|
@@ -110,6 +113,7 @@ export function useFrames(
|
|
|
110
113
|
const state = computed(() => ({
|
|
111
114
|
dragDirections: dragDirections.value,
|
|
112
115
|
dragPoint: dragPoint.value,
|
|
116
|
+
dragDistance: dragDistance.value,
|
|
113
117
|
isDragging: isDragging.value,
|
|
114
118
|
showDragging: showDragging.value,
|
|
115
119
|
draggingFrameId: frameDragFrameId.value,
|
|
@@ -128,10 +132,13 @@ export function useFrames(
|
|
|
128
132
|
let controller: AbortController
|
|
129
133
|
|
|
130
134
|
function resetState(): void {
|
|
135
|
+
dragStartPoint = undefined
|
|
136
|
+
|
|
131
137
|
draggingEdges.value = []
|
|
132
138
|
draggingIntersection.value = undefined
|
|
133
139
|
isDragging.value = false
|
|
134
140
|
dragPoint.value = undefined
|
|
141
|
+
dragDistance.value = -1
|
|
135
142
|
touchingFrames.value = []
|
|
136
143
|
frameDragFrameId.value = undefined
|
|
137
144
|
dragDirStore.reset()
|
|
@@ -154,6 +161,7 @@ export function useFrames(
|
|
|
154
161
|
|
|
155
162
|
const point = toWindowCoord(win.value, e)
|
|
156
163
|
dragPoint.value = point
|
|
164
|
+
dragStartPoint = { ...point }
|
|
157
165
|
dragDirStore.update(point)
|
|
158
166
|
|
|
159
167
|
isDragging.value = type
|
|
@@ -205,6 +213,13 @@ export function useFrames(
|
|
|
205
213
|
const point = toWindowCoord(win.value, e)
|
|
206
214
|
const didChange = dragDirStore.update(point)
|
|
207
215
|
dragPoint.value = point
|
|
216
|
+
// at least one drag move has happened
|
|
217
|
+
dragDistance.value = 0
|
|
218
|
+
if (dragStartPoint) {
|
|
219
|
+
dragDistance.value = Math.sqrt(
|
|
220
|
+
Math.pow(point.x - dragStartPoint.x, 2) + Math.pow(point.y - dragStartPoint.y, 2)
|
|
221
|
+
)
|
|
222
|
+
}
|
|
208
223
|
if (!didChange) return
|
|
209
224
|
const res = handler.onDragChange("move", e, state.value, forceRecalculateEdges, cancel)
|
|
210
225
|
|
|
@@ -13,6 +13,7 @@ export type CloseInfo = Exclude<ReturnType<typeof getCloseFrameInfo>, KnownError
|
|
|
13
13
|
|
|
14
14
|
export class CloseAction implements IDragAction {
|
|
15
15
|
name = "close" as const
|
|
16
|
+
minDragDistance = 5
|
|
16
17
|
|
|
17
18
|
state: {
|
|
18
19
|
allowed: true
|
|
@@ -62,12 +63,15 @@ export class CloseAction implements IDragAction {
|
|
|
62
63
|
config?: {
|
|
63
64
|
debug?: boolean | string
|
|
64
65
|
closeHints?: Partial<CloseAction["closeHints"]>
|
|
66
|
+
/** Minimum pixel distance the user must drag before the action is allowed (decos shown and action applied). Defaults to 5. */
|
|
67
|
+
minDragDistance?: number
|
|
65
68
|
}
|
|
66
69
|
) {
|
|
67
70
|
if (handleEvent !== undefined) this.handleEvent = handleEvent
|
|
68
71
|
if (modifyDecos !== undefined) this.modifyDecos = modifyDecos
|
|
69
72
|
this.hooks = hooks
|
|
70
73
|
if (config?.debug) this.debug = true
|
|
74
|
+
if (config?.minDragDistance !== undefined) this.minDragDistance = config.minDragDistance
|
|
71
75
|
this.reset()
|
|
72
76
|
}
|
|
73
77
|
|
|
@@ -151,6 +155,9 @@ export class CloseAction implements IDragAction {
|
|
|
151
155
|
_e: PointerEvent | undefined,
|
|
152
156
|
state: DragState
|
|
153
157
|
): ActionDragChangeResult {
|
|
158
|
+
if (state.dragDistance <= this.minDragDistance) {
|
|
159
|
+
return { updateEdges: false, shapes: [] }
|
|
160
|
+
}
|
|
154
161
|
const {
|
|
155
162
|
touchingFramesArrays,
|
|
156
163
|
dragDirections,
|
|
@@ -13,6 +13,9 @@ import type { KnownError } from "../utils/KnownError.js"
|
|
|
13
13
|
|
|
14
14
|
export class FrameDragAction implements IDragAction {
|
|
15
15
|
name = "frameDrag" as const
|
|
16
|
+
|
|
17
|
+
minDragDistance = 5
|
|
18
|
+
|
|
16
19
|
state: {
|
|
17
20
|
lastReturn?: LayoutChange<"split" | "swap" | "rearrange" | "dock"> | KnownError
|
|
18
21
|
} = {
|
|
@@ -52,12 +55,15 @@ export class FrameDragAction implements IDragAction {
|
|
|
52
55
|
hooks: FrameDragAction["hooks"] = {},
|
|
53
56
|
config?: {
|
|
54
57
|
debug?: boolean | string
|
|
58
|
+
/** Minimum pixel distance the user must drag before the action is allowed (decos shown and action applied). Defaults to 5. */
|
|
59
|
+
minDragDistance?: number
|
|
55
60
|
}
|
|
56
61
|
) {
|
|
57
62
|
if (handleEvent !== undefined) this.handleEvent = handleEvent
|
|
58
63
|
if (modifyDecos !== undefined) this.modifyDecos = modifyDecos
|
|
59
64
|
this.hooks = hooks
|
|
60
65
|
if (config?.debug) this.debug = true
|
|
66
|
+
if (config?.minDragDistance !== undefined) this.minDragDistance = config.minDragDistance
|
|
61
67
|
|
|
62
68
|
this.reset()
|
|
63
69
|
}
|
|
@@ -149,6 +155,9 @@ export class FrameDragAction implements IDragAction {
|
|
|
149
155
|
_e: PointerEvent | undefined,
|
|
150
156
|
state: DragState
|
|
151
157
|
): ActionDragChangeResult {
|
|
158
|
+
if (state.dragDistance <= this.minDragDistance) {
|
|
159
|
+
return { updateEdges: false, shapes: [], showDragging: false }
|
|
160
|
+
}
|
|
152
161
|
const { win, draggingFrameId, dragHoveredFrame } = state
|
|
153
162
|
const matchedZone = getDragZones(state, settings.zoneSizes)
|
|
154
163
|
|
|
@@ -16,6 +16,7 @@ export type DragChangeType = "start" | "move" | "end"
|
|
|
16
16
|
|
|
17
17
|
export class SplitAction implements IDragAction {
|
|
18
18
|
name = "split" as const
|
|
19
|
+
minDragDistance = 5
|
|
19
20
|
|
|
20
21
|
state: {
|
|
21
22
|
allowed: true
|
|
@@ -57,6 +58,8 @@ export class SplitAction implements IDragAction {
|
|
|
57
58
|
config?: {
|
|
58
59
|
debug?: boolean | string
|
|
59
60
|
splitHints?: Partial<SplitAction["splitHints"]>
|
|
61
|
+
/** Minimum pixel distance the user must drag before the action is allowed (decos shown and action applied). Defaults to 5. */
|
|
62
|
+
minDragDistance?: number
|
|
60
63
|
}
|
|
61
64
|
) {
|
|
62
65
|
if (handleEvent !== undefined) this.handleEvent = handleEvent
|
|
@@ -65,6 +68,7 @@ export class SplitAction implements IDragAction {
|
|
|
65
68
|
this.hooks = hooks
|
|
66
69
|
this.reset()
|
|
67
70
|
if (config?.debug) this.debug = true
|
|
71
|
+
if (config?.minDragDistance !== undefined) this.minDragDistance = config.minDragDistance
|
|
68
72
|
if (config?.splitHints?.actions) this.splitHints.actions = config.splitHints.actions
|
|
69
73
|
if (config?.splitHints?.transformError) this.splitHints.transformError = config.splitHints.transformError
|
|
70
74
|
}
|
|
@@ -106,7 +110,8 @@ export class SplitAction implements IDragAction {
|
|
|
106
110
|
canHandleRequest(e: PointerEvent | KeyboardEvent, state: DragState): boolean {
|
|
107
111
|
const { draggingEdges } = state
|
|
108
112
|
if (draggingEdges.length !== 1) return false
|
|
109
|
-
|
|
113
|
+
// hint should not be shown when dragging from window edge but we should still handle the event
|
|
114
|
+
this.setTextHints(state.isDragging === "edge" && !state.isDraggingFromWindowEdge ? true : undefined)
|
|
110
115
|
if (this.handleEvent(e, state)) {
|
|
111
116
|
this.hooks.onStart?.()
|
|
112
117
|
return true
|
|
@@ -154,7 +159,7 @@ export class SplitAction implements IDragAction {
|
|
|
154
159
|
dragDirections[oppositeOrientation]!,
|
|
155
160
|
dragPoint!
|
|
156
161
|
)
|
|
157
|
-
this.setTextHints(canSplit)
|
|
162
|
+
this.setTextHints(state.isDragging === "edge" && !state.isDraggingFromWindowEdge ? canSplit : undefined)
|
|
158
163
|
if (!(canSplit instanceof Error)) {
|
|
159
164
|
this.state.allowed = true
|
|
160
165
|
this.state.res = canSplit
|
|
@@ -173,7 +178,10 @@ export class SplitAction implements IDragAction {
|
|
|
173
178
|
_e: PointerEvent | undefined,
|
|
174
179
|
state: DragState
|
|
175
180
|
): ActionDragChangeResult {
|
|
176
|
-
const { dragHoveredFrame } = state
|
|
181
|
+
const { dragHoveredFrame, dragDistance } = state
|
|
182
|
+
if (dragDistance <= this.minDragDistance) {
|
|
183
|
+
return { updateEdges: false, shapes: [], showDragging: false }
|
|
184
|
+
}
|
|
177
185
|
let ok = false
|
|
178
186
|
if (dragHoveredFrame) {
|
|
179
187
|
if (this.state.lastPoint?.x === state.dragPoint?.x && this.state.lastPoint?.y === state.dragPoint?.y && this.state.lastReturn) {
|
package/src/runtime/settings.ts
CHANGED
|
@@ -442,6 +442,8 @@ export type DragState = {
|
|
|
442
442
|
dragDirections: Record<Orientation, Direction | undefined>
|
|
443
443
|
/** The curren point (in scaled window coordinates) the user is dragging at. */
|
|
444
444
|
dragPoint?: Point
|
|
445
|
+
/** Cumulative pixel distance the user has dragged from the initial click point. 0 on start, increases on each move. */
|
|
446
|
+
dragDistance: number
|
|
445
447
|
/** Whether the user is currently dragging and what type of drag. Is truthy string during all drag events. */
|
|
446
448
|
isDragging: boolean | "frame" | "edge"
|
|
447
449
|
/** Whether to show the moved frames while dragging. */
|