Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

QskArcShadownode #350

Closed
wants to merge 15 commits into from
318 changes: 298 additions & 20 deletions playground/charts/ChartView.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,169 @@
#include <QskTextLabel.h>
#include <QskGraphicLabel.h>
#include <QskSlider.h>
#include <QskShadowMetrics.h>
#include <QskBoxBorderColors.h>
#include <QskBoxBorderMetrics.h>

#include <qpainter.h>

QSK_SUBCONTROL(ArcControl, Arc)

namespace
{
class LinearGradientSlider : public QskSlider
{
Q_OBJECT
Q_PROPERTY( QColor selectedColor READ selectedColor NOTIFY selectedColorChanged )
using Inherited = QskSlider;

public:
QSK_STATES( Grayscale, Alpha )

explicit LinearGradientSlider( QQuickItem* parent = nullptr );
explicit LinearGradientSlider( Qt::Orientation orientation, QQuickItem* parent = nullptr );
QColor selectedColor() const;

protected:
void mousePressEvent( QMouseEvent* event ) override
{
if ( event->button() == Qt::RightButton )
{
// RGB->GRAYSCALE->ALPHA
const auto a = skinStates().testFlag(Alpha);
const auto g = skinStates().testFlag(Grayscale);

if ( g )
{
setSkinStateFlag( Grayscale, false );
setSkinStateFlag( Alpha, true );
}
else if ( a )
{
setSkinStateFlag( Grayscale, false );
setSkinStateFlag( Alpha, false );
}
else
{
setSkinStateFlag( Grayscale, true );
setSkinStateFlag( Alpha, false );
}
}
else
{
QskSlider::mousePressEvent( event );
}
}

void mouseReleaseEvent( QMouseEvent* event ) override
{
if ( event->button() == Qt::RightButton ) {}
else
{
QskSlider::mouseReleaseEvent( event );
}
}

Q_SIGNALS:
void selectedColorChanged();

private:

QColor colorForPosition(const QskGradient& gradient, qreal ratio)
{
return gradient.extracted( ratio, ratio ).startColor();
}

QColor m_color;
};

QSK_STATE( LinearGradientSlider, Grayscale, QskAspect::FirstUserState << 0 )
QSK_STATE( LinearGradientSlider, Alpha, QskAspect::FirstUserState << 1 )

LinearGradientSlider::LinearGradientSlider( QQuickItem* parent )
: LinearGradientSlider( Qt::Horizontal, parent )
{
}

LinearGradientSlider::LinearGradientSlider( Qt::Orientation orientation, QQuickItem* parent )
: Inherited( orientation, parent )
{
static const QskGradientStops stopsRGB = {
{ 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 ) },
};

static const QskGradientStops stopsGrayscale = {
{ 0.0000, QColor::fromRgb( 0, 0, 0 ) },
{ 1.0000, QColor::fromRgb( 255, 255, 255 ) },
};

static const QskGradientStops stopsAlpha = {
{ 0.0000, QColor::fromRgb( 0, 0, 0, 0) },
{ 1.0000, QColor::fromRgb( 0, 0, 0, 255 ) },
};

auto make_gradient = []( const QskGradientStops& stops, Qt::Orientation orientation ) {
QskGradient gradient(stops);
gradient.setLinearDirection(orientation);
return gradient;
};

static constexpr auto Horizontal = static_cast<QskAspect::Variation>(Qt::Horizontal);
static constexpr auto Vertical = static_cast<QskAspect::Variation>(Qt::Vertical);

setColor( Fill, Qt::transparent );

setGradientHint( Groove, make_gradient(stopsRGB, Qt::Horizontal) );
setGradientHint( Groove | Horizontal, make_gradient(stopsRGB, Qt::Horizontal) );
setGradientHint( Groove | Vertical, make_gradient(stopsRGB, Qt::Vertical) );

setGradientHint( Groove | Grayscale, make_gradient( stopsGrayscale, Qt::Horizontal ) );
setGradientHint( Groove | Grayscale | Horizontal, make_gradient( stopsGrayscale, Qt::Horizontal ) );
setGradientHint( Groove | Grayscale | Vertical, make_gradient( stopsGrayscale, Qt::Vertical ) );

setGradientHint( Groove | Alpha, make_gradient( stopsGrayscale, Qt::Horizontal ) );
setGradientHint( Groove | Alpha | Horizontal, make_gradient( stopsGrayscale, Qt::Horizontal ) );
setGradientHint( Groove | Alpha | Vertical, make_gradient( stopsGrayscale, Qt::Vertical ) );

setBoxBorderColorsHint( Handle, Qt::white );
setBoxBorderMetricsHint( Handle, 2 );

connect( this, &QskSlider::valueChanged, this, [ this ]( qreal value ) {
value = this->orientation() == Qt::Horizontal ? value : 1.0 - value;
const auto gradient = gradientHint(Groove);
const auto selectedColor = colorForPosition(gradient, value);
setColor( Inherited::Handle, selectedColor );
setColor( Inherited::Ripple, selectedColor );
setBoxBorderColorsHint( Inherited::Handle, Qt::white );
if(skinStates().testFlag(Alpha))
{
m_color.setAlpha(value * 255);
}
else
{
m_color.setRed(selectedColor.red());
m_color.setGreen(selectedColor.green());
m_color.setBlue(selectedColor.blue());
}
Q_EMIT selectedColorChanged();
} );

valueChanged(0.0);

setAcceptedMouseButtons(Qt::LeftButton | Qt::RightButton);
}

QColor LinearGradientSlider::selectedColor() const
{
return m_color;
}

class ChartBox : public QskControl
{
Q_OBJECT
Expand Down Expand Up @@ -83,18 +241,21 @@ namespace
}

namespace
{
{
class SliderBox : public QskLinearBox
{
Q_OBJECT

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 );
textLabel->setSizePolicy( Qt::Horizontal, QskSizePolicy::Fixed );

auto slider = new QskSlider( this );
auto slider = allocator( this );
slider->setBoundaries( min, max );
slider->setValue( value );
slider->setStepSize( 1.0 );
Expand All @@ -110,7 +271,7 @@ namespace
}

namespace
{
{
class ControlPanel : public QskGridBox
{
Q_OBJECT
Expand All @@ -126,6 +287,14 @@ 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 spreadRadius = new SliderBox( "Spread Radius", 0.0, 1.0, 0.01 );
auto blurRadius = new SliderBox( "Blur Radius", 0.0, 1.0, 0.01 );
auto sliderOffsetX = new SliderBox( "Offset X", -1.0, +1.0, 0 );
auto sliderOffsetY = new SliderBox( "Offset Y", -1.0, +1.0, 0 );
auto sliderStrokeWidth = new SliderBox( "Stroke Width", 0, 10, 1 );
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 ); } );
auto sliderStrokeColor = new SliderBox( "Stroke Color", 0.0, 1.0, 0, []( QQuickItem* parent = nullptr ) { return new LinearGradientSlider( parent ); } );

connect( sliderStart, &SliderBox::valueChanged,
this, &ControlPanel::startAngleChanged );
Expand All @@ -136,15 +305,67 @@ namespace
connect( sliderExtent, &SliderBox::valueChanged,
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( spreadRadius, &SliderBox::valueChanged,
this, &ControlPanel::spreadRadiusChanged );

connect( blurRadius, &SliderBox::valueChanged,
this, &ControlPanel::blurRadiusChanged );

connect( sliderStrokeWidth, &SliderBox::valueChanged,
this, &ControlPanel::strokeWidthChanged );

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());
} );

connect( sliderStrokeColor, &SliderBox::valueChanged, this, [=](){
auto* const slider = sliderStrokeColor->findChild<LinearGradientSlider*>();
Q_EMIT strokeColorChanged(slider->selectedColor());
} );

addItem( sliderStart, 0, 0 );
addItem( sliderExtent, 0, 1 );
addItem( sliderSpan, 1, 0, 1, 2 );
addItem( sliderSpan, 0, 2);

addItem( spreadRadius, 1, 0 );
addItem( blurRadius, 1, 1 );
addItem( sliderStrokeWidth, 1, 2);

addItem( sliderOffsetX, 2, 0 );
addItem( sliderOffsetY, 2, 1 );

addItem( sliderStrokeColor, 3, 0);
addItem( sliderFillColor, 3, 1);
addItem( sliderShadowColor, 3, 2);
}

Q_SIGNALS:
void thicknessChanged( qreal );
void startAngleChanged( qreal );
void spanAngleChanged( qreal );
void offsetXChanged( qreal );
void offsetYChanged( qreal );
void fillColorChanged( QColor );
void strokeColorChanged( QColor );
void shadowColorChanged( QColor );
void spreadRadiusChanged( qreal );
void blurRadiusChanged( qreal );
void strokeWidthChanged( qreal );
};

class Legend : public QskGridBox
Expand Down Expand Up @@ -198,28 +419,85 @@ namespace

}

ChartView::ChartView( CircularChart* chart, QQuickItem* parent )
ChartView::ChartView( ArcControl* chart, QQuickItem* parent )
: QskMainView( parent )
{
setColor(Panel, Qt::white);

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);
hBox->setDefaultAlignment(Qt::AlignCenter);
hBox->setMargins(16);

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

connect( controlPanel, &ControlPanel::spanAngleChanged,
chartBox, &ChartBox::setSpanAngle );

const auto subcontrol = ArcControl::Arc;

connect( controlPanel, &ControlPanel::thicknessChanged, chart, [ = ]( qreal v ) {
auto m = chart->arcMetricsHint( subcontrol );
m.setThickness( v ) ;
chart->setArcMetricsHint( subcontrol, m );
} );

connect( controlPanel, &ControlPanel::startAngleChanged, chart, [ = ]( qreal v ) {
auto m = chart->arcMetricsHint( subcontrol );
m.setStartAngle( v );
chart->setArcMetricsHint( subcontrol, m );
} );

connect( controlPanel, &ControlPanel::spanAngleChanged, chart, [ = ]( qreal v ) {
auto m = chart->arcMetricsHint( subcontrol );
m.setSpanAngle( v );
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::spreadRadiusChanged, chart, [ = ]( qreal v ) {
auto h = chart->shadowMetricsHint( subcontrol );
h.setSpreadRadius( v );
chart->setShadowMetricsHint( subcontrol, h );
} );

connect( controlPanel, &ControlPanel::blurRadiusChanged, chart, [ = ]( qreal v ) {
auto h = chart->shadowMetricsHint( subcontrol );
h.setBlurRadius( 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 );
} );

connect( controlPanel, &ControlPanel::strokeColorChanged, chart,
[ = ]( QColor c ) {
chart->setColor( subcontrol | QskAspect::Border, c );
} );

connect( controlPanel, &ControlPanel::strokeWidthChanged, chart, [ = ]( qreal v ) {
chart->setMetric(subcontrol | QskAspect::Border, v);
} );

setHeader( controlPanel );
setBody( hBox );
Expand Down
Loading
Loading