xref: /haiku/src/tests/servers/app/newerClipping/ViewLayer.cpp (revision cbe0a0c436162d78cc3f92a305b64918c839d079)
1 
2 #include <stdio.h>
3 
4 #include <List.h>
5 #include <View.h> // for resize modes
6 
7 #include "Desktop.h"
8 #include "DrawingEngine.h"
9 #include "WindowLayer.h"
10 
11 #include "ViewLayer.h"
12 
13 extern BWindow* wind;
14 
15 // constructor
16 ViewLayer::ViewLayer(BRect frame, const char* name,
17 			 uint32 resizeMode, uint32 flags,
18 			 rgb_color viewColor)
19 	: fName(name),
20 
21 	  fFrame(frame),
22 	  fScrollingOffset(0.0, 0.0),
23 
24 	  fViewColor(viewColor),
25 
26 	  fResizeMode(resizeMode),
27 	  fFlags(flags),
28 
29 	  // ViewLayers start visible by default
30 	  fHidden(false),
31 	  fVisible(true),
32 
33 	  fWindow(NULL),
34 	  fParent(NULL),
35 
36 	  fFirstChild(NULL),
37 	  fPreviousSibling(NULL),
38 	  fNextSibling(NULL),
39 	  fLastChild(NULL),
40 
41 	  fCurrentChild(NULL),
42 
43 	  fLocalClipping(Bounds()),
44 	  fScreenClipping(),
45 	  fScreenClippingValid(false)
46 {
47 	fFrame.left = float((int32)fFrame.left);
48 	fFrame.top = float((int32)fFrame.top);
49 	fFrame.right = float((int32)fFrame.right);
50 	fFrame.bottom = float((int32)fFrame.bottom);
51 }
52 
53 // destructor
54 ViewLayer::~ViewLayer()
55 {
56 	// iterate over children and delete each one
57 	ViewLayer* layer = fFirstChild;
58 	while (layer) {
59 		ViewLayer* toast = layer;
60 		layer = layer->fNextSibling;
61 		delete toast;
62 	}
63 }
64 
65 // Bounds
66 BRect
67 ViewLayer::Bounds() const
68 {
69 	BRect bounds(fScrollingOffset.x, fScrollingOffset.y,
70 				 fScrollingOffset.x + fFrame.Width(),
71 				 fScrollingOffset.y + fFrame.Height());
72 	return bounds;
73 }
74 
75 // ConvertToVisibleInTopView
76 void
77 ViewLayer::ConvertToVisibleInTopView(BRect* bounds) const
78 {
79 	*bounds = *bounds & Bounds();
80 	// NOTE: this step is necessary even if we don't have a parent!
81 	ConvertToParent(bounds);
82 
83 	if (fParent)
84 		fParent->ConvertToVisibleInTopView(bounds);
85 }
86 
87 // AttachedToWindow
88 void
89 ViewLayer::AttachedToWindow(WindowLayer* window)
90 {
91 	fWindow = window;
92 
93 	for (ViewLayer* child = FirstChild(); child; child = NextChild())
94 		child->AttachedToWindow(window);
95 }
96 
97 
98 // DetachedFromWindow
99 void
100 ViewLayer::DetachedFromWindow()
101 {
102 	fWindow = NULL;
103 	for (ViewLayer* child = FirstChild(); child; child = NextChild())
104 		child->DetachedFromWindow();
105 }
106 
107 // AddChild
108 void
109 ViewLayer::AddChild(ViewLayer* layer)
110 {
111 	if (layer->fParent) {
112 		printf("ViewLayer::AddChild() - ViewLayer already has a parent\n");
113 		return;
114 	}
115 
116 	layer->fParent = this;
117 
118 	if (!fLastChild) {
119 		// no children yet
120 		fFirstChild = layer;
121 	} else {
122 		// append layer to formerly last child
123 		fLastChild->fNextSibling = layer;
124 		layer->fPreviousSibling = fLastChild;
125 	}
126 	fLastChild = layer;
127 
128 	if (layer->IsVisible())
129 		RebuildClipping(false);
130 
131 	if (fWindow) {
132 		layer->AttachedToWindow(fWindow);
133 
134 		if (fVisible && layer->IsVisible()) {
135 			// trigger redraw
136 			BRect clippedFrame = layer->Frame();
137 			ConvertToVisibleInTopView(&clippedFrame);
138 			BRegion dirty(clippedFrame);
139 			fWindow->MarkContentDirty(&dirty);
140 		}
141 	}
142 }
143 
144 // RemoveChild
145 bool
146 ViewLayer::RemoveChild(ViewLayer* layer)
147 {
148 	if (layer->fParent != this) {
149 		printf("ViewLayer::RemoveChild(%p - %s) - ViewLayer is not child of this (%p) layer!\n", layer, layer ? layer->Name() : NULL, this);
150 		return false;
151 	}
152 
153 	layer->fParent = NULL;
154 
155 	if (fLastChild == layer)
156 		fLastChild = layer->fPreviousSibling;
157 		// layer->fNextSibling would be NULL
158 
159 	if (fFirstChild == layer )
160 		fFirstChild = layer->fNextSibling;
161 		// layer->fPreviousSibling would be NULL
162 
163 	// connect child before and after layer
164 	if (layer->fPreviousSibling)
165 		layer->fPreviousSibling->fNextSibling = layer->fNextSibling;
166 
167 	if (layer->fNextSibling)
168 		layer->fNextSibling->fPreviousSibling = layer->fPreviousSibling;
169 
170 	// layer has no siblings anymore
171 	layer->fPreviousSibling = NULL;
172 	layer->fNextSibling = NULL;
173 
174 	if (layer->IsVisible())
175 		RebuildClipping(false);
176 
177 	if (fWindow) {
178 		layer->DetachedFromWindow();
179 
180 		if (fVisible && layer->IsVisible()) {
181 			// trigger redraw
182 			BRect clippedFrame = layer->Frame();
183 			ConvertToVisibleInTopView(&clippedFrame);
184 			BRegion dirty(clippedFrame);
185 			fWindow->MarkContentDirty(&dirty);
186 		}
187 	}
188 
189 	return true;
190 }
191 
192 // FirstChild
193 ViewLayer*
194 ViewLayer::FirstChild() const
195 {
196 	fCurrentChild = fFirstChild;
197 	return fCurrentChild;
198 }
199 
200 // PreviousChild
201 ViewLayer*
202 ViewLayer::PreviousChild() const
203 {
204 	fCurrentChild = fCurrentChild->fPreviousSibling;
205 	return fCurrentChild;
206 }
207 
208 // NextChild
209 ViewLayer*
210 ViewLayer::NextChild() const
211 {
212 	fCurrentChild = fCurrentChild->fNextSibling;
213 	return fCurrentChild;
214 }
215 
216 // LastChild
217 ViewLayer*
218 ViewLayer::LastChild() const
219 {
220 	fCurrentChild = fLastChild;
221 	return fCurrentChild;
222 }
223 
224 // TopLayer
225 ViewLayer*
226 ViewLayer::TopLayer()
227 {
228 	// returns the top level view of the hirarchy,
229 	// it doesn't have to be the top level of a window
230 
231 	if (fParent)
232 		return fParent->TopLayer();
233 
234 	return this;
235 }
236 
237 // CountChildren
238 uint32
239 ViewLayer::CountChildren(bool deep) const
240 {
241 	uint32 count = 0;
242 	for (ViewLayer* child = FirstChild(); child; child = NextChild()) {
243 		count++;
244 		if (deep) {
245 			count += child->CountChildren(deep);
246 		}
247 	}
248 	return count;
249 }
250 
251 // CollectTokensForChildren
252 void
253 ViewLayer::CollectTokensForChildren(BList* tokenMap) const
254 {
255 	for (ViewLayer* child = FirstChild(); child; child = NextChild()) {
256 		tokenMap->AddItem((void*)child);
257 		child->CollectTokensForChildren(tokenMap);
258 	}
259 }
260 
261 // ViewAt
262 ViewLayer*
263 ViewLayer::ViewAt(const BPoint& where, BRegion* windowContentClipping)
264 {
265 	if (!fVisible)
266 		return NULL;
267 
268 	if (ScreenClipping(windowContentClipping).Contains(where))
269 		return this;
270 
271 	for (ViewLayer* child = FirstChild(); child; child = NextChild()) {
272 		ViewLayer* layer = child->ViewAt(where, windowContentClipping);
273 		if (layer)
274 			return layer;
275 	}
276 	return NULL;
277 }
278 
279 // ConvertToParent
280 void
281 ViewLayer::ConvertToParent(BPoint* point) const
282 {
283 	// remove scrolling offset and convert to parent coordinate space
284 	point->x += fFrame.left - fScrollingOffset.x;
285 	point->y += fFrame.top - fScrollingOffset.y;
286 }
287 
288 // ConvertToParent
289 void
290 ViewLayer::ConvertToParent(BRect* rect) const
291 {
292 	// remove scrolling offset and convert to parent coordinate space
293 	rect->OffsetBy(fFrame.left - fScrollingOffset.x,
294 				   fFrame.top - fScrollingOffset.y);
295 }
296 
297 // ConvertToParent
298 void
299 ViewLayer::ConvertToParent(BRegion* region) const
300 {
301 	// remove scrolling offset and convert to parent coordinate space
302 	region->OffsetBy(fFrame.left - fScrollingOffset.x,
303 					 fFrame.top - fScrollingOffset.y);
304 }
305 
306 // ConvertFromParent
307 void
308 ViewLayer::ConvertFromParent(BPoint* point) const
309 {
310 	// remove scrolling offset and convert to parent coordinate space
311 	point->x += fScrollingOffset.x - fFrame.left;
312 	point->y += fScrollingOffset.y - fFrame.top;
313 }
314 
315 // ConvertFromParent
316 void
317 ViewLayer::ConvertFromParent(BRect* rect) const
318 {
319 	// remove scrolling offset and convert to parent coordinate space
320 	rect->OffsetBy(fScrollingOffset.x - fFrame.left,
321 				   fScrollingOffset.y - fFrame.top);
322 }
323 
324 // ConvertFromParent
325 void
326 ViewLayer::ConvertFromParent(BRegion* region) const
327 {
328 	// remove scrolling offset and convert to parent coordinate space
329 	region->OffsetBy(fScrollingOffset.x - fFrame.left,
330 					 fScrollingOffset.y - fFrame.top);
331 }
332 
333 // ConvertToTop
334 void
335 ViewLayer::ConvertToTop(BPoint* point) const
336 {
337 	ConvertToParent(point);
338 
339 	if (fParent)
340 		fParent->ConvertToTop(point);
341 }
342 
343 // ConvertToTop
344 void
345 ViewLayer::ConvertToTop(BRect* rect) const
346 {
347 	ConvertToParent(rect);
348 
349 	if (fParent)
350 		fParent->ConvertToTop(rect);
351 }
352 
353 // ConvertToTop
354 void
355 ViewLayer::ConvertToTop(BRegion* region) const
356 {
357 	ConvertToParent(region);
358 
359 	if (fParent)
360 		fParent->ConvertToTop(region);
361 }
362 
363 // ConvertFromTop
364 void
365 ViewLayer::ConvertFromTop(BPoint* point) const
366 {
367 	ConvertFromParent(point);
368 
369 	if (fParent)
370 		fParent->ConvertFromTop(point);
371 }
372 
373 // ConvertFromTop
374 void
375 ViewLayer::ConvertFromTop(BRect* rect) const
376 {
377 	ConvertFromParent(rect);
378 
379 	if (fParent)
380 		fParent->ConvertFromTop(rect);
381 }
382 
383 // ConvertFromTop
384 void
385 ViewLayer::ConvertFromTop(BRegion* region) const
386 {
387 	ConvertFromParent(region);
388 
389 	if (fParent)
390 		fParent->ConvertFromTop(region);
391 }
392 
393 // SetName
394 void
395 ViewLayer::SetName(const char* string)
396 {
397 	fName.SetTo(string);
398 }
399 
400 // #pragma mark -
401 
402 // MoveBy
403 void
404 ViewLayer::MoveBy(int32 x, int32 y, BRegion* dirtyRegion)
405 {
406 	if (x == 0 && y == 0)
407 		return;
408 
409 	fFrame.OffsetBy(x, y);
410 
411 	// to move on screen, we must not be hidden and we must have a parent
412 	if (fVisible && fParent && dirtyRegion) {
413 #if 0
414 // based on redraw on new location
415 		// the place were we are now visible
416 		BRect newVisibleBounds = Bounds();
417 		// we can use the frame of the old
418 		// local clipping to see which parts need invalidation
419 		BRect oldVisibleBounds(Bounds());
420 		oldVisibleBounds.OffsetBy(-x, -y);
421 		ConvertToTop(&oldVisibleBounds);
422 
423 		ConvertToVisibleInTopView(&newVisibleBounds);
424 
425 		dirtyRegion->Include(oldVisibleBounds);
426 		// newVisibleBounds already is in screen coords
427 		dirtyRegion->Include(newVisibleBounds);
428 #else
429 // blitting version, invalidates
430 // old contents
431 		BRect oldVisibleBounds(Bounds());
432 		oldVisibleBounds.OffsetBy(-x, -y);
433 		ConvertToTop(&oldVisibleBounds);
434 
435 		BRect newVisibleBounds(Bounds());
436 		// NOTE: using ConvertToVisibleInTopView()
437 		// instead of ConvertToTop()! see below
438 		ConvertToVisibleInTopView(&newVisibleBounds);
439 
440 		newVisibleBounds.OffsetBy(-x, -y);
441 
442 		// clipping oldVisibleBounds to newVisibleBounds
443 		// makes sure we don't copy parts hidden under
444 		// parent views
445 		BRegion copyRegion(oldVisibleBounds & newVisibleBounds);
446 		fWindow->CopyContents(&copyRegion, x, y);
447 
448 		BRegion dirty(oldVisibleBounds);
449 		newVisibleBounds.OffsetBy(x, y);
450 		dirty.Exclude(newVisibleBounds);
451 		dirtyRegion->Include(&dirty);
452 #endif
453 	}
454 
455 	if (!fParent) {
456 		// the top view's screen clipping does not change,
457 		// because no parts are clipped away from parent
458 		// views
459 		_MoveScreenClipping(x, y, true);
460 	} else {
461 		// parts might have been revealed from underneath
462 		// the parent, or might now be hidden underneath
463 		// the parent, this is taken care of when building
464 		// the screen clipping
465 		InvalidateScreenClipping(true);
466 	}
467 }
468 
469 // ResizeBy
470 void
471 ViewLayer::ResizeBy(int32 x, int32 y, BRegion* dirtyRegion)
472 {
473 	if (x == 0 && y == 0)
474 		return;
475 
476 	fFrame.right += x;
477 	fFrame.bottom += y;
478 
479 	if (fVisible && dirtyRegion) {
480 		BRect oldBounds(Bounds());
481 		oldBounds.right -= x;
482 		oldBounds.bottom -= y;
483 
484 		BRegion dirty(Bounds());
485 		dirty.Include(oldBounds);
486 
487 		if (!(fFlags & B_FULL_UPDATE_ON_RESIZE)) {
488 			// the dirty region is just the difference of
489 			// old and new bounds
490 			dirty.Exclude(oldBounds & Bounds());
491 		}
492 
493 		InvalidateScreenClipping(true);
494 
495 		if (dirty.CountRects() > 0) {
496 			// exclude children, they are expected to
497 			// include their own dirty regions in ParentResized()
498 			for (ViewLayer* child = FirstChild(); child; child = NextChild()) {
499 				if (child->IsVisible()) {
500 					BRect previousChildVisible(child->Frame() & oldBounds & Bounds());
501 					if (dirty.Frame().Intersects(previousChildVisible)) {
502 						dirty.Exclude(previousChildVisible);
503 					}
504 				}
505 			}
506 
507 			ConvertToTop(&dirty);
508 			dirtyRegion->Include(&dirty);
509 		}
510 	}
511 
512 	// layout the children
513 	for (ViewLayer* child = FirstChild(); child; child = NextChild())
514 		child->ParentResized(x, y, dirtyRegion);
515 
516 	// at this point, children are at their new locations,
517 	// so we can rebuild the clipping
518 	// TODO: when the implementation of Hide() and Show() is
519 	// complete, see if this should be avoided
520 	RebuildClipping(false);
521 }
522 
523 // ParentResized
524 void
525 ViewLayer::ParentResized(int32 x, int32 y, BRegion* dirtyRegion)
526 {
527 	uint16 rm = fResizeMode & 0x0000FFFF;
528 	BRect newFrame = fFrame;
529 
530 	// follow with left side
531 	if ((rm & 0x0F00U) == _VIEW_RIGHT_ << 8)
532 		newFrame.left += x;
533 	else if ((rm & 0x0F00U) == _VIEW_CENTER_ << 8)
534 		newFrame.left += x / 2;
535 
536 	// follow with right side
537 	if ((rm & 0x000FU) == _VIEW_RIGHT_)
538 		newFrame.right += x;
539 	else if ((rm & 0x000FU) == _VIEW_CENTER_)
540 		newFrame.right += x / 2;
541 
542 	// follow with top side
543 	if ((rm & 0xF000U) == _VIEW_BOTTOM_ << 12)
544 		newFrame.top += y;
545 	else if ((rm & 0xF000U) == _VIEW_CENTER_ << 12)
546 		newFrame.top += y / 2;
547 
548 	// follow with bottom side
549 	if ((rm & 0x00F0U) == _VIEW_BOTTOM_ << 4)
550 		newFrame.bottom += y;
551 	else if ((rm & 0x00F0U) == _VIEW_CENTER_ << 4)
552 		newFrame.bottom += y / 2;
553 
554 	if (newFrame != fFrame) {
555 		// careful, MoveBy will change fFrame
556 		int32 widthDiff = (int32)(newFrame.Width() - fFrame.Width());
557 		int32 heightDiff = (int32)(newFrame.Height() - fFrame.Height());
558 
559 		MoveBy(newFrame.left - fFrame.left,
560 			   newFrame.top - fFrame.top, dirtyRegion);
561 
562 		ResizeBy(widthDiff, heightDiff, dirtyRegion);
563 	}
564 }
565 
566 // ScrollBy
567 void
568 ViewLayer::ScrollBy(int32 x, int32 y, BRegion* dirtyRegion)
569 {
570 	// blitting version, invalidates
571 	// old contents
572 
573 	// remember old bounds for tracking dirty region
574 	BRect oldBounds(Bounds());
575 	// find the area of the view that can be scrolled,
576 	// contents are shifted in the opposite direction from scrolling
577 	BRect stillVisibleBounds(oldBounds);
578 	stillVisibleBounds.OffsetBy(x, y);
579 
580 	// NOTE: using ConvertToVisibleInTopView()
581 	// instead of ConvertToTop(), this makes
582 	// sure we don't try to move or invalidate an
583 	// area hidden underneath the parent view
584 	ConvertToVisibleInTopView(&oldBounds);
585 	ConvertToVisibleInTopView(&stillVisibleBounds);
586 
587 	fScrollingOffset.x += x;
588 	fScrollingOffset.y += y;
589 
590 	// do the blit, this will make sure
591 	// that other more complex dirty regions
592 	// are taken care of
593 	BRegion copyRegion(stillVisibleBounds);
594 	fWindow->CopyContents(&copyRegion, -x, -y);
595 
596 	// find the dirty region as far as we are
597 	// concerned
598 	BRegion dirty(oldBounds);
599 	stillVisibleBounds.OffsetBy(-x, -y);
600 	dirty.Exclude(stillVisibleBounds);
601 	dirtyRegion->Include(&dirty);
602 
603 	// the screen clipping of this view and it's
604 	// childs is no longer valid
605 	InvalidateScreenClipping(true);
606 	RebuildClipping(false);
607 }
608 
609 // #pragma mark -
610 
611 // Draw
612 void
613 ViewLayer::Draw(DrawingEngine* drawingEngine, BRegion* effectiveClipping,
614 				BRegion* windowContentClipping, bool deep)
615 {
616 	// we can only draw within our own area
617 	BRegion redraw(ScreenClipping(windowContentClipping));
618 	// add the current clipping
619 	redraw.IntersectWith(effectiveClipping);
620 
621 	// fill visible region with white
622 	drawingEngine->FillRegion(&redraw, (rgb_color){ 255, 255, 255, 255 });
623 
624 	// let children draw
625 	if (deep) {
626 		// before passing the clipping on to children, exclude our
627 		// own region from the available clipping
628 		effectiveClipping->Exclude(&ScreenClipping(windowContentClipping));
629 
630 		for (ViewLayer* child = FirstChild(); child; child = NextChild()) {
631 			child->Draw(drawingEngine, effectiveClipping,
632 						windowContentClipping, deep);
633 		}
634 	}
635 }
636 
637 // ClientDraw
638 void
639 ViewLayer::ClientDraw(DrawingEngine* drawingEngine, BRegion* effectiveClipping)
640 {
641 	BRect b(Bounds());
642 	b.OffsetTo(0.0, 0.0);
643 	ConvertToTop(&b);
644 
645 	if (drawingEngine->Lock()) {
646 		drawingEngine->ConstrainClipping(effectiveClipping);
647 
648 		// draw a frame with the view color
649 		drawingEngine->StrokeRect(b, fViewColor);
650 		b.InsetBy(1, 1);
651 		drawingEngine->StrokeRect(b, fViewColor);
652 		b.InsetBy(1, 1);
653 		drawingEngine->StrokeRect(b, fViewColor);
654 		b.InsetBy(1, 1);
655 		drawingEngine->StrokeLine(b.LeftTop(), b.RightBottom(), fViewColor);
656 
657 		drawingEngine->Unlock();
658 	}
659 }
660 
661 // #pragma mark -
662 
663 // SetHidden
664 void
665 ViewLayer::SetHidden(bool hidden)
666 {
667 	// TODO: test...
668 
669 	if (fHidden != hidden) {
670 		fHidden = hidden;
671 
672 		// recurse into children and update their visible flag
673 		if (fParent) {
674 			bool olfVisible = fVisible;
675 			UpdateVisibleDeep(fParent->IsVisible());
676 			if (olfVisible != fVisible) {
677 				// include or exclude us from the parent area
678 				fParent->RebuildClipping(false);
679 				if (fWindow) {
680 					// trigger a redraw
681 					BRect clippedBounds = Bounds();
682 					ConvertToVisibleInTopView(&clippedBounds);
683 					BRegion dirty(clippedBounds);
684 					fWindow->MarkContentDirty(&dirty);
685 				}
686 			}
687 		} else {
688 			UpdateVisibleDeep(true);
689 		}
690 	}
691 }
692 
693 // IsHidden
694 bool
695 ViewLayer::IsHidden() const
696 {
697 	return fHidden;
698 }
699 
700 // UpdateVisibleDeep
701 void
702 ViewLayer::UpdateVisibleDeep(bool parentVisible)
703 {
704 	fVisible = parentVisible && !fHidden;
705 	for (ViewLayer* child = FirstChild(); child; child = NextChild())
706 		child->UpdateVisibleDeep(fVisible);
707 }
708 
709 // PrintToStream
710 void
711 ViewLayer::PrintToStream() const
712 {
713 }
714 
715 // RebuildClipping
716 void
717 ViewLayer::RebuildClipping(bool deep)
718 {
719 	// the clipping spans over the bounds area
720 	fLocalClipping.Set(Bounds());
721 
722 	// exclude all childs from the clipping
723 	for (ViewLayer* child = FirstChild(); child; child = NextChild()) {
724 		if (child->IsVisible())
725 			fLocalClipping.Exclude(child->Frame());
726 
727 		if (deep)
728 			child->RebuildClipping(deep);
729 	}
730 
731 	fScreenClippingValid = false;
732 }
733 
734 // ScreenClipping
735 BRegion&
736 ViewLayer::ScreenClipping(BRegion* windowContentClipping, bool force) const
737 {
738 	if (!fScreenClippingValid || force) {
739 		fScreenClipping = fLocalClipping;
740 		ConvertToTop(&fScreenClipping);
741 
742 		// see if we parts of our bounds are hidden underneath
743 		// the parent, the local clipping does not account for this
744 		BRect clippedBounds = Bounds();
745 		ConvertToVisibleInTopView(&clippedBounds);
746 		if (clippedBounds.Width() < fScreenClipping.Frame().Width() ||
747 			clippedBounds.Height() < fScreenClipping.Frame().Height()) {
748 			BRegion temp(clippedBounds);
749 			fScreenClipping.IntersectWith(&temp);
750 		}
751 
752 		fScreenClipping.IntersectWith(windowContentClipping);
753 		fScreenClippingValid = true;
754 	}
755 	return fScreenClipping;
756 }
757 
758 // InvalidateScreenClipping
759 void
760 ViewLayer::InvalidateScreenClipping(bool deep)
761 {
762 	fScreenClippingValid = false;
763 	if (deep) {
764 		// invalidate the childrens screen clipping as well
765 		for (ViewLayer* child = FirstChild(); child; child = NextChild()) {
766 			child->InvalidateScreenClipping(deep);
767 		}
768 	}
769 }
770 
771 // _MoveScreenClipping
772 void
773 ViewLayer::_MoveScreenClipping(int32 x, int32 y, bool deep)
774 {
775 	if (fScreenClippingValid)
776 		fScreenClipping.OffsetBy(x, y);
777 
778 	if (deep) {
779 		// move the childrens screen clipping as well
780 		for (ViewLayer* child = FirstChild(); child; child = NextChild()) {
781 			child->_MoveScreenClipping(x, y, deep);
782 		}
783 	}
784 }
785 
786