X-Git-Url: https://git.localhorst.tv/?a=blobdiff_plain;ds=sidebyside;f=src%2Fui%2Fui.cpp;h=cedbcd127be0273798ab294b699c2cd40d128403;hb=c51b3bbef5c9b8ab52f55d46f08c5992fe574f70;hp=f7a102eaf73e1b3b85cc2d4b7704ccb8f0163336;hpb=76b630bd0a147bf7c78d3380237c86b9bfc48530;p=blobs.git diff --git a/src/ui/ui.cpp b/src/ui/ui.cpp index f7a102e..cedbcd1 100644 --- a/src/ui/ui.cpp +++ b/src/ui/ui.cpp @@ -1,22 +1,47 @@ #include "CreaturePanel.hpp" +#include "Label.hpp" +#include "Meter.hpp" #include "../app/Assets.hpp" #include "../creature/Creature.hpp" +#include "../creature/Need.hpp" #include "../graphics/Viewport.hpp" #include -#include -#include - namespace blobs { namespace ui { CreaturePanel::CreaturePanel(const app::Assets &assets) -: c(nullptr) -, name(assets.fonts.large) { - name.Origin(Gravity::NORTH_EAST); +: assets(assets) +, c(nullptr) +, name(new Label(assets.fonts.large)) +, needs(new Panel) +, panel() +, health_meter(new Meter) +, need_meters() { + Label *health_label = new Label(assets.fonts.medium); + health_label->Text("Health"); + health_meter + ->Size(glm::vec2(100.0f, assets.fonts.medium.Height() + assets.fonts.medium.Descent())) + ->Padding(glm::vec2(1.0f)) + ->Border(1.0f) + ->FillColor(glm::vec4(0.9f, 0.0f, 0.0f, 1.0f)) + ->BorderColor(glm::vec4(0.0f, 0.0f, 0.0f, 1.0f)); + Panel *health_panel = new Panel; + health_panel + ->Add(health_label) + ->Add(health_meter) + ->Direction(Panel::HORIZONTAL); + panel + .Add(name) + ->Add(health_panel) + ->Add(needs) + ->Padding(glm::vec2(10.0f)) + ->Spacing(10.0f) + ->Direction(Panel::VERTICAL) + ->Background(glm::vec4(0.7f, 0.7f, 0.7f, 1.0f)); } CreaturePanel::~CreaturePanel() { @@ -25,7 +50,35 @@ CreaturePanel::~CreaturePanel() { void CreaturePanel::Show(creature::Creature &cr) { c = &cr; - name.Text(c->Name()); + name->Text(c->Name()); + CreateNeeds(); +} + +void CreaturePanel::CreateNeeds() { + needs->Clear()->Reserve(c->Needs().size()); + need_meters.clear(); + need_meters.reserve(c->Needs().size()); + for (auto &need : c->Needs()) { + Label *label = new Label(assets.fonts.medium); + label->Text(need->name); + Meter *meter = new Meter; + meter + ->Value(1.0f - need->value) + ->Size(glm::vec2(100.0f, assets.fonts.medium.Height() + assets.fonts.medium.Descent())) + ->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); + need_meters.push_back(meter); + } + panel.Relayout(); } void CreaturePanel::Hide() noexcept { @@ -35,91 +88,30 @@ void CreaturePanel::Hide() noexcept { void CreaturePanel::Draw(app::Assets &assets, graphics::Viewport &viewport) noexcept { 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; + health_meter->Value(c->Health()); + + if (need_meters.size() != c->Needs().size()) { + CreateNeeds(); + } else { + auto need = c->Needs().begin(); + auto need_end = c->Needs().end(); + auto meter = need_meters.begin(); + for (; need != need_end; ++need, ++meter) { + (*meter)->Value(1.0f - (*need)->value); + if ((*need)->IsSatisfied()) { + (*meter)->FillColor(glm::vec4(0.0f, 0.7f, 0.0f, 1.0f)); + } else if ((*need)->IsInconvenient()) { + (*meter)->FillColor(glm::vec4(0.7f, 0.5f, 0.0f, 1.0f)); + } else { + (*meter)->FillColor(glm::vec4(0.9f, 0.0f, 0.0f, 1.0f)); + } + } } - 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(); -} + const glm::vec2 margin(20.0f); -void Label::Update() { - if (!dirty) return; - font->Render(text, tex); - dirty = false; + panel.Position(glm::vec2(viewport.Width() - margin.x - panel.Size().x, margin.y)); + panel.Draw(assets, viewport); } }