Browse Source

wip, made Color a tagged number type

Alexander Rose 6 years ago
parent
commit
728af1f90a

+ 2 - 2
src/mol-app/ui/transform/backbone.tsx

@@ -46,7 +46,7 @@ export class Backbone extends View<Controller<any>, BackboneState, { transform:
         flatShaded: false,
         detail: 2,
         colorTheme: { name: 'element-symbol' } as ColorThemeProps,
-        colorValue: 0x000000,
+        colorValue: Color(0x000000),
         sizeTheme: { name: 'uniform', factor: 1 } as SizeThemeProps,
         visible: true,
         alpha: 1,
@@ -149,7 +149,7 @@ export class Backbone extends View<Controller<any>, BackboneState, { transform:
                                     className='molstar-form-control'
                                     value={this.state.colorValue}
                                     onChange={(e) => {
-                                        const colorValue = parseInt(e.target.value)
+                                        const colorValue = Color(parseInt(e.target.value))
                                         this.update({
                                             colorTheme: {
                                                 name: 'uniform',

+ 2 - 2
src/mol-app/ui/transform/ball-and-stick.tsx

@@ -48,7 +48,7 @@ export class BallAndStick extends View<Controller<any>, BallAndStickState, { tra
         flipSided: false,
         flatShaded: false,
         colorTheme: { name: 'element-symbol' } as ColorThemeProps,
-        colorValue: 0x000000,
+        colorValue: Color(0x000000),
         sizeTheme: { name: 'uniform', value: 0.15 } as SizeThemeProps,
         visible: true,
         alpha: 1,
@@ -139,7 +139,7 @@ export class BallAndStick extends View<Controller<any>, BallAndStickState, { tra
                                     className='molstar-form-control'
                                     value={this.state.colorValue}
                                     onChange={(e) => {
-                                        const colorValue = parseInt(e.target.value)
+                                        const colorValue = Color(parseInt(e.target.value))
                                         this.update({
                                             colorTheme: {
                                                 name: 'uniform',

+ 2 - 2
src/mol-app/ui/transform/carbohydrate.tsx

@@ -49,7 +49,7 @@ export class Carbohydrate extends View<Controller<any>, CarbohydrateState, { tra
         flatShaded: false,
         detail: 2,
         colorTheme: { name: 'element-symbol' } as ColorThemeProps,
-        colorValue: 0x000000,
+        colorValue: Color(0x000000),
         sizeTheme: { name: 'uniform', factor: 1 } as SizeThemeProps,
         visible: true,
         alpha: 1,
@@ -155,7 +155,7 @@ export class Carbohydrate extends View<Controller<any>, CarbohydrateState, { tra
                                     className='molstar-form-control'
                                     value={this.state.colorValue}
                                     onChange={(e) => {
-                                        const colorValue = parseInt(e.target.value)
+                                        const colorValue = Color(parseInt(e.target.value))
                                         this.update({
                                             colorTheme: {
                                                 name: 'uniform',

+ 2 - 2
src/mol-app/ui/transform/cartoon.tsx

@@ -49,7 +49,7 @@ export class Cartoon extends View<Controller<any>, CartoonState, { transform: Ca
         flatShaded: false,
         detail: 2,
         colorTheme: { name: 'element-symbol' } as ColorThemeProps,
-        colorValue: 0x000000,
+        colorValue: Color(0x000000),
         sizeTheme: { name: 'uniform', value: 0.13, factor: 1 } as SizeThemeProps,
         visible: true,
         alpha: 1,
@@ -155,7 +155,7 @@ export class Cartoon extends View<Controller<any>, CartoonState, { transform: Ca
                                     className='molstar-form-control'
                                     value={this.state.colorValue}
                                     onChange={(e) => {
-                                        const colorValue = parseInt(e.target.value)
+                                        const colorValue = Color(parseInt(e.target.value))
                                         this.update({
                                             colorTheme: {
                                                 name: 'uniform',

+ 2 - 2
src/mol-app/ui/transform/distance-restraint.tsx

@@ -48,7 +48,7 @@ export class DistanceRestraint extends View<Controller<any>, DistanceRestraintSt
         flipSided: false,
         flatShaded: false,
         colorTheme: { name: 'element-symbol' } as ColorThemeProps,
-        colorValue: 0x000000,
+        colorValue: Color(0x000000),
         sizeTheme: { name: 'uniform' } as SizeThemeProps,
         visible: true,
         alpha: 1,
@@ -139,7 +139,7 @@ export class DistanceRestraint extends View<Controller<any>, DistanceRestraintSt
                                     className='molstar-form-control'
                                     value={this.state.colorValue}
                                     onChange={(e) => {
-                                        const colorValue = parseInt(e.target.value)
+                                        const colorValue = Color(parseInt(e.target.value))
                                         this.update({
                                             colorTheme: {
                                                 name: 'uniform',

+ 2 - 2
src/mol-app/ui/transform/spacefill.tsx

@@ -45,7 +45,7 @@ export class Spacefill extends View<Controller<any>, SpacefillState, { transform
         flatShaded: false,
         detail: 2,
         colorTheme: { name: 'element-symbol' } as ColorThemeProps,
-        colorValue: 0x000000,
+        colorValue: Color(0x000000),
         sizeTheme: { name: 'uniform', factor: 1 } as SizeThemeProps,
         visible: true,
         alpha: 1,
@@ -147,7 +147,7 @@ export class Spacefill extends View<Controller<any>, SpacefillState, { transform
                                     className='molstar-form-control'
                                     value={this.state.colorValue}
                                     onChange={(e) => {
-                                        const colorValue = parseInt(e.target.value)
+                                        const colorValue = Color(parseInt(e.target.value))
                                         this.update({
                                             colorTheme: {
                                                 name: 'uniform',

+ 2 - 1
src/mol-geo/representation/volume/surface.ts

@@ -20,6 +20,7 @@ import { PickingId } from '../../util/picking';
 import { createEmptyMarkers, MarkerAction } from '../../util/marker-data';
 import { Loci, EmptyLoci } from 'mol-model/loci';
 import { fillSerial } from 'mol-util/array';
+import { Color } from 'mol-util/color';
 
 export function computeVolumeSurface(volume: VolumeData, isoValue: VolumeIsoValue) {
     return Task.create<Mesh>('Volume Surface', async ctx => {
@@ -65,7 +66,7 @@ export default function SurfaceVisual(): VolumeVisual<SurfaceProps> {
             }
 
             const instanceCount = 1
-            const color = createValueColor(0x7ec0ee)
+            const color = createValueColor(Color(0x7ec0ee))
             const marker = createEmptyMarkers()
 
             const values: MeshValues = {

+ 2 - 1
src/mol-gl/_spec/renderer.spec.ts

@@ -20,6 +20,7 @@ import { PointValues } from '../renderable/point';
 import Scene from '../scene';
 import { createEmptyMarkers } from 'mol-geo/util/marker-data';
 import { fillSerial } from 'mol-util/array';
+import { Color } from 'mol-util/color';
 
 // function writeImage(gl: WebGLRenderingContext, width: number, height: number) {
 //     const pixels = new Uint8Array(width * height * 4)
@@ -47,7 +48,7 @@ function createPoints() {
     const aPosition = ValueCell.create(new Float32Array([0, -1, 0, -1, 0, 0, 1, 1, 0]))
     const aElementId = ValueCell.create(fillSerial(new Float32Array(3)))
     const aInstanceId = ValueCell.create(fillSerial(new Float32Array(1)))
-    const color = createValueColor(0xFF0000)
+    const color = createValueColor(Color(0xFF0000))
     const size = createValueSize(1)
     const marker = createEmptyMarkers()
 

+ 17 - 15
src/mol-model/structure/structure/carbohydrates/constants.ts

@@ -1,3 +1,5 @@
+import { Color, ColorMap } from 'mol-util/color';
+
 /**
  * Copyright (c) 2018 mol* contributors, licensed under MIT, See LICENSE file for more info.
  *
@@ -5,26 +7,26 @@
  * @author David Sehnal <david.sehnal@gmail.com>
  */
 
-// https://www.ncbi.nlm.nih.gov/glycans/snfg.html
+// follows community standard from https://www.ncbi.nlm.nih.gov/glycans/snfg.html
 
 export const enum SaccharideShapes {
     FilledSphere, FilledCube, CrossedCube, DividedDiamond, FilledCone, DevidedCone,
     FlatBox, FilledStar, FilledDiamond, FlatDiamond, FlatHexagon, Pentagon
 }
 
-export const enum SaccharideColors {
-    Blue = 0x0090bc,
-    Green =	0x00a651,
-    Yellow = 0xffd400,
-    Orange = 0xf47920,
-    Pink = 0xf69ea1,
-    Purple = 0xa54399,
-    LightBlue = 0x8fcce9,
-    Brown = 0xa17a4d,
-    Red = 0xed1c24,
+export const SaccharideColors = ColorMap({
+    Blue: 0x0090bc,
+    Green:	0x00a651,
+    Yellow: 0xffd400,
+    Orange: 0xf47920,
+    Pink: 0xf69ea1,
+    Purple: 0xa54399,
+    LightBlue: 0x8fcce9,
+    Brown: 0xa17a4d,
+    Red: 0xed1c24,
 
-    Secondary = 0xf1ece1
-}
+    Secondary: 0xf1ece1
+})
 
 export const enum SaccharideType {
     Hexose, HexNAc, Hexosamine, Hexuronate, Deoxyhexose, DeoxyhexNAc, DiDeoxyhexose,
@@ -72,11 +74,11 @@ export function getSaccharideShape(type: SaccharideType) {
 export type SaccharideComponent = {
     abbr: string
     name: string
-    color: SaccharideColors
+    color: Color
     type: SaccharideType
 }
 
-export const UnknownSaccharideComponent = {
+export const UnknownSaccharideComponent: SaccharideComponent = {
     abbr: 'Unk',
     name: 'Unknown',
     color: SaccharideColors.Secondary,

+ 5 - 3
src/mol-util/color/color.ts

@@ -5,7 +5,9 @@
  */
 
 /** RGB color triplet expressed as a single number */
-type Color = number
+type Color = { readonly '@type': 'color' } & number
+
+function Color(hex: number) { return hex as Color }
 
 namespace Color {
     export function toRgb(hexColor: Color) {
@@ -17,7 +19,7 @@ namespace Color {
     }
 
     export function fromRgb(r: number, g: number, b: number ): Color {
-        return (r << 16) | (g << 8) | b
+        return ((r << 16) | (g << 8) | b) as Color
     }
 
     /** Copies hex color to rgb array */
@@ -47,7 +49,7 @@ namespace Color {
         const g = g1 + (g2 - g1) * t
         const b = b1 + (b2 - b1) * t
 
-        return (r << 16) | (g << 8) | b
+        return ((r << 16) | (g << 8) | b) as Color
     }
 }
 

+ 6 - 0
src/mol-util/color/index.ts

@@ -7,5 +7,11 @@
 import Color from './color'
 import { ColorScale } from './scale';
 
+type ColorTable<T extends { [k: string]: number[] }> = { [k in keyof T]: Color[] }
+export function ColorTable<T extends { [k: string]: number[] }>(o: T) { return o as ColorTable<T> }
+
+type ColorMap<T extends { [k: string]: number }> = { [k in keyof T]: Color }
+export function ColorMap<T extends { [k: string]: number }>(o: T) { return o as ColorMap<T> }
+
 export { Color, ColorScale }
 export { ColorBrewer, ColorNames } from './tables'

+ 6 - 4
src/mol-util/color/tables.ts

@@ -4,13 +4,15 @@
  * @author Alexander Rose <alexander.rose@weirdbyte.de>
  */
 
+import { ColorMap, ColorTable } from './index';
+
 /**
  * Brewer Color Lists
  *
  * Copyright (c) 2002 Cynthia Brewer, Mark Harrower, and The Pennsylvania State University.
  * Licensed under the Apache License, Version 2.0 (the "License");
  */
-export const ColorBrewer = {
+export const ColorBrewer = ColorTable({
     // sequential
     OrRd: [0xfff7ec, 0xfee8c8, 0xfdd49e, 0xfdbb84, 0xfc8d59, 0xef6548, 0xd7301f, 0xb30000, 0x7f0000],
     PuBu: [0xfff7fb, 0xece7f2, 0xd0d1e6, 0xa6bddb, 0x74a9cf, 0x3690c0, 0x0570b0, 0x045a8d, 0x023858],
@@ -52,10 +54,10 @@ export const ColorBrewer = {
     Paired: [0xa6cee3, 0x1f78b4, 0xb2df8a, 0x33a02c, 0xfb9a99, 0xe31a1c, 0xfdbf6f, 0xff7f00, 0xcab2d6, 0x6a3d9a, 0xffff99, 0xb15928],
     Pastel2: [0xb3e2cd, 0xfdcdac, 0xcbd5e8, 0xf4cae4, 0xe6f5c9, 0xfff2ae, 0xf1e2cc, 0xcccccc],
     Pastel1: [0xfbb4ae, 0xb3cde3, 0xccebc5, 0xdecbe4, 0xfed9a6, 0xffffcc, 0xe5d8bd, 0xfddaec, 0xf2f2f2]
-}
+})
 
 /** X11 color names http://www.w3.org/TR/css3-color/#svg-color */
-export const ColorNames = {
+export const ColorNames = ColorMap({
     aliceblue: 0xf0f8ff,
     antiquewhite: 0xfaebd7,
     aqua: 0x00ffff,
@@ -211,4 +213,4 @@ export const ColorNames = {
     whitesmoke: 0xf5f5f5,
     yellow: 0xffff00,
     yellowgreen: 0x9acd32
-}
+})

+ 2 - 1
src/mol-view/theme/color/carbohydrate-symbol.ts

@@ -10,8 +10,9 @@ import { SaccharideColors } from 'mol-model/structure/structure/carbohydrates/co
 import { Location } from 'mol-model/location';
 import { ColorThemeProps, ColorTheme } from '../color';
 import { LocationColor } from 'mol-geo/util/color-data';
+import { Color } from 'mol-util/color';
 
-const DefaultColor = 0xCCCCCC;
+const DefaultColor = 0xCCCCCC as Color
 
 export function CarbohydrateSymbolColorTheme(props: ColorThemeProps): ColorTheme {
     let colorFn: LocationColor

+ 3 - 1
src/mol-view/theme/color/chain-id.ts

@@ -10,6 +10,8 @@ import { ColorScale, Color } from 'mol-util/color';
 import { Location } from 'mol-model/location';
 import { ColorThemeProps, ColorTheme } from '../color';
 
+const DefaultColor = 0xCCCCCC as Color
+
 function getAsymId(unit: Unit): StructureElement.Property<string> {
     switch (unit.kind) {
         case Unit.Kind.Atomic:
@@ -37,7 +39,7 @@ export function ChainIdColorTheme(props: ColorThemeProps): ColorTheme {
             l.element = location.aUnit.elements[location.aIndex]
             return scale.color(map.get(asym_id(l)) || 0)
         }
-        return 0
+        return DefaultColor
     }
 
     return {

+ 1 - 1
src/mol-view/theme/color/cross-link.ts

@@ -12,7 +12,7 @@ import { ColorThemeProps, ColorTheme } from '../color';
 import { LocationColor } from 'mol-geo/util/color-data';
 import { Vec3 } from 'mol-math/linear-algebra';
 
-const DefaultColor = 0xCCCCCC;
+const DefaultColor = 0xCCCCCC as Color
 
 const distVecA = Vec3.zero(), distVecB = Vec3.zero()
 function linkDistance(link: Link.Location) {

+ 2 - 2
src/mol-view/theme/color/element-index.ts

@@ -11,7 +11,7 @@ import { OrderedSet } from 'mol-data/int';
 import { LocationColor } from 'mol-geo/util/color-data';
 import { ColorThemeProps, ColorTheme } from '../color';
 
-const DefaultColor = 0xCCCCCC;
+const DefaultColor = 0xCCCCCC as Color
 
 export function ElementIndexColorTheme(props: ColorThemeProps): ColorTheme {
     let colorFn: LocationColor
@@ -37,7 +37,7 @@ export function ElementIndexColorTheme(props: ColorThemeProps): ColorTheme {
                 const unitId = Unit.findUnitById(location.aUnit.id, units)
                 return scale.color(cummulativeElementCount.get(unitId) || 0 + location.aIndex)
             }
-            return 0
+            return DefaultColor
         }
     } else {
         colorFn = () => DefaultColor

+ 5 - 5
src/mol-view/theme/color/element-symbol.ts

@@ -5,20 +5,20 @@
  */
 
 import { ElementSymbol } from 'mol-model/structure/model/types';
-import { Color } from 'mol-util/color';
+import { Color, ColorMap } from 'mol-util/color';
 import { StructureElement, Unit, Link } from 'mol-model/structure';
 import { Location } from 'mol-model/location';
 import { ColorThemeProps, ColorTheme } from '../color';
 
 // from Jmol http://jmol.sourceforge.net/jscolors/ (or 0xFFFFFF)
-export const ElementSymbolColors: { [k: string]: Color } = {
+export const ElementSymbolColors = ColorMap({
     'H': 0xFFFFFF, 'HE': 0xD9FFFF, 'LI': 0xCC80FF, 'BE': 0xC2FF00, 'B': 0xFFB5B5, 'C': 0x909090, 'N': 0x3050F8, 'O': 0xFF0D0D, 'F': 0x90E050, 'NE': 0xB3E3F5, 'NA': 0xAB5CF2, 'MG': 0x8AFF00, 'AL': 0xBFA6A6, 'SI': 0xF0C8A0, 'P': 0xFF8000, 'S': 0xFFFF30, 'CL': 0x1FF01F, 'AR': 0x80D1E3, 'K': 0x8F40D4, 'CA': 0x3DFF00, 'SC': 0xE6E6E6, 'TI': 0xBFC2C7, 'V': 0xA6A6AB, 'CR': 0x8A99C7, 'MN': 0x9C7AC7, 'FE': 0xE06633, 'CO': 0xF090A0, 'NI': 0x50D050, 'CU': 0xC88033, 'ZN': 0x7D80B0, 'GA': 0xC28F8F, 'GE': 0x668F8F, 'AS': 0xBD80E3, 'SE': 0xFFA100, 'BR': 0xA62929, 'KR': 0x5CB8D1, 'RB': 0x702EB0, 'SR': 0x00FF00, 'Y': 0x94FFFF, 'ZR': 0x94E0E0, 'NB': 0x73C2C9, 'MO': 0x54B5B5, 'TC': 0x3B9E9E, 'RU': 0x248F8F, 'RH': 0x0A7D8C, 'PD': 0x006985, 'AG': 0xC0C0C0, 'CD': 0xFFD98F, 'IN': 0xA67573, 'SN': 0x668080, 'SB': 0x9E63B5, 'TE': 0xD47A00, 'I': 0x940094, 'XE': 0x940094, 'CS': 0x57178F, 'BA': 0x00C900, 'LA': 0x70D4FF, 'CE': 0xFFFFC7, 'PR': 0xD9FFC7, 'ND': 0xC7FFC7, 'PM': 0xA3FFC7, 'SM': 0x8FFFC7, 'EU': 0x61FFC7, 'GD': 0x45FFC7, 'TB': 0x30FFC7, 'DY': 0x1FFFC7, 'HO': 0x00FF9C, 'ER': 0x00E675, 'TM': 0x00D452, 'YB': 0x00BF38, 'LU': 0x00AB24, 'HF': 0x4DC2FF, 'TA': 0x4DA6FF, 'W': 0x2194D6, 'RE': 0x267DAB, 'OS': 0x266696, 'IR': 0x175487, 'PT': 0xD0D0E0, 'AU': 0xFFD123, 'HG': 0xB8B8D0, 'TL': 0xA6544D, 'PB': 0x575961, 'BI': 0x9E4FB5, 'PO': 0xAB5C00, 'AT': 0x754F45, 'RN': 0x428296, 'FR': 0x420066, 'RA': 0x007D00, 'AC': 0x70ABFA, 'TH': 0x00BAFF, 'PA': 0x00A1FF, 'U': 0x008FFF, 'NP': 0x0080FF, 'PU': 0x006BFF, 'AM': 0x545CF2, 'CM': 0x785CE3, 'BK': 0x8A4FE3, 'CF': 0xA136D4, 'ES': 0xB31FD4, 'FM': 0xB31FBA, 'MD': 0xB30DA6, 'NO': 0xBD0D87, 'LR': 0xC70066, 'RF': 0xCC0059, 'DB': 0xD1004F, 'SG': 0xD90045, 'BH': 0xE00038, 'HS': 0xE6002E, 'MT': 0xEB0026, 'DS': 0xFFFFFF, 'RG': 0xFFFFFF, 'CN': 0xFFFFFF, 'UUT': 0xFFFFFF, 'FL': 0xFFFFFF, 'UUP': 0xFFFFFF, 'LV': 0xFFFFFF, 'UUH': 0xFFFFFF, 'D': 0xFFFFC0, 'T': 0xFFFFA0
-}
+})
 
-const DefaultElementSymbolColor = 0xFFFFFF
+const DefaultElementSymbolColor = 0xFFFFFF as Color
 
 export function elementSymbolColor(element: ElementSymbol): Color {
-    const c = ElementSymbolColors[element as any as string];
+    const c = (ElementSymbolColors as { [k: string]: Color })[element];
     return c === void 0 ? DefaultElementSymbolColor : c
 }
 

+ 2 - 1
src/mol-view/theme/color/uniform.ts

@@ -5,8 +5,9 @@
  */
 
 import { ColorTheme, ColorThemeProps } from '../color';
+import { Color } from 'mol-util/color';
 
-const DefaultColor = 0xCCCCCC;
+const DefaultColor = 0xCCCCCC as Color
 
 export function UniformColorTheme(props: ColorThemeProps): ColorTheme {
     const color = props.value || DefaultColor

+ 2 - 2
src/mol-view/theme/color/unit-index.ts

@@ -10,7 +10,7 @@ import { Unit, StructureElement, Link } from 'mol-model/structure';
 import { LocationColor } from 'mol-geo/util/color-data';
 import { ColorTheme, ColorThemeProps } from '../color';
 
-const DefaultColor = 0xCCCCCC;
+const DefaultColor = 0xCCCCCC as Color
 
 export function UnitIndexColorTheme(props: ColorThemeProps): ColorTheme {
     let colorFn: LocationColor
@@ -27,7 +27,7 @@ export function UnitIndexColorTheme(props: ColorThemeProps): ColorTheme {
             } else if (Link.isLocation(location)) {
                 return scale.color(Unit.findUnitById(location.aUnit.id, units))
             }
-            return 0
+            return DefaultColor
         }
     } else {
         colorFn = () => DefaultColor

+ 2 - 1
src/mol-view/viewer.ts

@@ -24,6 +24,7 @@ import { RenderVariant } from 'mol-gl/webgl/render-item';
 import { PickingId, decodeIdRGBA } from 'mol-geo/util/picking';
 import { MarkerAction } from 'mol-geo/util/marker-data';
 import { Loci, EmptyLoci, isEmptyLoci } from 'mol-model/loci';
+import { Color } from 'mol-util/color';
 
 interface Viewer {
     center: (p: Vec3) => void
@@ -101,7 +102,7 @@ namespace Viewer {
         // const controls = TrackballControls.create(input, scene, {})
         const controls = TrackballControls.create(input, camera, {})
         // const renderer = Renderer.create(ctx, camera, { clearColor: 0xFFFFFF })
-        const renderer = Renderer.create(ctx, camera, { clearColor: 0x000000 })
+        const renderer = Renderer.create(ctx, camera, { clearColor: Color(0x000000) })
 
         const pickScale = 1 / 4
         const pickWidth = Math.round(canvas.width * pickScale)