Group rooms in roomlist by account

The ConversationListView is now an BOutlineListView, and rooms are
added as subitems to the item of their associated account. Right now,
account items aren't selectable or useful.
This commit is contained in:
Jaidyn Ann 2021-06-11 17:24:04 -05:00
parent 86f64cfa40
commit 552e937e51
10 changed files with 198 additions and 43 deletions

View File

@ -57,6 +57,7 @@ SRCS = \
application/preferences/PreferencesBehavior.cpp \ application/preferences/PreferencesBehavior.cpp \
application/preferences/PreferencesReplicant.cpp \ application/preferences/PreferencesReplicant.cpp \
application/views/CayaRenderView.cpp \ application/views/CayaRenderView.cpp \
application/views/ConversationAccountItem.cpp \
application/views/ConversationItem.cpp \ application/views/ConversationItem.cpp \
application/views/ConversationListView.cpp \ application/views/ConversationListView.cpp \
application/views/ConversationView.cpp \ application/views/ConversationView.cpp \

View File

@ -1,4 +1,5 @@
/* /*
* Copyright 2021, Jaidyn Levesque. All rights reserved.
* Copyright 2009-2011, Andrea Anzani. All rights reserved. * Copyright 2009-2011, Andrea Anzani. All rights reserved.
* Copyright 2009-2011, Pier Luigi Fiorini. All rights reserved. * Copyright 2009-2011, Pier Luigi Fiorini. All rights reserved.
* Distributed under the terms of the MIT License. * Distributed under the terms of the MIT License.
@ -14,13 +15,15 @@
#include "Account.h" #include "Account.h"
#include "Conversation.h" #include "Conversation.h"
#include "ConversationAccountItem.h"
ProtocolLooper::ProtocolLooper(CayaProtocol* protocol, int64 instance) ProtocolLooper::ProtocolLooper(CayaProtocol* protocol, int64 instance)
: :
BLooper(), BLooper(),
fProtocol(protocol), fProtocol(protocol),
fInstance(instance) fInstance(instance),
fListItem(NULL)
{ {
Account* account = reinterpret_cast<Account*>( Account* account = reinterpret_cast<Account*>(
protocol->MessengerInterface()); protocol->MessengerInterface());
@ -153,3 +156,13 @@ ProtocolLooper::GetInstance()
} }
ConversationAccountItem*
ProtocolLooper::GetListItem()
{
if (fListItem == NULL)
fListItem = new ConversationAccountItem(fProtocol->GetName(),
fInstance);
return fListItem;
}

View File

@ -1,4 +1,5 @@
/* /*
* Copyright 2021, Jaidyn Levesque. All rights reserved.
* Copyright 2009-2011, Andrea Anzani. All rights reserved. * Copyright 2009-2011, Andrea Anzani. All rights reserved.
* Copyright 2009-2011, Pier Luigi Fiorini. All rights reserved. * Copyright 2009-2011, Pier Luigi Fiorini. All rights reserved.
* Distributed under the terms of the MIT License. * Distributed under the terms of the MIT License.
@ -15,6 +16,7 @@
class Contact; class Contact;
class Conversation; class Conversation;
class ConversationAccountItem;
class User; class User;
@ -49,6 +51,9 @@ public:
int64 GetInstance(); int64 GetInstance();
ConversationAccountItem*
GetListItem();
private: private:
CayaProtocol* fProtocol; CayaProtocol* fProtocol;
int64 fInstance; int64 fInstance;
@ -58,6 +63,9 @@ private:
ChatMap fChatMap; ChatMap fChatMap;
RosterMap fRosterMap; RosterMap fRosterMap;
UserMap fUserMap; UserMap fUserMap;
ConversationAccountItem*
fListItem;
}; };
#endif // _PROTOCOL_LOOPER_H #endif // _PROTOCOL_LOOPER_H

View File

@ -0,0 +1,23 @@
/*
* Copyright 2021, Jaidyn Levesque <jadedctrl@teknik.io>
* All rights reserved. Distributed under the terms of the MIT license.
*/
#include "ConversationAccountItem.h"
ConversationAccountItem::ConversationAccountItem(const char* name, int64 instance)
:
BStringItem(name),
fInstance(instance)
{
}
int64
ConversationAccountItem::GetInstance()
{
return fInstance;
}

View File

@ -0,0 +1,25 @@
/*
* Copyright 2021, Jaidyn Levesque <jadedctrl@teknik.io>
* All rights reserved. Distributed under the terms of the MIT license.
*/
#ifndef CONVERSATIONACCITEM_H
#define CONVERSATIONACCITEM_H
#include <StringItem.h>
class Conversation;
class ConversationAccountItem : public BStringItem {
public:
ConversationAccountItem(const char* name, int64 instance);
int64 GetInstance();
private:
int64 fInstance;
};
#endif // CONVERSATIONACCITEM_H

View File

@ -5,7 +5,7 @@
#ifndef CONVERSATIONITEM_H #ifndef CONVERSATIONITEM_H
#define CONVERSATIONITEM_H #define CONVERSATIONITEM_H
#include <ListView.h> #include <StringItem.h>
#include "Observer.h" #include "Observer.h"

View File

@ -12,6 +12,7 @@
#include "CayaMessages.h" #include "CayaMessages.h"
#include "CayaProtocolMessages.h" #include "CayaProtocolMessages.h"
#include "Conversation.h" #include "Conversation.h"
#include "ConversationAccountItem.h"
#include "ConversationItem.h" #include "ConversationItem.h"
#include "ProtocolLooper.h" #include "ProtocolLooper.h"
@ -21,7 +22,7 @@ const uint32 kLeaveSelectedChat = 'CVcs';
ConversationListView::ConversationListView(const char* name) ConversationListView::ConversationListView(const char* name)
: BListView(name) : BOutlineListView(name)
{ {
} }
@ -35,7 +36,8 @@ ConversationListView::MessageReceived(BMessage* msg)
ConversationItem* item; ConversationItem* item;
int32 selIndex = CurrentSelection(); int32 selIndex = CurrentSelection();
if ((item = (ConversationItem*)ItemAt(selIndex)) != NULL) if (ItemAt(selIndex)->OutlineLevel() == 1
&& (item = (ConversationItem*)ItemAt(selIndex)) != NULL)
item->GetConversation()->ShowView(false, true); item->GetConversation()->ShowView(false, true);
break; break;
} }
@ -66,10 +68,18 @@ ConversationListView::MouseDown(BPoint where)
{ {
int32 selection = CurrentSelection(); int32 selection = CurrentSelection();
BListView::MouseDown(where); BOutlineListView::MouseDown(where);
// Don't allow deselcting a room int32 newSel = CurrentSelection();
if (CurrentSelection() < 0 && selection >= 0)
// Don't allow selecting an AccountItem
if (ItemAt(newSel)->OutlineLevel() == 0) {
Select(selection);
return;
}
// Don't allow deselecting a room
if (newSel < 0 && selection >= 0)
Select(selection); Select(selection);
uint32 buttons = 0; uint32 buttons = 0;
@ -92,6 +102,68 @@ ConversationListView::SelectionChanged()
} }
void
ConversationListView::AddConversation(Conversation* chat)
{
ConversationAccountItem* superItem = _EnsureAccountItem(chat);
ConversationItem* item = chat->GetListItem();
if (superItem == NULL || item == NULL)
return;
AddUnder(item, superItem);
}
void
ConversationListView::RemoveConversation(Conversation* chat)
{
RemoveItem(chat->GetListItem());
}
int32
ConversationListView::CountConversations()
{
int32 count = 0;
for (int32 i = 0; i < CountItems(); i++)
if (ItemAt(i)->OutlineLevel() == 1)
count++;
return count;
}
int32
ConversationListView::ConversationIndexOf(Conversation* chat)
{
ConversationItem* item = chat->GetListItem();
int32 index = IndexOf(item);
int32 chatIndex = index;
if (item == NULL || index < 0)
return -1;
for (int i = 0; i < index; i++)
if (ItemAt(i)->OutlineLevel() == 0) // If AccountItem
chatIndex--;
return chatIndex;
}
void
ConversationListView::SelectConversation(int32 index)
{
for (int32 i = 0, cindex = -1; i < CountItems(); i++) {
if (ItemAt(i)->OutlineLevel() == 1) // If ConversationItem
cindex++;
if (cindex == index) {
Select(i);
break;
}
}
}
BPopUpMenu* BPopUpMenu*
ConversationListView::_ConversationPopUp() ConversationListView::_ConversationPopUp()
{ {
@ -118,3 +190,18 @@ ConversationListView::_BlankPopUp()
} }
ConversationAccountItem*
ConversationListView::_EnsureAccountItem(Conversation* chat)
{
ProtocolLooper* looper;
if (chat == NULL || (looper = chat->GetProtocolLooper()) == NULL)
return NULL;
ConversationAccountItem* item = looper->GetListItem();
if (HasItem(item) == false)
AddItem(item);
return item;
}

View File

@ -8,9 +8,11 @@
#include <OutlineListView.h> #include <OutlineListView.h>
class BPopUpMenu; class BPopUpMenu;
class Conversation;
class ConversationAccountItem;
class ConversationListView : public BListView { class ConversationListView : public BOutlineListView {
public: public:
ConversationListView(const char* name); ConversationListView(const char* name);
@ -18,9 +20,18 @@ public:
void SelectionChanged(); void SelectionChanged();
void MouseDown(BPoint where); void MouseDown(BPoint where);
void AddConversation(Conversation* chat);
void RemoveConversation(Conversation* chat);
int32 CountConversations();
int32 ConversationIndexOf(Conversation* chat);
void SelectConversation(int32 index);
private: private:
BPopUpMenu* _ConversationPopUp(); BPopUpMenu* _ConversationPopUp();
BPopUpMenu* _BlankPopUp(); BPopUpMenu* _BlankPopUp();
ConversationAccountItem* _EnsureAccountItem(Conversation* chat);
}; };

View File

@ -1,4 +1,5 @@
/* /*
* Copyright 2021, Jaidyn Levesque. All rights reserved.
* Copyright 2009-2011, Andrea Anzani. All rights reserved. * Copyright 2009-2011, Andrea Anzani. All rights reserved.
* Copyright 2009-2011, Pier Luigi Fiorini. All rights reserved. * Copyright 2009-2011, Pier Luigi Fiorini. All rights reserved.
* Distributed under the terms of the MIT License. * Distributed under the terms of the MIT License.
@ -87,10 +88,9 @@ MainWindow::QuitRequested()
ReplicantStatusView::RemoveReplicant(); ReplicantStatusView::RemoveReplicant();
be_app->PostMessage(B_QUIT_REQUESTED); be_app->PostMessage(B_QUIT_REQUESTED);
return true; return true;
} else { } else
return false; return false;
} }
}
void void
@ -146,9 +146,9 @@ MainWindow::MessageReceived(BMessage* message)
if (fConversation == NULL) if (fConversation == NULL)
break; break;
int32 index = fListView->IndexOf(fConversation->GetListItem()); int32 index = fListView->ConversationIndexOf(fConversation);
if (index > 0) if (index > 0)
fListView->Select(index - 1); fListView->SelectConversation(index - 1);
break; break;
} }
@ -157,10 +157,10 @@ MainWindow::MessageReceived(BMessage* message)
if (fConversation == NULL) if (fConversation == NULL)
break; break;
int32 index = fListView->IndexOf(fConversation->GetListItem()); int32 index = fListView->ConversationIndexOf(fConversation);
int32 count = fListView->CountItems(); int32 count = fListView->CountConversations();
if (index < (count - 1)) if (index < (count - 1))
fListView->Select(index + 1); fListView->SelectConversation(index + 1);
break; break;
} }
@ -249,7 +249,7 @@ MainWindow::ImMessage(BMessage* msg)
if (item == NULL) if (item == NULL)
break; break;
_RemoveListItem(item); _RemoveConversation(item->GetConversation());
item->GetConversation()->GetView()->MessageReceived(msg); item->GetConversation()->GetView()->MessageReceived(msg);
break; break;
} }
@ -425,18 +425,16 @@ MainWindow::_EnsureConversationItem(BMessage* msg)
BString chat_id = msg->FindString("chat_id"); BString chat_id = msg->FindString("chat_id");
Conversation* chat = fServer->ConversationById(chat_id, msg->FindInt64("instance")); Conversation* chat = fServer->ConversationById(chat_id, msg->FindInt64("instance"));
ConversationItem* item = chat->GetListItem();
if (chat != NULL) { if (chat != NULL) {
ConversationItem* item = chat->GetListItem(); if (fListView->HasItem(item))
if (fListView->HasItem(item)) { fListView->InvalidateItem(fListView->IndexOf(item));
_UpdateListItem(item); else if (item != NULL)
} fListView->AddConversation(chat);
else if (item != NULL) {
fListView->AddItem(item);
}
if (fListView->CountItems() == 1) if (fListView->CountConversations() == 1)
fListView->Select(0); fListView->SelectConversation(0);
return item; return item;
} }
@ -445,35 +443,24 @@ MainWindow::_EnsureConversationItem(BMessage* msg)
void void
MainWindow::_UpdateListItem(ConversationItem* item) MainWindow::_RemoveConversation(Conversation* chat)
{ {
if (fListView->HasItem(item) == true) int32 index = fListView->ConversationIndexOf(chat);
fListView->InvalidateItem(fListView->IndexOf(item));
else
fListView->AddItem(item);
}
void
MainWindow::_RemoveListItem(ConversationItem* item)
{
int32 index = fListView->IndexOf(item);
if (index > 0) if (index > 0)
index--; index--;
fListView->RemoveItem(item); fListView->RemoveConversation(chat);
Conversation* chat = item->GetConversation();
ProtocolLooper* looper = chat->GetProtocolLooper(); ProtocolLooper* looper = chat->GetProtocolLooper();
if (chat != NULL && looper != NULL) if (chat != NULL && looper != NULL)
looper->RemoveConversation(chat); looper->RemoveConversation(chat);
if (fListView->CountItems() == 0) { if (fListView->CountConversations() == 0) {
fChatView = new ConversationView(); fChatView = new ConversationView();
SetConversation(NULL); SetConversation(NULL);
} }
else else
fListView->Select(index); fListView->SelectConversation(index);
} }

View File

@ -1,4 +1,5 @@
/* /*
* Copyright 2021, Jaidyn Levesque. All rights reserved.
* Copyright 2009-2011, Andrea Anzani. All rights reserved. * Copyright 2009-2011, Andrea Anzani. All rights reserved.
* Copyright 2009-2011, Pier Luigi Fiorini. All rights reserved. * Copyright 2009-2011, Pier Luigi Fiorini. All rights reserved.
* Distributed under the terms of the MIT License. * Distributed under the terms of the MIT License.
@ -50,8 +51,7 @@ private:
ConversationItem* ConversationItem*
_EnsureConversationItem(BMessage* msg); _EnsureConversationItem(BMessage* msg);
void _UpdateListItem(ConversationItem* item); void _RemoveConversation(Conversation* chat);
void _RemoveListItem(ConversationItem* item);
Server* fServer; Server* fServer;