/** * Copyright (c) 2018-2022 mol* contributors, licensed under MIT, See LICENSE file for more info. * * @author Alexander Rose <alexander.rose@weirdbyte.de> */ import { Color } from '../mol-util/color'; import { Location } from '../mol-model/location'; import { ColorType, ColorTypeDirect, ColorTypeGrid, ColorTypeLocation } from '../mol-geo/geometry/color-data'; import { CarbohydrateSymbolColorThemeProvider } from './color/carbohydrate-symbol'; import { UniformColorThemeProvider } from './color/uniform'; import { deepEqual } from '../mol-util'; import { ParamDefinition as PD } from '../mol-util/param-definition'; import { ThemeDataContext, ThemeRegistry, ThemeProvider } from './theme'; import { ChainIdColorThemeProvider } from './color/chain-id'; import { ElementIndexColorThemeProvider } from './color/element-index'; import { ElementSymbolColorThemeProvider } from './color/element-symbol'; import { MoleculeTypeColorThemeProvider } from './color/molecule-type'; import { PolymerIdColorThemeProvider } from './color/polymer-id'; import { PolymerIndexColorThemeProvider } from './color/polymer-index'; import { ResidueNameColorThemeProvider } from './color/residue-name'; import { SecondaryStructureColorThemeProvider } from './color/secondary-structure'; import { SequenceIdColorThemeProvider } from './color/sequence-id'; import { ShapeGroupColorThemeProvider } from './color/shape-group'; import { UnitIndexColorThemeProvider } from './color/unit-index'; import { ScaleLegend, TableLegend } from '../mol-util/legend'; import { UncertaintyColorThemeProvider } from './color/uncertainty'; import { EntitySourceColorThemeProvider } from './color/entity-source'; import { IllustrativeColorThemeProvider } from './color/illustrative'; import { HydrophobicityColorThemeProvider } from './color/hydrophobicity'; import { TrajectoryIndexColorThemeProvider } from './color/trajectory-index'; import { OccupancyColorThemeProvider } from './color/occupancy'; import { OperatorNameColorThemeProvider } from './color/operator-name'; import { OperatorHklColorThemeProvider } from './color/operator-hkl'; import { PartialChargeColorThemeProvider } from './color/partial-charge'; import { AtomIdColorThemeProvider } from './color/atom-id'; import { EntityIdColorThemeProvider } from './color/entity-id'; import { Texture, TextureFilter } from '../mol-gl/webgl/texture'; import { VolumeValueColorThemeProvider } from './color/volume-value'; import { Vec3, Vec4 } from '../mol-math/linear-algebra'; import { ModelIndexColorThemeProvider } from './color/model-index'; import { StructureIndexColorThemeProvider } from './color/structure-index'; import { VolumeSegmentColorThemeProvider } from './color/volume-segment'; import { ExternalVolumeColorThemeProvider } from './color/external-volume'; import { ColorThemeCategory } from './color/categories'; export type LocationColor = (location: Location, isSecondary: boolean) => Color export interface ColorVolume { colors: Texture dimension: Vec3 transform: Vec4 } export { ColorTheme }; type ColorThemeShared<P extends PD.Params, G extends ColorType> = { readonly factory: ColorTheme.Factory<P, G> readonly props: Readonly<PD.Values<P>> /** * if palette is defined, 24bit RGB color value normalized to interval [0, 1] * is used as index to the colors */ readonly palette?: Readonly<ColorTheme.Palette> readonly preferSmoothing?: boolean readonly contextHash?: number readonly description?: string readonly legend?: Readonly<ScaleLegend | TableLegend> } type ColorThemeLocation<P extends PD.Params> = { readonly granularity: ColorTypeLocation readonly color: LocationColor } & ColorThemeShared<P, ColorTypeLocation> type ColorThemeGrid<P extends PD.Params> = { readonly granularity: ColorTypeGrid readonly grid: ColorVolume } & ColorThemeShared<P, ColorTypeGrid> type ColorThemeDirect<P extends PD.Params> = { readonly granularity: ColorTypeDirect } & ColorThemeShared<P, ColorTypeDirect> type ColorTheme<P extends PD.Params, G extends ColorType = ColorTypeLocation> = G extends ColorTypeLocation ? ColorThemeLocation<P> : G extends ColorTypeGrid ? ColorThemeGrid<P> : G extends ColorTypeDirect ? ColorThemeDirect<P> : never namespace ColorTheme { export const Category = ColorThemeCategory; export interface Palette { filter?: TextureFilter, colors: Color[] } export const PaletteScale = (1 << 24) - 1; export type Props = { [k: string]: any } export type Factory<P extends PD.Params, G extends ColorType> = (ctx: ThemeDataContext, props: PD.Values<P>) => ColorTheme<P, G> export const EmptyFactory = () => Empty; const EmptyColor = Color(0xCCCCCC); export const Empty: ColorTheme<{}> = { factory: EmptyFactory, granularity: 'uniform', color: () => EmptyColor, props: {} }; export function areEqual(themeA: ColorTheme<any, any>, themeB: ColorTheme<any, any>) { return themeA.contextHash === themeB.contextHash && themeA.factory === themeB.factory && deepEqual(themeA.props, themeB.props); } export interface Provider<P extends PD.Params = any, Id extends string = string, G extends ColorType = ColorType> extends ThemeProvider<ColorTheme<P, G>, P, Id, G> { } export const EmptyProvider: Provider<{}> = { name: '', label: '', category: '', factory: EmptyFactory, getParams: () => ({}), defaultValues: {}, isApplicable: () => true }; export type Registry = ThemeRegistry<ColorTheme<any, any>> export function createRegistry() { return new ThemeRegistry(BuiltIn as { [k: string]: Provider<any, any, any> }, EmptyProvider); } export const BuiltIn = { 'atom-id': AtomIdColorThemeProvider, 'carbohydrate-symbol': CarbohydrateSymbolColorThemeProvider, 'chain-id': ChainIdColorThemeProvider, 'element-index': ElementIndexColorThemeProvider, 'element-symbol': ElementSymbolColorThemeProvider, 'entity-id': EntityIdColorThemeProvider, 'entity-source': EntitySourceColorThemeProvider, 'hydrophobicity': HydrophobicityColorThemeProvider, 'illustrative': IllustrativeColorThemeProvider, 'model-index': ModelIndexColorThemeProvider, 'molecule-type': MoleculeTypeColorThemeProvider, 'occupancy': OccupancyColorThemeProvider, 'operator-hkl': OperatorHklColorThemeProvider, 'operator-name': OperatorNameColorThemeProvider, 'partial-charge': PartialChargeColorThemeProvider, 'polymer-id': PolymerIdColorThemeProvider, 'polymer-index': PolymerIndexColorThemeProvider, 'residue-name': ResidueNameColorThemeProvider, 'secondary-structure': SecondaryStructureColorThemeProvider, 'sequence-id': SequenceIdColorThemeProvider, 'shape-group': ShapeGroupColorThemeProvider, 'structure-index': StructureIndexColorThemeProvider, 'trajectory-index': TrajectoryIndexColorThemeProvider, 'uncertainty': UncertaintyColorThemeProvider, 'unit-index': UnitIndexColorThemeProvider, 'uniform': UniformColorThemeProvider, 'volume-segment': VolumeSegmentColorThemeProvider, 'volume-value': VolumeValueColorThemeProvider, 'external-volume': ExternalVolumeColorThemeProvider, }; type _BuiltIn = typeof BuiltIn export type BuiltIn = keyof _BuiltIn export type ParamValues<C extends ColorTheme.Provider<any>> = C extends ColorTheme.Provider<infer P> ? PD.Values<P> : never export type BuiltInParams<T extends BuiltIn> = Partial<ParamValues<_BuiltIn[T]>> } export function ColorThemeProvider<P extends PD.Params, Id extends string>(p: ColorTheme.Provider<P, Id>): ColorTheme.Provider<P, Id> { return p; }