File: bouton_folco.c - Tab length: 1 2 4 8 - Lines: on off - No wrap: on off

#include "Button.h"
#include "SpritesList.h"
#include "Sdl.h"

bool InitButtonFail (BUTTON* button)
{
    ButtonClose (button);
    return false;
}

bool ButtonInit (BUTTON* button,
                 SDL_Renderer* renderer,
                 char* SprEnabled,
                 char* SprDisabled,
                 char* SprClicked,
                 int x,
                 int y,
                 bool enabled,
                 button_MouseOver over,
                 button_MouseOut out,
                 button_LeftClick leftclick)
{
    bool ret = false;
    // Init pointers in case of failure
    button->SprClicked = NULL;
    button->SprEnabled = NULL;
    button->SprDisabled = NULL;

    // Load sprites
    button->SprEnabled = LoadSprite (SprEnabled, renderer);
    if (button->SprEnabled == NULL)
    {
        ButtonClose (button);
        goto exit;
    }

    if (SprDisabled != NULL) {
        button->SprDisabled = LoadSprite (SprDisabled, renderer);
        if (button->SprDisabled == NULL)
        {
            ButtonClose (button);
            goto exit;
        }
    }

    if (SprClicked != NULL) {
        button->SprClicked = LoadSprite (SprClicked, renderer);
        if (button->SprClicked == NULL)
        {
            ButtonClose (button);
            goto exit;
        }
    }

    // Callbacks
    button->over = over;
    button->out = out;
    button->leftclick = leftclick;

    // Status
    button->status = STATUS_MOUSE_OUT;
    button->enabled = enabled;

    // Location and size
    button->dest.x = x;
    button->dest.y = y;
    SDL_QueryTexture (button->SprEnabled, NULL, NULL, &button->dest.w, &button->dest.h);

    // Default sprite
    button->sprite = enabled ? button->SprEnabled : button->SprDisabled;
    ret = true;

    exit:
    return true;
}

void ButtonClose (BUTTON* button)
{
    if (button->SprEnabled != NULL)
        UnloadSprite (button->SprEnabled);
    if (button->SprDisabled != NULL)
        UnloadSprite (button->SprDisabled);
    if (button->SprClicked != NULL)
        UnloadSprite (button->SprClicked);
}

bool ButtonUpdate (BUTTON* button, SDL_Event* event, int mouse_x, int mouse_y)
{
    bool ret = true;
    if (button->enabled) {
        if ((mouse_x >= button->dest.x) && (mouse_x < button->dest.x + button->dest.w) && (mouse_y >= button->dest.y) &&
            (mouse_y < button->dest.y + button->dest.h)) {
            // The mouse is over the button
            switch (button->status) {
                case STATUS_MOUSE_OUT:
                    button->status = STATUS_MOUSE_OVER;
                    if (button->over != NULL)
                        ret = button->over ();
                    break;

                case STATUS_MOUSE_OVER:
                    if ((event->type == SDL_MOUSEBUTTONDOWN) && (event->button.button == SDL_BUTTON_LEFT)) {
                        button->status = STATUS_CLICK_LEFT_DOWN;
                        button->sprite = button->SprClicked == NULL ? button->SprEnabled : button->SprClicked;
                        break;
                    }
                case STATUS_CLICK_LEFT_DOWN:
                    if ((event->type == SDL_MOUSEBUTTONUP) && (event->button.button == SDL_BUTTON_LEFT)) {
                        button->status = STATUS_CLICK_LEFT_UP;
                        ret = button->leftclick ();
                        button->status = STATUS_MOUSE_OVER;
                        button->sprite = button->SprEnabled;
                        break;
                    }
            }
        } else {
            // The mouse is out of the  button
            if (button->status != STATUS_MOUSE_OUT) {
                // But it was over before
                button->status = STATUS_MOUSE_OUT;
                if (button->out != NULL)
                    ret = button->out ();
            }
        }
    } else { // Button is disabled
        button->status = STATUS_MOUSE_OUT;
        button->sprite = button->SprDisabled == NULL ? button->SprEnabled : button->SprDisabled;
    }
    return ret;
}

bool ButtonDraw (BUTTON* button, SDL_Renderer* renderer)
{
    return SDL_RenderCopy (renderer, button->sprite, NULL, &button->dest) == 0 ? true : false;
}