From 63d8bbef26046d029e15080023eeee972aae675e Mon Sep 17 00:00:00 2001 From: Jaidyn Ann Date: Mon, 31 May 2021 10:50:43 -0500 Subject: [PATCH] Add user-list to the conversation view, menu tweaks UserListView and UserItem were added as the backbone of the user-list, and the (currently unused) Caya message CAYA_SEND_INVITE was established for inviting users to rooms. Some menus were reworked (e.g., pop-ups of the RosterListView) or generally tweaked to be more sensical or consistent. --- application/CayaMessages.h | 3 + application/Conversation.cpp | 2 + application/MainWindow.cpp | 10 ++ application/Makefile | 2 + application/User.cpp | 11 ++ application/User.h | 8 +- application/views/ConversationListView.cpp | 2 +- application/views/ConversationView.cpp | 164 ++++++++++++--------- application/views/ConversationView.h | 24 +-- application/views/RosterListView.cpp | 33 ++--- application/views/UserItem.cpp | 43 ++++++ application/views/UserItem.h | 32 ++++ application/views/UserListView.cpp | 95 ++++++++++++ application/views/UserListView.h | 28 ++++ 14 files changed, 360 insertions(+), 97 deletions(-) create mode 100644 application/views/UserItem.cpp create mode 100644 application/views/UserItem.h create mode 100644 application/views/UserListView.cpp create mode 100644 application/views/UserListView.h diff --git a/application/CayaMessages.h b/application/CayaMessages.h index c59ba3d..d88eed7 100644 --- a/application/CayaMessages.h +++ b/application/CayaMessages.h @@ -20,6 +20,9 @@ const uint32 CAYA_CHAT = 'CYch'; //! Create a new chat const uint32 CAYA_NEW_CHAT = 'CYnc'; +//! Invite user to current chat +const uint32 CAYA_SEND_INVITE = 'CYin'; + //! Send replicant's messenger to Caya const uint32 CAYA_REPLICANT_MESSENGER = 'RPme'; diff --git a/application/Conversation.cpp b/application/Conversation.cpp index e286f4e..27dccbe 100644 --- a/application/Conversation.cpp +++ b/application/Conversation.cpp @@ -272,6 +272,7 @@ Conversation::_EnsureUser(BMessage* msg) if (user == NULL && serverUser != NULL) { fUsers.AddItem(id, serverUser); user = serverUser; + GetView()->UpdateUserList(fUsers); } else if (user == NULL) { user = new Contact(id, _GetServer()->Looper()); @@ -279,6 +280,7 @@ Conversation::_EnsureUser(BMessage* msg) _GetServer()->AddContact(user); fUsers.AddItem(id, user); + GetView()->UpdateUserList(fUsers); } user->RegisterObserver(this); diff --git a/application/MainWindow.cpp b/application/MainWindow.cpp index 0f5dab6..6cbf6bf 100644 --- a/application/MainWindow.cpp +++ b/application/MainWindow.cpp @@ -334,6 +334,7 @@ MainWindow::_CreateMenuBar() { BMenuBar* menuBar = new BMenuBar("MenuBar"); + // Program BMenu* programMenu = new BMenu("Program"); programMenu->AddItem(new BMenuItem("About" B_UTF8_ELLIPSIS, new BMessage(B_ABOUT_REQUESTED))); @@ -344,16 +345,25 @@ MainWindow::_CreateMenuBar() new BMessage(B_QUIT_REQUESTED), 'Q', B_COMMAND_KEY)); programMenu->SetTargetForItems(this); + // Chat BMenu* chatMenu = new BMenu("Chat"); + BMenuItem* invite = new BMenuItem("Invite user" B_UTF8_ELLIPSIS, + new BMessage(CAYA_SEND_INVITE), 'I', B_COMMAND_KEY); + invite->SetEnabled(false); + chatMenu->AddItem(new BMenuItem("New chat" B_UTF8_ELLIPSIS, new BMessage(CAYA_NEW_CHAT), 'M', B_COMMAND_KEY)); + chatMenu->AddSeparatorItem(); + chatMenu->AddItem(invite); chatMenu->SetTargetForItems(this); + // Window BMenu* windowMenu = new BMenu("Window"); windowMenu->AddItem(new BMenuItem("Up", new BMessage(CAYA_MOVE_UP), B_UP_ARROW, B_COMMAND_KEY)); windowMenu->AddItem(new BMenuItem("Down", new BMessage(CAYA_MOVE_DOWN), B_DOWN_ARROW, B_COMMAND_KEY)); + windowMenu->SetTargetForItems(this); menuBar->AddItem(programMenu); menuBar->AddItem(chatMenu); diff --git a/application/Makefile b/application/Makefile index ff4ff38..ccd2033 100644 --- a/application/Makefile +++ b/application/Makefile @@ -74,6 +74,8 @@ SRCS = \ application/views/StatusMenuItem.cpp \ application/views/StatusView.cpp \ application/views/UserInfoWindow.cpp \ + application/views/UserItem.cpp \ + application/views/UserListView.cpp \ application/views/UserPopUp.cpp diff --git a/application/User.cpp b/application/User.cpp index bbc443c..9efaf70 100644 --- a/application/User.cpp +++ b/application/User.cpp @@ -18,6 +18,7 @@ #include "NotifyMessage.h" #include "ProtocolLooper.h" #include "ProtocolManager.h" +#include "UserItem.h" #include "UserPopUp.h" @@ -27,6 +28,7 @@ User::User(BString id, BMessenger msgn) fName(id), fMessenger(msgn), fLooper(NULL), + fListItem(NULL), fStatus(CAYA_OFFLINE), fPopUp(NULL) { @@ -137,6 +139,15 @@ User::ProtocolBitmap() const } +UserItem* +User::GetListItem() +{ + if (fListItem == NULL) + fListItem = new UserItem(fName, this); + return fListItem; +} + + CayaStatus User::GetNotifyStatus() const { diff --git a/application/User.h b/application/User.h index 9571536..84893a1 100644 --- a/application/User.h +++ b/application/User.h @@ -19,9 +19,9 @@ class BBitmap; class Conversation; -class UserPopUp; class ProtocolLooper; -class RosterItem; +class UserItem; +class UserPopUp; typedef KeyMap ChatMap; @@ -49,6 +49,8 @@ public: void SetProtocolLooper(ProtocolLooper* looper); BBitmap* ProtocolBitmap() const; + UserItem* GetListItem(); + BString GetName() const; BBitmap* AvatarBitmap() const; CayaStatus GetNotifyStatus() const; @@ -65,6 +67,8 @@ protected: BMessenger fMessenger; ProtocolLooper* fLooper; + UserItem* fListItem; + BString fID; bigtime_t fInstance; BString fName; diff --git a/application/views/ConversationListView.cpp b/application/views/ConversationListView.cpp index 69514a0..428f206 100644 --- a/application/views/ConversationListView.cpp +++ b/application/views/ConversationListView.cpp @@ -88,7 +88,7 @@ ConversationListView::_BlankPopUp() { BPopUpMenu* menu = new BPopUpMenu("blankPopUp"); menu->AddItem(new BMenuItem("New chat" B_UTF8_ELLIPSIS, - new BMessage(CAYA_NEW_CHAT))); + new BMessage(CAYA_NEW_CHAT), 'M', B_COMMAND_KEY)); menu->SetTargetForItems(Window()); return menu; diff --git a/application/views/ConversationView.cpp b/application/views/ConversationView.cpp index fe23a7b..ad5be4f 100644 --- a/application/views/ConversationView.cpp +++ b/application/views/ConversationView.cpp @@ -9,9 +9,11 @@ #include "ConversationView.h" #include +#include #include #include #include +#include #include @@ -22,6 +24,8 @@ #include "Contact.h" #include "Conversation.h" #include "NotifyMessage.h" +#include "UserItem.h" +#include "UserListView.h" ConversationView::ConversationView() @@ -30,37 +34,7 @@ ConversationView::ConversationView() fMessageQueue() { fMessageCount = 0; - - fReceiveView = new CayaRenderView("fReceiveView"); - BScrollView* scrollViewReceive = new BScrollView("scrollviewR", - fReceiveView, B_WILL_DRAW, false, true); - - - fPersonalMessage = new BTextView("personalMessage", B_WILL_DRAW); - fPersonalMessage->SetExplicitAlignment( - BAlignment(B_ALIGN_LEFT, B_ALIGN_MIDDLE)); - - fPersonalMessage->SetText(""); - fPersonalMessage->MakeEditable(false); - fPersonalMessage->SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR)); - - fStatus = new BStringView("status", ""); - - fAvatar = new BitmapView("ContactIcon"); - fAvatar->SetExplicitMinSize(BSize(50, 50)); - fAvatar->SetExplicitPreferredSize(BSize(50, 50)); - fAvatar->SetExplicitAlignment(BAlignment(B_ALIGN_RIGHT, B_ALIGN_MIDDLE)); - - fProtocolView = new BitmapView("protocolView"); - - BLayoutBuilder::Group<>(this, B_VERTICAL) - .AddGroup(B_HORIZONTAL) - .Add(fProtocolView) - .Add(fPersonalMessage) - .Add(fAvatar) - .End() - .Add(scrollViewReceive, 3); -// .Add(fStatus, 4) + _InitInterface(); } @@ -81,35 +55,13 @@ ConversationView::QuitRequested() } -Conversation* -ConversationView::GetConversation() -{ - return fConversation; -} - - void -ConversationView::SetConversation(Conversation* chat) +ConversationView::AttachedToWindow() { - fConversation = chat; - fContact = chat->Users().ValueAt(0); - fPersonalMessage->SetText(chat->GetName()); -} - - -void -ConversationView::UpdateAvatar() -{ - if (fContact->AvatarBitmap() != NULL) - fAvatar->SetBitmap(fContact->AvatarBitmap()); -} - - -void -ConversationView::UpdatePersonalMessage() -{ - if (fContact->GetNotifyPersonalStatus() != NULL) - fPersonalMessage->SetText(fContact->GetNotifyPersonalStatus()); + while (fMessageQueue.IsEmpty() == false) { + BMessage* msg = fMessageQueue.RemoveItemAt(0); + ImMessage(msg); + } } @@ -141,16 +93,6 @@ ConversationView::MessageReceived(BMessage* message) } -void -ConversationView::AttachedToWindow() -{ - while (fMessageQueue.IsEmpty() == false) { - BMessage* msg = fMessageQueue.RemoveItemAt(0); - ImMessage(msg); - } -} - - void ConversationView::ImMessage(BMessage* msg) { @@ -220,6 +162,50 @@ ConversationView::ImMessage(BMessage* msg) } +Conversation* +ConversationView::GetConversation() +{ + return fConversation; +} + + +void +ConversationView::SetConversation(Conversation* chat) +{ + fConversation = chat; + fContact = chat->Users().ValueAt(0); + fPersonalMessage->SetText(chat->GetName()); +} + + +void +ConversationView::UpdateAvatar() +{ + if (fContact->AvatarBitmap() != NULL) + fAvatar->SetBitmap(fContact->AvatarBitmap()); +} + + +void +ConversationView::UpdatePersonalMessage() +{ + if (fContact->GetNotifyPersonalStatus() != NULL) + fPersonalMessage->SetText(fContact->GetNotifyPersonalStatus()); +} + + +void +ConversationView::UpdateUserList(UserMap users) +{ + fUserList->MakeEmpty(); + for (int i = 0; i < users.CountItems(); i++) { + User* user = users.ValueAt(i); + if (fUserList->HasItem(user->GetListItem()) == false) + fUserList->AddItem(user->GetListItem()); + } +} + + void ConversationView::ObserveString(int32 what, BString str) { @@ -291,6 +277,48 @@ ConversationView::AppendStatus(CayaStatus status) } +void +ConversationView::_InitInterface() +{ + fReceiveView = new CayaRenderView("fReceiveView"); + BScrollView* scrollViewReceive = new BScrollView("receiveScrollView", + fReceiveView, B_WILL_DRAW, false, true); + + fPersonalMessage = new BTextView("personalMessage", B_WILL_DRAW); + fPersonalMessage->SetExplicitAlignment( + BAlignment(B_ALIGN_LEFT, B_ALIGN_MIDDLE)); + + fPersonalMessage->SetText(""); + fPersonalMessage->MakeEditable(false); + fPersonalMessage->SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR)); + + fStatus = new BStringView("status", ""); + + fAvatar = new BitmapView("ContactIcon"); + fAvatar->SetExplicitMinSize(BSize(50, 50)); + fAvatar->SetExplicitPreferredSize(BSize(50, 50)); + fAvatar->SetExplicitAlignment(BAlignment(B_ALIGN_RIGHT, B_ALIGN_MIDDLE)); + + fProtocolView = new BitmapView("protocolView"); + + fUserList = new UserListView("userList"); + BScrollView* scrollViewUsers = new BScrollView("userScrollView", + fUserList, B_WILL_DRAW, false, true); + + BLayoutBuilder::Group<>(this, B_VERTICAL) + .AddGroup(B_HORIZONTAL) + .Add(fProtocolView) + .Add(fPersonalMessage) + .Add(fAvatar) + .End() + .AddSplit(B_HORIZONTAL, 0) + .Add(scrollViewReceive, 5) + .Add(scrollViewUsers, 1) + .End(); +// .Add(fStatus, 4) +} + + bool ConversationView::_AppendOrEnqueueMessage(BMessage* msg) { diff --git a/application/views/ConversationView.h b/application/views/ConversationView.h index 6e483e0..e1b17f4 100644 --- a/application/views/ConversationView.h +++ b/application/views/ConversationView.h @@ -7,17 +7,17 @@ #include #include -#include -#include #include "CayaConstants.h" +#include "Conversation.h" -class BMessageQueue; +class BStringView; +class BTextView; class BitmapView; class CayaRenderView; class Contact; -class Conversation; +class UserListView; class ConversationView : public BGroupView { @@ -25,17 +25,19 @@ public: ConversationView(); ConversationView(Conversation* chat); - virtual void MessageReceived(BMessage* message); virtual bool QuitRequested(); + virtual void AttachedToWindow(); + + virtual void MessageReceived(BMessage* message); + void ImMessage(BMessage* msg); Conversation* GetConversation(); void SetConversation(Conversation* chat); - void AttachedToWindow(); void UpdateAvatar(); void UpdatePersonalMessage(); - void ImMessage(BMessage* msg); + void UpdateUserList(UserMap users); void ObserveString(int32 what, BString str); void ObservePointer(int32 what, void* ptr); @@ -46,18 +48,22 @@ public: void AvoidFocus(bool avoid); private: + void _InitInterface(); + bool _AppendOrEnqueueMessage(BMessage* msg); void _AppendMessage(BMessage* msg); Conversation* fConversation; Contact* fContact; + int32 fMessageCount; + BObjectList fMessageQueue; + CayaRenderView* fReceiveView; BStringView* fStatus; BTextView* fPersonalMessage; BitmapView* fProtocolView; BitmapView* fAvatar; - int32 fMessageCount; - BObjectList fMessageQueue; + UserListView* fUserList; }; diff --git a/application/views/RosterListView.cpp b/application/views/RosterListView.cpp index 2e722a2..74fa984 100644 --- a/application/views/RosterListView.cpp +++ b/application/views/RosterListView.cpp @@ -16,9 +16,12 @@ #include #include -#include "UserInfoWindow.h" +#include "CayaProtocolMessages.h" #include "Contact.h" +#include "ProtocolLooper.h" #include "RosterItem.h" +#include "TheApp.h" +#include "UserInfoWindow.h" const int32 kAddPeople = 'ADPL'; const int32 kSendFile = 'SDFL'; @@ -62,24 +65,15 @@ RosterListView::RosterListView(const char* name) fPopUp = new BPopUpMenu("contextMenu", false, false); BMenuItem* item = NULL; - fPopUp->AddItem(new BMenuItem("Start a Conversation", new BMessage(kStartConv))); - item = new BMenuItem("Send a File", new BMessage(kSendFile)); + fPopUp->AddItem(new BMenuItem("Start a chat", new BMessage(kStartConv))); + item = new BMenuItem("Send a file" B_UTF8_ELLIPSIS, new BMessage(kSendFile)); item->SetEnabled(false); fPopUp->AddItem(item); fPopUp->AddItem(new BSeparatorItem()); - fPopUp->AddItem(new BMenuItem("Get Informations", new BMessage(kGetInfo))); - - item = new BMenuItem("Show Logs", new BMessage(kShowLogs)); - item->SetEnabled(false); - fPopUp->AddItem(item); - - fPopUp->AddItem(new BSeparatorItem()); - - item = new BMenuItem("Add to Address Book", new BMessage(kAddPeople)); - item->SetEnabled(false); - fPopUp->AddItem(item); + fPopUp->AddItem(new BMenuItem("User info" B_UTF8_ELLIPSIS, + new BMessage(kGetInfo))); fPopUp->SetTargetForItems(this); } @@ -114,10 +108,15 @@ RosterListView::MessageReceived(BMessage* msg) case kStartConv: { - if (ritem == NULL) + User* user; + if (ritem == NULL || (user = ritem->GetContact()) == NULL) return; -// Contact* link = ritem->GetContact(); -// link->ShowWindow(false, true); + + BMessage* start = new BMessage(IM_MESSAGE); + start->AddInt32("im_what", IM_CREATE_CHAT); + start->AddString("user_id", user->GetId()); + + user->GetProtocolLooper()->PostMessage(start); break; } diff --git a/application/views/UserItem.cpp b/application/views/UserItem.cpp new file mode 100644 index 0000000..d203536 --- /dev/null +++ b/application/views/UserItem.cpp @@ -0,0 +1,43 @@ +/* + * Copyright 2021, Jaidyn Levesque + * All rights reserved. Distributed under the terms of the MIT license. + */ + +#include "UserItem.h" + +#include "User.h" + + +UserItem::UserItem(const char* name, User* user) + : + BStringItem(name), + fUser(user) +{ +} + + +User* +UserItem::GetUser() +{ + return fUser; +} + + +void +UserItem::ObserveString(int32 what, BString str) +{ +} + + +void +UserItem::ObservePointer(int32 what, void* ptr) +{ +} + + +void +UserItem::ObserveInteger(int32 what, int32 val) +{ +} + + diff --git a/application/views/UserItem.h b/application/views/UserItem.h new file mode 100644 index 0000000..ef5638e --- /dev/null +++ b/application/views/UserItem.h @@ -0,0 +1,32 @@ +/* + * Copyright 2021, Jaidyn Levesque + * All rights reserved. Distributed under the terms of the MIT license. + */ +#ifndef USERITEM_H +#define USERITEM_H + +#include + +#include "Observer.h" + +class User; + + +class UserItem : public BStringItem, public Observer { +public: + UserItem(const char* name, User* user); + + User* GetUser(); + +protected: + void ObserveString(int32 what, BString str); + void ObservePointer(int32 what, void* ptr); + void ObserveInteger(int32 what, int32 val); + +private: + User* fUser; +}; + + +#endif // USERITEM_H + diff --git a/application/views/UserListView.cpp b/application/views/UserListView.cpp new file mode 100644 index 0000000..0670cbe --- /dev/null +++ b/application/views/UserListView.cpp @@ -0,0 +1,95 @@ +/* + * Copyright 2021, Jaidyn Levesque + * All rights reserved. Distributed under the terms of the MIT license. + */ + +#include "UserListView.h" + +#include +#include +#include + +#include "CayaMessages.h" +#include "User.h" +#include "UserInfoWindow.h" +#include "UserItem.h" + + +const uint32 kUserInfo = 'ULui'; +//const uint32 kLeaveSelectedChat = 'CVcs'; + + +UserListView::UserListView(const char* name) + : BListView(name) +{ +} + + +void +UserListView::MessageReceived(BMessage* msg) +{ + switch (msg->what) { + case kUserInfo: + { + UserItem* item = (UserItem*)ItemAt(CurrentSelection()); + if (item == NULL) + return; + + UserInfoWindow* win = new UserInfoWindow(item->GetUser()); + win->Show(); + break; + } + + default: + BListView::MessageReceived(msg); + } +} + + +void +UserListView::MouseDown(BPoint where) +{ + BListView::MouseDown(where); + + uint32 buttons = 0; + Window()->CurrentMessage()->FindInt32("buttons", (int32*)&buttons); + + if (!(buttons & B_SECONDARY_MOUSE_BUTTON)) + return; + + if (CurrentSelection() >= 0) + _UserPopUp()->Go(ConvertToScreen(where), true, false); + else + _BlankPopUp()->Go(ConvertToScreen(where), true, false); +} + + +BPopUpMenu* +UserListView::_UserPopUp() +{ + BPopUpMenu* menu = new BPopUpMenu("userPopUp"); + menu->AddItem(new BMenuItem("User info…" B_UTF8_ELLIPSIS, + new BMessage(kUserInfo))); + menu->SetTargetForItems(this); + + return menu; + +} + + +BPopUpMenu* +UserListView::_BlankPopUp() +{ + BPopUpMenu* menu = new BPopUpMenu("blankPopUp"); + + BMenuItem* invite = new BMenuItem("Invite user…" B_UTF8_ELLIPSIS, + new BMessage(CAYA_SEND_INVITE), 'I', B_COMMAND_KEY); + invite->SetEnabled(false); + + menu->AddItem(invite); + menu->SetTargetForItems(Window()); + + return menu; +} + + diff --git a/application/views/UserListView.h b/application/views/UserListView.h new file mode 100644 index 0000000..ded9c48 --- /dev/null +++ b/application/views/UserListView.h @@ -0,0 +1,28 @@ +/* + * 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 UserListView : public BListView { +public: + UserListView(const char* name); + + void MessageReceived(BMessage* msg); + + void MouseDown(BPoint where); + +private: + BPopUpMenu* _UserPopUp(); + BPopUpMenu* _BlankPopUp(); +}; + + +#endif // CONVERSATIONLIST_H +