@n-uf/placement 26.11.9 → 26.11.11
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 +47 -0
- package/README.md +104 -11
- package/dist/{chunk-XUV6MJ2P.js → chunk-2H3CSPEH.js} +38 -4
- package/dist/chunk-2H3CSPEH.js.map +1 -0
- package/dist/{chunk-PWQWD2CS.js → chunk-CJA6LRHN.js} +283 -34
- package/dist/chunk-CJA6LRHN.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-B_U2Zf7x.d.ts} +180 -27
- 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,20 +133,49 @@ 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);
|
|
102
170
|
const from = w.kind === "column" ? state.sides[w.side][w.index].width : 0;
|
|
103
171
|
const s = liftPanel(state, id);
|
|
104
172
|
const cols = [...s.sides[side]];
|
|
105
|
-
if (options.into && cols[index])
|
|
106
|
-
|
|
173
|
+
if (options.into && cols[index]) {
|
|
174
|
+
const panels = [...cols[index].panels];
|
|
175
|
+
const at = typeof options.at === "number" && !Number.isNaN(options.at) ? Math.max(0, Math.min(Math.floor(options.at), panels.length)) : panels.length;
|
|
176
|
+
panels.splice(at, 0, id);
|
|
177
|
+
cols[index] = { ...cols[index], panels, ...cols[index].show === "tabs" ? { active: id } : {} };
|
|
178
|
+
} else {
|
|
107
179
|
const at = Math.max(0, Math.min(index, cols.length));
|
|
108
180
|
cols.splice(at, 0, { panels: [id], width: options.width ?? from });
|
|
109
181
|
}
|
|
@@ -164,8 +236,12 @@ function samePlaces(a, b, defs) {
|
|
|
164
236
|
(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
237
|
).join("\u2016");
|
|
166
238
|
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("|");
|
|
239
|
+
const bs = (s) => EDGES.map((e) => {
|
|
240
|
+
const b2 = s.bands?.[e];
|
|
241
|
+
return b2 ? `${b2.panels.join(",")}@${Math.round(bandHeight(defs, b2))}` : "";
|
|
242
|
+
}).join("\u2016");
|
|
167
243
|
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);
|
|
244
|
+
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
245
|
}
|
|
170
246
|
|
|
171
247
|
// src/panels/layout.ts
|
|
@@ -182,6 +258,67 @@ function layoutPanels(defs, state, stage, options = {}) {
|
|
|
182
258
|
const kept = new Set(state.kept);
|
|
183
259
|
const by = opt.giveWay.by;
|
|
184
260
|
const ride = opt.fold === "ride";
|
|
261
|
+
const px = (v) => typeof v === "number" && Number.isFinite(v) ? Math.max(0, v) : 0;
|
|
262
|
+
const reserveOpt = opt.reserve ?? {};
|
|
263
|
+
const bandOpts = opt.bands ?? {};
|
|
264
|
+
const minH = typeof opt.pagesMinHeight === "number" ? opt.pagesMinHeight : DEFAULT_PANELS_OPTIONS.pagesMinHeight;
|
|
265
|
+
const res = { top: px(reserveOpt.top), right: px(reserveOpt.right), bottom: px(reserveOpt.bottom), left: px(reserveOpt.left) };
|
|
266
|
+
const bandsIn = [];
|
|
267
|
+
const offNotes = [];
|
|
268
|
+
for (const edge of EDGES) {
|
|
269
|
+
const b = state.bands?.[edge];
|
|
270
|
+
if (!b) continue;
|
|
271
|
+
const panels = b.panels.filter((id) => !closed.has(id));
|
|
272
|
+
if (panels.length === 0) continue;
|
|
273
|
+
const o = bandOpts[edge];
|
|
274
|
+
if (!o) {
|
|
275
|
+
offNotes.push({ code: "band-off", edge, items: panels });
|
|
276
|
+
continue;
|
|
277
|
+
}
|
|
278
|
+
const ds = panels.map((id) => bandSize(defOf(defs, id)));
|
|
279
|
+
const min = Math.max(0, ...ds.map((d) => d.min));
|
|
280
|
+
const max = Math.max(min, Math.min(...ds.map((d) => d.max)));
|
|
281
|
+
const height = clamp(Number.isFinite(b.height) ? b.height : min, min, max);
|
|
282
|
+
const age = Math.max(...panels.map((id) => state.clock[id]?.[by] ?? 0));
|
|
283
|
+
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 });
|
|
284
|
+
}
|
|
285
|
+
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));
|
|
286
|
+
const gh = { auto: /* @__PURE__ */ new Set(), heights: /* @__PURE__ */ new Map() };
|
|
287
|
+
const fitH = (list, room) => {
|
|
288
|
+
const order2 = bOrder.filter((b) => list.includes(b));
|
|
289
|
+
const hands = list.length - order2.length;
|
|
290
|
+
const fit2 = (k) => {
|
|
291
|
+
const auto = new Set(order2.slice(0, k));
|
|
292
|
+
const heights = new Map(order2.filter((b) => !auto.has(b)).map((b) => [b, b.height]));
|
|
293
|
+
let excess = [...heights.values()].reduce((a, b) => a + b, 0) + (hands + auto.size) * opt.bar - room;
|
|
294
|
+
for (const b of order2) {
|
|
295
|
+
if (excess <= 0 || auto.has(b)) continue;
|
|
296
|
+
const take = Math.min(excess, b.height - b.min);
|
|
297
|
+
if (take > 0) {
|
|
298
|
+
heights.set(b, b.height - take);
|
|
299
|
+
excess -= take;
|
|
300
|
+
}
|
|
301
|
+
}
|
|
302
|
+
return { auto, heights, excess };
|
|
303
|
+
};
|
|
304
|
+
let g2 = fit2(0);
|
|
305
|
+
for (let k = 1; g2.excess > 0 && k <= order2.length; k++) g2 = fit2(k);
|
|
306
|
+
for (const b of g2.auto) gh.auto.add(b);
|
|
307
|
+
for (const [b, h] of g2.heights) gh.heights.set(b, h);
|
|
308
|
+
};
|
|
309
|
+
const reservedIn = bandsIn.filter((b) => b.mode === "reserved");
|
|
310
|
+
const overlayIn = bandsIn.filter((b) => b.mode === "overlay");
|
|
311
|
+
fitH(reservedIn, H - res.top - res.bottom - Math.max(minH, overlayIn.length * opt.bar));
|
|
312
|
+
const bandH = (b) => b ? gh.heights.get(b) ?? opt.bar : 0;
|
|
313
|
+
const pagesH = H - res.top - res.bottom - reservedIn.reduce((a, b) => a + bandH(b), 0);
|
|
314
|
+
fitH(overlayIn, pagesH - minH);
|
|
315
|
+
const topB = bandsIn.find((b) => b.edge === "top");
|
|
316
|
+
const botB = bandsIn.find((b) => b.edge === "bottom");
|
|
317
|
+
const hT = bandH(topB);
|
|
318
|
+
const hB = bandH(botB);
|
|
319
|
+
const colTop = topB?.span === "full" ? (topB.mode === "overlay" ? res.top : 0) + hT : 0;
|
|
320
|
+
const colBot = botB?.span === "full" ? H - (botB.mode === "overlay" ? res.bottom : 0) - hB : H;
|
|
321
|
+
const CH = Math.max(0, colBot - colTop);
|
|
185
322
|
const cols = [];
|
|
186
323
|
for (const side of SIDES) {
|
|
187
324
|
state.sides[side].forEach((c, index) => {
|
|
@@ -261,7 +398,7 @@ function layoutPanels(defs, state, stage, options = {}) {
|
|
|
261
398
|
const open2 = (side) => cols.some((c) => c.side === side && !c.hand && !auto.has(c));
|
|
262
399
|
const railed = (side) => cols.some((c) => c.side === side && (auto.has(c) || c.hand && !(ride && open2(side))));
|
|
263
400
|
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;
|
|
401
|
+
let excess = [...widths.values()].reduce((a, b) => a + b, 0) + SIDES.filter(railed).length * opt.rail + opt.pagesMin + res.left + res.right - W;
|
|
265
402
|
for (const c of order) {
|
|
266
403
|
if (excess <= 0 || auto.has(c)) continue;
|
|
267
404
|
const take = Math.min(excess, c.width - c.min);
|
|
@@ -292,8 +429,8 @@ function layoutPanels(defs, state, stage, options = {}) {
|
|
|
292
429
|
const riders = host ? mine.filter((c) => c.hand) : [];
|
|
293
430
|
const inRail = mine.filter((c) => c.hand && !riders.includes(c) || g.auto.has(c));
|
|
294
431
|
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) }));
|
|
432
|
+
const r = side === "left" ? rect(0, colTop, opt.rail, CH) : rect(W - opt.rail, colTop, opt.rail, CH);
|
|
433
|
+
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
434
|
rails[side] = { side, rect: r, segments };
|
|
298
435
|
for (const s of segments) {
|
|
299
436
|
const c = inRail.find((x) => x.panels.includes(s.id));
|
|
@@ -307,11 +444,11 @@ function layoutPanels(defs, state, stage, options = {}) {
|
|
|
307
444
|
const w = g.widths.get(c);
|
|
308
445
|
if (w === void 0 || riders.includes(c)) continue;
|
|
309
446
|
if (side === "left") {
|
|
310
|
-
at.set(c, rect(x0,
|
|
447
|
+
at.set(c, rect(x0, colTop, w, CH));
|
|
311
448
|
x0 += w;
|
|
312
449
|
} else {
|
|
313
450
|
x1 -= w;
|
|
314
|
-
at.set(c, rect(x1,
|
|
451
|
+
at.set(c, rect(x1, colTop, w, CH));
|
|
315
452
|
}
|
|
316
453
|
}
|
|
317
454
|
const riding = riders.flatMap((c) => c.panels.map((id) => ({ id, c })));
|
|
@@ -324,13 +461,13 @@ function layoutPanels(defs, state, stage, options = {}) {
|
|
|
324
461
|
const hr = at.get(host);
|
|
325
462
|
const first = riding.findIndex((x) => x.c === c);
|
|
326
463
|
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 })
|
|
464
|
+
(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
465
|
);
|
|
329
|
-
placedCols.push({ ...base, rect: rect(hr.x, first * opt.bar, hr.width, c.panels.length * opt.bar), shrunk: false, rides: host.index });
|
|
466
|
+
placedCols.push({ ...base, rect: rect(hr.x, colTop + first * opt.bar, hr.width, c.panels.length * opt.bar), shrunk: false, rides: host.index });
|
|
330
467
|
continue;
|
|
331
468
|
}
|
|
332
|
-
const r = at.get(c) ?? rect(side === "left" ? x0 : x1,
|
|
333
|
-
const y0 = c === host ? top : 0;
|
|
469
|
+
const r = at.get(c) ?? rect(side === "left" ? x0 : x1, colTop, 0, CH);
|
|
470
|
+
const y0 = colTop + (c === host ? top : 0);
|
|
334
471
|
const tabbed = c.show === "tabs";
|
|
335
472
|
const strip = rect(r.x, y0, r.width, opt.tabs);
|
|
336
473
|
const shown = tabbed && w !== void 0 ? { strip, active: c.active } : {};
|
|
@@ -340,7 +477,7 @@ function layoutPanels(defs, state, stage, options = {}) {
|
|
|
340
477
|
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
478
|
};
|
|
342
479
|
if (tabbed) {
|
|
343
|
-
const body = rect(r.x, y0 + opt.tabs, r.width, Math.max(0,
|
|
480
|
+
const body = rect(r.x, y0 + opt.tabs, r.width, Math.max(0, colBot - y0 - opt.tabs));
|
|
344
481
|
const shade = folded.has(c.active);
|
|
345
482
|
const tw = r.width / c.panels.length;
|
|
346
483
|
c.panels.forEach((id, i) => {
|
|
@@ -350,7 +487,7 @@ function layoutPanels(defs, state, stage, options = {}) {
|
|
|
350
487
|
});
|
|
351
488
|
continue;
|
|
352
489
|
}
|
|
353
|
-
const hs = sectionHeights(c,
|
|
490
|
+
const hs = sectionHeights(c, colBot - y0);
|
|
354
491
|
let y = y0;
|
|
355
492
|
for (const id of c.panels) {
|
|
356
493
|
const s = hs.get(id);
|
|
@@ -360,8 +497,39 @@ function layoutPanels(defs, state, stage, options = {}) {
|
|
|
360
497
|
for (const id of c.panels) if (hs.get(id).folded === "auto") notes.push({ code: "section-folded", side, column: c.index, items: [id] });
|
|
361
498
|
}
|
|
362
499
|
}
|
|
363
|
-
|
|
500
|
+
for (const b of bOrder) {
|
|
501
|
+
const h = gh.heights.get(b);
|
|
502
|
+
if (h !== void 0 && h < b.height) notes.push({ code: "band-shrunk", edge: b.edge, items: b.panels, from: b.height, to: h });
|
|
503
|
+
}
|
|
504
|
+
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 });
|
|
505
|
+
const pw = Math.max(0, x1 - x0);
|
|
506
|
+
const pTop = topB?.mode === "reserved" ? hT : 0;
|
|
507
|
+
const pBot = botB?.mode === "reserved" ? H - hB : H;
|
|
508
|
+
const reserved = {};
|
|
509
|
+
const iTop = pTop + res.top + (topB?.mode === "overlay" ? hT : 0);
|
|
510
|
+
const iBot = pBot - res.bottom - (botB?.mode === "overlay" ? hB : 0);
|
|
511
|
+
if (res.top > 0) reserved.top = rect(x0, pTop, pw, res.top);
|
|
512
|
+
if (res.right > 0) reserved.right = rect(x0 + pw - res.right, iTop, res.right, Math.max(0, iBot - iTop));
|
|
513
|
+
if (res.bottom > 0) reserved.bottom = rect(x0, pBot - res.bottom, pw, res.bottom);
|
|
514
|
+
if (res.left > 0) reserved.left = rect(x0, iTop, res.left, Math.max(0, iBot - iTop));
|
|
515
|
+
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
516
|
if (pages.width < opt.pagesMin) notes.push({ code: "pages-under-min", width: pages.width, min: opt.pagesMin });
|
|
517
|
+
if ((bandsIn.length || res.top + res.bottom > 0) && pages.height < minH - 1e-9) notes.push({ code: "pages-short", height: pages.height, min: minH });
|
|
518
|
+
const bands = {};
|
|
519
|
+
for (const b of bandsIn) {
|
|
520
|
+
const h = bandH(b);
|
|
521
|
+
const full = b.span === "full";
|
|
522
|
+
const over = b.mode === "overlay";
|
|
523
|
+
const y = b.edge === "top" ? over ? res.top : 0 : over ? H - res.bottom - h : H - h;
|
|
524
|
+
const r = full ? rect(0, y, W, h) : rect(x0, y, pw, h);
|
|
525
|
+
const f = b.hand ? "hand" : gh.auto.has(b) ? "auto" : null;
|
|
526
|
+
const hh = gh.heights.get(b);
|
|
527
|
+
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 };
|
|
528
|
+
const share = r.width / b.panels.length;
|
|
529
|
+
b.panels.forEach(
|
|
530
|
+
(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] })
|
|
531
|
+
);
|
|
532
|
+
}
|
|
365
533
|
state.floats.forEach((f, i) => {
|
|
366
534
|
if (closed.has(f.id)) return;
|
|
367
535
|
const shaded = folded.has(f.id);
|
|
@@ -390,7 +558,8 @@ function layoutPanels(defs, state, stage, options = {}) {
|
|
|
390
558
|
...clamped ? { clamped: true } : {}
|
|
391
559
|
});
|
|
392
560
|
});
|
|
393
|
-
|
|
561
|
+
notes.push(...offNotes);
|
|
562
|
+
return { items, columns: placedCols, rails, notes, pages, bands, reserved };
|
|
394
563
|
}
|
|
395
564
|
|
|
396
565
|
// src/panels/targets.ts
|
|
@@ -400,19 +569,26 @@ function placeRank(place) {
|
|
|
400
569
|
switch (place.kind) {
|
|
401
570
|
case "float":
|
|
402
571
|
return 3e3;
|
|
572
|
+
case "band":
|
|
573
|
+
return (place.edge === "top" ? 2e3 : 2500) + Math.min(place.index, 499);
|
|
403
574
|
case "rail":
|
|
404
575
|
return place.side === "left" ? 0 : 1999;
|
|
405
576
|
case "column":
|
|
406
577
|
return place.side === "left" ? 1 + 2 * place.index : 1998 - 2 * place.index;
|
|
407
|
-
case "into":
|
|
408
|
-
|
|
578
|
+
case "into": {
|
|
579
|
+
const base = place.side === "left" ? 2 + 2 * place.index : 1997 - 2 * place.index;
|
|
580
|
+
return place.at === void 0 ? base : base - 0.5 + Math.min(Math.max(0, place.at), 499) / 1e3;
|
|
581
|
+
}
|
|
409
582
|
}
|
|
410
583
|
}
|
|
411
|
-
function homePlace(state, id) {
|
|
584
|
+
function homePlace(state, id, options = {}) {
|
|
412
585
|
const w = whereIs(state, id);
|
|
413
586
|
if (w.kind === "float") return { kind: "float" };
|
|
414
587
|
if (w.kind === "none") return null;
|
|
415
|
-
|
|
588
|
+
if (w.kind === "band") return { kind: "band", edge: w.edge, index: w.index };
|
|
589
|
+
const col = state.sides[w.side][w.index];
|
|
590
|
+
if (col.panels.length === 1) return { kind: "column", side: w.side, index: w.index };
|
|
591
|
+
return options.stackSlots && col.show !== "tabs" ? { kind: "into", side: w.side, index: w.index, at: col.panels.indexOf(id) } : { kind: "into", side: w.side, index: w.index };
|
|
416
592
|
}
|
|
417
593
|
var cut = (x0, x1, lo, hi) => [Math.max(x0, lo), Math.min(x1, hi)];
|
|
418
594
|
function panelTargets(input) {
|
|
@@ -425,19 +601,40 @@ function panelTargets(input) {
|
|
|
425
601
|
const W = stage.width;
|
|
426
602
|
const H = stage.height;
|
|
427
603
|
const R = COLUMN_REACH;
|
|
604
|
+
const bandOpts = opt.bands ?? {};
|
|
605
|
+
const reserve = opt.reserve ?? {};
|
|
606
|
+
const px = (v) => typeof v === "number" && Number.isFinite(v) ? Math.max(0, v) : 0;
|
|
428
607
|
const out = [];
|
|
429
|
-
const
|
|
608
|
+
const idOf = (place) => {
|
|
609
|
+
switch (place.kind) {
|
|
610
|
+
case "float":
|
|
611
|
+
return "float";
|
|
612
|
+
case "rail":
|
|
613
|
+
return `rail:${place.side}`;
|
|
614
|
+
case "band":
|
|
615
|
+
return s0.bands?.[place.edge] ? `band:${place.edge}:${place.index}` : `band:${place.edge}`;
|
|
616
|
+
case "into":
|
|
617
|
+
return place.at === void 0 ? `into:${place.side}:${place.index}` : `into:${place.side}:${place.index}:${place.at}`;
|
|
618
|
+
default:
|
|
619
|
+
return `${place.kind}:${place.side}:${place.index}`;
|
|
620
|
+
}
|
|
621
|
+
};
|
|
622
|
+
const add = (place, priority, hit, make, free = false, marker) => {
|
|
430
623
|
if (hit.width <= 0 || hit.height <= 0) return;
|
|
431
624
|
if (input.allows && !input.allows(id, place)) return;
|
|
432
625
|
if (place.kind !== "float" && samePlaces(make({ x: 0, y: 0 }, { x: 0, y: 0 }), state, defs)) return;
|
|
433
|
-
out.push({ id: place
|
|
626
|
+
out.push({ id: idOf(place), priority, hit, panel: id, place, order: placeRank(place), make, ...free ? { free: true } : {}, ...marker ? { marker } : {} });
|
|
434
627
|
};
|
|
628
|
+
const fullTop = l0.bands.top?.span === "full" ? l0.bands.top.rect : null;
|
|
629
|
+
const fullBot = l0.bands.bottom?.span === "full" ? l0.bands.bottom.rect : null;
|
|
630
|
+
const top = fullTop ? fullTop.y + fullTop.height : 0;
|
|
631
|
+
const CH = Math.max(0, (fullBot ? fullBot.y : H) - top);
|
|
435
632
|
for (const side of SIDES) {
|
|
436
633
|
if (def?.sides && !def.sides.includes(side)) continue;
|
|
437
634
|
const left = side === "left";
|
|
438
635
|
const rail = l0.rails[side];
|
|
439
636
|
const edge = rail ? rail.rect.width : RAIL_EDGE;
|
|
440
|
-
const railHit = rail ? rail.rect : left ? rect(0,
|
|
637
|
+
const railHit = rail ? rail.rect : left ? rect(0, top, RAIL_EDGE, CH) : rect(W - RAIL_EDGE, top, RAIL_EDGE, CH);
|
|
441
638
|
add({ kind: "rail", side }, 1, railHit, () => {
|
|
442
639
|
const s = dock(state, id, side, 0, { width });
|
|
443
640
|
return { ...s, folded: [...s.folded.filter((x) => x !== id), id] };
|
|
@@ -447,16 +644,61 @@ function panelTargets(input) {
|
|
|
447
644
|
const hi = left ? W : W - edge;
|
|
448
645
|
const band = (x, outer, i) => {
|
|
449
646
|
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,
|
|
647
|
+
add({ kind: "column", side, index: i }, 2, rect(a, top, b - a, CH), () => dock(state, id, side, i, { width }));
|
|
451
648
|
};
|
|
452
|
-
if (open2.length === 0) band(left ? l0.pages.x : l0.pages.x + l0.pages.width, true, s0.sides[side].length);
|
|
649
|
+
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
650
|
open2.forEach((c, k) => {
|
|
454
651
|
band(left ? c.rect.x : c.rect.x + c.rect.width, k === 0, c.index);
|
|
455
|
-
|
|
652
|
+
const col = s0.sides[side][c.index];
|
|
653
|
+
const into = () => dock(state, id, side, c.index, { into: true });
|
|
654
|
+
const members = input.stackSlots && col.show !== "tabs" ? col.panels.flatMap((p, at) => {
|
|
655
|
+
const r = l0.items.get(p)?.rect;
|
|
656
|
+
return r ? [{ at, rect: r }] : [];
|
|
657
|
+
}) : [];
|
|
658
|
+
if (members.length === 0) {
|
|
659
|
+
add({ kind: "into", side, index: c.index }, 2, c.rect, into);
|
|
660
|
+
return;
|
|
661
|
+
}
|
|
662
|
+
const mid = (r) => r.y + r.height / 2;
|
|
663
|
+
const marker = (make) => {
|
|
664
|
+
const r = layoutPanels(defs, make(), stage, opt).items.get(id)?.rect;
|
|
665
|
+
return rect(c.rect.x, r ? r.y : c.rect.y, c.rect.width, 0);
|
|
666
|
+
};
|
|
667
|
+
const bottom = c.rect.y + c.rect.height;
|
|
668
|
+
members.forEach(({ at, rect: r }, k2) => {
|
|
669
|
+
const prev = members[k2 - 1];
|
|
670
|
+
const y0 = prev ? mid(prev.rect) : c.rect.y;
|
|
671
|
+
const make = () => dock(state, id, side, c.index, { into: true, at });
|
|
672
|
+
add({ kind: "into", side, index: c.index, at }, 2, rect(c.rect.x, y0, c.rect.width, mid(r) - y0), make, false, marker(make));
|
|
673
|
+
});
|
|
674
|
+
const last2 = members.at(-1).rect;
|
|
675
|
+
add({ kind: "into", side, index: c.index }, 2, rect(c.rect.x, mid(last2), c.rect.width, bottom - mid(last2)), into, false, marker(into));
|
|
456
676
|
});
|
|
457
677
|
const last = open2.at(-1);
|
|
458
678
|
if (last) band(left ? last.rect.x + last.rect.width : last.rect.x, false, last.index + 1);
|
|
459
679
|
}
|
|
680
|
+
const home = whereIs(state, id);
|
|
681
|
+
for (const e of EDGES) {
|
|
682
|
+
if (!bandOpts[e] || def?.sides && !def.sides.includes(e)) continue;
|
|
683
|
+
const pb = l0.bands[e];
|
|
684
|
+
const list = s0.bands?.[e]?.panels ?? [];
|
|
685
|
+
const make = (i) => () => dockBand(state, id, e, i, defs);
|
|
686
|
+
if (!pb) {
|
|
687
|
+
if (home.kind === "band" && home.edge === e && !s0.bands?.[e]) continue;
|
|
688
|
+
const p = l0.pages;
|
|
689
|
+
const h = Math.min(2 * opt.bar, p.height);
|
|
690
|
+
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));
|
|
691
|
+
continue;
|
|
692
|
+
}
|
|
693
|
+
const m = pb.panels.length;
|
|
694
|
+
const share = pb.rect.width / m;
|
|
695
|
+
for (let k = 0; k <= m; k++) {
|
|
696
|
+
const i = k < m ? list.indexOf(pb.panels[k]) : list.length;
|
|
697
|
+
const a = pb.rect.x + Math.max(0, k - 0.5) * share;
|
|
698
|
+
const b = pb.rect.x + Math.min(m, k + 0.5) * share;
|
|
699
|
+
add({ kind: "band", edge: e, index: i }, 2, rect(a, pb.rect.y, b - a, pb.rect.height), make(i));
|
|
700
|
+
}
|
|
701
|
+
}
|
|
460
702
|
if (def?.floats !== false) {
|
|
461
703
|
const was = state.floats.find((f) => f.id === id);
|
|
462
704
|
const size = was ? { width: was.rect.width, height: was.rect.height } : floatSize(def).natural;
|
|
@@ -498,12 +740,15 @@ function panelStops(targets, options = {}) {
|
|
|
498
740
|
stops.push({ id: t.id, place: t.place, state: t.make({ x: 0, y: 0 }, { x: 0, y: 0 }), home: false, order: t.order });
|
|
499
741
|
}
|
|
500
742
|
const h = options.home;
|
|
501
|
-
|
|
743
|
+
const after = h?.place.kind === "float" ? 1 : h?.place.kind === "into" && h.place.at !== void 0 ? 5e-4 : 0.5;
|
|
744
|
+
if (h) stops.push({ id: "home", place: h.place, state: h.state, home: true, order: placeRank(h.place) + after });
|
|
502
745
|
return stops.sort((a, b) => a.order - b.order).map(({ order: _order, ...s }) => s);
|
|
503
746
|
}
|
|
504
747
|
|
|
505
748
|
export {
|
|
506
749
|
SIDES,
|
|
750
|
+
EDGES,
|
|
751
|
+
BAND_SIZE,
|
|
507
752
|
IDENTITY_VIEW,
|
|
508
753
|
DEFAULT_PANELS_OPTIONS,
|
|
509
754
|
FLOAT_HEIGHT,
|
|
@@ -512,6 +757,8 @@ export {
|
|
|
512
757
|
tick,
|
|
513
758
|
defOf,
|
|
514
759
|
floatSize,
|
|
760
|
+
bandSize,
|
|
761
|
+
bandHeight,
|
|
515
762
|
ownWidth,
|
|
516
763
|
createPanels,
|
|
517
764
|
liftPanel,
|
|
@@ -520,6 +767,8 @@ export {
|
|
|
520
767
|
focus,
|
|
521
768
|
toggleFold,
|
|
522
769
|
keep,
|
|
770
|
+
dockBand,
|
|
771
|
+
resizeBand,
|
|
523
772
|
dock,
|
|
524
773
|
showTabs,
|
|
525
774
|
activate,
|
|
@@ -541,4 +790,4 @@ export {
|
|
|
541
790
|
panelDrop,
|
|
542
791
|
panelStops
|
|
543
792
|
};
|
|
544
|
-
//# sourceMappingURL=chunk-
|
|
793
|
+
//# sourceMappingURL=chunk-CJA6LRHN.js.map
|