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

mol-plugin: custom param editors for transformers, assembly fix

parent 87fee7a9
No related branches found
No related tags found
No related merge requests found
......@@ -29,6 +29,7 @@ import { VolumeRepresentationRegistry } from 'mol-repr/volume/registry';
import { PLUGIN_VERSION, PLUGIN_VERSION_DATE } from './version';
import { PluginLayout } from './layout';
import { List } from 'immutable';
import { StateTransformParameters } from './ui/state/common';
export class PluginContext {
private disposed = false;
......@@ -87,6 +88,7 @@ export class PluginContext {
}
readonly customModelProperties = new CustomPropertyRegistry();
readonly customParamEditors = new Map<string, StateTransformParameters.Class>();
initViewer(canvas: HTMLCanvasElement, container: HTMLDivElement) {
try {
......@@ -136,6 +138,16 @@ export class PluginContext {
this.disposed = true;
}
applyTransform(state: State, a: Transform.Ref, transformer: Transformer, params: any) {
const tree = state.tree.build().to(a).apply(transformer, params);
return PluginCommands.State.Update.dispatch(this, { state, tree });
}
updateTransform(state: State, a: Transform.Ref, params: any) {
const tree = state.build().to(a).update(params);
return PluginCommands.State.Update.dispatch(this, { state, tree });
}
private initBuiltInBehavior() {
BuiltInPluginBehaviors.State.registerDefault(this);
BuiltInPluginBehaviors.Representation.registerDefault(this);
......@@ -145,7 +157,7 @@ export class PluginContext {
merge(this.state.dataState.events.log, this.state.behaviorState.events.log).subscribe(e => this.events.log.next(e));
}
async initBehaviors() {
private async initBehaviors() {
const tree = this.state.behaviorState.tree.build();
for (const b of this.spec.behaviors) {
......@@ -155,20 +167,18 @@ export class PluginContext {
await this.runTask(this.state.behaviorState.updateTree(tree, true));
}
initDataActions() {
private initDataActions() {
for (const a of this.spec.actions) {
this.state.dataState.actions.add(a.action);
}
}
applyTransform(state: State, a: Transform.Ref, transformer: Transformer, params: any) {
const tree = state.tree.build().to(a).apply(transformer, params);
return PluginCommands.State.Update.dispatch(this, { state, tree });
}
private initCustomParamEditors() {
if (!this.spec.customParamEditors) return;
updateTransform(state: State, a: Transform.Ref, params: any) {
const tree = state.build().to(a).update(params);
return PluginCommands.State.Update.dispatch(this, { state, tree });
for (const [t, e] of this.spec.customParamEditors) {
this.customParamEditors.set(t.id, e);
}
}
constructor(public spec: PluginSpec) {
......@@ -178,6 +188,7 @@ export class PluginContext {
this.initBehaviors();
this.initDataActions();
this.initCustomParamEditors();
this.lociLabels = new LociLabelManager(this);
......
......@@ -14,6 +14,7 @@ export { PluginSpec }
interface PluginSpec {
actions: PluginSpec.Action[],
behaviors: PluginSpec.Behavior[],
customParamEditors?: [StateAction | Transformer, StateTransformParameters.Class][]
initialLayout?: PluginLayoutStateProps
}
......
......@@ -140,17 +140,19 @@ const StructureAssemblyFromModel = PluginStateTransform.BuiltIn({
apply({ a, params }, plugin: PluginContext) {
return Task.create('Build Assembly', async ctx => {
const model = a.data;
const id = params.id;
const asm = ModelSymmetry.findAssembly(model, id || '');
let id = params.id;
let asm = ModelSymmetry.findAssembly(model, id || '');
if (!!id && id !== 'deposited' && !asm) throw new Error(`Assembly '${id}' not found`);
const base = Structure.ofModel(model);
if (!asm) {
if ((id && !asm) || model.symmetry.assemblies.length === 0) {
if (!!id && id !== 'deposited') plugin.log.warn(`Model '${a.label}' has no assembly, returning deposited structure.`);
const label = { label: a.data.label, description: structureDesc(base) };
return new SO.Molecule.Structure(base, label);
}
asm = model.symmetry.assemblies[0];
id = asm.id;
const s = await StructureSymmetry.buildAssembly(base, id!).runInContext(ctx);
const props = { label: `Assembly ${id}`, description: structureDesc(s) };
return new SO.Molecule.Structure(s, props);
......
......@@ -41,6 +41,7 @@ class ApplyActionContol extends TransformContolBase<ApplyActionContol.Props, App
});
}
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; }
canApply() { return !this.state.error && !this.state.busy; }
canAutoApply() { return false; }
......
......@@ -102,6 +102,7 @@ abstract class TransformContolBase<P, S extends TransformContolBase.ControlState
abstract getInfo(): StateTransformParameters.Props['info'];
abstract getHeader(): Transformer.Definition['display'];
abstract canApply(): boolean;
abstract getTransformerId(): string;
abstract canAutoApply(newParams: any): boolean;
abstract applyText(): string;
abstract isUpdate(): boolean;
......@@ -170,13 +171,18 @@ abstract class TransformContolBase<P, S extends TransformContolBase.ControlState
const display = this.getHeader();
const tId = this.getTransformerId();
const ParamEditor: StateTransformParameters.Class = this.plugin.customParamEditors.has(tId)
? this.plugin.customParamEditors.get(tId)!
: StateTransformParameters;
return <div className='msp-transform-wrapper'>
<div className='msp-transform-header'>
<button className='msp-btn msp-btn-block' onClick={this.toggleExpanded}>{display.name}</button>
{!this.state.isCollapsed && <button className='msp-btn msp-btn-link msp-transform-default-params' onClick={this.setDefault} disabled={this.state.busy} style={{ float: 'right'}} title='Set default params'></button>}
</div>
{!this.state.isCollapsed && <>
<StateTransformParameters info={info} events={this.events} params={this.state.params} isDisabled={this.state.busy} />
<ParamEditor info={info} events={this.events} params={this.state.params} isDisabled={this.state.busy} />
<div className='msp-transform-apply-wrap'>
<button className='msp-btn msp-btn-block msp-transform-refresh msp-form-control' title='Refresh params' onClick={this.refresh} disabled={this.state.busy || this.state.isInitial}>
......
......@@ -28,6 +28,7 @@ namespace UpdateTransformContol {
class UpdateTransformContol extends TransformContolBase<UpdateTransformContol.Props, UpdateTransformContol.ComponentState> {
applyAction() { return this.plugin.updateTransform(this.props.state, this.props.transform.ref, this.state.params); }
getInfo() { return this._getInfo(this.props.transform); }
getTransformerId() { return this.props.transform.transformer.id; }
getHeader() { return this.props.transform.transformer.definition.display; }
canApply() { return !this.state.error && !this.state.busy && !this.state.isInitial; }
applyText() { return this.canApply() ? 'Update' : 'Nothing to Update'; }
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment