#include "Text.hpp"
#include "../graphics/align.hpp"
+#include "../graphics/PrimitiveMesh.hpp"
#include <deque>
#include <string>
void Position(const glm::vec3 &, Gravity) noexcept;
void Foreground(const glm::vec4 &col) noexcept { fg = col; }
- void Background(const glm::vec4 &col) noexcept { bg = col; }
+ void Background(const glm::vec4 &col) noexcept { bg = col; dirty = true; }
void PushLine(const char *);
void PushLine(const std::string &l) {
void Render(Viewport &) noexcept;
+private:
+ void Recalc();
+
private:
const Font &font;
std::deque<Text> lines;
glm::vec3 pos;
glm::vec3 adv;
+ glm::vec2 size;
glm::vec4 bg;
glm::vec4 fg;
+ PrimitiveMesh bg_mesh;
+
Gravity grav;
+ bool dirty;
};
, adv(0.0f, font.LineSkip(), 0.0f)
, bg(1.0f, 1.0f, 1.0f, 0.0f)
, fg(1.0f, 1.0f, 1.0f, 1.0f)
-, grav(Gravity::NORTH_WEST) {
+, grav(Gravity::NORTH_WEST)
+, dirty(true) {
}
for (Text &txt : lines) {
txt.Pivot(g);
}
+ dirty = true;
}
void MessageBox::PushLine(const char *text) {
while (lines.size() > max_lines) {
lines.pop_back();
}
+ dirty = true;
+}
+
+namespace {
+
+PrimitiveMesh::Buffer bg_buf;
+
+}
+
+void MessageBox::Recalc() {
+ size = glm::vec2(0.0f, 0.0f);
+ for (const Text &line : lines) {
+ size.x = std::max(size.x, line.Size().x);
+ size.y += line.Size().y;
+ }
+ bg_buf.FillRect(size.x, size.y, bg, align(grav, size));
+ bg_mesh.Update(bg_buf);
+ bg_buf.Clear();
+ dirty = false;
}
void MessageBox::Render(Viewport &viewport) noexcept {
+ viewport.SetCursor(pos, grav);
+ if (bg.a > std::numeric_limits<float>::epsilon()) {
+ if (dirty) {
+ Recalc();
+ }
+ PlainColor &prog = viewport.HUDColorProgram();
+ prog.SetM(viewport.Cursor());
+ bg_mesh.DrawTriangles();
+ viewport.MoveCursor(glm::vec3(0.0f, 0.0f, -1.0f));
+ }
BlendedSprite &prog = viewport.SpriteProgram();
- prog.SetBG(bg);
+ prog.SetBG(glm::vec4(0.0f));
prog.SetFG(fg);
- viewport.SetCursor(pos, grav);
for (Text &txt : lines) {
prog.SetM(viewport.Cursor());
txt.Render(viewport);