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