! \internal This is a helper function for the implementation of \ref updateLayout in subclasses. It calculates the sizes of one-dimensional sections with provided constraints on maximum section sizes, minimum section sizes, relative stretch factors and the final total size of all sections. The QVector entries refer to the sections. Thus all QVectors must have the same size. \
| 3868 | The return value is a QVector containing the section sizes. |
| 3869 | */ |
| 3870 | QVector<int> QCPLayout::getSectionSizes(QVector<int> maxSizes, QVector<int> minSizes, QVector<double> stretchFactors, int totalSize) const |
| 3871 | { |
| 3872 | if (maxSizes.size() != minSizes.size() || minSizes.size() != stretchFactors.size()) |
| 3873 | { |
| 3874 | qDebug() << Q_FUNC_INFO << "Passed vector sizes aren't equal:" << maxSizes << minSizes << stretchFactors; |
| 3875 | return QVector<int>(); |
| 3876 | } |
| 3877 | if (stretchFactors.isEmpty()) |
| 3878 | return QVector<int>(); |
| 3879 | int sectionCount = stretchFactors.size(); |
| 3880 | QVector<double> sectionSizes(sectionCount); |
| 3881 | // if provided total size is forced smaller than total minimum size, ignore minimum sizes (squeeze sections): |
| 3882 | int minSizeSum = 0; |
| 3883 | for (int i=0; i<sectionCount; ++i) |
| 3884 | minSizeSum += minSizes.at(i); |
| 3885 | if (totalSize < minSizeSum) |
| 3886 | { |
| 3887 | // new stretch factors are minimum sizes and minimum sizes are set to zero: |
| 3888 | for (int i=0; i<sectionCount; ++i) |
| 3889 | { |
| 3890 | stretchFactors[i] = minSizes.at(i); |
| 3891 | minSizes[i] = 0; |
| 3892 | } |
| 3893 | } |
| 3894 | |
| 3895 | QList<int> minimumLockedSections; |
| 3896 | QList<int> unfinishedSections; |
| 3897 | for (int i=0; i<sectionCount; ++i) |
| 3898 | unfinishedSections.append(i); |
| 3899 | double freeSize = totalSize; |
| 3900 | |
| 3901 | int outerIterations = 0; |
| 3902 | while (!unfinishedSections.isEmpty() && outerIterations < sectionCount*2) // the iteration check ist just a failsafe in case something really strange happens |
| 3903 | { |
| 3904 | ++outerIterations; |
| 3905 | int innerIterations = 0; |
| 3906 | while (!unfinishedSections.isEmpty() && innerIterations < sectionCount*2) // the iteration check ist just a failsafe in case something really strange happens |
| 3907 | { |
| 3908 | ++innerIterations; |
| 3909 | // find section that hits its maximum next: |
| 3910 | int nextId = -1; |
| 3911 | double nextMax = 1e12; |
| 3912 | for (int i=0; i<unfinishedSections.size(); ++i) |
| 3913 | { |
| 3914 | int secId = unfinishedSections.at(i); |
| 3915 | double hitsMaxAt = (maxSizes.at(secId)-sectionSizes.at(secId))/stretchFactors.at(secId); |
| 3916 | if (hitsMaxAt < nextMax) |
| 3917 | { |
| 3918 | nextMax = hitsMaxAt; |
| 3919 | nextId = secId; |
| 3920 | } |
| 3921 | } |
| 3922 | // check if that maximum is actually within the bounds of the total size (i.e. can we stretch all remaining sections so far that the found section |
| 3923 | // actually hits its maximum, without exceeding the total size when we add up all sections) |
| 3924 | double stretchFactorSum = 0; |
| 3925 | for (int i=0; i<unfinishedSections.size(); ++i) |
| 3926 | stretchFactorSum += stretchFactors.at(unfinishedSections.at(i)); |
| 3927 | double nextMaxLimit = freeSize/stretchFactorSum; |