Jelajahi Sumber

various ui tweaks, added CollapsableControls

Alexander Rose 5 tahun lalu
induk
melakukan
afa7a04af0

+ 2 - 2
src/mol-plugin/skin/base/components/controls.scss

@@ -259,7 +259,7 @@
     }
 }
 
-.msp-conrol-group-expander {
+.msp-control-group-expander {
     display: block;
     position: absolute;
     line-height: $row-height;
@@ -312,7 +312,7 @@
 
 .msp-help:hover span {
     display: inline-block;
-    background: linear-gradient($default-background, change-color($default-background, $alpha: 0.5));
+    background: linear-gradient($default-background, change-color($default-background, $alpha: 0.8));
 }
 
 .msp-help-text {

+ 1 - 0
src/mol-plugin/skin/base/components/temp.scss

@@ -5,6 +5,7 @@
 .msp-section-header {
     height: $row-height;
     line-height: $row-height;
+    margin-top: $control-spacing;
     margin-bottom: $control-spacing;
     text-align: right;
     padding: 0 $control-spacing;

+ 23 - 16
src/mol-plugin/skin/base/icons.scss

@@ -1,16 +1,13 @@
-
 [class^="msp-icon-"]:before, [class*=" msp-icon-"]:before {
   font-family: "fontello";
   font-style: normal;
   font-weight: normal;
-  speak: none;
 
   display: inline-block;
   text-decoration: inherit;
   width: 1em;
   margin-right: .2em;
   text-align: center;
-  /* opacity: .8; */
 
   /* For safety - reset parent styles, that can break glyph codes*/
   font-variant: normal;
@@ -23,15 +20,9 @@
   /* remove if not needed */
   margin-left: .2em;
 
-  /* you can be more comfortable with increased icons size */
-  /* font-size: 120%; */
-
   /* Font smoothing. That was taken from TWBS */
   -webkit-font-smoothing: antialiased;
   -moz-osx-font-smoothing: grayscale;
-
-  /* Uncomment for 3D effect */
-  /* text-shadow: 1px 1px 1px rgba(127, 127, 127, 0.3); */
 }
 
 .msp-icon-expand-layout:before {
@@ -103,31 +94,31 @@
 }
 
 .msp-icon-help:before {
-    content: '\e81c'
+    content: "\e81c";
 }
 
 .msp-icon-help-circle:before {
-	content: '\e81d';
+	content: "\e81d";
 }
 
 .msp-icon-info:before {
-    content: '\e81e'
+    content: "\e81e";
 }
 
 .msp-icon-left-open-big:before {
-    content: '\e87c'
+    content: "\e87c";
 }
 
 .msp-icon-right-open-big:before {
-    content: '\e87d'
+    content: "\e87d";
 }
 
 .msp-icon-left-open:before {
-    content: '\e874'
+    content: "\e874";
 }
 
 .msp-icon-right-open:before {
-    content: '\e875'
+    content: "\e875";
 }
 
 .msp-icon-screenshot:before {
@@ -213,3 +204,19 @@
 .msp-icon-tape:before {
 	content: "\e8c8";
 }
+
+.msp-icon-help-circle-expand {
+	width: 2.5em !important;
+}
+.msp-icon-help-circle-expand:before {
+	width: 2.5em !important;
+	content: "\e81d\0020\e885";
+}
+
+.msp-icon-help-circle-collapse {
+	width: 2.5em !important;
+}
+.msp-icon-help-circle-collapse:before {
+	width: 2.5em !important;
+	content: "\e81d\0020\e883";
+}

+ 38 - 2
src/mol-plugin/ui/base.tsx

@@ -1,7 +1,8 @@
 /**
- * Copyright (c) 2018 mol* contributors, licensed under MIT, See LICENSE file for more info.
+ * Copyright (c) 2018-2019 mol* contributors, licensed under MIT, See LICENSE file for more info.
  *
  * @author David Sehnal <david.sehnal@gmail.com>
+ * @author Alexander Rose <alexander.rose@weirdbyte.de>
  */
 
 import * as React from 'react';
@@ -61,4 +62,39 @@ export abstract class PurePluginUIComponent<P = {}, S = {}, SS = {}> extends Rea
 }
 
 export type _Props<C extends React.Component> = C extends React.Component<infer P> ? P : never
-export type _State<C extends React.Component> = C extends React.Component<any, infer S> ? S : never
+export type _State<C extends React.Component> = C extends React.Component<any, infer S> ? S : never
+
+//
+
+export type CollapsableProps = { initiallyCollapsed?: boolean, header?: string }
+export type CollapsableState = { isCollapsed: boolean, header: string }
+
+export abstract class CollapsableControls<P extends CollapsableProps = CollapsableProps, S extends CollapsableState = CollapsableState, SS = {}> extends PluginUIComponent<P, S, SS> {
+    toggleCollapsed = () => {
+        this.setState({ isCollapsed: !this.state.isCollapsed })
+    }
+
+    protected abstract defaultState(): S
+    protected abstract renderControls(): JSX.Element | null
+
+    render() {
+        const wrapClass = this.state.isCollapsed
+            ? 'msp-transform-wrapper msp-transform-wrapper-collapsed'
+            : 'msp-transform-wrapper';
+
+        return <div className={wrapClass}>
+            <div className='msp-transform-header'>
+                <button className='msp-btn msp-btn-block' onClick={this.toggleCollapsed}>
+                    <span className={`msp-icon msp-icon-${this.state.isCollapsed ? 'expand' : 'collapse'}`} />
+                    {this.state.header}
+                </button>
+            </div>
+            {!this.state.isCollapsed && this.renderControls()}
+        </div>
+    }
+
+    constructor(props: P, context?: any) {
+        super(props, context)
+        this.state = this.defaultState()
+    }
+}

+ 1 - 1
src/mol-plugin/ui/controls/common.tsx

@@ -122,7 +122,7 @@ export class ExpandableGroup extends React.Component<{
             <div className='msp-control-row'>
                 <span>
                     {label}
-                    <button className='msp-btn-link msp-btn-icon msp-conrol-group-expander' onClick={this.toggleExpanded} title={`${this.state.isExpanded ? 'Less' : 'More'} options`}
+                    <button className='msp-btn-link msp-btn-icon msp-control-group-expander' onClick={this.toggleExpanded} title={`${this.state.isExpanded ? 'Less' : 'More'} options`}
                         style={{ background: 'transparent', textAlign: 'left', padding: '0' }}>
                         <span className={`msp-icon msp-icon-${this.state.isExpanded ? 'minus' : 'plus'}`} style={{ display: 'inline-block' }} />
                     </button>

+ 2 - 2
src/mol-plugin/ui/controls/parameters.tsx

@@ -129,9 +129,9 @@ export abstract class SimpleParam<P extends PD.Any> extends React.PureComponent<
                 <span title={this.props.param.description}>
                     {label}
                     {hasHelp &&
-                        <button className='msp-help msp-btn-link msp-btn-icon msp-conrol-group-expander' onClick={this.toggleExpanded} title={`${this.state.isExpanded ? 'Hide' : 'Show'} help`}
+                        <button className='msp-help msp-btn-link msp-btn-icon msp-control-group-expander' onClick={this.toggleExpanded} title={`${this.state.isExpanded ? 'Hide' : 'Show'} help`}
                                 style={{ background: 'transparent', textAlign: 'left', padding: '0' }}>
-                                <span className={`msp-icon msp-icon-help-circle`} />
+                                <span className={`msp-icon msp-icon-help-circle-${this.state.isExpanded ? 'collapse' : 'expand'}`} />
                         </button>
                     }
                 </span>

+ 1 - 6
src/mol-plugin/ui/state/common.tsx

@@ -182,18 +182,13 @@ abstract class TransformControlBase<P, S extends TransformControlBase.ComponentS
         const wrapClass = this.state.isCollapsed
             ? 'msp-transform-wrapper msp-transform-wrapper-collapsed'
             : 'msp-transform-wrapper';
-        // this.isUpdate()
-        //     ? !isEmpty && !this.state.isCollapsed
-        //     ? 'msp-transform-update-wrapper'
-        //     : 'msp-transform-update-wrapper-collapsed'
-        //     : 'msp-transform-wrapper';
 
         const { a, b } = this.getSourceAndTarget();
         return <div className={wrapClass}>
             <div className='msp-transform-header'>
                 <button className='msp-btn msp-btn-block' onClick={this.toggleExpanded} title={display.description}>
+                    <span className={`msp-icon msp-icon-${this.state.isCollapsed ? 'expand' : 'collapse'}`} />
                     {display.name}
-                    {/* {!isEmpty && this.state.isCollapsed && this.isUpdate() && <small>Click to Edit</small>} */}
                 </button>
             </div>
             {!isEmpty && !this.state.isCollapsed && <>

+ 11 - 6
src/mol-plugin/ui/structure/representation.tsx

@@ -15,6 +15,7 @@ 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';
+import { CollapsableControls } from '../base';
 
 abstract class BaseStructureRepresentationControls extends PluginUIComponent {
     onChange = (value: string) => {
@@ -85,7 +86,7 @@ class SelectionStructureRepresentationControls extends BaseStructureRepresentati
     }
 }
 
-export class StructureRepresentationControls extends PluginUIComponent {
+export class StructureRepresentationControls extends CollapsableControls {
     preset = async (value: string) => {
         const presetFn = P[value as keyof typeof P]
         if (presetFn) {
@@ -121,15 +122,19 @@ export class StructureRepresentationControls extends PluginUIComponent {
         }
     }
 
-    render() {
+    defaultState() {
+        return {
+            isCollapsed: false,
+            header: 'Representation'
+        }
+    }
+
+    renderControls() {
         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>
+        return <div>
             <div className='msp-control-row'>
                 <div className='msp-select-row'>
                     <ButtonSelect label='Preset' onChange={this.preset}>

+ 31 - 31
src/mol-plugin/ui/structure/selection.tsx

@@ -5,7 +5,7 @@
  */
 
 import * as React from 'react';
-import { PluginUIComponent } from '../base';
+import { CollapsableControls } from '../base';
 import { StructureSelectionQueries, SelectionModifier } from '../../util/structure-selection-helper';
 import { ButtonSelect, Options } from '../controls/common';
 import { PluginCommands } from '../../command';
@@ -18,9 +18,7 @@ const StructureSelectionParams = {
     granularity: Interactivity.Params.granularity,
 }
 
-export class StructureSelectionControls extends PluginUIComponent<{}, {}> {
-    state = {}
-
+export class StructureSelectionControls extends CollapsableControls {
     componentDidMount() {
         this.subscribe(this.plugin.events.interactivity.selectionUpdated, () => {
             this.forceUpdate()
@@ -61,38 +59,40 @@ export class StructureSelectionControls extends PluginUIComponent<{}, {}> {
     remove = (value: string) => this.set('remove', value)
     only = (value: string) => this.set('only', value)
 
-    render() {
+    defaultState() {
+        return {
+            isCollapsed: false,
+            header: 'Selection'
+        }
+    }
+
+    renderControls() {
         const queries = Object.keys(StructureSelectionQueries).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'>Selection</button>
+        return <div>
+            <div className='msp-control-row msp-row-text'>
+                <div>{this.stats}</div>
             </div>
-            <div>
-                <div className='msp-control-row msp-row-text'>
-                    <div>{this.stats}</div>
-                </div>
-                <ParameterControls params={StructureSelectionParams} values={this.values} onChange={this.setProps} />
-                <div className='msp-control-row'>
-                    <div className='msp-select-row'>
-                        <ButtonSelect label='Add' onChange={this.add}>
-                            <optgroup label='Add'>
-                                {Options(queries)}
-                            </optgroup>
-                        </ButtonSelect>
-                        <ButtonSelect label='Remove' onChange={this.remove}>
-                            <optgroup label='Remove'>
-                                {Options(queries)}
-                            </optgroup>
-                        </ButtonSelect>
-                        <ButtonSelect label='Only' onChange={this.only}>
-                            <optgroup label='Only'>
-                                {Options(queries)}
-                            </optgroup>
-                        </ButtonSelect>
-                    </div>
+            <ParameterControls params={StructureSelectionParams} values={this.values} onChange={this.setProps} />
+            <div className='msp-control-row'>
+                <div className='msp-select-row'>
+                    <ButtonSelect label='Add' onChange={this.add}>
+                        <optgroup label='Add'>
+                            {Options(queries)}
+                        </optgroup>
+                    </ButtonSelect>
+                    <ButtonSelect label='Remove' onChange={this.remove}>
+                        <optgroup label='Remove'>
+                            {Options(queries)}
+                        </optgroup>
+                    </ButtonSelect>
+                    <ButtonSelect label='Only' onChange={this.only}>
+                        <optgroup label='Only'>
+                            {Options(queries)}
+                        </optgroup>
+                    </ButtonSelect>
                 </div>
             </div>
         </div>