/** * Copyright (c) 2019 mol* contributors, licensed under MIT, See LICENSE file for more info. * * @author Alexander Rose <alexander.rose@weirdbyte.de> */ import * as React from 'react'; import { PluginUIComponent } from '../base'; import { Structure, StructureElement } from '../../../mol-model/structure'; import { isEmptyLoci } from '../../../mol-model/loci'; import { ColorOptions, ParameterControls } from '../controls/parameters'; import { Color } from '../../../mol-util/color'; import { ButtonSelect, Options } from '../controls/common' import { ParamDefinition as PD } from '../../../mol-util/param-definition'; import { VisualQuality, VisualQualityOptions } from '../../../mol-geo/geometry/base'; import { StructureRepresentationPresets as P } from '../../util/structure-representation-helper'; import { camelCaseToWords } from '../../../mol-util/string'; abstract class BaseStructureRepresentationControls extends PluginUIComponent { onChange = (value: string) => { console.log('onChange', value) } abstract label: string abstract lociGetter(structure: Structure): StructureElement.Loci show = (value: string) => { this.plugin.helpers.structureRepresentation.set('add', value, this.lociGetter) } hide = (value: string) => { if (value === '__all__') { const { types } = this.plugin.structureRepresentation.registry for (let i = 0, il = types.length; i < il; ++i) { this.plugin.helpers.structureRepresentation.set('remove', types[i][0], this.lociGetter) } } else { this.plugin.helpers.structureRepresentation.set('remove', value, this.lociGetter) } } color = (value: string) => { const color = Color(parseInt(value)) this.plugin.helpers.structureOverpaint.set(color, this.lociGetter) } render() { const { types } = this.plugin.structureRepresentation.registry return <div className='msp-control-row'> <span title={this.label}>{this.label}</span> <div className='msp-select-row'> <ButtonSelect label='Show' onChange={this.show}> <optgroup label='Show'>{Options(types)}</optgroup> </ButtonSelect> <ButtonSelect label='Hide' onChange={this.hide}> <optgroup label='Clear'> <option key={'__all__'} value={'__all__'}>All</option> </optgroup> <optgroup label='Hide'>{Options(types)}</optgroup> </ButtonSelect> <ButtonSelect label='Color' onChange={this.color}> <optgroup label='Clear'> <option key={-1} value={-1}>Theme</option> </optgroup> <optgroup label='Color'>{ColorOptions()}</optgroup> </ButtonSelect> </div> </div> } } class EverythingStructureRepresentationControls extends BaseStructureRepresentationControls { label = 'Everything' lociGetter = (structure: Structure) => { return StructureElement.Loci.all(structure) } } class SelectionStructureRepresentationControls extends BaseStructureRepresentationControls { label = 'Selection' lociGetter = (structure: Structure) => { const loci = this.plugin.helpers.structureSelectionManager.get(structure) return isEmptyLoci(loci) ? StructureElement.Loci.none(structure) : loci } } export class StructureRepresentationControls extends PluginUIComponent { preset = async (value: string) => { const presetFn = P[value as keyof typeof P] if (presetFn) { await presetFn(this.plugin.helpers.structureRepresentation) } } onChange = async (p: { param: PD.Base<any>, name: string, value: any }) => { if (p.name === 'options') { await this.plugin.helpers.structureRepresentation.setIgnoreHydrogens(!p.value.showHydrogens) await this.plugin.helpers.structureRepresentation.setQuality(p.value.visualQuality) this.forceUpdate() } } get params () { const { options } = this.values return { options: PD.Group({ showHydrogens: PD.Boolean(options.showHydrogens), visualQuality: PD.Select<VisualQuality>(options.visualQuality, VisualQualityOptions), }, { isExpanded: true }) } } get values () { const { structureRepresentation: rep } = this.plugin.helpers return { options: { showHydrogens: !rep.ignoreHydrogens, visualQuality: rep.quality, } } } render() { const presets = Object.keys(P).map(name => { return [name, camelCaseToWords(name)] as [string, string] }) return <div className='msp-transform-wrapper'> <div className='msp-transform-header'> <button className='msp-btn msp-btn-block'>Representation</button> </div> <div className='msp-control-row'> <div className='msp-select-row'> <ButtonSelect label='Preset' onChange={this.preset}> <optgroup label='Preset'>{Options(presets)}</optgroup> </ButtonSelect> </div> </div> <EverythingStructureRepresentationControls /> <SelectionStructureRepresentationControls /> <ParameterControls params={this.params} values={this.values} onChange={this.onChange} /> </div> } }