xref: /haiku/src/apps/deskbar/BarMenuBar.cpp (revision 220d04022750f40f8bac8f01fa551211e28d04f2)
1 /*
2 Open Tracker License
3 
4 Terms and Conditions
5 
6 Copyright (c) 1991-2000, Be Incorporated. All rights reserved.
7 
8 Permission is hereby granted, free of charge, to any person obtaining a copy of
9 this software and associated documentation files (the "Software"), to deal in
10 the Software without restriction, including without limitation the rights to
11 use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
12 of the Software, and to permit persons to whom the Software is furnished to do
13 so, subject to the following conditions:
14 
15 The above copyright notice and this permission notice applies to all licensees
16 and shall be included in all copies or substantial portions of the Software.
17 
18 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF TITLE, MERCHANTABILITY,
20 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
21 BE INCORPORATED BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
22 AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF, OR IN CONNECTION
23 WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
24 
25 Except as contained in this notice, the name of Be Incorporated shall not be
26 used in advertising or otherwise to promote the sale, use or other dealings in
27 this Software without prior written authorization from Be Incorporated.
28 
29 Tracker(TM), Be(R), BeOS(R), and BeIA(TM) are trademarks or registered
30 trademarks of Be Incorporated in the United States and other countries. Other
31 brand product names are registered trademarks or trademarks of their respective
32 holders.
33 All rights reserved.
34 */
35 
36 
37 #include "BarMenuBar.h"
38 
39 #include <Bitmap.h>
40 #include <ControlLook.h>
41 #include <Debug.h>
42 #include <NodeInfo.h>
43 
44 #include "icons.h"
45 
46 #include "BarMenuTitle.h"
47 #include "BarView.h"
48 #include "BarWindow.h"
49 #include "DeskbarMenu.h"
50 #include "DeskbarUtils.h"
51 #include "ResourceSet.h"
52 #include "TeamMenu.h"
53 
54 
55 const float kSepItemWidth = 5.0f;
56 
57 
58 //	#pragma mark - TSeparatorItem
59 
60 
61 TSeparatorItem::TSeparatorItem()
62 	:
63 	BSeparatorItem()
64 {
65 }
66 
67 
68 void
69 TSeparatorItem::Draw()
70 {
71 	BMenu* menu = Menu();
72 	if (menu == NULL)
73 		return;
74 
75 	BRect frame(Frame());
76 	frame.right = frame.left + kSepItemWidth;
77 	rgb_color base = menu->LowColor();
78 
79 	menu->PushState();
80 
81 	menu->SetHighColor(tint_color(base, 1.22));
82 	frame.top--;
83 		// need to expand the frame for some reason
84 
85 	// stroke a darker line on the left edge
86 	menu->StrokeLine(frame.LeftTop(), frame.LeftBottom());
87 	frame.left++;
88 
89 	// fill in background
90 	be_control_look->DrawButtonBackground(menu, frame, frame, base);
91 
92 	menu->PopState();
93 }
94 
95 
96 //	#pragma mark - TBarMenuBar
97 
98 
99 TBarMenuBar::TBarMenuBar(BRect frame, const char* name, TBarView* barView)
100 	:
101 	BMenuBar(frame, name, B_FOLLOW_NONE, B_ITEMS_IN_ROW, false),
102 	fBarView(barView),
103 	fAppListMenuItem(NULL),
104 	fSeparatorItem(NULL)
105 {
106 	SetItemMargins(0.0f, 0.0f, 0.0f, 0.0f);
107 
108 	TDeskbarMenu* beMenu = new TDeskbarMenu(barView);
109 	TBarWindow::SetDeskbarMenu(beMenu);
110 
111 	fDeskbarMenuItem = new TBarMenuTitle(0.0f, 0.0f,
112 		AppResSet()->FindBitmap(B_MESSAGE_TYPE, R_LeafLogoBitmap), beMenu);
113 	AddItem(fDeskbarMenuItem);
114 }
115 
116 
117 TBarMenuBar::~TBarMenuBar()
118 {
119 }
120 
121 
122 void
123 TBarMenuBar::SmartResize(float width, float height)
124 {
125 	if (width == -1.0f && height == -1.0f) {
126 		BRect frame = Frame();
127 		width = frame.Width();
128 		height = frame.Height();
129 	} else
130 		ResizeTo(width, height);
131 
132 	width -= 1;
133 
134 	if (fSeparatorItem != NULL)
135 		fDeskbarMenuItem->SetContentSize(width - kSepItemWidth, height);
136 	else {
137 		int32 count = CountItems();
138 		if (fDeskbarMenuItem)
139 			fDeskbarMenuItem->SetContentSize(width / count, height);
140 		if (fAppListMenuItem)
141 			fAppListMenuItem->SetContentSize(width / count, height);
142 	}
143 
144 	InvalidateLayout();
145 }
146 
147 
148 bool
149 TBarMenuBar::AddTeamMenu()
150 {
151 	if (CountItems() > 1)
152 		return false;
153 
154 	BRect frame(Frame());
155 
156 	delete fAppListMenuItem;
157 	fAppListMenuItem = new TBarMenuTitle(0.0f, 0.0f,
158 		AppResSet()->FindBitmap(B_MESSAGE_TYPE, R_TeamIcon), new TTeamMenu());
159 
160 	bool added = AddItem(fAppListMenuItem);
161 
162 	if (added)
163 		SmartResize(frame.Width() - 1.0f, frame.Height());
164 	else
165 		SmartResize(frame.Width(), frame.Height());
166 
167 	return added;
168 }
169 
170 
171 bool
172 TBarMenuBar::RemoveTeamMenu()
173 {
174 	if (CountItems() < 2)
175 		return false;
176 
177 	bool removed = false;
178 
179 	if (fAppListMenuItem != NULL && RemoveItem(fAppListMenuItem)) {
180 		delete fAppListMenuItem;
181 		fAppListMenuItem = NULL;
182 		SmartResize(-1, -1);
183 		removed = true;
184 	}
185 
186 	return removed;
187 }
188 
189 
190 bool
191 TBarMenuBar::AddSeparatorItem()
192 {
193 	if (CountItems() > 1)
194 		return false;
195 
196 	BRect frame(Frame());
197 
198 	delete fSeparatorItem;
199 	fSeparatorItem = new TSeparatorItem();
200 
201 	bool added = AddItem(fSeparatorItem);
202 
203 	if (added)
204 		SmartResize(frame.Width() - 1.0f, frame.Height());
205 	else
206 		SmartResize(frame.Width(), frame.Height());
207 
208 	return added;
209 }
210 
211 
212 bool
213 TBarMenuBar::RemoveSeperatorItem()
214 {
215 	if (CountItems() < 2)
216 		return false;
217 
218 	bool removed = false;
219 
220 	if (fSeparatorItem != NULL && RemoveItem(fSeparatorItem)) {
221 		delete fSeparatorItem;
222 		fSeparatorItem = NULL;
223 		SmartResize(-1, -1);
224 		removed = true;
225 	}
226 
227 	return removed;
228 }
229 
230 
231 void
232 TBarMenuBar::Draw(BRect updateRect)
233 {
234 	// skip the fancy BMenuBar drawing code
235 	BMenu::Draw(updateRect);
236 }
237 
238 
239 void
240 TBarMenuBar::DrawBackground(BRect updateRect)
241 {
242 	BMenu::DrawBackground(updateRect);
243 }
244 
245 
246 void
247 TBarMenuBar::MouseMoved(BPoint where, uint32 code, const BMessage* message)
248 {
249 	// the following code parallels that in ExpandoMenuBar for DnD tracking
250 
251 	if (!message) {
252 		// force a cleanup
253 		fBarView->DragStop(true);
254 		BMenuBar::MouseMoved(where, code, message);
255 		return;
256 	}
257 
258 	switch (code) {
259 		case B_ENTERED_VIEW:
260 		{
261 			BPoint loc;
262 			uint32 buttons;
263 			GetMouse(&loc, &buttons);
264 			if (message != NULL && buttons != 0) {
265 				// attempt to start DnD tracking
266 				fBarView->CacheDragData(const_cast<BMessage*>(message));
267 				MouseDown(loc);
268 			}
269 			break;
270 		}
271 	}
272 
273 	BMenuBar::MouseMoved(where, code, message);
274 }
275 
276 
277 static void
278 init_tracking_hook(BMenuItem* item, bool (*hookFunction)(BMenu*, void*),
279 	void* state)
280 {
281 	if (!item)
282 		return;
283 
284 	BMenu* windowMenu = item->Submenu();
285 	if (windowMenu) {
286 		// have a menu, set the tracking hook
287 		windowMenu->SetTrackingHook(hookFunction, state);
288 	}
289 }
290 
291 
292 void
293 TBarMenuBar::InitTrackingHook(bool (*hookFunction)(BMenu*, void*),
294 	void* state, bool both)
295 {
296 	BPoint loc;
297 	uint32 buttons;
298 	GetMouse(&loc, &buttons);
299 	// set the hook functions for the two menus
300 	// will always have the deskbar menu
301 	// may have the app menu as well (mini mode)
302 	if (fDeskbarMenuItem->Frame().Contains(loc) || both)
303 		init_tracking_hook(fDeskbarMenuItem, hookFunction, state);
304 
305 	if (fAppListMenuItem && (fAppListMenuItem->Frame().Contains(loc) || both))
306 		init_tracking_hook(fAppListMenuItem, hookFunction, state);
307 }
308