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