diff options
author | yipstanley <stanley_yip@brown.edu> | 2019-01-19 21:55:30 -0500 |
---|---|---|
committer | yipstanley <stanley_yip@brown.edu> | 2019-01-19 21:55:30 -0500 |
commit | 08e2d1fd54824a1e8638a66ff031253ae72ab77b (patch) | |
tree | 83c690909b0835241f4b9d08082371e4e988f9a8 /src | |
parent | a0fadfc2017632dc17455ecf5fe7dd669834e887 (diff) |
resizing!
Diffstat (limited to 'src')
-rw-r--r-- | src/DocumentDecorations.scss | 18 | ||||
-rw-r--r-- | src/DocumentDecorations.tsx | 132 | ||||
-rw-r--r-- | src/views/freeformcanvas/CollectionFreeFormView.tsx | 8 | ||||
-rw-r--r-- | src/views/nodes/DocumentView.tsx | 36 |
4 files changed, 167 insertions, 27 deletions
diff --git a/src/DocumentDecorations.scss b/src/DocumentDecorations.scss index 8d2824b7e..fff4d201a 100644 --- a/src/DocumentDecorations.scss +++ b/src/DocumentDecorations.scss @@ -1,4 +1,4 @@ -.documentDecorations-container { +#documentDecorations-container { position: absolute; z-index: 1000; display: grid; @@ -15,4 +15,20 @@ pointer-events: auto; background: lightblue; opacity: 0.8; +} + +#documentDecorations-topLeftResizer, #documentDecorations-bottomRightResizer { + cursor: nwse-resize; +} + +#documentDecorations-topRightResizer, #documentDecorations-bottomLeftResizer { + cursor: nesw-resize; +} + +#documentDecorations-topResizer, #documentDecorations-bottomResizer { + cursor: ns-resize; +} + +#documentDecorations-leftResizer, #documentDecorations-rightResizer { + cursor: ew-resize; }
\ No newline at end of file diff --git a/src/DocumentDecorations.tsx b/src/DocumentDecorations.tsx index a83d5327b..d7466dcac 100644 --- a/src/DocumentDecorations.tsx +++ b/src/DocumentDecorations.tsx @@ -7,7 +7,13 @@ import './DocumentDecorations.scss' @observer export class DocumentDecorations extends React.Component { - @computed + static Instance: DocumentDecorations + constructor(props: Readonly<{}>) { + super(props) + + DocumentDecorations.Instance = this + } + get x(): number { let left = Number.MAX_VALUE; SelectionManager.SelectedDocuments().forEach(element => { @@ -18,7 +24,6 @@ export class DocumentDecorations extends React.Component { return left; } - @computed get y(): number { let top = Number.MAX_VALUE; SelectionManager.SelectedDocuments().forEach(element => { @@ -29,7 +34,6 @@ export class DocumentDecorations extends React.Component { return top; } - @computed get height(): number { return (SelectionManager.SelectedDocuments().reduce((bottom, element) => { if (element.mainCont.current !== null) { @@ -41,7 +45,6 @@ export class DocumentDecorations extends React.Component { }, Number.MIN_VALUE)) - this.y; } - @computed get width(): number { let right = Number.MIN_VALUE; SelectionManager.SelectedDocuments().forEach(element => { @@ -52,23 +55,122 @@ export class DocumentDecorations extends React.Component { return right - this.x; } + private _resizer = "" + private _isPointerDown = false; + @observable private _opacity = 1; + + @computed + get opacity(): number { + return this._opacity + } + + set opacity(o: number) { + this._opacity = Math.min(Math.max(0, o), 1) + } + + onPointerDown = (e: React.PointerEvent): void => { + e.stopPropagation(); + if (e.button === 0) { + this._isPointerDown = true; + this._resizer = e.currentTarget.id; + document.removeEventListener("pointermove", this.onPointerMove); + document.addEventListener("pointermove", this.onPointerMove); + document.removeEventListener("pointerup", this.onPointerUp); + document.addEventListener("pointerup", this.onPointerUp); + } + } + + onPointerMove = (e: PointerEvent): void => { + e.stopPropagation(); + e.preventDefault(); + if (!this._isPointerDown) { + return; + } + + let dX = 0, dY = 0, dW = 0, dH = 0; + + switch (this._resizer) { + case "": + break; + case "documentDecorations-topLeftResizer": + dX = -1 + dY = -1 + dW = -(e.movementX) + dH = -(e.movementY) + break; + case "documentDecorations-topRightResizer": + dW = e.movementX + dY = -1 + dH = -(e.movementY) + break; + case "documentDecorations-topResizer": + dY = -1 + dH = -(e.movementY) + break; + case "documentDecorations-bottomLeftResizer": + dX = -1 + dW = -(e.movementX) + dH = e.movementY + break; + case "documentDecorations-bottomRightResizer": + dW = e.movementX + dH = e.movementY + break; + case "documentDecorations-bottomResizer": + dH = e.movementY + break; + case "documentDecorations-leftResizer": + dX = -1 + dW = -(e.movementX) + break; + case "documentDecorations-rightResizer": + dW = e.movementX + break; + } + + SelectionManager.SelectedDocuments().forEach(element => { + if (element.mainCont.current !== null) { + let scale = element.width / element.mainCont.current.getBoundingClientRect().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.width = actualdW; + element.height = actualdH; + } + }) + + this.forceUpdate() + } + + onPointerUp = (e: PointerEvent): void => { + e.stopPropagation(); + if (e.button === 0) { + e.preventDefault(); + this._isPointerDown = false; + document.removeEventListener("pointermove", this.onPointerMove); + document.removeEventListener("pointerup", this.onPointerUp); + } + } + render() { - return( - <div className="documentDecorations-container" style={{ + return ( + <div id="documentDecorations-container" style={{ width: `${this.width + 40}px`, height: `${this.height + 40}px`, left: this.x - 20, - top: this.y - 20 + top: this.y - 20, + opacity: this.opacity }}> - <div id="documentDecorations-topLeftResizer" className="documentDecorations-resizer"></div> - <div id="documentDecorations-topResizer" className="documentDecorations-resizer"></div> - <div id="documentDecorations-topRightResizer" className="documentDecorations-resizer"></div> - <div id="documentDecorations-leftResizer" className="documentDecorations-resizer"></div> + <div id="documentDecorations-topLeftResizer" className="documentDecorations-resizer" onPointerDown={this.onPointerDown} onContextMenu={(e) => e.preventDefault()}></div> + <div id="documentDecorations-topResizer" className="documentDecorations-resizer" onPointerDown={this.onPointerDown} onContextMenu={(e) => e.preventDefault()}></div> + <div id="documentDecorations-topRightResizer" className="documentDecorations-resizer" onPointerDown={this.onPointerDown} onContextMenu={(e) => e.preventDefault()}></div> + <div id="documentDecorations-leftResizer" className="documentDecorations-resizer" onPointerDown={this.onPointerDown} onContextMenu={(e) => e.preventDefault()}></div> <div id="documentDecorations-centerCont"></div> - <div id="documentDecorations-rightResizer" className="documentDecorations-resizer"></div> - <div id="documentDecorations-bottomLeftResizer" className="documentDecorations-resizer"></div> - <div id="documentDecorations-bottomResizer" className="documentDecorations-resizer"></div> - <div id="documentDecorations-bottomRightResizer" className="documentDecorations-resizer"></div> + <div id="documentDecorations-rightResizer" className="documentDecorations-resizer" onPointerDown={this.onPointerDown} onContextMenu={(e) => e.preventDefault()}></div> + <div id="documentDecorations-bottomLeftResizer" className="documentDecorations-resizer" onPointerDown={this.onPointerDown} onContextMenu={(e) => e.preventDefault()}></div> + <div id="documentDecorations-bottomResizer" className="documentDecorations-resizer" onPointerDown={this.onPointerDown} onContextMenu={(e) => e.preventDefault()}></div> + <div id="documentDecorations-bottomRightResizer" className="documentDecorations-resizer" onPointerDown={this.onPointerDown} onContextMenu={(e) => e.preventDefault()}></div> </div> ) diff --git a/src/views/freeformcanvas/CollectionFreeFormView.tsx b/src/views/freeformcanvas/CollectionFreeFormView.tsx index 9a4f5ffa1..4e9e0cd21 100644 --- a/src/views/freeformcanvas/CollectionFreeFormView.tsx +++ b/src/views/freeformcanvas/CollectionFreeFormView.tsx @@ -9,6 +9,7 @@ import { DocumentView } from "../nodes/DocumentView"; import { ListField } from "../../fields/ListField"; import { NumberField } from "../../fields/NumberField"; import { SSL_OP_SINGLE_DH_USE } from "constants"; +import { DocumentDecorations } from "../../DocumentDecorations"; interface IProps { fieldKey: Key; @@ -60,14 +61,13 @@ export class CollectionFreeFormView extends React.Component<IProps> { } const { doc } = this.props; - // if docView is selected, pan, else dont pan - console.log(this.props.isSelected) - - let x = doc.GetFieldValue(KeyStore.PanX, NumberField, Number(0)); let y = doc.GetFieldValue(KeyStore.PanY, NumberField, Number(0)); doc.SetFieldValue(KeyStore.PanX, x + e.movementX, NumberField); doc.SetFieldValue(KeyStore.PanY, y + e.movementY, NumberField); + + + DocumentDecorations.Instance.forceUpdate() } @action diff --git a/src/views/nodes/DocumentView.tsx b/src/views/nodes/DocumentView.tsx index 5b0951f45..e37172943 100644 --- a/src/views/nodes/DocumentView.tsx +++ b/src/views/nodes/DocumentView.tsx @@ -11,6 +11,7 @@ import { FreeFormCanvas } from "../freeformcanvas/FreeFormCanvas" import { CollectionFreeFormView } from "../freeformcanvas/CollectionFreeFormView" import "./NodeView.scss" import { SelectionManager } from "../../util/SelectionManager"; +import { DocumentDecorations } from "../../DocumentDecorations"; const JsxParser = require('react-jsx-parser').default;//TODO Why does this need to be imported like this? interface IProps { @@ -53,11 +54,19 @@ export class DocumentView extends React.Component<IProps> { return this.props.dvm.Doc.GetFieldValue(KeyStore.Width, NumberField, Number(0)); } + set width(w: number) { + this.props.dvm.Doc.SetFieldValue(KeyStore.Width, w, NumberField) + } + @computed get height(): number { return this.props.dvm.Doc.GetFieldValue(KeyStore.Height, NumberField, Number(0)); } + set height(h: number) { + this.props.dvm.Doc.SetFieldValue(KeyStore.Height, h, NumberField) + } + @computed get layout(): string { return this.props.dvm.Doc.GetFieldValue(KeyStore.Layout, TextField, String("<p>Error loading layout data</p>")); @@ -99,6 +108,9 @@ export class DocumentView extends React.Component<IProps> { this._isPointerDown = false; document.removeEventListener("pointermove", this.onPointerMove); document.removeEventListener("pointerup", this.onPointerUp); + console.log(this.x); + console.log(this.y) + DocumentDecorations.Instance.opacity = 1 } } @@ -110,6 +122,14 @@ export class DocumentView extends React.Component<IProps> { } this.x += e.movementX; this.y += e.movementY; + DocumentDecorations.Instance.opacity = 0 + } + + onDragStart = (e: React.DragEvent<HTMLDivElement>): void => { + if (this.mainCont.current !== null) { + this.mainCont.current.style.opacity = "0"; + // e.dataTransfer.setDragImage() + } } render() { @@ -130,13 +150,15 @@ export class DocumentView extends React.Component<IProps> { return ( <div className="node" ref={this._mainCont} style={{ - transform: this.transform, - width: this.width, - height: this.height - }} onPointerDown={this.onPointerDown} onContextMenu={ - (e) => { - e.preventDefault() - }}> + transform: this.transform, + width: this.width, + height: this.height, + }} + onContextMenu={ + (e) => { + e.preventDefault() + }} + onPointerDown={this.onPointerDown}> <JsxParser components={{ FieldTextBox, FreeFormCanvas, CollectionFreeFormView }} bindings={bindings} |