Don't assume a fixed minimum width is sufficient for extended partitions: It's

not. Partition widgets that have children need to have the minium width
dynamically calculated.

svn path=/trunk/extragear/sysadmin/partitionmanager/; revision=907517
This commit is contained in:
Volker Lanz 2009-01-08 10:13:42 +00:00
parent ea2a943d2f
commit 6c4d8711d4
1 changed files with 29 additions and 15 deletions

View File

@ -54,33 +54,33 @@ bool distributeLostPixels(QList<qint32>& childrenWidth, qint32 lostPixels)
return true;
}
bool levelChildrenWidths(QList<qint32>& childrenWidth, const qint32 destWidgetWidth)
bool levelChildrenWidths(QList<qint32>& childrenWidth, const QList<qint32>& minChildrenWidth, const qint32 destWidgetWidth)
{
if (childrenWidth.size() == 0)
return false;
distributeLostPixels(childrenWidth, destWidgetWidth - sum(childrenWidth));
// if we find out a partition is too narrow, adjust its screen
// width to minWidth() and increase adjust by how much we had to increase the
// width to its minimum width and increase adjust by how much we had to increase the
// screen width. thus, in the end, we have the number of pixels we need
// to find somewhere else in adjust.
qint32 adjust = 0;
for (qint32 i = 0; i < childrenWidth.size(); i++)
if (childrenWidth[i] < PartWidgetBase::minWidth())
if (childrenWidth[i] < minChildrenWidth[i])
{
adjust += PartWidgetBase::minWidth() - childrenWidth[i];
childrenWidth[i] = PartWidgetBase::minWidth();
adjust += minChildrenWidth[i] - childrenWidth[i];
childrenWidth[i] = minChildrenWidth[i];
}
// find out how many partitions are wide enough to have their width reduced; we'd love to
// check for w > minWidth - (pixels_to_reduce_by), but that last value _depends_ on the
// number we're trying to find here...
qint32 numReducable = 0;
foreach(int w, childrenWidth)
if (w > PartWidgetBase::minWidth())
for (qint32 i = 0; i < childrenWidth.size(); i++)
if (childrenWidth[i] > minChildrenWidth[i])
numReducable++;
// no need to do anything... or nothing can be done because all are too narrow
if (adjust == 0 || numReducable == 0)
return false;
@ -90,12 +90,12 @@ bool levelChildrenWidths(QList<qint32>& childrenWidth, const qint32 destWidgetWi
// on screen widths of those big enough anyway
const qint32 reduce = ceil(1.0 * adjust / numReducable);
for (qint32 i = 0; i < childrenWidth.size(); i++)
if (childrenWidth[i] > PartWidgetBase::minWidth())
if (childrenWidth[i] > minChildrenWidth[i])
childrenWidth[i] -= reduce;
// distribute pixels lost due to rounding errors
distributeLostPixels(childrenWidth, destWidgetWidth - sum(childrenWidth));
return true;
}
@ -103,29 +103,43 @@ void PartWidgetBase::positionChildren(const QWidget* destWidget, const Partition
{
if (partitions.size() == 0)
return;
QList<qint32> childrenWidth;
QList<qint32> minChildrenWidth;
const qint32 destWidgetWidth = destWidget->width() - 2 * borderWidth() - (partitions.size() - 1) * spacing();
if (destWidgetWidth < 0)
return;
qint64 totalLength = 0;
foreach (const Partition* p, partitions)
totalLength += p->length();
// calculate unleveled width for each child and store it
for (int i = 0; i < partitions.size(); i++)
{
childrenWidth.append(partitions[i]->length() * destWidgetWidth / totalLength);
// Calculate the minimum width for the widget. This is easy for primary and logical partitions: they
// just have a fixed min width (configured in m_MinWidth). But for extended partitions things
// are not quite as simple. We need to calc the sum of the min widths for each child, taking
// spacing and borders into account, and add our own min width.
qint32 min = (minWidth() + 2 * borderWidth() + spacing()) * partitions[i]->children().size() - spacing() + 2 * borderWidth();
// if it's too small, this partition is a primary or logical so just use the configured value
if (min < minWidth())
min = minWidth();
minChildrenWidth.append(min);
}
// now go level the widths as long as required
while (levelChildrenWidths(childrenWidth, destWidgetWidth))
while (levelChildrenWidths(childrenWidth, minChildrenWidth, destWidgetWidth))
;
// move the children to their positions and resize them
for (int i = 0, x = borderWidth(); i < widgets.size(); i++)
{
widgets[i]->setMinimumWidth(minWidth());
widgets[i]->setMinimumWidth(minChildrenWidth[i]);
widgets[i]->move(x, borderHeight());
widgets[i]->resize(childrenWidth[i], destWidget->height() - 2 * borderHeight());
x += childrenWidth[i] + spacing();