xref: /haiku/src/apps/icon-o-matic/generic/gui/popup_control/PopupControl.cpp (revision 128277c969aa806add78941cd2972754c37a1572)
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
PopupControl(const char * name,PopupView * child)21 PopupControl::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
~PopupControl()32 PopupControl::~PopupControl()
33 {
34 }
35 
36 // MessageReceived
37 void
MessageReceived(BMessage * message)38 PopupControl::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
58 void
SetPopupAlignment(float hPopupAlignment,float vPopupAlignment)59 PopupControl::SetPopupAlignment(float hPopupAlignment, float vPopupAlignment)
60 {
61 	fHPopupAlignment = hPopupAlignment;
62 	fVPopupAlignment = vPopupAlignment;
63 }
64 
65 // SetPopupLocation
66 //
67 // overrides Alignment
68 void
SetPopupLocation(BPoint leftTop)69 PopupControl::SetPopupLocation(BPoint leftTop)
70 {
71 	fPopupLeftTop = leftTop;
72 	fHPopupAlignment = -1.0;
73 	fVPopupAlignment = -1.0;
74 }
75 
76 // ShowPopup
77 void
ShowPopup(BPoint * offset)78 PopupControl::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
129 void
HidePopup()130 PopupControl::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
142 void
PopupShown()143 PopupControl::PopupShown()
144 {
145 }
146 
147 // PopupHidden
148 void
PopupHidden(bool canceled)149 PopupControl::PopupHidden(bool canceled)
150 {
151 }
152 
153 
154