diff --git a/apps/shared/banner_view.cpp b/apps/shared/banner_view.cpp index 0f7ff8af2..3420c5c1e 100644 --- a/apps/shared/banner_view.cpp +++ b/apps/shared/banner_view.cpp @@ -1,5 +1,5 @@ #include "banner_view.h" -#include +#include namespace Shared { @@ -12,61 +12,53 @@ KDSize BannerView::minimalSizeForOptimalDisplay() const { } void BannerView::layoutSubviews() { + assert(!m_frame.isEmpty()); /* We iterate on subviews, adding their width until we exceed the view bound. * The last subview that exceeds the bound is recorded as the first subview of * the next line. For the current line, we scan again the subviews and frame * them by equally distributing the remaining width. We then jump to the next * line and iterate the process. */ - KDCoordinate totalWidth = bounds().width(); - KDCoordinate lineWidth = 0; - View * textViewPreviousLine = subviewAtIndex(0); + const KDCoordinate lineWidth = m_frame.width(); + KDCoordinate remainingWidth = lineWidth; int indexOfFirstViewOfCurrentLine = 0; KDCoordinate y = 0; /* We do a last iteration of the loop to layout the last line. */ for (int i = 0; i <= numberOfSubviews(); i++) { - View * textView = nullptr; - KDCoordinate currentViewWidth = totalWidth; - if (i < numberOfSubviews()) { - textView = subviewAtIndex(i); - currentViewWidth = textView->minimalSizeForOptimalDisplay().width(); - } - // The subview exceed the total width - if (lineWidth + currentViewWidth > totalWidth) { + KDCoordinate subviewWidth = (i < numberOfSubviews()) ? subviewAtIndex(i)->minimalSizeForOptimalDisplay().width() : lineWidth; + if (subviewWidth > remainingWidth) { KDCoordinate x = 0; - int nbOfTextViewInLine = i > indexOfFirstViewOfCurrentLine ? i-indexOfFirstViewOfCurrentLine : 1; - KDCoordinate roundingError = totalWidth-lineWidth-nbOfTextViewInLine*(int)((totalWidth-lineWidth)/nbOfTextViewInLine); + int nbOfSubviewsOnLine = i > indexOfFirstViewOfCurrentLine ? i-indexOfFirstViewOfCurrentLine : 1; + KDCoordinate roundingError = remainingWidth % nbOfSubviewsOnLine; + View * subviewPreviousLine = nullptr; for (int j = indexOfFirstViewOfCurrentLine; j < i; j++) { - textViewPreviousLine = subviewAtIndex(j); - KDCoordinate textWidth = textViewPreviousLine->minimalSizeForOptimalDisplay().width() + (totalWidth - lineWidth)/nbOfTextViewInLine; - // For the last text view, avoid letting a 1-pixel-wide empty vertical due to rounding error: - textWidth = j == i-1 ? textWidth + roundingError : textWidth; - KDCoordinate textHeight = textViewPreviousLine->minimalSizeForOptimalDisplay().height(); - textViewPreviousLine->setFrame(KDRect(x, y, textWidth, textHeight)); - x += textWidth; + subviewPreviousLine = subviewAtIndex(j); + KDCoordinate width = subviewPreviousLine->minimalSizeForOptimalDisplay().width() + remainingWidth/nbOfSubviewsOnLine + (j == i-1) * roundingError; + KDCoordinate height = subviewPreviousLine->minimalSizeForOptimalDisplay().height(); + subviewPreviousLine->setFrame(KDRect(x, y, width, height)); + x += width; } // Next line - y += textViewPreviousLine->minimalSizeForOptimalDisplay().height(); - lineWidth = 0; + y += subviewPreviousLine->minimalSizeForOptimalDisplay().height(); + remainingWidth = lineWidth; indexOfFirstViewOfCurrentLine = i; } - lineWidth += currentViewWidth; + remainingWidth -= subviewWidth; } } int BannerView::numberOfLines() const { - KDCoordinate width = bounds().width(); - KDCoordinate usedWidth = 0; - KDCoordinate lineNumber = 0; + int lineNumber = 1; + const KDCoordinate lineWidth = m_frame.width(); + KDCoordinate remainingWidth = lineWidth; for (int i = 0; i < numberOfSubviews(); i++) { - KDCoordinate textWidth = const_cast(this)->subviewAtIndex(i)->minimalSizeForOptimalDisplay().width(); - if (usedWidth+textWidth > width) { - usedWidth = textWidth; + KDCoordinate subviewWidth = const_cast(this)->subviewAtIndex(i)->minimalSizeForOptimalDisplay().width(); + if (subviewWidth > remainingWidth) { + remainingWidth = lineWidth; lineNumber++; - } else { - usedWidth += textWidth; } + remainingWidth -= subviewWidth; } - return lineNumber+1; + return lineNumber; } }