From 13ea8fecdfc70bfaddb58cbb4db69e42eb909829 Mon Sep 17 00:00:00 2001 From: Jaidyn Ann Date: Thu, 27 May 2021 11:15:30 -0500 Subject: [PATCH] Write conversation list, put it in main window Now all active conversations will be listed in the main window, in a ConversationListView. Clicking one of the items will open its conversation window as you'd expect, etc. --- application/CayaMessages.h | 3 + application/Conversation.cpp | 9 +++ application/Conversation.h | 6 +- application/MainWindow.cpp | 46 ++++++++++- application/MainWindow.h | 12 +-- application/Makefile | 14 ++-- application/Server.cpp | 3 +- application/Server.h | 4 + application/views/ConversationItem.cpp | 43 ++++++++++ application/views/ConversationItem.h | 31 ++++++++ application/views/ConversationListView.cpp | 92 ++++++++++++++++++++++ application/views/ConversationListView.h | 27 +++++++ 12 files changed, 275 insertions(+), 15 deletions(-) create mode 100644 application/views/ConversationItem.cpp create mode 100644 application/views/ConversationItem.h create mode 100644 application/views/ConversationListView.cpp create mode 100644 application/views/ConversationListView.h diff --git a/application/CayaMessages.h b/application/CayaMessages.h index acd40d5..4b50edf 100644 --- a/application/CayaMessages.h +++ b/application/CayaMessages.h @@ -17,6 +17,9 @@ const uint32 CAYA_CLOSE_CHAT_WINDOW = 'CYcw'; //! Chat messages const uint32 CAYA_CHAT = 'CYch'; +//! Create a new chat +const uint32 CAYA_NEW_CHAT = 'CYnc'; + //! Send replicant's messenger to Caya const uint32 CAYA_REPLICANT_MESSENGER = 'RPme'; diff --git a/application/Conversation.cpp b/application/Conversation.cpp index c65d224..4616975 100644 --- a/application/Conversation.cpp +++ b/application/Conversation.cpp @@ -13,6 +13,7 @@ #include "CayaProtocolMessages.h" #include "CayaUtils.h" #include "ChatWindow.h" +#include "ConversationItem.h" #include "MainWindow.h" #include "ProtocolLooper.h" #include "ProtocolManager.h" @@ -31,6 +32,7 @@ Conversation::Conversation(BString id, BMessenger msgn) fLooper(NULL), fDateFormatter() { + fConversationItem = new ConversationItem(fName.String(), this); } @@ -181,6 +183,13 @@ Conversation::SetProtocolLooper(ProtocolLooper* looper) } +ConversationItem* +Conversation::GetConversationItem() +{ + return fConversationItem; +} + + BString Conversation::GetName() const { diff --git a/application/Conversation.h b/application/Conversation.h index 840cb16..3b2f8e9 100644 --- a/application/Conversation.h +++ b/application/Conversation.h @@ -11,11 +11,12 @@ #include -#include "Notifier.h" +#include "Observer.h" #include "User.h" class ChatWindow; class Contact; +class ConversationItem; class ProtocolLooper; class Server; @@ -49,6 +50,8 @@ public: ProtocolLooper* GetProtocolLooper() const; void SetProtocolLooper(ProtocolLooper* looper); + ConversationItem* GetConversationItem(); + BString GetName() const; UserMap Users(); @@ -68,6 +71,7 @@ private: ProtocolLooper* fLooper; ChatWindow* fChatWindow; bool fNewWindow; + ConversationItem* fConversationItem; BString fID; BString fName; diff --git a/application/MainWindow.cpp b/application/MainWindow.cpp index 700c323..82a4608 100644 --- a/application/MainWindow.cpp +++ b/application/MainWindow.cpp @@ -26,6 +26,8 @@ #include "CayaMessages.h" #include "CayaProtocolMessages.h" #include "CayaPreferences.h" +#include "ConversationItem.h" +#include "ConversationListView.h" #include "NotifyMessage.h" #include "MainWindow.h" #include "PreferencesDialog.h" @@ -36,7 +38,6 @@ const uint32 kLogin = 'LOGI'; -const uint32 CAYA_NEW_CHAT = 'CRCH'; MainWindow::MainWindow() @@ -67,8 +68,11 @@ MainWindow::MainWindow() menuBar->AddItem(programMenu); menuBar->AddItem(chatMenu); + fListView = new ConversationListView("roomList"); + BLayoutBuilder::Group<>(this, B_VERTICAL, 0.0f) .Add(menuBar) + .Add(fListView) .AddGroup(B_VERTICAL) .SetInsets(5, 5, 5, 10) .Add(fStatusView) @@ -220,6 +224,13 @@ MainWindow::ImMessage(BMessage* msg) } break; } + case IM_MESSAGE_RECEIVED: + case IM_MESSAGE_SENT: + case IM_CHAT_CREATED: + { + _EnsureConversationItem(msg); + break; + } } } @@ -235,6 +246,16 @@ MainWindow::ObserveInteger(int32 what, int32 val) } +void +MainWindow::UpdateListItem(ConversationItem* item) +{ + if (fListView->HasItem(item) == true) + fListView->InvalidateItem(fListView->IndexOf(item)); + else + fListView->AddItem(item); +} + + void MainWindow::WorkspaceActivated(int32 workspace, bool active) { @@ -245,3 +266,26 @@ MainWindow::WorkspaceActivated(int32 workspace, bool active) } +ConversationItem* +MainWindow::_EnsureConversationItem(BMessage* msg) +{ + ChatMap chats = fServer->Conversations(); + + BString chat_id = msg->FindString("chat_id"); + Conversation* chat = fServer->ConversationById(chat_id); + + if (chat != NULL) { + ConversationItem* item = chat->GetConversationItem(); + if (fListView->HasItem(item)) { + UpdateListItem(item); + } + else if (item != NULL) { + fListView->AddItem(item); + } + return item; + } + + return NULL; +} + + diff --git a/application/MainWindow.h b/application/MainWindow.h index a3baba2..41ac15a 100644 --- a/application/MainWindow.h +++ b/application/MainWindow.h @@ -13,9 +13,10 @@ class BCardLayout; class BTextControl; +class ConversationItem; +class ConversationListView; class Server; class StatusView; -class RosterListView; class RosterItem; @@ -37,17 +38,16 @@ public: Server* GetServer() const { return fServer; } - void UpdateListItem(RosterItem* item); + void UpdateListItem(ConversationItem* item); int32 CountItems() const; RosterItem* ItemAt(int index); - void AddItem(RosterItem*); - bool HasItem(RosterItem*); - void RemoveItem(RosterItem*); private: + ConversationItem* _EnsureConversationItem(BMessage* msg); + + ConversationListView* fListView; StatusView* fStatusView; - RosterListView* fListView; Server* fServer; bool fWorkspaceChanged; }; diff --git a/application/Makefile b/application/Makefile index feaf281..b9ec14e 100644 --- a/application/Makefile +++ b/application/Makefile @@ -62,15 +62,17 @@ SRCS = \ application/preferences/PreferencesBehavior.cpp \ application/preferences/PreferencesReplicant.cpp \ application/preferences/PreferencesChatWindow.cpp \ - application/views/SearchBarTextControl.cpp \ - application/views/NicknameTextControl.cpp \ - application/views/RosterItem.cpp \ - application/views/RosterListView.cpp \ - application/views/StatusMenuItem.cpp \ - application/views/StatusView.cpp \ application/views/CayaRenderView.cpp \ + application/views/ConversationItem.cpp \ + application/views/ConversationListView.cpp \ + application/views/NicknameTextControl.cpp \ application/views/ReplicantStatusView.cpp \ application/views/ReplicantMenuItem.cpp \ + application/views/RosterItem.cpp \ + application/views/RosterListView.cpp \ + application/views/SearchBarTextControl.cpp \ + application/views/StatusMenuItem.cpp \ + application/views/StatusView.cpp \ application/views/UserInfoWindow.cpp \ application/views/UserPopUp.cpp diff --git a/application/Server.cpp b/application/Server.cpp index 8e3dbc4..a610ede 100644 --- a/application/Server.cpp +++ b/application/Server.cpp @@ -340,6 +340,7 @@ Server::ImMessage(BMessage* msg) chat->AddUser(user); chat->ShowWindow(false, true); } + break; } case IM_SEND_MESSAGE: @@ -354,7 +355,7 @@ Server::ImMessage(BMessage* msg) { Conversation* item = _EnsureConversation(msg); item->ImMessage(msg); - result = B_SKIP_MESSAGE; + break; } case IM_CONTACT_STARTED_TYPING: diff --git a/application/Server.h b/application/Server.h index 11e225e..7f68bc1 100644 --- a/application/Server.h +++ b/application/Server.h @@ -19,10 +19,12 @@ class CayaProtocol; class RosterItem; class ProtocolLooper; + typedef KeyMap RosterMap; typedef KeyMap ChatMap; typedef KeyMap ProtocolLoopers; + class Server: public BMessageFilter { public: Server(); @@ -65,4 +67,6 @@ private: Contact* fMySelf; }; + #endif // _SERVER_H + diff --git a/application/views/ConversationItem.cpp b/application/views/ConversationItem.cpp new file mode 100644 index 0000000..2224b85 --- /dev/null +++ b/application/views/ConversationItem.cpp @@ -0,0 +1,43 @@ +/* + * Copyright 2021, Jaidyn Levesque + * All rights reserved. Distributed under the terms of the MIT license. + */ + +#include "ConversationItem.h" + +#include "Conversation.h" + + +ConversationItem::ConversationItem(const char* name, Conversation* chat) + : + BStringItem(name), + fChat(chat) +{ +} + + +Conversation* +ConversationItem::GetConversation() +{ + return fChat; +} + + +void +ConversationItem::ObserveString(int32 what, BString str) +{ +} + + +void +ConversationItem::ObservePointer(int32 what, void* ptr) +{ +} + + +void +ConversationItem::ObserveInteger(int32 what, int32 val) +{ +} + + diff --git a/application/views/ConversationItem.h b/application/views/ConversationItem.h new file mode 100644 index 0000000..48b8cd7 --- /dev/null +++ b/application/views/ConversationItem.h @@ -0,0 +1,31 @@ +/* + * Copyright 2021, Jaidyn Levesque + * All rights reserved. Distributed under the terms of the MIT license. + */ +#ifndef CONVERSATIONITEM_H +#define CONVERSATIONITEM_H + +#include + +#include "Observer.h" + +class Conversation; + + +class ConversationItem : public BStringItem, public Observer { +public: + ConversationItem(const char* name, Conversation* chat); + + Conversation* GetConversation(); + +protected: + void ObserveString(int32 what, BString str); + void ObservePointer(int32 what, void* ptr); + void ObserveInteger(int32 what, int32 val); + +private: + Conversation* fChat; +}; + + +#endif // CONVERSATIONITEM_H diff --git a/application/views/ConversationListView.cpp b/application/views/ConversationListView.cpp new file mode 100644 index 0000000..7e3f057 --- /dev/null +++ b/application/views/ConversationListView.cpp @@ -0,0 +1,92 @@ +/* + * Copyright 2021, Jaidyn Levesque + * All rights reserved. Distributed under the terms of the MIT license. + */ + +#include "ConversationListView.h" + +#include +#include +#include + +#include "CayaMessages.h" +#include "Conversation.h" +#include "ConversationItem.h" + + +const uint32 kOpenSelectedChat = 'CVos'; +const uint32 kLeaveSelectedChat = 'CVcs'; + + +ConversationListView::ConversationListView(const char* name) + : BOutlineListView(name) +{ +} + + +void +ConversationListView::MessageReceived(BMessage* msg) +{ + switch (msg->what) { + case kOpenSelectedChat: + { + ConversationItem* item; + int32 selIndex = CurrentSelection(); + + if ((item = (ConversationItem*)ItemAt(selIndex)) != NULL) + item->GetConversation()->ShowWindow(false, true); + break; + } + + default: + BOutlineListView::MessageReceived(msg); + } +} + + +void +ConversationListView::MouseDown(BPoint where) +{ + BListView::MouseDown(where); + + uint32 buttons = 0; + Window()->CurrentMessage()->FindInt32("buttons", (int32*)&buttons); + + if (buttons & B_PRIMARY_MOUSE_BUTTON) + MessageReceived(new BMessage(kOpenSelectedChat)); + + if (!(buttons & B_SECONDARY_MOUSE_BUTTON)) + return; + + if (CurrentSelection() >= 0) + _ConversationPopUp()->Go(ConvertToScreen(where), true, false); + else + _BlankPopUp()->Go(ConvertToScreen(where), true, false); +} + + +BPopUpMenu* +ConversationListView::_ConversationPopUp() +{ + BPopUpMenu* menu = new BPopUpMenu("chatPopUp"); + menu->AddItem(new BMenuItem("Open chat…", new BMessage(kOpenSelectedChat))); + menu->AddItem(new BMenuItem("Leave chat", new BMessage(kLeaveSelectedChat))); + menu->SetTargetForItems(this); + + return menu; + +} + + +BPopUpMenu* +ConversationListView::_BlankPopUp() +{ + BPopUpMenu* menu = new BPopUpMenu("blankPopUp"); + menu->AddItem(new BMenuItem("New chat" B_UTF8_ELLIPSIS, + new BMessage(CAYA_NEW_CHAT))); + menu->SetTargetForItems(Window()); + + return menu; +} + + diff --git a/application/views/ConversationListView.h b/application/views/ConversationListView.h new file mode 100644 index 0000000..b6a6d3f --- /dev/null +++ b/application/views/ConversationListView.h @@ -0,0 +1,27 @@ +/* + * Copyright 2021, Jaidyn Levesque + * All rights reserved. Distributed under the terms of the MIT license. + */ +#ifndef CONVERSATIONLIST_H +#define CONVERSATIONLIST_H + +#include + +class BPopUpMenu; + + +class ConversationListView : public BOutlineListView { +public: + ConversationListView(const char* name); + + void MessageReceived(BMessage* msg); + void MouseDown(BPoint where); + +private: + BPopUpMenu* _ConversationPopUp(); + BPopUpMenu* _BlankPopUp(); +}; + + +#endif // CONVERSATIONLIST_H +