123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312 |
- #include "Button.hxx"
- #include "../AssetManager.hxx"
- #include "../../SDLRenderer.hxx"
- #include <cassert>
- namespace {
- SDL_Rect const UPPER_LEFT{
- .x = 0,
- .y = 0,
- .w = 6,
- .h = 5,
- };
- SDL_Rect const UPPER_EDGE{
- .x = 6,
- .y = 0,
- .w = 37,
- .h = 5,
- };
- SDL_Rect const UPPER_RIGHT{
- .x = 43,
- .y = 0,
- .w = 6,
- .h = 5,
- };
- SDL_Rect const LEFT_EDGE{
- .x = 0,
- .y = 5,
- .w = 6,
- .h = 35,
- };
- SDL_Rect const CENTER{
- .x = 6,
- .y = 5,
- .w = 37,
- .h = 35,
- };
- SDL_Rect const RIGHT_EDGE{
- .x = 43,
- .y = 5,
- .w = 6,
- .h = 35,
- };
- SDL_Rect const LOWER_LEFT_UP{
- .x = 0,
- .y = 40,
- .w = 6,
- .h = 9,
- };
- SDL_Rect const LOWER_EDGE_UP{
- .x = 6,
- .y = 40,
- .w = 37,
- .h = 9,
- };
- SDL_Rect const LOWER_RIGHT_UP{
- .x = 43,
- .y = 40,
- .w = 6,
- .h = 9,
- };
- SDL_Rect const LOWER_LEFT_DOWN{
- .x = 0,
- .y = 40,
- .w = 6,
- .h = 5,
- };
- SDL_Rect const LOWER_EDGE_DOWN{
- .x = 6,
- .y = 40,
- .w = 37,
- .h = 5,
- };
- SDL_Rect const LOWER_RIGHT_DOWN{
- .x = 43,
- .y = 40,
- .w = 6,
- .h = 5,
- };
- SDL_Rect calculate_text_rect(SDL_Rect const& area, SDL_Texture* texture)
- {
- int text_w, text_h;
- SDL_QueryTexture(texture, nullptr, nullptr, &text_w, &text_h);
- float const text_aspect = static_cast<float>(text_w)/static_cast<float>(text_h);
- float const area_aspect = static_cast<float>(area.w)/static_cast<float>(area.h);
- int put_w, put_h;
- if (text_aspect>area_aspect) {
- put_w = area.w;
- put_h = static_cast<int>(static_cast<float>(put_w)/text_aspect);
- }
- else {
- put_h = area.h;
- put_w = static_cast<int>(static_cast<float>(put_h)*text_aspect);
- }
- return {
- .x = area.x+(area.w-put_w)/2,
- .y = area.y+(area.h-put_h)/2,
- .w = put_w,
- .h = put_h,
- };
- }
- }
- Button::Button(std::string title, int x, int y, int w, int h)
- :title_{std::move(title)}, x_{x}, y_{y}, w_{w}, h_{h}, pressed_{false}
- {
- assert(w_>=12);
- assert(h_>=14);
- up_ = std::async(std::launch::deferred, [] {
- return AssetManager::instance().get_texture_asset("blue_button_up.png");
- });
- down_ = std::async(std::launch::deferred, [] {
- return AssetManager::instance().get_texture_asset("blue_button_down.png");
- });
- font_ = std::async(std::launch::deferred, [] {
- return AssetManager::instance().get_font_asset("kenvector_future.ttf");
- });
- }
- void Button::set_pressed(bool const pressed)
- {
- pressed_ = pressed;
- }
- bool Button::is_pressed() const
- {
- return pressed_;
- }
- void Button::render(SDLRenderer& renderer)
- {
- auto const text = TTF_RenderUTF8_Solid(font_.get(), title_.c_str(), {0, 0, 0, SDL_ALPHA_OPAQUE});
- auto const text_ure = SDL_CreateTextureFromSurface(renderer, text);
- SDL_FreeSurface(text);
- if (pressed_) {
- auto const down = down_.get();
- SDL_Rect const upper_left{
- .x = x_,
- .y = y_+4,
- .w = 6,
- .h = 5,
- };
- SDL_RenderCopy(renderer, down, &::UPPER_LEFT, &upper_left);
- SDL_Rect const upper_edge{
- .x = x_+6,
- .y = y_+4,
- .w = w_-12,
- .h = 5,
- };
- SDL_RenderCopy(renderer, down, &::UPPER_EDGE, &upper_edge);
- SDL_Rect const upper_right{
- .x = x_+w_-6,
- .y = y_+4,
- .w = 6,
- .h = 5,
- };
- SDL_RenderCopy(renderer, down, &::UPPER_RIGHT, &upper_right);
- SDL_Rect const left_edge{
- .x = x_,
- .y = y_+9,
- .w = 6,
- .h = h_-14,
- };
- SDL_RenderCopy(renderer, down, &::LEFT_EDGE, &left_edge);
- SDL_Rect const center{
- .x = x_+6,
- .y = y_+9,
- .w = w_-12,
- .h = h_-14,
- };
- SDL_RenderCopy(renderer, down, &::CENTER, ¢er);
- SDL_Rect const text_rect = ::calculate_text_rect(center, text_ure);
- SDL_RenderCopy(renderer, text_ure, nullptr, &text_rect);
- SDL_Rect const right_edge{
- .x = x_+w_-6,
- .y = y_+9,
- .w = 6,
- .h = h_-14,
- };
- SDL_RenderCopy(renderer, down, &::RIGHT_EDGE, &right_edge);
- SDL_Rect const lower_left{
- .x = x_,
- .y = y_+h_-5,
- .w = 6,
- .h = 5,
- };
- SDL_RenderCopy(renderer, down, &::LOWER_LEFT_DOWN, &lower_left);
- SDL_Rect const lower_edge{
- .x = x_+6,
- .y = y_+h_-5,
- .w = w_-12,
- .h = 5,
- };
- SDL_RenderCopy(renderer, down, &::LOWER_EDGE_DOWN, &lower_edge);
- SDL_Rect const lower_right{
- .x = x_+w_-6,
- .y = y_+h_-5,
- .w = 6,
- .h = 5,
- };
- SDL_RenderCopy(renderer, down, &::LOWER_RIGHT_DOWN, &lower_right);
- }
- else {
- auto const up = up_.get();
- SDL_Rect const upper_left{
- .x = x_,
- .y = y_,
- .w = 6,
- .h = 5,
- };
- SDL_RenderCopy(renderer, up, &::UPPER_LEFT, &upper_left);
- SDL_Rect const upper_edge{
- .x = x_+6,
- .y = y_,
- .w = w_-12,
- .h = 5,
- };
- SDL_RenderCopy(renderer, up, &::UPPER_EDGE, &upper_edge);
- SDL_Rect const upper_right{
- .x = x_+w_-6,
- .y = y_,
- .w = 6,
- .h = 5,
- };
- SDL_RenderCopy(renderer, up, &::UPPER_RIGHT, &upper_right);
- SDL_Rect const left_edge{
- .x = x_,
- .y = y_+5,
- .w = 6,
- .h = h_-14,
- };
- SDL_RenderCopy(renderer, up, &::LEFT_EDGE, &left_edge);
- SDL_Rect const center{
- .x = x_+6,
- .y = y_+5,
- .w = w_-12,
- .h = h_-14,
- };
- SDL_RenderCopy(renderer, up, &::CENTER, ¢er);
- SDL_Rect const text_rect = ::calculate_text_rect(center, text_ure);
- SDL_RenderCopy(renderer, text_ure, nullptr, &text_rect);
- SDL_Rect const right_edge{
- .x = x_+w_-6,
- .y = y_+5,
- .w = 6,
- .h = h_-14,
- };
- SDL_RenderCopy(renderer, up, &::RIGHT_EDGE, &right_edge);
- SDL_Rect const lower_left{
- .x = x_,
- .y = y_+h_-9,
- .w = 6,
- .h = 9,
- };
- SDL_RenderCopy(renderer, up, &::LOWER_LEFT_UP, &lower_left);
- SDL_Rect const lower_edge{
- .x = x_+6,
- .y = y_+h_-9,
- .w = w_-12,
- .h = 9,
- };
- SDL_RenderCopy(renderer, up, &::LOWER_EDGE_UP, &lower_edge);
- SDL_Rect const lower_right{
- .x = x_+w_-6,
- .y = y_+h_-9,
- .w = 6,
- .h = 9,
- };
- SDL_RenderCopy(renderer, up, &::LOWER_RIGHT_UP, &lower_right);
- }
- SDL_DestroyTexture(text_ure);
- }
|