From d89b1039ecc05d4d6c40fc38f51da9cee0c00af6 Mon Sep 17 00:00:00 2001 From: Hannah Date: Sun, 10 Feb 2019 22:13:15 -0500 Subject: Small changes for starting annotations --- src/client/views/nodes/FormattedTextBox.tsx | 2 -- 1 file changed, 2 deletions(-) (limited to 'src/client/views/nodes/FormattedTextBox.tsx') diff --git a/src/client/views/nodes/FormattedTextBox.tsx b/src/client/views/nodes/FormattedTextBox.tsx index 8bc4c902c..eead43b9f 100644 --- a/src/client/views/nodes/FormattedTextBox.tsx +++ b/src/client/views/nodes/FormattedTextBox.tsx @@ -1,5 +1,4 @@ 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"; @@ -31,7 +30,6 @@ import { CollectionFreeFormDocumentView } from "./CollectionFreeFormDocumentView // 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 { public static LayoutString() { return FieldView.LayoutString("FormattedTextBox"); } -- cgit v1.2.3-70-g09d2 From dad5b1f21df41444a577db1ee108980b8b8ab0a9 Mon Sep 17 00:00:00 2001 From: Tyler Schicke Date: Mon, 11 Feb 2019 21:42:49 -0500 Subject: Changed FieldId type around to clean some stuff up --- src/client/Server.ts | 23 ++++++++++++---------- src/client/SocketStub.ts | 6 +++--- src/client/documents/Documents.ts | 4 ++-- src/client/views/nodes/AnnotationView.tsx | 12 ----------- .../views/nodes/CollectionFreeFormDocumentView.tsx | 3 ++- src/client/views/nodes/FormattedTextBox.tsx | 1 + src/fields/Document.ts | 7 +++---- src/fields/Field.ts | 10 +++++----- 8 files changed, 29 insertions(+), 37 deletions(-) delete mode 100644 src/client/views/nodes/AnnotationView.tsx (limited to 'src/client/views/nodes/FormattedTextBox.tsx') diff --git a/src/client/Server.ts b/src/client/Server.ts index 85e55a84e..0cb6e17c2 100644 --- a/src/client/Server.ts +++ b/src/client/Server.ts @@ -1,16 +1,16 @@ -import { Field, FieldWaiting, FIELD_ID, FIELD_WAITING, FieldValue } from "../fields/Field" +import { Field, FieldWaiting, FieldId, FIELD_WAITING, FieldValue, Opt } from "../fields/Field" import { Key, KeyStore } from "../fields/Key" import { ObservableMap, action } from "mobx"; import { Document } from "../fields/Document" import { SocketStub } from "./SocketStub"; export class Server { - private static ClientFieldsCached: ObservableMap = new ObservableMap(); + private static ClientFieldsCached: ObservableMap = new ObservableMap(); // Retrieves the cached value of the field and sends a request to the server for the real value (if it's not cached). // Call this is from within a reaction and test whether the return value is FieldWaiting. // 'hackTimeout' is here temporarily for simplicity when debugging things. - public static GetField(fieldid: FIELD_ID, callback: (field: Field) => void = (f) => { }, hackTimeout: number = -1) { + public static GetField(fieldid: FieldId, callback: (field: Field) => void = (f) => { }, hackTimeout: number = -1) { if (!this.ClientFieldsCached.get(fieldid)) { this.ClientFieldsCached.set(fieldid, FieldWaiting); //simulating a server call with a registered callback action @@ -24,15 +24,18 @@ export class Server { } static times = 0; // hack for testing - public static GetDocumentField(doc: Document, key: Key) { + public static GetDocumentField(doc: Document, key: Key): FieldValue { var hackTimeout: number = key == KeyStore.Data ? (this.times++ == 0 ? 5000 : 1000) : key == KeyStore.X ? 2500 : 500; - return this.GetField(doc._proxies.get(key), - action((fieldfromserver: Field) => { - doc._proxies.delete(key); - doc.fields.set(key, fieldfromserver); - }) - , hackTimeout); + let fieldId = doc._proxies.get(key); + if (fieldId) { + return this.GetField(fieldId, + action((fieldfromserver: Field) => { + doc._proxies.delete(key); + doc.fields.set(key, fieldfromserver); + }) + , hackTimeout); + } } public static AddDocument(document: Document) { diff --git a/src/client/SocketStub.ts b/src/client/SocketStub.ts index 58dedbf82..cea30cb8b 100644 --- a/src/client/SocketStub.ts +++ b/src/client/SocketStub.ts @@ -1,11 +1,11 @@ -import { Field, FIELD_ID } from "../fields/Field" +import { Field, FieldId } from "../fields/Field" import { Key, KeyStore } from "../fields/Key" import { ObservableMap, action } from "mobx"; import { Document } from "../fields/Document" export class SocketStub { - static FieldStore: ObservableMap = new ObservableMap(); + static FieldStore: ObservableMap = new ObservableMap(); public static SEND_ADD_DOCUMENT(document: Document) { // Send a serialized version of the document to the server @@ -19,7 +19,7 @@ export class SocketStub { document.fields.forEach((f, key) => (this.FieldStore.get(document.Id) as Document)._proxies.set(key, (f as Field).Id)); } - public static SEND_FIELD_REQUEST(fieldid: FIELD_ID, callback: (field: Field) => void, timeout: number) { + public static SEND_FIELD_REQUEST(fieldid: FieldId, callback: (field: Field) => void, timeout: number) { if (timeout < 0)// this is a hack to make things easier to setup until we have a server... won't be neededa fter that. callback(this.FieldStore.get(fieldid) as Field); diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts index 6925234fe..575112c85 100644 --- a/src/client/documents/Documents.ts +++ b/src/client/documents/Documents.ts @@ -10,7 +10,7 @@ import { CollectionSchemaView } from "../views/collections/CollectionSchemaView" import { ImageField } from "../../fields/ImageField"; import { ImageBox } from "../views/nodes/ImageBox"; import { CollectionFreeFormView } from "../views/collections/CollectionFreeFormView"; -import { FIELD_ID } from "../../fields/Field"; +import { FieldId } from "../../fields/Field"; interface DocumentOptions { x?: number; @@ -107,7 +107,7 @@ export namespace Documents { } - let imageProtoId: FIELD_ID; + let imageProtoId: FieldId; function GetImagePrototype(): Document { if (imageProtoId === undefined) { let imageProto = new Document(); diff --git a/src/client/views/nodes/AnnotationView.tsx b/src/client/views/nodes/AnnotationView.tsx deleted file mode 100644 index 2e50370a1..000000000 --- a/src/client/views/nodes/AnnotationView.tsx +++ /dev/null @@ -1,12 +0,0 @@ -import React = require('react') -import { CollectionViewProps } from '../collections/CollectionViewBase'; - -export class AnnotationView extends React.Component { - - render() { - return ( - <> - ); - } - -} \ No newline at end of file diff --git a/src/client/views/nodes/CollectionFreeFormDocumentView.tsx b/src/client/views/nodes/CollectionFreeFormDocumentView.tsx index 1d53cedc4..a111a9936 100644 --- a/src/client/views/nodes/CollectionFreeFormDocumentView.tsx +++ b/src/client/views/nodes/CollectionFreeFormDocumentView.tsx @@ -17,6 +17,7 @@ export class CollectionFreeFormDocumentView extends DocumentView { private _contextMenuCanOpen = false; private _downX: number = 0; private _downY: number = 0; + // private _mainCont = React.createRef(); constructor(props: DocumentViewProps) { super(props); @@ -216,7 +217,7 @@ export class CollectionFreeFormDocumentView extends DocumentView { onContextMenu={this.onContextMenu} onPointerDown={this.onPointerDown}> - + ); } diff --git a/src/client/views/nodes/FormattedTextBox.tsx b/src/client/views/nodes/FormattedTextBox.tsx index eead43b9f..8f959762a 100644 --- a/src/client/views/nodes/FormattedTextBox.tsx +++ b/src/client/views/nodes/FormattedTextBox.tsx @@ -12,6 +12,7 @@ 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 diff --git a/src/fields/Document.ts b/src/fields/Document.ts index 6f9752a8e..c682d8e94 100644 --- a/src/fields/Document.ts +++ b/src/fields/Document.ts @@ -1,15 +1,14 @@ -import { Field, Cast, Opt, FieldWaiting, FIELD_ID, FieldValue } from "./Field" +import { Field, Cast, Opt, FieldWaiting, FieldId, FieldValue } from "./Field" import { Key, KeyStore } from "./Key" import { NumberField } from "./NumberField"; import { ObservableMap, computed, action, observable } from "mobx"; import { TextField } from "./TextField"; import { ListField } from "./ListField"; -import { findDOMNode } from "react-dom"; import { Server } from "../client/Server"; export class Document extends Field { - public fields: ObservableMap> = new ObservableMap(); - public _proxies: ObservableMap = new ObservableMap(); + public fields: ObservableMap = new ObservableMap(); + public _proxies: ObservableMap = new ObservableMap(); @computed public get Title() { diff --git a/src/fields/Field.ts b/src/fields/Field.ts index 6adee9b61..4a3968699 100644 --- a/src/fields/Field.ts +++ b/src/fields/Field.ts @@ -10,21 +10,21 @@ export function Cast(field: FieldValue, ctor: { new(): T return undefined; } -export let FieldWaiting: FIELD_WAITING = ""; +export const FieldWaiting: FIELD_WAITING = ""; export type FIELD_WAITING = ""; -export type FIELD_ID = string | undefined; +export type FieldId = string; export type Opt = T | undefined; export type FieldValue = Opt | FIELD_WAITING; export abstract class Field { //FieldUpdated: TypedEvent> = new TypedEvent>(); - private id: FIELD_ID; - get Id(): FIELD_ID { + private id: FieldId; + get Id(): FieldId { return this.id; } - constructor(id: FIELD_ID = undefined) { + constructor(id: Opt = undefined) { this.id = id || Utils.GenerateGuid(); } -- cgit v1.2.3-70-g09d2 From 7a93f60c9529e5d175e617fc7c07145a9b33e572 Mon Sep 17 00:00:00 2001 From: bobzel Date: Tue, 12 Feb 2019 15:49:06 -0500 Subject: more updates to resizing, etc. --- src/client/documents/Documents.ts | 4 +- src/client/views/Main.tsx | 6 +-- .../views/collections/CollectionDockingView.tsx | 63 +++++++++++++++------- .../views/collections/CollectionFreeFormView.tsx | 7 +-- .../views/collections/CollectionSchemaView.tsx | 2 +- .../views/collections/CollectionViewBase.tsx | 5 +- .../views/nodes/CollectionFreeFormDocumentView.tsx | 2 +- src/client/views/nodes/DocumentView.tsx | 9 +++- src/client/views/nodes/FormattedTextBox.tsx | 2 +- src/client/views/nodes/ImageBox.tsx | 3 +- 10 files changed, 68 insertions(+), 35 deletions(-) (limited to 'src/client/views/nodes/FormattedTextBox.tsx') diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts index 7512d25cb..72fa608ad 100644 --- a/src/client/documents/Documents.ts +++ b/src/client/documents/Documents.ts @@ -127,7 +127,7 @@ export namespace Documents { imageProto.Set(KeyStore.NativeHeight, new NumberField(300)); imageProto.Set(KeyStore.Width, new NumberField(300)); imageProto.Set(KeyStore.Height, new NumberField(300)); - imageProto.Set(KeyStore.Layout, new TextField("")); + imageProto.Set(KeyStore.Layout, new TextField(CollectionFreeFormView.LayoutString("AnnotationsKey"))); imageProto.Set(KeyStore.BackgroundLayout, new TextField(ImageBox.LayoutString())); // imageProto.SetField(KeyStore.Layout, new TextField('
')); imageProto.Set(KeyStore.LayoutKeys, new ListField([KeyStore.Data, KeyStore.Annotations])); @@ -161,7 +161,7 @@ export namespace Documents { collectionProto.Set(KeyStore.PanY, new NumberField(0)); collectionProto.Set(KeyStore.Width, new NumberField(300)); collectionProto.Set(KeyStore.Height, new NumberField(300)); - collectionProto.Set(KeyStore.Layout, new TextField(CollectionFreeFormView.LayoutString())); + collectionProto.Set(KeyStore.Layout, new TextField(CollectionFreeFormView.LayoutString("DataKey"))); collectionProto.Set(KeyStore.LayoutKeys, new ListField([KeyStore.Data])); } return collectionProto; diff --git a/src/client/views/Main.tsx b/src/client/views/Main.tsx index b58704264..ba92cc17e 100644 --- a/src/client/views/Main.tsx +++ b/src/client/views/Main.tsx @@ -40,7 +40,7 @@ document.addEventListener("pointerdown", action(function (e: PointerEvent) { //runInAction(() => { - let doc1 = Documents.TextDocument({ title: "hello" }); + 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)); @@ -62,7 +62,7 @@ document.addEventListener("pointerdown", action(function (e: PointerEvent) { // 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 = [doc4, doc1, doc3]; + let docset2 = [doc3, doc1, doc2]; let doc6 = Documents.CollectionDocument(docset2, { x: 350, y: 100, width: 600, height: 600, title: "docking collection" }); @@ -76,7 +76,7 @@ document.addEventListener("pointerdown", action(function (e: PointerEvent) { mainNodes.Data.push(doc3); // mainNodes.Data.push(doc5); // mainNodes.Data.push(doc1); - //mainNodes.Data.push(doc2); + // mainNodes.Data.push(doc2); mainNodes.Data.push(doc6); mainContainer.Set(KeyStore.Data, mainNodes); } diff --git a/src/client/views/collections/CollectionDockingView.tsx b/src/client/views/collections/CollectionDockingView.tsx index e3d50eb80..d3e90d11c 100644 --- a/src/client/views/collections/CollectionDockingView.tsx +++ b/src/client/views/collections/CollectionDockingView.tsx @@ -2,7 +2,7 @@ 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'; -import { action, computed } from "mobx"; +import { action, computed, reaction, observable } from "mobx"; import { observer } from "mobx-react"; import * as ReactDOM from 'react-dom'; import { Document } from "../../../fields/Document"; @@ -44,7 +44,7 @@ export class CollectionDockingView extends CollectionViewBase { 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 { type: 'component', componentName: 'documentViewComponent', componentState: { doc: doc, scaling: 1 } }; }); return new GoldenLayout({ settings: { @@ -111,6 +111,7 @@ export class CollectionDockingView extends CollectionViewBase { public static myLayout: any = null; + public rcs: Array = new Array(); private static _dragDiv: any = null; private static _dragParent: HTMLElement | null = null; private static _dragElement: HTMLDivElement; @@ -119,7 +120,7 @@ export class CollectionDockingView extends CollectionViewBase { var newItemConfig = { type: 'component', componentName: 'documentViewComponent', - componentState: { doc: dragDoc } + componentState: { doc: dragDoc, scaling: 1 } }; this._dragElement = dragElement; this._dragParent = dragElement.parentElement; @@ -160,7 +161,6 @@ export class CollectionDockingView extends CollectionViewBase { CollectionDockingView.myLayout._maximizedStack = null; } } - // // Creates a vertical split on the right side of the docking view, and then adds the Document to that split // @@ -241,21 +241,8 @@ export class CollectionDockingView extends CollectionViewBase { var containingDiv = "component_" + me.nextId(); container.getElement().html("
"); setTimeout(function () { - var htmlElement = document.getElementById(containingDiv); - container.on('resize', (e: any) => { - // state.doc.SetNumber(KeyStore.Width, htmlElement!.clientWidth); - // if (htmlElement!.clientHeight > 0) - // state.doc.SetNumber(KeyStore.Height, htmlElement!.clientHeight); - }) - ReactDOM.render(( - Transform.Identity} - Scaling={1} - ContainingCollectionView={me} DocumentView={undefined} /> - ), - htmlElement - ); + state.rc = new RenderClass(containingDiv, state.doc, me, container); + me.rcs.push(state.rc); if (CollectionDockingView.myLayout._maxstack != null) { CollectionDockingView.myLayout._maxstack.click(); } @@ -294,4 +281,42 @@ export class CollectionDockingView extends CollectionViewBase {
); } +} + +class RenderClass { + + @observable _resizeCount: number = 0; + + _collectionDockingView: CollectionDockingView; + _htmlElement: any; + _document: Document; + constructor(containingDiv: string, doc: Document, me: CollectionDockingView, container: any) { + this._collectionDockingView = me; + this._htmlElement = document.getElementById(containingDiv); + this._document = doc; + container.on('resize', action((e: any) => { + var nativeWidth = doc.GetNumber(KeyStore.NativeWidth, 0); + if (this._htmlElement != null && this._htmlElement.childElementCount > 0 && nativeWidth > 0) { + let scaling = nativeWidth > 0 ? this._htmlElement!.clientWidth / nativeWidth : 1; + (this._htmlElement!.children[0] as any).style.transformOrigin = "0px 0px"; + (this._htmlElement!.children[0] as any).style.transform = `translate(0px,0px) scale(${scaling}, ${scaling}) `; + (this._htmlElement!.children[0] as any).style.width = nativeWidth.toString() + "px"; + } + })); + + this.render(); + } + render() { + var nativeWidth = this._document.GetNumber(KeyStore.NativeWidth, 0); + let scaling = nativeWidth > 0 ? this._htmlElement!.clientWidth / nativeWidth : 1; + ReactDOM.render(( + Transform.Identity} + Scaling={scaling} + ContainingCollectionView={this._collectionDockingView} DocumentView={undefined} /> + ), + this._htmlElement + ); + } } \ No newline at end of file diff --git a/src/client/views/collections/CollectionFreeFormView.tsx b/src/client/views/collections/CollectionFreeFormView.tsx index 977a03f58..15450d737 100644 --- a/src/client/views/collections/CollectionFreeFormView.tsx +++ b/src/client/views/collections/CollectionFreeFormView.tsx @@ -17,7 +17,7 @@ import { Transform } from "../../util/Transform"; @observer export class CollectionFreeFormView extends CollectionViewBase { - public static LayoutString() { return CollectionViewBase.LayoutString("CollectionFreeFormView"); } + public static LayoutString(fieldKey: string = "DataKey") { return CollectionViewBase.LayoutString("CollectionFreeFormView", fieldKey); } private _containerRef = React.createRef(); private _canvasRef = React.createRef(); private _lastX: number = 0; @@ -218,6 +218,7 @@ export class CollectionFreeFormView extends CollectionViewBase { const value: Document[] = Document.GetList(this.props.CollectionFieldKey, []); const panx: number = Document.GetNumber(KeyStore.PanX, 0); const pany: number = Document.GetNumber(KeyStore.PanY, 0); + var me = this; return (
{this.props.BackgroundView} @@ -240,7 +241,7 @@ export class CollectionFreeFormView extends CollectionViewBase { AddDocument={this.addDocument} RemoveDocument={this.removeDocument} GetTransform={this.getTransform} - Scaling={this.resizeScaling} + Scaling={1} ContainingCollectionView={this} DocumentView={undefined} />); })}
diff --git a/src/client/views/collections/CollectionSchemaView.tsx b/src/client/views/collections/CollectionSchemaView.tsx index 331c4f6fe..f1e882e20 100644 --- a/src/client/views/collections/CollectionSchemaView.tsx +++ b/src/client/views/collections/CollectionSchemaView.tsx @@ -27,7 +27,7 @@ export class CollectionSchemaView extends CollectionViewBase { let props: FieldViewProps = { doc: rowProps.value[0], fieldKey: rowProps.value[1], - DocumentViewForField: undefined + DocumentViewForField: undefined, } let contents = ( diff --git a/src/client/views/collections/CollectionViewBase.tsx b/src/client/views/collections/CollectionViewBase.tsx index eea7908ce..7e2fcb39d 100644 --- a/src/client/views/collections/CollectionViewBase.tsx +++ b/src/client/views/collections/CollectionViewBase.tsx @@ -19,6 +19,7 @@ export interface CollectionViewProps { ContainingDocumentView: Opt; GetTransform: () => Transform; BackgroundView: Opt; + Scaling: number; } export const COLLECTION_BORDER_WIDTH = 2; @@ -26,8 +27,8 @@ export const COLLECTION_BORDER_WIDTH = 2; @observer export class CollectionViewBase extends React.Component { - public static LayoutString(collectionType: string) { - return `<${collectionType} DocumentForCollection={Document} CollectionFieldKey={DataKey} ContainingDocumentView={DocumentView}/>`; + public static LayoutString(collectionType: string, fieldKey: string = "DataKey") { + return `<${collectionType} Scaling={Scaling} DocumentForCollection={Document} CollectionFieldKey={${fieldKey}} ContainingDocumentView={DocumentView} BackgroundView={BackgroundView} />`; } @computed public get active(): boolean { diff --git a/src/client/views/nodes/CollectionFreeFormDocumentView.tsx b/src/client/views/nodes/CollectionFreeFormDocumentView.tsx index 54d3a1b56..9cd42a069 100644 --- a/src/client/views/nodes/CollectionFreeFormDocumentView.tsx +++ b/src/client/views/nodes/CollectionFreeFormDocumentView.tsx @@ -238,7 +238,7 @@ export class CollectionFreeFormDocumentView extends DocumentView { onContextMenu={this.onContextMenu} onPointerDown={this.onPointerDown}> - +
); } diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx index 691ac6311..3a73f2fde 100644 --- a/src/client/views/nodes/DocumentView.tsx +++ b/src/client/views/nodes/DocumentView.tsx @@ -115,7 +115,7 @@ export class DocumentView extends React.Component { 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; + Yy = ry - COLLECTION_BORDER_WIDTH + 18 * Ss; } let W = COLLECTION_BORDER_WIDTH; @@ -158,8 +158,13 @@ export class DocumentView extends React.Component { onError={(test: any) => { console.log(test) }} />; bindings["BackgroundView"] = this.backgroundLayout ? annotated : null; + + var width = this.props.Document.GetNumber(KeyStore.NativeWidth, 0); + var strwidth = width > 0 ? width.toString() + "px" : "100%"; + var height = this.props.Document.GetNumber(KeyStore.NativeHeight, 0); + var strheight = height > 0 ? height.toString() + "px" : "100%"; return ( -
+
{ return (
) diff --git a/src/client/views/nodes/ImageBox.tsx b/src/client/views/nodes/ImageBox.tsx index 60be5f94d..2fa70734d 100644 --- a/src/client/views/nodes/ImageBox.tsx +++ b/src/client/views/nodes/ImageBox.tsx @@ -85,10 +85,11 @@ export class ImageBox extends React.Component { 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"; + let nativeWidth = this.props.doc.GetNumber(KeyStore.NativeWidth, 1); return (
- Image not found + Image not found {this.lightbox(path)}
) } -- cgit v1.2.3-70-g09d2 From c93c3e1970c6ecc91b60f1782e82b1bfdc7fef30 Mon Sep 17 00:00:00 2001 From: Tyler Schicke Date: Wed, 13 Feb 2019 04:50:56 -0500 Subject: A lot of stuff working, a lot of other stuff not working --- .vscode/launch.json | 6 +- src/client/util/DragManager.ts | 2 + src/client/util/SelectionManager.ts | 12 +- src/client/util/Transform.ts | 70 ++++---- src/client/views/DocumentDecorations.tsx | 39 ++++- src/client/views/Main.tsx | 1 + .../views/collections/CollectionDockingView.tsx | 10 +- .../views/collections/CollectionFreeFormView.tsx | 55 +++--- .../views/collections/CollectionSchemaView.tsx | 4 +- .../views/collections/CollectionViewBase.tsx | 10 +- .../views/nodes/CollectionFreeFormDocumentView.tsx | 138 +--------------- src/client/views/nodes/DocumentView.tsx | 184 +++++++++++++++++++-- src/client/views/nodes/FieldView.tsx | 6 +- src/client/views/nodes/FormattedTextBox.tsx | 2 +- src/client/views/nodes/ImageBox.tsx | 4 +- 15 files changed, 303 insertions(+), 240 deletions(-) (limited to 'src/client/views/nodes/FormattedTextBox.tsx') diff --git a/.vscode/launch.json b/.vscode/launch.json index 9a0a9afb4..546ede805 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -11,7 +11,11 @@ "sourceMaps": true, "breakOnLoad": true, "url": "http://localhost:1050", - "webRoot": "${workspaceFolder}" + "webRoot": "${workspaceFolder}", + "skipFiles": [ + "${workspaceRoot}/node_modules/**/*.js", + "${workspaceRoot}/node_modules/**/*.ts", + ] }, { "type": "node", diff --git a/src/client/util/DragManager.ts b/src/client/util/DragManager.ts index f4dcce7c8..93b927f8b 100644 --- a/src/client/util/DragManager.ts +++ b/src/client/util/DragManager.ts @@ -78,6 +78,8 @@ export namespace DragManager { dragElement.style.transformOrigin = "0 0"; dragElement.style.zIndex = "1000"; dragElement.style.transform = `translate(${x}px, ${y}px) scale(${scaleX}, ${scaleY})`; + dragElement.style.width = `${rect.width}px`; + dragElement.style.height = `${rect.height}px`; dragDiv.appendChild(dragElement); _lastPointerX = dragData["xOffset"] + rect.left; _lastPointerY = dragData["yOffset"] + rect.top; diff --git a/src/client/util/SelectionManager.ts b/src/client/util/SelectionManager.ts index 0759ae110..1a711ae64 100644 --- a/src/client/util/SelectionManager.ts +++ b/src/client/util/SelectionManager.ts @@ -1,13 +1,13 @@ -import { CollectionFreeFormDocumentView } from "../views/nodes/CollectionFreeFormDocumentView"; import { observable, action } from "mobx"; +import { DocumentView } from "../views/nodes/DocumentView"; export namespace SelectionManager { class Manager { @observable - SelectedDocuments: Array = []; + SelectedDocuments: Array = []; @action - SelectDoc(doc: CollectionFreeFormDocumentView, ctrlPressed: boolean): void { + SelectDoc(doc: DocumentView, ctrlPressed: boolean): void { // if doc is not in SelectedDocuments, add it if (!ctrlPressed) { manager.SelectedDocuments = []; @@ -21,11 +21,11 @@ export namespace SelectionManager { const manager = new Manager; - export function SelectDoc(doc: CollectionFreeFormDocumentView, ctrlPressed: boolean): void { + export function SelectDoc(doc: DocumentView, ctrlPressed: boolean): void { manager.SelectDoc(doc, ctrlPressed) } - export function IsSelected(doc: CollectionFreeFormDocumentView): boolean { + export function IsSelected(doc: DocumentView): boolean { return manager.SelectedDocuments.indexOf(doc) !== -1; } @@ -33,7 +33,7 @@ export namespace SelectionManager { manager.SelectedDocuments = [] } - export function SelectedDocuments(): Array { + export function SelectedDocuments(): Array { return manager.SelectedDocuments; } } \ No newline at end of file diff --git a/src/client/util/Transform.ts b/src/client/util/Transform.ts index 3edc8d569..8ae3f837f 100644 --- a/src/client/util/Transform.ts +++ b/src/client/util/Transform.ts @@ -23,29 +23,13 @@ export class Transform { return this; } - translated = (x: number, y: number): Transform => { - return this.copy().translate(x, y); - } - - preTranslate = (x: number, y: number): Transform => { - this._translateX += x * this._scale; - this._translateY += y * this._scale; - return this; - } - - preTranslated = (x: number, y: number): Transform => { - return this.copy().preTranslate(x, y); - } - scale = (scale: number): Transform => { this._scale *= scale; + this._translateX *= scale; + this._translateY *= scale; return this; } - scaled = (scale: number): Transform => { - return this.copy().scale(scale); - } - scaleAbout = (scale: number, x: number, y: number): Transform => { this._translateX += x * this._scale - x * this._scale * scale; this._translateY += y * this._scale - y * this._scale * scale; @@ -53,21 +37,6 @@ export class Transform { return this; } - scaledAbout = (scale: number, x: number, y: number): Transform => { - return this.copy().scaleAbout(scale, x, y); - } - - preScale = (scale: number): Transform => { - this._scale *= scale; - this._translateX *= scale; - this._translateY *= scale; - return this; - } - - preScaled = (scale: number): Transform => { - return this.copy().preScale(scale); - } - transform = (transform: Transform): Transform => { this._translateX += transform._translateX * this._scale; this._translateY += transform._translateY * this._scale; @@ -75,8 +44,15 @@ export class Transform { return this; } - transformed = (transform: Transform): Transform => { - return this.copy().transform(transform); + preTranslate = (x: number, y: number): Transform => { + this._translateX += this._scale * x; + this._translateY += this._scale * y; + return this; + } + + preScale = (scale: number): Transform => { + this._scale *= scale; + return this; } preTransform = (transform: Transform): Transform => { @@ -86,6 +62,30 @@ export class Transform { return this; } + translated = (x: number, y: number): Transform => { + return this.copy().translate(x, y); + } + + preTranslated = (x: number, y: number): Transform => { + return this.copy().preTranslate(x, y); + } + + scaled = (scale: number): Transform => { + return this.copy().scale(scale); + } + + scaledAbout = (scale: number, x: number, y: number): Transform => { + return this.copy().scaleAbout(scale, x, y); + } + + preScaled = (scale: number): Transform => { + return this.copy().preScale(scale); + } + + transformed = (transform: Transform): Transform => { + return this.copy().transform(transform); + } + preTransformed = (transform: Transform): Transform => { return this.copy().preTransform(transform); } diff --git a/src/client/views/DocumentDecorations.tsx b/src/client/views/DocumentDecorations.tsx index 85b44307f..5abe3f5b2 100644 --- a/src/client/views/DocumentDecorations.tsx +++ b/src/client/views/DocumentDecorations.tsx @@ -4,6 +4,8 @@ import { SelectionManager } from "../util/SelectionManager"; import { observer } from "mobx-react"; import './DocumentDecorations.scss' import { CollectionFreeFormView } from "./collections/CollectionFreeFormView"; +import { KeyStore } from "../../fields/Key"; +import { NumberField } from "../../fields/NumberField"; @observer export class DocumentDecorations extends React.Component { @@ -25,9 +27,12 @@ export class DocumentDecorations extends React.Component { !(element.props.ContainingCollectionView instanceof CollectionFreeFormView)) { return bounds; } - let transform = element.getTransform().inverse(); + let transform = element.props.GetTransform().inverse(); var [sptX, sptY] = transform.transformPoint(0, 0); - var [bptX, bptY] = transform.transformDirection(element.width, element.height); + // var [bptX, bptY] = transform.transformDirection(element.width, element.height); + let doc = element.props.Document; + let [bptX, bptY] = [doc.GetNumber(KeyStore.Width, 0), doc.GetNumber(KeyStore.Height, 0)]; + [bptX, bptY] = transform.transformPoint(bptX, bptY); return { x: Math.min(sptX, bounds.x), y: Math.min(sptY, bounds.y), r: Math.max(bptX, bounds.r), b: Math.max(bptY, bounds.b) @@ -106,16 +111,32 @@ export class DocumentDecorations extends React.Component { SelectionManager.SelectedDocuments().forEach(element => { const rect = element.screenRect; + // if (rect.width !== 0) { + // let scale = element.width / rect.width; + // let actualdW = Math.max(element.width + (dW * scale), 20); + // let actualdH = Math.max(element.height + (dH * scale), 20); + // element.x += dX * (actualdW - element.width); + // element.y += dY * (actualdH - element.height); + // if (Math.abs(dW) > Math.abs(dH)) + // element.width = actualdW; + // else + // element.height = actualdH; + // } if (rect.width !== 0) { - let scale = element.width / rect.width; - let actualdW = Math.max(element.width + (dW * scale), 20); - let actualdH = Math.max(element.height + (dH * scale), 20); - element.x += dX * (actualdW - element.width); - element.y += dY * (actualdH - element.height); + let doc = element.props.Document; + let width = doc.GetOrCreate(KeyStore.Width, NumberField); + let height = doc.GetOrCreate(KeyStore.Height, NumberField); + let x = doc.GetOrCreate(KeyStore.X, NumberField); + let y = doc.GetOrCreate(KeyStore.X, NumberField); + let scale = width.Data / rect.width; + let actualdW = Math.max(width.Data + (dW * scale), 20); + let actualdH = Math.max(height.Data + (dH * scale), 20); + x.Data += dX * (actualdW - width.Data); + y.Data += dY * (actualdH - height.Data); if (Math.abs(dW) > Math.abs(dH)) - element.width = actualdW; + width.Data = actualdW; else - element.height = actualdH; + height.Data = actualdH; } }) } diff --git a/src/client/views/Main.tsx b/src/client/views/Main.tsx index 6ca0000b8..c7ad3e249 100644 --- a/src/client/views/Main.tsx +++ b/src/client/views/Main.tsx @@ -84,6 +84,7 @@ ReactDOM.render(( Transform.Identity} Scaling={1} + isTopMost={true} ContainingCollectionView={undefined} DocumentView={undefined} /> diff --git a/src/client/views/collections/CollectionDockingView.tsx b/src/client/views/collections/CollectionDockingView.tsx index d3e90d11c..c870a9cf0 100644 --- a/src/client/views/collections/CollectionDockingView.tsx +++ b/src/client/views/collections/CollectionDockingView.tsx @@ -16,6 +16,7 @@ import "./CollectionDockingView.scss"; import { CollectionViewBase, CollectionViewProps, COLLECTION_BORDER_WIDTH } from "./CollectionViewBase"; import React = require("react"); import { changeDependenciesStateTo0 } from "mobx/lib/internal"; +import { Utils } from "../../../Utils"; @observer export class CollectionDockingView extends CollectionViewBase { @@ -100,6 +101,7 @@ export class CollectionDockingView extends CollectionViewBase { return ( Transform.Identity} + isTopMost={true} Scaling={1} ContainingCollectionView={this} DocumentView={undefined} />); } @@ -307,12 +309,16 @@ class RenderClass { this.render(); } render() { - var nativeWidth = this._document.GetNumber(KeyStore.NativeWidth, 0); + let nativeWidth = this._document.GetNumber(KeyStore.NativeWidth, 0); let scaling = nativeWidth > 0 ? this._htmlElement!.clientWidth / nativeWidth : 1; ReactDOM.render(( Transform.Identity} + GetTransform={() => { + let { scale, translateX, translateY } = Utils.GetScreenTransform(this._htmlElement); + return this._collectionDockingView.props.GetTransform().scale(scale).translate(-translateX, -translateY) + }} + isTopMost={true} Scaling={scaling} ContainingCollectionView={this._collectionDockingView} DocumentView={undefined} /> ), diff --git a/src/client/views/collections/CollectionFreeFormView.tsx b/src/client/views/collections/CollectionFreeFormView.tsx index 975eaaae8..7947b1c51 100644 --- a/src/client/views/collections/CollectionFreeFormView.tsx +++ b/src/client/views/collections/CollectionFreeFormView.tsx @@ -14,6 +14,7 @@ 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"; @observer export class CollectionFreeFormView extends CollectionViewBase { @@ -45,23 +46,21 @@ export class CollectionFreeFormView extends CollectionViewBase { @action drop = (e: Event, de: DragManager.DropEvent) => { - const doc = de.data["document"]; + const doc: DocumentView = 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 { translateX, translateY } = Utils.GetScreenTransform(this._canvasRef.current!); - const currScale = this.resizeScaling * this.zoomScaling * this.props.ContainingDocumentView!.ScalingToScreenSpace; - const screenX = de.x - xOffset; - const screenY = de.y - yOffset; - doc.x = (screenX - translateX) / currScale; - doc.y = (screenY - translateY) / currScale; - this.bringToFront(doc); + 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 transform = doc.props.GetTransform(); + const screenX = de.x - xOffset; + const screenY = de.y - yOffset; + const [x, y] = transform.transformPoint(screenX, screenY); + doc.props.Document.SetNumber(KeyStore.X, x); + doc.props.Document.SetNumber(KeyStore.Y, y); + this.bringToFront(doc); e.stopPropagation(); } @@ -94,8 +93,8 @@ export class CollectionFreeFormView extends CollectionViewBase { document.removeEventListener("pointerup", this.onPointerUp); e.stopPropagation(); if (Math.abs(this._downX - e.clientX) < 3 && Math.abs(this._downY - e.clientY) < 3) { - if (!SelectionManager.IsSelected(this.props.ContainingDocumentView as CollectionFreeFormDocumentView)) { - SelectionManager.SelectDoc(this.props.ContainingDocumentView as CollectionFreeFormDocumentView, false); + if (!this.props.isSelected()) { + this.props.select(false); } } } @@ -105,11 +104,11 @@ export class CollectionFreeFormView extends CollectionViewBase { if (!e.cancelBubble && this.active) { e.preventDefault(); e.stopPropagation(); - let currScale: number = this.props.ContainingDocumentView!.ScalingToScreenSpace; let x = this.props.DocumentForCollection.GetNumber(KeyStore.PanX, 0); let y = this.props.DocumentForCollection.GetNumber(KeyStore.PanY, 0); + let [dx, dy] = this.props.GetTransform().transformDirection(e.clientX - this._lastX, e.clientY - this._lastY); - this.SetPan(x + (e.pageX - this._lastX) / currScale, y + (e.pageY - this._lastY) / currScale); + this.SetPan(x + dx, y + dy); } this._lastX = e.pageX; this._lastY = e.pageY; @@ -124,15 +123,14 @@ export class CollectionFreeFormView extends CollectionViewBase { // if (modes[e.deltaMode] == 'pixels') coefficient = 50; // else if (modes[e.deltaMode] == 'lines') coefficient = 1000; // This should correspond to line-height?? let transform = this.getTransform(); - let localTransform = this.getLocalTransform(); - let deltaScale = (1 - (e.deltaY / coefficient)) * transform.Scale; - let newDeltaScale = this.isAnnotationOverlay ? Math.max(1, deltaScale) : deltaScale; + let deltaScale = (1 - (e.deltaY / coefficient)); let [x, y] = transform.transformPoint(e.clientX, e.clientY); - localTransform.scaleAbout(newDeltaScale, x, y); + let localTransform = this.getLocalTransform(); + localTransform.scaleAbout(deltaScale, x, y); - this.props.DocumentForCollection.SetNumber(KeyStore.Scale, newDeltaScale); + this.props.DocumentForCollection.SetNumber(KeyStore.Scale, localTransform.Scale); this.SetPan(localTransform.TranslateX, localTransform.TranslateY); } @@ -182,7 +180,7 @@ export class CollectionFreeFormView extends CollectionViewBase { } @action - bringToFront(doc: CollectionFreeFormDocumentView) { + bringToFront(doc: DocumentView) { const { CollectionFieldKey: fieldKey, DocumentForCollection: Document } = this.props; const value: Document[] = Document.GetList(fieldKey, []); @@ -213,12 +211,12 @@ export class CollectionFreeFormView extends CollectionViewBase { getTransform = (): Transform => { const [x, y] = this.translate; - return this.props.GetTransform().scaled(this.scale).translate(x, y); + return this.props.GetTransform().translate(-COLLECTION_BORDER_WIDTH, -COLLECTION_BORDER_WIDTH).transform(this.getLocalTransform().inverse()) } getLocalTransform = (): Transform => { const [x, y] = this.translate; - return new Transform(x, y, this.scale); + return Transform.Identity.scale(this.scale).translate(x, y); } render() { @@ -249,8 +247,9 @@ export class CollectionFreeFormView extends CollectionViewBase { AddDocument={this.addDocument} RemoveDocument={this.removeDocument} GetTransform={this.getTransform} + isTopMost={false} Scaling={1} - ContainingCollectionView={this} DocumentView={undefined} />); + ContainingCollectionView={this} DocumentView={this.props.ContainingDocumentView} />); })}
diff --git a/src/client/views/collections/CollectionSchemaView.tsx b/src/client/views/collections/CollectionSchemaView.tsx index f1e882e20..adae8560e 100644 --- a/src/client/views/collections/CollectionSchemaView.tsx +++ b/src/client/views/collections/CollectionSchemaView.tsx @@ -27,7 +27,8 @@ export class CollectionSchemaView extends CollectionViewBase { let props: FieldViewProps = { doc: rowProps.value[0], fieldKey: rowProps.value[1], - DocumentViewForField: undefined, + isSelected: () => false, + isTopMost: false } let contents = ( @@ -110,6 +111,7 @@ export class CollectionSchemaView extends CollectionViewBase { AddDocument={this.addDocument} RemoveDocument={this.removeDocument} GetTransform={() => Transform.Identity}//TODO This should probably be an actual transform Scaling={1} + isTopMost={false} DocumentView={undefined} ContainingCollectionView={this} /> ) } else { diff --git a/src/client/views/collections/CollectionViewBase.tsx b/src/client/views/collections/CollectionViewBase.tsx index cf5bc70c4..2c950c8ae 100644 --- a/src/client/views/collections/CollectionViewBase.tsx +++ b/src/client/views/collections/CollectionViewBase.tsx @@ -18,6 +18,9 @@ export interface CollectionViewProps { DocumentForCollection: Document; ContainingDocumentView: Opt; GetTransform: () => Transform; + isSelected: () => boolean; + isTopMost: boolean; + select: (ctrlPressed: boolean) => void; BackgroundView: Opt; Scaling: number; } @@ -29,16 +32,15 @@ export class CollectionViewBase extends React.Component { public static LayoutString(collectionType: string, fieldKey: string = "DataKey") { return `<${collectionType} Scaling={Scaling} DocumentForCollection={Document} - GetTransform={GetTransform} CollectionFieldKey={${fieldKey}} + GetTransform={GetTransform} CollectionFieldKey={${fieldKey}} isSelected={isSelected} select={select} + isTopMost={isTopMost} ContainingDocumentView={DocumentView} BackgroundView={BackgroundView} />`; } @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); + var topMost = this.props.isTopMost; return isSelected || childSelected || topMost; } @action diff --git a/src/client/views/nodes/CollectionFreeFormDocumentView.tsx b/src/client/views/nodes/CollectionFreeFormDocumentView.tsx index 9cd42a069..54bc7327b 100644 --- a/src/client/views/nodes/CollectionFreeFormDocumentView.tsx +++ b/src/client/views/nodes/CollectionFreeFormDocumentView.tsx @@ -14,11 +14,8 @@ import { Transform } from "../../util/Transform"; @observer -export class CollectionFreeFormDocumentView extends DocumentView { - private _contextMenuCanOpen = false; - private _downX: number = 0; - private _downY: number = 0; - // private _mainCont = React.createRef(); +export class CollectionFreeFormDocumentView extends React.Component { + private _mainCont = React.createRef(); constructor(props: DocumentViewProps) { super(props); @@ -95,130 +92,6 @@ export class CollectionFreeFormDocumentView extends DocumentView { 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); - } - } getTransform = (): Transform => { return this.props.GetTransform().translated(this.x, this.y); @@ -234,11 +107,10 @@ export class CollectionFreeFormDocumentView extends DocumentView { height: freestyling ? this.height : "100%", position: freestyling ? "absolute" : "relative", zIndex: freestyling ? this.zIndex : 0, - }} - onContextMenu={this.onContextMenu} - onPointerDown={this.onPointerDown}> + backgroundColor: "transparent" + }} > - +
); } diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx index d7ecc6d9d..cb080c08e 100644 --- a/src/client/views/nodes/DocumentView.tsx +++ b/src/client/views/nodes/DocumentView.tsx @@ -16,6 +16,9 @@ import { ImageBox } from "../nodes/ImageBox"; import "./NodeView.scss"; import React = require("react"); import { Transform } from "../../util/Transform"; +import { SelectionManager } from "../../util/SelectionManager"; +import { DragManager } from "../../util/DragManager"; +import { ContextMenu } from "../ContextMenu"; const JsxParser = require('react-jsx-parser').default;//TODO Why does this need to be imported like this? export interface DocumentViewProps { @@ -26,24 +29,34 @@ export interface DocumentViewProps { AddDocument?: (doc: Document) => void; RemoveDocument?: (doc: Document) => boolean; GetTransform: () => Transform; + isTopMost: boolean; Scaling: number; } @observer export class DocumentView extends React.Component { - protected _mainCont = React.createRef(); + private _mainCont = React.createRef(); get MainContent() { return this._mainCont; } + get screenRect(): ClientRect | DOMRect { + if (this._mainCont.current) { + return this._mainCont.current.getBoundingClientRect(); + } + return new DOMRect(); + } @computed get layout(): string { return this.props.Document.GetData(KeyStore.Layout, TextField, String("

Error loading layout data

")); } @computed - get backgroundLayout(): string { - return this.props.Document.GetData(KeyStore.BackgroundLayout, TextField, String("

Error loading layout data

")); + get backgroundLayout(): string | undefined { + let field = this.props.Document.GetT(KeyStore.BackgroundLayout, TextField); + if (field && field !== "") { + return field.Data; + } } @computed @@ -56,6 +69,134 @@ export class DocumentView extends React.Component { return this.props.Document.GetData(KeyStore.LayoutFields, ListField, new Array()); } + @computed + get active(): boolean { + return SelectionManager.IsSelected(this) || this.props.ContainingCollectionView === undefined || + this.props.ContainingCollectionView.active; + } + + private _contextMenuCanOpen = false; + private _downX: number = 0; + private _downY: number = 0; + 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); + } + } + + @action + dragComplete = (e: DragManager.DragCompleteEvent) => { + } + + @computed + get topMost(): boolean { + return this.props.ContainingCollectionView == undefined || this.props.ContainingCollectionView instanceof CollectionDockingView; + } + + 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 [left, top] = this.props.GetTransform().inverse().transformPoint(0, 0); + let dragData: { [id: string]: any } = {}; + dragData["document"] = this; + dragData["xOffset"] = e.x - left; + dragData["yOffset"] = e.y - 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.RemoveDocument) { + this.props.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); + } + } + // // returns the cumulative scaling between the document and the screen // @@ -69,9 +210,19 @@ export class DocumentView extends React.Component { return 1; } + isSelected = () => { + return SelectionManager.IsSelected(this); + } + + select = (ctrlPressed: boolean) => { + SelectionManager.SelectDoc(this, ctrlPressed) + } + render() { let bindings = { ...this.props } as any; + bindings.isSelected = this.isSelected; + bindings.select = this.select; for (const key of this.layoutKeys) { bindings[key.Name + "Key"] = key; // this maps string values of the form Key to an actual key Kestore.keyname e.g, "DataKey" => KeyStore.Data } @@ -82,26 +233,29 @@ export class DocumentView extends React.Component { 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. + let annotated = null; + let backgroundLayout = this.backgroundLayout; + if (backgroundLayout) { + annotated = { console.log(test) }} + />; } - var annotated = { console.log(test) }} - />; - bindings["BackgroundView"] = this.backgroundLayout ? annotated : null; + bindings.BackgroundView = annotated; var width = this.props.Document.GetNumber(KeyStore.NativeWidth, 0); var strwidth = width > 0 ? width.toString() + "px" : "100%"; var height = this.props.Document.GetNumber(KeyStore.NativeHeight, 0); var strheight = height > 0 ? height.toString() + "px" : "100%"; return ( -
+
+ isSelected: () => boolean; + isTopMost: boolean; } @observer export class FieldView extends React.Component { - public static LayoutString(fieldType: string) { return `<${fieldType} doc={Document} DocumentViewForField={DocumentView} fieldKey={DataKey} />`; } + public static LayoutString(fieldType: string) { return `<${fieldType} doc={Document} DocumentViewForField={DocumentView} fieldKey={DataKey} isSelected={isSelected} isTopMost={isTopMost} />`; } @computed get field(): FieldValue { const { doc, fieldKey } = this.props; diff --git a/src/client/views/nodes/FormattedTextBox.tsx b/src/client/views/nodes/FormattedTextBox.tsx index f6bd0c0f8..2e3d396c1 100644 --- a/src/client/views/nodes/FormattedTextBox.tsx +++ b/src/client/views/nodes/FormattedTextBox.tsx @@ -110,7 +110,7 @@ export class FormattedTextBox extends React.Component { } onPointerDown = (e: React.PointerEvent): void => { let me = this; - if (e.buttons === 1 && me.props.DocumentViewForField instanceof CollectionFreeFormDocumentView && SelectionManager.IsSelected(me.props.DocumentViewForField)) { + if (e.buttons === 1 && this.props.isSelected()) { e.stopPropagation(); } } diff --git a/src/client/views/nodes/ImageBox.tsx b/src/client/views/nodes/ImageBox.tsx index 2fa70734d..e1fa26e2f 100644 --- a/src/client/views/nodes/ImageBox.tsx +++ b/src/client/views/nodes/ImageBox.tsx @@ -41,7 +41,7 @@ export class ImageBox extends React.Component { 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)) { + if (e.buttons === 1 && this.props.isSelected()) { e.stopPropagation(); this._downX = e.clientX; this._downY = e.clientY; @@ -63,7 +63,7 @@ export class ImageBox extends React.Component { 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)) { + if (this._isOpen && this.props.isSelected()) { return ( Date: Fri, 22 Feb 2019 21:39:40 -0500 Subject: moved backgroundLayout to CollectionFreeForm --- src/client/views/DocumentDecorations.tsx | 2 +- .../views/collections/CollectionFreeFormView.tsx | 58 ++++++++++++++-------- .../views/collections/CollectionSchemaView.tsx | 3 +- src/client/views/collections/CollectionView.tsx | 2 +- .../views/collections/CollectionViewBase.tsx | 2 +- src/client/views/nodes/DocumentView.tsx | 41 ++++----------- src/client/views/nodes/FieldView.tsx | 3 +- src/client/views/nodes/FormattedTextBox.tsx | 1 - 8 files changed, 55 insertions(+), 57 deletions(-) (limited to 'src/client/views/nodes/FormattedTextBox.tsx') diff --git a/src/client/views/DocumentDecorations.tsx b/src/client/views/DocumentDecorations.tsx index efd50e49e..09df8cdaa 100644 --- a/src/client/views/DocumentDecorations.tsx +++ b/src/client/views/DocumentDecorations.tsx @@ -101,7 +101,7 @@ export class DocumentDecorations extends React.Component { } SelectionManager.SelectedDocuments().forEach(element => { - const rect = element.screenRect; + const rect = element.screenRect(); if (rect.width !== 0) { let doc = element.props.Document; let width = doc.GetOrCreate(KeyStore.Width, NumberField); diff --git a/src/client/views/collections/CollectionFreeFormView.tsx b/src/client/views/collections/CollectionFreeFormView.tsx index 43bc24a12..565402046 100644 --- a/src/client/views/collections/CollectionFreeFormView.tsx +++ b/src/client/views/collections/CollectionFreeFormView.tsx @@ -1,18 +1,25 @@ +import { action, computed } from "mobx"; import { observer } from "mobx-react"; -import React = require("react"); -import { action, computed, trace } from "mobx"; -import { CollectionFreeFormDocumentView } from "../nodes/CollectionFreeFormDocumentView"; -import { DragManager } from "../../util/DragManager"; -import "./CollectionFreeFormView.scss"; -import { COLLECTION_BORDER_WIDTH } from "./CollectionView"; -import { KeyStore } from "../../../fields/KeyStore"; import { Document } from "../../../fields/Document"; -import { ListField } from "../../../fields/ListField"; import { FieldWaiting } from "../../../fields/Field"; +import { KeyStore } from "../../../fields/KeyStore"; +import { ListField } from "../../../fields/ListField"; +import { TextField } from "../../../fields/TextField"; +import { DragManager } from "../../util/DragManager"; import { Transform } from "../../util/Transform"; -import { DocumentView } from "../nodes/DocumentView"; import { undoBatch } from "../../util/UndoManager"; -import { CollectionViewBase, SubCollectionViewProps } from "./CollectionViewBase"; +import { CollectionDockingView } from "../collections/CollectionDockingView"; +import { CollectionSchemaView } from "../collections/CollectionSchemaView"; +import { CollectionView } from "../collections/CollectionView"; +import { CollectionFreeFormDocumentView } from "../nodes/CollectionFreeFormDocumentView"; +import { DocumentView } from "../nodes/DocumentView"; +import { FormattedTextBox } from "../nodes/FormattedTextBox"; +import { ImageBox } from "../nodes/ImageBox"; +import "./CollectionFreeFormView.scss"; +import { COLLECTION_BORDER_WIDTH } from "./CollectionView"; +import { CollectionViewBase } from "./CollectionViewBase"; +import React = require("react"); +const JsxParser = require('react-jsx-parser').default;//TODO Why does this need to be imported like this? @observer export class CollectionFreeFormView extends CollectionViewBase { @@ -145,16 +152,13 @@ export class CollectionFreeFormView extends CollectionViewBase { }); } - getTransform = (): Transform => { - return this.props.ScreenToLocalTransform().translate(-COLLECTION_BORDER_WIDTH, -COLLECTION_BORDER_WIDTH).transform(this.getLocalTransform()) - } - getLocalTransform = (): Transform => { - return Transform.Identity.translate(-this.panX, -this.panY).scale(1 / this.scale); + @computed get backgroundLayout(): string | undefined { + let field = this.props.Document.GetT(KeyStore.BackgroundLayout, TextField); + if (field && field !== "") { + return field.Data; + } } - - noScaling = () => 1; - @computed get views() { const { fieldKey, Document } = this.props; @@ -175,6 +179,21 @@ export class CollectionFreeFormView extends CollectionViewBase { return null; } + @computed + get backgroundView() { + return !this.backgroundLayout ? (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; + render() { const panx: number = this.props.Document.GetNumber(KeyStore.PanX, 0); const pany: number = this.props.Document.GetNumber(KeyStore.PanY, 0); @@ -190,8 +209,7 @@ export class CollectionFreeFormView extends CollectionViewBase {
- - {this.props.BackgroundView ? this.props.BackgroundView() : null} + {this.backgroundView} {this.views}
diff --git a/src/client/views/collections/CollectionSchemaView.tsx b/src/client/views/collections/CollectionSchemaView.tsx index ca47f6998..d2db93120 100644 --- a/src/client/views/collections/CollectionSchemaView.tsx +++ b/src/client/views/collections/CollectionSchemaView.tsx @@ -34,7 +34,8 @@ export class CollectionSchemaView extends CollectionViewBase { fieldKey: rowProps.value[1], isSelected: () => false, select: () => { }, - isTopMost: false + isTopMost: false, + bindings: {} } let contents = ( diff --git a/src/client/views/collections/CollectionView.tsx b/src/client/views/collections/CollectionView.tsx index ff1803ec3..90080ab43 100644 --- a/src/client/views/collections/CollectionView.tsx +++ b/src/client/views/collections/CollectionView.tsx @@ -28,7 +28,7 @@ export class CollectionView extends React.Component { public static LayoutString(fieldKey: string = "DataKey") { return ``; } public active = () => { diff --git a/src/client/views/collections/CollectionViewBase.tsx b/src/client/views/collections/CollectionViewBase.tsx index 06de56383..da7f71163 100644 --- a/src/client/views/collections/CollectionViewBase.tsx +++ b/src/client/views/collections/CollectionViewBase.tsx @@ -19,7 +19,7 @@ export interface CollectionViewProps { isSelected: () => boolean; isTopMost: boolean; select: (ctrlPressed: boolean) => void; - BackgroundView?: () => JSX.Element; + bindings: any; } export interface SubCollectionViewProps extends CollectionViewProps { active: () => boolean; diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx index d9b1d90d8..a9e211431 100644 --- a/src/client/views/nodes/DocumentView.tsx +++ b/src/client/views/nodes/DocumentView.tsx @@ -5,7 +5,6 @@ import { Field, FieldWaiting, Opt } from "../../../fields/Field"; import { Key } from "../../../fields/Key"; import { KeyStore } from "../../../fields/KeyStore"; import { ListField } from "../../../fields/ListField"; -import { TextField } from "../../../fields/TextField"; import { DragManager } from "../../util/DragManager"; import { SelectionManager } from "../../util/SelectionManager"; import { Transform } from "../../util/Transform"; @@ -84,21 +83,13 @@ export class DocumentView extends React.Component { private _downX: number = 0; private _downY: number = 0; - get screenRect(): ClientRect | DOMRect { - return (this._mainCont.current) ? this._mainCont.current.getBoundingClientRect() : new DOMRect(); - } @computed get active(): boolean { return SelectionManager.IsSelected(this) || !this.props.ContainingCollectionView || this.props.ContainingCollectionView.active(); } @computed get topMost(): boolean { return !this.props.ContainingCollectionView || this.props.ContainingCollectionView.collectionViewType == CollectionViewType.Docking; } @computed get layout(): string { return this.props.Document.GetText(KeyStore.Layout, "

Error loading layout data

"); } @computed get layoutKeys(): Key[] { return this.props.Document.GetData(KeyStore.LayoutKeys, ListField, new Array()); } @computed get layoutFields(): Key[] { return this.props.Document.GetData(KeyStore.LayoutFields, ListField, new Array()); } - @computed get backgroundLayout(): string | undefined { - let field = this.props.Document.GetT(KeyStore.BackgroundLayout, TextField); - if (field && field !== "") { - return field.Data; - } - } + screenRect = (): ClientRect | DOMRect => this._mainCont.current ? this._mainCont.current.getBoundingClientRect() : new DOMRect(); onPointerDown = (e: React.PointerEvent): void => { this._downX = e.clientX; @@ -174,6 +165,7 @@ export class DocumentView extends React.Component { ContextMenu.Instance.displayMenu(e.pageX - 15, e.pageY - 15) } + @action onContextMenu = (e: React.MouseEvent): void => { e.preventDefault() e.stopPropagation(); @@ -230,32 +222,19 @@ export class DocumentView extends React.Component { let field = this.props.Document.Get(key); this._documentBindings[key.Name] = field && field != FieldWaiting ? field.GetValue() : field; } - - /* - tfs: - Should this be moved to CollectionFreeformView or another component that renders - Document backgrounds (or contents based on a layout key, which could be used here as well) - that CollectionFreeformView uses? It seems like a lot for it to be here considering only one view currently uses it... - */ - let backgroundLayout = this.backgroundLayout; - if (backgroundLayout) { - let backgroundView = () => ( { console.log(test) }} - />); - this._documentBindings.BackgroundView = backgroundView; - } + this._documentBindings.bindings = this._documentBindings; var scaling = this.props.ContentScaling(); var nativeWidth = this.props.Document.GetNumber(KeyStore.NativeWidth, 0); var nativeHeight = this.props.Document.GetNumber(KeyStore.NativeHeight, 0); - var nodeWidth = nativeWidth > 0 ? nativeWidth.toString() + "px" : "100%"; - var nodeHeight = nativeHeight > 0 ? nativeHeight.toString() + "px" : "100%"; return ( -
0 ? nativeWidth.toString() + "px" : "100%", + height: nativeHeight > 0 ? nativeHeight.toString() + "px" : "100%", + transformOrigin: "left top", + transform: `scale(${scaling},${scaling})` + }} onContextMenu={this.onContextMenu} onPointerDown={this.onPointerDown} > {this.mainContent} diff --git a/src/client/views/nodes/FieldView.tsx b/src/client/views/nodes/FieldView.tsx index 821172d71..97d3f2a85 100644 --- a/src/client/views/nodes/FieldView.tsx +++ b/src/client/views/nodes/FieldView.tsx @@ -22,11 +22,12 @@ export interface FieldViewProps { isSelected: () => boolean; select: () => void; isTopMost: boolean; + bindings: any; } @observer export class FieldView extends React.Component { - public static LayoutString(fieldType: { name: string }) { return `<${fieldType.name} doc={Document} DocumentViewForField={DocumentView} fieldKey={DataKey} isSelected={isSelected} select={select} isTopMost={isTopMost} />`; } + public static LayoutString(fieldType: { name: string }) { return `<${fieldType.name} doc={Document} DocumentViewForField={DocumentView} bindings={bindings} fieldKey={DataKey} isSelected={isSelected} select={select} isTopMost={isTopMost} />`; } @computed get field(): FieldValue { const { doc, fieldKey } = this.props; diff --git a/src/client/views/nodes/FormattedTextBox.tsx b/src/client/views/nodes/FormattedTextBox.tsx index b17650d06..16728d471 100644 --- a/src/client/views/nodes/FormattedTextBox.tsx +++ b/src/client/views/nodes/FormattedTextBox.tsx @@ -6,7 +6,6 @@ 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"; -- cgit v1.2.3-70-g09d2 From f4ec29ad3143cf13bf7fa05985926242cabb6b1a 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/views/nodes/FormattedTextBox.tsx') 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