Compare commits

..

17 Commits

Author SHA1 Message Date
Uwe Rathmann 9040e006ad Merge branch 'master' into features/modelobjectbinder 2025-02-28 09:31:35 +01:00
Uwe Rathmann d9ef4f51ae Merge branch 'master' into features/modelobjectbinder 2025-02-06 10:28:04 +01:00
Uwe Rathmann 04e3378abb QskTextInput -> QskTextField 2024-12-10 14:29:36 +01:00
Uwe Rathmann 52686242ec Merge branch 'master' into features/modelobjectbinder 2024-12-10 14:10:57 +01:00
Uwe Rathmann c6fc72e07c Merge branch 'master' into features/modelobjectbinder 2024-12-02 10:16:42 +01:00
Uwe Rathmann 69eae90d3a Merge branch 'master' into features/modelobjectbinder 2024-09-17 17:43:06 +02:00
Uwe Rathmann a888d9c5a8 dummy implementation of the destructor in C++ file to avoid compiler
errors because of not knowing PrivateData otherwise
2024-09-11 18:49:17 +02:00
Uwe Rathmann cd8fd0d2b2 Merge branch 'master' into features/modelobjectbinder 2024-09-11 18:13:26 +02:00
Uwe Rathmann 6a547e4698 Qt5 incompatibility fixed 2024-02-26 15:49:06 +01:00
Uwe Rathmann 0a651782ba QskModelObjectBinder API improved, models example polished 2024-02-26 15:27:52 +01:00
Uwe Rathmann 7b4db3afc1 wip 2024-02-26 12:16:56 +01:00
Uwe Rathmann e2486f914d QSql dependency removed ( using a QStandardItemModel instead ) 2024-02-26 11:39:16 +01:00
Uwe Rathmann 60c7442fd0 role check fixed 2024-02-26 11:37:59 +01:00
Uwe Rathmann 8faa6a8cad bugs fixed, QskModelObjectBinder improved 2024-02-26 10:52:52 +01:00
Uwe Rathmann 1a5dc6d358 Qt5 incompatibility fixed 2024-02-25 13:55:40 +01:00
Uwe Rathmann 59afa42c84 QskModelObjectBinder modified and moved to src/controls 2024-02-25 13:28:11 +01:00
Uwe Rathmann 6ea2126638 Squashed commit of the following:
Merge: f614117d f0d49d9e
Author: Uwe Rathmann <Uwe.Rathmann@tigertal.de>
Date:   Sun Feb 25 09:11:12 2024 +0100

    Merge branch 'master' of https://github.com/ovenpasta/qskinny into models
    ( Author: Aldo Nicolas Bruno <ovenpasta@pizzahack.eu> )
2024-02-25 13:21:59 +01:00
41 changed files with 1008 additions and 537 deletions

View File

@ -202,6 +202,7 @@ jobs:
install-deps: "true"
modules: "qtwebengine"
cached: ${{ steps.cache-qt-5-15.outputs.cache-hit }}
setup-python: "false"
tools: ""
set-env: "true"
tools-only: "false"
@ -215,6 +216,7 @@ jobs:
install-deps: "true"
modules: "qtwebengine qtshadertools"
cached: ${{ steps.cache-qt-6-2.outputs.cache-hit }}
setup-python: "false"
tools: ""
set-env: "true"
tools-only: "false"

View File

@ -149,7 +149,7 @@ function(qsk_add_example target)
endfunction()
function(qsk_add_shaders target shader_name)
function(qsk_add_shaders target)
cmake_parse_arguments( arg "" "" "FILES" ${ARGN} )
@ -160,7 +160,7 @@ function(qsk_add_shaders target shader_name)
list(APPEND outfiles "${qsbname}.qsb")
endforeach()
qt6_add_shaders( ${target} ${shader_name} BATCHABLE PRECOMPILE QUIET
qt6_add_shaders( ${target} "qskshaders" BATCHABLE PRECOMPILE QUIET
PREFIX "/qskinny/shaders" ${ARGV} OUTPUTS ${outfiles} )
# pass on OUTPUT_TARGETS to the caller of this function

View File

@ -5,7 +5,9 @@
#include "QskMaterial3ProgressBarSkinlet.h"
#include <QskProgressBar.h>
#include <QskBoxHints.h>
#include <QskBoxShapeMetrics.h>
#include <QskBoxBorderMetrics.h>
#include <QskBoxBorderColors.h>
#include <QskMargins.h>
#include <QskClipNode.h>
#include <QskSGNode.h>
@ -63,11 +65,11 @@ QSGNode* QskMaterial3ProgressBarSkinlet::updateStopIndicatorNode(
else
rect.setBottom( rect.top() + rect.width() );
QskBoxHints hints;
hints.shape = progressBar->boxShapeHint( Q::Fill );
hints.gradient = progressBar->gradientHint( Q::Fill ).endColor();
const auto color = progressBar->gradientHint( Q::Fill ).endColor();
const auto shape = progressBar->boxShapeHint( Q::Fill );
return updateBoxNode( progressBar, node, rect, hints );
return updateBoxNode( progressBar, node, rect, shape,
QskBoxBorderMetrics(), QskBoxBorderColors(), color );
}
QSGNode* QskMaterial3ProgressBarSkinlet::updateGrooveClipNode(

View File

@ -14,8 +14,8 @@ StorageBarSkinlet::StorageBarSkinlet( QskSkin* skin )
setNodeRoles( { Pictures, Music, Videos, Documents, Others, Free } );
}
QRectF StorageBarSkinlet::subControlRect( const QskSkinnable* skinnable,
const QRectF& contentsRect, QskAspect::Subcontrol subControl ) const
QRectF StorageBarSkinlet::subControlRect( const QskSkinnable* skinnable, const QRectF& contentsRect,
QskAspect::Subcontrol subControl ) const
{
const auto* const bar = static_cast< const S* >( skinnable );
@ -70,29 +70,35 @@ QRectF StorageBarSkinlet::subControlRect( const QskSkinnable* skinnable,
return Inherited::subControlRect( skinnable, contentsRect, subControl );
}
namespace
{
inline QSGNode* updateSegmentBoxNode(
const S* const skinnable, const QskAspect::Subcontrol& subcontrol, QSGNode* const node )
{
return QskSkinlet::updateBoxNode( skinnable, node, skinnable->subControlRect( subcontrol ),
skinnable->gradientHint( subcontrol ), subcontrol );
}
}
QSGNode* StorageBarSkinlet::updateSubNode(
const QskSkinnable* const skinnable, const quint8 nodeRole, QSGNode* const node ) const
{
const auto* const bar = static_cast< const S* >( skinnable );
switch ( nodeRole )
{
case Pictures:
return updateBoxNode( skinnable, node, S::Pictures );
return updateSegmentBoxNode( bar, S::Pictures, node );
case Music:
return updateBoxNode( skinnable, node, S::Music );
return updateSegmentBoxNode( bar, S::Music, node );
case Videos:
return updateBoxNode( skinnable, node, S::Videos );
return updateSegmentBoxNode( bar, S::Videos, node );
case Documents:
return updateBoxNode( skinnable, node, S::Documents );
return updateSegmentBoxNode( bar, S::Documents, node );
case Others:
return updateBoxNode( skinnable, node, S::Others );
return updateSegmentBoxNode( bar, S::Others, node );
case Free:
return updateBoxNode( skinnable, node, S::Free );
return updateSegmentBoxNode( bar, S::Free, node );
default:
return Inherited::updateSubNode( skinnable, nodeRole, node );
}

View File

@ -9,6 +9,7 @@ add_subdirectory(shadows)
add_subdirectory(shapes)
add_subdirectory(charts)
add_subdirectory(plots)
add_subdirectory(models)
if (BUILD_INPUTCONTEXT)
add_subdirectory(inputpanel)

View File

@ -0,0 +1,7 @@
############################################################################
# QSkinny - Copyright (C) The authors
# SPDX-License-Identifier: BSD-3-Clause
############################################################################
qsk_add_example(models MainView.h MainView.cpp main.cpp)
target_link_libraries(models)

View File

@ -0,0 +1,215 @@
/******************************************************************************
* QSkinny - Copyright (C) The authors
* SPDX-License-Identifier: BSD-3-Clause
*****************************************************************************/
#include "MainView.h"
#include <QskLinearBox.h>
#include <QskPushButton.h>
#include <QskTextLabel.h>
#include <QskTextField.h>
#include <QskSpinBox.h>
#include <QskSeparator.h>
#include <QskFontRole.h>
#include <QskModelObjectBinder.h>
#include <QStandardItemModel>
namespace
{
class TitleLabel : public QskTextLabel
{
public:
TitleLabel( const QString& text, QQuickItem* parent = nullptr )
: QskTextLabel( text, parent )
{
setFontRole( QskFontRole::Title );
}
};
class SpinBox : public QskSpinBox
{
public:
SpinBox( QQuickItem* parent = nullptr )
: QskSpinBox( -100.0, 100.0, 1.0, parent )
{
initSizePolicy( QskSizePolicy::Fixed, QskSizePolicy::Fixed );
}
};
class Header : public QskLinearBox
{
Q_OBJECT
public:
Header( QQuickItem* parent = nullptr )
: QskLinearBox( Qt::Horizontal, parent )
{
initSizePolicy( QskSizePolicy::Ignored, QskSizePolicy::Fixed );
setPaddingHint( QskBox::Panel, 5 );
setPanel( true );
auto rowButton = new QskPushButton( "Toggle Row" );
auto submitButton = new QskPushButton( "Submit Changes" );
connect( rowButton, &QskPushButton::clicked,
this, &Header::rowClicked );
connect( submitButton, &QskPushButton::clicked,
this, &Header::submitClicked );
addItem( rowButton );
addItem( submitButton );
addStretch( 1 );
}
Q_SIGNALS:
void rowClicked();
void submitClicked();
};
class Model : public QStandardItemModel
{
public:
Model( QObject* parent = nullptr )
: QStandardItemModel( 2, 2, parent )
{
initValue( 0, 0, 1.0 );
initValue( 0, 1, "HELLO" );
initValue( 1, 0, 2.0 );
initValue( 1, 1, "WORLD" );
}
private:
void initValue( int row, int col, const QVariant& value )
{
setData( index( row, col ), value, Qt::EditRole );
}
};
class DisplayBox : public QskLinearBox
{
public:
DisplayBox( QQuickItem* parent = nullptr )
: QskLinearBox( Qt::Horizontal, parent )
{
setMargins( 10, 0, 10, 0 );
initSizePolicy( QskSizePolicy::MinimumExpanding, QskSizePolicy::Fixed );
addItem( new SpinBox() );
addItem( new QskTextField() );
}
};
class ModelBox : public QskLinearBox
{
public:
ModelBox( QAbstractItemModel* model )
: QskLinearBox( Qt::Horizontal, model->columnCount() )
, m_model( model )
{
setMargins( 10, 0, 10, 0 );
setExtraSpacingAt( Qt::BottomEdge );
for ( int row = 0; row < model->rowCount(); row++ )
{
for ( int col = 0; col < model->columnCount(); col++ )
{
const auto value = model->data(
model->index( row, col ), Qt::EditRole );
if ( value.userType() == QVariant::Double )
{
auto spinBox = new SpinBox( this );
connect( spinBox, &QskSpinBox::valueChanged,
this, &ModelBox::updateModel );
}
else
{
auto textField = new QskTextField( this );
connect( textField, &QskTextField::textChanged,
this, &ModelBox::updateModel );
}
}
}
updateDisplay();
connect( m_model, &Model::dataChanged, this, &ModelBox::updateDisplay );
}
private:
void updateModel()
{
if ( auto item = qobject_cast< const QQuickItem* >( sender() ) )
{
const int index = indexOf( item );
const auto modelIndex = m_model->index(
index / dimension(), index % dimension() );
const auto property = item->metaObject()->userProperty();
m_model->setData( modelIndex, property.read( item ), Qt::EditRole );
}
}
void updateDisplay() const
{
for ( int row = 0; row < m_model->rowCount(); row++ )
{
for ( int col = 0; col < m_model->columnCount(); col++ )
{
const auto index = m_model->index( row, col );
if ( auto item = itemAtIndex( row * dimension() + col ) )
{
const auto property = item->metaObject()->userProperty();
property.write( item, m_model->data( index, Qt::EditRole ) );
}
}
}
}
QPointer< QAbstractItemModel > m_model;
};
}
MainView::MainView( QQuickItem* parent )
: QskMainView( parent )
{
m_binder = new QskModelObjectBinder( new Model( this ), this );
auto header = new Header();
auto displayBox = new DisplayBox();
for ( int i = 0; i < displayBox->elementCount(); i++ )
m_binder->bindObject( displayBox->itemAtIndex( i ), i );
auto box = new QskLinearBox( Qt::Vertical );
box->addItem( new TitleLabel( "Editor:" ) );
box->addItem( displayBox );
box->addItem( new QskSeparator() );
box->addItem( new TitleLabel( "Model:" ) );
box->addItem( new ModelBox( m_binder->model() ) );
setHeader( header );
setBody( box );
connect( header, &Header::rowClicked,
this, &MainView::toogleRow );
connect( header, &Header::submitClicked,
m_binder, &QskModelObjectBinder::submit );
}
void MainView::toogleRow()
{
m_binder->setCurrentRow( m_binder->currentRow() == 0 ? 1 : 0 );
}
#include "MainView.moc"

View File

@ -0,0 +1,21 @@
/******************************************************************************
* QSkinny - Copyright (C) The authors
* SPDX-License-Identifier: BSD-3-Clause
*****************************************************************************/
#pragma once
#include <QskMainView.h>
class QskModelObjectBinder;
class MainView : public QskMainView
{
public:
MainView( QQuickItem* = nullptr );
private:
void toogleRow();
QskModelObjectBinder* m_binder;
};

View File

@ -0,0 +1,37 @@
/******************************************************************************
* QSkinny - Copyright (C) The authors
* SPDX-License-Identifier: BSD-3-Clause
*****************************************************************************/
#include "MainView.h"
#include <SkinnyShortcut.h>
#include <QskObjectCounter.h>
#include <QskFocusIndicator.h>
#include <QskWindow.h>
#include <QGuiApplication>
int main( int argc, char* argv[] )
{
#ifdef ITEM_STATISTICS
QskObjectCounter counter( true );
#endif
QGuiApplication app( argc, argv );
SkinnyShortcut::enable( SkinnyShortcut::AllShortcuts );
QskWindow window;
window.resize( 600, 400 );
auto focusIndicator = new QskFocusIndicator();
focusIndicator->setObjectName( "FocusIndicator" );
window.addItem( focusIndicator );
window.addItem( new MainView() );
window.show();
return app.exec();
}

View File

@ -9,7 +9,6 @@
#include <QskSGNode.h>
#include <QskTextOptions.h>
#include <QskTextColors.h>
#include <QskBoxHints.h>
#include <QskPlotCurve.h>
#include <QskPlotCorridor.h>
@ -144,10 +143,8 @@ QSGNode* PlotCursorSkinlet::updateSampleNode( const QskSkinnable* skinnable,
if ( subControl == Q::LabelPanel )
{
auto hints = skinnable->boxHints( subControl );
hints.gradient = skinnable->gradientHint( aspect );
return updateBoxNode( skinnable, node, rect, hints );
const auto gradient = skinnable->gradientHint( aspect );
return updateBoxNode( skinnable, node, rect, gradient, subControl );
}
if ( subControl == Q::LabelText )

View File

@ -35,6 +35,6 @@ if (QT_VERSION_MAJOR VERSION_GREATER_EQUAL 6)
shaders/arcshadow-vulkan.vert
shaders/arcshadow-vulkan.frag
)
qsk_add_shaders( ${target} "qskArcShaders" FILES ${SHADERS} OUTPUT_TARGETS shader_target)
qsk_add_shaders( ${target} FILES ${SHADERS} OUTPUT_TARGETS shader_target)
endif()

View File

@ -8,7 +8,7 @@
#include <QskSkinlet.h>
#include <QskArcNode.h>
#include <QskArcHints.h>
#include <QskArcMetrics.h>
#include <QskShadowMetrics.h>
#include <QskSGNode.h>
#include <QskRgbValue.h>
@ -107,7 +107,14 @@ namespace
return nullptr;
auto arcNode = QskSGNode::ensureNode< QskArcNode >( node );
arcNode->setArcData( rect, arc->arcHints( Q::Arc ) );
const auto metrics = arc->arcMetricsHint( Q::Arc );
const auto fillGradient = arc->gradientHint( Q::Arc );
const auto borderColor = arc->color( Q::Arc | QskAspect::Border );
const auto borderWidth = arc->metric( Q::Arc | QskAspect::Border );
arcNode->setArcData( rect, metrics, borderWidth, borderColor, fillGradient );
return arcNode;
}

View File

@ -21,7 +21,6 @@ Slider::Slider( const QString& text, qreal min, qreal max,
m_slider->setBoundaries( min, max );
m_slider->setStepSize( step );
m_slider->setSnapping( true );
m_slider->setTickPolicy( Qsk::Never ); // too many steps
m_slider->setValue( value );
m_valueLabel = new QskTextLabel( this );

View File

@ -5,7 +5,6 @@
list(APPEND HEADERS
common/QskArcMetrics.h
common/QskArcHints.h
common/QskAspect.h
common/QskBoxBorderColors.h
common/QskBoxBorderMetrics.h
@ -42,7 +41,6 @@ list(APPEND HEADERS
list(APPEND SOURCES
common/QskArcMetrics.cpp
common/QskArcHints.cpp
common/QskAspect.cpp
common/QskBoxBorderColors.cpp
common/QskBoxBorderMetrics.cpp
@ -235,6 +233,7 @@ list(APPEND HEADERS
controls/QskListViewSkinlet.h
controls/QskMenu.h
controls/QskMenuSkinlet.h
controls/QskModelObjectBinder.h
controls/QskObjectTree.h
controls/QskPageIndicator.h
controls/QskPageIndicatorSkinlet.h
@ -347,6 +346,7 @@ list(APPEND SOURCES
controls/QskListViewSkinlet.cpp
controls/QskMenuSkinlet.cpp
controls/QskMenu.cpp
controls/QskModelObjectBinder.cpp
controls/QskObjectTree.cpp
controls/QskPageIndicator.cpp
controls/QskPageIndicatorSkinlet.cpp
@ -510,7 +510,7 @@ else()
endif()
if (QT_VERSION_MAJOR VERSION_GREATER_EQUAL 6)
qsk_add_shaders( ${target} "qskshaders" FILES ${SHADERS} OUTPUT_TARGETS shader_target)
qsk_add_shaders( ${target} FILES ${SHADERS} OUTPUT_TARGETS shader_target)
endif()
target_include_directories(${target} PUBLIC

View File

@ -1,69 +0,0 @@
/******************************************************************************
* QSkinny - Copyright (C) The authors
* SPDX-License-Identifier: BSD-3-Clause
*****************************************************************************/
#include "QskArcHints.h"
#include "QskRgbValue.h"
static inline qreal qskInterpolated( qreal from, qreal to, qreal ratio )
{
return from + ( to - from ) * ratio;
}
QskArcHints::QskArcHints()
{
}
QskArcHints::QskArcHints( const QskArcMetrics& metrics, qreal borderWidth,
const QColor& borderColor, const QskGradient& gradient )
: metrics( metrics )
, borderWidth( borderWidth )
, borderColor( borderColor )
, gradient( gradient )
{
}
bool QskArcHints::isVisible() const
{
if ( metrics.isNull() )
return false;
if ( borderWidth > 0.0 && borderColor.isValid() && borderColor.alpha() > 0 )
return true;
return gradient.isVisible();
}
QskArcHints QskArcHints::toAbsolute( const QSizeF& size ) const noexcept
{
return QskArcHints( metrics.toAbsolute( size ),
borderWidth, borderColor, gradient );
}
QskArcHints QskArcHints::interpolated(
const QskArcHints& to, qreal value ) const noexcept
{
return QskArcHints(
metrics.interpolated( to.metrics, value ),
qskInterpolated( borderWidth, to.borderWidth, value ),
QskRgb::interpolated( borderColor, to.borderColor, value ),
gradient.interpolated( to.gradient, value )
);
}
#ifndef QT_NO_DEBUG_STREAM
#include <qdebug.h>
QDebug operator<<( QDebug debug, const QskArcHints& hints )
{
debug << hints.metrics << hints.borderWidth
<< hints.borderColor << hints.gradient;
return debug;
}
#endif
#include "moc_QskArcHints.cpp"

View File

@ -1,47 +0,0 @@
/******************************************************************************
* QSkinny - Copyright (C) The authors
* SPDX-License-Identifier: BSD-3-Clause
*****************************************************************************/
#ifndef QSK_ARC_HINTS_H
#define QSK_ARC_HINTS_H
#include "QskArcMetrics.h"
#include "QskGradient.h"
#include <qcolor.h>
class QSK_EXPORT QskArcHints
{
Q_GADGET
Q_PROPERTY( QskArcMetrics metrics MEMBER metrics )
Q_PROPERTY( qreal borderWidth MEMBER borderWidth )
Q_PROPERTY( QColor borderColor MEMBER borderColor )
public:
QskArcHints();
QskArcHints( const QskArcMetrics&, qreal borderWidth,
const QColor& borderColor, const QskGradient& );
QskArcHints toAbsolute( const QSizeF& ) const noexcept;
QskArcHints interpolated(
const QskArcHints&, qreal value ) const noexcept;
bool isVisible() const;
QskArcMetrics metrics;
qreal borderWidth = 0.0;
QColor borderColor;
QskGradient gradient;
};
#ifndef QT_NO_DEBUG_STREAM
class QDebug;
QSK_EXPORT QDebug operator<<( QDebug, const QskArcHints& );
#endif
#endif

View File

@ -81,7 +81,7 @@ QskGradient::QskGradient( const QColor& color1, const QColor& color2 )
QskGradient::QskGradient( QGradient::Preset preset )
: QskGradient()
{
setStops( qskFromQGradientStops( QGradient( preset ).stops() ) );
setStops( qskBuildGradientStops( QGradient( preset ).stops() ) );
}
QskGradient::QskGradient( const QVector< QskGradientStop >& stops )
@ -165,7 +165,7 @@ QskGradient::QskGradient( const QGradient& qGradient )
}
}
setStops( qskFromQGradientStops( qGradient.stops() ) );
setStops( qskBuildGradientStops( qGradient.stops() ) );
}
QskGradient::QskGradient( const QskGradient& other ) noexcept
@ -305,7 +305,7 @@ void QskGradient::setStops( const QColor& color1, const QColor& color2 )
void QskGradient::setStops( QGradient::Preset preset )
{
const auto stops = qskFromQGradientStops( QGradient( preset ).stops() );
const auto stops = qskBuildGradientStops( QGradient( preset ).stops() );
setStops( stops );
}

View File

@ -23,31 +23,6 @@ static void qskRegisterGradientStop()
Q_CONSTRUCTOR_FUNCTION( qskRegisterGradientStop )
static inline qreal qskBoundedStopPos( qreal pos )
{
if ( ( pos < 0.0 ) || qFuzzyIsNull( pos ) )
return 0.0;
if ( ( pos > 1.0 ) || qFuzzyCompare( pos, 1.0 ) )
return 1.0;
return pos;
}
static inline QVector< QskGradientStop >
qskNormalizedStops( const QVector< QskGradientStop >& stops )
{
auto s = stops;
if ( s.first().position() > 0.0 )
s.prepend( QskGradientStop( 0.0, s.first().color() ) );
if ( s.last().position() < 1.0 )
s.append( QskGradientStop( 1.0, s.last().color() ) );
return s;
}
void QskGradientStop::setPosition( qreal position ) noexcept
{
m_position = position;
@ -81,19 +56,26 @@ QskHashValue QskGradientStop::hash( QskHashValue seed ) const noexcept
return qHashBits( &m_color, sizeof( m_color ), hash );
}
QskGradientStop QskGradientStop::interpolated(
const QskGradientStop& to, qreal ratio ) const
QColor QskGradientStop::interpolated(
const QskGradientStop& s1, const QskGradientStop& s2, qreal position ) noexcept
{
return QskGradientStop(
m_position + ( to.m_position - m_position ) * ratio,
QskRgb::interpolated( m_color, to.m_color, ratio )
);
}
if ( s1.color() == s2.color() )
return s1.color();
QVariant QskGradientStop::interpolate(
const QskGradientStop& from, const QskGradientStop& to, qreal ratio )
{
return QVariant::fromValue( from.interpolated( to, ratio ) );
auto min = &s1;
auto max = &s2;
if ( min->position() > max->position() )
std::swap( min, max );
if ( position <= min->position() )
return min->color();
if ( position >= max->position() )
return max->color();
const qreal r = ( position - min->position() ) / ( max->position() - min->position() );
return QskRgb::interpolated( min->color(), max->color(), r );
}
#ifndef QT_NO_DEBUG_STREAM
@ -113,23 +95,19 @@ QDebug operator<<( QDebug debug, const QskGradientStop& stop )
#endif
#include "moc_QskGradientStop.cpp"
// some helper functions around QskGradientStops
static inline QColor qskColorAtPosition(
const QskGradientStop& s1, const QskGradientStop& s2, qreal pos )
static inline QColor qskInterpolatedColor(
const QskGradientStops& stops, int index1, int index2, qreal position )
{
const auto dp = s2.position() - s1.position();
if ( qFuzzyIsNull( dp ) )
return s1.color();
const auto max = static_cast< int >( stops.count() ) - 1;
return QskRgb::interpolated(
s1.color(), s2.color(), ( pos - s1.position() ) / dp );
}
index1 = qBound( 0, index1, max );
index2 = qBound( 0, index2, max );
static inline QskGradientStop qskCreateStopAtPosition(
const QskGradientStop& s1, const QskGradientStop& s2, qreal pos )
{
return { pos, qskColorAtPosition( s1, s2, pos ) };
return QskGradientStop::interpolated( stops[ index1 ], stops[ index2 ], position );
}
bool qskIsVisible( const QskGradientStops& stops ) noexcept
@ -300,126 +278,43 @@ QColor qskInterpolatedColorAt( const QskGradientStops& stops, qreal pos ) noexce
if ( stops.isEmpty() )
return QColor();
pos = qBound( 0.0, pos, 1.0 );
if ( pos <= stops.first().position() )
return stops.first().color();
for ( int i = 1; i < stops.count(); i++ )
{
if ( pos <= stops[ i ].position() )
return qskColorAtPosition( stops[ i - 1 ], stops[ i ], pos );
if ( pos <= stops[i].position() )
return qskInterpolatedColor( stops, i - 1, i, pos );
}
return stops.last().color();
}
QskGradientStops qskReplacedGradientStops( const QskGradientStops& gradientStops,
const QskGradientStop& stop1, const QskGradientStop& stop2 )
{
if ( stop1.position() >= stop2.position() )
return gradientStops;
const auto s1 = QskGradientStop( qskBoundedStopPos( stop1.position() ), stop1.color() );
const auto s2 = QskGradientStop( qskBoundedStopPos( stop2.position() ), stop2.color() );
QskGradientStops stops;
if ( s1.position() == 0.0 && s2.position() == 1.0 )
{
stops = { s1, s2 };
}
else if ( qskIsMonochrome( gradientStops ) )
{
stops.reserve( 4 );
const auto c = gradientStops.isEmpty()
? QColor::fromRgba( 0 ) : gradientStops.first().color();
if ( s1.position() > 0.0 )
stops += { s1.position(), c };
stops += s1;
stops += s2;
if ( s2.position() < 1.0 )
stops += { s2.position(), c };
}
else
{
// not the most efficient implementation - maybe later TODO ...
const auto stops0 = qskNormalizedStops( gradientStops );
int i = 0;
if ( s1.position() > 0.0 )
{
while ( s1.position() > stops0[i].position() )
stops += stops0[i++];
if ( s1.position() == stops0[i].position() )
stops += stops0[i++];
else
stops += qskCreateStopAtPosition( stops0[i - 1], stops0[i], s1.position() );
}
stops += s1;
while ( s2.position() > stops0[i].position() )
i++;
stops += s2;
if ( s2.position() < 1.0 )
{
while ( stops0[i + 1].position() == s2.position() )
i++;
if ( s2.position() != stops0[i].position() )
stops += qskCreateStopAtPosition( stops0[i - 1], stops0[i], s2.position() );
while( i < stops0.count() )
stops += stops0[i++];
}
}
return stops;
}
QskGradientStops qskClippedGradientStops(
const QskGradientStops& stops, qreal from, qreal to )
{
return qskReplacedGradientStops( stops, { from, 0 }, { to, 0 } );
}
QskGradientStops qskExtractedGradientStops(
const QskGradientStops& stops, qreal from, qreal to )
const QskGradientStops& gradientStops, qreal from, qreal to )
{
if ( ( from > to ) || ( to > 1.0 ) || ( from < 0.0 ) || stops.isEmpty() )
if ( ( from > to ) || ( from > 1.0 ) || gradientStops.isEmpty() )
return QskGradientStops();
from = qskBoundedStopPos( from );
to = qskBoundedStopPos( to );
if ( ( from <= 0.0 ) && ( to >= 1.0 ) )
return gradientStops;
if ( ( from == 0.0 ) && ( to == 1.0 ) )
return stops;
from = qMax( from, 0.0 );
to = qMin( to, 1.0 );
if ( from == to )
{
const auto color = qskInterpolatedColorAt( stops, from );
QVector< QskGradientStop > stops1 = gradientStops;
QVector< QskGradientStop > s;
s.reserve( 2 );
s += QskGradientStop( 0.0, color );
s += QskGradientStop( 1.0, color );
#if 1
// not the most efficient implementation - maybe later TODO ...
return s;
}
if ( stops1.first().position() > 0.0 )
stops1.prepend( QskGradientStop( 0.0, stops1.first().color() ) );
/*
For situations where we have no stops at 0.0 and 1.0 we insert them
manually. Not the most efficient implementation, but we avoid having
to deal with these situations for the moment. TODO ...
*/
const auto stops1 = qskNormalizedStops( stops );
if ( stops1.last().position() < 1.0 )
stops1.append( QskGradientStop( 1.0, stops1.last().color() ) );
#endif
QVector< QskGradientStop > stops2;
stops2.reserve( stops1.count() );
@ -436,26 +331,26 @@ QskGradientStops qskExtractedGradientStops(
{
int i = 0;
if ( from == 0.0 )
for ( ; i < stops1.count(); i++ )
{
stops2 += stops1[i++];
}
else
{
while( stops1[++i].position() <= from ); // skip leading stops
stops2 += QskGradientStop( 0.0,
qskColorAtPosition( stops1[i - 1], stops1[ i ], from ) );
if ( stops1[i].position() > from )
break;
}
while ( stops1[i].position() < to )
stops2 += QskGradientStop( 0.0,
qskInterpolatedColor( stops1, i - 1, i, from ) );
for ( ; i < stops1.count(); i++ )
{
if ( stops1[i].position() >= to )
break;
const auto pos = ( stops1[i].position() - from ) / ( to - from );
stops2 += QskGradientStop( pos, stops1[i++].color() );
stops2 += QskGradientStop( pos, stops1[i].color() );
}
stops2 += QskGradientStop( 1.0,
qskColorAtPosition( stops1[i - 1], stops1[ i ], to ) );
qskInterpolatedColor( stops1, i, i + 1, to ) );
}
return stops2;
@ -472,7 +367,7 @@ QskGradientStops qskRevertedGradientStops( const QskGradientStops& stops )
return s;
}
QVector< QskGradientStop > qskFromQGradientStops( const QGradientStops& qtStops )
QVector< QskGradientStop > qskBuildGradientStops( const QGradientStops& qtStops )
{
QVector< QskGradientStop > stops;
stops.reserve( qtStops.count() );
@ -568,5 +463,3 @@ QGradientStops qskToQGradientStops( const QskGradientStops& stops )
return qStops;
}
#include "moc_QskGradientStop.cpp"

View File

@ -45,10 +45,8 @@ class QSK_EXPORT QskGradientStop
void setRgb( QRgb ) noexcept;
QRgb rgb() const noexcept;
QskGradientStop interpolated( const QskGradientStop&, qreal ) const;
static QVariant interpolate( const QskGradientStop&,
const QskGradientStop&, qreal );
static QColor interpolated(
const QskGradientStop&, const QskGradientStop&, qreal position ) noexcept;
QskHashValue hash( QskHashValue seed ) const noexcept;
@ -131,48 +129,27 @@ QSK_EXPORT QskGradientStops qskInterpolatedGradientStops(
const QskGradientStops&, bool, const QskGradientStops&, bool,
qreal ratio );
// interpolating colors in direction of a color.
QSK_EXPORT QskGradientStops qskInterpolatedGradientStops(
const QskGradientStops&, const QColor&, qreal ratio );
// interpolating colors starting from a color.
QSK_EXPORT QskGradientStops qskInterpolatedGradientStops(
const QColor&, const QskGradientStops&, qreal ratio );
// interpolating the opacity of the colors
QSK_EXPORT QskGradientStops qskTransparentGradientStops(
const QskGradientStops&, qreal ratio );
// extracting the colors of [from, to ] and stretching them to [0.0, 1.0]
QSK_EXPORT QskGradientStops qskExtractedGradientStops(
const QskGradientStops&, qreal from, qreal to );
// reverting the color stops
QSK_EXPORT QskGradientStops qskRevertedGradientStops( const QskGradientStops& );
QSK_EXPORT QskGradientStops qskReplacedGradientStops(
const QskGradientStops&, const QskGradientStop&, const QskGradientStop& );
QSK_EXPORT QskGradientStops qskClippedGradientStops(
const QskGradientStops&, qreal from, qreal to );
/*
creating equidistant color stops from a list of colors.
when discrete is true the result will contain 2 stops at each position
one with the previous and one with the following color so that the
interval [pos1-pos2] will be monochrome.
*/
QSK_EXPORT QskGradientStops qskBuildGradientStops(
const QVector< QRgb >&, bool discrete = false );
QSK_EXPORT QskGradientStops qskBuildGradientStops(
const QVector< QColor >&, bool discrete = false );
/*
convert color stops from/to a vector of QGradientStop, that can be
used for QGradients.
*/
QSK_EXPORT QskGradientStops qskFromQGradientStops( const QVector< QGradientStop >& );
QSK_EXPORT QskGradientStops qskRevertedGradientStops( const QskGradientStops& );
QSK_EXPORT QskGradientStops qskBuildGradientStops( const QVector< QGradientStop >& );
QSK_EXPORT QVector< QGradientStop > qskToQGradientStops( const QVector< QskGradientStop >& );
#endif

View File

@ -41,7 +41,7 @@ class QSK_EXPORT QskTextColors
void setLinkColor( QRgb );
void setLinkColor( Qt::GlobalColor );
QskTextColors interpolated( const QskTextColors&, qreal ratio ) const;
QskTextColors interpolated( const QskTextColors&, qreal value ) const;
static QVariant interpolate( const QskTextColors&,
const QskTextColors&, qreal ratio );

View File

@ -9,7 +9,6 @@
#include "QskGraphic.h"
#include "QskColorFilter.h"
#include "QskTextOptions.h"
#include "QskBoxHints.h"
#include "QskFunctions.h"
#include "QskMargins.h"
#include "QskFunctions.h"
@ -573,13 +572,11 @@ QSGNode* QskMenuSkinlet::updateSampleNode( const QskSkinnable* skinnable,
if ( subControl == Q::Separator )
{
auto hints = skinnable->boxHints( subControl );
auto& gradient = hints.gradient;
auto gradient = menu->gradientHint( subControl );
if ( ( gradient.type() == QskGradient::Stops ) && !gradient.isMonochrome() )
gradient.setLinearDirection( Qt::Vertical );
return updateBoxNode( menu, node, rect, hints );
return updateBoxNode( menu, node, rect, gradient, subControl );
}
return nullptr;

View File

@ -0,0 +1,274 @@
/******************************************************************************
* QSkinny - Copyright (C) The authors
* SPDX-License-Identifier: BSD-3-Clause
*****************************************************************************/
#include "QskModelObjectBinder.h"
#include <qmetaobject.h>
#include <qabstractitemmodel.h>
#include <qpointer.h>
static inline QMetaProperty qskMetaProperty(
const QMetaObject* metaObject, const QByteArray& name )
{
if ( name.isEmpty() )
return metaObject->userProperty();
const auto idx = metaObject->indexOfProperty( name );
return ( idx >= 0 ) ? metaObject->property( idx ) : QMetaProperty();
}
static void qskEnableConnections( QObject* object,
QskModelObjectBinder* binder, bool on )
{
if ( on )
{
QObject::connect( object, &QObject::destroyed,
binder, &QskModelObjectBinder::unbindObject );
}
else
{
QObject::disconnect( object, &QObject::destroyed,
binder, &QskModelObjectBinder::unbindObject );
}
}
namespace
{
struct Binding
{
Binding( int column, const QMetaProperty& property )
: property( property )
, column( column )
{
}
QMetaProperty property;
int column;
};
}
class QskModelObjectBinder::PrivateData
{
public:
void updateProperties()
{
if ( model && currentRowIndex.isValid() )
{
for ( auto it = bindings.constBegin(); it != bindings.constEnd(); ++it )
updateObjectProperty( it.key(), it.value() );
}
}
void updateProperties( const QModelIndex& topLeft,
const QModelIndex& bottomRight, const QVector< int >& roles )
{
if ( !( model && currentRowIndex.isValid() ) )
return;
if ( !( roles.isEmpty() || roles.contains( Qt::EditRole ) ) )
return;
const int row = currentRowIndex.row();
if ( topLeft.row() <= row && row <= bottomRight.row() )
{
for ( auto it = bindings.constBegin(); it != bindings.constEnd(); ++it )
{
const int col = it.value().column;
if( topLeft.column() <= col && col <= bottomRight.column() )
updateObjectProperty( it.key(), it.value() );
}
}
}
void updateObjectProperty( QObject* object, const Binding& binding )
{
const auto index = model->index( currentRowIndex.row(), binding.column );
binding.property.write( object, index.data( Qt::EditRole ) );
}
public:
QMap< QObject*, Binding > bindings;
QPointer< QAbstractItemModel > model;
QPersistentModelIndex currentRowIndex;
};
QskModelObjectBinder::QskModelObjectBinder( QObject* parent )
: QObject( parent )
, m_data( new PrivateData() )
{
}
QskModelObjectBinder::QskModelObjectBinder( QAbstractItemModel* model, QObject* parent )
: QskModelObjectBinder( parent )
{
setModel( model );
}
QskModelObjectBinder::~QskModelObjectBinder()
{
}
void QskModelObjectBinder::bindObject(
QObject* object, int column, const QByteArray& propertyName )
{
if( object == nullptr )
return;
// does not work with dynamic properties ...
const auto metaProperty = qskMetaProperty( object->metaObject(), propertyName );
Q_ASSERT( metaProperty.isValid() );
if ( metaProperty.isValid() )
{
const Binding binding = { column, metaProperty };
m_data->bindings.insert( object, binding );
qskEnableConnections( object, this, true );
if ( m_data->model && m_data->currentRowIndex.isValid() )
m_data->updateObjectProperty( object, binding );
}
}
void QskModelObjectBinder::unbindObject( QObject* object )
{
auto& bindings = m_data->bindings;
auto it = bindings.find( object );
if ( it != bindings.end() )
{
qskEnableConnections( object, this, false );
bindings.erase( it );
}
}
void QskModelObjectBinder::clearBindings()
{
auto& bindings = m_data->bindings;
for ( auto it = bindings.constBegin(); it != bindings.constEnd(); ++it )
qskEnableConnections( it.key(), this, false );
bindings.clear();
}
QObjectList QskModelObjectBinder::boundObjects() const
{
auto& bindings = m_data->bindings;
QObjectList objects;
objects.reserve( bindings.count() );
for ( auto it = bindings.constBegin(); it != bindings.constEnd(); ++it )
objects += it.key();
return objects;
}
QMetaProperty QskModelObjectBinder::boundProperty( const QObject* object ) const
{
auto it = m_data->bindings.constFind( const_cast< QObject* >( object ) );
if ( it != m_data->bindings.constEnd() )
return it.value().property;
return QMetaProperty();
}
void QskModelObjectBinder::setModel( QAbstractItemModel* model )
{
if ( model == m_data->model )
return;
if ( m_data->model )
{
disconnect( m_data->model, &QAbstractItemModel::dataChanged, this, nullptr );
m_data->model = nullptr;
m_data->currentRowIndex = QModelIndex();
clearBindings();
}
m_data->model = model;
if( model )
{
auto updateProperties = [this](
const QModelIndex& topLeft, const QModelIndex& bottomRight,
const QVector< int >& roles )
{
m_data->updateProperties( topLeft, bottomRight, roles );
};
connect( m_data->model, &QAbstractItemModel::dataChanged,
this, updateProperties );
connect( m_data->model, &QObject::destroyed,
this, &QskModelObjectBinder::clearBindings );
setCurrentRow( 0 );
}
}
const QAbstractItemModel* QskModelObjectBinder::model() const
{
return m_data->model;
}
QAbstractItemModel* QskModelObjectBinder::model()
{
return m_data->model;
}
void QskModelObjectBinder::setCurrentRow( int row )
{
auto model = m_data->model.data();
auto& bindings = m_data->bindings;
Q_ASSERT( model != nullptr );
if ( model && row >= 0 && row < model->rowCount() )
{
m_data->currentRowIndex = model->index( row, 0 );
for ( auto it = bindings.constBegin(); it != bindings.constEnd(); ++it )
m_data->updateObjectProperty( it.key(), it.value() );
Q_EMIT currentRowChanged( row );
}
}
int QskModelObjectBinder::currentRow() const
{
return m_data->currentRowIndex.row();
}
void QskModelObjectBinder::submit()
{
if ( auto model = m_data->model )
{
const auto& bindings = m_data->bindings;
for ( auto it = bindings.begin(); it != bindings.end(); ++it )
{
const auto value = it.value().property.read( it.key() );
const auto row = m_data->currentRowIndex.row();
const auto index = model->index( row, it.value().column );
model->setData( index, value );
}
}
}
void QskModelObjectBinder::revert()
{
m_data->updateProperties();
}
#include "moc_QskModelObjectBinder.cpp"

View File

@ -0,0 +1,61 @@
/******************************************************************************
* QSkinny - Copyright (C) The authors
* SPDX-License-Identifier: BSD-3-Clause
*****************************************************************************/
#ifndef QSK_MODEL_OBJECT_BINDER_H
#define QSK_MODEL_OBJECT_BINDER_H
#include "QskGlobal.h"
#include <qobject.h>
#include <qbytearray.h>
#include <memory>
class QAbstractItemModel;
class QMetaProperty;
class QSK_EXPORT QskModelObjectBinder : public QObject
{
Q_OBJECT
Q_PROPERTY( int currentRow READ currentRow
WRITE setCurrentRow NOTIFY currentRowChanged )
public:
QskModelObjectBinder( QObject* parent = nullptr );
QskModelObjectBinder( QAbstractItemModel*, QObject* parent = nullptr );
~QskModelObjectBinder() override;
void setModel( QAbstractItemModel* );
const QAbstractItemModel* model() const;
QAbstractItemModel* model();
void setCurrentRow( int row );
int currentRow() const;
void bindObject( QObject*, int column,
const QByteArray& propertyName = QByteArray() );
void unbindObject( QObject* );
QMetaProperty boundProperty( const QObject* ) const;
QObjectList boundObjects() const;
Q_SIGNALS:
void currentRowChanged( int );
public Q_SLOTS:
void submit();
void revert();
void clearBindings();
private:
class PrivateData;
std::unique_ptr< PrivateData > m_data;
};
#endif

View File

@ -6,7 +6,6 @@
#include "QskPopupSkinlet.h"
#include "QskPopup.h"
#include "QskRgbValue.h"
#include "QskBoxHints.h"
static inline QRgb qskInterpolatedRgb( QRgb rgb, qreal factor )
{
@ -59,9 +58,7 @@ QSGNode* QskPopupSkinlet::updateOverlayNode(
if ( rect.isEmpty() )
return nullptr;
auto hints = popup->boxHints( Q::Overlay );
auto& gradient = hints.gradient;
auto gradient = popup->gradientHint( Q::Overlay );
if ( gradient.isVisible() && factor != 1.0 )
{
@ -73,7 +70,7 @@ QSGNode* QskPopupSkinlet::updateOverlayNode(
gradient.setStops( stops );
}
return updateBoxNode( popup, node, rect, hints );
return updateBoxNode( popup, node, rect, gradient, QskPopup::Overlay );
}
#include "moc_QskPopupSkinlet.cpp"

View File

@ -6,7 +6,7 @@
#include "QskProgressBarSkinlet.h"
#include "QskProgressBar.h"
#include "QskIntervalF.h"
#include "QskBoxHints.h"
#include "QskBoxBorderMetrics.h"
#include <qeasingcurve.h>
#include <cmath>
@ -50,6 +50,41 @@ static QskIntervalF qskFillInterval( const QskProgressIndicator* indicator )
return QskIntervalF( pos1, pos2 );
}
static QskGradient qskFillGradient( const QskProgressBar* progressBar )
{
auto gradient = progressBar->gradientHint( Q::Fill );
if ( gradient.isVisible() && !gradient.isMonochrome()
&& ( gradient.type() == QskGradient::Stops ) )
{
/*
When having stops only we use a linear gradient,
where the colors are increasing in direction of the
progress value. We interprete the gradient as a
definition for the 100% situation and have to adjust
the stops for smaller bars.
For this situation it would be more convenient to
adjust the start/stop positions, but the box renderer is
not supporting this yet. TODO ...
*/
const auto intv = qskFillInterval( progressBar );
const auto stops = qskExtractedGradientStops(
gradient.stops(), intv.lowerBound(), intv.upperBound() );
gradient.setStops( stops );
gradient.setLinearDirection( progressBar->orientation() );
if ( progressBar->orientation() == Qt::Vertical || progressBar->layoutMirroring() )
gradient.reverse();
}
return gradient;
}
QskProgressBarSkinlet::QskProgressBarSkinlet( QskSkin* skin )
: Inherited( skin )
{
@ -87,40 +122,9 @@ QSGNode* QskProgressBarSkinlet::updateFillNode(
if ( rect.isEmpty() )
return nullptr;
auto hints = indicator->boxHints( Q::Fill );
auto& gradient = hints.gradient;
if ( gradient.isVisible() && !gradient.isMonochrome()
&& ( gradient.type() == QskGradient::Stops ) )
{
/*
When having stops only we use a linear gradient,
where the colors are increasing in direction of the
progress value. We interprete the gradient as a
definition for the 100% situation and have to adjust
the stops for smaller bars.
For this situation it would be more convenient to
adjust the start/stop positions, but the box renderer is
not supporting this yet. TODO ...
*/
const auto intv = qskFillInterval( indicator );
const auto stops = qskExtractedGradientStops(
gradient.stops(), intv.lowerBound(), intv.upperBound() );
gradient.setStops( stops );
const auto orientation = static_cast< const Q* >( indicator )->orientation();
gradient.setLinearDirection( orientation );
if ( orientation == Qt::Vertical || indicator->layoutMirroring() )
gradient.reverse();
}
return updateBoxNode( indicator, node, rect, hints );
const auto progressBar = static_cast< const Q* >( indicator );
return updateBoxNode( indicator, node, rect,
qskFillGradient( progressBar ), Q::Fill );
}
QRectF QskProgressBarSkinlet::grooveRect(

View File

@ -4,7 +4,7 @@
*****************************************************************************/
#include "QskProgressRingSkinlet.h"
#include "QskArcHints.h"
#include "QskArcMetrics.h"
#include "QskProgressRing.h"
#include "QskIntervalF.h"
@ -85,12 +85,8 @@ QSGNode* QskProgressRingSkinlet::updateGrooveNode(
endAngle = fillAngles.first - 360.0 + spacing;
}
auto hints = indicator->arcHints( Q::Groove );
hints.metrics.setStartAngle( startAngle );
hints.metrics.setSpanAngle( endAngle - startAngle );
const auto rect = indicator->subControlRect( Q::Groove );
return updateArcNode( ring, node, rect, hints );
return updateArcNode( ring, node,
startAngle, endAngle - startAngle, Q::Groove );
}
}
@ -108,14 +104,16 @@ QSGNode* QskProgressRingSkinlet::updateFillNode(
if ( rect.isEmpty() )
return nullptr;
auto hints = ring->arcHints( subControl );
if ( !hints.isVisible() )
const auto metrics = ring->arcMetricsHint( subControl );
if ( metrics.isNull() )
return nullptr;
auto gradient = ring->gradientHint( subControl );
if ( !gradient.isVisible() )
return nullptr;
const auto intv = qskFillInterval( ring );
auto& gradient = hints.gradient;
if ( ( gradient.type() == QskGradient::Stops ) && !gradient.isMonochrome() )
{
const auto stops = qskExtractedGradientStops( gradient.stops(),
@ -123,15 +121,14 @@ QSGNode* QskProgressRingSkinlet::updateFillNode(
gradient.setStops( stops );
if ( hints.metrics.spanAngle() < 0.0 )
if ( metrics.spanAngle() < 0.0 )
gradient.reverse();
}
const auto angles = qskFillAngles( hints.metrics, intv );
hints.metrics.setStartAngle( angles.first );
hints.metrics.setSpanAngle( angles.second - angles.first );
const auto angles = qskFillAngles( metrics, intv );
return updateArcNode( ring, node, rect, hints );
return updateArcNode( ring, node, rect, gradient,
angles.first, angles.second - angles.first, subControl );
}
QSizeF QskProgressRingSkinlet::sizeHint( const QskSkinnable* skinnable,

View File

@ -6,7 +6,6 @@
#include "QskSeparatorSkinlet.h"
#include "QskSeparator.h"
#include "QskBoxHints.h"
#include "QskGradientDirection.h"
#include "QskAspect.h"
@ -43,12 +42,8 @@ QSGNode* QskSeparatorSkinlet::updateSubNode(
using Q = QskSeparator;
const auto rect = separator->subControlRect( Q::Panel );
if ( rect.isEmpty() )
return nullptr;
auto hints = separator->boxHints( Q::Panel );
auto& gradient = hints.gradient;
auto gradient = separator->gradientHint( Q::Panel );
if ( ( gradient.type() == QskGradient::Stops ) && !gradient.isMonochrome() )
{
// gradient in opposite orientation
@ -58,7 +53,7 @@ QSGNode* QskSeparatorSkinlet::updateSubNode(
gradient.setLinearDirection( orientation );
}
return updateBoxNode( separator, node, rect, hints );
return updateBoxNode( separator, node, rect, gradient, Q::Panel );
}
}

View File

@ -7,7 +7,9 @@
#include "QskArcNode.h"
#include "QskAspect.h"
#include "QskArcHints.h"
#include "QskArcMetrics.h"
#include "QskBoxBorderColors.h"
#include "QskBoxBorderMetrics.h"
#include "QskBoxNode.h"
#include "QskBoxRectangleNode.h"
#include "QskBoxShapeMetrics.h"
@ -154,6 +156,18 @@ static inline bool qskIsBoxVisible( const QskBoxBorderMetrics& borderMetrics,
return !borderMetrics.isNull() && borderColors.isVisible();
}
static inline bool qskIsArcVisible( const QskArcMetrics& arcMetrics,
qreal borderWidth, const QColor borderColor, const QskGradient& gradient )
{
if ( arcMetrics.isNull() )
return false;
if ( borderWidth > 0.0 && borderColor.isValid() && borderColor.alpha() > 0 )
return true;
return gradient.isVisible();
}
static inline bool qskIsLineVisible( const QColor& lineColor, qreal lineWidth )
{
return ( lineWidth > 0.0 ) && lineColor.isValid() && ( lineColor.alpha() > 0 );
@ -188,18 +202,22 @@ static inline QQuickWindow* qskWindowOfSkinnable( const QskSkinnable* skinnable
return nullptr;
}
static inline QSGNode* qskUpdateBoxNode( const QskSkinnable* skinnable,
QSGNode* node, const QRectF& rect, const QskBoxHints& hints )
static inline QSGNode* qskUpdateBoxNode(
const QskSkinnable* skinnable, QSGNode* node, const QRectF& rect,
const QskBoxShapeMetrics& shape, const QskBoxBorderMetrics& borderMetrics,
const QskBoxBorderColors& borderColors, const QskGradient& gradient,
const QskShadowMetrics& shadowMetrics, const QColor& shadowColor )
{
if ( !rect.isEmpty() )
{
if ( qskIsBoxVisible( hints.borderMetrics, hints.borderColors, hints.gradient )
|| qskIsShadowVisible( hints.shadowMetrics, hints.shadowColor ) )
if ( qskIsBoxVisible( borderMetrics, borderColors, gradient )
|| qskIsShadowVisible( shadowMetrics, shadowColor ) )
{
if ( auto window = qskWindowOfSkinnable( skinnable ) )
{
auto boxNode = QskSGNode::ensureNode< QskBoxNode >( node );
boxNode->updateNode( window, rect, hints );
boxNode->updateNode( window, rect, shape, borderMetrics,
borderColors, gradient, shadowMetrics, shadowColor );
return boxNode;
}
@ -209,20 +227,21 @@ static inline QSGNode* qskUpdateBoxNode( const QskSkinnable* skinnable,
return nullptr;
}
static inline QSGNode* qskUpdateArcNode( const QskSkinnable* skinnable,
QSGNode* node, const QRectF& rect, const QskArcHints& hints )
static inline QSGNode* qskUpdateArcNode(
const QskSkinnable*, QSGNode* node, const QRectF& rect,
qreal borderWidth, const QColor borderColor,
const QskGradient& gradient, const QskArcMetrics& metrics )
{
Q_UNUSED( skinnable );
if ( rect.isEmpty() )
return nullptr;
if ( !rect.isEmpty() && hints.isVisible() )
{
auto arcNode = QskSGNode::ensureNode< QskArcNode >( node );
arcNode->setArcData( rect, hints );
if ( !qskIsArcVisible( metrics, borderWidth, borderColor, gradient ) )
return nullptr;
return arcNode;
}
auto arcNode = QskSGNode::ensureNode< QskArcNode >( node );
arcNode->setArcData( rect, metrics, borderWidth, borderColor, gradient );
return nullptr;
return arcNode;
}
static inline QSGNode* qskUpdateLineNode(
@ -415,30 +434,54 @@ void QskSkinlet::replaceChildNode( quint8 role,
QSGNode* QskSkinlet::updateBoxNode( const QskSkinnable* skinnable,
QSGNode* node, QskAspect::Subcontrol subControl ) const
{
auto r = qskSubControlRect( this, skinnable, subControl );
if ( r.isEmpty() )
return nullptr;
r = r.marginsRemoved( skinnable->marginHint( subControl ) );
return qskUpdateBoxNode( skinnable, node,
r, skinnable->boxHints( subControl ) );
const auto rect = qskSubControlRect( this, skinnable, subControl );
return updateBoxNode( skinnable, node, rect, subControl );
}
QSGNode* QskSkinlet::updateBoxNode( const QskSkinnable* skinnable,
QSGNode* node, const QRectF& rect, QskAspect::Subcontrol subControl )
{
if ( rect.isEmpty() )
const auto fillGradient = skinnable->gradientHint( subControl );
return updateBoxNode( skinnable, node, rect, fillGradient, subControl );
}
QSGNode* QskSkinlet::updateBoxNode( const QskSkinnable* skinnable,
QSGNode* node, const QRectF& rect, const QskGradient& fillGradient,
QskAspect::Subcontrol subControl )
{
const auto margins = skinnable->marginHint( subControl );
const auto boxRect = rect.marginsRemoved( margins );
if ( boxRect.isEmpty() )
return nullptr;
const auto r = rect.marginsRemoved( skinnable->marginHint( subControl ) );
return qskUpdateBoxNode( skinnable, node, r, skinnable->boxHints( subControl ) );
const auto borderMetrics = skinnable->boxBorderMetricsHint( subControl );
const auto borderColors = skinnable->boxBorderColorsHint( subControl );
const auto shape = skinnable->boxShapeHint( subControl );
const auto shadowMetrics = skinnable->shadowMetricsHint( subControl );
const auto shadowColor = skinnable->shadowColorHint( subControl );
return qskUpdateBoxNode( skinnable, node,
boxRect, shape, borderMetrics, borderColors, fillGradient,
shadowMetrics, shadowColor );
}
QSGNode* QskSkinlet::updateBoxNode(
const QskSkinnable* skinnable, QSGNode* node, const QRectF& rect,
const QskBoxShapeMetrics& shape, const QskBoxBorderMetrics& borderMetrics,
const QskBoxBorderColors& borderColors, const QskGradient& fillGradient )
{
return qskUpdateBoxNode( skinnable, node,
rect, shape, borderMetrics, borderColors, fillGradient,
QskShadowMetrics(), QColor() );
}
QSGNode* QskSkinlet::updateBoxNode( const QskSkinnable* skinnable,
QSGNode* node, const QRectF& rect, const QskBoxHints& hints )
{
return qskUpdateBoxNode( skinnable, node, rect, hints );
return qskUpdateBoxNode( skinnable, node, rect,
hints.shape, hints.borderMetrics, hints.borderColors, hints.gradient,
hints.shadowMetrics, hints.shadowColor );
}
QSGNode* QskSkinlet::updateInterpolatedBoxNode(
@ -483,24 +526,79 @@ QSGNode* QskSkinlet::updateInterpolatedBoxNode(
QSGNode* QskSkinlet::updateArcNode( const QskSkinnable* skinnable,
QSGNode* node, QskAspect::Subcontrol subControl ) const
{
auto rect = qskSubControlRect( this, skinnable, subControl );
rect = rect.marginsRemoved( skinnable->marginHint( subControl ) );
return qskUpdateArcNode( skinnable,
node, rect, skinnable->arcHints( subControl ) );
}
QSGNode* QskSkinlet::updateArcNode( const QskSkinnable* skinnable,
QSGNode* node, const QRectF& rect, const QskArcHints& hints )
{
return qskUpdateArcNode( skinnable, node, rect, hints );
const auto rect = qskSubControlRect( this, skinnable, subControl );
return updateArcNode( skinnable, node, rect, subControl );
}
QSGNode* QskSkinlet::updateArcNode( const QskSkinnable* skinnable,
QSGNode* node, const QRectF& rect, QskAspect::Subcontrol subControl )
{
const auto fillGradient = skinnable->gradientHint( subControl );
return updateArcNode( skinnable, node, rect, fillGradient, subControl );
}
QSGNode* QskSkinlet::updateArcNode( const QskSkinnable* skinnable,
QSGNode* node, const QRectF& rect, const QskGradient& fillGradient,
QskAspect::Subcontrol subControl )
{
const auto metrics = skinnable->arcMetricsHint( subControl );
const auto r = rect.marginsRemoved( skinnable->marginHint( subControl ) );
const qreal borderWidth = skinnable->metric( subControl | QskAspect::Border );
QColor borderColor;
if ( borderWidth > 0.0 )
borderColor = skinnable->color( subControl | QskAspect::Border );
return qskUpdateArcNode( skinnable, node,
rect, skinnable->arcHints( subControl ) );
r, borderWidth, borderColor, fillGradient, metrics );
}
QSGNode* QskSkinlet::updateArcNode(
const QskSkinnable* skinnable, QSGNode* node, const QRectF& rect,
qreal borderWidth, const QColor& borderColor,
const QskGradient& fillGradient, const QskArcMetrics& metrics )
{
return qskUpdateArcNode( skinnable, node, rect,
borderWidth, borderColor, fillGradient, metrics );
}
QSGNode* QskSkinlet::updateArcNode( const QskSkinnable* skinnable,
QSGNode* node, qreal startAngle, qreal spanAngle,
QskAspect::Subcontrol subControl ) const
{
const auto rect = qskSubControlRect( this, skinnable, subControl );
return updateArcNode( skinnable, node,
rect, startAngle, spanAngle, subControl );
}
QSGNode* QskSkinlet::updateArcNode( const QskSkinnable* skinnable,
QSGNode* node, const QRectF& rect, qreal startAngle, qreal spanAngle,
QskAspect::Subcontrol subControl )
{
const auto fillGradient = skinnable->gradientHint( subControl );
return updateArcNode( skinnable, node, rect,
fillGradient, startAngle, spanAngle, subControl );
}
QSGNode* QskSkinlet::updateArcNode( const QskSkinnable* skinnable,
QSGNode* node, const QRectF& rect, const QskGradient& fillGradient,
qreal startAngle, qreal spanAngle, QskAspect::Subcontrol subControl )
{
auto arcMetrics = skinnable->arcMetricsHint( subControl );
arcMetrics.setStartAngle( startAngle );
arcMetrics.setSpanAngle( spanAngle );
const qreal borderWidth = skinnable->metric( subControl | QskAspect::Border );
QColor borderColor;
if ( borderWidth > 0.0 )
borderColor = skinnable->color( subControl | QskAspect::Border );
const auto r = rect.marginsRemoved( skinnable->marginHint( subControl ) );
return updateArcNode( skinnable, node, r,
borderWidth, borderColor, fillGradient, arcMetrics );
}
QSGNode* QskSkinlet::updateLineNode( const QskSkinnable* skinnable,

View File

@ -23,8 +23,10 @@ class QskColorFilter;
class QskGraphic;
class QskTextOptions;
class QskTextColors;
class QskBoxShapeMetrics;
class QskBoxBorderMetrics;
class QskBoxBorderColors;
class QskBoxHints;
class QskArcHints;
class QSGNode;
@ -74,6 +76,13 @@ class QSK_EXPORT QskSkinlet
static QSGNode* updateBoxNode( const QskSkinnable*, QSGNode*,
const QRectF&, QskAspect::Subcontrol );
static QSGNode* updateBoxNode( const QskSkinnable*, QSGNode*,
const QRectF&, const QskGradient&, QskAspect::Subcontrol );
static QSGNode* updateBoxNode( const QskSkinnable*, QSGNode*,
const QRectF&, const QskBoxShapeMetrics&, const QskBoxBorderMetrics&,
const QskBoxBorderColors&, const QskGradient& );
static QSGNode* updateBoxNode( const QskSkinnable*, QSGNode*,
const QRectF&, const QskBoxHints& );
@ -85,7 +94,18 @@ class QSK_EXPORT QskSkinlet
const QRectF&, QskAspect::Subcontrol );
static QSGNode* updateArcNode( const QskSkinnable*, QSGNode*,
const QRectF&, const QskArcHints& );
const QRectF&, const QskGradient&, QskAspect::Subcontrol );
static QSGNode* updateArcNode( const QskSkinnable*, QSGNode*,
const QRectF&, qreal borderWidth, const QColor& borderColor,
const QskGradient&, const QskArcMetrics& );
static QSGNode* updateArcNode( const QskSkinnable*, QSGNode*,
const QRectF&, qreal startAngle, qreal spanAngle, QskAspect::Subcontrol );
static QSGNode* updateArcNode( const QskSkinnable*, QSGNode*,
const QRectF&, const QskGradient&, qreal startAngle, qreal spanAngle,
QskAspect::Subcontrol );
static QSGNode* updateLineNode( const QskSkinnable*, QSGNode*,
const QLineF&, QskAspect::Subcontrol );
@ -136,6 +156,10 @@ class QSK_EXPORT QskSkinlet
QSGNode* updateArcNode( const QskSkinnable*, QSGNode*,
QskAspect::Subcontrol ) const;
QSGNode* updateArcNode( const QskSkinnable*, QSGNode*,
qreal startAngle, qreal spanAngle,
QskAspect::Subcontrol ) const;
QSGNode* updateBoxClipNode( const QskSkinnable*, QSGNode*,
QskAspect::Subcontrol ) const;

View File

@ -6,7 +6,7 @@
#include "QskSkinnable.h"
#include "QskAnimationHint.h"
#include "QskArcHints.h"
#include "QskArcMetrics.h"
#include "QskAspect.h"
#include "QskColorFilter.h"
#include "QskControl.h"
@ -637,23 +637,9 @@ QColor QskSkinnable::shadowColorHint( QskAspect aspect, QskSkinHintStatus* statu
QskBoxHints QskSkinnable::boxHints( QskAspect aspect ) const
{
return QskBoxHints(
boxShapeHint( aspect ),
boxBorderMetricsHint( aspect ),
boxBorderColorsHint( aspect ),
gradientHint( aspect ),
shadowMetricsHint( aspect ),
shadowColorHint( aspect )
);
}
QskArcHints QskSkinnable::arcHints( QskAspect aspect ) const
{
return QskArcHints(
arcMetricsHint( aspect ),
metric( aspect | QskAspect::Border ),
color( aspect | QskAspect::Border ),
gradientHint( aspect )
);
boxShapeHint( aspect ), boxBorderMetricsHint( aspect ),
boxBorderColorsHint( aspect ), gradientHint( aspect ),
shadowMetricsHint( aspect ), shadowColorHint( aspect ) );
}
bool QskSkinnable::setArcMetricsHint(

View File

@ -22,7 +22,6 @@ class QDebug;
class QSGNode;
class QQuickItem;
class QskArcHints;
class QskArcMetrics;
class QskControl;
class QskAnimationHint;
@ -227,7 +226,6 @@ class QSK_EXPORT QskSkinnable
QColor shadowColorHint( QskAspect, QskSkinHintStatus* = nullptr ) const;
QskBoxHints boxHints( QskAspect ) const;
QskArcHints arcHints( QskAspect ) const;
bool setArcMetricsHint( QskAspect, const QskArcMetrics& );
bool resetArcMetricsHint( QskAspect );

View File

@ -197,23 +197,6 @@ bool QskSlider::hasOrigin() const
return m_data->hasOrigin;
}
void QskSlider::setTickPolicy( Qsk::Policy policy )
{
if ( setFlagHint( Tick | QskAspect::Option, policy ) )
Q_EMIT tickPolicyChanged( policy );
}
void QskSlider::resetTickPolicy()
{
if ( resetSkinHint( Tick | QskAspect::Option ) )
Q_EMIT tickPolicyChanged( tickPolicy() );
}
Qsk::Policy QskSlider::tickPolicy() const
{
return flagHint< Qsk::Policy >( Tick | QskAspect::Option, Qsk::Maybe );
}
QskAspect::Variation QskSlider::effectiveVariation() const
{
return static_cast< QskAspect::Variation >( m_data->orientation );

View File

@ -22,9 +22,6 @@ class QSK_EXPORT QskSlider : public QskBoundedValueInput
Q_PROPERTY( bool tracking READ isTracking
WRITE setTracking NOTIFY trackingChanged )
Q_PROPERTY( Qsk::Policy tickPolicy READ tickPolicy
WRITE setTickPolicy RESET resetTickPolicy NOTIFY tickPolicyChanged )
Q_PROPERTY( qreal origin READ origin
WRITE setOrigin RESET resetOrigin NOTIFY originChanged )
@ -42,10 +39,6 @@ class QSK_EXPORT QskSlider : public QskBoundedValueInput
void setOrientation( Qt::Orientation );
Qt::Orientation orientation() const;
void setTickPolicy( Qsk::Policy );
void resetTickPolicy();
Qsk::Policy tickPolicy() const;
void setInverted( bool );
bool isInverted() const;
@ -68,7 +61,6 @@ class QSK_EXPORT QskSlider : public QskBoundedValueInput
void invertedChanged( bool );
void trackingChanged( bool );
void originChanged( qreal );
void tickPolicyChanged( Qsk::Policy );
protected:
void mousePressEvent( QMouseEvent* ) override;

View File

@ -388,7 +388,10 @@ bool QskSliderSkinlet::hasGraduation( const QskSlider* slider ) const
{
if ( slider->stepSize() )
{
switch( slider->tickPolicy() )
const auto policy = slider->flagHint< Qsk::Policy >(
Q::Tick | QskAspect::Option, Qsk::Never );
switch( policy )
{
case Qsk::Always:
return true;

View File

@ -129,7 +129,7 @@ namespace
{
if ( qskIsAncestorOf( this, item ) )
{
const auto pos = mapFromItem( item, QPointF() ) + scrollPos();
const auto pos = mapFromItem( item, QPointF() );
ensureVisible( QRectF( pos.x(), pos.y(), item->width(), item->height() ) );
}
}

View File

@ -13,7 +13,6 @@
#include "QskGraduationMetrics.h"
#include "QskColorFilter.h"
#include "QskGradient.h"
#include "QskGradientStop.h"
#include "QskMargins.h"
#include "QskIntervalF.h"
#include "QskTextColors.h"
@ -44,7 +43,6 @@ static void qskRegisterInterpolator()
qRegisterAnimationInterpolator< QskColorFilter >( QskColorFilter::interpolate );
qRegisterAnimationInterpolator< QskIntervalF >( QskIntervalF::interpolate );
qRegisterAnimationInterpolator< QskMargins >( QskMargins::interpolate );
qRegisterAnimationInterpolator< QskGradientStop >( QskGradientStop::interpolate );
qRegisterAnimationInterpolator< QskGradient >( QskGradient::interpolate );
qRegisterAnimationInterpolator< QskBoxShapeMetrics >( QskBoxShapeMetrics::interpolate );
qRegisterAnimationInterpolator< QskBoxBorderMetrics >( QskBoxBorderMetrics::interpolate );

View File

@ -4,10 +4,11 @@
*****************************************************************************/
#include "QskArcNode.h"
#include "QskArcHints.h"
#include "QskArcMetrics.h"
#include "QskArcRenderNode.h"
#include "QskArcRenderer.h"
#include "QskMargins.h"
#include "QskGradient.h"
#include "QskSGNode.h"
#include "QskRgbValue.h"
@ -57,21 +58,24 @@ QskArcNode::~QskArcNode()
{
}
void QskArcNode::setArcData( const QRectF& rect, const QskArcHints& hints )
void QskArcNode::setArcData( const QRectF& rect,
const QskArcMetrics& arcMetrics, const QskGradient& gradient )
{
setArcData( rect, arcMetrics, 0.0, QColor(), gradient );
}
void QskArcNode::setArcData( const QRectF& rect, const QskArcMetrics& arcMetrics,
const qreal borderWidth, const QColor& borderColor, const QskGradient& gradient )
{
using namespace QskSGNode;
QskArcRenderNode* arcNode = nullptr;
QskArcRenderNode* fillNode = nullptr;
if ( !rect.isEmpty() && hints.isVisible() )
if ( !( rect.isEmpty() || arcMetrics.isNull() ) )
{
const auto& gradient = hints.gradient;
const auto borderWidth = hints.borderWidth;
const auto borderColor = hints.borderColor;
const bool radial = false;
const auto metricsArc = hints.metrics.toAbsolute( rect.size() );
const auto metricsArc = arcMetrics.toAbsolute( rect.size() );
const auto hasFilling = gradient.isVisible();
const auto hasBorder = ( borderWidth > 0.0 ) && QskRgb::isVisible( borderColor );

View File

@ -9,7 +9,8 @@
#include "QskGlobal.h"
#include <qsgnode.h>
class QskArcHints;
class QskArcMetrics;
class QskGradient;
class QSK_EXPORT QskArcNode : public QSGNode
{
@ -17,7 +18,10 @@ class QSK_EXPORT QskArcNode : public QSGNode
QskArcNode();
~QskArcNode() override;
void setArcData( const QRectF&, const QskArcHints& );
void setArcData( const QRectF&, const QskArcMetrics&, const QskGradient& );
void setArcData( const QRectF&, const QskArcMetrics&,
qreal borderWidth, const QColor& borderColor, const QskGradient& );
};
#endif

View File

@ -8,8 +8,12 @@
#include "QskBoxRectangleNode.h"
#include "QskSGNode.h"
#include "QskBoxHints.h"
#include "QskGradient.h"
#include "QskGradientDirection.h"
#include "QskShadowMetrics.h"
#include "QskBoxBorderMetrics.h"
#include "QskBoxBorderColors.h"
#include "QskBoxShapeMetrics.h"
#include "QskRgbValue.h"
namespace
@ -56,8 +60,10 @@ QskBoxNode::~QskBoxNode()
{
}
void QskBoxNode::updateNode( const QQuickWindow* window,
const QRectF& rect, const QskBoxHints& hints )
void QskBoxNode::updateNode( const QQuickWindow* window, const QRectF& rect,
const QskBoxShapeMetrics& shapeMetrics, const QskBoxBorderMetrics& borderMetrics,
const QskBoxBorderColors& borderColors, const QskGradient& gradient,
const QskShadowMetrics& shadowMetrics, const QColor& shadowColor )
{
using namespace QskSGNode;
@ -68,13 +74,6 @@ void QskBoxNode::updateNode( const QQuickWindow* window,
if ( !rect.isEmpty() )
{
const auto& shapeMetrics = hints.shape;
const auto& borderMetrics = hints.borderMetrics;
const auto& borderColors = hints.borderColors;
const auto& gradient = hints.gradient;
const auto& shadowMetrics = hints.shadowMetrics;
const auto& shadowColor = hints.shadowColor;
const auto hasFilling = gradient.isVisible();
const auto hasBorder = !borderMetrics.isNull() && borderColors.isVisible();
const auto hasShadow = !shadowMetrics.isNull() && QskRgb::isVisible( shadowColor );

View File

@ -9,8 +9,14 @@
#include "QskGlobal.h"
#include <qsgnode.h>
class QskBoxHints;
class QskShadowMetrics;
class QskBoxShapeMetrics;
class QskBoxBorderMetrics;
class QskBoxBorderColors;
class QskGradient;
class QskShadowMetrics;
class QQuickWindow;
class QColor;
class QSK_EXPORT QskBoxNode : public QSGNode
{
@ -18,7 +24,10 @@ class QSK_EXPORT QskBoxNode : public QSGNode
QskBoxNode();
~QskBoxNode() override;
void updateNode( const QQuickWindow*, const QRectF&, const QskBoxHints& );
void updateNode( const QQuickWindow*, const QRectF&,
const QskBoxShapeMetrics&, const QskBoxBorderMetrics&,
const QskBoxBorderColors&, const QskGradient&,
const QskShadowMetrics&, const QColor& shadowColor );
};
#endif

View File

@ -54,16 +54,16 @@ namespace
}
#if QT_VERSION >= QT_VERSION_CHECK( 6, 0, 0 )
// make Qt 5/6 APIs matching
QSGMaterialShader* createShader(
QSGRendererInterface::RenderMode ) const override final
#else
QSGMaterialShader* createShader() const override final
#endif
{
return createMaterialShader();
return createShader();
}
virtual QSGMaterialShader* createMaterialShader() const = 0;
virtual QSGMaterialShader* createShader() const = 0;
#endif
virtual bool setGradient( const QskGradient& ) = 0;
};
@ -217,7 +217,7 @@ namespace
return GradientMaterial::compare( other );
}
QSGMaterialShader* createMaterialShader() const override;
QSGMaterialShader* createShader() const override;
/*
xy: position
@ -299,7 +299,7 @@ namespace
};
#endif
QSGMaterialShader* LinearMaterial::createMaterialShader() const
QSGMaterialShader* LinearMaterial::createShader() const
{
#if QT_VERSION < QT_VERSION_CHECK( 6, 0, 0 )
if ( !( flags() & QSGMaterial::RhiShaderWanted ) )
@ -371,7 +371,7 @@ namespace
}
}
QSGMaterialShader* createMaterialShader() const override;
QSGMaterialShader* createShader() const override;
QVector2D m_center;
QVector2D m_radius;
@ -465,7 +465,7 @@ namespace
};
#endif
QSGMaterialShader* RadialMaterial::createMaterialShader() const
QSGMaterialShader* RadialMaterial::createShader() const
{
#ifdef SHADER_GL
if ( !( flags() & QSGMaterial::RhiShaderWanted ) )
@ -575,7 +575,7 @@ namespace
return GradientMaterial::compare( other );
}
QSGMaterialShader* createMaterialShader() const override;
QSGMaterialShader* createShader() const override;
QVector2D m_center;
float m_aspectRatio = 1.0;
@ -685,7 +685,7 @@ namespace
};
#endif
QSGMaterialShader* ConicMaterial::createMaterialShader() const
QSGMaterialShader* ConicMaterial::createShader() const
{
#ifdef SHADER_GL
if ( !( flags() & QSGMaterial::RhiShaderWanted ) )