123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379 |
- /*
- * Copyright 2011-2012, Dario Casalinuovo. All rights reserved.
- * Distributed under the terms of the MIT License.
- *
- * Authors:
- * Dario Casalinuovo
- */
- #include "ReplicantStatusView.h"
- #include <stdio.h>
- #include <Application.h>
- #include <AppFileInfo.h>
- #include <Bitmap.h>
- #include <Catalog.h>
- #include <Deskbar.h>
- #include <IconUtils.h>
- #include <Message.h>
- #include <MenuField.h>
- #include <MenuItem.h>
- #include <PopUpMenu.h>
- #include <Roster.h>
- #include <Window.h>
- #include <libinterface/BitmapMenuItem.h>
- #include <libinterface/BitmapUtils.h>
- #include <libinterface/BitmapView.h>
- #include "AppMessages.h"
- #include "AppPreferences.h"
- #include "ChatOMatic.h"
- #include "ChatProtocolMessages.h"
- #include "ReplicantMenuItem.h"
- #include "Utils.h"
- #undef B_TRANSLATION_CONTEXT
- #define B_TRANSLATION_CONTEXT "ReplicantStatusView"
- extern "C" _EXPORT BView *instantiate_deskbar_item(void);
- // The following handler is added to the Deskbar's looper
- // to receive notifications from Caya
- class ReplicantHandler : public BHandler {
- public:
- ReplicantHandler(const char* name, ReplicantStatusView* target)
- :
- BHandler(name)
- {
- fTarget = target;
- }
- ~ReplicantHandler() {}
- virtual void MessageReceived(BMessage* message)
- {
- switch (message->what) {
- case IM_OWN_STATUS_SET:
- {
- int32 status;
- if (message->FindInt32("status", &status) != B_OK)
- return;
- fTarget->SetStatus((UserStatus)status);
- break;
- }
- default:
- BHandler::MessageReceived(message);
- }
- }
- private:
- ReplicantStatusView* fTarget;
- };
- ReplicantStatusView::ReplicantStatusView()
- :
- BView(BRect(0, 0, 15, 15), "ReplicantStatusView",
- B_FOLLOW_LEFT | B_FOLLOW_TOP, B_WILL_DRAW)
- {
- _Init();
- }
- ReplicantStatusView::ReplicantStatusView(BMessage* archive)
- :
- BView(archive)
- {
- _Init();
- }
- ReplicantStatusView::~ReplicantStatusView()
- {
- delete fCayaMsg;
- delete fReplicantHandler;
- delete fReplicantMenu;
- // TODO: Use a list for that
- // maybe our List wrapper to std::list
- delete fConnectingIcon;
- delete fIcon;
- delete fOfflineIcon;
- delete fBusyIcon;
- delete fAwayIcon;
- }
- void
- ReplicantStatusView::MessageReceived(BMessage* msg)
- {
- switch (msg->what) {
- case APP_REPLICANT_STATUS_SET:
- {
- int32 status;
- if (msg->FindInt32("status", &status) != B_OK)
- return;
- SetStatus((UserStatus)status);
- fCayaMsg->SendMessage(msg);
- break;
- }
- case APP_REPLICANT_EXIT:
- case APP_SHOW_SETTINGS:
- case APP_REPLICANT_SHOW_WINDOW:
- case APP_REPLICANT_MESSENGER:
- fCayaMsg->SendMessage(msg);
- break;
- default:
- BView::MessageReceived(msg);
- }
- }
- void
- ReplicantStatusView::SetStatus(UserStatus status)
- {
- for (int32 i = 0; i < fReplicantMenu->CountItems(); i++) {
- ReplicantMenuItem* item
- = dynamic_cast<ReplicantMenuItem*>(fReplicantMenu->ItemAt(i));
- if (item == NULL)
- continue;
- if (item->IsMarked())
- item->SetMarked(false);
- if (item && item->Status() == status && !item->IsCustom())
- item->SetMarked(true);
- }
- switch (status) {
- case STATUS_AWAY:
- fIcon = fAwayIcon;
- break;
- case STATUS_DO_NOT_DISTURB:
- fIcon = fBusyIcon;
- break;
- case STATUS_CUSTOM_STATUS:
- fIcon = fAppIcon;
- break;
- case STATUS_INVISIBLE:
- case STATUS_OFFLINE:
- fIcon = fOfflineIcon;
- break;
- default:
- fIcon = fIcon;
- break;
- }
- Invalidate();
- }
- // Draw our deskbar icon.
- void
- ReplicantStatusView::Draw(BRect rect)
- {
- SetDrawingMode(B_OP_ALPHA);
- DrawBitmap(fIcon);
- }
- ReplicantStatusView*
- ReplicantStatusView::Instantiate(BMessage* archive)
- {
- if (!validate_instantiation(archive, "ReplicantStatusView"))
- return NULL;
- return new ReplicantStatusView(archive);
- }
- status_t
- ReplicantStatusView::Archive(BMessage* archive, bool deep) const
- {
- status_t status = BView::Archive(archive, deep);
- if (status == B_OK)
- status = archive->AddString("add_on", APP_SIGNATURE);
- if (status == B_OK)
- status = archive->AddString("class", "ReplicantStatusView");
- return status;
- }
- void
- ReplicantStatusView::AttachedToWindow()
- {
- BView::AttachedToWindow();
- if (Parent())
- SetViewColor(Parent()->ViewColor());
- else
- SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR));
- SetLowColor(ViewColor());
- fReplicantHandler = new ReplicantHandler("CayaReplicantHandler", this);
- if (Window()->Lock()) {
- Window()->AddHandler(fReplicantHandler);
- Window()->Unlock();
- }
- BMessage msg(APP_REPLICANT_MESSENGER);
- BMessenger messenger(fReplicantHandler);
- if (!messenger.IsValid())
- return;
- msg.AddMessenger("messenger", messenger);
- fCayaMsg->SendMessage(&msg);
- }
- void
- ReplicantStatusView::DetachedFromWindow()
- {
- if (Window()->Lock()) {
- Window()->RemoveHandler(fReplicantHandler);
- Window()->Unlock();
- }
- }
- void
- ReplicantStatusView::MouseDown(BPoint point)
- {
- uint32 buttons;
- if (LockLooper()) {
- GetMouse(&point, &buttons, false);
- UnlockLooper();
- }
- if (buttons & B_PRIMARY_MOUSE_BUTTON) {
- // Show / Hide Window command
- BMessage msg(APP_REPLICANT_SHOW_WINDOW);
- fCayaMsg->SendMessage(&msg);
- } else if(buttons & B_SECONDARY_MOUSE_BUTTON) {
- // Build replicant menu
- _ShowMenu(point);
- }
- }
- void
- ReplicantStatusView::_Init()
- {
- SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR));
- // Creating the Send messenger and sending
- // a messenger targeting this to Caya.
- // This will allow the Replicant to communicate
- // whith Caya.
- fCayaMsg = new BMessenger(APP_SIGNATURE);
- fResources = ChatResources();
- //Get icons from resources
- fConnectingIcon = _GetIcon(kOnlineReplicant);
- fAppIcon = _GetIcon(kIconReplicant);
- fOfflineIcon = _GetIcon(kOfflineReplicant);
- fIcon = fOfflineIcon;
- fBusyIcon = _GetIcon(kBusyReplicant);
- fAwayIcon = _GetIcon(kAwayReplicant);
- fExitMenuIcon = _GetIcon(kExitMenuReplicant);
- fPreferencesIcon = _GetIcon(kToolIcon);
- // Build the replicant menu
- _BuildMenu();
- }
- BBitmap*
- ReplicantStatusView::_GetIcon(const uint32 id)
- {
- BBitmap* icon = IconFromResources(&fResources, id, B_MINI_ICON);
- return icon;
- }
- void
- ReplicantStatusView::_BuildMenu()
- {
- // Status menu
- fReplicantMenu = new BPopUpMenu(" - ", false, false);
- // Add status menu items
- int32 s = STATUS_ONLINE;
- while (s >= STATUS_ONLINE && s < STATUS_STATUSES) {
- BMessage* msg = new BMessage(APP_REPLICANT_STATUS_SET);
- msg->AddInt32("status", s);
- ReplicantMenuItem* item = new ReplicantMenuItem(
- UserStatusToString((UserStatus)s), (UserStatus)s);
- fReplicantMenu->AddItem(item);
- // Mark offline status by default
- if (s == STATUS_OFFLINE)
- item->SetMarked(true);
- s++;
- }
- fReplicantMenu->AddItem(new BSeparatorItem());
- fReplicantMenu->AddItem(new BitmapMenuItem(B_TRANSLATE("Preferences "),
- new BMessage(APP_SHOW_SETTINGS), fPreferencesIcon));
- fReplicantMenu->AddItem(new BitmapMenuItem(B_TRANSLATE("Exit"),
- new BMessage(APP_REPLICANT_EXIT), fExitMenuIcon));
- fReplicantMenu->SetTargetForItems(this);
- }
- void
- ReplicantStatusView::_ShowMenu(BPoint point)
- {
- fReplicantMenu->SetTargetForItems(this);
- ConvertToScreen(&point);
- fReplicantMenu->Go(point, true, true, true);
- }
- extern "C" _EXPORT BView *
- instantiate_deskbar_item(void)
- {
- return new ReplicantStatusView();
- }
- // The following methods install
- // and remove the Caya's replicant
- // from Deskbar.
- status_t
- ReplicantStatusView::InstallReplicant()
- {
- if (AppPreferences::Get()->DisableReplicant == true)
- return B_OK;
-
- BDeskbar deskbar;
- if (deskbar.HasItem("ReplicantStatusView")) {
- ReplicantStatusView::RemoveReplicant();
- }
- ReplicantStatusView* view = new ReplicantStatusView();
- return deskbar.AddItem(view);
- }
- status_t
- ReplicantStatusView::RemoveReplicant()
- {
- BDeskbar deskbar;
- return deskbar.RemoveItem("ReplicantStatusView");
- }
|