scratch-gui
Version:
GraphicaL User Interface for creating and running Scratch 3.0 projects
189 lines (179 loc) • 7.28 kB
JSX
import PropTypes from 'prop-types';
import React from 'react';
import classNames from 'classnames';
import {defineMessages, injectIntl, intlShape} from 'react-intl';
import Box from '../box/box.jsx';
import SpriteInfo from '../../containers/sprite-info.jsx';
import SpriteSelectorItem from '../../containers/sprite-selector-item.jsx';
import ActionMenu from '../action-menu/action-menu.jsx';
import styles from './sprite-selector.css';
import fileUploadIcon from '../action-menu/icon--file-upload.svg';
import paintIcon from '../action-menu/icon--paint.svg';
import spriteIcon from '../action-menu/icon--sprite.svg';
import surpriseIcon from '../action-menu/icon--surprise.svg';
const messages = defineMessages({
addSpriteFromLibrary: {
id: 'gui.spriteSelector.addSpriteFromLibrary',
description: 'Button to add a sprite in the target pane from library',
defaultMessage: 'Choose a Sprite'
},
addSpriteFromPaint: {
id: 'gui.spriteSelector.addSpriteFromPaint',
description: 'Button to add a sprite in the target pane from paint',
defaultMessage: 'Paint'
},
addSpriteFromSurprise: {
id: 'gui.spriteSelector.addSpriteFromSurprise',
description: 'Button to add a random sprite in the target pane',
defaultMessage: 'Surprise'
},
addSpriteFromFile: {
id: 'gui.spriteSelector.addSpriteFromFile',
description: 'Button to add a sprite in the target pane from file',
defaultMessage: 'Upload'
}
});
const SpriteSelectorComponent = function (props) {
const {
editingTarget,
hoveredTarget,
intl,
onChangeSpriteDirection,
onChangeSpriteName,
onChangeSpriteSize,
onChangeSpriteVisibility,
onChangeSpriteX,
onChangeSpriteY,
onDeleteSprite,
onDuplicateSprite,
onFileUploadClick,
onNewSpriteClick,
onPaintSpriteClick,
onSelectSprite,
onSpriteUpload,
onSurpriseSpriteClick,
raised,
selectedId,
spriteFileInput,
sprites,
...componentProps
} = props;
let selectedSprite = sprites[selectedId];
let spriteInfoDisabled = false;
if (typeof selectedSprite === 'undefined') {
selectedSprite = {};
spriteInfoDisabled = true;
}
return (
<Box
className={styles.spriteSelector}
{...componentProps}
>
<SpriteInfo
direction={selectedSprite.direction}
disabled={spriteInfoDisabled}
name={selectedSprite.name}
size={selectedSprite.size}
visible={selectedSprite.visible}
x={selectedSprite.x}
y={selectedSprite.y}
onChangeDirection={onChangeSpriteDirection}
onChangeName={onChangeSpriteName}
onChangeSize={onChangeSpriteSize}
onChangeVisibility={onChangeSpriteVisibility}
onChangeX={onChangeSpriteX}
onChangeY={onChangeSpriteY}
/>
<Box className={styles.scrollWrapper}>
<Box className={styles.itemsWrapper}>
{Object.keys(sprites)
// Re-order by list order
.sort((id1, id2) => sprites[id1].order - sprites[id2].order)
.map(id => sprites[id])
.map(sprite => (
<SpriteSelectorItem
assetId={sprite.costume && sprite.costume.assetId}
className={hoveredTarget.sprite === sprite.id &&
sprite.id !== editingTarget &&
hoveredTarget.receivedBlocks ?
classNames(styles.sprite, styles.receivedBlocks) :
raised && sprite.id !== editingTarget ?
classNames(styles.sprite, styles.raised) : styles.sprite}
id={sprite.id}
key={sprite.id}
name={sprite.name}
selected={sprite.id === selectedId}
onClick={onSelectSprite}
onDeleteButtonClick={onDeleteSprite}
onDuplicateButtonClick={onDuplicateSprite}
/>
))
}
</Box>
</Box>
<ActionMenu
className={styles.addButton}
img={spriteIcon}
moreButtons={[
{
title: intl.formatMessage(messages.addSpriteFromFile),
img: fileUploadIcon,
onClick: onFileUploadClick,
fileAccept: '.svg, .png, .jpg, .jpeg, .sprite2', // TODO add sprite 3
fileChange: onSpriteUpload,
fileInput: spriteFileInput
}, {
title: intl.formatMessage(messages.addSpriteFromSurprise),
img: surpriseIcon,
onClick: onSurpriseSpriteClick // TODO need real function for this
}, {
title: intl.formatMessage(messages.addSpriteFromPaint),
img: paintIcon,
onClick: onPaintSpriteClick // TODO need real function for this
}
]}
title={intl.formatMessage(messages.addSpriteFromLibrary)}
onClick={onNewSpriteClick}
/>
</Box>
);
};
SpriteSelectorComponent.propTypes = {
editingTarget: PropTypes.string,
hoveredTarget: PropTypes.shape({
hoveredSprite: PropTypes.string,
receivedBlocks: PropTypes.bool
}),
intl: intlShape.isRequired,
onChangeSpriteDirection: PropTypes.func,
onChangeSpriteName: PropTypes.func,
onChangeSpriteSize: PropTypes.func,
onChangeSpriteVisibility: PropTypes.func,
onChangeSpriteX: PropTypes.func,
onChangeSpriteY: PropTypes.func,
onDeleteSprite: PropTypes.func,
onDuplicateSprite: PropTypes.func,
onFileUploadClick: PropTypes.func,
onNewSpriteClick: PropTypes.func,
onPaintSpriteClick: PropTypes.func,
onSelectSprite: PropTypes.func,
onSpriteUpload: PropTypes.func,
onSurpriseSpriteClick: PropTypes.func,
raised: PropTypes.bool,
selectedId: PropTypes.string,
spriteFileInput: PropTypes.func,
sprites: PropTypes.shape({
id: PropTypes.shape({
costume: PropTypes.shape({
url: PropTypes.string,
name: PropTypes.string.isRequired,
bitmapResolution: PropTypes.number.isRequired,
rotationCenterX: PropTypes.number.isRequired,
rotationCenterY: PropTypes.number.isRequired
}),
name: PropTypes.string.isRequired,
order: PropTypes.number.isRequired
})
})
};
export default injectIntl(SpriteSelectorComponent);