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