regular-layout 0.0.1 → 0.1.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 +26 -7
- package/dist/common/calculate_edge.d.ts +15 -0
- package/dist/common/constants.d.ts +29 -0
- package/dist/common/generate_grid.d.ts +1 -1
- package/dist/common/generate_overlay.d.ts +1 -1
- package/dist/common/insert_child.d.ts +1 -1
- package/dist/common/layout_config.d.ts +8 -15
- package/dist/common/redistribute_panel_sizes.d.ts +1 -1
- package/dist/extensions.d.ts +14 -0
- package/dist/index.js +9 -9
- package/dist/index.js.map +4 -4
- package/dist/regular-layout-frame.d.ts +7 -0
- package/dist/regular-layout.d.ts +47 -17
- package/package.json +2 -1
- package/src/common/calculate_edge.ts +104 -0
- package/src/common/calculate_intersect.ts +22 -9
- package/src/common/constants.ts +46 -0
- package/src/common/flatten.ts +5 -0
- package/src/common/generate_grid.ts +7 -4
- package/src/common/generate_overlay.ts +8 -5
- package/src/common/insert_child.ts +22 -15
- package/src/common/layout_config.ts +9 -18
- package/src/common/redistribute_panel_sizes.ts +7 -5
- package/src/common/remove_child.ts +38 -13
- package/src/extensions.ts +30 -2
- package/src/regular-layout-frame.ts +146 -23
- package/src/regular-layout.ts +163 -91
- package/dist/common/calculate_split.d.ts +0 -2
- package/src/common/calculate_split.ts +0 -53
package/src/regular-layout.ts
CHANGED
|
@@ -22,18 +22,17 @@ import type {
|
|
|
22
22
|
LayoutPath,
|
|
23
23
|
Layout,
|
|
24
24
|
LayoutDivider,
|
|
25
|
+
TabLayout,
|
|
26
|
+
OverlayMode,
|
|
25
27
|
} from "./common/layout_config.ts";
|
|
26
28
|
import { calculate_intersection } from "./common/calculate_intersect.ts";
|
|
27
29
|
import { remove_child } from "./common/remove_child.ts";
|
|
28
30
|
import { insert_child } from "./common/insert_child.ts";
|
|
29
31
|
import { redistribute_panel_sizes } from "./common/redistribute_panel_sizes.ts";
|
|
30
32
|
import { updateOverlaySheet } from "./common/generate_overlay.ts";
|
|
31
|
-
import {
|
|
33
|
+
import { calculate_edge } from "./common/calculate_edge.ts";
|
|
32
34
|
import { flatten } from "./common/flatten.ts";
|
|
33
|
-
|
|
34
|
-
export type OverlayMode = "grid" | "absolute" | "interactive";
|
|
35
|
-
|
|
36
|
-
const OVERLAY_DEFAULT: OverlayMode = "absolute";
|
|
35
|
+
import { OVERLAY_CLASSNAME, OVERLAY_DEFAULT } from "./common/constants.ts";
|
|
37
36
|
|
|
38
37
|
/**
|
|
39
38
|
* A Web Component that provides a resizable panel layout system.
|
|
@@ -85,9 +84,6 @@ export class RegularLayout extends HTMLElement {
|
|
|
85
84
|
this._shadowRoot.adoptedStyleSheets = [this._stylesheet];
|
|
86
85
|
this._shadowRoot.appendChild(this._unslotted_slot);
|
|
87
86
|
this._slots = new Map();
|
|
88
|
-
this.onPointerDown = this.onPointerDown.bind(this);
|
|
89
|
-
this.onPointerMove = this.onPointerMove.bind(this);
|
|
90
|
-
this.onPointerUp = this.onPointerUp.bind(this);
|
|
91
87
|
}
|
|
92
88
|
|
|
93
89
|
connectedCallback() {
|
|
@@ -108,74 +104,85 @@ export class RegularLayout extends HTMLElement {
|
|
|
108
104
|
*
|
|
109
105
|
* @param x - X coordinate in screen pixels.
|
|
110
106
|
* @param y - Y coordinate in screen pixels.
|
|
111
|
-
* @param
|
|
112
|
-
*
|
|
113
|
-
*
|
|
114
|
-
*
|
|
107
|
+
* @param dragTarget - A `LayoutPath` (presumably from `calculateIntersect`)
|
|
108
|
+
* which points to the drag element in the current layout.
|
|
109
|
+
* @param className - The CSS class name to use for the overlay panel
|
|
110
|
+
* (defaults to "overlay").
|
|
111
|
+
* @param mode - Overlay rendering mode: "grid" uses CSS grid to position
|
|
112
|
+
* the target, "absolute" positions the panel absolutely. Defaults to
|
|
113
|
+
* "absolute".
|
|
115
114
|
*/
|
|
116
|
-
setOverlayState
|
|
115
|
+
setOverlayState = (
|
|
117
116
|
x: number,
|
|
118
117
|
y: number,
|
|
119
|
-
{ slot }: LayoutPath<
|
|
120
|
-
|
|
121
|
-
|
|
118
|
+
{ slot }: LayoutPath<unknown>,
|
|
119
|
+
className: string = OVERLAY_CLASSNAME,
|
|
120
|
+
mode: OverlayMode = OVERLAY_DEFAULT,
|
|
121
|
+
) => {
|
|
122
122
|
let panel = this._panel;
|
|
123
123
|
if (mode === "absolute") {
|
|
124
124
|
panel = remove_child(panel, slot);
|
|
125
|
-
this.
|
|
125
|
+
this.updateSlots(panel, slot);
|
|
126
|
+
this._slots.get(slot)?.assignedElements()[0]?.classList.add(className);
|
|
126
127
|
}
|
|
127
128
|
|
|
128
129
|
const [col, row, box] = this.relativeCoordinates(x, y);
|
|
129
130
|
let drop_target = calculate_intersection(col, row, panel, false);
|
|
130
131
|
if (drop_target) {
|
|
131
|
-
drop_target =
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
if (drop_target) {
|
|
135
|
-
if (mode === "interactive") {
|
|
136
|
-
let new_panel = remove_child(this._panel, slot);
|
|
137
|
-
new_panel = flatten(insert_child(new_panel, slot, drop_target.path));
|
|
138
|
-
const css = create_css_grid_layout(new_panel);
|
|
139
|
-
this._stylesheet.replaceSync(css);
|
|
140
|
-
} else if (mode === "grid") {
|
|
132
|
+
drop_target = calculate_edge(col, row, panel, slot, drop_target);
|
|
133
|
+
if (mode === "grid") {
|
|
141
134
|
const path: [string, string] = [slot, drop_target.slot];
|
|
142
135
|
const css = create_css_grid_layout(this._panel, false, path);
|
|
143
136
|
this._stylesheet.replaceSync(css);
|
|
144
137
|
} else if (mode === "absolute") {
|
|
145
|
-
const
|
|
146
|
-
|
|
138
|
+
const grid_css = create_css_grid_layout(panel);
|
|
139
|
+
const overlay_css = updateOverlaySheet(slot, { ...drop_target, box });
|
|
140
|
+
this._stylesheet.replaceSync([grid_css, overlay_css].join("\n"));
|
|
147
141
|
}
|
|
142
|
+
} else {
|
|
143
|
+
const css = `${create_css_grid_layout(panel)}}`;
|
|
144
|
+
this._stylesheet.replaceSync(css);
|
|
148
145
|
}
|
|
149
|
-
|
|
146
|
+
|
|
147
|
+
const event = new CustomEvent("regular-layout-before-update", {
|
|
148
|
+
detail: panel,
|
|
149
|
+
});
|
|
150
|
+
|
|
151
|
+
this.dispatchEvent(event);
|
|
152
|
+
};
|
|
150
153
|
|
|
151
154
|
/**
|
|
152
155
|
* Clears the overlay state and commits the panel placement.
|
|
153
156
|
*
|
|
154
157
|
* @param x - X coordinate in screen pixels.
|
|
155
158
|
* @param y - Y coordinate in screen pixels.
|
|
156
|
-
* @param
|
|
159
|
+
* @param dragTarget - A `LayoutPath` (presumably from `calculateIntersect`)
|
|
160
|
+
* which points to the drag element in the current layout.
|
|
161
|
+
* @param className - The CSS class name to use for the overlay panel
|
|
162
|
+
* (defaults to "overlay").
|
|
157
163
|
* @param mode - Overlay rendering mode that was used, must match the mode
|
|
158
|
-
*
|
|
164
|
+
* passed to `setOverlayState`. Defaults to "absolute".
|
|
159
165
|
*/
|
|
160
|
-
clearOverlayState
|
|
166
|
+
clearOverlayState = (
|
|
161
167
|
x: number,
|
|
162
168
|
y: number,
|
|
163
|
-
drag_target: LayoutPath<
|
|
164
|
-
|
|
165
|
-
|
|
169
|
+
drag_target: LayoutPath<unknown>,
|
|
170
|
+
className: string = OVERLAY_CLASSNAME,
|
|
171
|
+
mode: OverlayMode = OVERLAY_DEFAULT,
|
|
172
|
+
) => {
|
|
166
173
|
let panel = this._panel;
|
|
167
174
|
if (mode === "absolute") {
|
|
168
175
|
panel = remove_child(panel, drag_target.slot);
|
|
169
|
-
this.
|
|
170
|
-
.
|
|
171
|
-
?.
|
|
176
|
+
this._slots
|
|
177
|
+
.get(drag_target.slot)
|
|
178
|
+
?.assignedElements()[0]
|
|
179
|
+
?.classList.remove(className);
|
|
172
180
|
}
|
|
173
181
|
|
|
174
182
|
const [col, row, _] = this.relativeCoordinates(x, y);
|
|
175
183
|
let drop_target = calculate_intersection(col, row, panel, false);
|
|
176
184
|
if (drop_target) {
|
|
177
|
-
|
|
178
|
-
drop_target = calculate_split(
|
|
185
|
+
drop_target = calculate_edge(
|
|
179
186
|
col,
|
|
180
187
|
row,
|
|
181
188
|
panel,
|
|
@@ -184,10 +191,17 @@ export class RegularLayout extends HTMLElement {
|
|
|
184
191
|
);
|
|
185
192
|
}
|
|
186
193
|
|
|
187
|
-
const { path } = drop_target ? drop_target : drag_target;
|
|
188
|
-
this.
|
|
189
|
-
|
|
190
|
-
|
|
194
|
+
const { path, orientation } = drop_target ? drop_target : drag_target;
|
|
195
|
+
this.restore(
|
|
196
|
+
insert_child(
|
|
197
|
+
panel,
|
|
198
|
+
drag_target.slot,
|
|
199
|
+
path,
|
|
200
|
+
orientation,
|
|
201
|
+
!drop_target?.is_edge,
|
|
202
|
+
),
|
|
203
|
+
);
|
|
204
|
+
};
|
|
191
205
|
|
|
192
206
|
/**
|
|
193
207
|
* Inserts a new panel into the layout at a specified path.
|
|
@@ -195,32 +209,56 @@ export class RegularLayout extends HTMLElement {
|
|
|
195
209
|
* @param name - Unique identifier for the new panel.
|
|
196
210
|
* @param path - Index path defining where to insert.
|
|
197
211
|
*/
|
|
198
|
-
insertPanel(name: string, path: number[] = []) {
|
|
212
|
+
insertPanel = (name: string, path: number[] = []) => {
|
|
199
213
|
this.restore(insert_child(this._panel, name, path));
|
|
200
|
-
}
|
|
214
|
+
};
|
|
201
215
|
|
|
202
216
|
/**
|
|
203
217
|
* Removes a panel from the layout by name.
|
|
204
218
|
*
|
|
205
219
|
* @param name - Name of the panel to remove
|
|
206
220
|
*/
|
|
207
|
-
removePanel(name: string) {
|
|
221
|
+
removePanel = (name: string) => {
|
|
208
222
|
this.restore(remove_child(this._panel, name));
|
|
209
|
-
}
|
|
223
|
+
};
|
|
224
|
+
|
|
225
|
+
/**
|
|
226
|
+
* Retrieves a panel by name from the layout tree.
|
|
227
|
+
*
|
|
228
|
+
* @param name - Name of the panel to find.
|
|
229
|
+
* @param layout - Optional layout tree to search in (defaults to current layout).
|
|
230
|
+
* @returns The TabLayout containing the panel if found, null otherwise.
|
|
231
|
+
*/
|
|
232
|
+
getPanel = (name: string, layout: Layout = this._panel): TabLayout | null => {
|
|
233
|
+
if (layout.type === "child-panel") {
|
|
234
|
+
if (layout.child.includes(name)) {
|
|
235
|
+
return layout;
|
|
236
|
+
}
|
|
237
|
+
return null;
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
for (const child of layout.children) {
|
|
241
|
+
const found = this.getPanel(name, child);
|
|
242
|
+
if (found) {
|
|
243
|
+
return found;
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
return null;
|
|
248
|
+
};
|
|
210
249
|
|
|
211
250
|
/**
|
|
212
251
|
* Determines which panel is at a given screen coordinate.
|
|
213
|
-
* Useful for drag-and-drop operations or custom interactions.
|
|
214
252
|
*
|
|
215
253
|
* @param column - X coordinate in screen pixels.
|
|
216
254
|
* @param row - Y coordinate in screen pixels.
|
|
217
255
|
* @returns Panel information if a panel is at that position, null otherwise.
|
|
218
256
|
*/
|
|
219
|
-
calculateIntersect(
|
|
257
|
+
calculateIntersect = (
|
|
220
258
|
x: number,
|
|
221
259
|
y: number,
|
|
222
260
|
check_dividers: boolean = false,
|
|
223
|
-
): LayoutPath<DOMRect> | null {
|
|
261
|
+
): LayoutPath<DOMRect> | null => {
|
|
224
262
|
const [col, row, box] = this.relativeCoordinates(x, y);
|
|
225
263
|
const panel = calculate_intersection(col, row, this._panel, check_dividers);
|
|
226
264
|
if (panel?.type === "layout-path") {
|
|
@@ -228,7 +266,14 @@ export class RegularLayout extends HTMLElement {
|
|
|
228
266
|
}
|
|
229
267
|
|
|
230
268
|
return null;
|
|
231
|
-
}
|
|
269
|
+
};
|
|
270
|
+
|
|
271
|
+
/**
|
|
272
|
+
* Clears the entire layout, unslotting all panels.
|
|
273
|
+
*/
|
|
274
|
+
clear = () => {
|
|
275
|
+
this.restore(EMPTY_PANEL);
|
|
276
|
+
};
|
|
232
277
|
|
|
233
278
|
/**
|
|
234
279
|
* Restores the layout from a saved state.
|
|
@@ -242,29 +287,17 @@ export class RegularLayout extends HTMLElement {
|
|
|
242
287
|
* layout.restore(savedState);
|
|
243
288
|
* ```
|
|
244
289
|
*/
|
|
245
|
-
restore(layout: Layout, _is_flattened: boolean = false) {
|
|
290
|
+
restore = (layout: Layout, _is_flattened: boolean = false) => {
|
|
246
291
|
this._panel = !_is_flattened ? flatten(layout) : layout;
|
|
247
|
-
const css = create_css_grid_layout(
|
|
292
|
+
const css = create_css_grid_layout(this._panel);
|
|
248
293
|
this._stylesheet.replaceSync(css);
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
const slot = document.createElement("slot");
|
|
254
|
-
slot.setAttribute("name", name);
|
|
255
|
-
this._shadowRoot.appendChild(slot);
|
|
256
|
-
this._slots.set(name, slot);
|
|
257
|
-
}
|
|
258
|
-
}
|
|
294
|
+
this.updateSlots(this._panel);
|
|
295
|
+
const event = new CustomEvent("regular-layout-update", {
|
|
296
|
+
detail: this._panel,
|
|
297
|
+
});
|
|
259
298
|
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
if (child) {
|
|
263
|
-
this._shadowRoot.removeChild(child);
|
|
264
|
-
this._slots.delete(key);
|
|
265
|
-
}
|
|
266
|
-
}
|
|
267
|
-
}
|
|
299
|
+
this.dispatchEvent(event);
|
|
300
|
+
};
|
|
268
301
|
|
|
269
302
|
/**
|
|
270
303
|
* Serializes the current layout state, which can be restored via `restore`.
|
|
@@ -278,32 +311,71 @@ export class RegularLayout extends HTMLElement {
|
|
|
278
311
|
* localStorage.setItem('layout', JSON.stringify(state));
|
|
279
312
|
* ```
|
|
280
313
|
*/
|
|
281
|
-
save(): Layout {
|
|
314
|
+
save = (): Layout => {
|
|
282
315
|
return structuredClone(this._panel);
|
|
283
|
-
}
|
|
316
|
+
};
|
|
284
317
|
|
|
285
|
-
|
|
318
|
+
/**
|
|
319
|
+
* Converts screen coordinates to relative layout coordinates.
|
|
320
|
+
*
|
|
321
|
+
* Transforms absolute pixel positions into normalized coordinates (0-1 range)
|
|
322
|
+
* relative to the layout's bounding box.
|
|
323
|
+
*
|
|
324
|
+
* @param clientX - X coordinate in screen pixels (client space).
|
|
325
|
+
* @param clientY - Y coordinate in screen pixels (client space).
|
|
326
|
+
* @returns A tuple containing:
|
|
327
|
+
* - col: Normalized X coordinate (0 = left edge, 1 = right edge)
|
|
328
|
+
* - row: Normalized Y coordinate (0 = top edge, 1 = bottom edge)
|
|
329
|
+
* - box: The layout element's bounding rectangle
|
|
330
|
+
*/
|
|
331
|
+
relativeCoordinates = (
|
|
286
332
|
clientX: number,
|
|
287
333
|
clientY: number,
|
|
288
|
-
): [number, number, DOMRect] {
|
|
334
|
+
): [number, number, DOMRect] => {
|
|
289
335
|
const box = this.getBoundingClientRect();
|
|
290
336
|
const col = (clientX - box.left) / (box.right - box.left);
|
|
291
337
|
const row = (clientY - box.top) / (box.bottom - box.top);
|
|
292
338
|
return [col, row, box];
|
|
293
|
-
}
|
|
339
|
+
};
|
|
294
340
|
|
|
295
|
-
private
|
|
296
|
-
const
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
this._dragPath = [hit, col, row];
|
|
300
|
-
this.setPointerCapture(event.pointerId);
|
|
301
|
-
event.preventDefault();
|
|
302
|
-
event.stopImmediatePropagation();
|
|
341
|
+
private updateSlots = (layout: Layout, overlay?: string) => {
|
|
342
|
+
const old = new Set(this._slots.keys());
|
|
343
|
+
if (overlay) {
|
|
344
|
+
old.delete(overlay);
|
|
303
345
|
}
|
|
304
|
-
}
|
|
305
346
|
|
|
306
|
-
|
|
347
|
+
for (const name of iter_panel_children(layout)) {
|
|
348
|
+
old.delete(name);
|
|
349
|
+
if (!this._slots.has(name)) {
|
|
350
|
+
const slot = document.createElement("slot");
|
|
351
|
+
slot.setAttribute("name", name);
|
|
352
|
+
this._shadowRoot.appendChild(slot);
|
|
353
|
+
this._slots.set(name, slot);
|
|
354
|
+
}
|
|
355
|
+
}
|
|
356
|
+
|
|
357
|
+
for (const key of old) {
|
|
358
|
+
const child = this._slots.get(key);
|
|
359
|
+
if (child) {
|
|
360
|
+
this._shadowRoot.removeChild(child);
|
|
361
|
+
this._slots.delete(key);
|
|
362
|
+
}
|
|
363
|
+
}
|
|
364
|
+
};
|
|
365
|
+
|
|
366
|
+
private onPointerDown = (event: PointerEvent) => {
|
|
367
|
+
if (event.target === this) {
|
|
368
|
+
const [col, row] = this.relativeCoordinates(event.clientX, event.clientY);
|
|
369
|
+
const hit = calculate_intersection(col, row, this._panel);
|
|
370
|
+
if (hit && hit.type !== "layout-path") {
|
|
371
|
+
this._dragPath = [hit, col, row];
|
|
372
|
+
this.setPointerCapture(event.pointerId);
|
|
373
|
+
event.preventDefault();
|
|
374
|
+
}
|
|
375
|
+
}
|
|
376
|
+
};
|
|
377
|
+
|
|
378
|
+
private onPointerMove = (event: PointerEvent) => {
|
|
307
379
|
if (this._dragPath) {
|
|
308
380
|
const [col, row] = this.relativeCoordinates(event.clientX, event.clientY);
|
|
309
381
|
const old_panel = this._panel;
|
|
@@ -312,9 +384,9 @@ export class RegularLayout extends HTMLElement {
|
|
|
312
384
|
const panel = redistribute_panel_sizes(old_panel, path, offset);
|
|
313
385
|
this._stylesheet.replaceSync(create_css_grid_layout(panel));
|
|
314
386
|
}
|
|
315
|
-
}
|
|
387
|
+
};
|
|
316
388
|
|
|
317
|
-
private onPointerUp(event: PointerEvent) {
|
|
389
|
+
private onPointerUp = (event: PointerEvent) => {
|
|
318
390
|
if (this._dragPath) {
|
|
319
391
|
this.releasePointerCapture(event.pointerId);
|
|
320
392
|
const [col, row] = this.relativeCoordinates(event.clientX, event.clientY);
|
|
@@ -330,5 +402,5 @@ export class RegularLayout extends HTMLElement {
|
|
|
330
402
|
|
|
331
403
|
this._dragPath = undefined;
|
|
332
404
|
}
|
|
333
|
-
}
|
|
405
|
+
};
|
|
334
406
|
}
|
|
@@ -1,53 +0,0 @@
|
|
|
1
|
-
import { calculate_intersection } from "./calculate_intersect";
|
|
2
|
-
import { insert_child } from "./insert_child";
|
|
3
|
-
import {
|
|
4
|
-
SPLIT_EDGE_TOLERANCE,
|
|
5
|
-
type Layout,
|
|
6
|
-
type LayoutPath,
|
|
7
|
-
} from "./layout_config";
|
|
8
|
-
|
|
9
|
-
export function calculate_split(
|
|
10
|
-
col: number,
|
|
11
|
-
row: number,
|
|
12
|
-
panel: Layout,
|
|
13
|
-
slot: string,
|
|
14
|
-
config: LayoutPath,
|
|
15
|
-
): LayoutPath {
|
|
16
|
-
if (
|
|
17
|
-
config.column_offset < SPLIT_EDGE_TOLERANCE ||
|
|
18
|
-
config.column_offset > 1 - SPLIT_EDGE_TOLERANCE
|
|
19
|
-
) {
|
|
20
|
-
if (config.orientation === "vertical") {
|
|
21
|
-
const new_panel = insert_child(panel, slot, [
|
|
22
|
-
...config.path,
|
|
23
|
-
config.column_offset < SPLIT_EDGE_TOLERANCE ? 0 : 1,
|
|
24
|
-
]);
|
|
25
|
-
|
|
26
|
-
config = calculate_intersection(col, row, new_panel, false);
|
|
27
|
-
} else {
|
|
28
|
-
const new_panel = insert_child(panel, slot, config.path);
|
|
29
|
-
config = calculate_intersection(col, row, new_panel, false);
|
|
30
|
-
}
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
if (
|
|
34
|
-
(config.row_offset < SPLIT_EDGE_TOLERANCE &&
|
|
35
|
-
config.row_offset < config.column_offset) ||
|
|
36
|
-
(config.row_offset > 1 - SPLIT_EDGE_TOLERANCE &&
|
|
37
|
-
config.row_offset > config.column_offset)
|
|
38
|
-
) {
|
|
39
|
-
if (config.orientation === "horizontal") {
|
|
40
|
-
const new_panel = insert_child(panel, slot, [
|
|
41
|
-
...config.path,
|
|
42
|
-
config.row_offset < SPLIT_EDGE_TOLERANCE ? 0 : 1,
|
|
43
|
-
]);
|
|
44
|
-
|
|
45
|
-
config = calculate_intersection(col, row, new_panel, false);
|
|
46
|
-
} else {
|
|
47
|
-
const new_panel = insert_child(panel, slot, config.path);
|
|
48
|
-
config = calculate_intersection(col, row, new_panel, false);
|
|
49
|
-
}
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
return config;
|
|
53
|
-
}
|