diff --git a/src/components/mode-tools/mode-tools.jsx b/src/components/mode-tools/mode-tools.jsx
index 9aa4942696..a3055f1d18 100644
--- a/src/components/mode-tools/mode-tools.jsx
+++ b/src/components/mode-tools/mode-tools.jsx
@@ -7,6 +7,7 @@ import {changeBrushSize} from '../../reducers/brush-mode';
import {changeBrushSize as changeEraserSize} from '../../reducers/eraser-mode';
import {changeBitBrushSize} from '../../reducers/bit-brush-size';
import {changeBitEraserSize} from '../../reducers/bit-eraser-size';
+import {changeRectRadius} from '../../reducers/rect-mode';
import {setShapesFilled} from '../../reducers/fill-bitmap-shapes';
import FontDropdown from '../../containers/font-dropdown.jsx';
@@ -33,6 +34,7 @@ import curvedPointIcon from '!../../tw-recolor/build!./icons/curved-point.svg';
import eraserIcon from '../eraser-mode/eraser.svg';
import flipHorizontalIcon from '!../../tw-recolor/build!./icons/flip-horizontal.svg';
import flipVerticalIcon from '!../../tw-recolor/build!./icons/flip-vertical.svg';
+import roundRectIcon from '../rounded-rect-mode/rounded-rectangle.svg';
import straightPointIcon from '!../../tw-recolor/build!./icons/straight-point.svg';
import bitOvalIcon from '../bit-oval-mode/oval.svg';
import bitRectIcon from '../bit-rect-mode/rectangle.svg';
@@ -54,6 +56,11 @@ const ModeToolsComponent = props => {
description: 'Label for the eraser size input',
id: 'paint.modeTools.eraserSize'
},
+ rectRadius: {
+ defaultMessage: 'Corner radius',
+ description: 'Label for the corner radius input',
+ id: 'paint.modeTools.rectRadius'
+ },
copy: {
defaultMessage: 'Copy',
description: 'Label for the copy button',
@@ -140,6 +147,34 @@ const ModeToolsComponent = props => {
);
}
+ case Modes.RECT:
+ {
+ // to do: use reducers
+ const currentIcon = roundRectIcon;
+ const currentRadiusValue = props.rectRadius;
+ const changeFunction = props.onRectRadiusSliderChange;
+ return (
+
+
+
![{props.intl.formatMessage(messages.rectRadius)}]({currentIcon})
+
+
+
+ );
+ }
case Modes.BIT_ERASER:
/* falls through */
case Modes.ERASER:
@@ -314,6 +349,7 @@ ModeToolsComponent.propTypes = {
className: PropTypes.string,
clipboardItems: PropTypes.arrayOf(PropTypes.array),
eraserValue: PropTypes.number,
+ rectRadius: PropTypes.number,
fillBitmapShapes: PropTypes.bool,
format: PropTypes.oneOf(Object.keys(Formats)),
hasSelectedUncurvedPoints: PropTypes.bool,
@@ -323,6 +359,7 @@ ModeToolsComponent.propTypes = {
onBitBrushSliderChange: PropTypes.func.isRequired,
onBitEraserSliderChange: PropTypes.func.isRequired,
onBrushSliderChange: PropTypes.func.isRequired,
+ onRectRadiusSliderChange: PropTypes.func,
onCopyToClipboard: PropTypes.func.isRequired,
onCurvePoints: PropTypes.func.isRequired,
onDelete: PropTypes.func.isRequired,
@@ -345,7 +382,8 @@ const mapStateToProps = state => ({
bitEraserSize: state.scratchPaint.bitEraserSize,
brushValue: state.scratchPaint.brushMode.brushSize,
clipboardItems: state.scratchPaint.clipboard.items,
- eraserValue: state.scratchPaint.eraserMode.brushSize
+ eraserValue: state.scratchPaint.eraserMode.brushSize,
+ rectRadius: state.scratchPaint.rectMode.rectRadius
});
const mapDispatchToProps = dispatch => ({
onBrushSliderChange: brushSize => {
@@ -360,6 +398,9 @@ const mapDispatchToProps = dispatch => ({
onEraserSliderChange: eraserSize => {
dispatch(changeEraserSize(eraserSize));
},
+ onRectRadiusSliderChange: rectRadius => {
+ dispatch(changeRectRadius(rectRadius));
+ },
onFillShapes: () => {
dispatch(setShapesFilled(true));
},
diff --git a/src/containers/rect-mode.jsx b/src/containers/rect-mode.jsx
index 872316b17e..0357cc5105 100644
--- a/src/containers/rect-mode.jsx
+++ b/src/containers/rect-mode.jsx
@@ -10,6 +10,7 @@ import GradientTypes from '../lib/gradient-types';
import {changeFillColor, clearFillGradient, DEFAULT_COLOR} from '../reducers/fill-style';
import {changeStrokeColor, clearStrokeGradient} from '../reducers/stroke-style';
+import {changeRectRadius} from '../reducers/rect-mode';
import {changeMode} from '../reducers/modes';
import {clearSelectedItems, setSelectedItems} from '../reducers/selected-items';
import {setCursor} from '../reducers/cursor';
@@ -36,6 +37,9 @@ class RectMode extends React.Component {
if (this.tool && nextProps.colorState !== this.props.colorState) {
this.tool.setColorState(nextProps.colorState);
}
+ if (this.tool && nextProps.rectRadius !== this.props.rectRadius) {
+ this.tool.setRectRadius(nextProps.rectRadius);
+ }
if (this.tool && nextProps.selectedItems !== this.props.selectedItems) {
this.tool.onSelectionChanged(nextProps.selectedItems);
}
@@ -65,6 +69,7 @@ class RectMode extends React.Component {
this.props.onUpdateImage
);
this.tool.setColorState(this.props.colorState);
+ this.tool.setRectRadius(this.props.rectRadius);
this.tool.activate();
}
validateColorState () { // TODO move to shared class
@@ -140,7 +145,10 @@ RectMode.propTypes = {
isRectModeActive: PropTypes.bool.isRequired,
onChangeFillColor: PropTypes.func.isRequired,
onChangeStrokeColor: PropTypes.func.isRequired,
+ // eslint-disable-next-line react/no-unused-prop-types
+ onChangeRectRadius: PropTypes.func.isRequired,
onUpdateImage: PropTypes.func.isRequired,
+ rectRadius: PropTypes.number,
selectedItems: PropTypes.arrayOf(PropTypes.instanceOf(paper.Item)),
setCursor: PropTypes.func.isRequired,
setSelectedItems: PropTypes.func.isRequired
@@ -148,6 +156,7 @@ RectMode.propTypes = {
const mapStateToProps = state => ({
colorState: state.scratchPaint.color,
+ rectRadius: state.scratchPaint.rectMode.rectRadius,
isRectModeActive: state.scratchPaint.mode === Modes.RECT,
selectedItems: state.scratchPaint.selectedItems
});
@@ -175,6 +184,9 @@ const mapDispatchToProps = dispatch => ({
},
onChangeStrokeColor: strokeColor => {
dispatch(changeStrokeColor(strokeColor));
+ },
+ onChangeRectRadius: rectRadius => {
+ dispatch(changeRectRadius(rectRadius));
}
});
diff --git a/src/helper/tools/rect-tool.js b/src/helper/tools/rect-tool.js
index 3bd84a0a25..2d90800073 100644
--- a/src/helper/tools/rect-tool.js
+++ b/src/helper/tools/rect-tool.js
@@ -46,6 +46,7 @@ class RectTool extends paper.Tool {
this.colorState = null;
this.isBoundingBoxMode = null;
this.active = false;
+ this.rectRadius = 16;
}
getHitOptions () {
return {
@@ -60,6 +61,9 @@ class RectTool extends paper.Tool {
tolerance: RectTool.TOLERANCE / paper.view.zoom
};
}
+ setRectRadius (rectRadius) {
+ this.rectRadius = rectRadius;
+ }
/**
* Should be called if the selection changes to update the bounds of the bounding box.
* @param {Array} selectedItems Array of selected items.
@@ -100,7 +104,7 @@ class RectTool extends paper.Tool {
rect.size = squareDimensions.size.abs();
}
- this.rect = new paper.Path.Rectangle(rect);
+ this.rect = new paper.Path.Rectangle(rect, this.rectRadius);
if (event.modifiers.alt) {
this.rect.position = event.downPoint;
} else if (event.modifiers.shift) {
diff --git a/src/reducers/rect-mode.js b/src/reducers/rect-mode.js
new file mode 100644
index 0000000000..5b3796e2a5
--- /dev/null
+++ b/src/reducers/rect-mode.js
@@ -0,0 +1,31 @@
+import log from '../log/log';
+
+const CHANGE_RECT_RADIUS = 'scratch-paint/rect-mode/CHANGE_RECT_RADIUS';
+const initialState = {rectRadius: 0};
+
+const reducer = function (state, action) {
+ if (typeof state === 'undefined') state = initialState;
+ switch (action.type) {
+ case CHANGE_RECT_RADIUS:
+ if (isNaN(action.rectRadius)) {
+ log.warn(`Invalid corner radius: ${action.rectRadius}`);
+ return state;
+ }
+ return {rectRadius: Math.max(1, action.rectRadius)};
+ default:
+ return state;
+ }
+};
+
+// Action creators ==================================
+const changeRectRadius = function (rectRadius) {
+ return {
+ type: CHANGE_RECT_RADIUS,
+ rectRadius: rectRadius
+ };
+};
+
+export {
+ reducer as default,
+ changeRectRadius
+};
diff --git a/src/reducers/scratch-paint-reducer.js b/src/reducers/scratch-paint-reducer.js
index 3dc9be3308..cff5d33498 100644
--- a/src/reducers/scratch-paint-reducer.js
+++ b/src/reducers/scratch-paint-reducer.js
@@ -15,6 +15,7 @@ import formatReducer from './format';
import hoverReducer from './hover';
import layoutReducer from './layout';
import modalsReducer from './modals';
+import rectModeReducer from './rect-mode';
import selectedItemReducer from './selected-items';
import textEditTargetReducer from './text-edit-target';
import themeReducer from './theme';
@@ -39,6 +40,7 @@ export default combineReducers({
hoveredItemId: hoverReducer,
layout: layoutReducer,
modals: modalsReducer,
+ rectMode: rectModeReducer,
selectedItems: selectedItemReducer,
textEditTarget: textEditTargetReducer,
theme: themeReducer,