]> git.localhorst.tv Git - ffmpeg-test.git/commitdiff
show multiple messages
authorDaniel Karbach <daniel.karbach@localhorst.tv>
Wed, 2 Oct 2024 12:04:10 +0000 (14:04 +0200)
committerDaniel Karbach <daniel.karbach@localhorst.tv>
Wed, 2 Oct 2024 12:04:10 +0000 (14:04 +0200)
src/app/Message.h [new file with mode: 0644]
src/app/Renderer.h
src/cairo/Context.h
src/gfx/ColorRGB.h [new file with mode: 0644]
src/gfx/Position.h [new file with mode: 0644]
src/gfx/Rectangle.h [new file with mode: 0644]
src/gfx/Size.h [new file with mode: 0644]
src/gfx/Spacing.h [new file with mode: 0644]
src/main.cpp
src/ws/Connection.cpp

diff --git a/src/app/Message.h b/src/app/Message.h
new file mode 100644 (file)
index 0000000..30fbc81
--- /dev/null
@@ -0,0 +1,106 @@
+#ifndef TEST_APP_MESSAGE_H_
+#define TEST_APP_MESSAGE_H_
+
+#include <string>
+
+#include "../cairo/Context.h"
+#include "../gfx/ColorRGB.h"
+#include "../gfx/Position.h"
+#include "../gfx/Size.h"
+#include "../gfx/Spacing.h"
+#include "../pango/Layout.h"
+
+namespace app {
+
+class Message {
+
+public:
+       Message(cairo::Context &ctx)
+       : ctx(ctx)
+       , text_layout(ctx.CreateLayout())
+       , channel_layout(ctx.CreateLayout())
+       , bg_color{0.1, 0.1, 0.1}
+       , text_color{1, 1, 1}
+       , channel_color{0.392, 0.255, 0.647}
+       , padding(10) {
+       }
+       ~Message() {
+       }
+
+       Message(const Message &) = delete;
+       Message &operator =(const Message &) = delete;
+
+public:
+       void SetTextFont(pango::Font &font) {
+               text_layout.SetFont(font);
+       }
+
+       void SetChannelFont(pango::Font &font) {
+               channel_layout.SetFont(font);
+       }
+
+       void SetWidth(double width) {
+               size.w = width;
+               int inner_width = width - padding.left - padding.right;
+               text_layout.SetWidth(inner_width);
+               channel_layout.SetWidth(inner_width);
+       }
+
+       void SetText(const std::string &t) {
+               text_layout.SetText(t);
+       }
+
+       void SetChannel(const std::string &c) {
+               channel_layout.SetText(c);
+       }
+
+       void SetPosition(const gfx::Position &p) {
+               pos = p;
+       }
+
+       double GetHeight() const {
+               return size.h;
+       }
+
+       void Update() {
+               text_layout.Update();
+               channel_layout.Update();
+               text_offset = padding.Offset();
+               channel_offset = text_offset;
+               channel_offset.y += text_layout.GetLogicalRect().height + 10.0;
+               size.h = channel_offset.y + channel_layout.GetLogicalRect().height + padding.bottom;
+       }
+
+       void Render() {
+               ctx.SetSourceColor(bg_color);
+               ctx.Rectangle(pos, size);
+               ctx.Fill();
+
+               ctx.MoveTo(pos + text_offset);
+               ctx.SetSourceColor(text_color);
+               text_layout.Render();
+
+               ctx.MoveTo(pos + channel_offset);
+               ctx.SetSourceColor(channel_color);
+               channel_layout.Render();
+       }
+
+private:
+       cairo::Context ctx;
+       pango::Layout text_layout;
+       pango::Layout channel_layout;
+       gfx::ColorRGB bg_color;
+       gfx::ColorRGB text_color;
+       gfx::ColorRGB channel_color;
+
+       gfx::Position pos;
+       gfx::Size size;
+       gfx::Spacing padding;
+       gfx::Position text_offset;
+       gfx::Position channel_offset;
+
+};
+
+}
+
+#endif
index b31c73c2f58f25f648c2b062493f48a9e72a40a7..a74c7c8d02b229319e05338c4dd3775f8f800747 100644 (file)
@@ -2,14 +2,15 @@
 #define TEST_APP_RENDERER_H_
 
 #include <cstdint>
-#include <iostream>
+#include <list>
+
 extern "C" {
 #include "cairo.h"
 }
 
+#include "Message.h"
 #include "../cairo/Context.h"
 #include "../cairo/Surface.h"
-#include "../pango/Layout.h"
 
 namespace app {
 
@@ -22,17 +23,8 @@ public:
        , surface(plane, linesize, CAIRO_FORMAT_ARGB32, width, height)
        , ctx(surface.CreateContext())
        , width(width)
-       , height(height)
-       , text()
-       , text_layout(ctx.CreateLayout())
-       , channel()
-       , channel_layout(ctx.CreateLayout()) {
-               text_layout.SetFont(text_font);
-               text_layout.SetWidth(width / 2);
-               channel_layout.SetFont(channel_font);
-               channel_layout.SetWidth(width / 2);
-               SetText("Hello, I am a long text that should wrap eventually when it gets long enough to cross the halfway point of the total width available (not including the offset which is added afterwards).");
-               SetChannel("");
+       , height(height) {
+               PushMessage("Hello, I am a long text that should wrap eventually when it gets long enough to cross the halfway point of the total width available (not including the offset which is added afterwards).", "The Dummy Channel");
        }
        ~Renderer() {
        }
@@ -45,30 +37,32 @@ public:
                ctx.SetSourceRGB(0, 0, 0);
                ctx.Paint();
 
-               ctx.MoveTo(50, 50);
-               ctx.SetSourceRGB(1, 1, 1);
-               text_layout.Render();
-
-               ctx.MoveTo(50, 50 + text_layout.GetLogicalRect().height + 10);
-               ctx.SetSourceRGB(0.392, 0.255, 0.647);
-               channel_layout.Render();
+               for (Message &msg : msgs) {
+                       msg.Render();
+               }
 
                surface.Flush();
        }
 
-       void SetText(const std::string &t) {
-               text = t;
-               text_layout.SetText(text);
-               text_layout.Update();
+       void PushMessage(const std::string &text, const std::string &channel) {
+               msgs.emplace_front(ctx);
+               Message &msg = msgs.front();
+               msg.SetTextFont(text_font);
+               msg.SetChannelFont(channel_font);
+               msg.SetWidth(width / 2.0);
+               msg.SetText(text);
+               msg.SetChannel(channel);
+               msg.Update();
+               if (msgs.size() > 3) {
+                       msgs.pop_back();
+               }
+               gfx::Position pos({ 50, 50 });
+               for (Message &msg : msgs) {
+                       msg.SetPosition(pos);
+                       pos.y += msg.GetHeight() + 10.0;
+               }
        }
 
-       void SetChannel(const std::string &c) {
-               channel = c;
-               channel_layout.SetText(channel);
-               channel_layout.Update();
-       }
-
-
 private:
        pango::Font text_font;
        pango::Font channel_font;
@@ -78,10 +72,7 @@ private:
        int width;
        int height;
 
-       std::string text;
-       pango::Layout text_layout;
-       std::string channel;
-       pango::Layout channel_layout;
+       std::list<Message> msgs;
 
 };
 
index 6824820faacf20b54b968605b191037a30d0d0ea..e34548e1c0010525707555eba91fffc3892c499b 100644 (file)
@@ -4,9 +4,14 @@
 #include <cairo.h>
 #include <iostream>
 #include <ostream>
+#include <utility>
 
 #include "Error.h"
 #include "Face.h"
+#include "../gfx/ColorRGB.h"
+#include "../gfx/Position.h"
+#include "../gfx/Rectangle.h"
+#include "../gfx/Size.h"
 #include "../pango/Layout.h"
 
 namespace cairo {
@@ -27,9 +32,16 @@ public:
        }
        Context(Context &&other): ctx(cairo_reference(other.ctx)) {
        }
-
-       Context(const Context &) = delete;
-       Context &operator =(const Context &) = delete;
+       Context(const Context &other): ctx(cairo_reference(other.ctx)) {
+       }
+       Context &operator =(const Context &other) {
+               Context temp(other);
+               Swap(temp);
+               return *this;
+       }
+       void Swap(Context &other) {
+               std::swap(ctx, other.ctx);
+       }
 
 public:
        pango::Layout CreateLayout() {
@@ -49,10 +61,18 @@ public:
                cairo_text_extents(ctx, text, &extends);
        }
 
+       void MoveTo(const gfx::Position &pos) {
+               MoveTo(pos.x, pos.y);
+       }
+
        void MoveTo(double x, double y) {
                cairo_move_to(ctx, x, y);
        }
 
+       void LineTo(const gfx::Position &pos) {
+               LineTo(pos.x, pos.y);
+       }
+
        void LineTo(double x, double y) {
                cairo_line_to(ctx, x, y);
        }
@@ -65,6 +85,14 @@ public:
                cairo_paint_with_alpha(ctx, alpha);
        }
 
+       void Rectangle(const gfx::Rectangle &r) {
+               Rectangle(r.x, r.y, r.w, r.h);
+       }
+
+       void Rectangle(const gfx::Position &pos, const gfx::Size &size) {
+               Rectangle(pos.x, pos.y, size.w, size.h);
+       }
+
        void Rectangle(double x, double y, double w, double h) {
                cairo_rectangle(ctx, x, y, w, h);
        }
@@ -85,6 +113,10 @@ public:
                cairo_set_line_width(ctx, width);
        }
 
+       void SetSourceColor(const gfx::ColorRGB &color) {
+               SetSourceRGB(color.r, color.g, color.b);
+       }
+
        void SetSourceRGB(double r, double g, double b) {
                cairo_set_source_rgb(ctx, r, g, b);
        }
@@ -108,4 +140,13 @@ private:
 
 }
 
+namespace std {
+
+template<>
+inline void swap<cairo::Context>(cairo::Context &a, cairo::Context &b) {
+       a.Swap(b);
+}
+
+}
+
 #endif
diff --git a/src/gfx/ColorRGB.h b/src/gfx/ColorRGB.h
new file mode 100644 (file)
index 0000000..2d30fbf
--- /dev/null
@@ -0,0 +1,16 @@
+#ifndef TEST_GFX_COLORRGB_H_
+#define TEST_GFX_COLORRGB_H_
+
+namespace gfx {
+
+struct ColorRGB {
+
+       double r = 0.0;
+       double g = 0.0;
+       double b = 0.0;
+
+};
+
+}
+
+#endif
diff --git a/src/gfx/Position.h b/src/gfx/Position.h
new file mode 100644 (file)
index 0000000..380e67b
--- /dev/null
@@ -0,0 +1,25 @@
+#ifndef TEST_GFX_POSITION_H_
+#define TEST_GFX_POSITION_H_
+
+#include <ostream>
+
+namespace gfx {
+
+struct Position {
+
+       double x = 0.0;
+       double y = 0.0;
+
+};
+
+}
+
+inline gfx::Position operator +(const gfx::Position &a, const gfx::Position &b) {
+       return gfx::Position{a.x + b.x, a.y + b.y};
+}
+
+inline std::ostream &operator <<(std::ostream &out, const gfx::Position &pos) {
+       return out << '(' << pos.x << ", " << pos.y << ')';
+}
+
+#endif
diff --git a/src/gfx/Rectangle.h b/src/gfx/Rectangle.h
new file mode 100644 (file)
index 0000000..bd14cb5
--- /dev/null
@@ -0,0 +1,23 @@
+#ifndef TEST_GFX_RECTANGLE_H_
+#define TEST_GFX_RECTANGLE_H_
+
+#include "Position.h"
+
+namespace gfx {
+
+struct Rectangle {
+
+       double x = 0.0;
+       double y = 0.0;
+       double w = 0.0;
+       double h = 0.0;
+
+       Position Position() const {
+               return gfx::Position{x, y};
+       }
+
+};
+
+}
+
+#endif
diff --git a/src/gfx/Size.h b/src/gfx/Size.h
new file mode 100644 (file)
index 0000000..3ab08e2
--- /dev/null
@@ -0,0 +1,21 @@
+#ifndef TEST_GFX_SIZE_H_
+#define TEST_GFX_SIZE_H_
+
+#include <ostream>
+
+namespace gfx {
+
+struct Size {
+
+       double w = 0.0;
+       double h = 0.0;
+
+};
+
+}
+
+inline std::ostream &operator <<(std::ostream &out, const gfx::Size &size) {
+       return out << size.w << 'x' << size.h;
+}
+
+#endif
diff --git a/src/gfx/Spacing.h b/src/gfx/Spacing.h
new file mode 100644 (file)
index 0000000..d6f0bf8
--- /dev/null
@@ -0,0 +1,30 @@
+#ifndef TEST_GFX_SPACING_H_
+#define TEST_GFX_SPACING_H_
+
+#include "Position.h"
+
+namespace gfx {
+
+struct Spacing {
+
+       double left = 0.0;
+       double top = 0.0;
+       double bottom = 0.0;
+       double right = 0.0;
+
+       explicit Spacing(double all)
+       : left(all), top(all), bottom(all), right(all) {
+       }
+       Spacing(double horiz, double vert)
+       : left(horiz), top(vert), bottom(horiz), right(vert) {
+       }
+
+       Position Offset() const {
+               return Position{left, top};
+       }
+
+};
+
+}
+
+#endif
index 31cfa98136bf9433ea04e89fead81194df1008a5..862628577d6a55601caff3450cc61ab2ebe3814a 100644 (file)
@@ -41,8 +41,7 @@ void ws_handler(void *user, const Json::Value &json) {
        const std::string text = data["model"]["text"].asString();
        const std::string channel = data["model"]["channel"]["title"].asString();
        if (text.length() > 0) {
-               renderer->SetText(text);
-               renderer->SetChannel(channel);
+               renderer->PushMessage(text, channel);
        }
 }
 
index 6debd2844721481178be988ba8ecec10ec2b2225..a11131833a56464150f20a6ac773b81f20b6d7c5 100644 (file)
@@ -63,6 +63,7 @@ int Connection::ProtoCallback(lws_callback_reasons reason, void *in, size_t len)
                        Ping();
                        lws_set_timer_usecs(wsi, 30000000);
                        break;
+               case LWS_CALLBACK_CLIENT_RECEIVE_PONG:
                case LWS_CALLBACK_CLIENT_HTTP_BIND_PROTOCOL:
                case LWS_CALLBACK_CLIENT_HTTP_DROP_PROTOCOL:
                case LWS_CALLBACK_WS_CLIENT_BIND_PROTOCOL: