1/*
2 * Copyright 2000, Georges-Edouard Berenger. All rights reserved.
3 * Distributed under the terms of the MIT License.
4 */
5
6
7#include "KernelMemoryBarMenuItem.h"
8
9#include "Colors.h"
10#include "MemoryBarMenu.h"
11#include "ProcessController.h"
12
13#include <stdio.h>
14
15#include <Catalog.h>
16#include <StringForSize.h>
17
18#undef B_TRANSLATION_CONTEXT
19#define B_TRANSLATION_CONTEXT "ProcessController"
20
21
22KernelMemoryBarMenuItem::KernelMemoryBarMenuItem(system_info& systemInfo)
23	: BMenuItem(B_TRANSLATE("System resources & caches" B_UTF8_ELLIPSIS), NULL)
24{
25	fLastSum = -1;
26	fGrenze1 = -1;
27	fGrenze2 = -1;
28	fPhysicalMemory = (int64)systemInfo.max_pages * B_PAGE_SIZE / 1024LL;
29	fCommittedMemory = (int64)systemInfo.used_pages * B_PAGE_SIZE / 1024LL;
30	fCachedMemory = (int64)systemInfo.cached_pages * B_PAGE_SIZE / 1024LL;
31}
32
33
34void
35KernelMemoryBarMenuItem::DrawContent()
36{
37	DrawBar(true);
38	Menu()->MovePenTo(ContentLocation());
39	BMenuItem::DrawContent();
40}
41
42
43void
44KernelMemoryBarMenuItem::UpdateSituation(int64 committedMemory,
45	int64 cachedMemory)
46{
47	fCommittedMemory = committedMemory;
48	fCachedMemory = cachedMemory;
49	DrawBar(false);
50}
51
52
53void
54KernelMemoryBarMenuItem::DrawBar(bool force)
55{
56	bool selected = IsSelected();
57	BRect frame = Frame();
58	BMenu* menu = Menu();
59	rgb_color highColor = menu->HighColor();
60
61	BFont font;
62	menu->GetFont(&font);
63	BRect cadre = bar_rect(frame, &font);
64
65	// draw the bar itself
66	if (fLastSum < 0)
67		force = true;
68	if (force) {
69		if (selected)
70			menu->SetHighColor(gFrameColorSelected);
71		else
72			menu->SetHighColor(gFrameColor);
73		menu->StrokeRect (cadre);
74	}
75	cadre.InsetBy(1, 1);
76	BRect r = cadre;
77
78	double grenze1 = cadre.left + (cadre.right - cadre.left)
79						* fCachedMemory / fPhysicalMemory;
80	double grenze2 = cadre.left + (cadre.right - cadre.left)
81						* fCommittedMemory / fPhysicalMemory;
82	if (grenze1 > cadre.right)
83		grenze1 = cadre.right;
84	if (grenze2 > cadre.right)
85		grenze2 = cadre.right;
86	r.right = grenze1;
87	if (!force)
88		r.left = fGrenze1;
89	if (r.left < r.right) {
90		if (selected)
91			menu->SetHighColor(gKernelColorSelected);
92		else
93			menu->SetHighColor(gKernelColor);
94		menu->FillRect (r);
95	}
96	r.left = grenze1;
97	r.right = grenze2;
98	if (!force) {
99		if (fGrenze2 > r.left && r.left >= fGrenze1)
100			r.left = fGrenze2;
101		if (fGrenze1 < r.right && r.right <= fGrenze2)
102			r.right = fGrenze1;
103	}
104	if (r.left < r.right) {
105		if (selected)
106			menu->SetHighColor(tint_color (kLavender, B_HIGHLIGHT_BACKGROUND_TINT));
107		else
108			menu->SetHighColor(kLavender);
109		menu->FillRect (r);
110	}
111	r.left = grenze2;
112	r.right = cadre.right;
113	if (!force)
114		r.right = fGrenze2;
115	if (r.left < r.right) {
116		if (selected)
117			menu->SetHighColor(gWhiteSelected);
118		else
119			menu->SetHighColor(kWhite);
120		menu->FillRect(r);
121	}
122	menu->SetHighColor(highColor);
123	fGrenze1 = grenze1;
124	fGrenze2 = grenze2;
125
126	// draw the value
127	double sum = fCachedMemory * FLT_MAX + fCommittedMemory;
128	if (force || sum != fLastSum) {
129		if (selected) {
130			menu->SetLowColor(gMenuBackColorSelected);
131			menu->SetHighColor(gMenuBackColorSelected);
132		} else {
133			menu->SetLowColor(gMenuBackColor);
134			menu->SetHighColor(gMenuBackColor);
135		}
136		BRect trect(cadre.left - kMargin - gMemoryTextWidth, frame.top,
137			cadre.left - kMargin, frame.bottom);
138		menu->FillRect(trect);
139		menu->SetHighColor(highColor);
140
141		char infos[128];
142		string_for_size(fCachedMemory * 1024.0, infos, sizeof(infos));
143		BPoint loc(cadre.left, cadre.bottom + 1);
144		loc.x -= kMargin + gMemoryTextWidth / 2 + menu->StringWidth(infos);
145		menu->DrawString(infos, loc);
146		string_for_size(fCommittedMemory * 1024.0, infos, sizeof(infos));
147		loc.x = cadre.left - kMargin - menu->StringWidth(infos);
148		menu->DrawString(infos, loc);
149		fLastSum = sum;
150	}
151}
152
153
154void
155KernelMemoryBarMenuItem::GetContentSize(float* _width, float* _height)
156{
157	BMenuItem::GetContentSize(_width, _height);
158	if (*_height < 16)
159		*_height = 16;
160
161	*_width += 20 + kBarWidth + kMargin + gMemoryTextWidth;
162}
163
164