- Differ internally between margins and paddings
- Add a small padding in the icons-view and the compact-views
- Optimize the width of the icons-view if previews are shown
12 files changed:
void KFileItemListGroupHeader::updateText()
{
void KFileItemListGroupHeader::updateText()
{
- const qreal width = size().width() - 4 * styleOption().margin;
+ const qreal width = size().width() - 4 * styleOption().padding;
m_font = font(); // TODO: Most probably the font size will be slightly shrinked in future
QFontMetricsF fontMetrics(m_font);
m_font = font(); // TODO: Most probably the font size will be slightly shrinked in future
QFontMetricsF fontMetrics(m_font);
case IconsLayout: {
const QString text = KStringHandler::preProcessWrap(values["name"].toString());
case IconsLayout: {
const QString text = KStringHandler::preProcessWrap(values["name"].toString());
- const qreal maxWidth = itemSize().width() - 2 * option.margin;
+ const qreal maxWidth = itemSize().width() - 2 * option.padding;
int textLinesCount = 0;
QTextLine line;
int textLinesCount = 0;
QTextLine line;
const qreal height = textLinesCount * option.fontMetrics.height() +
option.iconSize +
const qreal height = textLinesCount * option.fontMetrics.height() +
option.iconSize +
return QSizeF(itemSize().width(), height);
}
return QSizeF(itemSize().width(), height);
}
maximumRequiredWidth = qMax(maximumRequiredWidth, requiredWidth);
}
maximumRequiredWidth = qMax(maximumRequiredWidth, requiredWidth);
}
- const qreal width = option.margin * 4 + option.iconSize + maximumRequiredWidth;
- const qreal height = option.margin * 2 + qMax(option.iconSize, (1 + additionalRolesCount) * option.fontMetrics.height());
+ const qreal width = option.padding * 4 + option.iconSize + maximumRequiredWidth;
+ const qreal height = option.padding * 2 + qMax(option.iconSize, (1 + additionalRolesCount) * option.fontMetrics.height());
return QSizeF(width, height);
}
case DetailsLayout: {
// The width will be determined dynamically by KFileItemListView::visibleRoleSizes()
return QSizeF(width, height);
}
case DetailsLayout: {
// The width will be determined dynamically by KFileItemListView::visibleRoleSizes()
- const qreal height = option.margin * 2 + qMax(option.iconSize, option.fontMetrics.height());
+ const qreal height = option.padding * 2 + qMax(option.iconSize, option.fontMetrics.height());
return QSizeF(-1, height);
}
return QSizeF(-1, height);
}
const KItemListStyleOption& option = styleOption();
qreal width = m_minimumRolesWidths.value(role, 0);
const KItemListStyleOption& option = styleOption();
qreal width = m_minimumRolesWidths.value(role, 0);
- const qreal height = option.margin * 2 + option.fontMetrics.height();
+ const qreal height = option.padding * 2 + option.fontMetrics.height();
const QHash<QByteArray, QVariant> values = model()->data(index);
const QString text = KFileItemListWidget::roleText(role, values);
if (!text.isEmpty()) {
const QHash<QByteArray, QVariant> values = model()->data(index);
const QString text = KFileItemListWidget::roleText(role, values);
if (!text.isEmpty()) {
- const qreal columnMargin = option.margin * 3;
- width = qMax(width, qreal(2 * columnMargin + option.fontMetrics.width(text)));
+ const qreal columnPadding = option.padding * 3;
+ width = qMax(width, qreal(2 * columnPadding + option.fontMetrics.width(text)));
}
if (role == "name") {
// Increase the width by the expansion-toggle and the current expansion level
const int expansionLevel = values.value("expansionLevel", 0).toInt();
}
if (role == "name") {
// Increase the width by the expansion-toggle and the current expansion level
const int expansionLevel = values.value("expansionLevel", 0).toInt();
- width += option.margin + expansionLevel * itemSize().height() + KIconLoader::SizeSmall;
+ width += option.padding + expansionLevel * itemSize().height() + KIconLoader::SizeSmall;
// Increase the width by the required space for the icon
// Increase the width by the required space for the icon
- width += option.margin * 2 + option.iconSize;
+ width += option.padding * 2 + option.iconSize;
}
return QSizeF(width, height);
}
return QSizeF(width, height);
const KItemListStyleOption& option = styleOption();
const int iconSize = option.iconSize;
if (m_itemLayout == IconsLayout) {
const KItemListStyleOption& option = styleOption();
const int iconSize = option.iconSize;
if (m_itemLayout == IconsLayout) {
- const int maxIconWidth = itemSize().width() - 2 * option.margin;
+ const int maxIconWidth = itemSize().width() - 2 * option.padding;
return QSize(maxIconWidth, iconSize);
}
return QSize(maxIconWidth, iconSize);
}
// Prevent a possible overlapping of the additional-information texts
// with the icon. This can happen if the user has minimized the width
// of the name-column to a very small value.
// Prevent a possible overlapping of the additional-information texts
// with the icon. This can happen if the user has minimized the width
// of the name-column to a very small value.
- const qreal minX = m_pixmapPos.x() + m_pixmap.width() + 4 * itemListStyleOption.margin;
+ const qreal minX = m_pixmapPos.x() + m_pixmap.width() + 4 * itemListStyleOption.padding;
if (m_textPos[Name + 1].x() < minX) {
clipAdditionalInfoBounds = true;
painter->save();
if (m_textPos[Name + 1].x() < minX) {
clipAdditionalInfoBounds = true;
painter->save();
// when trying to hit the toggle.
const int widgetHeight = size().height();
const int widgetWidth = size().width();
// when trying to hit the toggle.
const int widgetHeight = size().height();
const int widgetWidth = size().width();
- const int minMargin = 2;
+ const int minPadding = 2;
- if (toggleSize + minMargin * 2 >= widgetHeight) {
+ if (toggleSize + minPadding * 2 >= widgetHeight) {
toggleSize = widgetHeight;
pos.setY(0);
}
toggleSize = widgetHeight;
pos.setY(0);
}
- if (toggleSize + minMargin * 2 >= widgetWidth) {
+ if (toggleSize + minPadding * 2 >= widgetWidth) {
toggleSize = widgetWidth;
pos.setX(0);
}
toggleSize = widgetWidth;
pos.setX(0);
}
if (expansionLevel >= 0) {
const qreal widgetHeight = size().height();
const qreal expansionLevelSize = KIconLoader::SizeSmall;
if (expansionLevel >= 0) {
const qreal widgetHeight = size().height();
const qreal expansionLevelSize = KIconLoader::SizeSmall;
- const qreal x = option.margin + expansionLevel * widgetHeight;
+ const qreal x = option.padding + expansionLevel * widgetHeight;
const qreal y = (widgetHeight - expansionLevelSize) / 2;
m_expansionArea = QRectF(x, y, expansionLevelSize, expansionLevelSize);
return;
const qreal y = (widgetHeight - expansionLevelSize) / 2;
m_expansionArea = QRectF(x, y, expansionLevelSize, expansionLevelSize);
return;
const QSizeF widgetSize = size();
const bool iconOnTop = (m_layout == IconsLayout);
const KItemListStyleOption& option = styleOption();
const QSizeF widgetSize = size();
const bool iconOnTop = (m_layout == IconsLayout);
const KItemListStyleOption& option = styleOption();
- const qreal margin = option.margin;
+ const qreal padding = option.padding;
- const int maxIconWidth = iconOnTop ? widgetSize.width() - 2 * margin : option.iconSize;
+ const int maxIconWidth = iconOnTop ? widgetSize.width() - 2 * padding : option.iconSize;
const int maxIconHeight = option.iconSize;
const QHash<QByteArray, QVariant> values = data();
const int maxIconHeight = option.iconSize;
const QHash<QByteArray, QVariant> values = data();
int scaledIconSize = 0;
if (iconOnTop) {
int scaledIconSize = 0;
if (iconOnTop) {
- scaledIconSize = static_cast<int>(m_textPos[Name].y() - 2 * margin);
+ scaledIconSize = static_cast<int>(m_textPos[Name].y() - 2 * padding);
} else {
const int textRowsCount = (m_layout == CompactLayout) ? visibleRoles().count() : 1;
const qreal requiredTextHeight = textRowsCount * option.fontMetrics.height();
scaledIconSize = (requiredTextHeight < maxIconHeight) ?
} else {
const int textRowsCount = (m_layout == CompactLayout) ? visibleRoles().count() : 1;
const qreal requiredTextHeight = textRowsCount * option.fontMetrics.height();
scaledIconSize = (requiredTextHeight < maxIconHeight) ?
- widgetSize.height() - 2 * margin : maxIconHeight;
+ widgetSize.height() - 2 * padding : maxIconHeight;
- const int maxScaledIconWidth = iconOnTop ? widgetSize.width() - 2 * margin : scaledIconSize;
+ const int maxScaledIconWidth = iconOnTop ? widgetSize.width() - 2 * padding : scaledIconSize;
const int maxScaledIconHeight = scaledIconSize;
m_scaledPixmapSize = m_pixmap.size();
const int maxScaledIconHeight = scaledIconSize;
m_scaledPixmapSize = m_pixmap.size();
if (iconOnTop) {
// Center horizontally and align on bottom within the icon-area
m_pixmapPos.setX((widgetSize.width() - m_scaledPixmapSize.width()) / 2);
if (iconOnTop) {
// Center horizontally and align on bottom within the icon-area
m_pixmapPos.setX((widgetSize.width() - m_scaledPixmapSize.width()) / 2);
- m_pixmapPos.setY(margin + scaledIconSize - m_scaledPixmapSize.height());
+ m_pixmapPos.setY(padding + scaledIconSize - m_scaledPixmapSize.height());
} else {
// Center horizontally and vertically within the icon-area
} else {
// Center horizontally and vertically within the icon-area
- m_pixmapPos.setX(m_textPos[Name].x() - 2 * margin
+ m_pixmapPos.setX(m_textPos[Name].x() - 2 * padding
- (scaledIconSize + m_scaledPixmapSize.width()) / 2);
- (scaledIconSize + m_scaledPixmapSize.width()) / 2);
- m_pixmapPos.setY(margin
+ m_pixmapPos.setY(padding
+ (scaledIconSize - m_scaledPixmapSize.height()) / 2);
}
m_iconRect = QRectF(m_pixmapPos, QSizeF(m_scaledPixmapSize));
+ (scaledIconSize - m_scaledPixmapSize.height()) / 2);
}
m_iconRect = QRectF(m_pixmapPos, QSizeF(m_scaledPixmapSize));
- m_iconRect.adjust(-margin, -margin, margin, margin);
+ m_iconRect.adjust(-padding, -padding, padding, padding);
// Prepare the pixmap that is used when the item gets hovered
if (isHovered()) {
// Prepare the pixmap that is used when the item gets hovered
if (isHovered()) {
const QHash<QByteArray, QVariant> values = data();
const KItemListStyleOption& option = styleOption();
const QHash<QByteArray, QVariant> values = data();
const KItemListStyleOption& option = styleOption();
- const qreal margin = option.margin;
- const qreal maxWidth = size().width() - 2 * margin;
+ const qreal padding = option.padding;
+ const qreal maxWidth = size().width() - 2 * padding;
const qreal widgetHeight = size().height();
const qreal fontHeight = option.fontMetrics.height();
const qreal widgetHeight = size().height();
const qreal fontHeight = option.fontMetrics.height();
textLinesCount += additionalRolesCount;
m_text[Name].setTextWidth(maxWidth);
textLinesCount += additionalRolesCount;
m_text[Name].setTextWidth(maxWidth);
- m_textPos[Name] = QPointF(margin, widgetHeight - textLinesCount * fontHeight - margin);
- m_textRect = QRectF(margin + (maxWidth - requiredWidthForName) / 2,
+ m_textPos[Name] = QPointF(padding, widgetHeight - textLinesCount * fontHeight - padding);
+ m_textRect = QRectF(padding + (maxWidth - requiredWidthForName) / 2,
m_textPos[Name].y(),
requiredWidthForName,
textLinesCountForName * fontHeight);
m_textPos[Name].y(),
requiredWidthForName,
textLinesCountForName * fontHeight);
// TODO: QFontMetrics::elidedText() works different regarding the given width
// in comparison to QTextLine::setLineWidth(). It might happen that the text does
// not get elided although it does not fit into the given width. As workaround
// TODO: QFontMetrics::elidedText() works different regarding the given width
// in comparison to QTextLine::setLineWidth(). It might happen that the text does
// not get elided although it does not fit into the given width. As workaround
- // the margin is substracted.
- const QString elidedText = option.fontMetrics.elidedText(text, Qt::ElideRight, maxWidth - margin);
+ // the padding is substracted.
+ const QString elidedText = option.fontMetrics.elidedText(text, Qt::ElideRight, maxWidth - padding);
m_text[textId].setText(elidedText);
}
}
layout.endLayout();
m_text[textId].setText(elidedText);
}
}
layout.endLayout();
- m_textPos[textId] = QPointF(margin, y);
+ m_textPos[textId] = QPointF(padding, y);
m_text[textId].setTextWidth(maxWidth);
m_text[textId].setTextWidth(maxWidth);
- const QRectF textRect(margin + (maxWidth - requiredWidth) / 2, y, requiredWidth, fontHeight);
+ const QRectF textRect(padding + (maxWidth - requiredWidth) / 2, y, requiredWidth, fontHeight);
m_textRect |= textRect;
y += fontHeight;
}
m_textRect |= textRect;
y += fontHeight;
}
- // Add a margin to the text rectangle
- m_textRect.adjust(-margin, -margin, margin, margin);
+ // Add a padding to the text rectangle
+ m_textRect.adjust(-padding, -padding, padding, padding);
}
void KFileItemListWidget::updateCompactLayoutTextCache()
}
void KFileItemListWidget::updateCompactLayoutTextCache()
const qreal widgetHeight = size().height();
const qreal fontHeight = option.fontMetrics.height();
const qreal textLinesHeight = qMax(visibleRoles().count(), 1) * fontHeight;
const qreal widgetHeight = size().height();
const qreal fontHeight = option.fontMetrics.height();
const qreal textLinesHeight = qMax(visibleRoles().count(), 1) * fontHeight;
- const int scaledIconSize = (textLinesHeight < option.iconSize) ? widgetHeight - 2 * option.margin : option.iconSize;
+ const int scaledIconSize = (textLinesHeight < option.iconSize) ? widgetHeight - 2 * option.padding : option.iconSize;
qreal maximumRequiredTextWidth = 0;
qreal maximumRequiredTextWidth = 0;
- const qreal x = option.margin * 3 + scaledIconSize;
+ const qreal x = option.padding * 3 + scaledIconSize;
qreal y = (widgetHeight - textLinesHeight) / 2;
qreal y = (widgetHeight - textLinesHeight) / 2;
- const qreal maxWidth = size().width() - x - option.margin;
+ const qreal maxWidth = size().width() - x - option.padding;
foreach (const QByteArray& role, m_sortedVisibleRoles) {
const TextId textId = roleTextId(role);
foreach (const QByteArray& role, m_sortedVisibleRoles) {
const TextId textId = roleTextId(role);
- m_textRect = QRectF(x - option.margin, 0, maximumRequiredTextWidth + 2 * option.margin, widgetHeight);
+ m_textRect = QRectF(x - option.padding, 0, maximumRequiredTextWidth + 2 * option.padding, widgetHeight);
}
void KFileItemListWidget::updateDetailsLayoutTextCache()
}
void KFileItemListWidget::updateDetailsLayoutTextCache()
const QHash<QByteArray, QVariant> values = data();
const qreal widgetHeight = size().height();
const QHash<QByteArray, QVariant> values = data();
const qreal widgetHeight = size().height();
- const int scaledIconSize = widgetHeight - 2 * option.margin;
+ const int scaledIconSize = widgetHeight - 2 * option.padding;
const int fontHeight = option.fontMetrics.height();
const int fontHeight = option.fontMetrics.height();
- const qreal columnMargin = option.margin * 3;
- const qreal firstColumnInc = m_expansionArea.right() + option.margin * 2 + scaledIconSize;
+ const qreal columnPadding = option.padding * 3;
+ const qreal firstColumnInc = m_expansionArea.right() + option.padding * 2 + scaledIconSize;
qreal x = firstColumnInc;
qreal x = firstColumnInc;
- const qreal y = qMax(qreal(option.margin), (widgetHeight - fontHeight) / 2);
+ const qreal y = qMax(qreal(option.padding), (widgetHeight - fontHeight) / 2);
foreach (const QByteArray& role, m_sortedVisibleRoles) {
const TextId textId = roleTextId(role);
foreach (const QByteArray& role, m_sortedVisibleRoles) {
const TextId textId = roleTextId(role);
// Elide the text in case it does not fit into the available column-width
qreal requiredWidth = option.fontMetrics.width(text);
const qreal columnWidth = visibleRolesSizes().value(role, QSizeF(0, 0)).width();
// Elide the text in case it does not fit into the available column-width
qreal requiredWidth = option.fontMetrics.width(text);
const qreal columnWidth = visibleRolesSizes().value(role, QSizeF(0, 0)).width();
- qreal availableTextWidth = columnWidth - 2 * columnMargin;
+ qreal availableTextWidth = columnWidth - 2 * columnPadding;
if (textId == Name) {
availableTextWidth -= firstColumnInc;
}
if (textId == Name) {
availableTextWidth -= firstColumnInc;
}
}
m_text[textId].setText(text);
}
m_text[textId].setText(text);
- m_textPos[textId] = QPointF(x + columnMargin, y);
+ m_textPos[textId] = QPointF(x + columnPadding, y);
x += columnWidth;
switch (textId) {
case Name: {
x += columnWidth;
switch (textId) {
case Name: {
- m_textRect = QRectF(m_textPos[textId].x() - option.margin, 0,
- requiredWidth + 2 * option.margin, size().height());
+ m_textRect = QRectF(m_textPos[textId].x() - option.padding, 0,
+ requiredWidth + 2 * option.padding, size().height());
// The column after the name should always be aligned on the same x-position independent
// from the expansion-level shown in the name column
// The column after the name should always be aligned on the same x-position independent
// from the expansion-level shown in the name column
}
case Size:
// The values for the size should be right aligned
}
case Size:
// The values for the size should be right aligned
- m_textPos[textId].rx() += columnWidth - requiredWidth - 2 * columnMargin;
+ m_textPos[textId].rx() += columnWidth - requiredWidth - 2 * columnPadding;
if (m_scrollOrientation != Qt::Horizontal) {
painter->setPen(m_roleColor);
if (m_scrollOrientation != Qt::Horizontal) {
painter->setPen(m_roleColor);
- const qreal y = m_roleBounds.y() - m_styleOption.margin;
+ const qreal y = m_roleBounds.y() - m_styleOption.padding;
painter->drawLine(0, y, size().width() - 1, y);
}
}
painter->drawLine(0, y, size().width() - 1, y);
}
}
(c1.green() * p1 + c2.green() * p2) / 100,
(c1.blue() * p1 + c2.blue() * p2) / 100);
(c1.green() * p1 + c2.green() * p2) / 100,
(c1.blue() * p1 + c2.blue() * p2) / 100);
- const int margin = m_styleOption.margin;
+ const int padding = m_styleOption.padding;
const QFontMetrics fontMetrics(m_styleOption.font);
const qreal roleHeight = fontMetrics.height();
const QFontMetrics fontMetrics(m_styleOption.font);
const qreal roleHeight = fontMetrics.height();
- m_roleBounds = QRectF(margin,
- size().height() - roleHeight - margin,
- size().width() - 2 * margin,
+ m_roleBounds = QRectF(padding,
+ size().height() - roleHeight - padding,
+ size().width() - 2 * padding,
roleHeight);
m_dirtyCache = false;
roleHeight);
m_dirtyCache = false;
font(),
fontMetrics(QFont()),
palette(),
font(),
fontMetrics(QFont()),
palette(),
+ padding(0),
+ horizontalMargin(0),
+ verticalMargin(0),
iconSize(KIconLoader::SizeMedium)
{
}
iconSize(KIconLoader::SizeMedium)
{
}
font(other.font),
fontMetrics(other.fontMetrics),
palette(other.palette),
font(other.font),
fontMetrics(other.fontMetrics),
palette(other.palette),
+ padding(other.padding),
+ horizontalMargin(other.horizontalMargin),
+ verticalMargin(other.verticalMargin),
iconSize(other.iconSize)
{
}
iconSize(other.iconSize)
{
}
QFont font;
QFontMetrics fontMetrics;
QPalette palette;
QFont font;
QFontMetrics fontMetrics;
QPalette palette;
+ int padding;
+ int horizontalMargin;
+ int verticalMargin;
// Skip animations when the number of rows or columns
// are changed in the grid layout. Although the animation
// engine can handle this usecase, it looks obtrusive.
// Skip animations when the number of rows or columns
// are changed in the grid layout. Although the animation
// engine can handle this usecase, it looks obtrusive.
- const bool animate = !changesItemGridLayout(m_layouter->size(), itemSize);
+ const bool animate = !changesItemGridLayout(m_layouter->size(),
+ itemSize,
+ m_layouter->itemMargin());
const KItemListStyleOption previousOption = m_styleOption;
m_styleOption = option;
const KItemListStyleOption previousOption = m_styleOption;
m_styleOption = option;
+ bool animate = true;
+ const QSizeF margin(option.horizontalMargin, option.verticalMargin);
+ if (margin != m_layouter->itemMargin()) {
+ // Skip animations when the number of rows or columns
+ // are changed in the grid layout. Although the animation
+ // engine can handle this usecase, it looks obtrusive.
+ animate = !changesItemGridLayout(m_layouter->size(),
+ m_layouter->itemSize(),
+ margin);
+ m_layouter->setItemMargin(margin);
+ }
+
if (m_grouped) {
updateGroupHeaderHeight();
}
if (m_grouped) {
updateGroupHeaderHeight();
}
}
m_sizeHintResolver->clearCache();
}
m_sizeHintResolver->clearCache();
+ doLayout(animate ? Animation : NoAnimation);
onStyleOptionChanged(option, previousOption);
}
onStyleOptionChanged(option, previousOption);
}
m_layouter->setSize(newSize);
doLayout(Animation);
} else {
m_layouter->setSize(newSize);
doLayout(Animation);
} else {
- const bool animate = !changesItemGridLayout(newSize, m_layouter->itemSize());
+ const bool animate = !changesItemGridLayout(newSize,
+ m_layouter->itemSize(),
+ m_layouter->itemMargin());
m_layouter->setSize(newSize);
if (animate) {
m_layouter->setSize(newSize);
if (animate) {
// one row in the vertical scroll-orientation or one column in the horizontal scroll-orientation.
// Otherwise instead of a moving-animation a create-animation on the new position will be used
// instead. This is done to prevent overlapping (and confusing) moving-animations.
// one row in the vertical scroll-orientation or one column in the horizontal scroll-orientation.
// Otherwise instead of a moving-animation a create-animation on the new position will be used
// instead. This is done to prevent overlapping (and confusing) moving-animations.
- const qreal xMax = m_itemSize.width();
- const qreal yMax = m_itemSize.height();
+ const QSizeF itemMargin = m_layouter->itemMargin();
+ const qreal xMax = m_itemSize.width() + itemMargin.width();
+ const qreal yMax = m_itemSize.height() + itemMargin.height();
qreal xDiff = qAbs(oldPos.x() - newPos.x());
qreal yDiff = qAbs(oldPos.y() - newPos.y());
if (scrollOrientation() == Qt::Vertical) {
qreal xDiff = qAbs(oldPos.x() - newPos.x());
qreal yDiff = qAbs(oldPos.y() - newPos.y());
if (scrollOrientation() == Qt::Vertical) {
return m_header ? m_header->geometry() : QRectF();
}
return m_header ? m_header->geometry() : QRectF();
}
-bool KItemListView::changesItemGridLayout(const QSizeF& newGridSize, const QSizeF& newItemSize) const
+bool KItemListView::changesItemGridLayout(const QSizeF& newGridSize,
+ const QSizeF& newItemSize,
+ const QSizeF& newItemMargin) const
{
if (newItemSize.isEmpty() || newGridSize.isEmpty()) {
return false;
{
if (newItemSize.isEmpty() || newGridSize.isEmpty()) {
return false;
if (m_layouter->scrollOrientation() == Qt::Vertical) {
const qreal itemWidth = m_layouter->itemSize().width();
if (itemWidth > 0) {
if (m_layouter->scrollOrientation() == Qt::Vertical) {
const qreal itemWidth = m_layouter->itemSize().width();
if (itemWidth > 0) {
- const int newColumnCount = newGridSize.width() / newItemSize.width();
+ const int newColumnCount = itemsPerSize(newGridSize.width(),
+ newItemSize.width(),
+ newItemMargin.width());
if (m_model->count() > newColumnCount) {
if (m_model->count() > newColumnCount) {
- const int oldColumnCount = m_layouter->size().width() / itemWidth;
+ const int oldColumnCount = itemsPerSize(m_layouter->size().width(),
+ itemWidth,
+ m_layouter->itemMargin().width());
return oldColumnCount != newColumnCount;
}
}
} else {
const qreal itemHeight = m_layouter->itemSize().height();
if (itemHeight > 0) {
return oldColumnCount != newColumnCount;
}
}
} else {
const qreal itemHeight = m_layouter->itemSize().height();
if (itemHeight > 0) {
- const int newRowCount = newGridSize.height() / newItemSize.height();
+ const int newRowCount = itemsPerSize(newGridSize.height(),
+ newItemSize.height(),
+ newItemMargin.height());
if (m_model->count() > newRowCount) {
if (m_model->count() > newRowCount) {
- const int oldRowCount = m_layouter->size().height() / itemHeight;
+ const int oldRowCount = itemsPerSize(m_layouter->size().height(),
+ itemHeight,
+ m_layouter->itemMargin().height());
return oldRowCount != newRowCount;
}
}
return oldRowCount != newRowCount;
}
}
{
qreal groupHeaderHeight = m_styleOption.fontMetrics.height();
groupHeaderHeight += (scrollOrientation() == Qt::Vertical)
{
qreal groupHeaderHeight = m_styleOption.fontMetrics.height();
groupHeaderHeight += (scrollOrientation() == Qt::Vertical)
- ? m_styleOption.margin * 4 : m_styleOption.margin * 2;
+ ? m_styleOption.padding * 4 : m_styleOption.padding * 2;
m_layouter->setGroupHeaderHeight(groupHeaderHeight);
updateVisibleGroupHeaders();
m_layouter->setGroupHeaderHeight(groupHeaderHeight);
updateVisibleGroupHeaders();
+int KItemListView::itemsPerSize(qreal size, qreal itemSize, qreal itemMargin)
+{
+ const qreal availableSize = size - itemMargin;
+ const int count = availableSize / (itemSize + itemMargin);
+ return count;
+}
+
KItemListCreatorBase::~KItemListCreatorBase()
KItemListCreatorBase::~KItemListCreatorBase()
* the new grid- and item-size. Used to determine whether an animation
* should be done when applying the new layout.
*/
* the new grid- and item-size. Used to determine whether an animation
* should be done when applying the new layout.
*/
- bool changesItemGridLayout(const QSizeF& newGridSize, const QSizeF& newItemSize) const;
+ bool changesItemGridLayout(const QSizeF& newGridSize,
+ const QSizeF& newItemSize,
+ const QSizeF& newItemMargin) const;
/**
* @param changedItemCount Number of inserted or removed items.
/**
* @param changedItemCount Number of inserted or removed items.
* value != 0 will be returned.
*/
static int calculateAutoScrollingIncrement(int pos, int range, int oldInc);
* value != 0 will be returned.
*/
static int calculateAutoScrollingIncrement(int pos, int range, int oldInc);
+
+ /**
+ * Helper functions for changesItemCount().
+ * @return The number of items that fit into the available size by
+ * respecting the size of the item and the margin between the items.
+ */
+ static int itemsPerSize(qreal size, qreal itemSize, qreal itemMargin);
private:
bool m_enabledSelectionToggles;
private:
bool m_enabledSelectionToggles;
m_scrollOrientation(Qt::Vertical),
m_size(),
m_itemSize(128, 128),
m_scrollOrientation(Qt::Vertical),
m_size(),
m_itemSize(128, 128),
m_headerHeight(0),
m_model(0),
m_sizeHintResolver(0),
m_headerHeight(0),
m_model(0),
m_sizeHintResolver(0),
+void KItemListViewLayouter::setItemMargin(const QSizeF& margin)
+{
+ if (m_itemMargin != margin) {
+ m_itemMargin = margin;
+ m_dirty = true;
+ }
+}
+
+QSizeF KItemListViewLayouter::itemMargin() const
+{
+ return m_itemMargin;
+}
+
void KItemListViewLayouter::setHeaderHeight(qreal height)
{
if (m_headerHeight != height) {
void KItemListViewLayouter::setHeaderHeight(qreal height)
{
if (m_headerHeight != height) {
m_visibleIndexesDirty = true;
QSizeF itemSize = m_itemSize;
m_visibleIndexesDirty = true;
QSizeF itemSize = m_itemSize;
+ QSizeF itemMargin = m_itemMargin;
QSizeF size = m_size;
const bool grouped = createGroupHeaders();
QSizeF size = m_size;
const bool grouped = createGroupHeaders();
// a vertical scrolling
itemSize.setWidth(m_itemSize.height());
itemSize.setHeight(m_itemSize.width());
// a vertical scrolling
itemSize.setWidth(m_itemSize.height());
itemSize.setHeight(m_itemSize.width());
+ itemMargin.setWidth(m_itemMargin.height());
+ itemMargin.setHeight(m_itemMargin.width());
size.setWidth(m_size.height());
size.setHeight(m_size.width());
size.setWidth(m_size.height());
size.setHeight(m_size.width());
- m_columnWidth = itemSize.width();
- m_columnCount = qMax(1, int(size.width() / m_columnWidth));
- m_xPosInc = 0;
+ m_columnWidth = itemSize.width() + itemMargin.width();
+ const qreal widthForColumns = size.width() - itemMargin.width();
+ m_columnCount = qMax(1, int(widthForColumns / m_columnWidth));
+ m_xPosInc = itemMargin.width();
const int itemCount = m_model->count();
if (itemCount > m_columnCount) {
const int itemCount = m_model->count();
if (itemCount > m_columnCount) {
m_itemRects.reserve(itemCount);
m_itemRects.reserve(itemCount);
- qreal y = m_headerHeight;
+ qreal y = m_headerHeight + itemMargin.height();
int rowIndex = 0;
int index = 0;
int rowIndex = 0;
int index = 0;
+ y += maxItemHeight + itemMargin.height();
++rowIndex;
}
if (m_itemRects.count() > itemCount) {
m_itemRects.erase(m_itemRects.begin() + itemCount,
++rowIndex;
}
if (m_itemRects.count() > itemCount) {
m_itemRects.erase(m_itemRects.begin() + itemCount,
void setItemSize(const QSizeF& size);
QSizeF itemSize() const;
void setItemSize(const QSizeF& size);
QSizeF itemSize() const;
+ /**
+ * Margin between the rows and columns of items.
+ */
+ void setItemMargin(const QSizeF& margin);
+ QSizeF itemMargin() const;
+
/**
* Sets the height of the header that is always aligned
* at the top. A height of <= 0.0 means that no header is
/**
* Sets the height of the header that is always aligned
* at the top. A height of <= 0.0 means that no header is
*/
void setGroupHeaderHeight(qreal height);
qreal groupHeaderHeight() const;
*/
void setGroupHeaderHeight(qreal height);
qreal groupHeaderHeight() const;
-
- // TODO: add note that offset can be < 0 or > maximumOffset!
void setScrollOffset(qreal scrollOffset);
qreal scrollOffset() const;
void setScrollOffset(qreal scrollOffset);
qreal scrollOffset() const;
QSizeF m_size;
QSizeF m_itemSize;
QSizeF m_size;
QSizeF m_itemSize;
+ QSizeF m_itemMargin;
+ qreal m_headerHeight;
const KItemModelBase* m_model;
const KItemListSizeHintResolver* m_sizeHintResolver;
const KItemModelBase* m_model;
const KItemListSizeHintResolver* m_sizeHintResolver;
view->setWidgetCreator(new KItemListWidgetCreator<KFileItemListWidget>());
KItemListStyleOption styleOption = view->styleOption();
view->setWidgetCreator(new KItemListWidgetCreator<KFileItemListWidget>());
KItemListStyleOption styleOption = view->styleOption();
- styleOption.margin = 2;
+ styleOption.padding = 2;
styleOption.iconSize = KIconLoader::SizeSmall;
view->setStyleOption(styleOption);
const qreal itemHeight = qMax(int(KIconLoader::SizeSmall), styleOption.fontMetrics.height());
styleOption.iconSize = KIconLoader::SizeSmall;
view->setStyleOption(styleOption);
const qreal itemHeight = qMax(int(KIconLoader::SizeSmall), styleOption.fontMetrics.height());
- view->setItemSize(QSizeF(-1, itemHeight + 2 * styleOption.margin));
+ view->setItemSize(QSizeF(-1, itemHeight + 2 * styleOption.padding));
view->setItemLayout(KFileItemListView::DetailsLayout);
// Set the opacity to 0 initially. The opacity will be increased after the loading of the initial tree
// has been finished in slotLoadingCompleted(). This prevents an unnecessary animation-mess when
view->setItemLayout(KFileItemListView::DetailsLayout);
// Set the opacity to 0 initially. The opacity will be increased after the loading of the initial tree
// has been finished in slotLoadingCompleted(). This prevents an unnecessary animation-mess when
m_zoomLevel = ZoomLevelInfo::zoomLevelForIconSize(QSize(iconSize, iconSize));
KItemListStyleOption styleOption = m_fileItemListView->styleOption();
m_zoomLevel = ZoomLevelInfo::zoomLevelForIconSize(QSize(iconSize, iconSize));
KItemListStyleOption styleOption = m_fileItemListView->styleOption();
- const int innerMargin = (iconSize >= KIconLoader::SizeSmallMedium) ? 4 : 2;
+ const int padding = (iconSize >= KIconLoader::SizeSmallMedium) ? 4 : 2;
+ int horizontalMargin = 0;
+ int verticalMargin = 0;
// Calculate the item-width and item-height
int itemWidth;
// Calculate the item-width and item-height
int itemWidth;
case KFileItemListView::IconsLayout: {
const int minItemWidth = 64;
itemWidth = minItemWidth + IconsModeSettings::textWidthIndex() * 64;
case KFileItemListView::IconsLayout: {
const int minItemWidth = 64;
itemWidth = minItemWidth + IconsModeSettings::textWidthIndex() * 64;
- if (itemWidth < iconSize + innerMargin * 2) {
- itemWidth = iconSize + innerMargin * 2;
+
+ if (previewsShown()) {
+ // Optimize the width for previews with a 3:2 aspect ratio instead
+ // of a 1:1 ratio to avoid wasting too much vertical space when
+ // photos.
+ const int minWidth = iconSize * 3 / 2;
+ itemWidth = qMax(itemWidth, minWidth);
- itemHeight = innerMargin * 3 + iconSize + styleOption.fontMetrics.height();
+
+ if (itemWidth < iconSize + padding * 2) {
+ itemWidth = iconSize + padding * 2;
+ }
+ itemHeight = padding * 3 + iconSize + styleOption.fontMetrics.height();
+
+ horizontalMargin = padding * 2;
+ verticalMargin = horizontalMargin;
break;
}
case KFileItemListView::CompactLayout: {
break;
}
case KFileItemListView::CompactLayout: {
- itemWidth = innerMargin * 4 + iconSize + styleOption.fontMetrics.height() * 5;
+ itemWidth = padding * 4 + iconSize + styleOption.fontMetrics.height() * 5;
const int textLinesCount = m_fileItemListView->visibleRoles().count();
const int textLinesCount = m_fileItemListView->visibleRoles().count();
- itemHeight = innerMargin * 2 + qMax(iconSize, textLinesCount * styleOption.fontMetrics.height());
+ itemHeight = padding * 2 + qMax(iconSize, textLinesCount * styleOption.fontMetrics.height());
+
+ horizontalMargin = padding * 2;
break;
}
case KFileItemListView::DetailsLayout: {
itemWidth = -1;
break;
}
case KFileItemListView::DetailsLayout: {
itemWidth = -1;
- itemHeight = innerMargin * 2 + qMax(iconSize, styleOption.fontMetrics.height());
+ itemHeight = padding * 2 + qMax(iconSize, styleOption.fontMetrics.height());
}
// Apply the calculated values
}
// Apply the calculated values
- styleOption.margin = innerMargin;
+ styleOption.padding = padding;
+ styleOption.horizontalMargin = horizontalMargin;
+ styleOption.verticalMargin = verticalMargin;
styleOption.iconSize = iconSize;
m_fileItemListView->beginTransaction();
m_fileItemListView->setStyleOption(styleOption);
styleOption.iconSize = iconSize;
m_fileItemListView->beginTransaction();
m_fileItemListView->setStyleOption(styleOption);