From f86a5e2ad2d0a57e77bd5f43d109faff5cc50bda Mon Sep 17 00:00:00 2001 From: usodhi <61431818+usodhi@users.noreply.github.com> Date: Tue, 21 Apr 2020 16:26:31 +0530 Subject: re-setup of grid view --- src/client/views/collections/CollectionView.tsx | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'src/client/views/collections/CollectionView.tsx') diff --git a/src/client/views/collections/CollectionView.tsx b/src/client/views/collections/CollectionView.tsx index 877e4355f..bedc928ad 100644 --- a/src/client/views/collections/CollectionView.tsx +++ b/src/client/views/collections/CollectionView.tsx @@ -46,6 +46,7 @@ import { InteractionUtils } from '../../util/InteractionUtils'; import { ObjectField } from '../../../new_fields/ObjectField'; import CollectionMapView from './CollectionMapView'; import { Transform } from 'prosemirror-transform'; +import { CollectionGridView } from './collectionGrid/CollectionGridView'; const higflyout = require("@hig/flyout"); export const { anchorPoints } = higflyout; export const Flyout = higflyout.default; @@ -67,7 +68,8 @@ export enum CollectionViewType { Carousel = "carousel", Linear = "linear", Staff = "staff", - Map = "map" + Map = "map", + Grid = "grid" } export interface CollectionRenderProps { @@ -174,6 +176,7 @@ export class CollectionView extends Touchable { case CollectionViewType.Masonry: { this.props.Document.singleColumn = false; return (); } case CollectionViewType.Time: { return (); } case CollectionViewType.Map: return (); + case CollectionViewType.Grid: return (); case CollectionViewType.Freeform: default: { this.props.Document._freeformLayoutEngine = undefined; return (); } } @@ -216,6 +219,7 @@ export class CollectionView extends Touchable { subItems.push({ description: "Carousel", event: () => this.props.Document._viewType = CollectionViewType.Carousel, icon: "columns" }); subItems.push({ description: "Pivot/Time", event: () => this.props.Document._viewType = CollectionViewType.Time, icon: "columns" }); subItems.push({ description: "Map", event: () => this.props.Document._viewType = CollectionViewType.Map, icon: "globe-americas" }); + subItems.push({ description: "Grid", event: () => this.props.Document._viewType = CollectionViewType.Grid, icon: "rainbow" }); switch (this.props.Document._viewType) { case CollectionViewType.Freeform: { subItems.push({ description: "Custom", icon: "fingerprint", event: AddCustomFreeFormLayout(this.props.Document, this.props.fieldKey) }); -- cgit v1.2.3-70-g09d2 From 83d282a6b5e607e3c7dae4b5e5d37a8b458f81cc Mon Sep 17 00:00:00 2001 From: usodhi <61431818+usodhi@users.noreply.github.com> 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/collections/CollectionView.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: Wed, 27 May 2020 10:31:31 -0400 Subject: fixed doc decorations and sizing of grid view docs. --- src/client/views/collections/CollectionView.tsx | 2 +- .../collectionGrid/CollectionGridView.tsx | 52 +++++++++++----------- 2 files changed, 28 insertions(+), 26 deletions(-) (limited to 'src/client/views/collections/CollectionView.tsx') diff --git a/src/client/views/collections/CollectionView.tsx b/src/client/views/collections/CollectionView.tsx index d1fbb445d..1beddfba9 100644 --- a/src/client/views/collections/CollectionView.tsx +++ b/src/client/views/collections/CollectionView.tsx @@ -92,7 +92,7 @@ export interface CollectionRenderProps { export class CollectionView extends Touchable { public static LayoutString(fieldStr: string) { return FieldView.LayoutString(CollectionView, fieldStr); } - private _isChildActive = false; //TODO should this be observable? + _isChildActive = false; //TODO should this be observable? get _isLightboxOpen() { return BoolCast(this.props.Document.isLightboxOpen); } set _isLightboxOpen(value) { this.props.Document.isLightboxOpen = value; } @observable private _curLightboxImg = 0; diff --git a/src/client/views/collections/collectionGrid/CollectionGridView.tsx b/src/client/views/collections/collectionGrid/CollectionGridView.tsx index 4986353ba..bc554e2c2 100644 --- a/src/client/views/collections/collectionGrid/CollectionGridView.tsx +++ b/src/client/views/collections/collectionGrid/CollectionGridView.tsx @@ -63,11 +63,13 @@ export class CollectionGridView extends CollectionSubView(GridSchema) { * documents before the target. */ private lookupIndividualTransform = (doc: Doc) => { - - 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); + const yTranslation = this.rowHeightPlusGap * NumCast(doc.y) + 10; + const xTranslation = this.colWidthPlusGap * NumCast(doc.x) + 10; + return this.props.ScreenToLocalTransform().translate(-xTranslation, -yTranslation); } + @computed get colWidthPlusGap() { return (this.props.PanelWidth() - 10) / NumCast(this.props.Document.numCols); } + @computed get rowHeightPlusGap() { return NumCast(this.props.Document.rowHeight) + 10; } @computed get onChildClickHandler() { return ScriptCast(this.Document.onChildClick); } @@ -75,13 +77,13 @@ export class CollectionGridView extends CollectionSubView(GridSchema) { * 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); + @observable private width = (doc: Doc) => NumCast(doc.w) * this.colWidthPlusGap - 10; /** * 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); + @observable private height = (doc: Doc) => NumCast(doc.h) * this.rowHeightPlusGap - 10; addDocTab = (doc: Doc, where: string) => { if (where === "inPlace" && this.layoutDoc.isInPlaceContainer) { @@ -92,25 +94,25 @@ export class CollectionGridView extends CollectionSubView(GridSchema) { } getDisplayDoc(layout: Doc, dxf: () => Transform, width: () => number, height: () => number) { - return ; + return
+ +
; } @@ -238,7 +240,7 @@ export class CollectionGridView extends CollectionSubView(GridSchema) { 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), - pointerEvents: !this.props.isSelected() && !SnappingManager.GetIsDragging() ? "none" : undefined + pointerEvents: !this.props.isSelected() && !this.props.ContainingCollectionView?._isChildActive && !SnappingManager.GetIsDragging() ? "none" : undefined }} ref={this.createDashEventsTarget} onPointerDown={e => e.stopPropagation()} -- cgit v1.2.3-70-g09d2 From 4cdd53c1208cd17593e0ecdb34e89265760a6512 Mon Sep 17 00:00:00 2001 From: usodhi <61431818+usodhi@users.noreply.github.com> Date: Thu, 4 Jun 2020 12:46:51 +0530 Subject: added numcols buttons to chrome + fixed some chrome css + added rowheight slider + rowheight slider css + fixed bug on document delete in freeform and reenter grid --- package-lock.json | 84 +++++++++++++--------- src/client/views/collections/CollectionView.tsx | 2 +- .../views/collections/CollectionViewChromes.scss | 7 ++ .../views/collections/CollectionViewChromes.tsx | 52 +++++++++++--- .../collectionGrid/CollectionGridView.scss | 47 ++++++++++-- .../collectionGrid/CollectionGridView.tsx | 72 +++++++++---------- .../views/collections/collectionGrid/Grid.tsx | 9 ++- 7 files changed, 180 insertions(+), 93 deletions(-) (limited to 'src/client/views/collections/CollectionView.tsx') diff --git a/package-lock.json b/package-lock.json index adf71ee58..14b279ef6 100644 --- a/package-lock.json +++ b/package-lock.json @@ -2836,7 +2836,8 @@ }, "ansi-regex": { "version": "2.1.1", - "bundled": true + "bundled": true, + "optional": true }, "aproba": { "version": "1.2.0", @@ -2854,11 +2855,13 @@ }, "balanced-match": { "version": "1.0.0", - "bundled": true + "bundled": true, + "optional": true }, "brace-expansion": { "version": "1.1.11", "bundled": true, + "optional": true, "requires": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" @@ -2871,15 +2874,18 @@ }, "code-point-at": { "version": "1.1.0", - "bundled": true + "bundled": true, + "optional": true }, "concat-map": { "version": "0.0.1", - "bundled": true + "bundled": true, + "optional": true }, "console-control-strings": { "version": "1.1.0", - "bundled": true + "bundled": true, + "optional": true }, "core-util-is": { "version": "1.0.2", @@ -2982,7 +2988,8 @@ }, "inherits": { "version": "2.0.4", - "bundled": true + "bundled": true, + "optional": true }, "ini": { "version": "1.3.5", @@ -2992,6 +2999,7 @@ "is-fullwidth-code-point": { "version": "1.0.0", "bundled": true, + "optional": true, "requires": { "number-is-nan": "^1.0.0" } @@ -3004,17 +3012,20 @@ "minimatch": { "version": "3.0.4", "bundled": true, + "optional": true, "requires": { "brace-expansion": "^1.1.7" } }, "minimist": { "version": "1.2.5", - "bundled": true + "bundled": true, + "optional": true }, "minipass": { "version": "2.9.0", "bundled": true, + "optional": true, "requires": { "safe-buffer": "^5.1.2", "yallist": "^3.0.0" @@ -3031,6 +3042,7 @@ "mkdirp": { "version": "0.5.3", "bundled": true, + "optional": true, "requires": { "minimist": "^1.2.5" } @@ -3086,7 +3098,8 @@ }, "npm-normalize-package-bin": { "version": "1.0.1", - "bundled": true + "bundled": true, + "optional": true }, "npm-packlist": { "version": "1.4.8", @@ -3111,7 +3124,8 @@ }, "number-is-nan": { "version": "1.0.1", - "bundled": true + "bundled": true, + "optional": true }, "object-assign": { "version": "4.1.1", @@ -3121,6 +3135,7 @@ "once": { "version": "1.4.0", "bundled": true, + "optional": true, "requires": { "wrappy": "1" } @@ -3189,7 +3204,8 @@ }, "safe-buffer": { "version": "5.1.2", - "bundled": true + "bundled": true, + "optional": true }, "safer-buffer": { "version": "2.1.2", @@ -3219,6 +3235,7 @@ "string-width": { "version": "1.0.2", "bundled": true, + "optional": true, "requires": { "code-point-at": "^1.0.0", "is-fullwidth-code-point": "^1.0.0", @@ -3236,6 +3253,7 @@ "strip-ansi": { "version": "3.0.1", "bundled": true, + "optional": true, "requires": { "ansi-regex": "^2.0.0" } @@ -3274,11 +3292,13 @@ }, "wrappy": { "version": "1.0.2", - "bundled": true + "bundled": true, + "optional": true }, "yallist": { "version": "3.1.1", - "bundled": true + "bundled": true, + "optional": true } } } @@ -9500,7 +9520,7 @@ }, "chownr": { "version": "1.1.4", - "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz", + "resolved": false, "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==" }, "ci-info": { @@ -9806,7 +9826,7 @@ }, "deep-extend": { "version": "0.6.0", - "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", + "resolved": false, "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==" }, "defaults": { @@ -10305,7 +10325,7 @@ }, "glob": { "version": "7.1.6", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", + "resolved": false, "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", "requires": { "fs.realpath": "^1.0.0", @@ -10393,7 +10413,7 @@ }, "hosted-git-info": { "version": "2.8.8", - "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.8.tgz", + "resolved": false, "integrity": "sha512-f/wzC2QaWBs7t9IYqB4T3sR1xviIViXJRJTWBlx2Gf3g0Xi5vI7Yy4koXQ1c9OYDGHN9sBy1DQ2AB8fqZBWhUg==" }, "http-cache-semantics": { @@ -10529,7 +10549,7 @@ }, "is-ci": { "version": "1.2.1", - "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-1.2.1.tgz", + "resolved": false, "integrity": "sha512-s6tfsaQaQi3JNciBH6shVqEDvhGut0SUXr31ag8Pd8BBbVVlcGfWhpPmEOoM6RJ5TFhbypvf5yyRw/VXW1IiWg==", "requires": { "ci-info": "^1.5.0" @@ -10605,7 +10625,7 @@ }, "is-retry-allowed": { "version": "1.2.0", - "resolved": "https://registry.npmjs.org/is-retry-allowed/-/is-retry-allowed-1.2.0.tgz", + "resolved": false, "integrity": "sha512-RUbUeKwvm3XG2VYamhJL1xFktgjvPzL0Hq8C+6yrWIswDy3BIXGqCxhxkc30N9jqK311gVU137K8Ei55/zVJRg==" }, "is-stream": { @@ -11114,7 +11134,7 @@ }, "mkdirp": { "version": "0.5.4", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.4.tgz", + "resolved": false, "integrity": "sha512-iG9AK/dJLtJ0XNgTuDbSyNS3zECqDlAhnQW4CsNxBG3LQJBbHmRX1egw39DmtOdCAqY+dKXV+sgPgilNWUKMVw==", "requires": { "minimist": "^1.2.5" @@ -11122,7 +11142,7 @@ "dependencies": { "minimist": { "version": "1.2.5", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", + "resolved": false, "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==" } } @@ -11174,7 +11194,7 @@ }, "node-gyp": { "version": "5.1.0", - "resolved": "https://registry.npmjs.org/node-gyp/-/node-gyp-5.1.0.tgz", + "resolved": false, "integrity": "sha512-OUTryc5bt/P8zVgNUmC6xdXiDJxLMAW8cF5tLQOT9E5sOQj+UeQxnnPy74K3CLCa/SOjjBlbuzDLR8ANwA+wmw==", "requires": { "env-paths": "^2.2.0", @@ -11288,7 +11308,7 @@ }, "npm-packlist": { "version": "1.4.8", - "resolved": "https://registry.npmjs.org/npm-packlist/-/npm-packlist-1.4.8.tgz", + "resolved": false, "integrity": "sha512-5+AZgwru5IevF5ZdnFglB5wNlHG1AOOuw28WhUq8/8emhBmLv6jX5by4WJCh7lW0uSYZYS6DXqIsyZVIXRZU9A==", "requires": { "ignore-walk": "^3.0.1", @@ -11308,7 +11328,7 @@ }, "npm-profile": { "version": "4.0.4", - "resolved": "https://registry.npmjs.org/npm-profile/-/npm-profile-4.0.4.tgz", + "resolved": false, "integrity": "sha512-Ta8xq8TLMpqssF0H60BXS1A90iMoM6GeKwsmravJ6wYjWwSzcYBTdyWa3DZCYqPutacBMEm7cxiOkiIeCUAHDQ==", "requires": { "aproba": "^1.1.2 || 2", @@ -11318,7 +11338,7 @@ }, "npm-registry-fetch": { "version": "4.0.3", - "resolved": "https://registry.npmjs.org/npm-registry-fetch/-/npm-registry-fetch-4.0.3.tgz", + "resolved": false, "integrity": "sha512-WGvUx0lkKFhu9MbiGFuT9nG2NpfQ+4dCJwRwwtK2HK5izJEvwDxMeUyqbuMS7N/OkpVCqDorV6rO5E4V9F8lJw==", "requires": { "JSONStream": "^1.3.4", @@ -11753,7 +11773,7 @@ }, "rc": { "version": "1.2.8", - "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", + "resolved": false, "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==", "requires": { "deep-extend": "^0.6.0", @@ -11764,7 +11784,7 @@ "dependencies": { "minimist": { "version": "1.2.5", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", + "resolved": false, "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==" } } @@ -11823,7 +11843,7 @@ }, "readable-stream": { "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", + "resolved": false, "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", "requires": { "inherits": "^2.0.3", @@ -11844,7 +11864,7 @@ }, "registry-auth-token": { "version": "3.4.0", - "resolved": "https://registry.npmjs.org/registry-auth-token/-/registry-auth-token-3.4.0.tgz", + "resolved": false, "integrity": "sha512-4LM6Fw8eBQdwMYcES4yTnn2TqIasbXuwDx3um+QRs7S55aMKCBKBxvPXl2RiUjHwuJLTyYfxSpmfSAjQpcuP+A==", "requires": { "rc": "^1.1.6", @@ -11908,7 +11928,7 @@ }, "rimraf": { "version": "2.7.1", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", + "resolved": false, "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", "requires": { "glob": "^7.1.3" @@ -12207,7 +12227,7 @@ }, "string_decoder": { "version": "1.3.0", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "resolved": false, "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", "requires": { "safe-buffer": "~5.2.0" @@ -12215,7 +12235,7 @@ "dependencies": { "safe-buffer": { "version": "5.2.0", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.0.tgz", + "resolved": false, "integrity": "sha512-fZEwUGbVl7kouZs1jCdMLdt95hdIv0ZeHg6L7qPeciMZhZ+/gdesW4wgTARkrFWEpspjEATAzUGPG8N2jJiwbg==" } } @@ -12527,7 +12547,7 @@ }, "widest-line": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/widest-line/-/widest-line-2.0.1.tgz", + "resolved": false, "integrity": "sha512-Ba5m9/Fa4Xt9eb2ELXt77JxVDV8w7qQrH0zS/TWSJdLyAwQjWoOzpzj5lwVftDz6n/EOu3tNACS84v509qwnJA==", "requires": { "string-width": "^2.1.1" diff --git a/src/client/views/collections/CollectionView.tsx b/src/client/views/collections/CollectionView.tsx index bcb190de4..df84cab56 100644 --- a/src/client/views/collections/CollectionView.tsx +++ b/src/client/views/collections/CollectionView.tsx @@ -232,7 +232,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" }); + subItems.push({ description: "Grid", event: () => func(CollectionViewType.Grid), icon: "th-list" }); 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 42ec35853..f6027471b 100644 --- a/src/client/views/collections/CollectionViewChromes.scss +++ b/src/client/views/collections/CollectionViewChromes.scss @@ -181,9 +181,16 @@ .grid-control { align-self: center; width: 30%; + display: flex; + flex-direction: row; .grid-icon { margin-right: 5px; + align-self: center; + } + + .flexLabel { + margin-bottom: 0; } } diff --git a/src/client/views/collections/CollectionViewChromes.tsx b/src/client/views/collections/CollectionViewChromes.tsx index 3d712e4f5..5a76a4605 100644 --- a/src/client/views/collections/CollectionViewChromes.tsx +++ b/src/client/views/collections/CollectionViewChromes.tsx @@ -93,7 +93,7 @@ export class CollectionViewBaseChrome extends React.Component { @@ -569,6 +569,9 @@ export class CollectionTreeViewChrome extends React.Component { + private clicked: boolean = false; + private entered: boolean = false; + /** * Sets the value of `numCols` on the grid's Document to the value entered. */ @@ -577,7 +580,6 @@ export class CollectionGridViewChrome extends React.Component 0 && 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 } } @@ -602,27 +604,59 @@ export class CollectionGridViewChrome extends React.Component { + this.clicked = true; + this.entered && (this.props.CollectionView.props.Document.numCols as number)--; + undoBatch(() => (this.props.CollectionView.props.Document.numCols as number)++)(); + this.entered = false; + } + + onDecrementButtonClick = () => { + this.clicked = true; + this.entered && (this.props.CollectionView.props.Document.numCols as number)++; + undoBatch(() => (this.props.CollectionView.props.Document.numCols as number)--)(); + this.entered = false; + } + + incrementValue = () => { + this.entered = true; + if (!this.clicked) { + (this.props.CollectionView.props.Document.numCols as number)++; + } + this.clicked = false; + } + + decrementValue = () => { + this.entered = true; + if (!this.clicked) { + (this.props.CollectionView.props.Document.numCols as number)--; + } + this.clicked = false; + } + render() { return ( -
- +
+ - ) => e.currentTarget.focus()} /> + ) => { e.stopPropagation(); e.preventDefault(); e.currentTarget.focus(); }} /> + + - + - ) => e.currentTarget.focus()} /> + ) => { e.stopPropagation(); e.preventDefault(); e.currentTarget.focus(); }} /> - + - +
); diff --git a/src/client/views/collections/collectionGrid/CollectionGridView.scss b/src/client/views/collections/collectionGrid/CollectionGridView.scss index 94b0d958c..e06e8dc90 100644 --- a/src/client/views/collections/collectionGrid/CollectionGridView.scss +++ b/src/client/views/collections/collectionGrid/CollectionGridView.scss @@ -9,6 +9,43 @@ height: 100%; overflow-y: auto; background-color: white; + overflow-x: hidden; + + display: flex; + flex-direction: row; + + .rowHeightSlider { + + -webkit-appearance: none; + appearance: none; + width: 100%; + height: 15px; + background: #d3d3d3; + // border-radius: 5px; + + position: absolute; + height: 3; + left: 5; + top: 40; + transform-origin: left; + transform: rotate(90deg); + outline: none; + opacity: 0.7; + } + + .rowHeightSlider:hover { + opacity: 1; + } + + .rowHeightSlider::-webkit-slider-thumb { + -webkit-appearance: none; + appearance: none; + width: 10px; + height: 10px; + border-radius: 50%; + background: darkgrey; + opacity: 1; + } } .collectionGridView-addDocumentButton { @@ -17,7 +54,8 @@ margin: auto; width: 90%; cursor: text; - + min-height: 30px; + max-height: 30px; font-size: 75%; letter-spacing: 2px; @@ -31,15 +69,14 @@ .editableView-container-editing, .editableView-container-editing-oneLine { - min-height: 20px; display: flex; align-items: center; flex-direction: row; - height: auto; + height: 20px; + width: 100%; color: grey; padding: 10px; - width: 100%; span::before, span::after { @@ -67,8 +104,6 @@ align-items: center; } } - - } } diff --git a/src/client/views/collections/collectionGrid/CollectionGridView.tsx b/src/client/views/collections/collectionGrid/CollectionGridView.tsx index c56d6ee53..68612c9dc 100644 --- a/src/client/views/collections/collectionGrid/CollectionGridView.tsx +++ b/src/client/views/collections/collectionGrid/CollectionGridView.tsx @@ -3,7 +3,7 @@ import * as React from "react"; import { Doc, Opt } from '../../../../fields/Doc'; import { documentSchema } from '../../../../fields/documentSchemas'; import { makeInterface } from '../../../../fields/Schema'; -import { BoolCast, NumCast, ScriptCast } from '../../../../fields/Types'; +import { BoolCast, NumCast, ScriptCast, StrCast } from '../../../../fields/Types'; import { Transform } from '../../../util/Transform'; import { undoBatch } from '../../../util/UndoManager'; import { ContentFittingDocumentView } from '../../nodes/ContentFittingDocumentView'; @@ -15,9 +15,9 @@ import Grid, { Layout } from "./Grid"; import { Id } from '../../../../fields/FieldSymbols'; import { observer } from 'mobx-react'; import { SnappingManager } from '../../../util/SnappingManager'; -import "./CollectionGridView.scss"; import { Docs } from '../../../documents/Documents'; import { EditableView, EditableProps } from '../../EditableView'; +import "./CollectionGridView.scss"; type GridSchema = makeInterface<[typeof documentSchema]>; @@ -37,28 +37,38 @@ export class CollectionGridView extends CollectionSubView(GridSchema) { this.props.Document.flexGrid = BoolCast(this.props.Document.flexGrid, true); this.setLayout = this.setLayout.bind(this); - // this.addTextDoc = this.addTextDoc.bind(this); + this.onSliderChange = this.onSliderChange.bind(this); this.containerRef = React.createRef(); } componentDidMount() { - this.changeListenerDisposer = computed(() => this.childLayoutPairs).observe(({ oldValue, newValue }) => { const layouts: Layout[] = this.parsedLayoutList; + + // 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) { + layouts.forEach(({ i }, index) => { + const targetId = i; + if (!newValue.find(({ layout: preserved }) => preserved[Id] === targetId)) { + layouts.splice(index, 1); + } + }); + } + if (!oldValue || newValue.length > oldValue.length) { // for each document that was added, add a corresponding grid layout document newValue.forEach(({ layout }, i) => { const targetId = layout[Id]; if (!layouts.find((gridLayout: Layout) => gridLayout.i === targetId)) { - console.log("pushing") layouts.push({ i: targetId, w: 2, h: 2, - x: 2 * (i % Math.floor(this.props.Document.numCols as number / 2)), - y: 2 * Math.floor(i / Math.floor(this.props.Document.numCols as number / 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)) }); } }); @@ -72,9 +82,7 @@ export class CollectionGridView extends CollectionSubView(GridSchema) { } }); } - this.unStringifiedLayoutList = layouts; - // this.props.Document.gridLayoutString = JSON.stringify(layouts); }, true); } @@ -82,23 +90,6 @@ export class CollectionGridView extends CollectionSubView(GridSchema) { this.changeListenerDisposer && this.changeListenerDisposer(); } - /** - * Establishes the x and y properties of the @param layoutDoc, currently - * using the @param previousLength for the computations. - * - * However, this could also be more of a first fit algorithm, iterating through - * this.toLayoutList(DocListCast(this.props.Document.gridLayouts)) and finding the - * first gap in the layout structure that suits the width and height. It would be - * easiest to see that a column is free (for a given row, if two documents' x are separated - * by a value greater than the ratio width of the document you're trying to insert), - * but you would then have to ensure that the next row at that column has a y at least - * as big as the ratio height of the document you're trying to insert. - */ - private findNextLayout(layoutDoc: Doc, previousLength: number) { - layoutDoc.x = 2 * (previousLength % Math.floor(this.props.Document.numCols as number / 2)); - layoutDoc.y = 2 * Math.floor(previousLength / Math.floor(this.props.Document.numCols as number / 2)); - } - /** * @returns the transform that will correctly place * the document decorations box, shifted to the right by @@ -108,8 +99,8 @@ export class CollectionGridView extends CollectionSubView(GridSchema) { private lookupIndividualTransform = (layout: Layout) => { const index = this.childLayoutPairs.findIndex(({ layout: layoutDoc }) => layoutDoc[Id] === layout.i); - const yTranslation = (this.props.Document.flexGrid ? NumCast(layout.y) : 2 * Math.floor(index / Math.floor(this.props.Document.numCols as number / 2))) * this.rowHeightPlusGap + 10 - this._scroll; - const xTranslation = (this.props.Document.flexGrid ? NumCast(layout.x) : 2 * (index % Math.floor(this.props.Document.numCols as number / 2))) * this.colWidthPlusGap + 10; + 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; return this.props.ScreenToLocalTransform().translate(-xTranslation, -yTranslation); } @@ -119,7 +110,7 @@ export class CollectionGridView extends CollectionSubView(GridSchema) { @computed get onChildClickHandler() { return ScriptCast(this.Document.onChildClick); } - get parsedLayoutList() { return this.props.Document.gridLayoutString ? JSON.parse(this.props.Document.gridLayoutString as string) : []; } + get parsedLayoutList() { return this.props.Document.gridLayoutString ? JSON.parse(StrCast(this.props.Document.gridLayoutString)) : []; } set unStringifiedLayoutList(layouts: Layout[]) { this.props.Document.gridLayoutString = JSON.stringify(layouts); } @@ -177,7 +168,6 @@ export class CollectionGridView extends CollectionSubView(GridSchema) { let update: Opt; const targetId = doc[Id]; const gridLayout = layouts.find(gridLayout => gridLayout.i === targetId); - // const gridLayout = DocListCast(this.props.Document.gridLayouts).find(gridLayout => StrCast(gridLayout.i) === targetId); if (this.props.Document.flexGrid && gridLayout && (update = layoutArray.find(layout => layout.i === targetId))) { gridLayout.x = update.x; gridLayout.y = update.y; @@ -186,7 +176,6 @@ export class CollectionGridView extends CollectionSubView(GridSchema) { } }); - // this.props.Document.gridLayoutString = JSON.stringify(layouts); this.unStringifiedLayoutList = layouts; } @@ -210,7 +199,7 @@ export class CollectionGridView extends CollectionSubView(GridSchema) { const width = () => this.width(gridLayout); const height = () => this.height(gridLayout); collector.push( -
{this.getDisplayDoc(layout, dxf, width, height)} @@ -231,14 +220,18 @@ export class CollectionGridView extends CollectionSubView(GridSchema) { return this.props.Document.flexGrid ? layouts : layouts.map(({ i }, index) => ({ i: i, - x: 2 * (index % Math.floor(this.props.Document.numCols as number / 2)), - y: 2 * Math.floor(index / Math.floor(this.props.Document.numCols as number / 2)), + 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, static: true })); } + onSliderChange = (event: React.ChangeEvent) => { + this.props.Document.rowHeight = event.currentTarget.valueAsNumber; + } + @undoBatch @action addTextDocument = (value: string) => this.props.addDocument(Docs.Create.TextDocument(value, { title: value })); /** @@ -254,14 +247,13 @@ export class CollectionGridView extends CollectionSubView(GridSchema) { const newEditableViewProps: EditableProps = { GetValue: () => "", SetValue: this.addTextDocument, - contents: "+ NEW", + contents: "+ ADD TEXT DOCUMENT AT END", }; const childDocumentViews: JSX.Element[] = this.contents; const chromeStatus = this.props.Document._chromeStatus; const showChrome = (chromeStatus !== 'view-mode' && chromeStatus !== 'disabled'); - return (
) => this._scroll = e.currentTarget.scrollTop)} > + e.currentTarget.focus()} /> this.setLayout(layout)} transformScale={this.props.ScreenToLocalTransform().Scale} - // flex={this.props.Document.flexGrid as boolean} /> +
); diff --git a/src/client/views/collections/collectionGrid/Grid.tsx b/src/client/views/collections/collectionGrid/Grid.tsx index cae06c4e7..29bafda9b 100644 --- a/src/client/views/collections/collectionGrid/Grid.tsx +++ b/src/client/views/collections/collectionGrid/Grid.tsx @@ -36,7 +36,6 @@ export default class Grid extends React.Component { * @param layout `Layout[]` */ onLayoutChange(layout: Layout[]) { - console.log("layout changed"); this.props.setLayout(layout); } @@ -50,12 +49,12 @@ export default class Grid extends React.Component { width={this.props.width} compactType={null} isDroppable={true} - // isDraggable={this.props.childrenDraggable} + isDraggable={this.props.childrenDraggable} + isResizable={this.props.childrenDraggable} useCSSTransforms={true} - margin={[10, 10]} onLayoutChange={this.onLayoutChange} - preventCollision={false} // change this to true later - // transformScale={2} // 1.2/scale + preventCollision={true} + transformScale={this.props.transformScale} style={{ zIndex: 5 }} > {this.props.nodeList} -- cgit v1.2.3-70-g09d2 From 78f70dbd2136aa8b7b05bacafc71a8a714462d29 Mon Sep 17 00:00:00 2001 From: usodhi <61431818+usodhi@users.noreply.github.com> Date: Thu, 4 Jun 2020 20:03:19 +0530 Subject: slider added + wheel propagation prevented + fixed bug in changeListenerDisposer --- src/client/views/collections/CollectionView.tsx | 2 +- .../collectionGrid/CollectionGridView.tsx | 55 ++++++++++++++++++---- .../views/collections/collectionGrid/Grid.tsx | 18 ++++++- 3 files changed, 63 insertions(+), 12 deletions(-) (limited to 'src/client/views/collections/CollectionView.tsx') diff --git a/src/client/views/collections/CollectionView.tsx b/src/client/views/collections/CollectionView.tsx index df84cab56..d6f729598 100644 --- a/src/client/views/collections/CollectionView.tsx +++ b/src/client/views/collections/CollectionView.tsx @@ -264,7 +264,7 @@ export class CollectionView extends Touchable this.props.Document._viewType = CollectionViewType.Carousel, icon: "columns" }); subItems.push({ description: "Pivot/Time", event: () => this.props.Document._viewType = CollectionViewType.Time, icon: "columns" }); subItems.push({ description: "Map", event: () => this.props.Document._viewType = CollectionViewType.Map, icon: "globe-americas" }); - subItems.push({ description: "Grid", event: () => this.props.Document._viewType = CollectionViewType.Grid, icon: "rainbow" }); + subItems.push({ description: "Grid", event: () => this.props.Document._viewType = CollectionViewType.Grid, icon: "th-list" }); switch (this.props.Document._viewType) { case CollectionViewType.Freeform: { subItems.push({ description: "Custom", icon: "fingerprint", event: AddCustomFreeFormLayout(this.props.Document, this.props.fieldKey) }); diff --git a/src/client/views/collections/collectionGrid/CollectionGridView.tsx b/src/client/views/collections/collectionGrid/CollectionGridView.tsx index 68612c9dc..dd4e28e33 100644 --- a/src/client/views/collections/collectionGrid/CollectionGridView.tsx +++ b/src/client/views/collections/collectionGrid/CollectionGridView.tsx @@ -28,6 +28,7 @@ export class CollectionGridView extends CollectionSubView(GridSchema) { private containerRef: React.RefObject; @observable private _scroll: number = 0; private changeListenerDisposer: Opt; + private rowHeight: number = 0; constructor(props: Readonly) { super(props); @@ -38,7 +39,7 @@ export class CollectionGridView extends CollectionSubView(GridSchema) { this.setLayout = this.setLayout.bind(this); this.onSliderChange = this.onSliderChange.bind(this); - + // this.deletePlaceholder = this.deletePlaceholder.bind(this); this.containerRef = React.createRef(); } @@ -49,7 +50,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) { + if (!oldValue && newValue.length) { layouts.forEach(({ i }, index) => { const targetId = i; if (!newValue.find(({ layout: preserved }) => preserved[Id] === targetId)) { @@ -88,8 +89,28 @@ export class CollectionGridView extends CollectionSubView(GridSchema) { componentWillUnmount() { this.changeListenerDisposer && this.changeListenerDisposer(); + console.log("unmounted") } + // deletePlaceholder(placeholder: Layout, e: MouseEvent) { + + // const { left, right, top, bottom } = this.containerRef.current!.getBoundingClientRect(); + // if (e.clientX > right || e.clientX < left || e.clientY < top || e.clientY > bottom) { + // const layouts: Layout[] = this.parsedLayoutList; + // const index = layouts.findIndex((gridLayout: Layout) => gridLayout.i === placeholder.i); + // index !== -1 && layouts.splice(index, 1); + + // const i = this.childLayoutPairs.findIndex(({ layout }) => placeholder.i === layout.i); + // i !== -1 && this.childLayoutPairs.splice(i, 1); + + // console.log("deleting"); + + // this.unStringifiedLayoutList = layouts; + // } + + // } + + /** * @returns the transform that will correctly place * the document decorations box, shifted to the right by @@ -232,6 +253,16 @@ export class CollectionGridView extends CollectionSubView(GridSchema) { this.props.Document.rowHeight = event.currentTarget.valueAsNumber; } + onSliderDown = () => { + this.rowHeight = NumCast(this.props.Document.rowHeight); + } + + onSliderUp = () => { + const tempVal = this.props.Document.rowHeight; + this.props.Document.rowHeight = this.rowHeight; + undoBatch(() => this.props.Document.rowHeight = tempVal)(); + } + @undoBatch @action addTextDocument = (value: string) => this.props.addDocument(Docs.Create.TextDocument(value, { title: value })); /** @@ -243,7 +274,6 @@ export class CollectionGridView extends CollectionSubView(GridSchema) { * the setLayout event, which makes these unintended changes permanent by writing them to the likely now resolved documents. */ render() { - const newEditableViewProps: EditableProps = { GetValue: () => "", SetValue: this.addTextDocument, @@ -257,8 +287,8 @@ export class CollectionGridView extends CollectionSubView(GridSchema) { return (
{showChrome ? @@ -280,9 +313,10 @@ export class CollectionGridView extends CollectionSubView(GridSchema) { }
) => this._scroll = e.currentTarget.scrollTop)} + onScroll={action(e => this._scroll = e.currentTarget.scrollTop)} + onWheel={e => e.stopPropagation()} > - e.currentTarget.focus()} /> + e.currentTarget.focus()} />
diff --git a/src/client/views/collections/collectionGrid/Grid.tsx b/src/client/views/collections/collectionGrid/Grid.tsx index 29bafda9b..df550e3c2 100644 --- a/src/client/views/collections/collectionGrid/Grid.tsx +++ b/src/client/views/collections/collectionGrid/Grid.tsx @@ -19,6 +19,7 @@ interface GridProps { setLayout: Function; transformScale: number; childrenDraggable: boolean; + // deletePlaceholder: Function; } /** @@ -27,9 +28,12 @@ interface GridProps { @observer export default class Grid extends React.Component { + // private dragging: boolean = false; + constructor(props: Readonly) { super(props); this.onLayoutChange = this.onLayoutChange.bind(this); + // this.onDrag = this.onDrag.bind(this); } /** * If there has been a change in layout, calls a method in CollectionGridView to set the layouts on the Document. @@ -39,8 +43,20 @@ export default class Grid extends React.Component { this.props.setLayout(layout); } + // onDrag(layout: Layout[], + // oldItem: Layout, + // newItem: Layout, + // placeholder: Layout, + // event: MouseEvent, + // element: HTMLElement) { + // this.props.deletePlaceholder(placeholder, event); + // console.log("Grid -> event", event.clientX) + + // } + render() { console.log(this.props.transformScale); + return ( { useCSSTransforms={true} onLayoutChange={this.onLayoutChange} preventCollision={true} - transformScale={this.props.transformScale} + transformScale={this.props.transformScale} // still doesn't work :( style={{ zIndex: 5 }} > {this.props.nodeList} -- cgit v1.2.3-70-g09d2 From 34d43b0d7ff1829514566e2b6b8514f6176e7c60 Mon Sep 17 00:00:00 2001 From: Bob Zeleznik Date: Tue, 9 Jun 2020 11:48:22 -0400 Subject: fixed keyFrame animation positioning issues when adding a doc at t != 0. added isInkMask field and inkStroke menu option to create an ink mask. added cantLeaveCollection flag. --- src/client/views/InkingStroke.tsx | 21 +++++++++++++++------ src/client/views/collections/CollectionSubView.tsx | 2 +- src/client/views/collections/CollectionView.tsx | 3 ++- .../collectionFreeForm/CollectionFreeFormView.tsx | 2 +- .../views/nodes/CollectionFreeFormDocumentView.tsx | 17 ++++++++--------- src/fields/documentSchemas.ts | 2 ++ 6 files changed, 29 insertions(+), 18 deletions(-) (limited to 'src/client/views/collections/CollectionView.tsx') diff --git a/src/client/views/InkingStroke.tsx b/src/client/views/InkingStroke.tsx index b545ede54..7dac2e3b5 100644 --- a/src/client/views/InkingStroke.tsx +++ b/src/client/views/InkingStroke.tsx @@ -31,6 +31,14 @@ export class InkingStroke extends ViewBoxBaseComponent { + this.props.Document._backgroundColor = "rgba(0,0,0,0.7)"; + this.props.Document.mixBlendMode = "hard-light"; + this.props.Document.color = "#9b9b9bff"; + this.props.Document.cantLeaveCollection = true; + this.props.Document.isInkMask = true; + } + render() { TraceMobx(); const data: InkData = Cast(this.dataDoc[this.fieldKey], InkField)?.inkData ?? []; @@ -52,13 +60,14 @@ export class InkingStroke extends ViewBoxBaseComponent { - ContextMenu.Instance.addItem({ - description: "Analyze Stroke", - event: this.analyzeStrokes, - icon: "paint-brush" - }); + ContextMenu.Instance.addItem({ description: "Analyze Stroke", event: this.analyzeStrokes, icon: "paint-brush" }); + ContextMenu.Instance.addItem({ description: "Make Mask", event: this.makeMask, icon: "paint-brush" }); }} > {points} diff --git a/src/client/views/collections/CollectionSubView.tsx b/src/client/views/collections/CollectionSubView.tsx index 167bce131..47d571bcc 100644 --- a/src/client/views/collections/CollectionSubView.tsx +++ b/src/client/views/collections/CollectionSubView.tsx @@ -221,7 +221,7 @@ export function CollectionSubView(schemaCtor: (doc: Doc) => T, moreProps?: } else { added = this.addDocument(docDragData.droppedDocuments); } - e.stopPropagation(); + added && e.stopPropagation(); return added; } else if (de.complete.annoDragData) { diff --git a/src/client/views/collections/CollectionView.tsx b/src/client/views/collections/CollectionView.tsx index 3330abbc4..7f2b5ff8e 100644 --- a/src/client/views/collections/CollectionView.tsx +++ b/src/client/views/collections/CollectionView.tsx @@ -163,7 +163,8 @@ export class CollectionView extends Touchable { diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx index 379156179..d512f815c 100644 --- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx +++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx @@ -202,7 +202,7 @@ export class CollectionFreeFormView extends CollectionSubView pair.layout).slice().sort((doc1, doc2) => NumCast(doc1.zIndex) - NumCast(doc2.zIndex)); - zsorted.forEach((doc, index) => doc.zIndex = index + 1); + zsorted.forEach((doc, index) => doc.zIndex = doc.isInkMask ? 5000 : index + 1); const dropPos = [NumCast(docDragData.droppedDocuments[0].x), NumCast(docDragData.droppedDocuments[0].y)]; for (let i = 0; i < docDragData.droppedDocuments.length; i++) { const d = docDragData.droppedDocuments[i]; diff --git a/src/client/views/nodes/CollectionFreeFormDocumentView.tsx b/src/client/views/nodes/CollectionFreeFormDocumentView.tsx index 910aa744d..77a2e04e6 100644 --- a/src/client/views/nodes/CollectionFreeFormDocumentView.tsx +++ b/src/client/views/nodes/CollectionFreeFormDocumentView.tsx @@ -36,7 +36,8 @@ export class CollectionFreeFormDocumentView extends DocComponent(numberRange(timecode + 1).map(i => undefined) as any as number[]); const ylist = new List(numberRange(timecode + 1).map(i => undefined) as any as number[]); const olist = new List(numberRange(timecode + 1).map(t => progressivize && t < i ? 0 : 1)); - xlist[Math.max(curTimecode - 1, 0)] = xlist[curTimecode] = NumCast(doc.x); - ylist[Math.max(curTimecode - 1, 0)] = ylist[curTimecode] = NumCast(doc.y); + xlist[curTimecode] = NumCast(doc.x); + ylist[curTimecode] = NumCast(doc.y); doc["x-indexed"] = xlist; doc["y-indexed"] = ylist; doc["opacity-indexed"] = olist; - doc.activeFrame = ComputedField.MakeFunction("self.context ? (self.context.currentFrame||0) : 0"); + doc.activeFrame = ComputedField.MakeFunction("self.context?.currentFrame||0"); doc.x = ComputedField.MakeInterpolated("x", "activeFrame"); doc.y = ComputedField.MakeInterpolated("y", "activeFrame"); doc.opacity = ComputedField.MakeInterpolated("opacity", "activeFrame"); @@ -151,12 +150,12 @@ export class CollectionFreeFormDocumentView extends DocComponent {Doc.UserDoc().renderStyle !== "comic" ? (null) :
diff --git a/src/fields/documentSchemas.ts b/src/fields/documentSchemas.ts index 6474ed148..353333028 100644 --- a/src/fields/documentSchemas.ts +++ b/src/fields/documentSchemas.ts @@ -58,6 +58,7 @@ export const documentSchema = createSchema({ color: "string", // foreground color of document fitToBox: "boolean", // whether freeform view contents should be zoomed/panned to fill the area of the document view fontSize: "string", + isInkMask: "boolean", // is the document a mask (ie, sits on top of other documents, has an unbounded width/height that is dark, and content uses 'hard-light' mix-blend-mode to let other documents pop through) layout: "string", // this is the native layout string for the document. templates can be added using other fields and setting layoutKey below layoutKey: "string", // holds the field key for the field that actually holds the current lyoat letterSpacing: "string", @@ -83,6 +84,7 @@ export const documentSchema = createSchema({ _lockedTransform: "boolean",// whether a freeformview can pan/zoom // drag drop properties + cantLeaveCollection: "boolean",// whether document can be dropped into a different collection dragFactory: Doc, // the document that serves as the "template" for the onDragStart script. ie, to drag out copies of the dragFactory document. dropAction: "string", // override specifying what should happen when this document is dropped (can be "alias", "copy", "move") targetDropAction: "string", // allows the target of a drop event to specify the dropAction ("alias", "copy", "move") NOTE: if the document is dropped within the same collection, the dropAction is coerced to 'move' -- cgit v1.2.3-70-g09d2 From dd2af3952a5b9e65ef3394b1f5604f0eace1e870 Mon Sep 17 00:00:00 2001 From: Bob Zeleznik Date: Tue, 9 Jun 2020 14:03:24 -0400 Subject: fixed maps --- src/client/views/collections/CollectionView.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/client/views/collections/CollectionView.tsx') diff --git a/src/client/views/collections/CollectionView.tsx b/src/client/views/collections/CollectionView.tsx index 7f2b5ff8e..c3fc3a40a 100644 --- a/src/client/views/collections/CollectionView.tsx +++ b/src/client/views/collections/CollectionView.tsx @@ -32,7 +32,7 @@ import { CollectionDockingView } from "./CollectionDockingView"; import { AddCustomFreeFormLayout } from './collectionFreeForm/CollectionFreeFormLayoutEngines'; import { CollectionFreeFormView } from './collectionFreeForm/CollectionFreeFormView'; import { CollectionLinearView } from './CollectionLinearView'; -import { CollectionMapView } from './CollectionMapView'; +import CollectionMapView from './CollectionMapView'; import { CollectionMulticolumnView } from './collectionMulticolumn/CollectionMulticolumnView'; import { CollectionMultirowView } from './collectionMulticolumn/CollectionMultirowView'; import { CollectionPileView } from './CollectionPileView'; -- cgit v1.2.3-70-g09d2 From 747581ac65f706710becad034c5f5abff76b8e51 Mon Sep 17 00:00:00 2001 From: Bob Zeleznik Date: Tue, 9 Jun 2020 17:26:05 -0400 Subject: fixed lots of errors/warnings. added 'a' to be able embed documents on drop. added 'l' toggle to perist lasso/marquee mode. --- src/client/apis/youtube/YoutubeBox.tsx | 3 +- src/client/documents/Documents.ts | 2 +- src/client/util/DragManager.ts | 50 +++++++++++++++------- .../util/Import & Export/DirectoryImportBox.tsx | 4 +- src/client/views/DocumentDecorations.tsx | 2 +- src/client/views/GlobalKeyHandler.ts | 1 + src/client/views/InkingStroke.tsx | 4 +- src/client/views/TemplateMenu.tsx | 4 +- src/client/views/animationtimeline/Keyframe.tsx | 8 ++-- src/client/views/animationtimeline/Timeline.tsx | 2 +- .../views/animationtimeline/TimelineOverview.tsx | 4 +- .../views/collections/CollectionPileView.tsx | 7 +-- .../views/collections/CollectionStackingView.tsx | 3 +- .../CollectionStackingViewFieldColumn.tsx | 2 +- src/client/views/collections/CollectionSubView.tsx | 4 +- .../views/collections/CollectionTimeView.tsx | 3 +- src/client/views/collections/CollectionView.tsx | 2 +- .../views/collections/CollectionViewChromes.tsx | 2 +- .../collectionFreeForm/CollectionFreeFormView.tsx | 13 +++--- .../collectionFreeForm/MarqueeView.scss | 2 +- .../collections/collectionFreeForm/MarqueeView.tsx | 9 ++-- src/client/views/nodes/ScreenshotBox.tsx | 3 +- src/client/views/nodes/VideoBox.tsx | 2 +- .../views/nodes/formattedText/DashDocView.tsx | 4 +- .../views/nodes/formattedText/DashFieldView.tsx | 7 +-- .../views/nodes/formattedText/FormattedTextBox.tsx | 4 +- .../views/nodes/formattedText/RichTextSchema.tsx | 4 +- src/client/views/webcam/DashWebRTCVideo.tsx | 3 +- src/fields/Doc.ts | 4 +- src/fields/RichTextUtils.ts | 6 +-- src/server/ApiManagers/UploadManager.ts | 3 +- 31 files changed, 96 insertions(+), 75 deletions(-) (limited to 'src/client/views/collections/CollectionView.tsx') diff --git a/src/client/apis/youtube/YoutubeBox.tsx b/src/client/apis/youtube/YoutubeBox.tsx index 748d571c0..2a1f55710 100644 --- a/src/client/apis/youtube/YoutubeBox.tsx +++ b/src/client/apis/youtube/YoutubeBox.tsx @@ -10,6 +10,7 @@ import { FieldView, FieldViewProps } from "../../views/nodes/FieldView"; import "../../views/nodes/WebBox.scss"; import "./YoutubeBox.scss"; import React = require("react"); +import { InkTool } from '../../../fields/InkField'; interface VideoTemplate { thumbnailUrl: string; @@ -349,7 +350,7 @@ export class YoutubeBox extends React.Component { const frozen = !this.props.isSelected() || DocumentDecorations.Instance.Interacting; - const classname = "webBox-cont" + (this.props.isSelected() && !Doc.GetSelectedTool() && !DocumentDecorations.Instance.Interacting ? "-interactive" : ""); + const classname = "webBox-cont" + (this.props.isSelected() && Doc.GetSelectedTool() === InkTool.None && !DocumentDecorations.Instance.Interacting ? "-interactive" : ""); return ( <>
diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts index 8d3e5a771..8d867348f 100644 --- a/src/client/documents/Documents.ts +++ b/src/client/documents/Documents.ts @@ -631,7 +631,7 @@ export namespace Docs { return doc; } - export function InkDocument(color: string, tool: number, strokeWidth: string, strokeBezier: string, points: { X: number, Y: number }[], options: DocumentOptions = {}) { + export function InkDocument(color: string, tool: string, strokeWidth: string, strokeBezier: string, points: { X: number, Y: number }[], options: DocumentOptions = {}) { const I = new Doc(); I.type = DocumentType.INK; I.layout = InkingStroke.LayoutString("data"); diff --git a/src/client/util/DragManager.ts b/src/client/util/DragManager.ts index e7a14f9c5..f1afaf734 100644 --- a/src/client/util/DragManager.ts +++ b/src/client/util/DragManager.ts @@ -67,6 +67,7 @@ export function SetupDrag( export namespace DragManager { let dragDiv: HTMLDivElement; + let dragLabel: HTMLDivElement; export let StartWindowDrag: Opt<((e: any, dragDocs: Doc[]) => void)> = undefined; export function Root() { @@ -97,7 +98,8 @@ export namespace DragManager { readonly shiftKey: boolean, readonly altKey: boolean, readonly metaKey: boolean, - readonly ctrlKey: boolean + readonly ctrlKey: boolean, + readonly embedKey: boolean, ) { } } @@ -309,14 +311,24 @@ export namespace DragManager { }; } export let docsBeingDragged: Doc[] = []; + export let CanEmbed = false; export function StartDrag(eles: HTMLElement[], dragData: { [id: string]: any }, downX: number, downY: number, options?: DragOptions, finishDrag?: (dropData: DragCompleteEvent) => void) { eles = eles.filter(e => e); + CanEmbed = false; if (!dragDiv) { dragDiv = document.createElement("div"); dragDiv.className = "dragManager-dragDiv"; dragDiv.style.pointerEvents = "none"; + dragLabel = document.createElement("div") as HTMLDivElement; + dragLabel.className = "dragManager-dragLabel"; + dragLabel.style.zIndex = "100001"; + dragLabel.style.fontSize = "10"; + dragLabel.style.position = "absolute"; + dragLabel.innerText = "press 'a' to embed on drop"; + dragDiv.appendChild(dragLabel); DragManager.Root().appendChild(dragDiv); } + dragLabel.style.display = ""; SnappingManager.SetIsDragging(true); const scaleXs: number[] = []; const scaleYs: number[] = []; @@ -358,6 +370,7 @@ export namespace DragManager { dragElement.style.transform = `translate(${rect.left + (options?.offsetX || 0)}px, ${rect.top + (options?.offsetY || 0)}px) scale(${scaleX}, ${scaleY})`; dragElement.style.width = `${rect.width / scaleX}px`; dragElement.style.height = `${rect.height / scaleY}px`; + dragLabel.style.transform = `translate(${rect.left + (options?.offsetX || 0)}px, ${rect.top + (options?.offsetY || 0) - 20}px)`; if (docsBeingDragged.length) { const pdfBox = dragElement.getElementsByTagName("canvas"); @@ -399,20 +412,21 @@ export namespace DragManager { if (dragData instanceof DocumentDragData) { dragData.userDropAction = e.ctrlKey && e.altKey ? "copy" : e.ctrlKey ? "alias" : undefined; } - if (e.shiftKey && dragData.droppedDocuments.length === 1) { - !dragData.dropAction && (dragData.dropAction = alias); - if (dragData.dropAction === "move") { - dragData.removeDocument?.(dragData.draggedDocuments[0]); + if (e) + if (e.shiftKey && dragData.droppedDocuments.length === 1) { + !dragData.dropAction && (dragData.dropAction = alias); + if (dragData.dropAction === "move") { + dragData.removeDocument?.(dragData.draggedDocuments[0]); + } + AbortDrag(); + finishDrag?.(new DragCompleteEvent(true, dragData)); + DragManager.StartWindowDrag?.({ + pageX: e.pageX, + pageY: e.pageY, + preventDefault: emptyFunction, + button: 0 + }, dragData.droppedDocuments); } - AbortDrag(); - finishDrag?.(new DragCompleteEvent(true, dragData)); - DragManager.StartWindowDrag?.({ - pageX: e.pageX, - pageY: e.pageY, - preventDefault: emptyFunction, - button: 0 - }, dragData.droppedDocuments); - } const { thisX, thisY } = snapDrag(e, xFromLeft, yFromTop, xFromRight, yFromBottom); @@ -421,12 +435,14 @@ export namespace DragManager { const moveY = thisY - lastY; lastX = thisX; lastY = thisY; + dragLabel.style.transform = `translate(${xs[0] + moveX + (options?.offsetX || 0)}px, ${ys[0] + moveY + (options?.offsetY || 0) - 20}px)`; dragElements.map((dragElement, i) => (dragElement.style.transform = `translate(${(xs[i] += moveX) + (options?.offsetX || 0)}px, ${(ys[i] += moveY) + (options?.offsetY || 0)}px) scale(${scaleXs[i]}, ${scaleYs[i]})`) ); }; const hideDragShowOriginalElements = () => { + dragLabel.style.display = "none"; dragElements.map(dragElement => dragElement.parentNode === dragDiv && dragDiv.removeChild(dragElement)); eles.map(ele => ele.parentElement && ele.parentElement?.className === dragData.dragDivName ? (ele.parentElement.hidden = false) : (ele.hidden = false)); }; @@ -481,7 +497,8 @@ export namespace DragManager { shiftKey: e.shiftKey, altKey: e.altKey, metaKey: e.metaKey, - ctrlKey: e.ctrlKey + ctrlKey: e.ctrlKey, + embedKey: CanEmbed } }) ); @@ -496,7 +513,8 @@ export namespace DragManager { shiftKey: e.shiftKey, altKey: e.altKey, metaKey: e.metaKey, - ctrlKey: e.ctrlKey + ctrlKey: e.ctrlKey, + embedKey: CanEmbed } }) ); diff --git a/src/client/util/Import & Export/DirectoryImportBox.tsx b/src/client/util/Import & Export/DirectoryImportBox.tsx index 4e5cde558..25c556697 100644 --- a/src/client/util/Import & Export/DirectoryImportBox.tsx +++ b/src/client/util/Import & Export/DirectoryImportBox.tsx @@ -7,7 +7,7 @@ import Measure, { ContentRect } from "react-measure"; import { library } from '@fortawesome/fontawesome-svg-core'; import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; import { faTag, faPlus, faCloudUploadAlt } from '@fortawesome/free-solid-svg-icons'; -import { Docs, DocumentOptions } from "../../documents/Documents"; +import { Docs, DocumentOptions, DocUtils } from "../../documents/Documents"; import { observer } from "mobx-react"; import ImportMetadataEntry, { keyPlaceholder, valuePlaceholder } from "./ImportMetadataEntry"; import { Utils } from "../../../Utils"; @@ -123,7 +123,7 @@ export default class DirectoryImportBox extends React.Component } const { accessPaths, exifData } = result; const path = Utils.prepend(accessPaths.agnostic.client); - const document = await Doc.Get.DocumentFromType(type, path, { _width: 300, title: name }); + const document = await DocUtils.DocumentFromType(type, path, { _width: 300, title: name }); const { data, error } = exifData; if (document) { Doc.GetProto(document).exif = error || Doc.Get.FromJson({ data }); diff --git a/src/client/views/DocumentDecorations.tsx b/src/client/views/DocumentDecorations.tsx index e7a237e62..6ca7331d6 100644 --- a/src/client/views/DocumentDecorations.tsx +++ b/src/client/views/DocumentDecorations.tsx @@ -403,7 +403,7 @@ export class DocumentDecorations extends React.Component<{}, { value: string }> onPointerUp = (e: PointerEvent): void => { SelectionManager.SelectedDocuments().map(dv => { if (NumCast(dv.layoutDoc._delayAutoHeight) < this._dragHeights.get(dv.layoutDoc)!) { - dv.nativeWidth > 0 && Doc.toggleNativeDimensions(dv.layoutDoc, dv.props.ContentScaling(), dv.panelWidth(), dv.panelHeight()); + dv.nativeWidth > 0 && Doc.toggleNativeDimensions(dv.layoutDoc, dv.props.ContentScaling(), dv.props.PanelWidth(), dv.props.PanelHeight()); dv.layoutDoc._autoHeight = true; } dv.layoutDoc._delayAutoHeight = undefined; diff --git a/src/client/views/GlobalKeyHandler.ts b/src/client/views/GlobalKeyHandler.ts index 2d5af5386..772cb07b1 100644 --- a/src/client/views/GlobalKeyHandler.ts +++ b/src/client/views/GlobalKeyHandler.ts @@ -72,6 +72,7 @@ export default class KeyManager { private unmodified = action((keyname: string, e: KeyboardEvent) => { switch (keyname) { + case "a": DragManager.CanEmbed = true; case " ": MarqueeView.DragMarquee = !MarqueeView.DragMarquee; break; diff --git a/src/client/views/InkingStroke.tsx b/src/client/views/InkingStroke.tsx index 7dac2e3b5..7d73247af 100644 --- a/src/client/views/InkingStroke.tsx +++ b/src/client/views/InkingStroke.tsx @@ -92,5 +92,5 @@ Scripting.addGlobal(function activateBrush(pen: any, width: any, color: any) { Scripting.addGlobal(function activateEraser(pen: any) { return Doc.SetSelectedTool(pen ? InkTool.Eraser : InkTool.None); }); Scripting.addGlobal(function activateStamp(pen: any) { return Doc.SetSelectedTool(pen ? InkTool.Stamp : InkTool.None); }); Scripting.addGlobal(function deactivateInk() { return Doc.SetSelectedTool(InkTool.None); }); -Scripting.addGlobal(function setInkWidth(width: any) { return Doc.SetSelectedTool(width); }); -Scripting.addGlobal(function setInkColor(color: any) { return Doc.SetSelectedTool(color); }); \ No newline at end of file +Scripting.addGlobal(function setInkWidth(width: any) { return SetActiveInkWidth(width); }); +Scripting.addGlobal(function setInkColor(color: any) { return SetActiveInkColor(color); }); \ No newline at end of file diff --git a/src/client/views/TemplateMenu.tsx b/src/client/views/TemplateMenu.tsx index 77e6ebf44..f135823a8 100644 --- a/src/client/views/TemplateMenu.tsx +++ b/src/client/views/TemplateMenu.tsx @@ -7,7 +7,7 @@ import { DocumentView } from "./nodes/DocumentView"; import { Template } from "./Templates"; import React = require("react"); import { Doc, DocListCast } from "../../fields/Doc"; -import { Docs, } from "../documents/Documents"; +import { Docs, DocUtils, } from "../documents/Documents"; import { StrCast, Cast } from "../../fields/Types"; import { CollectionTreeView } from "./collections/CollectionTreeView"; import { returnTrue, emptyFunction, returnFalse, returnOne, emptyPath, returnZero } from "../../Utils"; @@ -176,5 +176,5 @@ Scripting.addGlobal(function switchView(doc: Doc, template: Doc | undefined) { template = Cast(template.dragFactory, Doc, null); } const templateTitle = StrCast(template?.title); - return templateTitle && Doc.makeCustomViewClicked(doc, Docs.Create.FreeformDocument, templateTitle, template); + return templateTitle && DocUtils.makeCustomViewClicked(doc, Docs.Create.FreeformDocument, templateTitle, template); }); diff --git a/src/client/views/animationtimeline/Keyframe.tsx b/src/client/views/animationtimeline/Keyframe.tsx index b562bd957..3a7182a94 100644 --- a/src/client/views/animationtimeline/Keyframe.tsx +++ b/src/client/views/animationtimeline/Keyframe.tsx @@ -180,10 +180,10 @@ export class Keyframe extends React.Component { const fadeIn = this.props.makeKeyData(this.regiondata, this.regiondata.position + this.regiondata.fadeIn, KeyframeFunc.KeyframeType.fade); const fadeOut = this.props.makeKeyData(this.regiondata, this.regiondata.position + this.regiondata.duration - this.regiondata.fadeOut, KeyframeFunc.KeyframeType.fade); const finish = this.props.makeKeyData(this.regiondata, this.regiondata.position + this.regiondata.duration, KeyframeFunc.KeyframeType.end); - (fadeIn as Doc).opacity = 1; - (fadeOut as Doc).opacity = 1; - (start as Doc).opacity = 0.1; - (finish as Doc).opacity = 0.1; + fadeIn.opacity = 1; + fadeOut.opacity = 1; + start.opacity = 0.1; + finish.opacity = 0.1; this.forceUpdate(); //not needed, if setTimeout is gone... }, 1000); } diff --git a/src/client/views/animationtimeline/Timeline.tsx b/src/client/views/animationtimeline/Timeline.tsx index 43f15a33f..ab984f727 100644 --- a/src/client/views/animationtimeline/Timeline.tsx +++ b/src/client/views/animationtimeline/Timeline.tsx @@ -445,7 +445,7 @@ export class Timeline extends React.Component { // @computed getCurrentTime = () => { - let current = KeyframeFunc.convertPixelTime(this._currentBarX, "mili", "time", this._tickSpacing, this._tickIncrement); + const current = KeyframeFunc.convertPixelTime(this._currentBarX, "mili", "time", this._tickSpacing, this._tickIncrement); return this.toReadTime(current > this._time ? this._time : current); } diff --git a/src/client/views/animationtimeline/TimelineOverview.tsx b/src/client/views/animationtimeline/TimelineOverview.tsx index 31e248823..81a5587e4 100644 --- a/src/client/views/animationtimeline/TimelineOverview.tsx +++ b/src/client/views/animationtimeline/TimelineOverview.tsx @@ -42,9 +42,9 @@ export class TimelineOverview extends React.Component{ this.setOverviewWidth(); this._authoringReaction = reaction( - () => this.props.parent._isAuthoring, + () => this.props.isAuthoring, () => { - if (!this.props.parent._isAuthoring) { + if (!this.props.isAuthoring) { runInAction(() => { this.setOverviewWidth(); }); diff --git a/src/client/views/collections/CollectionPileView.tsx b/src/client/views/collections/CollectionPileView.tsx index fc48e0327..22a3877ab 100644 --- a/src/client/views/collections/CollectionPileView.tsx +++ b/src/client/views/collections/CollectionPileView.tsx @@ -12,6 +12,7 @@ import { SelectionManager } from "../../util/SelectionManager"; import { UndoManager, undoBatch } from "../../util/UndoManager"; import { SnappingManager } from "../../util/SnappingManager"; import { DragManager } from "../../util/DragManager"; +import { DocUtils } from "../../documents/Documents"; @observer export class CollectionPileView extends CollectionSubView(doc => doc) { @@ -45,12 +46,12 @@ export class CollectionPileView extends CollectionSubView(doc => doc) { if (this.layoutEngine() === 'starburst') { const defaultSize = 110; this.layoutDoc._overflow = undefined; - this.childDocs.forEach(d => Doc.iconify(d)); + this.childDocs.forEach(d => DocUtils.iconify(d)); this.rootDoc.x = NumCast(this.rootDoc.x) + this.layoutDoc[WidthSym]() / 2 - NumCast(this.layoutDoc._starburstPileWidth, defaultSize) / 2; this.rootDoc.y = NumCast(this.rootDoc.y) + this.layoutDoc[HeightSym]() / 2 - NumCast(this.layoutDoc._starburstPileHeight, defaultSize) / 2; this.layoutDoc._width = NumCast(this.layoutDoc._starburstPileWidth, defaultSize); this.layoutDoc._height = NumCast(this.layoutDoc._starburstPileHeight, defaultSize); - Doc.pileup(this.childDocs); + DocUtils.pileup(this.childDocs); this.layoutDoc._panX = 0; this.layoutDoc._panY = -10; this.props.Document._pileLayoutEngine = 'pass'; @@ -76,7 +77,7 @@ export class CollectionPileView extends CollectionSubView(doc => doc) { onInternalDrop = (e: Event, de: DragManager.DropEvent) => { if (super.onInternalDrop(e, de)) { if (de.complete.docDragData) { - Doc.pileup(this.childDocs); + DocUtils.pileup(this.childDocs); } } return true; diff --git a/src/client/views/collections/CollectionStackingView.tsx b/src/client/views/collections/CollectionStackingView.tsx index bd48d1727..0a1b03522 100644 --- a/src/client/views/collections/CollectionStackingView.tsx +++ b/src/client/views/collections/CollectionStackingView.tsx @@ -27,6 +27,7 @@ import { CollectionSubView } from "./CollectionSubView"; import { CollectionViewType } from "./CollectionView"; import { SnappingManager } from "../../util/SnappingManager"; import { CollectionFreeFormDocumentView } from "../nodes/CollectionFreeFormDocumentView"; +import { DocUtils } from "../../documents/Documents"; const _global = (window /* browser */ || global /* node */) as any; type StackingDocument = makeInterface<[typeof collectionSchema, typeof documentSchema]>; @@ -412,7 +413,7 @@ export class CollectionStackingView extends CollectionSubView(StackingDocument) if (value && this.sectionHeaders) { const schemaHdrField = new SchemaHeaderField(value); this.sectionHeaders.push(schemaHdrField); - Doc.addFieldEnumerations(undefined, this.pivotField, [{ title: value, _backgroundColor: schemaHdrField.color }]); + DocUtils.addFieldEnumerations(undefined, this.pivotField, [{ title: value, _backgroundColor: schemaHdrField.color }]); return true; } return false; diff --git a/src/client/views/collections/CollectionStackingViewFieldColumn.tsx b/src/client/views/collections/CollectionStackingViewFieldColumn.tsx index a269b21f5..bcd55f0fe 100644 --- a/src/client/views/collections/CollectionStackingViewFieldColumn.tsx +++ b/src/client/views/collections/CollectionStackingViewFieldColumn.tsx @@ -235,7 +235,7 @@ export class CollectionStackingViewFieldColumn extends React.Component dataDoc[fieldKey] instanceof RichTextField || dataDoc[fieldKey] instanceof ImageField || typeof (dataDoc[fieldKey]) === "string").map(fieldKey => docItems.push({ description: ":" + fieldKey, event: () => { - const created = Docs.Get.DocumentFromField(dataDoc, fieldKey, Doc.GetProto(this.props.parent.props.Document)); + const created = DocUtils.DocumentFromField(dataDoc, fieldKey, Doc.GetProto(this.props.parent.props.Document)); if (created) { if (this.props.parent.Document.isTemplateDoc) { Doc.MakeMetadataFieldTemplate(created, this.props.parent.props.Document); diff --git a/src/client/views/collections/CollectionSubView.tsx b/src/client/views/collections/CollectionSubView.tsx index 47d571bcc..93d20c475 100644 --- a/src/client/views/collections/CollectionSubView.tsx +++ b/src/client/views/collections/CollectionSubView.tsx @@ -10,7 +10,7 @@ import { WebField } from "../../../fields/URLField"; import { Cast, ScriptCast, NumCast } from "../../../fields/Types"; import { GestureUtils } from "../../../pen-gestures/GestureUtils"; import { Upload } from "../../../server/SharedMediaTypes"; -import { Utils } from "../../../Utils"; +import { Utils, returnFalse } from "../../../Utils"; import { DocServer } from "../../DocServer"; import { Networking } from "../../Network"; import { ImageUtils } from "../../util/Import & Export/ImageUtils"; @@ -217,7 +217,7 @@ export function CollectionSubView(schemaCtor: (doc: Doc) => T, moreProps?: const movedDocs = docDragData.droppedDocuments.filter((d, i) => docDragData.draggedDocuments[i] === d); const addedDocs = docDragData.droppedDocuments.filter((d, i) => docDragData.draggedDocuments[i] !== d); const res = addedDocs.length ? this.addDocument(addedDocs) : true; - added = movedDocs.length ? docDragData.moveDocument(movedDocs, this.props.Document, this.addDocument) : res; + added = movedDocs.length ? docDragData.moveDocument(movedDocs, this.props.Document, de.embedKey || !this.props.isAnnotationOverlay ? this.addDocument : returnFalse) : res; } else { added = this.addDocument(docDragData.droppedDocuments); } diff --git a/src/client/views/collections/CollectionTimeView.tsx b/src/client/views/collections/CollectionTimeView.tsx index 15bc0bfd5..c2d682361 100644 --- a/src/client/views/collections/CollectionTimeView.tsx +++ b/src/client/views/collections/CollectionTimeView.tsx @@ -19,6 +19,7 @@ const higflyout = require("@hig/flyout"); export const { anchorPoints } = higflyout; export const Flyout = higflyout.default; import React = require("react"); +import { DocUtils } from "../../documents/Documents"; @observer export class CollectionTimeView extends CollectionSubView(doc => doc) { @@ -28,7 +29,7 @@ export class CollectionTimeView extends CollectionSubView(doc => doc) { @observable _childClickedScript: Opt; @observable _viewDefDivClick: Opt; async componentDidMount() { - const detailView = (await DocCastAsync(this.props.Document.childClickedOpenTemplateView)) || Doc.findTemplate("detailView", StrCast(this.props.Document.type), ""); + const detailView = (await DocCastAsync(this.props.Document.childClickedOpenTemplateView)) || DocUtils.findTemplate("detailView", StrCast(this.props.Document.type), ""); const childText = "const alias = getAlias(self); switchView(alias, detailView); alias.dropAction='alias'; alias.removeDropProperties=new List(['dropAction']); useRightSplit(alias, shiftKey); "; runInAction(() => { this._childClickedScript = ScriptField.MakeScript(childText, { this: Doc.name, shiftKey: "boolean" }, { detailView: detailView! }); diff --git a/src/client/views/collections/CollectionView.tsx b/src/client/views/collections/CollectionView.tsx index c3fc3a40a..7e5f427ba 100644 --- a/src/client/views/collections/CollectionView.tsx +++ b/src/client/views/collections/CollectionView.tsx @@ -164,7 +164,7 @@ export class CollectionView extends Touchable { diff --git a/src/client/views/collections/CollectionViewChromes.tsx b/src/client/views/collections/CollectionViewChromes.tsx index 29a3e559a..3dc740c25 100644 --- a/src/client/views/collections/CollectionViewChromes.tsx +++ b/src/client/views/collections/CollectionViewChromes.tsx @@ -93,7 +93,7 @@ export class CollectionViewBaseChrome extends React.Component { diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx index d512f815c..aa4fc48f3 100644 --- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx +++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx @@ -177,7 +177,7 @@ export class CollectionFreeFormView extends CollectionSubView { SelectionManager.DeselectAll(); @@ -251,11 +251,11 @@ export class CollectionFreeFormView extends CollectionSubView { // if (this.props.Document.isBackground) return false; const [xp, yp] = this.getTransform().transformPoint(de.x, de.y); - if (this.isAnnotationOverlay !== true && de.complete.linkDragData) + if (this.isAnnotationOverlay !== true && de.complete.linkDragData) { return this.internalLinkDrop(e, de, de.complete.linkDragData, xp, yp); - if (de.complete.annoDragData?.dropDocument && super.onInternalDrop(e, de)) + } else if (de.complete.annoDragData?.dropDocument && super.onInternalDrop(e, de)) { return this.internalPdfAnnoDrop(e, de.complete.annoDragData, xp, yp); - if (de.complete.docDragData?.droppedDocuments.length && this.internalDocDrop(e, de, de.complete.docDragData, xp, yp)) { + } else if (de.complete.docDragData?.droppedDocuments.length && this.internalDocDrop(e, de, de.complete.docDragData, xp, yp)) { return true; } else { UndoManager.Undo(); @@ -530,9 +530,7 @@ export class CollectionFreeFormView extends CollectionSubView { - console.log(results); const wordResults = results.filter((r: any) => r.category === "inkWord"); for (const word of wordResults) { const indices: number[] = word.strokeIds; @@ -617,8 +615,7 @@ export class CollectionFreeFormView extends CollectionSubView this.props.removeDocument(d)); - const newCollection = Doc.pileup(selected, this.Bounds.left + this.Bounds.width / 2, this.Bounds.top + this.Bounds.height / 2); + const newCollection = DocUtils.pileup(selected, this.Bounds.left + this.Bounds.width / 2, this.Bounds.top + this.Bounds.height / 2); this.props.addDocument(newCollection!); this.props.selectDocuments([newCollection!], []); MarqueeOptionsMenu.Instance.fadeOut(true); @@ -527,7 +526,7 @@ export class MarqueeView extends React.Component { - this._freeHand = x; + this._freeHand = !this._freeHand; } // @action // marqueeInkSelect(ink: Map) { @@ -697,7 +696,7 @@ export class MarqueeView extends React.Component - {/* */} +
; } else { diff --git a/src/client/views/nodes/ScreenshotBox.tsx b/src/client/views/nodes/ScreenshotBox.tsx index d75b864cf..f7dee0896 100644 --- a/src/client/views/nodes/ScreenshotBox.tsx +++ b/src/client/views/nodes/ScreenshotBox.tsx @@ -18,6 +18,7 @@ import { ContextMenuProps } from "../ContextMenuItem"; import { ViewBoxBaseComponent } from "../DocComponent"; import { FieldView, FieldViewProps } from './FieldView'; import "./ScreenshotBox.scss"; +import { InkTool } from "../../../fields/InkField"; const path = require('path'); type ScreenshotDocument = makeInterface<[typeof documentSchema]>; @@ -132,7 +133,7 @@ export class ScreenshotBox extends ViewBoxBaseComponentLoading
: