aboutsummaryrefslogtreecommitdiff
path: root/src/client/views/nodes/button/FontIconBox.tsx
diff options
context:
space:
mode:
Diffstat (limited to 'src/client/views/nodes/button/FontIconBox.tsx')
-rw-r--r--src/client/views/nodes/button/FontIconBox.tsx200
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;
}
}
});