@n-uf/placement 26.11.9 → 26.11.10
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/CHANGELOG.md +33 -0
- package/README.md +89 -7
- package/dist/{chunk-XUV6MJ2P.js → chunk-7R5H2ABL.js} +38 -4
- package/dist/chunk-7R5H2ABL.js.map +1 -0
- package/dist/{chunk-PWQWD2CS.js → chunk-PJD5HKYX.js} +240 -25
- package/dist/chunk-PJD5HKYX.js.map +1 -0
- package/dist/desk.d.ts +12 -6
- package/dist/desk.js +35 -7
- package/dist/desk.js.map +1 -1
- package/dist/panels.d.ts +12 -3
- package/dist/panels.js +14 -2
- package/dist/{targets-DwOTs4UC.d.ts → targets-CLV69zMw.d.ts} +150 -22
- package/dist/targets.d.ts +1 -1
- package/dist/targets.js +1 -1
- package/package.json +1 -1
- package/dist/chunk-PWQWD2CS.js.map +0 -1
- package/dist/chunk-XUV6MJ2P.js.map +0 -1
|
@@ -4,6 +4,8 @@ import {
|
|
|
4
4
|
|
|
5
5
|
// src/panels/model.ts
|
|
6
6
|
var SIDES = ["left", "right"];
|
|
7
|
+
var EDGES = ["top", "bottom"];
|
|
8
|
+
var BAND_SIZE = { min: 120, max: 480, natural: 200 };
|
|
7
9
|
var IDENTITY_VIEW = { x: 0, y: 0, scale: 1 };
|
|
8
10
|
var DEFAULT_PANELS_OPTIONS = {
|
|
9
11
|
giveWay: { order: "oldest", by: "used" },
|
|
@@ -16,7 +18,10 @@ var DEFAULT_PANELS_OPTIONS = {
|
|
|
16
18
|
rail: 36,
|
|
17
19
|
segment: 36,
|
|
18
20
|
railInset: 4,
|
|
19
|
-
tabs: 28
|
|
21
|
+
tabs: 28,
|
|
22
|
+
bands: {},
|
|
23
|
+
pagesMinHeight: 240,
|
|
24
|
+
reserve: {}
|
|
20
25
|
};
|
|
21
26
|
var FLOAT_HEIGHT = 360;
|
|
22
27
|
var FLOAT_MIN = { width: 160, height: 120 };
|
|
@@ -27,6 +32,10 @@ function whereIs(state, id) {
|
|
|
27
32
|
const index = state.sides[side].findIndex((c) => c.panels.includes(id));
|
|
28
33
|
if (index >= 0) return { kind: "column", side, index };
|
|
29
34
|
}
|
|
35
|
+
for (const edge of EDGES) {
|
|
36
|
+
const index = state.bands?.[edge]?.panels.indexOf(id) ?? -1;
|
|
37
|
+
if (index >= 0) return { kind: "band", edge, index };
|
|
38
|
+
}
|
|
30
39
|
const float2 = state.floats.find((f) => f.id === id);
|
|
31
40
|
return float2 ? { kind: "float", float: float2 } : { kind: "none" };
|
|
32
41
|
}
|
|
@@ -42,6 +51,21 @@ function floatSize(def) {
|
|
|
42
51
|
const width = Math.max(FLOAT_MIN.width, def?.width.natural ?? FLOAT_MIN.width);
|
|
43
52
|
return { min: FLOAT_MIN, natural: { width, height: FLOAT_HEIGHT } };
|
|
44
53
|
}
|
|
54
|
+
var bandSize = (def) => ({ ...def?.band ?? BAND_SIZE });
|
|
55
|
+
function bandHeight(defs, band) {
|
|
56
|
+
if (!defs) return band.height;
|
|
57
|
+
const ds = band.panels.map((id) => bandSize(defOf(defs, id)));
|
|
58
|
+
const lo = Math.max(0, ...ds.map((d) => d.min));
|
|
59
|
+
const hi = Math.max(lo, Math.min(...ds.map((d) => d.max)));
|
|
60
|
+
return Math.min(Math.max(Number.isFinite(band.height) ? band.height : lo, lo), hi);
|
|
61
|
+
}
|
|
62
|
+
var withBand = (state, edge, band) => {
|
|
63
|
+
const { bands: _b, ...rest } = state;
|
|
64
|
+
const bands = { ...state.bands };
|
|
65
|
+
if (band && band.panels.length) bands[edge] = band;
|
|
66
|
+
else delete bands[edge];
|
|
67
|
+
return EDGES.some((e) => bands[e]) ? { ...rest, bands } : rest;
|
|
68
|
+
};
|
|
45
69
|
function ownWidth(defs, state, id) {
|
|
46
70
|
const def = defOf(defs, id);
|
|
47
71
|
const w = whereIs(state, id);
|
|
@@ -63,10 +87,18 @@ function createPanels(defs, start) {
|
|
|
63
87
|
return { id: f.id, rect: { x: f.x, y: f.y, width: f.width ?? n.width, height: f.height ?? n.height }, ...f.pinned ? { pinned: true } : {} };
|
|
64
88
|
});
|
|
65
89
|
const sides = { left: (start.left ?? []).map(column), right: (start.right ?? []).map(column) };
|
|
66
|
-
const
|
|
90
|
+
const bands = {};
|
|
91
|
+
for (const edge of EDGES) {
|
|
92
|
+
const ids = start[edge] ?? [];
|
|
93
|
+
if (!ids.length) continue;
|
|
94
|
+
const natural = Math.max(0, ...ids.map((id) => bandSize(defOf(defs, id)).natural));
|
|
95
|
+
bands[edge] = { panels: [...ids], height: bandHeight(defs, { panels: ids, height: natural }) };
|
|
96
|
+
}
|
|
97
|
+
const order = [...sides.left, ...sides.right].flatMap((c) => c.panels).concat(EDGES.flatMap((e) => bands[e]?.panels ?? [])).concat(floats.map((f) => f.id));
|
|
67
98
|
const clock = {};
|
|
68
99
|
order.forEach((id, i) => clock[id] = { opened: i + 1, used: i + 1 });
|
|
69
|
-
|
|
100
|
+
const s = { sides, floats, folded: [...start.folded ?? []], kept: [...start.kept ?? []], closed: [...start.closed ?? []], clock };
|
|
101
|
+
return EDGES.some((e) => bands[e]) ? { ...s, bands } : s;
|
|
70
102
|
}
|
|
71
103
|
function liftPanel(state, id) {
|
|
72
104
|
const out = (c) => {
|
|
@@ -74,11 +106,22 @@ function liftPanel(state, id) {
|
|
|
74
106
|
return { ...c.active === id ? rest : c, panels: without(c.panels, id) };
|
|
75
107
|
};
|
|
76
108
|
const lift = (cols) => cols.map(out).filter((c) => c.panels.length > 0);
|
|
77
|
-
|
|
109
|
+
let s = { ...state, sides: { left: lift(state.sides.left), right: lift(state.sides.right) }, floats: state.floats.filter((f) => f.id !== id) };
|
|
110
|
+
for (const edge of EDGES) {
|
|
111
|
+
const b = s.bands?.[edge];
|
|
112
|
+
if (b?.panels.includes(id)) s = withBand(s, edge, { ...b, panels: without(b.panels, id) });
|
|
113
|
+
}
|
|
114
|
+
return s;
|
|
78
115
|
}
|
|
79
116
|
function open(state, id, at) {
|
|
80
117
|
let s = { ...state, closed: without(state.closed, id) };
|
|
81
|
-
if (at && whereIs(s, id).kind === "none")
|
|
118
|
+
if (at && whereIs(s, id).kind === "none") {
|
|
119
|
+
if ("edge" in at) {
|
|
120
|
+
const b = s.bands?.[at.edge];
|
|
121
|
+
const panels = [...b?.panels ?? [], id];
|
|
122
|
+
s = withBand({ ...s, folded: s.folded.filter((x) => !panels.includes(x)) }, at.edge, { panels, height: b?.height ?? at.height ?? BAND_SIZE.natural });
|
|
123
|
+
} else s = { ...s, sides: { ...s.sides, [at.side]: [...s.sides[at.side], { panels: [id], width: at.width }] } };
|
|
124
|
+
}
|
|
82
125
|
const w = whereIs(s, id);
|
|
83
126
|
if (w.kind === "column" && s.sides[w.side][w.index].show === "tabs") s = { ...s, sides: { ...s.sides, [w.side]: s.sides[w.side].map((c, i) => i === w.index ? { ...c, active: id } : c) } };
|
|
84
127
|
return bump(s, id, true);
|
|
@@ -90,12 +133,37 @@ function focus(state, id) {
|
|
|
90
133
|
return bump(s, id, false);
|
|
91
134
|
}
|
|
92
135
|
function toggleFold(state, id) {
|
|
136
|
+
const w = whereIs(state, id);
|
|
137
|
+
if (w.kind === "band") {
|
|
138
|
+
const ids = state.bands[w.edge].panels;
|
|
139
|
+
const shown = ids.filter((x) => !state.closed.includes(x));
|
|
140
|
+
if ((shown.length ? shown : ids).every((x) => state.folded.includes(x))) return bump({ ...state, folded: state.folded.filter((x) => !ids.includes(x)) }, id, false);
|
|
141
|
+
return { ...state, folded: [...state.folded.filter((x) => !ids.includes(x)), ...ids] };
|
|
142
|
+
}
|
|
93
143
|
if (state.folded.includes(id)) return bump({ ...state, folded: without(state.folded, id) }, id, false);
|
|
94
144
|
return { ...state, folded: [...state.folded, id] };
|
|
95
145
|
}
|
|
96
146
|
function keep(state, id, on) {
|
|
97
147
|
if (!on) return { ...state, kept: without(state.kept, id) };
|
|
98
|
-
|
|
148
|
+
const k = whereIs(state, id).kind;
|
|
149
|
+
return k === "column" || k === "band" ? { ...state, kept: withOnce(state.kept, id) } : state;
|
|
150
|
+
}
|
|
151
|
+
function dockBand(state, id, edge, index, defs) {
|
|
152
|
+
const s = liftPanel(state, id);
|
|
153
|
+
const b = s.bands?.[edge];
|
|
154
|
+
const panels = [...b?.panels ?? []];
|
|
155
|
+
panels.splice(Math.max(0, Math.min(index, panels.length)), 0, id);
|
|
156
|
+
const height = b?.height ?? bandSize(defs ? defOf(defs, id) : void 0).natural;
|
|
157
|
+
const s1 = withBand(s, edge, { panels, height });
|
|
158
|
+
return bump({ ...s1, folded: s1.folded.filter((x) => !panels.includes(x)), closed: without(s1.closed, id) }, id, false);
|
|
159
|
+
}
|
|
160
|
+
function resizeBand(state, edge, height) {
|
|
161
|
+
const b = state.bands?.[edge];
|
|
162
|
+
if (!b || !Number.isFinite(height)) return state;
|
|
163
|
+
const t = tick(state);
|
|
164
|
+
const clock = { ...state.clock };
|
|
165
|
+
for (const id of b.panels) clock[id] = { opened: clock[id]?.opened ?? 0, used: t };
|
|
166
|
+
return { ...withBand(state, edge, { ...b, height: Math.max(0, height) }), clock };
|
|
99
167
|
}
|
|
100
168
|
function dock(state, id, side, index, options = {}) {
|
|
101
169
|
const w = whereIs(state, id);
|
|
@@ -164,8 +232,12 @@ function samePlaces(a, b, defs) {
|
|
|
164
232
|
(side) => s.sides[side].map((c) => `${c.panels.join(",")}@${Math.round(columnWidth(defs, c))}${c.show === "tabs" ? `/tabs:${c.active ?? c.panels[0]}` : ""}`).join("|")
|
|
165
233
|
).join("\u2016");
|
|
166
234
|
const fl = (s) => s.floats.map((f) => `${f.id}@${Math.round(f.rect.x)},${Math.round(f.rect.y)},${Math.round(f.rect.width)},${Math.round(f.rect.height)}${f.pinned ? "p" : ""}`).join("|");
|
|
235
|
+
const bs = (s) => EDGES.map((e) => {
|
|
236
|
+
const b2 = s.bands?.[e];
|
|
237
|
+
return b2 ? `${b2.panels.join(",")}@${Math.round(bandHeight(defs, b2))}` : "";
|
|
238
|
+
}).join("\u2016");
|
|
167
239
|
const set = (l) => [...l].sort().join(",");
|
|
168
|
-
return cols(a) === cols(b) && fl(a) === fl(b) && set(a.folded) === set(b.folded) && set(a.kept) === set(b.kept) && set(a.closed) === set(b.closed);
|
|
240
|
+
return cols(a) === cols(b) && bs(a) === bs(b) && fl(a) === fl(b) && set(a.folded) === set(b.folded) && set(a.kept) === set(b.kept) && set(a.closed) === set(b.closed);
|
|
169
241
|
}
|
|
170
242
|
|
|
171
243
|
// src/panels/layout.ts
|
|
@@ -182,6 +254,67 @@ function layoutPanels(defs, state, stage, options = {}) {
|
|
|
182
254
|
const kept = new Set(state.kept);
|
|
183
255
|
const by = opt.giveWay.by;
|
|
184
256
|
const ride = opt.fold === "ride";
|
|
257
|
+
const px = (v) => typeof v === "number" && Number.isFinite(v) ? Math.max(0, v) : 0;
|
|
258
|
+
const reserveOpt = opt.reserve ?? {};
|
|
259
|
+
const bandOpts = opt.bands ?? {};
|
|
260
|
+
const minH = typeof opt.pagesMinHeight === "number" ? opt.pagesMinHeight : DEFAULT_PANELS_OPTIONS.pagesMinHeight;
|
|
261
|
+
const res = { top: px(reserveOpt.top), right: px(reserveOpt.right), bottom: px(reserveOpt.bottom), left: px(reserveOpt.left) };
|
|
262
|
+
const bandsIn = [];
|
|
263
|
+
const offNotes = [];
|
|
264
|
+
for (const edge of EDGES) {
|
|
265
|
+
const b = state.bands?.[edge];
|
|
266
|
+
if (!b) continue;
|
|
267
|
+
const panels = b.panels.filter((id) => !closed.has(id));
|
|
268
|
+
if (panels.length === 0) continue;
|
|
269
|
+
const o = bandOpts[edge];
|
|
270
|
+
if (!o) {
|
|
271
|
+
offNotes.push({ code: "band-off", edge, items: panels });
|
|
272
|
+
continue;
|
|
273
|
+
}
|
|
274
|
+
const ds = panels.map((id) => bandSize(defOf(defs, id)));
|
|
275
|
+
const min = Math.max(0, ...ds.map((d) => d.min));
|
|
276
|
+
const max = Math.max(min, Math.min(...ds.map((d) => d.max)));
|
|
277
|
+
const height = clamp(Number.isFinite(b.height) ? b.height : min, min, max);
|
|
278
|
+
const age = Math.max(...panels.map((id) => state.clock[id]?.[by] ?? 0));
|
|
279
|
+
bandsIn.push({ edge, panels, at: panels.map((id) => b.panels.indexOf(id)), min, max, height, hand: panels.every((id) => folded.has(id)), kept: panels.some((id) => kept.has(id)), age, mode: o.mode, span: o.span });
|
|
280
|
+
}
|
|
281
|
+
const bOrder = bandsIn.filter((b) => !b.hand).sort((a, b) => Number(a.kept) - Number(b.kept) || (opt.giveWay.order === "oldest" ? a.age - b.age : b.age - a.age) || EDGES.indexOf(b.edge) - EDGES.indexOf(a.edge));
|
|
282
|
+
const gh = { auto: /* @__PURE__ */ new Set(), heights: /* @__PURE__ */ new Map() };
|
|
283
|
+
const fitH = (list, room) => {
|
|
284
|
+
const order2 = bOrder.filter((b) => list.includes(b));
|
|
285
|
+
const hands = list.length - order2.length;
|
|
286
|
+
const fit2 = (k) => {
|
|
287
|
+
const auto = new Set(order2.slice(0, k));
|
|
288
|
+
const heights = new Map(order2.filter((b) => !auto.has(b)).map((b) => [b, b.height]));
|
|
289
|
+
let excess = [...heights.values()].reduce((a, b) => a + b, 0) + (hands + auto.size) * opt.bar - room;
|
|
290
|
+
for (const b of order2) {
|
|
291
|
+
if (excess <= 0 || auto.has(b)) continue;
|
|
292
|
+
const take = Math.min(excess, b.height - b.min);
|
|
293
|
+
if (take > 0) {
|
|
294
|
+
heights.set(b, b.height - take);
|
|
295
|
+
excess -= take;
|
|
296
|
+
}
|
|
297
|
+
}
|
|
298
|
+
return { auto, heights, excess };
|
|
299
|
+
};
|
|
300
|
+
let g2 = fit2(0);
|
|
301
|
+
for (let k = 1; g2.excess > 0 && k <= order2.length; k++) g2 = fit2(k);
|
|
302
|
+
for (const b of g2.auto) gh.auto.add(b);
|
|
303
|
+
for (const [b, h] of g2.heights) gh.heights.set(b, h);
|
|
304
|
+
};
|
|
305
|
+
const reservedIn = bandsIn.filter((b) => b.mode === "reserved");
|
|
306
|
+
const overlayIn = bandsIn.filter((b) => b.mode === "overlay");
|
|
307
|
+
fitH(reservedIn, H - res.top - res.bottom - Math.max(minH, overlayIn.length * opt.bar));
|
|
308
|
+
const bandH = (b) => b ? gh.heights.get(b) ?? opt.bar : 0;
|
|
309
|
+
const pagesH = H - res.top - res.bottom - reservedIn.reduce((a, b) => a + bandH(b), 0);
|
|
310
|
+
fitH(overlayIn, pagesH - minH);
|
|
311
|
+
const topB = bandsIn.find((b) => b.edge === "top");
|
|
312
|
+
const botB = bandsIn.find((b) => b.edge === "bottom");
|
|
313
|
+
const hT = bandH(topB);
|
|
314
|
+
const hB = bandH(botB);
|
|
315
|
+
const colTop = topB?.span === "full" ? (topB.mode === "overlay" ? res.top : 0) + hT : 0;
|
|
316
|
+
const colBot = botB?.span === "full" ? H - (botB.mode === "overlay" ? res.bottom : 0) - hB : H;
|
|
317
|
+
const CH = Math.max(0, colBot - colTop);
|
|
185
318
|
const cols = [];
|
|
186
319
|
for (const side of SIDES) {
|
|
187
320
|
state.sides[side].forEach((c, index) => {
|
|
@@ -261,7 +394,7 @@ function layoutPanels(defs, state, stage, options = {}) {
|
|
|
261
394
|
const open2 = (side) => cols.some((c) => c.side === side && !c.hand && !auto.has(c));
|
|
262
395
|
const railed = (side) => cols.some((c) => c.side === side && (auto.has(c) || c.hand && !(ride && open2(side))));
|
|
263
396
|
const widths = new Map(order.filter((c) => !auto.has(c)).map((c) => [c, c.width]));
|
|
264
|
-
let excess = [...widths.values()].reduce((a, b) => a + b, 0) + SIDES.filter(railed).length * opt.rail + opt.pagesMin - W;
|
|
397
|
+
let excess = [...widths.values()].reduce((a, b) => a + b, 0) + SIDES.filter(railed).length * opt.rail + opt.pagesMin + res.left + res.right - W;
|
|
265
398
|
for (const c of order) {
|
|
266
399
|
if (excess <= 0 || auto.has(c)) continue;
|
|
267
400
|
const take = Math.min(excess, c.width - c.min);
|
|
@@ -292,8 +425,8 @@ function layoutPanels(defs, state, stage, options = {}) {
|
|
|
292
425
|
const riders = host ? mine.filter((c) => c.hand) : [];
|
|
293
426
|
const inRail = mine.filter((c) => c.hand && !riders.includes(c) || g.auto.has(c));
|
|
294
427
|
if (inRail.length) {
|
|
295
|
-
const r = side === "left" ? rect(0,
|
|
296
|
-
const segments = inRail.flatMap((c) => c.panels).map((id, i) => ({ id, rect: rect(r.x, opt.railInset + i * opt.segment, opt.rail, opt.segment) }));
|
|
428
|
+
const r = side === "left" ? rect(0, colTop, opt.rail, CH) : rect(W - opt.rail, colTop, opt.rail, CH);
|
|
429
|
+
const segments = inRail.flatMap((c) => c.panels).map((id, i) => ({ id, rect: rect(r.x, colTop + opt.railInset + i * opt.segment, opt.rail, opt.segment) }));
|
|
297
430
|
rails[side] = { side, rect: r, segments };
|
|
298
431
|
for (const s of segments) {
|
|
299
432
|
const c = inRail.find((x) => x.panels.includes(s.id));
|
|
@@ -307,11 +440,11 @@ function layoutPanels(defs, state, stage, options = {}) {
|
|
|
307
440
|
const w = g.widths.get(c);
|
|
308
441
|
if (w === void 0 || riders.includes(c)) continue;
|
|
309
442
|
if (side === "left") {
|
|
310
|
-
at.set(c, rect(x0,
|
|
443
|
+
at.set(c, rect(x0, colTop, w, CH));
|
|
311
444
|
x0 += w;
|
|
312
445
|
} else {
|
|
313
446
|
x1 -= w;
|
|
314
|
-
at.set(c, rect(x1,
|
|
447
|
+
at.set(c, rect(x1, colTop, w, CH));
|
|
315
448
|
}
|
|
316
449
|
}
|
|
317
450
|
const riding = riders.flatMap((c) => c.panels.map((id) => ({ id, c })));
|
|
@@ -324,13 +457,13 @@ function layoutPanels(defs, state, stage, options = {}) {
|
|
|
324
457
|
const hr = at.get(host);
|
|
325
458
|
const first = riding.findIndex((x) => x.c === c);
|
|
326
459
|
c.panels.forEach(
|
|
327
|
-
(id, i) => items.set(id, { rect: rect(hr.x, (first + i) * opt.bar, hr.width, opt.bar), kind: "bar", layer: 0, hidden: false, folded: "hand", kept: kept.has(id), pinned: false, floating: false, side, column: c.index, rides: host.index })
|
|
460
|
+
(id, i) => items.set(id, { rect: rect(hr.x, colTop + (first + i) * opt.bar, hr.width, opt.bar), kind: "bar", layer: 0, hidden: false, folded: "hand", kept: kept.has(id), pinned: false, floating: false, side, column: c.index, rides: host.index })
|
|
328
461
|
);
|
|
329
|
-
placedCols.push({ ...base, rect: rect(hr.x, first * opt.bar, hr.width, c.panels.length * opt.bar), shrunk: false, rides: host.index });
|
|
462
|
+
placedCols.push({ ...base, rect: rect(hr.x, colTop + first * opt.bar, hr.width, c.panels.length * opt.bar), shrunk: false, rides: host.index });
|
|
330
463
|
continue;
|
|
331
464
|
}
|
|
332
|
-
const r = at.get(c) ?? rect(side === "left" ? x0 : x1,
|
|
333
|
-
const y0 = c === host ? top : 0;
|
|
465
|
+
const r = at.get(c) ?? rect(side === "left" ? x0 : x1, colTop, 0, CH);
|
|
466
|
+
const y0 = colTop + (c === host ? top : 0);
|
|
334
467
|
const tabbed = c.show === "tabs";
|
|
335
468
|
const strip = rect(r.x, y0, r.width, opt.tabs);
|
|
336
469
|
const shown = tabbed && w !== void 0 ? { strip, active: c.active } : {};
|
|
@@ -340,7 +473,7 @@ function layoutPanels(defs, state, stage, options = {}) {
|
|
|
340
473
|
items.set(id, { rect: to, kind, layer: 0, hidden: more.hidden ?? false, folded: f, kept: kept.has(id), pinned: false, floating: false, side, column: c.index, ...more.tab ? { tab: more.tab } : {} });
|
|
341
474
|
};
|
|
342
475
|
if (tabbed) {
|
|
343
|
-
const body = rect(r.x, y0 + opt.tabs, r.width, Math.max(0,
|
|
476
|
+
const body = rect(r.x, y0 + opt.tabs, r.width, Math.max(0, colBot - y0 - opt.tabs));
|
|
344
477
|
const shade = folded.has(c.active);
|
|
345
478
|
const tw = r.width / c.panels.length;
|
|
346
479
|
c.panels.forEach((id, i) => {
|
|
@@ -350,7 +483,7 @@ function layoutPanels(defs, state, stage, options = {}) {
|
|
|
350
483
|
});
|
|
351
484
|
continue;
|
|
352
485
|
}
|
|
353
|
-
const hs = sectionHeights(c,
|
|
486
|
+
const hs = sectionHeights(c, colBot - y0);
|
|
354
487
|
let y = y0;
|
|
355
488
|
for (const id of c.panels) {
|
|
356
489
|
const s = hs.get(id);
|
|
@@ -360,8 +493,39 @@ function layoutPanels(defs, state, stage, options = {}) {
|
|
|
360
493
|
for (const id of c.panels) if (hs.get(id).folded === "auto") notes.push({ code: "section-folded", side, column: c.index, items: [id] });
|
|
361
494
|
}
|
|
362
495
|
}
|
|
363
|
-
|
|
496
|
+
for (const b of bOrder) {
|
|
497
|
+
const h = gh.heights.get(b);
|
|
498
|
+
if (h !== void 0 && h < b.height) notes.push({ code: "band-shrunk", edge: b.edge, items: b.panels, from: b.height, to: h });
|
|
499
|
+
}
|
|
500
|
+
for (const b of bOrder) if (gh.auto.has(b)) notes.push({ code: b.kept ? "kept-folded" : "band-folded", edge: b.edge, items: b.panels });
|
|
501
|
+
const pw = Math.max(0, x1 - x0);
|
|
502
|
+
const pTop = topB?.mode === "reserved" ? hT : 0;
|
|
503
|
+
const pBot = botB?.mode === "reserved" ? H - hB : H;
|
|
504
|
+
const reserved = {};
|
|
505
|
+
const iTop = pTop + res.top + (topB?.mode === "overlay" ? hT : 0);
|
|
506
|
+
const iBot = pBot - res.bottom - (botB?.mode === "overlay" ? hB : 0);
|
|
507
|
+
if (res.top > 0) reserved.top = rect(x0, pTop, pw, res.top);
|
|
508
|
+
if (res.right > 0) reserved.right = rect(x0 + pw - res.right, iTop, res.right, Math.max(0, iBot - iTop));
|
|
509
|
+
if (res.bottom > 0) reserved.bottom = rect(x0, pBot - res.bottom, pw, res.bottom);
|
|
510
|
+
if (res.left > 0) reserved.left = rect(x0, iTop, res.left, Math.max(0, iBot - iTop));
|
|
511
|
+
const pages = rect(x0 + res.left, pTop + res.top, Math.max(0, pw - res.left - res.right), Math.max(0, pBot - res.bottom - pTop - res.top));
|
|
364
512
|
if (pages.width < opt.pagesMin) notes.push({ code: "pages-under-min", width: pages.width, min: opt.pagesMin });
|
|
513
|
+
if ((bandsIn.length || res.top + res.bottom > 0) && pages.height < minH - 1e-9) notes.push({ code: "pages-short", height: pages.height, min: minH });
|
|
514
|
+
const bands = {};
|
|
515
|
+
for (const b of bandsIn) {
|
|
516
|
+
const h = bandH(b);
|
|
517
|
+
const full = b.span === "full";
|
|
518
|
+
const over = b.mode === "overlay";
|
|
519
|
+
const y = b.edge === "top" ? over ? res.top : 0 : over ? H - res.bottom - h : H - h;
|
|
520
|
+
const r = full ? rect(0, y, W, h) : rect(x0, y, pw, h);
|
|
521
|
+
const f = b.hand ? "hand" : gh.auto.has(b) ? "auto" : null;
|
|
522
|
+
const hh = gh.heights.get(b);
|
|
523
|
+
bands[b.edge] = { edge: b.edge, rect: r, height: b.height, min: b.min, max: b.max, folded: f, shrunk: hh !== void 0 && hh < b.height, kept: b.kept, mode: b.mode, span: b.span, panels: b.panels };
|
|
524
|
+
const share = r.width / b.panels.length;
|
|
525
|
+
b.panels.forEach(
|
|
526
|
+
(id, i) => items.set(id, { rect: rect(r.x + i * share, r.y, share, h), kind: f ? "bar" : "band", layer: over ? 5 : 0, hidden: false, folded: f, kept: kept.has(id), pinned: false, floating: false, edge: b.edge, index: b.at[i] })
|
|
527
|
+
);
|
|
528
|
+
}
|
|
365
529
|
state.floats.forEach((f, i) => {
|
|
366
530
|
if (closed.has(f.id)) return;
|
|
367
531
|
const shaded = folded.has(f.id);
|
|
@@ -390,7 +554,8 @@ function layoutPanels(defs, state, stage, options = {}) {
|
|
|
390
554
|
...clamped ? { clamped: true } : {}
|
|
391
555
|
});
|
|
392
556
|
});
|
|
393
|
-
|
|
557
|
+
notes.push(...offNotes);
|
|
558
|
+
return { items, columns: placedCols, rails, notes, pages, bands, reserved };
|
|
394
559
|
}
|
|
395
560
|
|
|
396
561
|
// src/panels/targets.ts
|
|
@@ -400,6 +565,8 @@ function placeRank(place) {
|
|
|
400
565
|
switch (place.kind) {
|
|
401
566
|
case "float":
|
|
402
567
|
return 3e3;
|
|
568
|
+
case "band":
|
|
569
|
+
return (place.edge === "top" ? 2e3 : 2500) + Math.min(place.index, 499);
|
|
403
570
|
case "rail":
|
|
404
571
|
return place.side === "left" ? 0 : 1999;
|
|
405
572
|
case "column":
|
|
@@ -412,6 +579,7 @@ function homePlace(state, id) {
|
|
|
412
579
|
const w = whereIs(state, id);
|
|
413
580
|
if (w.kind === "float") return { kind: "float" };
|
|
414
581
|
if (w.kind === "none") return null;
|
|
582
|
+
if (w.kind === "band") return { kind: "band", edge: w.edge, index: w.index };
|
|
415
583
|
return state.sides[w.side][w.index].panels.length === 1 ? { kind: "column", side: w.side, index: w.index } : { kind: "into", side: w.side, index: w.index };
|
|
416
584
|
}
|
|
417
585
|
var cut = (x0, x1, lo, hi) => [Math.max(x0, lo), Math.min(x1, hi)];
|
|
@@ -425,19 +593,38 @@ function panelTargets(input) {
|
|
|
425
593
|
const W = stage.width;
|
|
426
594
|
const H = stage.height;
|
|
427
595
|
const R = COLUMN_REACH;
|
|
596
|
+
const bandOpts = opt.bands ?? {};
|
|
597
|
+
const reserve = opt.reserve ?? {};
|
|
598
|
+
const px = (v) => typeof v === "number" && Number.isFinite(v) ? Math.max(0, v) : 0;
|
|
428
599
|
const out = [];
|
|
600
|
+
const idOf = (place) => {
|
|
601
|
+
switch (place.kind) {
|
|
602
|
+
case "float":
|
|
603
|
+
return "float";
|
|
604
|
+
case "rail":
|
|
605
|
+
return `rail:${place.side}`;
|
|
606
|
+
case "band":
|
|
607
|
+
return s0.bands?.[place.edge] ? `band:${place.edge}:${place.index}` : `band:${place.edge}`;
|
|
608
|
+
default:
|
|
609
|
+
return `${place.kind}:${place.side}:${place.index}`;
|
|
610
|
+
}
|
|
611
|
+
};
|
|
429
612
|
const add = (place, priority, hit, make, free = false) => {
|
|
430
613
|
if (hit.width <= 0 || hit.height <= 0) return;
|
|
431
614
|
if (input.allows && !input.allows(id, place)) return;
|
|
432
615
|
if (place.kind !== "float" && samePlaces(make({ x: 0, y: 0 }, { x: 0, y: 0 }), state, defs)) return;
|
|
433
|
-
out.push({ id: place
|
|
616
|
+
out.push({ id: idOf(place), priority, hit, panel: id, place, order: placeRank(place), make, ...free ? { free: true } : {} });
|
|
434
617
|
};
|
|
618
|
+
const fullTop = l0.bands.top?.span === "full" ? l0.bands.top.rect : null;
|
|
619
|
+
const fullBot = l0.bands.bottom?.span === "full" ? l0.bands.bottom.rect : null;
|
|
620
|
+
const top = fullTop ? fullTop.y + fullTop.height : 0;
|
|
621
|
+
const CH = Math.max(0, (fullBot ? fullBot.y : H) - top);
|
|
435
622
|
for (const side of SIDES) {
|
|
436
623
|
if (def?.sides && !def.sides.includes(side)) continue;
|
|
437
624
|
const left = side === "left";
|
|
438
625
|
const rail = l0.rails[side];
|
|
439
626
|
const edge = rail ? rail.rect.width : RAIL_EDGE;
|
|
440
|
-
const railHit = rail ? rail.rect : left ? rect(0,
|
|
627
|
+
const railHit = rail ? rail.rect : left ? rect(0, top, RAIL_EDGE, CH) : rect(W - RAIL_EDGE, top, RAIL_EDGE, CH);
|
|
441
628
|
add({ kind: "rail", side }, 1, railHit, () => {
|
|
442
629
|
const s = dock(state, id, side, 0, { width });
|
|
443
630
|
return { ...s, folded: [...s.folded.filter((x) => x !== id), id] };
|
|
@@ -447,9 +634,9 @@ function panelTargets(input) {
|
|
|
447
634
|
const hi = left ? W : W - edge;
|
|
448
635
|
const band = (x, outer, i) => {
|
|
449
636
|
const [a, b] = outer ? left ? cut(x, x + 2 * R, lo, hi) : cut(x - 2 * R, x, lo, hi) : cut(x - R, x + R, lo, hi);
|
|
450
|
-
add({ kind: "column", side, index: i }, 2, rect(a,
|
|
637
|
+
add({ kind: "column", side, index: i }, 2, rect(a, top, b - a, CH), () => dock(state, id, side, i, { width }));
|
|
451
638
|
};
|
|
452
|
-
if (open2.length === 0) band(left ? l0.pages.x : l0.pages.x + l0.pages.width, true, s0.sides[side].length);
|
|
639
|
+
if (open2.length === 0) band(left ? l0.pages.x - px(reserve.left) : l0.pages.x + l0.pages.width + px(reserve.right), true, s0.sides[side].length);
|
|
453
640
|
open2.forEach((c, k) => {
|
|
454
641
|
band(left ? c.rect.x : c.rect.x + c.rect.width, k === 0, c.index);
|
|
455
642
|
add({ kind: "into", side, index: c.index }, 2, c.rect, () => dock(state, id, side, c.index, { into: true }));
|
|
@@ -457,6 +644,28 @@ function panelTargets(input) {
|
|
|
457
644
|
const last = open2.at(-1);
|
|
458
645
|
if (last) band(left ? last.rect.x + last.rect.width : last.rect.x, false, last.index + 1);
|
|
459
646
|
}
|
|
647
|
+
const home = whereIs(state, id);
|
|
648
|
+
for (const e of EDGES) {
|
|
649
|
+
if (!bandOpts[e] || def?.sides && !def.sides.includes(e)) continue;
|
|
650
|
+
const pb = l0.bands[e];
|
|
651
|
+
const list = s0.bands?.[e]?.panels ?? [];
|
|
652
|
+
const make = (i) => () => dockBand(state, id, e, i, defs);
|
|
653
|
+
if (!pb) {
|
|
654
|
+
if (home.kind === "band" && home.edge === e && !s0.bands?.[e]) continue;
|
|
655
|
+
const p = l0.pages;
|
|
656
|
+
const h = Math.min(2 * opt.bar, p.height);
|
|
657
|
+
add({ kind: "band", edge: e, index: list.length }, 2, rect(p.x, e === "top" ? p.y : p.y + p.height - h, p.width, h), make(list.length));
|
|
658
|
+
continue;
|
|
659
|
+
}
|
|
660
|
+
const m = pb.panels.length;
|
|
661
|
+
const share = pb.rect.width / m;
|
|
662
|
+
for (let k = 0; k <= m; k++) {
|
|
663
|
+
const i = k < m ? list.indexOf(pb.panels[k]) : list.length;
|
|
664
|
+
const a = pb.rect.x + Math.max(0, k - 0.5) * share;
|
|
665
|
+
const b = pb.rect.x + Math.min(m, k + 0.5) * share;
|
|
666
|
+
add({ kind: "band", edge: e, index: i }, 2, rect(a, pb.rect.y, b - a, pb.rect.height), make(i));
|
|
667
|
+
}
|
|
668
|
+
}
|
|
460
669
|
if (def?.floats !== false) {
|
|
461
670
|
const was = state.floats.find((f) => f.id === id);
|
|
462
671
|
const size = was ? { width: was.rect.width, height: was.rect.height } : floatSize(def).natural;
|
|
@@ -504,6 +713,8 @@ function panelStops(targets, options = {}) {
|
|
|
504
713
|
|
|
505
714
|
export {
|
|
506
715
|
SIDES,
|
|
716
|
+
EDGES,
|
|
717
|
+
BAND_SIZE,
|
|
507
718
|
IDENTITY_VIEW,
|
|
508
719
|
DEFAULT_PANELS_OPTIONS,
|
|
509
720
|
FLOAT_HEIGHT,
|
|
@@ -512,6 +723,8 @@ export {
|
|
|
512
723
|
tick,
|
|
513
724
|
defOf,
|
|
514
725
|
floatSize,
|
|
726
|
+
bandSize,
|
|
727
|
+
bandHeight,
|
|
515
728
|
ownWidth,
|
|
516
729
|
createPanels,
|
|
517
730
|
liftPanel,
|
|
@@ -520,6 +733,8 @@ export {
|
|
|
520
733
|
focus,
|
|
521
734
|
toggleFold,
|
|
522
735
|
keep,
|
|
736
|
+
dockBand,
|
|
737
|
+
resizeBand,
|
|
523
738
|
dock,
|
|
524
739
|
showTabs,
|
|
525
740
|
activate,
|
|
@@ -541,4 +756,4 @@ export {
|
|
|
541
756
|
panelDrop,
|
|
542
757
|
panelStops
|
|
543
758
|
};
|
|
544
|
-
//# sourceMappingURL=chunk-
|
|
759
|
+
//# sourceMappingURL=chunk-PJD5HKYX.js.map
|