xref: /haiku/src/apps/deskbar/TeamMenuItem.cpp (revision ac121994b122349558d8621012759d23c8609c8d)
141281cf3SAxel Dörfler /*
241281cf3SAxel Dörfler Open Tracker License
341281cf3SAxel Dörfler 
441281cf3SAxel Dörfler Terms and Conditions
541281cf3SAxel Dörfler 
641281cf3SAxel Dörfler Copyright (c) 1991-2000, Be Incorporated. All rights reserved.
741281cf3SAxel Dörfler 
841281cf3SAxel Dörfler Permission is hereby granted, free of charge, to any person obtaining a copy of
941281cf3SAxel Dörfler this software and associated documentation files (the "Software"), to deal in
1041281cf3SAxel Dörfler the Software without restriction, including without limitation the rights to
1141281cf3SAxel Dörfler use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
1241281cf3SAxel Dörfler of the Software, and to permit persons to whom the Software is furnished to do
1341281cf3SAxel Dörfler so, subject to the following conditions:
1441281cf3SAxel Dörfler 
1541281cf3SAxel Dörfler The above copyright notice and this permission notice applies to all licensees
1641281cf3SAxel Dörfler and shall be included in all copies or substantial portions of the Software.
1741281cf3SAxel Dörfler 
1841281cf3SAxel Dörfler THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
1941281cf3SAxel Dörfler IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF TITLE, MERCHANTABILITY,
2041281cf3SAxel Dörfler FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
2141281cf3SAxel Dörfler BE INCORPORATED BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
2241281cf3SAxel Dörfler AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF, OR IN CONNECTION
2341281cf3SAxel Dörfler WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
2441281cf3SAxel Dörfler 
2541281cf3SAxel Dörfler Except as contained in this notice, the name of Be Incorporated shall not be
2641281cf3SAxel Dörfler used in advertising or otherwise to promote the sale, use or other dealings in
2741281cf3SAxel Dörfler this Software without prior written authorization from Be Incorporated.
2841281cf3SAxel Dörfler 
291687edd0SFredrik Holmqvist Tracker(TM), Be(R), BeOS(R), and BeIA(TM) are trademarks or registered
301687edd0SFredrik Holmqvist trademarks of Be Incorporated in the United States and other countries. Other
311687edd0SFredrik Holmqvist brand product names are registered trademarks or trademarks of their respective
321687edd0SFredrik Holmqvist holders.
3341281cf3SAxel Dörfler All rights reserved.
3441281cf3SAxel Dörfler */
3541281cf3SAxel Dörfler 
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 
4315eb397eSJohn Scipione #include <algorithm>
4415eb397eSJohn Scipione 
4541281cf3SAxel Dörfler #include <Bitmap.h>
46cb6afcb1SStephan Aßmus #include <ControlLook.h>
471cd61330SJohn Scipione #include <Debug.h>
4841281cf3SAxel Dörfler #include <Font.h>
4915eb397eSJohn Scipione #include <Mime.h>
5041281cf3SAxel Dörfler #include <Region.h>
5141281cf3SAxel Dörfler #include <Roster.h>
5241281cf3SAxel Dörfler #include <Resources.h>
534f97a431SJohn Scipione #include <Window.h>
5441281cf3SAxel Dörfler 
5541281cf3SAxel Dörfler #include "BarApp.h"
5641281cf3SAxel Dörfler #include "BarMenuBar.h"
574ae3e542SJohn Scipione #include "BarView.h"
5841281cf3SAxel Dörfler #include "ExpandoMenuBar.h"
5941281cf3SAxel Dörfler #include "ResourceSet.h"
6041281cf3SAxel Dörfler #include "ShowHideMenuItem.h"
6115eb397eSJohn Scipione #include "StatusView.h"
6241281cf3SAxel Dörfler #include "TeamMenu.h"
6341281cf3SAxel Dörfler #include "WindowMenu.h"
6441281cf3SAxel Dörfler #include "WindowMenuItem.h"
6541281cf3SAxel Dörfler 
6641281cf3SAxel Dörfler 
671e0308a8SAugustin Cavalier static float sHPad, sVPad, sLabelOffset = 0.0f;
6841281cf3SAxel Dörfler 
6941281cf3SAxel Dörfler 
70072c2dcdSJohn Scipione //	#pragma mark - TTeamMenuItem
71072c2dcdSJohn Scipione 
72072c2dcdSJohn Scipione 
TTeamMenuItem(BList * team,BBitmap * icon,char * name,char * signature,float width,float height)73c9363f78SJohn Scipione TTeamMenuItem::TTeamMenuItem(BList* team, BBitmap* icon, char* name,
74c9363f78SJohn Scipione 	char* signature, float width, float height)
7501f35d10SJohn Scipione 	:
76c9363f78SJohn Scipione 	TTruncatableMenuItem(new TWindowMenu(team, signature))
7741281cf3SAxel Dörfler {
78e9982f68SJohn Scipione 	_Init(team, icon, name, signature, width, height);
7941281cf3SAxel Dörfler }
8041281cf3SAxel Dörfler 
8141281cf3SAxel Dörfler 
TTeamMenuItem(float width,float height)8218bcf77aSJohn Scipione TTeamMenuItem::TTeamMenuItem(float width, float height)
8301f35d10SJohn Scipione 	:
84c9363f78SJohn Scipione 	TTruncatableMenuItem("", NULL)
8541281cf3SAxel Dörfler {
86e9982f68SJohn Scipione 	_Init(NULL, NULL, strdup(""), strdup(""), width, height);
8741281cf3SAxel Dörfler }
8841281cf3SAxel Dörfler 
8941281cf3SAxel Dörfler 
~TTeamMenuItem()9041281cf3SAxel Dörfler TTeamMenuItem::~TTeamMenuItem()
9141281cf3SAxel Dörfler {
9241281cf3SAxel Dörfler 	delete fTeam;
9341281cf3SAxel Dörfler 	delete fIcon;
94c9363f78SJohn Scipione 	free(fSignature);
955e625eadSJohn Scipione }
965e625eadSJohn Scipione 
975e625eadSJohn Scipione 
984f97a431SJohn Scipione /*!	Vulcan Death Grip and other team mouse button handling
994f97a431SJohn Scipione 
1004f97a431SJohn Scipione 	\returns true if handled, false otherwise
1014f97a431SJohn Scipione */
1024f97a431SJohn Scipione bool
HandleMouseDown(BPoint where)1034f97a431SJohn Scipione TTeamMenuItem::HandleMouseDown(BPoint where)
1044f97a431SJohn Scipione {
1054f97a431SJohn Scipione 	BMenu* menu = Menu();
1064f97a431SJohn Scipione 	if (menu == NULL)
1074f97a431SJohn Scipione 		return false;
1084f97a431SJohn Scipione 
1094f97a431SJohn Scipione 	BWindow* window = menu->Window();
1104f97a431SJohn Scipione 	if (window == NULL)
1114f97a431SJohn Scipione 		return false;
1124f97a431SJohn Scipione 
1134f97a431SJohn Scipione 	BMessage* message = window->CurrentMessage();
1144f97a431SJohn Scipione 	if (message == NULL)
1154f97a431SJohn Scipione 		return false;
1164f97a431SJohn Scipione 
1174f97a431SJohn Scipione 	int32 modifiers = 0;
1184f97a431SJohn Scipione 	int32 buttons = 0;
1194f97a431SJohn Scipione 	message->FindInt32("modifiers", &modifiers);
1204f97a431SJohn Scipione 	message->FindInt32("buttons", &buttons);
1214f97a431SJohn Scipione 
1224f97a431SJohn Scipione 	// check for three finger salute, a.k.a. Vulcan Death Grip
1234f97a431SJohn Scipione 	if ((modifiers & B_COMMAND_KEY) != 0
1244f97a431SJohn Scipione 		&& (modifiers & B_CONTROL_KEY) != 0
1254f97a431SJohn Scipione 		&& (modifiers & B_SHIFT_KEY) != 0) {
1264f97a431SJohn Scipione 		BMessage appMessage(B_SOME_APP_QUIT);
1274f97a431SJohn Scipione 		int32 teamCount = fTeam->CountItems();
1284f97a431SJohn Scipione 		BMessage quitMessage(teamCount == 1 ? B_SOME_APP_QUIT : kRemoveTeam);
1294f97a431SJohn Scipione 		quitMessage.AddInt32("itemIndex", menu->IndexOf(this));
1304f97a431SJohn Scipione 		for (int32 index = 0; index < teamCount; index++) {
1314f97a431SJohn Scipione 			team_id team = (addr_t)fTeam->ItemAt(index);
1324f97a431SJohn Scipione 			appMessage.AddInt32("be:team", team);
1334f97a431SJohn Scipione 			quitMessage.AddInt32("team", team);
1344f97a431SJohn Scipione 
1354f97a431SJohn Scipione 			kill_team(team);
1364f97a431SJohn Scipione 		}
1374f97a431SJohn Scipione 		be_app->PostMessage(&appMessage);
1384f97a431SJohn Scipione 		TExpandoMenuBar* expando = dynamic_cast<TExpandoMenuBar*>(menu);
1394f97a431SJohn Scipione 		window->PostMessage(&quitMessage, expando != NULL ? expando : menu);
1404f97a431SJohn Scipione 		return true;
1414f97a431SJohn Scipione 	} else if ((modifiers & B_SHIFT_KEY) == 0
1424f97a431SJohn Scipione 		&& (buttons & B_TERTIARY_MOUSE_BUTTON) != 0) {
1434f97a431SJohn Scipione 		// launch new team
1444f97a431SJohn Scipione 		be_roster->Launch(Signature());
1454f97a431SJohn Scipione 		return true;
1464f97a431SJohn Scipione 	} else if ((modifiers & B_CONTROL_KEY) != 0) {
1474f97a431SJohn Scipione 		// control click - show all/hide all shortcut
1484f97a431SJohn Scipione 		BMessage showMessage((modifiers & B_SHIFT_KEY) != 0
1494f97a431SJohn Scipione 			? kMinimizeTeam : kBringTeamToFront);
1504f97a431SJohn Scipione 		showMessage.AddInt32("itemIndex", menu->IndexOf(this));
1514f97a431SJohn Scipione 		window->PostMessage(&showMessage, menu);
1524f97a431SJohn Scipione 		return true;
1534f97a431SJohn Scipione 	}
1544f97a431SJohn Scipione 
1554f97a431SJohn Scipione 	return false;
1564f97a431SJohn Scipione }
1574f97a431SJohn Scipione 
1584f97a431SJohn Scipione 
15941281cf3SAxel Dörfler status_t
Invoke(BMessage * message)16041281cf3SAxel Dörfler TTeamMenuItem::Invoke(BMessage* message)
16141281cf3SAxel Dörfler {
1626a27de89SMurai Takashi 	if (fBarView != NULL) {
1631dccb7aaSJohn Scipione 		if (fBarView->InvokeItem(Signature())) {
16441281cf3SAxel Dörfler 			// handles drop on application
16541281cf3SAxel Dörfler 			return B_OK;
1661dccb7aaSJohn Scipione 		}
16741281cf3SAxel Dörfler 
16841281cf3SAxel Dörfler 		// if the app could not handle the drag message
16941281cf3SAxel Dörfler 		// and we were dragging, then kill the drag
17041281cf3SAxel Dörfler 		// should never get here, disabled item will not invoke
1716a27de89SMurai Takashi 		if (fBarView->Dragging())
1721dccb7aaSJohn Scipione 			fBarView->DragStop();
1736a27de89SMurai Takashi 	}
17441281cf3SAxel Dörfler 
17541281cf3SAxel Dörfler 	// bring to front or minimize shortcuts
17641281cf3SAxel Dörfler 	uint32 mods = modifiers();
1771687edd0SFredrik Holmqvist 	if (mods & B_CONTROL_KEY) {
17841281cf3SAxel Dörfler 		TShowHideMenuItem::TeamShowHideCommon((mods & B_SHIFT_KEY)
17941281cf3SAxel Dörfler 			? B_MINIMIZE_WINDOW : B_BRING_TO_FRONT, Teams());
1801687edd0SFredrik Holmqvist 	}
18141281cf3SAxel Dörfler 
18241281cf3SAxel Dörfler 	return BMenuItem::Invoke(message);
18341281cf3SAxel Dörfler }
18441281cf3SAxel Dörfler 
18541281cf3SAxel Dörfler 
18641281cf3SAxel Dörfler void
SetOverrideSelected(bool selected)187249a4a18SStephan Aßmus TTeamMenuItem::SetOverrideSelected(bool selected)
188249a4a18SStephan Aßmus {
189249a4a18SStephan Aßmus 	fOverriddenSelected = selected;
190249a4a18SStephan Aßmus 	Highlight(selected);
191249a4a18SStephan Aßmus }
192249a4a18SStephan Aßmus 
193249a4a18SStephan Aßmus 
1941dccb7aaSJohn Scipione void
SetIcon(BBitmap * icon)195c9d2a320SJohn Scipione TTeamMenuItem::SetIcon(BBitmap* icon) {
196c9d2a320SJohn Scipione 	delete fIcon;
197c9d2a320SJohn Scipione 	fIcon = icon;
1982ce9bab8SJohn Scipione }
1992ce9bab8SJohn Scipione 
2002ce9bab8SJohn Scipione 
20141281cf3SAxel Dörfler void
GetContentSize(float * width,float * height)20241281cf3SAxel Dörfler TTeamMenuItem::GetContentSize(float* width, float* height)
20341281cf3SAxel Dörfler {
20441281cf3SAxel Dörfler 	BMenuItem::GetContentSize(width, height);
20541281cf3SAxel Dörfler 
20641281cf3SAxel Dörfler 	if (fOverrideWidth != -1.0f)
20741281cf3SAxel Dörfler 		*width = fOverrideWidth;
2082ce9bab8SJohn Scipione 	else {
209396f398dSJohn Scipione 		const float iconSize = static_cast<TBarApp*>(be_app)->TeamIconSize();
210396f398dSJohn Scipione 		const float iconPadding = be_control_look->ComposeSpacing(kIconPadding);
211396f398dSJohn Scipione 		float iconOnlyWidth = iconSize + iconPadding;
212396f398dSJohn Scipione 		if (static_cast<TBarApp*>(be_app)->Settings()->hideLabels)
213396f398dSJohn Scipione 			iconOnlyWidth += iconPadding; // add an extra icon padding
21415eb397eSJohn Scipione 
21515eb397eSJohn Scipione 		if (fBarView->MiniState()) {
216396f398dSJohn Scipione 			if (static_cast<TBarApp*>(be_app)->Settings()->hideLabels)
21715eb397eSJohn Scipione 				*width = iconOnlyWidth;
21815eb397eSJohn Scipione 			else
2199f4bb0f5SAugustin Cavalier 				*width = gMinimumWindowWidth - (gDragRegionWidth + kGutter) * 2;
22015eb397eSJohn Scipione 		} else if (!fBarView->Vertical()) {
2210d2645e4SJohn Scipione 			TExpandoMenuBar* menu = static_cast<TExpandoMenuBar*>(Menu());
2220d2645e4SJohn Scipione 			*width = menu->MaxHorizontalItemWidth();
22315eb397eSJohn Scipione 		} else
22415eb397eSJohn Scipione 			*width = static_cast<TBarApp*>(be_app)->Settings()->width;
22518bcf77aSJohn Scipione 	}
22641281cf3SAxel Dörfler 
22741281cf3SAxel Dörfler 	if (fOverrideHeight != -1.0f)
22841281cf3SAxel Dörfler 		*height = fOverrideHeight;
22915eb397eSJohn Scipione 	else
23015eb397eSJohn Scipione 		*height = fBarView->TeamMenuItemHeight();
23141281cf3SAxel Dörfler }
23241281cf3SAxel Dörfler 
23341281cf3SAxel Dörfler 
23441281cf3SAxel Dörfler void
Draw()23541281cf3SAxel Dörfler TTeamMenuItem::Draw()
23641281cf3SAxel Dörfler {
2376b65d934SJohn Scipione 	BRect frame = Frame();
23841281cf3SAxel Dörfler 	BMenu* menu = Menu();
239fe624b39SJohn Scipione 
24041281cf3SAxel Dörfler 	menu->PushState();
2415b0fd10dSJohn Scipione 
24216c10517Slooncraz 	rgb_color menuColor = ui_color(B_MENU_BACKGROUND_COLOR);
2431dccb7aaSJohn Scipione 	bool canHandle = !fBarView->Dragging()
2441dccb7aaSJohn Scipione 		|| fBarView->AppCanHandleTypes(Signature());
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;
25018bcf77aSJohn Scipione 	if (fBarView->Vertical()) {
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();
274fe624b39SJohn Scipione 
275cb6afcb1SStephan Aßmus 	menu->PopState();
27641281cf3SAxel Dörfler }
27741281cf3SAxel Dörfler 
27841281cf3SAxel Dörfler 
27941281cf3SAxel Dörfler void
DrawContent()28041281cf3SAxel Dörfler TTeamMenuItem::DrawContent()
28141281cf3SAxel Dörfler {
28241281cf3SAxel Dörfler 	BMenu* menu = Menu();
28315eb397eSJohn Scipione 	BRect frame = Frame();
28415eb397eSJohn Scipione 
2852ce9bab8SJohn Scipione 	if (fIcon != NULL) {
28659deaf10SStephan Aßmus 		if (fIcon->ColorSpace() == B_RGBA32) {
28759deaf10SStephan Aßmus 			menu->SetDrawingMode(B_OP_ALPHA);
28859deaf10SStephan Aßmus 			menu->SetBlendingMode(B_PIXEL_ALPHA, B_ALPHA_OVERLAY);
2891687edd0SFredrik Holmqvist 		} else
29041281cf3SAxel Dörfler 			menu->SetDrawingMode(B_OP_OVER);
29141281cf3SAxel Dörfler 
292396f398dSJohn Scipione 		BRect iconBounds = fIcon->Bounds();
2936b65d934SJohn Scipione 		BRect updateRect = iconBounds;
294c9363f78SJohn Scipione 		BPoint contentLocation = ContentLocation();
2951e0308a8SAugustin Cavalier 		BPoint drawLocation = contentLocation + BPoint(sHPad, sVPad);
296396f398dSJohn Scipione 		const int32 large = be_control_look->ComposeIconSize(B_LARGE_ICON)
297396f398dSJohn Scipione 			.IntegerWidth() + 1;
2981687edd0SFredrik Holmqvist 
29918bcf77aSJohn Scipione 		if (static_cast<TBarApp*>(be_app)->Settings()->hideLabels
300396f398dSJohn Scipione 			|| (fBarView->Vertical() && iconBounds.Width() > large)) {
30115eb397eSJohn Scipione 			// determine icon location (centered horizontally)
302c9363f78SJohn Scipione 			float offsetx = contentLocation.x
30315eb397eSJohn Scipione 				+ floorf((frame.Width() - iconBounds.Width()) / 2);
3041e0308a8SAugustin Cavalier 			float offsety = contentLocation.y + sVPad + kGutter;
3052ce9bab8SJohn Scipione 
30615eb397eSJohn Scipione 			// draw icon
3076b65d934SJohn Scipione 			updateRect.OffsetTo(BPoint(offsetx, offsety));
3086b65d934SJohn Scipione 			menu->DrawBitmapAsync(fIcon, updateRect);
3092ce9bab8SJohn Scipione 
31015eb397eSJohn Scipione 			// determine label position (below icon)
31115eb397eSJohn Scipione 			drawLocation.x = floorf((frame.Width() - fLabelWidth) / 2);
3121e0308a8SAugustin Cavalier 			drawLocation.y = frame.top + sVPad + iconBounds.Height() + sVPad;
3132ce9bab8SJohn Scipione 		} else {
31415eb397eSJohn Scipione 			// determine icon location (centered vertically)
3151e0308a8SAugustin Cavalier 			float offsetx = contentLocation.x + sHPad;
316c9363f78SJohn Scipione 			float offsety = contentLocation.y +
31715eb397eSJohn Scipione 				floorf((frame.Height() - iconBounds.Height()) / 2);
3182ce9bab8SJohn Scipione 
31915eb397eSJohn Scipione 			// draw icon
3206b65d934SJohn Scipione 			updateRect.OffsetTo(BPoint(offsetx, offsety));
3216b65d934SJohn Scipione 			menu->DrawBitmapAsync(fIcon, updateRect);
32241281cf3SAxel Dörfler 
32315eb397eSJohn Scipione 			// determine label position (centered vertically)
3241e0308a8SAugustin Cavalier 			drawLocation.x += iconBounds.Width() + sLabelOffset;
32515eb397eSJohn Scipione 			drawLocation.y = frame.top
32615eb397eSJohn Scipione 				+ ceilf((frame.Height() - fLabelHeight) / 2);
3272ce9bab8SJohn Scipione 		}
3282ce9bab8SJohn Scipione 
329c9363f78SJohn Scipione 		menu->MovePenTo(drawLocation);
33041281cf3SAxel Dörfler 	}
33141281cf3SAxel Dörfler 
33241281cf3SAxel Dörfler 	// override the drawing of the content when the item is disabled
33341281cf3SAxel Dörfler 	// the wrong lowcolor is used when the item is disabled since the
33441281cf3SAxel Dörfler 	// text color does not change
33515eb397eSJohn Scipione 	menu->SetDrawingMode(B_OP_OVER);
33615eb397eSJohn Scipione 	menu->SetHighColor(ui_color(B_MENU_ITEM_TEXT_COLOR));
33741281cf3SAxel Dörfler 
3381dccb7aaSJohn Scipione 	bool canHandle = !fBarView->Dragging()
3391dccb7aaSJohn Scipione 		|| fBarView->AppCanHandleTypes(Signature());
340249a4a18SStephan Aßmus 	if (_IsSelected() && IsEnabled() && canHandle)
34116c10517Slooncraz 		menu->SetLowColor(tint_color(ui_color(B_MENU_BACKGROUND_COLOR),
34241281cf3SAxel Dörfler 			B_HIGHLIGHT_BACKGROUND_TINT));
34341281cf3SAxel Dörfler 	else
34416c10517Slooncraz 		menu->SetLowColor(ui_color(B_MENU_BACKGROUND_COLOR));
34541281cf3SAxel Dörfler 
346859c3781SJohn Scipione 	if (IsSelected())
347859c3781SJohn Scipione 		menu->SetHighColor(ui_color(B_MENU_SELECTED_ITEM_TEXT_COLOR));
348859c3781SJohn Scipione 	else
349859c3781SJohn Scipione 		menu->SetHighColor(ui_color(B_MENU_ITEM_TEXT_COLOR));
350859c3781SJohn Scipione 
35115eb397eSJohn Scipione 	menu->MovePenBy(0, fLabelAscent);
35215eb397eSJohn Scipione 
35315eb397eSJohn Scipione 	// draw label
354c9363f78SJohn Scipione 	if (!static_cast<TBarApp*>(be_app)->Settings()->hideLabels) {
355c9363f78SJohn Scipione 		float labelWidth = menu->StringWidth(Label());
356c9363f78SJohn Scipione 		BPoint penLocation = menu->PenLocation();
35715eb397eSJohn Scipione 		// truncate to max width
35815eb397eSJohn Scipione 		float offset = penLocation.x - frame.left;
359c9363f78SJohn Scipione 		menu->DrawString(Label(labelWidth + offset));
360c9363f78SJohn Scipione 	}
36141281cf3SAxel Dörfler 
36215eb397eSJohn Scipione 	// draw expander arrow
3635e625eadSJohn Scipione 	if (fBarView->Vertical()
3645e625eadSJohn Scipione 		&& static_cast<TBarApp*>(be_app)->Settings()->superExpando
3655e625eadSJohn Scipione 		&& fBarView->ExpandoState()) {
3665e625eadSJohn Scipione 		DrawExpanderArrow();
3675e625eadSJohn Scipione 	}
3685e625eadSJohn Scipione }
3695e625eadSJohn Scipione 
37041281cf3SAxel Dörfler 
3715b0fd10dSJohn Scipione void
DrawExpanderArrow()3721dccb7aaSJohn Scipione TTeamMenuItem::DrawExpanderArrow()
3735b0fd10dSJohn Scipione {
3746b65d934SJohn Scipione 	BRect frame = Frame();
3751e0308a8SAugustin Cavalier 	BRect rect(0.0f, 0.0f, kSwitchWidth, sHPad + 2.0f);
3765b0fd10dSJohn Scipione 	rect.OffsetTo(BPoint(frame.right - rect.Width(),
3775b0fd10dSJohn Scipione 		ContentLocation().y + ((frame.Height() - rect.Height()) / 2)));
3789a9f4ef5SMikael Konradsson 
3799a9f4ef5SMikael Konradsson 	float colorTint = B_DARKEN_3_TINT;
3809a9f4ef5SMikael Konradsson 	rgb_color bgColor = ui_color(B_MENU_BACKGROUND_COLOR);
38115eb397eSJohn Scipione 	if (bgColor.red + bgColor.green + bgColor.blue <= 128 * 3)
3829a9f4ef5SMikael Konradsson 		colorTint = B_LIGHTEN_2_TINT;
3839a9f4ef5SMikael Konradsson 
38415eb397eSJohn Scipione 	be_control_look->DrawArrowShape(Menu(), rect, Menu()->Frame(),
38515eb397eSJohn Scipione 		bgColor, fArrowDirection, 0, colorTint);
38641281cf3SAxel Dörfler }
38741281cf3SAxel Dörfler 
38841281cf3SAxel Dörfler 
38941281cf3SAxel Dörfler void
ToggleExpandState(bool resizeWindow)39041281cf3SAxel Dörfler TTeamMenuItem::ToggleExpandState(bool resizeWindow)
39141281cf3SAxel Dörfler {
39241281cf3SAxel Dörfler 	fExpanded = !fExpanded;
3931dccb7aaSJohn Scipione 	fArrowDirection = fExpanded ? BControlLook::B_DOWN_ARROW
3941dccb7aaSJohn Scipione 		: BControlLook::B_RIGHT_ARROW;
39541281cf3SAxel Dörfler 
39641281cf3SAxel Dörfler 	if (fExpanded) {
39741281cf3SAxel Dörfler 		// Populate Menu() with the stuff from SubMenu().
39841281cf3SAxel Dörfler 		TWindowMenu* sub = (static_cast<TWindowMenu*>(Submenu()));
3995b0fd10dSJohn Scipione 		if (sub != NULL) {
40041281cf3SAxel Dörfler 			// force the menu to update it's contents.
401bdfed6c0SAxel Dörfler 			bool locked = sub->LockLooper();
402bdfed6c0SAxel Dörfler 				// if locking the looper failed, the menu is just not visible
403bdfed6c0SAxel Dörfler 			sub->AttachedToWindow();
404bdfed6c0SAxel Dörfler 			if (locked)
405bdfed6c0SAxel Dörfler 				sub->UnlockLooper();
406bdfed6c0SAxel Dörfler 
40741281cf3SAxel Dörfler 			if (sub->CountItems() > 1) {
40841281cf3SAxel Dörfler 				TExpandoMenuBar* parent = static_cast<TExpandoMenuBar*>(Menu());
40941281cf3SAxel Dörfler 				int myindex = parent->IndexOf(this) + 1;
41041281cf3SAxel Dörfler 
41141281cf3SAxel Dörfler 				TWindowMenuItem* windowItem = NULL;
412deaae5fcSJohn Scipione 				int32 childIndex = 0;
413deaae5fcSJohn Scipione 				int32 totalChildren = sub->CountItems() - 4;
41471bd3ba5SJonas Sundström 					// hide, show, close, separator.
41541281cf3SAxel Dörfler 				for (; childIndex < totalChildren; childIndex++) {
41671bd3ba5SJonas Sundström 					windowItem = static_cast<TWindowMenuItem*>
41771bd3ba5SJonas Sundström 						(sub->RemoveItem((int32)0));
41841281cf3SAxel Dörfler 					parent->AddItem(windowItem, myindex + childIndex);
4195e625eadSJohn Scipione 					windowItem->SetExpanded(true);
42041281cf3SAxel Dörfler 				}
42141281cf3SAxel Dörfler 				sub->SetExpanded(true, myindex + childIndex);
42241281cf3SAxel Dörfler 
42341281cf3SAxel Dörfler 				if (resizeWindow)
424afa1c291SJohn Scipione 					parent->SizeWindow(-1);
425c0107fb2SJonas Sundström 			}
42641281cf3SAxel Dörfler 		}
42741281cf3SAxel Dörfler 	} else {
42841281cf3SAxel Dörfler 		// Remove the goodies from the Menu() that should be in the SubMenu();
42941281cf3SAxel Dörfler 		TWindowMenu* sub = static_cast<TWindowMenu*>(Submenu());
4305b0fd10dSJohn Scipione 		if (sub != NULL) {
43141281cf3SAxel Dörfler 			TExpandoMenuBar* parent = static_cast<TExpandoMenuBar*>(Menu());
43241281cf3SAxel Dörfler 
43341281cf3SAxel Dörfler 			TWindowMenuItem* windowItem = NULL;
434deaae5fcSJohn Scipione 			int32 childIndex = parent->IndexOf(this) + 1;
435deaae5fcSJohn Scipione 			while (parent->SubmenuAt(childIndex) == NULL
436deaae5fcSJohn Scipione 				&& childIndex < parent->CountItems()) {
43715eb397eSJohn Scipione 				windowItem = static_cast<TWindowMenuItem*>(
43815eb397eSJohn Scipione 					parent->RemoveItem(childIndex));
43941281cf3SAxel Dörfler 				sub->AddItem(windowItem, 0);
4405e625eadSJohn Scipione 				windowItem->SetExpanded(false);
44141281cf3SAxel Dörfler 			}
44241281cf3SAxel Dörfler 			sub->SetExpanded(false, 0);
44341281cf3SAxel Dörfler 
44441281cf3SAxel Dörfler 			if (resizeWindow)
44549ff476dSJohn Scipione 				parent->SizeWindow(1);
446c0107fb2SJonas Sundström 		}
44741281cf3SAxel Dörfler 	}
44841281cf3SAxel Dörfler }
44941281cf3SAxel Dörfler 
45041281cf3SAxel Dörfler 
45141281cf3SAxel Dörfler TWindowMenuItem*
ExpandedWindowItem(int32 id)45241281cf3SAxel Dörfler TTeamMenuItem::ExpandedWindowItem(int32 id)
45341281cf3SAxel Dörfler {
4541687edd0SFredrik Holmqvist 	if (!fExpanded) {
4551687edd0SFredrik Holmqvist 		// Paranoia
45641281cf3SAxel Dörfler 		return NULL;
4571687edd0SFredrik Holmqvist 	}
45841281cf3SAxel Dörfler 
45941281cf3SAxel Dörfler 	TExpandoMenuBar* parent = static_cast<TExpandoMenuBar*>(Menu());
46041281cf3SAxel Dörfler 	int childIndex = parent->IndexOf(this) + 1;
46141281cf3SAxel Dörfler 
46271bd3ba5SJonas Sundström 	while (!parent->SubmenuAt(childIndex)
46371bd3ba5SJonas Sundström 		&& childIndex < parent->CountItems()) {
46471bd3ba5SJonas Sundström 		TWindowMenuItem* item
46571bd3ba5SJonas Sundström 			= static_cast<TWindowMenuItem*>(parent->ItemAt(childIndex));
46641281cf3SAxel Dörfler 		if (item->ID() == id)
46741281cf3SAxel Dörfler 			return item;
46841281cf3SAxel Dörfler 
46941281cf3SAxel Dörfler 		childIndex++;
47041281cf3SAxel Dörfler 	}
47141281cf3SAxel Dörfler 	return NULL;
47241281cf3SAxel Dörfler }
47341281cf3SAxel Dörfler 
47441281cf3SAxel Dörfler 
47541281cf3SAxel Dörfler BRect
ExpanderBounds() const47641281cf3SAxel Dörfler TTeamMenuItem::ExpanderBounds() const
47741281cf3SAxel Dörfler {
47841281cf3SAxel Dörfler 	BRect bounds(Frame());
47941281cf3SAxel Dörfler 	bounds.left = bounds.right - kSwitchWidth;
48041281cf3SAxel Dörfler 	return bounds;
48141281cf3SAxel Dörfler }
48241281cf3SAxel Dörfler 
483249a4a18SStephan Aßmus 
4845b0fd10dSJohn Scipione //	#pragma mark - Private methods
4855b0fd10dSJohn Scipione 
4865b0fd10dSJohn Scipione 
4875b0fd10dSJohn Scipione void
_Init(BList * team,BBitmap * icon,char * name,char * signature,float width,float height)488e9982f68SJohn Scipione TTeamMenuItem::_Init(BList* team, BBitmap* icon, char* name, char* signature,
48918bcf77aSJohn Scipione 	float width, float height)
4905b0fd10dSJohn Scipione {
4911e0308a8SAugustin Cavalier 	if (sHPad == 0.0f) {
4921e0308a8SAugustin Cavalier 		// Initialize the padding values.
4931e0308a8SAugustin Cavalier 		sHPad = be_control_look->ComposeSpacing(B_USE_SMALL_SPACING);
4941e0308a8SAugustin Cavalier 		sVPad = ceilf(be_control_look->ComposeSpacing(B_USE_SMALL_SPACING) / 4.0f);
4951e0308a8SAugustin Cavalier 		sLabelOffset = ceilf((be_control_look->DefaultLabelSpacing() / 3.0f) * 4.0f);
4961e0308a8SAugustin Cavalier 	}
4971e0308a8SAugustin Cavalier 
4985b0fd10dSJohn Scipione 	fTeam = team;
4995b0fd10dSJohn Scipione 	fIcon = icon;
500c9363f78SJohn Scipione 	fSignature = signature;
501c38afcd6SJohn Scipione 
502c38afcd6SJohn Scipione 	if (name == NULL) {
5035b0fd10dSJohn Scipione 		char temp[32];
5045b0fd10dSJohn Scipione 		snprintf(temp, sizeof(temp), "team %ld", (addr_t)team->ItemAt(0));
505c38afcd6SJohn Scipione 		name = strdup(temp);
5065b0fd10dSJohn Scipione 	}
507c9363f78SJohn Scipione 
508c38afcd6SJohn Scipione 	SetLabel(name);
509c9363f78SJohn Scipione 
5101dccb7aaSJohn Scipione 	fOverrideWidth = width;
5111dccb7aaSJohn Scipione 	fOverrideHeight = height;
5125b0fd10dSJohn Scipione 
5131dccb7aaSJohn Scipione 	fBarView = static_cast<TBarApp*>(be_app)->BarView();
5145b0fd10dSJohn Scipione 
515*ac121994SJohn Scipione 	// use menu font (parent font not available yet)
516*ac121994SJohn Scipione 	menu_info info;
517*ac121994SJohn Scipione 	get_menu_info(&info);
518*ac121994SJohn Scipione 	BFont font;
519*ac121994SJohn Scipione 	font.SetFamilyAndStyle(info.f_family, info.f_style);
520*ac121994SJohn Scipione 	font.SetSize(info.font_size);
521c38afcd6SJohn Scipione 	fLabelWidth = ceilf(font.StringWidth(name));
522c38afcd6SJohn Scipione 	font_height fontHeight;
523c38afcd6SJohn Scipione 	font.GetHeight(&fontHeight);
524c38afcd6SJohn Scipione 	fLabelAscent = ceilf(fontHeight.ascent);
525c38afcd6SJohn Scipione 	fLabelDescent = ceilf(fontHeight.descent + fontHeight.leading);
52615eb397eSJohn Scipione 	fLabelHeight = fLabelAscent + fLabelDescent;
527c38afcd6SJohn Scipione 
5285b0fd10dSJohn Scipione 	fOverriddenSelected = false;
5295b0fd10dSJohn Scipione 
5305b0fd10dSJohn Scipione 	fExpanded = false;
5311dccb7aaSJohn Scipione 	fArrowDirection = BControlLook::B_RIGHT_ARROW;
5325b0fd10dSJohn Scipione }
5335b0fd10dSJohn Scipione 
5345b0fd10dSJohn Scipione 
535249a4a18SStephan Aßmus bool
_IsSelected() const536249a4a18SStephan Aßmus TTeamMenuItem::_IsSelected() const
537249a4a18SStephan Aßmus {
538249a4a18SStephan Aßmus 	return IsSelected() || fOverriddenSelected;
539249a4a18SStephan Aßmus }
540