edit constraint by its constraint annotation, dbl click or from the menu

This commit is contained in:
Val Erastov 2022-08-26 23:33:36 -07:00
parent 583400ab33
commit 38cffa5e6c
17 changed files with 92 additions and 38 deletions

View file

@ -14,7 +14,6 @@ export function GenericWizard({documentationLink, title, icon, left, top, classN
top?: number,
onCancel: () => any,
onOK: () => any,
onKeyDown?: (e) => any,
infoText?: any,
icon?: any
} & WindowProps ) {
@ -25,6 +24,8 @@ export function GenericWizard({documentationLink, title, icon, left, top, classN
title={(title||'').toUpperCase()}
icon={icon}
className={cx('mid-typography', className)}
onEscapePressed={onCancel}
onEnterPressed={onOK}
controlButtons={<>
<WindowControlButton title='help' onClick={(e) => DocumentationTopic$.next({
documentationLink: documentationLink,

View file

@ -29,6 +29,8 @@ export interface WindowProps {
props?: JSX.IntrinsicAttributes;
footer?: JSX.Element;
compact?: boolean;
onEscapePressed?: () => any,
onEnterPressed?: () => any
}
export default class Window extends React.Component<WindowProps> {
@ -47,9 +49,21 @@ export default class Window extends React.Component<WindowProps> {
const {initWidth, initHeight, initLeft, initTop, initRight, initBottom, centerScreen, setFocus, className, resizeCapturingBuffer,
resize, enableResize, children, title, icon, minimizable = false, onClose, controlButtons, footer, compact,
onEscapePressed, onEnterPressed,
onResize, ...props} = this.props;
return <div className={cx(ls.root, this.resizeConfig&&ls.mandatoryBorder, compact&&ls.compact, className)} {...props} ref={this.keepRef}>
const onKeyDown = e => {
switch (e.keyCode) {
case 27 :
onEscapePressed ? onEscapePressed() : onClose();
break;
case 13 :
onEnterPressed();
break;
}
};
return <div className={cx(ls.root, this.resizeConfig&&ls.mandatoryBorder, compact&&ls.compact, className)} {...props} ref={this.keepRef} onKeyDown={onKeyDown}>
<div className={ls.bar + ' disable-selection'} onMouseDown={this.startDrag} onMouseUp={this.stopDrag}>
<div className={ls.title}>{icon} <b>{title.toUpperCase()}</b></div>
<div className={ls.controlButtons}>

View file

@ -44,17 +44,6 @@ export default function Wizard(props: WizardProps) {
const error = state.error;
const onKeyDown = e => {
switch (e.keyCode) {
case 27 :
cancel();
break;
case 13 :
onOK();
break;
}
};
const focusFirstInput = el => {
if (props.noFocus) {
return;
@ -86,7 +75,6 @@ export default function Wizard(props: WizardProps) {
title={title}
icon={icon}
onClose={cancel}
onKeyDown={onKeyDown}
setFocus={focusFirstInput}
className='Wizard'
data-operation-id={operation.id}

View file

@ -14,7 +14,10 @@ export function activate(ctx) {
//to attach to a dom element: Mousetrap(domElement).bind(...
for (const action of Object.keys(keymap)) {
const dataProvider = getDataProvider(action, services);
Mousetrap.bind(keymap[action], () => ctx.actionService.run(action, dataProvider ? dataProvider() : undefined));
Mousetrap.bind(keymap[action], (e) => {
e.preventDefault();
ctx.actionService.run(action, dataProvider ? dataProvider() : undefined)
});
}
Mousetrap.bind('esc', services.menu.closeAll)
}

View file

@ -61,7 +61,7 @@ export function activate(ctx) {
const signature = ctx.expressionService.signature;
if (sketch && (!sketch.metadata || sketch.metadata.expressionsSignature !== signature)) {
try {
const viewer = new Viewer(headlessCanvas, IO);
const viewer = new Viewer(headlessCanvas, IO, {});
viewer.parametricManager.externalConstantResolver = ctx.expressionService.evaluateExpression;
// viewer.historyManager.init(savedSketch);
viewer.io._loadSketch(sketch);
@ -97,7 +97,7 @@ export function activate(ctx) {
if (sketch) {
try {
const viewer = new Viewer(headlessCanvas, IO);
const viewer = new Viewer(headlessCanvas, IO, {});
viewer.parametricManager.externalConstantResolver = ctx.expressionService.evaluateExpression;
// viewer.historyManager.init(savedSketch);

View file

@ -124,10 +124,6 @@ function atatchToToolStreams(context) {
function startReact(appCtx) {
const reactControls = document.getElementById('react-controls');
reactControls.onkeydown = e => {
e.stopPropagation();
// e.preventDefault();
};
ReactDOM.render(
<Scope><SketcherApp applicationContext={appCtx} /></Scope>,
reactControls

View file

@ -5,7 +5,7 @@ import {Segment} from "../shapes/segment";
import {isInstanceOf, matchAll, matchTypes} from "./matchUtils";
import {Arc} from "../shapes/arc";
import {FilletTool} from "../tools/fillet";
import {editConstraint as _editConstraint} from "../components/ConstraintEditor";
import {showConstraintEditorUI} from "../components/ConstraintEditor";
import {BezierCurve} from "../shapes/bezier-curve";
import {
AngleBetweenConstraintIcon,
@ -648,6 +648,6 @@ export default [
];
function editConstraint(ctx, constraint, onApply) {
_editConstraint(ctx.ui.$constraintEditRequest, constraint, onApply)
export function editConstraint(ctx, constraint, onApply) {
showConstraintEditorUI(ctx.ui.$constraintEditRequest, constraint, onApply)
}

View file

@ -1,5 +1,7 @@
import {BsTextareaT} from "react-icons/all";
import {BiPencil, BsTextareaT} from "react-icons/all";
import {Label} from "sketcher/shapes/label";
import {isConstraintAnnotation} from "sketcher/constr/constraintAnnotation";
import {editConstraint} from "sketcher/actions/constraintActions";
export default [
@ -36,6 +38,24 @@ export default [
},
{
id: 'EditConstraintFromItsAnnotation',
shortName: 'Edit Constraint',
kind: 'Misc',
description: 'Edit the constraint the annotation refers to',
icon: BiPencil,
selectionMatcher: {
selector: 'function',
match: (selection) => isConstraintAnnotation(selection[0])
},
invoke: (ctx) => {
const [obj] = ctx.viewer.selected;
editConstraint(ctx, obj.constraint, () => {
ctx.viewer.parametricManager.constraintUpdated(obj.constraint);
})
}
},
];

View file

@ -62,6 +62,8 @@ export function ConstraintEditor() {
};
return <Window initWidth={250} initLeft={5} initTop={5} title={constraint.schema.name} onClose={onCancel}
onEnterPressed={onApply}
onEscapePressed={onCancel}
onMouseEnter={highlight}
onMouseLeave={unHighlight}>
@ -104,7 +106,7 @@ export function ConstraintEditor() {
}
export function editConstraint(rqStream, constraint, onApply) {
export function showConstraintEditorUI(rqStream, constraint, onApply) {
rqStream.next({
constraint,
onCancel: () => rqStream.next(null),

View file

@ -3,7 +3,7 @@ import ls from './ConstraintExplorer.less';
import Fa from 'ui/components/Fa';
import {useStream} from "ui/effects";
import cx from 'classnames';
import {editConstraint} from "./ConstraintEditor";
import {showConstraintEditorUI} from "./ConstraintEditor";
import {NoIcon} from "../icons/NoIcon";
import {SketcherAppContext} from "./SketcherAppContext";
import {StageControl} from "./StageControl";
@ -50,9 +50,8 @@ export function ConstraintButton({prefix='', constraint: c, ...props}) {
const edit = (constraint) => {
if (constraint.editable) {
editConstraint(ui.$constraintEditRequest, constraint, () => {
viewer.parametricManager.revalidateConstraint(c);
viewer.parametricManager.invalidate();
showConstraintEditorUI(ui.$constraintEditRequest, constraint, () => {
viewer.parametricManager.constraintUpdated(c);
});
}
};

View file

@ -3,4 +3,12 @@ export interface ConstraintAnnotation<T> {
save(): T;
load(data: T);
isConstraintAnnotation: boolean;
}
export function isConstraintAnnotation(obj: any): obj is ConstraintAnnotation<any> {
return obj&&obj.isConstraintAnnotation === true;
}

View file

@ -290,6 +290,11 @@ class ParametricManager {
this.notify();
}
constraintUpdated(constraint) {
this.revalidateConstraint(constraint);
this.invalidate();
}
prepare(interactiveObjects) {
this.groundStage.prepare(interactiveObjects);
for (const stage of this.stages) {

View file

@ -7,6 +7,8 @@ export class AngleBetweenAnnotation extends AngleBetweenDimension implements Con
constraint: AlgNumConstraint;
isConstraintAnnotation = true;
constructor(a, b, constraint) {
super(a, b);
this.constraint = constraint;
@ -35,6 +37,8 @@ export class AngleAbsoluteAnnotation extends AngleBetweenDimension implements Co
constraint: AlgNumConstraint;
isConstraintAnnotation = true;
constructor(segment, constraint) {
super({
a: segment.a,
@ -100,6 +104,8 @@ export class LengthAnnotation extends LinearDimension implements ConstraintAnnot
constraint: AlgNumConstraint;
isConstraintAnnotation = true;
constructor(segment, constraint) {
super(segment.a, segment.b);
this.constraint = constraint;
@ -128,6 +134,8 @@ export class RadiusLengthAnnotation extends DiameterDimension implements Constra
constraint: AlgNumConstraint;
isConstraintAnnotation = true;
constructor(obj, constraint) {
super(obj);
this.constraint = constraint;

View file

@ -13,11 +13,7 @@ export function createAppContext() {
}
export function createEssentialAppContext(canvas) {
return {
viewer: new Viewer(canvas, IO),
const applicationContext = {
get actions() {
return getSketcherActionIndex();
},
@ -35,6 +31,8 @@ export function createEssentialAppContext(canvas) {
}));
}
};
applicationContext.viewer = new Viewer(canvas, IO, applicationContext);
return applicationContext;
}

View file

@ -1,5 +1,7 @@
import {Tool} from './tool'
import {GetShapeEditTool} from './edit-tools-map'
import {isConstraintAnnotation} from "sketcher/constr/constraintAnnotation";
import {editConstraint} from "sketcher/actions/constraintActions";
export class BasePanTool extends Tool {
@ -51,6 +53,15 @@ export class BasePanTool extends Tool {
this.startDragging(e);
}
dblclick() {
const [obj] = this.viewer.selected;
if (isConstraintAnnotation(obj)) {
editConstraint(this.viewer.applicationContext, obj.constraint, () => {
this.viewer.parametricManager.constraintUpdated(obj.constraint);
})
}
}
startDragging(e) {}
}

View file

@ -55,9 +55,11 @@ export class Viewer {
interactiveScale: number;
unscale: number;
customSelectionHandler: any;
applicationContext: any;
constructor(canvas, IO) {
constructor(canvas, IO, applicationContext) {
this.applicationContext = applicationContext;
this.presicion = 3;
this.canvas = canvas;
this.io = new IO(this);

View file

@ -20,11 +20,10 @@
<div style="width: 100%; height: calc(100% - 65px); display: flex;">
<div id="dock" class="panel b-right scroll" style="width: 245px; height: 100%; flex-shrink: 0;"></div>
<div id="viewer-container" style="background: #808080; overflow: hidden; height: 100%; position: relative; flex-grow: 1;">
<div id="react-controls"></div>
<div class="tool-hint" style="position: absolute; bottom: 5px; right: 5px;"></div>
<canvas width="300" height="300" id="viewer"></canvas>
<div id="react-controls" style="position: absolute; top: 0; right: 0; left: 0; height: 0;"></div>
</div>
<div id="right-toolbar" class="panel b-left scroll" style="height: 100%; flex-shrink: 0"></div>