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