1 /* 2 * Copyright 2003-2006, Haiku. 3 * Distributed under the terms of the MIT License. 4 * 5 * Authors: 6 * Michael Phipps 7 * Jérôme Duval, jerome.duval@free.fr 8 * Axel Dörfler, axeld@pinc-software.de 9 */ 10 11 12 #include "PreviewView.h" 13 #include "ScreenCornerSelector.h" 14 #include "ScreenSaverItem.h" 15 #include "ScreenSaverWindow.h" 16 17 #include <Application.h> 18 #include <Box.h> 19 #include <Button.h> 20 #include <Directory.h> 21 #include <Entry.h> 22 #include <File.h> 23 #include <FindDirectory.h> 24 #include <Font.h> 25 #include <ListView.h> 26 #include <Path.h> 27 #include <Roster.h> 28 #include <Screen.h> 29 #include <ScreenSaver.h> 30 #include <ScrollView.h> 31 #include <Slider.h> 32 #include <StringView.h> 33 #include <TabView.h> 34 35 #include <stdio.h> 36 37 38 const uint32 kPreviewMonitorGap = 16; 39 const uint32 kMinSettingsWidth = 230; 40 const uint32 kMinSettingsHeight = 120; 41 42 const int32 kMsgSaverSelected = 'SSEL'; 43 const int32 kMsgTestSaver = 'TEST'; 44 const int32 kMsgAddSaver = 'ADD '; 45 const int32 kMsgPasswordCheckBox = 'PWCB'; 46 const int32 kMsgRunSliderChanged = 'RSCG'; 47 const int32 kMsgPasswordSliderChanged = 'PWCG'; 48 const int32 kMsgChangePassword = 'PWBT'; 49 const int32 kMsgEnableScreenSaverBox = 'ESCH'; 50 51 const int32 kMsgTurnOffCheckBox = 'TUOF'; 52 const int32 kMsgTurnOffSliderChanged = 'TUCG'; 53 54 const int32 kMsgFadeCornerChanged = 'fdcc'; 55 const int32 kMsgNeverFadeCornerChanged = 'nfcc'; 56 57 static const uint32 kTimeSliderChanged = 'tsch'; 58 59 60 class TimeSlider : public BSlider { 61 public: 62 TimeSlider(BRect frame, const char* name, uint32 modificationMessage); 63 virtual ~TimeSlider(); 64 65 virtual void AttachedToWindow(); 66 virtual void MessageReceived(BMessage* message); 67 virtual void SetValue(int32 value); 68 69 void SetTime(bigtime_t useconds); 70 bigtime_t Time(); 71 72 private: 73 void _TimeToString(bigtime_t useconds, BString& string); 74 75 uint32 fModificationMessage; 76 }; 77 78 class FadeView : public BView { 79 public: 80 FadeView(BRect frame, const char* name, ScreenSaverSettings& settings); 81 82 virtual void AttachedToWindow(); 83 }; 84 85 class ModulesView : public BView { 86 public: 87 ModulesView(BRect frame, const char* name, ScreenSaverSettings& settings); 88 virtual ~ModulesView(); 89 90 virtual void DetachedFromWindow(); 91 virtual void AttachedToWindow(); 92 virtual void AllAttached(); 93 virtual void MessageReceived(BMessage* message); 94 95 void PopulateScreenSaverList(); 96 void SaveState(); 97 98 private: 99 static int _CompareScreenSaverItems(const void* left, const void* right); 100 BScreenSaver* _ScreenSaver(); 101 void _CloseSaver(); 102 void _OpenSaver(); 103 104 BFilePanel* fFilePanel; 105 BListView* fListView; 106 BButton* fTestButton; 107 BButton* fAddButton; 108 109 ScreenSaverSettings& fSettings; 110 ScreenSaverRunner* fSaverRunner; 111 BString fCurrentName; 112 113 BBox* fSettingsBox; 114 BView* fSettingsView; 115 116 PreviewView* fPreviewView; 117 }; 118 119 static const int32 kTimeInUnits[] = { 120 30, 60, 90, 121 120, 150, 180, 122 240, 300, 360, 123 420, 480, 540, 124 600, 900, 1200, 125 1500, 1800, 2400, 126 3000, 3600, 5400, 127 7200, 9000, 10800, 128 14400, 18000 129 }; 130 static const int32 kTimeUnitCount = sizeof(kTimeInUnits) / sizeof(kTimeInUnits[0]); 131 132 133 TimeSlider::TimeSlider(BRect frame, const char* name, uint32 modificationMessage) 134 : BSlider(frame, name, "0 minutes", new BMessage(kTimeSliderChanged), 135 0, kTimeUnitCount - 1, B_TRIANGLE_THUMB, B_FOLLOW_LEFT_RIGHT), 136 fModificationMessage(modificationMessage) 137 { 138 SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR)); 139 SetModificationMessage(new BMessage(kTimeSliderChanged)); 140 SetBarThickness(10); 141 } 142 143 144 TimeSlider::~TimeSlider() 145 { 146 } 147 148 149 void 150 TimeSlider::AttachedToWindow() 151 { 152 SetTarget(this); 153 } 154 155 156 void 157 TimeSlider::MessageReceived(BMessage* message) 158 { 159 switch (message->what) { 160 case kTimeSliderChanged: 161 Window()->PostMessage(fModificationMessage); 162 break; 163 164 default: 165 BSlider::MessageReceived(message); 166 } 167 } 168 169 170 void 171 TimeSlider::SetValue(int32 value) 172 { 173 int32 oldValue = Value(); 174 BSlider::SetValue(value); 175 176 if (oldValue != Value()) { 177 BString label; 178 _TimeToString(kTimeInUnits[Value()] * 1000000LL, label); 179 SetLabel(label.String()); 180 } 181 } 182 183 184 void 185 TimeSlider::SetTime(bigtime_t useconds) 186 { 187 for (int t = 0; t < kTimeUnitCount; t++) { 188 if (kTimeInUnits[t] * 1000000LL == useconds) { 189 SetValue(t); 190 break; 191 } 192 } 193 } 194 195 196 bigtime_t 197 TimeSlider::Time() 198 { 199 return 1000000LL * kTimeInUnits[Value()]; 200 } 201 202 203 void 204 TimeSlider::_TimeToString(bigtime_t useconds, BString& string) 205 { 206 useconds /= 1000000LL; 207 // convert to seconds 208 209 string = ""; 210 211 // hours 212 uint32 hours = useconds / 3600; 213 if (hours != 0) 214 string << hours << " hours"; 215 216 useconds %= 3600; 217 218 // minutes 219 uint32 minutes = useconds / 60; 220 if (hours != 0) 221 string << " "; 222 if (minutes != 0) 223 string << minutes << " minutes"; 224 225 useconds %= 60; 226 227 // seconds 228 uint32 seconds = useconds; 229 if (hours != 0 || minutes != 0) 230 string << " "; 231 if (seconds != 0) 232 string << seconds << " seconds"; 233 } 234 235 236 // #pragma mark - 237 238 239 FadeView::FadeView(BRect rect, const char* name, ScreenSaverSettings& settings) 240 : BView(rect, name, B_FOLLOW_ALL, B_WILL_DRAW) 241 { 242 SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR)); 243 } 244 245 246 void 247 FadeView::AttachedToWindow() 248 { 249 if (Parent() != NULL) { 250 // We adopt the size of our parent view (in case the window 251 // was resized during our absence (BTabView...) 252 ResizeTo(Parent()->Bounds().Width(), Parent()->Bounds().Height()); 253 } 254 } 255 256 257 // #pragma mark - 258 259 260 ModulesView::ModulesView(BRect rect, const char* name, ScreenSaverSettings& settings) 261 : BView(rect, name, B_FOLLOW_ALL, B_WILL_DRAW), 262 fSettings(settings), 263 fSaverRunner(NULL), 264 fSettingsView(NULL) 265 { 266 SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR)); 267 268 fTestButton = new BButton(rect, "TestButton", "Test", new BMessage(kMsgTestSaver), 269 B_FOLLOW_LEFT | B_FOLLOW_BOTTOM); 270 float width, height; 271 fTestButton->GetPreferredSize(&width, &height); 272 fTestButton->ResizeTo(width + 16, height); 273 fTestButton->MoveTo(8, rect.bottom - 8 - height); 274 AddChild(fTestButton); 275 276 rect = fTestButton->Frame(); 277 rect.OffsetBy(fTestButton->Bounds().Width() + 8, 0); 278 fAddButton = new BButton(rect, "AddButton", "Add" B_UTF8_ELLIPSIS, 279 new BMessage(kMsgAddSaver), B_FOLLOW_LEFT | B_FOLLOW_BOTTOM); 280 AddChild(fAddButton); 281 282 rect = Bounds().InsetByCopy(8 + kPreviewMonitorGap, 12); 283 rect.right = fAddButton->Frame().right - kPreviewMonitorGap; 284 rect.bottom = rect.top + 3 * rect.Width() / 4; 285 // 4:3 monitor 286 287 fPreviewView = new PreviewView(rect, "preview"); 288 AddChild(fPreviewView); 289 290 rect.left = 8; 291 rect.right -= B_V_SCROLL_BAR_WIDTH + 2 - kPreviewMonitorGap; 292 // scroll view border 293 rect.top = rect.bottom + 14; 294 rect.bottom = fTestButton->Frame().top - 10; 295 fListView = new BListView(rect, "SaversListView", B_SINGLE_SELECTION_LIST, 296 B_FOLLOW_LEFT | B_FOLLOW_TOP_BOTTOM); 297 fListView->SetSelectionMessage(new BMessage(kMsgSaverSelected)); 298 AddChild(new BScrollView("scroll_list", fListView, 299 B_FOLLOW_LEFT | B_FOLLOW_TOP_BOTTOM, 0, false, true)); 300 301 rect = Bounds().InsetByCopy(8, 8); 302 rect.left = fAddButton->Frame().right + 8; 303 AddChild(fSettingsBox = new BBox(rect, "SettingsBox", B_FOLLOW_ALL, B_WILL_DRAW)); 304 fSettingsBox->SetLabel("Module settings"); 305 306 PopulateScreenSaverList(); 307 fFilePanel = new BFilePanel(); 308 } 309 310 311 ModulesView::~ModulesView() 312 { 313 delete fFilePanel; 314 } 315 316 317 void 318 ModulesView::DetachedFromWindow() 319 { 320 _CloseSaver(); 321 } 322 323 324 void 325 ModulesView::AttachedToWindow() 326 { 327 if (Parent() != NULL) { 328 // We adopt the size of our parent view (in case the window 329 // was resized during our absence (BTabView...) 330 ResizeTo(Parent()->Bounds().Width(), Parent()->Bounds().Height()); 331 } 332 333 _OpenSaver(); 334 335 fListView->SetTarget(this); 336 fTestButton->SetTarget(this); 337 fAddButton->SetTarget(this); 338 } 339 340 341 void 342 ModulesView::AllAttached() 343 { 344 // This only works after the view has been attached 345 fListView->ScrollToSelection(); 346 } 347 348 349 void 350 ModulesView::MessageReceived(BMessage* message) 351 { 352 switch (message->what) { 353 case kMsgSaverSelected: 354 { 355 int selection = fListView->CurrentSelection(); 356 if (selection < 0) 357 break; 358 359 ScreenSaverItem* item = (ScreenSaverItem *)fListView->ItemAt(selection); 360 if (item == NULL) 361 break; 362 363 if (!strcmp(item->Text(), "Blackness")) 364 fSettings.SetModuleName(""); 365 else 366 fSettings.SetModuleName(item->Text()); 367 368 _CloseSaver(); 369 _OpenSaver(); 370 break; 371 } 372 373 case kMsgTestSaver: 374 SaveState(); 375 fSettings.Save(); 376 377 be_roster->Launch(SCREEN_BLANKER_SIG, &fSettings.Message()); 378 break; 379 380 case kMsgAddSaver: 381 fFilePanel->Show(); 382 break; 383 384 default: 385 BView::MessageReceived(message); 386 } 387 } 388 389 390 void 391 ModulesView::SaveState() 392 { 393 BScreenSaver* saver = _ScreenSaver(); 394 if (saver == NULL) 395 return; 396 397 BMessage state; 398 if (saver->SaveState(&state) == B_OK) 399 fSettings.SetModuleState(fCurrentName.String(), &state); 400 } 401 402 403 void 404 ModulesView::PopulateScreenSaverList() 405 { 406 fListView->DeselectAll(); 407 while (ScreenSaverItem* item = (ScreenSaverItem *)fListView->RemoveItem((int32)0)) { 408 delete item; 409 } 410 411 // Blackness is a built-in screen saver 412 fListView->AddItem(new ScreenSaverItem("Blackness", "")); 413 414 // Iterate over add-on directories, and add their files to the list view 415 416 directory_which which[] = {B_BEOS_ADDONS_DIRECTORY, B_USER_ADDONS_DIRECTORY}; 417 ScreenSaverItem* selectItem = NULL; 418 419 for (uint32 i = 0; i < sizeof(which) / sizeof(which[0]); i++) { 420 BPath basePath; 421 find_directory(which[i], &basePath); 422 basePath.Append("Screen Savers", true); 423 424 BDirectory dir(basePath.Path()); 425 BEntry entry; 426 while (dir.GetNextEntry(&entry, true) == B_OK) { 427 char name[B_FILE_NAME_LENGTH]; 428 if (entry.GetName(name) != B_OK) 429 continue; 430 431 BPath path = basePath; 432 path.Append(name); 433 434 ScreenSaverItem* item = new ScreenSaverItem(name, path.Path()); 435 fListView->AddItem(item); 436 437 if (!strcmp(fSettings.ModuleName(), item->Text()) 438 || (!strcmp(fSettings.ModuleName(), "") 439 && !strcmp(item->Text(), "Blackness"))) 440 selectItem = item; 441 } 442 } 443 444 fListView->SortItems(_CompareScreenSaverItems); 445 446 fListView->Select(fListView->IndexOf(selectItem)); 447 fListView->ScrollToSelection(); 448 } 449 450 451 //! sorting function for ScreenSaverItems 452 int 453 ModulesView::_CompareScreenSaverItems(const void* left, const void* right) 454 { 455 ScreenSaverItem* leftItem = *(ScreenSaverItem **)left; 456 ScreenSaverItem* rightItem = *(ScreenSaverItem **)right; 457 458 return strcmp(leftItem->Text(), rightItem->Text()); 459 } 460 461 462 BScreenSaver* 463 ModulesView::_ScreenSaver() 464 { 465 if (fSaverRunner != NULL) 466 return fSaverRunner->ScreenSaver(); 467 468 return NULL; 469 } 470 471 472 void 473 ModulesView::_CloseSaver() 474 { 475 // remove old screen saver preview & config 476 477 BScreenSaver* saver = _ScreenSaver(); 478 BView* view = fPreviewView->RemovePreview(); 479 if (fSettingsView != NULL) 480 fSettingsBox->RemoveChild(fSettingsView); 481 482 if (saver != NULL) 483 saver->StopConfig(); 484 485 SaveState(); 486 487 delete view; 488 delete fSettingsView; 489 delete fSaverRunner; 490 491 fSettingsView = NULL; 492 fSaverRunner = NULL; 493 } 494 495 496 void 497 ModulesView::_OpenSaver() 498 { 499 // create new screen saver preview & config 500 501 BView* view = fPreviewView->AddPreview(); 502 fCurrentName = fSettings.ModuleName(); 503 fSaverRunner = new ScreenSaverRunner(Window(), view, true, fSettings); 504 BScreenSaver* saver = _ScreenSaver(); 505 506 #ifdef __HAIKU__ 507 BRect rect = fSettingsBox->InnerFrame().InsetByCopy(4, 4); 508 #else 509 BRect rect = fSettingsBox->Bounds().InsetByCopy(4, 4); 510 rect.top += 14; 511 #endif 512 fSettingsView = new BView(rect, "SettingsView", B_FOLLOW_ALL, B_WILL_DRAW); 513 fSettingsView->SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR)); 514 fSettingsBox->AddChild(fSettingsView); 515 516 if (saver != NULL) { 517 fSaverRunner->Run(); 518 saver->StartConfig(fSettingsView); 519 } 520 521 if (fSettingsView->ChildAt(0) == NULL) { 522 // There are no settings at all, we add the module name here to 523 // let it look a bit better at least. 524 rect = BRect(15, 15, 20, 20); 525 BStringView* stringView = new BStringView(rect, "module", fSettings.ModuleName()[0] 526 ? fSettings.ModuleName() : "Blackness"); 527 stringView->SetFont(be_bold_font); 528 stringView->ResizeToPreferred(); 529 fSettingsView->AddChild(stringView); 530 531 rect.OffsetBy(0, stringView->Bounds().Height() + 4); 532 stringView = new BStringView(rect, "info", saver || !fSettings.ModuleName()[0] 533 ? "No options available" : "Could not load screen saver"); 534 stringView->ResizeToPreferred(); 535 fSettingsView->AddChild(stringView); 536 } 537 538 ScreenSaverWindow* window = dynamic_cast<ScreenSaverWindow*>(Window()); 539 if (window == NULL) 540 return; 541 542 // find the minimal size of the settings view 543 544 float right = 0, bottom = 0; 545 int32 i = 0; 546 while ((view = fSettingsView->ChildAt(i++)) != NULL) { 547 // very simple heuristic... 548 float viewRight = view->Frame().right; 549 if ((view->ResizingMode() & _rule_(0, 0xf, 0, 0xf)) == B_FOLLOW_LEFT_RIGHT) { 550 float width, height; 551 view->GetPreferredSize(&width, &height); 552 viewRight = view->Frame().left + width / 2; 553 } else if ((view->ResizingMode() & _rule_(0, 0xf, 0, 0xf)) == B_FOLLOW_RIGHT) 554 viewRight = 8 + view->Frame().Width(); 555 556 float viewBottom = view->Frame().bottom; 557 if ((view->ResizingMode() & _rule_(0xf, 0, 0xf, 0)) == B_FOLLOW_TOP_BOTTOM) { 558 float width, height; 559 view->GetPreferredSize(&width, &height); 560 viewBottom = view->Frame().top + height; 561 } else if ((view->ResizingMode() & _rule_(0xf, 0, 0xf, 0)) == B_FOLLOW_BOTTOM) 562 viewBottom = 8 + view->Frame().Height(); 563 564 if (viewRight > right) 565 right = viewRight; 566 if (viewBottom > bottom) 567 bottom = viewBottom; 568 } 569 570 if (right < kMinSettingsWidth) 571 right = kMinSettingsWidth; 572 if (bottom < kMinSettingsHeight) 573 bottom = kMinSettingsHeight; 574 575 BPoint leftTop = fSettingsView->LeftTop(); 576 fSettingsView->ConvertToScreen(&leftTop); 577 window->ConvertFromScreen(&leftTop); 578 window->SetMinimalSizeLimit(leftTop.x + right + 16, 579 leftTop.y + bottom + 16); 580 } 581 582 583 // #pragma mark - 584 585 586 ScreenSaverWindow::ScreenSaverWindow() 587 : BWindow(BRect(50, 50, 496, 375), "Screen Saver", 588 B_TITLED_WINDOW, B_ASYNCHRONOUS_CONTROLS /*| B_NOT_ZOOMABLE | B_NOT_RESIZABLE*/) 589 { 590 fSettings.Load(); 591 592 BRect rect = Bounds(); 593 594 // Create a background view 595 BView *background = new BView(rect, "background", B_FOLLOW_ALL, 0); 596 background->SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR)); 597 AddChild(background); 598 599 // Add the tab view to the background 600 rect.top += 4; 601 fTabView = new BTabView(rect, "tab_view"); 602 603 // Create the controls inside the tabs 604 rect = fTabView->ContainerView()->Bounds(); 605 _SetupFadeTab(rect); 606 fModulesView = new ModulesView(rect, "Modules", fSettings); 607 608 fTabView->AddTab(fFadeView); 609 fTabView->AddTab(fModulesView); 610 background->AddChild(fTabView); 611 612 // Create the password editing window 613 fPasswordWindow = new PasswordWindow(fSettings); 614 fPasswordWindow->Run(); 615 616 // TODO: better limits! 617 fMinWidth = 430; 618 fMinHeight = 325; 619 SetMinimalSizeLimit(fMinWidth, fMinHeight); 620 MoveTo(fSettings.WindowFrame().left, fSettings.WindowFrame().top); 621 ResizeTo(fSettings.WindowFrame().Width(), fSettings.WindowFrame().Height()); 622 623 fEnableCheckBox->SetValue(fSettings.TimeFlags() & ENABLE_SAVER ? B_CONTROL_ON : B_CONTROL_OFF); 624 fRunSlider->SetTime(fSettings.BlankTime()); 625 fTurnOffSlider->SetTime(fSettings.OffTime() + fSettings.BlankTime()); 626 fFadeNow->SetCorner(fSettings.BlankCorner()); 627 fFadeNever->SetCorner(fSettings.NeverBlankCorner()); 628 fPasswordCheckBox->SetValue(fSettings.LockEnable()); 629 fPasswordSlider->SetTime(fSettings.PasswordTime()); 630 631 fTabView->Select(fSettings.WindowTab()); 632 633 _UpdateTurnOffScreen(); 634 _UpdateStatus(); 635 } 636 637 638 ScreenSaverWindow::~ScreenSaverWindow() 639 { 640 } 641 642 643 //! Create the controls for the fade tab 644 void 645 ScreenSaverWindow::_SetupFadeTab(BRect rect) 646 { 647 fFadeView = new FadeView(rect, "Fade", fSettings); 648 649 float labelWidth = be_plain_font->StringWidth("Turn off screen") + 20.0f; 650 651 font_height fontHeight; 652 be_plain_font->GetHeight(&fontHeight); 653 float textHeight = ceilf(fontHeight.ascent + fontHeight.descent); 654 655 // taken from BRadioButton: 656 float radioButtonOffset = 2 * floorf(textHeight / 2 - 2) + floorf(textHeight / 2); 657 658 fEnableCheckBox = new BCheckBox(BRect(0, 0, 1, 1), "EnableCheckBox", 659 "Enable Screen Saver", new BMessage(kMsgEnableScreenSaverBox)); 660 fEnableCheckBox->ResizeToPreferred(); 661 662 rect.InsetBy(8, 8); 663 BBox* box = new BBox(rect, "EnableScreenSaverBox", B_FOLLOW_ALL); 664 box->SetLabel(fEnableCheckBox); 665 fFadeView->AddChild(box); 666 667 // Run Module 668 rect.left += radioButtonOffset; 669 rect.top = fEnableCheckBox->Bounds().bottom + 8.0f; 670 rect.right = box->Bounds().right - 8; 671 BStringView* stringView = new BStringView(rect, NULL, "Run module"); 672 stringView->ResizeToPreferred(); 673 box->AddChild(stringView); 674 675 rect.left += labelWidth; 676 fRunSlider = new TimeSlider(rect, "RunSlider", kMsgRunSliderChanged); 677 float width, height; 678 fRunSlider->GetPreferredSize(&width, &height); 679 fRunSlider->ResizeTo(fRunSlider->Bounds().Width(), height); 680 box->AddChild(fRunSlider); 681 682 // Turn Off 683 rect.left = 8; 684 rect.OffsetBy(0, fRunSlider->Bounds().Height() + 4.0f); 685 fTurnOffCheckBox = new BCheckBox(rect, "TurnOffScreenCheckBox", 686 "Turn off screen", new BMessage(kMsgTurnOffCheckBox)); 687 fTurnOffCheckBox->ResizeToPreferred(); 688 box->AddChild(fTurnOffCheckBox); 689 690 rect.left += radioButtonOffset + labelWidth; 691 fTurnOffSlider = new TimeSlider(rect, "TurnOffSlider", kMsgTurnOffSliderChanged); 692 fTurnOffSlider->ResizeTo(fTurnOffSlider->Bounds().Width(), height); 693 box->AddChild(fTurnOffSlider); 694 695 // Password 696 rect.left = 8; 697 rect.OffsetBy(0, fTurnOffSlider->Bounds().Height() + 4.0f); 698 fPasswordCheckBox = new BCheckBox(rect, "PasswordCheckbox", 699 "Password lock", new BMessage(kMsgPasswordCheckBox)); 700 fPasswordCheckBox->ResizeToPreferred(); 701 box->AddChild(fPasswordCheckBox); 702 703 rect.left += radioButtonOffset + labelWidth; 704 fPasswordSlider = new TimeSlider(rect, "PasswordSlider", kMsgPasswordSliderChanged); 705 fPasswordSlider->ResizeTo(fPasswordSlider->Bounds().Width(), height); 706 box->AddChild(fPasswordSlider); 707 708 rect.OffsetBy(0, fTurnOffSlider->Bounds().Height() + 4.0f); 709 rect.left = rect.right; 710 fPasswordButton = new BButton(rect, "PasswordButton", "Password" B_UTF8_ELLIPSIS, 711 new BMessage(kMsgChangePassword), B_FOLLOW_TOP | B_FOLLOW_RIGHT); 712 fPasswordButton->ResizeToPreferred(); 713 fPasswordButton->MoveBy(-fPasswordButton->Bounds().Width(), 0); 714 box->AddChild(fPasswordButton); 715 716 // Bottom 717 718 box->AddChild(fFadeNow = new ScreenCornerSelector(BRect(20,205,80,260), "FadeNow", 719 new BMessage(kMsgFadeCornerChanged), B_FOLLOW_LEFT | B_FOLLOW_BOTTOM)); 720 box->AddChild(fFadeNever = new ScreenCornerSelector(BRect(220,205,280,260), "FadeNever", 721 new BMessage(kMsgNeverFadeCornerChanged), B_FOLLOW_LEFT | B_FOLLOW_BOTTOM)); 722 723 rect = BRect(90,215,193,230); 724 stringView = new BStringView(rect, NULL, "Fade now when", 725 B_FOLLOW_LEFT | B_FOLLOW_BOTTOM); 726 stringView->ResizeToPreferred(); 727 box->AddChild(stringView); 728 729 rect.OffsetBy(0, stringView->Bounds().Height()); 730 stringView = new BStringView(rect, NULL, "mouse is here", 731 B_FOLLOW_LEFT | B_FOLLOW_BOTTOM); 732 stringView->ResizeToPreferred(); 733 box->AddChild(stringView); 734 735 rect = BRect(290,215,387,230); 736 stringView = new BStringView(rect, NULL,"Don't fade when", 737 B_FOLLOW_LEFT | B_FOLLOW_BOTTOM); 738 stringView->ResizeToPreferred(); 739 box->AddChild(stringView); 740 741 rect.OffsetBy(0, stringView->Bounds().Height()); 742 stringView = new BStringView(rect, NULL, "mouse is here", 743 B_FOLLOW_LEFT | B_FOLLOW_BOTTOM); 744 stringView->ResizeToPreferred(); 745 box->AddChild(stringView); 746 } 747 748 749 void 750 ScreenSaverWindow::_UpdateTurnOffScreen() 751 { 752 bool enabled = (fSettings.TimeFlags() & ENABLE_DPMS_MASK) != 0; 753 754 BScreen screen(this); 755 uint32 dpmsCapabilities = screen.DPMSCapabilites(); 756 757 fTurnOffScreenFlags = 0; 758 if (dpmsCapabilities & B_DPMS_OFF) 759 fTurnOffScreenFlags |= ENABLE_DPMS_OFF; 760 if (dpmsCapabilities & B_DPMS_STAND_BY) 761 fTurnOffScreenFlags |= ENABLE_DPMS_STAND_BY; 762 if (dpmsCapabilities & B_DPMS_SUSPEND) 763 fTurnOffScreenFlags |= ENABLE_DPMS_SUSPEND; 764 765 fTurnOffCheckBox->SetValue(enabled && fTurnOffScreenFlags != 0 766 ? B_CONTROL_ON : B_CONTROL_OFF); 767 } 768 769 770 void 771 ScreenSaverWindow::_UpdateStatus() 772 { 773 DisableUpdates(); 774 775 bool enabled = fEnableCheckBox->Value() == B_CONTROL_ON; 776 fPasswordCheckBox->SetEnabled(enabled); 777 fTurnOffCheckBox->SetEnabled(enabled && fTurnOffScreenFlags != 0); 778 fRunSlider->SetEnabled(enabled); 779 fTurnOffSlider->SetEnabled(enabled && fTurnOffCheckBox->Value()); 780 fPasswordSlider->SetEnabled(enabled && fPasswordCheckBox->Value()); 781 fPasswordButton->SetEnabled(enabled && fPasswordCheckBox->Value()); 782 783 EnableUpdates(); 784 785 // Update the saved preferences 786 fSettings.SetWindowFrame(Frame()); 787 fSettings.SetWindowTab(fTabView->Selection()); 788 fSettings.SetTimeFlags((enabled ? ENABLE_SAVER : 0) 789 | (fTurnOffCheckBox->Value() ? fTurnOffScreenFlags : 0)); 790 fSettings.SetBlankTime(fRunSlider->Time()); 791 bigtime_t offTime = fTurnOffSlider->Time() - fSettings.BlankTime(); 792 fSettings.SetOffTime(offTime); 793 fSettings.SetSuspendTime(offTime); 794 fSettings.SetStandByTime(offTime); 795 fSettings.SetBlankCorner(fFadeNow->Corner()); 796 fSettings.SetNeverBlankCorner(fFadeNever->Corner()); 797 fSettings.SetLockEnable(fPasswordCheckBox->Value()); 798 fSettings.SetPasswordTime(fPasswordSlider->Time()); 799 800 // TODO - Tell the password window to update its stuff 801 } 802 803 804 void 805 ScreenSaverWindow::SetMinimalSizeLimit(float width, float height) 806 { 807 if (width < fMinWidth) 808 width = fMinWidth; 809 if (height < fMinHeight) 810 height = fMinHeight; 811 812 SetSizeLimits(width, 32767, height, 32767); 813 } 814 815 816 void 817 ScreenSaverWindow::MessageReceived(BMessage *msg) 818 { 819 switch (msg->what) { 820 // "Fade" tab 821 822 case kMsgRunSliderChanged: 823 if (fRunSlider->Value() > fTurnOffSlider->Value()) 824 fTurnOffSlider->SetValue(fRunSlider->Value()); 825 826 if (fRunSlider->Value() > fPasswordSlider->Value()) 827 fPasswordSlider->SetValue(fRunSlider->Value()); 828 break; 829 830 case kMsgTurnOffCheckBox: 831 fTurnOffSlider->SetEnabled(fTurnOffCheckBox->Value() == B_CONTROL_ON); 832 break; 833 834 case kMsgTurnOffSliderChanged: 835 if (fRunSlider->Value() > fTurnOffSlider->Value()) 836 fRunSlider->SetValue(fTurnOffSlider->Value()); 837 break; 838 839 case kMsgPasswordSliderChanged: 840 if (fPasswordSlider->Value() < fRunSlider->Value()) 841 fRunSlider->SetValue(fPasswordSlider->Value()); 842 break; 843 844 case kMsgPasswordCheckBox: 845 case kMsgEnableScreenSaverBox: 846 case kMsgFadeCornerChanged: 847 case kMsgNeverFadeCornerChanged: 848 _UpdateStatus(); 849 fSettings.Save(); 850 break; 851 852 case kMsgChangePassword: 853 fPasswordWindow->Show(); 854 break; 855 856 // "Modules" tab 857 858 case kMsgUpdateList: 859 fModulesView->PopulateScreenSaverList(); 860 break; 861 } 862 BWindow::MessageReceived(msg); 863 } 864 865 866 void 867 ScreenSaverWindow::ScreenChanged(BRect frame, color_space colorSpace) 868 { 869 _UpdateTurnOffScreen(); 870 } 871 872 873 bool 874 ScreenSaverWindow::QuitRequested() 875 { 876 _UpdateStatus(); 877 fModulesView->SaveState(); 878 fSettings.Save(); 879 880 be_app->PostMessage(B_QUIT_REQUESTED); 881 return true; 882 } 883 884