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