focusIndicator around the current row
This commit is contained in:
parent
f0a2803df7
commit
881a607428
|
@ -7,6 +7,7 @@
|
|||
#include "QskAspect.h"
|
||||
#include "QskColorFilter.h"
|
||||
#include "QskEvent.h"
|
||||
#include "QskSkinlet.h"
|
||||
|
||||
#include <qguiapplication.h>
|
||||
#include <qstylehints.h>
|
||||
|
@ -24,20 +25,26 @@ class QskListView::PrivateData
|
|||
PrivateData()
|
||||
: preferredWidthFromColumns( false )
|
||||
, selectionMode( QskListView::SingleSelection )
|
||||
, selectedRow( -1 )
|
||||
{
|
||||
}
|
||||
|
||||
/*
|
||||
Currently we only support single selection. We can't navigate
|
||||
the current item ( = focus ) without changing the selection.
|
||||
So for the moment the selected row is always the currentRow.
|
||||
*/
|
||||
|
||||
bool preferredWidthFromColumns : 1;
|
||||
SelectionMode selectionMode : 4;
|
||||
|
||||
int selectedRow;
|
||||
int selectedRow = -1;
|
||||
};
|
||||
|
||||
QskListView::QskListView( QQuickItem* parent )
|
||||
: QskScrollView( parent )
|
||||
, m_data( new PrivateData() )
|
||||
{
|
||||
connect( this, &QskScrollView::scrollPosChanged, &QskControl::focusIndicatorRectChanged );
|
||||
}
|
||||
|
||||
QskListView::~QskListView()
|
||||
|
@ -123,6 +130,7 @@ void QskListView::setSelectedRow( int row )
|
|||
{
|
||||
m_data->selectedRow = row;
|
||||
Q_EMIT selectedRowChanged( row );
|
||||
Q_EMIT focusIndicatorRectChanged();
|
||||
|
||||
update();
|
||||
}
|
||||
|
@ -159,6 +167,19 @@ QskColorFilter QskListView::graphicFilterAt( int row, int col ) const
|
|||
return QskColorFilter();
|
||||
}
|
||||
|
||||
QRectF QskListView::focusIndicatorRect() const
|
||||
{
|
||||
if( m_data->selectedRow >= 0 )
|
||||
{
|
||||
const auto rect = effectiveSkinlet()->sampleRect(
|
||||
this, contentsRect(), Cell, m_data->selectedRow );
|
||||
|
||||
return rect.translated( -scrollPos() );
|
||||
}
|
||||
|
||||
return Inherited::focusIndicatorRect();
|
||||
}
|
||||
|
||||
void QskListView::keyPressEvent( QKeyEvent* event )
|
||||
{
|
||||
if ( m_data->selectionMode == NoSelection )
|
||||
|
@ -206,8 +227,19 @@ void QskListView::keyPressEvent( QKeyEvent* event )
|
|||
}
|
||||
default:
|
||||
{
|
||||
Inherited::keyPressEvent( event );
|
||||
return;
|
||||
if ( const int steps = qskFocusChainIncrement( event ) )
|
||||
{
|
||||
row += steps;
|
||||
|
||||
if( row < 0 )
|
||||
{
|
||||
row += rowCount();
|
||||
}
|
||||
else if( row >= rowCount() )
|
||||
{
|
||||
row %= rowCount();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -75,6 +75,8 @@ class QSK_EXPORT QskListView : public QskScrollView
|
|||
virtual QskColorFilter graphicFilterAt( int row, int col ) const;
|
||||
#endif
|
||||
|
||||
QRectF focusIndicatorRect() const override;
|
||||
|
||||
public Q_SLOTS:
|
||||
void setSelectedRow( int row );
|
||||
|
||||
|
|
|
@ -127,8 +127,6 @@ void QskListViewSkinlet::updateBackgroundNodes(
|
|||
rowMax = listView->rowCount() - 1;
|
||||
|
||||
const int rowSelected = listView->selectedRow();
|
||||
const double x0 = viewRect.left() + scrolledPos.x();
|
||||
const double y0 = viewRect.top();
|
||||
|
||||
auto rowNode = backgroundNode->firstChild();
|
||||
|
||||
|
@ -138,8 +136,7 @@ void QskListViewSkinlet::updateBackgroundNodes(
|
|||
{
|
||||
if ( row % 2 )
|
||||
{
|
||||
const QRectF rect( x0, y0 + row * cellHeight,
|
||||
viewRect.width(), cellHeight );
|
||||
const auto rect = sampleRect( listView, listView->contentsRect(), Q::Cell, row );
|
||||
|
||||
auto newNode = updateBoxNode( listView, rowNode, rect, Q::Cell );
|
||||
if ( newNode )
|
||||
|
@ -158,8 +155,7 @@ void QskListViewSkinlet::updateBackgroundNodes(
|
|||
QskSkinStateChanger stateChanger( listView );
|
||||
stateChanger.setStates( listView->skinStates() | QskListView::Selected );
|
||||
|
||||
const QRectF rect( x0, y0 + rowSelected * cellHeight,
|
||||
viewRect.width(), cellHeight );
|
||||
const auto rect = sampleRect( listView, listView->contentsRect(), Q::Cell, rowSelected );
|
||||
|
||||
rowNode = updateBoxNode( listView, rowNode, rect, Q::Cell );
|
||||
if ( rowNode && rowNode->parent() != backgroundNode )
|
||||
|
@ -490,4 +486,26 @@ QSizeF QskListViewSkinlet::sizeHint( const QskSkinnable* skinnable,
|
|||
return QSizeF( w, -1.0 );
|
||||
}
|
||||
|
||||
QRectF QskListViewSkinlet::sampleRect( const QskSkinnable* skinnable,
|
||||
const QRectF& contentsRect, QskAspect::Subcontrol subControl, int index ) const
|
||||
{
|
||||
using Q = QskListView;
|
||||
const auto listView = static_cast< const QskListView* >( skinnable );
|
||||
|
||||
if ( subControl == Q::Cell )
|
||||
{
|
||||
const auto cellHeight = listView->rowHeight();
|
||||
const auto viewRect = listView->viewContentsRect();
|
||||
const auto scrolledPos = listView->scrollPos();
|
||||
|
||||
const double x0 = viewRect.left() + scrolledPos.x();
|
||||
const double y0 = viewRect.top();
|
||||
|
||||
const QRectF rect( x0, y0 + index * cellHeight, viewRect.width(), cellHeight );
|
||||
return rect;
|
||||
}
|
||||
|
||||
return Inherited::sampleRect( skinnable, contentsRect, subControl, index );
|
||||
}
|
||||
|
||||
#include "moc_QskListViewSkinlet.cpp"
|
||||
|
|
|
@ -37,6 +37,9 @@ class QSK_EXPORT QskListViewSkinlet : public QskScrollViewSkinlet
|
|||
QSizeF sizeHint( const QskSkinnable*,
|
||||
Qt::SizeHint, const QSizeF& ) const override;
|
||||
|
||||
QRectF sampleRect( const QskSkinnable*,
|
||||
const QRectF&, QskAspect::Subcontrol, int index ) const override;
|
||||
|
||||
protected:
|
||||
QSGNode* updateContentsNode(
|
||||
const QskScrollView*, QSGNode* ) const override;
|
||||
|
|
Loading…
Reference in New Issue