2 * Copyright 2003-2014 Haiku, Inc. All rights reserved.
3 * Distributed under the terms of the MIT License.
6 * Axel Dörfler, axeld@pinc-software.de
7 * Jérôme Duval, jerome.duval@free.fr
9 * John Scipione, jscipione@gmail.com
10 * Puck Meerburg, puck@puckipedia.nl
14 #include "ScreenSaverWindow.h"
19 #include <Alignment.h>
20 #include <Application.h>
25 #include <ControlLook.h>
26 #include <Directory.h>
27 #include <DurationFormat.h>
30 #include <FindDirectory.h>
33 #include <LayoutBuilder.h>
40 #include <ScreenSaver.h>
41 #include <ScreenSaverRunner.h>
42 #include <ScrollView.h>
45 #include <StringView.h>
50 // for std::max and std::min
52 #include <BuildScreenSaverDefaultSettingsView.h>
54 #include "PreviewView.h"
55 #include "ScreenCornerSelector.h"
56 #include "ScreenSaverItem.h"
57 #include "ScreenSaverShared.h"
59 #undef B_TRANSLATION_CONTEXT
60 #define B_TRANSLATION_CONTEXT "ScreenSaver"
63 const uint32 kPreviewMonitorGap
= 16;
64 const uint32 kMinSettingsWidth
= 230;
65 const uint32 kMinSettingsHeight
= 120;
67 const int32 kMsgSaverSelected
= 'SSEL';
68 const int32 kMsgPasswordCheckBox
= 'PWCB';
69 const int32 kMsgRunSliderChanged
= 'RSch';
70 const int32 kMsgRunSliderUpdate
= 'RSup';
71 const int32 kMsgPasswordSliderChanged
= 'PWch';
72 const int32 kMsgPasswordSliderUpdate
= 'PWup';
73 const int32 kMsgChangePassword
= 'PWBT';
74 const int32 kMsgEnableScreenSaverBox
= 'ESCH';
76 const int32 kMsgTurnOffCheckBox
= 'TUOF';
77 const int32 kMsgTurnOffSliderChanged
= 'TUch';
78 const int32 kMsgTurnOffSliderUpdate
= 'TUup';
80 const int32 kMsgFadeCornerChanged
= 'fdcc';
81 const int32 kMsgNeverFadeCornerChanged
= 'nfcc';
84 class TimeSlider
: public BSlider
{
86 TimeSlider(const char* name
,
87 uint32 changedMessage
,
88 uint32 updateMessage
);
89 virtual ~TimeSlider();
91 virtual void SetValue(int32 value
);
93 void SetTime(bigtime_t useconds
);
94 bigtime_t
Time() const;
97 void _TimeToString(bigtime_t useconds
,
102 class TabView
: public BTabView
{
106 virtual void MouseDown(BPoint where
);
110 class FadeView
: public BView
{
112 FadeView(const char* name
,
113 ScreenSaverSettings
& settings
);
115 virtual void AttachedToWindow();
116 virtual void MessageReceived(BMessage
* message
);
118 void UpdateTurnOffScreen();
122 ScreenSaverSettings
& fSettings
;
123 uint32 fTurnOffScreenFlags
;
125 BCheckBox
* fEnableCheckBox
;
126 TimeSlider
* fRunSlider
;
128 BTextView
* fTurnOffNotSupported
;
129 BCheckBox
* fTurnOffCheckBox
;
130 TimeSlider
* fTurnOffSlider
;
132 BCheckBox
* fPasswordCheckBox
;
133 TimeSlider
* fPasswordSlider
;
134 BButton
* fPasswordButton
;
136 ScreenCornerSelector
* fFadeNow
;
137 ScreenCornerSelector
* fFadeNever
;
141 class ModulesView
: public BView
{
143 ModulesView(const char* name
,
144 ScreenSaverSettings
& settings
);
145 virtual ~ModulesView();
147 virtual void DetachedFromWindow();
148 virtual void AttachedToWindow();
149 virtual void AllAttached();
150 virtual void MessageReceived(BMessage
* message
);
152 void EmptyScreenSaverList();
153 void PopulateScreenSaverList();
157 BScreenSaver
* ScreenSaver();
160 friend class TabView
;
162 static int _CompareScreenSaverItems(const void* left
,
169 ScreenSaverSettings
& fSettings
;
171 BListView
* fScreenSaversListView
;
172 BButton
* fTestButton
;
174 ScreenSaverRunner
* fSaverRunner
;
175 BString fCurrentName
;
178 BView
* fSettingsView
;
180 PreviewView
* fPreviewView
;
182 team_id fScreenSaverTestTeam
;
186 // #pragma mark - TimeSlider
189 static const int32 kTimeInUnits
[] = {
201 static const int32 kTimeUnitCount
202 = sizeof(kTimeInUnits
) / sizeof(kTimeInUnits
[0]);
205 TimeSlider::TimeSlider(const char* name
, uint32 changedMessage
,
206 uint32 updateMessage
)
208 BSlider(name
, B_TRANSLATE("30 seconds"), new BMessage(changedMessage
),
209 0, kTimeUnitCount
- 1, B_HORIZONTAL
, B_TRIANGLE_THUMB
)
211 SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR
));
212 SetModificationMessage(new BMessage(updateMessage
));
217 TimeSlider::~TimeSlider()
223 TimeSlider::SetValue(int32 value
)
225 int32 oldValue
= Value();
226 BSlider::SetValue(value
);
228 if (oldValue
!= Value()) {
230 _TimeToString(kTimeInUnits
[Value()] * 1000000LL, label
);
231 SetLabel(label
.String());
237 TimeSlider::SetTime(bigtime_t useconds
)
239 for (int t
= 0; t
< kTimeUnitCount
; t
++) {
240 if (kTimeInUnits
[t
] * 1000000LL == useconds
) {
249 TimeSlider::Time() const
251 return 1000000LL * kTimeInUnits
[Value()];
256 TimeSlider::_TimeToString(bigtime_t useconds
, BString
& string
)
258 BDurationFormat formatter
;
259 formatter
.Format(string
, 0, useconds
);
263 // #pragma mark - FadeView
266 FadeView::FadeView(const char* name
, ScreenSaverSettings
& settings
)
268 BView(name
, B_WILL_DRAW
),
271 SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR
));
273 font_height fontHeight
;
274 be_plain_font
->GetHeight(&fontHeight
);
275 float textHeight
= ceilf(fontHeight
.ascent
+ fontHeight
.descent
);
277 fEnableCheckBox
= new BCheckBox("EnableCheckBox",
278 B_TRANSLATE("Enable screensaver"),
279 new BMessage(kMsgEnableScreenSaverBox
));
281 BBox
* box
= new BBox("EnableScreenSaverBox");
282 box
->SetLabel(fEnableCheckBox
);
285 BStringView
* startScreenSaver
= new BStringView("startScreenSaver",
286 B_TRANSLATE("Start screensaver"));
287 startScreenSaver
->SetAlignment(B_ALIGN_RIGHT
);
289 fRunSlider
= new TimeSlider("RunSlider", kMsgRunSliderChanged
,
290 kMsgRunSliderUpdate
);
293 rgb_color textColor
= tint_color(ui_color(B_PANEL_BACKGROUND_COLOR
),
294 B_DISABLED_LABEL_TINT
);
295 fTurnOffNotSupported
= new BTextView("not_supported", be_plain_font
,
296 &textColor
, B_WILL_DRAW
);
297 fTurnOffNotSupported
->SetExplicitMinSize(BSize(B_SIZE_UNSET
,
298 3 + textHeight
* 3));
299 fTurnOffNotSupported
->SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR
));
300 fTurnOffNotSupported
->MakeEditable(false);
301 fTurnOffNotSupported
->MakeSelectable(false);
302 fTurnOffNotSupported
->SetText(
303 B_TRANSLATE("Display Power Management Signaling not available"));
305 fTurnOffCheckBox
= new BCheckBox("TurnOffScreenCheckBox",
306 B_TRANSLATE("Turn off screen"), new BMessage(kMsgTurnOffCheckBox
));
307 fTurnOffCheckBox
->SetExplicitAlignment(BAlignment(B_ALIGN_LEFT
,
308 B_ALIGN_VERTICAL_CENTER
));
310 fTurnOffSlider
= new TimeSlider("TurnOffSlider", kMsgTurnOffSliderChanged
,
311 kMsgTurnOffSliderUpdate
);
314 fPasswordCheckBox
= new BCheckBox("PasswordCheckbox",
315 B_TRANSLATE("Password lock"), new BMessage(kMsgPasswordCheckBox
));
316 fPasswordCheckBox
->SetExplicitAlignment(BAlignment(B_ALIGN_LEFT
,
317 B_ALIGN_VERTICAL_CENTER
));
319 fPasswordSlider
= new TimeSlider("PasswordSlider",
320 kMsgPasswordSliderChanged
, kMsgPasswordSliderUpdate
);
322 fPasswordButton
= new BButton("PasswordButton",
323 B_TRANSLATE("Password" B_UTF8_ELLIPSIS
),
324 new BMessage(kMsgChangePassword
));
327 float monitorHeight
= 10 + textHeight
* 3;
328 float aspectRatio
= 4.0f
/ 3.0f
;
329 float monitorWidth
= monitorHeight
* aspectRatio
;
330 BRect monitorRect
= BRect(0, 0, monitorWidth
, monitorHeight
);
332 fFadeNow
= new ScreenCornerSelector(monitorRect
, "FadeNow",
333 new BMessage(kMsgFadeCornerChanged
), B_FOLLOW_NONE
);
334 BTextView
* fadeNowText
= new BTextView("FadeNowText", B_WILL_DRAW
);
335 fadeNowText
->SetExplicitMinSize(BSize(B_SIZE_UNSET
,
336 4 + textHeight
* 4));
337 fadeNowText
->SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR
));
338 fadeNowText
->MakeEditable(false);
339 fadeNowText
->MakeSelectable(false);
340 fadeNowText
->SetText(B_TRANSLATE("Fade now when mouse is here"));
342 fFadeNever
= new ScreenCornerSelector(monitorRect
, "FadeNever",
343 new BMessage(kMsgNeverFadeCornerChanged
), B_FOLLOW_NONE
);
344 BTextView
* fadeNeverText
= new BTextView("FadeNeverText", B_WILL_DRAW
);
345 fadeNeverText
->SetExplicitMinSize(BSize(B_SIZE_UNSET
,
346 4 + textHeight
* 4));
347 fadeNeverText
->SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR
));
348 fadeNeverText
->MakeEditable(false);
349 fadeNeverText
->MakeSelectable(false);
350 fadeNeverText
->SetText(B_TRANSLATE("Don't fade when mouse is here"));
352 box
->AddChild(BLayoutBuilder::Group
<>(B_VERTICAL
)
353 .SetInsets(B_USE_DEFAULT_SPACING
, 0, B_USE_DEFAULT_SPACING
,
354 B_USE_DEFAULT_SPACING
)
355 .AddGrid(B_USE_DEFAULT_SPACING
, B_USE_SMALL_SPACING
)
356 .Add(startScreenSaver
, 0, 0)
357 .Add(fRunSlider
, 1, 0)
358 .Add(fTurnOffCheckBox
, 0, 1)
359 .Add(BLayoutBuilder::Group
<>(B_VERTICAL
)
360 .Add(fTurnOffNotSupported
)
363 .Add(fPasswordCheckBox
, 0, 2)
364 .Add(fPasswordSlider
, 1, 2)
366 .AddGroup(B_HORIZONTAL
)
368 .Add(fPasswordButton
)
371 .AddGroup(B_HORIZONTAL
)
373 .AddGroup(B_VERTICAL
, 0)
378 .AddGroup(B_VERTICAL
, 0)
386 BLayoutBuilder::Group
<>(this, B_HORIZONTAL
)
387 .SetInsets(B_USE_SMALL_SPACING
)
394 FadeView::AttachedToWindow()
396 fEnableCheckBox
->SetTarget(this);
397 fRunSlider
->SetTarget(this);
398 fTurnOffCheckBox
->SetTarget(this);
399 fTurnOffSlider
->SetTarget(this);
400 fFadeNow
->SetTarget(this);
401 fFadeNever
->SetTarget(this);
402 fPasswordCheckBox
->SetTarget(this);
403 fPasswordSlider
->SetTarget(this);
405 fEnableCheckBox
->SetValue(
406 fSettings
.TimeFlags() & ENABLE_SAVER
? B_CONTROL_ON
: B_CONTROL_OFF
);
407 fRunSlider
->SetTime(fSettings
.BlankTime());
408 fTurnOffSlider
->SetTime(fSettings
.OffTime() + fSettings
.BlankTime());
409 fFadeNow
->SetCorner(fSettings
.BlankCorner());
410 fFadeNever
->SetCorner(fSettings
.NeverBlankCorner());
411 fPasswordCheckBox
->SetValue(fSettings
.LockEnable());
412 fPasswordSlider
->SetTime(fSettings
.PasswordTime());
414 UpdateTurnOffScreen();
420 FadeView::MessageReceived(BMessage
*message
)
422 switch (message
->what
) {
423 case kMsgRunSliderChanged
:
424 case kMsgRunSliderUpdate
:
425 if (fRunSlider
->Value() > fTurnOffSlider
->Value())
426 fTurnOffSlider
->SetValue(fRunSlider
->Value());
428 if (fRunSlider
->Value() > fPasswordSlider
->Value())
429 fPasswordSlider
->SetValue(fRunSlider
->Value());
432 case kMsgTurnOffSliderChanged
:
433 case kMsgTurnOffSliderUpdate
:
434 if (fRunSlider
->Value() > fTurnOffSlider
->Value())
435 fRunSlider
->SetValue(fTurnOffSlider
->Value());
438 case kMsgPasswordSliderChanged
:
439 case kMsgPasswordSliderUpdate
:
440 if (fPasswordSlider
->Value() < fRunSlider
->Value())
441 fRunSlider
->SetValue(fPasswordSlider
->Value());
444 case kMsgTurnOffCheckBox
:
445 fTurnOffSlider
->SetEnabled(
446 fTurnOffCheckBox
->Value() == B_CONTROL_ON
);
450 switch (message
->what
) {
451 case kMsgRunSliderChanged
:
452 case kMsgTurnOffSliderChanged
:
453 case kMsgPasswordSliderChanged
:
454 case kMsgPasswordCheckBox
:
455 case kMsgEnableScreenSaverBox
:
456 case kMsgFadeCornerChanged
:
457 case kMsgNeverFadeCornerChanged
:
463 BView::MessageReceived(message
);
469 FadeView::UpdateTurnOffScreen()
471 bool enabled
= (fSettings
.TimeFlags() & ENABLE_DPMS_MASK
) != 0;
473 BScreen
screen(Window());
474 uint32 dpmsCapabilities
= screen
.DPMSCapabilites();
476 fTurnOffScreenFlags
= 0;
477 if (dpmsCapabilities
& B_DPMS_OFF
)
478 fTurnOffScreenFlags
|= ENABLE_DPMS_OFF
;
479 if (dpmsCapabilities
& B_DPMS_STAND_BY
)
480 fTurnOffScreenFlags
|= ENABLE_DPMS_STAND_BY
;
481 if (dpmsCapabilities
& B_DPMS_SUSPEND
)
482 fTurnOffScreenFlags
|= ENABLE_DPMS_SUSPEND
;
484 fTurnOffCheckBox
->SetValue(enabled
&& fTurnOffScreenFlags
!= 0
485 ? B_CONTROL_ON
: B_CONTROL_OFF
);
487 enabled
= fEnableCheckBox
->Value() == B_CONTROL_ON
;
488 fTurnOffCheckBox
->SetEnabled(enabled
&& fTurnOffScreenFlags
!= 0);
489 if (fTurnOffScreenFlags
!= 0) {
490 fTurnOffNotSupported
->Hide();
491 fTurnOffSlider
->Show();
493 fTurnOffSlider
->Hide();
494 fTurnOffNotSupported
->Show();
500 FadeView::UpdateStatus()
502 Window()->DisableUpdates();
504 bool enabled
= fEnableCheckBox
->Value() == B_CONTROL_ON
;
505 fPasswordCheckBox
->SetEnabled(enabled
);
506 fTurnOffCheckBox
->SetEnabled(enabled
&& fTurnOffScreenFlags
!= 0);
507 fRunSlider
->SetEnabled(enabled
);
508 fTurnOffSlider
->SetEnabled(enabled
&& fTurnOffCheckBox
->Value());
509 fPasswordSlider
->SetEnabled(enabled
&& fPasswordCheckBox
->Value());
510 fPasswordButton
->SetEnabled(enabled
&& fPasswordCheckBox
->Value());
512 Window()->EnableUpdates();
514 // Update the saved preferences
515 fSettings
.SetWindowFrame(Frame());
516 fSettings
.SetTimeFlags((enabled
? ENABLE_SAVER
: 0)
517 | (fTurnOffCheckBox
->Value() ? fTurnOffScreenFlags
: 0));
518 fSettings
.SetBlankTime(fRunSlider
->Time());
519 bigtime_t offTime
= fTurnOffSlider
->Time() - fSettings
.BlankTime();
520 fSettings
.SetOffTime(offTime
);
521 fSettings
.SetSuspendTime(offTime
);
522 fSettings
.SetStandByTime(offTime
);
523 fSettings
.SetBlankCorner(fFadeNow
->Corner());
524 fSettings
.SetNeverBlankCorner(fFadeNever
->Corner());
525 fSettings
.SetLockEnable(fPasswordCheckBox
->Value());
526 fSettings
.SetPasswordTime(fPasswordSlider
->Time());
528 // TODO - Tell the password window to update its stuff
532 // #pragma mark - ModulesView
535 ModulesView::ModulesView(const char* name
, ScreenSaverSettings
& settings
)
537 BView(name
, B_WILL_DRAW
),
539 fScreenSaversListView(new BListView("SaversListView")),
540 fTestButton(new BButton("TestButton", B_TRANSLATE("Test"),
541 new BMessage(kMsgTestSaver
))),
543 fSettingsBox(new BBox("SettingsBox")),
545 fPreviewView(new PreviewView("preview")),
546 fScreenSaverTestTeam(-1)
548 SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR
));
550 fScreenSaversListView
->SetSelectionMessage(
551 new BMessage(kMsgSaverSelected
));
552 BScrollView
* saversListScrollView
= new BScrollView("scroll_list",
553 fScreenSaversListView
, 0, false, true);
555 fSettingsBox
->SetLabel(B_TRANSLATE("Screensaver settings"));
557 BLayoutBuilder::Group
<>(this, B_HORIZONTAL
)
558 .SetInsets(B_USE_DEFAULT_SPACING
)
559 .AddGroup(B_VERTICAL
)
561 .Add(saversListScrollView
)
562 .AddGroup(B_HORIZONTAL
)
572 ModulesView::~ModulesView()
581 ModulesView::DetachedFromWindow()
584 EmptyScreenSaverList();
591 ModulesView::AttachedToWindow()
593 fScreenSaversListView
->SetTarget(this);
594 fTestButton
->SetTarget(this);
599 ModulesView::AllAttached()
601 PopulateScreenSaverList();
602 fScreenSaversListView
->Invoke();
607 ModulesView::MessageReceived(BMessage
* message
)
609 switch (message
->what
) {
610 case kMsgSaverSelected
:
612 int32 selection
= fScreenSaversListView
->CurrentSelection();
616 ScreenSaverItem
* item
617 = (ScreenSaverItem
*)fScreenSaversListView
->ItemAt(selection
);
621 if (strcmp(item
->Text(), B_TRANSLATE("Blackness")) == 0)
622 fSettings
.SetModuleName("");
624 fSettings
.SetModuleName(item
->Text());
640 be_roster
->StartWatching(BMessenger(this, Looper()),
642 BMessage
message(kMsgTestSaver
);
643 if (be_roster
->Launch(SCREEN_BLANKER_SIG
, &message
,
644 &fScreenSaverTestTeam
) == B_OK
) {
648 // Try really hard to launch it. It's very likely that this fails
649 // when we run from the CD, and there is only an incomplete mime
650 // database for example...
652 if (find_directory(B_SYSTEM_BIN_DIRECTORY
, &path
) != B_OK
653 || path
.Append("screen_blanker") != B_OK
) {
654 path
.SetTo("/bin/screen_blanker");
657 BEntry
entry(path
.Path());
659 if (entry
.GetRef(&ref
) == B_OK
) {
660 be_roster
->Launch(&ref
, &message
,
661 &fScreenSaverTestTeam
);
666 case B_SOME_APP_QUIT
:
669 if (message
->FindInt32("be:team", &team
) == B_OK
670 && team
== fScreenSaverTestTeam
) {
671 be_roster
->StopWatching(this);
678 BView::MessageReceived(message
);
684 ModulesView::SaveState()
686 BScreenSaver
* saver
= ScreenSaver();
691 if (saver
->SaveState(&state
) == B_OK
)
692 fSettings
.SetModuleState(fCurrentName
.String(), &state
);
697 ModulesView::EmptyScreenSaverList()
699 fScreenSaversListView
->DeselectAll();
700 while (BListItem
* item
= fScreenSaversListView
->RemoveItem((int32
)0))
706 ModulesView::PopulateScreenSaverList()
708 // Blackness is a built-in screen saver
709 ScreenSaverItem
* defaultItem
710 = new ScreenSaverItem(B_TRANSLATE("Blackness"), "");
711 fScreenSaversListView
->AddItem(defaultItem
);
713 // Iterate over add-on directories, and add their files to the list view
715 directory_which which
[] = {
716 B_USER_NONPACKAGED_ADDONS_DIRECTORY
,
717 B_USER_ADDONS_DIRECTORY
,
718 B_SYSTEM_NONPACKAGED_ADDONS_DIRECTORY
,
719 B_SYSTEM_ADDONS_DIRECTORY
,
721 ScreenSaverItem
* selectedItem
= NULL
;
723 for (uint32 i
= 0; i
< sizeof(which
) / sizeof(which
[0]); i
++) {
725 if (find_directory(which
[i
], &basePath
) != B_OK
)
727 else if (basePath
.Append("Screen Savers", true) != B_OK
)
730 BDirectory
dir(basePath
.Path());
732 while (dir
.GetNextEntry(&entry
, true) == B_OK
) {
733 char name
[B_FILE_NAME_LENGTH
];
734 if (entry
.GetName(name
) != B_OK
)
737 BPath
path(basePath
);
738 if (path
.Append(name
) != B_OK
)
741 ScreenSaverItem
* item
= new ScreenSaverItem(name
, path
.Path());
742 fScreenSaversListView
->AddItem(item
);
744 if (selectedItem
!= NULL
)
747 if (strcmp(fSettings
.ModuleName(), item
->Text()) == 0)
752 fScreenSaversListView
->SortItems(_CompareScreenSaverItems
);
753 if (selectedItem
== NULL
)
754 selectedItem
= defaultItem
;
756 fScreenSaversListView
->Select(fScreenSaversListView
->IndexOf(selectedItem
));
757 fScreenSaversListView
->ScrollToSelection();
761 //! Sorting function for ScreenSaverItems
763 ModulesView::_CompareScreenSaverItems(const void* left
, const void* right
)
765 ScreenSaverItem
* leftItem
= *(ScreenSaverItem
**)left
;
766 ScreenSaverItem
* rightItem
= *(ScreenSaverItem
**)right
;
768 return strcasecmp(leftItem
->Text(), rightItem
->Text());
773 ModulesView::ScreenSaver()
775 if (fSaverRunner
!= NULL
)
776 return fSaverRunner
->ScreenSaver();
783 ModulesView::_CloseSaver()
785 // remove old screen saver preview & config
787 BScreenSaver
* saver
= ScreenSaver();
788 BView
* view
= fPreviewView
->RemovePreview();
789 if (fSettingsView
!= NULL
)
790 fSettingsBox
->RemoveChild(fSettingsView
);
792 if (fSaverRunner
!= NULL
)
793 fSaverRunner
->Quit();
799 delete fSettingsView
;
801 // the saver runner also unloads the add-on, so it must
804 fSettingsView
= NULL
;
810 ModulesView::_OpenSaver()
812 // create new screen saver preview & config
814 BView
* view
= fPreviewView
->AddPreview();
815 fCurrentName
= fSettings
.ModuleName();
816 fSaverRunner
= new ScreenSaverRunner(view
->Window(), view
, fSettings
);
819 BRect rect
= fSettingsBox
->InnerFrame().InsetByCopy(4, 4);
821 BRect rect
= fSettingsBox
->Bounds().InsetByCopy(4, 4);
824 fSettingsView
= new BView(rect
, "SettingsView", B_FOLLOW_ALL
, B_WILL_DRAW
);
826 fSettingsView
->SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR
));
827 fSettingsBox
->AddChild(fSettingsView
);
829 BScreenSaver
* saver
= ScreenSaver();
830 if (saver
!= NULL
&& fSettingsView
!= NULL
) {
831 saver
->StartConfig(fSettingsView
);
832 if (saver
->StartSaver(view
, true) == B_OK
) {
833 fPreviewView
->HideNoPreview();
836 fPreviewView
->ShowNoPreview();
838 // Failed to load OR this is the "Darkness" screensaver. Show a black
839 // preview (this is what will happen in both cases when screen_blanker
841 fPreviewView
->HideNoPreview();
844 if (fSettingsView
->ChildAt(0) == NULL
) {
845 // There are no settings at all, we add the module name here to
846 // let it look a bit better at least.
847 BPrivate::BuildScreenSaverDefaultSettingsView(fSettingsView
,
848 fSettings
.ModuleName()[0] ? fSettings
.ModuleName()
849 : B_TRANSLATE("Blackness"),
850 saver
!= NULL
|| !fSettings
.ModuleName()[0]
851 ? B_TRANSLATE("No options available")
852 : B_TRANSLATE("Could not load screen saver"));
857 // #pragma mark - TabView
862 BTabView("tab_view", B_WIDTH_FROM_LABEL
)
868 TabView::MouseDown(BPoint where
)
870 BTab
* fadeTab
= TabAt(0);
871 BRect
fadeTabFrame(TabFrame(0));
872 BTab
* modulesTab
= TabAt(1);
873 BRect
modulesTabFrame(TabFrame(1));
874 ModulesView
* modulesView
= dynamic_cast<ModulesView
*>(modulesTab
->View());
876 if (fadeTab
!= NULL
&& Selection() != 0 && fadeTabFrame
.Contains(where
)
877 && modulesView
!= NULL
) {
878 // clicked on the fade tab
879 modulesView
->SaveState();
880 modulesView
->_CloseSaver();
881 } else if (modulesTab
!= NULL
&& Selection() != 1
882 && modulesTabFrame
.Contains(where
) && modulesView
!= NULL
) {
883 // clicked on the modules tab
884 BMessage
message(kMsgSaverSelected
);
885 modulesView
->MessageReceived(&message
);
888 BTabView::MouseDown(where
);
892 // #pragma mark - ScreenSaverWindow
895 ScreenSaverWindow::ScreenSaverWindow()
897 BWindow(BRect(50, 50, 496, 375),
898 B_TRANSLATE_SYSTEM_NAME("ScreenSaver"), B_TITLED_WINDOW
,
899 B_ASYNCHRONOUS_CONTROLS
| B_AUTO_UPDATE_SIZE_LIMITS
)
903 fMinWidth
= ceilf(std::max(446.0f
,
904 be_control_look
->DefaultItemSpacing() * 44.6f
));
906 font_height fontHeight
;
907 be_plain_font
->GetHeight(&fontHeight
);
908 float textHeight
= ceilf(fontHeight
.ascent
+ fontHeight
.descent
);
910 fMinHeight
= ceilf(std::max(325.0f
, textHeight
* 28));
912 // Create the password editing window
913 fPasswordWindow
= new PasswordWindow(fSettings
);
914 fPasswordWindow
->Run();
916 // Create the tab view
917 fTabView
= new TabView();
918 fTabView
->SetBorder(B_NO_BORDER
);
920 // Create the controls inside the tabs
921 fFadeView
= new FadeView(B_TRANSLATE("General"), fSettings
);
922 fModulesView
= new ModulesView(B_TRANSLATE("Screensavers"), fSettings
);
924 fTabView
->AddTab(fFadeView
);
925 fTabView
->AddTab(fModulesView
);
927 // Create the topmost background view
928 BView
* topView
= new BView("topView", B_WILL_DRAW
);
929 topView
->SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR
));
930 topView
->SetExplicitAlignment(BAlignment(B_ALIGN_USE_FULL_WIDTH
,
931 B_ALIGN_USE_FULL_HEIGHT
));
932 topView
->SetExplicitMinSize(BSize(fMinWidth
, fMinHeight
));
933 BLayoutBuilder::Group
<>(topView
, B_VERTICAL
)
934 .SetInsets(0, B_USE_SMALL_SPACING
, 0, 0)
938 SetLayout(new BGroupLayout(B_VERTICAL
));
939 GetLayout()->AddView(topView
);
941 fTabView
->Select(fSettings
.WindowTab());
943 if (fSettings
.WindowFrame().left
> 0 && fSettings
.WindowFrame().top
> 0)
944 MoveTo(fSettings
.WindowFrame().left
, fSettings
.WindowFrame().top
);
946 if (fSettings
.WindowFrame().Width() > 0
947 && fSettings
.WindowFrame().Height() > 0) {
948 ResizeTo(fSettings
.WindowFrame().Width(),
949 fSettings
.WindowFrame().Height());
954 ScreenSaverWindow::~ScreenSaverWindow()
957 fFadeView
->UpdateStatus();
958 fSettings
.SetWindowTab(fTabView
->Selection());
960 delete fTabView
->RemoveTab(1);
961 // We delete this here in order to make sure the module view saves its
962 // state while the window is still intact.
969 ScreenSaverWindow::MessageReceived(BMessage
* message
)
971 switch (message
->what
) {
972 case kMsgChangePassword
:
973 fPasswordWindow
->CenterIn(Frame());
974 fPasswordWindow
->Show();
978 fModulesView
->EmptyScreenSaverList();
979 fModulesView
->PopulateScreenSaverList();
983 BWindow::MessageReceived(message
);
989 ScreenSaverWindow::ScreenChanged(BRect frame
, color_space colorSpace
)
991 fFadeView
->UpdateTurnOffScreen();
996 ScreenSaverWindow::QuitRequested()
998 be_app
->PostMessage(B_QUIT_REQUESTED
);