From e08a074a1c6f3ca9824c1d9de2cb36c31dc98494 Mon Sep 17 00:00:00 2001 From: David Sehnal <david.sehnal@gmail.com> Date: Sat, 8 Feb 2020 17:02:44 +0100 Subject: [PATCH] mol-plugin: config --- src/apps/viewer/index.ts | 3 +- .../skin/base/components/temp.scss | 1 + src/mol-plugin-ui/state/snapshots.tsx | 19 ++++----- src/mol-plugin/config.ts | 40 +++++++++++++++++++ src/mol-plugin/context.ts | 4 ++ src/mol-plugin/index.ts | 6 ++- src/mol-plugin/spec.ts | 4 +- 7 files changed, 65 insertions(+), 12 deletions(-) create mode 100644 src/mol-plugin/config.ts diff --git a/src/apps/viewer/index.ts b/src/apps/viewer/index.ts index da6fb6504..f5474d4a0 100644 --- a/src/apps/viewer/index.ts +++ b/src/apps/viewer/index.ts @@ -42,7 +42,8 @@ function init() { controls: { ...DefaultPluginSpec.layout && DefaultPluginSpec.layout.controls } - } + }, + config: DefaultPluginSpec.config }; const plugin = createPlugin(document.getElementById('app')!, spec); trySetSnapshot(plugin); diff --git a/src/mol-plugin-ui/skin/base/components/temp.scss b/src/mol-plugin-ui/skin/base/components/temp.scss index b77c4cd2d..004a90f17 100644 --- a/src/mol-plugin-ui/skin/base/components/temp.scss +++ b/src/mol-plugin-ui/skin/base/components/temp.scss @@ -83,6 +83,7 @@ > li { position: relative; + overflow: hidden; > button:first-child { border-left: $control-spacing solid color-increase-contrast($default-background, 12%) !important; diff --git a/src/mol-plugin-ui/state/snapshots.tsx b/src/mol-plugin-ui/state/snapshots.tsx index a74699a32..515d86628 100644 --- a/src/mol-plugin-ui/state/snapshots.tsx +++ b/src/mol-plugin-ui/state/snapshots.tsx @@ -15,6 +15,7 @@ import { PluginState } from '../../mol-plugin/state'; import { urlCombine } from '../../mol-util/url'; import { IconButton, Icon, SectionHeader } from '../controls/common'; import { formatTimespan } from '../../mol-util/now'; +import { PluginConfig } from '../../mol-plugin/config'; export class StateSnapshots extends PluginUIComponent<{ }> { downloadToFile = () => { @@ -161,22 +162,22 @@ class LocalStateSnapshotList extends PluginUIComponent<{ }, { }> { export type RemoteEntry = { url: string, removeUrl: string, timestamp: number, id: string, name: string, description: string, isSticky?: boolean } export class RemoteStateSnapshots extends PluginUIComponent< { listOnly?: boolean }, - { params: PD.Values<typeof RemoteStateSnapshots.Params>, entries: OrderedMap<string, RemoteEntry>, isBusy: boolean }> { + { params: PD.Values<RemoteStateSnapshots['Params']>, entries: OrderedMap<string, RemoteEntry>, isBusy: boolean }> { - state = { params: PD.getDefaultValues(RemoteStateSnapshots.Params), entries: OrderedMap<string, RemoteEntry>(), isBusy: false }; - - static Params = { + Params = { name: PD.Text(), options: PD.Group({ description: PD.Text(), playOnLoad: PD.Boolean(false), - serverUrl: PD.Text('https://webchem.ncbr.muni.cz/molstar-state') + serverUrl: PD.Text(this.plugin.config.get(PluginConfig.PluginState.Server)) }) }; - static ListOnlyParams = { + state = { params: PD.getDefaultValues(this.Params), entries: OrderedMap<string, RemoteEntry>(), isBusy: false }; + + ListOnlyParams = { options: PD.Group({ - serverUrl: PD.Text('https://webchem.ncbr.muni.cz/molstar-state') + serverUrl: PD.Text(this.plugin.config.get(PluginConfig.PluginState.Server)) }, { isFlat: true }) }; @@ -268,7 +269,7 @@ export class RemoteStateSnapshots extends PluginUIComponent< <SectionHeader title='Remote States' /> {!this.props.listOnly && <> - <ParameterControls params={RemoteStateSnapshots.Params} values={this.state.params} onEnter={this.upload} onChange={p => { + <ParameterControls params={this.Params} values={this.state.params} onEnter={this.upload} onChange={p => { this.setState({ params: { ...this.state.params, [p.name]: p.value } } as any); }} isDisabled={this.state.isBusy}/> <div className='msp-btn-row-group'> @@ -281,7 +282,7 @@ export class RemoteStateSnapshots extends PluginUIComponent< fetch={this.fetch} remove={this.props.listOnly ? void 0 : this.remove} /> {this.props.listOnly && <> - <ParameterControls params={RemoteStateSnapshots.ListOnlyParams} values={this.state.params} onEnter={this.upload} onChange={p => { + <ParameterControls params={this.ListOnlyParams} values={this.state.params} onEnter={this.upload} onChange={p => { this.setState({ params: { ...this.state.params, [p.name]: p.value } } as any); }} isDisabled={this.state.isBusy}/> <div className='msp-btn-row-group'> diff --git a/src/mol-plugin/config.ts b/src/mol-plugin/config.ts new file mode 100644 index 000000000..b2d094f05 --- /dev/null +++ b/src/mol-plugin/config.ts @@ -0,0 +1,40 @@ +/** + * Copyright (c) 2020 mol* contributors, licensed under MIT, See LICENSE file for more info. + * + * @author David Sehnal <david.sehnal@gmail.com> + */ + +export class PluginConfigItem<T = any> { + toString() { return this.key; } + valueOf() { return this.key; } + constructor(public key: string, public defaultValue?: T) { } +} + +function item<T>(key: string, defaultValue?: T) { return new PluginConfigItem(key, defaultValue); } + +export const PluginConfig = { + item, + PluginState: { Server: item('plugin-state.server', 'https://webchem.ncbr.muni.cz/molstar-state') } +} + +export class PluginConfigManager { + private _config = new Map<PluginConfigItem<any>, unknown>(); + + get<T>(key: PluginConfigItem<T>) { + if (!this._config.has(key)) return key.defaultValue; + return this._config.get(key) as T; + } + + set<T>(key: PluginConfigItem<T>, value: T) { + this._config.set(key, value); + } + + delete<T>(key: PluginConfigItem<T>) { + this._config.delete(key); + } + + constructor(initial?: Map<PluginConfigItem, unknown>) { + if (!initial) return; + initial.forEach((v, k) => this._config.set(k, v)); + } +} \ No newline at end of file diff --git a/src/mol-plugin/context.ts b/src/mol-plugin/context.ts index 213a3e574..f61454b6c 100644 --- a/src/mol-plugin/context.ts +++ b/src/mol-plugin/context.ts @@ -44,6 +44,7 @@ import { StructureMeasurementManager } from './util/structure-measurement'; import { ViewportScreenshotHelper } from './util/viewport-screenshot'; import { StructureRepresentationManager } from './state/representation/structure'; import { CustomProperty } from '../mol-model-props/common/custom-property'; +import { PluginConfigManager } from './config'; interface Log { entries: List<LogEntry> @@ -88,6 +89,8 @@ export class PluginContext { selectionUpdated: this.ev() } } as const + + readonly config = new PluginConfigManager(this.spec.config); readonly behaviors = { state: { @@ -113,6 +116,7 @@ export class PluginContext { readonly lociLabels: LociLabelManager; + readonly structureRepresentation = { registry: new StructureRepresentationRegistry(), themeCtx: { colorThemeRegistry: ColorTheme.createRegistry(), sizeThemeRegistry: SizeTheme.createRegistry() } as ThemeRegistryContext, diff --git a/src/mol-plugin/index.ts b/src/mol-plugin/index.ts index 68c8b525a..d8832d51d 100644 --- a/src/mol-plugin/index.ts +++ b/src/mol-plugin/index.ts @@ -18,6 +18,7 @@ import { InitVolumeStreaming, BoxifyVolumeStreaming, CreateVolumeStreamingBehavi import { StructureRepresentationInteraction } from './behavior/dynamic/selection/structure-representation-interaction'; import { TransformStructureConformation } from './state/actions/structure'; import { VolumeStreamingCustomControls } from '../mol-plugin-ui/custom/volume'; +import { PluginConfig } from './config'; export const DefaultPluginSpec: PluginSpec = { actions: [ @@ -86,7 +87,10 @@ export const DefaultPluginSpec: PluginSpec = { AnimateAssemblyUnwind, AnimateUnitsExplode, AnimateStateInterpolation - ] + ], + config: new Map([ + [PluginConfig.PluginState.Server, 'https://webchem.ncbr.muni.cz/molstar-state'] + ]) } export function createPlugin(target: HTMLElement, spec?: PluginSpec): PluginContext { diff --git a/src/mol-plugin/spec.ts b/src/mol-plugin/spec.ts index 61c9a21f9..c3c11f44d 100644 --- a/src/mol-plugin/spec.ts +++ b/src/mol-plugin/spec.ts @@ -10,6 +10,7 @@ import { StateTransformParameters } from '../mol-plugin-ui/state/common'; import { PluginLayoutStateProps } from './layout'; import { PluginStateAnimation } from './state/animation/model'; import { ParamDefinition as PD } from '../mol-util/param-definition'; +import { PluginConfigItem } from './config'; export { PluginSpec } @@ -25,7 +26,8 @@ interface PluginSpec { }, components?: { remoteState?: 'none' | 'default' // TODO: props for server etc - } + }, + config?: Map<PluginConfigItem, unknown> } namespace PluginSpec { -- GitLab