use better ellipse ring shader

This commit is contained in:
Vogel, Rick 2023-12-05 12:13:39 +01:00
parent 9f8bf9deaf
commit af149c0e84
6 changed files with 105 additions and 39 deletions

View File

@ -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,
chartBox, &ChartBox::setThickness );
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::startAngleChanged,
chartBox, &ChartBox::setStartAngle );
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::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 );

View File

@ -12,5 +12,5 @@ class CircularChart;
class ChartView : public QskMainView
{
public:
ChartView( CircularChart*, QQuickItem* parent = nullptr );
ChartView( QskControl*, QQuickItem* parent = nullptr );
};

View File

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

View File

@ -11,10 +11,15 @@
#include <QskFocusIndicator.h>
#include <QskObjectCounter.h>
#include <QskRgbValue.h>
#include <QskSkinlet.h>
#include <QskArcNode.h>
#include <QskArcMetrics.h>
#include <SkinnyShortcut.h>
#include <QGuiApplication>
#include <qpainterpath.h>
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();

View File

@ -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<QSGSimpleMaterial< QskArcShadowMaterialProperties >*>(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();
@ -202,15 +210,7 @@ void QskArcNode::setArcData( const QRectF& rect, const QskArcMetrics& arcMetrics
}
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;
shadowNode->update( arcRect, metrics, Qt::black, extend );
}
else
{

View File

@ -1,4 +1,5 @@
uniform lowp float qt_Opacity;
uniform lowp vec4 color;
uniform lowp vec4 rect;
uniform lowp float radius;