Skip to content
Snippets Groups Projects
Commit f69670c3 authored by David Sehnal's avatar David Sehnal
Browse files

mol-plugin: action select control

parent a0b537ef
No related branches found
No related tags found
No related merge requests found
......@@ -101,3 +101,23 @@
}
}
}
.msp-action-select {
position: relative;
select {
padding-left: $control-spacing + $row-height;
}
option:first-child {
color: color-lower-contrast($font-color, 15%);
}
> .msp-icon {
display: block;
top: 0;
left: $control-spacing;
position: absolute;
line-height: $row-height;
}
}
\ No newline at end of file
......@@ -224,3 +224,7 @@
.msp-icon-flow-cascade:before {
content: "\e8d8";
}
.msp-icon-flow-tree:before {
content: "\e8da";
}
\ No newline at end of file
......@@ -14,7 +14,7 @@ import { PluginContext } from '../context';
import { PluginReactContext, PluginUIComponent } from './base';
import { LociLabels, TrajectoryViewportControls, StateSnapshotViewportControls, AnimationViewportControls, StructureToolsWrapper } from './controls';
import { StateSnapshots } from './state';
import { StateObjectActions } from './state/actions';
import { StateObjectActionSelect } from './state/actions';
import { StateTree } from './state/tree';
import { BackgroundTaskProgress } from './task';
import { Viewport, ViewportControls } from './viewport';
......@@ -254,7 +254,11 @@ export class CurrentObject extends PluginUIComponent {
</div>
<UpdateTransformControl state={current.state} transform={transform} customHeader='none' />
</> }
{cell.status === 'ok' && <StateObjectActions state={current.state} nodeRef={ref} initiallyCollapsed />}
{cell.status === 'ok' &&
<StateObjectActionSelect state={current.state} nodeRef={ref} plugin={this.plugin} />
}
{/* <StateObjectActions state={current.state} nodeRef={ref} initiallyCollapsed />} */}
</>;
}
}
\ No newline at end of file
......@@ -7,8 +7,9 @@
import * as React from 'react';
import { PluginUIComponent } from '../base';
import { ApplyActionControl } from './apply-action';
import { State } from '../../../mol-state';
import { State, StateAction } from '../../../mol-state';
import { Icon } from '../controls/common';
import { PluginContext } from '../../context';
export class StateObjectActions extends PluginUIComponent<{ state: State, nodeRef: string, hideHeader?: boolean, initiallyCollapsed?: boolean }> {
get current() {
......@@ -16,9 +17,9 @@ export class StateObjectActions extends PluginUIComponent<{ state: State, nodeRe
}
componentDidMount() {
this.subscribe(this.plugin.state.behavior.currentObject, o => {
this.forceUpdate();
});
// this.subscribe(this.plugin.state.behavior.currentObject, o => {
// this.forceUpdate();
// });
this.subscribe(this.plugin.events.state.object.updated, ({ ref, state }) => {
const current = this.current;
......@@ -42,3 +43,76 @@ export class StateObjectActions extends PluginUIComponent<{ state: State, nodeRe
</div>;
}
}
interface StateObjectActionSelectProps {
plugin: PluginContext,
state: State,
nodeRef: string
}
interface StateObjectActionSelectState {
state: State,
nodeRef: string,
version: string,
actions: readonly StateAction[],
currentActionIndex: number
}
function createStateObjectActionSelectState(props: StateObjectActionSelectProps): StateObjectActionSelectState {
const cell = props.state.cells.get(props.nodeRef)!;
const actions = props.state.actions.fromCell(cell, props.plugin);
(actions as StateAction[]).sort((a, b) => a.definition.display.name < b.definition.display.name ? -1 : a.definition.display.name === b.definition.display.name ? 0 : 1);
return {
state: props.state,
nodeRef: props.nodeRef,
version: cell.transform.version,
actions,
currentActionIndex: -1
}
}
export class StateObjectActionSelect extends PluginUIComponent<StateObjectActionSelectProps, StateObjectActionSelectState> {
state = createStateObjectActionSelectState(this.props);
get current() {
return this.plugin.state.behavior.currentObject.value;
}
static getDerivedStateFromProps(props: StateObjectActionSelectProps, state: StateObjectActionSelectState) {
if (state.state !== props.state || state.nodeRef !== props.nodeRef) return createStateObjectActionSelectState(props);
const cell = props.state.cells.get(props.nodeRef)!;
if (cell.transform.version !== state.version) return createStateObjectActionSelectState(props);
return null;
}
componentDidMount() {
this.subscribe(this.plugin.events.state.object.updated, ({ ref, state }) => {
const current = this.current;
if (current.ref !== ref || current.state !== state) return;
this.setState(createStateObjectActionSelectState(this.props));
});
}
onChange = (e: React.ChangeEvent<HTMLSelectElement>) => {
this.setState({ currentActionIndex: parseInt(e.target.value, 10) });
}
render() {
const actions = this.state.actions;
if (actions.length === 0) return null;
const current = this.state.currentActionIndex >= 0 && actions[this.state.currentActionIndex];
const title = current ? current.definition.display.description : 'Select Action';
return <>
<div className='msp-contol-row msp-action-select'>
<select className='msp-form-control' title={title} value={this.state.currentActionIndex} onChange={this.onChange} style={{ fontWeight: 'bold' }}>
<option key={-1} value={-1} style={{ color: '#999' }}>[ Select Action ]</option>
{actions.map((a, i) => <option key={i} value={i}>{a.definition.display.name}</option>)}
</select>
<Icon name='flow-tree' />
</div>
{current && <ApplyActionControl key={current.id} plugin={this.plugin} state={this.props.state} action={current} nodeRef={this.props.nodeRef} hideHeader />}
</>;
}
}
\ No newline at end of file
......@@ -19,6 +19,7 @@ namespace ApplyActionControl {
nodeRef: StateTransform.Ref,
state: State,
action: StateAction,
hideHeader?: boolean,
initiallyCollapsed?: boolean
}
......@@ -42,7 +43,7 @@ class ApplyActionControl extends TransformControlBase<ApplyActionControl.Props,
}
getInfo() { return this._getInfo(this.props.nodeRef, this.props.state.transforms.get(this.props.nodeRef).version); }
getTransformerId() { return this.props.state.transforms.get(this.props.nodeRef).transformer.id; }
getHeader() { return this.props.action.definition.display; }
getHeader() { return this.props.hideHeader ? 'none' : this.props.action.definition.display; }
canApply() { return !this.state.error && !this.state.busy; }
canAutoApply() { return false; }
applyText() { return 'Apply'; }
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment