From 810f6b9b2737f3617910e498f577499fcbf3ffab Mon Sep 17 00:00:00 2001 From: bob Date: Fri, 17 Jan 2020 10:33:05 -0500 Subject: moved multilcolumnview into collections directory --- .../collections/CollectionMulticolumnView.tsx | 232 +++++++++++++++++++++ 1 file changed, 232 insertions(+) create mode 100644 src/client/views/collections/CollectionMulticolumnView.tsx (limited to 'src/client/views/collections/CollectionMulticolumnView.tsx') diff --git a/src/client/views/collections/CollectionMulticolumnView.tsx b/src/client/views/collections/CollectionMulticolumnView.tsx new file mode 100644 index 000000000..19a7b1123 --- /dev/null +++ b/src/client/views/collections/CollectionMulticolumnView.tsx @@ -0,0 +1,232 @@ +import { observer } from 'mobx-react'; +import { makeInterface } from '../../../new_fields/Schema'; +import { documentSchema } from '../../../new_fields/documentSchemas'; +import { CollectionSubView } from './CollectionSubView'; +import * as React from "react"; +import { Doc } from '../../../new_fields/Doc'; +import { NumCast, StrCast } from '../../../new_fields/Types'; +import { ContentFittingDocumentView } from './../nodes/ContentFittingDocumentView'; +import { Utils } from '../../../Utils'; +import "./collectionMulticolumnView.scss"; +import { computed } from 'mobx'; + +type MulticolumnDocument = makeInterface<[typeof documentSchema]>; +const MulticolumnDocument = makeInterface(documentSchema); + +interface Unresolved { + target: Doc; + magnitude: number; + unit: string; +} + +interface Resolved { + target: Doc; + pixels: number; +} + +interface LayoutData { + unresolved: Unresolved[]; + numFixed: number; + numRatio: number; + starSum: number; +} + +const resolvedUnits = ["*", "px"]; +const resizerWidth = 2; + +@observer +export class CollectionMulticolumnView extends CollectionSubView(MulticolumnDocument) { + @computed + private get resolvedLayoutInformation(): LayoutData { + const unresolved: Unresolved[] = []; + let starSum = 0, numFixed = 0, numRatio = 0; + for (const target of this.childDocs) { + const unit = StrCast(target.widthUnit); + const magnitude = NumCast(target.widthMagnitude); + if (unit && magnitude && magnitude > 0 && resolvedUnits.includes(unit)) { + if (unit === "*") { + starSum += magnitude; + numRatio++; + } else { + numFixed++; + } + unresolved.push({ target, magnitude, unit }); + } + // otherwise, the particular configuration entry is ignored and the remaining + // space is allocated as if the document were absent from the configuration list + } + return { unresolved, numRatio, numFixed, starSum }; + } + + /** + * This returns the total quantity, in pixels, that this + * view needs to reserve for child documents that have + * (with higher priority) requested a fixed pixel width. + * + * If the underlying resolvedLayoutInformation returns null + * because we're waiting on promises to resolve, this value will be undefined as well. + */ + @computed + private get totalFixedAllocation(): number | undefined { + return this.resolvedLayoutInformation?.unresolved.reduce( + (sum, { magnitude, unit }) => sum + (unit === "px" ? magnitude : 0), 0); + } + + /** + * This returns the total quantity, in pixels, that this + * view needs to reserve for child documents that have + * (with lower priority) requested a certain relative proportion of the + * remaining pixel width not allocated for fixed widths. + * + * If the underlying totalFixedAllocation returns undefined + * because we're waiting indirectly on promises to resolve, this value will be undefined as well. + */ + @computed + private get totalRatioAllocation(): number | undefined { + const layoutInfoLen = this.resolvedLayoutInformation?.unresolved.length; + if (layoutInfoLen > 0 && this.totalFixedAllocation !== undefined) + return this.props.PanelWidth() - (this.totalFixedAllocation + resizerWidth * (layoutInfoLen - 1)); + } + + /** + * This returns the total quantity, in pixels, that + * 1* (relative / star unit) is worth. For example, + * if the configuration has three documents, with, respectively, + * widths of 2*, 2* and 1*, and the panel width returns 1000px, + * this accessor returns 1000 / (2 + 2 + 1), or 200px. + * Elsewhere, this is then multiplied by each relative-width + * document's (potentially decimal) * count to compute its actual width (400px, 400px and 200px). + * + * If the underlying totalRatioAllocation or this.resolveLayoutInformation return undefined + * because we're waiting indirectly on promises to resolve, this value will be undefined as well. + */ + @computed + private get columnUnitLength(): number | undefined { + if (this.resolvedLayoutInformation && this.totalRatioAllocation !== undefined) { + return this.totalRatioAllocation / this.resolvedLayoutInformation.starSum; + } + } + + @computed + private get contents(): JSX.Element[] | null { + const layout = this.resolvedLayoutInformation; + const columnUnitLength = this.columnUnitLength; + if (layout === null || columnUnitLength === undefined) { + return (null); // we're still waiting on promises to resolve + } + const resolved: Resolved[] = []; + layout.unresolved.forEach(item => { + const { unit, magnitude, ...remaining } = item; + let width = magnitude; + if (unit === "*") { + width = magnitude * columnUnitLength; + } + resolved.push({ pixels: width, ...remaining }); + }); + const collector: JSX.Element[] = []; + for (let i = 0; i < resolved.length; i++) { + const { target, pixels } = resolved[i]; + collector.push( +
+ pixels} + getTransform={this.props.ScreenToLocalTransform} + /> + {NumCast(target.widthMagnitude).toFixed(3)} {StrCast(target.widthUnit)} +
, + + ); + } + collector.pop(); // removes the final extraneous resize bar + return collector; + } + + render(): JSX.Element { + return ( +
+ {this.contents} +
+ ); + } + +} + +interface SpacerProps { + width: number; + columnUnitLength: number; + toLeft?: Doc; + toRight?: Doc; +} + +class ResizeBar extends React.Component { + + private registerResizing = (e: React.PointerEvent) => { + e.stopPropagation(); + e.preventDefault(); + window.removeEventListener("pointermove", this.onPointerMove); + window.removeEventListener("pointerup", this.onPointerUp); + window.addEventListener("pointermove", this.onPointerMove); + window.addEventListener("pointerup", this.onPointerUp); + } + + private onPointerMove = ({ movementX }: PointerEvent) => { + const { toLeft, toRight, columnUnitLength } = this.props; + const target = movementX > 0 ? toRight : toLeft; + if (target) { + const { widthUnit, widthMagnitude } = target; + if (widthUnit === "*") { + target.widthMagnitude = NumCast(widthMagnitude) - Math.abs(movementX) / columnUnitLength; + } + } + } + + private get opacity() { + const { toLeft, toRight } = this.props; + if (toLeft && toRight) { + if (StrCast(toLeft.widthUnit) === "px" && StrCast(toRight.widthUnit) === "px") { + return 0; + } + return 0.4; + } else if (toLeft) { + if (StrCast(toLeft.widthUnit) === "px") { + return 0; + } + return 0.4; + } else if (toRight) { + if (StrCast(toRight.widthUnit) === "px") { + return 0; + } + return 0.4; + } + return 0; + } + + private onPointerUp = () => { + window.removeEventListener("pointermove", this.onPointerMove); + window.removeEventListener("pointerup", this.onPointerUp); + } + + render() { + return ( +
+ ); + } + +} \ No newline at end of file -- cgit v1.2.3-70-g09d2 From fc4dd8c7d361bc848b6b27c67d5da26b8aab408e Mon Sep 17 00:00:00 2001 From: bob Date: Fri, 17 Jan 2020 10:58:19 -0500 Subject: adjustments to multiColumnView to support templates --- src/client/views/collections/CollectionMulticolumnView.tsx | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'src/client/views/collections/CollectionMulticolumnView.tsx') diff --git a/src/client/views/collections/CollectionMulticolumnView.tsx b/src/client/views/collections/CollectionMulticolumnView.tsx index 19a7b1123..157c5e367 100644 --- a/src/client/views/collections/CollectionMulticolumnView.tsx +++ b/src/client/views/collections/CollectionMulticolumnView.tsx @@ -40,9 +40,9 @@ export class CollectionMulticolumnView extends CollectionSubView(MulticolumnDocu private get resolvedLayoutInformation(): LayoutData { const unresolved: Unresolved[] = []; let starSum = 0, numFixed = 0, numRatio = 0; - for (const target of this.childDocs) { - const unit = StrCast(target.widthUnit); - const magnitude = NumCast(target.widthMagnitude); + for (const pair of this.childLayoutPairs) { + const unit = StrCast(pair.layout.widthUnit); + const magnitude = NumCast(pair.layout.widthMagnitude); if (unit && magnitude && magnitude > 0 && resolvedUnits.includes(unit)) { if (unit === "*") { starSum += magnitude; @@ -50,7 +50,7 @@ export class CollectionMulticolumnView extends CollectionSubView(MulticolumnDocu } else { numFixed++; } - unresolved.push({ target, magnitude, unit }); + unresolved.push({ target: pair.layout, magnitude, unit }); } // otherwise, the particular configuration entry is ignored and the remaining // space is allocated as if the document were absent from the configuration list @@ -132,7 +132,7 @@ export class CollectionMulticolumnView extends CollectionSubView(MulticolumnDocu {...this.props} key={Utils.GenerateGuid()} Document={target} - DataDocument={undefined} + DataDocument={target.resolvedDataDoc as Doc} PanelWidth={() => pixels} getTransform={this.props.ScreenToLocalTransform} /> -- cgit v1.2.3-70-g09d2 From 9af3c5967e45b98186a2862a1f23e2494630ddb3 Mon Sep 17 00:00:00 2001 From: bob Date: Fri, 17 Jan 2020 11:32:56 -0500 Subject: fixed placement of documentdecorations for multicolumnview --- src/client/views/collections/CollectionMulticolumnView.tsx | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'src/client/views/collections/CollectionMulticolumnView.tsx') diff --git a/src/client/views/collections/CollectionMulticolumnView.tsx b/src/client/views/collections/CollectionMulticolumnView.tsx index 157c5e367..a04df171a 100644 --- a/src/client/views/collections/CollectionMulticolumnView.tsx +++ b/src/client/views/collections/CollectionMulticolumnView.tsx @@ -124,8 +124,10 @@ export class CollectionMulticolumnView extends CollectionSubView(MulticolumnDocu resolved.push({ pixels: width, ...remaining }); }); const collector: JSX.Element[] = []; + let offset = 0; for (let i = 0; i < resolved.length; i++) { const { target, pixels } = resolved[i]; + const shiftX = offset; collector.push(
pixels} - getTransform={this.props.ScreenToLocalTransform} + getTransform={() => this.props.ScreenToLocalTransform().translate(-shiftX, 0)} /> {NumCast(target.widthMagnitude).toFixed(3)} {StrCast(target.widthUnit)}
, @@ -146,6 +148,7 @@ export class CollectionMulticolumnView extends CollectionSubView(MulticolumnDocu toRight={resolved[i + 1]?.target} /> ); + offset += pixels + resizerWidth; } collector.pop(); // removes the final extraneous resize bar return collector; -- cgit v1.2.3-70-g09d2 From f783e6cd66d4a7e303bd327d028076e3d76815bc Mon Sep 17 00:00:00 2001 From: Sam Wilkins Date: Fri, 17 Jan 2020 11:45:49 -0500 Subject: drop target added to mc view --- src/client/views/collections/CollectionMulticolumnView.tsx | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) (limited to 'src/client/views/collections/CollectionMulticolumnView.tsx') diff --git a/src/client/views/collections/CollectionMulticolumnView.tsx b/src/client/views/collections/CollectionMulticolumnView.tsx index 157c5e367..4744de34c 100644 --- a/src/client/views/collections/CollectionMulticolumnView.tsx +++ b/src/client/views/collections/CollectionMulticolumnView.tsx @@ -36,6 +36,7 @@ const resizerWidth = 2; @observer export class CollectionMulticolumnView extends CollectionSubView(MulticolumnDocument) { + @computed private get resolvedLayoutInformation(): LayoutData { const unresolved: Unresolved[] = []; @@ -84,8 +85,9 @@ export class CollectionMulticolumnView extends CollectionSubView(MulticolumnDocu @computed private get totalRatioAllocation(): number | undefined { const layoutInfoLen = this.resolvedLayoutInformation?.unresolved.length; - if (layoutInfoLen > 0 && this.totalFixedAllocation !== undefined) + if (layoutInfoLen > 0 && this.totalFixedAllocation !== undefined) { return this.props.PanelWidth() - (this.totalFixedAllocation + resizerWidth * (layoutInfoLen - 1)); + } } /** @@ -153,7 +155,10 @@ export class CollectionMulticolumnView extends CollectionSubView(MulticolumnDocu render(): JSX.Element { return ( -
+
{this.contents}
); -- cgit v1.2.3-70-g09d2