From c2282cef5208541ce8b696b86bc45acbd9f132b3 Mon Sep 17 00:00:00 2001 From: bob Date: Tue, 11 Feb 2020 15:13:35 -0500 Subject: added a publish button to doc dec titles/. --- src/client/views/DocumentDecorations.scss | 12 ++++++++++++ 1 file changed, 12 insertions(+) (limited to 'src/client/views/DocumentDecorations.scss') diff --git a/src/client/views/DocumentDecorations.scss b/src/client/views/DocumentDecorations.scss index 32346165d..d57b1456a 100644 --- a/src/client/views/DocumentDecorations.scss +++ b/src/client/views/DocumentDecorations.scss @@ -98,6 +98,18 @@ $linkGap : 3px; pointer-events: auto; overflow: hidden; text-align: center; + display:inline-block; + } + .publishBox { + width: 20px; + height: 22px; + grid-column-start: 3; + grid-column-end: 4; + pointer-events: all; + background: darkgray; + display: inline-block; + position: absolute; + right: 0; } } -- cgit v1.2.3-70-g09d2 From e619117f38191d81ae81a0bd502c6ce3d471d600 Mon Sep 17 00:00:00 2001 From: Bob Zeleznik Date: Tue, 11 Feb 2020 23:03:29 -0500 Subject: fixed document decorations. --- src/client/views/DocumentDecorations.scss | 3 ++- src/client/views/DocumentDecorations.tsx | 11 ++++++----- 2 files changed, 8 insertions(+), 6 deletions(-) (limited to 'src/client/views/DocumentDecorations.scss') diff --git a/src/client/views/DocumentDecorations.scss b/src/client/views/DocumentDecorations.scss index d57b1456a..455e53a79 100644 --- a/src/client/views/DocumentDecorations.scss +++ b/src/client/views/DocumentDecorations.scss @@ -165,11 +165,12 @@ $linkGap : 3px; .link-button-container { margin-top: $linkGap; - grid-column: 1/4; width: max-content; height: auto; display: flex; flex-direction: row; + z-index: 5; + position: absolute; } .linkButtonWrapper { diff --git a/src/client/views/DocumentDecorations.tsx b/src/client/views/DocumentDecorations.tsx index 3dfe34234..c9863b9ca 100644 --- a/src/client/views/DocumentDecorations.tsx +++ b/src/client/views/DocumentDecorations.tsx @@ -509,11 +509,11 @@ export class DocumentDecorations extends React.Component<{}, { value: string }> top: bounds.y - this._resizeBorderWidth / 2, pointerEvents: this.Interacting ? "none" : "all", zIndex: SelectionManager.SelectedDocuments().length > 1 ? 900 : 0, - }} onPointerDown={this.onBackgroundDown} onContextMenu={(e: React.MouseEvent) => { e.preventDefault(); e.stopPropagation(); }} > + }} onPointerDown={this.onBackgroundDown} onContextMenu={e => { e.preventDefault(); e.stopPropagation(); }} >
e.preventDefault()}>
e.preventDefault()}>
e.preventDefault()}>
-
- -
+
+
+ +
); } -- cgit v1.2.3-70-g09d2 From 8034deb2249b23e418427c4713c84f1ad76223c2 Mon Sep 17 00:00:00 2001 From: Bob Zeleznik Date: Sat, 15 Feb 2020 14:43:42 -0500 Subject: fixed dark scheme a bit more. fixed entering metadata on goldenlayout tabs --- src/client/util/DocumentManager.ts | 2 +- src/client/views/DocumentButtonBar.tsx | 2 +- src/client/views/DocumentDecorations.scss | 4 ++ src/client/views/DocumentDecorations.tsx | 62 +++++++++++++--------- src/client/views/MainView.scss | 9 +++- src/client/views/MainView.tsx | 8 +-- src/client/views/MetadataEntryMenu.scss | 6 +++ src/client/views/MetadataEntryMenu.tsx | 25 ++++----- .../CollectionStackingViewFieldColumn.tsx | 2 +- .../views/collections/ParentDocumentSelector.tsx | 5 +- src/client/views/nodes/ButtonBox.tsx | 2 +- .../authentication/models/current_user_utils.ts | 14 ++--- 12 files changed, 84 insertions(+), 57 deletions(-) (limited to 'src/client/views/DocumentDecorations.scss') diff --git a/src/client/util/DocumentManager.ts b/src/client/util/DocumentManager.ts index 60bb25272..d66bb3f09 100644 --- a/src/client/util/DocumentManager.ts +++ b/src/client/util/DocumentManager.ts @@ -208,7 +208,7 @@ export class DocumentManager { @action zoomIntoScale = (docDelegate: Doc, scale: number) => { const docView = DocumentManager.Instance.getDocumentView(Doc.GetProto(docDelegate)); - docView && docView.props.zoomToScale(scale); + docView?.props.zoomToScale(scale); } getScaleOfDocView = (docDelegate: Doc) => { diff --git a/src/client/views/DocumentButtonBar.tsx b/src/client/views/DocumentButtonBar.tsx index 2201fe710..ec1f879c2 100644 --- a/src/client/views/DocumentButtonBar.tsx +++ b/src/client/views/DocumentButtonBar.tsx @@ -242,7 +242,7 @@ export class DocumentButtonBar extends React.Component<{ views: (DocumentView | return !view0 ? (null) :
this.props.views.filter(dv => dv).map(dv => dv!.props.Document)} suggestWithFunction /> /* tfs: @bcz This might need to be the data document? */}> -
+
e.stopPropagation()} > {}
diff --git a/src/client/views/DocumentDecorations.scss b/src/client/views/DocumentDecorations.scss index 455e53a79..c847dd4d0 100644 --- a/src/client/views/DocumentDecorations.scss +++ b/src/client/views/DocumentDecorations.scss @@ -259,6 +259,10 @@ $linkGap : 3px; } } +.documentDecorations-darkScheme { + background: dimgray; +} + #template-list { position: absolute; top: 25px; diff --git a/src/client/views/DocumentDecorations.tsx b/src/client/views/DocumentDecorations.tsx index 65c02591c..12427cdac 100644 --- a/src/client/views/DocumentDecorations.tsx +++ b/src/client/views/DocumentDecorations.tsx @@ -479,17 +479,29 @@ export class DocumentDecorations extends React.Component<{}, { value: string }> return ; } render() { + const darkScheme = Cast(Doc.UserDoc().activeWorkspace, Doc, null)?.darkScheme ? "dimgray" : undefined; const bounds = this.Bounds; const seldoc = SelectionManager.SelectedDocuments().length ? SelectionManager.SelectedDocuments()[0] : undefined; if (SelectionManager.GetIsDragging() || bounds.x === Number.MAX_VALUE || !seldoc || this._hidden || isNaN(bounds.r) || isNaN(bounds.b) || isNaN(bounds.x) || isNaN(bounds.y)) { return (null); } const minimizeIcon = ( -
+
{/* Currently, this is set to be enabled if there is no ink selected. It might be interesting to think about minimizing ink if it's useful? -syip2*/} - {SelectionManager.SelectedDocuments().length === 1 ? DocumentDecorations.DocumentIcon(StrCast(SelectionManager.SelectedDocuments()[0].props.Document.layout, "...")) : "..."} + {SelectionManager.SelectedDocuments().length === 1 ? DocumentDecorations.DocumentIcon(StrCast(seldoc.props.Document.layout, "...")) : "..."}
); + const titleArea = this._edtingTitle ? + <> + this.titleBlur(true)} onChange={this.titleChanged} onKeyPress={this.titleEntered} /> +
DocUtils.Publish(seldoc.props.Document, this._accumulatedTitle, seldoc.props.addDocument, seldoc.props.removeDocument)}> + +
+ : +
{`${this.selectionTitle}`}
; + bounds.x = Math.max(0, bounds.x - this._resizeBorderWidth / 2) + this._resizeBorderWidth / 2; bounds.y = Math.max(0, bounds.y - this._resizeBorderWidth / 2 - this._titleHeight) + this._resizeBorderWidth / 2 + this._titleHeight; const borderRadiusDraggerWidth = 15; @@ -519,38 +531,36 @@ export class DocumentDecorations extends React.Component<{}, { value: string }> opacity: this._opacity }}> {minimizeIcon} - - {this._edtingTitle ? <> - this.titleBlur(true)} onChange={this.titleChanged} onKeyPress={this.titleEntered} /> -
{ - const promoteDoc = SelectionManager.SelectedDocuments()[0]; - DocUtils.Publish(promoteDoc.props.Document, this._accumulatedTitle, promoteDoc.props.addDocument, promoteDoc.props.removeDocument); - }}> - -
- : -
{`${this.selectionTitle}`}
} -
+ {titleArea} +
-
e.preventDefault()}>
-
e.preventDefault()}>
-
e.preventDefault()}>
-
e.preventDefault()}>
+
e.preventDefault()}>
+
e.preventDefault()}>
+
e.preventDefault()}>
+
e.preventDefault()}>
-
e.preventDefault()}>
-
e.preventDefault()}>
-
e.preventDefault()}>
-
e.preventDefault()}>
-
e.preventDefault()}>
+
e.preventDefault()}>
+
e.preventDefault()}>
+
e.preventDefault()}>
+
e.preventDefault()}>
+
e.preventDefault()}>
-
+
); } } \ No newline at end of file diff --git a/src/client/views/MainView.scss b/src/client/views/MainView.scss index d39c217ec..b8fd7be0b 100644 --- a/src/client/views/MainView.scss +++ b/src/client/views/MainView.scss @@ -21,7 +21,7 @@ z-index: 1; } -#mainView-container { +.mainView-container, .mainView-container-dark { width: 100%; height: 100%; position: absolute; @@ -31,6 +31,13 @@ touch-action: none; } +.mainView-container-dark { + .lm_splitter { + background: dimgray; + opacity: 0.5; + } +} + .mainView-mainContent { width: 100%; height: 100%; diff --git a/src/client/views/MainView.tsx b/src/client/views/MainView.tsx index ba49a2b53..5d739474e 100644 --- a/src/client/views/MainView.tsx +++ b/src/client/views/MainView.tsx @@ -276,7 +276,7 @@ export class MainView extends React.Component { childBackgroundColor = (doc: Doc) => { if (this.darkScheme) { - return doc.type === DocumentType.TEXT ? "#112423" : "black"; + return doc.type === DocumentType.TEXT ? "#2d2d2d" : "black"; } return doc.type === DocumentType.TEXT ? "#f1efeb" : doc.type === DocumentType.COL && doc._viewType === CollectionViewType.Tree ? "lightgray" : "white"; @@ -448,10 +448,10 @@ export class MainView extends React.Component { @computed get mainContent() { const sidebar = this.userDoc && this.userDoc.sidebarContainer; return !this.userDoc || !(sidebar instanceof Doc) ? (null) : ( -
+
+ style={{ backgroundColor: `${StrCast(sidebar.backgroundColor, this.darkScheme ? "dimGray" : "black")}` }} > + return (
diff --git a/src/client/views/MetadataEntryMenu.scss b/src/client/views/MetadataEntryMenu.scss index 5f4a52c0c..5776cf070 100644 --- a/src/client/views/MetadataEntryMenu.scss +++ b/src/client/views/MetadataEntryMenu.scss @@ -8,6 +8,12 @@ } } +.metadataEntry-autoSuggester { + width: 100%; + height: 100%; + padding-right: 10px; +} + #metadataEntry-outer { overflow: auto !important; } diff --git a/src/client/views/MetadataEntryMenu.tsx b/src/client/views/MetadataEntryMenu.tsx index 23b21ae0c..8bc80ed06 100644 --- a/src/client/views/MetadataEntryMenu.tsx +++ b/src/client/views/MetadataEntryMenu.tsx @@ -195,10 +195,10 @@ export class MetadataEntryMenu extends React.Component{ _ref = React.createRef(); render() { - return ( -
-
- Key: + return (
e.stopPropagation()}> +
+ Key: +
this.autosuggestRef.current!.input?.focus()} > { onSuggestionsFetchRequested={emptyFunction} onSuggestionsClearRequested={emptyFunction} ref={this.autosuggestRef} /> - Value: - this._ref.current!.focus()} onChange={this.onValueChange} onKeyDown={this.onValueKeyDown} /> - {this.considerChildOptions} -
-
-
    - {this._allSuggestions.slice().sort().map(s =>
  • { this._currentKey = s; this.previewValue(); })} >{s}
  • )} -
+ Value: + this._ref.current!.focus()} onChange={this.onValueChange} onKeyDown={this.onValueKeyDown} /> + {this.considerChildOptions} +
+
+
    + {this._allSuggestions.slice().sort().map(s =>
  • { this._currentKey = s; this.previewValue(); })} >{s}
  • )} +
+
); } } \ No newline at end of file diff --git a/src/client/views/collections/CollectionStackingViewFieldColumn.tsx b/src/client/views/collections/CollectionStackingViewFieldColumn.tsx index 3fc05c6b7..2ff477c57 100644 --- a/src/client/views/collections/CollectionStackingViewFieldColumn.tsx +++ b/src/client/views/collections/CollectionStackingViewFieldColumn.tsx @@ -360,7 +360,7 @@ export class CollectionStackingViewFieldColumn extends React.Component diff --git a/src/client/views/collections/ParentDocumentSelector.tsx b/src/client/views/collections/ParentDocumentSelector.tsx index 6e406638b..41b9e821c 100644 --- a/src/client/views/collections/ParentDocumentSelector.tsx +++ b/src/client/views/collections/ParentDocumentSelector.tsx @@ -78,13 +78,12 @@ export class SelectorContextMenu extends React.Component { export class ParentDocSelector extends React.Component { render() { const flyout = ( -
+
); return
e.stopPropagation()} className="parentDocumentSelector-linkFlyout"> - + diff --git a/src/client/views/nodes/ButtonBox.tsx b/src/client/views/nodes/ButtonBox.tsx index ee48b47b7..de0b509eb 100644 --- a/src/client/views/nodes/ButtonBox.tsx +++ b/src/client/views/nodes/ButtonBox.tsx @@ -81,7 +81,7 @@ export class ButtonBox extends DocComponent(Butt
diff --git a/src/server/authentication/models/current_user_utils.ts b/src/server/authentication/models/current_user_utils.ts index 32c375bd7..d09837d96 100644 --- a/src/server/authentication/models/current_user_utils.ts +++ b/src/server/authentication/models/current_user_utils.ts @@ -164,7 +164,7 @@ export class CurrentUserUtils { }); return Docs.Create.ButtonDocument({ - _width: 35, _height: 25, backgroundColor: "lightgrey", color: "rgb(34, 34, 34)", title: "Tools", fontSize: 10, targetContainer: sidebarContainer, + _width: 35, _height: 25, title: "Tools", fontSize: 10, targetContainer: sidebarContainer, letterSpacing: "0px", textTransform: "unset", borderRounding: "5px 5px 0px 0px", boxShadow: "3px 3px 0px rgb(34, 34, 34)", sourcePanel: Docs.Create.StackingDocument([dragCreators, color], { _width: 500, lockedPosition: true, _chromeStatus: "disabled", title: "tools stack" @@ -177,20 +177,20 @@ export class CurrentUserUtils { static setupLibraryPanel(sidebarContainer: Doc, doc: Doc) { // setup workspaces library item doc.workspaces = Docs.Create.TreeDocument([], { - title: "WORKSPACES", _height: 100, forceActive: true, boxShadow: "0 0", lockedPosition: true, backgroundColor: "#eeeeee" + title: "WORKSPACES", _height: 100, forceActive: true, boxShadow: "0 0", lockedPosition: true, }); doc.documents = Docs.Create.TreeDocument([], { - title: "DOCUMENTS", _height: 42, forceActive: true, boxShadow: "0 0", treeViewPreventOpen: true, lockedPosition: true, backgroundColor: "#eeeeee" + title: "DOCUMENTS", _height: 42, forceActive: true, boxShadow: "0 0", treeViewPreventOpen: true, lockedPosition: true, }); // setup Recently Closed library item doc.recentlyClosed = Docs.Create.TreeDocument([], { - title: "RECENTLY CLOSED", _height: 75, forceActive: true, boxShadow: "0 0", treeViewPreventOpen: true, lockedPosition: true, backgroundColor: "#eeeeee" + title: "RECENTLY CLOSED", _height: 75, forceActive: true, boxShadow: "0 0", treeViewPreventOpen: true, lockedPosition: true, }); return Docs.Create.ButtonDocument({ - _width: 50, _height: 25, backgroundColor: "lightgrey", color: "rgb(34, 34, 34)", title: "Library", fontSize: 10, + _width: 50, _height: 25, title: "Library", fontSize: 10, letterSpacing: "0px", textTransform: "unset", borderRounding: "5px 5px 0px 0px", boxShadow: "3px 3px 0px rgb(34, 34, 34)", sourcePanel: Docs.Create.TreeDocument([doc.workspaces as Doc, doc.documents as Doc, doc.recentlyClosed as Doc], { title: "Library", _xMargin: 5, _yMargin: 5, _gridGap: 5, forceActive: true, dropAction: "alias", lockedPosition: true, boxShadow: "0 0", @@ -203,7 +203,7 @@ export class CurrentUserUtils { // setup the Search button which will display the search panel. static setupSearchPanel(sidebarContainer: Doc) { return Docs.Create.ButtonDocument({ - _width: 50, _height: 25, backgroundColor: "lightgrey", color: "rgb(34, 34, 34)", title: "Search", fontSize: 10, + _width: 50, _height: 25, title: "Search", fontSize: 10, letterSpacing: "0px", textTransform: "unset", borderRounding: "5px 5px 0px 0px", boxShadow: "3px 3px 0px rgb(34, 34, 34)", sourcePanel: Docs.Create.QueryDocument({ title: "search stack", ignoreClick: true @@ -239,7 +239,7 @@ export class CurrentUserUtils { Docs.Create.MulticolumnDocument([], { title: "images", _height: 200 }), Docs.Create.TextDocument("", { title: "contents", _height: 100 }) ], - { _width: 400, _height: 300, title: "slideView", _chromeStatus: "disabled", _xMargin: 3, _yMargin: 3, backgroundColor: "lightGray", _autoHeight: true }); + { _width: 400, _height: 300, title: "slideView", _chromeStatus: "disabled", _xMargin: 3, _yMargin: 3, _autoHeight: true }); slideTemplate.isTemplateDoc = makeTemplate(slideTemplate); const iconDoc = Docs.Create.TextDocument("", { title: "icon", _width: 150, _height: 30, isTemplateDoc: true, onClick: ScriptField.MakeScript("setNativeView(this)") }); -- cgit v1.2.3-70-g09d2 From 4e31a6cc1dfdfaf79ad6b3d84980efa5e350b1bf Mon Sep 17 00:00:00 2001 From: bob Date: Tue, 18 Feb 2020 12:41:19 -0500 Subject: added gear icon to open context menu with right-click --- src/client/views/DocumentDecorations.scss | 2 +- src/client/views/DocumentDecorations.tsx | 46 ++++++++++++++++++++++++++++- src/client/views/nodes/FormattedTextBox.tsx | 8 ++++- 3 files changed, 53 insertions(+), 3 deletions(-) (limited to 'src/client/views/DocumentDecorations.scss') diff --git a/src/client/views/DocumentDecorations.scss b/src/client/views/DocumentDecorations.scss index c847dd4d0..4bf7e5ec4 100644 --- a/src/client/views/DocumentDecorations.scss +++ b/src/client/views/DocumentDecorations.scss @@ -98,7 +98,7 @@ $linkGap : 3px; pointer-events: auto; overflow: hidden; text-align: center; - display:inline-block; + display:flex; } .publishBox { width: 20px; diff --git a/src/client/views/DocumentDecorations.tsx b/src/client/views/DocumentDecorations.tsx index 5bef5c5b5..2d49a13b6 100644 --- a/src/client/views/DocumentDecorations.tsx +++ b/src/client/views/DocumentDecorations.tsx @@ -19,6 +19,7 @@ import './DocumentDecorations.scss'; import { DocumentView } from "./nodes/DocumentView"; import React = require("react"); import { Id } from '../../new_fields/FieldSymbols'; +import e = require('express'); library.add(faCaretUp); library.add(faObjectGroup); @@ -139,6 +140,44 @@ export class DocumentDecorations extends React.Component<{}, { value: string }> setTimeout(() => this._keyinput.current!.focus(), 0); } + @action onSettingsDown = (e: React.PointerEvent): void => { + setupMoveUpEvents(this, e, () => false, (e) => { }, this.onSettingsClick); + } + + simulateMouseClick(element: Element, x: number, y: number, sx: number, sy: number) { + ["pointerdown", "pointerup"].map(event => element.dispatchEvent( + new PointerEvent(event, { + view: window, + bubbles: true, + cancelable: true, + button: 2, + pointerType: "mouse", + clientX: x, + clientY: y, + screenX: sx, + screenY: sy, + }))); + + element.dispatchEvent( + new MouseEvent("contextmenu", { + view: window, + bubbles: true, + cancelable: true, + button: 2, + clientX: x, + clientY: y, + movementX: 0, + movementY: 0, + screenX: sx, + screenY: sy, + })); + } + @action onSettingsClick = (e: PointerEvent): void => { + if (e.button === 0 && !e.altKey && !e.ctrlKey) { + this.simulateMouseClick(SelectionManager.SelectedDocuments()[0].ContentDiv!.children[0].children[0], e.clientX, e.clientY + 30, e.screenX, e.screenY + 30); + } + } + onBackgroundDown = (e: React.PointerEvent): void => { setupMoveUpEvents(this, e, this.onBackgroundMove, (e) => { }, (e) => { }); } @@ -377,7 +416,12 @@ export class DocumentDecorations extends React.Component<{}, { value: string }>
: -
{`${this.selectionTitle}`}
; +
+
+ +
+ {`${this.selectionTitle}`} +
; bounds.x = Math.max(0, bounds.x - this._resizeBorderWidth / 2) + this._resizeBorderWidth / 2; bounds.y = Math.max(0, bounds.y - this._resizeBorderWidth / 2 - this._titleHeight) + this._resizeBorderWidth / 2 + this._titleHeight; diff --git a/src/client/views/nodes/FormattedTextBox.tsx b/src/client/views/nodes/FormattedTextBox.tsx index 8f6fce4da..26711259c 100644 --- a/src/client/views/nodes/FormattedTextBox.tsx +++ b/src/client/views/nodes/FormattedTextBox.tsx @@ -372,6 +372,7 @@ export class FormattedTextBox extends DocAnnotatableComponent<(FieldViewProps & !this.props.Document.expandedTemplate && funcs.push({ description: "Make Template", event: () => { this.props.Document.isTemplateDoc = true; Doc.AddDocToList(Cast(Doc.UserDoc().noteTypes, Doc, null), "data", this.props.Document); }, icon: "eye" }); funcs.push({ description: "Toggle Sidebar", event: () => { e.stopPropagation(); this.props.Document._showSidebar = !this.props.Document._showSidebar; }, icon: "expand-arrows-alt" }); funcs.push({ description: "Record Bullet", event: () => { e.stopPropagation(); this.recordBullet(); }, icon: "expand-arrows-alt" }); + funcs.push({ description: "Toggle Menubar", event: () => { e.stopPropagation(); this.toggleMenubar(); }, icon: "expand-arrows-alt" }); ["My Text", "Text from Others", "Todo Items", "Important Items", "Ignore Items", "Disagree Items", "By Recent Minute", "By Recent Hour"].forEach(option => funcs.push({ description: (FormattedTextBox._highlights.indexOf(option) === -1 ? "Highlight " : "Unhighlight ") + option, event: () => { @@ -409,6 +410,11 @@ export class FormattedTextBox extends DocAnnotatableComponent<(FieldViewProps & DictationManager.Controls.stop(!abort); } + @action + toggleMenubar = () => { + this.props.Document._chromeStatus = this.props.Document._chromeStatus == "disabled" ? "enabled" : "disabled"; + } + recordBullet = async () => { const completedCue = "end session"; const results = await DictationManager.Controls.listen({ @@ -856,7 +862,7 @@ export class FormattedTextBox extends DocAnnotatableComponent<(FieldViewProps & // jump rich text menu to this textbox const { current } = this._ref; - if (current) { + if (current && this.props.Document._chromeStatus !== "disabled") { const x = Math.min(Math.max(current.getBoundingClientRect().left, 0), window.innerWidth - RichTextMenu.Instance.width); const y = this._ref.current!.getBoundingClientRect().top - RichTextMenu.Instance.height - 50; RichTextMenu.Instance.jumpTo(x, y); -- cgit v1.2.3-70-g09d2 From 66cfe6c5fab54c970ac51a4cd29ce1db50e464b3 Mon Sep 17 00:00:00 2001 From: bob Date: Tue, 18 Feb 2020 13:24:03 -0500 Subject: fixed titling. added border for embedded docs in text boxes. --- src/client/util/RichTextSchema.tsx | 8 +++++--- src/client/views/DocumentButtonBar.tsx | 2 +- src/client/views/DocumentDecorations.scss | 6 +++++- src/client/views/DocumentDecorations.tsx | 11 ++++------- src/client/views/collections/ParentDocumentSelector.tsx | 2 +- 5 files changed, 16 insertions(+), 13 deletions(-) (limited to 'src/client/views/DocumentDecorations.scss') diff --git a/src/client/util/RichTextSchema.tsx b/src/client/util/RichTextSchema.tsx index 656215368..23b0a56a8 100644 --- a/src/client/util/RichTextSchema.tsx +++ b/src/client/util/RichTextSchema.tsx @@ -12,7 +12,7 @@ import { Doc, Field, HeightSym, WidthSym } from "../../new_fields/Doc"; import { Id } from "../../new_fields/FieldSymbols"; import { ObjectField } from "../../new_fields/ObjectField"; import { ComputedField } from "../../new_fields/ScriptField"; -import { BoolCast, NumCast, StrCast } from "../../new_fields/Types"; +import { BoolCast, NumCast, StrCast, Cast } from "../../new_fields/Types"; import { emptyFunction, returnEmptyString, returnFalse, returnOne, Utils } from "../../Utils"; import { DocServer } from "../DocServer"; import { DocumentView } from "../views/nodes/DocumentView"; @@ -731,6 +731,7 @@ export class DashDocView { this._outer = document.createElement("span"); this._outer.style.position = "relative"; this._outer.style.textIndent = "0"; + this._outer.style.border = "1px solid " + StrCast(tbox.Document.color, (Cast(Doc.UserDoc().activeWorkspace, Doc, null).darkScheme ? "dimGray" : "lightGray")); this._outer.style.width = node.attrs.width; this._outer.style.height = node.attrs.height; this._outer.style.display = node.attrs.hidden ? "none" : "inline-block"; @@ -810,9 +811,10 @@ export class DashDocView { } } this._reactionDisposer?.(); - this._reactionDisposer = reaction(() => [finalLayout[WidthSym](), finalLayout[HeightSym]()], (dim) => { + this._reactionDisposer = reaction(() => ({ dim: [finalLayout[WidthSym](), finalLayout[HeightSym]()], color: finalLayout.color }), ({ dim, color }) => { this._dashSpan.style.width = this._outer.style.width = Math.max(20, dim[0]) + "px"; this._dashSpan.style.height = this._outer.style.height = Math.max(20, dim[1]) + "px"; + this._outer.style.border = "1px solid " + StrCast(finalLayout.color, (Cast(Doc.UserDoc().activeWorkspace, Doc, null).darkScheme ? "dimGray" : "lightGray")); }, { fireImmediately: true }); ReactDOM.render( = new Map(); Array.from(Object.values(Templates.TemplateList)).map(template => templates.set(template, this.props.views.reduce((checked, doc) => checked || doc?.props.Document["_show" + template.Name] ? true : false, false as boolean))); - return !view0 ? (null) :
+ return !view0 ? (null) :
v).map(v => v as DocumentView)} templates={templates} />}>
diff --git a/src/client/views/DocumentDecorations.scss b/src/client/views/DocumentDecorations.scss index 4bf7e5ec4..202174097 100644 --- a/src/client/views/DocumentDecorations.scss +++ b/src/client/views/DocumentDecorations.scss @@ -90,7 +90,7 @@ $linkGap : 3px; cursor: ew-resize; } - .title { + .documentDecorations-title { background: $alt-accent; opacity: 1; grid-column-start: 3; @@ -99,6 +99,10 @@ $linkGap : 3px; overflow: hidden; text-align: center; display:flex; + .documentDecorations-contextMenu { + width: 25px; + height: calc(100% + 8px); // 8px for the height of the top resizer bar + } } .publishBox { width: 20px; diff --git a/src/client/views/DocumentDecorations.tsx b/src/client/views/DocumentDecorations.tsx index 2d49a13b6..8e4598339 100644 --- a/src/client/views/DocumentDecorations.tsx +++ b/src/client/views/DocumentDecorations.tsx @@ -106,13 +106,10 @@ export class DocumentDecorations extends React.Component<{}, { value: string }> } else if (this._titleControlString.startsWith("#")) { const selectionTitleFieldKey = this._titleControlString.substring(1); selectionTitleFieldKey === "title" && (SelectionManager.SelectedDocuments()[0].props.Document.customTitle = !this._accumulatedTitle.startsWith("-")); - let didAnything = false; UndoManager.RunInBatch(() => selectionTitleFieldKey && SelectionManager.SelectedDocuments().forEach(d => { const value = typeof d.props.Document[selectionTitleFieldKey] === "number" ? +this._accumulatedTitle : this._accumulatedTitle; - didAnything = didAnything || d.props.Document[selectionTitleFieldKey] !== value; Doc.SetInPlace(d.props.Document, selectionTitleFieldKey, value, true); }), "title blur"); - if (!didAnything) UndoManager.Undo(); } } }); @@ -402,22 +399,22 @@ export class DocumentDecorations extends React.Component<{}, { value: string }> return (null); } const minimizeIcon = ( -
+
{/* Currently, this is set to be enabled if there is no ink selected. It might be interesting to think about minimizing ink if it's useful? -syip2*/} {SelectionManager.SelectedDocuments().length === 1 ? DocumentDecorations.DocumentIcon(StrCast(seldoc.props.Document.layout, "...")) : "..."}
); const titleArea = this._edtingTitle ? <> - this.titleBlur(true)} onChange={action(e => this._accumulatedTitle = e.target.value)} onKeyPress={this.titleEntered} />
DocUtils.Publish(seldoc.props.Document, this._accumulatedTitle, seldoc.props.addDocument, seldoc.props.removeDocument)}>
: -
-
+
+
{`${this.selectionTitle}`} diff --git a/src/client/views/collections/ParentDocumentSelector.tsx b/src/client/views/collections/ParentDocumentSelector.tsx index 41b9e821c..027ac5a0e 100644 --- a/src/client/views/collections/ParentDocumentSelector.tsx +++ b/src/client/views/collections/ParentDocumentSelector.tsx @@ -82,7 +82,7 @@ export class ParentDocSelector extends React.Component {
); - return
e.stopPropagation()} className="parentDocumentSelector-linkFlyout"> + return
e.stopPropagation()} className="parentDocumentSelector-linkFlyout"> -- cgit v1.2.3-70-g09d2 From fc945bcf674efe62aad67be8c1f337cd9b8c83e2 Mon Sep 17 00:00:00 2001 From: bob Date: Fri, 28 Feb 2020 14:59:31 -0500 Subject: fixed stacking view input color. made doc decs more size aware. fixed default note templates to be templates. --- src/client/views/DocumentDecorations.scss | 12 ++++-- src/client/views/DocumentDecorations.tsx | 49 ++++++++++++---------- .../views/collections/CollectionStackingView.scss | 1 - src/client/views/nodes/FormattedTextBox.tsx | 10 +++-- .../authentication/models/current_user_utils.ts | 10 ++--- 5 files changed, 46 insertions(+), 36 deletions(-) (limited to 'src/client/views/DocumentDecorations.scss') diff --git a/src/client/views/DocumentDecorations.scss b/src/client/views/DocumentDecorations.scss index 202174097..1992c5efa 100644 --- a/src/client/views/DocumentDecorations.scss +++ b/src/client/views/DocumentDecorations.scss @@ -90,6 +90,14 @@ $linkGap : 3px; cursor: ew-resize; } + .documentDecorations-contextMenu { + background: $alt-accent; + width: 25px; + height: calc(100% + 8px); // 8px for the height of the top resizer bar + grid-column-start: 1; + grid-column-end : 2; + pointer-events: all; + } .documentDecorations-title { background: $alt-accent; opacity: 1; @@ -99,10 +107,6 @@ $linkGap : 3px; overflow: hidden; text-align: center; display:flex; - .documentDecorations-contextMenu { - width: 25px; - height: calc(100% + 8px); // 8px for the height of the top resizer bar - } } .publishBox { width: 20px; diff --git a/src/client/views/DocumentDecorations.tsx b/src/client/views/DocumentDecorations.tsx index a01f32152..9c69e6083 100644 --- a/src/client/views/DocumentDecorations.tsx +++ b/src/client/views/DocumentDecorations.tsx @@ -403,17 +403,21 @@ export class DocumentDecorations extends React.Component<{}, { value: string }> if (SelectionManager.GetIsDragging() || bounds.x === Number.MAX_VALUE || !seldoc || this._hidden || isNaN(bounds.r) || isNaN(bounds.b) || isNaN(bounds.x) || isNaN(bounds.y)) { return (null); } - const minimizeIcon = ( -
- {/* Currently, this is set to be enabled if there is no ink selected. It might be interesting to think about minimizing ink if it's useful? -syip2*/} - {SelectionManager.SelectedDocuments().length === 1 ? DocumentDecorations.DocumentIcon(StrCast(seldoc.props.Document.layout, "...")) : "..."} -
); + const minimal = bounds.r - bounds.x < 100 ? true : false; + const minimizeIcon = minimal ? ( +
+ +
) : ( +
+ {/* Currently, this is set to be enabled if there is no ink selected. It might be interesting to think about minimizing ink if it's useful? -syip2*/} + {SelectionManager.SelectedDocuments().length === 1 ? DocumentDecorations.DocumentIcon(StrCast(seldoc.props.Document.layout, "...")) : "..."} +
); const titleArea = this._edtingTitle ? <> - this.titleBlur(true)} onChange={action(e => this._accumulatedTitle = e.target.value)} onKeyPress={this.titleEntered} /> -
{ if (!seldoc.props.Document.customTitle) { seldoc.props.Document.customTitle = true; @@ -423,12 +427,12 @@ export class DocumentDecorations extends React.Component<{}, { value: string }> DocUtils.Publish(seldoc.props.Document, this._accumulatedTitle, seldoc.props.addDocument, seldoc.props.removeDocument); })}> -
+
} : -
-
+
+ {minimal ? (null) :
-
+
} {`${this.selectionTitle}`}
; @@ -443,7 +447,7 @@ export class DocumentDecorations extends React.Component<{}, { value: string }> if (bounds.y > bounds.b) { bounds.y = bounds.b - (this._resizeBorderWidth + this._linkBoxHeight + this._titleHeight); } - return (
+ return (
}}> {minimizeIcon} {titleArea} -
+
e.preventDefault()}>
+ onPointerDown={this.onPointerDown} onContextMenu={(e) => e.preventDefault()}>
e.preventDefault()}>
+ onPointerDown={this.onPointerDown} onContextMenu={(e) => e.preventDefault()}>
e.preventDefault()}>
+ onPointerDown={this.onPointerDown} onContextMenu={(e) => e.preventDefault()}>
e.preventDefault()}>
+ onPointerDown={this.onPointerDown} onContextMenu={(e) => e.preventDefault()}>
e.preventDefault()}>
+ onPointerDown={this.onPointerDown} onContextMenu={(e) => e.preventDefault()}>
e.preventDefault()}>
+ onPointerDown={this.onPointerDown} onContextMenu={(e) => e.preventDefault()}>
e.preventDefault()}>
+ onPointerDown={this.onPointerDown} onContextMenu={(e) => e.preventDefault()}>
e.preventDefault()}>
+ onPointerDown={this.onPointerDown} onContextMenu={(e) => e.preventDefault()}>
e.preventDefault()}>
+ onPointerDown={this.onRadiusDown} onContextMenu={(e) => e.preventDefault()}>
diff --git a/src/client/views/collections/CollectionStackingView.scss b/src/client/views/collections/CollectionStackingView.scss index 8e3919532..bfa5ea278 100644 --- a/src/client/views/collections/CollectionStackingView.scss +++ b/src/client/views/collections/CollectionStackingView.scss @@ -306,7 +306,6 @@ overflow: hidden; margin: auto; width: 90%; - color: lightgrey; overflow: ellipses; .editableView-container-editing-oneLine, diff --git a/src/client/views/nodes/FormattedTextBox.tsx b/src/client/views/nodes/FormattedTextBox.tsx index b2458ea1d..f74e5f002 100644 --- a/src/client/views/nodes/FormattedTextBox.tsx +++ b/src/client/views/nodes/FormattedTextBox.tsx @@ -46,6 +46,7 @@ import { FieldView, FieldViewProps } from "./FieldView"; import "./FormattedTextBox.scss"; import { FormattedTextBoxComment, formattedTextBoxCommentPlugin } from './FormattedTextBoxComment'; import React = require("react"); +import { PrefetchProxy } from '../../../new_fields/Proxy'; library.add(faEdit); library.add(faSmile, faTextHeight, faUpload); @@ -376,12 +377,15 @@ export class FormattedTextBox extends DocAnnotatableComponent<(FieldViewProps & toggleSidebar = () => this._sidebarMovement < 5 && (this.props.Document.sidebarWidthPercent = StrCast(this.props.Document.sidebarWidthPercent, "0%") === "0%" ? "25%" : "0%"); - public static DefaultLayout: Doc | string | undefined; + public static get DefaultLayout(): Doc | string | undefined { + return Cast(Doc.UserDoc().defaultTextLayout, Doc, null) || StrCast(Doc.UserDoc().defaultTextLayout, null); + } specificContextMenu = (e: React.MouseEvent): void => { const funcs: ContextMenuProps[] = []; - this.props.Document.isTemplateDoc && funcs.push({ description: "Make Default Layout", event: async () => FormattedTextBox.DefaultLayout = this.props.Document.proto as Doc, icon: "eye" }); - funcs.push({ description: "Reset Default Layout", event: () => FormattedTextBox.DefaultLayout = undefined, icon: "eye" }); + this.props.Document.isTemplateDoc && funcs.push({ description: "Make Default Layout", event: async () => Doc.UserDoc().defaultTextLayout = new PrefetchProxy(this.props.Document.proto as Doc), icon: "eye" }); + funcs.push({ description: "Reset Default Layout", event: () => Doc.UserDoc().defaultTextLayout = undefined, icon: "eye" }); !this.props.Document.expandedTemplate && funcs.push({ description: "Make Template", event: () => { this.props.Document.isTemplateDoc = true; Doc.AddDocToList(Cast(Doc.UserDoc().noteTypes, Doc, null), "data", this.props.Document); }, icon: "eye" }); + funcs.push({ description: "Toggle Single Line", event: () => this.props.Document.singleLine = !this.props.Document.singleLine, icon: "expand-arrows-alt" }); funcs.push({ description: "Toggle Sidebar", event: () => this.props.Document._showSidebar = !this.props.Document._showSidebar, icon: "expand-arrows-alt" }); funcs.push({ description: "Record Bullet", event: () => this.recordBullet(), icon: "expand-arrows-alt" }); funcs.push({ description: "Toggle Menubar", event: () => this.toggleMenubar(), icon: "expand-arrows-alt" }); diff --git a/src/server/authentication/models/current_user_utils.ts b/src/server/authentication/models/current_user_utils.ts index ea19d9da8..658b9b715 100644 --- a/src/server/authentication/models/current_user_utils.ts +++ b/src/server/authentication/models/current_user_utils.ts @@ -42,11 +42,11 @@ export class CurrentUserUtils { Docs.Create.TextDocument("completed", { title: "completed", _backgroundColor: "green", color: "white" }) ]; const noteTemplates = [ - Docs.Create.TextDocument("", { title: "Note", backgroundColor: "yellow" }), - Docs.Create.TextDocument("", { title: "Idea", backgroundColor: "pink" }), - Docs.Create.TextDocument("", { title: "Topic", backgroundColor: "lightBlue" }), - Docs.Create.TextDocument("", { title: "Person", backgroundColor: "lightGreen" }), - Docs.Create.TextDocument("", { title: "Todo", backgroundColor: "orange", _autoHeight: false, _height: 100, _showCaption: "caption" }) + Docs.Create.TextDocument("", { title: "Note", isTemplateDoc: true, backgroundColor: "yellow" }), + Docs.Create.TextDocument("", { title: "Idea", isTemplateDoc: true, backgroundColor: "pink" }), + Docs.Create.TextDocument("", { title: "Topic", isTemplateDoc: true, backgroundColor: "lightBlue" }), + Docs.Create.TextDocument("", { title: "Person", isTemplateDoc: true, backgroundColor: "lightGreen" }), + Docs.Create.TextDocument("", { title: "Todo", isTemplateDoc: true, backgroundColor: "orange", _autoHeight: false, _height: 100, _showCaption: "caption" }) ]; doc.fieldTypes = Docs.Create.TreeDocument([], { title: "field enumerations" }); Doc.enumeratedTextTemplate(Doc.GetProto(noteTemplates[4]), FormattedTextBox.LayoutString("Todo"), "taskStatus", taskStatusValues); -- cgit v1.2.3-70-g09d2 From 8b71007c98f3c5f5092d15c6ce91142729bcec22 Mon Sep 17 00:00:00 2001 From: bob Date: Tue, 3 Mar 2020 14:02:17 -0500 Subject: fixed dragging from linear view because of screentransform. added [[key=value]] syntax. added button for seeing enumerated values. added step up button in DocDec for selecting parent collection --- src/client/util/RichTextRules.ts | 8 ++- src/client/util/RichTextSchema.tsx | 57 +++++++++++++++------- src/client/views/DocumentDecorations.scss | 11 +++++ src/client/views/DocumentDecorations.tsx | 16 +++++- .../views/collections/CollectionLinearView.tsx | 2 +- src/new_fields/Doc.ts | 34 ++++++------- 6 files changed, 89 insertions(+), 39 deletions(-) (limited to 'src/client/views/DocumentDecorations.scss') diff --git a/src/client/util/RichTextRules.ts b/src/client/util/RichTextRules.ts index 70a1a5154..7ffc2dd9c 100644 --- a/src/client/util/RichTextRules.ts +++ b/src/client/util/RichTextRules.ts @@ -81,10 +81,11 @@ export class RichTextRules { // create a text display of a metadata field on this or another document, or create a hyperlink portal to another document [[ : ]] // [[:Doc]] => hyperlink [[fieldKey]] => show field [[fieldKey:Doc]] => show field of doc new InputRule( - new RegExp(/\[\[([a-zA-Z_#@\? \-0-9]*)(:[a-zA-Z_#@\? \-0-9]+)?\]\]$/), + new RegExp(/\[\[([a-zA-Z_#@\? \-0-9]*)(=[a-zA-Z_#@\? \-0-9]*)?(:[a-zA-Z_#@\? \-0-9]+)?\]\]$/), (state, match, start, end) => { const fieldKey = match[1]; - const docid = match[2]?.substring(1); + const docid = match[3]?.substring(1); + const value = match[2]?.substring(1); if (!fieldKey) { if (docid) { DocServer.GetRefField(docid).then(docx => { @@ -97,6 +98,9 @@ export class RichTextRules { } return state.tr; } + if (value !== "") { + this.Document[DataSym][fieldKey] = value; + } const fieldView = state.schema.nodes.dashField.create({ fieldKey, docid }); return state.tr.deleteRange(start, end).insert(start, fieldView); }), diff --git a/src/client/util/RichTextSchema.tsx b/src/client/util/RichTextSchema.tsx index 2ef22b6a0..034f5d55a 100644 --- a/src/client/util/RichTextSchema.tsx +++ b/src/client/util/RichTextSchema.tsx @@ -8,28 +8,25 @@ import { EditorState, NodeSelection, Plugin, TextSelection } from "prosemirror-s import { StepMap } from "prosemirror-transform"; import { EditorView } from "prosemirror-view"; import * as ReactDOM from 'react-dom'; -import { Doc, Field, HeightSym, WidthSym, DocListCast } from "../../new_fields/Doc"; +import { Doc, DocListCast, Field, HeightSym, WidthSym } from "../../new_fields/Doc"; import { Id } from "../../new_fields/FieldSymbols"; +import { List } from "../../new_fields/List"; 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, NumCast, StrCast, Cast } from "../../new_fields/Types"; +import { BoolCast, Cast, NumCast, StrCast } from "../../new_fields/Types"; import { emptyFunction, returnEmptyString, returnFalse, returnOne, Utils } from "../../Utils"; import { DocServer } from "../DocServer"; +import { Docs } from "../documents/Documents"; +import { CollectionViewType } from "../views/collections/CollectionView"; +import { ContextMenu } from "../views/ContextMenu"; import { DocumentView } from "../views/nodes/DocumentView"; import { FormattedTextBox } from "../views/nodes/FormattedTextBox"; import { DocumentManager } from "./DocumentManager"; import ParagraphNodeSpec from "./ParagraphNodeSpec"; import { Transform } from "./Transform"; import React = require("react"); -import { CollectionSchemaBooleanCell } from "../views/collections/CollectionSchemaCells"; -import { ContextMenu } from "../views/ContextMenu"; -import { ContextMenuProps } from "../views/ContextMenuItem"; -import { Docs } from "../documents/Documents"; -import { CollectionView, CollectionViewType } from "../views/collections/CollectionView"; -import { toBlob } from "html-to-image"; -import { listSpec } from "../../new_fields/Schema"; -import { List } from "../../new_fields/List"; -import { SchemaHeaderField } from "../../new_fields/SchemaHeaderField"; const blockquoteDOM: DOMOutputSpecArray = ["blockquote", 0], hrDOM: DOMOutputSpecArray = ["hr"], preDOM: DOMOutputSpecArray = ["pre", ["code", 0]], brDOM: DOMOutputSpecArray = ["br"], ulDOM: DOMOutputSpecArray = ["ul", 0]; @@ -839,8 +836,8 @@ export class DashDocView { zoomToScale={emptyFunction} getScale={returnOne} dontRegisterView={false} - ContainingCollectionView={undefined} - ContainingCollectionDoc={undefined} + ContainingCollectionView={this._textBox.props.ContainingCollectionView} + ContainingCollectionDoc={this._textBox.props.ContainingCollectionDoc} ContentScaling={this.contentScaling} />, this._dashSpan); if (node.attrs.width !== dashDoc._width + "px" || node.attrs.height !== dashDoc._height + "px") { @@ -863,6 +860,7 @@ export class DashFieldView { _fieldWrapper: HTMLDivElement; // container for label and value _labelSpan: HTMLSpanElement; // field label _fieldSpan: HTMLDivElement; // field value + _enumerables: HTMLDivElement; // field value _reactionDisposer: IReactionDisposer | undefined; _textBoxDoc: Doc; @observable _dashDoc: Doc | undefined; @@ -879,6 +877,19 @@ export class DashFieldView { this._fieldWrapper.style.display = "inline-block"; const self = this; + this._enumerables = document.createElement("div"); + this._enumerables.style.width = "10px"; + 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(); + const collview = await Doc.addEnumerationToTextField(self._textBoxDoc, node.attrs.fieldKey, [Docs.Create.TextDocument(self._fieldSpan.innerText, { title: self._fieldSpan.innerText })]); + collview instanceof Doc && tbox.props.addDocTab(collview, "onRight"); + } + this._fieldSpan = document.createElement("div"); this._fieldSpan.id = Utils.GenerateGuid(); this._fieldSpan.contentEditable = "true"; @@ -888,7 +899,10 @@ export class DashFieldView { this._fieldSpan.style.backgroundColor = "rgba(155, 155, 155, 0.24)"; this._fieldSpan.onkeypress = function (e: any) { e.stopPropagation(); }; this._fieldSpan.onkeyup = function (e: any) { e.stopPropagation(); }; - this._fieldSpan.onmousedown = function (e: any) { e.stopPropagation(); }; + this._fieldSpan.onmousedown = function (e: any) { + e.stopPropagation(); + self._enumerables.style.display = "inline-block"; + }; this._fieldSpan.oncontextmenu = function (e: any) { ContextMenu.Instance.addItem({ description: "Show Enumeration Templates", event: () => { @@ -898,15 +912,17 @@ export class DashFieldView { }); }; this._fieldSpan.onblur = function (e: any) { + self._enumerables.style.display = "none"; let newText = self._fieldSpan.innerText.startsWith(":=") ? ":=-computed-" : self._fieldSpan.innerText; + // look for a document whose id === the fieldKey being displayed. If there's a match, then that document // holds the different enumerated values for the field in the titles of its collected documents. // if there's a partial match from the start of the input text, complete the text --- TODO: make this an auto suggest box and select from a drop down. - - // alternatively, if the text starts with a ':=' then treat it as an expression by making a computed field from its value storing it in the key DocServer.GetRefField(node.attrs.fieldKey).then(options => { (options instanceof Doc) && DocListCast(options.data).forEach(opt => StrCast(opt.title).startsWith(newText) && (newText = StrCast(opt.title))); self._fieldSpan.innerHTML = self._dashDoc![self._fieldKey] = newText; + + // if the text starts with a ':=' then treat it as an expression by making a computed field from its value storing it in the key if (newText.startsWith(":=") && self._dashDoc && e.data === null && !e.inputType.includes("delete")) { Doc.Layout(tbox.props.Document)[self._fieldKey] = ComputedField.MakeFunction(self._fieldSpan.innerText.substring(2)); } @@ -947,8 +963,12 @@ export class DashFieldView { this._labelSpan.title = "click to see related tags"; this._labelSpan.onpointerdown = function (e: any) { e.stopPropagation(); - if (tbox.props.ContainingCollectionDoc) { - const alias = Doc.MakeAlias(tbox.props.ContainingCollectionDoc); + let container = tbox.props.ContainingCollectionView; + while (container?.props.Document.isTemplateForField || container?.props.Document.isTemplateDoc) { + container = container.props.ContainingCollectionView; + } + if (container) { + const alias = Doc.MakeAlias(container.props.Document); alias.viewType = CollectionViewType.Time; let list = Cast(alias.schemaColumns, listSpec(SchemaHeaderField)); if (!list) { @@ -974,6 +994,7 @@ export class DashFieldView { this._fieldWrapper.appendChild(this._labelSpan); this._fieldWrapper.appendChild(this._fieldSpan); + this._fieldWrapper.appendChild(this._enumerables); (this as any).dom = this._fieldWrapper; } destroy() { diff --git a/src/client/views/DocumentDecorations.scss b/src/client/views/DocumentDecorations.scss index 1992c5efa..fdf7c3f42 100644 --- a/src/client/views/DocumentDecorations.scss +++ b/src/client/views/DocumentDecorations.scss @@ -27,6 +27,17 @@ $linkGap : 3px; opacity: 1; } + .documentDecorations-selector { + pointer-events: auto; + height: 15px; + width: 15px; + left: -20px; + top: 20px; + display: inline-block; + position: absolute; + opacity: 0.5; + } + .documentDecorations-radius { pointer-events: auto; background: black; diff --git a/src/client/views/DocumentDecorations.tsx b/src/client/views/DocumentDecorations.tsx index 4922411e8..c98be0d4a 100644 --- a/src/client/views/DocumentDecorations.tsx +++ b/src/client/views/DocumentDecorations.tsx @@ -8,7 +8,7 @@ import { PositionDocument } from '../../new_fields/documentSchemas'; import { ScriptField } from '../../new_fields/ScriptField'; import { Cast, StrCast, NumCast } from "../../new_fields/Types"; import { CurrentUserUtils } from '../../server/authentication/models/current_user_utils'; -import { Utils, setupMoveUpEvents } from "../../Utils"; +import { Utils, setupMoveUpEvents, emptyFunction, returnFalse } from "../../Utils"; import { DocUtils } from "../documents/Documents"; import { DocumentType } from '../documents/DocumentTypes'; import { DragManager } from "../util/DragManager"; @@ -244,6 +244,16 @@ export class DocumentDecorations extends React.Component<{}, { value: string }> SelectionManager.DeselectAll(); } + @action + onSelectorUp = (e: React.PointerEvent): void => { + setupMoveUpEvents(this, e, returnFalse, emptyFunction, action((e) => { + const selDoc = SelectionManager.SelectedDocuments()?.[0]; + if (selDoc) { + selDoc.props.ContainingCollectionView?.props.select(false); + } + })); + } + @action onRadiusDown = (e: React.PointerEvent): void => { setupMoveUpEvents(this, e, this.onRadiusMove, (e) => this._resizeUndo?.end(), (e) => { }); @@ -496,6 +506,10 @@ export class DocumentDecorations extends React.Component<{}, { value: string }> onPointerDown={this.onPointerDown} onContextMenu={(e) => e.preventDefault()}>
e.preventDefault()}>
+ {seldoc.props.renderDepth <= 1 || !seldoc.props.ContainingCollectionView ? (null) :
e.preventDefault()}> + +
}
e.preventDefault()}>
diff --git a/src/client/views/collections/CollectionLinearView.tsx b/src/client/views/collections/CollectionLinearView.tsx index 9384eb381..79ec6d518 100644 --- a/src/client/views/collections/CollectionLinearView.tsx +++ b/src/client/views/collections/CollectionLinearView.tsx @@ -77,7 +77,7 @@ export class CollectionLinearView extends CollectionSubView(LinearDocument) { getTransform = (ele: React.RefObject) => () => { if (!ele.current) return Transform.Identity(); const { scale, translateX, translateY } = Utils.GetScreenTransform(ele.current); - return new Transform(-translateX, -translateY, 1 / scale); + return new Transform(-translateX, -translateY, 1); } render() { diff --git a/src/new_fields/Doc.ts b/src/new_fields/Doc.ts index 0f3896055..6d94f050c 100644 --- a/src/new_fields/Doc.ts +++ b/src/new_fields/Doc.ts @@ -865,25 +865,25 @@ export namespace Doc { return (await DocServer.GetRefField(enumeratedFieldKey)) as Doc; } - export function addEnumerationToTextField(doc: Opt, enumeratedFieldKey: string, enumeratedDocs: Doc[]) { - DocServer.GetRefField(enumeratedFieldKey).then(optionsCollection => { - if (!(optionsCollection instanceof Doc)) { - optionsCollection = Docs.Create.StackingDocument([], { title: `${enumeratedFieldKey} field set` }, enumeratedFieldKey); - Doc.AddDocToList((Doc.UserDoc().fieldTypes as Doc), "data", optionsCollection as Doc); + export async function addEnumerationToTextField(doc: Opt, enumeratedFieldKey: string, enumeratedDocs: Doc[]) { + let optionsCollection = await DocServer.GetRefField(enumeratedFieldKey); + if (!(optionsCollection instanceof Doc)) { + optionsCollection = Docs.Create.StackingDocument([], { title: `${enumeratedFieldKey} field set` }, enumeratedFieldKey); + Doc.AddDocToList((Doc.UserDoc().fieldTypes as Doc), "data", optionsCollection as Doc); + } + const options = optionsCollection as Doc; + doc && (Doc.GetProto(doc).backgroundColor = ComputedField.MakeFunction(`options.data.find(doc => doc.title === (this.expandedTemplate||this).${enumeratedFieldKey})?._backgroundColor || "white"`, undefined, { options })); + doc && (Doc.GetProto(doc).color = ComputedField.MakeFunction(`options.data.find(doc => doc.title === (this.expandedTemplate||this).${enumeratedFieldKey}).color || "black"`, undefined, { options })); + enumeratedDocs.map(enumeratedDoc => { + const found = DocListCast(options.data).find(d => d.title === enumeratedDoc.title); + if (found) { + found._backgroundColor = enumeratedDoc._backgroundColor || found._backgroundColor; + found._color = enumeratedDoc._color || found._color; + } else { + Doc.AddDocToList(options, "data", enumeratedDoc); } - const options = optionsCollection as Doc; - doc && (Doc.GetProto(doc).backgroundColor = ComputedField.MakeFunction(`options.data.find(doc => doc.title === (this.expandedTemplate||this).${enumeratedFieldKey})?._backgroundColor || "white"`, undefined, { options })); - doc && (Doc.GetProto(doc).color = ComputedField.MakeFunction(`options.data.find(doc => doc.title === (this.expandedTemplate||this).${enumeratedFieldKey}).color || "black"`, undefined, { options })); - enumeratedDocs.map(enumeratedDoc => { - const found = DocListCast(options.data).find(d => d.title === enumeratedDoc.title); - if (found) { - found._backgroundColor = enumeratedDoc._backgroundColor || found._backgroundColor; - found._color = enumeratedDoc._color || found._color; - } else { - Doc.AddDocToList(options, "data", enumeratedDoc); - } - }); }); + return optionsCollection; } } -- cgit v1.2.3-70-g09d2 From 15d332d4167a1b021087cec78a45d96b526b02d9 Mon Sep 17 00:00:00 2001 From: Bob Zeleznik Date: Tue, 3 Mar 2020 21:40:09 -0500 Subject: make sure doc decorations is behind doc button bar flyouts --- src/client/views/DocumentDecorations.scss | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/client/views/DocumentDecorations.scss') diff --git a/src/client/views/DocumentDecorations.scss b/src/client/views/DocumentDecorations.scss index fdf7c3f42..8d6002f8f 100644 --- a/src/client/views/DocumentDecorations.scss +++ b/src/client/views/DocumentDecorations.scss @@ -188,7 +188,7 @@ $linkGap : 3px; height: auto; display: flex; flex-direction: row; - z-index: 5; + z-index: 998; position: absolute; } -- cgit v1.2.3-70-g09d2 From 786572f3cd674459f55b7f66e8eb257026f373ef Mon Sep 17 00:00:00 2001 From: Bob Zeleznik Date: Mon, 23 Mar 2020 21:24:50 -0400 Subject: fixed RichTextMenu to not obscure selection. fixed templateMenu to display a TreeView document of options. fixed resize in docDecorations for dragging corners other than bottom-right. --- src/client/util/DropConverter.ts | 2 +- src/client/views/DocumentButtonBar.tsx | 4 +- src/client/views/DocumentDecorations.scss | 3 + src/client/views/DocumentDecorations.tsx | 6 +- src/client/views/TemplateMenu.tsx | 94 ++++++++++++++++++---- .../views/collections/CollectionDockingView.tsx | 27 +++++-- .../views/collections/CollectionLinearView.tsx | 20 ++--- .../views/collections/CollectionTreeView.scss | 1 + .../views/collections/CollectionTreeView.tsx | 7 +- .../views/collections/ParentDocumentSelector.tsx | 22 ++--- .../collections/collectionFreeForm/MarqueeView.tsx | 12 ++- src/client/views/nodes/DocumentView.tsx | 15 ++-- src/client/views/nodes/FormattedTextBox.tsx | 25 ++++-- src/client/views/search/SearchItem.tsx | 2 +- src/new_fields/Doc.ts | 2 - src/new_fields/ScriptField.ts | 4 +- src/new_fields/util.ts | 1 - .../authentication/models/current_user_utils.ts | 16 +++- 18 files changed, 189 insertions(+), 74 deletions(-) (limited to 'src/client/views/DocumentDecorations.scss') diff --git a/src/client/util/DropConverter.ts b/src/client/util/DropConverter.ts index 861cde5de..a6a43d06a 100644 --- a/src/client/util/DropConverter.ts +++ b/src/client/util/DropConverter.ts @@ -49,7 +49,7 @@ export function convertDropDataToButtons(data: DragManager.DocumentDragData) { (layoutDoc.layout instanceof Doc) && !data.userDropAction; } layoutDoc.isTemplateDoc = true; - dbox = Docs.Create.FontIconDocument({ _nativeWidth: 100, _nativeHeight: 100, _width: 100, _height: 100, backgroundColor: StrCast(doc.backgroundColor), title: "Custom", icon: layoutDoc.isTemplateDoc ? "font" : "bolt" }); + dbox = Docs.Create.FontIconDocument({ _nativeWidth: 100, _nativeHeight: 100, _width: 100, _height: 100, backgroundColor: StrCast(doc.backgroundColor), title: StrCast(layoutDoc.title), icon: layoutDoc.isTemplateDoc ? "font" : "bolt" }); dbox.dragFactory = layoutDoc; dbox.removeDropProperties = doc.removeDropProperties instanceof ObjectField ? ObjectField.MakeCopy(doc.removeDropProperties) : undefined; dbox.onDragStart = ScriptField.MakeFunction('getCopy(this.dragFactory, true)'); diff --git a/src/client/views/DocumentButtonBar.tsx b/src/client/views/DocumentButtonBar.tsx index 23875fa33..8a33232b4 100644 --- a/src/client/views/DocumentButtonBar.tsx +++ b/src/client/views/DocumentButtonBar.tsx @@ -108,7 +108,7 @@ export class DocumentButtonBar extends React.Component<{ views: (DocumentView | this._pullColorAnimating = false; }); - get view0() { return this.props.views && this.props.views.length ? this.props.views[0] : undefined; } + get view0() { return this.props.views?.[0]; } @action onLinkButtonMoved = (e: PointerEvent): void => { @@ -250,7 +250,7 @@ export class DocumentButtonBar extends React.Component<{ views: (DocumentView | @computed get contextButton() { - return !this.view0 ? (null) : v).map(v => v as DocumentView)} Document={this.view0.props.Document} addDocTab={(doc, where) => { + return !this.view0 ? (null) : { where === "onRight" ? CollectionDockingView.AddRightSplit(doc) : this.props.stack ? CollectionDockingView.Instance.AddTab(this.props.stack, doc) : this.view0?.props.addDocTab(doc, "onRight"); diff --git a/src/client/views/DocumentDecorations.scss b/src/client/views/DocumentDecorations.scss index 8d6002f8f..353520026 100644 --- a/src/client/views/DocumentDecorations.scss +++ b/src/client/views/DocumentDecorations.scss @@ -80,6 +80,7 @@ $linkGap : 3px; #documentDecorations-topLeftResizer, #documentDecorations-bottomRightResizer { cursor: nwse-resize; + background: dimGray; } #documentDecorations-bottomRightResizer { @@ -89,6 +90,7 @@ $linkGap : 3px; #documentDecorations-topRightResizer, #documentDecorations-bottomLeftResizer { cursor: nesw-resize; + background: dimGray; } #documentDecorations-topResizer, @@ -158,6 +160,7 @@ $linkGap : 3px; padding-top: 5px; width: $MINIMIZED_ICON_SIZE; height: $MINIMIZED_ICON_SIZE; + max-height: 20px; } .documentDecorations-background { diff --git a/src/client/views/DocumentDecorations.tsx b/src/client/views/DocumentDecorations.tsx index c4abc935f..ff72592d8 100644 --- a/src/client/views/DocumentDecorations.tsx +++ b/src/client/views/DocumentDecorations.tsx @@ -266,7 +266,7 @@ export class DocumentDecorations extends React.Component<{}, { value: string }> let dist = Math.sqrt((e.clientX - down[0]) * (e.clientX - down[0]) + (e.clientY - down[1]) * (e.clientY - down[1])); dist = dist < 3 ? 0 : dist; SelectionManager.SelectedDocuments().map(dv => dv.props.Document).map(doc => doc.layout instanceof Doc ? doc.layout : doc.isTemplateForField ? doc : Doc.GetProto(doc)). - map(d => d.borderRounding = `${Math.max(0, dist)}px`); + map(d => d.borderRounding = `${Math.max(0, dist)}%`); return false; } @@ -330,6 +330,10 @@ export class DocumentDecorations extends React.Component<{}, { value: string }> const width = (layoutDoc._width || 0); const height = (layoutDoc._height || (nheight / nwidth * width)); const scale = element.props.ScreenToLocalTransform().Scale * element.props.ContentScaling(); + if (nwidth && nheight) { + if (Math.abs(dW) > Math.abs(dH)) dH = dW * nheight / nwidth; + else dW = dH * nwidth / nheight; + } const actualdW = Math.max(width + (dW * scale), 20); const actualdH = Math.max(height + (dH * scale), 20); doc.x = (doc.x || 0) + dX * (actualdW - width); diff --git a/src/client/views/TemplateMenu.tsx b/src/client/views/TemplateMenu.tsx index 5029b4074..cf6ce2c6f 100644 --- a/src/client/views/TemplateMenu.tsx +++ b/src/client/views/TemplateMenu.tsx @@ -1,4 +1,4 @@ -import { action, observable, runInAction, ObservableSet } from "mobx"; +import { action, observable, runInAction, ObservableSet, trace, computed } from "mobx"; import { observer } from "mobx-react"; import { SelectionManager } from "../util/SelectionManager"; import { undoBatch } from "../util/UndoManager"; @@ -7,8 +7,13 @@ import { DocumentView } from "./nodes/DocumentView"; import { Template } from "./Templates"; import React = require("react"); import { Doc, DocListCast } from "../../new_fields/Doc"; +import { Docs, } from "../documents/Documents"; import { StrCast, Cast } from "../../new_fields/Types"; -import { CurrentUserUtils } from "../../server/authentication/models/current_user_utils"; +import { CollectionTreeView } from "./collections/CollectionTreeView"; +import { returnTrue, emptyFunction, returnFalse, returnOne, emptyPath } from "../../Utils"; +import { Transform } from "../util/Transform"; +import { ScriptField, ComputedField } from "../../new_fields/ScriptField"; +import { Scripting } from "../util/Scripting"; @observer class TemplateToggle extends React.Component<{ template: Template, checked: boolean, toggle: (event: React.ChangeEvent, template: Template) => void }> { @@ -50,7 +55,10 @@ export class TemplateMenu extends React.Component { @observable private _hidden: boolean = true; toggleLayout = (e: React.ChangeEvent, layout: string): void => { - this.props.docViews.map(dv => dv.switchViews(e.target.checked, layout));//.setCustomView(e.target.checked, layout)); + this.props.docViews.map(dv => dv.switchViews(e.target.checked, layout)); + } + toggleDefault = (e: React.ChangeEvent): void => { + this.props.docViews.map(dv => dv.switchViews(false, "layout")); } toggleFloat = (e: React.ChangeEvent): void => { @@ -94,27 +102,81 @@ export class TemplateMenu extends React.Component { Array.from(Object.keys(Doc.GetProto(this.props.docViews[0].props.Document))). filter(key => key.startsWith("layout_")). map(key => runInAction(() => this._addedKeys.add(key.replace("layout_", "")))); - DocListCast(Cast(CurrentUserUtils.UserDocument.expandingButtons, Doc, null)?.data)?.map(btnDoc => { - if (StrCast(Cast(btnDoc?.dragFactory, Doc, null)?.title)) { - runInAction(() => this._addedKeys.add(StrCast(Cast(btnDoc?.dragFactory, Doc, null)?.title))); - } - }); } + 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 }); + } render() { - const layout = Doc.Layout(this.props.docViews[0].Document); + const firstDoc = this.props.docViews[0].props.Document; + const templateName = StrCast(firstDoc.layoutKey, "layout").replace("layout_", ""); + const noteTypesDoc = Cast(Doc.UserDoc().noteTypes, Doc, null); + const noteTypes = DocListCast(noteTypesDoc?.data); + const addedTypes = DocListCast(Cast(Doc.UserDoc().templateButtons, Doc, null)?.data) + const layout = Doc.Layout(firstDoc); const templateMenu: Array = []; this.props.templates.forEach((checked, template) => templateMenu.push()); - templateMenu.push(); - templateMenu.push(); + templateMenu.push(); + templateMenu.push(); templateMenu.push(); - this._addedKeys && Array.from(this._addedKeys).map(layout => - templateMenu.push( this.toggleLayout(e, layout)} />) - ); + templateMenu.push(); + if (noteTypesDoc) { + addedTypes.concat(noteTypes).map(template => template.treeViewChecked = ComputedField.MakeFunction("templateIsUsed(this, firstDoc)", { firstDoc: "string" }, { firstDoc: StrCast(firstDoc.title) })); + this._addedKeys && Array.from(this._addedKeys).filter(key => !noteTypes.some(nt => nt.title === key)).forEach(template => templateMenu.push( + this.toggleLayout(e, template)} />)); + templateMenu.push( + false} + removeDocument={(doc: Doc) => false} + addDocument={(doc: Doc) => false} /> + ); + } return
    - {templateMenu} + {templateMenu}
; } -} \ No newline at end of file +} + +Scripting.addGlobal(function switchView(doc: Doc, template: Doc) { + if (template.dragFactory) { + template = Cast(template.dragFactory, Doc, null); + } + let templateTitle = StrCast(template?.title); + return templateTitle && DocumentView.makeCustomViewClicked(doc, undefined, Docs.Create.FreeformDocument, templateTitle, template) +}); + +Scripting.addGlobal(function templateIsUsed(templateDoc: Doc, firstDocTitlte: string) { + const firstDoc = SelectionManager.SelectedDocuments()[0].props.Document; + const template = StrCast(templateDoc.dragFactory ? Cast(templateDoc.dragFactory, Doc, null)?.title : templateDoc.title); + return StrCast(firstDoc.layoutKey) === "layout_" + template ? 'check' : 'unchecked'; + // return SelectionManager.SelectedDocuments().some(view => StrCast(view.props.Document.layoutKey) === "layout_" + template) ? 'check' : 'unchecked' +}) \ No newline at end of file diff --git a/src/client/views/collections/CollectionDockingView.tsx b/src/client/views/collections/CollectionDockingView.tsx index 00e22d6fb..1fb78f625 100644 --- a/src/client/views/collections/CollectionDockingView.tsx +++ b/src/client/views/collections/CollectionDockingView.tsx @@ -2,7 +2,7 @@ import { library } from '@fortawesome/fontawesome-svg-core'; import { faFile } from '@fortawesome/free-solid-svg-icons'; import 'golden-layout/src/css/goldenlayout-base.css'; import 'golden-layout/src/css/goldenlayout-dark-theme.css'; -import { action, computed, Lambda, observable, reaction, runInAction } from "mobx"; +import { action, computed, Lambda, observable, reaction, runInAction, trace } from "mobx"; import { observer } from "mobx-react"; import * as ReactDOM from 'react-dom'; import Measure from "react-measure"; @@ -20,7 +20,7 @@ import { DocServer } from "../../DocServer"; import { Docs } from '../../documents/Documents'; import { DocumentType } from '../../documents/DocumentTypes'; import { DocumentManager } from '../../util/DocumentManager'; -import { DragManager } from "../../util/DragManager"; +import { DragManager, dropActionType } from "../../util/DragManager"; import { Scripting } from '../../util/Scripting'; import { SelectionManager } from '../../util/SelectionManager'; import { Transform } from '../../util/Transform'; @@ -504,15 +504,25 @@ export class CollectionDockingView extends React.Component { + const onDown = (e: React.PointerEvent) => { + if (!(e.nativeEvent as any).defaultPrevented) { e.preventDefault(); e.stopPropagation(); const dragData = new DragManager.DocumentDragData([doc]); - dragData.dropAction = doc.dropAction === "alias" ? "alias" : doc.dropAction === "copy" ? "copy" : undefined; + dragData.dropAction = doc.dropAction as dropActionType; DragManager.StartDocumentDrag([gearSpan], dragData, e.clientX, e.clientY); - }}>, gearSpan); + } + } + let rendered = false; + tab.buttonDisposer = reaction(() => ((view: Opt) => view ? [view] : [])(DocumentManager.Instance.getDocumentView(doc)), + (views) => { + !rendered && ReactDOM.render( + + , + gearSpan); + rendered = true; + }); + tab.reactComponents = [gearSpan]; tab.element.append(gearSpan); tab.reactionDisposer = reaction(() => ({ title: doc.title, degree: Doc.IsBrushedDegree(doc) }), ({ title, degree }) => { @@ -526,7 +536,8 @@ export class CollectionDockingView extends React.Component this.isCurrent(pair.layout)).map((pair, ind) => { + this.childLayoutPairs.map((pair, ind) => { Cast(pair.layout.proto?.onPointerUp, ScriptField)?.script.run({ this: pair.layout.proto }, console.log); }); } @@ -48,7 +48,7 @@ export class CollectionLinearView extends CollectionSubView(LinearDocument) { (i) => runInAction(() => { this._selectedIndex = i; let selected: any = undefined; - this.childLayoutPairs.filter((pair) => this.isCurrent(pair.layout)).map(async (pair, ind) => { + this.childLayoutPairs.map(async (pair, ind) => { const isSelected = this._selectedIndex === ind; if (isSelected) { selected = pair; @@ -71,8 +71,6 @@ export class CollectionLinearView extends CollectionSubView(LinearDocument) { } } - public isCurrent(doc: Doc) { return (Math.abs(NumCast(doc.displayTimecode, -1) - NumCast(this.Document.currentTimecode, -1)) < 1.5 || NumCast(doc.displayTimecode, -1) === -1); } - dimension = () => NumCast(this.props.Document._height); // 2 * the padding getTransform = (ele: React.RefObject) => () => { if (!ele.current) return Transform.Identity(); @@ -87,17 +85,21 @@ export class CollectionLinearView extends CollectionSubView(LinearDocument) {
this.props.Document.linearViewIsExpanded = this.addMenuToggle.current!.checked)} /> - + -
- {this.childLayoutPairs.filter((pair) => this.isCurrent(pair.layout)).map((pair, ind) => { +
+ {this.childLayoutPairs.map((pair, ind) => { const nested = pair.layout._viewType === CollectionViewType.Linear; const dref = React.createRef(); const nativeWidth = NumCast(pair.layout._nativeWidth, this.dimension()); const deltaSize = nativeWidth * .15 / 2; - return
this._mainEle && this._mainEle.scrollHeight > this._mainEle.clientHeight && e.stopPropagation()} onDrop={this.onTreeDrop} diff --git a/src/client/views/collections/ParentDocumentSelector.tsx b/src/client/views/collections/ParentDocumentSelector.tsx index 43ba5c614..35e3a8958 100644 --- a/src/client/views/collections/ParentDocumentSelector.tsx +++ b/src/client/views/collections/ParentDocumentSelector.tsx @@ -2,7 +2,7 @@ import * as React from "react"; import './ParentDocumentSelector.scss'; import { Doc } from "../../../new_fields/Doc"; import { observer } from "mobx-react"; -import { observable, action, runInAction } from "mobx"; +import { observable, action, runInAction, trace, computed } from "mobx"; import { Id } from "../../../new_fields/FieldSymbols"; import { SearchUtil } from "../../util/SearchUtil"; import { CollectionDockingView } from "./CollectionDockingView"; @@ -14,6 +14,7 @@ import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; import { faCog, faChevronCircleUp } from "@fortawesome/free-solid-svg-icons"; import { library } from "@fortawesome/fontawesome-svg-core"; import { DocumentView } from "../nodes/DocumentView"; +import { SelectionManager } from "../../util/SelectionManager"; const higflyout = require("@hig/flyout"); export const { anchorPoints } = higflyout; export const Flyout = higflyout.default; @@ -22,7 +23,6 @@ library.add(faCog); type SelectorProps = { Document: Doc, - Views: DocumentView[], Stack?: any, addDocTab(doc: Doc, location: string): void }; @@ -93,7 +93,7 @@ export class ParentDocSelector extends React.Component { } @observer -export class DockingViewButtonSelector extends React.Component<{ Document: Doc, Stack: any }> { +export class DockingViewButtonSelector extends React.Component<{ views: DocumentView[], Stack: any }> { @observable hover = false; customStylesheet(styles: any) { @@ -106,15 +106,19 @@ export class DockingViewButtonSelector extends React.Component<{ Document: Doc, }; } - render() { - const view = DocumentManager.Instance.getDocumentView(this.props.Document); - const flyout = ( + @computed get flyout() { + trace(); + return (
- +
); - return !this.props.Stack && e.stopPropagation()} className="buttonSelector"> - + } + + render() { + trace(); + return { this.props.views[0].select(false); e.stopPropagation(); }} className="buttonSelector"> + ; diff --git a/src/client/views/collections/collectionFreeForm/MarqueeView.tsx b/src/client/views/collections/collectionFreeForm/MarqueeView.tsx index 4bf3329eb..17bba9568 100644 --- a/src/client/views/collections/collectionFreeForm/MarqueeView.tsx +++ b/src/client/views/collections/collectionFreeForm/MarqueeView.tsx @@ -107,8 +107,14 @@ export class MarqueeView extends React.Component(Docu static makeCustomViewClicked = (doc: Doc, dataDoc: Opt, creator: (documents: Array, options: DocumentOptions, id?: string) => Doc, name: string = "custom", docLayoutTemplate?: Doc) => { const batch = UndoManager.StartBatch("CustomViewClicked"); const customName = "layout_" + name; - if (!StrCast(doc.title).endsWith(name)) doc.title = doc.title + "_" + name; if (doc[customName] === undefined) { const _width = NumCast(doc._width); const _height = NumCast(doc._height); @@ -634,13 +633,15 @@ export class DocumentView extends DocComponent(Docu // } else if (custom) { DocumentView.makeNativeViewClicked(this.props.Document); + const userDoc = Doc.UserDoc(); - const imgView = Cast(Doc.UserDoc().iconView, Doc, null); - const iconImgView = Cast(Doc.UserDoc().iconImageView, Doc, null); - const iconColView = Cast(Doc.UserDoc().iconColView, Doc, null); + const imgView = Cast(userDoc.iconView, Doc, null); + const iconImgView = Cast(userDoc.iconImageView, Doc, null); + const iconColView = Cast(userDoc.iconColView, Doc, null); const iconViews = [imgView, iconImgView, iconColView]; - const expandingButtons = DocListCast(Cast(Doc.UserDoc().expandingButtons, Doc, null)?.data); - const allTemplates = iconViews.concat(expandingButtons); + const templateButtons = DocListCast(Cast(userDoc.templateButtons, Doc, null)?.data); + const noteTypes = DocListCast(Cast(userDoc.noteTypes, Doc, null)?.data); + const allTemplates = iconViews.concat(templateButtons).concat(noteTypes); let foundLayout: Opt; allTemplates.map(btnDoc => (btnDoc.dragFactory as Doc) || btnDoc).filter(doc => doc.isTemplateDoc).forEach(tempDoc => { if (StrCast(tempDoc.title) === this.props.Document.type + "_" + layout) { @@ -1028,7 +1029,7 @@ export class DocumentView extends DocComponent(Docu
); const captionView = (!showCaption ? (null) :
- { this.ProseRef = ele; - this.dropDisposer && this.dropDisposer(); + this.dropDisposer?.(); ele && (this.dropDisposer = DragManager.MakeDropTarget(ele, this.drop.bind(this))); } @@ -386,9 +387,14 @@ export class FormattedTextBox extends DocAnnotatableComponent<(FieldViewProps & } specificContextMenu = (e: React.MouseEvent): void => { const funcs: ContextMenuProps[] = []; - this.props.Document.isTemplateDoc && funcs.push({ description: "Make Default Layout", event: async () => Doc.UserDoc().defaultTextLayout = new PrefetchProxy(this.props.Document.proto as Doc), icon: "eye" }); + this.props.Document.isTemplateDoc && funcs.push({ description: "Make Default Layout", event: async () => Doc.UserDoc().defaultTextLayout = new PrefetchProxy(this.props.Document), icon: "eye" }); funcs.push({ description: "Reset Default Layout", event: () => Doc.UserDoc().defaultTextLayout = undefined, icon: "eye" }); - !this.props.Document.expandedTemplate && funcs.push({ description: "Make Template", event: () => { this.props.Document.isTemplateDoc = true; Doc.AddDocToList(Cast(Doc.UserDoc().noteTypes, Doc, null), "data", this.props.Document); }, icon: "eye" }); + !this.props.Document.expandedTemplate && funcs.push({ + description: "Make Template", event: () => { + this.props.Document.isTemplateDoc = makeTemplate(this.props.Document, true); + Doc.AddDocToList(Cast(Doc.UserDoc().noteTypes, Doc, null), "data", this.props.Document); + }, icon: "eye" + }); funcs.push({ description: "Toggle Single Line", event: () => this.props.Document._singleLine = !this.props.Document._singleLine, icon: "expand-arrows-alt" }); funcs.push({ description: "Toggle Sidebar", event: () => this.props.Document._showSidebar = !this.props.Document._showSidebar, icon: "expand-arrows-alt" }); funcs.push({ description: "Toggle Audio", event: () => this.props.Document._showAudio = !this.props.Document._showAudio, icon: "expand-arrows-alt" }); @@ -901,6 +907,7 @@ export class FormattedTextBox extends DocAnnotatableComponent<(FieldViewProps & if (e.buttons === 1 && this.props.isSelected(true) && !e.altKey) { e.stopPropagation(); } + this._downX = this._downY = Number.NaN; } @action @@ -914,12 +921,16 @@ export class FormattedTextBox extends DocAnnotatableComponent<(FieldViewProps & prosediv && (prosediv.keeplocation = undefined); const pos = this._editorView?.state.selection.$from.pos || 1; keeplocation && setTimeout(() => this._editorView?.dispatch(this._editorView?.state.tr.setSelection(TextSelection.create(this._editorView.state.doc, pos)))); + const coords = !Number.isNaN(this._downX) ? { left: this._downX, top: this._downY, bottom: this._downY, right: this._downX } : this._editorView?.coordsAtPos(pos); // jump rich text menu to this textbox - const { current } = this._ref; - if (current && this.props.Document._chromeStatus !== "disabled") { - const x = Math.min(Math.max(current.getBoundingClientRect().left, 0), window.innerWidth - RichTextMenu.Instance.width); - const y = this._ref.current!.getBoundingClientRect().top - RichTextMenu.Instance.height - 50; + const bounds = this._ref.current?.getBoundingClientRect(); + if (bounds && this.props.Document._chromeStatus !== "disabled") { + const x = Math.min(Math.max(bounds.left, 0), window.innerWidth - RichTextMenu.Instance.width); + let y = Math.min(Math.max(0, bounds.top - RichTextMenu.Instance.height - 50), window.innerHeight - RichTextMenu.Instance.height); + if (coords && coords.left > x && coords.left < x + RichTextMenu.Instance.width && coords.top > y && coords.top < y + RichTextMenu.Instance.height + 50) { + y = Math.min(bounds.bottom, window.innerHeight - RichTextMenu.Instance.height); + } RichTextMenu.Instance.jumpTo(x, y); } } diff --git a/src/client/views/search/SearchItem.tsx b/src/client/views/search/SearchItem.tsx index 2cbb24da7..63cef5101 100644 --- a/src/client/views/search/SearchItem.tsx +++ b/src/client/views/search/SearchItem.tsx @@ -272,7 +272,7 @@ export class SearchItem extends React.Component { @computed get contextButton() { - return CollectionDockingView.AddRightSplit(doc)} />; + return CollectionDockingView.AddRightSplit(doc)} />; } render() { diff --git a/src/new_fields/Doc.ts b/src/new_fields/Doc.ts index 50adf0392..322b57272 100644 --- a/src/new_fields/Doc.ts +++ b/src/new_fields/Doc.ts @@ -795,8 +795,6 @@ export namespace Doc { const prevLayout = StrCast(doc.layoutKey).split("_")[1]; const deiconify = prevLayout === "icon" && StrCast(doc.deiconifyLayout) ? "layout_" + StrCast(doc.deiconifyLayout) : ""; prevLayout === "icon" && (doc.deiconifyLayout = undefined); - if (StrCast(doc.title).endsWith("_" + prevLayout) && deiconify) doc.title = StrCast(doc.title).replace("_" + prevLayout, deiconify); - else doc.title = undefined; doc.layoutKey = deiconify || "layout"; } export function setDocFilterRange(target: Doc, key: string, range?: number[]) { diff --git a/src/new_fields/ScriptField.ts b/src/new_fields/ScriptField.ts index 9288fea9e..606f55b7c 100644 --- a/src/new_fields/ScriptField.ts +++ b/src/new_fields/ScriptField.ts @@ -119,8 +119,8 @@ export class ScriptField extends ObjectField { return compiled.compiled ? new ScriptField(compiled) : undefined; } - public static MakeScript(script: string, params: object = {}) { - const compiled = ScriptField.CompileScript(script, params, false); + public static MakeScript(script: string, params: object = {}, capturedVariables?: { [name: string]: Field }) { + const compiled = ScriptField.CompileScript(script, params, false, capturedVariables); return compiled.compiled ? new ScriptField(compiled) : undefined; } } diff --git a/src/new_fields/util.ts b/src/new_fields/util.ts index 6d7f6b56e..3ab1b299b 100644 --- a/src/new_fields/util.ts +++ b/src/new_fields/util.ts @@ -7,7 +7,6 @@ import { ObjectField } from "./ObjectField"; import { action, trace } from "mobx"; import { Parent, OnUpdate, Update, Id, SelfProxy, Self } from "./FieldSymbols"; import { DocServer } from "../client/DocServer"; -import { props } from "bluebird"; function _readOnlySetter(): never { throw new Error("Documents can't be modified in read-only mode"); diff --git a/src/server/authentication/models/current_user_utils.ts b/src/server/authentication/models/current_user_utils.ts index 31588bf82..9c39ce7de 100644 --- a/src/server/authentication/models/current_user_utils.ts +++ b/src/server/authentication/models/current_user_utils.ts @@ -53,7 +53,7 @@ export class CurrentUserUtils { ]; doc.fieldTypes = Docs.Create.TreeDocument([], { title: "field enumerations" }); Doc.addFieldEnumerations(Doc.GetProto(noteTemplates[4]), "taskStatus", taskStatusValues); - doc.noteTypes = new PrefetchProxy(Docs.Create.TreeDocument(noteTemplates.map(nt => makeTemplate(nt, true, StrCast(nt.style)) ? nt : nt), { title: "Note Types", _height: 75 })); + doc.noteTypes = new PrefetchProxy(Docs.Create.TreeDocument(noteTemplates.map(nt => makeTemplate(nt, true, StrCast(nt.style)) ? nt : nt), { title: "Note Layouts", _height: 75 })); } // setup the "creator" buttons for the sidebar-- eg. the default set of draggable document creation tools @@ -292,12 +292,20 @@ export class CurrentUserUtils { { _nativeWidth: 100, _nativeHeight: 100, _width: 100, _height: 100, dropAction: "alias", onDragStart: ScriptField.MakeFunction('getCopy(this.dragFactory, true)'), dragFactory: slideTemplate, removeDropProperties: new List(["dropAction"]), title: "presentation slide", icon: "sticky-note" }); doc.descriptionBtn = Docs.Create.FontIconDocument( { _nativeWidth: 100, _nativeHeight: 100, _width: 100, _height: 100, dropAction: "alias", onDragStart: ScriptField.MakeFunction('getCopy(this.dragFactory, true)'), dragFactory: descriptionTemplate, removeDropProperties: new List(["dropAction"]), title: "description view", icon: "sticky-note" }); - doc.expandingButtons = Docs.Create.LinearDocument([doc.undoBtn as Doc, doc.redoBtn as Doc, doc.slidesBtn as Doc, doc.descriptionBtn as Doc, - ...DocListCast(Cast(doc.noteTypes, Doc, null))], { + doc.templateButtons = Docs.Create.LinearDocument([doc.slidesBtn as Doc, doc.descriptionBtn as Doc], { + title: "template buttons", _gridGap: 5, _xMargin: 5, _yMargin: 5, _height: 42, _width: 100, boxShadow: "0 0", dontSelect: true, + backgroundColor: "black", treeViewPreventOpen: true, forceActive: true, lockedPosition: true, _chromeStatus: "disabled", linearViewIsExpanded: true, + dropConverter: ScriptField.MakeScript("convertToButtons(dragData)", { dragData: DragManager.DocumentDragData.name }) + }); + doc.expandingButtons = Docs.Create.LinearDocument([doc.undoBtn as Doc, doc.redoBtn as Doc, doc.templateButtons as Doc], { title: "expanding buttons", _gridGap: 5, _xMargin: 5, _yMargin: 5, _height: 42, _width: 100, boxShadow: "0 0", - backgroundColor: "black", treeViewPreventOpen: true, forceActive: true, lockedPosition: true, + backgroundColor: "black", treeViewPreventOpen: true, forceActive: true, lockedPosition: true, linearViewIsExpanded: true, dropConverter: ScriptField.MakeScript("convertToButtons(dragData)", { dragData: DragManager.DocumentDragData.name }) }); + doc.templateDocs = new PrefetchProxy(Docs.Create.TreeDocument([doc.noteTypes as Doc, doc.templateButtons as Doc], { + title: "template layouts", _xPadding: 0, dropConverter: ScriptField.MakeScript("convertToButtons(dragData)", + { dragData: DragManager.DocumentDragData.name }) + })); } // sets up the default set of documents to be shown in the Overlay layer -- cgit v1.2.3-70-g09d2