xref: /haiku/src/apps/deskbar/TeamMenuItem.cpp (revision eddec292d5dd8251a00851880e16e6a5c07c1e3f)
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 
2941281cf3SAxel Dörfler Tracker(TM), Be(R), BeOS(R), and BeIA(TM) are trademarks or registered trademarks
3041281cf3SAxel Dörfler of Be Incorporated in the United States and other countries. Other brand product
3141281cf3SAxel Dörfler names are registered trademarks or trademarks of their respective holders.
3241281cf3SAxel Dörfler All rights reserved.
3341281cf3SAxel Dörfler */
3441281cf3SAxel Dörfler 
3541281cf3SAxel Dörfler #include <Debug.h>
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>
4541281cf3SAxel Dörfler #include <Font.h>
4641281cf3SAxel Dörfler #include <Region.h>
4741281cf3SAxel Dörfler #include <Roster.h>
4841281cf3SAxel Dörfler #include <Resources.h>
4941281cf3SAxel Dörfler 
5041281cf3SAxel Dörfler #include "BarApp.h"
5141281cf3SAxel Dörfler #include "BarMenuBar.h"
5241281cf3SAxel Dörfler #include "ExpandoMenuBar.h"
5341281cf3SAxel Dörfler #include "ResourceSet.h"
5441281cf3SAxel Dörfler #include "ShowHideMenuItem.h"
5541281cf3SAxel Dörfler #include "TeamMenu.h"
5641281cf3SAxel Dörfler #include "WindowMenu.h"
5741281cf3SAxel Dörfler #include "WindowMenuItem.h"
5841281cf3SAxel Dörfler 
5941281cf3SAxel Dörfler 
6041281cf3SAxel Dörfler const float kHPad = 8.0f;
6141281cf3SAxel Dörfler const float kVPad = 1.0f;
6241281cf3SAxel Dörfler const float kLabelOffset = 8.0f;
6341281cf3SAxel Dörfler const float kSwitchWidth = 12;
6441281cf3SAxel Dörfler 
6541281cf3SAxel Dörfler 
6641281cf3SAxel Dörfler TTeamMenuItem::TTeamMenuItem(BList* team, BBitmap* icon, char* name, char* sig,
6741281cf3SAxel Dörfler 	float width, float height, bool drawLabel, bool vertical)
6841281cf3SAxel Dörfler 	:	BMenuItem(new TWindowMenu(team, sig))
6941281cf3SAxel Dörfler {
7041281cf3SAxel Dörfler 	InitData(team, icon, name, sig, width, height, drawLabel, vertical);
7141281cf3SAxel Dörfler }
7241281cf3SAxel Dörfler 
7341281cf3SAxel Dörfler 
7441281cf3SAxel Dörfler TTeamMenuItem::TTeamMenuItem(float width,float height,bool vertical)
7541281cf3SAxel Dörfler 	:	BMenuItem("", NULL)
7641281cf3SAxel Dörfler {
7741281cf3SAxel Dörfler 	InitData(NULL, NULL, strdup(""), strdup(""), width, height, false, vertical);
7841281cf3SAxel Dörfler }
7941281cf3SAxel Dörfler 
8041281cf3SAxel Dörfler 
8141281cf3SAxel Dörfler void
8241281cf3SAxel Dörfler TTeamMenuItem::InitData(BList* team, BBitmap* icon, char* name, char* sig,
8341281cf3SAxel Dörfler 	float width, float height, bool drawLabel, bool vertical)
8441281cf3SAxel Dörfler {
8541281cf3SAxel Dörfler 	fTeam = team;
8641281cf3SAxel Dörfler 	fIcon = icon;
8741281cf3SAxel Dörfler 	fName = name;
8841281cf3SAxel Dörfler 	fSig = sig;
8941281cf3SAxel Dörfler 	if (fName == NULL) {
90136d40a8SStefano Ceccherini 		char temp[32];
91136d40a8SStefano Ceccherini 		snprintf(temp, sizeof(temp), "team %ld", (int32)team->ItemAt(0));
92136d40a8SStefano Ceccherini 		fName = strdup(temp);
9341281cf3SAxel Dörfler 	}
9441281cf3SAxel Dörfler 
95136d40a8SStefano Ceccherini 	SetLabel(fName);
96136d40a8SStefano Ceccherini 
9741281cf3SAxel Dörfler 	BFont font(be_plain_font);
9841281cf3SAxel Dörfler 	fLabelWidth = ceilf(font.StringWidth(fName));
9941281cf3SAxel Dörfler 	font_height fontHeight;
10041281cf3SAxel Dörfler 	font.GetHeight(&fontHeight);
10141281cf3SAxel Dörfler 	fLabelAscent = ceilf(fontHeight.ascent);
10241281cf3SAxel Dörfler 	fLabelDescent = ceilf(fontHeight.descent + fontHeight.leading);
10341281cf3SAxel Dörfler 
10441281cf3SAxel Dörfler 	fOverrideWidth = width;
10541281cf3SAxel Dörfler 	fOverrideHeight = height;
106249a4a18SStephan Aßmus 	fOverriddenSelected = false;
10741281cf3SAxel Dörfler 
10841281cf3SAxel Dörfler 	fDrawLabel = drawLabel;
10941281cf3SAxel Dörfler 	fVertical = vertical;
11041281cf3SAxel Dörfler 
11141281cf3SAxel Dörfler 	fExpanded = false;
11241281cf3SAxel Dörfler }
11341281cf3SAxel Dörfler 
11441281cf3SAxel Dörfler 
11541281cf3SAxel Dörfler TTeamMenuItem::~TTeamMenuItem()
11641281cf3SAxel Dörfler {
11741281cf3SAxel Dörfler 	delete fTeam;
11841281cf3SAxel Dörfler 	delete fIcon;
11941281cf3SAxel Dörfler 	free(fName);
12041281cf3SAxel Dörfler 	free(fSig);
12141281cf3SAxel Dörfler }
12241281cf3SAxel Dörfler 
12341281cf3SAxel Dörfler 
12441281cf3SAxel Dörfler status_t
12541281cf3SAxel Dörfler TTeamMenuItem::Invoke(BMessage* message)
12641281cf3SAxel Dörfler {
12741281cf3SAxel Dörfler 	if ((static_cast<TBarApp*>(be_app))->BarView()->InvokeItem(Signature()))
12841281cf3SAxel Dörfler 		//	handles drop on application
12941281cf3SAxel Dörfler 		return B_OK;
13041281cf3SAxel Dörfler 
13141281cf3SAxel Dörfler 	//	if the app could not handle the drag message
13241281cf3SAxel Dörfler 	//	and we were dragging, then kill the drag
13341281cf3SAxel Dörfler 	//	should never get here, disabled item will not invoke
13441281cf3SAxel Dörfler 	TBarView* barview = (static_cast<TBarApp*>(be_app))->BarView();
13541281cf3SAxel Dörfler 	if (barview && barview->Dragging())
13641281cf3SAxel Dörfler 		barview->DragStop();
13741281cf3SAxel Dörfler 
13841281cf3SAxel Dörfler 	// bring to front or minimize shortcuts
13941281cf3SAxel Dörfler 	uint32 mods = modifiers();
14041281cf3SAxel Dörfler 	if (mods & B_CONTROL_KEY)
14141281cf3SAxel Dörfler 		TShowHideMenuItem::TeamShowHideCommon((mods & B_SHIFT_KEY)
14241281cf3SAxel Dörfler 				? B_MINIMIZE_WINDOW : B_BRING_TO_FRONT, Teams());
14341281cf3SAxel Dörfler 
14441281cf3SAxel Dörfler 	return BMenuItem::Invoke(message);
14541281cf3SAxel Dörfler }
14641281cf3SAxel Dörfler 
14741281cf3SAxel Dörfler 
14841281cf3SAxel Dörfler void
14941281cf3SAxel Dörfler TTeamMenuItem::SetOverrideWidth(float width)
15041281cf3SAxel Dörfler {
15141281cf3SAxel Dörfler 	fOverrideWidth = width;
15241281cf3SAxel Dörfler }
15341281cf3SAxel Dörfler 
15441281cf3SAxel Dörfler 
15541281cf3SAxel Dörfler void
15641281cf3SAxel Dörfler TTeamMenuItem::SetOverrideHeight(float height)
15741281cf3SAxel Dörfler {
15841281cf3SAxel Dörfler 	fOverrideHeight = height;
15941281cf3SAxel Dörfler }
16041281cf3SAxel Dörfler 
16141281cf3SAxel Dörfler 
162249a4a18SStephan Aßmus void
163249a4a18SStephan Aßmus TTeamMenuItem::SetOverrideSelected(bool selected)
164249a4a18SStephan Aßmus {
165249a4a18SStephan Aßmus 	fOverriddenSelected = selected;
166249a4a18SStephan Aßmus 	Highlight(selected);
167249a4a18SStephan Aßmus }
168249a4a18SStephan Aßmus 
169249a4a18SStephan Aßmus 
17041281cf3SAxel Dörfler float
17141281cf3SAxel Dörfler TTeamMenuItem::LabelWidth() const
17241281cf3SAxel Dörfler {
17341281cf3SAxel Dörfler 	return fLabelWidth;
17441281cf3SAxel Dörfler }
17541281cf3SAxel Dörfler 
17641281cf3SAxel Dörfler 
17741281cf3SAxel Dörfler BList*
17841281cf3SAxel Dörfler TTeamMenuItem::Teams() const
17941281cf3SAxel Dörfler {
18041281cf3SAxel Dörfler 	return fTeam;
18141281cf3SAxel Dörfler }
18241281cf3SAxel Dörfler 
18341281cf3SAxel Dörfler 
18441281cf3SAxel Dörfler const char*
18541281cf3SAxel Dörfler TTeamMenuItem::Signature() const
18641281cf3SAxel Dörfler {
18741281cf3SAxel Dörfler 	return fSig;
18841281cf3SAxel Dörfler }
18941281cf3SAxel Dörfler 
19041281cf3SAxel Dörfler 
19141281cf3SAxel Dörfler const char*
19241281cf3SAxel Dörfler TTeamMenuItem::Name() const
19341281cf3SAxel Dörfler {
19441281cf3SAxel Dörfler 	return fName;
19541281cf3SAxel Dörfler }
19641281cf3SAxel Dörfler 
19741281cf3SAxel Dörfler 
19841281cf3SAxel Dörfler void
19941281cf3SAxel Dörfler TTeamMenuItem::GetContentSize(float* width, float* height)
20041281cf3SAxel Dörfler {
20141281cf3SAxel Dörfler 	BRect iconBounds;
20241281cf3SAxel Dörfler 
20341281cf3SAxel Dörfler 	if (fIcon)
20441281cf3SAxel Dörfler 		iconBounds = fIcon->Bounds();
20541281cf3SAxel Dörfler 	else
20641281cf3SAxel Dörfler 		iconBounds = BRect(0, 0, 15, 15);
20741281cf3SAxel Dörfler 
20841281cf3SAxel Dörfler 	BMenuItem::GetContentSize(width, height);
20941281cf3SAxel Dörfler 
21041281cf3SAxel Dörfler 	if (fOverrideWidth != -1.0f)
21141281cf3SAxel Dörfler 		*width = fOverrideWidth;
21241281cf3SAxel Dörfler 	else
21371bd3ba5SJonas Sundström 		*width = kHPad + iconBounds.Width() + kLabelOffset + fLabelWidth + kHPad
21471bd3ba5SJonas Sundström 			+ 20;
21541281cf3SAxel Dörfler 
21641281cf3SAxel Dörfler 	if (fOverrideHeight != -1.0f)
21741281cf3SAxel Dörfler 		*height = fOverrideHeight;
21841281cf3SAxel Dörfler 	else {
21941281cf3SAxel Dörfler 		*height = iconBounds.Height();
22041281cf3SAxel Dörfler 		float labelHeight = fLabelAscent + fLabelDescent;
22141281cf3SAxel Dörfler 		if (labelHeight > *height)
22241281cf3SAxel Dörfler 			*height = labelHeight;
22341281cf3SAxel Dörfler 		*height += (kVPad * 2) + 2;
22441281cf3SAxel Dörfler 	}
22541281cf3SAxel Dörfler 	*height += 2;
22641281cf3SAxel Dörfler }
22741281cf3SAxel Dörfler 
22841281cf3SAxel Dörfler 
22941281cf3SAxel Dörfler void
23041281cf3SAxel Dörfler TTeamMenuItem::Draw()
23141281cf3SAxel Dörfler {
23241281cf3SAxel Dörfler 	BRect frame(Frame());
23341281cf3SAxel Dörfler 	BMenu* menu = Menu();
23441281cf3SAxel Dörfler 	menu->PushState();
235cb6afcb1SStephan Aßmus 	rgb_color menuColor = menu->LowColor();
236cb6afcb1SStephan Aßmus 
237cb6afcb1SStephan Aßmus 	TBarView* barview = (static_cast<TBarApp*>(be_app))->BarView();
238cb6afcb1SStephan Aßmus 	bool canHandle = !barview->Dragging()
239cb6afcb1SStephan Aßmus 		|| barview->AppCanHandleTypes(Signature());
240cb6afcb1SStephan Aßmus 
241cb6afcb1SStephan Aßmus 	if (be_control_look != NULL) {
242cb6afcb1SStephan Aßmus 		uint32 flags = 0;
243cb6afcb1SStephan Aßmus 		if (_IsSelected() && canHandle)
244cb6afcb1SStephan Aßmus 			flags |= BControlLook::B_ACTIVATED;
245cb6afcb1SStephan Aßmus 
246cb6afcb1SStephan Aßmus 		uint32 borders = BControlLook::B_TOP_BORDER;
247cb6afcb1SStephan Aßmus 		if (fVertical) {
248cb6afcb1SStephan Aßmus 			menu->SetHighColor(tint_color(menuColor, B_DARKEN_1_TINT));
249cb6afcb1SStephan Aßmus 			borders |= BControlLook::B_LEFT_BORDER
250cb6afcb1SStephan Aßmus 				| BControlLook::B_RIGHT_BORDER;
251cb6afcb1SStephan Aßmus 			menu->StrokeLine(frame.LeftBottom(), frame.RightBottom());
252cb6afcb1SStephan Aßmus 			frame.bottom--;
253cb6afcb1SStephan Aßmus 
254cb6afcb1SStephan Aßmus 			be_control_look->DrawMenuBarBackground(menu, frame, frame,
255cb6afcb1SStephan Aßmus 				menuColor, flags, borders);
256cb6afcb1SStephan Aßmus 		} else {
257cb6afcb1SStephan Aßmus 			if (flags & BControlLook::B_ACTIVATED)
258cb6afcb1SStephan Aßmus 				menu->SetHighColor(tint_color(menuColor, B_DARKEN_3_TINT));
259cb6afcb1SStephan Aßmus 			else
260cb6afcb1SStephan Aßmus 				menu->SetHighColor(tint_color(menuColor, 1.22));
261cb6afcb1SStephan Aßmus 			borders |= BControlLook::B_BOTTOM_BORDER;
262cb6afcb1SStephan Aßmus 			menu->StrokeLine(frame.LeftTop(), frame.LeftBottom());
263cb6afcb1SStephan Aßmus 			frame.left++;
264cb6afcb1SStephan Aßmus 
265cb6afcb1SStephan Aßmus 			be_control_look->DrawButtonBackground(menu, frame, frame,
266cb6afcb1SStephan Aßmus 				menuColor, flags, borders);
267cb6afcb1SStephan Aßmus 		}
268cb6afcb1SStephan Aßmus 
269cb6afcb1SStephan Aßmus 		menu->MovePenTo(ContentLocation());
270cb6afcb1SStephan Aßmus 		DrawContent();
271cb6afcb1SStephan Aßmus 		menu->PopState();
272cb6afcb1SStephan Aßmus 		return;
273cb6afcb1SStephan Aßmus 	}
27441281cf3SAxel Dörfler 
27541281cf3SAxel Dörfler 	//	if not selected or being tracked on, fill with gray
276*eddec292SOliver Tappe 	if ((!_IsSelected() && !menu->IsRedrawAfterSticky()) || !canHandle
277cb6afcb1SStephan Aßmus 		|| !IsEnabled()) {
27841281cf3SAxel Dörfler 		frame.InsetBy(1, 1);
27941281cf3SAxel Dörfler 		menu->SetHighColor(menuColor);
28041281cf3SAxel Dörfler 		menu->FillRect(frame);
28141281cf3SAxel Dörfler 	}
28241281cf3SAxel Dörfler 
28341281cf3SAxel Dörfler 	//	draw the gray, unselected item, border
284249a4a18SStephan Aßmus 	if (!_IsSelected() || !IsEnabled()) {
28541281cf3SAxel Dörfler 		rgb_color shadow = tint_color(menuColor, B_DARKEN_1_TINT);
28641281cf3SAxel Dörfler 		rgb_color light = tint_color(menuColor, B_LIGHTEN_2_TINT);
28741281cf3SAxel Dörfler 
28841281cf3SAxel Dörfler 		frame = Frame();
28941281cf3SAxel Dörfler 
29041281cf3SAxel Dörfler 		menu->SetHighColor(shadow);
29141281cf3SAxel Dörfler 		if (fVertical)
29241281cf3SAxel Dörfler 			menu->StrokeLine(frame.LeftBottom(), frame.RightBottom());
29341281cf3SAxel Dörfler 		else
29471bd3ba5SJonas Sundström 			menu->StrokeLine(frame.LeftBottom() + BPoint(1, 0),
29571bd3ba5SJonas Sundström 				frame.RightBottom());
29641281cf3SAxel Dörfler 
29741281cf3SAxel Dörfler 		menu->StrokeLine(frame.RightBottom(), frame.RightTop());
29841281cf3SAxel Dörfler 
29941281cf3SAxel Dörfler 		menu->SetHighColor(light);
30041281cf3SAxel Dörfler 		menu->StrokeLine(frame.RightTop() + BPoint(-1, 0), frame.LeftTop());
30141281cf3SAxel Dörfler 		if (fVertical)
30271bd3ba5SJonas Sundström 			menu->StrokeLine(frame.LeftTop(), frame.LeftBottom()
30371bd3ba5SJonas Sundström 				+ BPoint(0, -1));
30441281cf3SAxel Dörfler 		else
30541281cf3SAxel Dörfler 			menu->StrokeLine(frame.LeftTop(), frame.LeftBottom());
30641281cf3SAxel Dörfler 	}
30741281cf3SAxel Dörfler 
30841281cf3SAxel Dörfler 	//	if selected or being tracked on, fill with the hilite gray color
30971bd3ba5SJonas Sundström 	if (IsEnabled() && _IsSelected() && !menu->IsRedrawAfterSticky()
31071bd3ba5SJonas Sundström 		&& canHandle) {
31141281cf3SAxel Dörfler 		// fill
31241281cf3SAxel Dörfler 		menu->SetHighColor(tint_color(menuColor, B_HIGHLIGHT_BACKGROUND_TINT));
31341281cf3SAxel Dörfler 		menu->FillRect(frame);
31441281cf3SAxel Dörfler 
31541281cf3SAxel Dörfler 		// these continue the dark grey border on the left or top edge
31641281cf3SAxel Dörfler 		menu->SetHighColor(tint_color(menuColor, B_DARKEN_4_TINT));
31741281cf3SAxel Dörfler 		if (fVertical)
31841281cf3SAxel Dörfler 			// dark line at top
31941281cf3SAxel Dörfler 			menu->StrokeLine(frame.LeftTop(), frame.RightTop());
32041281cf3SAxel Dörfler 		else
32141281cf3SAxel Dörfler 			// dark line on the left
32241281cf3SAxel Dörfler 			menu->StrokeLine(frame.LeftTop(), frame.LeftBottom());
32341281cf3SAxel Dörfler 	} else
32441281cf3SAxel Dörfler 		menu->SetLowColor(menuColor);
32541281cf3SAxel Dörfler 
32641281cf3SAxel Dörfler 	menu->MovePenTo(ContentLocation());
32741281cf3SAxel Dörfler 	DrawContent();
32841281cf3SAxel Dörfler 	menu->PopState();
32941281cf3SAxel Dörfler }
33041281cf3SAxel Dörfler 
33141281cf3SAxel Dörfler 
33241281cf3SAxel Dörfler void
33341281cf3SAxel Dörfler TTeamMenuItem::DrawContent()
33441281cf3SAxel Dörfler {
33541281cf3SAxel Dörfler 	BMenu* menu = Menu();
33641281cf3SAxel Dörfler 	if (fIcon) {
33759deaf10SStephan Aßmus 		if (fIcon->ColorSpace() == B_RGBA32) {
33859deaf10SStephan Aßmus 			menu->SetDrawingMode(B_OP_ALPHA);
33959deaf10SStephan Aßmus 			menu->SetBlendingMode(B_PIXEL_ALPHA, B_ALPHA_OVERLAY);
34059deaf10SStephan Aßmus 		} else {
34141281cf3SAxel Dörfler 			menu->SetDrawingMode(B_OP_OVER);
34259deaf10SStephan Aßmus 		}
34341281cf3SAxel Dörfler 		BRect frame(Frame());
34441281cf3SAxel Dörfler 
34541281cf3SAxel Dörfler 		BRect iconBounds(fIcon->Bounds());
34641281cf3SAxel Dörfler 		BRect dstRect(iconBounds);
34741281cf3SAxel Dörfler 		float extra = fVertical ? 0.0f : 1.0f;
34841281cf3SAxel Dörfler 		BPoint contLoc = ContentLocation();
34941281cf3SAxel Dörfler 		dstRect.OffsetTo(BPoint(contLoc.x + kHPad, contLoc.y +
35041281cf3SAxel Dörfler 			((frame.Height() - iconBounds.Height()) / 2) + extra));
35141281cf3SAxel Dörfler 		menu->DrawBitmapAsync(fIcon, dstRect);
35241281cf3SAxel Dörfler 
35341281cf3SAxel Dörfler 		float labelHeight = fLabelAscent + fLabelDescent;
35441281cf3SAxel Dörfler 		BPoint drawLoc = contLoc + BPoint(kHPad, kVPad);
35541281cf3SAxel Dörfler 		drawLoc.x += iconBounds.Width() + kLabelOffset;
35641281cf3SAxel Dörfler 		drawLoc.y = frame.top + ((frame.Height() - labelHeight) / 2) + 1.0f;
35741281cf3SAxel Dörfler 		menu->MovePenTo(drawLoc);
35841281cf3SAxel Dörfler 	}
35941281cf3SAxel Dörfler 
36041281cf3SAxel Dörfler 	//	set the pen to black so that either method will draw in the same color
361cb6afcb1SStephan Aßmus 	//	low color is set in inherited::DrawContent, override makes sure its
362cb6afcb1SStephan Aßmus 	//  what we want
36341281cf3SAxel Dörfler 	if (fDrawLabel) {
364cb6afcb1SStephan Aßmus 		menu->SetDrawingMode(B_OP_OVER);
36541281cf3SAxel Dörfler 		menu->SetHighColor(0, 0, 0);
36641281cf3SAxel Dörfler 
36741281cf3SAxel Dörfler 		//	override the drawing of the content when the item is disabled
36841281cf3SAxel Dörfler 		//	the wrong lowcolor is used when the item is disabled since the
36941281cf3SAxel Dörfler 		//	text color does not change
37041281cf3SAxel Dörfler 		DrawContentLabel();
37141281cf3SAxel Dörfler 	}
37241281cf3SAxel Dörfler 
37341281cf3SAxel Dörfler 	// Draw the expandable icon.
37441281cf3SAxel Dörfler 	TBarView* barView = (static_cast<TBarApp*>(be_app))->BarView();
37541281cf3SAxel Dörfler 	if (fVertical && static_cast<TBarApp*>(be_app)->Settings()->superExpando
37641281cf3SAxel Dörfler 		&& barView->Expando()) {
37741281cf3SAxel Dörfler 		BRect frame(Frame());
37841281cf3SAxel Dörfler 		BRect rect(0, 0, kSwitchWidth, 10);
37941281cf3SAxel Dörfler 		rect.OffsetTo(BPoint(frame.right - rect.Width(),
38041281cf3SAxel Dörfler 			ContentLocation().y + ((frame.Height() - rect.Height()) / 2)));
38141281cf3SAxel Dörfler 
382cb6afcb1SStephan Aßmus 		if (be_control_look != NULL) {
383cb6afcb1SStephan Aßmus 			uint32 arrowDirection = fExpanded
384cb6afcb1SStephan Aßmus 				? BControlLook::B_UP_ARROW : BControlLook::B_DOWN_ARROW;
385cb6afcb1SStephan Aßmus 			be_control_look->DrawArrowShape(menu, rect, rect, menu->LowColor(),
386cb6afcb1SStephan Aßmus 				arrowDirection, 0, B_DARKEN_3_TINT);
387cb6afcb1SStephan Aßmus 		} else {
38841281cf3SAxel Dörfler 			rgb_color outlineColor = {80, 80, 80, 255};
38941281cf3SAxel Dörfler 			rgb_color middleColor = {200, 200, 200, 255};
39041281cf3SAxel Dörfler 
3911407220dSStefano Ceccherini 			menu->SetDrawingMode(B_OP_OVER);
39241281cf3SAxel Dörfler 
39341281cf3SAxel Dörfler 			if (!fExpanded) {
39441281cf3SAxel Dörfler 				menu->BeginLineArray(6);
39541281cf3SAxel Dörfler 
39641281cf3SAxel Dörfler 				menu->AddLine(BPoint(rect.left + 3, rect.top + 1),
39741281cf3SAxel Dörfler 					BPoint(rect.left + 3, rect.bottom - 1), outlineColor);
39841281cf3SAxel Dörfler 				menu->AddLine(BPoint(rect.left + 3, rect.top + 1),
39941281cf3SAxel Dörfler 					BPoint(rect.left + 7, rect.top + 5), outlineColor);
40041281cf3SAxel Dörfler 				menu->AddLine(BPoint(rect.left + 7, rect.top + 5),
40141281cf3SAxel Dörfler 					BPoint(rect.left + 3, rect.bottom - 1), outlineColor);
40241281cf3SAxel Dörfler 
40341281cf3SAxel Dörfler 				menu->AddLine(BPoint(rect.left + 4, rect.top + 3),
40441281cf3SAxel Dörfler 					BPoint(rect.left + 4, rect.bottom - 3), middleColor);
40541281cf3SAxel Dörfler 				menu->AddLine(BPoint(rect.left + 5, rect.top + 4),
40641281cf3SAxel Dörfler 					BPoint(rect.left + 5, rect.bottom - 4), middleColor);
40741281cf3SAxel Dörfler 				menu->AddLine(BPoint(rect.left + 5, rect.top + 5),
40841281cf3SAxel Dörfler 					BPoint(rect.left + 6, rect.top + 5), middleColor);
40941281cf3SAxel Dörfler 				menu->EndLineArray();
41041281cf3SAxel Dörfler 			} else {
41141281cf3SAxel Dörfler 				// expanded state
41241281cf3SAxel Dörfler 
41341281cf3SAxel Dörfler 				menu->BeginLineArray(6);
41441281cf3SAxel Dörfler 				menu->AddLine(BPoint(rect.left + 1, rect.top + 3),
41541281cf3SAxel Dörfler 					BPoint(rect.right - 3, rect.top + 3), outlineColor);
41641281cf3SAxel Dörfler 				menu->AddLine(BPoint(rect.left + 1, rect.top + 3),
41741281cf3SAxel Dörfler 					BPoint(rect.left + 5, rect.top + 7), outlineColor);
41841281cf3SAxel Dörfler 				menu->AddLine(BPoint(rect.left + 5, rect.top + 7),
41941281cf3SAxel Dörfler 					BPoint(rect.right - 3, rect.top + 3), outlineColor);
42041281cf3SAxel Dörfler 
42141281cf3SAxel Dörfler 				menu->AddLine(BPoint(rect.left + 3, rect.top + 4),
42241281cf3SAxel Dörfler 					BPoint(rect.right - 5, rect.top + 4), middleColor);
42341281cf3SAxel Dörfler 				menu->AddLine(BPoint(rect.left + 4, rect.top + 5),
42441281cf3SAxel Dörfler 					BPoint(rect.right - 6, rect.top + 5), middleColor);
42541281cf3SAxel Dörfler 				menu->AddLine(BPoint(rect.left + 5, rect.top + 5),
42641281cf3SAxel Dörfler 					BPoint(rect.left + 5, rect.top + 6), middleColor);
42741281cf3SAxel Dörfler 				menu->EndLineArray();
42841281cf3SAxel Dörfler 			}
42941281cf3SAxel Dörfler 		}
43041281cf3SAxel Dörfler 	}
431cb6afcb1SStephan Aßmus }
43241281cf3SAxel Dörfler 
43341281cf3SAxel Dörfler 
43441281cf3SAxel Dörfler void
43541281cf3SAxel Dörfler TTeamMenuItem::DrawContentLabel()
43641281cf3SAxel Dörfler {
43741281cf3SAxel Dörfler 	BMenu* menu = Menu();
43841281cf3SAxel Dörfler 	menu->MovePenBy(0, fLabelAscent);
43941281cf3SAxel Dörfler 
44041281cf3SAxel Dörfler 	float cachedWidth = menu->StringWidth(Label());
44141281cf3SAxel Dörfler 	if (Submenu() && fVertical)
44241281cf3SAxel Dörfler 		cachedWidth += 18;
44341281cf3SAxel Dörfler 
44441281cf3SAxel Dörfler 	const char* label = Label();
44541281cf3SAxel Dörfler 	char* truncLabel = NULL;
44641281cf3SAxel Dörfler 	float max = 0;
44741281cf3SAxel Dörfler 	if (static_cast<TBarApp*>(be_app)->Settings()->superExpando && fVertical)
44841281cf3SAxel Dörfler 		max = menu->MaxContentWidth() - kSwitchWidth;
44941281cf3SAxel Dörfler 	else
45041281cf3SAxel Dörfler 		max = menu->MaxContentWidth();
45141281cf3SAxel Dörfler 
45241281cf3SAxel Dörfler 	if (max > 0) {
45341281cf3SAxel Dörfler  		BPoint penloc = menu->PenLocation();
45441281cf3SAxel Dörfler 		BRect frame = Frame();
45541281cf3SAxel Dörfler 		float offset = penloc.x - frame.left;
45641281cf3SAxel Dörfler 	 	if (cachedWidth + offset > max) {
45741281cf3SAxel Dörfler 			truncLabel = (char*)malloc(strlen(label) + 4);
45841281cf3SAxel Dörfler 			if (!truncLabel)
45941281cf3SAxel Dörfler 				return;
46041281cf3SAxel Dörfler 			TruncateLabel(max-offset, truncLabel);
46141281cf3SAxel Dörfler 			label = truncLabel;
46241281cf3SAxel Dörfler 		}
46341281cf3SAxel Dörfler 	}
46441281cf3SAxel Dörfler 
46541281cf3SAxel Dörfler 	if (!label)
46641281cf3SAxel Dörfler 		label = Label();
46741281cf3SAxel Dörfler 
46841281cf3SAxel Dörfler 	TBarView* barview = (static_cast<TBarApp*>(be_app))->BarView();
469eaa9af99SStephan Aßmus 	bool canHandle = !barview->Dragging()
470eaa9af99SStephan Aßmus 		|| barview->AppCanHandleTypes(Signature());
471249a4a18SStephan Aßmus 	if (_IsSelected() && IsEnabled() && canHandle)
472eaa9af99SStephan Aßmus 		menu->SetLowColor(tint_color(menu->ViewColor(),
47341281cf3SAxel Dörfler 			B_HIGHLIGHT_BACKGROUND_TINT));
47441281cf3SAxel Dörfler 	else
47541281cf3SAxel Dörfler 		menu->SetLowColor(menu->ViewColor());
47641281cf3SAxel Dörfler 
47741281cf3SAxel Dörfler 	menu->DrawString(label);
47841281cf3SAxel Dörfler 
47941281cf3SAxel Dörfler 	free(truncLabel);
48041281cf3SAxel Dörfler }
48141281cf3SAxel Dörfler 
48241281cf3SAxel Dörfler 
48341281cf3SAxel Dörfler bool
48441281cf3SAxel Dörfler TTeamMenuItem::IsExpanded()
48541281cf3SAxel Dörfler {
48641281cf3SAxel Dörfler 	return fExpanded;
48741281cf3SAxel Dörfler }
48841281cf3SAxel Dörfler 
48941281cf3SAxel Dörfler 
49041281cf3SAxel Dörfler void
49141281cf3SAxel Dörfler TTeamMenuItem::ToggleExpandState(bool resizeWindow)
49241281cf3SAxel Dörfler {
49341281cf3SAxel Dörfler 	fExpanded = !fExpanded;
49441281cf3SAxel Dörfler 
49541281cf3SAxel Dörfler 	if (fExpanded) {
49641281cf3SAxel Dörfler 		// Populate Menu() with the stuff from SubMenu().
49741281cf3SAxel Dörfler 		TWindowMenu* sub = (static_cast<TWindowMenu*>(Submenu()));
49841281cf3SAxel Dörfler 		if (sub) {
49941281cf3SAxel Dörfler 			// force the menu to update it's contents.
500bdfed6c0SAxel Dörfler 			bool locked = sub->LockLooper();
501bdfed6c0SAxel Dörfler 				// if locking the looper failed, the menu is just not visible
502bdfed6c0SAxel Dörfler 			sub->AttachedToWindow();
503bdfed6c0SAxel Dörfler 			if (locked)
504bdfed6c0SAxel Dörfler 				sub->UnlockLooper();
505bdfed6c0SAxel Dörfler 
50641281cf3SAxel Dörfler 			if (sub->CountItems() > 1){
50741281cf3SAxel Dörfler 				TExpandoMenuBar* parent = static_cast<TExpandoMenuBar*>(Menu());
50841281cf3SAxel Dörfler 				int myindex = parent->IndexOf(this) + 1;
50941281cf3SAxel Dörfler 
51041281cf3SAxel Dörfler 				TWindowMenuItem* windowItem = NULL;
51141281cf3SAxel Dörfler 				int childIndex = 0;
51271bd3ba5SJonas Sundström 				int totalChildren = sub->CountItems() - 4;
51371bd3ba5SJonas Sundström 					// hide, show, close, separator.
51441281cf3SAxel Dörfler 				for (; childIndex < totalChildren; childIndex++) {
51571bd3ba5SJonas Sundström 					windowItem = static_cast<TWindowMenuItem*>
51671bd3ba5SJonas Sundström 						(sub->RemoveItem((int32)0));
51741281cf3SAxel Dörfler 					parent->AddItem(windowItem, myindex + childIndex);
51841281cf3SAxel Dörfler 					windowItem->ExpandedItem(true);
51941281cf3SAxel Dörfler 				}
52041281cf3SAxel Dörfler 				sub->SetExpanded(true, myindex + childIndex);
52141281cf3SAxel Dörfler 
52241281cf3SAxel Dörfler 				if (resizeWindow)
52341281cf3SAxel Dörfler 					parent->SizeWindow();
52441281cf3SAxel Dörfler 			} else
52541281cf3SAxel Dörfler 				fExpanded = fExpanded;
52641281cf3SAxel Dörfler 		}
52741281cf3SAxel Dörfler 	} else {
52841281cf3SAxel Dörfler 		// Remove the goodies from the Menu() that should be in the SubMenu();
52941281cf3SAxel Dörfler 		TWindowMenu* sub = static_cast<TWindowMenu*>(Submenu());
53041281cf3SAxel Dörfler 
53141281cf3SAxel Dörfler 		if (sub) {
53241281cf3SAxel Dörfler 			TExpandoMenuBar* parent = static_cast<TExpandoMenuBar*>(Menu());
53341281cf3SAxel Dörfler 
53441281cf3SAxel Dörfler 			TWindowMenuItem* windowItem = NULL;
53541281cf3SAxel Dörfler 			int childIndex = parent->IndexOf(this) + 1;
53671bd3ba5SJonas Sundström 			while (!parent->SubmenuAt(childIndex) && childIndex
53771bd3ba5SJonas Sundström 				< parent->CountItems()) {
53871bd3ba5SJonas Sundström 				windowItem = static_cast<TWindowMenuItem*>
53971bd3ba5SJonas Sundström 					(parent->RemoveItem(childIndex));
54041281cf3SAxel Dörfler 				sub->AddItem(windowItem, 0);
54141281cf3SAxel Dörfler 				windowItem->ExpandedItem(false);
54241281cf3SAxel Dörfler 			}
54341281cf3SAxel Dörfler 			sub->SetExpanded(false, 0);
54441281cf3SAxel Dörfler 
54541281cf3SAxel Dörfler 			if (resizeWindow)
54641281cf3SAxel Dörfler 				parent->SizeWindow();
54741281cf3SAxel Dörfler 		} else
54841281cf3SAxel Dörfler 			fExpanded = fExpanded;
54941281cf3SAxel Dörfler 	}
55041281cf3SAxel Dörfler }
55141281cf3SAxel Dörfler 
55241281cf3SAxel Dörfler 
55341281cf3SAxel Dörfler TWindowMenuItem*
55441281cf3SAxel Dörfler TTeamMenuItem::ExpandedWindowItem(int32 id)
55541281cf3SAxel Dörfler {
55641281cf3SAxel Dörfler 	if (!fExpanded)	// Paranoia
55741281cf3SAxel Dörfler 		return NULL;
55841281cf3SAxel Dörfler 
55941281cf3SAxel Dörfler 	TExpandoMenuBar* parent = static_cast<TExpandoMenuBar*>(Menu());
56041281cf3SAxel Dörfler 	int childIndex = parent->IndexOf(this) + 1;
56141281cf3SAxel Dörfler 
56271bd3ba5SJonas Sundström 	while (!parent->SubmenuAt(childIndex)
56371bd3ba5SJonas Sundström 		&& childIndex < parent->CountItems()) {
56471bd3ba5SJonas Sundström 		TWindowMenuItem* item
56571bd3ba5SJonas Sundström 			= static_cast<TWindowMenuItem*>(parent->ItemAt(childIndex));
56641281cf3SAxel Dörfler 		if (item->ID() == id)
56741281cf3SAxel Dörfler 			return item;
56841281cf3SAxel Dörfler 
56941281cf3SAxel Dörfler 		childIndex++;
57041281cf3SAxel Dörfler 	}
57141281cf3SAxel Dörfler 	return NULL;
57241281cf3SAxel Dörfler }
57341281cf3SAxel Dörfler 
57441281cf3SAxel Dörfler 
57541281cf3SAxel Dörfler BRect
57641281cf3SAxel Dörfler TTeamMenuItem::ExpanderBounds() const
57741281cf3SAxel Dörfler {
57841281cf3SAxel Dörfler 	BRect bounds(Frame());
57941281cf3SAxel Dörfler 	bounds.left = bounds.right - kSwitchWidth;
58041281cf3SAxel Dörfler 	return bounds;
58141281cf3SAxel Dörfler }
58241281cf3SAxel Dörfler 
583249a4a18SStephan Aßmus 
584249a4a18SStephan Aßmus bool
585249a4a18SStephan Aßmus TTeamMenuItem::_IsSelected() const
586249a4a18SStephan Aßmus {
587249a4a18SStephan Aßmus 	return IsSelected() || fOverriddenSelected;
588249a4a18SStephan Aßmus }
589249a4a18SStephan Aßmus 
590