Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Rounded rectangles #3

Open
wants to merge 8 commits into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
43 changes: 42 additions & 1 deletion src/components/mode-tools/mode-tools.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -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';
Expand All @@ -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';
Expand All @@ -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',
Expand Down Expand Up @@ -140,6 +147,34 @@ const ModeToolsComponent = props => {
</div>
);
}
case Modes.RECT:
{
// to do: use reducers
const currentIcon = roundRectIcon;
const currentRadiusValue = props.rectRadius;
const changeFunction = props.onRectRadiusSliderChange;
return (
<div className={classNames(props.className, styles.modeTools)}>
<div>
<img
alt={props.intl.formatMessage(messages.rectRadius)}
className={styles.modeToolsIcon}
draggable={false}
src={currentIcon}
/>
</div>
<LiveInput
range
small
max={MAX_STROKE_WIDTH}
min="1"
type="number"
value={currentRadiusValue}
onSubmit={changeFunction}
/>
</div>
);
}
case Modes.BIT_ERASER:
/* falls through */
case Modes.ERASER:
Expand Down Expand Up @@ -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,
Expand All @@ -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,
Expand All @@ -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 => {
Expand All @@ -360,6 +398,9 @@ const mapDispatchToProps = dispatch => ({
onEraserSliderChange: eraserSize => {
dispatch(changeEraserSize(eraserSize));
},
onRectRadiusSliderChange: rectRadius => {
dispatch(changeRectRadius(rectRadius));
},
onFillShapes: () => {
dispatch(setShapesFilled(true));
},
Expand Down
12 changes: 12 additions & 0 deletions src/containers/rect-mode.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -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';
Expand All @@ -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);
}
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -140,14 +145,18 @@ 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
};

const mapStateToProps = state => ({
colorState: state.scratchPaint.color,
rectRadius: state.scratchPaint.rectMode.rectRadius,
isRectModeActive: state.scratchPaint.mode === Modes.RECT,
selectedItems: state.scratchPaint.selectedItems
});
Expand Down Expand Up @@ -175,6 +184,9 @@ const mapDispatchToProps = dispatch => ({
},
onChangeStrokeColor: strokeColor => {
dispatch(changeStrokeColor(strokeColor));
},
onChangeRectRadius: rectRadius => {
dispatch(changeRectRadius(rectRadius));
}
});

Expand Down
6 changes: 5 additions & 1 deletion src/helper/tools/rect-tool.js
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ class RectTool extends paper.Tool {
this.colorState = null;
this.isBoundingBoxMode = null;
this.active = false;
this.rectRadius = 16;
}
getHitOptions () {
return {
Expand All @@ -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<paper.Item>} selectedItems Array of selected items.
Expand Down Expand Up @@ -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) {
Expand Down
31 changes: 31 additions & 0 deletions src/reducers/rect-mode.js
Original file line number Diff line number Diff line change
@@ -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
};
2 changes: 2 additions & 0 deletions src/reducers/scratch-paint-reducer.js
Original file line number Diff line number Diff line change
Expand Up @@ -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';
Expand All @@ -39,6 +40,7 @@ export default combineReducers({
hoveredItemId: hoverReducer,
layout: layoutReducer,
modals: modalsReducer,
rectMode: rectModeReducer,
selectedItems: selectedItemReducer,
textEditTarget: textEditTargetReducer,
theme: themeReducer,
Expand Down
Loading