void WidgetContainer::MarkDirty(WidgetContainer* theWidget) { if (theWidget->mDirty) return; // Only mark things dirty that are on top of this widget // Mark ourselves dirty MarkDirty(); theWidget->mDirty = true; // Top-level windows are treated differently, as marking a child dirty always // causes a parent redraw which always causes all children to redraw if (mParent != NULL) return; if (theWidget->mHasAlpha) MarkDirtyFull(theWidget); else { bool found = false; WidgetList::iterator anItr = mWidgets.begin(); while (anItr != mWidgets.end()) { Widget* aWidget = *anItr; if (aWidget == theWidget) found = true; else if (found) { if ((aWidget->mVisible) && (aWidget->Intersects(theWidget))) MarkDirty(aWidget); } ++anItr; } } }
void WidgetContainer::MarkDirtyFull(WidgetContainer* theWidget) { // Mark all things dirty that are under or over this widget // Mark ourselves dirty MarkDirtyFull(); theWidget->mDirty = true; // Top-level windows are treated differently, as marking a child dirty always // causes a parent redraw which always causes all children to redraw if (mParent != NULL) return; WidgetList::iterator aFoundWidgetItr = std::find(mWidgets.begin(), mWidgets.end(), theWidget); if (aFoundWidgetItr == mWidgets.end()) return; WidgetList::iterator anItr = aFoundWidgetItr; if (anItr != mWidgets.begin()) { anItr--; for (;;) { Widget* aWidget = *anItr; if (aWidget->mVisible) { if ((!aWidget->mHasTransparencies) && (!aWidget->mHasAlpha)) { // Clip the widget's bounds to the screen and check if it fully overlapped by this non-transparent widget underneath it // If it is fully overlapped then we can stop marking dirty underneath it since it's not transparent. Rect aRect = Rect(theWidget->mX,theWidget->mY,theWidget->mWidth,theWidget->mHeight).Intersection(Rect(0,0,mWidth,mHeight)); if ((aWidget->Contains(aRect.mX, aRect.mY) && (aWidget->Contains(aRect.mX + aRect.mWidth - 1, aRect.mY + aRect.mHeight - 1)))) { // If this widget is fully contained within a lower widget, there is no need to dig down // any deeper. aWidget->MarkDirty(); break; } } if (aWidget->Intersects(theWidget)) MarkDirty(aWidget); } if (anItr == mWidgets.begin()) break; --anItr; } } anItr = aFoundWidgetItr; while (anItr != mWidgets.end()) { Widget* aWidget = *anItr; if ((aWidget->mVisible) && (aWidget->Intersects(theWidget))) MarkDirty(aWidget); ++anItr; } }