xref: /haiku/src/add-ons/screen_savers/shelf/Shelf.cpp (revision 2510baa4685f8f570c607ceedfd73473d69342c4)
1 /*
2  * Copyright 2007-2012, Haiku, Inc. All Rights Reserved.
3  * Distributed under the terms of the MIT License.
4  *
5  * Authors:
6  *		Ryan Leavengood
7  *		François Revol <revol@free.fr>
8  */
9 
10 
11 #include <Application.h>
12 #include <Alert.h>
13 #include <Button.h>
14 #include <Font.h>
15 #include <Screen.h>
16 #include <ScreenSaver.h>
17 #include <Shelf.h>
18 #include <String.h>
19 #include <StringView.h>
20 #include <View.h>
21 #include <Window.h>
22 #include <Debug.h>
23 
24 
25 const rgb_color kMediumBlue = {0, 0, 100};
26 const rgb_color kWhite = {255, 255, 255};
27 
28 const char *kInConfigName = "InConfig";
29 const char *kShelfArchiveName = "Shelf";
30 
31 
32 // Inspired by the classic BeOS screensaver, of course
33 class Shelf : public BScreenSaver
34 {
35 	public:
36 					Shelf(BMessage *archive, image_id);
37 		void		Draw(BView *view, int32 frame);
38 		void		StartConfig(BView *view);
39 		void		StopConfig();
40 		status_t	StartSaver(BView *view, bool preview);
41 		void		StopSaver();
42 		status_t	SaveState(BMessage *state) const;
43 
44 	private:
45 		BShelf		*fShelf;
46 		BWindow		*fConfigWindow;
47 		bool		fInConfig;
48 		bool		fInEdit;
49 		BMallocIO	fShelfData;
50 };
51 
52 
53 BScreenSaver *instantiate_screen_saver(BMessage *msg, image_id image)
54 {
55 	PRINT(("%s()\n", __FUNCTION__));
56 	return new Shelf(msg, image);
57 }
58 
59 
60 Shelf::Shelf(BMessage *archive, image_id id)
61  :	BScreenSaver(archive, id)
62  ,	fShelf(NULL)
63  ,	fConfigWindow(NULL)
64  ,	fInConfig(false)
65  ,	fInEdit(false)
66  ,	fShelfData()
67 {
68 	archive->PrintToStream();
69 	if (archive->FindBool(kInConfigName, &fInConfig) < B_OK)
70 		fInConfig = false;
71 
72 	status_t status;
73 	const void *data;
74 	ssize_t length;
75 
76 	status = archive->FindData(kShelfArchiveName, 'shlf', &data, &length);
77 	if (status == B_OK) {
78 		fShelfData.WriteAt(0LL, data, length);
79 		fShelfData.Seek(SEEK_SET, 0LL);
80 	}
81 
82 
83 /*
84 	if (fInConfig) {
85 		fInEdit = true;
86 		fInConfig = false;
87 	}
88 */}
89 
90 
91 void
92 Shelf::StartConfig(BView *view)
93 {
94 	PRINT(("%p:%s()\n", this, __FUNCTION__));
95 	fInConfig = true;
96 	view->AddChild(new BStringView(BRect(20, 10, 200, 35), "",
97 		"Shelf, by François Revol."));
98 
99 	BScreen screen;
100 	fConfigWindow = new BWindow(screen.Frame(), "Shelf Config",
101 		B_UNTYPED_WINDOW, B_NOT_MOVABLE | B_NOT_CLOSABLE | B_NOT_ZOOMABLE
102 		| B_NOT_MINIMIZABLE | B_NOT_RESIZABLE | B_AVOID_FRONT | B_AVOID_FOCUS);
103 
104 	BView *shelfView = new BView(fConfigWindow->Bounds(), "ShelfView",
105 		B_FOLLOW_NONE, B_WILL_DRAW | B_FRAME_EVENTS);
106 	shelfView->SetViewColor(216, 216, 216, 0);
107 
108 	fConfigWindow->AddChild(shelfView);
109 
110 	fShelfData.Seek(SEEK_SET, 0LL);
111 	fShelf = new BShelf(&fShelfData, shelfView);
112 	fShelf->SetDisplaysZombies(true);
113 	fShelfData.Seek(SEEK_SET, 0LL);
114 
115 	// start the Looper
116 	fConfigWindow->Show();
117 
118 	fConfigWindow->Lock();
119 	fConfigWindow->SendBehind(view->Window());
120 	fConfigWindow->Unlock();
121 
122 	//"\nDrop replicants on me!"
123 }
124 
125 
126 void
127 Shelf::StopConfig()
128 {
129 	fInConfig = false;
130 	PRINT(("%p:%s()\n", this, __FUNCTION__));
131 	fConfigWindow->Lock();
132 	fConfigWindow->Quit();
133 	fShelf = NULL;
134 
135 	BScreenSaver::StopConfig();
136 }
137 
138 
139 status_t
140 Shelf::StartSaver(BView *view, bool preview)
141 {
142 	PRINT(("%p:%s(, %d)\n", this, __FUNCTION__, preview));
143 	if (!preview) {
144 		view->SetViewColor(216, 216, 216, 0);
145 		fShelfData.Seek(SEEK_SET, 0LL);
146 		fShelf = new BShelf(&fShelfData, view);
147 
148 	}
149 	BString s;
150 	s << "preview: " << preview << " ";
151 	s << "BView:Name: " << view->Name() << " ";
152 	s << "BApp:Name: " << be_app->Name();
153 
154 	PRINT(("%p:%s:%s\n", this, __FUNCTION__, s.String()));
155 	//BAlert *a = new BAlert("debug", s.String(), "Ok");
156 	//a->Go();
157 	return B_ERROR;
158 #if 0
159 	float width = view->Bounds().Width();
160 	float height = view->Bounds().Height();
161 
162 	BFont font;
163 	view->GetFont(&font);
164 	font.SetSize(height / 2.5);
165 	view->SetFont(&font);
166 
167 	BRect rect;
168 	escapement_delta delta;
169 	delta.nonspace = 0;
170 	delta.space = 0;
171 	// If anyone has suggestions for how to clean this up, speak up
172 	font.GetBoundingBoxesForStrings(&fLine1, 1, B_SCREEN_METRIC, &delta, &rect);
173 	float y = ((height - (rect.Height() * 2 + height / 10)) / 2) + rect.Height();
174 	fLine1Start.Set((width - rect.Width()) / 2, y);
175 	font.GetBoundingBoxesForStrings(&fLine2, 1, B_SCREEN_METRIC, &delta, &rect);
176 	fLine2Start.Set((width - rect.Width()) / 2, y + rect.Height() + height / 10);
177 
178 #endif
179 	return B_OK;
180 }
181 
182 
183 void
184 Shelf::StopSaver()
185 {
186 	PRINT(("%p:%s()\n", this, __FUNCTION__));
187 	//if (fShelf)
188 		//delete fShelf;
189 	//fShelf = NULL;
190 }
191 
192 
193 status_t
194 Shelf::SaveState(BMessage *state) const
195 {
196 	status_t status;
197 
198 	PRINT(("%p:%s()\n", this, __FUNCTION__));
199 	state->PrintToStream();
200 
201 	if (fInConfig)
202 		state->AddBool(kInConfigName, fInConfig);
203 	if (!fInConfig)
204 		state->RemoveData(kInConfigName);
205 	if (fInConfig && fShelf) {
206 		status = state->AddBool("got it", true);
207 
208 		fShelf->LockLooper();
209 		status = fShelf->Save();
210 		fShelf->UnlockLooper();
211 		if (status < B_OK)
212 			return status;
213 		status = state->AddData(kShelfArchiveName, 'shlf', fShelfData.Buffer(),
214 			fShelfData.BufferLength());
215 
216 //		return B_OK;
217 //fShelfData.SetSize(0LL);
218 #if 0
219 		BMallocIO mio;
220 		status = fShelf->SetSaveLocation(&mio);
221 		if (status < B_OK)
222 			return status;
223 		status = fShelf->Save();
224 		fShelf->SetSaveLocation((BDataIO *)NULL);
225 		if (status < B_OK)
226 			return status;
227 		status = state->AddData(kShelfArchiveName, 'shlf', mio.Buffer(),
228 			mio.BufferLength());
229 #endif
230 		if (status < B_OK)
231 			return status;
232 	}
233 	return B_OK;
234 }
235 
236 
237 void
238 Shelf::Draw(BView *view, int32 frame)
239 {
240 	PRINT(("%p:%s(, %d)\n", this, __FUNCTION__, frame));
241 	BScreenSaver::Draw(view, frame);
242 #if 0
243 	if (frame == 0) {
244 		// fill with blue on first frame
245 		view->SetLowColor(kMediumBlue);
246 		view->FillRect(view->Bounds(), B_SOLID_LOW);
247 
248 		// Set tick size to 500,000 microseconds = 0.5 second
249 		SetTickSize(500000);
250 	} else {
251 		// Drawing the background color every other frame to make the text blink
252 		if (frame % 2 == 1)
253 			view->SetHighColor(kWhite);
254 		else
255 			view->SetHighColor(kMediumBlue);
256 
257 		view->DrawString(fLine1, fLine1Start);
258 		view->DrawString(fLine2, fLine2Start);
259 	}
260 #endif
261 }
262 
263 
264