From 0e56c4db6ef5ab47f7940c6d38e30f987312ae1d Mon Sep 17 00:00:00 2001 From: Matthew Taylor <mewtaylor@gmail.com> Date: Wed, 3 Jan 2018 15:26:55 -0500 Subject: [PATCH] Implement paint-75: Add blank costume button (#1137) * Implement paint-75: Add blank costume button * add backdrop icon, use default name thanks @fsih ! --- .../asset-panel/icon--add-backdrop-lib.svg | Bin 0 -> 2300 bytes .../asset-panel/icon--add-blank-costume.svg | Bin 0 -> 1787 bytes src/components/asset-panel/selector.css | 1 + src/containers/costume-tab.jsx | 112 ++++++++++++------ 4 files changed, 78 insertions(+), 35 deletions(-) create mode 100644 src/components/asset-panel/icon--add-backdrop-lib.svg create mode 100644 src/components/asset-panel/icon--add-blank-costume.svg 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 GIT binary patch literal 2300 zcmcImO>f&U488YPXzFDJY}t~(3p>S@p}S<*fNq!FTw9I3xOQNxNw!}<QnphkOWN%) z0ZmAWdL$nyrt!`0u_7DUc4bp1lrx(WS!YdN*2{!``+94JlyoYs^R#Menb5kSH?xbl z+bqep%vF(45v_NW6tY|v3N#P3O)0nUn_WU}ViOS&;lbXs6HW=Zt-FL4O0BOgYrEaD zt;3pjX$jl5Er1_Pu6I>guTB~AD2gn7N@o`YR{X{^$wyhsHdRe~P3~4wWd(5^CdgYS zvi<0am}KJdzA5BmnGWf)ta-G${*Gx5kg8OboTYhg-Y;XT*Lr8U?6TRsm8p_BP@#&! zAB!!0G+I4$J(P|xE8DD+q|6h#PE}z75gD)~@cU;%fu$BdXR*~=4p9K&2oo>$?Jwz4 z;_Xhg%}ST0mZN44g@NOTvZ}CVc!;vuK2=~XH?nT>e18EbmRY(^Xxlv1huc4z68fUw zpCr;p@j-Sg)vQg^<RY|pfq?E&ZCZB^P5YQoEmlC#TR0akgUZ4(i0S*`pj-{LLw0Zt z>D?*J?;Wsv29QIW?D1TGl#k&iknhuMmA4S=3#cQEflbp#dkS%adOxD7vXV!+pxL;F zy!u8um(#O*?gy{<p8%g^oO^qEM%Z(yj8OO;V_Onv&rduugdhunpL3gO%{Bx`fx|u5 zCAPsM7Vr>C5t4;%1WbfH3?d$Zz2P%k_@V3hU<j8zBH(WUpdOh62*({hwE}H|umE)e zKL>T<S_42_eT?6!eiC;@y57HmgkHMyD7d}d_xL!i@Nr?1&&@o|e=0w7fx!d}<M&x; zaECc$4x%u)U;zQDwd51-G7pb|w}?4-2Mj~p3s^(~=AsZ14HA%rk2XGY$=qXs0Wdz% z03Nt<(2>tLG7Cfiq9&gsw}QjI4F(`YgpUHS3xIkLDIP>L?r-!Ga1T|*%|4|uw|``D z7%d~qe@|*ZIX-XF>R=?njQS<p=7lG8P@1Ps9z}3+zUiNb>!Otp&=AAKg;3%4>*Ys( z@i4H*F?)Hd*Pl&wVvPI8V|<#xu^d~=*CRS;NC&HE1gCrdT$q1fru`fc&iHWugR2+Q VK6`lb;E&CNjlH6U82`bT{RWM8FEaoD literal 0 HcmV?d00001 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 GIT binary patch literal 1787 zcma)7O>f&q6ujqGY}reKlB<2YZ@&yl0V=?~I6#0jm)sbMmRQTAK+=|ferHL^vK<30 zA;`<&?##S-PxSor)BRpNR$X7W%_1YIGEp__c2hUoMfUyg>mp>LAIfG^?%SqXWKElW zUVfPOk6Ur9H^Xj`>2P?;#ICBhyWxEISXakC+owgQgc3U7lf4w7OhC5j7ujwY4p+0; z@pzO+Bin8}(@Los=uca&p7wQf_ufW|G0w)P+46(HHUF(B#9viYb>+}@SK`}UHLQ1n zjnv|!iOR)Kq7W|>f3~~ozAjJY%5{4`>!&kCaiSdRVP7rF%|`Txt{$rSY(gf%P1UcL ztF9`CYJ)h2-APl<XXB&uuG@Z@5d4{tt*AGP>}$EL3PjNlU3)i1+f?Vf;uJ0(-`4wm z$~`?y>!N$uV|VpfHSK2ed;l?3>+-P3y7r-Y4gb^D=<S404#v197pSe6YCBUcvfp_X z{q^-J*R(lZ^Q{=VvgvQz?tYPt%RMUpXeC;PD;Msx`jm|Y{&8kJSEJuBPOKM8qs-}R zekhSAV)~*bQ*h4Nm@9Gf;*Mo7-WWrE()+e64^@V!)6xH8y&TRjl;TFcxcgtM^V#;b z)UUvECFG?gueEkLmYSHY@nS_z5_=T_<rJj#C`cJWR+90SEaw!Z_KKCWf>;`6?W0eq zHNko|pkPTVMq)4r8MI-iv>+or866!q2T6{ik0GHTW$hs6rBmKJ$Dq)V_Evl7d8w?i z7A8nWQXGQG;nIPWlQohQqH!D($`H0HF_2{M1F_Cw-f3er3~TIFQAL}>q|=(5<>bK{ zqX<34QU|znZcG9M$`h<9so1iyUT8Q&J{I|4!XmR#0F89)JnG9m6d0x1AXb{CXUBm# z4+za#9oPx2q=z)PlU$6B5vF**9Y4eu6oT>*sLdfm&MRVY!%~a^fw=^`K+2{#l{Cs3 z_6dyaFp?~ybi^t+6Gjx?&`NRh29Ay>x&$+m(xlC}`vk8rqDlv}gmaXY+Lv5wnIb~j zXlb;ToEDe~KOUckLTTekixpbqkd;FF5r9V1QHSu-z?xMS4T(q&<2Iq}B4!1=KrLe; zL4k2ph&l2ohk88>jU^*m{~El6_L2ep$8m6s9-IX)2ri(O%4-|lI92bY{$u(T{(R{A gT~V*w=Iu*GNqc@tKEJo#z5<?qljCBZ{=Y2$1y9zkf&c&j literal 0 HcmV?d00001 diff --git a/src/components/asset-panel/selector.css b/src/components/asset-panel/selector.css index 63e686832..546a7863d 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 9f84d53c2..a142ff912 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()); }, -- GitLab