aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorBob Zeleznik <zzzman@gmail.com>2019-08-14 13:41:23 -0400
committerBob Zeleznik <zzzman@gmail.com>2019-08-14 13:41:23 -0400
commitc357ef923eafc17210f278d36a0693fe902b21fb (patch)
treec790a908d6717dafcce826f3df6859c009315c8f /src
parent7a71c9005189e111e9c9d197d02cc9a6a1bce389 (diff)
fixed more sizing issues with stacking/masonry views
Diffstat (limited to 'src')
-rw-r--r--src/client/views/collections/CollectionDockingView.tsx2
-rw-r--r--src/client/views/collections/CollectionStackingView.tsx90
-rw-r--r--src/client/views/collections/CollectionStackingViewFieldColumn.tsx66
3 files changed, 60 insertions, 98 deletions
diff --git a/src/client/views/collections/CollectionDockingView.tsx b/src/client/views/collections/CollectionDockingView.tsx
index 13bb34037..7332a490a 100644
--- a/src/client/views/collections/CollectionDockingView.tsx
+++ b/src/client/views/collections/CollectionDockingView.tsx
@@ -389,7 +389,7 @@ export class CollectionDockingView extends React.Component<SubCollectionViewProp
const stack = tab.contentItem.parent;
// shifts the focus to this tab when another tab is dragged over it
tab.element[0].onmouseenter = (e: any) => {
- if (!this._isPointerDown) return;
+ if (!this._isPointerDown || !SelectionManager.GetIsDragging()) return;
var activeContentItem = tab.header.parent.getActiveContentItem();
if (tab.contentItem !== activeContentItem) {
tab.header.parent.setActiveContentItem(tab.contentItem);
diff --git a/src/client/views/collections/CollectionStackingView.tsx b/src/client/views/collections/CollectionStackingView.tsx
index d68ef2bbd..4e49e368b 100644
--- a/src/client/views/collections/CollectionStackingView.tsx
+++ b/src/client/views/collections/CollectionStackingView.tsx
@@ -10,7 +10,7 @@ import { List } from "../../../new_fields/List";
import { listSpec } from "../../../new_fields/Schema";
import { SchemaHeaderField } from "../../../new_fields/SchemaHeaderField";
import { BoolCast, Cast, NumCast, StrCast, ScriptCast } from "../../../new_fields/Types";
-import { emptyFunction, Utils } from "../../../Utils";
+import { emptyFunction, Utils, numberRange } from "../../../Utils";
import { DocumentType } from "../../documents/Documents";
import { DragManager } from "../../util/DragManager";
import { Transform } from "../../util/Transform";
@@ -33,14 +33,21 @@ export class CollectionStackingView extends CollectionSubView(doc => doc) {
_docXfs: any[] = [];
_columnStart: number = 0;
@observable private cursor: CursorProperty = "grab";
- get sectionHeaders() { return Cast(this.props.Document.sectionHeaders, listSpec(SchemaHeaderField)); }
+ @computed get sectionHeaders() { return Cast(this.props.Document.sectionHeaders, listSpec(SchemaHeaderField)); }
+ @computed get sectionFilter() { return StrCast(this.props.Document.sectionFilter); }
+ @computed get filteredChildren() { return this.childDocs.filter(d => !d.isMinimized); }
@computed get xMargin() { return NumCast(this.props.Document.xMargin, 2 * this.gridGap); }
@computed get yMargin() { return NumCast(this.props.Document.yMargin, 2 * this.gridGap); }
@computed get gridGap() { return NumCast(this.props.Document.gridGap, 10); }
- @computed get singleColumn() { return BoolCast(this.props.Document.singleColumn, true); }
- @computed get columnWidth() { return this.singleColumn ? (this.props.PanelWidth() / (this.props as any).ContentScaling() - 2 * this.xMargin) : Math.min(this.props.PanelWidth() - 2 * this.xMargin, NumCast(this.props.Document.columnWidth, 250)); }
- @computed get filteredChildren() { return this.childDocs.filter(d => !d.isMinimized); }
- @computed get sectionFilter() { return StrCast(this.props.Document.sectionFilter); }
+ @computed get isStackingView() { return BoolCast(this.props.Document.singleColumn, true); }
+ @computed get numGroupColumns() { return this.isStackingView ? Math.max(1, this.Sections.size + (this.showAddAGroup ? 1 : 0)) : 1; }
+ @computed get showAddAGroup() { return (this.sectionFilter && (this.props.CollectionView.props.Document.chromeStatus !== 'view-mode' && this.props.CollectionView.props.Document.chromeStatus !== 'disabled')); }
+ @computed get columnWidth() {
+ 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));
+ }
+
+ childDocHeight(child: Doc) { return this.getDocHeight(Doc.GetLayoutDataDocPair(this.props.Document, this.props.DataDoc, this.props.fieldKey, child).layout); }
get layoutDoc() {
// if this document's layout field contains a document (ie, a rendering template), then we will use that
@@ -48,7 +55,6 @@ export class CollectionStackingView extends CollectionSubView(doc => doc) {
return this.props.Document.layout instanceof Doc ? this.props.Document.layout : this.props.Document;
}
-
get Sections() {
if (!this.sectionFilter) return new Map<SchemaHeaderField, Doc[]>();
@@ -78,33 +84,19 @@ export class CollectionStackingView extends CollectionSubView(doc => doc) {
}
componentDidMount() {
- // is there any reason this needs to exist? -syip
+ // is there any reason this needs to exist? -syip. yes, it handles autoHeight for stacking views (masonry isn't yet supported).
this._heightDisposer = reaction(() => {
- if (this.singleColumn && BoolCast(this.props.Document.autoHeight)) {
- let maxHght = 0;
- Array.from(this.Sections.values()).map(s => {
- let hgt = 50 + s.reduce((height, d, i) => {
- let pair = Doc.GetLayoutDataDocPair(this.props.Document, this.props.DataDoc, this.props.fieldKey, d);
- return height + this.getDocHeight(pair.layout, this.Sections.size) + (i === this.filteredChildren.length - 1 ? this.yMargin : this.gridGap);
- }, this.yMargin);
- maxHght = Math.max(hgt, maxHght);
- })
- if (!maxHght) {
- let hgt = this.Sections.size * 50 + this.filteredChildren.reduce((height, d, i) => {
- let pair = Doc.GetLayoutDataDocPair(this.props.Document, this.props.DataDoc, this.props.fieldKey, d);
- return height + this.getDocHeight(pair.layout) + (i === this.filteredChildren.length - 1 ? this.yMargin : this.gridGap);
- }, this.yMargin);
- maxHght = hgt * this.props.ContentScaling();
- }
- return maxHght * this.props.ContentScaling();
+ if (this.isStackingView && BoolCast(this.props.Document.autoHeight)) {
+ let sectionsList = Array.from(this.Sections.size ? this.Sections.values() : [this.filteredChildren]);
+ return this.props.ContentScaling() * sectionsList.reduce((maxHght, s) => Math.max(maxHght,
+ 50 + s.reduce((height, d, i) => height + this.childDocHeight(d) + (i === s.length - 1 ? this.yMargin : this.gridGap), this.yMargin)
+ ), 0);
}
return -1;
},
(hgt: number) => {
- if (hgt !== -1) {
- let doc = this.props.DataDoc && this.props.DataDoc.layout === this.layoutDoc ? this.props.DataDoc : this.layoutDoc;
- doc.height = hgt;
- }
+ let doc = hgt === -1 ? undefined : this.props.DataDoc && this.props.DataDoc.layout === this.layoutDoc ? this.props.DataDoc : this.layoutDoc;
+ doc && (doc.height = hgt);
},
{ fireImmediately: true }
);
@@ -137,7 +129,7 @@ export class CollectionStackingView extends CollectionSubView(doc => doc) {
@computed get onClickHandler() { return this.props.onClick ? this.props.onClick : ScriptCast(this.Document.onChildClick); }
getDisplayDoc(layoutDoc: Doc, dataDoc: Doc | undefined, dxf: () => Transform, width: () => number) {
- let height = () => this.getDocHeight(layoutDoc, this.singleColumn ? this.Sections.size : 1);
+ let height = () => this.getDocHeight(layoutDoc);
let finalDxf = () => dxf().scale(this.columnWidth / layoutDoc[WidthSym]());
return <CollectionSchemaPreview
Document={layoutDoc}
@@ -160,12 +152,13 @@ export class CollectionStackingView extends CollectionSubView(doc => doc) {
previewScript={undefined}>
</CollectionSchemaPreview>;
}
- getDocHeight(d: Doc, columnScale: number = 1) {
+ getDocHeight(d: Doc) {
let nw = NumCast(d.nativeWidth);
let nh = NumCast(d.nativeHeight);
if (!d.ignoreAspect && nw && nh) {
let aspect = nw && nh ? nh / nw : 1;
- let wid = d.nativeWidth && !d.ignoreAspect && this.props.Document.fillColumn ? this.columnWidth / columnScale : Math.min(d[WidthSym](), this.columnWidth / columnScale);
+ 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[HeightSym]();
@@ -251,15 +244,14 @@ export class CollectionStackingView extends CollectionSubView(doc => doc) {
});
}
headings = () => Array.from(this.Sections.keys());
- section = (heading: SchemaHeaderField | undefined, docList: Doc[]) => {
- if (!this.singleColumn) return this.sectionMasonry(heading, docList);
+ sectionStacking = (heading: SchemaHeaderField | undefined, docList: Doc[]) => {
let key = this.sectionFilter;
let type: "string" | "number" | "bigint" | "boolean" | "symbol" | "undefined" | "object" | "function" | undefined = undefined;
let types = docList.length ? docList.map(d => typeof d[key]) : this.childDocs.map(d => typeof d[key]);
if (types.map((i, idx) => types.indexOf(i) === idx).length === 1) {
type = types[0];
}
- let cols = () => this.singleColumn ? 1 : Math.max(1, Math.min(this.filteredChildren.length,
+ let cols = () => this.isStackingView ? 1 : Math.max(1, Math.min(this.filteredChildren.length,
Math.floor((this.props.PanelWidth() - 2 * this.xMargin) / (this.columnWidth + this.gridGap))));
return <CollectionStackingViewFieldColumn
key={heading ? heading.heading : ""}
@@ -283,13 +275,13 @@ export class CollectionStackingView extends CollectionSubView(doc => doc) {
translate(offset[0], offset[1]).
scale(NumCast(doc.width, 1) / this.columnWidth);
}
- children(docs: Doc[]) {
+ masonryChildren(docs: Doc[]) {
this._docXfs.length = 0;
return docs.map((d, i) => {
+ let dref = React.createRef<HTMLDivElement>();
let layoutDoc = Doc.expandTemplateLayout(d, this.props.DataDoc);
let width = () => (d.nativeWidth && !d.ignoreAspect && !this.props.Document.fillColumn ? Math.min(d[WidthSym](), this.columnWidth) : this.columnWidth);/// (uniqueHeadings.length + 1);
let height = () => this.getDocHeight(layoutDoc);
- let dref = React.createRef<HTMLDivElement>();
let dxf = () => this.getDocTransform(layoutDoc, dref.current!);
let rowSpan = Math.ceil((height() + this.gridGap) / this.gridGap);
this._docXfs.push({ dxf: dxf, width: width, height: height });
@@ -302,8 +294,6 @@ export class CollectionStackingView extends CollectionSubView(doc => doc) {
sectionMasonry(heading: SchemaHeaderField | undefined, docList: Doc[]) {
let cols = Math.max(1, Math.min(docList.length,
Math.floor((this.props.PanelWidth() - 2 * this.xMargin) / (this.columnWidth + this.gridGap))));
- let templatecols = "";
- for (let i = 0; i < cols; i++) templatecols += `${this.columnWidth}px `;
return <div key={heading ? heading.heading : "empty"} className="collectionStackingView-masonrySection">
{!heading ? (null) :
<div key={`${heading.heading}`} className="collectionStackingView-sectionHeader" style={{ background: heading.color }}>
@@ -314,10 +304,9 @@ export class CollectionStackingView extends CollectionSubView(doc => doc) {
padding: `${this.yMargin}px ${this.xMargin}px`,
width: `${cols * (this.columnWidth + this.gridGap) + 2 * this.xMargin - this.gridGap}px`,
gridGap: this.gridGap,
- gridTemplateColumns: templatecols,
- }}
- >
- {this.children(docList)}
+ gridTemplateColumns: numberRange(cols).reduce((list, i) => list + ` ${this.columnWidth}px`, ""),
+ }}>
+ {this.masonryChildren(docList)}
{this.columnDragger}
</div>
</div>;
@@ -356,7 +345,6 @@ export class CollectionStackingView extends CollectionSubView(doc => doc) {
}
render() {
- let headings = Array.from(this.Sections.keys());
let editableViewProps = {
GetValue: () => "",
SetValue: this.addGroup,
@@ -364,18 +352,16 @@ export class CollectionStackingView extends CollectionSubView(doc => doc) {
};
Doc.UpdateDocumentExtensionForField(this.props.DataDoc ? this.props.DataDoc : this.props.Document, this.props.fieldKey);
- // let uniqueHeadings = headings.map((i, idx) => headings.indexOf(i) === idx);
+ let sections = (this.sectionFilter ? Array.from(this.Sections.entries()).sort(this.sortFunc) : [[undefined, this.filteredChildren] as [SchemaHeaderField | undefined, Doc[]]])
return (
- <div className={this.singleColumn ? "collectionStackingView" : "collectionMasonryView"}
+ <div className={this.isStackingView ? "collectionStackingView" : "collectionMasonryView"}
ref={this.createRef} onDrop={this.onDrop.bind(this)} onContextMenu={this.onContextMenu} onWheel={(e: React.WheelEvent) => e.stopPropagation()} >
- {this.sectionFilter ? Array.from(this.Sections.entries()).sort(this.sortFunc).
- map((section: [SchemaHeaderField, Doc[]]) => this.section(section[0], section[1])) :
- this.section(undefined, this.filteredChildren)}
- {(this.sectionFilter && (this.props.CollectionView.props.Document.chromeStatus !== 'view-mode' && this.props.CollectionView.props.Document.chromeStatus !== 'disabled')) ?
+ {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 / (headings.length + ((this.props.CollectionView.props.Document.chromeStatus !== 'view-mode' && this.props.CollectionView.props.Document.chromeStatus !== 'disabled') ? 1 : 0))) - 10, marginTop: 10 }}>
+ style={{ width: this.columnWidth / this.numGroupColumns - 10, marginTop: 10 }}>
<EditableView {...editableViewProps} />
- </div> : null}
+ </div>}
{this.props.CollectionView.props.Document.chromeStatus !== 'disabled' ? <Switch
onChange={this.onToggle}
onClick={this.onToggle}
diff --git a/src/client/views/collections/CollectionStackingViewFieldColumn.tsx b/src/client/views/collections/CollectionStackingViewFieldColumn.tsx
index 4a8d7debd..74c7ef305 100644
--- a/src/client/views/collections/CollectionStackingViewFieldColumn.tsx
+++ b/src/client/views/collections/CollectionStackingViewFieldColumn.tsx
@@ -1,28 +1,25 @@
import React = require("react");
+import { library } from '@fortawesome/fontawesome-svg-core';
+import { faPalette } from '@fortawesome/free-solid-svg-icons';
+import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
+import { action, observable } from "mobx";
import { observer } from "mobx-react";
-import { number } from "prop-types";
import { Doc, WidthSym } from "../../../new_fields/Doc";
-import { CollectionStackingView } from "./CollectionStackingView";
import { Id } from "../../../new_fields/FieldSymbols";
+import { PastelSchemaPalette, SchemaHeaderField } from "../../../new_fields/SchemaHeaderField";
+import { ScriptField } from "../../../new_fields/ScriptField";
+import { NumCast, StrCast } from "../../../new_fields/Types";
import { Utils } from "../../../Utils";
-import { NumCast, StrCast, BoolCast } from "../../../new_fields/Types";
-import { EditableView } from "../EditableView";
-import { action, observable, computed } from "mobx";
-import { undoBatch } from "../../util/UndoManager";
-import { DragManager } from "../../util/DragManager";
-import { DocumentManager } from "../../util/DocumentManager";
-import { SelectionManager } from "../../util/SelectionManager";
-import "./CollectionStackingView.scss";
import { Docs } from "../../documents/Documents";
-import { SchemaHeaderField, PastelSchemaPalette } from "../../../new_fields/SchemaHeaderField";
-import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
-import { ScriptField } from "../../../new_fields/ScriptField";
+import { DragManager } from "../../util/DragManager";
import { CompileScript } from "../../util/Scripting";
-import { RichTextField } from "../../../new_fields/RichTextField";
+import { SelectionManager } from "../../util/SelectionManager";
import { Transform } from "../../util/Transform";
-import { Flyout, anchorPoints } from "../DocumentDecorations";
-import { library } from '@fortawesome/fontawesome-svg-core';
-import { faPalette } from '@fortawesome/free-solid-svg-icons';
+import { undoBatch } from "../../util/UndoManager";
+import { anchorPoints, Flyout } from "../DocumentDecorations";
+import { EditableView } from "../EditableView";
+import { CollectionStackingView } from "./CollectionStackingView";
+import "./CollectionStackingView.scss";
library.add(faPalette);
@@ -81,38 +78,17 @@ export class CollectionStackingViewFieldColumn extends React.Component<CSVFieldC
let parent = this.props.parent;
parent._docXfs.length = 0;
return docs.map((d, i) => {
- let headings = this.props.headings();
- let uniqueHeadings = headings.map((i, idx) => headings.indexOf(i) === idx);
let pair = Doc.GetLayoutDataDocPair(parent.props.Document, parent.props.DataDoc, parent.props.fieldKey, d);
- let width = () => (d.nativeWidth && !d.ignoreAspect && !parent.props.Document.fillColumn ? Math.min(d[WidthSym](), parent.columnWidth / (uniqueHeadings.length + 1)) : parent.columnWidth / (uniqueHeadings.length + 1));/// (uniqueHeadings.length + 1);
- let height = () => parent.getDocHeight(pair.layout, uniqueHeadings.length + 1);// / (d.nativeWidth && !BoolCast(d.ignoreAspect) ? uniqueHeadings.length + 1 : 1);
+ 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>();
- // if (uniqueHeadings.length > 0) {
let dxf = () => this.getDocTransform(pair.layout, dref.current!);
this.props.parent._docXfs.push({ dxf: dxf, width: width, height: height });
- // }
- // else {
- // //have to add the height of all previous single column sections or the doc decorations will be in the wrong place.
- // let dxf = () => this.getDocTransform(layoutDoc, i, width());
- // this.props.parent._docXfs.push({ dxf: dxf, width: width, height: height });
- // }
- let rowHgtPcnt = height();
let rowSpan = Math.ceil((height() + parent.gridGap) / parent.gridGap);
- let style = parent.singleColumn ? { width: width(), margin: "auto", marginTop: i === 0 ? 0 : parent.gridGap, height: `${rowHgtPcnt}` } : { gridRowEnd: `span ${rowSpan}` };
- return <div className={`collectionStackingView-${parent.singleColumn ? "columnDoc" : "masonryDoc"}`} key={d[Id]} ref={dref} style={style} >
+ 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} >
{this.props.parent.getDisplayDoc(pair.layout, pair.data, dxf, width)}
</div>;
- // } else {
- // let dref = React.createRef<HTMLDivElement>();
- // let dxf = () => this.getDocTransform(layoutDoc, dref.current!);
- // this.props.parent._docXfs.push({ dxf: dxf, width: width, height: height });
- // let rowHgtPcnt = height();
- // let rowSpan = Math.ceil((height() + parent.gridGap) / parent.gridGap);
- // let divStyle = parent.singleColumn ? { width: width(), marginTop: i === 0 ? 0 : parent.gridGap, height: `${rowHgtPcnt}` } : { gridRowEnd: `span ${rowSpan}` };
- // return <div className="collectionStackingView-masonryDoc" key={d[Id]} ref={dref} style={divStyle} >
- // {this.props.parent.getDisplayDoc(layoutDoc, d, dxf, width)}
- // </div>;
- // }
});
}
@@ -278,7 +254,7 @@ export class CollectionStackingViewFieldColumn extends React.Component<CSVFieldC
let headings = this.props.headings();
let heading = this._heading;
let style = this.props.parent;
- let singleColumn = style.singleColumn;
+ let singleColumn = style.isStackingView;
let uniqueHeadings = headings.map((i, idx) => headings.indexOf(i) === idx);
let evContents = heading ? heading : this.props.type && this.props.type === "number" ? "0" : `NO ${key.toUpperCase()} VALUE`;
let headerEditableViewProps = {
@@ -326,7 +302,7 @@ export class CollectionStackingViewFieldColumn extends React.Component<CSVFieldC
</button>}
</div>
</div> : (null);
- for (let i = 0; i < cols; i++) templatecols += `${style.columnWidth}px `;
+ for (let i = 0; i < cols; i++) templatecols += `${style.columnWidth / style.numGroupColumns}px `;
return (
<div className="collectionStackingViewFieldColumn" key={heading} style={{ width: `${100 / ((uniqueHeadings.length + ((this.props.parent.props.CollectionView.props.Document.chromeStatus !== 'view-mode' && this.props.parent.props.CollectionView.props.Document.chromeStatus !== 'disabled') ? 1 : 0)) || 1)}%`, background: this._background }}
ref={this.createColumnDropRef} onPointerEnter={this.pointerEntered} onPointerLeave={this.pointerLeave}>
@@ -348,7 +324,7 @@ export class CollectionStackingViewFieldColumn extends React.Component<CSVFieldC
</div>
{(this.props.parent.props.CollectionView.props.Document.chromeStatus !== 'view-mode' && this.props.parent.props.CollectionView.props.Document.chromeStatus !== 'disabled') ?
<div key={`${heading}-add-document`} className="collectionStackingView-addDocumentButton"
- style={{ width: style.columnWidth / (uniqueHeadings.length + 1) }}>
+ style={{ width: style.columnWidth / style.numGroupColumns }}>
<EditableView {...newEditableViewProps} />
</div> : null}
</div>