StatusView.cpp 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235
  1. /*
  2. * Copyright 2009, Pier Luigi Fiorini. All rights reserved.
  3. * Copyright 2021, Jaidyn Levesque. All rights reserved.
  4. * Distributed under the terms of the MIT License.
  5. *
  6. * Authors:
  7. * Pier Luigi Fiorini, pierluigi.fiorini@gmail.com
  8. * Jaidyn Levesque, jadedctrl@teknik.io
  9. */
  10. #include "StatusView.h"
  11. #include <Bitmap.h>
  12. #include <LayoutBuilder.h>
  13. #include <Message.h>
  14. #include <PopUpMenu.h>
  15. #include <libinterface/BitmapMenuItem.h>
  16. #include <libinterface/BitmapUtils.h>
  17. #include <libinterface/BitmapView.h>
  18. #include <libinterface/EnterTextView.h>
  19. #include <libinterface/MenuButton.h>
  20. #include "AccountsMenu.h"
  21. #include "ChatProtocolMessages.h"
  22. #include "Contact.h"
  23. #include "ImageCache.h"
  24. #include "NotifyMessage.h"
  25. #include "Server.h"
  26. #include "StatusManager.h"
  27. #include "StatusMenuItem.h"
  28. #include "Utils.h"
  29. const int32 kSelectAccount = 'SVsa';
  30. const int32 kSetNick = 'SVsn';
  31. StatusView::StatusView(const char* name, Server* server)
  32. :
  33. BView(name, B_WILL_DRAW),
  34. fServer(server),
  35. fAccount(-1)
  36. {
  37. // Nick name
  38. fNickname = new EnterTextView("nicknameTextView", be_bold_font, NULL);
  39. fNickname->MakeEditable(true);
  40. fNickname->MakeResizable(true);
  41. fNickname->SetTarget(this);
  42. fNickname->SetMessage(BMessage(kSetNick), "nick");
  43. // Status menu
  44. fStatusMenu = new BPopUpMenu("-");
  45. // Add status menu items
  46. int32 s = STATUS_ONLINE;
  47. while (s >= STATUS_ONLINE && s < STATUS_STATUSES) {
  48. StatusMenuItem* item = new StatusMenuItem(UserStatusToString(
  49. (UserStatus)s), (UserStatus)s);
  50. fStatusMenu->AddItem(item);
  51. /*// Add items for custom messages
  52. if (s == STATUS_ONLINE || s == STATUS_DO_NOT_DISTURB) {
  53. item = new StatusMenuItem("Custom...", (UserStatus)s, true);
  54. fStatusMenu->AddItem(item);
  55. fStatusMenu->AddItem(new BSeparatorItem());
  56. }*/
  57. // Mark offline status by default
  58. if (s == STATUS_OFFLINE)
  59. item->SetMarked(true);
  60. s++;
  61. }
  62. // Menu field
  63. BMenuField* statusField = new BMenuField("StatusField", NULL,
  64. fStatusMenu);
  65. // Icon
  66. fAvatar = new BitmapView("AvatarIcon");
  67. fAvatar->SetExplicitMaxSize(BSize(50, 50));
  68. fAvatar->SetExplicitPreferredSize(BSize(50, 50));
  69. fAvatar->SetBitmap(ImageCache::Get()->GetImage("kPersonIcon"));
  70. // Changing the account used
  71. fAccountsMenu = new AccountsMenu("statusAccountsMenu",
  72. BMessage(kSelectAccount), new BMessage(kSelectAccount), fServer);
  73. fAccountsButton = new MenuButton("statusAccountsButton", "", new BMessage());
  74. fAccountsButton->SetMenu(fAccountsMenu);
  75. BMessage selected(kSelectAccount);
  76. MessageReceived(&selected);
  77. // Set layout
  78. BLayoutBuilder::Group<>(this, B_VERTICAL)
  79. .AddGroup(B_HORIZONTAL)
  80. .SetInsets(0)
  81. .Add(statusField)
  82. .Add(fAccountsButton)
  83. .End()
  84. .AddGroup(B_HORIZONTAL)
  85. .Add(fNickname)
  86. .Add(fAvatar)
  87. .End()
  88. .End();
  89. }
  90. void
  91. StatusView::AttachedToWindow()
  92. {
  93. //fNickname->SetTarget(this);
  94. fStatusMenu->SetTargetForItems(this);
  95. }
  96. void
  97. StatusView::MessageReceived(BMessage* msg)
  98. {
  99. switch (msg->what) {
  100. case kSetNick:
  101. {
  102. BString nick;
  103. if (msg->FindString("nick", &nick) == B_OK)
  104. StatusManager::Get()->SetNickname(nick, fAccount);
  105. _SetToAccount();
  106. break;
  107. }
  108. case kSetStatus:
  109. {
  110. int32 status;
  111. if (msg->FindInt32("status", &status) == B_OK)
  112. StatusManager::Get()->SetStatus((UserStatus)status, "",
  113. fAccount);
  114. _SetToAccount();
  115. break;
  116. }
  117. case kSelectAccount:
  118. {
  119. int32 index = msg->GetInt32("index", 0);
  120. BitmapMenuItem* item = (BitmapMenuItem*)fAccountsMenu->ItemAt(index);
  121. // Set button icon/label
  122. fAccountsButton->SetLabel("");
  123. BBitmap* bitmap = item->Bitmap();
  124. fAccountsButton->SetIcon(bitmap);
  125. if (bitmap == NULL) {
  126. char label[2] = { item->Label()[0], '\0' };
  127. fAccountsButton->SetLabel(label);
  128. }
  129. fAccount = msg->GetInt64("instance", -1);
  130. _SetToAccount();
  131. break;
  132. }
  133. case IM_MESSAGE: {
  134. int32 im_what = msg->GetInt32("im_what", 0);
  135. if (im_what == IM_PROTOCOL_READY || im_what == IM_PROTOCOL_DISABLE)
  136. fAccountsMenu->SetTargetForItems(this);
  137. break;
  138. }
  139. default:
  140. BView::MessageReceived(msg);
  141. }
  142. }
  143. void
  144. StatusView::ObserveString(int32 what, BString str)
  145. {
  146. if (what == STR_CONTACT_NAME || what == STR_PERSONAL_STATUS)
  147. _SetToAccount();
  148. }
  149. void
  150. StatusView::ObserveInteger(int32 what, int32 value)
  151. {
  152. if (what == INT_ACCOUNT_STATUS || what == INT_CONTACT_STATUS)
  153. _SetToAccount();
  154. }
  155. void
  156. StatusView::ObservePointer(int32 what, void* ptr)
  157. {
  158. if (what == PTR_AVATAR_BITMAP)
  159. _SetToAccount();
  160. }
  161. void
  162. StatusView::_SetToAccount()
  163. {
  164. int64 instance = fAccount;
  165. if (instance == -1)
  166. instance = fServer->GetActiveAccounts().ValueAt(0);
  167. ProtocolLooper* looper = fServer->GetProtocolLooper(instance);
  168. if (looper == NULL || looper->GetOwnContact() == NULL)
  169. return;
  170. Contact* contact = looper->GetOwnContact();
  171. _SetAvatarIcon(contact->AvatarBitmap());
  172. _SetName(contact->GetName());
  173. _SetStatus(contact->GetNotifyStatus());
  174. }
  175. void
  176. StatusView::_SetName(BString name)
  177. {
  178. fNickname->SetText(name.String());
  179. }
  180. void
  181. StatusView::_SetStatus(UserStatus status)
  182. {
  183. for (int32 i = 0; i < fStatusMenu->CountItems(); i++) {
  184. StatusMenuItem* item
  185. = reinterpret_cast<StatusMenuItem*>(fStatusMenu->ItemAt(i));
  186. if (item && item->Status() == status && !item->IsCustom())
  187. item->SetMarked(true);
  188. }
  189. }
  190. void
  191. StatusView::_SetAvatarIcon(const BBitmap* bitmap)
  192. {
  193. fAvatar->SetBitmap(bitmap);
  194. }