Compare commits

..

61 Commits

Author SHA1 Message Date
Uwe Rathmann d1153d3707 Merge branch 'master' into features/effectnode 2025-02-28 09:24:18 +01:00
Uwe Rathmann 3834597d51 Merge branch 'master' into features/effectnode 2025-02-18 16:23:18 +01:00
Uwe Rathmann 4438498e6f Merge branch 'master' into features/effectnode 2025-02-06 13:51:58 +01:00
Uwe Rathmann 92a8c7e395 compiler warnings fixed 2025-02-06 10:25:21 +01:00
Uwe Rathmann e8657d72ff Merge branch 'master' into features/effectnode 2025-02-06 10:21:21 +01:00
Uwe Rathmann c5bdecce00 Merge branch 'master' into features/effectnode 2024-12-10 14:11:51 +01:00
Uwe Rathmann 9cedf5f71b Merge branch 'master' into features/effectnode 2024-12-02 10:11:07 +01:00
Uwe Rathmann f0c8de601f Merge branch 'master' into features/effectnode 2024-09-17 17:42:18 +02:00
Uwe Rathmann 621923c5dd Merge branch 'master' into features/effectnode 2024-09-11 18:21:39 +02:00
Uwe Rathmann c3aea9a4a3 Merge branch 'master' into features/effectnode 2024-01-30 17:10:47 +01:00
Rick Vogel fb4494bdbb fix M_PI by using qmath 2024-01-29 11:57:54 +01:00
Uwe Rathmann 3121f0b5c7 Merge branch 'master' into features/effectnode 2024-01-17 16:06:36 +01:00
Uwe Rathmann cb583abc38 Merge branch 'master' into features/effectnode 2024-01-08 16:33:00 +01:00
Uwe Rathmann 242f063925 building the qsb files with make 2024-01-08 16:32:18 +01:00
Uwe Rathmann d397e4f26a Merge branch 'master' into features/effectnode 2024-01-08 16:09:35 +01:00
Uwe Rathmann 02a63cdd76 using subControlRect 2023-12-29 08:50:46 +01:00
Uwe Rathmann e49da68ab3 Merge branch 'master' into features/effectnode 2023-12-28 17:27:35 +01:00
Uwe Rathmann dd1136a32b Merge branch 'master' into features/effectnode 2023-12-28 17:03:30 +01:00
Uwe Rathmann bba0a680bf blocking updates for nodes that are not part of the QskSceneTexture 2023-12-28 16:57:58 +01:00
Uwe Rathmann 56b1ecf707 comparisonKey fixed 2023-12-28 16:37:13 +01:00
Uwe Rathmann cb9b83bbca returning the effective ( not the intended ) size of the texture 2023-12-28 16:35:27 +01:00
Uwe Rathmann ccb79967f4 update problem with legacy Qt5 OpenGL code fixed 2023-12-28 16:29:29 +01:00
Uwe Rathmann a79650a76e Merge branch 'master' into features/effectnode 2023-12-27 09:02:01 +01:00
Uwe Rathmann ac2ee95962 rgbswap shader also for Qt5 2023-12-27 09:01:37 +01:00
Uwe Rathmann 880ae2abdf Merge branch 'master' into features/effectnode 2023-12-22 14:16:33 +01:00
Uwe Rathmann 6ad68a6da8 Qt5/RHI supported 2023-12-22 13:57:45 +01:00
Uwe Rathmann e1069d9292 Merge branch 'master' into features/effectnode 2023-12-22 13:54:46 +01:00
Uwe Rathmann ec5bb05f4a Merge branch 'master' into features/effectnode 2023-12-21 18:38:57 +01:00
Uwe Rathmann 0b0933122c beatified 2023-12-21 09:04:32 +01:00
Uwe Rathmann 5e0eaf9f6d wip 2023-12-21 09:03:19 +01:00
Uwe Rathmann 4184e4ccf8 wip 2023-12-21 08:58:38 +01:00
Uwe Rathmann 583cf4e87f update issues fixed 2023-12-21 07:14:55 +01:00
Uwe Rathmann f3ee4749b8 Qt5 updates fixed 2023-12-20 11:19:48 +01:00
Uwe Rathmann f9674760c0 Material classes reorganized 2023-12-19 18:37:34 +01:00
Uwe Rathmann 717960f15f texture flip fixed 2023-12-19 12:46:17 +01:00
Uwe Rathmann 862e566507 Squashed commit of the following:
commit 84b7cb31a62edee3ceae702ce52be68cbe222f8a
Author: Uwe Rathmann <Uwe.Rathmann@tigertal.de>
Date:   Tue Dec 19 12:30:23 2023 +0100

    wip

commit 07c4b93e0611298e5e3981017c988fc7e45b6977
Author: Uwe Rathmann <Uwe.Rathmann@tigertal.de>
Date:   Tue Dec 19 12:21:55 2023 +0100

    wip

commit 019448f5e1ea6eed7b767f09ae7fdb0802928a98
Author: Uwe Rathmann <Uwe.Rathmann@tigertal.de>
Date:   Tue Dec 19 12:01:01 2023 +0100

    wip

commit b79f5cba8abc50bd487f08480a62d5c8bcc3c148
Author: Uwe Rathmann <Uwe.Rathmann@tigertal.de>
Date:   Tue Dec 19 11:50:55 2023 +0100

    wip

commit 942291edb6016f29fb2f5c786b84fb7defa10ae2
Author: Uwe Rathmann <Uwe.Rathmann@tigertal.de>
Date:   Tue Dec 19 11:23:28 2023 +0100

    wip

commit 5ae203a03a8413416f723155bf364190937929da
Author: Uwe Rathmann <Uwe.Rathmann@tigertal.de>
Date:   Tue Dec 19 11:23:16 2023 +0100

    wip

commit b5b4453be94c9bdc6655370c949b096061ad1c3a
Author: Uwe Rathmann <Uwe.Rathmann@tigertal.de>
Date:   Tue Dec 19 11:04:15 2023 +0100

    wip

commit cd519b840c6436bdec74a6a92cc5ba69a3f162de
Author: Uwe Rathmann <Uwe.Rathmann@tigertal.de>
Date:   Tue Dec 19 10:50:13 2023 +0100

    wip

commit 9daed04a2c1dde10340764b6ea7769598edeff3d
Author: Uwe Rathmann <Uwe.Rathmann@tigertal.de>
Date:   Tue Dec 19 09:46:10 2023 +0100

    wip

commit c6190b84dde26b4e2790f8154ed3d81db4630b3b
Author: Uwe Rathmann <Uwe.Rathmann@tigertal.de>
Date:   Tue Dec 19 09:34:28 2023 +0100

    wip

commit 837b14e8f688a29aa3294eaaa0c0dbfe66f95dce
Author: Uwe Rathmann <Uwe.Rathmann@tigertal.de>
Date:   Tue Dec 19 09:23:01 2023 +0100

    wip

commit 6486c343a8cfa2a56370f20374939180b576ce2a
Author: Uwe Rathmann <Uwe.Rathmann@tigertal.de>
Date:   Tue Dec 19 08:41:40 2023 +0100

    wip

commit 230aca347b97c0a1bdb75fad6d52153688941aa6
Author: Uwe Rathmann <Uwe.Rathmann@tigertal.de>
Date:   Tue Dec 19 08:37:56 2023 +0100

    wip

commit ec4018de7e8d1940a2e693e9e8183413e02f06c2
Author: Uwe Rathmann <Uwe.Rathmann@tigertal.de>
Date:   Tue Dec 19 08:33:22 2023 +0100

    wip

commit bc3480a01f34d2e92b2445f5e73c0f12262f63a0
Author: Uwe Rathmann <Uwe.Rathmann@tigertal.de>
Date:   Tue Dec 19 08:30:41 2023 +0100

    wip

commit dd896518938f7828f3bc5b5275fccb90d34b08a3
Author: Uwe Rathmann <Uwe.Rathmann@tigertal.de>
Date:   Tue Dec 19 07:50:13 2023 +0100

    wip

commit c534c54ff8af674a45669bc4b688f3a28448a055
Author: Uwe Rathmann <Uwe.Rathmann@tigertal.de>
Date:   Tue Dec 19 07:07:19 2023 +0100

    wip

commit bd7af3f28e8a1a79590acb9be41e0ac9046f1fbc
Author: Uwe Rathmann <Uwe.Rathmann@tigertal.de>
Date:   Mon Dec 18 17:50:34 2023 +0100

    wip

commit 639926d3beccdc49aa98db5fe53f5eb70694a763
Author: Uwe Rathmann <Uwe.Rathmann@tigertal.de>
Date:   Mon Dec 18 17:48:16 2023 +0100

    wip

commit b74c790aa15a23cf3d5875f6280407170d2113bb
Author: Uwe Rathmann <Uwe.Rathmann@tigertal.de>
Date:   Mon Dec 18 17:35:51 2023 +0100

    wip

commit 1403da5a05c5782567b8e34e9a6672e041b483ed
Author: Uwe Rathmann <Uwe.Rathmann@tigertal.de>
Date:   Mon Dec 18 16:52:45 2023 +0100

    wip

commit 74d69d44fc8876d95d25c1e5ab96dcf416f93a0e
Author: Uwe Rathmann <Uwe.Rathmann@tigertal.de>
Date:   Mon Dec 18 16:04:22 2023 +0100

    wip

commit 81269cab9a4a2f07b86442c0b5524b0364909124
Author: Uwe Rathmann <Uwe.Rathmann@tigertal.de>
Date:   Mon Dec 18 15:50:08 2023 +0100

    wip

commit a4f0b8c98960155ee8174e0b5253affc73881158
Author: Uwe Rathmann <Uwe.Rathmann@tigertal.de>
Date:   Mon Dec 18 15:49:54 2023 +0100

    wip

commit fc9c5f032671d9b2b8798c97e3803ef8cb98e647
Author: Uwe Rathmann <Uwe.Rathmann@tigertal.de>
Date:   Mon Dec 18 15:39:34 2023 +0100

    wip

commit 2ca8789fed5ee98355662933fed04e8ed9b5e164
Author: Uwe Rathmann <Uwe.Rathmann@tigertal.de>
Date:   Mon Dec 18 15:28:53 2023 +0100

    wip

commit 3a325b6dab6ee558d6d0407c4e7c639575da4f6d
Author: Uwe Rathmann <Uwe.Rathmann@tigertal.de>
Date:   Mon Dec 18 15:24:42 2023 +0100

    wip

commit 102f872db8a158274de674230f23573f941bed23
Author: Uwe Rathmann <Uwe.Rathmann@tigertal.de>
Date:   Mon Dec 18 15:22:26 2023 +0100

    wip

commit 829eb67b0e6351e77f702acab90705f3cb3e9b4a
Author: Uwe Rathmann <Uwe.Rathmann@tigertal.de>
Date:   Mon Dec 18 14:39:31 2023 +0100

    wip

commit 5f89fc9257fdbd169c5f80d6776aa707848dd5c3
Author: Uwe Rathmann <Uwe.Rathmann@tigertal.de>
Date:   Mon Dec 18 14:18:18 2023 +0100

    wip

commit 4b9e2964c3cc3d4b08e55e98ea5b7b06b169b5f2
Author: Uwe Rathmann <Uwe.Rathmann@tigertal.de>
Date:   Mon Dec 18 13:21:48 2023 +0100

    wip

commit 8c94d26ed98d906a010401d7357e45249d9b11e8
Author: Uwe Rathmann <Uwe.Rathmann@tigertal.de>
Date:   Mon Dec 18 12:42:51 2023 +0100

    wip

commit 096180f6034f93725ebc9d97b8934dcca6e4b41d
Author: Uwe Rathmann <Uwe.Rathmann@tigertal.de>
Date:   Mon Dec 18 12:15:04 2023 +0100

    wip

commit f9f794a19e9b9d6455793a6c61c26e5e1d0e12e0
Author: Uwe Rathmann <Uwe.Rathmann@tigertal.de>
Date:   Mon Dec 18 11:34:07 2023 +0100

    wip

commit 8b5a8c859503b3b155737b975fb344b2dc87bf94
Author: Uwe Rathmann <Uwe.Rathmann@tigertal.de>
Date:   Mon Dec 18 11:32:03 2023 +0100

    wip

commit 67f78561f3bae7c4a779d75921cfabbebf802f9b
Author: Uwe Rathmann <Uwe.Rathmann@tigertal.de>
Date:   Mon Dec 18 11:29:32 2023 +0100

    wip

commit ad6515a95ea6803698f76c221c10f4160e82a668
Author: Uwe Rathmann <Uwe.Rathmann@tigertal.de>
Date:   Mon Dec 18 11:19:28 2023 +0100

    wip

commit 2e719e809f29f07dc38ae2f3213e10bbb730c968
Author: Uwe Rathmann <Uwe.Rathmann@tigertal.de>
Date:   Mon Dec 18 11:16:43 2023 +0100

    wip

commit 2212e09f165130e1621df564aa37bdbefe7377db
Author: Uwe Rathmann <Uwe.Rathmann@tigertal.de>
Date:   Mon Dec 18 11:16:00 2023 +0100

    wip

commit 171aae01c802ad10ad268e35da3dcd33fc6c2b6c
Author: Uwe Rathmann <Uwe.Rathmann@tigertal.de>
Date:   Mon Dec 18 10:52:06 2023 +0100

    wip

commit ab117a43f0a405f4c09f1c395ab215bbcb09a57e
Author: Uwe Rathmann <Uwe.Rathmann@tigertal.de>
Date:   Mon Dec 18 10:47:41 2023 +0100

    wip
2023-12-19 12:45:40 +01:00
Uwe Rathmann 361b5d532e BlurringNode -> TextureFilterNode 2023-12-18 09:39:17 +01:00
Uwe Rathmann 0df5775e3e Overlay supports the box model now 2023-12-18 09:02:45 +01:00
Uwe Rathmann d9ebaa8b03 Merge branch 'master' into features/effectnode 2023-12-17 18:13:52 +01:00
Uwe Rathmann 7f410a0781 synced with master 2023-12-17 17:35:30 +01:00
Uwe Rathmann a286603676 Merge branch 'master' into features/effectnode 2023-12-17 17:32:57 +01:00
Uwe Rathmann 26a05e9b7b Merge branch 'master' into features/effectnode 2023-12-17 17:28:50 +01:00
Uwe Rathmann 450d20ec5a Merge branch 'master' into features/effectnode 2023-12-17 17:19:48 +01:00
Uwe Rathmann 908d302236 better no QSGDynamicTexture 2023-12-17 16:20:20 +01:00
Uwe Rathmann 06a32bf29b forgotten changes committed 2023-12-17 15:54:53 +01:00
Uwe Rathmann e75445e17d Overlay as QskControl 2023-12-17 12:33:23 +01:00
Uwe Rathmann e0acd82619 classes moved from parrot to src/nodes 2023-12-16 12:27:09 +01:00
Uwe Rathmann 3e32a14264 using a rgbswap for the moment 2023-12-15 19:16:28 +01:00
Uwe Rathmann 7837ff6c8c SceneTexture is blocking trailing nodes 2023-12-15 12:54:13 +01:00
Uwe Rathmann 728dffd1df work in progress 2023-12-14 13:01:23 +01:00
Uwe Rathmann f4fdc125e6 Squashed commit of the following:
commit 1a5e9421d9d74ebd257fc5404687bd21bea62503
Author: Uwe Rathmann <Uwe.Rathmann@tigertal.de>
Date:   Thu Dec 14 12:59:10 2023 +0100

    wip

commit db4a97a79ca5ff4f9a39223c7601d5d173862f70
Author: Uwe Rathmann <Uwe.Rathmann@tigertal.de>
Date:   Thu Dec 14 12:58:42 2023 +0100

    wip

commit 5fc7c8298f26dabd14baca942d854924109d76f2
Author: Uwe Rathmann <Uwe.Rathmann@tigertal.de>
Date:   Thu Dec 14 12:57:18 2023 +0100

    wip

commit a2a7056a1df69d1fcc5a6de7ebb6c1b99d1bf7eb
Author: Uwe Rathmann <Uwe.Rathmann@tigertal.de>
Date:   Thu Dec 14 12:50:26 2023 +0100

    wip

commit a35d79069c20e2c76ef92eec308d5eb459f110ec
Author: Uwe Rathmann <Uwe.Rathmann@tigertal.de>
Date:   Thu Dec 14 12:23:15 2023 +0100

    wip

commit d0828ee074c7a247621590b5575c587e1a876706
Author: Uwe Rathmann <Uwe.Rathmann@tigertal.de>
Date:   Thu Dec 14 11:17:37 2023 +0100

    wip
2023-12-14 13:01:13 +01:00
Uwe Rathmann dda2525970 using QSGGeometry::updateTexturedRectGeometry 2023-12-13 15:09:20 +01:00
Uwe Rathmann 245491724d disable the alpha channel 2023-12-13 07:27:40 +01:00
Uwe Rathmann 048e76d021 using the scene root node 2023-12-12 10:55:30 +01:00
Uwe Rathmann 7615cffdd4 using SceneTexture instead of QSGLayer. blocking the renderer hen
reaching the itemNode is not solved yet
2023-12-11 09:07:56 +01:00
Uwe Rathmann 162534c13c class names shortened 2023-12-08 15:47:32 +01:00
Uwe Rathmann ff1b479938 seems to work now - even when being a child 2023-12-08 15:35:34 +01:00
Uwe Rathmann 725500fdaf some improvement for Overlays being the child of the grabbed item - not
finaly solved
2023-12-07 18:17:41 +01:00
Uwe Rathmann 7f6e77d53d using QSGLayer 2023-12-07 11:24:47 +01:00
Uwe Rathmann 0392f8ea36 Qt6 supported 2023-12-04 12:48:11 +01:00
Uwe Rathmann a90f1c4439 playground/parrots derived from Ricks work 2023-12-03 18:06:34 +01:00
53 changed files with 1371 additions and 537 deletions

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -0,0 +1,44 @@
############################################################################
# QSkinny - Copyright (C) 2016 Uwe Rathmann
# SPDX-License-Identifier: BSD-3-Clause
############################################################################
set(SOURCES
Overlay.h Overlay.cpp
TextureFilterMaterial.h TextureFilterMaterial.cpp
TextureFilterNode.h TextureFilterNode.cpp
main.cpp)
qt_add_resources(SOURCES images.qrc)
if (QT_VERSION_MAJOR VERSION_LESS 6)
qt_add_resources(SOURCES shaders.qrc)
endif()
qsk_add_example(parrots ${SOURCES})
if (QT_VERSION_MAJOR VERSION_GREATER_EQUAL 6)
qt6_add_shaders(parrots "shaders"
BATCHABLE
PRECOMPILE
QUIET
PREFIX
"/shaders"
FILES
shaders/blur-vulkan.vert
shaders/blur-vulkan.frag
shaders/rgbswap-vulkan.frag
OUTPUTS
blur.vert.qsb
blur.frag.qsb
rgbswap.vert.qsb
)
endif()

View File

@ -0,0 +1,206 @@
/******************************************************************************
* QSkinny - Copyright (C) 2016 Uwe Rathmann
* SPDX-License-Identifier: BSD-3-Clause
*****************************************************************************/
#include "Overlay.h"
#include "TextureFilterNode.h"
#include "TextureFilterMaterial.h"
#include <QskSkinlet.h>
#include <QskQuick.h>
#include <QskBoxShapeMetrics.h>
#include <QskBoxBorderMetrics.h>
#include <QskBoxBorderColors.h>
#include <QskGradient.h>
#include <QskSceneTexture.h>
#include <QskSGNode.h>
#include <QskRgbValue.h>
namespace
{
class Material final : public TextureFilterMaterial
{
public:
using TextureFilterMaterial::TextureFilterMaterial;
QSGMaterialType* type() const override
{
static QSGMaterialType staticType;
return &staticType;
}
};
class FilterNode final : public TextureFilterNode
{
public:
FilterNode( bool useRhi, QSGTexture* texture )
{
QString shaders[] = { ":/shaders/blur.vert", ":/shaders/blur.frag" };
if ( useRhi )
{
shaders[0] += ".qsb";
shaders[1] += ".qsb";
}
setFlag( QSGNode::OwnsMaterial, true );
setTextureMaterial( new Material( shaders[0], shaders[1] ) );
setOwnsTexture( true );
setTexture( texture );
}
};
class Skinlet final : public QskSkinlet
{
using Inherited = QskSkinlet;
public:
enum NodeRole { FillRole, BorderRole };
Skinlet()
{
setNodeRoles( { FillRole, BorderRole } );
}
QRectF subControlRect( const QskSkinnable*,
const QRectF& contentsRect, QskAspect::Subcontrol ) const override
{
return contentsRect;
}
QSGNode* updateSubNode( const QskSkinnable* skinnable,
quint8 nodeRole, QSGNode* node ) const override
{
const auto overlay = static_cast< const Overlay* >( skinnable );
switch ( nodeRole )
{
case FillRole:
return updateFillNode( overlay, node );
case BorderRole:
return updateBoxNode( skinnable, node, Overlay::Panel );
};
return nullptr;
}
private:
QSGNode* updateFillNode( const Overlay* overlay, QSGNode* node ) const
{
/*
There should be a way to avoid the clip node by passing the
vertex list directly to the texture node. TODO ...
*/
using Q = Overlay;
QSGNode* clipNode = nullptr;
QSGNode* textureNode = nullptr;
if ( node )
{
if ( node->firstChild() )
{
clipNode = node;
textureNode = node->firstChild();
}
else
{
textureNode = node;
}
}
textureNode = updateTextureNode( overlay, textureNode );
if ( overlay->boxShapeHint( Q::Panel ).isRectangle() )
{
delete clipNode;
clipNode = nullptr;
}
else
{
clipNode = updateBoxClipNode( overlay, clipNode, Q::Panel );
QskSGNode::setParentNode( textureNode, clipNode );
}
return clipNode ? clipNode : textureNode;
}
QSGNode* updateTextureNode( const Overlay* overlay, QSGNode* node ) const
{
const auto window = overlay->window();
const auto rect = overlay->subControlRect( Overlay::Panel );
if ( rect.isEmpty() )
return nullptr;
auto rootNode = qskScenegraphAnchorNode( window );
if ( rootNode == nullptr )
return nullptr;
auto textureNode = static_cast< FilterNode* >( node );
if ( textureNode == nullptr )
{
auto texture = new QskSceneTexture( window );
QObject::connect( texture, &QskSceneTexture::updateRequested,
overlay, &QQuickItem::update );
const bool useRhi = qskRenderingHardwareInterface( window );
textureNode = new FilterNode( useRhi, texture );
}
auto texture = qobject_cast< QskSceneTexture* >( textureNode->texture() );
Q_ASSERT( texture );
if ( texture->isDirty() || rect != textureNode->rect() )
{
texture->setFiltering(
overlay->smooth() ? QSGTexture::Linear : QSGTexture::Nearest );
auto finalNode = const_cast< QSGTransformNode* >( qskItemNode( overlay ) );
texture->render( rootNode, finalNode,
rect.translated( overlay->position() ) );
textureNode->markDirty( QSGNode::DirtyMaterial );
}
textureNode->setRect( rect );
return textureNode;
}
};
}
QSK_SUBCONTROL( Overlay, Panel )
Overlay::Overlay( QQuickItem* parent )
: Inherited( parent )
{
setSkinlet( new Skinlet() );
setBoxBorderMetricsHint( Panel, 1 );
setBoxBorderColorsHint( Panel, QskRgb::toTransparent( QskRgb::DarkGrey, 100 ) );
setBoxShapeHint( Panel, QskBoxShapeMetrics( 25, Qt::RelativeSize ) );
}
Overlay::~Overlay()
{
}
QRectF Overlay::layoutRectForSize( const QSizeF& size ) const
{
return subControlContentsRect( size, Panel );
}
void Overlay::geometryChange(
const QRectF& newGeometry, const QRectF& oldGeometry )
{
Inherited::geometryChange( newGeometry, oldGeometry );
update();
}
#include "moc_Overlay.cpp"

View File

@ -0,0 +1,26 @@
/******************************************************************************
* QSkinny - Copyright (C) 2016 Uwe Rathmann
* SPDX-License-Identifier: BSD-3-Clause
*****************************************************************************/
#pragma once
#include <QskControl.h>
class Overlay : public QskControl
{
Q_OBJECT
using Inherited = QskControl;
public:
QSK_SUBCONTROLS( Panel )
Overlay( QQuickItem* = nullptr );
~Overlay() override;
QRectF layoutRectForSize( const QSizeF& ) const override;
protected:
void geometryChange( const QRectF&, const QRectF& ) override;
};

View File

@ -0,0 +1,216 @@
/******************************************************************************
* QSkinny - Copyright (C) 2016 Uwe Rathmann
* SPDX-License-Identifier: BSD-3-Clause
*****************************************************************************/
#include "TextureFilterMaterial.h"
#include <qsgmaterial.h>
#include <qsgmaterialshader.h>
#include <qsgtexture.h>
#if QT_VERSION < QT_VERSION_CHECK( 6, 0, 0 )
#include <qsgmaterialrhishader.h>
using RhiShader = QSGMaterialRhiShader;
#else
using RhiShader = QSGMaterialShader;
#endif
#if QT_VERSION < QT_VERSION_CHECK( 6, 0, 0 )
namespace
{
class ShaderGL : public QSGMaterialShader
{
public:
void setSource( QOpenGLShader::ShaderType type, const QString& fileName )
{
setShaderSourceFile( type, fileName );
}
char const* const* attributeNames() const override
{
static char const* const names[] = { "in_vertex", "in_coord", nullptr };
return names;
}
void initialize() override
{
QSGMaterialShader::initialize();
auto p = program();
m_matrixId = p->uniformLocation( "matrix" );
m_opacityId = p->uniformLocation( "opacity" );
}
void updateState( const QSGMaterialShader::RenderState& state,
QSGMaterial* newMaterial, QSGMaterial* oldMaterial ) override
{
auto p = program();
if ( state.isMatrixDirty() )
p->setUniformValue( m_matrixId, state.combinedMatrix() );
if ( state.isOpacityDirty() )
p->setUniformValue( m_opacityId, state.opacity() );
auto material = static_cast< TextureFilterMaterial* >( newMaterial );
if ( auto texture = material->texture() )
{
auto textureId = -1;
if ( auto oldMat = static_cast< TextureFilterMaterial* >( oldMaterial ) )
{
if ( oldMat->texture() )
textureId = oldMat->texture()->textureId();
}
if ( texture->textureId() != textureId )
texture->bind();
else
texture->updateBindOptions();
}
}
private:
int m_matrixId = -1;
int m_opacityId = -1;
};
}
#endif
namespace
{
class ShaderRhi : public RhiShader
{
public:
ShaderRhi()
{
setFlag( UpdatesGraphicsPipelineState, true );
}
#if QT_VERSION < QT_VERSION_CHECK( 6, 0, 0 )
void setSource( QOpenGLShader::ShaderType type, const QString& fileName )
{
setShaderSourceFile( type, fileName );
}
#endif
void setSource( Stage stage, const QString& filename )
{
setShaderFileName( stage, filename );
}
bool updateUniformData( RenderState& state,
QSGMaterial*, QSGMaterial* ) override
{
Q_ASSERT( state.uniformData()->size() >= 68 );
auto data = state.uniformData()->data();
bool changed = false;
if ( state.isMatrixDirty() )
{
const auto matrix = state.combinedMatrix();
memcpy( data + 0, matrix.constData(), 64 );
changed = true;
}
if ( state.isOpacityDirty() )
{
const float opacity = state.opacity();
memcpy( data + 64, &opacity, 4 );
changed = true;
}
return changed;
}
void updateSampledImage( RenderState& state, int binding,
QSGTexture** texture, QSGMaterial* newMaterial, QSGMaterial* ) override
{
Q_UNUSED( binding );
Q_ASSERT( binding == 1 );
auto mat = dynamic_cast< TextureFilterMaterial* >( newMaterial );
if ( auto txt = mat->texture() )
{
#if QT_VERSION < QT_VERSION_CHECK( 6, 0, 0 )
txt->updateRhiTexture( state.rhi(), state.resourceUpdateBatch() );
#else
txt->commitTextureOperations( state.rhi(), state.resourceUpdateBatch() );
#endif
*texture = txt;
}
}
};
}
#if QT_VERSION < QT_VERSION_CHECK( 6, 0, 0 )
QSGMaterialShader* TextureFilterMaterial::createShader() const
{
if ( flags() & QSGMaterial::RhiShaderWanted )
{
auto shader = new ShaderRhi();
shader->setSource( ShaderRhi::VertexStage, m_shaderFiles[ 0 ] );
shader->setSource( ShaderRhi::FragmentStage, m_shaderFiles[ 1 ] );
return shader;
}
else
{
auto shader = new ShaderGL();
shader->setSource( QOpenGLShader::Vertex, m_shaderFiles[ 0 ] );
shader->setSource( QOpenGLShader::Fragment, m_shaderFiles[ 1 ] );
return shader;
}
}
#else
QSGMaterialShader* TextureFilterMaterial::createShader(
QSGRendererInterface::RenderMode ) const
{
auto shader = new ShaderRhi();
shader->setSource( ShaderRhi::VertexStage, m_shaderFiles[ 0 ] );
shader->setSource( ShaderRhi::FragmentStage, m_shaderFiles[ 1 ] );
return shader;
}
#endif
TextureFilterMaterial::TextureFilterMaterial(
const QString& vertexShaderFile, const QString& fragmentShaderFile )
: m_shaderFiles{ vertexShaderFile, fragmentShaderFile }
{
setFlag( Blending | RequiresFullMatrix, true );
#if QT_VERSION < QT_VERSION_CHECK( 6, 0, 0 )
setFlag( SupportsRhiShader, true );
#endif
}
TextureFilterMaterial::~TextureFilterMaterial()
{
}
int TextureFilterMaterial::compare( const QSGMaterial* other ) const
{
auto material = static_cast< const TextureFilterMaterial* >( other );
const auto key1 = texture()->comparisonKey();
const auto key2 = material->texture()->comparisonKey();
return ( key1 == key2 ) ? 0 : ( ( key1 > key2 ) ? 1 : -1 );
}

View File

@ -0,0 +1,36 @@
/******************************************************************************
* QSkinny - Copyright (C) 2016 Uwe Rathmann
* SPDX-License-Identifier: BSD-3-Clause
*****************************************************************************/
#pragma once
#include <qsgmaterial.h>
#include <qstring.h>
class QSGTexture;
class TextureFilterMaterial : public QSGMaterial
{
public:
TextureFilterMaterial( const QString& vertexShaderSourceFile,
const QString& fragmentShaderSourceFile );
~TextureFilterMaterial() override;
int compare( const QSGMaterial* other ) const override;
void setTexture( QSGTexture* texture ) { m_texture = texture; }
QSGTexture* texture() const { return m_texture; }
#if QT_VERSION >= QT_VERSION_CHECK( 6, 0, 0 )
QSGMaterialShader* createShader(
QSGRendererInterface::RenderMode ) const override final;
#else
QSGMaterialShader* createShader() const override final;
#endif
private:
QSGTexture* m_texture = nullptr;
const QString m_shaderFiles[ 2 ];
};

View File

@ -0,0 +1,104 @@
/******************************************************************************
* QSkinny - Copyright (C) 2016 Uwe Rathmann
* SPDX-License-Identifier: BSD-3-Clause
*****************************************************************************/
#include "TextureFilterNode.h"
#include "TextureFilterMaterial.h"
#include <qsgtexture.h>
#include <private/qsgnode_p.h>
class TextureFilterNodePrivate final : public QSGGeometryNodePrivate
{
public:
TextureFilterNodePrivate()
: geometry( QSGGeometry::defaultAttributes_TexturedPoint2D(), 4 )
{
}
QSGGeometry geometry;
QRectF rect;
bool ownsTexture = false;
};
TextureFilterNode::TextureFilterNode()
: QSGGeometryNode( *new TextureFilterNodePrivate )
{
Q_D( TextureFilterNode );
setGeometry( &d->geometry );
setFlag( QSGNode::OwnsMaterial, true );
}
TextureFilterNode::~TextureFilterNode()
{
setTexture( nullptr );
}
void TextureFilterNode::setTextureMaterial( TextureFilterMaterial* material )
{
QSGTexture* texture = nullptr;
if ( auto oldMaterial = textureMaterial() )
texture = oldMaterial->texture();
Inherited::setMaterial( material );
if ( material )
material->setTexture( texture );
}
TextureFilterMaterial* TextureFilterNode::textureMaterial() const
{
return dynamic_cast< TextureFilterMaterial* >( material() );
}
void TextureFilterNode::setTexture( QSGTexture* texture )
{
if ( auto mat = textureMaterial() )
{
if ( ownsTexture() && mat->texture() != texture )
delete mat->texture();
mat->setTexture( texture );
markDirty( QSGNode::DirtyMaterial );
}
}
QSGTexture* TextureFilterNode::texture() const
{
auto mat = textureMaterial();
return mat ? mat->texture() : nullptr;
}
void TextureFilterNode::setRect( const QRectF& rect )
{
Q_D( TextureFilterNode );
if ( rect != d->rect )
{
d->rect = rect;
QSGGeometry::updateTexturedRectGeometry(
&d->geometry, rect, QRectF( 0, 0, 1, 1 ) );
d->geometry.markVertexDataDirty();
markDirty( QSGNode::DirtyGeometry );
}
}
QRectF TextureFilterNode::rect() const
{
return d_func()->rect;
}
void TextureFilterNode::setOwnsTexture( bool on )
{
d_func()->ownsTexture = on;
}
bool TextureFilterNode::ownsTexture() const
{
return d_func()->ownsTexture;
}

View File

@ -0,0 +1,39 @@
/******************************************************************************
* QSkinny - Copyright (C) 2016 Uwe Rathmann
* SPDX-License-Identifier: BSD-3-Clause
*****************************************************************************/
#pragma once
#include <qsgnode.h>
class TextureFilterMaterial;
class TextureFilterNodePrivate;
class QSGTexture;
class TextureFilterNode : public QSGGeometryNode
{
using Inherited = QSGGeometryNode;
public:
TextureFilterNode();
~TextureFilterNode();
void setTexture( QSGTexture* );
QSGTexture* texture() const;
void setOwnsTexture( bool );
bool ownsTexture() const;
void setRect( const QRectF& );
QRectF rect() const;
void setTextureMaterial( TextureFilterMaterial* );
TextureFilterMaterial* textureMaterial() const;
private:
void setMaterial( QSGMaterial* ) = delete;
Q_DECLARE_PRIVATE( TextureFilterNode )
};

View File

@ -0,0 +1,9 @@
<!DOCTYPE RCC>
<RCC version="1.0">
<qresource>
<file>images/parrots.jpg</file>
</qresource>
</RCC>

Binary file not shown.

After

Width:  |  Height:  |  Size: 45 KiB

179
playground/parrots/main.cpp Normal file
View File

@ -0,0 +1,179 @@
/******************************************************************************
* QSkinny - Copyright (C) 2016 Uwe Rathmann
* SPDX-License-Identifier: BSD-3-Clause
*****************************************************************************/
#include <SkinnyNamespace.h>
#include <QskFunctions.h>
#include <QskLinearBox.h>
#include <QskPushButton.h>
#include <QskQuick.h>
#include <QskWindow.h>
#include <QskGraphicLabel.h>
#include <QskGraphic.h>
#include <QskEvent.h>
#include <QskRgbValue.h>
#include <QGuiApplication>
#include <QDebug>
#include <SkinnyShortcut.h>
#include <qmath.h>
#include "Overlay.h"
class Image : public QskGraphicLabel
{
public:
Image( QQuickItem* parent = nullptr )
: QskGraphicLabel( parent )
{
const QImage image( ":/images/parrots.jpg" );
setGraphic( QskGraphic::fromImage( image ) );
}
};
class ForegroundItem : public QskLinearBox
{
public:
ForegroundItem( QQuickItem* parent = nullptr )
: QskLinearBox( Qt::Vertical, parent )
{
setMargins( 20 );
#if 0
auto label = new Image( this );
label->setSizePolicy( QskSizePolicy::Fixed, QskSizePolicy::Fixed );
label->setLayoutAlignmentHint( Qt::AlignCenter );
label->setObjectName( "miniParrots" );
#endif
auto button = new QskPushButton( "Button", this );
button->setLayoutAlignmentHint( Qt::AlignHCenter | Qt::AlignBottom );
button->setObjectName( "button" );
setObjectName( "foreground" );
}
};
class BackgroundItem : public QskControl
{
using Inherited = QskControl;
public:
BackgroundItem( QQuickItem* parent = nullptr )
: QskControl( parent )
{
setObjectName( "background" );
m_label = new Image( this );
m_label->setFillMode( QskGraphicLabel::Stretch );
m_label->setObjectName( "parrots" );
startTimer( 20 );
}
protected:
void timerEvent( QTimerEvent* ) override
{
updateLabel();
}
void geometryChange( const QRectF& newGeometry,
const QRectF& oldGeometry ) override
{
Inherited::geometryChange( newGeometry, oldGeometry );
updateLabel();
}
private:
void updateLabel()
{
static int counter = 0;
const auto angle = counter++ / 50.0 * M_PI * 2.0;
const auto x = std::cos( angle );
const auto y = std::sin( angle );
const qreal margin = 20;
auto labelRect = rect();
labelRect.adjust( margin, margin, -margin, -margin );
labelRect.translate( margin * x, margin * y );
if ( m_label )
m_label->setGeometry( labelRect );
}
private:
QskGraphicLabel* m_label = nullptr;
};
class MainView : public QskControl
{
public:
MainView( QQuickItem* parent = nullptr )
: QskControl( parent )
{
setPolishOnResize( true );
m_background = new BackgroundItem( this );
#if 0
{
auto box = new QskBox( m_background );
box->setGeometry( 20, 20, 600, 400 );
box->setFillGradient( QskRgb::SaddleBrown );
box->setObjectName( "redBox" );
}
#endif
m_overlay = new Overlay( m_background );
m_overlay->setAutoLayoutChildren( true );
m_overlay->setObjectName( "overlay" );
(void )new ForegroundItem( m_overlay );
#if 0
{
auto box = new QskBox( m_background );
box->setGeometry( 50, 50, 400, 200 );
box->setFillGradient( QskRgb::PaleGreen );
box->setObjectName( "blueBox" );
}
#endif
setObjectName( "mainView" );
}
protected:
void updateLayout() override
{
if ( m_background )
m_background->setGeometry( rect() );
QRectF blurredRect( QPointF(), 0.7 * size() );
blurredRect.moveCenter( rect().center() );
if ( m_overlay )
qskSetItemGeometry( m_overlay, blurredRect );
}
private:
BackgroundItem* m_background = nullptr;
Overlay* m_overlay = nullptr;
};
int main( int argc, char** argv )
{
QGuiApplication app( argc, argv );
SkinnyShortcut::enable( SkinnyShortcut::AllShortcuts );
QskWindow window;
window.setColor( Qt::darkGray );
window.addItem( new MainView( window.contentItem() ) );
window.resize( 800, 600 );
window.show();
return app.exec();
}

View File

@ -0,0 +1,8 @@
<!DOCTYPE RCC>
<RCC version="1.0">
<qresource>
<file>shaders/blur.vert</file>
<file>shaders/blur.frag</file>
<file>shaders/rgbswap.frag</file>
</qresource>
</RCC>

View File

@ -0,0 +1,25 @@
#version 440
layout( location = 0 ) in vec2 coord;
layout( location = 0 ) out vec4 fragColor;
layout( binding = 1 ) uniform sampler2D source;
layout( std140, binding = 0 ) uniform buf
{
mat4 matrix;
float opacity;
} ubuf;
void main()
{
vec2 delta = vec2( 0.01, 0.01 );
fragColor =(
0.0538 * texture( source, coord - 3.182 * delta )
+ 0.3229 * texture( source, coord - 1.364 * delta )
+ 0.2466 * texture( source, coord )
+ 0.3229 * texture( source, coord + 1.364 * delta )
+ 0.0538 * texture( source, coord + 3.182 * delta )
) * ubuf.opacity;
}

View File

@ -0,0 +1,21 @@
#version 440
layout( location = 0 ) in vec4 in_vertex;
layout( location = 1 ) in vec2 in_coord;
layout( location = 0 ) out vec2 coord;
layout( std140, binding = 0 ) uniform buf
{
mat4 matrix;
float opacity;
} ubuf;
out gl_PerVertex { vec4 gl_Position; };
void main()
{
coord = in_coord;
gl_Position = ubuf.matrix * in_vertex;
}

View File

@ -0,0 +1,17 @@
uniform sampler2D source;
uniform lowp float opacity;
varying highp vec2 coord;
void main()
{
vec2 delta = vec2( 0.01, 0.01 );
gl_FragColor =(
0.0538 * texture2D( source, coord - 3.182 * delta )
+ 0.3229 * texture2D( source, coord - 1.364 * delta )
+ 0.2466 * texture2D( source, coord )
+ 0.3229 * texture2D( source, coord + 1.364 * delta )
+ 0.0538 * texture2D( source, coord + 3.182 * delta)
) * opacity;
}

View File

@ -0,0 +1,12 @@
uniform highp mat4 matrix;
attribute highp vec4 in_vertex;
attribute highp vec2 in_coord;
varying highp vec2 coord;
void main()
{
coord = in_coord;
gl_Position = matrix * in_vertex;
}

View File

@ -0,0 +1,18 @@
#version 440
layout( location = 0 ) in vec2 coord;
layout( location = 0 ) out vec4 fragColor;
layout( binding = 1 ) uniform sampler2D source;
layout( std140, binding = 0 ) uniform buf
{
mat4 matrix;
float opacity;
} ubuf;
void main()
{
vec4 c = texture( source, coord );
fragColor = c.yzxw * ubuf.opacity;
}

View File

@ -0,0 +1,10 @@
uniform sampler2D source;
uniform lowp float opacity;
varying highp vec2 coord;
void main()
{
vec4 c = texture2D( source, coord );
gl_FragColor = c.yzxw * opacity;
}

View File

@ -0,0 +1,10 @@
#! /bin/sh
function qsbcompile {
qsbfile=`echo $1 | sed 's/-vulkan//'`
qsb --glsl 100es,120,150 --hlsl 50 --msl 12 -b -o ${qsbfile}.qsb $1
}
qsbcompile blur-vulkan.vert
qsbcompile blur-vulkan.frag
qsbcompile rgbswap-vulkan.frag

View File

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

View File

@ -8,7 +8,7 @@
#include <QskSkinlet.h> #include <QskSkinlet.h>
#include <QskArcNode.h> #include <QskArcNode.h>
#include <QskArcHints.h> #include <QskArcMetrics.h>
#include <QskShadowMetrics.h> #include <QskShadowMetrics.h>
#include <QskSGNode.h> #include <QskSGNode.h>
#include <QskRgbValue.h> #include <QskRgbValue.h>
@ -107,7 +107,14 @@ namespace
return nullptr; return nullptr;
auto arcNode = QskSGNode::ensureNode< QskArcNode >( node ); 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; return arcNode;
} }

View File

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

View File

@ -5,7 +5,6 @@
list(APPEND HEADERS list(APPEND HEADERS
common/QskArcMetrics.h common/QskArcMetrics.h
common/QskArcHints.h
common/QskAspect.h common/QskAspect.h
common/QskBoxBorderColors.h common/QskBoxBorderColors.h
common/QskBoxBorderMetrics.h common/QskBoxBorderMetrics.h
@ -42,7 +41,6 @@ list(APPEND HEADERS
list(APPEND SOURCES list(APPEND SOURCES
common/QskArcMetrics.cpp common/QskArcMetrics.cpp
common/QskArcHints.cpp
common/QskAspect.cpp common/QskAspect.cpp
common/QskBoxBorderColors.cpp common/QskBoxBorderColors.cpp
common/QskBoxBorderMetrics.cpp common/QskBoxBorderMetrics.cpp
@ -510,7 +508,7 @@ else()
endif() endif()
if (QT_VERSION_MAJOR VERSION_GREATER_EQUAL 6) 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() endif()
target_include_directories(${target} PUBLIC 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::QskGradient( QGradient::Preset preset )
: QskGradient() : QskGradient()
{ {
setStops( qskFromQGradientStops( QGradient( preset ).stops() ) ); setStops( qskBuildGradientStops( QGradient( preset ).stops() ) );
} }
QskGradient::QskGradient( const QVector< QskGradientStop >& 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 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 ) void QskGradient::setStops( QGradient::Preset preset )
{ {
const auto stops = qskFromQGradientStops( QGradient( preset ).stops() ); const auto stops = qskBuildGradientStops( QGradient( preset ).stops() );
setStops( stops ); setStops( stops );
} }

View File

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

View File

@ -45,10 +45,8 @@ class QSK_EXPORT QskGradientStop
void setRgb( QRgb ) noexcept; void setRgb( QRgb ) noexcept;
QRgb rgb() const noexcept; QRgb rgb() const noexcept;
QskGradientStop interpolated( const QskGradientStop&, qreal ) const; static QColor interpolated(
const QskGradientStop&, const QskGradientStop&, qreal position ) noexcept;
static QVariant interpolate( const QskGradientStop&,
const QskGradientStop&, qreal );
QskHashValue hash( QskHashValue seed ) const noexcept; QskHashValue hash( QskHashValue seed ) const noexcept;
@ -131,48 +129,27 @@ QSK_EXPORT QskGradientStops qskInterpolatedGradientStops(
const QskGradientStops&, bool, const QskGradientStops&, bool, const QskGradientStops&, bool, const QskGradientStops&, bool,
qreal ratio ); qreal ratio );
// interpolating colors in direction of a color.
QSK_EXPORT QskGradientStops qskInterpolatedGradientStops( QSK_EXPORT QskGradientStops qskInterpolatedGradientStops(
const QskGradientStops&, const QColor&, qreal ratio ); const QskGradientStops&, const QColor&, qreal ratio );
// interpolating colors starting from a color.
QSK_EXPORT QskGradientStops qskInterpolatedGradientStops( QSK_EXPORT QskGradientStops qskInterpolatedGradientStops(
const QColor&, const QskGradientStops&, qreal ratio ); const QColor&, const QskGradientStops&, qreal ratio );
// interpolating the opacity of the colors
QSK_EXPORT QskGradientStops qskTransparentGradientStops( QSK_EXPORT QskGradientStops qskTransparentGradientStops(
const QskGradientStops&, qreal ratio ); const QskGradientStops&, qreal ratio );
// extracting the colors of [from, to ] and stretching them to [0.0, 1.0]
QSK_EXPORT QskGradientStops qskExtractedGradientStops( QSK_EXPORT QskGradientStops qskExtractedGradientStops(
const QskGradientStops&, qreal from, qreal to ); 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( QSK_EXPORT QskGradientStops qskBuildGradientStops(
const QVector< QRgb >&, bool discrete = false ); const QVector< QRgb >&, bool discrete = false );
QSK_EXPORT QskGradientStops qskBuildGradientStops( QSK_EXPORT QskGradientStops qskBuildGradientStops(
const QVector< QColor >&, bool discrete = false ); const QVector< QColor >&, bool discrete = false );
/* QSK_EXPORT QskGradientStops qskRevertedGradientStops( const QskGradientStops& );
convert color stops from/to a vector of QGradientStop, that can be
used for QGradients. QSK_EXPORT QskGradientStops qskBuildGradientStops( const QVector< QGradientStop >& );
*/
QSK_EXPORT QskGradientStops qskFromQGradientStops( const QVector< QGradientStop >& );
QSK_EXPORT QVector< QGradientStop > qskToQGradientStops( const QVector< QskGradientStop >& ); QSK_EXPORT QVector< QGradientStop > qskToQGradientStops( const QVector< QskGradientStop >& );
#endif #endif

View File

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

View File

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

View File

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

View File

@ -6,7 +6,7 @@
#include "QskProgressBarSkinlet.h" #include "QskProgressBarSkinlet.h"
#include "QskProgressBar.h" #include "QskProgressBar.h"
#include "QskIntervalF.h" #include "QskIntervalF.h"
#include "QskBoxHints.h" #include "QskBoxBorderMetrics.h"
#include <qeasingcurve.h> #include <qeasingcurve.h>
#include <cmath> #include <cmath>
@ -50,6 +50,41 @@ static QskIntervalF qskFillInterval( const QskProgressIndicator* indicator )
return QskIntervalF( pos1, pos2 ); 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 ) QskProgressBarSkinlet::QskProgressBarSkinlet( QskSkin* skin )
: Inherited( skin ) : Inherited( skin )
{ {
@ -87,40 +122,9 @@ QSGNode* QskProgressBarSkinlet::updateFillNode(
if ( rect.isEmpty() ) if ( rect.isEmpty() )
return nullptr; return nullptr;
auto hints = indicator->boxHints( Q::Fill ); const auto progressBar = static_cast< const Q* >( indicator );
return updateBoxNode( indicator, node, rect,
auto& gradient = hints.gradient; qskFillGradient( progressBar ), 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( 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 );
} }
QRectF QskProgressBarSkinlet::grooveRect( QRectF QskProgressBarSkinlet::grooveRect(

View File

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

View File

@ -6,7 +6,6 @@
#include "QskSeparatorSkinlet.h" #include "QskSeparatorSkinlet.h"
#include "QskSeparator.h" #include "QskSeparator.h"
#include "QskBoxHints.h"
#include "QskGradientDirection.h" #include "QskGradientDirection.h"
#include "QskAspect.h" #include "QskAspect.h"
@ -43,12 +42,8 @@ QSGNode* QskSeparatorSkinlet::updateSubNode(
using Q = QskSeparator; using Q = QskSeparator;
const auto rect = separator->subControlRect( Q::Panel ); const auto rect = separator->subControlRect( Q::Panel );
if ( rect.isEmpty() )
return nullptr;
auto hints = separator->boxHints( Q::Panel ); auto gradient = separator->gradientHint( Q::Panel );
auto& gradient = hints.gradient;
if ( ( gradient.type() == QskGradient::Stops ) && !gradient.isMonochrome() ) if ( ( gradient.type() == QskGradient::Stops ) && !gradient.isMonochrome() )
{ {
// gradient in opposite orientation // gradient in opposite orientation
@ -58,7 +53,7 @@ QSGNode* QskSeparatorSkinlet::updateSubNode(
gradient.setLinearDirection( orientation ); 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 "QskArcNode.h"
#include "QskAspect.h" #include "QskAspect.h"
#include "QskArcHints.h" #include "QskArcMetrics.h"
#include "QskBoxBorderColors.h"
#include "QskBoxBorderMetrics.h"
#include "QskBoxNode.h" #include "QskBoxNode.h"
#include "QskBoxRectangleNode.h" #include "QskBoxRectangleNode.h"
#include "QskBoxShapeMetrics.h" #include "QskBoxShapeMetrics.h"
@ -154,6 +156,18 @@ static inline bool qskIsBoxVisible( const QskBoxBorderMetrics& borderMetrics,
return !borderMetrics.isNull() && borderColors.isVisible(); 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 ) static inline bool qskIsLineVisible( const QColor& lineColor, qreal lineWidth )
{ {
return ( lineWidth > 0.0 ) && lineColor.isValid() && ( lineColor.alpha() > 0 ); return ( lineWidth > 0.0 ) && lineColor.isValid() && ( lineColor.alpha() > 0 );
@ -188,18 +202,22 @@ static inline QQuickWindow* qskWindowOfSkinnable( const QskSkinnable* skinnable
return nullptr; return nullptr;
} }
static inline QSGNode* qskUpdateBoxNode( const QskSkinnable* skinnable, static inline QSGNode* qskUpdateBoxNode(
QSGNode* node, const QRectF& rect, const QskBoxHints& hints ) 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 ( !rect.isEmpty() )
{ {
if ( qskIsBoxVisible( hints.borderMetrics, hints.borderColors, hints.gradient ) if ( qskIsBoxVisible( borderMetrics, borderColors, gradient )
|| qskIsShadowVisible( hints.shadowMetrics, hints.shadowColor ) ) || qskIsShadowVisible( shadowMetrics, shadowColor ) )
{ {
if ( auto window = qskWindowOfSkinnable( skinnable ) ) if ( auto window = qskWindowOfSkinnable( skinnable ) )
{ {
auto boxNode = QskSGNode::ensureNode< QskBoxNode >( node ); auto boxNode = QskSGNode::ensureNode< QskBoxNode >( node );
boxNode->updateNode( window, rect, hints ); boxNode->updateNode( window, rect, shape, borderMetrics,
borderColors, gradient, shadowMetrics, shadowColor );
return boxNode; return boxNode;
} }
@ -209,20 +227,21 @@ static inline QSGNode* qskUpdateBoxNode( const QskSkinnable* skinnable,
return nullptr; return nullptr;
} }
static inline QSGNode* qskUpdateArcNode( const QskSkinnable* skinnable, static inline QSGNode* qskUpdateArcNode(
QSGNode* node, const QRectF& rect, const QskArcHints& hints ) 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 ( !qskIsArcVisible( metrics, borderWidth, borderColor, gradient ) )
return nullptr;
if ( !rect.isEmpty() && hints.isVisible() )
{
auto arcNode = QskSGNode::ensureNode< QskArcNode >( node ); auto arcNode = QskSGNode::ensureNode< QskArcNode >( node );
arcNode->setArcData( rect, hints ); arcNode->setArcData( rect, metrics, borderWidth, borderColor, gradient );
return arcNode; return arcNode;
}
return nullptr;
} }
static inline QSGNode* qskUpdateLineNode( static inline QSGNode* qskUpdateLineNode(
@ -415,30 +434,54 @@ void QskSkinlet::replaceChildNode( quint8 role,
QSGNode* QskSkinlet::updateBoxNode( const QskSkinnable* skinnable, QSGNode* QskSkinlet::updateBoxNode( const QskSkinnable* skinnable,
QSGNode* node, QskAspect::Subcontrol subControl ) const QSGNode* node, QskAspect::Subcontrol subControl ) const
{ {
auto r = qskSubControlRect( this, skinnable, subControl ); const auto rect = qskSubControlRect( this, skinnable, subControl );
if ( r.isEmpty() ) return updateBoxNode( skinnable, node, rect, subControl );
return nullptr;
r = r.marginsRemoved( skinnable->marginHint( subControl ) );
return qskUpdateBoxNode( skinnable, node,
r, skinnable->boxHints( subControl ) );
} }
QSGNode* QskSkinlet::updateBoxNode( const QskSkinnable* skinnable, QSGNode* QskSkinlet::updateBoxNode( const QskSkinnable* skinnable,
QSGNode* node, const QRectF& rect, QskAspect::Subcontrol subControl ) 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; return nullptr;
const auto r = rect.marginsRemoved( skinnable->marginHint( subControl ) ); const auto borderMetrics = skinnable->boxBorderMetricsHint( subControl );
return qskUpdateBoxNode( skinnable, node, r, skinnable->boxHints( 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* QskSkinlet::updateBoxNode( const QskSkinnable* skinnable,
QSGNode* node, const QRectF& rect, const QskBoxHints& hints ) 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( QSGNode* QskSkinlet::updateInterpolatedBoxNode(
@ -483,24 +526,79 @@ QSGNode* QskSkinlet::updateInterpolatedBoxNode(
QSGNode* QskSkinlet::updateArcNode( const QskSkinnable* skinnable, QSGNode* QskSkinlet::updateArcNode( const QskSkinnable* skinnable,
QSGNode* node, QskAspect::Subcontrol subControl ) const QSGNode* node, QskAspect::Subcontrol subControl ) const
{ {
auto rect = qskSubControlRect( this, skinnable, subControl ); const auto rect = qskSubControlRect( this, skinnable, subControl );
rect = rect.marginsRemoved( skinnable->marginHint( subControl ) ); return updateArcNode( skinnable, node, rect, 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 );
} }
QSGNode* QskSkinlet::updateArcNode( const QskSkinnable* skinnable, QSGNode* QskSkinlet::updateArcNode( const QskSkinnable* skinnable,
QSGNode* node, const QRectF& rect, QskAspect::Subcontrol subControl ) 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, 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, QSGNode* QskSkinlet::updateLineNode( const QskSkinnable* skinnable,

View File

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

View File

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

View File

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

View File

@ -197,23 +197,6 @@ bool QskSlider::hasOrigin() const
return m_data->hasOrigin; 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 QskAspect::Variation QskSlider::effectiveVariation() const
{ {
return static_cast< QskAspect::Variation >( m_data->orientation ); 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 Q_PROPERTY( bool tracking READ isTracking
WRITE setTracking NOTIFY trackingChanged ) WRITE setTracking NOTIFY trackingChanged )
Q_PROPERTY( Qsk::Policy tickPolicy READ tickPolicy
WRITE setTickPolicy RESET resetTickPolicy NOTIFY tickPolicyChanged )
Q_PROPERTY( qreal origin READ origin Q_PROPERTY( qreal origin READ origin
WRITE setOrigin RESET resetOrigin NOTIFY originChanged ) WRITE setOrigin RESET resetOrigin NOTIFY originChanged )
@ -42,10 +39,6 @@ class QSK_EXPORT QskSlider : public QskBoundedValueInput
void setOrientation( Qt::Orientation ); void setOrientation( Qt::Orientation );
Qt::Orientation orientation() const; Qt::Orientation orientation() const;
void setTickPolicy( Qsk::Policy );
void resetTickPolicy();
Qsk::Policy tickPolicy() const;
void setInverted( bool ); void setInverted( bool );
bool isInverted() const; bool isInverted() const;
@ -68,7 +61,6 @@ class QSK_EXPORT QskSlider : public QskBoundedValueInput
void invertedChanged( bool ); void invertedChanged( bool );
void trackingChanged( bool ); void trackingChanged( bool );
void originChanged( qreal ); void originChanged( qreal );
void tickPolicyChanged( Qsk::Policy );
protected: protected:
void mousePressEvent( QMouseEvent* ) override; void mousePressEvent( QMouseEvent* ) override;

View File

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

View File

@ -129,7 +129,7 @@ namespace
{ {
if ( qskIsAncestorOf( this, item ) ) 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() ) ); ensureVisible( QRectF( pos.x(), pos.y(), item->width(), item->height() ) );
} }
} }

View File

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

View File

@ -4,10 +4,11 @@
*****************************************************************************/ *****************************************************************************/
#include "QskArcNode.h" #include "QskArcNode.h"
#include "QskArcHints.h" #include "QskArcMetrics.h"
#include "QskArcRenderNode.h" #include "QskArcRenderNode.h"
#include "QskArcRenderer.h" #include "QskArcRenderer.h"
#include "QskMargins.h" #include "QskMargins.h"
#include "QskGradient.h"
#include "QskSGNode.h" #include "QskSGNode.h"
#include "QskRgbValue.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; using namespace QskSGNode;
QskArcRenderNode* arcNode = nullptr; QskArcRenderNode* arcNode = nullptr;
QskArcRenderNode* fillNode = 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 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 hasFilling = gradient.isVisible();
const auto hasBorder = ( borderWidth > 0.0 ) && QskRgb::isVisible( borderColor ); const auto hasBorder = ( borderWidth > 0.0 ) && QskRgb::isVisible( borderColor );

View File

@ -9,7 +9,8 @@
#include "QskGlobal.h" #include "QskGlobal.h"
#include <qsgnode.h> #include <qsgnode.h>
class QskArcHints; class QskArcMetrics;
class QskGradient;
class QSK_EXPORT QskArcNode : public QSGNode class QSK_EXPORT QskArcNode : public QSGNode
{ {
@ -17,7 +18,10 @@ class QSK_EXPORT QskArcNode : public QSGNode
QskArcNode(); QskArcNode();
~QskArcNode() override; ~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 #endif

View File

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

View File

@ -9,8 +9,14 @@
#include "QskGlobal.h" #include "QskGlobal.h"
#include <qsgnode.h> #include <qsgnode.h>
class QskBoxHints; class QskShadowMetrics;
class QskBoxShapeMetrics;
class QskBoxBorderMetrics;
class QskBoxBorderColors;
class QskGradient;
class QskShadowMetrics;
class QQuickWindow; class QQuickWindow;
class QColor;
class QSK_EXPORT QskBoxNode : public QSGNode class QSK_EXPORT QskBoxNode : public QSGNode
{ {
@ -18,7 +24,10 @@ class QSK_EXPORT QskBoxNode : public QSGNode
QskBoxNode(); QskBoxNode();
~QskBoxNode() override; ~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 #endif

View File

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