import { action, makeObservable, reaction } from 'mobx'; import { observer } from 'mobx-react'; import * as React from 'react'; import { DivHeight, DivWidth } from '../../../Utils'; import { Id } from '../../../fields/FieldSymbols'; import { NumCast, StrCast } from '../../../fields/Types'; import { TraceMobx } from '../../../fields/util'; import { DocUtils, Docs } from '../../documents/Documents'; import { undoBatch } from '../../util/UndoManager'; import { ViewBoxBaseComponent } from '../DocComponent'; import { LightboxView } from '../LightboxView'; import './EquationBox.scss'; import { FieldView, FieldViewProps } from './FieldView'; import EquationEditor from './formattedText/EquationEditor'; @observer export class EquationBox extends ViewBoxBaseComponent() { public static LayoutString(fieldKey: string) { return FieldView.LayoutString(EquationBox, fieldKey); } public static SelectOnLoad: string = ''; _ref: React.RefObject = React.createRef(); constructor(props: FieldViewProps) { super(props); makeObservable(this); } componentDidMount() { this._props.setContentViewBox?.(this); if (EquationBox.SelectOnLoad === this.Document[Id] && (!LightboxView.LightboxDoc || LightboxView.Contains(this.DocumentView?.()))) { this._props.select(false); this._ref.current!.mathField.focus(); this.dataDoc.text === 'x' && this._ref.current!.mathField.select(); EquationBox.SelectOnLoad = ''; } reaction( () => StrCast(this.dataDoc.text), text => { if (text && text !== this._ref.current!.mathField.latex()) { this._ref.current!.mathField.latex(text); } } //{ fireImmediately: true } ); reaction( () => this._props.isSelected(), selected => { if (this._ref.current) { if (selected) this._ref.current.element.current.children[0].addEventListener('keydown', this.keyPressed, true); else this._ref.current.element.current.children[0].removeEventListener('keydown', this.keyPressed); } }, { fireImmediately: true } ); } @action keyPressed = (e: KeyboardEvent) => { const _height = DivHeight(this._ref.current!.element.current); const _width = DivWidth(this._ref.current!.element.current); if (e.key === 'Enter') { const nextEq = Docs.Create.EquationDocument(e.shiftKey ? StrCast(this.dataDoc.text) : 'x', { title: '# math', _width, _height: 25, x: NumCast(this.layoutDoc.x), y: NumCast(this.layoutDoc.y) + _height + 10, }); EquationBox.SelectOnLoad = nextEq[Id]; this._props.addDocument?.(nextEq); e.stopPropagation(); } if (e.key === 'Tab') { const graph = Docs.Create.FunctionPlotDocument([this.Document], { x: NumCast(this.layoutDoc.x) + NumCast(this.layoutDoc._width), y: NumCast(this.layoutDoc.y), _width: 400, _height: 300, backgroundColor: 'white', }); const link = DocUtils.MakeLink(this.Document, graph, { link_relationship: 'function', link_description: 'input' }); this._props.addDocument?.(graph); link && this._props.addDocument?.(link); e.stopPropagation(); } if (e.key === 'Backspace' && !this.dataDoc.text) this._props.removeDocument?.(this.Document); }; @undoBatch onChange = (str: string) => (this.dataDoc.text = str); updateSize = () => { const style = this._ref.current && getComputedStyle(this._ref.current.element.current); if (style?.width.endsWith('px') && style?.height.endsWith('px')) { if (this.layoutDoc._nativeWidth) { // if equation has been scaled then editing the expression must also edit the native dimensions to keep the aspect ratio const prevNwidth = NumCast(this.layoutDoc._nativeWidth); const newNwidth = (this.layoutDoc._nativeWidth = Math.max(35, Number(style.width.replace('px', '')))); const newNheight = (this.layoutDoc._nativeHeight = Math.max(25, Number(style.height.replace('px', '')))); this.layoutDoc._width = (NumCast(this.layoutDoc._width) * NumCast(this.layoutDoc._nativeWidth)) / prevNwidth; this.layoutDoc._height = (NumCast(this.layoutDoc._width) * newNheight) / newNwidth; } else { this.layoutDoc._width = Math.max(35, Number(style.width.replace('px', ''))); this.layoutDoc._height = Math.max(25, Number(style.height.replace('px', ''))); } } }; render() { TraceMobx(); const scale = (this._props.NativeDimScaling?.() || 1) * NumCast(this.layoutDoc._freeform_scale, 1); return (
this.updateSize()} className="equationBox-cont" onPointerDown={e => !e.ctrlKey && e.stopPropagation()} style={{ transform: `scale(${scale})`, width: 'fit-content', // `${100 / scale}%`, height: `${100 / scale}%`, pointerEvents: !this._props.isSelected() ? 'none' : undefined, fontSize: StrCast(this.layoutDoc._text_fontSize), }} onKeyDown={e => e.stopPropagation()}>
); } }