From 955ec827382a50d0bda2cb657dbd1762b2477e59 Mon Sep 17 00:00:00 2001 From: Geireann Lindfield Roberts <60007097+geireann@users.noreply.github.com> Date: Fri, 1 Jul 2022 16:18:20 -0700 Subject: added resize handlers and linted document decorations --- src/Utils.ts | 15 ++++ src/client/views/DocumentDecorations.scss | 79 ++++++++++------------ src/client/views/DocumentDecorations.tsx | 70 ++++++++++++++----- src/client/views/global/globalEnums.tsx | 1 + .../views/nodes/CollectionFreeFormDocumentView.tsx | 1 + 5 files changed, 107 insertions(+), 59 deletions(-) (limited to 'src') diff --git a/src/Utils.ts b/src/Utils.ts index b87980397..6699aa133 100644 --- a/src/Utils.ts +++ b/src/Utils.ts @@ -677,7 +677,22 @@ export function StopEvent(e: React.PointerEvent | React.MouseEvent) { e.preventDefault(); } +/** + * Helper method for converting pixel string eg. '32px' into number eg. 32 + * @param value: string with 'px' ending + * @returns value: number + * + * Example: + * '32px' -> 32 + */ +export function numberValue(value: string | undefined):number { + if (value == undefined) return 0; + return parseInt(value); +} +export function numbersAlmostEqual(num1: number, num2: number) { + return Math.abs( num1 - num2 ) < 0.2; +} export function setupMoveUpEvents( target: object, diff --git a/src/client/views/DocumentDecorations.scss b/src/client/views/DocumentDecorations.scss index 135d6d001..af4ceb0b5 100644 --- a/src/client/views/DocumentDecorations.scss +++ b/src/client/views/DocumentDecorations.scss @@ -1,6 +1,8 @@ @import 'global/globalCssVariables'; $linkGap: 3px; +$headerHeight: 20px; +$resizeHandler: 8px; .documentDecorations-Dark, .documentDecorations { @@ -16,8 +18,8 @@ $linkGap: 3px; top: 0; left: 0; display: grid; - grid-template-rows: 20px 8px 1fr 8px; - grid-template-columns: 8px 1fr 8px; + grid-template-rows: $headerHeight $resizeHandler 1fr $resizeHandler; + grid-template-columns: $resizeHandler 1fr $resizeHandler; pointer-events: none; .documentDecorations-centerCont { @@ -82,29 +84,44 @@ $linkGap: 3px; grid-column: 3; } - .documentDecorations-rotation, + // Rotation handler + .documentDecorations-rotation { + border-radius: 100%; + height: 30; + width: 30; + right: -10; + top: 50%; + z-index: 1000000; + position: absolute; + pointer-events: all; + cursor: pointer; + background: white; + display: flex; + justify-content: center; + align-items: center; + text-align: center; + font-size: 30px; + } + + // Border radius handler .documentDecorations-borderRadius { - grid-column: 3; - grid-row: 4; + position: absolute; border-radius: 100%; - background: black; - height: 8; - right: -12; - top: 12; - position: relative; + background: $medium-gray; + height: 10; + width: 10; pointer-events: all; cursor: nwse-resize; - - .borderRadiusTooltip { - width: 10px; - height: 10px; - position: absolute; - } } - .documentDecorations-rotation { - background: transparent; - right: -15; + .documentDecorations-rotationPath { + position: absolute; + width: 100%; + height: 0; + transform: translate(0px, -25%); + padding-bottom: 100%; + border-radius: 100%; + border: solid $medium-gray 10px; } .documentDecorations-topLeftResizer, @@ -146,30 +163,6 @@ $linkGap: 3px; grid-column: 3; } - .documentDecorations-rotation, - .documentDecorations-borderRadius { - grid-column: 3; - grid-row: 4; - border-radius: 100%; - background: black; - height: 8; - right: -12; - top: 12; - position: relative; - pointer-events: all; - cursor: nwse-resize; - - .borderRadiusTooltip { - width: 10px; - height: 10px; - position: absolute; - } - } - .documentDecorations-rotation { - background: transparent; - right: -15; - } - .documentDecorations-topLeftResizer, .documentDecorations-bottomRightResizer { cursor: nwse-resize; diff --git a/src/client/views/DocumentDecorations.tsx b/src/client/views/DocumentDecorations.tsx index 17e135689..59675c986 100644 --- a/src/client/views/DocumentDecorations.tsx +++ b/src/client/views/DocumentDecorations.tsx @@ -10,7 +10,7 @@ import { InkField } from '../../fields/InkField'; import { ComputedField, ScriptField } from '../../fields/ScriptField'; import { Cast, FieldValue, NumCast, StrCast } from '../../fields/Types'; import { GetEffectiveAcl } from '../../fields/util'; -import { emptyFunction, returnFalse, setupMoveUpEvents } from '../../Utils'; +import { emptyFunction, returnFalse, setupMoveUpEvents, numberValue, numbersAlmostEqual } from '../../Utils'; import { Docs } from '../documents/Documents'; import { DocumentType } from '../documents/DocumentTypes'; import { CurrentUserUtils } from '../util/CurrentUserUtils'; @@ -30,6 +30,7 @@ import { DocumentView } from './nodes/DocumentView'; import { FormattedTextBox } from './nodes/formattedText/FormattedTextBox'; import { ImageBox } from './nodes/ImageBox'; import React = require('react'); +import { Colors } from './global/globalEnums'; @observer export class DocumentDecorations extends React.Component<{ PanelWidth: number; PanelHeight: number; boundsLeft: number; boundsTop: number }, { value: string }> { @@ -56,6 +57,7 @@ export class DocumentDecorations extends React.Component<{ PanelWidth: number; P @observable public pushIcon: IconProp = 'arrow-alt-circle-up'; @observable public pullIcon: IconProp = 'arrow-alt-circle-down'; @observable public pullColor: string = 'white'; + @observable private _showRotationPath: boolean = false; constructor(props: any) { super(props); @@ -262,27 +264,43 @@ export class DocumentDecorations extends React.Component<{ PanelWidth: number; P }; onSelectorClick = () => SelectionManager.Views()?.[0]?.props.ContainingCollectionView?.props.select(false); - + + /** + * Handles setting up events when user clicks on the border radius editor + * @param e PointerEvent + */ + @action onRadiusDown = (e: React.PointerEvent): void => { this._resizeUndo = UndoManager.StartBatch('DocDecs set radius'); + // Call util move event function setupMoveUpEvents( - this, - e, + this, // target + e, // pointerEvent (e, down) => { - const dist = Math.sqrt((e.clientX - down[0]) * (e.clientX - down[0]) + (e.clientY - down[1]) * (e.clientY - down[1])); + const x = this.Bounds.x + 3; + const y = this.Bounds.y + 3; + const maxDist = Math.min((this.Bounds.r - this.Bounds.x) / 2, (this.Bounds.b - this.Bounds.y) / 2); + let dist = Math.sqrt((e.clientX - x) * (e.clientX - x) + (e.clientY - y) * (e.clientY - y)); + if (e.clientX < x && e.clientY < y) dist = 0 SelectionManager.Views() .map(dv => dv.props.Document) - .map(doc => (doc.layout instanceof Doc ? doc.layout : doc.isTemplateForField ? doc : Doc.GetProto(doc))) - .map(d => (d.borderRounding = `${Math.max(0, dist < 3 ? 0 : dist)}px`)); + .map(doc => { + const docMax = Math.min(NumCast(doc.width)/2, NumCast(doc.height)/2); + const ratio = dist/maxDist; + const radius = Math.min(1, ratio) * docMax; + doc.borderRounding = `${radius}px`; + } + ); return false; - }, - e => this._resizeUndo?.end(), - e => {} + }, // moveEvent + e => this._resizeUndo?.end(), // upEvent + e => {} // clickEvent ); }; @action onRotateDown = (e: React.PointerEvent): void => { + this._showRotationPath = true; const rotateUndo = UndoManager.StartBatch('rotatedown'); const selectedInk = SelectionManager.Views().filter(i => i.ComponentView instanceof InkingStroke); const centerPoint = !selectedInk.length ? { X: this.Bounds.x, Y: this.Bounds.y } : { X: this.Bounds.c?.X ?? (this.Bounds.x + this.Bounds.r) / 2, Y: this.Bounds.c?.Y ?? (this.Bounds.y + this.Bounds.b) / 2 }; @@ -299,11 +317,13 @@ export class DocumentDecorations extends React.Component<{ PanelWidth: number; P SelectionManager.Views().forEach(dv => (dv.rootDoc._jitterRotation = NumCast(dv.rootDoc._jitterRotation) - (angle * 180) / Math.PI)); } return false; - }, + }, // moveEvent () => { + console.log('up') + action(() => this._showRotationPath = false); rotateUndo?.end(); UndoManager.FilterBatches(['data', 'x', 'y', 'width', 'height']); - }, + }, // upEvent emptyFunction ); }; @@ -614,11 +634,20 @@ export class DocumentDecorations extends React.Component<{ PanelWidth: number; P bounds.r = Math.max(bounds.x, Math.max(leftBounds, Math.min(window.innerWidth, bounds.r + borderRadiusDraggerWidth + this._resizeBorderWidth / 2) - this._resizeBorderWidth / 2 - borderRadiusDraggerWidth)); bounds.b = Math.max(bounds.y, Math.max(topBounds, Math.min(window.innerHeight, bounds.b + this._resizeBorderWidth / 2 + this._linkBoxHeight) - this._resizeBorderWidth / 2 - this._linkBoxHeight)); + // Rotation constants: Only allow rotation on ink and images const useRotation = seldoc.ComponentView instanceof InkingStroke || seldoc.ComponentView instanceof ImageBox; - const resizerScheme = colorScheme ? 'documentDecorations-resizer' + colorScheme : ''; - const rotation = NumCast(seldoc.rootDoc._jitterRotation); + + const resizerScheme = colorScheme ? 'documentDecorations-resizer' + colorScheme : ''; + // Radius constants + const borderRadius = numberValue(StrCast(seldoc.rootDoc.borderRounding)); + const docMax = Math.min(NumCast(seldoc.rootDoc.width)/2, NumCast(seldoc.rootDoc.height)/2); + const maxDist = Math.min((this.Bounds.r - this.Bounds.x) / 2, (this.Bounds.b - this.Bounds.y) / 2); + const radiusHandle = (borderRadius / docMax) * maxDist; + const radiusHandleLocation = Math.min(radiusHandle, maxDist) + const reachedMax:boolean = numbersAlmostEqual(radiusHandleLocation, maxDist); + console.log(reachedMax); return (
@@ -671,7 +700,16 @@ export class DocumentDecorations extends React.Component<{ PanelWidth: number; P {'⟲'}
)} -
e.preventDefault()} /> + {this._showRotationPath == true && ( +
+ +
+ )} +
e.preventDefault()} /> )} diff --git a/src/client/views/global/globalEnums.tsx b/src/client/views/global/globalEnums.tsx index 56779c37c..610c2b102 100644 --- a/src/client/views/global/globalEnums.tsx +++ b/src/client/views/global/globalEnums.tsx @@ -8,6 +8,7 @@ export enum Colors { MEDIUM_BLUE_ALT = "#4476f73d", // REDUCED OPACITY LIGHT_BLUE = "#BDDDF5", PINK = "#E0217D", + ERROR_RED = "#ff0033", YELLOW = "#F5D747", DROP_SHADOW = "#32323215", } diff --git a/src/client/views/nodes/CollectionFreeFormDocumentView.tsx b/src/client/views/nodes/CollectionFreeFormDocumentView.tsx index bedc97575..284584a3d 100644 --- a/src/client/views/nodes/CollectionFreeFormDocumentView.tsx +++ b/src/client/views/nodes/CollectionFreeFormDocumentView.tsx @@ -170,6 +170,7 @@ export class CollectionFreeFormDocumentView extends DocComponent Date: Sat, 2 Jul 2022 15:49:42 -0700 Subject: Update DocumentDecorations.tsx --- src/client/views/DocumentDecorations.tsx | 43 ++++++++++++++++---------------- 1 file changed, 22 insertions(+), 21 deletions(-) (limited to 'src') diff --git a/src/client/views/DocumentDecorations.tsx b/src/client/views/DocumentDecorations.tsx index 59675c986..8b83eaeb2 100644 --- a/src/client/views/DocumentDecorations.tsx +++ b/src/client/views/DocumentDecorations.tsx @@ -57,7 +57,9 @@ export class DocumentDecorations extends React.Component<{ PanelWidth: number; P @observable public pushIcon: IconProp = 'arrow-alt-circle-up'; @observable public pullIcon: IconProp = 'arrow-alt-circle-down'; @observable public pullColor: string = 'white'; - @observable private _showRotationPath: boolean = false; + @observable private _isRotating: boolean = false; + @observable private _isRounding: boolean = false; + @observable private _isResizing: boolean = false; constructor(props: any) { super(props); @@ -271,6 +273,7 @@ export class DocumentDecorations extends React.Component<{ PanelWidth: number; P */ @action onRadiusDown = (e: React.PointerEvent): void => { + this._isRounding = true; this._resizeUndo = UndoManager.StartBatch('DocDecs set radius'); // Call util move event function setupMoveUpEvents( @@ -293,17 +296,20 @@ export class DocumentDecorations extends React.Component<{ PanelWidth: number; P ); return false; }, // moveEvent - e => this._resizeUndo?.end(), // upEvent + action(e => { + this._isRounding = false; + this._resizeUndo?.end() + }), // upEvent e => {} // clickEvent ); }; @action onRotateDown = (e: React.PointerEvent): void => { - this._showRotationPath = true; + this._isRotating = true; const rotateUndo = UndoManager.StartBatch('rotatedown'); const selectedInk = SelectionManager.Views().filter(i => i.ComponentView instanceof InkingStroke); - const centerPoint = !selectedInk.length ? { X: this.Bounds.x, Y: this.Bounds.y } : { X: this.Bounds.c?.X ?? (this.Bounds.x + this.Bounds.r) / 2, Y: this.Bounds.c?.Y ?? (this.Bounds.y + this.Bounds.b) / 2 }; + const centerPoint = { X: (this.Bounds.x + this.Bounds.r) / 2, Y: (this.Bounds.y + this.Bounds.b) / 2 }; setupMoveUpEvents( this, e, @@ -318,12 +324,12 @@ export class DocumentDecorations extends React.Component<{ PanelWidth: number; P } return false; }, // moveEvent - () => { + action(() => { console.log('up') - action(() => this._showRotationPath = false); + this._isRotating = false; rotateUndo?.end(); UndoManager.FilterBatches(['data', 'x', 'y', 'width', 'height']); - }, // upEvent + }), // upEvent emptyFunction ); }; @@ -645,9 +651,9 @@ export class DocumentDecorations extends React.Component<{ PanelWidth: number; P const docMax = Math.min(NumCast(seldoc.rootDoc.width)/2, NumCast(seldoc.rootDoc.height)/2); const maxDist = Math.min((this.Bounds.r - this.Bounds.x) / 2, (this.Bounds.b - this.Bounds.y) / 2); const radiusHandle = (borderRadius / docMax) * maxDist; - const radiusHandleLocation = Math.min(radiusHandle, maxDist) + const radiusHandleLocation = Math.min(radiusHandle, maxDist); const reachedMax:boolean = numbersAlmostEqual(radiusHandleLocation, maxDist); - console.log(reachedMax); + console.log("reachedMax: ", reachedMax); return (
{bounds.r - bounds.x < 15 && bounds.b - bounds.y < 15 ? null : ( - <> +
@@ -683,7 +689,7 @@ export class DocumentDecorations extends React.Component<{ PanelWidth: number; P {titleArea} {hideOpenButton ? null : topBtn('open', 'external-link-alt', this.onMaximizeDown, undefined, 'Open in Tab (ctrl: as alias, shift: in new collection)')} {hideResizers ? null : ( - <> +
e.preventDefault()} />
e.preventDefault()} />
e.preventDefault()} /> @@ -700,17 +706,12 @@ export class DocumentDecorations extends React.Component<{ PanelWidth: number; P {'⟲'}
)} - {this._showRotationPath == true && ( -
- -
- )}
e.preventDefault()} /> - +
)} {hideDocumentButtonBar ? null : ( @@ -724,7 +725,7 @@ export class DocumentDecorations extends React.Component<{ PanelWidth: number; P
)}
- +
)}
); -- cgit v1.2.3-70-g09d2 From b7e04efc2a17d443155c93ad3185d464272ede99 Mon Sep 17 00:00:00 2001 From: Geireann Lindfield Roberts <60007097+geireann@users.noreply.github.com> Date: Sat, 2 Jul 2022 22:43:42 -0700 Subject: made document decorations hidden when making document edits --- src/client/views/DocumentDecorations.tsx | 41 ++++++++++++++++++++------------ 1 file changed, 26 insertions(+), 15 deletions(-) (limited to 'src') diff --git a/src/client/views/DocumentDecorations.tsx b/src/client/views/DocumentDecorations.tsx index 8b83eaeb2..4f30bf846 100644 --- a/src/client/views/DocumentDecorations.tsx +++ b/src/client/views/DocumentDecorations.tsx @@ -579,19 +579,23 @@ export class DocumentDecorations extends React.Component<{ PanelWidth: number; P return null; } // hide the decorations if the parent chooses to hide it or if the document itself hides it - const hideResizers = seldoc.props.hideResizeHandles || seldoc.rootDoc.hideResizeHandles || seldoc.rootDoc._isGroup; - const hideTitle = seldoc.props.hideDecorationTitle || seldoc.rootDoc.hideDecorationTitle; - const hideDocumentButtonBar = seldoc.props.hideDocumentButtonBar || seldoc.rootDoc.hideDocumentButtonBar; + const hideResizers = seldoc.props.hideResizeHandles || seldoc.rootDoc.hideResizeHandles || seldoc.rootDoc._isGroup || this._isRounding || this._isRotating; + const hideTitle = seldoc.props.hideDecorationTitle || seldoc.rootDoc.hideDecorationTitle || this._isRounding || this._isRotating; + const hideDocumentButtonBar = seldoc.props.hideDocumentButtonBar || seldoc.rootDoc.hideDocumentButtonBar || this._isRounding || + this._isRotating; // if multiple documents have been opened at the same time, then don't show open button const hideOpenButton = - seldoc.props.hideOpenButton || seldoc.rootDoc.hideOpenButton || SelectionManager.Views().some(docView => docView.props.Document._stayInCollection || docView.props.Document.isGroup || docView.props.Document.hideOpenButton); + seldoc.props.hideOpenButton || seldoc.rootDoc.hideOpenButton || SelectionManager.Views().some(docView => docView.props.Document._stayInCollection || docView.props.Document.isGroup || docView.props.Document.hideOpenButton) || this._isRounding || this._isRotating; const hideDeleteButton = + this._isRounding || + this._isRotating || seldoc.props.hideDeleteButton || seldoc.rootDoc.hideDeleteButton || SelectionManager.Views().some(docView => { const collectionAcl = docView.props.ContainingCollectionView ? GetEffectiveAcl(docView.props.ContainingCollectionDoc?.[DataSym]) : AclEdit; return docView.rootDoc.stayInCollection || (collectionAcl !== AclAdmin && collectionAcl !== AclEdit && GetEffectiveAcl(docView.rootDoc) !== AclAdmin); }); + const topBtn = (key: string, icon: string, pointerDown: undefined | ((e: React.PointerEvent) => void), click: undefined | ((e: any) => void), title: string) => ( {title}
} placement="top">
{hideDeleteButton ?
: topBtn('close', this.hasIcons ? 'times' : 'window-maximize', undefined, e => this.onCloseClick(this.hasIcons ? true : undefined), 'Close')} - {titleArea} + {hideTitle ? null : titleArea} {hideOpenButton ? null : topBtn('open', 'external-link-alt', this.onMaximizeDown, undefined, 'Open in Tab (ctrl: as alias, shift: in new collection)')} {hideResizers ? null : ( -
+ <>
e.preventDefault()} />
e.preventDefault()} />
e.preventDefault()} /> @@ -700,18 +706,23 @@ export class DocumentDecorations extends React.Component<{ PanelWidth: number; P
e.preventDefault()} />
e.preventDefault()} /> - {seldoc.props.renderDepth <= 1 || !seldoc.props.ContainingCollectionView ? null : topBtn('selector', 'arrow-alt-circle-up', undefined, this.onSelectorClick, 'tap to select containing document')} - {useRotation && ( -
e.preventDefault()}> - {'⟲'} -
- )} -
+ )} + + {useRotation && ( +
e.preventDefault()}> + {'⟲'} +
+ )} + + {useRounding && ( +
e.preventDefault()} /> -
+ }} className={`documentDecorations-borderRadius`} onPointerDown={this.onRadiusDown} onContextMenu={e => e.preventDefault()} + /> )} {hideDocumentButtonBar ? null : ( -- cgit v1.2.3-70-g09d2 From b8c89d70a5ae5373e84d95647e302017011dfa53 Mon Sep 17 00:00:00 2001 From: Geireann Lindfield Roberts <60007097+geireann@users.noreply.github.com> Date: Mon, 4 Jul 2022 12:59:59 -0700 Subject: updated start location of border radius --- src/client/views/DocumentDecorations.scss | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src') diff --git a/src/client/views/DocumentDecorations.scss b/src/client/views/DocumentDecorations.scss index af4ceb0b5..b490278c3 100644 --- a/src/client/views/DocumentDecorations.scss +++ b/src/client/views/DocumentDecorations.scss @@ -107,6 +107,8 @@ $resizeHandler: 8px; .documentDecorations-borderRadius { position: absolute; border-radius: 100%; + left: 3px; + top: 23px; background: $medium-gray; height: 10; width: 10; -- cgit v1.2.3-70-g09d2 From ab6aaa10e1ee4f465bf328e15e1f612fa94318d2 Mon Sep 17 00:00:00 2001 From: Geireann Lindfield Roberts <60007097+geireann@users.noreply.github.com> Date: Wed, 6 Jul 2022 15:57:21 -0700 Subject: edting -> editing --- src/client/views/DocumentDecorations.tsx | 37 ++++++++++++++++++++++---------- 1 file changed, 26 insertions(+), 11 deletions(-) (limited to 'src') diff --git a/src/client/views/DocumentDecorations.tsx b/src/client/views/DocumentDecorations.tsx index 336ec9c83..9544c588b 100644 --- a/src/client/views/DocumentDecorations.tsx +++ b/src/client/views/DocumentDecorations.tsx @@ -50,7 +50,7 @@ export class DocumentDecorations extends React.Component<{ PanelWidth: number; P @observable private _accumulatedTitle = ''; @observable private _titleControlString: string = '#title'; - @observable private _edtingTitle = false; + @observable private _editingTitle = false; @observable private _hidden = false; @observable public AddToSelection = false; // if Shift is pressed, then this should be set so that clicking on the selection background is ignored so overlapped documents can be added to the selection set. @observable public Interacting = false; @@ -66,7 +66,7 @@ export class DocumentDecorations extends React.Component<{ PanelWidth: number; P DocumentDecorations.Instance = this; reaction( () => SelectionManager.Views().slice(), - action(docs => (this._edtingTitle = false)) + action(docs => (this._editingTitle = false)) ); } @@ -93,7 +93,7 @@ export class DocumentDecorations extends React.Component<{ PanelWidth: number; P @action titleBlur = () => { - this._edtingTitle = false; + this._editingTitle = false; if (this._accumulatedTitle.startsWith('#') || this._accumulatedTitle.startsWith('=')) { this._titleControlString = this._accumulatedTitle; } else if (this._titleControlString.startsWith('#')) { @@ -147,8 +147,8 @@ export class DocumentDecorations extends React.Component<{ PanelWidth: number; P e => this.onBackgroundMove(true, e), e => {}, action(e => { - !this._edtingTitle && (this._accumulatedTitle = this._titleControlString.startsWith('#') ? this.selectionTitle : this._titleControlString); - this._edtingTitle = true; + !this._editingTitle && (this._accumulatedTitle = this._titleControlString.startsWith('#') ? this.selectionTitle : this._titleControlString); + this._editingTitle = true; this._keyinput.current && setTimeout(this._keyinput.current.focus); }) ); @@ -320,12 +320,29 @@ export class DocumentDecorations extends React.Component<{ PanelWidth: number; P if (selectedInk.length) { angle && InkStrokeProperties.Instance.rotateInk(selectedInk, -angle, centerPoint); } else { - SelectionManager.Views().forEach(dv => (dv.rootDoc._jitterRotation = NumCast(dv.rootDoc._jitterRotation) - (angle * 180) / Math.PI)); + SelectionManager.Views().forEach(dv => { + const oldRotation = NumCast(dv.rootDoc._jitterRotation); + // Rotation between -360 and 360 + let newRotation = (oldRotation - (angle * 180) / Math.PI) % 360; + + const diff = Math.round(newRotation / 45) - newRotation / 45 + if (diff < .05) { + console.log('show lines'); + } + dv.rootDoc._jitterRotation = newRotation; + }); } return false; }, // moveEvent action(() => { - console.log('up') + SelectionManager.Views().forEach(dv => { + const oldRotation = NumCast(dv.rootDoc._jitterRotation); + const diff = Math.round(oldRotation / 45) - oldRotation / 45 + if (diff < .05) { + let newRotation = Math.round(oldRotation / 45) * 45; + dv.rootDoc._jitterRotation = newRotation; + } + }) this._isRotating = false; rotateUndo?.end(); UndoManager.FilterBatches(['data', 'x', 'y', 'width', 'height']); @@ -619,7 +636,7 @@ export class DocumentDecorations extends React.Component<{ PanelWidth: number; P ); const colorScheme = StrCast(CurrentUserUtils.ActiveDashboard?.colorScheme); - const titleArea = hideTitle ? null : this._edtingTitle ? ( + const titleArea = hideTitle ? null : this._editingTitle ? (
e.preventDefault()} -- cgit v1.2.3-70-g09d2