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.tsx74
1 files changed, 41 insertions, 33 deletions
diff --git a/src/client/views/DocumentDecorations.tsx b/src/client/views/DocumentDecorations.tsx
index b4c19df2d..6ef3fcc66 100644
--- a/src/client/views/DocumentDecorations.tsx
+++ b/src/client/views/DocumentDecorations.tsx
@@ -1,7 +1,7 @@
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { Tooltip } from '@mui/material';
import { IconButton } from 'browndash-components';
-import { action, computed, observable, runInAction } from 'mobx';
+import { action, computed, makeObservable, observable, runInAction } from 'mobx';
import { observer } from 'mobx-react';
import { FaUndo } from 'react-icons/fa';
import { DateField } from '../../fields/DateField';
@@ -34,10 +34,15 @@ import { DocumentView, OpenWhereMod } from './nodes/DocumentView';
import { FormattedTextBox } from './nodes/formattedText/FormattedTextBox';
import { ImageBox } from './nodes/ImageBox';
import * as React from 'react';
-import * as _ from 'lodash';
+interface DocumentDecorationsProps {
+ PanelWidth: number;
+ PanelHeight: number;
+ boundsLeft: number;
+ boundsTop: number;
+}
@observer
-export class DocumentDecorations extends React.Component<{ PanelWidth: number; PanelHeight: number; boundsLeft: number; boundsTop: number }, { value: string }> {
+export class DocumentDecorations extends React.Component<DocumentDecorationsProps> {
static Instance: DocumentDecorations;
private _resizeHdlId = '';
private _keyinput = React.createRef<HTMLInputElement>();
@@ -61,8 +66,11 @@ export class DocumentDecorations extends React.Component<{ PanelWidth: number; P
@observable private _showRotCenter = false; // whether to show a draggable green dot that represents the center of rotation
@observable private _rotCenter = [0, 0]; // the center of rotation in object coordinates (0,0) = object center (not top left!)
- constructor(props: any) {
+ @observable _props: React.PropsWithChildren<DocumentDecorationsProps>;
+ constructor(props: React.PropsWithChildren<DocumentDecorationsProps>) {
super(props);
+ this._props = props;
+ makeObservable(this);
DocumentDecorations.Instance = this;
document.addEventListener('pointermove', // show decorations whenever pointer moves outside of selection bounds.
action(e => {
@@ -78,8 +86,8 @@ export class DocumentDecorations extends React.Component<{ PanelWidth: number; P
@computed get ClippedBounds() {
const bounds = this.Bounds;
- const leftBounds = this.props.boundsLeft;
- const topBounds = LightboxView.LightboxDoc ? 0 : this.props.boundsTop;
+ const leftBounds = this._props.boundsLeft;
+ const topBounds = LightboxView.LightboxDoc ? 0 : this._props.boundsTop;
bounds.x = Math.max(leftBounds, bounds.x - this._resizeBorderWidth / 2) + this._resizeBorderWidth / 2;
bounds.y = Math.max(topBounds, bounds.y - this._resizeBorderWidth / 2 - this._titleHeight) + this._resizeBorderWidth / 2 + this._titleHeight;
const borderRadiusDraggerWidth = 15;
@@ -92,7 +100,7 @@ export class DocumentDecorations extends React.Component<{ PanelWidth: number; P
return (LinkFollower.IsFollowing || DocumentView.ExploreMode) ?
{ x: 0, y: 0, r: 0, b: 0 }
: SelectionManager.Views()
- .filter(dv => dv.props.renderDepth > 0)
+ .filter(dv => dv._props.renderDepth > 0)
.map(dv => dv.getBounds())
.reduce((bounds, rect) => !rect ? bounds
: { x: Math.min(rect.left, bounds.x),
@@ -198,12 +206,12 @@ export class DocumentDecorations extends React.Component<{ PanelWidth: number; P
if (containers.size > 1) return false;
const { left, top } = dragDocView.getBounds() || { left: 0, top: 0 };
const dragData = new DragManager.DocumentDragData(
- SelectionManager.Views().map(dv => dv.props.Document),
- dragDocView.props.dropAction
+ SelectionManager.Views().map(dv => dv.Document),
+ dragDocView._props.dropAction
);
- dragData.offset = dragDocView.props.ScreenToLocalTransform().transformDirection(e.x - left, e.y - top);
- dragData.moveDocument = dragDocView.props.moveDocument;
- dragData.removeDocument = dragDocView.props.removeDocument;
+ dragData.offset = dragDocView._props.ScreenToLocalTransform().transformDirection(e.x - left, e.y - top);
+ dragData.moveDocument = dragDocView._props.moveDocument;
+ dragData.removeDocument = dragDocView._props.removeDocument;
dragData.isDocDecorationMove = true;
dragData.canEmbed = dragTitle;
this._hidden = true;
@@ -223,7 +231,7 @@ export class DocumentDecorations extends React.Component<{ PanelWidth: number; P
_deleteAfterIconify = false;
_iconifyBatch: UndoManager.Batch | undefined;
onCloseClick = (forceDeleteOrIconify: boolean | undefined) => {
- const views = SelectionManager.Views().filter(v => v && v.props.renderDepth > 0);
+ const views = SelectionManager.Views().filter(v => v && v._props.renderDepth > 0);
if (forceDeleteOrIconify === false && this._iconifyBatch) return;
this._deleteAfterIconify = forceDeleteOrIconify || this._iconifyBatch ? true : false;
var iconifyingCount = views.length;
@@ -231,11 +239,11 @@ export class DocumentDecorations extends React.Component<{ PanelWidth: number; P
if ((force || --iconifyingCount === 0) && this._iconifyBatch) {
if (this._deleteAfterIconify) {
views.forEach(iconView => {
- Doc.setNativeView(iconView.props.Document);
- if (iconView.props.Document.activeFrame) {
- iconView.props.Document.opacity = 0; // bcz: hacky ... allows inkMasks and other documents to be "turned off" without removing them from the animated collection which allows them to function properly in a presenation.
+ Doc.setNativeView(iconView.Document);
+ if (iconView.Document.activeFrame) {
+ iconView.Document.opacity = 0; // bcz: hacky ... allows inkMasks and other documents to be "turned off" without removing them from the animated collection which allows them to function properly in a presenation.
} else {
- iconView.props.removeDocument?.(iconView.props.Document);
+ iconView._props.removeDocument?.(iconView.Document);
}
});
views.forEach(SelectionManager.DeselectView);
@@ -296,7 +304,7 @@ export class DocumentDecorations extends React.Component<{ PanelWidth: number; P
SelectionManager.DeselectAll();
};
- onSelectContainerDocClick = () => SelectionManager.Views()?.[0]?.props.docViewPath?.().lastElement()?.select(false);
+ onSelectContainerDocClick = () => SelectionManager.Views()?.[0]?._props.docViewPath?.().lastElement()?.select(false);
/**
* sets up events when user clicks on the border radius editor
*/
@@ -344,7 +352,7 @@ export class DocumentDecorations extends React.Component<{ PanelWidth: number; P
};
setRotateCenter = (seldocview: DocumentView, rotCenter: number[]) => {
- const newloccentern = seldocview.props.ScreenToLocalTransform().transformPoint(rotCenter[0], rotCenter[1]);
+ const newloccentern = seldocview._props.ScreenToLocalTransform().transformPoint(rotCenter[0], rotCenter[1]);
const newlocenter = [newloccentern[0] - NumCast(seldocview.layoutDoc._width) / 2, newloccentern[1] - NumCast(seldocview.layoutDoc._height) / 2];
const final = Utils.rotPt(newlocenter[0], newlocenter[1], -(NumCast(seldocview.Document._rotation) / 180) * Math.PI);
seldocview.Document.rotation_centerX = final.x / NumCast(seldocview.layoutDoc._width);
@@ -376,7 +384,7 @@ export class DocumentDecorations extends React.Component<{ PanelWidth: number; P
const seldocview = SelectionManager.Views()[0];
SelectionManager.Views().forEach(dv => {
const accumRot = (NumCast(dv.Document._rotation) / 180) * Math.PI;
- const localRotCtr = dv.props.ScreenToLocalTransform().transformPoint(rcScreen.X, rcScreen.Y);
+ const localRotCtr = dv._props.ScreenToLocalTransform().transformPoint(rcScreen.X, rcScreen.Y);
const localRotCtrOffset = [localRotCtr[0] - NumCast(dv.Document.width) / 2, localRotCtr[1] - NumCast(dv.Document.height) / 2];
const startRotCtr = Utils.rotPt(localRotCtrOffset[0], localRotCtrOffset[1], -accumRot);
const unrotatedDocPos = { x: NumCast(dv.Document.x) + localRotCtrOffset[0] - startRotCtr.x, y: NumCast(dv.Document.y) + localRotCtrOffset[1] - startRotCtr.y };
@@ -454,7 +462,7 @@ export class DocumentDecorations extends React.Component<{ PanelWidth: number; P
dot = (b[0] - a[0]) * (p[1] - a[1]) - (b[1] - a[1]) * (p[0] - a[0]);
return [a[0] + atob[0] * t, a[1] + atob[1] * t];
};
- const tl = docView.props.ScreenToLocalTransform().inverse().transformPoint(0, 0);
+ const tl = docView._props.ScreenToLocalTransform().inverse().transformPoint(0, 0);
return project([e.clientX + this._offset.x, e.clientY + this._offset.y], tl, [tl[0] + fixedAspect, tl[1] + 1]);
};
onPointerMove = (e: PointerEvent, down: number[], move: number[]): boolean => {
@@ -475,7 +483,7 @@ export class DocumentDecorations extends React.Component<{ PanelWidth: number; P
!this._interactionLock && runInAction(async () => { // resize selected docs if we're not in the middle of a resize (ie, throttle input events to frame rate)
this._interactionLock = true;
this._snapPt = thisPt;
- e.ctrlKey && (SelectionManager.Views().forEach(docView => !Doc.NativeHeight(docView.props.Document) && docView.toggleNativeDimensions()));
+ e.ctrlKey && (SelectionManager.Views().forEach(docView => !Doc.NativeHeight(docView.Document) && docView.toggleNativeDimensions()));
const fixedAspect = SelectionManager.Docs().some(this.hasFixedAspect);
const scaleAspect = {x:scale.x === 1 && fixedAspect ? scale.y : scale.x, y: scale.x !== 1 && fixedAspect ? scale.x : scale.y};
SelectionManager.Views().forEach(docView =>
@@ -522,7 +530,7 @@ export class DocumentDecorations extends React.Component<{ PanelWidth: number; P
doc.xPadding = NumCast(doc.xPadding) * scale.x;
doc.yPadding = NumCast(doc.yPadding) * scale.y;
} else {
- const refCent = docView.props.ScreenToLocalTransform().transformPoint(refPt[0], refPt[1]); // fixed reference point for resize (ie, a point that doesn't move)
+ const refCent = docView._props.ScreenToLocalTransform().transformPoint(refPt[0], refPt[1]); // fixed reference point for resize (ie, a point that doesn't move)
const [nwidth, nheight] = [docView.nativeWidth, docView.nativeHeight];
const [initWidth, initHeight] = [NumCast(doc._width, 1), NumCast(doc._height)];
@@ -615,7 +623,7 @@ export class DocumentDecorations extends React.Component<{ PanelWidth: number; P
return ScriptField.MakeFunction(this._titleControlString.substring(1), { doc: Doc.name })!.script.run({ self: selected.Document, this: selected.layoutDoc }, console.log).result?.toString() || '';
}
if (this._titleControlString.startsWith('#')) {
- return Field.toString(selected.props.Document[this._titleControlString.substring(1)] as Field) || '-unset-';
+ return Field.toString(selected.Document[this._titleControlString.substring(1)] as Field) || '-unset-';
}
return this._accumulatedTitle;
}
@@ -625,7 +633,7 @@ export class DocumentDecorations extends React.Component<{ PanelWidth: number; P
@computed get rotCenter() {
const lastView = SelectionManager.Views().lastElement();
if (lastView) {
- const invXf = lastView.props.ScreenToLocalTransform().inverse();
+ const invXf = lastView._props.ScreenToLocalTransform().inverse();
const seldoc = lastView.layoutDoc;
const loccenter = Utils.rotPt(NumCast(seldoc.rotation_centerX) * NumCast(seldoc._width), NumCast(seldoc.rotation_centerY) * NumCast(seldoc._height), invXf.Rotate);
return invXf.transformPoint(loccenter.x + NumCast(seldoc._width) / 2, loccenter.y + NumCast(seldoc._height) / 2);
@@ -648,16 +656,16 @@ export class DocumentDecorations extends React.Component<{ PanelWidth: number; P
var shareSymbolIcon = ReverseHierarchyMap.get(shareMode)?.image;
// hide the decorations if the parent chooses to hide it or if the document itself hides it
- const hideDecorations = SnappingManager.GetIsResizing() || seldocview.props.hideDecorations || seldocview.Document.layout_hideDecorations;
+ const hideDecorations = SnappingManager.GetIsResizing() || seldocview._props.hideDecorations || seldocview.Document.layout_hideDecorations;
const hideResizers =
- ![AclAdmin, AclEdit, AclAugment].includes(GetEffectiveAcl(seldocview.Document)) || hideDecorations || seldocview.props.hideResizeHandles || seldocview.Document.layout_hideResizeHandles || this._isRounding || this._isRotating;
- const hideTitle = this._showNothing || hideDecorations || seldocview.props.hideDecorationTitle || seldocview.Document.layout_hideDecorationTitle || this._isRounding || this._isRotating;
- const hideDocumentButtonBar = hideDecorations || seldocview.props.hideDocumentButtonBar || seldocview.Document.layout_hideDocumentButtonBar || this._isRounding || this._isRotating;
+ ![AclAdmin, AclEdit, AclAugment].includes(GetEffectiveAcl(seldocview.Document)) || hideDecorations || seldocview._props.hideResizeHandles || seldocview.Document.layout_hideResizeHandles || this._isRounding || this._isRotating;
+ const hideTitle = this._showNothing || hideDecorations || seldocview._props.hideDecorationTitle || seldocview.Document.layout_hideDecorationTitle || this._isRounding || this._isRotating;
+ const hideDocumentButtonBar = hideDecorations || seldocview._props.hideDocumentButtonBar || seldocview.Document.layout_hideDocumentButtonBar || this._isRounding || this._isRotating;
// if multiple documents have been opened at the same time, then don't show open button
const hideOpenButton =
this._showNothing ||
hideDecorations ||
- seldocview.props.hideOpenButton ||
+ seldocview._props.hideOpenButton ||
seldocview.Document.layout_hideOpenButton ||
SelectionManager.Views().some(docView => docView.Document._dragOnlyWithinContainer || docView.Document.isGroup || docView.Document.layout_hideOpenButton) ||
this._isRounding ||
@@ -667,10 +675,10 @@ export class DocumentDecorations extends React.Component<{ PanelWidth: number; P
hideDecorations ||
this._isRounding ||
this._isRotating ||
- seldocview.props.hideDeleteButton ||
+ seldocview._props.hideDeleteButton ||
seldocview.Document.hideDeleteButton ||
SelectionManager.Views().some(docView => {
- const collectionAcl = docView.props.docViewPath()?.lastElement() ? GetEffectiveAcl(docView.props.docViewPath().lastElement().dataDoc) : AclEdit;
+ const collectionAcl = docView._props.docViewPath()?.lastElement() ? GetEffectiveAcl(docView._props.docViewPath().lastElement().dataDoc) : AclEdit;
return collectionAcl !== AclAdmin && collectionAcl !== AclEdit && GetEffectiveAcl(docView.Document) !== AclAdmin;
});
const topBtn = (key: string, icon: string, pointerDown: undefined | ((e: React.PointerEvent) => void), click: undefined | ((e: any) => void), title: string) => (
@@ -798,7 +806,7 @@ export class DocumentDecorations extends React.Component<{ PanelWidth: number; P
<div key="br" className="documentDecorations-bottomRightResizer" onPointerDown={this.onPointerDown} />
</>
)}
- {seldocview.props.renderDepth <= 1 || !seldocview.props.docViewPath().lastElement() ? null : topBtn('selector', 'arrow-alt-circle-up', undefined, this.onSelectContainerDocClick, 'tap to select containing document')}
+ {seldocview._props.renderDepth <= 1 || !seldocview._props.docViewPath().lastElement() ? null : topBtn('selector', 'arrow-alt-circle-up', undefined, this.onSelectContainerDocClick, 'tap to select containing document')}
{useRounding && (
<div
className="documentDecorations-borderRadius"