]> git.localhorst.tv Git - blobs.git/commitdiff
shoddy meters
authorDaniel Karbach <daniel.karbach@localhorst.tv>
Mon, 20 Nov 2017 21:19:25 +0000 (22:19 +0100)
committerDaniel Karbach <daniel.karbach@localhorst.tv>
Mon, 20 Nov 2017 21:19:25 +0000 (22:19 +0100)
src/creature/Creature.hpp
src/ui/CreaturePanel.hpp
src/ui/Label.hpp
src/ui/Meter.hpp [new file with mode: 0644]
src/ui/Panel.hpp
src/ui/Widget.hpp
src/ui/ui.cpp
src/ui/widgets.cpp

index e912553e6dcb3f3612e894281249a7d7d4e11bda..135cf9eb1d98d80d70a327f38a66e106d42af679 100644 (file)
@@ -49,6 +49,7 @@ public:
        double Health() const noexcept { return health; }
 
        void AddNeed(const Need &n) { needs.push_back(n); }
+       const std::vector<Need> &Needs() const noexcept { return needs; }
 
        void Tick(double dt);
 
index a487b1a1637878c4c526ddd9c208061f3b1582d3..76455d9baace86214a3af03e4728cc8bd94a1e4d 100644 (file)
@@ -1,7 +1,6 @@
 #ifndef BLOBS_UI_CREATUREPANEL_HPP_
 #define BLOBS_UI_CREATUREPANEL_HPP_
 
-#include "Label.hpp"
 #include "Panel.hpp"
 
 
@@ -17,6 +16,9 @@ namespace graphics {
 }
 namespace ui {
 
+class Label;
+class Meter;
+
 class CreaturePanel {
 
 public:
@@ -36,11 +38,18 @@ public:
        void Draw(app::Assets &, graphics::Viewport &) noexcept;
 
 private:
+       void CreateNeeds();
+
+private:
+       const app::Assets &assets;
        creature::Creature *c;
 
        Label *name;
+       Panel *needs;
        Panel panel;
 
+       std::vector<Meter *> meters;
+
 };
 
 }
index 90ed738639e5761df8de90ee4a2817ab48cdc0f8..1bc7e86bc4f0de8e733818c5eb3bd427b556bf1c 100644 (file)
@@ -21,10 +21,10 @@ public:
        ~Label() override;
 
 public:
-       Label &Text(const std::string &);
-       Label &Font(const graphics::Font &);
-       Label &Foreground(const glm::vec4 &);
-       Label &Background(const glm::vec4 &);
+       Label *Text(const std::string &);
+       Label *Font(const graphics::Font &);
+       Label *Foreground(const glm::vec4 &);
+       Label *Background(const glm::vec4 &);
 
        glm::vec2 Size() override;
        void Draw(app::Assets &, graphics::Viewport &) noexcept override;
diff --git a/src/ui/Meter.hpp b/src/ui/Meter.hpp
new file mode 100644 (file)
index 0000000..12885e4
--- /dev/null
@@ -0,0 +1,46 @@
+#ifndef BLOBS_UI_METER_HPP_
+#define BLOBS_UI_METER_HPP_
+
+#include "Widget.hpp"
+
+
+namespace blobs {
+namespace ui {
+
+class Meter
+: public Widget {
+
+public:
+       Meter();
+       ~Meter() override;
+
+public:
+       Meter *Size(const glm::vec2 &s) noexcept { size = s; return this; }
+       Meter *Padding(const glm::vec2 &p) noexcept { padding = p; return this; }
+       // TODO: gl line width is deprecated, use polys instead
+       Meter *Border(float b) noexcept { border = b; return this; }
+
+       Meter *FillColor(const glm::vec4 &c) noexcept { fill_color = c; return this; }
+       Meter *BorderColor(const glm::vec4 &c) noexcept { border_color = c; return this; }
+
+       Meter *Value(float v) noexcept { value = v; return this; }
+
+       glm::vec2 Size() override;
+       void Draw(app::Assets &, graphics::Viewport &) noexcept override;
+
+private:
+       glm::vec4 fill_color;
+       glm::vec4 border_color;
+
+       glm::vec2 size;
+       glm::vec2 padding;
+       float border;
+
+       float value;
+
+};
+
+}
+}
+
+#endif
index d62073b4ce46caac5e0899adc5af7afac6a9d37c..926766191e9b709a72bda65e9456a741472b91e8 100644 (file)
@@ -18,6 +18,7 @@ public:
                HORIZONTAL,
                VERTICAL,
        };
+       using Children_t = std::vector<std::unique_ptr<Widget>>;
 
 public:
        Panel();
@@ -25,19 +26,22 @@ public:
 
 public:
        // panel takes ownership
-       Panel &Add(Widget *);
+       Panel *Add(Widget *);
+       Panel *Clear();
+       Panel *Reserve(int n) { widgets.reserve(n); return this; }
+       const Children_t &Children() const noexcept { return widgets; }
 
-       Panel &Background(const glm::vec4 &);
-       Panel &Padding(const glm::vec2 &);
-       Panel &Spacing(float);
-       Panel &Direction(Dir);
+       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<std::unique_ptr<Widget>> widgets;
+       Children_t widgets;
        glm::vec4 bg_color;
        glm::vec2 padding;
        float spacing;
index cb83da251dbd9311ef2e04cd79d8b7a842d534a0..ed7c84825ae0a4b3dcca098d765e34fb172d5da9 100644 (file)
@@ -27,12 +27,12 @@ public:
        Widget &operator =(Widget &&) = delete;
 
 public:
-       Widget &Position(const glm::vec3 &p) noexcept { pos = p; return *this; }
+       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; }
+       Widget *Origin(Gravity o) noexcept { origin = o; return this; }
        Gravity Origin() const noexcept { return origin; }
 
        virtual glm::vec2 Size() = 0;
index 31f0396a9072c2f3fc6e438f90f45bd801ea1026..a1b2f9a22801ac7f0c3badcde035b4cc8cc307dd 100644 (file)
@@ -1,5 +1,7 @@
 #include "CreaturePanel.hpp"
 
+#include "Label.hpp"
+#include "Meter.hpp"
 #include "../app/Assets.hpp"
 #include "../creature/Creature.hpp"
 #include "../graphics/Viewport.hpp"
@@ -11,16 +13,19 @@ namespace blobs {
 namespace ui {
 
 CreaturePanel::CreaturePanel(const app::Assets &assets)
-: c(nullptr)
+: assets(assets)
+, c(nullptr)
 , name(new Label(assets.fonts.large))
+, needs(new Panel)
 , 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);
+               ->Add(needs)
+               ->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() {
@@ -30,6 +35,34 @@ CreaturePanel::~CreaturePanel() {
 void CreaturePanel::Show(creature::Creature &cr) {
        c = &cr;
        name->Text(c->Name());
+       CreateNeeds();
+}
+
+void CreaturePanel::CreateNeeds() {
+       needs->Clear()->Reserve(c->Needs().size());
+       meters.clear();
+       meters.reserve(c->Needs().size());
+       for (auto &need : c->Needs()) {
+               Label *label = new Label(assets.fonts.medium);
+               label
+                       ->Text(assets.data.resources[need.resource].label);
+               Meter *meter = new Meter;
+               meter
+                       ->Value(1.0f - need.value)
+                       ->Size(glm::vec2(100.0f, assets.fonts.medium.Height()))
+                       ->Padding(glm::vec2(1.0f))
+                       ->Border(1.0f)
+                       ->FillColor(glm::vec4(0.0f, 0.0f, 0.0f, 1.0f))
+                       ->BorderColor(glm::vec4(0.0f, 0.0f, 0.0f, 1.0f));
+               Panel *need_panel = new Panel;
+               need_panel
+                       ->Direction(Panel::HORIZONTAL)
+                       ->Spacing(10.0f)
+                       ->Add(label)
+                       ->Add(meter);
+               needs->Add(need_panel);
+               meters.push_back(meter);
+       }
        panel.Relayout();
 }
 
@@ -40,6 +73,19 @@ void CreaturePanel::Hide() noexcept {
 void CreaturePanel::Draw(app::Assets &assets, graphics::Viewport &viewport) noexcept {
        if (!c) return;
 
+       if (meters.size() != c->Needs().size()) {
+               CreateNeeds();
+       } else {
+               auto need = c->Needs().begin();
+               auto need_end = c->Needs().end();
+               auto meter = meters.begin();
+               for (; need != need_end; ++need, ++meter) {
+                       (*meter)->Value(1.0f - need->value)->FillColor(need->IsSatisfied()
+                               ? glm::vec4(0.0f, 0.0f, 0.0f, 1.0f)
+                               : glm::vec4(1.0f, 0.0f, 0.0f, 1.0f));
+               }
+       }
+
        const glm::vec2 margin(20.0f);
 
        panel.Position(glm::vec3(viewport.Width() - margin.x, margin.y, 0.0f));
index 94c4182ec0c1911aecba6a56b58811ce61a3901e..ffaeab8317737e7bd659d09bbc3d874cd39227ed 100644 (file)
@@ -1,4 +1,5 @@
 #include "Label.hpp"
+#include "Meter.hpp"
 #include "Panel.hpp"
 #include "Widget.hpp"
 
@@ -24,30 +25,30 @@ Label::Label(const graphics::Font &f)
 Label::~Label() {
 }
 
-Label &Label::Text(const std::string &t) {
+Label *Label::Text(const std::string &t) {
        if (text != t) {
                dirty = true;
        }
        text = t;
-       return *this;
+       return this;
 }
 
-Label &Label::Font(const graphics::Font &f) {
+Label *Label::Font(const graphics::Font &f) {
        if (font != &f) {
                dirty = true;
        }
        font = &f;
-       return *this;
+       return this;
 }
 
-Label &Label::Foreground(const glm::vec4 &c) {
+Label *Label::Foreground(const glm::vec4 &c) {
        fg_color = c;
-       return *this;
+       return this;
 }
 
-Label &Label::Background(const glm::vec4 &c) {
+Label *Label::Background(const glm::vec4 &c) {
        bg_color = c;
-       return *this;
+       return this;
 }
 
 glm::vec2 Label::Size() {
@@ -78,6 +79,45 @@ void Label::Update() {
 }
 
 
+Meter::Meter()
+: fill_color(1.0f)
+, border_color(1.0f)
+, size(3.0f)
+, padding(1.0f)
+, border(1.0f)
+, value(0.0f) {
+}
+
+Meter::~Meter() {
+}
+
+glm::vec2 Meter::Size() {
+       return size + (2.0f * padding) + (2.0f * border);
+}
+
+void Meter::Draw(app::Assets &assets, graphics::Viewport &viewport) noexcept {
+       glm::vec2 fullsize = Size();
+       assets.shaders.plain_color.Activate();
+
+       if (border > 0.0f) {
+               assets.shaders.plain_color.SetM(glm::translate(AlignedPosition())
+                       * glm::scale(glm::vec3(fullsize.x, fullsize.y, 1.0f)));
+               assets.shaders.plain_color.SetColor(border_color);
+               assets.shaders.plain_color.OutlineRect();
+       }
+
+       if (value > 0.0f) {
+               glm::vec3 top_left(glm::vec2(TopLeft()) + padding + glm::vec2(border), Position().z);
+               glm::vec3 actual_size(size.x * value, size.y, 1.0f);
+
+               assets.shaders.plain_color.SetM(glm::translate(align(Gravity::NORTH_WEST, actual_size, top_left))
+                       * glm::scale(actual_size));
+               assets.shaders.plain_color.SetColor(fill_color);
+               assets.shaders.plain_color.DrawRect();
+       }
+}
+
+
 Panel::Panel()
 : widgets()
 , bg_color(0.0f, 0.0f, 0.0f, 0.0f)
@@ -90,7 +130,7 @@ Panel::Panel()
 Panel::~Panel() {
 }
 
-Panel &Panel::Add(Widget *w) {
+Panel *Panel::Add(Widget *w) {
        std::unique_ptr<Widget> widget(w);
        glm::vec2 wsize = widget->Size();
        if (dir == HORIZONTAL) {
@@ -101,32 +141,38 @@ Panel &Panel::Add(Widget *w) {
                size.y += wsize.y;
        }
        widgets.emplace_back(std::move(widget));
-       return *this;
+       return this;
+}
+
+Panel *Panel::Clear() {
+       widgets.clear();
+       size = glm::vec2(0.0f);
+       return this;
 }
 
-Panel &Panel::Background(const glm::vec4 &c) {
+Panel *Panel::Background(const glm::vec4 &c) {
        bg_color = c;
-       return *this;
+       return this;
 }
 
-Panel &Panel::Padding(const glm::vec2 &p) {
+Panel *Panel::Padding(const glm::vec2 &p) {
        padding = p;
-       return *this;
+       return this;
 }
 
-Panel &Panel::Spacing(float s) {
+Panel *Panel::Spacing(float s) {
        spacing = s;
-       return *this;
+       return this;
 }
 
-Panel &Panel::Direction(Dir d) {
+Panel *Panel::Direction(Dir d) {
        dir = d;
        Relayout();
-       return *this;
+       return this;
 }
 
 glm::vec2 Panel::Size() {
-       return 2.0f * padding + glm::vec2(0.0f, (widgets.size() - 1) * spacing) + size;
+       return (2.0f * padding) + glm::vec2(0.0f, (widgets.size() - 1) * spacing) + size;
 }
 
 void Panel::Relayout() {
@@ -161,7 +207,7 @@ void Panel::Draw(app::Assets &assets, graphics::Viewport &viewport) noexcept {
        cursor.y += padding.y;
        cursor.z -= 1.0f;
        for (auto &w : widgets) {
-               w->Position(cursor).Origin(Gravity::NORTH_WEST);
+               w->Position(cursor)->Origin(Gravity::NORTH_WEST);
                w->Draw(assets, viewport);
                cursor[dir] += w->Size()[dir] + spacing;
        }