예제 #1
0
void CLayoutVertical::computeSize()
{
    // Nombre d'objets enfants
    const int nbr_children = getNumChildren();

    // Dimensions minimales et maximales du layout
    int min_height = 0;
    int max_height = 0;
    int min_width = 0;
    int max_width = 0;

    // Hauteur et largeur de chaque widget
    std::vector<int> widgets_h_min;
    std::vector<int> widgets_w_min;
    std::vector<int> widgets_h_max;
    std::vector<int> widgets_w_max;

    widgets_h_min.reserve(nbr_children);
    widgets_w_min.reserve(nbr_children);
    widgets_h_max.reserve(nbr_children);
    widgets_w_max.reserve(nbr_children);

    int totalStretch = 0;

    // On cherche la taille de chaque objet
    for (std::list<TLayoutItem>::const_iterator it = m_children.begin(); it != m_children.end(); ++it)
    {
        totalStretch += it->stretch;

        // Dimensions minimales
        int tmp_w = it->widget->getMinWidth();
        widgets_w_min.push_back(tmp_w);

        int tmp_h = it->widget->getMinHeight();
        widgets_h_min.push_back(tmp_h);

        tmp_w = SumInt(tmp_w, m_padding.getLeft() + m_padding.getRight());

        if (tmp_w > min_width)
        {
            min_width = tmp_w;
        }

        min_height = SumInt(min_height, SumInt(tmp_h, m_padding.getTop() + m_padding.getBottom()));

        // Dimensions maximales
        tmp_w = it->widget->getMaxWidth();
        widgets_w_max.push_back(tmp_w);

        tmp_h = it->widget->getMaxHeight();
        widgets_h_max.push_back(tmp_h);

        tmp_w = SumInt(tmp_w, m_padding.getLeft() + m_padding.getRight());

        if (tmp_w > max_width)
        {
            max_width = tmp_w;
        }

        max_height = SumInt(max_height, SumInt(tmp_h, m_padding.getTop() + m_padding.getBottom()));
    }

    min_width = SumInt(min_width, m_margin.getLeft() + m_margin.getRight());
    max_width = SumInt(max_width, m_margin.getLeft() + m_margin.getRight());

    min_height = SumInt(min_height, m_margin.getTop() + m_margin.getBottom());
    max_height = SumInt(max_height, m_margin.getTop() + m_margin.getBottom());

    setMinSize(min_width, min_height);
    setMaxSize(max_width, max_height);


    // Espace à répartir
    int residu = 0;

    if (min_height < m_height)
    {
        residu = m_height - min_height;
    }


    // Dimensions de chaque objet enfant
    std::vector<int> widgets_w;
    std::vector<int> widgets_h;

    widgets_w.reserve(nbr_children);
    widgets_h.reserve(nbr_children);

    int growingStretch = totalStretch;
    int growingChildren = nbr_children;

    // Calcul des dimensions de chaque objet enfant
    for (int i = 0; i < nbr_children; ++i)
    {
        if (widgets_w_min[i] < widgets_w_max[i])
        {
            if (widgets_w_max[i] < m_width - m_padding.getLeft() - m_padding.getRight())
                widgets_w[i] = widgets_w_min[i];
            else
                widgets_w[i] = m_width - m_padding.getLeft() - m_padding.getRight();
        }
        else
        {
            widgets_w[i] = widgets_w_min[i];
        }

        widgets_h[i] = widgets_h_min[i];

        if (widgets_h[i] >= widgets_h_max[i])
        {
            --growingChildren;
        }
    }


    while (residu > 0)
    {
        if (growingStretch == 0)
        {
            // Tous les widgets ont leur taille maximale
            if (growingChildren == 0)
            {
                int nbr_first = residu % nbr_children;
                int add_pixel = residu / nbr_children;
                residu = 0;

                int i = 0;

                // On modifie la taille des cases
                for (std::list<TLayoutItem>::iterator it = m_children.begin(); it != m_children.end(); ++it, ++i)
                {
                    it->size = widgets_h[i] + m_padding.getTop() + m_padding.getBottom() + add_pixel;
                    if (i < nbr_first)
                        ++(it->size);
                }
            }
            else
            {
                float pixelPerStretch = static_cast<float>(residu) / static_cast<float>(growingChildren);
                int pixelAdd = pixelPerStretch;

                if (pixelAdd == 0)
                {
                    growingChildren = 0;
                    continue;
                }

                int i = 0;

                // Pour chaque objet enfant
                for (std::list<TLayoutItem>::iterator it = m_children.begin(); it != m_children.end(); ++it, ++i)
                {
                    // On peut agrandir le widget
                    if (widgets_h[i] < widgets_h_max[i])
                    {
                        int pixelCanAdd = widgets_h_max[i] - widgets_h[i];

                        if (pixelCanAdd >= pixelAdd)
                        {
                            widgets_h[i] += pixelAdd;
                            residu -= pixelAdd;

                            if (pixelCanAdd == pixelAdd)
                            {
                                --growingChildren;
                            }
                        }
                        else
                        {
                            widgets_h[i] += pixelCanAdd;
                            residu -= pixelCanAdd;
                            --growingChildren;
                        }

                        it->size = widgets_h[i] + m_padding.getTop() + m_padding.getBottom();
                    }
                }
            }
        }
        else
        {
            float pixelPerStretch = static_cast<float>(residu) / static_cast<float>(growingStretch);

            if (pixelPerStretch < 1.0f)
            {
                growingStretch = 0;
                growingChildren = 0;
                continue;
            }

            bool noChange = true;
            int i = 0;

            // Pour chaque objet enfant
            for (std::list<TLayoutItem>::iterator it = m_children.begin(); it != m_children.end(); ++it, ++i)
            {
                // On peut agrandir le widget
                if (widgets_h[i] < widgets_h_max[i])
                {
                    int pixelAdd = pixelPerStretch * it->stretch;
                    int pixelCanAdd = widgets_h_max[i] - widgets_h[i];

                    if (pixelCanAdd >= pixelAdd)
                    {
                        widgets_h[i] += pixelAdd;
                        residu -= pixelAdd;

                        if (pixelCanAdd == pixelAdd)
                        {
                            --growingChildren;
                            growingStretch -= it->stretch;
                        }
                    }
                    else
                    {
                        widgets_h[i] += pixelCanAdd;
                        residu -= pixelCanAdd;

                        --growingChildren;
                        growingStretch -= it->stretch;
                    }

                    it->size = widgets_h[i] + m_padding.getTop() + m_padding.getBottom();

                    noChange = false;
                }
            }

            // Tous les widgets ont leur taille maximale
            if (noChange)
            {
                i = 0;

                // Pour chaque objet enfant
                for (std::list<TLayoutItem>::iterator it = m_children.begin(); it != m_children.end(); ++it, ++i)
                {
                    int pixelAdd = pixelPerStretch * it->stretch;
                    residu -= pixelAdd;
                    it->size = widgets_h[i] + m_padding.getTop() + m_padding.getBottom() + pixelAdd;
                }

                growingStretch = 0;
                growingChildren = 0;
            }
        }
    }


    int offset = m_margin.getTop();
    int i = 0;

    // On modifie la liste des objets
    for (std::list<TLayoutItem>::iterator it = m_children.begin(); it != m_children.end(); ++it, ++i)
    {
        // Dimensions de l'objet
        it->widget->setSize(widgets_w[i], widgets_h[i]);

        // Position de l'objet
        switch (it->align)
        {
            case AlignTopLeft:
                it->widget->setPosition(m_margin.getLeft() + m_padding.getLeft(), offset + m_padding.getTop());
                break;

            case AlignTopCenter:
                it->widget->setPosition((m_width - widgets_w[i]) / 2, offset + m_padding.getTop());
                break;

            case AlignTopRight:
                it->widget->setPosition(m_width - m_padding.getRight() - widgets_w[i], offset + m_padding.getTop());
                break;

            case AlignMiddleLeft:
                it->widget->setPosition(m_margin.getLeft() + m_padding.getLeft(), offset + (it->size - widgets_h[i]) / 2);
                break;

            default:
            case AlignMiddleCenter:
                it->widget->setPosition((m_width - widgets_w[i] ) / 2 , offset + (it->size - widgets_h[i]) / 2);
                break;

            case AlignMiddleRight:
                it->widget->setPosition(m_width - m_padding.getRight() - widgets_w[i], offset + (it->size - widgets_h[i]) / 2);
                break;

            case AlignBottomLeft:
                it->widget->setPosition(m_margin.getLeft() + m_padding.getLeft(), offset + it->size - widgets_h[i] - m_padding.getBottom());
                break;

            case AlignBottomCenter:
                it->widget->setPosition((m_width - widgets_w[i]) / 2 , offset + it->size - widgets_h[i] - m_padding.getBottom());
                break;

            case AlignBottomRight:
                it->widget->setPosition(m_width - m_padding.getRight() - widgets_w[i], offset + it->size - widgets_h[i] - m_padding.getBottom());
                break;
        }

        offset += it->size;
    }
}
예제 #2
0
int sumOfLevels(TreeNodePtr root){
	return SumInt(0,root);
}
예제 #3
0
int SumInt(int level,TreeNodePtr p){
	if (p == NULL) return 0;
	return level + SumInt(level+1,p->leftPtr) + SumInt(level+1,p->rightPtr);
}
예제 #4
0
int SumInt(int level, TreeNodePtr P){
	if (P == NULL) return 0;
	return level + SumInt(level+1,P->left) + SumInt(level+1,P->right);
}