mirror of
https://invent.kde.org/system/dolphin
synced 2024-09-19 16:31:21 +00:00
Provide scrollbar for large items
If an item does not fit into the available width/height a scrollbar should be provided (e.g. typically this represents the horizontal scrollbar in the details-view where the width can be larger than the than the visible width). Currently the interaction with the scrollbar is not implemented but this will be a quite minor task in comparison to this patch.
This commit is contained in:
parent
077ec63f58
commit
aee6535043
|
@ -167,7 +167,7 @@ QSizeF KFileItemListView::itemSizeHint(int index) const
|
|||
return QSize();
|
||||
}
|
||||
|
||||
QHash<QByteArray, QSizeF> KFileItemListView::visibleRoleSizes() const
|
||||
QHash<QByteArray, QSizeF> KFileItemListView::visibleRolesSizes() const
|
||||
{
|
||||
QElapsedTimer timer;
|
||||
timer.start();
|
||||
|
@ -293,7 +293,7 @@ void KFileItemListView::onItemSizeChanged(const QSizeF& current, const QSizeF& p
|
|||
triggerVisibleIndexRangeUpdate();
|
||||
}
|
||||
|
||||
void KFileItemListView::onOffsetChanged(qreal current, qreal previous)
|
||||
void KFileItemListView::onScrollOffsetChanged(qreal current, qreal previous)
|
||||
{
|
||||
Q_UNUSED(current);
|
||||
Q_UNUSED(previous);
|
||||
|
@ -353,7 +353,6 @@ void KFileItemListView::resizeEvent(QGraphicsSceneResizeEvent* event)
|
|||
{
|
||||
KItemListView::resizeEvent(event);
|
||||
triggerVisibleIndexRangeUpdate();
|
||||
markVisibleRolesSizesAsDirty();
|
||||
}
|
||||
|
||||
void KFileItemListView::slotItemsRemoved(const KItemRangeList& itemRanges)
|
||||
|
@ -435,8 +434,6 @@ QSizeF KFileItemListView::visibleRoleSizeHint(int index, const QByteArray& role)
|
|||
}
|
||||
|
||||
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;
|
||||
|
|
|
@ -61,7 +61,7 @@ public:
|
|||
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;
|
||||
|
@ -72,7 +72,7 @@ protected:
|
|||
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();
|
||||
|
|
|
@ -122,7 +122,7 @@ void KItemListContainer::scrollContentsBy(int dx, int dy)
|
|||
|
||||
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;
|
||||
|
@ -156,9 +156,9 @@ void KItemListContainer::scrollContentsBy(int dx, int dy)
|
|||
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);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -238,16 +238,20 @@ void KItemListContainer::slotViewChanged(KItemListView* current, KItemListView*
|
|||
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);
|
||||
}
|
||||
}
|
||||
|
@ -275,33 +279,30 @@ void KItemListContainer::scrollTo(qreal offset)
|
|||
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.
|
||||
|
@ -314,15 +315,41 @@ void KItemListContainer::updateScrollBars()
|
|||
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);
|
||||
}
|
||||
|
||||
// Make sure that the other scroll bar is hidden
|
||||
otherScrollBar->setMaximum(0);
|
||||
otherScrollBar->setValue(0);
|
||||
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));
|
||||
|
||||
itemOffsetScrollBar->setSingleStep(singleStep);
|
||||
itemOffsetScrollBar->setPageStep(pageStep);
|
||||
itemOffsetScrollBar->setMinimum(0);
|
||||
itemOffsetScrollBar->setMaximum(maximum);
|
||||
itemOffsetScrollBar->setValue(value);
|
||||
}
|
||||
|
||||
void KItemListContainer::updateGeometries()
|
||||
|
@ -344,7 +371,8 @@ 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()
|
||||
|
@ -361,7 +389,7 @@ 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)));
|
||||
|
|
|
@ -62,7 +62,8 @@ private slots:
|
|||
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();
|
||||
|
|
|
@ -91,7 +91,7 @@ void KItemListController::setView(KItemListView* view)
|
|||
|
||||
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;
|
||||
|
@ -99,7 +99,7 @@ void KItemListController::setView(KItemListView* 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);
|
||||
|
@ -331,14 +331,14 @@ bool KItemListController::mousePressEvent(QGraphicsSceneMouseEvent* event, const
|
|||
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();
|
||||
|
@ -371,14 +371,14 @@ bool KItemListController::mouseMoveEvent(QGraphicsSceneMouseEvent* event, const
|
|||
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);
|
||||
}
|
||||
|
@ -625,7 +625,7 @@ bool KItemListController::processEvent(QEvent* event, const QTransform& transfor
|
|||
return false;
|
||||
}
|
||||
|
||||
void KItemListController::slotViewOffsetChanged(qreal current, qreal previous)
|
||||
void KItemListController::slotViewScrollOffsetChanged(qreal current, qreal previous)
|
||||
{
|
||||
if (!m_view) {
|
||||
return;
|
||||
|
@ -662,9 +662,9 @@ void KItemListController::slotRubberBandChanged()
|
|||
|
||||
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()) {
|
||||
|
|
|
@ -135,7 +135,7 @@ signals:
|
|||
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
|
||||
|
|
|
@ -69,8 +69,10 @@ KItemListView::KItemListView(QGraphicsWidget* parent) :
|
|||
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(),
|
||||
|
@ -133,12 +135,14 @@ void KItemListView::setItemSize(const QSizeF& itemSize)
|
|||
|
||||
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();
|
||||
|
@ -151,34 +155,49 @@ QSizeF KItemListView::itemSize() const
|
|||
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::offset() const
|
||||
qreal KItemListView::scrollOffset() const
|
||||
{
|
||||
return m_layouter->offset();
|
||||
return m_layouter->scrollOffset();
|
||||
}
|
||||
|
||||
qreal KItemListView::maximumOffset() const
|
||||
qreal KItemListView::maximumScrollOffset() const
|
||||
{
|
||||
return m_layouter->maximumOffset();
|
||||
return m_layouter->maximumScrollOffset();
|
||||
}
|
||||
|
||||
void KItemListView::setItemOffset(qreal offset)
|
||||
{
|
||||
m_layouter->setItemOffset(offset);
|
||||
}
|
||||
|
||||
qreal KItemListView::itemOffset() const
|
||||
{
|
||||
return m_layouter->itemOffset();
|
||||
}
|
||||
|
||||
qreal KItemListView::maximumItemOffset() const
|
||||
{
|
||||
return m_layouter->maximumItemOffset();
|
||||
}
|
||||
|
||||
void KItemListView::setVisibleRoles(const QList<QByteArray>& roles)
|
||||
|
@ -198,7 +217,7 @@ void KItemListView::setVisibleRoles(const QList<QByteArray>& roles)
|
|||
m_layouter->markAsDirty();
|
||||
onVisibleRolesChanged(roles, previousRoles);
|
||||
|
||||
markVisibleRolesSizesAsDirty();
|
||||
updateVisibleRoleSizes();
|
||||
updateLayout();
|
||||
|
||||
if (m_header) {
|
||||
|
@ -320,10 +339,6 @@ void KItemListView::setGeometry(const QRectF& rect)
|
|||
return;
|
||||
}
|
||||
|
||||
if (m_itemSize.isEmpty()) {
|
||||
m_layouter->setItemSize(QSizeF());
|
||||
}
|
||||
|
||||
if (m_model->count() > 0) {
|
||||
prepareLayoutForIncreasedItemCount(rect.size(), LayouterSize);
|
||||
} else {
|
||||
|
@ -333,6 +348,8 @@ void KItemListView::setGeometry(const QRectF& rect)
|
|||
if (!m_layoutTimer->isActive()) {
|
||||
m_layoutTimer->start();
|
||||
}
|
||||
|
||||
updateVisibleRoleSizes();
|
||||
}
|
||||
|
||||
int KItemListView::itemAt(const QPointF& pos) const
|
||||
|
@ -387,7 +404,7 @@ QSizeF KItemListView::itemSizeHint(int index) const
|
|||
return itemSize();
|
||||
}
|
||||
|
||||
QHash<QByteArray, QSizeF> KItemListView::visibleRoleSizes() const
|
||||
QHash<QByteArray, QSizeF> KItemListView::visibleRolesSizes() const
|
||||
{
|
||||
return QHash<QByteArray, QSizeF>();
|
||||
}
|
||||
|
@ -445,9 +462,9 @@ void KItemListView::paint(QPainter* painter, const QStyleOptionGraphicsItem* opt
|
|||
|
||||
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;
|
||||
|
@ -494,7 +511,7 @@ void KItemListView::onItemSizeChanged(const QSizeF& current, const QSizeF& previ
|
|||
Q_UNUSED(previous);
|
||||
}
|
||||
|
||||
void KItemListView::onOffsetChanged(qreal current, qreal previous)
|
||||
void KItemListView::onScrollOffsetChanged(qreal current, qreal previous)
|
||||
{
|
||||
Q_UNUSED(current);
|
||||
Q_UNUSED(previous);
|
||||
|
@ -585,19 +602,9 @@ void KItemListView::resizeEvent(QGraphicsSceneResizeEvent* event)
|
|||
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) {
|
||||
|
@ -641,7 +648,7 @@ void KItemListView::slotItemsInserted(const KItemRangeList& itemRanges)
|
|||
}
|
||||
|
||||
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();
|
||||
|
@ -670,7 +677,7 @@ void KItemListView::slotItemsInserted(const KItemRangeList& itemRanges)
|
|||
|
||||
void KItemListView::slotItemsRemoved(const KItemRangeList& itemRanges)
|
||||
{
|
||||
markVisibleRolesSizesAsDirty();
|
||||
updateVisibleRoleSizes();
|
||||
|
||||
const bool hasMultipleRanges = (itemRanges.count() > 1);
|
||||
if (hasMultipleRanges) {
|
||||
|
@ -754,7 +761,7 @@ void KItemListView::slotItemsChanged(const KItemRangeList& itemRanges,
|
|||
{
|
||||
const bool updateSizeHints = itemSizeHintUpdateRequired(roles);
|
||||
if (updateSizeHints) {
|
||||
markVisibleRolesSizesAsDirty();
|
||||
updateVisibleRoleSizes();
|
||||
}
|
||||
|
||||
foreach (const KItemRange& itemRange, itemRanges) {
|
||||
|
@ -802,7 +809,7 @@ void KItemListView::slotCurrentChanged(int current, int previous)
|
|||
|
||||
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();
|
||||
|
@ -819,7 +826,7 @@ void KItemListView::slotCurrentChanged(int current, int previous)
|
|||
}
|
||||
}
|
||||
|
||||
if (newOffset != offset()) {
|
||||
if (newOffset != scrollOffset()) {
|
||||
emit scrollTo(newOffset);
|
||||
}
|
||||
}
|
||||
|
@ -917,10 +924,10 @@ void KItemListView::slotVisibleRoleWidthChanged(const QByteArray& role,
|
|||
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()
|
||||
|
@ -973,7 +980,7 @@ 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()
|
||||
|
@ -1057,7 +1064,7 @@ void KItemListView::doLayout(LayoutAnimationHint hint, int changedIndex, int cha
|
|||
return;
|
||||
}
|
||||
|
||||
applyDynamicItemSize();
|
||||
//markVisibleRolesSizesAsDirty();
|
||||
|
||||
const int firstVisibleIndex = m_layouter->firstVisibleIndex();
|
||||
const int lastVisibleIndex = m_layouter->lastVisibleIndex();
|
||||
|
@ -1066,13 +1073,13 @@ void KItemListView::doLayout(LayoutAnimationHint hint, int changedIndex, int cha
|
|||
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
|
||||
|
@ -1187,16 +1194,28 @@ void KItemListView::doLayout(LayoutAnimationHint hint, int changedIndex, int cha
|
|||
|
||||
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 newMaximumOffset = m_layouter->maximumOffset();
|
||||
if (m_oldMaximumOffset != newMaximumOffset) {
|
||||
emit maximumOffsetChanged(newMaximumOffset, m_oldMaximumOffset);
|
||||
m_oldMaximumOffset = newMaximumOffset;
|
||||
const qreal newMaximumScrollOffset = m_layouter->maximumScrollOffset();
|
||||
if (m_oldMaximumScrollOffset != newMaximumScrollOffset) {
|
||||
emit maximumScrollOffsetChanged(newMaximumScrollOffset, m_oldMaximumScrollOffset);
|
||||
m_oldMaximumScrollOffset = newMaximumScrollOffset;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1317,50 +1336,6 @@ void KItemListView::setLayouterSize(const QSizeF& size, SizeType sizeType)
|
|||
}
|
||||
}
|
||||
|
||||
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);
|
||||
|
@ -1406,6 +1381,46 @@ QHash<QByteArray, qreal> KItemListView::headerRolesWidths() const
|
|||
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;
|
||||
|
@ -1433,6 +1448,7 @@ int KItemListView::calculateAutoScrollingIncrement(int pos, int range, int oldIn
|
|||
}
|
||||
|
||||
|
||||
|
||||
KItemListCreatorBase::~KItemListCreatorBase()
|
||||
{
|
||||
qDeleteAll(m_recycleableWidgets);
|
||||
|
|
|
@ -65,7 +65,7 @@ class LIBDOLPHINPRIVATE_EXPORT KItemListView : public QGraphicsWidget
|
|||
{
|
||||
Q_OBJECT
|
||||
|
||||
Q_PROPERTY(qreal offset READ offset WRITE setOffset)
|
||||
Q_PROPERTY(qreal scrollOffset READ scrollOffset WRITE setScrollOffset)
|
||||
|
||||
public:
|
||||
KItemListView(QGraphicsWidget* parent = 0);
|
||||
|
@ -78,10 +78,15 @@ public:
|
|||
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;
|
||||
|
@ -159,7 +164,7 @@ public:
|
|||
* 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
|
||||
|
@ -193,8 +198,10 @@ public:
|
|||
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:
|
||||
|
@ -215,7 +222,7 @@ 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);
|
||||
|
||||
|
@ -232,15 +239,6 @@ protected:
|
|||
|
||||
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);
|
||||
|
||||
|
@ -320,12 +318,6 @@ private:
|
|||
*/
|
||||
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.
|
||||
|
@ -343,6 +335,13 @@ private:
|
|||
*/
|
||||
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.
|
||||
|
@ -377,8 +376,10 @@ private:
|
|||
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;
|
||||
|
|
|
@ -29,7 +29,7 @@
|
|||
KItemListViewAnimation::KItemListViewAnimation(QObject* parent) :
|
||||
QObject(parent),
|
||||
m_scrollOrientation(Qt::Vertical),
|
||||
m_offset(0),
|
||||
m_scrollOffset(0),
|
||||
m_animation()
|
||||
{
|
||||
}
|
||||
|
@ -51,10 +51,10 @@ Qt::Orientation KItemListViewAnimation::scrollOrientation() const
|
|||
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
|
||||
|
@ -108,9 +108,9 @@ void KItemListViewAnimation::setOffset(qreal offset)
|
|||
}
|
||||
}
|
||||
|
||||
qreal KItemListViewAnimation::offset() const
|
||||
qreal KItemListViewAnimation::scrollOffset() const
|
||||
{
|
||||
return m_offset;
|
||||
return m_scrollOffset;
|
||||
}
|
||||
|
||||
void KItemListViewAnimation::start(QGraphicsWidget* widget, AnimationType type, const QVariant& endValue)
|
||||
|
|
|
@ -49,8 +49,8 @@ public:
|
|||
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());
|
||||
|
||||
|
@ -70,7 +70,7 @@ private:
|
|||
enum { AnimationTypeCount = 4 };
|
||||
|
||||
Qt::Orientation m_scrollOrientation;
|
||||
qreal m_offset;
|
||||
qreal m_scrollOffset;
|
||||
QHash<QGraphicsWidget*, QPropertyAnimation*> m_animation[AnimationTypeCount];
|
||||
};
|
||||
|
||||
|
|
|
@ -42,8 +42,10 @@ KItemListViewLayouter::KItemListViewLayouter(QObject* parent) :
|
|||
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),
|
||||
|
@ -112,17 +114,42 @@ qreal KItemListViewLayouter::headerHeight() const
|
|||
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)
|
||||
|
@ -151,12 +178,6 @@ const KItemListSizeHintResolver* KItemListViewLayouter::sizeHintResolver() const
|
|||
return m_sizeHintResolver;
|
||||
}
|
||||
|
||||
qreal KItemListViewLayouter::maximumOffset() const
|
||||
{
|
||||
const_cast<KItemListViewLayouter*>(this)->doLayout();
|
||||
return m_maximumOffset;
|
||||
}
|
||||
|
||||
int KItemListViewLayouter::firstVisibleIndex() const
|
||||
{
|
||||
const_cast<KItemListViewLayouter*>(this)->doLayout();
|
||||
|
@ -182,15 +203,13 @@ QRectF KItemListViewLayouter::itemBoundingRect(int index) const
|
|||
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;
|
||||
}
|
||||
|
||||
|
@ -251,9 +270,11 @@ void KItemListViewLayouter::doLayout()
|
|||
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;
|
||||
|
@ -303,7 +324,13 @@ void KItemListViewLayouter::doLayout()
|
|||
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) {
|
||||
|
@ -354,7 +381,7 @@ void KItemListViewLayouter::updateVisibleIndexes()
|
|||
// 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;
|
||||
|
@ -362,7 +389,7 @@ void KItemListViewLayouter::updateVisibleIndexes()
|
|||
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;
|
||||
|
@ -371,7 +398,7 @@ void KItemListViewLayouter::updateVisibleIndexes()
|
|||
|
||||
// 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) {
|
||||
|
@ -404,7 +431,7 @@ void KItemListViewLayouter::updateGroupedVisibleIndexes()
|
|||
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;
|
||||
}
|
||||
|
@ -413,7 +440,7 @@ void KItemListViewLayouter::updateGroupedVisibleIndexes()
|
|||
// 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
|
||||
|
@ -431,7 +458,7 @@ void KItemListViewLayouter::updateGroupedVisibleIndexes()
|
|||
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;
|
||||
}
|
||||
|
|
|
@ -56,8 +56,15 @@ public:
|
|||
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;
|
||||
|
@ -65,7 +72,6 @@ public:
|
|||
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;
|
||||
|
@ -107,8 +113,11 @@ private:
|
|||
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;
|
||||
|
|
Loading…
Reference in a new issue