operation history wizard

This commit is contained in:
Val Erastov 2018-01-30 19:41:05 -08:00
parent f3f7354033
commit 9e5933fbe1
14 changed files with 107 additions and 31 deletions

View file

@ -26,7 +26,7 @@ export default class Folder extends React.Component{
let {title, closable, children} = this.props;
return <div className={ls.root}>
<div className={ls.title} onClick={closable ? this.tweakClose : null}>
<Fa fw icon={this.isClosed() ? 'chevron-right' : 'chevron-down'}/>
<span className={ls.handle}><Fa fw icon={this.isClosed() ? 'chevron-right' : 'chevron-down'}/></span>
{title}
</div>
{!this.isClosed() && children}

View file

@ -1,5 +1,17 @@
@import "~ui/styles/theme";
.root {
background-color: @bg-color-alt;
}
.title {
border-bottom: 1px solid @border-color;
background-color: @bg-color;
padding: 0.3rem 0.6rem;
line-height: 1.7;
}
.handle {
font-size: 0.8rem;
color: @font-color-suppressed;
}

View file

@ -6,10 +6,6 @@ export default function Stack({children}) {
return <div className={ls.root}>{children}</div>
}
Window.defaultProps = {
type: 'neutral',
};

View file

@ -2,8 +2,7 @@
@import '../styles/mixins';
.root > * {
border-bottom: 1px solid @border-color;
padding: 0.3rem 0.6rem;
line-height: 1.7;
}

View file

@ -16,7 +16,7 @@ export default class Window extends React.Component {
}
render() {
let {initWidth, initLeft, initTop, children, title, minimizable, onClose, ...props} = this.props;
let {initWidth, initLeft, initTop, setFocus, children, title, minimizable, onClose, ...props} = this.props;
return <div className={ls.root} style={this.getStyle()} {...props} ref={this.keepRef}>
<div className={ls.bar + ' disable-selection'}>
<div><b>{title.toUpperCase()}</b></div>
@ -41,8 +41,8 @@ export default class Window extends React.Component {
}
componentDidMount() {
if (this.props.onFocus) {
this.props.onFocus(this.el);
if (this.props.setFocus) {
this.props.setFocus(this.el);
} else {
this.el.focus();
}

View file

@ -2,5 +2,4 @@
display: flex;
justify-content: space-between;
align-items: baseline;
line-height: 1.5;
}

View file

@ -1,8 +1,12 @@
import React from 'react';
import PropTypes from 'prop-types';
export default function connect(WrappedComponent, tokens, {staticProps, mapProps, mapActions, mapSelfProps}) {
export default function connect(WrappedComponent, tokens, config) {
if (!config) {
config = DEFAULT_CONFIG;
}
let {staticProps, mapProps, mapActions, mapSelfProps} = config;
mapProps = createMapper(mapProps);
mapActions = mapActions || function({dispatch}) {
@ -82,6 +86,8 @@ function createMapper(mapper, comp) {
return mapper;
}
const DEFAULT_CONFIG = {};
export function DEFAULT_MAPPER(state) {
let props = {};
state.forEach(stateItem => Object.assign(props, stateItem));

View file

@ -14,8 +14,8 @@ export function activate({bus, services}) {
bus.subscribe(TOKENS.HISTORY_POINTER, (pointer) => {
let history = getHistory();
if (pointer < history.length) {
resetInternal(history.slice(0, pointer));
bus.setState(TOKENS.MODIFICATIONS, {pointer});
reset(history.slice(0, pointer));
}
});
@ -29,12 +29,22 @@ export function activate({bus, services}) {
});
}
function reset(modifications) {
function resetInternal(modifications) {
services.cadRegistry.reset();
for (let request of modifications) {
modifyInternal(request);
}
bus.dispatch(TOKENS.DID_MODIFY);
}
function reset(modifications) {
resetInternal(modifications);
bus.updateState(TOKENS.MODIFICATIONS,
() => {
return {
history: modifications,
pointer: modifications.length - 1
}
});
}
function modifyInternal(request) {
@ -56,7 +66,6 @@ export function activate({bus, services}) {
pointer: pointer++
}
});
bus.dispatch(TOKENS.DID_MODIFY);
}
services.craft = {
@ -67,5 +76,4 @@ export function activate({bus, services}) {
export const TOKENS = {
MODIFICATIONS: createToken('craft', 'modifications'),
HISTORY_POINTER: createToken('craft', 'historyPointer'),
DID_MODIFY: createToken('craft', 'didModify')
};

View file

@ -1,10 +1,44 @@
import React from 'react';
import PropTypes from 'prop-types';
import Stack from 'ui/components/Stack';
import connect from 'ui/connect';
import Fa from 'ui/components/Fa';
import ImgIcon from 'ui/components/ImgIcon';
import ls from './OperationHistory.less'
export default class OperationHistory extends React.Component {
import {TOKENS as CRAFT_TOKENS} from '../../craft/craftPlugin';
render() {
return <div >
OperationHistory
</div>
function OperationHistory({history, pointer}, {services: {operation: operationService}}) {
return <Stack>
{history.map(({type, params}, index) => {
let {appearance, paramsInfo} = getDescriptor(type, operationService.registry);
return <div key={index} className={ls.item}>
{appearance && <ImgIcon url={appearance.icon32} size={16}/>}
<span>{type} {paramsInfo && paramsInfo(params)} </span>
<span className={ls.buttons}>
<Fa icon='edit' />
<Fa icon='image' />
<Fa icon='remove' />
</span>
</div>;
})}
</Stack>;
}
const EMPTY_DESCRIPTOR = {};
function getDescriptor(type, registry) {
let descriptor = registry[type];
if (!descriptor) {
descriptor = EMPTY_DESCRIPTOR;
}
}
return descriptor;
}
OperationHistory.contextTypes = {
services: PropTypes.object
};
export default connect(OperationHistory, CRAFT_TOKENS.MODIFICATIONS);

View file

@ -0,0 +1,8 @@
.item {
word-wrap: break-word;
word-break: break-all;
}
.buttons {
}

View file

@ -0,0 +1,16 @@
import React, {Fragment} from 'react';
import ObjectExplorer from './ObjectExplorer';
import OperationHistory from './OperationHistory';
import Folder from 'ui/components/Folder';
import Fa from '../../../../../modules/ui/components/Fa';
export default function PartPanel() {
return <Fragment>
<Folder title={<span> <Fa fw icon='cubes' /> Model</span>}>
<ObjectExplorer/>
</Folder>
<Folder title={<span> <Fa fw icon='history' /> Modifications</span>}>
<OperationHistory/>
</Folder>
</Fragment>;
}

View file

@ -2,12 +2,11 @@ import React from 'react';
import PlugableControlBar from './PlugableControlBar';
import ls from './View3d.less';
import ObjectExplorer from './ObjectExplorer';
import OperationHistory from './OperationHistory';
import Abs from 'ui/components/Abs';
import {PlugableToolbarLeft, PlugableToolbarLeftSecondary, PlugableToolbarRight} from "./PlugableToolbar";
import {PlugableToolbarLeft, PlugableToolbarLeftSecondary, PlugableToolbarRight} from './PlugableToolbar';
import UISystem from './UISystem';
import WizardManager from './wizard/WizardManager';
import PartPanel from './PartPanel';
export default class View3d extends React.Component {
@ -20,8 +19,7 @@ export default class View3d extends React.Component {
render() {
return <UISystem className={ls.root} >
<div className={ls.sideBar}>
<ObjectExplorer/>
<OperationHistory/>
<PartPanel />
</div>
<div className={ls.viewer} id='viewer-container'>
<Abs left='0.8em' top='0.8em' className={ls.leftToolbarGroup}>

View file

@ -44,7 +44,7 @@ export default class Wizard extends React.Component {
title={title}
onClose={this.onClose}
onKeyDown={this.onKeyDown}
onFocus={this.focusFirstInput}>
setFocus={this.focusFirstInput}>
<Stack >
{metadata.map(([name, type, , params], index) => {
return <Field key={index}>

View file

@ -59,7 +59,7 @@ export function activate({bus, services}) {
services.appTabs.show(sceneFace.id, 'Sketch ' + sceneFace.id, 'sketcher.html#' + sketchURL);
}
bus.subscribe(CRAFT_TOKENS.DID_MODIFY, updateAllSketches);
bus.subscribe(CRAFT_TOKENS.MODIFICATIONS, updateAllSketches);
services.sketcher = {
sketchFace, updateAllSketches