aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/ChatWindow.cpp156
-rw-r--r--src/ImageButton.cpp14
-rw-r--r--src/InputDialog.cpp32
-rw-r--r--src/Window.cpp13
-rw-r--r--src/main.cpp1
5 files changed, 171 insertions, 45 deletions
diff --git a/src/ChatWindow.cpp b/src/ChatWindow.cpp
index c82e7fa..273f0e0 100644
--- a/src/ChatWindow.cpp
+++ b/src/ChatWindow.cpp
@@ -1,5 +1,6 @@
#include "../include/ChatWindow.hpp"
#include "../include/ChatMessage.hpp"
+#include "../include/InputDialog.hpp"
#include <gtkmm/alignment.h>
#include <gtkmm/viewport.h>
#include <gtkmm/scrollbar.h>
@@ -12,8 +13,12 @@ namespace dchat
const int MERGE_MESSAGE_TIMESTAMP_DIFF_SEC = 60;
ChatWindow::ChatWindow() :
- roomCount(0)
+ addRoomButton("images/add_button_small.png", " Add room"),
+ roomCount(0),
+ currentRoomData(nullptr)
{
+ leftPanelUsersStack.set_homogeneous(false);
+ messageAreaStack.set_homogeneous(false);
setupTopBar();
Gtk::Paned *sidePanels = Gtk::manage(new Gtk::Paned());
@@ -24,6 +29,7 @@ namespace dchat
setupLeftPanel(sidePanels);
Gtk::Grid *rightPanel = Gtk::manage(new Gtk::Grid());
+ rightPanel->set_vexpand(true);
rightPanel->set_hexpand(true);
sidePanels->add2(*rightPanel);
@@ -34,6 +40,17 @@ namespace dchat
set_hexpand(true);
}
+ ChatWindow::~ChatWindow()
+ {
+ for(auto &it : roomDataById)
+ {
+ delete it.second->leftPanelUsersLayout;
+ delete it.second->messageAreaLayout;
+ delete it.second->button;
+ delete it.second;
+ }
+ }
+
void ChatWindow::setupTopBar()
{
topbar.set_name("top-bar");
@@ -49,18 +66,21 @@ namespace dchat
topbarSpacer->set_size_request(50);
topbar.attach_next_to(*topbarSpacer, topbarSearchBar, Gtk::POS_RIGHT, 1, 1);
- currentChannelTitle.set_text("Linux");
- currentChannelTitle.set_name("current-channel-title");
+ currentChannelTitle.set_name("current-room-title");
topbar.attach_next_to(currentChannelTitle, *topbarSpacer, Gtk::POS_RIGHT, 1, 1);
}
void ChatWindow::setupLeftPanel(Gtk::Paned *sidePanels)
{
+ Gtk::Grid *leftPanelLayout = Gtk::manage(new Gtk::Grid());
+ leftPanelLayout->set_vexpand(true);
+ leftPanelLayout->set_size_request(200);
+ leftPanelLayout->set_name("left-panel");
+ sidePanels->add1(*leftPanelLayout);
+
Gtk::Paned *leftPanel = Gtk::manage(new Gtk::Paned(Gtk::ORIENTATION_VERTICAL));
- leftPanel->set_size_request(200);
- leftPanel->set_name("left-panel");
leftPanel->set_vexpand(true);
- sidePanels->add1(*leftPanel);
+ leftPanelLayout->attach(*leftPanel, 0, 0, 1, 2);
leftPanelChannels.set_vexpand(true);
leftPanel->add1(leftPanelChannels);
@@ -72,14 +92,26 @@ namespace dchat
leftPanelChannels.attach(*channelsTitle, 0, 0, 1, 1);
////
- leftPanelUsers.set_vexpand(true);
- leftPanel->add2(leftPanelUsers);
+ leftPanelUsersStack.set_vexpand(true);
+ leftPanel->add2(leftPanelUsersStack);
- Gtk::Label *usersTitle = Gtk::manage(new Gtk::Label());
- usersTitle->set_name("users-title");
- usersTitle->set_text("Users");
- usersTitle->set_halign(Gtk::ALIGN_START);
- leftPanelUsers.attach(*usersTitle, 0, 0, 1, 1);
+ addRoomButton.set_halign(Gtk::ALIGN_START);
+ leftPanelLayout->attach_next_to(addRoomButton, *leftPanel, Gtk::POS_BOTTOM, 1, 1);
+ addRoomButton.signal_clicked().connect([this]()
+ {
+ InputDialog createRoomDialog("Create a new room", "Room name");
+ switch(createRoomDialog.run())
+ {
+ case Gtk::RESPONSE_ACCEPT:
+ {
+ // TODO: Do not allow if room name size is == 0 or > 32
+ currentRoom->rooms->createRoom(createRoomDialog.getInput());
+ break;
+ }
+ default:
+ break;
+ }
+ });
}
void ChatWindow::setupMessageArea(Gtk::Grid *rightPanel)
@@ -89,8 +121,8 @@ namespace dchat
messageArea.set_policy(Gtk::PolicyType::POLICY_NEVER, Gtk::PolicyType::POLICY_AUTOMATIC);
rightPanel->attach(messageArea, 0, 0, 1, 2);
- messageAreaLayout.set_name("chat-area-layout");
- messageArea.add(messageAreaLayout);
+ messageAreaStack.set_name("chat-area-layout");
+ messageArea.add(messageAreaStack);
}
void ChatWindow::setupChatInput(Gtk::Grid *rightPanel)
@@ -159,17 +191,57 @@ namespace dchat
void ChatWindow::addRoom(std::shared_ptr<Room> room)
{
+ std::string roomIdStr = room->id->toString();
+ Gtk::Grid *leftPanelUsersLayout = new Gtk::Grid();
+ leftPanelUsersLayout->set_vexpand(true);
+ leftPanelUsersLayout->show();
+ leftPanelUsersStack.add(*leftPanelUsersLayout, roomIdStr);
+
+ Gtk::Label *usersTitle = Gtk::manage(new Gtk::Label());
+ usersTitle->get_style_context()->add_class("users-title");
+ usersTitle->set_text("Users");
+ usersTitle->set_halign(Gtk::ALIGN_START);
+ usersTitle->show();
+ leftPanelUsersLayout->attach(*usersTitle, 0, 0, 1, 1);
+
+ Gtk::Grid *messageAreaLayout = new Gtk::Grid();
+ messageAreaLayout->show();
+ messageAreaStack.add(*messageAreaLayout, roomIdStr);
+
fprintf(stderr, "Added channel %s\n", room->id->toString().c_str());
- Gtk::ToggleButton *channelButton = Gtk::manage(new Gtk::ToggleButton("Channel name"));
- channelButton->set_active(true);
- channelButton->get_style_context()->add_class("channel-button");
- channelButton->set_hexpand(true);
- channelButton->get_child()->set_halign(Gtk::ALIGN_START);
- channelButton->show();
- leftPanelChannels.attach(*channelButton, 0, 1 + roomCount, 1, 1);
+ Gtk::ToggleButton *roomButton = new Gtk::ToggleButton("Room name");
+ roomButton->set_active(true);
+ roomButton->get_style_context()->add_class("room-button");
+ roomButton->set_hexpand(true);
+ roomButton->set_halign(Gtk::ALIGN_START);
+ roomButton->get_child()->set_halign(Gtk::ALIGN_START);
+ roomButton->show();
+ roomButton->signal_clicked().connect([this, room]
+ {
+ setCurrentRoom(room);
+ });
+ leftPanelChannels.attach(*roomButton, 0, 1 + roomCount, 1, 1);
++roomCount;
- roomDataById[*room->id] = { channelButton };
+ currentRoomData = new RoomData { leftPanelUsersLayout, messageAreaLayout, roomButton };
+ roomDataById[*room->id] = currentRoomData;
+ currentRoom = room;
+
+ leftPanelUsersStack.set_visible_child(roomIdStr);
+ messageAreaStack.set_visible_child(roomIdStr);
+ }
+
+ void ChatWindow::setCurrentRoom(std::shared_ptr<Room> room)
+ {
+ std::string roomIdStr = room->id->toString();
+ leftPanelUsersStack.set_visible_child(roomIdStr);
+ messageAreaStack.set_visible_child(roomIdStr);
+ currentChannelTitle.set_text(room->name);
currentRoom = room;
+ currentRoomData = roomDataById[*room->id];
+
+ // TODO: Instead of scrolling to bottom, remember scroll position (even after restarting application).
+ // We want to show oldest unread message first
+ scrollToBottom();
}
void ChatWindow::addMessage(const RoomAddMessageRequest &request)
@@ -190,42 +262,41 @@ namespace dchat
messageById[request.message.id] = message;
if(!request.loadedFromCache && *request.room->id == *currentRoom->id)
{
- auto adj = messageArea.get_vadjustment();
- adj->set_value(adj->get_upper());
- messageAreaLayout.queue_draw();
- while(gtk_events_pending())
- gtk_main_iteration_do(FALSE);
+ currentRoomData->messageAreaLayout->queue_draw();
+ scrollToBottom();
}
return;
}
}
- ChatMessage *message = Gtk::manage(new ChatMessage(request.message.creator->nickname, request.message.text, request.message.timestampSeconds));
+ std::string userNickname = request.message.creator->nickname;
+ if(userNickname.empty())
+ userNickname = "Anonymous";
+ ChatMessage *message = Gtk::manage(new ChatMessage(userNickname, request.message.text, request.message.timestampSeconds));
message->set_valign(Gtk::Align::ALIGN_START);
message->set_hexpand(true);
message->show_all();
messageById[request.message.id] = message;
- messageAreaLayout.attach(*message, 0, roomMessages.size(), 1, 1);
+ RoomData *roomData = roomDataById[*request.room->id];
+ roomData->messageAreaLayout->attach(*message, 0, roomMessages.size(), 1, 1);
// TODO: When we get a message in the current room we scroll to the bottom, but this should only be done if we are not manually scrolling to view old messages
if(!request.loadedFromCache && *request.room->id == *currentRoom->id)
{
- auto adj = messageArea.get_vadjustment();
- adj->set_value(adj->get_upper());
- messageAreaLayout.queue_draw();
- while(gtk_events_pending())
- gtk_main_iteration_do(FALSE);
+ roomData->messageAreaLayout->queue_draw();
+ scrollToBottom();
}
}
void ChatWindow::addUser(std::shared_ptr<Room> room, std::shared_ptr<User> user)
{
- Gtk::Label *username = Gtk::manage(new Gtk::Label("NoName"));
+ Gtk::Label *username = Gtk::manage(new Gtk::Label("Anonymous"));
username->set_halign(Gtk::ALIGN_START);
username->show();
username->get_style_context()->add_class("username-list-username");
user->userdata = username;
- leftPanelUsers.attach(*username, 0, room->userByPublicKey.size(), 1, 1);
+ RoomData *roomData = roomDataById[*room->id];
+ roomData->leftPanelUsersLayout->attach(*username, 0, room->userByPublicKey.size(), 1, 1);
fprintf(stderr, "Added user %s\n", user->publicKey.toString().c_str());
}
@@ -236,8 +307,19 @@ namespace dchat
fprintf(stderr, "Set nickname for user %s to %s\n", request.user->publicKey.toString().c_str(), request.newNickname.c_str());
}
+ void ChatWindow::changeRoomName(const RoomChangeNameRequest &request)
+ {
+ Gtk::Button *button = roomDataById[*request.room->id]->button;
+ static_cast<Gtk::Label*>(button->get_child())->set_text(request.newName);
+ if(*request.room->id == *currentRoom->id)
+ currentChannelTitle.set_text(request.newName);
+ fprintf(stderr, "Changed room %s name to %s\n", request.room->id->toString().c_str(), request.newName.c_str());
+ }
+
void ChatWindow::scrollToBottom()
{
+ while(gtk_events_pending())
+ gtk_main_iteration_do(FALSE);
auto adj = messageArea.get_vadjustment();
adj->set_value(adj->get_upper());
}
diff --git a/src/ImageButton.cpp b/src/ImageButton.cpp
new file mode 100644
index 0000000..17939f7
--- /dev/null
+++ b/src/ImageButton.cpp
@@ -0,0 +1,14 @@
+#include "../include/ImageButton.hpp"
+#include <gtkmm/image.h>
+
+namespace dchat
+{
+ ImageButton::ImageButton(const char *filepath, const char *text) :
+ Gtk::Button(text)
+ {
+ Gtk::Image *image = Gtk::manage(new Gtk::Image(filepath));
+ set_always_show_image(true);
+ set_image(*image);
+ get_style_context()->add_class("image-button");
+ }
+} \ No newline at end of file
diff --git a/src/InputDialog.cpp b/src/InputDialog.cpp
new file mode 100644
index 0000000..520bfa2
--- /dev/null
+++ b/src/InputDialog.cpp
@@ -0,0 +1,32 @@
+#include "../include/InputDialog.hpp"
+#include <gtkmm/label.h>
+
+namespace dchat
+{
+ InputDialog::InputDialog(const char *title, const char *text, const char *acceptText, const char *cancelText)
+ {
+ set_title(title);
+
+ Gtk::Box *box = get_content_area();
+ Gtk::Label *label = Gtk::manage(new Gtk::Label(text));
+ label->set_valign(Gtk::ALIGN_END);
+ label->set_halign(Gtk::ALIGN_CENTER);
+ box->pack_start(*label, true, true);
+
+ entry.set_valign(Gtk::ALIGN_CENTER);
+ entry.set_halign(Gtk::ALIGN_CENTER);
+ entry.set_hexpand(true);
+ box->pack_end(entry, true, true);
+
+ add_button(acceptText, Gtk::RESPONSE_ACCEPT);
+ add_button(cancelText, Gtk::RESPONSE_CANCEL);
+ show_all();
+
+ set_size_request(300, 150);
+ }
+
+ Glib::ustring InputDialog::getInput() const
+ {
+ return entry.get_text();
+ }
+} \ No newline at end of file
diff --git a/src/Window.cpp b/src/Window.cpp
index b9e1490..e8129f0 100644
--- a/src/Window.cpp
+++ b/src/Window.cpp
@@ -5,7 +5,6 @@
#include <sibs/SafeDeserializer.hpp>
#include <math.h>
#include <chrono>
-#include <gtkmm.h>
namespace dchat
{
@@ -48,13 +47,7 @@ namespace dchat
drawBackgroundConnection.disconnect();
chatWindow.show_all();
stack.set_visible_child(chatWindow);
-
- Glib::signal_timeout().connect([this]
- {
- printf("scroll to bottom!\n");
- chatWindow.scrollToBottom();
- return false;
- }, 100);
+ chatWindow.scrollToBottom();
}
catch(std::exception &e)
{
@@ -130,6 +123,10 @@ namespace dchat
{
chatWindow.setUserNickname(request);
};
+ roomCallbackFuncs.changeRoomNameCallbackFunc = [this](const RoomChangeNameRequest &request)
+ {
+ chatWindow.changeRoomName(request);
+ };
windowNotification->show("Connecting to 83.252.53.188:27130");
Rooms::connect("83.252.53.188", 27130, roomCallbackFuncs);
diff --git a/src/main.cpp b/src/main.cpp
index 6c7dec6..71e54d3 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -1,6 +1,7 @@
#include "../include/Window.hpp"
#include <gtkmm/application.h>
#include <gtkmm/cssprovider.h>
+#include <gtkmm/settings.h>
int main (int argc, char *argv[])
{