mirror of
https://github.com/xibyte/jsketcher
synced 2025-12-06 08:25:19 +01:00
edit constraint by its constraint annotation, dbl click or from the menu
This commit is contained in:
parent
583400ab33
commit
38cffa5e6c
17 changed files with 92 additions and 38 deletions
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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}>
|
||||
|
|
|
|||
|
|
@ -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}
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
}
|
||||
|
|
@ -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);
|
||||
})
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
];
|
||||
|
||||
|
|
|
|||
|
|
@ -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),
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
});
|
||||
}
|
||||
};
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -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) {
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -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) {}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue