2 * Copyright 2009, Alexandre Deckner, alex@zappotek.com
3 * Distributed under the terms of the MIT License.
7 \class ShakeTrackingFilter
8 \brief A simple mouse shake detection filter
10 * A simple mouse filter that detects quick mouse shakes.
12 * It's detecting rough edges (u-turns) in the mouse movement
13 * and counts them within a time window.
14 * You can configure the message sent, the u-turn count threshold
15 * and the time threshold.
16 * It sends the count along with the message.
17 * For now, detection is limited within the view bounds, but
18 * it might be modified to accept a BRegion mask.
23 #include <ShakeTrackingFilter.h>
26 #include <Messenger.h>
27 #include <MessageRunner.h>
31 const uint32 kMsgCancel
= 'Canc';
34 ShakeTrackingFilter::ShakeTrackingFilter(BView
* targetView
, uint32 messageWhat
,
35 uint32 countThreshold
, bigtime_t timeThreshold
)
37 BMessageFilter(B_ANY_DELIVERY
, B_ANY_SOURCE
),
38 fTargetView(targetView
),
39 fMessageWhat(messageWhat
),
44 fCountThreshold(countThreshold
),
45 fTimeThreshold(timeThreshold
)
50 ShakeTrackingFilter::~ShakeTrackingFilter()
57 ShakeTrackingFilter::Filter(BMessage
* message
, BHandler
** /*_target*/)
59 if (fTargetView
== NULL
)
60 return B_DISPATCH_MESSAGE
;
62 switch (message
->what
) {
66 message
->FindPoint("be:view_where", &position
);
68 // TODO: allow using BRegion masks
69 if (!fTargetView
->Bounds().Contains(position
))
70 return B_DISPATCH_MESSAGE
;
72 fLowPass
.Input(position
- fLastPosition
);
74 BPoint delta
= fLowPass
.Output();
76 // normalized dot product
77 float norm
= delta
.x
* delta
.x
+ delta
.y
* delta
.y
;
83 norm
= fLastDelta
.x
* fLastDelta
.x
+ fLastDelta
.y
* fLastDelta
.y
;
89 float dot
= delta
.x
* fLastDelta
.x
+ delta
.y
* fLastDelta
.y
;
93 BMessage
* cancelMessage
= new BMessage(kMsgCancel
);
94 fCancelRunner
= new BMessageRunner(BMessenger(fTargetView
),
95 cancelMessage
, fTimeThreshold
, 1);
100 if (fCounter
>= fCountThreshold
) {
101 BMessage
shakeMessage(fMessageWhat
);
102 shakeMessage
.AddUInt32("count", fCounter
);
103 BMessenger
messenger(fTargetView
);
104 messenger
.SendMessage(&shakeMessage
);
108 fLastDelta
= fLowPass
.Output();
109 fLastPosition
= position
;
111 return B_DISPATCH_MESSAGE
;
115 delete fCancelRunner
;
116 fCancelRunner
= NULL
;
118 return B_SKIP_MESSAGE
;
124 return B_DISPATCH_MESSAGE
;
131 LowPassFilter::LowPassFilter(uint32 size
)
135 fPoints
= new BPoint
[fSize
];
139 LowPassFilter::~LowPassFilter()
146 LowPassFilter::Input(const BPoint
& p
)
148 // A fifo buffer that maintains a sum of its elements
150 for (uint32 i
= 0; i
< fSize
- 1; i
++)
151 fPoints
[i
] = fPoints
[i
+ 1];
152 fPoints
[fSize
- 1] = p
;
158 LowPassFilter::Output() const
160 return BPoint(fSum
.x
/ (float) fSize
, fSum
.y
/ (float) fSize
);