From 6d8be225ca6b25669b6d0d6c056c0d20268b821c Mon Sep 17 00:00:00 2001 From: Jaidyn Ann Date: Mon, 2 Aug 2021 21:59:44 -0500 Subject: [PATCH] Scaffolding of a multi-account StatusView MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit StatusView now allows the selecting of accounts through a MenuButton with BitmapMenuItems― the button for selecting an account is nice and discrete, just showing the bitmap of a protocol (in leiu of a label). No functional changes, other than this menu. I tried making all AccountsMenus use BitmapMenuItems, but that gets unweildy pretty quickly― for now they remain in this menu. Maybe optional ownership of bitmaps in BitmapMenuItems and caching of protocol items would help. --- application/AppResources.h | 1 + application/ImageCache.cpp | 2 + application/Makefile | 1 + application/views/StatusView.cpp | 107 +++++++++++++++++++++++++---- application/views/StatusView.h | 13 +++- application/windows/MainWindow.cpp | 10 ++- data/icons/misc/Asterisk | Bin 0 -> 4697 bytes data/icons/misc/Asterisk.rdef | 11 +++ libs/libinterface/BitmapMenuItem.h | 2 +- 9 files changed, 128 insertions(+), 19 deletions(-) create mode 100644 data/icons/misc/Asterisk create mode 100644 data/icons/misc/Asterisk.rdef diff --git a/application/AppResources.h b/application/AppResources.h index 1a28189..9a8827f 100644 --- a/application/AppResources.h +++ b/application/AppResources.h @@ -13,6 +13,7 @@ enum { kToolIcon = 20, kSearchIcon = 21, + kAsteriskIcon = 22, kProtocolSettingsTemplate = 1000, diff --git a/application/ImageCache.cpp b/application/ImageCache.cpp index 5344a9a..e30d693 100644 --- a/application/ImageCache.cpp +++ b/application/ImageCache.cpp @@ -37,6 +37,8 @@ ImageCache::ImageCache() _LoadResource(kBusyReplicant, "kBusyReplicant"); _LoadResource(kOfflineReplicant, "kOfflineReplicant"); _LoadResource(kOnlineReplicant, "kOnlineReplicant"); + + _LoadResource(kAsteriskIcon, "kAsteriskIcon"); } diff --git a/application/Makefile b/application/Makefile index 463f080..caf9b81 100644 --- a/application/Makefile +++ b/application/Makefile @@ -100,6 +100,7 @@ RDEFS = Cardie.rdef \ data/icons/replicant/MessageReceived.rdef \ data/icons/replicant/Offline.rdef \ data/icons/replicant/Online.rdef \ + data/icons/misc/Asterisk.rdef \ data/icons/misc/People-1.rdef \ data/icons/misc/People-2.rdef \ data/icons/misc/People-3.rdef \ diff --git a/application/views/StatusView.cpp b/application/views/StatusView.cpp index 1b63127..0028697 100644 --- a/application/views/StatusView.cpp +++ b/application/views/StatusView.cpp @@ -11,28 +11,31 @@ #include #include #include -#include -#include #include -#include #include #include #include +#include #include "AccountManager.h" +#include "ChatProtocolMessages.h" #include "ImageCache.h" #include "NicknameTextControl.h" +#include "Server.h" #include "StatusMenuItem.h" #include "Utils.h" -const int32 kSetNickname = 'stnk'; +const int32 kSetNickname = 'SVnk'; +const int32 kSelectAllAccounts = 'SVaa'; +const int32 kSelectAccount = 'SVsa'; -StatusView::StatusView(const char* name) +StatusView::StatusView(const char* name, Server* server) : - BView(name, B_WILL_DRAW) + BView(name, B_WILL_DRAW), + fServer(server) { // Nick name fNickname = new NicknameTextControl("Nickname", @@ -72,14 +75,25 @@ StatusView::StatusView(const char* name) fAvatar->SetExplicitPreferredSize(BSize(50, 50)); fAvatar->SetBitmap(ImageCache::Get()->GetImage("kPersonIcon")); + // Changing the account used + fAccountsMenu = new BPopUpMenu("statusAccountsMenu", true, false); + fAccountsButton = new MenuButton("statusAccountsButton", "", new BMessage()); + fAccountsButton->SetMenu(fAccountsMenu); + _PopulateAccountMenu(); + + BMessage selected(kSelectAllAccounts); + MessageReceived(&selected); + // Set layout - BLayoutBuilder::Group<>(this, B_HORIZONTAL) - .AddGroup(B_VERTICAL) + BLayoutBuilder::Group<>(this, B_VERTICAL) + .AddGroup(B_HORIZONTAL) + .SetInsets(0) .Add(statusField) - .AddGroup(B_HORIZONTAL) - .Add(fNickname) - .Add(fAvatar) - .End() + .Add(fAccountsButton) + .End() + .AddGroup(B_HORIZONTAL) + .Add(fNickname) + .Add(fAvatar) .End() .End(); } @@ -106,7 +120,6 @@ StatusView::MessageReceived(BMessage* msg) case kSetStatus: { int32 status; - if (msg->FindInt32("status", &status) != B_OK) return; @@ -114,6 +127,22 @@ StatusView::MessageReceived(BMessage* msg) accountManager->SetStatus((UserStatus)status, ""); break; } + case kSelectAllAccounts: + case kSelectAccount: + { + int32 index = msg->FindInt32("index"); + BitmapMenuItem* item = (BitmapMenuItem*)fAccountsMenu->ItemAt(index); + BBitmap* bitmap = item->Bitmap(); + fAccountsButton->SetIcon(bitmap); + break; + } + case IM_MESSAGE: + { + int32 im_what = msg->GetInt32("im_what", 0); + if (im_what == IM_PROTOCOL_DISABLE || im_what == IM_PROTOCOL_READY) + _PopulateAccountMenu(); + break; + } default: BView::MessageReceived(msg); } @@ -146,3 +175,55 @@ StatusView::SetAvatarIcon(const BBitmap* bitmap) if (bitmap != ImageCache::Get()->GetImage("kPersonIcon")) fAvatar->SetBitmap(bitmap); } + + +void +StatusView::_PopulateAccountMenu() +{ + AccountInstances accounts = fServer->GetActiveAccounts(); + BFont font; + GetFont(&font); + + if (fAccountsMenu->FindItem(B_TRANSLATE("All")) == NULL) { + BBitmap* icon = ImageCache::Get()->GetImage("kAsteriskIcon"); + BBitmap* resized = RescaleBitmap(icon, font.Size(), font.Size()); + + fAccountsMenu->AddItem(new BitmapMenuItem(B_TRANSLATE("All"), + new BMessage(kSelectAllAccounts), resized)); + fAccountsMenu->FindItem(B_TRANSLATE("All"))->SetMarked(true); + } + + // Add unpopulated entries + for (int i = 0; i < accounts.CountItems(); i++) { + BString name = accounts.KeyAt(i); + int64 instance = accounts.ValueAt(i); + ProtocolLooper* looper = fServer->GetProtocolLooper(instance); + if (looper == NULL || looper->Protocol() == NULL + || fAccountsMenu->FindItem(name.String()) != NULL) + continue; + + BBitmap* icon = looper->Protocol()->Icon(); + BBitmap* resized = RescaleBitmap(icon, font.Size(), font.Size()); + + BMessage* selected = new BMessage(kSelectAccount); + selected->AddInt64("instance", instance); + fAccountsMenu->AddItem(new BitmapMenuItem(name.String(), selected, + resized)); + } + + // Remove disabled accounts + if (fAccountsMenu->CountItems() - 1 > accounts.CountItems()) { + fAccountsMenu->FindMarked()->SetMarked(false); + fAccountsMenu->ItemAt(0)->SetMarked(true); + BMessage select(kSelectAllAccounts); + MessageReceived(&select); + + for (int i = 0; i < fAccountsMenu->CountItems(); i++) { + bool found = false; + accounts.ValueFor(BString(fAccountsMenu->ItemAt(i)->Label()), &found); + if (found == false) + fAccountsMenu->RemoveItem(i); + } + } + fAccountsMenu->SetTargetForItems(this); +} diff --git a/application/views/StatusView.h b/application/views/StatusView.h index 66c0459..a41a2d1 100644 --- a/application/views/StatusView.h +++ b/application/views/StatusView.h @@ -12,11 +12,13 @@ class BPopUpMenu; class BitmapView; +class MenuButton; class NicknameTextControl; +class Server; class StatusView : public BView { public: - StatusView(const char* name); + StatusView(const char* name, Server* server); virtual void AttachedToWindow(); virtual void MessageReceived(BMessage* msg); @@ -26,9 +28,16 @@ public: void SetAvatarIcon(const BBitmap* bitmap); private: - BPopUpMenu* fStatusMenu; + void _PopulateAccountMenu(); + NicknameTextControl* fNickname; BitmapView* fAvatar; + BPopUpMenu* fStatusMenu; + + MenuButton* fAccountsButton; + BPopUpMenu* fAccountsMenu; + + Server* fServer; }; #endif // _STATUS_VIEW_H diff --git a/application/windows/MainWindow.cpp b/application/windows/MainWindow.cpp index 691ce3a..5f40aee 100644 --- a/application/windows/MainWindow.cpp +++ b/application/windows/MainWindow.cpp @@ -53,12 +53,12 @@ MainWindow::MainWindow() fRosterWindow(NULL), fServer(NULL) { - _InitInterface(); - // Filter messages using Server fServer = new Server(); AddFilter(fServer); + _InitInterface(); + //TODO check for errors here ReplicantStatusView::InstallReplicant(); } @@ -283,8 +283,12 @@ MainWindow::ImMessage(BMessage* msg) if (fConversation == NULL) fChatView->MessageReceived(msg); _ToggleMenuItems(); + fStatusView->MessageReceived(msg); break; } + case IM_PROTOCOL_DISABLE: + fStatusView->MessageReceived(msg); + break; } } @@ -423,7 +427,7 @@ MainWindow::_InitInterface() { // Left side of window, Roomlist + Status fListView = new ConversationListView("roomList"); - fStatusView = new StatusView("statusView"); + fStatusView = new StatusView("statusView", fServer); fSplitView = new BSplitView(B_HORIZONTAL, 0); // Right-side of window, Chat + Textbox diff --git a/data/icons/misc/Asterisk b/data/icons/misc/Asterisk new file mode 100644 index 0000000000000000000000000000000000000000..c1f1e5233b7798f35ce3b318a2aee514ae387c1b GIT binary patch literal 4697 zcmeHKU1%It6h7NEo2HFT8~;$T3@EkH+WJF$2qBqGe-a_vEhd7(LR~kr-D!4bmYFd& z;={fuBHGX*RPaH3>01@?MSRdju~h7nKKLp=_$EZ8h!lz6ckkZK%$mUX0~O6FH+S!M z&zy7S+;hG=eWEZoJySULh(IzJYn#ZIdqlF>@9WXQQazWEoJ>#86=>s^ZA7)LjP!T$ zM{^>-VUOE!{Ppc3j}K`5W;v>b@-tM@M0Ejr^k||oUd>Bnuw$Y+Pqz^6(Tki->EvU0 zK;&H~G(baiOq+D_MGY6!p2VBCViXR|Vpz|R5a3uI+S0w0FK zn>zSxv8e3O)||yxses1X}sJGJ(f8Q80+|{JaZi{|3Pj*h_n2sj~8bdAtL~R zC|s2%I$p+A91~LU>wbW>RR3)uJtJ$ylqB&vUNg>*%ov4l|5vh<0ZACc?md)HVYb!<1Yi#e(y*S-h~ccsh7hL`2ypa z6eJc=Q1-&AA2iC5>w|@qtWI`*^h|%mb$v3!{O4Dzp#vgO(wdBxn~wSkf^~wXU)MgE z8rQ2ifg4#p?lW5@HFx+wR#Hz_t7Vw?|l#sS0?i98hGFJPKh*J&suUr z_c^!jM$1-MDc2qKe4~73qm7om)knH6*ZYWPyVXZo`M>nh(W367Pp1A(ADu_pq`8kS zqPj>oz4sA0Q-6-8zmLd|asK6he9R|$@4dtONZ)tKduI{2=H=wQLl)Zzf1`u1_X{IW N*)M;B-Ts+V`5o)(Tgw0d literal 0 HcmV?d00001 diff --git a/data/icons/misc/Asterisk.rdef b/data/icons/misc/Asterisk.rdef new file mode 100644 index 0000000..5a2a7bc --- /dev/null +++ b/data/icons/misc/Asterisk.rdef @@ -0,0 +1,11 @@ +#include "application/AppResources.h" + +resource(kAsteriskIcon) #'VICN' array { + $"6E6369660404006603005900020004020080FF80FF80FF80020006020000003C" + $"6000C000000000004C000048A0002580FF80A300B300010A0FB7FEB620B923B5" + $"D0B939B659B81FB670B8D5B75CB852B7A2B7CFB69CB75AB7A2B6D2B75CB785B6" + $"70B66EB659B684B5D0B7A6B620B786B501B81CB501030A0001001245D9190000" + $"000000004607C0CBB8BFCA27CC01178010040A0101001245D919000000000000" + $"4607C0CBE8BFCA57CC01178010040A0301000245D9190000000000004607C0CB" + $"E8BFCA57CC" +}; diff --git a/libs/libinterface/BitmapMenuItem.h b/libs/libinterface/BitmapMenuItem.h index dacd8ca..91cf5d9 100644 --- a/libs/libinterface/BitmapMenuItem.h +++ b/libs/libinterface/BitmapMenuItem.h @@ -29,7 +29,7 @@ public: virtual void DrawContent(void); virtual void SetBitmap(BBitmap *bitmap); - BBitmap* Bitmap(void) const; + BBitmap* Bitmap(void) const { return fBitmap; } private: BBitmap *fBitmap;