mirror of
https://github.com/baldurk/renderdoc.git
synced 2026-08-25 07:56:33 +00:00
Add custom painting and section handling to RDTableView & RDHeaderView
* This is used primarily for the buffer/mesh viewer to be able to pin the index/element column to the left side, group columns together with a noticeable separator, and other minor tweaks. * Unfortunately due to tight private coupling and lack of virtual functions in the QTableView and QHeaderView, a few unrelated functions have to be re-implemented to point to our own header.
This commit is contained in:
@@ -28,6 +28,20 @@
|
||||
#include <QPainter>
|
||||
#include <QPixmap>
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// this file contains a few hardcoded assumptions for my use case, especially
|
||||
// with the 'custom sizing' mode that allows merging sections and pinning sections
|
||||
// and so on.
|
||||
//
|
||||
// * No handling for moving/rearranging/hiding sections with the custom sizing
|
||||
// mode. Just needs more careful handling and distinguishing between logical
|
||||
// and visual indices.
|
||||
// * Probably a few places vertical orientation isn't handled right, but that
|
||||
// shouldn't be too bad.
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
RDHeaderView::RDHeaderView(Qt::Orientation orient, QWidget *parent) : QHeaderView(orient, parent)
|
||||
{
|
||||
m_sectionPreview = new QLabel(this);
|
||||
@@ -37,12 +51,285 @@ RDHeaderView::~RDHeaderView()
|
||||
{
|
||||
}
|
||||
|
||||
QSize RDHeaderView::sizeHint() const
|
||||
{
|
||||
if(!m_customSizing)
|
||||
return QHeaderView::sizeHint();
|
||||
return m_sizeHint;
|
||||
}
|
||||
|
||||
void RDHeaderView::setModel(QAbstractItemModel *model)
|
||||
{
|
||||
QAbstractItemModel *m = this->model();
|
||||
|
||||
if(m)
|
||||
{
|
||||
QObject::disconnect(m, &QAbstractItemModel::headerDataChanged, this,
|
||||
&RDHeaderView::headerDataChanged);
|
||||
QObject::disconnect(m, &QAbstractItemModel::columnsInserted, this,
|
||||
&RDHeaderView::columnsInserted);
|
||||
}
|
||||
|
||||
QHeaderView::setModel(model);
|
||||
|
||||
QObject::connect(model, &QAbstractItemModel::headerDataChanged, this,
|
||||
&RDHeaderView::headerDataChanged);
|
||||
QObject::connect(model, &QAbstractItemModel::columnsInserted, this, &RDHeaderView::columnsInserted);
|
||||
}
|
||||
|
||||
void RDHeaderView::reset()
|
||||
{
|
||||
if(m_customSizing)
|
||||
cacheSections();
|
||||
}
|
||||
|
||||
void RDHeaderView::cacheSections()
|
||||
{
|
||||
if(m_suppressSectionCache)
|
||||
return;
|
||||
|
||||
QAbstractItemModel *m = this->model();
|
||||
|
||||
int oldCount = m_sections.count();
|
||||
m_sections.resize(m->columnCount());
|
||||
|
||||
// give new sections a default minimum size
|
||||
for(int col = oldCount; col < m_sections.count(); col++)
|
||||
m_sections[col].size = 10;
|
||||
|
||||
for(int col = 0; col < m_sections.count(); col++)
|
||||
{
|
||||
if(m_columnGroupRole > 0)
|
||||
{
|
||||
QVariant v = m->data(m->index(0, col), m_columnGroupRole);
|
||||
if(v.isValid())
|
||||
m_sections[col].group = v.toInt();
|
||||
|
||||
if(col > 0)
|
||||
{
|
||||
m_sections[col - 1].groupGap =
|
||||
(m_sections[col].group != m_sections[col - 1].group) && m_sections[col].group >= 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
m_sections[col].group = col;
|
||||
m_sections[col].groupGap = true;
|
||||
}
|
||||
}
|
||||
|
||||
int accum = 0;
|
||||
|
||||
for(int col = 0; col < m_sections.count(); col++)
|
||||
{
|
||||
if(col == m_pinnedColumns)
|
||||
m_pinnedWidth = accum;
|
||||
|
||||
m_sections[col].offset = accum;
|
||||
accum += m_sections[col].size;
|
||||
|
||||
if(hasGroupGap(col))
|
||||
accum += groupGapSize();
|
||||
}
|
||||
|
||||
if(m_pinnedColumns >= m_sections.count())
|
||||
m_pinnedWidth = m_pinnedColumns;
|
||||
|
||||
QStyleOptionHeader opt;
|
||||
initStyleOption(&opt);
|
||||
|
||||
QFont f = font();
|
||||
f.setBold(true);
|
||||
|
||||
opt.section = 0;
|
||||
opt.fontMetrics = QFontMetrics(f);
|
||||
opt.text = m->headerData(0, orientation(), Qt::DisplayRole).toString();
|
||||
|
||||
m_sizeHint = style()->sizeFromContents(QStyle::CT_HeaderSection, &opt, QSize(), this);
|
||||
m_sizeHint.setWidth(accum);
|
||||
|
||||
viewport()->update(viewport()->rect());
|
||||
}
|
||||
|
||||
int RDHeaderView::sectionSize(int logicalIndex) const
|
||||
{
|
||||
if(m_customSizing)
|
||||
{
|
||||
if(logicalIndex < 0 || logicalIndex >= m_sections.count())
|
||||
return 0;
|
||||
|
||||
return m_sections[logicalIndex].size;
|
||||
}
|
||||
|
||||
return QHeaderView::sectionSize(logicalIndex);
|
||||
}
|
||||
|
||||
int RDHeaderView::sectionViewportPosition(int logicalIndex) const
|
||||
{
|
||||
if(m_customSizing)
|
||||
{
|
||||
if(logicalIndex < 0 || logicalIndex >= m_sections.count())
|
||||
return -1;
|
||||
|
||||
int offs = m_sections[logicalIndex].offset;
|
||||
|
||||
if(logicalIndex >= m_pinnedColumns)
|
||||
offs -= offset();
|
||||
|
||||
return offs;
|
||||
}
|
||||
|
||||
return QHeaderView::sectionViewportPosition(logicalIndex);
|
||||
}
|
||||
|
||||
int RDHeaderView::visualIndexAt(int position) const
|
||||
{
|
||||
if(m_customSizing)
|
||||
{
|
||||
if(m_sections.isEmpty())
|
||||
return -1;
|
||||
|
||||
if(position >= m_pinnedWidth)
|
||||
position += offset();
|
||||
|
||||
SectionData search;
|
||||
search.offset = position;
|
||||
auto it = std::lower_bound(
|
||||
m_sections.begin(), m_sections.end(), search,
|
||||
[this](const SectionData &a, const SectionData &b) { return a.offset <= b.offset; });
|
||||
|
||||
if(it != m_sections.begin())
|
||||
--it;
|
||||
|
||||
if(it->offset <= position &&
|
||||
position < (it->offset + it->size + (it->groupGap ? groupGapSize() : 0)))
|
||||
return (it - m_sections.begin());
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
return QHeaderView::visualIndexAt(position);
|
||||
}
|
||||
|
||||
int RDHeaderView::logicalIndexAt(int position) const
|
||||
{
|
||||
return visualIndexAt(position);
|
||||
}
|
||||
|
||||
int RDHeaderView::count() const
|
||||
{
|
||||
if(m_customSizing)
|
||||
return m_sections.count();
|
||||
|
||||
return QHeaderView::count();
|
||||
}
|
||||
|
||||
void RDHeaderView::resizeSection(int logicalIndex, int size)
|
||||
{
|
||||
if(!m_customSizing)
|
||||
return QHeaderView::resizeSection(logicalIndex, size);
|
||||
|
||||
if(logicalIndex >= 0 && logicalIndex < m_sections.count())
|
||||
{
|
||||
int oldSize = m_sections[logicalIndex].size;
|
||||
m_sections[logicalIndex].size = size;
|
||||
|
||||
emit sectionResized(logicalIndex, oldSize, size);
|
||||
}
|
||||
|
||||
cacheSections();
|
||||
}
|
||||
|
||||
void RDHeaderView::resizeSections(QHeaderView::ResizeMode mode)
|
||||
{
|
||||
if(!m_customSizing)
|
||||
return resizeSections(mode);
|
||||
|
||||
if(mode != ResizeToContents)
|
||||
return;
|
||||
|
||||
QAbstractItemModel *m = this->model();
|
||||
|
||||
int rowCount = m->rowCount();
|
||||
|
||||
for(int col = 0; col < m_sections.count(); col++)
|
||||
{
|
||||
QSize sz;
|
||||
|
||||
for(int row = 0; row < rowCount; row++)
|
||||
{
|
||||
QVariant v = m->data(m->index(row, col), Qt::SizeHintRole);
|
||||
if(v.isValid() && v.canConvert<QSize>())
|
||||
sz = sz.expandedTo(v.value<QSize>());
|
||||
}
|
||||
|
||||
int oldSize = m_sections[col].size;
|
||||
|
||||
m_sections[col].size = sz.width();
|
||||
|
||||
emit sectionResized(col, oldSize, sz.width());
|
||||
}
|
||||
}
|
||||
|
||||
void RDHeaderView::resizeSections(const QList<int> &sizes)
|
||||
{
|
||||
if(!m_customSizing)
|
||||
{
|
||||
for(int i = 0; i < qMin(sizes.count(), QHeaderView::count()); i++)
|
||||
{
|
||||
QHeaderView::resizeSection(i, sizes[i]);
|
||||
}
|
||||
}
|
||||
|
||||
for(int i = 0; i < qMin(sizes.count(), m_sections.count()); i++)
|
||||
{
|
||||
int oldSize = m_sections[i].size;
|
||||
|
||||
m_sections[i].size = sizes[i];
|
||||
|
||||
emit sectionResized(i, oldSize, sizes[i]);
|
||||
}
|
||||
|
||||
cacheSections();
|
||||
}
|
||||
|
||||
bool RDHeaderView::hasGroupGap(int columnIndex) const
|
||||
{
|
||||
if(columnIndex >= 0 && columnIndex < m_sections.count())
|
||||
return m_sections[columnIndex].groupGap;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool RDHeaderView::hasGroupTitle(int columnIndex) const
|
||||
{
|
||||
if(columnIndex == m_sections.count() - 1)
|
||||
return true;
|
||||
|
||||
if(columnIndex >= 0 && columnIndex < m_sections.count())
|
||||
return m_sections[columnIndex].groupGap || m_sections[columnIndex].group < 0;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void RDHeaderView::headerDataChanged(Qt::Orientation orientation, int logicalFirst, int logicalLast)
|
||||
{
|
||||
if(m_customSizing)
|
||||
cacheSections();
|
||||
}
|
||||
|
||||
void RDHeaderView::columnsInserted(const QModelIndex &parent, int first, int last)
|
||||
{
|
||||
if(m_customSizing)
|
||||
cacheSections();
|
||||
}
|
||||
|
||||
void RDHeaderView::mousePressEvent(QMouseEvent *event)
|
||||
{
|
||||
int mousePos = event->x();
|
||||
int idx = logicalIndexAt(mousePos);
|
||||
|
||||
if(idx >= 0 && event->buttons() == Qt::LeftButton)
|
||||
if(sectionsMovable() && idx >= 0 && event->buttons() == Qt::LeftButton)
|
||||
{
|
||||
int secSize = sectionSize(idx);
|
||||
int secPos = sectionViewportPosition(idx);
|
||||
@@ -75,6 +362,14 @@ void RDHeaderView::mousePressEvent(QMouseEvent *event)
|
||||
}
|
||||
}
|
||||
|
||||
if(m_customSizing)
|
||||
{
|
||||
m_resizeState = checkResizing(event);
|
||||
m_cursorPos = QCursor::pos().x();
|
||||
|
||||
return QAbstractItemView::mousePressEvent(event);
|
||||
}
|
||||
|
||||
QHeaderView::mousePressEvent(event);
|
||||
}
|
||||
|
||||
@@ -86,9 +381,140 @@ void RDHeaderView::mouseMoveEvent(QMouseEvent *event)
|
||||
return;
|
||||
}
|
||||
|
||||
if(m_customSizing)
|
||||
{
|
||||
if(m_resizeState.first == NoResize || m_resizeState.second < 0 ||
|
||||
m_resizeState.second >= m_sections.count())
|
||||
{
|
||||
auto res = checkResizing(event);
|
||||
|
||||
bool hasCursor = testAttribute(Qt::WA_SetCursor);
|
||||
|
||||
if(res.first != NoResize)
|
||||
{
|
||||
if(!hasCursor)
|
||||
setCursor(Qt::SplitHCursor);
|
||||
}
|
||||
else if(hasCursor)
|
||||
{
|
||||
unsetCursor();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
int curX = QCursor::pos().x();
|
||||
int delta = curX - m_cursorPos;
|
||||
|
||||
int idx = m_resizeState.second;
|
||||
|
||||
if(m_resizeState.first == LeftResize && idx > 0)
|
||||
idx--;
|
||||
|
||||
// batch the cache update
|
||||
m_suppressSectionCache = true;
|
||||
|
||||
int firstCol = idx;
|
||||
int lastCol = idx;
|
||||
|
||||
// idx is the last in a group, so search backwards to see if there are neighbour sections we
|
||||
// should share the resize with
|
||||
while(firstCol > 0 && m_sections[firstCol - 1].group == m_sections[lastCol].group)
|
||||
firstCol--;
|
||||
|
||||
// how much space could we lose on the columns, in total
|
||||
int freeSpace = 0;
|
||||
for(int col = firstCol; col <= lastCol; col++)
|
||||
freeSpace += m_sections[col].size - minimumSectionSize();
|
||||
|
||||
int numCols = lastCol - firstCol + 1;
|
||||
|
||||
// spread the delta amonst the colummns
|
||||
int perSectionDelta = delta / numCols;
|
||||
|
||||
// call resizeSection to emit the sectionResized signal but we set m_suppressSectionCache so
|
||||
// we won't cache sections.
|
||||
for(int col = firstCol; col <= lastCol; col++)
|
||||
resizeSection(col, qMax(minimumSectionSize(), m_sections[col].size + perSectionDelta));
|
||||
|
||||
// if there was an uneven spread, a few pixels will remain
|
||||
int remainder = delta - perSectionDelta * numCols;
|
||||
|
||||
// loop around for the remainder pixels, assigning them one by one to the smallest/largest
|
||||
// column.
|
||||
// this is inefficient but remainder is very small - at most 3.
|
||||
int step = remainder < 0 ? -1 : 1;
|
||||
for(int i = 0; i < qAbs(remainder); i++)
|
||||
{
|
||||
int chosenCol = firstCol;
|
||||
for(int col = firstCol; col <= lastCol; col++)
|
||||
{
|
||||
if(step > 0 && m_sections[col].size < m_sections[chosenCol].size)
|
||||
chosenCol = col;
|
||||
else if(step < 0 && m_sections[col].size > m_sections[chosenCol].size)
|
||||
chosenCol = col;
|
||||
}
|
||||
|
||||
resizeSection(chosenCol, qMax(minimumSectionSize(), m_sections[chosenCol].size + step));
|
||||
}
|
||||
|
||||
// only updating the cursor when the section is moving means that it becomes 'sticky'. If we
|
||||
// try to size down below the minimum size and keep going then it doesn't start resizing up
|
||||
// until it passes the divider again.
|
||||
int appliedDelta = delta;
|
||||
|
||||
// if we were resizing down, at best we removed the remaining free space
|
||||
if(delta < 0)
|
||||
appliedDelta = qMax(delta, -freeSpace);
|
||||
|
||||
m_cursorPos += appliedDelta;
|
||||
|
||||
m_suppressSectionCache = false;
|
||||
|
||||
cacheSections();
|
||||
}
|
||||
|
||||
return QAbstractItemView::mouseMoveEvent(event);
|
||||
}
|
||||
|
||||
QHeaderView::mouseMoveEvent(event);
|
||||
}
|
||||
|
||||
QPair<RDHeaderView::ResizeType, int> RDHeaderView::checkResizing(QMouseEvent *event)
|
||||
{
|
||||
int mousePos = event->x();
|
||||
int idx = logicalIndexAt(mousePos);
|
||||
|
||||
bool hasCursor = testAttribute(Qt::WA_SetCursor);
|
||||
bool cursorSet = false;
|
||||
|
||||
bool leftResize = idx > 0 && (m_sections[idx - 1].group != m_sections[idx].group);
|
||||
bool rightResize = idx >= 0 && hasGroupTitle(idx);
|
||||
|
||||
if(leftResize || rightResize)
|
||||
{
|
||||
int secSize = sectionSize(idx);
|
||||
int secPos = sectionViewportPosition(idx);
|
||||
|
||||
int handleWidth = style()->pixelMetric(QStyle::PM_HeaderGripMargin, 0, this);
|
||||
|
||||
int gapWidth = 0;
|
||||
if(hasGroupGap(idx))
|
||||
gapWidth = groupGapSize();
|
||||
|
||||
if(leftResize && secPos >= 0 && secSize > 0 && mousePos < secPos + handleWidth)
|
||||
{
|
||||
return qMakePair(LeftResize, idx);
|
||||
}
|
||||
if(rightResize && secPos >= 0 && secSize > 0 &&
|
||||
mousePos > secPos + secSize - handleWidth - gapWidth)
|
||||
{
|
||||
return qMakePair(RightResize, idx);
|
||||
}
|
||||
}
|
||||
|
||||
return qMakePair(NoResize, -1);
|
||||
}
|
||||
|
||||
void RDHeaderView::mouseReleaseEvent(QMouseEvent *event)
|
||||
{
|
||||
if(m_movingSection >= 0)
|
||||
@@ -132,5 +558,197 @@ void RDHeaderView::mouseReleaseEvent(QMouseEvent *event)
|
||||
|
||||
m_movingSection = -1;
|
||||
|
||||
if(m_customSizing)
|
||||
{
|
||||
m_resizeState = qMakePair(NoResize, -1);
|
||||
|
||||
return QAbstractItemView::mouseReleaseEvent(event);
|
||||
}
|
||||
|
||||
QHeaderView::mouseReleaseEvent(event);
|
||||
}
|
||||
|
||||
void RDHeaderView::paintEvent(QPaintEvent *e)
|
||||
{
|
||||
if(!m_customSizing)
|
||||
return QHeaderView::paintEvent(e);
|
||||
|
||||
if(count() == 0)
|
||||
return;
|
||||
|
||||
QPainter painter(viewport());
|
||||
|
||||
int start = qMax(visualIndexAt(e->rect().left()), 0);
|
||||
int end = visualIndexAt(e->rect().right());
|
||||
|
||||
if(end == -1)
|
||||
end = count() - 1;
|
||||
|
||||
// make sure we always paint the whole header for any merged headers
|
||||
while(start > 0 && !hasGroupTitle(start - 1))
|
||||
start--;
|
||||
while(end < m_sections.count() && !hasGroupTitle(end))
|
||||
end++;
|
||||
|
||||
QRect accumRect;
|
||||
for(int i = start; i <= end; ++i)
|
||||
{
|
||||
int pos = sectionViewportPosition(i);
|
||||
int size = sectionSize(i);
|
||||
|
||||
if(!hasGroupGap(i) && pos < 0)
|
||||
{
|
||||
size += pos;
|
||||
pos = 0;
|
||||
}
|
||||
|
||||
// either set or accumulate this section's rect
|
||||
if(accumRect.isEmpty())
|
||||
accumRect.setRect(pos, 0, size, viewport()->height());
|
||||
else
|
||||
accumRect.setWidth(accumRect.width() + size);
|
||||
|
||||
if(hasGroupTitle(i))
|
||||
{
|
||||
painter.save();
|
||||
accumRect.setWidth(accumRect.width() - 1);
|
||||
|
||||
if(accumRect.left() < m_pinnedWidth && i >= m_pinnedColumns)
|
||||
accumRect.setLeft(m_pinnedWidth);
|
||||
|
||||
paintSection(&painter, accumRect, i);
|
||||
painter.restore();
|
||||
|
||||
// if we have more sections to go, reset so we can accumulate the next group
|
||||
if(i < end)
|
||||
accumRect = QRect();
|
||||
}
|
||||
}
|
||||
|
||||
// clear the remainder of the header if there's a gap
|
||||
if(accumRect.right() < e->rect().right())
|
||||
{
|
||||
QStyleOption opt;
|
||||
opt.init(this);
|
||||
opt.state |= QStyle::State_Horizontal;
|
||||
opt.rect =
|
||||
QRect(accumRect.right() + 1, 0, e->rect().right() - accumRect.right(), viewport()->height());
|
||||
style()->drawControl(QStyle::CE_HeaderEmptyArea, &opt, &painter, this);
|
||||
}
|
||||
}
|
||||
|
||||
void RDHeaderView::paintSection(QPainter *painter, const QRect &rect, int section) const
|
||||
{
|
||||
if(!m_customSizing)
|
||||
return QHeaderView::paintSection(painter, rect, section);
|
||||
|
||||
if(!rect.isValid())
|
||||
return;
|
||||
|
||||
QStyleOptionHeader opt;
|
||||
initStyleOption(&opt);
|
||||
|
||||
QAbstractItemModel *m = this->model();
|
||||
|
||||
if(hasFocus())
|
||||
opt.state |= (QStyle::State_Active | QStyle::State_HasFocus);
|
||||
else
|
||||
opt.state &= ~(QStyle::State_Active | QStyle::State_HasFocus);
|
||||
|
||||
QVariant textAlignment = m->headerData(section, orientation(), Qt::TextAlignmentRole);
|
||||
opt.rect = rect;
|
||||
opt.section = section;
|
||||
opt.textAlignment = Qt::AlignLeft | Qt::AlignVCenter;
|
||||
opt.iconAlignment = Qt::AlignVCenter;
|
||||
|
||||
QVariant variant;
|
||||
|
||||
if(m_columnGroupRole)
|
||||
{
|
||||
variant = m->headerData(section, orientation(), m_columnGroupRole);
|
||||
if(variant.isValid() && variant.canConvert<QString>())
|
||||
opt.text = variant.toString();
|
||||
}
|
||||
|
||||
if(opt.text.isEmpty())
|
||||
opt.text = m->headerData(section, orientation(), Qt::DisplayRole).toString();
|
||||
|
||||
int margin = 2 * style()->pixelMetric(QStyle::PM_HeaderMargin, 0, this);
|
||||
|
||||
if(textElideMode() != Qt::ElideNone)
|
||||
opt.text = opt.fontMetrics.elidedText(opt.text, textElideMode(), rect.width() - margin);
|
||||
|
||||
if(section == 0 && section == m_sections.count() - 1)
|
||||
opt.position = QStyleOptionHeader::OnlyOneSection;
|
||||
else if(section == 0)
|
||||
opt.position = QStyleOptionHeader::Beginning;
|
||||
else if(section == m_sections.count() - 1)
|
||||
opt.position = QStyleOptionHeader::End;
|
||||
else
|
||||
opt.position = QStyleOptionHeader::Middle;
|
||||
|
||||
opt.orientation = orientation();
|
||||
|
||||
bool prevSel = section > 0 && selectionModel()->isColumnSelected(section - 1, QModelIndex());
|
||||
bool nextSel = section + 1 < m_sections.count() &&
|
||||
selectionModel()->isColumnSelected(section + 1, QModelIndex());
|
||||
|
||||
if(prevSel && nextSel)
|
||||
opt.selectedPosition = QStyleOptionHeader::NextAndPreviousAreSelected;
|
||||
else if(prevSel)
|
||||
opt.selectedPosition = QStyleOptionHeader::PreviousIsSelected;
|
||||
else if(nextSel)
|
||||
opt.selectedPosition = QStyleOptionHeader::NextIsSelected;
|
||||
else
|
||||
opt.selectedPosition = QStyleOptionHeader::NotAdjacent;
|
||||
|
||||
style()->drawControl(QStyle::CE_Header, &opt, painter, this);
|
||||
}
|
||||
|
||||
void RDHeaderView::currentChanged(const QModelIndex ¤t, const QModelIndex &old)
|
||||
{
|
||||
if(!m_customSizing)
|
||||
return QHeaderView::currentChanged(current, old);
|
||||
|
||||
// not optimal at all
|
||||
if(current != old)
|
||||
{
|
||||
QRect r = viewport()->rect();
|
||||
|
||||
if(old.isValid())
|
||||
{
|
||||
QRect rect = r;
|
||||
|
||||
if(orientation() == Qt::Horizontal)
|
||||
{
|
||||
rect.setLeft(sectionViewportPosition(old.column()));
|
||||
rect.setWidth(sectionSize(old.column()));
|
||||
}
|
||||
else
|
||||
{
|
||||
rect.setTop(sectionViewportPosition(old.column()));
|
||||
rect.setHeight(sectionSize(old.column()));
|
||||
}
|
||||
|
||||
viewport()->update(rect);
|
||||
}
|
||||
|
||||
if(current.isValid())
|
||||
{
|
||||
QRect rect = r;
|
||||
|
||||
if(orientation() == Qt::Horizontal)
|
||||
{
|
||||
rect.setLeft(sectionViewportPosition(current.column()));
|
||||
rect.setWidth(sectionSize(current.column()));
|
||||
}
|
||||
else
|
||||
{
|
||||
rect.setTop(sectionViewportPosition(current.column()));
|
||||
rect.setHeight(sectionSize(current.column()));
|
||||
}
|
||||
|
||||
viewport()->update(rect);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user