refactor(ui): move width, height, and fill properties to base Widget

Consolidate width, height, and fill (fill_parent, fill_width, fill_height) into the base Widget class. Replace per-widget set_fill(bool) with set_fill_parent(bool), set_fill_width(bool), and set_fill_height(bool).
This commit is contained in:
2026-07-19 20:56:31 +08:00
parent 2fd9f0b854
commit 8c79808b86
25 changed files with 183 additions and 156 deletions

View File

@@ -23,8 +23,8 @@ public:
float width() const override; float width() const override;
float height() const override; float height() const override;
Button& set_width(float width); Button& set_width(float width) override;
Button& set_height(float height); Button& set_height(float height) override;
Button& set_background_image(const std::string& path, Button& set_background_image(const std::string& path,
TextureManager& texture_manager); TextureManager& texture_manager);
Button& set_default_image(TextureManager& texture_manager); Button& set_default_image(TextureManager& texture_manager);
@@ -54,8 +54,6 @@ private:
"texture/ui/button001.png"; "texture/ui/button001.png";
std::function<void()> m_clicked; std::function<void()> m_clicked;
float m_width = NORMAL_BUTTON_WIDTH;
float m_height = NORMAL_BUTTON_HEIGHT;
float m_scale = DEFAULT_SCALE; float m_scale = DEFAULT_SCALE;
bool m_auto_scale = false; bool m_auto_scale = false;
void on_render(Renderer& renderer) override; void on_render(Renderer& renderer) override;

View File

@@ -17,7 +17,6 @@ public:
ChatBox& set_text_scale(float scale); ChatBox& set_text_scale(float scale);
// Only the width of TextField can be set; the height is calculated // Only the width of TextField can be set; the height is calculated
// dynamically // dynamically
ChatBox& set_width(float width);
ChatBox& set_show_lines(int lines); ChatBox& set_show_lines(int lines);
ChatBox& set_spacing(float spacing); ChatBox& set_spacing(float spacing);
ChatBox& clear_input(); ChatBox& clear_input();
@@ -42,8 +41,6 @@ private:
int m_lines = 10; int m_lines = 10;
bool m_scale = 1.0f; bool m_scale = 1.0f;
float m_spacing = 0.0f; float m_spacing = 0.0f;
float m_width = 0.0f;
float m_height = 0.0f;
float m_text_scale = 1.0f; float m_text_scale = 1.0f;
std::deque<Line> m_messages; std::deque<Line> m_messages;
std::unique_ptr<TextField> m_text_field; std::unique_ptr<TextField> m_text_field;

View File

@@ -26,8 +26,8 @@ public:
private: private:
int m_spacing = 0; int m_spacing = 0;
float m_content_height = 0; float m_content_height = 0.0f;
float m_content_width = 0; float m_content_width = 0.0f;
ColumnLayoutAnchor m_layout_anchor = ColumnLayoutAnchor::CENTER; ColumnLayoutAnchor m_layout_anchor = ColumnLayoutAnchor::CENTER;
}; };
} // namespace Cubed } // namespace Cubed

View File

@@ -21,17 +21,9 @@ public:
Image& set_scale(float scale); Image& set_scale(float scale);
float scale() const; float scale() const;
Image& set_height(float height);
Image& set_width(float width);
Image& set_fill(bool fill);
private: private:
void on_render(Renderer& renderer) override; void on_render(Renderer& renderer) override;
void on_update(float dt) override; void on_update(float dt) override;
float m_width = 0.0f;
float m_height = 0.0f;
bool m_fill = false;
const Texture* m_texture = nullptr; const Texture* m_texture = nullptr;
glm::vec2 m_pos{0.0f, 0.0f}; glm::vec2 m_pos{0.0f, 0.0f};

View File

@@ -16,11 +16,6 @@ public:
float height() const override; float height() const override;
float alpha() const; float alpha() const;
Rect& set_width(float width);
Rect& set_height(float height);
Rect& set_fill(bool fill);
Rect& set_scale(float scale); Rect& set_scale(float scale);
Rect& set_color(Color color); Rect& set_color(Color color);
Rect& set_alpha(float alpha); Rect& set_alpha(float alpha);
@@ -32,10 +27,7 @@ private:
void on_render(Renderer& renderer) override; void on_render(Renderer& renderer) override;
Color m_color = Color::WHITE; Color m_color = Color::WHITE;
float m_width = 0.0f;
float m_height = 0.0f;
float m_scale = 1.0f; float m_scale = 1.0f;
float m_alpha = 1.0f; float m_alpha = 1.0f;
bool m_fill = false;
}; };
} // namespace Cubed } // namespace Cubed

View File

@@ -21,8 +21,8 @@ public:
float height() const override; float height() const override;
Slider& set_scale(float scale); Slider& set_scale(float scale);
Slider& set_width(float width); Slider& set_width(float width) override;
Slider& set_height(float h); Slider& set_height(float h) override;
Slider& set_slider_text(const std::string& key, Slider& set_slider_text(const std::string& key,
const std::string& variable); const std::string& variable);
Slider& set_track_image(const std::string& path, Slider& set_track_image(const std::string& path,
@@ -48,8 +48,7 @@ private:
std::unique_ptr<Label> m_label; std::unique_ptr<Label> m_label;
ValueType m_type = ValueType::FLOAT; ValueType m_type = ValueType::FLOAT;
float m_scale = DEFAULT_SCALE; float m_scale = DEFAULT_SCALE;
float m_width = NORMAL_SLIDER_WIDTH;
float m_height = NORMAL_SLIDER_HEIGHT;
float m_xpos = 0.0f; float m_xpos = 0.0f;
bool m_dragging = false; bool m_dragging = false;
bool m_inside = false; bool m_inside = false;

View File

@@ -18,16 +18,14 @@ public:
float width() const override; float width() const override;
float height() const override; float height() const override;
TextField& set_width(float width); TextField& set_width(float width) override;
TextField& set_height(float height); TextField& set_height(float height) override;
TextField& set_show_text(const std::string& text); TextField& set_show_text(const std::string& text);
TextField& set_background(std::unique_ptr<Widget> background); TextField& set_background(std::unique_ptr<Widget> background);
TextField& set_auto_scale(bool auto_scale); TextField& set_auto_scale(bool auto_scale);
TextField& set_app(App* app); TextField& set_app(App* app);
TextField& set_typing(bool typing, bool finished); TextField& set_typing(bool typing, bool finished);
TextField& clear_input(); TextField& clear_input();
TextField& set_fill_width(bool fill);
TextField& set_fill_height(bool fill);
bool handle_mouse_move_event(const MouseMoveEvent& e) override; bool handle_mouse_move_event(const MouseMoveEvent& e) override;
bool handle_mouse_button_event(const MouseButtonEvent& e) override; bool handle_mouse_button_event(const MouseButtonEvent& e) override;
bool handle_text_input_event(const TextInputEvent& e) override; bool handle_text_input_event(const TextInputEvent& e) override;

View File

@@ -34,8 +34,16 @@ public:
virtual Widget& set_window_size(int width, int height); virtual Widget& set_window_size(int width, int height);
virtual Widget& set_visible(bool visible); virtual Widget& set_visible(bool visible);
// Returns the final display size // Returns the final display size
virtual float width() const; virtual float width() const;
virtual float height() const; virtual float height() const;
virtual Widget& set_width(float width);
virtual Widget& set_height(float height);
virtual Widget& set_fill_parent(bool fill);
virtual Widget& set_fill_width(bool fill);
virtual Widget& set_fill_height(bool fill);
virtual glm::vec2 pos() const; virtual glm::vec2 pos() const;
virtual bool handle_key_event(const KeyEvent& e); virtual bool handle_key_event(const KeyEvent& e);
@@ -44,7 +52,6 @@ public:
virtual bool handle_window_resize_event(const WindowResizeEvent& e); virtual bool handle_window_resize_event(const WindowResizeEvent& e);
virtual bool handle_mouse_move_event(const MouseMoveEvent& e); virtual bool handle_mouse_move_event(const MouseMoveEvent& e);
virtual bool handle_text_input_event(const TextInputEvent& e); virtual bool handle_text_input_event(const TextInputEvent& e);
void set_order(TraversalOrder order); void set_order(TraversalOrder order);
template <typename T, typename... Args> T& add_child(Args&&... args) { template <typename T, typename... Args> T& add_child(Args&&... args) {
@@ -56,12 +63,16 @@ public:
protected: protected:
Widget* m_parent = nullptr; Widget* m_parent = nullptr;
float m_window_height = 0; float m_window_height = 0.0f;
float m_window_width = 0; float m_window_width = 0.0f;
float m_width = 0.0f;
float m_height = 0.0f;
// Center is at the top-left corner, position is at the top-left corner // Center is at the top-left corner, position is at the top-left corner
Anchor m_anchor = Anchor::TOP_LEFT; Anchor m_anchor = Anchor::TOP_LEFT;
bool m_visible = true; bool m_visible = true;
bool m_fill_parent = false;
bool m_fill_height = false;
bool m_fill_width = false;
glm::ivec2 m_offset{0, 0}; glm::ivec2 m_offset{0, 0};
std::vector<std::unique_ptr<Widget>>& children(); std::vector<std::unique_ptr<Widget>>& children();

View File

@@ -5,13 +5,16 @@
namespace Cubed { namespace Cubed {
Button::Button(Widget* parent) : Widget(parent) { Button::Button(Widget* parent) : Widget(parent) {
m_background = std::make_unique<Image>(this); m_background = std::make_unique<Image>(this);
m_background->set_fill(true); m_background->set_fill_parent(true);
m_background->set_anchor(Anchor::TOP_LEFT); m_background->set_anchor(Anchor::TOP_LEFT);
m_foreground = std::make_unique<Label>(this); m_foreground = std::make_unique<Label>(this);
m_foreground->set_anchor(Anchor::CENTER); m_foreground->set_anchor(Anchor::CENTER);
m_width = NORMAL_BUTTON_WIDTH;
m_height = NORMAL_BUTTON_HEIGHT;
} }
void Button::on_update(float dt) { void Button::on_update(float dt) {
Widget::on_update(dt);
if (m_background) { if (m_background) {
m_background->update(dt); m_background->update(dt);
} }
@@ -27,6 +30,7 @@ void Button::on_render(Renderer& renderer) {
if (m_foreground) { if (m_foreground) {
m_foreground->render(renderer); m_foreground->render(renderer);
} }
Widget::on_render(renderer);
} }
bool Button::handle_mouse_move_event(const MouseMoveEvent& e) { bool Button::handle_mouse_move_event(const MouseMoveEvent& e) {
@@ -62,8 +66,20 @@ Button& Button::set_scale(float scale) {
float Button::scale() const { return m_scale; } float Button::scale() const { return m_scale; }
float Button::width() const { return m_width * m_scale; } float Button::width() const {
float Button::height() const { return m_height * m_scale; }
if (m_fill_width || m_fill_parent) {
return m_width;
}
return m_width * m_scale;
}
float Button::height() const {
if (m_fill_width || m_fill_parent) {
return m_width;
}
return m_height * m_scale;
}
Button& Button::set_width(float width) { Button& Button::set_width(float width) {
m_width = width; m_width = width;
update_text_scale(); update_text_scale();

View File

@@ -38,10 +38,6 @@ ChatBox& ChatBox::set_text_scale(float scale) {
return *this; return *this;
} }
ChatBox& ChatBox::set_width(float width) {
m_width = width;
return *this;
}
ChatBox& ChatBox::set_show_lines(int lines) { ChatBox& ChatBox::set_show_lines(int lines) {
m_lines = lines; m_lines = lines;
return *this; return *this;
@@ -56,7 +52,12 @@ ChatBox& ChatBox::clear_input() {
} }
std::string& ChatBox::get_input_text() { return m_text_field->input_text(); } std::string& ChatBox::get_input_text() { return m_text_field->input_text(); }
float ChatBox::width() const { return m_width * m_scale; } float ChatBox::width() const {
if (m_fill_width || m_fill_parent) {
return m_width;
}
return m_width * m_scale;
}
float ChatBox::height() const { float ChatBox::height() const {
// Height is dynamically calculated, no scaling needed // Height is dynamically calculated, no scaling needed
return m_height; return m_height;
@@ -100,8 +101,8 @@ void ChatBox::layout() {
m_height = m_lines == 0 ? 0 : (y - m_spacing); m_height = m_lines == 0 ? 0 : (y - m_spacing);
} }
void ChatBox::on_update(float dt) { void ChatBox::on_update(float dt) {
Widget::on_update(dt);
layout(); layout();
m_text_field->update(dt); m_text_field->update(dt);
} }
@@ -118,6 +119,7 @@ void ChatBox::on_render(Renderer& renderer) {
it->label->render(renderer); it->label->render(renderer);
} }
} }
Widget::on_render(renderer);
} }
bool ChatBox::handle_text_input_event(const TextInputEvent& e) { bool ChatBox::handle_text_input_event(const TextInputEvent& e) {
if (m_text_field && m_text_field->handle_text_input_event(e)) { if (m_text_field && m_text_field->handle_text_input_event(e)) {

View File

@@ -7,8 +7,8 @@ ColumnLayout::ColumnLayout(Widget* parent) : Widget(parent) {
ColumnLayout::~ColumnLayout() {} ColumnLayout::~ColumnLayout() {}
void ColumnLayout::update(float dt) { void ColumnLayout::update(float dt) {
layout();
Widget::update(dt); Widget::update(dt);
layout();
} }
float ColumnLayout::width() const { return m_content_width; } float ColumnLayout::width() const { return m_content_width; }

View File

@@ -16,14 +16,15 @@ void CreditsUI::init() {
auto& renderer = m_scene.scene_manager().app().renderer(); auto& renderer = m_scene.scene_manager().app().renderer();
auto image = std::make_unique<Image>(nullptr); auto image = std::make_unique<Image>(nullptr);
image->set_fill(true) image
.set_image("texture/ui/background.png", ->set_image("texture/ui/background.png",
m_scene.scene_manager().app().texture_manager()) m_scene.scene_manager().app().texture_manager())
.set_anchor(Anchor::TOP_LEFT) .set_anchor(Anchor::TOP_LEFT)
.set_window_size(renderer.window_width(), renderer.window_height()); .set_window_size(renderer.window_width(), renderer.window_height())
.set_fill_parent(true);
auto& rect = image->add_child<Rect>(); auto& rect = image->add_child<Rect>();
rect.set_fill(true).set_color(Color::BLACK).set_alpha(0.7f); rect.set_color(Color::BLACK).set_alpha(0.7f).set_fill_parent(true);
{ {
auto& button = rect.add_child<Button>(); auto& button = rect.add_child<Button>();

View File

@@ -16,10 +16,10 @@ void ErrorUI::init() {
bi->set_window_size(renderer.window_width(), renderer.window_height()); bi->set_window_size(renderer.window_width(), renderer.window_height());
bi->set_anchor(Anchor::TOP_LEFT); bi->set_anchor(Anchor::TOP_LEFT);
bi->set_image("texture/ui/background.png", texture_manager); bi->set_image("texture/ui/background.png", texture_manager);
bi->set_fill(true); bi->set_fill_parent(true);
auto& rect = bi->add_child<Rect>(); auto& rect = bi->add_child<Rect>();
rect.set_fill(true); rect.set_fill_parent(true);
rect.set_alpha(0.7f); rect.set_alpha(0.7f);
rect.set_color(Color::BLACK); rect.set_color(Color::BLACK);

View File

@@ -19,10 +19,10 @@ void HostGameUI::init() {
bi->set_window_size(renderer.window_width(), renderer.window_height()); bi->set_window_size(renderer.window_width(), renderer.window_height());
bi->set_anchor(Anchor::TOP_LEFT); bi->set_anchor(Anchor::TOP_LEFT);
bi->set_image("texture/ui/background.png", texture_manager); bi->set_image("texture/ui/background.png", texture_manager);
bi->set_fill(true); bi->set_fill_parent(true);
auto& rect = bi->add_child<Rect>(); auto& rect = bi->add_child<Rect>();
rect.set_fill(true); rect.set_fill_parent(true);
rect.set_alpha(0.7f); rect.set_alpha(0.7f);
rect.set_color(Color::BLACK); rect.set_color(Color::BLACK);
@@ -50,8 +50,8 @@ void HostGameUI::init() {
text_seed.set_show_text(tr("hostgame.world_seed")); text_seed.set_show_text(tr("hostgame.world_seed"));
text_seed.set_app(&m_scene.scene_manager().app()); text_seed.set_app(&m_scene.scene_manager().app());
std::unique_ptr<Image> back = std::make_unique<Image>(&text_seed); std::unique_ptr<Image> back = std::make_unique<Image>(&text_seed);
back->set_fill(true).set_image(DEFAULT_TEXT_FIELD_IMAGE, back->set_image(DEFAULT_TEXT_FIELD_IMAGE, texture_manager)
texture_manager); .set_fill_parent(true);
text_seed.set_background(std::move(back)); text_seed.set_background(std::move(back));
text_seed.set_on_finish([this, &text_seed]() { text_seed.set_on_finish([this, &text_seed]() {
unsigned seed = 0; unsigned seed = 0;
@@ -72,8 +72,8 @@ void HostGameUI::init() {
{ {
auto& text_port = layout.add_child<TextField>(); auto& text_port = layout.add_child<TextField>();
std::unique_ptr<Image> back = std::make_unique<Image>(&text_port); std::unique_ptr<Image> back = std::make_unique<Image>(&text_port);
back->set_fill(true).set_image(DEFAULT_TEXT_FIELD_IMAGE, back->set_image(DEFAULT_TEXT_FIELD_IMAGE, texture_manager)
texture_manager); .set_fill_parent(true);
text_port.set_background(std::move(back)); text_port.set_background(std::move(back));
text_port.set_show_text(tr("hostgame.port")); text_port.set_show_text(tr("hostgame.port"));
text_port.set_app(&m_scene.scene_manager().app()); text_port.set_app(&m_scene.scene_manager().app());

View File

@@ -6,20 +6,11 @@
namespace Cubed { namespace Cubed {
Image::Image(Widget* parent) : Widget(parent) {} Image::Image(Widget* parent) : Widget(parent) {}
void Image::on_render(Renderer& renderer) { renderer.render_image(*this); } void Image::on_render(Renderer& renderer) {
void Image::on_update(float) { renderer.render_image(*this);
if (m_fill) { Widget::on_render(renderer);
if (m_fill) {
if (!m_parent) {
m_width = m_window_width;
m_height = m_window_height;
} else {
m_width = m_parent->width();
m_height = m_parent->height();
}
}
}
} }
void Image::on_update(float dt) { Widget::on_update(dt); }
Image& Image::set_image(const std::string& path, Image& Image::set_image(const std::string& path,
TextureManager& texture_manager) { TextureManager& texture_manager) {
m_texture = texture_manager.get_image_texture(path); m_texture = texture_manager.get_image_texture(path);
@@ -37,6 +28,9 @@ float Image::height() const {
Logger::error("Image not set image!"); Logger::error("Image not set image!");
return 0.0f; return 0.0f;
} }
if (m_fill_height || m_fill_parent) {
return m_height;
}
return m_height * m_scale; return m_height * m_scale;
} }
@@ -45,23 +39,12 @@ float Image::width() const {
Logger::error("Image not set image!"); Logger::error("Image not set image!");
return 0.0f; return 0.0f;
} }
if (m_fill_parent || m_fill_width) {
return m_width;
}
return m_width * m_scale; return m_width * m_scale;
} }
Image& Image::set_height(float height) {
m_height = height;
return *this;
}
Image& Image ::set_width(float width) {
m_width = width;
return *this;
}
Image& Image::set_fill(bool fill) {
m_fill = fill;
return *this;
}
const Texture* Image::texture() const { return m_texture; } const Texture* Image::texture() const { return m_texture; }
} // namespace Cubed } // namespace Cubed

View File

@@ -17,10 +17,10 @@ void JoinGameUI::init() {
bi->set_window_size(renderer.window_width(), renderer.window_height()); bi->set_window_size(renderer.window_width(), renderer.window_height());
bi->set_anchor(Anchor::TOP_LEFT); bi->set_anchor(Anchor::TOP_LEFT);
bi->set_image("texture/ui/background.png", texture_manager); bi->set_image("texture/ui/background.png", texture_manager);
bi->set_fill(true); bi->set_fill_parent(true);
auto& rect = bi->add_child<Rect>(); auto& rect = bi->add_child<Rect>();
rect.set_fill(true); rect.set_fill_parent(true);
rect.set_alpha(0.7f); rect.set_alpha(0.7f);
rect.set_color(Color::BLACK); rect.set_color(Color::BLACK);
@@ -47,8 +47,8 @@ void JoinGameUI::init() {
auto& text_ip = layout.add_child<TextField>(); auto& text_ip = layout.add_child<TextField>();
text_ip.set_show_text(tr("joingame.server_ip")); text_ip.set_show_text(tr("joingame.server_ip"));
std::unique_ptr<Image> back = std::make_unique<Image>(&text_ip); std::unique_ptr<Image> back = std::make_unique<Image>(&text_ip);
back->set_fill(true).set_image(DEFAULT_TEXT_FIELD_IMAGE, back->set_image(DEFAULT_TEXT_FIELD_IMAGE, texture_manager)
texture_manager); .set_fill_parent(true);
text_ip.set_background(std::move(back)); text_ip.set_background(std::move(back));
text_ip.set_app(&m_scene.scene_manager().app()); text_ip.set_app(&m_scene.scene_manager().app());
text_ip.set_on_finish([this, &text_ip]() { text_ip.set_on_finish([this, &text_ip]() {

View File

@@ -24,7 +24,7 @@ Label& Label::enable_background() {
return *this; return *this;
} }
m_background = std::make_unique<Rect>(this); m_background = std::make_unique<Rect>(this);
m_background->set_fill(true); m_background->set_fill_parent(true);
m_background->set_anchor(Anchor::TOP_LEFT); m_background->set_anchor(Anchor::TOP_LEFT);
return *this; return *this;
} }
@@ -38,6 +38,7 @@ Label& Label::set_background_alpha(float alpha) {
} }
void Label::on_update(float dt) { void Label::on_update(float dt) {
Widget::on_update(dt);
if (m_background) { if (m_background) {
m_background->update(dt); m_background->update(dt);
} }
@@ -49,6 +50,7 @@ void Label::on_render(Renderer& renderer) {
m_background->render(renderer); m_background->render(renderer);
} }
renderer.render_lable(*this); renderer.render_lable(*this);
Widget::on_render(renderer);
} }
void Label::update_vertices() { void Label::update_vertices() {
@@ -57,8 +59,8 @@ void Label::update_vertices() {
m_offset_x = textmesh.min_x; m_offset_x = textmesh.min_x;
m_offset_y = textmesh.min_y; m_offset_y = textmesh.min_y;
m_real_width = textmesh.width; m_width = m_real_width = textmesh.width;
m_real_height = textmesh.height; m_height = m_real_height = textmesh.height;
m_data.update_sum(); m_data.update_sum();
m_data.upload(); m_data.upload();
@@ -66,8 +68,21 @@ void Label::update_vertices() {
const UIVertexData& Label::data() const { return m_data; } const UIVertexData& Label::data() const { return m_data; }
const TextStyle& Label::text_style() const { return m_text; } const TextStyle& Label::text_style() const { return m_text; }
float Label::width() const { return m_real_width * m_scale; } float Label::width() const {
float Label::height() const { return m_real_height * m_scale; }
if (m_fill_width || m_fill_parent) {
return m_width;
}
return m_width * m_scale;
}
float Label::height() const {
if (m_fill_height || m_fill_parent) {
return m_height;
}
return m_height * m_scale;
}
float Label::real_width() const { return m_real_width; } float Label::real_width() const { return m_real_width; }
float Label::real_height() const { return m_real_height; } float Label::real_height() const { return m_real_height; }
float Label::offset_x() const { return m_offset_x; } float Label::offset_x() const { return m_offset_x; }

View File

@@ -18,7 +18,7 @@ void MainMenuUIManager::init() {
auto image = std::make_unique<Image>(nullptr); auto image = std::make_unique<Image>(nullptr);
auto& texture_manager = m_scene.scene_manager().app().texture_manager(); auto& texture_manager = m_scene.scene_manager().app().texture_manager();
image->set_fill(true); image->set_fill_parent(true);
image->set_anchor(Anchor::TOP_LEFT); image->set_anchor(Anchor::TOP_LEFT);
image->set_image("texture/ui/background.png", texture_manager); image->set_image("texture/ui/background.png", texture_manager);
auto& renderer = m_scene.scene_manager().app().renderer(); auto& renderer = m_scene.scene_manager().app().renderer();

View File

@@ -12,7 +12,7 @@ PauseMenuUIManager::PauseMenuUIManager(WorldScene& scene) : m_scene(scene) {}
void PauseMenuUIManager::init() { void PauseMenuUIManager::init() {
auto rect = std::make_unique<Rect>(nullptr); auto rect = std::make_unique<Rect>(nullptr);
rect->set_fill(true); rect->set_fill_parent(true);
rect->set_color(Color::BLACK); rect->set_color(Color::BLACK);
rect->set_alpha(0.5f); rect->set_alpha(0.5f);
rect->set_anchor(Anchor::TOP_LEFT); rect->set_anchor(Anchor::TOP_LEFT);

View File

@@ -12,35 +12,27 @@ Rect::Rect(Widget* parent)
Rect::~Rect() {} Rect::~Rect() {}
void Rect::on_update(float) { void Rect::on_update(float dt) { Widget::on_update(dt); }
if (m_fill) { void Rect::on_render(Renderer& renderer) {
if (!m_parent) { renderer.render_rect(*this);
m_width = m_window_width; Widget::on_render(renderer);
m_height = m_window_height; }
} else {
m_width = m_parent->width(); float Rect::width() const {
m_height = m_parent->height();
} if (m_fill_width || m_fill_parent) {
return m_width;
} }
return m_width * m_scale;
} }
void Rect::on_render(Renderer& renderer) { renderer.render_rect(*this); } float Rect::height() const {
float Rect::width() const { return m_width * m_scale; } if (m_fill_height || m_fill_parent) {
float Rect::height() const { return m_height * m_scale; } return m_height;
}
return m_height * m_scale;
}
float Rect::alpha() const { return m_alpha; } float Rect::alpha() const { return m_alpha; }
Rect& Rect::set_width(float width) {
m_width = width;
return *this;
}
Rect& Rect::set_height(float height) {
m_height = height;
return *this;
}
Rect& Rect::set_fill(bool fill) {
m_fill = fill;
return *this;
}
Rect& Rect::set_scale(float scale) { Rect& Rect::set_scale(float scale) {
m_scale = scale; m_scale = scale;

View File

@@ -21,10 +21,10 @@ void SettingsUI::init() {
bi->set_window_size(renderer.window_width(), renderer.window_height()); bi->set_window_size(renderer.window_width(), renderer.window_height());
bi->set_anchor(Anchor::TOP_LEFT); bi->set_anchor(Anchor::TOP_LEFT);
bi->set_image("texture/ui/background.png", texture_manager); bi->set_image("texture/ui/background.png", texture_manager);
bi->set_fill(true); bi->set_fill_parent(true);
auto& rect = bi->add_child<Rect>(); auto& rect = bi->add_child<Rect>();
rect.set_fill(true); rect.set_fill_parent(true);
rect.set_alpha(0.7f); rect.set_alpha(0.7f);
rect.set_color(Color::BLACK); rect.set_color(Color::BLACK);

View File

@@ -13,6 +13,8 @@ Slider::Slider(Widget* parent) : Widget(parent) {
m_label = std::make_unique<Label>(this); m_label = std::make_unique<Label>(this);
m_label->set_anchor(Anchor::CENTER); m_label->set_anchor(Anchor::CENTER);
m_width = NORMAL_SLIDER_WIDTH;
m_height = NORMAL_SLIDER_HEIGHT;
update_text_scale(); update_text_scale();
} }
@@ -37,7 +39,7 @@ Slider& Slider::set_slider(int* value, const int& min, const int& max) {
void Slider::init_track() { void Slider::init_track() {
m_track = std::make_unique<Image>(this); m_track = std::make_unique<Image>(this);
m_track->set_fill(true); m_track->set_fill_parent(true);
m_track->set_anchor(Anchor::TOP_LEFT); m_track->set_anchor(Anchor::TOP_LEFT);
} }
@@ -54,8 +56,20 @@ void Slider::init_thumb() {
m_thumb->set_scale(m_scale); m_thumb->set_scale(m_scale);
} }
float Slider::width() const { return m_width * m_scale; } float Slider::width() const {
float Slider::height() const { return m_height * m_scale; }
if (m_fill_width || m_fill_parent) {
return m_width;
}
return m_width * m_scale;
}
float Slider::height() const {
if (m_fill_height || m_fill_parent) {
return m_height;
}
return m_height * m_scale;
}
Slider& Slider::set_scale(float scale) { Slider& Slider::set_scale(float scale) {
m_scale = scale; m_scale = scale;
@@ -160,6 +174,7 @@ void Slider::update_value(float mouse_x) {
} }
void Slider::on_update(float dt) { void Slider::on_update(float dt) {
Widget::on_update(dt);
if (!m_thumb || !m_track) { if (!m_thumb || !m_track) {
Logger::error("Please Set value and thumb and track"); Logger::error("Please Set value and thumb and track");
ASSERT(false); ASSERT(false);
@@ -216,6 +231,7 @@ void Slider::on_render(Renderer& renderer) {
if (m_label) { if (m_label) {
m_label->render(renderer); m_label->render(renderer);
} }
Widget::on_render(renderer);
} }
void Slider::update_text_scale() { void Slider::update_text_scale() {

View File

@@ -58,12 +58,7 @@ void TextField::on_render(Renderer& renderer) {
} }
void TextField::on_update(float dt) { void TextField::on_update(float dt) {
if (m_fill_height) { Widget::on_update(dt);
m_height = m_parent ? m_parent->height() : m_window_height;
}
if (m_fill_width) {
m_width = m_parent ? m_parent->width() : m_window_width;
}
m_cursor_timer += dt; m_cursor_timer += dt;
if (m_cursor_timer >= CURSOR_INTERVAL) { if (m_cursor_timer >= CURSOR_INTERVAL) {
@@ -176,15 +171,6 @@ TextField& TextField::clear_input() {
return *this; return *this;
} }
TextField& TextField::set_fill_width(bool fill) {
m_fill_width = fill;
return *this;
}
TextField& TextField::set_fill_height(bool fill) {
m_fill_height = fill;
return *this;
}
void TextField::start_typing() { void TextField::start_typing() {
if (m_app) { if (m_app) {
m_app->start_text_input(); m_app->start_text_input();

View File

@@ -3,7 +3,12 @@
#include "Cubed/tools/log.hpp" #include "Cubed/tools/log.hpp"
namespace Cubed { namespace Cubed {
Widget::Widget(Widget* parent) : m_parent(parent) {} Widget::Widget(Widget* parent) : m_parent(parent) {
if (!m_parent) {
// The root node of the window automatically fills the entire window.
set_fill_parent(true);
}
}
void Widget::update(float dt) { void Widget::update(float dt) {
on_update(dt); on_update(dt);
@@ -23,7 +28,18 @@ void Widget::render(Renderer& renderer) {
} }
} }
void Widget::on_update(float) {} void Widget::on_update(float) {
if (m_fill_width) {
m_width = m_parent ? m_parent->width() : m_window_width;
}
if (m_fill_height) {
m_height = m_parent ? m_parent->height() : m_window_height;
}
if (m_fill_parent) {
m_width = m_parent ? m_parent->width() : m_window_width;
m_height = m_parent ? m_parent->height() : m_window_height;
}
}
void Widget::on_render(Renderer&) {} void Widget::on_render(Renderer&) {}
std::vector<std::unique_ptr<Widget>>& Widget::children() { return m_children; } std::vector<std::unique_ptr<Widget>>& Widget::children() { return m_children; }
@@ -111,17 +127,29 @@ Widget& Widget::set_visible(bool visible) {
return *this; return *this;
} }
float Widget::width() const { float Widget::width() const { return m_width; }
if (m_parent) { float Widget::height() const { return m_height; }
return m_parent->width();
} Widget& Widget::set_width(float width) {
return m_window_width; m_width = width;
return *this;
} }
float Widget::height() const { Widget& Widget::set_height(float height) {
if (m_parent) { m_height = height;
return m_parent->height(); return *this;
} }
return m_window_height;
Widget& Widget::set_fill_parent(bool fill) {
m_fill_parent = fill;
return *this;
}
Widget& Widget::set_fill_width(bool fill) {
m_fill_width = fill;
return *this;
}
Widget& Widget::set_fill_height(bool fill) {
m_fill_height = fill;
return *this;
} }
glm::vec2 Widget::pos() const { return compute_position(); } glm::vec2 Widget::pos() const { return compute_position(); }

View File

@@ -15,6 +15,7 @@ WorldUIManager::~WorldUIManager() {}
void WorldUIManager::init() { void WorldUIManager::init() {
m_root_widget = std::make_unique<Widget>(nullptr); m_root_widget = std::make_unique<Widget>(nullptr);
m_root_widget->set_fill_parent(true);
auto& renderer = m_scene.scene_manager().app().renderer(); auto& renderer = m_scene.scene_manager().app().renderer();
m_root_widget->set_window_size(renderer.window_width(), m_root_widget->set_window_size(renderer.window_width(),
@@ -34,7 +35,7 @@ void WorldUIManager::init() {
auto text_field = std::make_unique<TextField>(&chat_box); auto text_field = std::make_unique<TextField>(&chat_box);
text_field->set_anchor(Anchor::BOTTOM_LEFT); text_field->set_anchor(Anchor::BOTTOM_LEFT);
auto rect = std::make_unique<Rect>(text_field.get()); auto rect = std::make_unique<Rect>(text_field.get());
rect->set_color(Color::GRAY).set_alpha(0.6f).set_fill(true); rect->set_color(Color::GRAY).set_alpha(0.6f).set_fill_parent(true);
text_field->set_background(std::move(rect)) text_field->set_background(std::move(rect))
.set_app(&m_scene.scene_manager().app()) .set_app(&m_scene.scene_manager().app())
.set_fill_width(true) .set_fill_width(true)