diff options
| author | bobzel <zzzman@gmail.com> | 2021-03-02 12:39:58 -0500 |
|---|---|---|
| committer | bobzel <zzzman@gmail.com> | 2021-03-02 12:39:58 -0500 |
| commit | faf9dc5ca6a7380f3b040dc2ddbe07c29689e014 (patch) | |
| tree | d76e7668597a72f496e7ea3ed4f1a14125c6c9ef /src/client/views/nodes/formattedText | |
| parent | c41696a3169dc765512d64972ba4503cea8393e0 (diff) | |
some cleanup and extensions to Equationbox stuff. can sort of be nested in text docs with ctrl-m.
Diffstat (limited to 'src/client/views/nodes/formattedText')
5 files changed, 102 insertions, 12 deletions
diff --git a/src/client/views/nodes/formattedText/DashFieldView.tsx b/src/client/views/nodes/formattedText/DashFieldView.tsx index b39a845db..62f65cdae 100644 --- a/src/client/views/nodes/formattedText/DashFieldView.tsx +++ b/src/client/views/nodes/formattedText/DashFieldView.tsx @@ -1,18 +1,18 @@ -import { IReactionDisposer, observable, computed, action } from "mobx"; -import { Doc, DocListCast, Field, DataSym } from "../../../../fields/Doc"; +import { action, computed, IReactionDisposer, observable } from "mobx"; +import { observer } from "mobx-react"; +import * as ReactDOM from 'react-dom'; +import { DataSym, Doc, DocListCast, Field } from "../../../../fields/Doc"; import { List } from "../../../../fields/List"; import { listSpec } from "../../../../fields/Schema"; import { SchemaHeaderField } from "../../../../fields/SchemaHeaderField"; import { ComputedField } from "../../../../fields/ScriptField"; import { Cast, StrCast } from "../../../../fields/Types"; import { DocServer } from "../../../DocServer"; +import { DocUtils } from "../../../documents/Documents"; import { CollectionViewType } from "../../collections/CollectionView"; +import "./DashFieldView.scss"; import { FormattedTextBox } from "./FormattedTextBox"; import React = require("react"); -import * as ReactDOM from 'react-dom'; -import "./DashFieldView.scss"; -import { observer } from "mobx-react"; -import { DocUtils } from "../../../documents/Documents"; export class DashFieldView { _fieldWrapper: HTMLDivElement; // container for label and value diff --git a/src/client/views/nodes/formattedText/EquationView.tsx b/src/client/views/nodes/formattedText/EquationView.tsx new file mode 100644 index 000000000..eff018635 --- /dev/null +++ b/src/client/views/nodes/formattedText/EquationView.tsx @@ -0,0 +1,75 @@ +import EquationEditor from "equation-editor-react"; +import { IReactionDisposer } from "mobx"; +import { observer } from "mobx-react"; +import * as ReactDOM from 'react-dom'; +import { Doc } from "../../../../fields/Doc"; +import { StrCast } from "../../../../fields/Types"; +import "./DashFieldView.scss"; +import { FormattedTextBox } from "./FormattedTextBox"; +import React = require("react"); + +export class EquationView { + _fieldWrapper: HTMLDivElement; // container for label and value + + constructor(node: any, view: any, getPos: any, tbox: FormattedTextBox) { + this._fieldWrapper = document.createElement("div"); + this._fieldWrapper.style.width = node.attrs.width; + this._fieldWrapper.style.height = node.attrs.height; + this._fieldWrapper.style.fontWeight = "bold"; + this._fieldWrapper.style.position = "relative"; + this._fieldWrapper.style.display = "inline-block"; + this._fieldWrapper.onkeypress = function (e: any) { e.stopPropagation(); }; + this._fieldWrapper.onkeydown = function (e: any) { e.stopPropagation(); }; + this._fieldWrapper.onkeyup = function (e: any) { e.stopPropagation(); }; + this._fieldWrapper.onmousedown = function (e: any) { e.stopPropagation(); }; + + ReactDOM.render(<EquationViewInternal + fieldKey={node.attrs.fieldKey} + width={node.attrs.width} + height={node.attrs.height} + tbox={tbox} + />, this._fieldWrapper); + (this as any).dom = this._fieldWrapper; + } + destroy() { ReactDOM.unmountComponentAtNode(this._fieldWrapper); } + selectNode() { } +} + +interface IEquationViewInternal { + fieldKey: string; + tbox: FormattedTextBox; + width: number; + height: number; +} + +@observer +export class EquationViewInternal extends React.Component<IEquationViewInternal> { + _reactionDisposer: IReactionDisposer | undefined; + _textBoxDoc: Doc; + _fieldKey: string; + + constructor(props: IEquationViewInternal) { + super(props); + this._fieldKey = this.props.fieldKey; + this._textBoxDoc = this.props.tbox.props.Document; + } + + componentWillUnmount() { this._reactionDisposer?.(); } + + render() { + return <div className="equationView" style={{ + position: "relative", + display: "inline-block", + width: this.props.width, + height: this.props.height, + }}> + <EquationEditor + value={StrCast(this._textBoxDoc[this._fieldKey], "y=")} + onChange={str => this._textBoxDoc[this._fieldKey] = str} + autoCommands="pi theta sqrt sum prod alpha beta gamma rho" + autoOperatorNames="sin cos tan" + spaceBehavesLikeTab={true} + /> + </div >; + } +}
\ No newline at end of file diff --git a/src/client/views/nodes/formattedText/FormattedTextBox.tsx b/src/client/views/nodes/formattedText/FormattedTextBox.tsx index 5066578aa..104d60fff 100644 --- a/src/client/views/nodes/formattedText/FormattedTextBox.tsx +++ b/src/client/views/nodes/formattedText/FormattedTextBox.tsx @@ -40,6 +40,7 @@ import { DashDocView } from "./RichTextSchema"; import { DashDocCommentView } from "./DashDocCommentView"; import { DashFieldView } from "./DashFieldView"; +import { EquationView } from "./EquationView"; import { SummaryView } from "./SummaryView"; import { OrderedListView } from "./OrderedListView"; import { FootnoteView } from "./FootnoteView"; @@ -596,7 +597,8 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp const options = cm.findByDescription("Options..."); const optionItems = options && "subitems" in options ? options.subitems : []; - !Doc.UserDoc().noviceMode && optionItems.push({ description: !this.Document._singleLine ? "Make Single Line" : "Make Multi Line", event: () => this.layoutDoc._singleLine = !this.layoutDoc._singleLine, icon: "expand-arrows-alt" }); + optionItems.push({ description: !this.Document._noSidebar ? "Hide Sidebar Handle" : "Show Sidebar Handle", event: () => this.layoutDoc._noSidebar = !this.layoutDoc._noSidebar, icon: "expand-arrows-alt" }); + optionItems.push({ description: !this.Document._singleLine ? "Make Single Line" : "Make Multi Line", event: () => this.layoutDoc._singleLine = !this.layoutDoc._singleLine, icon: "expand-arrows-alt" }); optionItems.push({ description: `${this.Document._autoHeight ? "Lock" : "Auto"} Height`, event: () => this.layoutDoc._autoHeight = !this.layoutDoc._autoHeight, icon: "plus" }); !options && cm.addItem({ description: "Options...", subitems: optionItems, icon: "eye" }); this._downX = this._downY = Number.NaN; @@ -745,7 +747,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp // Since we also monitor all component height changes, this will update the document's height. resetNativeHeight = (scrollHeight: number) => { const nh = this.layoutDoc.isTemplateForField ? 0 : NumCast(this.layoutDoc._nativeHeight); - this.rootDoc[this.fieldKey + "-height"] = scrollHeight * (this.props.scaling?.() || 1) + this.titleHeight; + this.rootDoc[this.fieldKey + "-height"] = scrollHeight + this.titleHeight; if (nh) this.layoutDoc._nativeHeight = scrollHeight; } @@ -1060,6 +1062,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp dashComment(node, view, getPos) { return new DashDocCommentView(node, view, getPos); }, dashDoc(node, view, getPos) { return new DashDocView(node, view, getPos, self); }, dashField(node, view, getPos) { return new DashFieldView(node, view, getPos, self); }, + equation(node, view, getPos) { return new EquationView(node, view, getPos, self); }, summary(node, view, getPos) { return new SummaryView(node, view, getPos); }, ordered_list(node, view, getPos) { return new OrderedListView(); }, footnote(node, view, getPos) { return new FootnoteView(node, view, getPos); } @@ -1163,7 +1166,6 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp } onPointerUp = (e: React.PointerEvent): void => { - FormattedTextBox.CanAnnotate = true; if (!this._editorView?.state.selection.empty && FormattedTextBox.CanAnnotate) this.setupAnchorMenu(); if (!this._downEvent) return; this._downEvent = false; @@ -1540,8 +1542,8 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp }} /> </div> - {this.props.noSidebar || !this.layoutDoc._showSidebar || this.sidebarWidthPercent === "0%" ? (null) : this.sidebarCollection} - {this.Document._singleLine ? (null) : this.sidebarHandle} + {(this.props.noSidebar || this.Document._noSidebar) || !this.layoutDoc._showSidebar || this.sidebarWidthPercent === "0%" ? (null) : this.sidebarCollection} + {(this.props.noSidebar || this.Document._noSidebar) || this.Document._singleLine ? (null) : this.sidebarHandle} {!this.layoutDoc._showAudio ? (null) : this.audioHandle} </div> </div> diff --git a/src/client/views/nodes/formattedText/ProsemirrorExampleTransfer.ts b/src/client/views/nodes/formattedText/ProsemirrorExampleTransfer.ts index eae4c0179..aa51a3a64 100644 --- a/src/client/views/nodes/formattedText/ProsemirrorExampleTransfer.ts +++ b/src/client/views/nodes/formattedText/ProsemirrorExampleTransfer.ts @@ -145,7 +145,7 @@ export function buildKeymap<S extends Schema<any>>(schema: S, props: any, mapKey bind("Shift-Ctrl-\\", setBlockType(schema.nodes.code_block)); bind("Ctrl-m", (state: EditorState<S>, dispatch: (tx: Transaction<S>) => void) => { - dispatch(state.tr.replaceSelectionWith(schema.nodes.dashField.create({ fieldKey: "math" + Utils.GenerateGuid() }))); + dispatch(state.tr.replaceSelectionWith(schema.nodes.equation.create({ fieldKey: "math" + Utils.GenerateGuid() }))); }) for (let i = 1; i <= 6; i++) { diff --git a/src/client/views/nodes/formattedText/nodes_rts.ts b/src/client/views/nodes/formattedText/nodes_rts.ts index 5d9c8b56d..3bd41fa7d 100644 --- a/src/client/views/nodes/formattedText/nodes_rts.ts +++ b/src/client/views/nodes/formattedText/nodes_rts.ts @@ -242,6 +242,19 @@ export const nodes: { [index: string]: NodeSpec } = { } }, + equation: { + inline: true, + attrs: { + fieldKey: { default: "" }, + }, + group: "inline", + draggable: false, + toDOM(node) { + const attrs = { style: `width: ${node.attrs.width}, height: ${node.attrs.height}` }; + return ["div", { ...node.attrs, ...attrs }]; + } + }, + video: { inline: true, attrs: { |
