From 7741fd9cc135f94fbc1b68d89d68e38c93648f33 Mon Sep 17 00:00:00 2001 From: Sam Wilkins Date: Fri, 10 Jan 2020 14:34:22 -0500 Subject: created multicolumn view file, made recipient parameter optional in sessionmanager --- src/client/views/CollectionMulticolumnView.tsx | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) create mode 100644 src/client/views/CollectionMulticolumnView.tsx (limited to 'src/client/views/CollectionMulticolumnView.tsx') diff --git a/src/client/views/CollectionMulticolumnView.tsx b/src/client/views/CollectionMulticolumnView.tsx new file mode 100644 index 000000000..8f0ffd3d0 --- /dev/null +++ b/src/client/views/CollectionMulticolumnView.tsx @@ -0,0 +1,25 @@ +import { observer } from 'mobx-react'; +import { makeInterface } from '../../new_fields/Schema'; +import { documentSchema } from '../../new_fields/documentSchemas'; +import { CollectionSubView } from './collections/CollectionSubView'; +import { DragManager } from '../util/DragManager'; + +type MulticolumnDocument = makeInterface<[typeof documentSchema]>; +const MulticolumnDocument = makeInterface(documentSchema); + +@observer +export default class CollectionMulticolumnView extends CollectionSubView(MulticolumnDocument) { + + private _dropDisposer?: DragManager.DragDropDisposer; + protected createDropTarget = (ele: HTMLDivElement) => { //used for stacking and masonry view + this._dropDisposer && this._dropDisposer(); + if (ele) { + this._dropDisposer = DragManager.MakeDropTarget(ele, this.drop.bind(this)); + } + } + + render() { + return null; + } + +} \ No newline at end of file -- cgit v1.2.3-70-g09d2 From ee10e28ba3f7c97b0947e2065d04562e33ed3498 Mon Sep 17 00:00:00 2001 From: Sam Wilkins Date: Fri, 10 Jan 2020 15:33:07 -0500 Subject: multicolumn changes --- src/client/views/CollectionMulticolumnView.tsx | 23 +++++++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) (limited to 'src/client/views/CollectionMulticolumnView.tsx') diff --git a/src/client/views/CollectionMulticolumnView.tsx b/src/client/views/CollectionMulticolumnView.tsx index 8f0ffd3d0..94e86c048 100644 --- a/src/client/views/CollectionMulticolumnView.tsx +++ b/src/client/views/CollectionMulticolumnView.tsx @@ -1,8 +1,11 @@ import { observer } from 'mobx-react'; import { makeInterface } from '../../new_fields/Schema'; import { documentSchema } from '../../new_fields/documentSchemas'; -import { CollectionSubView } from './collections/CollectionSubView'; +import { CollectionSubView, SubCollectionViewProps } from './collections/CollectionSubView'; import { DragManager } from '../util/DragManager'; +import * as React from "react"; +import { Doc } from '../../new_fields/Doc'; +import { NumCast } from '../../new_fields/Types'; type MulticolumnDocument = makeInterface<[typeof documentSchema]>; const MulticolumnDocument = makeInterface(documentSchema); @@ -10,6 +13,12 @@ const MulticolumnDocument = makeInterface(documentSchema); @observer export default class CollectionMulticolumnView extends CollectionSubView(MulticolumnDocument) { + constructor(props: Readonly) { + super(props); + const { Document } = this.props; + Document.multicolumnData = new Doc(); + } + private _dropDisposer?: DragManager.DragDropDisposer; protected createDropTarget = (ele: HTMLDivElement) => { //used for stacking and masonry view this._dropDisposer && this._dropDisposer(); @@ -18,8 +27,18 @@ export default class CollectionMulticolumnView extends CollectionSubView(Multico } } + public isCurrent(doc: Doc) { return !doc.isMinimized && (Math.abs(NumCast(doc.displayTimecode, -1) - NumCast(this.Document.currentTimecode, -1)) < 1.5 || NumCast(doc.displayTimecode, -1) === -1); } + render() { - return null; + return ( +
+
+ {this.childLayoutPairs.filter(pair => this.isCurrent(pair.layout)).map(({ layout, data }) => { + + })} +
+
+ ); } } \ No newline at end of file -- cgit v1.2.3-70-g09d2 From 87124df2d90c905f5b10a6cef58d2db44cb6aed6 Mon Sep 17 00:00:00 2001 From: Sam Wilkins Date: Tue, 14 Jan 2020 19:46:50 -0500 Subject: initial propagation of collectionmulticolumnview --- src/client/views/CollectionMulticolumnView.tsx | 4 ++-- src/client/views/collections/CollectionSubView.tsx | 6 ++++-- src/client/views/collections/CollectionView.tsx | 8 ++++++-- 3 files changed, 12 insertions(+), 6 deletions(-) (limited to 'src/client/views/CollectionMulticolumnView.tsx') diff --git a/src/client/views/CollectionMulticolumnView.tsx b/src/client/views/CollectionMulticolumnView.tsx index 94e86c048..da5b18155 100644 --- a/src/client/views/CollectionMulticolumnView.tsx +++ b/src/client/views/CollectionMulticolumnView.tsx @@ -12,6 +12,7 @@ const MulticolumnDocument = makeInterface(documentSchema); @observer export default class CollectionMulticolumnView extends CollectionSubView(MulticolumnDocument) { + private _dropDisposer?: DragManager.DragDropDisposer; constructor(props: Readonly) { super(props); @@ -19,8 +20,7 @@ export default class CollectionMulticolumnView extends CollectionSubView(Multico Document.multicolumnData = new Doc(); } - private _dropDisposer?: DragManager.DragDropDisposer; - protected createDropTarget = (ele: HTMLDivElement) => { //used for stacking and masonry view + protected createDropTarget = (ele: HTMLDivElement) => { this._dropDisposer && this._dropDisposer(); if (ele) { this._dropDisposer = DragManager.MakeDropTarget(ele, this.drop.bind(this)); diff --git a/src/client/views/collections/CollectionSubView.tsx b/src/client/views/collections/CollectionSubView.tsx index 062521690..5753dd34e 100644 --- a/src/client/views/collections/CollectionSubView.tsx +++ b/src/client/views/collections/CollectionSubView.tsx @@ -85,8 +85,10 @@ export function CollectionSubView(schemaCtor: (doc: Doc) => T) { return this.props.annotationsKey ? (this.extensionDoc ? this.extensionDoc[this.props.annotationsKey] : undefined) : this.dataDoc[this.props.fieldKey]; } - get childLayoutPairs() { - return this.childDocs.map(cd => Doc.GetLayoutDataDocPair(this.props.Document, this.props.DataDoc, this.props.fieldKey, cd)).filter(pair => pair.layout).map(pair => ({ layout: pair.layout!, data: pair.data! })); + get childLayoutPairs(): { layout: Doc; data: Doc; }[] { + const { Document, DataDoc, fieldKey } = this.props; + const validPairs = this.childDocs.map(doc => Doc.GetLayoutDataDocPair(Document, DataDoc, fieldKey, doc)).filter(pair => pair.layout); + return validPairs.map(({ data, layout }) => ({ data: data!, layout: layout! })); // this mapping is a bit of a hack to coerce types } get childDocList() { return Cast(this.dataField, listSpec(Doc)); diff --git a/src/client/views/collections/CollectionView.tsx b/src/client/views/collections/CollectionView.tsx index 55f0de779..26df89796 100644 --- a/src/client/views/collections/CollectionView.tsx +++ b/src/client/views/collections/CollectionView.tsx @@ -35,6 +35,7 @@ import { Touchable } from '../Touchable'; import { TraceMobx } from '../../../new_fields/util'; import { Utils } from '../../../Utils'; import { ScriptBox } from '../ScriptBox'; +import CollectionMulticolumnView from '../CollectionMulticolumnView'; const path = require('path'); library.add(faTh, faTree, faSquare, faProjectDiagram, faSignature, faThList, faFingerprint, faColumns, faEllipsisV, faImage, faEye as any, faCopy); @@ -48,7 +49,8 @@ export enum CollectionViewType { Masonry, Pivot, Linear, - Staff + Staff, + Multicolumn } export namespace CollectionViewType { @@ -61,7 +63,8 @@ export namespace CollectionViewType { ["stacking", CollectionViewType.Stacking], ["masonry", CollectionViewType.Masonry], ["pivot", CollectionViewType.Pivot], - ["linear", CollectionViewType.Linear] + ["linear", CollectionViewType.Linear], + ["multicolumn", CollectionViewType.Multicolumn] ]); export const valueOf = (value: string) => stringMapping.get(value.toLowerCase()); @@ -173,6 +176,7 @@ export class CollectionView extends Touchable { case CollectionViewType.Docking: return (); case CollectionViewType.Tree: return (); case CollectionViewType.Staff: return (); + case CollectionViewType.Multicolumn: return (); case CollectionViewType.Linear: { return (); } case CollectionViewType.Stacking: { this.props.Document.singleColumn = true; return (); } case CollectionViewType.Masonry: { this.props.Document.singleColumn = false; return (); } -- cgit v1.2.3-70-g09d2 From 6a3936235e5768c7632f0669debd804e86504a20 Mon Sep 17 00:00:00 2001 From: Sam Wilkins Date: Tue, 14 Jan 2020 20:00:14 -0500 Subject: multicolumn view in context menu --- src/client/views/CollectionMulticolumnView.tsx | 18 ++++++++++-------- src/client/views/collections/CollectionView.tsx | 1 + 2 files changed, 11 insertions(+), 8 deletions(-) (limited to 'src/client/views/CollectionMulticolumnView.tsx') diff --git a/src/client/views/CollectionMulticolumnView.tsx b/src/client/views/CollectionMulticolumnView.tsx index da5b18155..ea1f0c189 100644 --- a/src/client/views/CollectionMulticolumnView.tsx +++ b/src/client/views/CollectionMulticolumnView.tsx @@ -1,11 +1,12 @@ import { observer } from 'mobx-react'; -import { makeInterface } from '../../new_fields/Schema'; +import { makeInterface, listSpec } from '../../new_fields/Schema'; import { documentSchema } from '../../new_fields/documentSchemas'; import { CollectionSubView, SubCollectionViewProps } from './collections/CollectionSubView'; import { DragManager } from '../util/DragManager'; import * as React from "react"; -import { Doc } from '../../new_fields/Doc'; -import { NumCast } from '../../new_fields/Types'; +import { Doc, DocListCast } from '../../new_fields/Doc'; +import { NumCast, Cast } from '../../new_fields/Types'; +import { List } from '../../new_fields/List'; type MulticolumnDocument = makeInterface<[typeof documentSchema]>; const MulticolumnDocument = makeInterface(documentSchema); @@ -13,11 +14,12 @@ const MulticolumnDocument = makeInterface(documentSchema); @observer export default class CollectionMulticolumnView extends CollectionSubView(MulticolumnDocument) { private _dropDisposer?: DragManager.DragDropDisposer; - - constructor(props: Readonly) { - super(props); + private get configuration() { const { Document } = this.props; - Document.multicolumnData = new Doc(); + if (!Document.multicolumnData) { + Document.multicolumnData = new List(); + } + return DocListCast(this.Document.multicolumnData); } protected createDropTarget = (ele: HTMLDivElement) => { @@ -33,7 +35,7 @@ export default class CollectionMulticolumnView extends CollectionSubView(Multico return (
- {this.childLayoutPairs.filter(pair => this.isCurrent(pair.layout)).map(({ layout, data }) => { + {this.configuration.map(config => ).filter(pair => this.isCurrent(pair.layout)).map(({ layout, data }) => { })}
diff --git a/src/client/views/collections/CollectionView.tsx b/src/client/views/collections/CollectionView.tsx index 26df89796..21371dd39 100644 --- a/src/client/views/collections/CollectionView.tsx +++ b/src/client/views/collections/CollectionView.tsx @@ -218,6 +218,7 @@ export class CollectionView extends Touchable { }, icon: "ellipsis-v" }); subItems.push({ description: "Staff", event: () => this.props.Document.viewType = CollectionViewType.Staff, icon: "music" }); + subItems.push({ description: "Multicolumn", event: () => this.props.Document.viewType = CollectionViewType.Multicolumn, icon: "columns" }); subItems.push({ description: "Masonry", event: () => this.props.Document.viewType = CollectionViewType.Masonry, icon: "columns" }); subItems.push({ description: "Pivot", event: () => this.props.Document.viewType = CollectionViewType.Pivot, icon: "columns" }); switch (this.props.Document.viewType) { -- cgit v1.2.3-70-g09d2 From 3ab47ee803372686966092751bd6a589b62a17c6 Mon Sep 17 00:00:00 2001 From: Sam Wilkins Date: Wed, 15 Jan 2020 13:26:07 -0500 Subject: linter + baseline functional multicolumn view --- src/Utils.ts | 4 +-- src/client/views/CollectionMulticolumnView.scss | 7 +++++ src/client/views/CollectionMulticolumnView.tsx | 39 ++++++++++++++++++++++--- src/client/views/nodes/DocumentView.tsx | 2 +- src/new_fields/Doc.ts | 6 ++-- 5 files changed, 48 insertions(+), 10 deletions(-) create mode 100644 src/client/views/CollectionMulticolumnView.scss (limited to 'src/client/views/CollectionMulticolumnView.tsx') diff --git a/src/Utils.ts b/src/Utils.ts index 562d9d83f..f50655f6c 100644 --- a/src/Utils.ts +++ b/src/Utils.ts @@ -329,7 +329,7 @@ export function timenow() { } export function aggregateBounds(boundsList: { x: number, y: number, width: number, height: number }[], xpad: number, ypad: number) { - let bounds = boundsList.reduce((bounds, b) => { + const bounds = boundsList.reduce((bounds, b) => { const [sptX, sptY] = [b.x, b.y]; const [bptX, bptY] = [sptX + b.width, sptY + b.height]; return { @@ -337,7 +337,7 @@ export function aggregateBounds(boundsList: { x: number, y: number, width: numbe r: Math.max(bptX, bounds.r), b: Math.max(bptY, bounds.b) }; }, { x: Number.MAX_VALUE, y: Number.MAX_VALUE, r: -Number.MAX_VALUE, b: -Number.MAX_VALUE }); - return { x: bounds.x !== Number.MAX_VALUE ? bounds.x - xpad : bounds.x, y: bounds.y !== Number.MAX_VALUE ? bounds.y - ypad : bounds.y, r: bounds.r !== -Number.MAX_VALUE ? bounds.r + 2 * xpad : bounds.r, b: bounds.b !== -Number.MAX_VALUE ? bounds.b + 2 * ypad : bounds.b } + return { x: bounds.x !== Number.MAX_VALUE ? bounds.x - xpad : bounds.x, y: bounds.y !== Number.MAX_VALUE ? bounds.y - ypad : bounds.y, r: bounds.r !== -Number.MAX_VALUE ? bounds.r + 2 * xpad : bounds.r, b: bounds.b !== -Number.MAX_VALUE ? bounds.b + 2 * ypad : bounds.b }; } export function intersectRect(r1: { left: number, top: number, width: number, height: number }, r2: { left: number, top: number, width: number, height: number }) { diff --git a/src/client/views/CollectionMulticolumnView.scss b/src/client/views/CollectionMulticolumnView.scss new file mode 100644 index 000000000..84e80da4a --- /dev/null +++ b/src/client/views/CollectionMulticolumnView.scss @@ -0,0 +1,7 @@ +.collectionMulticolumnView_outer, +.collectionMulticolumnView_contents { + width: 100%; + height: 100%; + overflow: hidden; +} + diff --git a/src/client/views/CollectionMulticolumnView.tsx b/src/client/views/CollectionMulticolumnView.tsx index ea1f0c189..0aa615ffc 100644 --- a/src/client/views/CollectionMulticolumnView.tsx +++ b/src/client/views/CollectionMulticolumnView.tsx @@ -1,12 +1,16 @@ import { observer } from 'mobx-react'; import { makeInterface, listSpec } from '../../new_fields/Schema'; import { documentSchema } from '../../new_fields/documentSchemas'; -import { CollectionSubView, SubCollectionViewProps } from './collections/CollectionSubView'; +import { CollectionSubView } from './collections/CollectionSubView'; import { DragManager } from '../util/DragManager'; import * as React from "react"; import { Doc, DocListCast } from '../../new_fields/Doc'; -import { NumCast, Cast } from '../../new_fields/Types'; +import { NumCast, Cast, StrCast } from '../../new_fields/Types'; import { List } from '../../new_fields/List'; +import { ContentFittingDocumentView } from './nodes/ContentFittingDocumentView'; +import { Utils } from '../../Utils'; +import { Transform } from '../util/Transform'; +import "./collectionMulticolumnView.scss"; type MulticolumnDocument = makeInterface<[typeof documentSchema]>; const MulticolumnDocument = makeInterface(documentSchema); @@ -29,14 +33,41 @@ export default class CollectionMulticolumnView extends CollectionSubView(Multico } } + getTransform = (ele: React.RefObject) => () => { + if (!ele.current) return Transform.Identity(); + const { scale, translateX, translateY } = Utils.GetScreenTransform(ele.current); + return new Transform(-translateX, -translateY, 1 / scale); + } + public isCurrent(doc: Doc) { return !doc.isMinimized && (Math.abs(NumCast(doc.displayTimecode, -1) - NumCast(this.Document.currentTimecode, -1)) < 1.5 || NumCast(doc.displayTimecode, -1) === -1); } render() { + const { PanelWidth } = this.props; return (
- {this.configuration.map(config => ).filter(pair => this.isCurrent(pair.layout)).map(({ layout, data }) => { - + {this.configuration.map(config => { + const { target } = config; + if (target instanceof Doc) { + let computedWidth: number = 0; + const widthSpecifier = Cast(config.columnWidth, "number"); + let matches: RegExpExecArray | null; + if (widthSpecifier !== undefined) { + computedWidth = widthSpecifier; + } else if ((matches = /([\d.]+)\%/.exec(StrCast(config.columnWidth))) !== null) { + computedWidth = Number(matches[1]) / 100 * PanelWidth(); + } + return (!computedWidth ? (null) : + computedWidth} + getTransform={this.props.ScreenToLocalTransform} + /> + ); + } + return (null); })}
diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx index e45c19533..8f3fa4530 100644 --- a/src/client/views/nodes/DocumentView.tsx +++ b/src/client/views/nodes/DocumentView.tsx @@ -196,7 +196,7 @@ export class DocumentView extends DocComponent(Docu ScriptBox.EditButtonScript("On Button Clicked ...", this.props.Document, "onClick", e.clientX, e.clientY); } else if (this.props.Document.isButton === "Selector") { // this should be moved to an OnClick script FormattedTextBoxComment.Hide(); - this.Document.links?.[0] instanceof Doc && (Doc.UserDoc().SelectedDocs = new List([Doc.LinkOtherAnchor(this.Document.links[0]!, this.props.Document)])); + this.Document.links?.[0] instanceof Doc && (Doc.UserDoc().SelectedDocs = new List([Doc.LinkOtherAnchor(this.Document.links[0], this.props.Document)])); } else if (this.Document.isButton) { SelectionManager.SelectDoc(this, e.ctrlKey); // don't think this should happen if a button action is actually triggered. this.buttonClick(e.altKey, e.ctrlKey); diff --git a/src/new_fields/Doc.ts b/src/new_fields/Doc.ts index d4634ba4b..26acfa9c3 100644 --- a/src/new_fields/Doc.ts +++ b/src/new_fields/Doc.ts @@ -405,7 +405,7 @@ export namespace Doc { } export function MakeAlias(doc: Doc) { const alias = !GetT(doc, "isPrototype", "boolean", true) ? Doc.MakeCopy(doc) : Doc.MakeDelegate(doc); - let layout = Doc.Layout(alias); + const layout = Doc.Layout(alias); if (layout instanceof Doc && layout !== alias) { Doc.SetLayout(alias, Doc.MakeAlias(layout)); } @@ -755,7 +755,7 @@ export namespace Doc { const modifiers = docFilters[i + 2]; const scriptText = `${modifiers === "x" ? "!" : ""}matchFieldValue(doc, "${key}", "${value}")`; docFilterText = docFilterText ? docFilterText + " || " + scriptText : scriptText; - }; + } return docFilterText ? "(" + docFilterText + ")" : ""; } } @@ -781,7 +781,7 @@ Scripting.addGlobal(function matchFieldValue(doc: Doc, key: string, value: any) if (StrCast(fieldVal, null) !== undefined) return StrCast(fieldVal) === value; if (NumCast(fieldVal, null) !== undefined) return NumCast(fieldVal) === value; if (Cast(fieldVal, listSpec("string"), []).length) { - let vals = Cast(fieldVal, listSpec("string"), []); + const vals = Cast(fieldVal, listSpec("string"), []); return vals.some(v => v === value); } return false; -- cgit v1.2.3-70-g09d2 From c9a1e2dbff70bf7033aaef6d5f468f43ee726aae Mon Sep 17 00:00:00 2001 From: Sam Wilkins Date: Wed, 15 Jan 2020 16:25:47 -0500 Subject: almost nothing --- src/client/views/CollectionMulticolumnView.tsx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src/client/views/CollectionMulticolumnView.tsx') diff --git a/src/client/views/CollectionMulticolumnView.tsx b/src/client/views/CollectionMulticolumnView.tsx index 0aa615ffc..3231c0da1 100644 --- a/src/client/views/CollectionMulticolumnView.tsx +++ b/src/client/views/CollectionMulticolumnView.tsx @@ -47,14 +47,14 @@ export default class CollectionMulticolumnView extends CollectionSubView(Multico
{this.configuration.map(config => { - const { target } = config; + const { target, columnWidth } = config; if (target instanceof Doc) { let computedWidth: number = 0; - const widthSpecifier = Cast(config.columnWidth, "number"); + const widthSpecifier = Cast(columnWidth, "number"); let matches: RegExpExecArray | null; if (widthSpecifier !== undefined) { computedWidth = widthSpecifier; - } else if ((matches = /([\d.]+)\%/.exec(StrCast(config.columnWidth))) !== null) { + } else if ((matches = /([\d.]+)\%/.exec(StrCast(columnWidth))) !== null) { computedWidth = Number(matches[1]) / 100 * PanelWidth(); } return (!computedWidth ? (null) : -- cgit v1.2.3-70-g09d2