xref: /haiku/src/apps/processcontroller/TeamBarMenuItem.cpp (revision 6eafb4b041ad79cb936b2041fdb9c56b1209cc10)
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 
28 #include <Bitmap.h>
29 
30 
31 #define B_USAGE_SELF 0
32 
33 
34 TeamBarMenuItem::TeamBarMenuItem(BMenu* menu, BMessage* kill_team, team_id team,
35 	BBitmap* icon, bool deleteIcon)
36 	:
37 	BMenuItem(menu, kill_team),
38 	fTeamID(team),
39 	fIcon(icon),
40 	fDeleteIcon(deleteIcon)
41 {
42 	Init();
43 }
44 
45 
46 void
47 TeamBarMenuItem::Init()
48 {
49 	if (get_team_usage_info(fTeamID, B_USAGE_SELF, &fTeamUsageInfo) != B_OK)
50 		fTeamUsageInfo.kernel_time = fTeamUsageInfo.user_time = 0;
51 
52 	if (fTeamID == B_SYSTEM_TEAM) {
53 		thread_info thinfos;
54 		bigtime_t idle = 0;
55 		for (unsigned int t = 1; t <= gCPUcount; t++) {
56 			if (get_thread_info(t, &thinfos) == B_OK)
57 				idle += thinfos.kernel_time + thinfos.user_time;
58 		}
59 		fTeamUsageInfo.kernel_time += fTeamUsageInfo.user_time;
60 		fTeamUsageInfo.user_time = idle;
61 	}
62 
63 	fLastTime = system_time();
64 	fKernel = -1;
65 	fGrenze1 = -1;
66 	fGrenze2 = -1;
67 }
68 
69 
70 TeamBarMenuItem::~TeamBarMenuItem()
71 {
72 	if (fDeleteIcon)
73 		delete fIcon;
74 }
75 
76 
77 void
78 TeamBarMenuItem::DrawContent()
79 {
80 	BPoint	loc;
81 
82 	DrawIcon();
83 	if (fKernel < 0)
84 		BarUpdate();
85 	else
86 		DrawBar(true);
87 
88 	loc = ContentLocation();
89 	loc.x += 20;
90 	Menu()->MovePenTo(loc);
91 	BMenuItem::DrawContent();
92 }
93 
94 
95 void
96 TeamBarMenuItem::DrawIcon()
97 {
98 	if (fIcon == NULL)
99 		return;
100 
101 	BPoint loc = ContentLocation();
102 	BRect frame = Frame();
103 
104 	loc.y = frame.top + (frame.bottom - frame.top - 15) / 2;
105 
106 	BMenu* menu = Menu();
107 
108 	if (fIcon->ColorSpace() == B_RGBA32) {
109 		menu->SetDrawingMode(B_OP_ALPHA);
110 		menu->SetBlendingMode(B_PIXEL_ALPHA, B_ALPHA_OVERLAY);
111 	} else
112 		menu->SetDrawingMode(B_OP_OVER);
113 
114 	menu->DrawBitmap(fIcon, loc);
115 
116 	menu->SetDrawingMode(B_OP_COPY);
117 }
118 
119 
120 void
121 TeamBarMenuItem::DrawBar(bool force)
122 {
123 	bool selected = IsSelected ();
124 	BRect frame = Frame();
125 	BMenu* menu = Menu ();
126 	rgb_color highColor = menu->HighColor();
127 	frame.right -=  24;
128 	frame.left = frame.right-kBarWidth;
129 	frame.top += 5;
130 	frame.bottom = frame.top+8;
131 
132 	if (fKernel < 0)
133 		return;
134 
135 	if (fGrenze1 < 0)
136 		force = true;
137 
138 	if (force) {
139 		if (selected)
140 			menu->SetHighColor(gFrameColorSelected);
141 		else
142 			menu->SetHighColor(gFrameColor);
143 
144 		menu->StrokeRect(frame);
145 	}
146 
147 	frame.InsetBy(1, 1);
148 	BRect r = frame;
149 	float grenze1 = frame.left + (frame.right - frame.left)
150 		* fKernel / gCPUcount;
151 	float grenze2 = frame.left + (frame.right - frame.left)
152 		* (fKernel + fUser) / gCPUcount;
153 
154 	if (grenze1 > frame.right)
155 		grenze1 = frame.right;
156 
157 	if (grenze2 > frame.right)
158 		grenze2 = frame.right;
159 
160 	r.right = grenze1;
161 	if (!force)
162 		r.left = fGrenze1;
163 
164 	if (r.left < r.right) {
165 		if (selected)
166 			menu->SetHighColor(gKernelColorSelected);
167 		else
168 			menu->SetHighColor(gKernelColor);
169 
170 		menu->FillRect(r);
171 	}
172 
173 	r.left = grenze1;
174 	r.right = grenze2;
175 
176 	if (!force) {
177 		if (fGrenze2 > r.left && r.left >= fGrenze1)
178 			r.left = fGrenze2;
179 
180 		if (fGrenze1 < r.right && r.right <= fGrenze2)
181 			r.right = fGrenze1;
182 	}
183 
184 	if (r.left < r.right) {
185 		if (selected) {
186 			menu->SetHighColor(fTeamID == B_SYSTEM_TEAM
187 				? gIdleColorSelected
188 				: gUserColorSelected);
189 		} else {
190 			menu->SetHighColor(fTeamID == B_SYSTEM_TEAM
191 				? gIdleColor
192 				: gUserColor);
193 		}
194 
195 		menu->FillRect(r);
196 	}
197 
198 	r.left = grenze2;
199 	r.right = frame.right;
200 
201 	if (!force)
202 		r.right = fGrenze2;
203 
204 	if (r.left < r.right) {
205 		if (selected)
206 			menu->SetHighColor(gWhiteSelected);
207 		else
208 			menu->SetHighColor(kWhite);
209 
210 		menu->FillRect(r);
211 	}
212 
213 	menu->SetHighColor(highColor);
214 	fGrenze1 = grenze1;
215 	fGrenze2 = grenze2;
216 }
217 
218 
219 void
220 TeamBarMenuItem::GetContentSize(float* width, float* height)
221 {
222 	BMenuItem::GetContentSize(width, height);
223 	if (height != NULL && *height < 16)
224 		*height = 16;
225 
226 	if (width != NULL)
227 		*width += 40 + kBarWidth;
228 }
229 
230 
231 void
232 TeamBarMenuItem::BarUpdate()
233 {
234 	team_usage_info usage;
235 	if (get_team_usage_info(fTeamID, B_USAGE_SELF, &usage) == B_OK) {
236 		bigtime_t now = system_time();
237 		bigtime_t idle = 0;
238 		if (fTeamID == B_SYSTEM_TEAM) {
239 			thread_info thinfos;
240 			for (unsigned int t = 1; t <= gCPUcount; t++) {
241 				if (get_thread_info(t, &thinfos) == B_OK)
242 					idle += thinfos.kernel_time + thinfos.user_time;
243 			}
244 			usage.kernel_time += usage.user_time;
245 			usage.user_time = idle;
246 			idle -= fTeamUsageInfo.user_time;
247 		}
248 
249 		fKernel = double(usage.kernel_time - fTeamUsageInfo.kernel_time - idle)
250 			/ double(now - fLastTime);
251 
252 		fUser = double(usage.user_time - fTeamUsageInfo.user_time)
253 			/ double(now - fLastTime);
254 
255 		if (fKernel < 0)
256 			fKernel = 0;
257 
258 		fLastTime = now;
259 		fTeamUsageInfo = usage;
260 		DrawBar(false);
261 	} else
262 		fKernel = -1;
263 }
264 
265 
266 void
267 TeamBarMenuItem::Reset(char* name, team_id team, BBitmap* icon, bool deleteIcon)
268 {
269 	SetLabel(name);
270 	fTeamID = team;
271 	Init();
272 
273 	if (fDeleteIcon)
274 		delete fIcon;
275 
276 	fDeleteIcon = deleteIcon;
277 	fIcon = icon;
278 	Message()->ReplaceInt32("team", team);
279 	((ThreadBarMenu*)Submenu())->Reset(team);
280 	BarUpdate();
281 }
282