xref: /haiku/src/apps/deskbar/BarMenuBar.cpp (revision 99d027cd0238c1d86da86d7c3f4200509ccc61a6)
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 <string.h>
40 
41 #include <Bitmap.h>
42 #include <Debug.h>
43 #include <NodeInfo.h>
44 
45 #include "icons.h"
46 
47 #include "BarWindow.h"
48 #include "DeskbarMenu.h"
49 #include "DeskbarUtils.h"
50 #include "ResourceSet.h"
51 #include "TeamMenu.h"
52 
53 
54 const float kSepItemWidth = 5.0f;
55 
56 TBarMenuBar::TBarMenuBar(TBarView* bar, BRect frame, const char* name)
57 	: BMenuBar(frame, name, B_FOLLOW_NONE, B_ITEMS_IN_ROW, false),
58 	fBarView(bar),
59 	fAppListMenuItem(NULL),
60 	fSeparatorItem(NULL)
61 {
62 	SetItemMargins(0.0f, 0.0f, 0.0f, 0.0f);
63 
64 	TDeskbarMenu* beMenu = new TDeskbarMenu(bar);
65 	TBarWindow::SetDeskbarMenu(beMenu);
66 
67 	const BBitmap* logoBitmap = AppResSet()->FindBitmap(B_MESSAGE_TYPE,
68 		R_LeafLogoBitmap);
69 	fDeskbarMenuItem = new TBarMenuTitle(frame.Width(), frame.Height(),
70 		logoBitmap, beMenu);
71 	AddItem(fDeskbarMenuItem);
72 }
73 
74 
75 TBarMenuBar::~TBarMenuBar()
76 {
77 }
78 
79 
80 void
81 TBarMenuBar::SmartResize(float width, float height)
82 {
83 	if (width == -1.0f && height == -1.0f) {
84 		BRect frame = Frame();
85 		width = frame.Width();
86 		height = frame.Height();
87 	} else
88 		ResizeTo(width, height);
89 
90 	width -= 1;
91 
92 	if (fSeparatorItem != NULL)
93 		fDeskbarMenuItem->SetWidthHeight(width - kSepItemWidth, height);
94 	else {
95 		int32 count = CountItems();
96 		if (fDeskbarMenuItem)
97 			fDeskbarMenuItem->SetWidthHeight(width / count, height);
98 		if (fAppListMenuItem)
99 			fAppListMenuItem->SetWidthHeight(width / count, height);
100 	}
101 
102 	InvalidateLayout();
103 }
104 
105 
106 bool
107 TBarMenuBar::AddTeamMenu()
108 {
109 	if (CountItems() > 1)
110 		return false;
111 
112 	BRect frame(Frame());
113 
114 	delete fAppListMenuItem;
115 	fAppListMenuItem = new TBarMenuTitle(0.0f, 0.0f,
116 		AppResSet()->FindBitmap(B_MESSAGE_TYPE, R_TeamIcon), new TTeamMenu());
117 
118 	bool added = AddItem(fAppListMenuItem);
119 
120 	if (added)
121 		SmartResize(frame.Width() - 1.0f, frame.Height());
122 	else
123 		SmartResize(frame.Width(), frame.Height());
124 
125 	return added;
126 }
127 
128 
129 bool
130 TBarMenuBar::RemoveTeamMenu()
131 {
132 	if (CountItems() < 2)
133 		return false;
134 
135 	bool removed = false;
136 
137 	if (fAppListMenuItem != NULL && RemoveItem(fAppListMenuItem)) {
138 		delete fAppListMenuItem;
139 		fAppListMenuItem = NULL;
140 		SmartResize(-1, -1);
141 		removed = true;
142 	}
143 
144 	return removed;
145 }
146 
147 
148 bool
149 TBarMenuBar::AddSeperatorItem()
150 {
151 	if (CountItems() > 1)
152 		return false;
153 
154 	BRect frame(Frame());
155 
156 	delete fSeparatorItem;
157 	fSeparatorItem = new TTeamMenuItem(kSepItemWidth,
158 		frame.Height() - 2, false);
159 	fSeparatorItem->SetEnabled(false);
160 
161 	bool added = AddItem(fSeparatorItem);
162 
163 	if (added)
164 		SmartResize(frame.Width() - 1.0f, frame.Height());
165 	else
166 		SmartResize(frame.Width(), frame.Height());
167 
168 	return added;
169 }
170 
171 
172 bool
173 TBarMenuBar::RemoveSeperatorItem()
174 {
175 	if (CountItems() < 2)
176 		return false;
177 
178 	bool removed = false;
179 
180 	if (fSeparatorItem != NULL && RemoveItem(fSeparatorItem)) {
181 		delete fSeparatorItem;
182 		fSeparatorItem = NULL;
183 		SmartResize(-1, -1);
184 		removed = true;
185 	}
186 
187 	return removed;
188 }
189 
190 
191 void
192 TBarMenuBar::Draw(BRect updateRect)
193 {
194 	// want to skip the fancy BMenuBar drawing code.
195 	BMenu::Draw(updateRect);
196 }
197 
198 
199 void
200 TBarMenuBar::DrawBackground(BRect updateRect)
201 {
202 	BMenu::DrawBackground(updateRect);
203 }
204 
205 
206 void
207 TBarMenuBar::MouseMoved(BPoint where, uint32 code, const BMessage* message)
208 {
209 	// the following code parallels that in ExpandoMenuBar for DnD tracking
210 
211 	if (!message) {
212 		// force a cleanup
213 		fBarView->DragStop(true);
214 		BMenuBar::MouseMoved(where, code, message);
215 		return;
216 	}
217 
218 	switch (code) {
219 		case B_ENTERED_VIEW:
220 		{
221 			BPoint loc;
222 			uint32 buttons;
223 			GetMouse(&loc, &buttons);
224 			// attempt to start DnD tracking
225 			if (message && buttons != 0) {
226 				fBarView->CacheDragData(const_cast<BMessage*>(message));
227 				MouseDown(loc);
228 			}
229 			break;
230 		}
231 	}
232 	BMenuBar::MouseMoved(where, code, message);
233 }
234 
235 
236 static void
237 init_tracking_hook(BMenuItem* item, bool (*hookFunction)(BMenu*, void*),
238 	void* state)
239 {
240 	if (!item)
241 		return;
242 
243 	BMenu* windowMenu = item->Submenu();
244 	if (windowMenu) {
245 		// have a menu, set the tracking hook
246 		windowMenu->SetTrackingHook(hookFunction, state);
247 	}
248 }
249 
250 
251 void
252 TBarMenuBar::InitTrackingHook(bool (*hookFunction)(BMenu*, void*),
253 	void* state, bool both)
254 {
255 	BPoint loc;
256 	uint32 buttons;
257 	GetMouse(&loc, &buttons);
258 	// set the hook functions for the two menus
259 	// will always have the deskbar menu
260 	// may have the app menu as well (mini mode)
261 	if (fDeskbarMenuItem->Frame().Contains(loc) || both)
262 		init_tracking_hook(fDeskbarMenuItem, hookFunction, state);
263 
264 	if (fAppListMenuItem && (fAppListMenuItem->Frame().Contains(loc) || both))
265 		init_tracking_hook(fAppListMenuItem, hookFunction, state);
266 }
267