a4cf8811e5
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@41208 a95241bf-73f2-0310-859d-f6bbb57e9c96
1005 lines
26 KiB
C++
1005 lines
26 KiB
C++
/*
|
|
* Copyright 2003-2010, Haiku.
|
|
* Distributed under the terms of the MIT License.
|
|
*
|
|
* Authors:
|
|
* Michael Phipps
|
|
* Jérôme Duval, jerome.duval@free.fr
|
|
* Axel Dörfler, axeld@pinc-software.de
|
|
*/
|
|
|
|
|
|
#include "ScreenSaverWindow.h"
|
|
|
|
#include <stdio.h>
|
|
|
|
#include <Application.h>
|
|
#include <Box.h>
|
|
#include <Button.h>
|
|
#include <Catalog.h>
|
|
#include <Directory.h>
|
|
#include <DurationFormat.h>
|
|
#include <Entry.h>
|
|
#include <File.h>
|
|
#include <FindDirectory.h>
|
|
#include <Font.h>
|
|
#include <ListView.h>
|
|
#include <Path.h>
|
|
#include <Roster.h>
|
|
#include <Screen.h>
|
|
#include <ScreenSaver.h>
|
|
#include <ScrollView.h>
|
|
#include <Slider.h>
|
|
#include <StringView.h>
|
|
#include <TabView.h>
|
|
#include <TextView.h>
|
|
|
|
#include <BuildScreenSaverDefaultSettingsView.h>
|
|
|
|
#include "PreviewView.h"
|
|
#include "ScreenCornerSelector.h"
|
|
#include "ScreenSaverItem.h"
|
|
|
|
#undef B_TRANSLATE_CONTEXT
|
|
#define B_TRANSLATE_CONTEXT "ScreenSaver"
|
|
|
|
const uint32 kPreviewMonitorGap = 16;
|
|
const uint32 kMinSettingsWidth = 230;
|
|
const uint32 kMinSettingsHeight = 120;
|
|
|
|
const int32 kMsgSaverSelected = 'SSEL';
|
|
const int32 kMsgTestSaver = 'TEST';
|
|
const int32 kMsgAddSaver = 'ADD ';
|
|
const int32 kMsgPasswordCheckBox = 'PWCB';
|
|
const int32 kMsgRunSliderChanged = 'RSch';
|
|
const int32 kMsgRunSliderUpdate = 'RSup';
|
|
const int32 kMsgPasswordSliderChanged = 'PWch';
|
|
const int32 kMsgPasswordSliderUpdate = 'PWup';
|
|
const int32 kMsgChangePassword = 'PWBT';
|
|
const int32 kMsgEnableScreenSaverBox = 'ESCH';
|
|
|
|
const int32 kMsgTurnOffCheckBox = 'TUOF';
|
|
const int32 kMsgTurnOffSliderChanged = 'TUch';
|
|
const int32 kMsgTurnOffSliderUpdate = 'TUup';
|
|
|
|
const int32 kMsgFadeCornerChanged = 'fdcc';
|
|
const int32 kMsgNeverFadeCornerChanged = 'nfcc';
|
|
|
|
|
|
class TimeSlider : public BSlider {
|
|
public:
|
|
TimeSlider(BRect frame, const char* name,
|
|
uint32 changedMessage,
|
|
uint32 updateMessage);
|
|
virtual ~TimeSlider();
|
|
|
|
virtual void AttachedToWindow();
|
|
virtual void SetValue(int32 value);
|
|
|
|
void SetTime(bigtime_t useconds);
|
|
bigtime_t Time() const;
|
|
|
|
private:
|
|
void _TimeToString(bigtime_t useconds,
|
|
BString& string);
|
|
};
|
|
|
|
|
|
class FadeView : public BView {
|
|
public:
|
|
FadeView(BRect frame, const char* name,
|
|
ScreenSaverSettings& settings);
|
|
|
|
virtual void AttachedToWindow();
|
|
};
|
|
|
|
|
|
class ModulesView : public BView {
|
|
public:
|
|
ModulesView(BRect frame, const char* name,
|
|
ScreenSaverSettings& settings);
|
|
virtual ~ModulesView();
|
|
|
|
virtual void DetachedFromWindow();
|
|
virtual void AttachedToWindow();
|
|
virtual void AllAttached();
|
|
virtual void MessageReceived(BMessage* message);
|
|
|
|
void PopulateScreenSaverList();
|
|
void SaveState();
|
|
|
|
private:
|
|
static int _CompareScreenSaverItems(const void* left,
|
|
const void* right);
|
|
|
|
BScreenSaver* _ScreenSaver();
|
|
void _CloseSaver();
|
|
void _OpenSaver();
|
|
|
|
private:
|
|
BFilePanel* fFilePanel;
|
|
BListView* fListView;
|
|
BButton* fTestButton;
|
|
BButton* fAddButton;
|
|
|
|
ScreenSaverSettings& fSettings;
|
|
ScreenSaverRunner* fSaverRunner;
|
|
BString fCurrentName;
|
|
|
|
BBox* fSettingsBox;
|
|
BView* fSettingsView;
|
|
|
|
PreviewView* fPreviewView;
|
|
|
|
team_id fScreenSaverTestTeam;
|
|
};
|
|
|
|
|
|
static const int32 kTimeInUnits[] = {
|
|
30, 60, 90,
|
|
120, 150, 180,
|
|
240, 300, 360,
|
|
420, 480, 540,
|
|
600, 900, 1200,
|
|
1500, 1800, 2400,
|
|
3000, 3600, 5400,
|
|
7200, 9000, 10800,
|
|
14400, 18000
|
|
};
|
|
static const int32 kTimeUnitCount
|
|
= sizeof(kTimeInUnits) / sizeof(kTimeInUnits[0]);
|
|
|
|
|
|
TimeSlider::TimeSlider(BRect frame, const char* name, uint32 changedMessage,
|
|
uint32 updateMessage)
|
|
:
|
|
BSlider(frame, name, B_TRANSLATE("30 seconds"),
|
|
new BMessage(changedMessage),
|
|
0, kTimeUnitCount - 1, B_TRIANGLE_THUMB, B_FOLLOW_LEFT_RIGHT)
|
|
{
|
|
SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR));
|
|
SetModificationMessage(new BMessage(updateMessage));
|
|
SetBarThickness(10);
|
|
}
|
|
|
|
|
|
TimeSlider::~TimeSlider()
|
|
{
|
|
}
|
|
|
|
|
|
void
|
|
TimeSlider::AttachedToWindow()
|
|
{
|
|
BSlider::AttachedToWindow();
|
|
SetTarget(Window());
|
|
}
|
|
|
|
|
|
void
|
|
TimeSlider::SetValue(int32 value)
|
|
{
|
|
int32 oldValue = Value();
|
|
BSlider::SetValue(value);
|
|
|
|
if (oldValue != Value()) {
|
|
BString label;
|
|
_TimeToString(kTimeInUnits[Value()] * 1000000LL, label);
|
|
SetLabel(label.String());
|
|
}
|
|
}
|
|
|
|
|
|
void
|
|
TimeSlider::SetTime(bigtime_t useconds)
|
|
{
|
|
for (int t = 0; t < kTimeUnitCount; t++) {
|
|
if (kTimeInUnits[t] * 1000000LL == useconds) {
|
|
SetValue(t);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
bigtime_t
|
|
TimeSlider::Time() const
|
|
{
|
|
return 1000000LL * kTimeInUnits[Value()];
|
|
}
|
|
|
|
|
|
void
|
|
TimeSlider::_TimeToString(bigtime_t useconds, BString& string)
|
|
{
|
|
BDurationFormat formatter;
|
|
formatter.Format(0, useconds, &string);
|
|
}
|
|
|
|
|
|
// #pragma mark -
|
|
|
|
|
|
FadeView::FadeView(BRect rect, const char* name, ScreenSaverSettings& settings)
|
|
:
|
|
BView(rect, name, B_FOLLOW_ALL, B_WILL_DRAW)
|
|
{
|
|
SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR));
|
|
}
|
|
|
|
|
|
void
|
|
FadeView::AttachedToWindow()
|
|
{
|
|
if (Parent() != NULL) {
|
|
// We adopt the size of our parent view (in case the window
|
|
// was resized during our absence (BTabView...)
|
|
ResizeTo(Parent()->Bounds().Width(), Parent()->Bounds().Height());
|
|
}
|
|
}
|
|
|
|
|
|
// #pragma mark -
|
|
|
|
|
|
ModulesView::ModulesView(BRect rect, const char* name,
|
|
ScreenSaverSettings& settings)
|
|
:
|
|
BView(rect, name, B_FOLLOW_ALL, B_WILL_DRAW),
|
|
fSettings(settings),
|
|
fSaverRunner(NULL),
|
|
fSettingsView(NULL),
|
|
fScreenSaverTestTeam(-1)
|
|
{
|
|
SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR));
|
|
|
|
fTestButton = new BButton(rect, "TestButton", B_TRANSLATE("Test"),
|
|
new BMessage(kMsgTestSaver), B_FOLLOW_LEFT | B_FOLLOW_BOTTOM);
|
|
float width, height;
|
|
fTestButton->GetPreferredSize(&width, &height);
|
|
fTestButton->ResizeTo(width + 16, height);
|
|
fTestButton->MoveTo(8, rect.bottom - 8 - height);
|
|
AddChild(fTestButton);
|
|
|
|
rect = fTestButton->Frame();
|
|
rect.OffsetBy(fTestButton->Bounds().Width() + 8, 0);
|
|
fAddButton = new BButton(rect, "AddButton",
|
|
B_TRANSLATE("Add" B_UTF8_ELLIPSIS), new BMessage(kMsgAddSaver),
|
|
B_FOLLOW_LEFT | B_FOLLOW_BOTTOM);
|
|
AddChild(fAddButton);
|
|
|
|
rect = Bounds().InsetByCopy(8 + kPreviewMonitorGap, 12);
|
|
rect.right = fAddButton->Frame().right - kPreviewMonitorGap;
|
|
rect.bottom = rect.top + 3 * rect.Width() / 4;
|
|
// 4:3 monitor
|
|
|
|
fPreviewView = new PreviewView(rect, "preview");
|
|
AddChild(fPreviewView);
|
|
|
|
rect.left = 8;
|
|
rect.right -= B_V_SCROLL_BAR_WIDTH + 2 - kPreviewMonitorGap;
|
|
// scroll view border
|
|
rect.top = rect.bottom + 14;
|
|
rect.bottom = fTestButton->Frame().top - 10;
|
|
fListView = new BListView(rect, "SaversListView", B_SINGLE_SELECTION_LIST,
|
|
B_FOLLOW_LEFT | B_FOLLOW_TOP_BOTTOM);
|
|
fListView->SetSelectionMessage(new BMessage(kMsgSaverSelected));
|
|
AddChild(new BScrollView("scroll_list", fListView,
|
|
B_FOLLOW_LEFT | B_FOLLOW_TOP_BOTTOM, 0, false, true));
|
|
|
|
rect = Bounds().InsetByCopy(8, 8);
|
|
rect.left = fAddButton->Frame().right + 8;
|
|
AddChild(fSettingsBox = new BBox(rect, "SettingsBox", B_FOLLOW_ALL,
|
|
B_WILL_DRAW));
|
|
fSettingsBox->SetLabel(B_TRANSLATE("Screensaver settings"));
|
|
|
|
PopulateScreenSaverList();
|
|
fFilePanel = new BFilePanel();
|
|
}
|
|
|
|
|
|
ModulesView::~ModulesView()
|
|
{
|
|
delete fFilePanel;
|
|
}
|
|
|
|
|
|
void
|
|
ModulesView::DetachedFromWindow()
|
|
{
|
|
SaveState();
|
|
_CloseSaver();
|
|
}
|
|
|
|
|
|
void
|
|
ModulesView::AttachedToWindow()
|
|
{
|
|
if (Parent() != NULL) {
|
|
// We adopt the size of our parent view (in case the window
|
|
// was resized during our absence (BTabView...)
|
|
ResizeTo(Parent()->Bounds().Width(), Parent()->Bounds().Height());
|
|
}
|
|
|
|
_OpenSaver();
|
|
|
|
fListView->SetTarget(this);
|
|
fTestButton->SetTarget(this);
|
|
fAddButton->SetTarget(this);
|
|
}
|
|
|
|
|
|
void
|
|
ModulesView::AllAttached()
|
|
{
|
|
// This only works after the view has been attached
|
|
fListView->ScrollToSelection();
|
|
}
|
|
|
|
|
|
void
|
|
ModulesView::MessageReceived(BMessage* message)
|
|
{
|
|
switch (message->what) {
|
|
case kMsgSaverSelected:
|
|
{
|
|
int selection = fListView->CurrentSelection();
|
|
if (selection < 0)
|
|
break;
|
|
|
|
ScreenSaverItem* item
|
|
= (ScreenSaverItem*)fListView->ItemAt(selection);
|
|
if (item == NULL)
|
|
break;
|
|
|
|
if (!strcmp(item->Text(), B_TRANSLATE("Blackness")))
|
|
fSettings.SetModuleName("");
|
|
else
|
|
fSettings.SetModuleName(item->Text());
|
|
|
|
SaveState();
|
|
_CloseSaver();
|
|
_OpenSaver();
|
|
fSettings.Save();
|
|
break;
|
|
}
|
|
|
|
case kMsgTestSaver:
|
|
{
|
|
SaveState();
|
|
fSettings.Save();
|
|
|
|
_CloseSaver();
|
|
|
|
be_roster->StartWatching(BMessenger(this, Looper()),
|
|
B_REQUEST_QUIT);
|
|
if (be_roster->Launch(SCREEN_BLANKER_SIG, &fSettings.Message(),
|
|
&fScreenSaverTestTeam) == B_OK)
|
|
break;
|
|
|
|
// Try really hard to launch it. It's very likely that this fails
|
|
// when we run from the CD, and there is only an incomplete mime
|
|
// database for example...
|
|
BPath path;
|
|
if (find_directory(B_SYSTEM_BIN_DIRECTORY, &path) != B_OK
|
|
|| path.Append("screen_blanker") != B_OK)
|
|
path.SetTo("/boot/system/bin/screen_blanker");
|
|
|
|
BEntry entry(path.Path());
|
|
entry_ref ref;
|
|
if (entry.GetRef(&ref) == B_OK) {
|
|
be_roster->Launch(&ref, &fSettings.Message(),
|
|
&fScreenSaverTestTeam);
|
|
}
|
|
break;
|
|
}
|
|
case kMsgAddSaver:
|
|
fFilePanel->Show();
|
|
break;
|
|
|
|
case B_SOME_APP_QUIT:
|
|
{
|
|
team_id team;
|
|
if (message->FindInt32("be:team", &team) == B_OK
|
|
&& team == fScreenSaverTestTeam) {
|
|
be_roster->StopWatching(this);
|
|
_OpenSaver();
|
|
}
|
|
break;
|
|
}
|
|
|
|
default:
|
|
BView::MessageReceived(message);
|
|
}
|
|
}
|
|
|
|
|
|
void
|
|
ModulesView::SaveState()
|
|
{
|
|
BScreenSaver* saver = _ScreenSaver();
|
|
if (saver == NULL)
|
|
return;
|
|
|
|
BMessage state;
|
|
if (saver->SaveState(&state) == B_OK)
|
|
fSettings.SetModuleState(fCurrentName.String(), &state);
|
|
}
|
|
|
|
|
|
void
|
|
ModulesView::PopulateScreenSaverList()
|
|
{
|
|
fListView->DeselectAll();
|
|
while (ScreenSaverItem* item
|
|
= (ScreenSaverItem*)fListView->RemoveItem((int32)0)) {
|
|
delete item;
|
|
}
|
|
|
|
// Blackness is a built-in screen saver
|
|
fListView->AddItem(new ScreenSaverItem(B_TRANSLATE("Blackness"), ""));
|
|
|
|
// Iterate over add-on directories, and add their files to the list view
|
|
|
|
directory_which which[] = {
|
|
B_BEOS_ADDONS_DIRECTORY, B_USER_ADDONS_DIRECTORY};
|
|
ScreenSaverItem* selectItem = NULL;
|
|
|
|
for (uint32 i = 0; i < sizeof(which) / sizeof(which[0]); i++) {
|
|
BPath basePath;
|
|
find_directory(which[i], &basePath);
|
|
basePath.Append("Screen Savers", true);
|
|
|
|
BDirectory dir(basePath.Path());
|
|
BEntry entry;
|
|
while (dir.GetNextEntry(&entry, true) == B_OK) {
|
|
char name[B_FILE_NAME_LENGTH];
|
|
if (entry.GetName(name) != B_OK)
|
|
continue;
|
|
|
|
BPath path = basePath;
|
|
path.Append(name);
|
|
|
|
ScreenSaverItem* item = new ScreenSaverItem(name, path.Path());
|
|
fListView->AddItem(item);
|
|
|
|
if (!strcmp(fSettings.ModuleName(), item->Text())
|
|
|| (!strcmp(fSettings.ModuleName(), "")
|
|
&& !strcmp(item->Text(), B_TRANSLATE("Blackness"))))
|
|
selectItem = item;
|
|
}
|
|
}
|
|
|
|
fListView->SortItems(_CompareScreenSaverItems);
|
|
|
|
fListView->Select(fListView->IndexOf(selectItem));
|
|
fListView->ScrollToSelection();
|
|
}
|
|
|
|
|
|
//! Sorting function for ScreenSaverItems
|
|
int
|
|
ModulesView::_CompareScreenSaverItems(const void* left, const void* right)
|
|
{
|
|
ScreenSaverItem* leftItem = *(ScreenSaverItem **)left;
|
|
ScreenSaverItem* rightItem = *(ScreenSaverItem **)right;
|
|
|
|
return strcasecmp(leftItem->Text(), rightItem->Text());
|
|
}
|
|
|
|
|
|
BScreenSaver*
|
|
ModulesView::_ScreenSaver()
|
|
{
|
|
if (fSaverRunner != NULL)
|
|
return fSaverRunner->ScreenSaver();
|
|
|
|
return NULL;
|
|
}
|
|
|
|
|
|
void
|
|
ModulesView::_CloseSaver()
|
|
{
|
|
// remove old screen saver preview & config
|
|
|
|
BScreenSaver* saver = _ScreenSaver();
|
|
BView* view = fPreviewView->RemovePreview();
|
|
if (fSettingsView != NULL)
|
|
fSettingsBox->RemoveChild(fSettingsView);
|
|
|
|
if (fSaverRunner != NULL)
|
|
fSaverRunner->Quit();
|
|
if (saver != NULL)
|
|
saver->StopConfig();
|
|
|
|
delete view;
|
|
delete fSettingsView;
|
|
delete fSaverRunner;
|
|
// the saver runner also unloads the add-on, so it must
|
|
// be deleted last
|
|
|
|
fSettingsView = NULL;
|
|
fSaverRunner = NULL;
|
|
}
|
|
|
|
|
|
void
|
|
ModulesView::_OpenSaver()
|
|
{
|
|
// create new screen saver preview & config
|
|
|
|
BView* view = fPreviewView->AddPreview();
|
|
fCurrentName = fSettings.ModuleName();
|
|
fSaverRunner = new ScreenSaverRunner(Window(), view, true, fSettings);
|
|
BScreenSaver* saver = _ScreenSaver();
|
|
|
|
#ifdef __HAIKU__
|
|
BRect rect = fSettingsBox->InnerFrame().InsetByCopy(4, 4);
|
|
#else
|
|
BRect rect = fSettingsBox->Bounds().InsetByCopy(4, 4);
|
|
rect.top += 14;
|
|
#endif
|
|
fSettingsView = new BView(rect, "SettingsView", B_FOLLOW_ALL, B_WILL_DRAW);
|
|
fSettingsView->SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR));
|
|
fSettingsBox->AddChild(fSettingsView);
|
|
|
|
if (saver != NULL) {
|
|
fSaverRunner->Run();
|
|
saver->StartConfig(fSettingsView);
|
|
}
|
|
|
|
if (fSettingsView->ChildAt(0) == NULL) {
|
|
// There are no settings at all, we add the module name here to
|
|
// let it look a bit better at least.
|
|
BPrivate::BuildScreenSaverDefaultSettingsView(fSettingsView,
|
|
fSettings.ModuleName()[0] ? fSettings.ModuleName() :
|
|
B_TRANSLATE("Blackness"), saver || !fSettings.ModuleName()[0]
|
|
? B_TRANSLATE("No options available") :
|
|
B_TRANSLATE("Could not load screen saver"));
|
|
}
|
|
|
|
ScreenSaverWindow* window = dynamic_cast<ScreenSaverWindow*>(Window());
|
|
if (window == NULL)
|
|
return;
|
|
|
|
// find the minimal size of the settings view
|
|
|
|
float right = 0, bottom = 0;
|
|
int32 i = 0;
|
|
while ((view = fSettingsView->ChildAt(i++)) != NULL) {
|
|
// very simple heuristic...
|
|
float viewRight = view->Frame().right;
|
|
if ((view->ResizingMode() & _rule_(0, 0xf, 0, 0xf))
|
|
== B_FOLLOW_LEFT_RIGHT) {
|
|
float width, height;
|
|
view->GetPreferredSize(&width, &height);
|
|
viewRight = view->Frame().left + width / 2;
|
|
} else if ((view->ResizingMode() & _rule_(0, 0xf, 0, 0xf))
|
|
== B_FOLLOW_RIGHT)
|
|
viewRight = 8 + view->Frame().Width();
|
|
|
|
float viewBottom = view->Frame().bottom;
|
|
if ((view->ResizingMode() & _rule_(0xf, 0, 0xf, 0))
|
|
== B_FOLLOW_TOP_BOTTOM) {
|
|
float width, height;
|
|
view->GetPreferredSize(&width, &height);
|
|
viewBottom = view->Frame().top + height;
|
|
} else if ((view->ResizingMode() & _rule_(0xf, 0, 0xf, 0))
|
|
== B_FOLLOW_BOTTOM)
|
|
viewBottom = 8 + view->Frame().Height();
|
|
|
|
if (viewRight > right)
|
|
right = viewRight;
|
|
if (viewBottom > bottom)
|
|
bottom = viewBottom;
|
|
}
|
|
|
|
if (right < kMinSettingsWidth)
|
|
right = kMinSettingsWidth;
|
|
if (bottom < kMinSettingsHeight)
|
|
bottom = kMinSettingsHeight;
|
|
|
|
BPoint leftTop = fSettingsView->LeftTop();
|
|
fSettingsView->ConvertToScreen(&leftTop);
|
|
window->ConvertFromScreen(&leftTop);
|
|
window->SetMinimalSizeLimit(leftTop.x + right + 16,
|
|
leftTop.y + bottom + 16);
|
|
}
|
|
|
|
|
|
// #pragma mark -
|
|
|
|
|
|
ScreenSaverWindow::ScreenSaverWindow()
|
|
:
|
|
BWindow(BRect(50, 50, 496, 375), B_TRANSLATE_SYSTEM_NAME("ScreenSaver"),
|
|
B_TITLED_WINDOW, B_ASYNCHRONOUS_CONTROLS)
|
|
{
|
|
fSettings.Load();
|
|
|
|
BRect rect = Bounds();
|
|
fMinWidth = 430;
|
|
fMinHeight = 325;
|
|
|
|
// Create a background view
|
|
BView *background = new BView(rect, "background", B_FOLLOW_ALL, 0);
|
|
background->SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR));
|
|
AddChild(background);
|
|
|
|
// Add the tab view to the background
|
|
rect.top += 4;
|
|
fTabView = new BTabView(rect, "tab_view");
|
|
|
|
// Create the controls inside the tabs
|
|
rect = fTabView->ContainerView()->Bounds();
|
|
_SetupFadeTab(rect);
|
|
fModulesView = new ModulesView(rect, B_TRANSLATE("Screensavers"), fSettings);
|
|
|
|
fTabView->AddTab(fFadeView);
|
|
fTabView->AddTab(fModulesView);
|
|
background->AddChild(fTabView);
|
|
|
|
// Create the password editing window
|
|
fPasswordWindow = new PasswordWindow(fSettings);
|
|
fPasswordWindow->Run();
|
|
|
|
SetMinimalSizeLimit(fMinWidth, fMinHeight);
|
|
MoveTo(fSettings.WindowFrame().left, fSettings.WindowFrame().top);
|
|
ResizeTo(fSettings.WindowFrame().Width(), fSettings.WindowFrame().Height());
|
|
|
|
fEnableCheckBox->SetValue(
|
|
fSettings.TimeFlags() & ENABLE_SAVER ? B_CONTROL_ON : B_CONTROL_OFF);
|
|
fRunSlider->SetTime(fSettings.BlankTime());
|
|
fTurnOffSlider->SetTime(fSettings.OffTime() + fSettings.BlankTime());
|
|
fFadeNow->SetCorner(fSettings.BlankCorner());
|
|
fFadeNever->SetCorner(fSettings.NeverBlankCorner());
|
|
fPasswordCheckBox->SetValue(fSettings.LockEnable());
|
|
fPasswordSlider->SetTime(fSettings.PasswordTime());
|
|
|
|
fTabView->Select(fSettings.WindowTab());
|
|
|
|
_UpdateTurnOffScreen();
|
|
_UpdateStatus();
|
|
}
|
|
|
|
|
|
ScreenSaverWindow::~ScreenSaverWindow()
|
|
{
|
|
Hide();
|
|
_UpdateStatus();
|
|
|
|
delete fTabView->RemoveTab(1);
|
|
// We delete this here in order to make sure the module view saves its
|
|
// state while the window is still intact.
|
|
|
|
fSettings.Save();
|
|
}
|
|
|
|
|
|
//! Create the controls for the "General" tab
|
|
void
|
|
ScreenSaverWindow::_SetupFadeTab(BRect rect)
|
|
{
|
|
fFadeView = new FadeView(rect, B_TRANSLATE("General"), fSettings);
|
|
|
|
float StringWidth1 = be_plain_font->StringWidth(B_TRANSLATE
|
|
("Start screensaver"));
|
|
float StringWidth2 = be_plain_font->StringWidth(B_TRANSLATE
|
|
("Turn off screen"));
|
|
float StringWidth3 = be_plain_font->StringWidth(B_TRANSLATE
|
|
("Password lock"));
|
|
|
|
float labelWidth = StringWidth1;
|
|
if (labelWidth < StringWidth2)
|
|
labelWidth = StringWidth2;
|
|
if (labelWidth < StringWidth3)
|
|
labelWidth = StringWidth3;
|
|
|
|
labelWidth += 20.0f;
|
|
|
|
font_height fontHeight;
|
|
be_plain_font->GetHeight(&fontHeight);
|
|
float textHeight = ceilf(fontHeight.ascent + fontHeight.descent);
|
|
|
|
// taken from BRadioButton:
|
|
float radioButtonOffset = 2 * floorf(textHeight / 2 - 2)
|
|
+ floorf(textHeight / 2);
|
|
|
|
fEnableCheckBox = new BCheckBox(BRect(0, 0, 1, 1), "EnableCheckBox",
|
|
B_TRANSLATE("Enable screensaver"),
|
|
new BMessage(kMsgEnableScreenSaverBox));
|
|
fEnableCheckBox->ResizeToPreferred();
|
|
|
|
rect.InsetBy(8, 8);
|
|
BBox* box = new BBox(rect, "EnableScreenSaverBox", B_FOLLOW_ALL);
|
|
box->SetLabel(fEnableCheckBox);
|
|
fFadeView->AddChild(box);
|
|
|
|
// Start Screensaver
|
|
rect.left += radioButtonOffset + 6;
|
|
rect.top = fEnableCheckBox->Bounds().bottom + 8.0f;
|
|
rect.right = box->Bounds().right - 8;
|
|
BStringView* stringView = new BStringView(rect, NULL,
|
|
B_TRANSLATE("Start screensaver"));
|
|
stringView->ResizeToPreferred();
|
|
box->AddChild(stringView);
|
|
|
|
rect.left += labelWidth - 4;
|
|
fRunSlider = new TimeSlider(rect, "RunSlider", kMsgRunSliderChanged,
|
|
kMsgRunSliderUpdate);
|
|
float width, height;
|
|
fRunSlider->GetPreferredSize(&width, &height);
|
|
fRunSlider->ResizeTo(fRunSlider->Bounds().Width(), height);
|
|
box->AddChild(fRunSlider);
|
|
|
|
// Turn Off
|
|
rect.left = 10;
|
|
rect.OffsetBy(0, fRunSlider->Bounds().Height() + 4.0f);
|
|
fTurnOffCheckBox = new BCheckBox(rect, "TurnOffScreenCheckBox",
|
|
B_TRANSLATE("Turn off screen"), new BMessage(kMsgTurnOffCheckBox));
|
|
fTurnOffCheckBox->ResizeToPreferred();
|
|
box->AddChild(fTurnOffCheckBox);
|
|
|
|
rect.top += 3;
|
|
rect.left += radioButtonOffset + labelWidth;
|
|
fTurnOffSlider = new TimeSlider(rect, "TurnOffSlider",
|
|
kMsgTurnOffSliderChanged, kMsgTurnOffSliderUpdate);
|
|
fTurnOffSlider->ResizeTo(fTurnOffSlider->Bounds().Width(), height);
|
|
box->AddChild(fTurnOffSlider);
|
|
|
|
rgb_color textColor = tint_color(ui_color(B_PANEL_BACKGROUND_COLOR),
|
|
B_DISABLED_LABEL_TINT);
|
|
BRect textRect(0, 0, fTurnOffSlider->Bounds().Width(), height);
|
|
textRect.InsetBy(0, 3);
|
|
fTurnOffNotSupported = new BTextView(rect, "not_supported",
|
|
textRect, be_plain_font, &textColor, B_FOLLOW_ALL, B_WILL_DRAW);
|
|
fTurnOffNotSupported->SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR));
|
|
fTurnOffNotSupported->MakeEditable(false);
|
|
fTurnOffNotSupported->MakeSelectable(false);
|
|
fTurnOffNotSupported->SetText(
|
|
B_TRANSLATE("Display Power Management Signaling not available"));
|
|
|
|
fTurnOffNotSupported->ResizeTo(fTurnOffSlider->Bounds().Width(), height);
|
|
box->AddChild(fTurnOffNotSupported);
|
|
|
|
// Password
|
|
rect.left = 10;
|
|
rect.OffsetBy(0, fTurnOffSlider->Bounds().Height() + 4.0f);
|
|
fPasswordCheckBox = new BCheckBox(rect, "PasswordCheckbox",
|
|
B_TRANSLATE("Password lock"), new BMessage(kMsgPasswordCheckBox));
|
|
fPasswordCheckBox->ResizeToPreferred();
|
|
box->AddChild(fPasswordCheckBox);
|
|
|
|
rect.top += 3;
|
|
rect.left += radioButtonOffset + labelWidth;
|
|
fPasswordSlider = new TimeSlider(rect, "PasswordSlider",
|
|
kMsgPasswordSliderChanged, kMsgPasswordSliderUpdate);
|
|
fPasswordSlider->ResizeTo(fPasswordSlider->Bounds().Width(), height);
|
|
box->AddChild(fPasswordSlider);
|
|
|
|
rect.OffsetBy(0, fTurnOffSlider->Bounds().Height() + 4.0f);
|
|
rect.left = rect.right;
|
|
fPasswordButton = new BButton(rect, "PasswordButton",
|
|
B_TRANSLATE("Password" B_UTF8_ELLIPSIS),
|
|
new BMessage(kMsgChangePassword), B_FOLLOW_TOP | B_FOLLOW_RIGHT);
|
|
fPasswordButton->ResizeToPreferred();
|
|
fPasswordButton->MoveBy(-fPasswordButton->Bounds().Width(), 0);
|
|
box->AddChild(fPasswordButton);
|
|
|
|
// Bottom
|
|
|
|
float monitorHeight = 10 + textHeight * 3;
|
|
float monitorWidth = monitorHeight * 4 / 3;
|
|
rect.left = 11;
|
|
rect.top = box->Bounds().Height() - 15 - monitorHeight;
|
|
rect.right = rect.left + monitorWidth;
|
|
rect.bottom = rect.top + monitorHeight;
|
|
box->AddChild(fFadeNow = new ScreenCornerSelector(rect, "FadeNow",
|
|
new BMessage(kMsgFadeCornerChanged), B_FOLLOW_LEFT | B_FOLLOW_BOTTOM));
|
|
|
|
rect.OffsetBy(monitorWidth + 10, 0);
|
|
stringView = new BStringView(rect, NULL, B_TRANSLATE("Fade now when"),
|
|
B_FOLLOW_LEFT | B_FOLLOW_BOTTOM);
|
|
stringView->ResizeToPreferred();
|
|
float maxWidth = stringView->Bounds().Width();
|
|
box->AddChild(stringView);
|
|
|
|
rect.OffsetBy(0, stringView->Bounds().Height());
|
|
stringView = new BStringView(rect, NULL, B_TRANSLATE("mouse is here"),
|
|
B_FOLLOW_LEFT | B_FOLLOW_BOTTOM);
|
|
stringView->ResizeToPreferred();
|
|
if (maxWidth < stringView->Bounds().Width())
|
|
maxWidth = stringView->Bounds().Width();
|
|
box->AddChild(stringView);
|
|
|
|
rect.left += maxWidth + 20;
|
|
rect.top = box->Bounds().Height() - 15 - monitorHeight;
|
|
rect.right = rect.left + monitorWidth;
|
|
rect.bottom = rect.top + monitorHeight;
|
|
box->AddChild(fFadeNever = new ScreenCornerSelector(rect, "FadeNever",
|
|
new BMessage(kMsgNeverFadeCornerChanged),
|
|
B_FOLLOW_LEFT | B_FOLLOW_BOTTOM));
|
|
|
|
rect.OffsetBy(monitorWidth + 10, 0);
|
|
stringView = new BStringView(rect, NULL,B_TRANSLATE("Don't fade when"),
|
|
B_FOLLOW_LEFT | B_FOLLOW_BOTTOM);
|
|
stringView->ResizeToPreferred();
|
|
if (maxWidth < stringView->Bounds().Width())
|
|
maxWidth = stringView->Bounds().Width();
|
|
box->AddChild(stringView);
|
|
|
|
rect.OffsetBy(0, stringView->Bounds().Height());
|
|
stringView = new BStringView(rect, NULL, B_TRANSLATE("mouse is here"),
|
|
B_FOLLOW_LEFT | B_FOLLOW_BOTTOM);
|
|
stringView->ResizeToPreferred();
|
|
if (maxWidth < stringView->Bounds().Width())
|
|
maxWidth = stringView->Bounds().Width();
|
|
box->AddChild(stringView);
|
|
|
|
float size = rect.left + maxWidth + 40;
|
|
if (fMinWidth < size)
|
|
fMinWidth = size;
|
|
size = fPasswordButton->Frame().bottom + box->Frame().top
|
|
+ monitorHeight + 40 + textHeight * 2;
|
|
if (fMinHeight < size)
|
|
fMinHeight = size;
|
|
}
|
|
|
|
|
|
void
|
|
ScreenSaverWindow::_UpdateTurnOffScreen()
|
|
{
|
|
bool enabled = (fSettings.TimeFlags() & ENABLE_DPMS_MASK) != 0;
|
|
|
|
BScreen screen(this);
|
|
uint32 dpmsCapabilities = screen.DPMSCapabilites();
|
|
|
|
fTurnOffScreenFlags = 0;
|
|
if (dpmsCapabilities & B_DPMS_OFF)
|
|
fTurnOffScreenFlags |= ENABLE_DPMS_OFF;
|
|
if (dpmsCapabilities & B_DPMS_STAND_BY)
|
|
fTurnOffScreenFlags |= ENABLE_DPMS_STAND_BY;
|
|
if (dpmsCapabilities & B_DPMS_SUSPEND)
|
|
fTurnOffScreenFlags |= ENABLE_DPMS_SUSPEND;
|
|
|
|
fTurnOffCheckBox->SetValue(enabled && fTurnOffScreenFlags != 0
|
|
? B_CONTROL_ON : B_CONTROL_OFF);
|
|
|
|
enabled = fEnableCheckBox->Value() == B_CONTROL_ON;
|
|
fTurnOffCheckBox->SetEnabled(enabled && fTurnOffScreenFlags != 0);
|
|
if (fTurnOffScreenFlags != 0) {
|
|
fTurnOffNotSupported->Hide();
|
|
fTurnOffSlider->Show();
|
|
} else {
|
|
fTurnOffSlider->Hide();
|
|
fTurnOffNotSupported->Show();
|
|
}
|
|
}
|
|
|
|
|
|
void
|
|
ScreenSaverWindow::_UpdateStatus()
|
|
{
|
|
DisableUpdates();
|
|
|
|
bool enabled = fEnableCheckBox->Value() == B_CONTROL_ON;
|
|
fPasswordCheckBox->SetEnabled(enabled);
|
|
fTurnOffCheckBox->SetEnabled(enabled && fTurnOffScreenFlags != 0);
|
|
fRunSlider->SetEnabled(enabled);
|
|
fTurnOffSlider->SetEnabled(enabled && fTurnOffCheckBox->Value());
|
|
fPasswordSlider->SetEnabled(enabled && fPasswordCheckBox->Value());
|
|
fPasswordButton->SetEnabled(enabled && fPasswordCheckBox->Value());
|
|
|
|
EnableUpdates();
|
|
|
|
// Update the saved preferences
|
|
fSettings.SetWindowFrame(Frame());
|
|
fSettings.SetWindowTab(fTabView->Selection());
|
|
fSettings.SetTimeFlags((enabled ? ENABLE_SAVER : 0)
|
|
| (fTurnOffCheckBox->Value() ? fTurnOffScreenFlags : 0));
|
|
fSettings.SetBlankTime(fRunSlider->Time());
|
|
bigtime_t offTime = fTurnOffSlider->Time() - fSettings.BlankTime();
|
|
fSettings.SetOffTime(offTime);
|
|
fSettings.SetSuspendTime(offTime);
|
|
fSettings.SetStandByTime(offTime);
|
|
fSettings.SetBlankCorner(fFadeNow->Corner());
|
|
fSettings.SetNeverBlankCorner(fFadeNever->Corner());
|
|
fSettings.SetLockEnable(fPasswordCheckBox->Value());
|
|
fSettings.SetPasswordTime(fPasswordSlider->Time());
|
|
|
|
// TODO - Tell the password window to update its stuff
|
|
}
|
|
|
|
|
|
void
|
|
ScreenSaverWindow::SetMinimalSizeLimit(float width, float height)
|
|
{
|
|
if (width < fMinWidth)
|
|
width = fMinWidth;
|
|
if (height < fMinHeight)
|
|
height = fMinHeight;
|
|
|
|
SetSizeLimits(width, 32767, height, 32767);
|
|
}
|
|
|
|
|
|
void
|
|
ScreenSaverWindow::MessageReceived(BMessage *msg)
|
|
{
|
|
// "Settings" tab, slider updates
|
|
|
|
switch (msg->what) {
|
|
case kMsgRunSliderChanged:
|
|
case kMsgRunSliderUpdate:
|
|
if (fRunSlider->Value() > fTurnOffSlider->Value())
|
|
fTurnOffSlider->SetValue(fRunSlider->Value());
|
|
|
|
if (fRunSlider->Value() > fPasswordSlider->Value())
|
|
fPasswordSlider->SetValue(fRunSlider->Value());
|
|
break;
|
|
|
|
case kMsgTurnOffSliderChanged:
|
|
case kMsgTurnOffSliderUpdate:
|
|
if (fRunSlider->Value() > fTurnOffSlider->Value())
|
|
fRunSlider->SetValue(fTurnOffSlider->Value());
|
|
break;
|
|
|
|
case kMsgPasswordSliderChanged:
|
|
case kMsgPasswordSliderUpdate:
|
|
if (fPasswordSlider->Value() < fRunSlider->Value())
|
|
fRunSlider->SetValue(fPasswordSlider->Value());
|
|
break;
|
|
}
|
|
|
|
switch (msg->what) {
|
|
// "General" tab
|
|
|
|
case kMsgTurnOffCheckBox:
|
|
fTurnOffSlider->SetEnabled(
|
|
fTurnOffCheckBox->Value() == B_CONTROL_ON);
|
|
break;
|
|
|
|
case kMsgRunSliderChanged:
|
|
case kMsgTurnOffSliderChanged:
|
|
case kMsgPasswordSliderChanged:
|
|
case kMsgPasswordCheckBox:
|
|
case kMsgEnableScreenSaverBox:
|
|
case kMsgFadeCornerChanged:
|
|
case kMsgNeverFadeCornerChanged:
|
|
_UpdateStatus();
|
|
fSettings.Save();
|
|
break;
|
|
|
|
case kMsgChangePassword:
|
|
fPasswordWindow->Show();
|
|
break;
|
|
|
|
// "Screensavers" tab
|
|
|
|
case kMsgUpdateList:
|
|
fModulesView->PopulateScreenSaverList();
|
|
break;
|
|
|
|
default:
|
|
BWindow::MessageReceived(msg);
|
|
break;
|
|
}
|
|
}
|
|
|
|
|
|
void
|
|
ScreenSaverWindow::ScreenChanged(BRect frame, color_space colorSpace)
|
|
{
|
|
_UpdateTurnOffScreen();
|
|
}
|
|
|
|
|
|
bool
|
|
ScreenSaverWindow::QuitRequested()
|
|
{
|
|
be_app->PostMessage(B_QUIT_REQUESTED);
|
|
return true;
|
|
}
|
|
|