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 "MouseAreaView.h" 13 #include "PreviewView.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 / 60; 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 fFadeNowString(NULL), 589 fFadeNowString2(NULL), 590 fDontFadeString(NULL), 591 fDontFadeString2(NULL), 592 fFadeNow(NULL), 593 fFadeNever(NULL) 594 { 595 fPrefs.LoadSettings(); 596 597 BRect rect = Bounds(); 598 599 // Create a background view 600 BView *background = new BView(rect, "background", B_FOLLOW_ALL, 0); 601 background->SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR)); 602 AddChild(background); 603 604 // Add the tab view to the background 605 rect.top += 4; 606 fTabView = new BTabView(rect, "tab_view"); 607 608 // Create the controls inside the tabs 609 rect = fTabView->ContainerView()->Bounds(); 610 _SetupFadeTab(rect); 611 fModulesView = new ModulesView(rect, "Modules", fPrefs); 612 613 fTabView->AddTab(fFadeView); 614 fTabView->AddTab(fModulesView); 615 background->AddChild(fTabView); 616 617 // Create the password editing window 618 fPasswordWindow = new PasswordWindow(fPrefs); 619 fPasswordWindow->Run(); 620 621 // TODO: better limits! 622 fMinWidth = 430; 623 fMinHeight = 325; 624 SetMinimalSizeLimit(fMinWidth, fMinHeight); 625 MoveTo(fPrefs.WindowFrame().left, fPrefs.WindowFrame().top); 626 ResizeTo(fPrefs.WindowFrame().Width(), fPrefs.WindowFrame().Height()); 627 628 fEnableCheckBox->SetValue(fPrefs.TimeFlags() & ENABLE_SAVER ? B_CONTROL_ON : B_CONTROL_OFF); 629 fRunSlider->SetTime(fPrefs.BlankTime()); 630 fTurnOffSlider->SetTime(fPrefs.OffTime() + fPrefs.BlankTime()); 631 fFadeNow->SetCorner(fPrefs.GetBlankCorner()); 632 fFadeNever->SetCorner(fPrefs.GetNeverBlankCorner()); 633 fPasswordCheckBox->SetValue(fPrefs.LockEnable()); 634 fPasswordSlider->SetTime(fPrefs.PasswordTime()); 635 636 fTabView->Select(fPrefs.WindowTab()); 637 638 _UpdateTurnOffScreen(); 639 _UpdateStatus(); 640 } 641 642 643 ScreenSaverWindow::~ScreenSaverWindow() 644 { 645 } 646 647 648 //! Create the controls for the fade tab 649 void 650 ScreenSaverWindow::_SetupFadeTab(BRect rect) 651 { 652 fFadeView = new FadeView(rect, "Fade", fPrefs); 653 654 /* 655 font_height fontHeight; 656 be_plain_font->GetHeight(&fontHeight); 657 float lineHeight = ceilf(fontHeight.ascent + fontHeight.descent); 658 */ 659 fEnableCheckBox = new BCheckBox(BRect(0, 0, 1, 1), "EnableCheckBox", 660 "Enable Screen Saver", new BMessage(kMsgEnableScreenSaverBox)); 661 fEnableCheckBox->ResizeToPreferred(); 662 663 rect.InsetBy(8, 8); 664 BBox* box = new BBox(rect, "EnableScreenSaverBox", B_FOLLOW_ALL); 665 box->SetLabel(fEnableCheckBox); 666 fFadeView->AddChild(box); 667 668 // Run Module 669 rect.top = fEnableCheckBox->Bounds().bottom + 8.0f; 670 BStringView* stringView = new BStringView(rect, NULL, "Run module"); 671 stringView->ResizeToPreferred(); 672 box->AddChild(stringView); 673 674 float topEdge = rect.top; 675 fRunSlider = new TimeSlider(BRect(135, topEdge, 420, topEdge + 20), 676 "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 topEdge += fRunSlider->Bounds().Height() + 4.0f; 684 fTurnOffCheckBox = new BCheckBox(BRect(20, topEdge-2, 127, topEdge + 20), 685 "TurnOffScreenCheckBox", "Turn off screen", new BMessage(kMsgTurnOffCheckBox)); 686 fTurnOffCheckBox->ResizeToPreferred(); 687 box->AddChild(fTurnOffCheckBox); 688 689 fTurnOffSlider = new TimeSlider(BRect(135, topEdge, 420, topEdge + 20), 690 "TurnOffSlider", kMsgTurnOffSliderChanged); 691 fTurnOffSlider->ResizeTo(fTurnOffSlider->Bounds().Width(), height); 692 box->AddChild(fTurnOffSlider); 693 694 // Password 695 topEdge += fTurnOffSlider->Bounds().Height() + 4.0f; 696 fPasswordCheckBox = new BCheckBox(BRect(20, topEdge - 2, 127, topEdge + 20), 697 "PasswordCheckbox", "Password lock", new BMessage(kMsgPasswordCheckBox)); 698 fPasswordCheckBox->ResizeToPreferred(); 699 box->AddChild(fPasswordCheckBox); 700 701 fPasswordSlider = new TimeSlider(BRect(135, topEdge, 420, topEdge + 20), 702 "PasswordSlider", kMsgPasswordSliderChanged); 703 fPasswordSlider->ResizeTo(fPasswordSlider->Bounds().Width(), height); 704 box->AddChild(fPasswordSlider); 705 706 topEdge += fPasswordSlider->Bounds().Height() + 4.0f; 707 fPasswordButton = new BButton(BRect(390, topEdge, 410, topEdge + 24), "PasswordButton", 708 "Password" B_UTF8_ELLIPSIS, new BMessage(kMsgChangePassword)); 709 fPasswordButton->ResizeToPreferred(); 710 fPasswordButton->MoveBy(-fPasswordButton->Bounds().Width(), 0); 711 box->AddChild(fPasswordButton); 712 713 // Bottom 714 715 box->AddChild(fFadeNow = new MouseAreaView(BRect(20,205,80,260),"fadeNow")); 716 box->AddChild(fFadeNever = new MouseAreaView(BRect(220,205,280,260),"fadeNever")); 717 718 box->AddChild(fFadeNowString = new BStringView(BRect(90,215,193,230),"FadeNowString","Fade now when")); 719 fFadeNowString->SetText("Fade now when"); 720 fFadeNowString->SetAlignment(B_ALIGN_LEFT); 721 722 box->AddChild(fFadeNowString2 = new BStringView(BRect(90,233,193,248),"FadeNowString2","mouse is here")); 723 fFadeNowString2->SetText("mouse is here"); 724 fFadeNowString2->SetAlignment(B_ALIGN_LEFT); 725 726 box->AddChild(fDontFadeString = new BStringView(BRect(290,215,387,230),"DontFadeString","Don't fade when")); 727 fDontFadeString->SetText("Don't fade when"); 728 fDontFadeString->SetAlignment(B_ALIGN_LEFT); 729 730 box->AddChild(fDontFadeString2 = new BStringView(BRect(290,233,387,248),"DontFadeString2","mouse is here")); 731 fDontFadeString2->SetText("mouse is here"); 732 fDontFadeString2->SetAlignment(B_ALIGN_LEFT); 733 } 734 735 736 void 737 ScreenSaverWindow::_UpdateTurnOffScreen() 738 { 739 bool enabled = (fPrefs.TimeFlags() & ENABLE_DPMS_MASK) != 0; 740 741 BScreen screen(this); 742 uint32 dpmsCapabilities = screen.DPMSCapabilites(); 743 744 fTurnOffScreenFlags = 0; 745 if (dpmsCapabilities & B_DPMS_OFF) 746 fTurnOffScreenFlags |= ENABLE_DPMS_OFF; 747 if (dpmsCapabilities & B_DPMS_STAND_BY) 748 fTurnOffScreenFlags |= ENABLE_DPMS_STAND_BY; 749 if (dpmsCapabilities & B_DPMS_SUSPEND) 750 fTurnOffScreenFlags |= ENABLE_DPMS_SUSPEND; 751 752 fTurnOffCheckBox->SetValue(enabled && fTurnOffScreenFlags != 0 753 ? B_CONTROL_ON : B_CONTROL_OFF); 754 } 755 756 757 void 758 ScreenSaverWindow::_UpdateStatus() 759 { 760 DisableUpdates(); 761 762 bool enabled = fEnableCheckBox->Value() == B_CONTROL_ON; 763 fPasswordCheckBox->SetEnabled(enabled); 764 fTurnOffCheckBox->SetEnabled(enabled && fTurnOffScreenFlags != 0); 765 fRunSlider->SetEnabled(enabled); 766 fTurnOffSlider->SetEnabled(enabled && fTurnOffCheckBox->Value()); 767 fPasswordSlider->SetEnabled(enabled && fPasswordCheckBox->Value()); 768 fPasswordButton->SetEnabled(enabled && fPasswordCheckBox->Value()); 769 770 EnableUpdates(); 771 772 // Update the saved preferences 773 fPrefs.SetWindowFrame(Frame()); 774 fPrefs.SetWindowTab(fTabView->Selection()); 775 fPrefs.SetTimeFlags((enabled ? ENABLE_SAVER : 0) 776 | (fTurnOffCheckBox->Value() ? fTurnOffScreenFlags : 0)); 777 fPrefs.SetBlankTime(fRunSlider->Time()); 778 bigtime_t offTime = fTurnOffSlider->Time() - fPrefs.BlankTime(); 779 fPrefs.SetOffTime(offTime); 780 fPrefs.SetSuspendTime(offTime); 781 fPrefs.SetStandbyTime(offTime); 782 fPrefs.SetBlankCorner(fFadeNow->Corner()); 783 fPrefs.SetNeverBlankCorner(fFadeNever->Corner()); 784 fPrefs.SetLockEnable(fPasswordCheckBox->Value()); 785 fPrefs.SetPasswordTime(fPasswordSlider->Time()); 786 787 // TODO - Tell the password window to update its stuff 788 } 789 790 791 void 792 ScreenSaverWindow::SetMinimalSizeLimit(float width, float height) 793 { 794 if (width < fMinWidth) 795 width = fMinWidth; 796 if (height < fMinHeight) 797 height = fMinHeight; 798 799 SetSizeLimits(width, 32767, height, 32767); 800 } 801 802 803 void 804 ScreenSaverWindow::MessageReceived(BMessage *msg) 805 { 806 switch (msg->what) { 807 // "Fade" tab 808 809 case kMsgRunSliderChanged: 810 if (fRunSlider->Value() > fTurnOffSlider->Value()) 811 fTurnOffSlider->SetValue(fRunSlider->Value()); 812 813 if (fRunSlider->Value() > fPasswordSlider->Value()) 814 fPasswordSlider->SetValue(fRunSlider->Value()); 815 break; 816 817 case kMsgTurnOffCheckBox: 818 fTurnOffSlider->SetEnabled(fTurnOffCheckBox->Value() == B_CONTROL_ON); 819 break; 820 821 case kMsgTurnOffSliderChanged: 822 if (fRunSlider->Value() > fTurnOffSlider->Value()) 823 fRunSlider->SetValue(fTurnOffSlider->Value()); 824 break; 825 826 case kMsgPasswordSliderChanged: 827 if (fPasswordSlider->Value() < fRunSlider->Value()) 828 fRunSlider->SetValue(fPasswordSlider->Value()); 829 break; 830 831 case kMsgPasswordCheckBox: 832 case kMsgEnableScreenSaverBox: 833 _UpdateStatus(); 834 break; 835 836 case kMsgChangePassword: 837 fPasswordWindow->Show(); 838 break; 839 840 // "Modules" tab 841 842 case kMsgUpdateList: 843 fModulesView->PopulateScreenSaverList(); 844 break; 845 } 846 BWindow::MessageReceived(msg); 847 } 848 849 850 void 851 ScreenSaverWindow::ScreenChanged(BRect frame, color_space colorSpace) 852 { 853 _UpdateTurnOffScreen(); 854 } 855 856 857 bool 858 ScreenSaverWindow::QuitRequested() 859 { 860 _UpdateStatus(); 861 fModulesView->SaveState(); 862 fPrefs.SaveSettings(); 863 864 be_app->PostMessage(B_QUIT_REQUESTED); 865 return true; 866 } 867 868