XNA Button

This post is about creating a simple event-based button in XNA. I'll dump the code here. Future self is responsible for understanding it in case he/I don't remember it.


public class Button
{
Texture2D _upTexture, _mouseOverTexture, _mouseDownTexture, _disabledTexture;
int _width, _height, _x, _y;
string _name;
bool _enabled;
Rectangle _drawRectangle;
 
//States
ButtonStates _state;
KeyboardState _prevKeyState;
MouseState _prevMouseState;
 
public bool Enabled
{
get
{
return _enabled;
}
 
set
{
_enabled = value;
}
}
 
public string Name
{
get
{
return _name; 
}
set
{
_name = value;
}
}
 
public int Width
{
get
{
return _width;        
}
set
{
_width = value;
UpdateRectangle();
}
}
 
public int Height
{
get
{
return _height;
}
set
{
_height = value;
UpdateRectangle();
}
}
 
public int Left
{
get
{
return _x;
}
set
{
_x = value;
UpdateRectangle();
}
}
 
public int Top
{
get
{
return _y;
}
set
{
_y = value;
UpdateRectangle();
}
}
 
void UpdateRectangle()
{
_drawRectangle.X = _x;
_drawRectangle.Y = _y;
_drawRectangle.Width = _width;
_drawRectangle.Height = _height;
}
 
public Button(Texture2D up, Texture2D mouseOver, Texture2D mouseDown, Texture2D disabled)
{
_upTexture = up;
_mouseOverTexture = mouseOver;
_mouseDownTexture = mouseDown;
_disabledTexture = disabled;
 
_width = _height = 50;
_x = _y = 0;
_enabled = true;
_drawRectangle = new Rectangle();
_state = ButtonStates.Up;
}
 
public void Update()
{
if (_prevKeyState == null || _prevMouseState == null)
{
_prevMouseState = Mouse.GetState();
_prevKeyState = Keyboard.GetState();
return;
}
 
KeyboardState currentKeyState = Keyboard.GetState();
MouseState currentMouseState = Mouse.GetState();
 
if (_enabled)
{
switch (_state)
{
case ButtonStates.Up:
if (_drawRectangle.Contains(currentMouseState.X, currentMouseState.Y))
{
if (currentMouseState.LeftButton == ButtonState.Pressed && _prevMouseState.LeftButton != ButtonState.Pressed)
{
_state = ButtonStates.MouseDown;
}
else
{
_state = ButtonStates.MouseOver;
}
}
break;
 
case ButtonStates.MouseOver:
if (_drawRectangle.Contains(currentMouseState.X, currentMouseState.Y))
{
if (currentMouseState.LeftButton == ButtonState.Pressed && _prevMouseState.LeftButton != ButtonState.Pressed)
{
_state = ButtonStates.MouseDown;
}
}
else
{
_state = ButtonStates.Up;
}
 
break;
 
case ButtonStates.MouseDown:
if (_drawRectangle.Contains(currentMouseState.X, currentMouseState.Y))
{
if (currentMouseState.LeftButton != ButtonState.Pressed && _prevMouseState.LeftButton == ButtonState.Pressed)
{
_state = ButtonStates.Up;
 
//Fire Click event
if (OnClick != null)
{
OnClick(this);
}
}
}
else
{
if (currentMouseState.LeftButton != ButtonState.Pressed && _prevMouseState.LeftButton == ButtonState.Pressed)
{
//Release outside
_state = ButtonStates.Up;                                
}
}
break;
 
default:
break;
}
}           
 
_prevKeyState = currentKeyState;
_prevMouseState = currentMouseState;

}
 
public void Draw(SpriteBatch spriteBatch)
{
if (_enabled)
{
switch (_state)
{
case ButtonStates.Up:
if (_upTexture != null)
{
spriteBatch.Draw(_upTexture, _drawRectangle, Color.White);
}
break;
case ButtonStates.MouseOver:
if (_mouseOverTexture != null)
{
spriteBatch.Draw(_mouseOverTexture, _drawRectangle, Color.White);
}
break;
case ButtonStates.MouseDown:
if (_mouseDownTexture != null)
{
spriteBatch.Draw(_mouseDownTexture, _drawRectangle, Color.White);
}
break;
default:
break;
}
}
else
{
if (_disabledTexture != null)
{
spriteBatch.Draw(_disabledTexture, _drawRectangle, Color.White);                   
}
}            
}
 
//Events
public delegate void Click(Button sender);
public event Click OnClick;
 
public enum ButtonStates
{
Up,
MouseOver,
MouseDown
}
}

Thats it! Use OnClick event in the game to tap the click event, call button.Update() in the update logic of the game code.

No comments:

Post a Comment