diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/client/views/ComponentDecorations.tsx | 6 | ||||
-rw-r--r-- | src/client/views/DocumentDecorations.tsx | 10 | ||||
-rw-r--r-- | src/client/views/InkingStroke.tsx | 14 | ||||
-rw-r--r-- | src/client/views/PropertiesView.scss | 1 | ||||
-rw-r--r-- | src/client/views/PropertiesView.tsx | 33 |
5 files changed, 42 insertions, 22 deletions
diff --git a/src/client/views/ComponentDecorations.tsx b/src/client/views/ComponentDecorations.tsx index 929b549e0..28e9d9792 100644 --- a/src/client/views/ComponentDecorations.tsx +++ b/src/client/views/ComponentDecorations.tsx @@ -5,11 +5,7 @@ import { DocumentView } from './nodes/DocumentView'; @observer export class ComponentDecorations extends React.Component<{ boundsTop: number; boundsLeft: number }, { value: string }> { - // eslint-disable-next-line no-use-before-define - static Instance: ComponentDecorations; - render() { - const seldoc = DocumentView.Selected().lastElement(); - return seldoc?.ComponentView?.componentUI?.(this.props.boundsLeft, this.props.boundsTop) ?? null; + return DocumentView.Selected().map(seldoc => seldoc?.ComponentView?.componentUI?.(this.props.boundsLeft, this.props.boundsTop) ?? null); } } diff --git a/src/client/views/DocumentDecorations.tsx b/src/client/views/DocumentDecorations.tsx index 66043c033..492c2bda1 100644 --- a/src/client/views/DocumentDecorations.tsx +++ b/src/client/views/DocumentDecorations.tsx @@ -181,7 +181,13 @@ export class DocumentDecorations extends ObservableReactComponent<DocumentDecora }; onBackgroundDown = (e: React.PointerEvent) => { - setupMoveUpEvents(this, e, moveEv => this.onBackgroundMove(false, moveEv), emptyFunction, emptyFunction); + setupMoveUpEvents( + this, + e, + moveEv => this.onBackgroundMove(false, moveEv), + emptyFunction, + (clickEv, doubleTap) => doubleTap && DocumentView.Selected().some(dv => dv.Document.layout_isSvg) && (InkStrokeProperties.Instance._controlButton = true) + ); e.stopPropagation(); }; @action @@ -791,7 +797,7 @@ export class DocumentDecorations extends ObservableReactComponent<DocumentDecora transformOrigin, background: SnappingManager.ShiftKey ? undefined : 'yellow', pointerEvents: SnappingManager.ShiftKey || SnappingManager.IsResizing ? 'none' : 'all', - display: DocumentView.Selected().length <= 1 || hideDecorations ? 'none' : undefined, + display: DocumentView.Selected().length <= 1 || InkStrokeProperties.Instance._controlButton || hideDecorations ? 'none' : undefined, transform: `rotate(${rotation}deg)`, }} onPointerDown={this.onBackgroundDown} diff --git a/src/client/views/InkingStroke.tsx b/src/client/views/InkingStroke.tsx index 5199eb02b..f847db6c2 100644 --- a/src/client/views/InkingStroke.tsx +++ b/src/client/views/InkingStroke.tsx @@ -21,7 +21,7 @@ Most of the operations that can be performed on an InkStroke (eg delete a point, rotate, stretch) are implemented in the InkStrokeProperties helper class */ import { Property } from 'csstype'; -import { action, computed, IReactionDisposer, observable, reaction } from 'mobx'; +import { action, computed, IReactionDisposer, makeObservable, observable, reaction } from 'mobx'; import { observer } from 'mobx-react'; import * as React from 'react'; import { DashColor, returnFalse, setupMoveUpEvents } from '../../ClientUtils'; @@ -66,9 +66,14 @@ export class InkingStroke extends ViewBoxAnnotatableComponent<FieldViewProps>() private _handledClick = false; // flag denoting whether ink stroke has handled a psuedo-click onPointerUp so that the real onClick event can be stopPropagated private _disposers: { [key: string]: IReactionDisposer } = {}; + constructor(props: FieldViewProps) { + super(props); + makeObservable(this); + } + @observable _nearestSeg?: number = undefined; // nearest Bezier segment along the ink stroke to the cursor (used for displaying the Add Point highlight) @observable _nearestT?: number = undefined; // nearest t value within the nearest Bezier segment " - @observable _nearestScrPt?: { X: number; Y: number }; // nearst screen point on the ink stroke "" + @observable _nearestScrPt?: { X: number; Y: number } = { X: 0, Y: 0 }; // nearst screen point on the ink stroke "" componentDidMount() { this._props.setContentViewBox?.(this); @@ -155,6 +160,7 @@ export class InkingStroke extends ViewBoxAnnotatableComponent<FieldViewProps>() const wasSelected = InkStrokeProperties.Instance._currentPoint === controlIndex; const isEditing = InkStrokeProperties.Instance._controlButton && this._props.isSelected(); this.controlUndo = undefined; + this._nearestScrPt = undefined; setupMoveUpEvents( this, e, @@ -275,7 +281,7 @@ export class InkingStroke extends ViewBoxAnnotatableComponent<FieldViewProps>() .map(p => ({ X: p[0], Y: p[1] })); const { distance, nearestT, nearestSeg, nearestPt } = InkStrokeProperties.nearestPtToStroke(screenPts, { X: e.clientX, Y: e.clientY }); - if (distance < 40) { + if (distance < 40 && !e.buttons) { this._nearestT = nearestT; this._nearestSeg = nearestSeg; this._nearestScrPt = nearestPt; @@ -427,7 +433,7 @@ export class InkingStroke extends ViewBoxAnnotatableComponent<FieldViewProps>() StrCast(this.layoutDoc.stroke_lineJoin) as Property.StrokeLinejoin, StrCast(this.layoutDoc.stroke_lineCap) as Property.StrokeLinecap, StrCast(this.layoutDoc.stroke_bezier), - !closed || !fillColor || DashColor(fillColor).alpha() === 0 ? 'none' : fillColor, + 'none', startMarker, endMarker, markerScale, diff --git a/src/client/views/PropertiesView.scss b/src/client/views/PropertiesView.scss index a5e60b831..693c75ebf 100644 --- a/src/client/views/PropertiesView.scss +++ b/src/client/views/PropertiesView.scss @@ -508,6 +508,7 @@ display: flex; margin-bottom: 3px; margin-left: 4px; + justify-content: space-evenly; .arrows-head { display: flex; diff --git a/src/client/views/PropertiesView.tsx b/src/client/views/PropertiesView.tsx index c539b1d0a..10c2a9898 100644 --- a/src/client/views/PropertiesView.tsx +++ b/src/client/views/PropertiesView.tsx @@ -3,6 +3,7 @@ import { faAnchor, faArrowRight, faWindowMaximize } from '@fortawesome/free-soli import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; import { Checkbox, Tooltip } from '@mui/material'; import { Colors, EditableText, IconButton, NumberInput, Size, Slider, Toggle, ToggleType, Type } from 'browndash-components'; +import { Property } from 'csstype'; import { concat } from 'lodash'; import { IReactionDisposer, action, computed, makeObservable, observable, reaction } from 'mobx'; import { observer } from 'mobx-react'; @@ -830,11 +831,7 @@ export class PropertiesView extends ObservableReactComponent<PropertiesViewProps @computed get shapeHgt() { return NumCast(this.selectedDoc?._height); } // prettier-ignore set shapeHgt(value) { this.selectedDoc && (this.selectedDoc._height = Math.round(value * 100) / 100); } // prettier-ignore @computed get strokeThk(){ return NumCast(this.selectedStrokes.lastElement()?.[DocData].stroke_width); } // prettier-ignore - set strokeThk(value) { - this.selectedStrokes.forEach(doc => { - doc[DocData].stroke_width = Math.round(value * 100) / 100; - }); - } + set strokeThk(value) { this.selectedStrokes.forEach(doc => { doc[DocData].stroke_width = Math.round(value * 100) / 100; }); } // prettier-ignore @computed get hgtInput() { return this.inputBoxDuo( @@ -1025,7 +1022,13 @@ export class PropertiesView extends ObservableReactComponent<PropertiesViewProps doc[DocData].stroke_dash = value ? this._lastDash : undefined; }); } - @computed get widthStk() { return this.getField('stroke_width') || '1'; } // prettier-ignore + @computed get lineCapStk() { return (this.getField('stroke_lineCap') || 'round' ) as Property.StrokeLinecap; } // prettier-ignore + set lineCapStk(value) { + this.selectedStrokes.forEach(doc => { + doc[DocData].stroke_lineCap = value; + }); + } + @computed get widthStk() { return this.getField('stroke') || '1'; } // prettier-ignore set widthStk(value) { this.selectedStrokes.forEach(doc => { doc[DocData].stroke_width = Number(value); @@ -1127,7 +1130,6 @@ export class PropertiesView extends ObservableReactComponent<PropertiesViewProps <div className="arrows-head"> <div className="arrows-head-title">Arrow Head: </div> <input - key="markHead" className="arrows-head-input" type="checkbox" checked={this.markHead !== ''} @@ -1137,16 +1139,25 @@ export class PropertiesView extends ObservableReactComponent<PropertiesViewProps <div className="arrows-tail"> <div className="arrows-tail-title">Arrow End: </div> <input - key="markTail" className="arrows-tail-input" type="checkbox" checked={this.markTail !== ''} - onChange={undoable( - action(() => { this.markTail = this.markTail ? '' : 'arrow'; }) ,"change arrow tail" - )} + onChange={undoable(action(() => { this.markTail = this.markTail ? '' : 'arrow'; }) ,"change arrow tail")} /> </div> </div> + <div className="arrows"> + {["butt", "round", "square"].map(cap => + <div className="arrows-tail" key={cap}> + <div className="arrows-tail-title">{cap}</div> + <input + className="arrows-tail-input" + type="checkbox" + checked={this.lineCapStk === cap} + onChange={undoable(action(() => { this.lineCapStk = cap as Property.StrokeLinecap; }), `change lineCap ${cap}`)} + /> + </div>)} + </div> <div className="dashed"> <div className="dashed-title">Dashed Line:</div> <input key="markHead" className="dashed-input" type="checkbox" checked={this.dashdStk === '2'} onChange={this.changeDash} /> |