Browse Source

unified font and svg icons

Alexander Rose 5 years ago
parent
commit
e1d0515fae

+ 1 - 1
src/mol-plugin-ui/controls/action-menu.tsx

@@ -36,7 +36,7 @@ export namespace ActionMenu {
     }
 
     export function Item(label: string, value: unknown): Item
-    export function Item(label: string, icon: string, value: unknown): Item
+    export function Item(label: string, icon: IconName, value: unknown): Item
     export function Item(label: string, iconOrValue: any, value?: unknown): Item {
         if (value) return { kind: 'item', label, icon: iconOrValue, value };
         return { kind: 'item', label, value: iconOrValue };

+ 0 - 3
src/mol-plugin-ui/controls/common.tsx

@@ -8,7 +8,6 @@ import * as React from 'react';
 import { Color } from '../../mol-util/color';
 import { PurePluginUIComponent } from '../base';
 import { IconName, Icon } from './icons';
-import { ShapeName, Shape } from './shapes';
 
 export class ControlGroup extends React.Component<{
     header: string,
@@ -311,7 +310,6 @@ export type ToggleButtonProps = {
     label?: string | JSX.Element,
     title?: string,
     icon?: IconName,
-    shape?: ShapeName,
     isSelected?: boolean,
     toggle: () => void
 }
@@ -329,7 +327,6 @@ export class ToggleButton extends React.PureComponent<ToggleButtonProps> {
         return <button onClick={this.onClick} title={this.props.title}
             disabled={props.disabled} style={props.style} className={className}>
             <Icon name={this.props.icon} />
-            <Shape name={this.props.shape} />
             {label && this.props.isSelected ? <b>{label}</b> : label}
         </button>;
     }

+ 109 - 4
src/mol-plugin-ui/controls/icons.tsx

@@ -2,11 +2,32 @@
  * Copyright (c) 2020 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';
 
-export type IconName =
+export type IconName = FontIconName | SvgIconName
+
+export function Icon(props: {
+    name: IconName | undefined,
+    style?: React.CSSProperties,
+    title?: string
+}) {
+    if (!props.name) return null;
+    switch (props.name) {
+        case 'union':
+        case 'subtract':
+        case 'intersect':
+        case 'set':
+            return <SvgIcon name={props.name} title={props.title} style={props.style} />
+        default: return <FontIcon name={props.name} title={props.title} style={props.style} />
+    }
+}
+
+//
+
+type FontIconName =
     | '' | 'expand-layout' | 'plus' | 'minus' | 'reset-scene' | 'ok' | 'back' | 'block' | 'off' | 'expand' | 'collapse' | 'visual-visibility'
     | 'abort' | 'focus-on-visual' | 'settings' | 'tools' | 'log' | 'remove' | 'help' | 'help-circle' | 'info' | 'left-open-big' | 'right-open-big'
     | 'left-open' | 'right-open' | 'screenshot' | 'model-prev' | 'model-next' | 'model-first' | 'down-thin' | 'up-thin' | 'left-thin' | 'right-thin'
@@ -29,11 +50,95 @@ export type IconName =
     | 'credit-card' | 'clipboard' | 'megaphone' | 'drive' | 'bucket' | 'thermometer' | 'key' | 'flow-branch' | 'flow-line' | 'flow-parallel' | 'rocket'
     | 'gauge' | 'help-circle-collapse' | 'help-circle-expand'
 
-export function Icon(props: {
-    name: IconName | undefined,
+function FontIcon(props: {
+    name: FontIconName,
     style?: React.CSSProperties,
     title?: string
 }) {
-    if (!props.name) return null;
     return <span className={`msp-icon msp-icon-${props.name}`} style={props.style} title={props.title} />;
+}
+
+//
+
+type SvgIconName =
+    | '' | 'set' | 'intersect' | 'union' | 'subtract'
+
+function SvgIcon(props: {
+    name: SvgIconName,
+    style?: React.CSSProperties,
+    title?: string
+}) {
+    return <div className='msp-icon msp-svg-icon' style={props.style} title={props.title}>{getSvg(props.name)}</div>;
+}
+
+function getSvg(name: SvgIconName) {
+    switch (name) {
+        case 'union': return <Union />
+        case 'subtract': return <Subtract />
+        case 'intersect': return <Intersect />
+        case 'set': return <Set />
+    }
+}
+
+const circleLeft = <circle r="6px" id="circle-left" cy="16px" cx="12px" strokeWidth="1"/>
+const circleRight = <circle r="6px" id="circle-right" cy="16px" cx="20px" strokeWidth="1"/>
+
+function Union() {
+    return <svg width="32px" height="32px" viewBox="0 0 32 32">
+        <defs>
+            {circleLeft}
+            {circleRight}
+        </defs>
+        <g>
+            <use href="#circle-left" className="msp-shape-filled"/>
+            <use href="#circle-right" className="msp-shape-filled"/>
+        </g>
+    </svg>;
+}
+
+function Subtract() {
+    return <svg width="32px" height="32px" viewBox="0 0 32 32">
+        <defs>
+            {circleLeft}
+            {circleRight}
+            <mask id="mask-left">
+                <use href="#circle-left" fill="white" stroke="white"/>
+                <use href="#circle-right" fill="black" strokeWidth="0" stroke="white"/>
+            </mask>
+        </defs>
+        <g>
+            <use href="#circle-left" className="msp-shape-filled" mask="url(#mask-left)"/>
+            <use href="#circle-right" className="msp-shape-empty"/>
+        </g>
+    </svg>;
+}
+
+function Intersect() {
+    return <svg width="32px" height="32px" viewBox="0 0 32 32">
+        <defs>
+            {circleLeft}
+            {circleRight}
+            <clipPath id="clip-left">
+                <use href="#circle-right"/>
+            </clipPath>
+        </defs>
+        <g>
+            <use href="#circle-left" className="msp-shape-filled" clipPath="url(#clip-left)"/>
+            <use href="#circle-left" className="msp-shape-empty"/>
+            <use href="#circle-right" className="msp-shape-empty"/>
+        </g>
+    </svg>;
+}
+
+function Set() {
+    return <svg width="32px" height="32px" viewBox="0 0 32 32">
+        <defs>
+            {circleLeft}
+            {circleRight}
+        </defs>
+        <g>
+            <use href="#circle-left" className="msp-shape-empty"/>
+            <use href="#circle-right" className="msp-shape-filled"/>
+        </g>
+    </svg>;
 }

+ 0 - 95
src/mol-plugin-ui/controls/shapes.tsx

@@ -1,95 +0,0 @@
-/**
- * Copyright (c) 2020 mol* contributors, licensed under MIT, See LICENSE file for more info.
- *
- * @author Alexander Rose <alexander.rose@weirdbyte.de>
- */
-
-import * as React from 'react';
-
-export type ShapeName =
-    | '' | 'set' | 'intersect' | 'union' | 'subtract'
-
-export function Shape(props: {
-    name?: ShapeName,
-    style?: React.CSSProperties,
-    title?: string
-}) {
-    const shape = getShape(props.name)
-    if (!shape) return null
-    return <span style={props.style} title={props.title}>
-        {shape}
-    </span>;
-}
-
-function getShape(name?: ShapeName) {
-    switch (name) {
-        case 'union': return <Union />
-        case 'subtract': return <Subtract />
-        case 'intersect': return <Intersect />
-        case 'set': return <Set />
-        default: return null
-    }
-}
-
-const circleLeft = <circle r="6px" id="circle-left" cy="16px" cx="12px" strokeWidth="1"/>
-const circleRight = <circle r="6px" id="circle-right" cy="16px" cx="20px" strokeWidth="1"/>
-
-function Union() {
-    return <svg width="32px" height="32px">
-        <defs>
-            {circleLeft}
-            {circleRight}
-        </defs>
-        <g>
-            <use href="#circle-left" className="msp-shape-filled"/>
-            <use href="#circle-right" className="msp-shape-filled"/>
-        </g>
-    </svg>;
-}
-
-function Subtract() {
-    return <svg width="32px" height="32px">
-        <defs>
-            {circleLeft}
-            {circleRight}
-            <mask id="mask-left">
-                <use href="#circle-left" fill="white" stroke="white"/>
-                <use href="#circle-right" fill="black" strokeWidth="0" stroke="white"/>
-            </mask>
-        </defs>
-        <g>
-            <use href="#circle-left" className="msp-shape-filled" mask="url(#mask-left)"/>
-            <use href="#circle-right" className="msp-shape-empty"/>
-        </g>
-    </svg>;
-}
-
-function Intersect() {
-    return <svg width="32px" height="32px">
-        <defs>
-            {circleLeft}
-            {circleRight}
-            <clipPath id="clip-left">
-                <use href="#circle-right"/>
-            </clipPath>
-        </defs>
-        <g>
-            <use href="#circle-left" className="msp-shape-filled" clipPath="url(#clip-left)"/>
-            <use href="#circle-left" className="msp-shape-empty"/>
-            <use href="#circle-right" className="msp-shape-empty"/>
-        </g>
-    </svg>;
-}
-
-function Set() {
-    return <svg width="32px" height="32px">
-        <defs>
-            {circleLeft}
-            {circleRight}
-        </defs>
-        <g>
-            <use href="#circle-left" className="msp-shape-empty"/>
-            <use href="#circle-right" className="msp-shape-filled"/>
-        </g>
-    </svg>;
-}

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

@@ -335,6 +335,7 @@
 
     .msp-action-menu-button {
         margin-top: 1px;
+        display: flex;
         .msp-icon {
             font-size: 80%;
             margin-right: 6px;

+ 10 - 0
src/mol-plugin-ui/skin/base/icons.scss

@@ -25,6 +25,16 @@
   -moz-osx-font-smoothing: grayscale;
 }
 
+.msp-svg-icon svg {
+  height: 2.25em;
+  width: 2.25em;
+}
+
+.msp-svg-icon {
+  display: inline-flex;
+  align-self: center;
+}
+
 .msp-icon-help-circle-expand {
 	width: 2.5em !important;
 }

+ 4 - 4
src/mol-plugin-ui/structure/components.tsx

@@ -258,13 +258,13 @@ class StructureComponentGroup extends PurePluginUIComponent<{ group: StructureCo
         if (mng.canBeModified(this.props.group[0])) {
             ret.push([
                 ActionMenu.Header('Modify by Selection'),
-                ActionMenu.Item('Include', 'plus', () => mng.modifyByCurrentSelection(this.props.group, 'union')),
-                ActionMenu.Item('Subtract', 'minus', () => mng.modifyByCurrentSelection(this.props.group, 'subtract')),
-                ActionMenu.Item('Intersect', 'shuffle', () => mng.modifyByCurrentSelection(this.props.group, 'intersect'))
+                ActionMenu.Item('Include', 'union', () => mng.modifyByCurrentSelection(this.props.group, 'union')),
+                ActionMenu.Item('Subtract', 'subtract', () => mng.modifyByCurrentSelection(this.props.group, 'subtract')),
+                ActionMenu.Item('Intersect', 'intersect', () => mng.modifyByCurrentSelection(this.props.group, 'intersect'))
             ]);
         }
 
-        ret.push(ActionMenu.Item('Select This', 'flash', () => mng.selectThis(this.props.group)));
+        ret.push(ActionMenu.Item('Select This', 'set', () => mng.selectThis(this.props.group)));
 
         return ret;
     }

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

@@ -126,10 +126,10 @@ export class StructureSelectionControls<P, S extends StructureSelectionControlsS
     get controls() {
         return <>
             <div className='msp-control-row msp-select-row'>
-                <ToggleButton shape='union' title={ActionHeader.get('add')} toggle={this.toggleAdd} isSelected={this.state.action === 'add'} disabled={this.isDisabled} />
-                <ToggleButton shape='subtract' title={ActionHeader.get('remove')} toggle={this.toggleRemove} isSelected={this.state.action === 'remove'} disabled={this.isDisabled} />
-                <ToggleButton shape='intersect' title={ActionHeader.get('intersect')} toggle={this.toggleIntersect} isSelected={this.state.action === 'intersect'} disabled={this.isDisabled} />
-                <ToggleButton shape='set' title={ActionHeader.get('set')} toggle={this.toggleSet} isSelected={this.state.action === 'set'} disabled={this.isDisabled} />
+                <ToggleButton icon='union' title={ActionHeader.get('add')} toggle={this.toggleAdd} isSelected={this.state.action === 'add'} disabled={this.isDisabled} />
+                <ToggleButton icon='subtract' title={ActionHeader.get('remove')} toggle={this.toggleRemove} isSelected={this.state.action === 'remove'} disabled={this.isDisabled} />
+                <ToggleButton icon='intersect' title={ActionHeader.get('intersect')} toggle={this.toggleIntersect} isSelected={this.state.action === 'intersect'} disabled={this.isDisabled} />
+                <ToggleButton icon='set' title={ActionHeader.get('set')} toggle={this.toggleSet} isSelected={this.state.action === 'set'} disabled={this.isDisabled} />
                 <ToggleButton icon='brush' title='Color' toggle={this.toggleColor} isSelected={this.state.action === 'color'} disabled={this.isDisabled} />
             </div>
             {(this.state.action && this.state.action !== 'color') && <ActionMenu header={ActionHeader.get(this.state.action as StructureSelectionModifier)} items={this.queries} onSelect={this.selectQuery} />}