mirror of
https://invent.kde.org/system/dolphin
synced 2024-09-19 16:31:21 +00:00
Fix alternate backgrounds when enabling grouping
Up to now the alternating backgrounds just have been calculated by checking whether the item index is odd. This does not work well when grouping is enabled: In this case the alternate background color of the first item of a group should stay consistent.
This commit is contained in:
parent
bdd0fdf246
commit
dbc5fd7a49
|
@ -324,9 +324,6 @@ void KFileItemListView::initializeItemListWidget(KItemListWidget* item)
|
|||
case DetailsLayout: fileItemListWidget->setLayout(KFileItemListWidget::DetailsLayout); break;
|
||||
default: Q_ASSERT(false); break;
|
||||
}
|
||||
|
||||
fileItemListWidget->setAlternatingBackgroundColors(m_itemLayout == DetailsLayout &&
|
||||
visibleRoles().count() > 1);
|
||||
}
|
||||
|
||||
bool KFileItemListView::itemSizeHintUpdateRequired(const QSet<QByteArray>& changedRoles) const
|
||||
|
@ -379,20 +376,9 @@ void KFileItemListView::onScrollOffsetChanged(qreal current, qreal previous)
|
|||
|
||||
void KFileItemListView::onVisibleRolesChanged(const QList<QByteArray>& current, const QList<QByteArray>& previous)
|
||||
{
|
||||
Q_UNUSED(current);
|
||||
Q_UNUSED(previous);
|
||||
applyRolesToModel();
|
||||
|
||||
if (m_itemLayout == DetailsLayout) {
|
||||
// Only enable the alternating background colors if more than one role
|
||||
// is visible
|
||||
const int previousCount = previous.count();
|
||||
const int currentCount = current.count();
|
||||
if ((previousCount <= 1 && currentCount > 1) || (previousCount > 1 && currentCount <= 1)) {
|
||||
const bool enabled = (currentCount > 1);
|
||||
foreach (KItemListWidget* widget, visibleItemListWidgets()) {
|
||||
widget->setAlternatingBackgroundColors(enabled);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void KFileItemListView::onStyleOptionChanged(const KItemListStyleOption& current, const KItemListStyleOption& previous)
|
||||
|
|
|
@ -156,9 +156,24 @@ void KItemListView::setItemSize(const QSizeF& itemSize)
|
|||
const bool animate = !changesItemGridLayout(m_layouter->size(),
|
||||
itemSize,
|
||||
m_layouter->itemMargin());
|
||||
|
||||
|
||||
const bool updateAlternateBackgrounds = (m_visibleRoles.count() > 1) &&
|
||||
(( m_itemSize.isEmpty() && !itemSize.isEmpty()) ||
|
||||
(!m_itemSize.isEmpty() && itemSize.isEmpty()));
|
||||
|
||||
m_itemSize = itemSize;
|
||||
|
||||
if (updateAlternateBackgrounds) {
|
||||
// For an empty item size alternate backgrounds are drawn if more than
|
||||
// one role is shown. Assure that the backgrounds for visible items are
|
||||
// updated when changing the size in this context.
|
||||
QHashIterator<int, KItemListWidget*> it(m_visibleItems);
|
||||
while (it.hasNext()) {
|
||||
it.next();
|
||||
updateAlternateBackgroundForWidget(it.value());
|
||||
}
|
||||
}
|
||||
|
||||
if (itemSize.isEmpty()) {
|
||||
updateVisibleRolesSizes();
|
||||
} else {
|
||||
|
@ -238,12 +253,19 @@ void KItemListView::setVisibleRoles(const QList<QByteArray>& roles)
|
|||
const QList<QByteArray> previousRoles = m_visibleRoles;
|
||||
m_visibleRoles = roles;
|
||||
|
||||
const bool updateAlternateBackgrounds = m_itemSize.isEmpty() &&
|
||||
((roles.count() > 1 && previousRoles.count() <= 1) ||
|
||||
(roles.count() <= 1 && previousRoles.count() > 1));
|
||||
|
||||
QHashIterator<int, KItemListWidget*> it(m_visibleItems);
|
||||
while (it.hasNext()) {
|
||||
it.next();
|
||||
KItemListWidget* widget = it.value();
|
||||
widget->setVisibleRoles(roles);
|
||||
widget->setVisibleRolesSizes(m_stretchedVisibleRolesSizes);
|
||||
if (updateAlternateBackgrounds) {
|
||||
updateAlternateBackgroundForWidget(widget);
|
||||
}
|
||||
}
|
||||
|
||||
m_sizeHintResolver->clearCache();
|
||||
|
@ -785,9 +807,6 @@ void KItemListView::slotItemsInserted(const KItemRangeList& itemRanges)
|
|||
beginTransaction();
|
||||
}
|
||||
|
||||
// Important: Don't read any m_layouter-property inside the for-loop in case if
|
||||
// multiple ranges are given! m_layouter accesses m_sizeHintResolver which is
|
||||
// updated in each loop-cycle and has only a consistent state after the loop.
|
||||
m_layouter->markAsDirty();
|
||||
|
||||
int previouslyInsertedCount = 0;
|
||||
|
@ -823,11 +842,12 @@ void KItemListView::slotItemsInserted(const KItemRangeList& itemRanges)
|
|||
for (int i = itemsToMove.count() - 1; i >= 0; --i) {
|
||||
KItemListWidget* widget = m_visibleItems.value(itemsToMove[i]);
|
||||
Q_ASSERT(widget);
|
||||
const int newIndex = widget->index() + count;
|
||||
if (hasMultipleRanges) {
|
||||
setWidgetIndex(widget, widget->index() + count);
|
||||
setWidgetIndex(widget, newIndex);
|
||||
} else {
|
||||
// Try to animate the moving of the item
|
||||
moveWidgetToIndex(widget, widget->index() + count);
|
||||
moveWidgetToIndex(widget, newIndex);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -861,6 +881,12 @@ void KItemListView::slotItemsInserted(const KItemRangeList& itemRanges)
|
|||
}
|
||||
|
||||
if (hasMultipleRanges) {
|
||||
#ifndef QT_NO_DEBUG
|
||||
// Important: Don't read any m_layouter-property inside the for-loop in case if
|
||||
// multiple ranges are given! m_layouter accesses m_sizeHintResolver which is
|
||||
// updated in each loop-cycle and has only a consistent state after the loop.
|
||||
Q_ASSERT(m_layouter->isDirty());
|
||||
#endif
|
||||
m_endTransactionAnimationHint = NoAnimation;
|
||||
endTransaction();
|
||||
updateSiblingsInformation();
|
||||
|
@ -876,9 +902,6 @@ void KItemListView::slotItemsRemoved(const KItemRangeList& itemRanges)
|
|||
beginTransaction();
|
||||
}
|
||||
|
||||
// Important: Don't read any m_layouter-property inside the for-loop in case if
|
||||
// multiple ranges are given! m_layouter accesses m_sizeHintResolver which is
|
||||
// updated in each loop-cycle and has only a consistent state after the loop.
|
||||
m_layouter->markAsDirty();
|
||||
|
||||
for (int i = itemRanges.count() - 1; i >= 0; --i) {
|
||||
|
@ -959,6 +982,12 @@ void KItemListView::slotItemsRemoved(const KItemRangeList& itemRanges)
|
|||
}
|
||||
|
||||
if (hasMultipleRanges) {
|
||||
#ifndef QT_NO_DEBUG
|
||||
// Important: Don't read any m_layouter-property inside the for-loop in case if
|
||||
// multiple ranges are given! m_layouter accesses m_sizeHintResolver which is
|
||||
// updated in each loop-cycle and has only a consistent state after the loop.
|
||||
Q_ASSERT(m_layouter->isDirty());
|
||||
#endif
|
||||
m_endTransactionAnimationHint = NoAnimation;
|
||||
endTransaction();
|
||||
updateSiblingsInformation();
|
||||
|
@ -981,9 +1010,6 @@ void KItemListView::slotItemsMoved(const KItemRange& itemRange, const QList<int>
|
|||
KItemListWidget* widget = m_visibleItems.value(index);
|
||||
if (widget) {
|
||||
updateWidgetProperties(widget, index);
|
||||
if (m_grouped) {
|
||||
updateGroupHeaderForWidget(widget);
|
||||
}
|
||||
initializeItemListWidget(widget);
|
||||
}
|
||||
}
|
||||
|
@ -1048,6 +1074,17 @@ void KItemListView::slotGroupedSortingChanged(bool current)
|
|||
Q_ASSERT(m_visibleGroups.isEmpty());
|
||||
}
|
||||
|
||||
if (useAlternateBackgrounds()) {
|
||||
// Changing the group mode requires to update the alternate backgrounds
|
||||
// as with the enabled group mode the altering is done on base of the first
|
||||
// group item.
|
||||
QHashIterator<int, KItemListWidget*> it(m_visibleItems);
|
||||
while (it.hasNext()) {
|
||||
it.next();
|
||||
updateAlternateBackgroundForWidget(it.value());
|
||||
}
|
||||
}
|
||||
|
||||
doLayout(NoAnimation);
|
||||
}
|
||||
|
||||
|
@ -1077,13 +1114,11 @@ void KItemListView::slotCurrentChanged(int current, int previous)
|
|||
|
||||
KItemListWidget* previousWidget = m_visibleItems.value(previous, 0);
|
||||
if (previousWidget) {
|
||||
Q_ASSERT(previousWidget->isCurrent());
|
||||
previousWidget->setCurrent(false);
|
||||
}
|
||||
|
||||
KItemListWidget* currentWidget = m_visibleItems.value(current, 0);
|
||||
if (currentWidget) {
|
||||
Q_ASSERT(!currentWidget->isCurrent());
|
||||
currentWidget->setCurrent(true);
|
||||
}
|
||||
}
|
||||
|
@ -1406,10 +1441,8 @@ void KItemListView::doLayout(LayoutAnimationHint hint, int changedIndex, int cha
|
|||
const int oldIndex = reusableItems.takeLast();
|
||||
widget = m_visibleItems.value(oldIndex);
|
||||
setWidgetIndex(widget, i);
|
||||
|
||||
if (m_grouped) {
|
||||
updateGroupHeaderForWidget(widget);
|
||||
}
|
||||
updateWidgetProperties(widget, i);
|
||||
initializeItemListWidget(widget);
|
||||
} else {
|
||||
// No reusable KItemListWidget instance is available, create a new one
|
||||
widget = createWidget(i);
|
||||
|
@ -1626,14 +1659,9 @@ KItemListWidget* KItemListView::createWidget(int index)
|
|||
KItemListWidget* widget = m_widgetCreator->create(this);
|
||||
widget->setFlag(QGraphicsItem::ItemStacksBehindParent);
|
||||
|
||||
updateWidgetProperties(widget, index);
|
||||
m_visibleItems.insert(index, widget);
|
||||
m_visibleCells.insert(index, Cell());
|
||||
|
||||
if (m_grouped) {
|
||||
updateGroupHeaderForWidget(widget);
|
||||
}
|
||||
|
||||
updateWidgetProperties(widget, index);
|
||||
initializeItemListWidget(widget);
|
||||
return widget;
|
||||
}
|
||||
|
@ -1654,16 +1682,13 @@ void KItemListView::recycleWidget(KItemListWidget* widget)
|
|||
void KItemListView::setWidgetIndex(KItemListWidget* widget, int index)
|
||||
{
|
||||
const int oldIndex = widget->index();
|
||||
|
||||
m_visibleItems.remove(oldIndex);
|
||||
m_visibleCells.remove(oldIndex);
|
||||
|
||||
updateWidgetProperties(widget, index);
|
||||
|
||||
m_visibleItems.insert(index, widget);
|
||||
m_visibleCells.insert(index, Cell());
|
||||
|
||||
initializeItemListWidget(widget);
|
||||
widget->setIndex(index);
|
||||
}
|
||||
|
||||
void KItemListView::moveWidgetToIndex(KItemListWidget* widget, int index)
|
||||
|
@ -1701,11 +1726,15 @@ void KItemListView::updateWidgetProperties(KItemListWidget* widget, int index)
|
|||
widget->setCurrent(index == selectionManager->currentItem());
|
||||
widget->setSelected(selectionManager->isSelected(index));
|
||||
widget->setHovered(false);
|
||||
widget->setAlternatingBackgroundColors(false);
|
||||
widget->setEnabledSelectionToggle(enabledSelectionToggles());
|
||||
widget->setIndex(index);
|
||||
widget->setData(m_model->data(index));
|
||||
widget->setSiblingsInformation(QBitArray());
|
||||
updateAlternateBackgroundForWidget(widget);
|
||||
|
||||
if (m_grouped) {
|
||||
updateGroupHeaderForWidget(widget);
|
||||
}
|
||||
}
|
||||
|
||||
void KItemListView::updateGroupHeaderForWidget(KItemListWidget* widget)
|
||||
|
@ -1734,21 +1763,9 @@ void KItemListView::updateGroupHeaderForWidget(KItemListWidget* widget)
|
|||
}
|
||||
Q_ASSERT(groupHeader->parentItem() == widget);
|
||||
|
||||
// Determine the shown data for the header by doing a binary
|
||||
// search in the groups-list
|
||||
int min = 0;
|
||||
int max = groups.count() - 1;
|
||||
int mid = 0;
|
||||
do {
|
||||
mid = (min + max) / 2;
|
||||
if (index > groups.at(mid).first) {
|
||||
min = mid + 1;
|
||||
} else {
|
||||
max = mid - 1;
|
||||
}
|
||||
} while (groups.at(mid).first != index && min <= max);
|
||||
|
||||
groupHeader->setData(groups.at(mid).second);
|
||||
const int groupIndex = groupIndexForItem(index);
|
||||
Q_ASSERT(groupIndex >= 0);
|
||||
groupHeader->setData(groups.at(groupIndex).second);
|
||||
groupHeader->setRole(model()->sortRole());
|
||||
groupHeader->setStyleOption(m_styleOption);
|
||||
groupHeader->setScrollOrientation(scrollOrientation());
|
||||
|
@ -1803,6 +1820,60 @@ void KItemListView::updateVisibleGroupHeaders()
|
|||
}
|
||||
}
|
||||
|
||||
int KItemListView::groupIndexForItem(int index) const
|
||||
{
|
||||
Q_ASSERT(m_grouped);
|
||||
|
||||
const QList<QPair<int, QVariant> > groups = model()->groups();
|
||||
if (groups.isEmpty()) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
int min = 0;
|
||||
int max = groups.count() - 1;
|
||||
int mid = 0;
|
||||
do {
|
||||
mid = (min + max) / 2;
|
||||
if (index > groups[mid].first) {
|
||||
min = mid + 1;
|
||||
} else {
|
||||
max = mid - 1;
|
||||
}
|
||||
} while (groups[mid].first != index && min <= max);
|
||||
|
||||
if (min > max) {
|
||||
while (groups[mid].first > index && mid > 0) {
|
||||
--mid;
|
||||
}
|
||||
}
|
||||
|
||||
return mid;
|
||||
}
|
||||
|
||||
void KItemListView::updateAlternateBackgroundForWidget(KItemListWidget* widget)
|
||||
{
|
||||
bool enabled = useAlternateBackgrounds();
|
||||
if (enabled) {
|
||||
const int index = widget->index();
|
||||
enabled = (index & 0x1) > 0;
|
||||
if (m_grouped) {
|
||||
const int groupIndex = groupIndexForItem(index);
|
||||
if (groupIndex >= 0) {
|
||||
const QList<QPair<int, QVariant> > groups = model()->groups();
|
||||
const int indexOfFirstGroupItem = groups[groupIndex].first;
|
||||
const int relativeIndex = index - indexOfFirstGroupItem;
|
||||
enabled = (relativeIndex & 0x1) == 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
widget->setAlternateBackground(enabled);
|
||||
}
|
||||
|
||||
bool KItemListView::useAlternateBackgrounds() const
|
||||
{
|
||||
return m_itemSize.isEmpty() && m_visibleRoles.count() > 1;
|
||||
}
|
||||
|
||||
QHash<QByteArray, qreal> KItemListView::headerRolesWidths() const
|
||||
{
|
||||
QHash<QByteArray, qreal> rolesWidths;
|
||||
|
|
|
@ -396,14 +396,15 @@ private:
|
|||
void recycleWidget(KItemListWidget* widget);
|
||||
|
||||
/**
|
||||
* Changes the index of the widget to \a index. The cell-information
|
||||
* for the widget gets reset and will be updated in the next doLayout().
|
||||
* Changes the index of the widget to \a index and assures a consistent
|
||||
* update for m_visibleItems and m_visibleCells. The cell-information
|
||||
* for the new index will not be updated and be initialized as empty cell.
|
||||
*/
|
||||
void setWidgetIndex(KItemListWidget* widget, int index);
|
||||
|
||||
/**
|
||||
* Changes the index of the widget to \a index. In opposite to
|
||||
* setWidgetIndex() the cell-information of the widget gets updated.
|
||||
* setWidgetIndex() the cell-information for the widget gets updated.
|
||||
* This update gives doLayout() the chance to animate the moving
|
||||
* of the item visually (see moveWidget()).
|
||||
*/
|
||||
|
@ -421,7 +422,7 @@ private:
|
|||
void updateWidgetProperties(KItemListWidget* widget, int index);
|
||||
|
||||
/**
|
||||
* Helper method for createWidget() and setWidgetIndex() to create or update
|
||||
* Helper method for updateWidgetPropertes() to create or update
|
||||
* the itemlist group-header.
|
||||
*/
|
||||
void updateGroupHeaderForWidget(KItemListWidget* widget);
|
||||
|
@ -445,6 +446,26 @@ private:
|
|||
*/
|
||||
void updateVisibleGroupHeaders();
|
||||
|
||||
/**
|
||||
* @return Index for the item in the list returned by KItemModelBase::groups()
|
||||
* that represents the group where the item with the index \a index
|
||||
* belongs to. -1 is returned if no groups are available.
|
||||
*/
|
||||
int groupIndexForItem(int index) const;
|
||||
|
||||
/**
|
||||
* Updates the alternateBackground-property of the widget dependent
|
||||
* on the state of useAlternateBackgrounds() and the grouping state.
|
||||
*/
|
||||
void updateAlternateBackgroundForWidget(KItemListWidget* widget);
|
||||
|
||||
/**
|
||||
* @return True if alternate backgrounds should be used for the items.
|
||||
* This is the case if an empty item-size is given and if there
|
||||
* is more than one visible role.
|
||||
*/
|
||||
bool useAlternateBackgrounds() const;
|
||||
|
||||
/**
|
||||
* @return The widths of each visible role that is shown in the KItemListHeader.
|
||||
*/
|
||||
|
|
|
@ -340,6 +340,14 @@ void KItemListViewLayouter::markAsDirty()
|
|||
m_dirty = true;
|
||||
}
|
||||
|
||||
|
||||
#ifndef QT_NO_DEBUG
|
||||
bool KItemListViewLayouter::isDirty()
|
||||
{
|
||||
return m_dirty;
|
||||
}
|
||||
#endif
|
||||
|
||||
void KItemListViewLayouter::doLayout()
|
||||
{
|
||||
if (m_dirty) {
|
||||
|
|
|
@ -139,6 +139,15 @@ public:
|
|||
|
||||
void markAsDirty();
|
||||
|
||||
#ifndef QT_NO_DEBUG
|
||||
/**
|
||||
* @return True if the layouter has been marked as dirty and hence has
|
||||
* not called yet doLayout(). Is enabled only in the debugging
|
||||
* mode, as it is not useful to check the dirty state otherwise.
|
||||
*/
|
||||
bool isDirty();
|
||||
#endif
|
||||
|
||||
private:
|
||||
void doLayout();
|
||||
void updateVisibleIndexes();
|
||||
|
|
|
@ -40,7 +40,7 @@ KItemListWidget::KItemListWidget(QGraphicsItem* parent) :
|
|||
m_selected(false),
|
||||
m_current(false),
|
||||
m_hovered(false),
|
||||
m_alternatingBackgroundColors(false),
|
||||
m_alternateBackground(false),
|
||||
m_enabledSelectionToggle(false),
|
||||
m_data(),
|
||||
m_visibleRoles(),
|
||||
|
@ -105,7 +105,7 @@ void KItemListWidget::paint(QPainter* painter, const QStyleOptionGraphicsItem* o
|
|||
{
|
||||
Q_UNUSED(option);
|
||||
|
||||
if (m_alternatingBackgroundColors && (m_index & 0x1)) {
|
||||
if (m_alternateBackground) {
|
||||
const QColor backgroundColor = m_styleOption.palette.color(QPalette::AlternateBase);
|
||||
const QRectF backgroundRect(0, 0, size().width(), size().height());
|
||||
painter->fillRect(backgroundRect, backgroundColor);
|
||||
|
@ -276,18 +276,18 @@ bool KItemListWidget::isHovered() const
|
|||
return m_hovered;
|
||||
}
|
||||
|
||||
void KItemListWidget::setAlternatingBackgroundColors(bool enable)
|
||||
void KItemListWidget::setAlternateBackground(bool enable)
|
||||
{
|
||||
if (m_alternatingBackgroundColors != enable) {
|
||||
m_alternatingBackgroundColors = enable;
|
||||
alternatingBackgroundColorsChanged(enable);
|
||||
if (m_alternateBackground != enable) {
|
||||
m_alternateBackground = enable;
|
||||
alternateBackgroundChanged(enable);
|
||||
update();
|
||||
}
|
||||
}
|
||||
|
||||
bool KItemListWidget::alternatingBackgroundColors() const
|
||||
bool KItemListWidget::alternateBackground() const
|
||||
{
|
||||
return m_alternatingBackgroundColors;
|
||||
return m_alternateBackground;
|
||||
}
|
||||
|
||||
void KItemListWidget::setEnabledSelectionToggle(bool enable)
|
||||
|
@ -381,7 +381,7 @@ void KItemListWidget::hoveredChanged(bool hovered)
|
|||
Q_UNUSED(hovered);
|
||||
}
|
||||
|
||||
void KItemListWidget::alternatingBackgroundColorsChanged(bool enabled)
|
||||
void KItemListWidget::alternateBackgroundChanged(bool enabled)
|
||||
{
|
||||
Q_UNUSED(enabled);
|
||||
}
|
||||
|
|
|
@ -82,8 +82,8 @@ public:
|
|||
void setHovered(bool hovered);
|
||||
bool isHovered() const;
|
||||
|
||||
void setAlternatingBackgroundColors(bool enable);
|
||||
bool alternatingBackgroundColors() const;
|
||||
void setAlternateBackground(bool enable);
|
||||
bool alternateBackground() const;
|
||||
|
||||
void setEnabledSelectionToggle(bool enabled);
|
||||
bool enabledSelectionToggle() const;
|
||||
|
@ -138,7 +138,7 @@ protected:
|
|||
virtual void currentChanged(bool current);
|
||||
virtual void selectedChanged(bool selected);
|
||||
virtual void hoveredChanged(bool hovered);
|
||||
virtual void alternatingBackgroundColorsChanged(bool enabled);
|
||||
virtual void alternateBackgroundChanged(bool enabled);
|
||||
virtual void siblingsInformationChanged(const QBitArray& current, const QBitArray& previous);
|
||||
virtual void resizeEvent(QGraphicsSceneResizeEvent* event);
|
||||
|
||||
|
@ -164,7 +164,7 @@ private:
|
|||
bool m_selected;
|
||||
bool m_current;
|
||||
bool m_hovered;
|
||||
bool m_alternatingBackgroundColors;
|
||||
bool m_alternateBackground;
|
||||
bool m_enabledSelectionToggle;
|
||||
QHash<QByteArray, QVariant> m_data;
|
||||
QList<QByteArray> m_visibleRoles;
|
||||
|
|
Loading…
Reference in a new issue