xref: /haiku/src/apps/deskbar/TeamMenuItem.cpp (revision eaa9af9937ed538a6e175852bee9f22a2c20a814)
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 
3741281cf3SAxel Dörfler #include <string.h>
3841281cf3SAxel Dörfler #include <stdio.h>
39136d40a8SStefano Ceccherini #include <stdlib.h>
40136d40a8SStefano Ceccherini 
4141281cf3SAxel Dörfler #include <Bitmap.h>
4241281cf3SAxel Dörfler #include <Font.h>
4341281cf3SAxel Dörfler #include <Region.h>
4441281cf3SAxel Dörfler #include <Roster.h>
4541281cf3SAxel Dörfler #include <Resources.h>
4641281cf3SAxel Dörfler 
4741281cf3SAxel Dörfler #include "BarApp.h"
4841281cf3SAxel Dörfler #include "BarMenuBar.h"
4941281cf3SAxel Dörfler #include "ExpandoMenuBar.h"
5041281cf3SAxel Dörfler #include "ResourceSet.h"
5141281cf3SAxel Dörfler #include "ShowHideMenuItem.h"
5241281cf3SAxel Dörfler #include "TeamMenu.h"
5341281cf3SAxel Dörfler #include "TeamMenuItem.h"
5441281cf3SAxel Dörfler #include "WindowMenu.h"
5541281cf3SAxel Dörfler #include "WindowMenuItem.h"
5641281cf3SAxel Dörfler 
5741281cf3SAxel Dörfler 
5841281cf3SAxel Dörfler const float kHPad = 8.0f;
5941281cf3SAxel Dörfler const float kVPad = 1.0f;
6041281cf3SAxel Dörfler const float kLabelOffset = 8.0f;
6141281cf3SAxel Dörfler const float kSwitchWidth = 12;
6241281cf3SAxel Dörfler 
6341281cf3SAxel Dörfler 
6441281cf3SAxel Dörfler TTeamMenuItem::TTeamMenuItem(BList *team, BBitmap *icon, char *name, char *sig,
6541281cf3SAxel Dörfler 	float width, float height, bool drawLabel, bool vertical)
6641281cf3SAxel Dörfler 	:	BMenuItem(new TWindowMenu(team, sig))
6741281cf3SAxel Dörfler {
6841281cf3SAxel Dörfler 	InitData(team, icon, name, sig, width, height, drawLabel, vertical);
6941281cf3SAxel Dörfler }
7041281cf3SAxel Dörfler 
7141281cf3SAxel Dörfler 
7241281cf3SAxel Dörfler TTeamMenuItem::TTeamMenuItem(float width,float height,bool vertical)
7341281cf3SAxel Dörfler 	:	BMenuItem("", NULL)
7441281cf3SAxel Dörfler {
7541281cf3SAxel Dörfler 	InitData(NULL, NULL, strdup(""), strdup(""), width, height, false, vertical);
7641281cf3SAxel Dörfler }
7741281cf3SAxel Dörfler 
7841281cf3SAxel Dörfler 
7941281cf3SAxel Dörfler void
8041281cf3SAxel Dörfler TTeamMenuItem::InitData(BList *team, BBitmap *icon, char *name, char *sig,
8141281cf3SAxel Dörfler 	float width, float height, bool drawLabel, bool vertical)
8241281cf3SAxel Dörfler {
8341281cf3SAxel Dörfler 	fTeam = team;
8441281cf3SAxel Dörfler 	fIcon = icon;
8541281cf3SAxel Dörfler 	fName = name;
8641281cf3SAxel Dörfler 	fSig = sig;
8741281cf3SAxel Dörfler 	if (fName == NULL) {
88136d40a8SStefano Ceccherini 		char temp[32];
89136d40a8SStefano Ceccherini 		snprintf(temp, sizeof(temp), "team %ld", (int32)team->ItemAt(0));
90136d40a8SStefano Ceccherini 		fName = strdup(temp);
9141281cf3SAxel Dörfler 	}
9241281cf3SAxel Dörfler 
93136d40a8SStefano Ceccherini 	SetLabel(fName);
94136d40a8SStefano Ceccherini 
9541281cf3SAxel Dörfler 	BFont font(be_plain_font);
9641281cf3SAxel Dörfler 	fLabelWidth = ceilf(font.StringWidth(fName));
9741281cf3SAxel Dörfler 	font_height fontHeight;
9841281cf3SAxel Dörfler 	font.GetHeight(&fontHeight);
9941281cf3SAxel Dörfler 	fLabelAscent = ceilf(fontHeight.ascent);
10041281cf3SAxel Dörfler 	fLabelDescent = ceilf(fontHeight.descent + fontHeight.leading);
10141281cf3SAxel Dörfler 
10241281cf3SAxel Dörfler 	fOverrideWidth = width;
10341281cf3SAxel Dörfler 	fOverrideHeight = height;
10441281cf3SAxel Dörfler 
10541281cf3SAxel Dörfler 	fDrawLabel = drawLabel;
10641281cf3SAxel Dörfler 	fVertical = vertical;
10741281cf3SAxel Dörfler 
10841281cf3SAxel Dörfler 	fExpanded = false;
10941281cf3SAxel Dörfler }
11041281cf3SAxel Dörfler 
11141281cf3SAxel Dörfler 
11241281cf3SAxel Dörfler TTeamMenuItem::~TTeamMenuItem()
11341281cf3SAxel Dörfler {
11441281cf3SAxel Dörfler 	delete fTeam;
11541281cf3SAxel Dörfler 	delete fIcon;
11641281cf3SAxel Dörfler 	free(fName);
11741281cf3SAxel Dörfler 	free(fSig);
11841281cf3SAxel Dörfler }
11941281cf3SAxel Dörfler 
12041281cf3SAxel Dörfler 
12141281cf3SAxel Dörfler status_t
12241281cf3SAxel Dörfler TTeamMenuItem::Invoke(BMessage *message)
12341281cf3SAxel Dörfler {
12441281cf3SAxel Dörfler 	if ((static_cast<TBarApp *>(be_app))->BarView()->InvokeItem(Signature()))
12541281cf3SAxel Dörfler 		//	handles drop on application
12641281cf3SAxel Dörfler 		return B_OK;
12741281cf3SAxel Dörfler 
12841281cf3SAxel Dörfler 	//	if the app could not handle the drag message
12941281cf3SAxel Dörfler 	//	and we were dragging, then kill the drag
13041281cf3SAxel Dörfler 	//	should never get here, disabled item will not invoke
13141281cf3SAxel Dörfler 	TBarView *barview = (static_cast<TBarApp *>(be_app))->BarView();
13241281cf3SAxel Dörfler 	if (barview && barview->Dragging())
13341281cf3SAxel Dörfler 		barview->DragStop();
13441281cf3SAxel Dörfler 
13541281cf3SAxel Dörfler 	// bring to front or minimize shortcuts
13641281cf3SAxel Dörfler 	uint32 mods = modifiers();
13741281cf3SAxel Dörfler 	if (mods & B_CONTROL_KEY)
13841281cf3SAxel Dörfler 		TShowHideMenuItem::TeamShowHideCommon((mods & B_SHIFT_KEY)
13941281cf3SAxel Dörfler 				? B_MINIMIZE_WINDOW : B_BRING_TO_FRONT, Teams());
14041281cf3SAxel Dörfler 
14141281cf3SAxel Dörfler 	return BMenuItem::Invoke(message);
14241281cf3SAxel Dörfler }
14341281cf3SAxel Dörfler 
14441281cf3SAxel Dörfler 
14541281cf3SAxel Dörfler void
14641281cf3SAxel Dörfler TTeamMenuItem::SetOverrideWidth(float width)
14741281cf3SAxel Dörfler {
14841281cf3SAxel Dörfler 	fOverrideWidth = width;
14941281cf3SAxel Dörfler }
15041281cf3SAxel Dörfler 
15141281cf3SAxel Dörfler 
15241281cf3SAxel Dörfler void
15341281cf3SAxel Dörfler TTeamMenuItem::SetOverrideHeight(float height)
15441281cf3SAxel Dörfler {
15541281cf3SAxel Dörfler 	fOverrideHeight = height;
15641281cf3SAxel Dörfler }
15741281cf3SAxel Dörfler 
15841281cf3SAxel Dörfler 
15941281cf3SAxel Dörfler float
16041281cf3SAxel Dörfler TTeamMenuItem::LabelWidth() const
16141281cf3SAxel Dörfler {
16241281cf3SAxel Dörfler 	return fLabelWidth;
16341281cf3SAxel Dörfler }
16441281cf3SAxel Dörfler 
16541281cf3SAxel Dörfler 
16641281cf3SAxel Dörfler BList *
16741281cf3SAxel Dörfler TTeamMenuItem::Teams() const
16841281cf3SAxel Dörfler {
16941281cf3SAxel Dörfler 	return fTeam;
17041281cf3SAxel Dörfler }
17141281cf3SAxel Dörfler 
17241281cf3SAxel Dörfler 
17341281cf3SAxel Dörfler const char *
17441281cf3SAxel Dörfler TTeamMenuItem::Signature() const
17541281cf3SAxel Dörfler {
17641281cf3SAxel Dörfler 	return fSig;
17741281cf3SAxel Dörfler }
17841281cf3SAxel Dörfler 
17941281cf3SAxel Dörfler 
18041281cf3SAxel Dörfler const char *
18141281cf3SAxel Dörfler TTeamMenuItem::Name() const
18241281cf3SAxel Dörfler {
18341281cf3SAxel Dörfler 	return fName;
18441281cf3SAxel Dörfler }
18541281cf3SAxel Dörfler 
18641281cf3SAxel Dörfler 
18741281cf3SAxel Dörfler void
18841281cf3SAxel Dörfler TTeamMenuItem::GetContentSize(float *width, float *height)
18941281cf3SAxel Dörfler {
19041281cf3SAxel Dörfler 	BRect iconBounds;
19141281cf3SAxel Dörfler 
19241281cf3SAxel Dörfler 	if (fIcon)
19341281cf3SAxel Dörfler 		iconBounds = fIcon->Bounds();
19441281cf3SAxel Dörfler 	else
19541281cf3SAxel Dörfler 		iconBounds = BRect(0, 0, 15, 15);
19641281cf3SAxel Dörfler 
19741281cf3SAxel Dörfler 	BMenuItem::GetContentSize(width, height);
19841281cf3SAxel Dörfler 
19941281cf3SAxel Dörfler 	if (fOverrideWidth != -1.0f)
20041281cf3SAxel Dörfler 		*width = fOverrideWidth;
20141281cf3SAxel Dörfler 	else
20241281cf3SAxel Dörfler 		*width = kHPad + iconBounds.Width() + kLabelOffset + fLabelWidth + kHPad + 20;
20341281cf3SAxel Dörfler 
20441281cf3SAxel Dörfler 	if (fOverrideHeight != -1.0f)
20541281cf3SAxel Dörfler 		*height = fOverrideHeight;
20641281cf3SAxel Dörfler 	else {
20741281cf3SAxel Dörfler 		*height = iconBounds.Height();
20841281cf3SAxel Dörfler 		float labelHeight = fLabelAscent + fLabelDescent;
20941281cf3SAxel Dörfler 		if (labelHeight > *height)
21041281cf3SAxel Dörfler 			*height = labelHeight;
21141281cf3SAxel Dörfler 		*height += (kVPad * 2) + 2;
21241281cf3SAxel Dörfler 	}
21341281cf3SAxel Dörfler 	*height += 2;
21441281cf3SAxel Dörfler }
21541281cf3SAxel Dörfler 
21641281cf3SAxel Dörfler 
21741281cf3SAxel Dörfler void
21841281cf3SAxel Dörfler TTeamMenuItem::Draw()
21941281cf3SAxel Dörfler {
22041281cf3SAxel Dörfler 	BRect frame(Frame());
22141281cf3SAxel Dörfler 	BMenu *menu = Menu();
22241281cf3SAxel Dörfler 	menu->PushState();
223*eaa9af99SStephan Aßmus 	rgb_color menuColor = menu->ViewColor();
22441281cf3SAxel Dörfler 
22541281cf3SAxel Dörfler 	//	if not selected or being tracked on, fill with gray
22641281cf3SAxel Dörfler 	TBarView *barview = (static_cast<TBarApp *>(be_app))->BarView();
22741281cf3SAxel Dörfler 	bool canHandle = !barview->Dragging() || barview->AppCanHandleTypes(Signature());
22841281cf3SAxel Dörfler 	if (!IsSelected() && !menu->IsRedrawAfterSticky() || !canHandle || !IsEnabled()) {
22941281cf3SAxel Dörfler 		frame.InsetBy(1, 1);
23041281cf3SAxel Dörfler 		menu->SetHighColor(menuColor);
23141281cf3SAxel Dörfler 		menu->FillRect(frame);
23241281cf3SAxel Dörfler 	}
23341281cf3SAxel Dörfler 
23441281cf3SAxel Dörfler 	//	draw the gray, unselected item, border
23541281cf3SAxel Dörfler 	if (!IsSelected() || !IsEnabled()) {
23641281cf3SAxel Dörfler 		rgb_color shadow = tint_color(menuColor, B_DARKEN_1_TINT);
23741281cf3SAxel Dörfler 		rgb_color light = tint_color(menuColor, B_LIGHTEN_2_TINT);
23841281cf3SAxel Dörfler 
23941281cf3SAxel Dörfler 		frame = Frame();
24041281cf3SAxel Dörfler 		if (!fVertical)
24141281cf3SAxel Dörfler 			frame.top += 1;
24241281cf3SAxel Dörfler 
24341281cf3SAxel Dörfler 		menu->SetHighColor(shadow);
24441281cf3SAxel Dörfler 		if (fVertical)
24541281cf3SAxel Dörfler 			menu->StrokeLine(frame.LeftBottom(), frame.RightBottom());
24641281cf3SAxel Dörfler 		else
24741281cf3SAxel Dörfler 			menu->StrokeLine(frame.LeftBottom() + BPoint(1, 0), frame.RightBottom());
24841281cf3SAxel Dörfler 
24941281cf3SAxel Dörfler 		menu->StrokeLine(frame.RightBottom(), frame.RightTop());
25041281cf3SAxel Dörfler 
25141281cf3SAxel Dörfler 		menu->SetHighColor(light);
25241281cf3SAxel Dörfler 		menu->StrokeLine(frame.RightTop() + BPoint(-1, 0), frame.LeftTop());
25341281cf3SAxel Dörfler 		if (fVertical)
25441281cf3SAxel Dörfler 			menu->StrokeLine(frame.LeftTop(), frame.LeftBottom() + BPoint(0, -1));
25541281cf3SAxel Dörfler 		else
25641281cf3SAxel Dörfler 			menu->StrokeLine(frame.LeftTop(), frame.LeftBottom());
25741281cf3SAxel Dörfler 	}
25841281cf3SAxel Dörfler 
25941281cf3SAxel Dörfler 	//	if selected or being tracked on, fill with the hilite gray color
26041281cf3SAxel Dörfler 	if (IsEnabled() && IsSelected() && !menu->IsRedrawAfterSticky() && canHandle) {
26141281cf3SAxel Dörfler 		// fill
26241281cf3SAxel Dörfler 		menu->SetHighColor(tint_color(menuColor, B_HIGHLIGHT_BACKGROUND_TINT));
26341281cf3SAxel Dörfler 		menu->FillRect(frame);
26441281cf3SAxel Dörfler 
26541281cf3SAxel Dörfler 		// these continue the dark grey border on the left or top edge
26641281cf3SAxel Dörfler 		menu->SetHighColor(tint_color(menuColor, B_DARKEN_4_TINT));
26741281cf3SAxel Dörfler 		if (fVertical)
26841281cf3SAxel Dörfler 			// dark line at top
26941281cf3SAxel Dörfler 			menu->StrokeLine(frame.LeftTop(), frame.RightTop());
27041281cf3SAxel Dörfler 		else
27141281cf3SAxel Dörfler 			// dark line on the left
27241281cf3SAxel Dörfler 			menu->StrokeLine(frame.LeftTop(), frame.LeftBottom());
27341281cf3SAxel Dörfler 	} else
27441281cf3SAxel Dörfler 		menu->SetLowColor(menuColor);
27541281cf3SAxel Dörfler 
27641281cf3SAxel Dörfler 	menu->MovePenTo(ContentLocation());
27741281cf3SAxel Dörfler 	DrawContent();
27841281cf3SAxel Dörfler 	menu->PopState();
27941281cf3SAxel Dörfler }
28041281cf3SAxel Dörfler 
28141281cf3SAxel Dörfler 
28241281cf3SAxel Dörfler void
28341281cf3SAxel Dörfler TTeamMenuItem::DrawContent()
28441281cf3SAxel Dörfler {
28541281cf3SAxel Dörfler 	BMenu *menu = Menu();
28641281cf3SAxel Dörfler 	if (fIcon) {
28759deaf10SStephan Aßmus 		if (fIcon->ColorSpace() == B_RGBA32) {
28859deaf10SStephan Aßmus 			menu->SetDrawingMode(B_OP_ALPHA);
28959deaf10SStephan Aßmus 			menu->SetBlendingMode(B_PIXEL_ALPHA, B_ALPHA_OVERLAY);
29059deaf10SStephan Aßmus 		} else {
29141281cf3SAxel Dörfler 			menu->SetDrawingMode(B_OP_OVER);
29259deaf10SStephan Aßmus 		}
29341281cf3SAxel Dörfler 		BRect frame(Frame());
29441281cf3SAxel Dörfler 
29541281cf3SAxel Dörfler 		if (!fVertical)
29641281cf3SAxel Dörfler 			frame.top += 1;
29741281cf3SAxel Dörfler 
29841281cf3SAxel Dörfler 		BRect iconBounds(fIcon->Bounds());
29941281cf3SAxel Dörfler 		BRect dstRect(iconBounds);
30041281cf3SAxel Dörfler 		float extra = fVertical ? 0.0f : 1.0f;
30141281cf3SAxel Dörfler 		BPoint contLoc = ContentLocation();
30241281cf3SAxel Dörfler 		dstRect.OffsetTo(BPoint(contLoc.x + kHPad, contLoc.y +
30341281cf3SAxel Dörfler 			((frame.Height() - iconBounds.Height()) / 2) + extra));
30441281cf3SAxel Dörfler 		menu->DrawBitmapAsync(fIcon, dstRect);
30541281cf3SAxel Dörfler 
30641281cf3SAxel Dörfler 		menu->SetDrawingMode(B_OP_COPY);
30741281cf3SAxel Dörfler 
30841281cf3SAxel Dörfler 		float labelHeight = fLabelAscent + fLabelDescent;
30941281cf3SAxel Dörfler 		BPoint drawLoc = contLoc + BPoint(kHPad, kVPad);
31041281cf3SAxel Dörfler 		drawLoc.x += iconBounds.Width() + kLabelOffset;
31141281cf3SAxel Dörfler 		drawLoc.y = frame.top + ((frame.Height() - labelHeight) / 2) + 1.0f;
31241281cf3SAxel Dörfler 		menu->MovePenTo(drawLoc);
31341281cf3SAxel Dörfler 	}
31441281cf3SAxel Dörfler 
31541281cf3SAxel Dörfler 	//	set the pen to black so that either method will draw in the same color
31641281cf3SAxel Dörfler 	//	low color is set in inherited::DrawContent, override makes sure its what we want
31741281cf3SAxel Dörfler 	if (fDrawLabel) {
31841281cf3SAxel Dörfler 		menu->SetHighColor(0, 0, 0);
31941281cf3SAxel Dörfler 
32041281cf3SAxel Dörfler 		//	override the drawing of the content when the item is disabled
32141281cf3SAxel Dörfler 		//	the wrong lowcolor is used when the item is disabled since the
32241281cf3SAxel Dörfler 		//	text color does not change
32341281cf3SAxel Dörfler 		DrawContentLabel();
32441281cf3SAxel Dörfler 	}
32541281cf3SAxel Dörfler 
32641281cf3SAxel Dörfler 	// Draw the expandable icon.
32741281cf3SAxel Dörfler 	TBarView *barView = (static_cast<TBarApp *>(be_app))->BarView();
32841281cf3SAxel Dörfler 	if (fVertical && static_cast<TBarApp *>(be_app)->Settings()->superExpando
32941281cf3SAxel Dörfler 		&& barView->Expando()) {
33041281cf3SAxel Dörfler 		BRect frame(Frame());
33141281cf3SAxel Dörfler 		BRect rect(0, 0, kSwitchWidth, 10);
33241281cf3SAxel Dörfler 		rect.OffsetTo(BPoint(frame.right - rect.Width(),
33341281cf3SAxel Dörfler 			ContentLocation().y + ((frame.Height() - rect.Height()) / 2)));
33441281cf3SAxel Dörfler 
33541281cf3SAxel Dörfler 		rgb_color outlineColor = {80, 80, 80, 255};
33641281cf3SAxel Dörfler 		rgb_color middleColor = {200, 200, 200, 255};
33741281cf3SAxel Dörfler 
3381407220dSStefano Ceccherini 		menu->SetDrawingMode(B_OP_OVER);
33941281cf3SAxel Dörfler 
34041281cf3SAxel Dörfler 		if (!fExpanded) {
34141281cf3SAxel Dörfler 			menu->BeginLineArray(6);
34241281cf3SAxel Dörfler 
34341281cf3SAxel Dörfler 			menu->AddLine(BPoint(rect.left + 3, rect.top + 1),
34441281cf3SAxel Dörfler 				BPoint(rect.left + 3, rect.bottom - 1), outlineColor);
34541281cf3SAxel Dörfler 			menu->AddLine(BPoint(rect.left + 3, rect.top + 1),
34641281cf3SAxel Dörfler 				BPoint(rect.left + 7, rect.top + 5), outlineColor);
34741281cf3SAxel Dörfler 			menu->AddLine(BPoint(rect.left + 7, rect.top + 5),
34841281cf3SAxel Dörfler 				BPoint(rect.left + 3, rect.bottom - 1), outlineColor);
34941281cf3SAxel Dörfler 
35041281cf3SAxel Dörfler 			menu->AddLine(BPoint(rect.left + 4, rect.top + 3),
35141281cf3SAxel Dörfler 				BPoint(rect.left + 4, rect.bottom - 3), middleColor);
35241281cf3SAxel Dörfler 			menu->AddLine(BPoint(rect.left + 5, rect.top + 4),
35341281cf3SAxel Dörfler 				BPoint(rect.left + 5, rect.bottom - 4), middleColor);
35441281cf3SAxel Dörfler 			menu->AddLine(BPoint(rect.left + 5, rect.top + 5),
35541281cf3SAxel Dörfler 				BPoint(rect.left + 6, rect.top + 5), middleColor);
35641281cf3SAxel Dörfler 			menu->EndLineArray();
35741281cf3SAxel Dörfler 		} else {
35841281cf3SAxel Dörfler 			// expanded state
35941281cf3SAxel Dörfler 
36041281cf3SAxel Dörfler 			menu->BeginLineArray(6);
36141281cf3SAxel Dörfler 			menu->AddLine(BPoint(rect.left + 1, rect.top + 3),
36241281cf3SAxel Dörfler 				BPoint(rect.right - 3, rect.top + 3), outlineColor);
36341281cf3SAxel Dörfler 			menu->AddLine(BPoint(rect.left + 1, rect.top + 3),
36441281cf3SAxel Dörfler 				BPoint(rect.left + 5, rect.top + 7), outlineColor);
36541281cf3SAxel Dörfler 			menu->AddLine(BPoint(rect.left + 5, rect.top + 7),
36641281cf3SAxel Dörfler 				BPoint(rect.right - 3, rect.top + 3), outlineColor);
36741281cf3SAxel Dörfler 
36841281cf3SAxel Dörfler 			menu->AddLine(BPoint(rect.left + 3, rect.top + 4),
36941281cf3SAxel Dörfler 				BPoint(rect.right - 5, rect.top + 4), middleColor);
37041281cf3SAxel Dörfler 			menu->AddLine(BPoint(rect.left + 4, rect.top + 5),
37141281cf3SAxel Dörfler 				BPoint(rect.right - 6, rect.top + 5), middleColor);
37241281cf3SAxel Dörfler 			menu->AddLine(BPoint(rect.left + 5, rect.top + 5),
37341281cf3SAxel Dörfler 				BPoint(rect.left + 5, rect.top + 6), middleColor);
37441281cf3SAxel Dörfler 			menu->EndLineArray();
37541281cf3SAxel Dörfler 		}
37641281cf3SAxel Dörfler 	}
37741281cf3SAxel Dörfler }
37841281cf3SAxel Dörfler 
37941281cf3SAxel Dörfler 
38041281cf3SAxel Dörfler void
38141281cf3SAxel Dörfler TTeamMenuItem::DrawContentLabel()
38241281cf3SAxel Dörfler {
38341281cf3SAxel Dörfler 	BMenu *menu = Menu();
38441281cf3SAxel Dörfler 	menu->MovePenBy(0, fLabelAscent);
38541281cf3SAxel Dörfler 	menu->SetDrawingMode(B_OP_COPY);
38641281cf3SAxel Dörfler 
38741281cf3SAxel Dörfler 	float cachedWidth = menu->StringWidth(Label());
38841281cf3SAxel Dörfler 	if (Submenu() && fVertical)
38941281cf3SAxel Dörfler 		cachedWidth += 18;
39041281cf3SAxel Dörfler 
39141281cf3SAxel Dörfler 	const char *label = Label();
39241281cf3SAxel Dörfler 	char *truncLabel = NULL;
39341281cf3SAxel Dörfler 	float max = 0;
39441281cf3SAxel Dörfler 	if (static_cast<TBarApp *>(be_app)->Settings()->superExpando && fVertical)
39541281cf3SAxel Dörfler 		max = menu->MaxContentWidth() - kSwitchWidth;
39641281cf3SAxel Dörfler 	else
39741281cf3SAxel Dörfler 		max = menu->MaxContentWidth();
39841281cf3SAxel Dörfler 
39941281cf3SAxel Dörfler 	if (max > 0) {
40041281cf3SAxel Dörfler  		BPoint penloc = menu->PenLocation();
40141281cf3SAxel Dörfler 		BRect frame = Frame();
40241281cf3SAxel Dörfler 		float offset = penloc.x - frame.left;
40341281cf3SAxel Dörfler 	 	if (cachedWidth + offset > max) {
40441281cf3SAxel Dörfler 			truncLabel = (char *)malloc(strlen(label) + 4);
40541281cf3SAxel Dörfler 			if (!truncLabel)
40641281cf3SAxel Dörfler 				return;
40741281cf3SAxel Dörfler 			TruncateLabel(max-offset, truncLabel);
40841281cf3SAxel Dörfler 			label = truncLabel;
40941281cf3SAxel Dörfler 		}
41041281cf3SAxel Dörfler 	}
41141281cf3SAxel Dörfler 
41241281cf3SAxel Dörfler 	if (!label)
41341281cf3SAxel Dörfler 		label = Label();
41441281cf3SAxel Dörfler 
41541281cf3SAxel Dörfler 	TBarView *barview = (static_cast<TBarApp *>(be_app))->BarView();
416*eaa9af99SStephan Aßmus 	bool canHandle = !barview->Dragging()
417*eaa9af99SStephan Aßmus 		|| barview->AppCanHandleTypes(Signature());
41841281cf3SAxel Dörfler 	if (IsSelected() && IsEnabled() && canHandle)
419*eaa9af99SStephan Aßmus 		menu->SetLowColor(tint_color(menu->ViewColor(),
42041281cf3SAxel Dörfler 			B_HIGHLIGHT_BACKGROUND_TINT));
42141281cf3SAxel Dörfler 	else
42241281cf3SAxel Dörfler 		menu->SetLowColor(menu->ViewColor());
42341281cf3SAxel Dörfler 
42441281cf3SAxel Dörfler 	menu->DrawString(label);
42541281cf3SAxel Dörfler 
42641281cf3SAxel Dörfler 	free(truncLabel);
42741281cf3SAxel Dörfler }
42841281cf3SAxel Dörfler 
42941281cf3SAxel Dörfler 
43041281cf3SAxel Dörfler bool
43141281cf3SAxel Dörfler TTeamMenuItem::IsExpanded()
43241281cf3SAxel Dörfler {
43341281cf3SAxel Dörfler 	return fExpanded;
43441281cf3SAxel Dörfler }
43541281cf3SAxel Dörfler 
43641281cf3SAxel Dörfler 
43741281cf3SAxel Dörfler void
43841281cf3SAxel Dörfler TTeamMenuItem::ToggleExpandState(bool resizeWindow)
43941281cf3SAxel Dörfler {
44041281cf3SAxel Dörfler 	fExpanded = !fExpanded;
44141281cf3SAxel Dörfler 
44241281cf3SAxel Dörfler 	if (fExpanded) {
44341281cf3SAxel Dörfler 		// Populate Menu() with the stuff from SubMenu().
44441281cf3SAxel Dörfler 		TWindowMenu *sub = (static_cast<TWindowMenu *>(Submenu()));
44541281cf3SAxel Dörfler 		if (sub) {
44641281cf3SAxel Dörfler 			// force the menu to update it's contents.
447bdfed6c0SAxel Dörfler 			bool locked = sub->LockLooper();
448bdfed6c0SAxel Dörfler 				// if locking the looper failed, the menu is just not visible
449bdfed6c0SAxel Dörfler 			sub->AttachedToWindow();
450bdfed6c0SAxel Dörfler 			if (locked)
451bdfed6c0SAxel Dörfler 				sub->UnlockLooper();
452bdfed6c0SAxel Dörfler 
45341281cf3SAxel Dörfler 			if (sub->CountItems() > 1){
45441281cf3SAxel Dörfler 				TExpandoMenuBar *parent = static_cast<TExpandoMenuBar *>(Menu());
45541281cf3SAxel Dörfler 				int myindex = parent->IndexOf(this) + 1;
45641281cf3SAxel Dörfler 
45741281cf3SAxel Dörfler 				TWindowMenuItem *windowItem = NULL;
45841281cf3SAxel Dörfler 				int childIndex = 0;
45941281cf3SAxel Dörfler 				int totalChildren = sub->CountItems() - 4; // hide, show, close, separator.
46041281cf3SAxel Dörfler 				for (; childIndex < totalChildren; childIndex++) {
46141281cf3SAxel Dörfler 					windowItem = static_cast<TWindowMenuItem *>(sub->RemoveItem((int32)0));
46241281cf3SAxel Dörfler 					parent->AddItem(windowItem, myindex + childIndex);
46341281cf3SAxel Dörfler 					windowItem->ExpandedItem(true);
46441281cf3SAxel Dörfler 				}
46541281cf3SAxel Dörfler 				sub->SetExpanded(true, myindex + childIndex);
46641281cf3SAxel Dörfler 
46741281cf3SAxel Dörfler 				if (resizeWindow)
46841281cf3SAxel Dörfler 					parent->SizeWindow();
46941281cf3SAxel Dörfler 			} else
47041281cf3SAxel Dörfler 				fExpanded = fExpanded;
47141281cf3SAxel Dörfler 		}
47241281cf3SAxel Dörfler 	} else {
47341281cf3SAxel Dörfler 		// Remove the goodies from the Menu() that should be in the SubMenu();
47441281cf3SAxel Dörfler 		TWindowMenu *sub = static_cast<TWindowMenu *>(Submenu());
47541281cf3SAxel Dörfler 
47641281cf3SAxel Dörfler 		if (sub) {
47741281cf3SAxel Dörfler 			TExpandoMenuBar *parent = static_cast<TExpandoMenuBar *>(Menu());
47841281cf3SAxel Dörfler 
47941281cf3SAxel Dörfler 			TWindowMenuItem *windowItem = NULL;
48041281cf3SAxel Dörfler 			int childIndex = parent->IndexOf(this) + 1;
48141281cf3SAxel Dörfler 			while (!parent->SubmenuAt(childIndex) && childIndex < parent->CountItems()) {
48241281cf3SAxel Dörfler 				windowItem = static_cast<TWindowMenuItem *>(parent->RemoveItem(childIndex));
48341281cf3SAxel Dörfler 				sub->AddItem(windowItem, 0);
48441281cf3SAxel Dörfler 				windowItem->ExpandedItem(false);
48541281cf3SAxel Dörfler 			}
48641281cf3SAxel Dörfler 			sub->SetExpanded(false, 0);
48741281cf3SAxel Dörfler 
48841281cf3SAxel Dörfler 			if (resizeWindow)
48941281cf3SAxel Dörfler 				parent->SizeWindow();
49041281cf3SAxel Dörfler 		} else
49141281cf3SAxel Dörfler 			fExpanded = fExpanded;
49241281cf3SAxel Dörfler 	}
49341281cf3SAxel Dörfler }
49441281cf3SAxel Dörfler 
49541281cf3SAxel Dörfler 
49641281cf3SAxel Dörfler TWindowMenuItem*
49741281cf3SAxel Dörfler TTeamMenuItem::ExpandedWindowItem(int32 id)
49841281cf3SAxel Dörfler {
49941281cf3SAxel Dörfler 	if (!fExpanded)	// Paranoia
50041281cf3SAxel Dörfler 		return NULL;
50141281cf3SAxel Dörfler 
50241281cf3SAxel Dörfler 	TExpandoMenuBar *parent = static_cast<TExpandoMenuBar *>(Menu());
50341281cf3SAxel Dörfler 	int childIndex = parent->IndexOf(this) + 1;
50441281cf3SAxel Dörfler 
50541281cf3SAxel Dörfler 	while (!parent->SubmenuAt(childIndex) && childIndex < parent->CountItems()) {
50641281cf3SAxel Dörfler 		TWindowMenuItem *item = static_cast<TWindowMenuItem *>(parent->ItemAt(childIndex));
50741281cf3SAxel Dörfler 		if (item->ID() == id)
50841281cf3SAxel Dörfler 			return item;
50941281cf3SAxel Dörfler 
51041281cf3SAxel Dörfler 		childIndex++;
51141281cf3SAxel Dörfler 	}
51241281cf3SAxel Dörfler 	return NULL;
51341281cf3SAxel Dörfler }
51441281cf3SAxel Dörfler 
51541281cf3SAxel Dörfler 
51641281cf3SAxel Dörfler BRect
51741281cf3SAxel Dörfler TTeamMenuItem::ExpanderBounds() const
51841281cf3SAxel Dörfler {
51941281cf3SAxel Dörfler 	BRect bounds(Frame());
52041281cf3SAxel Dörfler 	bounds.left = bounds.right - kSwitchWidth;
52141281cf3SAxel Dörfler 	return bounds;
52241281cf3SAxel Dörfler }
52341281cf3SAxel Dörfler 
524