From 92c3bd4102e40f2f4bfd93e10d0a4a57316614c1 Mon Sep 17 00:00:00 2001 From: bobzel Date: Mon, 22 Apr 2019 11:54:45 -0400 Subject: better fix --- src/client/util/DragManager.ts | 1 + 1 file changed, 1 insertion(+) (limited to 'src/client/util/DragManager.ts') diff --git a/src/client/util/DragManager.ts b/src/client/util/DragManager.ts index 46658867b..465b97981 100644 --- a/src/client/util/DragManager.ts +++ b/src/client/util/DragManager.ts @@ -174,6 +174,7 @@ export namespace DragManager { if (!dragDiv) { dragDiv = document.createElement("div"); dragDiv.className = "dragManager-dragDiv"; + dragDiv.style.pointerEvents = "none"; DragManager.Root().appendChild(dragDiv); } MainOverlayTextBox.Instance.SetTextDoc(); -- cgit v1.2.3-70-g09d2 From d2a95b1aa144e8dd4e87338525922dae1f3d9e67 Mon Sep 17 00:00:00 2001 From: bob Date: Wed, 24 Apr 2019 09:56:59 -0400 Subject: added blacklist to stop docs form linking to their parent collection. refactored drag threshold to Utils --- src/Utils.ts | 2 + src/client/util/DragManager.ts | 4 +- src/client/views/DocumentDecorations.tsx | 9 +++-- .../collections/collectionFreeForm/MarqueeView.tsx | 10 ++--- src/client/views/nodes/DocumentView.tsx | 43 ++++++++++++---------- 5 files changed, 39 insertions(+), 29 deletions(-) (limited to 'src/client/util/DragManager.ts') diff --git a/src/Utils.ts b/src/Utils.ts index 98f75d3b9..8252ba011 100644 --- a/src/Utils.ts +++ b/src/Utils.ts @@ -6,6 +6,8 @@ import { Document } from './fields/Document'; export class Utils { + public static DRAG_THRESHOLD = 4; + public static GenerateGuid(): string { return v4(); } diff --git a/src/client/util/DragManager.ts b/src/client/util/DragManager.ts index 465b97981..91b3ce616 100644 --- a/src/client/util/DragManager.ts +++ b/src/client/util/DragManager.ts @@ -158,11 +158,13 @@ export namespace DragManager { } export class LinkDragData { - constructor(linkSourceDoc: Document) { + constructor(linkSourceDoc: Document, blacklist: Document[] = []) { this.linkSourceDocument = linkSourceDoc; + this.blacklist = blacklist; } droppedDocuments: Document[] = []; linkSourceDocument: Document; + blacklist: Document[]; [id: string]: any; } diff --git a/src/client/views/DocumentDecorations.tsx b/src/client/views/DocumentDecorations.tsx index 539f19707..5c57a829a 100644 --- a/src/client/views/DocumentDecorations.tsx +++ b/src/client/views/DocumentDecorations.tsx @@ -19,6 +19,7 @@ import { CompileScript } from "../util/Scripting"; import { IconBox } from "./nodes/IconBox"; import { FieldValue, Field } from "../../fields/Field"; import { Documents } from "../documents/Documents"; +import { Utils } from "../northstar/utils/Utils"; const higflyout = require("@hig/flyout"); export const { anchorPoints } = higflyout; export const Flyout = higflyout.default; @@ -207,8 +208,8 @@ export class DocumentDecorations extends React.Component<{}, { value: string }> @action onMinimizeMove = (e: PointerEvent): void => { e.stopPropagation(); - let moved = Math.abs(e.pageX - this._downX) > 4 || Math.abs(e.pageY - this._downY) > 4; - if (moved) { + if (Math.abs(e.pageX - this._downX) > Utils.DRAG_THRESHOLD || + Math.abs(e.pageY - this._downY) > Utils.DRAG_THRESHOLD) { let selDoc = SelectionManager.SelectedDocuments()[0]; let selDocPos = selDoc.props.ScreenToLocalTransform().scale(selDoc.props.ContentScaling()).inverse().transformPoint(0, 0); let snapped = Math.abs(e.pageX - selDocPos[0]) < 20 && Math.abs(e.pageY - selDocPos[1]) < 20; @@ -316,7 +317,9 @@ export class DocumentDecorations extends React.Component<{}, { value: string }> if (this._linkerButton.current !== null) { document.removeEventListener("pointermove", this.onLinkerButtonMoved); document.removeEventListener("pointerup", this.onLinkerButtonUp); - let dragData = new DragManager.LinkDragData(SelectionManager.SelectedDocuments()[0].props.Document); + let selDoc = SelectionManager.SelectedDocuments()[0]; + let container = selDoc.props.ContainingCollectionView ? selDoc.props.ContainingCollectionView.props.Document.GetPrototype() : undefined; + let dragData = new DragManager.LinkDragData(selDoc.props.Document, container ? [container] : []); DragManager.StartLinkDrag(this._linkerButton.current, dragData, e.pageX, e.pageY, { handlers: { dragComplete: action(emptyFunction), diff --git a/src/client/views/collections/collectionFreeForm/MarqueeView.tsx b/src/client/views/collections/collectionFreeForm/MarqueeView.tsx index 06e8a9fc6..39b42dac9 100644 --- a/src/client/views/collections/collectionFreeForm/MarqueeView.tsx +++ b/src/client/views/collections/collectionFreeForm/MarqueeView.tsx @@ -13,6 +13,7 @@ import { PreviewCursor } from "../../PreviewCursor"; import { CollectionFreeFormView } from "./CollectionFreeFormView"; import "./MarqueeView.scss"; import React = require("react"); +import { Utils } from "../../../../Utils"; interface MarqueeViewProps { getContainerTransform: () => Transform; @@ -33,7 +34,6 @@ export class MarqueeView extends React.Component @observable _downX: number = 0; @observable _downY: number = 0; @observable _visible: boolean = false; - static DRAG_THRESHOLD = 4; @action cleanupInteractions = (all: boolean = false) => { @@ -74,8 +74,8 @@ export class MarqueeView extends React.Component this._lastX = e.pageX; this._lastY = e.pageY; if (!e.cancelBubble) { - if (Math.abs(this._lastX - this._downX) > MarqueeView.DRAG_THRESHOLD || - Math.abs(this._lastY - this._downY) > MarqueeView.DRAG_THRESHOLD) { + if (Math.abs(this._lastX - this._downX) > Utils.DRAG_THRESHOLD || + Math.abs(this._lastY - this._downY) > Utils.DRAG_THRESHOLD) { this._visible = true; e.stopPropagation(); e.preventDefault(); @@ -101,8 +101,8 @@ export class MarqueeView extends React.Component @action onClick = (e: React.MouseEvent): void => { - if (Math.abs(e.clientX - this._downX) < MarqueeView.DRAG_THRESHOLD && - Math.abs(e.clientY - this._downY) < MarqueeView.DRAG_THRESHOLD) { + if (Math.abs(e.clientX - this._downX) < Utils.DRAG_THRESHOLD && + Math.abs(e.clientY - this._downY) < Utils.DRAG_THRESHOLD) { PreviewCursor.Show(e.clientX, e.clientY, this.onKeyPress); // let the DocumentView stopPropagation of this event when it selects this document } else { // why do we get a click event when the cursor have moved a big distance? diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx index b3b9f6e51..252f4d039 100644 --- a/src/client/views/nodes/DocumentView.tsx +++ b/src/client/views/nodes/DocumentView.tsx @@ -148,7 +148,8 @@ export class DocumentView extends React.Component { onClick = (e: React.MouseEvent): void => { if (CurrentUserUtils.MainDocId != this.props.Document.Id && - (Math.abs(e.clientX - this._downX) < MarqueeView.DRAG_THRESHOLD && Math.abs(e.clientY - this._downY) < MarqueeView.DRAG_THRESHOLD)) { + (Math.abs(e.clientX - this._downX) < Utils.DRAG_THRESHOLD && + Math.abs(e.clientY - this._downY) < Utils.DRAG_THRESHOLD)) { SelectionManager.SelectDoc(this, e.ctrlKey); } e.stopPropagation(); @@ -230,25 +231,27 @@ export class DocumentView extends React.Component { let dstTarg = protoDest ? protoDest : destDoc; let srcTarg = protoSrc ? protoSrc : sourceDoc; - linkDoc.Set(KeyStore.LinkedToDocs, dstTarg); - linkDoc.Set(KeyStore.LinkedFromDocs, srcTarg); - const prom1 = new Promise(resolve => dstTarg.GetOrCreateAsync( - KeyStore.LinkedFromDocs, - ListField, - field => { - (field as ListField).Data.push(linkDoc); - resolve(); - } - )); - const prom2 = new Promise(resolve => srcTarg.GetOrCreateAsync( - KeyStore.LinkedToDocs, - ListField, - field => { - (field as ListField).Data.push(linkDoc); - resolve(); - } - )); - Promise.all([prom1, prom2]).finally(() => batch.end()); + if ((de.data as DragManager.LinkDragData).blacklist.indexOf(dstTarg) === -1) { + linkDoc.Set(KeyStore.LinkedToDocs, dstTarg); + linkDoc.Set(KeyStore.LinkedFromDocs, srcTarg); + const prom1 = new Promise(resolve => dstTarg.GetOrCreateAsync( + KeyStore.LinkedFromDocs, + ListField, + field => { + (field as ListField).Data.push(linkDoc); + resolve(); + } + )); + const prom2 = new Promise(resolve => srcTarg.GetOrCreateAsync( + KeyStore.LinkedToDocs, + ListField, + field => { + (field as ListField).Data.push(linkDoc); + resolve(); + } + )); + Promise.all([prom1, prom2]).finally(() => batch.end()); + } }) ) ); -- cgit v1.2.3-70-g09d2 From 20becbb5ca40350ed85e01f73f29621ba7783bb9 Mon Sep 17 00:00:00 2001 From: bob Date: Wed, 24 Apr 2019 12:20:38 -0400 Subject: playing with linking --- src/client/util/DragManager.ts | 6 ++-- src/client/views/DocumentDecorations.tsx | 3 +- src/client/views/PreviewCursor.tsx | 8 +++-- .../collections/collectionFreeForm/MarqueeView.tsx | 33 ++++++++++++++++--- .../views/nodes/CollectionFreeFormDocumentView.tsx | 16 ++++----- src/client/views/nodes/DocumentView.tsx | 38 ++-------------------- src/client/views/nodes/FormattedTextBox.tsx | 2 ++ src/fields/Document.ts | 31 ++++++++++++++++++ 8 files changed, 80 insertions(+), 57 deletions(-) (limited to 'src/client/util/DragManager.ts') diff --git a/src/client/util/DragManager.ts b/src/client/util/DragManager.ts index 91b3ce616..5aa7ad8e2 100644 --- a/src/client/util/DragManager.ts +++ b/src/client/util/DragManager.ts @@ -41,11 +41,11 @@ export function SetupDrag(_reference: React.RefObject, docFunc: } export async function DragLinksAsDocuments(dragEle: HTMLElement, x: number, y: number, sourceDoc: Document) { - let srcTarg = sourceDoc.GetT(KeyStore.Prototype, Document); - let draggedDocs = (srcTarg && srcTarg !== FieldWaiting) ? + let srcTarg = sourceDoc.GetPrototype(); + let draggedDocs = srcTarg ? srcTarg.GetList(KeyStore.LinkedToDocs, [] as Document[]).map(linkDoc => (linkDoc.GetT(KeyStore.LinkedToDocs, Document)) as Document) : []; - let draggedFromDocs = (srcTarg && srcTarg !== FieldWaiting) ? + let draggedFromDocs = srcTarg ? srcTarg.GetList(KeyStore.LinkedFromDocs, [] as Document[]).map(linkDoc => (linkDoc.GetT(KeyStore.LinkedFromDocs, Document)) as Document) : []; draggedDocs.push(...draggedFromDocs); diff --git a/src/client/views/DocumentDecorations.tsx b/src/client/views/DocumentDecorations.tsx index 5c57a829a..9995c1c3f 100644 --- a/src/client/views/DocumentDecorations.tsx +++ b/src/client/views/DocumentDecorations.tsx @@ -6,7 +6,7 @@ import { ListField } from "../../fields/ListField"; import { NumberField } from "../../fields/NumberField"; import { TextField } from "../../fields/TextField"; import { Document } from "../../fields/Document"; -import { emptyFunction } from "../../Utils"; +import { emptyFunction, Utils } from "../../Utils"; import { DragLinksAsDocuments, DragManager } from "../util/DragManager"; import { SelectionManager } from "../util/SelectionManager"; import { undoBatch } from "../util/UndoManager"; @@ -19,7 +19,6 @@ import { CompileScript } from "../util/Scripting"; import { IconBox } from "./nodes/IconBox"; import { FieldValue, Field } from "../../fields/Field"; import { Documents } from "../documents/Documents"; -import { Utils } from "../northstar/utils/Utils"; const higflyout = require("@hig/flyout"); export const { anchorPoints } = higflyout; export const Flyout = higflyout.default; diff --git a/src/client/views/PreviewCursor.tsx b/src/client/views/PreviewCursor.tsx index 39b6c6544..744ec0535 100644 --- a/src/client/views/PreviewCursor.tsx +++ b/src/client/views/PreviewCursor.tsx @@ -17,7 +17,7 @@ export class PreviewCursor extends React.Component<{}> { constructor(props: any) { super(props); - document.addEventListener("keypress", this.onKeyPress) + document.addEventListener("keydown", this.onKeyPress) } @action @@ -28,8 +28,12 @@ export class PreviewCursor extends React.Component<{}> { //if not these keys, make a textbox if preview cursor is active! if (!e.ctrlKey && !e.altKey && !e.defaultPrevented && !(e as any).DASHFormattedTextBoxHandled) { PreviewCursor.Visible && PreviewCursor._onKeyPress && PreviewCursor._onKeyPress(e); + PreviewCursor.Visible = false; + } else if (e.ctrlKey) { + if (e.key == "v") { + PreviewCursor.Visible && PreviewCursor._onKeyPress && PreviewCursor._onKeyPress(e); + } } - PreviewCursor.Visible = false; } @action public static Show(x: number, y: number, onKeyPress: (e: KeyboardEvent) => void) { diff --git a/src/client/views/collections/collectionFreeForm/MarqueeView.tsx b/src/client/views/collections/collectionFreeForm/MarqueeView.tsx index 39b42dac9..898fff019 100644 --- a/src/client/views/collections/collectionFreeForm/MarqueeView.tsx +++ b/src/client/views/collections/collectionFreeForm/MarqueeView.tsx @@ -14,6 +14,7 @@ import { CollectionFreeFormView } from "./CollectionFreeFormView"; import "./MarqueeView.scss"; import React = require("react"); import { Utils } from "../../../../Utils"; +import { ListField } from "../../../../fields/ListField"; interface MarqueeViewProps { getContainerTransform: () => Transform; @@ -128,16 +129,16 @@ export class MarqueeView extends React.Component @undoBatch @action marqueeCommand = (e: KeyboardEvent) => { - if (e.key === "Backspace" || e.key === "Delete") { + if (e.key === "Backspace" || e.key === "Delete" || e.key == "d") { this.marqueeSelect().map(d => this.props.removeDocument(d)); let ink = this.props.container.props.Document.GetT(KeyStore.Ink, InkField); if (ink && ink !== FieldWaiting) { this.marqueeInkDelete(ink.Data); } - this.cleanupInteractions(); + this.cleanupInteractions(true); e.stopPropagation(); } - if (e.key === "c") { + if (e.key === "c" || e.key === "r") { e.stopPropagation(); let bounds = this.Bounds; let selected = this.marqueeSelect().map(d => { @@ -155,16 +156,38 @@ export class MarqueeView extends React.Component y: bounds.top, panx: 0, pany: 0, + backgroundColor: selected.length ? "white" : "", scale: zoomBasis, width: bounds.width * zoomBasis, height: bounds.height * zoomBasis, ink: inkData ? this.marqueeInkSelect(inkData) : undefined, title: "a nested collection" }); - this.props.addDocument(newCollection, false); + this.marqueeInkDelete(inkData); - this.cleanupInteractions(); SelectionManager.DeselectAll(); + if (e.key === "r") { + let summary = Documents.TextDocument({ x: bounds.left, y: bounds.top, width: 300, height: 100, backgroundColor: "yellow", title: "-summary-" }); + summary.GetPrototype()!.CreateLink(newCollection.GetPrototype()!); + this.props.addLiveTextDocument(summary); + e.preventDefault(); + } + else { + this.props.addDocument(newCollection, false); + } + this.cleanupInteractions(true); + } + if (e.key === "s") { + e.stopPropagation(); + e.preventDefault(); + let bounds = this.Bounds; + let selected = this.marqueeSelect(); + SelectionManager.DeselectAll(); + let summary = Documents.TextDocument({ x: bounds.left + bounds.width + 25, y: bounds.top, width: 300, height: 100, backgroundColor: "yellow", title: "-summary-" }); + this.props.addLiveTextDocument(summary); + selected.map(select => summary.GetPrototype()!.CreateLink(select.GetPrototype()!)); + + this.cleanupInteractions(true); } } @action diff --git a/src/client/views/nodes/CollectionFreeFormDocumentView.tsx b/src/client/views/nodes/CollectionFreeFormDocumentView.tsx index 671bfbc04..420324d40 100644 --- a/src/client/views/nodes/CollectionFreeFormDocumentView.tsx +++ b/src/client/views/nodes/CollectionFreeFormDocumentView.tsx @@ -7,7 +7,7 @@ import { Transform } from "../../util/Transform"; import { DocumentView, DocumentViewProps } from "./DocumentView"; import "./DocumentView.scss"; import React = require("react"); -import { OmitKeys } from "../../../Utils"; +import { OmitKeys, Utils } from "../../../Utils"; import { SelectionManager } from "../../util/SelectionManager"; import { ListField } from "../../../fields/ListField"; import { BooleanField } from "../../../fields/BooleanField"; @@ -102,9 +102,7 @@ export class CollectionFreeFormDocumentView extends React.Component => { SelectionManager.DeselectAll(); let isMinimized: boolean | undefined; - let minDoc = await this.props.Document.GetTAsync(KeyStore.MinimizedDoc, Document); - if (!minDoc) return; - let minimizedDocSet = await minDoc.GetTAsync(KeyStore.LinkTags, ListField); + let minimizedDocSet = await this.props.Document.GetTAsync(KeyStore.LinkTags, ListField); if (!minimizedDocSet) return; minimizedDocSet.Data.map(async minimizedDoc => { if (minimizedDoc instanceof Document) { @@ -136,16 +134,13 @@ export class CollectionFreeFormDocumentView extends React.Component { this._downX = e.clientX; this._downY = e.clientY; - document.removeEventListener("pointerup", this.onPointerUp); - document.addEventListener("pointerup", this.onPointerUp); } - onPointerUp = (e: PointerEvent): void => { - document.removeEventListener("pointerup", this.onPointerUp); + onClick = (e: React.MouseEvent): void => { e.stopPropagation(); - if (Math.abs(e.clientX - this._downX) < 4 && Math.abs(e.clientY - this._downY) < 4) { + if (Math.abs(e.clientX - this._downX) < Utils.DRAG_THRESHOLD && + Math.abs(e.clientY - this._downY) < Utils.DRAG_THRESHOLD) { this.props.Document.GetTAsync(KeyStore.MaximizedDoc, Document).then(maxdoc => { if (maxdoc instanceof Document) { // bcz: need a better way to associate behaviors with click events on widget-documents - SelectionManager.DeselectAll(); this.props.addDocument && this.props.addDocument(maxdoc, false); this.toggleIcon(); } @@ -170,6 +165,7 @@ export class CollectionFreeFormDocumentView extends React.Component { Math.abs(e.clientY - this._downY) < Utils.DRAG_THRESHOLD)) { SelectionManager.SelectDoc(this, e.ctrlKey); } - e.stopPropagation(); } onPointerDown = (e: React.PointerEvent): void => { this._downX = e.clientX; @@ -217,43 +216,12 @@ export class DocumentView extends React.Component { @action drop = (e: Event, de: DragManager.DropEvent) => { if (de.data instanceof DragManager.LinkDragData) { - let sourceDoc: Document = de.data.linkSourceDocument; - let destDoc: Document = this.props.Document; - let linkDoc: Document = new Document(); + let sourceDoc = de.data.linkSourceDocument; + let destDoc = this.props.Document; destDoc.GetTAsync(KeyStore.Prototype, Document).then(protoDest => sourceDoc.GetTAsync(KeyStore.Prototype, Document).then(protoSrc => - runInAction(() => { - let batch = UndoManager.StartBatch("document view drop"); - linkDoc.SetText(KeyStore.Title, "New Link"); - linkDoc.SetText(KeyStore.LinkDescription, ""); - linkDoc.SetText(KeyStore.LinkTags, "Default"); - - let dstTarg = protoDest ? protoDest : destDoc; - let srcTarg = protoSrc ? protoSrc : sourceDoc; - if ((de.data as DragManager.LinkDragData).blacklist.indexOf(dstTarg) === -1) { - linkDoc.Set(KeyStore.LinkedToDocs, dstTarg); - linkDoc.Set(KeyStore.LinkedFromDocs, srcTarg); - const prom1 = new Promise(resolve => dstTarg.GetOrCreateAsync( - KeyStore.LinkedFromDocs, - ListField, - field => { - (field as ListField).Data.push(linkDoc); - resolve(); - } - )); - const prom2 = new Promise(resolve => srcTarg.GetOrCreateAsync( - KeyStore.LinkedToDocs, - ListField, - field => { - (field as ListField).Data.push(linkDoc); - resolve(); - } - )); - Promise.all([prom1, prom2]).finally(() => batch.end()); - } - }) - ) + (protoSrc ? protoSrc : sourceDoc).CreateLink(protoDest ? protoDest : destDoc)) ); e.stopPropagation(); } diff --git a/src/client/views/nodes/FormattedTextBox.tsx b/src/client/views/nodes/FormattedTextBox.tsx index 91b44962d..9cd58c73a 100644 --- a/src/client/views/nodes/FormattedTextBox.tsx +++ b/src/client/views/nodes/FormattedTextBox.tsx @@ -270,8 +270,10 @@ export class FormattedTextBox extends React.Component<(FieldViewProps & Formatte } render() { let style = this.props.isOverlay ? "scroll" : "hidden"; + let color = this.props.Document.GetText(KeyStore.BackgroundColor, ""); return (
dstTarg.GetOrCreateAsync( + KeyStore.LinkedFromDocs, + ListField, + field => { + (field as ListField).Data.push(linkDoc); + resolve(); + } + )); + const prom2 = new Promise(resolve => srcTarg.GetOrCreateAsync( + KeyStore.LinkedToDocs, + ListField, + field => { + (field as ListField).Data.push(linkDoc); + resolve(); + } + )); + Promise.all([prom1, prom2]).finally(() => batch.end()); + return linkDoc; + } + MakeDelegate(id?: string): Document { let delegate = new Document(id); -- cgit v1.2.3-70-g09d2 From 430c14fe9d059ea3f7905d30500ba53f4fc288b9 Mon Sep 17 00:00:00 2001 From: Tyler Schicke Date: Sat, 27 Apr 2019 16:07:40 -0400 Subject: Drag manager --- src/client/util/DragManager.ts | 38 +++++++++++++++++++------------------- src/new_fields/Doc.ts | 28 ++++++++++++++++++++++++++++ 2 files changed, 47 insertions(+), 19 deletions(-) (limited to 'src/client/util/DragManager.ts') diff --git a/src/client/util/DragManager.ts b/src/client/util/DragManager.ts index 5aa7ad8e2..0174b2f54 100644 --- a/src/client/util/DragManager.ts +++ b/src/client/util/DragManager.ts @@ -1,14 +1,14 @@ import { action } from "mobx"; -import { Document } from "../../fields/Document"; -import { FieldWaiting } from "../../fields/Field"; -import { KeyStore } from "../../fields/KeyStore"; import { emptyFunction } from "../../Utils"; import { CollectionDockingView } from "../views/collections/CollectionDockingView"; import { DocumentDecorations } from "../views/DocumentDecorations"; import * as globalCssVariables from "../views/globalCssVariables.scss"; import { MainOverlayTextBox } from "../views/MainOverlayTextBox"; +import { Doc } from "../../new_fields/Doc"; +import { Cast } from "../../new_fields/Types"; +import { listSpec } from "../../new_fields/Schema"; -export function SetupDrag(_reference: React.RefObject, docFunc: () => Document, moveFunc?: DragManager.MoveFunction, copyOnDrop: boolean = false) { +export function SetupDrag(_reference: React.RefObject, docFunc: () => Doc, moveFunc?: DragManager.MoveFunction, copyOnDrop: boolean = false) { let onRowMove = action((e: PointerEvent): void => { e.stopPropagation(); e.preventDefault(); @@ -40,19 +40,19 @@ export function SetupDrag(_reference: React.RefObject, docFunc: return onItemDown; } -export async function DragLinksAsDocuments(dragEle: HTMLElement, x: number, y: number, sourceDoc: Document) { - let srcTarg = sourceDoc.GetPrototype(); +export async function DragLinksAsDocuments(dragEle: HTMLElement, x: number, y: number, sourceDoc: Doc) { + let srcTarg = sourceDoc.proto; let draggedDocs = srcTarg ? - srcTarg.GetList(KeyStore.LinkedToDocs, [] as Document[]).map(linkDoc => - (linkDoc.GetT(KeyStore.LinkedToDocs, Document)) as Document) : []; + Cast(srcTarg.linkedToDocs, listSpec(Doc), []).map(linkDoc => + Cast(linkDoc.linkedTo, Doc) as Doc) : []; let draggedFromDocs = srcTarg ? - srcTarg.GetList(KeyStore.LinkedFromDocs, [] as Document[]).map(linkDoc => - (linkDoc.GetT(KeyStore.LinkedFromDocs, Document)) as Document) : []; + Cast(srcTarg.linkedFromDocs, listSpec(Doc), []).map(linkDoc => + Cast(linkDoc.linkedFrom, Doc) as Doc) : []; draggedDocs.push(...draggedFromDocs); if (draggedDocs.length) { - let moddrag = [] as Document[]; + let moddrag: Doc[] = []; for (const draggedDoc of draggedDocs) { - let doc = await draggedDoc.GetTAsync(KeyStore.AnnotationOn, Document); + let doc = await Cast(draggedDoc.annotationOn, Doc); if (doc) moddrag.push(doc); } let dragData = new DragManager.DocumentDragData(moddrag.length ? moddrag : draggedDocs); @@ -134,16 +134,16 @@ export namespace DragManager { }; } - export type MoveFunction = (document: Document, targetCollection: Document, addDocument: (document: Document) => boolean) => boolean; + export type MoveFunction = (document: Doc, targetCollection: Doc, addDocument: (document: Doc) => boolean) => boolean; export class DocumentDragData { - constructor(dragDoc: Document[]) { + constructor(dragDoc: Doc[]) { this.draggedDocuments = dragDoc; this.droppedDocuments = dragDoc; this.xOffset = 0; this.yOffset = 0; } - draggedDocuments: Document[]; - droppedDocuments: Document[]; + draggedDocuments: Doc[]; + droppedDocuments: Doc[]; xOffset: number; yOffset: number; aliasOnDrop?: boolean; @@ -154,7 +154,7 @@ export namespace DragManager { export function StartDocumentDrag(eles: HTMLElement[], dragData: DocumentDragData, downX: number, downY: number, options?: DragOptions) { StartDrag(eles, dragData, downX, downY, options, - (dropData: { [id: string]: any }) => (dropData.droppedDocuments = dragData.aliasOnDrop ? dragData.draggedDocuments.map(d => d.CreateAlias()) : dragData.copyOnDrop ? dragData.draggedDocuments.map(d => d.Copy(true) as Document) : dragData.draggedDocuments)); + (dropData: { [id: string]: any }) => (dropData.droppedDocuments = dragData.aliasOnDrop ? dragData.draggedDocuments.map(d => Doc.MakeAlias(d)) : dragData.copyOnDrop ? dragData.draggedDocuments.map(d => Doc.MakeCopy(d, true)) : dragData.draggedDocuments)); } export class LinkDragData { @@ -186,7 +186,7 @@ export namespace DragManager { let xs: number[] = []; let ys: number[] = []; - const docs: Document[] = + const docs: Doc[] = dragData instanceof DocumentDragData ? dragData.draggedDocuments : []; let dragElements = eles.map(ele => { const w = ele.offsetWidth, @@ -275,7 +275,7 @@ export namespace DragManager { AbortDrag = () => { document.removeEventListener("pointermove", moveHandler, true); document.removeEventListener("pointerup", upHandler); - dragElements.map(dragElement => { if (dragElement.parentNode == dragDiv) dragDiv.removeChild(dragElement); }); + dragElements.map(dragElement => { if (dragElement.parentNode === dragDiv) dragDiv.removeChild(dragElement); }); eles.map(ele => (ele.hidden = false)); }; const upHandler = (e: PointerEvent) => { diff --git a/src/new_fields/Doc.ts b/src/new_fields/Doc.ts index a1515fe49..fb7b6e360 100644 --- a/src/new_fields/Doc.ts +++ b/src/new_fields/Doc.ts @@ -34,6 +34,13 @@ export class ObjectField { readonly [Id] = ""; } +export namespace ObjectField { + export function MakeCopy(field: ObjectField) { + //TODO Types + return field; + } +} + export function IsField(field: any): field is Field { return (typeof field === "string") || (typeof field === "number") @@ -137,6 +144,27 @@ export namespace Doc { return alias; } + export function MakeCopy(doc: Doc, copyProto: boolean = false): Doc { + const copy = new Doc; + Object.keys(doc).forEach(async key => { + const field = await doc[key]; + if (key === "proto" && copyProto) { + if (field instanceof Doc) { + copy[key] = Doc.MakeCopy(field); + } + } else { + if (field instanceof RefField) { + copy[key] = field; + } else if (field instanceof ObjectField) { + copy[key] = ObjectField.MakeCopy(field); + } else { + copy[key] = field; + } + } + }) + return copy; + } + export function MakeLink(source: Doc, target: Doc): Doc { let linkDoc = new Doc; UndoManager.RunInBatch(() => { -- cgit v1.2.3-70-g09d2 From 7a820b3b175ea52712927e75ce16e32f0ed3a131 Mon Sep 17 00:00:00 2001 From: Tyler Schicke Date: Sat, 27 Apr 2019 19:51:58 -0400 Subject: Compiling --- src/client/util/DragManager.ts | 8 +++---- src/client/views/MainOverlayTextBox.tsx | 17 +++++++------- .../collectionFreeForm/CollectionFreeFormView.tsx | 2 +- src/client/views/nodes/FormattedTextBox.tsx | 17 ++++++-------- src/fields/RichTextField.ts | 26 ---------------------- src/new_fields/RichTextField.ts | 12 ++++++++++ src/new_fields/Types.ts | 14 ++++++------ 7 files changed, 39 insertions(+), 57 deletions(-) delete mode 100644 src/fields/RichTextField.ts create mode 100644 src/new_fields/RichTextField.ts (limited to 'src/client/util/DragManager.ts') diff --git a/src/client/util/DragManager.ts b/src/client/util/DragManager.ts index 0174b2f54..e65f2b9ed 100644 --- a/src/client/util/DragManager.ts +++ b/src/client/util/DragManager.ts @@ -158,13 +158,13 @@ export namespace DragManager { } export class LinkDragData { - constructor(linkSourceDoc: Document, blacklist: Document[] = []) { + constructor(linkSourceDoc: Doc, blacklist: Doc[] = []) { this.linkSourceDocument = linkSourceDoc; this.blacklist = blacklist; } - droppedDocuments: Document[] = []; - linkSourceDocument: Document; - blacklist: Document[]; + droppedDocuments: Doc[] = []; + linkSourceDocument: Doc; + blacklist: Doc[]; [id: string]: any; } diff --git a/src/client/views/MainOverlayTextBox.tsx b/src/client/views/MainOverlayTextBox.tsx index be8d67925..a7ced36bf 100644 --- a/src/client/views/MainOverlayTextBox.tsx +++ b/src/client/views/MainOverlayTextBox.tsx @@ -2,16 +2,15 @@ import { action, observable, trace } from 'mobx'; import { observer } from 'mobx-react'; import "normalize.css"; import * as React from 'react'; -import { Document } from '../../fields/Document'; -import { Key } from '../../fields/Key'; -import { KeyStore } from '../../fields/KeyStore'; -import { emptyDocFunction, emptyFunction, returnTrue, returnZero } from '../../Utils'; +import { emptyFunction, returnTrue, returnZero } from '../../Utils'; import '../northstar/model/ModelExtensions'; import '../northstar/utils/Extensions'; import { DragManager } from '../util/DragManager'; import { Transform } from '../util/Transform'; import "./MainOverlayTextBox.scss"; import { FormattedTextBox } from './nodes/FormattedTextBox'; +import { Doc } from '../../new_fields/Doc'; +import { NumCast } from '../../new_fields/Types'; interface MainOverlayTextBoxProps { } @@ -19,11 +18,11 @@ interface MainOverlayTextBoxProps { @observer export class MainOverlayTextBox extends React.Component { public static Instance: MainOverlayTextBox; - @observable public TextDoc?: Document = undefined; + @observable public TextDoc?: Doc = undefined; public TextScroll: number = 0; @observable _textRect: any; @observable _textXf: () => Transform = () => Transform.Identity(); - private _textFieldKey: Key = KeyStore.Data; + private _textFieldKey: string = "data"; private _textColor: string | null = null; private _textTargetDiv: HTMLDivElement | undefined; private _textProxyDiv: React.RefObject; @@ -35,7 +34,7 @@ export class MainOverlayTextBox extends React.Component } @action - SetTextDoc(textDoc?: Document, textFieldKey?: Key, div?: HTMLDivElement, tx?: () => Transform) { + SetTextDoc(textDoc?: Doc, textFieldKey?: string, div?: HTMLDivElement, tx?: () => Transform) { if (this._textTargetDiv) { this._textTargetDiv.style.color = this._textColor; } @@ -94,10 +93,10 @@ export class MainOverlayTextBox extends React.Component let s = 1 / this._textXf().Scale; return
+ style={{ width: `${NumCast(this.TextDoc.width)}px`, height: `${NumCast(this.TextDoc.height)}px` }}> + ScreenToLocalTransform={this._textXf} PanelWidth={returnZero} PanelHeight={returnZero} focus={emptyFunction} />
; } diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx index 80900c450..047fbad18 100644 --- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx +++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx @@ -97,7 +97,7 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) { if (!NumCast(d.height)) { let nw = NumCast(d.nativeWidth); let nh = NumCast(d.nativeHeight); - d.height = nw && nh ? nh / nw * d.Width() : 300; + d.height = nw && nh ? nh / nw * NumCast(d.Width) : 300; } this.bringToFront(d); }); diff --git a/src/client/views/nodes/FormattedTextBox.tsx b/src/client/views/nodes/FormattedTextBox.tsx index c65b1ac89..7a85c9dd3 100644 --- a/src/client/views/nodes/FormattedTextBox.tsx +++ b/src/client/views/nodes/FormattedTextBox.tsx @@ -20,7 +20,8 @@ import { createSchema, makeInterface } from "../../../new_fields/Schema"; import { Opt, Doc } from "../../../new_fields/Doc"; import { observer } from "mobx-react"; import { InkingControl } from "../InkingControl"; -import { StrCast } from "../../../new_fields/Types"; +import { StrCast, Cast } from "../../../new_fields/Types"; +import { RichTextField } from "../../../new_fields/RichTextField"; const { buildMenuItems } = require("prosemirror-example-setup"); const { menuBar } = require("prosemirror-menu"); @@ -77,11 +78,7 @@ export class FormattedTextBox extends DocComponent<(FieldViewProps & FormattedTe const state = this._editorView.state.apply(tx); this._editorView.updateState(state); this._applyingChange = true; - this.props.Document.SetDataOnPrototype( - this.props.fieldKey, - JSON.stringify(state.toJSON()), - RichTextField - ); + Doc.SetOnPrototype(this.props.Document, this.props.fieldKey, new RichTextField(JSON.stringify(state.toJSON()))); Doc.SetOnPrototype(this.props.Document, "documentText", state.doc.textBetween(0, state.doc.content.size, "\n\n")); this._applyingChange = false; // doc.SetData(fieldKey, JSON.stringify(state.toJSON()), RichTextField); @@ -127,8 +124,8 @@ export class FormattedTextBox extends DocComponent<(FieldViewProps & FormattedTe this._reactionDisposer = reaction( () => { - const field = this.props.Document ? this.props.Document.GetT(this.props.fieldKey, RichTextField) : undefined; - return field && field !== FieldWaiting ? field.Data : undefined; + const field = this.props.Document ? Cast(this.props.Document[this.props.fieldKey], RichTextField) : undefined; + return field ? field.Data : undefined; }, field => field && this._editorView && !this._applyingChange && this._editorView.updateState(EditorState.fromJSON(config, JSON.parse(field))) @@ -136,8 +133,8 @@ export class FormattedTextBox extends DocComponent<(FieldViewProps & FormattedTe this.setupEditor(config, this.props.Document); } - private setupEditor(config: any, doc?: Document) { - let field = doc ? doc.GetT(this.props.fieldKey, RichTextField) : undefined; + private setupEditor(config: any, doc?: Doc) { + let field = doc ? Cast(doc[this.props.fieldKey], RichTextField) : undefined; if (this._ref.current) { this._editorView = new EditorView(this._ref.current, { state: field && field.Data ? EditorState.fromJSON(config, JSON.parse(field.Data)) : EditorState.create(config), diff --git a/src/fields/RichTextField.ts b/src/fields/RichTextField.ts deleted file mode 100644 index f53f48ca6..000000000 --- a/src/fields/RichTextField.ts +++ /dev/null @@ -1,26 +0,0 @@ -import { BasicField } from "./BasicField"; -import { Types } from "../server/Message"; -import { FieldId } from "./Field"; - -export class RichTextField extends BasicField { - constructor(data: string = "", id?: FieldId, save: boolean = true) { - super(data, save, id); - } - - ToScriptString(): string { - return `new RichTextField(${this.Data})`; - } - - Copy() { - return new RichTextField(this.Data); - } - - ToJson() { - return { - type: Types.RichText, - data: this.Data, - id: this.Id - }; - } - -} \ No newline at end of file diff --git a/src/new_fields/RichTextField.ts b/src/new_fields/RichTextField.ts new file mode 100644 index 000000000..156e4efd9 --- /dev/null +++ b/src/new_fields/RichTextField.ts @@ -0,0 +1,12 @@ +import { ObjectField } from "./Doc"; +import { serializable } from "serializr"; + +export class RichTextField extends ObjectField { + @serializable(true) + readonly Data: string; + + constructor(data: string) { + super(); + this.Data = data; + } +} \ No newline at end of file diff --git a/src/new_fields/Types.ts b/src/new_fields/Types.ts index 4808d6e46..7fa18673f 100644 --- a/src/new_fields/Types.ts +++ b/src/new_fields/Types.ts @@ -38,10 +38,10 @@ export interface Interface { } export function Cast | ListSpec>(field: FieldResult, ctor: T): FieldResult>; -export function Cast | ListSpec>(field: FieldResult, ctor: T, defaultVal: WithoutList>): WithoutList>; -export function Cast | ListSpec>(field: FieldResult, ctor: T, defaultVal?: ToType): FieldResult> | undefined { +export function Cast | ListSpec>(field: FieldResult, ctor: T, defaultVal: WithoutList> | null): WithoutList>; +export function Cast | ListSpec>(field: FieldResult, ctor: T, defaultVal?: ToType | null): FieldResult> | undefined { if (field instanceof Promise) { - return defaultVal === undefined ? field.then(f => Cast(f, ctor) as any) as any : defaultVal; + return defaultVal === undefined ? field.then(f => Cast(f, ctor) as any) as any : defaultVal === null ? undefined : defaultVal; } if (field !== undefined && !(field instanceof Promise)) { if (typeof ctor === "string") { @@ -56,18 +56,18 @@ export function Cast | ListSpec>(field: Fi return field as ToType; } } - return defaultVal; + return defaultVal === null ? undefined : defaultVal; } -export function NumCast(field: FieldResult, defaultVal: Opt = 0) { +export function NumCast(field: FieldResult, defaultVal: number | null = 0) { return Cast(field, "number", defaultVal); } -export function StrCast(field: FieldResult, defaultVal: Opt = "") { +export function StrCast(field: FieldResult, defaultVal: string | null = "") { return Cast(field, "string", defaultVal); } -export function BoolCast(field: FieldResult, defaultVal: Opt = undefined) { +export function BoolCast(field: FieldResult, defaultVal: boolean | null = null) { return Cast(field, "boolean", defaultVal); } -- cgit v1.2.3-70-g09d2 From 07c95bfdf0d72cc5ee6cd6612632ac91e47274d1 Mon Sep 17 00:00:00 2001 From: Bob Zeleznik Date: Sat, 27 Apr 2019 22:00:21 -0400 Subject: fixed dragdecorations titling. fixed some event issues with dragging and textbox's context menu on mac --- src/client/util/DragManager.ts | 32 ++++---- src/client/views/DocumentDecorations.tsx | 116 ++++++++++++++-------------- src/client/views/nodes/FormattedTextBox.tsx | 4 +- 3 files changed, 77 insertions(+), 75 deletions(-) (limited to 'src/client/util/DragManager.ts') diff --git a/src/client/util/DragManager.ts b/src/client/util/DragManager.ts index 5aa7ad8e2..136852e12 100644 --- a/src/client/util/DragManager.ts +++ b/src/client/util/DragManager.ts @@ -172,6 +172,8 @@ export namespace DragManager { StartDrag([ele], dragData, downX, downY, options); } + export let AbortDrag: () => void = emptyFunction; + function StartDrag(eles: HTMLElement[], dragData: { [id: string]: any }, downX: number, downY: number, options?: DragOptions, finishDrag?: (dropData: { [id: string]: any }) => void) { if (!dragDiv) { dragDiv = document.createElement("div"); @@ -272,23 +274,32 @@ export namespace DragManager { ); }; - AbortDrag = () => { + let hideDragElements = () => { + dragElements.map(dragElement => dragElement.parentNode == dragDiv && dragDiv.removeChild(dragElement)); + eles.map(ele => (ele.hidden = false)); + }; + let endDrag = () => { document.removeEventListener("pointermove", moveHandler, true); document.removeEventListener("pointerup", upHandler); - dragElements.map(dragElement => { if (dragElement.parentNode == dragDiv) dragDiv.removeChild(dragElement); }); - eles.map(ele => (ele.hidden = false)); + if (options) { + options.handlers.dragComplete({}); + } + } + + AbortDrag = () => { + hideDragElements(); + endDrag(); }; const upHandler = (e: PointerEvent) => { - AbortDrag(); - FinishDrag(eles, e, dragData, options, finishDrag); + hideDragElements(); + dispatchDrag(eles, e, dragData, options, finishDrag); + endDrag(); }; document.addEventListener("pointermove", moveHandler, true); document.addEventListener("pointerup", upHandler); } - export let AbortDrag: () => void = emptyFunction; - - function FinishDrag(dragEles: HTMLElement[], e: PointerEvent, dragData: { [index: string]: any }, options?: DragOptions, finishDrag?: (dragData: { [index: string]: any }) => void) { + function dispatchDrag(dragEles: HTMLElement[], e: PointerEvent, dragData: { [index: string]: any }, options?: DragOptions, finishDrag?: (dragData: { [index: string]: any }) => void) { let removed = dragEles.map(dragEle => { let parent = dragEle.parentElement; if (parent) parent.removeChild(dragEle); @@ -313,11 +324,6 @@ export namespace DragManager { } }) ); - - if (options) { - options.handlers.dragComplete({}); - } } - DocumentDecorations.Instance.Hidden = false; } } diff --git a/src/client/views/DocumentDecorations.tsx b/src/client/views/DocumentDecorations.tsx index cacb9aead..d20df5f4a 100644 --- a/src/client/views/DocumentDecorations.tsx +++ b/src/client/views/DocumentDecorations.tsx @@ -39,30 +39,23 @@ export class DocumentDecorations extends React.Component<{}, { value: string }> private _downY = 0; @observable private _minimizedX = 0; @observable private _minimizedY = 0; - //@observable private _title: string = this._documents[0].props.Document.Title; - @observable private _title: string = this._documents.length > 0 ? this._documents[0].props.Document.Title : ""; + @observable private _title: string = ""; + @observable private _edtingTitle = false; @observable private _fieldKey: Key = KeyStore.Title; @observable private _hidden = false; @observable private _opacity = 1; - @observable private _dragging = false; @observable private _iconifying = false; @observable public Interacting = false; - constructor(props: Readonly<{}>) { super(props); DocumentDecorations.Instance = this; - this.handleChange = this.handleChange.bind(this); this.keyinput = React.createRef(); } - @action - handleChange = (event: any) => { - this._title = event.target.value; - } - - @action - enterPressed = (e: any) => { + @action titleChanged = (event: any) => { this._title = event.target.value; } + @action titleBlur = () => { this._edtingTitle = false; } + @action titleEntered = (e: any) => { var key = e.keyCode || e.which; // enter pressed if (key === 13) { @@ -70,32 +63,49 @@ export class DocumentDecorations extends React.Component<{}, { value: string }> if (text[0] === '#') { let command = text.slice(1, text.length); this._fieldKey = new Key(command); - // if (command === "Title" || command === "title") { - // this._fieldKey = KeyStore.Title; - // } - // else if (command === "Width" || command === "width") { - // this._fieldKey = KeyStore.Width; - // } - this._title = "changed"; - // TODO: Change field with switch statement + this._title = this.getTitle(); } else { if (this._documents.length > 0) { let field = this._documents[0].props.Document.Get(this._fieldKey); - if (field instanceof TextField) { + if (field instanceof NumberField) { this._documents.forEach(d => - d.props.Document.Set(this._fieldKey, new TextField(this._title))); - } - else if (field instanceof NumberField) { + d.props.Document.SetNumber(this._fieldKey, +this._title)); + } else if (field instanceof TextField || true) { this._documents.forEach(d => - d.props.Document.Set(this._fieldKey, new NumberField(+this._title))); + d.props.Document.SetText(this._fieldKey, this._title)); } - this._title = "changed"; } } e.target.blur(); } } + @action onTitleDown = (e: React.PointerEvent): void => { + this._downX = e.clientX; + this._downY = e.clientY; + e.stopPropagation(); + this.onBackgroundDown(e); + document.removeEventListener("pointermove", this.onTitleMove); + document.removeEventListener("pointerup", this.onTitleUp); + document.addEventListener("pointermove", this.onTitleMove); + document.addEventListener("pointerup", this.onTitleUp); + } + @action onTitleMove = (e: PointerEvent): void => { + if (Math.abs(e.clientX - this._downX) > 4 || Math.abs(e.clientY - this._downY) > 4) { + this.Interacting = true; + } + if (this.Interacting) this.onBackgroundMove(e); + e.stopPropagation(); + } + @action onTitleUp = (e: PointerEvent): void => { + if (Math.abs(e.clientX - this._downX) < 4 || Math.abs(e.clientY - this._downY) < 4) { + this._title = this.getTitle(); + this._edtingTitle = true; + } + document.removeEventListener("pointermove", this.onTitleMove); + document.removeEventListener("pointerup", this.onTitleUp); + this.onBackgroundUp(e); + } @computed get Bounds(): { x: number, y: number, b: number, r: number } { @@ -114,50 +124,40 @@ export class DocumentDecorations extends React.Component<{}, { value: string }> }, { x: Number.MAX_VALUE, y: Number.MAX_VALUE, r: Number.MIN_VALUE, b: Number.MIN_VALUE }); } - - @computed - public get Hidden() { return this._hidden; } - public set Hidden(value: boolean) { this._hidden = value; } - - _lastDrag: number[] = [0, 0]; onBackgroundDown = (e: React.PointerEvent): void => { document.removeEventListener("pointermove", this.onBackgroundMove); - document.addEventListener("pointermove", this.onBackgroundMove); document.removeEventListener("pointerup", this.onBackgroundUp); + document.addEventListener("pointermove", this.onBackgroundMove); document.addEventListener("pointerup", this.onBackgroundUp); - this._lastDrag = [e.clientX, e.clientY]; e.stopPropagation(); - if (e.currentTarget.localName !== "input") { - e.preventDefault(); - } + e.preventDefault(); } @action onBackgroundMove = (e: PointerEvent): void => { let dragDocView = SelectionManager.SelectedDocuments()[0]; const [left, top] = dragDocView.props.ScreenToLocalTransform().scale(dragDocView.props.ContentScaling()).inverse().transformPoint(0, 0); - let dragData = new DragManager.DocumentDragData(SelectionManager.SelectedDocuments().map(dv => dv.props.Document)); const [xoff, yoff] = dragDocView.props.ScreenToLocalTransform().scale(dragDocView.props.ContentScaling()).transformDirection(e.x - left, e.y - top); + let dragData = new DragManager.DocumentDragData(SelectionManager.SelectedDocuments().map(dv => dv.props.Document)); dragData.xOffset = xoff; dragData.yOffset = yoff; dragData.aliasOnDrop = false; - let move = SelectionManager.SelectedDocuments()[0].props.moveDocument; - dragData.moveDocument = move; - this.Interacting = this._dragging = true; + dragData.moveDocument = SelectionManager.SelectedDocuments()[0].props.moveDocument; + this.Interacting = true; + this._hidden = true; document.removeEventListener("pointermove", this.onBackgroundMove); document.removeEventListener("pointerup", this.onBackgroundUp); - this.Hidden = true; + document.removeEventListener("pointermove", this.onTitleMove); + document.removeEventListener("pointerup", this.onTitleUp); DragManager.StartDocumentDrag(SelectionManager.SelectedDocuments().map(docView => docView.ContentDiv!), dragData, e.x, e.y, { - handlers: { - dragComplete: action(() => this.Interacting = this._dragging = false), - }, + handlers: { dragComplete: action(() => this._hidden = this.Interacting = false) }, hideSource: true }); e.stopPropagation(); } + @action onBackgroundUp = (e: PointerEvent): void => { - this.Hidden = true; document.removeEventListener("pointermove", this.onBackgroundMove); document.removeEventListener("pointerup", this.onBackgroundUp); e.stopPropagation(); @@ -451,7 +451,7 @@ export class DocumentDecorations extends React.Component<{}, { value: string }> } } - getValue = (): string => { + getTitle = (): string => { if (this._documents.length > 0) { let field = this._documents[0].props.Document.Get(this._fieldKey); if (field instanceof TextField) { @@ -461,7 +461,7 @@ export class DocumentDecorations extends React.Component<{}, { value: string }> return (field).GetValue().toString(); } } - return this._title; + return "-unset-"; } changeFlyoutContent = (): void => { @@ -473,21 +473,17 @@ export class DocumentDecorations extends React.Component<{}, { value: string }> render() { var bounds = this.Bounds; let seldoc = SelectionManager.SelectedDocuments().length ? SelectionManager.SelectedDocuments()[0] : undefined; - if (bounds.x === Number.MAX_VALUE || !seldoc) { - return (null); - } - let minimizeIcon = ( -
- {SelectionManager.SelectedDocuments().length == 1 ? IconBox.DocumentIcon(SelectionManager.SelectedDocuments()[0].props.Document.GetText(KeyStore.Layout, "...")) : "..."} -
); - - if (this.Hidden) { + if (bounds.x === Number.MAX_VALUE || !seldoc || this._hidden) { return (null); } if (isNaN(bounds.r) || isNaN(bounds.b) || isNaN(bounds.x) || isNaN(bounds.y)) { console.log("DocumentDecorations: Bounds Error"); return (null); } + let minimizeIcon = ( +
+ {SelectionManager.SelectedDocuments().length == 1 ? IconBox.DocumentIcon(SelectionManager.SelectedDocuments()[0].props.Document.GetText(KeyStore.Layout, "...")) : "..."} +
); let linkButton = null; if (SelectionManager.SelectedDocuments().length > 0) { @@ -508,7 +504,7 @@ export class DocumentDecorations extends React.Component<{}, { value: string }> height: (bounds.b - bounds.y + this._resizeBorderWidth) + "px", left: bounds.x - this._resizeBorderWidth / 2, top: bounds.y - this._resizeBorderWidth / 2, - pointerEvents: this._dragging ? "none" : "all", + pointerEvents: this.Interacting ? "none" : "all", zIndex: SelectionManager.SelectedDocuments().length > 1 ? 1000 : 0, }} onPointerDown={this.onBackgroundDown} onContextMenu={(e: React.MouseEvent) => { e.preventDefault(); e.stopPropagation(); }} >
@@ -521,7 +517,9 @@ export class DocumentDecorations extends React.Component<{}, { value: string }> }}> {minimizeIcon} - + {this._edtingTitle ? + : +
{`${this.getTitle()}`}
}
X
e.preventDefault()}>
e.preventDefault()}>
diff --git a/src/client/views/nodes/FormattedTextBox.tsx b/src/client/views/nodes/FormattedTextBox.tsx index 02d98de6b..d8cd28b6c 100644 --- a/src/client/views/nodes/FormattedTextBox.tsx +++ b/src/client/views/nodes/FormattedTextBox.tsx @@ -170,12 +170,10 @@ export class FormattedTextBox extends React.Component<(FieldViewProps & Formatte @action onPointerDown = (e: React.PointerEvent): void => { if (e.button === 1 && this.props.isSelected() && !e.altKey && !e.ctrlKey && !e.metaKey) { - console.log("first"); e.stopPropagation(); } - if (e.button === 2) { + if (e.button === 2 || (e.button === 0 && e.ctrlKey)) { this._gotDown = true; - console.log("second"); e.preventDefault(); } } -- cgit v1.2.3-70-g09d2 From 6d52cfb2a7b2b575f448e7d7c3f02a97afa0027b Mon Sep 17 00:00:00 2001 From: Bob Zeleznik Date: Wed, 1 May 2019 22:38:49 -0400 Subject: fixed drag drop making source documents disappear. improved TreeView collapsing. Chnaged schemaView options placement --- src/client/util/DragManager.ts | 17 +++++++++++------ src/client/views/collections/CollectionSchemaView.tsx | 2 +- src/client/views/collections/CollectionTreeView.tsx | 4 ++-- 3 files changed, 14 insertions(+), 9 deletions(-) (limited to 'src/client/util/DragManager.ts') diff --git a/src/client/util/DragManager.ts b/src/client/util/DragManager.ts index a149da52f..4acf609f4 100644 --- a/src/client/util/DragManager.ts +++ b/src/client/util/DragManager.ts @@ -301,15 +301,20 @@ export namespace DragManager { function dispatchDrag(dragEles: HTMLElement[], e: PointerEvent, dragData: { [index: string]: any }, options?: DragOptions, finishDrag?: (dragData: { [index: string]: any }) => void) { let removed = dragEles.map(dragEle => { - let parent = dragEle.parentElement; - if (parent) parent.removeChild(dragEle); - return [dragEle, parent]; + // let parent = dragEle.parentElement; + // if (parent) parent.removeChild(dragEle); + let ret = [dragEle, dragEle.style.width, dragEle.style.height]; + dragEle.style.width = "0"; + dragEle.style.height = "0"; + return ret; }); const target = document.elementFromPoint(e.x, e.y); removed.map(r => { - let dragEle = r[0]; - let parent = r[1]; - if (parent && dragEle) parent.appendChild(dragEle); + let dragEle = r[0] as HTMLElement; + dragEle.style.width = r[1] as string; + dragEle.style.height = r[2] as string; + // let parent = r[1]; + // if (parent && dragEle) parent.appendChild(dragEle); }); if (target) { if (finishDrag) finishDrag(dragData); diff --git a/src/client/views/collections/CollectionSchemaView.tsx b/src/client/views/collections/CollectionSchemaView.tsx index 1f26941c2..67784fa81 100644 --- a/src/client/views/collections/CollectionSchemaView.tsx +++ b/src/client/views/collections/CollectionSchemaView.tsx @@ -295,7 +295,7 @@ export class CollectionSchemaView extends CollectionSubView(doc => doc) { get tableOptionsPanel() { return !this.props.active() ? (null) : (
Options
diff --git a/src/client/views/collections/CollectionTreeView.tsx b/src/client/views/collections/CollectionTreeView.tsx index 1a6f1121d..2a620a5e6 100644 --- a/src/client/views/collections/CollectionTreeView.tsx +++ b/src/client/views/collections/CollectionTreeView.tsx @@ -104,7 +104,7 @@ class TreeView extends React.Component { childElements =
    {/* // bcz: should this work? {children.map(value => )} */} - {children.map(value => )} + {children.map(value => )}
; } else bulletType = BulletType.Collapsed; @@ -137,7 +137,7 @@ export class CollectionTreeView extends CollectionSubView(Document) { (children.map(value => //bcz: shouldn't this work? - I think value[Id] is undefined sometimes // ) - ) + ) ); return ( -- cgit v1.2.3-70-g09d2 From 1ece3904b6b3fbf4ddde29e93e31a30f3898e720 Mon Sep 17 00:00:00 2001 From: bob Date: Thu, 2 May 2019 13:20:27 -0400 Subject: cleaned up drag code - userDropAction takes precedence over dropAction. default is alias --- src/client/documents/Documents.ts | 3 ++- src/client/util/DragManager.ts | 19 ++++++++++------ src/client/views/DocumentDecorations.tsx | 1 - src/client/views/EditableView.tsx | 2 +- src/client/views/Main.tsx | 14 +++++------- src/client/views/collections/CollectionSubView.tsx | 6 ++--- .../views/collections/CollectionTreeView.scss | 3 ++- .../views/collections/CollectionTreeView.tsx | 26 +++++++++++----------- src/client/views/nodes/DocumentView.tsx | 12 +++++----- src/client/views/nodes/FormattedTextBox.tsx | 6 +++-- 10 files changed, 49 insertions(+), 43 deletions(-) (limited to 'src/client/util/DragManager.ts') diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts index 2de389a3c..8706359e4 100644 --- a/src/client/documents/Documents.ts +++ b/src/client/documents/Documents.ts @@ -32,6 +32,7 @@ import { IconField } from "../../new_fields/IconField"; import { listSpec } from "../../new_fields/Schema"; import { DocServer } from "../DocServer"; import { StrokeData, InkField } from "../../new_fields/InkField"; +import { dropActionType } from "../util/DragManager"; export interface DocumentOptions { x?: number; @@ -51,7 +52,7 @@ export interface DocumentOptions { templates?: List; viewType?: number; backgroundColor?: string; - copyDraggedItems?: boolean; + dropAction?: dropActionType; backgroundLayout?: string; curPage?: number; documentText?: string; diff --git a/src/client/util/DragManager.ts b/src/client/util/DragManager.ts index 4acf609f4..a3dbe6e43 100644 --- a/src/client/util/DragManager.ts +++ b/src/client/util/DragManager.ts @@ -1,14 +1,14 @@ import { action } from "mobx"; import { emptyFunction } from "../../Utils"; import { CollectionDockingView } from "../views/collections/CollectionDockingView"; -import { DocumentDecorations } from "../views/DocumentDecorations"; import * as globalCssVariables from "../views/globalCssVariables.scss"; import { MainOverlayTextBox } from "../views/MainOverlayTextBox"; import { Doc } from "../../new_fields/Doc"; import { Cast } from "../../new_fields/Types"; import { listSpec } from "../../new_fields/Schema"; -export function SetupDrag(_reference: React.RefObject, docFunc: () => Doc, moveFunc?: DragManager.MoveFunction, copyOnDrop: boolean = false) { +export type dropActionType = "alias" | "copy" | undefined; +export function SetupDrag(_reference: React.RefObject, docFunc: () => Doc, moveFunc?: DragManager.MoveFunction, dropAction?: dropActionType) { let onRowMove = action((e: PointerEvent): void => { e.stopPropagation(); e.preventDefault(); @@ -16,7 +16,7 @@ export function SetupDrag(_reference: React.RefObject, docFunc: document.removeEventListener("pointermove", onRowMove); document.removeEventListener('pointerup', onRowUp); var dragData = new DragManager.DocumentDragData([docFunc()]); - dragData.copyOnDrop = copyOnDrop; + dragData.dropAction = dropAction; dragData.moveDocument = moveFunc; DragManager.StartDocumentDrag([_reference.current!], dragData, e.x, e.y); }); @@ -146,15 +146,20 @@ export namespace DragManager { droppedDocuments: Doc[]; xOffset: number; yOffset: number; - aliasOnDrop?: boolean; - copyOnDrop?: boolean; + dropAction: dropActionType; + userDropAction: dropActionType; moveDocument?: MoveFunction; [id: string]: any; } export function StartDocumentDrag(eles: HTMLElement[], dragData: DocumentDragData, downX: number, downY: number, options?: DragOptions) { StartDrag(eles, dragData, downX, downY, options, - (dropData: { [id: string]: any }) => (dropData.droppedDocuments = dragData.aliasOnDrop ? dragData.draggedDocuments.map(d => Doc.MakeAlias(d)) : dragData.copyOnDrop ? dragData.draggedDocuments.map(d => Doc.MakeCopy(d, true)) : dragData.draggedDocuments)); + (dropData: { [id: string]: any }) => + (dropData.droppedDocuments = dragData.userDropAction == "alias" || (!dragData.userDropAction && dragData.dropAction == "alias") ? + dragData.draggedDocuments.map(d => Doc.MakeAlias(d)) : + dragData.userDropAction == "copy" || (!dragData.userDropAction && dragData.dropAction == "copy") ? + dragData.draggedDocuments.map(d => Doc.MakeCopy(d, true)) : + dragData.draggedDocuments)); } export class LinkDragData { @@ -252,7 +257,7 @@ export namespace DragManager { e.stopPropagation(); e.preventDefault(); if (dragData instanceof DocumentDragData) { - dragData.aliasOnDrop = e.ctrlKey || e.altKey; + dragData.userDropAction = e.ctrlKey || e.altKey ? "alias" : undefined; } if (e.shiftKey) { AbortDrag(); diff --git a/src/client/views/DocumentDecorations.tsx b/src/client/views/DocumentDecorations.tsx index 7dcd71495..d07adcb71 100644 --- a/src/client/views/DocumentDecorations.tsx +++ b/src/client/views/DocumentDecorations.tsx @@ -144,7 +144,6 @@ export class DocumentDecorations extends React.Component<{}, { value: string }> let dragData = new DragManager.DocumentDragData(SelectionManager.SelectedDocuments().map(dv => dv.props.Document)); dragData.xOffset = xoff; dragData.yOffset = yoff; - dragData.aliasOnDrop = false; dragData.moveDocument = SelectionManager.SelectedDocuments()[0].props.moveDocument; this.Interacting = true; this._hidden = true; diff --git a/src/client/views/EditableView.tsx b/src/client/views/EditableView.tsx index 2f17c6c51..73467eb9d 100644 --- a/src/client/views/EditableView.tsx +++ b/src/client/views/EditableView.tsx @@ -60,7 +60,7 @@ export class EditableView extends React.Component { return (
this.editing = true)} > - {this.props.contents} + {this.props.contents}
); } diff --git a/src/client/views/Main.tsx b/src/client/views/Main.tsx index b2ca4a196..a07a2d5b1 100644 --- a/src/client/views/Main.tsx +++ b/src/client/views/Main.tsx @@ -8,9 +8,7 @@ import * as React from 'react'; import * as ReactDOM from 'react-dom'; import Measure from 'react-measure'; import * as request from 'request'; -import { WorkspacesMenu } from '../../server/authentication/controllers/WorkspacesMenu'; import { CurrentUserUtils } from '../../server/authentication/models/current_user_utils'; -import { MessageStore } from '../../server/Message'; import { RouteStore } from '../../server/RouteStore'; import { emptyFunction, returnTrue, Utils, returnOne, returnZero } from '../../Utils'; import { Docs } from '../documents/Documents'; @@ -86,11 +84,11 @@ export class Main extends React.Component { this.initEventListeners(); this.initAuthenticationRouters(); - try { - this.initializeNorthstar(); - } catch (e) { + // try { + // this.initializeNorthstar(); + // } catch (e) { - } + // } } componentDidMount() { window.onpopstate = this.onHistory; } @@ -219,8 +217,8 @@ export class Main extends React.Component { let addTextNode = action(() => Docs.TextDocument({ borderRounding: -1, width: 200, height: 200, title: "a text note" })); let addColNode = action(() => Docs.FreeformDocument([], { width: 200, height: 200, title: "a freeform collection" })); let addSchemaNode = action(() => Docs.SchemaDocument([], { width: 200, height: 200, title: "a schema collection" })); - let addTreeNode = action(() => Docs.TreeDocument([CurrentUserUtils.UserDocument], { width: 250, height: 400, title: "Library:" + CurrentUserUtils.email, copyDraggedItems: true })); - // let addTreeNode = action(() => Docs.TreeDocument(this._northstarSchemas, { width: 250, height: 400, title: "northstar schemas", copyDraggedItems: true })); + let addTreeNode = action(() => Docs.TreeDocument([CurrentUserUtils.UserDocument], { width: 250, height: 400, title: "Library:" + CurrentUserUtils.email, dropAction: "alias" })); + // let addTreeNode = action(() => Docs.TreeDocument(this._northstarSchemas, { width: 250, height: 400, title: "northstar schemas", dropAction: "copy" })); let addVideoNode = action(() => Docs.VideoDocument(videourl, { width: 200, title: "video node" })); let addPDFNode = action(() => Docs.PdfDocument(pdfurl, { width: 200, height: 200, title: "a pdf doc" })); let addImageNode = action(() => Docs.ImageDocument(imgurl, { width: 200, title: "an image of a cat" })); diff --git a/src/client/views/collections/CollectionSubView.tsx b/src/client/views/collections/CollectionSubView.tsx index bcbde24f0..a59bc196e 100644 --- a/src/client/views/collections/CollectionSubView.tsx +++ b/src/client/views/collections/CollectionSubView.tsx @@ -83,13 +83,13 @@ export function CollectionSubView(schemaCtor: (doc: Doc) => T) { @action protected drop(e: Event, de: DragManager.DropEvent): boolean { if (de.data instanceof DragManager.DocumentDragData) { - if (de.data.aliasOnDrop || de.data.copyOnDrop) { + if (de.data.dropAction || de.data.userDropAction) { ["width", "height", "curPage"].map(key => de.data.draggedDocuments.map((draggedDocument: Doc, i: number) => PromiseValue(Cast(draggedDocument[key], "number")).then(f => f && (de.data.droppedDocuments[i][key] = f)))); } let added = false; - if (de.data.aliasOnDrop || de.data.copyOnDrop) { + if (de.data.dropAction || de.data.userDropAction) { added = de.data.droppedDocuments.reduce((added: boolean, d) => { let moved = this.props.addDocument(d); return moved || added; @@ -129,7 +129,7 @@ export function CollectionSubView(schemaCtor: (doc: Doc) => T) { } if (type.indexOf("excel") !== -1) { ctor = Docs.DBDocument; - options.copyDraggedItems = true; + options.dropAction = "copy"; } if (type.indexOf("html") !== -1) { if (path.includes('localhost')) { diff --git a/src/client/views/collections/CollectionTreeView.scss b/src/client/views/collections/CollectionTreeView.scss index ecb5f78bb..d00785879 100644 --- a/src/client/views/collections/CollectionTreeView.scss +++ b/src/client/views/collections/CollectionTreeView.scss @@ -45,7 +45,8 @@ .docContainer { margin-left: 10px; - display: inline-table; + display: block; + width: max-content; } .docContainer:hover { diff --git a/src/client/views/collections/CollectionTreeView.tsx b/src/client/views/collections/CollectionTreeView.tsx index 0520e0f88..037703c46 100644 --- a/src/client/views/collections/CollectionTreeView.tsx +++ b/src/client/views/collections/CollectionTreeView.tsx @@ -3,7 +3,7 @@ import { faCaretDown, faCaretRight, faTrashAlt } from '@fortawesome/free-solid-s import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; import { action, observable } from "mobx"; import { observer } from "mobx-react"; -import { DragManager, SetupDrag } from "../../util/DragManager"; +import { DragManager, SetupDrag, dropActionType } from "../../util/DragManager"; import { EditableView } from "../EditableView"; import { CollectionSubView } from "./CollectionSubView"; import "./CollectionTreeView.scss"; @@ -12,8 +12,6 @@ import { Document, listSpec } from '../../../new_fields/Schema'; import { Cast, StrCast, BoolCast, FieldValue } from '../../../new_fields/Types'; import { Doc } from '../../../new_fields/Doc'; import { Id } from '../../../new_fields/RefField'; -import { Utils } from '../../../Utils'; -import { JSXElement } from 'babel-types'; import { ContextMenu } from '../ContextMenu'; import { undoBatch } from '../../util/UndoManager'; import { Main } from '../Main'; @@ -24,7 +22,7 @@ export interface TreeViewProps { document: Doc; deleteDoc: (doc: Doc) => void; moveDocument: DragManager.MoveFunction; - copyOnDrag: boolean; + dropAction: "alias" | "copy" | undefined; } export enum BulletType { @@ -83,7 +81,7 @@ class TreeView extends React.Component { */ renderTitle() { let reference = React.createRef(); - let onItemDown = SetupDrag(reference, () => this.props.document, this.props.moveDocument, this.props.copyOnDrag); + let onItemDown = SetupDrag(reference, () => this.props.document, this.props.moveDocument, this.props.dropAction); let editableView = (titleString: string) => ( { height={36} GetValue={() => StrCast(this.props.document.title)} SetValue={(value: string) => { - this.props.document.title = value; + let target = this.props.document.proto ? this.props.document.proto : this.props.document; + target.title = value; return true; }} />); return (
{editableView(StrCast(this.props.document.title))} -
+ {/*
*/}
); } @@ -117,7 +116,7 @@ class TreeView extends React.Component { if (!this._collapsed) { bulletType = BulletType.Collapsible; contentElement =
    - {TreeView.GetChildElements(children, this.remove, this.move, this.props.copyOnDrag)} + {TreeView.GetChildElements(children, this.remove, this.move, this.props.dropAction)}
; } else bulletType = BulletType.Collapsed; @@ -130,9 +129,9 @@ class TreeView extends React.Component {
; } - public static GetChildElements(docs: Doc[], remove: ((doc: Doc) => void), move: DragManager.MoveFunction, copyOnDrag: boolean) { + public static GetChildElements(docs: Doc[], remove: ((doc: Doc) => void), move: DragManager.MoveFunction, dropAction: dropActionType) { return docs.filter(child => !child.excludeFromLibrary).map(child => - ); + ); } } @@ -154,13 +153,13 @@ export class CollectionTreeView extends CollectionSubView(Document) { } render() { const children = this.children; - let copyOnDrag = BoolCast(this.props.Document.copyDraggedItems, false); + let dropAction = StrCast(this.props.Document.dropAction, "alias") as dropActionType; if (!children) { return (null); } let testForLibrary = children && children.length === 1 && children[0] === CurrentUserUtils.UserDocument; var subchildren = testForLibrary ? Cast(children[0].data, listSpec(Doc), children) : children; - let childElements = TreeView.GetChildElements(subchildren, this.remove, this.props.moveDocument, copyOnDrag); + let childElements = TreeView.GetChildElements(subchildren, this.remove, this.props.moveDocument, dropAction); return (
StrCast(this.props.Document.title)} SetValue={(value: string) => { - this.props.Document.title = value; + let target = this.props.Document.proto ? this.props.Document.proto : this.props.Document; + target.title = value; return true; }} />
diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx index 86d34725d..b151657e1 100644 --- a/src/client/views/nodes/DocumentView.tsx +++ b/src/client/views/nodes/DocumentView.tsx @@ -3,7 +3,7 @@ import { observer } from "mobx-react"; import { emptyFunction, Utils } from "../../../Utils"; import { Docs } from "../../documents/Documents"; import { DocumentManager } from "../../util/DocumentManager"; -import { DragManager } from "../../util/DragManager"; +import { DragManager, dropActionType } from "../../util/DragManager"; import { SelectionManager } from "../../util/SelectionManager"; import { Transform } from "../../util/Transform"; import { undoBatch, UndoManager } from "../../util/UndoManager"; @@ -129,12 +129,12 @@ export class DocumentView extends DocComponent(Docu e.stopPropagation(); } - startDragging(x: number, y: number, dropAliasOfDraggedDoc: boolean) { + startDragging(x: number, y: number, dropAction: dropActionType) { if (this._mainCont.current) { const [left, top] = this.props.ScreenToLocalTransform().scale(this.props.ContentScaling()).inverse().transformPoint(0, 0); let dragData = new DragManager.DocumentDragData([this.props.Document]); const [xoff, yoff] = this.props.ScreenToLocalTransform().scale(this.props.ContentScaling()).transformDirection(x - left, y - top); - dragData.aliasOnDrop = dropAliasOfDraggedDoc; + dragData.dropAction = dropAction; dragData.xOffset = xoff; dragData.yOffset = yoff; dragData.moveDocument = this.props.moveDocument; @@ -142,7 +142,7 @@ export class DocumentView extends DocComponent(Docu handlers: { dragComplete: action(emptyFunction) }, - hideSource: !dropAliasOfDraggedDoc + hideSource: !dropAction }); } } @@ -162,7 +162,7 @@ export class DocumentView extends DocComponent(Docu } if (e.shiftKey && e.buttons === 1) { if (this.props.isTopMost) { - this.startDragging(e.pageX, e.pageY, e.altKey || e.ctrlKey); + this.startDragging(e.pageX, e.pageY, e.altKey || e.ctrlKey ? "alias" : undefined); } else { CollectionDockingView.Instance.StartOtherDrag([this.props.Document], e); } @@ -180,7 +180,7 @@ export class DocumentView extends DocComponent(Docu document.removeEventListener("pointermove", this.onPointerMove); document.removeEventListener("pointerup", this.onPointerUp); if (!e.altKey && !this.topMost && (!CollectionFreeFormView.RIGHT_BTN_DRAG && e.buttons === 1) || (CollectionFreeFormView.RIGHT_BTN_DRAG && e.buttons === 2)) { - this.startDragging(this._downX, this._downY, e.ctrlKey || e.altKey); + this.startDragging(this._downX, this._downY, e.ctrlKey || e.altKey ? "alias" : undefined); } } e.stopPropagation(); // doesn't actually stop propagation since all our listeners are listening to events on 'document' however it does mark the event as cancelBubble=true which we test for in the move event handlers diff --git a/src/client/views/nodes/FormattedTextBox.tsx b/src/client/views/nodes/FormattedTextBox.tsx index 7f269a505..1d362bdaa 100644 --- a/src/client/views/nodes/FormattedTextBox.tsx +++ b/src/client/views/nodes/FormattedTextBox.tsx @@ -89,7 +89,8 @@ export class FormattedTextBox extends DocComponent<(FieldViewProps & FormattedTe if (title && title.startsWith("-") && this._editorView) { let str = this._editorView.state.doc.textContent; let titlestr = str.substr(0, Math.min(40, str.length)); - this.props.Document.title = "-" + titlestr + (str.length > 40 ? "..." : ""); + let target = this.props.Document.proto ? this.props.Document.proto : this.props.Document; + target.title = "-" + titlestr + (str.length > 40 ? "..." : ""); }; } } @@ -275,7 +276,8 @@ export class FormattedTextBox extends DocComponent<(FieldViewProps & FormattedTe if (StrCast(this.props.Document.title).startsWith("-") && this._editorView) { let str = this._editorView.state.doc.textContent; let titlestr = str.substr(0, Math.min(40, str.length)); - this.props.Document.title = "-" + titlestr + (str.length > 40 ? "..." : ""); + let target = this.props.Document.proto ? this.props.Document.proto : this.props.Document; + target.title = "-" + titlestr + (str.length > 40 ? "..." : ""); } } render() { -- cgit v1.2.3-70-g09d2