diff options
-rw-r--r-- | src/client/util/DragManager.ts | 8 | ||||
-rw-r--r-- | src/client/views/StyleProvider.tsx | 29 | ||||
-rw-r--r-- | src/client/views/collections/CollectionView.tsx | 6 | ||||
-rw-r--r-- | src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx | 48 | ||||
-rw-r--r-- | src/client/views/collections/collectionFreeForm/MarqueeView.tsx | 25 | ||||
-rw-r--r-- | src/client/views/nodes/CollectionFreeFormDocumentView.tsx | 2 | ||||
-rw-r--r-- | src/client/views/nodes/DocumentView.tsx | 5 |
7 files changed, 90 insertions, 33 deletions
diff --git a/src/client/util/DragManager.ts b/src/client/util/DragManager.ts index bebdc8bb2..d24348746 100644 --- a/src/client/util/DragManager.ts +++ b/src/client/util/DragManager.ts @@ -213,7 +213,7 @@ export namespace DragManager { }; const finishDrag = (e: DragCompleteEvent) => { const docDragData = e.docDragData; - if (dropEvent) dropEvent(); // glr: optional additional function to be called - in this case with presentation trails + dropEvent?.(); // glr: optional additional function to be called - in this case with presentation trails if (docDragData && !docDragData.droppedDocuments.length) { docDragData.dropAction = dragData.userDropAction || dragData.dropAction; docDragData.droppedDocuments = @@ -344,6 +344,9 @@ export namespace DragManager { dragDiv.appendChild(dragLabel); DragManager.Root().appendChild(dragDiv); } + dragDiv.style.width = ""; + dragDiv.style.height = ""; + dragDiv.style.overflow = ""; dragDiv.hidden = false; const scaleXs: number[] = []; const scaleYs: number[] = []; @@ -544,6 +547,9 @@ export namespace DragManager { return ret; }); dragDiv.hidden = true; + dragDiv.style.width = "0"; + dragDiv.style.height = "0"; + dragDiv.style.overflow = "hidden"; const target = document.elementFromPoint(e.x, e.y); removed.map(r => { r.ele.style.width = r.w; diff --git a/src/client/views/StyleProvider.tsx b/src/client/views/StyleProvider.tsx index 912d718cf..3389095b8 100644 --- a/src/client/views/StyleProvider.tsx +++ b/src/client/views/StyleProvider.tsx @@ -91,7 +91,7 @@ export function DefaultStyleProvider(doc: Opt<Doc>, props: Opt<FieldViewProps | const backColor = backgroundCol() || "black"; const col = Color(backColor).rgb(); const colsum = (col.red() + col.green() + col.blue()); - if (colsum / col.alpha() > 600 || col.alpha() < 0.25) return "black"; + if (colsum / col.alpha() > 400 || col.alpha() < 0.25) return "black"; return "white"; case StyleProp.Hidden: return BoolCast(doc?._hidden, BoolCast(doc?.hidden)); case StyleProp.BorderRounding: return StrCast(doc?._borderRounding, StrCast(doc?.borderRounding)); @@ -119,13 +119,14 @@ export function DefaultStyleProvider(doc: Opt<Doc>, props: Opt<FieldViewProps | case DocumentType.BUTTON: docColor = docColor || (darkScheme() ? "#2d2d2d" : "lightgray"); break; case DocumentType.LINK: return "transparent"; case DocumentType.COL: - docColor = docColor || - (Doc.IsSystem(doc) ? (darkScheme() ? "rgb(62,62,62)" : "lightgrey") : - isBackground() ? "cyan" : - doc.annotationOn ? "#00000015" : - StrCast((props?.renderDepth || 0) > 0 ? - Doc.UserDoc().activeCollectionNestedBackground : - Doc.UserDoc().activeCollectionBackground)); + docColor = docColor ? docColor : + doc?._isGroup ? "#00000004" : + (Doc.IsSystem(doc) ? (darkScheme() ? "rgb(62,62,62)" : "lightgrey") : + isBackground() ? "cyan" : + doc.annotationOn ? "#00000015" : + StrCast((props?.renderDepth || 0) > 0 ? + Doc.UserDoc().activeCollectionNestedBackground : + Doc.UserDoc().activeCollectionBackground)); break; //if (doc._viewType !== CollectionViewType.Freeform && doc._viewType !== CollectionViewType.Time) return "rgb(62,62,62)"; default: docColor = darkScheme() ? "black" : "white"; break; @@ -135,18 +136,18 @@ export function DefaultStyleProvider(doc: Opt<Doc>, props: Opt<FieldViewProps | } case StyleProp.BoxShadow: { if (!doc || opacity() === 0) return undefined; // if it's not visible, then no shadow) - const backgroundHalo = (doc: Doc) => props?.ContainingCollectionDoc?._useClusters || NumCast(doc.group, -1) !== -1; if (doc?.isLinkButton && doc.type !== DocumentType.LINK) return StrCast(doc?._linkButtonShadow, "lightblue 0em 0em 1em"); switch (doc?.type) { - case DocumentType.COL: return isBackground() ? undefined : - `${darkScheme() ? "rgb(30, 32, 31) " : "#9c9396 "} ${StrCast(doc.boxShadow, "0.2vw 0.2vw 0.8vw")}`; + case DocumentType.COL: return StrCast(doc?.boxShadow, isBackground() || (doc?._isGroup && !SnappingManager.GetIsDragging()) ? undefined : + `${darkScheme() ? "rgb(30, 32, 31) " : "#9c9396 "} ${StrCast(doc.boxShadow, "0.2vw 0.2vw 0.8vw")}`); default: return doc.z ? `#9c9396 ${StrCast(doc?.boxShadow, "10px 10px 0.9vw")}` : // if it's a floating doc, give it a big shadow - backgroundHalo(doc) && doc.type !== DocumentType.INK ? (`${backgroundCol()} ${StrCast(doc.boxShadow, `0vw 0vw ${(isBackground() ? 100 : 50) / (docProps?.ContentScaling?.() || 1)}px`)}`) : // if it's just in a cluster, make the shadown roughly match the cluster border extent - isBackground() ? undefined : // if it's a background & has a cluster color, make the shadow spread really big - StrCast(doc.boxShadow, ""); + props?.ContainingCollectionDoc?._useClusters && doc.type !== DocumentType.INK ? (`${backgroundCol()} ${StrCast(doc.boxShadow, `0vw 0vw ${(isBackground() ? 100 : 50) / (docProps?.ContentScaling?.() || 1)}px`)}`) : // if it's just in a cluster, make the shadown roughly match the cluster border extent + NumCast(doc.group, -1) !== -1 && doc.type !== DocumentType.INK ? (`gray ${StrCast(doc.boxShadow, `0vw 0vw ${(isBackground() ? 100 : 50) / (docProps?.ContentScaling?.() || 1)}px`)}`) : // if it's just in a cluster, make the shadown roughly match the cluster border extent + isBackground() ? undefined : // if it's a background & has a cluster color, make the shadow spread really big + StrCast(doc.boxShadow, ""); } } case StyleProp.PointerEvents: diff --git a/src/client/views/collections/CollectionView.tsx b/src/client/views/collections/CollectionView.tsx index 04edc3d09..8c0cdba07 100644 --- a/src/client/views/collections/CollectionView.tsx +++ b/src/client/views/collections/CollectionView.tsx @@ -40,6 +40,7 @@ import { CollectionTreeView } from "./CollectionTreeView"; import './CollectionView.scss'; import { ScriptField } from '../../../fields/ScriptField'; import { StyleProp } from '../StyleProvider'; +import { SnappingManager } from '../../util/SnappingManager'; export const COLLECTION_BORDER_WIDTH = 2; const path = require('path'); @@ -108,6 +109,7 @@ export class CollectionView extends Touchable<CollectionViewProps> { active = (outsideReaction?: boolean) => (this.props.isSelected(outsideReaction) || this.props.rootSelected(outsideReaction) || this.props.Document.forceActive || + this.props.Document._isGroup || this._isChildActive || this.props.renderDepth === 0) ? true : @@ -385,10 +387,8 @@ export class CollectionView extends Touchable<CollectionViewProps> { ScreenToLocalTransform: this.screenToLocalTransform, CollectionView: this, }; - const boxShadow = Doc.UserDoc().renderStyle === "comic" || this.props.Document.treeViewOutlineMode || this.collectionViewType === CollectionViewType.Linear ? undefined : - this.props.styleProvider?.(this.props.Document, this.props, StyleProp.BoxShadow); return (<div className={"collectionView"} onContextMenu={this.onContextMenu} - style={{ pointerEvents: this.props.layerProvider?.(this.props.Document) === false ? "none" : undefined, boxShadow }}> + style={{ pointerEvents: (this.props.Document._isGroup && !SnappingManager.GetIsDragging()) ? "all" : this.props.layerProvider?.(this.props.Document) === false ? "none" : undefined }}> {this.showIsTagged()} {this.collectionViewType !== undefined ? this.SubView(this.collectionViewType, props) : (null)} {this.lightbox(DocListCast(this.props.Document[this.props.fieldKey]).filter(d => Cast(d.data, ImageField, null)).map(d => diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx index d17e87db4..9cc459495 100644 --- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx +++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx @@ -1,4 +1,4 @@ -import { action, computed, IReactionDisposer, observable, ObservableMap, reaction, runInAction } from "mobx"; +import { action, computed, IReactionDisposer, observable, ObservableMap, reaction, runInAction, trace } from "mobx"; import { observer } from "mobx-react"; import { computedFn } from "mobx-utils"; import { Doc, DocListCast, HeightSym, Opt, WidthSym, StrListCast } from "../../../../fields/Doc"; @@ -31,9 +31,9 @@ import { COLLECTION_BORDER_WIDTH } from "../../../views/globalCssVariables.scss" import { Timeline } from "../../animationtimeline/Timeline"; import { ContextMenu } from "../../ContextMenu"; import { ActiveArrowEnd, ActiveArrowStart, ActiveDash, ActiveFillColor, ActiveInkBezierApprox, ActiveInkColor, ActiveInkWidth } from "../../InkingStroke"; -import { CollectionFreeFormDocumentView } from "../../nodes/CollectionFreeFormDocumentView"; +import { CollectionFreeFormDocumentView, CollectionFreeFormDocumentViewProps } from "../../nodes/CollectionFreeFormDocumentView"; import { DocumentLinksButton } from "../../nodes/DocumentLinksButton"; -import { DocumentViewProps, DocAfterFocusFunc } from "../../nodes/DocumentView"; +import { DocumentViewProps, DocAfterFocusFunc, DocumentView } from "../../nodes/DocumentView"; import { FormattedTextBox } from "../../nodes/formattedText/FormattedTextBox"; import { pageSchema } from "../../nodes/ImageBox"; import { PresBox } from "../../nodes/PresBox"; @@ -220,8 +220,28 @@ export class CollectionFreeFormView extends CollectionSubView<PanZoomDocument, P return (pt => super.onExternalDrop(e, { x: pt[0], y: pt[1] }))(this.getTransform().transformPoint(e.pageX, e.pageY)); } + updateGroupBounds = () => { + if (!this.props.Document._isGroup) return; + const clist = this.childDocs.map(cd => ({ x: NumCast(cd.x), y: NumCast(cd.y), width: cd[WidthSym](), height: cd[HeightSym]() })); + const cbounds = aggregateBounds(clist, 0, 0); + const c = [NumCast(this.layoutDoc.x) + this.layoutDoc[WidthSym]() / 2, NumCast(this.layoutDoc.y) + this.layoutDoc[HeightSym]() / 2]; + const p = [NumCast(this.layoutDoc._panX), NumCast(this.layoutDoc._panY)]; + const pbounds = { + x: (cbounds.x - p[0]) * this.zoomScaling() + c[0], y: (cbounds.y - p[1]) * this.zoomScaling() + c[1], + r: (cbounds.r - p[0]) * this.zoomScaling() + c[0], b: (cbounds.b - p[1]) * this.zoomScaling() + c[1] + }; + + this.layoutDoc._width = (pbounds.r - pbounds.x); + this.layoutDoc._height = (pbounds.b - pbounds.y); + this.layoutDoc._panX = (cbounds.r + cbounds.x) / 2; + this.layoutDoc._panY = (cbounds.b + cbounds.y) / 2; + this.layoutDoc.x = pbounds.x; + this.layoutDoc.y = pbounds.y; + } + @action internalDocDrop(e: Event, de: DragManager.DropEvent, docDragData: DragManager.DocumentDragData, xp: number, yp: number) { + if (!this.ChildDrag && this.props.Document._isGroup) return false; if (!super.onInternalDrop(e, de)) return false; const refDoc = docDragData.droppedDocuments[0]; const [xpo, ypo] = this.getTransformOverlay().transformPoint(de.x, de.y); @@ -252,6 +272,8 @@ export class CollectionFreeFormView extends CollectionSubView<PanZoomDocument, P !StrListCast(d.layers).includes(StyleLayers.Background) && (d._raiseWhenDragged === undefined ? Doc.UserDoc()._raiseWhenDragged : d._raiseWhenDragged) && (d.zIndex = zsorted.length + 1 + i); // bringToFront } + this.updateGroupBounds(); + (docDragData.droppedDocuments.length === 1 || de.shiftKey) && this.updateClusterDocs(docDragData.droppedDocuments); return true; } @@ -422,7 +444,7 @@ export class CollectionFreeFormView extends CollectionSubView<PanZoomDocument, P set && set.filter(s => !StrListCast(s.layers).includes(StyleLayers.Background)).map(s => styleProp = StrCast(s.backgroundColor)); set && set.filter(s => StrListCast(s.layers).includes(StyleLayers.Background)).map(s => styleProp = StrCast(s.backgroundColor)); } - } else if (doc && NumCast(doc.group, -1) !== -1) styleProp = "gray"; + } //else if (doc && NumCast(doc.group, -1) !== -1) styleProp = "gray"; return styleProp; } @@ -654,6 +676,7 @@ export class CollectionFreeFormView extends CollectionSubView<PanZoomDocument, P return; } if (!e.cancelBubble) { + if (this.props.Document._isGroup) return; if (Doc.GetSelectedTool() === InkTool.None) { if (this.tryDragCluster(e, this._hitCluster)) { e.stopPropagation(); // doesn't actually stop propagation since all our listeners are listening to events on 'document' however it does mark the event as cancelBubble=true which we test for in the move event handlers @@ -987,6 +1010,7 @@ export class CollectionFreeFormView extends CollectionSubView<PanZoomDocument, P pw && ph && (this.Document[this.scaleFieldKey] = scale * Math.min(pw / NumCast(doc._width), ph / NumCast(doc._height))); } + @observable ChildDrag: DocumentView | undefined; onChildClickHandler = () => this.props.childClickScript || ScriptCast(this.Document.onChildClick); onChildDoubleClickHandler = () => this.props.childDoubleClickScript || ScriptCast(this.Document.onChildDoubleClick); parentActive = (outsideReaction: boolean) => this.props.active(outsideReaction) || this.props.parentActive?.(outsideReaction) || this.backgroundActive || this.layoutDoc._viewType === CollectionViewType.Pile ? true : false; @@ -1165,6 +1189,7 @@ export class CollectionFreeFormView extends CollectionSubView<PanZoomDocument, P key={entry[1].pair.layout[Id] + (entry[1].replica || "")} {...this.getChildDocumentViewProps(entry[1].pair.layout, entry[1].pair.data)} replica={entry[1].replica} + CollectionFreeFormView={this} dataProvider={this.childDataProvider} sizeProvider={this.childSizeProvider} layerProvider={this.props.layerProvider} @@ -1202,6 +1227,7 @@ export class CollectionFreeFormView extends CollectionSubView<PanZoomDocument, P } })); } + //this.updateGroupBounds(); this._marqueeRef.current?.addEventListener("dashDragAutoScroll", this.onDragAutoScroll as any); } @@ -1307,7 +1333,7 @@ export class CollectionFreeFormView extends CollectionSubView<PanZoomDocument, P !this.props.isAnnotationOverlay && !Doc.UserDoc().noviceMode && 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: "Ungroup 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" }); this.props.renderDepth && optionItems.push({ description: "Use Background Color as Default", event: () => Cast(Doc.UserDoc().emptyCollection, Doc, null)._backgroundColor = StrCast(this.layoutDoc._backgroundColor), icon: "palette" }); if (!Doc.UserDoc().noviceMode) { @@ -1468,6 +1494,7 @@ export class CollectionFreeFormView extends CollectionSubView<PanZoomDocument, P @computed get marqueeView() { return <MarqueeView {...this.props} + ungroup={this.props.Document._isGroup ? this.promoteCollection : undefined} nudge={this.isAnnotationOverlay || this.props.renderDepth > 0 ? undefined : this.nudge} addDocTab={this.addDocTab} trySelectCluster={this.trySelectCluster} @@ -1547,6 +1574,17 @@ export class CollectionFreeFormView extends CollectionSubView<PanZoomDocument, P {this._vLines?.map(l => <line y1="0" x1={l} y2="1000" x2={l} stroke="black" />)} </svg> </div>} + + {this.ChildDrag && this.props.Document._isGroup ? + <div className="collectionFreeForm-groupDropper" ref={this.createDashEventsTarget} style={{ + width: "10000", + height: "10000", + left: "-5000", + top: "-5000", + position: "absolute", + background: "#0009930", + pointerEvents: "all" + }} /> : (null)} </div >; } } diff --git a/src/client/views/collections/collectionFreeForm/MarqueeView.tsx b/src/client/views/collections/collectionFreeForm/MarqueeView.tsx index f1f190bff..0ab20fea2 100644 --- a/src/client/views/collections/collectionFreeForm/MarqueeView.tsx +++ b/src/client/views/collections/collectionFreeForm/MarqueeView.tsx @@ -38,6 +38,7 @@ interface MarqueeViewProps { isSelected: () => boolean; trySelectCluster: (addToSel: boolean) => boolean; nudge?: (x: number, y: number) => boolean; + ungroup?: () => void; setPreviewCursor?: (func: (x: number, y: number, drag: boolean) => void) => void; } @observer @@ -93,7 +94,11 @@ export class MarqueeView extends React.Component<SubCollectionViewProps & Marque cm.displayMenu(this._downX, this._downY); e.stopPropagation(); } else - if (e.key === ":") { + if (e.key === "u" && this.props.ungroup) { + e.stopPropagation(); + this.props.ungroup(); + } + else if (e.key === ":") { DocUtils.addDocumentCreatorMenuItems(this.props.addLiveTextDocument, this.props.addDocument || returnFalse, x, y); cm.displayMenu(this._downX, this._downY); @@ -341,8 +346,8 @@ export class MarqueeView extends React.Component<SubCollectionViewProps & Marque this.hideMarquee(); } - getCollection = action((selected: Doc[], creator: Opt<(documents: Array<Doc>, options: DocumentOptions, id?: string) => Doc>, layers: string[]) => { - const newCollection = creator ? creator(selected, { title: "nested stack", }) : ((doc: Doc) => { + getCollection = action((selected: Doc[], creator: Opt<(documents: Array<Doc>, options: DocumentOptions, id?: string) => Doc>, layers: string[], makeGroup: Opt<boolean>) => { + const newCollection = creator ? creator(selected, { title: makeGroup ? "grouping" : "nested stack", }) : ((doc: Doc) => { Doc.GetProto(doc).data = new List<Doc>(selected); Doc.GetProto(doc).title = "nested freeform"; doc._panX = doc._panY = 0; @@ -352,6 +357,7 @@ export class MarqueeView extends React.Component<SubCollectionViewProps & Marque newCollection.layers = new List<string>(layers); newCollection._width = this.Bounds.width; newCollection._height = this.Bounds.height; + newCollection._isGroup = makeGroup; newCollection.x = this.Bounds.left; newCollection.y = this.Bounds.top; selected.forEach(d => d.context = newCollection); @@ -410,9 +416,9 @@ export class MarqueeView extends React.Component<SubCollectionViewProps & Marque @undoBatch @action - collection = (e: KeyboardEvent | React.PointerEvent | undefined) => { + collection = (e: KeyboardEvent | React.PointerEvent | undefined, group?: boolean) => { const selected = this.marqueeSelect(false); - if (e instanceof KeyboardEvent ? e.key === "c" : true) { + if (e instanceof KeyboardEvent ? "cg".includes(e.key) : true) { selected.map(action(d => { const dx = NumCast(d.x); const dy = NumCast(d.y); @@ -426,7 +432,7 @@ export class MarqueeView extends React.Component<SubCollectionViewProps & Marque })); this.props.removeDocument?.(selected); } - const newCollection = this.getCollection(selected, (e as KeyboardEvent)?.key === "t" ? Docs.Create.StackingDocument : undefined, []); + const newCollection = this.getCollection(selected, (e as KeyboardEvent)?.key === "t" ? Docs.Create.StackingDocument : undefined, [], group); this.props.addDocument?.(newCollection); this.props.selectDocuments([newCollection]); MarqueeOptionsMenu.Instance.fadeOut(true); @@ -523,7 +529,7 @@ export class MarqueeView extends React.Component<SubCollectionViewProps & Marque @action background = (e: KeyboardEvent | React.PointerEvent | undefined) => { - const newCollection = this.getCollection([], undefined, [StyleLayers.Background]); + const newCollection = this.getCollection([], undefined, [StyleLayers.Background], undefined); this.props.addDocument?.(newCollection); MarqueeOptionsMenu.Instance.fadeOut(true); this.hideMarquee(); @@ -542,11 +548,12 @@ export class MarqueeView extends React.Component<SubCollectionViewProps & Marque this.delete(); e.stopPropagation(); } - if ("cbtsSp".indexOf(e.key) !== -1) { + if ("cbtsSpg".indexOf(e.key) !== -1) { this._commandExecuted = true; e.stopPropagation(); e.preventDefault(); (e as any).propagationIsStopped = true; + if (e.key === "g") this.collection(e, true); if (e.key === "c" || e.key === "t") this.collection(e); if (e.key === "s" || e.key === "S") this.summary(e); if (e.key === "b") this.background(e); @@ -634,7 +641,7 @@ export class MarqueeView extends React.Component<SubCollectionViewProps & Marque render() { return <div className="marqueeView" - style={{ overflow: !this.props.ContainingCollectionView && this.props.isAnnotationOverlay ? "visible" : StrCast(this.props.Document._overflow), cursor: MarqueeView.DragMarquee && this ? "crosshair" : "hand" }} + style={{ overflow: this.props.Document._isGroup || (!this.props.ContainingCollectionView && this.props.isAnnotationOverlay) ? "visible" : StrCast(this.props.Document._overflow), cursor: MarqueeView.DragMarquee && this ? "crosshair" : "hand" }} onDragOver={e => e.preventDefault()} onScroll={(e) => e.currentTarget.scrollTop = e.currentTarget.scrollLeft = 0} onClick={this.onClick} onPointerDown={this.onPointerDown}> {this._visible ? this.marqueeDiv : null} diff --git a/src/client/views/nodes/CollectionFreeFormDocumentView.tsx b/src/client/views/nodes/CollectionFreeFormDocumentView.tsx index a06dd530b..a9bcf17e2 100644 --- a/src/client/views/nodes/CollectionFreeFormDocumentView.tsx +++ b/src/client/views/nodes/CollectionFreeFormDocumentView.tsx @@ -16,6 +16,7 @@ import "./CollectionFreeFormDocumentView.scss"; import { DocumentView, DocumentViewProps } from "./DocumentView"; import { FieldViewProps } from "./FieldView"; import React = require("react"); +import { CollectionFreeFormView } from "../collections/collectionFreeForm/CollectionFreeFormView"; export interface CollectionFreeFormDocumentViewProps extends DocumentViewProps { dataProvider?: (doc: Doc, replica: string) => { x: number, y: number, zIndex?: number, opacity?: number, highlight?: boolean, z: number, transition?: string } | undefined; @@ -26,6 +27,7 @@ export interface CollectionFreeFormDocumentViewProps extends DocumentViewProps { jitterRotation: number; dataTransition?: string; replica: string; + CollectionFreeFormView: CollectionFreeFormView; } @observer diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx index eb1807a71..5909fceb5 100644 --- a/src/client/views/nodes/DocumentView.tsx +++ b/src/client/views/nodes/DocumentView.tsx @@ -338,6 +338,8 @@ export class DocumentViewInternal extends DocComponent<DocumentViewInternalProps startDragging(x: number, y: number, dropAction: dropActionType) { if (this._mainCont.current) { + const ffview = this.props.CollectionFreeFormDocumentView; + ffview && runInAction(() => (ffview().props.CollectionFreeFormView.ChildDrag = this.props.DocumentView)); const dragData = new DragManager.DocumentDragData([this.props.Document]); const [left, top] = this.props.ScreenToLocalTransform().scale(this.ContentScale).inverse().transformPoint(0, 0); dragData.offset = this.props.ScreenToLocalTransform().scale(this.ContentScale).transformDirection(x - left, y - top); @@ -345,7 +347,8 @@ export class DocumentViewInternal extends DocComponent<DocumentViewInternalProps dragData.treeViewDoc = this.props.treeViewDoc; dragData.removeDocument = this.props.removeDocument; dragData.moveDocument = this.props.moveDocument; - DragManager.StartDocumentDrag([this._mainCont.current], dragData, x, y, { hideSource: !dropAction && !this.layoutDoc.onDragStart }); + DragManager.StartDocumentDrag([this._mainCont.current], dragData, x, y, { hideSource: !dropAction && !this.layoutDoc.onDragStart }, + () => setTimeout(action(() => ffview && (ffview().props.CollectionFreeFormView.ChildDrag = undefined)))); // this needs to happen after the drop event is processed. } } onKeyDown = (e: React.KeyboardEvent) => { |