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