Wrote a small application to show the power status in a window, replicant, or the
Deskbar tray. Currently only works under BeOS, and has rather ugly graphics; Haiku doesn't have an APM kernel interface yet, and I was too lazy to make any nice icons/drawings :) git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@19145 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -19,6 +19,7 @@ SubInclude HAIKU_TOP src apps mediaplayer ;
|
|||||||
SubInclude HAIKU_TOP src apps midiplayer ;
|
SubInclude HAIKU_TOP src apps midiplayer ;
|
||||||
SubInclude HAIKU_TOP src apps people ;
|
SubInclude HAIKU_TOP src apps people ;
|
||||||
SubInclude HAIKU_TOP src apps poorman ;
|
SubInclude HAIKU_TOP src apps poorman ;
|
||||||
|
SubInclude HAIKU_TOP src apps powerstatus ;
|
||||||
SubInclude HAIKU_TOP src apps processcontroller ;
|
SubInclude HAIKU_TOP src apps processcontroller ;
|
||||||
SubInclude HAIKU_TOP src apps pulse ;
|
SubInclude HAIKU_TOP src apps pulse ;
|
||||||
SubInclude HAIKU_TOP src apps showimage ;
|
SubInclude HAIKU_TOP src apps showimage ;
|
||||||
|
|||||||
@@ -0,0 +1,13 @@
|
|||||||
|
SubDir HAIKU_TOP src apps powerstatus ;
|
||||||
|
|
||||||
|
SetSubDirSupportedPlatformsBeOSCompatible ;
|
||||||
|
|
||||||
|
UsePrivateHeaders shared ;
|
||||||
|
|
||||||
|
Application PowerStatus :
|
||||||
|
PowerStatusWindow.cpp
|
||||||
|
PowerStatusView.cpp
|
||||||
|
PowerStatus.cpp
|
||||||
|
: be
|
||||||
|
: PowerStatus.rdef
|
||||||
|
;
|
||||||
@@ -0,0 +1,135 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2006, Haiku, Inc. All Rights Reserved.
|
||||||
|
* Distributed under the terms of the MIT License.
|
||||||
|
*
|
||||||
|
* Authors:
|
||||||
|
* Axel Dörfler, [email protected]
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#include "PowerStatus.h"
|
||||||
|
#include "PowerStatusWindow.h"
|
||||||
|
|
||||||
|
#include <Alert.h>
|
||||||
|
#include <Application.h>
|
||||||
|
#include <Deskbar.h>
|
||||||
|
#include <Entry.h>
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
|
||||||
|
class PowerStatus : public BApplication {
|
||||||
|
public:
|
||||||
|
PowerStatus();
|
||||||
|
virtual ~PowerStatus();
|
||||||
|
|
||||||
|
virtual void ReadyToRun();
|
||||||
|
virtual void AboutRequested();
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
const char* kSignature = "application/x-vnd.Haiku-PowerStatus";
|
||||||
|
const char* kDeskbarSignature = "application/x-vnd.Be-TSKB";
|
||||||
|
const char* kDeskbarItemName = "PowerStatus";
|
||||||
|
|
||||||
|
|
||||||
|
status_t
|
||||||
|
our_image(image_info& image)
|
||||||
|
{
|
||||||
|
int32 cookie = 0;
|
||||||
|
while (get_next_image_info(B_CURRENT_TEAM, &cookie, &image) == B_OK) {
|
||||||
|
if ((char *)our_image >= (char *)image.text
|
||||||
|
&& (char *)our_image <= (char *)image.text + image.text_size)
|
||||||
|
return B_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
return B_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// #pragma mark -
|
||||||
|
|
||||||
|
|
||||||
|
PowerStatus::PowerStatus()
|
||||||
|
: BApplication(kSignature)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
PowerStatus::~PowerStatus()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
PowerStatus::ReadyToRun()
|
||||||
|
{
|
||||||
|
bool isInstalled = false;
|
||||||
|
bool isDeskbarRunning = true;
|
||||||
|
|
||||||
|
{
|
||||||
|
// if the Deskbar is not alive at this point, it might be after having
|
||||||
|
// acknowledged the requester below
|
||||||
|
BDeskbar deskbar;
|
||||||
|
#ifdef HAIKU_TARGET_PLATFORM_HAIKU
|
||||||
|
isDeskbarRunning = deskbar.IsRunning())
|
||||||
|
#endif
|
||||||
|
isInstalled = deskbar.HasItem(kDeskbarItemName);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isDeskbarRunning && !isInstalled) {
|
||||||
|
BAlert* alert = new BAlert("", "Do you want PowerStatus to live in the Deskbar?",
|
||||||
|
"Don't", "Install", NULL, B_WIDTH_AS_USUAL, B_WARNING_ALERT);
|
||||||
|
alert->SetShortcut(0, B_ESCAPE);
|
||||||
|
|
||||||
|
if (alert->Go()) {
|
||||||
|
image_info info;
|
||||||
|
entry_ref ref;
|
||||||
|
|
||||||
|
if (our_image(info) == B_OK
|
||||||
|
&& get_ref_for_path(info.name, &ref) == B_OK) {
|
||||||
|
BDeskbar deskbar;
|
||||||
|
deskbar.AddItem(&ref);
|
||||||
|
}
|
||||||
|
|
||||||
|
Quit();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
BWindow* window = new PowerStatusWindow();
|
||||||
|
window->Show();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
PowerStatus::AboutRequested()
|
||||||
|
{
|
||||||
|
BWindow* window = WindowAt(0);
|
||||||
|
if (window == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
|
BView* view = window->FindView(kDeskbarItemName);
|
||||||
|
if (view == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
|
BMessenger target((BHandler*)view);
|
||||||
|
BMessage about(B_ABOUT_REQUESTED);
|
||||||
|
target.SendMessage(&about);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// #pragma mark -
|
||||||
|
|
||||||
|
|
||||||
|
int
|
||||||
|
main(int, char**)
|
||||||
|
{
|
||||||
|
PowerStatus app;
|
||||||
|
app.Run();
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2006, Haiku, Inc. All Rights Reserved.
|
||||||
|
* Distributed under the terms of the MIT License.
|
||||||
|
*
|
||||||
|
* Authors:
|
||||||
|
* Axel Dörfler, [email protected]
|
||||||
|
*/
|
||||||
|
#ifndef POWER_STATUS_H
|
||||||
|
#define POWER_STATUS_H
|
||||||
|
|
||||||
|
|
||||||
|
extern const char* kSignature;
|
||||||
|
extern const char* kDeskbarItemName;
|
||||||
|
|
||||||
|
#endif // POWER_STATUS_H
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
|
||||||
|
resource(1, "BEOS:APP_SIG") #'MIMS' "application/x-vnd.Haiku-PowerStatus";
|
||||||
|
|
||||||
|
resource app_flags B_SINGLE_LAUNCH;
|
||||||
|
|
||||||
|
resource app_version {
|
||||||
|
major = 1,
|
||||||
|
middle = 0,
|
||||||
|
minor = 0,
|
||||||
|
|
||||||
|
variety = B_APPV_DEVELOPMENT,
|
||||||
|
internal = 0,
|
||||||
|
|
||||||
|
short_info = "PowerStatus",
|
||||||
|
long_info = "PowerStatus ©2006 Haiku"
|
||||||
|
};
|
||||||
|
|
||||||
@@ -0,0 +1,475 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2006, Haiku, Inc. All Rights Reserved.
|
||||||
|
* Distributed under the terms of the MIT License.
|
||||||
|
*
|
||||||
|
* Authors:
|
||||||
|
* Axel Dörfler, [email protected]
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#include "PowerStatusView.h"
|
||||||
|
#include "PowerStatus.h"
|
||||||
|
|
||||||
|
#include <Alert.h>
|
||||||
|
#include <Application.h>
|
||||||
|
#include <Deskbar.h>
|
||||||
|
#include <Dragger.h>
|
||||||
|
#include <Drivers.h>
|
||||||
|
#include <MenuItem.h>
|
||||||
|
#include <MessageRunner.h>
|
||||||
|
#include <PopUpMenu.h>
|
||||||
|
#include <TextView.h>
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
|
||||||
|
extern "C" _EXPORT BView *instantiate_deskbar_item(void);
|
||||||
|
|
||||||
|
|
||||||
|
const uint32 kMsgUpdate = 'updt';
|
||||||
|
const uint32 kMsgToggleLabel = 'tglb';
|
||||||
|
const uint32 kMsgToggleTime = 'tgtm';
|
||||||
|
const uint32 kMsgToggleStatusIcon = 'tgsi';
|
||||||
|
|
||||||
|
const uint32 kMinIconWidth = 16;
|
||||||
|
const uint32 kMinIconHeight = 16;
|
||||||
|
|
||||||
|
const bigtime_t kUpdateInterval = 1000000;
|
||||||
|
// every second
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef HAIKU_TARGET_PLATFORM_HAIKU
|
||||||
|
// definitions for the APM driver available for BeOS
|
||||||
|
enum {
|
||||||
|
APM_CONTROL = B_DEVICE_OP_CODES_END + 1,
|
||||||
|
APM_DUMP_POWER_STATUS,
|
||||||
|
APM_BIOS_CALL,
|
||||||
|
APM_SET_SAFETY
|
||||||
|
};
|
||||||
|
|
||||||
|
#define BIOS_APM_GET_POWER_STATUS 0x530a
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
PowerStatusView::PowerStatusView(BRect frame, int32 resizingMode, bool inDeskbar)
|
||||||
|
: BView(frame, kDeskbarItemName, resizingMode,
|
||||||
|
B_WILL_DRAW | B_FULL_UPDATE_ON_RESIZE),
|
||||||
|
fInDeskbar(inDeskbar)
|
||||||
|
{
|
||||||
|
_Init();
|
||||||
|
|
||||||
|
if (!inDeskbar) {
|
||||||
|
// we were obviously added to a standard window - let's add a dragger
|
||||||
|
frame.OffsetTo(B_ORIGIN);
|
||||||
|
frame.top = frame.bottom - 7;
|
||||||
|
frame.left = frame.right - 7;
|
||||||
|
BDragger* dragger = new BDragger(frame, this,
|
||||||
|
B_FOLLOW_RIGHT | B_FOLLOW_BOTTOM);
|
||||||
|
AddChild(dragger);
|
||||||
|
} else
|
||||||
|
_Update();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
PowerStatusView::PowerStatusView(BMessage* archive)
|
||||||
|
: BView(archive)
|
||||||
|
{
|
||||||
|
_Init();
|
||||||
|
|
||||||
|
bool value;
|
||||||
|
if (archive->FindBool("show label", &value) == B_OK)
|
||||||
|
fShowLabel = value;
|
||||||
|
if (archive->FindBool("show icon", &value) == B_OK)
|
||||||
|
fShowStatusIcon = value;
|
||||||
|
if (archive->FindBool("show time", &value) == B_OK)
|
||||||
|
fShowTime = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
PowerStatusView::~PowerStatusView()
|
||||||
|
{
|
||||||
|
#ifndef HAIKU_TARGET_PLATFORM_HAIKU
|
||||||
|
close(fDevice);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
PowerStatusView::_Init()
|
||||||
|
{
|
||||||
|
fShowLabel = true;
|
||||||
|
fShowTime = false;
|
||||||
|
fShowStatusIcon = true;
|
||||||
|
|
||||||
|
fMessageRunner = NULL;
|
||||||
|
fPercent = -1;
|
||||||
|
fOnline = true;
|
||||||
|
fTimeLeft = 0;
|
||||||
|
|
||||||
|
#ifdef HAIKU_TARGET_PLATFORM_HAIKU
|
||||||
|
// TODO: implement me
|
||||||
|
#else
|
||||||
|
fDevice = open("/dev/misc/apm", O_RDONLY);
|
||||||
|
if (fDevice < 0) {
|
||||||
|
fprintf(stderr, "No power interface found.\n");
|
||||||
|
_Quit();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
PowerStatusView::_Quit()
|
||||||
|
{
|
||||||
|
if (fInDeskbar) {
|
||||||
|
BDeskbar deskbar;
|
||||||
|
deskbar.RemoveItem(kDeskbarItemName);
|
||||||
|
} else
|
||||||
|
be_app->PostMessage(B_QUIT_REQUESTED);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
PowerStatusView *
|
||||||
|
PowerStatusView::Instantiate(BMessage* archive)
|
||||||
|
{
|
||||||
|
if (!validate_instantiation(archive, "PowerStatusView"))
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
return new PowerStatusView(archive);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
status_t
|
||||||
|
PowerStatusView::Archive(BMessage* archive, bool deep) const
|
||||||
|
{
|
||||||
|
status_t status = BView::Archive(archive, deep);
|
||||||
|
if (status == B_OK)
|
||||||
|
status = archive->AddString("add_on", kSignature);
|
||||||
|
if (status == B_OK)
|
||||||
|
status = archive->AddString("class", "PowerStatusView");
|
||||||
|
if (status == B_OK)
|
||||||
|
status = archive->AddBool("show label", fShowLabel);
|
||||||
|
if (status == B_OK)
|
||||||
|
status = archive->AddBool("show icon", fShowStatusIcon);
|
||||||
|
if (status == B_OK)
|
||||||
|
status = archive->AddBool("show time", fShowTime);
|
||||||
|
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
PowerStatusView::AttachedToWindow()
|
||||||
|
{
|
||||||
|
BView::AttachedToWindow();
|
||||||
|
if (Parent())
|
||||||
|
SetViewColor(Parent()->ViewColor());
|
||||||
|
else
|
||||||
|
SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR));
|
||||||
|
|
||||||
|
SetLowColor(ViewColor());
|
||||||
|
|
||||||
|
BMessage update(kMsgUpdate);
|
||||||
|
fMessageRunner = new BMessageRunner(this, &update, kUpdateInterval);
|
||||||
|
|
||||||
|
_Update();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
PowerStatusView::DetachedFromWindow()
|
||||||
|
{
|
||||||
|
delete fMessageRunner;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
PowerStatusView::MessageReceived(BMessage *message)
|
||||||
|
{
|
||||||
|
switch (message->what) {
|
||||||
|
case kMsgUpdate:
|
||||||
|
_Update();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case kMsgToggleLabel:
|
||||||
|
fShowLabel = !fShowLabel;
|
||||||
|
_Update(true);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case kMsgToggleTime:
|
||||||
|
fShowTime = !fShowTime;
|
||||||
|
_Update(true);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case kMsgToggleStatusIcon:
|
||||||
|
fShowStatusIcon = !fShowStatusIcon;
|
||||||
|
_Update(true);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case B_ABOUT_REQUESTED:
|
||||||
|
_AboutRequested();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case B_QUIT_REQUESTED:
|
||||||
|
_Quit();
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
BView::MessageReceived(message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
PowerStatusView::_DrawBattery(BRect rect)
|
||||||
|
{
|
||||||
|
float quarter = floorf((rect.Height() + 1) / 4);
|
||||||
|
rect.top += quarter;
|
||||||
|
rect.bottom -= quarter;
|
||||||
|
|
||||||
|
rect.InsetBy(2, 0);
|
||||||
|
|
||||||
|
float left = rect.left;
|
||||||
|
rect.left += rect.Width() / 11;
|
||||||
|
|
||||||
|
float gap = 1;
|
||||||
|
if (rect.Height() > 8) {
|
||||||
|
rect.InsetBy(1, 1);
|
||||||
|
SetPenSize(2);
|
||||||
|
gap = 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fOnline)
|
||||||
|
SetHighColor(92, 92, 92);
|
||||||
|
|
||||||
|
StrokeRect(rect);
|
||||||
|
|
||||||
|
SetPenSize(1);
|
||||||
|
FillRect(BRect(left, floorf(rect.top + rect.Height() / 4) + 1,
|
||||||
|
rect.left, floorf(rect.bottom - rect.Height() / 4)));
|
||||||
|
|
||||||
|
int32 percent = fPercent;
|
||||||
|
if (percent > 100 || percent < 0)
|
||||||
|
percent = 100;
|
||||||
|
|
||||||
|
if (percent > 0) {
|
||||||
|
if (percent < 16)
|
||||||
|
SetHighColor(180, 0, 0);
|
||||||
|
|
||||||
|
rect.InsetBy(gap + 1, gap + 1);
|
||||||
|
if (gap > 1) {
|
||||||
|
rect.right++;
|
||||||
|
rect.bottom++;
|
||||||
|
}
|
||||||
|
|
||||||
|
rect.right = rect.left + rect.Width() * min_c(percent, 100) / 100.0;
|
||||||
|
FillRect(rect);
|
||||||
|
}
|
||||||
|
|
||||||
|
SetHighColor(0, 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
PowerStatusView::Draw(BRect updateRect)
|
||||||
|
{
|
||||||
|
float aspect = Bounds().Width() / Bounds().Height();
|
||||||
|
bool below = aspect <= 1.0f;
|
||||||
|
|
||||||
|
font_height fontHeight;
|
||||||
|
GetFontHeight(&fontHeight);
|
||||||
|
float baseLine = ceilf(fontHeight.ascent);
|
||||||
|
|
||||||
|
char text[64];
|
||||||
|
_SetLabel(text, sizeof(text));
|
||||||
|
|
||||||
|
float textHeight = ceilf(fontHeight.descent + fontHeight.ascent);
|
||||||
|
float textWidth = StringWidth(text);
|
||||||
|
bool showLabel = fShowLabel && text[0];
|
||||||
|
|
||||||
|
BRect iconRect;
|
||||||
|
|
||||||
|
if (fShowStatusIcon) {
|
||||||
|
iconRect = Bounds();
|
||||||
|
if (showLabel) {
|
||||||
|
if (below)
|
||||||
|
iconRect.bottom -= textHeight + 4;
|
||||||
|
else
|
||||||
|
iconRect.right -= textWidth + 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
// make a square
|
||||||
|
iconRect.bottom = min_c(iconRect.bottom, iconRect.right);
|
||||||
|
iconRect.right = iconRect.bottom;
|
||||||
|
|
||||||
|
if (iconRect.Width() + 1 >= kMinIconWidth
|
||||||
|
&& iconRect.Height() + 1 >= kMinIconHeight) {
|
||||||
|
// TODO: have real icons
|
||||||
|
//if (!fOnline)
|
||||||
|
_DrawBattery(iconRect);
|
||||||
|
//else
|
||||||
|
// FillRect(iconRect);
|
||||||
|
} else {
|
||||||
|
// there is not enough space for the icon
|
||||||
|
iconRect.Set(0, 0, -1, -1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (showLabel) {
|
||||||
|
BPoint point(0, baseLine);
|
||||||
|
|
||||||
|
if (iconRect.IsValid()) {
|
||||||
|
if (below) {
|
||||||
|
point.x = (iconRect.Width() - textWidth) / 2;
|
||||||
|
point.y += iconRect.Height() + 2;
|
||||||
|
} else {
|
||||||
|
point.x = iconRect.Width() + 2;
|
||||||
|
point.y += (iconRect.Height() - textHeight) / 2;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
point.x = (Bounds().Width() - textWidth) / 2;
|
||||||
|
point.y += (Bounds().Height() - textHeight) / 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
DrawString(text, point);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
PowerStatusView::MouseDown(BPoint point)
|
||||||
|
{
|
||||||
|
BPopUpMenu *menu = new BPopUpMenu(B_EMPTY_STRING, false, false);
|
||||||
|
menu->SetFont(be_plain_font);
|
||||||
|
|
||||||
|
BMenuItem* item;
|
||||||
|
menu->AddItem(item = new BMenuItem("Show Text Label", new BMessage(kMsgToggleLabel)));
|
||||||
|
if (fShowLabel)
|
||||||
|
item->SetMarked(true);
|
||||||
|
menu->AddItem(item = new BMenuItem("Show Status Icon",
|
||||||
|
new BMessage(kMsgToggleStatusIcon)));
|
||||||
|
if (fShowStatusIcon)
|
||||||
|
item->SetMarked(true);
|
||||||
|
menu->AddItem(new BMenuItem(!fShowTime ? "Show Time" : "Show Percent",
|
||||||
|
new BMessage(kMsgToggleTime)));
|
||||||
|
|
||||||
|
menu->AddSeparatorItem();
|
||||||
|
menu->AddItem(new BMenuItem("About" B_UTF8_ELLIPSIS, new BMessage(B_ABOUT_REQUESTED)));
|
||||||
|
menu->AddItem(new BMenuItem("Quit", new BMessage(B_QUIT_REQUESTED)));
|
||||||
|
menu->SetTargetForItems(this);
|
||||||
|
|
||||||
|
ConvertToScreen(&point);
|
||||||
|
menu->Go(point, true, false, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
PowerStatusView::_AboutRequested()
|
||||||
|
{
|
||||||
|
BAlert *alert = new BAlert("about", "PowerStatus\n"
|
||||||
|
"\twritten by Axel Dörfler\n"
|
||||||
|
"\tCopyright 2006, Haiku, Inc.\n", "Ok");
|
||||||
|
BTextView *view = alert->TextView();
|
||||||
|
BFont font;
|
||||||
|
|
||||||
|
view->SetStylable(true);
|
||||||
|
|
||||||
|
view->GetFont(&font);
|
||||||
|
font.SetSize(18);
|
||||||
|
font.SetFace(B_BOLD_FACE);
|
||||||
|
view->SetFontAndColor(0, 11, &font);
|
||||||
|
|
||||||
|
alert->Go();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
PowerStatusView::_SetLabel(char* buffer, size_t bufferLength)
|
||||||
|
{
|
||||||
|
if (bufferLength < 1)
|
||||||
|
return;
|
||||||
|
|
||||||
|
buffer[0] = '\0';
|
||||||
|
|
||||||
|
if (!fShowLabel)
|
||||||
|
return;
|
||||||
|
|
||||||
|
const char* open = "";
|
||||||
|
const char* close = "";
|
||||||
|
if (fOnline) {
|
||||||
|
open = "(";
|
||||||
|
close = ")";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!fShowTime && fPercent >= 0)
|
||||||
|
snprintf(buffer, bufferLength, "%s%ld%%%s", open, fPercent, close);
|
||||||
|
else if (fShowTime && fTimeLeft >= 0) {
|
||||||
|
snprintf(buffer, bufferLength, "%s%ld:%ld%s",
|
||||||
|
open, fTimeLeft / 3600, fTimeLeft / 60, close);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
PowerStatusView::_Update(bool force)
|
||||||
|
{
|
||||||
|
#ifdef HAIKU_TARGET_PLATFORM_HAIKU
|
||||||
|
// TODO: retrieve data from APM/ACPI kernel interface
|
||||||
|
fPercent = 42;
|
||||||
|
fTimeLeft = 1500;
|
||||||
|
fOnline = true;
|
||||||
|
#else
|
||||||
|
if (fDevice < 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
uint16 regs[6] = {0, 0, 0, 0, 0, 0};
|
||||||
|
regs[0] = BIOS_APM_GET_POWER_STATUS;
|
||||||
|
regs[1] = 0x1;
|
||||||
|
if (ioctl(fDevice, APM_BIOS_CALL, regs) == 0) {
|
||||||
|
fOnline = (regs[1] >> 8) != 0 && (regs[1] >> 8) != 2;
|
||||||
|
fPercent = regs[2] & 255;
|
||||||
|
if (fPercent > 100)
|
||||||
|
fPercent = -1;
|
||||||
|
fTimeLeft = fPercent >= 0 ? regs[3] : -1;
|
||||||
|
if (fTimeLeft > 0xffff)
|
||||||
|
fTimeLeft = -1;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (fInDeskbar) {
|
||||||
|
// make sure the tray icon is large enough
|
||||||
|
float width = fShowStatusIcon ? kMinIconWidth + 2 : 0;
|
||||||
|
|
||||||
|
if (fShowLabel) {
|
||||||
|
char text[64];
|
||||||
|
_SetLabel(text, sizeof(text));
|
||||||
|
|
||||||
|
if (text[0])
|
||||||
|
width += ceilf(StringWidth(text)) + 4;
|
||||||
|
}
|
||||||
|
if (width == 0) {
|
||||||
|
// make sure we're not going away completely
|
||||||
|
width = 8;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (width != Bounds().Width())
|
||||||
|
ResizeTo(width, Bounds().Height());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (force)
|
||||||
|
Invalidate();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// #pragma mark -
|
||||||
|
|
||||||
|
|
||||||
|
extern "C" _EXPORT BView *
|
||||||
|
instantiate_deskbar_item(void)
|
||||||
|
{
|
||||||
|
return new PowerStatusView(BRect(0, 0, 15, 15), B_FOLLOW_NONE, true);
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,56 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2006, Haiku, Inc. All Rights Reserved.
|
||||||
|
* Distributed under the terms of the MIT License.
|
||||||
|
*
|
||||||
|
* Authors:
|
||||||
|
* Axel Dörfler, [email protected]
|
||||||
|
*/
|
||||||
|
#ifndef POWER_STATUS_VIEW_H
|
||||||
|
#define POWER_STATUS_VIEW_H
|
||||||
|
|
||||||
|
|
||||||
|
#include <View.h>
|
||||||
|
|
||||||
|
class BMessageRunner;
|
||||||
|
|
||||||
|
|
||||||
|
class PowerStatusView : public BView {
|
||||||
|
public:
|
||||||
|
PowerStatusView(BRect frame, int32 resizingMode, bool inDeskbar = false);
|
||||||
|
PowerStatusView(BMessage* archive);
|
||||||
|
virtual ~PowerStatusView();
|
||||||
|
|
||||||
|
static PowerStatusView* Instantiate(BMessage* archive);
|
||||||
|
virtual status_t Archive(BMessage* archive, bool deep = true) const;
|
||||||
|
|
||||||
|
virtual void AttachedToWindow();
|
||||||
|
virtual void DetachedFromWindow();
|
||||||
|
|
||||||
|
virtual void MessageReceived(BMessage* message);
|
||||||
|
virtual void MouseDown(BPoint where);
|
||||||
|
virtual void Draw(BRect updateRect);
|
||||||
|
|
||||||
|
private:
|
||||||
|
void _AboutRequested();
|
||||||
|
void _Quit();
|
||||||
|
void _Init();
|
||||||
|
void _SetLabel(char* buffer, size_t bufferLength);
|
||||||
|
void _Update(bool force = false);
|
||||||
|
void _DrawBattery(BRect rect);
|
||||||
|
|
||||||
|
BMessageRunner* fMessageRunner;
|
||||||
|
bool fInDeskbar;
|
||||||
|
bool fShowLabel;
|
||||||
|
bool fShowTime;
|
||||||
|
bool fShowStatusIcon;
|
||||||
|
|
||||||
|
int32 fPercent;
|
||||||
|
time_t fTimeLeft;
|
||||||
|
bool fOnline;
|
||||||
|
|
||||||
|
#ifndef HAIKU_TARGET_PLATFORM_HAIKU
|
||||||
|
int fDevice;
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // POWER_STATUS_VIEW_H
|
||||||
@@ -0,0 +1,38 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2006, Haiku, Inc. All Rights Reserved.
|
||||||
|
* Distributed under the terms of the MIT License.
|
||||||
|
*
|
||||||
|
* Authors:
|
||||||
|
* Axel Dörfler, [email protected]
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#include "PowerStatusWindow.h"
|
||||||
|
#include "PowerStatusView.h"
|
||||||
|
|
||||||
|
#include <Application.h>
|
||||||
|
|
||||||
|
|
||||||
|
PowerStatusWindow::PowerStatusWindow()
|
||||||
|
: BWindow(BRect(100, 150, 147, 197), "PowerStatus", B_TITLED_WINDOW,
|
||||||
|
B_NOT_ZOOMABLE | B_ASYNCHRONOUS_CONTROLS)
|
||||||
|
{
|
||||||
|
BView* topView = new BView(Bounds(), NULL, B_FOLLOW_ALL, B_WILL_DRAW);
|
||||||
|
topView->SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR));
|
||||||
|
AddChild(topView);
|
||||||
|
|
||||||
|
topView->AddChild(new PowerStatusView(Bounds(), B_FOLLOW_ALL));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
PowerStatusWindow::~PowerStatusWindow()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool
|
||||||
|
PowerStatusWindow::QuitRequested()
|
||||||
|
{
|
||||||
|
be_app->PostMessage(B_QUIT_REQUESTED);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2006, Haiku, Inc. All Rights Reserved.
|
||||||
|
* Distributed under the terms of the MIT License.
|
||||||
|
*
|
||||||
|
* Authors:
|
||||||
|
* Axel Dörfler, [email protected]
|
||||||
|
*/
|
||||||
|
#ifndef POWER_STATUS_WINDOW_H
|
||||||
|
#define POWER_STATUS_WINDOW_H
|
||||||
|
|
||||||
|
|
||||||
|
#include <Window.h>
|
||||||
|
|
||||||
|
|
||||||
|
class PowerStatusWindow : public BWindow {
|
||||||
|
public:
|
||||||
|
PowerStatusWindow();
|
||||||
|
virtual ~PowerStatusWindow();
|
||||||
|
|
||||||
|
virtual bool QuitRequested();
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // POWER_STATUS_WINDOW_H
|
||||||
Reference in New Issue
Block a user