[e1f88a9] | 1 | #include "button.hpp"
|
---|
| 2 |
|
---|
| 3 | #include <SDL2/SDL_ttf.h>
|
---|
[aa7707d] | 4 | // #include <SDL2/SDL2_gfxPrimitives.h>
|
---|
[e1f88a9] | 5 |
|
---|
| 6 | #include "../vulkan-game.hpp"
|
---|
| 7 |
|
---|
| 8 | // TODO: Figure out a good way to return errors instead of just printing them
|
---|
| 9 | // Probably throw an exception
|
---|
| 10 | // Make sure to cleanup anythign that was initialized correctly before the error
|
---|
| 11 | // TODO: Support better positioning options (e.g. align to left, right, top, bottom, center,
|
---|
| 12 | // and offsets from those positions)
|
---|
| 13 | Button::Button(string label, int x, int y, int padding, uint32_t color, uint32_t textColor,
|
---|
| 14 | VulkanGame& gameInfo, SDL_Renderer& renderer,
|
---|
| 15 | void (*onMouseClick)(VulkanGame& gameInfo),
|
---|
| 16 | void (*onMouseEnter)(UIElement& element),
|
---|
| 17 | void (*onMouseLeave)(UIElement& element)) :
|
---|
| 18 | UIElement(x, y, 0, 0, renderer, onMouseClick, onMouseEnter, onMouseLeave),
|
---|
| 19 | color(color),
|
---|
| 20 | focused(false),
|
---|
| 21 | gameInfo(gameInfo) {
|
---|
| 22 |
|
---|
| 23 | SDL_Color sdlTextColor {
|
---|
| 24 | static_cast<Uint8>((textColor >> 24) & 0xFF),
|
---|
| 25 | static_cast<Uint8>((textColor >> 16) & 0xFF),
|
---|
| 26 | static_cast<Uint8>((textColor >> 8) & 0xFF),
|
---|
| 27 | static_cast<Uint8>(textColor & 0xFF)
|
---|
| 28 | };
|
---|
| 29 |
|
---|
| 30 | SDL_Surface* labelSurface = TTF_RenderText_Blended(this->gameInfo.proggyFont, label.c_str(),
|
---|
| 31 | sdlTextColor);
|
---|
| 32 | if (labelSurface == nullptr) {
|
---|
| 33 | cout << "Unable to render text surface! SDL_ttf Error: " << TTF_GetError() << endl;
|
---|
| 34 | }
|
---|
| 35 |
|
---|
| 36 | this->labelTexture = SDL_CreateTextureFromSurface(&this->renderer, labelSurface);
|
---|
| 37 | if (this->labelTexture == nullptr) {
|
---|
| 38 | cout << "Unable to create texture from rendered text! SDL Error: " << SDL_GetError() << endl;
|
---|
| 39 | // SDL_FreeSurface(labelSurface);
|
---|
| 40 | }
|
---|
| 41 |
|
---|
| 42 | SDL_FreeSurface(labelSurface);
|
---|
| 43 |
|
---|
| 44 | TTF_SizeText(this->gameInfo.proggyFont, label.c_str(), &this->labelWidth, &this->labelHeight);
|
---|
| 45 |
|
---|
| 46 | this->width = this->labelWidth + padding;
|
---|
| 47 | this->height = this->labelHeight + padding;
|
---|
| 48 |
|
---|
| 49 | uint32_t rgb = color & 0xFFFFFF00;
|
---|
| 50 | uint32_t a = color & 0xFF;
|
---|
| 51 |
|
---|
| 52 | this->focusColor = (int)(rgb * 1.6) | a;
|
---|
| 53 | }
|
---|
| 54 |
|
---|
| 55 | Button::~Button() {
|
---|
| 56 | if (this->labelTexture != nullptr) {
|
---|
| 57 | SDL_DestroyTexture(this->labelTexture);
|
---|
| 58 | this->labelTexture = nullptr;
|
---|
| 59 | }
|
---|
| 60 | }
|
---|
| 61 |
|
---|
| 62 | void Button::init() {
|
---|
| 63 | this->focused = false;
|
---|
| 64 | }
|
---|
| 65 |
|
---|
| 66 | void Button::render(int x, int y) {
|
---|
| 67 | uint32_t cur_color = this->focused ? this->focusColor : this->color;
|
---|
| 68 |
|
---|
| 69 | uint8_t colorR = (cur_color >> 24) & 0xFF;
|
---|
| 70 | uint8_t colorG = (cur_color >> 16) & 0xFF;
|
---|
| 71 | uint8_t colorB = (cur_color >> 8) & 0xFF;
|
---|
| 72 | uint8_t colorA = cur_color & 0xFF;
|
---|
| 73 |
|
---|
[aa7707d] | 74 | /*
|
---|
[e1f88a9] | 75 | boxRGBA(&this->renderer, this->x + x, this->y + y, this->x + this->width, this->y + this->height,
|
---|
| 76 | colorR, colorG, colorB, colorA);
|
---|
[aa7707d] | 77 | */
|
---|
[e1f88a9] | 78 |
|
---|
| 79 | SDL_Rect rect = {
|
---|
| 80 | this->x + (this->width - this->labelWidth) / 2 + x,
|
---|
| 81 | this->y + (this->height - this->labelHeight) / 2 + y,
|
---|
| 82 | this->labelWidth,
|
---|
| 83 | this->labelHeight
|
---|
| 84 | };
|
---|
| 85 |
|
---|
| 86 | SDL_RenderCopy(&this->renderer, this->labelTexture, nullptr, &rect);
|
---|
| 87 | }
|
---|
| 88 |
|
---|
| 89 | void Button::handleEvent(UIEvent& e) {
|
---|
| 90 | switch(e.type) {
|
---|
| 91 | case UI_EVENT_MOUSEMOTION:
|
---|
| 92 | if (this->x < e.mouse.x && e.mouse.x < this->x + this->width &&
|
---|
| 93 | this->y < e.mouse.y && e.mouse.y < this->y + this->height) {
|
---|
| 94 | if (!this->focused) {
|
---|
| 95 | this->focused = true;
|
---|
| 96 | if (this->onMouseEnter != nullptr) {
|
---|
| 97 | this->onMouseEnter(*this);
|
---|
| 98 | }
|
---|
| 99 | }
|
---|
| 100 | } else if (this->focused) {
|
---|
| 101 | this->focused = false;
|
---|
| 102 | if (this->onMouseLeave != nullptr) {
|
---|
| 103 | this->onMouseLeave(*this);
|
---|
| 104 | }
|
---|
| 105 | }
|
---|
| 106 | break;
|
---|
| 107 | case UI_EVENT_MOUSEBUTTONDOWN:
|
---|
| 108 | break;
|
---|
| 109 | case UI_EVENT_MOUSEBUTTONUP:
|
---|
| 110 | if (this->x < e.mouse.x && e.mouse.x < this->x + this->width &&
|
---|
| 111 | this->y < e.mouse.y && e.mouse.y < this->y + this->height) {
|
---|
| 112 | if (this->onMouseClick != nullptr) {
|
---|
| 113 | this->onMouseClick(this->gameInfo);
|
---|
| 114 | }
|
---|
| 115 | }
|
---|
| 116 | break;
|
---|
| 117 | default:
|
---|
| 118 | //cout << "Unhandled UI event: " << e.type << endl;
|
---|
| 119 | break;
|
---|
| 120 | }
|
---|
| 121 | }
|
---|