jsketcher/web/app/sketcher/components/SketcherOperationWizard.jsx
2020-03-19 01:44:05 -07:00

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();
}
}