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.
This commit is contained in:
Jaidyn Ann 2021-05-31 10:50:43 -05:00
parent ca2e05915d
commit 63d8bbef26
14 changed files with 360 additions and 97 deletions

View File

@ -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';

View File

@ -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);

View File

@ -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);

View File

@ -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

View File

@ -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
{

View File

@ -19,9 +19,9 @@
class BBitmap;
class Conversation;
class UserPopUp;
class ProtocolLooper;
class RosterItem;
class UserItem;
class UserPopUp;
typedef KeyMap<BString, Conversation*> 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;

View File

@ -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;

View File

@ -9,9 +9,11 @@
#include "ConversationView.h"
#include <LayoutBuilder.h>
#include <ListView.h>
#include <Notification.h>
#include <ScrollView.h>
#include <StringList.h>
#include <StringView.h>
#include <libinterface/BitmapView.h>
@ -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());
while (fMessageQueue.IsEmpty() == false) {
BMessage* msg = fMessageQueue.RemoveItemAt(0);
ImMessage(msg);
}
void
ConversationView::UpdateAvatar()
{
if (fContact->AvatarBitmap() != NULL)
fAvatar->SetBitmap(fContact->AvatarBitmap());
}
void
ConversationView::UpdatePersonalMessage()
{
if (fContact->GetNotifyPersonalStatus() != NULL)
fPersonalMessage->SetText(fContact->GetNotifyPersonalStatus());
}
@ -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)
{

View File

@ -7,17 +7,17 @@
#include <GroupView.h>
#include <ObjectList.h>
#include <StringView.h>
#include <TextView.h>
#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<BMessage> fMessageQueue;
CayaRenderView* fReceiveView;
BStringView* fStatus;
BTextView* fPersonalMessage;
BitmapView* fProtocolView;
BitmapView* fAvatar;
int32 fMessageCount;
BObjectList<BMessage> fMessageQueue;
UserListView* fUserList;
};

View File

@ -16,9 +16,12 @@
#include <string.h>
#include <stdio.h>
#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;
}

View File

@ -0,0 +1,43 @@
/*
* Copyright 2021, Jaidyn Levesque <jadedctrl@teknik.io>
* 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)
{
}

View File

@ -0,0 +1,32 @@
/*
* Copyright 2021, Jaidyn Levesque <jadedctrl@teknik.io>
* All rights reserved. Distributed under the terms of the MIT license.
*/
#ifndef USERITEM_H
#define USERITEM_H
#include <StringItem.h>
#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

View File

@ -0,0 +1,95 @@
/*
* Copyright 2021, Jaidyn Levesque <jadedctrl@teknik.io>
* All rights reserved. Distributed under the terms of the MIT license.
*/
#include "UserListView.h"
#include <PopUpMenu.h>
#include <MenuItem.h>
#include <Window.h>
#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;
}

View File

@ -0,0 +1,28 @@
/*
* Copyright 2021, Jaidyn Levesque <jadedctrl@teknik.io>
* All rights reserved. Distributed under the terms of the MIT license.
*/
#ifndef CONVERSATIONLIST_H
#define CONVERSATIONLIST_H
#include <ListView.h>
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