package org.andengine.entity.sprite; import org.andengine.entity.scene.ITouchArea; import org.andengine.entity.scene.Scene; import org.andengine.input.touch.TouchEvent; import org.andengine.opengl.texture.region.ITextureRegion; import org.andengine.opengl.texture.region.ITiledTextureRegion; import org.andengine.opengl.texture.region.TiledTextureRegion; import org.andengine.opengl.vbo.VertexBufferObjectManager; import org.andengine.util.debug.Debug; /** * Note: {@link ButtonSprite} needs to be registered as a {@link ITouchArea} to the {@link Scene} via {@link Scene#registerTouchArea(ITouchArea)}, otherwise it won't be clickable. * To make {@link ButtonSprite} function properly, you should consider setting {@link Scene#setTouchAreaBindingOnActionDownEnabled(boolean)} to <code>true</code>. * * (c) Zynga 2012 * * @author Scott Kennedy <skennedy@zynga.com> * @author Nicolas Gramlich <ngramlich@zynga.com> * @since 15:51:57 - 05.01.2012 */ public class ButtonSprite extends TiledSprite { // =========================================================== // Constants // =========================================================== // =========================================================== // Fields // =========================================================== private final int mStateCount; private OnClickListener mOnClickListener; private boolean mEnabled = true; private State mState; // =========================================================== // Constructors // =========================================================== public ButtonSprite(final float pX, final float pY, final ITextureRegion pNormalTextureRegion, final VertexBufferObjectManager pVertexBufferObjectManager) { this(pX, pY, pNormalTextureRegion, pVertexBufferObjectManager, (OnClickListener) null); } public ButtonSprite(final float pX, final float pY, final ITextureRegion pNormalTextureRegion, final VertexBufferObjectManager pVertexBufferObjectManager, final OnClickListener pOnClickListener) { this(pX, pY, new TiledTextureRegion(pNormalTextureRegion.getTexture(), pNormalTextureRegion), pVertexBufferObjectManager, pOnClickListener); } public ButtonSprite(final float pX, final float pY, final ITextureRegion pNormalTextureRegion, final ITextureRegion pPressedTextureRegion, final VertexBufferObjectManager pVertexBufferObjectManager) { this(pX, pY, pNormalTextureRegion, pPressedTextureRegion, pVertexBufferObjectManager, (OnClickListener) null); } public ButtonSprite(final float pX, final float pY, final ITextureRegion pNormalTextureRegion, final ITextureRegion pPressedTextureRegion, final VertexBufferObjectManager pVertexBufferObjectManager, final OnClickListener pOnClickListener) { this(pX, pY, new TiledTextureRegion(pNormalTextureRegion.getTexture(), pNormalTextureRegion, pPressedTextureRegion), pVertexBufferObjectManager, pOnClickListener); } public ButtonSprite(final float pX, final float pY, final ITextureRegion pNormalTextureRegion, final ITextureRegion pPressedTextureRegion, final ITextureRegion pDisabledTextureRegion, final VertexBufferObjectManager pVertexBufferObjectManager) { this(pX, pY, pNormalTextureRegion, pPressedTextureRegion, pDisabledTextureRegion, pVertexBufferObjectManager, (OnClickListener) null); } public ButtonSprite(final float pX, final float pY, final ITextureRegion pNormalTextureRegion, final ITextureRegion pPressedTextureRegion, final ITextureRegion pDisabledTextureRegion, final VertexBufferObjectManager pVertexBufferObjectManager, final OnClickListener pOnClickListener) { this(pX, pY, new TiledTextureRegion(pNormalTextureRegion.getTexture(), pNormalTextureRegion, pPressedTextureRegion, pDisabledTextureRegion), pVertexBufferObjectManager, pOnClickListener); } public ButtonSprite(final float pX, final float pY, final ITiledTextureRegion pTiledTextureRegion, final VertexBufferObjectManager pVertexBufferObjectManager) { this(pX, pY, pTiledTextureRegion, pVertexBufferObjectManager, (OnClickListener) null); } public ButtonSprite(final float pX, final float pY, final ITiledTextureRegion pTiledTextureRegion, final VertexBufferObjectManager pVertexBufferObjectManager, final OnClickListener pOnClickListener) { super(pX, pY, pTiledTextureRegion, pVertexBufferObjectManager); this.mOnClickListener = pOnClickListener; this.mStateCount = pTiledTextureRegion.getTileCount(); switch(this.mStateCount) { case 1: Debug.w("No " + ITextureRegion.class.getSimpleName() + " supplied for " + State.class.getSimpleName() + "." + State.PRESSED + "."); case 2: Debug.w("No " + ITextureRegion.class.getSimpleName() + " supplied for " + State.class.getSimpleName() + "." + State.DISABLED + "."); break; case 3: break; default: throw new IllegalArgumentException("The supplied " + ITiledTextureRegion.class.getSimpleName() + " has an unexpected amount of states: '" + this.mStateCount + "'."); } this.changeState(State.NORMAL); } // =========================================================== // Getter & Setter // =========================================================== public boolean isEnabled() { return this.mEnabled; } public void setEnabled(final boolean pEnabled) { this.mEnabled = pEnabled; if(this.mEnabled && this.mState == State.DISABLED) { this.changeState(State.NORMAL); } else if(!this.mEnabled) { this.changeState(State.DISABLED); } } public boolean isPressed() { return this.mState == State.PRESSED; } public State getState() { return this.mState; } public void setOnClickListener(final OnClickListener pOnClickListener) { this.mOnClickListener = pOnClickListener; } // =========================================================== // Methods for/from SuperClass/Interfaces // =========================================================== @Override public boolean onAreaTouched(final TouchEvent pSceneTouchEvent, final float pTouchAreaLocalX, final float pTouchAreaLocalY) { if(!this.isEnabled()) { this.changeState(State.DISABLED); } else if(pSceneTouchEvent.isActionDown()) { this.changeState(State.PRESSED); } else if(pSceneTouchEvent.isActionCancel() || !this.contains(pSceneTouchEvent.getX(), pSceneTouchEvent.getY())) { this.changeState(State.NORMAL); } else if(pSceneTouchEvent.isActionUp() && this.mState == State.PRESSED) { this.changeState(State.NORMAL); if(this.mOnClickListener != null) { this.mOnClickListener.onClick(this, pTouchAreaLocalX, pTouchAreaLocalY); } } return true; } @Override public boolean contains(final float pX, final float pY) { if(!this.isVisible()) { return false; } else { return super.contains(pX, pY); } } // =========================================================== // Methods // =========================================================== private void changeState(final State pState) { if(pState == this.mState) { return; } this.mState = pState; final int stateTiledTextureRegionIndex = this.mState.getTiledTextureRegionIndex(); if(stateTiledTextureRegionIndex >= this.mStateCount) { this.setCurrentTileIndex(0); Debug.w(this.getClass().getSimpleName() + " changed its " + State.class.getSimpleName() + " to " + pState.toString() + ", which doesn't have a " + ITextureRegion.class.getSimpleName() + " supplied. Applying default " + ITextureRegion.class.getSimpleName() + "."); } else { this.setCurrentTileIndex(stateTiledTextureRegionIndex); } } // =========================================================== // Inner and Anonymous Classes // =========================================================== public interface OnClickListener { // =========================================================== // Constants // =========================================================== // =========================================================== // Methods // =========================================================== public void onClick(final ButtonSprite pButtonSprite, final float pTouchAreaLocalX, final float pTouchAreaLocalY); } public static enum State { // =========================================================== // Elements // =========================================================== NORMAL(0), PRESSED(1), DISABLED(2); // =========================================================== // Constants // =========================================================== // =========================================================== // Fields // =========================================================== private final int mTiledTextureRegionIndex; // =========================================================== // Constructors // =========================================================== private State(final int pTiledTextureRegionIndex) { this.mTiledTextureRegionIndex = pTiledTextureRegionIndex; } // =========================================================== // Getter & Setter // =========================================================== public int getTiledTextureRegionIndex() { return this.mTiledTextureRegionIndex; } // =========================================================== // Methods for/from SuperClass/Interfaces // =========================================================== // =========================================================== // Methods // =========================================================== // =========================================================== // Inner and Anonymous Classes // =========================================================== } }