xref: /haiku/src/apps/deskbar/BarMenuBar.cpp (revision 03f7c11ece0869967f2dc6b36cca8da7403594af)
141281cf3SAxel Dörfler /*
241281cf3SAxel Dörfler Open Tracker License
341281cf3SAxel Dörfler 
441281cf3SAxel Dörfler Terms and Conditions
541281cf3SAxel Dörfler 
641281cf3SAxel Dörfler Copyright (c) 1991-2000, Be Incorporated. All rights reserved.
741281cf3SAxel Dörfler 
841281cf3SAxel Dörfler Permission is hereby granted, free of charge, to any person obtaining a copy of
941281cf3SAxel Dörfler this software and associated documentation files (the "Software"), to deal in
1041281cf3SAxel Dörfler the Software without restriction, including without limitation the rights to
1141281cf3SAxel Dörfler use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
1241281cf3SAxel Dörfler of the Software, and to permit persons to whom the Software is furnished to do
1341281cf3SAxel Dörfler so, subject to the following conditions:
1441281cf3SAxel Dörfler 
1541281cf3SAxel Dörfler The above copyright notice and this permission notice applies to all licensees
1641281cf3SAxel Dörfler and shall be included in all copies or substantial portions of the Software.
1741281cf3SAxel Dörfler 
1841281cf3SAxel Dörfler THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
1941281cf3SAxel Dörfler IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF TITLE, MERCHANTABILITY,
2041281cf3SAxel Dörfler FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
2141281cf3SAxel Dörfler BE INCORPORATED BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
2241281cf3SAxel Dörfler AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF, OR IN CONNECTION
2341281cf3SAxel Dörfler WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
2441281cf3SAxel Dörfler 
2541281cf3SAxel Dörfler Except as contained in this notice, the name of Be Incorporated shall not be
2641281cf3SAxel Dörfler used in advertising or otherwise to promote the sale, use or other dealings in
2741281cf3SAxel Dörfler this Software without prior written authorization from Be Incorporated.
2841281cf3SAxel Dörfler 
294ec67d2bSFredrik Holmqvist Tracker(TM), Be(R), BeOS(R), and BeIA(TM) are trademarks or registered
304ec67d2bSFredrik Holmqvist trademarks of Be Incorporated in the United States and other countries. Other
314ec67d2bSFredrik Holmqvist brand product names are registered trademarks or trademarks of their respective
324ec67d2bSFredrik Holmqvist holders.
3341281cf3SAxel Dörfler All rights reserved.
3441281cf3SAxel Dörfler */
3541281cf3SAxel Dörfler 
361cf94bf9SStephan Aßmus 
371cf94bf9SStephan Aßmus #include "BarMenuBar.h"
381cf94bf9SStephan Aßmus 
3941281cf3SAxel Dörfler #include <Bitmap.h>
401cd61330SJohn Scipione #include <Debug.h>
4141281cf3SAxel Dörfler #include <NodeInfo.h>
4241281cf3SAxel Dörfler 
4341281cf3SAxel Dörfler #include "icons.h"
44615d572dSJohn Scipione 
4541281cf3SAxel Dörfler #include "BarWindow.h"
46323b6546SOliver Tappe #include "DeskbarMenu.h"
47323b6546SOliver Tappe #include "DeskbarUtils.h"
4841281cf3SAxel Dörfler #include "ResourceSet.h"
4941281cf3SAxel Dörfler #include "TeamMenu.h"
5041281cf3SAxel Dörfler 
5141281cf3SAxel Dörfler 
52c07e6ff2SJohn Scipione const float kSepItemWidth = 5.0f;
53c07e6ff2SJohn Scipione 
5441281cf3SAxel Dörfler TBarMenuBar::TBarMenuBar(TBarView* bar, BRect frame, const char* name)
5541281cf3SAxel Dörfler 	: BMenuBar(frame, name, B_FOLLOW_NONE, B_ITEMS_IN_ROW, false),
5641281cf3SAxel Dörfler 	fBarView(bar),
576c54ebe5SJohn Scipione 	fAppListMenuItem(NULL),
586c54ebe5SJohn Scipione 	fSeparatorItem(NULL)
5941281cf3SAxel Dörfler {
6041281cf3SAxel Dörfler 	SetItemMargins(0.0f, 0.0f, 0.0f, 0.0f);
6141281cf3SAxel Dörfler 
62323b6546SOliver Tappe 	TDeskbarMenu* beMenu = new TDeskbarMenu(bar);
63323b6546SOliver Tappe 	TBarWindow::SetDeskbarMenu(beMenu);
6441281cf3SAxel Dörfler 
65615d572dSJohn Scipione 	const BBitmap* logoBitmap = AppResSet()->FindBitmap(B_MESSAGE_TYPE,
66615d572dSJohn Scipione 		R_LeafLogoBitmap);
67323b6546SOliver Tappe 	fDeskbarMenuItem = new TBarMenuTitle(frame.Width(), frame.Height(),
68615d572dSJohn Scipione 		logoBitmap, beMenu);
69323b6546SOliver Tappe 	AddItem(fDeskbarMenuItem);
7041281cf3SAxel Dörfler }
7141281cf3SAxel Dörfler 
7241281cf3SAxel Dörfler 
7341281cf3SAxel Dörfler TBarMenuBar::~TBarMenuBar()
7441281cf3SAxel Dörfler {
7541281cf3SAxel Dörfler }
7641281cf3SAxel Dörfler 
7741281cf3SAxel Dörfler 
7841281cf3SAxel Dörfler void
7941281cf3SAxel Dörfler TBarMenuBar::SmartResize(float width, float height)
8041281cf3SAxel Dörfler {
817da06231SAxel Dörfler 	if (width == -1.0f && height == -1.0f) {
8241281cf3SAxel Dörfler 		BRect frame = Frame();
8341281cf3SAxel Dörfler 		width = frame.Width();
8441281cf3SAxel Dörfler 		height = frame.Height();
8541281cf3SAxel Dörfler 	} else
8641281cf3SAxel Dörfler 		ResizeTo(width, height);
8741281cf3SAxel Dörfler 
8841281cf3SAxel Dörfler 	width -= 1;
8941281cf3SAxel Dörfler 
900f10682fSJohn Scipione 	if (fSeparatorItem != NULL)
91*03f7c11eSJohn Scipione 		fDeskbarMenuItem->SetContentSize(width - kSepItemWidth, height);
92c07e6ff2SJohn Scipione 	else {
9341281cf3SAxel Dörfler 		int32 count = CountItems();
94323b6546SOliver Tappe 		if (fDeskbarMenuItem)
95*03f7c11eSJohn Scipione 			fDeskbarMenuItem->SetContentSize(width / count, height);
9641281cf3SAxel Dörfler 		if (fAppListMenuItem)
97*03f7c11eSJohn Scipione 			fAppListMenuItem->SetContentSize(width / count, height);
98c07e6ff2SJohn Scipione 	}
9941281cf3SAxel Dörfler 
10041281cf3SAxel Dörfler 	InvalidateLayout();
10141281cf3SAxel Dörfler }
10241281cf3SAxel Dörfler 
10341281cf3SAxel Dörfler 
104fc18a4f5SJohn Scipione bool
10541281cf3SAxel Dörfler TBarMenuBar::AddTeamMenu()
10641281cf3SAxel Dörfler {
10741281cf3SAxel Dörfler 	if (CountItems() > 1)
108fc18a4f5SJohn Scipione 		return false;
10941281cf3SAxel Dörfler 
11041281cf3SAxel Dörfler 	BRect frame(Frame());
11141281cf3SAxel Dörfler 
112cb7c5f05SJohn Scipione 	delete fAppListMenuItem;
11341281cf3SAxel Dörfler 	fAppListMenuItem = new TBarMenuTitle(0.0f, 0.0f,
11441281cf3SAxel Dörfler 		AppResSet()->FindBitmap(B_MESSAGE_TYPE, R_TeamIcon), new TTeamMenu());
115cb7c5f05SJohn Scipione 
116fc18a4f5SJohn Scipione 	bool added = AddItem(fAppListMenuItem);
117fc18a4f5SJohn Scipione 
118fc18a4f5SJohn Scipione 	if (added)
11941281cf3SAxel Dörfler 		SmartResize(frame.Width() - 1.0f, frame.Height());
120fc18a4f5SJohn Scipione 	else
12111f46c6dSJohn Scipione 		SmartResize(frame.Width(), frame.Height());
122fc18a4f5SJohn Scipione 
123fc18a4f5SJohn Scipione 	return added;
12441281cf3SAxel Dörfler }
12541281cf3SAxel Dörfler 
12641281cf3SAxel Dörfler 
127fc18a4f5SJohn Scipione bool
12841281cf3SAxel Dörfler TBarMenuBar::RemoveTeamMenu()
12941281cf3SAxel Dörfler {
13041281cf3SAxel Dörfler 	if (CountItems() < 2)
131fc18a4f5SJohn Scipione 		return false;
132fc18a4f5SJohn Scipione 
133fc18a4f5SJohn Scipione 	bool removed = false;
13441281cf3SAxel Dörfler 
13508282eb4SJohn Scipione 	if (fAppListMenuItem != NULL && RemoveItem(fAppListMenuItem)) {
13641281cf3SAxel Dörfler 		delete fAppListMenuItem;
13741281cf3SAxel Dörfler 		fAppListMenuItem = NULL;
13811f46c6dSJohn Scipione 		SmartResize(-1, -1);
139fc18a4f5SJohn Scipione 		removed = true;
14041281cf3SAxel Dörfler 	}
141fc18a4f5SJohn Scipione 
142fc18a4f5SJohn Scipione 	return removed;
14341281cf3SAxel Dörfler }
14441281cf3SAxel Dörfler 
14541281cf3SAxel Dörfler 
146fc18a4f5SJohn Scipione bool
147c07e6ff2SJohn Scipione TBarMenuBar::AddSeperatorItem()
148c07e6ff2SJohn Scipione {
149c07e6ff2SJohn Scipione 	if (CountItems() > 1)
150fc18a4f5SJohn Scipione 		return false;
151c07e6ff2SJohn Scipione 
152c07e6ff2SJohn Scipione 	BRect frame(Frame());
153c07e6ff2SJohn Scipione 
154cb7c5f05SJohn Scipione 	delete fSeparatorItem;
155c07e6ff2SJohn Scipione 	fSeparatorItem = new TTeamMenuItem(kSepItemWidth,
156c07e6ff2SJohn Scipione 		frame.Height() - 2, false);
157c07e6ff2SJohn Scipione 	fSeparatorItem->SetEnabled(false);
158cb7c5f05SJohn Scipione 
159fc18a4f5SJohn Scipione 	bool added = AddItem(fSeparatorItem);
160fc18a4f5SJohn Scipione 
161fc18a4f5SJohn Scipione 	if (added)
162c07e6ff2SJohn Scipione 		SmartResize(frame.Width() - 1.0f, frame.Height());
16311f46c6dSJohn Scipione 	else
16411f46c6dSJohn Scipione 		SmartResize(frame.Width(), frame.Height());
165fc18a4f5SJohn Scipione 
166fc18a4f5SJohn Scipione 	return added;
167c07e6ff2SJohn Scipione }
168c07e6ff2SJohn Scipione 
169c07e6ff2SJohn Scipione 
170fc18a4f5SJohn Scipione bool
171c07e6ff2SJohn Scipione TBarMenuBar::RemoveSeperatorItem()
172c07e6ff2SJohn Scipione {
173c07e6ff2SJohn Scipione 	if (CountItems() < 2)
174fc18a4f5SJohn Scipione 		return false;
175fc18a4f5SJohn Scipione 
176fc18a4f5SJohn Scipione 	bool removed = false;
177c07e6ff2SJohn Scipione 
17808282eb4SJohn Scipione 	if (fSeparatorItem != NULL && RemoveItem(fSeparatorItem)) {
179c07e6ff2SJohn Scipione 		delete fSeparatorItem;
180c07e6ff2SJohn Scipione 		fSeparatorItem = NULL;
18111f46c6dSJohn Scipione 		SmartResize(-1, -1);
182fc18a4f5SJohn Scipione 		removed = true;
183c07e6ff2SJohn Scipione 	}
184fc18a4f5SJohn Scipione 
185fc18a4f5SJohn Scipione 	return removed;
186c07e6ff2SJohn Scipione }
187c07e6ff2SJohn Scipione 
188c07e6ff2SJohn Scipione 
189c07e6ff2SJohn Scipione void
190d6f6b835SJohn Scipione TBarMenuBar::Draw(BRect updateRect)
19141281cf3SAxel Dörfler {
19241281cf3SAxel Dörfler 	// want to skip the fancy BMenuBar drawing code.
193d6f6b835SJohn Scipione 	BMenu::Draw(updateRect);
19441281cf3SAxel Dörfler }
19541281cf3SAxel Dörfler 
19641281cf3SAxel Dörfler 
19741281cf3SAxel Dörfler void
198d6f6b835SJohn Scipione TBarMenuBar::DrawBackground(BRect updateRect)
19941281cf3SAxel Dörfler {
200d6f6b835SJohn Scipione 	BMenu::DrawBackground(updateRect);
20141281cf3SAxel Dörfler }
20241281cf3SAxel Dörfler 
20341281cf3SAxel Dörfler 
20441281cf3SAxel Dörfler void
20541281cf3SAxel Dörfler TBarMenuBar::MouseMoved(BPoint where, uint32 code, const BMessage* message)
20641281cf3SAxel Dörfler {
2077da06231SAxel Dörfler 	// the following code parallels that in ExpandoMenuBar for DnD tracking
2087da06231SAxel Dörfler 
20941281cf3SAxel Dörfler 	if (!message) {
21041281cf3SAxel Dörfler 		// force a cleanup
21141281cf3SAxel Dörfler 		fBarView->DragStop(true);
21241281cf3SAxel Dörfler 		BMenuBar::MouseMoved(where, code, message);
21341281cf3SAxel Dörfler 		return;
21441281cf3SAxel Dörfler 	}
21541281cf3SAxel Dörfler 
21641281cf3SAxel Dörfler 	switch (code) {
21741281cf3SAxel Dörfler 		case B_ENTERED_VIEW:
21841281cf3SAxel Dörfler 		{
21941281cf3SAxel Dörfler 			BPoint loc;
22041281cf3SAxel Dörfler 			uint32 buttons;
22141281cf3SAxel Dörfler 			GetMouse(&loc, &buttons);
222fe624b39SJohn Scipione 			if (message != NULL && buttons != 0) {
2237da06231SAxel Dörfler 				// attempt to start DnD tracking
22441281cf3SAxel Dörfler 				fBarView->CacheDragData(const_cast<BMessage*>(message));
22541281cf3SAxel Dörfler 				MouseDown(loc);
22641281cf3SAxel Dörfler 			}
22741281cf3SAxel Dörfler 			break;
22841281cf3SAxel Dörfler 		}
2297da06231SAxel Dörfler 	}
230fe624b39SJohn Scipione 
23141281cf3SAxel Dörfler 	BMenuBar::MouseMoved(where, code, message);
23241281cf3SAxel Dörfler }
23341281cf3SAxel Dörfler 
23441281cf3SAxel Dörfler 
23541281cf3SAxel Dörfler static void
2367da06231SAxel Dörfler init_tracking_hook(BMenuItem* item, bool (*hookFunction)(BMenu*, void*),
2377da06231SAxel Dörfler 	void* state)
23841281cf3SAxel Dörfler {
23941281cf3SAxel Dörfler 	if (!item)
24041281cf3SAxel Dörfler 		return;
24141281cf3SAxel Dörfler 
2427da06231SAxel Dörfler 	BMenu* windowMenu = item->Submenu();
2434ec67d2bSFredrik Holmqvist 	if (windowMenu) {
24441281cf3SAxel Dörfler 		// have a menu, set the tracking hook
2457da06231SAxel Dörfler 		windowMenu->SetTrackingHook(hookFunction, state);
24641281cf3SAxel Dörfler 	}
2474ec67d2bSFredrik Holmqvist }
24841281cf3SAxel Dörfler 
24941281cf3SAxel Dörfler 
25041281cf3SAxel Dörfler void
2517da06231SAxel Dörfler TBarMenuBar::InitTrackingHook(bool (*hookFunction)(BMenu*, void*),
2527da06231SAxel Dörfler 	void* state, bool both)
25341281cf3SAxel Dörfler {
25441281cf3SAxel Dörfler 	BPoint loc;
25541281cf3SAxel Dörfler 	uint32 buttons;
25641281cf3SAxel Dörfler 	GetMouse(&loc, &buttons);
25741281cf3SAxel Dörfler 	// set the hook functions for the two menus
258323b6546SOliver Tappe 	// will always have the deskbar menu
25941281cf3SAxel Dörfler 	// may have the app menu as well (mini mode)
260323b6546SOliver Tappe 	if (fDeskbarMenuItem->Frame().Contains(loc) || both)
261323b6546SOliver Tappe 		init_tracking_hook(fDeskbarMenuItem, hookFunction, state);
26241281cf3SAxel Dörfler 
26341281cf3SAxel Dörfler 	if (fAppListMenuItem && (fAppListMenuItem->Frame().Contains(loc) || both))
2647da06231SAxel Dörfler 		init_tracking_hook(fAppListMenuItem, hookFunction, state);
26541281cf3SAxel Dörfler }
266