From 249a4a187ee9e9e24aa41146e071ad1c01e27283 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stephan=20A=C3=9Fmus?= Date: Mon, 13 Oct 2008 23:31:19 +0000 Subject: [PATCH] zooey + stippi: Reimplemented the drag message over the team entries dragging. The previous implementation used the menu bar tracking by faking a B_MOUSE_DOWN event. The problem was that in Haiku menus are always sticky and therefor the tracking thread was not exited when the user released the mouse (which was supposed to trigger the drop event in the Deskbar). The new implementation follows the drag in the asynchronous mouse hooks and uses it's own selection state in TTeamMenuItem to highlight the eventual drop targets. Fixes #2771. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@28063 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- src/apps/deskbar/ExpandoMenuBar.cpp | 75 +++++++++++++++++++++++------ src/apps/deskbar/ExpandoMenuBar.h | 4 +- src/apps/deskbar/TeamMenuItem.cpp | 24 +++++++-- src/apps/deskbar/TeamMenuItem.h | 4 ++ 4 files changed, 88 insertions(+), 19 deletions(-) diff --git a/src/apps/deskbar/ExpandoMenuBar.cpp b/src/apps/deskbar/ExpandoMenuBar.cpp index 5272fe705a..8aafe4eb25 100644 --- a/src/apps/deskbar/ExpandoMenuBar.cpp +++ b/src/apps/deskbar/ExpandoMenuBar.cpp @@ -78,7 +78,8 @@ TExpandoMenuBar::TExpandoMenuBar(TBarView *bar, BRect frame, const char *name, fShowTeamExpander(static_cast(be_app)->Settings()->superExpando), fExpandNewTeams(static_cast(be_app)->Settings()->expandNewTeams), fBarView(bar), - fFirstApp(0) + fFirstApp(0), + fPreviousDragTargetItem(NULL) { #ifdef DOUBLECLICKBRINGSTOFRONT fLastClickItem = -1; @@ -392,8 +393,8 @@ void TExpandoMenuBar::MouseMoved(BPoint where, uint32 code, const BMessage *message) { if (!message) { - // force a cleanup - fBarView->DragStop(true); + // force a cleanup + _FinishedDrag(); BMenuBar::MouseMoved(where, code, message); return; } @@ -403,26 +404,58 @@ TExpandoMenuBar::MouseMoved(BPoint where, uint32 code, const BMessage *message) || Window()->CurrentMessage()->FindInt32("buttons", (int32*)&buttons) < B_OK) buttons = 0; + if (buttons == 0) + return; + switch (code) { case B_ENTERED_VIEW: - if (message && buttons != 0) { - fBarView->CacheDragData(message); - MouseDown(where); - } + // fPreviousDragTargetItem should always be NULL here anyways. + if (fPreviousDragTargetItem) + _FinishedDrag(); + + fBarView->CacheDragData(message); + fPreviousDragTargetItem = NULL; break; + case B_OUTSIDE_VIEW: + // NOTE: Should not be here, but for the sake of defensive + // programming... case B_EXITED_VIEW: - if (fBarView->Dragging() && buttons != 0) { - if (!TeamItemAtPoint(where) - && !InBeMenu(where) - && (fSeparatorItem && !fSeparatorItem->Frame().Contains(where)) - && !Frame().Contains(where)) { - fBarView->DragStop(); + _FinishedDrag(); + break; + + case B_INSIDE_VIEW: + if (fBarView->Dragging()) { + TTeamMenuItem* item = NULL; + for (int32 i = 0; i < CountItems(); i++) { + BMenuItem* _item = ItemAt(i); + if (_item->Frame().Contains(where)) { + item = dynamic_cast(_item); + break; + } } + if (item == fPreviousDragTargetItem) + break; + if (fPreviousDragTargetItem != NULL) + fPreviousDragTargetItem->SetOverrideSelected(false); + if (item != NULL) + item->SetOverrideSelected(true); + fPreviousDragTargetItem = item; } break; } - BMenuBar::MouseMoved(where, code, message); +} + + +void +TExpandoMenuBar::MouseUp(BPoint where) +{ + if (!fBarView->Dragging()) { + BMenuBar::MouseUp(where); + return; + } + + _FinishedDrag(true); } @@ -816,3 +849,17 @@ TExpandoMenuBar::monitor_team_windows(void *arg) return B_OK; } + +void +TExpandoMenuBar::_FinishedDrag(bool invoke) +{ + if (fPreviousDragTargetItem != NULL) { + if (invoke) + fPreviousDragTargetItem->Invoke(); + fPreviousDragTargetItem->SetOverrideSelected(false); + fPreviousDragTargetItem = NULL; + } + if (!invoke && fBarView->Dragging()) + fBarView->DragStop(true); +} + diff --git a/src/apps/deskbar/ExpandoMenuBar.h b/src/apps/deskbar/ExpandoMenuBar.h index dbd154b501..beb8b33585 100644 --- a/src/apps/deskbar/ExpandoMenuBar.h +++ b/src/apps/deskbar/ExpandoMenuBar.h @@ -66,6 +66,7 @@ class TExpandoMenuBar : public BMenuBar { virtual void MessageReceived(BMessage *message); virtual void MouseDown(BPoint where); virtual void MouseMoved(BPoint where, uint32 code, const BMessage *); + virtual void MouseUp(BPoint where); virtual void Draw(BRect update); virtual void DrawBackground(BRect update); @@ -88,7 +89,7 @@ class TExpandoMenuBar : public BMenuBar { void AddTeam(team_id team, const char *signature); void RemoveTeam(team_id team, bool partial); - void Hilite(drag_and_drop_selection which); + void _FinishedDrag(bool invoke = false); bool fVertical; bool fOverflow; @@ -102,6 +103,7 @@ class TExpandoMenuBar : public BMenuBar { TBarMenuTitle *fBeMenuItem; TTeamMenuItem *fSeparatorItem; + TTeamMenuItem *fPreviousDragTargetItem; #ifdef DOUBLECLICKBRINGSTOFRONT int32 fLastClickItem; diff --git a/src/apps/deskbar/TeamMenuItem.cpp b/src/apps/deskbar/TeamMenuItem.cpp index 40665c7c73..0ab7e80288 100644 --- a/src/apps/deskbar/TeamMenuItem.cpp +++ b/src/apps/deskbar/TeamMenuItem.cpp @@ -101,6 +101,7 @@ TTeamMenuItem::InitData(BList *team, BBitmap *icon, char *name, char *sig, fOverrideWidth = width; fOverrideHeight = height; + fOverriddenSelected = false; fDrawLabel = drawLabel; fVertical = vertical; @@ -156,6 +157,14 @@ TTeamMenuItem::SetOverrideHeight(float height) } +void +TTeamMenuItem::SetOverrideSelected(bool selected) +{ + fOverriddenSelected = selected; + Highlight(selected); +} + + float TTeamMenuItem::LabelWidth() const { @@ -225,14 +234,14 @@ TTeamMenuItem::Draw() // if not selected or being tracked on, fill with gray TBarView *barview = (static_cast(be_app))->BarView(); bool canHandle = !barview->Dragging() || barview->AppCanHandleTypes(Signature()); - if (!IsSelected() && !menu->IsRedrawAfterSticky() || !canHandle || !IsEnabled()) { + if (!_IsSelected() && !menu->IsRedrawAfterSticky() || !canHandle || !IsEnabled()) { frame.InsetBy(1, 1); menu->SetHighColor(menuColor); menu->FillRect(frame); } // draw the gray, unselected item, border - if (!IsSelected() || !IsEnabled()) { + if (!_IsSelected() || !IsEnabled()) { rgb_color shadow = tint_color(menuColor, B_DARKEN_1_TINT); rgb_color light = tint_color(menuColor, B_LIGHTEN_2_TINT); @@ -257,7 +266,7 @@ TTeamMenuItem::Draw() } // if selected or being tracked on, fill with the hilite gray color - if (IsEnabled() && IsSelected() && !menu->IsRedrawAfterSticky() && canHandle) { + if (IsEnabled() && _IsSelected() && !menu->IsRedrawAfterSticky() && canHandle) { // fill menu->SetHighColor(tint_color(menuColor, B_HIGHLIGHT_BACKGROUND_TINT)); menu->FillRect(frame); @@ -415,7 +424,7 @@ TTeamMenuItem::DrawContentLabel() TBarView *barview = (static_cast(be_app))->BarView(); bool canHandle = !barview->Dragging() || barview->AppCanHandleTypes(Signature()); - if (IsSelected() && IsEnabled() && canHandle) + if (_IsSelected() && IsEnabled() && canHandle) menu->SetLowColor(tint_color(menu->ViewColor(), B_HIGHLIGHT_BACKGROUND_TINT)); else @@ -521,3 +530,10 @@ TTeamMenuItem::ExpanderBounds() const return bounds; } + +bool +TTeamMenuItem::_IsSelected() const +{ + return IsSelected() || fOverriddenSelected; +} + diff --git a/src/apps/deskbar/TeamMenuItem.h b/src/apps/deskbar/TeamMenuItem.h index 685b93788b..2cc74c36d0 100644 --- a/src/apps/deskbar/TeamMenuItem.h +++ b/src/apps/deskbar/TeamMenuItem.h @@ -59,6 +59,7 @@ class TTeamMenuItem : public BMenuItem { void SetOverrideWidth(float width); void SetOverrideHeight(float height); + void SetOverrideSelected(bool selected); bool IsExpanded(); void ToggleExpandState(bool resizeWindow); @@ -82,6 +83,8 @@ class TTeamMenuItem : public BMenuItem { float width = -1.0f, float height = -1.0f, bool drawLabel = true,bool vertical=true); + bool _IsSelected() const; + BList *fTeam; BBitmap *fIcon; char *fName; @@ -96,6 +99,7 @@ class TTeamMenuItem : public BMenuItem { bool fVertical; bool fExpanded; + bool fOverriddenSelected; }; #endif /* TEAMMENUITEM_H */