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
This commit is contained in:
Stephan Aßmus 2008-10-13 23:31:19 +00:00
parent dfcc059e7b
commit 249a4a187e
4 changed files with 88 additions and 19 deletions

View File

@ -78,7 +78,8 @@ TExpandoMenuBar::TExpandoMenuBar(TBarView *bar, BRect frame, const char *name,
fShowTeamExpander(static_cast<TBarApp *>(be_app)->Settings()->superExpando),
fExpandNewTeams(static_cast<TBarApp *>(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<TTeamMenuItem*>(_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);
}

View File

@ -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;

View File

@ -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<TBarApp *>(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<TBarApp *>(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;
}

View File

@ -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 */