diff --git a/src/components/asset-panel/icon--add-backdrop-lib.svg b/src/components/asset-panel/icon--add-backdrop-lib.svg new file mode 100644 index 0000000000000000000000000000000000000000..8c80f17aa6298fce7de769ca9dfcff12b444116f Binary files /dev/null and b/src/components/asset-panel/icon--add-backdrop-lib.svg differ diff --git a/src/components/asset-panel/icon--add-blank-costume.svg b/src/components/asset-panel/icon--add-blank-costume.svg new file mode 100644 index 0000000000000000000000000000000000000000..20843fe6161859f318031dc0bf1c7f0f9f54c24b Binary files /dev/null and b/src/components/asset-panel/icon--add-blank-costume.svg differ diff --git a/src/components/asset-panel/selector.css b/src/components/asset-panel/selector.css index 63e6868326617b20c9ae347b20a71f29400c195c..546a7863dd5a82cc597c9201219a69ca9c23137b 100644 --- a/src/components/asset-panel/selector.css +++ b/src/components/asset-panel/selector.css @@ -17,6 +17,7 @@ justify-content: space-around; margin: 1.25rem 0; color: $motion-primary; + text-align: center; } .new-button { diff --git a/src/containers/costume-tab.jsx b/src/containers/costume-tab.jsx index 9f84d53c2195cb8e3fc1e088ed2a667bfdd6132a..a142ff9121356edf2804cda81846fcc2e2a8a216 100644 --- a/src/containers/costume-tab.jsx +++ b/src/containers/costume-tab.jsx @@ -5,7 +5,6 @@ import {FormattedMessage} from 'react-intl'; import VM from 'scratch-vm'; import AssetPanel from '../components/asset-panel/asset-panel.jsx'; -import addCostumeIcon from '../components/asset-panel/icon--add-costume-lib.svg'; import PaintEditorWrapper from './paint-editor-wrapper.jsx'; import CostumeLibrary from './costume-library.jsx'; import BackdropLibrary from './backdrop-library.jsx'; @@ -18,17 +17,53 @@ import { openBackdropLibrary } from '../reducers/modals'; +import addBlankCostumeIcon from '../components/asset-panel/icon--add-blank-costume.svg'; +import addLibraryBackdropIcon from '../components/asset-panel/icon--add-backdrop-lib.svg'; +import addLibraryCostumeIcon from '../components/asset-panel/icon--add-costume-lib.svg'; +import costumeLibraryContent from '../lib/libraries/costumes.json'; + +const messages = { + addLibraryBackdropMsg: ( + <FormattedMessage + defaultMessage="Add Backdrop From Library" + description="Button to add a backdrop in the editor tab" + id="gui.costumeTab.addBackdrop" + /> + ), + addLibraryCostumeMsg: ( + <FormattedMessage + defaultMessage="Add Costume From Library" + description="Button to add a costume in the editor tab" + id="gui.costumeTab.addCostume" + /> + ), + addBlankBackdropMsg: ( + <FormattedMessage + defaultMessage="Add Blank Backdrop" + description="Button to add a blank backdrop in the editor tab" + id="gui.costumeTab.addBlankBackdrop" + /> + ), + addBlankCostumeMsg: ( + <FormattedMessage + defaultMessage="Add Blank Costume" + description="Button to add a blank costume in the editor tab" + id="gui.costumeTab.addBlankCostume" + /> + ) +}; + class CostumeTab extends React.Component { constructor (props) { super(props); bindAll(this, [ 'handleSelectCostume', 'handleDeleteCostume', - 'handleNewCostume' + 'handleNewCostume', + 'handleNewBlankCostume' ]); this.state = {selectedCostumeIndex: 0}; } - componentWillReceiveProps (nextProps) { const { editingTarget, @@ -41,27 +76,40 @@ class CostumeTab extends React.Component { this.setState({selectedCostumeIndex: target.costumes.length - 1}); } } - handleSelectCostume (costumeIndex) { this.props.vm.editingTarget.setCostume(costumeIndex); this.setState({selectedCostumeIndex: costumeIndex}); } - handleDeleteCostume (costumeIndex) { this.props.vm.deleteCostume(costumeIndex); } - handleNewCostume () { if (!this.props.vm.editingTarget) return; const costumes = this.props.vm.editingTarget.sprite.costumes || []; this.setState({selectedCostumeIndex: Math.max(costumes.length - 1, 0)}); } - + handleNewBlankCostume () { + const emptyItem = costumeLibraryContent.find(item => ( + item.name === 'Empty' + )); + const name = this.props.vm.editingTarget.isStage ? `backdrop1` : `costume1`; + const vmCostume = { + name: name, + rotationCenterX: emptyItem.info[0], + rotationCenterY: emptyItem.info[1], + bitmapResolution: emptyItem.info.length > 2 ? emptyItem.info[2] : 1, + skinId: null + }; + + this.props.vm.addCostume(emptyItem.md5, vmCostume).then(() => { + this.handleNewCostume(); + }); + } render () { // For paint wrapper const { - onNewBackdropClick, - onNewCostumeClick, + onNewLibraryBackdropClick, + onNewLibraryCostumeClick, costumeLibraryVisible, backdropLibraryVisible, onRequestCloseCostumeLibrary, @@ -82,31 +130,25 @@ class CostumeTab extends React.Component { return null; } - const addBackdropMsg = ( - <FormattedMessage - defaultMessage="Add Backdrop" - description="Button to add a backdrop in the editor tab" - id="gui.costumeTab.addBackdrop" - /> - ); - const addCostumeMsg = ( - <FormattedMessage - defaultMessage="Add Costume" - description="Button to add a costume in the editor tab" - id="gui.costumeTab.addCostume" - /> - ); - - const addMessage = target.isStage ? addBackdropMsg : addCostumeMsg; - const addFunc = target.isStage ? onNewBackdropClick : onNewCostumeClick; + const addLibraryMessage = target.isStage ? messages.addLibraryBackdropMsg : messages.addLibraryCostumeMsg; + const addBlankMessage = target.isStage ? messages.addBlankBackdropMsg : messages.addBlankCostumeMsg; + const addLibraryFunc = target.isStage ? onNewLibraryBackdropClick : onNewLibraryCostumeClick; + const addLibraryIcon = target.isStage ? addLibraryBackdropIcon : addLibraryCostumeIcon; return ( <AssetPanel - buttons={[{ - message: addMessage, - img: addCostumeIcon, - onClick: addFunc - }]} + buttons={[ + { + message: addBlankMessage, + img: addBlankCostumeIcon, + onClick: this.handleNewBlankCostume + }, + { + message: addLibraryMessage, + img: addLibraryIcon, + onClick: addLibraryFunc + } + ]} items={target.costumes || []} selectedItemIndex={this.state.selectedCostumeIndex} onDeleteClick={target.costumes.length > 1 ? this.handleDeleteCostume : null} @@ -142,8 +184,8 @@ CostumeTab.propTypes = { backdropLibraryVisible: PropTypes.bool, costumeLibraryVisible: PropTypes.bool, editingTarget: PropTypes.string, - onNewBackdropClick: PropTypes.func.isRequired, - onNewCostumeClick: PropTypes.func.isRequired, + onNewLibraryBackdropClick: PropTypes.func.isRequired, + onNewLibraryCostumeClick: PropTypes.func.isRequired, onRequestCloseBackdropLibrary: PropTypes.func.isRequired, onRequestCloseCostumeLibrary: PropTypes.func.isRequired, sprites: PropTypes.shape({ @@ -171,11 +213,11 @@ const mapStateToProps = state => ({ }); const mapDispatchToProps = dispatch => ({ - onNewBackdropClick: e => { + onNewLibraryBackdropClick: e => { e.preventDefault(); dispatch(openBackdropLibrary()); }, - onNewCostumeClick: e => { + onNewLibraryCostumeClick: e => { e.preventDefault(); dispatch(openCostumeLibrary()); },