xref: /haiku/src/apps/deskbar/TeamMenuItem.cpp (revision 1f0c9f183e3bd12f6056ca2251438ffada696d58)
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 
3641281cf3SAxel Dörfler #include <Debug.h>
37136d40a8SStefano Ceccherini 
38cb6afcb1SStephan Aßmus #include "TeamMenuItem.h"
39cb6afcb1SStephan Aßmus 
4041281cf3SAxel Dörfler #include <string.h>
4141281cf3SAxel Dörfler #include <stdio.h>
42136d40a8SStefano Ceccherini #include <stdlib.h>
43136d40a8SStefano Ceccherini 
4441281cf3SAxel Dörfler #include <Bitmap.h>
45cb6afcb1SStephan Aßmus #include <ControlLook.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];
93136d40a8SStefano Ceccherini 		snprintf(temp, sizeof(temp), "team %ld", (int32)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 
173*1f0c9f18SJohn Scipione bool
174*1f0c9f18SJohn Scipione TTeamMenuItem::DrawLabel() const
175*1f0c9f18SJohn Scipione {
176*1f0c9f18SJohn Scipione 	return fDrawLabel;
177*1f0c9f18SJohn Scipione }
178*1f0c9f18SJohn Scipione 
179*1f0c9f18SJohn Scipione 
1802ce9bab8SJohn Scipione void
1812ce9bab8SJohn Scipione TTeamMenuItem::SetDrawLabel(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 {
2432ce9bab8SJohn Scipione 			*height = iconBounds.Height() - kVPad * 8;
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 	// set the pen to black so that either method will draw in the same color
399cb6afcb1SStephan Aßmus 	// low color is set in inherited::DrawContent, override makes sure its
400cb6afcb1SStephan Aßmus 	// what we want
40141281cf3SAxel Dörfler 	if (fDrawLabel) {
402cb6afcb1SStephan Aßmus 		menu->SetDrawingMode(B_OP_OVER);
40341281cf3SAxel Dörfler 		menu->SetHighColor(0, 0, 0);
40441281cf3SAxel Dörfler 
40541281cf3SAxel Dörfler 		// override the drawing of the content when the item is disabled
40641281cf3SAxel Dörfler 		// the wrong lowcolor is used when the item is disabled since the
40741281cf3SAxel Dörfler 		// text color does not change
40841281cf3SAxel Dörfler 		DrawContentLabel();
40941281cf3SAxel Dörfler 	}
41041281cf3SAxel Dörfler 
41141281cf3SAxel Dörfler 	// Draw the expandable icon.
41241281cf3SAxel Dörfler 	TBarView* barView = (static_cast<TBarApp*>(be_app))->BarView();
41341281cf3SAxel Dörfler 	if (fVertical && static_cast<TBarApp*>(be_app)->Settings()->superExpando
414d0a49328SJohn Scipione 		&& barView->ExpandoState()) {
41541281cf3SAxel Dörfler 		BRect frame(Frame());
41641281cf3SAxel Dörfler 		BRect rect(0, 0, kSwitchWidth, 10);
41741281cf3SAxel Dörfler 		rect.OffsetTo(BPoint(frame.right - rect.Width(),
41841281cf3SAxel Dörfler 			ContentLocation().y + ((frame.Height() - rect.Height()) / 2)));
41941281cf3SAxel Dörfler 
420cb6afcb1SStephan Aßmus 		if (be_control_look != NULL) {
421cb6afcb1SStephan Aßmus 			uint32 arrowDirection = fExpanded
422cb6afcb1SStephan Aßmus 				? BControlLook::B_UP_ARROW : BControlLook::B_DOWN_ARROW;
423cb6afcb1SStephan Aßmus 			be_control_look->DrawArrowShape(menu, rect, rect, menu->LowColor(),
424cb6afcb1SStephan Aßmus 				arrowDirection, 0, B_DARKEN_3_TINT);
425cb6afcb1SStephan Aßmus 		} else {
42641281cf3SAxel Dörfler 			rgb_color outlineColor = {80, 80, 80, 255};
42741281cf3SAxel Dörfler 			rgb_color middleColor = {200, 200, 200, 255};
42841281cf3SAxel Dörfler 
4291407220dSStefano Ceccherini 			menu->SetDrawingMode(B_OP_OVER);
43041281cf3SAxel Dörfler 
43141281cf3SAxel Dörfler 			if (!fExpanded) {
43241281cf3SAxel Dörfler 				menu->BeginLineArray(6);
43341281cf3SAxel Dörfler 
43441281cf3SAxel Dörfler 				menu->AddLine(BPoint(rect.left + 3, rect.top + 1),
43541281cf3SAxel Dörfler 					BPoint(rect.left + 3, rect.bottom - 1), outlineColor);
43641281cf3SAxel Dörfler 				menu->AddLine(BPoint(rect.left + 3, rect.top + 1),
43741281cf3SAxel Dörfler 					BPoint(rect.left + 7, rect.top + 5), outlineColor);
43841281cf3SAxel Dörfler 				menu->AddLine(BPoint(rect.left + 7, rect.top + 5),
43941281cf3SAxel Dörfler 					BPoint(rect.left + 3, rect.bottom - 1), outlineColor);
44041281cf3SAxel Dörfler 
44141281cf3SAxel Dörfler 				menu->AddLine(BPoint(rect.left + 4, rect.top + 3),
44241281cf3SAxel Dörfler 					BPoint(rect.left + 4, rect.bottom - 3), middleColor);
44341281cf3SAxel Dörfler 				menu->AddLine(BPoint(rect.left + 5, rect.top + 4),
44441281cf3SAxel Dörfler 					BPoint(rect.left + 5, rect.bottom - 4), middleColor);
44541281cf3SAxel Dörfler 				menu->AddLine(BPoint(rect.left + 5, rect.top + 5),
44641281cf3SAxel Dörfler 					BPoint(rect.left + 6, rect.top + 5), middleColor);
44741281cf3SAxel Dörfler 				menu->EndLineArray();
44841281cf3SAxel Dörfler 			} else {
44941281cf3SAxel Dörfler 				// expanded state
45041281cf3SAxel Dörfler 
45141281cf3SAxel Dörfler 				menu->BeginLineArray(6);
45241281cf3SAxel Dörfler 				menu->AddLine(BPoint(rect.left + 1, rect.top + 3),
45341281cf3SAxel Dörfler 					BPoint(rect.right - 3, rect.top + 3), outlineColor);
45441281cf3SAxel Dörfler 				menu->AddLine(BPoint(rect.left + 1, rect.top + 3),
45541281cf3SAxel Dörfler 					BPoint(rect.left + 5, rect.top + 7), outlineColor);
45641281cf3SAxel Dörfler 				menu->AddLine(BPoint(rect.left + 5, rect.top + 7),
45741281cf3SAxel Dörfler 					BPoint(rect.right - 3, rect.top + 3), outlineColor);
45841281cf3SAxel Dörfler 
45941281cf3SAxel Dörfler 				menu->AddLine(BPoint(rect.left + 3, rect.top + 4),
46041281cf3SAxel Dörfler 					BPoint(rect.right - 5, rect.top + 4), middleColor);
46141281cf3SAxel Dörfler 				menu->AddLine(BPoint(rect.left + 4, rect.top + 5),
46241281cf3SAxel Dörfler 					BPoint(rect.right - 6, rect.top + 5), middleColor);
46341281cf3SAxel Dörfler 				menu->AddLine(BPoint(rect.left + 5, rect.top + 5),
46441281cf3SAxel Dörfler 					BPoint(rect.left + 5, rect.top + 6), middleColor);
46541281cf3SAxel Dörfler 				menu->EndLineArray();
46641281cf3SAxel Dörfler 			}
46741281cf3SAxel Dörfler 		}
46841281cf3SAxel Dörfler 	}
469cb6afcb1SStephan Aßmus }
47041281cf3SAxel Dörfler 
47141281cf3SAxel Dörfler 
47241281cf3SAxel Dörfler void
47341281cf3SAxel Dörfler TTeamMenuItem::DrawContentLabel()
47441281cf3SAxel Dörfler {
47541281cf3SAxel Dörfler 	BMenu* menu = Menu();
47641281cf3SAxel Dörfler 	menu->MovePenBy(0, fLabelAscent);
47741281cf3SAxel Dörfler 
47841281cf3SAxel Dörfler 	float cachedWidth = menu->StringWidth(Label());
47941281cf3SAxel Dörfler 	if (Submenu() && fVertical)
48041281cf3SAxel Dörfler 		cachedWidth += 18;
48141281cf3SAxel Dörfler 
48241281cf3SAxel Dörfler 	const char* label = Label();
48341281cf3SAxel Dörfler 	char* truncLabel = NULL;
48441281cf3SAxel Dörfler 	float max = 0;
4851687edd0SFredrik Holmqvist 
4862ce9bab8SJohn Scipione 	if (fVertical && static_cast<TBarApp*>(be_app)->Settings()->superExpando)
48741281cf3SAxel Dörfler 		max = menu->MaxContentWidth() - kSwitchWidth;
48841281cf3SAxel Dörfler 	else
4892ce9bab8SJohn Scipione 		max = menu->MaxContentWidth() - 4.0f;
49041281cf3SAxel Dörfler 
49141281cf3SAxel Dörfler 	if (max > 0) {
49241281cf3SAxel Dörfler 		BPoint penloc = menu->PenLocation();
49341281cf3SAxel Dörfler 		BRect frame = Frame();
49441281cf3SAxel Dörfler 		float offset = penloc.x - frame.left;
49541281cf3SAxel Dörfler 		if (cachedWidth + offset > max) {
49641281cf3SAxel Dörfler 			truncLabel = (char*)malloc(strlen(label) + 4);
49741281cf3SAxel Dörfler 			if (!truncLabel)
49841281cf3SAxel Dörfler 				return;
49941281cf3SAxel Dörfler 			TruncateLabel(max-offset, truncLabel);
50041281cf3SAxel Dörfler 			label = truncLabel;
50141281cf3SAxel Dörfler 		}
50241281cf3SAxel Dörfler 	}
50341281cf3SAxel Dörfler 
50441281cf3SAxel Dörfler 	if (!label)
50541281cf3SAxel Dörfler 		label = Label();
50641281cf3SAxel Dörfler 
50741281cf3SAxel Dörfler 	TBarView* barview = (static_cast<TBarApp*>(be_app))->BarView();
508eaa9af99SStephan Aßmus 	bool canHandle = !barview->Dragging()
509eaa9af99SStephan Aßmus 		|| barview->AppCanHandleTypes(Signature());
510249a4a18SStephan Aßmus 	if (_IsSelected() && IsEnabled() && canHandle)
511eaa9af99SStephan Aßmus 		menu->SetLowColor(tint_color(menu->ViewColor(),
51241281cf3SAxel Dörfler 			B_HIGHLIGHT_BACKGROUND_TINT));
51341281cf3SAxel Dörfler 	else
51441281cf3SAxel Dörfler 		menu->SetLowColor(menu->ViewColor());
51541281cf3SAxel Dörfler 
51641281cf3SAxel Dörfler 	menu->DrawString(label);
51741281cf3SAxel Dörfler 
51841281cf3SAxel Dörfler 	free(truncLabel);
51941281cf3SAxel Dörfler }
52041281cf3SAxel Dörfler 
52141281cf3SAxel Dörfler 
52241281cf3SAxel Dörfler bool
52341281cf3SAxel Dörfler TTeamMenuItem::IsExpanded()
52441281cf3SAxel Dörfler {
52541281cf3SAxel Dörfler 	return fExpanded;
52641281cf3SAxel Dörfler }
52741281cf3SAxel Dörfler 
52841281cf3SAxel Dörfler 
52941281cf3SAxel Dörfler void
53041281cf3SAxel Dörfler TTeamMenuItem::ToggleExpandState(bool resizeWindow)
53141281cf3SAxel Dörfler {
53241281cf3SAxel Dörfler 	fExpanded = !fExpanded;
53341281cf3SAxel Dörfler 
53441281cf3SAxel Dörfler 	if (fExpanded) {
53541281cf3SAxel Dörfler 		// Populate Menu() with the stuff from SubMenu().
53641281cf3SAxel Dörfler 		TWindowMenu* sub = (static_cast<TWindowMenu*>(Submenu()));
53741281cf3SAxel Dörfler 		if (sub) {
53841281cf3SAxel Dörfler 			// force the menu to update it's contents.
539bdfed6c0SAxel Dörfler 			bool locked = sub->LockLooper();
540bdfed6c0SAxel Dörfler 				// if locking the looper failed, the menu is just not visible
541bdfed6c0SAxel Dörfler 			sub->AttachedToWindow();
542bdfed6c0SAxel Dörfler 			if (locked)
543bdfed6c0SAxel Dörfler 				sub->UnlockLooper();
544bdfed6c0SAxel Dörfler 
54541281cf3SAxel Dörfler 			if (sub->CountItems() > 1) {
54641281cf3SAxel Dörfler 				TExpandoMenuBar* parent = static_cast<TExpandoMenuBar*>(Menu());
54741281cf3SAxel Dörfler 				int myindex = parent->IndexOf(this) + 1;
54841281cf3SAxel Dörfler 
54941281cf3SAxel Dörfler 				TWindowMenuItem* windowItem = NULL;
55041281cf3SAxel Dörfler 				int childIndex = 0;
55171bd3ba5SJonas Sundström 				int totalChildren = sub->CountItems() - 4;
55271bd3ba5SJonas Sundström 					// hide, show, close, separator.
55341281cf3SAxel Dörfler 				for (; childIndex < totalChildren; childIndex++) {
55471bd3ba5SJonas Sundström 					windowItem = static_cast<TWindowMenuItem*>
55571bd3ba5SJonas Sundström 						(sub->RemoveItem((int32)0));
55641281cf3SAxel Dörfler 					parent->AddItem(windowItem, myindex + childIndex);
55741281cf3SAxel Dörfler 					windowItem->ExpandedItem(true);
55841281cf3SAxel Dörfler 				}
55941281cf3SAxel Dörfler 				sub->SetExpanded(true, myindex + childIndex);
56041281cf3SAxel Dörfler 
56141281cf3SAxel Dörfler 				if (resizeWindow)
56241281cf3SAxel Dörfler 					parent->SizeWindow();
563c0107fb2SJonas Sundström 			}
56441281cf3SAxel Dörfler 		}
56541281cf3SAxel Dörfler 	} else {
56641281cf3SAxel Dörfler 		// Remove the goodies from the Menu() that should be in the SubMenu();
56741281cf3SAxel Dörfler 		TWindowMenu* sub = static_cast<TWindowMenu*>(Submenu());
56841281cf3SAxel Dörfler 
56941281cf3SAxel Dörfler 		if (sub) {
57041281cf3SAxel Dörfler 			TExpandoMenuBar* parent = static_cast<TExpandoMenuBar*>(Menu());
57141281cf3SAxel Dörfler 
57241281cf3SAxel Dörfler 			TWindowMenuItem* windowItem = NULL;
57341281cf3SAxel Dörfler 			int childIndex = parent->IndexOf(this) + 1;
57471bd3ba5SJonas Sundström 			while (!parent->SubmenuAt(childIndex) && childIndex
57571bd3ba5SJonas Sundström 				< parent->CountItems()) {
57671bd3ba5SJonas Sundström 				windowItem = static_cast<TWindowMenuItem*>
57771bd3ba5SJonas Sundström 					(parent->RemoveItem(childIndex));
57841281cf3SAxel Dörfler 				sub->AddItem(windowItem, 0);
57941281cf3SAxel Dörfler 				windowItem->ExpandedItem(false);
58041281cf3SAxel Dörfler 			}
58141281cf3SAxel Dörfler 			sub->SetExpanded(false, 0);
58241281cf3SAxel Dörfler 
58341281cf3SAxel Dörfler 			if (resizeWindow)
58441281cf3SAxel Dörfler 				parent->SizeWindow();
585c0107fb2SJonas Sundström 		}
58641281cf3SAxel Dörfler 	}
58741281cf3SAxel Dörfler }
58841281cf3SAxel Dörfler 
58941281cf3SAxel Dörfler 
59041281cf3SAxel Dörfler TWindowMenuItem*
59141281cf3SAxel Dörfler TTeamMenuItem::ExpandedWindowItem(int32 id)
59241281cf3SAxel Dörfler {
5931687edd0SFredrik Holmqvist 	if (!fExpanded) {
5941687edd0SFredrik Holmqvist 		// Paranoia
59541281cf3SAxel Dörfler 		return NULL;
5961687edd0SFredrik Holmqvist 	}
59741281cf3SAxel Dörfler 
59841281cf3SAxel Dörfler 	TExpandoMenuBar* parent = static_cast<TExpandoMenuBar*>(Menu());
59941281cf3SAxel Dörfler 	int childIndex = parent->IndexOf(this) + 1;
60041281cf3SAxel Dörfler 
60171bd3ba5SJonas Sundström 	while (!parent->SubmenuAt(childIndex)
60271bd3ba5SJonas Sundström 		&& childIndex < parent->CountItems()) {
60371bd3ba5SJonas Sundström 		TWindowMenuItem* item
60471bd3ba5SJonas Sundström 			= static_cast<TWindowMenuItem*>(parent->ItemAt(childIndex));
60541281cf3SAxel Dörfler 		if (item->ID() == id)
60641281cf3SAxel Dörfler 			return item;
60741281cf3SAxel Dörfler 
60841281cf3SAxel Dörfler 		childIndex++;
60941281cf3SAxel Dörfler 	}
61041281cf3SAxel Dörfler 	return NULL;
61141281cf3SAxel Dörfler }
61241281cf3SAxel Dörfler 
61341281cf3SAxel Dörfler 
61441281cf3SAxel Dörfler BRect
61541281cf3SAxel Dörfler TTeamMenuItem::ExpanderBounds() const
61641281cf3SAxel Dörfler {
61741281cf3SAxel Dörfler 	BRect bounds(Frame());
61841281cf3SAxel Dörfler 	bounds.left = bounds.right - kSwitchWidth;
61941281cf3SAxel Dörfler 	return bounds;
62041281cf3SAxel Dörfler }
62141281cf3SAxel Dörfler 
622249a4a18SStephan Aßmus 
623249a4a18SStephan Aßmus bool
624249a4a18SStephan Aßmus TTeamMenuItem::_IsSelected() const
625249a4a18SStephan Aßmus {
626249a4a18SStephan Aßmus 	return IsSelected() || fOverriddenSelected;
627249a4a18SStephan Aßmus }
628249a4a18SStephan Aßmus 
629