Files
haiku-beta6/src/apps/processcontroller/MemoryBarMenuItem.cpp
T
Augustin Cavalier f65814780e ProcessController: Relicense as MIT.
We received permission from the original author and all relevant contributors
(see the mailing list) to do this. (As best as can be established, BeUnited
did not modify the source code after importing besides adding their copyright.)
2020-10-10 15:57:49 -04:00

285 lines
5.7 KiB
C++

/*
* Copyright 2000, Georges-Edouard Berenger. All rights reserved.
* Distributed under the terms of the MIT License.
*/
#include "MemoryBarMenuItem.h"
#include "Colors.h"
#include "MemoryBarMenu.h"
#include "ProcessController.h"
#include <Bitmap.h>
#include <StringForSize.h>
#include <stdio.h>
MemoryBarMenuItem::MemoryBarMenuItem(const char *label, team_id team,
BBitmap* icon, bool deleteIcon, BMessage* message)
: BMenuItem(label, message),
fTeamID(team),
fIcon(icon),
fDeleteIcon(deleteIcon)
{
Init();
}
MemoryBarMenuItem::~MemoryBarMenuItem()
{
if (fDeleteIcon)
delete fIcon;
}
void
MemoryBarMenuItem::Init()
{
fWriteMemory = -1;
fAllMemory = -1;
fGrenze1 = -1;
fGrenze2 = -1;
fLastCommitted = -1;
fLastWrite = -1;
fLastAll = -1;
}
void
MemoryBarMenuItem::DrawContent()
{
DrawIcon();
if (fWriteMemory < 0)
BarUpdate();
else
DrawBar(true);
BPoint loc = ContentLocation();
loc.x += 20;
Menu()->MovePenTo(loc);
BMenuItem::DrawContent();
}
void
MemoryBarMenuItem::DrawIcon()
{
// TODO: exact code duplication with TeamBarMenuItem::DrawIcon()
if (!fIcon)
return;
BPoint loc = ContentLocation();
BRect frame = Frame();
loc.y = frame.top + (frame.bottom - frame.top - 15) / 2;
BMenu* menu = Menu();
if (fIcon->ColorSpace() == B_RGBA32) {
menu->SetDrawingMode(B_OP_ALPHA);
menu->SetBlendingMode(B_PIXEL_ALPHA, B_ALPHA_OVERLAY);
} else
menu->SetDrawingMode(B_OP_OVER);
menu->DrawBitmap(fIcon, loc);
menu->SetDrawingMode(B_OP_COPY);
}
void
MemoryBarMenuItem::DrawBar(bool force)
{
// only draw anything if something has changed
if (!force && fWriteMemory == fLastWrite && fAllMemory == fLastAll
&& fCommittedMemory == fLastCommitted)
return;
bool selected = IsSelected();
BRect frame = Frame();
BMenu* menu = Menu();
rgb_color highColor = menu->HighColor();
BFont font;
menu->GetFont(&font);
BRect rect = bar_rect(frame, &font);
// draw the bar itself
if (fWriteMemory < 0)
return;
if (fGrenze1 < 0)
force = true;
if (force) {
if (selected)
menu->SetHighColor(gFrameColorSelected);
else
menu->SetHighColor(gFrameColor);
menu->StrokeRect(rect);
}
rect.InsetBy(1, 1);
BRect r = rect;
double grenze1 = rect.left + (rect.right - rect.left) * float(fWriteMemory)
/ fCommittedMemory;
double grenze2 = rect.left + (rect.right - rect.left) * float(fAllMemory)
/ fCommittedMemory;
if (grenze1 > rect.right)
grenze1 = rect.right;
if (grenze2 > rect.right)
grenze2 = rect.right;
r.right = grenze1;
if (!force)
r.left = fGrenze1;
if (r.left < r.right) {
if (selected)
menu->SetHighColor(gKernelColorSelected);
else
menu->SetHighColor(gKernelColor);
menu->FillRect(r);
}
r.left = grenze1;
r.right = grenze2;
if (!force) {
if (fGrenze2 > r.left && r.left >= fGrenze1)
r.left = fGrenze2;
if (fGrenze1 < r.right && r.right <= fGrenze2)
r.right = fGrenze1;
}
if (r.left < r.right) {
if (selected)
menu->SetHighColor(gUserColorSelected);
else
menu->SetHighColor(gUserColor);
menu->FillRect(r);
}
r.left = grenze2;
r.right = rect.right;
if (!force)
r.right = fGrenze2;
if (r.left < r.right) {
if (selected)
menu->SetHighColor(gWhiteSelected);
else
menu->SetHighColor(kWhite);
menu->FillRect(r);
}
menu->SetHighColor(highColor);
fGrenze1 = grenze1;
fGrenze2 = grenze2;
fLastCommitted = fCommittedMemory;
// Draw the values if necessary; if only fCommitedMemory changes, only
// the bar might have to be updated
if (!force && fWriteMemory == fLastWrite && fAllMemory == fLastAll)
return;
if (selected)
menu->SetLowColor(gMenuBackColorSelected);
else
menu->SetLowColor(gMenuBackColor);
BRect textRect(rect.left - kMargin - gMemoryTextWidth, frame.top,
rect.left - kMargin, frame.bottom);
menu->FillRect(textRect, B_SOLID_LOW);
fLastWrite = fWriteMemory;
fLastAll = fAllMemory;
if (selected)
menu->SetHighColor(ui_color(B_MENU_SELECTED_ITEM_TEXT_COLOR));
else
menu->SetHighColor(ui_color(B_MENU_ITEM_TEXT_COLOR));
char infos[128];
string_for_size(fWriteMemory * 1024.0, infos, sizeof(infos));
BPoint loc(rect.left - kMargin - gMemoryTextWidth / 2 - menu->StringWidth(infos),
rect.bottom + 1);
menu->DrawString(infos, loc);
string_for_size(fAllMemory * 1024.0, infos, sizeof(infos));
loc.x = rect.left - kMargin - menu->StringWidth(infos);
menu->DrawString(infos, loc);
menu->SetHighColor(highColor);
}
void
MemoryBarMenuItem::GetContentSize(float* _width, float* _height)
{
BMenuItem::GetContentSize(_width, _height);
if (*_height < 16)
*_height = 16;
*_width += 30 + kBarWidth + kMargin + gMemoryTextWidth;
}
int
MemoryBarMenuItem::UpdateSituation(int64 committedMemory)
{
fCommittedMemory = committedMemory;
BarUpdate();
return fWriteMemory;
}
void
MemoryBarMenuItem::BarUpdate()
{
area_info areaInfo;
ssize_t cookie = 0;
int64 lram_size = 0;
int64 lwram_size = 0;
bool exists = false;
while (get_next_area_info(fTeamID, &cookie, &areaInfo) == B_OK) {
exists = true;
lram_size += areaInfo.ram_size;
// TODO: this won't work this way anymore under Haiku!
// int zone = (int (areaInfo.address) & 0xf0000000) >> 24;
if ((areaInfo.protection & B_WRITE_AREA) != 0)
lwram_size += areaInfo.ram_size;
// && (zone & 0xf0) != 0xA0 // Exclude media buffers
// && (fTeamID != gAppServerTeamID || zone != 0x90)) // Exclude app_server side of bitmaps
}
if (!exists) {
team_info info;
exists = get_team_info(fTeamID, &info) == B_OK;
}
if (exists) {
fWriteMemory = lwram_size / 1024;
fAllMemory = lram_size / 1024;
DrawBar(false);
} else
fWriteMemory = -1;
}
void
MemoryBarMenuItem::Reset(char* name, team_id team, BBitmap* icon,
bool deleteIcon)
{
SetLabel(name);
fTeamID = team;
if (fDeleteIcon)
delete fIcon;
fDeleteIcon = deleteIcon;
fIcon = icon;
Init();
}