diff options
author | Sam Wilkins <samwilkins333@gmail.com> | 2020-01-18 16:44:31 -0500 |
---|---|---|
committer | Sam Wilkins <samwilkins333@gmail.com> | 2020-01-18 16:44:31 -0500 |
commit | 9e90f5cb1d481889def9fe22b7e5d152777ea95d (patch) | |
tree | 9da51909bab443e611eb1a58fc9283f34d6a2c3b /src | |
parent | d9e8815ad25b413b825ae72267b85782e787407c (diff) |
cleanup and commenting
Diffstat (limited to 'src')
-rw-r--r-- | src/client/views/collections/collectionMulticolumn/CollectionMulticolumnView.tsx | 92 |
1 files changed, 62 insertions, 30 deletions
diff --git a/src/client/views/collections/collectionMulticolumn/CollectionMulticolumnView.tsx b/src/client/views/collections/collectionMulticolumn/CollectionMulticolumnView.tsx index e57e5eb26..d2209224f 100644 --- a/src/client/views/collections/collectionMulticolumn/CollectionMulticolumnView.tsx +++ b/src/client/views/collections/collectionMulticolumn/CollectionMulticolumnView.tsx @@ -16,16 +16,13 @@ import ResizeBar from './MulticolumnResizer'; type MulticolumnDocument = makeInterface<[typeof documentSchema]>; const MulticolumnDocument = makeInterface(documentSchema); -interface Unresolved { - target: Doc; +interface WidthSpecifier { magnitude: number; unit: string; } interface LayoutData { - unresolved: Unresolved[]; - numFixed: number; - numRatio: number; + widthSpecifiers: WidthSpecifier[]; starSum: number; } @@ -35,42 +32,57 @@ const resizerWidth = 4; @observer export class CollectionMulticolumnView extends CollectionSubView(MulticolumnDocument) { + /** + * @returns the list of layout documents whose width unit is + * *, denoting that it will be displayed with a ratio, not fixed pixel, value + */ @computed private get ratioDefinedDocs() { return this.childLayoutPairs.map(({ layout }) => layout).filter(({ widthUnit }) => StrCast(widthUnit) === "*"); } + /** + * This loops through all childLayoutPairs and extracts the values for widthUnit + * and widthMagnitude, ignoring any that are malformed. Additionally, it then + * normalizes the ratio values so that one * value is always 1, with the remaining + * values proportionate to that easily readable metric. + * @returns the list of the resolved width specifiers (unit and magnitude pairs) + * as well as the sum of the * coefficients, i.e. the ratio magnitudes + */ @computed private get resolvedLayoutInformation(): LayoutData { - const unresolved: Unresolved[] = []; - let starSum = 0, numFixed = 0, numRatio = 0; - - for (const { layout } of this.childLayoutPairs) { - const unit = StrCast(layout.widthUnit); - const magnitude = NumCast(layout.widthMagnitude); + let starSum = 0; + const widthSpecifiers: WidthSpecifier[] = []; + this.childLayoutPairs.map(({ layout: { widthUnit, widthMagnitude } }) => { + const unit = StrCast(widthUnit); + const magnitude = NumCast(widthMagnitude); if (unit && magnitude && magnitude > 0 && resolvedUnits.includes(unit)) { - if (unit === "*") { - starSum += magnitude; - numRatio++; - } else { - numFixed++; - } - unresolved.push({ target: layout, magnitude, unit }); + (unit === "*") && (starSum += magnitude); + widthSpecifiers.push({ 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 - } - + /** + * Otherwise, the child document is ignored and the remaining + * space is allocated as if the document were absent from the child list + */ + }); + /** + * Here, since these values are all relative, adjustments during resizing or + * manual updating can, though their ratios remain the same, cause the values + * themselves to drift toward zero. Thus, whenever we change any of the values, + * we normalize everything (dividing by the smallest magnitude). + */ setTimeout(() => { const { ratioDefinedDocs } = this; if (ratioDefinedDocs.length > 1) { const minimum = Math.min(...ratioDefinedDocs.map(({ widthMagnitude }) => NumCast(widthMagnitude))); - ratioDefinedDocs.forEach(layout => layout.widthMagnitude = NumCast(layout.widthMagnitude) / minimum); + if (minimum !== 0) { + ratioDefinedDocs.forEach(layout => layout.widthMagnitude = NumCast(layout.widthMagnitude) / minimum); + } } }); - return { unresolved, numRatio, numFixed, starSum }; + return { widthSpecifiers, starSum }; } /** @@ -83,12 +95,12 @@ export class CollectionMulticolumnView extends CollectionSubView(MulticolumnDocu */ @computed private get totalFixedAllocation(): number | undefined { - return this.resolvedLayoutInformation?.unresolved.reduce( + return this.resolvedLayoutInformation?.widthSpecifiers.reduce( (sum, { magnitude, unit }) => sum + (unit === "px" ? magnitude : 0), 0); } /** - * This returns the total quantity, in pixels, that 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. @@ -98,14 +110,14 @@ export class CollectionMulticolumnView extends CollectionSubView(MulticolumnDocu */ @computed private get totalRatioAllocation(): number | undefined { - const layoutInfoLen = this.resolvedLayoutInformation?.unresolved.length; + const layoutInfoLen = this.ratioDefinedDocs.length; if (layoutInfoLen > 0 && this.totalFixedAllocation !== undefined) { return this.props.PanelWidth() - (this.totalFixedAllocation + resizerWidth * (layoutInfoLen - 1)); } } /** - * This returns the total quantity, in pixels, that + * @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, @@ -123,8 +135,19 @@ export class CollectionMulticolumnView extends CollectionSubView(MulticolumnDocu } } + /** + * This wrapper function exists to prevent mobx from + * needlessly rerendering the internal ContentFittingDocumentViews + */ private getColumnUnitLength = () => this.columnUnitLength; + /** + * @param layout the document whose transform we'd like to compute + * Given a layout document, this function + * returns the resolved width it has requested, in pixels. + * @returns the stored column width if already in pixels, + * or the ratio width evaluated to a pixel value + */ private lookupPixels = (layout: Doc): number => { const columnUnitLength = this.columnUnitLength; if (columnUnitLength === undefined) { @@ -137,6 +160,12 @@ export class CollectionMulticolumnView extends CollectionSubView(MulticolumnDocu return width; } + /** + * @returns the transform that will correctly place + * the document decorations box, shifted to the right by + * the sum of all the resolved column widths of the + * documents before the target. + */ private lookupIndividualTransform = (layout: Doc) => { const columnUnitLength = this.columnUnitLength; if (columnUnitLength === undefined) { @@ -145,14 +174,17 @@ export class CollectionMulticolumnView extends CollectionSubView(MulticolumnDocu let offset = 0; for (const { layout: candidate } of this.childLayoutPairs) { if (candidate === layout) { - const shift = offset; - return this.props.ScreenToLocalTransform().translate(-shift, 0); + return this.props.ScreenToLocalTransform().translate(-offset, 0); } offset += this.lookupPixels(candidate) + resizerWidth; } return Transform.Identity(); // type coersion, this case should never be hit } + /** + * @returns the resolved list of rendered child documents, displayed + * at their resolved pixel widths, each separated by a resizer. + */ @computed private get contents(): JSX.Element[] | null { const { childLayoutPairs } = this; |