mirror of
https://github.com/zhenyan121/Cubed.git
synced 2026-08-08 17:57:02 +08:00
feat(ui): introduce anchor-based widget positioning system
Replace set_position with anchor and offset for relative positioning. Add parent pointer to widget hierarchy. Remove manual resize logic in UI managers.
This commit is contained in:
@@ -13,8 +13,9 @@ public:
|
||||
DebugCollector();
|
||||
|
||||
void report(const std::string& name, std::string_view content);
|
||||
void init_text();
|
||||
void init(int width, int height);
|
||||
Widget& get_widget();
|
||||
bool handle_event(const Event& e);
|
||||
|
||||
private:
|
||||
Widget m_widget;
|
||||
|
||||
15
include/Cubed/ui/anchor.hpp
Normal file
15
include/Cubed/ui/anchor.hpp
Normal file
@@ -0,0 +1,15 @@
|
||||
#pragma once
|
||||
|
||||
enum class Anchor {
|
||||
TOP_LEFT,
|
||||
TOP_CENTER,
|
||||
TOP_RIGHT,
|
||||
|
||||
CENTER_LEFT,
|
||||
CENTER,
|
||||
CENTER_RIGHT,
|
||||
|
||||
BOTTOM_LEFT,
|
||||
BOTTOM_CENTER,
|
||||
BOTTOM_RIGHT,
|
||||
};
|
||||
@@ -9,7 +9,7 @@
|
||||
namespace Cubed {
|
||||
class Button : public Widget {
|
||||
public:
|
||||
Button();
|
||||
Button(Widget* parent);
|
||||
|
||||
Button(const Button&) = delete;
|
||||
Button(Button&&) = delete;
|
||||
@@ -21,10 +21,11 @@ public:
|
||||
|
||||
bool handle_mouse_move_event(const MouseMoveEvent& e) override;
|
||||
bool handle_mouse_button_event(const MouseButtonEvent& e) override;
|
||||
|
||||
Widget& set_position(const glm::vec2& pos) override;
|
||||
Widget& set_position(float x, float y) override;
|
||||
void set_window_size(int width, int height) override;
|
||||
Button& set_scale(float scale);
|
||||
Widget& set_anchor(Anchor anchor) override;
|
||||
Widget& set_offset(glm::ivec2 offset) override;
|
||||
glm::vec2 pos() const override;
|
||||
float width() const override;
|
||||
float height() const override;
|
||||
float scale() const;
|
||||
@@ -34,16 +35,17 @@ public:
|
||||
}
|
||||
|
||||
template <typename T, typename... Args> T& set_background(Args&&... args) {
|
||||
auto w = std::make_unique<T>(std::forward<Args>(args)...);
|
||||
auto w = std::make_unique<T>(std::forward<Args>(args)..., m_parent);
|
||||
T& ref = *w;
|
||||
m_background = std::move(w);
|
||||
return ref;
|
||||
}
|
||||
|
||||
template <typename T, typename... Args> T& set_foreground(Args&&... args) {
|
||||
auto w = std::make_unique<T>(std::forward<Args>(args)...);
|
||||
auto w = std::make_unique<T>(std::forward<Args>(args)..., this);
|
||||
T& ref = *w;
|
||||
m_foreground = std::move(w);
|
||||
m_foreground->set_anchor(Anchor::CENTER);
|
||||
return ref;
|
||||
}
|
||||
|
||||
@@ -52,7 +54,5 @@ private:
|
||||
std::unique_ptr<Image> m_background;
|
||||
std::unique_ptr<Label> m_foreground;
|
||||
bool m_hovered = false;
|
||||
glm::vec2 m_min_pos;
|
||||
glm::vec2 m_max_pos;
|
||||
};
|
||||
} // namespace Cubed
|
||||
@@ -8,7 +8,7 @@ namespace Cubed {
|
||||
class TextureManager;
|
||||
class Image : public Widget {
|
||||
public:
|
||||
Image();
|
||||
Image(Widget* parent);
|
||||
void update(float dt) override;
|
||||
void render(Renderer& renderer) override;
|
||||
|
||||
|
||||
@@ -10,8 +10,8 @@ public:
|
||||
Label& operator=(const Label&) = delete;
|
||||
Label& operator=(Label&&) = delete;
|
||||
|
||||
Label(const std::string& id);
|
||||
Label();
|
||||
Label(const std::string& id, Widget* parent);
|
||||
Label(Widget* parent);
|
||||
virtual ~Label() = default;
|
||||
|
||||
Label& set_text(std::string_view text);
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
#pragma once
|
||||
#include "Cubed/input/event.hpp"
|
||||
#include "glm/ext/vector_float2.hpp"
|
||||
#include "Cubed/ui/anchor.hpp"
|
||||
|
||||
#include <glm/glm.hpp>
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
namespace Cubed {
|
||||
@@ -10,18 +11,19 @@ class Renderer;
|
||||
class Widget {
|
||||
|
||||
public:
|
||||
Widget(const std::string& id);
|
||||
Widget() = default;
|
||||
Widget(const std::string& id, Widget* parent);
|
||||
Widget(Widget* parent);
|
||||
virtual ~Widget() = default;
|
||||
virtual void update(float dt);
|
||||
virtual void render(Renderer& renderer);
|
||||
virtual const std::string& id() const;
|
||||
virtual Widget& set_position(const glm::vec2& pos);
|
||||
virtual Widget& set_position(float x, float y);
|
||||
virtual Widget& set_anchor(Anchor anchor);
|
||||
virtual Widget& set_offset(glm::ivec2 offset);
|
||||
virtual void set_window_size(int width, int height);
|
||||
// Returns the final display size
|
||||
virtual float width() const;
|
||||
virtual float height() const;
|
||||
virtual const glm::vec2& pos() const;
|
||||
virtual glm::vec2 pos() const;
|
||||
|
||||
virtual bool handle_key_event(const KeyEvent& e);
|
||||
virtual bool handle_mouse_button_event(const MouseButtonEvent& e);
|
||||
@@ -39,12 +41,16 @@ public:
|
||||
protected:
|
||||
virtual void on_update(float dt);
|
||||
virtual void on_render(Renderer& renderer);
|
||||
virtual glm::vec2 compute_position() const;
|
||||
Widget* m_parent = nullptr;
|
||||
std::string m_id;
|
||||
float m_window_height = 0;
|
||||
float m_window_width = 0;
|
||||
// Center is at the top-left corner, position is at the top-left corner
|
||||
glm::vec2 m_pos{0.0f, 0.0f};
|
||||
Anchor m_anchor = Anchor::TOP_LEFT;
|
||||
glm::ivec2 m_offset{0, 0};
|
||||
|
||||
private:
|
||||
Widget* m_parent = nullptr;
|
||||
std::vector<std::unique_ptr<Widget>> m_children;
|
||||
};
|
||||
} // namespace Cubed
|
||||
Reference in New Issue
Block a user