xref: /haiku/src/apps/deskbar/TeamMenuItem.cpp (revision 859c378175de9013dda77d57199efc4c962215e0)
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 
291687edd0SFredrik Holmqvist Tracker(TM), Be(R), BeOS(R), and BeIA(TM) are trademarks or registered
301687edd0SFredrik Holmqvist trademarks of Be Incorporated in the United States and other countries. Other
311687edd0SFredrik Holmqvist brand product names are registered trademarks or trademarks of their respective
321687edd0SFredrik Holmqvist holders.
3341281cf3SAxel Dörfler All rights reserved.
3441281cf3SAxel Dörfler */
3541281cf3SAxel Dörfler 
36136d40a8SStefano Ceccherini 
37cb6afcb1SStephan Aßmus #include "TeamMenuItem.h"
38cb6afcb1SStephan Aßmus 
3941281cf3SAxel Dörfler #include <string.h>
4041281cf3SAxel Dörfler #include <stdio.h>
41136d40a8SStefano Ceccherini #include <stdlib.h>
42136d40a8SStefano Ceccherini 
4341281cf3SAxel Dörfler #include <Bitmap.h>
44cb6afcb1SStephan Aßmus #include <ControlLook.h>
451cd61330SJohn Scipione #include <Debug.h>
4641281cf3SAxel Dörfler #include <Font.h>
4741281cf3SAxel Dörfler #include <Region.h>
4841281cf3SAxel Dörfler #include <Roster.h>
4941281cf3SAxel Dörfler #include <Resources.h>
5041281cf3SAxel Dörfler 
5141281cf3SAxel Dörfler #include "BarApp.h"
5241281cf3SAxel Dörfler #include "BarMenuBar.h"
5341281cf3SAxel Dörfler #include "ExpandoMenuBar.h"
5441281cf3SAxel Dörfler #include "ResourceSet.h"
5541281cf3SAxel Dörfler #include "ShowHideMenuItem.h"
5641281cf3SAxel Dörfler #include "TeamMenu.h"
5741281cf3SAxel Dörfler #include "WindowMenu.h"
5841281cf3SAxel Dörfler #include "WindowMenuItem.h"
5941281cf3SAxel Dörfler 
6041281cf3SAxel Dörfler 
6141281cf3SAxel Dörfler const float kHPad = 8.0f;
6241281cf3SAxel Dörfler const float kVPad = 1.0f;
6341281cf3SAxel Dörfler const float kLabelOffset = 8.0f;
6441281cf3SAxel Dörfler const float kSwitchWidth = 12;
6541281cf3SAxel Dörfler 
6641281cf3SAxel Dörfler 
6741281cf3SAxel Dörfler TTeamMenuItem::TTeamMenuItem(BList* team, BBitmap* icon, char* name, char* sig,
6841281cf3SAxel Dörfler 	float width, float height, bool drawLabel, bool vertical)
6941281cf3SAxel Dörfler 	:	BMenuItem(new TWindowMenu(team, sig))
7041281cf3SAxel Dörfler {
7141281cf3SAxel Dörfler 	InitData(team, icon, name, sig, width, height, drawLabel, vertical);
7241281cf3SAxel Dörfler }
7341281cf3SAxel Dörfler 
7441281cf3SAxel Dörfler 
7541281cf3SAxel Dörfler TTeamMenuItem::TTeamMenuItem(float width, float height, bool vertical)
7641281cf3SAxel Dörfler 	:	BMenuItem("", NULL)
7741281cf3SAxel Dörfler {
781687edd0SFredrik Holmqvist 	InitData(NULL, NULL, strdup(""), strdup(""), width, height, false,
791687edd0SFredrik Holmqvist 		vertical);
8041281cf3SAxel Dörfler }
8141281cf3SAxel Dörfler 
8241281cf3SAxel Dörfler 
8341281cf3SAxel Dörfler void
8441281cf3SAxel Dörfler TTeamMenuItem::InitData(BList* team, BBitmap* icon, char* name, char* sig,
8541281cf3SAxel Dörfler 	float width, float height, bool drawLabel, bool vertical)
8641281cf3SAxel Dörfler {
8741281cf3SAxel Dörfler 	fTeam = team;
8841281cf3SAxel Dörfler 	fIcon = icon;
8941281cf3SAxel Dörfler 	fName = name;
9041281cf3SAxel Dörfler 	fSig = sig;
9141281cf3SAxel Dörfler 	if (fName == NULL) {
92136d40a8SStefano Ceccherini 		char temp[32];
93e9632898SAlex Smith 		snprintf(temp, sizeof(temp), "team %ld", (addr_t)team->ItemAt(0));
94136d40a8SStefano Ceccherini 		fName = strdup(temp);
9541281cf3SAxel Dörfler 	}
9641281cf3SAxel Dörfler 
97136d40a8SStefano Ceccherini 	SetLabel(fName);
98136d40a8SStefano Ceccherini 
9941281cf3SAxel Dörfler 	BFont font(be_plain_font);
10041281cf3SAxel Dörfler 	fLabelWidth = ceilf(font.StringWidth(fName));
10141281cf3SAxel Dörfler 	font_height fontHeight;
10241281cf3SAxel Dörfler 	font.GetHeight(&fontHeight);
10341281cf3SAxel Dörfler 	fLabelAscent = ceilf(fontHeight.ascent);
10441281cf3SAxel Dörfler 	fLabelDescent = ceilf(fontHeight.descent + fontHeight.leading);
10541281cf3SAxel Dörfler 
10641281cf3SAxel Dörfler 	fOverrideWidth = width;
10741281cf3SAxel Dörfler 	fOverrideHeight = height;
108249a4a18SStephan Aßmus 	fOverriddenSelected = false;
10941281cf3SAxel Dörfler 
11041281cf3SAxel Dörfler 	fVertical = vertical;
1112ce9bab8SJohn Scipione 	fDrawLabel = drawLabel;
11241281cf3SAxel Dörfler 
11341281cf3SAxel Dörfler 	fExpanded = false;
11441281cf3SAxel Dörfler }
11541281cf3SAxel Dörfler 
11641281cf3SAxel Dörfler 
11741281cf3SAxel Dörfler TTeamMenuItem::~TTeamMenuItem()
11841281cf3SAxel Dörfler {
11941281cf3SAxel Dörfler 	delete fTeam;
12041281cf3SAxel Dörfler 	delete fIcon;
12141281cf3SAxel Dörfler 	free(fName);
12241281cf3SAxel Dörfler 	free(fSig);
12341281cf3SAxel Dörfler }
12441281cf3SAxel Dörfler 
12541281cf3SAxel Dörfler 
12641281cf3SAxel Dörfler status_t
12741281cf3SAxel Dörfler TTeamMenuItem::Invoke(BMessage* message)
12841281cf3SAxel Dörfler {
12941281cf3SAxel Dörfler 	if ((static_cast<TBarApp*>(be_app))->BarView()->InvokeItem(Signature()))
13041281cf3SAxel Dörfler 		// handles drop on application
13141281cf3SAxel Dörfler 		return B_OK;
13241281cf3SAxel Dörfler 
13341281cf3SAxel Dörfler 	// if the app could not handle the drag message
13441281cf3SAxel Dörfler 	// and we were dragging, then kill the drag
13541281cf3SAxel Dörfler 	// should never get here, disabled item will not invoke
1362ce9bab8SJohn Scipione 	TBarView* barView = (static_cast<TBarApp*>(be_app))->BarView();
1372ce9bab8SJohn Scipione 	if (barView && barView->Dragging())
1382ce9bab8SJohn Scipione 		barView->DragStop();
13941281cf3SAxel Dörfler 
14041281cf3SAxel Dörfler 	// bring to front or minimize shortcuts
14141281cf3SAxel Dörfler 	uint32 mods = modifiers();
1421687edd0SFredrik Holmqvist 	if (mods & B_CONTROL_KEY) {
14341281cf3SAxel Dörfler 		TShowHideMenuItem::TeamShowHideCommon((mods & B_SHIFT_KEY)
14441281cf3SAxel Dörfler 			? B_MINIMIZE_WINDOW : B_BRING_TO_FRONT, Teams());
1451687edd0SFredrik Holmqvist 	}
14641281cf3SAxel Dörfler 
14741281cf3SAxel Dörfler 	return BMenuItem::Invoke(message);
14841281cf3SAxel Dörfler }
14941281cf3SAxel Dörfler 
15041281cf3SAxel Dörfler 
15141281cf3SAxel Dörfler void
15241281cf3SAxel Dörfler TTeamMenuItem::SetOverrideWidth(float width)
15341281cf3SAxel Dörfler {
15441281cf3SAxel Dörfler 	fOverrideWidth = width;
15541281cf3SAxel Dörfler }
15641281cf3SAxel Dörfler 
15741281cf3SAxel Dörfler 
15841281cf3SAxel Dörfler void
15941281cf3SAxel Dörfler TTeamMenuItem::SetOverrideHeight(float height)
16041281cf3SAxel Dörfler {
16141281cf3SAxel Dörfler 	fOverrideHeight = height;
16241281cf3SAxel Dörfler }
16341281cf3SAxel Dörfler 
16441281cf3SAxel Dörfler 
165249a4a18SStephan Aßmus void
166249a4a18SStephan Aßmus TTeamMenuItem::SetOverrideSelected(bool selected)
167249a4a18SStephan Aßmus {
168249a4a18SStephan Aßmus 	fOverriddenSelected = selected;
169249a4a18SStephan Aßmus 	Highlight(selected);
170249a4a18SStephan Aßmus }
171249a4a18SStephan Aßmus 
172249a4a18SStephan Aßmus 
1731f0c9f18SJohn Scipione bool
174dc05c262SJohn Scipione TTeamMenuItem::HasLabel() const
1751f0c9f18SJohn Scipione {
1761f0c9f18SJohn Scipione 	return fDrawLabel;
1771f0c9f18SJohn Scipione }
1781f0c9f18SJohn Scipione 
1791f0c9f18SJohn Scipione 
1802ce9bab8SJohn Scipione void
181dc05c262SJohn Scipione TTeamMenuItem::SetHasLabel(bool drawLabel)
1822ce9bab8SJohn Scipione {
1832ce9bab8SJohn Scipione 	fDrawLabel = drawLabel;
1842ce9bab8SJohn Scipione }
1852ce9bab8SJohn Scipione 
1862ce9bab8SJohn Scipione 
18741281cf3SAxel Dörfler float
18841281cf3SAxel Dörfler TTeamMenuItem::LabelWidth() const
18941281cf3SAxel Dörfler {
19041281cf3SAxel Dörfler 	return fLabelWidth;
19141281cf3SAxel Dörfler }
19241281cf3SAxel Dörfler 
19341281cf3SAxel Dörfler 
19441281cf3SAxel Dörfler BList*
19541281cf3SAxel Dörfler TTeamMenuItem::Teams() const
19641281cf3SAxel Dörfler {
19741281cf3SAxel Dörfler 	return fTeam;
19841281cf3SAxel Dörfler }
19941281cf3SAxel Dörfler 
20041281cf3SAxel Dörfler 
20141281cf3SAxel Dörfler const char*
20241281cf3SAxel Dörfler TTeamMenuItem::Signature() const
20341281cf3SAxel Dörfler {
20441281cf3SAxel Dörfler 	return fSig;
20541281cf3SAxel Dörfler }
20641281cf3SAxel Dörfler 
20741281cf3SAxel Dörfler 
20841281cf3SAxel Dörfler const char*
20941281cf3SAxel Dörfler TTeamMenuItem::Name() const
21041281cf3SAxel Dörfler {
21141281cf3SAxel Dörfler 	return fName;
21241281cf3SAxel Dörfler }
21341281cf3SAxel Dörfler 
21441281cf3SAxel Dörfler 
21541281cf3SAxel Dörfler void
21641281cf3SAxel Dörfler TTeamMenuItem::GetContentSize(float* width, float* height)
21741281cf3SAxel Dörfler {
21841281cf3SAxel Dörfler 	BRect iconBounds;
21941281cf3SAxel Dörfler 
22041281cf3SAxel Dörfler 	if (fIcon)
22141281cf3SAxel Dörfler 		iconBounds = fIcon->Bounds();
22241281cf3SAxel Dörfler 	else
2232ce9bab8SJohn Scipione 		iconBounds = BRect(0, 0, kMinimumIconSize - 1, kMinimumIconSize - 1);
22441281cf3SAxel Dörfler 
22541281cf3SAxel Dörfler 	BMenuItem::GetContentSize(width, height);
22641281cf3SAxel Dörfler 
22741281cf3SAxel Dörfler 	if (fOverrideWidth != -1.0f)
22841281cf3SAxel Dörfler 		*width = fOverrideWidth;
2292ce9bab8SJohn Scipione 	else {
2302ce9bab8SJohn Scipione 		*width = kHPad + iconBounds.Width() + kHPad;
2312ce9bab8SJohn Scipione 		if (iconBounds.Width() <= 32 && fDrawLabel)
2322ce9bab8SJohn Scipione 			*width += LabelWidth() + kHPad;
2332ce9bab8SJohn Scipione 	}
23441281cf3SAxel Dörfler 
23541281cf3SAxel Dörfler 	if (fOverrideHeight != -1.0f)
23641281cf3SAxel Dörfler 		*height = fOverrideHeight;
23741281cf3SAxel Dörfler 	else {
2382ce9bab8SJohn Scipione 		if (fVertical) {
2392ce9bab8SJohn Scipione 			*height = iconBounds.Height() + kVPad * 4;
2402ce9bab8SJohn Scipione 			if (fDrawLabel && iconBounds.Width() > 32)
2412ce9bab8SJohn Scipione 				*height += fLabelAscent + fLabelDescent;
2422ce9bab8SJohn Scipione 		} else {
243c07e6ff2SJohn Scipione 			*height = iconBounds.Height() + kVPad * 4;
2442ce9bab8SJohn Scipione 		}
24541281cf3SAxel Dörfler 	}
24641281cf3SAxel Dörfler 	*height += 2;
24741281cf3SAxel Dörfler }
24841281cf3SAxel Dörfler 
24941281cf3SAxel Dörfler 
25041281cf3SAxel Dörfler void
25141281cf3SAxel Dörfler TTeamMenuItem::Draw()
25241281cf3SAxel Dörfler {
25341281cf3SAxel Dörfler 	BRect frame(Frame());
25441281cf3SAxel Dörfler 	BMenu* menu = Menu();
25541281cf3SAxel Dörfler 	menu->PushState();
256cb6afcb1SStephan Aßmus 	rgb_color menuColor = menu->LowColor();
2572ce9bab8SJohn Scipione 	TBarView* barView = (static_cast<TBarApp*>(be_app))->BarView();
2581687edd0SFredrik Holmqvist 
2592ce9bab8SJohn Scipione 	bool canHandle = !barView->Dragging()
2602ce9bab8SJohn Scipione 		|| barView->AppCanHandleTypes(Signature());
261cb6afcb1SStephan Aßmus 
262cb6afcb1SStephan Aßmus 	if (be_control_look != NULL) {
263cb6afcb1SStephan Aßmus 		uint32 flags = 0;
264cb6afcb1SStephan Aßmus 		if (_IsSelected() && canHandle)
265cb6afcb1SStephan Aßmus 			flags |= BControlLook::B_ACTIVATED;
266cb6afcb1SStephan Aßmus 
267cb6afcb1SStephan Aßmus 		uint32 borders = BControlLook::B_TOP_BORDER;
268cb6afcb1SStephan Aßmus 		if (fVertical) {
269cb6afcb1SStephan Aßmus 			menu->SetHighColor(tint_color(menuColor, B_DARKEN_1_TINT));
270cb6afcb1SStephan Aßmus 			borders |= BControlLook::B_LEFT_BORDER
271cb6afcb1SStephan Aßmus 				| BControlLook::B_RIGHT_BORDER;
272cb6afcb1SStephan Aßmus 			menu->StrokeLine(frame.LeftBottom(), frame.RightBottom());
273cb6afcb1SStephan Aßmus 			frame.bottom--;
274cb6afcb1SStephan Aßmus 
275cb6afcb1SStephan Aßmus 			be_control_look->DrawMenuBarBackground(menu, frame, frame,
276cb6afcb1SStephan Aßmus 				menuColor, flags, borders);
277cb6afcb1SStephan Aßmus 		} else {
278cb6afcb1SStephan Aßmus 			if (flags & BControlLook::B_ACTIVATED)
279cb6afcb1SStephan Aßmus 				menu->SetHighColor(tint_color(menuColor, B_DARKEN_3_TINT));
280cb6afcb1SStephan Aßmus 			else
281cb6afcb1SStephan Aßmus 				menu->SetHighColor(tint_color(menuColor, 1.22));
282cb6afcb1SStephan Aßmus 			borders |= BControlLook::B_BOTTOM_BORDER;
283cb6afcb1SStephan Aßmus 			menu->StrokeLine(frame.LeftTop(), frame.LeftBottom());
284cb6afcb1SStephan Aßmus 			frame.left++;
285cb6afcb1SStephan Aßmus 
286cb6afcb1SStephan Aßmus 			be_control_look->DrawButtonBackground(menu, frame, frame,
287cb6afcb1SStephan Aßmus 				menuColor, flags, borders);
288cb6afcb1SStephan Aßmus 		}
289cb6afcb1SStephan Aßmus 
290cb6afcb1SStephan Aßmus 		menu->MovePenTo(ContentLocation());
291cb6afcb1SStephan Aßmus 		DrawContent();
292cb6afcb1SStephan Aßmus 		menu->PopState();
293cb6afcb1SStephan Aßmus 		return;
294cb6afcb1SStephan Aßmus 	}
29541281cf3SAxel Dörfler 
29641281cf3SAxel Dörfler 	// if not selected or being tracked on, fill with gray
297eddec292SOliver Tappe 	if ((!_IsSelected() && !menu->IsRedrawAfterSticky()) || !canHandle
298cb6afcb1SStephan Aßmus 		|| !IsEnabled()) {
29941281cf3SAxel Dörfler 		frame.InsetBy(1, 1);
30041281cf3SAxel Dörfler 		menu->SetHighColor(menuColor);
30141281cf3SAxel Dörfler 		menu->FillRect(frame);
30241281cf3SAxel Dörfler 	}
30341281cf3SAxel Dörfler 
30441281cf3SAxel Dörfler 	// draw the gray, unselected item, border
305249a4a18SStephan Aßmus 	if (!_IsSelected() || !IsEnabled()) {
30641281cf3SAxel Dörfler 		rgb_color shadow = tint_color(menuColor, B_DARKEN_1_TINT);
30741281cf3SAxel Dörfler 		rgb_color light = tint_color(menuColor, B_LIGHTEN_2_TINT);
30841281cf3SAxel Dörfler 
30941281cf3SAxel Dörfler 		frame = Frame();
31041281cf3SAxel Dörfler 
31141281cf3SAxel Dörfler 		menu->SetHighColor(shadow);
31241281cf3SAxel Dörfler 		if (fVertical)
31341281cf3SAxel Dörfler 			menu->StrokeLine(frame.LeftBottom(), frame.RightBottom());
31441281cf3SAxel Dörfler 		else
31571bd3ba5SJonas Sundström 			menu->StrokeLine(frame.LeftBottom() + BPoint(1, 0),
31671bd3ba5SJonas Sundström 				frame.RightBottom());
31741281cf3SAxel Dörfler 
31841281cf3SAxel Dörfler 		menu->StrokeLine(frame.RightBottom(), frame.RightTop());
31941281cf3SAxel Dörfler 
32041281cf3SAxel Dörfler 		menu->SetHighColor(light);
32141281cf3SAxel Dörfler 		menu->StrokeLine(frame.RightTop() + BPoint(-1, 0), frame.LeftTop());
32241281cf3SAxel Dörfler 		if (fVertical)
32371bd3ba5SJonas Sundström 			menu->StrokeLine(frame.LeftTop(), frame.LeftBottom()
32471bd3ba5SJonas Sundström 				+ BPoint(0, -1));
32541281cf3SAxel Dörfler 		else
32641281cf3SAxel Dörfler 			menu->StrokeLine(frame.LeftTop(), frame.LeftBottom());
32741281cf3SAxel Dörfler 	}
32841281cf3SAxel Dörfler 
32941281cf3SAxel Dörfler 	// if selected or being tracked on, fill with the hilite gray color
33071bd3ba5SJonas Sundström 	if (IsEnabled() && _IsSelected() && !menu->IsRedrawAfterSticky()
33171bd3ba5SJonas Sundström 		&& canHandle) {
33241281cf3SAxel Dörfler 		// fill
33341281cf3SAxel Dörfler 		menu->SetHighColor(tint_color(menuColor, B_HIGHLIGHT_BACKGROUND_TINT));
33441281cf3SAxel Dörfler 		menu->FillRect(frame);
33541281cf3SAxel Dörfler 
33641281cf3SAxel Dörfler 		// these continue the dark grey border on the left or top edge
33741281cf3SAxel Dörfler 		menu->SetHighColor(tint_color(menuColor, B_DARKEN_4_TINT));
3381687edd0SFredrik Holmqvist 		if (fVertical) {
33941281cf3SAxel Dörfler 			// dark line at top
34041281cf3SAxel Dörfler 			menu->StrokeLine(frame.LeftTop(), frame.RightTop());
3411687edd0SFredrik Holmqvist 		} else {
34241281cf3SAxel Dörfler 			// dark line on the left
34341281cf3SAxel Dörfler 			menu->StrokeLine(frame.LeftTop(), frame.LeftBottom());
3441687edd0SFredrik Holmqvist 		}
34541281cf3SAxel Dörfler 	} else
34641281cf3SAxel Dörfler 		menu->SetLowColor(menuColor);
34741281cf3SAxel Dörfler 
34841281cf3SAxel Dörfler 	menu->MovePenTo(ContentLocation());
34941281cf3SAxel Dörfler 	DrawContent();
35041281cf3SAxel Dörfler 	menu->PopState();
35141281cf3SAxel Dörfler }
35241281cf3SAxel Dörfler 
35341281cf3SAxel Dörfler 
35441281cf3SAxel Dörfler void
35541281cf3SAxel Dörfler TTeamMenuItem::DrawContent()
35641281cf3SAxel Dörfler {
35741281cf3SAxel Dörfler 	BMenu* menu = Menu();
3582ce9bab8SJohn Scipione 	if (fIcon != NULL) {
35959deaf10SStephan Aßmus 		if (fIcon->ColorSpace() == B_RGBA32) {
36059deaf10SStephan Aßmus 			menu->SetDrawingMode(B_OP_ALPHA);
36159deaf10SStephan Aßmus 			menu->SetBlendingMode(B_PIXEL_ALPHA, B_ALPHA_OVERLAY);
3621687edd0SFredrik Holmqvist 		} else
36341281cf3SAxel Dörfler 			menu->SetDrawingMode(B_OP_OVER);
36441281cf3SAxel Dörfler 
3651687edd0SFredrik Holmqvist 		BRect frame(Frame());
36641281cf3SAxel Dörfler 		BRect iconBounds(fIcon->Bounds());
36741281cf3SAxel Dörfler 		BRect dstRect(iconBounds);
3682ce9bab8SJohn Scipione 		float extra = fVertical ? 0.0f : -1.0f;
36941281cf3SAxel Dörfler 		BPoint contLoc = ContentLocation();
3702ce9bab8SJohn Scipione 		BPoint drawLoc = contLoc + BPoint(kHPad, kVPad);
3711687edd0SFredrik Holmqvist 
3722ce9bab8SJohn Scipione 		if (!fDrawLabel || (fVertical && iconBounds.Width() > 32)) {
3732ce9bab8SJohn Scipione 			float offsetx = contLoc.x
3742ce9bab8SJohn Scipione 				+ ((frame.Width() - iconBounds.Width()) / 2) + extra;
3752ce9bab8SJohn Scipione 			float offsety = contLoc.y + 3.0f + extra;
3762ce9bab8SJohn Scipione 
3772ce9bab8SJohn Scipione 			dstRect.OffsetTo(BPoint(offsetx, offsety));
3782ce9bab8SJohn Scipione 			menu->DrawBitmapAsync(fIcon, dstRect);
3792ce9bab8SJohn Scipione 
3802ce9bab8SJohn Scipione 			drawLoc.x = ((frame.Width() - LabelWidth()) / 2);
3812ce9bab8SJohn Scipione 			drawLoc.y = frame.top + iconBounds.Height() + 4.0f;
3822ce9bab8SJohn Scipione 		} else {
3832ce9bab8SJohn Scipione 			float offsetx = contLoc.x + kHPad;
3842ce9bab8SJohn Scipione 			float offsety = contLoc.y +
3852ce9bab8SJohn Scipione 				((frame.Height() - iconBounds.Height()) / 2) + extra;
3862ce9bab8SJohn Scipione 
3872ce9bab8SJohn Scipione 			dstRect.OffsetTo(BPoint(offsetx, offsety));
38841281cf3SAxel Dörfler 			menu->DrawBitmapAsync(fIcon, dstRect);
38941281cf3SAxel Dörfler 
39041281cf3SAxel Dörfler 			float labelHeight = fLabelAscent + fLabelDescent;
39141281cf3SAxel Dörfler 			drawLoc.x += iconBounds.Width() + kLabelOffset;
3922ce9bab8SJohn Scipione 			drawLoc.y = frame.top + ((frame.Height() - labelHeight) / 2) + extra;
3932ce9bab8SJohn Scipione 		}
3942ce9bab8SJohn Scipione 
39541281cf3SAxel Dörfler 		menu->MovePenTo(drawLoc);
39641281cf3SAxel Dörfler 	}
39741281cf3SAxel Dörfler 
39841281cf3SAxel Dörfler 	if (fDrawLabel) {
399cb6afcb1SStephan Aßmus 		menu->SetDrawingMode(B_OP_OVER);
400e19488b2SRyan Leavengood 		menu->SetHighColor(ui_color(B_MENU_ITEM_TEXT_COLOR));
40141281cf3SAxel Dörfler 
40241281cf3SAxel Dörfler 		// override the drawing of the content when the item is disabled
40341281cf3SAxel Dörfler 		// the wrong lowcolor is used when the item is disabled since the
40441281cf3SAxel Dörfler 		// text color does not change
40541281cf3SAxel Dörfler 		DrawContentLabel();
40641281cf3SAxel Dörfler 	}
40741281cf3SAxel Dörfler 
40841281cf3SAxel Dörfler 	// Draw the expandable icon.
40941281cf3SAxel Dörfler 	TBarView* barView = (static_cast<TBarApp*>(be_app))->BarView();
41041281cf3SAxel Dörfler 	if (fVertical && static_cast<TBarApp*>(be_app)->Settings()->superExpando
411d0a49328SJohn Scipione 		&& barView->ExpandoState()) {
41241281cf3SAxel Dörfler 		BRect frame(Frame());
41341281cf3SAxel Dörfler 		BRect rect(0, 0, kSwitchWidth, 10);
41441281cf3SAxel Dörfler 		rect.OffsetTo(BPoint(frame.right - rect.Width(),
41541281cf3SAxel Dörfler 			ContentLocation().y + ((frame.Height() - rect.Height()) / 2)));
41641281cf3SAxel Dörfler 
417cb6afcb1SStephan Aßmus 		if (be_control_look != NULL) {
418cb6afcb1SStephan Aßmus 			uint32 arrowDirection = fExpanded
419cb6afcb1SStephan Aßmus 				? BControlLook::B_UP_ARROW : BControlLook::B_DOWN_ARROW;
420cb6afcb1SStephan Aßmus 			be_control_look->DrawArrowShape(menu, rect, rect, menu->LowColor(),
421cb6afcb1SStephan Aßmus 				arrowDirection, 0, B_DARKEN_3_TINT);
422cb6afcb1SStephan Aßmus 		} else {
42341281cf3SAxel Dörfler 			rgb_color outlineColor = {80, 80, 80, 255};
42441281cf3SAxel Dörfler 			rgb_color middleColor = {200, 200, 200, 255};
42541281cf3SAxel Dörfler 
4261407220dSStefano Ceccherini 			menu->SetDrawingMode(B_OP_OVER);
42741281cf3SAxel Dörfler 
42841281cf3SAxel Dörfler 			if (!fExpanded) {
42941281cf3SAxel Dörfler 				menu->BeginLineArray(6);
43041281cf3SAxel Dörfler 
43141281cf3SAxel Dörfler 				menu->AddLine(BPoint(rect.left + 3, rect.top + 1),
43241281cf3SAxel Dörfler 					BPoint(rect.left + 3, rect.bottom - 1), outlineColor);
43341281cf3SAxel Dörfler 				menu->AddLine(BPoint(rect.left + 3, rect.top + 1),
43441281cf3SAxel Dörfler 					BPoint(rect.left + 7, rect.top + 5), outlineColor);
43541281cf3SAxel Dörfler 				menu->AddLine(BPoint(rect.left + 7, rect.top + 5),
43641281cf3SAxel Dörfler 					BPoint(rect.left + 3, rect.bottom - 1), outlineColor);
43741281cf3SAxel Dörfler 
43841281cf3SAxel Dörfler 				menu->AddLine(BPoint(rect.left + 4, rect.top + 3),
43941281cf3SAxel Dörfler 					BPoint(rect.left + 4, rect.bottom - 3), middleColor);
44041281cf3SAxel Dörfler 				menu->AddLine(BPoint(rect.left + 5, rect.top + 4),
44141281cf3SAxel Dörfler 					BPoint(rect.left + 5, rect.bottom - 4), middleColor);
44241281cf3SAxel Dörfler 				menu->AddLine(BPoint(rect.left + 5, rect.top + 5),
44341281cf3SAxel Dörfler 					BPoint(rect.left + 6, rect.top + 5), middleColor);
44441281cf3SAxel Dörfler 				menu->EndLineArray();
44541281cf3SAxel Dörfler 			} else {
44641281cf3SAxel Dörfler 				// expanded state
44741281cf3SAxel Dörfler 
44841281cf3SAxel Dörfler 				menu->BeginLineArray(6);
44941281cf3SAxel Dörfler 				menu->AddLine(BPoint(rect.left + 1, rect.top + 3),
45041281cf3SAxel Dörfler 					BPoint(rect.right - 3, rect.top + 3), outlineColor);
45141281cf3SAxel Dörfler 				menu->AddLine(BPoint(rect.left + 1, rect.top + 3),
45241281cf3SAxel Dörfler 					BPoint(rect.left + 5, rect.top + 7), outlineColor);
45341281cf3SAxel Dörfler 				menu->AddLine(BPoint(rect.left + 5, rect.top + 7),
45441281cf3SAxel Dörfler 					BPoint(rect.right - 3, rect.top + 3), outlineColor);
45541281cf3SAxel Dörfler 
45641281cf3SAxel Dörfler 				menu->AddLine(BPoint(rect.left + 3, rect.top + 4),
45741281cf3SAxel Dörfler 					BPoint(rect.right - 5, rect.top + 4), middleColor);
45841281cf3SAxel Dörfler 				menu->AddLine(BPoint(rect.left + 4, rect.top + 5),
45941281cf3SAxel Dörfler 					BPoint(rect.right - 6, rect.top + 5), middleColor);
46041281cf3SAxel Dörfler 				menu->AddLine(BPoint(rect.left + 5, rect.top + 5),
46141281cf3SAxel Dörfler 					BPoint(rect.left + 5, rect.top + 6), middleColor);
46241281cf3SAxel Dörfler 				menu->EndLineArray();
46341281cf3SAxel Dörfler 			}
46441281cf3SAxel Dörfler 		}
46541281cf3SAxel Dörfler 	}
466cb6afcb1SStephan Aßmus }
46741281cf3SAxel Dörfler 
46841281cf3SAxel Dörfler 
46941281cf3SAxel Dörfler void
47041281cf3SAxel Dörfler TTeamMenuItem::DrawContentLabel()
47141281cf3SAxel Dörfler {
47241281cf3SAxel Dörfler 	BMenu* menu = Menu();
47341281cf3SAxel Dörfler 	menu->MovePenBy(0, fLabelAscent);
47441281cf3SAxel Dörfler 
47541281cf3SAxel Dörfler 	float cachedWidth = menu->StringWidth(Label());
47641281cf3SAxel Dörfler 	if (Submenu() && fVertical)
47741281cf3SAxel Dörfler 		cachedWidth += 18;
47841281cf3SAxel Dörfler 
47941281cf3SAxel Dörfler 	const char* label = Label();
48041281cf3SAxel Dörfler 	char* truncLabel = NULL;
48141281cf3SAxel Dörfler 	float max = 0;
4821687edd0SFredrik Holmqvist 
4832ce9bab8SJohn Scipione 	if (fVertical && static_cast<TBarApp*>(be_app)->Settings()->superExpando)
48441281cf3SAxel Dörfler 		max = menu->MaxContentWidth() - kSwitchWidth;
48541281cf3SAxel Dörfler 	else
4862ce9bab8SJohn Scipione 		max = menu->MaxContentWidth() - 4.0f;
48741281cf3SAxel Dörfler 
48841281cf3SAxel Dörfler 	if (max > 0) {
48941281cf3SAxel Dörfler 		BPoint penloc = menu->PenLocation();
49041281cf3SAxel Dörfler 		BRect frame = Frame();
49141281cf3SAxel Dörfler 		float offset = penloc.x - frame.left;
49241281cf3SAxel Dörfler 		if (cachedWidth + offset > max) {
49341281cf3SAxel Dörfler 			truncLabel = (char*)malloc(strlen(label) + 4);
49441281cf3SAxel Dörfler 			if (!truncLabel)
49541281cf3SAxel Dörfler 				return;
49641281cf3SAxel Dörfler 			TruncateLabel(max-offset, truncLabel);
49741281cf3SAxel Dörfler 			label = truncLabel;
49841281cf3SAxel Dörfler 		}
49941281cf3SAxel Dörfler 	}
50041281cf3SAxel Dörfler 
50141281cf3SAxel Dörfler 	if (!label)
50241281cf3SAxel Dörfler 		label = Label();
50341281cf3SAxel Dörfler 
50441281cf3SAxel Dörfler 	TBarView* barview = (static_cast<TBarApp*>(be_app))->BarView();
505eaa9af99SStephan Aßmus 	bool canHandle = !barview->Dragging()
506eaa9af99SStephan Aßmus 		|| barview->AppCanHandleTypes(Signature());
507249a4a18SStephan Aßmus 	if (_IsSelected() && IsEnabled() && canHandle)
508ab4e79c3SRyan Leavengood 		menu->SetLowColor(tint_color(menu->LowColor(),
50941281cf3SAxel Dörfler 			B_HIGHLIGHT_BACKGROUND_TINT));
51041281cf3SAxel Dörfler 	else
511ab4e79c3SRyan Leavengood 		menu->SetLowColor(menu->LowColor());
51241281cf3SAxel Dörfler 
513*859c3781SJohn Scipione 	if (IsSelected())
514*859c3781SJohn Scipione 		menu->SetHighColor(ui_color(B_MENU_SELECTED_ITEM_TEXT_COLOR));
515*859c3781SJohn Scipione 	else
516*859c3781SJohn Scipione 		menu->SetHighColor(ui_color(B_MENU_ITEM_TEXT_COLOR));
517*859c3781SJohn Scipione 
51841281cf3SAxel Dörfler 	menu->DrawString(label);
51941281cf3SAxel Dörfler 
52041281cf3SAxel Dörfler 	free(truncLabel);
52141281cf3SAxel Dörfler }
52241281cf3SAxel Dörfler 
52341281cf3SAxel Dörfler 
52441281cf3SAxel Dörfler bool
52541281cf3SAxel Dörfler TTeamMenuItem::IsExpanded()
52641281cf3SAxel Dörfler {
52741281cf3SAxel Dörfler 	return fExpanded;
52841281cf3SAxel Dörfler }
52941281cf3SAxel Dörfler 
53041281cf3SAxel Dörfler 
53141281cf3SAxel Dörfler void
53241281cf3SAxel Dörfler TTeamMenuItem::ToggleExpandState(bool resizeWindow)
53341281cf3SAxel Dörfler {
53441281cf3SAxel Dörfler 	fExpanded = !fExpanded;
53541281cf3SAxel Dörfler 
53641281cf3SAxel Dörfler 	if (fExpanded) {
53741281cf3SAxel Dörfler 		// Populate Menu() with the stuff from SubMenu().
53841281cf3SAxel Dörfler 		TWindowMenu* sub = (static_cast<TWindowMenu*>(Submenu()));
53941281cf3SAxel Dörfler 		if (sub) {
54041281cf3SAxel Dörfler 			// force the menu to update it's contents.
541bdfed6c0SAxel Dörfler 			bool locked = sub->LockLooper();
542bdfed6c0SAxel Dörfler 				// if locking the looper failed, the menu is just not visible
543bdfed6c0SAxel Dörfler 			sub->AttachedToWindow();
544bdfed6c0SAxel Dörfler 			if (locked)
545bdfed6c0SAxel Dörfler 				sub->UnlockLooper();
546bdfed6c0SAxel Dörfler 
54741281cf3SAxel Dörfler 			if (sub->CountItems() > 1) {
54841281cf3SAxel Dörfler 				TExpandoMenuBar* parent = static_cast<TExpandoMenuBar*>(Menu());
54941281cf3SAxel Dörfler 				int myindex = parent->IndexOf(this) + 1;
55041281cf3SAxel Dörfler 
55141281cf3SAxel Dörfler 				TWindowMenuItem* windowItem = NULL;
55241281cf3SAxel Dörfler 				int childIndex = 0;
55371bd3ba5SJonas Sundström 				int totalChildren = sub->CountItems() - 4;
55471bd3ba5SJonas Sundström 					// hide, show, close, separator.
55541281cf3SAxel Dörfler 				for (; childIndex < totalChildren; childIndex++) {
55671bd3ba5SJonas Sundström 					windowItem = static_cast<TWindowMenuItem*>
55771bd3ba5SJonas Sundström 						(sub->RemoveItem((int32)0));
55841281cf3SAxel Dörfler 					parent->AddItem(windowItem, myindex + childIndex);
55941281cf3SAxel Dörfler 					windowItem->ExpandedItem(true);
56041281cf3SAxel Dörfler 				}
56141281cf3SAxel Dörfler 				sub->SetExpanded(true, myindex + childIndex);
56241281cf3SAxel Dörfler 
56341281cf3SAxel Dörfler 				if (resizeWindow)
564afa1c291SJohn Scipione 					parent->SizeWindow(-1);
565c0107fb2SJonas Sundström 			}
56641281cf3SAxel Dörfler 		}
56741281cf3SAxel Dörfler 	} else {
56841281cf3SAxel Dörfler 		// Remove the goodies from the Menu() that should be in the SubMenu();
56941281cf3SAxel Dörfler 		TWindowMenu* sub = static_cast<TWindowMenu*>(Submenu());
57041281cf3SAxel Dörfler 
57141281cf3SAxel Dörfler 		if (sub) {
57241281cf3SAxel Dörfler 			TExpandoMenuBar* parent = static_cast<TExpandoMenuBar*>(Menu());
57341281cf3SAxel Dörfler 
57441281cf3SAxel Dörfler 			TWindowMenuItem* windowItem = NULL;
57541281cf3SAxel Dörfler 			int childIndex = parent->IndexOf(this) + 1;
57671bd3ba5SJonas Sundström 			while (!parent->SubmenuAt(childIndex) && childIndex
57771bd3ba5SJonas Sundström 				< parent->CountItems()) {
57871bd3ba5SJonas Sundström 				windowItem = static_cast<TWindowMenuItem*>
57971bd3ba5SJonas Sundström 					(parent->RemoveItem(childIndex));
58041281cf3SAxel Dörfler 				sub->AddItem(windowItem, 0);
58141281cf3SAxel Dörfler 				windowItem->ExpandedItem(false);
58241281cf3SAxel Dörfler 			}
58341281cf3SAxel Dörfler 			sub->SetExpanded(false, 0);
58441281cf3SAxel Dörfler 
58541281cf3SAxel Dörfler 			if (resizeWindow)
58649ff476dSJohn Scipione 				parent->SizeWindow(1);
587c0107fb2SJonas Sundström 		}
58841281cf3SAxel Dörfler 	}
58941281cf3SAxel Dörfler }
59041281cf3SAxel Dörfler 
59141281cf3SAxel Dörfler 
59241281cf3SAxel Dörfler TWindowMenuItem*
59341281cf3SAxel Dörfler TTeamMenuItem::ExpandedWindowItem(int32 id)
59441281cf3SAxel Dörfler {
5951687edd0SFredrik Holmqvist 	if (!fExpanded) {
5961687edd0SFredrik Holmqvist 		// Paranoia
59741281cf3SAxel Dörfler 		return NULL;
5981687edd0SFredrik Holmqvist 	}
59941281cf3SAxel Dörfler 
60041281cf3SAxel Dörfler 	TExpandoMenuBar* parent = static_cast<TExpandoMenuBar*>(Menu());
60141281cf3SAxel Dörfler 	int childIndex = parent->IndexOf(this) + 1;
60241281cf3SAxel Dörfler 
60371bd3ba5SJonas Sundström 	while (!parent->SubmenuAt(childIndex)
60471bd3ba5SJonas Sundström 		&& childIndex < parent->CountItems()) {
60571bd3ba5SJonas Sundström 		TWindowMenuItem* item
60671bd3ba5SJonas Sundström 			= static_cast<TWindowMenuItem*>(parent->ItemAt(childIndex));
60741281cf3SAxel Dörfler 		if (item->ID() == id)
60841281cf3SAxel Dörfler 			return item;
60941281cf3SAxel Dörfler 
61041281cf3SAxel Dörfler 		childIndex++;
61141281cf3SAxel Dörfler 	}
61241281cf3SAxel Dörfler 	return NULL;
61341281cf3SAxel Dörfler }
61441281cf3SAxel Dörfler 
61541281cf3SAxel Dörfler 
61641281cf3SAxel Dörfler BRect
61741281cf3SAxel Dörfler TTeamMenuItem::ExpanderBounds() const
61841281cf3SAxel Dörfler {
61941281cf3SAxel Dörfler 	BRect bounds(Frame());
62041281cf3SAxel Dörfler 	bounds.left = bounds.right - kSwitchWidth;
62141281cf3SAxel Dörfler 	return bounds;
62241281cf3SAxel Dörfler }
62341281cf3SAxel Dörfler 
624249a4a18SStephan Aßmus 
625249a4a18SStephan Aßmus bool
626249a4a18SStephan Aßmus TTeamMenuItem::_IsSelected() const
627249a4a18SStephan Aßmus {
628249a4a18SStephan Aßmus 	return IsSelected() || fOverriddenSelected;
629249a4a18SStephan Aßmus }
630