diff options
Diffstat (limited to 'src/client/views/nodes')
| -rw-r--r-- | src/client/views/nodes/CollectionFreeFormDocumentView.tsx | 190 | ||||
| -rw-r--r-- | src/client/views/nodes/DocumentView.scss (renamed from src/client/views/nodes/NodeView.scss) | 2 | ||||
| -rw-r--r-- | src/client/views/nodes/DocumentView.tsx | 276 | ||||
| -rw-r--r-- | src/client/views/nodes/FieldView.tsx | 6 | ||||
| -rw-r--r-- | src/client/views/nodes/FormattedTextBox.scss | 2 | ||||
| -rw-r--r-- | src/client/views/nodes/FormattedTextBox.tsx | 7 | ||||
| -rw-r--r-- | src/client/views/nodes/ImageBox.scss | 8 | ||||
| -rw-r--r-- | src/client/views/nodes/ImageBox.tsx | 14 |
8 files changed, 251 insertions, 254 deletions
diff --git a/src/client/views/nodes/CollectionFreeFormDocumentView.tsx b/src/client/views/nodes/CollectionFreeFormDocumentView.tsx index bfd50da81..e04135257 100644 --- a/src/client/views/nodes/CollectionFreeFormDocumentView.tsx +++ b/src/client/views/nodes/CollectionFreeFormDocumentView.tsx @@ -7,17 +7,16 @@ import { SelectionManager } from "../../util/SelectionManager"; import { CollectionDockingView } from "../collections/CollectionDockingView"; import { CollectionFreeFormView } from "../collections/CollectionFreeFormView"; import { ContextMenu } from "../ContextMenu"; -import "./NodeView.scss"; +import "./DocumentView.scss"; import React = require("react"); import { DocumentView, DocumentViewProps } from "./DocumentView"; import { Utils } from "../../../Utils"; +import { Transform } from "../../util/Transform"; @observer -export class CollectionFreeFormDocumentView extends DocumentView { - private _contextMenuCanOpen = false; - private _downX: number = 0; - private _downY: number = 0; +export class CollectionFreeFormDocumentView extends React.Component<DocumentViewProps> { + private _mainCont = React.createRef<HTMLDivElement>(); constructor(props: DocumentViewProps) { super(props); @@ -30,198 +29,71 @@ export class CollectionFreeFormDocumentView extends DocumentView { } @computed - get x(): number { - return this.props.Document.GetData(KeyStore.X, NumberField, Number(0)); - } - - @computed - get y(): number { - return this.props.Document.GetData(KeyStore.Y, NumberField, Number(0)); - } - - set x(x: number) { - this.props.Document.SetData(KeyStore.X, x, NumberField) - } - - set y(y: number) { - this.props.Document.SetData(KeyStore.Y, y, NumberField) + get transform(): string { + return `scale(${this.props.Scaling}, ${this.props.Scaling}) translate(${this.props.Document.GetNumber(KeyStore.X, 0)}px, ${this.props.Document.GetNumber(KeyStore.Y, 0)}px)`; } @computed - get transform(): string { - return `translate(${this.x}px, ${this.y}px)`; + get width(): number { + return this.props.Document.GetNumber(KeyStore.Width, 0); } @computed - get width(): number { - return this.props.Document.GetData(KeyStore.Width, NumberField, Number(0)); + get nativeWidth(): number { + return this.props.Document.GetNumber(KeyStore.NativeWidth, 0); } set width(w: number) { this.props.Document.SetData(KeyStore.Width, w, NumberField) + if (this.nativeWidth > 0 && this.nativeHeight > 0) { + this.props.Document.SetNumber(KeyStore.Height, this.nativeHeight / this.nativeWidth * w) + } } @computed get height(): number { - return this.props.Document.GetData(KeyStore.Height, NumberField, Number(0)); + return this.props.Document.GetNumber(KeyStore.Height, 0); + } + @computed + get nativeHeight(): number { + return this.props.Document.GetNumber(KeyStore.NativeHeight, 0); } set height(h: number) { - this.props.Document.SetData(KeyStore.Height, h, NumberField) + this.props.Document.SetData(KeyStore.Height, h, NumberField); + if (this.nativeWidth > 0 && this.nativeHeight > 0) { + this.props.Document.SetNumber(KeyStore.Width, this.nativeWidth / this.nativeHeight * h) + } } @computed get zIndex(): number { - return this.props.Document.GetData(KeyStore.ZIndex, NumberField, Number(0)); + return this.props.Document.GetNumber(KeyStore.ZIndex, 0); } set zIndex(h: number) { this.props.Document.SetData(KeyStore.ZIndex, h, NumberField) } - @action - dragComplete = (e: DragManager.DragCompleteEvent) => { - } - - @computed - get active(): boolean { - return SelectionManager.IsSelected(this) || this.props.ContainingCollectionView === undefined || - this.props.ContainingCollectionView.active; - } - - @computed - get topMost(): boolean { - return this.props.ContainingCollectionView == undefined || this.props.ContainingCollectionView instanceof CollectionDockingView; - } - - onPointerDown = (e: React.PointerEvent): void => { - this._downX = e.clientX; - this._downY = e.clientY; - var me = this; - if (e.shiftKey && e.buttons === 1) { - CollectionDockingView.StartOtherDrag(this._mainCont.current!, this.props.Document); - e.stopPropagation(); - return; - } - this._contextMenuCanOpen = e.button == 2; - if (this.active && !e.isDefaultPrevented()) { - e.stopPropagation(); - if (e.buttons === 2) { - e.preventDefault(); - } - document.removeEventListener("pointermove", this.onPointerMove) - document.addEventListener("pointermove", this.onPointerMove); - document.removeEventListener("pointerup", this.onPointerUp) - document.addEventListener("pointerup", this.onPointerUp); - } - } - - onPointerMove = (e: PointerEvent): void => { - if (e.cancelBubble) { - this._contextMenuCanOpen = false; - return; - } - if (Math.abs(this._downX - e.clientX) > 3 || Math.abs(this._downY - e.clientY) > 3) { - this._contextMenuCanOpen = false; - if (this._mainCont.current != null && !this.topMost) { - this._contextMenuCanOpen = false; - const rect = this.screenRect; - let dragData: { [id: string]: any } = {}; - dragData["document"] = this; - dragData["xOffset"] = e.x - rect.left; - dragData["yOffset"] = e.y - rect.top; - DragManager.StartDrag(this._mainCont.current, dragData, { - handlers: { - dragComplete: this.dragComplete, - }, - hideSource: true - }) - } - } - e.stopPropagation(); - e.preventDefault(); - } - - onPointerUp = (e: PointerEvent): void => { - document.removeEventListener("pointermove", this.onPointerMove) - document.removeEventListener("pointerup", this.onPointerUp) - e.stopPropagation(); - if (Math.abs(e.clientX - this._downX) < 4 && Math.abs(e.clientY - this._downY) < 4) { - SelectionManager.SelectDoc(this, e.ctrlKey); - } - } - - openRight = (e: React.MouseEvent): void => { - CollectionDockingView.AddRightSplit(this.props.Document); - } - - deleteClicked = (e: React.MouseEvent): void => { - if (this.props.ContainingCollectionView instanceof CollectionFreeFormView) { - this.props.ContainingCollectionView.removeDocument(this.props.Document) - } - } - @action - fullScreenClicked = (e: React.MouseEvent): void => { - CollectionDockingView.OpenFullScreen(this.props.Document); - ContextMenu.Instance.clearItems(); - ContextMenu.Instance.addItem({ description: "Close Full Screen", event: this.closeFullScreenClicked }); - ContextMenu.Instance.displayMenu(e.pageX - 15, e.pageY - 15) - } - @action - closeFullScreenClicked = (e: React.MouseEvent): void => { - CollectionDockingView.CloseFullScreen(); - ContextMenu.Instance.clearItems(); - ContextMenu.Instance.addItem({ description: "Full Screen", event: this.fullScreenClicked }) - ContextMenu.Instance.displayMenu(e.pageX - 15, e.pageY - 15) - } - - @action - onContextMenu = (e: React.MouseEvent): void => { - if (!SelectionManager.IsSelected(this)) { - return; - } - e.preventDefault() - - if (!this._contextMenuCanOpen) { - return; - } - - if (this.topMost) { - ContextMenu.Instance.clearItems() - ContextMenu.Instance.addItem({ description: "Full Screen", event: this.fullScreenClicked }) - } - 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 }) - SelectionManager.SelectDoc(this, e.ctrlKey); - } - ContextMenu.Instance.addItem({ - description: "Copy ID", event: () => { - Utils.CopyText(this.props.Document.Id) - } - }) - ContextMenu.Instance.displayMenu(e.pageX - 15, e.pageY - 15) + getTransform = (): Transform => { + return this.props.ScreenToLocalTransform().translate(-this.props.Document.GetNumber(KeyStore.X, 0), -this.props.Document.GetNumber(KeyStore.Y, 0)); } render() { + var parentScaling = this.nativeWidth > 0 ? this.width / this.nativeWidth : 1; return ( - <div className="node" ref={this._mainCont} style={{ + <div ref={this._mainCont} style={{ + transformOrigin: "left top", transform: this.transform, width: this.width, height: this.height, position: "absolute", zIndex: this.zIndex, - }} - onContextMenu={this.onContextMenu} - onPointerDown={this.onPointerDown}> + backgroundColor: "transparent" + }} > - <DocumentView {...this.props} DocumentView={this} /> + <DocumentView {...this.props} Scaling={this.width / this.nativeWidth} ScreenToLocalTransform={this.getTransform} /> </div> ); } diff --git a/src/client/views/nodes/NodeView.scss b/src/client/views/nodes/DocumentView.scss index dac1c0a8e..8e2ebd690 100644 --- a/src/client/views/nodes/NodeView.scss +++ b/src/client/views/nodes/DocumentView.scss @@ -1,4 +1,4 @@ -.node { +.documentView-node { position: absolute; background: #cdcdcd; overflow: hidden; diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx index 3767d28c6..aa85fba03 100644 --- a/src/client/views/nodes/DocumentView.tsx +++ b/src/client/views/nodes/DocumentView.tsx @@ -5,8 +5,6 @@ import { Opt, FieldWaiting, Field } from "../../../fields/Field"; import { Key } from "../../../fields/Key"; import { KeyStore } from "../../../fields/KeyStore"; import { ListField } from "../../../fields/ListField"; -import { NumberField } from "../../../fields/NumberField"; -import { TextField } from "../../../fields/TextField"; import { Utils } from "../../../Utils"; import { CollectionDockingView } from "../collections/CollectionDockingView"; import { CollectionFreeFormView } from "../collections/CollectionFreeFormView"; @@ -14,14 +12,25 @@ import { CollectionSchemaView } from "../collections/CollectionSchemaView"; import { CollectionViewBase, COLLECTION_BORDER_WIDTH } from "../collections/CollectionViewBase"; import { FormattedTextBox } from "../nodes/FormattedTextBox"; import { ImageBox } from "../nodes/ImageBox"; -import "./NodeView.scss"; +import "./DocumentView.scss"; import React = require("react"); +import { Transform } from "../../util/Transform"; +import { SelectionManager } from "../../util/SelectionManager"; +import { DragManager } from "../../util/DragManager"; +import { ContextMenu } from "../ContextMenu"; +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 { - Document: Document; - DocumentView: Opt<DocumentView> // needed only to set ContainingDocumentView on CollectionViewProps when invoked from JsxParser -- is there a better way? ContainingCollectionView: Opt<CollectionViewBase>; + + Document: Document; + AddDocument?: (doc: Document) => void; + RemoveDocument?: (doc: Document) => boolean; + ScreenToLocalTransform: () => Transform; + isTopMost: boolean; + //tfs: This shouldn't be necessary I don't think + Scaling: number; } export interface JsxArgs extends DocumentViewProps { Keys: { [name: string]: Key } @@ -68,13 +77,27 @@ export function FakeJsxArgs(keys: string[], fields: string[] = []): JsxArgs { @observer export class DocumentView extends React.Component<DocumentViewProps> { - protected _mainCont = React.createRef<any>(); + private _mainCont = React.createRef<HTMLDivElement>(); 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("<p>Error loading layout data</p>")); + return this.props.Document.GetText(KeyStore.Layout, "<p>Error loading layout data</p>"); + } + + @computed + get backgroundLayout(): string | undefined { + let field = this.props.Document.GetT(KeyStore.BackgroundLayout, TextField); + if (field && field !== "<Waiting>") { + return field.Data; + } } @computed @@ -87,94 +110,164 @@ export class DocumentView extends React.Component<DocumentViewProps> { return this.props.Document.GetData(KeyStore.LayoutFields, ListField, new Array<Key>()); } - // - // returns the cumulative scaling between the document and the screen - // @computed - public get ScalingToScreenSpace(): number { - if (this.props.ContainingCollectionView != undefined && - this.props.ContainingCollectionView.props.DocumentViewForField != undefined) { - let ss = this.props.ContainingCollectionView.props.doc.GetData(KeyStore.Scale, NumberField, Number(1)); - return this.props.ContainingCollectionView.props.DocumentViewForField.ScalingToScreenSpace * ss; + 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); } - return 1; } - // - // Converts a coordinate in the screen space of the app into a local document coordinate. - // - public TransformToLocalPoint(screenX: number, screenY: number) { - // if this collection view is nested within another collection view, then - // first transform the screen point into the parent collection's coordinate space. - let { LocalX: parentX, LocalY: parentY } = this.props.ContainingCollectionView != undefined && - this.props.ContainingCollectionView.props.DocumentViewForField != undefined ? - this.props.ContainingCollectionView.props.DocumentViewForField.TransformToLocalPoint(screenX, screenY) : - { LocalX: screenX, LocalY: screenY }; - let ContainerX: number = parentX - COLLECTION_BORDER_WIDTH; - let ContainerY: number = parentY - COLLECTION_BORDER_WIDTH; - - var Xx = this.props.Document.GetData(KeyStore.X, NumberField, Number(0)); - var Yy = this.props.Document.GetData(KeyStore.Y, NumberField, Number(0)); - // CollectionDockingViews change the location of their children frames without using a Dash transformation. - // They also ignore any transformation that may have been applied to their content document. - // NOTE: this currently assumes CollectionDockingViews aren't nested. - if (this.props.ContainingCollectionView instanceof CollectionDockingView) { - var { translateX: rx, translateY: ry } = Utils.GetScreenTransform(this.MainContent.current!); - Xx = rx - COLLECTION_BORDER_WIDTH; - Yy = ry - COLLECTION_BORDER_WIDTH; - } - - let Ss = this.props.Document.GetData(KeyStore.Scale, NumberField, Number(1)); - let Panxx = this.props.Document.GetData(KeyStore.PanX, NumberField, Number(0)); - let Panyy = this.props.Document.GetData(KeyStore.PanY, NumberField, Number(0)); - let LocalX = (ContainerX - (Xx + Panxx)) / Ss; - let LocalY = (ContainerY - (Yy + Panyy)) / Ss; - - return { LocalX, Ss, Panxx, Xx, LocalY, Panyy, Yy, ContainerX, ContainerY }; + @action + dragComplete = (e: DragManager.DragCompleteEvent) => { } - // - // Converts a point in the coordinate space of a document to a screen space coordinate. - // - public TransformToScreenPoint(localX: number, localY: number, Ss: number = 1, Panxx: number = 0, Panyy: number = 0): { ScreenX: number, ScreenY: number } { + @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.ScreenToLocalTransform().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(); + } - var Xx = this.props.Document.GetData(KeyStore.X, NumberField, Number(0)); - var Yy = this.props.Document.GetData(KeyStore.Y, NumberField, Number(0)); - // CollectionDockingViews change the location of their children frames without using a Dash transformation. - // They also ignore any transformation that may have been applied to their content document. - // NOTE: this currently assumes CollectionDockingViews aren't nested. - if (this.props.ContainingCollectionView instanceof CollectionDockingView) { - var { translateX: rx, translateY: ry } = Utils.GetScreenTransform(this.MainContent.current!); - Xx = rx - COLLECTION_BORDER_WIDTH; - Yy = ry - COLLECTION_BORDER_WIDTH; + 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) + } - let W = COLLECTION_BORDER_WIDTH; - let H = COLLECTION_BORDER_WIDTH; - let parentX = (localX - W) * Ss + (Xx + Panxx) + W; - let parentY = (localY - H) * Ss + (Yy + Panyy) + H; + @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); + } + } - // if this collection view is nested within another collection view, then - // first transform the local point into the parent collection's coordinate space. - let containingDocView = this.props.ContainingCollectionView != undefined ? this.props.ContainingCollectionView.props.DocumentViewForField : undefined; - if (containingDocView != undefined) { - let ss = containingDocView.props.Document.GetData(KeyStore.Scale, NumberField, Number(1)); - let panxx = containingDocView.props.Document.GetData(KeyStore.PanX, NumberField, Number(0)) + COLLECTION_BORDER_WIDTH * ss; - let panyy = containingDocView.props.Document.GetData(KeyStore.PanY, NumberField, Number(0)) + COLLECTION_BORDER_WIDTH * ss; - let { ScreenX, ScreenY } = containingDocView.TransformToScreenPoint(parentX, parentY, ss, panxx, panyy); - parentX = ScreenX; - parentY = ScreenY; + // + // returns the cumulative scaling between the document and the screen + // tfs: I don't think this should be necessary + // + @computed + public get ScalingToScreenSpace(): number { + if (this.props.ContainingCollectionView != undefined && + this.props.ContainingCollectionView.props.ContainingDocumentView != undefined) { + let ss = this.props.ContainingCollectionView.props.Document.GetNumber(KeyStore.Scale, 1); + return this.props.ContainingCollectionView.props.ContainingDocumentView.ScalingToScreenSpace * ss; } - return { ScreenX: parentX, ScreenY: parentY }; + return 1; } + isSelected = () => { + return SelectionManager.IsSelected(this); + } + + select = (ctrlPressed: boolean) => { + SelectionManager.SelectDoc(this, ctrlPressed) + } render() { - let bindings = { ...this.props } as any; let lkeys = this.props.Document.GetT(KeyStore.LayoutKeys, ListField); if (!lkeys || lkeys === "<Waiting>") { return <p>Error loading layout keys</p>; } + 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 <keyname>Key to an actual key Kestore.keyname e.g, "DataKey" => KeyStore.Data } @@ -182,13 +275,36 @@ export class DocumentView extends React.Component<DocumentViewProps> { 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. + /* + 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 = () => (<JsxParser + components={{ FormattedTextBox, ImageBox, CollectionFreeFormView, CollectionDockingView, CollectionSchemaView }} + bindings={bindings} + jsx={this.backgroundLayout} + showWarnings={true} + onError={(test: any) => { console.log(test) }} + />); + bindings.BackgroundView = backgroundView; } + + bindings.DocumentView = this; + + 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 ( - <div className="node" ref={this._mainCont} style={{ width: "100%", height: "100%", }}> + <div className="documentView-node" ref={this._mainCont} style={{ width: strwidth, height: strheight, transformOrigin: "left top", transform: `scale(${this.props.Scaling},${this.props.Scaling})` }} + onContextMenu={this.onContextMenu} + onPointerDown={this.onPointerDown} > <JsxParser - components={{ FormattedTextBox: FormattedTextBox, ImageBox, CollectionFreeFormView, CollectionDockingView, CollectionSchemaView }} + components={{ FormattedTextBox, ImageBox, CollectionFreeFormView, CollectionDockingView, CollectionSchemaView }} bindings={bindings} jsx={this.layout} showWarnings={true} diff --git a/src/client/views/nodes/FieldView.tsx b/src/client/views/nodes/FieldView.tsx index fae124528..918acff4c 100644 --- a/src/client/views/nodes/FieldView.tsx +++ b/src/client/views/nodes/FieldView.tsx @@ -10,7 +10,6 @@ import { ImageField } from "../../../fields/ImageField"; import { Key } from "../../../fields/Key"; import { FormattedTextBox } from "./FormattedTextBox"; import { ImageBox } from "./ImageBox"; -import { DocumentView } from "./DocumentView"; // // these properties get assigned through the render() method of the DocumentView when it creates this node. @@ -20,12 +19,13 @@ import { DocumentView } from "./DocumentView"; export interface FieldViewProps { fieldKey: Key; doc: Document; - DocumentViewForField: Opt<DocumentView> + isSelected: () => boolean; + isTopMost: boolean; } @observer export class FieldView extends React.Component<FieldViewProps> { - public static LayoutString(fieldType: { name: string }) { return `<${fieldType.name} doc={Document} DocumentViewForField={DocumentView} fieldKey={DataKey} />`; } + public static LayoutString(fieldType: { name: string }) { return `<${fieldType.name} doc={Document} DocumentViewForField={DocumentView} fieldKey={DataKey} isSelected={isSelected} isTopMost={isTopMost} />`; } @computed get field(): FieldValue<Field> { const { doc, fieldKey } = this.props; diff --git a/src/client/views/nodes/FormattedTextBox.scss b/src/client/views/nodes/FormattedTextBox.scss index 492367fce..5139d5d6b 100644 --- a/src/client/views/nodes/FormattedTextBox.scss +++ b/src/client/views/nodes/FormattedTextBox.scss @@ -9,6 +9,6 @@ } .formattedTextBox-cont { - background: white; + background: beige; padding: 1vw; }
\ No newline at end of file diff --git a/src/client/views/nodes/FormattedTextBox.tsx b/src/client/views/nodes/FormattedTextBox.tsx index 39d7bf4f0..b17650d06 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"; @@ -13,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 @@ -31,7 +31,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<FieldViewProps> { public static LayoutString() { return FieldView.LayoutString(FormattedTextBox) } @@ -111,7 +110,7 @@ export class FormattedTextBox extends React.Component<FieldViewProps> { } 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(); } } @@ -119,7 +118,7 @@ export class FormattedTextBox extends React.Component<FieldViewProps> { return (<div className="formattedTextBox-cont" style={{ color: "initial", - whiteSpace: "initial" + whiteSpace: "initial", }} onPointerDown={this.onPointerDown} ref={this._ref} />) diff --git a/src/client/views/nodes/ImageBox.scss b/src/client/views/nodes/ImageBox.scss index 136fda1d0..36f5e0fe0 100644 --- a/src/client/views/nodes/ImageBox.scss +++ b/src/client/views/nodes/ImageBox.scss @@ -1,6 +1,14 @@ .imageBox-cont { padding: 0vw; + position: absolute; + width: 100%; + max-width: 100%; + max-height: 100% +} +.imageBox-cont img { + max-width: 100%; + max-height: 100% } .imageBox-button { diff --git a/src/client/views/nodes/ImageBox.tsx b/src/client/views/nodes/ImageBox.tsx index 013b8b7d3..b5ce8b28c 100644 --- a/src/client/views/nodes/ImageBox.tsx +++ b/src/client/views/nodes/ImageBox.tsx @@ -1,15 +1,14 @@ import Lightbox from 'react-image-lightbox'; import 'react-image-lightbox/style.css'; // This only needs to be imported once in your app -import { SelectionManager } from "../../util/SelectionManager"; import "./ImageBox.scss"; import React = require("react") import { ImageField } from '../../../fields/ImageField'; import { FieldViewProps, FieldView } from './FieldView'; -import { CollectionFreeFormDocumentView } from './CollectionFreeFormDocumentView'; import { FieldWaiting } from '../../../fields/Field'; import { observer } from "mobx-react" import { observable, action } from 'mobx'; +import { KeyStore } from '../../../fields/KeyStore'; @observer export class ImageBox extends React.Component<FieldViewProps> { @@ -40,7 +39,7 @@ export class ImageBox extends React.Component<FieldViewProps> { 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; @@ -62,12 +61,14 @@ export class ImageBox extends React.Component<FieldViewProps> { 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 (<Lightbox mainSrc={images[this._photoIndex]} nextSrc={images[(this._photoIndex + 1) % images.length]} prevSrc={images[(this._photoIndex + images.length - 1) % images.length]} - onCloseRequest={() => this.setState({ isOpen: false })} + onCloseRequest={action(() => + this._isOpen = false + )} onMovePrevRequest={action(() => this._photoIndex = (this._photoIndex + images.length - 1) % images.length )} @@ -82,10 +83,11 @@ export class ImageBox extends React.Component<FieldViewProps> { 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 ( <div className="imageBox-cont" onPointerDown={this.onPointerDown} ref={this._ref} > - <img src={path} width="100%" alt="Image not found" /> + <img src={path} width={nativeWidth} alt="Image not found" /> {this.lightbox(path)} </div>) } |
