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.tsx61
1 files changed, 42 insertions, 19 deletions
diff --git a/src/client/views/DocumentDecorations.tsx b/src/client/views/DocumentDecorations.tsx
index 93c3e3338..34b05da56 100644
--- a/src/client/views/DocumentDecorations.tsx
+++ b/src/client/views/DocumentDecorations.tsx
@@ -1,7 +1,8 @@
+import { IconProp } from '@fortawesome/fontawesome-svg-core';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { Tooltip } from '@mui/material';
import { IconButton } from 'browndash-components';
-import { action, computed, makeObservable, observable, runInAction } from 'mobx';
+import { action, computed, makeObservable, observable, runInAction, trace } from 'mobx';
import { observer } from 'mobx-react';
import * as React from 'react';
import { FaUndo } from 'react-icons/fa';
@@ -34,6 +35,8 @@ import { DocumentView } from './nodes/DocumentView';
import { ImageBox } from './nodes/ImageBox';
import { OpenWhere, OpenWhereMod } from './nodes/OpenWhere';
import { FormattedTextBox } from './nodes/formattedText/FormattedTextBox';
+import { TagsView } from './TagsView';
+import { setTime } from 'react-datepicker/dist/date_utils';
interface DocumentDecorationsProps {
PanelWidth: number;
@@ -57,6 +60,7 @@ export class DocumentDecorations extends ObservableReactComponent<DocumentDecora
private _interactionLock?: boolean;
@observable _showNothing = true;
+ @observable private _forceRender = 0
@observable private _accumulatedTitle = '';
@observable private _titleControlString: string = '$title';
@observable private _editingTitle = false;
@@ -88,6 +92,7 @@ export class DocumentDecorations extends ObservableReactComponent<DocumentDecora
(this._showNothing = !inputting && !DocumentButtonBar.Instance?._tooltipOpen && !(this.Bounds.x !== Number.MAX_VALUE && //
(this.Bounds.x > center.x+x || this.Bounds.r < center.x+x ||
this.Bounds.y > center.y+y || this.Bounds.b < center.y+y )));
+
})); // prettier-ignore
}
@@ -145,7 +150,7 @@ export class DocumentDecorations extends ObservableReactComponent<DocumentDecora
titleEntered = (e: React.KeyboardEvent) => {
if (e.key === 'Enter') {
e.stopPropagation();
- (e.target as any).blur();
+ (e.target as HTMLElement).blur?.();
}
};
@@ -170,7 +175,8 @@ export class DocumentDecorations extends ObservableReactComponent<DocumentDecora
!this._editingTitle && (this._accumulatedTitle = this._titleControlString.startsWith('$') ? (selected && Field.toKeyValueString(selected, this._titleControlString.substring(1))) || '-unset-' : this._titleControlString);
this._editingTitle = true;
this._keyinput.current && setTimeout(this._keyinput.current.focus);
- })
+ }),
+ false // can't preventDefault since that will mess up goldenlayout if you drag over the tab bar. so just stop propagation below.
);
e.stopPropagation();
}
@@ -192,7 +198,7 @@ export class DocumentDecorations extends ObservableReactComponent<DocumentDecora
if (containers.size > 1) return false;
const { left, top } = dragDocView.getBounds || { left: 0, top: 0 };
const dragData = new DragManager.DocumentDragData(DocumentView.SelectedDocs(), dragDocView._props.dropAction);
- dragData.offset = dragDocView.screenToContentsTransform().transformDirection(e.x - left, e.y - top);
+ dragData.offset = dragDocView.screenToViewTransform().transformDirection(e.x - left, e.y - top);
dragData.moveDocument = dragDocView._props.moveDocument;
dragData.removeDocument = dragDocView._props.removeDocument;
dragData.isDocDecorationMove = true;
@@ -229,7 +235,8 @@ export class DocumentDecorations extends ObservableReactComponent<DocumentDecora
if (iconViewDoc.activeFrame) {
iconViewDoc.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.Document);
+ if (iconView.Document.annotationOn && iconView.Document.face) iconView.Document.hidden = true;
+ else iconView._props.removeDocument?.(iconView.Document);
}
});
views.forEach(DocumentView.DeselectView);
@@ -239,7 +246,7 @@ export class DocumentDecorations extends ObservableReactComponent<DocumentDecora
}
});
if (!this._iconifyBatch) {
- (document.activeElement as any).blur?.();
+ (document.activeElement as HTMLElement).blur?.();
this._iconifyBatch = UndoManager.StartBatch(forceDeleteOrIconify ? 'delete selected docs' : 'iconifying');
} else {
// eslint-disable-next-line no-param-reassign
@@ -254,7 +261,7 @@ export class DocumentDecorations extends ObservableReactComponent<DocumentDecora
setupMoveUpEvents(this, e, () => DragManager.StartWindowDrag?.(e, [DocumentView.SelectedDocs().lastElement()]) ?? false, emptyFunction, this.onMaximizeClick, false, false);
e.stopPropagation();
};
- onMaximizeClick = (e: any): void => {
+ onMaximizeClick = (e: PointerEvent): void => {
const selView = DocumentView.Selected()[0];
if (selView) {
if (e.ctrlKey) {
@@ -335,7 +342,7 @@ export class DocumentDecorations extends ObservableReactComponent<DocumentDecora
setRotateCenter = (seldocview: DocumentView, rotCenter: number[]) => {
const selDoc = seldocview.Document;
- const newloccentern = seldocview.screenToContentsTransform().transformPoint(rotCenter[0], rotCenter[1]);
+ const newloccentern = seldocview.screenToViewTransform().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);
selDoc._rotation_centerX = final.x / NumCast(seldocview.layoutDoc._width);
@@ -349,8 +356,10 @@ export class DocumentDecorations extends ObservableReactComponent<DocumentDecora
setupMoveUpEvents(
this,
e,
- (moveEv: PointerEvent, down: number[], delta: number[]) => // return false to keep getting events
- this.setRotateCenter(seldocview, [this.rotCenter[0] + delta[0], this.rotCenter[1] + delta[1]]) as any as boolean,
+ (moveEv: PointerEvent, down: number[], delta: number[]) => {
+ this.setRotateCenter(seldocview, [this.rotCenter[0] + delta[0], this.rotCenter[1] + delta[1]]);
+ return false;
+ },
action(() => { this._isRotating = false; }), // upEvent
action(() => { seldocview.Document._rotation_centerX = seldocview.Document._rotation_centerY = 0; }),
true
@@ -430,7 +439,7 @@ export class DocumentDecorations extends ObservableReactComponent<DocumentDecora
setupMoveUpEvents(this, e, this.onPointerMove, this.onPointerUp, emptyFunction);
e.stopPropagation();
const id = (this._resizeHdlId = e.currentTarget.className);
- const pad = id.includes('Left') || id.includes('Right') ? Number(getComputedStyle(e.target as any).width.replace('px', '')) / 2 : 0;
+ const pad = id.includes('Left') || id.includes('Right') ? Number(getComputedStyle(e.target as HTMLElement).width?.replace('px', '')) / 2 : 0;
const bounds = e.currentTarget.getBoundingClientRect();
this._offset = {
x: id.toLowerCase().includes('left') ? bounds.right - e.clientX - pad : bounds.left - e.clientX + pad, //
@@ -478,7 +487,7 @@ export class DocumentDecorations extends ObservableReactComponent<DocumentDecora
const scaleAspect = {x:scale.x === 1 && hasFixedAspect ? scale.y : scale.x, y: scale.x !== 1 && hasFixedAspect ? scale.x : scale.y};
DocumentView.Selected().forEach(docView =>
this.resizeView(docView, refPt, scaleAspect, { dragHdl, ctrlKey:e.ctrlKey })); // prettier-ignore
- await new Promise<any>(res => { setTimeout(() => { res(this._interactionLock = undefined)})});
+ await new Promise<void>(res => { setTimeout(() => { res(this._interactionLock = undefined)})});
}); // prettier-ignore
return false;
@@ -613,8 +622,7 @@ export class DocumentDecorations extends ObservableReactComponent<DocumentDecora
});
};
- @computed
- get selectionTitle(): string {
+ @computed get selectionTitle(): string {
if (DocumentView.Selected().length === 1) {
const selected = DocumentView.Selected()[0];
if (this._titleControlString.startsWith('$')) {
@@ -628,15 +636,16 @@ export class DocumentDecorations extends ObservableReactComponent<DocumentDecora
@computed get rotCenter() {
const lastView = DocumentView.Selected().lastElement();
if (lastView) {
- const invXf = lastView.screenToContentsTransform().inverse();
+ const invXf = lastView.screenToViewTransform().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);
}
return this._rotCenter;
}
-
+;
render() {
+ this._forceRender;
const { b, r, x, y } = this.Bounds;
const seldocview = DocumentView.Selected().lastElement();
if (SnappingManager.IsDragging || r - x < 1 || x === Number.MAX_VALUE || !seldocview || this._hidden || isNaN(r) || isNaN(b) || isNaN(x) || isNaN(y)) {
@@ -649,6 +658,11 @@ export class DocumentDecorations extends ObservableReactComponent<DocumentDecora
return null;
}
+ if (seldocview && !seldocview?.ContentDiv?.getBoundingClientRect().width) {
+ setTimeout(action(() => this._forceRender++)); // if the selected Doc has no width, then assume it's stil being layed out and try to render again later.
+ return null;
+ }
+
// sharing
const acl = GetEffectiveAcl(!this._showLayoutAcl ? Doc.GetProto(seldocview.Document) : seldocview.Document);
const docShareMode = HierarchyMapping.get(acl)!.name;
@@ -681,10 +695,10 @@ export class DocumentDecorations extends ObservableReactComponent<DocumentDecora
const collectionAcl = docView.containerViewPath?.()?.lastElement() ? GetEffectiveAcl(docView.containerViewPath?.().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) => (
+ const topBtn = (key: string, icon: IconProp, pointerDown: undefined | ((e: React.PointerEvent) => void), click: undefined | ((e: PointerEvent) => void), title: string) => (
<Tooltip key={key} title={<div className="dash-tooltip">{title}</div>} placement="top">
- <div className={`documentDecorations-${key}Button`} onContextMenu={e => e.preventDefault()} onPointerDown={pointerDown ?? (e => setupMoveUpEvents(this, e, returnFalse, emptyFunction, clickEv => click!(clickEv)))}>
- <FontAwesomeIcon icon={icon as any} />
+ <div className={`documentDecorations-${key}Button`} onContextMenu={e => e.preventDefault()} onPointerDown={pointerDown ?? (e => setupMoveUpEvents(this, e, returnFalse, emptyFunction, clickEv => click?.(clickEv)))}>
+ <FontAwesomeIcon icon={icon} />
</div>
</Tooltip>
);
@@ -830,11 +844,20 @@ export class DocumentDecorations extends ObservableReactComponent<DocumentDecora
<div
className="link-button-container"
style={{
+ top: DocumentView.Selected().length > 1 ? 0 : `${seldocview.showTags ? 4 + seldocview.TagPanelHeight : 4}px`,
transform: `translate(${-this._resizeBorderWidth / 2 + 10}px, ${this._resizeBorderWidth + bounds.b - bounds.y + this._titleHeight}px) `,
}}>
<DocumentButtonBar views={() => DocumentView.Selected()} />
</div>
)}
+ <div
+ className="documentDecorations-tagsView"
+ style={{
+ top: `${seldocview.showTags ? 4 + seldocview.TagPanelHeight : 4}px`,
+ transform: `translate(${-this._resizeBorderWidth / 2 + 10}px, ${this._resizeBorderWidth + bounds.b - bounds.y + this._titleHeight}px) `,
+ }}>
+ {DocumentView.Selected().length > 1 ? <TagsView Views={DocumentView.Selected()} /> : null}
+ </div>
</div>
{useRotation && (