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