#include <AppDefs.h>
#include <Message.h>
#include <MessageFilter.h>
#include <View.h>
#include "PopupControl.h"
#include "PopupView.h"
#include "PopupWindow.h"
class MouseDownFilter : public BMessageFilter {
public:
MouseDownFilter(BWindow* window);
virtual filter_result Filter(BMessage*, BHandler** target);
private:
BWindow* fWindow;
};
MouseDownFilter::MouseDownFilter(BWindow* window)
: BMessageFilter(B_MOUSE_DOWN),
fWindow(window)
{
}
filter_result
MouseDownFilter::Filter(BMessage* message, BHandler** target)
{
if (fWindow) {
if (BView* view = dynamic_cast<BView*>(*target)) {
BPoint point;
if (message->FindPoint("where", &point) == B_OK) {
if (!fWindow->Frame().Contains(view->ConvertToScreen(point)))
*target = fWindow;
}
}
}
return B_DISPATCH_MESSAGE;
}
PopupWindow::PopupWindow(PopupView* child, PopupControl* control)
: MWindow(BRect(0.0, 0.0, 10.0, 10.0), "popup",
B_NO_BORDER_WINDOW_LOOK, B_FLOATING_ALL_WINDOW_FEEL,
B_ASYNCHRONOUS_CONTROLS),
fCanceled(true),
fControl(control)
{
AddChild(child);
child->SetPopupWindow(this);
AddCommonFilter(new MouseDownFilter(this));
}
PopupWindow::~PopupWindow()
{
}
void
PopupWindow::MessageReceived(BMessage* message)
{
switch (message->what) {
case B_MOUSE_DOWN:
fCanceled = true;
Hide();
break;
default:
MWindow::MessageReceived(message);
break;
}
}
void
PopupWindow::Show()
{
if (BLooper *looper = fControl->Looper())
looper->PostMessage(MSG_POPUP_SHOWN, fControl);
MWindow::Show();
}
void
PopupWindow::Hide()
{
if (BLooper *looper = fControl->Looper()) {
BMessage msg(MSG_POPUP_HIDDEN);
msg.AddBool("canceled", fCanceled);
looper->PostMessage(&msg, fControl);
}
MWindow::Hide();
}
bool
PopupWindow::QuitRequested()
{
return false;
}
void
PopupWindow::PopupDone(bool canceled)
{
fCanceled = canceled;
Hide();
}