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

mol-plugin: wip

parent ffbf1010
No related branches found
No related tags found
No related merge requests found
...@@ -8,7 +8,7 @@ export * from './behavior/behavior' ...@@ -8,7 +8,7 @@ export * from './behavior/behavior'
import * as StaticState from './behavior/static/state' import * as StaticState from './behavior/static/state'
import * as StaticRepresentation from './behavior/static/representation' import * as StaticRepresentation from './behavior/static/representation'
import * as StaticCamera from './behavior/static/representation' import * as StaticCamera from './behavior/static/camera'
import * as DynamicRepresentation from './behavior/dynamic/representation' import * as DynamicRepresentation from './behavior/dynamic/representation'
......
...@@ -5,6 +5,23 @@ ...@@ -5,6 +5,23 @@
*/ */
import { PluginContext } from 'mol-plugin/context'; import { PluginContext } from 'mol-plugin/context';
import { PluginCommands } from 'mol-plugin/command';
import { PluginStateObject as SO } from '../../state/objects';
export function registerDefault(ctx: PluginContext) { export function registerDefault(ctx: PluginContext) {
Reset(ctx);
} }
export function Reset(ctx: PluginContext) {
PluginCommands.Camera.Reset.subscribe(ctx, () => {
const sel = ctx.state.data.select(q => q.root.subtree().ofType(SO.Molecule.Structure));
if (!sel.length) return;
const center = (sel[0].obj! as SO.Molecule.Structure).data.boundary.sphere.center;
ctx.canvas3d.camera.setState({ target: center });
ctx.canvas3d.requestDraw(true);
// TODO
// ctx.canvas3d.resetCamera();
})
}
\ No newline at end of file
...@@ -5,8 +5,11 @@ ...@@ -5,8 +5,11 @@
*/ */
import * as State from './command/state'; import * as State from './command/state';
import * as Camera from './command/camera';
export * from './command/command'; export * from './command/command';
export const PluginCommands = { export const PluginCommands = {
State State,
Camera
} }
\ No newline at end of file
/**
* Copyright (c) 2018 mol* contributors, licensed under MIT, See LICENSE file for more info.
*
* @author David Sehnal <david.sehnal@gmail.com>
*/
import { PluginCommand } from './command';
export const Reset = PluginCommand<{}>({ isImmediate: true });
\ No newline at end of file
...@@ -116,10 +116,6 @@ export class PluginContext { ...@@ -116,10 +116,6 @@ export class PluginContext {
return PluginCommands.State.Update.dispatch(this, { state, tree }); return PluginCommands.State.Update.dispatch(this, { state, tree });
} }
_test_createState(id: string) {
this.runTask(this.state.data.apply(CreateStructureFromPDBe, { id }));
}
private initEvents() { private initEvents() {
merge(this.events.state.data.object.created, this.events.state.behavior.object.created).subscribe(o => { merge(this.events.state.data.object.created, this.events.state.behavior.object.created).subscribe(o => {
if (!SO.isBehavior(o.obj)) return; if (!SO.isBehavior(o.obj)) return;
...@@ -140,15 +136,6 @@ export class PluginContext { ...@@ -140,15 +136,6 @@ export class PluginContext {
}); });
} }
_test_centerView() {
const sel = this.state.data.select(q => q.root.subtree().ofType(SO.Molecule.Structure.type));
if (!sel.length) return;
const center = (sel[0].obj! as SO.Molecule.Structure).data.boundary.sphere.center;
this.canvas3d.camera.setState({ target: center });
this.canvas3d.requestDraw(true);
}
constructor() { constructor() {
this.initEvents(); this.initEvents();
this.initBuiltInBehavior(); this.initBuiltInBehavior();
......
...@@ -12,7 +12,7 @@ export const PluginReactContext = React.createContext(void 0 as any as PluginCon ...@@ -12,7 +12,7 @@ export const PluginReactContext = React.createContext(void 0 as any as PluginCon
export abstract class PluginComponent<P = {}, S = {}, SS = {}> extends React.Component<P, S, SS> { export abstract class PluginComponent<P = {}, S = {}, SS = {}> extends React.Component<P, S, SS> {
static contextType = PluginReactContext; static contextType = PluginReactContext;
readonly context: PluginContext; readonly plugin: PluginContext;
private subs: Subscription[] | undefined = void 0; private subs: Subscription[] | undefined = void 0;
...@@ -30,6 +30,7 @@ export abstract class PluginComponent<P = {}, S = {}, SS = {}> extends React.Com ...@@ -30,6 +30,7 @@ export abstract class PluginComponent<P = {}, S = {}, SS = {}> extends React.Com
constructor(props: P, context?: any) { constructor(props: P, context?: any) {
super(props, context); super(props, context);
this.plugin = context;
if (this.init) this.init(); if (this.init) this.init();
} }
} }
\ No newline at end of file
...@@ -17,18 +17,16 @@ export class Controls extends PluginComponent<{ }, { }> { ...@@ -17,18 +17,16 @@ export class Controls extends PluginComponent<{ }, { }> {
private _snap: any = void 0; private _snap: any = void 0;
private getSnapshot = () => { private getSnapshot = () => {
this._snap = this.context.state.getSnapshot(); this._snap = this.plugin.state.getSnapshot();
console.log(btoa(JSON.stringify(this._snap))); console.log(btoa(JSON.stringify(this._snap)));
} }
private setSnapshot = () => { private setSnapshot = () => {
if (!this._snap) return; if (!this._snap) return;
this.context.state.setSnapshot(this._snap); this.plugin.state.setSnapshot(this._snap);
} }
render() { render() {
return <div> return <div>
<button onClick={() => this.context._test_centerView()}>Center View</button><br />
<hr />
<button onClick={this.getSnapshot}>Get Snapshot</button> <button onClick={this.getSnapshot}>Get Snapshot</button>
<button onClick={this.setSnapshot}>Set Snapshot</button> <button onClick={this.setSnapshot}>Set Snapshot</button>
</div>; </div>;
...@@ -40,16 +38,16 @@ export class _test_TrajectoryControls extends PluginComponent { ...@@ -40,16 +38,16 @@ export class _test_TrajectoryControls extends PluginComponent {
render() { render() {
return <div> return <div>
<b>Trajectory: </b> <b>Trajectory: </b>
<button onClick={() => PluginCommands.State.ApplyAction.dispatch(this.context, { <button onClick={() => PluginCommands.State.ApplyAction.dispatch(this.plugin, {
state: this.context.state.data, state: this.plugin.state.data,
action: UpdateTrajectory.create({ action: 'advance', by: -1 }) action: UpdateTrajectory.create({ action: 'advance', by: -1 })
})}>&lt;&lt;</button> })}>&lt;&lt;</button>
<button onClick={() => PluginCommands.State.ApplyAction.dispatch(this.context, { <button onClick={() => PluginCommands.State.ApplyAction.dispatch(this.plugin, {
state: this.context.state.data, state: this.plugin.state.data,
action: UpdateTrajectory.create({ action: 'reset' }) action: UpdateTrajectory.create({ action: 'reset' })
})}>Reset</button> })}>Reset</button>
<button onClick={() => PluginCommands.State.ApplyAction.dispatch(this.context, { <button onClick={() => PluginCommands.State.ApplyAction.dispatch(this.plugin, {
state: this.context.state.data, state: this.plugin.state.data,
action: UpdateTrajectory.create({ action: 'advance', by: +1 }) action: UpdateTrajectory.create({ action: 'advance', by: +1 })
})}>&gt;&gt;</button><br /> })}>&gt;&gt;</button><br />
</div> </div>
...@@ -67,7 +65,7 @@ export class _test_ApplyAction extends PluginComponent<{ nodeRef: Transform.Ref, ...@@ -67,7 +65,7 @@ export class _test_ApplyAction extends PluginComponent<{ nodeRef: Transform.Ref,
if (!p || !p.default) return {}; if (!p || !p.default) return {};
const obj = this.getObj(); const obj = this.getObj();
if (!obj.obj) return {}; if (!obj.obj) return {};
return p.default(obj.obj, this.context); return p.default(obj.obj, this.plugin);
} }
private getParamDef() { private getParamDef() {
...@@ -75,12 +73,12 @@ export class _test_ApplyAction extends PluginComponent<{ nodeRef: Transform.Ref, ...@@ -75,12 +73,12 @@ export class _test_ApplyAction extends PluginComponent<{ nodeRef: Transform.Ref,
if (!p || !p.controls) return {}; if (!p || !p.controls) return {};
const obj = this.getObj(); const obj = this.getObj();
if (!obj.obj) return {}; if (!obj.obj) return {};
return p.controls(obj.obj, this.context); return p.controls(obj.obj, this.plugin);
} }
private create() { private create() {
console.log('Apply Action', this.state.params); console.log('Apply Action', this.state.params);
PluginCommands.State.ApplyAction.dispatch(this.context, { PluginCommands.State.ApplyAction.dispatch(this.plugin, {
state: this.props.state, state: this.props.state,
action: this.props.action.create(this.state.params), action: this.props.action.create(this.state.params),
ref: this.props.nodeRef ref: this.props.nodeRef
...@@ -130,12 +128,12 @@ export class _test_UpdateTransform extends PluginComponent<{ state: State, nodeR ...@@ -130,12 +128,12 @@ export class _test_UpdateTransform extends PluginComponent<{ state: State, nodeR
const src = this.getCell(cell.sourceRef); const src = this.getCell(cell.sourceRef);
if (!src || !src.obj) return void 0; if (!src || !src.obj) return void 0;
return def.params.controls(src.obj, this.context); return def.params.controls(src.obj, this.plugin);
} }
private update() { private update() {
console.log(this.props.nodeRef, this.state.params); console.log(this.props.nodeRef, this.state.params);
this.context.updateTransform(this.props.state, this.props.nodeRef, this.state.params); this.plugin.updateTransform(this.props.state, this.props.nodeRef, this.state.params);
} }
// componentDidMount() { // componentDidMount() {
......
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
import * as React from 'react'; import * as React from 'react';
import { PluginContext } from '../context'; import { PluginContext } from '../context';
import { StateTree } from './state-tree'; import { StateTree } from './state-tree';
import { Viewport } from './viewport'; import { Viewport, ViewportControls } from './viewport';
import { Controls, _test_UpdateTransform, _test_ApplyAction, _test_TrajectoryControls } from './controls'; import { Controls, _test_UpdateTransform, _test_ApplyAction, _test_TrajectoryControls } from './controls';
import { PluginComponent, PluginReactContext } from './base'; import { PluginComponent, PluginReactContext } from './base';
import { merge } from 'rxjs'; import { merge } from 'rxjs';
...@@ -27,6 +27,7 @@ export class Plugin extends React.Component<{ plugin: PluginContext }, {}> { ...@@ -27,6 +27,7 @@ export class Plugin extends React.Component<{ plugin: PluginContext }, {}> {
<div style={{ position: 'absolute', left: '10px', top: '10px', height: '100%', color: 'white' }}> <div style={{ position: 'absolute', left: '10px', top: '10px', height: '100%', color: 'white' }}>
<_test_TrajectoryControls /> <_test_TrajectoryControls />
</div> </div>
<ViewportControls />
</div> </div>
<div style={{ position: 'absolute', width: '300px', right: '0', height: '100%', padding: '10px' }}> <div style={{ position: 'absolute', width: '300px', right: '0', height: '100%', padding: '10px' }}>
<_test_CurrentObject /> <_test_CurrentObject />
...@@ -41,23 +42,23 @@ export class Plugin extends React.Component<{ plugin: PluginContext }, {}> { ...@@ -41,23 +42,23 @@ export class Plugin extends React.Component<{ plugin: PluginContext }, {}> {
export class _test_CurrentObject extends PluginComponent { export class _test_CurrentObject extends PluginComponent {
componentDidMount() { componentDidMount() {
let current: State.ObjectEvent | undefined = void 0; let current: State.ObjectEvent | undefined = void 0;
this.subscribe(merge(this.context.behaviors.state.data.currentObject, this.context.behaviors.state.behavior.currentObject), o => { this.subscribe(merge(this.plugin.behaviors.state.data.currentObject, this.plugin.behaviors.state.behavior.currentObject), o => {
current = o; current = o;
this.forceUpdate() this.forceUpdate()
}); });
this.subscribe(this.context.events.state.data.object.updated, ({ ref, state }) => { this.subscribe(this.plugin.events.state.data.object.updated, ({ ref, state }) => {
if (!current || current.ref !== ref && current.state !== state) return; if (!current || current.ref !== ref && current.state !== state) return;
this.forceUpdate(); this.forceUpdate();
}); });
} }
render() { render() {
const current = this.context.behaviors.state.data.currentObject.value; const current = this.plugin.behaviors.state.data.currentObject.value;
const ref = current.ref; const ref = current.ref;
// const n = this.props.plugin.state.data.tree.nodes.get(ref)!; // const n = this.props.plugin.state.data.tree.nodes.get(ref)!;
const obj = this.context.state.data.cells.get(ref)!; const obj = this.plugin.state.data.cells.get(ref)!;
const type = obj && obj.obj ? obj.obj.type : void 0; const type = obj && obj.obj ? obj.obj.type : void 0;
......
...@@ -28,7 +28,7 @@ export class StateTree extends PluginComponent<{ state: State }, { }> { ...@@ -28,7 +28,7 @@ export class StateTree extends PluginComponent<{ state: State }, { }> {
export class StateTreeNode extends PluginComponent<{ nodeRef: string, state: State }, { }> { export class StateTreeNode extends PluginComponent<{ nodeRef: string, state: State }, { }> {
componentDidMount() { componentDidMount() {
this.subscribe(merge(this.context.events.state.data.object.cellState, this.context.events.state.behavior.object.cellState), o => { this.subscribe(merge(this.plugin.events.state.data.object.cellState, this.plugin.events.state.behavior.object.cellState), o => {
if (o.ref === this.props.nodeRef && o.state === this.props.state) this.forceUpdate(); if (o.ref === this.props.nodeRef && o.state === this.props.state) this.forceUpdate();
}); });
} }
...@@ -39,7 +39,7 @@ export class StateTreeNode extends PluginComponent<{ nodeRef: string, state: Sta ...@@ -39,7 +39,7 @@ export class StateTreeNode extends PluginComponent<{ nodeRef: string, state: Sta
const remove = <>[<a href='#' onClick={e => { const remove = <>[<a href='#' onClick={e => {
e.preventDefault(); e.preventDefault();
PluginCommands.State.RemoveObject.dispatch(this.context, { state: this.props.state, ref: this.props.nodeRef }); PluginCommands.State.RemoveObject.dispatch(this.plugin, { state: this.props.state, ref: this.props.nodeRef });
}}>X</a>]</> }}>X</a>]</>
let label: any; let label: any;
...@@ -47,13 +47,13 @@ export class StateTreeNode extends PluginComponent<{ nodeRef: string, state: Sta ...@@ -47,13 +47,13 @@ export class StateTreeNode extends PluginComponent<{ nodeRef: string, state: Sta
const name = (n.transformer.definition.display && n.transformer.definition.display.name) || n.transformer.definition.name; const name = (n.transformer.definition.display && n.transformer.definition.display.name) || n.transformer.definition.name;
label = <><b>{cell.status}</b> <a href='#' onClick={e => { label = <><b>{cell.status}</b> <a href='#' onClick={e => {
e.preventDefault(); e.preventDefault();
PluginCommands.State.SetCurrentObject.dispatch(this.context, { state: this.props.state, ref: this.props.nodeRef }); PluginCommands.State.SetCurrentObject.dispatch(this.plugin, { state: this.props.state, ref: this.props.nodeRef });
}}>{name}</a>: <i>{cell.errorText}</i></>; }}>{name}</a>: <i>{cell.errorText}</i></>;
} else { } else {
const obj = cell.obj as PluginStateObject.Any; const obj = cell.obj as PluginStateObject.Any;
label = <><a href='#' onClick={e => { label = <><a href='#' onClick={e => {
e.preventDefault(); e.preventDefault();
PluginCommands.State.SetCurrentObject.dispatch(this.context, { state: this.props.state, ref: this.props.nodeRef }); PluginCommands.State.SetCurrentObject.dispatch(this.plugin, { state: this.props.state, ref: this.props.nodeRef });
}}>{obj.label}</a> {obj.description ? <small>{obj.description}</small> : void 0}</>; }}>{obj.label}</a> {obj.description ? <small>{obj.description}</small> : void 0}</>;
} }
...@@ -62,14 +62,14 @@ export class StateTreeNode extends PluginComponent<{ nodeRef: string, state: Sta ...@@ -62,14 +62,14 @@ export class StateTreeNode extends PluginComponent<{ nodeRef: string, state: Sta
const expander = <> const expander = <>
[<a href='#' onClick={e => { [<a href='#' onClick={e => {
e.preventDefault(); e.preventDefault();
PluginCommands.State.ToggleExpanded.dispatch(this.context, { state: this.props.state, ref: this.props.nodeRef }); PluginCommands.State.ToggleExpanded.dispatch(this.plugin, { state: this.props.state, ref: this.props.nodeRef });
}}>{cellState.isCollapsed ? '+' : '-'}</a>] }}>{cellState.isCollapsed ? '+' : '-'}</a>]
</>; </>;
const visibility = <> const visibility = <>
[<a href='#' onClick={e => { [<a href='#' onClick={e => {
e.preventDefault(); e.preventDefault();
PluginCommands.State.ToggleVisibility.dispatch(this.context, { state: this.props.state, ref: this.props.nodeRef }); PluginCommands.State.ToggleVisibility.dispatch(this.plugin, { state: this.props.state, ref: this.props.nodeRef });
}}>{cellState.isHidden ? 'H' : 'V'}</a>] }}>{cellState.isHidden ? 'H' : 'V'}</a>]
</>; </>;
......
...@@ -9,11 +9,24 @@ import * as React from 'react'; ...@@ -9,11 +9,24 @@ import * as React from 'react';
import { ButtonsType } from 'mol-util/input/input-observer'; import { ButtonsType } from 'mol-util/input/input-observer';
import { Canvas3dIdentifyHelper } from 'mol-plugin/util/canvas3d-identify'; import { Canvas3dIdentifyHelper } from 'mol-plugin/util/canvas3d-identify';
import { PluginComponent } from './base'; import { PluginComponent } from './base';
import { PluginCommands } from 'mol-plugin/command';
interface ViewportState { interface ViewportState {
noWebGl: boolean noWebGl: boolean
} }
export class ViewportControls extends PluginComponent {
resetCamera = () => {
PluginCommands.Camera.Reset.dispatch(this.plugin, {});
}
render() {
return <div style={{ position: 'absolute', right: '10px', top: '10px', height: '100%', color: 'white' }}>
<button onClick={this.resetCamera}>Reset Camera</button>
</div>
}
}
export class Viewport extends PluginComponent<{ }, ViewportState> { export class Viewport extends PluginComponent<{ }, ViewportState> {
private container: HTMLDivElement | null = null; private container: HTMLDivElement | null = null;
private canvas: HTMLCanvasElement | null = null; private canvas: HTMLCanvasElement | null = null;
...@@ -23,19 +36,19 @@ export class Viewport extends PluginComponent<{ }, ViewportState> { ...@@ -23,19 +36,19 @@ export class Viewport extends PluginComponent<{ }, ViewportState> {
}; };
private handleResize = () => { private handleResize = () => {
this.context.canvas3d.handleResize(); this.plugin.canvas3d.handleResize();
} }
componentDidMount() { componentDidMount() {
if (!this.canvas || !this.container || !this.context.initViewer(this.canvas, this.container)) { if (!this.canvas || !this.container || !this.plugin.initViewer(this.canvas, this.container)) {
this.setState({ noWebGl: true }); this.setState({ noWebGl: true });
} }
this.handleResize(); this.handleResize();
const canvas3d = this.context.canvas3d; const canvas3d = this.plugin.canvas3d;
this.subscribe(canvas3d.input.resize, this.handleResize); this.subscribe(canvas3d.input.resize, this.handleResize);
const idHelper = new Canvas3dIdentifyHelper(this.context, 15); const idHelper = new Canvas3dIdentifyHelper(this.plugin, 15);
this.subscribe(canvas3d.input.move, ({x, y, inside, buttons}) => { this.subscribe(canvas3d.input.move, ({x, y, inside, buttons}) => {
if (!inside || buttons) { return; } if (!inside || buttons) { return; }
......
...@@ -51,8 +51,8 @@ namespace StateSelection { ...@@ -51,8 +51,8 @@ namespace StateSelection {
withStatus(s: StateObjectCell.Status): Builder; withStatus(s: StateObjectCell.Status): Builder;
subtree(): Builder; subtree(): Builder;
children(): Builder; children(): Builder;
ofType(t: StateObject.Type): Builder; ofType(t: StateObject.Ctor): Builder;
ancestorOfType(t: StateObject.Type): Builder; ancestorOfType(t: StateObject.Ctor): Builder;
select(state: State): CellSeq select(state: State): CellSeq
} }
...@@ -184,7 +184,7 @@ namespace StateSelection { ...@@ -184,7 +184,7 @@ namespace StateSelection {
} }
registerModifier('ofType', ofType); registerModifier('ofType', ofType);
export function ofType(b: Selector, t: StateObject.Type) { return filter(b, n => n.obj ? n.obj.type === t : false); } export function ofType(b: Selector, t: StateObject.Ctor) { return filter(b, n => n.obj ? n.obj.type === t.type : false); }
registerModifier('ancestorOfType', ancestorOfType); registerModifier('ancestorOfType', ancestorOfType);
export function ancestorOfType(b: Selector, types: StateObject.Ctor[]) { return unique(mapEntity(b, (n, s) => findAncestorOfType(s.tree, s.cells, n.transform.ref, types))); } export function ancestorOfType(b: Selector, types: StateObject.Ctor[]) { return unique(mapEntity(b, (n, s) => findAncestorOfType(s.tree, s.cells, n.transform.ref, types))); }
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment