use better ellipse ring shader
This commit is contained in:
parent
9f8bf9deaf
commit
af149c0e84
|
@ -126,6 +126,8 @@ 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 sliderOffsetY = new SliderBox( "Offset Y", 0.0, 100.0, 0 );
|
||||||
|
|
||||||
connect( sliderStart, &SliderBox::valueChanged,
|
connect( sliderStart, &SliderBox::valueChanged,
|
||||||
this, &ControlPanel::startAngleChanged );
|
this, &ControlPanel::startAngleChanged );
|
||||||
|
@ -198,28 +200,38 @@ namespace
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ChartView::ChartView( CircularChart* chart, QQuickItem* parent )
|
ChartView::ChartView( QskControl* chart, QQuickItem* parent )
|
||||||
: QskMainView( parent )
|
: QskMainView( parent )
|
||||||
{
|
{
|
||||||
auto hBox = new QskLinearBox( Qt::Horizontal );
|
auto hBox = new QskLinearBox( Qt::Horizontal );
|
||||||
|
|
||||||
auto chartBox = new ChartBox( chart, hBox );
|
// auto chartBox = new ChartBox( chart, hBox );
|
||||||
|
|
||||||
auto legend = new Legend( hBox );
|
// auto legend = new Legend( hBox );
|
||||||
legend->setSizePolicy( QskSizePolicy::Fixed, QskSizePolicy::Fixed );
|
// legend->setSizePolicy( QskSizePolicy::Fixed, QskSizePolicy::Fixed );
|
||||||
legend->setSamples( chart->series() );
|
// 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 );
|
controlPanel->setSizePolicy( Qt::Vertical, QskSizePolicy::Fixed );
|
||||||
|
|
||||||
connect( controlPanel, &ControlPanel::thicknessChanged,
|
connect( controlPanel, &ControlPanel::thicknessChanged, chart, [ chart ](qreal v) {
|
||||||
chartBox, &ChartBox::setThickness );
|
auto m = chart->arcMetricsHint( QskControl::Background );
|
||||||
|
m.setThickness(v);
|
||||||
|
chart->setArcMetricsHint( QskControl::Background, m );
|
||||||
|
} );
|
||||||
|
|
||||||
connect( controlPanel, &ControlPanel::startAngleChanged,
|
connect( controlPanel, &ControlPanel::startAngleChanged, chart, [ chart ](qreal v) {
|
||||||
chartBox, &ChartBox::setStartAngle );
|
auto m = chart->arcMetricsHint( QskControl::Background );
|
||||||
|
m.setStartAngle(v);
|
||||||
|
chart->setArcMetricsHint( QskControl::Background, m );
|
||||||
|
} );
|
||||||
|
|
||||||
connect( controlPanel, &ControlPanel::spanAngleChanged,
|
connect( controlPanel, &ControlPanel::spanAngleChanged, chart, [ chart ](qreal v) {
|
||||||
chartBox, &ChartBox::setSpanAngle );
|
auto m = chart->arcMetricsHint( QskControl::Background );
|
||||||
|
m.setSpanAngle(v);
|
||||||
|
chart->setArcMetricsHint( QskControl::Background, m );
|
||||||
|
} );
|
||||||
|
|
||||||
setHeader( controlPanel );
|
setHeader( controlPanel );
|
||||||
setBody( hBox );
|
setBody( hBox );
|
||||||
|
|
|
@ -12,5 +12,5 @@ class CircularChart;
|
||||||
class ChartView : public QskMainView
|
class ChartView : public QskMainView
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
ChartView( CircularChart*, QQuickItem* parent = nullptr );
|
ChartView( QskControl*, QQuickItem* parent = nullptr );
|
||||||
};
|
};
|
||||||
|
|
|
@ -269,7 +269,8 @@ QSGNode* CircularChartSkinlet::updateSubNode(
|
||||||
}
|
}
|
||||||
|
|
||||||
case SegmentRole:
|
case SegmentRole:
|
||||||
return updateSeriesNode( skinnable, Q::Segment, node );
|
//return updateSeriesNode( skinnable, Q::Segment, node );
|
||||||
|
return Inherited::updateSubNode( skinnable, nodeRole, node );
|
||||||
|
|
||||||
case SegmentLabelRole:
|
case SegmentLabelRole:
|
||||||
return updateSeriesNode( skinnable, Q::SegmentLabel, node );
|
return updateSeriesNode( skinnable, Q::SegmentLabel, node );
|
||||||
|
@ -314,16 +315,16 @@ QSGNode* CircularChartSkinlet::updateSampleNode( const QskSkinnable* skinnable,
|
||||||
|
|
||||||
const auto chart = static_cast< const CircularChart* >( skinnable );
|
const auto chart = static_cast< const CircularChart* >( skinnable );
|
||||||
|
|
||||||
if ( subControl == Q::Segment )
|
if ( subControl == Q::Segment )
|
||||||
{
|
{
|
||||||
const auto aspect = Q::Segment | QskAspect::Border;
|
const auto aspect = Q::Segment | QskAspect::Border;
|
||||||
|
|
||||||
const auto borderColor = skinnable->color( aspect );
|
const auto borderColor = skinnable->color( aspect );
|
||||||
const auto borderWidth = skinnable->metric( aspect );
|
const auto borderWidth = skinnable->metric( aspect );
|
||||||
|
|
||||||
return updateArcSegmentNode( skinnable, node, borderWidth, borderColor,
|
return updateArcSegmentNode( skinnable, node, borderWidth, borderColor,
|
||||||
chart->gradientAt( index ), ::segmentMetrics( skinnable, index ) );
|
chart->gradientAt( index ), ::segmentMetrics( skinnable, index ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( subControl == Q::SegmentLabel )
|
if ( subControl == Q::SegmentLabel )
|
||||||
{
|
{
|
||||||
|
|
|
@ -11,10 +11,15 @@
|
||||||
#include <QskFocusIndicator.h>
|
#include <QskFocusIndicator.h>
|
||||||
#include <QskObjectCounter.h>
|
#include <QskObjectCounter.h>
|
||||||
#include <QskRgbValue.h>
|
#include <QskRgbValue.h>
|
||||||
|
#include <QskSkinlet.h>
|
||||||
|
#include <QskArcNode.h>
|
||||||
|
#include <QskArcMetrics.h>
|
||||||
|
|
||||||
#include <SkinnyShortcut.h>
|
#include <SkinnyShortcut.h>
|
||||||
#include <QGuiApplication>
|
#include <QGuiApplication>
|
||||||
|
|
||||||
|
#include <qpainterpath.h>
|
||||||
|
|
||||||
namespace
|
namespace
|
||||||
{
|
{
|
||||||
class DistroChart : public CircularChart
|
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[] )
|
int main( int argc, char* argv[] )
|
||||||
{
|
{
|
||||||
#ifdef ITEM_STATISTICS
|
#ifdef ITEM_STATISTICS
|
||||||
|
@ -69,8 +109,20 @@ int main( int argc, char* argv[] )
|
||||||
|
|
||||||
SkinnyShortcut::enable( SkinnyShortcut::AllShortcuts );
|
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;
|
QskWindow window;
|
||||||
window.addItem( new ChartView( new DistroChart() ) );
|
window.addItem( new ChartView( control ) );
|
||||||
window.addItem( new QskFocusIndicator() );
|
window.addItem( new QskFocusIndicator() );
|
||||||
window.resize( 600, 500 );
|
window.resize( 600, 500 );
|
||||||
window.show();
|
window.show();
|
||||||
|
|
|
@ -87,12 +87,20 @@ namespace
|
||||||
|
|
||||||
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 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* const material = static_cast<QSGSimpleMaterial< QskArcShadowMaterialProperties >*>(this->material());
|
||||||
auto& state = *material->state();
|
auto& state = *material->state();
|
||||||
state.color = color;
|
state.color = color;
|
||||||
state.rect = rect;
|
state.rect = r;
|
||||||
state.radius = 1.0 - metrics.thickness() / size;
|
state.radius = 1.0 - (metrics.thickness() + extend / 4) / 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();
|
||||||
|
@ -202,15 +210,7 @@ void QskArcNode::setArcData( const QRectF& rect, const QskArcMetrics& arcMetrics
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto extend = 16.0;
|
const auto extend = 16.0;
|
||||||
const auto e = extend / 4;
|
shadowNode->update( arcRect, metrics, Qt::black, extend );
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
uniform lowp float qt_Opacity;
|
uniform lowp float qt_Opacity;
|
||||||
|
|
||||||
uniform lowp vec4 color;
|
uniform lowp vec4 color;
|
||||||
uniform lowp vec4 rect;
|
uniform lowp vec4 rect;
|
||||||
uniform lowp float radius;
|
uniform lowp float radius;
|
||||||
|
|
Loading…
Reference in New Issue