HaikuDepot: notify work status from main window
[haiku.git] / src / apps / powerstatus / ExtendedInfoWindow.cpp
blob469a15d9188e0efe8dce06a9aa586937242426a4
1 /*
2 * Copyright 2009-2017, Haiku, Inc. All Rights Reserved.
3 * Distributed under the terms of the MIT License.
5 * Authors:
6 * Clemens Zeidler, haiku@Clemens-Zeidler.de
7 * Kacper Kasper, kacperkasper@gmail.com
8 */
11 #include "ExtendedInfoWindow.h"
13 #include <ControlLook.h>
14 #include <Catalog.h>
15 #include <GroupView.h>
16 #include <LayoutBuilder.h>
17 #include <SpaceLayoutItem.h>
18 #include <TabView.h>
21 #include <algorithm>
24 #undef B_TRANSLATION_CONTEXT
25 #define B_TRANSLATION_CONTEXT "PowerStatus"
28 const size_t kLinesCount = 16;
31 // #pragma mark -
34 BatteryInfoView::BatteryInfoView()
36 BView("battery info view", B_AUTO_UPDATE_SIZE_LIMITS)
38 SetViewUIColor(B_PANEL_BACKGROUND_COLOR);
40 BGroupLayout* layout = new BGroupLayout(B_VERTICAL, 0);
41 layout->SetInsets(B_USE_DEFAULT_SPACING, B_USE_DEFAULT_SPACING,
42 0, B_USE_DEFAULT_SPACING);
43 SetLayout(layout);
45 for (size_t i = 0; i < kLinesCount; i++) {
46 BStringView* view = new BStringView("info", "");
47 AddChild(view);
48 fStringList.AddItem(view);
50 fStringList.ItemAt(0)->SetFont(be_bold_font);
51 AddChild(BSpaceLayoutItem::CreateGlue());
55 BatteryInfoView::~BatteryInfoView()
57 for (int32 i = 0; i < fStringList.CountItems(); i++)
58 delete fStringList.ItemAt(i);
62 void
63 BatteryInfoView::Update(battery_info& info, acpi_extended_battery_info& extInfo)
65 fBatteryInfo = info;
66 fBatteryExtendedInfo = extInfo;
68 for (size_t i = 0; i < kLinesCount; i++) {
69 fStringList.ItemAt(i)->SetText(_GetTextForLine(i));
74 void
75 BatteryInfoView::AttachedToWindow()
77 Window()->CenterOnScreen();
81 BString
82 BatteryInfoView::_GetTextForLine(size_t line)
84 BString powerUnit;
85 BString rateUnit;
86 switch (fBatteryExtendedInfo.power_unit) {
87 case 0:
88 powerUnit = B_TRANSLATE(" mWh");
89 rateUnit = B_TRANSLATE(" mW");
90 break;
92 case 1:
93 powerUnit = B_TRANSLATE(" mAh");
94 rateUnit = B_TRANSLATE(" mA");
95 break;
98 BString string;
99 switch (line) {
100 case 0: {
101 if ((fBatteryInfo.state & BATTERY_CHARGING) != 0)
102 string = B_TRANSLATE("Battery charging");
103 else if ((fBatteryInfo.state & BATTERY_DISCHARGING) != 0)
104 string = B_TRANSLATE("Battery discharging");
105 else if ((fBatteryInfo.state & BATTERY_CRITICAL_STATE) != 0
106 && fBatteryExtendedInfo.model_number[0] == '\0'
107 && fBatteryExtendedInfo.serial_number[0] == '\0'
108 && fBatteryExtendedInfo.type[0] == '\0'
109 && fBatteryExtendedInfo.oem_info[0] == '\0')
110 string = B_TRANSLATE("Empty battery slot");
111 else if ((fBatteryInfo.state & BATTERY_CRITICAL_STATE) != 0)
112 string = B_TRANSLATE("Damaged battery");
113 else
114 string = B_TRANSLATE("Battery unused");
115 break;
117 case 1:
118 string = B_TRANSLATE("Capacity: ");
119 string << fBatteryInfo.capacity;
120 string << powerUnit;
121 break;
122 case 2:
123 string = B_TRANSLATE("Last full charge: ");
124 string << fBatteryInfo.full_capacity;
125 string << powerUnit;
126 break;
127 case 3:
128 string = B_TRANSLATE("Current rate: ");
129 string << fBatteryInfo.current_rate;
130 string << rateUnit;
131 break;
132 // case 4 missed intentionally
133 case 5:
134 string = B_TRANSLATE("Design capacity: ");
135 string << fBatteryExtendedInfo.design_capacity;
136 string << powerUnit;
137 break;
138 case 6:
139 string = B_TRANSLATE("Technology: ");
140 if (fBatteryExtendedInfo.technology == 0)
141 string << B_TRANSLATE("non-rechargeable");
142 else if (fBatteryExtendedInfo.technology == 1)
143 string << B_TRANSLATE("rechargeable");
144 else
145 string << "?";
146 break;
147 case 7:
148 string = B_TRANSLATE("Design voltage: ");
149 string << fBatteryExtendedInfo.design_voltage;
150 string << B_TRANSLATE(" mV");
151 break;
152 case 8:
153 string = B_TRANSLATE("Design capacity warning: ");
154 string << fBatteryExtendedInfo.design_capacity_warning;
155 string << powerUnit;
156 break;
157 case 9:
158 string = B_TRANSLATE("Design capacity low warning: ");
159 string << fBatteryExtendedInfo.design_capacity_low;
160 string << powerUnit;
161 break;
162 case 10:
163 string = B_TRANSLATE("Capacity granularity 1: ");
164 string << fBatteryExtendedInfo.capacity_granularity_1;
165 string << powerUnit;
166 break;
167 case 11:
168 string = B_TRANSLATE("Capacity granularity 2: ");
169 string << fBatteryExtendedInfo.capacity_granularity_2;
170 string << powerUnit;
171 break;
172 case 12:
173 string = B_TRANSLATE("Model number: ");
174 string << fBatteryExtendedInfo.model_number;
175 break;
176 case 13:
177 string = B_TRANSLATE("Serial number: ");
178 string << fBatteryExtendedInfo.serial_number;
179 break;
180 case 14:
181 string = B_TRANSLATE("Type: ");
182 string += fBatteryExtendedInfo.type;
183 break;
184 case 15:
185 string = B_TRANSLATE("OEM info: ");
186 string += fBatteryExtendedInfo.oem_info;
187 break;
188 default:
189 string = "";
190 break;
192 return string;
196 // #pragma mark -
199 BatteryTab::BatteryTab(BatteryInfoView* target,
200 ExtPowerStatusView* view)
202 fBatteryView(view)
207 BatteryTab::~BatteryTab()
212 void
213 BatteryTab::Select(BView* owner)
215 BTab::Select(owner);
216 fBatteryView->Select();
219 void
220 BatteryTab::DrawFocusMark(BView* owner, BRect frame)
222 float vertOffset = IsSelected() ? 3 : 2;
223 float horzOffset = IsSelected() ? 2 : 4;
224 float width = frame.Width() - horzOffset * 2;
225 BPoint pt1((frame.left + frame.right - width) / 2.0 + horzOffset,
226 frame.bottom - vertOffset);
227 BPoint pt2((frame.left + frame.right + width) / 2.0,
228 frame.bottom - vertOffset);
229 owner->SetHighUIColor(B_KEYBOARD_NAVIGATION_COLOR);
230 owner->StrokeLine(pt1, pt2);
234 void
235 BatteryTab::DrawLabel(BView* owner, BRect frame)
237 BRect rect = frame;
238 float size = std::min(rect.Width(), rect.Height());
239 rect.right = rect.left + size;
240 rect.bottom = rect.top + size;
241 if (frame.Width() > rect.Height()) {
242 rect.OffsetBy((frame.Width() - size) / 2.0f, 0.0f);
243 } else {
244 rect.OffsetBy(0.0f, (frame.Height() - size) / 2.0f);
246 fBatteryView->DrawTo(owner, rect);
250 BatteryTabView::BatteryTabView(const char* name)
252 BTabView(name)
257 BatteryTabView::~BatteryTabView()
262 BRect
263 BatteryTabView::TabFrame(int32 index) const
265 BRect bounds(Bounds());
266 float width = TabHeight();
267 float height = TabHeight();
268 float offset = BControlLook::ComposeSpacing(B_USE_WINDOW_SPACING);
269 switch (TabSide()) {
270 case kTopSide:
271 return BRect(offset + index * width, 0.0f,
272 offset + index * width + width, height);
273 case kBottomSide:
274 return BRect(offset + index * width, bounds.bottom - height,
275 offset + index * width + width, bounds.bottom);
276 case kLeftSide:
277 return BRect(0.0f, offset + index * width, height,
278 offset + index * width + width);
279 case kRightSide:
280 return BRect(bounds.right - height, offset + index * width,
281 bounds.right, offset + index * width + width);
282 default:
283 return BRect();
288 ExtPowerStatusView::ExtPowerStatusView(PowerStatusDriverInterface* interface,
289 BRect frame, int32 resizingMode, int batteryID,
290 BatteryInfoView* batteryInfoView, ExtendedInfoWindow* window)
292 PowerStatusView(interface, frame, resizingMode, batteryID),
293 fExtendedInfoWindow(window),
294 fBatteryInfoView(batteryInfoView),
295 fBatteryTabView(window->GetBatteryTabView())
300 void
301 ExtPowerStatusView::Select(bool select)
303 fSelected = select;
304 Update(true);
308 bool
309 ExtPowerStatusView::IsCritical()
311 return (fBatteryInfo.state & BATTERY_CRITICAL_STATE) != 0;
315 void
316 ExtPowerStatusView::Update(bool force)
318 PowerStatusView::Update(force);
319 if (!fSelected)
320 return;
322 acpi_extended_battery_info extInfo;
323 fDriverInterface->GetExtendedBatteryInfo(fBatteryID, &extInfo);
325 fBatteryInfoView->Update(fBatteryInfo, extInfo);
326 fBatteryInfoView->Invalidate();
328 fBatteryTabView->Invalidate();
332 // #pragma mark -
335 ExtendedInfoWindow::ExtendedInfoWindow(PowerStatusDriverInterface* interface)
337 BWindow(BRect(100, 150, 500, 500), B_TRANSLATE("Extended battery info"),
338 B_TITLED_WINDOW,
339 B_NOT_RESIZABLE | B_NOT_ZOOMABLE | B_AVOID_FRONT
340 | B_ASYNCHRONOUS_CONTROLS),
341 fDriverInterface(interface),
342 fSelectedView(NULL)
344 fDriverInterface->AcquireReference();
346 float scale = be_plain_font->Size() / 12.0f;
347 float tabHeight = 70.0f * scale;
348 BRect batteryRect(0, 0, 50 * scale, 50 * scale);
349 fBatteryTabView = new BatteryTabView("tabview");
350 fBatteryTabView->SetBorder(B_NO_BORDER);
351 fBatteryTabView->SetTabHeight(tabHeight);
352 fBatteryTabView->SetTabSide(BTabView::kLeftSide);
353 BLayoutBuilder::Group<>(this, B_VERTICAL, 0)
354 .SetInsets(B_USE_DEFAULT_SPACING, 0, B_USE_DEFAULT_SPACING, 0)
355 .Add(fBatteryTabView);
357 for (int i = 0; i < interface->GetBatteryCount(); i++) {
358 BatteryInfoView* batteryInfoView = new BatteryInfoView();
359 ExtPowerStatusView* view = new ExtPowerStatusView(interface,
360 batteryRect, B_FOLLOW_NONE, i, batteryInfoView, this);
361 BatteryTab* tab = new BatteryTab(batteryInfoView, view);
362 fBatteryTabView->AddTab(batteryInfoView, tab);
363 // Has to be added, otherwise it won't get info updates
364 view->Hide();
365 AddChild(view);
367 fBatteryViewList.AddItem(view);
368 fDriverInterface->StartWatching(view);
369 if (!view->IsCritical())
370 fSelectedView = view;
373 if (!fSelectedView && fBatteryViewList.CountItems() > 0)
374 fSelectedView = fBatteryViewList.ItemAt(0);
375 fSelectedView->Select();
377 BSize size = GetLayout()->PreferredSize();
378 ResizeTo(size.width, size.height);
382 ExtendedInfoWindow::~ExtendedInfoWindow()
384 for (int i = 0; i < fBatteryViewList.CountItems(); i++)
385 fDriverInterface->StopWatching(fBatteryViewList.ItemAt(i));
387 fDriverInterface->ReleaseReference();
391 BatteryTabView*
392 ExtendedInfoWindow::GetBatteryTabView()
394 return fBatteryTabView;