mirror of
https://github.com/scratchfoundation/scratch-paint.git
synced 2024-12-23 05:52:42 -05:00
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.
This commit is contained in:
parent
706a9c101d
commit
ea36e10577
17 changed files with 308 additions and 35 deletions
|
@ -1,5 +1,5 @@
|
||||||
$border-radius: .25rem;
|
@import "../../css/units";
|
||||||
|
|
||||||
.button-group {
|
.button-group {
|
||||||
padding: 0 1rem;
|
padding: 0 $grid-unit;
|
||||||
}
|
}
|
||||||
|
|
|
@ -39,6 +39,11 @@ export default function (Input) {
|
||||||
this.setState({value: null});
|
this.setState({value: null});
|
||||||
}
|
}
|
||||||
handleChange (e) {
|
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});
|
this.setState({value: e.target.value});
|
||||||
}
|
}
|
||||||
render () {
|
render () {
|
||||||
|
|
|
@ -10,7 +10,7 @@ See https://github.com/LLK/scratch-paint/issues/13 */
|
||||||
padding: 0 0.75rem;
|
padding: 0 0.75rem;
|
||||||
|
|
||||||
font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
|
font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
|
||||||
font-size: 0.625rem;
|
font-size: 0.75rem;
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
color: $text-primary;
|
color: $text-primary;
|
||||||
|
|
||||||
|
@ -36,8 +36,8 @@ See https://github.com/LLK/scratch-paint/issues/13 */
|
||||||
}
|
}
|
||||||
|
|
||||||
.input-form:focus {
|
.input-form:focus {
|
||||||
border-color: #4c97ff;
|
border-color: $motion-primary;
|
||||||
box-shadow: inset 0 0 0 -2px rgba(0, 0, 0, 0.1);
|
box-shadow: 0 0 0 $grid-unit $motion-transparent;
|
||||||
}
|
}
|
||||||
|
|
||||||
.input-small {
|
.input-small {
|
||||||
|
|
|
@ -13,7 +13,7 @@ See https://github.com/LLK/scratch-paint/issues/13 */
|
||||||
|
|
||||||
.input-label, .input-label-secondary {
|
.input-label, .input-label-secondary {
|
||||||
font-size: 0.625rem;
|
font-size: 0.625rem;
|
||||||
margin-right: calc($space / 2);
|
margin-right: calc(2 * $grid-unit);
|
||||||
user-select: none;
|
user-select: none;
|
||||||
cursor: default;
|
cursor: default;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
@import '../../css/units.css';
|
@import '../../css/units.css';
|
||||||
|
|
||||||
.input-group + .input-group {
|
.input-group + .input-group {
|
||||||
margin-left: calc(2 * $space);
|
margin-left: calc(3 * $grid-unit);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
@import "../../../css/colors.css";
|
@import "../../css/colors.css";
|
||||||
@import "../../../css/units.css";
|
@import "../../css/units.css";
|
||||||
|
|
||||||
$border-radius: 0.25rem;
|
$border-radius: 0.25rem;
|
||||||
|
|
||||||
|
@ -16,7 +16,7 @@ $border-radius: 0.25rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
.mod-edit-field:active {
|
.mod-edit-field:active {
|
||||||
background-color: $ui-background-blue;
|
background-color: $motion-transparent;
|
||||||
}
|
}
|
||||||
|
|
||||||
.edit-field-icon {
|
.edit-field-icon {
|
||||||
|
@ -28,4 +28,6 @@ $border-radius: 0.25rem;
|
||||||
|
|
||||||
.edit-field-title {
|
.edit-field-title {
|
||||||
display: block;
|
display: block;
|
||||||
|
margin-top: .125rem;
|
||||||
|
font-size: .625rem;
|
||||||
}
|
}
|
|
@ -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 classNames from 'classnames';
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import PropTypes from 'prop-types';
|
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 => (
|
||||||
<Button
|
<Button
|
||||||
className={classNames(props.className, styles.modEditField)}
|
className={classNames(props.className, styles.modEditField)}
|
||||||
|
disabled={props.disabled}
|
||||||
onClick={props.onClick}
|
onClick={props.onClick}
|
||||||
>
|
>
|
||||||
<img
|
<img
|
||||||
|
@ -20,12 +25,13 @@ const EditFieldButton = props => (
|
||||||
</Button>
|
</Button>
|
||||||
);
|
);
|
||||||
|
|
||||||
EditFieldButton.propTypes = {
|
LabeledIconButton.propTypes = {
|
||||||
className: PropTypes.string,
|
className: PropTypes.string,
|
||||||
|
disabled: PropTypes.string,
|
||||||
imgAlt: PropTypes.string.isRequired,
|
imgAlt: PropTypes.string.isRequired,
|
||||||
imgSrc: PropTypes.string.isRequired,
|
imgSrc: PropTypes.string.isRequired,
|
||||||
onClick: PropTypes.func.isRequired,
|
onClick: PropTypes.func.isRequired,
|
||||||
title: PropTypes.string.isRequired
|
title: PropTypes.string.isRequired
|
||||||
};
|
};
|
||||||
|
|
||||||
export default EditFieldButton;
|
export default LabeledIconButton;
|
17
src/components/mode-tools/curved-point.svg
Executable file
17
src/components/mode-tools/curved-point.svg
Executable file
|
@ -0,0 +1,17 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<svg width="20px" height="20px" viewBox="0 0 20 20" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||||
|
<!-- Generator: Sketch 43.2 (39069) - http://www.bohemiancoding.com/sketch -->
|
||||||
|
<title>curved-point</title>
|
||||||
|
<desc>Created with Sketch.</desc>
|
||||||
|
<defs></defs>
|
||||||
|
<g id="Page-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
|
||||||
|
<g id="curved-point">
|
||||||
|
<path d="M2,15 C2,10.5818452 5.58151214,7 10.000744,7 C14.4184879,7 18,10.5818452 18,15" id="Stroke-3" stroke="#4C97FF" stroke-width="0.75" fill-opacity="0.25" fill="#4C97FF" stroke-linecap="round" stroke-linejoin="round"></path>
|
||||||
|
<path d="M3,7 L17,7" id="Stroke-7" stroke="#4C97FF" stroke-width="0.75" stroke-linecap="round" stroke-linejoin="round"></path>
|
||||||
|
<circle id="Oval-4" fill-opacity="0.25" fill="#4C97FF" cx="10" cy="7" r="3"></circle>
|
||||||
|
<circle id="Oval-4" fill="#4C97FF" cx="10" cy="7" r="2"></circle>
|
||||||
|
<circle id="Oval-5" fill="#4C97FF" cx="3" cy="7" r="1"></circle>
|
||||||
|
<circle id="Oval-5-Copy" fill="#4C97FF" cx="17" cy="7" r="1"></circle>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 1.2 KiB |
20
src/components/mode-tools/flip-horizontal.svg
Executable file
20
src/components/mode-tools/flip-horizontal.svg
Executable file
|
@ -0,0 +1,20 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<svg width="20px" height="20px" viewBox="0 0 20 20" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||||
|
<!-- Generator: Sketch 43.2 (39069) - http://www.bohemiancoding.com/sketch -->
|
||||||
|
<title>flip-horizontal</title>
|
||||||
|
<desc>Created with Sketch.</desc>
|
||||||
|
<defs></defs>
|
||||||
|
<g id="Page-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
|
||||||
|
<g id="flip-horizontal">
|
||||||
|
<g transform="translate(2.000000, 3.000000)">
|
||||||
|
<circle id="Oval" fill="#575E75" opacity="0.5" cx="8" cy="0.75" r="1"></circle>
|
||||||
|
<circle id="Oval" fill="#575E75" opacity="0.5" cx="8" cy="13.25" r="1"></circle>
|
||||||
|
<circle id="Oval-Copy" fill="#575E75" opacity="0.5" cx="8" cy="3.875" r="1"></circle>
|
||||||
|
<circle id="Oval-Copy-2" fill="#575E75" opacity="0.5" cx="8" cy="7" r="1"></circle>
|
||||||
|
<circle id="Oval-Copy-3" fill="#575E75" opacity="0.5" cx="8" cy="10.125" r="1"></circle>
|
||||||
|
<path d="M16,3.08425423 L16,10.9157458 C16,11.4342626 15.2574491,11.6956996 14.8235798,11.3282353 L10.2019293,7.41103711 C9.93269025,7.18445835 9.93269025,6.81408922 10.2019293,6.58751046 L14.8235798,2.67176469 C15.2574491,2.30430042 16,2.56573745 16,3.08425423" id="Fill-11" fill="#4C97FF" opacity="0.5"></path>
|
||||||
|
<path d="M0,10.9157458 L0,3.08425423 C0,2.56573745 0.742550911,2.30430042 1.17470525,2.67176469 L5.79807074,6.58896289 C6.06730975,6.81554165 6.06730975,7.18591078 5.79807074,7.41248954 L1.17470525,11.3282353 C0.742550911,11.6956996 0,11.4342626 0,10.9157458" id="Fill-14" fill="#4C97FF"></path>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 1.7 KiB |
20
src/components/mode-tools/flip-vertical.svg
Executable file
20
src/components/mode-tools/flip-vertical.svg
Executable file
|
@ -0,0 +1,20 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<svg width="20px" height="20px" viewBox="0 0 20 20" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||||
|
<!-- Generator: Sketch 43.2 (39069) - http://www.bohemiancoding.com/sketch -->
|
||||||
|
<title>flip-vertical</title>
|
||||||
|
<desc>Created with Sketch.</desc>
|
||||||
|
<defs></defs>
|
||||||
|
<g id="Page-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
|
||||||
|
<g id="flip-vertical">
|
||||||
|
<g id="flip-horizontal" transform="translate(10.000000, 10.000000) rotate(90.000000) translate(-10.000000, -10.000000) translate(2.000000, 3.000000)">
|
||||||
|
<circle id="Oval" fill="#575E75" opacity="0.5" cx="8" cy="0.75" r="1"></circle>
|
||||||
|
<circle id="Oval" fill="#575E75" opacity="0.5" cx="8" cy="13.25" r="1"></circle>
|
||||||
|
<circle id="Oval-Copy" fill="#575E75" opacity="0.5" cx="8" cy="3.875" r="1"></circle>
|
||||||
|
<circle id="Oval-Copy-2" fill="#575E75" opacity="0.5" cx="8" cy="7" r="1"></circle>
|
||||||
|
<circle id="Oval-Copy-3" fill="#575E75" opacity="0.5" cx="8" cy="10.125" r="1"></circle>
|
||||||
|
<path d="M16,3.08425423 L16,10.9157458 C16,11.4342626 15.2574491,11.6956996 14.8235798,11.3282353 L10.2019293,7.41103711 C9.93269025,7.18445835 9.93269025,6.81408922 10.2019293,6.58751046 L14.8235798,2.67176469 C15.2574491,2.30430042 16,2.56573745 16,3.08425423" id="Fill-11" fill="#4C97FF" opacity="0.5"></path>
|
||||||
|
<path d="M0,10.9157458 L0,3.08425423 C0,2.56573745 0.742550911,2.30430042 1.17470525,2.67176469 L5.79807074,6.58896289 C6.06730975,6.81554165 6.06730975,7.18591078 5.79807074,7.41248954 L1.17470525,11.3282353 C0.742550911,11.6956996 0,11.4342626 0,10.9157458" id="Fill-14" fill="#4C97FF"></path>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 1.8 KiB |
13
src/components/mode-tools/mode-tools.css
Normal file
13
src/components/mode-tools/mode-tools.css
Normal file
|
@ -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;
|
||||||
|
}
|
170
src/components/mode-tools/mode-tools.jsx
Normal file
170
src/components/mode-tools/mode-tools.jsx
Normal file
|
@ -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 (
|
||||||
|
<div className={classNames(props.className, styles.modeTools)}>
|
||||||
|
<div>
|
||||||
|
<img
|
||||||
|
alt={brushMessage}
|
||||||
|
className={styles.modeToolsIcon}
|
||||||
|
src={brushIcon}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<BufferedInput
|
||||||
|
small
|
||||||
|
max={MAX_STROKE_WIDTH}
|
||||||
|
min="0"
|
||||||
|
type="number"
|
||||||
|
value={props.brushValue}
|
||||||
|
onSubmit={props.onBrushSliderChange}
|
||||||
|
/>
|
||||||
|
<Popover
|
||||||
|
body={
|
||||||
|
<Slider
|
||||||
|
value={props.brushValue}
|
||||||
|
onChange={props.onBrushSliderChange}
|
||||||
|
/>
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
case Modes.ERASER:
|
||||||
|
return (
|
||||||
|
<div className={classNames(props.className, styles.modeTools)}>
|
||||||
|
<div>
|
||||||
|
<img
|
||||||
|
alt={eraserMessage}
|
||||||
|
className={styles.modeToolsIcon}
|
||||||
|
src={eraserIcon}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<BufferedInput
|
||||||
|
small
|
||||||
|
max={MAX_STROKE_WIDTH}
|
||||||
|
min="0"
|
||||||
|
type="number"
|
||||||
|
value={props.eraserValue}
|
||||||
|
onSubmit={props.onEraserSliderChange}
|
||||||
|
/>
|
||||||
|
<Popover
|
||||||
|
body={
|
||||||
|
<Slider
|
||||||
|
value={props.eraserValue}
|
||||||
|
onChange={props.onEraserSliderChange}
|
||||||
|
/>
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
case Modes.RESHAPE:
|
||||||
|
return (
|
||||||
|
<div className={classNames(props.className, styles.modeTools)}>
|
||||||
|
<LabeledIconButton
|
||||||
|
disabled
|
||||||
|
imgAlt="Curved Point Icon"
|
||||||
|
imgSrc={curvedPointIcon}
|
||||||
|
title="Curved"
|
||||||
|
onClick={function () {}}
|
||||||
|
/>
|
||||||
|
<LabeledIconButton
|
||||||
|
disabled
|
||||||
|
imgAlt="Straight Point Icon"
|
||||||
|
imgSrc={straightPointIcon}
|
||||||
|
title="Pointed"
|
||||||
|
onClick={function () {}}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
case Modes.SELECT:
|
||||||
|
return (
|
||||||
|
<div className={classNames(props.className, styles.modeTools)}>
|
||||||
|
<LabeledIconButton
|
||||||
|
disabled
|
||||||
|
imgAlt="Flip Horizontal Icon"
|
||||||
|
imgSrc={flipHorizontalIcon}
|
||||||
|
title="Flip Horizontal"
|
||||||
|
onClick={function () {}}
|
||||||
|
/>
|
||||||
|
<LabeledIconButton
|
||||||
|
disabled
|
||||||
|
imgAlt="Flip Vertical Icon"
|
||||||
|
imgSrc={flipVerticalIcon}
|
||||||
|
title="Flip Vertical"
|
||||||
|
onClick={function () {}}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
default:
|
||||||
|
// Leave empty for now, if mode not supported
|
||||||
|
return (
|
||||||
|
<div className={classNames(props.className, styles.modeTools)} />
|
||||||
|
);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
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));
|
14
src/components/mode-tools/straight-point.svg
Executable file
14
src/components/mode-tools/straight-point.svg
Executable file
|
@ -0,0 +1,14 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<svg width="20px" height="20px" viewBox="0 0 20 20" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||||
|
<!-- Generator: Sketch 43.2 (39069) - http://www.bohemiancoding.com/sketch -->
|
||||||
|
<title>straight-point</title>
|
||||||
|
<desc>Created with Sketch.</desc>
|
||||||
|
<defs></defs>
|
||||||
|
<g id="Page-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
|
||||||
|
<g id="straight-point" fill="#4C97FF">
|
||||||
|
<polyline id="Path-2" stroke="#4C97FF" stroke-width="0.75" fill-opacity="0.25" stroke-linecap="round" stroke-linejoin="round" points="2 15 10 7 18 15"></polyline>
|
||||||
|
<circle id="Oval-4" fill-opacity="0.25" cx="10" cy="7" r="3"></circle>
|
||||||
|
<circle id="Oval-4" cx="10" cy="7" r="2"></circle>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 852 B |
|
@ -4,7 +4,7 @@
|
||||||
.editor-container {
|
.editor-container {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
padding: calc(2 * $space);
|
padding: calc(4 * $grid-unit);
|
||||||
}
|
}
|
||||||
|
|
||||||
.row {
|
.row {
|
||||||
|
@ -15,22 +15,22 @@
|
||||||
|
|
||||||
.editor-container-top {
|
.editor-container-top {
|
||||||
border-bottom: 1px dashed $ui-pane-border;
|
border-bottom: 1px dashed $ui-pane-border;
|
||||||
padding-bottom: 1rem;
|
padding-bottom: calc(2 * $grid-unit);
|
||||||
}
|
}
|
||||||
|
|
||||||
.top-align-row {
|
.top-align-row {
|
||||||
display: flex;
|
display: flex;
|
||||||
padding-top:20px;
|
padding-top: calc(5 * $grid-unit);
|
||||||
flex-direction: row;
|
flex-direction: row;
|
||||||
}
|
}
|
||||||
|
|
||||||
.row + .row {
|
.row + .row {
|
||||||
margin-top: calc(2 * $space);
|
margin-top: calc(2 * $grid-unit);
|
||||||
}
|
}
|
||||||
|
|
||||||
.mod-dashed-border {
|
.mod-dashed-border {
|
||||||
border-right: 1px dashed $ui-pane-border;
|
border-right: 1px dashed $ui-pane-border;
|
||||||
padding-right: calc(2 * $space);
|
padding-right: calc(3 * $grid-unit);
|
||||||
}
|
}
|
||||||
|
|
||||||
$border-radius: 0.25rem;
|
$border-radius: 0.25rem;
|
||||||
|
@ -40,7 +40,7 @@ $border-radius: 0.25rem;
|
||||||
border: 1px solid $ui-pane-border;
|
border: 1px solid $ui-pane-border;
|
||||||
border-radius: 0;
|
border-radius: 0;
|
||||||
border-left: none;
|
border-left: none;
|
||||||
padding: 0.5rem;
|
padding: calc(2 * $grid-unit);
|
||||||
}
|
}
|
||||||
|
|
||||||
.button-group-button:active {
|
.button-group-button:active {
|
||||||
|
@ -59,13 +59,13 @@ $border-radius: 0.25rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
.button-group-button-icon {
|
.button-group-button-icon {
|
||||||
width: 1.5rem;
|
width: 1.25rem;
|
||||||
height: 1.5rem;
|
height: 1.25rem;
|
||||||
vertical-align: middle;
|
vertical-align: middle;
|
||||||
}
|
}
|
||||||
|
|
||||||
.mod-mode-tools {
|
.mod-mode-tools {
|
||||||
margin-left: calc(2 * $space);
|
margin-left: calc(3 * $grid-unit);
|
||||||
}
|
}
|
||||||
|
|
||||||
.canvas-container {
|
.canvas-container {
|
||||||
|
@ -79,7 +79,7 @@ $border-radius: 0.25rem;
|
||||||
|
|
||||||
.mode-selector {
|
.mode-selector {
|
||||||
display: flex;
|
display: flex;
|
||||||
margin-right: .5rem;
|
margin-right: calc(2 * $grid-unit);
|
||||||
max-width: 5.5rem;
|
max-width: 5.5rem;
|
||||||
flex-direction: row;
|
flex-direction: row;
|
||||||
flex-wrap: wrap;
|
flex-wrap: wrap;
|
||||||
|
|
|
@ -8,10 +8,11 @@ import PaperCanvas from '../../containers/paper-canvas.jsx';
|
||||||
import Button from '../button/button.jsx';
|
import Button from '../button/button.jsx';
|
||||||
import ButtonGroup from '../button-group/button-group.jsx';
|
import ButtonGroup from '../button-group/button-group.jsx';
|
||||||
import BrushMode from '../../containers/brush-mode.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 EraserMode from '../../containers/eraser-mode.jsx';
|
||||||
import InputGroup from '../input-group/input-group.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 LineMode from '../../containers/line-mode.jsx';
|
||||||
|
import ModeToolsComponent from '../mode-tools/mode-tools.jsx';
|
||||||
import OvalMode from '../../containers/oval-mode.jsx';
|
import OvalMode from '../../containers/oval-mode.jsx';
|
||||||
import PenMode from '../../containers/pen-mode.jsx';
|
import PenMode from '../../containers/pen-mode.jsx';
|
||||||
import RectMode from '../../containers/rect-mode.jsx';
|
import RectMode from '../../containers/rect-mode.jsx';
|
||||||
|
@ -103,13 +104,13 @@ class PaintEditorComponent extends React.Component {
|
||||||
|
|
||||||
{/* Group/Ungroup */}
|
{/* Group/Ungroup */}
|
||||||
<InputGroup className={styles.modDashedBorder}>
|
<InputGroup className={styles.modDashedBorder}>
|
||||||
<EditFieldButton
|
<LabeledIconButton
|
||||||
imgAlt="Group Icon"
|
imgAlt="Group Icon"
|
||||||
imgSrc={groupIcon}
|
imgSrc={groupIcon}
|
||||||
title="Group"
|
title="Group"
|
||||||
onClick={this.props.onGroup}
|
onClick={this.props.onGroup}
|
||||||
/>
|
/>
|
||||||
<EditFieldButton
|
<LabeledIconButton
|
||||||
imgAlt="Ungroup Icon"
|
imgAlt="Ungroup Icon"
|
||||||
imgSrc={ungroupIcon}
|
imgSrc={ungroupIcon}
|
||||||
title="Ungroup"
|
title="Ungroup"
|
||||||
|
@ -119,13 +120,13 @@ class PaintEditorComponent extends React.Component {
|
||||||
|
|
||||||
{/* Forward/Backward */}
|
{/* Forward/Backward */}
|
||||||
<InputGroup className={styles.modDashedBorder}>
|
<InputGroup className={styles.modDashedBorder}>
|
||||||
<EditFieldButton
|
<LabeledIconButton
|
||||||
imgAlt="Send Forward Icon"
|
imgAlt="Send Forward Icon"
|
||||||
imgSrc={sendForwardIcon}
|
imgSrc={sendForwardIcon}
|
||||||
title="Forward"
|
title="Forward"
|
||||||
onClick={this.props.onSendForward}
|
onClick={this.props.onSendForward}
|
||||||
/>
|
/>
|
||||||
<EditFieldButton
|
<LabeledIconButton
|
||||||
imgAlt="Send Backward Icon"
|
imgAlt="Send Backward Icon"
|
||||||
imgSrc={sendBackwardIcon}
|
imgSrc={sendBackwardIcon}
|
||||||
title="Backward"
|
title="Backward"
|
||||||
|
@ -135,13 +136,13 @@ class PaintEditorComponent extends React.Component {
|
||||||
|
|
||||||
{/* Front/Back */}
|
{/* Front/Back */}
|
||||||
<InputGroup>
|
<InputGroup>
|
||||||
<EditFieldButton
|
<LabeledIconButton
|
||||||
imgAlt="Send to Front Icon"
|
imgAlt="Send to Front Icon"
|
||||||
imgSrc={sendFrontIcon}
|
imgSrc={sendFrontIcon}
|
||||||
title="Front"
|
title="Front"
|
||||||
onClick={this.props.onSendToFront}
|
onClick={this.props.onSendToFront}
|
||||||
/>
|
/>
|
||||||
<EditFieldButton
|
<LabeledIconButton
|
||||||
imgAlt="Send to Back Icon"
|
imgAlt="Send to Back Icon"
|
||||||
imgSrc={sendBackIcon}
|
imgSrc={sendBackIcon}
|
||||||
title="Back"
|
title="Back"
|
||||||
|
@ -151,7 +152,7 @@ class PaintEditorComponent extends React.Component {
|
||||||
|
|
||||||
{/* To be rotation point */}
|
{/* To be rotation point */}
|
||||||
{/* <InputGroup>
|
{/* <InputGroup>
|
||||||
<EditFieldButton
|
<LabeledIconButton
|
||||||
imgAlt="Rotation Point Icon"
|
imgAlt="Rotation Point Icon"
|
||||||
imgSrc={rotationPointIcon}
|
imgSrc={rotationPointIcon}
|
||||||
title="Rotation Point"
|
title="Rotation Point"
|
||||||
|
@ -177,7 +178,7 @@ class PaintEditorComponent extends React.Component {
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<InputGroup className={styles.modModeTools}>
|
<InputGroup className={styles.modModeTools}>
|
||||||
Mode tools
|
<ModeToolsComponent />
|
||||||
</InputGroup>
|
</InputGroup>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -14,7 +14,7 @@ $border-radius: .25rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
.mod-tool-select.is-selected {
|
.mod-tool-select.is-selected {
|
||||||
background-color: $ui-background-blue;
|
background-color: $motion-transparent;
|
||||||
}
|
}
|
||||||
|
|
||||||
.mod-tool-select:focus {
|
.mod-tool-select:focus {
|
||||||
|
|
|
@ -2,7 +2,12 @@
|
||||||
@todo This file is copied from GUI and should be pulled out into a shared library.
|
@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 */
|
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;
|
$space: 0.5rem;
|
||||||
|
$grid-unit: .25rem;
|
||||||
|
|
||||||
$sprites-per-row: 5;
|
$sprites-per-row: 5;
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue