aboutsummaryrefslogtreecommitdiff
path: root/src/client/views/nodes/FontIconBox/FontIconBox.tsx
diff options
context:
space:
mode:
Diffstat (limited to 'src/client/views/nodes/FontIconBox/FontIconBox.tsx')
-rw-r--r--src/client/views/nodes/FontIconBox/FontIconBox.tsx195
1 files changed, 110 insertions, 85 deletions
diff --git a/src/client/views/nodes/FontIconBox/FontIconBox.tsx b/src/client/views/nodes/FontIconBox/FontIconBox.tsx
index feaf84b7b..f699568f1 100644
--- a/src/client/views/nodes/FontIconBox/FontIconBox.tsx
+++ b/src/client/views/nodes/FontIconBox/FontIconBox.tsx
@@ -1,11 +1,13 @@
+import { Button, ColorPicker, Dropdown, DropdownType, IconButton, IListItemProps, MultiToggle, NumberDropdown, NumberDropdownType, Popup, Size, Toggle, ToggleType, Type } from '@dash/components';
import { IconProp } from '@fortawesome/fontawesome-svg-core';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
-import { Button, ColorPicker, Dropdown, DropdownType, IconButton, IListItemProps, MultiToggle, NumberDropdown, NumberDropdownType, Popup, Size, Toggle, ToggleType, Type } from 'browndash-components';
import { action, computed, makeObservable, observable } from 'mobx';
import { observer } from 'mobx-react';
import * as React from 'react';
-import { ClientUtils, returnFalse, returnTrue, setupMoveUpEvents } from '../../../../ClientUtils';
+import { ClientUtils, DashColor, returnFalse, returnTrue, setupMoveUpEvents } from '../../../../ClientUtils';
import { Doc, DocListCast, StrListCast } from '../../../../fields/Doc';
+import { InkTool } from '../../../../fields/InkField';
+import { ScriptField } from '../../../../fields/ScriptField';
import { BoolCast, DocCast, NumCast, ScriptCast, StrCast } from '../../../../fields/Types';
import { emptyFunction } from '../../../../Utils';
import { Docs } from '../../../documents/Documents';
@@ -126,11 +128,13 @@ export class FontIconBox extends ViewBoxBaseComponent<ButtonProps>() {
background={SnappingManager.userBackgroundColor}
numberDropdownType={type}
showPlusMinus={false}
- tooltip={this.label}
+ formLabel={(StrCast(this.Document.title).startsWith(' ') ? '\u00A0' : '') + StrCast(this.Document.title)}
+ tooltip={StrCast(this.Document.toolTip, this.label)}
type={Type.PRIM}
min={NumCast(this.dataDoc.numBtnMin, 0)}
max={NumCast(this.dataDoc.numBtnMax, 100)}
number={checkResult}
+ size={Size.XSMALL}
setNumber={undoable(value => numScript(value), `${this.Document.title} button set from list`)}
fillWidth
/>
@@ -149,73 +153,91 @@ export class FontIconBox extends ViewBoxBaseComponent<ButtonProps>() {
};
/**
+ * Displays custom dropdown menu for fonts -- this is a HACK -- fix for generality, don't copy
+ */
+ handleFontDropdown = (script: () => string, buttonList: string[]) => {
+ // text = StrCast((RichTextMenu.Instance?.TextView?.EditorView ? RichTextMenu.Instance : Doc.UserDoc()).fontFamily);
+ return {
+ buttonList,
+ jsx: undefined,
+ selectedVal: script(),
+ toolTip: 'Set text font',
+ getStyle: (val: string) => ({ fontFamily: val }),
+ };
+ };
+ /**
+ * Displays custom dropdown menu for view selection -- this is a HACK -- fix for generality, don't copy
+ */
+ handleViewDropdown = (script: ScriptField, buttonList: string[]) => {
+ const selected = Array.from(script?.script.run({ _readOnly_: true }).result as Doc[]);
+ const noviceList = [CollectionViewType.Freeform, CollectionViewType.Schema, CollectionViewType.Card, CollectionViewType.Carousel3D, CollectionViewType.Carousel, CollectionViewType.Stacking, CollectionViewType.NoteTaking];
+ return selected.length === 1 && selected[0].type === DocumentType.COL
+ ? {
+ buttonList: buttonList.filter(value => !Doc.noviceMode || !noviceList.length || noviceList.includes(value as CollectionViewType)),
+ getStyle: undefined,
+ selectedVal: StrCast(selected[0]._type_collection),
+ toolTip: 'change view type (press Shift to add as a new view)',
+ }
+ : {
+ jsx: selected.length ? (
+ <Popup
+ icon={<FontAwesomeIcon size="1x" icon={selected.length > 1 ? 'caret-down' : (Doc.toIcon(selected.lastElement()) as IconProp)} />}
+ text={selected.length === 1 ? ClientUtils.cleanDocumentType(StrCast(selected[0].type) as DocumentType) : selected.length + ' selected'}
+ type={Type.TERT}
+ color={SnappingManager.userColor}
+ background={SnappingManager.userVariantColor}
+ popup={<SelectedDocView selectedDocs={selected} />}
+ fillWidth
+ />
+ ) : (
+ <Button
+ text={`${Doc.ActiveTool === InkTool.None ? 'Text box' : Doc.ActiveInk} defaults`} //
+ type={Type.TERT}
+ color={SnappingManager.userColor}
+ background={SnappingManager.userVariantColor}
+ fillWidth
+ inactive
+ />
+ ),
+ };
+ };
+
+ /**
* Dropdown list
*/
@computed get dropdownListButton() {
const script = ScriptCast(this.Document.script);
-
- let noviceList: string[] = [];
- let text: string | undefined;
- let getStyle: (val: string) => { [key: string]: string } = () => ({});
- let icon: IconProp = 'caret-down';
- const isViewDropdown = script?.script.originalScript.startsWith('{ return setView');
- if (isViewDropdown) {
- const selected = Array.from(script?.script.run({ _readOnly_: true }).result as Doc[]);
- // const selected = DocumentView.SelectedDocs();
- if (selected.lastElement()) {
- if (StrCast(selected.lastElement().type) === DocumentType.COL) {
- text = StrCast(selected.lastElement()._type_collection);
- } else {
- if (selected.length > 1) {
- text = selected.length + ' selected';
- } else {
- text = ClientUtils.cleanDocumentType(StrCast(selected.lastElement().type) as DocumentType, '' as CollectionViewType);
- icon = Doc.toIcon(selected.lastElement());
- }
- return (
- <Popup
- icon={<FontAwesomeIcon size="1x" icon={icon} />}
- text={text}
- type={Type.TERT}
- color={SnappingManager.userColor}
- background={SnappingManager.userVariantColor}
- popup={<SelectedDocView selectedDocs={selected} />}
- fillWidth
- />
- );
- }
- } else {
- return <Button text="None Selected" type={Type.TERT} color={SnappingManager.userColor} background={SnappingManager.userVariantColor} fillWidth inactive />;
- }
- noviceList = [CollectionViewType.Freeform, CollectionViewType.Schema, CollectionViewType.Carousel3D, CollectionViewType.Stacking, CollectionViewType.NoteTaking];
- } else {
- text = script?.script.run({ this: this.Document, value: '', _readOnly_: true }).result as string;
- // text = StrCast((RichTextMenu.Instance?.TextView?.EditorView ? RichTextMenu.Instance : Doc.UserDoc()).fontFamily);
- if (this.Document.title === 'Font') getStyle = (val: string) => ({ fontFamily: val }); // bcz: major hack to style the font dropdown items --- needs to become part of the dropdown's metadata
- }
+ const selectedFunc = () => script?.script.run({ this: this.Document, value: '', _readOnly_: true }).result as string;
+ const { buttonList, selectedVal, getStyle, jsx, toolTip } = (() => {
+ switch (this.Document.title) {
+ case 'Font': return this.handleFontDropdown(selectedFunc, this.buttonList);
+ case 'Perspective': return this.handleViewDropdown(script, this.buttonList);
+ default: return { buttonList: this.buttonList, selectedVal: selectedFunc(), toolTip: undefined, jsx: undefined, getStyle: undefined };
+ } // prettier-ignore
+ })();
+ if (jsx) return jsx;
// Get items to place into the list
- const list: IListItemProps[] = this.buttonList
- .filter(value => !Doc.noviceMode || !noviceList.length || noviceList.includes(value))
- .map(value => ({
- text: typeof value === 'string' ? value.charAt(0).toUpperCase() + value.slice(1) : StrCast(DocCast(value)?.title),
- val: value,
- style: getStyle(value),
- // shortcut: '#',
- }));
+ const list: IListItemProps[] = buttonList.map(value => ({
+ text: typeof value === 'string' ? value.charAt(0).toUpperCase() + value.slice(1) : StrCast(DocCast(value)?.title),
+ val: value,
+ style: getStyle?.(value),
+ // shortcut: '#',
+ }));
return (
<Dropdown
- selectedVal={text}
- setSelectedVal={undoable(value => script.script.run({ this: this.Document, value }), `dropdown select ${this.label}`)}
+ selectedVal={selectedVal}
+ setSelectedVal={undoable((value, e) => script.script.run({ this: this.Document, value, shiftKey: e.shiftKey }), `dropdown select ${this.label}`)}
color={SnappingManager.userColor}
background={SnappingManager.userVariantColor}
+ toolTip={toolTip}
type={Type.TERT}
closeOnSelect={false}
dropdownType={DropdownType.SELECT}
onItemDown={this.dropdownItemDown}
items={list}
- tooltip={this.label}
+ tooltip={StrCast(this.Document.toolTip, this.label)}
fillWidth
/>
);
@@ -235,49 +257,50 @@ export class FontIconBox extends ViewBoxBaseComponent<ButtonProps>() {
const tooltip: string = StrCast(this.Document.toolTip);
return (
- <ColorPicker
- setSelectedColor={value => {
- if (!this.colorBatch) this.colorBatch = UndoManager.StartBatch(`Set ${tooltip} color`);
- this.colorScript?.script.run({ this: this.Document, value: value, _readOnly_: false });
- }}
- setFinalColor={value => {
- this.colorScript?.script.run({ this: this.Document, value: value, _readOnly_: false });
- this.colorBatch?.end();
- this.colorBatch = undefined;
- }}
- defaultPickerType="Classic"
- selectedColor={curColor}
- type={Type.PRIM}
- color={color}
- background={SnappingManager.userBackgroundColor}
- icon={this.Icon(color) ?? undefined}
- tooltip={tooltip}
- label={this.label}
- />
+ <div onPointerDown={e => e.stopPropagation()}>
+ <ColorPicker
+ setSelectedColor={value => {
+ if (!this.colorBatch) this.colorBatch = UndoManager.StartBatch(`Set ${tooltip} color`);
+ this.colorScript?.script.run({ this: this.Document, value: value, _readOnly_: false });
+ }}
+ setFinalColor={value => {
+ this.colorScript?.script.run({ this: this.Document, value: value, _readOnly_: false });
+ this.colorBatch?.end();
+ this.colorBatch = undefined;
+ }}
+ defaultPickerType="Classic"
+ selectedColor={curColor}
+ type={Type.PRIM}
+ color={color}
+ background={SnappingManager.userBackgroundColor}
+ icon={this.Icon(color) ?? undefined}
+ tooltip={tooltip}
+ label={this.label}
+ />
+ </div>
);
}
@computed get multiToggleButton() {
- // Determine the type of toggle button
- const tooltip: string = StrCast(this.Document.toolTip);
+ const tooltip = StrCast(this.Document.toolTip);
const script = ScriptCast(this.Document.onClick)?.script;
const toggleStatus = script?.run({ this: this.Document, value: undefined, _readOnly_: true }).result as boolean;
- // Colors
+
const color = this._props.styleProvider?.(this.layoutDoc, this._props, StyleProp.Color) as string;
- const background = this._props.styleProvider?.(this.layoutDoc, this._props, StyleProp.BackgroundColor) as string;
const items = DocListCast(this.dataDoc.data);
const selectedItems = items.filter(itemDoc => ScriptCast(itemDoc.onClick).script.run({ this: itemDoc, value: undefined, _readOnly_: true }).result).map(item => StrCast(item.toolType));
+
return (
<MultiToggle
- tooltip={`Toggle ${tooltip}`}
+ tooltip={`Click to Toggle ${tooltip} or select new option`}
type={Type.PRIM}
color={color}
- background={background === SnappingManager.userBackgroundColor ? undefined : background}
+ background={undefined}
multiSelect={true}
onPointerDown={e => script && !toggleStatus && setupMoveUpEvents(this, e, returnFalse, emptyFunction, () => script.run({ this: this.Document, value: undefined, _readOnly_: false }))}
isToggle={false}
toggleStatus={toggleStatus}
- label={this.label}
+ label={selectedItems.length === 1 ? selectedItems[0] : this.label}
items={items.map(item => ({
icon: <FontAwesomeIcon className={`fontIconBox-icon-${this.type}`} icon={StrCast(item.icon) as IconProp} color={color} />,
tooltip: StrCast(item.toolTip),
@@ -290,7 +313,7 @@ export class FontIconBox extends ViewBoxBaseComponent<ButtonProps>() {
// it would be better to pas the 'added' flag to the callback script, but our script generator from currentUserUtils makes it hard to define
// arbitrary parameter variables (but it could be done as a special case or with additional effort when creating the sript)
const itemsChanged = items.filter(item => (val instanceof Array ? val.includes(item.toolType as string | number) : item.toolType === val));
- itemsChanged.forEach(itemDoc => ScriptCast(itemDoc.onClick).script.run({ this: itemDoc, _added_: added, itemDoc, _readOnly_: false }));
+ itemsChanged.forEach(itemDoc => ScriptCast(itemDoc.onClick).script.run({ this: itemDoc, _added_: added, value: toggleStatus, itemDoc, _readOnly_: false }));
}}
/>
);
@@ -308,17 +331,19 @@ export class FontIconBox extends ViewBoxBaseComponent<ButtonProps>() {
const toggleStatus = (script?.script.run({ this: this.Document, value: undefined, _readOnly_: true }).result as boolean) ?? false;
// Colors
const color = this._props.styleProvider?.(this.layoutDoc, this._props, StyleProp.Color) as string;
- // const backgroundColor = this._props.styleProvider?.(this.layoutDoc, this._props, StyleProp.BackgroundColor);
+ // bcz: ink shapes are tri-state - off, one-shot, and on. Need to update Toggle buttons to allow this and update currentUserUtils to set the tri-state on the Doc
+ // in the meantime, if the button matches a tool type that is not locked, we want to set the background color to something distinct.
+ const inkShapeHack = ((this.Document.toolType && this.Document.toolType === SnappingManager.InkShape) || this.Document.toolType === Doc.ActiveTool) && !SnappingManager.KeepGestureMode;
return (
<Toggle
tooltip={`Toggle ${tooltip}`}
toggleType={ToggleType.BUTTON}
- type={Type.PRIM}
+ type={inkShapeHack ? Type.TERT : Type.PRIM}
toggleStatus={toggleStatus}
text={buttonText}
color={color}
- // background={SnappingManager.userBackgroundColor}
+ background={inkShapeHack ? DashColor(SnappingManager.userBackgroundColor).darken(0.05).toString() : undefined}
icon={this.Icon(color)!}
label={this.label}
onPointerDown={e =>
@@ -392,7 +417,7 @@ export class FontIconBox extends ViewBoxBaseComponent<ButtonProps>() {
render() {
return (
- <div style={{ margin: 'auto', width: '100%' }} onContextMenu={this.specificContextMenu}>
+ <div className="fonticonbox" onContextMenu={this.specificContextMenu}>
{this.renderButton()}
</div>
);