Merge 0e240cafb7
into 9e4e31f349
This commit is contained in:
commit
9e9b6da301
|
@ -75,6 +75,11 @@ project(QSkinny
|
||||||
HOMEPAGE_URL "https://github.com/uwerat/qskinny"
|
HOMEPAGE_URL "https://github.com/uwerat/qskinny"
|
||||||
VERSION 0.8.0)
|
VERSION 0.8.0)
|
||||||
|
|
||||||
|
if(MSVC)
|
||||||
|
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /MP")
|
||||||
|
message(STATUS "Added parallel build arguments to CMAKE_CXX_FLAGS: ${CMAKE_CXX_FLAGS}")
|
||||||
|
endif()
|
||||||
|
|
||||||
qsk_setup_options()
|
qsk_setup_options()
|
||||||
|
|
||||||
include(GNUInstallDirs)
|
include(GNUInstallDirs)
|
||||||
|
|
|
@ -3,4 +3,6 @@
|
||||||
# SPDX-License-Identifier: BSD-3-Clause
|
# SPDX-License-Identifier: BSD-3-Clause
|
||||||
############################################################################
|
############################################################################
|
||||||
|
|
||||||
qsk_add_example(listbox main.cpp)
|
qsk_add_example(listbox main.cpp
|
||||||
|
ListBox.h ListBox.cpp
|
||||||
|
TreeBox.h TreeBox.cpp)
|
||||||
|
|
|
@ -0,0 +1,44 @@
|
||||||
|
/******************************************************************************
|
||||||
|
* QSkinny - Copyright (C) 2016 Uwe Rathmann
|
||||||
|
* SPDX-License-Identifier: BSD-3-Clause
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
#include "ListBox.h"
|
||||||
|
#include <QskFunctions.h>
|
||||||
|
|
||||||
|
ListBox::ListBox( QQuickItem* parent )
|
||||||
|
: Inherited( parent )
|
||||||
|
{
|
||||||
|
setAlternatingRowColors( true );
|
||||||
|
|
||||||
|
// increasing the padding of each row: usually the job of the skin !
|
||||||
|
setPaddingHint( Cell, QMargins( 10, 20, 10, 20 ) );
|
||||||
|
|
||||||
|
populate();
|
||||||
|
|
||||||
|
setSelectedRow( 5 );
|
||||||
|
}
|
||||||
|
|
||||||
|
void ListBox::populate()
|
||||||
|
{
|
||||||
|
const int count = 10000;
|
||||||
|
|
||||||
|
const QString format( "Row %1: The quick brown fox jumps over the lazy dog" );
|
||||||
|
|
||||||
|
QStringList entries;
|
||||||
|
entries.reserve( count );
|
||||||
|
|
||||||
|
for ( int i = 0; i < count; i++ )
|
||||||
|
{
|
||||||
|
entries += format.arg( i + 1 );
|
||||||
|
}
|
||||||
|
|
||||||
|
// we know, that the last entry is the longest one and
|
||||||
|
// can prevent the list box from having to find it out
|
||||||
|
// the expensive way.
|
||||||
|
|
||||||
|
const qreal maxWidth = qskHorizontalAdvance( effectiveFont( Cell ), entries.last() );
|
||||||
|
setColumnWidthHint( 0, maxWidth );
|
||||||
|
|
||||||
|
append( entries );
|
||||||
|
}
|
|
@ -0,0 +1,17 @@
|
||||||
|
/******************************************************************************
|
||||||
|
* QSkinny - Copyright (C) 2016 Uwe Rathmann
|
||||||
|
* SPDX-License-Identifier: BSD-3-Clause
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
#include <QskSimpleListBox.h>
|
||||||
|
|
||||||
|
class ListBox : public QskSimpleListBox
|
||||||
|
{
|
||||||
|
using Inherited = QskSimpleListBox;
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit ListBox( QQuickItem* parent = nullptr );
|
||||||
|
|
||||||
|
private:
|
||||||
|
void populate();
|
||||||
|
};
|
|
@ -0,0 +1,74 @@
|
||||||
|
/******************************************************************************
|
||||||
|
* QSkinny - Copyright (C) 2016 Uwe Rathmann
|
||||||
|
* SPDX-License-Identifier: BSD-3-Clause
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
#include "TreeBox.h"
|
||||||
|
|
||||||
|
QSK_SUBCONTROL( TreeBox, FirstRow )
|
||||||
|
QSK_SUBCONTROL( TreeBox, SecondRow )
|
||||||
|
|
||||||
|
TreeBox::TreeBox( QQuickItem* const parent )
|
||||||
|
: Inherited( parent )
|
||||||
|
{
|
||||||
|
setAlternatingRowColors( true );
|
||||||
|
setPaddingHint( Cell, QMargins( 10, 20, 10, 20 ) );
|
||||||
|
|
||||||
|
setAlternatingRowColors( true );
|
||||||
|
setColor( FirstRow, Qt::white );
|
||||||
|
setColor( SecondRow, color( Panel ) );
|
||||||
|
updateScrollableSize();
|
||||||
|
};
|
||||||
|
|
||||||
|
QskAspect::Subcontrol TreeBox::rowSubControl( int row ) const noexcept
|
||||||
|
{
|
||||||
|
if ( alternatingRowColors() )
|
||||||
|
{
|
||||||
|
if ( row == selectedRow() )
|
||||||
|
{
|
||||||
|
return Cell;
|
||||||
|
}
|
||||||
|
return row % 2 == 0 ? Cell : QskAspect::NoSubcontrol;
|
||||||
|
}
|
||||||
|
return QskAspect::NoSubcontrol;
|
||||||
|
}
|
||||||
|
|
||||||
|
int TreeBox::rowCount() const
|
||||||
|
{
|
||||||
|
return 100000;
|
||||||
|
}
|
||||||
|
|
||||||
|
int TreeBox::columnCount() const
|
||||||
|
{
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
qreal TreeBox::columnWidth( int col ) const
|
||||||
|
{
|
||||||
|
return col == 0 ? 100 : 350;
|
||||||
|
}
|
||||||
|
|
||||||
|
qreal TreeBox::rowHeight() const
|
||||||
|
{
|
||||||
|
const auto hint = strutSizeHint( Cell );
|
||||||
|
const auto padding = paddingHint( Cell );
|
||||||
|
|
||||||
|
qreal h = effectiveFontHeight( Text );
|
||||||
|
h += padding.top() + padding.bottom();
|
||||||
|
|
||||||
|
return qMax( h, hint.height() );
|
||||||
|
}
|
||||||
|
|
||||||
|
Q_INVOKABLE QVariant TreeBox::valueAt( int row, int col ) const
|
||||||
|
{
|
||||||
|
if ( col == 0 )
|
||||||
|
{
|
||||||
|
return QString::number( row );
|
||||||
|
}
|
||||||
|
return QStringLiteral( "The quick brown fox jumps over the lazy dog" );
|
||||||
|
}
|
||||||
|
|
||||||
|
qreal TreeBox::rowOffset( int row ) const
|
||||||
|
{
|
||||||
|
return ( row % 4 ) * 10;
|
||||||
|
}
|
|
@ -0,0 +1,25 @@
|
||||||
|
/******************************************************************************
|
||||||
|
* QSkinny - Copyright (C) 2016 Uwe Rathmann
|
||||||
|
* SPDX-License-Identifier: BSD-3-Clause
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <QskTreeView.h>
|
||||||
|
|
||||||
|
class TreeBox final : public QskTreeView
|
||||||
|
{
|
||||||
|
using Inherited = QskTreeView;
|
||||||
|
|
||||||
|
public:
|
||||||
|
QSK_SUBCONTROLS( FirstRow, SecondRow )
|
||||||
|
|
||||||
|
explicit TreeBox( QQuickItem* parent = nullptr );
|
||||||
|
QskAspect::Subcontrol rowSubControl( int row ) const noexcept override;
|
||||||
|
int rowCount() const override;
|
||||||
|
int columnCount() const override;
|
||||||
|
qreal columnWidth( int col ) const override;
|
||||||
|
qreal rowHeight() const override;
|
||||||
|
Q_INVOKABLE QVariant valueAt( int row, int col ) const override;
|
||||||
|
qreal rowOffset( int row ) const override;
|
||||||
|
};
|
|
@ -5,56 +5,16 @@
|
||||||
|
|
||||||
#include <SkinnyShortcut.h>
|
#include <SkinnyShortcut.h>
|
||||||
|
|
||||||
#include <QskAspect.h>
|
#ifdef ITEM_STATISTICS
|
||||||
#include <QskObjectCounter.h>
|
#include <QskObjectCounter.h>
|
||||||
#include <QskSimpleListBox.h>
|
#endif
|
||||||
|
#include <QskLinearBox.h>
|
||||||
#include <QskWindow.h>
|
#include <QskWindow.h>
|
||||||
#include <QskFunctions.h>
|
|
||||||
|
|
||||||
#include <QFontMetricsF>
|
|
||||||
#include <QGuiApplication>
|
#include <QGuiApplication>
|
||||||
|
|
||||||
class ListBox : public QskSimpleListBox
|
#include "ListBox.h"
|
||||||
{
|
#include "TreeBox.h"
|
||||||
public:
|
|
||||||
ListBox()
|
|
||||||
{
|
|
||||||
setMargins( QMarginsF( 15, 10, 10, 10 ) );
|
|
||||||
setAlternatingRowColors( true );
|
|
||||||
|
|
||||||
// increasing the padding of each row: usually the job of the skin !
|
|
||||||
setPaddingHint( Cell, QMargins( 10, 20, 10, 20 ) );
|
|
||||||
|
|
||||||
populate();
|
|
||||||
|
|
||||||
setSelectedRow( 5 );
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
void populate()
|
|
||||||
{
|
|
||||||
const int count = 10000;
|
|
||||||
|
|
||||||
const QString format( "Row %1: The quick brown fox jumps over the lazy dog" );
|
|
||||||
|
|
||||||
QStringList entries;
|
|
||||||
entries.reserve( count );
|
|
||||||
|
|
||||||
for ( int i = 0; i < count; i++ )
|
|
||||||
{
|
|
||||||
entries += format.arg( i + 1 );
|
|
||||||
}
|
|
||||||
|
|
||||||
// we know, that the last entry is the longest one and
|
|
||||||
// can prevent the list box from having to find it out
|
|
||||||
// the expensive way.
|
|
||||||
|
|
||||||
const qreal maxWidth = qskHorizontalAdvance( effectiveFont( Cell ), entries.last() );
|
|
||||||
setColumnWidthHint( 0, maxWidth );
|
|
||||||
|
|
||||||
append( entries );
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
int main( int argc, char* argv[] )
|
int main( int argc, char* argv[] )
|
||||||
{
|
{
|
||||||
|
@ -69,7 +29,12 @@ int main( int argc, char* argv[] )
|
||||||
QskWindow window;
|
QskWindow window;
|
||||||
window.setColor( "Silver" );
|
window.setColor( "Silver" );
|
||||||
|
|
||||||
window.addItem( new ListBox() );
|
auto* const layout = new QskLinearBox( Qt::Horizontal );
|
||||||
|
layout->setSpacing( 8 );
|
||||||
|
( void ) new ListBox( layout );
|
||||||
|
( void ) new TreeBox( layout );
|
||||||
|
|
||||||
|
window.addItem( layout );
|
||||||
window.resize( 400, 600 );
|
window.resize( 400, 600 );
|
||||||
window.show();
|
window.show();
|
||||||
|
|
||||||
|
|
|
@ -19,6 +19,7 @@
|
||||||
#include <QskGraphicIO.h>
|
#include <QskGraphicIO.h>
|
||||||
#include <QskInputPanelBox.h>
|
#include <QskInputPanelBox.h>
|
||||||
#include <QskListView.h>
|
#include <QskListView.h>
|
||||||
|
#include <QskTreeView.h>
|
||||||
#include <QskMenu.h>
|
#include <QskMenu.h>
|
||||||
#include <QskPageIndicator.h>
|
#include <QskPageIndicator.h>
|
||||||
#include <QskPushButton.h>
|
#include <QskPushButton.h>
|
||||||
|
@ -90,6 +91,7 @@ namespace
|
||||||
void setupInputPanel();
|
void setupInputPanel();
|
||||||
void setupVirtualKeyboard();
|
void setupVirtualKeyboard();
|
||||||
void setupListView();
|
void setupListView();
|
||||||
|
void setupTreeView();
|
||||||
void setupMenu();
|
void setupMenu();
|
||||||
void setupPageIndicator();
|
void setupPageIndicator();
|
||||||
void setupPopup();
|
void setupPopup();
|
||||||
|
@ -157,6 +159,7 @@ void Editor::setup()
|
||||||
setupInputPanel();
|
setupInputPanel();
|
||||||
setupVirtualKeyboard();
|
setupVirtualKeyboard();
|
||||||
setupListView();
|
setupListView();
|
||||||
|
setupTreeView();
|
||||||
setupMenu();
|
setupMenu();
|
||||||
setupPageIndicator();
|
setupPageIndicator();
|
||||||
setupPopup();
|
setupPopup();
|
||||||
|
@ -1144,7 +1147,20 @@ void Editor::setupListView()
|
||||||
using Q = QskListView;
|
using Q = QskListView;
|
||||||
|
|
||||||
setPadding( Q::Cell, { 16_dp, 12_dp, 16_dp, 12_dp } );
|
setPadding( Q::Cell, { 16_dp, 12_dp, 16_dp, 12_dp } );
|
||||||
setBoxBorderMetrics( Q::Cell, { 0, 0, 0, 1_dp } );
|
setBoxBorderMetrics( Q::Cell, { 0, 1_dp, 0, 1_dp } );
|
||||||
|
setBoxBorderColors( Q::Cell, m_pal.outline );
|
||||||
|
setColor( Q::Cell, m_pal.surface );
|
||||||
|
setColor( Q::Cell | Q::Selected, m_pal.primary12 );
|
||||||
|
|
||||||
|
setColor( Q::Text, m_pal.onSurfaceVariant );
|
||||||
|
}
|
||||||
|
|
||||||
|
void Editor::setupTreeView()
|
||||||
|
{
|
||||||
|
using Q = QskTreeView;
|
||||||
|
|
||||||
|
setPadding( Q::Cell, { 16_dp, 12_dp, 16_dp, 12_dp } );
|
||||||
|
setBoxBorderMetrics( Q::Cell, { 0, 1_dp, 0, 1_dp } );
|
||||||
setBoxBorderColors( Q::Cell, m_pal.outline );
|
setBoxBorderColors( Q::Cell, m_pal.outline );
|
||||||
setColor( Q::Cell, m_pal.surface );
|
setColor( Q::Cell, m_pal.surface );
|
||||||
setColor( Q::Cell | Q::Selected, m_pal.primary12 );
|
setColor( Q::Cell | Q::Selected, m_pal.primary12 );
|
||||||
|
|
|
@ -16,6 +16,7 @@
|
||||||
#include <QskInputPanelBox.h>
|
#include <QskInputPanelBox.h>
|
||||||
#include <QskInputPredictionBar.h>
|
#include <QskInputPredictionBar.h>
|
||||||
#include <QskListView.h>
|
#include <QskListView.h>
|
||||||
|
#include <QskTreeView.h>
|
||||||
#include <QskMenu.h>
|
#include <QskMenu.h>
|
||||||
#include <QskPageIndicator.h>
|
#include <QskPageIndicator.h>
|
||||||
#include <QskPopup.h>
|
#include <QskPopup.h>
|
||||||
|
@ -158,6 +159,7 @@ namespace
|
||||||
void setupInputPredictionBar();
|
void setupInputPredictionBar();
|
||||||
void setupVirtualKeyboard();
|
void setupVirtualKeyboard();
|
||||||
void setupListView();
|
void setupListView();
|
||||||
|
void setupTreeView();
|
||||||
void setupMenu();
|
void setupMenu();
|
||||||
void setupPageIndicator();
|
void setupPageIndicator();
|
||||||
void setupPopup();
|
void setupPopup();
|
||||||
|
@ -283,6 +285,7 @@ void Editor::setup()
|
||||||
setupInputPredictionBar();
|
setupInputPredictionBar();
|
||||||
setupVirtualKeyboard();
|
setupVirtualKeyboard();
|
||||||
setupListView();
|
setupListView();
|
||||||
|
setupTreeView();
|
||||||
setupMenu();
|
setupMenu();
|
||||||
setupPageIndicator();
|
setupPageIndicator();
|
||||||
setupPopup();
|
setupPopup();
|
||||||
|
@ -1056,6 +1059,20 @@ void Editor::setupListView()
|
||||||
setColor( Q::Text | Q::Selected, m_pal.highlightedText );
|
setColor( Q::Text | Q::Selected, m_pal.highlightedText );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Editor::setupTreeView()
|
||||||
|
{
|
||||||
|
using Q = QskTreeView;
|
||||||
|
|
||||||
|
// padding for each cell
|
||||||
|
setPadding( Q::Cell, QskMargins( 4, 8 ) );
|
||||||
|
|
||||||
|
setColor( Q::Text, m_pal.themeForeground );
|
||||||
|
setColor( Q::Cell, m_pal.contrasted );
|
||||||
|
|
||||||
|
setColor( Q::Cell | Q::Selected, m_pal.highlighted );
|
||||||
|
setColor( Q::Text | Q::Selected, m_pal.highlightedText );
|
||||||
|
}
|
||||||
|
|
||||||
void Editor::setupSubWindow()
|
void Editor::setupSubWindow()
|
||||||
{
|
{
|
||||||
using A = QskAspect;
|
using A = QskAspect;
|
||||||
|
|
|
@ -188,6 +188,8 @@ list(APPEND HEADERS
|
||||||
controls/QskInputGrabber.h
|
controls/QskInputGrabber.h
|
||||||
controls/QskListView.h
|
controls/QskListView.h
|
||||||
controls/QskListViewSkinlet.h
|
controls/QskListViewSkinlet.h
|
||||||
|
controls/QskTreeView.h
|
||||||
|
controls/QskTreeViewSkinlet.h
|
||||||
controls/QskMenu.h
|
controls/QskMenu.h
|
||||||
controls/QskMenuSkinlet.h
|
controls/QskMenuSkinlet.h
|
||||||
controls/QskObjectTree.h
|
controls/QskObjectTree.h
|
||||||
|
@ -286,6 +288,8 @@ list(APPEND SOURCES
|
||||||
controls/QskInputGrabber.cpp
|
controls/QskInputGrabber.cpp
|
||||||
controls/QskListView.cpp
|
controls/QskListView.cpp
|
||||||
controls/QskListViewSkinlet.cpp
|
controls/QskListViewSkinlet.cpp
|
||||||
|
controls/QskTreeView.cpp
|
||||||
|
controls/QskTreeViewSkinlet.cpp
|
||||||
controls/QskMenuSkinlet.cpp
|
controls/QskMenuSkinlet.cpp
|
||||||
controls/QskMenu.cpp
|
controls/QskMenu.cpp
|
||||||
controls/QskObjectTree.cpp
|
controls/QskObjectTree.cpp
|
||||||
|
|
|
@ -151,6 +151,31 @@ QskColorFilter QskListView::graphicFilterAt( int row, int col ) const
|
||||||
return QskColorFilter();
|
return QskColorFilter();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QskAspect::Subcontrol QskListView::rowSubControl( int row ) const noexcept
|
||||||
|
{
|
||||||
|
if ( alternatingRowColors() )
|
||||||
|
{
|
||||||
|
if ( row == selectedRow() )
|
||||||
|
{
|
||||||
|
return Cell;
|
||||||
|
}
|
||||||
|
return row % 2 == 0 ? Cell : QskAspect::NoSubcontrol;
|
||||||
|
}
|
||||||
|
return QskAspect::NoSubcontrol;
|
||||||
|
}
|
||||||
|
|
||||||
|
QskAspect::Subcontrol QskListView::cellSubControl( int row, int col ) const noexcept
|
||||||
|
{
|
||||||
|
Q_UNUSED(row);
|
||||||
|
Q_UNUSED(col);
|
||||||
|
return Cell;
|
||||||
|
}
|
||||||
|
|
||||||
|
QskAspect::Subcontrol QskListView::textSubControl( int row, int col ) const noexcept
|
||||||
|
{
|
||||||
|
return Text;
|
||||||
|
}
|
||||||
|
|
||||||
void QskListView::keyPressEvent( QKeyEvent* event )
|
void QskListView::keyPressEvent( QKeyEvent* event )
|
||||||
{
|
{
|
||||||
if ( m_data->selectionMode == NoSelection )
|
if ( m_data->selectionMode == NoSelection )
|
||||||
|
@ -374,4 +399,10 @@ void QskListView::componentComplete()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
qreal QskListView::rowOffset( int row ) const
|
||||||
|
{
|
||||||
|
Q_UNUSED(row);
|
||||||
|
return 0.0;
|
||||||
|
}
|
||||||
|
|
||||||
#include "moc_QskListView.cpp"
|
#include "moc_QskListView.cpp"
|
||||||
|
|
|
@ -64,6 +64,7 @@ class QSK_EXPORT QskListView : public QskScrollView
|
||||||
|
|
||||||
virtual qreal columnWidth( int col ) const = 0;
|
virtual qreal columnWidth( int col ) const = 0;
|
||||||
virtual qreal rowHeight() const = 0;
|
virtual qreal rowHeight() const = 0;
|
||||||
|
virtual qreal rowOffset( int row ) const;
|
||||||
|
|
||||||
Q_INVOKABLE virtual QVariant valueAt( int row, int col ) const = 0;
|
Q_INVOKABLE virtual QVariant valueAt( int row, int col ) const = 0;
|
||||||
|
|
||||||
|
@ -71,6 +72,10 @@ class QSK_EXPORT QskListView : public QskScrollView
|
||||||
virtual QskColorFilter graphicFilterAt( int row, int col ) const;
|
virtual QskColorFilter graphicFilterAt( int row, int col ) const;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
virtual QskAspect::Subcontrol rowSubControl( int row ) const noexcept;
|
||||||
|
virtual QskAspect::Subcontrol cellSubControl( int row, int col ) const noexcept;
|
||||||
|
virtual QskAspect::Subcontrol textSubControl( int row, int col ) const noexcept;
|
||||||
|
|
||||||
public Q_SLOTS:
|
public Q_SLOTS:
|
||||||
void setSelectedRow( int row );
|
void setSelectedRow( int row );
|
||||||
|
|
||||||
|
|
|
@ -110,6 +110,48 @@ QSGNode* QskListViewSkinlet::updateContentsNode(
|
||||||
return listViewNode;
|
return listViewNode;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void QskListViewSkinlet::updateBackgroundNode( const QskListView* listView, QSGNode* rowNode, const QRectF& boxRect, const int row ) const
|
||||||
|
{
|
||||||
|
const auto selectedRow = listView->selectedRow();
|
||||||
|
const auto subControl = listView->rowSubControl( row );
|
||||||
|
|
||||||
|
// current row is a selected row
|
||||||
|
if ( row == selectedRow )
|
||||||
|
{
|
||||||
|
auto* boxNode = rowNode->firstChild();
|
||||||
|
auto prepend = boxNode == nullptr;
|
||||||
|
|
||||||
|
QskSkinStateChanger stateChanger( listView );
|
||||||
|
stateChanger.setStates( listView->skinStates() | QskListView::Selected );
|
||||||
|
boxNode = updateBoxNode( listView, boxNode, boxRect, subControl );
|
||||||
|
|
||||||
|
if ( boxNode && prepend )
|
||||||
|
{
|
||||||
|
rowNode->prependChildNode( boxNode );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// current row should be styled
|
||||||
|
else if ( subControl != QskAspect::NoSubcontrol)
|
||||||
|
{
|
||||||
|
auto* boxNode = rowNode->firstChild();
|
||||||
|
auto prepend = boxNode == nullptr;
|
||||||
|
|
||||||
|
const auto gradient = listView->gradientHint(subControl);
|
||||||
|
|
||||||
|
boxNode = updateBoxNode( listView, boxNode, boxRect, subControl );
|
||||||
|
|
||||||
|
if ( boxNode && prepend )
|
||||||
|
{
|
||||||
|
rowNode->prependChildNode( boxNode );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// current row should not be styled
|
||||||
|
else
|
||||||
|
{
|
||||||
|
rowNode->removeAllChildNodes();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void QskListViewSkinlet::updateBackgroundNodes(
|
void QskListViewSkinlet::updateBackgroundNodes(
|
||||||
const QskListView* listView, QskListViewNode* listViewNode ) const
|
const QskListView* listView, QskListViewNode* listViewNode ) const
|
||||||
{
|
{
|
||||||
|
@ -125,57 +167,29 @@ void QskListViewSkinlet::updateBackgroundNodes(
|
||||||
if ( rowMax >= listView->rowCount() )
|
if ( rowMax >= listView->rowCount() )
|
||||||
rowMax = listView->rowCount() - 1;
|
rowMax = listView->rowCount() - 1;
|
||||||
|
|
||||||
const int rowSelected = listView->selectedRow();
|
const double x0 = viewRect.left();
|
||||||
const double x0 = viewRect.left() + scrolledPos.x();
|
|
||||||
const double y0 = viewRect.top();
|
const double y0 = viewRect.top();
|
||||||
|
|
||||||
auto* rowNode = static_cast< QSGSimpleRectNode* >( backgroundNode->firstChild() );
|
auto* rowNode = static_cast< QSGNode* >( backgroundNode->firstChild() );
|
||||||
|
|
||||||
if ( listView->alternatingRowColors() )
|
if ( listView->alternatingRowColors() )
|
||||||
{
|
{
|
||||||
#if 1
|
|
||||||
/*
|
|
||||||
Cell might be better for regular cells, while ( Cell | AlternateColor )
|
|
||||||
could be used for the alternate color TODO ...
|
|
||||||
*/
|
|
||||||
#endif
|
|
||||||
const auto color = listView->color( QskListView::Cell );
|
|
||||||
|
|
||||||
for ( int row = rowMin; row <= rowMax; row++ )
|
for ( int row = rowMin; row <= rowMax; row++ )
|
||||||
{
|
{
|
||||||
if ( row % 2 )
|
const auto offsetX = listView->rowOffset( row );
|
||||||
{
|
const QRectF boxRect{ x0 + offsetX, y0 + row * cellHeight, viewRect.width() - offsetX + scrolledPos.x(),
|
||||||
if ( rowNode == nullptr )
|
cellHeight };
|
||||||
{
|
|
||||||
rowNode = new QSGSimpleRectNode();
|
|
||||||
backgroundNode->appendChildNode( rowNode );
|
|
||||||
}
|
|
||||||
|
|
||||||
rowNode->setRect( x0, y0 + row * cellHeight, viewRect.width(), cellHeight );
|
|
||||||
rowNode->setColor( color );
|
|
||||||
|
|
||||||
rowNode = static_cast< QSGSimpleRectNode* >( rowNode->nextSibling() );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( rowSelected >= rowMin && rowSelected <= rowMax )
|
|
||||||
{
|
|
||||||
QskSkinStateChanger stateChanger( listView );
|
|
||||||
stateChanger.setStates( listView->skinStates() | QskListView::Selected );
|
|
||||||
|
|
||||||
const QColor color = listView->color( QskListView::Cell );
|
|
||||||
|
|
||||||
if ( rowNode == nullptr )
|
if ( rowNode == nullptr )
|
||||||
{
|
{
|
||||||
rowNode = new QSGSimpleRectNode();
|
rowNode = new QSGNode;
|
||||||
|
updateBackgroundNode( listView, rowNode, boxRect, row );
|
||||||
backgroundNode->appendChildNode( rowNode );
|
backgroundNode->appendChildNode( rowNode );
|
||||||
}
|
}
|
||||||
|
|
||||||
rowNode->setRect( x0, y0 + rowSelected * cellHeight, viewRect.width(), cellHeight );
|
updateBackgroundNode( listView, rowNode, boxRect, row );
|
||||||
rowNode->setColor( color );
|
rowNode = rowNode->nextSibling();
|
||||||
|
}
|
||||||
rowNode = static_cast< QSGSimpleRectNode* >( rowNode->nextSibling() );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
QSGNode* nextNode = rowNode;
|
QSGNode* nextNode = rowNode;
|
||||||
|
@ -199,7 +213,8 @@ void QskListViewSkinlet::updateForegroundNodes(
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto margins = listView->paddingHint( QskListView::Cell );
|
const auto subControl = listView->rowSubControl(0);
|
||||||
|
const auto margins = listView->paddingHint( subControl );
|
||||||
|
|
||||||
const auto cr = listView->viewContentsRect();
|
const auto cr = listView->viewContentsRect();
|
||||||
const auto scrolledPos = listView->scrollPos();
|
const auto scrolledPos = listView->scrollPos();
|
||||||
|
@ -255,8 +270,8 @@ void QskListViewSkinlet::updateForegroundNodes(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
updateVisibleForegroundNodes( listView, listViewNode,
|
updateVisibleForegroundNodes(
|
||||||
rowMin, rowMax, colMin, colMax, margins, forwards );
|
listView, listViewNode, rowMin, rowMax, colMin, colMax, margins, forwards );
|
||||||
|
|
||||||
// finally putting the nodes into their position
|
// finally putting the nodes into their position
|
||||||
auto node = parentNode->firstChild();
|
auto node = parentNode->firstChild();
|
||||||
|
@ -272,9 +287,10 @@ void QskListViewSkinlet::updateForegroundNodes(
|
||||||
{
|
{
|
||||||
Q_ASSERT( node->type() == QSGNode::TransformNodeType );
|
Q_ASSERT( node->type() == QSGNode::TransformNodeType );
|
||||||
auto transformNode = static_cast< QSGTransformNode* >( node );
|
auto transformNode = static_cast< QSGTransformNode* >( node );
|
||||||
|
const auto offsetX = col == 0 ? listView->rowOffset( row ) : 0.0;
|
||||||
|
|
||||||
QTransform transform;
|
QTransform transform;
|
||||||
transform.translate( x + margins.left(), y + margins.top() );
|
transform.translate( x + margins.left() + offsetX, y + margins.top() );
|
||||||
|
|
||||||
transformNode->setMatrix( transform );
|
transformNode->setMatrix( transform );
|
||||||
|
|
||||||
|
@ -288,10 +304,9 @@ void QskListViewSkinlet::updateForegroundNodes(
|
||||||
listViewNode->resetRows( rowMin, rowMax );
|
listViewNode->resetRows( rowMin, rowMax );
|
||||||
}
|
}
|
||||||
|
|
||||||
void QskListViewSkinlet::updateVisibleForegroundNodes(
|
void QskListViewSkinlet::updateVisibleForegroundNodes( const QskListView* listView,
|
||||||
const QskListView* listView, QskListViewNode* listViewNode,
|
QskListViewNode* listViewNode, int rowMin, int rowMax, int colMin, int colMax,
|
||||||
int rowMin, int rowMax, int colMin, int colMax, const QMarginsF& margins,
|
const QMarginsF& margins, bool forward ) const
|
||||||
bool forward ) const
|
|
||||||
{
|
{
|
||||||
auto parentNode = listViewNode->foregroundNode();
|
auto parentNode = listViewNode->foregroundNode();
|
||||||
|
|
||||||
|
@ -312,11 +327,12 @@ void QskListViewSkinlet::updateVisibleForegroundNodes(
|
||||||
|
|
||||||
for ( int col = 0; col < listView->columnCount(); col++ )
|
for ( int col = 0; col < listView->columnCount(); col++ )
|
||||||
{
|
{
|
||||||
const qreal w = listView->columnWidth( col ) - ( margins.left() + margins.right() );
|
const auto offsetX = col == 0 ? listView->rowOffset( row ) : 0.0;
|
||||||
|
const qreal w =
|
||||||
|
listView->columnWidth( col ) - ( margins.left() + margins.right() ) - offsetX;
|
||||||
|
|
||||||
node = updateForegroundNode( listView,
|
node = updateForegroundNode( listView, parentNode,
|
||||||
parentNode, static_cast< QSGTransformNode* >( node ),
|
static_cast< QSGTransformNode* >( node ), row, col, QSizeF( w, h ), forward );
|
||||||
row, col, QSizeF( w, h ), forward );
|
|
||||||
|
|
||||||
node = node->nextSibling();
|
node = node->nextSibling();
|
||||||
}
|
}
|
||||||
|
@ -335,11 +351,12 @@ void QskListViewSkinlet::updateVisibleForegroundNodes(
|
||||||
|
|
||||||
for ( int col = listView->columnCount() - 1; col >= 0; col-- )
|
for ( int col = listView->columnCount() - 1; col >= 0; col-- )
|
||||||
{
|
{
|
||||||
const qreal w = listView->columnWidth( col ) - ( margins.left() + margins.right() );
|
const auto offsetX = col == 0 ? listView->rowOffset( row ) : 0.0;
|
||||||
|
const qreal w =
|
||||||
|
listView->columnWidth( col ) - ( margins.left() + margins.right() ) - offsetX;
|
||||||
|
|
||||||
node = updateForegroundNode( listView,
|
node = updateForegroundNode( listView, parentNode,
|
||||||
parentNode, static_cast< QSGTransformNode* >( node ),
|
static_cast< QSGTransformNode* >( node ), row, col, QSizeF( w, h ), forward );
|
||||||
row, col, QSizeF( w, h ), forward );
|
|
||||||
|
|
||||||
node = node->previousSibling();
|
node = node->previousSibling();
|
||||||
}
|
}
|
||||||
|
@ -347,9 +364,9 @@ void QskListViewSkinlet::updateVisibleForegroundNodes(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
QSGTransformNode* QskListViewSkinlet::updateForegroundNode(
|
QSGTransformNode* QskListViewSkinlet::updateForegroundNode( const QskListView* listView,
|
||||||
const QskListView* listView, QSGNode* parentNode, QSGTransformNode* cellNode,
|
QSGNode* parentNode, QSGTransformNode* cellNode, int row, int col, const QSizeF& size,
|
||||||
int row, int col, const QSizeF& size, bool forward ) const
|
bool forward ) const
|
||||||
{
|
{
|
||||||
const QRectF cellRect( 0.0, 0.0, size.width(), size.height() );
|
const QRectF cellRect( 0.0, 0.0, size.width(), size.height() );
|
||||||
|
|
||||||
|
@ -431,8 +448,8 @@ QSGTransformNode* QskListViewSkinlet::updateForegroundNode(
|
||||||
return newCellNode;
|
return newCellNode;
|
||||||
}
|
}
|
||||||
|
|
||||||
QSGNode* QskListViewSkinlet::updateCellNode( const QskListView* listView,
|
QSGNode* QskListViewSkinlet::updateCellNode(
|
||||||
QSGNode* contentNode, const QRectF& rect, int row, int col ) const
|
const QskListView* listView, QSGNode* contentNode, const QRectF& rect, int row, int col ) const
|
||||||
{
|
{
|
||||||
using namespace QskSGNode;
|
using namespace QskSGNode;
|
||||||
|
|
||||||
|
@ -452,8 +469,10 @@ QSGNode* QskListViewSkinlet::updateCellNode( const QskListView* listView,
|
||||||
public API of QskListView TODO ...
|
public API of QskListView TODO ...
|
||||||
*/
|
*/
|
||||||
#endif
|
#endif
|
||||||
const auto alignment = listView->alignmentHint(
|
|
||||||
QskListView::Cell, Qt::AlignVCenter | Qt::AlignLeft );
|
const auto subControl = listView->cellSubControl(row, col);
|
||||||
|
const auto alignment =
|
||||||
|
listView->alignmentHint( subControl, Qt::AlignVCenter | Qt::AlignLeft );
|
||||||
|
|
||||||
const auto value = listView->valueAt( row, col );
|
const auto value = listView->valueAt( row, col );
|
||||||
|
|
||||||
|
@ -464,8 +483,8 @@ QSGNode* QskListViewSkinlet::updateCellNode( const QskListView* listView,
|
||||||
|
|
||||||
const auto colorFilter = listView->graphicFilterAt( row, col );
|
const auto colorFilter = listView->graphicFilterAt( row, col );
|
||||||
|
|
||||||
newNode = updateGraphicNode( listView, newNode,
|
newNode = updateGraphicNode(
|
||||||
value.value< QskGraphic >(), colorFilter, rect, alignment );
|
listView, newNode, value.value< QskGraphic >(), colorFilter, rect, alignment );
|
||||||
|
|
||||||
if ( newNode )
|
if ( newNode )
|
||||||
setNodeRole( newNode, GraphicRole );
|
setNodeRole( newNode, GraphicRole );
|
||||||
|
@ -475,8 +494,10 @@ QSGNode* QskListViewSkinlet::updateCellNode( const QskListView* listView,
|
||||||
if ( nodeRole( contentNode ) == TextRole )
|
if ( nodeRole( contentNode ) == TextRole )
|
||||||
newNode = contentNode;
|
newNode = contentNode;
|
||||||
|
|
||||||
newNode = updateTextNode( listView, newNode, rect, alignment,
|
const auto subControl = listView->textSubControl( row, col );
|
||||||
value.toString(), QskListView::Text );
|
const auto alignment = listView->alignmentHint( subControl );
|
||||||
|
newNode =
|
||||||
|
updateTextNode( listView, newNode, rect, alignment, value.toString(), subControl );
|
||||||
|
|
||||||
if ( newNode )
|
if ( newNode )
|
||||||
setNodeRole( newNode, TextRole );
|
setNodeRole( newNode, TextRole );
|
||||||
|
@ -489,8 +510,8 @@ QSGNode* QskListViewSkinlet::updateCellNode( const QskListView* listView,
|
||||||
return newNode;
|
return newNode;
|
||||||
}
|
}
|
||||||
|
|
||||||
QSizeF QskListViewSkinlet::sizeHint( const QskSkinnable* skinnable,
|
QSizeF QskListViewSkinlet::sizeHint(
|
||||||
Qt::SizeHint which, const QSizeF& ) const
|
const QskSkinnable* skinnable, Qt::SizeHint which, const QSizeF& ) const
|
||||||
{
|
{
|
||||||
const auto listView = static_cast< const QskListView* >( skinnable );
|
const auto listView = static_cast< const QskListView* >( skinnable );
|
||||||
|
|
||||||
|
|
|
@ -44,6 +44,7 @@ class QSK_EXPORT QskListViewSkinlet : public QskScrollViewSkinlet
|
||||||
virtual QSGNode* updateCellNode( const QskListView*,
|
virtual QSGNode* updateCellNode( const QskListView*,
|
||||||
QSGNode*, const QRectF&, int row, int col ) const;
|
QSGNode*, const QRectF&, int row, int col ) const;
|
||||||
|
|
||||||
|
virtual void updateBackgroundNode( const QskListView* listView, QSGNode* rowNode, const QRectF& boxRect, const int row ) const;
|
||||||
private:
|
private:
|
||||||
void updateForegroundNodes( const QskListView*, QskListViewNode* ) const;
|
void updateForegroundNodes( const QskListView*, QskListViewNode* ) const;
|
||||||
void updateBackgroundNodes( const QskListView*, QskListViewNode* ) const;
|
void updateBackgroundNodes( const QskListView*, QskListViewNode* ) const;
|
||||||
|
|
|
@ -0,0 +1,16 @@
|
||||||
|
/******************************************************************************
|
||||||
|
* QSkinny - Copyright (C) 2016 Uwe Rathmann
|
||||||
|
* SPDX-License-Identifier: BSD-3-Clause
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
#include "QskTreeView.h"
|
||||||
|
|
||||||
|
QSK_SUBCONTROL( QskTreeView, Cell )
|
||||||
|
QSK_SUBCONTROL( QskTreeView, Text )
|
||||||
|
|
||||||
|
QskTreeView::QskTreeView( QQuickItem* const parent )
|
||||||
|
: Inherited( parent )
|
||||||
|
{
|
||||||
|
setSubcontrolProxy( Inherited::Cell, Cell );
|
||||||
|
setSubcontrolProxy( Inherited::Text, Text );
|
||||||
|
}
|
|
@ -0,0 +1,18 @@
|
||||||
|
/******************************************************************************
|
||||||
|
* QSkinny - Copyright (C) 2016 Uwe Rathmann
|
||||||
|
* SPDX-License-Identifier: BSD-3-Clause
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <QskListView.h>
|
||||||
|
|
||||||
|
class QSK_EXPORT QskTreeView : public QskListView
|
||||||
|
{
|
||||||
|
using Inherited = QskListView;
|
||||||
|
|
||||||
|
public:
|
||||||
|
QSK_SUBCONTROLS( Cell, Text )
|
||||||
|
|
||||||
|
explicit QskTreeView( QQuickItem* const parent = nullptr );
|
||||||
|
};
|
|
@ -0,0 +1,13 @@
|
||||||
|
/******************************************************************************
|
||||||
|
* QSkinny - Copyright (C) 2016 Uwe Rathmann
|
||||||
|
* SPDX-License-Identifier: BSD-3-Clause
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
#include "QskTreeViewSkinlet.h"
|
||||||
|
|
||||||
|
QskTreeViewSkinlet::QskTreeViewSkinlet( QskSkin* skin )
|
||||||
|
: Inherited( skin )
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
#include "moc_QskTreeViewSkinlet.cpp"
|
|
@ -0,0 +1,21 @@
|
||||||
|
/******************************************************************************
|
||||||
|
* QSkinny - Copyright (C) 2016 Uwe Rathmann
|
||||||
|
* SPDX-License-Identifier: BSD-3-Clause
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
#ifndef QSK_TREE_VIEW_SKINLET_H
|
||||||
|
#define QSK_TREE_VIEW_SKINLET_H
|
||||||
|
|
||||||
|
#include "QskListViewSkinlet.h"
|
||||||
|
|
||||||
|
class QSK_EXPORT QskTreeViewSkinlet : public QskListViewSkinlet
|
||||||
|
{
|
||||||
|
Q_GADGET
|
||||||
|
|
||||||
|
using Inherited = QskListViewSkinlet;
|
||||||
|
|
||||||
|
public:
|
||||||
|
Q_INVOKABLE QskTreeViewSkinlet( QskSkin* = nullptr );
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
Loading…
Reference in New Issue