Browse Source

Theme namespace

Alexander Rose 5 years ago
parent
commit
aeda6d3312

+ 2 - 2
src/apps/structure-info/volume.ts

@@ -16,7 +16,7 @@ import { Table } from '../../mol-data/db';
 import { StringBuilder } from '../../mol-util';
 import { Task } from '../../mol-task';
 import { createVolumeIsosurfaceMesh } from '../../mol-repr/volume/isosurface';
-import { createEmptyTheme } from '../../mol-theme/theme';
+import { Theme } from '../../mol-theme/theme';
 import { volumeFromDensityServerData } from '../../mol-model-formats/volume/density-server';
 
 require('util.promisify').shim();
@@ -40,7 +40,7 @@ function print(data: Volume) {
 }
 
 async function doMesh(data: Volume, filename: string) {
-    const mesh = await Task.create('', runtime => createVolumeIsosurfaceMesh({ runtime }, data.volume, createEmptyTheme(), { isoValue: VolumeIsoValue.absolute(1.5) } )).run();
+    const mesh = await Task.create('', runtime => createVolumeIsosurfaceMesh({ runtime }, data.volume, Theme.createEmpty(), { isoValue: VolumeIsoValue.absolute(1.5) } )).run();
     console.log({ vc: mesh.vertexCount, tc: mesh.triangleCount });
 
     // Export the mesh in OBJ format.

+ 3 - 3
src/mol-plugin/behavior/dynamic/volume-streaming/transformers.ts

@@ -18,7 +18,7 @@ import { getStreamingMethod, getIds, getContourLevel, getEmdbIds } from './util'
 import { VolumeStreaming } from './behavior';
 import { VolumeRepresentation3DHelpers } from '../../../../mol-plugin/state/transforms/representation';
 import { BuiltInVolumeRepresentations } from '../../../../mol-repr/volume/registry';
-import { createTheme } from '../../../../mol-theme/theme';
+import { Theme } from '../../../../mol-theme/theme';
 import { Box3D } from '../../../../mol-math/geometry';
 import { Vec3 } from '../../../../mol-math/linear-algebra';
 
@@ -249,7 +249,7 @@ const VolumeStreamingVisual = PluginStateTransform.BuiltIn({
         const provider = BuiltInVolumeRepresentations.isosurface;
         const props = params.type.params || {}
         const repr = provider.factory({ webgl: plugin.canvas3d?.webgl, ...plugin.volumeRepresentation.themeCtx }, provider.getParams)
-        repr.setTheme(createTheme(plugin.volumeRepresentation.themeCtx, { volume: channel.data }, params))
+        repr.setTheme(Theme.create(plugin.volumeRepresentation.themeCtx, { volume: channel.data }, params))
         await repr.createOrUpdate(props, channel.data).runInContext(ctx);
         return new SO.Volume.Representation3D({ repr, source: a }, { label: `${Math.round(channel.isoValue.relativeValue * 100) / 100} σ [${srcParams.channel}]` });
     }),
@@ -262,7 +262,7 @@ const VolumeStreamingVisual = PluginStateTransform.BuiltIn({
 
         const params = createVolumeProps(a.data, newParams.channel);
         const props = { ...b.data.repr.props, ...params.type.params };
-        b.data.repr.setTheme(createTheme(plugin.volumeRepresentation.themeCtx, { volume: channel.data }, params))
+        b.data.repr.setTheme(Theme.create(plugin.volumeRepresentation.themeCtx, { volume: channel.data }, params))
         await b.data.repr.createOrUpdate(props, channel.data).runInContext(ctx);
         return StateTransformer.UpdateResult.Updated;
     })

+ 2 - 2
src/mol-plugin/state/transforms/representation.ts

@@ -207,7 +207,7 @@ const StructureRepresentation3D = PluginStateTransform.BuiltIn({
             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)
-            repr.setTheme(createTheme(plugin.structureRepresentation.themeCtx, { structure: a.data }, params))
+            repr.setTheme(Theme.create(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.Structure.Representation3D({ repr, source: a } , { label: provider.label });
@@ -217,7 +217,7 @@ const StructureRepresentation3D = PluginStateTransform.BuiltIn({
         return Task.create('Structure Representation', async ctx => {
             if (newParams.type.name !== oldParams.type.name) return StateTransformer.UpdateResult.Recreate;
             const props = { ...b.data.repr.props, ...newParams.type.params }
-            b.data.repr.setTheme(createTheme(plugin.structureRepresentation.themeCtx, { structure: a.data }, newParams));
+            b.data.repr.setTheme(Theme.create(plugin.structureRepresentation.themeCtx, { structure: a.data }, newParams));
             await b.data.repr.createOrUpdate(props, a.data).runInContext(ctx);
             b.data.source = a
             return StateTransformer.UpdateResult.Updated;

+ 5 - 4
src/mol-repr/representation.ts

@@ -8,7 +8,7 @@ import { ParamDefinition as PD } from '../mol-util/param-definition';
 import { WebGLContext } from '../mol-gl/webgl/context';
 import { ColorTheme } from '../mol-theme/color';
 import { SizeTheme } from '../mol-theme/size';
-import { ThemeRegistryContext, Theme, createEmptyTheme } from '../mol-theme/theme';
+import { ThemeRegistryContext, Theme } from '../mol-theme/theme';
 import { Subject } from 'rxjs';
 import { GraphicsRenderObject } from '../mol-gl/render-object';
 import { Task } from '../mol-task';
@@ -47,6 +47,7 @@ export interface RepresentationProvider<D, P extends PD.Params, S extends Repres
     readonly defaultColorTheme: string
     readonly defaultSizeTheme: string
     readonly isApplicable: (data: D) => boolean
+    readonly ensureDependencies?: (data: D) => Promise<void>
 }
 
 export namespace RepresentationProvider {
@@ -186,7 +187,7 @@ namespace Representation {
 
     export type Any = Representation<any, any, any>
     export const Empty: Any = {
-        label: '', groupCount: 0, renderObjects: [], props: {}, params: {}, updated: new Subject(), state: createState(), theme: createEmptyTheme(),
+        label: '', groupCount: 0, renderObjects: [], props: {}, params: {}, updated: new Subject(), state: createState(), theme: Theme.createEmpty(),
         createOrUpdate: () => Task.constant('', undefined),
         setState: () => {},
         setTheme: () => {},
@@ -201,7 +202,7 @@ namespace Representation {
         let version = 0
         const updated = new Subject<number>()
         const currentState = stateBuilder.create()
-        let currentTheme = createEmptyTheme()
+        let currentTheme = Theme.createEmpty()
 
         let currentParams: P
         let currentProps: PD.Values<P>
@@ -303,7 +304,7 @@ namespace Representation {
         let version = 0
         const updated = new Subject<number>()
         const currentState = Representation.createState()
-        const currentTheme = createEmptyTheme()
+        const currentTheme = Theme.createEmpty()
 
         const currentParams = PD.clone(BaseGeometry.Params)
         const currentProps = PD.getDefaultValues(BaseGeometry.Params)

+ 2 - 2
src/mol-repr/shape/representation.ts

@@ -9,7 +9,7 @@ import { Representation } from '../representation';
 import { Shape, ShapeGroup } from '../../mol-model/shape';
 import { Subject } from 'rxjs';
 import { getNextMaterialId, RenderObjectKindType, createRenderObject, RenderObjectValuesType } from '../../mol-gl/render-object';
-import { createEmptyTheme, Theme } from '../../mol-theme/theme';
+import { Theme } from '../../mol-theme/theme';
 import { LocationIterator } from '../../mol-geo/util/location-iterator';
 import { VisualUpdateState } from '../util';
 import { ShapeGroupColorTheme } from '../../mol-theme/color/shape-group';
@@ -47,7 +47,7 @@ export function ShapeRepresentation<D, G extends Geometry, P extends Geometry.Pa
     const renderObjects: RenderObjectKindType[G['kind']][] = []
     let _renderObject: RenderObjectKindType[G['kind']] | undefined
     let _shape: Shape<G>
-    let _theme = createEmptyTheme()
+    let _theme = Theme.createEmpty()
     let currentProps: PD.Values<P> = PD.getDefaultValues(geometryUtils.Params as P) // TODO avoid casting
     let currentParams: P
     let locationIt: LocationIterator

+ 2 - 2
src/mol-repr/structure/complex-representation.ts

@@ -11,7 +11,7 @@ import { RepresentationContext, RepresentationParamsGetter } from '../representa
 import { Structure, StructureElement, Link } from '../../mol-model/structure';
 import { Subject } from 'rxjs';
 import { getNextMaterialId, GraphicsRenderObject } from '../../mol-gl/render-object';
-import { createEmptyTheme, Theme } from '../../mol-theme/theme';
+import { Theme } from '../../mol-theme/theme';
 import { Task } from '../../mol-task';
 import { PickingId } from '../../mol-geo/geometry/picking';
 import { EmptyLoci, Loci, isEveryLoci } from '../../mol-model/loci';
@@ -29,7 +29,7 @@ export function ComplexRepresentation<P extends StructureParams>(label: string,
     let _structure: Structure
     let _params: P
     let _props: PD.Values<P>
-    let _theme = createEmptyTheme()
+    let _theme = Theme.createEmpty()
 
     function createOrUpdate(props: Partial<PD.Values<P>> = {}, structure?: Structure) {
         if (structure && structure !== _structure) {

+ 2 - 2
src/mol-repr/structure/complex-visual.ts

@@ -10,7 +10,7 @@ import { Visual, VisualContext } from '../visual';
 import { Structure, StructureElement } from '../../mol-model/structure';
 import { Geometry, GeometryUtils } from '../../mol-geo/geometry/geometry';
 import { LocationIterator } from '../../mol-geo/util/location-iterator';
-import { Theme, createEmptyTheme } from '../../mol-theme/theme';
+import { Theme } from '../../mol-theme/theme';
 import { createIdentityTransform } from '../../mol-geo/geometry/transform-data';
 import { createRenderObject, RenderObjectKindType, RenderObjectValuesType } from '../../mol-gl/render-object';
 import { UnitKind, UnitKindOptions } from './visual/util/common';
@@ -72,7 +72,7 @@ export function ComplexVisual<G extends Geometry, P extends ComplexParams & Geom
     let newStructure: Structure
 
     let currentProps: PD.Values<P> = Object.assign({}, defaultProps)
-    let currentTheme: Theme = createEmptyTheme()
+    let currentTheme: Theme = Theme.createEmpty()
     let currentStructure: Structure
 
     let geometry: G

+ 2 - 2
src/mol-repr/structure/units-representation.ts

@@ -14,7 +14,7 @@ import { RepresentationContext, RepresentationParamsGetter } from '../representa
 import { Structure, Unit, StructureElement, Link } from '../../mol-model/structure';
 import { Subject } from 'rxjs';
 import { getNextMaterialId, GraphicsRenderObject } from '../../mol-gl/render-object';
-import { createEmptyTheme, Theme } from '../../mol-theme/theme';
+import { Theme } from '../../mol-theme/theme';
 import { Task } from '../../mol-task';
 import { PickingId } from '../../mol-geo/geometry/picking';
 import { Loci, EmptyLoci, isEmptyLoci, isEveryLoci } from '../../mol-model/loci';
@@ -41,7 +41,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 = createEmptyTheme()
+    let _theme = Theme.createEmpty()
 
     function createOrUpdate(props: Partial<PD.Values<P>> = {}, structure?: Structure) {
         if (structure && structure !== _structure) {

+ 2 - 2
src/mol-repr/structure/units-visual.ts

@@ -10,7 +10,7 @@ import { RepresentationProps } from '../representation';
 import { Visual, VisualContext } from '../visual';
 import { Geometry, GeometryUtils } from '../../mol-geo/geometry/geometry';
 import { LocationIterator } from '../../mol-geo/util/location-iterator';
-import { Theme, createEmptyTheme } from '../../mol-theme/theme';
+import { Theme } from '../../mol-theme/theme';
 import { createUnitsTransform, includesUnitKind } from './visual/util/common';
 import { createRenderObject, RenderObjectKindType, RenderObjectValuesType } from '../../mol-gl/render-object';
 import { UnitsParams } from './units-representation';
@@ -70,7 +70,7 @@ export function UnitsVisual<G extends Geometry, P extends UnitsParams & Geometry
     let renderObject: RenderObjectKindType[G['kind']] | undefined
 
     let newProps: PD.Values<P> = Object.assign({}, defaultProps)
-    let newTheme: Theme = createEmptyTheme()
+    let newTheme: Theme = Theme.createEmpty()
     let newStructureGroup: StructureGroup
 
     let currentProps: PD.Values<P>

+ 3 - 3
src/mol-repr/volume/representation.ts

@@ -9,7 +9,7 @@ import { Visual, VisualContext } from '../visual';
 import { VolumeData } from '../../mol-model/volume';
 import { Geometry, GeometryUtils } from '../../mol-geo/geometry/geometry';
 import { LocationIterator } from '../../mol-geo/util/location-iterator';
-import { Theme, createEmptyTheme } from '../../mol-theme/theme';
+import { Theme } from '../../mol-theme/theme';
 import { createIdentityTransform } from '../../mol-geo/geometry/transform-data';
 import { createRenderObject, RenderObjectKindType, RenderObjectValuesType, getNextMaterialId, GraphicsRenderObject } from '../../mol-gl/render-object';
 import { PickingId } from '../../mol-geo/geometry/picking';
@@ -64,7 +64,7 @@ export function VolumeVisual<G extends Geometry, P extends VolumeParams & Geomet
     let newVolume: VolumeData
 
     let currentProps: PD.Values<P> = Object.assign({}, defaultProps)
-    let currentTheme: Theme = createEmptyTheme()
+    let currentTheme: Theme = Theme.createEmpty()
     let currentVolume: VolumeData
 
     let geometry: G
@@ -219,7 +219,7 @@ export function VolumeRepresentation<P extends VolumeParams>(label: string, ctx:
     let _volume: VolumeData
     let _params: P
     let _props: PD.Values<P>
-    let _theme = createEmptyTheme()
+    let _theme = Theme.createEmpty()
 
     function createOrUpdate(props: Partial<PD.Values<P>> = {}, volume?: VolumeData) {
         if (volume && volume !== _volume) {

+ 13 - 4
src/mol-theme/theme.ts

@@ -23,16 +23,19 @@ export interface ThemeDataContext {
     shape?: Shape
 }
 
-export interface Theme {
+export { Theme }
+
+interface Theme {
     color: ColorTheme<any>
     size: SizeTheme<any>
     // label: LabelTheme // TODO
 }
 
+namespace Theme {
 type Props = { [k: string]: any }
 
-export function createTheme(ctx: ThemeRegistryContext, data: ThemeDataContext, props: Props, theme?: Theme) {
-    theme = theme || createEmptyTheme()
+    export function create(ctx: ThemeRegistryContext, data: ThemeDataContext, props: Props, theme?: Theme) {
+        theme = theme || createEmpty()
 
     const colorProps = props.colorTheme as PD.NamedParams
     const sizeProps = props.sizeTheme as PD.NamedParams
@@ -43,10 +46,16 @@ export function createTheme(ctx: ThemeRegistryContext, data: ThemeDataContext, p
     return theme
 }
 
-export function createEmptyTheme(): Theme {
+    export function createEmpty(): Theme {
     return { color: ColorTheme.Empty, size: SizeTheme.Empty }
 }
 
+    export async function ensureDependencies(ctx: ThemeRegistryContext, data: ThemeDataContext, props: Props) {
+        await ctx.colorThemeRegistry.get(props.colorTheme.name).ensureDependencies?.(data)
+        await ctx.sizeThemeRegistry.get(props.sizeTheme.name).ensureDependencies?.(data)
+    }
+}
+
 //
 
 export interface ThemeProvider<T extends ColorTheme<P> | SizeTheme<P>, P extends PD.Params> {