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