- Well, i told ya it was better with a BMessageRunner ;-P

git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@27283 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Alexandre Deckner 2008-09-02 02:20:12 +00:00
parent 935ebe7840
commit 57b269650e
5 changed files with 24 additions and 197 deletions

View File

@ -34,7 +34,6 @@ Application Deskbar :
CalendarMenuItem.cpp
DeskBarUtils.cpp
ExpandoMenuBar.cpp
LongClickTracker.cpp
ShowHideMenuItem.cpp
StatusView.cpp
StatusViewShelf.cpp

View File

@ -1,139 +0,0 @@
/*
* Copyright 2008, Haiku, Inc. All Rights Reserved.
* Distributed under the terms of the MIT License.
*
* Authors:
* Alexandre Deckner <alex@zappotek.com>
*/
#include "LongClickTracker.h"
#include <View.h>
LongClickTracker::LongClickTracker(BView *view, uint32 messageWhat)
: fView(view),
fMessenger(NULL),
fMessageWhat(messageWhat),
fThread(B_ERROR),
fQuit(false)
{
// use the doubleClickSpeed as a threshold
get_click_speed(&fLongClickThreshold);
}
LongClickTracker::~LongClickTracker()
{
if (fThread != B_NO_ERROR)
return;
fQuit = true;
status_t ret;
wait_for_thread(fThread, &ret);
delete fMessenger;
}
// Must be called _after_ the view has been attached to a window
status_t
LongClickTracker::Start()
{
status_t err;
if (!fView->Window())
return B_ERROR;
fMessenger = new BMessenger(fView, NULL, &err);
if (err != B_OK)
return err;
fThread = spawn_thread(LongClickTracker::_ThreadEntry, "clickTracker",
B_NORMAL_PRIORITY, this);
err = resume_thread(fThread);
if (err != B_NO_ERROR) {
kill_thread(fThread);
fThread = B_ERROR;
} else {
fQuit = false;
}
return err;
}
int32
LongClickTracker::_ThreadEntry(void *pointer)
{
LongClickTracker *that = reinterpret_cast<LongClickTracker*>(pointer);
that->_Track();
return B_OK;
}
void
LongClickTracker::_Track()
{
uint32 buttons;
BPoint position;
bool timing = false;
//when true, we are currently timing the last click duration
bool ready = true;
//when true, button has been released, we can start timing on next click
bigtime_t clickTime = 0;
BRect bounds;
fView->LockLooper();
bounds = fView->Bounds();
fView->UnlockLooper();
while (!fQuit) {
snooze(20000);
if (fView->Window()) {
fView->LockLooper();
fView->GetMouse(&position, &buttons, false);
fView->UnlockLooper();
}
if (timing) {
if (!bounds.Contains(position)) {
//mouse exited the view, stop timing
timing = false;
ready = false; //not ready yet, the button might be still down
}
if (buttons != B_PRIMARY_MOUSE_BUTTON) {
//button has been released, stop timing, set ready
timing = false;
ready = true;
} else if ((system_time() - clickTime) > fLongClickThreshold){
BMessage message(fMessageWhat);
message.AddPoint("where", position);
fMessenger->SendMessage(&message);
timing = false;
ready = false;
}
}
if (!ready && !timing && (buttons != B_PRIMARY_MOUSE_BUTTON)) {
//mouse released, ready to time on next click
ready = true;
}
if (ready && !timing && buttons == B_PRIMARY_MOUSE_BUTTON
&& bounds.Contains(position)) {
//mouse clicked in view, start timing
timing = true;
clickTime = system_time();
}
}
}

View File

@ -1,52 +0,0 @@
/*
* Copyright 2007-2008, Haiku, Inc. All Rights Reserved.
* Distributed under the terms of the MIT License.
*
* Authors:
* Alexandre Deckner <alex@zappotek.com>
*/
/*
* LongClickTracker:
* This class provides a way to track long clicks asynchronously.
* Set the view to track and the code of the message you want to receive.
* When a long click occurs in the view, a message will be sent to the view.
* It contains the coordinates of the click (last postion) in a BPoint:"where"
*
* Could be extended to be more parametrable and/or support other kind of
* complex mouse tracking. This could also be done on the input server side
* eventually, and use this class for R5 backward compatibility.
*
* Call Start() after the view has been attached to a window.
*/
#ifndef _LONG_CLICK_TRACKER_H_
#define _LONG_CLICK_TRACKER_H_
#include <Messenger.h>
#include <OS.h>
class BView;
class BMessenger;
class LongClickTracker
{
public:
LongClickTracker(BView *view, uint32 messageWhat);
~LongClickTracker();
status_t Start();
protected:
static int32 _ThreadEntry(void *that);
void _Track();
BView* fView;
BMessenger* fMessenger;
int32 fMessageWhat;
thread_id fThread;
bool fQuit;
bigtime_t fLongClickThreshold;
};
#endif // _LONG_CLICK_TRACKER_H_

View File

@ -45,6 +45,7 @@ All rights reserved.
#include <Debug.h>
#include <MenuItem.h>
#include <MessageRunner.h>
#include <PopUpMenu.h>
#include <Roster.h>
#include <Window.h>
@ -85,7 +86,7 @@ TTimeView::TTimeView(float maxWidth, float height, bool showSeconds, bool milTim
fMaxWidth(maxWidth),
fHeight(height),
fOrientation(true),
fLongClickTracker(this, kMsgLongClick)
fLongClickMessageRunner(NULL)
{
fShowingDate = false;
fTime = fLastTime = time(NULL);
@ -157,8 +158,6 @@ TTimeView::AttachedToWindow()
ResizeToPreferred();
CalculateTextPlacement();
fLongClickTracker.Start();
}
@ -376,6 +375,17 @@ TTimeView::MouseDown(BPoint point)
if (buttons == B_SECONDARY_MOUSE_BUTTON) {
ShowClockOptions(ConvertToScreen(point));
return;
} else if (buttons == B_PRIMARY_MOUSE_BUTTON) {
BMessage * longClickMessage = new BMessage(kMsgLongClick);
longClickMessage->AddPoint("where", point);
bigtime_t longClickThreshold;
get_click_speed(&longClickThreshold);
// use the doubleClickSpeed as a threshold
delete fLongClickMessageRunner;
fLongClickMessageRunner = new BMessageRunner(BMessenger(this),
longClickMessage, longClickThreshold, 1);
}
// flip to/from showing date or time
@ -391,6 +401,14 @@ TTimeView::MouseDown(BPoint point)
}
void
TTimeView::MouseUp(BPoint point)
{
delete fLongClickMessageRunner;
fLongClickMessageRunner = NULL;
}
void
TTimeView::Pulse()
{

View File

@ -36,13 +36,13 @@ All rights reserved.
#include <OS.h>
#include <View.h>
#include "LongClickTracker.h"
const uint32 kMsgShowSeconds = 'ShSc';
const uint32 kMsgMilTime = 'MilT';
const uint32 kMsgFullDate = 'FDat';
const uint32 kMsgEuroDate = 'EDat';
class BMessageRunner;
#ifdef AS_REPLICANT
class _EXPORT TTimeView;
@ -67,6 +67,7 @@ class TTimeView : public BView {
void FrameMoved(BPoint);
void MessageReceived(BMessage*);
void MouseDown(BPoint where);
void MouseUp(BPoint where);
void Pulse();
bool ShowingSeconds() { return fShowSeconds; }
@ -125,7 +126,7 @@ class TTimeView : public BView {
BPoint fTimeLocation;
BPoint fDateLocation;
LongClickTracker fLongClickTracker;
BMessageRunner* fLongClickMessageRunner;
};