diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/fields/Document.ts | 7 | ||||
-rw-r--r-- | src/views/collections/CollectionDockingView.tsx | 271 | ||||
-rw-r--r-- | src/views/nodes/DocumentView.tsx | 1 |
3 files changed, 115 insertions, 164 deletions
diff --git a/src/fields/Document.ts b/src/fields/Document.ts index 6b1cccaf9..9580ab5c0 100644 --- a/src/fields/Document.ts +++ b/src/fields/Document.ts @@ -1,10 +1,15 @@ import { Field, Cast, Opt } from "./Field" import { Key, KeyStore } from "./Key" -import { ObservableMap } from "mobx"; +import { ObservableMap, computed } from "mobx"; +import { TextField } from "./TextField"; export class Document extends Field { private fields: ObservableMap<Key, Field> = new ObservableMap(); + static _untitledDocName = "<untitled>"; + @computed + public get Title() { return this.GetFieldValue(KeyStore.Title, TextField, Document._untitledDocName); } + GetField(key: Key, ignoreProto: boolean = false): Opt<Field> { let field: Opt<Field>; if (ignoreProto) { diff --git a/src/views/collections/CollectionDockingView.tsx b/src/views/collections/CollectionDockingView.tsx index e07e53168..fd492503d 100644 --- a/src/views/collections/CollectionDockingView.tsx +++ b/src/views/collections/CollectionDockingView.tsx @@ -1,10 +1,10 @@ import { observer } from "mobx-react"; -import { Key, KeyStore } from "../../fields/Key"; +import { KeyStore } from "../../fields/Key"; import React = require("react"); import FlexLayout from "flexlayout-react"; import { action, observable, computed } from "mobx"; import { Document } from "../../fields/Document"; -import { DocumentView, DocumentFieldViewProps, CollectionViewProps } from "../nodes/DocumentView"; +import { DocumentView, CollectionViewProps } from "../nodes/DocumentView"; import { ListField } from "../../fields/ListField"; import { NumberField } from "../../fields/NumberField"; import { SSL_OP_SINGLE_DH_USE } from "constants"; @@ -14,69 +14,42 @@ import "./CollectionDockingView.scss" import 'golden-layout/src/css/goldenlayout-base.css'; import 'golden-layout/src/css/goldenlayout-dark-theme.css'; import * as GoldenLayout from "golden-layout"; -import { CollectionFreeFormView } from './CollectionFreeFormView'; import * as ReactDOM from 'react-dom'; -import { TextField } from "../../fields/TextField"; @observer export class CollectionDockingView extends React.Component<CollectionViewProps> { + private static UseGoldenLayout = true; public static LayoutString() { return '<CollectionDockingView Document={Document} fieldKey={DataKey} ContainingDocumentView={ContainingDocumentView}/>'; } - - - private _times: number = 0; private _containerRef = React.createRef<HTMLDivElement>(); - private _canvasRef = React.createRef<HTMLDivElement>(); - private _json = { - global: {}, - borders: [], - layout: { - "type": "row", - "weight": 100, - "children": [ - { - "type": "tabset", - "weight": 50, - "selected": 0, - "children": [ - { - "type": "tab", - "name": "CHILD #1", - "component": "doc1", - } - ] - }, - { - "type": "tabset", - "weight": 50, - "selected": 0, - "children": [ - { - "type": "tab", - "name": "CHILD #2", - "component": "doc2", - } - ] - }, - { - "type": "tabset", - "weight": 50, - "selected": 0, - "children": [ - { - "type": "tab", - "name": "CHILD #3", - "component": "doc3", - } - ] - } - ] - } - }; - private _model: any; + @computed + private get modelForFlexLayout() { + const { fieldKey, Document: Document } = this.props; + const value: Document[] = Document.GetFieldValue(fieldKey, ListField, []); + var docs = value.map(doc => { + return { type: 'tabset', weight: 50, selected: 0, children: [ { type: "tab", name: doc.Title, component: doc.Id } ] }; + }); + return FlexLayout.Model.fromJson({ + global: {}, borders: [], + layout: { + "type": "row", + "weight": 100, + "children": docs + } + }); + } + @computed + private get modelForGoldenLayout(): any { + const { fieldKey, Document: Document } = this.props; + const value: Document[] = Document.GetFieldValue(fieldKey, ListField, []); + var docs = value.map(doc => { + var d = { type: 'component', componentName: 'documentViewComponent', componentState: { doc: doc } }; + return d; + }); + return new GoldenLayout({ content: [ { type: 'row', content: docs } ] }); + } constructor(props: CollectionViewProps) { super(props); - this._model = FlexLayout.Model.fromJson(this._json); } public static BORDER_WIDTH = 2; @@ -90,80 +63,13 @@ export class CollectionDockingView extends React.Component<CollectionViewProps> return isSelected || childSelected || topMost; } - myLayout: any = null; componentDidMount: () => void = () => { - - const { fieldKey, Document: Document } = this.props; - - const value: Document[] = Document.GetFieldValue(fieldKey, ListField, []); - if (this._containerRef.current) { - if (this.myLayout == null) { - var docs = value.map(doc => { - var d = { fcomponent: undefined, type: 'component', componentName: 'documentViewComponent', componentState: { doc: doc } }; - return d; - }); - this.myLayout = new GoldenLayout({ - content: [ { - type: 'row', - content: docs - } ] - }); - - this.myLayout.on('stackCreated', function (stack: any) { - stack - .header - .controlsContainer - .find('.lm_close') //get the close icon - .off('click') //unbind the current click handler - .click(function () { - //add your own - if (confirm('really close this?')) { - stack.remove(); - } - }); - }); - - this.myLayout.on('tabCreated', function (tab: any) { - var docToRender = tab.contentItem.config.componentState.doc; - var dflt: string = "<untitled>"; - tab.setTitle(docToRender.GetFieldValue(KeyStore.Title, TextField, dflt)); - tab - .closeElement - .off('click') //unbind the current click handler - .click(function () { - //add your own - if (confirm('really close this?')) { - tab.contentItem.remove(); - } - }); - }); - - this.myLayout.registerComponent('documentViewComponent', this.registerComponentWithCallback); - this.myLayout.container = this._containerRef.current; - this.myLayout.init(); - } + if (this._containerRef.current && CollectionDockingView.UseGoldenLayout) { + this.goldenLayoutFactory(); } } private nextId = (function () { var _next_id = 0; return function () { return _next_id++; } })(); - private registerComponentWithCallback = (container: any, state: any) => { - var containingDiv = "component_" + this.nextId(); - container.getElement().html("<div id='" + containingDiv + "'></div>"); - var me = this; - var docToRender = state.doc; - // bcz: ugly way to do this. wait until containoing div has been created, then look it up in the DOM and render our document view into it. - setTimeout(function () { - ReactDOM.render(( - <div style={{ display: "grid" }}> - <DocumentView key={docToRender.Id} Document={docToRender} ContainingCollectionView={me} ContainingDocumentView={me.props.ContainingDocumentView} /> - </div> - ), - document.getElementById(containingDiv) - ) - }, 0); - }; - - @action addDocument = (doc: Document): void => { //TODO This won't create the field if it doesn't already exist @@ -193,64 +99,105 @@ export class CollectionDockingView extends React.Component<CollectionViewProps> } } } - factory = (node: any): any => { + + flexLayoutFactory = (node: any): any => { var component = node.getComponent(); if (component === "button") { return <button>{node.getName()}</button>; } const { fieldKey, Document: Document } = this.props; const value: Document[] = Document.GetFieldValue(fieldKey, ListField, []); - if (component === "doc1" && value.length > 0) { - return (<DocumentView key={value[ 0 ].Id} ContainingCollectionView={this} Document={value[ 0 ]} ContainingDocumentView={this.props.ContainingDocumentView} />); - } - if (component === "doc2" && value.length > 1) { - return (<DocumentView key={value[ 1 ].Id} ContainingCollectionView={this} Document={value[ 1 ]} ContainingDocumentView={this.props.ContainingDocumentView} />); - } - if (component === "doc3" && value.length > 2) { - return (<DocumentView key={value[ 2 ].Id} ContainingCollectionView={this} Document={value[ 2 ]} ContainingDocumentView={this.props.ContainingDocumentView} />); + for (var i: number = 0; i < value.length; i++) { + if (value[ i ].Id === component) { + return (<DocumentView key={value[ i ].Id} ContainingCollectionView={this} Document={value[ i ]} ContainingDocumentView={this.props.ContainingDocumentView} />); + } } if (component === "text") { return (<div className="panel">Panel {node.getName()}</div>); } } + goldenLayoutFactory() { + var myLayout = this.modelForGoldenLayout; - render() { + myLayout.on('stackCreated', function (stack: any) { + stack.header.controlsContainer.find('.lm_close') //get the close icon + .off('click') //unbind the current click handler + .click(function () { + if (confirm('really close this?')) { + stack.remove(); + } + }); + }); + + myLayout.on('tabCreated', function (tab: any) { + tab.setTitle(tab.contentItem.config.componentState.doc.Title); + tab.closeElement.off('click') //unbind the current click handler + .click(function () { + if (confirm('really close this?')) { + tab.contentItem.remove(); + } + }); + }); + + var me = this; + myLayout.registerComponent('documentViewComponent', function (container: any, state: any) { + // bcz: this is crufty + // calling html() causes a div tag to be added in the DOM with id 'containingDiv'. + // Apparently, we need to wait to allow a live html div element to actually be instantiated. + // After a timeout, we lookup the live html div element and add our React DocumentView to it. + var containingDiv = "component_" + me.nextId(); + container.getElement().html("<div id='" + containingDiv + "'></div>"); + setTimeout(function () { + ReactDOM.render(( + <DocumentView key={state.doc.Id} Document={state.doc} ContainingCollectionView={me} ContainingDocumentView={me.props.ContainingDocumentView} /> + ), + document.getElementById(containingDiv) + ) + }, 0); + }); + myLayout.container = this._containerRef.current; + myLayout.init(); + } - const { fieldKey, Document: Document } = this.props; + render() { + const { fieldKey, Document: Document } = this.props; const value: Document[] = Document.GetFieldValue(fieldKey, ListField, []); // bcz: not sure why, but I need these to force the flexlayout to update when the collection size changes. var s = this.props.ContainingDocumentView!.ScalingToScreenSpace; var w = Document.GetFieldValue(KeyStore.Width, NumberField, Number(0)) / s; var h = Document.GetFieldValue(KeyStore.Height, NumberField, Number(0)) / s; - return ( - <div className="border" style={{ - borderStyle: "solid", - borderWidth: `${CollectionDockingView.BORDER_WIDTH}px`, - }}> - <div className="collectiondockingview-container" onPointerDown={this.onPointerDown} onContextMenu={(e) => e.preventDefault()} ref={this._containerRef} - style={{ - width: "100%", - height: "100%" - }} > + if (CollectionDockingView.UseGoldenLayout) { + return ( + <div className="border" style={{ + borderStyle: "solid", + borderWidth: `${CollectionDockingView.BORDER_WIDTH}px`, + }}> + <div className="collectiondockingview-container" onPointerDown={this.onPointerDown} onContextMenu={(e) => e.preventDefault()} ref={this._containerRef} + style={{ + width: "100%", + height: "100%" + }} > + </div> </div> - </div> - ); - // return ( - // <div className="border" style={{ - // borderStyle: "solid", - // borderWidth: `${CollectionDockingView.BORDER_WIDTH}px`, - // }}> - // <div className="collectiondockingview-container" onPointerDown={this.onPointerDown} onContextMenu={(e) => e.preventDefault()} ref={this._containerRef} - // style={{ - // width: s > 1 ? "100%" : w - 2 * CollectionDockingView.BORDER_WIDTH, - // height: s > 1 ? "100%" : h - 2 * CollectionDockingView.BORDER_WIDTH - // }} > - // <FlexLayout.Layout model={this._model} factory={this.factory} /> - // </div> - // </div> - // ); + ); + } else { + return ( + <div className="border" style={{ + borderStyle: "solid", + borderWidth: `${CollectionDockingView.BORDER_WIDTH}px`, + }}> + <div className="collectiondockingview-container" onPointerDown={this.onPointerDown} onContextMenu={(e) => e.preventDefault()} ref={this._containerRef} + style={{ + width: s > 1 ? "100%" : w - 2 * CollectionDockingView.BORDER_WIDTH, + height: s > 1 ? "100%" : h - 2 * CollectionDockingView.BORDER_WIDTH + }} > + <FlexLayout.Layout model={this.modelForFlexLayout} factory={this.flexLayoutFactory} /> + </div> + </div> + ); + } } }
\ No newline at end of file diff --git a/src/views/nodes/DocumentView.tsx b/src/views/nodes/DocumentView.tsx index 86d5ed305..1e4cc1cca 100644 --- a/src/views/nodes/DocumentView.tsx +++ b/src/views/nodes/DocumentView.tsx @@ -11,7 +11,6 @@ import { CollectionFreeFormView } from "../collections/CollectionFreeFormView" import { CollectionDockingView } from "../collections/CollectionDockingView" 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"; |