qskinny/src/controls/QskListView.cpp

307 lines
6.6 KiB
C++
Raw Normal View History

2017-07-21 18:21:34 +02:00
/******************************************************************************
* QSkinny - Copyright (C) 2016 Uwe Rathmann
* This file may be used under the terms of the QSkinny License, Version 1.0
*****************************************************************************/
#include "QskListView.h"
#include "QskColorFilter.h"
#include "QskAspect.h"
QSK_SUBCONTROL( QskListView, Cell )
QSK_SUBCONTROL( QskListView, Text )
QSK_SUBCONTROL( QskListView, CellSelected )
QSK_SUBCONTROL( QskListView, TextSelected )
class QskListView::PrivateData
{
public:
PrivateData():
preferredWidthFromColumns( false ),
alternatingRowColors( false ),
selectionMode( QskListView::SingleSelection ),
selectedRow( -1 )
{
}
QskTextOptions textOptions;
bool preferredWidthFromColumns : 1;
bool alternatingRowColors : 1;
SelectionMode selectionMode : 4;
int selectedRow;
};
QskListView::QskListView( QQuickItem* parent ):
QskScrollView( parent ),
m_data( new PrivateData() )
{
}
QskListView::~QskListView()
{
}
void QskListView::setPreferredWidthFromColumns( bool on )
{
if ( on != m_data->preferredWidthFromColumns )
{
m_data->preferredWidthFromColumns = on;
resetImplicitSize();
2017-10-30 08:33:43 +01:00
Q_EMIT preferredWidthFromColumnsChanged();
2017-07-21 18:21:34 +02:00
}
}
bool QskListView::preferredWidthFromColumns() const
{
return m_data->preferredWidthFromColumns;
}
void QskListView::setAlternatingRowColors( bool on )
{
if ( on != m_data->alternatingRowColors )
{
m_data->alternatingRowColors = on;
update();
Q_EMIT alternatingRowColorsChanged();
}
}
bool QskListView::alternatingRowColors() const
{
return m_data->alternatingRowColors;
}
2017-10-20 13:31:55 +02:00
void QskListView::setTextOptions( const QskTextOptions& textOptions )
2017-07-21 18:21:34 +02:00
{
if ( textOptions != m_data->textOptions )
{
m_data->textOptions = textOptions;
updateScrollableSize();
Q_EMIT textOptionsChanged();
}
}
QskTextOptions QskListView::textOptions() const
{
return m_data->textOptions;
}
void QskListView::setSelectedRow( int row )
{
if ( row < 0 )
row = -1;
if ( row >= rowCount() )
{
if ( !isComponentComplete() )
{
// when being called from Qml we delay the checks until
// componentComplete
}
else
{
if ( row >= rowCount() )
row = -1;
}
}
if ( row != m_data->selectedRow )
{
m_data->selectedRow = row;
Q_EMIT selectedRowChanged( row );
update();
}
}
int QskListView::selectedRow() const
{
return m_data->selectedRow;
}
void QskListView::setSelectionMode( SelectionMode mode )
{
if ( mode != m_data->selectionMode )
{
m_data->selectionMode = mode;
if ( m_data->selectionMode == NoSelection )
setSelectedRow( -1 );
Q_EMIT selectionModeChanged();
}
}
QskListView::SelectionMode QskListView::selectionMode() const
{
return m_data->selectionMode;
}
QskColorFilter QskListView::graphicFilterAt( int row, int col ) const
{
Q_UNUSED( row );
Q_UNUSED( col );
return QskColorFilter();
}
QskAspect::Subcontrol QskListView::textSubControlAt( int row, int col ) const
{
Q_UNUSED( col );
return ( row == selectedRow() ) ? TextSelected : Text;
}
QSizeF QskListView::contentsSizeHint() const
{
qreal w = -1.0; // shouldn't we return something ???
if ( m_data->preferredWidthFromColumns )
{
w = scrollableSize().width();
w += metric( QskScrollView::VerticalScrollBar );
}
return QSizeF( w, -1.0 );
}
void QskListView::keyPressEvent( QKeyEvent* event )
{
if ( m_data->selectionMode == NoSelection )
2017-11-21 09:05:09 +01:00
{
Inherited::keyPressEvent( event );
2017-07-21 18:21:34 +02:00
return;
2017-11-21 09:05:09 +01:00
}
2017-07-21 18:21:34 +02:00
int row = selectedRow();
2017-10-18 20:00:06 +02:00
2017-07-21 18:21:34 +02:00
switch ( event->key() )
{
case Qt::Key_Down:
{
if ( row < rowCount() - 1 )
row++;
break;
}
case Qt::Key_Up:
{
if ( row == -1 )
row = rowCount() - 1;
if ( row != 0 )
row--;
break;
}
case Qt::Key_Home:
{
row = 0;
break;
}
case Qt::Key_End:
{
row = rowCount() - 1;
break;
}
case Qt::Key_PageUp:
case Qt::Key_PageDown:
{
// TODO ...
2017-11-21 09:05:09 +01:00
return Inherited::keyPressEvent( event );
2017-07-21 18:21:34 +02:00
}
default:
{
2017-11-21 09:05:09 +01:00
return Inherited::keyPressEvent( event );
2017-07-21 18:21:34 +02:00
}
}
const int r = selectedRow();
setSelectedRow( row );
row = selectedRow();
if ( row != r )
{
2017-12-07 17:12:52 +01:00
const qreal rowPos = row * rowHeight();
2017-07-21 18:21:34 +02:00
if ( rowPos < scrollPos().y() )
{
setScrollPos( QPointF( scrollPos().x(), rowPos ) );
}
else
{
const QRectF vr = viewContentsRect();
const double scrolledBottom = scrollPos().y() + vr.height();
if ( rowPos + rowHeight() > scrolledBottom )
{
const double y = rowPos + rowHeight() - vr.height();
setScrollPos( QPointF( scrollPos().x(), y ) );
}
}
}
}
void QskListView::keyReleaseEvent( QKeyEvent* event )
{
Inherited::keyReleaseEvent( event );
}
void QskListView::mousePressEvent( QMouseEvent* event )
{
if ( m_data->selectionMode != NoSelection )
{
const QRectF vr = viewContentsRect();
if ( vr.contains( event->pos() ) )
{
const int row = ( event->pos().y() - vr.top() + scrollPos().y() ) / rowHeight();
if ( row >= 0 && row < rowCount() )
setSelectedRow( row );
2017-10-25 17:10:50 +02:00
return;
2017-07-21 18:21:34 +02:00
}
}
2017-10-25 17:10:50 +02:00
Inherited::mousePressEvent( event );
2017-07-21 18:21:34 +02:00
}
void QskListView::mouseReleaseEvent( QMouseEvent* event )
{
Inherited::mouseReleaseEvent( event );
}
void QskListView::updateScrollableSize()
{
const double h = rowCount() * rowHeight();
2017-12-07 17:12:52 +01:00
qreal w = 0.0;
2017-07-21 18:21:34 +02:00
for ( int col = 0; col < columnCount(); col++ )
w += columnWidth( col );
const QSizeF sz = scrollableSize();
2017-12-07 17:12:52 +01:00
setScrollableSize( QSizeF( w, h ) );
2017-07-21 18:21:34 +02:00
if ( m_data->preferredWidthFromColumns &&
sz.width() != scrollableSize().width() )
{
resetImplicitSize();
}
}
void QskListView::componentComplete()
{
Inherited::componentComplete();
if ( m_data->selectedRow >= 0 )
{
// during Qml instantiation we might have set an invalid
// row selection
if ( m_data->selectedRow >= rowCount() )
setSelectedRow( -1 );
}
}
#include "moc_QskListView.cpp"