xref: /haiku/src/tests/servers/app/inverse_clipping/main.cpp (revision 268f99dd7dc4bd7474a8bd2742d3f1ec1de6752a)
1 #include <Application.h>
2 #include <GridView.h>
3 #include <LayoutBuilder.h>
4 #include <Picture.h>
5 #include <ScrollView.h>
6 #include <Shape.h>
7 #include <View.h>
8 #include <Window.h>
9 
10 
11 typedef void (*clipper)(BView*, BRect, bool);
12 typedef void (*test)(BView*, clipper);
13 
14 static const BRect bigRect(-1000,-1000, 1000,1000);
15 static const BRect baseRect(-25,-10, 25,10);
16 static const BRect corner(-25,-10, -15,0);
17 static const BRect crossRect(-5,-35, 5,40);
18 
19 
20 static void
rectClipper(BView * view,BRect rect,bool inverse)21 rectClipper(BView* view, BRect rect, bool inverse)
22 {
23 	if (inverse)
24 		view->ClipToInverseRect(rect);
25 	else
26 		view->ClipToRect(rect);
27 }
28 
29 static void
pictureClipper(BView * view,BRect rect,bool inverse)30 pictureClipper(BView* view, BRect rect, bool inverse)
31 {
32 	BPicture p;
33 	view->BeginPicture(&p);
34 	view->FillEllipse(rect);
35 	view->SetHighColor(0, 0, 0, 0);
36 	view->FillEllipse(rect.InsetByCopy(rect.Width()/4, rect.Height()/4));
37 	view->EndPicture();
38 
39 	if (inverse)
40 		view->ClipToInversePicture(&p);
41 	else
42 		view->ClipToPicture(&p);
43 }
44 
45 static void
shapeClipper(BView * view,BRect rect,bool inverse)46 shapeClipper(BView* view, BRect rect, bool inverse)
47 {
48 	BShape s;
49 	s.MoveTo(rect.LeftTop());
50 	s.LineTo(rect.RightBottom());
51 	s.ArcTo(rect.Width()/4, rect.Height()/4, 0, false, true, rect.RightTop());
52 	s.LineTo(rect.LeftBottom());
53 	s.Close();
54 
55 	if (inverse)
56 		view->ClipToInverseShape(&s);
57 	else
58 		view->ClipToShape(&s);
59 }
60 
61 
62 static void
testBase(BView * view,clipper clip,bool inverse)63 testBase(BView* view, clipper clip, bool inverse)
64 {
65 	clip(view, baseRect, inverse);
66 	view->SetHighColor(255,0,0);
67 	view->FillRect(bigRect);
68 }
69 
70 static void
testBaseDirect(BView * view,clipper clip)71 testBaseDirect(BView* view, clipper clip)
72 {
73 	testBase(view, clip, false);
74 }
75 
76 static void
testBaseInverse(BView * view,clipper clip)77 testBaseInverse(BView* view, clipper clip)
78 {
79 	testBase(view, clip, true);
80 }
81 
82 static void
testCross(BView * view,clipper clip,bool inverse)83 testCross(BView* view, clipper clip, bool inverse)
84 {
85 	clip(view, crossRect, inverse);
86 	view->SetHighColor(0,0,255);
87 	view->FillRect(bigRect);
88 }
89 
90 static void
testCorner(BView * view,clipper clip,bool inverse)91 testCorner(BView* view, clipper clip, bool inverse)
92 {
93 	clip(view, corner, inverse);
94 	view->SetHighColor(0,255,0);
95 	view->FillRect(bigRect);
96 }
97 
98 static void
testCross00(BView * view,clipper clip)99 testCross00(BView* view, clipper clip)
100 {
101 	testBase(view, clip, false);
102 	testCross(view, clip, false);
103 }
104 
105 static void
testCross01(BView * view,clipper clip)106 testCross01(BView* view, clipper clip)
107 {
108 	testBase(view, clip, false);
109 	testCross(view, clip, true);
110 }
111 
112 static void
testCross10(BView * view,clipper clip)113 testCross10(BView* view, clipper clip)
114 {
115 	testBase(view, clip, true);
116 	testCross(view, clip, false);
117 }
118 
119 static void
testCross11(BView * view,clipper clip)120 testCross11(BView* view, clipper clip)
121 {
122 	testBase(view, clip, true);
123 	testCross(view, clip, true);
124 }
125 
126 static void
test3000(BView * view,clipper clip)127 test3000(BView* view, clipper clip)
128 {
129 	testBase(view, clip, false);
130 	testCorner(view, clip, false);
131 	testCross(view, clip, false);
132 }
133 
134 static void
test3001(BView * view,clipper clip)135 test3001(BView* view, clipper clip)
136 {
137 	testBase(view, clip, false);
138 	testCorner(view, clip, false);
139 	testCross(view, clip, true);
140 }
141 
142 static void
test3010(BView * view,clipper clip)143 test3010(BView* view, clipper clip)
144 {
145 	testBase(view, clip, false);
146 	testCorner(view, clip, true);
147 	testCross(view, clip, false);
148 }
149 
150 static void
test3011(BView * view,clipper clip)151 test3011(BView* view, clipper clip)
152 {
153 	testBase(view, clip, false);
154 	testCorner(view, clip, true);
155 	testCross(view, clip, true);
156 }
157 
158 static void
test3100(BView * view,clipper clip)159 test3100(BView* view, clipper clip)
160 {
161 	testBase(view, clip, true);
162 	testCorner(view, clip, false);
163 	testCross(view, clip, false);
164 }
165 
166 static void
test3101(BView * view,clipper clip)167 test3101(BView* view, clipper clip)
168 {
169 	testBase(view, clip, true);
170 	testCorner(view, clip, false);
171 	testCross(view, clip, true);
172 }
173 
174 static void
test3110(BView * view,clipper clip)175 test3110(BView* view, clipper clip)
176 {
177 	testBase(view, clip, true);
178 	testCorner(view, clip, true);
179 	testCross(view, clip, false);
180 }
181 
182 static void
test3111(BView * view,clipper clip)183 test3111(BView* view, clipper clip)
184 {
185 	testBase(view, clip, true);
186 	testCorner(view, clip, true);
187 	testCross(view, clip, true);
188 }
189 
190 static const test tests[] = {
191 	testBaseDirect, testBaseInverse,
192 	testCross00, testCross01, testCross10, testCross11,
193 	test3000, test3001, test3010, test3011,
194 	test3100, test3101, test3110, test3111
195 };
196 
197 
198 class View : public BView {
199 public:
200 								View(const char* name, test, clipper);
201 			void				Draw(BRect);
202 			void				AttachedToWindow();
203 
204 private:
205 			test				fTest;
206 			clipper				fClipper;
207 };
208 
View(const char * name,test fTest,clipper fClipper)209 View::View(const char* name, test fTest, clipper fClipper)
210 	:
211 	BView(BRect(0,0, 100,100), name, 0, B_WILL_DRAW),
212 	fTest(fTest),
213 	fClipper(fClipper)
214 {
215 }
216 
217 void
AttachedToWindow()218 View::AttachedToWindow()
219 {
220 	BView::AttachedToWindow();
221 	TranslateBy(50, 50);
222 }
223 
224 void
Draw(BRect)225 View::Draw(BRect)
226 {
227 	fTest(this, fClipper);
228 }
229 
230 
231 class App : public BApplication {
232 public:
233 								App();
234 };
235 
App()236 App::App()
237 	:
238 	BApplication("application/x-vnd.Haiku-Test_inverse_clip")
239 {
240 	BWindow* window = new BWindow(BRect(100,100, 800,400), "clip test",
241 		B_TITLED_WINDOW, B_QUIT_ON_WINDOW_CLOSE);
242 
243 	BGridView* grid = new BGridView();
244 	grid->SetResizingMode(B_FOLLOW_ALL_SIDES);
245 
246 	BLayoutBuilder::Grid<> layout(grid);
247 	layout.SetInsets(B_USE_DEFAULT_SPACING);
248 
249 	int testsCount = B_COUNT_OF(tests);
250 	for (int i = 0; i < testsCount; i++) {
251 		layout.Add(new View("region", tests[i], rectClipper), 0, i);
252 		layout.Add(new View("rotate", tests[i], rectClipper), 1, i);
253 			// This one changes from Region to Shape clipping
254 		layout.Add(new View("picture", tests[i], pictureClipper), 2, i);
255 		layout.Add(new View("rotate", tests[i], pictureClipper), 3, i);
256 		layout.Add(new View("shape", tests[i], shapeClipper), 4, i);
257 		layout.Add(new View("rotate", tests[i], shapeClipper), 5, i);
258 	}
259 
260 	BScrollView* scroll = new BScrollView("scroll", grid, B_FOLLOW_ALL_SIDES,
261 		0, true, true, B_NO_BORDER);
262 	window->AddChild(scroll);
263 	BRect bounds(window->Bounds());
264 	scroll->ResizeTo(bounds.Width(), bounds.Height());
265 
266 	BView* rotate;
267 	while ((rotate = window->FindView("rotate")) != NULL) {
268 		rotate->RotateBy(0.78);
269 		rotate->SetName("rotated");
270 	}
271 
272 	window->Show();
273 }
274 
275 
276 int
main()277 main()
278 {
279 	App app;
280 	app.Run();
281 	return 0;
282 }
283