xref: /haiku/src/apps/processcontroller/TeamBarMenuItem.cpp (revision 69f814cded60c5f977a61a2ab747e4456323e6f2)
1 /*
2 	ProcessController © 2000, Georges-Edouard Berenger, All Rights Reserved.
3 	Copyright (C) 2004 beunited.org
4 
5 	This library is free software; you can redistribute it and/or
6 	modify it under the terms of the GNU Lesser General Public
7 	License as published by the Free Software Foundation; either
8 	version 2.1 of the License, or (at your option) any later version.
9 
10 	This library is distributed in the hope that it will be useful,
11 	but WITHOUT ANY WARRANTY; without even the implied warranty of
12 	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13 	Lesser General Public License for more details.
14 
15 	You should have received a copy of the GNU Lesser General Public
16 	License along with this library; if not, write to the Free Software
17 	Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
18 */
19 
20 
21 #include "TeamBarMenuItem.h"
22 
23 #include "Colors.h"
24 #include "ProcessController.h"
25 #include "ThreadBarMenu.h"
26 #include "ThreadBarMenuItem.h"
27 #include "Utilities.h"
28 
29 #include <Bitmap.h>
30 
31 
32 #define B_USAGE_SELF 0
33 
34 
35 TeamBarMenuItem::TeamBarMenuItem(BMenu* menu, BMessage* kill_team, team_id team,
36 	BBitmap* icon, bool deleteIcon)
37 	:
38 	BMenuItem(menu, kill_team),
39 	fTeamID(team),
40 	fIcon(icon),
41 	fDeleteIcon(deleteIcon)
42 {
43 	Init();
44 }
45 
46 
47 void
48 TeamBarMenuItem::Init()
49 {
50 	if (get_team_usage_info(fTeamID, B_USAGE_SELF, &fTeamUsageInfo) != B_OK)
51 		fTeamUsageInfo.kernel_time = fTeamUsageInfo.user_time = 0;
52 
53 	if (fTeamID == B_SYSTEM_TEAM) {
54 		thread_info thinfos;
55 		bigtime_t idle = 0;
56 		for (unsigned int t = 1; t <= gCPUcount; t++) {
57 			if (get_thread_info(t, &thinfos) == B_OK)
58 				idle += thinfos.kernel_time + thinfos.user_time;
59 		}
60 		fTeamUsageInfo.kernel_time += fTeamUsageInfo.user_time;
61 		fTeamUsageInfo.user_time = idle;
62 	}
63 
64 	fLastTime = system_time();
65 	fKernel = -1;
66 	fGrenze1 = -1;
67 	fGrenze2 = -1;
68 }
69 
70 
71 TeamBarMenuItem::~TeamBarMenuItem()
72 {
73 	if (fDeleteIcon)
74 		delete fIcon;
75 }
76 
77 
78 void
79 TeamBarMenuItem::DrawContent()
80 {
81 	BPoint	loc;
82 
83 	DrawIcon();
84 	if (fKernel < 0)
85 		BarUpdate();
86 	else
87 		DrawBar(true);
88 
89 	loc = ContentLocation();
90 	loc.x += 20;
91 	Menu()->MovePenTo(loc);
92 	BMenuItem::DrawContent();
93 }
94 
95 
96 void
97 TeamBarMenuItem::DrawIcon()
98 {
99 	if (fIcon == NULL)
100 		return;
101 
102 	BPoint loc = ContentLocation();
103 	BRect frame = Frame();
104 
105 	loc.y = frame.top + (frame.bottom - frame.top - 15) / 2;
106 
107 	BMenu* menu = Menu();
108 
109 	if (fIcon->ColorSpace() == B_RGBA32) {
110 		menu->SetDrawingMode(B_OP_ALPHA);
111 		menu->SetBlendingMode(B_PIXEL_ALPHA, B_ALPHA_OVERLAY);
112 	} else
113 		menu->SetDrawingMode(B_OP_OVER);
114 
115 	menu->DrawBitmap(fIcon, loc);
116 
117 	menu->SetDrawingMode(B_OP_COPY);
118 }
119 
120 
121 void
122 TeamBarMenuItem::DrawBar(bool force)
123 {
124 	bool selected = IsSelected ();
125 	BRect frame = Frame();
126 	BMenu* menu = Menu ();
127 	rgb_color highColor = menu->HighColor();
128 
129 	BFont font;
130 	menu->GetFont(&font);
131 	frame = bar_rect(frame, &font);
132 
133 	if (fKernel < 0)
134 		return;
135 
136 	if (fGrenze1 < 0)
137 		force = true;
138 
139 	if (force) {
140 		if (selected)
141 			menu->SetHighColor(gFrameColorSelected);
142 		else
143 			menu->SetHighColor(gFrameColor);
144 
145 		menu->StrokeRect(frame);
146 	}
147 
148 	frame.InsetBy(1, 1);
149 	BRect r = frame;
150 	float grenze1 = frame.left + (frame.right - frame.left)
151 		* fKernel / gCPUcount;
152 	float grenze2 = frame.left + (frame.right - frame.left)
153 		* (fKernel + fUser) / gCPUcount;
154 
155 	if (grenze1 > frame.right)
156 		grenze1 = frame.right;
157 
158 	if (grenze2 > frame.right)
159 		grenze2 = frame.right;
160 
161 	r.right = grenze1;
162 	if (!force)
163 		r.left = fGrenze1;
164 
165 	if (r.left < r.right) {
166 		if (selected)
167 			menu->SetHighColor(gKernelColorSelected);
168 		else
169 			menu->SetHighColor(gKernelColor);
170 
171 		menu->FillRect(r);
172 	}
173 
174 	r.left = grenze1;
175 	r.right = grenze2;
176 
177 	if (!force) {
178 		if (fGrenze2 > r.left && r.left >= fGrenze1)
179 			r.left = fGrenze2;
180 
181 		if (fGrenze1 < r.right && r.right <= fGrenze2)
182 			r.right = fGrenze1;
183 	}
184 
185 	if (r.left < r.right) {
186 		if (selected) {
187 			menu->SetHighColor(fTeamID == B_SYSTEM_TEAM
188 				? gIdleColorSelected
189 				: gUserColorSelected);
190 		} else {
191 			menu->SetHighColor(fTeamID == B_SYSTEM_TEAM
192 				? gIdleColor
193 				: gUserColor);
194 		}
195 
196 		menu->FillRect(r);
197 	}
198 
199 	r.left = grenze2;
200 	r.right = frame.right;
201 
202 	if (!force)
203 		r.right = fGrenze2;
204 
205 	if (r.left < r.right) {
206 		if (selected)
207 			menu->SetHighColor(gWhiteSelected);
208 		else
209 			menu->SetHighColor(kWhite);
210 
211 		menu->FillRect(r);
212 	}
213 
214 	menu->SetHighColor(highColor);
215 	fGrenze1 = grenze1;
216 	fGrenze2 = grenze2;
217 }
218 
219 
220 void
221 TeamBarMenuItem::GetContentSize(float* width, float* height)
222 {
223 	BMenuItem::GetContentSize(width, height);
224 	if (height != NULL && *height < 16)
225 		*height = 16;
226 
227 	if (width != NULL)
228 		*width += 40 + kBarWidth;
229 }
230 
231 
232 void
233 TeamBarMenuItem::BarUpdate()
234 {
235 	team_usage_info usage;
236 	if (get_team_usage_info(fTeamID, B_USAGE_SELF, &usage) == B_OK) {
237 		bigtime_t now = system_time();
238 		bigtime_t idle = 0;
239 		if (fTeamID == B_SYSTEM_TEAM) {
240 			thread_info thinfos;
241 			for (unsigned int t = 1; t <= gCPUcount; t++) {
242 				if (get_thread_info(t, &thinfos) == B_OK)
243 					idle += thinfos.kernel_time + thinfos.user_time;
244 			}
245 			usage.kernel_time += usage.user_time;
246 			usage.user_time = idle;
247 			idle -= fTeamUsageInfo.user_time;
248 		}
249 
250 		fKernel = double(usage.kernel_time - fTeamUsageInfo.kernel_time - idle)
251 			/ double(now - fLastTime);
252 
253 		fUser = double(usage.user_time - fTeamUsageInfo.user_time)
254 			/ double(now - fLastTime);
255 
256 		if (fKernel < 0)
257 			fKernel = 0;
258 
259 		fLastTime = now;
260 		fTeamUsageInfo = usage;
261 		DrawBar(false);
262 	} else
263 		fKernel = -1;
264 }
265 
266 
267 void
268 TeamBarMenuItem::Reset(char* name, team_id team, BBitmap* icon, bool deleteIcon)
269 {
270 	SetLabel(name);
271 	fTeamID = team;
272 	Init();
273 
274 	if (fDeleteIcon)
275 		delete fIcon;
276 
277 	fDeleteIcon = deleteIcon;
278 	fIcon = icon;
279 	Message()->ReplaceInt32("team", team);
280 	((ThreadBarMenu*)Submenu())->Reset(team);
281 	BarUpdate();
282 }
283