From 4352634712d00d3f26799e296cdce6ac4e52b83c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mathis=20Rib=C3=A9mont?= Date: Mon, 13 Dec 2021 11:24:35 +0100 Subject: [PATCH] button work with hover --- Pontu/include/engine/Button.h | 40 ++++++++++++++++++----- Pontu/src/engine/Button.c | 32 +++++++++++------- Pontu/test/{testBouton.c => testButton.c} | 32 ++++++++++++++---- 3 files changed, 79 insertions(+), 25 deletions(-) rename Pontu/test/{testBouton.c => testButton.c} (67%) diff --git a/Pontu/include/engine/Button.h b/Pontu/include/engine/Button.h index ad6a67a..1152304 100644 --- a/Pontu/include/engine/Button.h +++ b/Pontu/include/engine/Button.h @@ -1,7 +1,7 @@ /** * \file Button.h * \brief Basic button - * \author Allan Point + * \author Allan Point, Mathis Ribémont * \date 29/11/2021 */ @@ -11,6 +11,8 @@ #include #include +struct P_buttonArg; + /** * \struct P_Button * \brief Represents a button @@ -18,13 +20,27 @@ typedef struct { SDL_Texture* texture; ///> background sprite or texture + SDL_Texture* hoverTexture; ///> texture to draw when the button is hovered SDL_Rect rect; ///> defines coordinates and size for hitbox and display - void (*onClick)(void); ///> action done on click + void (*onClick)(struct P_buttonArg* arg); ///> action done on click + bool drawn; ///> is the button drawn + bool hover; ///> is the button hovered } P_Button; +/** + * \struct P_Button + * \brief Structure of arguments to pass to onClick function + */ +typedef struct P_buttonArg +{ + P_Button* buttonCaller; ///> button who call the one click + SDL_Texture* texture; ///> texture to putt on the button if we want to change his default texture; +} P_ButtonArg; + /** * \brief Creates a brand new button with specs - * \param[in] texture background image for the button (NOT NULL) + * \param[in] texture texture for the button (NOT NULL) + * \param[in] hoverTexture texture for the button when it's hover (can be NULL) * \param[in] coordx placement in width * \param[in] coordy placement in height * \param[in] sizex button's width @@ -33,15 +49,16 @@ typedef struct * \pre At least text or texture must be defined, or an error will be printed in STDERR. * \return a button created with the specs passed as params, or NULL if there was an error. */ -P_Button createButton(SDL_Texture* texture, const int coordx, const int coordy, const int sizex, const int sizey, void (*onClick)(void)); +P_Button createButton(SDL_Texture* texture, SDL_Texture* hoverTexture ,const int coordx, const int coordy, const int sizex, const int sizey, void (*onClick)(P_ButtonArg* arg)); /** - * \brief draw a button on a renderer + * \brief draw a button on a renderer with his texture according if it hover or not * \param[in] renderer the renderer you want to draw the button on * \param[in] button the button you want to draw * \pre At least text or texture must be defined, or an error will be printed in STDERR. + * \return false if the texture is null */ -void drawButtonOnRenderer(SDL_Renderer* renderer, const P_Button* button); +bool drawButtonOnRenderer(SDL_Renderer* renderer, P_Button* button); /** * \brief Test if a point is on a button @@ -50,7 +67,14 @@ void drawButtonOnRenderer(SDL_Renderer* renderer, const P_Button* button); * \param[in] y y of the point * \return SDL_TRUE if the point is on the button */ -SDL_bool isHover(P_Button button, int x,int y);// dit si le bouton est survolé en donnant les coordonnées x,y -//void changeButtonTexture(P_Button* button, const SDL_Texture* texture); +bool isHover(P_Button* button, int x,int y);// dit si le bouton est survolé en donnant les coordonnées x,y + +/** + * \brief Test if a point is on a button + * \param[in] button the button target + * \param[in] texture the texture you want to apply to the button + * \return false if the texture is NULL + */ +bool changeButtonTexture(P_Button* button, SDL_Texture* texture); #endif diff --git a/Pontu/src/engine/Button.c b/Pontu/src/engine/Button.c index 1f8c866..57419cc 100644 --- a/Pontu/src/engine/Button.c +++ b/Pontu/src/engine/Button.c @@ -1,34 +1,44 @@ #include "engine/Button.h" #include #include +#include -P_Button createButton(SDL_Texture* texture, const int coordx, - const int coordy, const int sizex, const int sizey, - void (*onClick)(void)) +P_Button createButton(SDL_Texture* texture, SDL_Texture* hoverTexture ,const int coordx, const int coordy, const int sizex, const int sizey, void (*onClick)(P_ButtonArg* arg)) { // Declarations - P_Button b = { .rect = { .x = coordx, .y = coordy, .w = sizex, .h = sizey }, .onClick = onClick }; + P_Button b = { .rect = { .x = coordx, .y = coordy, .w = sizex, .h = sizey }, .onClick = onClick, .drawn = false}; assert(texture != NULL && "ERROR: Button created without texture"); b.texture = texture; - + b.hoverTexture = hoverTexture; return b; } -void drawButtonOnRenderer(SDL_Renderer* renderer,const P_Button* button) +bool drawButtonOnRenderer(SDL_Renderer* renderer, P_Button* button) { - if(SDL_RenderCopy(renderer,button->texture,NULL,&(button->rect))) + if(SDL_RenderCopy(renderer,button->hover && button->hoverTexture != NULL ? button->hoverTexture : button->texture,NULL,&(button->rect))) { - fprintf(stderr,"Error: %s\n",SDL_GetError()); - exit(1); + fprintf(stderr,"Warning: %s\n",SDL_GetError()); + return false; } + button->drawn = true; } -SDL_bool isHover(const P_Button button,const int x,const int y) +bool isHover(P_Button* button,const int x,const int y) { SDL_Point coord; coord.x = x; coord.y = y; - return SDL_PointInRect(&coord,&(button.rect)); + button->hover = SDL_PointInRect(&coord,&(button->rect)); + return button->hover && button->drawn; +} + +bool changeButtonTexture(P_Button* button, SDL_Texture* texture) +{ + if(texture == NULL){ + fprintf(stderr,"Warning: button texture cannot change to NULL\n"); + return false; + } + button->texture = texture; } diff --git a/Pontu/test/testBouton.c b/Pontu/test/testButton.c similarity index 67% rename from Pontu/test/testBouton.c rename to Pontu/test/testButton.c index 61e7dc2..3feb247 100644 --- a/Pontu/test/testBouton.c +++ b/Pontu/test/testButton.c @@ -4,8 +4,9 @@ //gcc test.c -I ../include $(sdl2-config --cflags --libs) -void action(){ +void action(P_ButtonArg* arg){ printf("Clické\n"); + changeButtonTexture(arg->buttonCaller,arg->texture); } int main(int argc, char const *argv[]) { @@ -61,10 +62,26 @@ int main(int argc, char const *argv[]) { SDL_Texture* buttonTexture = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_RGBA8888,SDL_TEXTUREACCESS_TARGET,20,20); SDL_SetRenderTarget(renderer, buttonTexture); SDL_SetRenderDrawColor(renderer, 255,255,255,255); - SDL_Rect buttonRect = {.x = 0,.y = 0,.w = 20,.h = 20}; + SDL_Rect buttonRect = {.x = 0,.y = 0,.w = 50,.h = 70}; SDL_RenderFillRect(renderer, &buttonRect); - P_Button button = createButton(buttonTexture, 10, 10, 20, 20, &action); + + SDL_Texture* blueTexture = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_RGBA8888,SDL_TEXTUREACCESS_TARGET,20,20); + SDL_SetRenderDrawColor(renderer, 0,0,255,255); + SDL_SetRenderTarget(renderer, blueTexture); + SDL_RenderFillRect(renderer, &buttonRect); + + P_Button button = createButton(buttonTexture,blueTexture ,20, 20, 70, 50, &action); + P_ButtonArg arg; + arg.buttonCaller = &button; + + SDL_Texture* violetTexture = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_RGBA8888,SDL_TEXTUREACCESS_TARGET,20,20); + SDL_SetRenderDrawColor(renderer, 150,75,200,255); + SDL_SetRenderTarget(renderer, violetTexture); + SDL_RenderFillRect(renderer, &buttonRect); + SDL_SetRenderTarget(renderer, NULL); + arg.texture = violetTexture; + button.hoverTexture = blueTexture; while(!quit) { while(SDL_PollEvent(&event)) @@ -75,9 +92,12 @@ int main(int argc, char const *argv[]) { quit = SDL_TRUE; break; case SDL_MOUSEBUTTONUP: - if(isHover(button,event.button.x,event.button.y)) - button.onClick(); - + if(isHover(&button,event.button.x,event.button.y)) + button.onClick(&arg); + break; + case SDL_MOUSEMOTION: + //on vérifie à chaque tour ou est la souris, drawButtonOnRenderer choisit la bonne texture à afficher + isHover(&button,event.motion.x,event.motion.y); break; } }