From f80cddf158c6a43259d68ed0be9bfe084d464b4a Mon Sep 17 00:00:00 2001 From: bob Date: Tue, 19 Feb 2019 09:29:34 -0500 Subject: converted docking collection to use a GoldenLayout layout string for its data --- src/client/documents/Documents.ts | 1 + 1 file changed, 1 insertion(+) (limited to 'src/client/documents') diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts index 72fa608ad..36119e552 100644 --- a/src/client/documents/Documents.ts +++ b/src/client/documents/Documents.ts @@ -169,6 +169,7 @@ export namespace Documents { export function CollectionDocument(documents: Array, options: DocumentOptions = {}): Document { let doc = GetCollectionPrototype().MakeDelegate(); + Server.AddDocument(doc); setupOptions(doc, options); doc.Set(KeyStore.Data, new ListField(documents)); return doc; -- cgit v1.2.3-70-g09d2 From 1f5cc996f5f64dc0e706a79ec3e0816fd9f895b1 Mon Sep 17 00:00:00 2001 From: bob Date: Tue, 19 Feb 2019 11:13:22 -0500 Subject: added layout saving/loading to collectiondockingview & cleaned up to use react-component --- src/client/documents/Documents.ts | 4 +- src/client/views/Main.tsx | 82 +++--- .../views/collections/CollectionDockingView.tsx | 303 +++++++++------------ src/client/views/nodes/DocumentView.tsx | 8 +- 4 files changed, 174 insertions(+), 223 deletions(-) (limited to 'src/client/documents') diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts index 36119e552..f954b37a8 100644 --- a/src/client/documents/Documents.ts +++ b/src/client/documents/Documents.ts @@ -107,10 +107,10 @@ export namespace Documents { return dockProto; } - export function DockDocument(documents: Array, options: DocumentOptions = {}): Document { + export function DockDocument(config: string, options: DocumentOptions = {}): Document { let doc = GetDockPrototype().MakeDelegate(); setupOptions(doc, options); - doc.Set(KeyStore.Data, new ListField(documents)); + doc.SetText(KeyStore.Data, config); return doc; } diff --git a/src/client/views/Main.tsx b/src/client/views/Main.tsx index 933c904fb..a86fdb9b0 100644 --- a/src/client/views/Main.tsx +++ b/src/client/views/Main.tsx @@ -14,6 +14,7 @@ import { ContextMenu } from './ContextMenu'; import { DocumentView } from './nodes/DocumentView'; import { ImageField } from '../../fields/ImageField'; import { Transform } from '../util/Transform'; +import { CollectionDockingView } from './collections/CollectionDockingView'; configure({ @@ -21,9 +22,6 @@ configure({ }); const mainNodeCollection = new Array(); -let mainContainer = Documents.DockDocument(mainNodeCollection, { - x: 0, y: 0, title: "main container" -}) window.addEventListener("drop", function (e) { e.preventDefault(); @@ -38,49 +36,41 @@ document.addEventListener("pointerdown", action(function (e: PointerEvent) { }), true) -//runInAction(() => -{ - let doc1 = Documents.TextDocument({ title: "hello", width: 400, height: 300 }); - let doc2 = doc1.MakeDelegate(); - doc2.Set(KS.X, new NumberField(150)); - doc2.Set(KS.Y, new NumberField(20)); - let doc3 = Documents.ImageDocument("https://psmag.com/.image/t_share/MTMyNzc2NzM1MDY1MjgzMDM4/shutterstock_151341212jpg.jpg", { - x: 450, y: 100, title: "dog", width: 606, height: 386, nativeWidth: 606, nativeHeight: 386 - }); - //doc3.Set(KeyStore.Data, new ImageField); - const schemaDocs = Array.from(Array(5).keys()).map(v => Documents.ImageDocument("https://psmag.com/.image/t_share/MTMyNzc2NzM1MDY1MjgzMDM4/shutterstock_151341212jpg.jpg", { - x: 50 + 100 * v, y: 50, width: 100, height: 100, title: "cat" + v, nativeWidth: 606, nativeHeight: 386 - })); - schemaDocs.push(doc3); - schemaDocs[0].SetData(KS.Author, "Tyler", TextField); - schemaDocs[4].SetData(KS.Author, "Bob", TextField); - schemaDocs.push(doc2); - const doc7 = Documents.SchemaDocument(schemaDocs) - const docset = [doc1, doc2, doc3, doc7]; - let doc4 = Documents.CollectionDocument(docset, { - x: 0, y: 400, title: "mini collection" - }); - // let doc5 = Documents.ImageDocument("https://upload.wikimedia.org/wikipedia/commons/thumb/3/3a/Cat03.jpg/1200px-Cat03.jpg", { - // x: 650, y: 500, width: 600, height: 600, title: "cat 2" - // }); - let docset2 = [doc3, doc4, doc2]; - let doc6 = Documents.CollectionDocument(docset2, { - x: 350, y: 100, width: 600, height: 600, title: "docking collection" - }); - let mainNodes = mainContainer.GetOrCreate>(KeyStore.Data, ListField); - // mainNodes.Data.push(doc6); - // mainNodes.Data.push(doc2); - mainNodes.Data.push(doc4); - mainNodes.Data.push(doc3); - // mainNodes.Data.push(doc5); - // mainNodes.Data.push(doc1); - // mainNodes.Data.push(doc2); - mainNodes.Data.push(doc6); - var layoutstr = `{"settings":{"hasHeaders":true,"constrainDragToContainer":true,"reorderEnabled":true,"selectionEnabled":true,"popoutWholeStack":false,"blockedPopoutsThrowError":true,"closePopoutsOnUnload":true,"showPopoutIcon":true,"showMaximiseIcon":true,"showCloseIcon":true,"responsiveMode":"onload","tabOverlapAllowance":0,"reorderOnTabMenuClick":true,"tabControlOffset":10},"dimensions":{"borderWidth":5,"borderGrabWidth":15,"minItemHeight":10,"minItemWidth":10,"headerHeight":20,"dragProxyWidth":300,"dragProxyHeight":200},"labels":{"close":"close","maximise":"maximise","minimise":"minimise","popout":"open in new window","popin":"pop in","tabDropdown":"additional tabs"},"content":[{"type":"row","isClosable":true,"reorderEnabled":true,"title":"","content":[{"type":"stack","width":33.333333333333336,"isClosable":true,"reorderEnabled":true,"title":"","activeItemIndex":0,"content":[{"type":"component","componentName":"documentViewComponent","componentState":{"doc":"${doc3.Id}","title":"mini collection","scaling":1},"isClosable":true,"reorderEnabled":true,"title":"documentViewComponent"}]},{"type":"stack","width":33.333333333333336,"isClosable":true,"reorderEnabled":true,"title":"","activeItemIndex":0,"content":[{"type":"component","componentName":"documentViewComponent","componentState":{"doc":"${doc6.Id}","title":"","scaling":1},"isClosable":true,"reorderEnabled":true,"title":"documentViewComponent"}]},{"type":"stack","width":16.666666666666668,"isClosable":true,"reorderEnabled":true,"title":"","activeItemIndex":0,"content":[{"type":"component","componentName":"documentViewComponent","componentState":{"doc":"${doc4.Id}","title":"docking collection","scaling":1},"isClosable":true,"reorderEnabled":true,"title":"documentViewComponent"}]},{"type":"stack","isClosable":true,"reorderEnabled":true,"title":"","width":16.666666666666668,"activeItemIndex":0,"content":[{"type":"component","componentName":"documentViewComponent","componentState":{"doc":"${doc4.Id}","title":"hello"},"isClosable":true,"reorderEnabled":true,"title":"documentViewComponent"}]}]}],"isClosable":true,"reorderEnabled":true,"title":"","openPopouts":[],"maximisedItemId":null}` - mainContainer.SetText(KeyStore.Data, layoutstr) -} -//} -//); +let doc1 = Documents.TextDocument({ title: "hello", width: 400, height: 300 }); +let doc2 = doc1.MakeDelegate(); +doc2.Set(KS.X, new NumberField(150)); +doc2.Set(KS.Y, new NumberField(20)); +let doc3 = Documents.ImageDocument("https://psmag.com/.image/t_share/MTMyNzc2NzM1MDY1MjgzMDM4/shutterstock_151341212jpg.jpg", { + x: 450, y: 100, title: "dog", width: 606, height: 386, nativeWidth: 606, nativeHeight: 386 +}); +//doc3.Set(KeyStore.Data, new ImageField); +const schemaDocs = Array.from(Array(5).keys()).map(v => Documents.ImageDocument("https://psmag.com/.image/t_share/MTMyNzc2NzM1MDY1MjgzMDM4/shutterstock_151341212jpg.jpg", { + x: 50 + 100 * v, y: 50, width: 100, height: 100, title: "cat" + v, nativeWidth: 606, nativeHeight: 386 +})); +schemaDocs.push(doc3); +schemaDocs[0].SetData(KS.Author, "Tyler", TextField); +schemaDocs[4].SetData(KS.Author, "Bob", TextField); +schemaDocs.push(doc2); +const doc7 = Documents.SchemaDocument(schemaDocs) +const docset = [doc1, doc2, doc3, doc7]; +let doc4 = Documents.CollectionDocument(docset, { + x: 0, y: 400, title: "mini collection" +}); +// let doc5 = Documents.ImageDocument("https://upload.wikimedia.org/wikipedia/commons/thumb/3/3a/Cat03.jpg/1200px-Cat03.jpg", { +// x: 650, y: 500, width: 600, height: 600, title: "cat 2" +// }); +let docset2 = [doc3, doc4, doc2]; +let doc6 = Documents.CollectionDocument(docset2, { + x: 350, y: 100, width: 600, height: 600, title: "docking collection" +}); + +var docs = [doc4, doc3, doc6].map(doc => CollectionDockingView.makeDocumentConfig(doc)); +var config = { + settings: { selectionEnabled: false }, content: [{ type: 'row', content: docs }] +}; +let mainContainer = Documents.DockDocument(JSON.stringify(config), { + x: 0, y: 0, title: "main container" +}) ReactDOM.render((
diff --git a/src/client/views/collections/CollectionDockingView.tsx b/src/client/views/collections/CollectionDockingView.tsx index 4c83186f8..9cc92712e 100644 --- a/src/client/views/collections/CollectionDockingView.tsx +++ b/src/client/views/collections/CollectionDockingView.tsx @@ -1,4 +1,3 @@ -import FlexLayout from "flexlayout-react"; import * as GoldenLayout from "golden-layout"; import 'golden-layout/src/css/goldenlayout-base.css'; import 'golden-layout/src/css/goldenlayout-dark-theme.css'; @@ -8,7 +7,6 @@ import { Document } from "../../../fields/Document"; import { KeyStore } from "../../../fields/Key"; import { ListField } from "../../../fields/ListField"; import { DragManager } from "../../util/DragManager"; -import { Transform } from "../../util/Transform"; import { DocumentView } from "../nodes/DocumentView"; import "./CollectionDockingView.scss"; import { CollectionViewBase, CollectionViewProps, COLLECTION_BORDER_WIDTH } from "./CollectionViewBase"; @@ -22,73 +20,37 @@ import { Server } from "../../Server"; @observer export class CollectionDockingView extends CollectionViewBase { - private static UseGoldenLayout = true; + public static Instance: CollectionDockingView; public static LayoutString() { return CollectionViewBase.LayoutString("CollectionDockingView"); } - private _containerRef = React.createRef(); - @computed - private get modelForGoldenLayout(): GoldenLayout { - var json = this.props.Document.GetText(KeyStore.Data, ""); - if (json != "") { - return new GoldenLayout(JSON.parse(json)) - } - const { fieldKey: fieldKey, Document: Document } = this.props; - const value: Document[] = Document.GetData(fieldKey, ListField, []); - var docs = value.map(doc => { - return { type: 'component', componentName: 'documentViewComponent', componentState: { doc: doc.Id, title: doc.Title, scaling: 1 } }; - }); - 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 + public static makeDocumentConfig(document: Document) { + return { + type: 'react-component', + component: 'DocumentFrameRenderer', + title: document.Title, + props: { + documentId: document.Id, + CollectionDockingView: CollectionDockingView.Instance, + } } } - 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); - } + private _goldenLayout: any = null; + private _dragDiv: any = null; + private _dragParent: HTMLElement | null = null; + private _dragElement: HTMLDivElement | undefined; + private _dragFakeElement: HTMLDivElement | undefined; + private _containerRef = React.createRef(); + private _makeFullScreen: boolean = false; + private _maximizedStack: any = null; - @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(); - } - } + constructor(props: CollectionViewProps) { + super(props); + CollectionDockingView.Instance = this; + (window as any).React = React; + (window as any).ReactDOM = ReactDOM; } - 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.Id, title: dragDoc.Title, scaling: 1 } - }; + public StartOtherDrag(dragElement: HTMLDivElement, dragDoc: Document) { this._dragElement = dragElement; this._dragParent = dragElement.parentElement; // bcz: we want to copy this document into the header, not move it there. @@ -98,7 +60,7 @@ export class CollectionDockingView extends CollectionViewBase { this._dragDiv = document.createElement("div"); this._dragDiv.style.opacity = 0; DragManager.Root().appendChild(this._dragDiv); - CollectionDockingView.myLayout.createDragSource(this._dragDiv, newItemConfig); + this._goldenLayout.createDragSource(this._dragDiv, CollectionDockingView.makeDocumentConfig(dragDoc)); // - add our document to that div so that GoldenLayout will get the move events its listening for this._dragDiv.appendChild(this._dragElement); @@ -111,40 +73,29 @@ export class CollectionDockingView extends CollectionViewBase { // 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.Id, title: document.Title } - }; - CollectionDockingView.myLayout._makeFullScreen = true; - CollectionDockingView.myLayout.root.contentItems[0].addChild(newItemConfig); + public OpenFullScreen(document: Document) { + this._makeFullScreen = true; + this._goldenLayout.root.contentItems[0].addChild(CollectionDockingView.makeDocumentConfig(document)); } - public static CloseFullScreen() { - if (CollectionDockingView.myLayout._maximizedStack != null) { - CollectionDockingView.myLayout._maximizedStack.header.controlsContainer.find('.lm_close').click(); - CollectionDockingView.myLayout._maximizedStack = null; + public CloseFullScreen() { + if (this._maximizedStack) { + this._maximizedStack.header.controlsContainer.find('.lm_close').click(); + this._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.Id, title: document.Title } - } + public AddRightSplit(document: Document) { let newItemStackConfig = { type: 'stack', - content: [newItemConfig] + content: [CollectionDockingView.makeDocumentConfig(document)] }; - var newContentItem = new CollectionDockingView.myLayout._typeToItem[newItemStackConfig.type](CollectionDockingView.myLayout, newItemStackConfig, parent); + var newContentItem = new this._goldenLayout._typeToItem[newItemStackConfig.type](this._goldenLayout, newItemStackConfig, parent); - if (CollectionDockingView.myLayout.root.contentItems[0].isRow) { - var rowlayout = CollectionDockingView.myLayout.root.contentItems[0]; + if (this._goldenLayout.root.contentItems[0].isRow) { + var rowlayout = this._goldenLayout.root.contentItems[0]; var lastRowItem = rowlayout.contentItems[rowlayout.contentItems.length - 1]; lastRowItem.config["width"] *= 0.5; @@ -153,8 +104,8 @@ export class CollectionDockingView extends CollectionViewBase { rowlayout.callDownwards('setSize'); } else { - var collayout = CollectionDockingView.myLayout.root.contentItems[0]; - var newRow = collayout.layoutManager.createContentItem({ type: "row" }, CollectionDockingView.myLayout); + var collayout = this._goldenLayout.root.contentItems[0]; + var newRow = collayout.layoutManager.createContentItem({ type: "row" }, this._goldenLayout); collayout.parent.replaceChild(collayout, newRow); newRow.addChild(newContentItem, undefined, true); @@ -164,70 +115,75 @@ export class CollectionDockingView extends CollectionViewBase { newContentItem.config["width"] = 50; collayout.parent.callDownwards('setSize'); } - var state = JSON.stringify(CollectionDockingView.myLayout.toConfig()); - console.log(state); } - 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; + componentDidMount: () => void = () => { + if (this._containerRef.current) { + + this._goldenLayout = new GoldenLayout(JSON.parse(this.props.Document.GetText(KeyStore.Data, ""))); + this._goldenLayout.on('tabCreated', this.tabCreated); + this._goldenLayout.on('stackCreated', this.stackCreated); + this._goldenLayout.registerComponent('DocumentFrameRenderer', DockedFrameRenderer); + this._goldenLayout.container = this._containerRef.current; + this._goldenLayout.init(); + + 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); + } + @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 + this._goldenLayout.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(); } - tab.setTitle(tab.contentItem.config.componentState.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'); + tabCreated = (tab: any) => { + { + if (this._dragDiv) { + this._dragDiv.removeChild(this._dragElement); + this._dragParent!.removeChild(this._dragFakeElement!); + this._dragParent!.appendChild(this._dragElement!); + DragManager.Root().removeChild(this._dragDiv); + this._dragDiv = null; } - //stack.header.controlsContainer.find('.lm_popout').hide(); - stack.header.controlsContainer.find('.lm_close') //get the close icon - .off('click') //unbind the current click handler + //tab.setTitle(tab.contentItem.config.componentState.title); + tab.closeElement.off('click') //unbind the current click handler .click(function () { - //if (confirm('really close this?')) { - stack.remove(); - //} + tab.contentItem.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("
"); - setTimeout(function () { - let divContainer = document.getElementById(containingDiv) as HTMLDivElement; - if (divContainer) { - let props: DockingProps = { - ContainingDiv: containingDiv, - DocumentId: state.doc, - Container: container, - CollectionDockingView: me, - HtmlElement: divContainer, - } - ReactDOM.render((), divContainer); - if (CollectionDockingView.myLayout._maxstack) { - CollectionDockingView.myLayout._maxstack.click(); - } - } - }, 0); - }); - CollectionDockingView.myLayout.container = this._containerRef.current; - CollectionDockingView.myLayout.init(); + stackCreated = (stack: any) => { + if (this._makeFullScreen) { + this._maximizedStack = stack; + setTimeout(function () { stack.header.controlsContainer.find('.lm_maximise').click() }, 10); + this._makeFullScreen = false; + } + //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(); + //} + }); } @@ -243,8 +199,8 @@ export class CollectionDockingView extends CollectionViewBase { diff --git a/src/client/views/collections/CollectionSchemaView.tsx b/src/client/views/collections/CollectionSchemaView.tsx index 5ec288b13..9405c820f 100644 --- a/src/client/views/collections/CollectionSchemaView.tsx +++ b/src/client/views/collections/CollectionSchemaView.tsx @@ -13,12 +13,10 @@ import { EditableView } from "../EditableView"; import { DocumentView } from "../nodes/DocumentView"; import { FieldView, FieldViewProps } from "../nodes/FieldView"; import "./CollectionSchemaView.scss"; -import { CollectionViewBase, COLLECTION_BORDER_WIDTH } from "./CollectionViewBase"; +import { COLLECTION_BORDER_WIDTH, CollectionViewProps, SubCollectionViewProps } from "./CollectionView"; @observer -export class CollectionSchemaView extends CollectionViewBase { - public static LayoutString(fieldKey: string = "DataKey") { return CollectionViewBase.LayoutString("CollectionSchemaView", fieldKey); } - +export class CollectionSchemaView extends React.Component { private _mainCont = React.createRef(); private DIVIDER_WIDTH = 5; @@ -34,6 +32,7 @@ export class CollectionSchemaView extends CollectionViewBase { doc: rowProps.value[0], fieldKey: rowProps.value[1], isSelected: () => false, + select: () => { }, isTopMost: false } let contents = ( @@ -112,7 +111,7 @@ export class CollectionSchemaView extends CollectionViewBase { // e.preventDefault(); // } else { - if (e.buttons === 1 && this.active) { + if (e.buttons === 1 && this.props.active()) { e.stopPropagation(); } } @@ -145,12 +144,12 @@ export class CollectionSchemaView extends CollectionViewBase { {({ measureRef }) =>
+ ContainingCollectionView={this.props.CollectionView} />
} diff --git a/src/client/views/collections/CollectionView.tsx b/src/client/views/collections/CollectionView.tsx new file mode 100644 index 000000000..651d85879 --- /dev/null +++ b/src/client/views/collections/CollectionView.tsx @@ -0,0 +1,116 @@ +import { action, computed } from "mobx"; +import { observer } from "mobx-react"; +import { Document } from "../../../fields/Document"; +import { Key } from "../../../fields/Key"; +import { ListField } from "../../../fields/ListField"; +import { SelectionManager } from "../../util/SelectionManager"; +import { ContextMenu } from "../ContextMenu"; +import React = require("react"); +import { Transform } from "../../util/Transform"; +import { KeyStore } from "../../../fields/KeyStore"; +import { NumberField } from "../../../fields/NumberField"; +import { CollectionFreeFormView } from "./CollectionFreeFormView"; +import { CollectionDockingView } from "./CollectionDockingView"; +import { CollectionSchemaView } from "./CollectionSchemaView"; +import { Opt } from "../../../fields/Field"; + + +export interface CollectionViewProps { + fieldKey: Key; + Document: Document; + ScreenToLocalTransform: () => Transform; + isSelected: () => boolean; + isTopMost: boolean; + select: (ctrlPressed: boolean) => void; + BackgroundView?: () => JSX.Element; +} + +export interface SubCollectionViewProps extends CollectionViewProps { + active: () => boolean; + addDocument: (doc: Document) => void; + removeDocument: (doc: Document) => boolean; + CollectionView: Opt; +} + +export enum CollectionViewType { + Invalid, + Freeform, + Schema, + Docking, +} + +export const COLLECTION_BORDER_WIDTH = 2; + +@observer +export class CollectionView extends React.Component { + + public static LayoutString(fieldKey: string = "DataKey") { + return ``; + } + public active = () => { + var isSelected = this.props.isSelected(); + var childSelected = SelectionManager.SelectedDocuments().some(view => view.props.ContainingCollectionView == this); + var topMost = this.props.isTopMost; + 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.Document.GetData(this.props.fieldKey, ListField, new Array()) + value.push(doc); + } + + @action + removeDocument = (doc: Document): boolean => { + //TODO This won't create the field if it doesn't already exist + const value = this.props.Document.GetData(this.props.fieldKey, ListField, new Array()) + let index = value.indexOf(doc); + if (index !== -1) { + value.splice(index, 1) + + SelectionManager.DeselectAll() + ContextMenu.Instance.clearItems() + return true; + } + return false + } + + get collectionViewType(): CollectionViewType { + let Document = this.props.Document; + let viewField = Document.GetT(KeyStore.ViewType, NumberField); + if (viewField === "") { + return CollectionViewType.Invalid; + } else if (viewField) { + return viewField.Data; + } else { + return CollectionViewType.Freeform; + } + } + + set collectionViewType(type: CollectionViewType) { + let Document = this.props.Document; + Document.SetData(KeyStore.ViewType, type, NumberField); + } + + render() { + let viewType = this.collectionViewType; + switch (viewType) { + case CollectionViewType.Freeform: + return () + case CollectionViewType.Schema: + return () + case CollectionViewType.Docking: + return () + default: + return
+ } + } +} \ No newline at end of file diff --git a/src/client/views/collections/CollectionViewBase.tsx b/src/client/views/collections/CollectionViewBase.tsx deleted file mode 100644 index 0acc890d8..000000000 --- a/src/client/views/collections/CollectionViewBase.tsx +++ /dev/null @@ -1,61 +0,0 @@ -import { action, computed } from "mobx"; -import { observer } from "mobx-react"; -import { Document } from "../../../fields/Document"; -import { Key } from "../../../fields/Key"; -import { ListField } from "../../../fields/ListField"; -import { SelectionManager } from "../../util/SelectionManager"; -import { ContextMenu } from "../ContextMenu"; -import React = require("react"); -import { Transform } from "../../util/Transform"; - - -export interface CollectionViewProps { - fieldKey: Key; - Document: Document; - ScreenToLocalTransform: () => Transform; - isSelected: () => boolean; - isTopMost: boolean; - select: (ctrlPressed: boolean) => void; - BackgroundView?: () => JSX.Element; -} - -export const COLLECTION_BORDER_WIDTH = 2; - -@observer -export class CollectionViewBase extends React.Component { - - public static LayoutString(collectionType: string, fieldKey: string = "DataKey") { - return `<${collectionType} Document={Document} - ScreenToLocalTransform={ScreenToLocalTransform} fieldKey={${fieldKey}} isSelected={isSelected} select={select} - isTopMost={isTopMost} BackgroundView={BackgroundView} />`; - } - @computed - public get active(): boolean { - var isSelected = this.props.isSelected(); - var childSelected = SelectionManager.SelectedDocuments().some(view => view.props.ContainingCollectionView == this); - var topMost = this.props.isTopMost; - 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.Document.GetData(this.props.fieldKey, ListField, new Array()) - value.push(doc); - } - - @action - removeDocument = (doc: Document): boolean => { - //TODO This won't create the field if it doesn't already exist - const value = this.props.Document.GetData(this.props.fieldKey, ListField, new Array()) - let index = value.indexOf(doc); - if (index !== -1) { - value.splice(index, 1) - - SelectionManager.DeselectAll() - ContextMenu.Instance.clearItems() - return true; - } - return false - } - -} \ No newline at end of file diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx index 7cf00a116..2114a5697 100644 --- a/src/client/views/nodes/DocumentView.tsx +++ b/src/client/views/nodes/DocumentView.tsx @@ -9,7 +9,7 @@ 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 { COLLECTION_BORDER_WIDTH, CollectionView, CollectionViewType } from "../collections/CollectionView"; import { FormattedTextBox } from "../nodes/FormattedTextBox"; import { ImageBox } from "../nodes/ImageBox"; import "./DocumentView.scss"; @@ -22,7 +22,7 @@ import { TextField } from "../../../fields/TextField"; const JsxParser = require('react-jsx-parser').default;//TODO Why does this need to be imported like this? export interface DocumentViewProps { - ContainingCollectionView: Opt; + ContainingCollectionView: Opt; Document: Document; AddDocument?: (doc: Document) => void; @@ -114,7 +114,7 @@ export class DocumentView extends React.Component { @computed get active(): boolean { return SelectionManager.IsSelected(this) || !this.props.ContainingCollectionView || - this.props.ContainingCollectionView.active; + this.props.ContainingCollectionView.active(); } private _contextMenuCanOpen = false; @@ -233,6 +233,9 @@ export class DocumentView extends React.Component { 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.addItem({ description: "Freeform", event: () => { this.props.Document.SetNumber(KeyStore.ViewType, CollectionViewType.Freeform) } }) + ContextMenu.Instance.addItem({ description: "Schema", event: () => { this.props.Document.SetNumber(KeyStore.ViewType, CollectionViewType.Schema) } }) + ContextMenu.Instance.addItem({ description: "Docking", event: () => { this.props.Document.SetNumber(KeyStore.ViewType, CollectionViewType.Docking) } }) ContextMenu.Instance.displayMenu(e.pageX - 15, e.pageY - 15) SelectionManager.SelectDoc(this, e.ctrlKey); } @@ -275,7 +278,7 @@ export class DocumentView extends React.Component { let backgroundLayout = this.backgroundLayout; if (backgroundLayout) { let backgroundView = () => ( { onContextMenu={this.onContextMenu} onPointerDown={this.onPointerDown} > boolean; + select: () => void; isTopMost: boolean; } @observer export class FieldView extends React.Component { - public static LayoutString(fieldType: { name: string }) { return `<${fieldType.name} doc={Document} DocumentViewForField={DocumentView} fieldKey={DataKey} isSelected={isSelected} isTopMost={isTopMost} />`; } + public static LayoutString(fieldType: { name: string }) { return `<${fieldType.name} doc={Document} DocumentViewForField={DocumentView} fieldKey={DataKey} isSelected={isSelected} select={select} isTopMost={isTopMost} />`; } @computed get field(): FieldValue { const { doc, fieldKey } = this.props; diff --git a/src/fields/BasicField.ts b/src/fields/BasicField.ts index 91977b243..a92c4a236 100644 --- a/src/fields/BasicField.ts +++ b/src/fields/BasicField.ts @@ -32,7 +32,7 @@ export abstract class BasicField extends Field { return; } let oldValue = this.data; - this.data = value; + this.setData(value); UndoManager.AddEvent({ undo: () => this.Data = oldValue, redo: () => this.Data = value @@ -40,6 +40,10 @@ export abstract class BasicField extends Field { Server.UpdateField(this); } + protected setData(value: T) { + this.data = value; + } + @action TrySetValue(value: any): boolean { if (typeof value == typeof this.data) { diff --git a/src/fields/Document.ts b/src/fields/Document.ts index 6667485b6..ff13732b3 100644 --- a/src/fields/Document.ts +++ b/src/fields/Document.ts @@ -90,6 +90,15 @@ export class Document extends Field { return field; } + GetAsync(key: Key, callback: (field: Field) => void): boolean { + //This currently doesn't deal with prototypes + if (this._proxies.has(key.Id)) { + Server.GetDocumentField(this, key, callback); + return true; + } + return false; + } + GetT(key: Key, ctor: { new(...args: any[]): T }, ignoreProto: boolean = false): FieldValue { var getfield = this.Get(key, ignoreProto); if (getfield != FieldWaiting) { diff --git a/src/fields/KeyStore.ts b/src/fields/KeyStore.ts index 7056886aa..6d6c6a546 100644 --- a/src/fields/KeyStore.ts +++ b/src/fields/KeyStore.ts @@ -16,6 +16,7 @@ export namespace KeyStore { export const ZIndex = new Key("ZIndex"); export const Data = new Key("Data"); export const Annotations = new Key("Annotations"); + export const ViewType = new Key("ViewType"); export const Layout = new Key("Layout"); export const BackgroundLayout = new Key("BackgroundLayout"); export const LayoutKeys = new Key("LayoutKeys"); diff --git a/src/fields/ListField.ts b/src/fields/ListField.ts index 75c2eb343..700600804 100644 --- a/src/fields/ListField.ts +++ b/src/fields/ListField.ts @@ -1,4 +1,4 @@ -import { action, IArrayChange, IArraySplice, IObservableArray, observe } from "mobx"; +import { action, IArrayChange, IArraySplice, IObservableArray, observe, observable, Lambda } from "mobx"; import { Server } from "../client/Server"; import { UndoManager } from "../client/util/UndoManager"; import { Types } from "../server/Message"; @@ -13,7 +13,12 @@ export class ListField extends BasicField { if (save) { Server.UpdateField(this); } - observe(this.Data as IObservableArray, (change: IArrayChange | IArraySplice) => { + this.observeList(); + } + + private observeDisposer: Lambda | undefined; + private observeList(): void { + this.observeDisposer = observe(this.Data as IObservableArray, (change: IArrayChange | IArraySplice) => { this.updateProxies() if (change.type == "splice") { UndoManager.AddEvent({ @@ -27,7 +32,15 @@ export class ListField extends BasicField { }) } Server.UpdateField(this); - }) + }); + } + + protected setData(value: T[]) { + if (this.observeDisposer) { + this.observeDisposer() + } + this.data = observable(value); + this.observeList(); } private updateProxies() { -- cgit v1.2.3-70-g09d2 From 9b23c5123abf42c3751938d831556cdb94ad3951 Mon Sep 17 00:00:00 2001 From: bob Date: Fri, 22 Feb 2019 13:42:25 -0500 Subject: moved common code into CollectionViewBase. --- src/client/documents/Documents.ts | 2 +- src/client/util/DragManager.ts | 1 + .../views/collections/CollectionDockingView.tsx | 3 +- .../views/collections/CollectionFreeFormView.tsx | 59 ++-------------- .../views/collections/CollectionSchemaView.tsx | 13 ++-- src/client/views/collections/CollectionView.tsx | 20 +----- .../views/collections/CollectionViewBase.tsx | 82 ++++++++++++++++++++++ 7 files changed, 102 insertions(+), 78 deletions(-) create mode 100644 src/client/views/collections/CollectionViewBase.tsx (limited to 'src/client/documents') diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts index bfa6cb7a9..156a09316 100644 --- a/src/client/documents/Documents.ts +++ b/src/client/documents/Documents.ts @@ -13,7 +13,7 @@ import { CollectionFreeFormView } from "../views/collections/CollectionFreeFormV import { FieldId } from "../../fields/Field"; import { CollectionView, CollectionViewType } from "../views/collections/CollectionView"; -interface DocumentOptions { +export interface DocumentOptions { x?: number; y?: number; width?: number; diff --git a/src/client/util/DragManager.ts b/src/client/util/DragManager.ts index 6d5fe12a7..eb4b3aeaa 100644 --- a/src/client/util/DragManager.ts +++ b/src/client/util/DragManager.ts @@ -44,6 +44,7 @@ export namespace DragManager { drop: (e: Event, de: DropEvent) => void; } + export function MakeDropTarget(element: HTMLElement, options: DropOptions): DragDropDisposer { if ("canDrop" in element.dataset) { throw new Error("Element is already droppable, can't make it droppable again"); diff --git a/src/client/views/collections/CollectionDockingView.tsx b/src/client/views/collections/CollectionDockingView.tsx index 752007439..857af023d 100644 --- a/src/client/views/collections/CollectionDockingView.tsx +++ b/src/client/views/collections/CollectionDockingView.tsx @@ -14,8 +14,9 @@ import { DragManager } from "../../util/DragManager"; import { undoBatch } from "../../util/UndoManager"; import { DocumentView } from "../nodes/DocumentView"; import "./CollectionDockingView.scss"; -import { CollectionViewProps, COLLECTION_BORDER_WIDTH, SubCollectionViewProps } from "./CollectionView"; +import { COLLECTION_BORDER_WIDTH } from "./CollectionView"; import React = require("react"); +import { SubCollectionViewProps } from "./CollectionViewBase"; @observer export class CollectionDockingView extends React.Component { diff --git a/src/client/views/collections/CollectionFreeFormView.tsx b/src/client/views/collections/CollectionFreeFormView.tsx index b78b1a3b6..b8312aff7 100644 --- a/src/client/views/collections/CollectionFreeFormView.tsx +++ b/src/client/views/collections/CollectionFreeFormView.tsx @@ -4,20 +4,18 @@ import { action, computed, trace } from "mobx"; import { CollectionFreeFormDocumentView } from "../nodes/CollectionFreeFormDocumentView"; import { DragManager } from "../../util/DragManager"; import "./CollectionFreeFormView.scss"; -import { COLLECTION_BORDER_WIDTH, CollectionViewProps, SubCollectionViewProps } from "./CollectionView"; +import { COLLECTION_BORDER_WIDTH } from "./CollectionView"; import { KeyStore } from "../../../fields/KeyStore"; import { Document } from "../../../fields/Document"; import { ListField } from "../../../fields/ListField"; -import { NumberField } from "../../../fields/NumberField"; -import { Documents } from "../../documents/Documents"; import { FieldWaiting } from "../../../fields/Field"; import { Transform } from "../../util/Transform"; import { DocumentView } from "../nodes/DocumentView"; import { undoBatch } from "../../util/UndoManager"; -import { jSXElement } from "babel-types"; +import { CollectionViewBase, SubCollectionViewProps } from "./CollectionViewBase"; @observer -export class CollectionFreeFormView extends React.Component { +export class CollectionFreeFormView extends CollectionViewBase { private _canvasRef = React.createRef(); private _lastX: number = 0; private _lastY: number = 0; @@ -45,13 +43,8 @@ export class CollectionFreeFormView extends React.Component { + super.drop(e, de); const doc: DocumentView = de.data["document"]; - if (doc.props.ContainingCollectionView && doc.props.ContainingCollectionView !== this.props.CollectionView) { - if (doc.props.RemoveDocument) { - doc.props.RemoveDocument(doc.props.Document); - } - this.props.addDocument(doc.props.Document); - } const xOffset = de.data["xOffset"] as number || 0; const yOffset = de.data["yOffset"] as number || 0; //this should be able to use translate and scale methods on an Identity transform, no? @@ -62,21 +55,6 @@ export class CollectionFreeFormView extends React.Component { - if (this.dropDisposer) { - this.dropDisposer(); - } - if (ele) { - this.dropDisposer = DragManager.MakeDropTarget(ele, { - handlers: { - drop: this.drop - } - }); - } } @action @@ -148,36 +126,11 @@ export class CollectionFreeFormView extends React.Component { - e.stopPropagation() - e.preventDefault() - let fReader = new FileReader() - let file = e.dataTransfer.items[0].getAsFile(); - let that = this; const panx: number = this.props.Document.GetNumber(KeyStore.PanX, 0); const pany: number = this.props.Document.GetNumber(KeyStore.PanY, 0); let x = e.pageX - panx let y = e.pageY - pany - - fReader.addEventListener("load", action("drop", () => { - if (fReader.result) { - let url = "" + fReader.result; - let doc = Documents.ImageDocument(url, { - x: x, y: y - }) - let docs = that.props.Document.GetT(KeyStore.Data, ListField); - if (docs != FieldWaiting) { - if (!docs) { - docs = new ListField(); - that.props.Document.Set(KeyStore.Data, docs) - } - docs.Data.push(doc); - } - } - }), false) - - if (file) { - fReader.readAsDataURL(file) - } + super.onDrop(e, { x: x, y: y }); } onDragOver = (): void => { @@ -249,7 +202,7 @@ export class CollectionFreeFormView extends React.Component e.preventDefault()} - onDrop={this.onDrop} + onDrop={this.onDrop.bind(this)} onDragOver={this.onDragOver} style={{ borderWidth: `${COLLECTION_BORDER_WIDTH}px`, }} ref={this.createDropTarget}> diff --git a/src/client/views/collections/CollectionSchemaView.tsx b/src/client/views/collections/CollectionSchemaView.tsx index f25e721c0..df732308a 100644 --- a/src/client/views/collections/CollectionSchemaView.tsx +++ b/src/client/views/collections/CollectionSchemaView.tsx @@ -5,7 +5,7 @@ import Measure from "react-measure"; import ReactTable, { CellInfo, ComponentPropsGetterR, ReactTableDefaults } from "react-table"; import "react-table/react-table.css"; import { Document } from "../../../fields/Document"; -import { Field } from "../../../fields/Field"; +import { Field, FieldWaiting } from "../../../fields/Field"; import { KeyStore } from "../../../fields/KeyStore"; import { CompileScript, ToField } from "../../util/Scripting"; import { Transform } from "../../util/Transform"; @@ -13,10 +13,11 @@ import { EditableView } from "../EditableView"; import { DocumentView } from "../nodes/DocumentView"; import { FieldView, FieldViewProps } from "../nodes/FieldView"; import "./CollectionSchemaView.scss"; -import { COLLECTION_BORDER_WIDTH, CollectionViewProps, SubCollectionViewProps } from "./CollectionView"; +import { COLLECTION_BORDER_WIDTH } from "./CollectionView"; +import { CollectionViewBase } from "./CollectionViewBase"; @observer -export class CollectionSchemaView extends React.Component { +export class CollectionSchemaView extends CollectionViewBase { private _mainCont = React.createRef(); private DIVIDER_WIDTH = 5; @@ -117,6 +118,7 @@ export class CollectionSchemaView extends React.Component { return this.props.ScreenToLocalTransform().translate(- COLLECTION_BORDER_WIDTH - this.DIVIDER_WIDTH - this._dividerX, - COLLECTION_BORDER_WIDTH).scale(1 / this._parentScaling); } @@ -181,7 +183,10 @@ export class CollectionSchemaView extends React.Component
-
+
this.onDrop(e, {})} + ref={this.createDropTarget} + style={{ position: "relative", float: "left", width: `calc(${100 - this._splitPercentage}% - ${this.DIVIDER_WIDTH}px)`, height: "100%" }}> {content}
diff --git a/src/client/views/collections/CollectionView.tsx b/src/client/views/collections/CollectionView.tsx index 651d85879..ff1803ec3 100644 --- a/src/client/views/collections/CollectionView.tsx +++ b/src/client/views/collections/CollectionView.tsx @@ -1,36 +1,18 @@ import { action, computed } from "mobx"; import { observer } from "mobx-react"; import { Document } from "../../../fields/Document"; -import { Key } from "../../../fields/Key"; import { ListField } from "../../../fields/ListField"; import { SelectionManager } from "../../util/SelectionManager"; import { ContextMenu } from "../ContextMenu"; import React = require("react"); -import { Transform } from "../../util/Transform"; import { KeyStore } from "../../../fields/KeyStore"; import { NumberField } from "../../../fields/NumberField"; import { CollectionFreeFormView } from "./CollectionFreeFormView"; import { CollectionDockingView } from "./CollectionDockingView"; import { CollectionSchemaView } from "./CollectionSchemaView"; -import { Opt } from "../../../fields/Field"; +import { CollectionViewProps } from "./CollectionViewBase"; -export interface CollectionViewProps { - fieldKey: Key; - Document: Document; - ScreenToLocalTransform: () => Transform; - isSelected: () => boolean; - isTopMost: boolean; - select: (ctrlPressed: boolean) => void; - BackgroundView?: () => JSX.Element; -} - -export interface SubCollectionViewProps extends CollectionViewProps { - active: () => boolean; - addDocument: (doc: Document) => void; - removeDocument: (doc: Document) => boolean; - CollectionView: Opt; -} export enum CollectionViewType { Invalid, diff --git a/src/client/views/collections/CollectionViewBase.tsx b/src/client/views/collections/CollectionViewBase.tsx new file mode 100644 index 000000000..06de56383 --- /dev/null +++ b/src/client/views/collections/CollectionViewBase.tsx @@ -0,0 +1,82 @@ +import { action, computed } from "mobx"; +import { Document } from "../../../fields/Document"; +import { ListField } from "../../../fields/ListField"; +import React = require("react"); +import { KeyStore } from "../../../fields/KeyStore"; +import { Opt, FieldWaiting } from "../../../fields/Field"; +import { undoBatch } from "../../util/UndoManager"; +import { DragManager } from "../../util/DragManager"; +import { DocumentView } from "../nodes/DocumentView"; +import { Documents, DocumentOptions } from "../../documents/Documents"; +import { Key } from "../../../fields/Key"; +import { Transform } from "../../util/Transform"; + + +export interface CollectionViewProps { + fieldKey: Key; + Document: Document; + ScreenToLocalTransform: () => Transform; + isSelected: () => boolean; + isTopMost: boolean; + select: (ctrlPressed: boolean) => void; + BackgroundView?: () => JSX.Element; +} +export interface SubCollectionViewProps extends CollectionViewProps { + active: () => boolean; + addDocument: (doc: Document) => void; + removeDocument: (doc: Document) => boolean; + CollectionView: any; +} + +export class CollectionViewBase extends React.Component { + private dropDisposer?: DragManager.DragDropDisposer; + protected createDropTarget = (ele: HTMLDivElement) => { + if (this.dropDisposer) { + this.dropDisposer(); + } + if (ele) { + this.dropDisposer = DragManager.MakeDropTarget(ele, { handlers: { drop: this.drop.bind(this) } }); + } + } + + @undoBatch + @action + protected drop(e: Event, de: DragManager.DropEvent) { + const doc: DocumentView = de.data["document"]; + if (doc.props.ContainingCollectionView && doc.props.ContainingCollectionView !== this.props.CollectionView) { + if (doc.props.RemoveDocument) { + doc.props.RemoveDocument(doc.props.Document); + } + this.props.addDocument(doc.props.Document); + } + e.stopPropagation(); + } + + @action + protected onDrop(e: React.DragEvent, options: DocumentOptions): void { + e.stopPropagation() + e.preventDefault() + let fReader = new FileReader() + let file = e.dataTransfer.items[0].getAsFile(); + let that = this; + + fReader.addEventListener("load", action("drop", () => { + if (fReader.result) { + let url = "" + fReader.result; + let doc = Documents.ImageDocument(url, options) + let docs = that.props.Document.GetT(KeyStore.Data, ListField); + if (docs != FieldWaiting) { + if (!docs) { + docs = new ListField(); + that.props.Document.Set(KeyStore.Data, docs) + } + docs.Data.push(doc); + } + } + }), false) + + if (file) { + fReader.readAsDataURL(file) + } + } +} -- cgit v1.2.3-70-g09d2 From 451c31e529dad9fbec94e71790907848f7c3fb24 Mon Sep 17 00:00:00 2001 From: Bob Zeleznik Date: Sat, 23 Feb 2019 02:34:58 -0500 Subject: css hacking to fix layout issues related to making a captioned image style --- src/client/documents/Documents.ts | 20 ++++++++++++++++---- .../views/collections/CollectionFreeFormView.scss | 2 ++ .../views/collections/CollectionFreeFormView.tsx | 5 +++-- src/client/views/nodes/FieldView.tsx | 3 ++- src/client/views/nodes/FormattedTextBox.scss | 4 ++-- src/client/views/nodes/FormattedTextBox.tsx | 5 ++--- src/client/views/nodes/ImageBox.scss | 3 ++- src/fields/KeyStore.ts | 1 + 8 files changed, 30 insertions(+), 13 deletions(-) (limited to 'src/client/documents') diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts index 156a09316..6ec5aa711 100644 --- a/src/client/documents/Documents.ts +++ b/src/client/documents/Documents.ts @@ -5,13 +5,10 @@ import { TextField } from "../../fields/TextField"; import { NumberField } from "../../fields/NumberField"; import { ListField } from "../../fields/ListField"; import { FormattedTextBox } from "../views/nodes/FormattedTextBox"; -import { CollectionDockingView } from "../views/collections/CollectionDockingView"; -import { CollectionSchemaView } from "../views/collections/CollectionSchemaView"; import { ImageField } from "../../fields/ImageField"; import { ImageBox } from "../views/nodes/ImageBox"; -import { CollectionFreeFormView } from "../views/collections/CollectionFreeFormView"; -import { FieldId } from "../../fields/Field"; import { CollectionView, CollectionViewType } from "../views/collections/CollectionView"; +import { FieldView } from "../views/nodes/FieldView"; export interface DocumentOptions { x?: number; @@ -102,12 +99,27 @@ export namespace Documents { return imageProto; } return imageProto; + } + // example of custom display string for an image that shows a caption. + function CaptionLayoutString() { + return `
+
` + + ImageBox.LayoutString() + + `
+
` + + FormattedTextBox.LayoutString("CaptionKey") + + `
+
` }; + export function ImageDocument(url: string, options: DocumentOptions = {}): Document { let doc = GetImagePrototype().MakeDelegate(); setupOptions(doc, options); doc.Set(KeyStore.Data, new ImageField(new URL(url))); + doc.Set(KeyStore.Caption, new TextField("my caption...")); + doc.Set(KeyStore.BackgroundLayout, new TextField(CaptionLayoutString())); + doc.Set(KeyStore.LayoutKeys, new ListField([KeyStore.Data, KeyStore.Annotations, KeyStore.Caption])); let annotation = Documents.TextDocument({ title: "hello" }); doc.Set(KeyStore.Annotations, new ListField([annotation])); diff --git a/src/client/views/collections/CollectionFreeFormView.scss b/src/client/views/collections/CollectionFreeFormView.scss index 4cf474f77..6d678528a 100644 --- a/src/client/views/collections/CollectionFreeFormView.scss +++ b/src/client/views/collections/CollectionFreeFormView.scss @@ -11,5 +11,7 @@ position: absolute; top: 0; left: 0; + width:100%; + height: 100% } } \ No newline at end of file diff --git a/src/client/views/collections/CollectionFreeFormView.tsx b/src/client/views/collections/CollectionFreeFormView.tsx index c12a82617..6d2662105 100644 --- a/src/client/views/collections/CollectionFreeFormView.tsx +++ b/src/client/views/collections/CollectionFreeFormView.tsx @@ -34,7 +34,7 @@ export class CollectionFreeFormView extends CollectionViewBase { @computed get panX(): number { return this.props.Document.GetNumber(KeyStore.PanX, 0) } @computed get panY(): number { return this.props.Document.GetNumber(KeyStore.PanY, 0) } @computed get scale(): number { return this.props.Document.GetNumber(KeyStore.Scale, 1); } - @computed get isAnnotationOverlay() { return this.props.fieldKey == KeyStore.Annotations; } + @computed get isAnnotationOverlay() { return this.props.fieldKey.Id === KeyStore.Annotations.Id; } // bcz: ? Why do we need to compare Id's? @computed get nativeWidth() { return this.props.Document.GetNumber(KeyStore.NativeWidth, 0); } @computed get nativeHeight() { return this.props.Document.GetNumber(KeyStore.NativeHeight, 0); } @computed get zoomScaling() { return this.props.Document.GetNumber(KeyStore.Scale, 1); } @@ -91,6 +91,7 @@ export class CollectionFreeFormView extends CollectionViewBase { let [dx, dy] = this.props.ScreenToLocalTransform().transformDirection(e.clientX - this._lastX, e.clientY - this._lastY); this.SetPan(x + dx, y + dy); + console.log("px = " + x + " " + y) } this._lastX = e.pageX; this._lastY = e.pageY; @@ -209,7 +210,7 @@ export class CollectionFreeFormView extends CollectionViewBase { style={{ borderWidth: `${COLLECTION_BORDER_WIDTH}px`, }} ref={this.createDropTarget}>
{this.backgroundView} {this.views} diff --git a/src/client/views/nodes/FieldView.tsx b/src/client/views/nodes/FieldView.tsx index 97d3f2a85..9dda08d8d 100644 --- a/src/client/views/nodes/FieldView.tsx +++ b/src/client/views/nodes/FieldView.tsx @@ -27,7 +27,8 @@ export interface FieldViewProps { @observer export class FieldView extends React.Component { - public static LayoutString(fieldType: { name: string }) { return `<${fieldType.name} doc={Document} DocumentViewForField={DocumentView} bindings={bindings} fieldKey={DataKey} isSelected={isSelected} select={select} isTopMost={isTopMost} />`; } + public static LayoutString(fieldType: { name: string }, fieldStr: string = "DataKey") { return `<${fieldType.name} doc={Document} DocumentViewForField={DocumentView} bindings={bindings} fieldKey={${fieldStr}} isSelected={isSelected} select={select} isTopMost={isTopMost} />`; } + @computed get field(): FieldValue { const { doc, fieldKey } = this.props; diff --git a/src/client/views/nodes/FormattedTextBox.scss b/src/client/views/nodes/FormattedTextBox.scss index 5139d5d6b..872a2138b 100644 --- a/src/client/views/nodes/FormattedTextBox.scss +++ b/src/client/views/nodes/FormattedTextBox.scss @@ -1,7 +1,7 @@ .ProseMirror { - margin-top: -1em; width: 100%; - height: 100%; + height: auto; + min-height: 100% } .ProseMirror:focus { diff --git a/src/client/views/nodes/FormattedTextBox.tsx b/src/client/views/nodes/FormattedTextBox.tsx index 16728d471..c0969a8c3 100644 --- a/src/client/views/nodes/FormattedTextBox.tsx +++ b/src/client/views/nodes/FormattedTextBox.tsx @@ -10,8 +10,6 @@ import "./FormattedTextBox.scss"; import React = require("react") import { RichTextField } from "../../../fields/RichTextField"; import { FieldViewProps, FieldView } from "./FieldView"; -import { CollectionFreeFormDocumentView } from "./CollectionFreeFormDocumentView"; -import { observer } from "mobx-react"; // FormattedTextBox: Displays an editable plain text node that maps to a specified Key of a Document @@ -32,7 +30,7 @@ import { observer } from "mobx-react"; //] export class FormattedTextBox extends React.Component { - public static LayoutString() { return FieldView.LayoutString(FormattedTextBox) } + public static LayoutString(fieldStr: string = "DataKey") { return FieldView.LayoutString(FormattedTextBox, fieldStr) } private _ref: React.RefObject; private _editorView: Opt; private _reactionDisposer: Opt; @@ -118,6 +116,7 @@ export class FormattedTextBox extends React.Component { style={{ color: "initial", whiteSpace: "initial", + height: "auto" }} onPointerDown={this.onPointerDown} ref={this._ref} />) diff --git a/src/client/views/nodes/ImageBox.scss b/src/client/views/nodes/ImageBox.scss index 36f5e0fe0..5b15b3329 100644 --- a/src/client/views/nodes/ImageBox.scss +++ b/src/client/views/nodes/ImageBox.scss @@ -1,7 +1,8 @@ .imageBox-cont { padding: 0vw; - position: absolute; + position: relative; + text-align: center; width: 100%; max-width: 100%; max-height: 100% diff --git a/src/fields/KeyStore.ts b/src/fields/KeyStore.ts index 6d6c6a546..42e3f6b58 100644 --- a/src/fields/KeyStore.ts +++ b/src/fields/KeyStore.ts @@ -22,5 +22,6 @@ export namespace KeyStore { export const LayoutKeys = new Key("LayoutKeys"); export const LayoutFields = new Key("LayoutFields"); export const ColumnsKey = new Key("SchemaColumns"); + export const Caption = new Key("Caption"); export const ActiveFrame = new Key("ActiveFrame"); } -- cgit v1.2.3-70-g09d2 From 9663623dbe9f54bd3f233c8de7cb9f112f17a7cc Mon Sep 17 00:00:00 2001 From: Tyler Schicke Date: Sat, 23 Feb 2019 04:49:48 -0500 Subject: Added web clippings on drag and drop --- src/client/documents/Documents.ts | 24 +++++++++++++++++++++ .../views/collections/CollectionFreeFormView.tsx | 3 ++- .../views/collections/CollectionViewBase.tsx | 9 ++++++++ src/client/views/nodes/DocumentView.tsx | 3 ++- src/client/views/nodes/FieldView.tsx | 4 ++++ src/client/views/nodes/WebView.tsx | 22 +++++++++++++++++++ src/fields/HtmlField.ts | 25 ++++++++++++++++++++++ src/fields/KeyStore.ts | 1 + src/fields/TextField.ts | 2 +- src/server/Message.ts | 2 +- src/server/ServerUtil.ts | 6 +++++- 11 files changed, 96 insertions(+), 5 deletions(-) create mode 100644 src/client/views/nodes/WebView.tsx create mode 100644 src/fields/HtmlField.ts (limited to 'src/client/documents') diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts index 6ec5aa711..d8e1db0b0 100644 --- a/src/client/documents/Documents.ts +++ b/src/client/documents/Documents.ts @@ -9,6 +9,8 @@ import { ImageField } from "../../fields/ImageField"; import { ImageBox } from "../views/nodes/ImageBox"; import { CollectionView, CollectionViewType } from "../views/collections/CollectionView"; import { FieldView } from "../views/nodes/FieldView"; +import { HtmlField } from "../../fields/HtmlField"; +import { WebView } from "../views/nodes/WebView"; export interface DocumentOptions { x?: number; @@ -79,6 +81,28 @@ export namespace Documents { return doc; } + let htmlProto: Document; + const htmlProtoId = "htmlProto"; + function GetHtmlPrototype(): Document { + if (!htmlProto) { + htmlProto = new Document(htmlProtoId); + htmlProto.Set(KeyStore.X, new NumberField(0)); + htmlProto.Set(KeyStore.Y, new NumberField(0)); + htmlProto.Set(KeyStore.Width, new NumberField(300)); + htmlProto.Set(KeyStore.Height, new NumberField(150)); + htmlProto.Set(KeyStore.Layout, new TextField(WebView.LayoutString())); + htmlProto.Set(KeyStore.LayoutKeys, new ListField([KeyStore.Data])); + } + return htmlProto; + } + + export function HtmlDocument(html: string, options: DocumentOptions = {}): Document { + let doc = GetHtmlPrototype().MakeDelegate(); + setupOptions(doc, options); + doc.Set(KeyStore.Data, new HtmlField(html)); + return doc; + } + let imageProto: Document; const imageProtoId = "imageProto"; function GetImagePrototype(): Document { diff --git a/src/client/views/collections/CollectionFreeFormView.tsx b/src/client/views/collections/CollectionFreeFormView.tsx index 4799eda97..b031c35a7 100644 --- a/src/client/views/collections/CollectionFreeFormView.tsx +++ b/src/client/views/collections/CollectionFreeFormView.tsx @@ -13,6 +13,7 @@ import { CollectionSchemaView } from "../collections/CollectionSchemaView"; import { CollectionView } from "../collections/CollectionView"; import { CollectionFreeFormDocumentView } from "../nodes/CollectionFreeFormDocumentView"; import { DocumentView } from "../nodes/DocumentView"; +import { WebView } from "../nodes/WebView"; import { FormattedTextBox } from "../nodes/FormattedTextBox"; import { ImageBox } from "../nodes/ImageBox"; import "./CollectionFreeFormView.scss"; @@ -185,7 +186,7 @@ export class CollectionFreeFormView extends CollectionViewBase { get backgroundView() { return !this.backgroundLayout ? (null) : ( e.preventDefault() let that = this; + let html = e.dataTransfer.getData("text/html"); + let text = e.dataTransfer.getData("text/plain"); + if (html) { + let htmlDoc = Documents.HtmlDocument(html, { ...options }); + htmlDoc.SetText(KeyStore.DocumentText, text); + this.props.addDocument(htmlDoc); + return; + } + for (let i = 0; i < e.dataTransfer.items.length; i++) { let item = e.dataTransfer.items[i]; if (item.kind === "string" && item.type.indexOf("uri") != -1) { diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx index a9e211431..ad1328e5d 100644 --- a/src/client/views/nodes/DocumentView.tsx +++ b/src/client/views/nodes/DocumentView.tsx @@ -12,6 +12,7 @@ import { CollectionDockingView } from "../collections/CollectionDockingView"; import { CollectionFreeFormView } from "../collections/CollectionFreeFormView"; import { CollectionSchemaView } from "../collections/CollectionSchemaView"; import { CollectionView, CollectionViewType } from "../collections/CollectionView"; +import { WebView } from "./WebView"; import { ContextMenu } from "../ContextMenu"; import { FormattedTextBox } from "../nodes/FormattedTextBox"; import { ImageBox } from "../nodes/ImageBox"; @@ -196,7 +197,7 @@ export class DocumentView extends React.Component { @computed get mainContent() { return { } else if (field instanceof NumberField) { return

{field.Data}

+ } else if (field instanceof HtmlField) { + return } else if (field != FieldWaiting) { return

{field.GetValue}

} else diff --git a/src/client/views/nodes/WebView.tsx b/src/client/views/nodes/WebView.tsx new file mode 100644 index 000000000..717aa8bf5 --- /dev/null +++ b/src/client/views/nodes/WebView.tsx @@ -0,0 +1,22 @@ +import { FieldViewProps, FieldView } from "./FieldView"; +import { computed } from "mobx"; +import { observer } from "mobx-react"; +import { KeyStore } from "../../../fields/KeyStore"; +import React = require('react') +import { TextField } from "../../../fields/TextField"; +import { HtmlField } from "../../../fields/HtmlField"; +import { RichTextField } from "../../../fields/RichTextField"; + +@observer +export class WebView extends React.Component { + public static LayoutString(fieldStr: string = "DataKey") { return FieldView.LayoutString(WebView, fieldStr) } + + @computed + get html(): string { + return this.props.doc.GetData(KeyStore.Data, HtmlField, "" as string); + } + + render() { + return + } +} \ No newline at end of file diff --git a/src/fields/HtmlField.ts b/src/fields/HtmlField.ts new file mode 100644 index 000000000..a07326095 --- /dev/null +++ b/src/fields/HtmlField.ts @@ -0,0 +1,25 @@ +import { BasicField } from "./BasicField"; +import { Types } from "../server/Message"; +import { FieldId } from "./Field"; + +export class HtmlField extends BasicField { + constructor(data: string = "", id?: FieldId, save: boolean = true) { + super(data, save, id); + } + + ToScriptString(): string { + return `new HtmlField("${this.Data}")`; + } + + Copy() { + return new HtmlField(this.Data); + } + + ToJson(): { _id: string; type: Types; data: any; } { + return { + type: Types.Html, + data: this.Data, + _id: this.Id, + } + } +} \ No newline at end of file diff --git a/src/fields/KeyStore.ts b/src/fields/KeyStore.ts index 42e3f6b58..290fa2be7 100644 --- a/src/fields/KeyStore.ts +++ b/src/fields/KeyStore.ts @@ -24,4 +24,5 @@ export namespace KeyStore { export const ColumnsKey = new Key("SchemaColumns"); export const Caption = new Key("Caption"); export const ActiveFrame = new Key("ActiveFrame"); + export const DocumentText = new Key("DocumentText"); } diff --git a/src/fields/TextField.ts b/src/fields/TextField.ts index ad96ab6d9..71d8ea310 100644 --- a/src/fields/TextField.ts +++ b/src/fields/TextField.ts @@ -22,4 +22,4 @@ export class TextField extends BasicField { _id: this.Id } } -} +} \ No newline at end of file diff --git a/src/server/Message.ts b/src/server/Message.ts index 7f3190f7f..80fc9a80d 100644 --- a/src/server/Message.ts +++ b/src/server/Message.ts @@ -45,7 +45,7 @@ export class GetFieldArgs { } export enum Types { - Number, List, Key, Image, Document, Text, RichText, DocumentReference + Number, List, Key, Image, Document, Text, RichText, DocumentReference, Html } export class DocumentTransfer implements Transferable { diff --git a/src/server/ServerUtil.ts b/src/server/ServerUtil.ts index 46c409ec4..08e72fdae 100644 --- a/src/server/ServerUtil.ts +++ b/src/server/ServerUtil.ts @@ -9,6 +9,7 @@ import { Document } from './../fields/Document'; import { Server } from './../client/Server'; import { Types } from './Message'; import { Utils } from '../Utils'; +import { HtmlField } from '../fields/HtmlField'; export class ServerUtils { public static FromJson(json: any): Field { @@ -27,6 +28,8 @@ export class ServerUtils { return new NumberField(data, id, false) case Types.Text: return new TextField(data, id, false) + case Types.Html: + return new HtmlField(data, id, false) case Types.RichText: return new RichTextField(data, id, false) case Types.Key: @@ -42,7 +45,8 @@ export class ServerUtils { doc._proxies.set(element[0], element[1]); }); return doc + default: + throw Error("Error, unrecognized field type received from server. If you just created a new field type, be sure to add it here"); } - return new TextField(data, id) } } \ No newline at end of file -- cgit v1.2.3-70-g09d2 From cdcfa6efa54a79b304cdcb2ffb084451116aeaac Mon Sep 17 00:00:00 2001 From: Bob Zeleznik Date: Sat, 23 Feb 2019 10:12:39 -0500 Subject: added an overlay layer to collections... but it blocks events. not sure how to fix. --- src/client/documents/Documents.ts | 7 +++++++ .../views/collections/CollectionFreeFormView.tsx | 24 ++++++++++++++++++++++ src/fields/KeyStore.ts | 1 + 3 files changed, 32 insertions(+) (limited to 'src/client/documents') diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts index 6ec5aa711..e0d44e535 100644 --- a/src/client/documents/Documents.ts +++ b/src/client/documents/Documents.ts @@ -112,6 +112,12 @@ export namespace Documents { + FormattedTextBox.LayoutString("CaptionKey") + `
` }; + function OverlayLayoutString() { + return `
+
` + + FormattedTextBox.LayoutString("CaptionKey") + + `
+
` }; export function ImageDocument(url: string, options: DocumentOptions = {}): Document { let doc = GetImagePrototype().MakeDelegate(); @@ -119,6 +125,7 @@ export namespace Documents { doc.Set(KeyStore.Data, new ImageField(new URL(url))); doc.Set(KeyStore.Caption, new TextField("my caption...")); doc.Set(KeyStore.BackgroundLayout, new TextField(CaptionLayoutString())); + //doc.Set(KeyStore.OverlayLayout, new TextField(OverlayLayoutString())); doc.Set(KeyStore.LayoutKeys, new ListField([KeyStore.Data, KeyStore.Annotations, KeyStore.Caption])); let annotation = Documents.TextDocument({ title: "hello" }); diff --git a/src/client/views/collections/CollectionFreeFormView.tsx b/src/client/views/collections/CollectionFreeFormView.tsx index 4799eda97..ee0f3730d 100644 --- a/src/client/views/collections/CollectionFreeFormView.tsx +++ b/src/client/views/collections/CollectionFreeFormView.tsx @@ -161,6 +161,12 @@ export class CollectionFreeFormView extends CollectionViewBase { return field.Data; } } + @computed get overlayLayout(): string | undefined { + let field = this.props.Document.GetT(KeyStore.OverlayLayout, TextField); + if (field && field !== "") { + return field.Data; + } + } @computed get views() { const { fieldKey, Document } = this.props; @@ -192,6 +198,17 @@ export class CollectionFreeFormView extends CollectionViewBase { onError={(test: any) => console.log(test)} />); } + @computed + get overlayView() { + return !this.overlayLayout ? (null) : + ( console.log(test)} + />); + } getTransform = (): Transform => this.props.ScreenToLocalTransform().translate(-COLLECTION_BORDER_WIDTH, -COLLECTION_BORDER_WIDTH).transform(this.getLocalTransform()) getLocalTransform = (): Transform => Transform.Identity.translate(-this.panX, -this.panY).scale(1 / this.scale); noScaling = () => 1; @@ -199,6 +216,12 @@ export class CollectionFreeFormView extends CollectionViewBase { render() { const panx: number = this.props.Document.GetNumber(KeyStore.PanX, 0); const pany: number = this.props.Document.GetNumber(KeyStore.PanY, 0); + var overlay = this.overlayView ? +
+ {this.overlayView} +
+ : + (null); return (
+ {overlay}
); } diff --git a/src/fields/KeyStore.ts b/src/fields/KeyStore.ts index 42e3f6b58..78ed09efd 100644 --- a/src/fields/KeyStore.ts +++ b/src/fields/KeyStore.ts @@ -19,6 +19,7 @@ export namespace KeyStore { export const ViewType = new Key("ViewType"); export const Layout = new Key("Layout"); export const BackgroundLayout = new Key("BackgroundLayout"); + export const OverlayLayout = new Key("OverlayLayout"); export const LayoutKeys = new Key("LayoutKeys"); export const LayoutFields = new Key("LayoutFields"); export const ColumnsKey = new Key("SchemaColumns"); -- cgit v1.2.3-70-g09d2 From d9d55e422826da1fe87aa7973c92e54bc0c99f02 Mon Sep 17 00:00:00 2001 From: Bob Zeleznik Date: Sat, 23 Feb 2019 11:38:15 -0500 Subject: working overlays --- src/client/documents/Documents.ts | 14 +++++++------- src/client/views/collections/CollectionFreeFormView.scss | 9 +++++++++ src/client/views/collections/CollectionFreeFormView.tsx | 6 +++--- src/client/views/nodes/FormattedTextBox.scss | 2 +- 4 files changed, 20 insertions(+), 11 deletions(-) (limited to 'src/client/documents') diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts index 72efb45f5..4c5f26fbd 100644 --- a/src/client/documents/Documents.ts +++ b/src/client/documents/Documents.ts @@ -127,18 +127,18 @@ export namespace Documents { } // example of custom display string for an image that shows a caption. - function CaptionLayoutString() { + function EmbeddedCaption() { return `
` + ImageBox.LayoutString() + `
-
` +
` + FormattedTextBox.LayoutString("CaptionKey") + `
` }; - function OverlayLayoutString() { - return `
-
` + function FixedCaption() { + return `
+
` + FormattedTextBox.LayoutString("CaptionKey") + `
` }; @@ -148,8 +148,8 @@ export namespace Documents { setupOptions(doc, options); doc.Set(KeyStore.Data, new ImageField(new URL(url))); doc.Set(KeyStore.Caption, new TextField("my caption...")); - doc.Set(KeyStore.BackgroundLayout, new TextField(CaptionLayoutString())); - //doc.Set(KeyStore.OverlayLayout, new TextField(OverlayLayoutString())); + doc.Set(KeyStore.BackgroundLayout, new TextField(EmbeddedCaption())); + doc.Set(KeyStore.OverlayLayout, new TextField(FixedCaption())); doc.Set(KeyStore.LayoutKeys, new ListField([KeyStore.Data, KeyStore.Annotations, KeyStore.Caption])); let annotation = Documents.TextDocument({ title: "hello" }); diff --git a/src/client/views/collections/CollectionFreeFormView.scss b/src/client/views/collections/CollectionFreeFormView.scss index 6d678528a..e682b9815 100644 --- a/src/client/views/collections/CollectionFreeFormView.scss +++ b/src/client/views/collections/CollectionFreeFormView.scss @@ -1,4 +1,13 @@ .collectionfreeformview-container { + + ::-webkit-scrollbar { + -webkit-appearance: none; + width: 10px; + } + ::-webkit-scrollbar-thumb { + border-radius: 5px; + background-color: rgba(0,0,0,.5); + } border-style: solid; box-sizing: border-box; position: relative; diff --git a/src/client/views/collections/CollectionFreeFormView.tsx b/src/client/views/collections/CollectionFreeFormView.tsx index 85f7d5677..cb6668634 100644 --- a/src/client/views/collections/CollectionFreeFormView.tsx +++ b/src/client/views/collections/CollectionFreeFormView.tsx @@ -120,8 +120,8 @@ export class CollectionFreeFormView extends CollectionViewBase { private SetPan(panX: number, panY: number) { const newPanX = Math.max((1 - this.zoomScaling) * this.nativeWidth, Math.min(0, panX)); const newPanY = Math.max((1 - this.zoomScaling) * this.nativeHeight, Math.min(0, panY)); - this.props.Document.SetNumber(KeyStore.PanX, this.isAnnotationOverlay ? newPanX : panX); - this.props.Document.SetNumber(KeyStore.PanY, this.isAnnotationOverlay ? newPanY : panY); + this.props.Document.SetNumber(KeyStore.PanX, false && this.isAnnotationOverlay ? newPanX : panX); + this.props.Document.SetNumber(KeyStore.PanY, false && this.isAnnotationOverlay ? newPanY : panY); } @action @@ -238,7 +238,7 @@ export class CollectionFreeFormView extends CollectionViewBase { {this.backgroundView} {this.views}
- {overlay} + {this.overlayView}
); } diff --git a/src/client/views/nodes/FormattedTextBox.scss b/src/client/views/nodes/FormattedTextBox.scss index 872a2138b..226456fab 100644 --- a/src/client/views/nodes/FormattedTextBox.scss +++ b/src/client/views/nodes/FormattedTextBox.scss @@ -10,5 +10,5 @@ .formattedTextBox-cont { background: beige; - padding: 1vw; + padding: 0; } \ No newline at end of file -- cgit v1.2.3-70-g09d2 From e57c8ed3944bf737afdb2f564d159a53f8a6b1c6 Mon Sep 17 00:00:00 2001 From: Bob Zeleznik Date: Mon, 25 Feb 2019 01:56:29 -0500 Subject: more css cleanup --- src/client/documents/Documents.ts | 4 +- src/client/views/EditableView.tsx | 2 +- .../views/collections/CollectionDockingView.tsx | 2 +- .../views/collections/CollectionFreeFormView.scss | 6 ++ .../views/collections/CollectionFreeFormView.tsx | 6 -- .../views/collections/CollectionSchemaView.scss | 73 ++++++++++------------ .../views/collections/CollectionSchemaView.tsx | 7 ++- .../views/nodes/CollectionFreeFormDocumentView.tsx | 2 +- src/client/views/nodes/FormattedTextBox.scss | 4 ++ src/client/views/nodes/FormattedTextBox.tsx | 6 +- src/client/views/nodes/ImageBox.scss | 6 +- 11 files changed, 58 insertions(+), 60 deletions(-) (limited to 'src/client/documents') diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts index 4c5f26fbd..2dfff6235 100644 --- a/src/client/documents/Documents.ts +++ b/src/client/documents/Documents.ts @@ -128,8 +128,8 @@ export namespace Documents { // example of custom display string for an image that shows a caption. function EmbeddedCaption() { - return `
-
` + return `
+
` + ImageBox.LayoutString() + `
` diff --git a/src/client/views/EditableView.tsx b/src/client/views/EditableView.tsx index 3d1c2ebf4..8d9a47eaa 100644 --- a/src/client/views/EditableView.tsx +++ b/src/client/views/EditableView.tsx @@ -30,7 +30,7 @@ export class EditableView extends React.Component { style={{ width: "100%" }}> } else { return ( -
this.editing = true)} > {this.props.contents} diff --git a/src/client/views/collections/CollectionDockingView.tsx b/src/client/views/collections/CollectionDockingView.tsx index 86dc66e39..2230ec14f 100644 --- a/src/client/views/collections/CollectionDockingView.tsx +++ b/src/client/views/collections/CollectionDockingView.tsx @@ -285,7 +285,7 @@ export class DockedFrameRenderer extends React.Component { if (!this._document) return (null); var content = -
+
.jsx-parser{ + position:absolute; + height: 100%; + } + border-style: solid; box-sizing: border-box; position: relative; diff --git a/src/client/views/collections/CollectionFreeFormView.tsx b/src/client/views/collections/CollectionFreeFormView.tsx index cb6668634..c40da6eaa 100644 --- a/src/client/views/collections/CollectionFreeFormView.tsx +++ b/src/client/views/collections/CollectionFreeFormView.tsx @@ -217,12 +217,6 @@ export class CollectionFreeFormView extends CollectionViewBase { render() { const panx: number = this.props.Document.GetNumber(KeyStore.PanX, 0); const pany: number = this.props.Document.GetNumber(KeyStore.PanY, 0); - var overlay = this.overlayView ? -
- {this.overlayView} -
- : - (null); return (
.jsx-parser{ - position:absolute - } - } - .imageBox-cont { - position:relative; - max-height:100%; - } .ReactTable { position: absolute; // display: inline-block; @@ -32,23 +22,40 @@ height: 100%; background: white; box-sizing: border-box; - } - .ReactTable .rt-table { - overflow-y: auto; - overflow-x: auto; - height: 100%; + .rt-table { + overflow-y: auto; + overflow-x: auto; + height: 100%; - display: -webkit-inline-box; - direction: ltr; - // direction:rtl; - // display:block; - } - .ReactTable .rt-tbody { - //direction: ltr; - direction: rtl; - } - .ReactTable .rt-tr-group { - direction: ltr; + display: -webkit-inline-box; + direction: ltr; + // direction:rtl; + // display:block; + } + .rt-tbody { + //direction: ltr; + direction: rtl; + } + .rt-tr-group { + direction: ltr; + } + .rt-td { + border-width: 1; + border-right-color: #aaa; + .imageBox-cont { + position:relative; + max-height:100%; + } + .imageBox-cont img { + object-fit: contain; + max-width: 100%; + height: 100% + } + } + .rt-tr-group { + border-width: 1; + border-bottom-color: #aaa + } } .ReactTable .rt-thead.-header { background:grey; @@ -61,24 +68,10 @@ border-bottom-style: solid; border-bottom-width: 1; } - .ReactTable .rt-td { - border-width: 1; - border-right-color: #aaa - } - .ReactTable .rt-tr-group { - border-width: 1; - border-bottom-color: #aaa - } - .imageBox-cont img { - object-fit: contain; - height: 100% - } .documentView-node:first-child { background: grey; .imageBox-cont img { object-fit: contain; - max-width: 100%; - height: 100% } } } diff --git a/src/client/views/collections/CollectionSchemaView.tsx b/src/client/views/collections/CollectionSchemaView.tsx index d2db93120..dc952ef82 100644 --- a/src/client/views/collections/CollectionSchemaView.tsx +++ b/src/client/views/collections/CollectionSchemaView.tsx @@ -16,6 +16,8 @@ import "./CollectionSchemaView.scss"; import { COLLECTION_BORDER_WIDTH } from "./CollectionView"; import { CollectionViewBase } from "./CollectionViewBase"; +// bcz: need to add drag and drop of rows and columns. This seems like it might work for rows: https://codesandbox.io/s/l94mn1q657 + @observer export class CollectionSchemaView extends CollectionViewBase { private _mainCont = React.createRef(); @@ -140,7 +142,7 @@ export class CollectionSchemaView extends CollectionViewBase { let content = this._selectedIndex == -1 || !selected ? (null) : ( {({ measureRef }) => -
+
diff --git a/src/client/views/nodes/CollectionFreeFormDocumentView.tsx b/src/client/views/nodes/CollectionFreeFormDocumentView.tsx index 17123bf52..d7243421a 100644 --- a/src/client/views/nodes/CollectionFreeFormDocumentView.tsx +++ b/src/client/views/nodes/CollectionFreeFormDocumentView.tsx @@ -88,7 +88,7 @@ export class CollectionFreeFormDocumentView extends React.Component { } } render() { + var val = this.props.doc.Get(this.props.fieldKey); return (
) } diff --git a/src/client/views/nodes/ImageBox.scss b/src/client/views/nodes/ImageBox.scss index 5b15b3329..ea459b911 100644 --- a/src/client/views/nodes/ImageBox.scss +++ b/src/client/views/nodes/ImageBox.scss @@ -4,12 +4,14 @@ position: relative; text-align: center; width: 100%; + height: auto; max-width: 100%; max-height: 100% } + .imageBox-cont img { - max-width: 100%; - max-height: 100% + object-fit: contain; + height: 100%; } .imageBox-button { -- cgit v1.2.3-70-g09d2