diff options
Diffstat (limited to 'src/views')
20 files changed, 0 insertions, 2024 deletions
diff --git a/src/views/ContextMenu.scss b/src/views/ContextMenu.scss deleted file mode 100644 index 234f82eb9..000000000 --- a/src/views/ContextMenu.scss +++ /dev/null @@ -1,34 +0,0 @@ -.contextMenu-cont { - position: absolute; - display: flex; - z-index: 1000; - box-shadow: #AAAAAA .2vw .2vw .4vw; -} - -.contextMenu-item { - width: 10vw; - height: 4vh; - background: #DDDDDD; - display: flex; - justify-content: center; - align-items: center; - flex-direction: column; - -webkit-touch-callout: none; - -webkit-user-select: none; - -khtml-user-select: none; - -moz-user-select: none; - -ms-user-select: none; - user-select: none; - transition: all .1s; -} - -.contextMenu-item:hover { - transition: all .1s; - background: #AAAAAA -} - -.contextMenu-description { - font-size: 1.5vw; - text-align: left; - width: 8vw; -}
\ No newline at end of file diff --git a/src/views/ContextMenu.tsx b/src/views/ContextMenu.tsx deleted file mode 100644 index 4f26a75d2..000000000 --- a/src/views/ContextMenu.tsx +++ /dev/null @@ -1,68 +0,0 @@ -import React = require("react"); -import { ContextMenuItem, ContextMenuProps } from "./ContextMenuItem"; -import { observable } from "mobx"; -import { observer } from "mobx-react"; -import "./ContextMenu.scss" - -@observer -export class ContextMenu extends React.Component { - static Instance: ContextMenu - - @observable private _items: Array<ContextMenuProps> = [{ description: "test", event: (e: React.MouseEvent) => e.preventDefault() }]; - @observable private _pageX: number = 0; - @observable private _pageY: number = 0; - @observable private _display: string = "none"; - - private ref: React.RefObject<HTMLDivElement>; - - constructor(props: Readonly<{}>) { - super(props); - - this.ref = React.createRef() - - ContextMenu.Instance = this; - } - - clearItems() { - this._items = [] - this._display = "none" - } - - addItem(item: ContextMenuProps) { - if (this._items.indexOf(item) === -1) { - this._items.push(item); - } - } - - getItems() { - return this._items; - } - - displayMenu(x: number, y: number) { - this._pageX = x - this._pageY = y - - this._display = "flex" - } - - intersects = (x: number, y: number): boolean => { - if (this.ref.current && this._display !== "none") { - if (x >= this._pageX && x <= this._pageX + this.ref.current.getBoundingClientRect().width) { - if (y >= this._pageY && y <= this._pageY + this.ref.current.getBoundingClientRect().height) { - return true; - } - } - } - return false; - } - - render() { - return ( - <div className="contextMenu-cont" style={{ left: this._pageX, top: this._pageY, display: this._display }} ref={this.ref}> - {this._items.map(prop => { - return <ContextMenuItem {...prop} key={prop.description} /> - })} - </div> - ) - } -}
\ No newline at end of file diff --git a/src/views/ContextMenuItem.tsx b/src/views/ContextMenuItem.tsx deleted file mode 100644 index 8f00f8b3d..000000000 --- a/src/views/ContextMenuItem.tsx +++ /dev/null @@ -1,17 +0,0 @@ -import React = require("react"); -import { ContextMenu } from "./ContextMenu"; - -export interface ContextMenuProps { - description: string; - event: (e: React.MouseEvent<HTMLDivElement>) => void; -} - -export class ContextMenuItem extends React.Component<ContextMenuProps> { - render() { - return ( - <div className="contextMenu-item" onClick={this.props.event}> - <div className="contextMenu-description">{this.props.description}</div> - </div> - ) - } -}
\ No newline at end of file diff --git a/src/views/EditableView.tsx b/src/views/EditableView.tsx deleted file mode 100644 index 2e784d3f9..000000000 --- a/src/views/EditableView.tsx +++ /dev/null @@ -1,39 +0,0 @@ -import React = require('react') -import { observer } from 'mobx-react'; -import { observable, action } from 'mobx'; - -export interface EditableProps { - GetValue(): string; - SetValue(value: string): boolean; - contents: any; -} - -@observer -export class EditableView extends React.Component<EditableProps> { - @observable - editing: boolean = false; - - @action - onKeyDown = (e: React.KeyboardEvent<HTMLInputElement>) => { - if (e.key == "Enter" && !e.ctrlKey) { - this.props.SetValue(e.currentTarget.value); - this.editing = false; - } else if (e.key == "Escape") { - this.editing = false; - } - } - - render() { - if (this.editing) { - return <input defaultValue={this.props.GetValue()} onKeyDown={this.onKeyDown} autoFocus onBlur={action(() => this.editing = false)} - style={{ width: "100%" }}></input> - } else { - return ( - <div> - {this.props.contents} - <button onClick={action(() => this.editing = true)}>Edit</button> - </div> - ) - } - } -}
\ No newline at end of file diff --git a/src/views/collections/CollectionDockingView.scss b/src/views/collections/CollectionDockingView.scss deleted file mode 100644 index db924b57f..000000000 --- a/src/views/collections/CollectionDockingView.scss +++ /dev/null @@ -1,336 +0,0 @@ -.collectiondockingview-container { - position: relative; - top: 0; - left: 0; - overflow: hidden; - .lm_controls>li { - opacity: 0.6; - transform: scale(1.2); - } - .lm_maximised .lm_controls .lm_maximise { - opacity: 1; - transform: scale(0.8); - background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAkAAAAJCAYAAADgkQYQAAAAKElEQVR4nGP8////fwYCgImQAgYGBgYWKM2IR81/okwajIpgvsMbVgAwgQYRVakEKQAAAABJRU5ErkJggg==) !important; - } - .flexlayout__layout { - left: 0; - top: 0; - right: 0; - bottom: 0; - position: absolute; - overflow: hidden; - } - .flexlayout__splitter { - background-color: black; - } - .flexlayout__splitter:hover { - background-color: #333; - } - .flexlayout__splitter_drag { - border-radius: 5px; - background-color: #444; - z-index: 1000; - } - .flexlayout__outline_rect { - position: absolute; - cursor: move; - border: 2px solid #cfe8ff; - box-shadow: inset 0 0 60px rgba(0, 0, 0, .2); - border-radius: 5px; - z-index: 1000; - box-sizing: border-box; - } - .flexlayout__outline_rect_edge { - cursor: move; - border: 2px solid #b7d1b5; - box-shadow: inset 0 0 60px rgba(0, 0, 0, .2); - border-radius: 5px; - z-index: 1000; - box-sizing: border-box; - } - .flexlayout__edge_rect { - position: absolute; - z-index: 1000; - box-shadow: inset 0 0 5px rgba(0, 0, 0, .2); - background-color: lightgray; - } - .flexlayout__drag_rect { - position: absolute; - cursor: move; - border: 2px solid #aaaaaa; - box-shadow: inset 0 0 60px rgba(0, 0, 0, .3); - border-radius: 5px; - z-index: 1000; - box-sizing: border-box; - background-color: #eeeeee; - opacity: 0.9; - text-align: center; - display: flex; - justify-content: center; - flex-direction: column; - overflow: hidden; - padding: 10px; - word-wrap: break-word; - } - .flexlayout__tabset { - overflow: hidden; - background-color: #222; - box-sizing: border-box; - } - .flexlayout__tab { - overflow: auto; - position: absolute; - box-sizing: border-box; - background-color: #222; - color: black; - } - .flexlayout__tab_button { - cursor: pointer; - padding: 2px 8px 3px 8px; - margin: 2px; - /*box-shadow: inset 0px 0px 5px rgba(0, 0, 0, .15);*/ - /*border-top-left-radius: 3px;*/ - /*border-top-right-radius: 3px;*/ - float: left; - vertical-align: top; - box-sizing: border-box; - } - .flexlayout__tab_button--selected { - color: #ddd; - background-color: #222; - } - .flexlayout__tab_button--unselected { - color: gray; - } - .flexlayout__tab_button_leading { - display: inline-block; - } - .flexlayout__tab_button_content { - display: inline-block; - } - .flexlayout__tab_button_textbox { - float: left; - border: none; - color: lightgreen; - background-color: #222; - } - .flexlayout__tab_button_textbox:focus { - outline: none; - } - .flexlayout__tab_button_trailing { - display: inline-block; - margin-left: 5px; - margin-top: 3px; - width: 8px; - height: 8px; - } - .flexlayout__tab_button:hover .flexlayout__tab_button_trailing, - .flexlayout__tab_button--selected .flexlayout__tab_button_trailing { - background: transparent url("../../../node_modules/flexlayout-react/images/close_white.png") no-repeat center; - } - .flexlayout__tab_button_overflow { - float: left; - width: 20px; - height: 15px; - margin-top: 2px; - padding-left: 12px; - border: none; - font-size: 10px; - color: lightgray; - font-family: Arial, sans-serif; - background: transparent url("../../../node_modules/flexlayout-react/images/more.png") no-repeat left; - } - .flexlayout__tabset_header { - position: absolute; - left: 0; - right: 0; - color: #eee; - background-color: #212121; - padding: 3px 3px 3px 5px; - /*box-shadow: inset 0px 0px 3px 0px rgba(136, 136, 136, 0.54);*/ - box-sizing: border-box; - } - .flexlayout__tab_header_inner { - position: absolute; - left: 0; - top: 0; - bottom: 0; - width: 10000px; - } - .flexlayout__tab_header_outer { - background-color: black; - position: absolute; - left: 0; - right: 0; - /*top: 0px;*/ - /*height: 100px;*/ - overflow: hidden; - } - .flexlayout__tabset-selected { - background-image: linear-gradient(#111, #444); - } - .flexlayout__tabset-maximized { - background-image: linear-gradient(#666, #333); - } - .flexlayout__tab_toolbar { - position: absolute; - display: flex; - flex-direction: row-reverse; - align-items: center; - top: 0; - bottom: 0; - right: 0; - } - .flexlayout__tab_toolbar_button-min { - width: 20px; - height: 20px; - border: none; - outline-width: 0; - background: transparent url("../../../node_modules/flexlayout-react/images/maximize.png") no-repeat center; - } - .flexlayout__tab_toolbar_button-max { - width: 20px; - height: 20px; - border: none; - outline-width: 0; - background: transparent url("../../../node_modules/flexlayout-react/images/restore.png") no-repeat center; - } - .flexlayout__popup_menu {} - .flexlayout__popup_menu_item { - padding: 2px 10px 2px 10px; - color: #ddd; - } - .flexlayout__popup_menu_item:hover { - background-color: #444444; - } - .flexlayout__popup_menu_container { - box-shadow: inset 0 0 5px rgba(0, 0, 0, .15); - border: 1px solid #555; - background: #222; - border-radius: 3px; - position: absolute; - z-index: 1000; - } - .flexlayout__border_top { - background-color: black; - border-bottom: 1px solid #ddd; - box-sizing: border-box; - overflow: hidden; - } - .flexlayout__border_bottom { - background-color: black; - border-top: 1px solid #333; - box-sizing: border-box; - overflow: hidden; - } - .flexlayout__border_left { - background-color: black; - border-right: 1px solid #333; - box-sizing: border-box; - overflow: hidden; - } - .flexlayout__border_right { - background-color: black; - border-left: 1px solid #333; - box-sizing: border-box; - overflow: hidden; - } - .flexlayout__border_inner_bottom { - display: flex; - } - .flexlayout__border_inner_left { - position: absolute; - white-space: nowrap; - right: 23px; - transform-origin: top right; - transform: rotate(-90deg); - } - .flexlayout__border_inner_right { - position: absolute; - white-space: nowrap; - left: 23px; - transform-origin: top left; - transform: rotate(90deg); - } - .flexlayout__border_button { - background-color: #222; - color: white; - display: inline-block; - white-space: nowrap; - cursor: pointer; - padding: 2px 8px 3px 8px; - margin: 2px; - vertical-align: top; - box-sizing: border-box; - } - .flexlayout__border_button--selected { - color: #ddd; - background-color: #222; - } - .flexlayout__border_button--unselected { - color: gray; - } - .flexlayout__border_button_leading { - float: left; - display: inline; - } - .flexlayout__border_button_content { - display: inline-block; - } - .flexlayout__border_button_textbox { - float: left; - border: none; - color: green; - background-color: #ddd; - } - .flexlayout__border_button_textbox:focus { - outline: none; - } - .flexlayout__border_button_trailing { - display: inline-block; - margin-left: 5px; - margin-top: 3px; - width: 8px; - height: 8px; - } - .flexlayout__border_button:hover .flexlayout__border_button_trailing, - .flexlayout__border_button--selected .flexlayout__border_button_trailing { - background: transparent url("../../../node_modules/flexlayout-react/images/close_white.png") no-repeat center; - } - .flexlayout__border_toolbar_left { - position: absolute; - display: flex; - flex-direction: column-reverse; - align-items: center; - bottom: 0; - left: 0; - right: 0; - } - .flexlayout__border_toolbar_right { - position: absolute; - display: flex; - flex-direction: column-reverse; - align-items: center; - bottom: 0; - left: 0; - right: 0; - } - .flexlayout__border_toolbar_top { - position: absolute; - display: flex; - flex-direction: row-reverse; - align-items: center; - top: 0; - bottom: 0; - right: 0; - } - .flexlayout__border_toolbar_bottom { - position: absolute; - display: flex; - flex-direction: row-reverse; - align-items: center; - top: 0; - bottom: 0; - right: 0; - } -}
\ No newline at end of file diff --git a/src/views/collections/CollectionDockingView.tsx b/src/views/collections/CollectionDockingView.tsx deleted file mode 100644 index adef03357..000000000 --- a/src/views/collections/CollectionDockingView.tsx +++ /dev/null @@ -1,282 +0,0 @@ -import { observer } from "mobx-react"; -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 } from "../nodes/DocumentView"; -import { ListField } from "../../fields/ListField"; -import { NumberField } from "../../fields/NumberField"; -import { SSL_OP_SINGLE_DH_USE } from "constants"; -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 * as ReactDOM from 'react-dom'; -import { DragManager } from "../../util/DragManager"; -import { CollectionViewBase, CollectionViewProps, COLLECTION_BORDER_WIDTH } from "./CollectionViewBase"; - -@observer -export class CollectionDockingView extends CollectionViewBase { - - private static UseGoldenLayout = true; - public static LayoutString() { return CollectionViewBase.LayoutString("CollectionDockingView"); } - private _containerRef = React.createRef<HTMLDivElement>(); - @computed - private get modelForFlexLayout() { - const { CollectionFieldKey: fieldKey, DocumentForCollection: Document } = this.props; - const value: Document[] = Document.GetData(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 { CollectionFieldKey: fieldKey, DocumentForCollection: Document } = this.props; - const value: Document[] = Document.GetData(fieldKey, ListField, []); - var docs = value.map(doc => { - return { type: 'component', componentName: 'documentViewComponent', componentState: { doc: doc } }; - }); - return new GoldenLayout({ - settings: { - selectionEnabled: true - }, content: [{ type: 'row', content: docs }] - }); - } - constructor(props: CollectionViewProps) { - super(props); - } - - componentDidMount: () => void = () => { - if (this._containerRef.current && CollectionDockingView.UseGoldenLayout) { - this.goldenLayoutFactory(); - window.addEventListener('resize', this.onResize); // bcz: would rather add this event to the parent node, but resize events only come from Window - } - } - componentWillUnmount: () => void = () => { - window.removeEventListener('resize', this.onResize); - } - private nextId = (function () { var _next_id = 0; return function () { return _next_id++; } })(); - - - @action - onResize = (event: any) => { - var cur = this.props.ContainingDocumentView!.MainContent.current; - - // bcz: since GoldenLayout isn't a React component itself, we need to notify it to resize when its document container's size has changed - CollectionDockingView.myLayout.updateSize(cur!.getBoundingClientRect().width, cur!.getBoundingClientRect().height); - } - - @action - onPointerDown = (e: React.PointerEvent): void => { - if (e.button === 2 && this.active) { - e.stopPropagation(); - e.preventDefault(); - } else { - if (e.buttons === 1 && this.active) { - e.stopPropagation(); - } - } - } - - flexLayoutFactory = (node: any): any => { - var component = node.getComponent(); - if (component === "button") { - return <button>{node.getName()}</button>; - } - const { CollectionFieldKey: fieldKey, DocumentForCollection: Document } = this.props; - const value: Document[] = Document.GetData(fieldKey, ListField, []); - 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]} DocumentView={undefined} />); - } - } - if (component === "text") { - return (<div className="panel">Panel {node.getName()}</div>); - } - } - - public static myLayout: any = null; - - private static _dragDiv: any = null; - private static _dragParent: HTMLElement | null = null; - private static _dragElement: HTMLDivElement; - private static _dragFakeElement: HTMLDivElement; - public static StartOtherDrag(dragElement: HTMLDivElement, dragDoc: Document) { - var newItemConfig = { - type: 'component', - componentName: 'documentViewComponent', - componentState: { doc: dragDoc } - }; - this._dragElement = dragElement; - this._dragParent = dragElement.parentElement; - // bcz: we want to copy this document into the header, not move it there. - // However, GoldenLayout is setup to move things, so we have to do some kludgy stuff: - - // - create a temporary invisible div and register that as a DragSource with GoldenLayout - this._dragDiv = document.createElement("div"); - this._dragDiv.style.opacity = 0; - DragManager.Root().appendChild(this._dragDiv); - CollectionDockingView.myLayout.createDragSource(this._dragDiv, newItemConfig); - - // - add our document to that div so that GoldenLayout will get the move events its listening for - this._dragDiv.appendChild(this._dragElement); - - // - add a duplicate of our document to the original document's container - // (GoldenLayout will be removing our original one) - this._dragFakeElement = dragElement.cloneNode(true) as HTMLDivElement; - this._dragParent!.appendChild(this._dragFakeElement); - - // all of this must be undone when the document has been dropped (see tabCreated) - } - - _makeFullScreen: boolean = false; - _maximizedStack: any = null; - public static OpenFullScreen(document: Document) { - var newItemConfig = { - type: 'component', - componentName: 'documentViewComponent', - componentState: { doc: document } - }; - CollectionDockingView.myLayout._makeFullScreen = true; - CollectionDockingView.myLayout.root.contentItems[0].addChild(newItemConfig); - } - public static CloseFullScreen() { - if (CollectionDockingView.myLayout._maximizedStack != null) { - CollectionDockingView.myLayout._maximizedStack.header.controlsContainer.find('.lm_close').click(); - CollectionDockingView.myLayout._maximizedStack = null; - } - } - - // - // Creates a vertical split on the right side of the docking view, and then adds the Document to that split - // - public static AddRightSplit(document: Document) { - var newItemConfig = { - type: 'component', - componentName: 'documentViewComponent', - componentState: { doc: document } - } - let newItemStackConfig = { - type: 'stack', - content: [newItemConfig] - }; - var newContentItem = new CollectionDockingView.myLayout._typeToItem[newItemStackConfig.type](CollectionDockingView.myLayout, newItemStackConfig, parent); - - if (CollectionDockingView.myLayout.root.contentItems[0].isRow) { - var rowlayout = CollectionDockingView.myLayout.root.contentItems[0]; - var lastRowItem = rowlayout.contentItems[rowlayout.contentItems.length - 1]; - - lastRowItem.config["width"] *= 0.5; - newContentItem.config["width"] = lastRowItem.config["width"]; - rowlayout.addChild(newContentItem, rowlayout.contentItems.length, true); - rowlayout.callDownwards('setSize'); - } - else { - var collayout = CollectionDockingView.myLayout.root.contentItems[0]; - var newRow = collayout.layoutManager.createContentItem({ type: "row" }, CollectionDockingView.myLayout); - collayout.parent.replaceChild(collayout, newRow); - - newRow.addChild(newContentItem, undefined, true); - newRow.addChild(collayout, 0, true); - - collayout.config["width"] = 50; - newContentItem.config["width"] = 50; - collayout.parent.callDownwards('setSize'); - } - } - goldenLayoutFactory() { - CollectionDockingView.myLayout = this.modelForGoldenLayout; - - var layout = CollectionDockingView.myLayout; - CollectionDockingView.myLayout.on('tabCreated', function (tab: any) { - if (CollectionDockingView._dragDiv) { - CollectionDockingView._dragDiv.removeChild(CollectionDockingView._dragElement); - CollectionDockingView._dragParent!.removeChild(CollectionDockingView._dragFakeElement); - CollectionDockingView._dragParent!.appendChild(CollectionDockingView._dragElement); - DragManager.Root().removeChild(CollectionDockingView._dragDiv); - CollectionDockingView._dragDiv = null; - } - tab.setTitle(tab.contentItem.config.componentState.doc.Title); - tab.closeElement.off('click') //unbind the current click handler - .click(function () { - tab.contentItem.remove(); - }); - }); - - CollectionDockingView.myLayout.on('stackCreated', function (stack: any) { - if (CollectionDockingView.myLayout._makeFullScreen) { - CollectionDockingView.myLayout._maximizedStack = stack; - CollectionDockingView.myLayout._maxstack = stack.header.controlsContainer.find('.lm_maximise'); - } - //stack.header.controlsContainer.find('.lm_popout').hide(); - 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(); - //} - }); - }); - - var me = this; - CollectionDockingView.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} DocumentView={undefined} /> - ), - document.getElementById(containingDiv) - ); - if (CollectionDockingView.myLayout._maxstack != null) { - CollectionDockingView.myLayout._maxstack.click(); - } - }, 0); - }); - CollectionDockingView.myLayout.container = this._containerRef.current; - CollectionDockingView.myLayout.init(); - } - - - render() { - const { CollectionFieldKey: fieldKey, DocumentForCollection: Document } = this.props; - const value: Document[] = Document.GetData(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 != undefined ? this.props.ContainingDocumentView!.ScalingToScreenSpace : 1; - var w = Document.GetData(KeyStore.Width, NumberField, Number(0)) / s; - var h = Document.GetData(KeyStore.Height, NumberField, Number(0)) / s; - - var chooseLayout = () => { - if (!CollectionDockingView.UseGoldenLayout) - return <FlexLayout.Layout model={this.modelForFlexLayout} factory={this.flexLayoutFactory} />; - } - - return ( - <div className="border" style={{ - borderStyle: "solid", - borderWidth: `${COLLECTION_BORDER_WIDTH}px`, - }}> - <div className="collectiondockingview-container" id="menuContainer" onPointerDown={this.onPointerDown} onContextMenu={(e) => e.preventDefault()} ref={this._containerRef} - style={{ - width: CollectionDockingView.UseGoldenLayout || s > 1 ? "100%" : w - 2 * COLLECTION_BORDER_WIDTH, - height: CollectionDockingView.UseGoldenLayout || s > 1 ? "100%" : h - 2 * COLLECTION_BORDER_WIDTH - }} > - {chooseLayout()} - </div> - </div> - ); - } -}
\ No newline at end of file diff --git a/src/views/collections/CollectionFreeFormView.scss b/src/views/collections/CollectionFreeFormView.scss deleted file mode 100644 index e9d134e7b..000000000 --- a/src/views/collections/CollectionFreeFormView.scss +++ /dev/null @@ -1,20 +0,0 @@ -.collectionfreeformview-container { - position: relative; - top: 0; - left: 0; - width: 100%; - height: 100%; - overflow: hidden; - .collectionfreeformview { - position: absolute; - top: 0; - left: 0; - } -} - -.border { - border-style: solid; - box-sizing: border-box; - width: 100%; - height: 100%; -}
\ No newline at end of file diff --git a/src/views/collections/CollectionFreeFormView.tsx b/src/views/collections/CollectionFreeFormView.tsx deleted file mode 100644 index 612f9acbe..000000000 --- a/src/views/collections/CollectionFreeFormView.tsx +++ /dev/null @@ -1,206 +0,0 @@ -import { observer } from "mobx-react"; -import { Key, KeyStore } from "../../fields/Key"; -import React = require("react"); -import { action, observable, computed } from "mobx"; -import { Document } from "../../fields/Document"; -import { CollectionFreeFormDocumentView } from "../nodes/CollectionFreeFormDocumentView"; -import { ListField } from "../../fields/ListField"; -import { NumberField } from "../../fields/NumberField"; -import { SSL_OP_SINGLE_DH_USE } from "constants"; -import { Documents } from "../../documents/Documents"; -import { DragManager } from "../../util/DragManager"; -import "./CollectionFreeFormView.scss"; -import { Utils } from "../../Utils"; -import { CollectionViewBase, CollectionViewProps, COLLECTION_BORDER_WIDTH } from "./CollectionViewBase"; -import { SelectionManager } from "../../util/SelectionManager"; -import { FieldWaiting } from "../../fields/Field"; - -@observer -export class CollectionFreeFormView extends CollectionViewBase { - public static LayoutString() { return CollectionViewBase.LayoutString("CollectionFreeFormView"); } - private _containerRef = React.createRef<HTMLDivElement>(); - private _canvasRef = React.createRef<HTMLDivElement>(); - private _nodeContainerRef = React.createRef<HTMLDivElement>(); - private _lastX: number = 0; - private _lastY: number = 0; - - constructor(props: CollectionViewProps) { - super(props); - } - - @action - drop = (e: Event, de: DragManager.DropEvent) => { - const doc = de.data["document"]; - var me = this; - if (doc instanceof CollectionFreeFormDocumentView) { - if (doc.props.ContainingCollectionView && doc.props.ContainingCollectionView !== this) { - doc.props.ContainingCollectionView.removeDocument(doc.props.Document); - this.addDocument(doc.props.Document); - } - const xOffset = de.data["xOffset"] as number || 0; - const yOffset = de.data["yOffset"] as number || 0; - const { scale, translateX, translateY } = Utils.GetScreenTransform(this._canvasRef.current!); - let sscale = this.props.ContainingDocumentView!.props.Document.GetData(KeyStore.Scale, NumberField, Number(1)) - const screenX = de.x - xOffset; - const screenY = de.y - yOffset; - const docX = (screenX - translateX) / sscale / scale; - const docY = (screenY - translateY) / sscale / scale; - doc.x = docX; - doc.y = docY; - this.bringToFront(doc); - } - e.stopPropagation(); - } - - componentDidMount() { - if (this._containerRef.current) { - DragManager.MakeDropTarget(this._containerRef.current, { - handlers: { - drop: this.drop - } - }); - } - } - - @action - onPointerDown = (e: React.PointerEvent): void => { - if ((e.button === 2 && this.active) || - !e.defaultPrevented) { - document.removeEventListener("pointermove", this.onPointerMove); - document.addEventListener("pointermove", this.onPointerMove); - document.removeEventListener("pointerup", this.onPointerUp); - document.addEventListener("pointerup", this.onPointerUp); - this._lastX = e.pageX; - this._lastY = e.pageY; - } - } - - @action - onPointerUp = (e: PointerEvent): void => { - document.removeEventListener("pointermove", this.onPointerMove); - document.removeEventListener("pointerup", this.onPointerUp); - e.stopPropagation(); - SelectionManager.DeselectAll(); - } - - @action - onPointerMove = (e: PointerEvent): void => { - var me = this; - if (!e.cancelBubble && this.active) { - e.preventDefault(); - e.stopPropagation(); - let currScale: number = this.props.ContainingDocumentView!.ScalingToScreenSpace; - let x = this.props.DocumentForCollection.GetData(KeyStore.PanX, NumberField, Number(0)); - let y = this.props.DocumentForCollection.GetData(KeyStore.PanY, NumberField, Number(0)); - this.props.DocumentForCollection.SetData(KeyStore.PanX, x + (e.pageX - this._lastX) / currScale, NumberField); - this.props.DocumentForCollection.SetData(KeyStore.PanY, y + (e.pageY - this._lastY) / currScale, NumberField); - } - this._lastX = e.pageX; - this._lastY = e.pageY; - } - - @action - onPointerWheel = (e: React.WheelEvent): void => { - e.stopPropagation(); - - let { LocalX, Ss, Panxx, Xx, LocalY, Panyy, Yy, ContainerX, ContainerY } = this.props.ContainingDocumentView!.TransformToLocalPoint(e.pageX, e.pageY); - - var deltaScale = (1 - (e.deltaY / 1000)) * Ss; - - var newContainerX = LocalX * deltaScale + Panxx + Xx; - var newContainerY = LocalY * deltaScale + Panyy + Yy; - - let dx = ContainerX - newContainerX; - let dy = ContainerY - newContainerY; - - this.props.DocumentForCollection.Set(KeyStore.Scale, new NumberField(deltaScale)); - this.props.DocumentForCollection.SetData(KeyStore.PanX, Panxx + dx, NumberField); - this.props.DocumentForCollection.SetData(KeyStore.PanY, Panyy + dy, NumberField); - } - - @action - onDrop = (e: React.DragEvent): void => { - e.stopPropagation() - e.preventDefault() - let fReader = new FileReader() - let file = e.dataTransfer.items[0].getAsFile(); - let that = this; - const panx: number = this.props.DocumentForCollection.GetData(KeyStore.PanX, NumberField, Number(0)); - const pany: number = this.props.DocumentForCollection.GetData(KeyStore.PanY, NumberField, Number(0)); - let x = e.pageX - panx - let y = e.pageY - pany - - fReader.addEventListener("load", action("drop", (event) => { - if (fReader.result) { - let url = "" + fReader.result; - let doc = Documents.ImageDocument(url, { - x: x, y: y - }) - let docs = that.props.DocumentForCollection.GetT(KeyStore.Data, ListField); - if (docs != FieldWaiting) { - if (!docs) { - docs = new ListField<Document>(); - that.props.DocumentForCollection.Set(KeyStore.Data, docs) - } - docs.Data.push(doc); - } - } - }), false) - - if (file) { - fReader.readAsDataURL(file) - } - } - - onDragOver = (e: React.DragEvent): void => { - } - - @action - bringToFront(doc: CollectionFreeFormDocumentView) { - const { CollectionFieldKey: fieldKey, DocumentForCollection: Document } = this.props; - - const value: Document[] = Document.GetList<Document>(fieldKey, []); - var topmost = value.reduce((topmost, d) => Math.max(d.GetNumber(KeyStore.ZIndex, 0), topmost), -1000); - value.map(d => { - var zind = d.GetNumber(KeyStore.ZIndex, 0); - if (zind != topmost - 1 - (topmost - zind) && d != doc.props.Document) { - d.SetData(KeyStore.ZIndex, topmost - 1 - (topmost - zind), NumberField); - } - }) - - if (doc.props.Document.GetNumber(KeyStore.ZIndex, 0) != 0) { - doc.props.Document.SetData(KeyStore.ZIndex, 0, NumberField); - } - } - - render() { - const { CollectionFieldKey: fieldKey, DocumentForCollection: Document } = this.props; - const value: Document[] = Document.GetList<Document>(fieldKey, []); - const panx: number = Document.GetNumber(KeyStore.PanX, 0); - const pany: number = Document.GetNumber(KeyStore.PanY, 0); - const currScale: number = Document.GetNumber(KeyStore.Scale, 1); - - return ( - <div className="border" style={{ - borderWidth: `${COLLECTION_BORDER_WIDTH}px`, - }}> - <div className="collectionfreeformview-container" - onPointerDown={this.onPointerDown} - onWheel={this.onPointerWheel} - onContextMenu={(e) => e.preventDefault()} - onDrop={this.onDrop} - onDragOver={this.onDragOver} - ref={this._containerRef}> - <div className="collectionfreeformview" style={{ transform: `translate(${panx}px, ${pany}px) scale(${currScale}, ${currScale})`, transformOrigin: `left, top` }} ref={this._canvasRef}> - - <div className="node-container" ref={this._nodeContainerRef}> - {value.map(doc => { - return (<CollectionFreeFormDocumentView key={doc.Id} ContainingCollectionView={this} Document={doc} DocumentView={undefined} />); - })} - </div> - </div> - </div> - </div> - ); - } -}
\ No newline at end of file diff --git a/src/views/collections/CollectionSchemaView.scss b/src/views/collections/CollectionSchemaView.scss deleted file mode 100644 index 707b44db6..000000000 --- a/src/views/collections/CollectionSchemaView.scss +++ /dev/null @@ -1,108 +0,0 @@ -.Resizer { - box-sizing: border-box; - background: #000; - opacity: 0.5; - z-index: 1; - background-clip: padding-box; - &.horizontal { - height: 11px; - margin: -5px 0; - border-top: 5px solid rgba(255, 255, 255, 0); - border-bottom: 5px solid rgba(255, 255, 255, 0); - cursor: row-resize; - width: 100%; - &:hover { - border-top: 5px solid rgba(0, 0, 0, 0.5); - border-bottom: 5px solid rgba(0, 0, 0, 0.5); - } - } - &.vertical { - width: 11px; - margin: 0 -5px; - border-left: 5px solid rgba(255, 255, 255, 0); - border-right: 5px solid rgba(255, 255, 255, 0); - cursor: col-resize; - &:hover { - border-left: 5px solid rgba(0, 0, 0, 0.5); - border-right: 5px solid rgba(0, 0, 0, 0.5); - } - } - &:hover { - -webkit-transition: all 2s ease; - transition: all 2s ease; - } -} - -.vertical { - section { - width: 100vh; - height: 100vh; - display: -webkit-box; - display: -webkit-flex; - display: -ms-flexbox; - display: flex; - -webkit-box-orient: vertical; - -webkit-box-direction: normal; - -webkit-flex-direction: column; - -ms-flex-direction: column; - flex-direction: column; - } - header { - padding: 1rem; - background: #eee; - } - footer { - padding: 1rem; - background: #eee; - } -} - -.horizontal { - section { - width: 100vh; - height: 100vh; - display: flex; - flex-direction: column; - } - header { - padding: 1rem; - background: #eee; - } - footer { - padding: 1rem; - background: #eee; - } -} - -.parent { - width: 100%; - height: 100%; - -webkit-box-flex: 1; - -webkit-flex: 1; - -ms-flex: 1; - flex: 1; - display: -webkit-box; - display: -webkit-flex; - display: -ms-flexbox; - display: flex; - -webkit-box-orient: vertical; - -webkit-box-direction: normal; - -webkit-flex-direction: column; - -ms-flex-direction: column; - flex-direction: column; -} - -.header { - background: #aaa; - height: 3rem; - line-height: 3rem; -} - -.wrapper { - background: #ffa; - margin: 5rem; - -webkit-box-flex: 1; - -webkit-flex: 1; - -ms-flex: 1; - flex: 1; -}
\ No newline at end of file diff --git a/src/views/collections/CollectionSchemaView.tsx b/src/views/collections/CollectionSchemaView.tsx deleted file mode 100644 index 6f591a1bc..000000000 --- a/src/views/collections/CollectionSchemaView.tsx +++ /dev/null @@ -1,144 +0,0 @@ -import React = require("react") -import ReactTable, { ReactTableDefaults, CellInfo, ComponentPropsGetterRC, ComponentPropsGetterR } from "react-table"; -import { observer } from "mobx-react"; -import { KeyStore as KS, Key } from "../../fields/Key"; -import { Document } from "../../fields/Document"; -import { FieldView, FieldViewProps } from "../nodes/FieldView"; -import "react-table/react-table.css" -import { observable, action, computed } from "mobx"; -import SplitPane from "react-split-pane" -import "./CollectionSchemaView.scss" -import { ScrollBox } from "../../util/ScrollBox"; -import { CollectionViewBase } from "./CollectionViewBase"; -import { DocumentView } from "../nodes/DocumentView"; -import { EditableView } from "../EditableView"; -import { CompileScript, ToField } from "../../util/Scripting"; -import { Field } from "../../fields/Field"; - -@observer -export class CollectionSchemaView extends CollectionViewBase { - public static LayoutString() { return CollectionViewBase.LayoutString("CollectionSchemaView"); } - - @observable - selectedIndex = 0; - - renderCell = (rowProps: CellInfo) => { - let props: FieldViewProps = { - doc: rowProps.value[0], - fieldKey: rowProps.value[1], - DocumentViewForField: undefined - } - let contents = ( - <FieldView {...props} /> - ) - return ( - <EditableView contents={contents} GetValue={() => { - let field = props.doc.Get(props.fieldKey); - if (field && field instanceof Field) { - return field.ToScriptString(); - } - return field || ""; - }} SetValue={(value: string) => { - let script = CompileScript(value); - if (!script.compiled) { - return false; - } - let field = script(); - if (field instanceof Field) { - props.doc.Set(props.fieldKey, field); - return true; - } else { - let dataField = ToField(field); - if (dataField) { - props.doc.Set(props.fieldKey, dataField); - return true; - } - } - return false; - }}></EditableView> - ) - } - - private getTrProps: ComponentPropsGetterR = (state, rowInfo) => { - const that = this; - if (!rowInfo) { - return {}; - } - return { - onClick: action((e: React.MouseEvent, handleOriginal: Function) => { - that.selectedIndex = rowInfo.index; - const doc: Document = rowInfo.original; - console.log("Row clicked: ", doc.Title) - - if (handleOriginal) { - handleOriginal() - } - }), - style: { - background: rowInfo.index == this.selectedIndex ? "#00afec" : "white", - color: rowInfo.index == this.selectedIndex ? "white" : "black" - } - }; - } - - onPointerDown = (e: React.PointerEvent) => { - let target = e.target as HTMLElement; - if (target.tagName == "SPAN" && target.className.includes("Resizer")) { - e.stopPropagation(); - } - if (e.button === 2 && this.active) { - e.stopPropagation(); - e.preventDefault(); - } else { - if (e.buttons === 1 && this.active) { - e.stopPropagation(); - } - } - } - - render() { - const { DocumentForCollection: Document, CollectionFieldKey: fieldKey } = this.props; - const children = Document.GetList<Document>(fieldKey, []); - const columns = Document.GetList(KS.ColumnsKey, - [KS.Title, KS.Data, KS.Author]) - let content; - if (this.selectedIndex != -1) { - content = ( - <DocumentView Document={children[this.selectedIndex]} DocumentView={undefined} ContainingCollectionView={this} /> - ) - } else { - content = <div /> - } - return ( - <div onPointerDown={this.onPointerDown} > - <SplitPane split={"vertical"} defaultSize="60%"> - <ScrollBox> - <ReactTable - data={children} - pageSize={children.length} - page={0} - showPagination={false} - style={{ - display: "inline-block" - }} - columns={columns.map(col => { - return ( - { - Header: col.Name, - accessor: (doc: Document) => [doc, col], - id: col.Id - }) - })} - column={{ - ...ReactTableDefaults.column, - Cell: this.renderCell - }} - getTrProps={this.getTrProps} - /> - </ScrollBox> - {content} - </SplitPane> - </div> - ) - } -}
\ No newline at end of file diff --git a/src/views/collections/CollectionViewBase.tsx b/src/views/collections/CollectionViewBase.tsx deleted file mode 100644 index 35d938d43..000000000 --- a/src/views/collections/CollectionViewBase.tsx +++ /dev/null @@ -1,57 +0,0 @@ -import { action, computed } from "mobx"; -import { observer } from "mobx-react"; -import { Document } from "../../fields/Document"; -import { Opt } from "../../fields/Field"; -import { Key, KeyStore } from "../../fields/Key"; -import { ListField } from "../../fields/ListField"; -import { SelectionManager } from "../../util/SelectionManager"; -import { ContextMenu } from "../ContextMenu"; -import React = require("react"); -import { DocumentView } from "../nodes/DocumentView"; -import { CollectionDockingView } from "./CollectionDockingView"; -import { CollectionFreeFormDocumentView } from "../nodes/CollectionFreeFormDocumentView"; - - -export interface CollectionViewProps { - CollectionFieldKey: Key; - DocumentForCollection: Document; - ContainingDocumentView: Opt<DocumentView>; -} - -export const COLLECTION_BORDER_WIDTH = 2; - -@observer -export class CollectionViewBase extends React.Component<CollectionViewProps> { - - public static LayoutString(collectionType: string) { - return `<${collectionType} DocumentForCollection={Document} CollectionFieldKey={DataKey} ContainingDocumentView={DocumentView}/>`; - } - @computed - public get active(): boolean { - var isSelected = (this.props.ContainingDocumentView instanceof CollectionFreeFormDocumentView && SelectionManager.IsSelected(this.props.ContainingDocumentView)); - var childSelected = SelectionManager.SelectedDocuments().some(view => view.props.ContainingCollectionView == this); - var topMost = this.props.ContainingDocumentView != undefined && ( - this.props.ContainingDocumentView.props.ContainingCollectionView == undefined || - this.props.ContainingDocumentView.props.ContainingCollectionView instanceof CollectionDockingView); - return isSelected || childSelected || topMost; - } - @action - addDocument = (doc: Document): void => { - //TODO This won't create the field if it doesn't already exist - const value = this.props.DocumentForCollection.GetData(this.props.CollectionFieldKey, ListField, new Array<Document>()) - value.push(doc); - } - - @action - removeDocument = (doc: Document): void => { - //TODO This won't create the field if it doesn't already exist - const value = this.props.DocumentForCollection.GetData(this.props.CollectionFieldKey, ListField, new Array<Document>()) - if (value.indexOf(doc) !== -1) { - value.splice(value.indexOf(doc), 1) - - SelectionManager.DeselectAll() - ContextMenu.Instance.clearItems() - } - } - -}
\ No newline at end of file diff --git a/src/views/nodes/CollectionFreeFormDocumentView.tsx b/src/views/nodes/CollectionFreeFormDocumentView.tsx deleted file mode 100644 index e0bb459e9..000000000 --- a/src/views/nodes/CollectionFreeFormDocumentView.tsx +++ /dev/null @@ -1,223 +0,0 @@ -import { action, computed } from "mobx"; -import { observer } from "mobx-react"; -import { Key, KeyStore } from "../../fields/Key"; -import { NumberField } from "../../fields/NumberField"; -import { DragManager } from "../../util/DragManager"; -import { SelectionManager } from "../../util/SelectionManager"; -import { CollectionDockingView } from "../collections/CollectionDockingView"; -import { CollectionFreeFormView } from "../collections/CollectionFreeFormView"; -import { ContextMenu } from "../ContextMenu"; -import "./NodeView.scss"; -import React = require("react"); -import { DocumentView, DocumentViewProps } from "./DocumentView"; - - -@observer -export class CollectionFreeFormDocumentView extends DocumentView { - private _contextMenuCanOpen = false; - private _downX: number = 0; - private _downY: number = 0; - - constructor(props: DocumentViewProps) { - super(props); - } - get screenRect(): ClientRect | DOMRect { - if (this._mainCont.current) { - return this._mainCont.current.getBoundingClientRect(); - } - return new DOMRect(); - } - - @computed - get x(): number { - return this.props.Document.GetData(KeyStore.X, NumberField, Number(0)); - } - - @computed - get y(): number { - return this.props.Document.GetData(KeyStore.Y, NumberField, Number(0)); - } - - set x(x: number) { - this.props.Document.SetData(KeyStore.X, x, NumberField) - } - - set y(y: number) { - this.props.Document.SetData(KeyStore.Y, y, NumberField) - } - - @computed - get transform(): string { - return `translate(${this.x}px, ${this.y}px)`; - } - - @computed - get width(): number { - return this.props.Document.GetData(KeyStore.Width, NumberField, Number(0)); - } - - set width(w: number) { - this.props.Document.SetData(KeyStore.Width, w, NumberField) - } - - @computed - get height(): number { - return this.props.Document.GetData(KeyStore.Height, NumberField, Number(0)); - } - - set height(h: number) { - this.props.Document.SetData(KeyStore.Height, h, NumberField) - } - - @computed - get zIndex(): number { - return this.props.Document.GetData(KeyStore.ZIndex, NumberField, Number(0)); - } - - set zIndex(h: number) { - this.props.Document.SetData(KeyStore.ZIndex, h, NumberField) - } - - @action - dragComplete = (e: DragManager.DragCompleteEvent) => { - } - - @computed - get active(): boolean { - return SelectionManager.IsSelected(this) || this.props.ContainingCollectionView === undefined || - this.props.ContainingCollectionView.active; - } - - @computed - get topMost(): boolean { - return this.props.ContainingCollectionView == undefined || this.props.ContainingCollectionView instanceof CollectionDockingView; - } - - onPointerDown = (e: React.PointerEvent): void => { - this._downX = e.clientX; - this._downY = e.clientY; - var me = this; - if (e.shiftKey && e.buttons === 1) { - CollectionDockingView.StartOtherDrag(this._mainCont.current!, this.props.Document); - e.stopPropagation(); - return; - } - this._contextMenuCanOpen = e.button == 2; - if (this.active && !e.isDefaultPrevented()) { - e.stopPropagation(); - if (e.buttons === 2) { - e.preventDefault(); - } - document.removeEventListener("pointermove", this.onPointerMove) - document.addEventListener("pointermove", this.onPointerMove); - document.removeEventListener("pointerup", this.onPointerUp) - document.addEventListener("pointerup", this.onPointerUp); - } - } - - onPointerMove = (e: PointerEvent): void => { - if (e.cancelBubble) { - this._contextMenuCanOpen = false; - return; - } - if (Math.abs(this._downX - e.clientX) > 3 || Math.abs(this._downY - e.clientY) > 3) { - this._contextMenuCanOpen = false; - if (this._mainCont.current != null && !this.topMost) { - this._contextMenuCanOpen = false; - const rect = this.screenRect; - let dragData: { [id: string]: any } = {}; - dragData["document"] = this; - dragData["xOffset"] = e.x - rect.left; - dragData["yOffset"] = e.y - rect.top; - DragManager.StartDrag(this._mainCont.current, dragData, { - handlers: { - dragComplete: this.dragComplete, - }, - hideSource: true - }) - } - } - e.stopPropagation(); - e.preventDefault(); - } - - onPointerUp = (e: PointerEvent): void => { - document.removeEventListener("pointermove", this.onPointerMove) - document.removeEventListener("pointerup", this.onPointerUp) - e.stopPropagation(); - if (Math.abs(e.clientX - this._downX) < 4 && Math.abs(e.clientY - this._downY) < 4) { - SelectionManager.SelectDoc(this, e.ctrlKey); - } - } - - openRight = (e: React.MouseEvent): void => { - CollectionDockingView.AddRightSplit(this.props.Document); - } - - deleteClicked = (e: React.MouseEvent): void => { - if (this.props.ContainingCollectionView instanceof CollectionFreeFormView) { - this.props.ContainingCollectionView.removeDocument(this.props.Document) - } - } - @action - fullScreenClicked = (e: React.MouseEvent): void => { - CollectionDockingView.OpenFullScreen(this.props.Document); - ContextMenu.Instance.clearItems(); - ContextMenu.Instance.addItem({ description: "Close Full Screen", event: this.closeFullScreenClicked }); - ContextMenu.Instance.displayMenu(e.pageX - 15, e.pageY - 15) - } - @action - closeFullScreenClicked = (e: React.MouseEvent): void => { - CollectionDockingView.CloseFullScreen(); - ContextMenu.Instance.clearItems(); - ContextMenu.Instance.addItem({ description: "Full Screen", event: this.fullScreenClicked }) - ContextMenu.Instance.displayMenu(e.pageX - 15, e.pageY - 15) - } - - @action - onContextMenu = (e: React.MouseEvent): void => { - if (!SelectionManager.IsSelected(this)) { - return; - } - e.preventDefault() - - if (!this._contextMenuCanOpen) { - return; - } - - if (this.topMost) { - ContextMenu.Instance.clearItems() - ContextMenu.Instance.addItem({ description: "Full Screen", event: this.fullScreenClicked }) - ContextMenu.Instance.displayMenu(e.pageX - 15, e.pageY - 15) - } - else { - // DocumentViews should stop propogation of this event - e.stopPropagation(); - - ContextMenu.Instance.clearItems(); - ContextMenu.Instance.addItem({ description: "Full Screen", event: this.fullScreenClicked }) - ContextMenu.Instance.addItem({ description: "Open Right", event: this.openRight }) - ContextMenu.Instance.addItem({ description: "Delete", event: this.deleteClicked }) - ContextMenu.Instance.displayMenu(e.pageX - 15, e.pageY - 15) - SelectionManager.SelectDoc(this, e.ctrlKey); - } - } - - render() { - var freestyling = this.props.ContainingCollectionView instanceof CollectionFreeFormView; - return ( - <div className="node" ref={this._mainCont} style={{ - transform: freestyling ? this.transform : "", - width: freestyling ? this.width : "100%", - height: freestyling ? this.height : "100%", - position: freestyling ? "absolute" : "relative", - zIndex: freestyling ? this.zIndex : 0, - }} - onContextMenu={this.onContextMenu} - onPointerDown={this.onPointerDown}> - - <DocumentView {...this.props} DocumentView={this} /> - </div> - ); - } -}
\ No newline at end of file diff --git a/src/views/nodes/DocumentView.tsx b/src/views/nodes/DocumentView.tsx deleted file mode 100644 index 39be54a4d..000000000 --- a/src/views/nodes/DocumentView.tsx +++ /dev/null @@ -1,153 +0,0 @@ -import { action, computed } from "mobx"; -import { observer } from "mobx-react"; -import { Document } from "../../fields/Document"; -import { Opt, FieldWaiting } from "../../fields/Field"; -import { Key, KeyStore } from "../../fields/Key"; -import { ListField } from "../../fields/ListField"; -import { NumberField } from "../../fields/NumberField"; -import { TextField } from "../../fields/TextField"; -import { Utils } from "../../Utils"; -import { CollectionDockingView } from "../collections/CollectionDockingView"; -import { CollectionFreeFormView } from "../collections/CollectionFreeFormView"; -import { CollectionSchemaView } from "../collections/CollectionSchemaView"; -import { CollectionViewBase, COLLECTION_BORDER_WIDTH } from "../collections/CollectionViewBase"; -import { FormattedTextBox } from "../nodes/FormattedTextBox"; -import { ImageBox } from "../nodes/ImageBox"; -import "./NodeView.scss"; -import React = require("react"); -const JsxParser = require('react-jsx-parser').default;//TODO Why does this need to be imported like this? - -export interface DocumentViewProps { - Document: Document; - DocumentView: Opt<DocumentView> // needed only to set ContainingDocumentView on CollectionViewProps when invoked from JsxParser -- is there a better way? - ContainingCollectionView: Opt<CollectionViewBase>; -} -@observer -export class DocumentView extends React.Component<DocumentViewProps> { - - protected _mainCont = React.createRef<any>(); - get MainContent() { - return this._mainCont; - } - @computed - get layout(): string { - return this.props.Document.GetData(KeyStore.Layout, TextField, String("<p>Error loading layout data</p>")); - } - - @computed - get layoutKeys(): Key[] { - return this.props.Document.GetData(KeyStore.LayoutKeys, ListField, new Array<Key>()); - } - - @computed - get layoutFields(): Key[] { - return this.props.Document.GetData(KeyStore.LayoutFields, ListField, new Array<Key>()); - } - - // - // returns the cumulative scaling between the document and the screen - // - @computed - public get ScalingToScreenSpace(): number { - if (this.props.ContainingCollectionView != undefined && - this.props.ContainingCollectionView.props.ContainingDocumentView != undefined) { - let ss = this.props.ContainingCollectionView.props.DocumentForCollection.GetData(KeyStore.Scale, NumberField, Number(1)); - return this.props.ContainingCollectionView.props.ContainingDocumentView.ScalingToScreenSpace * ss; - } - return 1; - } - - // - // Converts a coordinate in the screen space of the app into a local document coordinate. - // - public TransformToLocalPoint(screenX: number, screenY: number) { - // if this collection view is nested within another collection view, then - // first transform the screen point into the parent collection's coordinate space. - let { LocalX: parentX, LocalY: parentY } = this.props.ContainingCollectionView != undefined && - this.props.ContainingCollectionView.props.ContainingDocumentView != undefined ? - this.props.ContainingCollectionView.props.ContainingDocumentView.TransformToLocalPoint(screenX, screenY) : - { LocalX: screenX, LocalY: screenY }; - let ContainerX: number = parentX - COLLECTION_BORDER_WIDTH; - let ContainerY: number = parentY - COLLECTION_BORDER_WIDTH; - - var Xx = this.props.Document.GetData(KeyStore.X, NumberField, Number(0)); - var Yy = this.props.Document.GetData(KeyStore.Y, NumberField, Number(0)); - // CollectionDockingViews change the location of their children frames without using a Dash transformation. - // They also ignore any transformation that may have been applied to their content document. - // NOTE: this currently assumes CollectionDockingViews aren't nested. - if (this.props.ContainingCollectionView instanceof CollectionDockingView) { - var { translateX: rx, translateY: ry } = Utils.GetScreenTransform(this.MainContent.current!); - Xx = rx - COLLECTION_BORDER_WIDTH; - Yy = ry - COLLECTION_BORDER_WIDTH; - } - - let Ss = this.props.Document.GetData(KeyStore.Scale, NumberField, Number(1)); - let Panxx = this.props.Document.GetData(KeyStore.PanX, NumberField, Number(0)); - let Panyy = this.props.Document.GetData(KeyStore.PanY, NumberField, Number(0)); - let LocalX = (ContainerX - (Xx + Panxx)) / Ss; - let LocalY = (ContainerY - (Yy + Panyy)) / Ss; - - return { LocalX, Ss, 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 } { - - var Xx = this.props.Document.GetData(KeyStore.X, NumberField, Number(0)); - var Yy = this.props.Document.GetData(KeyStore.Y, NumberField, Number(0)); - // CollectionDockingViews change the location of their children frames without using a Dash transformation. - // They also ignore any transformation that may have been applied to their content document. - // NOTE: this currently assumes CollectionDockingViews aren't nested. - if (this.props.ContainingCollectionView instanceof CollectionDockingView) { - var { translateX: rx, translateY: ry } = Utils.GetScreenTransform(this.MainContent.current!); - Xx = rx - COLLECTION_BORDER_WIDTH; - Yy = ry - COLLECTION_BORDER_WIDTH; - } - - let W = COLLECTION_BORDER_WIDTH; - let H = COLLECTION_BORDER_WIDTH; - let parentX = (localX - W) * Ss + (Xx + Panxx) + W; - let parentY = (localY - H) * Ss + (Yy + Panyy) + H; - - // if this collection view is nested within another collection view, then - // first transform the local point into the parent collection's coordinate space. - let containingDocView = this.props.ContainingCollectionView != undefined ? this.props.ContainingCollectionView.props.ContainingDocumentView : undefined; - if (containingDocView != undefined) { - let ss = containingDocView.props.Document.GetData(KeyStore.Scale, NumberField, Number(1)); - let panxx = containingDocView.props.Document.GetData(KeyStore.PanX, NumberField, Number(0)) + COLLECTION_BORDER_WIDTH * ss; - let panyy = containingDocView.props.Document.GetData(KeyStore.PanY, NumberField, Number(0)) + COLLECTION_BORDER_WIDTH * ss; - let { ScreenX, ScreenY } = containingDocView.TransformToScreenPoint(parentX, parentY, ss, panxx, panyy); - parentX = ScreenX; - parentY = ScreenY; - } - return { ScreenX: parentX, ScreenY: parentY }; - } - - - render() { - let bindings = { ...this.props } as any; - for (const key of this.layoutKeys) { - bindings[key.Name + "Key"] = key; // this maps string values of the form <keyname>Key to an actual key Kestore.keyname e.g, "DataKey" => KeyStore.Data - } - for (const key of this.layoutFields) { - let field = this.props.Document.Get(key); - bindings[key.Name] = field && field != FieldWaiting ? field.GetValue() : field; - } - if (bindings.DocumentView === undefined) { - bindings.DocumentView = this; // set the DocumentView to this if it hasn't already been set by a sub-class during its render method. - } - return ( - <div className="node" ref={this._mainCont} style={{ width: "100%", height: "100%", }}> - <JsxParser - components={{ FormattedTextBox: FormattedTextBox, ImageBox, CollectionFreeFormView, CollectionDockingView, CollectionSchemaView }} - bindings={bindings} - jsx={this.layout} - showWarnings={true} - onError={(test: any) => { console.log(test) }} - /> - </div> - ) - } -} diff --git a/src/views/nodes/FieldTextBox.scss b/src/views/nodes/FieldTextBox.scss deleted file mode 100644 index b6ce2fabc..000000000 --- a/src/views/nodes/FieldTextBox.scss +++ /dev/null @@ -1,14 +0,0 @@ -.ProseMirror { - margin-top: -1em; - width: 100%; - height: 100%; -} - -.ProseMirror:focus { - outline: none !important -} - -.fieldTextBox-cont { - background: white; - padding: 1vw; -}
\ No newline at end of file diff --git a/src/views/nodes/FieldView.tsx b/src/views/nodes/FieldView.tsx deleted file mode 100644 index 3a7652284..000000000 --- a/src/views/nodes/FieldView.tsx +++ /dev/null @@ -1,56 +0,0 @@ -import React = require("react") -import { Document } from "../../fields/Document"; -import { observer } from "mobx-react"; -import { computed } from "mobx"; -import { Field, Opt, FieldWaiting, FieldValue } from "../../fields/Field"; -import { TextField } from "../../fields/TextField"; -import { NumberField } from "../../fields/NumberField"; -import { RichTextField } from "../../fields/RichTextField"; -import { FormattedTextBox } from "./FormattedTextBox"; -import { ImageField } from "../../fields/ImageField"; -import { ImageBox } from "./ImageBox"; -import { Key } from "../../fields/Key"; -import { DocumentView } from "./DocumentView"; - -// -// these properties get assigned through the render() method of the DocumentView when it creates this node. -// However, that only happens because the properties are "defined" in the markup for the field view. -// See the LayoutString method on each field view : ImageBox, FormattedTextBox, etc. -// -export interface FieldViewProps { - fieldKey: Key; - doc: Document; - DocumentViewForField: Opt<DocumentView> -} - -@observer -export class FieldView extends React.Component<FieldViewProps> { - public static LayoutString(fieldType: string) { return `<${fieldType} doc={Document} DocumentViewForField={DocumentView} fieldKey={DataKey} />`; } - @computed - get field(): FieldValue<Field> { - const { doc, fieldKey } = this.props; - return doc.Get(fieldKey); - } - render() { - const field = this.field; - if (!field) { - return <p>{'<null>'}</p> - } - if (field instanceof TextField) { - return <p>{field.Data}</p> - } - else if (field instanceof RichTextField) { - return <FormattedTextBox {...this.props} /> - } - else if (field instanceof ImageField) { - return <ImageBox {...this.props} /> - } - else if (field instanceof NumberField) { - return <p>{field.Data}</p> - } else if (field != FieldWaiting) { - return <p>{field.GetValue}</p> - } else - return <p> {"Waiting for server..."} </p> - } - -}
\ No newline at end of file diff --git a/src/views/nodes/FormattedTextBox.scss b/src/views/nodes/FormattedTextBox.scss deleted file mode 100644 index 492367fce..000000000 --- a/src/views/nodes/FormattedTextBox.scss +++ /dev/null @@ -1,14 +0,0 @@ -.ProseMirror { - margin-top: -1em; - width: 100%; - height: 100%; -} - -.ProseMirror:focus { - outline: none !important -} - -.formattedTextBox-cont { - background: white; - padding: 1vw; -}
\ No newline at end of file diff --git a/src/views/nodes/FormattedTextBox.tsx b/src/views/nodes/FormattedTextBox.tsx deleted file mode 100644 index 6d0e117cc..000000000 --- a/src/views/nodes/FormattedTextBox.tsx +++ /dev/null @@ -1,127 +0,0 @@ -import { action, IReactionDisposer, reaction } from "mobx"; -import { observer } from "mobx-react" -import { baseKeymap } from "prosemirror-commands"; -import { history, redo, undo } from "prosemirror-history"; -import { keymap } from "prosemirror-keymap"; -import { schema } from "prosemirror-schema-basic"; -import { EditorState, Transaction } from "prosemirror-state"; -import { EditorView } from "prosemirror-view"; -import { Opt, FieldWaiting, FieldValue } from "../../fields/Field"; -import { SelectionManager } from "../../util/SelectionManager"; -import "./FormattedTextBox.scss"; -import React = require("react") -import { RichTextField } from "../../fields/RichTextField"; -import { FieldViewProps, FieldView } from "./FieldView"; -import { CollectionFreeFormDocumentView } from "./CollectionFreeFormDocumentView"; - - -// FormattedTextBox: Displays an editable plain text node that maps to a specified Key of a Document -// -// HTML Markup: <FormattedTextBox Doc={Document's ID} FieldKey={Key's name + "Key"} -// -// In Code, the node's HTML is specified in the document's parameterized structure as: -// document.SetField(KeyStore.Layout, "<FormattedTextBox doc={doc} fieldKey={<KEYNAME>Key} />"); -// and the node's binding to the specified document KEYNAME as: -// document.SetField(KeyStore.LayoutKeys, new ListField([KeyStore.<KEYNAME>])); -// The Jsx parser at run time will bind: -// 'fieldKey' property to the Key stored in LayoutKeys -// and 'doc' property to the document that is being rendered -// -// When rendered() by React, this extracts the TextController from the Document stored at the -// specified Key and assigns it to an HTML input node. When changes are made tot his node, -// this will edit the document and assign the new value to that field. -//] -@observer -export class FormattedTextBox extends React.Component<FieldViewProps> { - - public static LayoutString() { return FieldView.LayoutString("FormattedTextBox"); } - private _ref: React.RefObject<HTMLDivElement>; - private _editorView: Opt<EditorView>; - private _reactionDisposer: Opt<IReactionDisposer>; - - constructor(props: FieldViewProps) { - super(props); - - this._ref = React.createRef(); - - this.onChange = this.onChange.bind(this); - } - - dispatchTransaction = (tx: Transaction) => { - if (this._editorView) { - const state = this._editorView.state.apply(tx); - this._editorView.updateState(state); - const { doc, fieldKey } = this.props; - doc.SetData(fieldKey, JSON.stringify(state.toJSON()), RichTextField); - } - } - - componentDidMount() { - let state: EditorState; - const { doc, fieldKey } = this.props; - const config = { - schema, - plugins: [ - history(), - keymap({ "Mod-z": undo, "Mod-y": redo }), - keymap(baseKeymap) - ] - }; - - let field = doc.GetT(fieldKey, RichTextField); - if (field && field != FieldWaiting) { // bcz: don't think this works - state = EditorState.fromJSON(config, JSON.parse(field.Data)); - } else { - state = EditorState.create(config); - } - if (this._ref.current) { - this._editorView = new EditorView(this._ref.current, { - state, - dispatchTransaction: this.dispatchTransaction - }); - } - - this._reactionDisposer = reaction(() => { - const field = this.props.doc.GetT(this.props.fieldKey, RichTextField); - return field && field != FieldWaiting ? field.Data : undefined; - }, (field) => { - if (field && this._editorView) { - this._editorView.updateState(EditorState.fromJSON(config, JSON.parse(field))); - } - }) - } - - componentWillUnmount() { - if (this._editorView) { - this._editorView.destroy(); - } - if (this._reactionDisposer) { - this._reactionDisposer(); - } - } - - shouldComponentUpdate() { - return false; - } - - @action - onChange(e: React.ChangeEvent<HTMLInputElement>) { - const { fieldKey, doc } = this.props; - doc.SetData(fieldKey, e.target.value, RichTextField); - } - onPointerDown = (e: React.PointerEvent): void => { - let me = this; - if (e.buttons === 1 && me.props.DocumentViewForField instanceof CollectionFreeFormDocumentView && SelectionManager.IsSelected(me.props.DocumentViewForField)) { - e.stopPropagation(); - } - } - render() { - return (<div className="formattedTextBox-cont" - style={{ - color: "initial", - whiteSpace: "initial" - }} - onPointerDown={this.onPointerDown} - ref={this._ref} />) - } -}
\ No newline at end of file diff --git a/src/views/nodes/ImageBox.scss b/src/views/nodes/ImageBox.scss deleted file mode 100644 index 136fda1d0..000000000 --- a/src/views/nodes/ImageBox.scss +++ /dev/null @@ -1,11 +0,0 @@ - -.imageBox-cont { - padding: 0vw; -} - -.imageBox-button { - padding : 0vw; - border: none; - width : 100%; - height: 100%; -}
\ No newline at end of file diff --git a/src/views/nodes/ImageBox.tsx b/src/views/nodes/ImageBox.tsx deleted file mode 100644 index 123c76d19..000000000 --- a/src/views/nodes/ImageBox.tsx +++ /dev/null @@ -1,92 +0,0 @@ - -import Lightbox from 'react-image-lightbox'; -import 'react-image-lightbox/style.css'; // This only needs to be imported once in your app -import { SelectionManager } from "../../util/SelectionManager"; -import "./ImageBox.scss"; -import React = require("react") -import { ImageField } from '../../fields/ImageField'; -import { FieldViewProps, FieldView } from './FieldView'; -import { CollectionFreeFormDocumentView } from './CollectionFreeFormDocumentView'; -import { FieldWaiting } from '../../fields/Field'; -import { observer } from "mobx-react" -import { observable, action } from 'mobx'; - -@observer -export class ImageBox extends React.Component<FieldViewProps> { - - public static LayoutString() { return FieldView.LayoutString("ImageBox"); } - private _ref: React.RefObject<HTMLDivElement>; - private _downX: number = 0; - private _downY: number = 0; - private _lastTap: number = 0; - @observable private _photoIndex: number = 0; - @observable private _isOpen: boolean = false; - - constructor(props: FieldViewProps) { - super(props); - - this._ref = React.createRef(); - this.state = { - photoIndex: 0, - isOpen: false, - }; - } - - componentDidMount() { - } - - componentWillUnmount() { - } - - onPointerDown = (e: React.PointerEvent): void => { - if (Date.now() - this._lastTap < 300) { - if (e.buttons === 1 && this.props.DocumentViewForField instanceof CollectionFreeFormDocumentView && SelectionManager.IsSelected(this.props.DocumentViewForField)) { - e.stopPropagation(); - this._downX = e.clientX; - this._downY = e.clientY; - document.removeEventListener("pointerup", this.onPointerUp); - document.addEventListener("pointerup", this.onPointerUp); - } - } else { - this._lastTap = Date.now(); - } - } - @action - onPointerUp = (e: PointerEvent): void => { - document.removeEventListener("pointerup", this.onPointerUp); - if (Math.abs(e.clientX - this._downX) < 2 && Math.abs(e.clientY - this._downY) < 2) { - this._isOpen = true; - } - e.stopPropagation(); - } - - lightbox = (path: string) => { - const images = [path, "http://www.cs.brown.edu/~bcz/face.gif"]; - if (this._isOpen && this.props.DocumentViewForField instanceof CollectionFreeFormDocumentView && SelectionManager.IsSelected(this.props.DocumentViewForField)) { - return (<Lightbox - mainSrc={images[this._photoIndex]} - nextSrc={images[(this._photoIndex + 1) % images.length]} - prevSrc={images[(this._photoIndex + images.length - 1) % images.length]} - onCloseRequest={() => this.setState({ isOpen: false })} - onMovePrevRequest={action(() => - this._photoIndex = (this._photoIndex + images.length - 1) % images.length - )} - onMoveNextRequest={action(() => - this._photoIndex = (this._photoIndex + 1) % images.length - )} - />) - } - } - - render() { - let field = this.props.doc.Get(this.props.fieldKey); - let path = field == FieldWaiting ? "https://image.flaticon.com/icons/svg/66/66163.svg" : - field instanceof ImageField ? field.Data.href : "http://www.cs.brown.edu/~bcz/face.gif"; - - return ( - <div className="imageBox-cont" onPointerDown={this.onPointerDown} ref={this._ref} > - <img src={path} width="100%" alt="Image not found" /> - {this.lightbox(path)} - </div>) - } -}
\ No newline at end of file diff --git a/src/views/nodes/NodeView.scss b/src/views/nodes/NodeView.scss deleted file mode 100644 index dac1c0a8e..000000000 --- a/src/views/nodes/NodeView.scss +++ /dev/null @@ -1,23 +0,0 @@ -.node { - position: absolute; - background: #cdcdcd; - overflow: hidden; - &.minimized { - width: 30px; - height: 30px; - } - .top { - background: #232323; - height: 20px; - cursor: pointer; - } - .content { - padding: 20px 20px; - height: auto; - box-sizing: border-box; - } - .scroll-box { - overflow-y: scroll; - height: calc(100% - 20px); - } -}
\ No newline at end of file |