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 "PopupControl.h" 11 12#include <stdio.h> 13 14#include <Message.h> 15#include <Screen.h> 16 17#include "PopupView.h" 18#include "PopupWindow.h" 19 20// constructor 21PopupControl::PopupControl(const char* name, PopupView* child) 22 : BView(BRect(0.0f, 0.0f, 10.0f, 10.0f), 23 name, B_FOLLOW_NONE, B_WILL_DRAW | B_FULL_UPDATE_ON_RESIZE), 24 fPopupWindow(NULL), 25 fPopupChild(child), 26 fHPopupAlignment(0.5), 27 fVPopupAlignment(0.5) 28{ 29} 30 31// destructor 32PopupControl::~PopupControl() 33{ 34} 35 36// MessageReceived 37void 38PopupControl::MessageReceived(BMessage* message) 39{ 40 switch (message->what) { 41 case MSG_POPUP_SHOWN: 42 PopupShown(); 43 break; 44 case MSG_POPUP_HIDDEN: 45 bool canceled; 46 if (message->FindBool("canceled", &canceled) != B_OK) 47 canceled = true; 48 PopupHidden(canceled); 49 HidePopup(); 50 break; 51 default: 52 BView::MessageReceived(message); 53 break; 54 } 55} 56 57// SetPopupLocation 58void 59PopupControl::SetPopupAlignment(float hPopupAlignment, float vPopupAlignment) 60{ 61 fHPopupAlignment = hPopupAlignment; 62 fVPopupAlignment = vPopupAlignment; 63} 64 65// SetPopupLocation 66// 67// overrides Alignment 68void 69PopupControl::SetPopupLocation(BPoint leftTop) 70{ 71 fPopupLeftTop = leftTop; 72 fHPopupAlignment = -1.0; 73 fVPopupAlignment = -1.0; 74} 75 76// ShowPopup 77void 78PopupControl::ShowPopup(BPoint* offset) 79{ 80 if (!fPopupWindow) { 81 fPopupWindow = new PopupWindow(fPopupChild, this); 82 fPopupWindow->RecalcSize(); 83 BRect frame(fPopupWindow->Frame()); 84 85 BPoint leftLocation; 86 if (fHPopupAlignment >= 0.0 && fVPopupAlignment >= 0.0) { 87 leftLocation = ConvertToScreen(Bounds().LeftTop()); 88 leftLocation.x -= fPopupWindow->Frame().Width() + 1.0; 89 leftLocation.y -= fPopupWindow->Frame().Height() + 1.0; 90 float totalWidth = Bounds().Width() + fPopupWindow->Frame().Width(); 91 float totalHeight = Bounds().Height() + fPopupWindow->Frame().Height(); 92 leftLocation.x += fHPopupAlignment * totalWidth; 93 leftLocation.y += fHPopupAlignment * totalHeight; 94 } else 95 leftLocation = ConvertToScreen(fPopupLeftTop); 96 97 frame.OffsetTo(leftLocation); 98 BScreen screen(fPopupWindow); 99 BRect dest(screen.Frame()); 100 // check if too big 101 if (frame.Width() > dest.Width()) 102 frame.right = frame.left + dest.Width(); 103 if (frame.Height() > dest.Height()) 104 frame.bottom = frame.top + dest.Height(); 105 // check if out of screen 106 float hOffset = 0.0; 107 float vOffset = 0.0; 108 if (frame.bottom > dest.bottom) 109 vOffset = dest.bottom - frame.bottom; 110 if (frame.top < dest.top) 111 vOffset = dest.top - frame.top; 112 if (frame.right > dest.right) 113 hOffset = dest.right - frame.right; 114 if (frame.left < dest.left) 115 hOffset = dest.left - frame.left; 116 // finally move/resize our popup window 117 frame.OffsetBy(hOffset, vOffset); 118 if (offset) { 119 offset->x += hOffset; 120 offset->y += vOffset; 121 } 122 fPopupWindow->MoveTo(frame.LeftTop()); 123 fPopupWindow->ResizeTo(frame.Width(), frame.Height()); 124 fPopupWindow->Show(); 125 } 126} 127 128// HidePopup 129void 130PopupControl::HidePopup() 131{ 132 if (fPopupWindow) { 133 fPopupWindow->Lock(); 134 fPopupChild->SetPopupWindow(NULL); 135 fPopupWindow->RemoveChild(fPopupChild); 136 fPopupWindow->Quit(); 137 fPopupWindow = NULL; 138 } 139} 140 141// PopupShown 142void 143PopupControl::PopupShown() 144{ 145} 146 147// PopupHidden 148void 149PopupControl::PopupHidden(bool canceled) 150{ 151} 152 153 154