From 37324d134c8d788a73b8b1d35afa7ea6b0e88d37 Mon Sep 17 00:00:00 2001 From: Bob Zeleznik Date: Fri, 1 May 2020 12:47:51 -0400 Subject: cleaned up buxton template. fixed adding docs to collections. --- src/client/views/collections/CollectionStackingViewFieldColumn.tsx | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) (limited to 'src/client/views/collections/CollectionStackingViewFieldColumn.tsx') diff --git a/src/client/views/collections/CollectionStackingViewFieldColumn.tsx b/src/client/views/collections/CollectionStackingViewFieldColumn.tsx index 323d7be25..8a9539eb0 100644 --- a/src/client/views/collections/CollectionStackingViewFieldColumn.tsx +++ b/src/client/views/collections/CollectionStackingViewFieldColumn.tsx @@ -322,11 +322,7 @@ export class CollectionStackingViewFieldColumn extends React.Component + style={{ background: evContents !== `NO ${key.toUpperCase()} VALUE` ? this._color : "inherit" }}> {evContents === `NO ${key.toUpperCase()} VALUE` ? (null) :
-- cgit v1.2.3-70-g09d2 From 3d5bc514936ba804eaa24e9ca1f4619bcaf81eb5 Mon Sep 17 00:00:00 2001 From: Bob Zeleznik Date: Sun, 3 May 2020 23:59:35 -0400 Subject: extended documentBox's to support drag and drop of style. reorganized imports to avoid some cycles --- src/client/documents/Documents.ts | 10 +- src/client/util/DragManager.ts | 112 +++++++-------------- src/client/util/DropConverter.ts | 2 + src/client/util/SelectionManager.ts | 5 - src/client/views/DocumentDecorations.tsx | 5 +- src/client/views/MainView.tsx | 8 +- .../views/collections/CollectionDockingView.tsx | 5 +- .../collections/CollectionMasonryViewFieldRow.tsx | 2 +- .../views/collections/CollectionPileView.tsx | 5 +- .../views/collections/CollectionSchemaCells.tsx | 2 +- .../CollectionSchemaMovableTableHOC.tsx | 4 +- .../views/collections/CollectionStackingView.tsx | 4 +- .../CollectionStackingViewFieldColumn.tsx | 4 +- .../views/collections/CollectionTreeView.tsx | 4 +- .../CollectionFreeFormLinksView.tsx | 3 +- .../collectionFreeForm/CollectionFreeFormView.tsx | 6 +- src/client/views/linking/LinkMenuGroup.tsx | 4 +- src/client/views/linking/LinkMenuItem.tsx | 39 ++++++- src/client/views/nodes/AudioBox.tsx | 10 +- .../views/nodes/ContentFittingDocumentView.tsx | 8 +- src/client/views/nodes/DocumentBox.scss | 3 +- src/client/views/nodes/DocumentBox.tsx | 57 +++++++---- src/client/views/nodes/DocumentView.tsx | 2 +- src/client/views/nodes/QueryBox.tsx | 3 +- .../views/nodes/formattedText/FormattedTextBox.tsx | 13 ++- .../authentication/models/current_user_utils.ts | 27 +++-- 26 files changed, 189 insertions(+), 158 deletions(-) (limited to 'src/client/views/collections/CollectionStackingViewFieldColumn.tsx') diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts index 8ea8ded0f..45687f597 100644 --- a/src/client/documents/Documents.ts +++ b/src/client/documents/Documents.ts @@ -139,6 +139,7 @@ export interface DocumentOptions { ischecked?: ScriptField; // returns whether a font icon box is checked activePen?: Doc; // which pen document is currently active (used as the radio button state for the 'unhecked' pen tool scripts) onClick?: ScriptField; + onDoubleClick?: ScriptField; onChildClick?: ScriptField; // script given to children of a collection to execute when they are clicked onChildDoubleClick?: ScriptField; // script given to children of a collection to execute when they are double clicked onPointerDown?: ScriptField; @@ -493,7 +494,7 @@ export namespace Docs { const dataDoc = MakeDataDelegate(proto, protoProps, data, fieldKey); const viewDoc = Doc.MakeDelegate(dataDoc, delegId); - viewDoc.type !== DocumentType.LINK && AudioBox.ActiveRecordings.map(d => DocUtils.MakeLink({ doc: viewDoc }, { doc: d }, "audio link", "audio timeline")); + viewDoc.type !== DocumentType.LINK && DocUtils.MakeLinkToActiveAudio(viewDoc); return Doc.assign(viewDoc, delegateProps, true); } @@ -645,7 +646,7 @@ export namespace Docs { } export function DocumentDocument(document?: Doc, options: DocumentOptions = {}) { - return InstanceFromProto(Prototypes.get(DocumentType.DOCHOLDER), document, { title: document ? document.title + "" : "container", ...options }); + return InstanceFromProto(Prototypes.get(DocumentType.DOCHOLDER), document, { title: document ? document.title + "" : "container", targetDropAction: "move", ...options }); } export function FreeformDocument(documents: Array, options: DocumentOptions, id?: string) { @@ -1005,6 +1006,11 @@ export namespace DocUtils { }); } + export let ActiveRecordings: Doc[] = []; + + export function MakeLinkToActiveAudio(doc: Doc) { + DocUtils.ActiveRecordings.map(d => DocUtils.MakeLink({ doc: doc }, { doc: d }, "audio link", "audio timeline")); + } export function MakeLink(source: { doc: Doc }, target: { doc: Doc }, linkRelationship: string = "", id?: string) { const sv = DocumentManager.Instance.getDocumentView(source.doc); if (sv && sv.props.ContainingCollectionDoc === target.doc) return; diff --git a/src/client/util/DragManager.ts b/src/client/util/DragManager.ts index 041f2fc2c..d91eb60ef 100644 --- a/src/client/util/DragManager.ts +++ b/src/client/util/DragManager.ts @@ -1,26 +1,16 @@ -import { Doc, Field, DocListCast } from "../../new_fields/Doc"; -import { Cast, ScriptCast, StrCast, NumCast } from "../../new_fields/Types"; -import { emptyFunction } from "../../Utils"; -import { CollectionDockingView } from "../views/collections/CollectionDockingView"; -import * as globalCssVariables from "../views/globalCssVariables.scss"; -import { DocumentManager } from "./DocumentManager"; -import { LinkManager } from "./LinkManager"; -import { SelectionManager } from "./SelectionManager"; -import { SchemaHeaderField } from "../../new_fields/SchemaHeaderField"; -import { Docs, DocUtils } from "../documents/Documents"; -import { ScriptField } from "../../new_fields/ScriptField"; +import { action, observable, runInAction } from "mobx"; +import { DateField } from "../../new_fields/DateField"; +import { Doc, Field, Opt } from "../../new_fields/Doc"; import { List } from "../../new_fields/List"; import { PrefetchProxy } from "../../new_fields/Proxy"; import { listSpec } from "../../new_fields/Schema"; -import { Scripting } from "./Scripting"; -import { convertDropDataToButtons } from "./DropConverter"; -import { AudioBox } from "../views/nodes/AudioBox"; -import { DateField } from "../../new_fields/DateField"; -import { DocumentView } from "../views/nodes/DocumentView"; +import { SchemaHeaderField } from "../../new_fields/SchemaHeaderField"; +import { ScriptField } from "../../new_fields/ScriptField"; +import { Cast, NumCast, ScriptCast, StrCast } from "../../new_fields/Types"; +import { emptyFunction } from "../../Utils"; +import { Docs, DocUtils } from "../documents/Documents"; +import * as globalCssVariables from "../views/globalCssVariables.scss"; import { UndoManager } from "./UndoManager"; -import { PointData } from "../../new_fields/InkField"; -import { MainView } from "../views/MainView"; -import { action } from "mobx"; export type dropActionType = "alias" | "copy" | "move" | undefined; // undefined = move export function SetupDrag( @@ -56,10 +46,10 @@ export function SetupDrag( const onItemDown = async (e: React.PointerEvent) => { if (e.button === 0) { e.stopPropagation(); - if (e.shiftKey && CollectionDockingView.Instance) { + if (e.shiftKey) { e.persist(); const dragDoc = await docFunc(); - dragDoc && CollectionDockingView.Instance.StartOtherDrag({ + dragDoc && DragManager.Vals.Instance.StartWindowDrag?.({ pageX: e.pageX, pageY: e.pageY, preventDefault: emptyFunction, @@ -76,8 +66,19 @@ export function SetupDrag( export namespace DragManager { let dragDiv: HTMLDivElement; - export let horizSnapLines: number[] = []; - export let vertSnapLines: number[] = []; + export class Vals { + static Instance: Vals = new Vals(); + @observable public IsDragging: boolean = false; + @observable public horizSnapLines: number[] = []; + @observable public vertSnapLines: number[] = []; + public StartWindowDrag: Opt<((e: any, dragDocs: Doc[]) => void)> = undefined; + public SetIsDragging(dragging: boolean) { runInAction(() => this.IsDragging = dragging); } + public GetIsDragging() { return this.IsDragging; } + public clearSnapLines() { + this.vertSnapLines.length = 0; + this.horizSnapLines.length = 0; + } + } export function Root() { const root = document.getElementById("root"); @@ -215,7 +216,7 @@ export namespace DragManager { export function StartDocumentDrag(eles: HTMLElement[], dragData: DocumentDragData, downX: number, downY: number, options?: DragOptions) { const addAudioTag = (dropDoc: any) => { dropDoc && !dropDoc.creationDate && (dropDoc.creationDate = new DateField); - dropDoc instanceof Doc && AudioBox.ActiveRecordings.map(d => DocUtils.MakeLink({ doc: dropDoc }, { doc: d }, "audio link", "audio timeline")); + dropDoc instanceof Doc && DocUtils.MakeLinkToActiveAudio(dropDoc); return dropDoc; }; const batch = UndoManager.StartBatch("dragging"); @@ -246,40 +247,6 @@ export namespace DragManager { StartDrag(eles, new DragManager.DocumentDragData([]), downX, downY, options, finishDrag); } - // drag links and drop link targets (aliasing them if needed) - export async function StartLinkTargetsDrag(dragEle: HTMLElement, docView: DocumentView, downX: number, downY: number, sourceDoc: Doc, specificLinks?: Doc[]) { - const draggedDocs = (specificLinks ? specificLinks : DocListCast(sourceDoc.links)).map(link => LinkManager.Instance.getOppositeAnchor(link, sourceDoc)).filter(l => l) as Doc[]; - - if (draggedDocs.length) { - const moddrag: Doc[] = []; - for (const draggedDoc of draggedDocs) { - const doc = await Cast(draggedDoc.annotationOn, Doc); - if (doc) moddrag.push(doc); - } - - const dragData = new DragManager.DocumentDragData(moddrag.length ? moddrag : draggedDocs); - dragData.moveDocument = (doc: Doc, targetCollection: Doc | undefined, addDocument: (doc: Doc) => boolean): boolean => { - docView.props.removeDocument?.(doc); - addDocument(doc); - return true; - }; - const containingView = docView.props.ContainingCollectionView; - const finishDrag = (e: DragCompleteEvent) => - e.docDragData && (e.docDragData.droppedDocuments = - dragData.draggedDocuments.reduce((droppedDocs, d) => { - const dvs = DocumentManager.Instance.getDocumentViews(d).filter(dv => dv.props.ContainingCollectionView === containingView); - if (dvs.length) { - dvs.forEach(dv => droppedDocs.push(dv.props.Document)); - } else { - droppedDocs.push(Doc.MakeAlias(d)); - } - return droppedDocs; - }, [] as Doc[])); - - StartDrag([dragEle], dragData, downX, downY, undefined, finishDrag); - } - } - // drag&drop the pdf annotation anchor which will create a text note on drop via a dropCompleted() DragOption export function StartPdfAnnoDrag(eles: HTMLElement[], dragData: PdfAnnoDragData, downX: number, downY: number, options?: DragOptions) { StartDrag(eles, dragData, downX, downY, options); @@ -300,10 +267,8 @@ export namespace DragManager { } export function SetSnapLines(horizLines: number[], vertLines: number[]) { - horizSnapLines = horizLines; - vertSnapLines = vertLines; - MainView.Instance._hLines = horizLines; - MainView.Instance._vLines = vertLines; + DragManager.Vals.Instance.horizSnapLines.push(...horizLines); + DragManager.Vals.Instance.vertSnapLines.push(...vertLines); } export function snapDrag(e: PointerEvent, xFromLeft: number, yFromTop: number, xFromRight: number, yFromBottom: number) { @@ -320,10 +285,13 @@ export namespace DragManager { return drag; }; - return { thisX: snapVal([xFromLeft, xFromRight], e.pageX, vertSnapLines), thisY: snapVal([yFromTop, yFromBottom], e.pageY, horizSnapLines) }; + return { + thisX: snapVal([xFromLeft, xFromRight], e.pageX, DragManager.Vals.Instance.vertSnapLines), + thisY: snapVal([yFromTop, yFromBottom], e.pageY, DragManager.Vals.Instance.horizSnapLines) + }; } export let docsBeingDragged: Doc[] = []; - function StartDrag(eles: HTMLElement[], dragData: { [id: string]: any }, downX: number, downY: number, options?: DragOptions, finishDrag?: (dropData: DragCompleteEvent) => void) { + export function StartDrag(eles: HTMLElement[], dragData: { [id: string]: any }, downX: number, downY: number, options?: DragOptions, finishDrag?: (dropData: DragCompleteEvent) => void) { eles = eles.filter(e => e); if (!dragDiv) { dragDiv = document.createElement("div"); @@ -331,7 +299,7 @@ export namespace DragManager { dragDiv.style.pointerEvents = "none"; DragManager.Root().appendChild(dragDiv); } - SelectionManager.SetIsDragging(true); + DragManager.Vals.Instance.SetIsDragging(true); const scaleXs: number[] = []; const scaleYs: number[] = []; const xs: number[] = []; @@ -413,14 +381,14 @@ export namespace DragManager { if (dragData instanceof DocumentDragData) { dragData.userDropAction = e.ctrlKey && e.altKey ? "copy" : e.ctrlKey ? "alias" : undefined; } - if (e.shiftKey && CollectionDockingView.Instance && dragData.droppedDocuments.length === 1) { + 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)); - CollectionDockingView.Instance.StartOtherDrag({ + DragManager.Vals.Instance.StartWindowDrag?.({ pageX: e.pageX, pageY: e.pageY, preventDefault: emptyFunction, @@ -447,22 +415,19 @@ export namespace DragManager { const endDrag = action(() => { document.removeEventListener("pointermove", moveHandler, true); document.removeEventListener("pointerup", upHandler); - MainView.Instance._hLines = []; - MainView.Instance._vLines = []; - vertSnapLines.length = 0; - horizSnapLines.length = 0; + DragManager.Vals.Instance.clearSnapLines(); }); AbortDrag = () => { hideDragShowOriginalElements(); - SelectionManager.SetIsDragging(false); + DragManager.Vals.Instance.SetIsDragging(false); options?.dragComplete?.(new DragCompleteEvent(true, dragData)); endDrag(); }; const upHandler = (e: PointerEvent) => { hideDragShowOriginalElements(); dispatchDrag(eles, e, dragData, xFromLeft, yFromTop, xFromRight, yFromBottom, options, finishDrag); - SelectionManager.SetIsDragging(false); + DragManager.Vals.Instance.SetIsDragging(false); endDrag(); options?.dragComplete?.(new DragCompleteEvent(false, dragData)); }; @@ -520,4 +485,3 @@ export namespace DragManager { } } } -Scripting.addGlobal(function convertToButtons(dragData: any) { convertDropDataToButtons(dragData as DragManager.DocumentDragData); }); diff --git a/src/client/util/DropConverter.ts b/src/client/util/DropConverter.ts index b1993d401..d6db882b8 100644 --- a/src/client/util/DropConverter.ts +++ b/src/client/util/DropConverter.ts @@ -7,6 +7,7 @@ import { Docs } from "../documents/Documents"; import { ScriptField, ComputedField } from "../../new_fields/ScriptField"; import { RichTextField } from "../../new_fields/RichTextField"; import { ImageField } from "../../new_fields/URLField"; +import { Scripting } from "./Scripting"; // // converts 'doc' into a template that can be used to render other documents. @@ -75,3 +76,4 @@ export function convertDropDataToButtons(data: DragManager.DocumentDragData) { data.droppedDocuments[i] = dbox; }); } +Scripting.addGlobal(function convertToButtons(dragData: any) { convertDropDataToButtons(dragData as DragManager.DocumentDragData); }); \ No newline at end of file diff --git a/src/client/util/SelectionManager.ts b/src/client/util/SelectionManager.ts index a49977c42..d509168b6 100644 --- a/src/client/util/SelectionManager.ts +++ b/src/client/util/SelectionManager.ts @@ -8,10 +8,8 @@ export namespace SelectionManager { class Manager { - @observable IsDragging: boolean = false; SelectedDocuments: ObservableMap = new ObservableMap(); - @action SelectDoc(docView: DocumentView, ctrlPressed: boolean): void { // if doc is not in SelectedDocuments, add it @@ -78,9 +76,6 @@ export namespace SelectionManager { if (found) manager.SelectDoc(found, false); } - export function SetIsDragging(dragging: boolean) { runInAction(() => manager.IsDragging = dragging); } - export function GetIsDragging() { return manager.IsDragging; } - export function SelectedDocuments(): Array { return Array.from(manager.SelectedDocuments.keys()); } diff --git a/src/client/views/DocumentDecorations.tsx b/src/client/views/DocumentDecorations.tsx index 396fe12b5..f8e77d90a 100644 --- a/src/client/views/DocumentDecorations.tsx +++ b/src/client/views/DocumentDecorations.tsx @@ -364,8 +364,7 @@ export class DocumentDecorations extends React.Component<{}, { value: string }> this.Interacting = false; (e.button === 0) && this._resizeUndo?.end(); this._resizeUndo = undefined; - MainView.Instance._hLines = []; - MainView.Instance._vLines = []; + DragManager.Vals.Instance.clearSnapLines(); } @computed @@ -404,7 +403,7 @@ export class DocumentDecorations extends React.Component<{}, { value: string }> const darkScheme = Cast(Doc.UserDoc().activeWorkspace, Doc, null)?.darkScheme ? "dimgray" : undefined; const bounds = this.Bounds; const seldoc = SelectionManager.SelectedDocuments().length ? SelectionManager.SelectedDocuments()[0] : undefined; - if (SelectionManager.GetIsDragging() || bounds.r - bounds.x < 2 || bounds.x === Number.MAX_VALUE || !seldoc || this._hidden || isNaN(bounds.r) || isNaN(bounds.b) || isNaN(bounds.x) || isNaN(bounds.y)) { + if (DragManager.Vals.Instance.GetIsDragging() || bounds.r - bounds.x < 2 || bounds.x === Number.MAX_VALUE || !seldoc || this._hidden || isNaN(bounds.r) || isNaN(bounds.b) || isNaN(bounds.x) || isNaN(bounds.y)) { return (null); } const minimal = bounds.r - bounds.x < 100 ? true : false; diff --git a/src/client/views/MainView.tsx b/src/client/views/MainView.tsx index a29a6baac..71c2bf245 100644 --- a/src/client/views/MainView.tsx +++ b/src/client/views/MainView.tsx @@ -43,6 +43,7 @@ import PDFMenu from './pdf/PDFMenu'; import { PreviewCursor } from './PreviewCursor'; import { ScriptField } from '../../new_fields/ScriptField'; import { TimelineMenu } from './animationtimeline/TimelineMenu'; +import { DragManager } from '../util/DragManager'; @observer export class MainView extends React.Component { @@ -574,9 +575,6 @@ export class MainView extends React.Component { return this._mainViewRef; } - @observable public _hLines: any; - @observable public _vLines: any; - render() { return (
@@ -597,8 +595,8 @@ export class MainView extends React.Component { {// TO VIEW SNAP LINES
- {this._hLines?.map((l: any) => )} - {this._vLines?.map((l: any) => )} + {DragManager.Vals.Instance.horizSnapLines.map((l: any) => )} + {DragManager.Vals.Instance.vertSnapLines.map((l: any) => )}
} diff --git a/src/client/views/collections/CollectionDockingView.tsx b/src/client/views/collections/CollectionDockingView.tsx index 822f44f5a..33ece13cc 100644 --- a/src/client/views/collections/CollectionDockingView.tsx +++ b/src/client/views/collections/CollectionDockingView.tsx @@ -68,10 +68,11 @@ export class CollectionDockingView extends React.Component { let config: any; if (dragDocs.length === 1) { config = CollectionDockingView.makeDocumentConfig(dragDocs[0]); @@ -499,7 +500,7 @@ export class CollectionDockingView extends React.Component { - if (!this._isPointerDown || !SelectionManager.GetIsDragging()) return; + if (!this._isPointerDown || !DragManager.Vals.Instance.GetIsDragging()) return; const activeContentItem = tab.header.parent.getActiveContentItem(); if (tab.contentItem !== activeContentItem) { tab.header.parent.setActiveContentItem(tab.contentItem); diff --git a/src/client/views/collections/CollectionMasonryViewFieldRow.tsx b/src/client/views/collections/CollectionMasonryViewFieldRow.tsx index 7ad15ef41..c74cfbcf4 100644 --- a/src/client/views/collections/CollectionMasonryViewFieldRow.tsx +++ b/src/client/views/collections/CollectionMasonryViewFieldRow.tsx @@ -132,7 +132,7 @@ export class CollectionMasonryViewFieldRow extends React.Component SelectionManager.GetIsDragging() && (this._background = "#b4b4b4")); + pointerEnteredRow = action(() => DragManager.Vals.Instance.GetIsDragging() && (this._background = "#b4b4b4")); @action pointerLeaveRow = () => { diff --git a/src/client/views/collections/CollectionPileView.tsx b/src/client/views/collections/CollectionPileView.tsx index 8b8cbc6e8..0a10c24b3 100644 --- a/src/client/views/collections/CollectionPileView.tsx +++ b/src/client/views/collections/CollectionPileView.tsx @@ -12,6 +12,7 @@ import React = require("react"); import { setupMoveUpEvents, emptyFunction, returnFalse } from "../../../Utils"; import { SelectionManager } from "../../util/SelectionManager"; import { UndoManager } from "../../util/UndoManager"; +import { DragManager } from "../../util/DragManager"; @observer export class CollectionPileView extends CollectionSubView(doc => doc) { @@ -78,7 +79,7 @@ export class CollectionPileView extends CollectionSubView(doc => doc) { _undoBatch: UndoManager.Batch | undefined; pointerDown = (e: React.PointerEvent) => { let dist = 0; - SelectionManager.SetIsDragging(true); + DragManager.Vals.Instance.SetIsDragging(true); // this._lastTap should be set to 0, and this._doubleTap should be set to false in the class header setupMoveUpEvents(this, e, (e: PointerEvent, down: number[], delta: number[]) => { if (this.layoutEngine() === "pass" && this.childDocs.length && this.props.isSelected(true)) { @@ -98,7 +99,7 @@ export class CollectionPileView extends CollectionSubView(doc => doc) { }, () => { this._undoBatch?.end(); this._undoBatch = undefined; - SelectionManager.SetIsDragging(false); + DragManager.Vals.Instance.SetIsDragging(false); if (!this.childDocs.length) { this.props.ContainingCollectionView?.removeDocument(this.props.Document); } diff --git a/src/client/views/collections/CollectionSchemaCells.tsx b/src/client/views/collections/CollectionSchemaCells.tsx index 82204ca7b..0e6489947 100644 --- a/src/client/views/collections/CollectionSchemaCells.tsx +++ b/src/client/views/collections/CollectionSchemaCells.tsx @@ -189,7 +189,7 @@ export class CollectionSchemaCell extends React.Component { this._document[props.fieldKey] instanceof Doc ? "alias" : this.props.Document.schemaDoc ? "copy" : undefined)(e); }; const onPointerEnter = (e: React.PointerEvent): void => { - if (e.buttons === 1 && SelectionManager.GetIsDragging() && (type === "document" || type === undefined)) { + if (e.buttons === 1 && DragManager.Vals.Instance.GetIsDragging() && (type === "document" || type === undefined)) { dragRef.current!.className = "collectionSchemaView-cellContainer doc-drag-over"; } }; diff --git a/src/client/views/collections/CollectionSchemaMovableTableHOC.tsx b/src/client/views/collections/CollectionSchemaMovableTableHOC.tsx index 972714e34..f9cd9a628 100644 --- a/src/client/views/collections/CollectionSchemaMovableTableHOC.tsx +++ b/src/client/views/collections/CollectionSchemaMovableTableHOC.tsx @@ -32,7 +32,7 @@ export class MovableColumn extends React.Component { private _dragRef: React.RefObject = React.createRef(); onPointerEnter = (e: React.PointerEvent): void => { - if (e.buttons === 1 && SelectionManager.GetIsDragging()) { + if (e.buttons === 1 && DragManager.Vals.Instance.GetIsDragging()) { this._header!.current!.className = "collectionSchema-col-wrapper"; document.addEventListener("pointermove", this.onDragMove, true); } @@ -143,7 +143,7 @@ export class MovableRow extends React.Component { private _rowDropDisposer?: DragManager.DragDropDisposer; onPointerEnter = (e: React.PointerEvent): void => { - if (e.buttons === 1 && SelectionManager.GetIsDragging()) { + if (e.buttons === 1 && DragManager.Vals.Instance.GetIsDragging()) { this._header!.current!.className = "collectionSchema-row-wrapper"; document.addEventListener("pointermove", this.onDragMove, true); } diff --git a/src/client/views/collections/CollectionStackingView.tsx b/src/client/views/collections/CollectionStackingView.tsx index 1fd5c3f44..f6cdebc9b 100644 --- a/src/client/views/collections/CollectionStackingView.tsx +++ b/src/client/views/collections/CollectionStackingView.tsx @@ -312,7 +312,7 @@ export class CollectionStackingView extends CollectionSubView(StackingDocument) this.refList.push(ref); const doc = this.props.DataDoc && this.props.DataDoc.layout === this.layoutDoc ? this.props.DataDoc : this.layoutDoc; this.observer = new _global.ResizeObserver(action((entries: any) => { - if (this.props.Document._autoHeight && ref && this.refList.length && !SelectionManager.GetIsDragging()) { + if (this.props.Document._autoHeight && ref && this.refList.length && !DragManager.Vals.Instance.GetIsDragging()) { Doc.Layout(doc)._height = Math.min(1200, Math.max(...this.refList.map(r => Number(getComputedStyle(r).height.replace("px", ""))))); } })); @@ -359,7 +359,7 @@ export class CollectionStackingView extends CollectionSubView(StackingDocument) this.refList.push(ref); const doc = this.props.DataDoc && this.props.DataDoc.layout === this.layoutDoc ? this.props.DataDoc : this.layoutDoc; this.observer = new _global.ResizeObserver(action((entries: any) => { - if (this.props.Document._autoHeight && ref && this.refList.length && !SelectionManager.GetIsDragging()) { + if (this.props.Document._autoHeight && ref && this.refList.length && !DragManager.Vals.Instance.GetIsDragging()) { Doc.Layout(doc)._height = this.refList.reduce((p, r) => p + Number(getComputedStyle(r).height.replace("px", "")), 0); } })); diff --git a/src/client/views/collections/CollectionStackingViewFieldColumn.tsx b/src/client/views/collections/CollectionStackingViewFieldColumn.tsx index 8a9539eb0..1d16a5478 100644 --- a/src/client/views/collections/CollectionStackingViewFieldColumn.tsx +++ b/src/client/views/collections/CollectionStackingViewFieldColumn.tsx @@ -120,7 +120,7 @@ export class CollectionStackingViewFieldColumn extends React.Component { - if (SelectionManager.GetIsDragging()) { + if (DragManager.Vals.Instance.GetIsDragging()) { this._background = "#b4b4b4"; } } @@ -355,7 +355,7 @@ export class CollectionStackingViewFieldColumn extends React.Component diff --git a/src/client/views/collections/CollectionTreeView.tsx b/src/client/views/collections/CollectionTreeView.tsx index 6d6f8d316..288fa8794 100644 --- a/src/client/views/collections/CollectionTreeView.tsx +++ b/src/client/views/collections/CollectionTreeView.tsx @@ -147,7 +147,7 @@ class TreeView extends React.Component { onPointerEnter = (e: React.PointerEvent): void => { this.props.active(true) && Doc.BrushDoc(this.dataDoc); - if (e.buttons === 1 && SelectionManager.GetIsDragging()) { + if (e.buttons === 1 && DragManager.Vals.Instance.GetIsDragging()) { this._header!.current!.className = "treeViewItem-header"; document.addEventListener("pointermove", this.onDragMove, true); } @@ -451,7 +451,7 @@ class TreeView extends React.Component { fontWeight: this.props.document.searchMatch ? "bold" : undefined, textDecoration: Doc.GetT(this.props.document, "title", "string", true) ? "underline" : undefined, outline: BoolCast(this.props.document.workspaceBrush) ? "dashed 1px #06123232" : undefined, - pointerEvents: this.props.active() || SelectionManager.GetIsDragging() ? undefined : "none" + pointerEvents: this.props.active() || DragManager.Vals.Instance.GetIsDragging() ? undefined : "none" }} > {Doc.GetT(this.props.document, "editTitle", "boolean", true) ? this.editableView("title") : diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinksView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinksView.tsx index 7df1e909f..0873fd1bb 100644 --- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinksView.tsx +++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinksView.tsx @@ -10,6 +10,7 @@ import React = require("react"); import { Utils, emptyFunction } from "../../../../Utils"; import { SelectionManager } from "../../../util/SelectionManager"; import { DocumentType } from "../../../documents/DocumentTypes"; +import { DragManager } from "../../../util/DragManager"; @observer export class CollectionFreeFormLinksView extends React.Component { @@ -36,7 +37,7 @@ export class CollectionFreeFormLinksView extends React.Component { } render() { - return SelectionManager.GetIsDragging() ? (null) :
+ return DragManager.Vals.Instance.GetIsDragging() ? (null) :
{this.uniqueConnections} diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx index 411fbd9e2..b2401e69e 100644 --- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx +++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx @@ -1174,7 +1174,7 @@ export class CollectionFreeFormView extends CollectionSubView { - if (SelectionManager.GetIsDragging()) { + if (DragManager.Vals.Instance.GetIsDragging()) { this.setupDragLines(); } e.stopPropagation(); @@ -1233,7 +1233,7 @@ export class CollectionFreeFormView extends CollectionSubView { document.removeEventListener("pointerup", this.onLinkButtonUp); const targets = this.props.group.map(l => LinkManager.Instance.getOppositeAnchor(l, this.props.sourceDoc)).filter(d => d) as Doc[]; - DragManager.StartLinkTargetsDrag(this._drag.current, this.props.docView, e.x, e.y, this.props.sourceDoc, targets); + StartLinkTargetsDrag(this._drag.current, this.props.docView, e.x, e.y, this.props.sourceDoc, targets); } e.stopPropagation(); } diff --git a/src/client/views/linking/LinkMenuItem.tsx b/src/client/views/linking/LinkMenuItem.tsx index d091e06ef..d4e58fa8e 100644 --- a/src/client/views/linking/LinkMenuItem.tsx +++ b/src/client/views/linking/LinkMenuItem.tsx @@ -3,7 +3,7 @@ import { faArrowRight, faChevronDown, faChevronUp, faEdit, faEye, faTimes } from import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; import { action, observable } from 'mobx'; import { observer } from "mobx-react"; -import { Doc } from '../../../new_fields/Doc'; +import { Doc, DocListCast } from '../../../new_fields/Doc'; import { Cast, StrCast } from '../../../new_fields/Types'; import { DragManager } from '../../util/DragManager'; import { LinkManager } from '../../util/LinkManager'; @@ -26,6 +26,41 @@ interface LinkMenuItemProps { addDocTab: (document: Doc, where: string) => boolean; } +// drag links and drop link targets (aliasing them if needed) +export async function StartLinkTargetsDrag(dragEle: HTMLElement, docView: DocumentView, downX: number, downY: number, sourceDoc: Doc, specificLinks?: Doc[]) { + const draggedDocs = (specificLinks ? specificLinks : DocListCast(sourceDoc.links)).map(link => LinkManager.Instance.getOppositeAnchor(link, sourceDoc)).filter(l => l) as Doc[]; + + if (draggedDocs.length) { + const moddrag: Doc[] = []; + for (const draggedDoc of draggedDocs) { + const doc = await Cast(draggedDoc.annotationOn, Doc); + if (doc) moddrag.push(doc); + } + + const dragData = new DragManager.DocumentDragData(moddrag.length ? moddrag : draggedDocs); + dragData.moveDocument = (doc: Doc, targetCollection: Doc | undefined, addDocument: (doc: Doc) => boolean): boolean => { + docView.props.removeDocument?.(doc); + addDocument(doc); + return true; + }; + const containingView = docView.props.ContainingCollectionView; + const finishDrag = (e: DragManager.DragCompleteEvent) => + e.docDragData && (e.docDragData.droppedDocuments = + dragData.draggedDocuments.reduce((droppedDocs, d) => { + const dvs = DocumentManager.Instance.getDocumentViews(d).filter(dv => dv.props.ContainingCollectionView === containingView); + if (dvs.length) { + dvs.forEach(dv => droppedDocs.push(dv.props.Document)); + } else { + droppedDocs.push(Doc.MakeAlias(d)); + } + return droppedDocs; + }, [] as Doc[])); + + DragManager.StartDrag([dragEle], dragData, downX, downY, undefined, finishDrag); + } +} + + @observer export class LinkMenuItem extends React.Component { private _drag = React.createRef(); @@ -83,7 +118,7 @@ export class LinkMenuItem extends React.Component { document.removeEventListener("pointerup", this.onLinkButtonUp); this._eleClone.style.transform = `translate(${e.x}px, ${e.y}px)`; - DragManager.StartLinkTargetsDrag(this._eleClone, this.props.docView, e.x, e.y, this.props.sourceDoc, [this.props.linkDoc]); + StartLinkTargetsDrag(this._eleClone, this.props.docView, e.x, e.y, this.props.sourceDoc, [this.props.linkDoc]); } e.stopPropagation(); } diff --git a/src/client/views/nodes/AudioBox.tsx b/src/client/views/nodes/AudioBox.tsx index 3feb533a0..1c5e13620 100644 --- a/src/client/views/nodes/AudioBox.tsx +++ b/src/client/views/nodes/AudioBox.tsx @@ -17,10 +17,9 @@ import { ContextMenu } from "../ContextMenu"; import { Id } from "../../../new_fields/FieldSymbols"; import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; import { DocumentView } from "./DocumentView"; -import { Docs } from "../../documents/Documents"; +import { Docs, DocUtils } from "../../documents/Documents"; import { ComputedField } from "../../../new_fields/ScriptField"; import { Networking } from "../../Network"; -import { Upload } from "../../../server/SharedMediaTypes"; import { LinkAnchorBox } from "./LinkAnchorBox"; // testing testing @@ -57,7 +56,6 @@ export class AudioBox extends ViewBoxBaseComponent { runInAction(() => AudioBox._scrubTime = 0); runInAction(() => AudioBox._scrubTime = timeInMillisFrom1970); }; - public static ActiveRecordings: Doc[] = []; @computed get recordingStart() { return Cast(this.dataDoc[this.props.fieldKey + "-recordingStart"], DateField)?.date.getTime(); } async slideTemplate() { return (await Cast((await Cast(Doc.UserDoc().slidesBtn, Doc) as Doc).dragFactory, Doc) as Doc); } @@ -145,7 +143,7 @@ export class AudioBox extends ViewBoxBaseComponent { const [{ result }] = await Networking.UploadFilesToServer(e.data); if (!(result instanceof Error)) { @@ -172,8 +170,8 @@ export class AudioBox extends ViewBoxBaseComponent { diff --git a/src/client/views/nodes/ContentFittingDocumentView.tsx b/src/client/views/nodes/ContentFittingDocumentView.tsx index 3c2c6c87e..1c6250b94 100644 --- a/src/client/views/nodes/ContentFittingDocumentView.tsx +++ b/src/client/views/nodes/ContentFittingDocumentView.tsx @@ -3,7 +3,7 @@ import { computed } from "mobx"; import { observer } from "mobx-react"; import "react-table/react-table.css"; import { Doc, Opt, WidthSym, HeightSym } from "../../../new_fields/Doc"; -import { NumCast, StrCast } from "../../../new_fields/Types"; +import { NumCast, StrCast, Cast } from "../../../new_fields/Types"; import { TraceMobx } from "../../../new_fields/util"; import { emptyFunction, returnOne } from "../../../Utils"; import '../DocumentDecorations.scss'; @@ -14,7 +14,11 @@ import "./ContentFittingDocumentView.scss"; @observer export class ContentFittingDocumentView extends React.Component{ public get displayName() { return "DocumentView(" + this.props.Document?.title + ")"; } // this makes mobx trace() statements more descriptive - private get layoutDoc() { return this.props.LayoutTemplate?.() || Doc.Layout(this.props.Document); } + private get layoutDoc() { + return this.props.LayoutTemplate?.() || + (this.props.layoutKey && Doc.Layout(this.props.Document, Cast(this.props.Document[this.props.layoutKey], Doc, null))) || + Doc.Layout(this.props.Document); + } @computed get freezeDimensions() { return this.props.FreezeDimensions; } nativeWidth = () => NumCast(this.layoutDoc?._nativeWidth, this.props.NativeWidth?.() || (this.freezeDimensions && this.layoutDoc ? this.layoutDoc[WidthSym]() : this.props.PanelWidth())); nativeHeight = () => NumCast(this.layoutDoc?._nativeHeight, this.props.NativeHeight?.() || (this.freezeDimensions && this.layoutDoc ? this.layoutDoc[HeightSym]() : this.props.PanelHeight())); diff --git a/src/client/views/nodes/DocumentBox.scss b/src/client/views/nodes/DocumentBox.scss index ce21391ce..3a27c16c1 100644 --- a/src/client/views/nodes/DocumentBox.scss +++ b/src/client/views/nodes/DocumentBox.scss @@ -2,7 +2,8 @@ width: 100%; height: 100%; pointer-events: all; - background: gray; + background: rgb(241, 239, 235); + position: absolute; .documentBox-lock { margin: auto; color: white; diff --git a/src/client/views/nodes/DocumentBox.tsx b/src/client/views/nodes/DocumentBox.tsx index 8d422fe67..b53c7cfe6 100644 --- a/src/client/views/nodes/DocumentBox.tsx +++ b/src/client/views/nodes/DocumentBox.tsx @@ -1,23 +1,24 @@ import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; -import { IReactionDisposer, reaction, computed } from "mobx"; +import { action, IReactionDisposer, reaction } from "mobx"; import { observer } from "mobx-react"; import { Doc, Field } from "../../../new_fields/Doc"; -import { documentSchema, collectionSchema } from "../../../new_fields/documentSchemas"; +import { collectionSchema, documentSchema } from "../../../new_fields/documentSchemas"; import { makeInterface } from "../../../new_fields/Schema"; import { ComputedField } from "../../../new_fields/ScriptField"; import { Cast, NumCast, StrCast } from "../../../new_fields/Types"; +import { TraceMobx } from "../../../new_fields/util"; import { emptyPath, returnFalse, returnOne, returnZero } from "../../../Utils"; +import { DocumentType } from "../../documents/DocumentTypes"; +import { DragManager } from "../../util/DragManager"; +import { undoBatch } from "../../util/UndoManager"; import { ContextMenu } from "../ContextMenu"; import { ContextMenuProps } from "../ContextMenuItem"; import { ViewBoxAnnotatableComponent } from "../DocComponent"; import { ContentFittingDocumentView } from "./ContentFittingDocumentView"; import "./DocumentBox.scss"; +import { DocumentView } from "./DocumentView"; import { FieldView, FieldViewProps } from "./FieldView"; import React = require("react"); -import { TraceMobx } from "../../../new_fields/util"; -import { Docs } from "../../documents/Documents"; -import { KeyValueBox } from "./KeyValueBox"; -import { DocumentView } from "./DocumentView"; type DocHolderBoxSchema = makeInterface<[typeof documentSchema, typeof collectionSchema]>; const DocHolderBoxDocument = makeInterface(documentSchema, collectionSchema); @@ -26,7 +27,9 @@ const DocHolderBoxDocument = makeInterface(documentSchema, collectionSchema); export class DocHolderBox extends ViewBoxAnnotatableComponent(DocHolderBoxDocument) { public static LayoutString(fieldKey: string) { return FieldView.LayoutString(DocHolderBox, fieldKey); } _prevSelectionDisposer: IReactionDisposer | undefined; + _dropDisposer?: DragManager.DragDropDisposer; _selections: Doc[] = []; + _contRef = React.createRef(); _curSelection = -1; componentDidMount() { this._prevSelectionDisposer = reaction(() => this.layoutDoc[this.props.fieldKey], (data) => { @@ -101,21 +104,15 @@ export class DocHolderBox extends ViewBoxAnnotatableComponent(); pwidth = () => this.props.PanelWidth() - 2 * this.xPad; pheight = () => this.props.PanelHeight() - 2 * this.yPad; getTransform = () => this.props.ScreenToLocalTransform().translate(-this.xPad, -this.yPad); isActive = () => this.active() || !this.props.renderDepth; + layoutTemplateDoc = () => Cast(this.props.Document.childLayoutTemplate, Doc, null); get renderContents() { const containedDoc = Cast(this.dataDoc[this.props.fieldKey], Doc, null); - const childTemplateName = StrCast(this.layoutDoc.childTemplateName); - if (containedDoc && childTemplateName && !containedDoc["layout_" + childTemplateName]) { - setTimeout(() => { - Doc.createCustomView(containedDoc, Docs.Create.StackingDocument, childTemplateName); - Doc.expandTemplateLayout(Cast(containedDoc["layout_" + childTemplateName], Doc, null), containedDoc, undefined); - }, 0); - } - const contents = !(containedDoc instanceof Doc) ? (null) : this.layoutDoc.childLayoutString ? + const layoutTemplate = StrCast(this.layoutDoc.childLayoutString); + const contents = !(containedDoc instanceof Doc) ? (null) : this.layoutDoc.childLayoutString || this.layoutTemplateDoc() ? : @@ -150,8 +147,8 @@ export class DocHolderBox extends ViewBoxAnnotatableComponent {this.renderContents} -
; } + + @undoBatch + @action + drop = (e: Event, de: DragManager.DropEvent) => { + if (de.complete.docDragData) { + if (de.complete.docDragData.draggedDocuments[0].type === DocumentType.FONTICON) { + const doc = Cast(de.complete.docDragData.draggedDocuments[0].dragFactory, Doc, null); + this.props.Document.childLayoutTemplate = doc; + } + } + } + protected createDropTarget = (ele: HTMLDivElement) => { + this._dropDisposer?.(); + ele && (this._dropDisposer = DragManager.MakeDropTarget(ele, this.drop.bind(this), this.props.Document)); + } + } diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx index 7a16e8836..c4cd5978a 100644 --- a/src/client/views/nodes/DocumentView.tsx +++ b/src/client/views/nodes/DocumentView.tsx @@ -1102,7 +1102,7 @@ export class DocumentView extends DocComponent(Docu } @computed get ignorePointerEvents() { return this.props.pointerEvents === false || - (this.Document.isBackground && !this.isSelected() && !SelectionManager.GetIsDragging()) || + (this.Document.isBackground && !this.isSelected() && !DragManager.Vals.Instance.GetIsDragging()) || (this.Document.type === DocumentType.INK && InkingControl.Instance.selectedTool !== InkTool.None); } @undoBatch diff --git a/src/client/views/nodes/QueryBox.tsx b/src/client/views/nodes/QueryBox.tsx index 76885eada..d248b098c 100644 --- a/src/client/views/nodes/QueryBox.tsx +++ b/src/client/views/nodes/QueryBox.tsx @@ -11,6 +11,7 @@ import { SearchBox } from "../search/SearchBox"; import { FieldView, FieldViewProps } from './FieldView'; import "./QueryBox.scss"; import { List } from "../../../new_fields/List"; +import { DragManager } from "../../util/DragManager"; type QueryDocument = makeInterface<[typeof documentSchema]>; const QueryDocument = makeInterface(documentSchema); @@ -27,7 +28,7 @@ export class QueryBox extends ViewBoxAnnotatableComponent e.stopPropagation()} > m.type === this._editorView!.state.schema.marks.user_mark).map(m => AudioBox.SetScrubTime(Math.max(0, m.attrs.modified * 1000))); const curText = state.doc.textBetween(0, state.doc.content.size, " \n"); - const curTemp = Cast(this.props.Document[this.props.fieldKey + "-textTemplate"], RichTextField); - const curProto = Cast(Cast(this.dataDoc.proto, Doc, null)?.[this.fieldKey], RichTextField, null); + const curTemp = Cast(this.props.Document[this.props.fieldKey + "-textTemplate"], RichTextField); // the actual text in the text box + const curProto = Cast(Cast(this.dataDoc.proto, Doc, null)?.[this.fieldKey], RichTextField, null); // the default text inherited from a prototype + const curLayout = this.rootDoc !== this.layoutDoc ? Cast(this.layoutDoc[this.fieldKey], RichTextField, null) : undefined; // the default text stored in a layout template const json = JSON.stringify(state.toJSON()); if (!this._applyingChange && json.replace(/"selection":.*/, "") !== curProto?.Data.replace(/"selection":.*/, "")) { this._applyingChange = true; this.dataDoc[this.props.fieldKey + "-lastModified"] = new DateField(new Date(Date.now())); - if ((!curTemp && !curProto) || curText) { // if no template, or there's text, write it to the document. (if this is driven by a template, then this overwrites the template text which is intended) - this.dataDoc[this.props.fieldKey] = new RichTextField(json, curText); - this.dataDoc[this.props.fieldKey + "-noTemplate"] = (curTemp?.Text || "") !== curText; // mark the data field as being split from the template if it has been edited + if ((!curTemp && !curProto) || curText) { // if no template, or there's text that didn't come from the layout template, write it to the document. (if this is driven by a template, then this overwrites the template text which is intended) + if (curText !== curLayout?.Text) { + this.dataDoc[this.props.fieldKey] = new RichTextField(json, curText); + this.dataDoc[this.props.fieldKey + "-noTemplate"] = (curTemp?.Text || "") !== curText; // mark the data field as being split from the template if it has been edited + } } else { // if we've deleted all the text in a note driven by a template, then restore the template data this.dataDoc[this.props.fieldKey] = undefined; this._editorView.updateState(EditorState.fromJSON(this.config, JSON.parse((curProto || curTemp).Data))); diff --git a/src/server/authentication/models/current_user_utils.ts b/src/server/authentication/models/current_user_utils.ts index b63a3dbbf..bf99f449f 100644 --- a/src/server/authentication/models/current_user_utils.ts +++ b/src/server/authentication/models/current_user_utils.ts @@ -217,28 +217,29 @@ export class CurrentUserUtils { static setupDefaultIconTemplates(doc: Doc) { if (doc["template-icon-view"] === undefined) { const iconView = Docs.Create.TextDocument("", { - title: "icon", _width: 150, _height: 30, isTemplateDoc: true, - onClick: ScriptField.MakeScript("deiconifyView(self)") + title: "icon", _width: 150, _height: 30, isTemplateDoc: true, onDoubleClick: ScriptField.MakeScript("deiconifyView(self)") }); Doc.GetProto(iconView).icon = new RichTextField('{"doc":{"type":"doc","content":[{"type":"paragraph","attrs":{"align":null,"color":null,"id":null,"indent":null,"inset":null,"lineSpacing":null,"paddingBottom":null,"paddingTop":null},"content":[{"type":"dashField","attrs":{"fieldKey":"title","docid":""}}]}]},"selection":{"type":"text","anchor":2,"head":2},"storedMarks":[]}', ""); iconView.isTemplateDoc = makeTemplate(iconView); doc["template-icon-view"] = new PrefetchProxy(iconView); } if (doc["template-icon-view-rtf"] === undefined) { - const iconRtfView = Docs.Create.LabelDocument({ title: "icon_" + DocumentType.RTF, textTransform: "unset", letterSpacing: "unset", _width: 150, _height: 70, _xPadding: 10, _yPadding: 10, isTemplateDoc: true, onClick: ScriptField.MakeScript("deiconifyView(self)") }); + const iconRtfView = Docs.Create.LabelDocument({ + title: "icon_" + DocumentType.RTF, textTransform: "unset", letterSpacing: "unset", + _width: 150, _height: 70, _xPadding: 10, _yPadding: 10, isTemplateDoc: true, onDoubleClick: ScriptField.MakeScript("deiconifyView(self)") + }); iconRtfView.isTemplateDoc = makeTemplate(iconRtfView, true, "icon_" + DocumentType.RTF); doc["template-icon-view-rtf"] = new PrefetchProxy(iconRtfView); } if (doc["template-icon-view-img"] === undefined) { const iconImageView = Docs.Create.ImageDocument("http://www.cs.brown.edu/~bcz/face.gif", { - title: "data", _width: 50, isTemplateDoc: true, - onClick: ScriptField.MakeScript("deiconifyView(self)") + title: "data", _width: 50, isTemplateDoc: true, onDoubleClick: ScriptField.MakeScript("deiconifyView(self)") }); iconImageView.isTemplateDoc = makeTemplate(iconImageView, true, "icon_" + DocumentType.IMG); doc["template-icon-view-img"] = new PrefetchProxy(iconImageView); } if (doc["template-icon-view-col"] === undefined) { - const iconColView = Docs.Create.TreeDocument([], { title: "data", _width: 180, _height: 80, onClick: ScriptField.MakeScript("deiconifyView(self)") }); + const iconColView = Docs.Create.TreeDocument([], { title: "data", _width: 180, _height: 80, onDoubleClick: ScriptField.MakeScript("deiconifyView(self)") }); iconColView.isTemplateDoc = makeTemplate(iconColView, true, "icon_" + DocumentType.COL); doc["template-icon-view-col"] = new PrefetchProxy(iconColView); } @@ -265,9 +266,17 @@ export class CurrentUserUtils { doc.emptyCollection = Docs.Create.FreeformDocument([], { _nativeWidth: undefined, _nativeHeight: undefined, _LODdisable: true, _width: 150, _height: 100, title: "freeform" }); } + if (doc.emptyDocHolder === undefined) { + doc.emptyDocHolder = Docs.Create.DocumentDocument( + ComputedField.MakeFunction("selectedDocs(this,this.excludeCollections,[_last_])?.[0]") as any, + { _width: 250, _height: 250, title: "container" }); + } + if (doc.emptyWebpage === undefined) { + doc.emptyWebpage = Docs.Create.WebDocument("", { title: "New Webpage", _width: 600 }) + } return [ { title: "Drag a collection", label: "Col", icon: "folder", click: 'openOnRight(getCopy(this.dragFactory, true))', drag: 'getCopy(this.dragFactory, true)', dragFactory: doc.emptyCollection as Doc }, - { title: "Drag a web page", label: "Web", icon: "globe-asia", ignoreClick: true, drag: 'Docs.Create.WebDocument("", { title: "New Webpage" })' }, + { title: "Drag a web page", label: "Web", icon: "globe-asia", click: 'openOnRight(getCopy(this.dragFactory, true))', drag: 'getCopy(this.dragFactory, true)', dragFactory: doc.emptyWebpage as Doc }, { title: "Drag a cat image", label: "Img", icon: "cat", ignoreClick: true, drag: 'Docs.Create.ImageDocument("https://upload.wikimedia.org/wikipedia/commons/thumb/3/3a/Cat03.jpg/1200px-Cat03.jpg", { _width: 250, _nativeWidth:250, title: "an image of a cat" })' }, { title: "Drag a screenshot", label: "Grab", icon: "photo-video", ignoreClick: true, drag: 'Docs.Create.ScreenshotDocument("", { _width: 400, _height: 200, title: "screen snapshot" })' }, { title: "Drag a webcam", label: "Cam", icon: "video", ignoreClick: true, drag: 'Docs.Create.WebCamDocument("", { _width: 400, _height: 400, title: "a test cam" })' }, @@ -284,7 +293,7 @@ export class CurrentUserUtils { // { title: "use stamp", icon: "stamp", click: 'activateStamp(this.activePen.inkPen = sameDocs(this.activePen.inkPen, this) ? undefined : this)', backgroundColor: "orange", ischecked: `sameDocs(this.activePen.inkPen, this)`, activePen: doc }, // { title: "use eraser", icon: "eraser", click: 'activateEraser(this.activePen.inkPen = sameDocs(this.activePen.inkPen, this) ? undefined : this);', ischecked: `sameDocs(this.activePen.inkPen, this)`, backgroundColor: "pink", activePen: doc }, // { title: "use drag", icon: "mouse-pointer", click: 'deactivateInk();this.activePen.inkPen = this;', ischecked: `sameDocs(this.activePen.inkPen, this)`, backgroundColor: "white", activePen: doc }, - { title: "Drag a document previewer", label: "Prev", icon: "expand", ignoreClick: true, drag: 'Docs.Create.DocumentDocument(ComputedField.MakeFunction("selectedDocs(this,this.excludeCollections,[_last_])?.[0]"), { _width: 250, _height: 250, title: "container" })' }, + { title: "Drag a document previewer", label: "Prev", icon: "expand", click: 'openOnRight(getCopy(this.dragFactory, true))', drag: 'getCopy(this.dragFactory,true)', dragFactory: doc.emptyDocHolder as Doc }, { title: "Drag a Calculator REPL", label: "repl", icon: "calculator", click: 'addOverlayWindow("ScriptingRepl", { x: 300, y: 100, width: 200, height: 200, title: "Scripting REPL" })' }, ]; @@ -308,7 +317,7 @@ export class CurrentUserUtils { title: data.title, label: data.label, ignoreClick: data.ignoreClick, - dropAction: data.click ? "copy" : undefined, + dropAction: "copy", onDragStart: data.drag ? ScriptField.MakeFunction(data.drag) : undefined, onClick: data.click ? ScriptField.MakeScript(data.click) : undefined, ischecked: data.ischecked ? ComputedField.MakeFunction(data.ischecked) : undefined, -- cgit v1.2.3-70-g09d2 From d9227908ba8e8db5084c468a242b2839ab11a33d Mon Sep 17 00:00:00 2001 From: Bob Zeleznik Date: Mon, 4 May 2020 12:50:46 -0400 Subject: fixed links and snap lines broken by moving things into DragManager. --- src/client/documents/Documents.ts | 2 +- src/client/util/DragManager.ts | 34 ++-- src/client/util/SelectionManager.ts | 3 + src/client/util/SnappingManager.ts | 29 +++ src/client/views/DocumentDecorations.tsx | 5 +- src/client/views/MainView.scss | 9 + src/client/views/MainView.tsx | 18 +- .../views/collections/CollectionDockingView.tsx | 5 +- .../collections/CollectionMasonryViewFieldRow.tsx | 4 +- .../views/collections/CollectionPileView.tsx | 6 +- .../views/collections/CollectionSchemaCells.tsx | 4 +- .../CollectionSchemaMovableTableHOC.tsx | 6 +- .../views/collections/CollectionStackingView.tsx | 7 +- .../CollectionStackingViewFieldColumn.tsx | 6 +- .../views/collections/CollectionTreeView.tsx | 7 +- .../CollectionFreeFormLinkView.tsx | 9 +- .../CollectionFreeFormLinksView.tsx | 4 +- .../collectionFreeForm/CollectionFreeFormView.tsx | 7 +- src/client/views/nodes/DocHolderBox.scss | 15 ++ src/client/views/nodes/DocHolderBox.tsx | 207 +++++++++++++++++++++ src/client/views/nodes/DocumentBox.scss | 15 -- src/client/views/nodes/DocumentBox.tsx | 207 --------------------- src/client/views/nodes/DocumentContentsView.tsx | 2 +- src/client/views/nodes/DocumentView.tsx | 3 +- src/client/views/nodes/QueryBox.tsx | 5 +- 25 files changed, 328 insertions(+), 291 deletions(-) create mode 100644 src/client/util/SnappingManager.ts create mode 100644 src/client/views/nodes/DocHolderBox.scss create mode 100644 src/client/views/nodes/DocHolderBox.tsx delete mode 100644 src/client/views/nodes/DocumentBox.scss delete mode 100644 src/client/views/nodes/DocumentBox.tsx (limited to 'src/client/views/collections/CollectionStackingViewFieldColumn.tsx') diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts index 45687f597..f5d6cd7f6 100644 --- a/src/client/documents/Documents.ts +++ b/src/client/documents/Documents.ts @@ -37,7 +37,7 @@ import { DashWebRTCVideo } from "../views/webcam/DashWebRTCVideo"; import { QueryBox } from "../views/nodes/QueryBox"; import { ColorBox } from "../views/nodes/ColorBox"; import { LinkAnchorBox } from "../views/nodes/LinkAnchorBox"; -import { DocHolderBox } from "../views/nodes/DocumentBox"; +import { DocHolderBox } from "../views/nodes/DocHolderBox"; import { InkingStroke } from "../views/InkingStroke"; import { InkField } from "../../new_fields/InkField"; import { InkingControl } from "../views/InkingControl"; diff --git a/src/client/util/DragManager.ts b/src/client/util/DragManager.ts index 348aba588..0d208cf1b 100644 --- a/src/client/util/DragManager.ts +++ b/src/client/util/DragManager.ts @@ -11,6 +11,7 @@ import { emptyFunction } from "../../Utils"; import { Docs, DocUtils } from "../documents/Documents"; import * as globalCssVariables from "../views/globalCssVariables.scss"; import { UndoManager } from "./UndoManager"; +import { SnappingManager } from "./SnappingManager"; export type dropActionType = "alias" | "copy" | "move" | undefined; // undefined = move export function SetupDrag( @@ -49,7 +50,7 @@ export function SetupDrag( if (e.shiftKey) { e.persist(); const dragDoc = await docFunc(); - dragDoc && DragManager.Vals.Instance.StartWindowDrag?.({ + dragDoc && DragManager.StartWindowDrag?.({ pageX: e.pageX, pageY: e.pageY, preventDefault: emptyFunction, @@ -66,19 +67,7 @@ export function SetupDrag( export namespace DragManager { let dragDiv: HTMLDivElement; - export class Vals { - static Instance: Vals = new Vals(); - @observable public IsDragging: boolean = false; - @observable public horizSnapLines: number[] = []; - @observable public vertSnapLines: number[] = []; - public StartWindowDrag: Opt<((e: any, dragDocs: Doc[]) => void)> = undefined; - public SetIsDragging(dragging: boolean) { runInAction(() => this.IsDragging = dragging); } - public GetIsDragging() { return this.IsDragging; } - @action public clearSnapLines() { - this.vertSnapLines.length = 0; - this.horizSnapLines.length = 0; - } - } + export let StartWindowDrag: Opt<((e: any, dragDocs: Doc[]) => void)> = undefined; export function Root() { const root = document.getElementById("root"); @@ -267,8 +256,7 @@ export namespace DragManager { } export function SetSnapLines(horizLines: number[], vertLines: number[]) { - DragManager.Vals.Instance.horizSnapLines.push(...horizLines); - DragManager.Vals.Instance.vertSnapLines.push(...vertLines); + SnappingManager.setSnapLines(horizLines, vertLines); } export function snapDrag(e: PointerEvent, xFromLeft: number, yFromTop: number, xFromRight: number, yFromBottom: number) { @@ -286,8 +274,8 @@ export namespace DragManager { }; return { - thisX: snapVal([xFromLeft, xFromRight], e.pageX, DragManager.Vals.Instance.vertSnapLines), - thisY: snapVal([yFromTop, yFromBottom], e.pageY, DragManager.Vals.Instance.horizSnapLines) + thisX: snapVal([xFromLeft, xFromRight], e.pageX, SnappingManager.vertSnapLines()), + thisY: snapVal([yFromTop, yFromBottom], e.pageY, SnappingManager.horizSnapLines()) }; } export let docsBeingDragged: Doc[] = []; @@ -299,7 +287,7 @@ export namespace DragManager { dragDiv.style.pointerEvents = "none"; DragManager.Root().appendChild(dragDiv); } - DragManager.Vals.Instance.SetIsDragging(true); + SnappingManager.SetIsDragging(true); const scaleXs: number[] = []; const scaleYs: number[] = []; const xs: number[] = []; @@ -388,7 +376,7 @@ export namespace DragManager { } AbortDrag(); finishDrag?.(new DragCompleteEvent(true, dragData)); - DragManager.Vals.Instance.StartWindowDrag?.({ + DragManager.StartWindowDrag?.({ pageX: e.pageX, pageY: e.pageY, preventDefault: emptyFunction, @@ -415,19 +403,19 @@ export namespace DragManager { const endDrag = action(() => { document.removeEventListener("pointermove", moveHandler, true); document.removeEventListener("pointerup", upHandler); - DragManager.Vals.Instance.clearSnapLines(); + SnappingManager.clearSnapLines(); }); AbortDrag = () => { hideDragShowOriginalElements(); - DragManager.Vals.Instance.SetIsDragging(false); + SnappingManager.SetIsDragging(false); options?.dragComplete?.(new DragCompleteEvent(true, dragData)); endDrag(); }; const upHandler = (e: PointerEvent) => { hideDragShowOriginalElements(); dispatchDrag(eles, e, dragData, xFromLeft, yFromTop, xFromRight, yFromBottom, options, finishDrag); - DragManager.Vals.Instance.SetIsDragging(false); + SnappingManager.SetIsDragging(false); endDrag(); options?.dragComplete?.(new DragCompleteEvent(false, dragData)); }; diff --git a/src/client/util/SelectionManager.ts b/src/client/util/SelectionManager.ts index d509168b6..11d2cafb2 100644 --- a/src/client/util/SelectionManager.ts +++ b/src/client/util/SelectionManager.ts @@ -8,6 +8,7 @@ export namespace SelectionManager { class Manager { + @observable IsDragging: boolean = false; SelectedDocuments: ObservableMap = new ObservableMap(); @action @@ -53,6 +54,8 @@ export namespace SelectionManager { manager.SelectDoc(docView, ctrlPressed); } + export function SetIsDragging(dragging: boolean) { runInAction(() => manager.IsDragging = dragging); } + export function GetIsDragging() { return manager.IsDragging; } // computed functions, such as used in IsSelected generate errors if they're called outside of a // reaction context. Specifying the context with 'outsideReaction' allows an efficiency feature // to avoid unnecessary mobx invalidations when running inside a reaction. diff --git a/src/client/util/SnappingManager.ts b/src/client/util/SnappingManager.ts new file mode 100644 index 000000000..fc07e8ab4 --- /dev/null +++ b/src/client/util/SnappingManager.ts @@ -0,0 +1,29 @@ +import { observable, action, runInAction } from "mobx"; + +export namespace SnappingManager { + + class Manager { + @observable IsDragging: boolean = false; + @observable public horizSnapLines: number[] = []; + @observable public vertSnapLines: number[] = []; + @action public clearSnapLines() { + this.vertSnapLines = []; + this.horizSnapLines = []; + } + @action public setSnapLines(horizLines: number[], vertLines: number[]) { + this.horizSnapLines = horizLines; + this.vertSnapLines = vertLines; + } + } + + const manager = new Manager(); + + export function clearSnapLines() { manager.clearSnapLines(); } + export function setSnapLines(horizLines: number[], vertLines: number[]) { manager.setSnapLines(horizLines, vertLines); } + export function horizSnapLines() { return manager.horizSnapLines; } + export function vertSnapLines() { return manager.vertSnapLines; } + + export function SetIsDragging(dragging: boolean) { runInAction(() => manager.IsDragging = dragging); } + export function GetIsDragging() { return manager.IsDragging; } +} + diff --git a/src/client/views/DocumentDecorations.tsx b/src/client/views/DocumentDecorations.tsx index f8e77d90a..b89806656 100644 --- a/src/client/views/DocumentDecorations.tsx +++ b/src/client/views/DocumentDecorations.tsx @@ -21,6 +21,7 @@ import { Id } from '../../new_fields/FieldSymbols'; import e = require('express'); import { CollectionDockingView } from './collections/CollectionDockingView'; import { MainView } from './MainView'; +import { SnappingManager } from '../util/SnappingManager'; library.add(faCaretUp); library.add(faObjectGroup); @@ -364,7 +365,7 @@ export class DocumentDecorations extends React.Component<{}, { value: string }> this.Interacting = false; (e.button === 0) && this._resizeUndo?.end(); this._resizeUndo = undefined; - DragManager.Vals.Instance.clearSnapLines(); + SnappingManager.clearSnapLines(); } @computed @@ -403,7 +404,7 @@ export class DocumentDecorations extends React.Component<{}, { value: string }> const darkScheme = Cast(Doc.UserDoc().activeWorkspace, Doc, null)?.darkScheme ? "dimgray" : undefined; const bounds = this.Bounds; const seldoc = SelectionManager.SelectedDocuments().length ? SelectionManager.SelectedDocuments()[0] : undefined; - if (DragManager.Vals.Instance.GetIsDragging() || bounds.r - bounds.x < 2 || bounds.x === Number.MAX_VALUE || !seldoc || this._hidden || isNaN(bounds.r) || isNaN(bounds.b) || isNaN(bounds.x) || isNaN(bounds.y)) { + if (SnappingManager.GetIsDragging() || bounds.r - bounds.x < 2 || bounds.x === Number.MAX_VALUE || !seldoc || this._hidden || isNaN(bounds.r) || isNaN(bounds.b) || isNaN(bounds.x) || isNaN(bounds.y)) { return (null); } const minimal = bounds.r - bounds.x < 100 ? true : false; diff --git a/src/client/views/MainView.scss b/src/client/views/MainView.scss index 04288a9e1..753ba700c 100644 --- a/src/client/views/MainView.scss +++ b/src/client/views/MainView.scss @@ -22,6 +22,15 @@ z-index: 1; } +.mainView-snapLines { + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 100%; + pointer-events:none; +} + .mainView-container, .mainView-container-dark { input { color: unset !important; diff --git a/src/client/views/MainView.tsx b/src/client/views/MainView.tsx index 71c2bf245..9ebd60c52 100644 --- a/src/client/views/MainView.tsx +++ b/src/client/views/MainView.tsx @@ -44,6 +44,7 @@ import { PreviewCursor } from './PreviewCursor'; import { ScriptField } from '../../new_fields/ScriptField'; import { TimelineMenu } from './animationtimeline/TimelineMenu'; import { DragManager } from '../util/DragManager'; +import { SnappingManager } from '../util/SnappingManager'; @observer export class MainView extends React.Component { @@ -575,6 +576,15 @@ export class MainView extends React.Component { return this._mainViewRef; } + @computed get snapLines() { + return
+ + {SnappingManager.horizSnapLines().map(l => )} + {SnappingManager.vertSnapLines().map(l => )} + +
+ } + render() { return (
@@ -592,14 +602,8 @@ export class MainView extends React.Component { - {// TO VIEW SNAP LINES -
- - {DragManager.Vals.Instance.horizSnapLines.map((l: any) => )} - {DragManager.Vals.Instance.vertSnapLines.map((l: any) => )} - -
} + {this.snapLines}
); } } diff --git a/src/client/views/collections/CollectionDockingView.tsx b/src/client/views/collections/CollectionDockingView.tsx index 33ece13cc..6cd5d1b1b 100644 --- a/src/client/views/collections/CollectionDockingView.tsx +++ b/src/client/views/collections/CollectionDockingView.tsx @@ -30,6 +30,7 @@ import { SubCollectionViewProps } from "./CollectionSubView"; import { DockingViewButtonSelector } from './ParentDocumentSelector'; import React = require("react"); import { CollectionViewType } from './CollectionView'; +import { SnappingManager } from '../../util/SnappingManager'; library.add(faFile); const _global = (window /* browser */ || global /* node */) as any; @@ -68,7 +69,7 @@ export class CollectionDockingView extends React.Component { - if (!this._isPointerDown || !DragManager.Vals.Instance.GetIsDragging()) return; + if (!this._isPointerDown || !SnappingManager.GetIsDragging()) return; const activeContentItem = tab.header.parent.getActiveContentItem(); if (tab.contentItem !== activeContentItem) { tab.header.parent.setActiveContentItem(tab.contentItem); diff --git a/src/client/views/collections/CollectionMasonryViewFieldRow.tsx b/src/client/views/collections/CollectionMasonryViewFieldRow.tsx index c74cfbcf4..95c7643c9 100644 --- a/src/client/views/collections/CollectionMasonryViewFieldRow.tsx +++ b/src/client/views/collections/CollectionMasonryViewFieldRow.tsx @@ -12,12 +12,12 @@ import { numberRange, setupMoveUpEvents, emptyFunction } from "../../../Utils"; import { Docs } from "../../documents/Documents"; import { DragManager } from "../../util/DragManager"; import { CompileScript } from "../../util/Scripting"; -import { SelectionManager } from "../../util/SelectionManager"; import { Transform } from "../../util/Transform"; import { undoBatch } from "../../util/UndoManager"; import { EditableView } from "../EditableView"; import { CollectionStackingView } from "./CollectionStackingView"; import "./CollectionStackingView.scss"; +import { SnappingManager } from "../../util/SnappingManager"; const higflyout = require("@hig/flyout"); export const { anchorPoints } = higflyout; export const Flyout = higflyout.default; @@ -132,7 +132,7 @@ export class CollectionMasonryViewFieldRow extends React.Component DragManager.Vals.Instance.GetIsDragging() && (this._background = "#b4b4b4")); + pointerEnteredRow = action(() => SnappingManager.GetIsDragging() && (this._background = "#b4b4b4")); @action pointerLeaveRow = () => { diff --git a/src/client/views/collections/CollectionPileView.tsx b/src/client/views/collections/CollectionPileView.tsx index 0a10c24b3..d3ae21f3a 100644 --- a/src/client/views/collections/CollectionPileView.tsx +++ b/src/client/views/collections/CollectionPileView.tsx @@ -12,7 +12,7 @@ import React = require("react"); import { setupMoveUpEvents, emptyFunction, returnFalse } from "../../../Utils"; import { SelectionManager } from "../../util/SelectionManager"; import { UndoManager } from "../../util/UndoManager"; -import { DragManager } from "../../util/DragManager"; +import { SnappingManager } from "../../util/SnappingManager"; @observer export class CollectionPileView extends CollectionSubView(doc => doc) { @@ -79,7 +79,7 @@ export class CollectionPileView extends CollectionSubView(doc => doc) { _undoBatch: UndoManager.Batch | undefined; pointerDown = (e: React.PointerEvent) => { let dist = 0; - DragManager.Vals.Instance.SetIsDragging(true); + SnappingManager.SetIsDragging(true); // this._lastTap should be set to 0, and this._doubleTap should be set to false in the class header setupMoveUpEvents(this, e, (e: PointerEvent, down: number[], delta: number[]) => { if (this.layoutEngine() === "pass" && this.childDocs.length && this.props.isSelected(true)) { @@ -99,7 +99,7 @@ export class CollectionPileView extends CollectionSubView(doc => doc) { }, () => { this._undoBatch?.end(); this._undoBatch = undefined; - DragManager.Vals.Instance.SetIsDragging(false); + SnappingManager.SetIsDragging(false); if (!this.childDocs.length) { this.props.ContainingCollectionView?.removeDocument(this.props.Document); } diff --git a/src/client/views/collections/CollectionSchemaCells.tsx b/src/client/views/collections/CollectionSchemaCells.tsx index 0e6489947..5253ee0b9 100644 --- a/src/client/views/collections/CollectionSchemaCells.tsx +++ b/src/client/views/collections/CollectionSchemaCells.tsx @@ -18,11 +18,11 @@ import "./CollectionSchemaView.scss"; import { CollectionView } from "./CollectionView"; import { NumCast, StrCast, BoolCast, FieldValue, Cast } from "../../../new_fields/Types"; import { Docs } from "../../documents/Documents"; -import { SelectionManager } from "../../util/SelectionManager"; import { library } from '@fortawesome/fontawesome-svg-core'; import { faExpand } from '@fortawesome/free-solid-svg-icons'; import { SchemaHeaderField } from "../../../new_fields/SchemaHeaderField"; import { undoBatch } from "../../util/UndoManager"; +import { SnappingManager } from "../../util/SnappingManager"; library.add(faExpand); @@ -189,7 +189,7 @@ export class CollectionSchemaCell extends React.Component { this._document[props.fieldKey] instanceof Doc ? "alias" : this.props.Document.schemaDoc ? "copy" : undefined)(e); }; const onPointerEnter = (e: React.PointerEvent): void => { - if (e.buttons === 1 && DragManager.Vals.Instance.GetIsDragging() && (type === "document" || type === undefined)) { + if (e.buttons === 1 && SnappingManager.GetIsDragging() && (type === "document" || type === undefined)) { dragRef.current!.className = "collectionSchemaView-cellContainer doc-drag-over"; } }; diff --git a/src/client/views/collections/CollectionSchemaMovableTableHOC.tsx b/src/client/views/collections/CollectionSchemaMovableTableHOC.tsx index f9cd9a628..8636e3eb5 100644 --- a/src/client/views/collections/CollectionSchemaMovableTableHOC.tsx +++ b/src/client/views/collections/CollectionSchemaMovableTableHOC.tsx @@ -4,7 +4,6 @@ import "./CollectionSchemaView.scss"; import { Transform } from "../../util/Transform"; import { Doc } from "../../../new_fields/Doc"; import { DragManager, SetupDrag, dropActionType } from "../../util/DragManager"; -import { SelectionManager } from "../../util/SelectionManager"; import { Cast, FieldValue, StrCast } from "../../../new_fields/Types"; import { ContextMenu } from "../ContextMenu"; import { action } from "mobx"; @@ -14,6 +13,7 @@ import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; import { DocumentManager } from "../../util/DocumentManager"; import { SchemaHeaderField } from "../../../new_fields/SchemaHeaderField"; import { undoBatch } from "../../util/UndoManager"; +import { SnappingManager } from "../../util/SnappingManager"; library.add(faGripVertical, faTrash); @@ -32,7 +32,7 @@ export class MovableColumn extends React.Component { private _dragRef: React.RefObject = React.createRef(); onPointerEnter = (e: React.PointerEvent): void => { - if (e.buttons === 1 && DragManager.Vals.Instance.GetIsDragging()) { + if (e.buttons === 1 && SnappingManager.GetIsDragging()) { this._header!.current!.className = "collectionSchema-col-wrapper"; document.addEventListener("pointermove", this.onDragMove, true); } @@ -143,7 +143,7 @@ export class MovableRow extends React.Component { private _rowDropDisposer?: DragManager.DragDropDisposer; onPointerEnter = (e: React.PointerEvent): void => { - if (e.buttons === 1 && DragManager.Vals.Instance.GetIsDragging()) { + if (e.buttons === 1 && SnappingManager.GetIsDragging()) { this._header!.current!.className = "collectionSchema-row-wrapper"; document.addEventListener("pointermove", this.onDragMove, true); } diff --git a/src/client/views/collections/CollectionStackingView.tsx b/src/client/views/collections/CollectionStackingView.tsx index f6cdebc9b..b6faea845 100644 --- a/src/client/views/collections/CollectionStackingView.tsx +++ b/src/client/views/collections/CollectionStackingView.tsx @@ -14,7 +14,6 @@ import { BoolCast, Cast, NumCast, ScriptCast, StrCast } from "../../../new_field import { TraceMobx } from "../../../new_fields/util"; import { emptyFunction, returnFalse, returnOne, returnZero, setupMoveUpEvents, Utils } from "../../../Utils"; import { DragManager, dropActionType } from "../../util/DragManager"; -import { SelectionManager } from "../../util/SelectionManager"; import { Transform } from "../../util/Transform"; import { undoBatch } from "../../util/UndoManager"; import { ContextMenu } from "../ContextMenu"; @@ -26,7 +25,7 @@ import "./CollectionStackingView.scss"; import { CollectionStackingViewFieldColumn } from "./CollectionStackingViewFieldColumn"; import { CollectionSubView } from "./CollectionSubView"; import { CollectionViewType } from "./CollectionView"; -import { ScriptField } from "../../../new_fields/ScriptField"; +import { SnappingManager } from "../../util/SnappingManager"; const _global = (window /* browser */ || global /* node */) as any; type StackingDocument = makeInterface<[typeof collectionSchema, typeof documentSchema]>; @@ -312,7 +311,7 @@ export class CollectionStackingView extends CollectionSubView(StackingDocument) this.refList.push(ref); const doc = this.props.DataDoc && this.props.DataDoc.layout === this.layoutDoc ? this.props.DataDoc : this.layoutDoc; this.observer = new _global.ResizeObserver(action((entries: any) => { - if (this.props.Document._autoHeight && ref && this.refList.length && !DragManager.Vals.Instance.GetIsDragging()) { + if (this.props.Document._autoHeight && ref && this.refList.length && !SnappingManager.GetIsDragging()) { Doc.Layout(doc)._height = Math.min(1200, Math.max(...this.refList.map(r => Number(getComputedStyle(r).height.replace("px", ""))))); } })); @@ -359,7 +358,7 @@ export class CollectionStackingView extends CollectionSubView(StackingDocument) this.refList.push(ref); const doc = this.props.DataDoc && this.props.DataDoc.layout === this.layoutDoc ? this.props.DataDoc : this.layoutDoc; this.observer = new _global.ResizeObserver(action((entries: any) => { - if (this.props.Document._autoHeight && ref && this.refList.length && !DragManager.Vals.Instance.GetIsDragging()) { + if (this.props.Document._autoHeight && ref && this.refList.length && !SnappingManager.GetIsDragging()) { Doc.Layout(doc)._height = this.refList.reduce((p, r) => p + Number(getComputedStyle(r).height.replace("px", "")), 0); } })); diff --git a/src/client/views/collections/CollectionStackingViewFieldColumn.tsx b/src/client/views/collections/CollectionStackingViewFieldColumn.tsx index 1d16a5478..dccef7983 100644 --- a/src/client/views/collections/CollectionStackingViewFieldColumn.tsx +++ b/src/client/views/collections/CollectionStackingViewFieldColumn.tsx @@ -13,7 +13,6 @@ import { ImageField } from "../../../new_fields/URLField"; import { TraceMobx } from "../../../new_fields/util"; import { Docs, DocUtils } from "../../documents/Documents"; import { DragManager } from "../../util/DragManager"; -import { SelectionManager } from "../../util/SelectionManager"; import { Transform } from "../../util/Transform"; import { undoBatch } from "../../util/UndoManager"; import { ContextMenu } from "../ContextMenu"; @@ -23,6 +22,7 @@ import { CollectionStackingView } from "./CollectionStackingView"; import { setupMoveUpEvents, emptyFunction } from "../../../Utils"; import "./CollectionStackingView.scss"; import { listSpec } from "../../../new_fields/Schema"; +import { SnappingManager } from "../../util/SnappingManager"; const higflyout = require("@hig/flyout"); export const { anchorPoints } = higflyout; export const Flyout = higflyout.default; @@ -120,7 +120,7 @@ export class CollectionStackingViewFieldColumn extends React.Component { - if (DragManager.Vals.Instance.GetIsDragging()) { + if (SnappingManager.GetIsDragging()) { this._background = "#b4b4b4"; } } @@ -355,7 +355,7 @@ export class CollectionStackingViewFieldColumn extends React.Component diff --git a/src/client/views/collections/CollectionTreeView.tsx b/src/client/views/collections/CollectionTreeView.tsx index 288fa8794..f2b0e3155 100644 --- a/src/client/views/collections/CollectionTreeView.tsx +++ b/src/client/views/collections/CollectionTreeView.tsx @@ -6,6 +6,7 @@ import { observer } from "mobx-react"; import { DataSym, Doc, DocListCast, Field, HeightSym, Opt, WidthSym } from '../../../new_fields/Doc'; import { Id } from '../../../new_fields/FieldSymbols'; import { List } from '../../../new_fields/List'; +import { PrefetchProxy } from '../../../new_fields/Proxy'; import { Document, listSpec } from '../../../new_fields/Schema'; import { ComputedField, ScriptField } from '../../../new_fields/ScriptField'; import { BoolCast, Cast, NumCast, ScriptCast, StrCast } from '../../../new_fields/Types'; @@ -13,6 +14,7 @@ import { emptyFunction, emptyPath, returnFalse, returnOne, returnTrue, returnZer import { Docs, DocUtils } from '../../documents/Documents'; import { DocumentType } from "../../documents/DocumentTypes"; import { DocumentManager } from '../../util/DocumentManager'; +import { SnappingManager } from '../../util/SnappingManager'; import { DragManager, dropActionType, SetupDrag } from "../../util/DragManager"; import { Scripting } from '../../util/Scripting'; import { SelectionManager } from '../../util/SelectionManager'; @@ -31,7 +33,6 @@ import { CollectionSubView } from "./CollectionSubView"; import "./CollectionTreeView.scss"; import { CollectionViewType } from './CollectionView'; import React = require("react"); -import { PrefetchProxy } from '../../../new_fields/Proxy'; export interface TreeViewProps { @@ -147,7 +148,7 @@ class TreeView extends React.Component { onPointerEnter = (e: React.PointerEvent): void => { this.props.active(true) && Doc.BrushDoc(this.dataDoc); - if (e.buttons === 1 && DragManager.Vals.Instance.GetIsDragging()) { + if (e.buttons === 1 && SnappingManager.GetIsDragging()) { this._header!.current!.className = "treeViewItem-header"; document.addEventListener("pointermove", this.onDragMove, true); } @@ -451,7 +452,7 @@ class TreeView extends React.Component { fontWeight: this.props.document.searchMatch ? "bold" : undefined, textDecoration: Doc.GetT(this.props.document, "title", "string", true) ? "underline" : undefined, outline: BoolCast(this.props.document.workspaceBrush) ? "dashed 1px #06123232" : undefined, - pointerEvents: this.props.active() || DragManager.Vals.Instance.GetIsDragging() ? undefined : "none" + pointerEvents: this.props.active() || SnappingManager.GetIsDragging() ? undefined : "none" }} > {Doc.GetT(this.props.document, "editTitle", "boolean", true) ? this.editableView("title") : diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinkView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinkView.tsx index 0c9a1aa9a..695898ca9 100644 --- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinkView.tsx +++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinkView.tsx @@ -9,7 +9,7 @@ import { DocumentType } from "../../../documents/DocumentTypes"; import { observable, action, reaction, IReactionDisposer } from "mobx"; import { StrCast } from "../../../../new_fields/Types"; import { Id } from "../../../../new_fields/FieldSymbols"; -import { DragManager } from "../../../util/DragManager"; +import { SnappingManager } from "../../../util/SnappingManager"; export interface CollectionFreeFormLinkViewProps { A: DocumentView; @@ -25,7 +25,7 @@ export class CollectionFreeFormLinkView extends React.Component [this.props.A.props.ScreenToLocalTransform(), this.props.B.props.ScreenToLocalTransform(), this.props.A.isSelected() || Doc.IsBrushed(this.props.A.props.Document), this.props.A.isSelected() || Doc.IsBrushed(this.props.A.props.Document)], action(() => { - if (DragManager.Vals.Instance.GetIsDragging()) return; + if (SnappingManager.GetIsDragging()) return; setTimeout(action(() => this._opacity = 1), 0); // since the render code depends on querying the Dom through getBoudndingClientRect, we need to delay triggering render() setTimeout(action(() => (!this.props.LinkDocs.length || !this.props.LinkDocs[0].linkDisplay) && (this._opacity = 0.05)), 750); // this will unhighlight the link line. const acont = this.props.A.props.Document.type === DocumentType.LINK ? this.props.A.ContentDiv!.getElementsByClassName("linkAnchorBox-cont") : []; @@ -83,7 +83,7 @@ export class CollectionFreeFormLinkView extends React.Component - + {text !== "-ungrouped-" ? text : ""} + return SnappingManager.GetIsDragging() ? (null) :
{this.uniqueConnections} diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx index 2aa9b1f5f..37957b0f6 100644 --- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx +++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx @@ -45,6 +45,7 @@ import { MarqueeView } from "./MarqueeView"; import React = require("react"); import { CollectionViewType } from "../CollectionView"; import { Timeline } from "../../animationtimeline/Timeline"; +import { SnappingManager } from "../../../util/SnappingManager"; library.add(faEye as any, faTable, faPaintBrush, faExpandArrowsAlt, faCompressArrowsAlt, faCompass, faUpload, faBraille, faChalkboard, faFileUpload); @@ -1174,7 +1175,7 @@ export class CollectionFreeFormView extends CollectionSubView { - if (DragManager.Vals.Instance.GetIsDragging()) { + if (SnappingManager.GetIsDragging()) { this.setupDragLines(); } e.stopPropagation(); @@ -1233,7 +1234,7 @@ export class CollectionFreeFormView extends CollectionSubView; +const DocHolderBoxDocument = makeInterface(documentSchema, collectionSchema); + +@observer +export class DocHolderBox extends ViewBoxAnnotatableComponent(DocHolderBoxDocument) { + public static LayoutString(fieldKey: string) { return FieldView.LayoutString(DocHolderBox, fieldKey); } + _prevSelectionDisposer: IReactionDisposer | undefined; + _dropDisposer?: DragManager.DragDropDisposer; + _selections: Doc[] = []; + _contRef = React.createRef(); + _curSelection = -1; + componentDidMount() { + this._prevSelectionDisposer = reaction(() => this.layoutDoc[this.props.fieldKey], (data) => { + if (data instanceof Doc && !this.isSelectionLocked()) { + this._selections.indexOf(data) !== -1 && this._selections.splice(this._selections.indexOf(data), 1); + this._selections.push(data); + this._curSelection = this._selections.length - 1; + } + }); + } + componentWillUnmount() { + this._prevSelectionDisposer?.(); + } + specificContextMenu = (e: React.MouseEvent): void => { + const funcs: ContextMenuProps[] = []; + funcs.push({ description: (this.isSelectionLocked() ? "Show" : "Lock") + " Selection", event: () => this.toggleLockSelection, icon: "expand-arrows-alt" }); + funcs.push({ description: (this.layoutDoc.excludeCollections ? "Include" : "Exclude") + " Collections", event: () => this.layoutDoc.excludeCollections = !this.layoutDoc.excludeCollections, icon: "expand-arrows-alt" }); + funcs.push({ description: `${this.layoutDoc.forceActive ? "Select" : "Force"} Contents Active`, event: () => this.layoutDoc.forceActive = !this.layoutDoc.forceActive, icon: "project-diagram" }); + funcs.push({ description: `Show ${this.layoutDoc.childLayoutTemplateName !== "keyValue" ? "key values" : "contents"}`, event: () => this.layoutDoc.childLayoutString = this.layoutDoc.childLayoutString ? undefined : "", icon: "project-diagram" }); + + ContextMenu.Instance.addItem({ description: "Options...", subitems: funcs, icon: "asterisk" }); + } + lockSelection = () => { + this.layoutDoc[this.props.fieldKey] = this.layoutDoc[this.props.fieldKey]; + } + showSelection = () => { + this.layoutDoc[this.props.fieldKey] = ComputedField.MakeFunction(`selectedDocs(self,this.excludeCollections,[_last_])?.[0]`); + } + isSelectionLocked = () => { + const kvpstring = Field.toKeyValueString(this.layoutDoc, this.props.fieldKey); + return !kvpstring || kvpstring.includes("DOC"); + } + toggleLockSelection = () => { + !this.isSelectionLocked() ? this.lockSelection() : this.showSelection(); + return true; + } + prevSelection = () => { + this.lockSelection(); + if (this._curSelection > 0) { + this.layoutDoc[this.props.fieldKey] = this._selections[--this._curSelection]; + return true; + } + } + nextSelection = () => { + if (this._curSelection < this._selections.length - 1 && this._selections.length) { + this.layoutDoc[this.props.fieldKey] = this._selections[++this._curSelection]; + return true; + } + } + onPointerDown = (e: React.PointerEvent) => { + if (this.active() && e.button === 0 && !e.ctrlKey) { + e.stopPropagation(); + } + } + onLockClick = (e: React.MouseEvent) => { + this.toggleLockSelection(); + (e.nativeEvent as any).formattedHandled = true; + e.stopPropagation(); + } + get xPad() { return NumCast(this.props.Document._xPadding); } + get yPad() { return NumCast(this.props.Document._yPadding); } + onClick = (e: React.MouseEvent) => { + let hitWidget: boolean | undefined = false; + if (this._contRef.current!.getBoundingClientRect().top + this.yPad > e.clientY) hitWidget = (() => { this.props.select(false); return true; })(); + else if (this._contRef.current!.getBoundingClientRect().bottom - this.yPad < e.clientY) hitWidget = (() => { this.props.select(false); return true; })(); + else { + if (this._contRef.current!.getBoundingClientRect().left + this.xPad > e.clientX) hitWidget = this.prevSelection(); + if (this._contRef.current!.getBoundingClientRect().right - this.xPad < e.clientX) hitWidget = this.nextSelection(); + } + if (hitWidget) { + (e.nativeEvent as any).formattedHandled = true; + e.stopPropagation(); + } + } + pwidth = () => this.props.PanelWidth() - 2 * this.xPad; + pheight = () => this.props.PanelHeight() - 2 * this.yPad; + getTransform = () => this.props.ScreenToLocalTransform().translate(-this.xPad, -this.yPad); + isActive = () => this.active() || !this.props.renderDepth; + layoutTemplateDoc = () => Cast(this.props.Document.childLayoutTemplate, Doc, null); + get renderContents() { + const containedDoc = Cast(this.dataDoc[this.props.fieldKey], Doc, null); + const layoutTemplate = StrCast(this.layoutDoc.childLayoutString); + const contents = !(containedDoc instanceof Doc) ? (null) : this.layoutDoc.childLayoutString || this.layoutTemplateDoc() ? + : + ; + return contents; + } + render() { + TraceMobx(); + return
+ {this.renderContents} +
+ +
+
; + } + + @undoBatch + @action + drop = (e: Event, de: DragManager.DropEvent) => { + if (de.complete.docDragData) { + if (de.complete.docDragData.draggedDocuments[0].type === DocumentType.FONTICON) { + const doc = Cast(de.complete.docDragData.draggedDocuments[0].dragFactory, Doc, null); + this.props.Document.childLayoutTemplate = doc; + } + } + } + protected createDropTarget = (ele: HTMLDivElement) => { + this._dropDisposer?.(); + ele && (this._dropDisposer = DragManager.MakeDropTarget(ele, this.drop.bind(this), this.props.Document)); + } + +} diff --git a/src/client/views/nodes/DocumentBox.scss b/src/client/views/nodes/DocumentBox.scss deleted file mode 100644 index 3a27c16c1..000000000 --- a/src/client/views/nodes/DocumentBox.scss +++ /dev/null @@ -1,15 +0,0 @@ -.documentBox-container { - width: 100%; - height: 100%; - pointer-events: all; - background: rgb(241, 239, 235); - position: absolute; - .documentBox-lock { - margin: auto; - color: white; - position: absolute; - } - .contentFittingDocumentView { - position: absolute; - } -} \ No newline at end of file diff --git a/src/client/views/nodes/DocumentBox.tsx b/src/client/views/nodes/DocumentBox.tsx deleted file mode 100644 index b53c7cfe6..000000000 --- a/src/client/views/nodes/DocumentBox.tsx +++ /dev/null @@ -1,207 +0,0 @@ -import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; -import { action, IReactionDisposer, reaction } from "mobx"; -import { observer } from "mobx-react"; -import { Doc, Field } from "../../../new_fields/Doc"; -import { collectionSchema, documentSchema } from "../../../new_fields/documentSchemas"; -import { makeInterface } from "../../../new_fields/Schema"; -import { ComputedField } from "../../../new_fields/ScriptField"; -import { Cast, NumCast, StrCast } from "../../../new_fields/Types"; -import { TraceMobx } from "../../../new_fields/util"; -import { emptyPath, returnFalse, returnOne, returnZero } from "../../../Utils"; -import { DocumentType } from "../../documents/DocumentTypes"; -import { DragManager } from "../../util/DragManager"; -import { undoBatch } from "../../util/UndoManager"; -import { ContextMenu } from "../ContextMenu"; -import { ContextMenuProps } from "../ContextMenuItem"; -import { ViewBoxAnnotatableComponent } from "../DocComponent"; -import { ContentFittingDocumentView } from "./ContentFittingDocumentView"; -import "./DocumentBox.scss"; -import { DocumentView } from "./DocumentView"; -import { FieldView, FieldViewProps } from "./FieldView"; -import React = require("react"); - -type DocHolderBoxSchema = makeInterface<[typeof documentSchema, typeof collectionSchema]>; -const DocHolderBoxDocument = makeInterface(documentSchema, collectionSchema); - -@observer -export class DocHolderBox extends ViewBoxAnnotatableComponent(DocHolderBoxDocument) { - public static LayoutString(fieldKey: string) { return FieldView.LayoutString(DocHolderBox, fieldKey); } - _prevSelectionDisposer: IReactionDisposer | undefined; - _dropDisposer?: DragManager.DragDropDisposer; - _selections: Doc[] = []; - _contRef = React.createRef(); - _curSelection = -1; - componentDidMount() { - this._prevSelectionDisposer = reaction(() => this.layoutDoc[this.props.fieldKey], (data) => { - if (data instanceof Doc && !this.isSelectionLocked()) { - this._selections.indexOf(data) !== -1 && this._selections.splice(this._selections.indexOf(data), 1); - this._selections.push(data); - this._curSelection = this._selections.length - 1; - } - }); - } - componentWillUnmount() { - this._prevSelectionDisposer?.(); - } - specificContextMenu = (e: React.MouseEvent): void => { - const funcs: ContextMenuProps[] = []; - funcs.push({ description: (this.isSelectionLocked() ? "Show" : "Lock") + " Selection", event: () => this.toggleLockSelection, icon: "expand-arrows-alt" }); - funcs.push({ description: (this.layoutDoc.excludeCollections ? "Include" : "Exclude") + " Collections", event: () => this.layoutDoc.excludeCollections = !this.layoutDoc.excludeCollections, icon: "expand-arrows-alt" }); - funcs.push({ description: `${this.layoutDoc.forceActive ? "Select" : "Force"} Contents Active`, event: () => this.layoutDoc.forceActive = !this.layoutDoc.forceActive, icon: "project-diagram" }); - funcs.push({ description: `Show ${this.layoutDoc.childLayoutTemplateName !== "keyValue" ? "key values" : "contents"}`, event: () => this.layoutDoc.childLayoutString = this.layoutDoc.childLayoutString ? undefined : "", icon: "project-diagram" }); - - ContextMenu.Instance.addItem({ description: "Options...", subitems: funcs, icon: "asterisk" }); - } - lockSelection = () => { - this.layoutDoc[this.props.fieldKey] = this.layoutDoc[this.props.fieldKey]; - } - showSelection = () => { - this.layoutDoc[this.props.fieldKey] = ComputedField.MakeFunction(`selectedDocs(self,this.excludeCollections,[_last_])?.[0]`); - } - isSelectionLocked = () => { - const kvpstring = Field.toKeyValueString(this.layoutDoc, this.props.fieldKey); - return !kvpstring || kvpstring.includes("DOC"); - } - toggleLockSelection = () => { - !this.isSelectionLocked() ? this.lockSelection() : this.showSelection(); - return true; - } - prevSelection = () => { - this.lockSelection(); - if (this._curSelection > 0) { - this.layoutDoc[this.props.fieldKey] = this._selections[--this._curSelection]; - return true; - } - } - nextSelection = () => { - if (this._curSelection < this._selections.length - 1 && this._selections.length) { - this.layoutDoc[this.props.fieldKey] = this._selections[++this._curSelection]; - return true; - } - } - onPointerDown = (e: React.PointerEvent) => { - if (this.active() && e.button === 0 && !e.ctrlKey) { - e.stopPropagation(); - } - } - onLockClick = (e: React.MouseEvent) => { - this.toggleLockSelection(); - (e.nativeEvent as any).formattedHandled = true; - e.stopPropagation(); - } - get xPad() { return NumCast(this.props.Document._xPadding); } - get yPad() { return NumCast(this.props.Document._yPadding); } - onClick = (e: React.MouseEvent) => { - let hitWidget: boolean | undefined = false; - if (this._contRef.current!.getBoundingClientRect().top + this.yPad > e.clientY) hitWidget = (() => { this.props.select(false); return true; })(); - else if (this._contRef.current!.getBoundingClientRect().bottom - this.yPad < e.clientY) hitWidget = (() => { this.props.select(false); return true; })(); - else { - if (this._contRef.current!.getBoundingClientRect().left + this.xPad > e.clientX) hitWidget = this.prevSelection(); - if (this._contRef.current!.getBoundingClientRect().right - this.xPad < e.clientX) hitWidget = this.nextSelection(); - } - if (hitWidget) { - (e.nativeEvent as any).formattedHandled = true; - e.stopPropagation(); - } - } - pwidth = () => this.props.PanelWidth() - 2 * this.xPad; - pheight = () => this.props.PanelHeight() - 2 * this.yPad; - getTransform = () => this.props.ScreenToLocalTransform().translate(-this.xPad, -this.yPad); - isActive = () => this.active() || !this.props.renderDepth; - layoutTemplateDoc = () => Cast(this.props.Document.childLayoutTemplate, Doc, null); - get renderContents() { - const containedDoc = Cast(this.dataDoc[this.props.fieldKey], Doc, null); - const layoutTemplate = StrCast(this.layoutDoc.childLayoutString); - const contents = !(containedDoc instanceof Doc) ? (null) : this.layoutDoc.childLayoutString || this.layoutTemplateDoc() ? - : - ; - return contents; - } - render() { - TraceMobx(); - return
- {this.renderContents} -
- -
-
; - } - - @undoBatch - @action - drop = (e: Event, de: DragManager.DropEvent) => { - if (de.complete.docDragData) { - if (de.complete.docDragData.draggedDocuments[0].type === DocumentType.FONTICON) { - const doc = Cast(de.complete.docDragData.draggedDocuments[0].dragFactory, Doc, null); - this.props.Document.childLayoutTemplate = doc; - } - } - } - protected createDropTarget = (ele: HTMLDivElement) => { - this._dropDisposer?.(); - ele && (this._dropDisposer = DragManager.MakeDropTarget(ele, this.drop.bind(this), this.props.Document)); - } - -} diff --git a/src/client/views/nodes/DocumentContentsView.tsx b/src/client/views/nodes/DocumentContentsView.tsx index 81667e549..395a6e0b2 100644 --- a/src/client/views/nodes/DocumentContentsView.tsx +++ b/src/client/views/nodes/DocumentContentsView.tsx @@ -14,7 +14,7 @@ import { LabelBox } from "./LabelBox"; import { SliderBox } from "./SliderBox"; import { LinkBox } from "./LinkBox"; import { ScriptingBox } from "./ScriptingBox"; -import { DocHolderBox } from "./DocumentBox"; +import { DocHolderBox } from "./DocHolderBox"; import { DocumentViewProps } from "./DocumentView"; import "./DocumentView.scss"; import { FontIconBox } from "./FontIconBox"; diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx index 7a81801e1..86e58ca7a 100644 --- a/src/client/views/nodes/DocumentView.tsx +++ b/src/client/views/nodes/DocumentView.tsx @@ -23,6 +23,7 @@ import { Docs, DocUtils } from "../../documents/Documents"; import { DocumentType } from '../../documents/DocumentTypes'; import { ClientUtils } from '../../util/ClientUtils'; import { DocumentManager } from "../../util/DocumentManager"; +import { SnappingManager } from '../../util/SnappingManager'; import { DragManager, dropActionType } from "../../util/DragManager"; import { InteractionUtils } from '../../util/InteractionUtils'; import { Scripting } from '../../util/Scripting'; @@ -1105,7 +1106,7 @@ export class DocumentView extends DocComponent(Docu } @computed get ignorePointerEvents() { return this.props.pointerEvents === false || - (this.Document.isBackground && !this.isSelected() && !DragManager.Vals.Instance.GetIsDragging()) || + (this.Document.isBackground && !this.isSelected() && !SnappingManager.GetIsDragging()) || (this.Document.type === DocumentType.INK && InkingControl.Instance.selectedTool !== InkTool.None); } @undoBatch diff --git a/src/client/views/nodes/QueryBox.tsx b/src/client/views/nodes/QueryBox.tsx index d248b098c..2a21a380d 100644 --- a/src/client/views/nodes/QueryBox.tsx +++ b/src/client/views/nodes/QueryBox.tsx @@ -5,13 +5,12 @@ import { documentSchema } from "../../../new_fields/documentSchemas"; import { Id } from '../../../new_fields/FieldSymbols'; import { makeInterface, listSpec } from "../../../new_fields/Schema"; import { StrCast, Cast } from "../../../new_fields/Types"; -import { SelectionManager } from "../../util/SelectionManager"; import { ViewBoxAnnotatableComponent } from '../DocComponent'; import { SearchBox } from "../search/SearchBox"; import { FieldView, FieldViewProps } from './FieldView'; import "./QueryBox.scss"; import { List } from "../../../new_fields/List"; -import { DragManager } from "../../util/DragManager"; +import { SnappingManager } from "../../util/SnappingManager"; type QueryDocument = makeInterface<[typeof documentSchema]>; const QueryDocument = makeInterface(documentSchema); @@ -28,7 +27,7 @@ export class QueryBox extends ViewBoxAnnotatableComponent e.stopPropagation()} >