1 /* 2 * Copyright 2003, Michael Phipps. All rights reserved. 3 * Distributed under the terms of the MIT License. 4 */ 5 6 #include <ListView.h> 7 #include <Application.h> 8 #include <Button.h> 9 #include <Box.h> 10 #include <Font.h> 11 #include <TabView.h> 12 #include <Directory.h> 13 #include <Entry.h> 14 #include <File.h> 15 #include <Path.h> 16 #include <ScrollView.h> 17 #include <FindDirectory.h> 18 #include <Slider.h> 19 #include <StringView.h> 20 #include <ScreenSaver.h> 21 #include <Roster.h> 22 #include <stdio.h> 23 24 #include "ScreenSaverWindow.h" 25 #include "ScreenSaverItem.h" 26 #include "MouseAreaView.h" 27 #include "PreviewView.h" 28 29 #include <Debug.h> 30 #define CALLED() PRINT(("%s\n", __PRETTY_FUNCTION__)) 31 32 static const char *kTimes[]={"30 seconds", "1 minute", "1 minute 30 seconds", 33 "2 minutes", "2 minutes 30 seconds", "3 minutes", 34 "4 minutes", "5 minutes", "6 minutes", 35 "7 minutes", "8 minutes", "9 minutes", 36 "10 minutes", "15 minutes", "20 minutes", 37 "25 minutes", "30 minutes", "40 minutes", 38 "50 minutes", "1 hour", "1 hour 30 minutes", 39 "2 hours", "2 hours 30 minutes", "3 hours", 40 "4 hours", "5 hours"}; 41 42 static const int32 kTimeInUnits[]={ 30, 60, 90, 43 120, 150, 180, 44 240, 300, 360, 45 420, 480, 540, 46 600, 900, 1200, 47 1500, 1800, 2400, 48 3000, 3600, 5400, 49 7200, 9000, 10800, 50 14400, 18000}; 51 52 const int32 PASSWORD_CHECKBOX = 'psCB'; 53 54 void drawPositionalMonitor(BView *view,BRect areaToDrawIn,int state); 55 BView *drawSampleMonitor(BView *view, BRect area); 56 57 int32 58 UnitsToSlider(bigtime_t val) 59 { 60 int count = sizeof(kTimeInUnits)/sizeof(int); 61 for (int t=0; t<count; t++) 62 if (kTimeInUnits[t]*1000000LL == val) 63 return t; 64 return -1; 65 } 66 67 68 ScreenSaverWin::ScreenSaverWin() 69 : BWindow(BRect(50,50,496,375),"OBOS Screen Saver", 70 B_TITLED_WINDOW,B_ASYNCHRONOUS_CONTROLS | B_NOT_ZOOMABLE | B_NOT_RESIZABLE) , 71 fFadeState(0),fNoFadeState(0), 72 fSelectedAddonFileName(NULL), 73 fCurrentAddon(NULL), fTestButton(NULL), 74 fTurnOffMinutes(NULL), fRunMinutes(NULL), 75 fPasswordMinutes(NULL), fPasswordButton(NULL), 76 fFadeNowString(NULL), 77 fFadeNowString2(NULL), 78 fDontFadeString(NULL), fDontFadeString2(NULL), 79 fFadeNow(NULL),fFadeNever(NULL), 80 fPwMessenger(NULL), 81 fSettingsArea(NULL) 82 { 83 SetupForm(); 84 } 85 86 87 ScreenSaverWin::~ScreenSaverWin() 88 { 89 } 90 91 92 void 93 ScreenSaverWin::SaverSelected() 94 { 95 CALLED(); 96 UpdateStatus(); 97 if (fListView1->CurrentSelection()>=0) { 98 if (fPreviewDisplay->ScreenSaver()) 99 fPreviewDisplay->ScreenSaver()->StopConfig(); 100 ScreenSaverItem* item = reinterpret_cast<ScreenSaverItem*>(fListView1->ItemAt(fListView1->CurrentSelection())); 101 BString settingsMsgName(item->Path()); 102 fPreviewDisplay->SetScreenSaver(settingsMsgName); 103 if (fSettingsArea) { 104 fModuleSettingsBox->RemoveChild(fSettingsArea); 105 delete fSettingsArea; 106 } 107 BRect bnds = fModuleSettingsBox->Bounds(); 108 bnds.InsetBy(5,10); 109 fSettingsArea = new BView(bnds,"settingsArea",B_FOLLOW_NONE,B_WILL_DRAW); 110 fSettingsArea->SetViewColor(216,216,216); 111 fModuleSettingsBox->AddChild(fSettingsArea); 112 113 if (fPreviewDisplay->ScreenSaver()) 114 fPreviewDisplay->ScreenSaver()->StartConfig(fSettingsArea); 115 } 116 } 117 118 119 void 120 ScreenSaverWin::MessageReceived(BMessage *msg) 121 { 122 switch(msg->what) { 123 case kPasswordCheckbox: 124 fPasswordSlider->SetEnabled(fPasswordCheckbox->Value()==B_CONTROL_ON); 125 break; 126 case kRunSliderChanged: 127 fRunSlider->SetLabel(kTimes[fRunSlider->Value()]); 128 if (fRunSlider->Value()>fPasswordSlider->Value()) { 129 fTurnOffSlider->SetValue(fRunSlider->Value()); 130 fTurnOffSlider->SetLabel(kTimes[fTurnOffSlider->Value()]); 131 fPasswordSlider->SetValue(fRunSlider->Value()); 132 fPasswordSlider->SetLabel(kTimes[fPasswordSlider->Value()]); 133 } 134 break; 135 case kTurnOffSliderChanged: 136 fTurnOffSlider->SetLabel(kTimes[fTurnOffSlider->Value()]); 137 break; 138 case kPasswordSliderChanged: 139 fPasswordSlider->SetLabel(kTimes[fPasswordSlider->Value()]); 140 if (fPasswordSlider->Value()<fRunSlider->Value()) { 141 fRunSlider->SetValue(fPasswordSlider->Value()); 142 fRunSlider->SetLabel(kTimes[fRunSlider->Value()]); 143 } 144 break; 145 case kPwbutton: 146 fPwMessenger->SendMessage(kShow); 147 break; 148 case B_QUIT_REQUESTED: 149 be_app->PostMessage(B_QUIT_REQUESTED); 150 break; 151 case kSaver_sel: 152 SaverSelected(); 153 break; 154 case kTest_btn: 155 { 156 BMessage *settings = fPrefs.GetSettings(); 157 be_roster->Launch("application/x-vnd.haiku-ScreenSaverApp", settings); 158 delete settings; 159 break; 160 } 161 case kAdd_btn: 162 fFilePanel->Show(); 163 break; 164 case kUpdatelist: 165 PopulateScreenSaverList(); 166 break; 167 } 168 BWindow::MessageReceived(msg); 169 } 170 171 172 bool 173 ScreenSaverWin::QuitRequested() 174 { 175 UpdateStatus(); 176 fPrefs.SaveSettings(); 177 be_app->PostMessage(B_QUIT_REQUESTED); 178 return(true); 179 } 180 181 182 void 183 ScreenSaverWin::UpdateStatus(void) 184 { 185 DisableUpdates(); 186 // Policy - enable and disable controls as per checkboxes, etc 187 fPasswordCheckbox->SetEnabled(fEnableCheckbox->Value()); 188 fTurnOffScreenCheckBox->SetEnabled(fEnableCheckbox->Value()); 189 fRunSlider->SetEnabled(fEnableCheckbox->Value()); 190 fTurnOffSlider->SetEnabled(fEnableCheckbox->Value() && fTurnOffScreenCheckBox->Value()); 191 fTurnOffSlider->SetEnabled(false); // This never seems to turn on in the R5 version 192 fTurnOffScreenCheckBox->SetEnabled(false); 193 fPasswordSlider->SetEnabled(fEnableCheckbox->Value() && fPasswordCheckbox->Value()); 194 fPasswordButton->SetEnabled(fEnableCheckbox->Value() && fPasswordCheckbox->Value()); 195 // Set the labels for the sliders 196 fRunSlider->SetLabel(kTimes[fRunSlider->Value()]); 197 fTurnOffSlider->SetLabel(kTimes[fTurnOffSlider->Value()]); 198 fPasswordSlider->SetLabel(kTimes[fPasswordSlider->Value()]); 199 EnableUpdates(); 200 // Update the saved preferences 201 fPrefs.SetWindowFrame(Frame()); 202 fPrefs.SetWindowTab(fTabView->Selection()); 203 fPrefs.SetTimeFlags(fEnableCheckbox->Value()); 204 fPrefs.SetBlankTime(1000000LL* kTimeInUnits[fRunSlider->Value()]); 205 fPrefs.SetOffTime(1000000LL* kTimeInUnits[fTurnOffSlider->Value()]); 206 fPrefs.SetSuspendTime(1000000LL* kTimeInUnits[fTurnOffSlider->Value()]); 207 fPrefs.SetStandbyTime(1000000LL* kTimeInUnits[fTurnOffSlider->Value()]); 208 fPrefs.SetBlankCorner(fFadeNow->getDirection()); 209 fPrefs.SetNeverBlankCorner(fFadeNever->getDirection()); 210 fPrefs.SetLockEnable(fPasswordCheckbox->Value()); 211 fPrefs.SetPasswordTime(1000000LL* kTimeInUnits[fPasswordSlider->Value()]); 212 int selection = fListView1->CurrentSelection(); 213 if (selection >= 0) { 214 fPrefs.SetModuleName(((ScreenSaverItem *)(fListView1->ItemAt(selection)))->Text()); 215 if (strcmp(fPrefs.ModuleName(), "Blackness") == 0) 216 fPrefs.SetModuleName(""); 217 } 218 // TODO - Tell the password window to update its stuff 219 BMessage ssState; 220 if ((fPreviewDisplay->ScreenSaver()) && (fPreviewDisplay->ScreenSaver()->SaveState(&ssState)==B_OK)) 221 fPrefs.SetState(fPrefs.ModuleName(), &ssState); 222 }; 223 224 225 void 226 ScreenSaverWin::SetupForm() 227 { 228 fFilePanel=new BFilePanel(); 229 230 BRect r = Bounds(); 231 BTab *tab; 232 233 // Create a background view 234 BView *background = new BView(r,"background",B_FOLLOW_NONE,0); 235 background->SetViewColor(216,216,216,0); 236 AddChild(background); 237 238 // Add the tab view to the background 239 r.top += 4; 240 fTabView = new BTabView(r, "tab_view"); 241 fTabView->SetViewColor(216,216,216,0); 242 r = fTabView->Bounds(); 243 r.InsetBy(0,4); 244 r.bottom -= fTabView->TabHeight(); 245 246 // Time to load the settings into a message and implement them... 247 fPrefs.LoadSettings(); 248 249 tab = new BTab(); 250 fTab2 = new BView(r,"Fade",B_FOLLOW_NONE,0); 251 fTabView->AddTab(fTab2, tab); 252 tab->SetLabel("Fade"); 253 254 tab = new BTab(); 255 fTab1 = new BView(r,"Modules",B_FOLLOW_NONE,0); 256 fTabView->AddTab(fTab1, tab); 257 tab->SetLabel("Modules"); 258 background->AddChild(fTabView); 259 260 // Create the controls inside the tabs 261 SetupTab2(); 262 SetupTab1(); 263 264 // Create the password editing window 265 fPwWin = new PasswordWindow(); 266 fPwMessenger = new BMessenger(NULL,fPwWin); 267 fPwWin->Run(); 268 269 MoveTo(fPrefs.WindowFrame().left,fPrefs.WindowFrame().top); 270 //ResizeTo(fPrefs.WindowFrame().right-fPrefs.WindowFrame().left,fPrefs.WindowFrame().bottom-fPrefs.WindowFrame().top); 271 fTabView->Select(fPrefs.WindowTab()); 272 fEnableCheckbox->SetValue(fPrefs.TimeFlags()); 273 fRunSlider->SetValue(UnitsToSlider(fPrefs.BlankTime())); 274 fTurnOffSlider->SetValue(UnitsToSlider(fPrefs.OffTime())); 275 fFadeNow->setDirection(fPrefs.GetBlankCorner()); 276 fFadeNever->setDirection(fPrefs.GetNeverBlankCorner()); 277 fPasswordCheckbox->SetValue(fPrefs.LockEnable()); 278 fPasswordSlider->SetValue(UnitsToSlider(fPrefs.PasswordTime())); 279 int32 count = fListView1->CountItems(); 280 for (int32 i=0; i<count; i++) { 281 ScreenSaverItem *item = dynamic_cast<ScreenSaverItem*>(fListView1->ItemAt(i)); 282 printf("modulename %s-%s\n", fPrefs.ModuleName(), item->Text()); 283 if ((strcmp(fPrefs.ModuleName(), item->Text()) == 0) 284 || (strcmp(fPrefs.ModuleName(),"") == 0 && strcmp(item->Text(), "Blackness") ==0)) { 285 fListView1->Select(i); 286 SaverSelected(); 287 fListView1->ScrollToSelection(); 288 break; 289 } 290 } 291 UpdateStatus(); 292 } 293 294 295 // Set the common Look and Feel stuff for a given control 296 void 297 commonLookAndFeel(BView *widget,bool isSlider,bool isControl) 298 { 299 {rgb_color clr = {216,216,216,255}; widget->SetViewColor(clr);} 300 if (isSlider) { 301 BSlider *slid=dynamic_cast<BSlider *>(widget); 302 {rgb_color clr = {160,160,160,0}; slid->SetBarColor(clr);} 303 slid->SetHashMarks(B_HASH_MARKS_NONE); 304 slid->SetHashMarkCount(0); 305 slid->SetStyle(B_TRIANGLE_THUMB); 306 slid->SetLimitLabels("",""); 307 slid->SetLimitLabels(NULL,NULL); 308 slid->SetLabel("0 minutes"); 309 slid->SetValue(0); 310 slid->SetEnabled(true); 311 } 312 {rgb_color clr = {0,0,0,0}; widget->SetHighColor(clr);} 313 widget->SetFlags(B_WILL_DRAW|B_NAVIGABLE); 314 widget->SetResizingMode(B_FOLLOW_NONE); 315 widget->SetFontSize(10); 316 widget->SetFont(be_plain_font); 317 if (isControl) { 318 BControl *wid=dynamic_cast<BControl *>(widget); 319 wid->SetEnabled(true); 320 } 321 } 322 323 324 // Iterate over a directory, adding the directories files to the list 325 void 326 addScreenSaversToList (directory_which dir, BListView *list) 327 { 328 BPath path; 329 find_directory(dir,&path); 330 path.Append("Screen Savers",true); 331 332 BDirectory ssDir(path.Path()); 333 BEntry thisSS; 334 char thisName[B_FILE_NAME_LENGTH]; 335 336 while (B_OK==ssDir.GetNextEntry(&thisSS,true)) { 337 thisSS.GetName(thisName); 338 BString pathname = path.Path(); 339 pathname += "/"; 340 pathname += thisName; 341 list->AddItem(new ScreenSaverItem(thisName, pathname.String())); 342 } 343 } 344 345 346 // sorting function for ScreenSaverItems 347 int 348 ScreenSaverWin::CompareScreenSaverItems(const void* left, const void* right) 349 { 350 ScreenSaverItem* leftItem = *(ScreenSaverItem **)left; 351 ScreenSaverItem* rightItem = *(ScreenSaverItem **)right; 352 353 return strcmp(leftItem->Text(),rightItem->Text()); 354 } 355 356 357 void 358 ScreenSaverWin::PopulateScreenSaverList(void) 359 { 360 fListView1->DeselectAll(); 361 while (void *i=fListView1->RemoveItem((int32)0)) 362 delete ((ScreenSaverItem *)i); 363 364 fListView1->AddItem(new ScreenSaverItem("Blackness", "")); 365 addScreenSaversToList(B_BEOS_ADDONS_DIRECTORY, fListView1); 366 addScreenSaversToList(B_USER_ADDONS_DIRECTORY, fListView1); 367 368 fListView1->SortItems(CompareScreenSaverItems); 369 } 370 371 372 // Create the controls for the first tab 373 void 374 ScreenSaverWin::SetupTab1() 375 { 376 int columns[4]={15,150,180,430}; 377 int rows[6]={15,120,135,255,263,280}; 378 379 {rgb_color clr = {216,216,216,255}; fTab1->SetViewColor(clr);} 380 fTab1->AddChild( fModuleSettingsBox = new BBox(BRect(columns[2],rows[0],columns[3],rows[5]),"ModuleSettingsBox",B_FOLLOW_NONE,B_WILL_DRAW)); 381 fModuleSettingsBox->SetLabel("Module settings"); 382 fModuleSettingsBox->SetBorder(B_FANCY_BORDER); 383 384 fListView1 = new BListView(BRect(columns[0],rows[2],columns[1]+3,rows[3]),"ListView1",B_SINGLE_SELECTION_LIST); 385 fTab1->AddChild(new BScrollView("scroll_list",fListView1,B_FOLLOW_NONE,0,false,true)); 386 commonLookAndFeel(fModuleSettingsBox,false,false); 387 {rgb_color clr = {255,255,255,0}; fListView1->SetViewColor(clr);} 388 fListView1->SetListType(B_SINGLE_SELECTION_LIST); 389 390 // selection message for screensaver list 391 fListView1->SetSelectionMessage( new BMessage( kSaver_sel ) ); 392 393 fTab1->AddChild( fTestButton = new BButton(BRect(columns[0],rows[4],91,rows[5]),"TestButton","Test", new BMessage (kTest_btn))); 394 commonLookAndFeel(fTestButton,false,true); 395 fTestButton->SetLabel("Test"); 396 397 fTab1->AddChild( fAddButton = new BButton(BRect(97,rows[4],columns[2]-10,rows[5]),"AddButton","Add...", new BMessage (kAdd_btn))); 398 commonLookAndFeel(fAddButton,false,true); 399 fAddButton->SetLabel("Add..."); 400 401 fTab1->AddChild(fPreviewDisplay = new PreviewView(BRect(columns[0]+5,rows[0],columns[1],rows[1]),"preview",&fPrefs)); 402 PopulateScreenSaverList(); 403 } 404 405 406 // Create the controls for the second tab 407 void 408 ScreenSaverWin::SetupTab2() 409 { 410 font_height stdFontHt; 411 be_plain_font->GetHeight(&stdFontHt); 412 int stringHeight=(int)(stdFontHt.ascent+stdFontHt.descent),sliderHeight=30; 413 int topEdge; 414 {rgb_color clr = {216,216,216,255}; fTab2->SetViewColor(clr);} 415 fTab2->AddChild( fEnableScreenSaverBox = new BBox(BRect(8,6,436,280),"EnableScreenSaverBox")); 416 commonLookAndFeel(fEnableScreenSaverBox,false,false); 417 418 fEnableCheckbox = new BCheckBox(BRect(0,0,90,stringHeight),"EnableCheckBox","Enable Screen Saver", new BMessage (kTab2_chg)); 419 fEnableScreenSaverBox->SetLabel(fEnableCheckbox); 420 fEnableScreenSaverBox->SetBorder(B_FANCY_BORDER); 421 422 // Run Module 423 topEdge=26; 424 fEnableScreenSaverBox->AddChild( fStringView1 = new BStringView(BRect(21,topEdge,101,topEdge+stringHeight),"StringView1","Run module")); 425 commonLookAndFeel(fStringView1,false,false); 426 fStringView1->SetText("Run module"); 427 fStringView1->SetAlignment(B_ALIGN_LEFT); 428 429 fEnableScreenSaverBox->AddChild( fRunSlider = new BSlider(BRect(132,topEdge,415,topEdge+sliderHeight),"RunSlider","minutes", new BMessage(kRunSliderChanged), 0, 25)); 430 fRunSlider->SetModificationMessage(new BMessage(kRunSliderChanged)); 431 commonLookAndFeel(fRunSlider,true,true); 432 float w,h; 433 fRunSlider->GetPreferredSize(&w,&h); 434 sliderHeight=(int)h; 435 436 // Turn Off 437 topEdge+=sliderHeight; 438 fEnableScreenSaverBox->AddChild( fTurnOffScreenCheckBox = new BCheckBox(BRect(9,topEdge,107,topEdge+stringHeight),"TurnOffScreenCheckBox","Turn off screen", new BMessage (kTab2_chg))); 439 commonLookAndFeel(fTurnOffScreenCheckBox,false,true); 440 fTurnOffScreenCheckBox->SetLabel("Turn off screen"); 441 fTurnOffScreenCheckBox->SetResizingMode(B_FOLLOW_NONE); 442 443 fEnableScreenSaverBox->AddChild( fTurnOffSlider = new BSlider(BRect(132,topEdge,415,topEdge+sliderHeight),"TurnOffSlider","", new BMessage(kTurnOffSliderChanged), 0, 25)); 444 fTurnOffSlider->SetModificationMessage(new BMessage(kTurnOffSliderChanged)); 445 commonLookAndFeel(fTurnOffSlider,true,true); 446 447 // Password 448 topEdge+=sliderHeight; 449 fEnableScreenSaverBox->AddChild( fPasswordCheckbox = new BCheckBox(BRect(9,topEdge,108,topEdge+stringHeight),"PasswordCheckbox","Password lock", new BMessage (kPasswordCheckbox))); 450 commonLookAndFeel(fPasswordCheckbox,false,true); 451 fPasswordCheckbox->SetLabel("Password lock"); 452 453 fEnableScreenSaverBox->AddChild( fPasswordSlider = new BSlider(BRect(132,topEdge,415,topEdge+sliderHeight),"PasswordSlider","", new BMessage(kPasswordSliderChanged), 0, 25)); 454 fPasswordSlider->SetModificationMessage(new BMessage(kPasswordSliderChanged)); 455 commonLookAndFeel(fPasswordSlider,true,true); 456 457 topEdge+=sliderHeight; 458 fEnableScreenSaverBox->AddChild( fPasswordButton = new BButton(BRect(331,topEdge,405,topEdge+25),"PasswordButton","Password...", new BMessage (kPwbutton))); 459 commonLookAndFeel(fPasswordButton,false,true); 460 fPasswordButton->SetLabel("Password..."); 461 462 // Bottom 463 464 fEnableScreenSaverBox->AddChild(fFadeNow=new MouseAreaView(BRect(20,205,80,260),"fadeNow")); 465 fEnableScreenSaverBox->AddChild(fFadeNever=new MouseAreaView(BRect(220,205,280,260),"fadeNever")); 466 467 fEnableScreenSaverBox->AddChild( fFadeNowString = new BStringView(BRect(85,210,188,222),"FadeNowString","Fade now when")); 468 commonLookAndFeel(fFadeNowString,false,false); 469 fFadeNowString->SetText("Fade now when"); 470 fFadeNowString->SetAlignment(B_ALIGN_LEFT); 471 472 fEnableScreenSaverBox->AddChild( fFadeNowString2 = new BStringView(BRect(85,225,188,237),"FadeNowString2","mouse is here")); 473 commonLookAndFeel(fFadeNowString2,false,false); 474 fFadeNowString2->SetText("mouse is here"); 475 fFadeNowString2->SetAlignment(B_ALIGN_LEFT); 476 477 fEnableScreenSaverBox->AddChild( fDontFadeString = new BStringView(BRect(285,210,382,222),"DontFadeString","Don't fade when")); 478 commonLookAndFeel(fDontFadeString,false,false); 479 fDontFadeString->SetText("Don't fade when"); 480 fDontFadeString->SetAlignment(B_ALIGN_LEFT); 481 482 fEnableScreenSaverBox->AddChild( fDontFadeString2 = new BStringView(BRect(285,225,382,237),"DontFadeString2","mouse is here")); 483 commonLookAndFeel(fDontFadeString2,false,false); 484 fDontFadeString2->SetText("mouse is here"); 485 fDontFadeString2->SetAlignment(B_ALIGN_LEFT); 486 } 487