xref: /haiku/src/apps/powerstatus/ExtendedInfoWindow.cpp (revision d1929affbb30225275baafc889310bf23e3b909c)
16aed176cSClemens Zeidler /*
2*d1929affSKacper Kasper  * Copyright 2009-2017, Haiku, Inc. All Rights Reserved.
36aed176cSClemens Zeidler  * Distributed under the terms of the MIT License.
46aed176cSClemens Zeidler  *
56aed176cSClemens Zeidler  * Authors:
66aed176cSClemens Zeidler  *		Clemens Zeidler, haiku@Clemens-Zeidler.de
7*d1929affSKacper Kasper  *		Kacper Kasper, kacperkasper@gmail.com
86aed176cSClemens Zeidler  */
96aed176cSClemens Zeidler 
10bd767f5aSAxel Dörfler 
116aed176cSClemens Zeidler #include "ExtendedInfoWindow.h"
126aed176cSClemens Zeidler 
136aed176cSClemens Zeidler #include <Box.h>
143bd54e05SAdrien Destugues #include <Catalog.h>
156aed176cSClemens Zeidler #include <GroupView.h>
166aed176cSClemens Zeidler #include <SpaceLayoutItem.h>
176aed176cSClemens Zeidler 
186aed176cSClemens Zeidler 
19546208a5SOliver Tappe #undef B_TRANSLATION_CONTEXT
20546208a5SOliver Tappe #define B_TRANSLATION_CONTEXT "PowerStatus"
213bd54e05SAdrien Destugues 
223bd54e05SAdrien Destugues 
23*d1929affSKacper Kasper const size_t kLinesCount = 16;
24e391ec67SClemens Zeidler 
25e391ec67SClemens Zeidler 
26bd767f5aSAxel Dörfler //	#pragma mark -
27bd767f5aSAxel Dörfler 
28e391ec67SClemens Zeidler 
29e391ec67SClemens Zeidler BatteryInfoView::BatteryInfoView()
306aed176cSClemens Zeidler 	:
31*d1929affSKacper Kasper 	BView("battery info view", B_AUTO_UPDATE_SIZE_LIMITS)
326aed176cSClemens Zeidler {
33fa19dd44Slooncraz 	SetViewUIColor(B_PANEL_BACKGROUND_COLOR);
34*d1929affSKacper Kasper 
35*d1929affSKacper Kasper 	SetLayout(new BGroupLayout(B_VERTICAL, B_USE_ITEM_SPACING));
36*d1929affSKacper Kasper 
37*d1929affSKacper Kasper 	for (size_t i = 0; i < kLinesCount; i++) {
38*d1929affSKacper Kasper 		BStringView* view = new BStringView("info", "");
39*d1929affSKacper Kasper 		AddChild(view);
40*d1929affSKacper Kasper 		fStringList.AddItem(view);
41*d1929affSKacper Kasper 	}
42*d1929affSKacper Kasper 	fStringList.ItemAt(0)->SetFont(be_bold_font);
43*d1929affSKacper Kasper 	AddChild(BSpaceLayoutItem::CreateGlue());
446aed176cSClemens Zeidler }
456aed176cSClemens Zeidler 
466aed176cSClemens Zeidler 
47e391ec67SClemens Zeidler BatteryInfoView::~BatteryInfoView()
48e391ec67SClemens Zeidler {
49*d1929affSKacper Kasper 	for (int32 i = 0; i < fStringList.CountItems(); i++)
50*d1929affSKacper Kasper 		delete fStringList.ItemAt(i);
51e391ec67SClemens Zeidler }
52e391ec67SClemens Zeidler 
53e391ec67SClemens Zeidler 
546aed176cSClemens Zeidler void
556aed176cSClemens Zeidler BatteryInfoView::Update(battery_info& info, acpi_extended_battery_info& extInfo)
566aed176cSClemens Zeidler {
576aed176cSClemens Zeidler 	fBatteryInfo = info;
586aed176cSClemens Zeidler 	fBatteryExtendedInfo = extInfo;
59e391ec67SClemens Zeidler 
60*d1929affSKacper Kasper 	for (size_t i = 0; i < kLinesCount; i++) {
61*d1929affSKacper Kasper 		fStringList.ItemAt(i)->SetText(_GetTextForLine(i));
626aed176cSClemens Zeidler 	}
63e391ec67SClemens Zeidler }
64e391ec67SClemens Zeidler 
65e391ec67SClemens Zeidler 
668b24b02fSClemens Zeidler void
678b24b02fSClemens Zeidler BatteryInfoView::AttachedToWindow()
688b24b02fSClemens Zeidler {
693e1f071cSClemens Zeidler 	Window()->CenterOnScreen();
708b24b02fSClemens Zeidler }
718b24b02fSClemens Zeidler 
728b24b02fSClemens Zeidler 
73*d1929affSKacper Kasper BString
74*d1929affSKacper Kasper BatteryInfoView::_GetTextForLine(size_t line)
75e391ec67SClemens Zeidler {
766aed176cSClemens Zeidler 	BString powerUnit;
776aed176cSClemens Zeidler 	BString rateUnit;
786aed176cSClemens Zeidler 	switch (fBatteryExtendedInfo.power_unit) {
796aed176cSClemens Zeidler 		case 0:
803bd54e05SAdrien Destugues 			powerUnit = B_TRANSLATE(" mWh");
813bd54e05SAdrien Destugues 			rateUnit = B_TRANSLATE(" mW");
826aed176cSClemens Zeidler 			break;
836aed176cSClemens Zeidler 
846aed176cSClemens Zeidler 		case 1:
853bd54e05SAdrien Destugues 			powerUnit = B_TRANSLATE(" mAh");
863bd54e05SAdrien Destugues 			rateUnit = B_TRANSLATE(" mA");
876aed176cSClemens Zeidler 			break;
886aed176cSClemens Zeidler 	}
896aed176cSClemens Zeidler 
90*d1929affSKacper Kasper 	BString string;
91*d1929affSKacper Kasper 	switch (line) {
92*d1929affSKacper Kasper 		case 0: {
93a11e2f43SAxel Dörfler 			if ((fBatteryInfo.state & BATTERY_CHARGING) != 0)
94*d1929affSKacper Kasper 				string = B_TRANSLATE("Battery charging");
95a11e2f43SAxel Dörfler 			else if ((fBatteryInfo.state & BATTERY_DISCHARGING) != 0)
96*d1929affSKacper Kasper 				string = B_TRANSLATE("Battery discharging");
97a11e2f43SAxel Dörfler 			else if ((fBatteryInfo.state & BATTERY_CRITICAL_STATE) != 0
98829200a0SAlexander von Gluck IV 				&& fBatteryExtendedInfo.model_number[0] == '\0'
99829200a0SAlexander von Gluck IV 				&& fBatteryExtendedInfo.serial_number[0] == '\0'
100829200a0SAlexander von Gluck IV 				&& fBatteryExtendedInfo.type[0] == '\0'
101829200a0SAlexander von Gluck IV 				&& fBatteryExtendedInfo.oem_info[0] == '\0')
102*d1929affSKacper Kasper 				string = B_TRANSLATE("Empty battery slot");
103a11e2f43SAxel Dörfler 			else if ((fBatteryInfo.state & BATTERY_CRITICAL_STATE) != 0)
104*d1929affSKacper Kasper 				string = B_TRANSLATE("Damaged battery");
1056aed176cSClemens Zeidler 			else
106*d1929affSKacper Kasper 				string = B_TRANSLATE("Battery unused");
107*d1929affSKacper Kasper 			break;
108*d1929affSKacper Kasper 		}
109*d1929affSKacper Kasper 		case 1:
110*d1929affSKacper Kasper 			string = B_TRANSLATE("Capacity: ");
111*d1929affSKacper Kasper 			string << fBatteryInfo.capacity;
112*d1929affSKacper Kasper 			string << powerUnit;
113*d1929affSKacper Kasper 			break;
114*d1929affSKacper Kasper 		case 2:
115*d1929affSKacper Kasper 			string = B_TRANSLATE("Last full charge: ");
116*d1929affSKacper Kasper 			string << fBatteryInfo.full_capacity;
117*d1929affSKacper Kasper 			string << powerUnit;
118*d1929affSKacper Kasper 			break;
119*d1929affSKacper Kasper 		case 3:
120*d1929affSKacper Kasper 			string = B_TRANSLATE("Current rate: ");
121*d1929affSKacper Kasper 			string << fBatteryInfo.current_rate;
122*d1929affSKacper Kasper 			string << rateUnit;
123*d1929affSKacper Kasper 			break;
124*d1929affSKacper Kasper 		// case 4 missed intentionally
125*d1929affSKacper Kasper 		case 5:
126*d1929affSKacper Kasper 			string = B_TRANSLATE("Design capacity: ");
127*d1929affSKacper Kasper 			string << fBatteryExtendedInfo.design_capacity;
128*d1929affSKacper Kasper 			string << powerUnit;
129*d1929affSKacper Kasper 			break;
130*d1929affSKacper Kasper 		case 6:
131*d1929affSKacper Kasper 			string = B_TRANSLATE("Technology: ");
132b636a0ecSClemens Zeidler 			if (fBatteryExtendedInfo.technology == 0)
133*d1929affSKacper Kasper 				string << B_TRANSLATE("non-rechargeable");
134b636a0ecSClemens Zeidler 			else if (fBatteryExtendedInfo.technology == 1)
135*d1929affSKacper Kasper 				string << B_TRANSLATE("rechargeable");
136b636a0ecSClemens Zeidler 			else
137*d1929affSKacper Kasper 				string << "?";
138*d1929affSKacper Kasper 			break;
139*d1929affSKacper Kasper 		case 7:
140*d1929affSKacper Kasper 			string = B_TRANSLATE("Design voltage: ");
141*d1929affSKacper Kasper 			string << fBatteryExtendedInfo.design_voltage;
142*d1929affSKacper Kasper 			string << B_TRANSLATE(" mV");
143*d1929affSKacper Kasper 			break;
144*d1929affSKacper Kasper 		case 8:
145*d1929affSKacper Kasper 			string = B_TRANSLATE("Design capacity warning: ");
146*d1929affSKacper Kasper 			string << fBatteryExtendedInfo.design_capacity_warning;
147*d1929affSKacper Kasper 			string << powerUnit;
148*d1929affSKacper Kasper 			break;
149*d1929affSKacper Kasper 		case 9:
150*d1929affSKacper Kasper 			string = B_TRANSLATE("Design capacity low warning: ");
151*d1929affSKacper Kasper 			string << fBatteryExtendedInfo.design_capacity_low;
152*d1929affSKacper Kasper 			string << powerUnit;
153*d1929affSKacper Kasper 			break;
154*d1929affSKacper Kasper 		case 10:
155*d1929affSKacper Kasper 			string = B_TRANSLATE("Capacity granularity 1: ");
156*d1929affSKacper Kasper 			string << fBatteryExtendedInfo.capacity_granularity_1;
157*d1929affSKacper Kasper 			string << powerUnit;
158*d1929affSKacper Kasper 			break;
159*d1929affSKacper Kasper 		case 11:
160*d1929affSKacper Kasper 			string = B_TRANSLATE("Capacity granularity 2: ");
161*d1929affSKacper Kasper 			string << fBatteryExtendedInfo.capacity_granularity_2;
162*d1929affSKacper Kasper 			string << powerUnit;
163*d1929affSKacper Kasper 			break;
164*d1929affSKacper Kasper 		case 12:
165*d1929affSKacper Kasper 			string = B_TRANSLATE("Model number: ");
166*d1929affSKacper Kasper 			string << fBatteryExtendedInfo.model_number;
167*d1929affSKacper Kasper 			break;
168*d1929affSKacper Kasper 		case 13:
169*d1929affSKacper Kasper 			string = B_TRANSLATE("Serial number: ");
170*d1929affSKacper Kasper 			string << fBatteryExtendedInfo.serial_number;
171*d1929affSKacper Kasper 			break;
172*d1929affSKacper Kasper 		case 14:
173*d1929affSKacper Kasper 			string = B_TRANSLATE("Type: ");
174*d1929affSKacper Kasper 			string += fBatteryExtendedInfo.type;
175*d1929affSKacper Kasper 			break;
176*d1929affSKacper Kasper 		case 15:
177*d1929affSKacper Kasper 			string = B_TRANSLATE("OEM info: ");
178*d1929affSKacper Kasper 			string += fBatteryExtendedInfo.oem_info;
179*d1929affSKacper Kasper 			break;
180*d1929affSKacper Kasper 		default:
181*d1929affSKacper Kasper 			string = "";
182*d1929affSKacper Kasper 			break;
183e391ec67SClemens Zeidler 	}
184*d1929affSKacper Kasper 	return string;
1856aed176cSClemens Zeidler }
1866aed176cSClemens Zeidler 
1876aed176cSClemens Zeidler 
188bd767f5aSAxel Dörfler //	#pragma mark -
189bd767f5aSAxel Dörfler 
190bd767f5aSAxel Dörfler 
1916aed176cSClemens Zeidler ExtPowerStatusView::ExtPowerStatusView(PowerStatusDriverInterface* interface,
192bd767f5aSAxel Dörfler 		BRect frame, int32 resizingMode, int batteryID,
1936aed176cSClemens Zeidler 		ExtendedInfoWindow* window)
1946aed176cSClemens Zeidler 	:
195bd767f5aSAxel Dörfler 	PowerStatusView(interface, frame, resizingMode, batteryID),
1966aed176cSClemens Zeidler 	fExtendedInfoWindow(window),
1976aed176cSClemens Zeidler 	fBatteryInfoView(window->GetExtendedBatteryInfoView()),
1986aed176cSClemens Zeidler 	fSelected(false)
1996aed176cSClemens Zeidler {
2006aed176cSClemens Zeidler }
2016aed176cSClemens Zeidler 
2026aed176cSClemens Zeidler 
2036aed176cSClemens Zeidler void
2046aed176cSClemens Zeidler ExtPowerStatusView::Draw(BRect updateRect)
2056aed176cSClemens Zeidler {
20624c9b9dfSJanus 	if (fSelected) {
20724c9b9dfSJanus 		rgb_color lowColor = LowColor();
2086aed176cSClemens Zeidler 		SetLowColor(102, 152, 203);
20924c9b9dfSJanus 		FillRect(updateRect, B_SOLID_LOW);
21024c9b9dfSJanus 		SetLowColor(lowColor);
21124c9b9dfSJanus 	}
2126aed176cSClemens Zeidler 	PowerStatusView::Draw(updateRect);
2136aed176cSClemens Zeidler }
2146aed176cSClemens Zeidler 
2156aed176cSClemens Zeidler 
2166aed176cSClemens Zeidler void
2176aed176cSClemens Zeidler ExtPowerStatusView::MouseDown(BPoint where)
2186aed176cSClemens Zeidler {
2196aed176cSClemens Zeidler 	if (!fSelected) {
2206aed176cSClemens Zeidler 		fSelected = true;
221bd767f5aSAxel Dörfler 		Update(true);
222bd767f5aSAxel Dörfler 		if (ExtendedInfoWindow* window
223bd767f5aSAxel Dörfler 				= dynamic_cast<ExtendedInfoWindow*>(Window()))
224bd767f5aSAxel Dörfler 			window->BatterySelected(this);
2256aed176cSClemens Zeidler 	}
2266aed176cSClemens Zeidler }
2276aed176cSClemens Zeidler 
2286aed176cSClemens Zeidler 
2296aed176cSClemens Zeidler void
2306aed176cSClemens Zeidler ExtPowerStatusView::Select(bool select)
2316aed176cSClemens Zeidler {
2326aed176cSClemens Zeidler 	fSelected = select;
233bd767f5aSAxel Dörfler 	Update(true);
2346aed176cSClemens Zeidler }
2356aed176cSClemens Zeidler 
2366aed176cSClemens Zeidler 
2376aed176cSClemens Zeidler bool
238bd767f5aSAxel Dörfler ExtPowerStatusView::IsCritical()
2396aed176cSClemens Zeidler {
240bd767f5aSAxel Dörfler 	return (fBatteryInfo.state & BATTERY_CRITICAL_STATE) != 0;
2416aed176cSClemens Zeidler }
2426aed176cSClemens Zeidler 
2436aed176cSClemens Zeidler 
2446aed176cSClemens Zeidler void
245bd767f5aSAxel Dörfler ExtPowerStatusView::Update(bool force)
2466aed176cSClemens Zeidler {
247bd767f5aSAxel Dörfler 	PowerStatusView::Update(force);
2486aed176cSClemens Zeidler 	if (!fSelected)
2496aed176cSClemens Zeidler 		return;
2506aed176cSClemens Zeidler 
2516aed176cSClemens Zeidler 	acpi_extended_battery_info extInfo;
252b19e9d5bSAxel Dörfler 	fDriverInterface->GetExtendedBatteryInfo(fBatteryID, &extInfo);
2536aed176cSClemens Zeidler 
2546aed176cSClemens Zeidler 	fBatteryInfoView->Update(fBatteryInfo, extInfo);
2556aed176cSClemens Zeidler 	fBatteryInfoView->Invalidate();
2566aed176cSClemens Zeidler }
2576aed176cSClemens Zeidler 
2586aed176cSClemens Zeidler 
259bd767f5aSAxel Dörfler //	#pragma mark -
260bd767f5aSAxel Dörfler 
261bd767f5aSAxel Dörfler 
2626aed176cSClemens Zeidler ExtendedInfoWindow::ExtendedInfoWindow(PowerStatusDriverInterface* interface)
2636aed176cSClemens Zeidler 	:
2643bd54e05SAdrien Destugues 	BWindow(BRect(100, 150, 500, 500), B_TRANSLATE("Extended battery info"),
2653bd54e05SAdrien Destugues 		B_TITLED_WINDOW,
266b19e9d5bSAxel Dörfler 		B_NOT_RESIZABLE | B_NOT_ZOOMABLE | B_AVOID_FRONT
267b19e9d5bSAxel Dörfler 			| B_ASYNCHRONOUS_CONTROLS),
2686aed176cSClemens Zeidler 	fDriverInterface(interface),
2696aed176cSClemens Zeidler 	fSelectedView(NULL)
2706aed176cSClemens Zeidler {
27108145692SClemens Zeidler 	fDriverInterface->AcquireReference();
27208145692SClemens Zeidler 
2736aed176cSClemens Zeidler 	BView *view = new BView(Bounds(), "view", B_FOLLOW_ALL, 0);
274fa19dd44Slooncraz 	view->SetViewUIColor(B_PANEL_BACKGROUND_COLOR);
2756aed176cSClemens Zeidler 	AddChild(view);
2766aed176cSClemens Zeidler 
2776aed176cSClemens Zeidler 	BGroupLayout* mainLayout = new BGroupLayout(B_VERTICAL);
2786aed176cSClemens Zeidler 	mainLayout->SetSpacing(10);
2796aed176cSClemens Zeidler 	mainLayout->SetInsets(10, 10, 10, 10);
2806aed176cSClemens Zeidler 	view->SetLayout(mainLayout);
2816aed176cSClemens Zeidler 
2826aed176cSClemens Zeidler 	BRect rect = Bounds();
2836aed176cSClemens Zeidler 	rect.InsetBy(5, 5);
2843bd54e05SAdrien Destugues 	BBox *infoBox = new BBox(rect, B_TRANSLATE("Power status box"));
2853bd54e05SAdrien Destugues 	infoBox->SetLabel(B_TRANSLATE("Battery info"));
2866aed176cSClemens Zeidler 	BGroupLayout* infoLayout = new BGroupLayout(B_HORIZONTAL);
2876aed176cSClemens Zeidler 	infoLayout->SetInsets(10, infoBox->TopBorderOffset() * 2 + 10, 10, 10);
2886aed176cSClemens Zeidler 	infoLayout->SetSpacing(10);
2896aed176cSClemens Zeidler 	infoBox->SetLayout(infoLayout);
2906aed176cSClemens Zeidler 	mainLayout->AddView(infoBox);
2916aed176cSClemens Zeidler 
2926aed176cSClemens Zeidler 	BGroupView* batteryView = new BGroupView(B_VERTICAL);
2936aed176cSClemens Zeidler 	batteryView->GroupLayout()->SetSpacing(10);
2946aed176cSClemens Zeidler 	infoLayout->AddView(batteryView);
2956aed176cSClemens Zeidler 
296e391ec67SClemens Zeidler 	// create before the battery views
297e391ec67SClemens Zeidler 	fBatteryInfoView = new BatteryInfoView();
2986aed176cSClemens Zeidler 
2996aed176cSClemens Zeidler 	BGroupLayout* batteryLayout = batteryView->GroupLayout();
3006aed176cSClemens Zeidler 	BRect batteryRect(0, 0, 50, 30);
3016aed176cSClemens Zeidler 	for (int i = 0; i < interface->GetBatteryCount(); i++) {
3026aed176cSClemens Zeidler 		ExtPowerStatusView* view = new ExtPowerStatusView(interface,
303e391ec67SClemens Zeidler 			batteryRect, B_FOLLOW_NONE, i, this);
304e391ec67SClemens Zeidler 		view->SetExplicitMaxSize(BSize(70, 80));
305e391ec67SClemens Zeidler 		view->SetExplicitMinSize(BSize(70, 80));
306e391ec67SClemens Zeidler 
3076aed176cSClemens Zeidler 		batteryLayout->AddView(view);
3086aed176cSClemens Zeidler 		fBatteryViewList.AddItem(view);
3096aed176cSClemens Zeidler 		fDriverInterface->StartWatching(view);
310bd767f5aSAxel Dörfler 		if (!view->IsCritical())
3116aed176cSClemens Zeidler 			fSelectedView = view;
3126aed176cSClemens Zeidler 	}
3136aed176cSClemens Zeidler 
3146aed176cSClemens Zeidler 	batteryLayout->AddItem(BSpaceLayoutItem::CreateGlue());
3156aed176cSClemens Zeidler 
316e391ec67SClemens Zeidler 	infoLayout->AddView(fBatteryInfoView);
3176aed176cSClemens Zeidler 
3186aed176cSClemens Zeidler 	if (!fSelectedView && fBatteryViewList.CountItems() > 0)
3196aed176cSClemens Zeidler 		fSelectedView = fBatteryViewList.ItemAt(0);
3206aed176cSClemens Zeidler 	fSelectedView->Select();
3216aed176cSClemens Zeidler 
3226aed176cSClemens Zeidler 	BSize size = mainLayout->PreferredSize();
3236aed176cSClemens Zeidler 	ResizeTo(size.width, size.height);
3246aed176cSClemens Zeidler }
3256aed176cSClemens Zeidler 
3266aed176cSClemens Zeidler 
3276aed176cSClemens Zeidler ExtendedInfoWindow::~ExtendedInfoWindow()
3286aed176cSClemens Zeidler {
32908145692SClemens Zeidler 	for (int i = 0; i < fBatteryViewList.CountItems(); i++)
3306aed176cSClemens Zeidler 		fDriverInterface->StopWatching(fBatteryViewList.ItemAt(i));
33108145692SClemens Zeidler 
33208145692SClemens Zeidler 	fDriverInterface->ReleaseReference();
3336aed176cSClemens Zeidler }
3346aed176cSClemens Zeidler 
3356aed176cSClemens Zeidler 
3366aed176cSClemens Zeidler BatteryInfoView*
3376aed176cSClemens Zeidler ExtendedInfoWindow::GetExtendedBatteryInfoView()
3386aed176cSClemens Zeidler {
3396aed176cSClemens Zeidler 	return fBatteryInfoView;
3406aed176cSClemens Zeidler }
3416aed176cSClemens Zeidler 
3426aed176cSClemens Zeidler 
3436aed176cSClemens Zeidler void
3446aed176cSClemens Zeidler ExtendedInfoWindow::BatterySelected(ExtPowerStatusView* view)
3456aed176cSClemens Zeidler {
3466aed176cSClemens Zeidler 	if (fSelectedView) {
3476aed176cSClemens Zeidler 		fSelectedView->Select(false);
3486aed176cSClemens Zeidler 		fSelectedView->Invalidate();
3496aed176cSClemens Zeidler 	}
3506aed176cSClemens Zeidler 
3516aed176cSClemens Zeidler 	fSelectedView = view;
3526aed176cSClemens Zeidler }
353