Skip to content

Commit 7aa5046

Browse files
committed
🎨: add support for extent precomputation for style policies
Allows to estimate the extents of morphs due to layout applocation before morphs are being initialized. Allows style policies to pre-compute styles for breakpoints before morphs are getting initialized.
1 parent c1b36e7 commit 7aa5046

File tree

1 file changed

+105
-0
lines changed

1 file changed

+105
-0
lines changed

lively.morphic/layout.js

Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -324,6 +324,14 @@ class Layout {
324324
this.active = false;
325325
}
326326

327+
estimateSubmorphExtents (containerSpec) {
328+
329+
}
330+
331+
estimateContainerExtent (containerSpec) {
332+
333+
}
334+
327335
resizesMorphVertically (aMorph) { // eslint-disable-line no-unused-vars
328336
return false;
329337
}
@@ -1375,6 +1383,103 @@ export class TilingLayout extends Layout {
13751383
* JS LAYOUT *
13761384
*************/
13771385

1386+
estimateTotalFixedExtent (containerSpec, extractBuildSpecs) {
1387+
const policies = this.config.resizePolicies;
1388+
const totalExtent = pt(
1389+
this.spacing * (containerSpec.submorphs.length - 1) + this.padding.left() + this.padding.right(),
1390+
this.spacing * (containerSpec.submorphs.length - 1) + this.padding.top() + this.padding.bottom()
1391+
);
1392+
totalExtent.horizontalFill = 0;
1393+
totalExtent.verticalFill = 0;
1394+
for (let i = 0; i < containerSpec.submorphs.length; i++) {
1395+
let match; let fixedTotalHeight; let fixedTotalWidth; let m = containerSpec.submorphs[i];
1396+
if (m.isPolicy) m = m.spec;
1397+
let ext = m.extent;
1398+
if (!ext && (m.width || m.height)) ext = pt(m.width || 10, m.height || 10);
1399+
if (m.isLayoutable === false) continue;
1400+
if (match = policies.find(([name, policy]) => name === m.name)) {
1401+
const [_, policy] = match;
1402+
if (policy.width === 'fixed') {
1403+
if (!ext) {
1404+
m = containerSpec.submorphs[i] = extractBuildSpecs(containerSpec.submorphs[i]);
1405+
ext = m.extent;
1406+
}
1407+
totalExtent.x += ext.x;
1408+
} else {
1409+
totalExtent.horizontalFill++;
1410+
}
1411+
if (policy.height === 'fixed') {
1412+
if (!ext) {
1413+
m = containerSpec.submorphs[i] = extractBuildSpecs(containerSpec.submorphs[i]);
1414+
ext = m.extent;
1415+
}
1416+
totalExtent.y += ext.y;
1417+
} else {
1418+
totalExtent.verticalFill++;
1419+
}
1420+
} else if (ext) {
1421+
totalExtent.x += ext.x;
1422+
totalExtent.y += ext.y;
1423+
}
1424+
}
1425+
return totalExtent;
1426+
}
1427+
1428+
estimateSubmorphExtents (containerSpec, extractBuildSpecs) {
1429+
if (!containerSpec.extent) return;
1430+
if (!containerSpec.submorphs?.length) return;
1431+
const policies = this.config.resizePolicies;
1432+
if (!policies) return;
1433+
1434+
for (let m of containerSpec.submorphs) {
1435+
let match, fixedTotalExtent;
1436+
if (m.isPolicy) m = m.spec;
1437+
if (match = policies.find(([name, policy]) => name === m.name)) {
1438+
const [_, policy] = match;
1439+
if (policy.width === 'fill') {
1440+
if (this.axis === 'column') {
1441+
m.width = containerSpec.extent.x - this.padding.left() - this.padding.right();
1442+
}
1443+
if (this.axis === 'row') {
1444+
if (!fixedTotalExtent) fixedTotalExtent = this.estimateTotalFixedExtent(containerSpec, extractBuildSpecs);
1445+
m.width = (containerSpec.extent.x - fixedTotalExtent.x) / fixedTotalExtent.horizontalFill;
1446+
}
1447+
}
1448+
1449+
if (policy.height === 'fill') {
1450+
if (this.axis === 'row') {
1451+
m.height = containerSpec.extent.y - this.padding.top() - this.padding.bottom();
1452+
}
1453+
if (this.axis === 'column') {
1454+
if (!fixedTotalExtent) fixedTotalExtent = this.estimateTotalFixedExtent(containerSpec, extractBuildSpecs);
1455+
m.height = (containerSpec.extent.y - fixedTotalExtent.y) / fixedTotalExtent.verticalHeight;
1456+
}
1457+
}
1458+
}
1459+
}
1460+
}
1461+
1462+
estimateContainerExtent (containerSpec, submorphs) {
1463+
if (submorphs.length == 0) return;
1464+
if (!this.hugContentsVertically && !this.hugContentsHorizontally) return;
1465+
1466+
if (this.axis === 'column') {
1467+
const height = arr.sum(submorphs.map(m => m.extent.y)) + this.spacing * (submorphs.length - 1) + this.padding.top() + this.padding.bottom();
1468+
const width = arr.max(submorphs.map(m => m.extent.x)) + this.padding.left() + this.padding.right();
1469+
const ext = containerSpec.extent || pt(10, 10);
1470+
if (this.hugContentsVertically) containerSpec.extent = ext.withY(height);
1471+
if (this.hugContentsHorizontally) containerSpec.extent = ext.withX(width);
1472+
}
1473+
1474+
if (this.axis === 'row') {
1475+
const height = arr.max(submorphs.map(m => m.extent.y)) + this.padding.top() + this.padding.bottom();
1476+
const width = arr.sum(submorphs.map(m => m.extent.x)) + this.spacing * (submorphs.length - 1) + this.padding.left() + this.padding.right();
1477+
const ext = containerSpec.extent || pt(10, 10);
1478+
if (this.hugContentsVertically) containerSpec.extent = ext.withY(height);
1479+
if (this.hugContentsHorizontally) containerSpec.extent = ext.withX(width);
1480+
}
1481+
}
1482+
13781483
apply (animate = false) {
13791484
if (this.active || !this.container || this.renderViaCSS) return;
13801485

0 commit comments

Comments
 (0)