From 8cc8853c3c1e5dfd7681bc0c31bc0eb88a4ef959 Mon Sep 17 00:00:00 2001 From: dec05eba Date: Sat, 3 Nov 2018 01:10:08 +0100 Subject: Add room name change event, create new room button, multiple rooms --- src/ChatWindow.cpp | 156 ++++++++++++++++++++++++++++++++++++++++------------- 1 file changed, 119 insertions(+), 37 deletions(-) (limited to 'src/ChatWindow.cpp') 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 #include #include @@ -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) { + 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) + { + 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, std::shared_ptr 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(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()); } -- cgit v1.2.3