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