diff --git a/src/apps/deskbar/ExpandoMenuBar.cpp b/src/apps/deskbar/ExpandoMenuBar.cpp index d5cd5a3aa7..400eb736f2 100644 --- a/src/apps/deskbar/ExpandoMenuBar.cpp +++ b/src/apps/deskbar/ExpandoMenuBar.cpp @@ -71,9 +71,6 @@ All rights reserved. #include "WindowMenuItem.h" -const uint32 kMinimizeTeam = 'mntm'; -const uint32 kBringTeamToFront = 'bftm'; - bool TExpandoMenuBar::sDoMonitor = false; thread_id TExpandoMenuBar::sMonThread = B_ERROR; BLocker TExpandoMenuBar::sMonLocker("expando monitor"); @@ -222,8 +219,7 @@ TExpandoMenuBar::MessageReceived(BMessage* message) break; TShowHideMenuItem::TeamShowHideCommon(B_MINIMIZE_WINDOW, - item->Teams(), - item->Menu()->ConvertToScreen(item->Frame()), + item->Teams(), item->Menu()->ConvertToScreen(item->Frame()), true); break; } @@ -251,80 +247,57 @@ TExpandoMenuBar::MessageReceived(BMessage* message) void TExpandoMenuBar::MouseDown(BPoint where) { - BMessage* message = Window()->CurrentMessage(); - BMenuItem* menuItem; - TTeamMenuItem* item = TeamItemAtPoint(where, &menuItem); - fLastClickedItem = item; + if (fBarView == NULL || fBarView->Dragging()) + return BMenuBar::MouseDown(where); - if (message == NULL || item == NULL || fBarView == NULL - || fBarView->Dragging()) { - BMenuBar::MouseDown(where); - return; - } + BMessage* message = Window()->CurrentMessage(); + BMenuItem* item = ItemAtPoint(where); + fLastClickedItem = item; + if (message == NULL || item == NULL) + return BMenuBar::MouseDown(where); int32 modifiers = 0; int32 buttons = 0; message->FindInt32("modifiers", &modifiers); message->FindInt32("buttons", &buttons); - // check for three finger salute, a.k.a. Vulcan Death Grip - if ((modifiers & B_COMMAND_KEY) != 0 - && (modifiers & B_CONTROL_KEY) != 0 - && (modifiers & B_SHIFT_KEY) != 0) { - const BList* teams = item->Teams(); - int32 teamCount = teams->CountItems(); - team_id teamID; - for (int32 team = 0; team < teamCount; team++) { - teamID = (addr_t)teams->ItemAt(team); - kill_team(teamID); - RemoveTeam(teamID, false); - // remove the team from display immediately - } - return; - // absorb the message - } else if (item != NULL - && (modifiers & B_SHIFT_KEY) == 0 + // close window item + if ((modifiers & B_SHIFT_KEY) != 0 && (buttons & B_TERTIARY_MOUSE_BUTTON) != 0) { - be_roster->Launch(item->Signature()); - return; - // absorb the message - } else { - TWindowMenuItem* wndItem = dynamic_cast(menuItem); - if (wndItem != NULL - && (modifiers & B_SHIFT_KEY) != 0 - && (buttons & B_TERTIARY_MOUSE_BUTTON) != 0) { - // close window - client_window_info* info; - BMessenger wnd; - info = get_window_info(wndItem->ID()); - if (info == NULL) return; - BMessenger::Private(wnd).SetTo( - info->team, info->client_port, info->client_token); - free(info); info = NULL; - wnd.SendMessage(B_QUIT_REQUESTED); - return; - // absorb the message + TWindowMenuItem* wItem = dynamic_cast(item); + if (wItem != NULL) { + // we have a window item + BMessenger messenger; + client_window_info* info = get_window_info(wItem->ID()); + if (info != NULL) { + BMessenger::Private(messenger).SetTo(info->team, + info->client_port, info->client_token); + messenger.SendMessage(B_QUIT_REQUESTED); + free(info); + return; + // absorb the message + } } } - // control click - show all/hide all shortcut - if ((modifiers & B_CONTROL_KEY) != 0) { - // show/hide item's teams - BMessage showMessage((modifiers & B_SHIFT_KEY) != 0 - ? kMinimizeTeam : kBringTeamToFront); - showMessage.AddInt32("itemIndex", IndexOf(item)); - Window()->PostMessage(&showMessage, this); + // below depends on item being a team item + + TTeamMenuItem* teamItem = dynamic_cast(item); + if (teamItem == NULL) + return BMenuBar::MouseDown(where); + + // check for three finger salute, a.k.a. Vulcan Death Grip + if (teamItem->HandleMouseDown(where)) return; // absorb the message - } // check if within expander bounds to expand window items if (Vertical() && static_cast(be_app)->Settings()->superExpando - && item->ExpanderBounds().Contains(where)) { + && teamItem->ExpanderBounds().Contains(where)) { // start the animation here, finish on mouse up - item->SetArrowDirection(BControlLook::B_RIGHT_DOWN_ARROW); + teamItem->SetArrowDirection(BControlLook::B_RIGHT_DOWN_ARROW); SetMouseEventMask(B_POINTER_EVENTS, B_NO_POINTER_HISTORY); - Invalidate(item->ExpanderBounds()); + Invalidate(teamItem->ExpanderBounds()); return; // absorb the message } @@ -335,9 +308,8 @@ TExpandoMenuBar::MouseDown(BPoint where) get_click_speed(&clickSpeed); bigtime_t delta = system_time() - fLastClickTime; if (message->FindInt32("clicks", &clicks) == B_OK && clicks > 1 - && item == menuItem && item == fLastClickedItem - && delta <= clickSpeed) { - be_roster->ActivateApp((addr_t)item->Teams()->ItemAt(0)); + && item == fLastClickedItem && delta <= clickSpeed) { + be_roster->ActivateApp((addr_t)teamItem->Teams()->ItemAt(0)); // activate this team return; // absorb the message @@ -489,15 +461,18 @@ TExpandoMenuBar::MouseMoved(BPoint where, uint32 code, const BMessage* message) void TExpandoMenuBar::MouseUp(BPoint where) { - TTeamMenuItem* lastItem = dynamic_cast(fLastClickedItem); - fLastClickedItem = NULL; - if (fBarView != NULL && fBarView->Dragging()) { _FinishedDrag(true); return; // absorb the message } + if (fLastClickedItem == NULL) + return BMenuBar::MouseUp(where); + + TTeamMenuItem* lastItem = dynamic_cast(fLastClickedItem); + fLastClickedItem = NULL; + if (Vertical() && static_cast(be_app)->Settings()->superExpando && lastItem != NULL && lastItem->ExpanderBounds().Contains(where)) { lastItem->ToggleExpandState(true); @@ -507,6 +482,7 @@ TExpandoMenuBar::MouseUp(BPoint where) Invalidate(lastItem->ExpanderBounds()); } + BMenuBar::MouseUp(where); } @@ -626,6 +602,21 @@ TExpandoMenuBar::InDeskbarMenu(BPoint loc) const } +BMenuItem* +TExpandoMenuBar::ItemAtPoint(BPoint point) +{ + int32 itemCount = CountItems(); + for (int32 index = 0; index < itemCount; index++) { + BMenuItem* item = ItemAt(index); + if (item != NULL && item->Frame().Contains(point)) + return item; + } + + // no item found + return NULL; +} + + /*! Returns the team menu item that belongs to the item under the specified \a point. If \a _item is given, it will return the exact menu item under @@ -637,13 +628,12 @@ TExpandoMenuBar::TeamItemAtPoint(BPoint point, BMenuItem** _item) TTeamMenuItem* lastApp = NULL; int32 itemCount = CountItems(); - for (int32 i = 0; i < itemCount; i++) { - BMenuItem* item = ItemAt(i); + for (int32 index = 0; index < itemCount; index++) { + BMenuItem* item = ItemAt(index); + if (item != NULL && item->Frame().Contains(point)) { + if (dynamic_cast(item) != NULL) + lastApp = (TTeamMenuItem*)item; - if (dynamic_cast(item) != NULL) - lastApp = (TTeamMenuItem*)item; - - if (item && item->Frame().Contains(point)) { if (_item != NULL) *_item = item; diff --git a/src/apps/deskbar/ExpandoMenuBar.h b/src/apps/deskbar/ExpandoMenuBar.h index facabecbe0..1c0a169e45 100644 --- a/src/apps/deskbar/ExpandoMenuBar.h +++ b/src/apps/deskbar/ExpandoMenuBar.h @@ -83,6 +83,7 @@ public: void BuildItems(); + BMenuItem* ItemAtPoint(BPoint point); TTeamMenuItem* TeamItemAtPoint(BPoint location, BMenuItem** _item = NULL); bool InDeskbarMenu(BPoint) const; diff --git a/src/apps/deskbar/TeamMenu.cpp b/src/apps/deskbar/TeamMenu.cpp index 5d1f1edef5..93fb9f8276 100644 --- a/src/apps/deskbar/TeamMenu.cpp +++ b/src/apps/deskbar/TeamMenu.cpp @@ -191,3 +191,64 @@ TTeamMenu::DetachedFromWindow() BMessenger self(this); TBarApp::Unsubscribe(self); } + + +void +TTeamMenu::MessageReceived(BMessage* message) +{ + TTeamMenuItem* item = NULL; + + switch (message->what) { + case B_SOME_APP_QUIT: + case kRemoveTeam: + { + int32 itemIndex = -1; + message->FindInt32("itemIndex", &itemIndex); + team_id team = -1; + message->FindInt32("team", &team); + + item = dynamic_cast(ItemAt(itemIndex)); + if (item != NULL && item->Teams()->HasItem((void*)(addr_t)team)) { + item->Teams()->RemoveItem(team); + RemoveItem(itemIndex); + delete item; + } + break; + } + + default: + BMenu::MessageReceived(message); + break; + } +} + + +void +TTeamMenu::MouseDown(BPoint where) +{ + if (fBarView == NULL || fBarView->Dragging()) + return BMenu::MouseDown(where); + + BMenuItem* item = ItemAtPoint(where); + if (item == NULL) + return BMenu::MouseDown(where); + + TTeamMenuItem* teamItem = dynamic_cast(item); + if (teamItem == NULL || !teamItem->HandleMouseDown(where)) + BMenu::MouseDown(where); +} + + +BMenuItem* +TTeamMenu::ItemAtPoint(BPoint point) +{ + int32 itemCount = CountItems(); + for (int32 index = 0; index < itemCount; index++) { + BMenuItem* item = ItemAt(index); + if (item != NULL && item->Frame().Contains(point)) + return item; + } + + // no item found + return NULL; +} diff --git a/src/apps/deskbar/TeamMenu.h b/src/apps/deskbar/TeamMenu.h index 552ab0e9e4..451afdef06 100644 --- a/src/apps/deskbar/TeamMenu.h +++ b/src/apps/deskbar/TeamMenu.h @@ -50,8 +50,12 @@ class TTeamMenu : public BMenu { public: TTeamMenu(TBarView* barView = NULL); - void AttachedToWindow(); - void DetachedFromWindow(); + virtual void AttachedToWindow(); + virtual void DetachedFromWindow(); + virtual void MessageReceived(BMessage* message); + virtual void MouseDown(BPoint where); + + BMenuItem* ItemAtPoint(BPoint point); static int CompareByName(const void* first, const void* second); diff --git a/src/apps/deskbar/TeamMenuItem.cpp b/src/apps/deskbar/TeamMenuItem.cpp index b7eba2fb2b..632a22dfae 100644 --- a/src/apps/deskbar/TeamMenuItem.cpp +++ b/src/apps/deskbar/TeamMenuItem.cpp @@ -50,6 +50,7 @@ All rights reserved. #include #include #include +#include #include "BarApp.h" #include "BarMenuBar.h" @@ -94,6 +95,67 @@ TTeamMenuItem::~TTeamMenuItem() } +/*! Vulcan Death Grip and other team mouse button handling + + \returns true if handled, false otherwise +*/ +bool +TTeamMenuItem::HandleMouseDown(BPoint where) +{ + BMenu* menu = Menu(); + if (menu == NULL) + return false; + + BWindow* window = menu->Window(); + if (window == NULL) + return false; + + BMessage* message = window->CurrentMessage(); + if (message == NULL) + return false; + + int32 modifiers = 0; + int32 buttons = 0; + message->FindInt32("modifiers", &modifiers); + message->FindInt32("buttons", &buttons); + + // check for three finger salute, a.k.a. Vulcan Death Grip + if ((modifiers & B_COMMAND_KEY) != 0 + && (modifiers & B_CONTROL_KEY) != 0 + && (modifiers & B_SHIFT_KEY) != 0) { + BMessage appMessage(B_SOME_APP_QUIT); + int32 teamCount = fTeam->CountItems(); + BMessage quitMessage(teamCount == 1 ? B_SOME_APP_QUIT : kRemoveTeam); + quitMessage.AddInt32("itemIndex", menu->IndexOf(this)); + for (int32 index = 0; index < teamCount; index++) { + team_id team = (addr_t)fTeam->ItemAt(index); + appMessage.AddInt32("be:team", team); + quitMessage.AddInt32("team", team); + + kill_team(team); + } + be_app->PostMessage(&appMessage); + TExpandoMenuBar* expando = dynamic_cast(menu); + window->PostMessage(&quitMessage, expando != NULL ? expando : menu); + return true; + } else if ((modifiers & B_SHIFT_KEY) == 0 + && (buttons & B_TERTIARY_MOUSE_BUTTON) != 0) { + // launch new team + be_roster->Launch(Signature()); + return true; + } else if ((modifiers & B_CONTROL_KEY) != 0) { + // control click - show all/hide all shortcut + BMessage showMessage((modifiers & B_SHIFT_KEY) != 0 + ? kMinimizeTeam : kBringTeamToFront); + showMessage.AddInt32("itemIndex", menu->IndexOf(this)); + window->PostMessage(&showMessage, menu); + return true; + } + + return false; +} + + status_t TTeamMenuItem::Invoke(BMessage* message) { diff --git a/src/apps/deskbar/TeamMenuItem.h b/src/apps/deskbar/TeamMenuItem.h index 011fa7c849..8608510635 100644 --- a/src/apps/deskbar/TeamMenuItem.h +++ b/src/apps/deskbar/TeamMenuItem.h @@ -46,6 +46,9 @@ All rights reserved. const float kSwitchWidth = 12.0f; +const uint32 kMinimizeTeam = 'mntm'; +const uint32 kBringTeamToFront = 'bftm'; + class BBitmap; class TBarView; @@ -60,6 +63,7 @@ public: float height = -1.0f); virtual ~TTeamMenuItem(); + bool HandleMouseDown(BPoint where); status_t Invoke(BMessage* message = NULL); void SetOverrideWidth(float width)