diff options
author | ab <abdullah_ahmed@brown.edu> | 2019-02-18 18:27:01 -0500 |
---|---|---|
committer | ab <abdullah_ahmed@brown.edu> | 2019-02-18 18:27:01 -0500 |
commit | c03e3fc75ef9ffb56cbfadb0c3164ead1fea4a40 (patch) | |
tree | 12b378c7bfd819aa7b22662281790ae61698daa7 | |
parent | 61aa3a0a34a647a7f414fbeb72345675a5154433 (diff) | |
parent | 3f98d6ec6050e7faa15179871f0d9669c1188a78 (diff) |
Merge branch 'master' of https://github.com/browngraphicslab/Dash-Web into decor
-rw-r--r-- | package-lock.json | 55 | ||||
-rw-r--r-- | package.json | 3 | ||||
-rw-r--r-- | src/client/views/DocumentDecorations.tsx | 5 | ||||
-rw-r--r-- | src/client/views/EditableView.tsx | 6 | ||||
-rw-r--r-- | src/client/views/Main.tsx | 7 | ||||
-rw-r--r-- | src/client/views/collections/CollectionDockingView.tsx | 110 | ||||
-rw-r--r-- | src/client/views/collections/CollectionFreeFormView.tsx | 21 | ||||
-rw-r--r-- | src/client/views/collections/CollectionSchemaView.scss | 59 | ||||
-rw-r--r-- | src/client/views/collections/CollectionSchemaView.tsx | 82 | ||||
-rw-r--r-- | src/client/views/collections/CollectionViewBase.tsx | 4 | ||||
-rw-r--r-- | src/client/views/nodes/CollectionFreeFormDocumentView.tsx | 51 | ||||
-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 | 149 | ||||
-rw-r--r-- | src/client/views/nodes/FormattedTextBox.scss | 2 | ||||
-rw-r--r-- | src/client/views/nodes/ImageBox.scss | 8 |
15 files changed, 355 insertions, 209 deletions
diff --git a/package-lock.json b/package-lock.json index 5af1aec8b..ddcc0a242 100644 --- a/package-lock.json +++ b/package-lock.json @@ -4,6 +4,14 @@ "lockfileVersion": 1, "requires": true, "dependencies": { + "@babel/runtime": { + "version": "7.3.1", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.3.1.tgz", + "integrity": "sha512-7jGW8ppV0ant637pIqAcFfQDDH1orEPGJb8aXfUozuCU3QqX7rX4DA8iwrbPrR1hcH0FTTHz47yQnk+bl5xHQA==", + "requires": { + "regenerator-runtime": "^0.12.0" + } + }, "@fortawesome/fontawesome-common-types": { "version": "0.2.14", "resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-common-types/-/fontawesome-common-types-0.2.14.tgz", @@ -208,6 +216,14 @@ "@types/react": "*" } }, + "@types/react-measure": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@types/react-measure/-/react-measure-2.0.4.tgz", + "integrity": "sha512-0puxiERCQ5Az4LyO+2r9bh6ECXTuy2PpsO+LY8ICezEi3YgIVaJwqRsplpNU18dZMqkpsdJlTB2cvSvkY0eR5Q==", + "requires": { + "@types/react": "*" + } + }, "@types/react-table": { "version": "6.7.21", "resolved": "https://registry.npmjs.org/@types/react-table/-/react-table-6.7.21.tgz", @@ -2145,6 +2161,11 @@ "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=" }, + "element-resize-event": { + "version": "2.0.9", + "resolved": "https://registry.npmjs.org/element-resize-event/-/element-resize-event-2.0.9.tgz", + "integrity": "sha1-L14VgaKW61J1IQwUG8VjQuIY+HY=" + }, "elliptic": { "version": "6.4.1", "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.4.1.tgz", @@ -3287,6 +3308,11 @@ "integrity": "sha1-6td0q+5y4gQJQzoGY2YCPdaIekE=", "dev": true }, + "get-node-dimensions": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/get-node-dimensions/-/get-node-dimensions-1.2.1.tgz", + "integrity": "sha512-2MSPMu7S1iOTL+BOa6K1S62hB2zUAYNF/lV0gSVlOaacd087lc6nR1H1r0e3B1CerTo+RceOmi1iJW+vp21xcQ==" + }, "get-stdin": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-4.0.1.tgz", @@ -8905,6 +8931,14 @@ "fast-deep-equal": "^2.0.1" } }, + "react-dimensions": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/react-dimensions/-/react-dimensions-1.3.1.tgz", + "integrity": "sha512-go5vMuGUxaB5PiTSIk+ZfAxLbHwcIgIfLhkBZ2SIMQjaCgnpttxa30z5ijEzfDjeOCTGRpxvkzcmE4Vt4Ppvyw==", + "requires": { + "element-resize-event": "^2.0.4" + } + }, "react-dom": { "version": "16.7.0", "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-16.7.0.tgz", @@ -8954,6 +8988,17 @@ "resolved": "https://registry.npmjs.org/react-lifecycles-compat/-/react-lifecycles-compat-3.0.4.tgz", "integrity": "sha512-fBASbA6LnOU9dOU2eW7aQ8xmYBSXUIWr+UmF9b1efZBazGNO+rcXT/icdKnYm2pTwcRylVUYwW7H1PHfLekVzA==" }, + "react-measure": { + "version": "2.2.4", + "resolved": "https://registry.npmjs.org/react-measure/-/react-measure-2.2.4.tgz", + "integrity": "sha512-gpZA4J8sKy1TzTfnOXiiTu01GV8B5OyfF9k7Owt38T6Xxlll19PBE13HKTtauEmDdJO5u4o3XcTiGqCw5wpfjw==", + "requires": { + "@babel/runtime": "^7.2.0", + "get-node-dimensions": "^1.2.1", + "prop-types": "^15.6.2", + "resize-observer-polyfill": "^1.5.0" + } + }, "react-modal": { "version": "3.8.1", "resolved": "https://registry.npmjs.org/react-modal/-/react-modal-3.8.1.tgz", @@ -9083,6 +9128,11 @@ "integrity": "sha512-1G6jJVDWrt0rK99kBjvEtziZNCICAuvIPkSiUFIQxVP06RCVpq3dmDo2oi6ABpYaDYaTRr67BEhL8r1wgEZZKg==", "dev": true }, + "regenerator-runtime": { + "version": "0.12.1", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.12.1.tgz", + "integrity": "sha512-odxIc1/vDlo4iZcfXqRYFj0vpXFNoGdKMAUieAlFYO6m/nl5e9KR/beGf41z4a1FI+aQgtjhuaSlDxQ0hmkrHg==" + }, "regex-not": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/regex-not/-/regex-not-1.0.2.tgz", @@ -9201,6 +9251,11 @@ "integrity": "sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8=", "dev": true }, + "resize-observer-polyfill": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/resize-observer-polyfill/-/resize-observer-polyfill-1.5.1.tgz", + "integrity": "sha512-LwZrotdHOo12nQuZlHEmtuXdqGoOD0OhaxopaNFxWzInpEgaLWoVuAMbTzixuosCx2nEG58ngzW3vxdWoxIgdg==" + }, "resolve-cwd": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-2.0.0.tgz", diff --git a/package.json b/package.json index 080f328c7..a227a52ac 100644 --- a/package.json +++ b/package.json @@ -43,6 +43,7 @@ "@types/prosemirror-state": "^1.2.1", "@types/prosemirror-transform": "^1.1.0", "@types/prosemirror-view": "^1.3.0", + "@types/react-measure": "^2.0.4", "@types/react-table": "^6.7.21", "@types/typescript": "^2.0.0", "@types/uuid": "^3.4.4", @@ -68,10 +69,12 @@ "prosemirror-view": "^1.7.1", "react": "^16.5.2", "react-contenteditable": "^3.2.6", + "react-dimensions": "^1.3.1", "react-dom": "^16.7.0", "react-golden-layout": "^1.0.6", "react-image-lightbox": "^5.1.0", "react-jsx-parser": "^1.13.0", + "react-measure": "^2.2.4", "react-mosaic": "0.0.20", "react-split-pane": "^0.1.85", "react-table": "^6.9.0", diff --git a/src/client/views/DocumentDecorations.tsx b/src/client/views/DocumentDecorations.tsx index 3e674e5ae..dcfedfcd1 100644 --- a/src/client/views/DocumentDecorations.tsx +++ b/src/client/views/DocumentDecorations.tsx @@ -5,6 +5,7 @@ import { observer } from "mobx-react"; import './DocumentDecorations.scss' import { CollectionFreeFormView } from "./collections/CollectionFreeFormView"; import ContentEditable from 'react-contenteditable' +import { KeyStore } from '../../fields/Key' @observer export class DocumentDecorations extends React.Component { @@ -115,8 +116,8 @@ export class DocumentDecorations extends React.Component { 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); + element.props.Document.SetNumber(KeyStore.X, element.props.Document.GetNumber(KeyStore.X, 0) + dX * (actualdW - element.width)); + element.props.Document.SetNumber(KeyStore.Y, element.props.Document.GetNumber(KeyStore.Y, 0) + dY * (actualdH - element.height)); if (Math.abs(dW) > Math.abs(dH)) element.width = actualdW; else diff --git a/src/client/views/EditableView.tsx b/src/client/views/EditableView.tsx index 2e784d3f9..3d1c2ebf4 100644 --- a/src/client/views/EditableView.tsx +++ b/src/client/views/EditableView.tsx @@ -6,6 +6,7 @@ export interface EditableProps { GetValue(): string; SetValue(value: string): boolean; contents: any; + height: number } @observer @@ -29,9 +30,10 @@ export class EditableView extends React.Component<EditableProps> { style={{ width: "100%" }}></input> } else { return ( - <div> + <div style={{ alignItems: "center", display: "flex", height: "100%", maxHeight: `${this.props.height}` }} + onClick={action(() => this.editing = true)} + > {this.props.contents} - <button onClick={action(() => this.editing = true)}>Edit</button> </div> ) } diff --git a/src/client/views/Main.tsx b/src/client/views/Main.tsx index b9f084b75..287fbc025 100644 --- a/src/client/views/Main.tsx +++ b/src/client/views/Main.tsx @@ -45,12 +45,13 @@ document.addEventListener("pointerdown", action(function (e: PointerEvent) { doc2.Set(KS.X, new NumberField(150)); doc2.Set(KS.Y, new NumberField(500)); let doc3 = Documents.ImageDocument("https://psmag.com/.image/t_share/MTMyNzc2NzM1MDY1MjgzMDM4/shutterstock_151341212jpg.jpg", { - x: 450, y: 100, title: "cat 1", width: 606, height: 386, nativeWidth: 606, nativeHeight: 386 + x: 450, y: 100, title: "dog", width: 606, height: 386, nativeWidth: 606, nativeHeight: 386 }); //doc3.Set(KeyStore.Data, new ImageField); const schemaDocs = Array.from(Array(5).keys()).map(v => Documents.ImageDocument("https://psmag.com/.image/t_share/MTMyNzc2NzM1MDY1MjgzMDM4/shutterstock_151341212jpg.jpg", { x: 50 + 100 * v, y: 50, width: 100, height: 100, title: "cat" + v, nativeWidth: 606, nativeHeight: 386 })); + schemaDocs.push(doc3); schemaDocs[0].SetData(KS.Author, "Tyler", TextField); schemaDocs[4].SetData(KS.Author, "Bob", TextField); schemaDocs.push(doc2); @@ -62,7 +63,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 = [doc3, doc1, doc2]; + let docset2 = [doc3, doc4, doc2]; let doc6 = Documents.CollectionDocument(docset2, { x: 350, y: 100, width: 600, height: 600, title: "docking collection" }); @@ -87,7 +88,7 @@ ReactDOM.render(( <div style={{ position: "absolute", width: "100%", height: "100%" }}> <DocumentView Document={mainContainer} AddDocument={undefined} RemoveDocument={undefined} GetTransform={() => Transform.Identity} - Scaling={1} + ParentScaling={1} ContainingCollectionView={undefined} DocumentView={undefined} /> <DocumentDecorations /> <ContextMenu /> diff --git a/src/client/views/collections/CollectionDockingView.tsx b/src/client/views/collections/CollectionDockingView.tsx index d3e90d11c..1653994cf 100644 --- a/src/client/views/collections/CollectionDockingView.tsx +++ b/src/client/views/collections/CollectionDockingView.tsx @@ -4,18 +4,17 @@ import 'golden-layout/src/css/goldenlayout-base.css'; import 'golden-layout/src/css/goldenlayout-dark-theme.css'; import { action, computed, reaction, observable } from "mobx"; import { observer } from "mobx-react"; -import * as ReactDOM from 'react-dom'; import { Document } from "../../../fields/Document"; import { KeyStore } from "../../../fields/Key"; import { ListField } from "../../../fields/ListField"; -import { NumberField } from "../../../fields/NumberField"; import { DragManager } from "../../util/DragManager"; import { Transform } from "../../util/Transform"; import { DocumentView } from "../nodes/DocumentView"; import "./CollectionDockingView.scss"; import { CollectionViewBase, CollectionViewProps, COLLECTION_BORDER_WIDTH } from "./CollectionViewBase"; import React = require("react"); -import { changeDependenciesStateTo0 } from "mobx/lib/internal"; +import * as ReactDOM from 'react-dom'; +import Measure from "react-measure"; @observer export class CollectionDockingView extends CollectionViewBase { @@ -67,7 +66,6 @@ export class CollectionDockingView extends CollectionViewBase { } private nextId = (function () { var _next_id = 0; return function () { return _next_id++; } })(); - @action onResize = (event: any) => { var cur = this.props.ContainingDocumentView!.MainContent.current; @@ -100,7 +98,7 @@ export class CollectionDockingView extends CollectionViewBase { return (<DocumentView key={value[i].Id} Document={value[i]} AddDocument={this.addDocument} RemoveDocument={this.removeDocument} GetTransform={() => Transform.Identity} - Scaling={1} + ParentScaling={1} ContainingCollectionView={this} DocumentView={undefined} />); } } @@ -111,7 +109,6 @@ export class CollectionDockingView extends CollectionViewBase { public static myLayout: any = null; - public rcs: Array<RenderClass> = new Array(); private static _dragDiv: any = null; private static _dragParent: HTMLElement | null = null; private static _dragElement: HTMLDivElement; @@ -241,10 +238,19 @@ export class CollectionDockingView extends CollectionViewBase { var containingDiv = "component_" + me.nextId(); container.getElement().html("<div id='" + containingDiv + "'></div>"); setTimeout(function () { - state.rc = new RenderClass(containingDiv, state.doc, me, container); - me.rcs.push(state.rc); - if (CollectionDockingView.myLayout._maxstack != null) { - CollectionDockingView.myLayout._maxstack.click(); + let divContainer = document.getElementById(containingDiv); + if (divContainer) { + let props: DockingProps = { + ContainingDiv: containingDiv, + Document: state.doc, + Container: container, + CollectionDockingView: me, + HtmlElement: divContainer + } + ReactDOM.render((<RenderClass {...props} />), divContainer); + if (CollectionDockingView.myLayout._maxstack) { + CollectionDockingView.myLayout._maxstack.click(); + } } }, 0); }); @@ -258,8 +264,8 @@ export class CollectionDockingView extends CollectionViewBase { const value: Document[] = Document.GetData(fieldKey, ListField, []); // bcz: not sure why, but I need these to force the flexlayout to update when the collection size changes. var s = this.props.ContainingDocumentView != undefined ? this.props.ContainingDocumentView!.ScalingToScreenSpace : 1; - var w = Document.GetData(KeyStore.Width, NumberField, Number(0)) / s; - var h = Document.GetData(KeyStore.Height, NumberField, Number(0)) / s; + var w = Document.GetNumber(KeyStore.Width, 0) / s; + var h = Document.GetNumber(KeyStore.Height, 0) / s; var chooseLayout = () => { if (!CollectionDockingView.UseGoldenLayout) @@ -267,56 +273,50 @@ export class CollectionDockingView extends CollectionViewBase { } return ( - <div className="border" style={{ - borderStyle: "solid", - borderWidth: `${COLLECTION_BORDER_WIDTH}px`, - }}> - <div className="collectiondockingview-container" id="menuContainer" onPointerDown={this.onPointerDown} onContextMenu={(e) => e.preventDefault()} ref={this._containerRef} - style={{ - width: CollectionDockingView.UseGoldenLayout || s > 1 ? "100%" : w - 2 * COLLECTION_BORDER_WIDTH, - height: CollectionDockingView.UseGoldenLayout || s > 1 ? "100%" : h - 2 * COLLECTION_BORDER_WIDTH - }} > - {chooseLayout()} - </div> + <div className="collectiondockingview-container" id="menuContainer" + onPointerDown={this.onPointerDown} onContextMenu={(e) => e.preventDefault()} ref={this._containerRef} + style={{ + width: CollectionDockingView.UseGoldenLayout || s > 1 ? "100%" : w - 2 * COLLECTION_BORDER_WIDTH, + height: CollectionDockingView.UseGoldenLayout || s > 1 ? "100%" : h - 2 * COLLECTION_BORDER_WIDTH, + borderStyle: "solid", + borderWidth: `${COLLECTION_BORDER_WIDTH}px`, + }} > + {chooseLayout()} </div> ); } } -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"; - } - })); +interface DockingProps { + ContainingDiv: string, + Document: Document, + Container: any, + HtmlElement: HTMLElement, + CollectionDockingView: CollectionDockingView +} +@observer +export class RenderClass extends React.Component<DockingProps> { + @observable + private _parentScaling = 1; // used to transfer the dimensions of the content pane in the DOM to the ParentScaling prop of the DocumentView - this.render(); - } render() { - var nativeWidth = this._document.GetNumber(KeyStore.NativeWidth, 0); - let scaling = nativeWidth > 0 ? this._htmlElement!.clientWidth / nativeWidth : 1; - ReactDOM.render(( - <DocumentView key={this._document.Id} Document={this._document} - AddDocument={this._collectionDockingView.addDocument} RemoveDocument={this._collectionDockingView.removeDocument} + let nativeWidth = this.props.Document.GetNumber(KeyStore.NativeWidth, 0); + var layout = this.props.Document.GetText(KeyStore.Layout, ""); + var content = + <DocumentView key={this.props.Document.Id} Document={this.props.Document} + AddDocument={this.props.CollectionDockingView.addDocument} + RemoveDocument={this.props.CollectionDockingView.removeDocument} GetTransform={() => Transform.Identity} - Scaling={scaling} - ContainingCollectionView={this._collectionDockingView} DocumentView={undefined} /> - ), - this._htmlElement - ); + ParentScaling={this._parentScaling} + ContainingCollectionView={this.props.CollectionDockingView} DocumentView={undefined} /> + + if (nativeWidth > 0 && (layout.indexOf("CollectionFreeForm") == -1 || layout.indexOf("AnnotationsKey") != -1)) { + return <Measure onResize={ + action((r: any) => this._parentScaling = nativeWidth > 0 ? r.entry.width / nativeWidth : 1)} + > + {({ measureRef }) => <div ref={measureRef}> {content} </div>} + </Measure> + } + return <div> {content} </div> } }
\ No newline at end of file diff --git a/src/client/views/collections/CollectionFreeFormView.tsx b/src/client/views/collections/CollectionFreeFormView.tsx index 15450d737..04373df12 100644 --- a/src/client/views/collections/CollectionFreeFormView.tsx +++ b/src/client/views/collections/CollectionFreeFormView.tsx @@ -58,8 +58,8 @@ export class CollectionFreeFormView extends CollectionViewBase { 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; + doc.props.Document.SetNumber(KeyStore.X, (screenX - translateX) / currScale); + doc.props.Document.SetNumber(KeyStore.Y, (screenY - translateY) / currScale); this.bringToFront(doc); } e.stopPropagation(); @@ -124,9 +124,10 @@ 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 { LocalX, Ss, Panxx, Xx, LocalY, Panyy, Yy, ContainerX, ContainerY } = this.props.ContainingDocumentView!.TransformToLocalPoint(e.pageX, e.pageY); - - var deltaScale = (1 - (e.deltaY / coefficient)) * Ss; + let { LocalX, LocalY, ContainerX, ContainerY } = this.props.ContainingDocumentView!.TransformToLocalPoint(e.pageX, e.pageY); + var Xx = this.props.ContainingDocumentView!.LeftCorner(); + var Yy = this.props.ContainingDocumentView!.TopCorner(); + var deltaScale = (1 - (e.deltaY / coefficient)) * this.props.ContainingDocumentView!.props.Document.GetNumber(KeyStore.Scale, 1); var newDeltaScale = this.isAnnotationOverlay ? Math.max(1, deltaScale) : deltaScale; this.props.DocumentForCollection.SetNumber(KeyStore.Scale, newDeltaScale); @@ -135,8 +136,8 @@ export class CollectionFreeFormView extends CollectionViewBase { @action private SetPan(panX: number, panY: number) { - const newPanX = Math.max(-(this.resizeScaling * this.zoomScaling - this.resizeScaling) * this.nativeWidth, Math.min(0, panX)); - const newPanY = Math.max(-(this.resizeScaling * this.zoomScaling - this.resizeScaling) * this.nativeHeight, Math.min(0, panY)); + const newPanX = Math.max((1 - this.zoomScaling) * this.nativeWidth, Math.min(0, panX)); + const newPanY = Math.max((1 - this.zoomScaling) * this.nativeHeight, Math.min(0, panY)); this.props.DocumentForCollection.SetNumber(KeyStore.PanX, this.isAnnotationOverlay ? newPanX : panX); this.props.DocumentForCollection.SetNumber(KeyStore.PanY, this.isAnnotationOverlay ? newPanY : panY); } @@ -148,8 +149,8 @@ export class CollectionFreeFormView extends CollectionViewBase { let fReader = new FileReader() let file = e.dataTransfer.items[0].getAsFile(); let that = this; - const panx: number = this.props.DocumentForCollection.GetData(KeyStore.PanX, NumberField, Number(0)); - const pany: number = this.props.DocumentForCollection.GetData(KeyStore.PanY, NumberField, Number(0)); + const panx: number = this.props.DocumentForCollection.GetNumber(KeyStore.PanX, 0); + const pany: number = this.props.DocumentForCollection.GetNumber(KeyStore.PanY, 0); let x = e.pageX - panx let y = e.pageY - pany @@ -241,7 +242,7 @@ export class CollectionFreeFormView extends CollectionViewBase { AddDocument={this.addDocument} RemoveDocument={this.removeDocument} GetTransform={this.getTransform} - Scaling={1} + ParentScaling={1} ContainingCollectionView={this} DocumentView={undefined} />); })} </div> diff --git a/src/client/views/collections/CollectionSchemaView.scss b/src/client/views/collections/CollectionSchemaView.scss index 707b44db6..633e3ca1b 100644 --- a/src/client/views/collections/CollectionSchemaView.scss +++ b/src/client/views/collections/CollectionSchemaView.scss @@ -1,3 +1,62 @@ + +.collectionSchemaView-container { + border-style: solid; + box-sizing: border-box; + position: absolute; + width: 100%; + height: 100%; + .collectionfreeformview-container { + border-width: 0px; + .collectionfreeformview > .jsx-parser{ + position:absolute + } + } + .imageBox-cont { + position:relative; + max-height:100%; + } + .ReactTable { + position: absolute; + display: inline-block; + width: 100%; + overflow: auto; + height: 100%; + background: white; + box-sizing: border-box; + } + .ReactTable .rt-thead.-header { + background:grey; + } + .ReactTable .rt-th, .ReactTable .rt-td { + max-height: 75px; + } + .ReactTable .rt-tbody .rt-tr-group:last-child { + border-bottom: grey; + border-bottom-style: solid; + border-bottom-width: 1; + } + .ReactTable .rt-td { + border-width: 1; + border-right-color: #aaa + } + .ReactTable .rt-tr-group { + border-width: 1; + border-bottom-color: #aaa + } + .imageBox-cont img { + object-fit: contain; + height: 100% + } + .documentView-node:first-child { + background: grey; + .imageBox-cont img { + object-fit: contain; + max-width: 100%; + height: 100% + } + } +} + .Resizer { box-sizing: border-box; background: #000; diff --git a/src/client/views/collections/CollectionSchemaView.tsx b/src/client/views/collections/CollectionSchemaView.tsx index f1e882e20..76706f520 100644 --- a/src/client/views/collections/CollectionSchemaView.tsx +++ b/src/client/views/collections/CollectionSchemaView.tsx @@ -7,14 +7,15 @@ import { observable, action, computed } from "mobx"; import SplitPane from "react-split-pane" import "./CollectionSchemaView.scss" import { ScrollBox } from "../../util/ScrollBox"; -import { CollectionViewBase } from "./CollectionViewBase"; +import { CollectionViewBase, COLLECTION_BORDER_WIDTH } from "./CollectionViewBase"; import { DocumentView } from "../nodes/DocumentView"; import { EditableView } from "../EditableView"; import { CompileScript, ToField } from "../../util/Scripting"; -import { KeyStore as KS, Key } from "../../../fields/Key"; +import { KeyStore as KS, Key, KeyStore } from "../../../fields/Key"; import { Document } from "../../../fields/Document"; import { Field } from "../../../fields/Field"; import { Transform } from "../../util/Transform"; +import Measure from "react-measure"; @observer export class CollectionSchemaView extends CollectionViewBase { @@ -33,7 +34,7 @@ export class CollectionSchemaView extends CollectionViewBase { <FieldView {...props} /> ) return ( - <EditableView contents={contents} GetValue={() => { + <EditableView contents={contents} height={36} GetValue={() => { let field = props.doc.Get(props.fieldKey); if (field && field instanceof Field) { return field.ToScriptString(); @@ -98,51 +99,62 @@ export class CollectionSchemaView extends CollectionViewBase { } } + + @observable + private _parentScaling = 1; // used to transfer the dimensions of the content pane in the DOM to the ParentScaling prop of the DocumentView render() { const { DocumentForCollection: Document, CollectionFieldKey: fieldKey } = this.props; const children = Document.GetList<Document>(fieldKey, []); const columns = Document.GetList(KS.ColumnsKey, [KS.Title, KS.Data, KS.Author]) let content; + var me = this; if (this.selectedIndex != -1) { content = ( - <DocumentView Document={children[this.selectedIndex]} - AddDocument={this.addDocument} RemoveDocument={this.removeDocument} - GetTransform={() => Transform.Identity}//TODO This should probably be an actual transform - Scaling={1} - DocumentView={undefined} ContainingCollectionView={this} /> + <Measure onResize={action((r: any) => { + var doc = children[this.selectedIndex]; + var n = doc.GetNumber(KeyStore.NativeWidth, 0); + if (n > 0 && r.entry.width > 0) { + this._parentScaling = r.entry.width / n; + } + })}> + {({ measureRef }) => + <div ref={measureRef}> + <DocumentView Document={children[this.selectedIndex]} + AddDocument={this.addDocument} RemoveDocument={this.removeDocument} + GetTransform={() => Transform.Identity}//TODO This should probably be an actual transform + ParentScaling={this._parentScaling} + DocumentView={undefined} ContainingCollectionView={me} /> + </div> + } + </Measure> ) } else { content = <div /> } return ( - <div onPointerDown={this.onPointerDown} > - <SplitPane split={"vertical"} defaultSize="60%"> - <ScrollBox> - <ReactTable - data={children} - pageSize={children.length} - page={0} - showPagination={false} - style={{ - display: "inline-block", - width: "100%" - }} - columns={columns.map(col => { - return ( - { - Header: col.Name, - accessor: (doc: Document) => [doc, col], - id: col.Id - }) - })} - column={{ - ...ReactTableDefaults.column, - Cell: this.renderCell - }} - getTrProps={this.getTrProps} - /> - </ScrollBox> + <div onPointerDown={this.onPointerDown} className="collectionSchemaView-container" + style={{ borderWidth: `${COLLECTION_BORDER_WIDTH}px`, }} > + <SplitPane split={"vertical"} defaultSize="60%" style={{ height: "100%", position: "relative", overflow: "none" }}> + <ReactTable + data={children} + pageSize={children.length} + page={0} + showPagination={false} + columns={columns.map(col => { + return ( + { + Header: col.Name, + accessor: (doc: Document) => [doc, col], + id: col.Id + }) + })} + column={{ + ...ReactTableDefaults.column, + Cell: this.renderCell + }} + getTrProps={this.getTrProps} + /> {content} </SplitPane> </div> diff --git a/src/client/views/collections/CollectionViewBase.tsx b/src/client/views/collections/CollectionViewBase.tsx index 7e2fcb39d..1cf07ce05 100644 --- a/src/client/views/collections/CollectionViewBase.tsx +++ b/src/client/views/collections/CollectionViewBase.tsx @@ -19,7 +19,7 @@ export interface CollectionViewProps { ContainingDocumentView: Opt<DocumentView>; GetTransform: () => Transform; BackgroundView: Opt<DocumentView>; - Scaling: number; + ParentScaling: number; } export const COLLECTION_BORDER_WIDTH = 2; @@ -28,7 +28,7 @@ export const COLLECTION_BORDER_WIDTH = 2; export class CollectionViewBase extends React.Component<CollectionViewProps> { public static LayoutString(collectionType: string, fieldKey: string = "DataKey") { - return `<${collectionType} Scaling={Scaling} DocumentForCollection={Document} CollectionFieldKey={${fieldKey}} ContainingDocumentView={DocumentView} BackgroundView={BackgroundView} />`; + return `<${collectionType} ParentScaling={ParentScaling} 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 9cd42a069..a2fbe96d2 100644 --- a/src/client/views/nodes/CollectionFreeFormDocumentView.tsx +++ b/src/client/views/nodes/CollectionFreeFormDocumentView.tsx @@ -7,7 +7,7 @@ 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 { Transform } from "../../util/Transform"; @@ -30,27 +30,17 @@ export class CollectionFreeFormDocumentView extends DocumentView { return new DOMRect(); } - @computed - get x(): number { - return this.props.Document.GetData(KeyStore.X, NumberField, Number(0)); - } - - @computed - get y(): number { - return this.props.Document.GetData(KeyStore.Y, NumberField, Number(0)); + public LeftCorner(): number { + return this.props.Document.GetNumber(KeyStore.X, 0) + super.LeftCorner(); } - set x(x: number) { - this.props.Document.SetData(KeyStore.X, x, NumberField) - } - - set y(y: number) { - this.props.Document.SetData(KeyStore.Y, y, NumberField) + public TopCorner(): number { + return this.props.Document.GetNumber(KeyStore.Y, 0) + super.TopCorner(); } @computed get transform(): string { - return `scale(${this.props.Scaling}, ${this.props.Scaling}) translate(${this.x}px, ${this.y}px)`; + return `scale(${this.props.ParentScaling}, ${this.props.ParentScaling}) translate(${this.props.Document.GetNumber(KeyStore.X, 0)}px, ${this.props.Document.GetNumber(KeyStore.Y, 0)}px)`; } @computed @@ -88,7 +78,7 @@ export class CollectionFreeFormDocumentView extends DocumentView { @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) { @@ -221,24 +211,25 @@ export class CollectionFreeFormDocumentView extends DocumentView { } getTransform = (): Transform => { - return this.props.GetTransform().translated(this.x, this.y); + return this.props.GetTransform().translated(this.props.Document.GetNumber(KeyStore.X, 0), this.props.Document.GetNumber(KeyStore.Y, 0)); } render() { - var freestyling = this.props.ContainingCollectionView instanceof CollectionFreeFormView; + var parentScaling = this.nativeWidth > 0 ? this.width / this.nativeWidth : 1; return ( - <div className="node" ref={this._mainCont} style={{ - transformOrigin: "left top", - transform: freestyling ? this.transform : "", - width: freestyling ? this.width : "100%", - height: freestyling ? this.height : "100%", - position: freestyling ? "absolute" : "relative", - zIndex: freestyling ? this.zIndex : 0, - }} + <div className="documentView-node" ref={this._mainCont} onContextMenu={this.onContextMenu} - onPointerDown={this.onPointerDown}> - - <DocumentView {...this.props} Scaling={this.width / this.nativeWidth} GetTransform={this.getTransform} DocumentView={this} /> + onPointerDown={this.onPointerDown} + style={{ + transformOrigin: "left top", + transform: this.transform, + width: this.width, + height: this.height, + position: "absolute", + zIndex: this.zIndex, + }}> + + <DocumentView {...this.props} ref={this._renderDoc} ParentScaling={parentScaling} GetTransform={this.getTransform} DocumentView={this} /> </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 3a73f2fde..c5270e0cd 100644 --- a/src/client/views/nodes/DocumentView.tsx +++ b/src/client/views/nodes/DocumentView.tsx @@ -4,8 +4,6 @@ import { Document } from "../../../fields/Document"; import { Opt, FieldWaiting } from "../../../fields/Field"; import { Key, KeyStore } from "../../../fields/Key"; import { ListField } from "../../../fields/ListField"; -import { NumberField } from "../../../fields/NumberField"; -import { TextField } from "../../../fields/TextField"; import { Utils } from "../../../Utils"; import { CollectionDockingView } from "../collections/CollectionDockingView"; import { CollectionFreeFormView } from "../collections/CollectionFreeFormView"; @@ -13,7 +11,7 @@ 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"; const JsxParser = require('react-jsx-parser').default;//TODO Why does this need to be imported like this? @@ -26,24 +24,31 @@ export interface DocumentViewProps { AddDocument?: (doc: Document) => void; RemoveDocument?: (doc: Document) => boolean; GetTransform: () => Transform; - Scaling: number; + ParentScaling: number; } @observer export class DocumentView extends React.Component<DocumentViewProps> { + protected _renderDoc = React.createRef<any>(); protected _mainCont = React.createRef<any>(); get MainContent() { return this._mainCont; } + + @computed + get parentScaling(): number { + return this._renderDoc.current ? this._renderDoc.current.props.ParentScaling : this.props.ParentScaling > 0 ? this.props.ParentScaling : 1; + } + @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 { - return this.props.Document.GetData(KeyStore.BackgroundLayout, TextField, String("<p>Error loading layout data</p>")); + return this.props.Document.GetText(KeyStore.BackgroundLayout, ""); } @computed @@ -69,75 +74,78 @@ export class DocumentView extends React.Component<DocumentViewProps> { return 1; } + + public LeftCorner(): number { + if (this.props.ContainingCollectionView) { + if (this.props.ContainingCollectionView instanceof CollectionDockingView) { + // this is a hacky way to account for the titles/pane placement/etc of a CollectionDockingView + // this only works if the collectionDockingView is the root collection, too. + // need to find a better way. + var { translateX: rx, translateY: ry } = Utils.GetScreenTransform(this.MainContent.current!); + return rx + COLLECTION_BORDER_WIDTH; + } + return COLLECTION_BORDER_WIDTH; // assumes all collections have the same border + } + return 0; + } + + public TopCorner(): number { + if (this.props.ContainingCollectionView) { + if (this.props.ContainingCollectionView instanceof CollectionDockingView) { + // this is a hacky way to account for the titles/pane placement/etc of a CollectionDockingView + // this only works if the collectionDockingView is the root collection, too. + // need to find a better way. + var { translateX: rx, translateY: ry } = Utils.GetScreenTransform(this.MainContent.current!); + return ry + COLLECTION_BORDER_WIDTH; + } + return COLLECTION_BORDER_WIDTH; // assumes all collections have the same border + } + return 0; + } // - // Converts a coordinate in the screen space of the app into a local document coordinate. + // Converts a coordinate in the screen space of the app to a local point in the space of the DocumentView. + // This also returns the point in the coordinate space of this document's containing CollectionView // public TransformToLocalPoint(screenX: number, screenY: number) { // if this collection view is nested within another collection view, then // first transform the screen point into the parent collection's coordinate space. - let { LocalX: parentX, LocalY: parentY } = this.props.ContainingCollectionView != undefined && - this.props.ContainingCollectionView.props.ContainingDocumentView != undefined ? - this.props.ContainingCollectionView.props.ContainingDocumentView.TransformToLocalPoint(screenX, screenY) : - { LocalX: screenX, LocalY: screenY }; + let containingCollectionViewDoc = this.props.ContainingCollectionView ? this.props.ContainingCollectionView.props.ContainingDocumentView : undefined; + let { LocalX: parentX, LocalY: parentY } = !containingCollectionViewDoc ? { LocalX: screenX, LocalY: screenY } : + containingCollectionViewDoc.TransformToLocalPoint(screenX, 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.GetNumber(KeyStore.Scale, 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; + let Panxx = this.props.Document.GetNumber(KeyStore.PanX, 0); + let Panyy = this.props.Document.GetNumber(KeyStore.PanY, 0); + let LocalX = (ContainerX - (this.LeftCorner() + Panxx)) / Ss; + let LocalY = (ContainerY - (this.TopCorner() + Panyy)) / Ss; - return { LocalX, Ss, Panxx, Xx, LocalY, Panyy, Yy, ContainerX, ContainerY }; + return { LocalX, LocalY, ContainerX, ContainerY }; } // - // Converts a point in the coordinate space of a document to a screen space coordinate. + // Converts a point in the coordinate space of the document to coordinate in app screen coordinates // - public TransformToScreenPoint(localX: number, localY: number, Ss: number = 1, Panxx: number = 0, Panyy: number = 0): { ScreenX: number, ScreenY: number } { - - var Xx = this.props.Document.GetData(KeyStore.X, NumberField, Number(0)); - var Yy = this.props.Document.GetData(KeyStore.Y, NumberField, Number(0)); - // CollectionDockingViews change the location of their children frames without using a Dash transformation. - // They also ignore any transformation that may have been applied to their content document. - // NOTE: this currently assumes CollectionDockingViews aren't nested. - if (this.props.ContainingCollectionView instanceof CollectionDockingView) { - var { translateX: rx, translateY: ry } = Utils.GetScreenTransform(this.MainContent.current!); - Xx = rx - COLLECTION_BORDER_WIDTH; - Yy = ry - COLLECTION_BORDER_WIDTH + 18 * Ss; - } - - 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; - + public TransformToScreenPoint(localX: number, localY: number, applyViewXf: boolean = false): { ScreenX: number, ScreenY: number } { + var parentScaling = applyViewXf ? this.parentScaling : 1; + let Panxx = applyViewXf ? this.props.Document.GetNumber(KeyStore.PanX, 0) : 0; + let Panyy = applyViewXf ? this.props.Document.GetNumber(KeyStore.PanY, 0) : 0; + var Zoom = applyViewXf ? this.props.Document.GetNumber(KeyStore.Scale, 1) : 1; + + let parentX = this.LeftCorner() + (Panxx + (localX - COLLECTION_BORDER_WIDTH) * Zoom) * parentScaling; + let parentY = this.TopCorner() + (Panyy + (localY - COLLECTION_BORDER_WIDTH) * Zoom) * parentScaling; // if this collection view is nested within another collection view, then // first transform the local point into the parent collection's coordinate space. - let containingDocView = this.props.ContainingCollectionView != undefined ? this.props.ContainingCollectionView.props.ContainingDocumentView : undefined; - if (containingDocView != undefined) { - let ss = containingDocView.props.Document.GetNumber(KeyStore.Scale, 1) * this.props.Scaling; - 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); + let containingDocView = this.props.ContainingCollectionView ? this.props.ContainingCollectionView.props.ContainingDocumentView : undefined; + if (containingDocView) { + let { ScreenX, ScreenY } = containingDocView.TransformToScreenPoint(parentX + COLLECTION_BORDER_WIDTH * parentScaling, parentY + COLLECTION_BORDER_WIDTH * parentScaling, true); parentX = ScreenX; parentY = ScreenY; } return { ScreenX: parentX, ScreenY: parentY }; } - render() { let bindings = { ...this.props } as any; for (const key of this.layoutKeys) { @@ -150,21 +158,28 @@ export class DocumentView extends React.Component<DocumentViewProps> { 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. } - var annotated = <JsxParser - components={{ FormattedTextBox: FormattedTextBox, ImageBox, CollectionFreeFormView, CollectionDockingView, CollectionSchemaView }} - bindings={bindings} - jsx={this.backgroundLayout} - showWarnings={true} - 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%"; + if (this.backgroundLayout) { + var backgroundview = <JsxParser + components={{ FormattedTextBox: FormattedTextBox, ImageBox, CollectionFreeFormView, CollectionDockingView, CollectionSchemaView }} + bindings={bindings} + jsx={this.backgroundLayout} + showWarnings={true} + onError={(test: any) => { console.log(test) }} + />; + bindings["BackgroundView"] = backgroundview; + } + var nativewidth = this.props.Document.GetNumber(KeyStore.NativeWidth, 0); + var nativeheight = this.props.Document.GetNumber(KeyStore.NativeHeight, 0); + var width = nativewidth > 0 ? nativewidth + "px" : "100%"; + var height = nativeheight > 0 ? nativeheight + "px" : "100%"; return ( - <div className="node" ref={this._mainCont} style={{ width: strwidth, height: strheight, transformOrigin: "left top", transform: `scale(${this.props.Scaling},${this.props.Scaling})` }}> + <div className="documentView-node" ref={this._mainCont} + style={{ + width: width, + height: height, + transformOrigin: "top left", + transform: `scale(${this.props.ParentScaling},${this.props.ParentScaling})` + }}> <JsxParser components={{ FormattedTextBox: FormattedTextBox, ImageBox, CollectionFreeFormView, CollectionDockingView, CollectionSchemaView }} bindings={bindings} 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/ImageBox.scss b/src/client/views/nodes/ImageBox.scss index 2bd8b1d3c..36f5e0fe0 100644 --- a/src/client/views/nodes/ImageBox.scss +++ b/src/client/views/nodes/ImageBox.scss @@ -2,7 +2,13 @@ .imageBox-cont { padding: 0vw; position: absolute; - width: 100% + width: 100%; + max-width: 100%; + max-height: 100% +} +.imageBox-cont img { + max-width: 100%; + max-height: 100% } .imageBox-button { |