AbstractView.tsx 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293
  1. import * as React from "react";
  2. import classes from '../../styles/RcsbFvStyle.module.scss';
  3. import {asyncScheduler, Subscription} from "rxjs";
  4. import {RcsbFvDOMConstants} from "../../RcsbFvConstants/RcsbFvConstants";
  5. import {
  6. SaguaroPluginModelMapType, ViewerCallbackManagerInterface, ViewerActionManagerInterface
  7. } from "../../RcsbFvStructure/StructureViewerInterface";
  8. import {RcsbFvSelectorManager} from "../../RcsbFvState/RcsbFvSelectorManager";
  9. import {SequenceViewInterface} from "./SequenceViewInterface";
  10. import {RcsbFvStateManager} from "../../RcsbFvState/RcsbFvStateManager";
  11. export interface AbstractViewInterface<R> {
  12. componentId: string;
  13. title?: string;
  14. subtitle?: string;
  15. structureViewer: ViewerCallbackManagerInterface & ViewerActionManagerInterface<R>;
  16. stateManager: RcsbFvStateManager;
  17. unmount:(flag:boolean,callback:()=>void)=>void;
  18. }
  19. export abstract class AbstractView<P,S,R> extends React.Component <P & AbstractViewInterface<R>, S> implements SequenceViewInterface {
  20. protected readonly componentDivId: string;
  21. protected readonly rcsbFvDivId: string;
  22. private updateDimTask: Subscription | null = null;
  23. protected constructor(props:P & AbstractViewInterface<R>) {
  24. super(props);
  25. this.componentDivId = props.componentId+"_"+RcsbFvDOMConstants.PFV_DIV;
  26. this.rcsbFvDivId = props.componentId+"_"+RcsbFvDOMConstants.PFV_APP_ID;
  27. }
  28. render():JSX.Element {
  29. return (
  30. <div id={this.componentDivId} >
  31. <div style={{paddingLeft:10, position:"relative"}}>
  32. {this.createTitle()}
  33. {this.createSubtitle()}
  34. {this.additionalContent()}
  35. </div>
  36. <div id ={this.rcsbFvDivId} />
  37. </div>
  38. );
  39. }
  40. componentDidMount() {
  41. this.props.stateManager.subscribe(o=>{
  42. if(o.view == "3d-view" && o.type == "selection-change")
  43. this.structureSelectionCallback();
  44. if(o.view == "3d-view" && o.type == "hover-change")
  45. this.structureHoverCallback()
  46. if(o.view == "3d-view" && o.type == "model-change")
  47. this.modelChangeCallback();
  48. if(o.view == "3d-view" && o.type == "representation-change")
  49. this.representationChangeCallback();
  50. });
  51. window.addEventListener('resize', this.resizeCallback);
  52. }
  53. componentWillUnmount() {
  54. this.props.structureViewer.unsubscribe();
  55. window.removeEventListener('resize', this.resizeCallback);
  56. }
  57. private resizeCallback: ()=>void = () => {
  58. if(this.updateDimTask)
  59. this.updateDimTask.unsubscribe();
  60. this.updateDimTask = asyncScheduler.schedule(()=> {
  61. this.updateDimensions();
  62. },300);
  63. };
  64. private createTitle(): JSX.Element | null{
  65. if(this.props.title)
  66. return (<div id={RcsbFvDOMConstants.TITLE_ID} className={classes.rcsbFvTitle}>{this.props.title}</div>)
  67. return null;
  68. }
  69. private createSubtitle(): JSX.Element | null{
  70. if(this.props.subtitle)
  71. return (<div id={RcsbFvDOMConstants.SUBTITLE_ID} className={classes.rcsbFvSubtitle}>{this.props.subtitle}</div>)
  72. return null;
  73. }
  74. abstract additionalContent(): JSX.Element | null;
  75. abstract updateDimensions(): void;
  76. abstract structureHoverCallback(): void;
  77. abstract representationChangeCallback(): void;
  78. abstract structureSelectionCallback(): void;
  79. abstract modelChangeCallback(): void;
  80. }