xref: /haiku/src/apps/deskbar/TeamMenuItem.cpp (revision 4f97a431b966877dc688abbe106a2967a2c93653)
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>
53*4f97a431SJohn 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 
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 
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 
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 
98*4f97a431SJohn Scipione /*!	Vulcan Death Grip and other team mouse button handling
99*4f97a431SJohn Scipione 
100*4f97a431SJohn Scipione 	\returns true if handled, false otherwise
101*4f97a431SJohn Scipione */
102*4f97a431SJohn Scipione bool
103*4f97a431SJohn Scipione TTeamMenuItem::HandleMouseDown(BPoint where)
104*4f97a431SJohn Scipione {
105*4f97a431SJohn Scipione 	BMenu* menu = Menu();
106*4f97a431SJohn Scipione 	if (menu == NULL)
107*4f97a431SJohn Scipione 		return false;
108*4f97a431SJohn Scipione 
109*4f97a431SJohn Scipione 	BWindow* window = menu->Window();
110*4f97a431SJohn Scipione 	if (window == NULL)
111*4f97a431SJohn Scipione 		return false;
112*4f97a431SJohn Scipione 
113*4f97a431SJohn Scipione 	BMessage* message = window->CurrentMessage();
114*4f97a431SJohn Scipione 	if (message == NULL)
115*4f97a431SJohn Scipione 		return false;
116*4f97a431SJohn Scipione 
117*4f97a431SJohn Scipione 	int32 modifiers = 0;
118*4f97a431SJohn Scipione 	int32 buttons = 0;
119*4f97a431SJohn Scipione 	message->FindInt32("modifiers", &modifiers);
120*4f97a431SJohn Scipione 	message->FindInt32("buttons", &buttons);
121*4f97a431SJohn Scipione 
122*4f97a431SJohn Scipione 	// check for three finger salute, a.k.a. Vulcan Death Grip
123*4f97a431SJohn Scipione 	if ((modifiers & B_COMMAND_KEY) != 0
124*4f97a431SJohn Scipione 		&& (modifiers & B_CONTROL_KEY) != 0
125*4f97a431SJohn Scipione 		&& (modifiers & B_SHIFT_KEY) != 0) {
126*4f97a431SJohn Scipione 		BMessage appMessage(B_SOME_APP_QUIT);
127*4f97a431SJohn Scipione 		int32 teamCount = fTeam->CountItems();
128*4f97a431SJohn Scipione 		BMessage quitMessage(teamCount == 1 ? B_SOME_APP_QUIT : kRemoveTeam);
129*4f97a431SJohn Scipione 		quitMessage.AddInt32("itemIndex", menu->IndexOf(this));
130*4f97a431SJohn Scipione 		for (int32 index = 0; index < teamCount; index++) {
131*4f97a431SJohn Scipione 			team_id team = (addr_t)fTeam->ItemAt(index);
132*4f97a431SJohn Scipione 			appMessage.AddInt32("be:team", team);
133*4f97a431SJohn Scipione 			quitMessage.AddInt32("team", team);
134*4f97a431SJohn Scipione 
135*4f97a431SJohn Scipione 			kill_team(team);
136*4f97a431SJohn Scipione 		}
137*4f97a431SJohn Scipione 		be_app->PostMessage(&appMessage);
138*4f97a431SJohn Scipione 		TExpandoMenuBar* expando = dynamic_cast<TExpandoMenuBar*>(menu);
139*4f97a431SJohn Scipione 		window->PostMessage(&quitMessage, expando != NULL ? expando : menu);
140*4f97a431SJohn Scipione 		return true;
141*4f97a431SJohn Scipione 	} else if ((modifiers & B_SHIFT_KEY) == 0
142*4f97a431SJohn Scipione 		&& (buttons & B_TERTIARY_MOUSE_BUTTON) != 0) {
143*4f97a431SJohn Scipione 		// launch new team
144*4f97a431SJohn Scipione 		be_roster->Launch(Signature());
145*4f97a431SJohn Scipione 		return true;
146*4f97a431SJohn Scipione 	} else if ((modifiers & B_CONTROL_KEY) != 0) {
147*4f97a431SJohn Scipione 		// control click - show all/hide all shortcut
148*4f97a431SJohn Scipione 		BMessage showMessage((modifiers & B_SHIFT_KEY) != 0
149*4f97a431SJohn Scipione 			? kMinimizeTeam : kBringTeamToFront);
150*4f97a431SJohn Scipione 		showMessage.AddInt32("itemIndex", menu->IndexOf(this));
151*4f97a431SJohn Scipione 		window->PostMessage(&showMessage, menu);
152*4f97a431SJohn Scipione 		return true;
153*4f97a431SJohn Scipione 	}
154*4f97a431SJohn Scipione 
155*4f97a431SJohn Scipione 	return false;
156*4f97a431SJohn Scipione }
157*4f97a431SJohn Scipione 
158*4f97a431SJohn Scipione 
15941281cf3SAxel Dörfler status_t
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
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
195c9d2a320SJohn Scipione TTeamMenuItem::SetIcon(BBitmap* icon) {
196c9d2a320SJohn Scipione 	delete fIcon;
197c9d2a320SJohn Scipione 	fIcon = icon;
1982ce9bab8SJohn Scipione }
1992ce9bab8SJohn Scipione 
2002ce9bab8SJohn Scipione 
20141281cf3SAxel Dörfler void
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 {
20915eb397eSJohn Scipione 		bool hideLabels = static_cast<TBarApp*>(be_app)->Settings()->hideLabels;
21015eb397eSJohn Scipione 		float iconSize = static_cast<TBarApp*>(be_app)->IconSize();
2111e0308a8SAugustin Cavalier 		float iconOnlyWidth = (be_control_look->ComposeSpacing(kIconPadding) * 2) + iconSize;
21215eb397eSJohn Scipione 
21315eb397eSJohn Scipione 		if (fBarView->MiniState()) {
21415eb397eSJohn Scipione 			if (hideLabels)
21515eb397eSJohn Scipione 				*width = iconOnlyWidth;
21615eb397eSJohn Scipione 			else
2179f4bb0f5SAugustin Cavalier 				*width = gMinimumWindowWidth - (gDragRegionWidth + kGutter) * 2;
21815eb397eSJohn Scipione 		} else if (!fBarView->Vertical()) {
2190d2645e4SJohn Scipione 			TExpandoMenuBar* menu = static_cast<TExpandoMenuBar*>(Menu());
2200d2645e4SJohn Scipione 			*width = menu->MaxHorizontalItemWidth();
22115eb397eSJohn Scipione 		} else
22215eb397eSJohn Scipione 			*width = static_cast<TBarApp*>(be_app)->Settings()->width;
22318bcf77aSJohn Scipione 	}
22441281cf3SAxel Dörfler 
22541281cf3SAxel Dörfler 	if (fOverrideHeight != -1.0f)
22641281cf3SAxel Dörfler 		*height = fOverrideHeight;
22715eb397eSJohn Scipione 	else
22815eb397eSJohn Scipione 		*height = fBarView->TeamMenuItemHeight();
22941281cf3SAxel Dörfler }
23041281cf3SAxel Dörfler 
23141281cf3SAxel Dörfler 
23241281cf3SAxel Dörfler void
23341281cf3SAxel Dörfler TTeamMenuItem::Draw()
23441281cf3SAxel Dörfler {
2356b65d934SJohn Scipione 	BRect frame = Frame();
23641281cf3SAxel Dörfler 	BMenu* menu = Menu();
237fe624b39SJohn Scipione 
23841281cf3SAxel Dörfler 	menu->PushState();
2395b0fd10dSJohn Scipione 
24016c10517Slooncraz 	rgb_color menuColor = ui_color(B_MENU_BACKGROUND_COLOR);
2411dccb7aaSJohn Scipione 	bool canHandle = !fBarView->Dragging()
2421dccb7aaSJohn Scipione 		|| fBarView->AppCanHandleTypes(Signature());
243cb6afcb1SStephan Aßmus 	uint32 flags = 0;
244cb6afcb1SStephan Aßmus 	if (_IsSelected() && canHandle)
245cb6afcb1SStephan Aßmus 		flags |= BControlLook::B_ACTIVATED;
246cb6afcb1SStephan Aßmus 
247cb6afcb1SStephan Aßmus 	uint32 borders = BControlLook::B_TOP_BORDER;
24818bcf77aSJohn Scipione 	if (fBarView->Vertical()) {
249cb6afcb1SStephan Aßmus 		menu->SetHighColor(tint_color(menuColor, B_DARKEN_1_TINT));
250cb6afcb1SStephan Aßmus 		borders |= BControlLook::B_LEFT_BORDER
251cb6afcb1SStephan Aßmus 			| BControlLook::B_RIGHT_BORDER;
252cb6afcb1SStephan Aßmus 		menu->StrokeLine(frame.LeftBottom(), frame.RightBottom());
253cb6afcb1SStephan Aßmus 		frame.bottom--;
254cb6afcb1SStephan Aßmus 
255cb6afcb1SStephan Aßmus 		be_control_look->DrawMenuBarBackground(menu, frame, frame,
256cb6afcb1SStephan Aßmus 			menuColor, flags, borders);
257cb6afcb1SStephan Aßmus 	} else {
258cb6afcb1SStephan Aßmus 		if (flags & BControlLook::B_ACTIVATED)
259cb6afcb1SStephan Aßmus 			menu->SetHighColor(tint_color(menuColor, B_DARKEN_3_TINT));
260cb6afcb1SStephan Aßmus 		else
261cb6afcb1SStephan Aßmus 			menu->SetHighColor(tint_color(menuColor, 1.22));
262cb6afcb1SStephan Aßmus 		borders |= BControlLook::B_BOTTOM_BORDER;
263cb6afcb1SStephan Aßmus 		menu->StrokeLine(frame.LeftTop(), frame.LeftBottom());
264cb6afcb1SStephan Aßmus 		frame.left++;
265cb6afcb1SStephan Aßmus 
266cb6afcb1SStephan Aßmus 		be_control_look->DrawButtonBackground(menu, frame, frame,
267cb6afcb1SStephan Aßmus 			menuColor, flags, borders);
268cb6afcb1SStephan Aßmus 	}
269cb6afcb1SStephan Aßmus 
270cb6afcb1SStephan Aßmus 	menu->MovePenTo(ContentLocation());
271cb6afcb1SStephan Aßmus 	DrawContent();
272fe624b39SJohn Scipione 
273cb6afcb1SStephan Aßmus 	menu->PopState();
27441281cf3SAxel Dörfler }
27541281cf3SAxel Dörfler 
27641281cf3SAxel Dörfler 
27741281cf3SAxel Dörfler void
27841281cf3SAxel Dörfler TTeamMenuItem::DrawContent()
27941281cf3SAxel Dörfler {
28041281cf3SAxel Dörfler 	BMenu* menu = Menu();
28115eb397eSJohn Scipione 	BRect frame = Frame();
28215eb397eSJohn Scipione 
2832ce9bab8SJohn Scipione 	if (fIcon != NULL) {
28459deaf10SStephan Aßmus 		if (fIcon->ColorSpace() == B_RGBA32) {
28559deaf10SStephan Aßmus 			menu->SetDrawingMode(B_OP_ALPHA);
28659deaf10SStephan Aßmus 			menu->SetBlendingMode(B_PIXEL_ALPHA, B_ALPHA_OVERLAY);
2871687edd0SFredrik Holmqvist 		} else
28841281cf3SAxel Dörfler 			menu->SetDrawingMode(B_OP_OVER);
28941281cf3SAxel Dörfler 
29015eb397eSJohn Scipione 		BRect iconBounds = fIcon != NULL ? fIcon->Bounds()
29115eb397eSJohn Scipione 			: BRect(0, 0, kMinimumIconSize - 1, kMinimumIconSize - 1);
2926b65d934SJohn Scipione 		BRect updateRect = iconBounds;
293c9363f78SJohn Scipione 		BPoint contentLocation = ContentLocation();
2941e0308a8SAugustin Cavalier 		BPoint drawLocation = contentLocation + BPoint(sHPad, sVPad);
2951687edd0SFredrik Holmqvist 
29618bcf77aSJohn Scipione 		if (static_cast<TBarApp*>(be_app)->Settings()->hideLabels
29718bcf77aSJohn Scipione 			|| (fBarView->Vertical() && iconBounds.Width() > 32)) {
29815eb397eSJohn Scipione 			// determine icon location (centered horizontally)
299c9363f78SJohn Scipione 			float offsetx = contentLocation.x
30015eb397eSJohn Scipione 				+ floorf((frame.Width() - iconBounds.Width()) / 2);
3011e0308a8SAugustin Cavalier 			float offsety = contentLocation.y + sVPad + kGutter;
3022ce9bab8SJohn Scipione 
30315eb397eSJohn Scipione 			// draw icon
3046b65d934SJohn Scipione 			updateRect.OffsetTo(BPoint(offsetx, offsety));
3056b65d934SJohn Scipione 			menu->DrawBitmapAsync(fIcon, updateRect);
3062ce9bab8SJohn Scipione 
30715eb397eSJohn Scipione 			// determine label position (below icon)
30815eb397eSJohn Scipione 			drawLocation.x = floorf((frame.Width() - fLabelWidth) / 2);
3091e0308a8SAugustin Cavalier 			drawLocation.y = frame.top + sVPad + iconBounds.Height() + sVPad;
3102ce9bab8SJohn Scipione 		} else {
31115eb397eSJohn Scipione 			// determine icon location (centered vertically)
3121e0308a8SAugustin Cavalier 			float offsetx = contentLocation.x + sHPad;
313c9363f78SJohn Scipione 			float offsety = contentLocation.y +
31415eb397eSJohn Scipione 				floorf((frame.Height() - iconBounds.Height()) / 2);
3152ce9bab8SJohn Scipione 
31615eb397eSJohn Scipione 			// draw icon
3176b65d934SJohn Scipione 			updateRect.OffsetTo(BPoint(offsetx, offsety));
3186b65d934SJohn Scipione 			menu->DrawBitmapAsync(fIcon, updateRect);
31941281cf3SAxel Dörfler 
32015eb397eSJohn Scipione 			// determine label position (centered vertically)
3211e0308a8SAugustin Cavalier 			drawLocation.x += iconBounds.Width() + sLabelOffset;
32215eb397eSJohn Scipione 			drawLocation.y = frame.top
32315eb397eSJohn Scipione 				+ ceilf((frame.Height() - fLabelHeight) / 2);
3242ce9bab8SJohn Scipione 		}
3252ce9bab8SJohn Scipione 
326c9363f78SJohn Scipione 		menu->MovePenTo(drawLocation);
32741281cf3SAxel Dörfler 	}
32841281cf3SAxel Dörfler 
32941281cf3SAxel Dörfler 	// override the drawing of the content when the item is disabled
33041281cf3SAxel Dörfler 	// the wrong lowcolor is used when the item is disabled since the
33141281cf3SAxel Dörfler 	// text color does not change
33215eb397eSJohn Scipione 	menu->SetDrawingMode(B_OP_OVER);
33315eb397eSJohn Scipione 	menu->SetHighColor(ui_color(B_MENU_ITEM_TEXT_COLOR));
33441281cf3SAxel Dörfler 
3351dccb7aaSJohn Scipione 	bool canHandle = !fBarView->Dragging()
3361dccb7aaSJohn Scipione 		|| fBarView->AppCanHandleTypes(Signature());
337249a4a18SStephan Aßmus 	if (_IsSelected() && IsEnabled() && canHandle)
33816c10517Slooncraz 		menu->SetLowColor(tint_color(ui_color(B_MENU_BACKGROUND_COLOR),
33941281cf3SAxel Dörfler 			B_HIGHLIGHT_BACKGROUND_TINT));
34041281cf3SAxel Dörfler 	else
34116c10517Slooncraz 		menu->SetLowColor(ui_color(B_MENU_BACKGROUND_COLOR));
34241281cf3SAxel Dörfler 
343859c3781SJohn Scipione 	if (IsSelected())
344859c3781SJohn Scipione 		menu->SetHighColor(ui_color(B_MENU_SELECTED_ITEM_TEXT_COLOR));
345859c3781SJohn Scipione 	else
346859c3781SJohn Scipione 		menu->SetHighColor(ui_color(B_MENU_ITEM_TEXT_COLOR));
347859c3781SJohn Scipione 
34815eb397eSJohn Scipione 	menu->MovePenBy(0, fLabelAscent);
34915eb397eSJohn Scipione 
35015eb397eSJohn Scipione 	// draw label
351c9363f78SJohn Scipione 	if (!static_cast<TBarApp*>(be_app)->Settings()->hideLabels) {
352c9363f78SJohn Scipione 		float labelWidth = menu->StringWidth(Label());
353c9363f78SJohn Scipione 		BPoint penLocation = menu->PenLocation();
35415eb397eSJohn Scipione 		// truncate to max width
35515eb397eSJohn Scipione 		float offset = penLocation.x - frame.left;
356c9363f78SJohn Scipione 		menu->DrawString(Label(labelWidth + offset));
357c9363f78SJohn Scipione 	}
35841281cf3SAxel Dörfler 
35915eb397eSJohn Scipione 	// draw expander arrow
3605e625eadSJohn Scipione 	if (fBarView->Vertical()
3615e625eadSJohn Scipione 		&& static_cast<TBarApp*>(be_app)->Settings()->superExpando
3625e625eadSJohn Scipione 		&& fBarView->ExpandoState()) {
3635e625eadSJohn Scipione 		DrawExpanderArrow();
3645e625eadSJohn Scipione 	}
3655e625eadSJohn Scipione }
3665e625eadSJohn Scipione 
36741281cf3SAxel Dörfler 
3685b0fd10dSJohn Scipione void
3691dccb7aaSJohn Scipione TTeamMenuItem::DrawExpanderArrow()
3705b0fd10dSJohn Scipione {
3716b65d934SJohn Scipione 	BRect frame = Frame();
3721e0308a8SAugustin Cavalier 	BRect rect(0.0f, 0.0f, kSwitchWidth, sHPad + 2.0f);
3735b0fd10dSJohn Scipione 	rect.OffsetTo(BPoint(frame.right - rect.Width(),
3745b0fd10dSJohn Scipione 		ContentLocation().y + ((frame.Height() - rect.Height()) / 2)));
3759a9f4ef5SMikael Konradsson 
3769a9f4ef5SMikael Konradsson 	float colorTint = B_DARKEN_3_TINT;
3779a9f4ef5SMikael Konradsson 	rgb_color bgColor = ui_color(B_MENU_BACKGROUND_COLOR);
37815eb397eSJohn Scipione 	if (bgColor.red + bgColor.green + bgColor.blue <= 128 * 3)
3799a9f4ef5SMikael Konradsson 		colorTint = B_LIGHTEN_2_TINT;
3809a9f4ef5SMikael Konradsson 
38115eb397eSJohn Scipione 	be_control_look->DrawArrowShape(Menu(), rect, Menu()->Frame(),
38215eb397eSJohn Scipione 		bgColor, fArrowDirection, 0, colorTint);
38341281cf3SAxel Dörfler }
38441281cf3SAxel Dörfler 
38541281cf3SAxel Dörfler 
38641281cf3SAxel Dörfler void
38741281cf3SAxel Dörfler TTeamMenuItem::ToggleExpandState(bool resizeWindow)
38841281cf3SAxel Dörfler {
38941281cf3SAxel Dörfler 	fExpanded = !fExpanded;
3901dccb7aaSJohn Scipione 	fArrowDirection = fExpanded ? BControlLook::B_DOWN_ARROW
3911dccb7aaSJohn Scipione 		: BControlLook::B_RIGHT_ARROW;
39241281cf3SAxel Dörfler 
39341281cf3SAxel Dörfler 	if (fExpanded) {
39441281cf3SAxel Dörfler 		// Populate Menu() with the stuff from SubMenu().
39541281cf3SAxel Dörfler 		TWindowMenu* sub = (static_cast<TWindowMenu*>(Submenu()));
3965b0fd10dSJohn Scipione 		if (sub != NULL) {
39741281cf3SAxel Dörfler 			// force the menu to update it's contents.
398bdfed6c0SAxel Dörfler 			bool locked = sub->LockLooper();
399bdfed6c0SAxel Dörfler 				// if locking the looper failed, the menu is just not visible
400bdfed6c0SAxel Dörfler 			sub->AttachedToWindow();
401bdfed6c0SAxel Dörfler 			if (locked)
402bdfed6c0SAxel Dörfler 				sub->UnlockLooper();
403bdfed6c0SAxel Dörfler 
40441281cf3SAxel Dörfler 			if (sub->CountItems() > 1) {
40541281cf3SAxel Dörfler 				TExpandoMenuBar* parent = static_cast<TExpandoMenuBar*>(Menu());
40641281cf3SAxel Dörfler 				int myindex = parent->IndexOf(this) + 1;
40741281cf3SAxel Dörfler 
40841281cf3SAxel Dörfler 				TWindowMenuItem* windowItem = NULL;
409deaae5fcSJohn Scipione 				int32 childIndex = 0;
410deaae5fcSJohn Scipione 				int32 totalChildren = sub->CountItems() - 4;
41171bd3ba5SJonas Sundström 					// hide, show, close, separator.
41241281cf3SAxel Dörfler 				for (; childIndex < totalChildren; childIndex++) {
41371bd3ba5SJonas Sundström 					windowItem = static_cast<TWindowMenuItem*>
41471bd3ba5SJonas Sundström 						(sub->RemoveItem((int32)0));
41541281cf3SAxel Dörfler 					parent->AddItem(windowItem, myindex + childIndex);
4165e625eadSJohn Scipione 					windowItem->SetExpanded(true);
41741281cf3SAxel Dörfler 				}
41841281cf3SAxel Dörfler 				sub->SetExpanded(true, myindex + childIndex);
41941281cf3SAxel Dörfler 
42041281cf3SAxel Dörfler 				if (resizeWindow)
421afa1c291SJohn Scipione 					parent->SizeWindow(-1);
422c0107fb2SJonas Sundström 			}
42341281cf3SAxel Dörfler 		}
42441281cf3SAxel Dörfler 	} else {
42541281cf3SAxel Dörfler 		// Remove the goodies from the Menu() that should be in the SubMenu();
42641281cf3SAxel Dörfler 		TWindowMenu* sub = static_cast<TWindowMenu*>(Submenu());
4275b0fd10dSJohn Scipione 		if (sub != NULL) {
42841281cf3SAxel Dörfler 			TExpandoMenuBar* parent = static_cast<TExpandoMenuBar*>(Menu());
42941281cf3SAxel Dörfler 
43041281cf3SAxel Dörfler 			TWindowMenuItem* windowItem = NULL;
431deaae5fcSJohn Scipione 			int32 childIndex = parent->IndexOf(this) + 1;
432deaae5fcSJohn Scipione 			while (parent->SubmenuAt(childIndex) == NULL
433deaae5fcSJohn Scipione 				&& childIndex < parent->CountItems()) {
43415eb397eSJohn Scipione 				windowItem = static_cast<TWindowMenuItem*>(
43515eb397eSJohn Scipione 					parent->RemoveItem(childIndex));
43641281cf3SAxel Dörfler 				sub->AddItem(windowItem, 0);
4375e625eadSJohn Scipione 				windowItem->SetExpanded(false);
43841281cf3SAxel Dörfler 			}
43941281cf3SAxel Dörfler 			sub->SetExpanded(false, 0);
44041281cf3SAxel Dörfler 
44141281cf3SAxel Dörfler 			if (resizeWindow)
44249ff476dSJohn Scipione 				parent->SizeWindow(1);
443c0107fb2SJonas Sundström 		}
44441281cf3SAxel Dörfler 	}
44541281cf3SAxel Dörfler }
44641281cf3SAxel Dörfler 
44741281cf3SAxel Dörfler 
44841281cf3SAxel Dörfler TWindowMenuItem*
44941281cf3SAxel Dörfler TTeamMenuItem::ExpandedWindowItem(int32 id)
45041281cf3SAxel Dörfler {
4511687edd0SFredrik Holmqvist 	if (!fExpanded) {
4521687edd0SFredrik Holmqvist 		// Paranoia
45341281cf3SAxel Dörfler 		return NULL;
4541687edd0SFredrik Holmqvist 	}
45541281cf3SAxel Dörfler 
45641281cf3SAxel Dörfler 	TExpandoMenuBar* parent = static_cast<TExpandoMenuBar*>(Menu());
45741281cf3SAxel Dörfler 	int childIndex = parent->IndexOf(this) + 1;
45841281cf3SAxel Dörfler 
45971bd3ba5SJonas Sundström 	while (!parent->SubmenuAt(childIndex)
46071bd3ba5SJonas Sundström 		&& childIndex < parent->CountItems()) {
46171bd3ba5SJonas Sundström 		TWindowMenuItem* item
46271bd3ba5SJonas Sundström 			= static_cast<TWindowMenuItem*>(parent->ItemAt(childIndex));
46341281cf3SAxel Dörfler 		if (item->ID() == id)
46441281cf3SAxel Dörfler 			return item;
46541281cf3SAxel Dörfler 
46641281cf3SAxel Dörfler 		childIndex++;
46741281cf3SAxel Dörfler 	}
46841281cf3SAxel Dörfler 	return NULL;
46941281cf3SAxel Dörfler }
47041281cf3SAxel Dörfler 
47141281cf3SAxel Dörfler 
47241281cf3SAxel Dörfler BRect
47341281cf3SAxel Dörfler TTeamMenuItem::ExpanderBounds() const
47441281cf3SAxel Dörfler {
47541281cf3SAxel Dörfler 	BRect bounds(Frame());
47641281cf3SAxel Dörfler 	bounds.left = bounds.right - kSwitchWidth;
47741281cf3SAxel Dörfler 	return bounds;
47841281cf3SAxel Dörfler }
47941281cf3SAxel Dörfler 
480249a4a18SStephan Aßmus 
4815b0fd10dSJohn Scipione //	#pragma mark - Private methods
4825b0fd10dSJohn Scipione 
4835b0fd10dSJohn Scipione 
4845b0fd10dSJohn Scipione void
485e9982f68SJohn Scipione TTeamMenuItem::_Init(BList* team, BBitmap* icon, char* name, char* signature,
48618bcf77aSJohn Scipione 	float width, float height)
4875b0fd10dSJohn Scipione {
4881e0308a8SAugustin Cavalier 	if (sHPad == 0.0f) {
4891e0308a8SAugustin Cavalier 		// Initialize the padding values.
4901e0308a8SAugustin Cavalier 		sHPad = be_control_look->ComposeSpacing(B_USE_SMALL_SPACING);
4911e0308a8SAugustin Cavalier 		sVPad = ceilf(be_control_look->ComposeSpacing(B_USE_SMALL_SPACING) / 4.0f);
4921e0308a8SAugustin Cavalier 		sLabelOffset = ceilf((be_control_look->DefaultLabelSpacing() / 3.0f) * 4.0f);
4931e0308a8SAugustin Cavalier 	}
4941e0308a8SAugustin Cavalier 
4955b0fd10dSJohn Scipione 	fTeam = team;
4965b0fd10dSJohn Scipione 	fIcon = icon;
497c9363f78SJohn Scipione 	fSignature = signature;
498c38afcd6SJohn Scipione 
499c38afcd6SJohn Scipione 	if (name == NULL) {
5005b0fd10dSJohn Scipione 		char temp[32];
5015b0fd10dSJohn Scipione 		snprintf(temp, sizeof(temp), "team %ld", (addr_t)team->ItemAt(0));
502c38afcd6SJohn Scipione 		name = strdup(temp);
5035b0fd10dSJohn Scipione 	}
504c9363f78SJohn Scipione 
505c38afcd6SJohn Scipione 	SetLabel(name);
506c9363f78SJohn Scipione 
5071dccb7aaSJohn Scipione 	fOverrideWidth = width;
5081dccb7aaSJohn Scipione 	fOverrideHeight = height;
5095b0fd10dSJohn Scipione 
5101dccb7aaSJohn Scipione 	fBarView = static_cast<TBarApp*>(be_app)->BarView();
5115b0fd10dSJohn Scipione 
512c38afcd6SJohn Scipione 	BFont font(be_plain_font);
513c38afcd6SJohn Scipione 	fLabelWidth = ceilf(font.StringWidth(name));
514c38afcd6SJohn Scipione 	font_height fontHeight;
515c38afcd6SJohn Scipione 	font.GetHeight(&fontHeight);
516c38afcd6SJohn Scipione 	fLabelAscent = ceilf(fontHeight.ascent);
517c38afcd6SJohn Scipione 	fLabelDescent = ceilf(fontHeight.descent + fontHeight.leading);
51815eb397eSJohn Scipione 	fLabelHeight = fLabelAscent + fLabelDescent;
519c38afcd6SJohn Scipione 
5205b0fd10dSJohn Scipione 	fOverriddenSelected = false;
5215b0fd10dSJohn Scipione 
5225b0fd10dSJohn Scipione 	fExpanded = false;
5231dccb7aaSJohn Scipione 	fArrowDirection = BControlLook::B_RIGHT_ARROW;
5245b0fd10dSJohn Scipione }
5255b0fd10dSJohn Scipione 
5265b0fd10dSJohn Scipione 
527249a4a18SStephan Aßmus bool
528249a4a18SStephan Aßmus TTeamMenuItem::_IsSelected() const
529249a4a18SStephan Aßmus {
530249a4a18SStephan Aßmus 	return IsSelected() || fOverriddenSelected;
531249a4a18SStephan Aßmus }
532