Set dimensions, position & alignment separately

This commit is contained in:
2022-05-19 23:31:53 +02:00
parent 9a6ae2c6d9
commit 3934e4777f
6 changed files with 106 additions and 31 deletions

View File

@ -1,15 +1,19 @@
#include "AMI.h"
#include "App.h"
#include "util.h"
AMI::AMI(SDL_Renderer* renderer)
: View{renderer}, avenir{util::load_font(AVENIR_FONT_PATH, 28)} {
SDL_Rect logo_rect = {.x = 182, .y = 0, .w = 116, .h = 40};
widgets.emplace_back(
std::make_unique<ImageWidget>(renderer, logo_rect, FT_LOGO_PATH));
SDL_Rect choose_rect = {.x = 0, .y = 45, .w = 480, .h = 40};
widgets.emplace_back(std::make_unique<TextWidget>(
renderer, choose_rect, avenir, "Choose a Mission:"));
: View{renderer}, avenir{util::load_font(AVENIR_FONT_PATH, 20)},
ft_logo{renderer, FT_LOGO_PATH}, choose{renderer, avenir,
"Choose a mission:"} {
ft_logo.set_height(40);
ft_logo.set_position(SCREEN_WIDTH / 2, 0);
ft_logo.set_alignment(Alignment::CENTER);
widgets.push_back(&ft_logo);
choose.set_position(SCREEN_WIDTH / 2, 45);
choose.set_alignment(Alignment::CENTER);
widgets.push_back(&choose);
}
void AMI::draw() {

View File

@ -1,3 +1,4 @@
#include "View.h"
View::View(SDL_Renderer* renderer) : renderer{renderer} {}
View::View(SDL_Renderer* renderer) : renderer{renderer} {}
View::~View() {}

View File

@ -7,16 +7,64 @@
#include <stdexcept>
Widget::Widget(SDL_Renderer* renderer, SDL_Rect rect)
: renderer{renderer}, dest_rect{rect} {}
Widget::Widget(SDL_Renderer* renderer) : renderer{renderer}, rect{0, 0, 0, 0} {}
Widget::~Widget() {}
void Widget::update_rect(SDL_Rect new_rect) { dest_rect = new_rect; }
void Widget::set_width(int width, bool preserve_aspect_ratio) {
if (preserve_aspect_ratio) {
float scale = width / rect.w;
rect.h = round(rect.h * scale);
}
rect.w = width;
}
TextureWidget::TextureWidget(SDL_Renderer* renderer, SDL_Rect dest_rect,
void Widget::set_height(int height, bool preserve_aspect_ratio) {
if (preserve_aspect_ratio) {
float scale = ((float)height) / rect.h;
rect.w = round(rect.w * scale);
}
rect.h = height;
}
void Widget::set_position(int x, int y) {
pos.x = x;
pos.y = y;
recalculate_rect();
}
void Widget::set_alignment(Alignment align) {
pos.align = align;
recalculate_rect();
}
void Widget::recalculate_rect() {
int x = pos.x;
int y = pos.y;
switch (pos.align) {
case Alignment::LEFT:
break;
case Alignment::RIGHT:
x -= rect.w;
break;
case Alignment::CENTER:
x -= rect.w / 2;
break;
default:
throw std::runtime_error(
fmt::format("Unknown alignment: {}", (int)pos.align));
}
rect.x = x;
rect.y = y;
}
TextureWidget::TextureWidget(SDL_Renderer* renderer,
std::optional<SDL_Texture*> texture)
: Widget{renderer, dest_rect}, texture{texture} {}
: Widget{renderer}, texture{texture} {
if (texture) {
update_dimensions_from_texture(*texture);
}
}
TextureWidget::~TextureWidget() {
if (texture) {
@ -27,7 +75,7 @@ TextureWidget::~TextureWidget() {
void TextureWidget::draw() {
if (texture) {
SDL_RenderCopy(renderer, *texture, NULL, &dest_rect);
SDL_RenderCopy(renderer, *texture, NULL, &rect);
}
}
@ -35,17 +83,23 @@ void TextureWidget::update_texture(SDL_Texture* new_texture) {
if (texture) {
SDL_DestroyTexture(*texture);
}
update_dimensions_from_texture(new_texture);
texture = new_texture;
}
ImageWidget::ImageWidget(SDL_Renderer* renderer, SDL_Rect dest_rect,
const std::string& path)
: TextureWidget{renderer, dest_rect, util::load_img(renderer, path)} {}
void TextureWidget::update_dimensions_from_texture(SDL_Texture* texture) {
if (SDL_QueryTexture(texture, nullptr, nullptr, &rect.w, &rect.h) != 0) {
throw std::runtime_error(
fmt::format("Couldn't query texture: {}", SDL_GetError()));
}
}
TextWidget::TextWidget(SDL_Renderer* renderer, SDL_Rect dest_rect,
TTF_Font* font, const std::string& initial_text)
: TextureWidget{renderer, dest_rect, std::nullopt}, font{font},
text{initial_text} {
ImageWidget::ImageWidget(SDL_Renderer* renderer, const std::string& path)
: TextureWidget{renderer, util::load_img(renderer, path)} {}
TextWidget::TextWidget(SDL_Renderer* renderer, TTF_Font* font,
const std::string& initial_text)
: TextureWidget{renderer, std::nullopt}, font{font}, text{initial_text} {
if (text != "") {
update_texture(generate_text(text));
}