diff options
author | Geireann Lindfield Roberts <60007097+geireann@users.noreply.github.com> | 2022-06-30 12:28:25 -0700 |
---|---|---|
committer | Geireann Lindfield Roberts <60007097+geireann@users.noreply.github.com> | 2022-06-30 12:28:25 -0700 |
commit | 891b03238ee7bf6bd9e83cc20c1720c42059ce04 (patch) | |
tree | b912f6f1e8177106ce015896882cdc8bb11acafd /src/client/views/nodes/button/FontIconBox.tsx | |
parent | bb02d3a052efdbf25d1069059a92b7a9d9cc1708 (diff) | |
parent | ea6e63648b21c46672b1b7cb1da0cbaa6857d0c1 (diff) |
Merge branch 'master' into parker
Diffstat (limited to 'src/client/views/nodes/button/FontIconBox.tsx')
-rw-r--r-- | src/client/views/nodes/button/FontIconBox.tsx | 200 |
1 files changed, 149 insertions, 51 deletions
diff --git a/src/client/views/nodes/button/FontIconBox.tsx b/src/client/views/nodes/button/FontIconBox.tsx index ca13590de..85efc67a5 100644 --- a/src/client/views/nodes/button/FontIconBox.tsx +++ b/src/client/views/nodes/button/FontIconBox.tsx @@ -1,21 +1,24 @@ import { IconProp } from '@fortawesome/fontawesome-svg-core'; import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; import { Tooltip } from '@material-ui/core'; +import { StringIterator } from 'lodash'; import { action, computed, observable } from 'mobx'; import { observer } from 'mobx-react'; import * as React from 'react'; import { ColorState, SketchPicker } from 'react-color'; -import { Doc, StrListCast } from '../../../../fields/Doc'; +import { Doc, HeightSym, StrListCast, WidthSym } from '../../../../fields/Doc'; import { InkTool } from '../../../../fields/InkField'; import { createSchema } from '../../../../fields/Schema'; import { ScriptField } from '../../../../fields/ScriptField'; import { BoolCast, Cast, NumCast, ScriptCast, StrCast } from '../../../../fields/Types'; import { WebField } from '../../../../fields/URLField'; -import { Utils } from '../../../../Utils'; +import { aggregateBounds, Utils } from '../../../../Utils'; import { DocumentType } from '../../../documents/DocumentTypes'; +import { CurrentUserUtils } from '../../../util/CurrentUserUtils'; import { ScriptingGlobals } from "../../../util/ScriptingGlobals"; import { SelectionManager } from '../../../util/SelectionManager'; import { undoBatch, UndoManager } from '../../../util/UndoManager'; +import { CollectionFreeFormView } from '../../collections/collectionFreeForm'; import { CollectionViewType } from '../../collections/CollectionView'; import { ContextMenu } from '../../ContextMenu'; import { DocComponent } from '../../DocComponent'; @@ -23,6 +26,7 @@ import { EditableView } from '../../EditableView'; import { GestureOverlay } from '../../GestureOverlay'; import { Colors } from '../../global/globalEnums'; import { ActiveFillColor, ActiveInkColor, ActiveInkWidth, SetActiveFillColor, SetActiveInkColor, SetActiveInkWidth } from '../../InkingStroke'; +import { InkTranscription } from '../../InkTranscription'; import { StyleProp } from '../../StyleProvider'; import { FieldView, FieldViewProps } from '.././FieldView'; import { RichTextMenu } from '../formattedText/RichTextMenu'; @@ -67,7 +71,7 @@ export class FontIconBox extends DocComponent<ButtonProps>() { useAsPrototype = (): void => { this.layoutDoc.onDragStart = ScriptField.MakeFunction('makeDelegate(this.dragFactory, true)'); }; specificContextMenu = (): void => { - if (!Doc.UserDoc().noviceMode) { + if (!Doc.noviceMode) { const cm = ContextMenu.Instance; cm.addItem({ description: "Show Template", event: this.showTemplate, icon: "tag" }); cm.addItem({ description: "Use as Render Template", event: this.dragAsTemplate, icon: "tag" }); @@ -75,6 +79,9 @@ export class FontIconBox extends DocComponent<ButtonProps>() { } } + static GetShowLabels() { return BoolCast(Doc.UserDoc()._showLabel); } + static SetShowLabels(show:boolean) { Doc.UserDoc()._showLabel = show; } + // Determining UI Specs @observable private label = StrCast(this.rootDoc.label, StrCast(this.rootDoc.title)); @observable private icon = StrCast(this.dataDoc.icon, "user") as any; @@ -107,25 +114,27 @@ export class FontIconBox extends DocComponent<ButtonProps>() { // Script for checking the outcome of the toggle const checkResult: number = numScript?.script.run({ value: 0, _readOnly_: true }).result || 0; + const label = !FontIconBox.GetShowLabels() ? (null) : + <div className="fontIconBox-label"> + {this.label} + </div>; + if (numBtnType === NumButtonType.Slider) { - const dropdown = - <div - className="menuButton-dropdownBox" - onPointerDown={e => e.stopPropagation()} - > - <input type="range" step="1" min={NumCast(this.rootDoc.numBtnMin, 0)} max={NumCast(this.rootDoc.numBtnMax, 100)} value={checkResult} - className={"menu-slider"} id="slider" - onPointerDown={() => this._batch = UndoManager.StartBatch("presDuration")} - onPointerUp={() => this._batch?.end()} - onChange={e => { e.stopPropagation(); setValue(Number(e.target.value)); }} - /> - </div>; + const dropdown = <div className="menuButton-dropdownBox" onPointerDown={e => e.stopPropagation()} > + <input type="range" step="1" min={NumCast(this.rootDoc.numBtnMin, 0)} max={NumCast(this.rootDoc.numBtnMax, 100)} value={checkResult} + className={"menu-slider"} id="slider" + onPointerDown={() => this._batch = UndoManager.StartBatch("presDuration")} + onPointerUp={() => this._batch?.end()} + onChange={e => { e.stopPropagation(); setValue(Number(e.target.value)); }} + /> + </div>; return ( <div className={`menuButton ${this.type} ${numBtnType}`} onClick={action(() => this.rootDoc.dropDownOpen = !this.rootDoc.dropDownOpen)} > {checkResult} + {label} {this.rootDoc.dropDownOpen ? dropdown : null} </div> ); @@ -206,7 +215,7 @@ export class FontIconBox extends DocComponent<ButtonProps>() { style={{ color: color, backgroundColor: backgroundColor, borderBottomLeftRadius: this.dropdown ? 0 : undefined }} onClick={action(() => this.rootDoc.dropDownOpen = !this.rootDoc.dropDownOpen)}> <FontAwesomeIcon className={`fontIconBox-icon-${this.type}`} icon={this.icon} color={color} /> - {!this.label || !Doc.UserDoc()._showLabel ? (null) : <div className="fontIconBox-label" style={{ color: color, backgroundColor: backgroundColor }}> {this.label} </div>} + {!this.label || !FontIconBox.GetShowLabels() ? (null) : <div className="fontIconBox-label" style={{ color: color, backgroundColor: backgroundColor }}> {this.label} </div>} <div className="menuButton-dropdown" style={{ borderBottomRightRadius: this.dropdown ? 0 : undefined }}> @@ -229,6 +238,7 @@ export class FontIconBox extends DocComponent<ButtonProps>() { const backgroundColor = this.props.styleProvider?.(this.rootDoc, this.props, StyleProp.BackgroundColor); const script = ScriptCast(this.rootDoc.script); + if (!script) { return null; } let noviceList: string[] = []; let text: string | undefined; @@ -263,7 +273,7 @@ export class FontIconBox extends DocComponent<ButtonProps>() { // Get items to place into the list const list = this.buttonList.map((value) => { - if (Doc.UserDoc().noviceMode && !noviceList.includes(value)) { + if (Doc.noviceMode && !noviceList.includes(value)) { return; } return <div className="list-item" key={`${value}`} @@ -276,8 +286,8 @@ export class FontIconBox extends DocComponent<ButtonProps>() { </div>; }); - const label = !this.label || !Doc.UserDoc()._showLabel ? (null) : - <div className="fontIconBox-label" style={{ color: color, backgroundColor: backgroundColor, position: "absolute" }}> + const label = !this.label || !FontIconBox.GetShowLabels() ? (null) : + <div className="fontIconBox-label" style={{ bottom: 0, position: "absolute", color: color, backgroundColor: backgroundColor }}> {this.label} </div>; @@ -330,8 +340,8 @@ export class FontIconBox extends DocComponent<ButtonProps>() { const backgroundColor = this.props.styleProvider?.(this.rootDoc, this.props, StyleProp.BackgroundColor); const curColor = this.colorScript?.script.run({ value: undefined, _readOnly_: true }).result ?? "transparent"; - const label = !this.label || !Doc.UserDoc()._showLabel ? (null) : - <div className="fontIconBox-label" style={{ color, backgroundColor, position: "absolute" }}> + const label = !this.label || !FontIconBox.GetShowLabels() ? (null) : + <div className="fontIconBox-label" style={{ color, backgroundColor }}> {this.label} </div>; @@ -342,7 +352,7 @@ export class FontIconBox extends DocComponent<ButtonProps>() { </div>; setTimeout(() => this.colorPicker(curColor)); // cause an update to the color picker rendered in MainView return ( - <div className={`menuButton ${this.type} ${this.colorPickerClosed}`} + <div className={`menuButton ${this.type + (FontIconBox.GetShowLabels() ? "Label" : "")} ${this.colorPickerClosed}`} style={{ color: color, borderBottomLeftRadius: this.dropdown ? 0 : undefined }} onClick={action(() => this.colorPickerClosed = !this.colorPickerClosed)} onPointerDown={e => e.stopPropagation()}> @@ -374,8 +384,8 @@ export class FontIconBox extends DocComponent<ButtonProps>() { const backgroundColor = this.props.styleProvider?.(this.rootDoc, this.props, StyleProp.BackgroundColor); // Button label - const label = !this.label || !Doc.UserDoc()._showLabel ? (null) : - <div className="fontIconBox-label" style={{ color, backgroundColor, position: "absolute" }}> + const label = !this.label || !FontIconBox.GetShowLabels() ? (null) : + <div className="fontIconBox-label" style={{ color, backgroundColor }}> {this.label} </div>; @@ -387,13 +397,13 @@ export class FontIconBox extends DocComponent<ButtonProps>() { <input type="checkbox" checked={backgroundColor === Colors.MEDIUM_BLUE} /> - <span className="slider round"></span> + <span className="slider round" /> </label> </div> ); } else { return ( - <div className={`menuButton ${this.type}`} + <div className={`menuButton ${this.type + (FontIconBox.GetShowLabels() ? "Label" : "")}`} style={{ opacity: 1, backgroundColor, color }}> <FontAwesomeIcon className={`fontIconBox-icon-${this.type}`} icon={this.icon} color={color} /> {label} @@ -416,7 +426,8 @@ export class FontIconBox extends DocComponent<ButtonProps>() { style={{ backgroundColor: "transparent", borderBottomLeftRadius: this.dropdown ? 0 : undefined }}> <div className="menuButton-wrap"> <FontAwesomeIcon className={`menuButton-icon-${this.type}`} icon={this.icon} color={"black"} size={"sm"} /> - {!this.label || !Doc.UserDoc()._showLabel ? (null) : <div className="fontIconBox-label" style={{ color: color, backgroundColor: backgroundColor }}> {this.label} </div>} + {!this.label || !FontIconBox.GetShowLabels() ? (null) : + <div className="fontIconBox-label" style={{ color: color, backgroundColor: backgroundColor }}> {this.label} </div>} </div> </div> ); @@ -442,12 +453,12 @@ export class FontIconBox extends DocComponent<ButtonProps>() { render() { const color = this.props.styleProvider?.(this.rootDoc, this.props, StyleProp.Color); const backgroundColor = this.props.styleProvider?.(this.rootDoc, this.props, StyleProp.BackgroundColor); - const label = !this.label || !Doc.UserDoc()._showLabel ? (null) : - <div className="fontIconBox-label" style={{ color, backgroundColor, position: "absolute" }}> + const label = !this.label || !FontIconBox.GetShowLabels() ? (null) : + <div className="fontIconBox-label" style={{ color, backgroundColor }}> {this.label} </div>; - const menuLabel = !this.label || !Doc.UserDoc()._showMenuLabel ? (null) : + const menuLabel = !this.label || !FontIconBox.GetShowLabels() ? (null) : <div className="fontIconBox-label" style={{ color, backgroundColor: "transparent" }}> {this.label} </div>; @@ -455,7 +466,7 @@ export class FontIconBox extends DocComponent<ButtonProps>() { const buttonText = StrCast(this.rootDoc.buttonText); // TODO:glr Add label of button type - let button = this.defaultButton; + let button: JSX.Element | null = this.defaultButton; switch (this.type) { case ButtonType.TextButton: @@ -489,7 +500,7 @@ export class FontIconBox extends DocComponent<ButtonProps>() { break; case ButtonType.ToolButton: button = ( - <div className={`menuButton ${this.type}`} style={{ opacity: 1, backgroundColor, color }}> + <div className={`menuButton ${this.type + (FontIconBox.GetShowLabels() ? "Label" : "")}`} style={{ opacity: 1, backgroundColor, color }}> <FontAwesomeIcon className={`fontIconBox-icon-${this.type}`} icon={this.icon} color={color} /> {label} </div> @@ -501,7 +512,7 @@ export class FontIconBox extends DocComponent<ButtonProps>() { break; case ButtonType.ClickButton: button = ( - <div className={`menuButton ${this.type}`} style={{ color, backgroundColor, opacity: 1 }}> + <div className={`menuButton ${this.type + (FontIconBox.GetShowLabels() ? "Label" : "")}`} style={{ color, backgroundColor, opacity: 1 }}> <FontAwesomeIcon className={`fontIconBox-icon-${this.type}`} icon={this.icon} color={color} /> {label} </div> @@ -514,7 +525,7 @@ export class FontIconBox extends DocComponent<ButtonProps>() { <div className={`menuButton ${this.type}`} style={{ color, backgroundColor }}> {this.icon === "pres-trail" ? trailsIcon : <FontAwesomeIcon className={`fontIconBox-icon-${this.type}`} icon={this.icon} color={color} />} {menuLabel} - <FontIconBadge collection={Cast(this.rootDoc.watchedDocuments, Doc, null)} /> + <FontIconBadge value={Cast(this.Document.badgeValue,"string",null)} /> </div > ); break; @@ -523,9 +534,10 @@ export class FontIconBox extends DocComponent<ButtonProps>() { } return !this.layoutDoc.toolTip || this.type === ButtonType.DropdownList || this.type === ButtonType.ColorButton || this.type === ButtonType.NumberButton || this.type === ButtonType.EditableText ? button : - <Tooltip title={<div className="dash-tooltip">{StrCast(this.layoutDoc.toolTip)}</div>}> - {button} - </Tooltip>; + button !== null ? + <Tooltip title={<div className="dash-tooltip">{StrCast(this.layoutDoc.toolTip)}</div>}> + {button} + </Tooltip > : null } } @@ -559,8 +571,8 @@ ScriptingGlobals.add(function setHeaderColor(color?: string, checkResult?: boole // toggle: Set overlay status of selected document ScriptingGlobals.add(function toggleOverlay(checkResult?: boolean) { const selected = SelectionManager.Views().length ? SelectionManager.Views()[0] : undefined; - if (checkResult && selected) { - if (NumCast(selected.Document.z) >= 1) return Colors.MEDIUM_BLUE; + if (checkResult) { + if (NumCast(selected?.Document.z) >= 1) return Colors.MEDIUM_BLUE; return "transparent"; } selected ? selected.props.CollectionFreeFormDocumentView?.().float() : console.log("[FontIconBox.tsx] toggleOverlay failed"); @@ -656,13 +668,20 @@ ScriptingGlobals.add(function setFontHighlight(color?: string, checkResult?: boo ScriptingGlobals.add(function setFontSize(size: string | number, checkResult?: boolean) { const editorView = RichTextMenu.Instance?.TextView?.EditorView; if (checkResult) { - return (editorView ? RichTextMenu.Instance.fontSize : StrCast(Doc.UserDoc().fontSize, "10px")).replace("px", ""); + return RichTextMenu.Instance.fontSize.replace("px", ""); } if (typeof size === "number") size = size.toString(); if (size && Number(size).toString() === size) size += "px"; if (editorView) RichTextMenu.Instance.setFontSize(size); else Doc.UserDoc()._fontSize = size; }); +ScriptingGlobals.add(function toggleNoAutoLinkAnchor(checkResult?: boolean) { + const editorView = RichTextMenu.Instance?.TextView?.EditorView; + if (checkResult) { + return (editorView ? RichTextMenu.Instance.noAutoLink : false) ? Colors.MEDIUM_BLUE : "transparent"; + } + if (editorView) RichTextMenu.Instance?.toggleNoAutoLinkAnchor(); +}); ScriptingGlobals.add(function toggleBold(checkResult?: boolean) { const editorView = RichTextMenu.Instance?.TextView?.EditorView; @@ -692,36 +711,115 @@ ScriptingGlobals.add(function toggleItalic(checkResult?: boolean) { }); +export function checkInksToGroup() { + // console.log("getting here to inks group"); + if (CurrentUserUtils.ActiveTool === InkTool.Write) { + CollectionFreeFormView.collectionsWithUnprocessedInk.forEach(ffView => { + // TODO: nda - will probably want to go through ffView unprocessed docs and then see if any of the inksToGroup docs are in it and only use those + // find all inkDocs in ffView.unprocessedDocs that are within 200 pixels of each other + const inksToGroup = ffView.unprocessedDocs.filter(inkDoc => { + // console.log(inkDoc.x, inkDoc.y); + }); + }); + } +} + +export function createInkGroup(inksToGroup?: Doc[], isSubGroup?: boolean) { + // TODO nda - if document being added to is a inkGrouping then we can just add to that group + if (CurrentUserUtils.ActiveTool === InkTool.Write) { + CollectionFreeFormView.collectionsWithUnprocessedInk.forEach(ffView => { + // TODO: nda - will probably want to go through ffView unprocessed docs and then see if any of the inksToGroup docs are in it and only use those + const selected = ffView.unprocessedDocs; + // loop through selected an get the bound + const bounds: { x: number, y: number, width?: number, height?: number }[] = [] + + selected.map(action(d => { + const x = NumCast(d.x); + const y = NumCast(d.y); + const width = d[WidthSym](); + const height = d[HeightSym](); + bounds.push({ x, y, width, height }); + })) + + const aggregBounds = aggregateBounds(bounds, 0, 0); + const marqViewRef = ffView._marqueeViewRef.current; + + // set the vals for bounds in marqueeView + if (marqViewRef) { + marqViewRef._downX = aggregBounds.x; + marqViewRef._downY = aggregBounds.y; + marqViewRef._lastX = aggregBounds.r; + marqViewRef._lastY = aggregBounds.b; + } + + selected.map(action(d => { + const dx = NumCast(d.x); + const dy = NumCast(d.y); + delete d.x; + delete d.y; + delete d.activeFrame; + delete d._timecodeToShow; // bcz: this should be automatic somehow.. along with any other properties that were logically associated with the original collection + delete d._timecodeToHide; // bcz: this should be automatic somehow.. along with any other properties that were logically associated with the original collection + // calculate pos based on bounds + if (marqViewRef?.Bounds) { + d.x = dx - marqViewRef.Bounds.left - marqViewRef.Bounds.width / 2; + d.y = dy - marqViewRef.Bounds.top - marqViewRef.Bounds.height / 2; + } + return d; + })); + ffView.props.removeDocument?.(selected); + // TODO: nda - this is the code to actually get a new grouped collection + const newCollection = marqViewRef?.getCollection(selected, undefined, true); + if (newCollection) { + newCollection.height = newCollection[HeightSym](); + newCollection.width = newCollection[WidthSym](); + } + + // nda - bug: when deleting a stroke before leaving writing mode, delete the stroke from unprocessed ink docs + newCollection && ffView.props.addDocument?.(newCollection); + // TODO: nda - will probably need to go through and only remove the unprocessed selected docs + ffView.unprocessedDocs = []; + + InkTranscription.Instance.transcribeInk(newCollection, selected, false, ffView); + }); + } + CollectionFreeFormView.collectionsWithUnprocessedInk.clear(); +} /** INK - * setActiveInkTool + * setActiveTool * setStrokeWidth * setStrokeColor **/ -ScriptingGlobals.add(function setActiveInkTool(tool: string, checkResult?: boolean) { +ScriptingGlobals.add(function setActiveTool(tool: string, checkResult?: boolean) { + InkTranscription.Instance?.createInkGroup(); if (checkResult) { - return ((Doc.UserDoc().activeInkTool === tool && !GestureOverlay.Instance?.InkShape) || GestureOverlay.Instance?.InkShape === tool) ? + return ((CurrentUserUtils.ActiveTool === tool && !GestureOverlay.Instance?.InkShape) || GestureOverlay.Instance?.InkShape === tool) ? Colors.MEDIUM_BLUE : "transparent"; } if (["circle", "square", "line"].includes(tool)) { if (GestureOverlay.Instance.InkShape === tool) { - Doc.UserDoc().activeInkTool = InkTool.None; + CurrentUserUtils.ActiveTool = InkTool.None; GestureOverlay.Instance.InkShape = InkTool.None; } else { - Doc.UserDoc().activeInkTool = InkTool.Pen; + CurrentUserUtils.ActiveTool = InkTool.Pen; GestureOverlay.Instance.InkShape = tool; } } else if (tool) { // pen or eraser - if (Doc.UserDoc().activeInkTool === tool && !GestureOverlay.Instance.InkShape) { - Doc.UserDoc().activeInkTool = InkTool.None; + if (CurrentUserUtils.ActiveTool === tool && !GestureOverlay.Instance.InkShape) { + CurrentUserUtils.ActiveTool = InkTool.None; + } else if (tool == InkTool.Write) { + // console.log("write mode selected - create groupDoc here!", tool) + CurrentUserUtils.ActiveTool = tool; + GestureOverlay.Instance.InkShape = ""; } else { - Doc.UserDoc().activeInkTool = tool; + CurrentUserUtils.ActiveTool = tool as any; GestureOverlay.Instance.InkShape = ""; } } else { - Doc.UserDoc().activeInkTool = InkTool.None; + CurrentUserUtils.ActiveTool = InkTool.None; } }); @@ -805,9 +903,9 @@ ScriptingGlobals.add(function toggleSchemaPreview(checkResult?: boolean) { } else if (selected) { if (NumCast(selected.schemaPreviewWidth) > 0) { - selected.schemaPreviewWidth = 200; - } else { selected.schemaPreviewWidth = 0; + } else { + selected.schemaPreviewWidth = 200; } } }); |