From 47ca0f416966012ca7fbe124e6b1cfe65459c286 Mon Sep 17 00:00:00 2001 From: Jaidyn Ann Date: Tue, 3 Aug 2021 10:29:19 -0500 Subject: [PATCH] Make all AccountsMenu items BitmapMenuItems Now all account menus will have the pretty protocol icons to go with them. :) The icons are scaled to text-size so that they might be displayed in a corresponding MenuButton, or maybe BMenuField at some point, and put into the ImageCache. The menu items do not have ownership of the bitmaps. --- application/views/AccountMenuItem.cpp | 5 +- application/views/AccountMenuItem.h | 6 +- application/views/AccountsMenu.cpp | 79 +++++++++++++++++++++++++-- application/views/AccountsMenu.h | 7 +++ 4 files changed, 87 insertions(+), 10 deletions(-) diff --git a/application/views/AccountMenuItem.cpp b/application/views/AccountMenuItem.cpp index fa927c3..cc07613 100644 --- a/application/views/AccountMenuItem.cpp +++ b/application/views/AccountMenuItem.cpp @@ -8,9 +8,10 @@ #include "AccountsMenu.h" -AccountMenuItem::AccountMenuItem(const char* label, BMessage* msg) +AccountMenuItem::AccountMenuItem(const char* label, BMessage* msg, + BBitmap* icon) : - BMenuItem(label, msg) + BitmapMenuItem(label, msg, icon, 0, 0, false) { } diff --git a/application/views/AccountMenuItem.h b/application/views/AccountMenuItem.h index a3010eb..2e510c3 100644 --- a/application/views/AccountMenuItem.h +++ b/application/views/AccountMenuItem.h @@ -7,10 +7,12 @@ #include +#include -class AccountMenuItem : public BMenuItem { + +class AccountMenuItem : public BitmapMenuItem { public: - AccountMenuItem(const char* label, BMessage* msg); + AccountMenuItem(const char* label, BMessage* msg, BBitmap* icon = NULL); virtual void SetMarked(bool mark); }; diff --git a/application/views/AccountsMenu.cpp b/application/views/AccountsMenu.cpp index 2a070b0..0dd7005 100644 --- a/application/views/AccountsMenu.cpp +++ b/application/views/AccountsMenu.cpp @@ -5,10 +5,15 @@ #include "AccountsMenu.h" +#include #include #include +#include +#include + #include "AccountMenuItem.h" +#include "ImageCache.h" #include "MainWindow.h" #include "Server.h" #include "TheApp.h" @@ -64,26 +69,56 @@ AccountsMenu::SetDefaultSelection(BMenuItem* item) void AccountsMenu::_PopulateMenu() { - if (CountItems() > 0) - RemoveItems(0, CountItems(), true); - - if (fAllMessage != NULL) - AddItem(new BMenuItem(B_TRANSLATE("All"), new BMessage(*fAllMessage))); + BFont font; + GetFont(&font); + + // Add 'all' item if missing + if (fAllMessage != NULL && FindItem(B_TRANSLATE("All")) == NULL) { + BBitmap* icon = _EnsureAsteriskIcon(); + AddItem(new BitmapMenuItem(B_TRANSLATE("All"), new BMessage(*fAllMessage), + icon, 0, 0, false)); + } Server* server = ((TheApp*)be_app)->GetMainWindow()->GetServer(); AccountInstances accounts = server->GetActiveAccounts(); + // Add protocol item if not already in menu for (int i = 0; i < accounts.CountItems(); i++) { + int64 instance = accounts.ValueAt(i); BString label = accounts.KeyAt(i).String(); if (label.CountChars() > 15) { label.RemoveChars(16, label.CountChars() - 16); label << B_UTF8_ELLIPSIS; } - AddItem(new AccountMenuItem(label.String(), new BMessage(fAccountMessage))); + + if (FindItem(label.String()) != NULL) + continue; + + ProtocolLooper* looper = server->GetProtocolLooper(instance); + BBitmap* icon = _EnsureProtocolIcon(label.String(), looper); + + BMessage* message = new BMessage(fAccountMessage); + message->AddInt64("instance", instance); + AddItem(new AccountMenuItem(label.String(), message, icon)); } int32 selection = fDefaultSelection; + // If an account has been disabled since last population… get ridda it + if ((fAllMessage != NULL && CountItems() - 1 > accounts.CountItems()) + || (fAllMessage == NULL && CountItems() > accounts.CountItems())) + for (int i = 0; i < CountItems(); i++) { + bool found = false; + int64 instance = ItemAt(i)->Message()->GetInt64("instance", 0); + for (int j = 0; j < accounts.CountItems(); j++) + if (accounts.ValueAt(j) == instance) + found = true; + + if (found == false) + RemoveItem(i); + } + + // Apply last/default selection if (fAllMessage == NULL && selection < CountItems() && selection >= 0) ItemAt(selection)->SetMarked(true); else if (CountItems() > 0) @@ -91,3 +126,35 @@ AccountsMenu::_PopulateMenu() else SetEnabled(false); } + + +BBitmap* +AccountsMenu::_EnsureProtocolIcon(const char* label, ProtocolLooper* looper) +{ + BFont font; + GetFont(&font); + BBitmap* icon = ImageCache::Get()->GetImage(label); + + if (icon == NULL && looper != NULL && looper->Protocol()->Icon() != NULL) { + BBitmap* unscaled = looper->Protocol()->Icon(); + icon = RescaleBitmap(unscaled, font.Size(), font.Size()); + ImageCache::Get()->AddImage(label, icon); + } + return icon; +} + + +BBitmap* +AccountsMenu::_EnsureAsteriskIcon() +{ + BFont font; + GetFont(&font); + BBitmap* icon = ImageCache::Get()->GetImage("kAsteriskScaled"); + + if (icon == NULL) { + BBitmap* unscaled = ImageCache::Get()->GetImage("kAsteriskIcon"); + icon = RescaleBitmap(unscaled, font.Size(), font.Size()); + ImageCache::Get()->AddImage("kAsteriskScaled", icon); + } + return icon; +} diff --git a/application/views/AccountsMenu.h b/application/views/AccountsMenu.h index 4a6d2bc..0842129 100644 --- a/application/views/AccountsMenu.h +++ b/application/views/AccountsMenu.h @@ -9,6 +9,8 @@ #include "Observer.h" +class ProtocolLooper; + class AccountsMenu : public BMenu, public Observer { public: @@ -23,6 +25,11 @@ public: private: void _PopulateMenu(); + BBitmap* _EnsureProtocolIcon(const char* label, + ProtocolLooper* looper); + BBitmap* _EnsureAsteriskIcon(); + + BMessage fAccountMessage; BMessage* fAllMessage; static int32 fDefaultSelection;