structure-view.tsx 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189
  1. /**
  2. * Copyright (c) 2018 mol* contributors, licensed under MIT, See LICENSE file for more info.
  3. *
  4. * @author Alexander Rose <alexander.rose@weirdbyte.de>
  5. */
  6. import * as React from 'react'
  7. import { StructureView } from '../structure-view';
  8. import { StructureRepresentation } from 'mol-geo/representation/structure';
  9. import { RepresentationComponent } from './representation';
  10. import { Representation } from 'mol-geo/representation';
  11. export interface StructureViewComponentProps {
  12. structureView: StructureView
  13. }
  14. export interface StructureViewComponentState {
  15. structureView: StructureView
  16. label: string
  17. modelId: number
  18. modelIds: { id: number, label: string }[]
  19. assemblyId: string
  20. assemblyIds: { id: string, label: string }[]
  21. symmetryFeatureId: number
  22. symmetryFeatureIds: { id: number, label: string }[]
  23. active: { [k: string]: boolean }
  24. structureRepresentations: { [k: string]: StructureRepresentation<any> }
  25. }
  26. export class StructureViewComponent extends React.Component<StructureViewComponentProps, StructureViewComponentState> {
  27. state = this.stateFromStructureView(this.props.structureView)
  28. private stateFromStructureView(sv: StructureView) {
  29. return {
  30. structureView: sv,
  31. label: sv.label,
  32. modelId: sv.modelId,
  33. modelIds: sv.getModelIds(),
  34. assemblyId: sv.assemblyId,
  35. assemblyIds: sv.getAssemblyIds(),
  36. symmetryFeatureId: sv.symmetryFeatureId,
  37. symmetryFeatureIds: sv.getSymmetryFeatureIds(),
  38. active: sv.active,
  39. structureRepresentations: sv.structureRepresentations
  40. }
  41. }
  42. componentWillMount() {
  43. this.setState(this.stateFromStructureView(this.props.structureView))
  44. }
  45. componentDidMount() {
  46. const sv = this.props.structureView
  47. this.props.structureView.updated.subscribe(() => this.setState({
  48. symmetryFeatureIds: sv.getSymmetryFeatureIds(),
  49. structureRepresentations: sv.structureRepresentations
  50. }))
  51. }
  52. componentWillReceiveProps(nextProps: StructureViewComponentProps) {
  53. if (nextProps.structureView !== this.props.structureView) {
  54. this.setState(this.stateFromStructureView(nextProps.structureView))
  55. nextProps.structureView.updated.subscribe(() => this.setState({
  56. symmetryFeatureIds: nextProps.structureView.getSymmetryFeatureIds(),
  57. structureRepresentations: nextProps.structureView.structureRepresentations
  58. }))
  59. }
  60. }
  61. async update(state: Partial<StructureViewComponentState>) {
  62. const sv = this.state.structureView
  63. if (state.modelId !== undefined) await sv.setModel(state.modelId)
  64. if (state.assemblyId !== undefined) await sv.setAssembly(state.assemblyId)
  65. if (state.symmetryFeatureId !== undefined) await sv.setSymmetryFeature(state.symmetryFeatureId)
  66. this.setState(this.stateFromStructureView(sv))
  67. }
  68. render() {
  69. const { structureView, label, modelIds, assemblyIds, symmetryFeatureIds, active, structureRepresentations } = this.state
  70. const modelIdOptions = modelIds.map(m => {
  71. return <option key={m.id} value={m.id}>{m.label}</option>
  72. })
  73. const assemblyIdOptions = assemblyIds.map(a => {
  74. return <option key={a.id} value={a.id}>{a.label}</option>
  75. })
  76. const symmetryFeatureIdOptions = symmetryFeatureIds.map(f => {
  77. return <option key={f.id} value={f.id}>{f.label}</option>
  78. })
  79. return <div>
  80. <div>
  81. <h2>{label}</h2>
  82. </div>
  83. <div>
  84. <div>
  85. <span>Model </span>
  86. <select
  87. style={{width: '100px'}}
  88. value={this.state.modelId}
  89. onChange={(e) => {
  90. this.update({ modelId: parseInt(e.target.value) })
  91. }}
  92. >
  93. {modelIdOptions}
  94. </select>
  95. <span> </span>
  96. <input type='range'
  97. defaultValue={this.state.modelId.toString()}
  98. min={Math.min(...modelIds.map(m => m.id))}
  99. max={Math.max(...modelIds.map(m => m.id))}
  100. step='1'
  101. onInput={(e) => {
  102. this.update({ modelId: parseInt(e.currentTarget.value) })
  103. }}
  104. >
  105. </input>
  106. </div>
  107. <div>
  108. <span>Assembly </span>
  109. <select
  110. style={{width: '150px'}}
  111. value={this.state.assemblyId}
  112. onChange={(e) => {
  113. this.update({ assemblyId: e.target.value })
  114. }}
  115. >
  116. {assemblyIdOptions}
  117. </select>
  118. </div>
  119. <div>
  120. <span>Symmetry Feature </span>
  121. <select
  122. style={{width: '150px'}}
  123. value={this.state.symmetryFeatureId}
  124. onChange={(e) => {
  125. this.update({ symmetryFeatureId: parseInt(e.target.value) })
  126. }}
  127. >
  128. {symmetryFeatureIdOptions}
  129. </select>
  130. </div>
  131. <div>
  132. <h4>Active</h4>
  133. { Object.keys(active).map((k, i) => {
  134. return <div key={i}>
  135. <input
  136. type='checkbox'
  137. checked={active[k]}
  138. onChange={(e) => {
  139. const sv = structureView
  140. if (k === 'symmetryAxes') {
  141. sv.setSymmetryAxes(e.target.checked)
  142. } else if (Object.keys(sv.structureRepresentations).includes(k)) {
  143. sv.setStructureRepresentation(k, e.target.checked)
  144. }
  145. }}
  146. /> {k}
  147. </div>
  148. } ) }
  149. </div>
  150. <div>
  151. <h3>Structure Representations</h3>
  152. { Object.keys(structureRepresentations).map((k, i) => {
  153. if (active[k]) {
  154. return <div key={i}>
  155. <RepresentationComponent
  156. repr={structureRepresentations[k] as Representation<any>}
  157. canvas3d={structureView.canvas3d}
  158. app={structureView.app}
  159. />
  160. </div>
  161. } else {
  162. return ''
  163. }
  164. } ) }
  165. </div>
  166. </div>
  167. </div>;
  168. }
  169. }