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