diff options
author | bobzel <zzzman@gmail.com> | 2024-11-05 10:22:31 -0500 |
---|---|---|
committer | bobzel <zzzman@gmail.com> | 2024-11-05 10:22:31 -0500 |
commit | 10a89be0b184df2750a4b3eceb48db205cb83e95 (patch) | |
tree | c0284ee35e1e1f075db11c14ab837c9c5c950c5f /src | |
parent | 4ab636e338a11e8153d43adddb0e0d3e6bad57ec (diff) |
fixed display of where control point will be added on mouse moves. fixed clickable ink line to not select fill area unless its actually painted. added end cap properties to ink stroke ui. enabled more than one ink stroke to show editable control points when multiselected.
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} /> |