From 7c93a65535a278dd1381b27fbd4c3869eed19527 Mon Sep 17 00:00:00 2001 From: yunahi <60233430+yunahi@users.noreply.github.com> Date: Fri, 3 Jul 2020 20:22:52 +0900 Subject: pin and icon --- .../collectionFreeForm/InkOptionsMenu.scss | 5 + .../collectionFreeForm/InkOptionsMenu.tsx | 267 ++++++++++++++------- 2 files changed, 179 insertions(+), 93 deletions(-) (limited to 'src/client/views/collections/collectionFreeForm') diff --git a/src/client/views/collections/collectionFreeForm/InkOptionsMenu.scss b/src/client/views/collections/collectionFreeForm/InkOptionsMenu.scss index a9fab4c1e..7329f4fc1 100644 --- a/src/client/views/collections/collectionFreeForm/InkOptionsMenu.scss +++ b/src/client/views/collections/collectionFreeForm/InkOptionsMenu.scss @@ -26,6 +26,11 @@ /* Make the buttons appear below each other */ } +.btn-draw { + display: inline; + /* Make the buttons appear below each other */ +} + .btn2-group { display: block; background: #323232; diff --git a/src/client/views/collections/collectionFreeForm/InkOptionsMenu.tsx b/src/client/views/collections/collectionFreeForm/InkOptionsMenu.tsx index f1032adaa..7de70b8cd 100644 --- a/src/client/views/collections/collectionFreeForm/InkOptionsMenu.tsx +++ b/src/client/views/collections/collectionFreeForm/InkOptionsMenu.tsx @@ -17,6 +17,7 @@ import { DocumentType } from "../../../documents/DocumentTypes"; import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; import { IconProp, library } from '@fortawesome/fontawesome-svg-core'; import { faBold, faItalic, faChevronLeft, faUnderline, faStrikethrough, faSubscript, faSuperscript, faIndent, faEyeDropper, faCaretDown, faPalette, faArrowsAlt, faHighlighter, faLink, faPaintRoller, faSleigh, faBars, faFillDrip, faBrush, faPenNib, faShapes, faArrowLeft, faEllipsisH, faBezierCurve, } from "@fortawesome/free-solid-svg-icons"; +import { Cast, StrCast, BoolCast } from "../../../../fields/Types"; library.add(faBold, faItalic, faChevronLeft, faUnderline, faStrikethrough, faSuperscript, faSubscript, faIndent, faEyeDropper, faCaretDown, faPalette, faArrowsAlt, faHighlighter, faLink, faPaintRoller, faBars, faFillDrip, faBrush, faPenNib, faShapes, faArrowLeft, faEllipsisH, faBezierCurve); @@ -28,36 +29,67 @@ export default class InkOptionsMenu extends AntimodeMenu { private _width = ["1", "5", "10", "100"]; // private _buttons = ["circle", "triangle", "rectangle", "arrow", "line"]; // private _icons = ["O", "∆", "ロ", "➜", "-"]; - private _buttons = ["circle", "triangle", "rectangle", "line", "noRec", "",]; - private _icons = ["O", "∆", "ロ", "⎯", "✖︎", " "]; + // private _buttons = ["circle", "triangle", "rectangle", "line", "noRec", "",]; + // private _icons = ["O", "∆", "ロ", "⎯⎯⎯", "✖︎", " "]; //arrowStart and arrowEnd must match and defs must exist in Inking Stroke - private _arrowStart = ["arrowHead", "arrowHead", "dot", "dot", "none"]; - private _arrowEnd = ["none", "arrowEnd", "none", "dot", "none"]; - private _arrowIcons = ["→", "↔︎", "•", "••", " "]; + // private _arrowStart = ["arrowHead", "arrowHead", "dot", "dot", "none"]; + // private _arrowEnd = ["none", "arrowEnd", "none", "dot", "none"]; + // private _arrowIcons = ["→", "↔︎", "•", "••", " "]; + private _draw = ["⎯", "→", "↔︎", "∿", "↝", "↭", "ロ", "O", "∆"]; + private _head = ["none", "arrowHead", "arrowHead", "none", "arrowHead", "arrowHead", "none", "none", "none"]; + private _end = ["none", "none", "arrowEnd", "none", "none", "arrowEnd", "none", "none", "none"]; + private _shape = ["", "", "", "", "", "", "rectangle", "circle", "triangle"]; + + @observable _shapesNum = this._shape.length; + @observable _selected = this._shapesNum; + + @observable private collapsed: boolean = false; @observable _colorBtn = false; @observable _widthBtn = false; @observable _fillBtn = false; - @observable _arrowBtn = false; - @observable _dashBtn = false; - @observable _shapeBtn = false; + // @observable _arrowBtn = false; + // @observable _dashBtn = false; + // @observable _shapeBtn = false; constructor(props: Readonly<{}>) { super(props); InkOptionsMenu.Instance = this; this._canFade = false; // don't let the inking menu fade away + this.Pinned = BoolCast(Doc.UserDoc()["inkOptionsMenu-pinned"]); + } - getColors = () => { - return this._palette; + @action + toggleMenuPin = (e: React.MouseEvent) => { + Doc.UserDoc()["inkOptionsMenu-pinned"] = this.Pinned = !this.Pinned; + if (!this.Pinned) { + // this.fadeOut(true); + } } @action - changeArrow = (arrowStart: string, arrowEnd: string) => { - SetActiveArrowStart(arrowStart); - SetActiveArrowEnd(arrowEnd); + protected toggleCollapse = (e: React.MouseEvent) => { + this.collapsed = !this.collapsed; + setTimeout(() => { + const x = Math.min(this._left, window.innerWidth - InkOptionsMenu.Instance.width); + InkOptionsMenu.Instance.jumpTo(x, this._top, true); + }, 0); + } + + + + + getColors = () => { + return this._palette; } + // @action + // changeArrow = (arrowStart: string, arrowEnd: string) => { + // SetActiveArrowStart(arrowStart); + // SetActiveArrowEnd(arrowEnd); + // } + @action changeColor = (color: string, type: string) => { const col: ColorState = { @@ -116,40 +148,77 @@ export default class InkOptionsMenu extends AntimodeMenu { this.editProperties(ActiveDash(), "dash"); } - @computed get arrowPicker() { - var currIcon; - for (var i = 0; i < this._arrowStart.length; i++) { - if (this._arrowStart[i] === ActiveArrowStart() && this._arrowEnd[i] === ActiveArrowEnd()) { - currIcon = this._arrowIcons[i]; - if (this._arrowIcons[i] === " ") { - currIcon = "➤"; - } - } - } - var arrowPicker = ; - if (this._arrowBtn) { - arrowPicker =
- {arrowPicker} - {this._arrowStart.map((arrowStart, i) => { - return ; - })} -
; - } - return arrowPicker; + @computed get drawButtons() { + const drawButtons =
+ {this._draw.map((icon, i) => { + return ; + })}
; + return drawButtons; } + // @computed get arrowPicker() { + // var currIcon; + // for (var i = 0; i < this._arrowStart.length; i++) { + // if (this._arrowStart[i] === ActiveArrowStart() && this._arrowEnd[i] === ActiveArrowEnd()) { + // currIcon = this._arrowIcons[i]; + // if (this._arrowIcons[i] === " ") { + // currIcon = "➤"; + // } + // } + // } + // var arrowPicker = ; + // if (this._arrowBtn) { + // arrowPicker =
+ // {arrowPicker} + // {this._arrowStart.map((arrowStart, i) => { + // return ; + // })} + //
; + // } + // return arrowPicker; + // } + @computed get widthPicker() { var widthPicker = ; - if (this._shapeBtn) { - shapePicker =
- {shapePicker} - {this._buttons.map((btn, i) => { - var ttl = btn; - if (btn === "") { - ttl = "no shape"; - } - if (btn === "noRec") { - ttl = "disable shape recognition"; - } - return ; - })} -
; - } - return shapePicker; - } + // @computed get shapePicker() { + // var currIcon; + // if (GestureOverlay.Instance.InkShape === "") { + // currIcon = ; + // } else { + // for (var i = 0; i < this._icons.length; i++) { + // if (GestureOverlay.Instance.InkShape === this._buttons[i]) { + // currIcon = this._icons[i]; + // } + // } + // } + // var shapePicker = ; + // if (this._shapeBtn) { + // shapePicker =
+ // {shapePicker} + // {this._buttons.map((btn, i) => { + // var ttl = btn; + // if (btn === "") { + // ttl = "no shape"; + // } + // if (btn === "noRec") { + // ttl = "disable shape recognition"; + // } + // return ; + // })} + //
; + // } + // return shapePicker; + // } @computed get bezierButton() { return , - this.shapePicker, - this.bezierButton, + // this.shapePicker, + // this.bezierButton, this.widthPicker, this.colorPicker, this.fillPicker, - this.arrowPicker, - this.dashButton, + this.drawButtons, + // this.arrowPicker, + // this.dashButton, + + ]; + + // return this.getElement(buttons); return this.getElement(buttons); } } Scripting.addGlobal(function activatePen(penBtn: any) { if (penBtn) { - Doc.SetSelectedTool(InkTool.Pen); + //no longer changes to inkmode + // Doc.SetSelectedTool(InkTool.Pen); InkOptionsMenu.Instance.jumpTo(300, 300); + InkOptionsMenu.Instance.Pinned = true; + } else { - Doc.SetSelectedTool(InkTool.None); + // Doc.SetSelectedTool(InkTool.None); + InkOptionsMenu.Instance.Pinned = false; InkOptionsMenu.Instance.fadeOut(true); + } }); \ No newline at end of file -- cgit v1.2.3-70-g09d2 From 8264ac5484c0c7b5d47cb78ce60f5d6568e736d9 Mon Sep 17 00:00:00 2001 From: anika-ahluwalia Date: Sat, 4 Jul 2020 17:25:10 -0500 Subject: redesigned editing menu, added link descriptions and popup on created --- src/client/documents/Documents.ts | 9 +-- src/client/util/LinkManager.ts | 6 +- src/client/views/EditableView.tsx | 6 +- src/client/views/GestureOverlay.tsx | 2 +- src/client/views/MainView.tsx | 2 + src/client/views/RecommendationsBox.tsx | 2 +- .../views/collections/CollectionTreeView.tsx | 2 +- src/client/views/collections/CollectionView.tsx | 2 +- .../collectionFreeForm/CollectionFreeFormView.tsx | 2 +- .../collections/collectionFreeForm/MarqueeView.tsx | 2 +- src/client/views/linking/LinkEditor.scss | 48 ++++++++++++--- src/client/views/linking/LinkEditor.tsx | 59 +++++++++++++++--- src/client/views/linking/LinkMenu.scss | 13 +++- src/client/views/linking/LinkMenu.tsx | 15 +++-- src/client/views/linking/LinkMenuGroup.tsx | 6 +- src/client/views/linking/LinkMenuItem.scss | 48 ++++++++++++--- src/client/views/linking/LinkMenuItem.tsx | 23 ++++--- src/client/views/nodes/DocumentLinksButton.tsx | 52 ++++++++++------ src/client/views/nodes/DocumentView.tsx | 42 +++++++++---- src/client/views/nodes/LinkCreatedBox.tsx | 8 +-- src/client/views/nodes/LinkDescriptionPopup.scss | 62 +++++++++++++++++++ src/client/views/nodes/LinkDescriptionPopup.tsx | 70 ++++++++++++++++++++++ 22 files changed, 393 insertions(+), 88 deletions(-) create mode 100644 src/client/views/nodes/LinkDescriptionPopup.scss create mode 100644 src/client/views/nodes/LinkDescriptionPopup.tsx (limited to 'src/client/views/collections/collectionFreeForm') diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts index f81c25bab..11b80aef9 100644 --- a/src/client/documents/Documents.ts +++ b/src/client/documents/Documents.ts @@ -94,6 +94,7 @@ export interface DocumentOptions { label?: string; // short form of title for use as an icon label style?: string; page?: number; + description?: string; // added for links _viewScale?: number; isDisplayPanel?: boolean; // whether the panel functions as GoldenLayout "stack" used to display documents forceActive?: boolean; @@ -259,7 +260,7 @@ export namespace Docs { }], [DocumentType.LINK, { layout: { view: LinkBox, dataField: defaultDataKey }, - options: { _height: 150 } + options: { _height: 150, description: "" } }], [DocumentType.LINKDB, { data: new List(), @@ -864,15 +865,15 @@ export namespace DocUtils { export let ActiveRecordings: Doc[] = []; export function MakeLinkToActiveAudio(doc: Doc) { - DocUtils.ActiveRecordings.map(d => DocUtils.MakeLink({ doc: doc }, { doc: d }, "audio link", "audio timeline")); + DocUtils.ActiveRecordings.map(d => DocUtils.MakeLink({ doc: doc }, { doc: d }, "audio link", "", "audio timeline")); } - export function MakeLink(source: { doc: Doc }, target: { doc: Doc }, linkRelationship: string = "", id?: string) { + export function MakeLink(source: { doc: Doc }, target: { doc: Doc }, linkRelationship: string = "", description: string = "", id?: string) { const sv = DocumentManager.Instance.getDocumentView(source.doc); if (sv && sv.props.ContainingCollectionDoc === target.doc) return; if (target.doc === Doc.UserDoc()) return undefined; - const linkDoc = Docs.Create.LinkDocument(source, target, { linkRelationship, layoutKey: "layout_linkView" }, id); + const linkDoc = Docs.Create.LinkDocument(source, target, { linkRelationship, layoutKey: "layout_linkView", description }, id); linkDoc.layout_linkView = Cast(Cast(Doc.UserDoc()["template-button-link"], Doc, null).dragFactory, Doc, null); Doc.GetProto(linkDoc).title = ComputedField.MakeFunction('self.anchor1?.title +" (" + (self.linkRelationship||"to") +") " + self.anchor2?.title'); diff --git a/src/client/util/LinkManager.ts b/src/client/util/LinkManager.ts index 749fabfcc..6da581f35 100644 --- a/src/client/util/LinkManager.ts +++ b/src/client/util/LinkManager.ts @@ -1,4 +1,4 @@ -import { Doc, DocListCast } from "../../fields/Doc"; +import { Doc, DocListCast, Opt } from "../../fields/Doc"; import { List } from "../../fields/List"; import { listSpec } from "../../fields/Schema"; import { Cast, StrCast } from "../../fields/Types"; @@ -23,6 +23,10 @@ import { Scripting } from "./Scripting"; export class LinkManager { private static _instance: LinkManager; + + + public static currentLink: Opt; + public static get Instance(): LinkManager { return this._instance || (this._instance = new this()); } diff --git a/src/client/views/EditableView.tsx b/src/client/views/EditableView.tsx index 628db366f..25a87ab56 100644 --- a/src/client/views/EditableView.tsx +++ b/src/client/views/EditableView.tsx @@ -194,7 +194,11 @@ export class EditableView extends React.Component { ref={this._ref} style={{ display: this.props.display, minHeight: "20px", height: `${this.props.height ? this.props.height : "auto"}`, maxHeight: `${this.props.maxHeight}` }} onClick={this.onClick} placeholder={this.props.placeholder}> - {this.props.contents ? this.props.contents?.valueOf() : this.props.placeholder?.valueOf()} + + {this.props.contents ? this.props.contents?.valueOf() : this.props.placeholder?.valueOf()} ); } diff --git a/src/client/views/GestureOverlay.tsx b/src/client/views/GestureOverlay.tsx index 487467b2b..cdc468066 100644 --- a/src/client/views/GestureOverlay.tsx +++ b/src/client/views/GestureOverlay.tsx @@ -551,7 +551,7 @@ export default class GestureOverlay extends Touchable { else if (this._d1 !== doc && !LinkManager.Instance.doesLinkExist(this._d1, doc)) { // we don't want to create a link between ink strokes (doing so makes drawing a t very hard) if (this._d1.type !== "ink" && doc.type !== "ink") { - DocUtils.MakeLink({ doc: this._d1 }, { doc: doc }, "gestural link"); + DocUtils.MakeLink({ doc: this._d1 }, { doc: doc }, "gestural link", ""); actionPerformed = true; } } diff --git a/src/client/views/MainView.tsx b/src/client/views/MainView.tsx index 15f818d1f..68ea51456 100644 --- a/src/client/views/MainView.tsx +++ b/src/client/views/MainView.tsx @@ -61,6 +61,7 @@ import { LinkMenu } from './linking/LinkMenu'; import { LinkDocPreview } from './nodes/LinkDocPreview'; import { Fade } from '@material-ui/core'; import { LinkCreatedBox } from './nodes/LinkCreatedBox'; +import { LinkDescriptionPopup } from './nodes/LinkDescriptionPopup'; @observer export class MainView extends React.Component { @@ -608,6 +609,7 @@ export class MainView extends React.Component { + {LinkDescriptionPopup.descriptionPopup ? : null} {DocumentLinksButton.EditLink ? : (null)} {LinkDocPreview.LinkInfo ? {
DocumentManager.Instance.jumpToDocument(doc, false)}>
-
DocUtils.MakeLink({ doc: this.props.Document.sourceDoc as Doc }, { doc: doc }, "Recommender", undefined)}> +
DocUtils.MakeLink({ doc: this.props.Document.sourceDoc as Doc }, { doc: doc }, "Recommender", "", undefined)}>
diff --git a/src/client/views/collections/CollectionTreeView.tsx b/src/client/views/collections/CollectionTreeView.tsx index 620b977fa..26c41f524 100644 --- a/src/client/views/collections/CollectionTreeView.tsx +++ b/src/client/views/collections/CollectionTreeView.tsx @@ -207,7 +207,7 @@ class TreeView extends React.Component { if (complete.linkDragData) { const sourceDoc = complete.linkDragData.linkSourceDocument; const destDoc = this.doc; - DocUtils.MakeLink({ doc: sourceDoc }, { doc: destDoc }, "tree link"); + DocUtils.MakeLink({ doc: sourceDoc }, { doc: destDoc }, "tree link", ""); e.stopPropagation(); } const docDragData = complete.docDragData; diff --git a/src/client/views/collections/CollectionView.tsx b/src/client/views/collections/CollectionView.tsx index 26abd2529..df21d6a28 100644 --- a/src/client/views/collections/CollectionView.tsx +++ b/src/client/views/collections/CollectionView.tsx @@ -147,7 +147,7 @@ export class CollectionView extends Touchable d instanceof Doc); first && (first.hidden = true); pushpinLink && (Doc.GetProto(pushpinLink).isPushpin = true); diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx index b81e400b3..9bf425db2 100644 --- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx +++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx @@ -246,7 +246,7 @@ export class CollectionFreeFormView extends CollectionSubView { + + @observable description = StrCast(LinkManager.currentLink?.description); + + //@observable description = this.props.linkDoc.description ? StrCast(this.props.linkDoc.description) : "DESCRIPTION"; + @action deleteLink = (): void => { LinkManager.Instance.deleteLink(this.props.linkDoc); this.props.showLinks(); } + @action + setDescripValue = (value: string) => { + if (LinkManager.currentLink) { + LinkManager.currentLink.description = value; + return true; + } + } + + @computed + get editDescription() { + return
+
+ Link Description:
+
+ StrCast(LinkManager.currentLink?.description)} + SetValue={value => { this.setDescripValue(value); return false; }} + contents={LinkManager.currentLink?.description} + placeholder={"(optional) enter link description"} + color={"rgb(88, 88, 88)"} + >
; + } + + @computed + get followingDropdown() { + return "choose follow behavior"; + } + render() { const destination = LinkManager.Instance.getOppositeAnchor(this.props.linkDoc, this.props.sourceDoc); const groups = [this.props.linkDoc].map(groupDoc => { - return ; + return ; }); return !destination ? (null) : (
- {this.props.hideback ? (null) : }
-

editing link to: {destination.proto?.title ?? destination.title ?? "untitled"}

- + {this.props.hideback ? (null) : } +

editing link to: { + destination.proto?.title ?? destination.title ?? "untitled"}

+
- {groups.length > 0 ? groups :
There are currently no relationships associated with this link.
} + +
{this.editDescription}
+
{this.followingDropdown}
+ + {/* {groups.length > 0 ? groups :
There are currently no relationships associated with this link.
} */}
); diff --git a/src/client/views/linking/LinkMenu.scss b/src/client/views/linking/LinkMenu.scss index 6468ccd3d..f827f25c2 100644 --- a/src/client/views/linking/LinkMenu.scss +++ b/src/client/views/linking/LinkMenu.scss @@ -11,12 +11,17 @@ position: absolute; z-index: 10; background: $link-color; - min-width: 150px + min-width: 150px; + border-radius: 5px; + padding-top: 6.5px; + padding-bottom: 6.5px; + padding-left: 6.5px; + padding-right: 2px; } .linkMenu-group { - border-bottom: 0.5px solid lightgray; - padding: 5px 0; + //border-bottom: 0.5px solid lightgray; + //@extend: 5px 0; &:last-child { @@ -26,9 +31,11 @@ .linkMenu-group-name { display: flex; + &:hover { p { background-color: lightgray; + } p.expand-one { diff --git a/src/client/views/linking/LinkMenu.tsx b/src/client/views/linking/LinkMenu.tsx index c672511ac..8721b9f3d 100644 --- a/src/client/views/linking/LinkMenu.tsx +++ b/src/client/views/linking/LinkMenu.tsx @@ -11,6 +11,7 @@ import { faTrash } from '@fortawesome/free-solid-svg-icons'; import { library } from "@fortawesome/fontawesome-svg-core"; import { DocumentLinksButton } from "../nodes/DocumentLinksButton"; import { LinkDocPreview } from "../nodes/LinkDocPreview"; +import { isUndefined } from "util"; library.add(faTrash); @@ -26,18 +27,19 @@ export class LinkMenu extends React.Component { @observable private _editingLink?: Doc; @observable private _linkMenuRef: Opt; + private _editorRef = React.createRef(); @action onClick = (e: PointerEvent) => { LinkDocPreview.LinkInfo = undefined; - if (this._linkMenuRef?.contains(e.target as any)) { - DocumentLinksButton.EditLink = undefined; - } - if (this._linkMenuRef && !this._linkMenuRef.contains(e.target as any)) { - DocumentLinksButton.EditLink = undefined; + if (this._linkMenuRef && !!!this._linkMenuRef.contains(e.target as any)) { + if (this._editorRef && !!!this._editorRef.current?.contains(e.target as any)) { + console.log("outside click"); + DocumentLinksButton.EditLink = undefined; + } } } @action @@ -82,7 +84,8 @@ export class LinkMenu extends React.Component { ref={(r) => this._linkMenuRef = r} style={{ left: this.props.location[0], top: this.props.location[1] }}> {!this._editingLink ? this.renderAllGroups(groups) : - this._editingLink = undefined)} /> + this._editingLink = undefined)} /> } ; } diff --git a/src/client/views/linking/LinkMenuGroup.tsx b/src/client/views/linking/LinkMenuGroup.tsx index 7892d381b..ec17776e3 100644 --- a/src/client/views/linking/LinkMenuGroup.tsx +++ b/src/client/views/linking/LinkMenuGroup.tsx @@ -26,6 +26,7 @@ export class LinkMenuGroup extends React.Component { private _drag = React.createRef(); private _table = React.createRef(); + private _menuRef = React.createRef(); onLinkButtonDown = (e: React.PointerEvent): void => { e.stopPropagation(); @@ -74,12 +75,13 @@ export class LinkMenuGroup extends React.Component { linkDoc={linkDoc} sourceDoc={this.props.sourceDoc} destinationDoc={destination} - showEditor={this.props.showEditor} />; + showEditor={this.props.showEditor} + menuRef={this._menuRef} />; } }); return ( -
+
{/*

{this.props.groupType}:

diff --git a/src/client/views/linking/LinkMenuItem.scss b/src/client/views/linking/LinkMenuItem.scss index e3ce69cd7..a71b2dbba 100644 --- a/src/client/views/linking/LinkMenuItem.scss +++ b/src/client/views/linking/LinkMenuItem.scss @@ -4,19 +4,38 @@ // border-top: 0.5px solid $main-accent; position: relative; display: flex; - font-size: 12px; .linkMenu-name { position: relative; - p { - padding: 4px 6px; - line-height: 12px; - border-radius: 5px; - overflow-wrap: break-word; - user-select: none; + .linkMenu-text { + + padding: 4px 2px; + + .linkMenu-destination-title { + text-decoration: none; + color: rgb(46, 82, 160); + font-size: 14px; + padding-bottom: 2px; + } + + .linkMenu-description { + text-decoration: none; + font-style: italic; + color: rgb(95, 97, 102); + font-size: 10px; + } + + p { + //padding: 4px 2px; + line-height: 12px; + border-radius: 5px; + overflow-wrap: break-word; + user-select: none; + } } + } .linkMenu-item-content { @@ -32,19 +51,30 @@ } &:hover { + .linkMenu-item-buttons { display: flex; } .linkMenu-item-content { + + .linkMenu-destination-title { + text-decoration: underline; + color: rgb(15, 57, 148); + } + &.expand-two p { width: calc(100% - 52px); - background-color: lightgray; + //text-decoration: underline; + //color: rgb(15, 57, 148); + //background-color: lightgray; } &.expand-three p { width: calc(100% - 84px); - background-color: lightgray; + //text-decoration: underline; + //color: rgb(15, 57, 148); + //background-color: lightgray; } } } diff --git a/src/client/views/linking/LinkMenuItem.tsx b/src/client/views/linking/LinkMenuItem.tsx index 04cd83ee0..891c6d263 100644 --- a/src/client/views/linking/LinkMenuItem.tsx +++ b/src/client/views/linking/LinkMenuItem.tsx @@ -26,6 +26,7 @@ interface LinkMenuItemProps { destinationDoc: Doc; showEditor: (linkDoc: Doc) => void; addDocTab: (document: Doc, where: string) => boolean; + menuRef: React.Ref; } // drag links and drop link targets (aliasing them if needed) @@ -77,6 +78,7 @@ export class LinkMenuItem extends React.Component { @action toggleShowMore(e: React.PointerEvent) { e.stopPropagation(); this._showMore = !this._showMore; } onEdit = (e: React.PointerEvent): void => { + LinkManager.currentLink = this.props.linkDoc; setupMoveUpEvents(this, e, this.editMoved, emptyFunction, () => this.props.showEditor(this.props.linkDoc)); } @@ -110,7 +112,8 @@ export class LinkMenuItem extends React.Component { document.removeEventListener("pointerup", this.onLinkButtonUp); document.addEventListener("pointerup", this.onLinkButtonUp); - if (this._buttonRef && this._buttonRef.current?.contains(e.target as any)) { + if (this._buttonRef && !!!this._buttonRef.current?.contains(e.target as any)) { + console.log("outside click"); LinkDocPreview.LinkInfo = undefined; } } @@ -174,18 +177,24 @@ export class LinkMenuItem extends React.Component { Location: [e.clientX, e.clientY + 20] }))} onPointerDown={this.onLinkButtonDown}> -

{StrCast(this.props.destinationDoc.title)}

+ +
+

+ {StrCast(this.props.destinationDoc.title)}

+ {this.props.linkDoc.description !== "" ?

+ {StrCast(this.props.linkDoc.description)}

: null}
+
{canExpand ?
this.toggleShowMore(e)}>
: <>} - {/*
-
*/} +
+
-
- -
+ {/*
+
*/}
{this._showMore ? this.renderMetadata() : <>} diff --git a/src/client/views/nodes/DocumentLinksButton.tsx b/src/client/views/nodes/DocumentLinksButton.tsx index bfd860f65..5d1a68af5 100644 --- a/src/client/views/nodes/DocumentLinksButton.tsx +++ b/src/client/views/nodes/DocumentLinksButton.tsx @@ -11,6 +11,8 @@ import { DocUtils } from "../../documents/Documents"; import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; import { LinkDocPreview } from "./LinkDocPreview"; import { LinkCreatedBox } from "./LinkCreatedBox"; +import { LinkDescriptionPopup } from "./LinkDescriptionPopup"; +import { LinkManager } from "../../util/LinkManager"; const higflyout = require("@hig/flyout"); export const { anchorPoints } = higflyout; export const Flyout = higflyout.default; @@ -54,6 +56,7 @@ export class DocumentLinksButton extends React.Component { setupMoveUpEvents(this, e, this.onLinkButtonMoved, emptyFunction, action((e, doubleTap) => { if (doubleTap && this.props.InMenu) { @@ -87,15 +90,22 @@ export class DocumentLinksButton extends React.Component { - LinkCreatedBox.popupX = e.screenX; - LinkCreatedBox.popupY = e.screenY - 120; - LinkCreatedBox.linkCreated = true; - setTimeout(action(() => { LinkCreatedBox.linkCreated = false; }), 2500); - }); + + if (DocumentLinksButton.StartLink && DocumentLinksButton.StartLink !== this.props.View) { + const linkDoc = DocUtils.MakeLink({ doc: DocumentLinksButton.StartLink.props.Document }, { doc: this.props.View.props.Document }, "long drag"); + LinkManager.currentLink = linkDoc; + runInAction(() => { + LinkCreatedBox.popupX = e.screenX; + LinkCreatedBox.popupY = e.screenY - 33; + LinkCreatedBox.linkCreated = true; + + LinkDescriptionPopup.popupX = e.screenX; + LinkDescriptionPopup.popupY = e.screenY; + LinkDescriptionPopup.descriptionPopup = true; + + setTimeout(action(() => { LinkCreatedBox.linkCreated = false; }), 2500); + }); + } } } })); @@ -109,15 +119,21 @@ export class DocumentLinksButton extends React.Component { - LinkCreatedBox.popupX = e.screenX; - LinkCreatedBox.popupY = e.screenY - 120; - LinkCreatedBox.linkCreated = true; - setTimeout(action(() => { LinkCreatedBox.linkCreated = false; }), 2500); - }); + if (DocumentLinksButton.StartLink && DocumentLinksButton.StartLink !== this.props.View) { + const linkDoc = DocUtils.MakeLink({ doc: DocumentLinksButton.StartLink.props.Document }, { doc: this.props.View.props.Document }, "long drag"); + LinkManager.currentLink = linkDoc; + runInAction(() => { + LinkCreatedBox.popupX = e.screenX; + LinkCreatedBox.popupY = e.screenY - 33; + LinkCreatedBox.linkCreated = true; + + LinkDescriptionPopup.popupX = e.screenX; + LinkDescriptionPopup.popupY = e.screenY; + LinkDescriptionPopup.descriptionPopup = true; + + setTimeout(action(() => { LinkCreatedBox.linkCreated = false; }), 2500); + }); + } } } diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx index b38db9a1e..9a4d9ac53 100644 --- a/src/client/views/nodes/DocumentView.tsx +++ b/src/client/views/nodes/DocumentView.tsx @@ -43,6 +43,8 @@ import React = require("react"); import { DocumentLinksButton } from './DocumentLinksButton'; import { MobileInterface } from '../../../mobile/MobileInterface'; import { LinkCreatedBox } from './LinkCreatedBox'; +import { LinkDescriptionPopup } from './LinkDescriptionPopup'; +import { LinkManager } from '../../util/LinkManager'; 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, @@ -642,30 +644,46 @@ export class DocumentView extends DocComponent(Docu e.stopPropagation(); de.complete.annoDragData.linkedToDoc = true; + const linkDoc = DocUtils.MakeLink({ doc: de.complete.annoDragData.annotationDocument }, { doc: this.props.Document }, "link"); + LinkManager.currentLink = linkDoc; + runInAction(() => { LinkCreatedBox.popupX = de.x; - LinkCreatedBox.popupY = de.y; + LinkCreatedBox.popupY = de.y - 33; LinkCreatedBox.linkCreated = true; + + LinkDescriptionPopup.popupX = de.x; + LinkDescriptionPopup.popupY = de.y; + LinkDescriptionPopup.descriptionPopup = true; + setTimeout(action(() => { LinkCreatedBox.linkCreated = false; }), 2500); }); - - DocUtils.MakeLink({ doc: de.complete.annoDragData.annotationDocument }, { doc: this.props.Document }, "link"); } if (de.complete.linkDragData) { e.stopPropagation(); // const docs = await SearchUtil.Search(`data_l:"${destDoc[Id]}"`, true); // const views = docs.map(d => DocumentManager.Instance.getDocumentView(d)).filter(d => d).map(d => d as DocumentView); - runInAction(() => { - LinkCreatedBox.popupX = de.x; - LinkCreatedBox.popupY = de.y; - LinkCreatedBox.linkCreated = true; - setTimeout(action(() => { LinkCreatedBox.linkCreated = false; }), 2500); - }); + if (de.complete.linkDragData.linkSourceDocument !== this.props.Document) { + const linkDoc = DocUtils.MakeLink({ doc: de.complete.linkDragData.linkSourceDocument }, + { doc: this.props.Document }, `link`); + LinkManager.currentLink = linkDoc; + + de.complete.linkDragData.linkSourceDocument !== this.props.Document && + (de.complete.linkDragData.linkDocument = linkDoc); // TODODO this is where in text links get passed + runInAction(() => { + LinkCreatedBox.popupX = de.x; + LinkCreatedBox.popupY = de.y - 33; + LinkCreatedBox.linkCreated = true; + + LinkDescriptionPopup.popupX = de.x; + LinkDescriptionPopup.popupY = de.y; + LinkDescriptionPopup.descriptionPopup = true; + + setTimeout(action(() => { LinkCreatedBox.linkCreated = false; }), 2500); + }); + } - de.complete.linkDragData.linkSourceDocument !== this.props.Document && - (de.complete.linkDragData.linkDocument = DocUtils.MakeLink({ doc: de.complete.linkDragData.linkSourceDocument }, - { doc: this.props.Document }, `link`)); // TODODO this is where in text links get passed } } diff --git a/src/client/views/nodes/LinkCreatedBox.tsx b/src/client/views/nodes/LinkCreatedBox.tsx index d157d3fca..648ae23c8 100644 --- a/src/client/views/nodes/LinkCreatedBox.tsx +++ b/src/client/views/nodes/LinkCreatedBox.tsx @@ -11,8 +11,8 @@ import { Fade } from "@material-ui/core"; export class LinkCreatedBox extends React.Component<{}> { @observable public static linkCreated: boolean = false; - @observable public static popupX: number = 600; - @observable public static popupY: number = 250; + @observable public static popupX: number = 500; + @observable public static popupY: number = 150; @action public static changeLinkCreated = () => { @@ -23,8 +23,8 @@ export class LinkCreatedBox extends React.Component<{}> { return
Link Created
; } diff --git a/src/client/views/nodes/LinkDescriptionPopup.scss b/src/client/views/nodes/LinkDescriptionPopup.scss new file mode 100644 index 000000000..474bd919b --- /dev/null +++ b/src/client/views/nodes/LinkDescriptionPopup.scss @@ -0,0 +1,62 @@ +.linkDescriptionPopup { + + display: flex; + + border: 1px solid rgb(100, 100, 100); + + width: auto; + position: absolute; + + height: auto; + z-index: 10000; + border-radius: 10px; + font-size: 12px; + //white-space: nowrap; + + background-color: rgba(250, 250, 250, 0.95); + padding-top: 9px; + padding-bottom: 9px; + padding-left: 9px; + padding-right: 9px; + + .linkDescriptionPopup-input { + float: left; + color: rgb(100, 100, 100); + } + + .linkDescriptionPopup-btn { + + float: right; + + + .linkDescriptionPopup-btn-dismiss { + background-color: white; + color: black; + display: inline; + right: 0; + border-radius: 10px; + border: 1px solid black; + padding: 3px; + font-size: 9px; + text-align: center; + position: relative; + transform: translateY(5px); + } + + .linkDescriptionPopup-btn-add { + background-color: black; + color: white; + display: inline; + right: 0; + border-radius: 10px; + border: 1px solid black; + padding: 3px; + font-size: 9px; + text-align: center; + position: relative; + transform: translateY(5px); + } + } + + +} \ No newline at end of file diff --git a/src/client/views/nodes/LinkDescriptionPopup.tsx b/src/client/views/nodes/LinkDescriptionPopup.tsx new file mode 100644 index 000000000..078a738e7 --- /dev/null +++ b/src/client/views/nodes/LinkDescriptionPopup.tsx @@ -0,0 +1,70 @@ +import React = require("react"); +import { observer } from "mobx-react"; +import "./LinkDescriptionPopup.scss"; +import { observable, action } from "mobx"; +import { EditableView } from "../EditableView"; +import { LinkManager } from "../../util/LinkManager"; + + +@observer +export class LinkDescriptionPopup extends React.Component<{}> { + + @observable public static descriptionPopup: boolean = false; + @observable public static popupX: number = 700; + @observable public static popupY: number = 350; + @observable description: string = ""; + @observable popupRef = React.createRef(); + + @action + descriptionChanged = (e: React.ChangeEvent) => { + this.description = e.currentTarget.value; + } + + @action + setDescription = () => { + if (LinkManager.currentLink) { + LinkManager.currentLink.description = this.description; + } + LinkDescriptionPopup.descriptionPopup = false; + } + + @action + onDismiss = () => { + LinkDescriptionPopup.descriptionPopup = false; + } + + @action + onClick = (e: PointerEvent) => { + if (this.popupRef && !!!this.popupRef.current?.contains(e.target as any)) { + LinkDescriptionPopup.descriptionPopup = false; + } + } + + @action + componentDidMount() { + document.addEventListener("pointerdown", this.onClick); + } + + componentWillUnmount() { + document.removeEventListener("pointerdown", this.onClick); + } + + render() { + return
+ this.descriptionChanged(e)}> + +
+
Dismiss
+
Add
+
+
; + } +} \ No newline at end of file -- cgit v1.2.3-70-g09d2 From 3beca8e7d268dc7b67b20b2c8760ea5e4b6fdb88 Mon Sep 17 00:00:00 2001 From: anika-ahluwalia Date: Wed, 8 Jul 2020 18:59:37 -0500 Subject: added dashDragging event --- src/client/util/DragManager.ts | 48 ++++++++++++++++++++++ .../collectionFreeForm/CollectionFreeFormView.tsx | 15 +++++++ src/client/views/nodes/DocumentLinksButton.tsx | 2 +- 3 files changed, 64 insertions(+), 1 deletion(-) (limited to 'src/client/views/collections/collectionFreeForm') diff --git a/src/client/util/DragManager.ts b/src/client/util/DragManager.ts index 2ceafff30..64c3d8458 100644 --- a/src/client/util/DragManager.ts +++ b/src/client/util/DragManager.ts @@ -427,6 +427,54 @@ export namespace DragManager { }, dragData.droppedDocuments); } + const target = document.elementFromPoint(e.x, e.y); + + const complete = new DragCompleteEvent(false, dragData); + + if (target) { + target.dispatchEvent( + new CustomEvent("dashDragging", { + bubbles: true, + detail: { + shiftKey: e.shiftKey, + altKey: e.altKey, + metaKey: e.metaKey, + ctrlKey: e.ctrlKey, + clientX: e.clientX, + clientY: e.clientY, + dataTransfer: new DataTransfer, + button: e.button, + buttons: e.buttons, + getModifierState: e.getModifierState, + movementX: e.movementX, + movementY: e.movementY, + pageX: e.pageX, + pageY: e.pageY, + relatedTarget: e.relatedTarget, + screenX: e.screenX, + screenY: e.screenY, + detail: e.detail, + view: e.view ? e.view : new Window, + nativeEvent: new DragEvent("dashDragging"), + currentTarget: target, + target: target, + bubbles: true, + cancelable: true, + defaultPrevented: true, + eventPhase: e.eventPhase, + isTrusted: true, + preventDefault: e.preventDefault, + isDefaultPrevented: () => true, + stopPropagation: e.stopPropagation, + isPropagationStopped: () => true, + persist: emptyFunction, + timeStamp: e.timeStamp, + type: "dashDragging" + } + }) + ); + } + const { thisX, thisY } = snapDrag(e, xFromLeft, yFromTop, xFromRight, yFromBottom); const moveX = thisX - lastX; diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx index 9bf425db2..5a762a85c 100644 --- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx +++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx @@ -1143,10 +1143,19 @@ export class CollectionFreeFormView extends CollectionSubView this.doLayoutComputation, (elements) => this._layoutElements = elements || [], { fireImmediately: true, name: "doLayout" }); + + const handler = (e: Event) => this.handleDragging(e, (e as CustomEvent).detail); + + document.addEventListener("dashDragging", handler); } + componentWillUnmount() { this._layoutComputeReaction?.(); + + const handler = (e: Event) => this.handleDragging(e, (e as CustomEvent).detail); + document.removeEventListener("dashDragging", handler); } + @computed get views() { return this._layoutElements.filter(ele => ele.bounds && !ele.bounds.z).map(ele => ele.ele); } elementFunc = () => this._layoutElements; @@ -1155,6 +1164,12 @@ export class CollectionFreeFormView extends CollectionSubView { + console.log(de.clientX); + console.log(de.clientX); + } + promoteCollection = undoBatch(action(() => { const childDocs = this.childDocs.slice(); childDocs.forEach(doc => { diff --git a/src/client/views/nodes/DocumentLinksButton.tsx b/src/client/views/nodes/DocumentLinksButton.tsx index 7fb447cab..44e72215d 100644 --- a/src/client/views/nodes/DocumentLinksButton.tsx +++ b/src/client/views/nodes/DocumentLinksButton.tsx @@ -152,7 +152,7 @@ export class DocumentLinksButton extends React.Component
Date: Thu, 9 Jul 2020 01:54:29 -0500 Subject: started dragging pans screen (needs cleaning) --- src/client/util/LinkManager.ts | 2 + .../collectionFreeForm/CollectionFreeFormView.tsx | 105 ++++++++++++++++++--- 2 files changed, 96 insertions(+), 11 deletions(-) (limited to 'src/client/views/collections/collectionFreeForm') diff --git a/src/client/util/LinkManager.ts b/src/client/util/LinkManager.ts index 6da581f35..50f3fc1d6 100644 --- a/src/client/util/LinkManager.ts +++ b/src/client/util/LinkManager.ts @@ -3,6 +3,7 @@ import { List } from "../../fields/List"; import { listSpec } from "../../fields/Schema"; import { Cast, StrCast } from "../../fields/Types"; import { Scripting } from "./Scripting"; +import { undoBatch } from "./UndoManager"; /* * link doc: @@ -52,6 +53,7 @@ export class LinkManager { return false; } + @undoBatch public deleteLink(linkDoc: Doc): boolean { if (LinkManager.Instance.LinkManagerDoc && linkDoc instanceof Doc) { Doc.RemoveDocFromList(LinkManager.Instance.LinkManagerDoc, "data", linkDoc); diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx index 5a762a85c..a3d3a210d 100644 --- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx +++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx @@ -101,6 +101,10 @@ export class CollectionFreeFormView extends CollectionSubView(); + @observable _marqueeRef = React.createRef(); + @observable canPanX: boolean = true; + @observable canPanY: boolean = true; + @computed get fitToContentScaling() { return this.fitToContent ? NumCast(this.layoutDoc.fitToContentScaling, 1) : 1; } @computed get fitToContent() { return (this.props.fitToBox || this.Document._fitToBox) && !this.isAnnotationOverlay; } @computed get parentScaling() { return this.props.ContentScaling && this.fitToContent && !this.isAnnotationOverlay ? this.props.ContentScaling() : 1; } @@ -1164,10 +1168,87 @@ export class CollectionFreeFormView extends CollectionSubView + @action handleDragging = (e: Event, de: DragEvent) => { - console.log(de.clientX); - console.log(de.clientX); + + const nw = NumCast(this.Document._nativeWidth, this.props.NativeWidth()); + const nh = NumCast(this.Document._nativeHeight, this.props.NativeHeight()); + const hscale = nh ? this.props.PanelHeight() / nh : 1; + const wscale = nw ? this.props.PanelWidth() / nw : 1; + + if (this._marqueeRef) { + if (this._marqueeRef.current) { + + // console.log("left: " + this._marqueeRef.current.clientLeft); + // console.log("width: " + this._marqueeRef.current.clientWidth); + // console.log("client x: " + de.clientX); + + // console.log("top: " + this._marqueeRef.current.clientTop); + // console.log("height: " + this._marqueeRef.current.clientHeight); + // console.log("client y: " + de.clientY); + + + if (this._marqueeRef.current.clientWidth > 0) { + if (de.clientX - 315 - this._marqueeRef.current.clientLeft < 25) { + console.log("PAN left "); + if (this.canPanX) { + this.Document._panX = de.clientX - 20 - this._marqueeRef.current.clientLeft; + setTimeout(action(() => { + this.canPanX = true; + this.panX(); + }), 2500); + this.canPanX = false; + } + } else if (de.clientX - 315 - this._marqueeRef.current.clientLeft - + this._marqueeRef.current.clientWidth < 25) { + console.log("PAN right "); + if (this.canPanX) { + this.Document._panX = de.clientX - 315 - this._marqueeRef.current.clientLeft - + this._marqueeRef.current.clientWidth; + + setTimeout(action(() => { + this.panX(); + this.canPanX = true; + }), 2500); + this.canPanX = false; + } + + } + } + + if (this._marqueeRef.current.clientHeight > 0) { + if (de.clientY - 120 - this._marqueeRef.current.clientTop < 25) { + console.log("PAN top "); + if (this.canPanY) { + this.Document._panY = de.clientY - 20 - this._marqueeRef.current.clientTop; + setTimeout(action(() => { + this.canPanY = true; + this.panY(); + }), 2500); + this.canPanY = false; + } + } else if (de.clientY - 120 - this._marqueeRef.current.clientTop - + this._marqueeRef.current.clientHeight < 25) { + console.log("PAN bottom "); + if (this.canPanY) { + this.Document._panY = de.clientY - 120 - this._marqueeRef.current.clientTop - + this._marqueeRef.current.clientHeight; + + setTimeout(action(() => { + this.panY(); + this.canPanY = true; + }), 2500); + this.canPanY = false; + } + + } + + } + } + } } promoteCollection = undoBatch(action(() => { @@ -1351,7 +1432,8 @@ export class CollectionFreeFormView extends CollectionSubView - - {this.children} - +
+ + {this.children} +
{this.showTimeline ? : (null)} ; } -- cgit v1.2.3-70-g09d2 From 58865aa5f27fa4a23af3a589bfc45868c7a77151 Mon Sep 17 00:00:00 2001 From: Bob Zeleznik Date: Thu, 9 Jul 2020 11:31:04 -0400 Subject: fixed issues with frame based animations for annotations on images,etc. --- .../views/collections/collectionFreeForm/CollectionFreeFormView.tsx | 2 +- src/client/views/nodes/CollectionFreeFormDocumentView.tsx | 6 +++--- src/client/views/presentationview/PresElementBox.tsx | 4 +++- 3 files changed, 7 insertions(+), 5 deletions(-) (limited to 'src/client/views/collections/collectionFreeForm') diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx index 9bf425db2..60c9d7f4a 100644 --- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx +++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx @@ -1065,7 +1065,7 @@ export class CollectionFreeFormView extends CollectionSubView) { const layoutDocs = this.childLayoutPairs.map(pair => pair.layout); - const initResult = this.Document.arrangeInit && this.Document.arrangeInit.script.run({ docs: layoutDocs, collection: this.Document }, console.log); + const initResult = this.Document.arrangeInit?.script.run({ docs: layoutDocs, collection: this.Document }, console.log); const state = initResult?.success ? initResult.result.scriptState : undefined; const elements = initResult?.success ? this.viewDefsToJSX(initResult.result.views) : []; diff --git a/src/client/views/nodes/CollectionFreeFormDocumentView.tsx b/src/client/views/nodes/CollectionFreeFormDocumentView.tsx index a3020f912..d79e2c9ff 100644 --- a/src/client/views/nodes/CollectionFreeFormDocumentView.tsx +++ b/src/client/views/nodes/CollectionFreeFormDocumentView.tsx @@ -73,9 +73,9 @@ export class CollectionFreeFormDocumentView extends DocComponent (i <= timecode && x !== undefined) || p === undefined ? x : p, undefined as any as number), - y: Cast(doc["y-indexed"], listSpec("number"), []).reduce((p, y, i) => (i <= timecode && y !== undefined) || p === undefined ? y : p, undefined as any as number), - opacity: Cast(doc["opacity-indexed"], listSpec("number"), []).reduce((p, o, i) => i <= timecode || p === undefined ? o : p, undefined as any as number), + x: Cast(doc["x-indexed"], listSpec("number"), [NumCast(doc.x)]).reduce((p, x, i) => (i <= timecode && x !== undefined) || p === undefined ? x : p, undefined as any as number), + y: Cast(doc["y-indexed"], listSpec("number"), [NumCast(doc.y)]).reduce((p, y, i) => (i <= timecode && y !== undefined) || p === undefined ? y : p, undefined as any as number), + opacity: Cast(doc["opacity-indexed"], listSpec("number"), [NumCast(doc.opacity, 1)]).reduce((p, o, i) => i <= timecode || p === undefined ? o : p, undefined as any as number), }); } diff --git a/src/client/views/presentationview/PresElementBox.tsx b/src/client/views/presentationview/PresElementBox.tsx index 6fd3455b6..4c0972736 100644 --- a/src/client/views/presentationview/PresElementBox.tsx +++ b/src/client/views/presentationview/PresElementBox.tsx @@ -15,6 +15,7 @@ import { FieldView, FieldViewProps } from '../nodes/FieldView'; import "./PresElementBox.scss"; import React = require("react"); import { CollectionFreeFormDocumentView } from "../nodes/CollectionFreeFormDocumentView"; +import { DocumentType } from "../../documents/DocumentTypes"; export const presSchema = createSchema({ presentationTargetDoc: Doc, @@ -100,7 +101,8 @@ export class PresElementBox extends ViewBoxBaseComponent Date: Thu, 9 Jul 2020 11:36:48 -0400 Subject: from last --- .../views/collections/collectionFreeForm/CollectionFreeFormView.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/client/views/collections/collectionFreeForm') diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx index 60c9d7f4a..d9aabd7c2 100644 --- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx +++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx @@ -205,7 +205,7 @@ export class CollectionFreeFormView extends CollectionSubView Date: Thu, 9 Jul 2020 12:15:42 -0500 Subject: fixed linking undo issues --- .../collectionFreeForm/CollectionFreeFormView.tsx | 96 ++++++++++++---------- src/client/views/nodes/DocumentLinksButton.tsx | 6 +- .../views/nodes/formattedText/FormattedTextBox.tsx | 2 + 3 files changed, 57 insertions(+), 47 deletions(-) (limited to 'src/client/views/collections/collectionFreeForm') diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx index a3d3a210d..ffa4be4b9 100644 --- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx +++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx @@ -1174,47 +1174,55 @@ export class CollectionFreeFormView extends CollectionSubView { - const nw = NumCast(this.Document._nativeWidth, this.props.NativeWidth()); - const nh = NumCast(this.Document._nativeHeight, this.props.NativeHeight()); - const hscale = nh ? this.props.PanelHeight() / nh : 1; - const wscale = nw ? this.props.PanelWidth() / nw : 1; + const top = this.panX(); + const left = this.panY(); + + const size = this.getTransform().transformDirection(this.props.PanelWidth(), this.props.PanelHeight()); + + const scale = this.getLocalTransform().inverse().Scale; if (this._marqueeRef) { + if (this._marqueeRef.current) { + // console.log("top: " + this._marqueeRef.current.clientTop); // console.log("left: " + this._marqueeRef.current.clientLeft); // console.log("width: " + this._marqueeRef.current.clientWidth); - // console.log("client x: " + de.clientX); - - // console.log("top: " + this._marqueeRef.current.clientTop); // console.log("height: " + this._marqueeRef.current.clientHeight); - // console.log("client y: " + de.clientY); + + console.log("width: " + this._marqueeRef.current.getBoundingClientRect().width); + console.log("height: " + this._marqueeRef.current.getBoundingClientRect().width); + console.log("x: " + this._marqueeRef.current.getBoundingClientRect().x); + console.log("y: " + this._marqueeRef.current.getBoundingClientRect().y); + + // console.log("mouse x: " + de.screenX); + // console.log("mouse y: " + de.screenY); if (this._marqueeRef.current.clientWidth > 0) { if (de.clientX - 315 - this._marqueeRef.current.clientLeft < 25) { console.log("PAN left "); - if (this.canPanX) { - this.Document._panX = de.clientX - 20 - this._marqueeRef.current.clientLeft; - setTimeout(action(() => { - this.canPanX = true; - this.panX(); - }), 2500); - this.canPanX = false; - } + + // if (this.canPanX) { + // this.Document._panX = left - 5; + // setTimeout(action(() => { + // this.canPanX = true; + // this.panX(); + // }), 250); + // this.canPanX = false; + // } } else if (de.clientX - 315 - this._marqueeRef.current.clientLeft - this._marqueeRef.current.clientWidth < 25) { console.log("PAN right "); - if (this.canPanX) { - this.Document._panX = de.clientX - 315 - this._marqueeRef.current.clientLeft - - this._marqueeRef.current.clientWidth; - - setTimeout(action(() => { - this.panX(); - this.canPanX = true; - }), 2500); - this.canPanX = false; - } + + // if (this.canPanX) { + // this.Document._panX = left + 5; + // setTimeout(action(() => { + // this.panX(); + // this.canPanX = true; + // }), 250); + // this.canPanX = false; + // } } } @@ -1222,27 +1230,27 @@ export class CollectionFreeFormView extends CollectionSubView 0) { if (de.clientY - 120 - this._marqueeRef.current.clientTop < 25) { console.log("PAN top "); - if (this.canPanY) { - this.Document._panY = de.clientY - 20 - this._marqueeRef.current.clientTop; - setTimeout(action(() => { - this.canPanY = true; - this.panY(); - }), 2500); - this.canPanY = false; - } + + // if (this.canPanY) { + // this.Document._panY = top - 5; + // setTimeout(action(() => { + // this.canPanY = true; + // this.panY(); + // }), 250); + // this.canPanY = false; + // } } else if (de.clientY - 120 - this._marqueeRef.current.clientTop - this._marqueeRef.current.clientHeight < 25) { console.log("PAN bottom "); - if (this.canPanY) { - this.Document._panY = de.clientY - 120 - this._marqueeRef.current.clientTop - - this._marqueeRef.current.clientHeight; - - setTimeout(action(() => { - this.panY(); - this.canPanY = true; - }), 2500); - this.canPanY = false; - } + + // if (this.canPanY) { + // this.Document._panY = top + 5; + // setTimeout(action(() => { + // this.panY(); + // this.canPanY = true; + // }), 250); + // this.canPanY = false; + // } } diff --git a/src/client/views/nodes/DocumentLinksButton.tsx b/src/client/views/nodes/DocumentLinksButton.tsx index 44e72215d..ce96eddfe 100644 --- a/src/client/views/nodes/DocumentLinksButton.tsx +++ b/src/client/views/nodes/DocumentLinksButton.tsx @@ -3,7 +3,7 @@ import { observer } from "mobx-react"; import { Doc, DocListCast } from "../../../fields/Doc"; import { emptyFunction, setupMoveUpEvents, returnFalse } from "../../../Utils"; import { DragManager } from "../../util/DragManager"; -import { UndoManager } from "../../util/UndoManager"; +import { UndoManager, undoBatch } from "../../util/UndoManager"; import './DocumentLinksButton.scss'; import { DocumentView } from "./DocumentView"; import React = require("react"); @@ -29,7 +29,7 @@ export class DocumentLinksButton extends React.Component { if (this._linkButton.current !== null) { const linkDrag = UndoManager.StartBatch("Drag Link"); @@ -56,7 +56,7 @@ export class DocumentLinksButton extends React.Component { setupMoveUpEvents(this, e, this.onLinkButtonMoved, emptyFunction, action((e, doubleTap) => { if (doubleTap && this.props.InMenu) { diff --git a/src/client/views/nodes/formattedText/FormattedTextBox.tsx b/src/client/views/nodes/formattedText/FormattedTextBox.tsx index fc63dfbf5..30e0738bf 100644 --- a/src/client/views/nodes/formattedText/FormattedTextBox.tsx +++ b/src/client/views/nodes/formattedText/FormattedTextBox.tsx @@ -944,6 +944,8 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp frag.forEach(node => nodes.push(marker(node))); return Fragment.fromArray(nodes); } + + function addLinkMark(node: Node, title: string, linkId: string) { if (!node.isText) { const content = addMarkToFrag(node.content, (node: Node) => addLinkMark(node, title, linkId)); -- cgit v1.2.3-70-g09d2 From f774d6953d23dda9b8b20ed24b64e28607d3d88c Mon Sep 17 00:00:00 2001 From: Bob Zeleznik Date: Thu, 9 Jul 2020 14:53:52 -0400 Subject: fixed auto panning in collectionview. --- .../collectionFreeForm/CollectionFreeFormView.tsx | 124 +++++++++------------ 1 file changed, 51 insertions(+), 73 deletions(-) (limited to 'src/client/views/collections/collectionFreeForm') diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx index ffa4be4b9..7a7505319 100644 --- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx +++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx @@ -1172,89 +1172,67 @@ export class CollectionFreeFormView extends CollectionSubView @action - handleDragging = (e: Event, de: DragEvent) => { + handleDragging = (e: CustomEvent, de: DragEvent) => { const top = this.panX(); const left = this.panY(); const size = this.getTransform().transformDirection(this.props.PanelWidth(), this.props.PanelHeight()); - const scale = this.getLocalTransform().inverse().Scale; - if (this._marqueeRef) { - - if (this._marqueeRef.current) { - - // console.log("top: " + this._marqueeRef.current.clientTop); - // console.log("left: " + this._marqueeRef.current.clientLeft); - // console.log("width: " + this._marqueeRef.current.clientWidth); - // console.log("height: " + this._marqueeRef.current.clientHeight); - - console.log("width: " + this._marqueeRef.current.getBoundingClientRect().width); - console.log("height: " + this._marqueeRef.current.getBoundingClientRect().width); - console.log("x: " + this._marqueeRef.current.getBoundingClientRect().x); - console.log("y: " + this._marqueeRef.current.getBoundingClientRect().y); - - // console.log("mouse x: " + de.screenX); - // console.log("mouse y: " + de.screenY); - - - if (this._marqueeRef.current.clientWidth > 0) { - if (de.clientX - 315 - this._marqueeRef.current.clientLeft < 25) { - console.log("PAN left "); - - // if (this.canPanX) { - // this.Document._panX = left - 5; - // setTimeout(action(() => { - // this.canPanX = true; - // this.panX(); - // }), 250); - // this.canPanX = false; - // } - } else if (de.clientX - 315 - this._marqueeRef.current.clientLeft - - this._marqueeRef.current.clientWidth < 25) { - console.log("PAN right "); - - // if (this.canPanX) { - // this.Document._panX = left + 5; - // setTimeout(action(() => { - // this.panX(); - // this.canPanX = true; - // }), 250); - // this.canPanX = false; - // } - - } - } + if (this._marqueeRef?.current) { + const dragX = e.detail.clientX; + const dragY = e.detail.clientY; + const bounds = this._marqueeRef.current?.getBoundingClientRect()!; + + if (dragX - bounds.left < 25) { + console.log("PAN left "); + + // if (this.canPanX) { + // this.Document._panX = left - 5; + // setTimeout(action(() => { + // this.canPanX = true; + // this.panX(); + // }), 250); + // this.canPanX = false; + // } + } else if (bounds.right - dragX < 25) { + console.log("PAN right "); + + // if (this.canPanX) { + // this.Document._panX = left + 5; + // setTimeout(action(() => { + // this.panX(); + // this.canPanX = true; + // }), 250); + // this.canPanX = false; + // } - if (this._marqueeRef.current.clientHeight > 0) { - if (de.clientY - 120 - this._marqueeRef.current.clientTop < 25) { - console.log("PAN top "); - - // if (this.canPanY) { - // this.Document._panY = top - 5; - // setTimeout(action(() => { - // this.canPanY = true; - // this.panY(); - // }), 250); - // this.canPanY = false; - // } - } else if (de.clientY - 120 - this._marqueeRef.current.clientTop - - this._marqueeRef.current.clientHeight < 25) { - console.log("PAN bottom "); - - // if (this.canPanY) { - // this.Document._panY = top + 5; - // setTimeout(action(() => { - // this.panY(); - // this.canPanY = true; - // }), 250); - // this.canPanY = false; - // } + } - } + if (dragY - bounds.top < 25) { + console.log("PAN top "); + + // if (this.canPanY) { + // this.Document._panY = top - 5; + // setTimeout(action(() => { + // this.canPanY = true; + // this.panY(); + // }), 250); + // this.canPanY = false; + // } + } else if (bounds.bottom - dragY < 25) { + console.log("PAN bottom "); + + // if (this.canPanY) { + // this.Document._panY = top + 5; + // setTimeout(action(() => { + // this.panY(); + // this.canPanY = true; + // }), 250); + // this.canPanY = false; + // } - } } } } -- cgit v1.2.3-70-g09d2 From 065a29e87c771b5cd9301b0468fb036e070cad17 Mon Sep 17 00:00:00 2001 From: yunahi <60233430+yunahi@users.noreply.github.com> Date: Fri, 10 Jul 2020 05:08:53 +0900 Subject: added format shape --- src/client/documents/Documents.ts | 3 +- src/client/util/InteractionUtils.tsx | 8 + src/client/util/SelectionManager.ts | 5 + src/client/views/AntimodeMenu.tsx | 18 + src/client/views/ContextMenu.tsx | 1 + src/client/views/DocumentDecorations.tsx | 2 + src/client/views/GestureOverlay.tsx | 17 +- src/client/views/InkingStroke.tsx | 15 +- src/client/views/MainView.tsx | 13 +- .../collectionFreeForm/FormatShapePane.scss | 53 ++ .../collectionFreeForm/FormatShapePane.tsx | 996 +++++++++++++++++++++ .../collectionFreeForm/InkOptionsMenu.scss | 2 +- .../collectionFreeForm/InkOptionsMenu.tsx | 40 +- 13 files changed, 1152 insertions(+), 21 deletions(-) create mode 100644 src/client/views/collections/collectionFreeForm/FormatShapePane.scss create mode 100644 src/client/views/collections/collectionFreeForm/FormatShapePane.tsx (limited to 'src/client/views/collections/collectionFreeForm') diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts index b70971c2d..eb8e04317 100644 --- a/src/client/documents/Documents.ts +++ b/src/client/documents/Documents.ts @@ -653,7 +653,7 @@ export namespace Docs { I.type = DocumentType.INK; I.layout = InkingStroke.LayoutString("data"); I.color = color; - I.strokeWidth = strokeWidth; + I.strokeWidth = Number(strokeWidth); I.strokeBezier = strokeBezier; I.fillColor = fillColor; I.arrowStart = arrowStart; @@ -667,6 +667,7 @@ export namespace Docs { I._width = options._width; I._height = options._height; I.author = Doc.CurrentUserEmail; + I.rotation = 0; I.data = new InkField(points); return I; // return I; diff --git a/src/client/util/InteractionUtils.tsx b/src/client/util/InteractionUtils.tsx index edeb461e0..2883e2056 100644 --- a/src/client/util/InteractionUtils.tsx +++ b/src/client/util/InteractionUtils.tsx @@ -3,6 +3,7 @@ import * as beziercurve from 'bezier-curve'; import * as fitCurve from 'fit-curve'; import "./InteractionUtils.scss"; import { Utils } from "../../Utils"; +import InkOptionsMenu from "../views/collections/collectionFreeForm/InkOptionsMenu"; export namespace InteractionUtils { export const MOUSETYPE = "mouse"; @@ -94,6 +95,13 @@ export namespace InteractionUtils { export function CreatePolyline(points: { X: number, Y: number }[], left: number, top: number, color: string, width: number, strokeWidth: number, bezier: string, fill: string, arrowStart: string, arrowEnd: string, dash: string, scalex: number, scaley: number, shape: string, pevents: string, drawHalo: boolean, nodefs: boolean) { + + // if (InkOptionsMenu.Instance.Pinned) { + // for (var i = 0; i < points.length; i++) { + // points[i].Y -= 35; + // } + // } + let pts: { X: number; Y: number; }[] = []; if (shape) { //if any of the shape are true pts = makePolygon(shape, points); diff --git a/src/client/util/SelectionManager.ts b/src/client/util/SelectionManager.ts index 024532f90..aea2c542b 100644 --- a/src/client/util/SelectionManager.ts +++ b/src/client/util/SelectionManager.ts @@ -5,6 +5,7 @@ import { computedFn } from "mobx-utils"; import { List } from "../../fields/List"; import { Scripting } from "./Scripting"; import { DocumentManager } from "./DocumentManager"; +import FormatShapePane from "../views/collections/collectionFreeForm/FormatShapePane"; export namespace SelectionManager { @@ -14,6 +15,8 @@ export namespace SelectionManager { SelectedDocuments: ObservableMap = new ObservableMap(); @action SelectDoc(docView: DocumentView, ctrlPressed: boolean): void { + console.log("select" + ); // if doc is not in SelectedDocuments, add it if (!manager.SelectedDocuments.get(docView)) { if (!ctrlPressed) { @@ -29,6 +32,8 @@ export namespace SelectionManager { manager.SelectedDocuments.set(docView, true); } Doc.UserDoc().activeSelection = new List(SelectionManager.SelectedDocuments().map(dv => dv.props.Document)); + FormatShapePane.Instance.selected(); + } @action DeselectDoc(docView: DocumentView): void { diff --git a/src/client/views/AntimodeMenu.tsx b/src/client/views/AntimodeMenu.tsx index d83ac434c..cb6de1785 100644 --- a/src/client/views/AntimodeMenu.tsx +++ b/src/client/views/AntimodeMenu.tsx @@ -1,6 +1,7 @@ import React = require("react"); import { observable, action } from "mobx"; import "./AntimodeMenu.scss"; +import { inherits } from "util"; /** * This is an abstract class that serves as the base for a PDF-style or Marquee-style @@ -147,6 +148,23 @@ export default abstract class AntimodeMenu extends React.Component { ); } + protected getElementVert(buttons: JSX.Element[]) { + return ( +
+ {buttons} +
+ ); + } + protected getElementWithRows(rows: JSX.Element[], numRows: number, hasDragger: boolean = true) { diff --git a/src/client/views/ContextMenu.tsx b/src/client/views/ContextMenu.tsx index 941d7b44a..1a6b7ab90 100644 --- a/src/client/views/ContextMenu.tsx +++ b/src/client/views/ContextMenu.tsx @@ -224,6 +224,7 @@ export class ContextMenu extends React.Component { } render() { + console.log("context"); if (!this._display) { return null; } diff --git a/src/client/views/DocumentDecorations.tsx b/src/client/views/DocumentDecorations.tsx index 4fda10926..8edd4c4a9 100644 --- a/src/client/views/DocumentDecorations.tsx +++ b/src/client/views/DocumentDecorations.tsx @@ -293,6 +293,8 @@ export class DocumentDecorations extends React.Component<{}, { value: string }> SelectionManager.SelectedDocuments().forEach(action((element: DocumentView) => { const doc = Document(element.rootDoc); if (doc.type === DocumentType.INK && doc.x && doc.y && doc._width && doc._height && doc.data) { + doc.rotation = Number(doc.rotation) + Number(angle); + console.log(doc.rotation); const ink = Cast(doc.data, InkField)?.inkData; if (ink) { diff --git a/src/client/views/GestureOverlay.tsx b/src/client/views/GestureOverlay.tsx index bfd659207..26a06090b 100644 --- a/src/client/views/GestureOverlay.tsx +++ b/src/client/views/GestureOverlay.tsx @@ -633,7 +633,8 @@ export default class GestureOverlay extends Touchable { this.makePolygon(this.InkShape, false); this.dispatchGesture(GestureUtils.Gestures.Stroke); this._points = []; - if (this.InkShape !== "noRec") { + if (InkOptionsMenu.Instance._double === "") { + this.InkShape = ""; } } @@ -687,12 +688,14 @@ export default class GestureOverlay extends Touchable { } //get out of ink mode after each stroke= console.log("now"); - Doc.SetSelectedTool(InkTool.None); - InkOptionsMenu.Instance._selected = InkOptionsMenu.Instance._shapesNum; - SetActiveArrowStart("none"); - GestureOverlay.Instance.SavedArrowStart = ActiveArrowStart(); - SetActiveArrowEnd("none"); - GestureOverlay.Instance.SavedArrowEnd = ActiveArrowEnd(); + if (InkOptionsMenu.Instance._double === "") { + Doc.SetSelectedTool(InkTool.None); + InkOptionsMenu.Instance._selected = InkOptionsMenu.Instance._shapesNum; + SetActiveArrowStart("none"); + GestureOverlay.Instance.SavedArrowStart = ActiveArrowStart(); + SetActiveArrowEnd("none"); + GestureOverlay.Instance.SavedArrowEnd = ActiveArrowEnd(); + } document.removeEventListener("pointermove", this.onPointerMove); document.removeEventListener("pointerup", this.onPointerUp); diff --git a/src/client/views/InkingStroke.tsx b/src/client/views/InkingStroke.tsx index c32e76cec..4a7ec40be 100644 --- a/src/client/views/InkingStroke.tsx +++ b/src/client/views/InkingStroke.tsx @@ -15,6 +15,8 @@ import { FieldView, FieldViewProps } from "./nodes/FieldView"; import React = require("react"); import { Scripting } from "../util/Scripting"; import { Doc } from "../../fields/Doc"; +import FormatShapePane from "./collections/collectionFreeForm/FormatShapePane"; +import { action } from "mobx"; library.add(faPaintBrush); @@ -38,10 +40,19 @@ export class InkingStroke extends ViewBoxBaseComponent { + console.log("Clicked"); + FormatShapePane.Instance.Pinned = true; + FormatShapePane.Instance.selected(); + + } + render() { TraceMobx(); const data: InkData = Cast(this.dataDoc[this.fieldKey], InkField)?.inkData ?? []; - const strokeWidth = Number(StrCast(this.layoutDoc.strokeWidth, ActiveInkWidth())); + // const strokeWidth = Number(StrCast(this.layoutDoc.strokeWidth, ActiveInkWidth())); + const strokeWidth = Number(this.layoutDoc.strokeWidth); const xs = data.map(p => p.X); const ys = data.map(p => p.Y); const left = Math.min(...xs) - strokeWidth / 2; @@ -74,6 +85,8 @@ export class InkingStroke extends ViewBoxBaseComponent { ContextMenu.Instance.addItem({ description: "Analyze Stroke", event: this.analyzeStrokes, icon: "paint-brush" }); ContextMenu.Instance.addItem({ description: "Make Mask", event: this.makeMask, icon: "paint-brush" }); + ContextMenu.Instance.addItem({ description: "Format Shape", event: this.formatShape, icon: "paint-brush" }); + }} > diff --git a/src/client/views/MainView.tsx b/src/client/views/MainView.tsx index afdff4ed8..3eed44654 100644 --- a/src/client/views/MainView.tsx +++ b/src/client/views/MainView.tsx @@ -58,7 +58,7 @@ import { DocumentManager } from '../util/DocumentManager'; import { DocumentLinksButton } from './nodes/DocumentLinksButton'; import { LinkMenu } from './linking/LinkMenu'; import { LinkDocPreview } from './nodes/LinkDocPreview'; - +import FormatShapePane from "./collections/collectionFreeForm/FormatShapePane"; @observer export class MainView extends React.Component { public static Instance: MainView; @@ -453,12 +453,13 @@ export class MainView extends React.Component { @computed get mainContent() { const sidebar = this.userDoc?.["tabs-panelContainer"]; - console.log(InkOptionsMenu.Instance?.Pinned); + console.log('${ ANTIMODEMENU_HEIGHT }'); return !this.userDoc || !(sidebar instanceof Doc) ? (null) : (
@@ -597,7 +598,10 @@ export class MainView extends React.Component { + + + {this.mainContent} @@ -608,6 +612,7 @@ export class MainView extends React.Component { linkDoc={LinkDocPreview.LinkInfo.linkDoc} linkSrc={LinkDocPreview.LinkInfo.linkSrc} href={LinkDocPreview.LinkInfo.href} addDocTab={LinkDocPreview.LinkInfo.addDocTab} /> : (null)} + diff --git a/src/client/views/collections/collectionFreeForm/FormatShapePane.scss b/src/client/views/collections/collectionFreeForm/FormatShapePane.scss new file mode 100644 index 000000000..5789c6c75 --- /dev/null +++ b/src/client/views/collections/collectionFreeForm/FormatShapePane.scss @@ -0,0 +1,53 @@ +.antimodeMenu-button { + width: 200px; + + .color-previewI { + width: 100%; + height: 40%; + } + + .color-previewII { + width: 100%; + height: 100%; + } + + +} + +.sketch-picker { + background: #323232; + + .flexbox-fit { + background: #323232; + } +} + +.btn-group { + display: grid; + grid-template-columns: auto auto auto auto; + /* Make the buttons appear below each other */ +} + +.btn-group-palette { + display: block; + /* Make the buttons appear below each other */ +} + +.btn-draw { + display: inline; + /* Make the buttons appear below each other */ +} + +.btn2-group { + display: block; + background: #323232; + grid-template-columns: auto; + + /* Make the buttons appear below each other */ + .antimodeMenu-button { + background: #323232; + display: block; + + + } +} \ No newline at end of file diff --git a/src/client/views/collections/collectionFreeForm/FormatShapePane.tsx b/src/client/views/collections/collectionFreeForm/FormatShapePane.tsx new file mode 100644 index 000000000..7b47b7ca4 --- /dev/null +++ b/src/client/views/collections/collectionFreeForm/FormatShapePane.tsx @@ -0,0 +1,996 @@ +import React = require("react"); +import AntimodeMenu from "../../AntimodeMenu"; +import { observer } from "mobx-react"; +import { observable, action, computed } from "mobx"; +import "./FormatShapePane.scss"; +import { ActiveInkColor, ActiveInkBezierApprox, ActiveFillColor, ActiveArrowStart, ActiveArrowEnd, SetActiveInkWidth, SetActiveInkColor, SetActiveBezierApprox, SetActiveFillColor, SetActiveArrowStart, SetActiveArrowEnd, ActiveDash, SetActiveDash } from "../../InkingStroke"; +import { Scripting } from "../../../util/Scripting"; +import { InkTool, InkField } from "../../../../fields/InkField"; +import { ColorState } from "react-color"; +import { Utils } from "../../../../Utils"; +import GestureOverlay from "../../GestureOverlay"; +import { Doc } from "../../../../fields/Doc"; +import { SelectionManager } from "../../../util/SelectionManager"; +import { DocumentView } from "../../../views/nodes/DocumentView"; +import { Document } from "../../../../fields/documentSchemas"; +import { DocumentType } from "../../../documents/DocumentTypes"; +import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; +import { IconProp, library } from '@fortawesome/fontawesome-svg-core'; +import { faRulerCombined, faFillDrip, faPenNib } from "@fortawesome/free-solid-svg-icons"; +import { Cast, StrCast, BoolCast, NumCast } from "../../../../fields/Types"; +import e = require("express"); +import { ChangeEvent } from "mongodb"; +import { black } from "colors"; + + +library.add(faRulerCombined, faFillDrip, faPenNib); + +@observer +export default class FormatShapePane extends AntimodeMenu { + static Instance: FormatShapePane; + + private _palette = ["#D0021B", "#F5A623", "#F8E71C", "#8B572A", "#7ED321", "#417505", "#9013FE", "#4A90E2", "#50E3C2", "#B8E986", "#000000", "#4A4A4A", "#9B9B9B", "#FFFFFF"]; + private _width = ["1", "5", "10", "100"]; + private _mode = ["fill-drip", "ruler-combined"]; + private _subMenu = ["fill", "line", "size", "position"]; + private _headIcon = ["⎯", "←"]; + private _endIcon = ["⎯", "→"]; + private _head = ["none", "arrowHead"]; + private _end = ["none", "arrowEnd"]; + + @observable private _subOpen = [false, false, false, false]; + + @observable private collapsed: boolean = false; + @observable private currMode: string = "fill-drip"; + @observable _fillBtn = false; + @observable _lineBtn = false; + + @observable _selectDoc: DocumentView[] = []; + + @observable _noFill = false; + @observable _solidFill = false; + @observable _noLine = false; + @observable _solidLine = false; + @observable _dashLine = false; + @observable _lock = false; + + @observable _multiple = false; + + @observable _widthBtn = false; + + @observable _currWidth = "10"; + + @observable _single = false; + @observable _currFill = "#D0021B"; + @observable _currColor = "#D0021B"; + + @observable _arrowHead = false; + @observable _arrowEnd = false; + + + @observable _currSizeHeight = "10"; + @observable _currSizeWidth = "10"; + @observable _currRotation = "10"; + + @observable _currPositionHorizontal = "10"; + @observable _currPositionVertical = "10"; + + + constructor(props: Readonly<{}>) { + super(props); + FormatShapePane.Instance = this; + this._canFade = false; // don't let the inking menu fade away + this.Pinned = BoolCast(Doc.UserDoc()["formatShapePane-pinned"]); + + } + + @action + toggleMenuPin = (e: React.MouseEvent) => { + Doc.UserDoc()["formatShapePane-pinned"] = this.Pinned = !this.Pinned; + if (!this.Pinned) { + // this.fadeOut(true); + } + } + + @action + protected toggleCollapse = (e: React.MouseEvent) => { + this.collapsed = !this.collapsed; + setTimeout(() => { + const x = Math.min(this._left, window.innerWidth - FormatShapePane.Instance.width); + FormatShapePane.Instance.jumpTo(x, this._top, true); + }, 0); + } + + @action + closePane = () => { + this.jumpTo(-300, -300); + this.Pinned = false; + + } + + @action + checkSame = () => { + const docs = SelectionManager.SelectedDocuments(); + const inks: DocumentView[] = []; + for (var i = 0; i < docs.length; i++) { + if (Document(docs[i].rootDoc).type === DocumentType.INK) { + inks.push(docs[i]); + } + } + const firstWidth = Document(inks[0].rootDoc).strokeWidth; + const firstColor = Document(inks[0].rootDoc).color; + const firstFill = Document(inks[0].rootDoc).fillColor; + // const firstBezier + const firstRotation = Document(inks[0].rootDoc).rotation; + const firstArrowStart = Document(inks[0].rootDoc).arrowStart; + const firstArrowEnd = Document(inks[0].rootDoc).arrowEnd; + const firstDash = Document(inks[0].rootDoc).dash; + const firstWidthSize = Document(inks[0].rootDoc)._width; + const firstHeightSize = Document(inks[0].rootDoc)._height; + const firstHorizontal = Document(inks[0].rootDoc).x; + const firstVertical = Document(inks[0].rootDoc).y; + this._noFill = Document(inks[0].rootDoc).fillColor === "none" ? true : false; + this._solidFill = Document(inks[0].rootDoc).fillColor === "none" ? false : true; + this._noLine = Document(inks[0].rootDoc).color === "none" ? true : false; + if (Document(inks[0].rootDoc).color !== "none") { + this._solidLine = true; + this._dashLine = true; + if (Document(inks[0].rootDoc).dash === "0") { + this._dashLine = false; + } else { + this._solidLine = false; + + } + } + // this._solidLine = (Document(inks[0].rootDoc).color === "none") ? false : Document(inks[0].rootDoc).dash === 0 ? true : false; + // this._dashLine = (Document(inks[0].rootDoc).color === "none") ? false : Document(inks[0].rootDoc).dash !== 0 ? true : false; + // // this._widthBtn = false; + this._currWidth = String(Document(inks[0].rootDoc).strokeWidth); + // this._single = false; + this._currFill = String(Document(inks[0].rootDoc).fillColor); + this._currColor = String(Document(inks[0].rootDoc).color); + this._arrowHead = Document(inks[0].rootDoc).arrowStart === "none" ? false : true; + this._arrowEnd = Document(inks[0].rootDoc).arrowEnd === "none" ? false : true; + this._currSizeHeight = String(Document(inks[0].rootDoc)._height); + this._currSizeWidth = String(Document(inks[0].rootDoc)._width); + this._currRotation = String(Document(inks[0].rootDoc).rotation); + this._currPositionHorizontal = String(Document(inks[0].rootDoc).x); + this._currPositionVertical = String(Document(inks[0].rootDoc).y); + for (var i = 0; i < inks.length; i++) { + if (Document(inks[i].rootDoc).strokeWidth !== firstWidth) { + this._currWidth = ""; + } + if (Document(inks[i].rootDoc).color !== firstColor) { + this._noLine = false; + this._solidLine = false; + this._dashLine = false; + } + if (Document(inks[i].rootDoc).fillColor !== firstFill) { + this._solidFill = false; + this._noFill = false; + } + if (Document(inks[i].rootDoc).arrowStart !== firstArrowStart) { + this._arrowHead = false; + } + if (Document(inks[i].rootDoc).arrowEnd !== firstArrowEnd) { + this._arrowEnd = false; + } + if (Document(inks[i].rootDoc).x !== firstHorizontal) { + this._currPositionHorizontal = ""; + } + if (Document(inks[i].rootDoc).y !== firstVertical) { + this._currPositionVertical = ""; + } + if (Document(inks[i].rootDoc)._width !== firstWidthSize) { + this._currSizeWidth = ""; + } + if (Document(inks[i].rootDoc)._height !== firstHeightSize) { + this._currSizeHeight = ""; + } + if (Document(inks[i].rootDoc).rotation !== firstRotation) { + this._currRotation = ""; + } + } + + + + } + + @action + upDownButtons = (dirs: string, field: string) => { + SelectionManager.SelectedDocuments().forEach(action((element: DocumentView) => { + const doc = Document(element.rootDoc); + if (doc.type === DocumentType.INK) { + switch (field) { + case "width": + if (doc.strokeWidth) { + doc.strokeWidth = dirs === "up" ? doc.strokeWidth + 1 : doc.strokeWidth - 1; + SetActiveInkWidth(String(doc.strokeWidth)); + + } + break; + case "sizeWidth": + if (doc._width && doc._height) { + const oldWidth = doc._width; + const oldHeight = doc._height; + + doc._width = dirs === "up" ? doc._width + 10 : doc._width - 10; + if (this._lock) { + doc._height = (doc._width * oldHeight) / oldWidth; + } + } + break; + case "sizeHeight": + if (doc._width && doc._height) { + const oldWidth = doc._width; + const oldHeight = doc._height; + doc._height = dirs === "up" ? doc._height + 10 : doc._height - 10; + if (this._lock) { + doc._width = (doc._height * oldWidth) / oldHeight; + } + } + break; + case "horizontal": + if (doc.x) { + doc.x = dirs === "up" ? doc.x + 10 : doc.x - 10; + } + break; + case "vertical": + if (doc.y) { + doc.y = dirs === "up" ? doc.y + 10 : doc.y - 10; + } + case "rotation": + + this.rotate(dirs === "up" ? Number(doc.rotation) + Number(0.1) : Number(doc.rotation) - Number(0.1)); + + break; + default: + break; + } + this.selected(); + + } + })); + } + + @action + editProperties = (value: any, field: string) => { + SelectionManager.SelectedDocuments().forEach(action((element: DocumentView) => { + const doc = Document(element.rootDoc); + if (doc.type === DocumentType.INK) { + switch (field) { + case "width": + SetActiveInkWidth(value); + doc.strokeWidth = Number(value); + break; + case "color": + doc.color = String(value); + break; + case "fill": + doc.fillColor = String(value); + break; + case "bezier": + // doc.strokeBezier === 300 ? doc.strokeBezier = 0 : doc.strokeBezier = 300; + break; + case "arrowStart": + doc.arrowStart = String(value); + break; + case "arrowEnd": + doc.arrowEnd = String(value); + break; + case "dash": + doc.dash = String(value); + break; + case "widthSize": + if (doc._width && doc._height) { + const oldWidth = doc._width; + const oldHeight = doc._height; + + doc._width = Number(value); + if (this._lock) { + doc._height = (doc._width * oldHeight) / oldWidth; + } + } + break; + case "heightSize": + if (doc._width && doc._height) { + const oldWidth = doc._width; + const oldHeight = doc._height; + + doc._height = Number(value); + if (this._lock) { + doc._width = (doc._height * oldWidth) / oldHeight; + } + } + break; + case "horizontal": + doc.x = Number(value); + break; + case "vertical": + doc.y = Number(value); + + break; + default: + break; + } + } + this.selected(); + })); + this.checkSame(); + + } + + @computed get close() { + const close = ; + return close; + } + + @computed get modes() { + const modes =
+ {this._mode.map(mode => { + return ; + }) + }
; + return modes; + } + + @action + selected = () => { + this._selectDoc = SelectionManager.SelectedDocuments(); + if (this._selectDoc.length === 1 && Document(this._selectDoc[0].rootDoc).type === DocumentType.INK) { + this._single = true; + const doc = Document(this._selectDoc[0].rootDoc); + if (doc.type === DocumentType.INK) { + console.log(doc.fillColor); + if (doc.fillColor === "none") { + this._noFill = true; + this._solidFill = false; + } else { + this._solidFill = true; + this._noFill = false; + this._currFill = String(doc.fillColor); + } + if (doc.color === "none") { + this._noLine = true; + this._solidLine = false; + this._dashLine = false; + } else { + console.log(doc.strokeWidth); + this._currWidth = String(doc.strokeWidth); + this._currColor = String(doc.color); + if (doc.dash === "0") { + this._solidLine = true; + this._noLine = false; + this._dashLine = false; + } else { + this._dashLine = true; + this._noLine = false; + this._solidLine = false; + } + + this._arrowHead = doc.arrowStart === "none" ? false : true; + this._arrowEnd = doc.arrowEnd === "none" ? false : true; + + + this._currPositionHorizontal = String(doc.x); + this._currPositionVertical = String(doc.y); + console.log(doc.rotation); + this._currRotation = String(doc.rotation); + this._currSizeHeight = String(doc._height); + this._currSizeWidth = String(doc._width); + } + + } + } else { + this._noFill = false; + this._solidFill = false; + this._single = false; + this._currFill = "#D0021B"; + this._noLine = false; + this._solidLine = false; + this._dashLine = false; + this._currColor = "#D0021B"; + this._arrowHead = false; + this._arrowEnd = false; + this._currPositionHorizontal = ""; + this._currPositionVertical = ""; + this._currRotation = ""; + this._currSizeHeight = ""; + this._currSizeWidth = ""; + } + this.checkSame(); + } + + @action + rotate = (degrees: number) => { + SelectionManager.SelectedDocuments().forEach(action((element: DocumentView) => { + const doc = Document(element.rootDoc); + if (doc.type === DocumentType.INK && doc.x && doc.y && doc._width && doc._height && doc.data) { + // doc.rotation = (Number(doc.rotation) + (Number(angle) * 180 / Math.PI)); + // console.log(doc.rotation); + const angle = Number(degrees) - Number(doc.rotation); + doc.rotation = Number(degrees); + const ink = Cast(doc.data, InkField)?.inkData; + if (ink) { + const xs = ink.map(p => p.X); + const ys = ink.map(p => p.Y); + const left = Math.min(...xs); + const top = Math.min(...ys); + const right = Math.max(...xs); + const bottom = Math.max(...ys); + const _centerPoints: { X: number, Y: number }[] = []; + _centerPoints.push({ X: left, Y: top }); + + const newPoints: { X: number, Y: number }[] = []; + for (var i = 0; i < ink.length; i++) { + const newX = Math.cos(angle) * (ink[i].X - _centerPoints[0].X) - Math.sin(angle) * (ink[i].Y - _centerPoints[0].Y) + _centerPoints[0].X; + const newY = Math.sin(angle) * (ink[i].X - _centerPoints[0].X) + Math.cos(angle) * (ink[i].Y - _centerPoints[0].Y) + _centerPoints[0].Y; + newPoints.push({ X: newX, Y: newY }); + } + doc.data = new InkField(newPoints); + const xs2 = newPoints.map(p => p.X); + const ys2 = newPoints.map(p => p.Y); + const left2 = Math.min(...xs2); + const top2 = Math.min(...ys2); + const right2 = Math.max(...xs2); + const bottom2 = Math.max(...ys2); + + doc._height = (bottom2 - top2) * element.props.ScreenToLocalTransform().Scale; + doc._width = (right2 - left2) * element.props.ScreenToLocalTransform().Scale; + + } + } + })); + } + + @action + toggle = (check: string) => { + switch (check) { + case "noFill": + if (!this._noFill) { + this._noFill = true; + this._solidFill = false; + } + break; + case "solidFill": + if (!this._solidFill) { + this._solidFill = true; + this._noFill = false; + if (this._currFill === "none") { + this._currFill = "#D0021B"; + } + } + break; + case "noLine": + if (!this._noLine) { + this._noLine = true; + this._solidLine = false; + this._dashLine = false; + } + break; + case "solidLine": + if (!this._solidLine) { + this._solidLine = true; + this._noLine = false; + this._dashLine = false; + if (this._currColor === "none") { + this._currColor = "#D0021B"; + } + } + break; + case "dashLine": + if (!this._dashLine) { + this._dashLine = true; + this._solidLine = false; + this._noLine = false; + if (this._currColor === "none") { + this._currColor = "#D0021B"; + } + } + break; + case "lock": + if (this._lock) { + this._lock = false; + } else { + this._lock = true; + } + break; + case "arrowHead": + this._arrowHead = this._arrowHead ? false : true; + break; + case "arrowEnd": + this._arrowEnd = this._arrowEnd ? false : true; + break; + default: + break; + } + } + + @computed get subMenu() { + const fillCheck =
+ { this.toggle("noFill"); this.editProperties("none", "fill"); })} /> + No Fill +

+ { this.toggle("solidFill"); this.editProperties(this._currFill, "fill"); })} /> + Solid Fill +

+

+ {this._solidFill ? "Color" : ""} + {this._solidFill ? this.fillButton : ""} + {this._fillBtn && this._solidFill ? this.fillPicker : ""} + +
; + const arrows = <> { this.toggle("arrowHead"); this.editProperties(this._arrowHead ? "arrowHead" : "none", "arrowStart"); })} /> + Arrow Head +

+ + { this.toggle("arrowEnd"); this.editProperties(this._arrowEnd ? "arrowEnd" : "none", "arrowEnd"); })} /> + Arrow End +

; + const lineCheck =
+ { this.toggle("noLine"); this.editProperties("none", "color"); })} /> + No Line +

+ { this.toggle("solidLine"); this.editProperties(this._currColor, "color"); this.editProperties("0", "dash"); })} /> + Solid Line +

+ { this.toggle("dashLine"); this.editProperties(this._currColor, "color"); this.editProperties("2", "dash"); })} /> + Dash Line +

+

+ {(this._solidLine || this._dashLine) ? "Color" : ""} + {(this._solidLine || this._dashLine) ? this.lineButton : ""} + {this._lineBtn && (this._solidLine || this._dashLine) ? this.linePicker : ""} +

+ {(this._solidLine || this._dashLine) ? "Width" : ""} + {(this._solidLine || this._dashLine) ? this.widthInput : ""} +

+

+ {(this._solidLine || this._dashLine) ? arrows : ""} + +
; + + const sizeCheck =
+ Height {this.sizeHeightInput} +

+

+ + + Width {this.sizeWidthInput} +

+

+ + { this.toggle("lock"); })} /> + Lock Ratio +

+

+ + + Rotation {this.rotationInput} +

+

+ + +
; + const positionCheck =
+ Horizontal {this.positionHorizontalInput} +

+

+ + Vertical {this.positionVerticalInput} +

+

+ + +
; + + const subMenu =
+ {this._subMenu.map((subMenu, i) => { + if (subMenu === "fill" || subMenu === "line") { + return
+ {this.currMode === "fill-drip" && subMenu === "fill" && this._subOpen[0] ? fillCheck : ""} + {this.currMode === "fill-drip" && subMenu === "line" && this._subOpen[1] ? lineCheck : ""} + +
; + } + else if (subMenu === "size" || subMenu === "position") { + return
+ {this.currMode === "ruler-combined" && subMenu === "size" && this._subOpen[2] ? sizeCheck : ""} + {this.currMode === "ruler-combined" && subMenu === "position" && this._subOpen[3] ? positionCheck : ""} + +
+ ; + + } + }) + }
; + return subMenu; + } + + @computed get fillButton() { + const fillButton = <> +

+

; + return fillButton; + } + @computed get fillPicker() { + const fillPicker =
+ {this._palette.map(color => { + return ; + })} + +
; + return fillPicker; + } + + @computed get lineButton() { + const lineButton = <> +

+

; + return lineButton; + } + @computed get linePicker() { + const linePicker =
+ {this._palette.map(color => { + return ; + })} + +
; + return linePicker; + } + @computed get widthInput() { + const widthInput = <> + this.onChange(e.target.value, "width")} + autoFocus> +
+ ; + return widthInput; + } + @computed get sizeHeightInput() { + const sizeHeightInput = <> + this.onChange(e.target.value, "sizeHeight")} + autoFocus> + +
+ + ; + return sizeHeightInput; + } + + @computed get sizeWidthInput() { + const sizeWidthInput = <> + this.onChange(e.target.value, "sizeWidth")} + autoFocus> + +

+ ; + return sizeWidthInput; + } + + @computed get rotationInput() { + const rotationInput = + <> + this.onChange(e.target.value, "rotation")} + autoFocus> + +

+ ; + return rotationInput; + } + + @computed get positionHorizontalInput() { + const positionHorizontalInput = + <> this.onChange(e.target.value, "positionHorizontal")} + autoFocus> + +

+ ; + return positionHorizontalInput; + } + + @computed get positionVerticalInput() { + const positionVerticalInput = + <> this.onChange(e.target.value, "positionVertical")} + autoFocus> + +

+ ; + return positionVerticalInput; + } + + + @action + onChange = (val: string, property: string): void => { + if (!Number.isNaN(Number(val)) && Number(val) !== null && val !== " ") { + + // if (val === "") { + // val = "0"; + // } + switch (property) { + case "width": + this._currWidth = val; + if (val !== "") { + this.editProperties(this._currWidth, "width"); + } + break; + case "sizeHeight": + this._currSizeHeight = val; + if (val !== "") { + this.editProperties(this._currSizeHeight, "heightSize"); + } + break; + case "sizeWidth": + this._currSizeWidth = val; + if (val !== "") { + + this.editProperties(this._currSizeWidth, "widthSize"); + } + break; + case "rotation": + + this._currRotation = val; + if (val !== "") { + + this.rotate(Number(val)); + } + break; + case "positionHorizontal": + this._currPositionHorizontal = val; if (val !== "") { + + this.editProperties(this._currPositionHorizontal, "horizontal"); + } + + break; + case "positionVertical": + this._currPositionVertical = val; + if (val !== "") { + + this.editProperties(this._currPositionVertical, "vertical"); + } + + break; + default: + break; + } + } + } + + + + + // @action + // changeWidth = (event: React.ChangeEvent) => { + // console.log(event.target.value); + // this._currWidth = NumCast(event.target.value); + + // } + + @computed get upDown() { + const upDown =
+ +

+ +
; + return upDown; + } + + + @computed get widthPicker() { + var widthPicker = ; + if (this._widthBtn) { + widthPicker =
+ {widthPicker} + {this._width.map(wid => { + return ; + })} +
; + } + return widthPicker; + } + + + + render() { + const buttons = [ + + this.close, + this.modes, + this.subMenu + + ]; + + return this.getElementVert(buttons); + } +} +Scripting.addGlobal(function activatePen2(penBtn: any) { + if (penBtn) { + //no longer changes to inkmode + // Doc.SetSelectedTool(InkTool.Pen); + FormatShapePane.Instance.jumpTo(300, 300); + FormatShapePane.Instance.Pinned = true; + + } else { + // Doc.SetSelectedTool(InkTool.None); + FormatShapePane.Instance.Pinned = false; + FormatShapePane.Instance.fadeOut(true); + + } +}); \ No newline at end of file diff --git a/src/client/views/collections/collectionFreeForm/InkOptionsMenu.scss b/src/client/views/collections/collectionFreeForm/InkOptionsMenu.scss index 7329f4fc1..f739fcc8c 100644 --- a/src/client/views/collections/collectionFreeForm/InkOptionsMenu.scss +++ b/src/client/views/collections/collectionFreeForm/InkOptionsMenu.scss @@ -32,7 +32,7 @@ } .btn2-group { - display: block; + display: grid; background: #323232; grid-template-columns: auto; diff --git a/src/client/views/collections/collectionFreeForm/InkOptionsMenu.tsx b/src/client/views/collections/collectionFreeForm/InkOptionsMenu.tsx index 7de70b8cd..e4f3248d0 100644 --- a/src/client/views/collections/collectionFreeForm/InkOptionsMenu.tsx +++ b/src/client/views/collections/collectionFreeForm/InkOptionsMenu.tsx @@ -36,14 +36,15 @@ export default class InkOptionsMenu extends AntimodeMenu { // private _arrowEnd = ["none", "arrowEnd", "none", "dot", "none"]; // private _arrowIcons = ["→", "↔︎", "•", "••", " "]; private _draw = ["⎯", "→", "↔︎", "∿", "↝", "↭", "ロ", "O", "∆"]; - private _head = ["none", "arrowHead", "arrowHead", "none", "arrowHead", "arrowHead", "none", "none", "none"]; - private _end = ["none", "none", "arrowEnd", "none", "none", "arrowEnd", "none", "none", "none"]; + private _head = ["none", "none", "arrowHead", "none", "none", "arrowHead", "none", "none", "none"]; + private _end = ["none", "arrowEnd", "arrowEnd", "none", "arrowEnd", "arrowEnd", "none", "none", "none"]; private _shape = ["", "", "", "", "", "", "rectangle", "circle", "triangle"]; @observable _shapesNum = this._shape.length; @observable _selected = this._shapesNum; @observable private collapsed: boolean = false; + @observable _double = ""; @observable _colorBtn = false; @observable _widthBtn = false; @@ -155,7 +156,7 @@ export default class InkOptionsMenu extends AntimodeMenu { className="antimodeMenu-button" key={icon} onPointerDown={action(() => { - console.log(this._selected); + this._double = ""; if (this._selected !== i) { this._selected = i; @@ -177,6 +178,31 @@ export default class InkOptionsMenu extends AntimodeMenu { } console.log(this._selected); + })} + onDoubleClick={action(() => { + console.log("double"); + this._double = this._draw[i]; + if (this._selected !== i) { + this._selected = i; + Doc.SetSelectedTool(InkTool.Pen); + SetActiveArrowStart(this._head[i]); + SetActiveArrowEnd(this._end[i]); + SetActiveBezierApprox("300"); + + // this.editProperties(this._head[i], "arrowStart"), this.editProperties(this._end[i], "arrowEnd"); + GestureOverlay.Instance.InkShape = this._shape[i]; + } else { + this._selected = this._shapesNum; + Doc.SetSelectedTool(InkTool.None); + SetActiveArrowStart("none"); + SetActiveArrowEnd("none"); + GestureOverlay.Instance.InkShape = ""; + SetActiveBezierApprox("0"); + + } + + + })} style={{ backgroundColor: i === this._selected ? "121212" : "", fontSize: "20" }}> {this._draw[i]} @@ -235,7 +261,7 @@ export default class InkOptionsMenu extends AntimodeMenu { className="antimodeMenu-button" key={wid} onPointerDown={action(() => { SetActiveInkWidth(wid); this._widthBtn = false; this.editProperties(wid, "width"); })} - style={{ backgroundColor: this._widthBtn ? "121212" : "" }}> + style={{ backgroundColor: this._widthBtn ? "121212" : "", zIndex: 1001 }}> {wid} ; })} @@ -265,7 +291,7 @@ export default class InkOptionsMenu extends AntimodeMenu { className="antimodeMenu-button" key={color} onPointerDown={action(() => { this.changeColor(color, "color"); this._colorBtn = false; this.editProperties(color, "color"); })} - style={{ backgroundColor: this._colorBtn ? "121212" : "" }}> + style={{ backgroundColor: this._colorBtn ? "121212" : "", zIndex: 1001 }}> {/* */}
; @@ -286,14 +312,14 @@ export default class InkOptionsMenu extends AntimodeMenu {
; if (this._fillBtn) { - fillPicker =
+ fillPicker =
{fillPicker} {this._palette.map(color => { return ; })} -- cgit v1.2.3-70-g09d2 From c8454d675a3081a83c56cf598b1b3637479b0459 Mon Sep 17 00:00:00 2001 From: yunahi <60233430+yunahi@users.noreply.github.com> Date: Fri, 10 Jul 2020 05:22:06 +0900 Subject: added format shape --- src/client/util/SelectionManager.ts | 3 +- .../collectionFreeForm/FormatShapePane.tsx | 137 ++++----------------- 2 files changed, 24 insertions(+), 116 deletions(-) (limited to 'src/client/views/collections/collectionFreeForm') diff --git a/src/client/util/SelectionManager.ts b/src/client/util/SelectionManager.ts index aea2c542b..af2f320d3 100644 --- a/src/client/util/SelectionManager.ts +++ b/src/client/util/SelectionManager.ts @@ -15,8 +15,7 @@ export namespace SelectionManager { SelectedDocuments: ObservableMap = new ObservableMap(); @action SelectDoc(docView: DocumentView, ctrlPressed: boolean): void { - console.log("select" - ); + // if doc is not in SelectedDocuments, add it if (!manager.SelectedDocuments.get(docView)) { if (!ctrlPressed) { diff --git a/src/client/views/collections/collectionFreeForm/FormatShapePane.tsx b/src/client/views/collections/collectionFreeForm/FormatShapePane.tsx index 7b47b7ca4..37ba805b6 100644 --- a/src/client/views/collections/collectionFreeForm/FormatShapePane.tsx +++ b/src/client/views/collections/collectionFreeForm/FormatShapePane.tsx @@ -3,12 +3,9 @@ import AntimodeMenu from "../../AntimodeMenu"; import { observer } from "mobx-react"; import { observable, action, computed } from "mobx"; import "./FormatShapePane.scss"; -import { ActiveInkColor, ActiveInkBezierApprox, ActiveFillColor, ActiveArrowStart, ActiveArrowEnd, SetActiveInkWidth, SetActiveInkColor, SetActiveBezierApprox, SetActiveFillColor, SetActiveArrowStart, SetActiveArrowEnd, ActiveDash, SetActiveDash } from "../../InkingStroke"; +import { SetActiveInkWidth } from "../../InkingStroke"; import { Scripting } from "../../../util/Scripting"; -import { InkTool, InkField } from "../../../../fields/InkField"; -import { ColorState } from "react-color"; -import { Utils } from "../../../../Utils"; -import GestureOverlay from "../../GestureOverlay"; +import { InkField } from "../../../../fields/InkField"; import { Doc } from "../../../../fields/Doc"; import { SelectionManager } from "../../../util/SelectionManager"; import { DocumentView } from "../../../views/nodes/DocumentView"; @@ -19,9 +16,6 @@ import { IconProp, library } from '@fortawesome/fontawesome-svg-core'; import { faRulerCombined, faFillDrip, faPenNib } from "@fortawesome/free-solid-svg-icons"; import { Cast, StrCast, BoolCast, NumCast } from "../../../../fields/Types"; import e = require("express"); -import { ChangeEvent } from "mongodb"; -import { black } from "colors"; - library.add(faRulerCombined, faFillDrip, faPenNib); @@ -33,63 +27,42 @@ export default class FormatShapePane extends AntimodeMenu { private _width = ["1", "5", "10", "100"]; private _mode = ["fill-drip", "ruler-combined"]; private _subMenu = ["fill", "line", "size", "position"]; - private _headIcon = ["⎯", "←"]; - private _endIcon = ["⎯", "→"]; - private _head = ["none", "arrowHead"]; - private _end = ["none", "arrowEnd"]; - @observable private _subOpen = [false, false, false, false]; - @observable private collapsed: boolean = false; @observable private currMode: string = "fill-drip"; @observable _fillBtn = false; @observable _lineBtn = false; - @observable _selectDoc: DocumentView[] = []; - @observable _noFill = false; @observable _solidFill = false; @observable _noLine = false; @observable _solidLine = false; @observable _dashLine = false; @observable _lock = false; - @observable _multiple = false; - @observable _widthBtn = false; - - @observable _currWidth = "10"; - @observable _single = false; - @observable _currFill = "#D0021B"; - @observable _currColor = "#D0021B"; - @observable _arrowHead = false; @observable _arrowEnd = false; - - @observable _currSizeHeight = "10"; @observable _currSizeWidth = "10"; @observable _currRotation = "10"; - @observable _currPositionHorizontal = "10"; @observable _currPositionVertical = "10"; - + @observable _currWidth = "10"; + @observable _currFill = "#D0021B"; + @observable _currColor = "#D0021B"; constructor(props: Readonly<{}>) { super(props); FormatShapePane.Instance = this; - this._canFade = false; // don't let the inking menu fade away + this._canFade = false; this.Pinned = BoolCast(Doc.UserDoc()["formatShapePane-pinned"]); - } @action toggleMenuPin = (e: React.MouseEvent) => { Doc.UserDoc()["formatShapePane-pinned"] = this.Pinned = !this.Pinned; - if (!this.Pinned) { - // this.fadeOut(true); - } } @action @@ -105,9 +78,9 @@ export default class FormatShapePane extends AntimodeMenu { closePane = () => { this.jumpTo(-300, -300); this.Pinned = false; - } + //if multiple inks are selected and do not share the same prop, leave blank @action checkSame = () => { const docs = SelectionManager.SelectedDocuments(); @@ -117,18 +90,6 @@ export default class FormatShapePane extends AntimodeMenu { inks.push(docs[i]); } } - const firstWidth = Document(inks[0].rootDoc).strokeWidth; - const firstColor = Document(inks[0].rootDoc).color; - const firstFill = Document(inks[0].rootDoc).fillColor; - // const firstBezier - const firstRotation = Document(inks[0].rootDoc).rotation; - const firstArrowStart = Document(inks[0].rootDoc).arrowStart; - const firstArrowEnd = Document(inks[0].rootDoc).arrowEnd; - const firstDash = Document(inks[0].rootDoc).dash; - const firstWidthSize = Document(inks[0].rootDoc)._width; - const firstHeightSize = Document(inks[0].rootDoc)._height; - const firstHorizontal = Document(inks[0].rootDoc).x; - const firstVertical = Document(inks[0].rootDoc).y; this._noFill = Document(inks[0].rootDoc).fillColor === "none" ? true : false; this._solidFill = Document(inks[0].rootDoc).fillColor === "none" ? false : true; this._noLine = Document(inks[0].rootDoc).color === "none" ? true : false; @@ -142,11 +103,7 @@ export default class FormatShapePane extends AntimodeMenu { } } - // this._solidLine = (Document(inks[0].rootDoc).color === "none") ? false : Document(inks[0].rootDoc).dash === 0 ? true : false; - // this._dashLine = (Document(inks[0].rootDoc).color === "none") ? false : Document(inks[0].rootDoc).dash !== 0 ? true : false; - // // this._widthBtn = false; this._currWidth = String(Document(inks[0].rootDoc).strokeWidth); - // this._single = false; this._currFill = String(Document(inks[0].rootDoc).fillColor); this._currColor = String(Document(inks[0].rootDoc).color); this._arrowHead = Document(inks[0].rootDoc).arrowStart === "none" ? false : true; @@ -157,45 +114,43 @@ export default class FormatShapePane extends AntimodeMenu { this._currPositionHorizontal = String(Document(inks[0].rootDoc).x); this._currPositionVertical = String(Document(inks[0].rootDoc).y); for (var i = 0; i < inks.length; i++) { - if (Document(inks[i].rootDoc).strokeWidth !== firstWidth) { + if (Document(inks[i].rootDoc).strokeWidth !== Document(inks[0].rootDoc).strokeWidth) { this._currWidth = ""; } - if (Document(inks[i].rootDoc).color !== firstColor) { + if (Document(inks[i].rootDoc).color !== Document(inks[0].rootDoc).color) { this._noLine = false; this._solidLine = false; this._dashLine = false; } - if (Document(inks[i].rootDoc).fillColor !== firstFill) { + if (Document(inks[i].rootDoc).fillColor !== Document(inks[0].rootDoc).fillColor) { this._solidFill = false; this._noFill = false; } - if (Document(inks[i].rootDoc).arrowStart !== firstArrowStart) { + if (Document(inks[i].rootDoc).arrowStart !== Document(inks[0].rootDoc).arrowStart) { this._arrowHead = false; } - if (Document(inks[i].rootDoc).arrowEnd !== firstArrowEnd) { + if (Document(inks[i].rootDoc).arrowEnd !== Document(inks[0].rootDoc).arrowEnd) { this._arrowEnd = false; } - if (Document(inks[i].rootDoc).x !== firstHorizontal) { + if (Document(inks[i].rootDoc).x !== Document(inks[0].rootDoc).x) { this._currPositionHorizontal = ""; } - if (Document(inks[i].rootDoc).y !== firstVertical) { + if (Document(inks[i].rootDoc).y !== Document(inks[0].rootDoc).y) { this._currPositionVertical = ""; } - if (Document(inks[i].rootDoc)._width !== firstWidthSize) { + if (Document(inks[i].rootDoc)._width !== Document(inks[0].rootDoc)._width) { this._currSizeWidth = ""; } - if (Document(inks[i].rootDoc)._height !== firstHeightSize) { + if (Document(inks[i].rootDoc)._height !== Document(inks[0].rootDoc)._height) { this._currSizeHeight = ""; } - if (Document(inks[i].rootDoc).rotation !== firstRotation) { + if (Document(inks[i].rootDoc).rotation !== Document(inks[0].rootDoc).rotation) { this._currRotation = ""; } } - - - } + @action upDownButtons = (dirs: string, field: string) => { SelectionManager.SelectedDocuments().forEach(action((element: DocumentView) => { @@ -206,14 +161,12 @@ export default class FormatShapePane extends AntimodeMenu { if (doc.strokeWidth) { doc.strokeWidth = dirs === "up" ? doc.strokeWidth + 1 : doc.strokeWidth - 1; SetActiveInkWidth(String(doc.strokeWidth)); - } break; case "sizeWidth": if (doc._width && doc._height) { const oldWidth = doc._width; const oldHeight = doc._height; - doc._width = dirs === "up" ? doc._width + 10 : doc._width - 10; if (this._lock) { doc._height = (doc._width * oldHeight) / oldWidth; @@ -240,19 +193,17 @@ export default class FormatShapePane extends AntimodeMenu { doc.y = dirs === "up" ? doc.y + 10 : doc.y - 10; } case "rotation": - this.rotate(dirs === "up" ? Number(doc.rotation) + Number(0.1) : Number(doc.rotation) - Number(0.1)); - break; default: break; } this.selected(); - } })); } + @action editProperties = (value: any, field: string) => { SelectionManager.SelectedDocuments().forEach(action((element: DocumentView) => { @@ -270,7 +221,6 @@ export default class FormatShapePane extends AntimodeMenu { doc.fillColor = String(value); break; case "bezier": - // doc.strokeBezier === 300 ? doc.strokeBezier = 0 : doc.strokeBezier = 300; break; case "arrowStart": doc.arrowStart = String(value); @@ -285,7 +235,6 @@ export default class FormatShapePane extends AntimodeMenu { if (doc._width && doc._height) { const oldWidth = doc._width; const oldHeight = doc._height; - doc._width = Number(value); if (this._lock) { doc._height = (doc._width * oldHeight) / oldWidth; @@ -296,7 +245,6 @@ export default class FormatShapePane extends AntimodeMenu { if (doc._width && doc._height) { const oldWidth = doc._width; const oldHeight = doc._height; - doc._height = Number(value); if (this._lock) { doc._width = (doc._height * oldWidth) / oldHeight; @@ -308,7 +256,6 @@ export default class FormatShapePane extends AntimodeMenu { break; case "vertical": doc.y = Number(value); - break; default: break; @@ -331,13 +278,14 @@ export default class FormatShapePane extends AntimodeMenu { return close; } + //select either coor&fill or size&position @computed get modes() { const modes =
{this._mode.map(mode => { return ; @@ -346,6 +294,7 @@ export default class FormatShapePane extends AntimodeMenu { return modes; } + //detects currently selected document and change value in pane @action selected = () => { this._selectDoc = SelectionManager.SelectedDocuments(); @@ -353,7 +302,6 @@ export default class FormatShapePane extends AntimodeMenu { this._single = true; const doc = Document(this._selectDoc[0].rootDoc); if (doc.type === DocumentType.INK) { - console.log(doc.fillColor); if (doc.fillColor === "none") { this._noFill = true; this._solidFill = false; @@ -382,11 +330,8 @@ export default class FormatShapePane extends AntimodeMenu { this._arrowHead = doc.arrowStart === "none" ? false : true; this._arrowEnd = doc.arrowEnd === "none" ? false : true; - - this._currPositionHorizontal = String(doc.x); this._currPositionVertical = String(doc.y); - console.log(doc.rotation); this._currRotation = String(doc.rotation); this._currSizeHeight = String(doc._height); this._currSizeWidth = String(doc._width); @@ -418,8 +363,6 @@ export default class FormatShapePane extends AntimodeMenu { SelectionManager.SelectedDocuments().forEach(action((element: DocumentView) => { const doc = Document(element.rootDoc); if (doc.type === DocumentType.INK && doc.x && doc.y && doc._width && doc._height && doc.data) { - // doc.rotation = (Number(doc.rotation) + (Number(angle) * 180 / Math.PI)); - // console.log(doc.rotation); const angle = Number(degrees) - Number(doc.rotation); doc.rotation = Number(degrees); const ink = Cast(doc.data, InkField)?.inkData; @@ -446,10 +389,8 @@ export default class FormatShapePane extends AntimodeMenu { const top2 = Math.min(...ys2); const right2 = Math.max(...xs2); const bottom2 = Math.max(...ys2); - doc._height = (bottom2 - top2) * element.props.ScreenToLocalTransform().Scale; doc._width = (right2 - left2) * element.props.ScreenToLocalTransform().Scale; - } } })); @@ -854,14 +795,11 @@ export default class FormatShapePane extends AntimodeMenu { return positionVerticalInput; } - + //change inputs @action onChange = (val: string, property: string): void => { if (!Number.isNaN(Number(val)) && Number(val) !== null && val !== " ") { - // if (val === "") { - // val = "0"; - // } switch (property) { case "width": this._currWidth = val; @@ -912,35 +850,6 @@ export default class FormatShapePane extends AntimodeMenu { } - - - // @action - // changeWidth = (event: React.ChangeEvent) => { - // console.log(event.target.value); - // this._currWidth = NumCast(event.target.value); - - // } - - @computed get upDown() { - const upDown =
- -

- -
; - return upDown; - } - - @computed get widthPicker() { var widthPicker =
-
+
Math.min(350, NumCast(target._width, 350))} - PanelHeight={() => Math.min(250, NumCast(target._height, 250))} + PanelWidth={() => 170} //Math.min(350, NumCast(target._width, 350))} + PanelHeight={() => 170} //Math.min(250, NumCast(target._height, 250))} focus={emptyFunction} whenActiveChanged={returnFalse} bringToFront={returnFalse} ContentScaling={returnOne} - NativeWidth={returnZero} - NativeHeight={returnZero} + NativeWidth={() => target._nativeWidth ? NumCast(target._nativeWidth) : 0} + NativeHeight={() => target._nativeHeight ? NumCast(target._nativeHeight) : 0} />
; -- cgit v1.2.3-70-g09d2 From 3d0c64cf9979f739177b0efd9970ad0e0a9fa3d0 Mon Sep 17 00:00:00 2001 From: anika-ahluwalia Date: Thu, 9 Jul 2020 17:00:12 -0500 Subject: small changes --- src/client/documents/Documents.ts | 6 +----- .../collections/collectionFreeForm/CollectionFreeFormView.tsx | 8 +++++--- src/client/views/linking/LinkMenuItem.tsx | 2 +- src/client/views/nodes/formattedText/FormattedTextBox.tsx | 2 ++ 4 files changed, 9 insertions(+), 9 deletions(-) (limited to 'src/client/views/collections/collectionFreeForm') diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts index 565e7c25d..fa85d58f0 100644 --- a/src/client/documents/Documents.ts +++ b/src/client/documents/Documents.ts @@ -909,7 +909,7 @@ export namespace DocUtils { DocUtils.ActiveRecordings.map(d => DocUtils.MakeLink({ doc: doc }, { doc: d }, "audio link", "audio timeline")); } - export function MakeLink(source: { doc: Doc }, target: { doc: Doc }, linkRelationship: string = "", description: string = "", id?: string, linkedText?: string) { + export function MakeLink(source: { doc: Doc }, target: { doc: Doc }, linkRelationship: string = "", description: string = "", id?: string) { const sv = DocumentManager.Instance.getDocumentView(source.doc); if (sv && sv.props.ContainingCollectionDoc === target.doc) return; if (target.doc === Doc.UserDoc()) return undefined; @@ -921,10 +921,6 @@ export namespace DocUtils { Doc.GetProto(source.doc).links = ComputedField.MakeFunction("links(self)"); Doc.GetProto(target.doc).links = ComputedField.MakeFunction("links(self)"); - if (linkedText) { - Doc.GetProto(linkDoc).linkedText = linkedText; - } - return linkDoc; } diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx index 965bfdf24..9d79c0c89 100644 --- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx +++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx @@ -1181,17 +1181,19 @@ export class CollectionFreeFormView extends CollectionSubView { this.props.destinationDoc.type === "screenshot" ? "photo-video" : this.props.destinationDoc.type === "webcam" ? "video" : this.props.destinationDoc.type === "audio" ? "microphone" : - this.props.destinationDoc.type === "button" ? "lightning" : + this.props.destinationDoc.type === "button" ? "bolt" : this.props.destinationDoc.type === "presentation" ? "tv" : this.props.destinationDoc.type === "query" ? "search" : this.props.destinationDoc.type === "script" ? "terminal" : diff --git a/src/client/views/nodes/formattedText/FormattedTextBox.tsx b/src/client/views/nodes/formattedText/FormattedTextBox.tsx index bff6f1c8c..4f6927d3d 100644 --- a/src/client/views/nodes/formattedText/FormattedTextBox.tsx +++ b/src/client/views/nodes/formattedText/FormattedTextBox.tsx @@ -176,9 +176,11 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp doLinkOnDeselect() { console.log("link on deselect"); + Array.from(this.linkOnDeselect.entries()).map(entry => { const key = entry[0]; const value = entry[1]; + const id = Utils.GenerateDeterministicGuid(this.dataDoc[Id] + key); DocServer.GetRefField(value).then(doc => { DocServer.GetRefField(id).then(linkDoc => { -- cgit v1.2.3-70-g09d2 From 756a2d4e680bcdcc339e8f2493f699bb01e3fbb0 Mon Sep 17 00:00:00 2001 From: Bob Zeleznik Date: Thu, 9 Jul 2020 18:37:03 -0400 Subject: fixed type errors. --- .../views/collections/collectionFreeForm/CollectionFreeFormView.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/client/views/collections/collectionFreeForm') diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx index 9d79c0c89..f2a39b240 100644 --- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx +++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx @@ -1172,7 +1172,7 @@ export class CollectionFreeFormView extends CollectionSubView - _lastClientY = 0; + _lastClientY: number | undefined = 0; @action handleDragging = (e: CustomEvent, de: DragEvent) => { if ((e as any).handlePan) return; @@ -1233,7 +1233,7 @@ export class CollectionFreeFormView extends CollectionSubView { setTimeout(() => { const dragY = this._lastClientY; - if (this._lastClientY !== undefined && this._marqueeRef.current) { + if (dragY !== undefined && this._marqueeRef.current) { const bounds = this._marqueeRef.current.getBoundingClientRect()!; this.Document._panY = NumCast(this.Document._panY) + delta; (dragY - bounds.top < 25 || bounds.bottom - dragY < 25) && this.continueYPan(delta); -- cgit v1.2.3-70-g09d2 From b9ba531c64fe7926a6794ab57e4989e1ea6c6992 Mon Sep 17 00:00:00 2001 From: Bob Zeleznik Date: Fri, 10 Jul 2020 11:23:44 -0400 Subject: fixes for x/y panning on drag --- .../collectionFreeForm/CollectionFreeFormView.tsx | 66 ++++++---------------- 1 file changed, 16 insertions(+), 50 deletions(-) (limited to 'src/client/views/collections/collectionFreeForm') diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx index f2a39b240..3fdf6683e 100644 --- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx +++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx @@ -84,6 +84,8 @@ export class CollectionFreeFormView extends CollectionSubView = new Map(); @@ -579,7 +581,7 @@ export class CollectionFreeFormView extends CollectionSubView { - this._lastClientY = undefined; + this._lastClientY = this._lastClientX = undefined; if (InteractionUtils.IsType(e, InteractionUtils.TOUCHTYPE)) return; document.removeEventListener("pointermove", this.onPointerMove); @@ -1172,76 +1174,40 @@ export class CollectionFreeFormView extends CollectionSubView - _lastClientY: number | undefined = 0; @action handleDragging = (e: CustomEvent, de: DragEvent) => { if ((e as any).handlePan) return; (e as any).handlePan = true; - const top = this.panX(); - const left = this.panY(); this._lastClientY = e.detail.clientY; - - console.log("draggg"); - - const size = this.getTransform().transformDirection(this.props.PanelWidth(), this.props.PanelHeight()); - const scale = this.getLocalTransform().inverse().Scale; + this._lastClientX = e.detail.clientX; if (this._marqueeRef?.current) { - - console.log("hellp"); - const dragX = e.detail.clientX; const dragY = e.detail.clientY; const bounds = this._marqueeRef.current?.getBoundingClientRect(); - if (dragX - bounds.left < 25) { - console.log("PAN left "); - - if (this.canPanX) { - this.Document._panX = left - 5; - setTimeout(action(() => { - this.canPanX = true; - this.panX(); - }), 250); - this.canPanX = false; - } - } else if (bounds.right - dragX < 25) { - console.log("PAN right "); - - if (this.canPanX) { - this.Document._panX = left + 5; - setTimeout(action(() => { - this.panX(); - this.canPanX = true; - }), 250); - this.canPanX = false; - } - - } - - if (dragY - bounds.top < 25) { - console.log("PAN top "); - this.continueYPan(-2); - } else if (bounds.bottom - dragY < 25) { - console.log("PAN bottom "); - this.continueYPan(2); - } + let deltaX = dragX - bounds.left < 25 ? -2 : bounds.right - dragX < 25 ? 2 : 0; + let deltaY = dragY - bounds.top < 25 ? -2 : bounds.bottom - dragY < 25 ? 2 : 0; + (deltaX !== 0 || deltaY !== 0) && this.continuePan(deltaX, deltaY); } e.stopPropagation(); } - continueYPan = (delta: number) => { + continuePan = (deltaX: number, deltaY: number) => { setTimeout(() => { const dragY = this._lastClientY; - if (dragY !== undefined && this._marqueeRef.current) { + const dragX = this._lastClientX; + if (dragY !== undefined && dragX !== undefined && this._marqueeRef.current) { const bounds = this._marqueeRef.current.getBoundingClientRect()!; - this.Document._panY = NumCast(this.Document._panY) + delta; - (dragY - bounds.top < 25 || bounds.bottom - dragY < 25) && this.continueYPan(delta); - } else this._lastClientY !== undefined && this.continueYPan(delta); + this.Document._panY = NumCast(this.Document._panY) + deltaY; + this.Document._panX = NumCast(this.Document._panX) + deltaX; + if (dragY - bounds.top < 25 || bounds.bottom - dragY < 25 || dragX - bounds.left < 25 || bounds.right - dragX < 25) { + this.continuePan(deltaX, deltaY); + } + } else this._lastClientY !== undefined && this._lastClientX !== undefined && this.continuePan(deltaX, deltaY); }, 50); } - promoteCollection = undoBatch(action(() => { const childDocs = this.childDocs.slice(); childDocs.forEach(doc => { -- cgit v1.2.3-70-g09d2 From d064024d9ab2cd8e836df5ba75e064d77617445b Mon Sep 17 00:00:00 2001 From: Bob Zeleznik Date: Fri, 10 Jul 2020 11:25:08 -0400 Subject: from last --- .../views/collections/collectionFreeForm/CollectionFreeFormView.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/client/views/collections/collectionFreeForm') diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx index 3fdf6683e..2191021d2 100644 --- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx +++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx @@ -1194,7 +1194,7 @@ export class CollectionFreeFormView extends CollectionSubView { - setTimeout(() => { + setTimeout(action(() => { const dragY = this._lastClientY; const dragX = this._lastClientX; if (dragY !== undefined && dragX !== undefined && this._marqueeRef.current) { @@ -1205,7 +1205,7 @@ export class CollectionFreeFormView extends CollectionSubView { -- cgit v1.2.3-70-g09d2 From 5a70fb56062d6a5ed45cf3cf4453089bc83f3c6b Mon Sep 17 00:00:00 2001 From: anika-ahluwalia Date: Fri, 10 Jul 2020 18:11:09 -0500 Subject: added showing individual links with one bug --- .../collectionFreeForm/CollectionFreeFormLinkView.tsx | 4 ++-- src/client/views/linking/LinkMenuItem.tsx | 13 ++++++++++--- src/client/views/nodes/DocumentLinksButton.tsx | 8 +++++++- src/client/views/nodes/DocumentView.tsx | 18 ++++++++++++++---- 4 files changed, 33 insertions(+), 10 deletions(-) (limited to 'src/client/views/collections/collectionFreeForm') diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinkView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinkView.tsx index a24693c30..ae79c27e0 100644 --- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinkView.tsx +++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinkView.tsx @@ -110,10 +110,10 @@ export class CollectionFreeFormLinkView extends React.Component - {text !== "-ungrouped-" ? text : ""} + {text} diff --git a/src/client/views/linking/LinkMenuItem.tsx b/src/client/views/linking/LinkMenuItem.tsx index f7d189b20..8fc1ea12f 100644 --- a/src/client/views/linking/LinkMenuItem.tsx +++ b/src/client/views/linking/LinkMenuItem.tsx @@ -177,11 +177,16 @@ export class LinkMenuItem extends React.Component { DocumentLinksButton.EditLink = undefined; } + @action + showLink = () => { + this.props.linkDoc.hidden = !this.props.linkDoc.hidden; + } + render() { const keys = LinkManager.Instance.getMetadataKeysInGroup(this.props.groupType);//groupMetadataKeys.get(this.props.groupType); const canExpand = keys ? keys.length > 0 : false; - const eyeIcon = this.props.linkDoc.shown ? "eye-slash" : "eye"; + const eyeIcon = this.props.linkDoc.hidden ? "eye-slash" : "eye"; const destinationIcon = this.props.destinationDoc.type === "image" ? "image" : this.props.destinationDoc.type === "comparison" ? "columns" : @@ -208,7 +213,9 @@ export class LinkMenuItem extends React.Component { // from anika to bob: here's where the text that is specifically linked would show up (linkDoc.storedText) // ... const source = this.props.sourceDoc.type === "rtf" ? this.props.linkDoc.storedText ? - "stored text would show up here" : undefined : undefined; + StrCast(this.props.linkDoc.storedText).length > 17 ? + StrCast(this.props.linkDoc.storedText).substr(0, 18) + : this.props.linkDoc.storedText : undefined : undefined; return (
@@ -243,7 +250,7 @@ export class LinkMenuItem extends React.Component {
: <>} -
+
diff --git a/src/client/views/nodes/DocumentLinksButton.tsx b/src/client/views/nodes/DocumentLinksButton.tsx index 22431117e..f07a2ea5a 100644 --- a/src/client/views/nodes/DocumentLinksButton.tsx +++ b/src/client/views/nodes/DocumentLinksButton.tsx @@ -95,6 +95,9 @@ export class DocumentLinksButton extends React.Component { LinkCreatedBox.popupX = e.screenX; LinkCreatedBox.popupY = e.screenY - 133; @@ -123,6 +126,9 @@ export class DocumentLinksButton extends React.Component { LinkCreatedBox.popupX = e.screenX; LinkCreatedBox.popupY = e.screenY - 133; @@ -173,7 +179,7 @@ export class DocumentLinksButton extends React.Component : (null)}
; - return (!links.length || links[0].hidden) && !this.props.AlwaysOn ? (null) : + return (!links.length) && !this.props.AlwaysOn ? (null) : {linkButton} ; diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx index 97e3bc01c..310260832 100644 --- a/src/client/views/nodes/DocumentView.tsx +++ b/src/client/views/nodes/DocumentView.tsx @@ -201,6 +201,8 @@ export class DocumentView extends DocComponent(Docu this._mainCont.current && (this.multiTouchDisposer = InteractionUtils.MakeMultiTouchTarget(this._mainCont.current, this.onTouchStart.bind(this))); // this._mainCont.current && (this.holdDisposer = InteractionUtils.MakeHoldTouchTarget(this._mainCont.current, this.handle1PointerHoldStart.bind(this))); + //this.layoutDoc.showAllLinks = true; + if (!this.props.dontRegisterView) { DocumentManager.Instance.DocumentViews.push(this); } @@ -646,6 +648,8 @@ export class DocumentView extends DocComponent(Docu const linkDoc = DocUtils.MakeLink({ doc: de.complete.annoDragData.annotationDocument }, { doc: this.props.Document }, "link"); LinkManager.currentLink = linkDoc; + linkDoc ? linkDoc.hidden = true : null; + linkDoc ? linkDoc.linkDisplay = true : null; runInAction(() => { LinkCreatedBox.popupX = de.x; @@ -668,6 +672,8 @@ export class DocumentView extends DocComponent(Docu const linkDoc = DocUtils.MakeLink({ doc: de.complete.linkDragData.linkSourceDocument }, { doc: this.props.Document }, `link`); LinkManager.currentLink = linkDoc; + linkDoc ? linkDoc.hidden = true : null; + linkDoc ? linkDoc.linkDisplay = true : null; de.complete.linkDragData.linkSourceDocument !== this.props.Document && (de.complete.linkDragData.linkDocument = linkDoc); // TODODO this is where in text links get passed @@ -783,9 +789,12 @@ export class DocumentView extends DocComponent(Docu const optionItems: ContextMenuProps[] = options && "subitems" in options ? options.subitems : []; const templateDoc = Cast(this.props.Document[StrCast(this.props.Document.layoutKey)], Doc, null); templateDoc && optionItems.push({ description: "Open Template ", event: () => this.props.addDocTab(templateDoc, "onRight"), icon: "eye" }); - optionItems.push({ description: "Toggle Show Each Link Dot", event: () => this.layoutDoc.showLinks = !this.layoutDoc.showLinks, icon: "eye" }); + optionItems.push({ + description: "Toggle Show Each Link Dot", event: () => { this.layoutDoc.showAllLinks = !this.layoutDoc.showAllLinks; }, icon: "eye" + }); !options && cm.addItem({ description: "Options...", subitems: optionItems, icon: "compass" }); + const existingOnClick = cm.findByDescription("OnClick..."); const onClicks: ContextMenuProps[] = existingOnClick && "subitems" in existingOnClick ? existingOnClick.subitems : []; onClicks.push({ description: "Enter Portal", event: this.makeIntoPortal, icon: "window-restore" }); @@ -1084,7 +1093,7 @@ export class DocumentView extends DocComponent(Docu select={this.select} onClick={this.onClickHandler} layoutKey={this.finalLayoutKey} /> - {this.layoutDoc.showLinks ? this.anchors : (null)} + {this.layoutDoc.showAllLinks ? this.allAnchors : null} {this.props.forcedBackgroundColor?.(this.Document) === "transparent" || this.props.dontRegisterView ? (null) : }
); @@ -1107,7 +1116,8 @@ export class DocumentView extends DocComponent(Docu hideLinkAnchor = (doc: Doc | Doc[]) => (doc instanceof Doc ? [doc] : doc).reduce((flg: boolean, doc) => flg && (doc.hidden = true), true) anchorPanelWidth = () => this.props.PanelWidth() || 1; anchorPanelHeight = () => this.props.PanelHeight() || 1; - @computed get anchors() { + + @computed get allAnchors() { TraceMobx(); return (this.props.treeViewDoc && this.props.LayoutTemplateString) || // render nothing for: tree view anchor dots this.layoutDoc.presBox || // presentationbox nodes @@ -1133,7 +1143,7 @@ export class DocumentView extends DocComponent(Docu if (this.props.treeViewDoc && !this.props.LayoutTemplateString) { // this happens when the document is a tree view label (but not an anchor dot) return
{StrCast(this.props.Document.title)} - {this.anchors} + {this.allAnchors}
; } -- cgit v1.2.3-70-g09d2 From 6b5c11a26e114f26f3907342f9afbd47b27cecf4 Mon Sep 17 00:00:00 2001 From: Bob Zeleznik Date: Sat, 11 Jul 2020 17:54:20 -0400 Subject: restructured ink to make more react-friendly --- src/client/util/CurrentUserUtils.ts | 6 +- src/client/util/InteractionUtils.tsx | 21 +- src/client/util/SelectionManager.ts | 3 - src/client/views/AntimodeMenu.tsx | 1 - src/client/views/DocumentDecorations.tsx | 5 +- src/client/views/InkingStroke.tsx | 18 +- .../collectionFreeForm/FormatShapePane.tsx | 801 +++++++-------------- .../collectionFreeForm/InkOptionsMenu.tsx | 24 +- src/client/views/nodes/ColorBox.tsx | 1 - 9 files changed, 299 insertions(+), 581 deletions(-) (limited to 'src/client/views/collections/collectionFreeForm') diff --git a/src/client/util/CurrentUserUtils.ts b/src/client/util/CurrentUserUtils.ts index d0ca0e57e..0b644fa79 100644 --- a/src/client/util/CurrentUserUtils.ts +++ b/src/client/util/CurrentUserUtils.ts @@ -760,9 +760,9 @@ export class CurrentUserUtils { doc.activeInkColor = StrCast(doc.activeInkColor, "rgb(0, 0, 0)"); doc.activeInkWidth = StrCast(doc.activeInkWidth, "1"); doc.activeInkBezier = StrCast(doc.activeInkBezier, "0"); - doc.activeFillColor = StrCast(doc.activeFillColor, "none"); - doc.activeArrowStart = StrCast(doc.activeArrowStart, "none"); - doc.activeArrowEnd = StrCast(doc.activeArrowEnd, "none"); + doc.activeFillColor = StrCast(doc.activeFillColor, ""); + doc.activeArrowStart = StrCast(doc.activeArrowStart, ""); + doc.activeArrowEnd = StrCast(doc.activeArrowEnd, ""); doc.activeDash = StrCast(doc.activeDash, "0"); doc.fontSize = NumCast(doc.fontSize, 12); doc["constants-snapThreshold"] = NumCast(doc["constants-snapThreshold"], 10); // diff --git a/src/client/util/InteractionUtils.tsx b/src/client/util/InteractionUtils.tsx index 2883e2056..6ab7bcc87 100644 --- a/src/client/util/InteractionUtils.tsx +++ b/src/client/util/InteractionUtils.tsx @@ -3,7 +3,6 @@ import * as beziercurve from 'bezier-curve'; import * as fitCurve from 'fit-curve'; import "./InteractionUtils.scss"; import { Utils } from "../../Utils"; -import InkOptionsMenu from "../views/collections/collectionFreeForm/InkOptionsMenu"; export namespace InteractionUtils { export const MOUSETYPE = "mouse"; @@ -96,12 +95,6 @@ export namespace InteractionUtils { color: string, width: number, strokeWidth: number, bezier: string, fill: string, arrowStart: string, arrowEnd: string, dash: string, scalex: number, scaley: number, shape: string, pevents: string, drawHalo: boolean, nodefs: boolean) { - // if (InkOptionsMenu.Instance.Pinned) { - // for (var i = 0; i < points.length; i++) { - // points[i].Y -= 35; - // } - // } - let pts: { X: number; Y: number; }[] = []; if (shape) { //if any of the shape are true pts = makePolygon(shape, points); @@ -127,15 +120,15 @@ export namespace InteractionUtils { const dashArray = String(Number(width) * Number(dash)); const defGuid = Utils.GenerateGuid(); const arrowDim = Math.max(0.5, 8 / Math.log(Math.max(2, strokeWidth))); - return ( {/* setting the svg fill sets the arrowhead fill */} + return ( {/* setting the svg fill sets the arrowStart fill */} {nodefs ? (null) : {arrowStart !== "dot" && arrowEnd !== "dot" ? (null) : } - {arrowStart !== "arrowHead" && arrowEnd !== "arrowHead" ? (null) : + {arrowStart !== "arrow" && arrowEnd !== "arrow" ? (null) : } - {arrowStart !== "arrowEnd" && arrowEnd !== "arrowEnd" ? (null) : + {arrowStart !== "arrow" && arrowEnd !== "arrow" ? (null) : } } @@ -144,7 +137,7 @@ export namespace InteractionUtils { points={strpts} style={{ filter: drawHalo ? "url(#inkSelectionHalo)" : undefined, - fill, + fill: fill ? fill : "transparent", opacity: strokeWidth !== width ? 0.5 : undefined, pointerEvents: pevents as any, stroke: color ?? "rgb(0, 0, 0)", @@ -153,8 +146,8 @@ export namespace InteractionUtils { strokeLinecap: "round", strokeDasharray: dashArray }} - markerStart={`url(#${arrowStart + defGuid})`} - markerEnd={`url(#${arrowEnd + defGuid})`} + markerStart={`url(#${arrowStart + "Start" + defGuid})`} + markerEnd={`url(#${arrowEnd + "End" + defGuid})`} /> ); @@ -163,7 +156,7 @@ export namespace InteractionUtils { // export function makeArrow() { // return ( // InkOptionsMenu.Instance.getColors().map(color => { - // const id1 = "arrowHeadTest" + color; + // const id1 = "arrowStartTest" + color; // console.log(color); // // diff --git a/src/client/util/SelectionManager.ts b/src/client/util/SelectionManager.ts index af2f320d3..9a968aeda 100644 --- a/src/client/util/SelectionManager.ts +++ b/src/client/util/SelectionManager.ts @@ -5,7 +5,6 @@ import { computedFn } from "mobx-utils"; import { List } from "../../fields/List"; import { Scripting } from "./Scripting"; import { DocumentManager } from "./DocumentManager"; -import FormatShapePane from "../views/collections/collectionFreeForm/FormatShapePane"; export namespace SelectionManager { @@ -31,8 +30,6 @@ export namespace SelectionManager { manager.SelectedDocuments.set(docView, true); } Doc.UserDoc().activeSelection = new List(SelectionManager.SelectedDocuments().map(dv => dv.props.Document)); - FormatShapePane.Instance.selected(); - } @action DeselectDoc(docView: DocumentView): void { diff --git a/src/client/views/AntimodeMenu.tsx b/src/client/views/AntimodeMenu.tsx index cb6de1785..3303a5e68 100644 --- a/src/client/views/AntimodeMenu.tsx +++ b/src/client/views/AntimodeMenu.tsx @@ -1,7 +1,6 @@ import React = require("react"); import { observable, action } from "mobx"; import "./AntimodeMenu.scss"; -import { inherits } from "util"; /** * This is an abstract class that serves as the base for a PDF-style or Marquee-style diff --git a/src/client/views/DocumentDecorations.tsx b/src/client/views/DocumentDecorations.tsx index 8edd4c4a9..81b4f9162 100644 --- a/src/client/views/DocumentDecorations.tsx +++ b/src/client/views/DocumentDecorations.tsx @@ -152,8 +152,8 @@ export class DocumentDecorations extends React.Component<{}, { value: string }> if (e.button === 0 && !e.altKey && !e.ctrlKey) { let child = SelectionManager.SelectedDocuments()[0].ContentDiv!.children[0]; while (child.children.length) { - const next = Array.from(child.children).find(c => !c.className.includes("collectionViewChrome")); - if (next?.className.includes("documentView-node")) break; + const next = Array.from(child.children).find(c => typeof (c.className) !== "string" || !c.className.includes("collectionViewChrome")); + if (typeof (next?.className) === "string" && next?.className.includes("documentView-node")) break; if (next) child = next; else break; } @@ -294,7 +294,6 @@ export class DocumentDecorations extends React.Component<{}, { value: string }> const doc = Document(element.rootDoc); if (doc.type === DocumentType.INK && doc.x && doc.y && doc._width && doc._height && doc.data) { doc.rotation = Number(doc.rotation) + Number(angle); - console.log(doc.rotation); const ink = Cast(doc.data, InkField)?.inkData; if (ink) { diff --git a/src/client/views/InkingStroke.tsx b/src/client/views/InkingStroke.tsx index 7d9a3c8b3..224abfd77 100644 --- a/src/client/views/InkingStroke.tsx +++ b/src/client/views/InkingStroke.tsx @@ -43,8 +43,6 @@ export class InkingStroke extends ViewBoxBaseComponent { FormatShapePane.Instance.Pinned = true; - FormatShapePane.Instance.selected(); - } render() { @@ -62,14 +60,14 @@ export class InkingStroke extends ViewBoxBaseComponent 5 ? strokeColor : "transparent", strokeWidth, (strokeWidth + 15), - StrCast(this.layoutDoc.strokeBezier, ActiveInkBezierApprox()), StrCast(this.layoutDoc.fillColor, ActiveFillColor()), + StrCast(this.layoutDoc.strokeBezier), StrCast(this.layoutDoc.fillColor, "transparent"), "none", "none", "0", scaleX, scaleY, "", this.props.active() ? "visiblepainted" : "none", false, true); return ( p && !i.rootDoc.fillColor ? true : false, true) || false; + } + @computed get _solidFill() { + return this.inks?.reduce((p, i) => p && i.rootDoc.fillColor ? true : false, true) || false; + } + set _noFill(value) { this._currFill = value ? "" : this._lastFill; } + set _solidFill(value) { this._noFill = !value; } + + @computed get _noLine() { + return this.inks?.reduce((p, i) => p && !i.rootDoc.color ? true : false, true) || false; + } + @computed get _solidLine() { + return this.inks?.reduce((p, i) => p && + i.rootDoc.color && (i.rootDoc.dash === undefined || i.rootDoc.dash === "0") ? true : false, true) || false; + } + @computed get _dashLine() { + return !this._noLine && this.inks?.reduce((p, i) => + (p === undefined || (p && p === i.rootDoc.dash)) && i.rootDoc.dash !== "0" ? StrCast(i.rootDoc.dash) : "", undefined as Opt) || ""; + } + set _noLine(value) { this._currColor = value ? "" : this._lastLine; } + set _solidLine(value) { this._dashLine = ""; this._noLine = !value; } + set _dashLine(value) { + value && (this._lastDash = value); this._noLine = false; + this.inks?.forEach(i => i.rootDoc.dash = value ? this._lastDash : undefined) + } + + @computed get _currFill() { + const cfill = this._noFill || !this.inks ? "" : StrCast(this.inks[0].rootDoc.fillColor); + cfill && (this._lastFill = cfill); + return cfill; + } + @computed get _currColor() { + const ccol = this._noLine || !this.inks ? "" : StrCast(this.inks[0].rootDoc.color, ""); + this._lastLine = ccol ? ccol : this._lastLine; + return ccol; + } + set _currFill(value) { value && (this._lastFill = value); this.inks?.forEach(i => i.rootDoc.fillColor = value); } + set _currColor(value) { value && (this._lastLine = value); this.inks?.forEach(i => i.rootDoc.color = value ? value : undefined) } + + @computed get _arrowStart() { + return this.inks?.reduce((p, i) => + (p === undefined || (p && p === i.rootDoc.arrowStart)) ? StrCast(i.rootDoc.arrowStart) : "", undefined as Opt) || ""; + } + @computed get _arrowEnd() { + return this.inks?.reduce((p, i) => + (p === undefined || (p && p === i.rootDoc.arrowEnd)) ? StrCast(i.rootDoc.arrowEnd) : "", undefined as Opt) || "" + } + set _arrowStart(value) { this.inks?.forEach(i => i.rootDoc.arrowStart = value); } + set _arrowEnd(value) { this.inks?.forEach(i => i.rootDoc.arrowEnd = value); } + + @computed get _currSizeHeight() { + return this.inks?.reduce((p, i) => + (p === undefined || (p === NumCast(i.rootDoc._height).toString())) ? NumCast(i.rootDoc._height).toString() : "", undefined as Opt) || "" + } + @computed get _currSizeWidth() { + return this.inks?.reduce((p, i) => + (p === undefined || (p === NumCast(i.rootDoc._width).toString())) ? NumCast(i.rootDoc._width).toString() : "", undefined as Opt) || "" + } + @computed get _currRotation() { + return this.inks?.reduce((p, i) => + (p === undefined || (p === NumCast(i.rootDoc.rotation).toString())) ? NumCast(i.rootDoc.rotation).toString() : "", undefined as Opt) || "" + } + @computed get _currPositionHorizontal() { + return this.inks?.reduce((p, i) => + (p === undefined || (p === NumCast(i.rootDoc.x).toString())) ? NumCast(i.rootDoc.x).toString() : "", undefined as Opt) || "" + } + @computed get _currPositionVertical() { + return this.inks?.reduce((p, i) => + (p === undefined || (p === NumCast(i.rootDoc.y).toString())) ? NumCast(i.rootDoc.y).toString() : "", undefined as Opt) || "" + } + @computed get _currStrokeWidth() { + return this.inks?.reduce((p, i) => + (p === undefined || (p === NumCast(i.rootDoc.strokeWidth).toString())) ? NumCast(i.rootDoc.strokeWidth).toString() : "", undefined as Opt) || "" + } + set _currPositionHorizontal(value) { this.inks?.forEach(i => i.rootDoc.x = Number(value)); } + set _currPositionVertical(value) { this.inks?.forEach(i => i.rootDoc.y = Number(value)); } + set _currRotation(value) { this.inks?.forEach(i => i.rootDoc.rotation = Number(value)); } + set _currStrokeWidth(value) { this.inks?.forEach(i => i.rootDoc.strokeWidth = Number(value)); } + set _currSizeWidth(value) { + this.inks?.forEach(i => { + const doc = i.rootDoc; + if (doc._width && doc._height) { + const oldWidth = NumCast(doc._width); + const oldHeight = NumCast(doc._height); + doc._width = Number(value); + if (this._lock) { + doc._height = (doc._width * oldHeight) / oldWidth; + } + } + }); + } + set _currSizeHeight(value) { + this.inks?.forEach(i => { + const doc = i.rootDoc; + if (doc._width && doc._height) { + const oldWidth = NumCast(doc._width); + const oldHeight = NumCast(doc._height); + doc._height = Number(value); + if (this._lock) { + doc._width = (doc._height * oldWidth) / oldHeight; + } + } + }); + } constructor(props: Readonly<{}>) { super(props); @@ -80,191 +178,40 @@ export default class FormatShapePane extends AntimodeMenu { this.Pinned = false; } - //if multiple inks are selected and do not share the same prop, leave blank - @action - checkSame = () => { - const docs = SelectionManager.SelectedDocuments(); - const inks: DocumentView[] = []; - for (var i = 0; i < docs.length; i++) { - if (Document(docs[i].rootDoc).type === DocumentType.INK) { - inks.push(docs[i]); - } - } - this._noFill = Document(inks[0].rootDoc).fillColor === "none" ? true : false; - this._solidFill = Document(inks[0].rootDoc).fillColor === "none" ? false : true; - this._noLine = Document(inks[0].rootDoc).color === "none" ? true : false; - if (Document(inks[0].rootDoc).color !== "none") { - this._solidLine = true; - this._dashLine = true; - if (Document(inks[0].rootDoc).dash === "0") { - this._dashLine = false; - } else { - this._solidLine = false; - - } - } - this._currWidth = String(Document(inks[0].rootDoc).strokeWidth); - this._currFill = String(Document(inks[0].rootDoc).fillColor); - this._currColor = String(Document(inks[0].rootDoc).color); - this._arrowHead = Document(inks[0].rootDoc).arrowStart === "none" ? false : true; - this._arrowEnd = Document(inks[0].rootDoc).arrowEnd === "none" ? false : true; - this._currSizeHeight = String(Document(inks[0].rootDoc)._height); - this._currSizeWidth = String(Document(inks[0].rootDoc)._width); - this._currRotation = String(Document(inks[0].rootDoc).rotation); - this._currPositionHorizontal = String(Document(inks[0].rootDoc).x); - this._currPositionVertical = String(Document(inks[0].rootDoc).y); - for (var i = 0; i < inks.length; i++) { - if (Document(inks[i].rootDoc).strokeWidth !== Document(inks[0].rootDoc).strokeWidth) { - this._currWidth = ""; - } - if (Document(inks[i].rootDoc).color !== Document(inks[0].rootDoc).color) { - this._noLine = false; - this._solidLine = false; - this._dashLine = false; - } - if (Document(inks[i].rootDoc).fillColor !== Document(inks[0].rootDoc).fillColor) { - this._solidFill = false; - this._noFill = false; - } - if (Document(inks[i].rootDoc).arrowStart !== Document(inks[0].rootDoc).arrowStart) { - this._arrowHead = false; - } - if (Document(inks[i].rootDoc).arrowEnd !== Document(inks[0].rootDoc).arrowEnd) { - this._arrowEnd = false; - } - if (Document(inks[i].rootDoc).x !== Document(inks[0].rootDoc).x) { - this._currPositionHorizontal = ""; - } - if (Document(inks[i].rootDoc).y !== Document(inks[0].rootDoc).y) { - this._currPositionVertical = ""; - } - if (Document(inks[i].rootDoc)._width !== Document(inks[0].rootDoc)._width) { - this._currSizeWidth = ""; - } - if (Document(inks[i].rootDoc)._height !== Document(inks[0].rootDoc)._height) { - this._currSizeHeight = ""; - } - if (Document(inks[i].rootDoc).rotation !== Document(inks[0].rootDoc).rotation) { - this._currRotation = ""; - } - } - } - - @action upDownButtons = (dirs: string, field: string) => { - SelectionManager.SelectedDocuments().forEach(action((element: DocumentView) => { - const doc = Document(element.rootDoc); - if (doc.type === DocumentType.INK) { - switch (field) { - case "width": - if (doc.strokeWidth) { - doc.strokeWidth = dirs === "up" ? doc.strokeWidth + 1 : doc.strokeWidth - 1; - SetActiveInkWidth(String(doc.strokeWidth)); + switch (field) { + case "horizontal": this.inks?.forEach(i => i.rootDoc.x = NumCast(i.rootDoc.x) + (dirs === "up" ? 10 : -10)); break; + case "vertical": this.inks?.forEach(i => i.rootDoc.y = NumCast(i.rootDoc.y) + (dirs === "up" ? 10 : -10)); break; + case "rotation": this.rotate((dirs === "up" ? .1 : -.1)); break; + case "width": this.inks?.forEach(i => i.rootDoc.strokeWidth = NumCast(i.rootDoc.strokeWidth) + (dirs === "up" ? .1 : -.1)); break; + case "sizeWidth": + this.inks?.forEach(i => { + const doc = i.rootDoc; + if (doc._width && doc._height) { + const oldWidth = NumCast(doc._width); + const oldHeight = NumCast(doc._height); + doc._width = NumCast(doc._width) + (dirs === "up" ? 10 : - 10); + if (this._lock) { + doc._height = (NumCast(doc._width) * oldHeight) / oldWidth; } - break; - case "sizeWidth": - if (doc._width && doc._height) { - const oldWidth = doc._width; - const oldHeight = doc._height; - doc._width = dirs === "up" ? doc._width + 10 : doc._width - 10; - if (this._lock) { - doc._height = (doc._width * oldHeight) / oldWidth; - } - } - break; - case "sizeHeight": - if (doc._width && doc._height) { - const oldWidth = doc._width; - const oldHeight = doc._height; - doc._height = dirs === "up" ? doc._height + 10 : doc._height - 10; - if (this._lock) { - doc._width = (doc._height * oldWidth) / oldHeight; - } - } - break; - case "horizontal": - if (doc.x) { - doc.x = dirs === "up" ? doc.x + 10 : doc.x - 10; - } - break; - case "vertical": - if (doc.y) { - doc.y = dirs === "up" ? doc.y + 10 : doc.y - 10; - } - case "rotation": - this.rotate(dirs === "up" ? Number(doc.rotation) + Number(0.1) : Number(doc.rotation) - Number(0.1)); - break; - default: - break; - } - this.selected(); - } - })); - } - - - @action - editProperties = (value: any, field: string) => { - SelectionManager.SelectedDocuments().forEach(action((element: DocumentView) => { - const doc = Document(element.rootDoc); - if (doc.type === DocumentType.INK) { - switch (field) { - case "width": - SetActiveInkWidth(value); - doc.strokeWidth = Number(value); - break; - case "color": - doc.color = String(value); - break; - case "fill": - doc.fillColor = String(value); - break; - case "bezier": - break; - case "arrowStart": - doc.arrowStart = String(value); - break; - case "arrowEnd": - doc.arrowEnd = String(value); - break; - case "dash": - doc.dash = String(value); - break; - case "widthSize": - if (doc._width && doc._height) { - const oldWidth = doc._width; - const oldHeight = doc._height; - doc._width = Number(value); - if (this._lock) { - doc._height = (doc._width * oldHeight) / oldWidth; - } - } - break; - case "heightSize": - if (doc._width && doc._height) { - const oldWidth = doc._width; - const oldHeight = doc._height; - doc._height = Number(value); - if (this._lock) { - doc._width = (doc._height * oldWidth) / oldHeight; - } + } + }); + break; + case "sizeHeight": + this.inks?.forEach(i => { + const doc = i.rootDoc; + if (doc._width && doc._height) { + const oldWidth = NumCast(doc._width); + const oldHeight = NumCast(doc._height) + doc._height = NumCast(doc._height) + (dirs === "up" ? 10 : - 10); + if (this._lock) { + doc._width = (NumCast(doc._height) * oldWidth) / oldHeight; } - break; - case "horizontal": - doc.x = Number(value); - break; - case "vertical": - doc.y = Number(value); - break; - default: - break; - } - } - this.selected(); - })); - this.checkSame(); - + } + }); + break; + } } @computed get close() { @@ -294,69 +241,6 @@ export default class FormatShapePane extends AntimodeMenu { return modes; } - //detects currently selected document and change value in pane - @action - selected = () => { - this._selectDoc = SelectionManager.SelectedDocuments(); - if (this._selectDoc.length === 1 && Document(this._selectDoc[0].rootDoc).type === DocumentType.INK) { - this._single = true; - const doc = Document(this._selectDoc[0].rootDoc); - if (doc.type === DocumentType.INK) { - if (doc.fillColor === "none") { - this._noFill = true; - this._solidFill = false; - } else { - this._solidFill = true; - this._noFill = false; - this._currFill = String(doc.fillColor); - } - if (doc.color === "none") { - this._noLine = true; - this._solidLine = false; - this._dashLine = false; - } else { - this._currWidth = String(doc.strokeWidth); - this._currColor = String(doc.color); - if (doc.dash === "0") { - this._solidLine = true; - this._noLine = false; - this._dashLine = false; - } else { - this._dashLine = true; - this._noLine = false; - this._solidLine = false; - } - - this._arrowHead = doc.arrowStart === "none" ? false : true; - this._arrowEnd = doc.arrowEnd === "none" ? false : true; - this._currPositionHorizontal = String(doc.x); - this._currPositionVertical = String(doc.y); - this._currRotation = String(doc.rotation); - this._currSizeHeight = String(doc._height); - this._currSizeWidth = String(doc._width); - } - - } - } else { - this._noFill = false; - this._solidFill = false; - this._single = false; - this._currFill = "#D0021B"; - this._noLine = false; - this._solidLine = false; - this._dashLine = false; - this._currColor = "#D0021B"; - this._arrowHead = false; - this._arrowEnd = false; - this._currPositionHorizontal = ""; - this._currPositionVertical = ""; - this._currRotation = ""; - this._currSizeHeight = ""; - this._currSizeWidth = ""; - } - this.checkSame(); - } - @action rotate = (degrees: number) => { SelectionManager.SelectedDocuments().forEach(action((element: DocumentView) => { @@ -395,143 +279,80 @@ export default class FormatShapePane extends AntimodeMenu { })); } - @action - toggle = (check: string) => { - switch (check) { - case "noFill": - if (!this._noFill) { - this._noFill = true; - this._solidFill = false; - } - break; - case "solidFill": - if (!this._solidFill) { - this._solidFill = true; - this._noFill = false; - if (this._currFill === "none") { - this._currFill = "#D0021B"; - } - } - break; - case "noLine": - if (!this._noLine) { - this._noLine = true; - this._solidLine = false; - this._dashLine = false; - } - break; - case "solidLine": - if (!this._solidLine) { - this._solidLine = true; - this._noLine = false; - this._dashLine = false; - if (this._currColor === "none") { - this._currColor = "#D0021B"; - } - } - break; - case "dashLine": - if (!this._dashLine) { - this._dashLine = true; - this._solidLine = false; - this._noLine = false; - if (this._currColor === "none") { - this._currColor = "#D0021B"; - } - } - break; - case "lock": - if (this._lock) { - this._lock = false; - } else { - this._lock = true; - } - break; - case "arrowHead": - this._arrowHead = this._arrowHead ? false : true; - break; - case "arrowEnd": - this._arrowEnd = this._arrowEnd ? false : true; - break; - default: - break; - } - } - @computed get subMenu() { const fillCheck =
- { this.toggle("noFill"); this.editProperties("none", "fill"); })} /> + this._noFill = true)} /> No Fill -

- { this.toggle("solidFill"); this.editProperties(this._currFill, "fill"); })} /> +
+ this._solidFill = true)} /> Solid Fill -

-

+
+
{this._solidFill ? "Color" : ""} {this._solidFill ? this.fillButton : ""} {this._fillBtn && this._solidFill ? this.fillPicker : ""}
; - const arrows = <> { this.toggle("arrowHead"); this.editProperties(this._arrowHead ? "arrowHead" : "none", "arrowStart"); })} /> + const arrows = <> this._arrowStart = this._arrowStart ? "" : "arrow")} /> Arrow Head -

+
- { this.toggle("arrowEnd"); this.editProperties(this._arrowEnd ? "arrowEnd" : "none", "arrowEnd"); })} /> + this._arrowEnd = this._arrowEnd ? "" : "arrow")} /> Arrow End -

; +
; const lineCheck =
- { this.toggle("noLine"); this.editProperties("none", "color"); })} /> + this._noLine = true)} /> No Line -

- { this.toggle("solidLine"); this.editProperties(this._currColor, "color"); this.editProperties("0", "dash"); })} /> +
+ this._solidLine = true)} /> Solid Line -

- { this.toggle("dashLine"); this.editProperties(this._currColor, "color"); this.editProperties("2", "dash"); })} /> +
+ this._dashLine = "2")} /> Dash Line -

-

+
+
{(this._solidLine || this._dashLine) ? "Color" : ""} {(this._solidLine || this._dashLine) ? this.lineButton : ""} {this._lineBtn && (this._solidLine || this._dashLine) ? this.linePicker : ""} -

+
{(this._solidLine || this._dashLine) ? "Width" : ""} {(this._solidLine || this._dashLine) ? this.widthInput : ""} -

-

+
+
{(this._solidLine || this._dashLine) ? arrows : ""}
; const sizeCheck =
Height {this.sizeHeightInput} -

-

+
+
Width {this.sizeWidthInput} -

-

+
+
- { this.toggle("lock"); })} /> + this._lock = !this._lock)} /> Lock Ratio -

-

+
+
Rotation {this.rotationInput} -

-

+
+
; const positionCheck =
Horizontal {this.positionHorizontalInput} -

-

+
+
Vertical {this.positionVerticalInput} -

-

+
+
; @@ -574,29 +395,30 @@ export default class FormatShapePane extends AntimodeMenu { } @computed get fillButton() { - const fillButton = <> + return <> +

-

; - return fillButton; +

+ ; } @computed get fillPicker() { - const fillPicker =
+ return
{this._palette.map(color => { return
; - return fillPicker; } @computed get lineButton() { - const lineButton = <> -

-

; - return lineButton; + return <> + +
+
+ ; } @computed get linePicker() { - const linePicker =
+ return
{this._palette.map(color => { return
; - return linePicker; } @computed get widthInput() { const widthInput = <> this.onChange(e.target.value, "width")} - autoFocus>
@@ -672,8 +494,8 @@ export default class FormatShapePane extends AntimodeMenu { this.onChange(e.target.value, "sizeHeight")} - autoFocus> + onChange={e => this._currSizeHeight = e.target.value} + autoFocus /> -

+
-

+
+

+ -

- ; - return positionHorizontalInput; + ; } @computed get positionVerticalInput() { - const positionVerticalInput = - <> + this.onChange(e.target.value, "positionVertical")} + onChange={e => this._currPositionVertical = e.target.value} autoFocus> - -

- ; - return positionVerticalInput; - } - - //change inputs - @action - onChange = (val: string, property: string): void => { - if (!Number.isNaN(Number(val)) && Number(val) !== null && val !== " ") { - - switch (property) { - case "width": - this._currWidth = val; - if (val !== "") { - this.editProperties(this._currWidth, "width"); - } - break; - case "sizeHeight": - this._currSizeHeight = val; - if (val !== "") { - this.editProperties(this._currSizeHeight, "heightSize"); - } - break; - case "sizeWidth": - this._currSizeWidth = val; - if (val !== "") { - - this.editProperties(this._currSizeWidth, "widthSize"); - } - break; - case "rotation": - - this._currRotation = val; - if (val !== "") { - - this.rotate(Number(val)); - } - break; - case "positionHorizontal": - this._currPositionHorizontal = val; if (val !== "") { - - this.editProperties(this._currPositionHorizontal, "horizontal"); - } - - break; - case "positionVertical": - this._currPositionVertical = val; - if (val !== "") { - - this.editProperties(this._currPositionVertical, "vertical"); - } - - break; - default: - break; - } - } - } - - - @computed get widthPicker() { - var widthPicker = ; - if (this._widthBtn) { - widthPicker =
- {widthPicker} - {this._width.map(wid => { - return ; - })} -
; - } - return widthPicker; +

+ + ; } - - render() { const buttons = [ diff --git a/src/client/views/collections/collectionFreeForm/InkOptionsMenu.tsx b/src/client/views/collections/collectionFreeForm/InkOptionsMenu.tsx index e4f3248d0..0866db2be 100644 --- a/src/client/views/collections/collectionFreeForm/InkOptionsMenu.tsx +++ b/src/client/views/collections/collectionFreeForm/InkOptionsMenu.tsx @@ -25,19 +25,19 @@ library.add(faBold, faItalic, faChevronLeft, faUnderline, faStrikethrough, faSup export default class InkOptionsMenu extends AntimodeMenu { static Instance: InkOptionsMenu; - private _palette = ["#D0021B", "#F5A623", "#F8E71C", "#8B572A", "#7ED321", "#417505", "#9013FE", "#4A90E2", "#50E3C2", "#B8E986", "#000000", "#4A4A4A", "#9B9B9B", "#FFFFFF", "none"]; + private _palette = ["#D0021B", "#F5A623", "#F8E71C", "#8B572A", "#7ED321", "#417505", "#9013FE", "#4A90E2", "#50E3C2", "#B8E986", "#000000", "#4A4A4A", "#9B9B9B", "#FFFFFF", ""]; private _width = ["1", "5", "10", "100"]; // private _buttons = ["circle", "triangle", "rectangle", "arrow", "line"]; // private _icons = ["O", "∆", "ロ", "➜", "-"]; // private _buttons = ["circle", "triangle", "rectangle", "line", "noRec", "",]; // private _icons = ["O", "∆", "ロ", "⎯⎯⎯", "✖︎", " "]; //arrowStart and arrowEnd must match and defs must exist in Inking Stroke - // private _arrowStart = ["arrowHead", "arrowHead", "dot", "dot", "none"]; + // private _arrowStart = ["arrowStart", "arrowStart", "dot", "dot", "none"]; // private _arrowEnd = ["none", "arrowEnd", "none", "dot", "none"]; // private _arrowIcons = ["→", "↔︎", "•", "••", " "]; private _draw = ["⎯", "→", "↔︎", "∿", "↝", "↭", "ロ", "O", "∆"]; - private _head = ["none", "none", "arrowHead", "none", "none", "arrowHead", "none", "none", "none"]; - private _end = ["none", "arrowEnd", "arrowEnd", "none", "arrowEnd", "arrowEnd", "none", "none", "none"]; + private _head = ["", "", "arrow", "", "", "arrow", "", "", ""]; + private _end = ["", "arrow", "arrow", "", "arrow", "arrow", "", "", ""]; private _shape = ["", "", "", "", "", "", "rectangle", "circle", "triangle"]; @observable _shapesNum = this._shape.length; @@ -122,12 +122,6 @@ export default class InkOptionsMenu extends AntimodeMenu { case "bezier": // doc.strokeBezier === 300 ? doc.strokeBezier = 0 : doc.strokeBezier = 300; break; - case "arrowStart": - doc.arrowStart = String(value); - break; - case "arrowEnd": - doc.arrowEnd = String(value); - break; case "dash": doc.dash = Number(value); default: @@ -165,13 +159,12 @@ export default class InkOptionsMenu extends AntimodeMenu { SetActiveArrowEnd(this._end[i]); SetActiveBezierApprox("300"); - // this.editProperties(this._head[i], "arrowStart"), this.editProperties(this._end[i], "arrowEnd"); GestureOverlay.Instance.InkShape = this._shape[i]; } else { this._selected = this._shapesNum; Doc.SetSelectedTool(InkTool.None); - SetActiveArrowStart("none"); - SetActiveArrowEnd("none"); + SetActiveArrowStart(""); + SetActiveArrowEnd(""); GestureOverlay.Instance.InkShape = ""; SetActiveBezierApprox("0"); @@ -189,13 +182,12 @@ export default class InkOptionsMenu extends AntimodeMenu { SetActiveArrowEnd(this._end[i]); SetActiveBezierApprox("300"); - // this.editProperties(this._head[i], "arrowStart"), this.editProperties(this._end[i], "arrowEnd"); GestureOverlay.Instance.InkShape = this._shape[i]; } else { this._selected = this._shapesNum; Doc.SetSelectedTool(InkTool.None); - SetActiveArrowStart("none"); - SetActiveArrowEnd("none"); + SetActiveArrowStart(""); + SetActiveArrowEnd(""); GestureOverlay.Instance.InkShape = ""; SetActiveBezierApprox("0"); diff --git a/src/client/views/nodes/ColorBox.tsx b/src/client/views/nodes/ColorBox.tsx index 137b387c0..31c5a8b13 100644 --- a/src/client/views/nodes/ColorBox.tsx +++ b/src/client/views/nodes/ColorBox.tsx @@ -14,7 +14,6 @@ import { ViewBoxBaseComponent } from "../DocComponent"; import { ActiveInkPen, ActiveInkWidth, ActiveInkBezierApprox, SetActiveInkColor, SetActiveInkWidth, SetActiveBezierApprox } from "../InkingStroke"; import "./ColorBox.scss"; import { FieldView, FieldViewProps } from './FieldView'; -import { FormattedTextBox } from "./formattedText/FormattedTextBox"; type ColorDocument = makeInterface<[typeof documentSchema]>; const ColorDocument = makeInterface(documentSchema); -- cgit v1.2.3-70-g09d2 From cef8f8d5fb9f5b9dc1f56768c4fa5ec406fbc6ba Mon Sep 17 00:00:00 2001 From: Bob Zeleznik Date: Sat, 11 Jul 2020 20:02:55 -0400 Subject: fixed layout of inkOptionsMenu --- src/client/views/collections/collectionFreeForm/FormatShapePane.scss | 2 +- src/client/views/collections/collectionFreeForm/FormatShapePane.tsx | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) (limited to 'src/client/views/collections/collectionFreeForm') diff --git a/src/client/views/collections/collectionFreeForm/FormatShapePane.scss b/src/client/views/collections/collectionFreeForm/FormatShapePane.scss index 80a74fe4c..7720140b9 100644 --- a/src/client/views/collections/collectionFreeForm/FormatShapePane.scss +++ b/src/client/views/collections/collectionFreeForm/FormatShapePane.scss @@ -1,6 +1,6 @@ .antimodeMenu-button { width: 200px; - position: absolute; + position: relative; text-align: left; .color-previewI { diff --git a/src/client/views/collections/collectionFreeForm/FormatShapePane.tsx b/src/client/views/collections/collectionFreeForm/FormatShapePane.tsx index 3a1c8b18d..095473330 100644 --- a/src/client/views/collections/collectionFreeForm/FormatShapePane.tsx +++ b/src/client/views/collections/collectionFreeForm/FormatShapePane.tsx @@ -136,7 +136,7 @@ export default class FormatShapePane extends AntimodeMenu { } @computed get close() { - return ; } @@ -320,7 +320,7 @@ export default class FormatShapePane extends AntimodeMenu { colorButton(value: string, setter: () => {}) { return <> - -- cgit v1.2.3-70-g09d2 From 49b6ab8536f570ef244199ac39194d3b176c9e77 Mon Sep 17 00:00:00 2001 From: Bob Zeleznik Date: Sat, 11 Jul 2020 20:47:55 -0400 Subject: added open formatting pane to inkOptions. switched to radio buttons for some options. changed names of stroke parameters to start with 'stroke" --- src/client/views/InkingStroke.tsx | 4 ++-- .../collectionFreeForm/FormatShapePane.tsx | 25 +++++++++++----------- .../collectionFreeForm/InkOptionsMenu.tsx | 17 +++++++++++---- src/client/views/nodes/ColorBox.tsx | 11 ++++++++-- 4 files changed, 37 insertions(+), 20 deletions(-) (limited to 'src/client/views/collections/collectionFreeForm') diff --git a/src/client/views/InkingStroke.tsx b/src/client/views/InkingStroke.tsx index 46f714875..d7f956e4f 100644 --- a/src/client/views/InkingStroke.tsx +++ b/src/client/views/InkingStroke.tsx @@ -63,8 +63,8 @@ export class InkingStroke extends ViewBoxBaseComponent 5 ? strokeColor : "transparent", strokeWidth, (strokeWidth + 15), StrCast(this.layoutDoc.strokeBezier), StrCast(this.layoutDoc.fillColor, "transparent"), diff --git a/src/client/views/collections/collectionFreeForm/FormatShapePane.tsx b/src/client/views/collections/collectionFreeForm/FormatShapePane.tsx index 095473330..77d1b646d 100644 --- a/src/client/views/collections/collectionFreeForm/FormatShapePane.tsx +++ b/src/client/views/collections/collectionFreeForm/FormatShapePane.tsx @@ -43,10 +43,10 @@ export default class FormatShapePane extends AntimodeMenu { @computed get _noFill() { return this.inks?.reduce((p, i) => p && !i.rootDoc.fillColor ? true : false, true) || false; } @computed get _solidFill() { return this.inks?.reduce((p, i) => p && i.rootDoc.fillColor ? true : false, true) || false; } @computed get _noLine() { return this.inks?.reduce((p, i) => p && !i.rootDoc.color ? true : false, true) || false; } - @computed get _solidLine() { return this.inks?.reduce((p, i) => p && i.rootDoc.color && (!i.rootDoc.dash || i.rootDoc.dash === "0") ? true : false, true) || false; } - @computed get _arrowStart() { return this.getField("arrowStart") || ""; } - @computed get _arrowEnd() { return this.getField("arrowEnd") || ""; } - @computed get _dashLine() { return !this._noLine && this.getField("dash") || ""; } + @computed get _solidLine() { return this.inks?.reduce((p, i) => p && i.rootDoc.color && (!i.rootDoc.strokeDash || i.rootDoc.strokeDash === "0") ? true : false, true) || false; } + @computed get _arrowStart() { return this.getField("strokeArrowStart") || ""; } + @computed get _arrowEnd() { return this.getField("strokeArrowEnd") || ""; } + @computed get _dashLine() { return !this._noLine && this.getField("strokeDash") || ""; } @computed get _currSizeHeight() { return this.getField("_height"); } @computed get _currSizeWidth() { return this.getField("_width"); } @computed get _currRotation() { return this.getField("rotation"); } @@ -59,13 +59,13 @@ export default class FormatShapePane extends AntimodeMenu { set _solidFill(value) { this._noFill = !value; } set _currFill(value) { value && (this._lastFill = value); this.inks?.forEach(i => i.rootDoc.fillColor = value ? value : undefined); } set _currColor(value) { value && (this._lastLine = value); this.inks?.forEach(i => i.rootDoc.color = value ? value : undefined); } - set _arrowStart(value) { this.inks?.forEach(i => i.rootDoc.arrowStart = value); } - set _arrowEnd(value) { this.inks?.forEach(i => i.rootDoc.arrowEnd = value); } + set _arrowStart(value) { this.inks?.forEach(i => i.rootDoc.strokeArrowStart = value); } + set _arrowEnd(value) { this.inks?.forEach(i => i.rootDoc.strokeArrowEnd = value); } set _noLine(value) { this._currColor = value ? "" : this._lastLine; } set _solidLine(value) { this._dashLine = ""; this._noLine = !value; } set _dashLine(value) { value && (this._lastDash = value) && (this._noLine = false); - this.inks?.forEach(i => i.rootDoc.dash = value ? this._lastDash : undefined); + this.inks?.forEach(i => i.rootDoc.strokeDash = value ? this._lastDash : undefined); } set _currXpos(value) { this.inks?.forEach(i => i.rootDoc.x = Number(value)); } set _currYpos(value) { this.inks?.forEach(i => i.rootDoc.y = Number(value)); } @@ -192,10 +192,10 @@ export default class FormatShapePane extends AntimodeMenu { @computed get subMenu() { const fillCheck =
- this._noFill = true)} /> + this._noFill = true)} /> No Fill
- this._solidFill = true)} /> + this._solidFill = true)} /> Solid Fill

@@ -214,13 +214,13 @@ export default class FormatShapePane extends AntimodeMenu { ; const lineCheck =
- this._noLine = true)} /> + this._noLine = true)} /> No Line
- this._solidLine = true)} /> + this._solidLine = true)} /> Solid Line
- this._dashLine = "2")} /> + this._dashLine = "2")} /> Dash Line

@@ -230,6 +230,7 @@ export default class FormatShapePane extends AntimodeMenu {
{(this._solidLine || this._dashLine) ? "Width" : ""} {(this._solidLine || this._dashLine) ? this.widthInput : ""} + {(this._solidLine || this._dashLine) ? this._currStrokeWidth = e.target.value} /> : (null)}

{(this._solidLine || this._dashLine) ? arrows : ""} diff --git a/src/client/views/collections/collectionFreeForm/InkOptionsMenu.tsx b/src/client/views/collections/collectionFreeForm/InkOptionsMenu.tsx index ddba8a66d..7f0bb5364 100644 --- a/src/client/views/collections/collectionFreeForm/InkOptionsMenu.tsx +++ b/src/client/views/collections/collectionFreeForm/InkOptionsMenu.tsx @@ -18,6 +18,7 @@ import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; import { IconProp, library } from '@fortawesome/fontawesome-svg-core'; import { faBold, faItalic, faChevronLeft, faUnderline, faStrikethrough, faSubscript, faSuperscript, faIndent, faEyeDropper, faCaretDown, faPalette, faArrowsAlt, faHighlighter, faLink, faPaintRoller, faSleigh, faBars, faFillDrip, faBrush, faPenNib, faShapes, faArrowLeft, faEllipsisH, faBezierCurve, } from "@fortawesome/free-solid-svg-icons"; import { Cast, StrCast, BoolCast } from "../../../../fields/Types"; +import FormatShapePane from "./FormatShapePane"; library.add(faBold, faItalic, faChevronLeft, faUnderline, faStrikethrough, faSuperscript, faSubscript, faIndent, faEyeDropper, faCaretDown, faPalette, faArrowsAlt, faHighlighter, faLink, faPaintRoller, faBars, faFillDrip, faBrush, faPenNib, faShapes, faArrowLeft, faEllipsisH, faBezierCurve); @@ -40,7 +41,7 @@ export default class InkOptionsMenu extends AntimodeMenu { private _draw = ["⎯", "→", "↔︎", "∿", "↝", "↭", "ロ", "O", "∆"]; private _head = ["", "", "arrow", "", "", "arrow", "", "", ""]; private _end = ["", "arrow", "arrow", "", "arrow", "arrow", "", "", ""]; - private _shape = ["", "", "", "", "", "", "rectangle", "circle", "triangle"]; + private _shape = ["line", "line", "line", "", "", "", "rectangle", "circle", "triangle"]; @observable _shapesNum = this._shape.length; @observable _selected = this._shapesNum; @@ -127,7 +128,7 @@ export default class InkOptionsMenu extends AntimodeMenu { // doc.strokeBezier === 300 ? doc.strokeBezier = 0 : doc.strokeBezier = 300; break; case "dash": - doc.dash = Number(value); + doc.strokeDash = Number(value); default: break; } @@ -144,7 +145,7 @@ export default class InkOptionsMenu extends AntimodeMenu { @action changeDash = (e: React.PointerEvent): void => { SetActiveDash(ActiveDash() === "0" ? "2" : "0"); - this.editProperties(ActiveDash(), "dash"); + this.editProperties(ActiveDash(), "strokeDash"); } @computed get drawButtons() { @@ -296,6 +297,14 @@ export default class InkOptionsMenu extends AntimodeMenu { } return colorPicker; } + @computed get formatPane() { + return ; + } @computed get fillPicker() { var fillPicker = - ]; // return this.getElement(buttons); diff --git a/src/client/views/nodes/ColorBox.tsx b/src/client/views/nodes/ColorBox.tsx index c35c52644..57028b0ca 100644 --- a/src/client/views/nodes/ColorBox.tsx +++ b/src/client/views/nodes/ColorBox.tsx @@ -14,6 +14,7 @@ import { ViewBoxBaseComponent } from "../DocComponent"; import { ActiveInkPen, ActiveInkWidth, ActiveInkBezierApprox, SetActiveInkColor, SetActiveInkWidth, SetActiveBezierApprox } from "../InkingStroke"; import "./ColorBox.scss"; import { FieldView, FieldViewProps } from './FieldView'; +import { DocumentType } from "../../documents/DocumentTypes"; type ColorDocument = makeInterface<[typeof documentSchema]>; const ColorDocument = makeInterface(documentSchema); @@ -62,9 +63,15 @@ export class ColorBox extends ViewBoxBaseComponent
{ActiveInkWidth() ?? 2}
- ) => SetActiveInkWidth(e.target.value)} /> + ) => { + SetActiveInkWidth(e.target.value); + SelectionManager.SelectedDocuments().filter(i => StrCast(i.rootDoc.type) === DocumentType.INK).map(i => i.rootDoc.strokeWidth = Number(e.target.value)); + }} />
{ActiveInkBezierApprox() ?? 2}
- ) => SetActiveBezierApprox(e.target.value)} /> + ) => { + SetActiveBezierApprox(e.target.value); + SelectionManager.SelectedDocuments().filter(i => StrCast(i.rootDoc.type) === DocumentType.INK).map(i => i.rootDoc.strokeBezier = e.target.value); + }} />

-- cgit v1.2.3-70-g09d2 From add9dfeec764b5a60a57344c79fd23a91c031a2d Mon Sep 17 00:00:00 2001 From: Bob Zeleznik Date: Sun, 12 Jul 2020 10:31:06 -0400 Subject: final cleanup of names and structure of FormatShapePane --- src/client/views/InkingStroke.tsx | 2 +- .../collectionFreeForm/FormatShapePane.scss | 5 + .../collectionFreeForm/FormatShapePane.tsx | 404 +++++++++------------ .../collectionFreeForm/InkOptionsMenu.tsx | 9 +- 4 files changed, 182 insertions(+), 238 deletions(-) (limited to 'src/client/views/collections/collectionFreeForm') diff --git a/src/client/views/InkingStroke.tsx b/src/client/views/InkingStroke.tsx index d7f956e4f..abc698e62 100644 --- a/src/client/views/InkingStroke.tsx +++ b/src/client/views/InkingStroke.tsx @@ -63,7 +63,7 @@ export class InkingStroke extends ViewBoxBaseComponent 5 ? strokeColor : "transparent", strokeWidth, (strokeWidth + 15), diff --git a/src/client/views/collections/collectionFreeForm/FormatShapePane.scss b/src/client/views/collections/collectionFreeForm/FormatShapePane.scss index 7720140b9..88876471c 100644 --- a/src/client/views/collections/collectionFreeForm/FormatShapePane.scss +++ b/src/client/views/collections/collectionFreeForm/FormatShapePane.scss @@ -22,6 +22,11 @@ padding: 0; } +.formatShapePane-inputBtn { + width: inherit; + position: absolute; +} + .sketch-picker { background: #323232; diff --git a/src/client/views/collections/collectionFreeForm/FormatShapePane.tsx b/src/client/views/collections/collectionFreeForm/FormatShapePane.tsx index 77d1b646d..56ba9e96a 100644 --- a/src/client/views/collections/collectionFreeForm/FormatShapePane.tsx +++ b/src/client/views/collections/collectionFreeForm/FormatShapePane.tsx @@ -1,18 +1,16 @@ import React = require("react"); -import AntimodeMenu from "../../AntimodeMenu"; +import { IconProp } from '@fortawesome/fontawesome-svg-core'; +import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; +import { action, computed, observable } from "mobx"; import { observer } from "mobx-react"; -import { observable, action, computed } from "mobx"; -import "./FormatShapePane.scss"; -import { Scripting } from "../../../util/Scripting"; -import { InkField } from "../../../../fields/InkField"; -import { Doc, Opt, Field } from "../../../../fields/Doc"; -import { SelectionManager } from "../../../util/SelectionManager"; -import { DocumentView } from "../../../views/nodes/DocumentView"; +import { Doc, Field, Opt } from "../../../../fields/Doc"; import { Document } from "../../../../fields/documentSchemas"; +import { InkField } from "../../../../fields/InkField"; +import { BoolCast, Cast, NumCast } from "../../../../fields/Types"; import { DocumentType } from "../../../documents/DocumentTypes"; -import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; -import { IconProp } from '@fortawesome/fontawesome-svg-core'; -import { Cast, StrCast, BoolCast, NumCast } from "../../../../fields/Types"; +import { SelectionManager } from "../../../util/SelectionManager"; +import AntimodeMenu from "../../AntimodeMenu"; +import "./FormatShapePane.scss"; @observer export default class FormatShapePane extends AntimodeMenu { @@ -23,63 +21,62 @@ export default class FormatShapePane extends AntimodeMenu { private _lastDash = "2"; private _palette = ["#D0021B", "#F5A623", "#F8E71C", "#8B572A", "#7ED321", "#417505", "#9013FE", "#4A90E2", "#50E3C2", "#B8E986", "#000000", "#4A4A4A", "#9B9B9B", "#FFFFFF"]; private _mode = ["fill-drip", "ruler-combined"]; - private _subMenu = ["fill", "line", "size", "position"]; @observable private _subOpen = [false, false, false, false]; - @observable private _currMode: string = "fill-drip"; + @observable private _currMode = "fill-drip"; @observable private _lock = false; @observable private _fillBtn = false; @observable private _lineBtn = false; getField(key: string) { - return this.inks?.reduce((p, i) => + return this.selectedInk?.reduce((p, i) => (p === undefined || (p && p === i.rootDoc[key])) && i.rootDoc[key] !== "0" ? Field.toString(i.rootDoc[key] as Field) : "", undefined as Opt) } - @computed get inks() { + @computed get selectedInk() { const inks = SelectionManager.SelectedDocuments().filter(i => Document(i.rootDoc).type === DocumentType.INK); return inks.length ? inks : undefined; } - @computed get _noFill() { return this.inks?.reduce((p, i) => p && !i.rootDoc.fillColor ? true : false, true) || false; } - @computed get _solidFill() { return this.inks?.reduce((p, i) => p && i.rootDoc.fillColor ? true : false, true) || false; } - @computed get _noLine() { return this.inks?.reduce((p, i) => p && !i.rootDoc.color ? true : false, true) || false; } - @computed get _solidLine() { return this.inks?.reduce((p, i) => p && i.rootDoc.color && (!i.rootDoc.strokeDash || i.rootDoc.strokeDash === "0") ? true : false, true) || false; } - @computed get _arrowStart() { return this.getField("strokeArrowStart") || ""; } - @computed get _arrowEnd() { return this.getField("strokeArrowEnd") || ""; } - @computed get _dashLine() { return !this._noLine && this.getField("strokeDash") || ""; } - @computed get _currSizeHeight() { return this.getField("_height"); } - @computed get _currSizeWidth() { return this.getField("_width"); } - @computed get _currRotation() { return this.getField("rotation"); } - @computed get _currXpos() { return this.getField("x"); } - @computed get _currYpos() { return this.getField("y"); } - @computed get _currStrokeWidth() { return this.getField("strokeWidth"); } - @computed get _currFill() { const cfill = this.getField("fillColor") || ""; cfill && (this._lastFill = cfill); return cfill; } - @computed get _currColor() { const ccol = this.getField("color") || ""; ccol && (this._lastLine = ccol); return ccol; } - set _noFill(value) { this._currFill = value ? "" : this._lastFill; } - set _solidFill(value) { this._noFill = !value; } - set _currFill(value) { value && (this._lastFill = value); this.inks?.forEach(i => i.rootDoc.fillColor = value ? value : undefined); } - set _currColor(value) { value && (this._lastLine = value); this.inks?.forEach(i => i.rootDoc.color = value ? value : undefined); } - set _arrowStart(value) { this.inks?.forEach(i => i.rootDoc.strokeArrowStart = value); } - set _arrowEnd(value) { this.inks?.forEach(i => i.rootDoc.strokeArrowEnd = value); } - set _noLine(value) { this._currColor = value ? "" : this._lastLine; } - set _solidLine(value) { this._dashLine = ""; this._noLine = !value; } - set _dashLine(value) { - value && (this._lastDash = value) && (this._noLine = false); - this.inks?.forEach(i => i.rootDoc.strokeDash = value ? this._lastDash : undefined); + @computed get unFilled() { return this.selectedInk?.reduce((p, i) => p && !i.rootDoc.fillColor ? true : false, true) || false; } + @computed get unStrokd() { return this.selectedInk?.reduce((p, i) => p && !i.rootDoc.color ? true : false, true) || false; } + @computed get solidFil() { return this.selectedInk?.reduce((p, i) => p && i.rootDoc.fillColor ? true : false, true) || false; } + @computed get solidStk() { return this.selectedInk?.reduce((p, i) => p && i.rootDoc.color && (!i.rootDoc.strokeDash || i.rootDoc.strokeDash === "0") ? true : false, true) || false; } + @computed get dashdStk() { return !this.unStrokd && this.getField("strokeDash") || ""; } + @computed get colorFil() { const ccol = this.getField("fillColor") || ""; ccol && (this._lastFill = ccol); return ccol; } + @computed get colorStk() { const ccol = this.getField("color") || ""; ccol && (this._lastLine = ccol); return ccol; } + @computed get widthStk() { return this.getField("strokeWidth") || "1"; } + @computed get markHead() { return this.getField("strokeStartMarker") || ""; } + @computed get markTail() { return this.getField("strokeEndMarker") || ""; } + @computed get shapeHgt() { return this.getField("_height"); } + @computed get shapeWid() { return this.getField("_width"); } + @computed get shapeXps() { return this.getField("x"); } + @computed get shapeYps() { return this.getField("y"); } + @computed get shapeRot() { return this.getField("rotation"); } + set unFilled(value) { this.colorFil = value ? "" : this._lastFill; } + set solidFil(value) { this.unFilled = !value; } + set colorFil(value) { value && (this._lastFill = value); this.selectedInk?.forEach(i => i.rootDoc.fillColor = value ? value : undefined); } + set colorStk(value) { value && (this._lastLine = value); this.selectedInk?.forEach(i => i.rootDoc.color = value ? value : undefined); } + set markHead(value) { this.selectedInk?.forEach(i => i.rootDoc.strokeStartMarker = value); } + set markTail(value) { this.selectedInk?.forEach(i => i.rootDoc.strokeEndMarker = value); } + set unStrokd(value) { this.colorStk = value ? "" : this._lastLine; } + set solidStk(value) { this.dashdStk = ""; this.unStrokd = !value; } + set dashdStk(value) { + value && (this._lastDash = value) && (this.unStrokd = false); + this.selectedInk?.forEach(i => i.rootDoc.strokeDash = value ? this._lastDash : undefined); } - set _currXpos(value) { this.inks?.forEach(i => i.rootDoc.x = Number(value)); } - set _currYpos(value) { this.inks?.forEach(i => i.rootDoc.y = Number(value)); } - set _currRotation(value) { this.inks?.forEach(i => i.rootDoc.rotation = Number(value)); } - set _currStrokeWidth(value) { this.inks?.forEach(i => i.rootDoc.strokeWidth = Number(value)); } - set _currSizeWidth(value) { - this.inks?.filter(i => i.rootDoc._width && i.rootDoc._height).forEach(i => { + set shapeXps(value) { this.selectedInk?.forEach(i => i.rootDoc.x = Number(value)); } + set shapeYps(value) { this.selectedInk?.forEach(i => i.rootDoc.y = Number(value)); } + set shapeRot(value) { this.selectedInk?.forEach(i => i.rootDoc.rotation = Number(value)); } + set widthStk(value) { this.selectedInk?.forEach(i => i.rootDoc.strokeWidth = Number(value)); } + set shapeWid(value) { + this.selectedInk?.filter(i => i.rootDoc._width && i.rootDoc._height).forEach(i => { const oldWidth = NumCast(i.rootDoc._width); i.rootDoc._width = Number(value); this._lock && (i.rootDoc._height = (i.rootDoc._width * NumCast(i.rootDoc._height)) / oldWidth); }); } - set _currSizeHeight(value) { - this.inks?.filter(i => i.rootDoc._width && i.rootDoc._height).forEach(i => { + set shapeHgt(value) { + this.selectedInk?.filter(i => i.rootDoc._width && i.rootDoc._height).forEach(i => { const oldHeight = NumCast(i.rootDoc._height); i.rootDoc._height = Number(value); this._lock && (i.rootDoc._width = (i.rootDoc._height * NumCast(i.rootDoc._width)) / oldHeight); @@ -90,72 +87,41 @@ export default class FormatShapePane extends AntimodeMenu { super(props); FormatShapePane.Instance = this; this._canFade = false; - this.Pinned = BoolCast(Doc.UserDoc()["formatShapePane-pinned"]); + this.Pinned = BoolCast(Doc.UserDoc()["menuFormatShape-pinned"]); } @action closePane = () => { - this.jumpTo(-300, -300); + this.fadeOut(false); this.Pinned = false; } @action upDownButtons = (dirs: string, field: string) => { switch (field) { - case "horizontal": this.inks?.forEach(i => i.rootDoc.x = NumCast(i.rootDoc.x) + (dirs === "up" ? 10 : -10)); break; - case "vertical": this.inks?.forEach(i => i.rootDoc.y = NumCast(i.rootDoc.y) + (dirs === "up" ? 10 : -10)); break; - case "rotation": this.rotate((dirs === "up" ? .1 : -.1)); break; - case "width": this.inks?.forEach(i => i.rootDoc.strokeWidth = NumCast(i.rootDoc.strokeWidth) + (dirs === "up" ? .1 : -.1)); break; - case "sizeWidth": - this.inks?.forEach(i => { - const doc = i.rootDoc; - if (doc._width && doc._height) { - const oldWidth = NumCast(doc._width); - const oldHeight = NumCast(doc._height); - doc._width = NumCast(doc._width) + (dirs === "up" ? 10 : - 10); - if (this._lock) { - doc._height = (NumCast(doc._width) * oldHeight) / oldWidth; - } - } - }); + case "rot": this.rotate((dirs === "up" ? .1 : -.1)); break; + case "Xps": this.selectedInk?.forEach(i => i.rootDoc.x = NumCast(i.rootDoc.x) + (dirs === "up" ? 10 : -10)); break; + case "Yps": this.selectedInk?.forEach(i => i.rootDoc.y = NumCast(i.rootDoc.y) + (dirs === "up" ? 10 : -10)); break; + case "stk": this.selectedInk?.forEach(i => i.rootDoc.strokeWidth = NumCast(i.rootDoc.strokeWidth) + (dirs === "up" ? .1 : -.1)); break; + case "wid": this.selectedInk?.filter(i => i.rootDoc._width && i.rootDoc._height).forEach(i => { + const oldWidth = NumCast(i.rootDoc._width); + i.rootDoc._width = oldWidth + (dirs === "up" ? 10 : - 10); + this._lock && (i.rootDoc._height = (i.rootDoc._width / oldWidth * NumCast(i.rootDoc._height))); + }); break; - case "sizeHeight": - this.inks?.forEach(i => { - const doc = i.rootDoc; - if (doc._width && doc._height) { - const oldWidth = NumCast(doc._width); - const oldHeight = NumCast(doc._height); - doc._height = NumCast(doc._height) + (dirs === "up" ? 10 : - 10); - if (this._lock) { - doc._width = (NumCast(doc._height) * oldWidth) / oldHeight; - } - } - }); + case "hgt": this.selectedInk?.filter(i => i.rootDoc._width && i.rootDoc._height).forEach(i => { + const oldHeight = NumCast(i.rootDoc._height); + i.rootDoc._height = oldHeight + (dirs === "up" ? 10 : - 10); + this._lock && (i.rootDoc._width = (i.rootDoc._height / oldHeight * NumCast(i.rootDoc._width))); + }); break; } } - @computed get close() { - return ; - } - - //select either coor&fill or size&position - @computed get modes() { - return
- {this._mode.map(mode => - )} -
; - } - @action rotate = (degrees: number) => { - SelectionManager.SelectedDocuments().forEach(action((element: DocumentView) => { - const doc = Document(element.rootDoc); + this.selectedInk?.forEach(action(inkView => { + const doc = Document(inkView.rootDoc); if (doc.type === DocumentType.INK && doc.x && doc.y && doc._width && doc._height && doc.data) { const angle = Number(degrees) - Number(doc.rotation); doc.rotation = Number(degrees); @@ -183,117 +149,13 @@ export default class FormatShapePane extends AntimodeMenu { const top2 = Math.min(...ys2); const right2 = Math.max(...xs2); const bottom2 = Math.max(...ys2); - doc._height = (bottom2 - top2) * element.props.ScreenToLocalTransform().Scale; - doc._width = (right2 - left2) * element.props.ScreenToLocalTransform().Scale; + doc._height = (bottom2 - top2) * inkView.props.ScreenToLocalTransform().Scale; + doc._width = (right2 - left2) * inkView.props.ScreenToLocalTransform().Scale; } } })); } - @computed get subMenu() { - const fillCheck =
- this._noFill = true)} /> - No Fill -
- this._solidFill = true)} /> - Solid Fill -
-
- {this._solidFill ? "Color" : ""} - {this._solidFill ? this.fillButton : ""} - {this._fillBtn && this._solidFill ? this.fillPicker : ""} -
; - - const arrows = <> - this._arrowStart = this._arrowStart ? "" : "arrow")} /> - Arrow Head -
- this._arrowEnd = this._arrowEnd ? "" : "arrow")} /> - Arrow End -
- ; - - const lineCheck =
- this._noLine = true)} /> - No Line -
- this._solidLine = true)} /> - Solid Line -
- this._dashLine = "2")} /> - Dash Line -
-
- {(this._solidLine || this._dashLine) ? "Color" : ""} - {(this._solidLine || this._dashLine) ? this.lineButton : ""} - {this._lineBtn && (this._solidLine || this._dashLine) ? this.linePicker : ""} -
- {(this._solidLine || this._dashLine) ? "Width" : ""} - {(this._solidLine || this._dashLine) ? this.widthInput : ""} - {(this._solidLine || this._dashLine) ? this._currStrokeWidth = e.target.value} /> : (null)} -
-
- {(this._solidLine || this._dashLine) ? arrows : ""} -
; - - const sizeCheck =
- Height {this.sizeHeightInput} -
-
- - Width {this.sizeWidthInput} -
-
- - this._lock = !this._lock)} /> - Lock Ratio -
-
- - Rotation {this.rotationInput} -
-
-
; - - const positionCheck =
- Horizontal {this.positionHorizontalInput} -
-
- - Vertical {this.positionVerticalInput} -
-
-
; - - return
- {this._subMenu.map((subMenu, i) => { - if (subMenu === "fill" || subMenu === "line") { - return
- - {this._currMode === "fill-drip" && subMenu === "fill" && this._subOpen[0] ? fillCheck : ""} - {this._currMode === "fill-drip" && subMenu === "line" && this._subOpen[1] ? lineCheck : ""} -
; - } - else if (subMenu === "size" || subMenu === "position") { - return
- - {this._currMode === "ruler-combined" && subMenu === "size" && this._subOpen[2] ? sizeCheck : ""} - {this._currMode === "ruler-combined" && subMenu === "position" && this._subOpen[3] ? positionCheck : ""} -
; - } - })} -
; - } colorPicker(setter: (color: string) => {}) { return
@@ -325,37 +187,119 @@ export default class FormatShapePane extends AntimodeMenu {
-

-

+

; } - @computed get fillButton() { return this.colorButton(this._currFill, () => this._fillBtn = !this._fillBtn); } - @computed get lineButton() { return this.colorButton(this._currColor, () => this._lineBtn = !this._lineBtn); } + @computed get fillButton() { return this.colorButton(this.colorFil, () => this._fillBtn = !this._fillBtn); } + @computed get lineButton() { return this.colorButton(this.colorStk, () => this._lineBtn = !this._lineBtn); } - @computed get fillPicker() { return this.colorPicker((color: string) => this._currFill = color); } - @computed get linePicker() { return this.colorPicker((color: string) => this._currColor = color); } + @computed get fillPicker() { return this.colorPicker((color: string) => this.colorFil = color); } + @computed get linePicker() { return this.colorPicker((color: string) => this.colorStk = color); } - @computed get widthInput() { return this.inputBox("width", this._currStrokeWidth, (val: string) => this._currStrokeWidth = val); } - @computed get sizeHeightInput() { return this.inputBox("height", this._currSizeHeight, (val: string) => this._currSizeHeight = val); } - @computed get sizeWidthInput() { return this.inputBox("height", this._currSizeWidth, (val: string) => this._currSizeWidth = val); } - @computed get rotationInput() { return this.inputBox("rotation", this._currRotation, (val: string) => this._currRotation = val); } - @computed get positionHorizontalInput() { return this.inputBox("horizontal", this._currXpos, (val: string) => this._currXpos = val); } - @computed get positionVerticalInput() { return this.inputBox("vertical", this._currYpos, (val: string) => this._currYpos = val); } + @computed get stkInput() { return this.inputBox("stk", this.widthStk, (val: string) => this.widthStk = val); } + @computed get hgtInput() { return this.inputBox("hgt", this.shapeHgt, (val: string) => this.shapeHgt = val); } + @computed get widInput() { return this.inputBox("wid", this.shapeWid, (val: string) => this.shapeWid = val); } + @computed get rotInput() { return this.inputBox("rot", this.shapeRot, (val: string) => this.shapeRot = val); } + @computed get XpsInput() { return this.inputBox("Xps", this.shapeXps, (val: string) => this.shapeXps = val); } + @computed get YpsInput() { return this.inputBox("Yps", this.shapeYps, (val: string) => this.shapeYps = val); } - render() { - return this.getElementVert([this.close, this.modes, this.subMenu]); + @computed get propertyGroupItems() { + const fillCheck =
+ this.unFilled = true)} /> + No Fill +
+ this.solidFil = true)} /> + Solid Fill +

+ {this.solidFil ? "Color" : ""} + {this.solidFil ? this.fillButton : ""} + {this._fillBtn && this.solidFil ? this.fillPicker : ""} +
; + + const markers = <> + this.markHead = this.markHead ? "" : "arrow")} /> + Arrow Head +
+ this.markTail = this.markTail ? "" : "arrow")} /> + Arrow End +
+ ; + + const lineCheck =
+ this.unStrokd = true)} /> + No Line +
+ this.solidStk = true)} /> + Solid Line +
+ this.dashdStk = "2")} /> + Dash Line +
+
+ {(this.solidStk || this.dashdStk) ? "Color" : ""} + {(this.solidStk || this.dashdStk) ? this.lineButton : ""} + {(this.solidStk || this.dashdStk) && this._lineBtn ? this.linePicker : ""} +
+ {(this.solidStk || this.dashdStk) ? "Width" : ""} + {(this.solidStk || this.dashdStk) ? this.stkInput : ""} + {(this.solidStk || this.dashdStk) ? this.widthStk = e.target.value} /> : (null)} +

+ {(this.solidStk || this.dashdStk) ? markers : ""} +
; + + const sizeCheck =
+ Height {this.hgtInput} +

+ Width {this.widInput} +

+ this._lock = !this._lock)} /> + Lock Ratio +

+ Rotation {this.rotInput} +

+
; + + const positionCheck =
+ Horizontal {this.XpsInput} +

+ Vertical {this.YpsInput} +

+
; + + const subMenus = this._currMode === "fill-drip" ? [`fill`, `line`] : [`size`, `position`]; + const menuItems = this._currMode === "fill-drip" ? [fillCheck, lineCheck] : [sizeCheck, positionCheck]; + const indexOffset = this._currMode === "fill-drip" ? 0 : 2; + return
+ {subMenus.map((subMenu, i) => +
+ + {menuItems[i]} +
)} +
; + } + + @computed get closeBtn() { + return ; + } + + @computed get propertyGroupBtn() { + return
+ {this._mode.map(mode => + )} +
; } -} -Scripting.addGlobal(function activatePen2(penBtn: any) { - if (penBtn) { - //no longer changes to inkmode - // Doc.SetSelectedTool(InkTool.Pen); - FormatShapePane.Instance.jumpTo(300, 300); - FormatShapePane.Instance.Pinned = true; - } else { - // Doc.SetSelectedTool(InkTool.None); - FormatShapePane.Instance.Pinned = false; - FormatShapePane.Instance.fadeOut(true); + + render() { + return this.getElementVert([this.closeBtn, this.propertyGroupBtn, this.propertyGroupItems]); } -}); \ No newline at end of file +} \ No newline at end of file diff --git a/src/client/views/collections/collectionFreeForm/InkOptionsMenu.tsx b/src/client/views/collections/collectionFreeForm/InkOptionsMenu.tsx index 7f0bb5364..15707ad9e 100644 --- a/src/client/views/collections/collectionFreeForm/InkOptionsMenu.tsx +++ b/src/client/views/collections/collectionFreeForm/InkOptionsMenu.tsx @@ -62,13 +62,13 @@ export default class InkOptionsMenu extends AntimodeMenu { super(props); InkOptionsMenu.Instance = this; this._canFade = false; // don't let the inking menu fade away - this.Pinned = BoolCast(Doc.UserDoc()["inkOptionsMenu-pinned"]); + this.Pinned = BoolCast(Doc.UserDoc()["menuInkOptions-pinned"]); } @action toggleMenuPin = (e: React.MouseEvent) => { - Doc.UserDoc()["inkOptionsMenu-pinned"] = this.Pinned = !this.Pinned; + Doc.UserDoc()["menuInkOptions-pinned"] = this.Pinned = !this.Pinned; if (!this.Pinned) { // this.fadeOut(true); } @@ -426,15 +426,10 @@ export default class InkOptionsMenu extends AntimodeMenu { } Scripting.addGlobal(function activatePen(penBtn: any) { if (penBtn) { - //no longer changes to inkmode - // Doc.SetSelectedTool(InkTool.Pen); InkOptionsMenu.Instance.jumpTo(300, 300); InkOptionsMenu.Instance.Pinned = true; - } else { - // Doc.SetSelectedTool(InkTool.None); InkOptionsMenu.Instance.Pinned = false; InkOptionsMenu.Instance.fadeOut(true); - } }); -- cgit v1.2.3-70-g09d2 From 0b0183de3a13649819983203e2aba1dc6b84fdb1 Mon Sep 17 00:00:00 2001 From: Bob Zeleznik Date: Sun, 12 Jul 2020 23:34:34 -0400 Subject: fixed updating RichTextMenu with proper values for fontFamily, size, bullet, and alignment --- src/client/documents/Documents.ts | 2 +- src/client/util/CurrentUserUtils.ts | 15 +-- src/client/util/DragManager.ts | 2 +- src/client/views/animationtimeline/Timeline.tsx | 4 +- .../collectionFreeForm/CollectionFreeFormView.tsx | 2 +- .../collections/collectionFreeForm/MarqueeView.tsx | 2 +- src/client/views/nodes/DocumentView.tsx | 2 +- src/client/views/nodes/LabelBox.tsx | 2 +- src/client/views/nodes/SliderBox.tsx | 2 +- .../views/nodes/formattedText/FormattedTextBox.tsx | 7 +- .../views/nodes/formattedText/RichTextMenu.tsx | 111 ++++++++++++--------- .../views/nodes/formattedText/RichTextRules.ts | 2 +- src/fields/documentSchemas.ts | 2 +- 13 files changed, 88 insertions(+), 67 deletions(-) (limited to 'src/client/views/collections/collectionFreeForm') diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts index 72b716492..a415e17c8 100644 --- a/src/client/documents/Documents.ts +++ b/src/client/documents/Documents.ts @@ -123,7 +123,7 @@ export interface DocumentOptions { isBackground?: boolean; isLinkButton?: boolean; _columnWidth?: number; - _fontSize?: number; + _fontSize?: string; _fontFamily?: string; curPage?: number; currentTimecode?: number; // the current timecode of a time-based document (e.g., current time of a video) value is in seconds diff --git a/src/client/util/CurrentUserUtils.ts b/src/client/util/CurrentUserUtils.ts index ce910c062..39781a5ce 100644 --- a/src/client/util/CurrentUserUtils.ts +++ b/src/client/util/CurrentUserUtils.ts @@ -211,7 +211,7 @@ export class CurrentUserUtils { details.text = new RichTextField(JSON.stringify(detailedTemplate), buxtonFieldKeys.join(" ")); const shared = { _chromeStatus: "disabled", _autoHeight: true, _xMargin: 0 }; - const detailViewOpts = { title: "detailView", _width: 300, _fontFamily: "Arial", _fontSize: 12 }; + const detailViewOpts = { title: "detailView", _width: 300, _fontFamily: "Arial", _fontSize: "12pt" }; const descriptionWrapperOpts = { title: "descriptions", _height: 300, _columnWidth: -1, treeViewHideTitle: true, _pivotField: "title" }; const descriptionWrapper = MasonryDocument([details, short, long], { ...shared, ...descriptionWrapperOpts }); @@ -525,13 +525,13 @@ export class CurrentUserUtils { // Sets up the title of the button static mobileButtonText = (opts: DocumentOptions, buttonTitle: string) => Docs.Create.TextDocument(buttonTitle, { ...opts, - dropAction: undefined, title: buttonTitle, _fontSize: 37, _xMargin: 0, _yMargin: 0, ignoreClick: true, _chromeStatus: "disabled", backgroundColor: "rgba(0,0,0,0)" + dropAction: undefined, title: buttonTitle, _fontSize: "37pt", _xMargin: 0, _yMargin: 0, ignoreClick: true, _chromeStatus: "disabled", backgroundColor: "rgba(0,0,0,0)" }) as any as Doc // Sets up the description of the button static mobileButtonInfo = (opts: DocumentOptions, buttonInfo: string) => Docs.Create.TextDocument(buttonInfo, { ...opts, - dropAction: undefined, title: "info", _fontSize: 25, _xMargin: 0, _yMargin: 0, ignoreClick: true, _chromeStatus: "disabled", backgroundColor: "rgba(0,0,0,0)", _dimMagnitude: 2, + dropAction: undefined, title: "info", _fontSize: "25pt", _xMargin: 0, _yMargin: 0, ignoreClick: true, _chromeStatus: "disabled", backgroundColor: "rgba(0,0,0,0)", _dimMagnitude: 2, }) as any as Doc @@ -598,7 +598,7 @@ export class CurrentUserUtils { _width: 500, lockedPosition: true, _chromeStatus: "disabled", title: "tools stack", forceActive: true })) as any as Doc; doc["tabs-button-tools"] = new PrefetchProxy(Docs.Create.ButtonDocument({ - _width: 35, _height: 25, title: "Tools", _fontSize: 10, + _width: 35, _height: 25, title: "Tools", _fontSize: "10pt", letterSpacing: "0px", textTransform: "unset", borderRounding: "5px 5px 0px 0px", boxShadow: "3px 3px 0px rgb(34, 34, 34)", sourcePanel: toolsStack, onDragStart: ScriptField.MakeFunction('getAlias(this.dragFactory, true)'), @@ -663,7 +663,7 @@ export class CurrentUserUtils { lockedPosition: true, boxShadow: "0 0", dontRegisterChildViews: true, targetDropAction: "same" })) as any as Doc; doc["tabs-button-library"] = new PrefetchProxy(Docs.Create.ButtonDocument({ - _width: 50, _height: 25, title: "Library", _fontSize: 10, targetDropAction: "same", + _width: 50, _height: 25, title: "Library", _fontSize: "10pt", targetDropAction: "same", letterSpacing: "0px", textTransform: "unset", borderRounding: "5px 5px 0px 0px", boxShadow: "3px 3px 0px rgb(34, 34, 34)", sourcePanel: libraryStack, onDragStart: ScriptField.MakeFunction('getAlias(this.dragFactory, true)'), @@ -681,7 +681,7 @@ export class CurrentUserUtils { static setupSearchBtnPanel(doc: Doc, sidebarContainer: Doc) { if (doc["tabs-button-search"] === undefined) { doc["tabs-button-search"] = new PrefetchProxy(Docs.Create.ButtonDocument({ - _width: 50, _height: 25, title: "Search", _fontSize: 10, + _width: 50, _height: 25, title: "Search", _fontSize: "10pt", letterSpacing: "0px", textTransform: "unset", borderRounding: "5px 5px 0px 0px", boxShadow: "3px 3px 0px rgb(34, 34, 34)", sourcePanel: new PrefetchProxy(Docs.Create.QueryDocument({ title: "search stack", })) as any as Doc, searchFileTypes: new List([DocumentType.RTF, DocumentType.IMG, DocumentType.PDF, DocumentType.VID, DocumentType.WEB, DocumentType.SCRIPTING]), @@ -824,7 +824,8 @@ export class CurrentUserUtils { doc.activeArrowStart = StrCast(doc.activeArrowStart, ""); doc.activeArrowEnd = StrCast(doc.activeArrowEnd, ""); doc.activeDash = StrCast(doc.activeDash, "0"); - doc.fontSize = NumCast(doc.fontSize, 12); + doc.fontSize = StrCast(doc.fontSize, "12pt"); + doc.fontFamily = StrCast(doc.fontFamily, "Arial"); doc["constants-snapThreshold"] = NumCast(doc["constants-snapThreshold"], 10); // doc["constants-dragThreshold"] = NumCast(doc["constants-dragThreshold"], 4); // Utils.DRAG_THRESHOLD = NumCast(doc["constants-dragThreshold"]); diff --git a/src/client/util/DragManager.ts b/src/client/util/DragManager.ts index 64c3d8458..5f34509a1 100644 --- a/src/client/util/DragManager.ts +++ b/src/client/util/DragManager.ts @@ -323,7 +323,7 @@ export namespace DragManager { dragLabel = document.createElement("div"); dragLabel.className = "dragManager-dragLabel"; dragLabel.style.zIndex = "100001"; - dragLabel.style.fontSize = "10"; + dragLabel.style.fontSize = "10pt"; dragLabel.style.position = "absolute"; // dragLabel.innerText = "press 'a' to embed on drop"; // bcz: need to move this to a status bar dragDiv.appendChild(dragLabel); diff --git a/src/client/views/animationtimeline/Timeline.tsx b/src/client/views/animationtimeline/Timeline.tsx index f54bd3aff..eac30ca75 100644 --- a/src/client/views/animationtimeline/Timeline.tsx +++ b/src/client/views/animationtimeline/Timeline.tsx @@ -385,10 +385,10 @@ export class Timeline extends React.Component { const ttime = `Total: ${this.toReadTime(this._time)}`; return (
-
+
{ctime}
-
+
{ttime}
diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx index 2191021d2..ef6ea8f99 100644 --- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx +++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx @@ -1034,7 +1034,7 @@ export class CollectionFreeFormView extends CollectionSubView val === undefined) ? undefined : { ele:
diff --git a/src/client/views/collections/collectionFreeForm/MarqueeView.tsx b/src/client/views/collections/collectionFreeForm/MarqueeView.tsx index b47236bea..2db665337 100644 --- a/src/client/views/collections/collectionFreeForm/MarqueeView.tsx +++ b/src/client/views/collections/collectionFreeForm/MarqueeView.tsx @@ -129,7 +129,7 @@ export class MarqueeView extends React.Component(Docu background: finalColor, opacity: finalOpacity, fontFamily: StrCast(this.Document._fontFamily, "inherit"), - fontSize: Cast(this.Document._fontSize, "number", null) + fontSize: Cast(this.Document._fontSize, "string", null) }}> {this.onClickHandler && this.props.ContainingCollectionView?.props.Document._viewType === CollectionViewType.Time ? <> {this.innards} diff --git a/src/client/views/nodes/LabelBox.tsx b/src/client/views/nodes/LabelBox.tsx index 360ead18e..836ef4149 100644 --- a/src/client/views/nodes/LabelBox.tsx +++ b/src/client/views/nodes/LabelBox.tsx @@ -67,7 +67,7 @@ export class LabelBox extends ViewBoxBaseComponent
this._editorView && RichTextMenu.Instance.updateFromDash(this._editorView, undefined, this.props), 0); - } else if (FormattedTextBoxComment.textBox === this) { + setTimeout(() => this._editorView && RichTextMenu.Instance.updateFromDash(this._editorView, undefined, this.props), this.props.isSelected() ? 10 : 0); // need to make sure that we update a text box that is selected after updating the one that was deselected + if (!this.props.isSelected() && FormattedTextBoxComment.textBox === this) { setTimeout(() => FormattedTextBoxComment.Hide(), 0); } const selPad = this.props.isSelected() ? -10 : 0; @@ -1376,7 +1375,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp opacity: this.props.hideOnLeave ? (this._entered ? 1 : 0.1) : 1, color: this.props.color ? this.props.color : StrCast(this.layoutDoc[this.props.fieldKey + "-color"], this.props.hideOnLeave ? "white" : "inherit"), pointerEvents: interactive ? undefined : "none", - fontSize: Cast(this.layoutDoc._fontSize, "number", null), + fontSize: Cast(this.layoutDoc._fontSize, "string", null), fontFamily: StrCast(this.layoutDoc._fontFamily, "inherit"), transition: "opacity 1s" }} diff --git a/src/client/views/nodes/formattedText/RichTextMenu.tsx b/src/client/views/nodes/formattedText/RichTextMenu.tsx index 1a8a4ceb7..a70f879ff 100644 --- a/src/client/views/nodes/formattedText/RichTextMenu.tsx +++ b/src/client/views/nodes/formattedText/RichTextMenu.tsx @@ -11,7 +11,7 @@ import { EditorState, NodeSelection, TextSelection } from "prosemirror-state"; import { EditorView } from "prosemirror-view"; import { Doc } from "../../../../fields/Doc"; import { DarkPastelSchemaPalette, PastelSchemaPalette } from '../../../../fields/SchemaHeaderField'; -import { Cast, StrCast, BoolCast } from "../../../../fields/Types"; +import { Cast, StrCast, BoolCast, NumCast } from "../../../../fields/Types"; import { unimplementedFunction, Utils } from "../../../../Utils"; import { DocServer } from "../../../DocServer"; import { LinkManager } from "../../../util/LinkManager"; @@ -112,6 +112,7 @@ export default class RichTextMenu extends AntimodeMenu { { node: schema.nodes.ordered_list.create({ mapStyle: "bullet" }), title: "Set list type", label: ":", command: this.changeListType }, { node: schema.nodes.ordered_list.create({ mapStyle: "decimal" }), title: "Set list type", label: "1.1", command: this.changeListType }, { node: schema.nodes.ordered_list.create({ mapStyle: "multi" }), title: "Set list type", label: "A.1", command: this.changeListType }, + { node: schema.nodes.ordered_list.create({ mapStyle: "" }), title: "Set list type", label: "", command: this.changeListType }, //{ node: undefined, title: "Set list type", label: "Remove", command: this.changeListType }, ]; @@ -217,7 +218,7 @@ export default class RichTextMenu extends AntimodeMenu { // finds font sizes and families in selection getActiveAlignment() { - if (this.view) { + if (this.view && this.TextView.props.isSelected()) { const path = (this.view.state.selection.$from as any).path; for (let i = path.length - 3; i < path.length && i >= 0; i -= 3) { if (path[i]?.type === this.view.state.schema.nodes.paragraph) { @@ -230,15 +231,18 @@ export default class RichTextMenu extends AntimodeMenu { // finds font sizes and families in selection getActiveListStyle() { - if (this.view) { + if (this.view && this.TextView.props.isSelected()) { const path = (this.view.state.selection.$from as any).path; for (let i = 0; i < path.length; i += 3) { if (path[i].type === this.view.state.schema.nodes.ordered_list) { return path[i].attrs.mapStyle; } } + if (this.view.state.selection.$from.nodeAfter?.type === this.view.state.schema.nodes.ordered_list) { + return this.view.state.selection.$from.nodeAfter?.attrs.mapStyle; + } } - return "decimal"; + return ""; } // finds font sizes and families in selection @@ -247,16 +251,21 @@ export default class RichTextMenu extends AntimodeMenu { const activeFamilies: string[] = []; const activeSizes: string[] = []; - const state = this.view.state; - const pos = this.view.state.selection.$from; - const ref_node = this.reference_node(pos); - if (ref_node && ref_node !== this.view.state.doc && ref_node.isText) { - ref_node.marks.forEach(m => { - m.type === state.schema.marks.pFontFamily && activeFamilies.push(m.attrs.family); - m.type === state.schema.marks.pFontSize && activeSizes.push(String(m.attrs.fontSize) + "pt"); - }); + if (this.TextView.props.isSelected()) { + const state = this.view.state; + const pos = this.view.state.selection.$from; + const ref_node = this.reference_node(pos); + if (ref_node && ref_node !== this.view.state.doc && ref_node.isText) { + ref_node.marks.forEach(m => { + m.type === state.schema.marks.pFontFamily && activeFamilies.push(m.attrs.family); + m.type === state.schema.marks.pFontSize && activeSizes.push(String(m.attrs.fontSize) + "pt"); + }); + } + !activeFamilies.length && (activeFamilies.push(StrCast(this.TextView.layoutDoc._fontFamily, StrCast(Doc.UserDoc().fontFamily)))); + !activeSizes.length && (activeSizes.push(StrCast(this.TextView.layoutDoc._fontSize, StrCast(Doc.UserDoc().fontSize)))); } - + !activeFamilies.length && (activeFamilies.push(StrCast(Doc.UserDoc().fontFamily))); + !activeSizes.length && (activeSizes.push(StrCast(Doc.UserDoc().fontSize))); return { activeFamilies, activeSizes }; } @@ -269,14 +278,14 @@ export default class RichTextMenu extends AntimodeMenu { //finds all active marks on selection in given group getActiveMarksOnSelection() { - if (!this.view) return; + let activeMarks: MarkType[] = []; + if (!this.view || !this.TextView.props.isSelected()) return activeMarks; const markGroup = [schema.marks.strong, schema.marks.em, schema.marks.underline, schema.marks.strikethrough, schema.marks.superscript, schema.marks.subscript]; if (this.view.state.storedMarks) return this.view.state.storedMarks.map(mark => mark.type); //current selection const { empty, ranges, $to } = this.view.state.selection as TextSelection; const state = this.view.state; - let activeMarks: MarkType[] = []; if (!empty) { activeMarks = markGroup.filter(mark => { const has = false; @@ -357,13 +366,9 @@ export default class RichTextMenu extends AntimodeMenu { createMarksDropdown(activeOption: string, options: { mark: Mark | null, title: string, label: string, command: (mark: Mark, view: EditorView) => void, hidden?: boolean, style?: {} }[], key: string): JSX.Element { const items = options.map(({ title, label, hidden, style }) => { if (hidden) { - return label === activeOption ? - : - ; + return ; } - return label === activeOption ? - : - ; + return ; }); const self = this; @@ -372,37 +377,42 @@ export default class RichTextMenu extends AntimodeMenu { e.preventDefault(); self.TextView.endUndoTypingBatch(); options.forEach(({ label, mark, command }) => { - if (e.target.value === label) { - UndoManager.RunInBatch(() => self.view && mark && command(mark, self.view), "text mark dropdown"); + if (e.target.value === label && mark) { + if (!self.TextView.props.isSelected()) { + switch (mark.type) { + case schema.marks.pFontFamily: Doc.UserDoc().fontFamily = mark.attrs.family; break; + case schema.marks.pFontSize: Doc.UserDoc().fontSize = mark.attrs.fontSize.toString() + "pt"; break; + } + } + else UndoManager.RunInBatch(() => self.view && mark && command(mark, self.view), "text mark dropdown"); } }); } - return ; + return ; } - createNodesDropdown(activeMap: string, options: { node: NodeType | any | null, title: string, label: string, command: (node: NodeType | any) => void, hidden?: boolean, style?: {} }[], key: string): JSX.Element { - const activeOption = activeMap === "bullet" ? ":" : activeMap === "decimal" ? "1.1" : "A.1"; + createNodesDropdown(activeMap: string, options: { node: NodeType | any | null, title: string, label: string, command: (node: NodeType | any) => void, hidden?: boolean, style?: {} }[], key: string, setter: (val: string) => {}): JSX.Element { + const activeOption = activeMap === "bullet" ? ":" : activeMap === "decimal" ? "1.1" : activeMap === "multi" ? "A.1" : ""; const items = options.map(({ title, label, hidden, style }) => { if (hidden) { - return label === activeOption ? - : - ; + return ; } - return label === activeOption ? - : - ; + return ; }); const self = this; function onChange(val: string) { self.TextView.endUndoTypingBatch(); options.forEach(({ label, node, command }) => { - if (val === label) { - UndoManager.RunInBatch(() => self.view && node && command(node), "nodes dropdown"); + if (val === label && node) { + if (self.TextView.props.isSelected()) { + UndoManager.RunInBatch(() => self.view && node && command(node), "nodes dropdown"); + setter(val); + } } }); } - return ; + return ; } changeFontSize = (mark: Mark, view: EditorView) => { @@ -416,10 +426,21 @@ export default class RichTextMenu extends AntimodeMenu { // TODO: remove doesn't work //remove all node type and apply the passed-in one to the selected text changeListType = (nodeType: Node | undefined) => { - if (!this.view) return; + if (!this.view || (nodeType as any)?.attrs.mapStyle === "") return; + + const nextIsOL = this.view.state.selection.$from.nodeAfter?.type === schema.nodes.ordered_list; + let inList: any = undefined; + let fromList = -1; + let path: any = Array.from((this.view.state.selection.$from as any).path); + for (let i = 0; i < path.length; i++) { + if (path[i]?.type === schema.nodes.ordered_list) { + inList = path[i]; + fromList = path[i - 1]; + } + } const marks = this.view.state.storedMarks || (this.view.state.selection.$to.parentOffset && this.view.state.selection.$from.marks()); - if (!wrapInList(schema.nodes.ordered_list)(this.view.state, (tx2: any) => { + if (inList || !wrapInList(schema.nodes.ordered_list)(this.view.state, (tx2: any) => { const tx3 = updateBullets(tx2, schema, nodeType && (nodeType as any).attrs.mapStyle, this.view!.state.selection.from - 1, this.view!.state.selection.to + 1); marks && tx3.ensureMarks([...marks]); marks && tx3.setStoredMarks([...marks]); @@ -427,12 +448,12 @@ export default class RichTextMenu extends AntimodeMenu { this.view!.dispatch(tx2); })) { const tx2 = this.view.state.tr; - if (nodeType && this.view.state.selection.$from.nodeAfter?.type === schema.nodes.ordered_list) { - const tx3 = updateBullets(tx2, schema, nodeType && (nodeType as any).attrs.mapStyle, this.view.state.selection.from, this.view.state.selection.to); + if (nodeType && (inList || nextIsOL)) { + const tx3 = updateBullets(tx2, schema, nodeType && (nodeType as any).attrs.mapStyle, inList ? fromList : this.view.state.selection.from, + inList ? fromList + inList.nodeSize : this.view.state.selection.to); marks && tx3.ensureMarks([...marks]); marks && tx3.setStoredMarks([...marks]); - - this.view.dispatch(tx3.setSelection(new NodeSelection(tx3.doc.resolve(this.view.state.selection.$from.pos)))); + this.view.dispatch(tx3); } } } @@ -448,13 +469,13 @@ export default class RichTextMenu extends AntimodeMenu { return true; } alignCenter = (state: EditorState, dispatch: any) => { - return this.alignParagraphs(state, "center", dispatch); + return this.TextView.props.isSelected() && this.alignParagraphs(state, "center", dispatch); } alignLeft = (state: EditorState, dispatch: any) => { - return this.alignParagraphs(state, "left", dispatch); + return this.TextView.props.isSelected() && this.alignParagraphs(state, "left", dispatch); } alignRight = (state: EditorState, dispatch: any) => { - return this.alignParagraphs(state, "right", dispatch); + return this.TextView.props.isSelected() && this.alignParagraphs(state, "right", dispatch); } alignParagraphs(state: EditorState, align: "left" | "right" | "center", dispatch: any) { @@ -914,7 +935,7 @@ export default class RichTextMenu extends AntimodeMenu { {[this.createMarksDropdown(this.activeFontSize, this.fontSizeOptions, "font size"), this.createMarksDropdown(this.activeFontFamily, this.fontFamilyOptions, "font family"),
, - this.createNodesDropdown(this.activeListType, this.listTypeOptions, "nodes"), + this.createNodesDropdown(this.activeListType, this.listTypeOptions, "nodes", action((val: string) => this.activeListType = val)), this.createButton("sort-amount-down", "Summarize", undefined, this.insertSummarizer), this.createButton("quote-left", "Blockquote", undefined, this.insertBlockquote), this.createButton("minus", "Horizontal Rule", undefined, this.insertHorizontalRule), diff --git a/src/client/views/nodes/formattedText/RichTextRules.ts b/src/client/views/nodes/formattedText/RichTextRules.ts index ca30dde9d..ef0fead4a 100644 --- a/src/client/views/nodes/formattedText/RichTextRules.ts +++ b/src/client/views/nodes/formattedText/RichTextRules.ts @@ -90,7 +90,7 @@ export class RichTextRules { textDoc.inlineTextCount = numInlines + 1; const inlineFieldKey = "inline" + numInlines; // which field on the text document this annotation will write to const inlineLayoutKey = "layout_" + inlineFieldKey; // the field holding the layout string that will render the inline annotation - const textDocInline = Docs.Create.TextDocument("", { layoutKey: inlineLayoutKey, _width: 75, _height: 35, annotationOn: textDoc, _autoHeight: true, _fontSize: 9, title: "inline comment" }); + const textDocInline = Docs.Create.TextDocument("", { layoutKey: inlineLayoutKey, _width: 75, _height: 35, annotationOn: textDoc, _autoHeight: true, _fontSize: "9pt", title: "inline comment" }); textDocInline.title = inlineFieldKey; // give the annotation its own title textDocInline.customTitle = true; // And make sure that it's 'custom' so that editing text doesn't change the title of the containing doc textDocInline.isTemplateForField = inlineFieldKey; // this is needed in case the containing text doc is converted to a template at some point diff --git a/src/fields/documentSchemas.ts b/src/fields/documentSchemas.ts index c1659d4d5..61a37ef8a 100644 --- a/src/fields/documentSchemas.ts +++ b/src/fields/documentSchemas.ts @@ -55,7 +55,7 @@ export const documentSchema = createSchema({ _columnsHideIfEmpty: "boolean", // whether empty stacking view column headings should be hidden _columnHeaders: listSpec(SchemaHeaderField), // header descriptions for stacking/masonry _schemaHeaders: listSpec(SchemaHeaderField), // header descriptions for schema views - _fontSize: "number", + _fontSize: "string", _fontFamily: "string", _sidebarWidthPercent: "string", // percent of text window width taken up by sidebar -- cgit v1.2.3-70-g09d2 From 0e2a5196b47c05eab74d0aae06c2db4a9528f0fb Mon Sep 17 00:00:00 2001 From: Bob Zeleznik Date: Mon, 13 Jul 2020 20:44:03 -0400 Subject: switched context menus to be less hierarchical. --- src/client/util/CurrentUserUtils.ts | 2 - src/client/util/SettingsManager.scss | 2 +- src/client/util/SettingsManager.tsx | 14 ++++++- src/client/views/ContextMenuItem.tsx | 6 +++ .../views/collections/CollectionCarousel3DView.tsx | 13 +----- .../views/collections/CollectionCarouselView.tsx | 14 +------ .../views/collections/CollectionTreeView.tsx | 2 +- src/client/views/collections/CollectionView.tsx | 6 +-- .../collectionFreeForm/FormatShapePane.tsx | 26 ++++++------ .../collectionGrid/CollectionGridView.tsx | 5 +-- src/client/views/nodes/DocumentView.tsx | 38 ++++++++--------- src/client/views/nodes/ImageBox.tsx | 48 +++++++++++----------- src/client/views/nodes/LabelBox.tsx | 2 +- .../views/nodes/formattedText/FormattedTextBox.tsx | 48 +++++++++++----------- 14 files changed, 111 insertions(+), 115 deletions(-) (limited to 'src/client/views/collections/collectionFreeForm') diff --git a/src/client/util/CurrentUserUtils.ts b/src/client/util/CurrentUserUtils.ts index 39781a5ce..048ab9edc 100644 --- a/src/client/util/CurrentUserUtils.ts +++ b/src/client/util/CurrentUserUtils.ts @@ -423,8 +423,6 @@ export class CurrentUserUtils { // { title: "use drag", icon: "mouse-pointer", click: 'deactivateInk();this.activeInkPen = this;', ischecked: `sameDocs(this.activeInkPen, this)`, backgroundColor: "white", activeInkPen: doc }, { title: "Drag a document previewer", label: "Prev", icon: "expand", click: 'openOnRight(getCopy(this.dragFactory, true))', drag: 'getCopy(this.dragFactory,true)', dragFactory: doc.emptyDocHolder as Doc }, { title: "Toggle a Calculator REPL", label: "repl", icon: "calculator", click: 'addOverlayWindow("ScriptingRepl", { x: 300, y: 100, width: 200, height: 200, title: "Scripting REPL" })' }, - { title: "Connect a Google Account", label: "Google Account", icon: "external-link-alt", click: 'GoogleAuthenticationManager.Instance.fetchOrGenerateAccessToken(true)' }, - { title: "Connect a Hypothesis Account", label: "Hypothesis Account", icon: "heading", click: 'HypothesisAuthenticationManager.Instance.fetchOrGenerateAccessToken(true)' }, ]; } diff --git a/src/client/util/SettingsManager.scss b/src/client/util/SettingsManager.scss index 13c65042c..6d394a38d 100644 --- a/src/client/util/SettingsManager.scss +++ b/src/client/util/SettingsManager.scss @@ -56,7 +56,7 @@ .settings-type { display: flex; flex-direction: column; - flex-basis: 30%; + flex-basis: 45%; } diff --git a/src/client/util/SettingsManager.tsx b/src/client/util/SettingsManager.tsx index 9888cce48..f7ca3942b 100644 --- a/src/client/util/SettingsManager.tsx +++ b/src/client/util/SettingsManager.tsx @@ -11,6 +11,8 @@ import { Networking } from "../Network"; import { CurrentUserUtils } from "./CurrentUserUtils"; import { Utils } from "../../Utils"; import { Doc } from "../../fields/Doc"; +import HypothesisAuthenticationManager from "../apis/HypothesisAuthenticationManager"; +import GoogleAuthenticationManager from "../apis/GoogleAuthenticationManager"; library.add(fa.faWindowClose); @@ -83,6 +85,14 @@ export default class SettingsManager extends React.Component<{}> { noviceToggle = (event: any) => { Doc.UserDoc().noviceMode = !Doc.UserDoc().noviceMode; } + @action + googleAuthorize = (event: any) => { + GoogleAuthenticationManager.Instance.fetchOrGenerateAccessToken(true) + } + @action + hypothesisAuthorize = (event: any) => { + HypothesisAuthenticationManager.Instance.fetchAccessToken(true) + } private get settingsInterface() { return ( @@ -96,7 +106,9 @@ export default class SettingsManager extends React.Component<{}> {
- + + + diff --git a/src/client/views/ContextMenuItem.tsx b/src/client/views/ContextMenuItem.tsx index 99840047f..68ebd8e14 100644 --- a/src/client/views/ContextMenuItem.tsx +++ b/src/client/views/ContextMenuItem.tsx @@ -19,6 +19,7 @@ export interface OriginalMenuProps { export interface SubmenuProps { description: string; subitems: ContextMenuProps[]; + noexpand?: boolean; icon: IconProp; //maybe should be optional (icon?) closeMenu?: () => void; } @@ -96,6 +97,11 @@ export class ContextMenuItem extends React.Component {this._items.map(prop => )}
; + if (!("noexpand" in this.props)) { + return <> + {this._items.map(prop => )} + ; + } return (
diff --git a/src/client/views/collections/CollectionCarousel3DView.tsx b/src/client/views/collections/CollectionCarousel3DView.tsx index 1344b70f4..8f1cd5311 100644 --- a/src/client/views/collections/CollectionCarousel3DView.tsx +++ b/src/client/views/collections/CollectionCarousel3DView.tsx @@ -108,17 +108,6 @@ export class CollectionCarousel3DView extends CollectionSubView(Carousel3DDocume }, 1500); } - onContextMenu = (e: React.MouseEvent): void => { - // need to test if propagation has stopped because GoldenLayout forces a parallel react hierarchy to be created for its top-level layout - if (!e.isPropagationStopped()) { - ContextMenu.Instance.addItem({ - description: "Make Hero Image", event: () => { - const index = NumCast(this.layoutDoc._itemIndex); - (this.dataDoc || Doc.GetProto(this.props.Document)).hero = ObjectField.MakeCopy(this.childLayoutPairs[index].layout.data as ObjectField); - }, icon: "plus" - }); - } - } _downX = 0; _downY = 0; onPointerDown = (e: React.PointerEvent) => { @@ -184,7 +173,7 @@ export class CollectionCarousel3DView extends CollectionSubView(Carousel3DDocume const index = NumCast(this.layoutDoc._itemIndex); const translateX = (1 - index) / this.childLayoutPairs.length * 100; - return
+ return
{this.content}
diff --git a/src/client/views/collections/CollectionCarouselView.tsx b/src/client/views/collections/CollectionCarouselView.tsx index bd0e4fc9a..b3fecfb91 100644 --- a/src/client/views/collections/CollectionCarouselView.tsx +++ b/src/client/views/collections/CollectionCarouselView.tsx @@ -83,18 +83,6 @@ export class CollectionCarouselView extends CollectionSubView(CarouselDocument) ; } - - onContextMenu = (e: React.MouseEvent): void => { - // need to test if propagation has stopped because GoldenLayout forces a parallel react hierarchy to be created for its top-level layout - if (!e.isPropagationStopped()) { - ContextMenu.Instance?.addItem({ - description: "Make Hero Image", event: () => { - const index = NumCast(this.layoutDoc._itemIndex); - (this.dataDoc || Doc.GetProto(this.props.Document)).hero = ObjectField.MakeCopy(this.childLayoutPairs[index].layout.data as ObjectField); - }, icon: "plus" - }); - } - } _downX = 0; _downY = 0; onPointerDown = (e: React.PointerEvent) => { @@ -119,7 +107,7 @@ export class CollectionCarouselView extends CollectionSubView(CarouselDocument) } render() { - return
+ return
{this.content} {this.props.Document._chromeStatus !== "replaced" ? this.buttons : (null)}
; diff --git a/src/client/views/collections/CollectionTreeView.tsx b/src/client/views/collections/CollectionTreeView.tsx index 26c41f524..dbd39d8df 100644 --- a/src/client/views/collections/CollectionTreeView.tsx +++ b/src/client/views/collections/CollectionTreeView.tsx @@ -780,7 +780,7 @@ export class CollectionTreeView extends CollectionSubView UndoManager.RunInBatch(() => DocUtils.makeCustomViewClicked(this.doc, undefined, "onCheckedClick"), "edit onCheckedClick"), icon: "edit" }); - !existingOnClick && ContextMenu.Instance.addItem({ description: "OnClick...", subitems: onClicks, icon: "hand-point-right" }); + !existingOnClick && ContextMenu.Instance.addItem({ description: "OnClick...", noexpand: true, subitems: onClicks, icon: "hand-point-right" }); } outerXf = () => Utils.GetScreenTransform(this._mainEle!); onTreeDrop = (e: React.DragEvent) => this.onExternalDrop(e, {}); diff --git a/src/client/views/collections/CollectionView.tsx b/src/client/views/collections/CollectionView.tsx index df21d6a28..cbd1ac9af 100644 --- a/src/client/views/collections/CollectionView.tsx +++ b/src/client/views/collections/CollectionView.tsx @@ -272,7 +272,7 @@ export class CollectionView extends Touchable this._isLightboxOpen = true), icon: "eye" }); - !existingVm && ContextMenu.Instance.addItem({ description: category, subitems: subItems, icon: "eye" }); + !existingVm && ContextMenu.Instance.addItem({ description: category, noexpand: true, subitems: subItems, icon: "eye" }); } onContextMenu = (e: React.MouseEvent): void => { @@ -294,7 +294,7 @@ export class CollectionView extends Touchable this.props.addDocTab(this.props.Document.childClickedOpenTemplateView as Doc, "onRight"), icon: "project-diagram" }); } - layoutItems.push({ description: `${this.props.Document.isInPlaceContainer ? "Unset" : "Set"} inPlace Container`, event: () => this.props.Document.isInPlaceContainer = !this.props.Document.isInPlaceContainer, icon: "project-diagram" }); + !Doc.UserDoc().noviceMode && layoutItems.push({ description: `${this.props.Document.isInPlaceContainer ? "Unset" : "Set"} inPlace Container`, event: () => this.props.Document.isInPlaceContainer = !this.props.Document.isInPlaceContainer, icon: "project-diagram" }); !existing && cm.addItem({ description: "Options...", subitems: layoutItems, icon: "hand-point-right" }); @@ -314,7 +314,7 @@ export class CollectionView extends Touchable this.props.Document[StrCast(childClick.targetScriptKey)] = ObjectField.MakeCopy(ScriptCast(childClick.data)), })); - !existingOnClick && cm.addItem({ description: "OnClick...", subitems: onClicks, icon: "hand-point-right" }); + !existingOnClick && cm.addItem({ description: "OnClick...", noexpand: true, subitems: onClicks, icon: "hand-point-right" }); if (!Doc.UserDoc().noviceMode) { const more = cm.findByDescription("More..."); diff --git a/src/client/views/collections/collectionFreeForm/FormatShapePane.tsx b/src/client/views/collections/collectionFreeForm/FormatShapePane.tsx index 56ba9e96a..9d9ce7f36 100644 --- a/src/client/views/collections/collectionFreeForm/FormatShapePane.tsx +++ b/src/client/views/collections/collectionFreeForm/FormatShapePane.tsx @@ -11,6 +11,7 @@ import { DocumentType } from "../../../documents/DocumentTypes"; import { SelectionManager } from "../../../util/SelectionManager"; import AntimodeMenu from "../../AntimodeMenu"; import "./FormatShapePane.scss"; +import { undoBatch } from "../../../util/UndoManager"; @observer export default class FormatShapePane extends AntimodeMenu { @@ -118,6 +119,7 @@ export default class FormatShapePane extends AntimodeMenu { } } + @undoBatch @action rotate = (degrees: number) => { this.selectedInk?.forEach(action(inkView => { @@ -160,7 +162,7 @@ export default class FormatShapePane extends AntimodeMenu { colorPicker(setter: (color: string) => {}) { return
{this._palette.map(color => - )}
; @@ -171,11 +173,11 @@ export default class FormatShapePane extends AntimodeMenu { type="text" value={value} onChange={e => setter(e.target.value)} autoFocus /> -
- ; @@ -183,7 +185,7 @@ export default class FormatShapePane extends AntimodeMenu { colorButton(value: string, setter: () => {}) { return <> - @@ -206,10 +208,10 @@ export default class FormatShapePane extends AntimodeMenu { @computed get propertyGroupItems() { const fillCheck =
- this.unFilled = true)} /> + this.unFilled = true))} /> No Fill
- this.solidFil = true)} /> + this.solidFil = true))} /> Solid Fill

{this.solidFil ? "Color" : ""} @@ -218,22 +220,22 @@ export default class FormatShapePane extends AntimodeMenu {
; const markers = <> - this.markHead = this.markHead ? "" : "arrow")} /> + this.markHead = this.markHead ? "" : "arrow"))} /> Arrow Head
- this.markTail = this.markTail ? "" : "arrow")} /> + this.markTail = this.markTail ? "" : "arrow"))} /> Arrow End
; const lineCheck =
- this.unStrokd = true)} /> + this.unStrokd = true))} /> No Line
- this.solidStk = true)} /> + this.solidStk = true))} /> Solid Line
- this.dashdStk = "2")} /> + this.dashdStk = "2"))} /> Dash Line

@@ -253,7 +255,7 @@ export default class FormatShapePane extends AntimodeMenu {

Width {this.widInput}

- this._lock = !this._lock)} /> + this._lock = !this._lock))} /> Lock Ratio

Rotation {this.rotInput} diff --git a/src/client/views/collections/collectionGrid/CollectionGridView.tsx b/src/client/views/collections/collectionGrid/CollectionGridView.tsx index 2015ca930..188b88c41 100644 --- a/src/client/views/collections/collectionGrid/CollectionGridView.tsx +++ b/src/client/views/collections/collectionGrid/CollectionGridView.tsx @@ -1,7 +1,7 @@ import { action, computed, Lambda, observable, reaction } from 'mobx'; import { observer } from 'mobx-react'; import * as React from "react"; -import { Doc, Opt } from '../../../../fields/Doc'; +import { Doc, Opt, WidthSym } from '../../../../fields/Doc'; import { documentSchema } from '../../../../fields/documentSchemas'; import { Id } from '../../../../fields/FieldSymbols'; import { makeInterface } from '../../../../fields/Schema'; @@ -248,8 +248,7 @@ export class CollectionGridView extends CollectionSubView(GridSchema) { */ onContextMenu = () => { const displayOptionsMenu: ContextMenuProps[] = []; - displayOptionsMenu.push({ description: "Contents", event: () => this.props.Document.display = "contents", icon: "copy" }); - displayOptionsMenu.push({ description: "Undefined", event: () => this.props.Document.display = undefined, icon: "exclamation" }); + displayOptionsMenu.push({ description: "Toggle Content Display Style", event: () => this.props.Document.display = this.props.Document.display ? undefined : "contents", icon: "copy" }); ContextMenu.Instance.addItem({ description: "Display", subitems: displayOptionsMenu, icon: "tv" }); } diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx index 6ef976ceb..a586e81d8 100644 --- a/src/client/views/nodes/DocumentView.tsx +++ b/src/client/views/nodes/DocumentView.tsx @@ -770,6 +770,7 @@ export class DocumentView extends DocComponent(Docu const options = cm.findByDescription("Options..."); const optionItems: ContextMenuProps[] = options && "subitems" in options ? options.subitems : []; const templateDoc = Cast(this.props.Document[StrCast(this.props.Document.layoutKey)], Doc, null); + optionItems.push({ description: this.Document.lockedPosition ? "Unlock Position" : "Lock Position", event: this.toggleLockPosition, icon: BoolCast(this.Document.lockedPosition) ? "unlock" : "lock" }); templateDoc && optionItems.push({ description: "Open Template ", event: () => this.props.addDocTab(templateDoc, "onRight"), icon: "eye" }); !options && cm.addItem({ description: "Options...", subitems: optionItems, icon: "compass" }); @@ -783,14 +784,14 @@ export class DocumentView extends DocComponent(Docu onClicks.push({ description: this.Document.isLinkButton ? "Remove Follow Behavior" : "Follow Link on Right", event: this.toggleFollowOnRight, icon: "concierge-bell" }); onClicks.push({ description: this.Document.isLinkButton || this.onClickHandler ? "Remove Click Behavior" : "Follow Link", event: this.toggleLinkButtonBehavior, icon: "concierge-bell" }); onClicks.push({ description: "Edit onClick Script", event: () => UndoManager.RunInBatch(() => DocUtils.makeCustomViewClicked(this.props.Document, undefined, "onClick"), "edit onClick"), icon: "edit" }); - !existingOnClick && cm.addItem({ description: "OnClick...", subitems: onClicks, icon: "hand-point-right" }); + !existingOnClick && cm.addItem({ description: "OnClick...", noexpand: true, subitems: onClicks, icon: "hand-point-right" }); const funcs: ContextMenuProps[] = []; if (this.layoutDoc.onDragStart) { funcs.push({ description: "Drag an Alias", icon: "edit", event: () => this.Document.dragFactory && (this.layoutDoc.onDragStart = ScriptField.MakeFunction('getAlias(this.dragFactory)')) }); funcs.push({ description: "Drag a Copy", icon: "edit", event: () => this.Document.dragFactory && (this.layoutDoc.onDragStart = ScriptField.MakeFunction('getCopy(this.dragFactory, true)')) }); funcs.push({ description: "Drag Document", icon: "edit", event: () => this.layoutDoc.onDragStart = undefined }); - cm.addItem({ description: "OnDrag...", subitems: funcs, icon: "asterisk" }); + cm.addItem({ description: "OnDrag...", noexpand: true, subitems: funcs, icon: "asterisk" }); } const more = cm.findByDescription("More..."); @@ -817,29 +818,28 @@ export class DocumentView extends DocComponent(Docu // a.download = `DocExport-${this.props.Document[Id]}.zip`; // a.click(); }); + moreItems.push({ description: "Copy ID", event: () => Utils.CopyText(Utils.prepend("/doc/" + this.props.Document[Id])), icon: "fingerprint" }); } - moreItems.push({ description: this.Document.lockedPosition ? "Unlock Position" : "Lock Position", event: this.toggleLockPosition, icon: BoolCast(this.Document.lockedPosition) ? "unlock" : "lock" }); - moreItems.push({ description: "Copy ID", event: () => Utils.CopyText(Utils.prepend("/doc/" + this.props.Document[Id])), icon: "fingerprint" }); moreItems.push({ description: "Delete", event: this.deleteClicked, icon: "trash" }); moreItems.push({ description: "Share", event: () => SharingManager.Instance.open(this), icon: "external-link-alt" }); !more && cm.addItem({ description: "More...", subitems: moreItems, icon: "hand-point-right" }); cm.moveAfter(cm.findByDescription("More...")!, cm.findByDescription("OnClick...")!); - const help = cm.findByDescription("Help..."); - const helpItems: ContextMenuProps[] = help && "subitems" in help ? help.subitems : []; - helpItems.push({ description: "Text Shortcuts Ctrl+/", event: () => this.props.addDocTab(Docs.Create.PdfDocument(Utils.prepend("/assets/cheat-sheet.pdf"), { _width: 300, _height: 300 }), "onRight"), icon: "keyboard" }); - helpItems.push({ description: "Show Fields ", event: () => this.props.addDocTab(Docs.Create.KVPDocument(this.props.Document, { _width: 300, _height: 300 }), "onRight"), icon: "layer-group" }); - cm.addItem({ description: "Help...", subitems: helpItems, icon: "question" }); - - const existingAcls = cm.findByDescription("Privacy..."); - const aclItems: ContextMenuProps[] = existingAcls && "subitems" in existingAcls ? existingAcls.subitems : []; - aclItems.push({ description: "Make Add Only", event: () => this.setAcl("addOnly"), icon: "concierge-bell" }); - aclItems.push({ description: "Make Read Only", event: () => this.setAcl("readOnly"), icon: "concierge-bell" }); - aclItems.push({ description: "Make Private", event: () => this.setAcl("ownerOnly"), icon: "concierge-bell" }); - aclItems.push({ description: "Make Editable", event: () => this.setAcl("write"), icon: "concierge-bell" }); - aclItems.push({ description: "Test Private", event: () => this.testAcl("ownerOnly"), icon: "concierge-bell" }); - aclItems.push({ description: "Test Readonly", event: () => this.testAcl("readOnly"), icon: "concierge-bell" }); - !existingAcls && cm.addItem({ description: "Privacy...", subitems: aclItems, icon: "question" }); + // const help = cm.findByDescription("Help..."); + // const helpItems: ContextMenuProps[] = help && "subitems" in help ? help.subitems : []; + // helpItems.push({ description: "Text Shortcuts Ctrl+/", event: () => this.props.addDocTab(Docs.Create.PdfDocument(Utils.prepend("/assets/cheat-sheet.pdf"), { _width: 300, _height: 300 }), "onRight"), icon: "keyboard" }); + // helpItems.push({ description: "Show Fields ", event: () => this.props.addDocTab(Docs.Create.KVPDocument(this.props.Document, { _width: 300, _height: 300 }), "onRight"), icon: "layer-group" }); + // cm.addItem({ description: "Help...", subitems: helpItems, icon: "question" }); + + // const existingAcls = cm.findByDescription("Privacy..."); + // const aclItems: ContextMenuProps[] = existingAcls && "subitems" in existingAcls ? existingAcls.subitems : []; + // aclItems.push({ description: "Make Add Only", event: () => this.setAcl("addOnly"), icon: "concierge-bell" }); + // aclItems.push({ description: "Make Read Only", event: () => this.setAcl("readOnly"), icon: "concierge-bell" }); + // aclItems.push({ description: "Make Private", event: () => this.setAcl("ownerOnly"), icon: "concierge-bell" }); + // aclItems.push({ description: "Make Editable", event: () => this.setAcl("write"), icon: "concierge-bell" }); + // aclItems.push({ description: "Test Private", event: () => this.testAcl("ownerOnly"), icon: "concierge-bell" }); + // aclItems.push({ description: "Test Readonly", event: () => this.testAcl("readOnly"), icon: "concierge-bell" }); + // !existingAcls && cm.addItem({ description: "Privacy...", subitems: aclItems, icon: "question" }); // const recommender_subitems: ContextMenuProps[] = []; diff --git a/src/client/views/nodes/ImageBox.tsx b/src/client/views/nodes/ImageBox.tsx index d16aa528c..4eba21eab 100644 --- a/src/client/views/nodes/ImageBox.tsx +++ b/src/client/views/nodes/ImageBox.tsx @@ -157,29 +157,31 @@ export class ImageBox extends ViewBoxAnnotatableComponent GooglePhotos.Transactions.UploadImages([this.props.Document]), icon: "caret-square-right" }); - funcs.push({ description: "Copy path", event: () => Utils.CopyText(field.url.href), icon: "expand-arrows-alt" }); - // funcs.push({ - // description: "Reset Native Dimensions", event: action(async () => { - // const curNW = NumCast(this.dataDoc[this.fieldKey + "-nativeWidth"]); - // const curNH = NumCast(this.dataDoc[this.fieldKey + "-nativeHeight"]); - // if (this.props.PanelWidth() / this.props.PanelHeight() > curNW / curNH) { - // this.dataDoc[this.fieldKey + "-nativeWidth"] = this.props.PanelHeight() * curNW / curNH; - // this.dataDoc[this.fieldKey + "-nativeHeight"] = this.props.PanelHeight(); - // } else { - // this.dataDoc[this.fieldKey + "-nativeWidth"] = this.props.PanelWidth(); - // this.dataDoc[this.fieldKey + "-nativeHeight"] = this.props.PanelWidth() * curNH / curNW; - // } - // }), icon: "expand-arrows-alt" - // }); - - const existingAnalyze = ContextMenu.Instance?.findByDescription("Analyzers..."); - const modes: ContextMenuProps[] = existingAnalyze && "subitems" in existingAnalyze ? existingAnalyze.subitems : []; - modes.push({ description: "Generate Tags", event: this.generateMetadata, icon: "tag" }); - modes.push({ description: "Find Faces", event: this.extractFaces, icon: "camera" }); - //modes.push({ description: "Recommend", event: this.extractText, icon: "brain" }); - !existingAnalyze && ContextMenu.Instance?.addItem({ description: "Analyzers...", subitems: modes, icon: "hand-point-right" }); + funcs.push({ description: "Rotate Clockwise 90", event: this.rotate, icon: "expand-arrows-alt" }); + if (!Doc.UserDoc().noviceMode) { + funcs.push({ description: "Export to Google Photos", event: () => GooglePhotos.Transactions.UploadImages([this.props.Document]), icon: "caret-square-right" }); + funcs.push({ description: "Copy path", event: () => Utils.CopyText(field.url.href), icon: "expand-arrows-alt" }); + // funcs.push({ + // description: "Reset Native Dimensions", event: action(async () => { + // const curNW = NumCast(this.dataDoc[this.fieldKey + "-nativeWidth"]); + // const curNH = NumCast(this.dataDoc[this.fieldKey + "-nativeHeight"]); + // if (this.props.PanelWidth() / this.props.PanelHeight() > curNW / curNH) { + // this.dataDoc[this.fieldKey + "-nativeWidth"] = this.props.PanelHeight() * curNW / curNH; + // this.dataDoc[this.fieldKey + "-nativeHeight"] = this.props.PanelHeight(); + // } else { + // this.dataDoc[this.fieldKey + "-nativeWidth"] = this.props.PanelWidth(); + // this.dataDoc[this.fieldKey + "-nativeHeight"] = this.props.PanelWidth() * curNH / curNW; + // } + // }), icon: "expand-arrows-alt" + // }); + + const existingAnalyze = ContextMenu.Instance?.findByDescription("Analyzers..."); + const modes: ContextMenuProps[] = existingAnalyze && "subitems" in existingAnalyze ? existingAnalyze.subitems : []; + modes.push({ description: "Generate Tags", event: this.generateMetadata, icon: "tag" }); + modes.push({ description: "Find Faces", event: this.extractFaces, icon: "camera" }); + //modes.push({ description: "Recommend", event: this.extractText, icon: "brain" }); + !existingAnalyze && ContextMenu.Instance?.addItem({ description: "Analyzers...", subitems: modes, icon: "hand-point-right" }); + } ContextMenu.Instance?.addItem({ description: "Options...", subitems: funcs, icon: "asterisk" }); } diff --git a/src/client/views/nodes/LabelBox.tsx b/src/client/views/nodes/LabelBox.tsx index 836ef4149..0dfbdc5cf 100644 --- a/src/client/views/nodes/LabelBox.tsx +++ b/src/client/views/nodes/LabelBox.tsx @@ -41,7 +41,7 @@ export class LabelBox extends ViewBoxBaseComponent DocUtils.makeCustomViewClicked(this.rootDoc, Docs.Create.FreeformDocument, "freeform"), icon: "eye" }); - appearanceItems.push({ description: "Change Perspective...", subitems: changeItems, icon: "external-link-alt" }); + appearanceItems.push({ description: "Change Perspective...", noexpand: true, subitems: changeItems, icon: "external-link-alt" }); const uicontrols: ContextMenuProps[] = []; uicontrols.push({ description: "Toggle Sidebar", event: () => this.layoutDoc._showSidebar = !this.layoutDoc._showSidebar, icon: "expand-arrows-alt" }); uicontrols.push({ description: "Toggle Dictation Icon", event: () => this.layoutDoc._showAudio = !this.layoutDoc._showAudio, icon: "expand-arrows-alt" }); @@ -489,10 +489,29 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp proto instanceof Doc && (proto.BROADCAST_MESSAGE = Cast(this.rootDoc[this.fieldKey], RichTextField)?.Text)), icon: "expand-arrows-alt" }); - appearanceItems.push({ description: "UI Controls...", subitems: uicontrols, icon: "asterisk" }); + appearanceItems.push({ description: "UI Controls...", noexpand: true, subitems: uicontrols, icon: "asterisk" }); this.rootDoc.isTemplateDoc && appearanceItems.push({ description: "Make Default Layout", event: async () => Doc.UserDoc().defaultTextLayout = new PrefetchProxy(this.rootDoc), icon: "eye" }); Doc.UserDoc().defaultTextLayout && appearanceItems.push({ description: "Reset default note style", event: () => Doc.UserDoc().defaultTextLayout = undefined, icon: "eye" }); - appearanceItems.push({ + + !appearance && ContextMenu.Instance.addItem({ description: "Appearance...", subitems: appearanceItems, icon: "eye" }); + + const funcs: ContextMenuProps[] = []; + + const highlighting: ContextMenuProps[] = []; + ["My Text", "Text from Others", "Todo Items", "Important Items", "Ignore Items", "Disagree Items", "By Recent Minute", "By Recent Hour"].forEach(option => + highlighting.push({ + description: (FormattedTextBox._highlights.indexOf(option) === -1 ? "Highlight " : "Unhighlight ") + option, event: () => { + e.stopPropagation(); + if (FormattedTextBox._highlights.indexOf(option) === -1) { + FormattedTextBox._highlights.push(option); + } else { + FormattedTextBox._highlights.splice(FormattedTextBox._highlights.indexOf(option), 1); + } + this.updateHighlights(); + }, icon: "expand-arrows-alt" + })); + funcs.push({ description: "highlighting...", noexpand: true, subitems: highlighting, icon: "hand-point-right" }); + funcs.push({ description: "Convert to be a template style", event: () => { if (!this.layoutDoc.isTemplateDoc) { const title = StrCast(this.rootDoc.title); @@ -517,29 +536,10 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp Doc.AddDocToList(Cast(Doc.UserDoc()["template-notes"], Doc, null), "data", this.rootDoc); }, icon: "eye" }); - !appearance && ContextMenu.Instance.addItem({ description: "Appearance...", subitems: appearanceItems, icon: "eye" }); + funcs.push({ description: `${this.Document._autoHeight ? "Variable Height" : "Auto Height"}`, event: () => this.layoutDoc._autoHeight = !this.layoutDoc._autoHeight, icon: "plus" }); - const funcs: ContextMenuProps[] = []; - - //funcs.push({ description: `${this.Document._autoHeight ? "Variable Height" : "Auto Height"}`, event: () => this.layoutDoc._autoHeight = !this.layoutDoc._autoHeight, icon: "plus" }); - funcs.push({ description: (!this.layoutDoc._nativeWidth || !this.layoutDoc._nativeHeight ? "Freeze" : "Unfreeze") + " Aspect", event: this.toggleNativeDimensions, icon: "snowflake" }); funcs.push({ description: "Toggle Single Line", event: () => this.layoutDoc._singleLine = !this.layoutDoc._singleLine, icon: "expand-arrows-alt" }); - - const highlighting: ContextMenuProps[] = []; - ["My Text", "Text from Others", "Todo Items", "Important Items", "Ignore Items", "Disagree Items", "By Recent Minute", "By Recent Hour"].forEach(option => - highlighting.push({ - description: (FormattedTextBox._highlights.indexOf(option) === -1 ? "Highlight " : "Unhighlight ") + option, event: () => { - e.stopPropagation(); - if (FormattedTextBox._highlights.indexOf(option) === -1) { - FormattedTextBox._highlights.push(option); - } else { - FormattedTextBox._highlights.splice(FormattedTextBox._highlights.indexOf(option), 1); - } - this.updateHighlights(); - }, icon: "expand-arrows-alt" - })); - funcs.push({ description: "highlighting...", subitems: highlighting, icon: "hand-point-right" }); - + funcs.push({ description: (!this.layoutDoc._nativeWidth || !this.layoutDoc._nativeHeight ? "Freeze" : "Unfreeze") + " Aspect", event: this.toggleNativeDimensions, icon: "snowflake" }); ContextMenu.Instance.addItem({ description: "Options...", subitems: funcs, icon: "asterisk" }); this._downX = this._downY = Number.NaN; } -- cgit v1.2.3-70-g09d2 From d3623e17ae881b50f712d259a18c4304f1bd0d24 Mon Sep 17 00:00:00 2001 From: anika-ahluwalia Date: Tue, 14 Jul 2020 12:40:24 -0500 Subject: tried fixing label on link line --- .../CollectionFreeFormLinkView.tsx | 89 +++++++++++++++++++++- 1 file changed, 86 insertions(+), 3 deletions(-) (limited to 'src/client/views/collections/collectionFreeForm') diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinkView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinkView.tsx index ae79c27e0..17f7e3128 100644 --- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinkView.tsx +++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinkView.tsx @@ -21,8 +21,16 @@ export interface CollectionFreeFormLinkViewProps { export class CollectionFreeFormLinkView extends React.Component { @observable _opacity: number = 0; _anchorDisposer: IReactionDisposer | undefined; + + @observable descriptionText = StrCast(this.props.A.props.Document.description); + @observable down: boolean = false; + @observable downCoor: number[] = [0, 0]; + @observable offset: number[] = [0, 0]; + @action componentDidMount() { + // document.addEventListener("pointerup", this.onUp); + this._anchorDisposer = reaction(() => [this.props.A.props.ScreenToLocalTransform(), this.props.B.props.ScreenToLocalTransform(), this.props.A.isSelected() || Doc.IsBrushed(this.props.A.props.Document), this.props.A.isSelected() || Doc.IsBrushed(this.props.A.props.Document)], action(() => { if (SnappingManager.GetIsDragging()) return; @@ -82,10 +90,47 @@ export class CollectionFreeFormLinkView extends React.Component) => { + if (e.key === "Enter") { + this.setDescripValue(this.descriptionText); + document.getElementById('input')?.blur(); + } + } + + @action + handleChange = (e: React.ChangeEvent) => { + this.descriptionText = e.target.value; + } + + @action + setDescripValue = (value: string) => { + this.props.A.props.Document.description = value; + return true; + } + + pointerDown = (e: React.PointerEvent) => { + this.down = true; + this.downCoor[0] = e.screenX; + this.downCoor[1] = e.screenY; + } + + onUp = (e: React.PointerEvent) => { + if (this.down) { + this.offset[0] = e.screenX - this.downCoor[0]; + this.offset[1] = e.screenY - this.downCoor[1]; + } + } + + @action componentWillUnmount() { this._anchorDisposer?.(); + //document.removeEventListener("pointerup", this.onUp); } + + render() { if (SnappingManager.GetIsDragging()) return null; this.props.A.props.ScreenToLocalTransform().transform(this.props.B.props.ScreenToLocalTransform()); @@ -110,11 +155,49 @@ export class CollectionFreeFormLinkView extends React.Component - - {text} + + {/* {this.down ?
: null} */} + + + {this.descriptionText} + + {/* */} + ); -- cgit v1.2.3-70-g09d2 From f6db7693e18e06c467a7136c591bd12a2cc96c7f Mon Sep 17 00:00:00 2001 From: Bob Zeleznik Date: Tue, 14 Jul 2020 14:20:53 -0400 Subject: fixed issues with creating & using scripting boxes by making scriptFields be a function, not value, prop --- src/client/documents/Documents.ts | 2 ++ src/client/util/CurrentUserUtils.ts | 26 ++++++++++++------ src/client/views/OverlayView.scss | 2 ++ src/client/views/TemplateMenu.tsx | 7 +++-- .../views/collections/CollectionCarousel3DView.tsx | 10 +++---- .../views/collections/CollectionCarouselView.tsx | 7 +++-- .../views/collections/CollectionStackingView.tsx | 4 +-- .../views/collections/CollectionTreeView.tsx | 30 +++++++++++--------- src/client/views/collections/CollectionView.tsx | 11 +++++--- .../collectionFreeForm/CollectionFreeFormView.tsx | 9 +++--- .../collectionGrid/CollectionGridView.tsx | 2 +- .../CollectionMulticolumnView.tsx | 4 +-- .../CollectionMultirowView.tsx | 4 +-- src/client/views/nodes/DocumentView.tsx | 32 +++++++++++----------- src/fields/documentSchemas.ts | 1 - 15 files changed, 87 insertions(+), 64 deletions(-) (limited to 'src/client/views/collections/collectionFreeForm') diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts index a415e17c8..90cef31d9 100644 --- a/src/client/documents/Documents.ts +++ b/src/client/documents/Documents.ts @@ -136,6 +136,8 @@ export interface DocumentOptions { dontRegisterChildViews?: boolean; lookupField?: ScriptField; // script that returns the value of a field. This script is passed the rootDoc, layoutDoc, field, and container of the document. see PresBox. "onDoubleClick-rawScript"?: string; // onDoubleClick script in raw text form + "onChildDoubleClick-rawScript"?: string; // onChildDoubleClick script in raw text form + "onChildClick-rawScript"?: string // on ChildClick script in raw text form "onClick-rawScript"?: string; // onClick script in raw text form "onCheckedClick-rawScript"?: string; // onChecked script in raw text form "onCheckedClick-params"?: List; // parameter list for onChecked treeview functions diff --git a/src/client/util/CurrentUserUtils.ts b/src/client/util/CurrentUserUtils.ts index 7a06e1bc1..ad8336e8a 100644 --- a/src/client/util/CurrentUserUtils.ts +++ b/src/client/util/CurrentUserUtils.ts @@ -413,7 +413,7 @@ export class CurrentUserUtils { { title: "Drag a presentation view", label: "Prezi", icon: "tv", click: 'openOnRight(Doc.UserDoc().activePresentation = getCopy(this.dragFactory, true))', drag: `Doc.UserDoc().activePresentation = getCopy(this.dragFactory,true)`, dragFactory: doc.emptyPresentation as Doc }, { title: "Drag a search box", label: "Query", icon: "search", ignoreClick: true, drag: 'Docs.Create.QueryDocument({ _width: 200, title: "an image of a cat" })' }, { title: "Drag a scripting box", label: "Script", icon: "terminal", click: 'openOnRight(getCopy(this.dragFactory, true))', drag: 'getCopy(this.dragFactory, true)', dragFactory: doc.emptyScript as Doc }, - // { title: "Drag an import folder", label: "Load", icon: "cloud-upload-alt", ignoreClick: true, drag: 'Docs.Create.DirectoryImportDocument({ title: "Directory Import", _width: 400, _height: 400 })' }, + { title: "Drag an import folder", label: "Load", icon: "cloud-upload-alt", ignoreClick: true, drag: 'Docs.Create.DirectoryImportDocument({ title: "Directory Import", _width: 400, _height: 400 })' }, { title: "Drag a mobile view", label: "Phone", icon: "mobile", click: 'openOnRight(Doc.UserDoc().activeMobileMenu)', drag: 'this.dragFactory', dragFactory: doc.activeMobileMenu as Doc }, // { title: "Drag an instance of the device collection", label: "Buxton", icon: "globe-asia", ignoreClick: true, drag: 'Docs.Create.Buxton()' }, // { title: "use pen", icon: "pen-nib", click: 'activatePen(this.activeInkPen = sameDocs(this.activeInkPen, this) ? undefined : this)', backgroundColor: "blue", ischecked: `sameDocs(this.activeInkPen, this)`, activeInkPen: doc }, @@ -775,17 +775,17 @@ export class CurrentUserUtils { static setupClickEditorTemplates(doc: Doc) { if (doc["clickFuncs-child"] === undefined) { + // to use this function, select it from the context menu of a collection. then edit the onChildClick script. Add two Doc variables: 'target' and 'thisContainer', then assign 'target' to some target collection. After that, clicking on any document in the initial collection will open it in the target const openInTarget = Docs.Create.ScriptingDocument(ScriptField.MakeScript( - "docCast(thisContainer.target).then((target) => {" + - " target && docCast(this.source).then((source) => { " + - " target.proto.data = new List([source || this]); " + - " }); " + - "})", - { target: Doc.name }), { title: "Click to open in target", _width: 300, _height: 200, targetScriptKey: "onChildClick" }); + "docCast(thisContainer.target).then((target) => target && (target.proto.data = new List([self]))) ", + { thisContainer: Doc.name }), { + title: "Click to open in target", _width: 300, _height: 200, + targetScriptKey: "onChildClick", + }); const openDetail = Docs.Create.ScriptingDocument(ScriptField.MakeScript( "openOnRight(self.doubleClickView)", - { target: Doc.name }), { title: "Double click to open doubleClickView", _width: 300, _height: 200, targetScriptKey: "onChildDoubleClick" }); + {}), { title: "Double click to open doubleClickView", _width: 300, _height: 200, targetScriptKey: "onChildDoubleClick" }); doc["clickFuncs-child"] = Docs.Create.TreeDocument([openInTarget, openDetail], { title: "on Child Click function templates" }); } @@ -797,14 +797,22 @@ export class CurrentUserUtils { title: "onClick", "onClick-rawScript": "console.log('click')", isTemplateDoc: true, isTemplateForField: "onClick", _width: 300, _height: 200 }, "onClick"); + const onChildClick = Docs.Create.ScriptingDocument(undefined, { + title: "onChildClick", "onChildClick-rawScript": "console.log('child click')", + isTemplateDoc: true, isTemplateForField: "onChildClick", _width: 300, _height: 200 + }, "onChildClick"); const onDoubleClick = Docs.Create.ScriptingDocument(undefined, { title: "onDoubleClick", "onDoubleClick-rawScript": "console.log('double click')", isTemplateDoc: true, isTemplateForField: "onDoubleClick", _width: 300, _height: 200 }, "onDoubleClick"); + const onChildDoubleClick = Docs.Create.ScriptingDocument(undefined, { + title: "onChildDoubleClick", "onChildDoubleClick-rawScript": "console.log('child double click')", + isTemplateDoc: true, isTemplateForField: "onChildDoubleClick", _width: 300, _height: 200 + }, "onChildDoubleClick"); const onCheckedClick = Docs.Create.ScriptingDocument(undefined, { title: "onCheckedClick", "onCheckedClick-rawScript": "console.log(heading + checked + containingTreeView)", "onCheckedClick-params": new List(["heading", "checked", "containingTreeView"]), isTemplateDoc: true, isTemplateForField: "onCheckedClick", _width: 300, _height: 200 }, "onCheckedClick"); - doc.clickFuncs = Docs.Create.TreeDocument([onClick, onDoubleClick, onCheckedClick], { title: "onClick funcs" }); + doc.clickFuncs = Docs.Create.TreeDocument([onClick, onChildClick, onDoubleClick, onCheckedClick], { title: "onClick funcs" }); } PromiseValue(Cast(doc.clickFuncs, Doc)).then(func => func && PromiseValue(func.data).then(DocListCast)); diff --git a/src/client/views/OverlayView.scss b/src/client/views/OverlayView.scss index 26c2e0e1e..09a349012 100644 --- a/src/client/views/OverlayView.scss +++ b/src/client/views/OverlayView.scss @@ -3,6 +3,8 @@ overflow: hidden; display: flex; flex-direction: column; + top: 0; + left: 0; } .overlayWindow-outerDiv, diff --git a/src/client/views/TemplateMenu.tsx b/src/client/views/TemplateMenu.tsx index 916e631d0..9fb8a227e 100644 --- a/src/client/views/TemplateMenu.tsx +++ b/src/client/views/TemplateMenu.tsx @@ -108,8 +108,9 @@ export class TemplateMenu extends React.Component { return100 = () => 100; @computed get scriptField() { - return ScriptField.MakeScript("docs.map(d => switchView(d, this))", { this: Doc.name, heading: "string", checked: "string", containingTreeView: Doc.name, firstDoc: Doc.name }, + const script = ScriptField.MakeScript("docs.map(d => switchView(d, this))", { this: Doc.name, heading: "string", checked: "string", containingTreeView: Doc.name, firstDoc: Doc.name }, { docs: new List(this.props.docViews.map(dv => dv.props.Document)) }); + return script ? () => script : undefined; } templateIsUsed = (selDoc: Doc, templateDoc: Doc) => { const template = StrCast(templateDoc.dragFactory ? Cast(templateDoc.dragFactory, Doc, null)?.title : templateDoc.title); @@ -142,8 +143,8 @@ export class TemplateMenu extends React.Component { ContainingCollectionView={undefined} docFilters={returnEmptyFilter} rootSelected={returnFalse} - onCheckedClick={this.scriptField!} - onChildClick={this.scriptField!} + onCheckedClick={this.scriptField} + onChildClick={this.scriptField} LibraryPath={emptyPath} dropAction={undefined} active={returnTrue} diff --git a/src/client/views/collections/CollectionCarousel3DView.tsx b/src/client/views/collections/CollectionCarousel3DView.tsx index 8f1cd5311..8e9970ada 100644 --- a/src/client/views/collections/CollectionCarousel3DView.tsx +++ b/src/client/views/collections/CollectionCarousel3DView.tsx @@ -38,15 +38,15 @@ export class CollectionCarousel3DView extends CollectionSubView(Carousel3DDocume panelWidth = () => this.props.PanelWidth() / 3; panelHeight = () => this.props.PanelHeight() * 0.6; + onChildDoubleClick = () => ScriptCast(this.layoutDoc.onChildDoubleClick); @computed get content() { const currentIndex = NumCast(this.layoutDoc._itemIndex); const displayDoc = (childPair: { layout: Doc, data: Doc }) => { + const script = ScriptField.MakeScript("child._showCaption = 'caption'", { child: Doc.name }, { child: childPair.layout }); + const onChildClick = script && (() => script); return ; const CarouselDocument = makeInterface(documentSchema, collectionSchema); @@ -40,14 +41,16 @@ export class CollectionCarouselView extends CollectionSubView(CarouselDocument) this.layoutDoc._itemIndex = (NumCast(this.layoutDoc._itemIndex) - 1 + this.childLayoutPairs.length) % this.childLayoutPairs.length; } panelHeight = () => this.props.PanelHeight() - 50; + onContentDoubleClick = () => ScriptCast(this.layoutDoc.onChildDoubleClick); + onContentClick = () => ScriptCast(this.layoutDoc.onChildClick); @computed get content() { const index = NumCast(this.layoutDoc._itemIndex); return !(this.childLayoutPairs?.[index]?.layout instanceof Doc) ? (null) : <>
this.props.childClickScript || ScriptCast(this.Document.onChildClick); } + @computed get onChildDoubleClickHandler() { return () => this.props.childDoubleClickScript || ScriptCast(this.Document.onChildDoubleClick); } addDocTab = (doc: Doc, where: string) => { if (where === "inPlace" && this.layoutDoc.isInPlaceContainer) { diff --git a/src/client/views/collections/CollectionTreeView.tsx b/src/client/views/collections/CollectionTreeView.tsx index dbd39d8df..8438248ad 100644 --- a/src/client/views/collections/CollectionTreeView.tsx +++ b/src/client/views/collections/CollectionTreeView.tsx @@ -61,8 +61,8 @@ export interface TreeViewProps { treeViewHideHeaderFields: () => boolean; treeViewPreventOpen: boolean; renderedIds: string[]; // list of document ids rendered used to avoid unending expansion of items in a cycle - onCheckedClick?: ScriptField; - onChildClick?: ScriptField; + onCheckedClick?: () => ScriptField; + onChildClick?: () => ScriptField; ignoreFields?: string[]; } @@ -76,7 +76,7 @@ export interface TreeViewProps { * treeViewExpandedView : name of field whose contents are being displayed as the document's subtree */ class TreeView extends React.Component { - private _editTitleScript: ScriptField | undefined; + private _editTitleScript: (() => ScriptField) | undefined; private _header?: React.RefObject = React.createRef(); private _treedropDisposer?: DragManager.DragDropDisposer; private _dref = React.createRef(); @@ -124,7 +124,8 @@ class TreeView extends React.Component { constructor(props: any) { super(props); - this._editTitleScript = ScriptField.MakeScript(`{setInPlace(self, 'editTitle', '${this._uniqueId}'); selectDoc(self);} `); + const script = ScriptField.MakeScript(`{setInPlace(self, 'editTitle', '${this._uniqueId}'); selectDoc(self);} `); + this._editTitleScript = script && (() => script); if (Doc.GetT(this.doc, "editTitle", "string", true) === "*") Doc.SetInPlace(this.doc, "editTitle", this._uniqueId, false); } @@ -368,13 +369,13 @@ class TreeView extends React.Component { } } - get onCheckedClick() { return this.props.onCheckedClick || ScriptCast(this.doc.onCheckedClick); } + get onCheckedClick() { return this.props.onCheckedClick || (() => ScriptCast(this.doc.onCheckedClick)); } @action bulletClick = (e: React.MouseEvent) => { - if (this.onCheckedClick && this.doc.type !== DocumentType.COL) { + if (this.onCheckedClick() && this.doc.type !== DocumentType.COL) { // this.props.document.treeViewChecked = this.props.document.treeViewChecked === "check" ? "x" : this.props.document.treeViewChecked === "x" ? undefined : "check"; - this.onCheckedClick.script.run({ + this.onCheckedClick()?.script.run({ this: this.doc.isTemplateForField && this.props.dataDoc ? this.props.dataDoc : this.doc, heading: this.props.containingCollection.title, checked: this.doc.treeViewChecked === "check" ? "x" : this.doc.treeViewChecked === "x" ? undefined : "check", @@ -388,7 +389,7 @@ class TreeView extends React.Component { @computed get renderBullet() { TraceMobx(); - const checked = this.doc.type === DocumentType.COL ? undefined : this.onCheckedClick ? (this.doc.treeViewChecked ?? "unchecked") : undefined; + const checked = this.doc.type === DocumentType.COL ? undefined : this.onCheckedClick() ? (this.doc.treeViewChecked ?? "unchecked") : undefined; return
{ treeViewPreventOpen: boolean, renderedIds: string[], libraryPath: Doc[] | undefined, - onCheckedClick: ScriptField | undefined, - onChildClick: ScriptField | undefined, + onCheckedClick?: () => ScriptField, + onChildClick?: () => ScriptField, ignoreFields: string[] | undefined ) { const viewSpecScript = Cast(containingCollection.viewSpecScript, ScriptField); @@ -658,8 +659,8 @@ class TreeView extends React.Component { export type collectionTreeViewProps = { treeViewHideTitle?: boolean; treeViewHideHeaderFields?: boolean; - onCheckedClick?: ScriptField; - onChildClick?: ScriptField; + onCheckedClick?: () => ScriptField; + onChildClick?: () => ScriptField; }; @observer @@ -797,6 +798,9 @@ export class CollectionTreeView extends CollectionSubView { console.log(e); } + onChildClick = () => { + return this.props.onChildClick?.() || ScriptCast(this.doc.onChildClick); + } render() { TraceMobx(); if (!(this.doc instanceof Doc)) return (null); @@ -839,7 +843,7 @@ export class CollectionTreeView extends CollectionSubView this.props.treeViewHideHeaderFields || BoolCast(this.doc.treeViewHideHeaderFields), BoolCast(this.doc.treeViewPreventOpen), [], this.props.LibraryPath, this.props.onCheckedClick, - this.props.onChildClick || ScriptCast(this.doc.onChildClick), this.props.ignoreFields) + this.onChildClick, this.props.ignoreFields) }
diff --git a/src/client/views/collections/CollectionView.tsx b/src/client/views/collections/CollectionView.tsx index cbd1ac9af..5165a8f11 100644 --- a/src/client/views/collections/CollectionView.tsx +++ b/src/client/views/collections/CollectionView.tsx @@ -305,14 +305,16 @@ export class CollectionView extends Touchable onClicks.push({ description: `Edit ${func.name} script`, icon: "edit", event: (obj: any) => { - ScriptBox.EditButtonScript(func.name + "...", this.props.Document, func.key, obj.x, obj.y, { thisContainer: Doc.name }); + const alias = Doc.MakeAlias(this.props.Document); + DocUtils.makeCustomViewClicked(alias, undefined, func.key); + this.props.addDocTab(alias, "onRight"); } })); DocListCast(Cast(Doc.UserDoc()["clickFuncs-child"], Doc, null).data).forEach(childClick => onClicks.push({ description: `Set child ${childClick.title}`, icon: "edit", - event: () => this.props.Document[StrCast(childClick.targetScriptKey)] = ObjectField.MakeCopy(ScriptCast(childClick.data)), + event: () => Doc.GetProto(this.props.Document)[StrCast(childClick.targetScriptKey)] = ObjectField.MakeCopy(ScriptCast(childClick.data)), })); !existingOnClick && cm.addItem({ description: "OnClick...", noexpand: true, subitems: onClicks, icon: "hand-point-right" }); @@ -470,7 +472,8 @@ export class CollectionView extends Touchable script : undefined; } @computed get filterView() { TraceMobx(); @@ -523,7 +526,7 @@ export class CollectionView extends Touchable (this.props.childClickScript || ScriptCast(this.Document.onChildClick)); } + @computed get onChildDoubleClickHandler() { return () => (this.props.childDoubleClickScript || ScriptCast(this.Document.onChildDoubleClick)); } @computed get backgroundActive() { return this.layoutDoc.isBackground && (this.props.ContainingCollectionView?.active() || this.props.active()); } backgroundHalo = () => BoolCast(this.Document.useClusters); parentActive = (outsideReaction: boolean) => this.props.active(outsideReaction) || this.backgroundActive ? true : false; @@ -1151,7 +1152,7 @@ export class CollectionFreeFormView extends CollectionSubView this._layoutElements = elements || [], { fireImmediately: true, name: "doLayout" }); - const handler = (e: Event) => this.handleDragging(e, (e as CustomEvent).detail); + const handler = (e: any) => this.handleDragging(e, (e as CustomEvent).detail); document.addEventListener("dashDragging", handler); } @@ -1159,7 +1160,7 @@ export class CollectionFreeFormView extends CollectionSubView this.handleDragging(e, (e as CustomEvent).detail); + const handler = (e: any) => this.handleDragging(e, (e as CustomEvent).detail); document.removeEventListener("dashDragging", handler); } diff --git a/src/client/views/collections/collectionGrid/CollectionGridView.tsx b/src/client/views/collections/collectionGrid/CollectionGridView.tsx index 188b88c41..b2e506dfa 100644 --- a/src/client/views/collections/collectionGrid/CollectionGridView.tsx +++ b/src/client/views/collections/collectionGrid/CollectionGridView.tsx @@ -31,7 +31,7 @@ export class CollectionGridView extends CollectionSubView(GridSchema) { @observable private _rowHeight: Opt; // temporary store of row height to make change undoable @observable private _scroll: number = 0; // required to make sure the decorations box container updates on scroll - @computed get onChildClickHandler() { return ScriptCast(this.Document.onChildClick); } + @computed get onChildClickHandler() { return () => ScriptCast(this.Document.onChildClick); } @computed get numCols() { return NumCast(this.props.Document.gridNumCols, 10); } @computed get rowHeight() { return this._rowHeight === undefined ? NumCast(this.props.Document.gridRowHeight, 100) : this._rowHeight; } diff --git a/src/client/views/collections/collectionMulticolumn/CollectionMulticolumnView.tsx b/src/client/views/collections/collectionMulticolumn/CollectionMulticolumnView.tsx index cd25c21b4..402e7563d 100644 --- a/src/client/views/collections/collectionMulticolumn/CollectionMulticolumnView.tsx +++ b/src/client/views/collections/collectionMulticolumn/CollectionMulticolumnView.tsx @@ -202,8 +202,8 @@ export class CollectionMulticolumnView extends CollectionSubView(MulticolumnDocu } - @computed get onChildClickHandler() { return ScriptCast(this.Document.onChildClick); } - @computed get onChildDoubleClickHandler() { return ScriptCast(this.Document.onChildDoubleClick); } + @computed get onChildClickHandler() { return () => ScriptCast(this.Document.onChildClick); } + @computed get onChildDoubleClickHandler() { return () => ScriptCast(this.Document.onChildDoubleClick); } addDocTab = (doc: Doc, where: string) => { diff --git a/src/client/views/collections/collectionMulticolumn/CollectionMultirowView.tsx b/src/client/views/collections/collectionMulticolumn/CollectionMultirowView.tsx index 51dcdcfe6..e4ef9b436 100644 --- a/src/client/views/collections/collectionMulticolumn/CollectionMultirowView.tsx +++ b/src/client/views/collections/collectionMulticolumn/CollectionMultirowView.tsx @@ -202,8 +202,8 @@ export class CollectionMultirowView extends CollectionSubView(MultirowDocument) } - @computed get onChildClickHandler() { return ScriptCast(this.Document.onChildClick); } - @computed get onChildDoubleClickHandler() { return ScriptCast(this.Document.onChildDoubleClick); } + @computed get onChildClickHandler() { return () => ScriptCast(this.Document.onChildClick); } + @computed get onChildDoubleClickHandler() { return () => ScriptCast(this.Document.onChildDoubleClick); } addDocTab = (doc: Doc, where: string) => { if (where === "inPlace" && this.layoutDoc.isInPlaceContainer) { diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx index 11be4c2e7..e338d5203 100644 --- a/src/client/views/nodes/DocumentView.tsx +++ b/src/client/views/nodes/DocumentView.tsx @@ -11,7 +11,7 @@ import { InkTool } from '../../../fields/InkField'; import { listSpec } from "../../../fields/Schema"; import { SchemaHeaderField } from '../../../fields/SchemaHeaderField'; import { ScriptField } from '../../../fields/ScriptField'; -import { BoolCast, Cast, NumCast, StrCast } from "../../../fields/Types"; +import { BoolCast, Cast, NumCast, StrCast, ScriptCast } from "../../../fields/Types"; import { TraceMobx } from '../../../fields/util'; import { GestureUtils } from '../../../pen-gestures/GestureUtils'; import { emptyFunction, OmitKeys, returnOne, returnTransparent, Utils, emptyPath } from "../../../Utils"; @@ -68,10 +68,10 @@ export interface DocumentViewProps { ignoreAutoHeight?: boolean; contextMenuItems?: () => { script: ScriptField, label: string }[]; rootSelected: (outsideReaction?: boolean) => boolean; // whether the root of a template has been selected - onClick?: ScriptField; - onDoubleClick?: ScriptField; - onPointerDown?: ScriptField; - onPointerUp?: ScriptField; + onClick?: () => ScriptField; + onDoubleClick?: () => ScriptField; + onPointerDown?: () => ScriptField; + onPointerUp?: () => ScriptField; treeViewDoc?: Doc; dropAction?: dropActionType; dragDivName?: string; @@ -127,10 +127,10 @@ export class DocumentView extends DocComponent(Docu @computed get freezeDimensions() { return this.props.FreezeDimensions; } @computed get nativeWidth() { return NumCast(this.layoutDoc._nativeWidth, this.props.NativeWidth() || (this.freezeDimensions ? this.layoutDoc[WidthSym]() : 0)); } @computed get nativeHeight() { return NumCast(this.layoutDoc._nativeHeight, this.props.NativeHeight() || (this.freezeDimensions ? this.layoutDoc[HeightSym]() : 0)); } - @computed get onClickHandler() { return this.props.onClick || Cast(this.Document.onClick, ScriptField, Cast(this.layoutDoc.onClick, ScriptField, null)); } - @computed get onDoubleClickHandler() { return this.props.onDoubleClick || Cast(this.layoutDoc.onDoubleClick, ScriptField, null) || this.Document.onDoubleClick; } - @computed get onPointerDownHandler() { return this.props.onPointerDown ? this.props.onPointerDown : this.Document.onPointerDown; } - @computed get onPointerUpHandler() { return this.props.onPointerUp ? this.props.onPointerUp : this.Document.onPointerUp; } + @computed get onClickHandler() { return this.props.onClick?.() ? this.props.onClick : (() => Cast(this.Document.onClick, ScriptField, Cast(this.layoutDoc.onClick, ScriptField, null))); } + @computed get onDoubleClickHandler() { return this.props.onDoubleClick?.() ? this.props.onDoubleClick : () => (Cast(this.layoutDoc.onDoubleClick, ScriptField, null) || this.Document.onDoubleClick); } + @computed get onPointerDownHandler() { return this.props.onPointerDown?.() ? this.props.onPointerDown : () => ScriptCast(this.Document.onPointerDown) } + @computed get onPointerUpHandler() { return this.props.onPointerUp ?? (() => ScriptCast(this.Document.onPointerUp)); } NativeWidth = () => this.nativeWidth; NativeHeight = () => this.nativeHeight; @@ -293,10 +293,10 @@ export class DocumentView extends DocComponent(Docu let stopPropagate = true; let preventDefault = true; !this.props.Document.isBackground && this.props.bringToFront(this.props.Document); - if (this._doubleTap && this.props.renderDepth && !this.onClickHandler?.script) { // disable double-click to show full screen for things that have an on click behavior since clicking them twice can be misinterpreted as a double click + if (this._doubleTap && this.props.renderDepth && !this.onClickHandler()?.script) { // disable double-click to show full screen for things that have an on click behavior since clicking them twice can be misinterpreted as a double click if (!(e.nativeEvent as any).formattedHandled) { - if (this.onDoubleClickHandler?.script && !StrCast(Doc.LayoutField(this.layoutDoc))?.includes("ScriptingBox")) { // bcz: hack? don't execute script if you're clicking on a scripting box itself - const func = () => this.onDoubleClickHandler.script.run({ + if (this.onDoubleClickHandler()?.script && !StrCast(Doc.LayoutField(this.layoutDoc))?.includes("ScriptingBox")) { // bcz: hack? don't execute script if you're clicking on a scripting box itself + const func = () => this.onDoubleClickHandler()?.script.run({ this: this.layoutDoc, self: this.rootDoc, thisContainer: this.props.ContainingCollectionDoc, shiftKey: e.shiftKey @@ -316,9 +316,9 @@ export class DocumentView extends DocComponent(Docu Doc.UnBrushDoc(this.props.Document); } } - } else if (this.onClickHandler?.script && !StrCast(Doc.LayoutField(this.layoutDoc))?.includes("ScriptingBox")) { // bcz: hack? don't execute script if you're clicking on a scripting box itself + } else if (this.onClickHandler()?.script && !StrCast(Doc.LayoutField(this.layoutDoc))?.includes("ScriptingBox")) { // bcz: hack? don't execute script if you're clicking on a scripting box itself //SelectionManager.DeselectAll(); - const func = () => this.onClickHandler.script.run({ + const func = () => this.onClickHandler()?.script.run({ this: this.layoutDoc, self: this.rootDoc, thisContainer: this.props.ContainingCollectionDoc, shiftKey: e.shiftKey @@ -553,8 +553,8 @@ export class DocumentView extends DocComponent(Docu onPointerUp = (e: PointerEvent): void => { this.cleanUpInteractions(); - if (this.onPointerUpHandler?.script && !InteractionUtils.IsType(e, InteractionUtils.PENTYPE)) { - this.onPointerUpHandler.script.run({ self: this.rootDoc, this: this.layoutDoc }, console.log); + if (this.onPointerUpHandler()?.script && !InteractionUtils.IsType(e, InteractionUtils.PENTYPE)) { + this.onPointerUpHandler()?.script.run({ self: this.rootDoc, this: this.layoutDoc }, console.log); document.removeEventListener("pointerup", this.onPointerUp); return; } diff --git a/src/fields/documentSchemas.ts b/src/fields/documentSchemas.ts index 61a37ef8a..9dda644f3 100644 --- a/src/fields/documentSchemas.ts +++ b/src/fields/documentSchemas.ts @@ -3,7 +3,6 @@ import { ScriptField } from "./ScriptField"; import { Doc } from "./Doc"; import { DateField } from "./DateField"; import { SchemaHeaderField } from "./SchemaHeaderField"; -import { Schema } from "prosemirror-model"; export const documentSchema = createSchema({ // content properties -- cgit v1.2.3-70-g09d2 From 06f03dc68f0371dda28ee65b97b7879c96f64462 Mon Sep 17 00:00:00 2001 From: Bob Zeleznik Date: Tue, 14 Jul 2020 14:34:31 -0400 Subject: from last --- .../views/collections/collectionFreeForm/CollectionFreeFormView.tsx | 1 - 1 file changed, 1 deletion(-) (limited to 'src/client/views/collections/collectionFreeForm') diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx index 1d23d92bf..f33b5371f 100644 --- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx +++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx @@ -46,7 +46,6 @@ import "./CollectionFreeFormView.scss"; import MarqueeOptionsMenu from "./MarqueeOptionsMenu"; import { MarqueeView } from "./MarqueeView"; import React = require("react"); -import { AnyAaaaRecord } from "dns"; library.add(faEye as any, faTable, faPaintBrush, faExpandArrowsAlt, faCompressArrowsAlt, faCompass, faUpload, faBraille, faChalkboard, faFileUpload); -- cgit v1.2.3-70-g09d2 From 866561aa20aff0f570d31edf64eae36cd2d35279 Mon Sep 17 00:00:00 2001 From: Bob Zeleznik Date: Tue, 14 Jul 2020 17:27:19 -0400 Subject: fixed onClickHandler stuff to use functions properly. fixed several linking to annotations/pushpins problems. --- src/client/documents/Documents.ts | 8 +- src/client/util/DocumentManager.ts | 4 +- src/client/util/LinkManager.ts | 11 ++- src/client/util/SettingsManager.tsx | 4 +- src/client/views/DocumentButtonBar.tsx | 2 +- src/client/views/MetadataEntryMenu.tsx | 96 ++++++---------------- src/client/views/collections/CollectionView.tsx | 7 +- .../collectionFreeForm/CollectionFreeFormView.tsx | 10 +-- .../collectionFreeForm/FormatShapePane.tsx | 2 +- .../collectionFreeForm/InkOptionsMenu.tsx | 2 +- .../collectionGrid/CollectionGridView.tsx | 2 +- .../CollectionMulticolumnView.tsx | 5 +- .../CollectionMultirowView.tsx | 4 +- src/client/views/linking/LinkMenuGroup.tsx | 4 +- src/client/views/linking/LinkMenuItem.tsx | 5 +- src/client/views/nodes/DocumentLinksButton.tsx | 3 - src/client/views/nodes/DocumentView.tsx | 17 ++-- src/client/views/nodes/FieldView.tsx | 2 +- .../views/nodes/formattedText/RichTextMenu.tsx | 2 +- src/fields/documentSchemas.ts | 3 + 20 files changed, 78 insertions(+), 115 deletions(-) (limited to 'src/client/views/collections/collectionFreeForm') diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts index 90cef31d9..1fd533b62 100644 --- a/src/client/documents/Documents.ts +++ b/src/client/documents/Documents.ts @@ -102,6 +102,8 @@ export interface DocumentOptions { childLayoutTemplate?: Doc; // template for collection to use to render its children (see PresBox or Buxton layout in tree view) childLayoutString?: string; // template string for collection to use to render its children hideFilterView?: boolean; // whether to hide the filter popout on collections + hideLinkButton?: boolean; // whether the blue link counter button should be hidden + hideAllLinks?: boolean; // whether all individual blue anchor dots should be hidden _columnsHideIfEmpty?: boolean; // whether stacking view column headings should be hidden isTemplateForField?: string; // the field key for which the containing document is a rendering template isTemplateDoc?: boolean; @@ -137,7 +139,7 @@ export interface DocumentOptions { lookupField?: ScriptField; // script that returns the value of a field. This script is passed the rootDoc, layoutDoc, field, and container of the document. see PresBox. "onDoubleClick-rawScript"?: string; // onDoubleClick script in raw text form "onChildDoubleClick-rawScript"?: string; // onChildDoubleClick script in raw text form - "onChildClick-rawScript"?: string // on ChildClick script in raw text form + "onChildClick-rawScript"?: string; // on ChildClick script in raw text form "onClick-rawScript"?: string; // onClick script in raw text form "onCheckedClick-rawScript"?: string; // onChecked script in raw text form "onCheckedClick-params"?: List; // parameter list for onChecked treeview functions @@ -779,7 +781,7 @@ export namespace Docs { export function FontIconDocument(options?: DocumentOptions) { - return InstanceFromProto(Prototypes.get(DocumentType.FONTICON), undefined, { ...(options || {}) }); + return InstanceFromProto(Prototypes.get(DocumentType.FONTICON), undefined, { hideLinkButton: true, ...(options || {}) }); } export function PresElementBoxDocument(options?: DocumentOptions) { @@ -912,6 +914,8 @@ export namespace DocUtils { if (target.doc === Doc.UserDoc()) return undefined; const linkDoc = Docs.Create.LinkDocument(source, target, { linkRelationship, layoutKey: "layout_linkView", description }, id); + linkDoc.linkDisplay = true; + linkDoc.hideAnhors = true; linkDoc.layout_linkView = Cast(Cast(Doc.UserDoc()["template-button-link"], Doc, null).dragFactory, Doc, null); Doc.GetProto(linkDoc).title = ComputedField.MakeFunction('self.anchor1?.title +" (" + (self.linkRelationship||"to") +") " + self.anchor2?.title'); diff --git a/src/client/util/DocumentManager.ts b/src/client/util/DocumentManager.ts index 1fa5faeb3..b66e7fdc4 100644 --- a/src/client/util/DocumentManager.ts +++ b/src/client/util/DocumentManager.ts @@ -146,7 +146,7 @@ export class DocumentManager { }; const docView = getFirstDocView(targetDoc, originatingDoc); let annotatedDoc = await Cast(targetDoc.annotationOn, Doc); - if (annotatedDoc && !linkDoc?.isPushpin) { + if (annotatedDoc && !targetDoc?.isPushpin) { const first = getFirstDocView(annotatedDoc); if (first) { annotatedDoc = first.props.Document; @@ -156,7 +156,7 @@ export class DocumentManager { } } if (docView) { // we have a docView already and aren't forced to create a new one ... just focus on the document. TODO move into view if necessary otherwise just highlight? - if (linkDoc?.isPushpin) docView.props.Document.hidden = !docView.props.Document.hidden; + if (originatingDoc?.isPushpin) docView.props.Document.hidden = !docView.props.Document.hidden; else { docView.props.Document.hidden && (docView.props.Document.hidden = undefined); docView.props.focus(docView.props.Document, willZoom, undefined, focusAndFinish); diff --git a/src/client/util/LinkManager.ts b/src/client/util/LinkManager.ts index 50f3fc1d6..974744344 100644 --- a/src/client/util/LinkManager.ts +++ b/src/client/util/LinkManager.ts @@ -63,12 +63,17 @@ export class LinkManager { } // finds all links that contain the given anchor - public getAllRelatedLinks(anchor: Doc): Doc[] { + public getAllDirectLinks(anchor: Doc): Doc[] { const related = LinkManager.Instance.getAllLinks().filter(link => { const protomatch1 = Doc.AreProtosEqual(anchor, Cast(link.anchor1, Doc, null)); const protomatch2 = Doc.AreProtosEqual(anchor, Cast(link.anchor2, Doc, null)); return protomatch1 || protomatch2 || Doc.AreProtosEqual(link, anchor); }); + return related; + } + // finds all links that contain the given anchor + public getAllRelatedLinks(anchor: Doc): Doc[] { + const related = LinkManager.Instance.getAllDirectLinks(anchor); DocListCast(anchor[Doc.LayoutFieldKey(anchor) + "-annotations"]).map(anno => { related.push(...LinkManager.Instance.getAllRelatedLinks(anno)); }); @@ -208,4 +213,6 @@ export class LinkManager { } Scripting.addGlobal(function links(doc: any) { return new List(LinkManager.Instance.getAllRelatedLinks(doc)); }, - "creates a link to inputted document", "(doc: any)"); \ No newline at end of file + "returns all the links to the document or its annotations", "(doc: any)"); +Scripting.addGlobal(function directLinks(doc: any) { return new List(LinkManager.Instance.getAllDirectLinks(doc)); }, + "returns all the links directly to the document", "(doc: any)"); \ No newline at end of file diff --git a/src/client/util/SettingsManager.tsx b/src/client/util/SettingsManager.tsx index f7ca3942b..981ee698d 100644 --- a/src/client/util/SettingsManager.tsx +++ b/src/client/util/SettingsManager.tsx @@ -87,11 +87,11 @@ export default class SettingsManager extends React.Component<{}> { } @action googleAuthorize = (event: any) => { - GoogleAuthenticationManager.Instance.fetchOrGenerateAccessToken(true) + GoogleAuthenticationManager.Instance.fetchOrGenerateAccessToken(true); } @action hypothesisAuthorize = (event: any) => { - HypothesisAuthenticationManager.Instance.fetchAccessToken(true) + HypothesisAuthenticationManager.Instance.fetchAccessToken(true); } private get settingsInterface() { diff --git a/src/client/views/DocumentButtonBar.tsx b/src/client/views/DocumentButtonBar.tsx index c188618f4..927c192cd 100644 --- a/src/client/views/DocumentButtonBar.tsx +++ b/src/client/views/DocumentButtonBar.tsx @@ -208,7 +208,7 @@ export class DocumentButtonBar extends React.Component<{ views: () => (DocumentV const view0 = this.view0; 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? */}> + content={ 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/MetadataEntryMenu.tsx b/src/client/views/MetadataEntryMenu.tsx index b0752ffb2..ca8a6e1d7 100644 --- a/src/client/views/MetadataEntryMenu.tsx +++ b/src/client/views/MetadataEntryMenu.tsx @@ -3,14 +3,14 @@ import "./MetadataEntryMenu.scss"; import { observer } from 'mobx-react'; import { observable, action, runInAction, trace, computed, IReactionDisposer, reaction } from 'mobx'; import { KeyValueBox } from './nodes/KeyValueBox'; -import { Doc, Field, DocListCastAsync } from '../../fields/Doc'; +import { Doc, Field, DocListCastAsync, DocListCast } from '../../fields/Doc'; import * as Autosuggest from 'react-autosuggest'; -import { undoBatch } from '../util/UndoManager'; +import { undoBatch, UndoManager } from '../util/UndoManager'; import { emptyFunction, emptyPath } from '../../Utils'; export type DocLike = Doc | Doc[] | Promise | Promise; export interface MetadataEntryProps { - docs: DocLike | (() => DocLike); + docs: Doc[]; onError?: () => boolean; suggestWithFunction?: boolean; } @@ -39,26 +39,13 @@ export class MetadataEntryMenu extends React.Component{ let onProto: boolean = false; let value: string | undefined = undefined; let docs = this.props.docs; - if (typeof docs === "function") { - if (this.props.suggestWithFunction) { - docs = docs(); - } else { - return; - } - } - docs = await docs; - if (docs instanceof Doc) { - await docs[this._currentKey]; - value = Field.toKeyValueString(docs, this._currentKey); - } else { - for (const doc of docs) { - const v = await doc[this._currentKey]; - onProto = onProto || !Object.keys(doc).includes(this._currentKey); - if (field === null) { - field = v; - } else if (v !== field) { - value = "multiple values"; - } + for (const doc of docs) { + const v = await doc[this._currentKey]; + onProto = onProto || !Object.keys(doc).includes(this._currentKey); + if (field === null) { + field = v; + } else if (v !== field) { + value = "multiple values"; } } if (value === undefined) { @@ -86,27 +73,16 @@ export class MetadataEntryMenu extends React.Component{ const script = KeyValueBox.CompileKVPScript(this._currentValue); if (!script) return; - let doc = this.props.docs; - if (typeof doc === "function") { - doc = doc(); - } - doc = await doc; - - let success: boolean; - if (doc instanceof Doc) { - success = KeyValueBox.ApplyKVPScript(doc, this._currentKey, script); - } else { - let childSuccess = true; - if (this._addChildren) { - for (const document of doc) { - const collectionChildren = await DocListCastAsync(document.data); - if (collectionChildren) { - childSuccess = collectionChildren.every(c => KeyValueBox.ApplyKVPScript(c, this._currentKey, script)); - } + let childSuccess = true; + if (this._addChildren) { + for (const document of this.props.docs) { + const collectionChildren = DocListCast(document.data); + if (collectionChildren) { + childSuccess = collectionChildren.every(c => KeyValueBox.ApplyKVPScript(c, this._currentKey, script)); } } - success = doc.every(d => KeyValueBox.ApplyKVPScript(d, this._currentKey, script)) && childSuccess; } + const success = this.props.docs.every(d => KeyValueBox.ApplyKVPScript(d, this._currentKey, script)) && childSuccess; if (!success) { if (this.props.onError) { if (this.props.onError()) { @@ -132,24 +108,12 @@ export class MetadataEntryMenu extends React.Component{ } } - getKeySuggestions = async (value: string): Promise => { + getKeySuggestions = (value: string) => { value = value.toLowerCase(); let docs = this.props.docs; - if (typeof docs === "function") { - if (this.props.suggestWithFunction) { - docs = docs(); - } else { - return []; - } - } - docs = await docs; - if (docs instanceof Doc) { - return Object.keys(docs).filter(key => key.toLowerCase().startsWith(value)); - } else { - const keys = new Set(); - docs.forEach(doc => Doc.allKeys(doc).forEach(key => keys.add(key))); - return Array.from(keys).filter(key => key.toLowerCase().startsWith(value)); - } + const keys = new Set(); + docs.forEach(doc => Doc.allKeys(doc).forEach(key => keys.add(key))); + return Array.from(keys).filter(key => key.toLowerCase().startsWith(value)); } getSuggestionValue = (suggestion: string) => suggestion; @@ -157,9 +121,8 @@ export class MetadataEntryMenu extends React.Component{ return (null); } componentDidMount() { - this._suggestionDispser = reaction(() => this._currentKey, - () => this.getKeySuggestions(this._currentKey).then(action((s: string[]) => this._allSuggestions = s)), + () => this._allSuggestions = this.getKeySuggestions(this._currentKey), { fireImmediately: true }); } componentWillUnmount() { @@ -171,19 +134,8 @@ export class MetadataEntryMenu extends React.Component{ } private get considerChildOptions() { - let docSource = this.props.docs; - if (typeof docSource === "function") { - docSource = docSource(); - } - docSource = docSource as Doc[] | Doc; - if (docSource instanceof Doc) { - if (docSource._viewType === undefined) { - return (null); - } - } else if (Array.isArray(docSource)) { - if (!docSource.every(doc => doc._viewType !== undefined)) { - return null; - } + if (!this.props.docs.every(doc => doc._viewType !== undefined)) { + return null; } return (
diff --git a/src/client/views/collections/CollectionView.tsx b/src/client/views/collections/CollectionView.tsx index 5165a8f11..6ab4645ea 100644 --- a/src/client/views/collections/CollectionView.tsx +++ b/src/client/views/collections/CollectionView.tsx @@ -140,17 +140,18 @@ export class CollectionView extends Touchable { const context = Cast(doc.context, Doc, null); - if (context && (context.type === DocumentType.VID || context.type === DocumentType.WEB || context.type === DocumentType.PDF || context.type === DocumentType.IMG) && - !DocListCast(doc.links).some(d => d.isPushpin)) { + if (context && (context.type === DocumentType.VID || context.type === DocumentType.WEB || context.type === DocumentType.PDF || context.type === DocumentType.IMG)) { const pushpin = Docs.Create.FontIconDocument({ icon: "map-pin", x: Cast(doc.x, "number", null), y: Cast(doc.y, "number", null), _backgroundColor: "#0000003d", color: "#ACCEF7", _width: 15, _height: 15, _xPadding: 0, isLinkButton: true, displayTimecode: Cast(doc.displayTimecode, "number", null) }); + pushpin.isPushpin = true; + Doc.GetProto(pushpin).annotationOn = doc.annotationOn; + Doc.SetInPlace(doc, "annotationOn", undefined, true); Doc.AddDocToList(context, Doc.LayoutFieldKey(context) + "-annotations", pushpin); const pushpinLink = DocUtils.MakeLink({ doc: pushpin }, { doc: doc }, "pushpin", ""); const first = DocListCast(pushpin.links).find(d => d instanceof Doc); first && (first.hidden = true); - pushpinLink && (Doc.GetProto(pushpinLink).isPushpin = true); doc.displayTimecode = undefined; } doc.context = this.props.Document; diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx index f33b5371f..994f4ce6e 100644 --- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx +++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx @@ -939,9 +939,9 @@ export class CollectionFreeFormView extends CollectionSubView (this.props.childClickScript || ScriptCast(this.Document.onChildClick)); } - @computed get onChildDoubleClickHandler() { return () => (this.props.childDoubleClickScript || ScriptCast(this.Document.onChildDoubleClick)); } @computed get backgroundActive() { return this.layoutDoc.isBackground && (this.props.ContainingCollectionView?.active() || this.props.active()); } + onChildClickHandler = () => this.props.childClickScript || ScriptCast(this.Document.onChildClick); + onChildDoubleClickHandler = () => this.props.childDoubleClickScript || ScriptCast(this.Document.onChildDoubleClick); backgroundHalo = () => BoolCast(this.Document.useClusters); parentActive = (outsideReaction: boolean) => this.props.active(outsideReaction) || this.backgroundActive ? true : false; getChildDocumentViewProps(childLayout: Doc, childData?: Doc): DocumentViewProps { @@ -1186,8 +1186,8 @@ export class CollectionFreeFormView extends CollectionSubView - (p === undefined || (p && p === i.rootDoc[key])) && i.rootDoc[key] !== "0" ? Field.toString(i.rootDoc[key] as Field) : "", undefined as Opt) + (p === undefined || (p && p === i.rootDoc[key])) && i.rootDoc[key] !== "0" ? Field.toString(i.rootDoc[key] as Field) : "", undefined as Opt); } @computed get selectedInk() { diff --git a/src/client/views/collections/collectionFreeForm/InkOptionsMenu.tsx b/src/client/views/collections/collectionFreeForm/InkOptionsMenu.tsx index 15707ad9e..5d115df69 100644 --- a/src/client/views/collections/collectionFreeForm/InkOptionsMenu.tsx +++ b/src/client/views/collections/collectionFreeForm/InkOptionsMenu.tsx @@ -128,7 +128,7 @@ export default class InkOptionsMenu extends AntimodeMenu { // doc.strokeBezier === 300 ? doc.strokeBezier = 0 : doc.strokeBezier = 300; break; case "dash": - doc.strokeDash = Number(value); + doc.strokeDash = value; default: break; } diff --git a/src/client/views/collections/collectionGrid/CollectionGridView.tsx b/src/client/views/collections/collectionGrid/CollectionGridView.tsx index b2e506dfa..73d0ae374 100644 --- a/src/client/views/collections/collectionGrid/CollectionGridView.tsx +++ b/src/client/views/collections/collectionGrid/CollectionGridView.tsx @@ -31,7 +31,7 @@ export class CollectionGridView extends CollectionSubView(GridSchema) { @observable private _rowHeight: Opt; // temporary store of row height to make change undoable @observable private _scroll: number = 0; // required to make sure the decorations box container updates on scroll - @computed get onChildClickHandler() { return () => ScriptCast(this.Document.onChildClick); } + onChildClickHandler = () => ScriptCast(this.Document.onChildClick); @computed get numCols() { return NumCast(this.props.Document.gridNumCols, 10); } @computed get rowHeight() { return this._rowHeight === undefined ? NumCast(this.props.Document.gridRowHeight, 100) : this._rowHeight; } diff --git a/src/client/views/collections/collectionMulticolumn/CollectionMulticolumnView.tsx b/src/client/views/collections/collectionMulticolumn/CollectionMulticolumnView.tsx index 402e7563d..21d283547 100644 --- a/src/client/views/collections/collectionMulticolumn/CollectionMulticolumnView.tsx +++ b/src/client/views/collections/collectionMulticolumn/CollectionMulticolumnView.tsx @@ -202,9 +202,8 @@ export class CollectionMulticolumnView extends CollectionSubView(MulticolumnDocu } - @computed get onChildClickHandler() { return () => ScriptCast(this.Document.onChildClick); } - @computed get onChildDoubleClickHandler() { return () => ScriptCast(this.Document.onChildDoubleClick); } - + onChildClickHandler = () => ScriptCast(this.Document.onChildClick); + onChildDoubleClickHandler = () => ScriptCast(this.Document.onChildDoubleClick); addDocTab = (doc: Doc, where: string) => { if (where === "inPlace" && this.layoutDoc.isInPlaceContainer) { diff --git a/src/client/views/collections/collectionMulticolumn/CollectionMultirowView.tsx b/src/client/views/collections/collectionMulticolumn/CollectionMultirowView.tsx index e4ef9b436..d02088a6c 100644 --- a/src/client/views/collections/collectionMulticolumn/CollectionMultirowView.tsx +++ b/src/client/views/collections/collectionMulticolumn/CollectionMultirowView.tsx @@ -202,8 +202,8 @@ export class CollectionMultirowView extends CollectionSubView(MultirowDocument) } - @computed get onChildClickHandler() { return () => ScriptCast(this.Document.onChildClick); } - @computed get onChildDoubleClickHandler() { return () => ScriptCast(this.Document.onChildDoubleClick); } + onChildClickHandler = () => ScriptCast(this.Document.onChildClick); + onChildDoubleClickHandler = () => ScriptCast(this.Document.onChildDoubleClick); addDocTab = (doc: Doc, where: string) => { if (where === "inPlace" && this.layoutDoc.isInPlaceContainer) { diff --git a/src/client/views/linking/LinkMenuGroup.tsx b/src/client/views/linking/LinkMenuGroup.tsx index 2f6b75437..2ae87ac13 100644 --- a/src/client/views/linking/LinkMenuGroup.tsx +++ b/src/client/views/linking/LinkMenuGroup.tsx @@ -11,6 +11,7 @@ import { DocumentView } from "../nodes/DocumentView"; import './LinkMenu.scss'; import { LinkMenuItem, StartLinkTargetsDrag } from "./LinkMenuItem"; import React = require("react"); +import { Cast } from "../../../fields/Types"; interface LinkMenuGroupProps { sourceDoc: Doc; @@ -66,7 +67,8 @@ export class LinkMenuGroup extends React.Component { render() { const groupItems = this.props.group.map(linkDoc => { - const destination = LinkManager.Instance.getOppositeAnchor(linkDoc, this.props.sourceDoc); + const destination = LinkManager.Instance.getOppositeAnchor(linkDoc, this.props.sourceDoc) || + LinkManager.Instance.getOppositeAnchor(linkDoc, Cast(linkDoc.anchor2, Doc, null).annotationOn === this.props.sourceDoc ? Cast(linkDoc.anchor2, Doc, null) : Cast(linkDoc.anchor1, Doc, null)); if (destination && this.props.sourceDoc) { return { const eyeIcon = this.props.linkDoc.hidden ? "eye-slash" : "eye"; - let destinationIcon: string = "";; + let destinationIcon: FontAwesomeIconProps["icon"] = "question"; switch (this.props.destinationDoc.type) { case DocumentType.IMG: destinationIcon = "image"; break; case DocumentType.COMPARISON: destinationIcon = "columns"; break; @@ -205,7 +205,6 @@ export class LinkMenuItem extends React.Component { case DocumentType.SCRIPTING: destinationIcon = "terminal"; break; case DocumentType.IMPORT: destinationIcon = "cloud-upload-alt"; break; case DocumentType.DOCHOLDER: destinationIcon = "expand"; break; - default: "question"; } const title = StrCast(this.props.destinationDoc.title).length > 18 ? diff --git a/src/client/views/nodes/DocumentLinksButton.tsx b/src/client/views/nodes/DocumentLinksButton.tsx index 83710cfbf..823e25471 100644 --- a/src/client/views/nodes/DocumentLinksButton.tsx +++ b/src/client/views/nodes/DocumentLinksButton.tsx @@ -101,8 +101,6 @@ export class DocumentLinksButton extends React.Component { if (linkDoc) { @@ -137,7 +135,6 @@ export class DocumentLinksButton extends React.Component { if (linkDoc) { diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx index 7d9c4da87..a6771443a 100644 --- a/src/client/views/nodes/DocumentView.tsx +++ b/src/client/views/nodes/DocumentView.tsx @@ -128,9 +128,9 @@ export class DocumentView extends DocComponent(Docu @computed get nativeWidth() { return NumCast(this.layoutDoc._nativeWidth, this.props.NativeWidth() || (this.freezeDimensions ? this.layoutDoc[WidthSym]() : 0)); } @computed get nativeHeight() { return NumCast(this.layoutDoc._nativeHeight, this.props.NativeHeight() || (this.freezeDimensions ? this.layoutDoc[HeightSym]() : 0)); } @computed get onClickHandler() { return this.props.onClick?.() ?? Cast(this.Document.onClick, ScriptField, Cast(this.layoutDoc.onClick, ScriptField, null)); } - @computed get onDoubleClickHandler() { return this.props.onDoubleClick?.() || (Cast(this.layoutDoc.onDoubleClick, ScriptField, null) || this.Document.onDoubleClick); } - @computed get onPointerDownHandler() { return this.props.onPointerDown?.() || ScriptCast(this.Document.onPointerDown) } - @computed get onPointerUpHandler() { return this.props.onPointerUp?.() || ScriptCast(this.Document.onPointerUp); } + @computed get onDoubleClickHandler() { return this.props.onDoubleClick?.() ?? (Cast(this.layoutDoc.onDoubleClick, ScriptField, null) ?? this.Document.onDoubleClick); } + @computed get onPointerDownHandler() { return this.props.onPointerDown?.() ?? ScriptCast(this.Document.onPointerDown); } + @computed get onPointerUpHandler() { return this.props.onPointerUp?.() ?? ScriptCast(this.Document.onPointerUp); } NativeWidth = () => this.nativeWidth; NativeHeight = () => this.nativeHeight; onClickFunc = () => this.onClickHandler; @@ -298,7 +298,7 @@ export class DocumentView extends DocComponent(Docu if (this._doubleTap && this.props.renderDepth && !this.onClickHandler?.script) { // disable double-click to show full screen for things that have an on click behavior since clicking them twice can be misinterpreted as a double click if (!(e.nativeEvent as any).formattedHandled) { if (this.onDoubleClickHandler?.script && !StrCast(Doc.LayoutField(this.layoutDoc))?.includes("ScriptingBox")) { // bcz: hack? don't execute script if you're clicking on a scripting box itself - const func = () => this.onDoubleClickHandler?.script.run({ + const func = () => this.onDoubleClickHandler.script.run({ this: this.layoutDoc, self: this.rootDoc, thisContainer: this.props.ContainingCollectionDoc, shiftKey: e.shiftKey @@ -320,7 +320,7 @@ export class DocumentView extends DocComponent(Docu } } else if (this.onClickHandler?.script && !StrCast(Doc.LayoutField(this.layoutDoc))?.includes("ScriptingBox")) { // bcz: hack? don't execute script if you're clicking on a scripting box itself //SelectionManager.DeselectAll(); - const func = () => this.onClickHandler?.script.run({ + const func = () => this.onClickHandler.script.run({ this: this.layoutDoc, self: this.rootDoc, thisContainer: this.props.ContainingCollectionDoc, shiftKey: e.shiftKey @@ -556,7 +556,7 @@ export class DocumentView extends DocComponent(Docu this.cleanUpInteractions(); if (this.onPointerUpHandler?.script && !InteractionUtils.IsType(e, InteractionUtils.PENTYPE)) { - this.onPointerUpHandler?.script.run({ self: this.rootDoc, this: this.layoutDoc }, console.log); + this.onPointerUpHandler.script.run({ self: this.rootDoc, this: this.layoutDoc }, console.log); document.removeEventListener("pointerup", this.onPointerUp); return; } @@ -644,7 +644,6 @@ export class DocumentView extends DocComponent(Docu const makeLink = action((linkDoc: Doc) => { LinkManager.currentLink = linkDoc; linkDoc.hidden = true; - linkDoc.linkDisplay = true; LinkCreatedBox.popupX = de.x; LinkCreatedBox.popupY = de.y - 33; @@ -1076,7 +1075,7 @@ export class DocumentView extends DocComponent(Docu layoutKey={this.finalLayoutKey} /> {this.layoutDoc.hideAllLinks ? (null) : this.allAnchors} {/* {this.allAnchors} */} - {this.props.forcedBackgroundColor?.(this.Document) === "transparent" || this.props.dontRegisterView ? (null) : } + {this.props.forcedBackgroundColor?.(this.Document) === "transparent" || this.layoutDoc.hideLinkButton || this.props.dontRegisterView ? (null) : }
); } @@ -1105,7 +1104,7 @@ export class DocumentView extends DocComponent(Docu return (this.props.treeViewDoc && this.props.LayoutTemplateString) || // render nothing for: tree view anchor dots this.layoutDoc.presBox || // presentationbox nodes this.props.dontRegisterView ? (null) : // view that are not registered - DocUtils.FilterDocs(DocListCast(this.Document.links), this.props.docFilters(), []).filter(d => !d.hidden && this.isNonTemporalLink).map((d, i) => + DocUtils.FilterDocs(LinkManager.Instance.getAllDirectLinks(this.Document), this.props.docFilters(), []).filter(d => !d.hidden && this.isNonTemporalLink).map((d, i) => ScriptField; dropAction: dropActionType; backgroundHalo?: () => boolean; docFilters: () => string[]; diff --git a/src/client/views/nodes/formattedText/RichTextMenu.tsx b/src/client/views/nodes/formattedText/RichTextMenu.tsx index 8da1f99b5..c8798d757 100644 --- a/src/client/views/nodes/formattedText/RichTextMenu.tsx +++ b/src/client/views/nodes/formattedText/RichTextMenu.tsx @@ -431,7 +431,7 @@ export default class RichTextMenu extends AntimodeMenu { const nextIsOL = this.view.state.selection.$from.nodeAfter?.type === schema.nodes.ordered_list; let inList: any = undefined; let fromList = -1; - let path: any = Array.from((this.view.state.selection.$from as any).path); + const path: any = Array.from((this.view.state.selection.$from as any).path); for (let i = 0; i < path.length; i++) { if (path[i]?.type === schema.nodes.ordered_list) { inList = path[i]; diff --git a/src/fields/documentSchemas.ts b/src/fields/documentSchemas.ts index 9dda644f3..ddffb56c3 100644 --- a/src/fields/documentSchemas.ts +++ b/src/fields/documentSchemas.ts @@ -65,6 +65,7 @@ export const documentSchema = createSchema({ color: "string", // foreground color of document fitToBox: "boolean", // whether freeform view contents should be zoomed/panned to fill the area of the document view fontSize: "string", + hidden: "boolean", // whether a document should not be displayed isInkMask: "boolean", // is the document a mask (ie, sits on top of other documents, has an unbounded width/height that is dark, and content uses 'hard-light' mix-blend-mode to let other documents pop through) layout: "string", // this is the native layout string for the document. templates can be added using other fields and setting layoutKey below layoutKey: "string", // holds the field key for the field that actually holds the current lyoat @@ -87,6 +88,8 @@ export const documentSchema = createSchema({ onPointerUp: ScriptField, // script to run when document is clicked (can be overriden by an onClick prop) onDragStart: ScriptField, // script to run when document is dragged (without being selected). the script should return the Doc to be dropped. followLinkLocation: "string",// flag for where to place content when following a click interaction (e.g., onRight, inPlace, inTab, ) + hideLinkButton: "boolean", // whether the blue link counter button should be hidden + hideAllLinks: "boolean", // whether all individual blue anchor dots should be hidden isInPlaceContainer: "boolean",// whether the marked object will display addDocTab() calls that target "inPlace" destinations isLinkButton: "boolean", // whether document functions as a link follow button to follow the first link on the document when clicked isBackground: "boolean", // whether document is a background element and ignores input events (can only select with marquee) -- cgit v1.2.3-70-g09d2 From 07d71ea914c5bae3136b6c911c38b3373afcd5a7 Mon Sep 17 00:00:00 2001 From: Bob Zeleznik Date: Tue, 14 Jul 2020 19:32:56 -0400 Subject: cleaned up InkOptionsMenu --- src/client/views/GestureOverlay.tsx | 5 +- src/client/views/MainView.tsx | 7 +- .../collectionFreeForm/InkOptionsMenu.tsx | 381 ++++----------------- 3 files changed, 77 insertions(+), 316 deletions(-) (limited to 'src/client/views/collections/collectionFreeForm') diff --git a/src/client/views/GestureOverlay.tsx b/src/client/views/GestureOverlay.tsx index a48b7b673..2f34cbc05 100644 --- a/src/client/views/GestureOverlay.tsx +++ b/src/client/views/GestureOverlay.tsx @@ -608,8 +608,7 @@ export default class GestureOverlay extends Touchable { this.makePolygon(this.InkShape, false); this.dispatchGesture(GestureUtils.Gestures.Stroke); this._points = []; - if (InkOptionsMenu.Instance._double === "") { - + if (!InkOptionsMenu.Instance._keepMode) { this.InkShape = ""; } } @@ -640,7 +639,7 @@ export default class GestureOverlay extends Touchable { this._points = []; } //get out of ink mode after each stroke= - if (InkOptionsMenu.Instance._double === "") { + if (!InkOptionsMenu.Instance._keepMode) { Doc.SetSelectedTool(InkTool.None); InkOptionsMenu.Instance._selected = InkOptionsMenu.Instance._shapesNum; SetActiveArrowStart("none"); diff --git a/src/client/views/MainView.tsx b/src/client/views/MainView.tsx index 2ed528836..41efe246c 100644 --- a/src/client/views/MainView.tsx +++ b/src/client/views/MainView.tsx @@ -1,4 +1,5 @@ import { library } from '@fortawesome/fontawesome-svg-core'; + import { faTasks, faEdit, faTrashAlt, faPalette, faAngleRight, faBell, faTrash, faCamera, faExpand, faCaretDown, faCaretLeft, faCaretRight, faCaretSquareDown, faCaretSquareRight, faArrowsAltH, faPlus, faMinus, faTerminal, faToggleOn, faFile as fileSolid, faExternalLinkAlt, faLocationArrow, faSearch, faFileDownload, faStop, faCalculator, faWindowMaximize, faAddressCard, @@ -6,7 +7,8 @@ import { faCommentAlt, faCompressArrowsAlt, faCut, faEllipsisV, faEraser, faExclamation, faFileAlt, faFileAudio, faFilePdf, faFilm, faFilter, faFont, faGlobeAsia, faHighlighter, faLongArrowAltRight, faMicrophone, faMousePointer, faMusic, faObjectGroup, faPause, faPen, faPenNib, faPhone, faPlay, faPortrait, faRedoAlt, faStamp, faStickyNote, faTimesCircle, faThumbtack, faTree, faTv, faUndoAlt, faVideo, faAsterisk, faBrain, faImage, faPaintBrush, faTimes, faEye, faArrowsAlt, faQuoteLeft, faSortAmountDown, faAlignLeft, faAlignCenter, faAlignRight, - faHeading, faRulerCombined, faFillDrip, faUnlink + faHeading, faRulerCombined, faFillDrip, faLink, faUnlink, faBold, faItalic, faChevronLeft, faUnderline, faStrikethrough, faSuperscript, faSubscript, faIndent, faEyeDropper, + faPaintRoller, faBars, faBrush, faShapes, faEllipsisH } from '@fortawesome/free-solid-svg-icons'; import { ANTIMODEMENU_HEIGHT } from './globalCssVariables.scss'; import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; @@ -147,7 +149,8 @@ export class MainView extends React.Component { faCommentAlt, faCompressArrowsAlt, faCut, faEllipsisV, faEraser, faExclamation, faFileAlt, faFileAudio, faFilePdf, faFilm, faFilter, faFont, faGlobeAsia, faHighlighter, faLongArrowAltRight, faMicrophone, faMousePointer, faMusic, faObjectGroup, faPause, faPen, faPenNib, faPhone, faPlay, faPortrait, faRedoAlt, faStamp, faStickyNote, faTrashAlt, faAngleRight, faBell, faThumbtack, faTree, faTv, faUndoAlt, faVideo, faAsterisk, faBrain, faImage, faPaintBrush, faTimes, faEye, faArrowsAlt, faQuoteLeft, faSortAmountDown, faAlignLeft, faAlignCenter, faAlignRight, - faHeading, faRulerCombined, faFillDrip, faUnlink); + faHeading, faRulerCombined, faFillDrip, faLink, faUnlink, faBold, faItalic, faChevronLeft, faUnderline, faStrikethrough, faSuperscript, faSubscript, faIndent, faEyeDropper, + faPaintRoller, faBars, faBrush, faShapes, faEllipsisH); this.initEventListeners(); this.initAuthenticationRouters(); } diff --git a/src/client/views/collections/collectionFreeForm/InkOptionsMenu.tsx b/src/client/views/collections/collectionFreeForm/InkOptionsMenu.tsx index 15707ad9e..23e1c194a 100644 --- a/src/client/views/collections/collectionFreeForm/InkOptionsMenu.tsx +++ b/src/client/views/collections/collectionFreeForm/InkOptionsMenu.tsx @@ -3,7 +3,7 @@ import AntimodeMenu from "../../AntimodeMenu"; import { observer } from "mobx-react"; import { observable, action, computed } from "mobx"; import "./InkOptionsMenu.scss"; -import { ActiveInkColor, ActiveInkBezierApprox, ActiveFillColor, ActiveArrowStart, ActiveArrowEnd, SetActiveInkWidth, SetActiveInkColor, SetActiveBezierApprox, SetActiveFillColor, SetActiveArrowStart, SetActiveArrowEnd, ActiveDash, SetActiveDash } from "../../InkingStroke"; +import { ActiveInkColor, ActiveFillColor, SetActiveInkWidth, SetActiveInkColor, SetActiveBezierApprox, SetActiveFillColor, SetActiveArrowStart, SetActiveArrowEnd, ActiveDash, SetActiveDash } from "../../InkingStroke"; import { Scripting } from "../../../util/Scripting"; import { InkTool } from "../../../../fields/InkField"; import { ColorState } from "react-color"; @@ -14,30 +14,16 @@ import { SelectionManager } from "../../../util/SelectionManager"; import { DocumentView } from "../../../views/nodes/DocumentView"; import { Document } from "../../../../fields/documentSchemas"; import { DocumentType } from "../../../documents/DocumentTypes"; -import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; -import { IconProp, library } from '@fortawesome/fontawesome-svg-core'; -import { faBold, faItalic, faChevronLeft, faUnderline, faStrikethrough, faSubscript, faSuperscript, faIndent, faEyeDropper, faCaretDown, faPalette, faArrowsAlt, faHighlighter, faLink, faPaintRoller, faSleigh, faBars, faFillDrip, faBrush, faPenNib, faShapes, faArrowLeft, faEllipsisH, faBezierCurve, } from "@fortawesome/free-solid-svg-icons"; -import { Cast, StrCast, BoolCast } from "../../../../fields/Types"; +import { FontAwesomeIcon, FontAwesomeIconProps } from "@fortawesome/react-fontawesome"; +import { BoolCast } from "../../../../fields/Types"; import FormatShapePane from "./FormatShapePane"; -library.add(faBold, faItalic, faChevronLeft, faUnderline, faStrikethrough, faSuperscript, faSubscript, faIndent, faEyeDropper, faCaretDown, faPalette, faArrowsAlt, faHighlighter, faLink, faPaintRoller, faBars, faFillDrip, faBrush, faPenNib, faShapes, faArrowLeft, faEllipsisH, faBezierCurve); - - - @observer export default class InkOptionsMenu extends AntimodeMenu { static Instance: InkOptionsMenu; private _palette = ["#D0021B", "#F5A623", "#F8E71C", "#8B572A", "#7ED321", "#417505", "#9013FE", "#4A90E2", "#50E3C2", "#B8E986", "#000000", "#4A4A4A", "#9B9B9B", "#FFFFFF", ""]; private _width = ["1", "5", "10", "100"]; - // private _buttons = ["circle", "triangle", "rectangle", "arrow", "line"]; - // private _icons = ["O", "∆", "ロ", "➜", "-"]; - // private _buttons = ["circle", "triangle", "rectangle", "line", "noRec", "",]; - // private _icons = ["O", "∆", "ロ", "⎯⎯⎯", "✖︎", " "]; - //arrowStart and arrowEnd must match and defs must exist in Inking Stroke - // private _arrowStart = ["arrowStart", "arrowStart", "dot", "dot", "none"]; - // private _arrowEnd = ["none", "arrowEnd", "none", "dot", "none"]; - // private _arrowIcons = ["→", "↔︎", "•", "••", " "]; private _draw = ["⎯", "→", "↔︎", "∿", "↝", "↭", "ロ", "O", "∆"]; private _head = ["", "", "arrow", "", "", "arrow", "", "", ""]; private _end = ["", "arrow", "arrow", "", "arrow", "arrow", "", "", ""]; @@ -46,56 +32,25 @@ export default class InkOptionsMenu extends AntimodeMenu { @observable _shapesNum = this._shape.length; @observable _selected = this._shapesNum; - @observable private collapsed: boolean = false; - @observable _double = ""; + @observable _collapsed = false; + @observable _keepMode = false; @observable _colorBtn = false; @observable _widthBtn = false; @observable _fillBtn = false; - // @observable _arrowBtn = false; - // @observable _dashBtn = false; - // @observable _shapeBtn = false; - - constructor(props: Readonly<{}>) { super(props); InkOptionsMenu.Instance = this; this._canFade = false; // don't let the inking menu fade away this.Pinned = BoolCast(Doc.UserDoc()["menuInkOptions-pinned"]); - } @action toggleMenuPin = (e: React.MouseEvent) => { Doc.UserDoc()["menuInkOptions-pinned"] = this.Pinned = !this.Pinned; - if (!this.Pinned) { - // this.fadeOut(true); - } - } - - @action - protected toggleCollapse = (e: React.MouseEvent) => { - this.collapsed = !this.collapsed; - setTimeout(() => { - const x = Math.min(this._left, window.innerWidth - InkOptionsMenu.Instance.width); - InkOptionsMenu.Instance.jumpTo(x, this._top, true); - }, 0); - } - - - - - getColors = () => { - return this._palette; } - // @action - // changeArrow = (arrowStart: string, arrowEnd: string) => { - // SetActiveArrowStart(arrowStart); - // SetActiveArrowEnd(arrowEnd); - // } - @action changeColor = (color: string, type: string) => { const col: ColorState = { @@ -115,313 +70,117 @@ export default class InkOptionsMenu extends AntimodeMenu { const doc = Document(element.rootDoc); if (doc.type === DocumentType.INK) { switch (field) { - case "width": - doc.strokeWidth = Number(value); - break; - case "color": - doc.color = String(value); - break; - case "fill": - doc.fillColor = String(value); - break; - case "bezier": - // doc.strokeBezier === 300 ? doc.strokeBezier = 0 : doc.strokeBezier = 300; - break; - case "dash": - doc.strokeDash = Number(value); - default: - break; + case "width": doc.strokeWidth = Number(value); break; + case "color": doc.color = String(value); break; + case "fill": doc.fillColor = String(value); break; + case "dash": doc.strokeDash = value; } } })); } - - @action - changeBezier = (e: React.PointerEvent): void => { - SetActiveBezierApprox(!ActiveInkBezierApprox() ? "300" : ""); - this.editProperties(0, "bezier"); - } - @action - changeDash = (e: React.PointerEvent): void => { - SetActiveDash(ActiveDash() === "0" ? "2" : "0"); - this.editProperties(ActiveDash(), "strokeDash"); - } - @computed get drawButtons() { - const drawButtons =
- {this._draw.map((icon, i) => { - return ; - })}
; - return drawButtons; + )} +
; } - // @computed get arrowPicker() { - // var currIcon; - // for (var i = 0; i < this._arrowStart.length; i++) { - // if (this._arrowStart[i] === ActiveArrowStart() && this._arrowEnd[i] === ActiveArrowEnd()) { - // currIcon = this._arrowIcons[i]; - // if (this._arrowIcons[i] === " ") { - // currIcon = "➤"; - // } - // } - // } - // var arrowPicker = ; - // if (this._arrowBtn) { - // arrowPicker =
- // {arrowPicker} - // {this._arrowStart.map((arrowStart, i) => { - // return ; - // })} - //
; - // } - // return arrowPicker; - // } + toggleButton = (key: string, value: boolean, setter: () => {}, icon: FontAwesomeIconProps["icon"], ele: JSX.Element | null) => { + return ; + } @computed get widthPicker() { - var widthPicker = ; - if (this._widthBtn) { - widthPicker =
+ var widthPicker = this.toggleButton("stroke width", this._widthBtn, () => this._widthBtn = !this._widthBtn, "bars", null); + return !this._widthBtn ? widthPicker : +
{widthPicker} - {this._width.map(wid => { - return ; - })} + )}
; - } - return widthPicker; } - - @computed get colorPicker() { - var colorPicker = ; - if (this._colorBtn) { - colorPicker =
+ var colorPicker = this.toggleButton("stroke color", this._colorBtn, () => this._colorBtn = !this._colorBtn, "pen-nib", +
); + return !this._colorBtn ? colorPicker : +
{colorPicker} - {this._palette.map(color => { - return ; - })} +
+ )}
; - } - return colorPicker; - } - @computed get formatPane() { - return ; } - @computed get fillPicker() { - var fillPicker = ; - if (this._fillBtn) { - fillPicker =
+ var fillPicker = this.toggleButton("shape fill color", this._fillBtn, () => this._fillBtn = !this._fillBtn, "fill-drip", +
); + return !this._fillBtn ? fillPicker : +
{fillPicker} - {this._palette.map(color => { - return ; - })} + )}
; - } - return fillPicker; } - // @computed get shapePicker() { - // var currIcon; - // if (GestureOverlay.Instance.InkShape === "") { - // currIcon = ; - // } else { - // for (var i = 0; i < this._icons.length; i++) { - // if (GestureOverlay.Instance.InkShape === this._buttons[i]) { - // currIcon = this._icons[i]; - // } - // } - // } - // var shapePicker = ; - // if (this._shapeBtn) { - // shapePicker =
- // {shapePicker} - // {this._buttons.map((btn, i) => { - // var ttl = btn; - // if (btn === "") { - // ttl = "no shape"; - // } - // if (btn === "noRec") { - // ttl = "disable shape recognition"; - // } - // return ; - // })} - //
; - // } - // return shapePicker; - // } - - @computed get bezierButton() { - return ; - } - - @computed get dashButton() { - return ; } render() { - const buttons = [ - // , - // this.shapePicker, - // this.bezierButton, + return this.getElement([ this.widthPicker, this.colorPicker, this.fillPicker, this.drawButtons, this.formatPane, - // this.arrowPicker, - // this.dashButton, - - ]; - - // return this.getElement(buttons); - return this.getElement(buttons); + ]); } } Scripting.addGlobal(function activatePen(penBtn: any) { -- cgit v1.2.3-70-g09d2 From 87acc13c460dad0223de96e6a2a56e18ecc45d67 Mon Sep 17 00:00:00 2001 From: Bob Zeleznik Date: Wed, 15 Jul 2020 12:06:21 -0400 Subject: made link description text clickable --- .../CollectionFreeFormLinkView.tsx | 82 ++++------------------ 1 file changed, 12 insertions(+), 70 deletions(-) (limited to 'src/client/views/collections/collectionFreeForm') diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinkView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinkView.tsx index 17f7e3128..2938c53cf 100644 --- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinkView.tsx +++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinkView.tsx @@ -1,15 +1,16 @@ import { observer } from "mobx-react"; import { Doc } from "../../../../fields/Doc"; -import { Utils } from '../../../../Utils'; +import { Utils, setupMoveUpEvents, emptyFunction, returnFalse } from '../../../../Utils'; import { DocumentView } from "../../nodes/DocumentView"; import "./CollectionFreeFormLinkView.scss"; import React = require("react"); -import v5 = require("uuid/v5"); import { DocumentType } from "../../../documents/DocumentTypes"; import { observable, action, reaction, IReactionDisposer } from "mobx"; import { StrCast, Cast } from "../../../../fields/Types"; import { Id } from "../../../../fields/FieldSymbols"; import { SnappingManager } from "../../../util/SnappingManager"; +import { OverlayView } from "../../OverlayView"; +import { LinkEditor } from "../../linking/LinkEditor"; export interface CollectionFreeFormLinkViewProps { A: DocumentView; @@ -29,8 +30,6 @@ export class CollectionFreeFormLinkView extends React.Component [this.props.A.props.ScreenToLocalTransform(), this.props.B.props.ScreenToLocalTransform(), this.props.A.isSelected() || Doc.IsBrushed(this.props.A.props.Document), this.props.A.isSelected() || Doc.IsBrushed(this.props.A.props.Document)], action(() => { if (SnappingManager.GetIsDragging()) return; @@ -91,43 +90,20 @@ export class CollectionFreeFormLinkView extends React.Component) => { - if (e.key === "Enter") { - this.setDescripValue(this.descriptionText); - document.getElementById('input')?.blur(); - } - } - - @action - handleChange = (e: React.ChangeEvent) => { - this.descriptionText = e.target.value; - } - - @action - setDescripValue = (value: string) => { - this.props.A.props.Document.description = value; - return true; - } pointerDown = (e: React.PointerEvent) => { - this.down = true; - this.downCoor[0] = e.screenX; - this.downCoor[1] = e.screenY; - } - - onUp = (e: React.PointerEvent) => { - if (this.down) { - this.offset[0] = e.screenX - this.downCoor[0]; - this.offset[1] = e.screenY - this.downCoor[1]; - } + setupMoveUpEvents(this, e, returnFalse, emptyFunction, () => { + // OverlayView.Instance.addElement( + // { })} + // />, { x: 300, y: 300 }); + }); } @action componentWillUnmount() { this._anchorDisposer?.(); - //document.removeEventListener("pointerup", this.onUp); } @@ -159,47 +135,13 @@ export class CollectionFreeFormLinkView extends React.Component - {/* {this.down ?
: null} */} - - - {this.descriptionText} - - - {/* */} - + + {this.descriptionText} + ); } } \ No newline at end of file -- cgit v1.2.3-70-g09d2 From d0fbc4d8eddc05993ab1fdf70baa2c72440c4846 Mon Sep 17 00:00:00 2001 From: Bob Zeleznik Date: Wed, 15 Jul 2020 12:17:58 -0400 Subject: made link label draggable. --- .../CollectionFreeFormLinkView.scss | 1 + .../CollectionFreeFormLinkView.tsx | 33 +++++++++------------- 2 files changed, 15 insertions(+), 19 deletions(-) (limited to 'src/client/views/collections/collectionFreeForm') diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinkView.scss b/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinkView.scss index 05111adb4..8cbda310a 100644 --- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinkView.scss +++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinkView.scss @@ -16,4 +16,5 @@ stroke: rgb(0,0,0); opacity: 0.5; pointer-events: all; + cursor: move; } diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinkView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinkView.tsx index 2938c53cf..7fa88d8ae 100644 --- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinkView.tsx +++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinkView.tsx @@ -6,7 +6,7 @@ import "./CollectionFreeFormLinkView.scss"; import React = require("react"); import { DocumentType } from "../../../documents/DocumentTypes"; import { observable, action, reaction, IReactionDisposer } from "mobx"; -import { StrCast, Cast } from "../../../../fields/Types"; +import { StrCast, Cast, NumCast } from "../../../../fields/Types"; import { Id } from "../../../../fields/FieldSymbols"; import { SnappingManager } from "../../../util/SnappingManager"; import { OverlayView } from "../../OverlayView"; @@ -23,12 +23,9 @@ export class CollectionFreeFormLinkView extends React.Component [this.props.A.props.ScreenToLocalTransform(), this.props.B.props.ScreenToLocalTransform(), this.props.A.isSelected() || Doc.IsBrushed(this.props.A.props.Document), this.props.A.isSelected() || Doc.IsBrushed(this.props.A.props.Document)], action(() => { @@ -92,7 +89,11 @@ export class CollectionFreeFormLinkView extends React.Component { - setupMoveUpEvents(this, e, returnFalse, emptyFunction, () => { + setupMoveUpEvents(this, e, (e, down, delta) => { + this.props.LinkDocs[0].linkOffsetX = NumCast(this.props.LinkDocs[0].linkOffsetX) + delta[0]; + this.props.LinkDocs[0].linkOffsetY = NumCast(this.props.LinkDocs[0].linkOffsetY) + delta[1]; + return false; + }, emptyFunction, () => { // OverlayView.Instance.addElement( // { })} @@ -101,14 +102,8 @@ export class CollectionFreeFormLinkView extends React.Component + return !a.width || !b.width || ((!this.props.LinkDocs[0].linkDisplay) && !aActive && !bActive) ? (null) : (<> - {this.descriptionText} + {StrCast(this.props.LinkDocs[0].description)} ); } -- cgit v1.2.3-70-g09d2 From 320ffdddca6bd3c1fcf76d09942058256a6d8590 Mon Sep 17 00:00:00 2001 From: Bob Zeleznik Date: Wed, 15 Jul 2020 12:25:21 -0400 Subject: from last. --- .../collections/collectionFreeForm/CollectionFreeFormLinkView.tsx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src/client/views/collections/collectionFreeForm') diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinkView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinkView.tsx index 7fa88d8ae..dea936113 100644 --- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinkView.tsx +++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinkView.tsx @@ -121,13 +121,13 @@ export class CollectionFreeFormLinkView extends React.Component -- cgit v1.2.3-70-g09d2 From 3fdee81100954e66f54c73661cb11967993ff467 Mon Sep 17 00:00:00 2001 From: Bob Zeleznik Date: Wed, 15 Jul 2020 15:24:53 -0400 Subject: fixed tooltips to share a csss style. added tooltips for richtext. --- src/client/documents/Documents.ts | 2 +- src/client/views/DocumentButtonBar.tsx | 10 ++--- src/client/views/DocumentDecorations.tsx | 15 +++---- src/client/views/MainView.scss | 4 ++ .../views/collections/CollectionLinearView.tsx | 20 +++++---- src/client/views/collections/CollectionMenu.tsx | 13 +++--- src/client/views/collections/CollectionView.tsx | 3 +- .../CollectionFreeFormLinkView.tsx | 12 +++--- src/client/views/linking/LinkEditor.tsx | 14 +++---- src/client/views/linking/LinkMenuItem.tsx | 19 +++------ src/client/views/nodes/DocumentLinksButton.tsx | 5 +-- src/client/views/nodes/DocumentView.tsx | 25 +++-------- .../formattedText/FormattedTextBoxComment.tsx | 4 +- .../views/nodes/formattedText/RichTextMenu.tsx | 49 +++++++++++++--------- src/client/views/pdf/PDFViewer.tsx | 2 +- 15 files changed, 94 insertions(+), 103 deletions(-) (limited to 'src/client/views/collections/collectionFreeForm') diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts index 1fd533b62..b57f4c6c7 100644 --- a/src/client/documents/Documents.ts +++ b/src/client/documents/Documents.ts @@ -915,7 +915,7 @@ export namespace DocUtils { const linkDoc = Docs.Create.LinkDocument(source, target, { linkRelationship, layoutKey: "layout_linkView", description }, id); linkDoc.linkDisplay = true; - linkDoc.hideAnhors = true; + linkDoc.hidden = true; linkDoc.layout_linkView = Cast(Cast(Doc.UserDoc()["template-button-link"], Doc, null).dragFactory, Doc, null); Doc.GetProto(linkDoc).title = ComputedField.MakeFunction('self.anchor1?.title +" (" + (self.linkRelationship||"to") +") " + self.anchor2?.title'); diff --git a/src/client/views/DocumentButtonBar.tsx b/src/client/views/DocumentButtonBar.tsx index 05538a28e..45f4c7393 100644 --- a/src/client/views/DocumentButtonBar.tsx +++ b/src/client/views/DocumentButtonBar.tsx @@ -118,7 +118,7 @@ export class DocumentButtonBar extends React.Component<{ views: () => (DocumentV const targetDoc = this.view0?.props.Document; const published = targetDoc && Doc.GetProto(targetDoc)[GoogleRef] !== undefined; const animation = this.isAnimatingPulse ? "shadow-pulse 1s linear infinite" : "none"; - return !targetDoc ? (null) :
{`${published ? "Push" : "Publish"} to Google Docs`}
}> + return !targetDoc ? (null) :
{`${published ? "Push" : "Publish"} to Google Docs`}
}>
(DocumentV })(); return !targetDoc || !dataDoc || !dataDoc[GoogleRef] ? (null) :
{title}
}> + title={<>
{title}
}>
{ @@ -197,7 +197,7 @@ export class DocumentButtonBar extends React.Component<{ views: () => (DocumentV get pinButton() { const targetDoc = this.view0?.props.Document; const isPinned = targetDoc && Doc.isDocPinned(targetDoc); - return !targetDoc ? (null) :
{Doc.isDocPinned(targetDoc) ? "Unpin from presentation" : "Pin to presentation"}
}> + return !targetDoc ? (null) :
{Doc.isDocPinned(targetDoc) ? "Unpin from presentation" : "Pin to presentation"}
}>
DockedFrameRenderer.PinDoc(targetDoc, isPinned)}> @@ -209,7 +209,7 @@ export class DocumentButtonBar extends React.Component<{ views: () => (DocumentV @computed get metadataButton() { const view0 = this.view0; - return !view0 ? (null) :
Show metadata panel
}> + return !view0 ? (null) :
Show metadata panel
}>
dv).map(dv => dv!.props.Document)} suggestWithFunction /> /* tfs: @bcz This might need to be the data document? */}> @@ -258,7 +258,7 @@ export class DocumentButtonBar extends React.Component<{ views: () => (DocumentV Array.from(Object.values(Templates.TemplateList)).map(template => templates.set(template, views.reduce((checked, doc) => checked || doc?.props.Document["_show" + template.Name] ? true : false, false as boolean))); return !view0 ? (null) : -
Tap: Customize layout. Drag: Create alias
}> +
Tap: Customize layout. Drag: Create alias
}>
this._aliasDown = true)} onClose={action(() => this._aliasDown = false)} content={!this._aliasDown ? (null) : v).map(v => v as DocumentView)} templates={templates} />}> diff --git a/src/client/views/DocumentDecorations.tsx b/src/client/views/DocumentDecorations.tsx index 2fd017f7b..376b1d46b 100644 --- a/src/client/views/DocumentDecorations.tsx +++ b/src/client/views/DocumentDecorations.tsx @@ -81,6 +81,7 @@ export class DocumentDecorations extends React.Component<{}, { value: string }> return SelectionManager.SelectedDocuments().reduce((bounds, documentView) => { if (documentView.props.renderDepth === 0 || documentView.props.treeViewDoc || + !documentView.ContentDiv || Doc.AreProtosEqual(documentView.props.Document, Doc.UserDoc())) { return bounds; } @@ -88,7 +89,7 @@ export class DocumentDecorations extends React.Component<{}, { value: string }> var [sptX, sptY] = transform.transformPoint(0, 0); let [bptX, bptY] = transform.transformPoint(documentView.props.PanelWidth(), documentView.props.PanelHeight()); if (documentView.props.Document.type === DocumentType.LINK) { - const docuBox = documentView.ContentDiv!.getElementsByClassName("linkAnchorBox-cont"); + const docuBox = documentView.ContentDiv.getElementsByClassName("linkAnchorBox-cont"); if (docuBox.length) { const rect = docuBox[0].getBoundingClientRect(); sptX = rect.left; @@ -544,11 +545,11 @@ export class DocumentDecorations extends React.Component<{}, { value: string }> } const minimal = bounds.r - bounds.x < 100 ? true : false; const maximizeIcon = minimal ? ( -
Show context menu
} placement="top"> +
Show context menu
} placement="top">
) : ( -
Iconify
} placement="top"> +
Iconify
} placement="top">
{/* 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*/} @@ -572,7 +573,7 @@ export class DocumentDecorations extends React.Component<{}, { value: string }>
} : <> - {minimal ? (null) :
Show context menu
} placement="top">
+ {minimal ? (null) :
Show context menu
} placement="top">
}
@@ -611,11 +612,11 @@ export class DocumentDecorations extends React.Component<{}, { value: string }> {maximizeIcon} {titleArea} {SelectionManager.SelectedDocuments().length !== 1 || seldoc.Document.type === DocumentType.INK ? (null) : -
{`${seldoc.finalLayoutKey.includes("icon") ? "De" : ""}Iconify Document`}
} placement="top"> +
{`${seldoc.finalLayoutKey.includes("icon") ? "De" : ""}Iconify Document`}
} placement="top">
{"_"}
} -
Open Document In Tab
} placement="top">
+
Open Document In Tab
} placement="top">
{SelectionManager.SelectedDocuments().length === 1 ? DocumentDecorations.DocumentIcon(StrCast(seldoc.props.Document.layout, "...")) : "..."}
e.preventDefault()}>
{seldoc.props.renderDepth <= 1 || !seldoc.props.ContainingCollectionView ? (null) : -
tap to select containing document
} placement="top"> +
tap to select containing document
} placement="top">
e.preventDefault()}> diff --git a/src/client/views/MainView.scss b/src/client/views/MainView.scss index 5b142ffda..e1ddbc533 100644 --- a/src/client/views/MainView.scss +++ b/src/client/views/MainView.scss @@ -1,6 +1,10 @@ @import "globalCssVariables"; @import "nodeModuleOverrides"; +.dash-tooltip { + font-size: 11px; + padding: 2px; +} .mainView-tabButtons { position: relative; diff --git a/src/client/views/collections/CollectionLinearView.tsx b/src/client/views/collections/CollectionLinearView.tsx index 319cca70f..407524353 100644 --- a/src/client/views/collections/CollectionLinearView.tsx +++ b/src/client/views/collections/CollectionLinearView.tsx @@ -124,7 +124,7 @@ export class CollectionLinearView extends CollectionSubView(LinearDocument) { return
-
{BoolCast(this.props.Document.linearViewIsExpanded) ? "Close menu" : "Open menu"}
} placement="top"> +
{BoolCast(this.props.Document.linearViewIsExpanded) ? "Close menu" : "Open menu"}
} placement="top"> {menuOpener}
e.stopPropagation()} > - Creating link from: {DocumentLinksButton.StartLink.title} + Creating link from: {DocumentLinksButton.StartLink.title} + -
{LinkDescriptionPopup.showDescriptions ? "Turn off description pop-up" : - "Turn on description pop-up"}
} placement="top"> - Labels: {LinkDescriptionPopup.showDescriptions ? LinkDescriptionPopup.showDescriptions : "ON"} +
{LinkDescriptionPopup.showDescriptions ? "Turn off description pop-up" : + "Turn on description pop-up"}
} placement="top"> + + Labels: {LinkDescriptionPopup.showDescriptions ? LinkDescriptionPopup.showDescriptions : "ON"}
-
Exit link clicking mode
} placement="top"> - Clear +
Exit link clicking mode
} placement="top"> + + Clear +
{/* : , - - ]); + const button = ; + + return this.getElement(!this.SelectedCollection ? [button] : + [, + button]); } } diff --git a/src/client/views/collections/CollectionView.tsx b/src/client/views/collections/CollectionView.tsx index c1a6b5b0d..c1da23470 100644 --- a/src/client/views/collections/CollectionView.tsx +++ b/src/client/views/collections/CollectionView.tsx @@ -142,6 +142,7 @@ export class CollectionView extends Touchable d instanceof Doc); - first && (first.hidden = true); doc.displayTimecode = undefined; } doc.context = this.props.Document; diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinkView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinkView.tsx index dea936113..0933d525a 100644 --- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinkView.tsx +++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinkView.tsx @@ -29,13 +29,13 @@ export class CollectionFreeFormLinkView extends React.Component [this.props.A.props.ScreenToLocalTransform(), this.props.B.props.ScreenToLocalTransform(), this.props.A.isSelected() || Doc.IsBrushed(this.props.A.props.Document), this.props.A.isSelected() || Doc.IsBrushed(this.props.A.props.Document)], action(() => { - if (SnappingManager.GetIsDragging()) return; + if (SnappingManager.GetIsDragging() || !this.props.A.ContentDiv || !this.props.B.ContentDiv) return; setTimeout(action(() => this._opacity = 1), 0); // since the render code depends on querying the Dom through getBoudndingClientRect, we need to delay triggering render() setTimeout(action(() => (!this.props.LinkDocs.length || !this.props.LinkDocs[0].linkDisplay) && (this._opacity = 0.05)), 750); // this will unhighlight the link line. - const acont = this.props.A.props.Document.type === DocumentType.LINK ? this.props.A.ContentDiv!.getElementsByClassName("linkAnchorBox-cont") : []; - const bcont = this.props.B.props.Document.type === DocumentType.LINK ? this.props.B.ContentDiv!.getElementsByClassName("linkAnchorBox-cont") : []; - const adiv = (acont.length ? acont[0] : this.props.A.ContentDiv!); - const bdiv = (bcont.length ? bcont[0] : this.props.B.ContentDiv!); + const acont = this.props.A.props.Document.type === DocumentType.LINK ? this.props.A.ContentDiv.getElementsByClassName("linkAnchorBox-cont") : []; + const bcont = this.props.B.props.Document.type === DocumentType.LINK ? this.props.B.ContentDiv.getElementsByClassName("linkAnchorBox-cont") : []; + const adiv = (acont.length ? acont[0] : this.props.A.ContentDiv); + const bdiv = (bcont.length ? bcont[0] : this.props.B.ContentDiv); const a = adiv.getBoundingClientRect(); const b = bdiv.getBoundingClientRect(); const abounds = adiv.parentElement!.getBoundingClientRect(); @@ -103,7 +103,7 @@ export class CollectionFreeFormLinkView extends React.Component { @observable description = StrCast(LinkManager.currentLink?.description); @observable openDropdown: boolean = false; - @observable followBehavior = this.props.linkDoc.follow ? this.props.linkDoc.follow : "Default"; @observable showInfo: boolean = false; @computed get infoIcon() { if (this.showInfo) { return "chevron-up"; } return "chevron-down"; } @observable private buttonColor: string = "black"; @@ -364,8 +363,7 @@ export class LinkEditor extends React.Component { @action changeFollowBehavior = (follow: string) => { this.openDropdown = false; - this.followBehavior = follow; - this.props.linkDoc.follow = follow; + Doc.GetProto(this.props.linkDoc).followLinkLocation = follow; } @computed @@ -376,7 +374,7 @@ export class LinkEditor extends React.Component {
- {this.followBehavior} + {StrCast(this.props.linkDoc.followLinkLocation, "Default")} @@ -388,11 +386,11 @@ export class LinkEditor extends React.Component { Default
this.changeFollowBehavior("Always open in right tab")}> + onPointerDown={() => this.changeFollowBehavior("onRight")}> Always open in right tab
this.changeFollowBehavior("Always open in new tab")}> + onPointerDown={() => this.changeFollowBehavior("inTab")}> Always open in new tab
@@ -416,7 +414,7 @@ export class LinkEditor extends React.Component { return !destination ? (null) : (
-
Return to link menu
} placement="top"> +
Return to link menu
} placement="top"> */} -
Show more link information
} placement="top"> +
Show more link information
} placement="top">
diff --git a/src/client/views/linking/LinkMenuItem.tsx b/src/client/views/linking/LinkMenuItem.tsx index 6782f625b..0e847632b 100644 --- a/src/client/views/linking/LinkMenuItem.tsx +++ b/src/client/views/linking/LinkMenuItem.tsx @@ -16,7 +16,6 @@ import { DocumentView } from '../nodes/DocumentView'; import { DocumentLinksButton } from '../nodes/DocumentLinksButton'; import { LinkDocPreview } from '../nodes/LinkDocPreview'; import { Tooltip } from '@material-ui/core'; -import { RichTextField } from '../../../fields/RichTextField'; import { DocumentType } from '../../documents/DocumentTypes'; library.add(faEye, faEdit, faTimes, faArrowRight, faChevronDown, faChevronUp, faPencilAlt, faEyeSlash); @@ -157,14 +156,8 @@ export class LinkMenuItem extends React.Component { DocumentLinksButton.EditLink = undefined; LinkDocPreview.LinkInfo = undefined; - if (this.props.linkDoc.follow) { - if (this.props.linkDoc.follow === "Default") { - DocumentManager.Instance.FollowLink(this.props.linkDoc, this.props.sourceDoc, doc => this.props.addDocTab(doc, "onRight"), false); - } else if (this.props.linkDoc.follow === "Always open in right tab") { - this.props.addDocTab(this.props.destinationDoc, "onRight"); - } else if (this.props.linkDoc.follow === "Always open in new tab") { - this.props.addDocTab(this.props.destinationDoc, "inTab"); - } + if (this.props.linkDoc.followLinkLocation && this.props.linkDoc.followLinkLocation !== "Default") { + this.props.addDocTab(this.props.destinationDoc, StrCast(this.props.linkDoc.followLinkLocation)); } else { DocumentManager.Instance.FollowLink(this.props.linkDoc, this.props.sourceDoc, doc => this.props.addDocTab(doc, "onRight"), false); } @@ -221,8 +214,6 @@ export class LinkMenuItem extends React.Component { StrCast(this.props.linkDoc.storedText).substr(0, 18) : this.props.linkDoc.storedText : undefined : undefined; - const showTitle = this.props.linkDoc.hidden ? "Show link" : "Hide link"; - return (
@@ -255,16 +246,16 @@ export class LinkMenuItem extends React.Component { {canExpand ?
this.toggleShowMore(e)}>
: <>} -
{showTitle}
}> +
{this.props.linkDoc.hidden ? "Show link" : "Hide link"}
}>
-
Edit Link
}> +
Edit Link
}>
-
Delete Link
}> +
Delete Link
}>
diff --git a/src/client/views/nodes/DocumentLinksButton.tsx b/src/client/views/nodes/DocumentLinksButton.tsx index 01c068966..bbef48e44 100644 --- a/src/client/views/nodes/DocumentLinksButton.tsx +++ b/src/client/views/nodes/DocumentLinksButton.tsx @@ -134,7 +134,6 @@ export class DocumentLinksButton extends React.Component { if (linkDoc) { @@ -213,10 +212,10 @@ export class DocumentLinksButton extends React.Component
{title}
}> +
{title}
}> {linkButton}
: !!!DocumentLinksButton.EditLink ? -
{title}
}> +
{title}
}> {linkButton}
: linkButton; diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx index a6771443a..c0a8b3a59 100644 --- a/src/client/views/nodes/DocumentView.tsx +++ b/src/client/views/nodes/DocumentView.tsx @@ -589,16 +589,12 @@ export class DocumentView extends DocComponent(Docu @undoBatch toggleLinkButtonBehavior = (): void => { + this.Document.ignoreClick = false; if (this.Document.isLinkButton || this.onClickHandler || this.Document.ignoreClick) { this.Document.isLinkButton = false; - const first = DocListCast(this.Document.links).find(d => d instanceof Doc); - first && (first.hidden = false); - this.Document.ignoreClick = false; this.Document.onClick = this.layoutDoc.onClick = undefined; } else { this.Document.isLinkButton = true; - const first = DocListCast(this.Document.links).find(d => d instanceof Doc); - first && (first.hidden = true); this.Document.followLinkZoom = false; this.Document.followLinkLocation = undefined; } @@ -606,14 +602,9 @@ export class DocumentView extends DocComponent(Docu @undoBatch toggleFollowInPlace = (): void => { + this.Document.ignoreClick = false; + this.Document.isLinkButton = !this.Document.isLinkButton; if (this.Document.isLinkButton) { - this.Document.isLinkButton = false; - const first = DocListCast(this.Document.links).find(d => d instanceof Doc); - first && (first.hidden = false); - } else { - this.Document.isLinkButton = true; - const first = DocListCast(this.Document.links).find(d => d instanceof Doc); - first && (first.hidden = true); this.Document.followLinkZoom = true; this.Document.followLinkLocation = "inPlace"; } @@ -621,15 +612,10 @@ export class DocumentView extends DocComponent(Docu @undoBatch toggleFollowOnRight = (): void => { + this.Document.ignoreClick = false; + this.Document.isLinkButton = !this.Document.isLinkButton; if (this.Document.isLinkButton) { - this.Document.isLinkButton = false; - const first = DocListCast(this.Document.links).find(d => d instanceof Doc); - first && (first.hidden = false); - } else { - this.Document.isLinkButton = true; this.Document.followLinkZoom = false; - const first = DocListCast(this.Document.links).find(d => d instanceof Doc); - first && (first.hidden = true); this.Document.followLinkLocation = "onRight"; } } @@ -643,7 +629,6 @@ export class DocumentView extends DocComponent(Docu } const makeLink = action((linkDoc: Doc) => { LinkManager.currentLink = linkDoc; - linkDoc.hidden = true; LinkCreatedBox.popupX = de.x; LinkCreatedBox.popupY = de.y - 33; diff --git a/src/client/views/nodes/formattedText/FormattedTextBoxComment.tsx b/src/client/views/nodes/formattedText/FormattedTextBoxComment.tsx index c98b5eac1..3687d5513 100644 --- a/src/client/views/nodes/formattedText/FormattedTextBoxComment.tsx +++ b/src/client/views/nodes/formattedText/FormattedTextBoxComment.tsx @@ -270,14 +270,14 @@ export class FormattedTextBoxComment {
-
Delete Link
} placement="top"> +
Delete Link
} placement="top">
this._deleteRef = r}>
-
Follow Link
} placement="top"> +
Follow Link
} placement="top">
this._followRef = r}> - - + {title}
} key={title} placement="bottom"> + +
); } @@ -388,7 +391,9 @@ export default class RichTextMenu extends AntimodeMenu { } }); } - return ; + return {key}
} placement="bottom"> + + ; } createNodesDropdown(activeMap: string, options: { node: NodeType | any | null, title: string, label: string, command: (node: NodeType | any) => void, hidden?: boolean, style?: {} }[], key: string, setter: (val: string) => {}): JSX.Element { @@ -412,7 +417,10 @@ export default class RichTextMenu extends AntimodeMenu { } }); } - return ; + + return {key}
} placement="bottom"> + + ; } changeFontSize = (mark: Mark, view: EditorView) => { @@ -595,10 +603,11 @@ export default class RichTextMenu extends AntimodeMenu { label = "No marks are currently stored"; } - const button = -
} placement="bottom"> + ; + +
; const dropdownContent =
@@ -667,11 +676,12 @@ export default class RichTextMenu extends AntimodeMenu { self.TextView.EditorView!.focus(); } - const button = -
} placement="bottom"> + ; + +
; const dropdownContent =
@@ -720,11 +730,12 @@ export default class RichTextMenu extends AntimodeMenu { UndoManager.RunInBatch(() => self.view && self.insertHighlight(self.activeHighlightColor, self.view.state, self.view.dispatch), "rt highlighter"); } - const button = -
} placement="bottom"> + ; + +
; const dropdownContent =
@@ -763,7 +774,9 @@ export default class RichTextMenu extends AntimodeMenu { const link = this.currentLink ? this.currentLink : ""; - const button = ; + const button = set hyperlink
} placement="bottom"> +
+ ; const dropdownContent =
@@ -774,9 +787,7 @@ export default class RichTextMenu extends AntimodeMenu {
; - return ( - - ); + return ; } async getTextLinkTargetTitle() { @@ -935,7 +946,7 @@ export default class RichTextMenu extends AntimodeMenu { {[this.createMarksDropdown(this.activeFontSize, this.fontSizeOptions, "font size", action((val: string) => this.activeFontSize = val)), this.createMarksDropdown(this.activeFontFamily, this.fontFamilyOptions, "font family", action((val: string) => this.activeFontFamily = val)),
, - this.createNodesDropdown(this.activeListType, this.listTypeOptions, "nodes", action((val: string) => this.activeListType = val)), + this.createNodesDropdown(this.activeListType, this.listTypeOptions, "list type", action((val: string) => this.activeListType = val)), this.createButton("sort-amount-down", "Summarize", undefined, this.insertSummarizer), this.createButton("quote-left", "Blockquote", undefined, this.insertBlockquote), this.createButton("minus", "Horizontal Rule", undefined, this.insertHorizontalRule), diff --git a/src/client/views/pdf/PDFViewer.tsx b/src/client/views/pdf/PDFViewer.tsx index 4e5fdbfbb..56212a773 100644 --- a/src/client/views/pdf/PDFViewer.tsx +++ b/src/client/views/pdf/PDFViewer.tsx @@ -637,7 +637,7 @@ export class PDFViewer extends ViewBoxAnnotatableComponent { - if (this.active()) { + if (this.active(true)) { e.stopPropagation(); if (e.ctrlKey) { const curScale = Number(this._pdfViewer.currentScaleValue); -- cgit v1.2.3-70-g09d2