123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235 |
- /*
- * Copyright 2009, Pier Luigi Fiorini. All rights reserved.
- * Copyright 2021, Jaidyn Levesque. All rights reserved.
- * Distributed under the terms of the MIT License.
- *
- * Authors:
- * Pier Luigi Fiorini, pierluigi.fiorini@gmail.com
- * Jaidyn Levesque, jadedctrl@teknik.io
- */
- #include "StatusView.h"
- #include <Bitmap.h>
- #include <LayoutBuilder.h>
- #include <Message.h>
- #include <PopUpMenu.h>
- #include <libinterface/BitmapMenuItem.h>
- #include <libinterface/BitmapUtils.h>
- #include <libinterface/BitmapView.h>
- #include <libinterface/EnterTextView.h>
- #include <libinterface/MenuButton.h>
- #include "AccountsMenu.h"
- #include "ChatProtocolMessages.h"
- #include "Contact.h"
- #include "ImageCache.h"
- #include "NotifyMessage.h"
- #include "Server.h"
- #include "StatusManager.h"
- #include "StatusMenuItem.h"
- #include "Utils.h"
- const int32 kSelectAccount = 'SVsa';
- const int32 kSetNick = 'SVsn';
- StatusView::StatusView(const char* name, Server* server)
- :
- BView(name, B_WILL_DRAW),
- fServer(server),
- fAccount(-1)
- {
- // Nick name
- fNickname = new EnterTextView("nicknameTextView", be_bold_font, NULL);
- fNickname->MakeEditable(true);
- fNickname->MakeResizable(true);
- fNickname->SetTarget(this);
- fNickname->SetMessage(BMessage(kSetNick), "nick");
- // Status menu
- fStatusMenu = new BPopUpMenu("-");
- // Add status menu items
- int32 s = STATUS_ONLINE;
- while (s >= STATUS_ONLINE && s < STATUS_STATUSES) {
- StatusMenuItem* item = new StatusMenuItem(UserStatusToString(
- (UserStatus)s), (UserStatus)s);
- fStatusMenu->AddItem(item);
- /*// Add items for custom messages
- if (s == STATUS_ONLINE || s == STATUS_DO_NOT_DISTURB) {
- item = new StatusMenuItem("Custom...", (UserStatus)s, true);
- fStatusMenu->AddItem(item);
- fStatusMenu->AddItem(new BSeparatorItem());
- }*/
- // Mark offline status by default
- if (s == STATUS_OFFLINE)
- item->SetMarked(true);
- s++;
- }
- // Menu field
- BMenuField* statusField = new BMenuField("StatusField", NULL,
- fStatusMenu);
- // Icon
- fAvatar = new BitmapView("AvatarIcon");
- fAvatar->SetExplicitMaxSize(BSize(50, 50));
- fAvatar->SetExplicitPreferredSize(BSize(50, 50));
- fAvatar->SetBitmap(ImageCache::Get()->GetImage("kPersonIcon"));
- // Changing the account used
- fAccountsMenu = new AccountsMenu("statusAccountsMenu",
- BMessage(kSelectAccount), new BMessage(kSelectAccount), fServer);
- fAccountsButton = new MenuButton("statusAccountsButton", "", new BMessage());
- fAccountsButton->SetMenu(fAccountsMenu);
- BMessage selected(kSelectAccount);
- MessageReceived(&selected);
- // Set layout
- BLayoutBuilder::Group<>(this, B_VERTICAL)
- .AddGroup(B_HORIZONTAL)
- .SetInsets(0)
- .Add(statusField)
- .Add(fAccountsButton)
- .End()
- .AddGroup(B_HORIZONTAL)
- .Add(fNickname)
- .Add(fAvatar)
- .End()
- .End();
- }
- void
- StatusView::AttachedToWindow()
- {
- //fNickname->SetTarget(this);
- fStatusMenu->SetTargetForItems(this);
- }
- void
- StatusView::MessageReceived(BMessage* msg)
- {
- switch (msg->what) {
- case kSetNick:
- {
- BString nick;
- if (msg->FindString("nick", &nick) == B_OK)
- StatusManager::Get()->SetNickname(nick, fAccount);
- _SetToAccount();
- break;
- }
- case kSetStatus:
- {
- int32 status;
- if (msg->FindInt32("status", &status) == B_OK)
- StatusManager::Get()->SetStatus((UserStatus)status, "",
- fAccount);
- _SetToAccount();
- break;
- }
- case kSelectAccount:
- {
- int32 index = msg->GetInt32("index", 0);
- BitmapMenuItem* item = (BitmapMenuItem*)fAccountsMenu->ItemAt(index);
- // Set button icon/label
- fAccountsButton->SetLabel("");
- BBitmap* bitmap = item->Bitmap();
- fAccountsButton->SetIcon(bitmap);
- if (bitmap == NULL) {
- char label[2] = { item->Label()[0], '\0' };
- fAccountsButton->SetLabel(label);
- }
- fAccount = msg->GetInt64("instance", -1);
- _SetToAccount();
- break;
- }
- case IM_MESSAGE: {
- int32 im_what = msg->GetInt32("im_what", 0);
- if (im_what == IM_PROTOCOL_READY || im_what == IM_PROTOCOL_DISABLE)
- fAccountsMenu->SetTargetForItems(this);
- break;
- }
- default:
- BView::MessageReceived(msg);
- }
- }
- void
- StatusView::ObserveString(int32 what, BString str)
- {
- if (what == STR_CONTACT_NAME || what == STR_PERSONAL_STATUS)
- _SetToAccount();
- }
- void
- StatusView::ObserveInteger(int32 what, int32 value)
- {
- if (what == INT_ACCOUNT_STATUS || what == INT_CONTACT_STATUS)
- _SetToAccount();
- }
- void
- StatusView::ObservePointer(int32 what, void* ptr)
- {
- if (what == PTR_AVATAR_BITMAP)
- _SetToAccount();
- }
- void
- StatusView::_SetToAccount()
- {
- int64 instance = fAccount;
- if (instance == -1)
- instance = fServer->GetActiveAccounts().ValueAt(0);
- ProtocolLooper* looper = fServer->GetProtocolLooper(instance);
- if (looper == NULL || looper->GetOwnContact() == NULL)
- return;
- Contact* contact = looper->GetOwnContact();
- _SetAvatarIcon(contact->AvatarBitmap());
- _SetName(contact->GetName());
- _SetStatus(contact->GetNotifyStatus());
- }
- void
- StatusView::_SetName(BString name)
- {
- fNickname->SetText(name.String());
- }
- void
- StatusView::_SetStatus(UserStatus status)
- {
- for (int32 i = 0; i < fStatusMenu->CountItems(); i++) {
- StatusMenuItem* item
- = reinterpret_cast<StatusMenuItem*>(fStatusMenu->ItemAt(i));
- if (item && item->Status() == status && !item->IsCustom())
- item->SetMarked(true);
- }
- }
- void
- StatusView::_SetAvatarIcon(const BBitmap* bitmap)
- {
- fAvatar->SetBitmap(bitmap);
- }
|