#include "PopupControl.h"
#include <stdio.h>
#include <Message.h>
#include <Screen.h>
#include "PopupView.h"
#include "PopupWindow.h"
PopupControl::PopupControl(const char* name, PopupView* child)
: BView(BRect(0.0f, 0.0f, 10.0f, 10.0f),
name, B_FOLLOW_NONE, B_WILL_DRAW | B_FULL_UPDATE_ON_RESIZE),
fPopupWindow(NULL),
fPopupChild(child),
fHPopupAlignment(0.5),
fVPopupAlignment(0.5)
{
}
PopupControl::~PopupControl()
{
}
void
PopupControl::MessageReceived(BMessage* message)
{
switch (message->what) {
case MSG_POPUP_SHOWN:
PopupShown();
break;
case MSG_POPUP_HIDDEN:
bool canceled;
if (message->FindBool("canceled", &canceled) != B_OK)
canceled = true;
PopupHidden(canceled);
HidePopup();
break;
default:
BView::MessageReceived(message);
break;
}
}
void
PopupControl::SetPopupAlignment(float hPopupAlignment, float vPopupAlignment)
{
fHPopupAlignment = hPopupAlignment;
fVPopupAlignment = vPopupAlignment;
}
void
PopupControl::SetPopupLocation(BPoint leftTop)
{
fPopupLeftTop = leftTop;
fHPopupAlignment = -1.0;
fVPopupAlignment = -1.0;
}
void
PopupControl::ShowPopup(BPoint* offset)
{
if (!fPopupWindow) {
fPopupWindow = new PopupWindow(fPopupChild, this);
fPopupWindow->RecalcSize();
BRect frame(fPopupWindow->Frame());
BPoint leftLocation;
if (fHPopupAlignment >= 0.0 && fVPopupAlignment >= 0.0) {
leftLocation = ConvertToScreen(Bounds().LeftTop());
leftLocation.x -= fPopupWindow->Frame().Width() + 1.0;
leftLocation.y -= fPopupWindow->Frame().Height() + 1.0;
float totalWidth = Bounds().Width() + fPopupWindow->Frame().Width();
float totalHeight = Bounds().Height() + fPopupWindow->Frame().Height();
leftLocation.x += fHPopupAlignment * totalWidth;
leftLocation.y += fHPopupAlignment * totalHeight;
} else
leftLocation = ConvertToScreen(fPopupLeftTop);
frame.OffsetTo(leftLocation);
BScreen screen(fPopupWindow);
BRect dest(screen.Frame());
if (frame.Width() > dest.Width())
frame.right = frame.left + dest.Width();
if (frame.Height() > dest.Height())
frame.bottom = frame.top + dest.Height();
float hOffset = 0.0;
float vOffset = 0.0;
if (frame.bottom > dest.bottom)
vOffset = dest.bottom - frame.bottom;
if (frame.top < dest.top)
vOffset = dest.top - frame.top;
if (frame.right > dest.right)
hOffset = dest.right - frame.right;
if (frame.left < dest.left)
hOffset = dest.left - frame.left;
frame.OffsetBy(hOffset, vOffset);
if (offset) {
offset->x += hOffset;
offset->y += vOffset;
}
fPopupWindow->MoveTo(frame.LeftTop());
fPopupWindow->ResizeTo(frame.Width(), frame.Height());
fPopupWindow->Show();
}
}
void
PopupControl::HidePopup()
{
if (fPopupWindow) {
fPopupWindow->Lock();
fPopupChild->SetPopupWindow(NULL);
fPopupWindow->RemoveChild(fPopupChild);
fPopupWindow->Quit();
fPopupWindow = NULL;
}
}
void
PopupControl::PopupShown()
{
}
void
PopupControl::PopupHidden(bool canceled)
{
}