diff options
| author | bob <bcz@cs.brown.edu> | 2020-02-07 13:58:33 -0500 |
|---|---|---|
| committer | bob <bcz@cs.brown.edu> | 2020-02-07 13:58:33 -0500 |
| commit | ea5e85e30b83b40135c83025d4f1be1ed188b9b7 (patch) | |
| tree | 6e28ccee1b6cdcdca2ad5ecb5d49365d0cd28b13 /src/client/views/collections/collectionMulticolumn | |
| parent | ccedb9302632fcdbc75292b90942a34b98bebcee (diff) | |
| parent | 688f54be8be328d733e05b0781aa8908305e14fa (diff) | |
Merge branch 'master' into fixinglayoutsyms
Diffstat (limited to 'src/client/views/collections/collectionMulticolumn')
6 files changed, 105 insertions, 88 deletions
diff --git a/src/client/views/collections/collectionMulticolumn/CollectionMulticolumnView.scss b/src/client/views/collections/collectionMulticolumn/CollectionMulticolumnView.scss index f57ba438a..0c74b8ddb 100644 --- a/src/client/views/collections/collectionMulticolumn/CollectionMulticolumnView.scss +++ b/src/client/views/collections/collectionMulticolumn/CollectionMulticolumnView.scss @@ -7,6 +7,7 @@ .document-wrapper { display: flex; flex-direction: column; + width: 100%; .label-wrapper { display: flex; @@ -17,13 +18,13 @@ } - .resizer { + .multiColumnResizer { cursor: ew-resize; transition: 0.5s opacity ease; display: flex; flex-direction: column; - .internal { + .multiColumnResizer-hdl { width: 100%; height: 100%; transition: 0.5s background-color ease; diff --git a/src/client/views/collections/collectionMulticolumn/CollectionMulticolumnView.tsx b/src/client/views/collections/collectionMulticolumn/CollectionMulticolumnView.tsx index 65862f34f..7d8de0db4 100644 --- a/src/client/views/collections/collectionMulticolumn/CollectionMulticolumnView.tsx +++ b/src/client/views/collections/collectionMulticolumn/CollectionMulticolumnView.tsx @@ -1,19 +1,18 @@ +import { action, computed } from 'mobx'; import { observer } from 'mobx-react'; -import { makeInterface } from '../../../../new_fields/Schema'; -import { documentSchema } from '../../../../new_fields/documentSchemas'; -import { CollectionSubView, SubCollectionViewProps } from '../CollectionSubView'; import * as React from "react"; import { Doc } from '../../../../new_fields/Doc'; -import { NumCast, StrCast, BoolCast, ScriptCast } from '../../../../new_fields/Types'; +import { documentSchema } from '../../../../new_fields/documentSchemas'; +import { makeInterface } from '../../../../new_fields/Schema'; +import { BoolCast, NumCast, ScriptCast, StrCast } from '../../../../new_fields/Types'; +import { DragManager } from '../../../util/DragManager'; +import { Transform } from '../../../util/Transform'; +import { undoBatch } from '../../../util/UndoManager'; import { ContentFittingDocumentView } from '../../nodes/ContentFittingDocumentView'; -import { Utils } from '../../../../Utils'; +import { CollectionSubView } from '../CollectionSubView'; import "./collectionMulticolumnView.scss"; -import { computed, trace, observable, action } from 'mobx'; -import { Transform } from '../../../util/Transform'; -import WidthLabel from './MulticolumnWidthLabel'; import ResizeBar from './MulticolumnResizer'; -import { undoBatch } from '../../../util/UndoManager'; -import { DragManager } from '../../../util/DragManager'; +import WidthLabel from './MulticolumnWidthLabel'; type MulticolumnDocument = makeInterface<[typeof documentSchema]>; const MulticolumnDocument = makeInterface(documentSchema); @@ -34,7 +33,7 @@ export const DimUnit = { }; const resolvedUnits = Object.values(DimUnit); -const resizerWidth = 4; +const resizerWidth = 8; @observer export class CollectionMulticolumnView extends CollectionSubView(MulticolumnDocument) { @@ -45,7 +44,7 @@ export class CollectionMulticolumnView extends CollectionSubView(MulticolumnDocu */ @computed private get ratioDefinedDocs() { - return this.childLayoutPairs.map(({ layout }) => layout).filter(({ dimUnit }) => StrCast(dimUnit) === DimUnit.Ratio); + return this.childLayoutPairs.map(pair => pair.layout).filter(layout => StrCast(layout.dimUnit, "*") === DimUnit.Ratio); } /** @@ -60,9 +59,9 @@ export class CollectionMulticolumnView extends CollectionSubView(MulticolumnDocu private get resolvedLayoutInformation(): LayoutData { let starSum = 0; const widthSpecifiers: WidthSpecifier[] = []; - this.childLayoutPairs.map(({ layout: { dimUnit, dimMagnitude } }) => { - const unit = StrCast(dimUnit); - const magnitude = NumCast(dimMagnitude); + this.childLayoutPairs.map(pair => { + const unit = StrCast(pair.layout.dimUnit, "*"); + const magnitude = NumCast(pair.layout.dimMagnitude, 1); if (unit && magnitude && magnitude > 0 && resolvedUnits.includes(unit)) { (unit === DimUnit.Ratio) && (starSum += magnitude); widthSpecifiers.push({ magnitude, unit }); @@ -82,9 +81,9 @@ export class CollectionMulticolumnView extends CollectionSubView(MulticolumnDocu setTimeout(() => { const { ratioDefinedDocs } = this; if (this.childLayoutPairs.length) { - const minimum = Math.min(...ratioDefinedDocs.map(({ dimMagnitude }) => NumCast(dimMagnitude))); + const minimum = Math.min(...ratioDefinedDocs.map(doc => NumCast(doc.dimMagnitude, 1))); if (minimum !== 0) { - ratioDefinedDocs.forEach(layout => layout.dimMagnitude = NumCast(layout.dimMagnitude) / minimum); + ratioDefinedDocs.forEach(layout => layout.dimMagnitude = NumCast(layout.dimMagnitude, 1) / minimum, 1); } } }); @@ -119,7 +118,7 @@ export class CollectionMulticolumnView extends CollectionSubView(MulticolumnDocu private get totalRatioAllocation(): number | undefined { const layoutInfoLen = this.resolvedLayoutInformation.widthSpecifiers.length; if (layoutInfoLen > 0 && this.totalFixedAllocation !== undefined) { - return this.props.PanelWidth() - (this.totalFixedAllocation + resizerWidth * (layoutInfoLen - 1)); + return this.props.PanelWidth() - (this.totalFixedAllocation + resizerWidth * (layoutInfoLen - 1)) - 2 * NumCast(this.props.Document._xMargin); } } @@ -160,8 +159,8 @@ export class CollectionMulticolumnView extends CollectionSubView(MulticolumnDocu if (columnUnitLength === undefined) { return 0; // we're still waiting on promises to resolve } - let width = NumCast(layout.dimMagnitude); - if (StrCast(layout.dimUnit) === DimUnit.Ratio) { + let width = NumCast(layout.dimMagnitude, 1); + if (StrCast(layout.dimUnit, "*") === DimUnit.Ratio) { width *= columnUnitLength; } return width; @@ -203,6 +202,19 @@ export class CollectionMulticolumnView extends CollectionSubView(MulticolumnDocu @computed get onChildClickHandler() { return ScriptCast(this.Document.onChildClick); } + getDisplayDoc(layout: Doc, dxf: () => Transform, width: () => number, height: () => number) { + return <ContentFittingDocumentView + {...this.props} + Document={layout} + DataDocument={layout.resolvedDataDoc as Doc} + CollectionDoc={this.props.Document} + PanelWidth={width} + PanelHeight={height} + getTransform={dxf} + onClick={this.onChildClickHandler} + renderDepth={this.props.renderDepth + 1} + /> + } /** * @returns the resolved list of rendered child documents, displayed * at their resolved pixel widths, each separated by a resizer. @@ -214,21 +226,14 @@ export class CollectionMulticolumnView extends CollectionSubView(MulticolumnDocu const collector: JSX.Element[] = []; for (let i = 0; i < childLayoutPairs.length; i++) { const { layout } = childLayoutPairs[i]; + const dxf = () => this.lookupIndividualTransform(layout).translate(-NumCast(Document._xMargin), -NumCast(Document._yMargin)); + const width = () => this.lookupPixels(layout); + const height = () => PanelHeight() - 2 * NumCast(Document._yMargin) - (BoolCast(Document.showWidthLabels) ? 20 : 0); collector.push( - <div - className={"document-wrapper"} - key={Utils.GenerateGuid()} - > - <ContentFittingDocumentView - {...this.props} - Document={layout} - DataDocument={layout.resolvedDataDoc as Doc} - CollectionDoc={this.props.Document} - PanelWidth={() => this.lookupPixels(layout)} - PanelHeight={() => PanelHeight() - (BoolCast(Document.showWidthLabels) ? 20 : 0)} - getTransform={() => this.lookupIndividualTransform(layout)} - onClick={this.onChildClickHandler} - /> + <div className={"document-wrapper"} + key={"wrapper" + i} + style={{ width: width() }} > + {this.getDisplayDoc(layout, dxf, width, height)} <WidthLabel layout={layout} collectionDoc={Document} @@ -236,7 +241,7 @@ export class CollectionMulticolumnView extends CollectionSubView(MulticolumnDocu </div>, <ResizeBar width={resizerWidth} - key={Utils.GenerateGuid()} + key={"resizer" + i} columnUnitLength={this.getColumnUnitLength} toLeft={layout} toRight={childLayoutPairs[i + 1]?.layout} @@ -249,7 +254,11 @@ export class CollectionMulticolumnView extends CollectionSubView(MulticolumnDocu render(): JSX.Element { return ( - <div className={"collectionMulticolumnView_contents"} ref={this.createDashEventsTarget}> + <div className={"collectionMulticolumnView_contents"} + style={{ + marginLeft: NumCast(this.props.Document._xMargin), marginRight: NumCast(this.props.Document._xMargin), + marginTop: NumCast(this.props.Document._yMargin), marginBottom: NumCast(this.props.Document._yMargin) + }} ref={this.createDashEventsTarget}> {this.contents} </div> ); diff --git a/src/client/views/collections/collectionMulticolumn/CollectionMultirowView.scss b/src/client/views/collections/collectionMulticolumn/CollectionMultirowView.scss index ef4b4a19c..64f607680 100644 --- a/src/client/views/collections/collectionMulticolumn/CollectionMultirowView.scss +++ b/src/client/views/collections/collectionMulticolumn/CollectionMultirowView.scss @@ -8,6 +8,7 @@ .document-wrapper { display: flex; flex-direction: row; + height: 100%; .label-wrapper { display: flex; @@ -18,13 +19,13 @@ } - .resizer { + .multiRowResizer { cursor: ew-resize; transition: 0.5s opacity ease; display: flex; flex-direction: row; - .internal { + .multiRowResizer-hdl { width: 100%; height: 100%; transition: 0.5s background-color ease; diff --git a/src/client/views/collections/collectionMulticolumn/CollectionMultirowView.tsx b/src/client/views/collections/collectionMulticolumn/CollectionMultirowView.tsx index aa440b677..ff7c4998f 100644 --- a/src/client/views/collections/collectionMulticolumn/CollectionMultirowView.tsx +++ b/src/client/views/collections/collectionMulticolumn/CollectionMultirowView.tsx @@ -34,7 +34,7 @@ export const DimUnit = { }; const resolvedUnits = Object.values(DimUnit); -const resizerHeight = 4; +const resizerHeight = 8; @observer export class CollectionMultirowView extends CollectionSubView(MultirowDocument) { @@ -45,7 +45,7 @@ export class CollectionMultirowView extends CollectionSubView(MultirowDocument) */ @computed private get ratioDefinedDocs() { - return this.childLayoutPairs.map(({ layout }) => layout).filter(({ dimUnit }) => StrCast(dimUnit) === DimUnit.Ratio); + return this.childLayoutPairs.map(pair => pair.layout).filter(layout => StrCast(layout.dimUnit, "*") === DimUnit.Ratio); } /** @@ -60,9 +60,9 @@ export class CollectionMultirowView extends CollectionSubView(MultirowDocument) private get resolvedLayoutInformation(): LayoutData { let starSum = 0; const heightSpecifiers: HeightSpecifier[] = []; - this.childLayoutPairs.map(({ layout: { dimUnit, dimMagnitude } }) => { - const unit = StrCast(dimUnit); - const magnitude = NumCast(dimMagnitude); + this.childLayoutPairs.map(pair => { + const unit = StrCast(pair.layout.dimUnit, "*"); + const magnitude = NumCast(pair.layout.dimMagnitude, 1); if (unit && magnitude && magnitude > 0 && resolvedUnits.includes(unit)) { (unit === DimUnit.Ratio) && (starSum += magnitude); heightSpecifiers.push({ magnitude, unit }); @@ -82,9 +82,9 @@ export class CollectionMultirowView extends CollectionSubView(MultirowDocument) setTimeout(() => { const { ratioDefinedDocs } = this; if (this.childLayoutPairs.length) { - const minimum = Math.min(...ratioDefinedDocs.map(({ dimMagnitude }) => NumCast(dimMagnitude))); + const minimum = Math.min(...ratioDefinedDocs.map(layout => NumCast(layout.dimMagnitude, 1))); if (minimum !== 0) { - ratioDefinedDocs.forEach(layout => layout.dimMagnitude = NumCast(layout.dimMagnitude) / minimum); + ratioDefinedDocs.forEach(layout => layout.dimMagnitude = NumCast(layout.dimMagnitude, 1) / minimum); } } }); @@ -119,7 +119,7 @@ export class CollectionMultirowView extends CollectionSubView(MultirowDocument) private get totalRatioAllocation(): number | undefined { const layoutInfoLen = this.resolvedLayoutInformation.heightSpecifiers.length; if (layoutInfoLen > 0 && this.totalFixedAllocation !== undefined) { - return this.props.PanelHeight() - (this.totalFixedAllocation + resizerHeight * (layoutInfoLen - 1)); + return this.props.PanelHeight() - (this.totalFixedAllocation + resizerHeight * (layoutInfoLen - 1)) - 2 * NumCast(this.props.Document._yMargin); } } @@ -160,8 +160,8 @@ export class CollectionMultirowView extends CollectionSubView(MultirowDocument) if (rowUnitLength === undefined) { return 0; // we're still waiting on promises to resolve } - let height = NumCast(layout.dimMagnitude); - if (StrCast(layout.dimUnit) === DimUnit.Ratio) { + let height = NumCast(layout.dimMagnitude, 1); + if (StrCast(layout.dimUnit, "*") === DimUnit.Ratio) { height *= rowUnitLength; } return height; @@ -203,6 +203,19 @@ export class CollectionMultirowView extends CollectionSubView(MultirowDocument) @computed get onChildClickHandler() { return ScriptCast(this.Document.onChildClick); } + getDisplayDoc(layout: Doc, dxf: () => Transform, width: () => number, height: () => number) { + return <ContentFittingDocumentView + {...this.props} + Document={layout} + DataDocument={layout.resolvedDataDoc as Doc} + CollectionDoc={this.props.Document} + PanelWidth={width} + PanelHeight={height} + getTransform={dxf} + onClick={this.onChildClickHandler} + renderDepth={this.props.renderDepth + 1} + /> + } /** * @returns the resolved list of rendered child documents, displayed * at their resolved pixel widths, each separated by a resizer. @@ -214,22 +227,15 @@ export class CollectionMultirowView extends CollectionSubView(MultirowDocument) const collector: JSX.Element[] = []; for (let i = 0; i < childLayoutPairs.length; i++) { const { layout } = childLayoutPairs[i]; + const dxf = () => this.lookupIndividualTransform(layout).translate(-NumCast(Document._xMargin), -NumCast(Document._yMargin)); + const height = () => this.lookupPixels(layout); + const width = () => PanelWidth() - 2 * NumCast(Document._xMargin) - (BoolCast(Document.showWidthLabels) ? 20 : 0); collector.push( <div className={"document-wrapper"} - key={Utils.GenerateGuid()} + key={"wrapper" + i} > - <ContentFittingDocumentView - {...this.props} - Document={layout} - DataDocument={layout.resolvedDataDoc as Doc} - CollectionDoc={this.props.Document} - PanelHeight={() => this.lookupPixels(layout)} - PanelWidth={() => PanelWidth() - (BoolCast(Document.showHeightLabels) ? 20 : 0)} - getTransform={() => this.lookupIndividualTransform(layout)} - onClick={this.onChildClickHandler} - renderDepth={this.props.renderDepth + 1} - /> + {this.getDisplayDoc(layout, dxf, width, height)} <HeightLabel layout={layout} collectionDoc={Document} @@ -237,7 +243,7 @@ export class CollectionMultirowView extends CollectionSubView(MultirowDocument) </div>, <ResizeBar height={resizerHeight} - key={Utils.GenerateGuid()} + key={"resizer" + i} columnUnitLength={this.getRowUnitLength} toTop={layout} toBottom={childLayoutPairs[i + 1]?.layout} @@ -250,7 +256,11 @@ export class CollectionMultirowView extends CollectionSubView(MultirowDocument) render(): JSX.Element { return ( - <div className={"collectionMultirowView_contents"} ref={this.createDashEventsTarget}> + <div className={"collectionMultirowView_contents"} + style={{ + marginLeft: NumCast(this.props.Document._xMargin), marginRight: NumCast(this.props.Document._xMargin), + marginTop: NumCast(this.props.Document._yMargin), marginBottom: NumCast(this.props.Document._yMargin) + }} ref={this.createDashEventsTarget}> {this.contents} </div> ); diff --git a/src/client/views/collections/collectionMulticolumn/MulticolumnResizer.tsx b/src/client/views/collections/collectionMulticolumn/MulticolumnResizer.tsx index 46c39d817..6b89402e6 100644 --- a/src/client/views/collections/collectionMulticolumn/MulticolumnResizer.tsx +++ b/src/client/views/collections/collectionMulticolumn/MulticolumnResizer.tsx @@ -46,14 +46,12 @@ export default class ResizeBar extends React.Component<ResizerProps> { const unitLength = columnUnitLength(); if (unitLength) { if (toNarrow) { - const { dimUnit, dimMagnitude } = toNarrow; - const scale = dimUnit === DimUnit.Ratio ? unitLength : 1; - toNarrow.dimMagnitude = NumCast(dimMagnitude) - Math.abs(movementX) / scale; + const scale = StrCast(toNarrow.dimUnit, "*") === DimUnit.Ratio ? unitLength : 1; + toNarrow.dimMagnitude = Math.max(0.05, NumCast(toNarrow.dimMagnitude, 1) - Math.abs(movementX) / scale); } if (this.resizeMode === ResizeMode.Pinned && toWiden) { - const { dimUnit, dimMagnitude } = toWiden; - const scale = dimUnit === DimUnit.Ratio ? unitLength : 1; - toWiden.dimMagnitude = NumCast(dimMagnitude) + Math.abs(movementX) / scale; + const scale = StrCast(toWiden.dimUnit, "*") === DimUnit.Ratio ? unitLength : 1; + toWiden.dimMagnitude = Math.max(0.05, NumCast(toWiden.dimMagnitude, 1) + Math.abs(movementX) / scale); } } } @@ -61,17 +59,17 @@ export default class ResizeBar extends React.Component<ResizerProps> { private get isActivated() { const { toLeft, toRight } = this.props; if (toLeft && toRight) { - if (StrCast(toLeft.dimUnit) === DimUnit.Pixel && StrCast(toRight.dimUnit) === DimUnit.Pixel) { + if (StrCast(toLeft.dimUnit, "*") === DimUnit.Pixel && StrCast(toRight.dimUnit, "*") === DimUnit.Pixel) { return false; } return true; } else if (toLeft) { - if (StrCast(toLeft.dimUnit) === DimUnit.Pixel) { + if (StrCast(toLeft.dimUnit, "*") === DimUnit.Pixel) { return false; } return true; } else if (toRight) { - if (StrCast(toRight.dimUnit) === DimUnit.Pixel) { + if (StrCast(toRight.dimUnit, "*") === DimUnit.Pixel) { return false; } return true; @@ -91,7 +89,7 @@ export default class ResizeBar extends React.Component<ResizerProps> { render() { return ( <div - className={"resizer"} + className={"multiColumnResizer"} style={{ width: this.props.width, opacity: this.isActivated && this.isHoverActive ? resizerOpacity : 0 @@ -100,12 +98,12 @@ export default class ResizeBar extends React.Component<ResizerProps> { onPointerLeave={action(() => !this.isResizingActive && (this.isHoverActive = false))} > <div - className={"internal"} + className={"multiColumnResizer-hdl"} onPointerDown={e => this.registerResizing(e, ResizeMode.Pinned)} style={{ backgroundColor: this.resizeMode }} /> <div - className={"internal"} + className={"multiColumnResizer-hdl"} onPointerDown={e => this.registerResizing(e, ResizeMode.Global)} style={{ backgroundColor: this.resizeMode }} /> diff --git a/src/client/views/collections/collectionMulticolumn/MultirowResizer.tsx b/src/client/views/collections/collectionMulticolumn/MultirowResizer.tsx index 4f58f3fa8..d00939b26 100644 --- a/src/client/views/collections/collectionMulticolumn/MultirowResizer.tsx +++ b/src/client/views/collections/collectionMulticolumn/MultirowResizer.tsx @@ -46,14 +46,12 @@ export default class ResizeBar extends React.Component<ResizerProps> { const unitLength = columnUnitLength(); if (unitLength) { if (toNarrow) { - const { dimUnit, dimMagnitude } = toNarrow; - const scale = dimUnit === DimUnit.Ratio ? unitLength : 1; - toNarrow.dimMagnitude = NumCast(dimMagnitude) - Math.abs(movementY) / scale; + const scale = StrCast(toNarrow.dimUnit, "*") === DimUnit.Ratio ? unitLength : 1; + toNarrow.dimMagnitude = Math.max(0.05, NumCast(toNarrow.dimMagnitude, 1) - Math.abs(movementY) / scale); } if (this.resizeMode === ResizeMode.Pinned && toWiden) { - const { dimUnit, dimMagnitude } = toWiden; - const scale = dimUnit === DimUnit.Ratio ? unitLength : 1; - toWiden.dimMagnitude = NumCast(dimMagnitude) + Math.abs(movementY) / scale; + const scale = StrCast(toWiden.dimUnit, "*") === DimUnit.Ratio ? unitLength : 1; + toWiden.dimMagnitude = Math.max(0.05, NumCast(toWiden.dimMagnitude, 1) + Math.abs(movementY) / scale); } } } @@ -61,17 +59,17 @@ export default class ResizeBar extends React.Component<ResizerProps> { private get isActivated() { const { toTop, toBottom } = this.props; if (toTop && toBottom) { - if (StrCast(toTop.dimUnit) === DimUnit.Pixel && StrCast(toBottom.dimUnit) === DimUnit.Pixel) { + if (StrCast(toTop.dimUnit, "*") === DimUnit.Pixel && StrCast(toBottom.dimUnit, "*") === DimUnit.Pixel) { return false; } return true; } else if (toTop) { - if (StrCast(toTop.dimUnit) === DimUnit.Pixel) { + if (StrCast(toTop.dimUnit, "*") === DimUnit.Pixel) { return false; } return true; } else if (toBottom) { - if (StrCast(toBottom.dimUnit) === DimUnit.Pixel) { + if (StrCast(toBottom.dimUnit, "*") === DimUnit.Pixel) { return false; } return true; @@ -91,7 +89,7 @@ export default class ResizeBar extends React.Component<ResizerProps> { render() { return ( <div - className={"resizer"} + className={"multiRowResizer"} style={{ height: this.props.height, opacity: this.isActivated && this.isHoverActive ? resizerOpacity : 0 @@ -100,12 +98,12 @@ export default class ResizeBar extends React.Component<ResizerProps> { onPointerLeave={action(() => !this.isResizingActive && (this.isHoverActive = false))} > <div - className={"internal"} + className={"multiRowResizer-hdl"} onPointerDown={e => this.registerResizing(e, ResizeMode.Pinned)} style={{ backgroundColor: this.resizeMode }} /> <div - className={"internal"} + className={"multiRowResizer-hdl"} onPointerDown={e => this.registerResizing(e, ResizeMode.Global)} style={{ backgroundColor: this.resizeMode }} /> |
