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