aboutsummaryrefslogtreecommitdiff
path: root/include
diff options
context:
space:
mode:
authordec05eba <dec05eba@protonmail.com>2018-04-22 05:58:44 +0200
committerdec05eba <dec05eba@protonmail.com>2018-04-22 05:59:18 +0200
commit1e0e68f9cda51c881b32a54d9eece71c1428f7ac (patch)
treeb8faa1d971c245e3fcf046aa1d2daa1fa601e0f9 /include
parent424b02609fa34175a4e2aadb95e68b3c9c8dc93c (diff)
Add video and gif support
Gif streams from url. Todo: Add play controls to video
Diffstat (limited to 'include')
-rw-r--r--include/Cache.hpp14
-rw-r--r--include/Channel.hpp3
-rw-r--r--include/Chatbar.hpp9
-rw-r--r--include/FileUtil.hpp18
-rw-r--r--include/Gif.hpp47
-rw-r--r--include/Message.hpp6
-rw-r--r--include/MessageBoard.hpp1
-rw-r--r--include/MessagePart.hpp7
-rw-r--r--include/StringView.hpp62
-rw-r--r--include/Video.hpp45
10 files changed, 205 insertions, 7 deletions
diff --git a/include/Cache.hpp b/include/Cache.hpp
index 59d997a..0314e7e 100644
--- a/include/Cache.hpp
+++ b/include/Cache.hpp
@@ -14,6 +14,8 @@ namespace TinyProcessLib
namespace dchat
{
+ class Gif;
+
struct ImageByUrlResult
{
enum class Type
@@ -23,9 +25,19 @@ namespace dchat
FAILED_DOWNLOAD
};
+ ImageByUrlResult() : texture(nullptr), type(Type::DOWNLOADING), isGif(false) {}
+ ImageByUrlResult(sf::Texture *_texture, Type _type) : texture(_texture), type(_type), isGif(false) {}
+ ImageByUrlResult(Gif *_gif, Type _type) : gif(_gif), type(_type), isGif(true) {}
+
// @texture is null if @type is DOWNLOADING or FAILED_DOWNLOAD
- sf::Texture *texture;
+ union
+ {
+ sf::Texture *texture;
+ Gif *gif;
+ };
+
Type type;
+ bool isGif;
};
class Cache
diff --git a/include/Channel.hpp b/include/Channel.hpp
index fa52a4b..b70803c 100644
--- a/include/Channel.hpp
+++ b/include/Channel.hpp
@@ -13,6 +13,9 @@ namespace dchat
Channel();
~Channel();
+ User* getLocalUser();
+ MessageBoard& getMessageBoard();
+
void processEvent(const sf::Event &event);
void draw(sf::RenderWindow &window, Cache &cache);
private:
diff --git a/include/Chatbar.hpp b/include/Chatbar.hpp
index 143ebba..d24b2af 100644
--- a/include/Chatbar.hpp
+++ b/include/Chatbar.hpp
@@ -3,9 +3,13 @@
#include <SFML/Graphics/Text.hpp>
#include <SFML/Graphics/RenderWindow.hpp>
#include <SFML/Graphics/RectangleShape.hpp>
+#include <SFML/Window/Event.hpp>
+#include <SFML/System/Clock.hpp>
namespace dchat
{
+ class Channel;
+
class Chatbar
{
public:
@@ -20,11 +24,16 @@ namespace dchat
void moveCaretLeft();
void moveCaretRight();
+ bool isFocused() const;
+
+ void processEvent(const sf::Event &event, Channel *channel);
void draw(sf::RenderWindow &window);
private:
sf::Text text;
sf::RectangleShape background;
int caretIndex;
sf::Vector2f caretOffset;
+ sf::Clock blinkTimer;
+ bool focused;
};
}
diff --git a/include/FileUtil.hpp b/include/FileUtil.hpp
new file mode 100644
index 0000000..0cfc808
--- /dev/null
+++ b/include/FileUtil.hpp
@@ -0,0 +1,18 @@
+#pragma once
+
+#include "StringView.hpp"
+#include <boost/filesystem/path.hpp>
+#include <stdexcept>
+
+namespace dchat
+{
+ class FileException : public std::runtime_error
+ {
+ public:
+ FileException(const std::string &errMsg) : std::runtime_error(errMsg) {}
+ };
+
+ // Throws FileException on error.
+ // Returned value is allocated with malloc and should be free'd by caller.
+ StringView getFileContent(const boost::filesystem::path &filepath);
+}
diff --git a/include/Gif.hpp b/include/Gif.hpp
new file mode 100644
index 0000000..1a69a52
--- /dev/null
+++ b/include/Gif.hpp
@@ -0,0 +1,47 @@
+#pragma once
+
+#include "StringView.hpp"
+#include <SFML/Graphics/RenderWindow.hpp>
+#include <SFML/Graphics/Texture.hpp>
+#include <SFML/Graphics/Sprite.hpp>
+#include <SFML/System/Clock.hpp>
+#include <boost/filesystem/path.hpp>
+#include <stdexcept>
+extern "C"
+{
+#include <libnsgif.h>
+}
+
+namespace dchat
+{
+ class GifLoadException : public std::runtime_error
+ {
+ public:
+ GifLoadException(const std::string &errMsg) : std::runtime_error(errMsg) {}
+ };
+
+ class Gif
+ {
+ public:
+ // Throws GifLoadException on error
+ Gif(const boost::filesystem::path &filepath);
+ Gif(StringView &&fileContent);
+ ~Gif();
+
+ void setPosition(const sf::Vector2f &position);
+ void setSize(const sf::Vector2f &size);
+ void draw(sf::RenderWindow &window);
+
+ static bool isDataGif(const StringView &data);
+ private:
+ void init();
+ private:
+ gif_animation gif;
+ StringView fileContent;
+ unsigned int currentFrame;
+ sf::Sprite sprite;
+ sf::Texture texture;
+ double timeElapsedCs;
+ sf::Clock frameTimer;
+ };
+}
diff --git a/include/Message.hpp b/include/Message.hpp
index efc1f4c..7cd7fdf 100644
--- a/include/Message.hpp
+++ b/include/Message.hpp
@@ -13,10 +13,12 @@ namespace dchat
Message(User *user);
virtual ~Message();
- void addText(const std::string &text);
- void addImage(const std::string &url);
+ void addText(const std::string &text, bool newLine = true);
+ void addEmoji(const std::string &url, bool newLine = true);
std::vector<MessagePart*>& getParts();
+ static Message* buildFromString(User *user, const std::string &str);
+
const User *user;
private:
std::vector<MessagePart*> messageParts;
diff --git a/include/MessageBoard.hpp b/include/MessageBoard.hpp
index 105d675..c510164 100644
--- a/include/MessageBoard.hpp
+++ b/include/MessageBoard.hpp
@@ -22,7 +22,6 @@ namespace dchat
void draw(sf::RenderWindow &window, Cache &cache);
private:
sf::RenderTexture staticContentTexture;
- bool useStaticContentTexture;
bool dirty;
bool selectingText;
bool leftMouseButtonPressed;
diff --git a/include/MessagePart.hpp b/include/MessagePart.hpp
index d0a0a03..00544fb 100644
--- a/include/MessagePart.hpp
+++ b/include/MessagePart.hpp
@@ -16,7 +16,7 @@ namespace dchat
EMOJI
};
- MessagePart(Type _type) : type(_type) {}
+ MessagePart(Type _type, bool _newLine) : type(_type), newLine(_newLine) {}
virtual ~MessagePart(){}
static float getSizeScaled();
@@ -24,12 +24,13 @@ namespace dchat
virtual sf::Vector2f getSize() const = 0;
const Type type;
+ bool newLine;
};
class MessagePartText : public MessagePart
{
public:
- MessagePartText(const std::string &text);
+ MessagePartText(const std::string &text, bool newLine);
static float getFontSizeScaled();
virtual sf::Vector2f getPosition() const override;
@@ -41,7 +42,7 @@ namespace dchat
class MessagePartEmoji : public MessagePart
{
public:
- MessagePartEmoji(const std::string &url);
+ MessagePartEmoji(const std::string &url, bool newLine);
static float getHeightScaled();
virtual sf::Vector2f getPosition() const override;
diff --git a/include/StringView.hpp b/include/StringView.hpp
new file mode 100644
index 0000000..3293358
--- /dev/null
+++ b/include/StringView.hpp
@@ -0,0 +1,62 @@
+#pragma once
+
+#include "types.hpp"
+#include <cstring>
+#include <cassert>
+
+namespace dchat
+{
+ class StringView
+ {
+ public:
+ StringView() : data(nullptr), size(0)
+ {
+
+ }
+
+ StringView(const StringView &other) : data(other.data), size(other.size)
+ {
+
+ }
+
+ StringView(const char *_data) : data(_data), size(strlen(_data))
+ {
+
+ }
+
+ StringView(const char *_data, usize _size) : data(_data), size(_size)
+ {
+
+ }
+
+ StringView operator = (const StringView &other)
+ {
+ StringView result(other.data, other.size);
+ return result;
+ }
+
+ StringView(StringView &&other)
+ {
+ data = other.data;
+ size = other.size;
+
+ other.data = nullptr;
+ other.size = 0;
+ }
+
+ bool equals(const StringView &other) const
+ {
+ if(size != other.size) return false;
+ return memcmp(data, other.data, size) == 0;
+ }
+
+ char operator [] (usize index) const
+ {
+ assert(index < size);
+ return data[index];
+ }
+
+ const char *data;
+ usize size;
+ };
+}
diff --git a/include/Video.hpp b/include/Video.hpp
new file mode 100644
index 0000000..f148c07
--- /dev/null
+++ b/include/Video.hpp
@@ -0,0 +1,45 @@
+#pragma once
+
+#include <SFML/Graphics/RenderWindow.hpp>
+#include <SFML/Graphics/Texture.hpp>
+#include <SFML/Graphics/Sprite.hpp>
+#include <SFML/Window/Context.hpp>
+#include <thread>
+#include <mutex>
+#include <atomic>
+#include <stdexcept>
+
+class mpv_handle;
+class mpv_render_context;
+
+namespace dchat
+{
+ class VideoInitializationException : public std::runtime_error
+ {
+ public:
+ VideoInitializationException(const std::string &errMsg) : std::runtime_error(errMsg) {}
+ };
+
+ class Video
+ {
+ public:
+ // Throws VideoInitializationException on error
+ Video(unsigned int width, unsigned int height, const char *file, bool loop = false);
+ ~Video();
+
+ void setPosition(float x, float y);
+ void draw(sf::RenderWindow &window);
+
+ // This counter is incremented when mpv wants to redraw content
+ std::atomic_int redrawCounter;
+ private:
+ sf::Context context;
+ mpv_handle *mpv;
+ mpv_render_context *mpvGl;
+ std::thread renderThread;
+ std::mutex renderMutex;
+ sf::Sprite sprite;
+ sf::Texture texture;
+ sf::Uint8 *textureBuffer;
+ };
+}