From f9f7e0aac784d3b32c5adab04d8ec5d7807b0390 Mon Sep 17 00:00:00 2001 From: bobzel Date: Thu, 10 Dec 2020 23:11:46 -0500 Subject: a little refactoring in CollecftionFreeFormView --- .../collectionFreeForm/CollectionFreeFormView.tsx | 95 ++++++++-------------- 1 file changed, 35 insertions(+), 60 deletions(-) (limited to 'src') diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx index 1b6cfbd21..75411b3c5 100644 --- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx +++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx @@ -1,7 +1,7 @@ import { action, computed, IReactionDisposer, observable, ObservableMap, reaction, runInAction } from "mobx"; import { observer } from "mobx-react"; import { computedFn } from "mobx-utils"; -import { Doc, DocListCast, HeightSym, Opt, WidthSym } from "../../../../fields/Doc"; +import { Doc, DocListCast, HeightSym, Opt, WidthSym, StrListCast } from "../../../../fields/Doc"; import { collectionSchema, documentSchema } from "../../../../fields/documentSchemas"; import { Id } from "../../../../fields/FieldSymbols"; import { InkData, InkField, InkTool } from "../../../../fields/InkField"; @@ -80,6 +80,8 @@ export type collectionFreeformViewProps = { @observer export class CollectionFreeFormView extends CollectionSubView>(PanZoomDocument) { + public get displayName() { return "CollectionFreeFormView(" + this.props.Document.title?.toString() + ")"; } // this makes mobx trace() statements more descriptive + private _lastX: number = 0; private _lastY: number = 0; private _downX: number = 0; @@ -94,18 +96,22 @@ export class CollectionFreeFormView extends CollectionSubView(); private _layoutSizeData = new ObservableMap(); private _cachedPool: Map = new Map(); + private _lastTap = 0; + private _nudgeTime = 0; + private _thumbIdentifier?: number; + + @observable private _hLines: number[] | undefined; + @observable private _vLines: number[] | undefined; @observable private _pullCoords: number[] = [0, 0]; @observable private _pullDirection: string = ""; + @observable private _showAnimTimeline = false; - public get displayName() { return "CollectionFreeFormView(" + this.props.Document.title?.toString() + ")"; } // this makes mobx trace() statements more descriptive @observable.shallow _layoutElements: ViewDefResult[] = []; // shallow because some layout items (eg pivot labels) are just generated 'divs' and can't be frozen as observables @observable _clusterSets: (Doc[])[] = []; @observable _timelineRef = React.createRef(); - @observable _marqueeRef = React.createRef(); - @observable canPanX: boolean = true; - @observable canPanY: boolean = true; + @computed get backgroundActive() { return this.props.layerProvider?.(this.layoutDoc) === false && (this.props.ContainingCollectionView?.active() || this.props.active()); } @computed get fitToContentScaling() { return this.fitToContent ? NumCast(this.layoutDoc.fitToContentScaling, 1) : 1; } @computed get fitToContent() { return (this.props.fitToBox || this.Document._fitToBox) && !this.isAnnotationOverlay; } @computed get parentScaling() { return this.props.ContentScaling && this.fitToContent ? this.props.ContentScaling() : 1; } @@ -154,6 +160,7 @@ export class CollectionFreeFormView extends CollectionSubView { let retVal = false; if (newBox instanceof Doc) { @@ -303,6 +310,7 @@ export class CollectionFreeFormView extends CollectionSubView { if (e.nativeEvent.cancelBubble || InteractionUtils.IsType(e, InteractionUtils.TOUCHTYPE) || InteractionUtils.IsType(e, InteractionUtils.PENTYPE) || (Doc.GetSelectedTool() === InkTool.Highlighter || Doc.GetSelectedTool() === InkTool.Pen)) { @@ -595,8 +602,6 @@ export class CollectionFreeFormView extends CollectionSubView { if (InteractionUtils.IsType(e, InteractionUtils.TOUCHTYPE)) return; @@ -768,7 +773,6 @@ export class CollectionFreeFormView extends CollectionSubView { let deltaScale = deltaY > 0 ? (1 / 1.05) : 1.05; @@ -981,7 +984,6 @@ export class CollectionFreeFormView extends CollectionSubView this.props.childClickScript || ScriptCast(this.Document.onChildClick); onChildDoubleClickHandler = () => this.props.childDoubleClickScript || ScriptCast(this.Document.onChildDoubleClick); // @ts-ignore @@ -1047,6 +1049,7 @@ export class CollectionFreeFormView extends CollectionSubView - @action onDragAutoScroll = (e: CustomEvent) => { if ((e as any).handlePan || this.props.isAnnotationOverlay) return; @@ -1254,7 +1255,6 @@ export class CollectionFreeFormView extends CollectionSubView { const docs = this.childLayoutPairs; @@ -1288,8 +1288,6 @@ export class CollectionFreeFormView extends CollectionSubView { if (this.props.isAnnotationOverlay || this.props.Document.annotationOn || !ContextMenu.Instance) return; @@ -1304,7 +1302,6 @@ export class CollectionFreeFormView extends CollectionSubView Doc.UserDoc().showSnapLines = !Doc.UserDoc().showSnapLines, icon: "compress-arrows-alt" }) : null; !Doc.UserDoc().noviceMode ? viewCtrlItems.push({ description: (this.Document._useClusters ? "Hide" : "Show") + " Clusters", event: () => this.updateClusters(!this.Document._useClusters), icon: "braille" }) : null; !viewctrls && ContextMenu.Instance.addItem({ description: "UI Controls...", subitems: viewCtrlItems, icon: "eye" }); @@ -1312,7 +1309,7 @@ export class CollectionFreeFormView extends CollectionSubView this.showTimeline = !this.showTimeline), icon: "eye" }); + optionItems.push({ description: (this._showAnimTimeline ? "Close" : "Open") + " Animation Timeline", event: action(() => this._showAnimTimeline = !this._showAnimTimeline), icon: "eye" }); this.props.ContainingCollectionView && optionItems.push({ description: "Move Items Out of Collection", event: this.promoteCollection, icon: "table" }); optionItems.push({ description: this.layoutDoc._lockedTransform ? "Unlock Transform" : "Lock Transform", event: this.toggleLockTransform, icon: this.layoutDoc._lockedTransform ? "unlock" : "lock" }); @@ -1320,7 +1317,6 @@ export class CollectionFreeFormView extends CollectionSubView this.Document._freeformLOD = !this.Document._freeformLOD, icon: "table" }); - } !options && ContextMenu.Instance.addItem({ description: "Options...", subitems: optionItems, icon: "eye" }); const mores = ContextMenu.Instance.findByDescription("More..."); @@ -1349,11 +1345,10 @@ export class CollectionFreeFormView extends CollectionSubView { + setTimeout(() => SearchUtil.Search(`{!join from=id to=proto_i}id:link*`, true, {}).then(docs => { docs.docs.forEach(d => LinkManager.Instance.addLink(d)); - }); - }, 2000); // need to give solr some time to update so that this query will find any link docs we've added. + }), 2000); // need to give solr some time to update so that this query will find any link docs we've added. } } } @@ -1361,57 +1356,38 @@ export class CollectionFreeFormView extends CollectionSubView r1.left + r1.width || r2.left + r2.width < r1.left || r2.top > r1.top + r1.height || r2.top + r2.height < r1.top); - } - @action setupDragLines = (snapToDraggedDoc: boolean = false) => { const activeDocs = this.getActiveDocuments(); - if (activeDocs.length > 50) { - DragManager.SetSnapLines([], []); - return; - } const size = this.getTransform().transformDirection(this.props.PanelWidth(), this.props.PanelHeight()); const selRect = { left: this.panX() - size[0] / 2, top: this.panY() - size[1] / 2, width: size[0], height: size[1] }; const docDims = (doc: Doc) => ({ left: NumCast(doc.x), top: NumCast(doc.y), width: NumCast(doc._width), height: NumCast(doc._height) }); - const isDocInView = (doc: Doc, rect: { left: number, top: number, width: number, height: number }) => { - if (this.intersectRect(docDims(doc), rect)) { - snappableDocs.push(doc); - } - }; - const snappableDocs: Doc[] = []; // the set of documents in the visible viewport that we will try to snap to; + const isDocInView = (doc: Doc, rect: { left: number, top: number, width: number, height: number }) => intersectRect(docDims(doc), rect); + const otherBounds = { left: this.panX(), top: this.panY(), width: Math.abs(size[0]), height: Math.abs(size[1]) }; - this.getActiveDocuments().filter(doc => !Cast(doc.layers, listSpec("string"), []).includes("background") && doc.z === undefined).map(doc => isDocInView(doc, selRect)); // first see if there are any foreground docs to snap to - !snappableDocs.length && this.getActiveDocuments().filter(doc => doc.z === undefined).map(doc => isDocInView(doc, selRect)); // if not, see if there are background docs to snap to - !snappableDocs.length && this.getActiveDocuments().filter(doc => doc.z !== undefined).map(doc => isDocInView(doc, otherBounds)); // if not, then why not snap to floating docs + let snappableDocs = activeDocs.filter(doc => !StrListCast(doc.layers).includes("background") && doc.z === undefined && isDocInView(doc, selRect)); // first see if there are any foreground docs to snap to + !snappableDocs.length && (snappableDocs = activeDocs.filter(doc => doc.z === undefined && isDocInView(doc, selRect))); // if not, see if there are background docs to snap to + !snappableDocs.length && (snappableDocs = activeDocs.filter(doc => doc.z !== undefined && isDocInView(doc, otherBounds))); // if not, then why not snap to floating docs const horizLines: number[] = []; const vertLines: number[] = []; + const invXf = this.getTransform().inverse(); snappableDocs.filter(doc => snapToDraggedDoc || !DragManager.docsBeingDragged.includes(Cast(doc.rootDocument, Doc, null) || doc)).forEach(doc => { const { left, top, width, height } = docDims(doc); - const topLeftInScreen = this.getTransform().inverse().transformPoint(left, top); - const docSize = this.getTransform().inverse().transformDirection(width, height); + const topLeftInScreen = invXf.transformPoint(left, top); + const docSize = invXf.transformDirection(width, height); horizLines.push(topLeftInScreen[1], topLeftInScreen[1] + docSize[1] / 2, topLeftInScreen[1] + docSize[1]); // horiz center line vertLines.push(topLeftInScreen[0], topLeftInScreen[0] + docSize[0] / 2, topLeftInScreen[0] + docSize[0]);// right line }); DragManager.SetSnapLines(horizLines, vertLines); } + onPointerOver = (e: React.PointerEvent) => { - if (SnappingManager.GetIsDragging()) { - this.setupDragLines(e.ctrlKey || e.shiftKey); - } + SnappingManager.GetIsDragging() && this.setupDragLines(e.ctrlKey || e.shiftKey); e.stopPropagation(); } - @observable private _hLines: number[] | undefined; - @observable private _vLines: number[] | undefined; - private childViews = () => { const children = typeof this.props.children === "function" ? (this.props.children as any)() as JSX.Element[] : []; return [ @@ -1426,13 +1402,13 @@ export class CollectionFreeFormView extends CollectionSubView); return eles; } + @computed get placeholder() { return
{this.props.Document.title?.toString()}
; } - _nudgeTime = 0; nudge = action((x: number, y: number) => { if (this.props.ContainingCollectionDoc?._viewType !== CollectionViewType.Freeform || this.props.ContainingCollectionDoc._panX !== undefined) { // bcz: this isn't ideal, but want to try it out... @@ -1450,7 +1426,7 @@ export class CollectionFreeFormView extends CollectionSubView; } + trySelectCluster = (addToSel: boolean) => { if (this._hitCluster !== -1) { - if (!addToSel) { - SelectionManager.DeselectAll(); - } + !addToSel && SelectionManager.DeselectAll(); const eles = this.childLayoutPairs.map(pair => pair.layout).filter(cd => (this.props.Document._useClusters ? NumCast(cd.cluster) : NumCast(cd.group, -1)) === this._hitCluster); this.selectDocuments(eles); return true; } return false; } + @computed get marqueeView() { return
- {this.layoutDoc["_backgroundGrid-show"] ? this.grid : (null)} + {this.layoutDoc["_backgroundGrid-show"] ? this.backgroundGrid : (null)}
- {this.showTimeline ? : (null)} + {this._showAnimTimeline ? : (null)}
; } - @computed get contentScaling() { if (this.props.isAnnotationOverlay && !this.props.forceScaling) return 0; const nw = returnVal(this.props.NativeWidth?.(), Doc.NativeWidth(this.Document)); -- cgit v1.2.3-70-g09d2