import classNames from 'classnames'; import {connect} from 'react-redux'; import PropTypes from 'prop-types'; import React from 'react'; 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 {setShapesFilled} from '../../reducers/fill-bitmap-shapes'; import FontDropdown from '../../containers/font-dropdown.jsx'; import LiveInputHOC from '../forms/live-input-hoc.jsx'; import Label from '../forms/label.jsx'; import {defineMessages, injectIntl, intlShape} from 'react-intl'; import Input from '../forms/input.jsx'; import InputGroup from '../input-group/input-group.jsx'; import LabeledIconButton from '../labeled-icon-button/labeled-icon-button.jsx'; import Modes from '../../lib/modes'; import Formats, {isBitmap, isVector} from '../../lib/format'; import {hideLabel} from '../../lib/hide-label'; import styles from './mode-tools.css'; import copyIcon from '!../../tw-recolor/build!./icons/copy.svg'; import pasteIcon from '!../../tw-recolor/build!./icons/paste.svg'; import deleteIcon from '!../../tw-recolor/build!./icons/delete.svg'; import bitBrushIcon from '../bit-brush-mode/brush.svg'; import bitEraserIcon from '../bit-eraser-mode/eraser.svg'; import bitLineIcon from '../bit-line-mode/line.svg'; import brushIcon from '../brush-mode/brush.svg'; 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 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'; import bitOvalOutlinedIcon from '../bit-oval-mode/oval-outlined.svg'; import bitRectOutlinedIcon from '../bit-rect-mode/rectangle-outlined.svg'; import {MAX_STROKE_WIDTH} from '../../reducers/stroke-width'; const LiveInput = LiveInputHOC(Input); const ModeToolsComponent = props => { const messages = defineMessages({ brushSize: { defaultMessage: 'Size', description: 'Label for the brush size input', id: 'paint.modeTools.brushSize' }, eraserSize: { defaultMessage: 'Eraser size', description: 'Label for the eraser size input', id: 'paint.modeTools.eraserSize' }, copy: { defaultMessage: 'Copy', description: 'Label for the copy button', id: 'paint.modeTools.copy' }, paste: { defaultMessage: 'Paste', description: 'Label for the paste button', id: 'paint.modeTools.paste' }, delete: { defaultMessage: 'Delete', description: 'Label for the delete button', id: 'paint.modeTools.delete' }, curved: { defaultMessage: 'Curved', description: 'Label for the button that converts selected points to curves', id: 'paint.modeTools.curved' }, pointed: { defaultMessage: 'Pointed', description: 'Label for the button that converts selected points to sharp points', id: 'paint.modeTools.pointed' }, thickness: { defaultMessage: 'Thickness', description: 'Label for the number input to choose the line thickness', id: 'paint.modeTools.thickness' }, flipHorizontal: { defaultMessage: 'Flip Horizontal', description: 'Label for the button to flip the image horizontally', id: 'paint.modeTools.flipHorizontal' }, flipVertical: { defaultMessage: 'Flip Vertical', description: 'Label for the button to flip the image vertically', id: 'paint.modeTools.flipVertical' }, filled: { defaultMessage: 'Filled', description: 'Label for the button that sets the bitmap rectangle/oval mode to draw outlines', id: 'paint.modeTools.filled' }, outlined: { defaultMessage: 'Outlined', description: 'Label for the button that sets the bitmap rectangle/oval mode to draw filled-in shapes', id: 'paint.modeTools.outlined' } }); switch (props.mode) { case Modes.BRUSH: /* falls through */ case Modes.BIT_BRUSH: /* falls through */ case Modes.BIT_LINE: { const currentIcon = isVector(props.format) ? brushIcon : props.mode === Modes.BIT_LINE ? bitLineIcon : bitBrushIcon; const currentBrushValue = isBitmap(props.format) ? props.bitBrushSize : props.brushValue; const changeFunction = isBitmap(props.format) ? props.onBitBrushSliderChange : props.onBrushSliderChange; const currentMessage = props.mode === Modes.BIT_LINE ? messages.thickness : messages.brushSize; return (
{props.intl.formatMessage(currentMessage)}
); } case Modes.BIT_ERASER: /* falls through */ case Modes.ERASER: { const currentIcon = isVector(props.format) ? eraserIcon : bitEraserIcon; const currentEraserValue = isBitmap(props.format) ? props.bitEraserSize : props.eraserValue; const changeFunction = isBitmap(props.format) ? props.onBitEraserSliderChange : props.onEraserSliderChange; return (
{props.intl.formatMessage(messages.eraserSize)}
); } case Modes.RESHAPE: return (
); case Modes.BIT_SELECT: /* falls through */ case Modes.SELECT: return (
0)} hideLabel={hideLabel(props.intl.locale)} imgSrc={pasteIcon} title={props.intl.formatMessage(messages.paste)} onClick={props.onPasteFromClipboard} />
); case Modes.BIT_TEXT: /* falls through */ case Modes.TEXT: return (
); case Modes.BIT_RECT: /* falls through */ case Modes.BIT_OVAL: { const fillIcon = props.mode === Modes.BIT_RECT ? bitRectIcon : bitOvalIcon; const outlineIcon = props.mode === Modes.BIT_RECT ? bitRectOutlinedIcon : bitOvalOutlinedIcon; return (
{props.fillBitmapShapes ? null : ( ) }
); } default: // Leave empty for now, if mode not supported return (
); } }; ModeToolsComponent.propTypes = { bitBrushSize: PropTypes.number, bitEraserSize: PropTypes.number, brushValue: PropTypes.number, className: PropTypes.string, clipboardItems: PropTypes.arrayOf(PropTypes.array), eraserValue: PropTypes.number, fillBitmapShapes: PropTypes.bool, format: PropTypes.oneOf(Object.keys(Formats)), hasSelectedUncurvedPoints: PropTypes.bool, hasSelectedUnpointedPoints: PropTypes.bool, intl: intlShape.isRequired, mode: PropTypes.string.isRequired, onBitBrushSliderChange: PropTypes.func.isRequired, onBitEraserSliderChange: PropTypes.func.isRequired, onBrushSliderChange: PropTypes.func.isRequired, onCopyToClipboard: PropTypes.func.isRequired, onCurvePoints: PropTypes.func.isRequired, onDelete: PropTypes.func.isRequired, onEraserSliderChange: PropTypes.func, onFillShapes: PropTypes.func.isRequired, onFlipHorizontal: PropTypes.func.isRequired, onFlipVertical: PropTypes.func.isRequired, onManageFonts: PropTypes.func, onOutlineShapes: PropTypes.func.isRequired, onPasteFromClipboard: PropTypes.func.isRequired, onPointPoints: PropTypes.func.isRequired, onUpdateImage: PropTypes.func.isRequired }; const mapStateToProps = state => ({ mode: state.scratchPaint.mode, format: state.scratchPaint.format, fillBitmapShapes: state.scratchPaint.fillBitmapShapes, bitBrushSize: state.scratchPaint.bitBrushSize, bitEraserSize: state.scratchPaint.bitEraserSize, brushValue: state.scratchPaint.brushMode.brushSize, clipboardItems: state.scratchPaint.clipboard.items, eraserValue: state.scratchPaint.eraserMode.brushSize }); const mapDispatchToProps = dispatch => ({ onBrushSliderChange: brushSize => { dispatch(changeBrushSize(brushSize)); }, onBitBrushSliderChange: bitBrushSize => { dispatch(changeBitBrushSize(bitBrushSize)); }, onBitEraserSliderChange: eraserSize => { dispatch(changeBitEraserSize(eraserSize)); }, onEraserSliderChange: eraserSize => { dispatch(changeEraserSize(eraserSize)); }, onFillShapes: () => { dispatch(setShapesFilled(true)); }, onOutlineShapes: () => { dispatch(setShapesFilled(false)); } }); export default connect( mapStateToProps, mapDispatchToProps )(injectIntl(ModeToolsComponent));