1 /*
2 * Copyright 2006, Haiku.
3 * Distributed under the terms of the MIT License.
4 *
5 * Authors:
6 * Stephan Aßmus <superstippi@gmx.de>
7 * Ingo Weinhold <bonefish@cs.tu-berlin.de>
8 */
9
10 #include <AppDefs.h>
11 #include <Message.h>
12 #include <MessageFilter.h>
13 #include <View.h>
14
15 #include "PopupControl.h"
16 #include "PopupView.h"
17
18 #include "PopupWindow.h"
19
20 // MouseDownFilter
21
22 class MouseDownFilter : public BMessageFilter {
23 public:
24 MouseDownFilter(BWindow* window);
25
26 virtual filter_result Filter(BMessage*, BHandler** target);
27
28 private:
29 BWindow* fWindow;
30 };
31
32 // constructor
MouseDownFilter(BWindow * window)33 MouseDownFilter::MouseDownFilter(BWindow* window)
34 : BMessageFilter(B_MOUSE_DOWN),
35 fWindow(window)
36 {
37 }
38
39 // Filter
40 filter_result
Filter(BMessage * message,BHandler ** target)41 MouseDownFilter::Filter(BMessage* message, BHandler** target)
42 {
43 if (fWindow) {
44 if (BView* view = dynamic_cast<BView*>(*target)) {
45 BPoint point;
46 if (message->FindPoint("where", &point) == B_OK) {
47 if (!fWindow->Frame().Contains(view->ConvertToScreen(point)))
48 *target = fWindow;
49 }
50 }
51 }
52 return B_DISPATCH_MESSAGE;
53 }
54
55
56 // PopupWindow
57
58 // constructor
PopupWindow(PopupView * child,PopupControl * control)59 PopupWindow::PopupWindow(PopupView* child, PopupControl* control)
60 : MWindow(BRect(0.0, 0.0, 10.0, 10.0), "popup",
61 B_NO_BORDER_WINDOW_LOOK, B_FLOATING_ALL_WINDOW_FEEL,
62 B_ASYNCHRONOUS_CONTROLS),
63 fCanceled(true),
64 fControl(control)
65 {
66 AddChild(child);
67 child->SetPopupWindow(this);
68 AddCommonFilter(new MouseDownFilter(this));
69 }
70
71 // destructor
~PopupWindow()72 PopupWindow::~PopupWindow()
73 {
74 }
75
76 // MessageReceived
77 void
MessageReceived(BMessage * message)78 PopupWindow::MessageReceived(BMessage* message)
79 {
80 switch (message->what) {
81 case B_MOUSE_DOWN:
82 fCanceled = true;
83 Hide();
84 break;
85 default:
86 MWindow::MessageReceived(message);
87 break;
88 }
89 }
90
91 // Show
92 void
Show()93 PopupWindow::Show()
94 {
95 if (BLooper *looper = fControl->Looper())
96 looper->PostMessage(MSG_POPUP_SHOWN, fControl);
97 MWindow::Show();
98 }
99
100 // Hide
101 void
Hide()102 PopupWindow::Hide()
103 {
104 if (BLooper *looper = fControl->Looper()) {
105 BMessage msg(MSG_POPUP_HIDDEN);
106 msg.AddBool("canceled", fCanceled);
107 looper->PostMessage(&msg, fControl);
108 }
109 MWindow::Hide();
110 }
111
112 // QuitRequested
113 bool
QuitRequested()114 PopupWindow::QuitRequested()
115 {
116 return false;
117 }
118
119 // PopupDone
120 void
PopupDone(bool canceled)121 PopupWindow::PopupDone(bool canceled)
122 {
123 fCanceled = canceled;
124 Hide();
125 }
126
127