2 * Copyright 2003-2016 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
8 * Puck Meerburg, puck@puckipedia.nl
10 * John Scipione, jscipione@gmail.com
14 #include "ScreenSaverWindow.h"
19 #include <Alignment.h>
20 #include <Application.h>
25 #include <ControlLook.h>
26 #include <DefaultSettingsView.h>
27 #include <Directory.h>
28 #include <DurationFormat.h>
31 #include <FindDirectory.h>
33 #include <GroupLayout.h>
34 #include <LayoutBuilder.h>
41 #include <ScreenSaver.h>
42 #include <ScreenSaverRunner.h>
43 #include <ScrollView.h>
46 #include <StringView.h>
51 // for std::max and std::min
53 #include "PreviewView.h"
54 #include "ScreenCornerSelector.h"
55 #include "ScreenSaverItem.h"
56 #include "ScreenSaverShared.h"
58 #undef B_TRANSLATION_CONTEXT
59 #define B_TRANSLATION_CONTEXT "ScreenSaver"
62 const uint32 kPreviewMonitorGap
= 16;
63 const uint32 kMinSettingsWidth
= 230;
64 const uint32 kMinSettingsHeight
= 120;
66 const int32 kMsgSaverSelected
= 'SSEL';
67 const int32 kMsgPasswordCheckBox
= 'PWCB';
68 const int32 kMsgRunSliderChanged
= 'RSch';
69 const int32 kMsgRunSliderUpdate
= 'RSup';
70 const int32 kMsgPasswordSliderChanged
= 'PWch';
71 const int32 kMsgPasswordSliderUpdate
= 'PWup';
72 const int32 kMsgChangePassword
= 'PWBT';
73 const int32 kMsgEnableScreenSaverBox
= 'ESCH';
75 const int32 kMsgTurnOffCheckBox
= 'TUOF';
76 const int32 kMsgTurnOffSliderChanged
= 'TUch';
77 const int32 kMsgTurnOffSliderUpdate
= 'TUup';
79 const int32 kMsgFadeCornerChanged
= 'fdcc';
80 const int32 kMsgNeverFadeCornerChanged
= 'nfcc';
82 const float kWindowWidth
= 446.0f
;
83 const float kWindowHeight
= 325.0f
;
84 const float kDefaultItemSpacingAt12pt
= 12.0f
* 0.85;
87 class TimeSlider
: public BSlider
{
89 TimeSlider(const char* name
,
90 uint32 changedMessage
,
91 uint32 updateMessage
);
92 virtual ~TimeSlider();
94 virtual void SetValue(int32 value
);
96 void SetTime(bigtime_t useconds
);
97 bigtime_t
Time() const;
100 void _TimeToString(bigtime_t useconds
,
105 class TabView
: public BTabView
{
109 virtual void MouseDown(BPoint where
);
113 class FadeView
: public BView
{
115 FadeView(const char* name
,
116 ScreenSaverSettings
& settings
);
118 virtual void AttachedToWindow();
119 virtual void MessageReceived(BMessage
* message
);
121 void UpdateTurnOffScreen();
125 void _UpdateColors();
126 ScreenSaverSettings
& fSettings
;
127 uint32 fTurnOffScreenFlags
;
129 BCheckBox
* fEnableCheckBox
;
130 TimeSlider
* fRunSlider
;
132 BTextView
* fTurnOffNotSupported
;
133 BCheckBox
* fTurnOffCheckBox
;
134 TimeSlider
* fTurnOffSlider
;
136 BTextView
* fFadeNeverText
;
137 BTextView
* fFadeNowText
;
139 BCheckBox
* fPasswordCheckBox
;
140 TimeSlider
* fPasswordSlider
;
141 BButton
* fPasswordButton
;
143 ScreenCornerSelector
* fFadeNow
;
144 ScreenCornerSelector
* fFadeNever
;
148 class ModulesView
: public BView
{
150 ModulesView(const char* name
,
151 ScreenSaverSettings
& settings
);
152 virtual ~ModulesView();
154 virtual void DetachedFromWindow();
155 virtual void AttachedToWindow();
156 virtual void AllAttached();
157 virtual void MessageReceived(BMessage
* message
);
159 void EmptyScreenSaverList();
160 void PopulateScreenSaverList();
164 BScreenSaver
* ScreenSaver();
167 friend class TabView
;
169 static int _CompareScreenSaverItems(const void* left
,
176 ScreenSaverSettings
& fSettings
;
178 BListView
* fScreenSaversListView
;
179 BButton
* fTestButton
;
181 ScreenSaverRunner
* fSaverRunner
;
182 BString fCurrentName
;
185 BView
* fSettingsView
;
187 PreviewView
* fPreviewView
;
189 team_id fScreenSaverTestTeam
;
193 // #pragma mark - TimeSlider
196 static const int32 kTimeInUnits
[] = {
208 static const int32 kTimeUnitCount
209 = sizeof(kTimeInUnits
) / sizeof(kTimeInUnits
[0]);
212 TimeSlider::TimeSlider(const char* name
, uint32 changedMessage
,
213 uint32 updateMessage
)
215 BSlider(name
, B_TRANSLATE("30 seconds"), new BMessage(changedMessage
),
216 0, kTimeUnitCount
- 1, B_HORIZONTAL
, B_TRIANGLE_THUMB
)
218 SetViewUIColor(B_PANEL_BACKGROUND_COLOR
);
219 SetModificationMessage(new BMessage(updateMessage
));
224 TimeSlider::~TimeSlider()
230 TimeSlider::SetValue(int32 value
)
232 int32 oldValue
= Value();
233 BSlider::SetValue(value
);
235 if (oldValue
!= Value()) {
237 _TimeToString(kTimeInUnits
[Value()] * 1000000LL, label
);
238 SetLabel(label
.String());
244 TimeSlider::SetTime(bigtime_t useconds
)
246 for (int t
= 0; t
< kTimeUnitCount
; t
++) {
247 if (kTimeInUnits
[t
] * 1000000LL == useconds
) {
256 TimeSlider::Time() const
258 return 1000000LL * kTimeInUnits
[Value()];
263 TimeSlider::_TimeToString(bigtime_t useconds
, BString
& string
)
265 BDurationFormat formatter
;
266 formatter
.Format(string
, 0, useconds
);
270 // #pragma mark - FadeView
273 FadeView::FadeView(const char* name
, ScreenSaverSettings
& settings
)
275 BView(name
, B_WILL_DRAW
),
278 SetViewUIColor(B_PANEL_BACKGROUND_COLOR
);
280 font_height fontHeight
;
281 be_plain_font
->GetHeight(&fontHeight
);
282 float textHeight
= ceilf(fontHeight
.ascent
+ fontHeight
.descent
);
284 fEnableCheckBox
= new BCheckBox("EnableCheckBox",
285 B_TRANSLATE("Enable screensaver"),
286 new BMessage(kMsgEnableScreenSaverBox
));
288 BBox
* box
= new BBox("EnableScreenSaverBox");
289 box
->SetLabel(fEnableCheckBox
);
292 BStringView
* startScreenSaver
= new BStringView("startScreenSaver",
293 B_TRANSLATE("Start screensaver"));
294 startScreenSaver
->SetAlignment(B_ALIGN_RIGHT
);
296 fRunSlider
= new TimeSlider("RunSlider", kMsgRunSliderChanged
,
297 kMsgRunSliderUpdate
);
300 rgb_color textColor
= disable_color(ui_color(B_PANEL_TEXT_COLOR
),
303 fTurnOffNotSupported
= new BTextView("not_supported", be_plain_font
,
304 &textColor
, B_WILL_DRAW
);
305 fTurnOffNotSupported
->SetExplicitMinSize(BSize(B_SIZE_UNSET
,
306 3 + textHeight
* 3));
307 fTurnOffNotSupported
->SetViewUIColor(B_PANEL_BACKGROUND_COLOR
);
308 fTurnOffNotSupported
->MakeEditable(false);
309 fTurnOffNotSupported
->MakeSelectable(false);
310 fTurnOffNotSupported
->SetText(
311 B_TRANSLATE("Display Power Management Signaling not available"));
313 fTurnOffCheckBox
= new BCheckBox("TurnOffScreenCheckBox",
314 B_TRANSLATE("Turn off screen"), new BMessage(kMsgTurnOffCheckBox
));
315 fTurnOffCheckBox
->SetExplicitAlignment(BAlignment(B_ALIGN_LEFT
,
316 B_ALIGN_VERTICAL_CENTER
));
318 fTurnOffSlider
= new TimeSlider("TurnOffSlider", kMsgTurnOffSliderChanged
,
319 kMsgTurnOffSliderUpdate
);
322 fPasswordCheckBox
= new BCheckBox("PasswordCheckbox",
323 B_TRANSLATE("Password lock"), new BMessage(kMsgPasswordCheckBox
));
324 fPasswordCheckBox
->SetExplicitAlignment(BAlignment(B_ALIGN_LEFT
,
325 B_ALIGN_VERTICAL_CENTER
));
327 fPasswordSlider
= new TimeSlider("PasswordSlider",
328 kMsgPasswordSliderChanged
, kMsgPasswordSliderUpdate
);
330 fPasswordButton
= new BButton("PasswordButton",
331 B_TRANSLATE("Password" B_UTF8_ELLIPSIS
),
332 new BMessage(kMsgChangePassword
));
335 float monitorHeight
= 10 + textHeight
* 3;
336 float aspectRatio
= 4.0f
/ 3.0f
;
337 float monitorWidth
= monitorHeight
* aspectRatio
;
338 BRect monitorRect
= BRect(0, 0, monitorWidth
, monitorHeight
);
340 fFadeNow
= new ScreenCornerSelector(monitorRect
, "FadeNow",
341 new BMessage(kMsgFadeCornerChanged
), B_FOLLOW_NONE
);
342 fFadeNowText
= new BTextView("FadeNowText", B_WILL_DRAW
);
343 fFadeNowText
->SetExplicitMinSize(BSize(B_SIZE_UNSET
,
344 4 + textHeight
* 4));
345 fFadeNowText
->SetViewUIColor(B_PANEL_BACKGROUND_COLOR
);
346 fFadeNowText
->MakeEditable(false);
347 fFadeNowText
->MakeSelectable(false);
348 fFadeNowText
->SetText(B_TRANSLATE("Fade now when mouse is here"));
350 fFadeNever
= new ScreenCornerSelector(monitorRect
, "FadeNever",
351 new BMessage(kMsgNeverFadeCornerChanged
), B_FOLLOW_NONE
);
352 fFadeNeverText
= new BTextView("FadeNeverText", B_WILL_DRAW
);
353 fFadeNeverText
->SetExplicitMinSize(BSize(B_SIZE_UNSET
,
354 4 + textHeight
* 4));
355 fFadeNeverText
->SetViewUIColor(B_PANEL_BACKGROUND_COLOR
);
356 fFadeNeverText
->MakeEditable(false);
357 fFadeNeverText
->MakeSelectable(false);
358 fFadeNeverText
->SetText(B_TRANSLATE("Don't fade when mouse is here"));
360 box
->AddChild(BLayoutBuilder::Group
<>(B_VERTICAL
, 0)
361 .SetInsets(B_USE_DEFAULT_SPACING
, 0, B_USE_DEFAULT_SPACING
,
362 B_USE_DEFAULT_SPACING
)
363 .AddGrid(B_USE_DEFAULT_SPACING
, B_USE_SMALL_SPACING
)
364 .Add(startScreenSaver
, 0, 0)
365 .Add(fRunSlider
, 1, 0)
366 .Add(fTurnOffCheckBox
, 0, 1)
367 .Add(BLayoutBuilder::Group
<>(B_VERTICAL
)
368 .Add(fTurnOffNotSupported
)
371 .Add(fPasswordCheckBox
, 0, 2)
372 .Add(fPasswordSlider
, 1, 2)
374 .AddGroup(B_HORIZONTAL
)
376 .Add(fPasswordButton
)
379 .AddGroup(B_HORIZONTAL
)
381 .AddGroup(B_VERTICAL
, 0)
386 .AddGroup(B_VERTICAL
, 0)
394 BLayoutBuilder::Group
<>(this, B_HORIZONTAL
)
395 .SetInsets(B_USE_WINDOW_SPACING
, B_USE_WINDOW_SPACING
,
396 B_USE_WINDOW_SPACING
, 0)
404 FadeView::AttachedToWindow()
406 fEnableCheckBox
->SetTarget(this);
407 fRunSlider
->SetTarget(this);
408 fTurnOffCheckBox
->SetTarget(this);
409 fTurnOffSlider
->SetTarget(this);
410 fFadeNow
->SetTarget(this);
411 fFadeNever
->SetTarget(this);
412 fPasswordCheckBox
->SetTarget(this);
413 fPasswordSlider
->SetTarget(this);
415 fEnableCheckBox
->SetValue(
416 fSettings
.TimeFlags() & ENABLE_SAVER
? B_CONTROL_ON
: B_CONTROL_OFF
);
417 fRunSlider
->SetTime(fSettings
.BlankTime());
418 fTurnOffSlider
->SetTime(fSettings
.OffTime() + fSettings
.BlankTime());
419 fFadeNow
->SetCorner(fSettings
.BlankCorner());
420 fFadeNever
->SetCorner(fSettings
.NeverBlankCorner());
421 fPasswordCheckBox
->SetValue(fSettings
.LockEnable());
422 fPasswordSlider
->SetTime(fSettings
.PasswordTime());
425 UpdateTurnOffScreen();
431 FadeView::MessageReceived(BMessage
*message
)
433 switch (message
->what
) {
434 case B_COLORS_UPDATED
:
437 case kMsgRunSliderChanged
:
438 case kMsgRunSliderUpdate
:
439 if (fRunSlider
->Value() > fTurnOffSlider
->Value())
440 fTurnOffSlider
->SetValue(fRunSlider
->Value());
442 if (fRunSlider
->Value() > fPasswordSlider
->Value())
443 fPasswordSlider
->SetValue(fRunSlider
->Value());
446 case kMsgTurnOffSliderChanged
:
447 case kMsgTurnOffSliderUpdate
:
448 if (fRunSlider
->Value() > fTurnOffSlider
->Value())
449 fRunSlider
->SetValue(fTurnOffSlider
->Value());
452 case kMsgPasswordSliderChanged
:
453 case kMsgPasswordSliderUpdate
:
454 if (fPasswordSlider
->Value() < fRunSlider
->Value())
455 fRunSlider
->SetValue(fPasswordSlider
->Value());
458 case kMsgTurnOffCheckBox
:
459 fTurnOffSlider
->SetEnabled(
460 fTurnOffCheckBox
->Value() == B_CONTROL_ON
);
464 switch (message
->what
) {
465 case kMsgRunSliderChanged
:
466 case kMsgTurnOffSliderChanged
:
467 case kMsgPasswordSliderChanged
:
468 case kMsgPasswordCheckBox
:
469 case kMsgEnableScreenSaverBox
:
470 case kMsgFadeCornerChanged
:
471 case kMsgNeverFadeCornerChanged
:
477 BView::MessageReceived(message
);
483 FadeView::UpdateTurnOffScreen()
485 bool enabled
= (fSettings
.TimeFlags() & ENABLE_DPMS_MASK
) != 0;
487 BScreen
screen(Window());
488 uint32 dpmsCapabilities
= screen
.DPMSCapabilites();
490 fTurnOffScreenFlags
= 0;
491 if (dpmsCapabilities
& B_DPMS_OFF
)
492 fTurnOffScreenFlags
|= ENABLE_DPMS_OFF
;
493 if (dpmsCapabilities
& B_DPMS_STAND_BY
)
494 fTurnOffScreenFlags
|= ENABLE_DPMS_STAND_BY
;
495 if (dpmsCapabilities
& B_DPMS_SUSPEND
)
496 fTurnOffScreenFlags
|= ENABLE_DPMS_SUSPEND
;
498 fTurnOffCheckBox
->SetValue(enabled
&& fTurnOffScreenFlags
!= 0
499 ? B_CONTROL_ON
: B_CONTROL_OFF
);
501 enabled
= fEnableCheckBox
->Value() == B_CONTROL_ON
;
502 fTurnOffCheckBox
->SetEnabled(enabled
&& fTurnOffScreenFlags
!= 0);
503 if (fTurnOffScreenFlags
!= 0) {
504 fTurnOffNotSupported
->Hide();
505 fTurnOffSlider
->Show();
507 fTurnOffSlider
->Hide();
508 fTurnOffNotSupported
->Show();
514 FadeView::UpdateStatus()
516 Window()->DisableUpdates();
518 bool enabled
= fEnableCheckBox
->Value() == B_CONTROL_ON
;
519 fPasswordCheckBox
->SetEnabled(enabled
);
520 fTurnOffCheckBox
->SetEnabled(enabled
&& fTurnOffScreenFlags
!= 0);
521 fRunSlider
->SetEnabled(enabled
);
522 fTurnOffSlider
->SetEnabled(enabled
&& fTurnOffCheckBox
->Value());
523 fPasswordSlider
->SetEnabled(enabled
&& fPasswordCheckBox
->Value());
524 fPasswordButton
->SetEnabled(enabled
&& fPasswordCheckBox
->Value());
526 Window()->EnableUpdates();
528 // Update the saved preferences
529 fSettings
.SetWindowFrame(Frame());
530 fSettings
.SetTimeFlags((enabled
? ENABLE_SAVER
: 0)
531 | (fTurnOffCheckBox
->Value() ? fTurnOffScreenFlags
: 0));
532 fSettings
.SetBlankTime(fRunSlider
->Time());
533 bigtime_t offTime
= fTurnOffSlider
->Time() - fSettings
.BlankTime();
534 fSettings
.SetOffTime(offTime
);
535 fSettings
.SetSuspendTime(offTime
);
536 fSettings
.SetStandByTime(offTime
);
537 fSettings
.SetBlankCorner(fFadeNow
->Corner());
538 fSettings
.SetNeverBlankCorner(fFadeNever
->Corner());
539 fSettings
.SetLockEnable(fPasswordCheckBox
->Value());
540 fSettings
.SetPasswordTime(fPasswordSlider
->Time());
542 // TODO - Tell the password window to update its stuff
547 FadeView::_UpdateColors()
549 rgb_color color
= ui_color(B_PANEL_TEXT_COLOR
);
550 fFadeNeverText
->SetFontAndColor(be_plain_font
, 0, &color
);
551 fFadeNowText
->SetFontAndColor(be_plain_font
, 0, &color
);
555 // #pragma mark - ModulesView
558 ModulesView::ModulesView(const char* name
, ScreenSaverSettings
& settings
)
560 BView(name
, B_WILL_DRAW
),
562 fScreenSaversListView(new BListView("SaversListView")),
563 fTestButton(new BButton("TestButton", B_TRANSLATE("Test"),
564 new BMessage(kMsgTestSaver
))),
566 fSettingsBox(new BBox("SettingsBox")),
568 fPreviewView(new PreviewView("preview")),
569 fScreenSaverTestTeam(-1)
571 SetViewUIColor(B_PANEL_BACKGROUND_COLOR
);
573 fScreenSaversListView
->SetSelectionMessage(
574 new BMessage(kMsgSaverSelected
));
575 BScrollView
* saversListScrollView
= new BScrollView("scroll_list",
576 fScreenSaversListView
, 0, false, true);
578 fSettingsBox
->SetLabel(B_TRANSLATE("Screensaver settings"));
579 fSettingsBox
->SetExplicitMinSize(BSize(
580 floorf(be_control_look
->DefaultItemSpacing()
581 * ((kWindowWidth
- 157.0f
) / kDefaultItemSpacingAt12pt
)),
584 BLayoutBuilder::Group
<>(this, B_HORIZONTAL
)
585 .SetInsets(B_USE_WINDOW_SPACING
, B_USE_WINDOW_SPACING
,
586 B_USE_WINDOW_SPACING
, 0)
587 .AddGroup(B_VERTICAL
)
589 .Add(saversListScrollView
)
590 .AddGroup(B_HORIZONTAL
)
600 ModulesView::~ModulesView()
609 ModulesView::DetachedFromWindow()
612 EmptyScreenSaverList();
619 ModulesView::AttachedToWindow()
621 fScreenSaversListView
->SetTarget(this);
622 fTestButton
->SetTarget(this);
627 ModulesView::AllAttached()
629 PopulateScreenSaverList();
630 fScreenSaversListView
->Invoke();
635 ModulesView::MessageReceived(BMessage
* message
)
637 switch (message
->what
) {
638 case kMsgSaverSelected
:
640 int32 selection
= fScreenSaversListView
->CurrentSelection();
644 ScreenSaverItem
* item
645 = (ScreenSaverItem
*)fScreenSaversListView
->ItemAt(selection
);
649 if (strcmp(item
->Text(), B_TRANSLATE("Blackness")) == 0)
650 fSettings
.SetModuleName("");
652 fSettings
.SetModuleName(item
->Text());
668 be_roster
->StartWatching(BMessenger(this, Looper()),
670 BMessage
message(kMsgTestSaver
);
671 if (be_roster
->Launch(SCREEN_BLANKER_SIG
, &message
,
672 &fScreenSaverTestTeam
) == B_OK
) {
676 // Try really hard to launch it. It's very likely that this fails
677 // when we run from the CD, and there is only an incomplete mime
678 // database for example...
680 if (find_directory(B_SYSTEM_BIN_DIRECTORY
, &path
) != B_OK
681 || path
.Append("screen_blanker") != B_OK
) {
682 path
.SetTo("/bin/screen_blanker");
685 BEntry
entry(path
.Path());
687 if (entry
.GetRef(&ref
) == B_OK
) {
688 be_roster
->Launch(&ref
, &message
,
689 &fScreenSaverTestTeam
);
694 case B_SOME_APP_QUIT
:
697 if (message
->FindInt32("be:team", &team
) == B_OK
698 && team
== fScreenSaverTestTeam
) {
699 be_roster
->StopWatching(this);
706 BView::MessageReceived(message
);
712 ModulesView::SaveState()
714 BScreenSaver
* saver
= ScreenSaver();
719 if (saver
->SaveState(&state
) == B_OK
)
720 fSettings
.SetModuleState(fCurrentName
.String(), &state
);
725 ModulesView::EmptyScreenSaverList()
727 fScreenSaversListView
->DeselectAll();
728 while (BListItem
* item
= fScreenSaversListView
->RemoveItem((int32
)0))
734 ModulesView::PopulateScreenSaverList()
736 // Blackness is a built-in screen saver
737 ScreenSaverItem
* defaultItem
738 = new ScreenSaverItem(B_TRANSLATE("Blackness"), "");
739 fScreenSaversListView
->AddItem(defaultItem
);
741 // Iterate over add-on directories, and add their files to the list view
743 directory_which which
[] = {
744 B_USER_NONPACKAGED_ADDONS_DIRECTORY
,
745 B_USER_ADDONS_DIRECTORY
,
746 B_SYSTEM_NONPACKAGED_ADDONS_DIRECTORY
,
747 B_SYSTEM_ADDONS_DIRECTORY
,
749 ScreenSaverItem
* selectedItem
= NULL
;
751 for (uint32 i
= 0; i
< sizeof(which
) / sizeof(which
[0]); i
++) {
753 if (find_directory(which
[i
], &basePath
) != B_OK
)
755 else if (basePath
.Append("Screen Savers", true) != B_OK
)
758 BDirectory
dir(basePath
.Path());
760 while (dir
.GetNextEntry(&entry
, true) == B_OK
) {
761 char name
[B_FILE_NAME_LENGTH
];
762 if (entry
.GetName(name
) != B_OK
)
765 BPath
path(basePath
);
766 if (path
.Append(name
) != B_OK
)
769 ScreenSaverItem
* item
= new ScreenSaverItem(name
, path
.Path());
770 fScreenSaversListView
->AddItem(item
);
772 if (selectedItem
!= NULL
)
775 if (strcmp(fSettings
.ModuleName(), item
->Text()) == 0)
780 fScreenSaversListView
->SortItems(_CompareScreenSaverItems
);
781 if (selectedItem
== NULL
)
782 selectedItem
= defaultItem
;
784 fScreenSaversListView
->Select(fScreenSaversListView
->IndexOf(selectedItem
));
785 fScreenSaversListView
->ScrollToSelection();
789 //! Sorting function for ScreenSaverItems
791 ModulesView::_CompareScreenSaverItems(const void* left
, const void* right
)
793 ScreenSaverItem
* leftItem
= *(ScreenSaverItem
**)left
;
794 ScreenSaverItem
* rightItem
= *(ScreenSaverItem
**)right
;
796 return strcasecmp(leftItem
->Text(), rightItem
->Text());
801 ModulesView::ScreenSaver()
803 if (fSaverRunner
!= NULL
)
804 return fSaverRunner
->ScreenSaver();
811 ModulesView::_CloseSaver()
813 // remove old screen saver preview & config
815 BScreenSaver
* saver
= ScreenSaver();
816 BView
* view
= fPreviewView
->RemovePreview();
817 if (fSettingsView
!= NULL
)
818 fSettingsBox
->RemoveChild(fSettingsView
);
820 if (fSaverRunner
!= NULL
)
821 fSaverRunner
->Quit();
827 delete fSettingsView
;
829 // the saver runner also unloads the add-on, so it must
832 fSettingsView
= NULL
;
838 ModulesView::_OpenSaver()
840 // create new screen saver preview & config
842 BView
* view
= fPreviewView
->AddPreview();
843 fCurrentName
= fSettings
.ModuleName();
844 fSaverRunner
= new ScreenSaverRunner(view
->Window(), view
, fSettings
);
847 BRect rect
= fSettingsBox
->InnerFrame().InsetByCopy(4, 4);
849 BRect rect
= fSettingsBox
->Bounds().InsetByCopy(4, 4);
852 fSettingsView
= new BView(rect
, "SettingsView", B_FOLLOW_ALL
, B_WILL_DRAW
);
854 fSettingsView
->SetViewUIColor(B_PANEL_BACKGROUND_COLOR
);
855 fSettingsBox
->AddChild(fSettingsView
);
857 BScreenSaver
* saver
= ScreenSaver();
858 if (saver
!= NULL
&& fSettingsView
!= NULL
) {
859 saver
->StartConfig(fSettingsView
);
860 if (saver
->StartSaver(view
, true) == B_OK
) {
861 fPreviewView
->HideNoPreview();
864 fPreviewView
->ShowNoPreview();
866 // Failed to load OR this is the "Blackness" screensaver. Show a black
867 // preview (this is what will happen in both cases when screen_blanker
869 fPreviewView
->HideNoPreview();
872 if (fSettingsView
->ChildAt(0) == NULL
) {
873 // There are no settings at all, we add the module name here to
874 // let it look a bit better at least.
875 BPrivate::BuildDefaultSettingsView(fSettingsView
,
876 fSettings
.ModuleName()[0] ? fSettings
.ModuleName()
877 : B_TRANSLATE("Blackness"),
878 saver
!= NULL
|| !fSettings
.ModuleName()[0]
879 ? B_TRANSLATE("No options available")
880 : B_TRANSLATE("Could not load screen saver"));
885 // #pragma mark - TabView
890 BTabView("tab_view", B_WIDTH_FROM_LABEL
)
896 TabView::MouseDown(BPoint where
)
898 BTab
* fadeTab
= TabAt(0);
899 BRect
fadeTabFrame(TabFrame(0));
900 BTab
* modulesTab
= TabAt(1);
901 BRect
modulesTabFrame(TabFrame(1));
902 ModulesView
* modulesView
= dynamic_cast<ModulesView
*>(modulesTab
->View());
904 if (fadeTab
!= NULL
&& Selection() != 0 && fadeTabFrame
.Contains(where
)
905 && modulesView
!= NULL
) {
906 // clicked on the fade tab
907 modulesView
->SaveState();
908 modulesView
->_CloseSaver();
909 } else if (modulesTab
!= NULL
&& Selection() != 1
910 && modulesTabFrame
.Contains(where
) && modulesView
!= NULL
) {
911 // clicked on the modules tab
912 BMessage
message(kMsgSaverSelected
);
913 modulesView
->MessageReceived(&message
);
916 BTabView::MouseDown(where
);
920 // #pragma mark - ScreenSaverWindow
923 ScreenSaverWindow::ScreenSaverWindow()
925 BWindow(BRect(50.0f
, 50.0f
, 50.0f
+ kWindowWidth
, 50.0f
+ kWindowHeight
),
926 B_TRANSLATE_SYSTEM_NAME("ScreenSaver"), B_TITLED_WINDOW
,
927 B_ASYNCHRONOUS_CONTROLS
| B_AUTO_UPDATE_SIZE_LIMITS
)
931 fMinWidth
= floorf(be_control_look
->DefaultItemSpacing()
932 * (kWindowWidth
/ kDefaultItemSpacingAt12pt
));
934 font_height fontHeight
;
935 be_plain_font
->GetHeight(&fontHeight
);
936 float textHeight
= ceilf(fontHeight
.ascent
+ fontHeight
.descent
);
938 fMinHeight
= ceilf(std::max(kWindowHeight
, textHeight
* 28));
940 // Create the password editing window
941 fPasswordWindow
= new PasswordWindow(fSettings
);
942 fPasswordWindow
->Run();
944 // Create the tab view
945 fTabView
= new TabView();
946 fTabView
->SetBorder(B_NO_BORDER
);
948 // Create the controls inside the tabs
949 fFadeView
= new FadeView(B_TRANSLATE("General"), fSettings
);
950 fModulesView
= new ModulesView(B_TRANSLATE("Screensavers"), fSettings
);
952 fTabView
->AddTab(fFadeView
);
953 fTabView
->AddTab(fModulesView
);
955 // Create the topmost background view
956 BView
* topView
= new BView("topView", B_WILL_DRAW
);
957 topView
->SetViewUIColor(B_PANEL_BACKGROUND_COLOR
);
958 topView
->SetExplicitAlignment(BAlignment(B_ALIGN_USE_FULL_WIDTH
,
959 B_ALIGN_USE_FULL_HEIGHT
));
960 topView
->SetExplicitMinSize(BSize(fMinWidth
, fMinHeight
));
961 BLayoutBuilder::Group
<>(topView
, B_VERTICAL
)
962 .SetInsets(0, B_USE_DEFAULT_SPACING
, 0, B_USE_WINDOW_SPACING
)
966 SetLayout(new BGroupLayout(B_VERTICAL
));
967 GetLayout()->AddView(topView
);
969 fTabView
->Select(fSettings
.WindowTab());
971 if (fSettings
.WindowFrame().left
> 0 && fSettings
.WindowFrame().top
> 0)
972 MoveTo(fSettings
.WindowFrame().left
, fSettings
.WindowFrame().top
);
974 if (fSettings
.WindowFrame().Width() > 0
975 && fSettings
.WindowFrame().Height() > 0) {
976 ResizeTo(fSettings
.WindowFrame().Width(),
977 fSettings
.WindowFrame().Height());
984 ScreenSaverWindow::~ScreenSaverWindow()
987 fFadeView
->UpdateStatus();
988 fSettings
.SetWindowTab(fTabView
->Selection());
990 delete fTabView
->RemoveTab(1);
991 // We delete this here in order to make sure the module view saves its
992 // state while the window is still intact.
999 ScreenSaverWindow::MessageReceived(BMessage
* message
)
1001 switch (message
->what
) {
1002 case kMsgChangePassword
:
1003 fPasswordWindow
->CenterIn(Frame());
1004 fPasswordWindow
->Show();
1007 case kMsgUpdateList
:
1008 fModulesView
->EmptyScreenSaverList();
1009 fModulesView
->PopulateScreenSaverList();
1013 BWindow::MessageReceived(message
);
1019 ScreenSaverWindow::ScreenChanged(BRect frame
, color_space colorSpace
)
1021 fFadeView
->UpdateTurnOffScreen();
1026 ScreenSaverWindow::QuitRequested()
1028 be_app
->PostMessage(B_QUIT_REQUESTED
);