From a2eb8ba283ce4a8fb7f423a9198e2a5778eba886 Mon Sep 17 00:00:00 2001 From: usodhi <61431818+usodhi@users.noreply.github.com> Date: Mon, 4 May 2020 12:18:11 +0530 Subject: updating from master --- src/client/views/nodes/ContentFittingDocumentView.tsx | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'src/client/views/nodes/ContentFittingDocumentView.tsx') diff --git a/src/client/views/nodes/ContentFittingDocumentView.tsx b/src/client/views/nodes/ContentFittingDocumentView.tsx index 641797cac..814f8fd9c 100644 --- a/src/client/views/nodes/ContentFittingDocumentView.tsx +++ b/src/client/views/nodes/ContentFittingDocumentView.tsx @@ -43,6 +43,7 @@ interface ContentFittingDocumentViewProps { pinToPres: (document: Doc) => void; dontRegisterView?: boolean; rootSelected: (outsideReaction?: boolean) => boolean; + Display?: string; } @observer @@ -77,7 +78,8 @@ export class ContentFittingDocumentView extends React.Component 0.001 ? "auto" : this.props.PanelWidth(), - height: Math.abs(this.centeringOffset) > 0.0001 ? "auto" : this.props.PanelHeight() + height: Math.abs(this.centeringOffset) > 0.0001 ? "auto" : this.props.PanelHeight(), + display: this.props.Display /* just added for grid */ }}> {!this.props.Document || !this.props.PanelWidth ? (null) : (
Date: Sun, 24 May 2020 10:36:31 +0530 Subject: Added chrome to grid view and modified grid mechanism --- src/client/views/collections/CollectionView.tsx | 1 + .../views/collections/CollectionViewChromes.scss | 30 ++- .../views/collections/CollectionViewChromes.tsx | 57 ++++- .../collectionGrid/CollectionGridView.tsx | 248 ++++++++++++--------- .../views/collections/collectionGrid/Grid.tsx | 8 + .../views/nodes/ContentFittingDocumentView.tsx | 2 +- src/client/views/nodes/DocumentView.tsx | 1 + 7 files changed, 225 insertions(+), 122 deletions(-) (limited to 'src/client/views/nodes/ContentFittingDocumentView.tsx') diff --git a/src/client/views/collections/CollectionView.tsx b/src/client/views/collections/CollectionView.tsx index 5b344813d..311e8d3a1 100644 --- a/src/client/views/collections/CollectionView.tsx +++ b/src/client/views/collections/CollectionView.tsx @@ -227,6 +227,7 @@ export class CollectionView extends Touchable func(CollectionViewType.Carousel), icon: "columns" }); subItems.push({ description: "Pivot/Time", event: () => func(CollectionViewType.Time), icon: "columns" }); subItems.push({ description: "Map", event: () => func(CollectionViewType.Map), icon: "globe-americas" }); + subItems.push({ description: "Grid", event: () => func(CollectionViewType.Grid), icon: "border-all" }); if (addExtras && this.props.Document._viewType === CollectionViewType.Freeform) { subItems.push({ description: "Custom", icon: "fingerprint", event: AddCustomFreeFormLayout(this.props.Document, this.props.fieldKey) }); } diff --git a/src/client/views/collections/CollectionViewChromes.scss b/src/client/views/collections/CollectionViewChromes.scss index e4581eb46..9795a3a22 100644 --- a/src/client/views/collections/CollectionViewChromes.scss +++ b/src/client/views/collections/CollectionViewChromes.scss @@ -3,7 +3,7 @@ .collectionViewChrome-cont { position: absolute; - width:100%; + width: 100%; opacity: 0.9; z-index: 9001; transition: top .5s; @@ -33,7 +33,7 @@ outline-color: black; } - .collectionViewBaseChrome-button{ + .collectionViewBaseChrome-button { font-size: 75%; text-transform: uppercase; letter-spacing: 2px; @@ -44,6 +44,7 @@ padding: 12px 10px 11px 10px; margin-left: 10px; } + .collectionViewBaseChrome-cmdPicker { margin-left: 3px; margin-right: 0px; @@ -51,14 +52,16 @@ border: none; color: grey; } + .commandEntry-outerDiv { pointer-events: all; background-color: gray; display: flex; flex-direction: row; + .commandEntry-drop { - color:white; - width:25px; + color: white; + width: 25px; margin-top: auto; margin-bottom: auto; } @@ -72,15 +75,17 @@ pointer-events: all; // margin-top: 10px; } + .collectionViewBaseChrome-template, .collectionViewBaseChrome-viewModes { display: grid; background: rgb(238, 238, 238); - color:grey; - margin-top:auto; - margin-bottom:auto; + color: grey; + margin-top: auto; + margin-bottom: auto; margin-left: 5px; } + .collectionViewBaseChrome-viewModes { margin-left: 25px; } @@ -88,7 +93,7 @@ .collectionViewBaseChrome-viewSpecs { margin-left: 5px; display: grid; - + .collectionViewBaseChrome-filterIcon { position: relative; display: flex; @@ -202,7 +207,7 @@ .collectionStackingViewChrome-pivotField, .collectionTreeViewChrome-pivotField { color: white; - width:100%; + width: 100%; min-width: 100px; text-align: center; background: rgb(238, 238, 238); @@ -232,6 +237,10 @@ .collectionTreeViewChrome-pivotField:hover { cursor: text; } + + .collectionGridViewChrome-entryBox { + width: 50%; + } } } @@ -292,8 +301,9 @@ flex-direction: column; height: 40px; } + .commandEntry-inputArea { - display:flex; + display: flex; flex-direction: row; width: 150px; margin: auto auto auto auto; diff --git a/src/client/views/collections/CollectionViewChromes.tsx b/src/client/views/collections/CollectionViewChromes.tsx index 5dc0b09ac..def20ae9b 100644 --- a/src/client/views/collections/CollectionViewChromes.tsx +++ b/src/client/views/collections/CollectionViewChromes.tsx @@ -2,7 +2,7 @@ import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; import { action, computed, observable, runInAction } from "mobx"; import { observer } from "mobx-react"; import * as React from "react"; -import { Doc, DocListCast } from "../../../fields/Doc"; +import { Doc, DocListCast, HeightSym } from "../../../fields/Doc"; import { Id } from "../../../fields/FieldSymbols"; import { List } from "../../../fields/List"; import { listSpec } from "../../../fields/Schema"; @@ -15,6 +15,8 @@ import { COLLECTION_BORDER_WIDTH } from "../globalCssVariables.scss"; import { CollectionViewType } from "./CollectionView"; import { CollectionView } from "./CollectionView"; import "./CollectionViewChromes.scss"; +import { CollectionGridView } from "./collectionGrid/CollectionGridView"; +import HeightLabel from "./collectionMulticolumn/MultirowHeightLabel"; const datepicker = require('js-datepicker'); interface CollectionViewChromeProps { @@ -205,6 +207,7 @@ export class CollectionViewBaseChrome extends React.Component); case CollectionViewType.Tree: return (); case CollectionViewType.Masonry: return (); + case CollectionViewType.Grid: return (); default: return null; } } @@ -504,3 +507,55 @@ export class CollectionTreeViewChrome extends React.Component { + + /** + * Sets the value of `numCols` on the grid's Document to the value entered. + */ + @action + onNumColsEnter = (e: React.KeyboardEvent) => { + if (e.key === "Enter" || e.key === "Tab") { + if (this.props.CollectionView.props.Document.numCols as number !== e.currentTarget.valueAsNumber) { + this.props.CollectionView.props.Document.numCols = e.currentTarget.valueAsNumber; + //this.props.CollectionView.forceUpdate(); // to be used if CollectionGridView is not an observer + } + + } + } + + /** + * Sets the value of `rowHeight` on the grid's Document to the value entered. + */ + @action + onRowHeightEnter = (e: React.KeyboardEvent) => { + if (e.key === "Enter" || e.key === "Tab") { + if (this.props.CollectionView.props.Document.rowHeight as number !== e.currentTarget.valueAsNumber) { + this.props.CollectionView.props.Document.rowHeight = e.currentTarget.valueAsNumber; + //this.props.CollectionView.forceUpdate(); + } + } + } + + render() { + return ( +
+ + + + + + + + + + + + +
+ ); + } +} \ No newline at end of file diff --git a/src/client/views/collections/collectionGrid/CollectionGridView.tsx b/src/client/views/collections/collectionGrid/CollectionGridView.tsx index cd1e0f7f0..ebb710af6 100644 --- a/src/client/views/collections/collectionGrid/CollectionGridView.tsx +++ b/src/client/views/collections/collectionGrid/CollectionGridView.tsx @@ -1,39 +1,58 @@ -import { action, computed, observable } from 'mobx'; -import { observer } from 'mobx-react'; +import { computed, observable, action } from 'mobx'; import * as React from "react"; -import { Doc, DataSym, DocListCast } from '../../../../new_fields/Doc'; -import { documentSchema } from '../../../../new_fields/documentSchemas'; -import { makeInterface } from '../../../../new_fields/Schema'; -import { BoolCast, NumCast, ScriptCast, StrCast, Cast } from '../../../../new_fields/Types'; +import { Doc, DocListCast } from '../../../../fields/Doc'; +import { documentSchema } from '../../../../fields/documentSchemas'; +import { makeInterface, createSchema } from '../../../../fields/Schema'; +import { BoolCast, NumCast, ScriptCast, StrCast, Cast } from '../../../../fields/Types'; import { DragManager } from '../../../util/DragManager'; import { Transform } from '../../../util/Transform'; import { undoBatch } from '../../../util/UndoManager'; import { ContentFittingDocumentView } from '../../nodes/ContentFittingDocumentView'; import { CollectionSubView } from '../CollectionSubView'; -import { List } from '../../../../new_fields/List'; +import { SubCollectionViewProps } from '../CollectionSubView'; +import { List } from '../../../../fields/List'; import { returnZero } from '../../../../Utils'; -import Grid from "./Grid"; -import { Layout } from "./Grid"; +import Grid, { Layout } from "./Grid"; +import { Id } from '../../../../fields/FieldSymbols'; +import { observer } from 'mobx-react'; type GridSchema = makeInterface<[typeof documentSchema]>; const GridSchema = makeInterface(documentSchema); +@observer export class CollectionGridView extends CollectionSubView(GridSchema) { - private layouts: Layout[] = []; - private layoutDocs: Doc[] = []; - @observable private numCols: number = 10; - @observable private rowHeight: number = 100; - @observable private isMounted: boolean = false; + constructor(props: Readonly) { + super(props); - componentDidMount() { - this.isMounted = true; + this.props.Document.numCols = this.props.Document.numCols ? this.props.Document.numCols : 10; + this.props.Document.rowHeight = this.props.Document.rowHeight ? this.props.Document.rowHeight : 100; } - componentWillUnmount() { - this.isMounted = false; - console.log("hola"); + componentDidMount() { + if (!(this.props.Document.gridLayouts as List)?.length) { + + console.log("no layouts stored on doc"); + + this.props.Document.gridLayouts = new List(); + + for (let i = 0; i < this.childLayoutPairs.length; i++) { + + const layoutDoc: Doc = new Doc(); + layoutDoc.i = layoutDoc[Id]; + layoutDoc.x = 2 * (i % 5); + layoutDoc.y = 2 * Math.floor(i / 5); + layoutDoc.w = 2; + layoutDoc.h = 2; + + (this.props.Document.gridLayouts as List).push(layoutDoc); + + // use childlayoutpairs length instead + } + + } + } /** @@ -42,18 +61,26 @@ export class CollectionGridView extends CollectionSubView(GridSchema) { * the sum of all the resolved column widths of the * documents before the target. */ - private lookupIndividualTransform = (layout: Layout) => { + private lookupIndividualTransform = (doc: Doc) => { - const yTranslation = this.rowHeight * layout.y;// + 15 * (layout.y - 1); - console.log(yTranslation); - return this.props.ScreenToLocalTransform().translate(-this.props.PanelWidth() / this.numCols * layout.x, -yTranslation); + const yTranslation = (this.props.Document.rowHeight as number) * (doc.y as number) + 10 * (doc.y as number); + return this.props.ScreenToLocalTransform().translate(-this.props.PanelWidth() / (this.props.Document.numCols as number) * (doc.x as number), -yTranslation); } @computed get onChildClickHandler() { return ScriptCast(this.Document.onChildClick); } - @observable private width = (layout: Layout) => layout.w * this.props.PanelWidth() / this.numCols; - @observable private height = (layout: Layout) => layout.h * this.rowHeight; + /** + * Sets the width of the decorating box. + * @param Doc doc + */ + @observable private width = (doc: Doc) => doc.w as number * this.props.PanelWidth() / (this.props.Document.numCols as number); + + /** + * Sets the height of the decorating box. + * @param doc `Doc` + */ + @observable private height = (doc: Doc) => doc.h as number * (this.props.Document.rowHeight as number); addDocTab = (doc: Doc, where: string) => { if (where === "inPlace" && this.layoutDoc.isInPlaceContainer) { @@ -81,15 +108,23 @@ export class CollectionGridView extends CollectionSubView(GridSchema) { onClick={this.onChildClickHandler} renderDepth={this.props.renderDepth + 1} parentActive={this.props.active} - //Display={"contents"} + display={"contents"} />; } - //@action + /** + * Saves the layouts received from the Grid to the Document. + * @param layouts `Layout[]` + */ set layout(layouts: Layout[]) { - this.layouts = layouts; - this.props.Document.gridLayouts = new List(); + + console.log("setting layout in CollectionGridView"); + console.log(layouts?.[0].w); + //this.props.Document.gridLayouts = new List(); + + const docList: Doc[] = []; + for (const layout of layouts) { const layoutDoc = new Doc(); layoutDoc.i = layout.i; @@ -98,126 +133,119 @@ export class CollectionGridView extends CollectionSubView(GridSchema) { layoutDoc.w = layout.w; layoutDoc.h = layout.h; - (this.props.Document.gridLayouts as List).push(layoutDoc); - console.log("gazoinks"); - + docList.push(layoutDoc); } - this.forceUpdate(); // better way to do this? + + this.props.Document.gridLayouts = new List(docList); } - get layout() { - //console.log(this.layouts.length === 0); - if (this.layouts.length === 0) { - if (this.props.Document.gridLayouts) { - //console.log(this.props.Document.gridLayouts); - // for (const layout of (this.props.Document.gridLayouts as List)) { - // if (layout instanceof Doc) { - // this.layouts.push( - // { i: layout.i as string, x: layout.x as number, y: layout.y as number, w: layout.w as number, h: layout.h as number } - // ); - // } - // else { - // layout.then((layout: Doc) => { - // this.layouts.push( - // { i: layout.i as string, x: layout.x as number, y: layout.y as number, w: layout.w as number, h: layout.h as number } - // ); - // console.log(layout.i); - // }); - // } - // } - // } - for (const layout of DocListCast(this.props.Document.gridLayouts)) { - this.layouts.push( - { i: layout.i as string, x: layout.x as number, y: layout.y as number, w: layout.w as number, h: layout.h as number } - ); - } - } - else { - for (let i = 0; i < this.childLayoutPairs.length; i++) { - this.layouts.push( - { i: 'wrapper' + i, x: 2 * (i % 5), y: 2 * Math.floor(i / 5), w: 2, h: 2 } - ); - - const layoutDoc: Doc = new Doc(); - layoutDoc.i = "wrapper" + i; - layoutDoc.x = 2 * (i % 5); - layoutDoc.y = 2 * Math.floor(i / 5); - layoutDoc.w = 2; - layoutDoc.h = 2; - - this.layoutDocs.push(layoutDoc); - this.props.Document.highest = i; - } - this.props.Document.gridLayouts = new List(this.layoutDocs); - } - } + // _.reject() on item removal? - return this.layouts; - } + /** + * @returns a list of `ContentFittingDocumentView`s inside wrapper divs. + * The key of the wrapper div must be the same as the `i` value of the corresponding layout. + */ @computed - private get contents(): [JSX.Element[], Layout[]] { + private get contents(): JSX.Element[] { const { childLayoutPairs } = this; const collector: JSX.Element[] = []; - const layoutArray: Layout[] = []; + //const layoutArray: Layout[] = []; + const docList: Doc[] = DocListCast(this.props.Document.gridLayouts); - const previousLength = this.layout.length; - layoutArray.push(...this.layout); + const previousLength = docList.length; + // layoutArray.push(...this.layout); - if (!layoutArray.length) { - return [[], []]; - } - - if (this.childLayoutPairs.length > previousLength) { - layoutArray.push( - { i: 'wrapper' + previousLength, x: 2 * (previousLength % 5), y: 2 * Math.floor(previousLength / 5), w: 2, h: 2 } - // add values to document - ); - // this.layout.push( - // { i: 'wrapper' + previousLength, x: 2 * (previousLength % 5), y: 2 * Math.floor(previousLength / 5), w: 2, h: 2 } - // ); + if (!previousLength) { + // console.log("early return"); + return []; } for (let i = 0; i < childLayoutPairs.length; i++) { const { layout } = childLayoutPairs[i]; - const dxf = () => this.lookupIndividualTransform(layoutArray[i]);//.translate(-NumCast(Document._xMargin), -NumCast(Document._yMargin)); - const width = () => this.width(layoutArray[i]); //this.lookupPixels(layout); - const height = () => this.height(layoutArray[i]);//PanelHeight() - 2 * NumCast(Document._yMargin) - (BoolCast(Document.showWidthLabels) ? 20 : 0); + const dxf = () => this.lookupIndividualTransform(docList?.[i]); + const width = () => this.width(docList?.[i]); + const height = () => this.height(docList?.[i]); collector.push(
{this.getDisplayDoc(layout, dxf, width, height)}
); } - return [collector, layoutArray]; + return collector; + } + + /** + * @returns a list of Layouts from a list of Docs + * @param docLayoutList `Doc[]` + */ + toLayoutList(docLayoutList: Doc[]): Layout[] { + + const layouts: Layout[] = []; + for (const layout of docLayoutList) { + layouts.push( + { i: layout.i as string, x: layout.x as number, y: layout.y as number, w: layout.w as number, h: layout.h as number } + ); + } + return layouts; + } + + /** + * Checks whether a new node has been added to the grid and updates the Document accordingly. + */ + checkUpdate() { + const previousLength = (this.props.Document.gridLayouts as List)?.length; + if (this.childLayoutPairs.length > previousLength) { + console.log("adding doc"); + const layoutDoc: Doc = new Doc(); + layoutDoc.i = layoutDoc[Id]; + layoutDoc.x = 2 * (previousLength % 5); + layoutDoc.y = 2 * Math.floor(previousLength / 5); + layoutDoc.w = 2; + layoutDoc.h = 2; + + (this.props.Document.gridLayouts as List).push(layoutDoc); + } } render(): JSX.Element { - const contents: JSX.Element[] = this.contents?.[0]; - const layout: Layout[] = this.contents?.[1]; - // if (this.isMounted) { + this.checkUpdate(); + + const contents: JSX.Element[] = this.contents; + const layout: Layout[] = this.toLayoutList(DocListCast(this.props.Document.gridLayouts)); + + if (layout.length === 0) { + console.log("layouts not loaded"); + } + else { + console.log("rendering with this"); + console.log(layout[0].w); + } + + return (
- + }} + ref={this.createDashEventsTarget} + onPointerDown={(e: React.PointerEvent) => e.stopPropagation()} + >
); - // } } } diff --git a/src/client/views/collections/collectionGrid/Grid.tsx b/src/client/views/collections/collectionGrid/Grid.tsx index ce0173e94..d400f2810 100644 --- a/src/client/views/collections/collectionGrid/Grid.tsx +++ b/src/client/views/collections/collectionGrid/Grid.tsx @@ -20,9 +20,16 @@ interface GridProps { rowHeight: number; } +/** + * Wrapper around the actual GridLayout of `react-grid-layout`. + */ @observer export default class Grid extends React.Component { + /** + * If there has been a change in layout, calls a method in CollectionGridView to set the layouts on the Document. + * @param layout `Layout[]` + */ onLayoutChange(layout: Layout[]) { this.props.gridView.layout = layout; } @@ -36,6 +43,7 @@ export default class Grid extends React.Component this.onLayoutChange(layout)} > {this.props.nodeList} diff --git a/src/client/views/nodes/ContentFittingDocumentView.tsx b/src/client/views/nodes/ContentFittingDocumentView.tsx index 39097865a..77555061f 100644 --- a/src/client/views/nodes/ContentFittingDocumentView.tsx +++ b/src/client/views/nodes/ContentFittingDocumentView.tsx @@ -83,7 +83,7 @@ export class ContentFittingDocumentView extends React.Component 0.001 ? "auto" : this.props.PanelWidth(), height: Math.abs(this.centeringOffset) > 0.0001 ? "auto" : this.props.PanelHeight(), - display: this.props.Display /* just added for grid */ + display: this.props.display /* just added for grid */ }}> {!this.props.Document || !this.props.PanelWidth ? (null) : (
Date: Thu, 11 Jun 2020 00:10:31 +0530 Subject: added customisability for default W, H, margin + added context menu display option + added lock in position functionality --- .../collectionGrid/CollectionGridView.tsx | 131 +++++++++++---------- .../views/collections/collectionGrid/Grid.tsx | 2 + .../views/nodes/ContentFittingDocumentView.tsx | 4 +- 3 files changed, 73 insertions(+), 64 deletions(-) (limited to 'src/client/views/nodes/ContentFittingDocumentView.tsx') diff --git a/src/client/views/collections/collectionGrid/CollectionGridView.tsx b/src/client/views/collections/collectionGrid/CollectionGridView.tsx index 01ad44a2d..d68277d32 100644 --- a/src/client/views/collections/collectionGrid/CollectionGridView.tsx +++ b/src/client/views/collections/collectionGrid/CollectionGridView.tsx @@ -1,4 +1,4 @@ -import { computed, observable, Lambda, action, autorun } from 'mobx'; +import { computed, observable, Lambda, action, reaction } from 'mobx'; import * as React from "react"; import { Doc, Opt } from '../../../../fields/Doc'; import { documentSchema } from '../../../../fields/documentSchemas'; @@ -9,7 +9,7 @@ import { undoBatch } from '../../../util/UndoManager'; import { ContentFittingDocumentView } from '../../nodes/ContentFittingDocumentView'; import { CollectionSubView } from '../CollectionSubView'; import { SubCollectionViewProps } from '../CollectionSubView'; -import { returnZero, returnFalse } from '../../../../Utils'; +import { returnZero } from '../../../../Utils'; import Grid, { Layout } from "./Grid"; import { Id } from '../../../../fields/FieldSymbols'; import { observer } from 'mobx-react'; @@ -18,7 +18,8 @@ import { Docs } from '../../../documents/Documents'; import { EditableView, EditableProps } from '../../EditableView'; import "./CollectionGridView.scss"; import { ContextMenu } from '../../ContextMenu'; -import { ScriptField } from '../../../../fields/ScriptField'; +import { List } from '../../../../fields/List'; +import { ContextMenuProps } from '../../ContextMenuItem'; type GridSchema = makeInterface<[typeof documentSchema]>; @@ -48,8 +49,16 @@ export class CollectionGridView extends CollectionSubView(GridSchema) { // determines whether nodes should move out of the way (i.e. collide) when other nodes are dragged over them this.props.Document.preventCollision = BoolCast(this.props.Document.preventCollision, false); + this.props.Document.defaultW = NumCast(this.props.Document.defaultW, 2); + this.props.Document.defaultH = NumCast(this.props.Document.defaultH, 2); + + this.props.Document.margin = NumCast(this.props.Document.margin, 10); + + this.props.Document.display = StrCast(this.props.Document.display, "contents"); + this.setLayout = this.setLayout.bind(this); this.onSliderChange = this.onSliderChange.bind(this); + this.onContextMenu = this.onContextMenu.bind(this); this.containerRef = React.createRef(); } @@ -65,6 +74,7 @@ export class CollectionGridView extends CollectionSubView(GridSchema) { // if grid view has been opened and then exited and a document has been deleted // this deletes the layout of that document from the layouts list + if (!oldValue && newValue.length) { layouts.forEach(({ i }, index) => { const targetId = i; @@ -76,16 +86,15 @@ export class CollectionGridView extends CollectionSubView(GridSchema) { if (!oldValue || newValue.length > oldValue.length) { // for each document that was added, add a corresponding grid layout object - newValue.forEach(({ layout }, i) => { const targetId = layout[Id]; if (!layouts.find((gridLayout: Layout) => gridLayout.i === targetId)) { layouts.push({ i: targetId, - w: 2, - h: 2, - x: 2 * (i % Math.floor(NumCast(this.props.Document.numCols) / 2)), - y: 2 * Math.floor(i / Math.floor(NumCast(this.props.Document.numCols) / 2)), + w: this.defaultW, + h: this.defaultH, + x: this.defaultW * (i % Math.floor(NumCast(this.props.Document.numCols) / this.defaultW)), + y: this.defaultH * Math.floor(i / Math.floor(NumCast(this.props.Document.numCols) / this.defaultH)), static: !this.props.Document.flexGrid }); } @@ -104,24 +113,19 @@ export class CollectionGridView extends CollectionSubView(GridSchema) { }, true); // updates the layouts if the reset button has been clicked - this.resetListenerDisposer = autorun(() => { - if (this.props.Document.resetLayout) { - if (this.props.Document.flexGrid) { - console.log("Resetting layout"); - const layouts: Layout[] = this.parsedLayoutList; - - this.setLayout( - layouts.map(({ i }, index) => ({ - i: i, - x: 2 * (index % Math.floor(NumCast(this.props.Document.numCols) / 2)), - y: 2 * Math.floor(index / Math.floor(NumCast(this.props.Document.numCols) / 2)), - w: 2, - h: 2, - }))); - } - - this.props.Document.resetLayout = false; + this.resetListenerDisposer = reaction(() => this.props.Document.resetLayout, () => { + if (this.props.Document.flexGrid) { + const layouts: Layout[] = this.parsedLayoutList; + this.setLayout( + layouts.map(({ i }, index) => ({ + i: i, + x: this.defaultW * (index % Math.floor(NumCast(this.props.Document.numCols) / this.defaultW)), + y: this.defaultH * Math.floor(index / Math.floor(NumCast(this.props.Document.numCols) / this.defaultH)), + w: this.defaultW, + h: this.defaultH, + }))); } + this.props.Document.resetLayout = false; }); } @@ -142,16 +146,28 @@ export class CollectionGridView extends CollectionSubView(GridSchema) { const index = this.childLayoutPairs.findIndex(({ layout: layoutDoc }) => layoutDoc[Id] === layout.i); // translations depend on whether the grid is flexible or static - const yTranslation = (this.props.Document.flexGrid ? NumCast(layout.y) : 2 * Math.floor(index / Math.floor(NumCast(this.props.Document.numCols) / 2))) * this.rowHeightPlusGap + 10 - this._scroll + 30; // 30 is the height of the add text doc bar - const xTranslation = (this.props.Document.flexGrid ? NumCast(layout.x) : 2 * (index % Math.floor(NumCast(this.props.Document.numCols) / 2))) * this.colWidthPlusGap + 10; + const xTranslation = (this.props.Document.flexGrid ? NumCast(layout.x) : this.defaultW * (index % Math.floor(NumCast(this.props.Document.numCols) / this.defaultW))) * this.colWidthPlusGap + this.margin; + const yTranslation = (this.props.Document.flexGrid ? NumCast(layout.y) : this.defaultH * Math.floor(index / Math.floor(NumCast(this.props.Document.numCols) / this.defaultH))) * this.rowHeightPlusGap + this.margin - this._scroll + 30; // 30 is the height of the add text doc bar return this.props.ScreenToLocalTransform().translate(-xTranslation, -yTranslation); } - // is this needed? it seems to never be called + @computed get onChildClickHandler() { return ScriptCast(this.Document.onChildClick); } - @computed get colWidthPlusGap() { return (this.props.PanelWidth() - 10) / NumCast(this.props.Document.numCols); } - @computed get rowHeightPlusGap() { return NumCast(this.props.Document.rowHeight) + 10; } + addDocTab = (doc: Doc, where: string) => { + if (where === "inPlace" && this.layoutDoc.isInPlaceContainer) { + this.dataDoc[this.props.fieldKey] = new List([doc]); + return true; + } + return this.props.addDocTab(doc, where); + } + + @computed get colWidthPlusGap() { return (this.props.PanelWidth() - this.margin) / NumCast(this.props.Document.numCols); } + @computed get rowHeightPlusGap() { return NumCast(this.props.Document.rowHeight) + this.margin; } + + @computed get margin() { return NumCast(this.props.Document.margin); } + @computed get defaultW() { return NumCast(this.props.Document.defaultW); } + @computed get defaultH() { return NumCast(this.props.Document.defaultH); } /** * @returns the layout list converted from JSON @@ -169,9 +185,10 @@ export class CollectionGridView extends CollectionSubView(GridSchema) { // sometimes there are issues with rendering when you switch from a different view // where the nodes are all squeezed together on the left hand side of the screen // until you click on the screen or close the chrome or interact with it in some way + // the component doesn't rerender when the component mounts // this seems to fix that though it isn't very elegant - console.log("setting unstringified") + console.log("setting unstringified"); this.mounted && (this.props.Document.gridLayoutString = ""); this.props.Document.gridLayoutString = JSON.stringify(layouts); this.mounted = false; @@ -182,31 +199,13 @@ export class CollectionGridView extends CollectionSubView(GridSchema) { * Sets the width of the decorating box. * @param layout */ - @observable private width = (layout: Layout) => (this.props.Document.flexGrid ? layout.w : 2) * this.colWidthPlusGap - 10; + @observable private width = (layout: Layout) => (this.props.Document.flexGrid ? layout.w : this.defaultW) * this.colWidthPlusGap - this.margin; /** * Sets the height of the decorating box. * @param layout */ - @observable private height = (layout: Layout) => (this.props.Document.flexGrid ? layout.h : 2) * this.rowHeightPlusGap - 10; - - contextMenuItems = (layoutDoc: Doc) => { - const layouts: Layout[] = this.parsedLayoutList; - const freezeScript = ScriptField.MakeFunction( - // "layouts.find(({ i }) => i === layoutDoc[Id]).static=true;" + - // "this.unStringifiedLayoutList = layouts;" + - "console.log(doc)", { doc: Doc.name } - ); - - // const layouts: Layout[] = this.parsedLayoutList; - - // const layoutToChange = layouts.find(({ i }) => i === layoutDoc[Id]); - // layoutToChange!.static = !layoutToChange!.static; - - // this.unStringifiedLayoutList = layouts; - - return [{ script: freezeScript!, label: "testing" }]; - } + @observable private height = (layout: Layout) => (this.props.Document.flexGrid ? layout.h : this.defaultH) * this.rowHeightPlusGap - this.margin; /** * @@ -223,7 +222,7 @@ export class CollectionGridView extends CollectionSubView(GridSchema) { DataDoc={layout.resolvedDataDoc as Doc} NativeHeight={returnZero} NativeWidth={returnZero} - addDocTab={returnFalse} + addDocTab={this.addDocTab} backgroundColor={this.props.backgroundColor} ContainingCollectionDoc={this.props.Document} PanelWidth={width} @@ -232,8 +231,7 @@ export class CollectionGridView extends CollectionSubView(GridSchema) { onClick={this.onChildClickHandler} renderDepth={this.props.renderDepth + 1} parentActive={this.props.active} - display={"contents"} - contextMenuItems={() => this.contextMenuItems(layout)} + display={StrCast(this.props.Document.display)} />; } @@ -292,7 +290,6 @@ export class CollectionGridView extends CollectionSubView(GridSchema) { collector.push(
ContextMenu.Instance.addItem({ description: "test", event: () => console.log("test"), icon: "rainbow" })} > {this.getDisplayDoc(layout, dxf, width, height)}
@@ -310,21 +307,22 @@ export class CollectionGridView extends CollectionSubView(GridSchema) { console.log("getting layoutlist"); const layouts: Layout[] = this.parsedLayoutList; + return this.props.Document.flexGrid ? - layouts.map(({ i, x, y, w, h, static: staticVal }) => ({ + layouts.map(({ i, x, y, w, h }) => ({ i: i, x: x + w > NumCast(this.props.Document.numCols) ? 0 : x, // handles wrapping around of nodes when numCols decreases y: y, w: w > NumCast(this.props.Document.numCols) ? NumCast(this.props.Document.numCols) : w, // reduces width if greater than numCols h: h, - static: staticVal // only needed if we implement freeze in place + static: BoolCast(this.childLayoutPairs.find(({ layout }) => layout[Id] === i)?.layout.lockedPosition, false) // checks if the lock position item has been selected in the context menu })) : layouts.map(({ i }, index) => ({ i: i, - x: 2 * (index % Math.floor(NumCast(this.props.Document.numCols) / 2)), - y: 2 * Math.floor(index / Math.floor(NumCast(this.props.Document.numCols) / 2)), - w: 2, - h: 2, + x: this.defaultW * (index % Math.floor(NumCast(this.props.Document.numCols) / this.defaultW)), + y: this.defaultH * Math.floor(index / Math.floor(NumCast(this.props.Document.numCols) / this.defaultH)), + w: this.defaultW, + h: this.defaultH, static: true })); } @@ -357,6 +355,14 @@ export class CollectionGridView extends CollectionSubView(GridSchema) { */ @undoBatch @action addTextDocument = (value: string) => this.props.addDocument(Docs.Create.TextDocument(value, { title: value })); + onContextMenu = () => { + const displayOptionsMenu: ContextMenuProps[] = []; + displayOptionsMenu.push({ description: "Contents", event: () => this.props.Document.display = "contents", icon: "copy" }); + displayOptionsMenu.push({ description: "Undefined", event: () => this.props.Document.display = undefined, icon: "exclamation" }); + + ContextMenu.Instance.addItem({ description: "Display", subitems: displayOptionsMenu, icon: "tv" }); + } + render() { console.log("and render"); @@ -376,7 +382,7 @@ export class CollectionGridView extends CollectionSubView(GridSchema) { style={{ pointerEvents: !this.props.active() && !SnappingManager.GetIsDragging() ? "none" : undefined }} - // onContextMenu={() => ContextMenu.Instance.addItem({ description: "test", event: () => console.log("test"), icon: "rainbow" })} + onContextMenu={this.onContextMenu} ref={this.createDashEventsTarget} onPointerDown={e => { if (this.props.active(true)) { @@ -417,6 +423,7 @@ export class CollectionGridView extends CollectionSubView(GridSchema) { transformScale={this.props.ScreenToLocalTransform().Scale} compactType={StrCast(this.props.Document.compactType)} preventCollision={BoolCast(this.props.Document.preventCollision)} + margin={this.margin} />
diff --git a/src/client/views/collections/collectionGrid/Grid.tsx b/src/client/views/collections/collectionGrid/Grid.tsx index 9192a38d7..529e7762f 100644 --- a/src/client/views/collections/collectionGrid/Grid.tsx +++ b/src/client/views/collections/collectionGrid/Grid.tsx @@ -21,6 +21,7 @@ interface GridProps { childrenDraggable: boolean; preventCollision: boolean; compactType: string; + margin: number; } /** @@ -47,6 +48,7 @@ export default class Grid extends React.Component { preventCollision={this.props.preventCollision} transformScale={1 / this.props.transformScale} // still doesn't work :( style={{ zIndex: 5 }} + margin={[this.props.margin, this.props.margin]} > {this.props.nodeList} diff --git a/src/client/views/nodes/ContentFittingDocumentView.tsx b/src/client/views/nodes/ContentFittingDocumentView.tsx index 77555061f..d9e7d072f 100644 --- a/src/client/views/nodes/ContentFittingDocumentView.tsx +++ b/src/client/views/nodes/ContentFittingDocumentView.tsx @@ -73,8 +73,8 @@ export class ContentFittingDocumentView extends React.Component this.props.ScreenToLocalTransform().translate(-this.centeringOffset, -this.centeringYOffset).scale(1 / this.contentScaling()); - private get centeringOffset() { return this.nativeWidth() && !this.props.Document._fitWidth ? (this.props.PanelWidth() - this.nativeWidth() * this.contentScaling()) / 2 : 0; } - private get centeringYOffset() { return Math.abs(this.centeringOffset) < 0.001 ? (this.props.PanelHeight() - this.nativeHeight() * this.contentScaling()) / 2 : 0; } + private get centeringOffset() { return this.nativeWidth() && !this.props.Document._fitWidth && this.props.display !== "contents" ? (this.props.PanelWidth() - this.nativeWidth() * this.contentScaling()) / 2 : 0; } + private get centeringYOffset() { return Math.abs(this.centeringOffset) < 0.001 && this.props.display !== "contents" ? (this.props.PanelHeight() - this.nativeHeight() * this.contentScaling()) / 2 : 0; } @computed get borderRounding() { return StrCast(this.props.Document?.borderRounding); } -- cgit v1.2.3-70-g09d2