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 BFont font; 120 menu->GetFont(&font); 121 BRect rect = bar_rect(frame, &font); 122 123 // draw the bar itself 124 if (fWriteMemory < 0) 125 return; 126 127 if (fGrenze1 < 0) 128 force = true; 129 130 if (force) { 131 if (selected) 132 menu->SetHighColor(gFrameColorSelected); 133 else 134 menu->SetHighColor(gFrameColor); 135 menu->StrokeRect(rect); 136 } 137 138 rect.InsetBy(1, 1); 139 BRect r = rect; 140 double grenze1 = rect.left + (rect.right - rect.left) * float(fWriteMemory) 141 / fCommittedMemory; 142 double grenze2 = rect.left + (rect.right - rect.left) * float(fAllMemory) 143 / fCommittedMemory; 144 if (grenze1 > rect.right) 145 grenze1 = rect.right; 146 if (grenze2 > rect.right) 147 grenze2 = rect.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(gUserColorSelected); 172 else 173 menu->SetHighColor(gUserColor); 174 menu->FillRect(r); 175 } 176 177 r.left = grenze2; 178 r.right = rect.right; 179 180 if (!force) 181 r.right = fGrenze2; 182 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(highColor); 192 fGrenze1 = grenze1; 193 fGrenze2 = grenze2; 194 195 fLastCommitted = fCommittedMemory; 196 197 // Draw the values if necessary; if only fCommitedMemory changes, only 198 // the bar might have to be updated 199 200 if (!force && fWriteMemory == fLastWrite && fAllMemory == fLastAll) 201 return; 202 203 if (selected) 204 menu->SetLowColor(gMenuBackColorSelected); 205 else 206 menu->SetLowColor(gMenuBackColor); 207 208 BRect textRect(rect.left - kMargin - gMemoryTextWidth, frame.top, 209 rect.left - kMargin, frame.bottom); 210 menu->FillRect(textRect, B_SOLID_LOW); 211 212 fLastWrite = fWriteMemory; 213 fLastAll = fAllMemory; 214 215 if (selected) 216 menu->SetHighColor(ui_color(B_MENU_SELECTED_ITEM_TEXT_COLOR)); 217 else 218 menu->SetHighColor(ui_color(B_MENU_ITEM_TEXT_COLOR)); 219 220 char infos[128]; 221 string_for_size(fWriteMemory * 1024.0, infos, sizeof(infos)); 222 223 BPoint loc(rect.left - kMargin - gMemoryTextWidth / 2 - menu->StringWidth(infos), 224 rect.bottom + 1); 225 menu->DrawString(infos, loc); 226 227 string_for_size(fAllMemory * 1024.0, infos, sizeof(infos)); 228 loc.x = rect.left - kMargin - menu->StringWidth(infos); 229 menu->DrawString(infos, loc); 230 menu->SetHighColor(highColor); 231 } 232 233 234 void 235 MemoryBarMenuItem::GetContentSize(float* _width, float* _height) 236 { 237 BMenuItem::GetContentSize(_width, _height); 238 if (*_height < 16) 239 *_height = 16; 240 *_width += 30 + kBarWidth + kMargin + gMemoryTextWidth; 241 } 242 243 244 int 245 MemoryBarMenuItem::UpdateSituation(int64 committedMemory) 246 { 247 fCommittedMemory = committedMemory; 248 BarUpdate(); 249 return fWriteMemory; 250 } 251 252 253 void 254 MemoryBarMenuItem::BarUpdate() 255 { 256 area_info areaInfo; 257 ssize_t cookie = 0; 258 int64 lram_size = 0; 259 int64 lwram_size = 0; 260 bool exists = false; 261 262 while (get_next_area_info(fTeamID, &cookie, &areaInfo) == B_OK) { 263 exists = true; 264 lram_size += areaInfo.ram_size; 265 266 // TODO: this won't work this way anymore under Haiku! 267 // int zone = (int (areaInfo.address) & 0xf0000000) >> 24; 268 if ((areaInfo.protection & B_WRITE_AREA) != 0) 269 lwram_size += areaInfo.ram_size; 270 // && (zone & 0xf0) != 0xA0 // Exclude media buffers 271 // && (fTeamID != gAppServerTeamID || zone != 0x90)) // Exclude app_server side of bitmaps 272 } 273 if (!exists) { 274 team_info info; 275 exists = get_team_info(fTeamID, &info) == B_OK; 276 } 277 if (exists) { 278 fWriteMemory = lwram_size / 1024; 279 fAllMemory = lram_size / 1024; 280 DrawBar(false); 281 } else 282 fWriteMemory = -1; 283 } 284 285 286 void 287 MemoryBarMenuItem::Reset(char* name, team_id team, BBitmap* icon, 288 bool deleteIcon) 289 { 290 SetLabel(name); 291 fTeamID = team; 292 if (fDeleteIcon) 293 delete fIcon; 294 295 fDeleteIcon = deleteIcon; 296 fIcon = icon; 297 Init(); 298 } 299