-
Alexander Rose authoredAlexander Rose authored
representation.tsx 5.53 KiB
/**
* 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>
}
}