aboutsummaryrefslogtreecommitdiff
path: root/src/client/views/DocumentDecorations.tsx
diff options
context:
space:
mode:
Diffstat (limited to 'src/client/views/DocumentDecorations.tsx')
-rw-r--r--src/client/views/DocumentDecorations.tsx169
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