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