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