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 "MemoryBarMenuItem.h" 22 23 #include "Colors.h" 24 #include "MemoryBarMenu.h" 25 #include "ProcessController.h" 26 27 #include <Bitmap.h> 28 #include <StringForSize.h> 29 30 #include <stdio.h> 31 32 33 MemoryBarMenuItem::MemoryBarMenuItem(const char *label, team_id team, 34 BBitmap* icon, bool deleteIcon, BMessage* message) 35 : BMenuItem(label, message), 36 fTeamID(team), 37 fIcon(icon), 38 fDeleteIcon(deleteIcon) 39 { 40 Init(); 41 } 42 43 44 MemoryBarMenuItem::~MemoryBarMenuItem() 45 { 46 if (fDeleteIcon) 47 delete fIcon; 48 } 49 50 51 void 52 MemoryBarMenuItem::Init() 53 { 54 fWriteMemory = -1; 55 fAllMemory = -1; 56 fGrenze1 = -1; 57 fGrenze2 = -1; 58 fLastCommitted = -1; 59 fLastWrite = -1; 60 fLastAll = -1; 61 } 62 63 64 void 65 MemoryBarMenuItem::DrawContent() 66 { 67 DrawIcon(); 68 if (fWriteMemory < 0) 69 BarUpdate(); 70 else 71 DrawBar(true); 72 73 BPoint loc = ContentLocation(); 74 loc.x += 20; 75 Menu()->MovePenTo(loc); 76 BMenuItem::DrawContent(); 77 } 78 79 80 void 81 MemoryBarMenuItem::DrawIcon() 82 { 83 // TODO: exact code duplication with TeamBarMenuItem::DrawIcon() 84 if (!fIcon) 85 return; 86 87 BPoint loc = ContentLocation(); 88 BRect frame = Frame(); 89 90 loc.y = frame.top + (frame.bottom - frame.top - 15) / 2; 91 92 BMenu* menu = Menu(); 93 94 if (fIcon->ColorSpace() == B_RGBA32) { 95 menu->SetDrawingMode(B_OP_ALPHA); 96 menu->SetBlendingMode(B_PIXEL_ALPHA, B_ALPHA_OVERLAY); 97 } else 98 menu->SetDrawingMode(B_OP_OVER); 99 100 menu->DrawBitmap(fIcon, loc); 101 102 menu->SetDrawingMode(B_OP_COPY); 103 } 104 105 106 void 107 MemoryBarMenuItem::DrawBar(bool force) 108 { 109 // only draw anything if something has changed 110 if (!force && fWriteMemory == fLastWrite && fAllMemory == fLastAll 111 && fCommittedMemory == fLastCommitted) 112 return; 113 114 bool selected = IsSelected(); 115 BRect frame = Frame(); 116 BMenu* menu = Menu(); 117 rgb_color highColor = menu->HighColor(); 118 119 // draw the bar itself 120 121 BRect rect(frame.right - kMargin - kBarWidth, frame.top + 5, 122 frame.right - kMargin, frame.top + 13); 123 if (fWriteMemory < 0) 124 return; 125 126 if (fGrenze1 < 0) 127 force = true; 128 129 if (force) { 130 if (selected) 131 menu->SetHighColor(gFrameColorSelected); 132 else 133 menu->SetHighColor(gFrameColor); 134 menu->StrokeRect(rect); 135 } 136 137 rect.InsetBy(1, 1); 138 BRect r = rect; 139 double grenze1 = rect.left + (rect.right - rect.left) * float(fWriteMemory) 140 / fCommittedMemory; 141 double grenze2 = rect.left + (rect.right - rect.left) * float(fAllMemory) 142 / fCommittedMemory; 143 if (grenze1 > rect.right) 144 grenze1 = rect.right; 145 if (grenze2 > rect.right) 146 grenze2 = rect.right; 147 r.right = grenze1; 148 if (!force) 149 r.left = fGrenze1; 150 if (r.left < r.right) { 151 if (selected) 152 menu->SetHighColor(gKernelColorSelected); 153 else 154 menu->SetHighColor(gKernelColor); 155 menu->FillRect(r); 156 } 157 158 r.left = grenze1; 159 r.right = grenze2; 160 161 if (!force) { 162 if (fGrenze2 > r.left && r.left >= fGrenze1) 163 r.left = fGrenze2; 164 if (fGrenze1 < r.right && r.right <= fGrenze2) 165 r.right = fGrenze1; 166 } 167 168 if (r.left < r.right) { 169 if (selected) 170 menu->SetHighColor(gUserColorSelected); 171 else 172 menu->SetHighColor(gUserColor); 173 menu->FillRect(r); 174 } 175 176 r.left = grenze2; 177 r.right = rect.right; 178 179 if (!force) 180 r.right = fGrenze2; 181 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(highColor); 191 fGrenze1 = grenze1; 192 fGrenze2 = grenze2; 193 194 fLastCommitted = fCommittedMemory; 195 196 // Draw the values if necessary; if only fCommitedMemory changes, only 197 // the bar might have to be updated 198 199 if (!force && fWriteMemory == fLastWrite && fAllMemory == fLastAll) 200 return; 201 202 if (selected) 203 menu->SetLowColor(gMenuBackColorSelected); 204 else 205 menu->SetLowColor(gMenuBackColor); 206 207 BRect textRect(rect.left - kMargin - gMemoryTextWidth, frame.top, 208 rect.left - kMargin, frame.bottom); 209 menu->FillRect(textRect, B_SOLID_LOW); 210 211 fLastWrite = fWriteMemory; 212 fLastAll = fAllMemory; 213 214 if (selected) 215 menu->SetHighColor(ui_color(B_MENU_SELECTED_ITEM_TEXT_COLOR)); 216 else 217 menu->SetHighColor(ui_color(B_MENU_ITEM_TEXT_COLOR)); 218 219 char infos[128]; 220 string_for_size(fWriteMemory * 1024.0, infos, sizeof(infos)); 221 222 BPoint loc(rect.left - kMargin - gMemoryTextWidth / 2 - menu->StringWidth(infos), 223 rect.bottom + 1); 224 menu->DrawString(infos, loc); 225 226 string_for_size(fAllMemory * 1024.0, infos, sizeof(infos)); 227 loc.x = rect.left - kMargin - menu->StringWidth(infos); 228 menu->DrawString(infos, loc); 229 menu->SetHighColor(highColor); 230 } 231 232 233 void 234 MemoryBarMenuItem::GetContentSize(float* _width, float* _height) 235 { 236 BMenuItem::GetContentSize(_width, _height); 237 if (*_height < 16) 238 *_height = 16; 239 *_width += 30 + kBarWidth + kMargin + gMemoryTextWidth; 240 } 241 242 243 int 244 MemoryBarMenuItem::UpdateSituation(int64 committedMemory) 245 { 246 fCommittedMemory = committedMemory; 247 BarUpdate(); 248 return fWriteMemory; 249 } 250 251 252 void 253 MemoryBarMenuItem::BarUpdate() 254 { 255 area_info areaInfo; 256 ssize_t cookie = 0; 257 int64 lram_size = 0; 258 int64 lwram_size = 0; 259 bool exists = false; 260 261 while (get_next_area_info(fTeamID, &cookie, &areaInfo) == B_OK) { 262 exists = true; 263 lram_size += areaInfo.ram_size; 264 265 // TODO: this won't work this way anymore under Haiku! 266 // int zone = (int (areaInfo.address) & 0xf0000000) >> 24; 267 if ((areaInfo.protection & B_WRITE_AREA) != 0) 268 lwram_size += areaInfo.ram_size; 269 // && (zone & 0xf0) != 0xA0 // Exclude media buffers 270 // && (fTeamID != gAppServerTeamID || zone != 0x90)) // Exclude app_server side of bitmaps 271 } 272 if (!exists) { 273 team_info info; 274 exists = get_team_info(fTeamID, &info) == B_OK; 275 } 276 if (exists) { 277 fWriteMemory = lwram_size / 1024; 278 fAllMemory = lram_size / 1024; 279 DrawBar(false); 280 } else 281 fWriteMemory = -1; 282 } 283 284 285 void 286 MemoryBarMenuItem::Reset(char* name, team_id team, BBitmap* icon, 287 bool deleteIcon) 288 { 289 SetLabel(name); 290 fTeamID = team; 291 if (fDeleteIcon) 292 delete fIcon; 293 294 fDeleteIcon = deleteIcon; 295 fIcon = icon; 296 Init(); 297 } 298