From 84c15417f2247fc650a9f7b2c959479519bd3ebb Mon Sep 17 00:00:00 2001 From: bobzel Date: Wed, 1 Nov 2023 23:54:49 -0400 Subject: fixes to snapping lines when dragging/resizing (lines are created for doc not being dragged, snapping lines are created for documents in groups). cleanup of pres path code. --- .../collectionFreeForm/CollectionFreeFormView.tsx | 98 +++++++++------------- 1 file changed, 38 insertions(+), 60 deletions(-) (limited to 'src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx') diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx index a8b743896..0c3033579 100644 --- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx +++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx @@ -16,7 +16,7 @@ import { BoolCast, Cast, DocCast, FieldValue, NumCast, ScriptCast, StrCast } fro import { ImageField } from '../../../../fields/URLField'; import { TraceMobx } from '../../../../fields/util'; import { GestureUtils } from '../../../../pen-gestures/GestureUtils'; -import { aggregateBounds, DashColor, emptyFunction, intersectRect, lightOrDark, returnFalse, returnNone, returnZero, setupMoveUpEvents, Utils } from '../../../../Utils'; +import { aggregateBounds, DashColor, emptyFunction, intersectRect, lightOrDark, returnFalse, returnZero, setupMoveUpEvents, Utils } from '../../../../Utils'; import { CognitiveServices } from '../../../cognitive_services/CognitiveServices'; import { Docs, DocUtils } from '../../../documents/Documents'; import { CollectionViewType, DocumentType } from '../../../documents/DocumentTypes'; @@ -118,8 +118,6 @@ export class CollectionFreeFormView extends CollectionSubView { - return (pt => super.onExternalDrop(e, { x: pt[0], y: pt[1] }))(this.getTransform().transformPoint(e.pageX, e.pageY)); - }; + onExternalDrop = (e: React.DragEvent) => (([x, y]) => super.onExternalDrop(e, { x, y }))(this.getTransform().transformPoint(e.pageX, e.pageY)); pickCluster(probe: number[]) { return this.childLayoutPairs @@ -1820,9 +1816,6 @@ export class CollectionFreeFormView extends CollectionSubView SnappingManager.SetShowSnapLines(!SnappingManager.GetShowSnapLines()), icon: 'compress-arrows-alt' }) - : null; !Doc.noviceMode ? viewCtrlItems.push({ description: (this.Document._freeform_useClusters ? 'Hide' : 'Show') + ' Clusters', event: () => this.updateClusters(!this.Document._freeform_useClusters), icon: 'braille' }) : null; !viewctrls && ContextMenu.Instance.addItem({ description: 'UI Controls...', subitems: viewCtrlItems, icon: 'eye' }); @@ -1858,23 +1851,38 @@ export class CollectionFreeFormView extends CollectionSubView { + dragEnding = () => { + this.GroupChildDrag = false; + SnappingManager.clearSnapLines(); + }; + @action + dragStarting = (snapToDraggedDoc: boolean = false, showGroupDragTarget: boolean, visited = new Set()) => { + if (visited.has(this.rootDoc)) return; + visited.add(this.rootDoc); + showGroupDragTarget && (this.GroupChildDrag = BoolCast(this.Document._isGroup)); + if (this.rootDoc._isGroup && this.props.CollectionFreeFormDocumentView?.().props.CollectionFreeFormView) { + this.props.CollectionFreeFormDocumentView?.().props.CollectionFreeFormView.dragStarting(snapToDraggedDoc, false, visited); + } const activeDocs = this.getActiveDocuments(); 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 }) => intersectRect(docDims(doc), rect); - const otherBounds = { left: this.panX(), top: this.panY(), width: Math.abs(size[0]), height: Math.abs(size[1]) }; - let snappableDocs = activeDocs.filter(doc => 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 snappableDocs = activeDocs.filter(doc => doc.z === undefined && isDocInView(doc, selRect)); // first see if there are any foreground docs to snap to + activeDocs.forEach( + doc => + doc._isGroup && + SnappingManager.GetIsResizing() !== doc && + !DragManager.docsBeingDragged.includes(doc) && + (DocumentManager.Instance.getDocumentView(doc)?.ComponentView as CollectionFreeFormView)?.dragStarting(snapToDraggedDoc, false, visited) + ); const horizLines: number[] = []; const vertLines: number[] = []; const invXf = this.getTransform().inverse(); snappableDocs - .filter(doc => snapToDraggedDoc || !DragManager.docsBeingDragged.includes(Cast(doc.rootDocument, Doc, null) || doc)) + .filter(doc => !doc._isGroup && (snapToDraggedDoc || (SnappingManager.GetIsResizing() !== doc && !DragManager.docsBeingDragged.includes(doc)))) .forEach(doc => { const { left, top, width, height } = docDims(doc); const topLeftInScreen = invXf.transformPoint(left, top); @@ -1883,7 +1891,7 @@ export class CollectionFreeFormView extends CollectionSubView this.childDocs.filter(doc => !this._renderCutoffData.get(doc[Id])).length !== 0; @@ -1913,7 +1921,6 @@ export class CollectionFreeFormView extends CollectionSubView (CollectionFreeFormView.ShowPresPaths ? PresBox.Instance.getPaths(this.rootDoc) : null); brushedView = () => this._brushedView; gridColor = () => DashColor(lightOrDark(this.props.styleProvider?.(this.layoutDoc, this.props, StyleProp.BackgroundColor))) @@ -1921,7 +1928,9 @@ export class CollectionFreeFormView extends CollectionSubView {this.children} @@ -2028,7 +2036,7 @@ export class CollectionFreeFormView extends CollectionSubView e.preventDefault()} onContextMenu={this.onContextMenu} style={{ @@ -2065,18 +2073,9 @@ export class CollectionFreeFormView extends CollectionSubView ) : ( <> - {this._firstRender ? this.placeholder : this.marqueeView} + {this.marqueeView} {this.props.noOverlay ? null : } - -
- - {(this._hLines ?? []) - .map(l => ) // - .concat((this._vLines ?? []).map(l => )) ?? []} - -
- - {this.GroupChildDrag ?
: null} + {!this.GroupChildDrag ? null :
} )}
@@ -2104,7 +2103,6 @@ interface CollectionFreeFormViewPannableContentsProps { children?: React.ReactNode | undefined; transition?: string; isAnnotationOverlay: boolean | undefined; - presPaths: () => JSX.Element | null; transform: () => string; brushedView: () => { panX: number; panY: number; width: number; height: number } | undefined; } @@ -2112,41 +2110,21 @@ interface CollectionFreeFormViewPannableContentsProps { @observer class CollectionFreeFormViewPannableContents extends React.Component { @computed get presPaths() { - return !this.props.presPaths() ? null : ( - <> -
{PresBox.Instance?.orderedPathLabels(this.props.rootDoc)}
- - - - - - - - - - - - - {this.props.presPaths()} - - - ); + return CollectionFreeFormView.ShowPresPaths ? PresBox.Instance.pathLines(this.props.rootDoc) : null; } // rectangle highlight used when following trail/link to a region of a collection that isn't a document - @computed get brushedView() { - const brushedView = this.props.brushedView(); - return !brushedView ? null : ( + showViewport = (viewport: { panX: number; panY: number; width: number; height: number } | undefined) => + !viewport ? null : (
); - } render() { return ( @@ -2165,7 +2143,7 @@ class CollectionFreeFormViewPannableContents extends React.Component {this.props.children} {this.presPaths} - {this.brushedView} + {this.showViewport(this.props.brushedView())}
); } -- cgit v1.2.3-70-g09d2