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