1 /*
2 * Copyright 2014 Stephan Aßmus <superstippi@gmx.de>
3 * All rights reserved. Distributed under the terms of the MIT license.
4 */
5
6
7 #include <stdio.h>
8 #include <string.h>
9
10 #include <Application.h>
11 #include <Message.h>
12 #include <Picture.h>
13 #include <LayoutBuilder.h>
14 #include <List.h>
15 #include <PopUpMenu.h>
16 #include <ScrollView.h>
17 #include <String.h>
18 #include <StringView.h>
19 #include <View.h>
20 #include <Window.h>
21
22
23 static const char* kAppSignature = "application/x.vnd-Haiku.ClipToPicture";
24
25
26 class TestRenderer {
27 public:
28 virtual void Draw(BView* view, BRect updateRect) = 0;
29 };
30
31
32 class Test {
33 public:
34 Test(const char* name,
35 TestRenderer* clippingTest,
36 TestRenderer* validateTest);
37 ~Test();
38
Name() const39 const char* Name() const
40 { return fName.String(); }
41
ClippingTest() const42 TestRenderer* ClippingTest() const
43 { return fClippingTest; }
ValidateTest() const44 TestRenderer* ValidateTest() const
45 { return fValidateTest; }
46
47 private:
48 BString fName;
49 TestRenderer* fClippingTest;
50 TestRenderer* fValidateTest;
51 };
52
53
Test(const char * name,TestRenderer * clippingTest,TestRenderer * validateTest)54 Test::Test(const char* name, TestRenderer* clippingTest,
55 TestRenderer* validateTest)
56 :
57 fName(name),
58 fClippingTest(clippingTest),
59 fValidateTest(validateTest)
60 {
61 }
62
63
~Test()64 Test::~Test()
65 {
66 delete fClippingTest;
67 delete fValidateTest;
68 }
69
70
71 // #pragma mark - TestView
72
73
74 class TestView : public BView {
75 public:
76 TestView();
77 virtual ~TestView();
78
79 virtual void Draw(BRect updateRect);
80
81 void SetTestRenderer(TestRenderer* renderer);
82
83 private:
84 TestRenderer* fTestRenderer;
85 };
86
87
TestView()88 TestView::TestView()
89 :
90 BView(NULL, B_WILL_DRAW),
91 fTestRenderer(NULL)
92 {
93 }
94
95
~TestView()96 TestView::~TestView()
97 {
98 }
99
100
101 void
Draw(BRect updateRect)102 TestView::Draw(BRect updateRect)
103 {
104 if (fTestRenderer != NULL)
105 fTestRenderer->Draw(this, updateRect);
106 }
107
108
109 void
SetTestRenderer(TestRenderer * renderer)110 TestView::SetTestRenderer(TestRenderer* renderer)
111 {
112 fTestRenderer = renderer;
113 Invalidate();
114 }
115
116
117 // #pragma mark - TestWindow
118
119
120 enum {
121 MSG_SELECT_TEST = 'stst'
122 };
123
124
125 class TestWindow : public BWindow {
126 public:
127 TestWindow();
128 virtual ~TestWindow();
129
130 virtual void MessageReceived(BMessage* message);
131
132 void AddTest(Test* test);
133 void SetToTest(int32 index);
134
135 private:
136 TestView* fClippingTestView;
137 TestView* fValidateTestView;
138
139 BMenuField* fTestSelectionField;
140
141 BList fTests;
142 };
143
144
TestWindow()145 TestWindow::TestWindow()
146 :
147 BWindow(BRect(50.0, 50.0, 450.0, 250.0), "ClipToPicture Test",
148 B_DOCUMENT_WINDOW, B_ASYNCHRONOUS_CONTROLS | B_QUIT_ON_WINDOW_CLOSE
149 | B_AUTO_UPDATE_SIZE_LIMITS)
150 {
151 fClippingTestView = new TestView();
152 fValidateTestView = new TestView();
153
154 BGroupView* group = new BGroupView(B_HORIZONTAL);
155 BLayoutBuilder::Group<>(group, B_HORIZONTAL, 0.0f)
156 .Add(fClippingTestView)
157 .Add(fValidateTestView)
158 ;
159
160 BScrollView* scrollView = new BScrollView("scroll", group, 0, true, true);
161
162 BStringView* leftLabel = new BStringView("left label",
163 "ClipToPicture:");
164 leftLabel->SetExplicitMaxSize(BSize(B_SIZE_UNLIMITED, B_SIZE_UNSET));
165
166 BStringView* rightLabel = new BStringView("right label",
167 "Validation:");
168 rightLabel->SetExplicitMaxSize(BSize(B_SIZE_UNLIMITED, B_SIZE_UNSET));
169
170 fTestSelectionField = new BMenuField("test selection",
171 "Select test:", new BPopUpMenu("select"));
172
173 BLayoutBuilder::Group<>(this, B_VERTICAL, 0.0f)
174 .AddGroup(B_HORIZONTAL)
175 .Add(fTestSelectionField)
176 .AddGlue()
177 .SetInsets(B_USE_DEFAULT_SPACING)
178 .End()
179 .AddGroup(B_HORIZONTAL)
180 .Add(leftLabel)
181 .Add(rightLabel)
182 .SetInsets(B_USE_DEFAULT_SPACING)
183 .End()
184 .Add(scrollView)
185 ;
186 }
187
188
~TestWindow()189 TestWindow::~TestWindow()
190 {
191 for (int32 i = fTests.CountItems() - 1; i >= 0; i++)
192 delete (Test*)fTests.ItemAt(i);
193 }
194
195
196 void
MessageReceived(BMessage * message)197 TestWindow::MessageReceived(BMessage* message)
198 {
199 switch (message->what) {
200 case MSG_SELECT_TEST:
201 {
202 int32 index;
203 if (message->FindInt32("index", &index) == B_OK)
204 SetToTest(index);
205 break;
206 }
207
208 default:
209 BWindow::MessageReceived(message);
210 }
211 }
212
213
214 void
AddTest(Test * test)215 TestWindow::AddTest(Test* test)
216 {
217 if (test == NULL || fTests.HasItem(test))
218 return;
219
220 if (!fTests.AddItem(test)) {
221 delete test;
222 return;
223 }
224
225 BMessage* message = new BMessage(MSG_SELECT_TEST);
226 message->AddInt32("index", fTests.CountItems() - 1);
227
228 BMenuItem* item = new BMenuItem(test->Name(), message);
229 if (!fTestSelectionField->Menu()->AddItem(item)) {
230 fTests.RemoveItem(fTests.CountItems() - 1);
231 delete test;
232 delete item;
233 return;
234 }
235
236 if (fTests.CountItems() == 1)
237 SetToTest(0);
238 }
239
240
241 void
SetToTest(int32 index)242 TestWindow::SetToTest(int32 index)
243 {
244 Test* test = (Test*)fTests.ItemAt(index);
245 if (test == NULL)
246 return;
247
248 fTestSelectionField->Menu()->ItemAt(index)->SetMarked(true);
249
250 fClippingTestView->SetTestRenderer(test->ClippingTest());
251 fValidateTestView->SetTestRenderer(test->ValidateTest());
252 }
253
254
255 // #pragma mark - Test1
256
257
258 class Test1Clipping : public TestRenderer {
Draw(BView * view,BRect updateRect)259 virtual void Draw(BView* view, BRect updateRect)
260 {
261 BPicture picture;
262 view->BeginPicture(&picture);
263 view->SetDrawingMode(B_OP_ALPHA);
264 view->SetBlendingMode(B_PIXEL_ALPHA, B_ALPHA_COMPOSITE);
265 view->DrawString("Clipping to text.", BPoint(20, 30));
266 view->EndPicture();
267
268 view->ClipToPicture(&picture);
269
270 view->FillRect(view->Bounds());
271 }
272 };
273
274
275 class Test1Validate : public TestRenderer {
Draw(BView * view,BRect updateRect)276 virtual void Draw(BView* view, BRect updateRect)
277 {
278 view->DrawString("Clipping to text.", BPoint(20, 30));
279 }
280 };
281
282
283 // #pragma mark - Test2
284
285
286 class Test2Clipping : public TestRenderer {
Draw(BView * view,BRect updateRect)287 virtual void Draw(BView* view, BRect updateRect)
288 {
289 view->PushState();
290
291 BPicture picture;
292 view->BeginPicture(&picture);
293 view->SetDrawingMode(B_OP_ALPHA);
294 view->SetBlendingMode(B_PIXEL_ALPHA, B_ALPHA_COMPOSITE);
295 view->SetScale(2.0);
296 view->DrawString("Scaled clipping", BPoint(10, 15));
297 view->DrawString("to text.", BPoint(10, 25));
298 view->EndPicture();
299
300 view->PopState();
301
302 view->ClipToPicture(&picture);
303
304 view->FillRect(view->Bounds());
305 }
306 };
307
308
309 class Test2Validate : public TestRenderer {
Draw(BView * view,BRect updateRect)310 virtual void Draw(BView* view, BRect updateRect)
311 {
312 view->SetScale(2.0);
313 view->DrawString("Scaled clipping", BPoint(10, 15));
314 view->DrawString("to text.", BPoint(10, 25));
315 }
316 };
317
318
319 // #pragma mark - Test2
320
321
322 class Test3Clipping : public TestRenderer {
Draw(BView * view,BRect updateRect)323 virtual void Draw(BView* view, BRect updateRect)
324 {
325 BPicture picture;
326 view->BeginPicture(&picture);
327 view->SetDrawingMode(B_OP_ALPHA);
328 view->SetBlendingMode(B_PIXEL_ALPHA, B_ALPHA_COMPOSITE);
329 view->DrawString("Scaled picture", BPoint(10, 15));
330 view->EndPicture();
331
332 view->SetScale(2.0);
333 view->ClipToPicture(&picture);
334
335 view->SetScale(1.0);
336 view->FillRect(view->Bounds());
337 }
338 };
339
340
341 class Test3Validate : public TestRenderer {
Draw(BView * view,BRect updateRect)342 virtual void Draw(BView* view, BRect updateRect)
343 {
344 view->SetScale(2.0);
345 view->DrawString("Scaled picture", BPoint(10, 15));
346 }
347 };
348
349
350 // #pragma mark - Test2
351
352
353 class Test4Clipping : public TestRenderer {
Draw(BView * view,BRect updateRect)354 virtual void Draw(BView* view, BRect updateRect)
355 {
356 view->SetDrawingMode(B_OP_ALPHA);
357 view->SetBlendingMode(B_PIXEL_ALPHA, B_ALPHA_COMPOSITE);
358
359 BPicture rect;
360 view->BeginPicture(&rect);
361 view->FillRect(BRect(20, 20, 50, 50));
362 view->EndPicture();
363
364 view->ClipToPicture(&rect);
365
366 view->PushState();
367 BPicture circle;
368 view->BeginPicture(&circle);
369 view->FillEllipse(BRect(20, 20, 50, 50));
370 view->EndPicture();
371
372 view->ClipToInversePicture(&circle);
373
374 view->FillRect(view->Bounds());
375
376 view->PopState();
377 }
378 };
379
380
381 class Test4Validate : public TestRenderer {
Draw(BView * view,BRect updateRect)382 virtual void Draw(BView* view, BRect updateRect)
383 {
384 view->FillRect(BRect(20, 20, 50, 50));
385 view->FillEllipse(BRect(20, 20, 50, 50), B_SOLID_LOW);
386 }
387 };
388
389
390 // #pragma mark -
391
392
393 int
main(int argc,char ** argv)394 main(int argc, char** argv)
395 {
396 BApplication app(kAppSignature);
397
398 TestWindow* window = new TestWindow();
399
400 window->AddTest(new Test("Simple clipping",
401 new Test1Clipping(), new Test1Validate()));
402
403 window->AddTest(new Test("Scaled clipping 1",
404 new Test2Clipping(), new Test2Validate()));
405
406 window->AddTest(new Test("Scaled clipping 2",
407 new Test3Clipping(), new Test3Validate()));
408
409 window->AddTest(new Test("Nested states",
410 new Test4Clipping(), new Test4Validate()));
411
412 window->SetToTest(3);
413 window->Show();
414
415 app.Run();
416 return 0;
417 }
418