AccountsMenu.cpp 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169
  1. /*
  2. * Copyright 2021, Jaidyn Levesque <jadedctrl@teknik.io>
  3. * All rights reserved. Distributed under the terms of the MIT license.
  4. */
  5. #include "AccountsMenu.h"
  6. #include <Bitmap.h>
  7. #include <Catalog.h>
  8. #include <MenuItem.h>
  9. #include <libinterface/BitmapMenuItem.h>
  10. #include <libinterface/BitmapUtils.h>
  11. #include "AccountMenuItem.h"
  12. #include "ImageCache.h"
  13. #include "MainWindow.h"
  14. #include "Server.h"
  15. #include "TheApp.h"
  16. #undef B_TRANSLATION_CONTEXT
  17. #define B_TRANSLATION_CONTEXT "AccountsMenu"
  18. int64 AccountsMenu::fDefaultSelection = -1;
  19. AccountsMenu::AccountsMenu(const char* name, BMessage msg, BMessage* allMsg,
  20. Server* server)
  21. :
  22. BPopUpMenu(name),
  23. fAccountMessage(msg),
  24. fAllMessage(allMsg),
  25. fServer(server)
  26. {
  27. _PopulateMenu();
  28. SetRadioMode(true);
  29. SetLabelFromMarked(true);
  30. fServer->RegisterObserver(this);
  31. }
  32. AccountsMenu::AccountsMenu(const char* name, BMessage msg, BMessage* allMsg)
  33. :
  34. AccountsMenu(name, msg, allMsg,
  35. ((TheApp*)be_app)->GetMainWindow()->GetServer())
  36. {
  37. }
  38. AccountsMenu::~AccountsMenu()
  39. {
  40. delete fAllMessage;
  41. fServer->UnregisterObserver(this);
  42. }
  43. void
  44. AccountsMenu::ObserveInteger(int32 what, int32 value)
  45. {
  46. _PopulateMenu();
  47. }
  48. void
  49. AccountsMenu::SetDefaultSelection(BMenuItem* item)
  50. {
  51. fDefaultSelection = item->Message()->GetInt64("instance", -1);
  52. }
  53. void
  54. AccountsMenu::_PopulateMenu()
  55. {
  56. // Add 'all' item if missing
  57. if (fAllMessage != NULL && FindItem(B_TRANSLATE("All")) == NULL) {
  58. BBitmap* icon = _EnsureAsteriskIcon();
  59. AddItem(new BitmapMenuItem(B_TRANSLATE("All"), new BMessage(*fAllMessage),
  60. icon, 0, 0, false));
  61. }
  62. AccountInstances accounts = fServer->GetActiveAccounts();
  63. // Add protocol item if not already in menu
  64. for (int i = 0; i < accounts.CountItems(); i++) {
  65. int64 instance = accounts.ValueAt(i);
  66. // Initialize default selection if necessary
  67. if (fDefaultSelection == -1)
  68. fDefaultSelection = instance;
  69. BString label = accounts.KeyAt(i).String();
  70. if (label.CountChars() > 15) {
  71. label.RemoveChars(16, label.CountChars() - 16);
  72. label << B_UTF8_ELLIPSIS;
  73. }
  74. if (FindItem(label.String()) != NULL)
  75. continue;
  76. ProtocolLooper* looper = fServer->GetProtocolLooper(instance);
  77. BBitmap* icon = _EnsureProtocolIcon(label.String(), looper);
  78. BMessage* message = new BMessage(fAccountMessage);
  79. message->AddInt64("instance", instance);
  80. AddItem(new AccountMenuItem(label.String(), message, icon));
  81. }
  82. // If an account has been disabled since last population… get ridda it
  83. if ((fAllMessage != NULL && CountItems() - 1 > accounts.CountItems())
  84. || (fAllMessage == NULL && CountItems() > accounts.CountItems()))
  85. for (int i = 0; i < CountItems(); i++) {
  86. bool found = false;
  87. int64 instance = ItemAt(i)->Message()->GetInt64("instance", 0);
  88. for (int j = 0; j < accounts.CountItems(); j++)
  89. if (accounts.ValueAt(j) == instance)
  90. found = true;
  91. if (fAllMessage != NULL && i == 0)
  92. continue;
  93. if (found == false)
  94. RemoveItem(i);
  95. }
  96. // Deselect all
  97. for (int i = 0; i < CountItems(); i++)
  98. ItemAt(i)->SetMarked(false);
  99. // Apply last/default selection
  100. BMenuItem* selection = ItemAt(0);
  101. if (fAllMessage == NULL)
  102. for (int i = 0; i < CountItems(); i++) {
  103. BMenuItem* item = ItemAt(i);
  104. if (item->Message()->GetInt64("instance", -1) == fDefaultSelection)
  105. selection = item;
  106. }
  107. selection->SetMarked(true);
  108. }
  109. BBitmap*
  110. AccountsMenu::_EnsureProtocolIcon(const char* label, ProtocolLooper* looper)
  111. {
  112. BFont font;
  113. BBitmap* icon = ImageCache::Get()->GetImage(label);
  114. if (icon == NULL && looper != NULL && looper->Protocol()->Icon() != NULL) {
  115. BBitmap* unscaled = looper->Protocol()->Icon();
  116. icon = RescaleBitmap(unscaled, font.Size(), font.Size());
  117. ImageCache::Get()->AddImage(label, icon);
  118. }
  119. return icon;
  120. }
  121. BBitmap*
  122. AccountsMenu::_EnsureAsteriskIcon()
  123. {
  124. BFont font;
  125. BBitmap* icon = ImageCache::Get()->GetImage("kAsteriskScaled");
  126. if (icon == NULL) {
  127. BBitmap* unscaled = ImageCache::Get()->GetImage("kAsteriskIcon");
  128. icon = RescaleBitmap(unscaled, font.Size(), font.Size());
  129. ImageCache::Get()->AddImage("kAsteriskScaled", icon);
  130. }
  131. return icon;
  132. }