Page 1 of 1

Button Class Not Drawing

Posted: Sat Jan 09, 2010 5:33 pm
by RandomDever

Code: Select all

class Button
{
public:
	Button( int x, int y, int w, int h, bool fOver, bool fDown );
	bool Check( SDL_Event event, SDL_Surface *buffer );
	void Load( SDL_Surface *image );
private:
	void Draw( int x, int y, SDL_Surface *screen, SDL_Rect clip );
	bool overImage;
	bool downImage;
	SDL_Surface *buttonImage;
	SDL_Surface *currentImage;
	int mouseX;
	int mouseY;
	SDL_Rect button;
	SDL_Rect out;
	SDL_Rect over;
	SDL_Rect down;
	SDL_Rect toggled;
};

Button::Button( int x, int y, int w, int h, bool fOver, bool fDown )
{
	overImage = fOver;
	downImage = fDown;
	button.x = x;
	button.y = y;
	button.w = w;
	button.h = h;
	out.x = 0;
	out.y = 0;
	out.w = w;
	out.h = h;
	if( fOver == true )
	{
		over.x = w + 1;
		over.y = 0;
		over.w = w;
		over.h = h;
	}
	if( fOver == false && fDown == true )
	{
		down.x = w + 1;
		down.y = 0;
		down.w = w;
		down.h = h;
	}
	if( fOver == true && fDown == true )
	{
		down.x = (w * 2) + 1;
		down.y = 0;
		down.w = w;
		down.h = h;
	}
	if( fOver == true && fDown == true )
	{
		toggled.x = (w * 3) + 1;
		toggled.y = 0;
		toggled.w = w;
		toggled.h = h;
	}
	if( fOver == false && fDown == true || fOver == true && fDown == false )
	{
		toggled.x = (w * 2) + 1;
		toggled.y = 0;
		toggled.w = w;
		toggled.h = h;
	}

}

bool Button::Check( SDL_Event event, SDL_Surface *buffer )
{
	SDL_GetMouseState( &mouseX, &mouseY );
	if( mouseX > button.x && mouseX < ( button.x + button.w ) && mouseY < button.y && mouseY > ( button.y + button.h ) )
	{
		if( overImage )
		{
			Draw( button.x, button.y, buffer, over );
		}
		while( event.type == SDL_MOUSEBUTTONDOWN && downImage )
		{
			Draw( button.x, button.y, buffer, down );
		}
		if( mouseX > button.x && mouseX < ( button.x + button.w ) && mouseY < button.y && mouseY > ( button.y + button.h ) )
		{
			Draw( button.x, button.y, buffer, toggled );
			return true;
		}
	}
	else
	{
		Draw( button.x, button.y, buffer, out );
		return false;
	}
}
void Button::Draw( int x, int y, SDL_Surface *screen, SDL_Rect clip )
{
	ApplySurface( x, y, buttonImage, screen, clip );
}
void Button::Load( SDL_Surface *image )
{
	buttonImage = image;
}
I've tried 4 iterations of this code creating and deleting functions but for some reason it just won't fucking draw.
It's so annoying cause I spent like an hour typing this shit up.

Any help would be SERIOUSLY appretiated. :bow:

Re: Button Class Not Drawing

Posted: Sat Jan 09, 2010 6:06 pm
by lotios611
Do you mind posting your ApplySurface() function?

Re: Button Class Not Drawing

Posted: Sat Jan 09, 2010 6:17 pm
by RandomDever
lotios611 wrote:Do you mind posting your ApplySurface() function?
Nope

Code: Select all

void ApplySurface( int x, int y, SDL_Surface* source, SDL_Surface* destination )
{
    //Make a temporary rectangle to hold the offsets
    SDL_Rect offset;

    //Give the offsets to the rectangle
    offset.x = x;
    offset.y = y;

    //Blit the surface
    SDL_BlitSurface( source, NULL, destination, &offset );
}

void ApplySurface( int x, int y, SDL_Surface* source, SDL_Surface* destination, SDL_Rect clip )
{
    //Make a temporary rectangle to hold the offsets
    SDL_Rect offset;

    //Give the offsets to the rectangle
    offset.x = x;
    offset.y = y;

    //Blit the surface
    SDL_BlitSurface( source, &clip, destination, &offset );
}

Re: Button Class Not Drawing

Posted: Sat Jan 09, 2010 6:21 pm
by RyanPridgeon

Code: Select all

void Button::Draw( int x, int y, SDL_Surface *screen, SDL_Rect clip )
{
   ApplySurface( x, y, buttonImage, screen, clip );
...

Code: Select all

void ApplySurface( int x, int y, SDL_Surface* source, SDL_Surface* destination )
{
What?

Re: Button Class Not Drawing

Posted: Sat Jan 09, 2010 9:21 pm
by Bakkon
RyanPridgeon wrote:What?
Scroll down. He has an overload that takes a clipping box.

As for RandomDev's problem, nothing really sticks out to me. You have an odd way of passing your surfaces around. Make sure your images are actually loading and nothing is null.

Re: Button Class Not Drawing

Posted: Sat Jan 09, 2010 10:02 pm
by XianForce
You sure the image was correctly loaded? Try outputting IMG_GetError() to a text file right after you try loading it... if there's an error, then you've found your problem.

Re: Button Class Not Drawing

Posted: Sat Jan 09, 2010 10:30 pm
by dandymcgee
I don't see any obvious errors. Did you try your debugger? Set a breakpoint at the line where you call "applysurface()", and watch what values are being passed.

Re: Button Class Not Drawing

Posted: Sun Jan 10, 2010 2:23 pm
by RandomDever

Code: Select all

class Button
{
public:
	Button( int x, int y, int w, int h, bool fOver, bool fDown );
	bool Check( SDL_Event event );
	void Load( SDL_Surface *image );
	SDL_Rect nextClip;
private:
	bool overImage;
	bool downImage;
	bool isToggled;
	SDL_Surface *buttonImage;
	SDL_Surface *currentImage;
	int mouseX;
	int mouseY;
	SDL_Rect button;
	SDL_Rect out;
	SDL_Rect over;
	SDL_Rect down;
	SDL_Rect toggled;
};

Button::Button( int x, int y, int w, int h, bool fOver, bool fDown )
{
	isToggled = false;
	overImage = fOver;
	downImage = fDown;
	button.x = x;
	button.y = y;
	button.w = w;
	button.h = h;
	out.x = 0;
	out.y = 0;
	out.w = w;
	out.h = h;
	if( fOver == true )
	{
		over.x = w + 1;
		over.y = 0;
		over.w = w;
		over.h = h;
	}
	if( fOver == false && fDown == true )
	{
		down.x = w + 1;
		down.y = 0;
		down.w = w;
		down.h = h;
	}
	if( fOver == true && fDown == true )
	{
		down.x = (w * 2) + 1;
		down.y = 0;
		down.w = w;
		down.h = h;
	}
	if( fOver == true && fDown == true )
	{
		toggled.x = (w * 3) + 1;
		toggled.y = 0;
		toggled.w = w;
		toggled.h = h;
	}
	if( fOver == false && fDown == true || fOver == true && fDown == false )
	{
		toggled.x = (w * 2) + 1;
		toggled.y = 0;
		toggled.w = w;
		toggled.h = h;
	}

}

bool Button::Check( SDL_Event event )
{

	SDL_GetMouseState( &mouseX, &mouseY );
	if( !isToggled )
	{
		if( mouseX > button.x && mouseX < ( button.x + button.w ) && mouseY > button.y && mouseY < ( button.y + button.h ) )
		{
			if( overImage )
			{
				nextClip = over;
			}
			if( event.type == SDL_MOUSEBUTTONDOWN && downImage )
			{
				if( event.button.button == SDL_BUTTON_LEFT )
				{
					nextClip = down;
				}
			}
			if( event.type == SDL_MOUSEBUTTONUP )
			{
				if( event.button.button == SDL_BUTTON_LEFT )
				{
					nextClip = toggled;
					isToggled = true;
				}
			}
		}
		else
		{
			nextClip = out;
		}
	}
	return isToggled;
}
void Button::Load( SDL_Surface *image )
{
	buttonImage = image;
}
This works if you apply the surface at run-time using the nextClip rectangle for the clip.
But you have to put check in the main game loop or it won't draw.
Check returns isToggled so you just say:
if( myButton.Check( event ) )
{
SDL_Quit(); // or
stateManager.NextState();
}
So here's a free button class.