regular-layout 0.3.0 → 0.4.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 +110 -22
- package/dist/{layout → core}/types.d.ts +6 -0
- package/dist/extensions.d.ts +6 -1
- package/dist/index.d.ts +2 -1
- package/dist/index.js +7 -7
- package/dist/index.js.map +4 -4
- package/dist/layout/calculate_edge.d.ts +2 -2
- package/dist/layout/calculate_intersect.d.ts +1 -1
- package/dist/layout/calculate_path.d.ts +1 -1
- package/dist/layout/calculate_presize_paths.d.ts +10 -0
- package/dist/layout/flatten.d.ts +1 -1
- package/dist/layout/generate_grid.d.ts +2 -2
- package/dist/layout/generate_overlay.d.ts +18 -2
- package/dist/layout/insert_child.d.ts +1 -1
- package/dist/layout/redistribute_panel_sizes.d.ts +2 -2
- package/dist/layout/remove_child.d.ts +1 -1
- package/dist/model/overlay_controller.d.ts +34 -0
- package/dist/model/presize_queue.d.ts +17 -0
- package/dist/regular-layout-tab.d.ts +1 -1
- package/dist/regular-layout.d.ts +37 -9
- package/package.json +5 -4
- package/src/{layout → core}/constants.ts +2 -2
- package/src/{layout → core}/types.ts +7 -0
- package/src/extensions.ts +13 -1
- package/src/index.ts +3 -1
- package/src/layout/calculate_edge.ts +2 -2
- package/src/layout/calculate_intersect.ts +5 -2
- package/src/layout/calculate_path.ts +1 -1
- package/src/layout/calculate_presize_paths.ts +93 -0
- package/src/layout/flatten.ts +1 -1
- package/src/layout/generate_grid.ts +2 -2
- package/src/layout/generate_overlay.ts +48 -16
- package/src/layout/insert_child.ts +1 -1
- package/src/layout/redistribute_panel_sizes.ts +2 -2
- package/src/layout/remove_child.ts +2 -2
- package/src/model/overlay_controller.ts +162 -0
- package/src/model/presize_queue.ts +79 -0
- package/src/regular-layout-frame.ts +2 -2
- package/src/regular-layout-tab.ts +1 -1
- package/src/regular-layout.ts +166 -131
- package/themes/borland.css +103 -0
- package/themes/chicago.css +55 -49
- package/themes/fluxbox.css +64 -60
- package/themes/gibson.css +174 -164
- package/themes/hotdog.css +53 -47
- package/themes/lorax.css +82 -75
- /package/dist/{layout → core}/constants.d.ts +0 -0
package/src/regular-layout.ts
CHANGED
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
* @packageDocumentation
|
|
17
17
|
*/
|
|
18
18
|
|
|
19
|
-
import { EMPTY_PANEL } from "./
|
|
19
|
+
import { EMPTY_PANEL } from "./core/types.ts";
|
|
20
20
|
import { create_css_grid_layout } from "./layout/generate_grid.ts";
|
|
21
21
|
import type {
|
|
22
22
|
LayoutPath,
|
|
@@ -26,20 +26,27 @@ import type {
|
|
|
26
26
|
OverlayMode,
|
|
27
27
|
Orientation,
|
|
28
28
|
LayoutPathTraversal,
|
|
29
|
-
|
|
29
|
+
ViewWindow,
|
|
30
|
+
} from "./core/types.ts";
|
|
31
|
+
|
|
30
32
|
import { calculate_intersection } from "./layout/calculate_intersect.ts";
|
|
31
33
|
import { remove_child } from "./layout/remove_child.ts";
|
|
32
34
|
import { insert_child } from "./layout/insert_child.ts";
|
|
33
35
|
import { redistribute_panel_sizes } from "./layout/redistribute_panel_sizes.ts";
|
|
34
|
-
import {
|
|
35
|
-
import { calculate_edge } from "./layout/calculate_edge.ts";
|
|
36
|
+
import { viewWindowToLocalRect } from "./layout/generate_overlay.ts";
|
|
36
37
|
import { flatten } from "./layout/flatten.ts";
|
|
37
38
|
import { calculate_path } from "./layout/calculate_path.ts";
|
|
39
|
+
import { PresizeQueue } from "./model/presize_queue.ts";
|
|
40
|
+
import {
|
|
41
|
+
OverlayController,
|
|
42
|
+
type OverlayHost,
|
|
43
|
+
} from "./model/overlay_controller.ts";
|
|
44
|
+
|
|
38
45
|
import {
|
|
39
46
|
DEFAULT_PHYSICS,
|
|
40
47
|
type PhysicsUpdate,
|
|
41
48
|
type Physics,
|
|
42
|
-
} from "./
|
|
49
|
+
} from "./core/constants.ts";
|
|
43
50
|
|
|
44
51
|
/**
|
|
45
52
|
* An interface which models the fields of `PointerEvent` that
|
|
@@ -109,6 +116,8 @@ export class RegularLayout extends HTMLElement {
|
|
|
109
116
|
private _cursor_override: boolean;
|
|
110
117
|
private _dimensions?: { box: DOMRect; style: CSSStyleDeclaration };
|
|
111
118
|
private _physics: Physics;
|
|
119
|
+
private _presizeQueue: PresizeQueue;
|
|
120
|
+
private _overlayController: OverlayController;
|
|
112
121
|
|
|
113
122
|
constructor() {
|
|
114
123
|
super();
|
|
@@ -119,6 +128,9 @@ export class RegularLayout extends HTMLElement {
|
|
|
119
128
|
this._stylesheet = new CSSStyleSheet();
|
|
120
129
|
this._cursor_stylesheet = new CSSStyleSheet();
|
|
121
130
|
this._cursor_override = false;
|
|
131
|
+
const event_name = `${this._physics.CUSTOM_EVENT_NAME_PREFIX}-before-resize`;
|
|
132
|
+
this._presizeQueue = new PresizeQueue(this, event_name);
|
|
133
|
+
this._overlayController = new OverlayController(this.create_overlay_host());
|
|
122
134
|
this._shadowRoot.adoptedStyleSheets = [
|
|
123
135
|
this._stylesheet,
|
|
124
136
|
this._cursor_stylesheet,
|
|
@@ -177,54 +189,13 @@ export class RegularLayout extends HTMLElement {
|
|
|
177
189
|
* the target, "absolute" positions the panel absolutely. Defaults to
|
|
178
190
|
* "absolute".
|
|
179
191
|
*/
|
|
180
|
-
setOverlayState = (
|
|
192
|
+
setOverlayState = async (
|
|
181
193
|
event: PointerEventCoordinates,
|
|
182
|
-
|
|
183
|
-
className
|
|
184
|
-
mode
|
|
194
|
+
target: LayoutPath,
|
|
195
|
+
className?: string,
|
|
196
|
+
mode?: OverlayMode,
|
|
185
197
|
) => {
|
|
186
|
-
|
|
187
|
-
const query = `:scope > [${this._physics.CHILD_ATTRIBUTE_NAME}="${slot}"]`;
|
|
188
|
-
const drag_element = this.querySelector(query);
|
|
189
|
-
if (drag_element) {
|
|
190
|
-
drag_element.classList.add(className);
|
|
191
|
-
}
|
|
192
|
-
|
|
193
|
-
// TODO: Don't recalculate box (but this currently protects against resize).
|
|
194
|
-
const [col, row, box, style] = this.relativeCoordinates(event, true);
|
|
195
|
-
let drop_target = calculate_intersection(col, row, panel);
|
|
196
|
-
if (drop_target) {
|
|
197
|
-
drop_target = calculate_edge(
|
|
198
|
-
col,
|
|
199
|
-
row,
|
|
200
|
-
panel,
|
|
201
|
-
slot,
|
|
202
|
-
drop_target,
|
|
203
|
-
box,
|
|
204
|
-
this._physics,
|
|
205
|
-
);
|
|
206
|
-
}
|
|
207
|
-
|
|
208
|
-
if (mode === "grid" && drop_target) {
|
|
209
|
-
const path: [string, string] = [slot, drop_target?.slot];
|
|
210
|
-
const css = create_css_grid_layout(panel, path, this._physics);
|
|
211
|
-
this._stylesheet.replaceSync(css);
|
|
212
|
-
} else if (mode === "absolute") {
|
|
213
|
-
const grid_css = create_css_grid_layout(panel, undefined, this._physics);
|
|
214
|
-
const overlay_css = updateOverlaySheet(
|
|
215
|
-
slot,
|
|
216
|
-
box,
|
|
217
|
-
style,
|
|
218
|
-
drop_target,
|
|
219
|
-
this._physics,
|
|
220
|
-
);
|
|
221
|
-
|
|
222
|
-
this._stylesheet.replaceSync([grid_css, overlay_css].join("\n"));
|
|
223
|
-
}
|
|
224
|
-
|
|
225
|
-
const event_name = `${this._physics.CUSTOM_EVENT_NAME_PREFIX}-before-update`;
|
|
226
|
-
const custom_event = new CustomEvent<Layout>(event_name, { detail: panel });
|
|
227
|
-
this.dispatchEvent(custom_event);
|
|
198
|
+
await this._overlayController.set(event, target, className, mode);
|
|
228
199
|
};
|
|
229
200
|
|
|
230
201
|
/**
|
|
@@ -239,54 +210,12 @@ export class RegularLayout extends HTMLElement {
|
|
|
239
210
|
* @param mode - Overlay rendering mode that was used, must match the mode
|
|
240
211
|
* passed to `setOverlayState`. Defaults to "absolute".
|
|
241
212
|
*/
|
|
242
|
-
clearOverlayState = (
|
|
213
|
+
clearOverlayState = async (
|
|
243
214
|
event: PointerEventCoordinates | null,
|
|
244
|
-
|
|
245
|
-
className
|
|
215
|
+
target: LayoutPath,
|
|
216
|
+
className?: string,
|
|
246
217
|
) => {
|
|
247
|
-
|
|
248
|
-
panel = remove_child(panel, slot);
|
|
249
|
-
const query = `:scope > [${this._physics.CHILD_ATTRIBUTE_NAME}="${slot}"]`;
|
|
250
|
-
const drag_element = this.querySelector(query);
|
|
251
|
-
if (drag_element) {
|
|
252
|
-
drag_element.classList.remove(className);
|
|
253
|
-
}
|
|
254
|
-
|
|
255
|
-
if (event === null) {
|
|
256
|
-
this.restore(layout);
|
|
257
|
-
return;
|
|
258
|
-
}
|
|
259
|
-
|
|
260
|
-
const [col, row, box] = this.relativeCoordinates(event, false);
|
|
261
|
-
let drop_target = calculate_intersection(col, row, panel);
|
|
262
|
-
if (drop_target) {
|
|
263
|
-
drop_target = calculate_edge(
|
|
264
|
-
col,
|
|
265
|
-
row,
|
|
266
|
-
panel,
|
|
267
|
-
slot,
|
|
268
|
-
drop_target,
|
|
269
|
-
box,
|
|
270
|
-
this._physics,
|
|
271
|
-
);
|
|
272
|
-
}
|
|
273
|
-
|
|
274
|
-
if (drop_target) {
|
|
275
|
-
const orientation = drop_target?.is_edge
|
|
276
|
-
? drop_target.orientation
|
|
277
|
-
: undefined;
|
|
278
|
-
|
|
279
|
-
const new_layout = insert_child(
|
|
280
|
-
panel,
|
|
281
|
-
slot,
|
|
282
|
-
drop_target.path,
|
|
283
|
-
orientation,
|
|
284
|
-
);
|
|
285
|
-
|
|
286
|
-
this.restore(new_layout);
|
|
287
|
-
} else {
|
|
288
|
-
this.restore(layout);
|
|
289
|
-
}
|
|
218
|
+
await this._overlayController.clear(event, target, className);
|
|
290
219
|
};
|
|
291
220
|
|
|
292
221
|
/**
|
|
@@ -300,7 +229,7 @@ export class RegularLayout extends HTMLElement {
|
|
|
300
229
|
* the new `SplitPanel` _if_ there is an option of orientation (e.g. if
|
|
301
230
|
* the layout had no pre-existing `SplitPanel`)
|
|
302
231
|
*/
|
|
303
|
-
insertPanel = (
|
|
232
|
+
insertPanel = async (
|
|
304
233
|
name: string,
|
|
305
234
|
path: LayoutPathTraversal = [],
|
|
306
235
|
split?: boolean | Orientation,
|
|
@@ -312,7 +241,7 @@ export class RegularLayout extends HTMLElement {
|
|
|
312
241
|
orientation = split;
|
|
313
242
|
}
|
|
314
243
|
|
|
315
|
-
this.restore(insert_child(this._panel, name, path, orientation));
|
|
244
|
+
await this.restore(insert_child(this._panel, name, path, orientation));
|
|
316
245
|
};
|
|
317
246
|
|
|
318
247
|
/**
|
|
@@ -320,8 +249,8 @@ export class RegularLayout extends HTMLElement {
|
|
|
320
249
|
*
|
|
321
250
|
* @param name - Name of the panel to remove
|
|
322
251
|
*/
|
|
323
|
-
removePanel = (name: string) => {
|
|
324
|
-
this.restore(remove_child(this._panel, name));
|
|
252
|
+
removePanel = async (name: string) => {
|
|
253
|
+
await this.restore(remove_child(this._panel, name));
|
|
325
254
|
};
|
|
326
255
|
|
|
327
256
|
/**
|
|
@@ -353,29 +282,61 @@ export class RegularLayout extends HTMLElement {
|
|
|
353
282
|
/**
|
|
354
283
|
* Clears the entire layout, unslotting all panels.
|
|
355
284
|
*/
|
|
356
|
-
clear = () => {
|
|
357
|
-
this.restore(EMPTY_PANEL);
|
|
285
|
+
clear = async () => {
|
|
286
|
+
await this.restore(EMPTY_PANEL);
|
|
287
|
+
};
|
|
288
|
+
|
|
289
|
+
/**
|
|
290
|
+
* Restores the layout from a saved state synchronously, without
|
|
291
|
+
* dispatching the `regular-layout-before-resize` event.
|
|
292
|
+
*
|
|
293
|
+
* @param layout - The layout tree to restore
|
|
294
|
+
*/
|
|
295
|
+
restoreSync = (layout: Layout, _is_flattened: boolean = false) => {
|
|
296
|
+
this._panel = !_is_flattened ? flatten(layout) : layout;
|
|
297
|
+
const css = create_css_grid_layout(this._panel, undefined, this._physics);
|
|
298
|
+
this._stylesheet.replaceSync(css);
|
|
299
|
+
const event_name = `${this._physics.CUSTOM_EVENT_NAME_PREFIX}-update`;
|
|
300
|
+
const event = new CustomEvent<Layout>(event_name, { detail: this._panel });
|
|
301
|
+
this.dispatchEvent(event);
|
|
358
302
|
};
|
|
359
303
|
|
|
360
304
|
/**
|
|
361
305
|
* Restores the layout from a saved state.
|
|
362
306
|
*
|
|
307
|
+
* Before applying, dispatches a cancelable `regular-layout-before-resize`
|
|
308
|
+
* event. If the event is cancelled via `preventDefault()`, the layout
|
|
309
|
+
* update is suspended until {@link resumeResize} is called.
|
|
310
|
+
*
|
|
363
311
|
* @param layout - The layout tree to restore
|
|
364
312
|
*
|
|
365
313
|
* @example
|
|
366
314
|
* ```typescript
|
|
367
315
|
* const layout = document.querySelector('regular-layout');
|
|
368
316
|
* const savedState = JSON.parse(localStorage.getItem('layout'));
|
|
369
|
-
* layout.restore(savedState);
|
|
317
|
+
* await layout.restore(savedState);
|
|
370
318
|
* ```
|
|
371
319
|
*/
|
|
372
|
-
restore = (layout: Layout, _is_flattened: boolean = false) => {
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
320
|
+
restore = async (layout: Layout, _is_flattened: boolean = false) => {
|
|
321
|
+
const panel = !_is_flattened ? flatten(layout) : layout;
|
|
322
|
+
await this._presizeQueue.run(panel, () => {
|
|
323
|
+
this._panel = panel;
|
|
324
|
+
const css = create_css_grid_layout(this._panel, undefined, this._physics);
|
|
325
|
+
this._stylesheet.replaceSync(css);
|
|
326
|
+
const event_name = `${this._physics.CUSTOM_EVENT_NAME_PREFIX}-update`;
|
|
327
|
+
const event = new CustomEvent<Layout>(event_name, {
|
|
328
|
+
detail: this._panel,
|
|
329
|
+
});
|
|
330
|
+
this.dispatchEvent(event);
|
|
331
|
+
});
|
|
332
|
+
};
|
|
333
|
+
|
|
334
|
+
/**
|
|
335
|
+
* Resumes a layout update that was suspended by cancelling the
|
|
336
|
+
* `regular-layout-before-resize` event.
|
|
337
|
+
*/
|
|
338
|
+
resumeResize = () => {
|
|
339
|
+
this._presizeQueue.resume();
|
|
379
340
|
};
|
|
380
341
|
|
|
381
342
|
/**
|
|
@@ -441,21 +402,53 @@ export class RegularLayout extends HTMLElement {
|
|
|
441
402
|
|
|
442
403
|
const box = this._dimensions.box;
|
|
443
404
|
const style = this._dimensions.style;
|
|
444
|
-
const
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
405
|
+
const paddingLeft = parseFloat(style.paddingLeft);
|
|
406
|
+
const paddingTop = parseFloat(style.paddingTop);
|
|
407
|
+
const contentWidth =
|
|
408
|
+
box.width - paddingLeft - parseFloat(style.paddingRight);
|
|
409
|
+
|
|
410
|
+
const contentHeight =
|
|
411
|
+
box.height - paddingTop - parseFloat(style.paddingBottom);
|
|
412
|
+
|
|
413
|
+
const localX = event.clientX - box.left - paddingLeft;
|
|
414
|
+
const localY = event.clientY - box.top - paddingTop;
|
|
415
|
+
const col = Math.max(0, Math.min(1, localX / contentWidth));
|
|
416
|
+
const row = Math.max(0, Math.min(1, localY / contentHeight));
|
|
456
417
|
return [col, row, box, style];
|
|
457
418
|
};
|
|
458
419
|
|
|
420
|
+
/**
|
|
421
|
+
* Converts a {@link ViewWindow} (normalized 0–1 coordinates) to a
|
|
422
|
+
* `DOMRect` in screen pixels, accounting for padding and optionally
|
|
423
|
+
* CSS `gap` and child `margin`.
|
|
424
|
+
*
|
|
425
|
+
* @param window - The view window to convert.
|
|
426
|
+
* @returns A `DOMRect` representing the window in screen coordinates.
|
|
427
|
+
*/
|
|
428
|
+
realCoordinates = (window: ViewWindow, child?: HTMLElement): DOMRect => {
|
|
429
|
+
if (!this._dimensions) {
|
|
430
|
+
this._dimensions = {
|
|
431
|
+
box: this.getBoundingClientRect(),
|
|
432
|
+
style: getComputedStyle(this),
|
|
433
|
+
};
|
|
434
|
+
}
|
|
435
|
+
|
|
436
|
+
const box = this._dimensions.box;
|
|
437
|
+
const style = this._dimensions.style;
|
|
438
|
+
let childStyle: CSSStyleDeclaration | undefined;
|
|
439
|
+
if (child) {
|
|
440
|
+
childStyle = getComputedStyle(child);
|
|
441
|
+
}
|
|
442
|
+
|
|
443
|
+
const local = viewWindowToLocalRect(window, box, style, childStyle);
|
|
444
|
+
return new DOMRect(
|
|
445
|
+
box.left + local.x,
|
|
446
|
+
box.top + local.y,
|
|
447
|
+
local.width,
|
|
448
|
+
local.height,
|
|
449
|
+
);
|
|
450
|
+
};
|
|
451
|
+
|
|
459
452
|
/**
|
|
460
453
|
* Calculates the Euclidean distance in pixels between the current pointer
|
|
461
454
|
* coordinates and a drag target's position within the layout.
|
|
@@ -476,7 +469,47 @@ export class RegularLayout extends HTMLElement {
|
|
|
476
469
|
return Math.sqrt(dx ** 2 + dy ** 2);
|
|
477
470
|
};
|
|
478
471
|
|
|
479
|
-
|
|
472
|
+
// ▇█████████████████■■■■ȺȺȺȺȺ▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀ȺȺȺȺȺ■■■■■█████████████████
|
|
473
|
+
// ███████▛▀▀█▃▄▄▅▆▆▆▇▇▇██████████████████████████████▇▇▇▆▆▆▅▅▄▃█▀▀▜███████
|
|
474
|
+
// ████▛▚▅▇███▍ ▗▄▃¯"▜██▘ ▜██▍ ▀█▋ ▐█▀▔▂▄▃ ▔▜█ ▗▃▃▃▄▊ ▄▄▃ ▔▜██▇▅▃▀████
|
|
475
|
+
// ███▋╺██████▍ ▐██▋ █▘ ◨Ƚ "██▍ ▙▁ ▀ ▐▋ █▛▀▀▀▜█ ´▂▂Ŋ█▊ °"▔ ▃██████▍▐███
|
|
476
|
+
// ████▄▝▜████▍ ▝▀▀ ▂▟▘ ▄▄▄▄ "█▍ ██▄ ▐█▃ ▝▀▀ ▐█ ▝▀▀▀▀▊ ██▖ ▝████▛▀▄████
|
|
477
|
+
// ██████▇▆▄▃█▀▀Ⱥ▼■███▇▇████▇▇█▇▇████▇████▇▇▇████▇▇▇▇▇▇▇█▇■◘▀▀▀▀▂▃▄▅▇██████
|
|
478
|
+
// ███████████████▇▇▆▆▆▅▅▅▅▅▅▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▅▅▅▅▅▅▆▆▆▇▇███████████████
|
|
479
|
+
//
|
|
480
|
+
//
|
|
481
|
+
// ┏▅▅▖ ▗▅▅▶ ▅▅▅▅▅▅▅ ▗▅▅▅▅▅▅▖ ▅▅▅▅▅▄▄▂ ▃▅▆▆▆▄▁ ┏▅▅▖ ▅▅▖▅▅▅▅▅▅▅▅▅
|
|
482
|
+
// ┣██▌▗██▛ ██▊▔▔▔▔ ▐██▋▔▔▔` ███▍"▜██▙ ▟██▘▔███▖ ▐██▌ ██▌^▔▔███^▔^
|
|
483
|
+
// ┣██▙██▋ ██▊▂▂▂ ▐██▋▂▂▂ ███▍ ▐██▋ ▐███ ▐██▋ ▐██▌ ██▌ ███▎
|
|
484
|
+
// ┣██████▌ ███▀▀▀ ▐███▀▀▘ ██████▛▀ ▐███ ▐██▋ ▐██▌ ██▌ ███▎
|
|
485
|
+
// ┣██▛ ▜██▖ ██▊ ▐██▋ ███▍ ▝███ ▟██▌ ▐██▌ ██▌ ███▎
|
|
486
|
+
// ┣██▌ ███ ███▆▆▆▆▎▐███▆▆▆▅ ███▍ ▀██▙▅██▛ ▝███▅▆██▘ ███▎
|
|
487
|
+
// ▔▔▔` ´▔▔` ▔▔▔▔▔▔▔ ´▔▔▔▔▔▔▔ ▔▔▔ ▔""▔¯ ▔""^▔ ▔▔▔
|
|
488
|
+
|
|
489
|
+
private create_overlay_host(): OverlayHost {
|
|
490
|
+
const self = this;
|
|
491
|
+
return {
|
|
492
|
+
get panel() {
|
|
493
|
+
return self._panel;
|
|
494
|
+
},
|
|
495
|
+
get physics() {
|
|
496
|
+
return self._physics;
|
|
497
|
+
},
|
|
498
|
+
get stylesheet() {
|
|
499
|
+
return self._stylesheet;
|
|
500
|
+
},
|
|
501
|
+
get presizeQueue() {
|
|
502
|
+
return self._presizeQueue;
|
|
503
|
+
},
|
|
504
|
+
relativeCoordinates: (event, recalculate) =>
|
|
505
|
+
self.relativeCoordinates(event, recalculate),
|
|
506
|
+
restore: (layout, isFlattened) => self.restore(layout, isFlattened),
|
|
507
|
+
querySelector: (selectors) => self.querySelector(selectors),
|
|
508
|
+
dispatchEvent: (event) => self.dispatchEvent(event),
|
|
509
|
+
};
|
|
510
|
+
}
|
|
511
|
+
|
|
512
|
+
private onDblClick = async (event: MouseEvent) => {
|
|
480
513
|
const [col, row, rect] = this.relativeCoordinates(event, false);
|
|
481
514
|
const divider = calculate_intersection(col, row, this._panel, {
|
|
482
515
|
rect,
|
|
@@ -490,7 +523,7 @@ export class RegularLayout extends HTMLElement {
|
|
|
490
523
|
undefined,
|
|
491
524
|
);
|
|
492
525
|
|
|
493
|
-
this.restore(panel, true);
|
|
526
|
+
await this.restore(panel, true);
|
|
494
527
|
}
|
|
495
528
|
};
|
|
496
529
|
|
|
@@ -507,15 +540,17 @@ export class RegularLayout extends HTMLElement {
|
|
|
507
540
|
}
|
|
508
541
|
};
|
|
509
542
|
|
|
510
|
-
private onPointerMove = (event: PointerEvent) => {
|
|
543
|
+
private onPointerMove = async (event: PointerEvent) => {
|
|
511
544
|
if (this._drag_target) {
|
|
512
545
|
const [col, row] = this.relativeCoordinates(event, false);
|
|
513
546
|
const [{ path, type }, old_col, old_row] = this._drag_target;
|
|
514
547
|
const offset = type === "horizontal" ? old_col - col : old_row - row;
|
|
515
548
|
const panel = redistribute_panel_sizes(this._panel, path, offset);
|
|
516
|
-
this.
|
|
517
|
-
|
|
518
|
-
|
|
549
|
+
await this._presizeQueue.run(panel, () => {
|
|
550
|
+
this._stylesheet.replaceSync(
|
|
551
|
+
create_css_grid_layout(panel, undefined, this._physics),
|
|
552
|
+
);
|
|
553
|
+
});
|
|
519
554
|
}
|
|
520
555
|
|
|
521
556
|
if (this._physics.GRID_DIVIDER_CHECK_TARGET && event.target !== this) {
|
|
@@ -545,14 +580,14 @@ export class RegularLayout extends HTMLElement {
|
|
|
545
580
|
}
|
|
546
581
|
};
|
|
547
582
|
|
|
548
|
-
private onPointerUp = (event: PointerEvent) => {
|
|
583
|
+
private onPointerUp = async (event: PointerEvent) => {
|
|
549
584
|
if (this._drag_target) {
|
|
550
585
|
this.releasePointerCapture(event.pointerId);
|
|
551
586
|
const [col, row] = this.relativeCoordinates(event, false);
|
|
552
587
|
const [{ path, type }, old_col, old_row] = this._drag_target;
|
|
553
588
|
const offset = type === "horizontal" ? old_col - col : old_row - row;
|
|
554
589
|
const panel = redistribute_panel_sizes(this._panel, path, offset);
|
|
555
|
-
this.restore(panel, true);
|
|
590
|
+
await this.restore(panel, true);
|
|
556
591
|
this._drag_target = undefined;
|
|
557
592
|
}
|
|
558
593
|
};
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
/* ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
|
|
2
|
+
* ░░░░░░░░▄▀░█▀▄░█▀▀░█▀▀░█░█░█░░░█▀█░█▀▄░░░░░█░░░█▀█░█░█░█▀█░█░█░▀█▀░▀▄░░░░░░░░
|
|
3
|
+
* ░░░░░░░▀▄░░█▀▄░█▀▀░█░█░█░█░█░░░█▀█░█▀▄░▀▀▀░█░░░█▀█░░█░░█░█░█░█░░█░░░▄▀░░░░░░░
|
|
4
|
+
* ░░░░░░░░░▀░▀░▀░▀▀▀░▀▀▀░▀▀▀░▀▀▀░▀░▀░▀░▀░░░░░▀▀▀░▀░▀░░▀░░▀▀▀░▀▀▀░░▀░░▀░░░░░░░░░
|
|
5
|
+
* ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
|
|
6
|
+
* ┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
|
|
7
|
+
* ┃ * Copyright (c) 2026, the Regular Layout Authors. This file is part * ┃
|
|
8
|
+
* ┃ * of the Regular Layout library, distributed under the terms of the * ┃
|
|
9
|
+
* ┃ * [Apache License 2.0](https://www.apache.org/licenses/LICENSE-2.0). * ┃
|
|
10
|
+
* ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
regular-layout.borland {
|
|
14
|
+
background-color: #0000aa;
|
|
15
|
+
font-family:
|
|
16
|
+
"ui-monospace", "SFMono-Regular", "SF Mono", "Menlo", "Consolas",
|
|
17
|
+
"Liberation Mono", monospace;
|
|
18
|
+
padding: 16px;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
/* Frame */
|
|
22
|
+
regular-layout.borland regular-layout-frame {
|
|
23
|
+
position: relative;
|
|
24
|
+
box-sizing: border-box;
|
|
25
|
+
margin: 4px;
|
|
26
|
+
background: #0000aa;
|
|
27
|
+
border: 1px solid #00aaaa;
|
|
28
|
+
box-shadow: 1px 1px 0 #000000;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
regular-layout.borland regular-layout-frame::part(container) {
|
|
32
|
+
padding: 4px 6px;
|
|
33
|
+
color: #ffff55;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
regular-layout.borland regular-layout-frame::part(close) {
|
|
37
|
+
background: #00aa00;
|
|
38
|
+
height: 16px;
|
|
39
|
+
align-self: center;
|
|
40
|
+
display: flex;
|
|
41
|
+
align-items: center;
|
|
42
|
+
justify-content: center;
|
|
43
|
+
padding: 0 3px;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
regular-layout.borland regular-layout-frame::part(close):hover {
|
|
47
|
+
background: #00ff00;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
regular-layout.borland regular-layout-frame::part(close):before {
|
|
51
|
+
content: "[×]";
|
|
52
|
+
font-size: 10px;
|
|
53
|
+
font-weight: bold;
|
|
54
|
+
color: #000000;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
regular-layout.borland regular-layout-frame::part(titlebar) {
|
|
58
|
+
display: flex;
|
|
59
|
+
align-items: stretch;
|
|
60
|
+
padding-right: 0;
|
|
61
|
+
height: 22px;
|
|
62
|
+
background: #0000aa;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
regular-layout.borland regular-layout-frame::part(tab) {
|
|
66
|
+
display: flex;
|
|
67
|
+
flex: 1 1 150px;
|
|
68
|
+
align-items: center;
|
|
69
|
+
padding: 0 3px 0 8px;
|
|
70
|
+
cursor: pointer;
|
|
71
|
+
text-overflow: ellipsis;
|
|
72
|
+
background: #0000aa;
|
|
73
|
+
color: #aaaaaa;
|
|
74
|
+
font-size: 11px;
|
|
75
|
+
font-weight: bold;
|
|
76
|
+
border-right: 1px solid #00aaaa;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
regular-layout.borland regular-layout-frame::part(active-tab) {
|
|
80
|
+
background: #00aaaa;
|
|
81
|
+
color: #000000;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
regular-layout.borland:has(.overlay) > * {
|
|
85
|
+
opacity: 0.6;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
regular-layout.borland:has(.overlay) > .overlay {
|
|
89
|
+
opacity: 1;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
/* Frame in Overlay Mode */
|
|
93
|
+
regular-layout.borland regular-layout-frame.overlay {
|
|
94
|
+
background: rgba(0, 170, 170, 0.9);
|
|
95
|
+
border: 1px solid #ffff55;
|
|
96
|
+
box-shadow: none;
|
|
97
|
+
margin: 0;
|
|
98
|
+
transition:
|
|
99
|
+
top 0.05s linear,
|
|
100
|
+
height 0.05s linear,
|
|
101
|
+
width 0.05s linear,
|
|
102
|
+
left 0.05s linear;
|
|
103
|
+
}
|
package/themes/chicago.css
CHANGED
|
@@ -11,79 +11,85 @@
|
|
|
11
11
|
*/
|
|
12
12
|
|
|
13
13
|
regular-layout.chicago {
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
14
|
+
background-color: #008080;
|
|
15
|
+
font-family:
|
|
16
|
+
"ui-monospace", "SFMono-Regular", "SF Mono", "Menlo", "Consolas",
|
|
17
|
+
"Liberation Mono", monospace;
|
|
18
|
+
padding: 24px;
|
|
17
19
|
}
|
|
18
20
|
|
|
19
21
|
/* Frame */
|
|
20
22
|
regular-layout.chicago regular-layout-frame {
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
23
|
+
position: relative;
|
|
24
|
+
box-sizing: border-box;
|
|
25
|
+
margin: 12px;
|
|
26
|
+
background: #c0c0c0;
|
|
27
|
+
border-width: 2px;
|
|
28
|
+
border-color: #ffffff #808080 #808080 #ffffff;
|
|
29
|
+
border-style: solid;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
regular-layout.chicago regular-layout-frame::part(container) {
|
|
33
|
+
padding: 6px;
|
|
28
34
|
}
|
|
29
35
|
|
|
30
36
|
regular-layout.chicago regular-layout-frame::part(close) {
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
37
|
+
border-width: 1px;
|
|
38
|
+
border-color: #ffffff #808080 #808080 #ffffff;
|
|
39
|
+
border-style: solid;
|
|
40
|
+
height: 16px;
|
|
41
|
+
background: #c0c0c0;
|
|
42
|
+
align-self: center;
|
|
43
|
+
display: flex;
|
|
44
|
+
align-items: center;
|
|
45
|
+
padding: 0px 4px;
|
|
40
46
|
}
|
|
41
47
|
|
|
42
48
|
regular-layout.chicago regular-layout-frame::part(close):before {
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
49
|
+
content: "X";
|
|
50
|
+
font-size: 10px;
|
|
51
|
+
font-weight: bold;
|
|
46
52
|
}
|
|
47
53
|
|
|
48
54
|
regular-layout.chicago regular-layout-frame::part(titlebar) {
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
55
|
+
display: flex;
|
|
56
|
+
align-items: stretch;
|
|
57
|
+
padding-right: 0px;
|
|
52
58
|
}
|
|
53
59
|
|
|
54
60
|
regular-layout.chicago regular-layout-frame::part(tab) {
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
61
|
+
display: flex;
|
|
62
|
+
flex: 1 1 150px;
|
|
63
|
+
align-items: center;
|
|
64
|
+
padding: 0 3px 0 8px;
|
|
65
|
+
cursor: pointer;
|
|
66
|
+
text-overflow: ellipsis;
|
|
67
|
+
background: #808080;
|
|
68
|
+
color: #fff;
|
|
69
|
+
font-family: "Tahoma", "Arial", sans-serif;
|
|
70
|
+
font-weight: bold;
|
|
71
|
+
font-size: 11px;
|
|
66
72
|
}
|
|
67
73
|
|
|
68
74
|
regular-layout.chicago regular-layout-frame::part(active-tab) {
|
|
69
|
-
|
|
70
|
-
|
|
75
|
+
background: #000080;
|
|
76
|
+
opacity: 1;
|
|
71
77
|
}
|
|
72
78
|
|
|
73
|
-
regular-layout.chicago:has(.overlay)
|
|
74
|
-
|
|
79
|
+
regular-layout.chicago:has(.overlay) > * {
|
|
80
|
+
opacity: 0.8;
|
|
75
81
|
}
|
|
76
82
|
|
|
77
|
-
regular-layout.chicago:has(.overlay)
|
|
78
|
-
|
|
83
|
+
regular-layout.chicago:has(.overlay) > .overlay {
|
|
84
|
+
opacity: 1;
|
|
79
85
|
}
|
|
80
86
|
|
|
81
87
|
/* Frame in Overlay Mode */
|
|
82
88
|
regular-layout.chicago regular-layout-frame.overlay {
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
}
|
|
89
|
+
margin: 0;
|
|
90
|
+
transition:
|
|
91
|
+
top 0.1s ease-in-out,
|
|
92
|
+
height 0.1s ease-in-out,
|
|
93
|
+
width 0.1s ease-in-out,
|
|
94
|
+
left 0.1s ease-in-out;
|
|
95
|
+
}
|