diff options
Diffstat (limited to 'src/client/views/DocumentDecorations.tsx')
-rw-r--r-- | src/client/views/DocumentDecorations.tsx | 169 |
1 files changed, 169 insertions, 0 deletions
diff --git a/src/client/views/DocumentDecorations.tsx b/src/client/views/DocumentDecorations.tsx new file mode 100644 index 000000000..9fd73a33b --- /dev/null +++ b/src/client/views/DocumentDecorations.tsx @@ -0,0 +1,169 @@ +import { observable, computed } from "mobx"; +import React = require("react"); +import { SelectionManager } from "../util/SelectionManager"; +import { observer } from "mobx-react"; +import './DocumentDecorations.scss' +import { KeyStore } from '../../fields/KeyStore' +import { NumberField } from "../../fields/NumberField"; + +@observer +export class DocumentDecorations extends React.Component { + static Instance: DocumentDecorations + private _resizer = "" + private _isPointerDown = false; + @observable private _hidden = false; + + constructor(props: Readonly<{}>) { + super(props) + + DocumentDecorations.Instance = this + } + + @computed + get Bounds(): { x: number, y: number, b: number, r: number } { + return SelectionManager.SelectedDocuments().reduce((bounds, documentView) => { + if (documentView.props.isTopMost) { + return bounds; + } + let transform = (documentView.props.ScreenToLocalTransform().scale(documentView.props.ContentScaling())).inverse(); + var [sptX, sptY] = transform.transformPoint(0, 0); + let [bptX, bptY] = transform.transformPoint(documentView.props.PanelWidth(), documentView.props.PanelHeight()); + 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) + } + }, { x: Number.MAX_VALUE, y: Number.MAX_VALUE, r: Number.MIN_VALUE, b: Number.MIN_VALUE }); + } + + + @computed + public get Hidden() { return this._hidden; } + public set Hidden(value: boolean) { this._hidden = value; } + + 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 => { + const rect = element.screenRect(); + if (rect.width !== 0) { + let doc = element.props.Document; + let width = doc.GetNumber(KeyStore.Width, 0); + let nwidth = doc.GetNumber(KeyStore.NativeWidth, 0); + let nheight = doc.GetNumber(KeyStore.NativeHeight, 0); + let height = doc.GetNumber(KeyStore.Height, nwidth ? nheight / nwidth * width : 0); + let x = doc.GetOrCreate(KeyStore.X, NumberField); + let y = doc.GetOrCreate(KeyStore.Y, NumberField); + let scale = width / rect.width; + let actualdW = Math.max(width + (dW * scale), 20); + let actualdH = Math.max(height + (dH * scale), 20); + x.Data += dX * (actualdW - width); + y.Data += dY * (actualdH - height); + var nativeWidth = doc.GetNumber(KeyStore.NativeWidth, 0); + var nativeHeight = doc.GetNumber(KeyStore.NativeHeight, 0); + if (nativeWidth > 0 && nativeHeight > 0) { + if (Math.abs(dW) > Math.abs(dH)) + actualdH = nativeHeight / nativeWidth * actualdW; + else actualdW = nativeWidth / nativeHeight * actualdH; + } + doc.SetNumber(KeyStore.Width, actualdW); + doc.SetNumber(KeyStore.Height, actualdH); + } + }) + } + + 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() { + var bounds = this.Bounds; + if (this.Hidden) { + return (null); + } + if (isNaN(bounds.r) || isNaN(bounds.b) || isNaN(bounds.x) || isNaN(bounds.y)) { + console.log("DocumentDecorations: Bounds Error") + return (null); + } + return ( + <div id="documentDecorations-container" style={{ + width: (bounds.r - bounds.x + 40) + "px", + height: (bounds.b - bounds.y + 40) + "px", + left: bounds.x - 20, + top: bounds.y - 20, + }}> + <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" 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> + ) + } +}
\ No newline at end of file |