This commit is contained in:
Rick Vogel 2023-06-03 05:14:13 -07:00 committed by GitHub
commit 9e9b6da301
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
18 changed files with 413 additions and 118 deletions

View File

@ -75,6 +75,11 @@ project(QSkinny
HOMEPAGE_URL "https://github.com/uwerat/qskinny"
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()
include(GNUInstallDirs)

View File

@ -3,4 +3,6 @@
# 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)

View File

@ -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 );
}

View File

@ -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();
};

View File

@ -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;
}

View File

@ -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;
};

View File

@ -5,56 +5,16 @@
#include <SkinnyShortcut.h>
#include <QskAspect.h>
#ifdef ITEM_STATISTICS
#include <QskObjectCounter.h>
#include <QskSimpleListBox.h>
#endif
#include <QskLinearBox.h>
#include <QskWindow.h>
#include <QskFunctions.h>
#include <QFontMetricsF>
#include <QGuiApplication>
class ListBox : public QskSimpleListBox
{
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 );
}
};
#include "ListBox.h"
#include "TreeBox.h"
int main( int argc, char* argv[] )
{
@ -69,7 +29,12 @@ int main( int argc, char* argv[] )
QskWindow window;
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.show();

View File

@ -19,6 +19,7 @@
#include <QskGraphicIO.h>
#include <QskInputPanelBox.h>
#include <QskListView.h>
#include <QskTreeView.h>
#include <QskMenu.h>
#include <QskPageIndicator.h>
#include <QskPushButton.h>
@ -90,6 +91,7 @@ namespace
void setupInputPanel();
void setupVirtualKeyboard();
void setupListView();
void setupTreeView();
void setupMenu();
void setupPageIndicator();
void setupPopup();
@ -157,6 +159,7 @@ void Editor::setup()
setupInputPanel();
setupVirtualKeyboard();
setupListView();
setupTreeView();
setupMenu();
setupPageIndicator();
setupPopup();
@ -1144,7 +1147,20 @@ void Editor::setupListView()
using Q = QskListView;
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 );
setColor( Q::Cell, m_pal.surface );
setColor( Q::Cell | Q::Selected, m_pal.primary12 );

View File

@ -16,6 +16,7 @@
#include <QskInputPanelBox.h>
#include <QskInputPredictionBar.h>
#include <QskListView.h>
#include <QskTreeView.h>
#include <QskMenu.h>
#include <QskPageIndicator.h>
#include <QskPopup.h>
@ -158,6 +159,7 @@ namespace
void setupInputPredictionBar();
void setupVirtualKeyboard();
void setupListView();
void setupTreeView();
void setupMenu();
void setupPageIndicator();
void setupPopup();
@ -283,6 +285,7 @@ void Editor::setup()
setupInputPredictionBar();
setupVirtualKeyboard();
setupListView();
setupTreeView();
setupMenu();
setupPageIndicator();
setupPopup();
@ -1056,6 +1059,20 @@ void Editor::setupListView()
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()
{
using A = QskAspect;

View File

@ -188,6 +188,8 @@ list(APPEND HEADERS
controls/QskInputGrabber.h
controls/QskListView.h
controls/QskListViewSkinlet.h
controls/QskTreeView.h
controls/QskTreeViewSkinlet.h
controls/QskMenu.h
controls/QskMenuSkinlet.h
controls/QskObjectTree.h
@ -286,6 +288,8 @@ list(APPEND SOURCES
controls/QskInputGrabber.cpp
controls/QskListView.cpp
controls/QskListViewSkinlet.cpp
controls/QskTreeView.cpp
controls/QskTreeViewSkinlet.cpp
controls/QskMenuSkinlet.cpp
controls/QskMenu.cpp
controls/QskObjectTree.cpp

View File

@ -151,6 +151,31 @@ QskColorFilter QskListView::graphicFilterAt( int row, int col ) const
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 )
{
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"

View File

@ -64,6 +64,7 @@ class QSK_EXPORT QskListView : public QskScrollView
virtual qreal columnWidth( int col ) const = 0;
virtual qreal rowHeight() const = 0;
virtual qreal rowOffset( int row ) const;
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;
#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:
void setSelectedRow( int row );

View File

@ -110,6 +110,48 @@ QSGNode* QskListViewSkinlet::updateContentsNode(
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(
const QskListView* listView, QskListViewNode* listViewNode ) const
{
@ -125,57 +167,29 @@ void QskListViewSkinlet::updateBackgroundNodes(
if ( rowMax >= listView->rowCount() )
rowMax = listView->rowCount() - 1;
const int rowSelected = listView->selectedRow();
const double x0 = viewRect.left() + scrolledPos.x();
const double x0 = viewRect.left();
const double y0 = viewRect.top();
auto* rowNode = static_cast< QSGSimpleRectNode* >( backgroundNode->firstChild() );
auto* rowNode = static_cast< QSGNode* >( backgroundNode->firstChild() );
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++ )
{
if ( row % 2 )
{
if ( rowNode == nullptr )
{
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 );
const auto offsetX = listView->rowOffset( row );
const QRectF boxRect{ x0 + offsetX, y0 + row * cellHeight, viewRect.width() - offsetX + scrolledPos.x(),
cellHeight };
if ( rowNode == nullptr )
{
rowNode = new QSGSimpleRectNode();
rowNode = new QSGNode;
updateBackgroundNode( listView, rowNode, boxRect, row );
backgroundNode->appendChildNode( rowNode );
}
rowNode->setRect( x0, y0 + rowSelected * cellHeight, viewRect.width(), cellHeight );
rowNode->setColor( color );
rowNode = static_cast< QSGSimpleRectNode* >( rowNode->nextSibling() );
updateBackgroundNode( listView, rowNode, boxRect, row );
rowNode = rowNode->nextSibling();
}
}
QSGNode* nextNode = rowNode;
@ -199,7 +213,8 @@ void QskListViewSkinlet::updateForegroundNodes(
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 scrolledPos = listView->scrollPos();
@ -255,8 +270,8 @@ void QskListViewSkinlet::updateForegroundNodes(
}
}
updateVisibleForegroundNodes( listView, listViewNode,
rowMin, rowMax, colMin, colMax, margins, forwards );
updateVisibleForegroundNodes(
listView, listViewNode, rowMin, rowMax, colMin, colMax, margins, forwards );
// finally putting the nodes into their position
auto node = parentNode->firstChild();
@ -272,9 +287,10 @@ void QskListViewSkinlet::updateForegroundNodes(
{
Q_ASSERT( node->type() == QSGNode::TransformNodeType );
auto transformNode = static_cast< QSGTransformNode* >( node );
const auto offsetX = col == 0 ? listView->rowOffset( row ) : 0.0;
QTransform transform;
transform.translate( x + margins.left(), y + margins.top() );
transform.translate( x + margins.left() + offsetX, y + margins.top() );
transformNode->setMatrix( transform );
@ -288,10 +304,9 @@ void QskListViewSkinlet::updateForegroundNodes(
listViewNode->resetRows( rowMin, rowMax );
}
void QskListViewSkinlet::updateVisibleForegroundNodes(
const QskListView* listView, QskListViewNode* listViewNode,
int rowMin, int rowMax, int colMin, int colMax, const QMarginsF& margins,
bool forward ) const
void QskListViewSkinlet::updateVisibleForegroundNodes( const QskListView* listView,
QskListViewNode* listViewNode, int rowMin, int rowMax, int colMin, int colMax,
const QMarginsF& margins, bool forward ) const
{
auto parentNode = listViewNode->foregroundNode();
@ -312,11 +327,12 @@ void QskListViewSkinlet::updateVisibleForegroundNodes(
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,
parentNode, static_cast< QSGTransformNode* >( node ),
row, col, QSizeF( w, h ), forward );
node = updateForegroundNode( listView, parentNode,
static_cast< QSGTransformNode* >( node ), row, col, QSizeF( w, h ), forward );
node = node->nextSibling();
}
@ -335,11 +351,12 @@ void QskListViewSkinlet::updateVisibleForegroundNodes(
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,
parentNode, static_cast< QSGTransformNode* >( node ),
row, col, QSizeF( w, h ), forward );
node = updateForegroundNode( listView, parentNode,
static_cast< QSGTransformNode* >( node ), row, col, QSizeF( w, h ), forward );
node = node->previousSibling();
}
@ -347,9 +364,9 @@ void QskListViewSkinlet::updateVisibleForegroundNodes(
}
}
QSGTransformNode* QskListViewSkinlet::updateForegroundNode(
const QskListView* listView, QSGNode* parentNode, QSGTransformNode* cellNode,
int row, int col, const QSizeF& size, bool forward ) const
QSGTransformNode* QskListViewSkinlet::updateForegroundNode( const QskListView* listView,
QSGNode* parentNode, QSGTransformNode* cellNode, int row, int col, const QSizeF& size,
bool forward ) const
{
const QRectF cellRect( 0.0, 0.0, size.width(), size.height() );
@ -431,8 +448,8 @@ QSGTransformNode* QskListViewSkinlet::updateForegroundNode(
return newCellNode;
}
QSGNode* QskListViewSkinlet::updateCellNode( const QskListView* listView,
QSGNode* contentNode, const QRectF& rect, int row, int col ) const
QSGNode* QskListViewSkinlet::updateCellNode(
const QskListView* listView, QSGNode* contentNode, const QRectF& rect, int row, int col ) const
{
using namespace QskSGNode;
@ -452,8 +469,10 @@ QSGNode* QskListViewSkinlet::updateCellNode( const QskListView* listView,
public API of QskListView TODO ...
*/
#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 );
@ -464,8 +483,8 @@ QSGNode* QskListViewSkinlet::updateCellNode( const QskListView* listView,
const auto colorFilter = listView->graphicFilterAt( row, col );
newNode = updateGraphicNode( listView, newNode,
value.value< QskGraphic >(), colorFilter, rect, alignment );
newNode = updateGraphicNode(
listView, newNode, value.value< QskGraphic >(), colorFilter, rect, alignment );
if ( newNode )
setNodeRole( newNode, GraphicRole );
@ -475,8 +494,10 @@ QSGNode* QskListViewSkinlet::updateCellNode( const QskListView* listView,
if ( nodeRole( contentNode ) == TextRole )
newNode = contentNode;
newNode = updateTextNode( listView, newNode, rect, alignment,
value.toString(), QskListView::Text );
const auto subControl = listView->textSubControl( row, col );
const auto alignment = listView->alignmentHint( subControl );
newNode =
updateTextNode( listView, newNode, rect, alignment, value.toString(), subControl );
if ( newNode )
setNodeRole( newNode, TextRole );
@ -489,8 +510,8 @@ QSGNode* QskListViewSkinlet::updateCellNode( const QskListView* listView,
return newNode;
}
QSizeF QskListViewSkinlet::sizeHint( const QskSkinnable* skinnable,
Qt::SizeHint which, const QSizeF& ) const
QSizeF QskListViewSkinlet::sizeHint(
const QskSkinnable* skinnable, Qt::SizeHint which, const QSizeF& ) const
{
const auto listView = static_cast< const QskListView* >( skinnable );

View File

@ -44,6 +44,7 @@ class QSK_EXPORT QskListViewSkinlet : public QskScrollViewSkinlet
virtual QSGNode* updateCellNode( const QskListView*,
QSGNode*, const QRectF&, int row, int col ) const;
virtual void updateBackgroundNode( const QskListView* listView, QSGNode* rowNode, const QRectF& boxRect, const int row ) const;
private:
void updateForegroundNodes( const QskListView*, QskListViewNode* ) const;
void updateBackgroundNodes( const QskListView*, QskListViewNode* ) const;

View File

@ -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 );
}

View File

@ -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 );
};

View File

@ -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"

View File

@ -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