xref: /haiku/src/apps/powerstatus/ExtendedInfoWindow.cpp (revision 9760dcae2038d47442f4658c2575844c6cf92c40)
1 /*
2  * Copyright 2009, Haiku, Inc. All Rights Reserved.
3  * Distributed under the terms of the MIT License.
4  *
5  * Authors:
6  *		Clemens Zeidler, haiku@Clemens-Zeidler.de
7  */
8 
9 
10 #include "ExtendedInfoWindow.h"
11 
12 #include <Box.h>
13 #include <GroupView.h>
14 #include <SpaceLayoutItem.h>
15 
16 
17 const int kLineSpacing = 5;
18 
19 
20 FontString::FontString()
21 {
22 	font = be_plain_font;
23 }
24 
25 
26 //	#pragma mark -
27 
28 
29 BatteryInfoView::BatteryInfoView()
30 	:
31 	BView("battery info view", B_WILL_DRAW | B_FULL_UPDATE_ON_RESIZE),
32 	fPreferredSize(200, 200),
33 	fMaxStringSize(0, 0)
34 {
35 	SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR));
36 }
37 
38 
39 BatteryInfoView::~BatteryInfoView()
40 {
41 	_ClearStringList();
42 }
43 
44 
45 void
46 BatteryInfoView::Update(battery_info& info, acpi_extended_battery_info& extInfo)
47 {
48 	fBatteryInfo = info;
49 	fBatteryExtendedInfo = extInfo;
50 
51 	_FillStringList();
52 }
53 
54 
55 void
56 BatteryInfoView::Draw(BRect updateRect)
57 {
58 	SetLowColor(ui_color(B_PANEL_BACKGROUND_COLOR));
59 
60 	BPoint point(10, 10);
61 
62 	float space = _MeasureString("").height + kLineSpacing;
63 
64 	for (int i = 0; i < fStringList.CountItems(); i++) {
65 		FontString* fontString = fStringList.ItemAt(i);
66 		SetFont(fontString->font);
67 		DrawString(fontString->string.String(), point);
68 		point.y += space;
69 	}
70 }
71 
72 
73 void
74 BatteryInfoView::GetPreferredSize(float* width, float* height)
75 {
76 	*width = fPreferredSize.width;
77 	*height = fPreferredSize.height;
78 }
79 
80 
81 void
82 BatteryInfoView::AttachedToWindow()
83 {
84 	Window()->CenterOnScreen();
85 }
86 
87 
88 BSize
89 BatteryInfoView::_MeasureString(const BString& string)
90 {
91 	BFont font;
92 	GetFont(&font);
93 	BSize size;
94 
95 	size.width = font.StringWidth(string);
96 
97 	font_height height;
98 	font.GetHeight(&height);
99 	size.height = height.ascent + height.descent;
100 
101 	return size;
102 }
103 
104 
105 void
106 BatteryInfoView::_FillStringList()
107 {
108 	_ClearStringList();
109 
110 	BString powerUnit;
111 	BString rateUnit;
112 	switch (fBatteryExtendedInfo.power_unit) {
113 		case 0:
114 			powerUnit = " mWh";
115 			rateUnit = " mW";
116 			break;
117 
118 		case 1:
119 			powerUnit = " mAh";
120 			rateUnit = " mA";
121 			break;
122 	}
123 
124 	FontString* fontString;
125 
126 	fontString = new FontString;
127 	fStringList.AddItem(fontString);
128 	fontString->font = be_bold_font;
129 
130 	if (fBatteryInfo.state & BATTERY_CHARGING)
131 		fontString->string = "Battery charging";
132 	else if (fBatteryInfo.state & BATTERY_DISCHARGING)
133 		fontString->string = "Battery discharging";
134 	else if (fBatteryInfo.state & BATTERY_CRITICAL_STATE)
135 		fontString->string = "Empty battery slot";
136 	else
137 		fontString->string = "Battery unused";
138 
139 	fontString = new FontString;
140 	fontString->string = "Capacity: ";
141 	fontString->string << fBatteryInfo.capacity;
142 	fontString->string << powerUnit;
143 	_AddToStringList(fontString);
144 
145 	fontString = new FontString;
146 	fontString->string = "Last full charge: ";
147 	fontString->string << fBatteryInfo.full_capacity;
148 	fontString->string << powerUnit;
149 	_AddToStringList(fontString);
150 
151 	fontString = new FontString;
152 	fontString->string = "Current rate: ";
153 	fontString->string << fBatteryInfo.current_rate;
154 	fontString->string << rateUnit;
155 	_AddToStringList(fontString);
156 
157 	// empty line
158 	fontString = new FontString;
159 	_AddToStringList(fontString);
160 
161 	fontString = new FontString;
162 	fontString->string = "Design capacity: ";
163 	fontString->string << fBatteryExtendedInfo.design_capacity;
164 	fontString->string << powerUnit;
165 	_AddToStringList(fontString);
166 
167 	fontString = new FontString;
168 	fontString->string = "Technology: ";
169 	if (fBatteryExtendedInfo.technology == 0)
170 		fontString->string << "non-rechargeable";
171 	else if (fBatteryExtendedInfo.technology == 1)
172 		fontString->string << "rechargeable";
173 	else
174 		fontString->string << "?";
175 	_AddToStringList(fontString);
176 
177 	fontString = new FontString;
178 	fontString->string = "Design voltage: ";
179 	fontString->string << fBatteryExtendedInfo.design_voltage;
180 	fontString->string << " mV";
181 	_AddToStringList(fontString);
182 
183 	fontString = new FontString;
184 	fontString->string = "Design capacity warning: ";
185 	fontString->string << fBatteryExtendedInfo.design_capacity_warning;
186 	fontString->string << powerUnit;
187 	_AddToStringList(fontString);
188 
189 	fontString = new FontString;
190 	fontString->string = "Design capacity low warning: ";
191 	fontString->string << fBatteryExtendedInfo.design_capacity_low;
192 	fontString->string << powerUnit;
193 	_AddToStringList(fontString);
194 
195 	fontString = new FontString;
196 	fontString->string = "Capacity granularity 1: ";
197 	fontString->string << fBatteryExtendedInfo.capacity_granularity_1;
198 	fontString->string << powerUnit;
199 	_AddToStringList(fontString);
200 
201 	fontString = new FontString;
202 	fontString->string = "Capacity granularity 2: ";
203 	fontString->string << fBatteryExtendedInfo.capacity_granularity_2;
204 	fontString->string << powerUnit;
205 	_AddToStringList(fontString);
206 
207 	fontString = new FontString;
208 	fontString->string = "Model number: ";
209 	fontString->string << fBatteryExtendedInfo.model_number;
210 	_AddToStringList(fontString);
211 
212 	fontString = new FontString;
213 	fontString->string = "Serial number: ";
214 	fontString->string << fBatteryExtendedInfo.serial_number;
215 	_AddToStringList(fontString);
216 
217 	fontString = new FontString;
218 	fontString->string = "Type: ";
219 	fontString->string += fBatteryExtendedInfo.type;
220 	_AddToStringList(fontString);
221 
222 	fontString = new FontString;
223 	fontString->string = "OEM info: ";
224 	fontString->string += fBatteryExtendedInfo.oem_info;
225 	_AddToStringList(fontString);
226 
227 	fPreferredSize.width = fMaxStringSize.width + 10;
228 	fPreferredSize.height = (fMaxStringSize.height + kLineSpacing) *
229 		fStringList.CountItems();
230 }
231 
232 
233 void
234 BatteryInfoView::_AddToStringList(FontString* fontString)
235 {
236 	fStringList.AddItem(fontString);
237 	BSize stringSize = _MeasureString(fontString->string);
238 	if (fMaxStringSize.width < stringSize.width)
239 		fMaxStringSize = stringSize;
240 }
241 
242 
243 void
244 BatteryInfoView::_ClearStringList()
245 {
246 	for (int i = 0; i < fStringList.CountItems(); i ++)
247 		delete fStringList.ItemAt(i);
248 	fStringList.MakeEmpty();
249 	fMaxStringSize = BSize(0, 0);
250 }
251 
252 
253 //	#pragma mark -
254 
255 
256 ExtPowerStatusView::ExtPowerStatusView(PowerStatusDriverInterface* interface,
257 		BRect frame, int32 resizingMode, int batteryID,
258 		ExtendedInfoWindow* window)
259 	:
260 	PowerStatusView(interface, frame, resizingMode, batteryID),
261 	fExtendedInfoWindow(window),
262 	fBatteryInfoView(window->GetExtendedBatteryInfoView()),
263 	fSelected(false)
264 {
265 }
266 
267 
268 void
269 ExtPowerStatusView::Draw(BRect updateRect)
270 {
271 	if (fSelected)
272 		SetLowColor(102, 152, 203);
273 	else
274 		SetLowColor(ui_color(B_PANEL_BACKGROUND_COLOR));
275 
276 	PowerStatusView::Draw(updateRect);
277 }
278 
279 
280 void
281 ExtPowerStatusView::MouseDown(BPoint where)
282 {
283 	if (!fSelected) {
284 		fSelected = true;
285 		Update(true);
286 		if (ExtendedInfoWindow* window
287 				= dynamic_cast<ExtendedInfoWindow*>(Window()))
288 			window->BatterySelected(this);
289 	}
290 }
291 
292 
293 void
294 ExtPowerStatusView::Select(bool select)
295 {
296 	fSelected = select;
297 	Update(true);
298 }
299 
300 
301 bool
302 ExtPowerStatusView::IsCritical()
303 {
304 	return (fBatteryInfo.state & BATTERY_CRITICAL_STATE) != 0;
305 }
306 
307 
308 void
309 ExtPowerStatusView::Update(bool force)
310 {
311 	PowerStatusView::Update(force);
312 	if (!fSelected)
313 		return;
314 
315 	acpi_extended_battery_info extInfo;
316 	fDriverInterface->GetExtendedBatteryInfo(&extInfo, fBatteryID);
317 
318 	fBatteryInfoView->Update(fBatteryInfo, extInfo);
319 	fBatteryInfoView->Invalidate();
320 }
321 
322 
323 //	#pragma mark -
324 
325 
326 ExtendedInfoWindow::ExtendedInfoWindow(PowerStatusDriverInterface* interface)
327 	:
328 	BWindow(BRect(100, 150, 500, 500), "Extended battery info", B_TITLED_WINDOW,
329 		B_NOT_RESIZABLE | B_NOT_ZOOMABLE | B_AVOID_FRONT |
330 		B_ASYNCHRONOUS_CONTROLS),
331 	fDriverInterface(interface),
332 	fSelectedView(NULL)
333 {
334 	fDriverInterface->AcquireReference();
335 
336 	BView *view = new BView(Bounds(), "view", B_FOLLOW_ALL, 0);
337 	view->SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR));
338 	AddChild(view);
339 
340 	BGroupLayout* mainLayout = new BGroupLayout(B_VERTICAL);
341 	mainLayout->SetSpacing(10);
342 	mainLayout->SetInsets(10, 10, 10, 10);
343 	view->SetLayout(mainLayout);
344 
345 	BRect rect = Bounds();
346 	rect.InsetBy(5, 5);
347 	BBox *infoBox = new BBox(rect, "Power status box");
348 	infoBox->SetLabel("Battery info");
349 	BGroupLayout* infoLayout = new BGroupLayout(B_HORIZONTAL);
350 	infoLayout->SetInsets(10, infoBox->TopBorderOffset() * 2 + 10, 10, 10);
351 	infoLayout->SetSpacing(10);
352 	infoBox->SetLayout(infoLayout);
353 	mainLayout->AddView(infoBox);
354 
355 	BGroupView* batteryView = new BGroupView(B_VERTICAL);
356 	batteryView->GroupLayout()->SetSpacing(10);
357 	infoLayout->AddView(batteryView);
358 
359 	// create before the battery views
360 	fBatteryInfoView = new BatteryInfoView();
361 
362 	BGroupLayout* batteryLayout = batteryView->GroupLayout();
363 	BRect batteryRect(0, 0, 50, 30);
364 	for (int i = 0; i < interface->GetBatteryCount(); i++) {
365 		ExtPowerStatusView* view = new ExtPowerStatusView(interface,
366 			batteryRect, B_FOLLOW_NONE, i, this);
367 		view->SetExplicitMaxSize(BSize(70, 80));
368 		view->SetExplicitMinSize(BSize(70, 80));
369 
370 		batteryLayout->AddView(view);
371 		fBatteryViewList.AddItem(view);
372 		fDriverInterface->StartWatching(view);
373 		if (!view->IsCritical())
374 			fSelectedView = view;
375 	}
376 
377 	batteryLayout->AddItem(BSpaceLayoutItem::CreateGlue());
378 
379 	infoLayout->AddView(fBatteryInfoView);
380 
381 	if (!fSelectedView && fBatteryViewList.CountItems() > 0)
382 		fSelectedView = fBatteryViewList.ItemAt(0);
383 	fSelectedView->Select();
384 
385 	BSize size = mainLayout->PreferredSize();
386 	ResizeTo(size.width, size.height);
387 }
388 
389 
390 ExtendedInfoWindow::~ExtendedInfoWindow()
391 {
392 	for (int i = 0; i < fBatteryViewList.CountItems(); i++)
393 		fDriverInterface->StopWatching(fBatteryViewList.ItemAt(i));
394 
395 	fDriverInterface->ReleaseReference();
396 }
397 
398 
399 BatteryInfoView*
400 ExtendedInfoWindow::GetExtendedBatteryInfoView()
401 {
402 	return fBatteryInfoView;
403 }
404 
405 
406 void
407 ExtendedInfoWindow::BatterySelected(ExtPowerStatusView* view)
408 {
409 	if (fSelectedView) {
410 		fSelectedView->Select(false);
411 		fSelectedView->Invalidate();
412 	}
413 
414 	fSelectedView = view;
415 }
416