From ea36e10577eef4abb514d2b97b50630936315897 Mon Sep 17 00:00:00 2001 From: Matthew Taylor Date: Wed, 25 Oct 2017 13:37:41 -0400 Subject: [PATCH 1/6] Add basic eraser and brush size picker this implements the first version of #36 and #37, in which the brush size picker is a numeric input field rather than a slider. --- src/components/button-group/button-group.css | 4 +- src/components/forms/buffered-input-hoc.jsx | 5 + src/components/forms/input.css | 6 +- src/components/forms/label.css | 2 +- src/components/input-group/input-group.css | 2 +- .../labeled-icon-button.css} | 8 +- .../labeled-icon-button.jsx} | 16 +- src/components/mode-tools/curved-point.svg | 17 ++ src/components/mode-tools/flip-horizontal.svg | 20 +++ src/components/mode-tools/flip-vertical.svg | 20 +++ src/components/mode-tools/mode-tools.css | 13 ++ src/components/mode-tools/mode-tools.jsx | 170 ++++++++++++++++++ src/components/mode-tools/straight-point.svg | 14 ++ src/components/paint-editor/paint-editor.css | 20 +-- src/components/paint-editor/paint-editor.jsx | 19 +- .../tool-select-base/tool-select-base.css | 2 +- src/css/units.css | 5 + 17 files changed, 308 insertions(+), 35 deletions(-) rename src/components/{paint-editor/edit-field-button/edit-field-button.css => labeled-icon-button/labeled-icon-button.css} (73%) rename src/components/{paint-editor/edit-field-button/edit-field-button.jsx => labeled-icon-button/labeled-icon-button.jsx} (60%) create mode 100755 src/components/mode-tools/curved-point.svg create mode 100755 src/components/mode-tools/flip-horizontal.svg create mode 100755 src/components/mode-tools/flip-vertical.svg create mode 100644 src/components/mode-tools/mode-tools.css create mode 100644 src/components/mode-tools/mode-tools.jsx create mode 100755 src/components/mode-tools/straight-point.svg diff --git a/src/components/button-group/button-group.css b/src/components/button-group/button-group.css index 37f8a7c4..b8505a8d 100644 --- a/src/components/button-group/button-group.css +++ b/src/components/button-group/button-group.css @@ -1,5 +1,5 @@ -$border-radius: .25rem; +@import "../../css/units"; .button-group { - padding: 0 1rem; + padding: 0 $grid-unit; } diff --git a/src/components/forms/buffered-input-hoc.jsx b/src/components/forms/buffered-input-hoc.jsx index b3561136..6dda865b 100644 --- a/src/components/forms/buffered-input-hoc.jsx +++ b/src/components/forms/buffered-input-hoc.jsx @@ -39,6 +39,11 @@ export default function (Input) { this.setState({value: null}); } handleChange (e) { + const isNumeric = typeof this.props.value === 'number'; + const validatesNumeric = isNumeric ? !isNaN(this.state.value) : true; + if (this.state.value !== null && validatesNumeric) { + this.props.onSubmit(isNumeric ? Number(this.state.value) : this.state.value); + } this.setState({value: e.target.value}); } render () { diff --git a/src/components/forms/input.css b/src/components/forms/input.css index 36855e44..6fba0c59 100644 --- a/src/components/forms/input.css +++ b/src/components/forms/input.css @@ -10,7 +10,7 @@ See https://github.com/LLK/scratch-paint/issues/13 */ padding: 0 0.75rem; font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; - font-size: 0.625rem; + font-size: 0.75rem; font-weight: bold; color: $text-primary; @@ -36,8 +36,8 @@ See https://github.com/LLK/scratch-paint/issues/13 */ } .input-form:focus { - border-color: #4c97ff; - box-shadow: inset 0 0 0 -2px rgba(0, 0, 0, 0.1); + border-color: $motion-primary; + box-shadow: 0 0 0 $grid-unit $motion-transparent; } .input-small { diff --git a/src/components/forms/label.css b/src/components/forms/label.css index 7871cdd3..73642f6e 100644 --- a/src/components/forms/label.css +++ b/src/components/forms/label.css @@ -13,7 +13,7 @@ See https://github.com/LLK/scratch-paint/issues/13 */ .input-label, .input-label-secondary { font-size: 0.625rem; - margin-right: calc($space / 2); + margin-right: calc(2 * $grid-unit); user-select: none; cursor: default; } diff --git a/src/components/input-group/input-group.css b/src/components/input-group/input-group.css index 26e8a5ec..80fdba7a 100644 --- a/src/components/input-group/input-group.css +++ b/src/components/input-group/input-group.css @@ -1,5 +1,5 @@ @import '../../css/units.css'; .input-group + .input-group { - margin-left: calc(2 * $space); + margin-left: calc(3 * $grid-unit); } diff --git a/src/components/paint-editor/edit-field-button/edit-field-button.css b/src/components/labeled-icon-button/labeled-icon-button.css similarity index 73% rename from src/components/paint-editor/edit-field-button/edit-field-button.css rename to src/components/labeled-icon-button/labeled-icon-button.css index 7f4a6ac5..8881eeb7 100644 --- a/src/components/paint-editor/edit-field-button/edit-field-button.css +++ b/src/components/labeled-icon-button/labeled-icon-button.css @@ -1,5 +1,5 @@ -@import "../../../css/colors.css"; -@import "../../../css/units.css"; +@import "../../css/colors.css"; +@import "../../css/units.css"; $border-radius: 0.25rem; @@ -16,7 +16,7 @@ $border-radius: 0.25rem; } .mod-edit-field:active { - background-color: $ui-background-blue; + background-color: $motion-transparent; } .edit-field-icon { @@ -28,4 +28,6 @@ $border-radius: 0.25rem; .edit-field-title { display: block; + margin-top: .125rem; + font-size: .625rem; } diff --git a/src/components/paint-editor/edit-field-button/edit-field-button.jsx b/src/components/labeled-icon-button/labeled-icon-button.jsx similarity index 60% rename from src/components/paint-editor/edit-field-button/edit-field-button.jsx rename to src/components/labeled-icon-button/labeled-icon-button.jsx index ed1e7d0a..792a14aa 100644 --- a/src/components/paint-editor/edit-field-button/edit-field-button.jsx +++ b/src/components/labeled-icon-button/labeled-icon-button.jsx @@ -1,14 +1,19 @@ +/* @todo This file should be pulled out into a shared library with scratch-gui, +consolidating this component with icon-button.jsx in gui. +See #13 */ + import classNames from 'classnames'; import React from 'react'; import PropTypes from 'prop-types'; -import Button from '../../button/button.jsx'; +import Button from '../button/button.jsx'; -import styles from './edit-field-button.css'; +import styles from './labeled-icon-button.css'; -const EditFieldButton = props => ( +const LabeledIconButton = props => ( ); -EditFieldButton.propTypes = { +LabeledIconButton.propTypes = { className: PropTypes.string, + disabled: PropTypes.string, imgAlt: PropTypes.string.isRequired, imgSrc: PropTypes.string.isRequired, onClick: PropTypes.func.isRequired, title: PropTypes.string.isRequired }; -export default EditFieldButton; +export default LabeledIconButton; diff --git a/src/components/mode-tools/curved-point.svg b/src/components/mode-tools/curved-point.svg new file mode 100755 index 00000000..6976d36c --- /dev/null +++ b/src/components/mode-tools/curved-point.svg @@ -0,0 +1,17 @@ + + + + curved-point + Created with Sketch. + + + + + + + + + + + + \ No newline at end of file diff --git a/src/components/mode-tools/flip-horizontal.svg b/src/components/mode-tools/flip-horizontal.svg new file mode 100755 index 00000000..972b68b3 --- /dev/null +++ b/src/components/mode-tools/flip-horizontal.svg @@ -0,0 +1,20 @@ + + + + flip-horizontal + Created with Sketch. + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/components/mode-tools/flip-vertical.svg b/src/components/mode-tools/flip-vertical.svg new file mode 100755 index 00000000..dbd3ea69 --- /dev/null +++ b/src/components/mode-tools/flip-vertical.svg @@ -0,0 +1,20 @@ + + + + flip-vertical + Created with Sketch. + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/components/mode-tools/mode-tools.css b/src/components/mode-tools/mode-tools.css new file mode 100644 index 00000000..7e319b00 --- /dev/null +++ b/src/components/mode-tools/mode-tools.css @@ -0,0 +1,13 @@ +@import "../../css/units.css"; + +.mode-tools { + display: flex; + min-height: 3rem; + align-items: center; +} + +.mode-tools-icon { + margin-right: calc(2 * $grid-unit); + width: 2rem; + height: 2rem; +} diff --git a/src/components/mode-tools/mode-tools.jsx b/src/components/mode-tools/mode-tools.jsx new file mode 100644 index 00000000..3b8d4990 --- /dev/null +++ b/src/components/mode-tools/mode-tools.jsx @@ -0,0 +1,170 @@ +import classNames from 'classnames'; +import {connect} from 'react-redux'; +import Popover from 'react-popover'; +import PropTypes from 'prop-types'; +import React from 'react'; + +import {changeBrushSize} from '../../reducers/brush-mode'; +import {changeBrushSize as changeEraserSize} from '../../reducers/eraser-mode'; + +import BufferedInputHOC from '../forms/buffered-input-hoc.jsx'; +import {injectIntl, intlShape} from 'react-intl'; +import Input from '../forms/input.jsx'; +import LabeledIconButton from '../labeled-icon-button/labeled-icon-button.jsx'; +import Modes from '../../modes/modes'; +import Slider from '../forms/slider.jsx'; +import styles from './mode-tools.css'; + +import brushIcon from '../brush-mode/brush.svg'; +import curvedPointIcon from './curved-point.svg'; +import eraserIcon from '../eraser-mode/eraser.svg'; +import flipHorizontalIcon from './flip-horizontal.svg'; +import flipVerticalIcon from './flip-vertical.svg'; +import straightPointIcon from './straight-point.svg'; + +import {MAX_STROKE_WIDTH} from '../../reducers/stroke-width'; + +const BufferedInput = BufferedInputHOC(Input); +const ModeToolsComponent = props => { + const brushMessage = props.intl.formatMessage({ + defaultMessage: 'Brush', + description: 'Label for the brush tool', + id: 'paint.brushMode.brush' + }); + const eraserMessage = props.intl.formatMessage({ + defaultMessage: 'Eraser', + description: 'Label for the eraser tool', + id: 'paint.eraserMode.eraser' + }); + + switch (props.mode) { + case Modes.BRUSH: + return ( +
+
+ {brushMessage} +
+ + + } + /> +
+ ); + case Modes.ERASER: + return ( +
+
+ {eraserMessage} +
+ + + } + /> +
+ ); + case Modes.RESHAPE: + return ( +
+ + +
+ ); + case Modes.SELECT: + return ( +
+ + +
+ ); + default: + // Leave empty for now, if mode not supported + return ( +
+ ); + } +}; + +ModeToolsComponent.propTypes = { + brushValue: PropTypes.number, + className: PropTypes.string, + eraserValue: PropTypes.number, + intl: intlShape.isRequired, + mode: PropTypes.string.isRequired, + onBrushSliderChange: PropTypes.func, + onEraserSliderChange: PropTypes.func +}; + +const mapStateToProps = state => ({ + mode: state.scratchPaint.mode, + brushValue: state.scratchPaint.brushMode.brushSize, + eraserValue: state.scratchPaint.eraserMode.brushSize +}); +const mapDispatchToProps = dispatch => ({ + onBrushSliderChange: brushSize => { + dispatch(changeBrushSize(brushSize)); + }, + onEraserSliderChange: eraserSize => { + dispatch(changeEraserSize(eraserSize)); + } +}); + +export default connect( + mapStateToProps, + mapDispatchToProps +)(injectIntl(ModeToolsComponent)); diff --git a/src/components/mode-tools/straight-point.svg b/src/components/mode-tools/straight-point.svg new file mode 100755 index 00000000..ff4d280e --- /dev/null +++ b/src/components/mode-tools/straight-point.svg @@ -0,0 +1,14 @@ + + + + straight-point + Created with Sketch. + + + + + + + + + \ No newline at end of file diff --git a/src/components/paint-editor/paint-editor.css b/src/components/paint-editor/paint-editor.css index c5d3f76e..e6342bd3 100644 --- a/src/components/paint-editor/paint-editor.css +++ b/src/components/paint-editor/paint-editor.css @@ -4,7 +4,7 @@ .editor-container { display: flex; flex-direction: column; - padding: calc(2 * $space); + padding: calc(4 * $grid-unit); } .row { @@ -15,22 +15,22 @@ .editor-container-top { border-bottom: 1px dashed $ui-pane-border; - padding-bottom: 1rem; + padding-bottom: calc(2 * $grid-unit); } .top-align-row { display: flex; - padding-top:20px; + padding-top: calc(5 * $grid-unit); flex-direction: row; } .row + .row { - margin-top: calc(2 * $space); + margin-top: calc(2 * $grid-unit); } .mod-dashed-border { border-right: 1px dashed $ui-pane-border; - padding-right: calc(2 * $space); + padding-right: calc(3 * $grid-unit); } $border-radius: 0.25rem; @@ -40,7 +40,7 @@ $border-radius: 0.25rem; border: 1px solid $ui-pane-border; border-radius: 0; border-left: none; - padding: 0.5rem; + padding: calc(2 * $grid-unit); } .button-group-button:active { @@ -59,13 +59,13 @@ $border-radius: 0.25rem; } .button-group-button-icon { - width: 1.5rem; - height: 1.5rem; + width: 1.25rem; + height: 1.25rem; vertical-align: middle; } .mod-mode-tools { - margin-left: calc(2 * $space); + margin-left: calc(3 * $grid-unit); } .canvas-container { @@ -79,7 +79,7 @@ $border-radius: 0.25rem; .mode-selector { display: flex; - margin-right: .5rem; + margin-right: calc(2 * $grid-unit); max-width: 5.5rem; flex-direction: row; flex-wrap: wrap; diff --git a/src/components/paint-editor/paint-editor.jsx b/src/components/paint-editor/paint-editor.jsx index 11e089b7..1f69cc73 100644 --- a/src/components/paint-editor/paint-editor.jsx +++ b/src/components/paint-editor/paint-editor.jsx @@ -8,10 +8,11 @@ import PaperCanvas from '../../containers/paper-canvas.jsx'; import Button from '../button/button.jsx'; import ButtonGroup from '../button-group/button-group.jsx'; import BrushMode from '../../containers/brush-mode.jsx'; -import EditFieldButton from './edit-field-button/edit-field-button.jsx'; import EraserMode from '../../containers/eraser-mode.jsx'; import InputGroup from '../input-group/input-group.jsx'; +import LabeledIconButton from '../labeled-icon-button/labeled-icon-button.jsx'; import LineMode from '../../containers/line-mode.jsx'; +import ModeToolsComponent from '../mode-tools/mode-tools.jsx'; import OvalMode from '../../containers/oval-mode.jsx'; import PenMode from '../../containers/pen-mode.jsx'; import RectMode from '../../containers/rect-mode.jsx'; @@ -103,13 +104,13 @@ class PaintEditorComponent extends React.Component { {/* Group/Ungroup */} - - - - - - -
- Mode tools + diff --git a/src/components/tool-select-base/tool-select-base.css b/src/components/tool-select-base/tool-select-base.css index 43f92286..fdfb3aa5 100644 --- a/src/components/tool-select-base/tool-select-base.css +++ b/src/components/tool-select-base/tool-select-base.css @@ -14,7 +14,7 @@ $border-radius: .25rem; } .mod-tool-select.is-selected { - background-color: $ui-background-blue; + background-color: $motion-transparent; } .mod-tool-select:focus { diff --git a/src/css/units.css b/src/css/units.css index acb466b1..c9e15169 100644 --- a/src/css/units.css +++ b/src/css/units.css @@ -2,7 +2,12 @@ @todo This file is copied from GUI and should be pulled out into a shared library. See https://github.com/LLK/scratch-paint/issues/13 */ +/* ACTUALLY, THIS IS EDITED ;) +THIS WAS CHANGED ON 10/25/2017 BY @mewtaylor TO ADD A VARIABLE FOR THE SMALLEST +GRID UNITS.*/ + $space: 0.5rem; +$grid-unit: .25rem; $sprites-per-row: 5; From 90c485ba233c3dd8d3d994d6cba031b1384ebd1d Mon Sep 17 00:00:00 2001 From: Matthew Taylor Date: Wed, 25 Oct 2017 13:51:57 -0400 Subject: [PATCH 2/6] remove half-baked slider stuff whoops! --- src/components/mode-tools/mode-tools.jsx | 16 ---------------- 1 file changed, 16 deletions(-) diff --git a/src/components/mode-tools/mode-tools.jsx b/src/components/mode-tools/mode-tools.jsx index 3b8d4990..33294bc2 100644 --- a/src/components/mode-tools/mode-tools.jsx +++ b/src/components/mode-tools/mode-tools.jsx @@ -56,14 +56,6 @@ const ModeToolsComponent = props => { value={props.brushValue} onSubmit={props.onBrushSliderChange} /> - - } - /> ); case Modes.ERASER: @@ -84,14 +76,6 @@ const ModeToolsComponent = props => { value={props.eraserValue} onSubmit={props.onEraserSliderChange} /> - - } - /> ); case Modes.RESHAPE: From 3574918f23d7be34eb4bfacfd3ddd1ceaa87215c Mon Sep 17 00:00:00 2001 From: Matthew Taylor Date: Wed, 25 Oct 2017 14:15:02 -0400 Subject: [PATCH 3/6] Add comment, and adjust handleChange() make `e.target.value` the submitted thing, rather than `this.props.value` --- src/components/forms/buffered-input-hoc.jsx | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/components/forms/buffered-input-hoc.jsx b/src/components/forms/buffered-input-hoc.jsx index 6dda865b..e7bc25a3 100644 --- a/src/components/forms/buffered-input-hoc.jsx +++ b/src/components/forms/buffered-input-hoc.jsx @@ -2,6 +2,10 @@ @todo This file is copied from GUI and should be pulled out into a shared library. See https://github.com/LLK/scratch-paint/issues/13 */ +/* ACTUALLY, THIS HAS BEEN EDITED ;) +handleChange() was adjusted here to actually send a change to `onSubmit()` so that +brush/eraser sizes change immediately on a numeric input*/ + import bindAll from 'lodash.bindall'; import PropTypes from 'prop-types'; import React from 'react'; @@ -40,9 +44,9 @@ export default function (Input) { } handleChange (e) { const isNumeric = typeof this.props.value === 'number'; - const validatesNumeric = isNumeric ? !isNaN(this.state.value) : true; - if (this.state.value !== null && validatesNumeric) { - this.props.onSubmit(isNumeric ? Number(this.state.value) : this.state.value); + const validatesNumeric = isNumeric ? !isNaN(e.target.value) : true; + if (e.target.value !== null && validatesNumeric) { + this.props.onSubmit(isNumeric ? Number(e.target.value) : e.target.value); } this.setState({value: e.target.value}); } From e2fd966ae93095d31161e41a39c69bc51a846cb8 Mon Sep 17 00:00:00 2001 From: Matthew Taylor Date: Wed, 25 Oct 2017 14:22:36 -0400 Subject: [PATCH 4/6] Increase max size to 1 --- src/components/mode-tools/mode-tools.jsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/components/mode-tools/mode-tools.jsx b/src/components/mode-tools/mode-tools.jsx index 33294bc2..0acb0978 100644 --- a/src/components/mode-tools/mode-tools.jsx +++ b/src/components/mode-tools/mode-tools.jsx @@ -51,7 +51,7 @@ const ModeToolsComponent = props => { { Date: Wed, 25 Oct 2017 14:36:08 -0400 Subject: [PATCH 5/6] remove unused reference --- src/components/mode-tools/mode-tools.jsx | 1 - 1 file changed, 1 deletion(-) diff --git a/src/components/mode-tools/mode-tools.jsx b/src/components/mode-tools/mode-tools.jsx index 0acb0978..0bc5c9ff 100644 --- a/src/components/mode-tools/mode-tools.jsx +++ b/src/components/mode-tools/mode-tools.jsx @@ -12,7 +12,6 @@ import {injectIntl, intlShape} from 'react-intl'; import Input from '../forms/input.jsx'; import LabeledIconButton from '../labeled-icon-button/labeled-icon-button.jsx'; import Modes from '../../modes/modes'; -import Slider from '../forms/slider.jsx'; import styles from './mode-tools.css'; import brushIcon from '../brush-mode/brush.svg'; From c1862284ff244e250e9c8e298f5bf3e5fe3ece0d Mon Sep 17 00:00:00 2001 From: Matthew Taylor Date: Wed, 25 Oct 2017 15:23:30 -0400 Subject: [PATCH 6/6] Remove unused reference --- src/components/mode-tools/mode-tools.jsx | 1 - 1 file changed, 1 deletion(-) diff --git a/src/components/mode-tools/mode-tools.jsx b/src/components/mode-tools/mode-tools.jsx index 0bc5c9ff..afe72006 100644 --- a/src/components/mode-tools/mode-tools.jsx +++ b/src/components/mode-tools/mode-tools.jsx @@ -1,6 +1,5 @@ import classNames from 'classnames'; import {connect} from 'react-redux'; -import Popover from 'react-popover'; import PropTypes from 'prop-types'; import React from 'react';