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