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 22class 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 33MouseDownFilter::MouseDownFilter(BWindow* window) 34 : BMessageFilter(B_MOUSE_DOWN), 35 fWindow(window) 36{ 37} 38 39// Filter 40filter_result 41MouseDownFilter::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 59PopupWindow::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 72PopupWindow::~PopupWindow() 73{ 74} 75 76// MessageReceived 77void 78PopupWindow::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 92void 93PopupWindow::Show() 94{ 95 if (BLooper *looper = fControl->Looper()) 96 looper->PostMessage(MSG_POPUP_SHOWN, fControl); 97 MWindow::Show(); 98} 99 100// Hide 101void 102PopupWindow::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 113bool 114PopupWindow::QuitRequested() 115{ 116 return false; 117} 118 119// PopupDone 120void 121PopupWindow::PopupDone(bool canceled) 122{ 123 fCanceled = canceled; 124 Hide(); 125} 126 127