- );
- }
-}
-
-export default JogPad;
diff --git a/src/web/widgets/Axes/Keypad.jsx b/src/web/widgets/Axes/Keypad.jsx
new file mode 100644
index 000000000..be88d004f
--- /dev/null
+++ b/src/web/widgets/Axes/Keypad.jsx
@@ -0,0 +1,434 @@
+import includes from 'lodash/includes';
+import classNames from 'classnames';
+import PropTypes from 'prop-types';
+import React, { PureComponent } from 'react';
+import { Button } from '../../components/Buttons';
+import Dropdown, { MenuItem } from '../../components/Dropdown';
+import controller from '../../lib/controller';
+import ensureArray from '../../lib/ensure-array';
+import i18n from '../../lib/i18n';
+import styles from './index.styl';
+
+class Keypad extends PureComponent {
+ static propTypes = {
+ config: PropTypes.objct,
+ state: PropTypes.object,
+ actions: PropTypes.object
+ };
+
+ handleSelect = (eventKey) => {
+ const commands = ensureArray(eventKey);
+ commands.forEach(command => controller.command('gcode', command));
+ };
+
+ render() {
+ const { config, state, actions } = this.props;
+ const { canClick, axes, keypadJogging, selectedAxis } = state;
+ const canClickX = canClick && includes(axes, 'x');
+ const canClickY = canClick && includes(axes, 'y');
+ const canClickXY = canClickX && canClickY;
+ const canClickZ = canClick && includes(axes, 'z');
+ const canClickA = canClick && includes(axes, 'a');
+ const highlightX = canClickX && (keypadJogging || selectedAxis === 'x');
+ const highlightY = canClickY && (keypadJogging || selectedAxis === 'y');
+ const highlightZ = canClickZ && (keypadJogging || selectedAxis === 'z');
+ const highlightA = canClickA && (keypadJogging || selectedAxis === 'a');
+
+ return (
+
+
+
+
+
+ {
+ const distance = actions.getJogDistance();
+ actions.jog({ X: -distance, Y: distance });
+ }}
+ disabled={!canClickXY}
+ title={i18n._('Move X- Y+')}
+ >
+
+
+
+
+
+
+ {
+ const distance = actions.getJogDistance();
+ actions.jog({ Y: distance });
+ }}
+ disabled={!canClickY}
+ title={i18n._('Move Y+')}
+ >
+ Y
+
+
+
+
+
+
+
+
+ {
+ const distance = actions.getJogDistance();
+ actions.jog({ X: distance, Y: distance });
+ }}
+ disabled={!canClickXY}
+ title={i18n._('Move X+ Y+')}
+ >
+
+
+
+
+
+
+ {
+ const distance = actions.getJogDistance();
+ actions.jog({ Z: distance });
+ }}
+ disabled={!canClickZ}
+ title={i18n._('Move Z+')}
+ >
+ Z
+
+
+
+
+
+
+
+
+ {
+ const distance = actions.getJogDistance();
+ actions.jog({ A: distance });
+ }}
+ disabled={!canClickA}
+ title={i18n._('Move A+')}
+ >
+ A
+
+
+
+
+
+
+
+
+ {
+ const wzero = config.get('wzero');
+ controller.command('gcode', wzero);
+ }}
+ disabled={!canClick}
+ title={i18n._('Go To Work Zero')}
+ >
+ W
+
+
+
+
+
+
+
+
+
+
+
+
+ {
+ const distance = actions.getJogDistance();
+ actions.jog({ X: -distance });
+ }}
+ disabled={!canClickX}
+ title={i18n._('Move X-')}
+ >
+ X
+
+
+
+
+
+
+
+
+ actions.move({ X: 0, Y: 0 })}
+ disabled={!canClickXY}
+ title={i18n._('Move To XY Zero (G0 X0 Y0)')}
+ >
+ X/Y
+
+
+
+
+
+ {
+ const distance = actions.getJogDistance();
+ actions.jog({ X: distance });
+ }}
+ disabled={!canClickX}
+ title={i18n._('Move X+')}
+ >
+ X
+ +
+
+
+
+
+
+ actions.move({ Z: 0 })}
+ disabled={!canClickZ}
+ title={i18n._('Move To Z Zero (G0 Z0)')}
+ >
+ Z
+
+
+
+
+
+
+
+
+ actions.move({ A: 0 })}
+ disabled={!canClickA}
+ title={i18n._('Move To A Zero (G0 A0)')}
+ >
+ A
+
+
+
+
+
+
+
+
+ {
+ const mzero = config.get('mzero');
+ controller.command('gcode', mzero);
+ }}
+ disabled={!canClick}
+ title={i18n._('Go To Machine Zero')}
+ >
+ M
+
+
+
+
+
+
+
+
+
+
+
+
+ {
+ const distance = actions.getJogDistance();
+ actions.jog({ X: -distance, Y: -distance });
+ }}
+ disabled={!canClickXY}
+ title={i18n._('Move X- Y-')}
+ >
+
+
+
+
+
+
+ {
+ const distance = actions.getJogDistance();
+ actions.jog({ Y: -distance });
+ }}
+ disabled={!canClickY}
+ title={i18n._('Move Y-')}
+ >
+ Y
+
+
+
+
+
+
+
+
+ {
+ const distance = actions.getJogDistance();
+ actions.jog({ X: distance, Y: -distance });
+ }}
+ disabled={!canClickXY}
+ title={i18n._('Move X+ Y-')}
+ >
+
+
+
+
+
+
+ {
+ const distance = actions.getJogDistance();
+ actions.jog({ Z: -distance });
+ }}
+ disabled={!canClickZ}
+ title={i18n._('Move Z-')}
+ >
+ Z
+
+
+
+
+
+
+
+
+ {
+ const distance = actions.getJogDistance();
+ actions.jog({ A: -distance });
+ }}
+ disabled={!canClickA}
+ title={i18n._('Move A-')}
+ >
+ A
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ );
+ }
+}
+
+export default Keypad;
diff --git a/src/web/widgets/Axes/KeypadOverlay.jsx b/src/web/widgets/Axes/KeypadOverlay.jsx
new file mode 100644
index 000000000..c28f2720c
--- /dev/null
+++ b/src/web/widgets/Axes/KeypadOverlay.jsx
@@ -0,0 +1,148 @@
+import React from 'react';
+import { Tooltip, OverlayTrigger } from 'react-bootstrap';
+import i18n from '../../lib/i18n';
+
+const keypadTooltip = () => {
+ const styles = {
+ tooltip: {
+ fontFamily: 'Consolas, Menlo, Monaco, Lucida Console, Liberation Mono, DejaVu Sans Mono, Bitstream Vera Sans Mono, Courier New, monospace, serif',
+ padding: 5
+ },
+ container: {
+ padding: 5
+ },
+ axisDirection: {
+ marginRight: 10
+ },
+ divider: {
+ borderTop: '1px solid #ccc',
+ marginTop: 5,
+ paddingTop: 5
+ },
+ kbd: {
+ border: '1px solid #aaa',
+ padding: '1px 4px',
+ fontFamily: 'sans-serif',
+ whiteSpace: 'nowrap'
+ },
+ icon: {
+ minWidth: 10,
+ textAlign: 'center'
+ }
+ };
+
+ return (
+
+
+
+
+ X+
+
+
+
+
+ {i18n._('Right')}
+
+
+ X-
+
+
+
+
+ {i18n._('Left')}
+
+
+ Y+
+
+
+
+
+ {i18n._('Up')}
+
+
+ Y-
+
+
+
+
+ {i18n._('Down')}
+
+
+ Z+
+
+
+
+
+ {i18n._('Page Up')}
+
+
+ Z-
+
+
+
+
+ {i18n._('Page Down')}
+
+
+ A+
+
+ {' ] '}
+
+
+ {i18n._('Right Square Bracket')}
+
+
+ A-
+
+ {' [ '}
+
+
+ {i18n._('Left Square Bracket')}
+
+
+
+
+
+
+
+
{i18n._('0.1x Move')}
+
+ {i18n._('Alt')}
+
+
+
+
{i18n._('10x Move')}
+
+ {i18n._('⇧ Shift')}
+
+
+
+
+
+
+
+ );
+};
+
+export default (props) => {
+ const { show, children } = { ...props };
+
+ if (!show) {
+ return children;
+ }
+
+ return (
+
+ {children}
+
+ );
+};
diff --git a/src/web/widgets/Axes/MotionButtonGroup.jsx b/src/web/widgets/Axes/MotionButtonGroup.jsx
deleted file mode 100644
index 92279c5fe..000000000
--- a/src/web/widgets/Axes/MotionButtonGroup.jsx
+++ /dev/null
@@ -1,86 +0,0 @@
-import React, { Component, PropTypes } from 'react';
-import shallowCompare from 'react-addons-shallow-compare';
-import { DropdownButton, MenuItem } from 'react-bootstrap';
-import i18n from '../../lib/i18n';
-import controller from '../../lib/controller';
-import styles from './index.styl';
-
-class MotionButtonGroup extends Component {
- static propTypes = {
- state: PropTypes.object,
- actions: PropTypes.object
- };
-
- shouldComponentUpdate(nextProps, nextState) {
- return shallowCompare(this, nextProps, nextState);
- }
- handleSelect(eventKey) {
- const data = eventKey;
- if (data) {
- controller.command('gcode', data);
- }
- }
- render() {
- const { state } = this.props;
- const { canClick } = state;
-
- return (
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- controller.command('gcode', 'G0 X0 Y0 Z0')}
- disabled={!canClick}
- >
- {i18n._('Go To Work Zero')}
-
-
-
-
-
-
- controller.command('gcode', 'G53 G0 X0 Y0 Z0')}
- disabled={!canClick}
- >
- {i18n._('Go To Machine Zero')}
-
-
-
-
-
- );
- }
-}
-
-export default MotionButtonGroup;
diff --git a/src/web/widgets/Axes/PositionInput.jsx b/src/web/widgets/Axes/PositionInput.jsx
index 5e9f77897..661aca0b9 100644
--- a/src/web/widgets/Axes/PositionInput.jsx
+++ b/src/web/widgets/Axes/PositionInput.jsx
@@ -1,6 +1,7 @@
-import React, { Component, PropTypes } from 'react';
+import PropTypes from 'prop-types';
+import React, { PureComponent } from 'react';
-class PositionInput extends Component {
+class PositionInput extends PureComponent {
static propTypes = {
defaultValue: PropTypes.string,
onOK: PropTypes.func.isRequired,
diff --git a/src/web/widgets/Axes/Settings.jsx b/src/web/widgets/Axes/Settings.jsx
deleted file mode 100644
index 564d769ff..000000000
--- a/src/web/widgets/Axes/Settings.jsx
+++ /dev/null
@@ -1,77 +0,0 @@
-import PropTypes from 'prop-types';
-import React, { Component } from 'react';
-import Modal from '../../components/Modal';
-import i18n from '../../lib/i18n';
-import AxesSettings from './AxesSettings';
-import ShuttleSettings from './ShuttleSettings';
-
-class Settings extends Component {
- static propTypes = {
- state: PropTypes.object,
- actions: PropTypes.object
- };
-
- saveChanges() {
- const { actions } = this.props;
- const { axes } = this.axesSettings.state;
- const { feedrateMin, feedrateMax, hertz, overshoot } = this.shuttleSettings.state;
-
- actions.saveConfig({
- axes,
- feedrateMin,
- feedrateMax,
- hertz,
- overshoot
- });
- }
- render() {
- const { state, actions } = this.props;
- const { axes, feedrateMin, feedrateMax, hertz, overshoot } = state.modal.params;
-
- return (
-
-
- {i18n._('Axes Settings')}
-
-
- {
- this.axesSettings = node;
- }}
- axes={axes}
- />
- {
- this.shuttleSettings = node;
- }}
- feedrateMin={feedrateMin}
- feedrateMax={feedrateMax}
- hertz={hertz}
- overshoot={overshoot}
- />
-
-
-
- {i18n._('Cancel')}
-
- {
- actions.closeModal();
- this.saveChanges();
- }}
- >
- {i18n._('Save Changes')}
-
-
-
- );
- }
-}
-
-export default Settings;
diff --git a/src/web/widgets/Axes/Settings/General.jsx b/src/web/widgets/Axes/Settings/General.jsx
new file mode 100644
index 000000000..c268f8907
--- /dev/null
+++ b/src/web/widgets/Axes/Settings/General.jsx
@@ -0,0 +1,150 @@
+import get from 'lodash/get';
+import includes from 'lodash/includes';
+import PropTypes from 'prop-types';
+import React, { PureComponent } from 'react';
+import i18n from '../../../lib/i18n';
+import Validation from '../../../lib/react-validation';
+
+class General extends PureComponent {
+ static propTypes = {
+ show: PropTypes.bool,
+ axes: PropTypes.array.isRequired,
+ wzero: PropTypes.string.isRequired,
+ mzero: PropTypes.string.isRequired
+ };
+ static defaultProps = {
+ show: false
+ };
+
+ fields = {
+ axisX: null,
+ axisY: null,
+ axisZ: null,
+ axisA: null,
+ wzero: null,
+ mzero: null
+ };
+
+ get value() {
+ const axes = [];
+ this.fields.axisX.checked && axes.push('x');
+ this.fields.axisY.checked && axes.push('y');
+ this.fields.axisZ.checked && axes.push('z');
+ this.fields.axisA.checked && axes.push('a');
+
+ return {
+ axes: axes,
+ wzero: get(this.fields.wzero, 'state.value'),
+ mzero: get(this.fields.mzero, 'state.value')
+ };
+ }
+ render() {
+ const { show, axes, wzero, mzero } = this.props;
+
+ return (
+
+
+
+
{
+ this.form = node;
+ }}
+ onSubmit={(event) => {
+ event.preventDefault();
+ }}
+ >
+
+
+
+ {
+ this.fields.wzero = node;
+ }}
+ className="form-control"
+ rows="2"
+ name="wzero"
+ value={wzero}
+ placeholder="G0 X0 Y0 Z0"
+ validations={['required']}
+ />
+
+
+
+ {
+ this.fields.mzero = node;
+ }}
+ className="form-control"
+ rows="2"
+ name="mzero"
+ value={mzero}
+ placeholder="G53 G0 X0 Y0 Z0"
+ validations={['required']}
+ />
+
+
+
+
+ );
+ }
+}
+
+export default General;
diff --git a/src/web/widgets/Axes/Settings/ShuttleXpress.jsx b/src/web/widgets/Axes/Settings/ShuttleXpress.jsx
new file mode 100644
index 000000000..16150d19c
--- /dev/null
+++ b/src/web/widgets/Axes/Settings/ShuttleXpress.jsx
@@ -0,0 +1,110 @@
+import Slider from 'rc-slider';
+import PropTypes from 'prop-types';
+import React, { PureComponent } from 'react';
+import i18n from '../../../lib/i18n';
+
+const FEEDRATE_RANGE = [100, 2500];
+const FEEDRATE_STEP = 50;
+const OVERSHOOT_RANGE = [1, 1.5];
+const OVERSHOOT_STEP = 0.01;
+
+class ShuttleXpress extends PureComponent {
+ static propTypes = {
+ show: PropTypes.bool,
+ feedrateMin: PropTypes.number,
+ feedrateMax: PropTypes.number,
+ hertz: PropTypes.number,
+ overshoot: PropTypes.number
+ };
+ static defaultProps = {
+ show: false
+ };
+
+ state = this.getInitialState();
+
+ getInitialState() {
+ const {
+ feedrateMin,
+ feedrateMax,
+ hertz,
+ overshoot
+ } = this.props;
+
+ return { feedrateMin, feedrateMax, hertz, overshoot };
+ }
+ componentWillReceiveProps(nextProps) {
+ const {
+ feedrateMin,
+ feedrateMax,
+ hertz,
+ overshoot
+ } = nextProps;
+
+ this.setState({ feedrateMin, feedrateMax, hertz, overshoot });
+ }
+ onFeedrateSliderChange(value) {
+ const [min, max] = value;
+ this.setState({
+ feedrateMin: min,
+ feedrateMax: max
+ });
+ }
+ onHertzChange(event) {
+ const { value } = event.target;
+ const hertz = Number(value);
+ this.setState({ hertz });
+ }
+ onOvershootSliderChange(value) {
+ const overshoot = value;
+ this.setState({ overshoot });
+ }
+ render() {
+ const { show } = this.props;
+ const { feedrateMin, feedrateMax, hertz, overshoot } = this.state;
+
+ return (
+
+
+
+ {i18n._('Feed Rate Range: {{min}} - {{max}} mm/min', { min: feedrateMin, max: feedrateMax })}
+
+
+
+
+
+
+
+
+
{i18n._('Distance Overshoot: {{overshoot}}x', { overshoot: overshoot })}
+
+
+
+ );
+ }
+}
+
+export default ShuttleXpress;
diff --git a/src/web/widgets/Axes/Settings/index.jsx b/src/web/widgets/Axes/Settings/index.jsx
new file mode 100644
index 000000000..3078cfea7
--- /dev/null
+++ b/src/web/widgets/Axes/Settings/index.jsx
@@ -0,0 +1,147 @@
+import noop from 'lodash/noop';
+import PropTypes from 'prop-types';
+import React, { PureComponent } from 'react';
+import Modal from '../../../components/Modal';
+import { Nav, NavItem } from '../../../components/Navs';
+import ensureArray from '../../../lib/ensure-array';
+import i18n from '../../../lib/i18n';
+import General from './General';
+import ShuttleXpress from './ShuttleXpress';
+import {
+ DEFAULT_AXES
+} from '../constants';
+
+class Settings extends PureComponent {
+ static propTypes = {
+ config: PropTypes.object.isRequired,
+ onSave: PropTypes.func,
+ onCancel: PropTypes.func
+ };
+ static defaultProps = {
+ onSave: noop,
+ onCancel: noop
+ };
+
+ config = this.props.config;
+ node = {
+ general: null,
+ shuttleXpress: null
+ };
+ state = {
+ activeKey: 'general'
+ };
+
+ load = () => {
+ return {
+ // General
+ general: {
+ axes: this.config.get('axes', DEFAULT_AXES),
+ wzero: this.config.get('wzero'),
+ mzero: this.config.get('mzero')
+ },
+ // ShuttleXpress
+ shuttleXpress: {
+ feedrateMin: this.config.get('shuttle.feedrateMin'),
+ feedrateMax: this.config.get('shuttle.feedrateMax'),
+ hertz: this.config.get('shuttle.hertz'),
+ overshoot: this.config.get('shuttle.overshoot')
+ }
+ };
+ };
+ save = () => {
+ // General
+ const { axes = DEFAULT_AXES, wzero, mzero } = this.node.general.value;
+ this.config.replace('axes', ensureArray(axes));
+ this.config.set('wzero', wzero);
+ this.config.set('mzero', mzero);
+
+ // ShuttleXpress
+ const { feedrateMin, feedrateMax, hertz, overshoot } = this.node.shuttleXpress.state;
+ this.config.set('shuttle.feedrateMin', feedrateMin);
+ this.config.set('shuttle.feedrateMax', feedrateMax);
+ this.config.set('shuttle.hertz', hertz);
+ this.config.set('shuttle.overshoot', overshoot);
+ };
+
+ render() {
+ const { general, shuttleXpress } = this.load();
+
+ return (
+
+
+ {i18n._('Axes Settings')}
+
+
+
+
+ {
+ this.node.general = node;
+ }}
+ show={this.state.activeKey === 'general'}
+ axes={general.axes}
+ wzero={general.wzero}
+ mzero={general.mzero}
+ />
+ {
+ this.node.shuttleXpress = node;
+ }}
+ show={this.state.activeKey === 'shuttleXpress'}
+ feedrateMin={shuttleXpress.feedrateMin}
+ feedrateMax={shuttleXpress.feedrateMax}
+ hertz={shuttleXpress.hertz}
+ overshoot={shuttleXpress.overshoot}
+ />
+
+
+
+
+ {i18n._('Cancel')}
+
+ {
+ const { general } = this.node;
+
+ general.form.validateAll();
+ if (Object.keys(general.form.state.errors).length > 0) {
+ return;
+ }
+
+ this.save();
+
+ // Update parent state
+ this.props.onSave(event);
+ }}
+ >
+ {i18n._('Save Changes')}
+
+
+
+ );
+ }
+}
+
+export default Settings;
diff --git a/src/web/widgets/Axes/ShuttleSettings.jsx b/src/web/widgets/Axes/ShuttleSettings.jsx
deleted file mode 100644
index 605514960..000000000
--- a/src/web/widgets/Axes/ShuttleSettings.jsx
+++ /dev/null
@@ -1,112 +0,0 @@
-import Slider from 'rc-slider';
-import PropTypes from 'prop-types';
-import React, { Component } from 'react';
-import i18n from '../../lib/i18n';
-
-const FEEDRATE_RANGE = [100, 2500];
-const FEEDRATE_STEP = 50;
-const OVERSHOOT_RANGE = [1, 1.5];
-const OVERSHOOT_STEP = 0.01;
-
-class ShuttleSettings extends Component {
- static propTypes = {
- feedrateMin: PropTypes.number,
- feedrateMax: PropTypes.number,
- hertz: PropTypes.number,
- overshoot: PropTypes.number
- };
-
- state = this.getInitialState();
-
- getInitialState() {
- const {
- feedrateMin,
- feedrateMax,
- hertz,
- overshoot
- } = this.props;
-
- return { feedrateMin, feedrateMax, hertz, overshoot };
- }
- componentWillReceiveProps(nextProps) {
- const {
- feedrateMin,
- feedrateMax,
- hertz,
- overshoot
- } = nextProps;
-
- this.setState({ feedrateMin, feedrateMax, hertz, overshoot });
- }
- onFeedrateSliderChange(value) {
- const [min, max] = value;
- this.setState({
- feedrateMin: min,
- feedrateMax: max
- });
- }
- onHertzChange(event) {
- const { value } = event.target;
- const hertz = Number(value);
- this.setState({ hertz });
- }
- onOvershootSliderChange(value) {
- const overshoot = value;
- this.setState({ overshoot });
- }
- render() {
- const { feedrateMin, feedrateMax, hertz, overshoot } = this.state;
-
- return (
-
-
-
{i18n._('Shuttle Settings')}
-
-
-
-
- {i18n._('Feed Rate Range: {{min}} - {{max}} mm/min', { min: feedrateMin, max: feedrateMax })}
-
-
-
-
-
-
-
-
-
- {i18n._('Distance Overshoot: {{overshoot}}x', { overshoot: overshoot })}
-
-
-
-
-
- );
- }
-}
-
-export default ShuttleSettings;
diff --git a/src/web/widgets/Axes/index.jsx b/src/web/widgets/Axes/index.jsx
index 2775e1b37..a93fdcfde 100644
--- a/src/web/widgets/Axes/index.jsx
+++ b/src/web/widgets/Axes/index.jsx
@@ -3,8 +3,8 @@ import includes from 'lodash/includes';
import map from 'lodash/map';
import mapValues from 'lodash/mapValues';
import classNames from 'classnames';
-import React, { Component, PropTypes } from 'react';
-import shallowCompare from 'react-addons-shallow-compare';
+import PropTypes from 'prop-types';
+import React, { PureComponent } from 'react';
import Widget from '../../components/Widget';
import combokeys from '../../lib/combokeys';
import controller from '../../lib/controller';
@@ -13,6 +13,8 @@ import i18n from '../../lib/i18n';
import { in2mm, mm2in } from '../../lib/units';
import WidgetConfig from '../WidgetConfig';
import Axes from './Axes';
+import KeypadOverlay from './KeypadOverlay';
+import Settings from './Settings';
import ShuttleControl from './ShuttleControl';
import {
// Units
@@ -79,7 +81,7 @@ const normalizeToRange = (n, min, max) => {
return n;
};
-class AxesWidget extends Component {
+class AxesWidget extends PureComponent {
static propTypes = {
widgetId: PropTypes.string.isRequired,
onFork: PropTypes.func.isRequired,
@@ -128,33 +130,6 @@ class AxesWidget extends Component {
}
});
},
- loadConfig: () => {
- return {
- axes: this.config.get('axes'),
- feedrateMin: this.config.get('shuttle.feedrateMin'),
- feedrateMax: this.config.get('shuttle.feedrateMax'),
- hertz: this.config.get('shuttle.hertz'),
- overshoot: this.config.get('shuttle.overshoot')
- };
- },
- saveConfig: (data) => {
- const {
- axes,
- feedrateMin,
- feedrateMax,
- hertz,
- overshoot
- } = { ...data };
-
- this.config.replace('axes', axes); // array
- this.config.set('shuttle.feedrateMin', feedrateMin);
- this.config.set('shuttle.feedrateMax', feedrateMax);
- this.config.set('shuttle.hertz', hertz);
- this.config.set('shuttle.overshoot', overshoot);
-
- // Update axes
- this.setState({ axes: axes });
- },
getJogDistance: () => {
const { units } = this.state;
const selectedDistance = this.config.get('jog.selectedDistance');
@@ -466,9 +441,6 @@ class AxesWidget extends Component {
this.removeControllerEvents();
this.removeShuttleControlEvents();
}
- shouldComponentUpdate(nextProps, nextState) {
- return shallowCompare(this, nextProps, nextState);
- }
componentDidUpdate(prevProps, prevState) {
const {
units,
@@ -618,6 +590,7 @@ class AxesWidget extends Component {
const { minimized, isFullscreen } = this.state;
const { units, machinePosition, workPosition } = this.state;
const isForkedWidget = widgetId.match(/\w+:[\w\-]+/);
+ const config = this.config;
const state = {
...this.state,
// Determine if the motion button is clickable
@@ -649,11 +622,22 @@ class AxesWidget extends Component {
}
+
+
+
+
+
{
- const data = actions.loadConfig();
- actions.openModal(MODAL_SETTINGS, data);
+ actions.openModal(MODAL_SETTINGS);
}}
>
@@ -715,7 +699,18 @@ class AxesWidget extends Component {
{ [styles.hidden]: minimized }
)}
>
-
+ {state.modal.name === MODAL_SETTINGS &&
+ {
+ const axes = config.get('axes', DEFAULT_AXES);
+ this.setState({ axes: axes });
+ actions.closeModal();
+ }}
+ onCancel={actions.closeModal}
+ />
+ }
+
);
diff --git a/src/web/widgets/Axes/index.styl b/src/web/widgets/Axes/index.styl
index e68152166..3e88a9c48 100644
--- a/src/web/widgets/Axes/index.styl
+++ b/src/web/widgets/Axes/index.styl
@@ -13,6 +13,7 @@
.row-space {
margin-bottom: 5px;
+ margin-right: -5px;
}
.col-space {
margin-right: 5px;
@@ -111,8 +112,25 @@
}
.action {
width: 1%;
- padding: 0 4px;
+ padding: 0;
text-align: center;
+
+ button.action-dropdown {
+ width: auto;
+ border-radius: 0;
+
+ > * {
+ color: #666;
+ }
+
+ &:hover {
+ background-color: #e6e6e6;
+
+ > * {
+ color: #333;
+ }
+ }
+ }
}
}
@@ -120,65 +138,54 @@
margin: 0;
}
-.jog-pad {
- button[class^="jog-"],
- button[class*=" jog-"] {
+.keypad {
+ button.btn-keypad {
font-size: 16px;
padding: 0;
- min-width: 35px;
width: 100%;
line-height: 30px;
text-align: center;
vertical-align: middle;
-
box-shadow: 1px 1px 2px rgba(0, 0, 0, 0.1);
+
&:active,
&.active {
box-shadow: 0 0 2px rgba(0, 0, 0, 0.1);
transform: translate(1px, 1px);
}
- }
-
- .jog-direction-highlight {
- button[class^="jog-"],
- button[class*=" jog-"] {
- background-color: rgba(240, 240, 240, .8);
- box-shadow: 1px 1px 2px rgba(0, 0, 0, .2);
- border-color: rgba(0, 0, 0, .3);
- &:hover {
- background-color: rgba(0, 0, 0, .2);
- }
-
- &:active,
- &.active {
- box-shadow: 0 0 2px rgba(0, 0, 0, .2);
- transform: translate(1px, 1px);
- }
+ .keypad-text + .keypad-subscript > * {
+ font-size: 60%;
}
- .jog-text {
- font-weight: 500;
+ :global {
+ i.fa,
+ span.fa {
+ color: #333;
+ }
}
}
-}
-.motion-controls {
- :global {
- .btn,
- .btn-group {
- width: 100%;
+ button.btn-keypad.highlight {
+ background-color: rgba(240, 240, 240, .8);
+ background-image: none;
+ box-shadow: 1px 1px 2px rgba(0, 0, 0, .2);
+ border-color: rgba(0, 0, 0, .4);
+
+ &:hover,
+ &.hover {
+ background-color: rgba(0, 0, 0, .1);
}
- }
- button {
- width: 100%;
- line-height: 30px;
- padding: 0 5px;
+ &:active,
+ &.active {
+ box-shadow: 0 0 2px rgba(0, 0, 0, .2);
+ transform: translate(1px, 1px);
+ }
}
}
-.jog-distance-control {
+.jog-distance {
:global {
.input-group {
.input-group-btn:not(:first-child):not(:last-child) {