mirror of
https://github.com/rio-labs/rio.git
synced 2026-05-02 08:59:27 -05:00
remove JS layouting
This commit is contained in:
committed by
Jakob Pinterits
parent
6e4975cce0
commit
fe5c5abfa6
@@ -1,5 +1,4 @@
|
||||
import { componentsById } from '../componentManagement';
|
||||
import { LayoutContext } from '../layouting';
|
||||
import { ComponentId } from '../dataModels';
|
||||
import { ComponentBase, ComponentState } from './componentBase';
|
||||
|
||||
@@ -10,7 +9,7 @@ export type LinearContainerState = ComponentState & {
|
||||
proportions?: 'homogeneous' | number[] | null;
|
||||
};
|
||||
|
||||
class LinearContainer extends ComponentBase {
|
||||
abstract class LinearContainer extends ComponentBase {
|
||||
state: Required<LinearContainerState>;
|
||||
|
||||
protected nGrowers: number; // Number of children that grow in the major axis
|
||||
@@ -27,19 +26,36 @@ class LinearContainer extends ComponentBase {
|
||||
deltaState: LinearContainerState,
|
||||
latentComponents: Set<ComponentBase>
|
||||
): void {
|
||||
super.updateElement(deltaState, latentComponents);
|
||||
|
||||
// Children
|
||||
if (deltaState.children !== undefined) {
|
||||
this.replaceChildren(
|
||||
latentComponents,
|
||||
deltaState.children,
|
||||
this.element
|
||||
this.element,
|
||||
true
|
||||
);
|
||||
|
||||
// Clear everybody's position
|
||||
for (let childElement of this.element
|
||||
.children as Iterable<HTMLElement>) {
|
||||
childElement.style.left = '0';
|
||||
childElement.style.top = '0';
|
||||
// Set the children's `flex-grow`
|
||||
let hasGrowers = false;
|
||||
for (let [index, childId] of deltaState.children.entries()) {
|
||||
let childComponent = componentsById[childId]!;
|
||||
let childWrapper = this.element.children[index] as HTMLElement;
|
||||
|
||||
if (this.getGrow(childComponent)) {
|
||||
hasGrowers = true;
|
||||
childWrapper.style.flexGrow = '1';
|
||||
} else {
|
||||
childWrapper.style.flexGrow = '0';
|
||||
}
|
||||
}
|
||||
|
||||
// If nobody wants to grow, all of them do
|
||||
if (!hasGrowers) {
|
||||
for (let childWrapper of this.element.children) {
|
||||
(childWrapper as HTMLElement).style.flexGrow = '1';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -54,118 +70,24 @@ class LinearContainer extends ComponentBase {
|
||||
deltaState.proportions === null
|
||||
) {
|
||||
} else if (deltaState.proportions === 'homogeneous') {
|
||||
throw new Error('not implemented yet');
|
||||
this.totalProportions = this.children.size;
|
||||
} else {
|
||||
throw new Error('not implemented yet');
|
||||
this.totalProportions = deltaState.proportions.reduce(
|
||||
(a, b) => a + b
|
||||
);
|
||||
}
|
||||
|
||||
// Re-layout
|
||||
this.makeLayoutDirty();
|
||||
}
|
||||
|
||||
/// Returns whether the given component grows in the direction of the
|
||||
/// container
|
||||
abstract getGrow(childComponent: ComponentBase): boolean;
|
||||
}
|
||||
|
||||
export class RowComponent extends LinearContainer {
|
||||
updateNaturalWidth(ctx: LayoutContext): void {
|
||||
if (this.state.proportions === null) {
|
||||
this.naturalWidth = 0;
|
||||
this.nGrowers = 0;
|
||||
|
||||
// Add up all children's requested widths
|
||||
for (let child of this.children) {
|
||||
this.naturalWidth += child.requestedWidth;
|
||||
this.nGrowers += child.state._grow_[0] as any as number;
|
||||
}
|
||||
} else {
|
||||
// When proportions are set, growers are ignored. Extra space is
|
||||
// distributed among all children.
|
||||
|
||||
// Each child has a requested width and a proportion number, which
|
||||
// essentially "cuts" the child into a certain number of equally
|
||||
// sized pieces. In order to find our natural width, we need to
|
||||
// determine the width of the largest piece, then multiply that by
|
||||
// the number of total pieces.
|
||||
let proportions =
|
||||
this.state.proportions === 'homogeneous'
|
||||
? Array(this.children.size).fill(1)
|
||||
: this.state.proportions;
|
||||
let maxProportionSize = 0;
|
||||
|
||||
for (let i = 0; i < proportions.length; i++) {
|
||||
let child = componentsById[this.state.children[i]]!;
|
||||
let proportion = proportions[i];
|
||||
|
||||
if (proportion !== 0) {
|
||||
let proportionSize = child.requestedWidth / proportion;
|
||||
|
||||
maxProportionSize = Math.max(
|
||||
maxProportionSize,
|
||||
proportionSize
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
this.naturalWidth = maxProportionSize * this.totalProportions;
|
||||
}
|
||||
|
||||
// Account for spacing
|
||||
this.naturalWidth +=
|
||||
Math.max(this.children.size - 1, 0) * this.state.spacing;
|
||||
}
|
||||
|
||||
updateAllocatedWidth(ctx: LayoutContext): void {
|
||||
if (this.state.proportions === null) {
|
||||
// If no child wants to grow, we pretend that all of them do.
|
||||
let forceGrow = this.nGrowers === 0;
|
||||
let nGrowers = forceGrow
|
||||
? this.state.children.length
|
||||
: this.nGrowers;
|
||||
|
||||
let additionalSpace = this.allocatedWidth - this.naturalWidth;
|
||||
let additionalSpacePerGrower = additionalSpace / nGrowers;
|
||||
|
||||
for (let child of this.children) {
|
||||
child.allocatedWidth = child.requestedWidth;
|
||||
|
||||
if (child.state._grow_[0] || forceGrow) {
|
||||
child.allocatedWidth += additionalSpacePerGrower;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
let proportions =
|
||||
this.state.proportions === 'homogeneous'
|
||||
? Array(this.children.size).fill(1)
|
||||
: this.state.proportions;
|
||||
|
||||
let spacing =
|
||||
Math.max(this.children.size - 1, 0) * this.state.spacing;
|
||||
let proportionSize =
|
||||
(this.allocatedWidth - spacing) / this.totalProportions;
|
||||
|
||||
for (let i = 0; i < proportions.length; i++) {
|
||||
let child = componentsById[this.state.children[i]]!;
|
||||
child.allocatedWidth = proportionSize * proportions[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
updateNaturalHeight(ctx: LayoutContext): void {
|
||||
this.naturalHeight = 0;
|
||||
|
||||
for (let child of this.children) {
|
||||
this.naturalHeight = Math.max(
|
||||
this.naturalHeight,
|
||||
child.requestedHeight
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
updateAllocatedHeight(ctx: LayoutContext): void {
|
||||
// Assign the allocated height to the children
|
||||
for (let child of this.children) {
|
||||
child.allocatedHeight = this.allocatedHeight;
|
||||
}
|
||||
getGrow(childComponent: ComponentBase): boolean {
|
||||
return childComponent.state._grow_[0];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -176,105 +98,7 @@ export class ColumnComponent extends LinearContainer {
|
||||
return element;
|
||||
}
|
||||
|
||||
updateNaturalWidth(ctx: LayoutContext): void {
|
||||
this.naturalWidth = 0;
|
||||
|
||||
for (let child of this.children) {
|
||||
this.naturalWidth = Math.max(
|
||||
this.naturalWidth,
|
||||
child.requestedWidth
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
updateAllocatedWidth(ctx: LayoutContext): void {
|
||||
// Assign the allocated width to the children
|
||||
for (let child of this.children) {
|
||||
child.allocatedWidth = this.allocatedWidth;
|
||||
}
|
||||
}
|
||||
|
||||
updateNaturalHeight(ctx: LayoutContext): void {
|
||||
if (this.state.proportions === null) {
|
||||
this.naturalHeight = 0;
|
||||
this.nGrowers = 0;
|
||||
|
||||
// Add up all children's requested heights
|
||||
for (let child of this.children) {
|
||||
this.naturalHeight += child.requestedHeight;
|
||||
this.nGrowers += child.state._grow_[1] as any as number;
|
||||
}
|
||||
} else {
|
||||
// When proportions are set, growers are ignored. Extra space is
|
||||
// distributed among all children.
|
||||
|
||||
// Each child has a requested width and a proportion number, which
|
||||
// essentially "cuts" the child into a certain number of equally
|
||||
// sized pieces. In order to find our natural width, we need to
|
||||
// determine the width of the largest piece, then multiply that by
|
||||
// the number of total pieces.
|
||||
let proportions =
|
||||
this.state.proportions === 'homogeneous'
|
||||
? Array(this.children.size).fill(1)
|
||||
: this.state.proportions;
|
||||
let maxProportionSize = 0;
|
||||
|
||||
for (let i = 0; i < proportions.length; i++) {
|
||||
let child = componentsById[this.state.children[i]]!;
|
||||
let proportion = proportions[i];
|
||||
|
||||
if (proportion !== 0) {
|
||||
let proportionSize = child.requestedHeight / proportion;
|
||||
|
||||
maxProportionSize = Math.max(
|
||||
maxProportionSize,
|
||||
proportionSize
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
this.naturalHeight = maxProportionSize * this.totalProportions;
|
||||
}
|
||||
|
||||
// Account for spacing
|
||||
this.naturalHeight +=
|
||||
Math.max(this.children.size - 1, 0) * this.state.spacing;
|
||||
}
|
||||
|
||||
updateAllocatedHeight(ctx: LayoutContext): void {
|
||||
// Assign the allocated height to the children
|
||||
if (this.state.proportions === null) {
|
||||
// If no child wants to grow, we pretend that all of them do.
|
||||
let forceGrow = this.nGrowers === 0;
|
||||
let nGrowers = forceGrow
|
||||
? this.state.children.length
|
||||
: this.nGrowers;
|
||||
|
||||
let additionalSpace = this.allocatedHeight - this.naturalHeight;
|
||||
let additionalSpacePerGrower = additionalSpace / nGrowers;
|
||||
|
||||
for (let child of this.children) {
|
||||
child.allocatedHeight = child.requestedHeight;
|
||||
|
||||
if (child.state._grow_[1] || forceGrow) {
|
||||
child.allocatedHeight += additionalSpacePerGrower;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
let proportions =
|
||||
this.state.proportions === 'homogeneous'
|
||||
? Array(this.children.size).fill(1)
|
||||
: this.state.proportions;
|
||||
|
||||
let spacing =
|
||||
Math.max(this.children.size - 1, 0) * this.state.spacing;
|
||||
let proportionSize =
|
||||
(this.allocatedHeight - spacing) / this.totalProportions;
|
||||
|
||||
for (let i = 0; i < proportions.length; i++) {
|
||||
let child = componentsById[this.state.children[i]]!;
|
||||
child.allocatedHeight = proportionSize * proportions[i];
|
||||
}
|
||||
}
|
||||
getGrow(childComponent: ComponentBase): boolean {
|
||||
return childComponent.state._grow_[1];
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user