Browse Source

Refactor Bindings and show them in "Simple settings"

David Sehnal 5 years ago
parent
commit
369b958335

+ 7 - 7
src/mol-canvas3d/controls/trackball.ts

@@ -21,15 +21,15 @@ const M = ModifiersKeys
 const Trigger = Binding.Trigger
 
 export const DefaultTrackballBindings = {
-    dragRotate: Binding([Trigger(B.Flag.Primary, M.create())], 'Rotate the 3D scene by dragging using ${triggers}'),
-    dragRotateZ: Binding([Trigger(B.Flag.Primary, M.create({ shift: true }))], 'Rotate the 3D scene around the z-axis by dragging using ${triggers}'),
-    dragPan: Binding([Trigger(B.Flag.Secondary, M.create()), Trigger(B.Flag.Primary, M.create({ control: true }))], 'Pan the 3D scene by dragging using ${triggers}'),
+    dragRotate: Binding([Trigger(B.Flag.Primary, M.create())], 'Rotate', 'Drag using ${triggers}'),
+    dragRotateZ: Binding([Trigger(B.Flag.Primary, M.create({ shift: true }))], 'Rotate around z-axis', 'Drag using ${triggers}'),
+    dragPan: Binding([Trigger(B.Flag.Secondary, M.create()), Trigger(B.Flag.Primary, M.create({ control: true }))], 'Pan', 'Drag using ${triggers}'),
     dragZoom: Binding.Empty,
-    dragFocus: Binding([Trigger(B.Flag.Forth, M.create())], 'Focus the 3D scene by dragging using ${triggers}'),
-    dragFocusZoom: Binding([Trigger(B.Flag.Auxilary, M.create())], 'Focus and zoom the 3D scene by dragging using ${triggers}'),
+    dragFocus: Binding([Trigger(B.Flag.Forth, M.create())], 'Focus', 'Drag using ${triggers}'),
+    dragFocusZoom: Binding([Trigger(B.Flag.Auxilary, M.create())], 'Focus and zoom', 'Drag using ${triggers}'),
 
-    scrollZoom: Binding([Trigger(B.Flag.Auxilary, M.create())], 'Zoom the 3D scene by scrolling using ${triggers}'),
-    scrollFocus: Binding([Trigger(B.Flag.Auxilary, M.create({ shift: true }))], 'Focus the 3D scene by scrolling using ${triggers}'),
+    scrollZoom: Binding([Trigger(B.Flag.Auxilary, M.create())], 'Zoom', 'Scroll using ${triggers}'),
+    scrollFocus: Binding([Trigger(B.Flag.Auxilary, M.create({ shift: true }))], 'Clip', 'Scroll using ${triggers}'),
     scrollFocusZoom: Binding.Empty,
 }
 

+ 1 - 1
src/mol-plugin-ui/viewport.tsx

@@ -94,7 +94,7 @@ export class ViewportControls extends PluginUIComponent<ViewportControlsProps, V
                     <div className='msp-semi-transparent-background' />
                     {this.icon('tools', this.toggleControls, 'Toggle Controls', this.plugin.layout.state.showControls)}
                     {this.icon('expand-layout', this.toggleExpanded, 'Toggle Expanded', this.plugin.layout.state.isExpanded)}
-                    {this.icon('settings', this.toggleSettingsExpanded, 'Settings', this.state.isSettingsExpanded)}
+                    {this.icon('settings', this.toggleSettingsExpanded, 'Settings / Controls Info', this.state.isSettingsExpanded)}
                 </div>
             </div>
             {this.state.isScreenshotExpanded && <div className='msp-viewport-controls-panel'>

+ 16 - 8
src/mol-plugin-ui/viewport/help.tsx

@@ -16,17 +16,19 @@ function getBindingsList(bindings: { [k: string]: Binding }) {
     return Object.keys(bindings).map(k => [k, bindings[k]] as [string, Binding])
 }
 
-class BindingsHelp extends React.Component<{ bindings: { [k: string]: Binding } }, { isExpanded: boolean }> {
+class BindingsHelp extends React.PureComponent<{ bindings: { [k: string]: Binding } }, { isExpanded: boolean }> {
     getBindingComponents() {
         const bindingsList = getBindingsList(this.props.bindings)
-        return <ul style={{ paddingLeft: '20px' }}>
+        return <>
             {bindingsList.map(value => {
                 const [name, binding] = value
                 return !Binding.isEmpty(binding)
-                    ? <li key={name}>{Binding.format(binding, name)}</li>
+                    ? <div key={name} style={{ marginBottom: '6px' }}>
+                        <b>{binding.action}</b><br /><span dangerouslySetInnerHTML={{ __html: Binding.format(binding, name) }} />
+                    </div> 
                     : null
             })}
-        </ul>
+        </>
     }
 
     render() {
@@ -42,7 +44,7 @@ class HelpText extends React.PureComponent {
     }
 }
 
-class HelpGroup extends React.Component<{ header: string, initiallyExpanded?: boolean }, { isExpanded: boolean }> {
+class HelpGroup extends React.PureComponent<{ header: string, initiallyExpanded?: boolean }, { isExpanded: boolean }> {
     state = {
         header: this.props.header,
         isExpanded: !!this.props.initiallyExpanded
@@ -69,12 +71,12 @@ function HelpSection(props: { header: string }) {
     return <div className='msp-simple-help-section'>{props.header}</div>;
 }
 
-export class HelpContent extends PluginUIComponent {
+export class ViewportHelpContent extends PluginUIComponent {
     componentDidMount() {
         this.subscribe(this.plugin.events.canvas3d.settingsUpdated, () => this.forceUpdate());
     }
 
-    private getMouseBindingComponents() {
+    render() {
         const interactionBindings: { [k: string]: Binding } = {}
         this.plugin.spec.behaviors.forEach(b => {
             const { bindings } = b.defaultParams
@@ -89,6 +91,12 @@ export class HelpContent extends PluginUIComponent {
             </HelpGroup>
         </>
     }
+}
+
+export class HelpContent extends PluginUIComponent {
+    componentDidMount() {
+        this.subscribe(this.plugin.events.canvas3d.settingsUpdated, () => this.forceUpdate());
+    }
 
     private formatTriggers(binding: Binding) {
         return binding.triggers.map(t => Binding.Trigger.format(t)).join(' or ')
@@ -164,7 +172,7 @@ export class HelpContent extends PluginUIComponent {
             </HelpGroup>
 
             <HelpSection header='Mouse Controls' />
-            {this.getMouseBindingComponents()}
+            <ViewportHelpContent />
         </div>
     }
 }

+ 5 - 1
src/mol-plugin-ui/viewport/simple-settings.tsx

@@ -17,6 +17,7 @@ import { ParamMapping } from '../../mol-util/param-mapping';
 import { Mutable } from '../../mol-util/type-helpers';
 import { PluginUIComponent } from '../base';
 import { ParameterMappingControl } from '../controls/parameters';
+import { ViewportHelpContent } from './help';
 
 export class SimpleSettingsControl extends PluginUIComponent {
     componentDidMount() {
@@ -31,7 +32,10 @@ export class SimpleSettingsControl extends PluginUIComponent {
 
     render() {
         if (!this.plugin.canvas3d) return null;
-        return <ParameterMappingControl mapping={SimpleSettingsMapping} />
+        return <>
+            <ParameterMappingControl mapping={SimpleSettingsMapping} />
+            <ViewportHelpContent />
+        </>
     }
 }
 

+ 3 - 3
src/mol-plugin/behavior/dynamic/camera.ts

@@ -20,12 +20,12 @@ const DefaultFocusLociBindings = {
     clickCenterFocus: Binding([
         Trigger(B.Flag.Auxilary, M.create()),
         Trigger(B.Flag.Primary, M.create({ alt: true }))
-    ], 'Center and focus the clicked element using ${triggers}.'),
+    ], 'Center and focus', 'Click element using ${triggers}'),
 }
 const FocusLociParams = {
     minRadius: PD.Numeric(8, { min: 1, max: 50, step: 1 }),
-    extraRadius: PD.Numeric(4, { min: 1, max: 50, step: 1 }, { description: 'Value added to the bounding-sphere radius of the Loci.' }),
-    durationMs: PD.Numeric(250, { min: 0, max: 1000, step: 1 }, { description: 'Camera transition duration.' }),
+    extraRadius: PD.Numeric(4, { min: 1, max: 50, step: 1 }, { description: 'Value added to the bounding-sphere radius of the Loci' }),
+    durationMs: PD.Numeric(250, { min: 0, max: 1000, step: 1 }, { description: 'Camera transition duration' }),
 
     bindings: PD.Value(DefaultFocusLociBindings, { isHidden: true }),
 }

+ 5 - 5
src/mol-plugin/behavior/dynamic/representation.ts

@@ -27,8 +27,8 @@ const Trigger = Binding.Trigger
 //
 
 const DefaultHighlightLociBindings = {
-    hoverHighlightOnly: Binding([Trigger(B.Flag.None)], 'Highlight hovered element using ${triggers}'),
-    hoverHighlightOnlyExtend: Binding([Trigger(B.Flag.None, M.create({ shift: true }))], 'Extend highlight from selected to hovered element along polymer using ${triggers}'),
+    hoverHighlightOnly: Binding([Trigger(B.Flag.None)], 'Highlight', 'Hover element using ${triggers}'),
+    hoverHighlightOnlyExtend: Binding([Trigger(B.Flag.None, M.create({ shift: true }))], 'Extend highlight', 'From selected to hovered element along polymer using ${triggers}'),
 }
 const HighlightLociParams = {
     bindings: PD.Value(DefaultHighlightLociBindings, { isHidden: true }),
@@ -76,11 +76,11 @@ export const HighlightLoci = PluginBehavior.create({
 
 const DefaultSelectLociBindings = {
     clickSelect: Binding.Empty,
-    clickToggleExtend: Binding([Trigger(B.Flag.Primary, M.create({ shift: true }))], 'Toggle selection of last click element extended along polymer using ${triggers}.'),
+    clickToggleExtend: Binding([Trigger(B.Flag.Primary, M.create({ shift: true }))], 'Toggle extended selection', '${triggers} to extend selection along polymer'),
     clickSelectOnly: Binding.Empty,
-    clickToggle: Binding([Trigger(B.Flag.Primary, M.create())], 'Toggle selection of clicked element using ${triggers}.'),
+    clickToggle: Binding([Trigger(B.Flag.Primary, M.create())], 'Toggle selection', '${triggers} on element'),
     clickDeselect: Binding.Empty,
-    clickDeselectAllOnEmpty: Binding([Trigger(B.Flag.Primary, M.create())], 'Deselect all when clicking on nothing using ${triggers}.'),
+    clickDeselectAllOnEmpty: Binding([Trigger(B.Flag.Primary, M.create())], 'Deselect all', 'Click on nothing using ${triggers}'),
 }
 const SelectLociParams = {
     bindings: PD.Value(DefaultSelectLociBindings, { isHidden: true }),

+ 1 - 1
src/mol-plugin/behavior/dynamic/selection/structure-representation-interaction.ts

@@ -27,7 +27,7 @@ const M = ModifiersKeys
 const Trigger = Binding.Trigger
 
 const DefaultStructureRepresentationInteractionBindings = {
-    clickInteractionAroundOnly: Binding([Trigger(B.Flag.Secondary, M.create()), Trigger(B.Flag.Primary, M.create({ control: true }))], 'Show the structure interaction around only the clicked element using ${triggers}.'),
+    clickInteractionAroundOnly: Binding([Trigger(B.Flag.Secondary, M.create()), Trigger(B.Flag.Primary, M.create({ control: true }))], 'Structure element interaction', 'Click element using ${triggers}; on nothing/same element to hide'),
 }
 
 const StructureRepresentationInteractionParams = (plugin: PluginContext) => {

+ 7 - 6
src/mol-util/binding.ts

@@ -11,19 +11,20 @@ export { Binding }
 
 interface Binding {
     triggers: Binding.Trigger[]
+    action: string
     description: string
 }
 
-function Binding(triggers: Binding.Trigger[], description = '') {
-    return Binding.create(triggers, description)
+function Binding(triggers: Binding.Trigger[], action = '', description = '') {
+    return Binding.create(triggers, action, description)
 }
 
 namespace Binding {
-    export function create(triggers: Trigger[], description = ''): Binding {
-        return { triggers, description }
+    export function create(triggers: Trigger[], action = '', description = ''): Binding {
+        return { triggers, action, description }
     }
 
-    export const Empty: Binding = { triggers: [], description: '' }
+    export const Empty: Binding = { triggers: [], action: '', description: '' }
     export function isEmpty(binding: Binding) {
         return binding.triggers.length === 0 ||
             binding.triggers.every(t => t.buttons === undefined && t.modifiers === undefined)
@@ -35,7 +36,7 @@ namespace Binding {
 
     export function format(binding: Binding, name = '') {
         const help = binding.description || stringToWords(name)
-        return interpolate(help, { triggers: binding.triggers.map(t => Trigger.format(t)).join(' or ') })
+        return interpolate(help, { triggers: '<i>' + binding.triggers.map(t => Trigger.format(t)).join(' or ') + '</i>' })
     }
 
     export interface Trigger {