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