2 * Copyright 2009, Alexandre Deckner, alex@zappotek.com
3 * Distributed under the terms of the MIT License.
7 \class DragTrackingFilter
8 \brief A simple mouse drag detection filter
10 * A simple mouse filter that detects the start of a mouse drag over a
11 * threshold distance and sends a message with the 'what' field of your
12 * choice. Especially useful for drag and drop.
13 * Allows you to free your code of encumbering mouse tracking details.
15 * It can detect fast drags spanning outside of a small view by temporarily
16 * setting the B_POINTER_EVENTS flag on the view.
19 #include <DragTrackingFilter.h>
22 #include <Messenger.h>
25 static const int kSquaredDragThreshold
= 9;
27 DragTrackingFilter::DragTrackingFilter(BView
* targetView
, uint32 messageWhat
)
28 : BMessageFilter(B_ANY_DELIVERY
, B_ANY_SOURCE
),
29 fTargetView(targetView
),
30 fMessageWhat(messageWhat
),
38 DragTrackingFilter::Filter(BMessage
* message
, BHandler
** /*_target*/)
40 if (fTargetView
== NULL
)
41 return B_DISPATCH_MESSAGE
;
43 switch (message
->what
) {
45 message
->FindPoint("where", &fClickPoint
);
46 message
->FindInt32("buttons", (int32
*)&fClickButtons
);
49 fTargetView
->SetMouseEventMask(B_POINTER_EVENTS
);
51 return B_DISPATCH_MESSAGE
;
55 return B_DISPATCH_MESSAGE
;
60 message
->FindPoint("be:view_where", &where
);
62 // TODO: be more flexible about buttons and pass their state
64 if (fIsTracking
&& (fClickButtons
& B_PRIMARY_MOUSE_BUTTON
)) {
66 BPoint
delta(fClickPoint
- where
);
67 float squaredDelta
= (delta
.x
* delta
.x
) + (delta
.y
* delta
.y
);
69 if (squaredDelta
>= kSquaredDragThreshold
) {
70 BMessage
dragClickMessage(fMessageWhat
);
71 dragClickMessage
.AddPoint("be:view_where", fClickPoint
);
72 // name it "be:view_where" since BView::DragMessage
73 // positions the dragging frame/bitmap by retrieving the
74 // current message and reading that field
75 BMessenger
messenger(fTargetView
);
76 messenger
.SendMessage(&dragClickMessage
);
81 return B_DISPATCH_MESSAGE
;
87 return B_DISPATCH_MESSAGE
;