xref: /haiku/src/apps/deskbar/TeamMenu.cpp (revision cbe0a0c436162d78cc3f92a305b64918c839d079)
1 /*
2 Open Tracker License
3 
4 Terms and Conditions
5 
6 Copyright (c) 1991-2000, Be Incorporated. All rights reserved.
7 
8 Permission is hereby granted, free of charge, to any person obtaining a copy of
9 this software and associated documentation files (the "Software"), to deal in
10 the Software without restriction, including without limitation the rights to
11 use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
12 of the Software, and to permit persons to whom the Software is furnished to do
13 so, subject to the following conditions:
14 
15 The above copyright notice and this permission notice applies to all licensees
16 and shall be included in all copies or substantial portions of the Software.
17 
18 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF TITLE, MERCHANTABILITY,
20 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
21 BE INCORPORATED BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
22 AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF, OR IN CONNECTION
23 WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
24 
25 Except as contained in this notice, the name of Be Incorporated shall not be
26 used in advertising or otherwise to promote the sale, use or other dealings in
27 this Software without prior written authorization from Be Incorporated.
28 
29 Tracker(TM), Be(R), BeOS(R), and BeIA(TM) are trademarks or registered
30 trademarks of Be Incorporated in the United States and other countries. Other
31 brand product names are registered trademarks or trademarks of their respective
32 holders.
33 All rights reserved.
34 */
35 
36 
37 #include "TeamMenu.h"
38 
39 #include <algorithm>
40 #include <strings.h>
41 
42 #include <Application.h>
43 #include <Collator.h>
44 #include <Debug.h>
45 #include <Mime.h>
46 #include <Roster.h>
47 
48 #include "BarApp.h"
49 #include "BarMenuBar.h"
50 #include "BarView.h"
51 #include "DeskbarUtils.h"
52 #include "StatusView.h"
53 #include "TeamMenuItem.h"
54 
55 
56 const float kIconPadding = 8.0f;
57 
58 
59 //	#pragma mark - TTeamMenuItem
60 
61 
62 TTeamMenu::TTeamMenu(TBarView* barView)
63 	:
64 	BMenu("Team Menu"),
65 	fBarView(barView)
66 {
67 	SetItemMargins(0.0f, 0.0f, 0.0f, 0.0f);
68 	SetFont(be_plain_font);
69 }
70 
71 
72 int
73 TTeamMenu::CompareByName(const void* first, const void* second)
74 {
75 	BCollator collator;
76 	BLocale::Default()->GetCollator(&collator);
77 
78 	return collator.Compare(
79 		(*(static_cast<BarTeamInfo* const*>(first)))->name,
80 		(*(static_cast<BarTeamInfo* const*>(second)))->name);
81 }
82 
83 
84 void
85 TTeamMenu::AttachedToWindow()
86 {
87 	RemoveItems(0, CountItems(), true);
88 		// remove all items
89 
90 	BMessenger self(this);
91 	BList teamList;
92 	TBarApp::Subscribe(self, &teamList);
93 
94 	bool dragging = fBarView != NULL && fBarView->Dragging();
95 	desk_settings* settings = static_cast<TBarApp*>(be_app)->Settings();
96 	int32 iconSize = static_cast<TBarApp*>(be_app)->IconSize();
97 	float iconOnlyWidth = iconSize + kIconPadding;
98 
99 	// calculate the minimum item width based on font and icon size
100 	float minItemWidth = 0;
101 	if (settings->hideLabels) {
102 		minItemWidth = std::max(floorf(gMinimumWindowWidth / 2),
103 			iconOnlyWidth);
104 	} else {
105 		float labelWidth = gMinimumWindowWidth - iconOnlyWidth
106 			+ (be_plain_font->Size() - 12) * 4;
107 		if (iconSize <= B_LARGE_ICON) // label wraps after 32x32
108 			labelWidth += iconSize - kMinimumIconSize;
109 		minItemWidth = iconOnlyWidth + labelWidth;
110 	}
111 
112 	float maxItemWidth = minItemWidth;
113 
114 	int32 itemCount = teamList.CountItems();
115 	if (!settings->hideLabels) {
116 		// go through list and find the widest label
117 		for (int32 i = 0; i < itemCount; i++) {
118 			BarTeamInfo* barInfo = (BarTeamInfo*)teamList.ItemAt(i);
119 			float labelWidth = StringWidth(barInfo->name);
120 			// label wraps after 32x32
121 			float itemWidth = iconSize > B_LARGE_ICON
122 				? std::max(labelWidth, iconOnlyWidth)
123 				: labelWidth + iconOnlyWidth + kMinimumIconSize
124 					+ (be_plain_font->Size() - 12) * 4;
125 			maxItemWidth = std::max(maxItemWidth, itemWidth);
126 		}
127 
128 		// but not too wide
129 		maxItemWidth = std::min(maxItemWidth, gMaximumWindowWidth);
130 	}
131 
132 	SetMaxContentWidth(maxItemWidth);
133 
134 	if (settings->sortRunningApps)
135 		teamList.SortItems(TTeamMenu::CompareByName);
136 
137 	// go through list and add the items
138 	for (int32 i = 0; i < itemCount; i++) {
139 		// add items back
140 		BarTeamInfo* barInfo = (BarTeamInfo*)teamList.ItemAt(i);
141 		TTeamMenuItem* item = new TTeamMenuItem(barInfo->teams,
142 			barInfo->icon, barInfo->name, barInfo->sig, maxItemWidth);
143 
144 		if (settings->trackerAlwaysFirst
145 			&& strcasecmp(barInfo->sig, kTrackerSignature) == 0) {
146 			AddItem(item, 0);
147 		} else
148 			AddItem(item);
149 
150 		if (dragging && item != NULL) {
151 			bool canhandle = fBarView->AppCanHandleTypes(item->Signature());
152 			if (item->IsEnabled() != canhandle)
153 				item->SetEnabled(canhandle);
154 
155 			BMenu* menu = item->Submenu();
156 			if (menu != NULL) {
157 				menu->SetTrackingHook(fBarView->MenuTrackingHook,
158 					fBarView->GetTrackingHookData());
159 			}
160 		}
161 	}
162 
163 	if (CountItems() == 0) {
164 		BMenuItem* item = new BMenuItem("no application running", NULL);
165 		item->SetEnabled(false);
166 		AddItem(item);
167 	}
168 
169 	if (dragging && fBarView->LockLooper()) {
170 		SetTrackingHook(fBarView->MenuTrackingHook,
171 			fBarView->GetTrackingHookData());
172 		fBarView->DragStart();
173 		fBarView->UnlockLooper();
174 	}
175 
176 	BMenu::AttachedToWindow();
177 }
178 
179 
180 void
181 TTeamMenu::DetachedFromWindow()
182 {
183 	if (fBarView != NULL) {
184 		BLooper* looper = fBarView->Looper();
185 		if (looper != NULL && looper->Lock()) {
186 			fBarView->DragStop();
187 			looper->Unlock();
188 		}
189 	}
190 
191 	BMenu::DetachedFromWindow();
192 
193 	BMessenger self(this);
194 	TBarApp::Unsubscribe(self);
195 }
196