Hovered/Pressed states for QskListView cells added

This commit is contained in:
Uwe Rathmann 2023-07-31 17:16:41 +02:00
parent 849411ea97
commit 946bac677d
6 changed files with 127 additions and 13 deletions

View File

@ -612,8 +612,10 @@ void Editor::setupFocusIndicatorColors(
void Editor::setupListViewMetrics()
{
using Q = QskListView;
using A = QskAspect;
setBoxBorderMetrics( Q::Cell | Q::Selected, { 3, 0, 0, 0 } );
for ( auto state : { A::NoState, Q::Hovered, Q::Pressed } )
setBoxBorderMetrics( Q::Cell | state | Q::Selected, { 3, 0, 0, 0 } );
#if 1
// taken from M3 - what are the actual values, TODO ...
setPadding( Q::Cell, { 16, 12, 16, 12 } );
@ -693,6 +695,9 @@ void Editor::setupListViewColors(
setColor( text, textColor );
}
}
setAnimation( Q::Cell | A::Color, 100 );
setAnimation( Q::Text | A::Color, 100 );
}
void Editor::setupMenuMetrics()

View File

@ -1150,6 +1150,7 @@ void Editor::setupScrollView()
void Editor::setupListView()
{
using A = QskAspect;
using Q = QskListView;
setStrutSize( Q::Cell, { -1, 56 } );
@ -1157,7 +1158,9 @@ void Editor::setupListView()
setBoxBorderColors( Q::Cell, m_pal.outline );
setGradient( Q::Cell, m_pal.surface );
setGradient( Q::Cell | Q::Selected, m_pal.primary12 );
for ( auto state : { A::NoState, Q::Hovered, Q::Pressed } )
setGradient( Q::Cell | state | Q::Selected, m_pal.primary12 );
setColor( Q::Text, m_pal.onSurface );
}

View File

@ -1057,12 +1057,17 @@ void Editor::setupListView()
// alternating row colors
setColor( Q::Cell | A::Lower, Qt::white );
setColor( Q::Cell | Q::Selected | A::Lower, m_pal.highlighted );
setColor( Q::Cell | A::Upper, m_pal.contrasted );
setColor( Q::Cell | Q::Selected | A::Upper, m_pal.highlighted );
setColor( Q::Text | Q::Selected, m_pal.highlightedText );
for ( auto state : { A::NoState, Q::Hovered, Q::Pressed } )
{
const auto aspect = Q::Cell | state | Q::Selected;
setColor( aspect | A::Lower, m_pal.highlighted );
setColor( aspect | A::Upper, m_pal.highlighted );
setColor( Q::Text | state | Q::Selected, m_pal.highlightedText );
}
}
void Editor::setupSubWindow()

View File

@ -46,6 +46,48 @@ class QskListView::PrivateData
{
}
void setRowState( QskListView* listView, int row, QskAspect::State state )
{
using Q = QskListView;
auto& storedRow = ( state == Q::Hovered )
? hoveredRow : ( ( state == Q::Pressed ) ? pressedRow : selectedRow );
if ( row == storedRow )
return;
if ( storedRow >= 0 )
{
const auto states = listView->rowStates( storedRow );
startTransitions( listView, storedRow, states, states & ~state );
}
if ( row >= 0 )
{
const auto states = listView->rowStates( row );
startTransitions( listView, row, states, states | state );
}
storedRow = row;
}
private:
inline void startTransitions( QskListView* listView, int row,
QskAspect::States oldStates, QskAspect::States newStates )
{
/*
working implementation can be found in
https://github.com/uwerat/qskinny/tree/features/listview
*/
Q_UNUSED( row );
Q_UNUSED( oldStates );
Q_UNUSED( newStates );
listView->update();
}
public:
/*
Currently we only support single selection. We can't navigate
the current item ( = focus ) without changing the selection.
@ -55,6 +97,8 @@ class QskListView::PrivateData
bool preferredWidthFromColumns : 1;
SelectionMode selectionMode : 4;
int hoveredRow = -1;
int pressedRow = -1;
int selectedRow = -1;
};
@ -131,7 +175,8 @@ void QskListView::setSelectedRow( int row )
if ( row != m_data->selectedRow )
{
m_data->selectedRow = row;
m_data->setRowState( this, row, Selected );
Q_EMIT selectedRowChanged( row );
Q_EMIT focusIndicatorRectChanged();
@ -280,6 +325,7 @@ void QskListView::mousePressEvent( QMouseEvent* event )
const int row = qskRowAt( this, qskMousePosition( event ) );
if ( row >= 0 )
{
m_data->setRowState( this, row, Pressed );
setSelectedRow( row );
return;
}
@ -290,9 +336,44 @@ void QskListView::mousePressEvent( QMouseEvent* event )
void QskListView::mouseReleaseEvent( QMouseEvent* event )
{
m_data->setRowState( this, -1, Pressed );
Inherited::mouseReleaseEvent( event );
}
void QskListView::mouseUngrabEvent()
{
m_data->setRowState( this, -1, Pressed );
Inherited::mouseUngrabEvent();
}
void QskListView::hoverEnterEvent( QHoverEvent* event )
{
if ( m_data->selectionMode != NoSelection )
{
const int row = qskRowAt( this, qskHoverPosition( event ) );
m_data->setRowState( this, row, Hovered );
}
Inherited::hoverEnterEvent( event );
}
void QskListView::hoverMoveEvent( QHoverEvent* event )
{
if ( m_data->selectionMode != NoSelection )
{
const int row = qskRowAt( this, qskHoverPosition( event ) );
m_data->setRowState( this, row, Hovered );
}
Inherited::hoverMoveEvent( event );
}
void QskListView::hoverLeaveEvent( QHoverEvent* event )
{
m_data->setRowState( this, -1, Hovered );
Inherited::hoverLeaveEvent( event );
}
void QskListView::changeEvent( QEvent* event )
{
if ( event->type() == QEvent::StyleChange )
@ -301,6 +382,25 @@ void QskListView::changeEvent( QEvent* event )
Inherited::changeEvent( event );
}
QskAspect::States QskListView::rowStates( int row ) const
{
auto states = skinStates();
if ( row >= 0 )
{
if ( row == m_data->selectedRow )
states |= Selected;
if ( row == m_data->hoveredRow )
states |= Hovered;
if ( row == m_data->pressedRow )
states |= Pressed;
}
return states;
}
#ifndef QT_NO_WHEELEVENT
static qreal qskAlignedToRows( const qreal y0, qreal dy,

View File

@ -54,6 +54,7 @@ class QSK_EXPORT QskListView : public QskScrollView
QskTextOptions textOptions() const;
Q_INVOKABLE int selectedRow() const;
QskAspect::States rowStates( int ) const;
virtual int rowCount() const = 0;
virtual int columnCount() const = 0;
@ -83,6 +84,11 @@ class QSK_EXPORT QskListView : public QskScrollView
void mousePressEvent( QMouseEvent* ) override;
void mouseReleaseEvent( QMouseEvent* ) override;
void mouseUngrabEvent() override;
void hoverEnterEvent( QHoverEvent* ) override;
void hoverMoveEvent( QHoverEvent* ) override;
void hoverLeaveEvent( QHoverEvent* ) override;
#ifndef QT_NO_WHEELEVENT
virtual QPointF scrollOffset( const QWheelEvent* ) const override;

View File

@ -470,12 +470,7 @@ QskAspect::States QskListViewSkinlet::sampleStates( const QskSkinnable* skinnabl
if ( subControl == Q::Cell || subControl == Q::Text || subControl == Q::Graphic )
{
const auto listView = static_cast< const QskListView* >( skinnable );
auto states = listView->skinStates();
if ( index == listView->selectedRow() )
states |= Q::Selected;
return states;
return listView->rowStates( index );
}
return Inherited::sampleStates( skinnable, subControl, index );