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 frame.right -= 24; 127 frame.left = frame.right-kBarWidth; 128 frame.top += 5; 129 frame.bottom = frame.top+8; 130 131 if (fKernel < 0) 132 return; 133 134 if (fGrenze1 < 0) 135 force = true; 136 137 if (force) { 138 if (selected) 139 menu->SetHighColor(gFrameColorSelected); 140 else 141 menu->SetHighColor(gFrameColor); 142 143 menu->StrokeRect(frame); 144 } 145 146 frame.InsetBy(1, 1); 147 BRect r = frame; 148 float grenze1 = frame.left + (frame.right - frame.left) 149 * fKernel / gCPUcount; 150 float grenze2 = frame.left + (frame.right - frame.left) 151 * (fKernel + fUser) / gCPUcount; 152 153 if (grenze1 > frame.right) 154 grenze1 = frame.right; 155 156 if (grenze2 > frame.right) 157 grenze2 = frame.right; 158 159 r.right = grenze1; 160 if (!force) 161 r.left = fGrenze1; 162 163 if (r.left < r.right) { 164 if (selected) 165 menu->SetHighColor(gKernelColorSelected); 166 else 167 menu->SetHighColor(gKernelColor); 168 169 menu->FillRect(r); 170 } 171 172 r.left = grenze1; 173 r.right = grenze2; 174 175 if (!force) { 176 if (fGrenze2 > r.left && r.left >= fGrenze1) 177 r.left = fGrenze2; 178 179 if (fGrenze1 < r.right && r.right <= fGrenze2) 180 r.right = fGrenze1; 181 } 182 183 if (r.left < r.right) { 184 if (selected) { 185 menu->SetHighColor(fTeamID == B_SYSTEM_TEAM 186 ? gIdleColorSelected 187 : gUserColorSelected); 188 } else { 189 menu->SetHighColor(fTeamID == B_SYSTEM_TEAM 190 ? gIdleColor 191 : gUserColor); 192 } 193 194 menu->FillRect(r); 195 } 196 197 r.left = grenze2; 198 r.right = frame.right; 199 200 if (!force) 201 r.right = fGrenze2; 202 203 if (r.left < r.right) { 204 if (selected) 205 menu->SetHighColor(gWhiteSelected); 206 else 207 menu->SetHighColor(kWhite); 208 209 menu->FillRect(r); 210 } 211 212 menu->SetHighColor(kBlack); 213 fGrenze1 = grenze1; 214 fGrenze2 = grenze2; 215 } 216 217 218 void 219 TeamBarMenuItem::GetContentSize(float* width, float* height) 220 { 221 BMenuItem::GetContentSize(width, height); 222 if (height != NULL && *height < 16) 223 *height = 16; 224 225 if (width != NULL) 226 *width += 40 + kBarWidth; 227 } 228 229 230 void 231 TeamBarMenuItem::BarUpdate() 232 { 233 team_usage_info usage; 234 if (get_team_usage_info(fTeamID, B_USAGE_SELF, &usage) == B_OK) { 235 bigtime_t now = system_time(); 236 bigtime_t idle = 0; 237 if (fTeamID == B_SYSTEM_TEAM) { 238 thread_info thinfos; 239 for (unsigned int t = 1; t <= gCPUcount; t++) { 240 if (get_thread_info(t, &thinfos) == B_OK) 241 idle += thinfos.kernel_time + thinfos.user_time; 242 } 243 usage.kernel_time += usage.user_time; 244 usage.user_time = idle; 245 idle -= fTeamUsageInfo.user_time; 246 } 247 248 fKernel = double(usage.kernel_time - fTeamUsageInfo.kernel_time - idle) 249 / double(now - fLastTime); 250 251 fUser = double(usage.user_time - fTeamUsageInfo.user_time) 252 / double(now - fLastTime); 253 254 if (fKernel < 0) 255 fKernel = 0; 256 257 fLastTime = now; 258 fTeamUsageInfo = usage; 259 DrawBar(false); 260 } else 261 fKernel = -1; 262 } 263 264 265 void 266 TeamBarMenuItem::Reset(char* name, team_id team, BBitmap* icon, bool deleteIcon) 267 { 268 SetLabel(name); 269 fTeamID = team; 270 Init(); 271 272 if (fDeleteIcon) 273 delete fIcon; 274 275 fDeleteIcon = deleteIcon; 276 fIcon = icon; 277 Message()->ReplaceInt32("team", team); 278 ((ThreadBarMenu*)Submenu())->Reset(team); 279 BarUpdate(); 280 } 281