From 6359f3a87938c6d1b0e66d336e2151f20faa84f0 Mon Sep 17 00:00:00 2001 From: Alexander Rose <alex.rose@rcsb.org> Date: Wed, 21 Nov 2018 15:13:29 -0800 Subject: [PATCH] wip, repr.setTheme --- src/mol-geo/geometry/geometry.ts | 5 ---- src/mol-plugin/state/actions/basic.ts | 21 +++++++++++-- .../state/transforms/representation.ts | 30 +++++++++++++++---- src/mol-repr/representation.ts | 14 +++++++-- src/mol-repr/shape/representation.ts | 10 +++++-- .../structure/complex-representation.ts | 11 +++++-- .../representation/ball-and-stick.ts | 2 -- .../structure/representation/carbohydrate.ts | 3 -- .../structure/representation/cartoon.ts | 3 -- .../representation/molecular-surface.ts | 3 -- .../structure/units-representation.ts | 11 +++++-- .../structure/visual/element-sphere.ts | 2 -- src/mol-repr/volume/representation.ts | 11 +++++-- src/mol-theme/color.ts | 6 +--- src/mol-theme/size.ts | 11 +++---- src/mol-theme/theme.ts | 2 +- 16 files changed, 92 insertions(+), 53 deletions(-) diff --git a/src/mol-geo/geometry/geometry.ts b/src/mol-geo/geometry/geometry.ts index eee463dc1..335d2349a 100644 --- a/src/mol-geo/geometry/geometry.ts +++ b/src/mol-geo/geometry/geometry.ts @@ -15,8 +15,6 @@ import { SizeType } from './size-data'; import { Lines } from './lines/lines'; import { ParamDefinition as PD } from 'mol-util/param-definition' import { DirectVolume } from './direct-volume/direct-volume'; -import { BuiltInSizeThemeOptions, getBuiltInSizeThemeParams } from 'mol-theme/size'; -import { BuiltInColorThemeOptions, getBuiltInColorThemeParams } from 'mol-theme/color'; import { Color } from 'mol-util/color'; import { Vec3 } from 'mol-math/linear-algebra'; @@ -67,9 +65,6 @@ export namespace Geometry { selectColor: PD.Color(Color.fromNormalizedRgb(0.2, 1.0, 0.1)), quality: PD.Select<VisualQuality>('auto', VisualQualityOptions), - - colorTheme: PD.Mapped('uniform', BuiltInColorThemeOptions, getBuiltInColorThemeParams), - sizeTheme: PD.Mapped('uniform', BuiltInSizeThemeOptions, getBuiltInSizeThemeParams), } export type Params = typeof Params diff --git a/src/mol-plugin/state/actions/basic.ts b/src/mol-plugin/state/actions/basic.ts index 95e00158c..190dc4fd5 100644 --- a/src/mol-plugin/state/actions/basic.ts +++ b/src/mol-plugin/state/actions/basic.ts @@ -14,6 +14,9 @@ import { BallAndStickParams } from 'mol-repr/structure/representation/ball-and-s import { Download } from '../transforms/data'; import { StateTree } from 'mol-state'; import { StateTreeBuilder } from 'mol-state/tree/builder'; +import { PolymerIdColorThemeParams } from 'mol-theme/color/polymer-id'; +import { UniformSizeThemeParams } from 'mol-theme/size/uniform'; +import { ElementSymbolColorThemeParams } from 'mol-theme/color/element-symbol'; // TODO: "structure parser provider" @@ -106,11 +109,23 @@ function createStructureTree(b: StateTreeBuilder.To<PluginStateObject.Data.Binar function complexRepresentation(root: StateTreeBuilder.To<PluginStateObject.Molecule.Structure>) { root.apply(StateTransforms.Model.StructureComplexElement, { type: 'atomic-sequence' }) - .apply(StateTransforms.Representation.StructureRepresentation3D, { type: { name: 'cartoon', params: PD.getDefaultValues(CartoonParams) } }); + .apply(StateTransforms.Representation.StructureRepresentation3D, { + type: { name: 'cartoon', params: PD.getDefaultValues(CartoonParams) }, + colorTheme: { name: 'polymer-id', params: PD.getDefaultValues(PolymerIdColorThemeParams) }, + sizeTheme: { name: 'uniform', params: PD.getDefaultValues(UniformSizeThemeParams) }, + }); root.apply(StateTransforms.Model.StructureComplexElement, { type: 'atomic-het' }) - .apply(StateTransforms.Representation.StructureRepresentation3D, { type: { name: 'ball-and-stick', params: PD.getDefaultValues(BallAndStickParams) } }); + .apply(StateTransforms.Representation.StructureRepresentation3D, { + type: { name: 'ball-and-stick', params: PD.getDefaultValues(BallAndStickParams) }, + colorTheme: { name: 'element-symbol', params: PD.getDefaultValues(ElementSymbolColorThemeParams) }, + sizeTheme: { name: 'uniform', params: PD.getDefaultValues(UniformSizeThemeParams) }, + }); root.apply(StateTransforms.Model.StructureComplexElement, { type: 'water' }) - .apply(StateTransforms.Representation.StructureRepresentation3D, { type: { name: 'ball-and-stick', params: { ...PD.getDefaultValues(BallAndStickParams), alpha: 0.51 } } }) + .apply(StateTransforms.Representation.StructureRepresentation3D, { + type: { name: 'ball-and-stick', params: { ...PD.getDefaultValues(BallAndStickParams), alpha: 0.51 } }, + colorTheme: { name: 'element-symbol', params: PD.getDefaultValues(ElementSymbolColorThemeParams) }, + sizeTheme: { name: 'uniform', params: PD.getDefaultValues(UniformSizeThemeParams) }, + }) root.apply(StateTransforms.Model.StructureComplexElement, { type: 'spheres' }); // TODO: create spheres visual } diff --git a/src/mol-plugin/state/transforms/representation.ts b/src/mol-plugin/state/transforms/representation.ts index d6c7f50ab..168481fc2 100644 --- a/src/mol-plugin/state/transforms/representation.ts +++ b/src/mol-plugin/state/transforms/representation.ts @@ -2,6 +2,7 @@ * Copyright (c) 2018 mol* contributors, licensed under MIT, See LICENSE file for more info. * * @author David Sehnal <david.sehnal@gmail.com> + * @author Alexander Rose <alexander.rose@weirdbyte.de> */ import { Transformer } from 'mol-state'; @@ -10,11 +11,14 @@ import { PluginStateTransform } from '../objects'; import { PluginStateObject as SO } from '../objects'; import { PluginContext } from 'mol-plugin/context'; import { ParamDefinition as PD } from 'mol-util/param-definition'; +import { createTheme } from 'mol-theme/theme'; export { StructureRepresentation3D } namespace StructureRepresentation3D { export interface Params { - type: { name: string, params: any /** todo is there "common type" */ }, + type: { name: string, params: any /** TODO is there "common type" */ }, + colorTheme: { name: string, params: any /** TODO is there "common type" */ }, + sizeTheme: { name: string, params: any /** TODO is there "common type" */ }, } } const StructureRepresentation3D = PluginStateTransform.Create<SO.Molecule.Structure, SO.Molecule.Representation3D, StructureRepresentation3D.Params>({ @@ -26,21 +30,37 @@ const StructureRepresentation3D = PluginStateTransform.Create<SO.Molecule.Struct type: PD.Mapped( ctx.structureRepresentation.registry.default.name, ctx.structureRepresentation.registry.types, - name => PD.Group<any>(ctx.structureRepresentation.registry.get(name).getParams(ctx.structureRepresentation.themeCtx, a.data))) + name => PD.Group<any>(ctx.structureRepresentation.registry.get(name).getParams(ctx.structureRepresentation.themeCtx, a.data))), + colorTheme: PD.Mapped( + // TODO how to get a default color theme dependent on the repr type? + ctx.structureRepresentation.themeCtx.colorThemeRegistry.default.name, + ctx.structureRepresentation.themeCtx.colorThemeRegistry.types, + name => PD.Group<any>(ctx.structureRepresentation.themeCtx.colorThemeRegistry.get(name).getParams({ structure: a.data })) + ), + sizeTheme: PD.Mapped( + // TODO how to get a default size theme dependent on the repr type? + ctx.structureRepresentation.themeCtx.sizeThemeRegistry.default.name, + ctx.structureRepresentation.themeCtx.sizeThemeRegistry.types, + name => PD.Group<any>(ctx.structureRepresentation.themeCtx.sizeThemeRegistry.get(name).getParams({ structure: a.data })) + ), }), apply({ a, params }, plugin: PluginContext) { return Task.create('Structure Representation', async ctx => { const provider = plugin.structureRepresentation.registry.get(params.type.name) + const props = params.type.params || {} const repr = provider.factory({ webgl: plugin.canvas3d.webgl, ...plugin.structureRepresentation.themeCtx }, provider.getParams) - await repr.createOrUpdate(params.type.params || {}, a.data).runInContext(ctx); + repr.setTheme(createTheme(plugin.structureRepresentation.themeCtx, { structure: a.data }, params)) + // TODO set initial state, repr.setState({}) + await repr.createOrUpdate(props, a.data).runInContext(ctx); return new SO.Molecule.Representation3D(repr, { label: provider.label }); }); }, update({ a, b, oldParams, newParams }, plugin: PluginContext) { return Task.create('Structure Representation', async ctx => { if (newParams.type.name !== oldParams.type.name) return Transformer.UpdateResult.Recreate; - - await b.data.createOrUpdate({ ...b.data.props, ...newParams.type.params }, a.data).runInContext(ctx); + const props = { ...b.data.props, ...newParams.type.params } + b.data.setTheme(createTheme(plugin.structureRepresentation.themeCtx, { structure: a.data }, newParams)) + await b.data.createOrUpdate(props, a.data).runInContext(ctx); return Transformer.UpdateResult.Updated; }); } diff --git a/src/mol-repr/representation.ts b/src/mol-repr/representation.ts index bff58847c..b990ba87a 100644 --- a/src/mol-repr/representation.ts +++ b/src/mol-repr/representation.ts @@ -14,7 +14,7 @@ import { WebGLContext } from 'mol-gl/webgl/context'; import { getQualityProps } from './util'; import { ColorTheme } from 'mol-theme/color'; import { SizeTheme } from 'mol-theme/size'; -import { Theme, ThemeRegistryContext } from 'mol-theme/theme'; +import { Theme, ThemeRegistryContext, createEmptyTheme } from 'mol-theme/theme'; import { Subject } from 'rxjs'; import { Mat4 } from 'mol-math/linear-algebra'; @@ -89,8 +89,10 @@ interface Representation<D, P extends PD.Params = {}> { readonly props: Readonly<PD.Values<P>> readonly params: Readonly<P> readonly state: Readonly<Representation.State> + readonly theme: Readonly<Theme> createOrUpdate: (props?: Partial<PD.Values<P>>, data?: D) => Task<void> setState: (state: Partial<Representation.State>) => void + setTheme: (theme: Theme) => void getLoci: (pickingId: PickingId) => Loci mark: (loci: Loci, action: MarkerAction) => boolean destroy: () => void @@ -114,9 +116,10 @@ namespace Representation { export type Any = Representation<any> export const Empty: Any = { - label: '', groupCount: 0, renderObjects: [], props: {}, params: {}, updated: new Subject(), state: createState(), + label: '', groupCount: 0, renderObjects: [], props: {}, params: {}, updated: new Subject(), state: createState(), theme: createEmptyTheme(), createOrUpdate: () => Task.constant('', undefined), setState: () => {}, + setTheme: () => {}, getLoci: () => EmptyLoci, mark: () => false, destroy: () => {} @@ -128,6 +131,7 @@ namespace Representation { let version = 0 const updated = new Subject<number>() const currentState = Representation.createState() + let currentTheme = createEmptyTheme() let currentParams: P let currentProps: PD.Values<P> @@ -192,6 +196,7 @@ namespace Representation { }) }, get state() { return currentState }, + get theme() { return currentTheme }, getLoci: (pickingId: PickingId) => { for (let i = 0, il = reprList.length; i < il; ++i) { const loci = reprList[i].getLoci(pickingId) @@ -212,6 +217,11 @@ namespace Representation { } Representation.updateState(currentState, state) }, + setTheme: (theme: Theme) => { + for (let i = 0, il = reprList.length; i < il; ++i) { + reprList[i].setTheme(theme) + } + }, destroy() { for (let i = 0, il = reprList.length; i < il; ++i) { reprList[i].destroy() diff --git a/src/mol-repr/shape/representation.ts b/src/mol-repr/shape/representation.ts index a6a04a224..ef2a5076c 100644 --- a/src/mol-repr/shape/representation.ts +++ b/src/mol-repr/shape/representation.ts @@ -18,7 +18,7 @@ import { createRenderableState } from 'mol-geo/geometry/geometry'; import { PickingId } from 'mol-geo/geometry/picking'; import { MarkerAction, applyMarkerAction } from 'mol-geo/geometry/marker-data'; import { LocationIterator } from 'mol-geo/util/location-iterator'; -import { createTheme } from 'mol-theme/theme'; +import { createEmptyTheme, Theme } from 'mol-theme/theme'; import { Subject } from 'rxjs'; export interface ShapeRepresentation<P extends ShapeParams> extends Representation<Shape, P> { } @@ -37,6 +37,7 @@ export function ShapeRepresentation<P extends ShapeParams>(ctx: RepresentationCo const renderObjects: RenderObject[] = [] let _renderObject: MeshRenderObject | undefined let _shape: Shape + let _theme = createEmptyTheme() let currentProps: PD.Values<P> = PD.getDefaultValues(ShapeParams) as PD.Values<P> let currentParams: P let locationIt: LocationIterator @@ -52,10 +53,9 @@ export function ShapeRepresentation<P extends ShapeParams>(ctx: RepresentationCo const mesh = _shape.mesh locationIt = ShapeGroupIterator.fromShape(_shape) - const theme = createTheme(ctx, currentProps, {}) const transform = createIdentityTransform() - const values = await Mesh.createValues(runtime, mesh, transform, locationIt, theme, currentProps) + const values = await Mesh.createValues(runtime, mesh, transform, locationIt, _theme, currentProps) const state = createRenderableState(currentProps) _renderObject = createMeshRenderObject(values, state) @@ -71,6 +71,7 @@ export function ShapeRepresentation<P extends ShapeParams>(ctx: RepresentationCo get props () { return currentProps }, get params () { return currentParams }, get state() { return _state }, + get theme() { return _theme }, updated, createOrUpdate, getLoci(pickingId: PickingId) { @@ -111,6 +112,9 @@ export function ShapeRepresentation<P extends ShapeParams>(ctx: RepresentationCo Representation.updateState(_state, state) }, + setTheme(theme: Theme) { + _theme = theme + }, destroy() { // TODO renderObjects.length = 0 diff --git a/src/mol-repr/structure/complex-representation.ts b/src/mol-repr/structure/complex-representation.ts index b069bb13f..2bbfa2955 100644 --- a/src/mol-repr/structure/complex-representation.ts +++ b/src/mol-repr/structure/complex-representation.ts @@ -13,7 +13,7 @@ import { ComplexVisual } from './complex-visual'; import { PickingId } from 'mol-geo/geometry/picking'; import { MarkerAction } from 'mol-geo/geometry/marker-data'; import { RepresentationContext, RepresentationParamsGetter, Representation } from 'mol-repr/representation'; -import { Theme, createTheme } from 'mol-theme/theme'; +import { Theme, createEmptyTheme } from 'mol-theme/theme'; import { ParamDefinition as PD } from 'mol-util/param-definition'; import { Subject } from 'rxjs'; @@ -26,7 +26,7 @@ export function ComplexRepresentation<P extends StructureParams>(label: string, let _structure: Structure let _params: P let _props: PD.Values<P> - let _theme: Theme + let _theme = createEmptyTheme() function createOrUpdate(props: Partial<PD.Values<P>> = {}, structure?: Structure) { if (structure && structure !== _structure) { @@ -35,7 +35,6 @@ export function ComplexRepresentation<P extends StructureParams>(label: string, if (!_props) _props = PD.getDefaultValues(_params) } _props = Object.assign({}, _props, props) - _theme = createTheme(ctx, { structure: _structure }, props, _theme) return Task.create('Creating or updating ComplexRepresentation', async runtime => { if (!visual) visual = visualCtor() @@ -59,6 +58,10 @@ export function ComplexRepresentation<P extends StructureParams>(label: string, Representation.updateState(_state, state) } + function setTheme(theme: Theme) { + _theme = theme + } + function destroy() { if (visual) visual.destroy() } @@ -74,9 +77,11 @@ export function ComplexRepresentation<P extends StructureParams>(label: string, get props() { return _props }, get params() { return _params }, get state() { return _state }, + get theme() { return _theme }, updated, createOrUpdate, setState, + setTheme, getLoci, mark, destroy diff --git a/src/mol-repr/structure/representation/ball-and-stick.ts b/src/mol-repr/structure/representation/ball-and-stick.ts index 490ae6ae5..3fcb18507 100644 --- a/src/mol-repr/structure/representation/ball-and-stick.ts +++ b/src/mol-repr/structure/representation/ball-and-stick.ts @@ -14,7 +14,6 @@ import { StructureRepresentation, StructureRepresentationProvider } from '../rep import { Representation, RepresentationParamsGetter, RepresentationContext } from 'mol-repr/representation'; import { ThemeRegistryContext } from 'mol-theme/theme'; import { Structure } from 'mol-model/structure'; -import { BuiltInColorThemeOptions, BuiltInColorThemes, ColorTheme } from 'mol-theme/color'; import { UnitKind, UnitKindOptions } from '../visual/util/common'; const BallAndStickVisuals = { @@ -32,7 +31,6 @@ export const BallAndStickParams = { unitKinds: PD.MultiSelect<UnitKind>(['atomic'], UnitKindOptions), sizeFactor: PD.Numeric(0.3, { min: 0.01, max: 10, step: 0.01 }), sizeAspectRatio: PD.Numeric(2/3, { min: 0.01, max: 3, step: 0.01 }), - colorTheme: PD.Mapped('element-symbol', BuiltInColorThemeOptions, name => PD.Group((BuiltInColorThemes as { [k: string]: ColorTheme.Provider<any> })[name].getParams({}))), visuals: PD.MultiSelect<BallAndStickVisualName>(['element-sphere', 'intra-link', 'inter-link'], BallAndStickVisualOptions), } export type BallAndStickParams = typeof BallAndStickParams diff --git a/src/mol-repr/structure/representation/carbohydrate.ts b/src/mol-repr/structure/representation/carbohydrate.ts index 2d56dcc9a..2aa068163 100644 --- a/src/mol-repr/structure/representation/carbohydrate.ts +++ b/src/mol-repr/structure/representation/carbohydrate.ts @@ -13,7 +13,6 @@ import { StructureRepresentation, StructureRepresentationProvider } from '../rep import { Representation, RepresentationParamsGetter, RepresentationContext } from 'mol-repr/representation'; import { ThemeRegistryContext } from 'mol-theme/theme'; import { Structure } from 'mol-model/structure'; -import { BuiltInColorThemeOptions, getBuiltInColorThemeParams } from 'mol-theme/color'; const CarbohydrateVisuals = { 'carbohydrate-symbol': (ctx: RepresentationContext, getParams: RepresentationParamsGetter<Structure, CarbohydrateSymbolParams>) => ComplexRepresentation('Carbohydrate symbol mesh', ctx, getParams, CarbohydrateSymbolVisual), @@ -27,10 +26,8 @@ export const CarbohydrateParams = { ...CarbohydrateSymbolParams, ...CarbohydrateLinkParams, ...CarbohydrateTerminalLinkParams, - colorTheme: PD.Mapped('carbohydrate-symbol', BuiltInColorThemeOptions, getBuiltInColorThemeParams), visuals: PD.MultiSelect<CarbohydrateVisualName>(['carbohydrate-symbol', 'carbohydrate-link', 'carbohydrate-terminal-link'], CarbohydrateVisualOptions), } -PD.getDefaultValues(CarbohydrateParams).colorTheme.name export type CarbohydrateParams = typeof CarbohydrateParams export function getCarbohydrateParams(ctx: ThemeRegistryContext, structure: Structure) { return PD.clone(CarbohydrateParams) diff --git a/src/mol-repr/structure/representation/cartoon.ts b/src/mol-repr/structure/representation/cartoon.ts index e04ce5b60..f6fbff786 100644 --- a/src/mol-repr/structure/representation/cartoon.ts +++ b/src/mol-repr/structure/representation/cartoon.ts @@ -14,7 +14,6 @@ import { Representation, RepresentationParamsGetter, RepresentationContext } fro import { PolymerDirectionVisual, PolymerDirectionParams } from '../visual/polymer-direction-wedge'; import { Structure } from 'mol-model/structure'; import { ThemeRegistryContext } from 'mol-theme/theme'; -import { BuiltInColorThemeOptions, getBuiltInColorThemeParams } from 'mol-theme/color'; const CartoonVisuals = { 'polymer-trace': (ctx: RepresentationContext, getParams: RepresentationParamsGetter<Structure, PolymerTraceParams>) => UnitsRepresentation('Polymer trace mesh', ctx, getParams, PolymerTraceVisual), @@ -31,10 +30,8 @@ export const CartoonParams = { ...NucleotideBlockParams, ...PolymerDirectionParams, sizeFactor: PD.Numeric(0.2, { min: 0, max: 10, step: 0.01 }), - colorTheme: PD.Mapped('polymer-id', BuiltInColorThemeOptions, getBuiltInColorThemeParams), visuals: PD.MultiSelect<CartoonVisualName>(['polymer-trace', 'polymer-gap', 'nucleotide-block'], CartoonVisualOptions), } -PD.getDefaultValues(CartoonParams).colorTheme.name export type CartoonParams = typeof CartoonParams export function getCartoonParams(ctx: ThemeRegistryContext, structure: Structure) { return PD.clone(CartoonParams) diff --git a/src/mol-repr/structure/representation/molecular-surface.ts b/src/mol-repr/structure/representation/molecular-surface.ts index d7056a42c..4181217d3 100644 --- a/src/mol-repr/structure/representation/molecular-surface.ts +++ b/src/mol-repr/structure/representation/molecular-surface.ts @@ -13,7 +13,6 @@ import { StructureRepresentation, StructureRepresentationProvider } from '../rep import { Representation, RepresentationParamsGetter, RepresentationContext } from 'mol-repr/representation'; import { ThemeRegistryContext } from 'mol-theme/theme'; import { Structure } from 'mol-model/structure'; -import { BuiltInColorThemeOptions, getBuiltInColorThemeParams } from 'mol-theme/color'; const MolecularSurfaceVisuals = { 'gaussian-surface': (ctx: RepresentationContext, getParams: RepresentationParamsGetter<Structure, GaussianSurfaceParams>) => UnitsRepresentation('Gaussian surface', ctx, getParams, GaussianSurfaceVisual), @@ -27,10 +26,8 @@ export const MolecularSurfaceParams = { ...GaussianSurfaceParams, ...GaussianWireframeParams, ...GaussianDensityVolumeParams, - colorTheme: PD.Mapped('polymer-id', BuiltInColorThemeOptions, getBuiltInColorThemeParams), visuals: PD.MultiSelect<MolecularSurfaceVisualName>(['gaussian-surface'], MolecularSurfaceVisualOptions), } -PD.getDefaultValues(MolecularSurfaceParams).colorTheme.name export type MolecularSurfaceParams = typeof MolecularSurfaceParams export function getMolecularSurfaceParams(ctx: ThemeRegistryContext, structure: Structure) { return PD.clone(MolecularSurfaceParams) diff --git a/src/mol-repr/structure/units-representation.ts b/src/mol-repr/structure/units-representation.ts index 706af09d5..b796a22dc 100644 --- a/src/mol-repr/structure/units-representation.ts +++ b/src/mol-repr/structure/units-representation.ts @@ -14,7 +14,7 @@ import { StructureGroup } from './units-visual'; import { StructureRepresentation, StructureParams } from './representation'; import { PickingId } from 'mol-geo/geometry/picking'; import { MarkerAction } from 'mol-geo/geometry/marker-data'; -import { Theme, createTheme } from 'mol-theme/theme'; +import { Theme, createEmptyTheme } from 'mol-theme/theme'; import { ParamDefinition as PD } from 'mol-util/param-definition'; import { UnitKind, UnitKindOptions } from './visual/util/common'; import { Subject } from 'rxjs'; @@ -37,7 +37,7 @@ export function UnitsRepresentation<P extends UnitsParams>(label: string, ctx: R let _groups: ReadonlyArray<Unit.SymmetryGroup> let _params: P let _props: PD.Values<P> - let _theme: Theme + let _theme = createEmptyTheme() function createOrUpdate(props: Partial<PD.Values<P>> = {}, structure?: Structure) { if (structure && structure !== _structure) { @@ -45,7 +45,6 @@ export function UnitsRepresentation<P extends UnitsParams>(label: string, ctx: R if (!_props) _props = PD.getDefaultValues(_params) } _props = Object.assign({}, _props, props) - _theme = createTheme(ctx, { structure: structure || _structure }, props, _theme) return Task.create('Creating or updating UnitsRepresentation', async runtime => { if (!_structure && !structure) { @@ -159,6 +158,10 @@ export function UnitsRepresentation<P extends UnitsParams>(label: string, ctx: R Representation.updateState(_state, state) } + function setTheme(theme: Theme) { + _theme = theme + } + function destroy() { visuals.forEach(({ visual }) => visual.destroy()) visuals.clear() @@ -183,9 +186,11 @@ export function UnitsRepresentation<P extends UnitsParams>(label: string, ctx: R get props() { return _props }, get params() { return _params }, get state() { return _state }, + get theme() { return _theme }, updated, createOrUpdate, setState, + setTheme, getLoci, mark, destroy diff --git a/src/mol-repr/structure/visual/element-sphere.ts b/src/mol-repr/structure/visual/element-sphere.ts index 50c2abc39..2b2f09c0f 100644 --- a/src/mol-repr/structure/visual/element-sphere.ts +++ b/src/mol-repr/structure/visual/element-sphere.ts @@ -10,11 +10,9 @@ import { VisualUpdateState } from '../../util'; import { createElementSphereMesh, markElement, getElementLoci, StructureElementIterator } from './util/element'; import { UnitsMeshVisual, UnitsMeshParams } from '../units-visual'; import { ParamDefinition as PD } from 'mol-util/param-definition'; -import { BuiltInSizeThemeOptions, getBuiltInSizeThemeParams } from 'mol-theme/size'; export const ElementSphereParams = { ...UnitsMeshParams, - sizeTheme: PD.Mapped('physical', BuiltInSizeThemeOptions, getBuiltInSizeThemeParams), sizeFactor: PD.Numeric(1, { min: 0, max: 10, step: 0.1 }), detail: PD.Numeric(0, { min: 0, max: 3, step: 1 }), } diff --git a/src/mol-repr/volume/representation.ts b/src/mol-repr/volume/representation.ts index 4b33b0b3b..3e240f660 100644 --- a/src/mol-repr/volume/representation.ts +++ b/src/mol-repr/volume/representation.ts @@ -19,7 +19,7 @@ import { LocationIterator } from 'mol-geo/util/location-iterator'; import { NullLocation } from 'mol-model/location'; import { VisualUpdateState } from 'mol-repr/util'; import { ValueCell } from 'mol-util'; -import { Theme, createTheme } from 'mol-theme/theme'; +import { Theme, createEmptyTheme } from 'mol-theme/theme'; import { Subject } from 'rxjs'; export interface VolumeVisual<P extends VolumeParams> extends Visual<VolumeData, P> { } @@ -152,7 +152,7 @@ export function VolumeRepresentation<P extends VolumeParams>(label: string, ctx: let _volume: VolumeData let _props: PD.Values<P> let _params: P - let _theme: Theme + let _theme = createEmptyTheme() let busy = false function createOrUpdate(props: Partial<PD.Values<P>> = {}, volume?: VolumeData) { @@ -162,7 +162,6 @@ export function VolumeRepresentation<P extends VolumeParams>(label: string, ctx: if (!_props) _props = PD.getDefaultValues(_params) } _props = Object.assign({}, _props, props) - _theme = createTheme(ctx, _props, {}, _theme) return Task.create('VolumeRepresentation.create', async runtime => { // TODO queue it somehow @@ -199,6 +198,10 @@ export function VolumeRepresentation<P extends VolumeParams>(label: string, ctx: Representation.updateState(_state, state) } + function setTheme(theme: Theme) { + _theme = theme + } + function destroy() { if (visual) visual.destroy() } @@ -214,9 +217,11 @@ export function VolumeRepresentation<P extends VolumeParams>(label: string, ctx: get props () { return _props }, get params() { return _params }, get state() { return _state }, + get theme() { return _theme }, updated, createOrUpdate, setState, + setTheme, getLoci, mark, destroy diff --git a/src/mol-theme/color.ts b/src/mol-theme/color.ts index 52d9608cf..5c34904e9 100644 --- a/src/mol-theme/color.ts +++ b/src/mol-theme/color.ts @@ -105,8 +105,4 @@ export const BuiltInColorThemes = { 'shape-group': ShapeGroupColorThemeProvider, 'unit-index': UnitIndexColorThemeProvider, 'uniform': UniformColorThemeProvider, -} -export type BuiltInColorThemeName = keyof typeof BuiltInColorThemes -export const BuiltInColorThemeNames = Object.keys(BuiltInColorThemes) -export const BuiltInColorThemeOptions = BuiltInColorThemeNames.map(n => [n, n] as [BuiltInColorThemeName, string]) -export const getBuiltInColorThemeParams = (name: string, ctx: ThemeDataContext = {}) => PD.Group((BuiltInColorThemes as { [k: string]: ColorTheme.Provider<any> })[name].getParams(ctx)) \ No newline at end of file +} \ No newline at end of file diff --git a/src/mol-theme/size.ts b/src/mol-theme/size.ts index 22042a455..67d7e6c17 100644 --- a/src/mol-theme/size.ts +++ b/src/mol-theme/size.ts @@ -31,6 +31,7 @@ namespace SizeTheme { readonly factory: (ctx: ThemeDataContext, props: PD.Values<P>) => SizeTheme<PD.Values<P>> readonly getParams: (ctx: ThemeDataContext) => P } + export const EmptyProvider: Provider<{}> = { label: '', factory: () => Empty, getParams: () => ({}) } export class Registry { private _list: { name: string, provider: Provider<any> }[] = [] @@ -53,8 +54,8 @@ namespace SizeTheme { this._map.set(name, provider) } - get(id: string) { - return this._map.get(id) + get<P extends PD.Params>(id: string) { + return this._map.get(id) || EmptyProvider as unknown as Provider<P> } create(id: string, ctx: ThemeDataContext, props = {}) { @@ -71,8 +72,4 @@ namespace SizeTheme { export const BuiltInSizeThemes = { 'physical': PhysicalSizeThemeProvider, 'uniform': UniformSizeThemeProvider -} -export type BuiltInSizeThemeName = keyof typeof BuiltInSizeThemes -export const BuiltInSizeThemeNames = Object.keys(BuiltInSizeThemes) -export const BuiltInSizeThemeOptions = BuiltInSizeThemeNames.map(n => [n, n] as [BuiltInSizeThemeName, string]) -export const getBuiltInSizeThemeParams = (name: string, ctx: ThemeDataContext = {}) => PD.Group((BuiltInSizeThemes as { [k: string]: SizeTheme.Provider<any> })[name].getParams(ctx)) \ No newline at end of file +} \ No newline at end of file diff --git a/src/mol-theme/theme.ts b/src/mol-theme/theme.ts index 4bd6aa1b0..ad2222c38 100644 --- a/src/mol-theme/theme.ts +++ b/src/mol-theme/theme.ts @@ -41,6 +41,6 @@ export function createTheme(ctx: ThemeRegistryContext, data: ThemeDataContext, p return theme } -export function createEmptyTheme() { +export function createEmptyTheme(): Theme { return { color: ColorTheme.Empty, size: SizeTheme.Empty } } \ No newline at end of file -- GitLab