diff options
-rw-r--r-- | include/Window.hpp | 22 | ||||
-rw-r--r-- | src/LoginWindow.cpp | 2 | ||||
-rw-r--r-- | src/Window.cpp | 119 |
3 files changed, 141 insertions, 2 deletions
diff --git a/include/Window.hpp b/include/Window.hpp index 29ec285..236affa 100644 --- a/include/Window.hpp +++ b/include/Window.hpp @@ -6,6 +6,8 @@ #include <gtkmm/stack.h> #include <odhtdb/Database.hpp> #include <mutex> +#include <random> +#include <vector> namespace dchat { @@ -15,10 +17,30 @@ namespace dchat Window(); virtual ~Window(); private: + bool drawBackground(const Cairo::RefPtr<Cairo::Context> &cairo); + private: std::unique_ptr<odhtdb::Database> database; std::mutex databaseCallbackMutex; Gtk::Stack stack; LoginWindow loginWindow; ChatWindow chatWindow; + + struct Node + { + double radius; + double originalPosX; + double originalPosY; + + double currentPosX; + double currentPosY; + + double targetPosX; + double targetPosY; + }; + + std::mt19937 backgroundRng; + std::vector<Node> backgroundNodes; + int prevTimeMillis; + sigc::connection drawBackgroundConnection; }; }
\ No newline at end of file diff --git a/src/LoginWindow.cpp b/src/LoginWindow.cpp index 33802f1..a1aa105 100644 --- a/src/LoginWindow.cpp +++ b/src/LoginWindow.cpp @@ -101,6 +101,7 @@ namespace dchat { loginLayout.hide(); registerLayout.show_all(); + get_window()->invalidate(true); return true; }); loginLayout.attach_next_to(*eventBox, *registerText, Gtk::POS_RIGHT, 1, 1); @@ -181,6 +182,7 @@ namespace dchat { registerLayout.hide(); loginLayout.show_all(); + get_window()->invalidate(true); return true; }); registerLayout.attach_next_to(*eventBox, *loginText, Gtk::POS_RIGHT, 1, 1); diff --git a/src/Window.cpp b/src/Window.cpp index 970242d..208c616 100644 --- a/src/Window.cpp +++ b/src/Window.cpp @@ -3,9 +3,14 @@ #include "../include/ChannelDataType.hpp" #include "../include/WindowNotification.hpp" #include <sibs/SafeDeserializer.hpp> +#include <math.h> +#include <chrono> namespace dchat { + const int nodesPerColumn = 5; + const int nodesPerRow = 5; + Window::Window() { set_border_width(0); @@ -29,7 +34,6 @@ namespace dchat loginWindow.setLoginHandler([this, windowNotification](const Glib::ustring &username, const Glib::ustring &password) { - std::lock_guard<std::mutex> lock(databaseCallbackMutex); if(!database) { windowNotification->show("You are not connected to the bootstrap node yet! please wait..."); @@ -41,6 +45,7 @@ namespace dchat fprintf(stderr, "Trying to login with username %s\n", username.raw().c_str()); auto storedNodes = database->getStoredNodeUserInfoDecrypted(username.raw(), password.raw()); windowNotification->show(Glib::ustring("Successfully logged in as ") + username); + drawBackgroundConnection.disconnect(); stack.set_visible_child(chatWindow); for(auto &nodeInfo : storedNodes) @@ -58,7 +63,6 @@ namespace dchat loginWindow.setRegisterHandler([this, windowNotification](const Glib::ustring &username, const Glib::ustring &password) { - std::lock_guard<std::mutex> lock(databaseCallbackMutex); if(!database) { windowNotification->show("You are not connected to the bootstrap node yet! please wait..."); @@ -70,6 +74,7 @@ namespace dchat fprintf(stderr, "Trying to register username %s\n", username.raw().c_str()); database->storeUserWithoutNodes(username.raw(), password.raw()); windowNotification->show(Glib::ustring("Successfully registered user ") + username); + drawBackgroundConnection.disconnect(); stack.set_visible_child(chatWindow); } catch(std::exception &e) @@ -146,10 +151,120 @@ namespace dchat database = odhtdb::Database::connect("83.252.53.188", 27130, Cache::getDchatDir(), callbackFuncs).get(); stack.set_visible_child(loginWindow); windowNotification->show("Connected to 83.252.53.188:27130"); + + backgroundRng.seed(std::random_device()()); + std::uniform_int_distribution<std::mt19937::result_type> sizeDeviationRand(0, 5); + std::uniform_int_distribution<std::mt19937::result_type> posDeviationRand(0, 100); + + const double spaceBetweenNodesColumn = 1.0 / (double)(nodesPerColumn - 1); + const double spaceBetweenNodesRow = 1.0 / (double)(nodesPerRow - 1); + for(int y = 0; y < nodesPerRow; ++y) + { + for(int x = 0; x < nodesPerColumn; ++x) + { + int sizeDeviation = sizeDeviationRand(backgroundRng); + //int xDeviation = posDeviationRand(backgroundRng) - 50; + //int yDeviation = posDeviationRand(backgroundRng) - 50; + int xDeviation = 0; + int yDeviation = 0; + + Node node; + node.radius = 5.0 + sizeDeviation; + node.originalPosX = /*spaceBetweenNodesColumn * 0.5 + */x * spaceBetweenNodesColumn + xDeviation * 0.001; + node.originalPosY = /*spaceBetweenNodesRow * 0.5 + */y * spaceBetweenNodesRow + yDeviation * 0.001; + node.currentPosX = node.originalPosX; + node.currentPosY = node.originalPosY; + node.targetPosX = node.currentPosX; + node.targetPosY = node.currentPosY; + backgroundNodes.push_back(node); + } + } + prevTimeMillis = std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::system_clock::now().time_since_epoch()).count() - 5000; + drawBackgroundConnection = signal_draw().connect(sigc::mem_fun(*this, &Window::drawBackground)); } Window::~Window() { } + + static void drawNode(const Cairo::RefPtr<Cairo::Context> &cairo, double x, double y, double radius) + { + cairo->arc(x, y, radius, 0.0, 2.0 * M_PI); + cairo->fill(); + cairo->arc(x, y, radius + (radius * 0.8), 0.0, 2.0 * M_PI); + cairo->set_line_width(radius * 0.1); + cairo->stroke(); + } + + bool Window::drawBackground(const Cairo::RefPtr<Cairo::Context> &cairo) + { + int windowWidth, windowHeight; + get_size(windowWidth, windowHeight); + cairo->set_source_rgb(0.5, 0.5, 0.5); + + int currentTimeMillis = std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::system_clock::now().time_since_epoch()).count(); + int deltaTimeMillis = currentTimeMillis - prevTimeMillis; + bool updateTarget = false; + if(deltaTimeMillis > 3000) + { + prevTimeMillis = currentTimeMillis; + updateTarget = true; + } + std::uniform_int_distribution<std::mt19937::result_type> posDeviationRand(0, 100); + const double moveSpeed = 0.0001; + + for(Node &node : backgroundNodes) + { + if(updateTarget) + { + int xDeviation = posDeviationRand(backgroundRng) - 50; + int yDeviation = posDeviationRand(backgroundRng) - 50; + + node.targetPosX = node.originalPosX + xDeviation * 0.001; + node.targetPosY = node.originalPosY + yDeviation * 0.001; + } + + double diffX = node.targetPosX - node.currentPosX; + double diffY = node.targetPosY - node.currentPosY; + double diffDist = std::max(0.01, std::sqrt(diffX*diffX + diffY*diffY)); + diffX /= diffDist; + diffY /= diffDist; + + node.currentPosX += (diffX * moveSpeed); + node.currentPosY += (diffY * moveSpeed); + + drawNode(cairo, node.currentPosX * windowWidth, node.currentPosY * windowHeight, node.radius); + } + + cairo->set_line_width(2.0); + for(int y = 0; y < nodesPerRow; ++y) + { + for(int x = 0; x < nodesPerColumn; ++x) + { + Node *currentNode = &backgroundNodes[x + y * nodesPerRow]; + if(x > 0) + { + Node *prevNode = &backgroundNodes[x - 1 + y * nodesPerRow]; + int currentNodeRadius = currentNode->radius + (currentNode->radius * 0.8); + int prevNodeRadius = prevNode->radius + (prevNode->radius * 0.8); + cairo->move_to(prevNode->currentPosX * windowWidth + prevNodeRadius, prevNode->currentPosY * windowHeight); + cairo->line_to(currentNode->currentPosX * windowWidth - currentNodeRadius, currentNode->currentPosY * windowHeight); + } + + if(y > 0) + { + Node *prevNode = &backgroundNodes[x + (y - 1) * nodesPerRow]; + int currentNodeRadius = currentNode->radius + (currentNode->radius * 0.8); + int prevNodeRadius = prevNode->radius + (prevNode->radius * 0.8); + cairo->move_to(prevNode->currentPosX * windowWidth, prevNode->currentPosY * windowHeight + prevNodeRadius); + cairo->line_to(currentNode->currentPosX * windowWidth, currentNode->currentPosY * windowHeight - currentNodeRadius); + } + } + } + cairo->stroke(); + + queue_draw(); + return true; + } }
\ No newline at end of file |