mirror of
https://github.com/xibyte/jsketcher
synced 2025-12-09 18:02:50 +01:00
146 lines
No EOL
4 KiB
JavaScript
146 lines
No EOL
4 KiB
JavaScript
import {FormContext, Group} from "../../cad/craft/wizard/components/form/Form";
|
|
import Entity from "../../cad/craft/wizard/components/form/EntityList";
|
|
import React, {useContext, useEffect, useState} from "react";
|
|
import Window from "ui/components/Window";
|
|
import Stack from "ui/components/Stack";
|
|
import ButtonGroup from "ui/components/controls/ButtonGroup";
|
|
import Button from "ui/components/controls/Button";
|
|
import {SketcherAppContext} from "./SketcherApp";
|
|
import {useStreamWithUpdater} from "../../../../modules/ui/effects";
|
|
|
|
|
|
export default function SketcherOperationWizard({}) {
|
|
|
|
const [state, setState] = useState(null);
|
|
|
|
const {viewer} = useContext(SketcherAppContext);
|
|
const [operationRequest, setRequest] = useStreamWithUpdater(streams => streams.ui.$wizardRequest);
|
|
|
|
const onClose = () => setRequest(null);
|
|
const apply = () => {
|
|
onClose();
|
|
operationRequest && operationRequest.onApply(state.params);
|
|
};
|
|
|
|
useEffect(() => {
|
|
if (operationRequest) {
|
|
|
|
const schema = operationRequest.schema;
|
|
|
|
const params = {};
|
|
const indexedSchema = {};
|
|
|
|
for (let field of schema) {
|
|
indexedSchema[field.name] = field;
|
|
|
|
if (field.type === 'selection') {
|
|
params[field.name] = [];
|
|
}
|
|
}
|
|
|
|
setState({params});
|
|
|
|
viewer.customSelectionHandler = (objects, exclusive) => {
|
|
|
|
setState(state => {
|
|
const {activeParam, params} = state;
|
|
let selectionParam = activeParam;
|
|
if (!(indexedSchema[selectionParam] && indexedSchema[selectionParam].type === 'selection')) {
|
|
let found = schema.find(f => f.type === 'selection');
|
|
if (!found) {
|
|
return state;
|
|
}
|
|
selectionParam = found.name;
|
|
}
|
|
|
|
return {
|
|
activeParam,
|
|
params: {
|
|
...params,
|
|
[selectionParam]: exclusive ? objects : [...params[selectionParam], ...objects]
|
|
}
|
|
}
|
|
});
|
|
};
|
|
|
|
return () => {
|
|
viewer.customSelectionHandler = null;
|
|
viewer.withdrawGlobal();
|
|
viewer.refresh();
|
|
}
|
|
}
|
|
}, [operationRequest]);
|
|
|
|
useEffect(() => {
|
|
if (state && operationRequest) {
|
|
syncSelection(state.params, operationRequest.schema, viewer);
|
|
}
|
|
});
|
|
|
|
if (!operationRequest || !state) {
|
|
return null;
|
|
}
|
|
const {title, schema} = operationRequest;
|
|
const {activeParam, params} = state;
|
|
|
|
let formContext = {
|
|
data: params,
|
|
activeParam,
|
|
setActiveParam: (activeParam) => setState(state => ({...state, activeParam})),
|
|
updateParam: (name, val) => setState(state => ({...state, params: {...params, name: val}}))
|
|
};
|
|
|
|
|
|
|
|
return <Window initWidth={250} initLeft={255} initTop={5}
|
|
title={title.toUpperCase()}
|
|
onClose={onClose}>
|
|
|
|
<FormContext.Provider value={formContext}>
|
|
|
|
<Group>
|
|
{schema.map(field => {
|
|
return (() => {
|
|
|
|
if (field.type === 'selection') {
|
|
return <Entity name={field.name} title={field.title || field.name}
|
|
placeholder={schema.placeholder} key={field.name}
|
|
onEntityEnter={obj => {viewer.capture('highlight2', [obj], true); viewer.refresh();}}
|
|
onEntityLeave={obj => {viewer.withdrawAll('highlight2');viewer.refresh();}}
|
|
entityRenderer={entityRenderer}/>
|
|
}
|
|
})();
|
|
|
|
})}
|
|
</Group>
|
|
|
|
</FormContext.Provider>
|
|
<Stack>
|
|
<ButtonGroup>
|
|
<Button onClick={onClose}>Cancel</Button>
|
|
<Button type='accent' onClick={apply}>OK</Button>
|
|
</ButtonGroup>
|
|
</Stack>
|
|
</Window>;
|
|
|
|
|
|
}
|
|
|
|
function entityRenderer(obj) {
|
|
|
|
return obj.simpleClassName + ':' + obj.id;
|
|
|
|
}
|
|
|
|
|
|
function syncSelection(params, schema, viewer) {
|
|
for (let field of schema) {
|
|
if (field.type === 'selection') {
|
|
const selection = params[field.name];
|
|
if (selection) {
|
|
viewer.capture(field.capture, selection, true);
|
|
}
|
|
}
|
|
viewer.refresh();
|
|
}
|
|
} |