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.tsx106
1 files changed, 48 insertions, 58 deletions
diff --git a/src/client/views/DocumentDecorations.tsx b/src/client/views/DocumentDecorations.tsx
index 2fb9f0fc1..2a44a9739 100644
--- a/src/client/views/DocumentDecorations.tsx
+++ b/src/client/views/DocumentDecorations.tsx
@@ -10,7 +10,6 @@ import { DateField } from '../../fields/DateField';
import { Doc, DocListCast, Field, HierarchyMapping, ReverseHierarchyMap } from '../../fields/Doc';
import { AclAdmin, AclAugment, AclEdit, DocData } from '../../fields/DocSymbols';
import { InkField } from '../../fields/InkField';
-import { RichTextField } from '../../fields/RichTextField';
import { ScriptField } from '../../fields/ScriptField';
import { BoolCast, Cast, DocCast, NumCast, StrCast } from '../../fields/Types';
import { GetEffectiveAcl } from '../../fields/util';
@@ -33,7 +32,9 @@ import { CollectionFreeFormView } from './collections/collectionFreeForm';
import { Colors } from './global/globalEnums';
import { DocumentView, OpenWhereMod } from './nodes/DocumentView';
import { ImageBox } from './nodes/ImageBox';
+import { KeyValueBox } from './nodes/KeyValueBox';
import { FormattedTextBox } from './nodes/formattedText/FormattedTextBox';
+import { identity } from 'lodash';
interface DocumentDecorationsProps {
PanelWidth: number;
@@ -57,7 +58,7 @@ export class DocumentDecorations extends ObservableReactComponent<DocumentDecora
@observable _showNothing = true;
@observable private _accumulatedTitle = '';
- @observable private _titleControlString: string = '#title';
+ @observable private _titleControlString: string = '$title';
@observable private _editingTitle = false;
@observable private _hidden = false;
@observable private _isRotating: boolean = false;
@@ -73,11 +74,18 @@ export class DocumentDecorations extends ObservableReactComponent<DocumentDecora
DocumentDecorations.Instance = this;
document.addEventListener('pointermove', // show decorations whenever pointer moves outside of selection bounds.
action(e => {
+ let inputting = false;
+ if (this._titleControlString.startsWith('$')) {
+ const titleFieldKey = this._titleControlString.substring(1);
+ if (SelectionManager.Views[0]?.Document[titleFieldKey] !== this._accumulatedTitle) {
+ inputting = true;
+ }
+ }
const center = {x: (this.Bounds.x+this.Bounds.r)/2, y: (this.Bounds.y+this.Bounds.b)/2};
const {x,y} = Utils.rotPt(e.clientX - center.x,
e.clientY - center.y,
NumCast(SelectionManager.Views.lastElement()?.screenToViewTransform().Rotate));
- (this._showNothing = !DocumentButtonBar.Instance?._tooltipOpen && !(this.Bounds.x !== Number.MAX_VALUE && //
+ (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
@@ -111,9 +119,9 @@ export class DocumentDecorations extends ObservableReactComponent<DocumentDecora
@action
titleBlur = () => {
- if (this._accumulatedTitle.startsWith('#') || this._accumulatedTitle.startsWith('=')) {
+ if (this._accumulatedTitle.startsWith('$')) {
this._titleControlString = this._accumulatedTitle;
- } else if (this._titleControlString.startsWith('#')) {
+ } else if (this._titleControlString.startsWith('$')) {
if (this._accumulatedTitle.startsWith('-->#')) {
SelectionManager.Docs.forEach(doc => (doc[DocData].onViewMounted = ScriptField.MakeScript(`updateTagsCollection(this)`)));
}
@@ -124,33 +132,8 @@ export class DocumentDecorations extends ObservableReactComponent<DocumentDecora
SelectionManager.Views.forEach(d => {
if (titleFieldKey === 'title') {
d.dataDoc.title_custom = !this._accumulatedTitle.startsWith('-');
- if (StrCast(d.Document.title).startsWith('@') && !this._accumulatedTitle.startsWith('@')) {
- Doc.RemFromMyPublished(d.Document);
- }
- if (!StrCast(d.Document.title).startsWith('@') && this._accumulatedTitle.startsWith('@')) {
- Doc.AddToMyPublished(d.Document);
- }
- }
- //@ts-ignore
- const titleField = +this._accumulatedTitle == this._accumulatedTitle ? +this._accumulatedTitle : this._accumulatedTitle;
-
- if (titleField.toString().startsWith('<this>')) {
- const title = titleField.toString().replace(/<this>\.?/, '');
- const curKey = Doc.LayoutFieldKey(d.Document);
- if (curKey !== title) {
- if (title) {
- if (d.dataDoc[title] === undefined || d.dataDoc[title] instanceof RichTextField || typeof d.dataDoc[title] === 'string') {
- d.Document.layout_fieldKey = `layout_${title}`;
- d.Document[`layout_${title}`] = FormattedTextBox.LayoutString(title);
- d.Document[`${title}_nativeWidth`] = d.Document[`${title}_nativeHeight`] = 0;
- }
- } else {
- d.Document.layout_fieldKey = undefined;
- }
- }
- } else {
- Doc.SetInPlace(d.Document, titleFieldKey, titleField, true);
}
+ KeyValueBox.SetField(d.Document, titleFieldKey, this._accumulatedTitle);
}),
'edit title'
);
@@ -181,7 +164,8 @@ export class DocumentDecorations extends ObservableReactComponent<DocumentDecora
e => this.onBackgroundMove(true, e),
emptyFunction,
action(e => {
- !this._editingTitle && (this._accumulatedTitle = this._titleControlString.startsWith('#') ? this.selectionTitle : this._titleControlString);
+ const selected = SelectionManager.Views.length === 1 ? SelectionManager.Docs[0] : undefined;
+ !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);
})
@@ -354,8 +338,8 @@ export class DocumentDecorations extends ObservableReactComponent<DocumentDecora
const newloccentern = seldocview.screenToContentsTransform().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);
- seldocview.Document.rotation_centerY = final.y / NumCast(seldocview.layoutDoc._height);
+ seldocview.Document._rotation_centerX = final.x / NumCast(seldocview.layoutDoc._width);
+ seldocview.Document._rotation_centerY = final.y / NumCast(seldocview.layoutDoc._height);
};
@action
@@ -368,8 +352,10 @@ export class DocumentDecorations extends ObservableReactComponent<DocumentDecora
(e: 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,
action(e => (this._isRotating = false)), // upEvent
- action(e => (seldocview.Document.rotation_centerX = seldocview.Document.rotation_centerY = 0))
+ action(e => (seldocview.Document._rotation_centerX = seldocview.Document._rotation_centerY = 0)),
+ true
); // prettier-ignore
+ e.stopPropagation();
};
@action
@@ -441,9 +427,13 @@ export class DocumentDecorations extends ObservableReactComponent<DocumentDecora
SnappingManager.SetIsResizing(SelectionManager.Docs.lastElement()); // turns off pointer events on things like youtube videos and web pages so that dragging doesn't get "stuck" when cursor moves over them
setupMoveUpEvents(this, e, this.onPointerMove, this.onPointerUp, emptyFunction);
e.stopPropagation();
- this._resizeHdlId = e.currentTarget.className;
+ 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 bounds = e.currentTarget.getBoundingClientRect();
- this._offset = { x: this._resizeHdlId.toLowerCase().includes('left') ? bounds.right - e.clientX : bounds.left - e.clientX, y: this._resizeHdlId.toLowerCase().includes('top') ? bounds.bottom - e.clientY : bounds.top - e.clientY };
+ this._offset = {
+ x: id.toLowerCase().includes('left') ? bounds.right - e.clientX - pad : bounds.left - e.clientX + pad, //
+ y: id.toLowerCase().includes('top') ? bounds.bottom - e.clientY - pad : bounds.top - e.clientY + pad,
+ };
this._resizeUndo = UndoManager.StartBatch('drag resizing');
this._snapPt = { x: e.pageX, y: e.pageY };
SelectionManager.Views.forEach(docView => docView.CollectionFreeFormView?.dragStarting(false, false));
@@ -622,11 +612,8 @@ export class DocumentDecorations extends ObservableReactComponent<DocumentDecora
get selectionTitle(): string {
if (SelectionManager.Views.length === 1) {
const selected = SelectionManager.Views[0];
- if (this._titleControlString.startsWith('=')) {
- 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.Document[this._titleControlString.substring(1)] as Field) || '-unset-';
+ if (this._titleControlString.startsWith('$')) {
+ return Field.toJavascriptString(selected.Document[this._titleControlString.substring(1)] as Field) || '-unset-';
}
return this._accumulatedTitle;
}
@@ -638,7 +625,7 @@ export class DocumentDecorations extends ObservableReactComponent<DocumentDecora
if (lastView) {
const invXf = lastView.screenToContentsTransform().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);
+ 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;
@@ -731,21 +718,24 @@ export class DocumentDecorations extends ObservableReactComponent<DocumentDecora
) : null;
const titleArea = this._editingTitle ? (
- <input
- ref={this._keyinput}
- className="documentDecorations-title"
- type="text"
- name="dynbox"
- autoComplete="on"
- value={hideTitle ? '' : this._accumulatedTitle}
- onBlur={action((e: React.FocusEvent) => {
- this._editingTitle = false;
- !hideTitle && this.titleBlur();
- })}
- onChange={action(e => !hideTitle && (this._accumulatedTitle = e.target.value))}
- onKeyDown={hideTitle ? emptyFunction : this.titleEntered}
- onPointerDown={e => e.stopPropagation()}
- />
+ <>
+ {r - x < 150 ? null : <span>{this._titleControlString + ':'}</span>}
+ <input
+ ref={this._keyinput}
+ className="documentDecorations-title"
+ type="text"
+ name="dynbox"
+ autoComplete="on"
+ value={hideTitle ? '' : this._accumulatedTitle}
+ onBlur={action((e: React.FocusEvent) => {
+ this._editingTitle = false;
+ this.titleBlur();
+ })}
+ onChange={action(e => !hideTitle && (this._accumulatedTitle = e.target.value))}
+ onKeyDown={hideTitle ? emptyFunction : this.titleEntered}
+ onPointerDown={e => e.stopPropagation()}
+ />
+ </>
) : (
<div className="documentDecorations-title" key="title">
{hideTitle ? null : (