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, ScreenSaverPrefs& prefs); 80 81 virtual void AttachedToWindow(); 82 }; 83 84 class ModulesView : public BView { 85 public: 86 ModulesView(BRect frame, const char* name, ScreenSaverPrefs& prefs); 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 ScreenSaverPrefs& fPrefs; 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, ScreenSaverPrefs& prefs) 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, ScreenSaverPrefs& prefs) 260 : BView(rect, name, B_FOLLOW_ALL, B_WILL_DRAW), 261 fPrefs(prefs), 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 fPrefs.SetModuleName(""); 364 else 365 fPrefs.SetModuleName(item->Text()); 366 367 _CloseSaver(); 368 _OpenSaver(); 369 break; 370 } 371 372 case kMsgTestSaver: 373 SaveState(); 374 fPrefs.SaveSettings(); 375 376 be_roster->Launch(SCREEN_BLANKER_SIG, &fPrefs.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 fPrefs.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(fPrefs.ModuleName(), item->Text()) 437 || (!strcmp(fPrefs.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 = fPrefs.ModuleName(); 502 fSaverRunner = new ScreenSaverRunner(Window(), view, true, fPrefs); 503 BScreenSaver* saver = _ScreenSaver(); 504 505 BRect rect = fSettingsBox->Bounds().InsetByCopy(4, 4); 506 #ifdef __HAIKU__ 507 rect.top += fSettingsBox->TopBorderOffset(); 508 #else 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", fPrefs.ModuleName()[0] 525 ? fPrefs.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 || !fPrefs.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 fPrefs.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", fPrefs); 606 607 fTabView->AddTab(fFadeView); 608 fTabView->AddTab(fModulesView); 609 background->AddChild(fTabView); 610 611 // Create the password editing window 612 fPasswordWindow = new PasswordWindow(fPrefs); 613 fPasswordWindow->Run(); 614 615 // TODO: better limits! 616 fMinWidth = 430; 617 fMinHeight = 325; 618 SetMinimalSizeLimit(fMinWidth, fMinHeight); 619 MoveTo(fPrefs.WindowFrame().left, fPrefs.WindowFrame().top); 620 ResizeTo(fPrefs.WindowFrame().Width(), fPrefs.WindowFrame().Height()); 621 622 fEnableCheckBox->SetValue(fPrefs.TimeFlags() & ENABLE_SAVER ? B_CONTROL_ON : B_CONTROL_OFF); 623 fRunSlider->SetTime(fPrefs.BlankTime()); 624 fTurnOffSlider->SetTime(fPrefs.OffTime() + fPrefs.BlankTime()); 625 fFadeNow->SetCorner(fPrefs.GetBlankCorner()); 626 fFadeNever->SetCorner(fPrefs.GetNeverBlankCorner()); 627 fPasswordCheckBox->SetValue(fPrefs.LockEnable()); 628 fPasswordSlider->SetTime(fPrefs.PasswordTime()); 629 630 fTabView->Select(fPrefs.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", fPrefs); 647 648 /* 649 font_height fontHeight; 650 be_plain_font->GetHeight(&fontHeight); 651 float lineHeight = ceilf(fontHeight.ascent + fontHeight.descent); 652 */ 653 fEnableCheckBox = new BCheckBox(BRect(0, 0, 1, 1), "EnableCheckBox", 654 "Enable Screen Saver", new BMessage(kMsgEnableScreenSaverBox)); 655 fEnableCheckBox->ResizeToPreferred(); 656 657 rect.InsetBy(8, 8); 658 BBox* box = new BBox(rect, "EnableScreenSaverBox", B_FOLLOW_ALL); 659 box->SetLabel(fEnableCheckBox); 660 fFadeView->AddChild(box); 661 662 // Run Module 663 rect.top = fEnableCheckBox->Bounds().bottom + 8.0f; 664 BStringView* stringView = new BStringView(rect, NULL, "Run module"); 665 stringView->ResizeToPreferred(); 666 box->AddChild(stringView); 667 668 float topEdge = rect.top; 669 fRunSlider = new TimeSlider(BRect(135, topEdge, 420, topEdge + 20), 670 "RunSlider", kMsgRunSliderChanged); 671 float width, height; 672 fRunSlider->GetPreferredSize(&width, &height); 673 fRunSlider->ResizeTo(fRunSlider->Bounds().Width(), height); 674 box->AddChild(fRunSlider); 675 676 // Turn Off 677 topEdge += fRunSlider->Bounds().Height() + 4.0f; 678 fTurnOffCheckBox = new BCheckBox(BRect(20, topEdge-2, 127, topEdge + 20), 679 "TurnOffScreenCheckBox", "Turn off screen", new BMessage(kMsgTurnOffCheckBox)); 680 fTurnOffCheckBox->ResizeToPreferred(); 681 box->AddChild(fTurnOffCheckBox); 682 683 fTurnOffSlider = new TimeSlider(BRect(135, topEdge, 420, topEdge + 20), 684 "TurnOffSlider", kMsgTurnOffSliderChanged); 685 fTurnOffSlider->ResizeTo(fTurnOffSlider->Bounds().Width(), height); 686 box->AddChild(fTurnOffSlider); 687 688 // Password 689 topEdge += fTurnOffSlider->Bounds().Height() + 4.0f; 690 fPasswordCheckBox = new BCheckBox(BRect(20, topEdge - 2, 127, topEdge + 20), 691 "PasswordCheckbox", "Password lock", new BMessage(kMsgPasswordCheckBox)); 692 fPasswordCheckBox->ResizeToPreferred(); 693 box->AddChild(fPasswordCheckBox); 694 695 fPasswordSlider = new TimeSlider(BRect(135, topEdge, 420, topEdge + 20), 696 "PasswordSlider", kMsgPasswordSliderChanged); 697 fPasswordSlider->ResizeTo(fPasswordSlider->Bounds().Width(), height); 698 box->AddChild(fPasswordSlider); 699 700 topEdge += fPasswordSlider->Bounds().Height() + 4.0f; 701 fPasswordButton = new BButton(BRect(390, topEdge, 410, topEdge + 24), "PasswordButton", 702 "Password" B_UTF8_ELLIPSIS, new BMessage(kMsgChangePassword)); 703 fPasswordButton->ResizeToPreferred(); 704 fPasswordButton->MoveBy(-fPasswordButton->Bounds().Width(), 0); 705 box->AddChild(fPasswordButton); 706 707 // Bottom 708 709 box->AddChild(fFadeNow = new ScreenCornerSelector(BRect(20,205,80,260),"fadeNow", 710 B_FOLLOW_LEFT | B_FOLLOW_BOTTOM)); 711 box->AddChild(fFadeNever = new ScreenCornerSelector(BRect(220,205,280,260),"fadeNever", 712 B_FOLLOW_LEFT | B_FOLLOW_BOTTOM)); 713 714 stringView = new BStringView(BRect(90,215,193,230), 715 "FadeNowString", "Fade now when", B_FOLLOW_LEFT | B_FOLLOW_BOTTOM); 716 box->AddChild(stringView); 717 718 stringView = new BStringView(BRect(90,233,193,248), 719 "FadeNowString2","mouse is here", B_FOLLOW_LEFT | B_FOLLOW_BOTTOM); 720 box->AddChild(stringView); 721 722 stringView = new BStringView(BRect(290,215,387,230), 723 "DontFadeString","Don't fade when", B_FOLLOW_LEFT | B_FOLLOW_BOTTOM); 724 box->AddChild(stringView); 725 726 stringView = new BStringView(BRect(290,233,387,248), 727 "DontFadeString2","mouse is here", B_FOLLOW_LEFT | B_FOLLOW_BOTTOM); 728 box->AddChild(stringView); 729 } 730 731 732 void 733 ScreenSaverWindow::_UpdateTurnOffScreen() 734 { 735 bool enabled = (fPrefs.TimeFlags() & ENABLE_DPMS_MASK) != 0; 736 737 BScreen screen(this); 738 uint32 dpmsCapabilities = screen.DPMSCapabilites(); 739 740 fTurnOffScreenFlags = 0; 741 if (dpmsCapabilities & B_DPMS_OFF) 742 fTurnOffScreenFlags |= ENABLE_DPMS_OFF; 743 if (dpmsCapabilities & B_DPMS_STAND_BY) 744 fTurnOffScreenFlags |= ENABLE_DPMS_STAND_BY; 745 if (dpmsCapabilities & B_DPMS_SUSPEND) 746 fTurnOffScreenFlags |= ENABLE_DPMS_SUSPEND; 747 748 fTurnOffCheckBox->SetValue(enabled && fTurnOffScreenFlags != 0 749 ? B_CONTROL_ON : B_CONTROL_OFF); 750 } 751 752 753 void 754 ScreenSaverWindow::_UpdateStatus() 755 { 756 DisableUpdates(); 757 758 bool enabled = fEnableCheckBox->Value() == B_CONTROL_ON; 759 fPasswordCheckBox->SetEnabled(enabled); 760 fTurnOffCheckBox->SetEnabled(enabled && fTurnOffScreenFlags != 0); 761 fRunSlider->SetEnabled(enabled); 762 fTurnOffSlider->SetEnabled(enabled && fTurnOffCheckBox->Value()); 763 fPasswordSlider->SetEnabled(enabled && fPasswordCheckBox->Value()); 764 fPasswordButton->SetEnabled(enabled && fPasswordCheckBox->Value()); 765 766 EnableUpdates(); 767 768 // Update the saved preferences 769 fPrefs.SetWindowFrame(Frame()); 770 fPrefs.SetWindowTab(fTabView->Selection()); 771 fPrefs.SetTimeFlags((enabled ? ENABLE_SAVER : 0) 772 | (fTurnOffCheckBox->Value() ? fTurnOffScreenFlags : 0)); 773 fPrefs.SetBlankTime(fRunSlider->Time()); 774 bigtime_t offTime = fTurnOffSlider->Time() - fPrefs.BlankTime(); 775 fPrefs.SetOffTime(offTime); 776 fPrefs.SetSuspendTime(offTime); 777 fPrefs.SetStandByTime(offTime); 778 fPrefs.SetBlankCorner(fFadeNow->Corner()); 779 fPrefs.SetNeverBlankCorner(fFadeNever->Corner()); 780 fPrefs.SetLockEnable(fPasswordCheckBox->Value()); 781 fPrefs.SetPasswordTime(fPasswordSlider->Time()); 782 783 // TODO - Tell the password window to update its stuff 784 } 785 786 787 void 788 ScreenSaverWindow::SetMinimalSizeLimit(float width, float height) 789 { 790 if (width < fMinWidth) 791 width = fMinWidth; 792 if (height < fMinHeight) 793 height = fMinHeight; 794 795 SetSizeLimits(width, 32767, height, 32767); 796 } 797 798 799 void 800 ScreenSaverWindow::MessageReceived(BMessage *msg) 801 { 802 switch (msg->what) { 803 // "Fade" tab 804 805 case kMsgRunSliderChanged: 806 if (fRunSlider->Value() > fTurnOffSlider->Value()) 807 fTurnOffSlider->SetValue(fRunSlider->Value()); 808 809 if (fRunSlider->Value() > fPasswordSlider->Value()) 810 fPasswordSlider->SetValue(fRunSlider->Value()); 811 break; 812 813 case kMsgTurnOffCheckBox: 814 fTurnOffSlider->SetEnabled(fTurnOffCheckBox->Value() == B_CONTROL_ON); 815 break; 816 817 case kMsgTurnOffSliderChanged: 818 if (fRunSlider->Value() > fTurnOffSlider->Value()) 819 fRunSlider->SetValue(fTurnOffSlider->Value()); 820 break; 821 822 case kMsgPasswordSliderChanged: 823 if (fPasswordSlider->Value() < fRunSlider->Value()) 824 fRunSlider->SetValue(fPasswordSlider->Value()); 825 break; 826 827 case kMsgPasswordCheckBox: 828 case kMsgEnableScreenSaverBox: 829 _UpdateStatus(); 830 break; 831 832 case kMsgChangePassword: 833 fPasswordWindow->Show(); 834 break; 835 836 // "Modules" tab 837 838 case kMsgUpdateList: 839 fModulesView->PopulateScreenSaverList(); 840 break; 841 } 842 BWindow::MessageReceived(msg); 843 } 844 845 846 void 847 ScreenSaverWindow::ScreenChanged(BRect frame, color_space colorSpace) 848 { 849 _UpdateTurnOffScreen(); 850 } 851 852 853 bool 854 ScreenSaverWindow::QuitRequested() 855 { 856 _UpdateStatus(); 857 fModulesView->SaveState(); 858 fPrefs.SaveSettings(); 859 860 be_app->PostMessage(B_QUIT_REQUESTED); 861 return true; 862 } 863 864