From 08fbeaf2ebf4ee2466fa156e6e8c663d2bef7864 Mon Sep 17 00:00:00 2001 From: Bob Zeleznik Date: Fri, 24 Apr 2020 00:06:48 -0400 Subject: moved iconify code into Doc from DocumentView. fixed up starburst a bit. --- src/client/util/RichTextSchema.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/client/util') diff --git a/src/client/util/RichTextSchema.tsx b/src/client/util/RichTextSchema.tsx index d23962d5c..b88a7b017 100644 --- a/src/client/util/RichTextSchema.tsx +++ b/src/client/util/RichTextSchema.tsx @@ -780,7 +780,7 @@ export class DashDocView { if (dashDocBase instanceof Doc) { const aliasedDoc = Doc.MakeAlias(dashDocBase, docid + alias); aliasedDoc.layoutKey = "layout"; - node.attrs.fieldKey && DocumentView.makeCustomViewClicked(aliasedDoc, Docs.Create.StackingDocument, node.attrs.fieldKey, undefined); + node.attrs.fieldKey && Doc.makeCustomViewClicked(aliasedDoc, Docs.Create.StackingDocument, node.attrs.fieldKey, undefined); self.doRender(aliasedDoc, removeDoc, node, view, getPos); } }); -- cgit v1.2.3-70-g09d2 From 308ae1521cbd58126d35239cfdd5a138f6fa1fe0 Mon Sep 17 00:00:00 2001 From: Bob Zeleznik Date: Sat, 25 Apr 2020 15:40:07 -0400 Subject: got rid of focus mechanism on click. fixed shift-click to multiselect. fixed pile view interactions. added FollowLink on click menu items. --- src/client/util/DragManager.ts | 9 +++- src/client/util/ProsemirrorExampleTransfer.ts | 18 +++++-- src/client/views/ContextMenu.tsx | 9 ++++ src/client/views/TemplateMenu.tsx | 5 +- .../views/collections/CollectionPileView.tsx | 38 +++++++++++-- src/client/views/collections/CollectionView.tsx | 2 +- .../collectionFreeForm/CollectionFreeFormView.tsx | 20 +++---- src/client/views/nodes/DocumentView.tsx | 63 +++++++++++++++------- src/client/views/nodes/FormattedTextBox.tsx | 4 +- src/client/views/nodes/FormattedTextBoxComment.tsx | 1 - src/client/views/nodes/LinkAnchorBox.tsx | 1 - src/client/views/pdf/Annotation.tsx | 1 - 12 files changed, 124 insertions(+), 47 deletions(-) (limited to 'src/client/util') diff --git a/src/client/util/DragManager.ts b/src/client/util/DragManager.ts index 42a78a4bf..6bb44f7d6 100644 --- a/src/client/util/DragManager.ts +++ b/src/client/util/DragManager.ts @@ -83,6 +83,7 @@ export namespace DragManager { } export let AbortDrag: () => void = emptyFunction; export type MoveFunction = (document: Doc, targetCollection: Doc | undefined, addDocument: (document: Doc) => boolean) => boolean; + export type RemoveFunction = (document: Doc) => boolean; export interface DragDropDisposer { (): void; } export interface DragOptions { @@ -138,6 +139,7 @@ export namespace DragManager { userDropAction: dropActionType; embedDoc?: boolean; moveDocument?: MoveFunction; + removeDocument?: RemoveFunction; isSelectionMove?: boolean; // indicates that an explicitly selected Document is being dragged. this will suppress onDragStart scripts } export class LinkDragData { @@ -351,12 +353,17 @@ export namespace DragManager { let lastX = downX; let lastY = downY; + let alias = "alias"; const moveHandler = (e: PointerEvent) => { e.preventDefault(); // required or dragging text menu link item ends up dragging the link button as native drag/drop if (dragData instanceof DocumentDragData) { dragData.userDropAction = e.ctrlKey && e.altKey ? "copy" : e.ctrlKey ? "alias" : undefined; } if (e.shiftKey && CollectionDockingView.Instance && 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({ @@ -366,7 +373,7 @@ export namespace DragManager { button: 0 }, dragData.droppedDocuments); } - //TODO: Why can't we use e.movementX and e.movementY? + alias = "move"; const moveX = e.pageX - lastX; const moveY = e.pageY - lastY; lastX = e.pageX; diff --git a/src/client/util/ProsemirrorExampleTransfer.ts b/src/client/util/ProsemirrorExampleTransfer.ts index 680f48f70..356f20ce6 100644 --- a/src/client/util/ProsemirrorExampleTransfer.ts +++ b/src/client/util/ProsemirrorExampleTransfer.ts @@ -7,7 +7,7 @@ import { splitListItem, wrapInList, } from "prosemirror-schema-list"; import { EditorState, Transaction, TextSelection } from "prosemirror-state"; import { SelectionManager } from "./SelectionManager"; import { Docs } from "../documents/Documents"; -import { NumCast, BoolCast, Cast } from "../../new_fields/Types"; +import { NumCast, BoolCast, Cast, StrCast } from "../../new_fields/Types"; import { Doc } from "../../new_fields/Doc"; import { FormattedTextBox } from "../views/nodes/FormattedTextBox"; import { Id } from "../../new_fields/FieldSymbols"; @@ -153,10 +153,16 @@ export default function buildKeymap>(schema: S, props: any const layoutDoc = props.Document; const originalDoc = layoutDoc.rootDocument || layoutDoc; if (originalDoc instanceof Doc) { + const layoutKey = StrCast(originalDoc.layoutKey); const newDoc = Docs.Create.TextDocument("", { - layout: Cast(originalDoc.layout, Doc, null) || FormattedTextBox.DefaultLayout, _singleLine: BoolCast(originalDoc._singleLine), + layout: Cast(originalDoc.layout, Doc, null) || FormattedTextBox.DefaultLayout, + layoutKey, + _singleLine: BoolCast(originalDoc._singleLine), x: NumCast(originalDoc.x), y: NumCast(originalDoc.y) + NumCast(originalDoc._height) + 10, _width: NumCast(layoutDoc._width), _height: NumCast(layoutDoc._height) }); + if (layoutKey !== "layout" && originalDoc[layoutKey] instanceof Doc) { + newDoc[layoutKey] = originalDoc[layoutKey]; + } FormattedTextBox.SelectOnLoad = newDoc[Id]; props.addDocument(newDoc); } @@ -171,10 +177,16 @@ export default function buildKeymap>(schema: S, props: any const layoutDoc = props.Document; const originalDoc = layoutDoc.rootDocument || layoutDoc; if (force || props.Document._singleLine) { + const layoutKey = StrCast(originalDoc.layoutKey); const newDoc = Docs.Create.TextDocument("", { - layout: Cast(originalDoc.layout, Doc, null) || FormattedTextBox.DefaultLayout, _singleLine: BoolCast(originalDoc._singleLine), + layout: Cast(originalDoc.layout, Doc, null) || FormattedTextBox.DefaultLayout, + layoutKey, + _singleLine: BoolCast(originalDoc._singleLine), x: NumCast(originalDoc.x) + NumCast(originalDoc._width) + 10, y: NumCast(originalDoc.y), _width: NumCast(layoutDoc._width), _height: NumCast(layoutDoc._height) }); + if (layoutKey !== "layout" && originalDoc[layoutKey] instanceof Doc) { + newDoc[layoutKey] = originalDoc[layoutKey]; + } FormattedTextBox.SelectOnLoad = newDoc[Id]; props.addDocument(newDoc); return true; diff --git a/src/client/views/ContextMenu.tsx b/src/client/views/ContextMenu.tsx index 4d04d4e89..5b66b63ed 100644 --- a/src/client/views/ContextMenu.tsx +++ b/src/client/views/ContextMenu.tsx @@ -99,6 +99,15 @@ export class ContextMenu extends React.Component { } } @action + moveAfter(item: ContextMenuProps, after: ContextMenuProps) { + if (this.findByDescription(after.description)) { + const curInd = this._items.findIndex((i) => i.description === item.description); + this._items.splice(curInd, 1); + const afterInd = this._items.findIndex((i) => i.description === after.description); + this._items.splice(afterInd + 1, 0, item); + } + } + @action setDefaultItem(prefix: string, item: (name: string) => void) { this._defaultPrefix = prefix; this._defaultItem = item; diff --git a/src/client/views/TemplateMenu.tsx b/src/client/views/TemplateMenu.tsx index 4c84a22ad..665ab4e41 100644 --- a/src/client/views/TemplateMenu.tsx +++ b/src/client/views/TemplateMenu.tsx @@ -14,6 +14,7 @@ import { returnTrue, emptyFunction, returnFalse, returnOne, emptyPath, returnZer import { Transform } from "../util/Transform"; import { ScriptField, ComputedField } from "../../new_fields/ScriptField"; import { Scripting } from "../util/Scripting"; +import { List } from "../../new_fields/List"; @observer class TemplateToggle extends React.Component<{ template: Template, checked: boolean, toggle: (event: React.ChangeEvent, template: Template) => void }> { @@ -106,8 +107,8 @@ export class TemplateMenu extends React.Component { return100 = () => 100; @computed get scriptField() { - return ScriptField.MakeScript("switchView(firstDoc, this)", { this: Doc.name, heading: "string", checked: "string", containingTreeView: Doc.name, firstDoc: Doc.name }, - { firstDoc: this.props.docViews[0].props.Document }); + return ScriptField.MakeScript("docs.map(d => switchView(d, this))", { this: Doc.name, heading: "string", checked: "string", containingTreeView: Doc.name, firstDoc: Doc.name }, + { docs: new List(this.props.docViews.map(dv => dv.props.Document)) }); } render() { const firstDoc = this.props.docViews[0].props.Document; diff --git a/src/client/views/collections/CollectionPileView.tsx b/src/client/views/collections/CollectionPileView.tsx index 511efe0a7..410b16ec7 100644 --- a/src/client/views/collections/CollectionPileView.tsx +++ b/src/client/views/collections/CollectionPileView.tsx @@ -11,6 +11,7 @@ import "./CollectionPileView.scss"; import React = require("react"); import { setupMoveUpEvents, emptyFunction, returnFalse } from "../../../Utils"; import { SelectionManager } from "../../util/SelectionManager"; +import { UndoManager } from "../../util/UndoManager"; @observer export class CollectionPileView extends CollectionSubView(doc => doc) { @@ -34,7 +35,10 @@ export class CollectionPileView extends CollectionSubView(doc => doc) { layoutEngine = () => this._layoutEngine; @computed get contents() { - return
+ return
; } @@ -71,9 +75,32 @@ export class CollectionPileView extends CollectionSubView(doc => doc) { } }); + _undoBatch: UndoManager.Batch | undefined; pointerDown = (e: React.PointerEvent) => { + let dist = 0; // this._lastTap should be set to 0, and this._doubleTap should be set to false in the class header - setupMoveUpEvents(this, e, returnFalse, emptyFunction, emptyFunction, false, false); // this sets _doubleTap + setupMoveUpEvents(this, e, (e: PointerEvent, down: number[], delta: number[]) => { + if (this.layoutEngine() === "pass" && this.childDocs.length && this.props.isSelected(true)) { + dist += Math.sqrt(delta[0] * delta[0] + delta[1] * delta[1]); + if (dist > 100) { + if (!this._undoBatch) { + this._undoBatch = UndoManager.StartBatch("layout pile"); + } + const doc = this.childDocs[0]; + doc.x = e.clientX; + doc.y = e.clientY; + this.props.addDocTab(doc, "inParent") && this.props.removeDocument(doc); + dist = 0; + } + } + return false; + }, () => { + this._undoBatch?.end(); + this._undoBatch = undefined; + if (!this.childDocs.length) { + this.props.ContainingCollectionView?.removeDocument(this.props.Document); + } + }, emptyFunction, false, this.layoutEngine() === "pass" && this.props.isSelected(true)); // this sets _doubleTap } onClick = (e: React.MouseEvent) => { @@ -81,10 +108,11 @@ export class CollectionPileView extends CollectionSubView(doc => doc) { SelectionManager.DeselectAll(); this.toggleStarburst(); e.stopPropagation(); - } else if (this.layoutEngine() === "pass") { - runInAction(() => this._contentsActive = false); - setTimeout(action(() => this._contentsActive = true), 300); } + // else if (this.layoutEngine() === "pass") { + // runInAction(() => this._contentsActive = false); + // setTimeout(action(() => this._contentsActive = true), 300); + // } } render() { diff --git a/src/client/views/collections/CollectionView.tsx b/src/client/views/collections/CollectionView.tsx index f82c6d8a6..2bd37bda5 100644 --- a/src/client/views/collections/CollectionView.tsx +++ b/src/client/views/collections/CollectionView.tsx @@ -225,7 +225,7 @@ export class CollectionView extends Touchable { if (!e.isPropagationStopped() && this.props.Document[Id] !== CurrentUserUtils.MainDocId) { // need to test this because GoldenLayout causes a parallel hierarchy in the React DOM for its children and the main document view7 this.setupViewTypes("Change Perspective...", (vtype => { this.props.Document._viewType = vtype; return this.props.Document; }), true); - this.setupViewTypes("New Perspective...", vtype => { + this.setupViewTypes("Add a Perspective...", vtype => { const newRendition = Doc.MakeAlias(this.props.Document); newRendition._viewType = vtype; this.props.addDocTab(newRendition, "onRight"); diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx index af9d3c5be..6a3764bb7 100644 --- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx +++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx @@ -821,18 +821,18 @@ export class CollectionFreeFormView extends CollectionSubView { if (afterFocus?.()) { diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx index 06bd40992..f9d9ca9a1 100644 --- a/src/client/views/nodes/DocumentView.tsx +++ b/src/client/views/nodes/DocumentView.tsx @@ -234,6 +234,7 @@ export class DocumentView extends DocComponent(Docu const [left, top] = this.props.ScreenToLocalTransform().scale(this.props.ContentScaling()).inverse().transformPoint(0, 0); dragData.offset = this.props.ScreenToLocalTransform().scale(this.props.ContentScaling()).transformDirection(x - left, y - top); dragData.dropAction = dropAction; + dragData.removeDocument = this.props.removeDocument; dragData.moveDocument = this.props.moveDocument;// this.Document.onDragStart ? undefined : this.props.moveDocument; dragData.dragDivName = this.props.dragDivName; DragManager.StartDocumentDrag([this._mainCont.current], dragData, x, y, { hideSource: !dropAction && !this.Document.onDragStart }); @@ -309,19 +310,19 @@ export class DocumentView extends DocComponent(Docu } else if (this.Document["onClick-rawScript"] && !StrCast(Doc.LayoutField(this.layoutDoc))?.includes("ScriptingBox")) {// bcz: hack? don't edit a script if you're clicking on a scripting box itself UndoManager.RunInBatch(() => Doc.makeCustomViewClicked(this.props.Document, undefined, "onClick"), "edit onClick"); //ScriptBox.EditButtonScript("On Button Clicked ...", this.props.Document, "onClick", e.clientX, e.clientY), "on button click"); - } else if (this.Document.isLinkButton) { + } else if (this.Document.isLinkButton && !e.shiftKey && !e.ctrlKey) { DocListCast(this.props.Document.links).length && this.followLinkClick(e.altKey, e.ctrlKey, e.shiftKey); } else { if ((this.props.Document.onDragStart || (this.props.Document.rootDocument)) && !(e.ctrlKey || e.button > 0)) { // onDragStart implies a button doc that we don't want to select when clicking. RootDocument & isTEmplaetForField implies we're clicking on part of a template instance and we want to select the whole template, not the part stopPropagate = false; // don't stop propagation for field templates -- want the selection to propagate up to the root document of the template } else { - if (this.props.Document.type === DocumentType.RTF) { - DocumentView._focusHack = this.props.ScreenToLocalTransform().transformPoint(e.clientX, e.clientY) || [0, 0]; - DocumentView._focusHack = [DocumentView._focusHack[0] + NumCast(this.props.Document.x), DocumentView._focusHack[1] + NumCast(this.props.Document.y)]; + // if (this.props.Document.type === DocumentType.RTF) { + // DocumentView._focusHack = this.props.ScreenToLocalTransform().transformPoint(e.clientX, e.clientY) || [0, 0]; + // DocumentView._focusHack = [DocumentView._focusHack[0] + NumCast(this.props.Document.x), DocumentView._focusHack[1] + NumCast(this.props.Document.y)]; - this.props.focus(this.props.Document, false); - } - SelectionManager.SelectDoc(this, e.ctrlKey); + // this.props.focus(this.props.Document, false); + // } + SelectionManager.SelectDoc(this, e.ctrlKey || e.shiftKey); } preventDefault = false; } @@ -329,7 +330,6 @@ export class DocumentView extends DocComponent(Docu preventDefault && e.preventDefault(); } } - static _focusHack: number[] = []; // bcz :this will get fixed... // follows a link - if the target is on screen, it highlights/pans to it. // if the target isn't onscreen, then it will open up the target in a tab, on the right, or in place @@ -344,11 +344,11 @@ export class DocumentView extends DocComponent(Docu finished && setTimeout(finished, 0); // finished() needs to be called right after hackToCallFinishAfterFocus(), but there's no callback for that so we use the hacky timeout. return false; // we must return false here so that the zoom to the document is not reversed. If it weren't for needing to call finished(), we wouldn't need this function at all since not having it is equivalent to returning false }; - this.props.addDocTab(doc, where) && this.props.focus(doc, true, undefined, hackToCallFinishAfterFocus); // add the target and focus on it. + this.props.addDocTab(doc, where) && this.props.focus(doc, BoolCast(this.Document.followLinkZoom, true), undefined, hackToCallFinishAfterFocus); // add the target and focus on it. return where !== "inPlace"; // return true to reset the initial focus&zoom (return false for 'inPlace' since resetting the initial focus&zoom will negate the zoom into the target) }; // first focus & zoom onto this (the clicked document). Then execute the function to focus on the target - this.props.focus(this.props.Document, true, 1, targetFocusAfterDocFocus); + this.props.focus(this.props.Document, BoolCast(this.Document.followLinkZoom, true), 1, targetFocusAfterDocFocus); }; await DocumentManager.Instance.FollowLink(undefined, this.props.Document, createViewFunc, shiftKey, this.props.ContainingCollectionDoc, batch.end, altKey ? true : undefined); } @@ -569,6 +569,7 @@ export class DocumentView extends DocComponent(Docu this.Document.onClick = undefined; } else { this.Document.isLinkButton = true; + this.Document.followLinkZoom = false; this.Document.followLinkLocation = undefined; } } @@ -579,10 +580,24 @@ export class DocumentView extends DocComponent(Docu this.Document.isLinkButton = false; } else { this.Document.isLinkButton = true; + this.Document.followLinkZoom = true; this.Document.followLinkLocation = "inPlace"; } } + @undoBatch + toggleFollowOnRight = (): void => { + if (this.Document.isLinkButton) { + this.Document.isLinkButton = false; + } else { + this.Document.isLinkButton = true; + this.Document.followLinkZoom = false; + const first = DocListCast(this.Document.links).find(d => d instanceof Doc); + first && (first.hidden = true); + this.Document.followLinkLocation = "onRight"; + } + } + @undoBatch @action drop = async (e: Event, de: DragManager.DropEvent) => { @@ -679,20 +694,27 @@ export class DocumentView extends DocComponent(Docu cm.addItem({ description: item.label, event: () => item.script.script.run({ this: this.layoutDoc, self: this.rootDoc }), icon: "sticky-note" })); - const existing = cm.findByDescription("Options..."); - const layoutItems: ContextMenuProps[] = existing && "subitems" in existing ? existing.subitems : []; - layoutItems.push({ description: `${this.Document._chromeStatus !== "disabled" ? "Hide" : "Show"} Chrome`, event: () => this.Document._chromeStatus = (this.Document._chromeStatus !== "disabled" ? "disabled" : "enabled"), icon: "project-diagram" }); - layoutItems.push({ description: `${this.Document._autoHeight ? "Variable Height" : "Auto Height"}`, event: () => this.layoutDoc._autoHeight = !this.layoutDoc._autoHeight, icon: "plus" }); - layoutItems.push({ description: this.Document.lockedPosition ? "Unlock Position" : "Lock Position", event: this.toggleLockPosition, icon: BoolCast(this.Document.lockedPosition) ? "unlock" : "lock" }); - layoutItems.push({ description: this.Document.lockedTransform ? "Unlock Transform" : "Lock Transform", event: this.toggleLockTransform, icon: BoolCast(this.Document.lockedTransform) ? "unlock" : "lock" }); - !existing && cm.addItem({ description: "Options...", subitems: layoutItems, icon: "compass" }); - - const open = cm.findByDescription("New Perspective..."); + let open = cm.findByDescription("Add a Perspective..."); const openItems: ContextMenuProps[] = open && "subitems" in open ? open.subitems : []; openItems.push({ description: "Open Fields ", event: () => this.props.addDocTab(Docs.Create.KVPDocument(this.props.Document, { _width: 300, _height: 300 }), "onRight"), icon: "layer-group" }); templateDoc && openItems.push({ description: "Open Template ", event: () => this.props.addDocTab(templateDoc, "onRight"), icon: "eye" }); - !open && cm.addItem({ description: "New Perspective...", subitems: openItems, icon: "external-link-alt" }); + if (!open) { + open = { description: "Add a Perspective....", subitems: openItems, icon: "external-link-alt" }; + cm.addItem(open); + } + + let options = cm.findByDescription("Options..."); + const optionItems: ContextMenuProps[] = options && "subitems" in options ? options.subitems : []; + optionItems.push({ description: `${this.Document._chromeStatus !== "disabled" ? "Hide" : "Show"} Chrome`, event: () => this.Document._chromeStatus = (this.Document._chromeStatus !== "disabled" ? "disabled" : "enabled"), icon: "project-diagram" }); + optionItems.push({ description: `${this.Document._autoHeight ? "Variable Height" : "Auto Height"}`, event: () => this.layoutDoc._autoHeight = !this.layoutDoc._autoHeight, icon: "plus" }); + optionItems.push({ description: this.Document.lockedPosition ? "Unlock Position" : "Lock Position", event: this.toggleLockPosition, icon: BoolCast(this.Document.lockedPosition) ? "unlock" : "lock" }); + optionItems.push({ description: this.Document.lockedTransform ? "Unlock Transform" : "Lock Transform", event: this.toggleLockTransform, icon: BoolCast(this.Document.lockedTransform) ? "unlock" : "lock" }); + if (!options) { + options = { description: "Options...", subitems: optionItems, icon: "compass" }; + cm.addItem(options); + } + cm.moveAfter(options, open); const existingOnClick = cm.findByDescription("OnClick..."); const onClicks: ContextMenuProps[] = existingOnClick && "subitems" in existingOnClick ? existingOnClick.subitems : []; @@ -700,6 +722,7 @@ export class DocumentView extends DocComponent(Docu onClicks.push({ description: "Toggle Detail", event: () => this.Document.onClick = ScriptField.MakeScript(`toggleDetail(self, "${this.props.Document.layoutKey}")`), icon: "window-restore" }); onClicks.push({ description: this.Document.ignoreClick ? "Select" : "Do Nothing", event: () => this.Document.ignoreClick = !this.Document.ignoreClick, icon: this.Document.ignoreClick ? "unlock" : "lock" }); onClicks.push({ description: this.Document.isLinkButton ? "Remove Follow Behavior" : "Follow Link in Place", event: this.toggleFollowInPlace, icon: "concierge-bell" }); + onClicks.push({ description: this.Document.isLinkButton ? "Remove Follow Behavior" : "Follow Link on Right", event: this.toggleFollowOnRight, icon: "concierge-bell" }); onClicks.push({ description: this.Document.isLinkButton || this.Document.onClick ? "Remove Click Behavior" : "Follow Link", event: this.toggleLinkButtonBehavior, icon: "concierge-bell" }); onClicks.push({ description: "Edit onClick Script", event: () => UndoManager.RunInBatch(() => Doc.makeCustomViewClicked(this.props.Document, undefined, "onClick"), "edit onClick"), icon: "edit" }); !existingOnClick && cm.addItem({ description: "OnClick...", subitems: onClicks, icon: "hand-point-right" }); diff --git a/src/client/views/nodes/FormattedTextBox.tsx b/src/client/views/nodes/FormattedTextBox.tsx index a018f17e8..d7cfbae9f 100644 --- a/src/client/views/nodes/FormattedTextBox.tsx +++ b/src/client/views/nodes/FormattedTextBox.tsx @@ -444,7 +444,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp changeItems.push({ description: "FreeForm", event: undoBatch(() => Doc.makeCustomViewClicked(this.rootDoc, Docs.Create.FreeformDocument, "freeform"), "change view"), icon: "eye" }); !change && cm.addItem({ description: "Change Perspective...", subitems: changeItems, icon: "external-link-alt" }); - const open = cm.findByDescription("New Perspective..."); + const open = cm.findByDescription("Add a Perspective..."); const openItems: ContextMenuProps[] = open && "subitems" in open ? open.subitems : []; openItems.push({ @@ -454,7 +454,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp this.props.addDocTab(alias, "onRight"); }), icon: "eye" }); - !open && cm.addItem({ description: "New Perspective...", subitems: openItems, icon: "external-link-alt" }); + !open && cm.addItem({ description: "Add a Perspective...", subitems: openItems, icon: "external-link-alt" }); } diff --git a/src/client/views/nodes/FormattedTextBoxComment.tsx b/src/client/views/nodes/FormattedTextBoxComment.tsx index 41df5b3c1..a9f76ae8f 100644 --- a/src/client/views/nodes/FormattedTextBoxComment.tsx +++ b/src/client/views/nodes/FormattedTextBoxComment.tsx @@ -88,7 +88,6 @@ export class FormattedTextBoxComment { if (FormattedTextBoxComment.linkDoc.type !== DocumentType.LINK) { textBox.props.addDocTab(FormattedTextBoxComment.linkDoc, e.ctrlKey ? "inTab" : "onRight"); } else { - DocumentView._focusHack = []; DocumentManager.Instance.FollowLink(FormattedTextBoxComment.linkDoc, textBox.props.Document, (doc: Doc, followLinkLocation: string) => textBox.props.addDocTab(doc, e.ctrlKey ? "inTab" : followLinkLocation)); } diff --git a/src/client/views/nodes/LinkAnchorBox.tsx b/src/client/views/nodes/LinkAnchorBox.tsx index eb647d0e4..707b9d12a 100644 --- a/src/client/views/nodes/LinkAnchorBox.tsx +++ b/src/client/views/nodes/LinkAnchorBox.tsx @@ -75,7 +75,6 @@ export class LinkAnchorBox extends ViewBoxBaseComponent { - DocumentView._focusHack = []; DocumentManager.Instance.FollowLink(this.rootDoc, anchorContainerDoc, document => this.props.addDocTab(document, StrCast(this.layoutDoc.linkOpenLocation, "inTab")), false); this._editing = false; }), 300 - (Date.now() - this._lastTap)); diff --git a/src/client/views/pdf/Annotation.tsx b/src/client/views/pdf/Annotation.tsx index eaf80d252..672d3adb8 100644 --- a/src/client/views/pdf/Annotation.tsx +++ b/src/client/views/pdf/Annotation.tsx @@ -98,7 +98,6 @@ class RegionAnnotation extends React.Component { else if (e.button === 0) { const annoGroup = await Cast(this.props.document.group, Doc); if (annoGroup) { - DocumentView._focusHack = []; DocumentManager.Instance.FollowLink(undefined, annoGroup, (doc, followLinkLocation) => this.props.addDocTab(doc, e.ctrlKey ? "inTab" : followLinkLocation), false, undefined); e.stopPropagation(); } -- cgit v1.2.3-70-g09d2 From 627adb92b604e117694e26af65afdc19920ac509 Mon Sep 17 00:00:00 2001 From: Bob Zeleznik Date: Sat, 25 Apr 2020 21:26:28 -0400 Subject: added internalPreDrop to set dropActions. made linksView turn off during dragging. --- src/client/util/DragManager.ts | 22 ++++++++++++++++++++-- .../views/collections/CollectionPileView.tsx | 2 ++ src/client/views/collections/CollectionSubView.tsx | 7 ++++++- .../CollectionFreeFormLinksView.tsx | 2 +- 4 files changed, 29 insertions(+), 4 deletions(-) (limited to 'src/client/util') diff --git a/src/client/util/DragManager.ts b/src/client/util/DragManager.ts index 6bb44f7d6..6a55f4a00 100644 --- a/src/client/util/DragManager.ts +++ b/src/client/util/DragManager.ts @@ -179,7 +179,8 @@ export namespace DragManager { export function MakeDropTarget( element: HTMLElement, - dropFunc: (e: Event, de: DropEvent) => void + dropFunc: (e: Event, de: DropEvent) => void, + preDropFunc?: (e: Event, de: DropEvent) => void ): DragDropDisposer { if ("canDrop" in element.dataset) { throw new Error( @@ -187,10 +188,13 @@ export namespace DragManager { ); } element.dataset.canDrop = "true"; - const handler = (e: Event) => { dropFunc(e, (e as CustomEvent).detail); }; + const handler = (e: Event) => dropFunc(e, (e as CustomEvent).detail); + const preDropHandler = (e: Event) => preDropFunc?.(e, (e as CustomEvent).detail); element.addEventListener("dashOnDrop", handler); + preDropFunc && element.addEventListener("dashPreDrop", preDropHandler); return () => { element.removeEventListener("dashOnDrop", handler); + preDropFunc && element.removeEventListener("dashPreDrop", preDropHandler); delete element.dataset.canDrop; }; } @@ -425,6 +429,20 @@ export namespace DragManager { }); if (target) { const complete = new DragCompleteEvent(false, dragData); + target.dispatchEvent( + new CustomEvent("dashPreDrop", { + bubbles: true, + detail: { + x: e.x, + y: e.y, + complete: complete, + shiftKey: e.shiftKey, + altKey: e.altKey, + metaKey: e.metaKey, + ctrlKey: e.ctrlKey + } + }) + ); finishDrag?.(complete); target.dispatchEvent( new CustomEvent("dashOnDrop", { diff --git a/src/client/views/collections/CollectionPileView.tsx b/src/client/views/collections/CollectionPileView.tsx index 410b16ec7..3bbfcc4d7 100644 --- a/src/client/views/collections/CollectionPileView.tsx +++ b/src/client/views/collections/CollectionPileView.tsx @@ -78,6 +78,7 @@ export class CollectionPileView extends CollectionSubView(doc => doc) { _undoBatch: UndoManager.Batch | undefined; pointerDown = (e: React.PointerEvent) => { let dist = 0; + SelectionManager.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)) { @@ -97,6 +98,7 @@ export class CollectionPileView extends CollectionSubView(doc => doc) { }, () => { this._undoBatch?.end(); this._undoBatch = undefined; + SelectionManager.SetIsDragging(false); if (!this.childDocs.length) { this.props.ContainingCollectionView?.removeDocument(this.props.Document); } diff --git a/src/client/views/collections/CollectionSubView.tsx b/src/client/views/collections/CollectionSubView.tsx index c530b24fb..60cc1bd49 100644 --- a/src/client/views/collections/CollectionSubView.tsx +++ b/src/client/views/collections/CollectionSubView.tsx @@ -64,7 +64,7 @@ export function CollectionSubView(schemaCtor: (doc: Doc) => T, moreProps?: this.multiTouchDisposer?.(); if (ele) { this._mainCont = ele; - this.dropDisposer = DragManager.MakeDropTarget(ele, this.onInternalDrop.bind(this)); + this.dropDisposer = DragManager.MakeDropTarget(ele, this.onInternalDrop.bind(this), this.onInternalPreDrop.bind(this)); this.gestureDisposer = GestureUtils.MakeGestureTarget(ele, this.onGesture.bind(this)); this.multiTouchDisposer = InteractionUtils.MakeMultiTouchTarget(ele, this.onTouchStart.bind(this)); } @@ -208,6 +208,11 @@ export function CollectionSubView(schemaCtor: (doc: Doc) => T, moreProps?: protected onGesture(e: Event, ge: GestureUtils.GestureEvent) { } + protected onInternalPreDrop(e: Event, de: DragManager.DropEvent): boolean { + // de.complete.docDragData!.dropAction = "alias"; bcz: for example, you can convert all drops to aliases here + return true; + } + @undoBatch @action protected onInternalDrop(e: Event, de: DragManager.DropEvent): boolean { diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinksView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinksView.tsx index 702b02a20..4b5e977df 100644 --- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinksView.tsx +++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinksView.tsx @@ -36,7 +36,7 @@ export class CollectionFreeFormLinksView extends React.Component { } render() { - return
+ return SelectionManager.GetIsDragging() ? (null) :
{this.uniqueConnections} -- cgit v1.2.3-70-g09d2 From f1ac48c19b4683668b0df91bd4ad68690a069029 Mon Sep 17 00:00:00 2001 From: Bob Zeleznik Date: Sat, 25 Apr 2020 21:43:21 -0400 Subject: added a targetDropAction field to specify the drop action from the target's side --- src/client/util/DragManager.ts | 15 ++++++++++----- src/client/views/collections/CollectionCarouselView.tsx | 2 +- src/client/views/collections/CollectionLinearView.tsx | 2 +- .../views/collections/CollectionSchemaMovableTableHOC.tsx | 2 +- src/client/views/collections/CollectionSubView.tsx | 9 ++------- src/client/views/collections/CollectionTreeView.tsx | 4 ++-- src/client/views/collections/CollectionViewChromes.tsx | 4 ++-- src/client/views/nodes/DocumentView.tsx | 4 ++-- src/client/views/nodes/FormattedTextBox.tsx | 2 +- src/client/views/nodes/ImageBox.tsx | 2 +- src/client/views/nodes/LabelBox.tsx | 2 +- src/new_fields/documentSchemas.ts | 3 ++- 12 files changed, 26 insertions(+), 25 deletions(-) (limited to 'src/client/util') diff --git a/src/client/util/DragManager.ts b/src/client/util/DragManager.ts index 6a55f4a00..577366cd4 100644 --- a/src/client/util/DragManager.ts +++ b/src/client/util/DragManager.ts @@ -1,5 +1,5 @@ import { Doc, Field, DocListCast } from "../../new_fields/Doc"; -import { Cast, ScriptCast } from "../../new_fields/Types"; +import { Cast, ScriptCast, StrCast } from "../../new_fields/Types"; import { emptyFunction } from "../../Utils"; import { CollectionDockingView } from "../views/collections/CollectionDockingView"; import * as globalCssVariables from "../views/globalCssVariables.scss"; @@ -180,7 +180,7 @@ export namespace DragManager { export function MakeDropTarget( element: HTMLElement, dropFunc: (e: Event, de: DropEvent) => void, - preDropFunc?: (e: Event, de: DropEvent) => void + doc?:Doc ): DragDropDisposer { if ("canDrop" in element.dataset) { throw new Error( @@ -189,12 +189,17 @@ export namespace DragManager { } element.dataset.canDrop = "true"; const handler = (e: Event) => dropFunc(e, (e as CustomEvent).detail); - const preDropHandler = (e: Event) => preDropFunc?.(e, (e as CustomEvent).detail); + const preDropHandler = (e:Event) => { + const de = (e as CustomEvent).detail; + if (de.complete.docDragData && doc?.targetDropAction) { + de.complete.docDragData!.dropAction = StrCast(doc.targetDropAction) as dropActionType; + } + } element.addEventListener("dashOnDrop", handler); - preDropFunc && element.addEventListener("dashPreDrop", preDropHandler); + doc && element.addEventListener("dashPreDrop", preDropHandler); return () => { element.removeEventListener("dashOnDrop", handler); - preDropFunc && element.removeEventListener("dashPreDrop", preDropHandler); + doc && element.removeEventListener("dashPreDrop", preDropHandler); delete element.dataset.canDrop; }; } diff --git a/src/client/views/collections/CollectionCarouselView.tsx b/src/client/views/collections/CollectionCarouselView.tsx index 9e7248db2..2453acddf 100644 --- a/src/client/views/collections/CollectionCarouselView.tsx +++ b/src/client/views/collections/CollectionCarouselView.tsx @@ -27,7 +27,7 @@ export class CollectionCarouselView extends CollectionSubView(CarouselDocument) protected createDashEventsTarget = (ele: HTMLDivElement) => { //used for stacking and masonry view this._dropDisposer?.(); if (ele) { - this._dropDisposer = DragManager.MakeDropTarget(ele, this.onInternalDrop.bind(this)); + this._dropDisposer = DragManager.MakeDropTarget(ele, this.onInternalDrop.bind(this), this.layoutDoc); } } diff --git a/src/client/views/collections/CollectionLinearView.tsx b/src/client/views/collections/CollectionLinearView.tsx index cb0206260..344dca23a 100644 --- a/src/client/views/collections/CollectionLinearView.tsx +++ b/src/client/views/collections/CollectionLinearView.tsx @@ -64,7 +64,7 @@ export class CollectionLinearView extends CollectionSubView(LinearDocument) { protected createDashEventsTarget = (ele: HTMLDivElement) => { //used for stacking and masonry view this._dropDisposer && this._dropDisposer(); if (ele) { - this._dropDisposer = DragManager.MakeDropTarget(ele, this.onInternalDrop.bind(this)); + this._dropDisposer = DragManager.MakeDropTarget(ele, this.onInternalDrop.bind(this), this.layoutDoc); } } diff --git a/src/client/views/collections/CollectionSchemaMovableTableHOC.tsx b/src/client/views/collections/CollectionSchemaMovableTableHOC.tsx index 670d6dbb2..972714e34 100644 --- a/src/client/views/collections/CollectionSchemaMovableTableHOC.tsx +++ b/src/client/views/collections/CollectionSchemaMovableTableHOC.tsx @@ -54,7 +54,7 @@ export class MovableColumn extends React.Component { } createColDropTarget = (ele: HTMLDivElement) => { - this._colDropDisposer && this._colDropDisposer(); + this._colDropDisposer?.(); if (ele) { this._colDropDisposer = DragManager.MakeDropTarget(ele, this.colDrop.bind(this)); } diff --git a/src/client/views/collections/CollectionSubView.tsx b/src/client/views/collections/CollectionSubView.tsx index 60cc1bd49..49abc6ee6 100644 --- a/src/client/views/collections/CollectionSubView.tsx +++ b/src/client/views/collections/CollectionSubView.tsx @@ -11,7 +11,7 @@ import { Utils } from "../../../Utils"; import { DocServer } from "../../DocServer"; import { DocumentType } from "../../documents/DocumentTypes"; import { Docs, DocumentOptions } from "../../documents/Documents"; -import { DragManager } from "../../util/DragManager"; +import { DragManager, dropActionType } from "../../util/DragManager"; import { undoBatch, UndoManager } from "../../util/UndoManager"; import { DocComponent } from "../DocComponent"; import { FieldViewProps } from "../nodes/FieldView"; @@ -64,7 +64,7 @@ export function CollectionSubView(schemaCtor: (doc: Doc) => T, moreProps?: this.multiTouchDisposer?.(); if (ele) { this._mainCont = ele; - this.dropDisposer = DragManager.MakeDropTarget(ele, this.onInternalDrop.bind(this), this.onInternalPreDrop.bind(this)); + this.dropDisposer = DragManager.MakeDropTarget(ele, this.onInternalDrop.bind(this), this.layoutDoc); this.gestureDisposer = GestureUtils.MakeGestureTarget(ele, this.onGesture.bind(this)); this.multiTouchDisposer = InteractionUtils.MakeMultiTouchTarget(ele, this.onTouchStart.bind(this)); } @@ -208,11 +208,6 @@ export function CollectionSubView(schemaCtor: (doc: Doc) => T, moreProps?: protected onGesture(e: Event, ge: GestureUtils.GestureEvent) { } - protected onInternalPreDrop(e: Event, de: DragManager.DropEvent): boolean { - // de.complete.docDragData!.dropAction = "alias"; bcz: for example, you can convert all drops to aliases here - return true; - } - @undoBatch @action protected onInternalDrop(e: Event, de: DragManager.DropEvent): boolean { diff --git a/src/client/views/collections/CollectionTreeView.tsx b/src/client/views/collections/CollectionTreeView.tsx index ca2004b79..8c5a4538e 100644 --- a/src/client/views/collections/CollectionTreeView.tsx +++ b/src/client/views/collections/CollectionTreeView.tsx @@ -143,7 +143,7 @@ class TreeView extends React.Component { protected createTreeDropTarget = (ele: HTMLDivElement) => { this._treedropDisposer && this._treedropDisposer(); - ele && (this._treedropDisposer = DragManager.MakeDropTarget(ele, this.treeDrop.bind(this))); + ele && (this._treedropDisposer = DragManager.MakeDropTarget(ele, this.treeDrop.bind(this)), this.props.document); } onPointerEnter = (e: React.PointerEvent): void => { @@ -663,7 +663,7 @@ export class CollectionTreeView extends CollectionSubView { this.treedropDisposer?.(); if (this._mainEle = ele) { - this.treedropDisposer = DragManager.MakeDropTarget(ele, this.onInternalDrop.bind(this)); + this.treedropDisposer = DragManager.MakeDropTarget(ele, this.onInternalDrop.bind(this), this.props.Document); } } diff --git a/src/client/views/collections/CollectionViewChromes.tsx b/src/client/views/collections/CollectionViewChromes.tsx index 7315d2c4e..d26e3a38b 100644 --- a/src/client/views/collections/CollectionViewChromes.tsx +++ b/src/client/views/collections/CollectionViewChromes.tsx @@ -215,9 +215,9 @@ export class CollectionViewBaseChrome extends React.Component { - this.dropDisposer && this.dropDisposer(); + this.dropDisposer?.(); if (ele) { - this.dropDisposer = DragManager.MakeDropTarget(ele, this.drop.bind(this)); + this.dropDisposer = DragManager.MakeDropTarget(ele, this.drop.bind(this), this.document); } } diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx index 7ae77fc65..2aee49ad3 100644 --- a/src/client/views/nodes/DocumentView.tsx +++ b/src/client/views/nodes/DocumentView.tsx @@ -191,7 +191,7 @@ export class DocumentView extends DocComponent(Docu @action componentDidMount() { - this._mainCont.current && (this._dropDisposer = DragManager.MakeDropTarget(this._mainCont.current, this.drop.bind(this))); + this._mainCont.current && (this._dropDisposer = DragManager.MakeDropTarget(this._mainCont.current, this.drop.bind(this), this.props.Document)); this._mainCont.current && (this._gestureEventDisposer = GestureUtils.MakeGestureTarget(this._mainCont.current, this.onGesture.bind(this))); this._mainCont.current && (this.multiTouchDisposer = InteractionUtils.MakeMultiTouchTarget(this._mainCont.current, this.onTouchStart.bind(this))); // this._mainCont.current && (this.holdDisposer = InteractionUtils.MakeHoldTouchTarget(this._mainCont.current, this.handle1PointerHoldStart.bind(this))); @@ -208,7 +208,7 @@ export class DocumentView extends DocComponent(Docu this.multiTouchDisposer?.(); this.holdDisposer?.(); if (this._mainCont.current) { - this._dropDisposer = DragManager.MakeDropTarget(this._mainCont.current, this.drop.bind(this)); + this._dropDisposer = DragManager.MakeDropTarget(this._mainCont.current, this.drop.bind(this), this.props.Document); this._gestureEventDisposer = GestureUtils.MakeGestureTarget(this._mainCont.current, this.onGesture.bind(this)); this.multiTouchDisposer = InteractionUtils.MakeMultiTouchTarget(this._mainCont.current, this.onTouchStart.bind(this)); this.holdDisposer = InteractionUtils.MakeHoldTouchTarget(this._mainCont.current, this.handle1PointerHoldStart.bind(this)); diff --git a/src/client/views/nodes/FormattedTextBox.tsx b/src/client/views/nodes/FormattedTextBox.tsx index d7cfbae9f..815b8b3ae 100644 --- a/src/client/views/nodes/FormattedTextBox.tsx +++ b/src/client/views/nodes/FormattedTextBox.tsx @@ -253,7 +253,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp protected createDropTarget = (ele: HTMLDivElement) => { this.ProseRef = ele; this.dropDisposer?.(); - ele && (this.dropDisposer = DragManager.MakeDropTarget(ele, this.drop.bind(this))); + ele && (this.dropDisposer = DragManager.MakeDropTarget(ele, this.drop.bind(this), this.props.Document)); } @undoBatch diff --git a/src/client/views/nodes/ImageBox.tsx b/src/client/views/nodes/ImageBox.tsx index 14b367868..08917d281 100644 --- a/src/client/views/nodes/ImageBox.tsx +++ b/src/client/views/nodes/ImageBox.tsx @@ -76,7 +76,7 @@ export class ImageBox extends ViewBoxAnnotatableComponent { this._dropDisposer && this._dropDisposer(); - ele && (this._dropDisposer = DragManager.MakeDropTarget(ele, this.drop.bind(this))); + ele && (this._dropDisposer = DragManager.MakeDropTarget(ele, this.drop.bind(this), this.props.Document)); } @undoBatch diff --git a/src/client/views/nodes/LabelBox.tsx b/src/client/views/nodes/LabelBox.tsx index 5c2fc3ffe..a41e4fac4 100644 --- a/src/client/views/nodes/LabelBox.tsx +++ b/src/client/views/nodes/LabelBox.tsx @@ -32,7 +32,7 @@ export class LabelBox extends ViewBoxBaseComponent { this.dropDisposer?.(); if (ele) { - this.dropDisposer = DragManager.MakeDropTarget(ele, this.drop.bind(this)); + this.dropDisposer = DragManager.MakeDropTarget(ele, this.drop.bind(this), this.props.Document); } } diff --git a/src/new_fields/documentSchemas.ts b/src/new_fields/documentSchemas.ts index 61b185e5c..f24ad42b2 100644 --- a/src/new_fields/documentSchemas.ts +++ b/src/new_fields/documentSchemas.ts @@ -8,7 +8,8 @@ export const documentSchema = createSchema({ layout: "string", // this is the native layout string for the document. templates can be added using other fields and setting layoutKey below layoutKey: "string", // holds the field key for the field that actually holds the current lyoat title: "string", // document title (can be on either data document or layout) - dropAction: "string", // override specifying what should happen when this document is dropped (can be "alias" or "copy") + dropAction: "string", // override specifying what should happen when this document is dropped (can be "alias", "copy", "move") + targetDropAction: "string", // allows the target of a drop event to specify the dropAction ("alias", "copy", "move") childDropAction: "string", // specify the override for what should happen when the child of a collection is dragged from it and dropped (can be "alias" or "copy") _autoHeight: "boolean", // whether the height of the document should be computed automatically based on its contents _nativeWidth: "number", // native width of document which determines how much document contents are scaled when the document's width is set -- cgit v1.2.3-70-g09d2 From e6549d43be83b50d364c4a3ab1e8e7381ce2fd59 Mon Sep 17 00:00:00 2001 From: Bob Zeleznik Date: Sun, 26 Apr 2020 01:56:41 -0400 Subject: fixed title layout for text. fixed documentBox for nested collections. fixed tree view for text boxes. changed labelbox formatting. --- src/client/util/DragManager.ts | 8 ++++---- src/client/views/collections/CollectionTreeView.tsx | 13 +++++++++---- .../collectionFreeForm/CollectionFreeFormView.tsx | 3 ++- src/client/views/nodes/ColorBox.scss | 1 + src/client/views/nodes/DocumentBox.tsx | 4 ++-- src/client/views/nodes/DocumentView.tsx | 7 ++----- src/client/views/nodes/FormattedTextBox.scss | 1 - src/client/views/nodes/FormattedTextBox.tsx | 4 ++-- src/client/views/nodes/LabelBox.scss | 2 -- src/client/views/nodes/LabelBox.tsx | 8 +++++++- src/server/authentication/models/current_user_utils.ts | 4 ++-- 11 files changed, 31 insertions(+), 24 deletions(-) (limited to 'src/client/util') diff --git a/src/client/util/DragManager.ts b/src/client/util/DragManager.ts index 577366cd4..35694a6bd 100644 --- a/src/client/util/DragManager.ts +++ b/src/client/util/DragManager.ts @@ -180,7 +180,7 @@ export namespace DragManager { export function MakeDropTarget( element: HTMLElement, dropFunc: (e: Event, de: DropEvent) => void, - doc?:Doc + doc?: Doc ): DragDropDisposer { if ("canDrop" in element.dataset) { throw new Error( @@ -189,12 +189,12 @@ export namespace DragManager { } element.dataset.canDrop = "true"; const handler = (e: Event) => dropFunc(e, (e as CustomEvent).detail); - const preDropHandler = (e:Event) => { + const preDropHandler = (e: Event) => { const de = (e as CustomEvent).detail; if (de.complete.docDragData && doc?.targetDropAction) { - de.complete.docDragData!.dropAction = StrCast(doc.targetDropAction) as dropActionType; + de.complete.docDragData.dropAction = StrCast(doc.targetDropAction) as dropActionType; } - } + }; element.addEventListener("dashOnDrop", handler); doc && element.addEventListener("dashPreDrop", preDropHandler); return () => { diff --git a/src/client/views/collections/CollectionTreeView.tsx b/src/client/views/collections/CollectionTreeView.tsx index 8c5a4538e..ddd7474bd 100644 --- a/src/client/views/collections/CollectionTreeView.tsx +++ b/src/client/views/collections/CollectionTreeView.tsx @@ -261,7 +261,7 @@ class TreeView extends React.Component { docHeight = () => { const layoutDoc = Doc.Layout(this.props.document); const bounds = this.boundsOfCollectionDocument; - return Math.min(this.MAX_EMBED_HEIGHT, (() => { + return Math.max(70, Math.min(this.MAX_EMBED_HEIGHT, (() => { const aspect = NumCast(layoutDoc._nativeHeight, layoutDoc._fitWidth ? 0 : layoutDoc[HeightSym]()) / NumCast(layoutDoc._nativeWidth, layoutDoc._fitWidth ? 1 : layoutDoc[WidthSym]()); if (aspect) return this.docWidth() * aspect; if (bounds) return this.docWidth() * (bounds.b - bounds.y) / (bounds.r - bounds.x); @@ -269,7 +269,7 @@ class TreeView extends React.Component { Math.min(this.docWidth() * NumCast(layoutDoc.scrollHeight, NumCast(layoutDoc._nativeHeight)) / NumCast(layoutDoc._nativeWidth, NumCast(this.props.containingCollection._height)))) : NumCast(layoutDoc._height) ? NumCast(layoutDoc._height) : 50; - })()); + })())); } @computed get expandedField() { @@ -321,6 +321,9 @@ class TreeView extends React.Component { return rows; } + rtfWidth = () => Math.min(Doc.Layout(this.props.document)?.[WidthSym](), this.props.panelWidth() - 20); + rtfHeight = () => this.rtfWidth() < Doc.Layout(this.props.document)?.[WidthSym]() ? Math.min(Doc.Layout(this.props.document)?.[HeightSym](), this.MAX_EMBED_HEIGHT) : this.MAX_EMBED_HEIGHT; + @computed get renderContent() { const expandKey = this.treeViewExpandedView === this.fieldKey ? this.fieldKey : this.treeViewExpandedView === "links" ? "links" : undefined; if (expandKey !== undefined) { @@ -355,8 +358,10 @@ class TreeView extends React.Component { backgroundColor={this.props.backgroundColor} fitToBox={this.boundsOfCollectionDocument !== undefined} FreezeDimensions={true} - PanelWidth={this.docWidth} - PanelHeight={this.docHeight} + NativeWidth={layoutDoc.type === DocumentType.RTF ? this.rtfWidth : undefined} + NativeHeight={layoutDoc.type === DocumentType.RTF ? this.rtfHeight : undefined} + PanelWidth={layoutDoc.type === DocumentType.RTF ? this.rtfWidth : this.docWidth} + PanelHeight={layoutDoc.type === DocumentType.RTF ? this.rtfHeight : this.docHeight} getTransform={this.docTransform} CollectionDoc={this.props.containingCollection} CollectionView={undefined} diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx index 852442fd4..28b461313 100644 --- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx +++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx @@ -1026,7 +1026,8 @@ export class CollectionFreeFormView extends CollectionSubView, bounds: this.childDataProvider(entry[1].pair.layout, entry[1].replica) diff --git a/src/client/views/nodes/ColorBox.scss b/src/client/views/nodes/ColorBox.scss index bf334c939..da3266dc1 100644 --- a/src/client/views/nodes/ColorBox.scss +++ b/src/client/views/nodes/ColorBox.scss @@ -3,6 +3,7 @@ height:100%; position: relative; pointer-events: none; + transform-origin: top left; .sketch-picker { margin:auto; diff --git a/src/client/views/nodes/DocumentBox.tsx b/src/client/views/nodes/DocumentBox.tsx index 0111cadd5..0d18baaed 100644 --- a/src/client/views/nodes/DocumentBox.tsx +++ b/src/client/views/nodes/DocumentBox.tsx @@ -120,8 +120,8 @@ export class DocHolderBox extends ViewBoxAnnotatableComponent(Docu layoutKey={this.finalLayoutKey} />
); const titleView = (!showTitle ? (null) : -
@@ -1086,10 +1086,7 @@ export class DocumentView extends DocComponent(Docu return !showTitle && !showCaption ? this.contents :
-
- {this.contents} -
- {titleView} + {this.Document.type !== DocumentType.RTF ? <> {this.contents} {titleView} : <> {titleView} {this.contents} } {captionView}
; } diff --git a/src/client/views/nodes/FormattedTextBox.scss b/src/client/views/nodes/FormattedTextBox.scss index 7a05ec3a3..3bedb7127 100644 --- a/src/client/views/nodes/FormattedTextBox.scss +++ b/src/client/views/nodes/FormattedTextBox.scss @@ -24,7 +24,6 @@ overflow-y: auto; overflow-x: hidden; color: initial; - height: 100%; max-height: 100%; display: flex; flex-direction: row; diff --git a/src/client/views/nodes/FormattedTextBox.tsx b/src/client/views/nodes/FormattedTextBox.tsx index 815b8b3ae..425af8ccf 100644 --- a/src/client/views/nodes/FormattedTextBox.tsx +++ b/src/client/views/nodes/FormattedTextBox.tsx @@ -194,7 +194,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp const tsel = this._editorView.state.selection.$from; tsel.marks().filter(m => 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\n"); + const curText = state.doc.textBetween(0, state.doc.content.size, " \n"); const curTemp = Cast(this.props.Document[this.props.fieldKey + "-textTemplate"], RichTextField); if (!this._applyingChange) { this._applyingChange = true; @@ -1211,7 +1211,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp return (
{StrCast(this.rootDoc.text, StrCast(this.rootDoc.title))} diff --git a/src/server/authentication/models/current_user_utils.ts b/src/server/authentication/models/current_user_utils.ts index afde524b6..25775edef 100644 --- a/src/server/authentication/models/current_user_utils.ts +++ b/src/server/authentication/models/current_user_utils.ts @@ -167,7 +167,7 @@ export class CurrentUserUtils { 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: 30, 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, onClick: ScriptField.MakeScript("deiconifyView(self)") }); iconRtfView.isTemplateDoc = makeTemplate(iconRtfView, true, "icon_" + DocumentType.RTF); doc["template-icon-view-rtf"] = new PrefetchProxy(iconRtfView); } @@ -214,7 +214,7 @@ export class CurrentUserUtils { { 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" })' }, { title: "Drag a audio recorder", label: "Audio", icon: "microphone", ignoreClick: true, drag: `Docs.Create.AudioDocument("${nullAudio}", { _width: 200, title: "ready to record audio" })` }, - { title: "Drag a clickable button", label: "Btn", icon: "bolt", ignoreClick: true, drag: 'Docs.Create.ButtonDocument({ _width: 150, _height: 50, title: "Button" })' }, + { title: "Drag a clickable button", label: "Btn", icon: "bolt", ignoreClick: true, drag: 'Docs.Create.ButtonDocument({ _width: 150, _height: 50, _xPadding:10, _yPadding: 10, title: "Button" })' }, { title: "Drag a presentation view", label: "Prezi", icon: "tv", click: 'openOnRight(Doc.UserDoc().activePresentation = getCopy(this.dragFactory, true))', drag: `Doc.UserDoc().activePresentation = getCopy(this.dragFactory,true)`, dragFactory: doc.emptyPresentation as Doc }, { title: "Drag a search box", label: "Query", icon: "search", ignoreClick: true, drag: 'Docs.Create.QueryDocument({ _width: 200, title: "an image of a cat" })' }, { title: "Drag a scripting box", label: "Script", icon: "terminal", ignoreClick: true, drag: 'Docs.Create.ScriptingDocument(undefined, { _width: 200, _height: 250 title: "untitled script" })' }, -- cgit v1.2.3-70-g09d2 From d24622da70be0100846afb780f3f8734f22f4196 Mon Sep 17 00:00:00 2001 From: Bob Zeleznik Date: Sun, 26 Apr 2020 11:30:47 -0400 Subject: tweaks to inline attribute fields in text boxes --- src/client/util/RichTextSchema.tsx | 21 ++++++++++----------- 1 file changed, 10 insertions(+), 11 deletions(-) (limited to 'src/client/util') diff --git a/src/client/util/RichTextSchema.tsx b/src/client/util/RichTextSchema.tsx index b88a7b017..8882cdc8e 100644 --- a/src/client/util/RichTextSchema.tsx +++ b/src/client/util/RichTextSchema.tsx @@ -15,7 +15,7 @@ import { ObjectField } from "../../new_fields/ObjectField"; import { listSpec } from "../../new_fields/Schema"; import { SchemaHeaderField } from "../../new_fields/SchemaHeaderField"; import { ComputedField } from "../../new_fields/ScriptField"; -import { BoolCast, Cast, NumCast, StrCast } from "../../new_fields/Types"; +import { BoolCast, Cast, NumCast, StrCast, FieldValue } from "../../new_fields/Types"; import { emptyFunction, returnEmptyString, returnFalse, returnOne, Utils, returnZero } from "../../Utils"; import { DocServer } from "../DocServer"; import { Docs } from "../documents/Documents"; @@ -879,7 +879,7 @@ export class DashDocView { export class DashFieldView { _fieldWrapper: HTMLDivElement; // container for label and value _labelSpan: HTMLSpanElement; // field label - _fieldSpan: HTMLDivElement; // field value + _fieldSpan: HTMLSpanElement; // field value _fieldCheck: HTMLInputElement; _enumerables: HTMLDivElement; // field value _reactionDisposer: IReactionDisposer | undefined; @@ -891,11 +891,12 @@ export class DashFieldView { constructor(node: any, view: any, getPos: any, tbox: FormattedTextBox) { this._fieldKey = node.attrs.fieldKey; this._textBoxDoc = tbox.props.Document; - this._fieldWrapper = document.createElement("div"); + this._fieldWrapper = document.createElement("p"); this._fieldWrapper.style.width = node.attrs.width; this._fieldWrapper.style.height = node.attrs.height; + this._fieldWrapper.style.fontWeight = "bold"; this._fieldWrapper.style.position = "relative"; - this._fieldWrapper.style.display = "inline-flex"; + this._fieldWrapper.style.display = "inline-block"; const self = this; this._enumerables = document.createElement("div"); @@ -903,7 +904,6 @@ export class DashFieldView { this._enumerables.style.height = "10px"; this._enumerables.style.position = "relative"; this._enumerables.style.display = "none"; - this._enumerables.style.background = "dimGray"; this._enumerables.onpointerdown = async (e) => { e.stopPropagation(); @@ -946,13 +946,13 @@ export class DashFieldView { self._dashDoc![self._fieldKey] = e.target.checked; }; - this._fieldSpan = document.createElement("div"); + this._fieldSpan = document.createElement("span"); this._fieldSpan.id = Utils.GenerateGuid(); this._fieldSpan.contentEditable = "true"; this._fieldSpan.style.position = "relative"; this._fieldSpan.style.display = "none"; this._fieldSpan.style.minWidth = "12px"; - this._fieldSpan.style.backgroundColor = "rgba(155, 155, 155, 0.24)"; + this._fieldSpan.style.fontSize = "large"; this._fieldSpan.onkeypress = function (e: any) { e.stopPropagation(); }; this._fieldSpan.onkeyup = function (e: any) { e.stopPropagation(); }; this._fieldSpan.onmousedown = function (e: any) { e.stopPropagation(); self._enumerables.style.display = "inline-block"; }; @@ -966,7 +966,7 @@ export class DashFieldView { this._labelSpan.innerHTML = `${self._fieldKey}: `; const fieldVal = Cast(this._dashDoc?.[self._fieldKey], "boolean", null); this._fieldCheck.style.display = (fieldVal === true || fieldVal === false) ? "inline-block" : "none"; - this._fieldSpan.style.display = !(fieldVal === true || fieldVal === false) ? "inline-block" : "none"; + this._fieldSpan.style.display = !(fieldVal === true || fieldVal === false) ? StrCast(this._dashDoc?.[self._fieldKey]) ? "" : "inline-block" : "none"; }; this._fieldSpan.onkeydown = function (e: any) { e.stopPropagation(); @@ -987,11 +987,10 @@ export class DashFieldView { }; this._labelSpan = document.createElement("span"); - this._labelSpan.style.backgroundColor = "rgba(155, 155, 155, 0.44)"; this._labelSpan.style.position = "relative"; - this._labelSpan.style.display = "inline-block"; this._labelSpan.style.fontSize = "small"; this._labelSpan.title = "click to see related tags"; + this._labelSpan.style.fontSize = "x-small"; this._labelSpan.onpointerdown = function (e: any) { e.stopPropagation(); let container = tbox.props.ContainingCollectionView; @@ -1029,7 +1028,7 @@ export class DashFieldView { this._fieldSpan.innerHTML = Field.toString(fval as Field) || ""; } this._fieldCheck.style.display = (boolVal === true || boolVal === false) ? "inline-block" : "none"; - this._fieldSpan.style.display = !(boolVal === true || boolVal === false) ? "inline-block" : "none"; + this._fieldSpan.style.display = !(fval === true || fval === false) ? (StrCast(fval) ? "" : "inline-block") : "none"; }, { fireImmediately: true }); this._fieldWrapper.appendChild(this._labelSpan); -- cgit v1.2.3-70-g09d2