diff --git a/src/mol-canvas3d/canvas3d.ts b/src/mol-canvas3d/canvas3d.ts index c2cf9bee32d6238cf22f86842e99c27dae62374d..f164a4edb4ab97aa5dc3c49ca8b6e64fc3c9be40 100644 --- a/src/mol-canvas3d/canvas3d.ts +++ b/src/mol-canvas3d/canvas3d.ts @@ -46,7 +46,7 @@ export const Canvas3DParams = { // showBoundingSpheres: PD.Boolean(false, { description: 'Show bounding spheres of render objects.' }), // }) } -export type Canvas3DParams = typeof Canvas3DParams +export type Canvas3DParams = PD.Values<typeof Canvas3DParams> export { Canvas3D } @@ -77,17 +77,17 @@ interface Canvas3D { readonly camera: Camera downloadScreenshot: () => void getImageData: (variant: RenderVariant) => ImageData - setProps: (props: Partial<PD.Values<Canvas3DParams>>) => void + setProps: (props: Partial<Canvas3DParams>) => void /** Returns a copy of the current Canvas3D instance props */ - readonly props: PD.Values<Canvas3DParams> + readonly props: Canvas3DParams readonly input: InputObserver readonly stats: RendererStats dispose: () => void } namespace Canvas3D { - export function create(canvas: HTMLCanvasElement, container: Element, props: Partial<PD.Values<Canvas3DParams>> = {}): Canvas3D { + export function create(canvas: HTMLCanvasElement, container: Element, props: Partial<Canvas3DParams> = {}): Canvas3D { const p = { ...PD.getDefaultValues(Canvas3DParams), ...props } const reprRenderObjects = new Map<Representation.Any, Set<RenderObject>>() @@ -370,7 +370,7 @@ namespace Canvas3D { } }, didDraw, - setProps: (props: Partial<PD.Values<Canvas3DParams>>) => { + setProps: (props: Partial<Canvas3DParams>) => { if (props.cameraMode !== undefined && props.cameraMode !== camera.state.mode) { camera.setState({ mode: props.cameraMode }) } diff --git a/src/mol-plugin/behavior.ts b/src/mol-plugin/behavior.ts index 0f5238d0f3a8068e45a5755bcc39e9929e6e6968..98010eb2a0f55405bcabeb769dc9fd2b40e467bb 100644 --- a/src/mol-plugin/behavior.ts +++ b/src/mol-plugin/behavior.ts @@ -9,6 +9,7 @@ export * from './behavior/behavior' import * as StaticState from './behavior/static/state' import * as StaticRepresentation from './behavior/static/representation' import * as StaticCamera from './behavior/static/camera' +import * as StaticMisc from './behavior/static/misc' import * as DynamicRepresentation from './behavior/dynamic/representation' import * as DynamicCamera from './behavior/dynamic/camera' @@ -16,7 +17,8 @@ import * as DynamicCamera from './behavior/dynamic/camera' export const BuiltInPluginBehaviors = { State: StaticState, Representation: StaticRepresentation, - Camera: StaticCamera + Camera: StaticCamera, + Misc: StaticMisc } export const PluginBehaviors = { diff --git a/src/mol-plugin/behavior/static/misc.ts b/src/mol-plugin/behavior/static/misc.ts new file mode 100644 index 0000000000000000000000000000000000000000..aff031d5bd5b855955024898797cec2cb409d626 --- /dev/null +++ b/src/mol-plugin/behavior/static/misc.ts @@ -0,0 +1,19 @@ +/** + * Copyright (c) 2018 mol* contributors, licensed under MIT, See LICENSE file for more info. + * + * @author David Sehnal <david.sehnal@gmail.com> + */ + +import { PluginContext } from 'mol-plugin/context'; +import { PluginCommands } from 'mol-plugin/command'; + +export function registerDefault(ctx: PluginContext) { + Canvas3DSetSettings(ctx); +} + +export function Canvas3DSetSettings(ctx: PluginContext) { + PluginCommands.Canvas3D.SetSettings.subscribe(ctx, e => { + ctx.canvas3d.setProps(e.settings); + ctx.events.canvad3d.settingsUpdated.next(); + }) +} diff --git a/src/mol-plugin/command.ts b/src/mol-plugin/command.ts index 880d8d053971d169d06c5a406cebed20d33c215d..34dee15c61b4b8c41202ea72f7efc25e78ff9a79 100644 --- a/src/mol-plugin/command.ts +++ b/src/mol-plugin/command.ts @@ -8,6 +8,7 @@ import { Camera } from 'mol-canvas3d/camera'; import { PluginCommand } from './command/base'; import { Transform, State } from 'mol-state'; import { StateAction } from 'mol-state/action'; +import { Canvas3DParams } from 'mol-canvas3d/canvas3d'; export * from './command/base'; @@ -41,5 +42,8 @@ export const PluginCommands = { Apply: PluginCommand<{ id: string }>({ isImmediate: true }), Clear: PluginCommand<{}>({ isImmediate: true }), } + }, + Canvas3D: { + SetSettings: PluginCommand<{ settings: Partial<Canvas3DParams> }>({ isImmediate: true }) } } \ No newline at end of file diff --git a/src/mol-plugin/context.ts b/src/mol-plugin/context.ts index fb6cf4760b2fc90af3680a87570b23dc2d3a9a60..38bf3dcb9beaa5bb85d40c82e7ba32d5ea232599 100644 --- a/src/mol-plugin/context.ts +++ b/src/mol-plugin/context.ts @@ -51,6 +51,9 @@ export class PluginContext { task: this.tasks.events, labels: { highlight: this.ev<{ entries: ReadonlyArray<LociLabelEntry> }>() + }, + canvad3d: { + settingsUpdated: this.ev() } }; @@ -75,7 +78,7 @@ export class PluginContext { initViewer(canvas: HTMLCanvasElement, container: HTMLDivElement) { try { (this.canvas3d as Canvas3D) = Canvas3D.create(canvas, container); - this.canvas3d.setProps({ backgroundColor: Color(0xFCFBF9) }); + PluginCommands.Canvas3D.SetSettings.dispatch(this, { settings: { backgroundColor: Color(0xFCFBF9) } }); this.canvas3d.animate(); return true; } catch (e) { @@ -116,6 +119,7 @@ export class PluginContext { BuiltInPluginBehaviors.State.registerDefault(this); BuiltInPluginBehaviors.Representation.registerDefault(this); BuiltInPluginBehaviors.Camera.registerDefault(this); + BuiltInPluginBehaviors.Misc.registerDefault(this); merge(this.state.dataState.events.log, this.state.behaviorState.events.log).subscribe(e => this.events.log.next(e)); } diff --git a/src/mol-plugin/state.ts b/src/mol-plugin/state.ts index a23cbcf603795ba1014fcc6d65810867d3955cc6..db6cf78e92ed1dd00141a05640cd6c43099ff8c5 100644 --- a/src/mol-plugin/state.ts +++ b/src/mol-plugin/state.ts @@ -13,6 +13,7 @@ import { PluginStateSnapshotManager } from './state/snapshots'; import { RxEventHelper } from 'mol-util/rx-event-helper'; import { Canvas3DParams } from 'mol-canvas3d/canvas3d'; import { ParamDefinition } from 'mol-util/param-definition'; +import { PluginCommands } from './command'; export { PluginState } class PluginState { @@ -54,7 +55,7 @@ class PluginState { async setSnapshot(snapshot: PluginState.Snapshot) { await this.plugin.runTask(this.behaviorState.setSnapshot(snapshot.behaviour)); await this.plugin.runTask(this.dataState.setSnapshot(snapshot.data)); - this.plugin.canvas3d.setProps(snapshot.canvas3d.viewport || { }) + PluginCommands.Canvas3D.SetSettings.dispatch(this.plugin, { settings: snapshot.canvas3d.viewport || { } }); this.cameraSnapshots.setStateSnapshot(snapshot.cameraSnapshots); this.plugin.canvas3d.camera.setState(snapshot.canvas3d.camera); this.plugin.canvas3d.requestDraw(true); @@ -91,7 +92,7 @@ namespace PluginState { cameraSnapshots: CameraSnapshotManager.StateSnapshot, canvas3d: { camera: Camera.Snapshot, - viewport: ParamDefinition.Values<Canvas3DParams> + viewport: Canvas3DParams } } } diff --git a/src/mol-plugin/ui/viewport.tsx b/src/mol-plugin/ui/viewport.tsx index 2ca33df42104d6c9ced5d3e2944af44653575e79..e33496c5852dddff1df0bd75fc88945beb170217 100644 --- a/src/mol-plugin/ui/viewport.tsx +++ b/src/mol-plugin/ui/viewport.tsx @@ -33,24 +33,35 @@ export class ViewportControls extends PluginComponent { e.currentTarget.blur(); } - hideSettings = () => { - this.setState({ isSettingsExpanded: false }); - } + // hideSettings = () => { + // this.setState({ isSettingsExpanded: false }); + // } setSettings = (p: { param: PD.Base<any>, name: string, value: any }) => { - this.plugin.canvas3d.setProps({ [p.name]: p.value }) - this.setState({ settings: this.plugin.canvas3d.props }) + PluginCommands.Canvas3D.SetSettings.dispatch(this.plugin, { settings: { [p.name]: p.value } }); + } + + componentDidMount() { + if (this.plugin.canvas3d) { + this.setState({ settings: this.plugin.canvas3d.props }); + } + + this.subscribe(this.plugin.events.canvad3d.settingsUpdated, e => { + this.setState({ settings: this.plugin.canvas3d.props }); + }); } render() { + // TODO: show some icons dimmed etc.. return <div className={'msp-viewport-controls'}> <div className='msp-viewport-controls-buttons'> - <button className='msp-btn msp-btn-link' title='Reset Camera' onClick={this.toggleSettingsExpanded}><span className='msp-icon msp-icon-settings'/></button> - <button className='msp-btn msp-btn-link' onClick={this.resetCamera}><span className='msp-icon msp-icon-reset-scene'/></button> + <button className='msp-btn msp-btn-link' onClick={this.toggleSettingsExpanded}><span className='msp-icon msp-icon-settings'/></button> + <button className='msp-btn msp-btn-link' title='Reset Camera' onClick={this.resetCamera}><span className='msp-icon msp-icon-reset-scene'/></button> </div> - <div onMouseLeave={this.hideSettings} className='msp-viewport-controls-scene-options' style={{ display: this.state.isSettingsExpanded ? 'block' : 'none' }}> + {this.state.isSettingsExpanded && + <div className='msp-viewport-controls-scene-options'> <ParameterControls params={Canvas3DParams} values={this.state.settings} onChange={this.setSettings} /> - </div> + </div>} </div> } }