6#include "QskListView.h" 
    8#include "QskColorFilter.h" 
   10#include "QskSkinlet.h" 
   12#include <qguiapplication.h> 
   13#include <qstylehints.h> 
   23#define FOCUS_ON_CURRENT 1 
   25static inline int qskRowAt( 
const QskListView* listView, 
const QPointF& pos )
 
   27    const auto rect = listView->viewContentsRect();
 
   28    if ( rect.contains( pos ) )
 
   30        const auto y = pos.y() - rect.top() + listView->scrollPos().y();
 
   32        const int row = y / listView->rowHeight();
 
   33        if ( row >= 0 && row < listView->rowCount() )
 
   40class QskListView::PrivateData
 
   44        : preferredWidthFromColumns( false )
 
   54            ? hoveredRow : ( ( state == 
Q::Pressed ) ? pressedRow : selectedRow );
 
   56        if ( row == storedRow )
 
   61            const auto states = listView->rowStates( storedRow );
 
   62            startTransitions( listView, storedRow, states, states & ~state );
 
   67            const auto states = listView->rowStates( row );
 
   68            startTransitions( listView, row, states, states | state );
 
   76    inline void startTransitions( 
QskListView* listView, 
int row,
 
   77        QskAspect::States oldStates, QskAspect::States newStates )
 
   81        listView->startHintTransitions(
 
   82            { Q::Cell, Q::Text }, oldStates, newStates, row );
 
   92    bool preferredWidthFromColumns : 1;
 
   93    SelectionMode selectionMode : 4;
 
  100QskListView::QskListView( QQuickItem* parent )
 
  102    , m_data( new PrivateData() )
 
  109QskListView::~QskListView()
 
  113void QskListView::setPreferredWidthFromColumns( 
bool on )
 
  115    if ( on != m_data->preferredWidthFromColumns )
 
  117        m_data->preferredWidthFromColumns = on;
 
  120        Q_EMIT preferredWidthFromColumnsChanged();
 
  124bool QskListView::preferredWidthFromColumns()
 const 
  126    return m_data->preferredWidthFromColumns;
 
  129void QskListView::setTextOptions( 
const QskTextOptions& textOptions )
 
  131    if ( setTextOptionsHint( Text, textOptions ) )
 
  133        updateScrollableSize();
 
  134        Q_EMIT textOptionsChanged();
 
  140    return textOptionsHint( Text );
 
  143void QskListView::resetTextOptions()
 
  145    if ( resetTextOptionsHint( Text ) )
 
  147        updateScrollableSize();
 
  148        Q_EMIT textOptionsChanged();
 
  152void QskListView::setSelectedRow( 
int row )
 
  157    if ( row >= rowCount() )
 
  159        if ( !isComponentComplete() )
 
  166            if ( row >= rowCount() )
 
  171    if ( row != m_data->selectedRow )
 
  173        m_data->setRowState( 
this, row, Selected );
 
  175        Q_EMIT selectedRowChanged( row );
 
  182int QskListView::selectedRow()
 const 
  184    return m_data->selectedRow;
 
  187void QskListView::setSelectionMode( SelectionMode mode )
 
  189    if ( mode != m_data->selectionMode )
 
  191        m_data->selectionMode = mode;
 
  193        if ( m_data->selectionMode == NoSelection )
 
  194            setSelectedRow( -1 );
 
  196        Q_EMIT selectionModeChanged();
 
  200QskListView::SelectionMode QskListView::selectionMode()
 const 
  202    return m_data->selectionMode;
 
  208    if( m_data->selectedRow >= 0 )
 
  213        rect = 
rect.translated( -scrollPos() );
 
  214        if ( 
rect.intersects( viewContentsRect() ) )
 
 
  222void QskListView::keyPressEvent( QKeyEvent* event )
 
  224    if ( m_data->selectionMode == NoSelection )
 
  226        Inherited::keyPressEvent( event );
 
  230    int row = selectedRow();
 
  232    switch ( event->key() )
 
  236            if ( row < rowCount() - 1 )
 
  243                row = rowCount() - 1;
 
  257            row = rowCount() - 1;
 
  261        case Qt::Key_PageDown:
 
  264            Inherited::keyPressEvent( event );
 
  269            Inherited::keyPressEvent( event );
 
  274    const int r = selectedRow();
 
  276    setSelectedRow( row );
 
  282        auto pos = scrollPos();
 
  284        const qreal rowPos = row * rowHeight();
 
  285        if ( rowPos < scrollPos().y() )
 
  291            const QRectF vr = viewContentsRect();
 
  293            const double scrolledBottom = scrollPos().y() + vr.height();
 
  294            if ( rowPos + rowHeight() > scrolledBottom )
 
  296                const double y = rowPos + rowHeight() - vr.height();
 
  301        if ( pos != scrollPos() )
 
  303            if ( event->isAutoRepeat() )
 
  311void QskListView::keyReleaseEvent( QKeyEvent* event )
 
  313    Inherited::keyReleaseEvent( event );
 
  316void QskListView::mousePressEvent( QMouseEvent* event )
 
  318    if ( m_data->selectionMode != NoSelection )
 
  320        const int row = qskRowAt( 
this, qskMousePosition( event ) );
 
  323            m_data->setRowState( 
this, row, Pressed );
 
  324            setSelectedRow( row );
 
  329    Inherited::mousePressEvent( event );
 
  332void QskListView::mouseReleaseEvent( QMouseEvent* event )
 
  334    m_data->setRowState( 
this, -1, Pressed );
 
  335    Inherited::mouseReleaseEvent( event );
 
  338void QskListView::mouseUngrabEvent()
 
  340    m_data->setRowState( 
this, -1, Pressed );
 
  341    Inherited::mouseUngrabEvent();
 
  344void QskListView::hoverEnterEvent( QHoverEvent* event )
 
  346    if ( m_data->selectionMode != NoSelection )
 
  348        const int row = qskRowAt( 
this, qskHoverPosition( event ) );
 
  349        m_data->setRowState( 
this, row, 
Hovered );
 
  352    Inherited::hoverEnterEvent( event );
 
  355void QskListView::hoverMoveEvent( QHoverEvent* event )
 
  357    if ( m_data->selectionMode != NoSelection )
 
  359        const int row = qskRowAt( 
this, qskHoverPosition( event ) );
 
  360        m_data->setRowState( 
this, row, 
Hovered );
 
  363    Inherited::hoverMoveEvent( event );
 
  366void QskListView::hoverLeaveEvent( QHoverEvent* event )
 
  368    m_data->setRowState( 
this, -1, 
Hovered );
 
  369    Inherited::hoverLeaveEvent( event );
 
  374    if ( event->type() == QEvent::StyleChange )
 
  375        updateScrollableSize();
 
 
  380QskAspect::States QskListView::rowStates( 
int row )
 const 
  382    auto states = skinStates();
 
  386        if ( row == m_data->selectedRow )
 
  389        if ( row == m_data->hoveredRow )
 
  392        if ( row == m_data->pressedRow )
 
  399#ifndef QT_NO_WHEELEVENT 
  401static qreal qskAlignedToRows( 
const qreal y0, qreal dy,
 
  402    qreal rowHeight, qreal viewHeight )
 
  408        y = qFloor( y / rowHeight ) * rowHeight;
 
  413        y = qCeil( y / rowHeight ) * rowHeight;
 
  420QPointF QskListView::scrollOffset( 
const QWheelEvent* event )
 const 
  424    const auto pos = qskWheelPosition( event );
 
  428        const auto steps = qskWheelSteps( event );
 
  429        offset.setY( steps );
 
  433        const auto steps = qskWheelSteps( event );
 
  434        offset.setX( steps );
 
  436    else if ( viewContentsRect().contains( pos ) )
 
  438        offset = 
event->angleDelta() / QWheelEvent::DefaultDeltasPerStep;
 
  441    if ( offset.x() != 0.0 )
 
  443        offset.rx() *= viewContentsRect().width(); 
 
  445    else if ( offset.y() != 0.0 )
 
  447        const qreal y0 = scrollPos().y();
 
  448        const auto viewHeight = viewContentsRect().height();
 
  449        const qreal rowHeight = this->rowHeight();
 
  451        const int numLines = QGuiApplication::styleHints()->wheelScrollLines();
 
  453        qreal dy = numLines * rowHeight;
 
  454        if ( event->modifiers() & ( Qt::ControlModifier | Qt::ShiftModifier ) )
 
  455            dy = qMax( dy, viewHeight );
 
  460        dy = qskAlignedToRows( y0, dy, rowHeight, viewHeight );
 
  462        offset.setY( y0 - dy );
 
  472void QskListView::updateScrollableSize()
 
  474    const double h = rowCount() * rowHeight();
 
  477    for ( 
int col = 0; col < columnCount(); col++ )
 
  478        w += columnWidth( col );
 
  480    const QSizeF sz = scrollableSize();
 
  482    setScrollableSize( QSizeF( w, h ) );
 
  484    if ( m_data->preferredWidthFromColumns &&
 
  485        sz.width() != scrollableSize().width() )
 
  491void QskListView::componentComplete()
 
  495    if ( m_data->selectedRow >= 0 )
 
  500        if ( m_data->selectedRow >= rowCount() )
 
  501            setSelectedRow( -1 );
 
  505#include "moc_QskListView.cpp" 
QRectF subControlRect(QskAspect::Subcontrol) const
void focusIndicatorRectChanged()
static const QskAspect::State Hovered
virtual QRectF focusIndicatorRect() const
QRectF contentsRect() const
virtual void changeEvent(QEvent *)
void componentComplete() override
QRectF focusIndicatorRect() const override
void changeEvent(QEvent *) override
const QskSkinlet * effectiveSkinlet() const