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 <Catalog.h>
15 #include <ControlLook.h>
16 #include <Font.h>
17 #include <LayoutBuilder.h>
18 #include <Screen.h>
19 #include <ScreenSaver.h>
20 #include <Shelf.h>
21 #include <String.h>
22 #include <StringView.h>
23 #include <View.h>
24 #include <Window.h>
25 #include <Debug.h>
26
27
28 #undef B_TRANSLATION_CONTEXT
29 #define B_TRANSLATION_CONTEXT "Shelf Screen Saver"
30
31
32 const rgb_color kMediumBlue = {0, 0, 100};
33 const rgb_color kWhite = {255, 255, 255};
34
35 const char *kInConfigName = "InConfig";
36 const char *kShelfArchiveName = "Shelf";
37
38
39 // Inspired by the classic BeOS screensaver, of course
40 class Shelf : public BScreenSaver
41 {
42 public:
43 Shelf(BMessage *archive, image_id);
44 void Draw(BView *view, int32 frame);
45 void StartConfig(BView *view);
46 void StopConfig();
47 status_t StartSaver(BView *view, bool preview);
48 void StopSaver();
49 status_t SaveState(BMessage *state) const;
50
51 private:
52 BShelf *fShelf;
53 BWindow *fConfigWindow;
54 bool fInConfig;
55 bool fInEdit;
56 BMallocIO fShelfData;
57 };
58
59
instantiate_screen_saver(BMessage * msg,image_id image)60 BScreenSaver *instantiate_screen_saver(BMessage *msg, image_id image)
61 {
62 PRINT(("%s()\n", __FUNCTION__));
63 return new Shelf(msg, image);
64 }
65
66
Shelf(BMessage * archive,image_id id)67 Shelf::Shelf(BMessage *archive, image_id id)
68 : BScreenSaver(archive, id)
69 , fShelf(NULL)
70 , fConfigWindow(NULL)
71 , fInConfig(false)
72 , fInEdit(false)
73 , fShelfData()
74 {
75 archive->PrintToStream();
76 if (archive->FindBool(kInConfigName, &fInConfig) < B_OK)
77 fInConfig = false;
78
79 status_t status;
80 const void *data;
81 ssize_t length;
82
83 status = archive->FindData(kShelfArchiveName, 'shlf', &data, &length);
84 if (status == B_OK) {
85 fShelfData.WriteAt(0LL, data, length);
86 fShelfData.Seek(SEEK_SET, 0LL);
87 }
88
89
90 /*
91 if (fInConfig) {
92 fInEdit = true;
93 fInConfig = false;
94 }
95 */}
96
97
98 void
StartConfig(BView * view)99 Shelf::StartConfig(BView *view)
100 {
101 PRINT(("%p:%s()\n", this, __FUNCTION__));
102 fInConfig = true;
103
104 BStringView* titleString = new BStringView("Title",
105 B_TRANSLATE("Shelf"));
106 titleString->SetFont(be_bold_font);
107
108 BStringView* copyrightString = new BStringView("Copyright",
109 B_TRANSLATE("© 2012 François Revol."));
110
111 BTextView* helpText = new BTextView("Help Text");
112 helpText->MakeEditable(false);
113 helpText->SetViewColor(view->ViewColor());
114 rgb_color textColor = ui_color(B_PANEL_TEXT_COLOR);
115 helpText->SetFontAndColor(be_plain_font, B_FONT_ALL, &textColor);
116 BString help;
117 help << B_TRANSLATE("Drop replicants on the full-screen window "
118 "behind the preferences panel.");
119 //help << "\n\n";
120 //help << B_TRANSLATE("You can also drop colors.");
121 helpText->SetText(help.String());
122
123 BLayoutBuilder::Group<>(view, B_VERTICAL, B_USE_HALF_ITEM_SPACING)
124 .SetInsets(B_USE_DEFAULT_SPACING)
125 .Add(titleString)
126 .Add(copyrightString)
127 .AddStrut(roundf(be_control_look->DefaultItemSpacing() / 2))
128 .Add(helpText)
129 .AddGlue()
130 .End();
131
132 BScreen screen;
133 fConfigWindow = new BWindow(screen.Frame(), "Shelf Config",
134 B_UNTYPED_WINDOW, B_NOT_MOVABLE | B_NOT_CLOSABLE | B_NOT_ZOOMABLE
135 | B_NOT_MINIMIZABLE | B_NOT_RESIZABLE | B_AVOID_FRONT | B_AVOID_FOCUS);
136
137 BView *shelfView = new BView(fConfigWindow->Bounds(), "ShelfView",
138 B_FOLLOW_NONE, B_WILL_DRAW | B_FRAME_EVENTS);
139 shelfView->SetViewColor(216, 216, 216, 0);
140
141 fConfigWindow->AddChild(shelfView);
142
143 fShelfData.Seek(SEEK_SET, 0LL);
144 fShelf = new BShelf(&fShelfData, shelfView);
145 fShelf->SetDisplaysZombies(true);
146 fShelfData.Seek(SEEK_SET, 0LL);
147
148 // start the Looper
149 fConfigWindow->Show();
150
151 fConfigWindow->Lock();
152 fConfigWindow->SendBehind(view->Window());
153 fConfigWindow->Unlock();
154
155 //"\nDrop replicants on me!"
156 }
157
158
159 void
StopConfig()160 Shelf::StopConfig()
161 {
162 fInConfig = false;
163 PRINT(("%p:%s()\n", this, __FUNCTION__));
164 fConfigWindow->Lock();
165 fConfigWindow->Quit();
166 fShelf = NULL;
167
168 BScreenSaver::StopConfig();
169 }
170
171
172 status_t
StartSaver(BView * view,bool preview)173 Shelf::StartSaver(BView *view, bool preview)
174 {
175 PRINT(("%p:%s(, %d)\n", this, __FUNCTION__, preview));
176 if (!preview) {
177 view->SetViewColor(216, 216, 216, 0);
178 fShelfData.Seek(SEEK_SET, 0LL);
179 fShelf = new BShelf(&fShelfData, view);
180
181 }
182 BString s;
183 s << "preview: " << preview << " ";
184 s << "BView:Name: " << view->Name() << " ";
185 s << "BApp:Name: " << be_app->Name();
186
187 PRINT(("%p:%s:%s\n", this, __FUNCTION__, s.String()));
188 //BAlert *a = new BAlert("debug", s.String(), "OK");
189 //a->Go();
190 return B_ERROR;
191 #if 0
192 float width = view->Bounds().Width();
193 float height = view->Bounds().Height();
194
195 BFont font;
196 view->GetFont(&font);
197 font.SetSize(height / 2.5);
198 view->SetFont(&font);
199
200 BRect rect;
201 escapement_delta delta;
202 delta.nonspace = 0;
203 delta.space = 0;
204 // If anyone has suggestions for how to clean this up, speak up
205 font.GetBoundingBoxesForStrings(&fLine1, 1, B_SCREEN_METRIC, &delta, &rect);
206 float y = ((height - (rect.Height() * 2 + height / 10)) / 2) + rect.Height();
207 fLine1Start.Set((width - rect.Width()) / 2, y);
208 font.GetBoundingBoxesForStrings(&fLine2, 1, B_SCREEN_METRIC, &delta, &rect);
209 fLine2Start.Set((width - rect.Width()) / 2, y + rect.Height() + height / 10);
210
211 #endif
212 return B_OK;
213 }
214
215
216 void
StopSaver()217 Shelf::StopSaver()
218 {
219 PRINT(("%p:%s()\n", this, __FUNCTION__));
220 //if (fShelf)
221 //delete fShelf;
222 //fShelf = NULL;
223 }
224
225
226 status_t
SaveState(BMessage * state) const227 Shelf::SaveState(BMessage *state) const
228 {
229 status_t status;
230
231 PRINT(("%p:%s()\n", this, __FUNCTION__));
232 state->PrintToStream();
233
234 if (fInConfig)
235 state->AddBool(kInConfigName, fInConfig);
236 if (!fInConfig)
237 state->RemoveData(kInConfigName);
238 if (fInConfig && fShelf) {
239 status = state->AddBool("got it", true);
240
241 fShelf->LockLooper();
242 status = fShelf->Save();
243 fShelf->UnlockLooper();
244 if (status < B_OK)
245 return status;
246 status = state->AddData(kShelfArchiveName, 'shlf', fShelfData.Buffer(),
247 fShelfData.BufferLength());
248
249 // return B_OK;
250 //fShelfData.SetSize(0LL);
251 #if 0
252 BMallocIO mio;
253 status = fShelf->SetSaveLocation(&mio);
254 if (status < B_OK)
255 return status;
256 status = fShelf->Save();
257 fShelf->SetSaveLocation((BDataIO *)NULL);
258 if (status < B_OK)
259 return status;
260 status = state->AddData(kShelfArchiveName, 'shlf', mio.Buffer(),
261 mio.BufferLength());
262 #endif
263 if (status < B_OK)
264 return status;
265 }
266 return B_OK;
267 }
268
269
270 void
Draw(BView * view,int32 frame)271 Shelf::Draw(BView *view, int32 frame)
272 {
273 PRINT(("%p:%s(, %" B_PRId32 ")\n", this, __FUNCTION__, frame));
274 BScreenSaver::Draw(view, frame);
275 #if 0
276 if (frame == 0) {
277 // fill with blue on first frame
278 view->SetLowColor(kMediumBlue);
279 view->FillRect(view->Bounds(), B_SOLID_LOW);
280
281 // Set tick size to 500,000 microseconds = 0.5 second
282 SetTickSize(500000);
283 } else {
284 // Drawing the background color every other frame to make the text blink
285 if (frame % 2 == 1)
286 view->SetHighColor(kWhite);
287 else
288 view->SetHighColor(kMediumBlue);
289
290 view->DrawString(fLine1, fLine1Start);
291 view->DrawString(fLine2, fLine2Start);
292 }
293 #endif
294 }
295
296
297