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