diff --git a/src/mol-plugin/component.ts b/src/mol-plugin/component.ts index fab609d81a056aa2604fc2252da0f604c34fe72e..3d15fcb180e8967f2379ce6e5566ef9d1f53a5b1 100644 --- a/src/mol-plugin/component.ts +++ b/src/mol-plugin/component.ts @@ -4,41 +4,38 @@ * @author David Sehnal <david.sehnal@gmail.com> */ -import { BehaviorSubject, Observable, Subject } from 'rxjs'; import { PluginContext } from './context'; import { shallowMergeArray } from 'mol-util/object'; +import { RxEventHelper } from 'mol-util/rx-event-helper'; export class PluginComponent<State> { - private _state: BehaviorSubject<State>; - private _updated = new Subject(); + private _ev: RxEventHelper; - updateState(...states: Partial<State>[]): boolean { - const latest = this.latestState; + protected get ev() { + return this._ev || (this._ev = RxEventHelper.create()); + } + + private _state: State; + + protected updateState(...states: Partial<State>[]): boolean { + const latest = this.state; const s = shallowMergeArray(latest, states); if (s !== latest) { - this._state.next(s); + this._state = s; return true; } return false; } - get states() { - return <Observable<State>>this._state; - } - - get latestState() { - return this._state.value; - } - - get updated() { - return <Observable<{}>>this._updated; + get state() { + return this._state; } - triggerUpdate() { - this._updated.next({}); + dispose() { + if (this._ev) this._ev.dispose(); } constructor(public context: PluginContext, initialState: State) { - this._state = new BehaviorSubject<State>(initialState); + this._state = initialState; } } \ No newline at end of file diff --git a/src/mol-plugin/context.ts b/src/mol-plugin/context.ts index c766545aaded8c723164c400fd16ff57ebc6487d..307b00eabe43af4e1a938095de229dbd59151286 100644 --- a/src/mol-plugin/context.ts +++ b/src/mol-plugin/context.ts @@ -93,7 +93,7 @@ export class PluginContext { initViewer(canvas: HTMLCanvasElement, container: HTMLDivElement) { try { this.layout.setRoot(container); - if (this.spec.initialLayout) this.layout.updateState(this.spec.initialLayout); + if (this.spec.initialLayout) this.layout.setProps(this.spec.initialLayout); (this.canvas3d as Canvas3D) = Canvas3D.create(canvas, container); PluginCommands.Canvas3D.SetSettings.dispatch(this, { settings: { backgroundColor: Color(0xFCFBF9) } }); this.canvas3d.animate(); @@ -135,6 +135,7 @@ export class PluginContext { this.ev.dispose(); this.state.dispose(); this.tasks.dispose(); + this.layout.dispose(); this.disposed = true; } diff --git a/src/mol-plugin/layout.ts b/src/mol-plugin/layout.ts index bca2e2cd1da0b3570afb58a0b9f620c2e7530ca4..f41fd2c3a5274897173470929aec9a1b6bd9e8c3 100644 --- a/src/mol-plugin/layout.ts +++ b/src/mol-plugin/layout.ts @@ -42,21 +42,30 @@ interface RootState { } export class PluginLayout extends PluginComponent<PluginLayoutStateProps> { + + readonly events = { + updated: this.ev() + } + private updateProps(state: Partial<PluginLayoutStateProps>) { - let prevExpanded = !!this.latestState.isExpanded; + let prevExpanded = !!this.state.isExpanded; this.updateState(state); if (this.root && typeof state.isExpanded === 'boolean' && state.isExpanded !== prevExpanded) this.handleExpand(); - this.triggerUpdate(); + this.events.updated.next(); } private root: HTMLElement; private rootState: RootState | undefined = void 0; private expandedViewport: HTMLMetaElement; + setProps(props: PluginLayoutStateProps) { + this.updateState(props); + } + setRoot(root: HTMLElement) { this.root = root; - if (this.latestState.isExpanded) this.handleExpand(); + if (this.state.isExpanded) this.handleExpand(); } private getScrollElement() { @@ -72,7 +81,7 @@ export class PluginLayout extends PluginComponent<PluginLayoutStateProps> { if (!body || !head) return; - if (this.latestState.isExpanded) { + if (this.state.isExpanded) { let children = head.children; let hasExp = false; let viewports: HTMLElement[] = []; diff --git a/src/mol-plugin/state.ts b/src/mol-plugin/state.ts index 5e3a349c88082113ea666c92133b15ed44591c7d..e583ebe6d378e158e285962fc446ede22c77b699 100644 --- a/src/mol-plugin/state.ts +++ b/src/mol-plugin/state.ts @@ -73,6 +73,7 @@ class PluginState { this.dataState.dispose(); this.behaviorState.dispose(); this.cameraSnapshots.dispose(); + this.animation.dispose(); } constructor(private plugin: import('./context').PluginContext) { diff --git a/src/mol-plugin/state/animation/manager.ts b/src/mol-plugin/state/animation/manager.ts index 9ef6136f45d5a8ec448f30c513767199177c9d90..734ddf49a427a22ec8200153e735b19e7ec24fa0 100644 --- a/src/mol-plugin/state/animation/manager.ts +++ b/src/mol-plugin/state/animation/manager.ts @@ -21,9 +21,17 @@ class PluginAnimationManager extends PluginComponent<PluginAnimationManager.Stat private _current: PluginAnimationManager.Current; private _params?: PD.For<PluginAnimationManager.State['params']> = void 0; + readonly events = { + updated: this.ev() + }; + get isEmpty() { return this.animations.length === 0; } get current() { return this._current!; } + private triggerUpdate() { + this.events.updated.next(); + } + getParams(): PD.Params { if (!this._params) { this._params = { @@ -36,8 +44,8 @@ class PluginAnimationManager extends PluginComponent<PluginAnimationManager.Stat } updateParams(newParams: Partial<PluginAnimationManager.State['params']>) { - this.updateState({ params: { ...this.latestState.params, ...newParams } }); - const anim = this.map.get(this.latestState.params.current)!; + this.updateState({ params: { ...this.state.params, ...newParams } }); + const anim = this.map.get(this.state.params.current)!; const params = anim.params(this.context) as PD.Params; this._current = { anim, @@ -98,7 +106,7 @@ class PluginAnimationManager extends PluginComponent<PluginAnimationManager.Stat } get isAnimating() { - return this.latestState.animationState === 'playing'; + return this.state.animationState === 'playing'; } private _frame: number | undefined = void 0; @@ -116,17 +124,17 @@ class PluginAnimationManager extends PluginComponent<PluginAnimationManager.Stat } else if (newState.kind === 'next') { this._current.state = newState.state; this._current.lastTime = t - this._current.startedTime; - if (this.latestState.animationState === 'playing') this._frame = requestAnimationFrame(this.animate); + if (this.state.animationState === 'playing') this._frame = requestAnimationFrame(this.animate); } else if (newState.kind === 'skip') { - if (this.latestState.animationState === 'playing') this._frame = requestAnimationFrame(this.animate); + if (this.state.animationState === 'playing') this._frame = requestAnimationFrame(this.animate); } } getSnapshot(): PluginAnimationManager.Snapshot { - if (!this.current) return { state: this.latestState }; + if (!this.current) return { state: this.state }; return { - state: this.latestState, + state: this.state, current: { paramValues: this._current.paramValues, state: this._current.anim.stateSerialization ? this._current.anim.stateSerialization.toJSON(this._current.state) : this._current.state @@ -144,7 +152,7 @@ class PluginAnimationManager extends PluginComponent<PluginAnimationManager.Stat ? this._current.anim.stateSerialization.fromJSON(snapshot.current.state) : snapshot.current.state; this.triggerUpdate(); - if (this.latestState.animationState === 'playing') this.resume(); + if (this.state.animationState === 'playing') this.resume(); } } diff --git a/src/mol-plugin/ui/base.tsx b/src/mol-plugin/ui/base.tsx index db43db77315ab37271bdd5b436115d5176272961..d4ae0171d84882a5f0c9fb6e2152b4fbfd5e2d83 100644 --- a/src/mol-plugin/ui/base.tsx +++ b/src/mol-plugin/ui/base.tsx @@ -10,7 +10,7 @@ import { PluginContext } from '../context'; export const PluginReactContext = React.createContext(void 0 as any as PluginContext); -export abstract class PluginComponent<P = {}, S = {}, SS = {}> extends React.Component<P, S, SS> { +export abstract class PluginUIComponent<P = {}, S = {}, SS = {}> extends React.Component<P, S, SS> { static contextType = PluginReactContext; readonly plugin: PluginContext; @@ -35,7 +35,7 @@ export abstract class PluginComponent<P = {}, S = {}, SS = {}> extends React.Com } } -export abstract class PurePluginComponent<P = {}, S = {}, SS = {}> extends React.PureComponent<P, S, SS> { +export abstract class PurePluginUIComponent<P = {}, S = {}, SS = {}> extends React.PureComponent<P, S, SS> { static contextType = PluginReactContext; readonly plugin: PluginContext; diff --git a/src/mol-plugin/ui/camera.tsx b/src/mol-plugin/ui/camera.tsx index ddcf5995d5fff6c62de49ea2e04d0f150da79a69..c818c3068a14acc6a0435a59c79f3c4448c6a056 100644 --- a/src/mol-plugin/ui/camera.tsx +++ b/src/mol-plugin/ui/camera.tsx @@ -6,11 +6,11 @@ import { PluginCommands } from 'mol-plugin/command'; import * as React from 'react'; -import { PluginComponent } from './base'; +import { PluginUIComponent } from './base'; import { ParamDefinition as PD } from 'mol-util/param-definition'; import { ParameterControls } from './controls/parameters'; -export class CameraSnapshots extends PluginComponent<{ }, { }> { +export class CameraSnapshots extends PluginUIComponent<{ }, { }> { render() { return <div> <div className='msp-section-header'>Camera Snapshots</div> @@ -20,7 +20,7 @@ export class CameraSnapshots extends PluginComponent<{ }, { }> { } } -class CameraSnapshotControls extends PluginComponent<{ }, { name: string, description: string }> { +class CameraSnapshotControls extends PluginUIComponent<{ }, { name: string, description: string }> { static Params = { name: PD.Text(), description: PD.Text() @@ -48,7 +48,7 @@ class CameraSnapshotControls extends PluginComponent<{ }, { name: string, descri } } -class CameraSnapshotList extends PluginComponent<{ }, { }> { +class CameraSnapshotList extends PluginUIComponent<{ }, { }> { componentDidMount() { this.subscribe(this.plugin.events.state.cameraSnapshots.changed, () => this.forceUpdate()); } diff --git a/src/mol-plugin/ui/controls.tsx b/src/mol-plugin/ui/controls.tsx index 2a29958116c3495a7dc844ea0dd2e10f4643761a..db69594a3c13abea794a75df957abdd9dad58e19 100644 --- a/src/mol-plugin/ui/controls.tsx +++ b/src/mol-plugin/ui/controls.tsx @@ -7,10 +7,10 @@ import * as React from 'react'; import { PluginCommands } from 'mol-plugin/command'; import { UpdateTrajectory } from 'mol-plugin/state/actions/basic'; -import { PluginComponent } from './base'; +import { PluginUIComponent } from './base'; import { LociLabelEntry } from 'mol-plugin/util/loci-label-manager'; -export class Controls extends PluginComponent<{ }, { }> { +export class Controls extends PluginUIComponent<{ }, { }> { render() { return <> @@ -18,7 +18,7 @@ export class Controls extends PluginComponent<{ }, { }> { } } -export class TrajectoryControls extends PluginComponent { +export class TrajectoryControls extends PluginUIComponent { render() { return <div> <button className='msp-btn msp-btn-link' onClick={() => PluginCommands.State.ApplyAction.dispatch(this.plugin, { @@ -37,7 +37,7 @@ export class TrajectoryControls extends PluginComponent { } } -export class LociLabelControl extends PluginComponent<{}, { entries: ReadonlyArray<LociLabelEntry> }> { +export class LociLabelControl extends PluginUIComponent<{}, { entries: ReadonlyArray<LociLabelEntry> }> { state = { entries: [] } componentDidMount() { diff --git a/src/mol-plugin/ui/plugin.tsx b/src/mol-plugin/ui/plugin.tsx index f4c812c8889e1afc94cb1b4d4f10be33c58a33c2..e0ee8590fa071f3d79fbd924b49c8bb4d3931282 100644 --- a/src/mol-plugin/ui/plugin.tsx +++ b/src/mol-plugin/ui/plugin.tsx @@ -9,7 +9,7 @@ import { PluginContext } from '../context'; import { StateTree } from './state-tree'; import { Viewport, ViewportControls } from './viewport'; import { Controls, TrajectoryControls, LociLabelControl } from './controls'; -import { PluginComponent, PluginReactContext } from './base'; +import { PluginUIComponent, PluginReactContext } from './base'; import { CameraSnapshots } from './camera'; import { StateSnapshots } from './state'; import { List } from 'immutable'; @@ -39,9 +39,9 @@ export class Plugin extends React.Component<{ plugin: PluginContext }, {}> { } } -class Layout extends PluginComponent { +class Layout extends PluginUIComponent { componentDidMount() { - this.subscribe(this.plugin.layout.updated, () => this.forceUpdate()); + this.subscribe(this.plugin.layout.events.updated, () => this.forceUpdate()); } region(kind: 'left' | 'right' | 'bottom' | 'main', element: JSX.Element) { @@ -53,7 +53,7 @@ class Layout extends PluginComponent { } render() { - const layout = this.plugin.layout.latestState; + const layout = this.plugin.layout.state; return <div className='msp-plugin'> <div className={`msp-plugin-content ${layout.isExpanded ? 'msp-layout-expanded' : 'msp-layout-standard msp-layout-standard-outside'}`}> <div className={layout.showControls ? 'msp-layout-hide-top' : 'msp-layout-hide-top msp-layout-hide-right msp-layout-hide-bottom msp-layout-hide-left'}> @@ -73,7 +73,7 @@ class Layout extends PluginComponent { } } -export class ViewportWrapper extends PluginComponent { +export class ViewportWrapper extends PluginUIComponent { render() { return <> <Viewport /> @@ -91,7 +91,7 @@ export class ViewportWrapper extends PluginComponent { } } -export class State extends PluginComponent { +export class State extends PluginUIComponent { componentDidMount() { this.subscribe(this.plugin.state.behavior.kind, () => this.forceUpdate()); } @@ -113,7 +113,7 @@ export class State extends PluginComponent { } } -export class Log extends PluginComponent<{}, { entries: List<LogEntry> }> { +export class Log extends PluginUIComponent<{}, { entries: List<LogEntry> }> { private wrapper = React.createRef<HTMLDivElement>(); componentDidMount() { @@ -151,7 +151,7 @@ export class Log extends PluginComponent<{}, { entries: List<LogEntry> }> { } } -export class CurrentObject extends PluginComponent { +export class CurrentObject extends PluginUIComponent { get current() { return this.plugin.state.behavior.currentObject.value; } diff --git a/src/mol-plugin/ui/state-tree.tsx b/src/mol-plugin/ui/state-tree.tsx index 59a5fc8c260476607d79dfe8a2bac39fd5ff1596..d91238056a0714691a169533c87f10c86155aa65 100644 --- a/src/mol-plugin/ui/state-tree.tsx +++ b/src/mol-plugin/ui/state-tree.tsx @@ -8,16 +8,16 @@ import * as React from 'react'; import { PluginStateObject } from 'mol-plugin/state/objects'; import { State, StateObject } from 'mol-state' import { PluginCommands } from 'mol-plugin/command'; -import { PluginComponent } from './base'; +import { PluginUIComponent } from './base'; -export class StateTree extends PluginComponent<{ state: State }> { +export class StateTree extends PluginUIComponent<{ state: State }> { render() { const n = this.props.state.tree.root.ref; return <StateTreeNode state={this.props.state} nodeRef={n} />; } } -class StateTreeNode extends PluginComponent<{ nodeRef: string, state: State }, { state: State, isCollapsed: boolean }> { +class StateTreeNode extends PluginUIComponent<{ nodeRef: string, state: State }, { state: State, isCollapsed: boolean }> { is(e: State.ObjectEvent) { return e.ref === this.props.nodeRef && e.state === this.props.state; } @@ -77,7 +77,7 @@ class StateTreeNode extends PluginComponent<{ nodeRef: string, state: State }, { } } -class StateTreeNodeLabel extends PluginComponent<{ nodeRef: string, state: State }, { state: State, isCurrent: boolean, isCollapsed: boolean }> { +class StateTreeNodeLabel extends PluginUIComponent<{ nodeRef: string, state: State }, { state: State, isCurrent: boolean, isCollapsed: boolean }> { is(e: State.ObjectEvent) { return e.ref === this.props.nodeRef && e.state === this.props.state; } diff --git a/src/mol-plugin/ui/state.tsx b/src/mol-plugin/ui/state.tsx index b9a16ad129c0e3dd4fc737170b9675fe757ba850..ed8c45d00816052ee185a6a24a062ec02aef3fae 100644 --- a/src/mol-plugin/ui/state.tsx +++ b/src/mol-plugin/ui/state.tsx @@ -6,14 +6,14 @@ import { PluginCommands } from 'mol-plugin/command'; import * as React from 'react'; -import { PluginComponent } from './base'; +import { PluginUIComponent } from './base'; import { shallowEqual } from 'mol-util'; import { List } from 'immutable'; import { ParameterControls } from './controls/parameters'; import { ParamDefinition as PD} from 'mol-util/param-definition'; import { Subject } from 'rxjs'; -export class StateSnapshots extends PluginComponent<{ }, { serverUrl: string }> { +export class StateSnapshots extends PluginUIComponent<{ }, { serverUrl: string }> { state = { serverUrl: 'https://webchem.ncbr.muni.cz/molstar-state' } updateServerUrl = (serverUrl: string) => { this.setState({ serverUrl }) }; @@ -31,7 +31,7 @@ export class StateSnapshots extends PluginComponent<{ }, { serverUrl: string }> // TODO: this is not nice: device some custom event system. const UploadedEvent = new Subject(); -class StateSnapshotControls extends PluginComponent<{ serverUrl: string, serverChanged: (url: string) => void }, { name: string, description: string, serverUrl: string, isUploading: boolean }> { +class StateSnapshotControls extends PluginUIComponent<{ serverUrl: string, serverChanged: (url: string) => void }, { name: string, description: string, serverUrl: string, isUploading: boolean }> { state = { name: '', description: '', serverUrl: this.props.serverUrl, isUploading: false }; static Params = { @@ -93,7 +93,7 @@ class StateSnapshotControls extends PluginComponent<{ serverUrl: string, serverC } } -class LocalStateSnapshotList extends PluginComponent<{ }, { }> { +class LocalStateSnapshotList extends PluginUIComponent<{ }, { }> { componentDidMount() { this.subscribe(this.plugin.events.state.snapshots.changed, () => this.forceUpdate()); } @@ -121,7 +121,7 @@ class LocalStateSnapshotList extends PluginComponent<{ }, { }> { } type RemoteEntry = { url: string, removeUrl: string, timestamp: number, id: string, name: string, description: string } -class RemoteStateSnapshotList extends PluginComponent<{ serverUrl: string }, { entries: List<RemoteEntry>, isFetching: boolean }> { +class RemoteStateSnapshotList extends PluginUIComponent<{ serverUrl: string }, { entries: List<RemoteEntry>, isFetching: boolean }> { state = { entries: List<RemoteEntry>(), isFetching: false }; componentDidMount() { diff --git a/src/mol-plugin/ui/state/animation.tsx b/src/mol-plugin/ui/state/animation.tsx index c25fc4edaa18045c164b7eb0395a23912a000b8d..64ebcc6c01f8474456d893097042057ca951cc17 100644 --- a/src/mol-plugin/ui/state/animation.tsx +++ b/src/mol-plugin/ui/state/animation.tsx @@ -5,12 +5,12 @@ */ import * as React from 'react'; -import { PluginComponent } from '../base'; +import { PluginUIComponent } from '../base'; import { ParameterControls, ParamOnChange } from '../controls/parameters'; -export class AnimationControls extends PluginComponent<{ }> { +export class AnimationControls extends PluginUIComponent<{ }> { componentDidMount() { - this.subscribe(this.plugin.state.animation.updated, () => this.forceUpdate()); + this.subscribe(this.plugin.state.animation.events.updated, () => this.forceUpdate()); } updateParams: ParamOnChange = p => { @@ -23,7 +23,7 @@ export class AnimationControls extends PluginComponent<{ }> { startOrStop = () => { const anim = this.plugin.state.animation; - if (anim.latestState.animationState === 'playing') anim.stop(); + if (anim.state.animationState === 'playing') anim.stop(); else anim.start(); } @@ -31,17 +31,17 @@ export class AnimationControls extends PluginComponent<{ }> { const anim = this.plugin.state.animation; if (anim.isEmpty) return null; - const isDisabled = anim.latestState.animationState === 'playing'; + const isDisabled = anim.state.animationState === 'playing'; return <div className='msp-animation-section'> <div className='msp-section-header'>Animations</div> - <ParameterControls params={anim.getParams()} values={anim.latestState.params} onChange={this.updateParams} isDisabled={isDisabled} /> + <ParameterControls params={anim.getParams()} values={anim.state.params} onChange={this.updateParams} isDisabled={isDisabled} /> <ParameterControls params={anim.current.params} values={anim.current.paramValues} onChange={this.updateCurrentParams} isDisabled={isDisabled} /> <div className='msp-btn-row-group'> <button className='msp-btn msp-btn-block msp-form-control' onClick={this.startOrStop}> - {anim.latestState.animationState === 'playing' ? 'Stop' : 'Start'} + {anim.state.animationState === 'playing' ? 'Stop' : 'Start'} </button> </div> </div> diff --git a/src/mol-plugin/ui/state/common.tsx b/src/mol-plugin/ui/state/common.tsx index daf5f2568aeca146e4cbf638d614a67ddc2906cf..b6570cbafc1cff2fbbe78c3fc2b7a3b9003a5e90 100644 --- a/src/mol-plugin/ui/state/common.tsx +++ b/src/mol-plugin/ui/state/common.tsx @@ -6,7 +6,7 @@ import { State, Transform, Transformer } from 'mol-state'; import * as React from 'react'; -import { PurePluginComponent } from '../base'; +import { PurePluginUIComponent } from '../base'; import { ParameterControls, ParamOnChange } from '../controls/parameters'; import { StateAction } from 'mol-state/action'; import { PluginContext } from 'mol-plugin/context'; @@ -15,7 +15,7 @@ import { Subject } from 'rxjs'; export { StateTransformParameters, TransformContolBase }; -class StateTransformParameters extends PurePluginComponent<StateTransformParameters.Props> { +class StateTransformParameters extends PurePluginUIComponent<StateTransformParameters.Props> { validate(params: any) { // TODO return void 0; @@ -97,7 +97,7 @@ namespace TransformContolBase { } } -abstract class TransformContolBase<P, S extends TransformContolBase.ControlState> extends PurePluginComponent<P, S> { +abstract class TransformContolBase<P, S extends TransformContolBase.ControlState> extends PurePluginUIComponent<P, S> { abstract applyAction(): Promise<void>; abstract getInfo(): StateTransformParameters.Props['info']; abstract getHeader(): Transformer.Definition['display']; diff --git a/src/mol-plugin/ui/task.tsx b/src/mol-plugin/ui/task.tsx index c45b783ea05824070df202b5e24712b37cf61c09..20b1c7f14a072a0276ef709d4893c9f0785e8f8f 100644 --- a/src/mol-plugin/ui/task.tsx +++ b/src/mol-plugin/ui/task.tsx @@ -5,13 +5,13 @@ */ import * as React from 'react'; -import { PluginComponent } from './base'; +import { PluginUIComponent } from './base'; import { OrderedMap } from 'immutable'; import { TaskManager } from 'mol-plugin/util/task-manager'; import { filter } from 'rxjs/operators'; import { Progress } from 'mol-task'; -export class BackgroundTaskProgress extends PluginComponent<{ }, { tracked: OrderedMap<number, TaskManager.ProgressEvent> }> { +export class BackgroundTaskProgress extends PluginUIComponent<{ }, { tracked: OrderedMap<number, TaskManager.ProgressEvent> }> { componentDidMount() { this.subscribe(this.plugin.events.task.progress.pipe(filter(e => e.level !== 'none')), e => { this.setState({ tracked: this.state.tracked.set(e.id, e) }) @@ -30,7 +30,7 @@ export class BackgroundTaskProgress extends PluginComponent<{ }, { tracked: Orde } } -class ProgressEntry extends PluginComponent<{ event: TaskManager.ProgressEvent }> { +class ProgressEntry extends PluginUIComponent<{ event: TaskManager.ProgressEvent }> { render() { const root = this.props.event.progress.root; const subtaskCount = countSubtasks(this.props.event.progress.root) - 1; diff --git a/src/mol-plugin/ui/viewport.tsx b/src/mol-plugin/ui/viewport.tsx index b23bf8977b3a8aa7e33481ba23ae61b17863d00b..ce917a04dbbaa269c33d1c9115bdec8f818f5baf 100644 --- a/src/mol-plugin/ui/viewport.tsx +++ b/src/mol-plugin/ui/viewport.tsx @@ -8,7 +8,7 @@ import * as React from 'react'; import { ButtonsType } from 'mol-util/input/input-observer'; import { Canvas3dIdentifyHelper } from 'mol-plugin/util/canvas3d-identify'; -import { PluginComponent } from './base'; +import { PluginUIComponent } from './base'; import { PluginCommands } from 'mol-plugin/command'; import { ParamDefinition as PD } from 'mol-util/param-definition'; import { ParameterControls } from './controls/parameters'; @@ -20,7 +20,7 @@ interface ViewportState { noWebGl: boolean } -export class ViewportControls extends PluginComponent { +export class ViewportControls extends PluginUIComponent { state = { isSettingsExpanded: false } @@ -35,11 +35,11 @@ export class ViewportControls extends PluginComponent { } toggleControls = () => { - PluginCommands.Layout.Update.dispatch(this.plugin, { state: { showControls: !this.plugin.layout.latestState.showControls } }); + PluginCommands.Layout.Update.dispatch(this.plugin, { state: { showControls: !this.plugin.layout.state.showControls } }); } toggleExpanded = () => { - PluginCommands.Layout.Update.dispatch(this.plugin, { state: { isExpanded: !this.plugin.layout.latestState.isExpanded } }); + PluginCommands.Layout.Update.dispatch(this.plugin, { state: { isExpanded: !this.plugin.layout.state.isExpanded } }); } setSettings = (p: { param: PD.Base<any>, name: string, value: any }) => { @@ -55,7 +55,7 @@ export class ViewportControls extends PluginComponent { this.forceUpdate(); }); - this.subscribe(this.plugin.layout.updated, () => { + this.subscribe(this.plugin.layout.events.updated, () => { this.forceUpdate(); }); } @@ -73,15 +73,15 @@ export class ViewportControls extends PluginComponent { // TODO: show some icons dimmed etc.. return <div className={'msp-viewport-controls'}> <div className='msp-viewport-controls-buttons'> - {this.icon('tools', this.toggleControls, 'Toggle Controls', this.plugin.layout.latestState.showControls)} - {this.icon('expand-layout', this.toggleExpanded, 'Toggle Expanded', this.plugin.layout.latestState.isExpanded)} + {this.icon('tools', this.toggleControls, 'Toggle Controls', this.plugin.layout.state.showControls)} + {this.icon('expand-layout', this.toggleExpanded, 'Toggle Expanded', this.plugin.layout.state.isExpanded)} {this.icon('settings', this.toggleSettingsExpanded, 'Settings', this.state.isSettingsExpanded)} {this.icon('reset-scene', this.resetCamera, 'Reset Camera')} </div> {this.state.isSettingsExpanded && <div className='msp-viewport-controls-scene-options'> <ControlGroup header='Layout' initialExpanded={true}> - <ParameterControls params={PluginLayoutStateParams} values={this.plugin.layout.latestState} onChange={this.setLayout} /> + <ParameterControls params={PluginLayoutStateParams} values={this.plugin.layout.state} onChange={this.setLayout} /> </ControlGroup> <ControlGroup header='Viewport' initialExpanded={true}> <ParameterControls params={Canvas3DParams} values={this.plugin.canvas3d.props} onChange={this.setSettings} /> @@ -91,7 +91,7 @@ export class ViewportControls extends PluginComponent { } } -export class Viewport extends PluginComponent<{ }, ViewportState> { +export class Viewport extends PluginUIComponent<{ }, ViewportState> { private container = React.createRef<HTMLDivElement>(); private canvas = React.createRef<HTMLCanvasElement>(); @@ -128,7 +128,7 @@ export class Viewport extends PluginComponent<{ }, ViewportState> { idHelper.select(x, y); }); - this.subscribe(this.plugin.layout.updated, () => { + this.subscribe(this.plugin.layout.events.updated, () => { setTimeout(this.handleResize, 50); }); }