m_enabledSelectionToggles(false),
m_grouped(false),
m_activeTransactions(0),
+ m_endTransactionAnimationHint(Animation),
m_itemSize(),
m_controller(0),
m_model(0),
it.next();
it.value()->setScrollOrientation(orientation);
}
+ updateGroupHeaderHeight();
+
}
doLayout(NoAnimation);
// 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());
m_itemSize = itemSize;
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();
+ }
+
QHashIterator<int, KItemListWidget*> it(m_visibleItems);
while (it.hasNext()) {
it.next();
it.value()->setStyleOption(option);
}
- m_sizeHintResolver->clearCache();
- doLayout(Animation);
+ m_sizeHintResolver->clearCache();
+ doLayout(animate ? Animation : NoAnimation);
+
onStyleOptionChanged(option, previousOption);
}
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) {
if (m_activeTransactions == 0) {
onTransactionEnd();
- doLayout(NoAnimation);
+ doLayout(m_endTransactionAnimationHint);
+ m_endTransactionAnimationHint = Animation;
}
}
return m_activeTransactions > 0;
}
-
void KItemListView::setHeaderShown(bool show)
{
// geometry update if necessary.
const int activeTransactions = m_activeTransactions;
m_activeTransactions = 0;
- doLayout(animateChangedItemCount(count) ? Animation : NoAnimation, index, -count);
+ doLayout(animateChangedItemCount(count) ? Animation : NoAnimation, index, -count);
m_activeTransactions = activeTransactions;
}
}
m_layouter->markAsDirty();
if (m_grouped) {
- // Apply the height of the header to the layouter
- const qreal groupHeaderHeight = m_styleOption.fontMetrics.height() +
- m_styleOption.margin * 2;
- m_layouter->setGroupHeaderHeight(groupHeaderHeight);
-
- updateVisibleGroupHeaders();
+ updateGroupHeaderHeight();
} else {
// Clear all visible headers
QMutableHashIterator<KItemListWidget*, KItemListGroupHeader*> it (m_visibleGroups);
m_layoutTimer->stop();
}
- if (!m_model || m_model->count() < 0 || m_activeTransactions > 0) {
+ if (m_activeTransactions > 0) {
+ if (hint == NoAnimation) {
+ // As soon as at least one property change should be done without animation,
+ // the whole transaction will be marked as not animated.
+ m_endTransactionAnimationHint = NoAnimation;
+ }
+ return;
+ }
+
+ if (!m_model || m_model->count() < 0) {
return;
}
// 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) {
return;
}
- KItemListGroupHeader* header = m_visibleGroups.value(widget);
- if (!header) {
- header = m_groupHeaderCreator->create(this);
- header->setParentItem(widget);
- m_visibleGroups.insert(widget, header);
+ KItemListGroupHeader* groupHeader = m_visibleGroups.value(widget);
+ if (!groupHeader) {
+ groupHeader = m_groupHeaderCreator->create(this);
+ groupHeader->setParentItem(widget);
+ m_visibleGroups.insert(widget, groupHeader);
}
- Q_ASSERT(header->parentItem() == widget);
+ Q_ASSERT(groupHeader->parentItem() == widget);
// Determine the shown data for the header by doing a binary
// search in the groups-list
}
} while (groups.at(mid).first != index && min <= max);
- header->setData(groups.at(mid).second);
- header->setRole(model()->sortRole());
- header->setStyleOption(m_styleOption);
- header->setScrollOrientation(scrollOrientation());
+ groupHeader->setData(groups.at(mid).second);
+ groupHeader->setRole(model()->sortRole());
+ groupHeader->setStyleOption(m_styleOption);
+ groupHeader->setScrollOrientation(scrollOrientation());
- header->show();
+ groupHeader->show();
}
void KItemListView::updateGroupHeaderLayout(KItemListWidget* widget)
{
- KItemListGroupHeader* header = m_visibleGroups.value(widget);
- Q_ASSERT(header);
+ KItemListGroupHeader* groupHeader = m_visibleGroups.value(widget);
+ Q_ASSERT(groupHeader);
const int index = widget->index();
const QRectF groupHeaderRect = m_layouter->groupHeaderRect(index);
// group header position to the relative position.
const QPointF groupHeaderPos(groupHeaderRect.x() - itemRect.x(),
- groupHeaderRect.height());
- header->setPos(groupHeaderPos);
- header->resize(groupHeaderRect.size());
+ groupHeader->setPos(groupHeaderPos);
+ groupHeader->resize(groupHeaderRect.size());
}
void KItemListView::recycleGroupHeaderForWidget(KItemListWidget* widget)
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 (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) {
- 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) {
- const int newRowCount = newGridSize.height() / newItemSize.height();
+ const int newRowCount = itemsPerSize(newGridSize.height(),
+ newItemSize.height(),
+ newItemMargin.height());
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 changedItemCount <= maximum * 2 / 3;
}
+
+bool KItemListView::scrollBarRequired(const QSizeF& size) const
+{
+ const QSizeF oldSize = m_layouter->size();
+
+ m_layouter->setSize(size);
+ const qreal maxOffset = m_layouter->maximumScrollOffset();
+ m_layouter->setSize(oldSize);
+
+ return m_layouter->scrollOrientation() == Qt::Vertical ? maxOffset > size.height()
+ : maxOffset > size.width();
+}
+
+void KItemListView::updateGroupHeaderHeight()
+{
+ qreal groupHeaderHeight = m_styleOption.fontMetrics.height();
+ groupHeaderHeight += (scrollOrientation() == Qt::Vertical)
+ ? m_styleOption.padding * 4 : m_styleOption.padding * 2;
+ m_layouter->setGroupHeaderHeight(groupHeaderHeight);
+
+ updateVisibleGroupHeaders();
+}
+
int KItemListView::calculateAutoScrollingIncrement(int pos, int range, int oldInc)
{
int inc = 0;
return inc;
}
+int KItemListView::itemsPerSize(qreal size, qreal itemSize, qreal itemMargin)
+{
+ const qreal availableSize = size - itemMargin;
+ const int count = availableSize / (itemSize + itemMargin);
+ return count;
+}
+
KItemListCreatorBase::~KItemListCreatorBase()