diff options
author | bob <bcz@cs.brown.edu> | 2019-01-28 16:47:04 -0500 |
---|---|---|
committer | bob <bcz@cs.brown.edu> | 2019-01-28 16:47:04 -0500 |
commit | 832297c980e8de78ead9cba85dad4d46bdd32b88 (patch) | |
tree | 9856f5dd1f853bf0ac120aa82bc7f03d0b6411ad /src | |
parent | 738d9fae678aa151d0ebb29ec4dbe62b18cd50f3 (diff) |
fixed selecting text in fieldTextBox
Diffstat (limited to 'src')
-rw-r--r-- | src/documents/Documents.ts | 19 | ||||
-rw-r--r-- | src/views/nodes/DocumentView.tsx | 61 | ||||
-rw-r--r-- | src/views/nodes/FieldTextBox.tsx | 49 | ||||
-rw-r--r-- | src/views/nodes/TextNodeView.tsx | 8 |
4 files changed, 76 insertions, 61 deletions
diff --git a/src/documents/Documents.ts b/src/documents/Documents.ts index 60fa79eea..145da7557 100644 --- a/src/documents/Documents.ts +++ b/src/documents/Documents.ts @@ -1,8 +1,9 @@ -import { Document } from "../fields/Document"; -import { KeyStore } from "../fields/Key"; -import { TextField } from "../fields/TextField"; -import { NumberField } from "../fields/NumberField"; -import { ListField } from "../fields/ListField"; +import {Document} from "../fields/Document"; +import {KeyStore} from "../fields/Key"; +import {TextField} from "../fields/TextField"; +import {NumberField} from "../fields/NumberField"; +import {ListField} from "../fields/ListField"; +import {FieldTextBox} from "../views/nodes/FieldTextBox"; interface DocumentOptions { x?: number; @@ -38,8 +39,8 @@ export namespace Documents { textProto.SetField(KeyStore.Y, new NumberField(0)); textProto.SetField(KeyStore.Width, new NumberField(300)); textProto.SetField(KeyStore.Height, new NumberField(150)); - textProto.SetField(KeyStore.Layout, new TextField("<FieldTextBox doc={Document} fieldKey={DataKey} />")); - textProto.SetField(KeyStore.LayoutKeys, new ListField([KeyStore.Data])); + textProto.SetField(KeyStore.Layout, new TextField(FieldTextBox.LayoutString())); + textProto.SetField(KeyStore.LayoutKeys, new ListField([ KeyStore.Data ])); } return textProto; } @@ -61,7 +62,7 @@ export namespace Documents { imageProto.SetField(KeyStore.Height, new NumberField(300)); imageProto.SetField(KeyStore.Layout, new TextField('<img src={Data} draggable="false" width="100%" alt="Image not found"/>')); // imageProto.SetField(KeyStore.Layout, new TextField('<div style={"background-image: " + {Data}} />')); - imageProto.SetField(KeyStore.LayoutFields, new ListField([KeyStore.Data])); + imageProto.SetField(KeyStore.LayoutFields, new ListField([ KeyStore.Data ])); } return imageProto; } @@ -85,7 +86,7 @@ export namespace Documents { collectionProto.SetField(KeyStore.Width, new NumberField(300)); collectionProto.SetField(KeyStore.Height, new NumberField(300)); collectionProto.SetField(KeyStore.Layout, new TextField('<CollectionFreeFormView Document={Document} fieldKey={DataKey} ContainingDocumentView={ContainingDocumentView}/>')); - collectionProto.SetField(KeyStore.LayoutKeys, new ListField([KeyStore.Data])); + collectionProto.SetField(KeyStore.LayoutKeys, new ListField([ KeyStore.Data ])); } return collectionProto; } diff --git a/src/views/nodes/DocumentView.tsx b/src/views/nodes/DocumentView.tsx index 19feefa70..6e874c5a8 100644 --- a/src/views/nodes/DocumentView.tsx +++ b/src/views/nodes/DocumentView.tsx @@ -1,20 +1,20 @@ -import {observer} from "mobx-react"; +import { observer } from "mobx-react"; import React = require("react"); -import {computed, observable, action} from "mobx"; -import {KeyStore, Key} from "../../fields/Key"; -import {NumberField} from "../../fields/NumberField"; -import {TextField} from "../../fields/TextField"; -import {DocumentViewModel} from "../../viewmodels/DocumentViewModel"; -import {ListField} from "../../fields/ListField"; -import {FieldTextBox} from "../nodes/FieldTextBox" -import {Document} from "../../fields/Document"; -import {CollectionFreeFormView} from "../freeformcanvas/CollectionFreeFormView" +import { computed, observable, action } from "mobx"; +import { KeyStore, Key } from "../../fields/Key"; +import { NumberField } from "../../fields/NumberField"; +import { TextField } from "../../fields/TextField"; +import { DocumentViewModel } from "../../viewmodels/DocumentViewModel"; +import { ListField } from "../../fields/ListField"; +import { FieldTextBox } from "../nodes/FieldTextBox" +import { Document } from "../../fields/Document"; +import { CollectionFreeFormView } from "../freeformcanvas/CollectionFreeFormView" import "./NodeView.scss" -import {SelectionManager} from "../../util/SelectionManager"; -import {DocumentDecorations} from "../../DocumentDecorations"; -import {ContextMenu} from "../ContextMenu"; -import {Opt} from "../../fields/Field"; -import {DragManager} from "../../util/DragManager"; +import { SelectionManager } from "../../util/SelectionManager"; +import { DocumentDecorations } from "../../DocumentDecorations"; +import { ContextMenu } from "../ContextMenu"; +import { Opt } from "../../fields/Field"; +import { DragManager } from "../../util/DragManager"; const JsxParser = require('react-jsx-parser').default;//TODO Why does this need to be imported like this? interface IProps { @@ -42,7 +42,7 @@ class DocumentContents extends React.Component<IProps> { } render() { let doc = this.props.Document; - let bindings = {...this.props} as any; + let bindings = { ...this.props } as any; for (const key of this.layoutKeys) { bindings[ key.Name + "Key" ] = key; } @@ -53,11 +53,11 @@ class DocumentContents extends React.Component<IProps> { } } return <JsxParser - components={{FieldTextBox, CollectionFreeFormView}} + components={{ FieldTextBox, CollectionFreeFormView }} bindings={bindings} jsx={this.layout} showWarnings={true} - onError={(test: any) => {console.log(test)}} + onError={(test: any) => { console.log(test) }} /> @@ -135,10 +135,9 @@ export class DocumentView extends React.Component<IProps> { // @computed public get ScalingToScreenSpace(): number { - let containingDocView = this.props.ContainingDocumentView; - if (containingDocView != undefined) { - let ss = containingDocView.props.Document.GetFieldValue(KeyStore.Scale, NumberField, Number(1)); - return containingDocView.ScalingToScreenSpace * ss; + if (this.props.ContainingDocumentView != undefined) { + let ss = this.props.ContainingDocumentView.props.Document.GetFieldValue(KeyStore.Scale, NumberField, Number(1)); + return this.props.ContainingDocumentView.ScalingToScreenSpace * ss; } return 1; } @@ -153,7 +152,7 @@ export class DocumentView extends React.Component<IProps> { // if this collection view is nested within another collection view, then // first transform the screen point into the parent collection's coordinate space. if (this.props.ContainingDocumentView != undefined) { - let {LocalX, LocalY} = this.props.ContainingDocumentView!.TransformToLocalPoint(screenX, screenY); + let { LocalX, LocalY } = this.props.ContainingDocumentView!.TransformToLocalPoint(screenX, screenY); ContainerX = LocalX - CollectionFreeFormView.BORDER_WIDTH; ContainerY = LocalY - CollectionFreeFormView.BORDER_WIDTH; } @@ -167,13 +166,13 @@ export class DocumentView extends React.Component<IProps> { let LocalX = (ContainerX - (Xx + Panxx) - W / 2) / Ss + W / 2; let LocalY = (ContainerY - (Yy + Panyy)) / Ss; - return {LocalX, Ss, W, Panxx, Xx, LocalY, Panyy, Yy, ContainerX, ContainerY}; + return { LocalX, Ss, W, Panxx, Xx, LocalY, Panyy, Yy, ContainerX, ContainerY }; } // // Converts a point in the coordinate space of a document to a screen space coordinate. // - public TransformToScreenPoint(localX: number, localY: number, Ss: number = 1, Panxx: number = 0, Panyy: number = 0): {ScreenX: number, ScreenY: number} { + public TransformToScreenPoint(localX: number, localY: number, Ss: number = 1, Panxx: number = 0, Panyy: number = 0): { ScreenX: number, ScreenY: number } { let W = this.props.Document.GetFieldValue(KeyStore.Width, NumberField, Number(0)); let H = CollectionFreeFormView.BORDER_WIDTH; @@ -189,11 +188,11 @@ export class DocumentView extends React.Component<IProps> { let ss = containingDocView.props.Document.GetFieldValue(KeyStore.Scale, NumberField, Number(1)); let panxx = containingDocView.props.Document.GetFieldValue(KeyStore.PanX, NumberField, Number(0)) + CollectionFreeFormView.BORDER_WIDTH * ss; let panyy = containingDocView.props.Document.GetFieldValue(KeyStore.PanY, NumberField, Number(0)) + CollectionFreeFormView.BORDER_WIDTH * ss; - let {ScreenX, ScreenY} = containingDocView.TransformToScreenPoint(parentX, parentY, ss, panxx, panyy); + let { ScreenX, ScreenY } = containingDocView.TransformToScreenPoint(parentX, parentY, ss, panxx, panyy); parentX = ScreenX; parentY = ScreenY; } - return {ScreenX: parentX, ScreenY: parentY}; + return { ScreenX: parentX, ScreenY: parentY }; } onPointerDown = (e: React.PointerEvent): void => { @@ -202,7 +201,9 @@ export class DocumentView extends React.Component<IProps> { this._contextMenuCanOpen = e.button == 2; if (this.active) { e.stopPropagation(); - e.preventDefault(); + if (e.buttons === 2) { + e.preventDefault(); + } document.removeEventListener("pointermove", this.onPointerMove) document.addEventListener("pointermove", this.onPointerMove); document.removeEventListener("pointerup", this.onPointerUp) @@ -215,7 +216,7 @@ export class DocumentView extends React.Component<IProps> { if (this._mainCont.current != null && this.props.ContainingCollectionView != null) { this._contextMenuCanOpen = false; const rect = this.screenRect; - let dragData: {[ id: string ]: any} = {}; + let dragData: { [ id: string ]: any } = {}; dragData[ "document" ] = this; dragData[ "xOffset" ] = e.x - rect.left; dragData[ "yOffset" ] = e.y - rect.top; @@ -266,7 +267,7 @@ export class DocumentView extends React.Component<IProps> { e.stopPropagation(); ContextMenu.Instance.clearItems(); - ContextMenu.Instance.addItem({description: "Delete", event: this.deleteClicked}) + ContextMenu.Instance.addItem({ description: "Delete", event: this.deleteClicked }) ContextMenu.Instance.displayMenu(e.pageX, e.pageY) SelectionManager.SelectDoc(this, e.ctrlKey); } diff --git a/src/views/nodes/FieldTextBox.tsx b/src/views/nodes/FieldTextBox.tsx index 4539bbab0..8568d04c5 100644 --- a/src/views/nodes/FieldTextBox.tsx +++ b/src/views/nodes/FieldTextBox.tsx @@ -1,23 +1,29 @@ -import { Key, KeyStore } from "../../fields/Key"; -import { Document } from "../../fields/Document"; -import { observer } from "mobx-react"; -import { TextField } from "../../fields/TextField"; +import {Key, KeyStore} from "../../fields/Key"; +import {Document} from "../../fields/Document"; +import {observer} from "mobx-react"; +import {TextField} from "../../fields/TextField"; import React = require("react") -import { action, observable, reaction, IReactionDisposer } from "mobx"; +import {action, observable, reaction, IReactionDisposer} from "mobx"; -import { schema } from "prosemirror-schema-basic"; -import { EditorState, Transaction } from "prosemirror-state" -import { EditorView } from "prosemirror-view" -import { keymap } from "prosemirror-keymap" -import { baseKeymap } from "prosemirror-commands" -import { undo, redo, history } from "prosemirror-history" -import { Opt } from "../../fields/Field"; +import {schema} from "prosemirror-schema-basic"; +import {EditorState, Transaction} from "prosemirror-state" +import {EditorView} from "prosemirror-view" +import {keymap} from "prosemirror-keymap" +import {baseKeymap} from "prosemirror-commands" +import {undo, redo, history} from "prosemirror-history" +import {Opt} from "../../fields/Field"; import "./FieldTextBox.scss" +import {DocumentView} from "./DocumentView"; +import {SelectionManager} from "../../util/SelectionManager"; + +// these properties are set via the render() method of the DocumentView when it creates this node. +// However, these properties are set below in the LayoutString() static method interface IProps { fieldKey: Key; doc: Document; + containingDocumentView: DocumentView } // FieldTextBox: Displays an editable plain text node that maps to a specified Key of a Document @@ -37,6 +43,8 @@ interface IProps { // this will edit the document and assign the new value to that field. // export class FieldTextBox extends React.Component<IProps> { + + public static LayoutString() {return "<FieldTextBox doc={Document} containingDocumentView={ContainingDocumentView} fieldKey={DataKey} />";} private _ref: React.RefObject<HTMLDivElement>; private _editorView: Opt<EditorView>; private _reactionDisposer: Opt<IReactionDisposer>; @@ -53,19 +61,19 @@ export class FieldTextBox extends React.Component<IProps> { if (this._editorView) { const state = this._editorView.state.apply(tx); this._editorView.updateState(state); - const { doc, fieldKey } = this.props; + const {doc, fieldKey} = this.props; doc.SetFieldValue(fieldKey, JSON.stringify(state.toJSON()), TextField); } } componentDidMount() { let state: EditorState; - const { doc, fieldKey } = this.props; + const {doc, fieldKey} = this.props; const config = { schema, plugins: [ history(), - keymap({ "Mod-z": undo, "Mod-y": redo }), + keymap({"Mod-z": undo, "Mod-y": redo}), keymap(baseKeymap) ] }; @@ -108,11 +116,16 @@ export class FieldTextBox extends React.Component<IProps> { @action onChange(e: React.ChangeEvent<HTMLInputElement>) { - const { fieldKey, doc } = this.props; + const {fieldKey, doc} = this.props; doc.SetFieldValue(fieldKey, e.target.value, TextField); } - + onPointerDown = (e: React.PointerEvent): void => { + let me = this; + if (e.buttons === 1 && SelectionManager.IsSelected(me.props.containingDocumentView)) { + e.stopPropagation(); + } + } render() { - return (<div className="fieldTextBox-cont" ref={this._ref} />) + return (<div className="fieldTextBox-cont" onPointerDown={this.onPointerDown} ref={this._ref} />) } }
\ No newline at end of file diff --git a/src/views/nodes/TextNodeView.tsx b/src/views/nodes/TextNodeView.tsx index 4831e658c..ab762df12 100644 --- a/src/views/nodes/TextNodeView.tsx +++ b/src/views/nodes/TextNodeView.tsx @@ -1,7 +1,7 @@ -import { observer } from "mobx-react"; -import { StaticTextNodeStore } from "../../stores/StaticTextNodeStore"; +import {observer} from "mobx-react"; +import {StaticTextNodeStore} from "../../stores/StaticTextNodeStore"; import "./NodeView.scss"; -import { TopBar } from "./TopBar"; +import {TopBar} from "./TopBar"; import React = require("react"); interface IProps { @@ -14,7 +14,7 @@ export class TextNodeView extends React.Component<IProps> { render() { let store = this.props.store; return ( - <div className="node text-node" style={{ transform: store.Transform }}> + <div className="node text-node" style={{transform: store.Transform}}> <TopBar store={store} /> <div className="scroll-box"> <div className="content"> |