xref: /haiku/src/apps/icon-o-matic/generic/gui/popup_control/PopupWindow.cpp (revision e81a954787e50e56a7f06f72705b7859b6ab06d1)
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
33 MouseDownFilter::MouseDownFilter(BWindow* window)
34 	: BMessageFilter(B_MOUSE_DOWN),
35 	  fWindow(window)
36 {
37 }
38 
39 // Filter
40 filter_result
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
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
72 PopupWindow::~PopupWindow()
73 {
74 }
75 
76 // MessageReceived
77 void
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
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
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
114 PopupWindow::QuitRequested()
115 {
116 	return false;
117 }
118 
119 // PopupDone
120 void
121 PopupWindow::PopupDone(bool canceled)
122 {
123 	fCanceled = canceled;
124 	Hide();
125 }
126 
127