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