diff options
author | Bob Zeleznik <zzzman@gmail.com> | 2019-10-10 01:22:27 -0400 |
---|---|---|
committer | Bob Zeleznik <zzzman@gmail.com> | 2019-10-10 01:22:27 -0400 |
commit | ee10ec0995fa67d27edb9032ba6fadf79bbdaaa1 (patch) | |
tree | 6acf13ed85a669b6b9e1baf7a7b4ea21c38053f7 | |
parent | f46a8292fed43e3ef0b4b3607475b8862b42e562 (diff) |
fixed document decorations for masonry view & scrolling. cleaned up duplicated code a bit.
4 files changed, 53 insertions, 79 deletions
diff --git a/src/client/views/collections/CollectionMasonryViewFieldRow.tsx b/src/client/views/collections/CollectionMasonryViewFieldRow.tsx index b744ce4a5..5c1960d53 100644 --- a/src/client/views/collections/CollectionMasonryViewFieldRow.tsx +++ b/src/client/views/collections/CollectionMasonryViewFieldRow.tsx @@ -88,32 +88,6 @@ export class CollectionMasonryViewFieldRow extends React.Component<CMVFieldRowPr } }) - masonryChildren(docs: Doc[]) { - let parent = this.props.parent; - parent._docXfs.length = 0; - return docs.map((d, i) => { - let dref = React.createRef<HTMLDivElement>(); - let layoutDoc = Doc.expandTemplateLayout(d, parent.props.DataDoc); - let width = () => (d.nativeWidth && !d.ignoreAspect && !parent.props.Document.fillColumn ? Math.min(d[WidthSym](), parent.columnWidth) : parent.columnWidth);/// (uniqueHeadings.length + 1); - let height = () => parent.getDocHeight(layoutDoc); - let dxf = () => parent.getDocTransform(layoutDoc as Doc, dref.current!); - let rowSpan = Math.ceil((height() + parent.gridGap) / parent.gridGap); - parent._docXfs.push({ dxf: dxf, width: width, height: height }); - return <div className="collectionStackingView-masonryDoc" key={d[Id]} ref={dref} style={{ gridRowEnd: `span ${rowSpan}` }} > - {this.props.parent.getDisplayDoc(layoutDoc as Doc, d, dxf, width)} - </div>; - }); - } - - getDocTransform(doc: Doc, dref: HTMLDivElement) { - let { scale, translateX, translateY } = Utils.GetScreenTransform(dref); - let outerXf = Utils.GetScreenTransform(this.props.parent._masonryGridRef!); - let offset = this.props.parent.props.ScreenToLocalTransform().transformDirection(outerXf.translateX - translateX, outerXf.translateY - translateY); - return this.props.parent.props.ScreenToLocalTransform(). - translate(offset[0], offset[1]). - scale(NumCast(doc.width, 1) / this.props.parent.columnWidth); - } - getValue = (value: string): any => { let parsed = parseInt(value); if (!isNaN(parsed)) { @@ -402,7 +376,7 @@ export class CollectionMasonryViewFieldRow extends React.Component<CMVFieldRowPr gridGap: this.props.parent.gridGap, gridTemplateColumns: numberRange(rows).reduce((list: string, i: any) => list + ` ${this.props.parent.columnWidth}px`, ""), }}> - {this.masonryChildren(this.props.docList)} + {this.props.parent.children(this.props.docList)} {this.props.parent.columnDragger} </div> {(chromeStatus !== 'view-mode' && chromeStatus !== 'disabled') ? diff --git a/src/client/views/collections/CollectionStackingView.scss b/src/client/views/collections/CollectionStackingView.scss index 7bf8348ff..b31f0b8e3 100644 --- a/src/client/views/collections/CollectionStackingView.scss +++ b/src/client/views/collections/CollectionStackingView.scss @@ -7,12 +7,16 @@ .collectionStackingView { display: flex; } - +.collectionStackingMasonry-cont { + position:relative; + height:100%; + width:100%; +} .collectionStackingView, .collectionMasonryView { height: 100%; width: 100%; - position: relative; + position: absolute; top: 0; overflow-y: auto; flex-wrap: wrap; diff --git a/src/client/views/collections/CollectionStackingView.tsx b/src/client/views/collections/CollectionStackingView.tsx index cde015152..0dfd1d9cf 100644 --- a/src/client/views/collections/CollectionStackingView.tsx +++ b/src/client/views/collections/CollectionStackingView.tsx @@ -29,12 +29,12 @@ import { CollectionMasonryViewFieldRow } from "./CollectionMasonryViewFieldRow"; export class CollectionStackingView extends CollectionSubView(doc => doc) { _masonryGridRef: HTMLDivElement | null = null; _draggerRef = React.createRef<HTMLDivElement>(); - @observable _heightMap = new Map<string, number>(); _heightDisposer?: IReactionDisposer; _sectionFilterDisposer?: IReactionDisposer; _docXfs: any[] = []; _columnStart: number = 0; - @observable private cursor: CursorProperty = "grab"; + @observable _heightMap = new Map<string, number>(); + @observable _cursor: CursorProperty = "grab"; @observable _scroll = 0; // used to force the document decoration to update when scrolling @computed get sectionHeaders() { return Cast(this.props.Document.sectionHeaders, listSpec(SchemaHeaderField)); } @computed get sectionFilter() { return StrCast(this.props.Document.sectionFilter); } @@ -49,12 +49,26 @@ export class CollectionStackingView extends CollectionSubView(doc => doc) { return Math.min(this.props.PanelWidth() / (this.props as any).ContentScaling() - 2 * this.xMargin, this.isStackingView ? Number.MAX_VALUE : NumCast(this.props.Document.columnWidth, 250)); } - @computed get NodeWidth() { - return this.props.PanelWidth(); - } + @computed get NodeWidth() { return this.props.PanelWidth(); } childDocHeight(child: Doc) { return this.getDocHeight(Doc.GetLayoutDataDocPair(this.props.Document, this.props.DataDoc, this.props.fieldKey, child).layout); } + children(docs: Doc[]) { + this._docXfs.length = 0; + return docs.map((d, i) => { + let pair = Doc.GetLayoutDataDocPair(this.props.Document, this.props.DataDoc, this.props.fieldKey, d); + let width = () => Math.min(d.nativeWidth && !d.ignoreAspect && !this.props.Document.fillColumn ? d[WidthSym]() : Number.MAX_VALUE, this.columnWidth / this.numGroupColumns); + let height = () => this.getDocHeight(pair.layout); + let dref = React.createRef<HTMLDivElement>(); + let dxf = () => this.getDocTransform(pair.layout!, dref.current!); + this._docXfs.push({ dxf: dxf, width: width, height: height }); + let rowSpan = Math.ceil((height() + this.gridGap) / this.gridGap); + let style = this.isStackingView ? { width: width(), margin: "auto", marginTop: i === 0 ? 0 : this.gridGap, height: height() } : { gridRowEnd: `span ${rowSpan}` }; + return <div className={`collectionStackingView-${this.isStackingView ? "columnDoc" : "masonryDoc"}`} key={d[Id]} ref={dref} style={style} > + {this.getDisplayDoc(pair.layout as Doc, pair.data, dxf, width)} + </div>; + }); + } @action setDocHeight = (key: string, sectionHeight: number) => { this._heightMap.set(key, sectionHeight); @@ -177,19 +191,19 @@ export class CollectionStackingView extends CollectionSubView(doc => doc) { if (!d) return 0; let nw = NumCast(d.nativeWidth); let nh = NumCast(d.nativeHeight); + let wid = this.columnWidth / (this.isStackingView ? this.numGroupColumns : 1); if (!d.ignoreAspect && !d.fitWidth && nw && nh) { let aspect = nw && nh ? nh / nw : 1; - let wid = this.columnWidth / (this.isStackingView ? this.numGroupColumns : 1); if (!(d.nativeWidth && !d.ignoreAspect && this.props.Document.fillColumn)) wid = Math.min(d[WidthSym](), wid); return wid * aspect; } - return d.fitWidth ? this.props.PanelHeight() - 2 * this.yMargin : d[HeightSym](); + return d.fitWidth ? Math.min(wid * NumCast(d.scrollHeight, NumCast(d.nativeHeight)) / NumCast(d.nativeWidth, 1), this.props.PanelHeight() - 2 * this.yMargin) : d[HeightSym](); } columnDividerDown = (e: React.PointerEvent) => { e.stopPropagation(); e.preventDefault(); - runInAction(() => this.cursor = "grabbing"); + runInAction(() => this._cursor = "grabbing"); document.addEventListener("pointermove", this.onDividerMove); document.addEventListener('pointerup', this.onDividerUp); this._columnStart = this.props.ScreenToLocalTransform().transformPoint(e.clientX, e.clientY)[0]; @@ -204,13 +218,13 @@ export class CollectionStackingView extends CollectionSubView(doc => doc) { @action onDividerUp = (e: PointerEvent): void => { - runInAction(() => this.cursor = "grab"); + runInAction(() => this._cursor = "grab"); document.removeEventListener("pointermove", this.onDividerMove); document.removeEventListener('pointerup', this.onDividerUp); } @computed get columnDragger() { - return <div className="collectionStackingView-columnDragger" onPointerDown={this.columnDividerDown} ref={this._draggerRef} style={{ cursor: this.cursor, left: `${this.columnWidth + this.xMargin}px` }} > + return <div className="collectionStackingView-columnDragger" onPointerDown={this.columnDividerDown} ref={this._draggerRef} style={{ cursor: this._cursor, left: `${this.columnWidth + this.xMargin}px` }} > <FontAwesomeIcon icon={"arrows-alt-h"} /> </div>; } @@ -375,26 +389,27 @@ export class CollectionStackingView extends CollectionSubView(doc => doc) { sections = entries.sort(this.sortFunc); } return ( - <div className={this.isStackingView ? "collectionStackingView" : "collectionMasonryView"} - ref={this.createRef} - onScroll={action((e: React.UIEvent<HTMLDivElement>) => this._scroll = e.currentTarget.scrollTop)} - onDrop={this.onDrop.bind(this)} - onContextMenu={this.onContextMenu} - onWheel={(e: React.WheelEvent) => e.stopPropagation()} > - {sections.map(section => this.isStackingView ? this.sectionStacking(section[0], section[1]) : this.sectionMasonry(section[0], section[1]))} - {!this.showAddAGroup ? (null) : - <div key={`${this.props.Document[Id]}-addGroup`} className="collectionStackingView-addGroupButton" - style={{ width: this.columnWidth / this.numGroupColumns - 10, marginTop: 10 }}> - <EditableView {...editableViewProps} /> - </div>} - {this.props.ContainingCollectionDoc && this.props.ContainingCollectionDoc.chromeStatus !== 'disabled' ? <Switch - onChange={this.onToggle} - onClick={this.onToggle} - defaultChecked={this.props.ContainingCollectionDoc.chromeStatus !== 'view-mode'} - checkedChildren="edit" - unCheckedChildren="view" - /> : null} - </div> + <div className="collectionStackingMasonry-cont" > + <div className={this.isStackingView ? "collectionStackingView" : "collectionMasonryView"} + ref={this.createRef} + onScroll={action((e: React.UIEvent<HTMLDivElement>) => this._scroll = e.currentTarget.scrollTop)} + onDrop={this.onDrop.bind(this)} + onContextMenu={this.onContextMenu} + onWheel={(e: React.WheelEvent) => e.stopPropagation()} > + {sections.map(section => this.isStackingView ? this.sectionStacking(section[0], section[1]) : this.sectionMasonry(section[0], section[1]))} + {!this.showAddAGroup ? (null) : + <div key={`${this.props.Document[Id]}-addGroup`} className="collectionStackingView-addGroupButton" + style={{ width: this.columnWidth / this.numGroupColumns - 10, marginTop: 10 }}> + <EditableView {...editableViewProps} /> + </div>} + {this.props.ContainingCollectionDoc && this.props.ContainingCollectionDoc.chromeStatus !== 'disabled' ? <Switch + onChange={this.onToggle} + onClick={this.onToggle} + defaultChecked={this.props.ContainingCollectionDoc.chromeStatus !== 'view-mode'} + checkedChildren="edit" + unCheckedChildren="view" + /> : null} + </div> </div> ); } }
\ No newline at end of file diff --git a/src/client/views/collections/CollectionStackingViewFieldColumn.tsx b/src/client/views/collections/CollectionStackingViewFieldColumn.tsx index cc7fe2aa1..e8627780d 100644 --- a/src/client/views/collections/CollectionStackingViewFieldColumn.tsx +++ b/src/client/views/collections/CollectionStackingViewFieldColumn.tsx @@ -73,25 +73,6 @@ export class CollectionStackingViewFieldColumn extends React.Component<CSVFieldC e.stopPropagation(); } }) - - children(docs: Doc[]) { - let parent = this.props.parent; - parent._docXfs.length = 0; - return docs.map((d, i) => { - let pair = Doc.GetLayoutDataDocPair(parent.props.Document, parent.props.DataDoc, parent.props.fieldKey, d); - let width = () => Math.min(d.nativeWidth && !d.ignoreAspect && !parent.props.Document.fillColumn ? d[WidthSym]() : Number.MAX_VALUE, parent.columnWidth / parent.numGroupColumns); - let height = () => parent.getDocHeight(pair.layout); - let dref = React.createRef<HTMLDivElement>(); - let dxf = () => parent.getDocTransform(pair.layout!, dref.current!); - parent._docXfs.push({ dxf: dxf, width: width, height: height }); - let rowSpan = Math.ceil((height() + parent.gridGap) / parent.gridGap); - let style = parent.isStackingView ? { width: width(), margin: "auto", marginTop: i === 0 ? 0 : parent.gridGap, height: height() } : { gridRowEnd: `span ${rowSpan}` }; - return <div className={`collectionStackingView-${parent.isStackingView ? "columnDoc" : "masonryDoc"}`} key={d[Id]} ref={dref} style={style} > - {parent.getDisplayDoc(pair.layout as Doc, pair.data, dxf, width)} - </div>; - }); - } - getValue = (value: string): any => { let parsed = parseInt(value); if (!isNaN(parsed)) { @@ -373,7 +354,7 @@ export class CollectionStackingViewFieldColumn extends React.Component<CSVFieldC gridTemplateColumns: singleColumn ? undefined : templatecols, gridAutoRows: singleColumn ? undefined : "0px" }}> - {this.children(this.props.docList)} + {this.props.parent.children(this.props.docList)} {singleColumn ? (null) : this.props.parent.columnDragger} </div> {(chromeStatus !== 'view-mode' && chromeStatus !== 'disabled') ? |