Tuesday, July 26, 2011

Creating a button with SDL

Mouse Events

The mouse events—mouse motion and mouse button each have their own structures for dealing with the events.


Mouse Motion Events

A mouse motion event is stored in an SDL_MouseMotionEvent, which looks like this.

typedef struct{
Uint8 type;
Uint8 state;
Uint16 x, y;
Sint16 xrel, yrel;
} SDL_MouseMotionEvent;

As with all SDL event structures, the type member specifies what type of event has occurred. In the case of a mouse motion event, this constant will only ever be SDL_MOUSEMOTION.
The state member is a combination of bit flags that tells you which mouse buttons are currently pressed, if any. Table below shows these bit flags.


Mouse Button State Bit Flags

Flag Meaning
SDL_BUTTON_LMASK The left button is currently pressed.
SDL_BUTTON_MMASK The middle button is currently pressed.
SDL_BUTTON_RMASK The right button is currently pressed.

The x and y members of SDL_MouseMotionEvent are (naturally) the x and y position of the mouse. The xrel and yrel members are the relative motion of the mouse since the last event. In some cases, the absolute position of the mouse (x and y) is the most important; other times,
only the relative position (xrel and yrel) is important.


Mouse Button Events

The other two types of mouse-generated events are button presses and button releases. Because they are similar in nature, both of them are stored in an SDL_MouseButtonEvent.

typedef struct{
Uint8 type;
Uint8 button;
Uint8 state;
Uint16 x, y;
} SDL_MouseButtonEvent;

The type member, as always, stores the type of event. In the case of a mouse button event, this value will be SDL_MOUSEBUTTONDOWN or SDL_MOUSEBUTTONUP.
The button member will be one of the following three values—SDL_BUTTON_ LEFT, SDL_BUTTON_MIDDLE, or SDL_BUTTON_RIGHT. The state member tells you whether the button stored in the button member has been pressed or released. The value will be SDL_PRESSED or SDL_RELEASED. Of course, you can get the same information from the
type member. Finally, the x and y members tell you the absolute position of the mouse when the button was pressed.


Using the mouse events, a button is created in the example below:

#include "SDL/SDL.h"
#include "SDL/SDL_image.h"
#include "SDL/SDL_ttf.h"

//Screen attributes
const int SCREEN_WIDTH = 310;
const int SCREEN_HEIGHT = 320;
const int SCREEN_BPP = 32;

//The surfaces
SDL_Surface *background = NULL;
SDL_Surface *button = NULL;
SDL_Surface *message=NULL;
SDL_Surface *screen = NULL;

//The event structure
SDL_Event event;

//The font that's going to be used
TTF_Font *font = NULL;

int mouse_x, mouse_y;
SDL_Rect frame[2];
int pressed=0;

//The color of the font
SDL_Color textColor = { 255, 255, 255 };

void apply_surface(SDL_Surface* source, int x, int y, SDL_Rect* clip )
{
//Holds offsets
SDL_Rect offset;

//Get offsets
offset.x = x;
offset.y = y;

//Blit
SDL_BlitSurface( source, clip, screen, &offset );
}

int button_check(int x)
{
apply_surface(button,20,50,&frame[pressed]);
SDL_Flip(screen);
//if mouse button was pressed
if(event.type == SDL_MOUSEBUTTONDOWN){
//if the left button was pressed
if(event.button.button &SDL_BUTTON_LEFT){
if(mouse_x>20 && mouse_y>50 && mouse_x<30 && mouse_y<60){
pressed=1;
x=1;
}
apply_surface(button,20,50,&frame[pressed]);
SDL_Flip(screen);
}
}
//if mouse was released
if(event.type == SDL_MOUSEBUTTONUP){
if(mouse_x>20 && mouse_y>50 && mouse_x<30 && mouse_y<60){
pressed=0;
x=0;
apply_surface(button,20,50,&frame[pressed]);
SDL_Flip(screen);
}
}
return x;
}

int main(int argc, char* argv[])
{
frame[0].x=0;
frame[0].y=0;
frame[0].w=10;
frame[0].h=10;
frame[1].x=10;
frame[1].y=0;
frame[1].w=10;
frame[1].h=10;
//Quit flag
int quit = 0;
int y=0;
SDL_Init(SDL_INIT_EVERYTHING);
TTF_Init();
//Set up the screen
screen = SDL_SetVideoMode( SCREEN_WIDTH, SCREEN_HEIGHT, SCREEN_BPP, SDL_SWSURFACE );
//Set the window caption
SDL_WM_SetCaption( "BUTTON", NULL );
//Load the background image
background = IMG_Load( "background.png" );
button=IMG_Load("button.png");

//Open the font
font = TTF_OpenFont( "CALIBRI.ttf", 50 );

//Render the text
message = TTF_RenderText_Solid( font, "Hello, World!", textColor );

//While the user hasn't quit
while( quit == 0 )
{
//While there's events to handle
while( SDL_PollEvent( &event ) )
{
//If the user has Xed out the window
if( event.type == SDL_QUIT )
{
//Quit the program
quit = 1;
}
if(event.type==SDL_MOUSEMOTION){
mouse_x=event.motion.x;
mouse_y=event.motion.y;
}
}
apply_surface( background,0,0,0 );
y=button_check(0);
if(y==1)
{
apply_surface( message, 10, 150, 0 );
SDL_Flip( screen );
}
}
//Free the surfaces
SDL_FreeSurface( background );
SDL_FreeSurface( message );

//Close the font that was used
TTF_CloseFont( font );

//Quit SDL_ttf
TTF_Quit();

//Quit SDL
SDL_Quit();
return 0;
}


The source code is available at:

1 comment: