diff --git a/playground/charts/ChartView.cpp b/playground/charts/ChartView.cpp index cbdc66cc..72eed589 100644 --- a/playground/charts/ChartView.cpp +++ b/playground/charts/ChartView.cpp @@ -126,6 +126,8 @@ namespace auto sliderStart = new SliderBox( "Angle", 0.0, 360.0, metrics.startAngle() ); auto sliderSpan = new SliderBox( "Span", -360.0, 360.0, metrics.spanAngle() ); auto sliderExtent = new SliderBox( "Extent", 10.0, 100.0, metrics.thickness() ); + auto sliderOffsetX = new SliderBox( "Offset X", 0.0, 100.0, 0 ); + auto sliderOffsetY = new SliderBox( "Offset Y", 0.0, 100.0, 0 ); connect( sliderStart, &SliderBox::valueChanged, this, &ControlPanel::startAngleChanged ); @@ -198,28 +200,38 @@ namespace } -ChartView::ChartView( CircularChart* chart, QQuickItem* parent ) +ChartView::ChartView( QskControl* chart, QQuickItem* parent ) : QskMainView( parent ) { auto hBox = new QskLinearBox( Qt::Horizontal ); - auto chartBox = new ChartBox( chart, hBox ); + // auto chartBox = new ChartBox( chart, hBox ); - auto legend = new Legend( hBox ); - legend->setSizePolicy( QskSizePolicy::Fixed, QskSizePolicy::Fixed ); - legend->setSamples( chart->series() ); + // auto legend = new Legend( hBox ); + // legend->setSizePolicy( QskSizePolicy::Fixed, QskSizePolicy::Fixed ); + // legend->setSamples( chart->series() ); + hBox->addItem(chart); - auto controlPanel = new ControlPanel( chartBox->arcMetrics() ); + auto controlPanel = new ControlPanel( chart->arcMetricsHint(QskControl::Background) ); controlPanel->setSizePolicy( Qt::Vertical, QskSizePolicy::Fixed ); + + connect( controlPanel, &ControlPanel::thicknessChanged, chart, [ chart ](qreal v) { + auto m = chart->arcMetricsHint( QskControl::Background ); + m.setThickness(v); + chart->setArcMetricsHint( QskControl::Background, m ); + } ); - connect( controlPanel, &ControlPanel::thicknessChanged, - chartBox, &ChartBox::setThickness ); + connect( controlPanel, &ControlPanel::startAngleChanged, chart, [ chart ](qreal v) { + auto m = chart->arcMetricsHint( QskControl::Background ); + m.setStartAngle(v); + chart->setArcMetricsHint( QskControl::Background, m ); + } ); - connect( controlPanel, &ControlPanel::startAngleChanged, - chartBox, &ChartBox::setStartAngle ); - - connect( controlPanel, &ControlPanel::spanAngleChanged, - chartBox, &ChartBox::setSpanAngle ); + connect( controlPanel, &ControlPanel::spanAngleChanged, chart, [ chart ](qreal v) { + auto m = chart->arcMetricsHint( QskControl::Background ); + m.setSpanAngle(v); + chart->setArcMetricsHint( QskControl::Background, m ); + } ); setHeader( controlPanel ); setBody( hBox ); diff --git a/playground/charts/ChartView.h b/playground/charts/ChartView.h index 808c6bd6..a60a2b8c 100644 --- a/playground/charts/ChartView.h +++ b/playground/charts/ChartView.h @@ -12,5 +12,5 @@ class CircularChart; class ChartView : public QskMainView { public: - ChartView( CircularChart*, QQuickItem* parent = nullptr ); + ChartView( QskControl*, QQuickItem* parent = nullptr ); }; diff --git a/playground/charts/CircularChartSkinlet.cpp b/playground/charts/CircularChartSkinlet.cpp index 79dc7217..b81c9f70 100644 --- a/playground/charts/CircularChartSkinlet.cpp +++ b/playground/charts/CircularChartSkinlet.cpp @@ -269,7 +269,8 @@ QSGNode* CircularChartSkinlet::updateSubNode( } case SegmentRole: - return updateSeriesNode( skinnable, Q::Segment, node ); + //return updateSeriesNode( skinnable, Q::Segment, node ); + return Inherited::updateSubNode( skinnable, nodeRole, node ); case SegmentLabelRole: return updateSeriesNode( skinnable, Q::SegmentLabel, node ); @@ -314,16 +315,16 @@ QSGNode* CircularChartSkinlet::updateSampleNode( const QskSkinnable* skinnable, const auto chart = static_cast< const CircularChart* >( skinnable ); - if ( subControl == Q::Segment ) - { - const auto aspect = Q::Segment | QskAspect::Border; - - const auto borderColor = skinnable->color( aspect ); - const auto borderWidth = skinnable->metric( aspect ); - - return updateArcSegmentNode( skinnable, node, borderWidth, borderColor, - chart->gradientAt( index ), ::segmentMetrics( skinnable, index ) ); - } + if ( subControl == Q::Segment ) + { + const auto aspect = Q::Segment | QskAspect::Border; + + const auto borderColor = skinnable->color( aspect ); + const auto borderWidth = skinnable->metric( aspect ); + + return updateArcSegmentNode( skinnable, node, borderWidth, borderColor, + chart->gradientAt( index ), ::segmentMetrics( skinnable, index ) ); + } if ( subControl == Q::SegmentLabel ) { diff --git a/playground/charts/main.cpp b/playground/charts/main.cpp index 90ab4688..aabd7a6a 100644 --- a/playground/charts/main.cpp +++ b/playground/charts/main.cpp @@ -11,10 +11,15 @@ #include #include #include +#include +#include +#include #include #include +#include + namespace { class DistroChart : public CircularChart @@ -59,6 +64,41 @@ namespace }; } +class ArcSkinlet : public QskSkinlet +{ + public: + enum NodeRoles + { + Arc + }; + ArcSkinlet( QskSkin* skin = nullptr ) + : QskSkinlet( skin ) + { + setNodeRoles( { Arc } ); + } + + QSGNode* updateSubNode( + const QskSkinnable* skinnable, quint8 nodeRole, QSGNode* node ) const override + { + if ( nodeRole == Arc ) + { + auto* const arcNode = + ( node == nullptr ) ? new QskArcNode : static_cast< QskArcNode* >( node ); + + const auto* const q = static_cast< const QskControl* >( skinnable ); + + const auto rect = q->contentsRect(); + const auto metrics = skinnable->arcMetricsHint(QskControl::Background); + const auto path = metrics.painterPath(rect); + const auto borderColor = q->color(QskControl::Background | QskAspect::Border); + const auto borderWidth = q->metric(QskControl::Background | QskAspect::Border); + arcNode->setArcData( rect, metrics, borderWidth, borderColor, { Qt::red } ); + return arcNode; + } + return nullptr; + } +}; + int main( int argc, char* argv[] ) { #ifdef ITEM_STATISTICS @@ -69,8 +109,20 @@ int main( int argc, char* argv[] ) SkinnyShortcut::enable( SkinnyShortcut::AllShortcuts ); + auto* const control = new QskControl; + auto* const skinlet = new ArcSkinlet; + control->setSkinlet(skinlet); + skinlet->setOwnedBySkinnable(true); + + QskArcMetrics metrics; + metrics.setSpanAngle(270); + metrics.setThickness(10); + control->setArcMetricsHint(QskControl::Background, metrics); + control->setMetric(QskControl::Background | QskAspect::Border, 4); + control->setColor(QskControl::Background | QskAspect::Border, Qt::blue); + QskWindow window; - window.addItem( new ChartView( new DistroChart() ) ); + window.addItem( new ChartView( control ) ); window.addItem( new QskFocusIndicator() ); window.resize( 600, 500 ); window.show(); diff --git a/src/nodes/QskArcNode.cpp b/src/nodes/QskArcNode.cpp index b14a97cc..be4fd192 100644 --- a/src/nodes/QskArcNode.cpp +++ b/src/nodes/QskArcNode.cpp @@ -87,12 +87,20 @@ namespace void update(const QRectF& rect, const QskArcMetrics& metrics, const QColor& color, const qreal extend) { - const auto size = qMin(rect.width(), rect.height()); + auto* const vertices = geometry()->vertexDataAsPoint2D(); + const auto r = rect.adjusted( 0, -4, +4, 0 ); + vertices[0].set(r.left(), r.top()); + vertices[1].set(r.left(), r.bottom()); + vertices[2].set(r.right(), r.top()); + vertices[3].set(r.right(), r.bottom()); + markDirty( QSGNode::DirtyGeometry ); + + const auto size = qMin(r.width(), r.height()); auto* const material = static_cast*>(this->material()); auto& state = *material->state(); state.color = color; - state.rect = rect; - state.radius = 1.0 - metrics.thickness() / size; + state.rect = r; + state.radius = 1.0 - (metrics.thickness() + extend / 4) / size; state.thickness = 2 * metrics.thickness() / size; state.startAngle = metrics.startAngle(); state.spanAngle = metrics.spanAngle(); @@ -201,16 +209,8 @@ void QskArcNode::setArcData( const QRectF& rect, const QskArcMetrics& arcMetrics QskSGNode::setNodeRole( shadowNode, ShadowRole ); } - const auto extend = 16.0; - const auto e = extend / 4; - auto* const vertices = shadowNode->geometry()->vertexDataAsPoint2D(); - const auto shadowRect = arcRect.adjusted( -e, +e, e, -e ); - vertices[0].set(shadowRect.left(), shadowRect.top()); - vertices[1].set(shadowRect.left(), shadowRect.bottom()); - vertices[2].set(shadowRect.right(), shadowRect.top()); - vertices[3].set(shadowRect.right(), shadowRect.bottom()); - shadowNode->update(shadowRect, metrics, Qt::black, extend); - qDebug() << shadowRect << arcRect; + const auto extend = 16.0; + shadowNode->update( arcRect, metrics, Qt::black, extend ); } else { diff --git a/src/nodes/shaders/arcshadow.frag b/src/nodes/shaders/arcshadow.frag index 77d369a8..49b44592 100644 --- a/src/nodes/shaders/arcshadow.frag +++ b/src/nodes/shaders/arcshadow.frag @@ -1,4 +1,5 @@ uniform lowp float qt_Opacity; + uniform lowp vec4 color; uniform lowp vec4 rect; uniform lowp float radius;