NS_IMETHODIMP nsViewManager::InsertChild(nsIView *aParent, nsIView *aChild, nsIView *aSibling, bool aAfter) { nsView* parent = static_cast<nsView*>(aParent); nsView* child = static_cast<nsView*>(aChild); nsView* sibling = static_cast<nsView*>(aSibling); NS_PRECONDITION(nsnull != parent, "null ptr"); NS_PRECONDITION(nsnull != child, "null ptr"); NS_ASSERTION(sibling == nsnull || sibling->GetParent() == parent, "tried to insert view with invalid sibling"); NS_ASSERTION(!IsViewInserted(child), "tried to insert an already-inserted view"); if ((nsnull != parent) && (nsnull != child)) { // if aAfter is set, we will insert the child after 'prev' (i.e. after 'kid' in document // order, otherwise after 'kid' (i.e. before 'kid' in document order). #if 1 if (nsnull == aSibling) { if (aAfter) { // insert at end of document order, i.e., before first view // this is the common case, by far parent->InsertChild(child, nsnull); ReparentWidgets(child, parent); } else { // insert at beginning of document order, i.e., after last view nsView *kid = parent->GetFirstChild(); nsView *prev = nsnull; while (kid) { prev = kid; kid = kid->GetNextSibling(); } // prev is last view or null if there are no children parent->InsertChild(child, prev); ReparentWidgets(child, parent); } } else { nsView *kid = parent->GetFirstChild(); nsView *prev = nsnull; while (kid && sibling != kid) { //get the next sibling view prev = kid; kid = kid->GetNextSibling(); } NS_ASSERTION(kid != nsnull, "couldn't find sibling in child list"); if (aAfter) { // insert after 'kid' in document order, i.e. before in view order parent->InsertChild(child, prev); ReparentWidgets(child, parent); } else { // insert before 'kid' in document order, i.e. after in view order parent->InsertChild(child, kid); ReparentWidgets(child, parent); } } #else // don't keep consistent document order, but order things by z-index instead // essentially we're emulating the old InsertChild(parent, child, zindex) PRInt32 zIndex = child->GetZIndex(); while (nsnull != kid) { PRInt32 idx = kid->GetZIndex(); if (CompareZIndex(zIndex, child->IsTopMost(), child->GetZIndexIsAuto(), idx, kid->IsTopMost(), kid->GetZIndexIsAuto()) >= 0) break; prev = kid; kid = kid->GetNextSibling(); } parent->InsertChild(child, prev); ReparentWidgets(child, parent); #endif // if the parent view is marked as "floating", make the newly added view float as well. if (parent->GetFloating()) child->SetFloating(true); //and mark this area as dirty if the view is visible... if (nsViewVisibility_kHide != child->GetVisibility()) child->GetViewManager()->InvalidateView(child); } return NS_OK; }
void nsViewManager::InsertChild(nsView *aParent, nsView *aChild, nsView *aSibling, bool aAfter) { NS_PRECONDITION(nullptr != aParent, "null ptr"); NS_PRECONDITION(nullptr != aChild, "null ptr"); NS_ASSERTION(aSibling == nullptr || aSibling->GetParent() == aParent, "tried to insert view with invalid sibling"); NS_ASSERTION(!IsViewInserted(aChild), "tried to insert an already-inserted view"); if ((nullptr != aParent) && (nullptr != aChild)) { // if aAfter is set, we will insert the child after 'prev' (i.e. after 'kid' in document // order, otherwise after 'kid' (i.e. before 'kid' in document order). if (nullptr == aSibling) { if (aAfter) { // insert at end of document order, i.e., before first view // this is the common case, by far aParent->InsertChild(aChild, nullptr); ReparentWidgets(aChild, aParent); } else { // insert at beginning of document order, i.e., after last view nsView *kid = aParent->GetFirstChild(); nsView *prev = nullptr; while (kid) { prev = kid; kid = kid->GetNextSibling(); } // prev is last view or null if there are no children aParent->InsertChild(aChild, prev); ReparentWidgets(aChild, aParent); } } else { nsView *kid = aParent->GetFirstChild(); nsView *prev = nullptr; while (kid && aSibling != kid) { //get the next sibling view prev = kid; kid = kid->GetNextSibling(); } NS_ASSERTION(kid != nullptr, "couldn't find sibling in child list"); if (aAfter) { // insert after 'kid' in document order, i.e. before in view order aParent->InsertChild(aChild, prev); ReparentWidgets(aChild, aParent); } else { // insert before 'kid' in document order, i.e. after in view order aParent->InsertChild(aChild, kid); ReparentWidgets(aChild, aParent); } } // if the parent view is marked as "floating", make the newly added view float as well. if (aParent->GetFloating()) aChild->SetFloating(true); //and mark this area as dirty if the view is visible... if (nsViewVisibility_kHide != aChild->GetVisibility()) aChild->GetViewManager()->InvalidateView(aChild); } }