From cc5520edda2adb46530f43fa148c4d46c8f962b3 Mon Sep 17 00:00:00 2001 From: Teo Mrnjavac Date: Fri, 4 Dec 2015 18:02:19 +0100 Subject: [PATCH] Add hover and click support to PartitionBarsView. --- .../partition/gui/PartitionBarsView.cpp | 140 +++++++++++++++--- src/modules/partition/gui/PartitionBarsView.h | 13 ++ 2 files changed, 135 insertions(+), 18 deletions(-) diff --git a/src/modules/partition/gui/PartitionBarsView.cpp b/src/modules/partition/gui/PartitionBarsView.cpp index 3ebde12c7..2181d83ea 100644 --- a/src/modules/partition/gui/PartitionBarsView.cpp +++ b/src/modules/partition/gui/PartitionBarsView.cpp @@ -23,11 +23,13 @@ #include -#include "utils/CalamaresUtilsGui.h" +#include +#include // Qt #include +#include #include @@ -38,9 +40,18 @@ static const int EXTENDED_PARTITION_MARGIN = 4; PartitionBarsView::PartitionBarsView( QWidget* parent ) : QAbstractItemView( parent ) + , m_hoveredRow( -1 ) { setSizePolicy( QSizePolicy::Expanding, QSizePolicy::Fixed ); setFrameStyle( QFrame::NoFrame ); + + // Debug + connect( this, &PartitionBarsView::clicked, + this, [=]( const QModelIndex& index ) + { + cDebug() << "Clicked row" << index.row(); + } ); + setMouseTracking( true ); } @@ -79,8 +90,8 @@ PartitionBarsView::paintEvent( QPaintEvent* event ) } -static void -drawSection( QPainter* painter, const QRect& rect_, int x, int width, const QModelIndex& index ) +void +PartitionBarsView::drawSection( QPainter* painter, const QRect& rect_, int x, int width, const QModelIndex& index ) { QColor color = index.isValid() ? index.data( Qt::DecorationRole ).value< QColor >() : @@ -99,7 +110,13 @@ drawSection( QPainter* painter, const QRect& rect_, int x, int width, const QMod rect.adjust( 0, 0, -1, -1 ); const QColor borderColor = color.darker(); painter->setPen( borderColor ); - painter->setBrush( color ); + + + if ( index.row() == m_hoveredRow ) + painter->setBrush( color.lighter( 105 ) ); + else + painter->setBrush( color ); + painter->drawRoundedRect( rect, radius, radius ); // Draw shade @@ -129,21 +146,10 @@ PartitionBarsView::drawPartitions( QPainter* painter, const QRect& rect, const Q const int count = modl->rowCount( parent ); const int totalWidth = rect.width(); qDebug() << "count:" << count << "totalWidth:" << totalWidth; - struct Item - { - qreal size; - QModelIndex index; - }; - QVector< Item > items( count ); - qreal total = 0; - for ( int row = 0; row < count; ++row ) - { - QModelIndex index = modl->index( row, 0, parent ); - qreal size = index.data( PartitionModel::SizeRole ).toLongLong(); - total += size; - items[ row ] = { size, index }; - } + auto pair = computeItemsVector( parent ); + QVector< PartitionBarsView::Item >& items = pair.first; + qreal& total = pair.second; int x = rect.x(); for ( int row = 0; row < count; ++row ) { @@ -181,6 +187,54 @@ PartitionBarsView::drawPartitions( QPainter* painter, const QRect& rect, const Q QModelIndex PartitionBarsView::indexAt( const QPoint& point ) const { + return indexAt( point, rect(), QModelIndex() ); +} + + +QModelIndex +PartitionBarsView::indexAt( const QPoint &point, const QRect &rect, const QModelIndex& parent ) const +{ + PartitionModel* modl = qobject_cast< PartitionModel* >( model() ); + if ( !modl ) + return QModelIndex(); + const int count = modl->rowCount( parent ); + const int totalWidth = rect.width(); + + auto pair = computeItemsVector( parent ); + QVector< PartitionBarsView::Item >& items = pair.first; + qreal& total = pair.second; + int x = rect.x(); + for ( int row = 0; row < count; ++row ) + { + const auto& item = items[ row ]; + int width; + if ( row < count - 1 ) + width = totalWidth * ( item.size / total ); + else + // Make sure we fill the last pixel column + width = rect.right() - x + 1; + + QRect thisItemRect( x, rect.y(), width, rect.height() ); + if ( thisItemRect.contains( point ) ) + { + if ( modl->hasChildren( item.index ) ) + { + QRect subRect( + x + EXTENDED_PARTITION_MARGIN, + rect.y() + EXTENDED_PARTITION_MARGIN, + width - 2 * EXTENDED_PARTITION_MARGIN, + rect.height() - 2 * EXTENDED_PARTITION_MARGIN + ); + if ( subRect.contains( point ) ) + return indexAt( point, subRect, item.index ); + return item.index; + } + else // contains but no children, we win + return item.index; + } + x += width; + } + return QModelIndex(); } @@ -239,8 +293,58 @@ PartitionBarsView::setSelection( const QRect& rect, QItemSelectionModel::Selecti } +void +PartitionBarsView::mouseMoveEvent( QMouseEvent* event ) +{ + QModelIndex candidateIndex = indexAt( event->pos() ); + int oldHoveredRow = m_hoveredRow; + if ( candidateIndex.isValid() ) + { + m_hoveredRow = candidateIndex.row(); + } + else + m_hoveredRow = -1; + + if ( oldHoveredRow != m_hoveredRow ) + { + viewport()->repaint(); + } +} + + +void +PartitionBarsView::leaveEvent( QEvent* event ) +{ + if ( m_hoveredRow > -1 ) + { + m_hoveredRow = -1; + viewport()->repaint(); + } +} + + void PartitionBarsView::updateGeometries() { updateGeometry(); //get a new rect() for redrawing all the labels } + + +QPair< QVector< PartitionBarsView::Item >, qreal > +PartitionBarsView::computeItemsVector( const QModelIndex& parent ) const +{ + const int count = model()->rowCount( parent ); + QVector< PartitionBarsView::Item > items( count ); + + qreal total = 0; + for ( int row = 0; row < count; ++row ) + { + QModelIndex index = model()->index( row, 0, parent ); + qreal size = index.data( PartitionModel::SizeRole ).toLongLong(); + total += size; + items[ row ] = { size, index }; + } + + return qMakePair( items, total ); +} + diff --git a/src/modules/partition/gui/PartitionBarsView.h b/src/modules/partition/gui/PartitionBarsView.h index aa6cf3c69..7f9869d75 100644 --- a/src/modules/partition/gui/PartitionBarsView.h +++ b/src/modules/partition/gui/PartitionBarsView.h @@ -54,11 +54,24 @@ protected: QModelIndex moveCursor( CursorAction cursorAction, Qt::KeyboardModifiers modifiers ) override; void setSelection( const QRect& rect, QItemSelectionModel::SelectionFlags flags ) override; + void mouseMoveEvent( QMouseEvent* event ) override; + void leaveEvent( QEvent* event ) override; + protected slots: void updateGeometries() override; private: void drawPartitions( QPainter* painter, const QRect& rect, const QModelIndex& parent ); + void drawSection( QPainter* painter, const QRect& rect_, int x, int width, const QModelIndex& index ); + QModelIndex indexAt( const QPoint& point, const QRect& rect, const QModelIndex& parent ) const; + + struct Item + { + qreal size; + QModelIndex index; + }; + inline QPair< QVector< Item >, qreal > computeItemsVector( const QModelIndex& parent ) const; + int m_hoveredRow; }; #endif /* PARTITIONPREVIEW_H */