import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; import { Tooltip } from '@material-ui/core'; 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 { createSchema, makeInterface } from '../../../../fields/Schema'; import { ScriptField } from '../../../../fields/ScriptField'; import { BoolCast, Cast, StrCast, ScriptCast } from '../../../../fields/Types'; import { SelectionManager } from '../../../util/SelectionManager'; import { ColorScheme } from '../../../util/SettingsManager'; import { undoBatch, UndoManager } from '../../../util/UndoManager'; import { ContextMenu } from '../../ContextMenu'; import { DocComponent } from '../../DocComponent'; import { StyleProp } from '../../StyleProvider'; import { FieldView, FieldViewProps } from '.././FieldView'; import './FontIconBox.scss'; const FontIconSchema = createSchema({ icon: "string", }); export enum ButtonType { MenuButton = "menuBtn", DropdownList = "drpdownList", DropdownButton = "drpdownBtn", ClickButton = "clickBtn", DoubleButton = "dblBtn", ToggleButton = "tglBtn", ColorButton = "colorBtn", ToolButton = "toolBtn" } export interface ButtonProps extends FieldViewProps { type?: ButtonType; } type FontIconDocument = makeInterface<[typeof FontIconSchema]>; const FontIconDocument = makeInterface(FontIconSchema); @observer export class FontIconBox extends DocComponent(FontIconDocument) { public static LayoutString(fieldKey: string) { return FieldView.LayoutString(FontIconBox, fieldKey); } showTemplate = (): void => { const dragFactory = Cast(this.layoutDoc.dragFactory, Doc, null); dragFactory && this.props.addDocTab(dragFactory, "add:right"); } dragAsTemplate = (): void => { this.layoutDoc.onDragStart = ScriptField.MakeFunction('getCopy(this.dragFactory, true)'); }; useAsPrototype = (): void => { this.layoutDoc.onDragStart = ScriptField.MakeFunction('makeDelegate(this.dragFactory, true)'); }; specificContextMenu = (): void => { if (!Doc.UserDoc().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" }); cm.addItem({ description: "Use as Prototype", event: this.useAsPrototype, icon: "tag" }); } } // Determining UI Specs @observable private label = StrCast(this.rootDoc.label, StrCast(this.rootDoc.title)); @observable private icon = StrCast(this.dataDoc.icon, "user") as any; @observable private dropdown: boolean = BoolCast(this.rootDoc.dropDownOpen); @observable private dropdownDirection: string = StrCast(this.rootDoc.dropDownDirection); @observable private buttonList: string[] = StrListCast(this.rootDoc.btnList); @observable private type = StrCast(this.rootDoc.btnType); /** * Types of buttons in dash: * - Main menu button (LHS) * - Tool button * - Expandable button (CollectionLinearView) * - Button inside of CollectionLinearView vs. outside of CollectionLinearView * - Action button * - Dropdown button * - Color button * - Dropdown list **/ /** * Dropdown button */ @computed get dropdownButton() { const active: string = StrCast(this.rootDoc.dropDownOpen); const color = this.props.styleProvider?.(this.rootDoc, this.props, StyleProp.Color); const backgroundColor = this.props.styleProvider?.(this.rootDoc, this.props, StyleProp.BackgroundColor); return (
this.rootDoc.dropDownOpen = !this.rootDoc.dropDownOpen)}> {!this.label || !Doc.UserDoc()._showLabel ? (null) :
{this.label}
}
{this.rootDoc.dropDownOpen ?
{/* DROPDOWN BOX CONTENTS */}
: null}
); } /** * Dropdown button */ @computed get dropdownListButton() { const active: string = StrCast(this.rootDoc.dropDownOpen); const color = this.props.styleProvider?.(this.rootDoc, this.props, StyleProp.Color); const backgroundColor = this.props.styleProvider?.(this.rootDoc, this.props, StyleProp.BackgroundColor); const script: string = StrCast(this.rootDoc.script); let noviceList: string[] = []; let text:string | undefined; let dropdown = true; let show = true; let icon: IconProp = "caret-down"; if (script == 'changeView'){ const selected = SelectionManager.Views().length ? SelectionManager.Views()[0] : undefined; if (selected && StrCast(selected.Document.type) == DocumentType.COL){ text = StrCast(selected.Document._viewType); } else if (selected) { dropdown = false; text = StrCast(selected.Document.type); icon = Doc.toIcon(selected.Document); } noviceList = [CollectionViewType.Freeform, CollectionViewType.Schema, CollectionViewType.Stacking]; } else if (script == 'changeFont') { const selected = SelectionManager.Views().length ? SelectionManager.Views()[0] : undefined; if (selected && StrCast(selected.Document.type) == DocumentType.RTF){ text = StrCast(selected.Document._fontFamily); } else { text = StrCast(Doc.UserDoc()._fontFamily); } noviceList = ["Roboto", "Times New Roman", "Arial", "Georgia", "Comic Sans MS", "Tahoma", "Impact", "Crimson Text"]; } else { show = false; } const items = this.buttonList.map((value) => { // console.log(value); if (Doc.UserDoc().noviceMode && !noviceList.includes(value)){ return; } const click = () => { const s = ScriptField.MakeScript(script+'("'+value+'")'); if (s){ // console.log(s.script); s.script.run().result; } } return
{value[0].toUpperCase() + value.slice(1)}
; }); const label = !this.label || !Doc.UserDoc()._showLabel ? (null) :
{this.label}
; return (
this.rootDoc.dropDownOpen = !this.rootDoc.dropDownOpen : undefined}>
{text && text[0].toUpperCase() + text.slice(1)}
{label}
{this.rootDoc.dropDownOpen ?
{items}
{ e.stopPropagation(); this.rootDoc.dropDownOpen = false; }} />
: null}
); } @computed get rangeButton() { return (
) } /** * Colour button */ @computed get colorButton() { const active: string = StrCast(this.rootDoc.dropDownOpen); const color = this.props.styleProvider?.(this.rootDoc, this.props, StyleProp.Color); const backgroundColor = this.props.styleProvider?.(this.rootDoc, this.props, StyleProp.BackgroundColor); const numSelected = SelectionManager.Views().length; const selectedDoc = numSelected > 0 ? SelectionManager.Views()[0].Document : undefined; const colorBox = (func: (color: ColorState) => void) => ; const label = !this.label || !Doc.UserDoc()._showLabel ? (null) :
{this.label}
; const dropdownCaret =
; const script: string = StrCast(this.rootDoc.script); const click = (value: ColorState) => { const hex: string = value.hex; const s = ScriptField.MakeScript(script+'("'+hex+'")'); if (s){ // console.log(s.script); s.script.run().result; } } return (
this.rootDoc.dropDownOpen = !this.rootDoc.dropDownOpen} onPointerDown={e => e.stopPropagation()}> {label} {dropdownCaret} {this.rootDoc.dropDownOpen ?
e.stopPropagation()} onClick={e => e.stopPropagation()} style={{ left: 0 }}> {colorBox((color) => click(color))}
{ e.stopPropagation(); this.rootDoc.dropDownOpen = false; }} />
: null}
); } @computed get toggleButton() { const numSelected = SelectionManager.Views().length; const selectedDoc = numSelected > 0 ? SelectionManager.Views()[0].Document : undefined; const script: string = StrCast(this.rootDoc.script)+"(true)"; let toggleTrue: boolean | undefined = false; if (script == 'toggleOverlay'){ toggleTrue = selectedDoc && BoolCast(selectedDoc.z); console.log('toggleOverlay'); } const boolResult = ScriptField.MakeScript(script)?.script.run().result; // console.log(this.rootDoc.title, script, boolResult); const color = this.props.styleProvider?.(this.rootDoc, this.props, StyleProp.Color); const backgroundColor = this.props.styleProvider?.(this.rootDoc, this.props, StyleProp.BackgroundColor); // const canClick: boolean = this.rootDoc.canClick ? eval(StrCast(this.rootDoc.canClick)) : false; const label = !this.label || !Doc.UserDoc()._showLabel ? (null) :
{this.label}
; return (
{label}
) } /** * Default */ @computed get defaultButton() { const color = this.props.styleProvider?.(this.rootDoc, this.props, StyleProp.Color); const backgroundColor = this.props.styleProvider?.(this.rootDoc, this.props, StyleProp.BackgroundColor); const active: string = StrCast(this.rootDoc.dropDownOpen); return (
{!this.label || !Doc.UserDoc()._showLabel ? (null) :
{this.label}
} {/* */}
) } render() { const color = this.props.styleProvider?.(this.rootDoc, this.props, StyleProp.Color); const backgroundColor = this.props.styleProvider?.(this.rootDoc, this.props, StyleProp.BackgroundColor); // Variables called through eval (from button) const canUndo: boolean = UndoManager.CanUndo(); const canRedo: boolean = UndoManager.CanRedo(); const numSelected = SelectionManager.Views().length; const selectedDoc = numSelected > 0 ? SelectionManager.Views()[0].Document : undefined; const userDoc = Doc.UserDoc(); const dark: boolean = Doc.UserDoc().colorScheme === ColorScheme.Dark; const active: string = StrCast(this.rootDoc.dropDownOpen); const label = !this.label || !Doc.UserDoc()._showLabel ? (null) :
{this.label}
; const menuLabel = !this.label || !Doc.UserDoc()._showMenuLabel ? (null) :
{this.label}
; // TODO:glr Add label of button type let button = this.defaultButton; switch (this.type) { case ButtonType.DropdownButton: button = this.dropdownButton; break; case ButtonType.DropdownList: button = this.dropdownListButton; break; case ButtonType.ColorButton: button = this.colorButton; break; case ButtonType.ToolButton: button = (
{label}
); break; case ButtonType.ToggleButton: button = this.toggleButton; break; case ButtonType.ClickButton: button = (
{label}
); break; case ButtonType.DoubleButton: button = (
{label}
); break; case ButtonType.MenuButton: button = (
{menuLabel}
); break; default: break; } return !this.layoutDoc.toolTip || this.type === ButtonType.DropdownList || this.type === ButtonType.ColorButton ? button : {StrCast(this.layoutDoc.toolTip)}
}> {button} ; } } // SCRIPTING BUTTONS import { Scripting } from "../../../util/Scripting"; import { CollectionViewType } from '../../collections/CollectionView'; import { DocumentType } from '../../../documents/DocumentTypes'; import { Colors } from '../../global/globalEnums'; import { IconProp } from '@fortawesome/fontawesome-svg-core'; // toggle: Set overlay status of selected document Scripting.addGlobal(function changeView(view: string) { const selected = SelectionManager.Views().length ? SelectionManager.Views()[0] : undefined; selected ? selected.Document._viewType = view : console.log("[FontIconBox.tsx] changeView failed"); }); // toggle: Set overlay status of selected document Scripting.addGlobal(function changeBackgroundColor(color?: string, checkResult?: boolean) { const selected = SelectionManager.Views().length ? SelectionManager.Views()[0] : undefined; if (checkResult){ return selected && selected.Document._backgroundColor; } selected ? selected.Document._backgroundColor = color : console.log("[FontIconBox.tsx] changeBackgroundColor failed"); }); // toggle: Set overlay status of selected document Scripting.addGlobal(function toggleOverlay(checkResult?:boolean) { const selected = SelectionManager.Views().length ? SelectionManager.Views()[0] : undefined; if (checkResult){ return selected && selected.Document.z == 1; } selected ? selected.props.CollectionFreeFormDocumentView?.().float() : console.log("[FontIconBox.tsx] toggleOverlay failed"); }); // toggle: Set overlay status of selected document Scripting.addGlobal(function changeFont(font: string) { // TODO: glr check if font selected and change selected font SelectionManager.Views().map(dv => dv.props.Document._fontFamily = font); console.log(font); Doc.UserDoc()._fontFamily = font; return Doc.UserDoc()._fontFamily; }); // toggle: Set overlay status of selected document Scripting.addGlobal(function changeFontColor(color: string) { // TODO: glr check if font selected and change selected font console.log(color); Doc.UserDoc()._fontColor = color; }); // toggle: Set overlay status of selected document Scripting.addGlobal(function changeFontSize(size: string) { // TODO: glr check if font selected and change selected font console.log(size); Doc.UserDoc()._fontSize = size; }); Scripting.addGlobal(function toggleBold(checkResult?:boolean) { if(checkResult) { console.log("got here"); return Doc.UserDoc().bold; } // TODO: glr check if font selected and change selected font SelectionManager.Views().map(dv => dv.props.Document.bold = !dv.props.Document.bold); Doc.UserDoc().bold = !Doc.UserDoc().bold; return Doc.UserDoc().bold; }); Scripting.addGlobal(function toggleUnderline(checkResult?:boolean) { if(checkResult) return Doc.UserDoc().underline; // TODO: glr check if font selected and change selected font SelectionManager.Views().map(dv => dv.props.Document.underline = !dv.props.Document.underline); Doc.UserDoc().bold = !Doc.UserDoc().underline; return Doc.UserDoc().underline; }); Scripting.addGlobal(function toggleItalic(checkResult?:boolean) { if(checkResult) return Doc.UserDoc().italic; // TODO: glr check if font selected and change selected font SelectionManager.Views().map(dv => dv.props.Document.italic = !dv.props.Document.italic); Doc.UserDoc().bold = !Doc.UserDoc().italic; return Doc.UserDoc().italic; });