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