return QSize();
}
-QHash<QByteArray, QSizeF> KFileItemListView::visibleRoleSizes() const
+QHash<QByteArray, QSizeF> KFileItemListView::visibleRolesSizes() const
{
QElapsedTimer timer;
timer.start();
triggerVisibleIndexRangeUpdate();
}
-void KFileItemListView::onOffsetChanged(qreal current, qreal previous)
+void KFileItemListView::onScrollOffsetChanged(qreal current, qreal previous)
{
Q_UNUSED(current);
Q_UNUSED(previous);
{
KItemListView::resizeEvent(event);
triggerVisibleIndexRangeUpdate();
- markVisibleRolesSizesAsDirty();
}
void KFileItemListView::slotItemsRemoved(const KItemRangeList& itemRanges)
}
if (role == "name") {
- Q_ASSERT(values.contains("expansionLevel"));
-
// 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;
virtual QSizeF itemSizeHint(int index) const;
/** @reimp */
- virtual QHash<QByteArray, QSizeF> visibleRoleSizes() const;
+ virtual QHash<QByteArray, QSizeF> visibleRolesSizes() const;
/** @reimp */
virtual QPixmap createDragPixmap(const QSet<int>& indexes) const;
virtual void onModelChanged(KItemModelBase* current, KItemModelBase* previous);
virtual void onScrollOrientationChanged(Qt::Orientation current, Qt::Orientation previous);
virtual void onItemSizeChanged(const QSizeF& current, const QSizeF& previous);
- virtual void onOffsetChanged(qreal current, qreal previous);
+ virtual void onScrollOffsetChanged(qreal current, qreal previous);
virtual void onVisibleRolesChanged(const QList<QByteArray>& current, const QList<QByteArray>& previous);
virtual void onStyleOptionChanged(const KItemListStyleOption& current, const KItemListStyleOption& previous);
virtual void onTransactionBegin();
const QScrollBar* scrollBar = (view->scrollOrientation() == Qt::Vertical)
? verticalScrollBar() : horizontalScrollBar();
- const qreal currentOffset = view->offset();
+ const qreal currentOffset = view->scrollOffset();
if (static_cast<int>(currentOffset) == scrollBar->value()) {
// The current offset is already synchronous to the scrollbar
return;
m_smoothScrollingAnimation->setEndValue(endOffset);
m_smoothScrollingAnimation->setEasingCurve(animRunning ? QEasingCurve::OutQuad : QEasingCurve::InOutQuad);
m_smoothScrollingAnimation->start();
- view->setOffset(startOffset);
+ view->setScrollOffset(startOffset);
} else {
- view->setOffset(endOffset);
+ view->setScrollOffset(endOffset);
}
}
QGraphicsScene* scene = static_cast<QGraphicsView*>(viewport())->scene();
if (previous) {
scene->removeItem(previous);
- disconnect(previous, SIGNAL(offsetChanged(qreal,qreal)), this, SLOT(updateScrollBars()));
- disconnect(previous, SIGNAL(maximumOffsetChanged(qreal,qreal)), this, SLOT(updateScrollBars()));
- disconnect(previous, SIGNAL(scrollTo(qreal)), this, SLOT(scrollTo(qreal)));
+ disconnect(previous, SIGNAL(scrollOffsetChanged(qreal,qreal)), this, SLOT(updateScrollOffsetScrollBar()));
+ disconnect(previous, SIGNAL(maximumScrollOffsetChanged(qreal,qreal)), this, SLOT(updateScrollOffsetScrollBar()));
+ disconnect(previous, SIGNAL(itemOffsetChanged(qreal,qreal)), this, SLOT(updateItemOffsetScrollBar()));
+ disconnect(previous, SIGNAL(maximumItemOffsetChanged(qreal,qreal)), this, SLOT(updateItemOffsetScrollBar()));
+ disconnect(previous, SIGNAL(scrollTo(qreal)), this, SLOT(scrollTo(qreal)));
m_smoothScrollingAnimation->setTargetObject(0);
}
if (current) {
scene->addItem(current);
- connect(current, SIGNAL(offsetChanged(qreal,qreal)), this, SLOT(updateScrollBars()));
- connect(current, SIGNAL(maximumOffsetChanged(qreal,qreal)), this, SLOT(updateScrollBars()));
- connect(current, SIGNAL(scrollTo(qreal)), this, SLOT(scrollTo(qreal)));
+ connect(current, SIGNAL(scrollOffsetChanged(qreal,qreal)), this, SLOT(updateScrollOffsetScrollBar()));
+ connect(current, SIGNAL(maximumScrollOffsetChanged(qreal,qreal)), this, SLOT(updateScrollOffsetScrollBar()));
+ connect(current, SIGNAL(itemOffsetChanged(qreal,qreal)), this, SLOT(updateItemOffsetScrollBar()));
+ connect(current, SIGNAL(maximumItemOffsetChanged(qreal,qreal)), this, SLOT(updateItemOffsetScrollBar()));
+ connect(current, SIGNAL(scrollTo(qreal)), this, SLOT(scrollTo(qreal)));
m_smoothScrollingAnimation->setTargetObject(current);
}
}
scrollBar->setValue(offset);
}
-void KItemListContainer::updateScrollBars()
+void KItemListContainer::updateScrollOffsetScrollBar()
{
const KItemListView* view = m_controller->view();
if (!view) {
return;
}
- QScrollBar* scrollBar = 0;
+ QScrollBar* scrollOffsetScrollBar = 0;
int singleStep = 0;
int pageStep = 0;
- QScrollBar* otherScrollBar = 0;
if (view->scrollOrientation() == Qt::Vertical) {
- scrollBar = verticalScrollBar();
+ scrollOffsetScrollBar = verticalScrollBar();
singleStep = view->itemSize().height();
pageStep = view->size().height();
- otherScrollBar = horizontalScrollBar();
} else {
- scrollBar = horizontalScrollBar();
+ scrollOffsetScrollBar = horizontalScrollBar();
singleStep = view->itemSize().width();
pageStep = view->size().width();
- otherScrollBar = verticalScrollBar();
}
- const int value = view->offset();
- const int maximum = qMax(0, int(view->maximumOffset() - pageStep));
+ const int value = view->scrollOffset();
+ const int maximum = qMax(0, int(view->maximumScrollOffset() - pageStep));
if (m_smoothScrollingAnimation->state() == QAbstractAnimation::Running) {
- if (maximum == scrollBar->maximum()) {
+ if (maximum == scrollOffsetScrollBar->maximum()) {
// The value has been changed by the animation, no update
// of the scrollbars is required as their target state will be
// reached with the end of the animation.
m_smoothScrollingAnimation->stop();
}
- scrollBar->setSingleStep(singleStep);
- scrollBar->setPageStep(pageStep);
- scrollBar->setMinimum(0);
- scrollBar->setMaximum(maximum);
- scrollBar->setValue(value);
+ scrollOffsetScrollBar->setSingleStep(singleStep);
+ scrollOffsetScrollBar->setPageStep(pageStep);
+ scrollOffsetScrollBar->setMinimum(0);
+ scrollOffsetScrollBar->setMaximum(maximum);
+ scrollOffsetScrollBar->setValue(value);
+}
+
+void KItemListContainer::updateItemOffsetScrollBar()
+{
+ const KItemListView* view = m_controller->view();
+ if (!view) {
+ return;
+ }
+
+ QScrollBar* itemOffsetScrollBar = 0;
+ int singleStep = 0;
+ int pageStep = 0;
+ if (view->scrollOrientation() == Qt::Vertical) {
+ itemOffsetScrollBar = horizontalScrollBar();
+ singleStep = view->itemSize().width() / 10;
+ pageStep = view->size().width();
+ } else {
+ itemOffsetScrollBar = verticalScrollBar();
+ singleStep = view->itemSize().height() / 10;
+ pageStep = view->size().height();
+ }
+
+ const int value = view->itemOffset();
+ const int maximum = qMax(0, int(view->maximumItemOffset() - pageStep));
- // Make sure that the other scroll bar is hidden
- otherScrollBar->setMaximum(0);
- otherScrollBar->setValue(0);
+ itemOffsetScrollBar->setSingleStep(singleStep);
+ itemOffsetScrollBar->setPageStep(pageStep);
+ itemOffsetScrollBar->setMinimum(0);
+ itemOffsetScrollBar->setMaximum(maximum);
+ itemOffsetScrollBar->setValue(value);
}
void KItemListContainer::updateGeometries()
static_cast<KItemListContainerViewport*>(viewport())->scene()->setSceneRect(0, 0, rect.width(), rect.height());
static_cast<KItemListContainerViewport*>(viewport())->viewport()->setGeometry(QRect(0, 0, rect.width(), rect.height()));
- updateScrollBars();
+ updateScrollOffsetScrollBar();
+ updateItemOffsetScrollBar();
}
void KItemListContainer::initialize()
QGraphicsView* graphicsView = new KItemListContainerViewport(new QGraphicsScene(this), this);
setViewport(graphicsView);
- m_smoothScrollingAnimation = new QPropertyAnimation(this, "offset");
+ m_smoothScrollingAnimation = new QPropertyAnimation(this, "scrollOffset");
m_smoothScrollingAnimation->setDuration(300);
connect(m_smoothScrollingAnimation, SIGNAL(stateChanged(QAbstractAnimation::State,QAbstractAnimation::State)),
this, SLOT(slotAnimationStateChanged(QAbstractAnimation::State,QAbstractAnimation::State)));
void slotViewChanged(KItemListView* current, KItemListView* previous);
void slotAnimationStateChanged(QAbstractAnimation::State newState, QAbstractAnimation::State oldState);
void scrollTo(qreal offset);
- void updateScrollBars();
+ void updateScrollOffsetScrollBar();
+ void updateItemOffsetScrollBar();
private:
void initialize();
KItemListView* oldView = m_view;
if (oldView) {
- disconnect(oldView, SIGNAL(offsetChanged(qreal,qreal)), this, SLOT(slotViewOffsetChanged(qreal,qreal)));
+ disconnect(oldView, SIGNAL(scrollOffsetChanged(qreal,qreal)), this, SLOT(slotViewScrollOffsetChanged(qreal,qreal)));
}
m_view = view;
if (m_view) {
m_view->setController(this);
m_view->setModel(m_model);
- connect(m_view, SIGNAL(offsetChanged(qreal,qreal)), this, SLOT(slotViewOffsetChanged(qreal,qreal)));
+ connect(m_view, SIGNAL(scrollOffsetChanged(qreal,qreal)), this, SLOT(slotViewScrollOffsetChanged(qreal,qreal)));
}
emit viewChanged(m_view, oldView);
KItemListRubberBand* rubberBand = m_view->rubberBand();
QPointF startPos = m_pressedMousePos;
if (m_view->scrollOrientation() == Qt::Vertical) {
- startPos.ry() += m_view->offset();
+ startPos.ry() += m_view->scrollOffset();
if (m_view->itemSize().width() < 0) {
// Use a special rubberband for views that have only one column and
// expand the rubberband to use the whole width of the view.
startPos.setX(0);
}
} else {
- startPos.rx() += m_view->offset();
+ startPos.rx() += m_view->scrollOffset();
}
m_oldSelection = m_selectionManager->selectedItems();
if (rubberBand->isActive()) {
QPointF endPos = transform.map(event->pos());
if (m_view->scrollOrientation() == Qt::Vertical) {
- endPos.ry() += m_view->offset();
+ endPos.ry() += m_view->scrollOffset();
if (m_view->itemSize().width() < 0) {
// Use a special rubberband for views that have only one column and
// expand the rubberband to use the whole width of the view.
endPos.setX(m_view->size().width());
}
} else {
- endPos.rx() += m_view->offset();
+ endPos.rx() += m_view->scrollOffset();
}
rubberBand->setEndPosition(endPos);
}
return false;
}
-void KItemListController::slotViewOffsetChanged(qreal current, qreal previous)
+void KItemListController::slotViewScrollOffsetChanged(qreal current, qreal previous)
{
if (!m_view) {
return;
const bool scrollVertical = (m_view->scrollOrientation() == Qt::Vertical);
if (scrollVertical) {
- rubberBandRect.translate(0, -m_view->offset());
+ rubberBandRect.translate(0, -m_view->scrollOffset());
} else {
- rubberBandRect.translate(-m_view->offset(), 0);
+ rubberBandRect.translate(-m_view->scrollOffset(), 0);
}
if (!m_oldSelection.isEmpty()) {
void viewChanged(KItemListView* current, KItemListView* previous);
private slots:
- void slotViewOffsetChanged(qreal current, qreal previous);
+ void slotViewScrollOffsetChanged(qreal current, qreal previous);
/**
* Is invoked when the rubberband boundaries have been changed and will select
m_layouter(0),
m_animation(0),
m_layoutTimer(0),
- m_oldOffset(0),
- m_oldMaximumOffset(0),
+ m_oldScrollOffset(0),
+ m_oldMaximumScrollOffset(0),
+ m_oldItemOffset(0),
+ m_oldMaximumItemOffset(0),
m_skipAutoScrollForRubberBand(false),
m_rubberBand(0),
m_mousePos(),
m_itemSize = itemSize;
- if (!markVisibleRolesSizesAsDirty()) {
- if (itemSize.width() < previousSize.width() || itemSize.height() < previousSize.height()) {
- prepareLayoutForIncreasedItemCount(itemSize, ItemSize);
- } else {
- m_layouter->setItemSize(itemSize);
- }
+ if (itemSize.isEmpty()) {
+ updateVisibleRoleSizes();
+ }
+
+ if (itemSize.width() < previousSize.width() || itemSize.height() < previousSize.height()) {
+ prepareLayoutForIncreasedItemCount(itemSize, ItemSize);
+ } else {
+ m_layouter->setItemSize(itemSize);
}
m_sizeHintResolver->clearCache();
return m_itemSize;
}
-void KItemListView::setOffset(qreal offset)
+void KItemListView::setScrollOffset(qreal offset)
{
if (offset < 0) {
offset = 0;
}
- const qreal previousOffset = m_layouter->offset();
+ const qreal previousOffset = m_layouter->scrollOffset();
if (offset == previousOffset) {
return;
}
- m_layouter->setOffset(offset);
- m_animation->setOffset(offset);
+ m_layouter->setScrollOffset(offset);
+ m_animation->setScrollOffset(offset);
if (!m_layoutTimer->isActive()) {
doLayout(NoAnimation, 0, 0);
update();
}
- onOffsetChanged(offset, previousOffset);
+ onScrollOffsetChanged(offset, previousOffset);
+}
+
+qreal KItemListView::scrollOffset() const
+{
+ return m_layouter->scrollOffset();
+}
+
+qreal KItemListView::maximumScrollOffset() const
+{
+ return m_layouter->maximumScrollOffset();
+}
+
+void KItemListView::setItemOffset(qreal offset)
+{
+ m_layouter->setItemOffset(offset);
}
-qreal KItemListView::offset() const
+qreal KItemListView::itemOffset() const
{
- return m_layouter->offset();
+ return m_layouter->itemOffset();
}
-qreal KItemListView::maximumOffset() const
+qreal KItemListView::maximumItemOffset() const
{
- return m_layouter->maximumOffset();
+ return m_layouter->maximumItemOffset();
}
void KItemListView::setVisibleRoles(const QList<QByteArray>& roles)
m_layouter->markAsDirty();
onVisibleRolesChanged(roles, previousRoles);
- markVisibleRolesSizesAsDirty();
+ updateVisibleRoleSizes();
updateLayout();
if (m_header) {
return;
}
- if (m_itemSize.isEmpty()) {
- m_layouter->setItemSize(QSizeF());
- }
-
if (m_model->count() > 0) {
prepareLayoutForIncreasedItemCount(rect.size(), LayouterSize);
} else {
if (!m_layoutTimer->isActive()) {
m_layoutTimer->start();
}
+
+ updateVisibleRoleSizes();
}
int KItemListView::itemAt(const QPointF& pos) const
return itemSize();
}
-QHash<QByteArray, QSizeF> KItemListView::visibleRoleSizes() const
+QHash<QByteArray, QSizeF> KItemListView::visibleRolesSizes() const
{
return QHash<QByteArray, QSizeF>();
}
const QPointF topLeft = rubberBandRect.topLeft();
if (scrollOrientation() == Qt::Vertical) {
- rubberBandRect.moveTo(topLeft.x(), topLeft.y() - offset());
+ rubberBandRect.moveTo(topLeft.x(), topLeft.y() - scrollOffset());
} else {
- rubberBandRect.moveTo(topLeft.x() - offset(), topLeft.y());
+ rubberBandRect.moveTo(topLeft.x() - scrollOffset(), topLeft.y());
}
QStyleOptionRubberBand opt;
Q_UNUSED(previous);
}
-void KItemListView::onOffsetChanged(qreal current, qreal previous)
+void KItemListView::onScrollOffsetChanged(qreal current, qreal previous)
{
Q_UNUSED(current);
Q_UNUSED(previous);
updateHeaderWidth();
}
-bool KItemListView::markVisibleRolesSizesAsDirty()
-{
- const bool dirty = m_itemSize.isEmpty();
- if (dirty && !m_useHeaderWidths) {
- m_visibleRolesSizes.clear();
- m_layouter->setItemSize(QSizeF());
- }
- return dirty;
-}
-
void KItemListView::slotItemsInserted(const KItemRangeList& itemRanges)
{
- markVisibleRolesSizesAsDirty();
+ updateVisibleRoleSizes();
const bool hasMultipleRanges = (itemRanges.count() > 1);
if (hasMultipleRanges) {
}
m_layouter->markAsDirty();
- if (m_model->count() == count && maximumOffset() > size().height()) {
+ if (m_model->count() == count && maximumScrollOffset() > size().height()) {
kDebug() << "Scrollbar required, skipping layout";
const int scrollBarExtent = style()->pixelMetric(QStyle::PM_ScrollBarExtent);
QSizeF layouterSize = m_layouter->size();
void KItemListView::slotItemsRemoved(const KItemRangeList& itemRanges)
{
- markVisibleRolesSizesAsDirty();
+ updateVisibleRoleSizes();
const bool hasMultipleRanges = (itemRanges.count() > 1);
if (hasMultipleRanges) {
{
const bool updateSizeHints = itemSizeHintUpdateRequired(roles);
if (updateSizeHints) {
- markVisibleRolesSizesAsDirty();
+ updateVisibleRoleSizes();
}
foreach (const KItemRange& itemRange, itemRanges) {
if (!viewGeometry.contains(currentBoundingRect)) {
// Make sure that the new current item is fully visible in the view.
- qreal newOffset = offset();
+ qreal newOffset = scrollOffset();
if (currentBoundingRect.top() < viewGeometry.top()) {
Q_ASSERT(scrollOrientation() == Qt::Vertical);
newOffset += currentBoundingRect.top() - viewGeometry.top();
}
}
- if (newOffset != offset()) {
+ if (newOffset != scrollOffset()) {
emit scrollTo(newOffset);
}
}
QSizeF roleSize = m_visibleRolesSizes.value(role);
roleSize.setWidth(currentWidth);
m_visibleRolesSizes.insert(role, roleSize);
- }
- m_layouter->setItemSize(QSizeF()); // Forces an update in applyDynamicItemSize()
- updateLayout();
+ updateVisibleRoleSizes();
+ updateLayout();
+ }
}
void KItemListView::triggerAutoScrolling()
// the autoscrolling may not get skipped anymore until a new rubberband is created
m_skipAutoScrollForRubberBand = false;
- setOffset(offset() + m_autoScrollIncrement);
+ setScrollOffset(scrollOffset() + m_autoScrollIncrement);
// Trigger the autoscroll timer which will periodically call
// triggerAutoScrolling()
return;
}
- applyDynamicItemSize();
+ //markVisibleRolesSizesAsDirty();
const int firstVisibleIndex = m_layouter->firstVisibleIndex();
const int lastVisibleIndex = m_layouter->lastVisibleIndex();
return;
}
- // Do a sanity check of the offset-property: When properties of the itemlist-view have been changed
+ // Do a sanity check of the scroll-offset property: When properties of the itemlist-view have been changed
// it might be possible that the maximum offset got changed too. Assure that the full visible range
// is still shown if the maximum offset got decreased.
const qreal visibleOffsetRange = (scrollOrientation() == Qt::Horizontal) ? size().width() : size().height();
- const qreal maxOffsetToShowFullRange = maximumOffset() - visibleOffsetRange;
- if (offset() > maxOffsetToShowFullRange) {
- m_layouter->setOffset(qMax(qreal(0), maxOffsetToShowFullRange));
+ const qreal maxOffsetToShowFullRange = maximumScrollOffset() - visibleOffsetRange;
+ if (scrollOffset() > maxOffsetToShowFullRange) {
+ m_layouter->setScrollOffset(qMax(qreal(0), maxOffsetToShowFullRange));
}
// Determine all items that are completely invisible and might be
void KItemListView::emitOffsetChanges()
{
- const qreal newOffset = m_layouter->offset();
- if (m_oldOffset != newOffset) {
- emit offsetChanged(newOffset, m_oldOffset);
- m_oldOffset = newOffset;
+ const qreal newScrollOffset = m_layouter->scrollOffset();
+ if (m_oldScrollOffset != newScrollOffset) {
+ emit scrollOffsetChanged(newScrollOffset, m_oldScrollOffset);
+ m_oldScrollOffset = newScrollOffset;
+ }
+
+ const qreal newMaximumScrollOffset = m_layouter->maximumScrollOffset();
+ if (m_oldMaximumScrollOffset != newMaximumScrollOffset) {
+ emit maximumScrollOffsetChanged(newMaximumScrollOffset, m_oldMaximumScrollOffset);
+ m_oldMaximumScrollOffset = newMaximumScrollOffset;
}
- const qreal newMaximumOffset = m_layouter->maximumOffset();
- if (m_oldMaximumOffset != newMaximumOffset) {
- emit maximumOffsetChanged(newMaximumOffset, m_oldMaximumOffset);
- m_oldMaximumOffset = newMaximumOffset;
+ const qreal newItemOffset = m_layouter->itemOffset();
+ if (m_oldItemOffset != newItemOffset) {
+ emit itemOffsetChanged(newItemOffset, m_oldItemOffset);
+ m_oldItemOffset = newItemOffset;
+ }
+
+ const qreal newMaximumItemOffset = m_layouter->maximumItemOffset();
+ if (m_oldMaximumItemOffset != newMaximumItemOffset) {
+ emit maximumItemOffsetChanged(newMaximumItemOffset, m_oldMaximumItemOffset);
+ m_oldMaximumItemOffset = newMaximumItemOffset;
}
}
}
}
-void KItemListView::applyDynamicItemSize()
-{
- if (!m_itemSize.isEmpty()) {
- return;
- }
-
- if (m_visibleRolesSizes.isEmpty()) {
- m_visibleRolesSizes = visibleRoleSizes();
- if (m_header) {
- m_header->setVisibleRolesWidths(headerRolesWidths());
- }
- }
-
- if (m_layouter->itemSize().isEmpty()) {
- // Calculate the maximum size of an item by considering the
- // visible role sizes and apply them to the layouter.
- qreal requiredWidth = 0;
- qreal requiredHeight = 0;
-
- QHashIterator<QByteArray, QSizeF> it(m_visibleRolesSizes);
- while (it.hasNext()) {
- it.next();
- const QSizeF& visibleRoleSize = it.value();
- requiredWidth += visibleRoleSize.width();
- requiredHeight += visibleRoleSize.height();
- }
-
- QSizeF dynamicItemSize = m_itemSize;
- if (dynamicItemSize.width() <= 0) {
- dynamicItemSize.setWidth(qMax(requiredWidth, size().width()));
- }
- if (dynamicItemSize.height() <= 0) {
- dynamicItemSize.setHeight(qMax(requiredHeight, size().height()));
- }
-
- m_layouter->setItemSize(dynamicItemSize);
-
- // Update the role sizes for all visible widgets
- foreach (KItemListWidget* widget, visibleItemListWidgets()) {
- widget->setVisibleRolesSizes(m_visibleRolesSizes);
- }
- }
-}
-
void KItemListView::updateWidgetProperties(KItemListWidget* widget, int index)
{
widget->setVisibleRoles(m_visibleRoles);
return rolesWidths;
}
+void KItemListView::updateVisibleRoleSizes()
+{
+ if (!m_itemSize.isEmpty() || m_useHeaderWidths) {
+ return;
+ }
+
+ m_visibleRolesSizes = visibleRolesSizes();
+ if (m_header) {
+ m_header->setVisibleRolesWidths(headerRolesWidths());
+ }
+
+ // Calculate the maximum size of an item by considering the
+ // visible role sizes and apply them to the layouter.
+ qreal requiredWidth = 0;
+ qreal requiredHeight = 0;
+
+ QHashIterator<QByteArray, QSizeF> it(m_visibleRolesSizes);
+ while (it.hasNext()) {
+ it.next();
+ const QSizeF& visibleRoleSize = it.value();
+ requiredWidth += visibleRoleSize.width();
+ requiredHeight += visibleRoleSize.height();
+ }
+
+ QSizeF dynamicItemSize = m_itemSize;
+ if (dynamicItemSize.width() <= 0) {
+ dynamicItemSize.setWidth(qMax(requiredWidth, size().width()));
+ }
+ if (dynamicItemSize.height() <= 0) {
+ dynamicItemSize.setHeight(qMax(requiredHeight, size().height()));
+ }
+
+ m_layouter->setItemSize(dynamicItemSize);
+
+ // Update the role sizes for all visible widgets
+ foreach (KItemListWidget* widget, visibleItemListWidgets()) {
+ widget->setVisibleRolesSizes(m_visibleRolesSizes);
+ }
+}
+
int KItemListView::calculateAutoScrollingIncrement(int pos, int range, int oldInc)
{
int inc = 0;
}
+
KItemListCreatorBase::~KItemListCreatorBase()
{
qDeleteAll(m_recycleableWidgets);
{
Q_OBJECT
- Q_PROPERTY(qreal offset READ offset WRITE setOffset)
+ Q_PROPERTY(qreal scrollOffset READ scrollOffset WRITE setScrollOffset)
public:
KItemListView(QGraphicsWidget* parent = 0);
QSizeF itemSize() const;
// TODO: add note that offset is not checked against maximumOffset, only against 0.
- void setOffset(qreal offset);
- qreal offset() const;
+ void setScrollOffset(qreal offset);
+ qreal scrollOffset() const;
- qreal maximumOffset() const;
+ qreal maximumScrollOffset() const;
+
+ void setItemOffset(qreal scrollOffset);
+ qreal itemOffset() const;
+
+ qreal maximumItemOffset() const;
void setVisibleRoles(const QList<QByteArray>& roles);
QList<QByteArray> visibleRoles() const;
* is empty. This allows to have dynamic but equal role sizes between
* all items. Per default an empty hash is returned.
*/
- virtual QHash<QByteArray, QSizeF> visibleRoleSizes() const;
+ virtual QHash<QByteArray, QSizeF> visibleRolesSizes() const;
/**
* @return The bounding rectangle of the item relative to the top/left of
virtual void paint(QPainter* painter, const QStyleOptionGraphicsItem* option, QWidget* widget = 0);
signals:
- void offsetChanged(qreal current, qreal previous);
- void maximumOffsetChanged(qreal current, qreal previous);
+ void scrollOffsetChanged(qreal current, qreal previous);
+ void maximumScrollOffsetChanged(qreal current, qreal previous);
+ void itemOffsetChanged(qreal current, qreal previous);
+ void maximumItemOffsetChanged(qreal current, qreal previous);
void scrollTo(qreal newOffset);
protected:
virtual void onScrollOrientationChanged(Qt::Orientation current, Qt::Orientation previous);
virtual void onItemSizeChanged(const QSizeF& current, const QSizeF& previous);
- virtual void onOffsetChanged(qreal current, qreal previous);
+ virtual void onScrollOffsetChanged(qreal current, qreal previous);
virtual void onVisibleRolesChanged(const QList<QByteArray>& current, const QList<QByteArray>& previous);
virtual void onStyleOptionChanged(const KItemListStyleOption& current, const KItemListStyleOption& previous);
QList<KItemListWidget*> visibleItemListWidgets() const;
- /**
- * Marks the visible roles as dirty so that they will get updated when doing the next
- * layout. The visible roles will only get marked as dirty if an empty item-size is
- * given and if the roles have not already been customized by the user by adjusting
- * the view-header.
- * @return True if the visible roles have been marked as dirty.
- */
- bool markVisibleRolesSizesAsDirty();
-
/** @reimp */
virtual void resizeEvent(QGraphicsSceneResizeEvent* event);
*/
void setLayouterSize(const QSizeF& size, SizeType sizeType);
- /**
- * Updates the m_visibleRoleSizes property and applies the dynamic
- * size to the layouter.
- */
- void applyDynamicItemSize();
-
/**
* Helper method for createWidget() and setWidgetIndex() to update the properties
* of the itemlist widget.
*/
QHash<QByteArray, qreal> headerRolesWidths() const;
+ /**
+ * Updates m_visibleRoleSizes by calling KItemListView::visibleRoleSizes()
+ * if the m_itemRect is empty and no custom header-widths are used
+ * (see m_useHeaderWidths).
+ */
+ void updateVisibleRoleSizes();
+
/**
* Helper function for triggerAutoScrolling().
* @param pos Logical position of the mouse relative to the range.
KItemListViewAnimation* m_animation;
QTimer* m_layoutTimer; // Triggers an asynchronous doLayout() call.
- qreal m_oldOffset;
- qreal m_oldMaximumOffset;
+ qreal m_oldScrollOffset;
+ qreal m_oldMaximumScrollOffset;
+ qreal m_oldItemOffset;
+ qreal m_oldMaximumItemOffset;
bool m_skipAutoScrollForRubberBand;
KItemListRubberBand* m_rubberBand;
KItemListViewAnimation::KItemListViewAnimation(QObject* parent) :
QObject(parent),
m_scrollOrientation(Qt::Vertical),
- m_offset(0),
+ m_scrollOffset(0),
m_animation()
{
}
return m_scrollOrientation;
}
-void KItemListViewAnimation::setOffset(qreal offset)
+void KItemListViewAnimation::setScrollOffset(qreal offset)
{
- const qreal diff = m_offset - offset;
- m_offset = offset;
+ const qreal diff = m_scrollOffset - offset;
+ m_scrollOffset = offset;
// The change of the offset requires that the position of all
// animated QGraphicsWidgets get adjusted. An exception is made
}
}
-qreal KItemListViewAnimation::offset() const
+qreal KItemListViewAnimation::scrollOffset() const
{
- return m_offset;
+ return m_scrollOffset;
}
void KItemListViewAnimation::start(QGraphicsWidget* widget, AnimationType type, const QVariant& endValue)
void setScrollOrientation(Qt::Orientation orientation);
Qt::Orientation scrollOrientation() const;
- void setOffset(qreal offset);
- qreal offset() const;
+ void setScrollOffset(qreal scrollOffset);
+ qreal scrollOffset() const;
void start(QGraphicsWidget* widget, AnimationType type, const QVariant& endValue = QVariant());
enum { AnimationTypeCount = 4 };
Qt::Orientation m_scrollOrientation;
- qreal m_offset;
+ qreal m_scrollOffset;
QHash<QGraphicsWidget*, QPropertyAnimation*> m_animation[AnimationTypeCount];
};
m_headerHeight(0),
m_model(0),
m_sizeHintResolver(0),
- m_offset(0),
- m_maximumOffset(0),
+ m_scrollOffset(0),
+ m_maximumScrollOffset(0),
+ m_itemOffset(0),
+ m_maximumItemOffset(0),
m_firstVisibleIndex(-1),
m_lastVisibleIndex(-1),
m_firstVisibleGroupIndex(-1),
return m_headerHeight;
}
-void KItemListViewLayouter::setOffset(qreal offset)
+void KItemListViewLayouter::setScrollOffset(qreal offset)
{
- if (m_offset != offset) {
- m_offset = offset;
+ if (m_scrollOffset != offset) {
+ m_scrollOffset = offset;
m_visibleIndexesDirty = true;
}
}
-qreal KItemListViewLayouter::offset() const
+qreal KItemListViewLayouter::scrollOffset() const
{
- return m_offset;
+ return m_scrollOffset;
+}
+
+qreal KItemListViewLayouter::maximumScrollOffset() const
+{
+ const_cast<KItemListViewLayouter*>(this)->doLayout();
+ return m_maximumScrollOffset;
+}
+
+void KItemListViewLayouter::setItemOffset(qreal offset)
+{
+ if (m_itemOffset != offset) {
+ m_itemOffset = offset;
+ m_visibleIndexesDirty = true;
+ }
+}
+
+qreal KItemListViewLayouter::itemOffset() const
+{
+ return m_itemOffset;
+}
+
+qreal KItemListViewLayouter::maximumItemOffset() const
+{
+ const_cast<KItemListViewLayouter*>(this)->doLayout();
+ return m_maximumItemOffset;
}
void KItemListViewLayouter::setModel(const KItemModelBase* model)
return m_sizeHintResolver;
}
-qreal KItemListViewLayouter::maximumOffset() const
-{
- const_cast<KItemListViewLayouter*>(this)->doLayout();
- return m_maximumOffset;
-}
-
int KItemListViewLayouter::firstVisibleIndex() const
{
const_cast<KItemListViewLayouter*>(this)->doLayout();
const QRectF& b = m_itemBoundingRects[index];
QRectF bounds(b.y(), b.x(), b.height(), b.width());
QPointF pos = bounds.topLeft();
- pos.rx() -= m_offset;
+ pos.rx() -= m_scrollOffset;
bounds.moveTo(pos);
return bounds;
}
QRectF bounds = m_itemBoundingRects[index];
- QPointF pos = bounds.topLeft();
- pos.ry() -= m_offset;
- bounds.moveTo(pos);
+ bounds.moveTo(bounds.topLeft() - QPointF(m_itemOffset, m_scrollOffset));
return bounds;
}
if (itemCount > m_columnCount) {
// Apply the unused width equally to each column
const qreal unusedWidth = size.width() - m_columnCount * m_columnWidth;
- const qreal columnInc = unusedWidth / (m_columnCount + 1);
- m_columnWidth += columnInc;
- m_xPosInc += columnInc;
+ if (unusedWidth > 0) {
+ const qreal columnInc = unusedWidth / (m_columnCount + 1);
+ m_columnWidth += columnInc;
+ m_xPosInc += columnInc;
+ }
}
int rowCount = itemCount / m_columnCount;
m_itemBoundingRects.end());
}
- m_maximumOffset = (itemCount > 0) ? m_itemBoundingRects.last().bottom() : 0;
+ if (itemCount > 0) {
+ m_maximumScrollOffset = m_itemBoundingRects.last().bottom();
+ m_maximumItemOffset = m_columnCount * m_columnWidth;
+ } else {
+ m_maximumScrollOffset = 0;
+ m_maximumItemOffset = 0;
+ }
m_grouped = !m_model->groupRole().isEmpty();
/*if (m_grouped) {
// Calculate the first visible index:
// 1. Guess the index by using the minimum row height
const int maxIndex = m_model->count() - 1;
- m_firstVisibleIndex = int(m_offset / minimumHeight) * m_columnCount;
+ m_firstVisibleIndex = int(m_scrollOffset / minimumHeight) * m_columnCount;
// 2. Decrease the index by checking the real row heights
int prevRowIndex = m_firstVisibleIndex - m_columnCount;
prevRowIndex -= m_columnCount;
}
- const qreal top = m_offset + m_headerHeight;
+ const qreal top = m_scrollOffset + m_headerHeight;
while (prevRowIndex >= 0 && m_itemBoundingRects[prevRowIndex].bottom() >= top) {
m_firstVisibleIndex = prevRowIndex;
prevRowIndex -= m_columnCount;
// Calculate the last visible index
const int visibleHeight = horizontalScrolling ? m_size.width() : m_size.height();
- const qreal bottom = m_offset + visibleHeight;
+ const qreal bottom = m_scrollOffset + visibleHeight;
m_lastVisibleIndex = m_firstVisibleIndex; // first visible row, first column
int nextRowIndex = m_lastVisibleIndex + m_columnCount;
while (nextRowIndex <= maxIndex && m_itemBoundingRects[nextRowIndex].y() <= bottom) {
const int lastGroupIndex = m_groups.count() - 1;
int groupIndex = lastGroupIndex;
for (int i = 1; i < m_groups.count(); ++i) {
- if (m_groups[i].y >= m_offset) {
+ if (m_groups[i].y >= m_scrollOffset) {
groupIndex = i - 1;
break;
}
// Calculate the first visible index
qreal groupY = m_groups[groupIndex].y;
m_firstVisibleIndex = m_groups[groupIndex].firstItemIndex;
- const int invisibleRowCount = int(m_offset - groupY) / int(m_itemSize.height());
+ const int invisibleRowCount = int(m_scrollOffset - groupY) / int(m_itemSize.height());
m_firstVisibleIndex += invisibleRowCount * m_columnCount;
if (groupIndex + 1 <= lastGroupIndex) {
// Check whether the calculated first visible index remains inside the current
m_firstVisibleIndex = qBound(0, m_firstVisibleIndex, maxIndex);
// Calculate the last visible index: Find group where the last visible item is shown.
- const qreal visibleBottom = m_offset + m_size.height(); // TODO: respect Qt::Horizontal alignment
+ const qreal visibleBottom = m_scrollOffset + m_size.height(); // TODO: respect Qt::Horizontal alignment
while ((groupIndex < lastGroupIndex) && (m_groups[groupIndex + 1].y < visibleBottom)) {
++groupIndex;
}
qreal headerHeight() const;
// TODO: add note that offset can be < 0 or > maximumOffset!
- void setOffset(qreal offset);
- qreal offset() const;
+ void setScrollOffset(qreal scrollOffset);
+ qreal scrollOffset() const;
+
+ qreal maximumScrollOffset() const;
+
+ void setItemOffset(qreal scrollOffset);
+ qreal itemOffset() const;
+
+ qreal maximumItemOffset() const;
void setModel(const KItemModelBase* model);
const KItemModelBase* model() const;
void setSizeHintResolver(const KItemListSizeHintResolver* sizeHintResolver);
const KItemListSizeHintResolver* sizeHintResolver() const;
- qreal maximumOffset() const;
// TODO: mention that return value is -1 if count == 0
int firstVisibleIndex() const;
const KItemModelBase* m_model;
const KItemListSizeHintResolver* m_sizeHintResolver;
- qreal m_offset;
- qreal m_maximumOffset;
+ qreal m_scrollOffset;
+ qreal m_maximumScrollOffset;
+
+ qreal m_itemOffset;
+ qreal m_maximumItemOffset;
int m_firstVisibleIndex;
int m_lastVisibleIndex;