Copyright 2007, Francois Revol. All Rights Reserved.
This file may be used under the terms of the Be Sample Code License.
*/
#define DEBUG 1
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <Debug.h>
#include <List.h>
#include <Message.h>
#include <OS.h>
#include <Application.h>
#include <Menu.h>
#include <MenuItem.h>
#include <MessageRunner.h>
#include <Region.h>
#include <Screen.h>
#if DEBUG
#include <Alert.h>
#include <Button.h>
#include <TextView.h>
#include <StringIO.h>
#include "DumpMessage.h"
#endif
#include "PenInputLooper.h"
#include "PenInputBackend.h"
#include "PenInputInkWindow.h"
#include "PenInputServerMethod.h"
#include "PenInputStrings.h"
PenInputLooper::PenInputLooper(PenInputServerMethod *method)
: BLooper("PenInputLooper", B_NORMAL_PRIORITY),
fOwner(method),
fInkWindow(NULL),
fBackend(NULL),
fDeskbarMenu(NULL),
fMouseDown(false),
fStroking(false),
fThresholdRunner(NULL),
fCachedMouseDown(NULL),
fShowInk(true),
fMouseDownThreshold(100000)
{
PRINT(("%s\n", __FUNCTION__));
fDeskbarMenu = new BMenu(_T("Options"));
BMenu *subMenu;
subMenu = new BMenu(_T("Backend"));
BMessage *msg;
msg = new BMessage(MSG_SET_BACKEND);
BMenuItem *item;
item = new BMenuItem(_T("Default"), msg);
item->SetMarked(true);
subMenu->AddItem(item);
item = new BMenuItem(subMenu);
fDeskbarMenu->AddItem(item);
msg = new BMessage(MSG_SHOW_INK);
item = new BMenuItem(_T("Show Ink"), msg);
item->SetMarked(true);
fDeskbarMenu->AddItem(item);
fDeskbarMenu->SetFont(be_plain_font);
fOwner->SetMenu(fDeskbarMenu, BMessenger(NULL, this));
#if 0
BRegion region;
fOwner->GetScreenRegion(®ion);
fInkWindow = new PenInputInkWindow(region.Frame());
#endif
BScreen screen;
fInkWindow = new PenInputInkWindow(screen.Frame());
fInkWindow->Show();
fInkWindow->Lock();
fInkWindow->Hide();
fInkWindow->Unlock();
fInkWindowMsgr = BMessenger(NULL, fInkWindow);
BMessage m(MSG_CHECK_PEN_DOWN);
fThresholdRunner = new BMessageRunner(BMessenger(NULL, this), &m, fMouseDownThreshold, 0);
Run();
}
void PenInputLooper::Quit()
{
PRINT(("%s\n", __FUNCTION__));
delete fThresholdRunner;
fInkWindow->Lock();
fInkWindow->Quit();
fOwner->SetMenu(NULL, BMessenger());
delete fDeskbarMenu;
BLooper::Quit();
}
void PenInputLooper::DispatchMessage(BMessage *message, BHandler *handler)
{
switch (message->what) {
#if 0
case B_MOUSE_MOVED:
case B_MOUSE_DOWN:
case B_MOUSE_UP:
case B_INPUT_METHOD_EVENT:
if (fBackend) {
fBackend->MessageReceived(message);
return;
}
#endif
default:
return BLooper::DispatchMessage(message, handler);
}
}
void PenInputLooper::MessageReceived(BMessage *message)
{
int32 v;
int32 buttons;
bool b;
#if 1
{
BStringIO sio;
DumpMessageToStream(message, sio);
fInkWindow->Lock();
sio << BString("StrokesCount: ");
BString tmp;
tmp << fInkWindow->fStrokeCount;
sio << tmp;
sio << BString("\nStrokes.Bounds: ");
sio << (fInkWindow->fStrokes.Bounds());
sio << BString("\n");
fInkWindow->Unlock();
fOwner->fDebugAlert->Lock();
fOwner->fDebugAlert->TextView()->Insert("Looper:\n");
fOwner->fDebugAlert->TextView()->Insert(sio.String());
fOwner->fDebugAlert->Unlock();
}
#endif
switch (message->what) {
case MSG_CHECK_PEN_DOWN:
if (fCachedMouseDown) {
EnqueueMessage(fCachedMouseDown);
fCachedMouseDown = NULL;
}
break;
case B_MOUSE_MOVED:
if (!fMouseDown) {
EnqueueMessage(DetachCurrentMessage());
break;
}
if (fShowInk) {
BMessage *msg = new BMessage(*message);
fInkWindowMsgr.SendMessage(msg);
}
if (fBackend)
fBackend->MessageReceived(message);
else
EnqueueMessage(DetachCurrentMessage());
break;
case B_MOUSE_DOWN:
if (message->FindInt32("buttons", &buttons) == B_OK) {
if (!(buttons & B_PRIMARY_MOUSE_BUTTON)) {
EnqueueMessage(DetachCurrentMessage());
break;
}
}
fMouseDown = true;
if (fShowInk) {
{
BMessage *msg = new BMessage(MSG_BEGIN_INK);
fInkWindowMsgr.SendMessage(msg);
}
BMessage *msg = new BMessage(*message);
fInkWindowMsgr.SendMessage(msg);
}
if (fBackend)
fBackend->MessageReceived(message);
break;
case B_MOUSE_UP:
if (message->FindInt32("buttons", &buttons) == B_OK) {
if (!fMouseDown || (buttons & B_PRIMARY_MOUSE_BUTTON)) {
EnqueueMessage(DetachCurrentMessage());
break;
}
}
fMouseDown = false;
if (fShowInk) {
BMessage *msg = new BMessage(*message);
fInkWindowMsgr.SendMessage(msg);
{
BMessage *msg = new BMessage(MSG_END_INK);
fInkWindowMsgr.SendMessage(msg);
}
}
if (fBackend)
fBackend->MessageReceived(message);
break;
case B_INPUT_METHOD_EVENT:
if (fBackend)
fBackend->MessageReceived(message);
break;
case MSG_METHOD_ACTIVATED:
if (message->FindBool(MSGF_ACTIVE, &b) < B_OK)
b = false;
HandleMethodActivated(b);
break;
case B_REPLY:
default:
BLooper::MessageReceived(message);
break;
}
}
void PenInputLooper::EnqueueMessage(BMessage *message)
{
fOwner->EnqueueMessage(message);
}
status_t PenInputLooper::InitCheck()
{
return B_OK;
}
void PenInputLooper::HandleMethodActivated(bool active)
{
if (fShowInk && active)
fInkWindowMsgr.SendMessage(MSG_SHOW_WIN);
if (fShowInk && !active)
fInkWindowMsgr.SendMessage(MSG_END_INK);
*/
}