From 7edce1af91621b7724e4763a5afabb4ab86d183c Mon Sep 17 00:00:00 2001 From: Bob Zeleznik Date: Sat, 14 Dec 2019 21:49:09 -0500 Subject: make %@ portal hyperlink creation create a link as well. --- src/client/views/nodes/DocumentView.tsx | 6 ------ src/client/views/nodes/FormattedTextBox.tsx | 1 + 2 files changed, 1 insertion(+), 6 deletions(-) (limited to 'src/client/views/nodes') diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx index b096d68fc..9f651a498 100644 --- a/src/client/views/nodes/DocumentView.tsx +++ b/src/client/views/nodes/DocumentView.tsx @@ -434,12 +434,6 @@ export class DocumentView extends DocComponent(Docu 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.isButton || this.Document.onClick ? "Remove Click Behavior" : "Follow Link", event: this.makeBtnClicked, icon: "concierge-bell" }); onClicks.push({ description: "Edit onClick Script", icon: "edit", event: (obj: any) => ScriptBox.EditButtonScript("On Button Clicked ...", this.props.Document, "onClick", obj.x, obj.y) }); - onClicks.push({ - description: "Edit onClick Foreach Doc Script", icon: "edit", event: (obj: any) => { - this.props.Document.collectionContext = this.props.ContainingCollectionDoc; - ScriptBox.EditButtonScript("Foreach Collection Doc (d) => ", this.props.Document, "onClick", obj.x, obj.y, "docList(this.collectionContext.data).map(d => {", "});\n"); - } - }); !existingOnClick && cm.addItem({ description: "OnClick...", subitems: onClicks, icon: "hand-point-right" }); const funcs: ContextMenuProps[] = []; diff --git a/src/client/views/nodes/FormattedTextBox.tsx b/src/client/views/nodes/FormattedTextBox.tsx index a298fd6af..e40c00e54 100644 --- a/src/client/views/nodes/FormattedTextBox.tsx +++ b/src/client/views/nodes/FormattedTextBox.tsx @@ -822,6 +822,7 @@ export class FormattedTextBox extends DocAnnotatableComponent<(FieldViewProps & clipboardTextSerializer: this.clipboardTextSerializer, handlePaste: this.handlePaste, }); + (this._editorView.state.schema as any).Document = this.props.Document; if (startup && this._editorView) { Doc.GetProto(doc).documentText = undefined; this._editorView.dispatch(this._editorView.state.tr.insertText(startup)); -- cgit v1.2.3-70-g09d2 From 877a6f481a06e2454ff9d8eabe43acb0e58a2676 Mon Sep 17 00:00:00 2001 From: Bob Zeleznik Date: Sun, 15 Dec 2019 10:38:23 -0500 Subject: writing selectedDocs to user doc to allow selection to be part of scripting --- src/client/util/DragManager.ts | 2 +- src/client/util/SelectionManager.ts | 3 +++ src/client/views/nodes/FormattedTextBox.tsx | 2 +- src/client/views/nodes/KeyValueBox.tsx | 3 ++- src/new_fields/Doc.ts | 12 +++++++++--- 5 files changed, 16 insertions(+), 6 deletions(-) (limited to 'src/client/views/nodes') diff --git a/src/client/util/DragManager.ts b/src/client/util/DragManager.ts index 2631a1e3c..df2f5fe3c 100644 --- a/src/client/util/DragManager.ts +++ b/src/client/util/DragManager.ts @@ -51,7 +51,7 @@ export function SetupDrag( e.stopPropagation(); if (e.shiftKey && CollectionDockingView.Instance) { e.persist(); - let dragDoc = await docFunc(); + const dragDoc = await docFunc(); dragDoc && CollectionDockingView.Instance.StartOtherDrag({ pageX: e.pageX, pageY: e.pageY, diff --git a/src/client/util/SelectionManager.ts b/src/client/util/SelectionManager.ts index e01216e0f..d9283de35 100644 --- a/src/client/util/SelectionManager.ts +++ b/src/client/util/SelectionManager.ts @@ -2,6 +2,8 @@ import { observable, action, runInAction, ObservableMap } from "mobx"; import { Doc } from "../../new_fields/Doc"; import { DocumentView } from "../views/nodes/DocumentView"; import { computedFn } from "mobx-utils"; +import { CurrentUserUtils } from "../../server/authentication/models/current_user_utils"; +import { List } from "../../new_fields/List"; export namespace SelectionManager { @@ -27,6 +29,7 @@ export namespace SelectionManager { manager.SelectedDocuments.clear(); manager.SelectedDocuments.set(docView, true); } + Doc.UserDoc().SelectedDocs = new List(SelectionManager.SelectedDocuments().map(dv => dv.props.Document)); } @action DeselectDoc(docView: DocumentView): void { diff --git a/src/client/views/nodes/FormattedTextBox.tsx b/src/client/views/nodes/FormattedTextBox.tsx index e40c00e54..3efbd434e 100644 --- a/src/client/views/nodes/FormattedTextBox.tsx +++ b/src/client/views/nodes/FormattedTextBox.tsx @@ -822,7 +822,7 @@ export class FormattedTextBox extends DocAnnotatableComponent<(FieldViewProps & clipboardTextSerializer: this.clipboardTextSerializer, handlePaste: this.handlePaste, }); - (this._editorView.state.schema as any).Document = this.props.Document; + this._editorView.state.schema.Document = this.props.Document; if (startup && this._editorView) { Doc.GetProto(doc).documentText = undefined; this._editorView.dispatch(this._editorView.state.tr.insertText(startup)); diff --git a/src/client/views/nodes/KeyValueBox.tsx b/src/client/views/nodes/KeyValueBox.tsx index 322d639dc..07d6d6f5e 100644 --- a/src/client/views/nodes/KeyValueBox.tsx +++ b/src/client/views/nodes/KeyValueBox.tsx @@ -57,7 +57,8 @@ export class KeyValueBox extends React.Component { value = eq ? value.substr(1) : value; const dubEq = value.startsWith(":=") ? "computed" : value.startsWith(";=") ? "script" : false; value = dubEq ? value.substr(2) : value; - const options: ScriptOptions = { addReturn: true, params: { this: "Doc" } }; + const editable = value.includes("selectedDocs"); // bcz: Argh TODO - need a UI mechanism for letting user know that a function can't be run read-only. e.g., selectedDocs() wants to cache its old value so it can't be run read-only + const options: ScriptOptions = { addReturn: true, params: { this: "Doc" }, editable: editable }; if (dubEq) options.typecheck = false; const script = CompileScript(value, options); if (!script.compiled) { diff --git a/src/new_fields/Doc.ts b/src/new_fields/Doc.ts index aa33d4c8b..a22b289bb 100644 --- a/src/new_fields/Doc.ts +++ b/src/new_fields/Doc.ts @@ -1,4 +1,4 @@ -import { observable, ObservableMap, runInAction, action } from "mobx"; +import { observable, ObservableMap, runInAction, action, untracked } from "mobx"; import { alias, map, serializable } from "serializr"; import { DocServer } from "../client/DocServer"; import { DocumentType } from "../client/documents/DocumentTypes"; @@ -474,7 +474,7 @@ export namespace Doc { return extension ? extension as Doc : undefined; } export function fieldExtensionDocSync(doc: Doc, fieldKey: string) { - return (doc[fieldKey + "_ext"] as Doc) || CreateDocumentExtensionForField(doc, fieldKey); + return (doc[fieldKey + "_ext"] as Doc) || CreateDocumentExtensionForField(doc, fieldKey); } export function CreateDocumentExtensionForField(doc: Doc, fieldKey: string) { @@ -753,4 +753,10 @@ Scripting.addGlobal(function aliasDocs(field: any) { return new List(field. Scripting.addGlobal(function docList(field: any) { return DocListCast(field); }); Scripting.addGlobal(function sameDocs(doc1: any, doc2: any) { return Doc.AreProtosEqual(doc1, doc2); }); Scripting.addGlobal(function undo() { return UndoManager.Undo(); }); -Scripting.addGlobal(function redo() { return UndoManager.Redo(); }); \ No newline at end of file +Scripting.addGlobal(function redo() { return UndoManager.Redo(); }); +Scripting.addGlobal(function selectedDocs(container: Doc, excludeCollections: boolean) { + let docs = DocListCast(Doc.UserDoc().SelectedDocs).filter(d => (!excludeCollections || !Cast(d.data, listSpec(Doc), null)) && d.type !== DocumentType.KVP && !Doc.AreProtosEqual(d, container)); + if (docs.length) untracked(() => container && (container.cachedSelection = new List(docs))); + else docs = untracked(() => DocListCast(container.cachedSelection)); + return new List(docs); +}); \ No newline at end of file -- cgit v1.2.3-70-g09d2 From 6683517a69f4806d026e7af85069f18b1f0a9d1f Mon Sep 17 00:00:00 2001 From: Bob Zeleznik Date: Sun, 15 Dec 2019 12:44:20 -0500 Subject: added _last_ for computedScripts to access last value of script --- src/client/util/RichTextSchema.tsx | 6 +++++- src/client/views/nodes/KeyValueBox.tsx | 3 +-- src/new_fields/Doc.ts | 5 ++--- src/new_fields/ScriptField.ts | 3 ++- 4 files changed, 10 insertions(+), 7 deletions(-) (limited to 'src/client/views/nodes') diff --git a/src/client/util/RichTextSchema.tsx b/src/client/util/RichTextSchema.tsx index 543f45731..7a048ed0d 100644 --- a/src/client/util/RichTextSchema.tsx +++ b/src/client/util/RichTextSchema.tsx @@ -741,7 +741,11 @@ export class DashDocView { self._dashDoc = dashDoc; dashDoc.hideSidebar = true; if (node.attrs.width !== dashDoc.width + "px" || node.attrs.height !== dashDoc.height + "px") { - view.dispatch(view.state.tr.setNodeMarkup(getPos(), null, { ...node.attrs, width: dashDoc.width + "px", height: dashDoc.height + "px" })); + try { // bcz: an exception will be thrown if two aliases are open at the same time when a doc view comment is made + view.dispatch(view.state.tr.setNodeMarkup(getPos(), null, { ...node.attrs, width: dashDoc.width + "px", height: dashDoc.height + "px" })); + } catch (e) { + console.log(e); + } } this._reactionDisposer && this._reactionDisposer(); this._reactionDisposer = reaction(() => dashDoc[HeightSym]() + dashDoc[WidthSym](), () => { diff --git a/src/client/views/nodes/KeyValueBox.tsx b/src/client/views/nodes/KeyValueBox.tsx index 07d6d6f5e..234a6a9d3 100644 --- a/src/client/views/nodes/KeyValueBox.tsx +++ b/src/client/views/nodes/KeyValueBox.tsx @@ -57,8 +57,7 @@ export class KeyValueBox extends React.Component { value = eq ? value.substr(1) : value; const dubEq = value.startsWith(":=") ? "computed" : value.startsWith(";=") ? "script" : false; value = dubEq ? value.substr(2) : value; - const editable = value.includes("selectedDocs"); // bcz: Argh TODO - need a UI mechanism for letting user know that a function can't be run read-only. e.g., selectedDocs() wants to cache its old value so it can't be run read-only - const options: ScriptOptions = { addReturn: true, params: { this: "Doc" }, editable: editable }; + const options: ScriptOptions = { addReturn: true, params: { this: "Doc", _last_: "any" }, editable: false }; if (dubEq) options.typecheck = false; const script = CompileScript(value, options); if (!script.compiled) { diff --git a/src/new_fields/Doc.ts b/src/new_fields/Doc.ts index a22b289bb..171f3fd2d 100644 --- a/src/new_fields/Doc.ts +++ b/src/new_fields/Doc.ts @@ -754,9 +754,8 @@ Scripting.addGlobal(function docList(field: any) { return DocListCast(field); }) Scripting.addGlobal(function sameDocs(doc1: any, doc2: any) { return Doc.AreProtosEqual(doc1, doc2); }); Scripting.addGlobal(function undo() { return UndoManager.Undo(); }); Scripting.addGlobal(function redo() { return UndoManager.Redo(); }); -Scripting.addGlobal(function selectedDocs(container: Doc, excludeCollections: boolean) { +Scripting.addGlobal(function selectedDocs(container: Doc, excludeCollections: boolean, prevValue: any) { let docs = DocListCast(Doc.UserDoc().SelectedDocs).filter(d => (!excludeCollections || !Cast(d.data, listSpec(Doc), null)) && d.type !== DocumentType.KVP && !Doc.AreProtosEqual(d, container)); - if (docs.length) untracked(() => container && (container.cachedSelection = new List(docs))); - else docs = untracked(() => DocListCast(container.cachedSelection)); + if (!docs.length) return prevValue; return new List(docs); }); \ No newline at end of file diff --git a/src/new_fields/ScriptField.ts b/src/new_fields/ScriptField.ts index 6b2723663..0cadb60ed 100644 --- a/src/new_fields/ScriptField.ts +++ b/src/new_fields/ScriptField.ts @@ -124,8 +124,9 @@ export class ScriptField extends ObjectField { @scriptingGlobal @Deserializable("computed", deserializeScript) export class ComputedField extends ScriptField { + _lastComputedResult: any; //TODO maybe add an observable cache based on what is passed in for doc, considering there shouldn't really be that many possible values for doc - value = computedFn((doc: Doc) => this.script.run({ this: doc }, console.log).result); + value = computedFn((doc: Doc) => this._lastComputedResult = this.script.run({ this: doc, _last_: this._lastComputedResult }, console.log).result); public static MakeScript(script: string, params: object = {}, ) { const compiled = ScriptField.CompileScript(script, params, false); return compiled.compiled ? new ComputedField(compiled) : undefined; -- cgit v1.2.3-70-g09d2 From 55823d0cc300f5cdd90ee34013bfdee93b5709e6 Mon Sep 17 00:00:00 2001 From: Bob Zeleznik Date: Sun, 15 Dec 2019 20:11:58 -0500 Subject: added a DocumentBox as a contentfitting container for another document. added a menu item for showing selected document. --- src/client/documents/DocumentTypes.ts | 3 +- src/client/documents/Documents.ts | 9 ++++ .../collectionFreeForm/CollectionFreeFormView.tsx | 2 +- .../views/nodes/ContentFittingDocumentView.tsx | 6 +-- src/client/views/nodes/DocumentBox.scss | 6 +++ src/client/views/nodes/DocumentBox.tsx | 55 ++++++++++++++++++++++ src/client/views/nodes/DocumentContentsView.tsx | 3 +- src/client/views/nodes/ImageBox.tsx | 1 - src/new_fields/ScriptField.ts | 2 +- .../authentication/models/current_user_utils.ts | 1 + 10 files changed, 80 insertions(+), 8 deletions(-) create mode 100644 src/client/views/nodes/DocumentBox.scss create mode 100644 src/client/views/nodes/DocumentBox.tsx (limited to 'src/client/views/nodes') diff --git a/src/client/documents/DocumentTypes.ts b/src/client/documents/DocumentTypes.ts index f6dd0c346..8f96b2fa6 100644 --- a/src/client/documents/DocumentTypes.ts +++ b/src/client/documents/DocumentTypes.ts @@ -25,5 +25,6 @@ export enum DocumentType { COLOR = "color", DOCULINK = "doculink", PDFANNO = "pdfanno", - INK = "ink" + INK = "ink", + DOCUMENT = "document" } \ No newline at end of file diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts index 4ba45ac30..50c51ace1 100644 --- a/src/client/documents/Documents.ts +++ b/src/client/documents/Documents.ts @@ -48,6 +48,7 @@ import { PresElementBox } from "../views/presentationview/PresElementBox"; import { QueryBox } from "../views/nodes/QueryBox"; import { ColorBox } from "../views/nodes/ColorBox"; import { DocuLinkBox } from "../views/nodes/DocuLinkBox"; +import { DocumentBox } from "../views/nodes/DocumentBox"; import { InkingStroke } from "../views/InkingStroke"; import { InkField } from "../../new_fields/InkField"; const requestImageSize = require('../util/request-image-size'); @@ -171,6 +172,10 @@ export namespace Docs { layout: { view: KeyValueBox, dataField: data }, options: { height: 150 } }], + [DocumentType.DOCUMENT, { + layout: { view: DocumentBox, dataField: data }, + options: { height: 250 } + }], [DocumentType.VID, { layout: { view: VideoBox, dataField: data }, options: { currentTimecode: 0 }, @@ -482,6 +487,10 @@ export namespace Docs { return InstanceFromProto(Prototypes.get(DocumentType.KVP), document, { title: document.title + ".kvp", ...options }); } + export function DocumentDocument(document?: Doc, options: DocumentOptions = {}) { + return InstanceFromProto(Prototypes.get(DocumentType.DOCUMENT), document, { title: document ? document.title + "" : "container", ...options }); + } + export function FreeformDocument(documents: Array, options: DocumentOptions, id?: string) { return InstanceFromProto(Prototypes.get(DocumentType.COL), new List(documents), { chromeStatus: "collapsed", schemaColumns: new List([new SchemaHeaderField("title", "#f1efeb")]), ...options, viewType: CollectionViewType.Freeform }, id); } diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx index 9bb6fa97e..0b18e9f25 100644 --- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx +++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx @@ -908,7 +908,7 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) {
- {!BoolCast(this.Document.LODdisable) && this.props.renderDepth > 0 && this.Document[WidthSym]() * this.Document[HeightSym]() / this.props.ScreenToLocalTransform().Scale < NumCast(this.Document.LODarea, 100000) ? this.placeholder : this.marqueeView} + {!BoolCast(this.Document.LODdisable) && !this.props.isAnnotationOverlay && this.props.renderDepth > 0 && this.Document[WidthSym]() * this.Document[HeightSym]() / this.props.ScreenToLocalTransform().Scale < NumCast(this.Document.LODarea, 100000) ? this.placeholder : this.marqueeView}
; } diff --git a/src/client/views/nodes/ContentFittingDocumentView.tsx b/src/client/views/nodes/ContentFittingDocumentView.tsx index 5e3306a11..2565fd932 100644 --- a/src/client/views/nodes/ContentFittingDocumentView.tsx +++ b/src/client/views/nodes/ContentFittingDocumentView.tsx @@ -31,9 +31,9 @@ interface ContentFittingDocumentViewProps { CollectionDoc?: Doc; onClick?: ScriptField; getTransform: () => Transform; - addDocument: (document: Doc) => boolean; - moveDocument: (document: Doc, target: Doc | undefined, addDoc: ((doc: Doc) => boolean)) => boolean; - removeDocument: (document: Doc) => boolean; + addDocument?: (document: Doc) => boolean; + moveDocument?: (document: Doc, target: Doc | undefined, addDoc: ((doc: Doc) => boolean)) => boolean; + removeDocument?: (document: Doc) => boolean; active: (outsideReaction: boolean) => boolean; whenActiveChanged: (isActive: boolean) => void; addDocTab: (document: Doc, dataDoc: Doc | undefined, where: string) => boolean; diff --git a/src/client/views/nodes/DocumentBox.scss b/src/client/views/nodes/DocumentBox.scss new file mode 100644 index 000000000..6a2f98166 --- /dev/null +++ b/src/client/views/nodes/DocumentBox.scss @@ -0,0 +1,6 @@ +.documentBox-container { + width: 100%; + height: 100%; + pointer-events: all; + background: gray; +} \ No newline at end of file diff --git a/src/client/views/nodes/DocumentBox.tsx b/src/client/views/nodes/DocumentBox.tsx new file mode 100644 index 000000000..2f2cba485 --- /dev/null +++ b/src/client/views/nodes/DocumentBox.tsx @@ -0,0 +1,55 @@ +import { observer } from "mobx-react"; +import { Doc } from "../../../new_fields/Doc"; +import { documentSchema } from "../../../new_fields/documentSchemas"; +import { makeInterface } from "../../../new_fields/Schema"; +import { ComputedField } from "../../../new_fields/ScriptField"; +import { emptyFunction, emptyPath } from "../../../Utils"; +import { ContextMenu } from "../ContextMenu"; +import { ContextMenuProps } from "../ContextMenuItem"; +import { DocComponent } from "../DocComponent"; +import { ContentFittingDocumentView } from "./ContentFittingDocumentView"; +import "./DocumentBox.scss"; +import { FieldView, FieldViewProps } from "./FieldView"; +import React = require("react"); + +type DocBoxSchema = makeInterface<[typeof documentSchema]>; +const DocBoxDocument = makeInterface(documentSchema); + +@observer +export class DocumentBox extends DocComponent(DocBoxDocument) { + public static LayoutString(fieldKey: string) { return FieldView.LayoutString(DocumentBox, fieldKey); } + + + specificContextMenu = (e: React.MouseEvent): void => { + const funcs: ContextMenuProps[] = []; + funcs.push({ description: "Auto Show Selected", event: () => Doc.GetProto(this.props.Document).data = ComputedField.MakeFunction("selectedDocs(this,true,_last_)?.[0]"), icon: "expand-arrows-alt" }); + + ContextMenu.Instance.addItem({ description: "DocumentBox Funcs...", subitems: funcs, icon: "asterisk" }); + } + render() { + const containedDoc = this.props.Document[this.props.fieldKey] as Doc; + return
+ {!containedDoc ? (null) : } +
; + } +} diff --git a/src/client/views/nodes/DocumentContentsView.tsx b/src/client/views/nodes/DocumentContentsView.tsx index 1bbc82119..8f6bfc8e1 100644 --- a/src/client/views/nodes/DocumentContentsView.tsx +++ b/src/client/views/nodes/DocumentContentsView.tsx @@ -14,6 +14,7 @@ import { LinkFollowBox } from "../linking/LinkFollowBox"; import { YoutubeBox } from "./../../apis/youtube/YoutubeBox"; import { AudioBox } from "./AudioBox"; import { ButtonBox } from "./ButtonBox"; +import { DocumentBox } from "./DocumentBox"; import { DocumentViewProps } from "./DocumentView"; import "./DocumentView.scss"; import { FontIconBox } from "./FontIconBox"; @@ -102,7 +103,7 @@ export class DocumentContentsView extends React.Component Date: Sun, 15 Dec 2019 21:47:34 -0500 Subject: fixed auto show seleted function --- src/client/views/nodes/DocumentBox.tsx | 2 +- src/new_fields/Doc.ts | 3 +-- 2 files changed, 2 insertions(+), 3 deletions(-) (limited to 'src/client/views/nodes') diff --git a/src/client/views/nodes/DocumentBox.tsx b/src/client/views/nodes/DocumentBox.tsx index 2f2cba485..b9a97b42d 100644 --- a/src/client/views/nodes/DocumentBox.tsx +++ b/src/client/views/nodes/DocumentBox.tsx @@ -22,7 +22,7 @@ export class DocumentBox extends DocComponent(DocB specificContextMenu = (e: React.MouseEvent): void => { const funcs: ContextMenuProps[] = []; - funcs.push({ description: "Auto Show Selected", event: () => Doc.GetProto(this.props.Document).data = ComputedField.MakeFunction("selectedDocs(this,true,_last_)?.[0]"), icon: "expand-arrows-alt" }); + funcs.push({ description: "Auto Show Selected", event: () => Doc.GetProto(this.props.Document).data = ComputedField.MakeFunction("selectedDocs(this,true,[_last_])?.[0]"), icon: "expand-arrows-alt" }); ContextMenu.Instance.addItem({ description: "DocumentBox Funcs...", subitems: funcs, icon: "asterisk" }); } diff --git a/src/new_fields/Doc.ts b/src/new_fields/Doc.ts index 171f3fd2d..c3a6a1658 100644 --- a/src/new_fields/Doc.ts +++ b/src/new_fields/Doc.ts @@ -756,6 +756,5 @@ Scripting.addGlobal(function undo() { return UndoManager.Undo(); }); Scripting.addGlobal(function redo() { return UndoManager.Redo(); }); Scripting.addGlobal(function selectedDocs(container: Doc, excludeCollections: boolean, prevValue: any) { let docs = DocListCast(Doc.UserDoc().SelectedDocs).filter(d => (!excludeCollections || !Cast(d.data, listSpec(Doc), null)) && d.type !== DocumentType.KVP && !Doc.AreProtosEqual(d, container)); - if (!docs.length) return prevValue; - return new List(docs); + return docs.length ? new List(docs) : prevValue; }); \ No newline at end of file -- cgit v1.2.3-70-g09d2 From 01aca20caca1f8736fd7035b8cda35e7c415aa2b Mon Sep 17 00:00:00 2001 From: Bob Zeleznik Date: Mon, 16 Dec 2019 00:38:59 -0500 Subject: added onclick option for selecting first link target. changed contentFittingDocView to center vertically as well as horizontally --- src/client/util/SelectionManager.ts | 5 ++++- src/client/views/nodes/ContentFittingDocumentView.scss | 5 +++-- src/client/views/nodes/ContentFittingDocumentView.tsx | 18 +++++++++++------- src/client/views/nodes/DocumentView.tsx | 15 +++++++++++++++ src/new_fields/Doc.ts | 4 +++- 5 files changed, 36 insertions(+), 11 deletions(-) (limited to 'src/client/views/nodes') diff --git a/src/client/util/SelectionManager.ts b/src/client/util/SelectionManager.ts index d9283de35..cb7a69295 100644 --- a/src/client/util/SelectionManager.ts +++ b/src/client/util/SelectionManager.ts @@ -2,8 +2,8 @@ import { observable, action, runInAction, ObservableMap } from "mobx"; import { Doc } from "../../new_fields/Doc"; import { DocumentView } from "../views/nodes/DocumentView"; import { computedFn } from "mobx-utils"; -import { CurrentUserUtils } from "../../server/authentication/models/current_user_utils"; import { List } from "../../new_fields/List"; +import { Scripting } from "./Scripting"; export namespace SelectionManager { @@ -81,3 +81,6 @@ export namespace SelectionManager { return Array.from(manager.SelectedDocuments.keys()); } } + +Scripting.addGlobal(function selectDoc(doc: any) { Doc.UserDoc().SelectedDocs = new List([doc]); }); + diff --git a/src/client/views/nodes/ContentFittingDocumentView.scss b/src/client/views/nodes/ContentFittingDocumentView.scss index 796e67269..2801af441 100644 --- a/src/client/views/nodes/ContentFittingDocumentView.scss +++ b/src/client/views/nodes/ContentFittingDocumentView.scss @@ -2,10 +2,11 @@ .contentFittingDocumentView { position: relative; - height: auto !important; + display: flex; + align-items: center; .contentFittingDocumentView-previewDoc { - position: absolute; + position: relative; display: inline; } diff --git a/src/client/views/nodes/ContentFittingDocumentView.tsx b/src/client/views/nodes/ContentFittingDocumentView.tsx index 2565fd932..e15790c9d 100644 --- a/src/client/views/nodes/ContentFittingDocumentView.tsx +++ b/src/client/views/nodes/ContentFittingDocumentView.tsx @@ -47,8 +47,8 @@ interface ContentFittingDocumentViewProps { export class ContentFittingDocumentView extends React.Component{ public get displayName() { return "DocumentView(" + this.props.Document?.title + ")"; } // this makes mobx trace() statements more descriptive private get layoutDoc() { return this.props.Document && Doc.Layout(this.props.Document); } - private get nativeWidth() { return NumCast(this.layoutDoc!.nativeWidth, this.props.PanelWidth()); } - private get nativeHeight() { return NumCast(this.layoutDoc!.nativeHeight, this.props.PanelHeight()); } + private get nativeWidth() { return NumCast(this.layoutDoc?.nativeWidth, this.props.PanelWidth()); } + private get nativeHeight() { return NumCast(this.layoutDoc?.nativeHeight, this.props.PanelHeight()); } private contentScaling = () => { const wscale = this.props.PanelWidth() / (this.nativeWidth ? this.nativeWidth : this.props.PanelWidth()); if (wscale * this.nativeHeight > this.props.PanelHeight()) { @@ -73,21 +73,25 @@ export class ContentFittingDocumentView extends React.Component this.nativeWidth && (!this.props.Document || !this.props.Document.fitWidth) ? this.nativeWidth * this.contentScaling() : this.props.PanelWidth(); private PanelHeight = () => this.nativeHeight && (!this.props.Document || !this.props.Document.fitWidth) ? this.nativeHeight * this.contentScaling() : this.props.PanelHeight(); - private getTransform = () => this.props.getTransform().translate(-this.centeringOffset, 0).scale(1 / this.contentScaling()); + private getTransform = () => this.props.getTransform().translate(-this.centeringOffset, -this.centeringYOffset).scale(1 / this.contentScaling()); private get centeringOffset() { return this.nativeWidth && (!this.props.Document || !this.props.Document.fitWidth) ? (this.props.PanelWidth() - this.nativeWidth * this.contentScaling()) / 2 : 0; } + private get centeringYOffset() { return Math.abs(this.centeringOffset) < 0.001 ? (this.props.PanelHeight() - this.nativeHeight * this.contentScaling()) / 2 : 0; } - @computed get borderRounding() { return StrCast(this.props.Document!.borderRounding); } + @computed get borderRounding() { return StrCast(this.props.Document?.borderRounding); } render() { TraceMobx(); - return (
+ return (
0.001 ? "auto" : this.props.PanelWidth(), + height: Math.abs(this.centeringOffset) > 0.0001 ? "auto" : this.props.PanelHeight() + }}> {!this.props.Document || !this.props.PanelWidth ? (null) : (
0.001 ? `${100 * this.nativeHeight / this.nativeWidth * this.props.PanelWidth() / this.props.PanelHeight()}%` : this.props.PanelHeight(), + width: Math.abs(this.centeringOffset) > 0.001 ? `${100 * (this.props.PanelWidth() - this.centeringOffset * 2) / this.props.PanelWidth()}%` : this.props.PanelWidth() }}> (Docu this.onClickHandler.script.run({ this: this.Document.isTemplateField && this.props.DataDoc ? this.props.DataDoc : this.props.Document }, console.log); } else if (this.Document.type === DocumentType.BUTTON) { ScriptBox.EditButtonScript("On Button Clicked ...", this.props.Document, "onClick", e.clientX, e.clientY); + } else if (this.props.Document.isButton === "Selector") { // this should be moved to an OnClick script + this.Document.links?.[0] instanceof Doc && (Doc.UserDoc().SelectedDocs = new List([Doc.LinkOtherAnchor(this.Document.links[0]!, this.props.Document)])); } else if (this.Document.isButton) { SelectionManager.SelectDoc(this, e.ctrlKey); // don't think this should happen if a button action is actually triggered. this.buttonClick(e.altKey, e.ctrlKey); @@ -315,6 +318,17 @@ export class DocumentView extends DocComponent(Docu } } + @undoBatch + makeSelBtnClicked = (): void => { + if (this.Document.isButton || this.Document.onClick || this.Document.ignoreClick) { + this.Document.isButton = false; + this.Document.ignoreClick = false; + this.Document.onClick = undefined; + } else { + this.props.Document.isButton = "Selector"; + } + } + @undoBatch @action drop = async (e: Event, de: DragManager.DropEvent) => { @@ -433,6 +447,7 @@ export class DocumentView extends DocComponent(Docu onClicks.push({ description: "Toggle Detail", event: () => this.Document.onClick = ScriptField.MakeScript("toggleDetail(this)"), 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.isButton || this.Document.onClick ? "Remove Click Behavior" : "Follow Link", event: this.makeBtnClicked, icon: "concierge-bell" }); + onClicks.push({ description: this.props.Document.isButton ? "Remove Select Link Behavior" : "Select Link", event: this.makeSelBtnClicked, icon: "concierge-bell" }); onClicks.push({ description: "Edit onClick Script", icon: "edit", event: (obj: any) => ScriptBox.EditButtonScript("On Button Clicked ...", this.props.Document, "onClick", obj.x, obj.y) }); !existingOnClick && cm.addItem({ description: "OnClick...", subitems: onClicks, icon: "hand-point-right" }); diff --git a/src/new_fields/Doc.ts b/src/new_fields/Doc.ts index c3a6a1658..b8f11c8c8 100644 --- a/src/new_fields/Doc.ts +++ b/src/new_fields/Doc.ts @@ -687,7 +687,9 @@ export namespace Doc { } + export function LinkOtherAnchor(linkDoc: Doc, anchorDoc: Doc) { return Doc.AreProtosEqual(anchorDoc, Cast(linkDoc.anchor1, Doc) as Doc) ? Cast(linkDoc.anchor2, Doc) as Doc : Cast(linkDoc.anchor1, Doc) as Doc; } export function LinkEndpoint(linkDoc: Doc, anchorDoc: Doc) { return Doc.AreProtosEqual(anchorDoc, Cast(linkDoc.anchor1, Doc) as Doc) ? "layoutKey1" : "layoutKey2"; } + export function linkFollowUnhighlight() { Doc.UnhighlightAll(); document.removeEventListener("pointerdown", linkFollowUnhighlight); @@ -755,6 +757,6 @@ Scripting.addGlobal(function sameDocs(doc1: any, doc2: any) { return Doc.AreProt Scripting.addGlobal(function undo() { return UndoManager.Undo(); }); Scripting.addGlobal(function redo() { return UndoManager.Redo(); }); Scripting.addGlobal(function selectedDocs(container: Doc, excludeCollections: boolean, prevValue: any) { - let docs = DocListCast(Doc.UserDoc().SelectedDocs).filter(d => (!excludeCollections || !Cast(d.data, listSpec(Doc), null)) && d.type !== DocumentType.KVP && !Doc.AreProtosEqual(d, container)); + const docs = DocListCast(Doc.UserDoc().SelectedDocs).filter(d => !Doc.AreProtosEqual(d, container) && (!excludeCollections || !Cast(d.data, listSpec(Doc), null)) && d.type !== DocumentType.KVP); return docs.length ? new List(docs) : prevValue; }); \ No newline at end of file -- cgit v1.2.3-70-g09d2 From 001cea83f6c57914e0e76a75a94f3e06e542a419 Mon Sep 17 00:00:00 2001 From: Bob Zeleznik Date: Mon, 16 Dec 2019 01:01:09 -0500 Subject: from last --- src/client/views/nodes/DocumentView.tsx | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src/client/views/nodes') diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx index 59e68fc4c..18885f272 100644 --- a/src/client/views/nodes/DocumentView.tsx +++ b/src/client/views/nodes/DocumentView.tsx @@ -44,6 +44,7 @@ import { InkingControl } from '../InkingControl'; import { InkTool } from '../../../new_fields/InkField'; import { TraceMobx } from '../../../new_fields/util'; import { List } from '../../../new_fields/List'; +import { FormattedTextBoxComment } from './FormattedTextBoxComment'; library.add(fa.faEdit, fa.faTrash, fa.faShare, fa.faDownload, fa.faExpandArrowsAlt, fa.faCompressArrowsAlt, fa.faLayerGroup, fa.faExternalLinkAlt, fa.faAlignCenter, fa.faCaretSquareRight, fa.faSquare, fa.faConciergeBell, fa.faWindowRestore, fa.faFolder, fa.faMapPin, fa.faLink, fa.faFingerprint, fa.faCrosshairs, fa.faDesktop, fa.faUnlock, fa.faLock, fa.faLaptopCode, fa.faMale, @@ -172,6 +173,7 @@ export class DocumentView extends DocComponent(Docu } else if (this.Document.type === DocumentType.BUTTON) { ScriptBox.EditButtonScript("On Button Clicked ...", this.props.Document, "onClick", e.clientX, e.clientY); } else if (this.props.Document.isButton === "Selector") { // this should be moved to an OnClick script + FormattedTextBoxComment.Hide(); this.Document.links?.[0] instanceof Doc && (Doc.UserDoc().SelectedDocs = new List([Doc.LinkOtherAnchor(this.Document.links[0]!, this.props.Document)])); } else if (this.Document.isButton) { SelectionManager.SelectDoc(this, e.ctrlKey); // don't think this should happen if a button action is actually triggered. -- cgit v1.2.3-70-g09d2 From 4d4a1438ac87d36c01b8ca084564cc7ad1cd3b0d Mon Sep 17 00:00:00 2001 From: bob Date: Mon, 16 Dec 2019 11:42:32 -0500 Subject: more exception fixes. added alt-f for floating docs. --- src/client/views/TemplateMenu.tsx | 19 +++------------- src/client/views/Templates.tsx | 2 +- src/client/views/nodes/DocumentView.tsx | 40 +++++++++++++++++++++++++-------- 3 files changed, 35 insertions(+), 26 deletions(-) (limited to 'src/client/views/nodes') diff --git a/src/client/views/TemplateMenu.tsx b/src/client/views/TemplateMenu.tsx index 598bcd56d..4609d5211 100644 --- a/src/client/views/TemplateMenu.tsx +++ b/src/client/views/TemplateMenu.tsx @@ -1,6 +1,5 @@ import { action, observable } from "mobx"; import { observer } from "mobx-react"; -import { DocumentManager } from "../util/DocumentManager"; import { DragManager } from "../util/DragManager"; import { SelectionManager } from "../util/SelectionManager"; import { undoBatch } from "../util/UndoManager"; @@ -10,7 +9,6 @@ import { Template, Templates } from "./Templates"; import React = require("react"); import { Doc } from "../../new_fields/Doc"; import { StrCast } from "../../new_fields/Types"; -import { emptyFunction } from "../../Utils"; const higflyout = require("@hig/flyout"); export const { anchorPoints } = higflyout; export const Flyout = higflyout.default; @@ -62,23 +60,12 @@ export class TemplateMenu extends React.Component { toggleFloat = (e: React.ChangeEvent): void => { SelectionManager.DeselectAll(); const topDocView = this.props.docs[0]; - const topDoc = topDocView.props.Document; const ex = e.target.getBoundingClientRect().left; const ey = e.target.getBoundingClientRect().top; - const de = new DragManager.DocumentDragData([topDoc]); - de.dragDivName = topDocView.props.dragDivName; - de.moveDocument = topDocView.props.moveDocument; - undoBatch(action(() => topDoc.z = topDoc.z ? 0 : 1))(); - setTimeout(() => { - const newDocView = DocumentManager.Instance.getDocumentView(topDoc); - if (newDocView) { - const contentDiv = newDocView.ContentDiv!; - const xf = contentDiv.getBoundingClientRect(); - DragManager.StartDocumentDrag([contentDiv], de, ex, ey, { offsetX: ex - xf.left, offsetY: ey - xf.top, hideSource: true }); - } - }, 0); + DocumentView.FloatDoc(topDocView, ex, ey); } + @undoBatch @action toggleTemplate = (event: React.ChangeEvent, template: Template): void => { @@ -155,7 +142,7 @@ export class TemplateMenu extends React.Component { const templateMenu: Array = []; this.props.templates.forEach((checked, template) => templateMenu.push()); - templateMenu.push(); + templateMenu.push(); templateMenu.push(); templateMenu.push(); return ( diff --git a/src/client/views/Templates.tsx b/src/client/views/Templates.tsx index ef78b60d4..f686bc23d 100644 --- a/src/client/views/Templates.tsx +++ b/src/client/views/Templates.tsx @@ -47,7 +47,7 @@ export namespace Templates {
` ); - export const Title = new Template("Title", TemplatePosition.InnerTop, + export const Title = new Template("Title (alt-t)", TemplatePosition.InnerTop, `
{props.Document.title} diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx index 18885f272..9688c6ad4 100644 --- a/src/client/views/nodes/DocumentView.tsx +++ b/src/client/views/nodes/DocumentView.tsx @@ -137,20 +137,42 @@ export class DocumentView extends DocComponent(Docu } } + public static FloatDoc(topDocView:DocumentView, x:number, y:number) { + const topDoc = topDocView.props.Document; + const de = new DragManager.DocumentDragData([topDoc]); + de.dragDivName = topDocView.props.dragDivName; + de.moveDocument = topDocView.props.moveDocument; + undoBatch(action(() => topDoc.z = topDoc.z ? 0 : 1))(); + setTimeout(() => { + const newDocView = DocumentManager.Instance.getDocumentView(topDoc); + if (newDocView) { + const contentDiv = newDocView.ContentDiv!; + const xf = contentDiv.getBoundingClientRect(); + DragManager.StartDocumentDrag([contentDiv], de, x, y, { offsetX: x - xf.left, offsetY: y - xf.top, hideSource: true }); + } + }, 0); + } + onKeyDown = (e: React.KeyboardEvent) => { - if (e.altKey && (e.key === "†" || e.key === "t") && !(e.nativeEvent as any).StopPropagationForReal) { + if (e.altKey && !(e.nativeEvent as any).StopPropagationForReal) { (e.nativeEvent as any).StopPropagationForReal = true; // e.stopPropagation() doesn't seem to work... e.stopPropagation(); e.preventDefault(); - if (!StrCast(this.Document.showTitle)) this.Document.showTitle = "title"; - if (!this._titleRef.current) setTimeout(() => this._titleRef.current?.setIsFocused(true), 0); - else if (!this._titleRef.current.setIsFocused(true)) { // if focus didn't change, focus on interior text... - { - this._titleRef.current?.setIsFocused(false); - const any = (this._mainCont.current?.getElementsByClassName("ProseMirror")?.[0] as any); - any.keeplocation = true; - any?.focus(); + if (e.key === "†" || e.key === "t") { + if (!StrCast(this.Document.showTitle)) this.Document.showTitle = "title"; + if (!this._titleRef.current) setTimeout(() => this._titleRef.current?.setIsFocused(true), 0); + else if (!this._titleRef.current.setIsFocused(true)) { // if focus didn't change, focus on interior text... + { + this._titleRef.current?.setIsFocused(false); + const any = (this._mainCont.current?.getElementsByClassName("ProseMirror")?.[0] as any); + any.keeplocation = true; + any?.focus(); + } } + } else if (e.key === "f") { + const ex = (e.nativeEvent.target! as any).getBoundingClientRect().left; + const ey = (e.nativeEvent.target!as any).getBoundingClientRect().top; + DocumentView.FloatDoc(this, ex, ey); } } } -- cgit v1.2.3-70-g09d2 From a68b3a82c7fd430119254cd8721bd4804e280ef3 Mon Sep 17 00:00:00 2001 From: Bob Zeleznik Date: Tue, 17 Dec 2019 11:25:47 -0500 Subject: made documentbox more usable with borders, fwd/back/lock. and annotation filtering. --- .../collectionFreeForm/CollectionFreeFormView.tsx | 5 +- src/client/views/nodes/DocumentBox.scss | 3 + src/client/views/nodes/DocumentBox.tsx | 69 +++++++++++++++++++--- src/client/views/nodes/KeyValuePair.tsx | 1 - src/new_fields/Doc.ts | 2 +- 5 files changed, 68 insertions(+), 12 deletions(-) (limited to 'src/client/views/nodes') diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx index 6653639de..ddd4fea56 100644 --- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx +++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx @@ -911,7 +911,10 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) {
- {!BoolCast(this.Document.LODdisable) && !this.props.isAnnotationOverlay && this.props.renderDepth > 0 && this.Document[WidthSym]() * this.Document[HeightSym]() / this.props.ScreenToLocalTransform().Scale / this.props.ScreenToLocalTransform().Scale < NumCast(this.Document.LODarea, 100000) ? this.placeholder : this.marqueeView} + {!BoolCast(this.Document.LODdisable) && !this.props.isAnnotationOverlay && this.props.renderDepth > 0 && + this.Document[WidthSym]() * this.Document[HeightSym]() / this.props.ScreenToLocalTransform().Scale / this.props.ScreenToLocalTransform().Scale < + NumCast(this.Document.LODarea, 100000) ? + this.placeholder : this.marqueeView}
; } diff --git a/src/client/views/nodes/DocumentBox.scss b/src/client/views/nodes/DocumentBox.scss index 6a2f98166..c70b324de 100644 --- a/src/client/views/nodes/DocumentBox.scss +++ b/src/client/views/nodes/DocumentBox.scss @@ -3,4 +3,7 @@ height: 100%; pointer-events: all; background: gray; + border: gray solid 15px; + border-top: #aaaaa3 inset 15px; + border-bottom: #aaaaa3 outset 15px; } \ No newline at end of file diff --git a/src/client/views/nodes/DocumentBox.tsx b/src/client/views/nodes/DocumentBox.tsx index b9a97b42d..e23b7a38b 100644 --- a/src/client/views/nodes/DocumentBox.tsx +++ b/src/client/views/nodes/DocumentBox.tsx @@ -1,8 +1,11 @@ +import { IReactionDisposer, reaction } from "mobx"; import { observer } from "mobx-react"; -import { Doc } from "../../../new_fields/Doc"; +import { Doc, Field } from "../../../new_fields/Doc"; import { documentSchema } from "../../../new_fields/documentSchemas"; +import { List } from "../../../new_fields/List"; import { makeInterface } from "../../../new_fields/Schema"; import { ComputedField } from "../../../new_fields/ScriptField"; +import { Cast, StrCast } from "../../../new_fields/Types"; import { emptyFunction, emptyPath } from "../../../Utils"; import { ContextMenu } from "../ContextMenu"; import { ContextMenuProps } from "../ContextMenuItem"; @@ -18,17 +21,65 @@ const DocBoxDocument = makeInterface(documentSchema); @observer export class DocumentBox extends DocComponent(DocBoxDocument) { public static LayoutString(fieldKey: string) { return FieldView.LayoutString(DocumentBox, fieldKey); } - - + _prevSelectionDisposer: IReactionDisposer | undefined; + _selections: Doc[] = []; + _curSelection = -1; + componentDidMount() { + this._prevSelectionDisposer = reaction(() => Cast(this.props.Document[this.props.fieldKey], Doc) as Doc, (data) => { + if (data && !this._selections.includes(data)) { + this._selections.length = ++this._curSelection; + this._selections.push(data); + } + }); + } specificContextMenu = (e: React.MouseEvent): void => { const funcs: ContextMenuProps[] = []; - funcs.push({ description: "Auto Show Selected", event: () => Doc.GetProto(this.props.Document).data = ComputedField.MakeFunction("selectedDocs(this,true,[_last_])?.[0]"), icon: "expand-arrows-alt" }); + funcs.push({ description: "Auto Show Selected", event: () => this.showSelection, icon: "expand-arrows-alt" }); + funcs.push({ description: "Prev Selection", event: () => this.prevSelection, icon: "expand-arrows-alt" }); + funcs.push({ description: "Lock Selection", event: () => this.lockSelection, icon: "expand-arrows-alt" }); ContextMenu.Instance.addItem({ description: "DocumentBox Funcs...", subitems: funcs, icon: "asterisk" }); } + lockSelection = () => { + Doc.GetProto(this.props.Document)[this.props.fieldKey] = this.props.Document[this.props.fieldKey]; + } + showSelection = () => { + Doc.GetProto(this.props.Document)[this.props.fieldKey] = ComputedField.MakeFunction("selectedDocs(this,true,[_last_])?.[0]"); + } + toggleLockSelection = () => { + const kvpstring = Field.toKeyValueString(this.props.Document, this.props.fieldKey); + (kvpstring.startsWith("=") || kvpstring.startsWith(":=")) ? this.lockSelection() : this.showSelection(); + } + prevSelection = () => { + if (this._curSelection > 0) { + Doc.UserDoc().SelectedDocs = new List([this._selections[--this._curSelection]]); + } + } + nextSelection = () => { + if (this._curSelection < this._selections.length - 1 && this._selections.length) { + Doc.UserDoc().SelectedDocs = new List([this._selections[++this._curSelection]]); + } + } + onPointerDown = (e: React.PointerEvent) => { + if (e.button === 0 && !e.altKey) { + e.stopPropagation(); + } + } + onClick = (e: React.MouseEvent) => { + if (this._contRef.current!.getBoundingClientRect().top + 15 > e.clientY) this.toggleLockSelection(); + else { + if (this._contRef.current!.getBoundingClientRect().left + 15 > e.clientX) this.prevSelection(); + if (this._contRef.current!.getBoundingClientRect().right - 15 < e.clientX) this.nextSelection(); + } + } + _contRef = React.createRef(); + pwidth = () => this.props.PanelWidth() - 30; + pheight = () => this.props.PanelHeight() - 30; + getTransform = () => this.props.ScreenToLocalTransform().translate(-15, -15); render() { const containedDoc = this.props.Document[this.props.fieldKey] as Doc; - return
+ return
{!containedDoc ? (null) : (DocB ruleProvider={this.props.ruleProvider} addDocTab={this.props.addDocTab} pinToPres={this.props.pinToPres} - getTransform={this.props.ScreenToLocalTransform} - renderDepth={this.props.renderDepth - 1} - PanelWidth={this.props.PanelWidth} - PanelHeight={this.props.PanelHeight} + getTransform={this.getTransform} + renderDepth={this.props.renderDepth + 1} + PanelWidth={this.pwidth} + PanelHeight={this.pheight} focus={this.props.focus} active={this.props.active} whenActiveChanged={this.props.whenActiveChanged} diff --git a/src/client/views/nodes/KeyValuePair.tsx b/src/client/views/nodes/KeyValuePair.tsx index 3e253b83a..91f8bb3b0 100644 --- a/src/client/views/nodes/KeyValuePair.tsx +++ b/src/client/views/nodes/KeyValuePair.tsx @@ -5,7 +5,6 @@ import { emptyFunction, returnFalse, returnOne, returnZero } from '../../../Util import { Docs } from '../../documents/Documents'; import { Transform } from '../../util/Transform'; import { undoBatch } from '../../util/UndoManager'; -import { CollectionDockingView } from '../collections/CollectionDockingView'; import { ContextMenu } from '../ContextMenu'; import { EditableView } from "../EditableView"; import { FieldView, FieldViewProps } from './FieldView'; diff --git a/src/new_fields/Doc.ts b/src/new_fields/Doc.ts index b8f11c8c8..168e42b77 100644 --- a/src/new_fields/Doc.ts +++ b/src/new_fields/Doc.ts @@ -757,6 +757,6 @@ Scripting.addGlobal(function sameDocs(doc1: any, doc2: any) { return Doc.AreProt Scripting.addGlobal(function undo() { return UndoManager.Undo(); }); Scripting.addGlobal(function redo() { return UndoManager.Redo(); }); Scripting.addGlobal(function selectedDocs(container: Doc, excludeCollections: boolean, prevValue: any) { - const docs = DocListCast(Doc.UserDoc().SelectedDocs).filter(d => !Doc.AreProtosEqual(d, container) && (!excludeCollections || !Cast(d.data, listSpec(Doc), null)) && d.type !== DocumentType.KVP); + const docs = DocListCast(Doc.UserDoc().SelectedDocs).filter(d => !Doc.AreProtosEqual(d, container) && !d.annotationOn && d.type !== DocumentType.DOCUMENT && d.type !== DocumentType.KVP && (!excludeCollections || !Cast(d.data, listSpec(Doc), null))); return docs.length ? new List(docs) : prevValue; }); \ No newline at end of file -- cgit v1.2.3-70-g09d2 From 96ada41d4c3c411be63bd656da65bba7894a4224 Mon Sep 17 00:00:00 2001 From: Bob Zeleznik Date: Tue, 17 Dec 2019 18:21:22 -0500 Subject: fixed up interactions with documentBox contents. --- src/client/views/DocComponent.tsx | 1 + .../collectionFreeForm/CollectionFreeFormView.tsx | 2 +- .../views/nodes/ContentFittingDocumentView.tsx | 2 +- src/client/views/nodes/DocumentBox.scss | 12 ++++++--- src/client/views/nodes/DocumentBox.tsx | 29 +++++++++++++--------- src/client/views/nodes/DocumentView.tsx | 4 +-- src/client/views/nodes/FormattedTextBox.tsx | 2 +- 7 files changed, 32 insertions(+), 20 deletions(-) (limited to 'src/client/views/nodes') diff --git a/src/client/views/DocComponent.tsx b/src/client/views/DocComponent.tsx index 7fbad4638..7c8e130b5 100644 --- a/src/client/views/DocComponent.tsx +++ b/src/client/views/DocComponent.tsx @@ -47,6 +47,7 @@ interface DocAnnotatableProps { Document: Doc; DataDoc?: Doc; fieldKey: string; + active: () => boolean; whenActiveChanged: (isActive: boolean) => void; isSelected: (outsideReaction?: boolean) => boolean; renderDepth: number; diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx index ddd4fea56..22983e730 100644 --- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx +++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx @@ -911,7 +911,7 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) {
- {!BoolCast(this.Document.LODdisable) && !this.props.isAnnotationOverlay && this.props.renderDepth > 0 && + {!BoolCast(this.Document.LODdisable) && !this.props.isAnnotationOverlay && this.props.renderDepth > 0 && this.props.CollectionView && this.Document[WidthSym]() * this.Document[HeightSym]() / this.props.ScreenToLocalTransform().Scale / this.props.ScreenToLocalTransform().Scale < NumCast(this.Document.LODarea, 100000) ? this.placeholder : this.marqueeView} diff --git a/src/client/views/nodes/ContentFittingDocumentView.tsx b/src/client/views/nodes/ContentFittingDocumentView.tsx index e15790c9d..2f8142a44 100644 --- a/src/client/views/nodes/ContentFittingDocumentView.tsx +++ b/src/client/views/nodes/ContentFittingDocumentView.tsx @@ -111,7 +111,7 @@ export class ContentFittingDocumentView extends React.Component(DocB } specificContextMenu = (e: React.MouseEvent): void => { const funcs: ContextMenuProps[] = []; - funcs.push({ description: "Auto Show Selected", event: () => this.showSelection, icon: "expand-arrows-alt" }); - funcs.push({ description: "Prev Selection", event: () => this.prevSelection, icon: "expand-arrows-alt" }); - funcs.push({ description: "Lock Selection", event: () => this.lockSelection, icon: "expand-arrows-alt" }); + funcs.push({ description: (this.isSelectionLocked() ? "Show" : "Lock") + " Selection", event: () => this.toggleLockSelection, icon: "expand-arrows-alt" }); + funcs.push({ description: `${this.props.Document.forceActive ? "Select" : "Force"} Contents Active`, event: () => this.props.Document.forceActive = !this.props.Document.forceActive, icon: "project-diagram" }); ContextMenu.Instance.addItem({ description: "DocumentBox Funcs...", subitems: funcs, icon: "asterisk" }); } @@ -46,9 +46,12 @@ export class DocumentBox extends DocComponent(DocB showSelection = () => { Doc.GetProto(this.props.Document)[this.props.fieldKey] = ComputedField.MakeFunction("selectedDocs(this,true,[_last_])?.[0]"); } - toggleLockSelection = () => { + isSelectionLocked = () => { const kvpstring = Field.toKeyValueString(this.props.Document, this.props.fieldKey); - (kvpstring.startsWith("=") || kvpstring.startsWith(":=")) ? this.lockSelection() : this.showSelection(); + return !(kvpstring.startsWith("=") || kvpstring.startsWith(":=")); + } + toggleLockSelection = () => { + !this.isSelectionLocked() ? this.lockSelection() : this.showSelection(); } prevSelection = () => { if (this._curSelection > 0) { @@ -61,9 +64,6 @@ export class DocumentBox extends DocComponent(DocB } } onPointerDown = (e: React.PointerEvent) => { - if (e.button === 0 && !e.altKey) { - e.stopPropagation(); - } } onClick = (e: React.MouseEvent) => { if (this._contRef.current!.getBoundingClientRect().top + 15 > e.clientY) this.toggleLockSelection(); @@ -78,9 +78,14 @@ export class DocumentBox extends DocComponent(DocB getTransform = () => this.props.ScreenToLocalTransform().translate(-15, -15); render() { const containedDoc = this.props.Document[this.props.fieldKey] as Doc; - return
- {!containedDoc ? (null) : + +
+ {!(containedDoc instanceof Doc) ? (null) : (DocB addDocTab={this.props.addDocTab} pinToPres={this.props.pinToPres} getTransform={this.getTransform} - renderDepth={this.props.renderDepth + 1} + renderDepth={this.props.Document.forceActive ? 0 : this.props.renderDepth + 1} // bcz: really need to have an 'alwaysSelected' prop that's not conflated with renderDepth PanelWidth={this.pwidth} PanelHeight={this.pheight} focus={this.props.focus} diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx index 9688c6ad4..8d3c3126d 100644 --- a/src/client/views/nodes/DocumentView.tsx +++ b/src/client/views/nodes/DocumentView.tsx @@ -137,7 +137,7 @@ export class DocumentView extends DocComponent(Docu } } - public static FloatDoc(topDocView:DocumentView, x:number, y:number) { + public static FloatDoc(topDocView: DocumentView, x: number, y: number) { const topDoc = topDocView.props.Document; const de = new DragManager.DocumentDragData([topDoc]); de.dragDivName = topDocView.props.dragDivName; @@ -171,7 +171,7 @@ export class DocumentView extends DocComponent(Docu } } else if (e.key === "f") { const ex = (e.nativeEvent.target! as any).getBoundingClientRect().left; - const ey = (e.nativeEvent.target!as any).getBoundingClientRect().top; + const ey = (e.nativeEvent.target! as any).getBoundingClientRect().top; DocumentView.FloatDoc(this, ex, ey); } } diff --git a/src/client/views/nodes/FormattedTextBox.tsx b/src/client/views/nodes/FormattedTextBox.tsx index 3efbd434e..b19729811 100644 --- a/src/client/views/nodes/FormattedTextBox.tsx +++ b/src/client/views/nodes/FormattedTextBox.tsx @@ -873,7 +873,7 @@ export class FormattedTextBox extends DocAnnotatableComponent<(FieldViewProps & if (this.props.onClick && e.button === 0) { e.preventDefault(); } - if (e.button === 0 && this.props.isSelected(true) && !e.altKey && !e.ctrlKey && !e.metaKey) { + if (e.button === 0 && this.active(true) && !e.altKey && !e.ctrlKey && !e.metaKey) { e.stopPropagation(); } if (e.button === 2 || (e.button === 0 && e.ctrlKey)) { -- cgit v1.2.3-70-g09d2