xref: /haiku/src/apps/deskbar/TeamMenuItem.cpp (revision 1687edd0fde594cd6f7c88f58a264c4787b4327d)
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 
29*1687edd0SFredrik Holmqvist Tracker(TM), Be(R), BeOS(R), and BeIA(TM) are trademarks or registered
30*1687edd0SFredrik Holmqvist trademarks of Be Incorporated in the United States and other countries. Other
31*1687edd0SFredrik Holmqvist brand product names are registered trademarks or trademarks of their respective
32*1687edd0SFredrik 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 {
78*1687edd0SFredrik Holmqvist 	InitData(NULL, NULL, strdup(""), strdup(""), width, height, false,
79*1687edd0SFredrik 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 	fDrawLabel = drawLabel;
11141281cf3SAxel Dörfler 	fVertical = vertical;
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
13641281cf3SAxel Dörfler 	TBarView* barview = (static_cast<TBarApp*>(be_app))->BarView();
13741281cf3SAxel Dörfler 	if (barview && barview->Dragging())
13841281cf3SAxel Dörfler 		barview->DragStop();
13941281cf3SAxel Dörfler 
14041281cf3SAxel Dörfler 	// bring to front or minimize shortcuts
14141281cf3SAxel Dörfler 	uint32 mods = modifiers();
142*1687edd0SFredrik 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());
145*1687edd0SFredrik 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 
17341281cf3SAxel Dörfler float
17441281cf3SAxel Dörfler TTeamMenuItem::LabelWidth() const
17541281cf3SAxel Dörfler {
17641281cf3SAxel Dörfler 	return fLabelWidth;
17741281cf3SAxel Dörfler }
17841281cf3SAxel Dörfler 
17941281cf3SAxel Dörfler 
18041281cf3SAxel Dörfler BList*
18141281cf3SAxel Dörfler TTeamMenuItem::Teams() const
18241281cf3SAxel Dörfler {
18341281cf3SAxel Dörfler 	return fTeam;
18441281cf3SAxel Dörfler }
18541281cf3SAxel Dörfler 
18641281cf3SAxel Dörfler 
18741281cf3SAxel Dörfler const char*
18841281cf3SAxel Dörfler TTeamMenuItem::Signature() const
18941281cf3SAxel Dörfler {
19041281cf3SAxel Dörfler 	return fSig;
19141281cf3SAxel Dörfler }
19241281cf3SAxel Dörfler 
19341281cf3SAxel Dörfler 
19441281cf3SAxel Dörfler const char*
19541281cf3SAxel Dörfler TTeamMenuItem::Name() const
19641281cf3SAxel Dörfler {
19741281cf3SAxel Dörfler 	return fName;
19841281cf3SAxel Dörfler }
19941281cf3SAxel Dörfler 
20041281cf3SAxel Dörfler 
20141281cf3SAxel Dörfler void
20241281cf3SAxel Dörfler TTeamMenuItem::GetContentSize(float* width, float* height)
20341281cf3SAxel Dörfler {
20441281cf3SAxel Dörfler 	BRect iconBounds;
20541281cf3SAxel Dörfler 
20641281cf3SAxel Dörfler 	if (fIcon)
20741281cf3SAxel Dörfler 		iconBounds = fIcon->Bounds();
20841281cf3SAxel Dörfler 	else
20941281cf3SAxel Dörfler 		iconBounds = BRect(0, 0, 15, 15);
21041281cf3SAxel Dörfler 
21141281cf3SAxel Dörfler 	BMenuItem::GetContentSize(width, height);
21241281cf3SAxel Dörfler 
21341281cf3SAxel Dörfler 	if (fOverrideWidth != -1.0f)
21441281cf3SAxel Dörfler 		*width = fOverrideWidth;
21541281cf3SAxel Dörfler 	else
21671bd3ba5SJonas Sundström 		*width = kHPad + iconBounds.Width() + kLabelOffset + fLabelWidth + kHPad
21771bd3ba5SJonas Sundström 			+ 20;
21841281cf3SAxel Dörfler 
21941281cf3SAxel Dörfler 	if (fOverrideHeight != -1.0f)
22041281cf3SAxel Dörfler 		*height = fOverrideHeight;
22141281cf3SAxel Dörfler 	else {
22241281cf3SAxel Dörfler 		*height = iconBounds.Height();
22341281cf3SAxel Dörfler 		float labelHeight = fLabelAscent + fLabelDescent;
22441281cf3SAxel Dörfler 		if (labelHeight > *height)
22541281cf3SAxel Dörfler 			*height = labelHeight;
22641281cf3SAxel Dörfler 		*height += (kVPad * 2) + 2;
22741281cf3SAxel Dörfler 	}
22841281cf3SAxel Dörfler 	*height += 2;
22941281cf3SAxel Dörfler }
23041281cf3SAxel Dörfler 
23141281cf3SAxel Dörfler 
23241281cf3SAxel Dörfler void
23341281cf3SAxel Dörfler TTeamMenuItem::Draw()
23441281cf3SAxel Dörfler {
23541281cf3SAxel Dörfler 	BRect frame(Frame());
23641281cf3SAxel Dörfler 	BMenu* menu = Menu();
23741281cf3SAxel Dörfler 	menu->PushState();
238cb6afcb1SStephan Aßmus 	rgb_color menuColor = menu->LowColor();
239cb6afcb1SStephan Aßmus 	TBarView* barview = (static_cast<TBarApp*>(be_app))->BarView();
240*1687edd0SFredrik Holmqvist 
241cb6afcb1SStephan Aßmus 	bool canHandle = !barview->Dragging()
242cb6afcb1SStephan Aßmus 		|| barview->AppCanHandleTypes(Signature());
243cb6afcb1SStephan Aßmus 
244cb6afcb1SStephan Aßmus 	if (be_control_look != NULL) {
245cb6afcb1SStephan Aßmus 		uint32 flags = 0;
246cb6afcb1SStephan Aßmus 		if (_IsSelected() && canHandle)
247cb6afcb1SStephan Aßmus 			flags |= BControlLook::B_ACTIVATED;
248cb6afcb1SStephan Aßmus 
249cb6afcb1SStephan Aßmus 		uint32 borders = BControlLook::B_TOP_BORDER;
250cb6afcb1SStephan Aßmus 		if (fVertical) {
251cb6afcb1SStephan Aßmus 			menu->SetHighColor(tint_color(menuColor, B_DARKEN_1_TINT));
252cb6afcb1SStephan Aßmus 			borders |= BControlLook::B_LEFT_BORDER
253cb6afcb1SStephan Aßmus 				| BControlLook::B_RIGHT_BORDER;
254cb6afcb1SStephan Aßmus 			menu->StrokeLine(frame.LeftBottom(), frame.RightBottom());
255cb6afcb1SStephan Aßmus 			frame.bottom--;
256cb6afcb1SStephan Aßmus 
257cb6afcb1SStephan Aßmus 			be_control_look->DrawMenuBarBackground(menu, frame, frame,
258cb6afcb1SStephan Aßmus 				menuColor, flags, borders);
259cb6afcb1SStephan Aßmus 		} else {
260cb6afcb1SStephan Aßmus 			if (flags & BControlLook::B_ACTIVATED)
261cb6afcb1SStephan Aßmus 				menu->SetHighColor(tint_color(menuColor, B_DARKEN_3_TINT));
262cb6afcb1SStephan Aßmus 			else
263cb6afcb1SStephan Aßmus 				menu->SetHighColor(tint_color(menuColor, 1.22));
264cb6afcb1SStephan Aßmus 			borders |= BControlLook::B_BOTTOM_BORDER;
265cb6afcb1SStephan Aßmus 			menu->StrokeLine(frame.LeftTop(), frame.LeftBottom());
266cb6afcb1SStephan Aßmus 			frame.left++;
267cb6afcb1SStephan Aßmus 
268cb6afcb1SStephan Aßmus 			be_control_look->DrawButtonBackground(menu, frame, frame,
269cb6afcb1SStephan Aßmus 				menuColor, flags, borders);
270cb6afcb1SStephan Aßmus 		}
271cb6afcb1SStephan Aßmus 
272cb6afcb1SStephan Aßmus 		menu->MovePenTo(ContentLocation());
273cb6afcb1SStephan Aßmus 		DrawContent();
274cb6afcb1SStephan Aßmus 		menu->PopState();
275cb6afcb1SStephan Aßmus 		return;
276cb6afcb1SStephan Aßmus 	}
27741281cf3SAxel Dörfler 
27841281cf3SAxel Dörfler 	//	if not selected or being tracked on, fill with gray
279eddec292SOliver Tappe 	if ((!_IsSelected() && !menu->IsRedrawAfterSticky()) || !canHandle
280cb6afcb1SStephan Aßmus 		|| !IsEnabled()) {
28141281cf3SAxel Dörfler 		frame.InsetBy(1, 1);
28241281cf3SAxel Dörfler 		menu->SetHighColor(menuColor);
28341281cf3SAxel Dörfler 		menu->FillRect(frame);
28441281cf3SAxel Dörfler 	}
28541281cf3SAxel Dörfler 
28641281cf3SAxel Dörfler 	//	draw the gray, unselected item, border
287249a4a18SStephan Aßmus 	if (!_IsSelected() || !IsEnabled()) {
28841281cf3SAxel Dörfler 		rgb_color shadow = tint_color(menuColor, B_DARKEN_1_TINT);
28941281cf3SAxel Dörfler 		rgb_color light = tint_color(menuColor, B_LIGHTEN_2_TINT);
29041281cf3SAxel Dörfler 
29141281cf3SAxel Dörfler 		frame = Frame();
29241281cf3SAxel Dörfler 
29341281cf3SAxel Dörfler 		menu->SetHighColor(shadow);
29441281cf3SAxel Dörfler 		if (fVertical)
29541281cf3SAxel Dörfler 			menu->StrokeLine(frame.LeftBottom(), frame.RightBottom());
29641281cf3SAxel Dörfler 		else
29771bd3ba5SJonas Sundström 			menu->StrokeLine(frame.LeftBottom() + BPoint(1, 0),
29871bd3ba5SJonas Sundström 				frame.RightBottom());
29941281cf3SAxel Dörfler 
30041281cf3SAxel Dörfler 		menu->StrokeLine(frame.RightBottom(), frame.RightTop());
30141281cf3SAxel Dörfler 
30241281cf3SAxel Dörfler 		menu->SetHighColor(light);
30341281cf3SAxel Dörfler 		menu->StrokeLine(frame.RightTop() + BPoint(-1, 0), frame.LeftTop());
30441281cf3SAxel Dörfler 		if (fVertical)
30571bd3ba5SJonas Sundström 			menu->StrokeLine(frame.LeftTop(), frame.LeftBottom()
30671bd3ba5SJonas Sundström 				+ BPoint(0, -1));
30741281cf3SAxel Dörfler 		else
30841281cf3SAxel Dörfler 			menu->StrokeLine(frame.LeftTop(), frame.LeftBottom());
30941281cf3SAxel Dörfler 	}
31041281cf3SAxel Dörfler 
31141281cf3SAxel Dörfler 	//	if selected or being tracked on, fill with the hilite gray color
31271bd3ba5SJonas Sundström 	if (IsEnabled() && _IsSelected() && !menu->IsRedrawAfterSticky()
31371bd3ba5SJonas Sundström 		&& canHandle) {
31441281cf3SAxel Dörfler 		// fill
31541281cf3SAxel Dörfler 		menu->SetHighColor(tint_color(menuColor, B_HIGHLIGHT_BACKGROUND_TINT));
31641281cf3SAxel Dörfler 		menu->FillRect(frame);
31741281cf3SAxel Dörfler 
31841281cf3SAxel Dörfler 		// these continue the dark grey border on the left or top edge
31941281cf3SAxel Dörfler 		menu->SetHighColor(tint_color(menuColor, B_DARKEN_4_TINT));
320*1687edd0SFredrik Holmqvist 		if (fVertical) {
32141281cf3SAxel Dörfler 			// dark line at top
32241281cf3SAxel Dörfler 			menu->StrokeLine(frame.LeftTop(), frame.RightTop());
323*1687edd0SFredrik Holmqvist 		} else {
32441281cf3SAxel Dörfler 			// dark line on the left
32541281cf3SAxel Dörfler 			menu->StrokeLine(frame.LeftTop(), frame.LeftBottom());
326*1687edd0SFredrik Holmqvist 		}
32741281cf3SAxel Dörfler 	} else
32841281cf3SAxel Dörfler 		menu->SetLowColor(menuColor);
32941281cf3SAxel Dörfler 
33041281cf3SAxel Dörfler 	menu->MovePenTo(ContentLocation());
33141281cf3SAxel Dörfler 	DrawContent();
33241281cf3SAxel Dörfler 	menu->PopState();
33341281cf3SAxel Dörfler }
33441281cf3SAxel Dörfler 
33541281cf3SAxel Dörfler 
33641281cf3SAxel Dörfler void
33741281cf3SAxel Dörfler TTeamMenuItem::DrawContent()
33841281cf3SAxel Dörfler {
33941281cf3SAxel Dörfler 	BMenu* menu = Menu();
34041281cf3SAxel Dörfler 	if (fIcon) {
34159deaf10SStephan Aßmus 		if (fIcon->ColorSpace() == B_RGBA32) {
34259deaf10SStephan Aßmus 			menu->SetDrawingMode(B_OP_ALPHA);
34359deaf10SStephan Aßmus 			menu->SetBlendingMode(B_PIXEL_ALPHA, B_ALPHA_OVERLAY);
344*1687edd0SFredrik Holmqvist 		} else
34541281cf3SAxel Dörfler 			menu->SetDrawingMode(B_OP_OVER);
34641281cf3SAxel Dörfler 
347*1687edd0SFredrik Holmqvist 		BRect frame(Frame());
34841281cf3SAxel Dörfler 		BRect iconBounds(fIcon->Bounds());
34941281cf3SAxel Dörfler 		BRect dstRect(iconBounds);
35041281cf3SAxel Dörfler 		float extra = fVertical ? 0.0f : 1.0f;
35141281cf3SAxel Dörfler 		BPoint contLoc = ContentLocation();
352*1687edd0SFredrik Holmqvist 
35341281cf3SAxel Dörfler 		dstRect.OffsetTo(BPoint(contLoc.x + kHPad, contLoc.y +
35441281cf3SAxel Dörfler 			((frame.Height() - iconBounds.Height()) / 2) + extra));
35541281cf3SAxel Dörfler 		menu->DrawBitmapAsync(fIcon, dstRect);
35641281cf3SAxel Dörfler 
35741281cf3SAxel Dörfler 		float labelHeight = fLabelAscent + fLabelDescent;
35841281cf3SAxel Dörfler 		BPoint drawLoc = contLoc + BPoint(kHPad, kVPad);
35941281cf3SAxel Dörfler 		drawLoc.x += iconBounds.Width() + kLabelOffset;
36041281cf3SAxel Dörfler 		drawLoc.y = frame.top + ((frame.Height() - labelHeight) / 2) + 1.0f;
36141281cf3SAxel Dörfler 		menu->MovePenTo(drawLoc);
36241281cf3SAxel Dörfler 	}
36341281cf3SAxel Dörfler 
36441281cf3SAxel Dörfler 	// set the pen to black so that either method will draw in the same color
365cb6afcb1SStephan Aßmus 	// low color is set in inherited::DrawContent, override makes sure its
366cb6afcb1SStephan Aßmus 	// what we want
36741281cf3SAxel Dörfler 	if (fDrawLabel) {
368cb6afcb1SStephan Aßmus 		menu->SetDrawingMode(B_OP_OVER);
36941281cf3SAxel Dörfler 		menu->SetHighColor(0, 0, 0);
37041281cf3SAxel Dörfler 
37141281cf3SAxel Dörfler 		// override the drawing of the content when the item is disabled
37241281cf3SAxel Dörfler 		// the wrong lowcolor is used when the item is disabled since the
37341281cf3SAxel Dörfler 		// text color does not change
37441281cf3SAxel Dörfler 		DrawContentLabel();
37541281cf3SAxel Dörfler 	}
37641281cf3SAxel Dörfler 
37741281cf3SAxel Dörfler 	// Draw the expandable icon.
37841281cf3SAxel Dörfler 	TBarView* barView = (static_cast<TBarApp*>(be_app))->BarView();
37941281cf3SAxel Dörfler 	if (fVertical && static_cast<TBarApp*>(be_app)->Settings()->superExpando
38041281cf3SAxel Dörfler 		&& barView->Expando()) {
38141281cf3SAxel Dörfler 		BRect frame(Frame());
38241281cf3SAxel Dörfler 		BRect rect(0, 0, kSwitchWidth, 10);
38341281cf3SAxel Dörfler 		rect.OffsetTo(BPoint(frame.right - rect.Width(),
38441281cf3SAxel Dörfler 			ContentLocation().y + ((frame.Height() - rect.Height()) / 2)));
38541281cf3SAxel Dörfler 
386cb6afcb1SStephan Aßmus 		if (be_control_look != NULL) {
387cb6afcb1SStephan Aßmus 			uint32 arrowDirection = fExpanded
388cb6afcb1SStephan Aßmus 				? BControlLook::B_UP_ARROW : BControlLook::B_DOWN_ARROW;
389cb6afcb1SStephan Aßmus 			be_control_look->DrawArrowShape(menu, rect, rect, menu->LowColor(),
390cb6afcb1SStephan Aßmus 				arrowDirection, 0, B_DARKEN_3_TINT);
391cb6afcb1SStephan Aßmus 		} else {
39241281cf3SAxel Dörfler 			rgb_color outlineColor = {80, 80, 80, 255};
39341281cf3SAxel Dörfler 			rgb_color middleColor = {200, 200, 200, 255};
39441281cf3SAxel Dörfler 
3951407220dSStefano Ceccherini 			menu->SetDrawingMode(B_OP_OVER);
39641281cf3SAxel Dörfler 
39741281cf3SAxel Dörfler 			if (!fExpanded) {
39841281cf3SAxel Dörfler 				menu->BeginLineArray(6);
39941281cf3SAxel Dörfler 
40041281cf3SAxel Dörfler 				menu->AddLine(BPoint(rect.left + 3, rect.top + 1),
40141281cf3SAxel Dörfler 					BPoint(rect.left + 3, rect.bottom - 1), outlineColor);
40241281cf3SAxel Dörfler 				menu->AddLine(BPoint(rect.left + 3, rect.top + 1),
40341281cf3SAxel Dörfler 					BPoint(rect.left + 7, rect.top + 5), outlineColor);
40441281cf3SAxel Dörfler 				menu->AddLine(BPoint(rect.left + 7, rect.top + 5),
40541281cf3SAxel Dörfler 					BPoint(rect.left + 3, rect.bottom - 1), outlineColor);
40641281cf3SAxel Dörfler 
40741281cf3SAxel Dörfler 				menu->AddLine(BPoint(rect.left + 4, rect.top + 3),
40841281cf3SAxel Dörfler 					BPoint(rect.left + 4, rect.bottom - 3), middleColor);
40941281cf3SAxel Dörfler 				menu->AddLine(BPoint(rect.left + 5, rect.top + 4),
41041281cf3SAxel Dörfler 					BPoint(rect.left + 5, rect.bottom - 4), middleColor);
41141281cf3SAxel Dörfler 				menu->AddLine(BPoint(rect.left + 5, rect.top + 5),
41241281cf3SAxel Dörfler 					BPoint(rect.left + 6, rect.top + 5), middleColor);
41341281cf3SAxel Dörfler 				menu->EndLineArray();
41441281cf3SAxel Dörfler 			} else {
41541281cf3SAxel Dörfler 				// expanded state
41641281cf3SAxel Dörfler 
41741281cf3SAxel Dörfler 				menu->BeginLineArray(6);
41841281cf3SAxel Dörfler 				menu->AddLine(BPoint(rect.left + 1, rect.top + 3),
41941281cf3SAxel Dörfler 					BPoint(rect.right - 3, rect.top + 3), outlineColor);
42041281cf3SAxel Dörfler 				menu->AddLine(BPoint(rect.left + 1, rect.top + 3),
42141281cf3SAxel Dörfler 					BPoint(rect.left + 5, rect.top + 7), outlineColor);
42241281cf3SAxel Dörfler 				menu->AddLine(BPoint(rect.left + 5, rect.top + 7),
42341281cf3SAxel Dörfler 					BPoint(rect.right - 3, rect.top + 3), outlineColor);
42441281cf3SAxel Dörfler 
42541281cf3SAxel Dörfler 				menu->AddLine(BPoint(rect.left + 3, rect.top + 4),
42641281cf3SAxel Dörfler 					BPoint(rect.right - 5, rect.top + 4), middleColor);
42741281cf3SAxel Dörfler 				menu->AddLine(BPoint(rect.left + 4, rect.top + 5),
42841281cf3SAxel Dörfler 					BPoint(rect.right - 6, rect.top + 5), middleColor);
42941281cf3SAxel Dörfler 				menu->AddLine(BPoint(rect.left + 5, rect.top + 5),
43041281cf3SAxel Dörfler 					BPoint(rect.left + 5, rect.top + 6), middleColor);
43141281cf3SAxel Dörfler 				menu->EndLineArray();
43241281cf3SAxel Dörfler 			}
43341281cf3SAxel Dörfler 		}
43441281cf3SAxel Dörfler 	}
435cb6afcb1SStephan Aßmus }
43641281cf3SAxel Dörfler 
43741281cf3SAxel Dörfler 
43841281cf3SAxel Dörfler void
43941281cf3SAxel Dörfler TTeamMenuItem::DrawContentLabel()
44041281cf3SAxel Dörfler {
44141281cf3SAxel Dörfler 	BMenu* menu = Menu();
44241281cf3SAxel Dörfler 	menu->MovePenBy(0, fLabelAscent);
44341281cf3SAxel Dörfler 
44441281cf3SAxel Dörfler 	float cachedWidth = menu->StringWidth(Label());
44541281cf3SAxel Dörfler 	if (Submenu() && fVertical)
44641281cf3SAxel Dörfler 		cachedWidth += 18;
44741281cf3SAxel Dörfler 
44841281cf3SAxel Dörfler 	const char* label = Label();
44941281cf3SAxel Dörfler 	char* truncLabel = NULL;
45041281cf3SAxel Dörfler 	float max = 0;
451*1687edd0SFredrik Holmqvist 
45241281cf3SAxel Dörfler 	if (static_cast<TBarApp*>(be_app)->Settings()->superExpando && fVertical)
45341281cf3SAxel Dörfler 		max = menu->MaxContentWidth() - kSwitchWidth;
45441281cf3SAxel Dörfler 	else
45541281cf3SAxel Dörfler 		max = menu->MaxContentWidth();
45641281cf3SAxel Dörfler 
45741281cf3SAxel Dörfler 	if (max > 0) {
45841281cf3SAxel Dörfler 		BPoint penloc = menu->PenLocation();
45941281cf3SAxel Dörfler 		BRect frame = Frame();
46041281cf3SAxel Dörfler 		float offset = penloc.x - frame.left;
46141281cf3SAxel Dörfler 		if (cachedWidth + offset > max) {
46241281cf3SAxel Dörfler 			truncLabel = (char*)malloc(strlen(label) + 4);
46341281cf3SAxel Dörfler 			if (!truncLabel)
46441281cf3SAxel Dörfler 				return;
46541281cf3SAxel Dörfler 			TruncateLabel(max-offset, truncLabel);
46641281cf3SAxel Dörfler 			label = truncLabel;
46741281cf3SAxel Dörfler 		}
46841281cf3SAxel Dörfler 	}
46941281cf3SAxel Dörfler 
47041281cf3SAxel Dörfler 	if (!label)
47141281cf3SAxel Dörfler 		label = Label();
47241281cf3SAxel Dörfler 
47341281cf3SAxel Dörfler 	TBarView* barview = (static_cast<TBarApp*>(be_app))->BarView();
474eaa9af99SStephan Aßmus 	bool canHandle = !barview->Dragging()
475eaa9af99SStephan Aßmus 		|| barview->AppCanHandleTypes(Signature());
476249a4a18SStephan Aßmus 	if (_IsSelected() && IsEnabled() && canHandle)
477eaa9af99SStephan Aßmus 		menu->SetLowColor(tint_color(menu->ViewColor(),
47841281cf3SAxel Dörfler 			B_HIGHLIGHT_BACKGROUND_TINT));
47941281cf3SAxel Dörfler 	else
48041281cf3SAxel Dörfler 		menu->SetLowColor(menu->ViewColor());
48141281cf3SAxel Dörfler 
48241281cf3SAxel Dörfler 	menu->DrawString(label);
48341281cf3SAxel Dörfler 
48441281cf3SAxel Dörfler 	free(truncLabel);
48541281cf3SAxel Dörfler }
48641281cf3SAxel Dörfler 
48741281cf3SAxel Dörfler 
48841281cf3SAxel Dörfler bool
48941281cf3SAxel Dörfler TTeamMenuItem::IsExpanded()
49041281cf3SAxel Dörfler {
49141281cf3SAxel Dörfler 	return fExpanded;
49241281cf3SAxel Dörfler }
49341281cf3SAxel Dörfler 
49441281cf3SAxel Dörfler 
49541281cf3SAxel Dörfler void
49641281cf3SAxel Dörfler TTeamMenuItem::ToggleExpandState(bool resizeWindow)
49741281cf3SAxel Dörfler {
49841281cf3SAxel Dörfler 	fExpanded = !fExpanded;
49941281cf3SAxel Dörfler 
50041281cf3SAxel Dörfler 	if (fExpanded) {
50141281cf3SAxel Dörfler 		// Populate Menu() with the stuff from SubMenu().
50241281cf3SAxel Dörfler 		TWindowMenu* sub = (static_cast<TWindowMenu*>(Submenu()));
50341281cf3SAxel Dörfler 		if (sub) {
50441281cf3SAxel Dörfler 			// force the menu to update it's contents.
505bdfed6c0SAxel Dörfler 			bool locked = sub->LockLooper();
506bdfed6c0SAxel Dörfler 				// if locking the looper failed, the menu is just not visible
507bdfed6c0SAxel Dörfler 			sub->AttachedToWindow();
508bdfed6c0SAxel Dörfler 			if (locked)
509bdfed6c0SAxel Dörfler 				sub->UnlockLooper();
510bdfed6c0SAxel Dörfler 
51141281cf3SAxel Dörfler 			if (sub->CountItems() > 1) {
51241281cf3SAxel Dörfler 				TExpandoMenuBar* parent = static_cast<TExpandoMenuBar*>(Menu());
51341281cf3SAxel Dörfler 				int myindex = parent->IndexOf(this) + 1;
51441281cf3SAxel Dörfler 
51541281cf3SAxel Dörfler 				TWindowMenuItem* windowItem = NULL;
51641281cf3SAxel Dörfler 				int childIndex = 0;
51771bd3ba5SJonas Sundström 				int totalChildren = sub->CountItems() - 4;
51871bd3ba5SJonas Sundström 					// hide, show, close, separator.
51941281cf3SAxel Dörfler 				for (; childIndex < totalChildren; childIndex++) {
52071bd3ba5SJonas Sundström 					windowItem = static_cast<TWindowMenuItem*>
52171bd3ba5SJonas Sundström 						(sub->RemoveItem((int32)0));
52241281cf3SAxel Dörfler 					parent->AddItem(windowItem, myindex + childIndex);
52341281cf3SAxel Dörfler 					windowItem->ExpandedItem(true);
52441281cf3SAxel Dörfler 				}
52541281cf3SAxel Dörfler 				sub->SetExpanded(true, myindex + childIndex);
52641281cf3SAxel Dörfler 
52741281cf3SAxel Dörfler 				if (resizeWindow)
52841281cf3SAxel Dörfler 					parent->SizeWindow();
529c0107fb2SJonas Sundström 			}
53041281cf3SAxel Dörfler 		}
53141281cf3SAxel Dörfler 	} else {
53241281cf3SAxel Dörfler 		// Remove the goodies from the Menu() that should be in the SubMenu();
53341281cf3SAxel Dörfler 		TWindowMenu* sub = static_cast<TWindowMenu*>(Submenu());
53441281cf3SAxel Dörfler 
53541281cf3SAxel Dörfler 		if (sub) {
53641281cf3SAxel Dörfler 			TExpandoMenuBar* parent = static_cast<TExpandoMenuBar*>(Menu());
53741281cf3SAxel Dörfler 
53841281cf3SAxel Dörfler 			TWindowMenuItem* windowItem = NULL;
53941281cf3SAxel Dörfler 			int childIndex = parent->IndexOf(this) + 1;
54071bd3ba5SJonas Sundström 			while (!parent->SubmenuAt(childIndex) && childIndex
54171bd3ba5SJonas Sundström 				< parent->CountItems()) {
54271bd3ba5SJonas Sundström 				windowItem = static_cast<TWindowMenuItem*>
54371bd3ba5SJonas Sundström 					(parent->RemoveItem(childIndex));
54441281cf3SAxel Dörfler 				sub->AddItem(windowItem, 0);
54541281cf3SAxel Dörfler 				windowItem->ExpandedItem(false);
54641281cf3SAxel Dörfler 			}
54741281cf3SAxel Dörfler 			sub->SetExpanded(false, 0);
54841281cf3SAxel Dörfler 
54941281cf3SAxel Dörfler 			if (resizeWindow)
55041281cf3SAxel Dörfler 				parent->SizeWindow();
551c0107fb2SJonas Sundström 		}
55241281cf3SAxel Dörfler 	}
55341281cf3SAxel Dörfler }
55441281cf3SAxel Dörfler 
55541281cf3SAxel Dörfler 
55641281cf3SAxel Dörfler TWindowMenuItem*
55741281cf3SAxel Dörfler TTeamMenuItem::ExpandedWindowItem(int32 id)
55841281cf3SAxel Dörfler {
559*1687edd0SFredrik Holmqvist 	if (!fExpanded) {
560*1687edd0SFredrik Holmqvist 		// Paranoia
56141281cf3SAxel Dörfler 		return NULL;
562*1687edd0SFredrik Holmqvist 	}
56341281cf3SAxel Dörfler 
56441281cf3SAxel Dörfler 	TExpandoMenuBar* parent = static_cast<TExpandoMenuBar*>(Menu());
56541281cf3SAxel Dörfler 	int childIndex = parent->IndexOf(this) + 1;
56641281cf3SAxel Dörfler 
56771bd3ba5SJonas Sundström 	while (!parent->SubmenuAt(childIndex)
56871bd3ba5SJonas Sundström 		&& childIndex < parent->CountItems()) {
56971bd3ba5SJonas Sundström 		TWindowMenuItem* item
57071bd3ba5SJonas Sundström 			= static_cast<TWindowMenuItem*>(parent->ItemAt(childIndex));
57141281cf3SAxel Dörfler 		if (item->ID() == id)
57241281cf3SAxel Dörfler 			return item;
57341281cf3SAxel Dörfler 
57441281cf3SAxel Dörfler 		childIndex++;
57541281cf3SAxel Dörfler 	}
57641281cf3SAxel Dörfler 	return NULL;
57741281cf3SAxel Dörfler }
57841281cf3SAxel Dörfler 
57941281cf3SAxel Dörfler 
58041281cf3SAxel Dörfler BRect
58141281cf3SAxel Dörfler TTeamMenuItem::ExpanderBounds() const
58241281cf3SAxel Dörfler {
58341281cf3SAxel Dörfler 	BRect bounds(Frame());
58441281cf3SAxel Dörfler 	bounds.left = bounds.right - kSwitchWidth;
58541281cf3SAxel Dörfler 	return bounds;
58641281cf3SAxel Dörfler }
58741281cf3SAxel Dörfler 
588249a4a18SStephan Aßmus 
589249a4a18SStephan Aßmus bool
590249a4a18SStephan Aßmus TTeamMenuItem::_IsSelected() const
591249a4a18SStephan Aßmus {
592249a4a18SStephan Aßmus 	return IsSelected() || fOverriddenSelected;
593249a4a18SStephan Aßmus }
594249a4a18SStephan Aßmus 
595