add shadow metrics
This commit is contained in:
parent
af149c0e84
commit
ded6523249
|
@ -17,11 +17,75 @@
|
||||||
#include <QskTextLabel.h>
|
#include <QskTextLabel.h>
|
||||||
#include <QskGraphicLabel.h>
|
#include <QskGraphicLabel.h>
|
||||||
#include <QskSlider.h>
|
#include <QskSlider.h>
|
||||||
|
#include <QskShadowMetrics.h>
|
||||||
|
#include <QskBoxBorderColors.h>
|
||||||
|
#include <QskBoxBorderMetrics.h>
|
||||||
|
|
||||||
#include <qpainter.h>
|
#include <qpainter.h>
|
||||||
|
|
||||||
|
QSK_SUBCONTROL(ArcControl, Arc)
|
||||||
|
|
||||||
namespace
|
namespace
|
||||||
{
|
{
|
||||||
|
class LinearGradientSlider : public QskSlider
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
Q_PROPERTY(
|
||||||
|
QColor selectedColor READ selectedColor NOTIFY selectedColorChanged )
|
||||||
|
using Inherited = QskSlider;
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit LinearGradientSlider( QQuickItem* parent = nullptr );
|
||||||
|
explicit LinearGradientSlider( Qt::Orientation orientation, QQuickItem* parent = nullptr );
|
||||||
|
QColor selectedColor() const;
|
||||||
|
|
||||||
|
Q_SIGNALS:
|
||||||
|
void selectedColorChanged();
|
||||||
|
};
|
||||||
|
|
||||||
|
LinearGradientSlider::LinearGradientSlider( QQuickItem* parent )
|
||||||
|
: LinearGradientSlider( Qt::Horizontal, parent )
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
LinearGradientSlider::LinearGradientSlider( Qt::Orientation orientation, QQuickItem* parent )
|
||||||
|
: Inherited( orientation, parent )
|
||||||
|
{
|
||||||
|
static const QVector< QskGradientStop > gradientStops = {
|
||||||
|
{ 0.0000, QColor::fromRgb( 255, 0, 0 ) },
|
||||||
|
{ 0.1667, QColor::fromRgb( 255, 255, 0 ) },
|
||||||
|
{ 0.3333, QColor::fromRgb( 0, 255, 0 ) },
|
||||||
|
{ 0.5000, QColor::fromRgb( 0, 255, 255 ) },
|
||||||
|
{ 0.6667, QColor::fromRgb( 0, 0, 255 ) },
|
||||||
|
{ 0.8333, QColor::fromRgb( 255, 0, 255 ) },
|
||||||
|
{ 1.0000, QColor::fromRgb( 255, 0, 0 ) },
|
||||||
|
};
|
||||||
|
|
||||||
|
QskGradient gradient( gradientStops );
|
||||||
|
gradient.setLinearDirection( orientation );
|
||||||
|
setGradientHint(Groove, {gradientStops});
|
||||||
|
|
||||||
|
setColor( Inherited::Fill, Qt::transparent );
|
||||||
|
setGradientHint( Inherited::Groove, gradient );
|
||||||
|
setBoxBorderColorsHint( Inherited::Handle, Qt::white );
|
||||||
|
setBoxBorderMetricsHint( Inherited::Handle, 2 );
|
||||||
|
|
||||||
|
connect( this, &QskSlider::valueChanged, this, [ this, gradient ]( qreal value ) {
|
||||||
|
value = this->orientation() == Qt::Horizontal ? value : 1.0 - value;
|
||||||
|
const auto selectedColor = gradient.extracted( value, value ).startColor();
|
||||||
|
setColor( Inherited::Handle, selectedColor );
|
||||||
|
setColor( Inherited::Ripple, selectedColor );
|
||||||
|
} );
|
||||||
|
|
||||||
|
valueChanged(0.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
QColor LinearGradientSlider::selectedColor() const
|
||||||
|
{
|
||||||
|
const auto gradient = gradientHint(Groove);
|
||||||
|
return gradient.extracted( value(), value() ).startColor();
|
||||||
|
}
|
||||||
|
|
||||||
class ChartBox : public QskControl
|
class ChartBox : public QskControl
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
@ -89,12 +153,15 @@ namespace
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
SliderBox( const QString& label, qreal min, qreal max, qreal value )
|
SliderBox(
|
||||||
|
const QString& label, qreal min, qreal max, qreal value,
|
||||||
|
std::function< QskSlider*( QQuickItem* ) > allocator =
|
||||||
|
[]( QQuickItem* parent = nullptr ) { return new QskSlider( parent ); } )
|
||||||
{
|
{
|
||||||
auto textLabel = new QskTextLabel( label, this );
|
auto textLabel = new QskTextLabel( label, this );
|
||||||
textLabel->setSizePolicy( Qt::Horizontal, QskSizePolicy::Fixed );
|
textLabel->setSizePolicy( Qt::Horizontal, QskSizePolicy::Fixed );
|
||||||
|
|
||||||
auto slider = new QskSlider( this );
|
auto slider = allocator( this );
|
||||||
slider->setBoundaries( min, max );
|
slider->setBoundaries( min, max );
|
||||||
slider->setValue( value );
|
slider->setValue( value );
|
||||||
slider->setStepSize( 1.0 );
|
slider->setStepSize( 1.0 );
|
||||||
|
@ -126,8 +193,11 @@ namespace
|
||||||
auto sliderStart = new SliderBox( "Angle", 0.0, 360.0, metrics.startAngle() );
|
auto sliderStart = new SliderBox( "Angle", 0.0, 360.0, metrics.startAngle() );
|
||||||
auto sliderSpan = new SliderBox( "Span", -360.0, 360.0, metrics.spanAngle() );
|
auto sliderSpan = new SliderBox( "Span", -360.0, 360.0, metrics.spanAngle() );
|
||||||
auto sliderExtent = new SliderBox( "Extent", 10.0, 100.0, metrics.thickness() );
|
auto sliderExtent = new SliderBox( "Extent", 10.0, 100.0, metrics.thickness() );
|
||||||
auto sliderOffsetX = new SliderBox( "Offset X", 0.0, 100.0, 0 );
|
auto shadowExtent = new SliderBox( "Shadow Extent", 0.0, 100.0, 50 );
|
||||||
auto sliderOffsetY = new SliderBox( "Offset Y", 0.0, 100.0, 0 );
|
auto sliderOffsetX = new SliderBox( "Offset X", -1.0, +1.0, 0 );
|
||||||
|
auto sliderOffsetY = new SliderBox( "Offset Y", -1.0, +1.0, 0 );
|
||||||
|
auto sliderFillColor = new SliderBox( "Fill Color", 0.0, 1.0, 0 , []( QQuickItem* parent = nullptr ) { return new LinearGradientSlider( parent ); });
|
||||||
|
auto sliderShadowColor = new SliderBox( "Shadow Color", 0.0, 1.0, 0, []( QQuickItem* parent = nullptr ) { return new LinearGradientSlider( parent ); } );
|
||||||
|
|
||||||
connect( sliderStart, &SliderBox::valueChanged,
|
connect( sliderStart, &SliderBox::valueChanged,
|
||||||
this, &ControlPanel::startAngleChanged );
|
this, &ControlPanel::startAngleChanged );
|
||||||
|
@ -138,15 +208,47 @@ namespace
|
||||||
connect( sliderExtent, &SliderBox::valueChanged,
|
connect( sliderExtent, &SliderBox::valueChanged,
|
||||||
this, &ControlPanel::thicknessChanged );
|
this, &ControlPanel::thicknessChanged );
|
||||||
|
|
||||||
|
connect( sliderExtent, &SliderBox::valueChanged,
|
||||||
|
this, &ControlPanel::thicknessChanged );
|
||||||
|
|
||||||
|
connect( sliderOffsetX, &SliderBox::valueChanged,
|
||||||
|
this, &ControlPanel::offsetXChanged );
|
||||||
|
|
||||||
|
connect( sliderOffsetY, &SliderBox::valueChanged,
|
||||||
|
this, &ControlPanel::offsetYChanged );
|
||||||
|
|
||||||
|
connect( shadowExtent, &SliderBox::valueChanged,
|
||||||
|
this, &ControlPanel::shadowExtendChanged );
|
||||||
|
|
||||||
|
connect( sliderFillColor, &SliderBox::valueChanged, this, [=](){
|
||||||
|
auto* const slider = sliderFillColor->findChild<LinearGradientSlider*>();
|
||||||
|
Q_EMIT fillColorChanged(slider->selectedColor());
|
||||||
|
} );
|
||||||
|
|
||||||
|
connect( sliderShadowColor, &SliderBox::valueChanged, this, [=](){
|
||||||
|
auto* const slider = sliderShadowColor->findChild<LinearGradientSlider*>();
|
||||||
|
Q_EMIT shadowColorChanged(slider->selectedColor());
|
||||||
|
} );
|
||||||
|
|
||||||
addItem( sliderStart, 0, 0 );
|
addItem( sliderStart, 0, 0 );
|
||||||
addItem( sliderExtent, 0, 1 );
|
addItem( sliderExtent, 0, 1 );
|
||||||
|
addItem( shadowExtent, 0, 2 );
|
||||||
addItem( sliderSpan, 1, 0, 1, 2 );
|
addItem( sliderSpan, 1, 0, 1, 2 );
|
||||||
|
addItem( sliderOffsetX, 2, 0, 1, 1 );
|
||||||
|
addItem( sliderOffsetY, 2, 1, 1, 1 );
|
||||||
|
addItem( sliderFillColor, 3, 0, 1, 1 );
|
||||||
|
addItem( sliderShadowColor, 3, 1, 1, 1 );
|
||||||
}
|
}
|
||||||
|
|
||||||
Q_SIGNALS:
|
Q_SIGNALS:
|
||||||
void thicknessChanged( qreal );
|
void thicknessChanged( qreal );
|
||||||
void startAngleChanged( qreal );
|
void startAngleChanged( qreal );
|
||||||
void spanAngleChanged( qreal );
|
void spanAngleChanged( qreal );
|
||||||
|
void offsetXChanged( qreal );
|
||||||
|
void offsetYChanged( qreal );
|
||||||
|
void fillColorChanged( QColor );
|
||||||
|
void shadowColorChanged( QColor );
|
||||||
|
void shadowExtendChanged( qreal );
|
||||||
};
|
};
|
||||||
|
|
||||||
class Legend : public QskGridBox
|
class Legend : public QskGridBox
|
||||||
|
@ -200,7 +302,7 @@ namespace
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ChartView::ChartView( QskControl* chart, QQuickItem* parent )
|
ChartView::ChartView( ArcControl* chart, QQuickItem* parent )
|
||||||
: QskMainView( parent )
|
: QskMainView( parent )
|
||||||
{
|
{
|
||||||
auto hBox = new QskLinearBox( Qt::Horizontal );
|
auto hBox = new QskLinearBox( Qt::Horizontal );
|
||||||
|
@ -215,24 +317,50 @@ ChartView::ChartView( QskControl* chart, QQuickItem* parent )
|
||||||
auto controlPanel = new ControlPanel( chart->arcMetricsHint(QskControl::Background) );
|
auto controlPanel = new ControlPanel( chart->arcMetricsHint(QskControl::Background) );
|
||||||
controlPanel->setSizePolicy( Qt::Vertical, QskSizePolicy::Fixed );
|
controlPanel->setSizePolicy( Qt::Vertical, QskSizePolicy::Fixed );
|
||||||
|
|
||||||
connect( controlPanel, &ControlPanel::thicknessChanged, chart, [ chart ](qreal v) {
|
const auto subcontrol = ArcControl::Arc;
|
||||||
auto m = chart->arcMetricsHint( QskControl::Background );
|
|
||||||
|
connect( controlPanel, &ControlPanel::thicknessChanged, chart, [ = ]( qreal v ) {
|
||||||
|
auto m = chart->arcMetricsHint( subcontrol );
|
||||||
m.setThickness( v ) ;
|
m.setThickness( v ) ;
|
||||||
chart->setArcMetricsHint( QskControl::Background, m );
|
chart->setArcMetricsHint( subcontrol, m );
|
||||||
} );
|
} );
|
||||||
|
|
||||||
connect( controlPanel, &ControlPanel::startAngleChanged, chart, [ chart ](qreal v) {
|
connect( controlPanel, &ControlPanel::startAngleChanged, chart, [ = ]( qreal v ) {
|
||||||
auto m = chart->arcMetricsHint( QskControl::Background );
|
auto m = chart->arcMetricsHint( subcontrol );
|
||||||
m.setStartAngle( v );
|
m.setStartAngle( v );
|
||||||
chart->setArcMetricsHint( QskControl::Background, m );
|
chart->setArcMetricsHint( subcontrol, m );
|
||||||
} );
|
} );
|
||||||
|
|
||||||
connect( controlPanel, &ControlPanel::spanAngleChanged, chart, [ chart ](qreal v) {
|
connect( controlPanel, &ControlPanel::spanAngleChanged, chart, [ = ]( qreal v ) {
|
||||||
auto m = chart->arcMetricsHint( QskControl::Background );
|
auto m = chart->arcMetricsHint( subcontrol );
|
||||||
m.setSpanAngle( v );
|
m.setSpanAngle( v );
|
||||||
chart->setArcMetricsHint( QskControl::Background, m );
|
chart->setArcMetricsHint( subcontrol, m );
|
||||||
} );
|
} );
|
||||||
|
|
||||||
|
connect( controlPanel, &ControlPanel::offsetXChanged, chart, [ = ]( qreal v ) {
|
||||||
|
auto h = chart->shadowMetricsHint( subcontrol );
|
||||||
|
h.setOffsetX( v );
|
||||||
|
chart->setShadowMetricsHint( subcontrol, h );
|
||||||
|
} );
|
||||||
|
|
||||||
|
connect( controlPanel, &ControlPanel::offsetYChanged, chart, [ = ]( qreal v ) {
|
||||||
|
auto h = chart->shadowMetricsHint( subcontrol );
|
||||||
|
h.setOffsetY( v );
|
||||||
|
chart->setShadowMetricsHint( subcontrol, h );
|
||||||
|
} );
|
||||||
|
|
||||||
|
connect( controlPanel, &ControlPanel::shadowExtendChanged, chart, [ = ]( qreal v ) {
|
||||||
|
auto h = chart->shadowMetricsHint( subcontrol );
|
||||||
|
h.setSpreadRadius( v );
|
||||||
|
chart->setShadowMetricsHint( subcontrol, h );
|
||||||
|
} );
|
||||||
|
|
||||||
|
connect( controlPanel, &ControlPanel::fillColorChanged, chart,
|
||||||
|
[ = ]( QColor c ) { chart->setColor( subcontrol, c ); } );
|
||||||
|
|
||||||
|
connect( controlPanel, &ControlPanel::shadowColorChanged, chart,
|
||||||
|
[ = ]( QColor c ) { chart->setShadowColorHint( subcontrol, c ); } );
|
||||||
|
|
||||||
setHeader( controlPanel );
|
setHeader( controlPanel );
|
||||||
setBody( hBox );
|
setBody( hBox );
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,10 +7,17 @@
|
||||||
|
|
||||||
#include <QskMainView.h>
|
#include <QskMainView.h>
|
||||||
|
|
||||||
|
class ArcControl : public QskControl
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
QSK_SUBCONTROLS(Arc)
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
class CircularChart;
|
class CircularChart;
|
||||||
|
|
||||||
class ChartView : public QskMainView
|
class ChartView : public QskMainView
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
ChartView( QskControl*, QQuickItem* parent = nullptr );
|
ChartView( ArcControl*, QQuickItem* parent = nullptr );
|
||||||
};
|
};
|
||||||
|
|
|
@ -10,6 +10,7 @@
|
||||||
#include <QskIntervalF.h>
|
#include <QskIntervalF.h>
|
||||||
#include <QskArcMetrics.h>
|
#include <QskArcMetrics.h>
|
||||||
#include <QskArcNode.h>
|
#include <QskArcNode.h>
|
||||||
|
#include <QskShadowMetrics.h>
|
||||||
|
|
||||||
#include <qpainterpath.h>
|
#include <qpainterpath.h>
|
||||||
#include <qmath.h>
|
#include <qmath.h>
|
||||||
|
@ -366,7 +367,7 @@ QSGNode* CircularChartSkinlet::updateArcSegmentNode(
|
||||||
arcNode = new QskArcNode();
|
arcNode = new QskArcNode();
|
||||||
|
|
||||||
arcNode->setArcData( m_data->closedArcRect, metrics,
|
arcNode->setArcData( m_data->closedArcRect, metrics,
|
||||||
borderWidth, borderColor, fillGradient );
|
borderWidth, borderColor, fillGradient, {}, {} );
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
return arcNode;
|
return arcNode;
|
||||||
|
|
|
@ -14,6 +14,7 @@
|
||||||
#include <QskSkinlet.h>
|
#include <QskSkinlet.h>
|
||||||
#include <QskArcNode.h>
|
#include <QskArcNode.h>
|
||||||
#include <QskArcMetrics.h>
|
#include <QskArcMetrics.h>
|
||||||
|
#include <QskShadowMetrics.h>
|
||||||
|
|
||||||
#include <SkinnyShortcut.h>
|
#include <SkinnyShortcut.h>
|
||||||
#include <QGuiApplication>
|
#include <QGuiApplication>
|
||||||
|
@ -64,6 +65,8 @@ namespace
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
using Q = ArcControl;
|
||||||
|
|
||||||
class ArcSkinlet : public QskSkinlet
|
class ArcSkinlet : public QskSkinlet
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
@ -71,6 +74,7 @@ class ArcSkinlet : public QskSkinlet
|
||||||
{
|
{
|
||||||
Arc
|
Arc
|
||||||
};
|
};
|
||||||
|
|
||||||
ArcSkinlet( QskSkin* skin = nullptr )
|
ArcSkinlet( QskSkin* skin = nullptr )
|
||||||
: QskSkinlet( skin )
|
: QskSkinlet( skin )
|
||||||
{
|
{
|
||||||
|
@ -85,14 +89,20 @@ class ArcSkinlet : public QskSkinlet
|
||||||
auto* const arcNode =
|
auto* const arcNode =
|
||||||
( node == nullptr ) ? new QskArcNode : static_cast< QskArcNode* >( node );
|
( node == nullptr ) ? new QskArcNode : static_cast< QskArcNode* >( node );
|
||||||
|
|
||||||
const auto* const q = static_cast< const QskControl* >( skinnable );
|
const auto* const q = static_cast< const Q* >( skinnable );
|
||||||
|
|
||||||
const auto rect = q->contentsRect();
|
const auto rect = q->contentsRect();
|
||||||
const auto metrics = skinnable->arcMetricsHint(QskControl::Background);
|
const auto metrics = skinnable->arcMetricsHint(Q::Arc);
|
||||||
const auto path = metrics.painterPath(rect);
|
|
||||||
const auto borderColor = q->color(QskControl::Background | QskAspect::Border);
|
const auto fillGradient = q->gradientHint(Q::Arc);
|
||||||
const auto borderWidth = q->metric(QskControl::Background | QskAspect::Border);
|
|
||||||
arcNode->setArcData( rect, metrics, borderWidth, borderColor, { Qt::red } );
|
const auto borderColor = q->color(Q::Arc | QskAspect::Border);
|
||||||
|
const auto borderWidth = q->metric(Q::Arc | QskAspect::Border);
|
||||||
|
|
||||||
|
const auto shadowColor = q->shadowColorHint(Q::Arc);
|
||||||
|
const auto shadowMetrics = q->shadowMetricsHint(Q::Arc);
|
||||||
|
|
||||||
|
arcNode->setArcData( rect, metrics, borderWidth, borderColor, fillGradient, shadowColor, shadowMetrics);
|
||||||
return arcNode;
|
return arcNode;
|
||||||
}
|
}
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
@ -109,7 +119,7 @@ int main( int argc, char* argv[] )
|
||||||
|
|
||||||
SkinnyShortcut::enable( SkinnyShortcut::AllShortcuts );
|
SkinnyShortcut::enable( SkinnyShortcut::AllShortcuts );
|
||||||
|
|
||||||
auto* const control = new QskControl;
|
auto* const control = new ArcControl;
|
||||||
auto* const skinlet = new ArcSkinlet;
|
auto* const skinlet = new ArcSkinlet;
|
||||||
control->setSkinlet(skinlet);
|
control->setSkinlet(skinlet);
|
||||||
skinlet->setOwnedBySkinnable(true);
|
skinlet->setOwnedBySkinnable(true);
|
||||||
|
@ -117,9 +127,18 @@ int main( int argc, char* argv[] )
|
||||||
QskArcMetrics metrics;
|
QskArcMetrics metrics;
|
||||||
metrics.setSpanAngle(270);
|
metrics.setSpanAngle(270);
|
||||||
metrics.setThickness(10);
|
metrics.setThickness(10);
|
||||||
control->setArcMetricsHint(QskControl::Background, metrics);
|
|
||||||
control->setMetric(QskControl::Background | QskAspect::Border, 4);
|
QskShadowMetrics shadowMetrics;
|
||||||
control->setColor(QskControl::Background | QskAspect::Border, Qt::blue);
|
shadowMetrics.setSpreadRadius(10);
|
||||||
|
shadowMetrics.setSizeMode(Qt::SizeMode::RelativeSize);
|
||||||
|
|
||||||
|
control->setBackgroundColor(Qt::white);
|
||||||
|
control->setGradientHint(Q::Arc, {Qt::red});
|
||||||
|
control->setArcMetricsHint(Q::Arc, metrics);
|
||||||
|
control->setMetric(Q::Arc | QskAspect::Border, 4);
|
||||||
|
control->setColor(Q::Arc | QskAspect::Border, Qt::blue);
|
||||||
|
control->setShadowColorHint(Q::Arc, Qt::blue);
|
||||||
|
control->setShadowMetricsHint(Q::Arc, shadowMetrics);
|
||||||
|
|
||||||
QskWindow window;
|
QskWindow window;
|
||||||
window.addItem( new ChartView( control ) );
|
window.addItem( new ChartView( control ) );
|
||||||
|
|
|
@ -231,7 +231,7 @@ static inline QSGNode* qskUpdateArcNode(
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
|
||||||
auto arcNode = QskSGNode::ensureNode< QskArcNode >( node );
|
auto arcNode = QskSGNode::ensureNode< QskArcNode >( node );
|
||||||
arcNode->setArcData( rect, metrics, borderWidth, borderColor, gradient );
|
arcNode->setArcData( rect, metrics, borderWidth, borderColor, gradient, {}, {} );
|
||||||
|
|
||||||
return arcNode;
|
return arcNode;
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,6 +10,7 @@
|
||||||
#include "QskShapeNode.h"
|
#include "QskShapeNode.h"
|
||||||
#include "QskStrokeNode.h"
|
#include "QskStrokeNode.h"
|
||||||
#include "QskSGNode.h"
|
#include "QskSGNode.h"
|
||||||
|
#include "QskShadowMetrics.h"
|
||||||
|
|
||||||
#include <qpen.h>
|
#include <qpen.h>
|
||||||
#include <qpainterpath.h>
|
#include <qpainterpath.h>
|
||||||
|
@ -25,6 +26,7 @@ namespace
|
||||||
{
|
{
|
||||||
QColor color = Qt::red;
|
QColor color = Qt::red;
|
||||||
QRectF rect;
|
QRectF rect;
|
||||||
|
QPointF offset;
|
||||||
qreal radius = 1.0; // [0.0,1.0]
|
qreal radius = 1.0; // [0.0,1.0]
|
||||||
qreal thickness = 0.2;
|
qreal thickness = 0.2;
|
||||||
qreal startAngle = 0.0; //< degree [0.0,360.0]
|
qreal startAngle = 0.0; //< degree [0.0,360.0]
|
||||||
|
@ -61,6 +63,7 @@ namespace
|
||||||
const auto& startAngle = newState->startAngle;
|
const auto& startAngle = newState->startAngle;
|
||||||
const auto& spanAngle = newState->spanAngle;
|
const auto& spanAngle = newState->spanAngle;
|
||||||
const auto& extend = newState->extend;
|
const auto& extend = newState->extend;
|
||||||
|
const auto& offset = newState->offset;
|
||||||
|
|
||||||
auto& p = *program();
|
auto& p = *program();
|
||||||
p.setUniformValue( "color", color.redF(), color.greenF(), color.blueF(), 1.0f );
|
p.setUniformValue( "color", color.redF(), color.greenF(), color.blueF(), 1.0f );
|
||||||
|
@ -70,8 +73,8 @@ namespace
|
||||||
p.setUniformValue( "startAngle", ( float ) startAngle - 90.0f );
|
p.setUniformValue( "startAngle", ( float ) startAngle - 90.0f );
|
||||||
p.setUniformValue( "spanAngle", ( float ) spanAngle );
|
p.setUniformValue( "spanAngle", ( float ) spanAngle );
|
||||||
p.setUniformValue( "extend", ( float ) extend );
|
p.setUniformValue( "extend", ( float ) extend );
|
||||||
|
p.setUniformValue( "offset", ( float ) offset.x(), ( float ) offset.y() );
|
||||||
}
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class QskArcShadowNode : public QSGGeometryNode
|
class QskArcShadowNode : public QSGGeometryNode
|
||||||
|
@ -85,10 +88,11 @@ namespace
|
||||||
material()->setFlag(QSGMaterial::Blending);
|
material()->setFlag(QSGMaterial::Blending);
|
||||||
}
|
}
|
||||||
|
|
||||||
void update(const QRectF& rect, const QskArcMetrics& metrics, const QColor& color, const qreal extend)
|
void update(const QRectF& rect, const QskArcMetrics& metrics, const QColor& color, const QskShadowMetrics& shadowMetrics = {}, const qreal borderWidth = 0.0)
|
||||||
{
|
{
|
||||||
auto* const vertices = geometry()->vertexDataAsPoint2D();
|
auto* const vertices = geometry()->vertexDataAsPoint2D();
|
||||||
const auto r = rect.adjusted( 0, -4, +4, 0 );
|
const auto b = borderWidth / 2;
|
||||||
|
const auto r = rect.adjusted( -b, -b, +b, +b );
|
||||||
vertices[0].set(r.left(), r.top());
|
vertices[0].set(r.left(), r.top());
|
||||||
vertices[1].set(r.left(), r.bottom());
|
vertices[1].set(r.left(), r.bottom());
|
||||||
vertices[2].set(r.right(), r.top());
|
vertices[2].set(r.right(), r.top());
|
||||||
|
@ -100,11 +104,12 @@ namespace
|
||||||
auto& state = *material->state();
|
auto& state = *material->state();
|
||||||
state.color = color;
|
state.color = color;
|
||||||
state.rect = r;
|
state.rect = r;
|
||||||
state.radius = 1.0 - (metrics.thickness() + extend / 4) / size;
|
state.radius = 1.0 - (metrics.thickness() + borderWidth) / size;
|
||||||
state.thickness = 2 * metrics.thickness() / size;
|
state.thickness = 2 * metrics.thickness() / size;
|
||||||
state.startAngle = metrics.startAngle();
|
state.startAngle = metrics.startAngle();
|
||||||
state.spanAngle = metrics.spanAngle();
|
state.spanAngle = metrics.spanAngle();
|
||||||
state.extend = extend;
|
state.extend = shadowMetrics.spreadRadius();
|
||||||
|
state.offset = shadowMetrics.offset();
|
||||||
markDirty( QSGNode::DirtyMaterial );
|
markDirty( QSGNode::DirtyMaterial );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -165,11 +170,11 @@ QskArcNode::~QskArcNode()
|
||||||
void QskArcNode::setArcData( const QRectF& rect,
|
void QskArcNode::setArcData( const QRectF& rect,
|
||||||
const QskArcMetrics& arcMetrics, const QskGradient& fillGradient )
|
const QskArcMetrics& arcMetrics, const QskGradient& fillGradient )
|
||||||
{
|
{
|
||||||
setArcData( rect, arcMetrics, 0.0, QColor(), fillGradient );
|
setArcData( rect, arcMetrics, 0.0, QColor(), fillGradient, {}, {} );
|
||||||
}
|
}
|
||||||
|
|
||||||
void QskArcNode::setArcData( const QRectF& rect, const QskArcMetrics& arcMetrics,
|
void QskArcNode::setArcData( const QRectF& rect, const QskArcMetrics& arcMetrics,
|
||||||
qreal borderWidth, const QColor& borderColor, const QskGradient& fillGradient )
|
const qreal borderWidth, const QColor& borderColor, const QskGradient& fillGradient, const QColor& shadowColor, const QskShadowMetrics& shadowMetrics )
|
||||||
{
|
{
|
||||||
enum NodeRole
|
enum NodeRole
|
||||||
{
|
{
|
||||||
|
@ -201,7 +206,7 @@ void QskArcNode::setArcData( const QRectF& rect, const QskArcMetrics& arcMetrics
|
||||||
|
|
||||||
const auto path = metrics.painterPath( arcRect );
|
const auto path = metrics.painterPath( arcRect );
|
||||||
|
|
||||||
if ( true /* TODO */ )
|
if ( shadowColor.alpha() > 0.0 )
|
||||||
{
|
{
|
||||||
if ( shadowNode == nullptr )
|
if ( shadowNode == nullptr )
|
||||||
{
|
{
|
||||||
|
@ -209,8 +214,7 @@ void QskArcNode::setArcData( const QRectF& rect, const QskArcMetrics& arcMetrics
|
||||||
QskSGNode::setNodeRole( shadowNode, ShadowRole );
|
QskSGNode::setNodeRole( shadowNode, ShadowRole );
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto extend = 16.0;
|
shadowNode->update( arcRect, metrics, shadowColor, shadowMetrics, borderWidth );
|
||||||
shadowNode->update( arcRect, metrics, Qt::black, extend );
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -261,7 +265,7 @@ void QskArcNode::setArcData( const QRectF& rect, const QskArcMetrics& arcMetrics
|
||||||
{
|
{
|
||||||
removeAllChildNodes();
|
removeAllChildNodes();
|
||||||
|
|
||||||
for ( QSGNode* node : { ( QSGNode* ) shadowNode, ( QSGNode* ) fillNode, ( QSGNode* ) borderNode })
|
for ( QSGNode* node : { ( QSGNode* ) borderNode, ( QSGNode* ) shadowNode, ( QSGNode* ) fillNode })
|
||||||
{
|
{
|
||||||
if ( node != nullptr )
|
if ( node != nullptr )
|
||||||
{
|
{
|
||||||
|
|
|
@ -10,6 +10,7 @@
|
||||||
|
|
||||||
class QskArcMetrics;
|
class QskArcMetrics;
|
||||||
class QskGradient;
|
class QskGradient;
|
||||||
|
class QskShadowMetrics;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
For the moment a QPainterPath/QskShapeNode.
|
For the moment a QPainterPath/QskShapeNode.
|
||||||
|
@ -24,7 +25,8 @@ class QSK_EXPORT QskArcNode : public QskShapeNode
|
||||||
|
|
||||||
void setArcData( const QRectF&, const QskArcMetrics&, const QskGradient& );
|
void setArcData( const QRectF&, const QskArcMetrics&, const QskGradient& );
|
||||||
void setArcData( const QRectF&, const QskArcMetrics&,
|
void setArcData( const QRectF&, const QskArcMetrics&,
|
||||||
qreal borderWidth, const QColor& borderColor, const QskGradient& );
|
qreal borderWidth, const QColor& borderColor, const QskGradient&,
|
||||||
|
const QColor& shadowColor, const QskShadowMetrics& shadowMetrics);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -2,6 +2,7 @@ uniform lowp float qt_Opacity;
|
||||||
|
|
||||||
uniform lowp vec4 color;
|
uniform lowp vec4 color;
|
||||||
uniform lowp vec4 rect;
|
uniform lowp vec4 rect;
|
||||||
|
uniform lowp vec2 offset;
|
||||||
uniform lowp float radius;
|
uniform lowp float radius;
|
||||||
uniform lowp float thickness;
|
uniform lowp float thickness;
|
||||||
uniform lowp float startAngle;
|
uniform lowp float startAngle;
|
||||||
|
@ -36,9 +37,17 @@ void main()
|
||||||
// rotation
|
// rotation
|
||||||
float ra = radians(startAngle + spanAngle / 2.0);
|
float ra = radians(startAngle + spanAngle / 2.0);
|
||||||
{
|
{
|
||||||
|
p = p + offset;
|
||||||
|
|
||||||
float sin_ra = sin(ra);
|
float sin_ra = sin(ra);
|
||||||
float cos_ra = cos(ra);
|
float cos_ra = cos(ra);
|
||||||
p = mat2(cos_ra, -sin_ra, sin_ra, cos_ra) * p;
|
mat2 transform = mat2
|
||||||
|
(
|
||||||
|
cos_ra, -sin_ra,
|
||||||
|
sin_ra, cos_ra
|
||||||
|
);
|
||||||
|
|
||||||
|
p = transform * p;
|
||||||
}
|
}
|
||||||
|
|
||||||
// distance
|
// distance
|
||||||
|
@ -48,5 +57,5 @@ void main()
|
||||||
// coloring
|
// coloring
|
||||||
float v = 1.0 - abs(d) * e;
|
float v = 1.0 - abs(d) * e;
|
||||||
float a = d >= 0.0 && abs(d) < e ? v : 0.0; // alpha
|
float a = d >= 0.0 && abs(d) < e ? v : 0.0; // alpha
|
||||||
gl_FragColor = vec4(color.rgb, a) * qt_Opacity;
|
gl_FragColor = vec4(color.rgb, 1.0) * a * qt_Opacity;
|
||||||
}
|
}
|
Loading…
Reference in New Issue