QHeaderView: Mark the drop section during section move

Currently there is no visual feedback where the section move will end
up. Therefore mark the drop section to show where the dragged section
will be inserted.

Fixes: QTBUG-673
Fixes: QTBUG-1114
Change-Id: I3e45a9a9c0604342bb0286fc7cd4c89c757c28cd
Reviewed-by: Richard Moe Gustavsen <richard.gustavsen@qt.io>
This commit is contained in:
Christian Ehrlicher 2020-12-23 22:21:08 +01:00
parent 693aa08ddf
commit 180c662b07
5 changed files with 37 additions and 5 deletions

View File

@ -2572,7 +2572,8 @@ void QHeaderView::mousePressEvent(QMouseEvent *e)
acceptMoveSection = false; // Do not allow moving the tree nod
if (acceptMoveSection) {
d->section = d->target = d->pressed;
d->target = -1;
d->section = d->pressed;
if (d->section == -1)
return;
d->state = QHeaderViewPrivate::MoveSection;
@ -2645,6 +2646,7 @@ void QHeaderView::mouseMoveEvent(QMouseEvent *e)
const int posThreshold = d->headerSectionPosition(visual) - d->offset + d->headerSectionSize(visual) / 2;
const int checkPos = d->reverse() ? d->viewport->width() - pos : pos;
int moving = visualIndex(d->section);
int oldTarget = d->target;
if (visual < moving) {
if (checkPos < posThreshold)
d->target = d->logicalIndex(visual);
@ -2658,6 +2660,8 @@ void QHeaderView::mouseMoveEvent(QMouseEvent *e)
} else {
d->target = d->section;
}
if (oldTarget != d->target || oldTarget == -1)
d->updateSectionsBeforeAfter(d->target);
d->updateSectionIndicator(d->section, pos);
}
return;
@ -2729,6 +2733,8 @@ void QHeaderView::mouseReleaseEvent(QMouseEvent *e)
moveSection(from, to);
d->section = d->target = -1;
d->updateSectionIndicator(d->section, pos);
if (from == to)
d->updateSectionsBeforeAfter(from);
break;
} // not moving
Q_FALLTHROUGH();
@ -2986,6 +2992,7 @@ void QHeaderView::initStyleOptionForIndex(QStyleOptionHeader *option, int logica
opt.selectedPosition = QStyleOptionHeader::NextIsSelected;
else
opt.selectedPosition = QStyleOptionHeader::NotAdjacent;
opt.isSectionDragTarget = d->target == logicalIndex;
}
/*!
@ -4047,6 +4054,25 @@ void QHeaderViewPrivate::setScrollOffset(const QScrollBar *scrollBar, QAbstractI
}
}
void QHeaderViewPrivate::updateSectionsBeforeAfter(int logical)
{
Q_Q(QHeaderView);
const int visual = visualIndex(logical);
int from = logicalIndex(visual > 1 ? visual - 1 : 0);
int to = logicalIndex(visual + 1 >= sectionCount() ? visual : visual + 1);
QRect updateRect;
if (orientation == Qt::Horizontal) {
if (reverse())
std::swap(from, to);
updateRect = QRect(QPoint(q->sectionViewportPosition(from), 0),
QPoint(q->sectionViewportPosition(to) + headerSectionSize(to), viewport->height()));
} else {
updateRect = QRect(QPoint(0, q->sectionViewportPosition(from)),
QPoint(viewport->width(), q->sectionViewportPosition(to) + headerSectionSize(to)));
}
viewport->update(updateRect);
}
#ifndef QT_NO_DATASTREAM
void QHeaderViewPrivate::write(QDataStream &out) const
{

View File

@ -385,6 +385,7 @@ public:
int viewSectionSizeHint(int logical) const;
int adjustedVisualIndex(int visualIndex) const;
void setScrollOffset(const QScrollBar *scrollBar, QAbstractItemView::ScrollMode scrollMode);
void updateSectionsBeforeAfter(int logical);
#ifndef QT_NO_DATASTREAM
void write(QDataStream &out) const;

View File

@ -1283,6 +1283,7 @@ void QFusionStyle::drawControl(ControlElement element, const QStyleOption *optio
QString pixmapName = QStyleHelper::uniqueName(QLatin1String("headersection"), option, option->rect.size());
pixmapName += QString::number(- int(header->position));
pixmapName += QString::number(- int(header->orientation));
pixmapName += QString::number(- int(header->isSectionDragTarget));
QPixmap cache;
if (!QPixmapCache::find(pixmapName, &cache)) {
@ -1291,9 +1292,12 @@ void QFusionStyle::drawControl(ControlElement element, const QStyleOption *optio
QRect pixmapRect(0, 0, rect.width(), rect.height());
QPainter cachePainter(&cache);
QColor buttonColor = d->buttonColor(option->palette);
QColor gradientStopColor;
QColor gradientStartColor = buttonColor.lighter(104);
gradientStopColor = buttonColor.darker(102);
QColor gradientStopColor = buttonColor.darker(102);
if (header->isSectionDragTarget) {
gradientStopColor = gradientStartColor.darker(130);
gradientStartColor = gradientStartColor.darker(130);
}
QLinearGradient gradient(pixmapRect.topLeft(), pixmapRect.bottomLeft());
if (option->palette.window().gradient()) {

View File

@ -748,7 +748,7 @@ QStyleOptionHeader::QStyleOptionHeader(int version)
section(0), textAlignment(Qt::AlignLeft), iconAlignment(Qt::AlignLeft),
position(QStyleOptionHeader::Beginning),
selectedPosition(QStyleOptionHeader::NotAdjacent), sortIndicator(None),
orientation(Qt::Horizontal), textElideMode(Qt::ElideNone), unused(0)
orientation(Qt::Horizontal), textElideMode(Qt::ElideNone), isSectionDragTarget(false), unused(0)
{
}

View File

@ -221,7 +221,8 @@ public:
SortIndicator sortIndicator;
Qt::Orientation orientation:2;
Qt::TextElideMode textElideMode:2;
int unused:28;
bool isSectionDragTarget:1;
int unused:27;
QStyleOptionHeader();
QStyleOptionHeader(const QStyleOptionHeader &other) : QStyleOption(Version, Type) { *this = other; }