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