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 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 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 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 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 71 testBaseDirect(BView* view, clipper clip) 72 { 73 testBase(view, clip, false); 74 } 75 76 static void 77 testBaseInverse(BView* view, clipper clip) 78 { 79 testBase(view, clip, true); 80 } 81 82 static void 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 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 99 testCross00(BView* view, clipper clip) 100 { 101 testBase(view, clip, false); 102 testCross(view, clip, false); 103 } 104 105 static void 106 testCross01(BView* view, clipper clip) 107 { 108 testBase(view, clip, false); 109 testCross(view, clip, true); 110 } 111 112 static void 113 testCross10(BView* view, clipper clip) 114 { 115 testBase(view, clip, true); 116 testCross(view, clip, false); 117 } 118 119 static void 120 testCross11(BView* view, clipper clip) 121 { 122 testBase(view, clip, true); 123 testCross(view, clip, true); 124 } 125 126 static void 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 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 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 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 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 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 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 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 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 218 View::AttachedToWindow() 219 { 220 BView::AttachedToWindow(); 221 TranslateBy(50, 50); 222 } 223 224 void 225 View::Draw(BRect) 226 { 227 fTest(this, fClipper); 228 } 229 230 231 class App : public BApplication { 232 public: 233 App(); 234 }; 235 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 277 main() 278 { 279 App app; 280 app.Run(); 281 return 0; 282 } 283