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