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