regular-layout 0.2.0 → 0.2.1
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/index.js +6 -6
- package/dist/index.js.map +3 -3
- package/dist/layout/calculate_edge.d.ts +2 -1
- package/dist/layout/calculate_intersect.d.ts +8 -2
- package/dist/layout/constants.d.ts +76 -38
- package/dist/layout/generate_grid.d.ts +2 -1
- package/dist/layout/generate_overlay.d.ts +1 -1
- package/dist/layout/redistribute_panel_sizes.d.ts +1 -1
- package/dist/regular-layout.d.ts +14 -0
- package/package.json +1 -1
- package/src/layout/calculate_edge.ts +23 -15
- package/src/layout/calculate_intersect.ts +9 -7
- package/src/layout/constants.ts +94 -38
- package/src/layout/generate_grid.ts +68 -24
- package/src/layout/generate_overlay.ts +4 -2
- package/src/layout/redistribute_panel_sizes.ts +10 -3
- package/src/layout/types.ts +1 -0
- package/src/regular-layout-frame.ts +8 -5
- package/src/regular-layout.ts +96 -33
- package/themes/lorax.css +2 -1
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
// ┃ * [Apache License 2.0](https://www.apache.org/licenses/LICENSE-2.0). * ┃
|
|
10
10
|
// ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛
|
|
11
11
|
|
|
12
|
-
import {
|
|
12
|
+
import { DEFAULT_PHYSICS, type Physics } from "./constants.ts";
|
|
13
13
|
import type { Layout } from "./types.ts";
|
|
14
14
|
|
|
15
15
|
interface GridCell {
|
|
@@ -20,10 +20,11 @@ interface GridCell {
|
|
|
20
20
|
rowEnd: number;
|
|
21
21
|
}
|
|
22
22
|
|
|
23
|
-
function dedupe_sort(result: number[], pos: number) {
|
|
23
|
+
function dedupe_sort(physics: Physics, result: number[], pos: number) {
|
|
24
24
|
if (
|
|
25
25
|
result.length === 0 ||
|
|
26
|
-
Math.abs(pos - result[result.length - 1]) >
|
|
26
|
+
Math.abs(pos - result[result.length - 1]) >
|
|
27
|
+
physics.GRID_TRACK_COLLAPSE_TOLERANCE
|
|
27
28
|
) {
|
|
28
29
|
result.push(pos);
|
|
29
30
|
}
|
|
@@ -31,9 +32,9 @@ function dedupe_sort(result: number[], pos: number) {
|
|
|
31
32
|
return result;
|
|
32
33
|
}
|
|
33
34
|
|
|
34
|
-
function dedupe_positions(positions: number[]): number[] {
|
|
35
|
+
function dedupe_positions(physics: Physics, positions: number[]): number[] {
|
|
35
36
|
const sorted = positions.sort((a, b) => a - b);
|
|
36
|
-
return sorted.reduce(dedupe_sort, []);
|
|
37
|
+
return sorted.reduce(dedupe_sort.bind(undefined, physics), []);
|
|
37
38
|
}
|
|
38
39
|
|
|
39
40
|
function collect_track_positions(
|
|
@@ -41,6 +42,7 @@ function collect_track_positions(
|
|
|
41
42
|
orientation: "horizontal" | "vertical",
|
|
42
43
|
start: number,
|
|
43
44
|
end: number,
|
|
45
|
+
physics: Physics,
|
|
44
46
|
): number[] {
|
|
45
47
|
if (panel.type === "child-panel") {
|
|
46
48
|
return [start, end];
|
|
@@ -59,6 +61,7 @@ function collect_track_positions(
|
|
|
59
61
|
orientation,
|
|
60
62
|
current,
|
|
61
63
|
next,
|
|
64
|
+
physics,
|
|
62
65
|
),
|
|
63
66
|
);
|
|
64
67
|
|
|
@@ -67,17 +70,21 @@ function collect_track_positions(
|
|
|
67
70
|
} else {
|
|
68
71
|
for (const child of panel.children) {
|
|
69
72
|
positions.push(
|
|
70
|
-
...collect_track_positions(child, orientation, start, end),
|
|
73
|
+
...collect_track_positions(child, orientation, start, end, physics),
|
|
71
74
|
);
|
|
72
75
|
}
|
|
73
76
|
}
|
|
74
77
|
|
|
75
|
-
return dedupe_positions(positions);
|
|
78
|
+
return dedupe_positions(physics, positions);
|
|
76
79
|
}
|
|
77
80
|
|
|
78
|
-
function find_track_index(
|
|
81
|
+
function find_track_index(
|
|
82
|
+
physics: Physics,
|
|
83
|
+
positions: number[],
|
|
84
|
+
value: number,
|
|
85
|
+
): number {
|
|
79
86
|
const index = positions.findIndex(
|
|
80
|
-
(pos) => Math.abs(pos - value) < GRID_TRACK_COLLAPSE_TOLERANCE,
|
|
87
|
+
(pos) => Math.abs(pos - value) < physics.GRID_TRACK_COLLAPSE_TOLERANCE,
|
|
81
88
|
);
|
|
82
89
|
|
|
83
90
|
return index === -1 ? 0 : index;
|
|
@@ -91,16 +98,17 @@ function build_cells(
|
|
|
91
98
|
colEnd: number,
|
|
92
99
|
rowStart: number,
|
|
93
100
|
rowEnd: number,
|
|
101
|
+
physics: Physics,
|
|
94
102
|
): GridCell[] {
|
|
95
103
|
if (panel.type === "child-panel") {
|
|
96
104
|
const selected = panel.selected ?? 0;
|
|
97
105
|
return [
|
|
98
106
|
{
|
|
99
107
|
child: panel.child[selected],
|
|
100
|
-
colStart: find_track_index(colPositions, colStart),
|
|
101
|
-
colEnd: find_track_index(colPositions, colEnd),
|
|
102
|
-
rowStart: find_track_index(rowPositions, rowStart),
|
|
103
|
-
rowEnd: find_track_index(rowPositions, rowEnd),
|
|
108
|
+
colStart: find_track_index(physics, colPositions, colStart),
|
|
109
|
+
colEnd: find_track_index(physics, colPositions, colEnd),
|
|
110
|
+
rowStart: find_track_index(physics, rowPositions, rowStart),
|
|
111
|
+
rowEnd: find_track_index(physics, rowPositions, rowEnd),
|
|
104
112
|
},
|
|
105
113
|
];
|
|
106
114
|
}
|
|
@@ -122,6 +130,7 @@ function build_cells(
|
|
|
122
130
|
next,
|
|
123
131
|
rowStart,
|
|
124
132
|
rowEnd,
|
|
133
|
+
physics,
|
|
125
134
|
),
|
|
126
135
|
);
|
|
127
136
|
} else {
|
|
@@ -134,6 +143,7 @@ function build_cells(
|
|
|
134
143
|
colEnd,
|
|
135
144
|
current,
|
|
136
145
|
next,
|
|
146
|
+
physics,
|
|
137
147
|
),
|
|
138
148
|
);
|
|
139
149
|
}
|
|
@@ -147,8 +157,13 @@ function build_cells(
|
|
|
147
157
|
const host_template = (rowTemplate: string, colTemplate: string) =>
|
|
148
158
|
`:host ::slotted(*){display:none}:host{display:grid;grid-template-rows:${rowTemplate};grid-template-columns:${colTemplate}}`;
|
|
149
159
|
|
|
150
|
-
const child_template = (
|
|
151
|
-
|
|
160
|
+
const child_template = (
|
|
161
|
+
physics: Physics,
|
|
162
|
+
slot: string,
|
|
163
|
+
rowPart: string,
|
|
164
|
+
colPart: string,
|
|
165
|
+
) =>
|
|
166
|
+
`:host ::slotted([${physics.CHILD_ATTRIBUTE_NAME}="${slot}"]){display:flex;grid-column:${colPart};grid-row:${rowPart}}`;
|
|
152
167
|
|
|
153
168
|
/**
|
|
154
169
|
* Generates CSS Grid styles to render a layout tree.
|
|
@@ -182,12 +197,15 @@ const child_template = (slot: string, rowPart: string, colPart: string) =>
|
|
|
182
197
|
*/
|
|
183
198
|
export function create_css_grid_layout(
|
|
184
199
|
layout: Layout,
|
|
185
|
-
round: boolean = false,
|
|
186
200
|
overlay?: [string, string],
|
|
201
|
+
physics: Physics = DEFAULT_PHYSICS,
|
|
187
202
|
): string {
|
|
188
203
|
if (layout.type === "child-panel") {
|
|
189
204
|
const selected = layout.selected ?? 0;
|
|
190
|
-
return
|
|
205
|
+
return [
|
|
206
|
+
host_template("100%", "100%"),
|
|
207
|
+
child_template(physics, layout.child[selected], "1", "1"),
|
|
208
|
+
].join("\n");
|
|
191
209
|
}
|
|
192
210
|
|
|
193
211
|
const createTemplate = (positions: number[]) => {
|
|
@@ -195,26 +213,52 @@ export function create_css_grid_layout(
|
|
|
195
213
|
.slice(0, -1)
|
|
196
214
|
.map((pos, i) => positions[i + 1] - pos);
|
|
197
215
|
return sizes
|
|
198
|
-
.map((s) => `${
|
|
216
|
+
.map((s) => `${physics.SHOULD_ROUND ? Math.round(s * 100) : s * 100}fr`)
|
|
199
217
|
.join(" ");
|
|
200
218
|
};
|
|
201
219
|
|
|
202
|
-
const colPositions = collect_track_positions(
|
|
220
|
+
const colPositions = collect_track_positions(
|
|
221
|
+
layout,
|
|
222
|
+
"horizontal",
|
|
223
|
+
0,
|
|
224
|
+
1,
|
|
225
|
+
physics,
|
|
226
|
+
);
|
|
227
|
+
|
|
203
228
|
const colTemplate = createTemplate(colPositions);
|
|
204
|
-
const rowPositions = collect_track_positions(
|
|
229
|
+
const rowPositions = collect_track_positions(
|
|
230
|
+
layout,
|
|
231
|
+
"vertical",
|
|
232
|
+
0,
|
|
233
|
+
1,
|
|
234
|
+
physics,
|
|
235
|
+
);
|
|
236
|
+
|
|
205
237
|
const rowTemplate = createTemplate(rowPositions);
|
|
206
238
|
const formatGridLine = (start: number, end: number) =>
|
|
207
239
|
end - start === 1 ? `${start + 1}` : `${start + 1} / ${end + 1}`;
|
|
208
240
|
|
|
209
|
-
const cells = build_cells(
|
|
241
|
+
const cells = build_cells(
|
|
242
|
+
layout,
|
|
243
|
+
colPositions,
|
|
244
|
+
rowPositions,
|
|
245
|
+
0,
|
|
246
|
+
1,
|
|
247
|
+
0,
|
|
248
|
+
1,
|
|
249
|
+
physics,
|
|
250
|
+
);
|
|
251
|
+
|
|
210
252
|
const css = [host_template(rowTemplate, colTemplate)];
|
|
211
253
|
for (const cell of cells) {
|
|
212
254
|
const colPart = formatGridLine(cell.colStart, cell.colEnd);
|
|
213
255
|
const rowPart = formatGridLine(cell.rowStart, cell.rowEnd);
|
|
214
|
-
css.push(child_template(cell.child, rowPart, colPart));
|
|
256
|
+
css.push(child_template(physics, cell.child, rowPart, colPart));
|
|
215
257
|
if (cell.child === overlay?.[1]) {
|
|
216
|
-
css.push(child_template(overlay[0], rowPart, colPart));
|
|
217
|
-
css.push(
|
|
258
|
+
css.push(child_template(physics, overlay[0], rowPart, colPart));
|
|
259
|
+
css.push(
|
|
260
|
+
`:host ::slotted([${physics.CHILD_ATTRIBUTE_NAME}=${overlay[0]}]){z-index:1}`,
|
|
261
|
+
);
|
|
218
262
|
}
|
|
219
263
|
}
|
|
220
264
|
|
|
@@ -9,6 +9,7 @@
|
|
|
9
9
|
// ┃ * [Apache License 2.0](https://www.apache.org/licenses/LICENSE-2.0). * ┃
|
|
10
10
|
// ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛
|
|
11
11
|
|
|
12
|
+
import { DEFAULT_PHYSICS } from "./constants";
|
|
12
13
|
import type { LayoutPath } from "./types";
|
|
13
14
|
|
|
14
15
|
export function updateOverlaySheet(
|
|
@@ -16,9 +17,10 @@ export function updateOverlaySheet(
|
|
|
16
17
|
box: DOMRect,
|
|
17
18
|
style: CSSStyleDeclaration,
|
|
18
19
|
drag_target: LayoutPath<undefined> | null,
|
|
20
|
+
physics = DEFAULT_PHYSICS,
|
|
19
21
|
) {
|
|
20
22
|
if (!drag_target) {
|
|
21
|
-
return `:host ::slotted([
|
|
23
|
+
return `:host ::slotted([${physics.CHILD_ATTRIBUTE_NAME}="${slot}"]){display:none;}`;
|
|
22
24
|
}
|
|
23
25
|
|
|
24
26
|
const {
|
|
@@ -36,5 +38,5 @@ export function updateOverlaySheet(
|
|
|
36
38
|
const height = (row_end - row_start) * box_height;
|
|
37
39
|
const width = (col_end - col_start) * box_width;
|
|
38
40
|
const css = `display:flex;position:absolute!important;z-index:1;top:${top}px;left:${left}px;height:${height}px;width:${width}px;`;
|
|
39
|
-
return `::slotted([
|
|
41
|
+
return `::slotted([${physics.CHILD_ATTRIBUTE_NAME}="${slot}"]){${css}}`;
|
|
40
42
|
}
|
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
// ┃ * [Apache License 2.0](https://www.apache.org/licenses/LICENSE-2.0). * ┃
|
|
10
10
|
// ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛
|
|
11
11
|
|
|
12
|
-
import {
|
|
12
|
+
import { DEFAULT_PHYSICS } from "./constants.ts";
|
|
13
13
|
import type { Layout } from "./types.ts";
|
|
14
14
|
|
|
15
15
|
/**
|
|
@@ -33,6 +33,7 @@ export function redistribute_panel_sizes(
|
|
|
33
33
|
panel: Layout,
|
|
34
34
|
path: number[],
|
|
35
35
|
delta: number,
|
|
36
|
+
physics = DEFAULT_PHYSICS,
|
|
36
37
|
): Layout {
|
|
37
38
|
// Clone the entire panel structure
|
|
38
39
|
const result = structuredClone(panel);
|
|
@@ -55,7 +56,12 @@ export function redistribute_panel_sizes(
|
|
|
55
56
|
|
|
56
57
|
// It would be fun to remove this condition.
|
|
57
58
|
if (index < current.sizes.length - 1) {
|
|
58
|
-
current.sizes = add_and_redistribute(
|
|
59
|
+
current.sizes = add_and_redistribute(
|
|
60
|
+
physics,
|
|
61
|
+
current.sizes,
|
|
62
|
+
index,
|
|
63
|
+
delta,
|
|
64
|
+
);
|
|
59
65
|
}
|
|
60
66
|
}
|
|
61
67
|
|
|
@@ -63,6 +69,7 @@ export function redistribute_panel_sizes(
|
|
|
63
69
|
}
|
|
64
70
|
|
|
65
71
|
function add_and_redistribute(
|
|
72
|
+
physics: typeof DEFAULT_PHYSICS,
|
|
66
73
|
arr: number[],
|
|
67
74
|
index: number,
|
|
68
75
|
delta: number,
|
|
@@ -83,7 +90,7 @@ function add_and_redistribute(
|
|
|
83
90
|
Math.sign(delta) *
|
|
84
91
|
Math.min(
|
|
85
92
|
Math.abs(delta),
|
|
86
|
-
(1 - MINIMUM_REDISTRIBUTION_SIZE_THRESHOLD) *
|
|
93
|
+
(1 - physics.MINIMUM_REDISTRIBUTION_SIZE_THRESHOLD) *
|
|
87
94
|
(delta > 0 ? before_total : after_total),
|
|
88
95
|
);
|
|
89
96
|
|
package/src/layout/types.ts
CHANGED
|
@@ -9,7 +9,6 @@
|
|
|
9
9
|
// ┃ * [Apache License 2.0](https://www.apache.org/licenses/LICENSE-2.0). * ┃
|
|
10
10
|
// ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛
|
|
11
11
|
|
|
12
|
-
import { MIN_DRAG_DISTANCE, OVERLAY_CLASSNAME } from "./layout/constants.ts";
|
|
13
12
|
import type { Layout, LayoutPath } from "./layout/types.ts";
|
|
14
13
|
import type { RegularLayoutEvent } from "./extensions.ts";
|
|
15
14
|
import type { RegularLayout } from "./regular-layout.ts";
|
|
@@ -115,6 +114,8 @@ export class RegularLayoutFrame extends HTMLElement {
|
|
|
115
114
|
|
|
116
115
|
private onPointerMove = (event: PointerEvent): void => {
|
|
117
116
|
if (this._drag_state) {
|
|
117
|
+
const physics = this._layout.savePhysics();
|
|
118
|
+
|
|
118
119
|
// Only initiate a drag if the cursor has moved sufficiently.
|
|
119
120
|
if (!this._drag_moved) {
|
|
120
121
|
const [current_col, current_row, box] =
|
|
@@ -122,7 +123,7 @@ export class RegularLayoutFrame extends HTMLElement {
|
|
|
122
123
|
|
|
123
124
|
const dx = (current_col - this._drag_state.column) * box.width;
|
|
124
125
|
const dy = (current_row - this._drag_state.row) * box.height;
|
|
125
|
-
if (Math.sqrt(dx * dx + dy * dy) <= MIN_DRAG_DISTANCE) {
|
|
126
|
+
if (Math.sqrt(dx * dx + dy * dy) <= physics.MIN_DRAG_DISTANCE) {
|
|
126
127
|
return;
|
|
127
128
|
}
|
|
128
129
|
}
|
|
@@ -132,7 +133,7 @@ export class RegularLayoutFrame extends HTMLElement {
|
|
|
132
133
|
event.clientX,
|
|
133
134
|
event.clientY,
|
|
134
135
|
this._drag_state,
|
|
135
|
-
OVERLAY_CLASSNAME,
|
|
136
|
+
physics.OVERLAY_CLASSNAME,
|
|
136
137
|
);
|
|
137
138
|
}
|
|
138
139
|
};
|
|
@@ -143,7 +144,6 @@ export class RegularLayoutFrame extends HTMLElement {
|
|
|
143
144
|
event.clientX,
|
|
144
145
|
event.clientY,
|
|
145
146
|
this._drag_state,
|
|
146
|
-
OVERLAY_CLASSNAME,
|
|
147
147
|
);
|
|
148
148
|
}
|
|
149
149
|
|
|
@@ -165,7 +165,10 @@ export class RegularLayoutFrame extends HTMLElement {
|
|
|
165
165
|
};
|
|
166
166
|
|
|
167
167
|
private drawTabs = (event: RegularLayoutEvent) => {
|
|
168
|
-
const slot = this.getAttribute(
|
|
168
|
+
const slot = this.getAttribute(
|
|
169
|
+
this._layout.savePhysics().CHILD_ATTRIBUTE_NAME,
|
|
170
|
+
);
|
|
171
|
+
|
|
169
172
|
if (!slot) {
|
|
170
173
|
return;
|
|
171
174
|
}
|
package/src/regular-layout.ts
CHANGED
|
@@ -34,9 +34,9 @@ import { updateOverlaySheet } from "./layout/generate_overlay.ts";
|
|
|
34
34
|
import { calculate_edge } from "./layout/calculate_edge.ts";
|
|
35
35
|
import { flatten } from "./layout/flatten.ts";
|
|
36
36
|
import {
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
37
|
+
DEFAULT_PHYSICS,
|
|
38
|
+
type PhysicsUpdate,
|
|
39
|
+
type Physics,
|
|
40
40
|
} from "./layout/constants.ts";
|
|
41
41
|
|
|
42
42
|
/**
|
|
@@ -80,9 +80,11 @@ export class RegularLayout extends HTMLElement {
|
|
|
80
80
|
private _drag_target?: [LayoutDivider, number, number];
|
|
81
81
|
private _cursor_override: boolean;
|
|
82
82
|
private _dimensions?: { box: DOMRect; style: CSSStyleDeclaration };
|
|
83
|
+
private _physics: Physics;
|
|
83
84
|
|
|
84
85
|
constructor() {
|
|
85
86
|
super();
|
|
87
|
+
this._physics = DEFAULT_PHYSICS;
|
|
86
88
|
this._panel = structuredClone(EMPTY_PANEL);
|
|
87
89
|
|
|
88
90
|
// Why does this implementation use a `<slot>` at all? We must use
|
|
@@ -130,12 +132,12 @@ export class RegularLayout extends HTMLElement {
|
|
|
130
132
|
y: number,
|
|
131
133
|
check_dividers: boolean = false,
|
|
132
134
|
): LayoutPath<Layout> | null => {
|
|
133
|
-
const [col, row,
|
|
135
|
+
const [col, row, rect] = this.relativeCoordinates(x, y, false);
|
|
134
136
|
const panel = calculate_intersection(
|
|
135
137
|
col,
|
|
136
138
|
row,
|
|
137
139
|
this._panel,
|
|
138
|
-
check_dividers ?
|
|
140
|
+
check_dividers ? { rect, size: this._physics.GRID_DIVIDER_SIZE } : null,
|
|
139
141
|
);
|
|
140
142
|
|
|
141
143
|
if (panel?.type === "layout-path") {
|
|
@@ -163,31 +165,47 @@ export class RegularLayout extends HTMLElement {
|
|
|
163
165
|
x: number,
|
|
164
166
|
y: number,
|
|
165
167
|
{ slot }: LayoutPath<unknown>,
|
|
166
|
-
className: string = OVERLAY_CLASSNAME,
|
|
167
|
-
mode: OverlayMode = OVERLAY_DEFAULT,
|
|
168
|
+
className: string = this._physics.OVERLAY_CLASSNAME,
|
|
169
|
+
mode: OverlayMode = this._physics.OVERLAY_DEFAULT,
|
|
168
170
|
) => {
|
|
169
171
|
const panel = remove_child(this._panel, slot);
|
|
170
172
|
Array.from(this.children)
|
|
171
|
-
.find((x) => x.getAttribute(
|
|
173
|
+
.find((x) => x.getAttribute(this._physics.CHILD_ATTRIBUTE_NAME) === slot)
|
|
172
174
|
?.classList.add(className);
|
|
173
175
|
|
|
174
176
|
const [col, row, box, style] = this.relativeCoordinates(x, y, false);
|
|
175
177
|
let drop_target = calculate_intersection(col, row, panel);
|
|
176
178
|
if (drop_target) {
|
|
177
|
-
drop_target = calculate_edge(
|
|
179
|
+
drop_target = calculate_edge(
|
|
180
|
+
col,
|
|
181
|
+
row,
|
|
182
|
+
panel,
|
|
183
|
+
slot,
|
|
184
|
+
drop_target,
|
|
185
|
+
box,
|
|
186
|
+
this._physics,
|
|
187
|
+
);
|
|
178
188
|
}
|
|
179
189
|
|
|
180
190
|
if (mode === "grid" && drop_target) {
|
|
181
191
|
const path: [string, string] = [slot, drop_target?.slot];
|
|
182
|
-
const css = create_css_grid_layout(panel,
|
|
192
|
+
const css = create_css_grid_layout(panel, path, this._physics);
|
|
183
193
|
this._stylesheet.replaceSync(css);
|
|
184
194
|
} else if (mode === "absolute") {
|
|
185
|
-
const grid_css = create_css_grid_layout(panel);
|
|
186
|
-
|
|
195
|
+
const grid_css = create_css_grid_layout(panel, undefined, this._physics);
|
|
196
|
+
|
|
197
|
+
const overlay_css = updateOverlaySheet(
|
|
198
|
+
slot,
|
|
199
|
+
box,
|
|
200
|
+
style,
|
|
201
|
+
drop_target,
|
|
202
|
+
this._physics,
|
|
203
|
+
);
|
|
204
|
+
|
|
187
205
|
this._stylesheet.replaceSync([grid_css, overlay_css].join("\n"));
|
|
188
206
|
}
|
|
189
207
|
|
|
190
|
-
const event_name = `${CUSTOM_EVENT_NAME_PREFIX}-before-update`;
|
|
208
|
+
const event_name = `${this._physics.CUSTOM_EVENT_NAME_PREFIX}-before-update`;
|
|
191
209
|
const event = new CustomEvent<Layout>(event_name, { detail: panel });
|
|
192
210
|
this.dispatchEvent(event);
|
|
193
211
|
};
|
|
@@ -208,12 +226,16 @@ export class RegularLayout extends HTMLElement {
|
|
|
208
226
|
x: number,
|
|
209
227
|
y: number,
|
|
210
228
|
drag_target: LayoutPath<Layout>,
|
|
211
|
-
className: string = OVERLAY_CLASSNAME,
|
|
229
|
+
className: string = this._physics.OVERLAY_CLASSNAME,
|
|
212
230
|
) => {
|
|
213
231
|
let panel = this._panel;
|
|
214
232
|
panel = remove_child(panel, drag_target.slot);
|
|
215
233
|
Array.from(this.children)
|
|
216
|
-
.find(
|
|
234
|
+
.find(
|
|
235
|
+
(x) =>
|
|
236
|
+
x.getAttribute(this._physics.CHILD_ATTRIBUTE_NAME) ===
|
|
237
|
+
drag_target.slot,
|
|
238
|
+
)
|
|
217
239
|
?.classList.remove(className);
|
|
218
240
|
|
|
219
241
|
const [col, row, box] = this.relativeCoordinates(x, y, false);
|
|
@@ -226,6 +248,7 @@ export class RegularLayout extends HTMLElement {
|
|
|
226
248
|
drag_target.slot,
|
|
227
249
|
drop_target,
|
|
228
250
|
box,
|
|
251
|
+
this._physics,
|
|
229
252
|
);
|
|
230
253
|
}
|
|
231
254
|
|
|
@@ -323,9 +346,10 @@ export class RegularLayout extends HTMLElement {
|
|
|
323
346
|
*/
|
|
324
347
|
restore = (layout: Layout, _is_flattened: boolean = false) => {
|
|
325
348
|
this._panel = !_is_flattened ? flatten(layout) : layout;
|
|
326
|
-
const css = create_css_grid_layout(this._panel);
|
|
349
|
+
const css = create_css_grid_layout(this._panel, undefined, this._physics);
|
|
350
|
+
|
|
327
351
|
this._stylesheet.replaceSync(css);
|
|
328
|
-
const event_name = `${CUSTOM_EVENT_NAME_PREFIX}-update`;
|
|
352
|
+
const event_name = `${this._physics.CUSTOM_EVENT_NAME_PREFIX}-update`;
|
|
329
353
|
const event = new CustomEvent<Layout>(event_name, { detail: this._panel });
|
|
330
354
|
this.dispatchEvent(event);
|
|
331
355
|
};
|
|
@@ -346,6 +370,27 @@ export class RegularLayout extends HTMLElement {
|
|
|
346
370
|
return structuredClone(this._panel);
|
|
347
371
|
};
|
|
348
372
|
|
|
373
|
+
/**
|
|
374
|
+
* Override this instance's global constants.
|
|
375
|
+
*
|
|
376
|
+
* @param physics
|
|
377
|
+
*/
|
|
378
|
+
restorePhysics(physics: PhysicsUpdate) {
|
|
379
|
+
this._physics = Object.freeze({
|
|
380
|
+
...this._physics,
|
|
381
|
+
...physics,
|
|
382
|
+
});
|
|
383
|
+
}
|
|
384
|
+
|
|
385
|
+
/**
|
|
386
|
+
* Get this instance's constants.
|
|
387
|
+
*
|
|
388
|
+
* @returns The current constants
|
|
389
|
+
*/
|
|
390
|
+
savePhysics(): Physics {
|
|
391
|
+
return this._physics;
|
|
392
|
+
}
|
|
393
|
+
|
|
349
394
|
/**
|
|
350
395
|
* Converts screen coordinates to relative layout coordinates.
|
|
351
396
|
*
|
|
@@ -388,13 +433,16 @@ export class RegularLayout extends HTMLElement {
|
|
|
388
433
|
};
|
|
389
434
|
|
|
390
435
|
private onPointerDown = (event: PointerEvent) => {
|
|
391
|
-
if (event.target === this) {
|
|
392
|
-
const [col, row,
|
|
436
|
+
if (!this._physics.GRID_DIVIDER_CHECK_TARGET || event.target === this) {
|
|
437
|
+
const [col, row, rect] = this.relativeCoordinates(
|
|
393
438
|
event.clientX,
|
|
394
439
|
event.clientY,
|
|
395
440
|
);
|
|
396
441
|
|
|
397
|
-
const hit = calculate_intersection(col, row, this._panel,
|
|
442
|
+
const hit = calculate_intersection(col, row, this._panel, {
|
|
443
|
+
rect,
|
|
444
|
+
size: this._physics.GRID_DIVIDER_SIZE,
|
|
445
|
+
});
|
|
398
446
|
if (hit && hit.type !== "layout-path") {
|
|
399
447
|
this._drag_target = [hit, col, row];
|
|
400
448
|
this.setPointerCapture(event.pointerId);
|
|
@@ -414,22 +462,37 @@ export class RegularLayout extends HTMLElement {
|
|
|
414
462
|
const [{ path, type }, old_col, old_row] = this._drag_target;
|
|
415
463
|
const offset = type === "horizontal" ? old_col - col : old_row - row;
|
|
416
464
|
const panel = redistribute_panel_sizes(this._panel, path, offset);
|
|
417
|
-
this._stylesheet.replaceSync(
|
|
418
|
-
|
|
419
|
-
const [col, row, box] = this.relativeCoordinates(
|
|
420
|
-
event.clientX,
|
|
421
|
-
event.clientY,
|
|
422
|
-
false,
|
|
465
|
+
this._stylesheet.replaceSync(
|
|
466
|
+
create_css_grid_layout(panel, undefined, this._physics),
|
|
423
467
|
);
|
|
468
|
+
}
|
|
424
469
|
|
|
425
|
-
|
|
426
|
-
if (
|
|
427
|
-
this.
|
|
428
|
-
this.
|
|
429
|
-
} else if (divider?.type === "horizontal") {
|
|
430
|
-
this._cursor_stylesheet.replaceSync(":host{cursor:col-resize");
|
|
431
|
-
this._cursor_override = true;
|
|
470
|
+
if (this._physics.GRID_DIVIDER_CHECK_TARGET && event.target !== this) {
|
|
471
|
+
if (this._cursor_override) {
|
|
472
|
+
this._cursor_override = false;
|
|
473
|
+
this._cursor_stylesheet.replaceSync("");
|
|
432
474
|
}
|
|
475
|
+
|
|
476
|
+
return;
|
|
477
|
+
}
|
|
478
|
+
|
|
479
|
+
const [col, row, rect] = this.relativeCoordinates(
|
|
480
|
+
event.clientX,
|
|
481
|
+
event.clientY,
|
|
482
|
+
false,
|
|
483
|
+
);
|
|
484
|
+
|
|
485
|
+
const divider = calculate_intersection(col, row, this._panel, {
|
|
486
|
+
rect,
|
|
487
|
+
size: this._physics.GRID_DIVIDER_SIZE,
|
|
488
|
+
});
|
|
489
|
+
|
|
490
|
+
if (divider?.type === "vertical") {
|
|
491
|
+
this._cursor_stylesheet.replaceSync(":host{cursor:row-resize");
|
|
492
|
+
this._cursor_override = true;
|
|
493
|
+
} else if (divider?.type === "horizontal") {
|
|
494
|
+
this._cursor_stylesheet.replaceSync(":host{cursor:col-resize");
|
|
495
|
+
this._cursor_override = true;
|
|
433
496
|
} else if (this._cursor_override) {
|
|
434
497
|
this._cursor_override = false;
|
|
435
498
|
this._cursor_stylesheet.replaceSync("");
|
package/themes/lorax.css
CHANGED
|
@@ -18,7 +18,7 @@ regular-layout.lorax {
|
|
|
18
18
|
regular-layout.lorax regular-layout-frame {
|
|
19
19
|
margin: 3px;
|
|
20
20
|
margin-top: 27px;
|
|
21
|
-
border-radius: 0
|
|
21
|
+
border-radius: 0 6px 6px 6px;
|
|
22
22
|
border: 1px solid #666;
|
|
23
23
|
box-shadow: 0px 6px 6px -4px rgba(150, 150, 180);
|
|
24
24
|
}
|
|
@@ -30,6 +30,7 @@ regular-layout.lorax regular-layout-frame::part(titlebar) {
|
|
|
30
30
|
margin-right: -1px;
|
|
31
31
|
margin-bottom: 0px;
|
|
32
32
|
margin-top: -24px;
|
|
33
|
+
padding-right: 6px;
|
|
33
34
|
}
|
|
34
35
|
|
|
35
36
|
regular-layout.lorax regular-layout-frame::part(tab) {
|