From: Daniel Karbach Date: Sun, 19 Nov 2017 22:35:35 +0000 (+0100) Subject: cleaned up ui a little X-Git-Url: http://git.localhorst.tv/?p=blobs.git;a=commitdiff_plain;h=56f570e713c42d30109a214e68a2beed96ba1999 cleaned up ui a little --- diff --git a/src/graphics/shader.cpp b/src/graphics/shader.cpp index 0a31360..b14da4d 100644 --- a/src/graphics/shader.cpp +++ b/src/graphics/shader.cpp @@ -673,10 +673,10 @@ PlainColor::PlainColor() vao.ReserveAttributes(4, GL_STATIC_DRAW); { auto attrib = vao.MapAttributes(GL_WRITE_ONLY); - attrib[0].position = glm::vec3(-1.0f, -1.0f, 0.0f); - attrib[1].position = glm::vec3(-1.0f, 1.0f, 0.0f); - attrib[2].position = glm::vec3( 1.0f, -1.0f, 0.0f); - attrib[3].position = glm::vec3( 1.0f, 1.0f, 0.0f); + attrib[0].position = glm::vec3(-0.5f, -0.5f, 0.0f); + attrib[1].position = glm::vec3(-0.5f, 0.5f, 0.0f); + attrib[2].position = glm::vec3( 0.5f, -0.5f, 0.0f); + attrib[3].position = glm::vec3( 0.5f, 0.5f, 0.0f); } vao.BindElements(); vao.ReserveElements(7, GL_STATIC_DRAW); @@ -807,13 +807,13 @@ AlphaSprite::AlphaSprite() vao.ReserveAttributes(4, GL_STATIC_DRAW); { auto attrib = vao.MapAttributes(GL_WRITE_ONLY); - attrib[0].position = glm::vec3(-1.0f, -1.0f, 0.0f); + attrib[0].position = glm::vec3(-0.5f, -0.5f, 0.0f); attrib[0].texture = glm::vec2(0.0f, 0.0f); - attrib[1].position = glm::vec3(-1.0f, 1.0f, 0.0f); + attrib[1].position = glm::vec3(-0.5f, 0.5f, 0.0f); attrib[1].texture = glm::vec2(0.0f, 1.0f); - attrib[2].position = glm::vec3( 1.0f, -1.0f, 0.0f); + attrib[2].position = glm::vec3( 0.5f, -0.5f, 0.0f); attrib[2].texture = glm::vec2(1.0f, 0.0f); - attrib[3].position = glm::vec3( 1.0f, 1.0f, 0.0f); + attrib[3].position = glm::vec3( 0.5f, 0.5f, 0.0f); attrib[3].texture = glm::vec2(1.0f, 1.0f); } vao.BindElements(); diff --git a/src/ui/CreaturePanel.hpp b/src/ui/CreaturePanel.hpp index b9888b2..a487b1a 100644 --- a/src/ui/CreaturePanel.hpp +++ b/src/ui/CreaturePanel.hpp @@ -2,6 +2,7 @@ #define BLOBS_UI_CREATUREPANEL_HPP_ #include "Label.hpp" +#include "Panel.hpp" namespace blobs { @@ -37,7 +38,8 @@ public: private: creature::Creature *c; - Label name; + Label *name; + Panel panel; }; diff --git a/src/ui/Label.hpp b/src/ui/Label.hpp index 0b9e0ca..90ed738 100644 --- a/src/ui/Label.hpp +++ b/src/ui/Label.hpp @@ -1,33 +1,24 @@ #ifndef BLOBS_UI_LABEL_HPP_ #define BLOBS_UI_LABEL_HPP_ -#include "align.hpp" +#include "Widget.hpp" #include "../graphics/Texture.hpp" #include namespace blobs { -namespace app { - struct Assets; -} namespace graphics { class Font; - class Viewport; } namespace ui { -class Label { +class Label +: public Widget { public: explicit Label(const graphics::Font &); - ~Label(); - - Label(const Label &) = delete; - Label &operator =(const Label &) = delete; - - Label(Label &&) = delete; - Label &operator =(Label &&) = delete; + ~Label() override; public: Label &Text(const std::string &); @@ -35,14 +26,8 @@ public: Label &Foreground(const glm::vec4 &); Label &Background(const glm::vec4 &); - Label &Position(const glm::vec3 &p) noexcept { pos = p; return *this; } - const glm::vec3 &Position() const noexcept { return pos; } - - Label &Origin(Gravity o) noexcept { origin = o; return *this; } - Gravity Origin() const noexcept { return origin; } - - glm::vec2 Size(); - void Draw(app::Assets &, graphics::Viewport &) noexcept; + glm::vec2 Size() override; + void Draw(app::Assets &, graphics::Viewport &) noexcept override; private: void Update(); @@ -53,8 +38,6 @@ private: graphics::Texture tex; glm::vec4 fg_color; glm::vec4 bg_color; - glm::vec3 pos; - Gravity origin; bool dirty; }; diff --git a/src/ui/Panel.hpp b/src/ui/Panel.hpp new file mode 100644 index 0000000..d62073b --- /dev/null +++ b/src/ui/Panel.hpp @@ -0,0 +1,52 @@ +#ifndef BLOBS_UI_PANEL_HPP_ +#define BLOBS_UI_PANEL_HPP_ + +#include "Widget.hpp" + +#include +#include + + +namespace blobs { +namespace ui { + +class Panel +: public Widget { + +public: + enum Dir { + HORIZONTAL, + VERTICAL, + }; + +public: + Panel(); + ~Panel() override; + +public: + // panel takes ownership + Panel &Add(Widget *); + + Panel &Background(const glm::vec4 &); + Panel &Padding(const glm::vec2 &); + Panel &Spacing(float); + Panel &Direction(Dir); + + glm::vec2 Size() override; + void Relayout(); + void Draw(app::Assets &, graphics::Viewport &) noexcept override; + +private: + std::vector> widgets; + glm::vec4 bg_color; + glm::vec2 padding; + float spacing; + Dir dir; + glm::vec2 size; + +}; + +} +} + +#endif diff --git a/src/ui/Widget.hpp b/src/ui/Widget.hpp new file mode 100644 index 0000000..cb83da2 --- /dev/null +++ b/src/ui/Widget.hpp @@ -0,0 +1,50 @@ +#ifndef BLOBS_UI_WIDGET_HPP_ +#define BLOBS_UI_WIDGET_HPP_ + +#include "align.hpp" +#include "../graphics/glm.hpp" + + +namespace blobs { +namespace app { + struct Assets; +} +namespace graphics { + class Viewport; +} +namespace ui { + +class Widget { + +public: + Widget(); + virtual ~Widget(); + + Widget(const Widget &) = delete; + Widget &operator =(const Widget &) = delete; + + Widget(Widget &&) = delete; + Widget &operator =(Widget &&) = delete; + +public: + Widget &Position(const glm::vec3 &p) noexcept { pos = p; return *this; } + const glm::vec3 &Position() const noexcept { return pos; } + glm::vec3 AlignedPosition() noexcept; + glm::vec3 TopLeft() noexcept; + + Widget &Origin(Gravity o) noexcept { origin = o; return *this; } + Gravity Origin() const noexcept { return origin; } + + virtual glm::vec2 Size() = 0; + virtual void Draw(app::Assets &, graphics::Viewport &) noexcept = 0; + +private: + glm::vec3 pos; + Gravity origin; + +}; + +} +} + +#endif diff --git a/src/ui/ui.cpp b/src/ui/ui.cpp index f7a102e..31f0396 100644 --- a/src/ui/ui.cpp +++ b/src/ui/ui.cpp @@ -6,17 +6,21 @@ #include -#include -#include - namespace blobs { namespace ui { CreaturePanel::CreaturePanel(const app::Assets &assets) : c(nullptr) -, name(assets.fonts.large) { - name.Origin(Gravity::NORTH_EAST); +, name(new Label(assets.fonts.large)) +, panel() { + panel + .Add(name) + .Padding(glm::vec2(10.0f)) + .Spacing(10.0f) + .Direction(Panel::VERTICAL) + .Background(glm::vec4(0.7f, 0.7f, 0.7f, 1.0f)) + .Origin(Gravity::NORTH_EAST); } CreaturePanel::~CreaturePanel() { @@ -25,7 +29,8 @@ CreaturePanel::~CreaturePanel() { void CreaturePanel::Show(creature::Creature &cr) { c = &cr; - name.Text(c->Name()); + name->Text(c->Name()); + panel.Relayout(); } void CreaturePanel::Hide() noexcept { @@ -36,90 +41,9 @@ void CreaturePanel::Draw(app::Assets &assets, graphics::Viewport &viewport) noex if (!c) return; const glm::vec2 margin(20.0f); - const glm::vec2 padding(10.0f); - - const glm::vec2 size(name.Size() + 2.0f * padding); - const glm::vec2 half_size = size * 0.5f; - - const glm::vec3 top_right(viewport.Width() - margin.x, margin.y, 0.0f); - name.Position(top_right - glm::vec3(padding.x, -padding.y, 1.0f)); - - assets.shaders.plain_color.Activate(); - assets.shaders.plain_color.SetM( - glm::translate(glm::vec3(top_right.x - half_size.x, top_right.y + half_size.y, 0.0f)) - * glm::scale(glm::vec3(half_size.x, half_size.y, 1.0f))); - assets.shaders.plain_color.SetColor(glm::vec3(0.7f, 0.7f, 0.7f)); - assets.shaders.plain_color.DrawRect(); - - name.Draw(assets, viewport); -} - - -Label::Label(const graphics::Font &f) -: font(&f) -, text() -, tex() -, fg_color(0.0f, 0.0f, 0.0f, 1.0f) -, bg_color(0.0f, 0.0f, 0.0f, 0.0f) -, pos(0.0f, 0.0f, 0.0f) -, origin(Gravity::CENTER) -, dirty(true) { -} - -Label::~Label() { -} - -Label &Label::Text(const std::string &t) { - if (text != t) { - dirty = true; - } - text = t; - return *this; -} - -Label &Label::Font(const graphics::Font &f) { - if (font != &f) { - dirty = true; - } - font = &f; - return *this; -} - -Label &Label::Foreground(const glm::vec4 &c) { - fg_color = c; - return *this; -} - -Label &Label::Background(const glm::vec4 &c) { - bg_color = c; - return *this; -} - -glm::vec2 Label::Size() { - Update(); - return tex.Size(); -} - -void Label::Draw(app::Assets &assets, graphics::Viewport &viewport) noexcept { - Update(); - glm::vec2 size = Size(); - glm::vec3 position = align(origin, size, pos); - - std::cout << "pos: " << pos << ", size: " << size << ", position: " << position << std::endl; - - assets.shaders.alpha_sprite.Activate(); - assets.shaders.alpha_sprite.SetM(glm::translate(position) - * glm::scale(glm::vec3(size.x * 0.5f, size.y * 0.5f, 1.0f))); - assets.shaders.alpha_sprite.SetTexture(tex); - assets.shaders.alpha_sprite.SetFgColor(fg_color); - assets.shaders.alpha_sprite.SetBgColor(bg_color); - assets.shaders.alpha_sprite.DrawRect(); -} -void Label::Update() { - if (!dirty) return; - font->Render(text, tex); - dirty = false; + panel.Position(glm::vec3(viewport.Width() - margin.x, margin.y, 0.0f)); + panel.Draw(assets, viewport); } } diff --git a/src/ui/widgets.cpp b/src/ui/widgets.cpp new file mode 100644 index 0000000..94c4182 --- /dev/null +++ b/src/ui/widgets.cpp @@ -0,0 +1,189 @@ +#include "Label.hpp" +#include "Panel.hpp" +#include "Widget.hpp" + +#include "../app/Assets.hpp" +#include "../graphics/Font.hpp" +#include "../graphics/Viewport.hpp" + +#include + + +namespace blobs { +namespace ui { + +Label::Label(const graphics::Font &f) +: font(&f) +, text() +, tex() +, fg_color(0.0f, 0.0f, 0.0f, 1.0f) +, bg_color(0.0f, 0.0f, 0.0f, 0.0f) +, dirty(true) { +} + +Label::~Label() { +} + +Label &Label::Text(const std::string &t) { + if (text != t) { + dirty = true; + } + text = t; + return *this; +} + +Label &Label::Font(const graphics::Font &f) { + if (font != &f) { + dirty = true; + } + font = &f; + return *this; +} + +Label &Label::Foreground(const glm::vec4 &c) { + fg_color = c; + return *this; +} + +Label &Label::Background(const glm::vec4 &c) { + bg_color = c; + return *this; +} + +glm::vec2 Label::Size() { + if (text.empty()) { + return glm::vec2(0.0f); + } + Update(); + return tex.Size(); +} + +void Label::Draw(app::Assets &assets, graphics::Viewport &viewport) noexcept { + Update(); + glm::vec2 size = Size(); + + assets.shaders.alpha_sprite.Activate(); + assets.shaders.alpha_sprite.SetM(glm::translate(AlignedPosition()) + * glm::scale(glm::vec3(size.x, size.y, 1.0f))); + assets.shaders.alpha_sprite.SetTexture(tex); + assets.shaders.alpha_sprite.SetFgColor(fg_color); + assets.shaders.alpha_sprite.SetBgColor(bg_color); + assets.shaders.alpha_sprite.DrawRect(); +} + +void Label::Update() { + if (!dirty) return; + font->Render(text, tex); + dirty = false; +} + + +Panel::Panel() +: widgets() +, bg_color(0.0f, 0.0f, 0.0f, 0.0f) +, padding(0.0f) +, spacing(0.0f) +, dir(VERTICAL) +, size(0.0f, 0.0f) { +} + +Panel::~Panel() { +} + +Panel &Panel::Add(Widget *w) { + std::unique_ptr widget(w); + glm::vec2 wsize = widget->Size(); + if (dir == HORIZONTAL) { + size.x += wsize.x; + size.y = std::max(size.y, wsize.y); + } else { + size.x = std::max(size.x, wsize.x); + size.y += wsize.y; + } + widgets.emplace_back(std::move(widget)); + return *this; +} + +Panel &Panel::Background(const glm::vec4 &c) { + bg_color = c; + return *this; +} + +Panel &Panel::Padding(const glm::vec2 &p) { + padding = p; + return *this; +} + +Panel &Panel::Spacing(float s) { + spacing = s; + return *this; +} + +Panel &Panel::Direction(Dir d) { + dir = d; + Relayout(); + return *this; +} + +glm::vec2 Panel::Size() { + return 2.0f * padding + glm::vec2(0.0f, (widgets.size() - 1) * spacing) + size; +} + +void Panel::Relayout() { + size = glm::vec2(0.0f); + if (dir == HORIZONTAL) { + for (auto &w : widgets) { + glm::vec2 wsize = w->Size(); + size.x += wsize.x; + size.y = std::max(size.y, wsize.y); + } + } else { + for (auto &w : widgets) { + glm::vec2 wsize = w->Size(); + size.x = std::max(size.x, wsize.x); + size.y += wsize.y; + } + } +} + +void Panel::Draw(app::Assets &assets, graphics::Viewport &viewport) noexcept { + if (bg_color.a > 0.0f) { + glm::vec2 fullsize = Size(); + assets.shaders.plain_color.Activate(); + assets.shaders.plain_color.SetM(glm::translate(AlignedPosition()) + * glm::scale(glm::vec3(fullsize.x, fullsize.y, 1.0f))); + assets.shaders.plain_color.SetColor(bg_color); + assets.shaders.plain_color.DrawRect(); + } + + glm::vec3 cursor = TopLeft(); + cursor.x += padding.x; + cursor.y += padding.y; + cursor.z -= 1.0f; + for (auto &w : widgets) { + w->Position(cursor).Origin(Gravity::NORTH_WEST); + w->Draw(assets, viewport); + cursor[dir] += w->Size()[dir] + spacing; + } +} + + +Widget::Widget() +: pos(0.0f) +, origin(Gravity::CENTER) { +} + +Widget::~Widget() { +} + +glm::vec3 Widget::AlignedPosition() noexcept { + return align(origin, Size(), pos); +} + +glm::vec3 Widget::TopLeft() noexcept { + glm::vec2 size = Size(); + return align(origin, size, pos) - glm::vec3(size * 0.5f, 0.0f); +} + +} +}