/** * Copyright (c) 2018-2019 mol* contributors, licensed under MIT, See LICENSE file for more info. * * @author Alexander Rose * @author David Sehnal */ import Autorenew from '@material-ui/icons/Autorenew'; import BuildOutlined from '@material-ui/icons/BuildOutlined'; import CameraOutlined from '@material-ui/icons/CameraOutlined'; import Close from '@material-ui/icons/Close'; import Crop from '@material-ui/icons/Crop'; import Fullscreen from '@material-ui/icons/Fullscreen'; import Tune from '@material-ui/icons/Tune'; import * as React from 'react'; import { resizeCanvas } from '../mol-canvas3d/util'; import { PluginCommands } from '../mol-plugin/commands'; import { PluginConfig } from '../mol-plugin/config'; import { ParamDefinition as PD } from '../mol-util/param-definition'; import { PluginUIComponent } from './base'; import { ControlGroup, IconButton } from './controls/common'; import { DownloadScreenshotControls } from './viewport/screenshot'; import { SimpleSettingsControl } from './viewport/simple-settings'; interface ViewportControlsState { isSettingsExpanded: boolean, isScreenshotExpanded: boolean } interface ViewportControlsProps { } export class ViewportControls extends PluginUIComponent { private allCollapsedState: ViewportControlsState = { isSettingsExpanded: false, isScreenshotExpanded: false }; state = { ...this.allCollapsedState } as ViewportControlsState; resetCamera = () => { PluginCommands.Camera.Reset(this.plugin, {}); } private toggle(panel: keyof ViewportControlsState) { return (e?: React.MouseEvent) => { this.setState({ ...this.allCollapsedState, [panel]: !this.state[panel] }); e?.currentTarget.blur(); }; } toggleSettingsExpanded = this.toggle('isSettingsExpanded'); toggleScreenshotExpanded = this.toggle('isScreenshotExpanded'); toggleControls = () => { PluginCommands.Layout.Update(this.plugin, { state: { showControls: !this.plugin.layout.state.showControls } }); } toggleExpanded = () => { PluginCommands.Layout.Update(this.plugin, { state: { isExpanded: !this.plugin.layout.state.isExpanded } }); } toggleSelectionMode = () => { this.plugin.selectionMode = !this.plugin.selectionMode; } setSettings = (p: { param: PD.Base, name: string, value: any }) => { PluginCommands.Canvas3D.SetSettings(this.plugin, { settings: { [p.name]: p.value } }); } setLayout = (p: { param: PD.Base, name: string, value: any }) => { PluginCommands.Layout.Update(this.plugin, { state: { [p.name]: p.value } }); } screenshot = () => { this.plugin.helpers.viewportScreenshot?.download(); } componentDidMount() { this.subscribe(this.plugin.events.canvas3d.settingsUpdated, () => this.forceUpdate()); this.subscribe(this.plugin.layout.events.updated, () => this.forceUpdate()); this.subscribe(this.plugin.behaviors.interaction.selectionMode, () => this.forceUpdate()); } icon(icon: React.FC, onClick: (e: React.MouseEvent) => void, title: string, isOn = true) { return ; } onMouseMove = (e: React.MouseEvent) => { // ignore mouse moves when no button is held if (e.buttons === 0) e.stopPropagation(); } render() { return
{this.icon(Autorenew, this.resetCamera, 'Reset Camera')}
{this.icon(CameraOutlined, this.toggleScreenshotExpanded, 'Screenshot / State Snapshot', this.state.isScreenshotExpanded)}
{this.icon(BuildOutlined, this.toggleControls, 'Toggle Controls Panel', this.plugin.layout.state.showControls)} {this.plugin.config.get(PluginConfig.Viewport.ShowExpand) && this.icon(Fullscreen, this.toggleExpanded, 'Toggle Expanded Viewport', this.plugin.layout.state.isExpanded)} {this.icon(Tune, this.toggleSettingsExpanded, 'Settings / Controls Info', this.state.isSettingsExpanded)}
{this.plugin.config.get(PluginConfig.Viewport.ShowSelectionMode) &&
{this.icon(Crop, this.toggleSelectionMode, 'Toggle Selection Mode', this.plugin.behaviors.interaction.selectionMode.value)}
}
{this.state.isScreenshotExpanded &&
} {this.state.isSettingsExpanded &&
}
; } } export const Logo = () => ; interface ViewportState { noWebGl: boolean showLogo: boolean } export class Viewport extends PluginUIComponent<{ }, ViewportState> { private container = React.createRef(); private canvas = React.createRef(); state: ViewportState = { noWebGl: false, showLogo: true }; private handleLogo = () => { this.setState({ showLogo: !this.plugin.canvas3d?.reprCount.value }); } private handleResize = () => { const container = this.container.current; const canvas = this.canvas.current; if (container && canvas) { resizeCanvas(canvas, container); this.plugin.canvas3d!.handleResize(); } } componentDidMount() { if (!this.canvas.current || !this.container.current || !this.plugin.initViewer(this.canvas.current!, this.container.current!)) { this.setState({ noWebGl: true }); return; } this.handleLogo(); this.handleResize(); const canvas3d = this.plugin.canvas3d!; this.subscribe(canvas3d.reprCount, this.handleLogo); this.subscribe(canvas3d.input.resize, this.handleResize); this.subscribe(canvas3d.interaction.click, e => this.plugin.behaviors.interaction.click.next(e)); this.subscribe(canvas3d.interaction.hover, e => this.plugin.behaviors.interaction.hover.next(e)); this.subscribe(this.plugin.layout.events.updated, () => { setTimeout(this.handleResize, 50); }); } componentWillUnmount() { if (super.componentWillUnmount) super.componentWillUnmount(); // TODO viewer cleanup } renderMissing() { return ; } render() { if (this.state.noWebGl) return this.renderMissing(); return
{this.state.showLogo && }
; } }