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