Set dimensions, position & alignment separately
This commit is contained in:
parent
9a6ae2c6d9
commit
3934e4777f
@ -11,7 +11,7 @@
|
|||||||
constexpr const char* FT_LOGO_PATH = "resources/Fasttube_Logo-white.bmp";
|
constexpr const char* FT_LOGO_PATH = "resources/Fasttube_Logo-white.bmp";
|
||||||
constexpr const char* AVENIR_FONT_PATH = "resources/Avenir-Book.ttf";
|
constexpr const char* AVENIR_FONT_PATH = "resources/Avenir-Book.ttf";
|
||||||
|
|
||||||
class AMI : public View {
|
class AMI final : public View {
|
||||||
public:
|
public:
|
||||||
AMI(SDL_Renderer* renderer);
|
AMI(SDL_Renderer* renderer);
|
||||||
|
|
||||||
@ -20,5 +20,8 @@ public:
|
|||||||
private:
|
private:
|
||||||
TTF_Font* avenir;
|
TTF_Font* avenir;
|
||||||
|
|
||||||
std::vector<std::unique_ptr<Widget>> widgets;
|
std::vector<Widget*> widgets;
|
||||||
|
|
||||||
|
ImageWidget ft_logo;
|
||||||
|
TextWidget choose;
|
||||||
};
|
};
|
@ -5,6 +5,7 @@
|
|||||||
class View {
|
class View {
|
||||||
public:
|
public:
|
||||||
View(SDL_Renderer* renderer);
|
View(SDL_Renderer* renderer);
|
||||||
|
virtual ~View();
|
||||||
|
|
||||||
virtual void draw() = 0;
|
virtual void draw() = 0;
|
||||||
|
|
||||||
|
@ -6,24 +6,36 @@
|
|||||||
#include <optional>
|
#include <optional>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
|
enum class Alignment { LEFT, RIGHT, CENTER };
|
||||||
|
struct PositionInfo {
|
||||||
|
int x;
|
||||||
|
int y;
|
||||||
|
Alignment align;
|
||||||
|
};
|
||||||
|
|
||||||
class Widget {
|
class Widget {
|
||||||
public:
|
public:
|
||||||
Widget(SDL_Renderer* renderer, SDL_Rect dest_rect);
|
Widget(SDL_Renderer* renderer);
|
||||||
virtual ~Widget();
|
virtual ~Widget();
|
||||||
|
|
||||||
virtual void update_rect(SDL_Rect new_rect);
|
virtual void set_width(int width, bool preserve_aspect_ratio = true);
|
||||||
|
virtual void set_height(int height, bool preserve_aspect_ratio = true);
|
||||||
|
virtual void set_position(int x, int y);
|
||||||
|
virtual void set_alignment(Alignment align);
|
||||||
|
|
||||||
virtual void draw() = 0;
|
virtual void draw() = 0;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
void recalculate_rect();
|
||||||
|
|
||||||
SDL_Renderer* renderer;
|
SDL_Renderer* renderer;
|
||||||
SDL_Rect dest_rect;
|
SDL_Rect rect;
|
||||||
|
PositionInfo pos;
|
||||||
};
|
};
|
||||||
|
|
||||||
class TextureWidget : public Widget {
|
class TextureWidget : public Widget {
|
||||||
public:
|
public:
|
||||||
TextureWidget(SDL_Renderer* renderer, SDL_Rect dest_rect,
|
TextureWidget(SDL_Renderer* renderer, std::optional<SDL_Texture*> texture);
|
||||||
std::optional<SDL_Texture*> texture);
|
|
||||||
~TextureWidget();
|
~TextureWidget();
|
||||||
|
|
||||||
virtual void draw() override;
|
virtual void draw() override;
|
||||||
@ -31,18 +43,18 @@ public:
|
|||||||
void update_texture(SDL_Texture* new_texture);
|
void update_texture(SDL_Texture* new_texture);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
void update_dimensions_from_texture(SDL_Texture* texture);
|
||||||
std::optional<SDL_Texture*> texture;
|
std::optional<SDL_Texture*> texture;
|
||||||
};
|
};
|
||||||
|
|
||||||
class ImageWidget : public TextureWidget {
|
class ImageWidget : public TextureWidget {
|
||||||
public:
|
public:
|
||||||
ImageWidget(SDL_Renderer* renderer, SDL_Rect dest_rect,
|
ImageWidget(SDL_Renderer* renderer, const std::string& path);
|
||||||
const std::string& path);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class TextWidget : public TextureWidget {
|
class TextWidget : public TextureWidget {
|
||||||
public:
|
public:
|
||||||
TextWidget(SDL_Renderer* renderer, SDL_Rect dest_rect, TTF_Font* font,
|
TextWidget(SDL_Renderer* renderer, TTF_Font* font,
|
||||||
const std::string& initial_text = "");
|
const std::string& initial_text = "");
|
||||||
~TextWidget();
|
~TextWidget();
|
||||||
|
|
||||||
|
18
src/AMI.cpp
18
src/AMI.cpp
@ -1,15 +1,19 @@
|
|||||||
#include "AMI.h"
|
#include "AMI.h"
|
||||||
|
|
||||||
|
#include "App.h"
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
|
|
||||||
AMI::AMI(SDL_Renderer* renderer)
|
AMI::AMI(SDL_Renderer* renderer)
|
||||||
: View{renderer}, avenir{util::load_font(AVENIR_FONT_PATH, 28)} {
|
: View{renderer}, avenir{util::load_font(AVENIR_FONT_PATH, 20)},
|
||||||
SDL_Rect logo_rect = {.x = 182, .y = 0, .w = 116, .h = 40};
|
ft_logo{renderer, FT_LOGO_PATH}, choose{renderer, avenir,
|
||||||
widgets.emplace_back(
|
"Choose a mission:"} {
|
||||||
std::make_unique<ImageWidget>(renderer, logo_rect, FT_LOGO_PATH));
|
ft_logo.set_height(40);
|
||||||
SDL_Rect choose_rect = {.x = 0, .y = 45, .w = 480, .h = 40};
|
ft_logo.set_position(SCREEN_WIDTH / 2, 0);
|
||||||
widgets.emplace_back(std::make_unique<TextWidget>(
|
ft_logo.set_alignment(Alignment::CENTER);
|
||||||
renderer, choose_rect, avenir, "Choose a Mission:"));
|
widgets.push_back(&ft_logo);
|
||||||
|
choose.set_position(SCREEN_WIDTH / 2, 45);
|
||||||
|
choose.set_alignment(Alignment::CENTER);
|
||||||
|
widgets.push_back(&choose);
|
||||||
}
|
}
|
||||||
|
|
||||||
void AMI::draw() {
|
void AMI::draw() {
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
#include "View.h"
|
#include "View.h"
|
||||||
|
|
||||||
View::View(SDL_Renderer* renderer) : renderer{renderer} {}
|
View::View(SDL_Renderer* renderer) : renderer{renderer} {}
|
||||||
|
View::~View() {}
|
@ -7,16 +7,64 @@
|
|||||||
|
|
||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
|
|
||||||
Widget::Widget(SDL_Renderer* renderer, SDL_Rect rect)
|
Widget::Widget(SDL_Renderer* renderer) : renderer{renderer}, rect{0, 0, 0, 0} {}
|
||||||
: renderer{renderer}, dest_rect{rect} {}
|
|
||||||
|
|
||||||
Widget::~Widget() {}
|
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)
|
std::optional<SDL_Texture*> texture)
|
||||||
: Widget{renderer, dest_rect}, texture{texture} {}
|
: Widget{renderer}, texture{texture} {
|
||||||
|
if (texture) {
|
||||||
|
update_dimensions_from_texture(*texture);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
TextureWidget::~TextureWidget() {
|
TextureWidget::~TextureWidget() {
|
||||||
if (texture) {
|
if (texture) {
|
||||||
@ -27,7 +75,7 @@ TextureWidget::~TextureWidget() {
|
|||||||
|
|
||||||
void TextureWidget::draw() {
|
void TextureWidget::draw() {
|
||||||
if (texture) {
|
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) {
|
if (texture) {
|
||||||
SDL_DestroyTexture(*texture);
|
SDL_DestroyTexture(*texture);
|
||||||
}
|
}
|
||||||
|
update_dimensions_from_texture(new_texture);
|
||||||
texture = new_texture;
|
texture = new_texture;
|
||||||
}
|
}
|
||||||
|
|
||||||
ImageWidget::ImageWidget(SDL_Renderer* renderer, SDL_Rect dest_rect,
|
void TextureWidget::update_dimensions_from_texture(SDL_Texture* texture) {
|
||||||
const std::string& path)
|
if (SDL_QueryTexture(texture, nullptr, nullptr, &rect.w, &rect.h) != 0) {
|
||||||
: TextureWidget{renderer, dest_rect, util::load_img(renderer, path)} {}
|
throw std::runtime_error(
|
||||||
|
fmt::format("Couldn't query texture: {}", SDL_GetError()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
TextWidget::TextWidget(SDL_Renderer* renderer, SDL_Rect dest_rect,
|
ImageWidget::ImageWidget(SDL_Renderer* renderer, const std::string& path)
|
||||||
TTF_Font* font, const std::string& initial_text)
|
: TextureWidget{renderer, util::load_img(renderer, path)} {}
|
||||||
: TextureWidget{renderer, dest_rect, std::nullopt}, font{font},
|
|
||||||
text{initial_text} {
|
TextWidget::TextWidget(SDL_Renderer* renderer, TTF_Font* font,
|
||||||
|
const std::string& initial_text)
|
||||||
|
: TextureWidget{renderer, std::nullopt}, font{font}, text{initial_text} {
|
||||||
if (text != "") {
|
if (text != "") {
|
||||||
update_texture(generate_text(text));
|
update_texture(generate_text(text));
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user