void nuiPopupMenu::CalcTreeSize(nuiRect& rRect, nuiTreeNode* pTree, uint32& cpt) { NGL_ASSERT(pTree); // no chance to happen cpt++; nuiRect rect(0,0,0,0); nuiWidgetPtr pWidget; nuiRect WidgetRect; uint32 depth = cpt; uint32 count = pTree->GetChildrenCount(); if (count <= 0) return; bool HasNonEmpty = false; for (uint32 i = 0; i < count; i++) { nuiTreeNode* pNode = dynamic_cast<nuiTreeNode*>(pTree->GetChild(i)); NGL_ASSERT(pNode); pWidget = pNode->GetElement(); NGL_ASSERT(pWidget); WidgetRect = pWidget->GetIdealRect(); rect.SetSize(MAX(rect.GetWidth(), WidgetRect.GetWidth()), rect.GetHeight() + WidgetRect.GetHeight()); if (!pNode->IsEmpty()) { HasNonEmpty = true; } if (pNode->IsOpened()) { if (mRects.size() <= depth + 1) // ensure that there is a rect for the next node { nuiMenuRect* pMenuRect = new nuiMenuRect(this, cpt+1); mRects.push_back(pMenuRect); mPopupTreeSink.Connect(pMenuRect->mpSBar->ValueChanged, &nuiPopupMenu::OnScrollBarChange, pMenuRect); } mRects[depth+1]->mpFromNode = pNode; CalcTreeSize(rRect, pNode, cpt); } } if (HasNonEmpty) { mRects[depth]->mHasNonEmpty = true; rect.SetSize(rect.GetWidth() + NUI_POPUP_TREE_HANDLE_SIZE * 2, rect.GetHeight()); } else { mRects[depth]->mHasNonEmpty = false; } mRects[depth]->mRect = rect; NGL_ASSERT(mRects.size() >= depth+1); rRect.SetSize(rect.GetWidth()+rRect.GetWidth(), rect.GetHeight()+rRect.GetHeight()); }
void nuiContainer::InternalSetLayout(const nuiRect& rect, bool PositionChanged, bool SizeChanged) { CheckValid(); if (mNeedSelfLayout || SizeChanged) { mInSetRect = true; SetRect(rect); mInSetRect = false; Invalidate(); } else { // Is this case the widget have just been moved inside its parent. No need to re layout it, only change the rect... mRect = rect; if (mNeedLayout) { // The children need to be re layed out (at least one of them!). nuiContainer::IteratorPtr pIt = GetFirstChild(false); do { nuiWidgetPtr pItem = pIt->GetWidget(); if (pItem) { // The rect of each child doesn't change BUT we still ask for its ideal rect. nuiRect rect(pItem->GetBorderedRect()); nuiRect ideal(pItem->GetIdealRect()); if (pItem->HasUserPos()) { rect = ideal; } else if (pItem->HasUserSize()) { rect.SetSize(ideal.GetWidth(), ideal.GetHeight()); } else { // Set the widget to the size of the parent } pItem->SetLayout(rect); } } while (GetNextChild(pIt)); delete pIt; } } //#TEST: #ifdef NUI_CHECK_LAYOUTS IteratorPtr pIt; for (pIt = GetFirstChild(); pIt && pIt->IsValid(); GetNextChild(pIt)) { nuiWidgetPtr pItem = pIt->GetWidget(); if (pItem->IsVisible()) { NGL_ASSERT(!pItem->GetNeedLayout()); } } delete pIt; //#TEST end #endif }