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