void nuiRect::RoundToSmallest() { mLeft = (nuiSize)ToAbove(mLeft ); mRight = (nuiSize)ToBelow(mRight ); mTop = (nuiSize)ToAbove(mTop ); mBottom = (nuiSize)ToBelow(mBottom); }
nuiRect nuiPopupMenu::CalcIdealSize() { if (mTrashRemoval) return nuiRect(); uint32 cpt = 0; nuiRect rect = mInitialPos; // this rect is for initial position of the menu if (mRects.empty()) { mRects.push_back(new nuiMenuRect(this, 0)); mPopupTreeSink.Connect(mRects[0]->mpSBar->ValueChanged, &nuiPopupMenu::OnScrollBarChange, mRects[0]); mRects[0]->mpFromNode = mpTree; } NGL_ASSERT(mpTree); nuiWidgetPtr pWidget = mpTree->GetElement(); NGL_ASSERT(pWidget); nuiRect WidgetRect = pWidget->GetIdealRect(); if (mShowFirstNode) rect.SetSize((nuiSize)ToAbove(WidgetRect.GetWidth() + NUI_POPUP_MARGIN), (nuiSize)ToAbove(WidgetRect.GetHeight())); //size of the first element we wish not to be selectable else rect.SetSize((nuiSize)0,(nuiSize)0); //size of the first element we wish not to be selectable bool HasNonEmpty = false; uint32 count = mpTree->GetChildrenCount(); nuiRect GlobRect = rect; for (uint32 i = 0; i < count; i++) { nuiTreeNode* pNode = dynamic_cast<nuiTreeNode*>(mpTree->GetChild(i)); if (pNode) { pWidget = pNode->GetElement(); 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() <= cpt + 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[cpt+1]->mpFromNode = pNode; NGL_ASSERT(mRects.size() > cpt+1); GlobRect = rect; CalcTreeSize(GlobRect, pNode, cpt); } } } if (HasNonEmpty) { mRects[0]->mHasNonEmpty = true; rect.SetSize(rect.GetWidth() + NUI_POPUP_TREE_HANDLE_SIZE * 2, rect.GetHeight()); } else { mRects[0]->mHasNonEmpty = false; } if (mInitialPos.GetWidth() > rect.GetWidth()) rect.SetWidth(mInitialPos.GetWidth()); mRects[0]->mRect = rect; if (cpt+1 < mRects.size()) { // there is unused rects int eraser_countdown = cpt; for (std::vector<nuiMenuRect*>::iterator it = mRects.begin(); it != mRects.end(); eraser_countdown--) { if (eraser_countdown >= 0) { it++; } else { if((*it)->mpSBar) { (*it)->mpSBar->SetVisible(false); (*it)->mpSBar->SetEnabled(false); mPopupTreeSink.DisconnectSource((*it)->mpSBar->ValueChanged); mSBarsPool.push_back((*it)->mpSBar); } delete *it; it = mRects.erase(it); } } } mIdealRect = GlobRect; return mIdealRect; }
void nuiOutliner::Tessellate(nuiPath& rPoints, const nuiPath& rVertices, uint offset, int count, float Quality) const { nuiPath Left; nuiPath Right; NGL_ASSERT(count); const nuiPoint& rstart = rVertices[offset]; const nuiPoint& rstop = rVertices[offset + count - 1]; bool closed = rstart == rstop; int segments = count; if (!closed) segments--; int i; // Create four outlined vertex per segment: for (i = 0; i < segments; i++) { int p1 = i; int p2 = (p1+1); p1 += offset; p2 += offset; const nuiPoint& rPoint = rVertices[p1]; const nuiPoint& rNextPoint = rVertices[p2]; if (!(rPoint == rNextPoint)) { nuiVector vec(rNextPoint - rPoint); vec.Normalize(); vec *= mRealLineWidth; float tmp = vec[0]; vec[0] = vec[1]; vec[1] = -tmp; Left.AddVertexOptim(nuiPoint(rPoint + vec)); Left.AddVertexOptim(nuiPoint(rNextPoint + vec)); Right.AddVertexOptim(nuiPoint(rPoint - vec)); Right.AddVertexOptim(nuiPoint(rNextPoint - vec)); } } Right.Reverse(); if (!Left.GetCount() || !Right.GetCount()) // Case of a path where all points have the same coordinates { switch (mLineCap) { case nuiLineCapBut: // The result is empty. break; case nuiLineCapRound: { const double CIRCLE_FACTOR = (1.0/3.5); const double X = rstart[0]; const double Y = rstart[1]; uint count = ToAbove((double)(2.0 * M_PI * (double)mRealLineWidth * (double)CIRCLE_FACTOR)); float step = 2.0f * (float)M_PI / (float)count; for (uint i = 0; i <= count; i++) { float angle = step * (float) i; float x = (float)(X + sin(angle) * mRealLineWidth); float y = (float)(Y + cos(angle) * mRealLineWidth); rPoints.AddVertexOptim(nuiPoint(x, y, 0)); } } break; case nuiLineCapSquare: { const float x = rstart[0]; const float y = rstart[1]; rPoints.AddVertexOptim(nuiPoint(x - mRealLineWidth, y - mRealLineWidth)); rPoints.AddVertexOptim(nuiPoint(x + mRealLineWidth, y - mRealLineWidth)); rPoints.AddVertexOptim(nuiPoint(x + mRealLineWidth, y + mRealLineWidth)); rPoints.AddVertexOptim(nuiPoint(x - mRealLineWidth, y + mRealLineWidth)); rPoints.AddVertexOptim(nuiPoint(x - mRealLineWidth, y - mRealLineWidth)); } break; } } else if (closed && Left.GetCount() >= 2 && Right.GetCount() >= 2) // Case of a closed path (make sure that is at least a segment). { // Left: int ndx1 = 0; int ndx2 = 0; for (i = 0; i < segments-1; i++) { ndx1 = i * 2; ndx2 = ndx1 + 2; AddJoin(Left[ndx1], Left[ndx1+1], Left[ndx2], Left[ndx2+1], rPoints); } if (mLineJoin == nuiLineJoinBevel) rPoints.AddVertexOptim(rPoints.Front()); else rPoints.Back() = rPoints.Front(); rPoints.StopPath(); // Right: for (i = 0; i < segments; i++) { ndx1 = i * 2; ndx2 = ndx1 + 2; AddJoin(Right[ndx1], Right[ndx1+1], Right[ndx2], Right[ndx2+1], rPoints); } rPoints.StopPath(); } else { NGL_ASSERT(!Left.IsEmpty()); NGL_ASSERT(!Right.IsEmpty()); int cnt = segments - 1; // Left: rPoints.AddVertexOptim(Left.Front()); int ndx1 = 0; int ndx2 = 0; for (i = 0; i < cnt; i++) { ndx1 = i * 2; ndx2 = ndx1 + 2; AddJoin(Left[ndx1], Left[ndx1+1], Left[ndx2], Left[ndx2+1], rPoints); } AddCap(Left.Back(), Right.Front(), rPoints); // Right: for (i = 0; i < cnt; i++) { ndx1 = i * 2; ndx2 = ndx1 + 2; AddJoin(Right[ndx1], Right[ndx1+1], Right[ndx2], Right[ndx2+1], rPoints); } AddCap(Right.Back(), Left.Front(), rPoints); rPoints.Front() = rPoints.Back(); rPoints.StopPath(); } }