Jump to content

  • Log In with Google      Sign In   
  • Create Account

c++ SDL Button class


Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.

  • You cannot reply to this topic
2 replies to this topic

#1 stoffe1100   Members   -  Reputation: 105

Like
0Likes
Like

Posted 02 April 2012 - 06:03 PM

Hello! Im new at SDL. I´m doing small experiments like what i was trying to do now when i got a stuck on a problem. I have made a button class called NewButton that got a bool function called CheckEvents that is supposed to return true if left mouse button was pressed while the mouse arrow is inside the "ButtonRect". It compiles fine and i can see my button on the screen. But nothing happends when i press it.

I know the code is not completely object oriented but that is not what i am focusing on now

And by the way, if you find any other things that i should have i mind please tell me, i wanna learn as much as possible Posted Image

And another question while i'm anyway starting a thread. Do i really have to pass in the screen surface to the button. Are there no way to make the screen variable global somehow. Seems dumb to do it this way.

I have been sitting up half night now only looking at this....

Thanks in advance!



Here is the main.cpp

#include <sdl.h>
#include <string>
#include "NewButton.h"
SDL_Event event;
bool running = true;
SDL_Surface * screen = SDL_SetVideoMode(800,600,32,SDL_HWSURFACE|SDL_DOUBLEBUF);

int main(int argc, char * args[]){
SDL_Surface * Image = SDL_LoadBMP("TestKnapp.BMP");
Image = SDL_DisplayFormat(Image);
NewButton ExitButton(400,300,100,50,Image,screen);
while(running){
  if(SDL_PollEvent(&event)){
  
   if(event.type == SDL_QUIT){running = false; SDL_Quit(); break;}
   if(event.type == SDL_KEYDOWN){
	if(event.key.keysym.sym == SDLK_ESCAPE){running = false; SDL_Quit(); break;}
   }
   if(ExitButton.CheckEvents()){
	running = false;
	SDL_Quit();
	break;
   }
  }
  ExitButton.DrawToScreen();
  SDL_Flip(screen);
}
return 0;
}

Here is NewButton.h

#pragma once
#ifndef newbutton
#define newbutton
#include <SDL.h>
#include <string>
using namespace std;

class NewButton
{
public:
NewButton(int x,int y, int w, int h,SDL_Surface * Image,SDL_Surface * screen);
void DrawToScreen();
bool CheckEvents();

private:
SDL_Surface * LocalScreen;
SDL_Surface * ButtonImage;
SDL_Rect ButtonRect;
SDL_Event event;
int MouseX,MouseY;
};

#endif

Here is NewButton.cpp

#include "NewButton.h"
#include <SDL.h>
#include <string>
using namespace std;
NewButton::NewButton(int x,int y, int w, int h,SDL_Surface * Image,SDL_Surface * screen):
LocalScreen(screen),
MouseX(0),
MouseY(0)
{
ButtonImage = Image;
ButtonRect.x = x;
ButtonRect.y = y;
ButtonRect.w = w;
ButtonRect.h = h;
}
void NewButton::DrawToScreen(){
SDL_BlitSurface(ButtonImage,NULL,LocalScreen,&ButtonRect);
}
bool NewButton::CheckEvents(){
if(SDL_PollEvent(&event)){
  if(event.type == SDL_MOUSEBUTTONDOWN){
   if(event.button.button == SDL_BUTTON_LEFT){
	MouseX = event.button.x;
	MouseY = event.button.y;
	if((MouseX > ButtonRect.x) && (MouseY > ButtonRect.y) && (MouseX < (ButtonRect.x + ButtonRect.w)) && (MouseY < (ButtonRect.y + ButtonRect.h))){
	 return true;
	}
   }
  }
}


return false;
}


Sponsor:

#2 JustinDaniel   Members   -  Reputation: 137

Like
3Likes
Like

Posted 02 April 2012 - 08:56 PM

The problem is, the event is not processing properly, You need to check when the user clicks the button and quickly respond to it.

Probably write a function to wrap the mouse intersecting and then check if the button is being pressed and if the mouse is on top of whatever object.
bool IsOnTop(int objectX, int objectY, int objectW, int objectH, int mouseX, int mouseY )
{
	if( mouseX < objectX || mouseY < objectY )
	{
		return false;
	}
	if( mouseX > objectX+objectW || mouseY > objectY+objectH )
	{
		return false;
	}

	return true;
}

//Then while handling events..
//Store a variable for the SDL_BUTTON_LEFT key

const Uint8 Button = SDL_BUTTON_LEFT;

//While handling events
if(event.type == SDL_MOUSEBUTTONDOWN )
	{
   	 if( (event.button.button &Button) == Button && intersects(Buttonrect.x, Buttonrect.y, Buttonrect.w, Buttonheight.h, event.button.x, event.button.y))
   	 {
	   	 return true; //Do the things you want when the mouse is clicked here.
   	 }
	}
}

And another question while i'm anyway starting a thread. Do i really have to pass in the screen surface to the button. Are there no way to make the screen variable global somehow. Seems dumb to do it this way

There is one way.
You could pass
SDL_GetVideoSurface();

In the place of SDL_Surface* destination or whatever without making the screen variable a global one

SDL_GetVideoSurface() returns a pointer to the current screen, i.e the main screen you set is returned as a pointer by the SDL_GetVideoSurface()

#3 spooderw   Members   -  Reputation: 123

Like
0Likes
Like

Posted 02 April 2012 - 09:00 PM

if(SDL_PollEvent(&event)){

   if(event.type == SDL_QUIT){running = false; SDL_Quit(); break;}
   if(event.type == SDL_KEYDOWN){
		if(event.key.keysym.sym == SDLK_ESCAPE){running = false; SDL_Quit(); break;}
   }
   if(ExitButton.CheckEvents()){
		running = false;
		SDL_Quit();
		break;
   }


If I am correct, this should be contained in a while loop, because if more than one event occurs in a single iteration of your game loop, you will only catch one of the events, which will not only result in missed input, but I believe it leaks memory and causes major slowdown.


Also, you should not have another event handler inside your button, you should pass in a bool that checks if the mouse is pressed.

It should be something like this:

main.cpp:
bool leftClick = false;
while(SDL_PollEvent(&event)){

   if(event.type == SDL_QUIT){running = false; SDL_Quit(); break;}
   if(event.type == SDL_KEYDOWN){
		if(event.key.keysym.sym == SDLK_ESCAPE){running = false; SDL_Quit(); break;}
	if(event.type == SDL_MOUSEBUTTONDOWN){
		 if(event.button.button == SDL_BUTTON_LEFT){
		  leftClick = true;}
	  if(event.type == SDL_MOUSEBUTTONUP){
		 if(event.button.button == SDL_BUTTON_LEFT){
		  leftClick = false;}
}
   if(ExitButton.CheckEvents(leftClick)){
		running = false;
		SDL_Quit();
		break;
   }


newbutton.cpp:
bool NewButton::CheckEvents(bool leftMousePressed){
	 if(leftMousePressed)
	 {
		if((MouseX > ButtonRect.x) && (MouseY > ButtonRect.y) && (MouseX < (ButtonRect.x + ButtonRect.w)) && (MouseY < (ButtonRect.y + ButtonRect.h))){
		 return true;
		}
	 }
   }
  }
}





Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.



PARTNERS