playing with shadows
This commit is contained in:
parent
1e9080ee82
commit
2438b0f7ee
|
@ -5,6 +5,7 @@ SUBDIRS += \
|
||||||
dialogbuttons \
|
dialogbuttons \
|
||||||
invoker \
|
invoker \
|
||||||
inputpanel \
|
inputpanel \
|
||||||
|
shadows \
|
||||||
images
|
images
|
||||||
|
|
||||||
qtHaveModule(webengine) {
|
qtHaveModule(webengine) {
|
||||||
|
|
|
@ -27,13 +27,12 @@ namespace
|
||||||
QSGMaterial* newMaterial, QSGMaterial* oldMaterial) override;
|
QSGMaterial* newMaterial, QSGMaterial* oldMaterial) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
int m_matrixLocation = -1;
|
int m_matrixId = -1;
|
||||||
int m_opacityLocation = -1;
|
int m_opacityId = -1;
|
||||||
int m_aspectLocation = -1;
|
int m_aspectId = -1;
|
||||||
int m_extentLocation = -1;
|
int m_blurExtentId = -1;
|
||||||
int m_radiusLocation = -1;
|
int m_radiusId = -1;
|
||||||
int m_colorLocation = -1;
|
int m_colorId = -1;
|
||||||
int m_offsetLocation = -1;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class Material final : public QSGMaterial
|
class Material final : public QSGMaterial
|
||||||
|
@ -48,10 +47,9 @@ namespace
|
||||||
int compare( const QSGMaterial* other ) const override;
|
int compare( const QSGMaterial* other ) const override;
|
||||||
|
|
||||||
QVector2D aspect = QVector2D{1.0, 1.0};
|
QVector2D aspect = QVector2D{1.0, 1.0};
|
||||||
float extent = 0.0;
|
float blurExtent = 0.0;
|
||||||
QVector4D radius = QVector4D{0.0, 0.0, 0.0, 0.0};
|
QVector4D radius = QVector4D{0.0, 0.0, 0.0, 0.0};
|
||||||
QColor color = Qt::black;
|
QColor color = Qt::black;
|
||||||
QVector2D offset;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
Shader::Shader()
|
Shader::Shader()
|
||||||
|
@ -74,13 +72,12 @@ namespace
|
||||||
|
|
||||||
auto p = program();
|
auto p = program();
|
||||||
|
|
||||||
m_matrixLocation = p->uniformLocation( "matrix" );
|
m_matrixId = p->uniformLocation( "matrix" );
|
||||||
m_aspectLocation = p->uniformLocation( "aspect" );
|
m_aspectId = p->uniformLocation( "aspect" );
|
||||||
m_opacityLocation = p->uniformLocation( "opacity" );
|
m_opacityId = p->uniformLocation( "opacity" );
|
||||||
m_extentLocation = p->uniformLocation( "extent" );
|
m_blurExtentId = p->uniformLocation( "blurExtent" );
|
||||||
m_offsetLocation = p->uniformLocation( "offset" );
|
m_radiusId = p->uniformLocation( "radius" );
|
||||||
m_radiusLocation = p->uniformLocation( "radius" );
|
m_colorId = p->uniformLocation( "color" );
|
||||||
m_colorLocation = p->uniformLocation( "color" );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Shader::updateState( const QSGMaterialShader::RenderState& state,
|
void Shader::updateState( const QSGMaterialShader::RenderState& state,
|
||||||
|
@ -89,20 +86,20 @@ namespace
|
||||||
auto p = program();
|
auto p = program();
|
||||||
|
|
||||||
if ( state.isMatrixDirty() )
|
if ( state.isMatrixDirty() )
|
||||||
p->setUniformValue(m_matrixLocation, state.combinedMatrix() );
|
p->setUniformValue( m_matrixId, state.combinedMatrix() );
|
||||||
|
|
||||||
if ( state.isOpacityDirty() )
|
if ( state.isOpacityDirty() )
|
||||||
p->setUniformValue(m_opacityLocation, state.opacity() );
|
p->setUniformValue( m_opacityId, state.opacity() );
|
||||||
|
|
||||||
if ( oldMaterial == nullptr || newMaterial->compare( oldMaterial ) != 0 )
|
if ( oldMaterial == nullptr || newMaterial->compare( oldMaterial ) != 0
|
||||||
|
|| state.isCachedMaterialDataDirty( ))
|
||||||
{
|
{
|
||||||
auto material = static_cast< const Material* >( newMaterial );
|
auto material = static_cast< const Material* >( newMaterial );
|
||||||
|
|
||||||
p->setUniformValue( m_aspectLocation, material->aspect );
|
p->setUniformValue( m_aspectId, material->aspect );
|
||||||
p->setUniformValue( m_extentLocation, material->extent );
|
p->setUniformValue( m_blurExtentId, material->blurExtent);
|
||||||
p->setUniformValue( m_radiusLocation, material->radius );
|
p->setUniformValue( m_radiusId, material->radius );
|
||||||
p->setUniformValue( m_colorLocation, material->color );
|
p->setUniformValue( m_colorId, material->color );
|
||||||
p->setUniformValue( m_offsetLocation, material->offset );
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -127,9 +124,8 @@ namespace
|
||||||
auto material = static_cast< const Material* >( other );
|
auto material = static_cast< const Material* >( other );
|
||||||
|
|
||||||
if ( material->color == color
|
if ( material->color == color
|
||||||
&& material->offset == offset
|
|
||||||
&& material->aspect == aspect
|
&& material->aspect == aspect
|
||||||
&& qFuzzyCompare(material->extent, extent)
|
&& qFuzzyCompare(material->blurExtent, blurExtent)
|
||||||
&& qFuzzyCompare(material->radius, radius) )
|
&& qFuzzyCompare(material->radius, radius) )
|
||||||
{
|
{
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -175,16 +171,16 @@ void BoxShadowNode::setRect( const QRectF& rect )
|
||||||
|
|
||||||
d->rect = rect;
|
d->rect = rect;
|
||||||
|
|
||||||
QVector2D newAspect( 1.0, 1.0 );
|
QVector2D aspect( 1.0, 1.0 );
|
||||||
|
|
||||||
if ( rect.width() >= rect.height() )
|
if ( rect.width() >= rect.height() )
|
||||||
newAspect.setX( rect.width() / rect.height() );
|
aspect.setX( rect.width() / rect.height() );
|
||||||
else
|
else
|
||||||
newAspect.setY( rect.height() / rect.width() );
|
aspect.setY( rect.height() / rect.width() );
|
||||||
|
|
||||||
if ( d->material.aspect != newAspect)
|
if ( d->material.aspect != aspect )
|
||||||
{
|
{
|
||||||
d->material.aspect = newAspect;
|
d->material.aspect = aspect;
|
||||||
markDirty( QSGNode::DirtyMaterial );
|
markDirty( QSGNode::DirtyMaterial );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -193,7 +189,7 @@ void BoxShadowNode::setShape( const QskBoxShapeMetrics& shape )
|
||||||
{
|
{
|
||||||
Q_D( BoxShadowNode );
|
Q_D( BoxShadowNode );
|
||||||
|
|
||||||
const float t = 0.5 * std::min( d->rect.width(), d->rect.height() );
|
const float t = std::min( d->rect.width(), d->rect.height() );
|
||||||
|
|
||||||
const float r1 = shape.radius( Qt::BottomRightCorner ).width();
|
const float r1 = shape.radius( Qt::BottomRightCorner ).width();
|
||||||
const float r2 = shape.radius( Qt::TopRightCorner ).width();
|
const float r2 = shape.radius( Qt::TopRightCorner ).width();
|
||||||
|
@ -228,51 +224,34 @@ void BoxShadowNode::setColor( const QColor& color )
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void BoxShadowNode::setShadow( qreal extent, qreal dx, qreal dy )
|
void BoxShadowNode::setBlurRadius( qreal blurRadius )
|
||||||
{
|
{
|
||||||
Q_D( BoxShadowNode );
|
Q_D( BoxShadowNode );
|
||||||
|
|
||||||
if ( extent <= 0.0 )
|
if ( blurRadius <= 0.0 )
|
||||||
extent = 0.0;
|
blurRadius = 0.0;
|
||||||
|
|
||||||
const auto minDimension = std::min( d->rect.width(), d->rect.height() );
|
const float t = 0.5 * std::min( d->rect.width(), d->rect.height() );
|
||||||
|
const float uniformExtent = blurRadius / t;
|
||||||
|
|
||||||
const float uniformExtent = ( extent / minDimension ) * 2.0;
|
if ( !qFuzzyCompare( d->material.blurExtent, uniformExtent ) )
|
||||||
|
|
||||||
if ( !qFuzzyCompare( d->material.extent, uniformExtent ) )
|
|
||||||
{
|
{
|
||||||
d->material.extent = uniformExtent;
|
d->material.blurExtent = uniformExtent;
|
||||||
markDirty( QSGNode::DirtyMaterial );
|
markDirty( QSGNode::DirtyMaterial );
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto uniformOffset = QVector2D( dx, dy ) / minDimension;
|
|
||||||
|
|
||||||
if ( d->material.offset != uniformOffset)
|
|
||||||
{
|
|
||||||
d->material.offset = uniformOffset;
|
|
||||||
markDirty( QSGNode::DirtyMaterial );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void BoxShadowNode::setClipRect( const QRectF& rect )
|
||||||
|
{
|
||||||
|
Q_UNUSED( rect )
|
||||||
}
|
}
|
||||||
|
|
||||||
void BoxShadowNode::updateGeometry()
|
void BoxShadowNode::updateGeometry()
|
||||||
{
|
{
|
||||||
Q_D( BoxShadowNode );
|
Q_D( BoxShadowNode );
|
||||||
|
|
||||||
const auto sz = d->material.extent;
|
|
||||||
const auto aspect = d->material.aspect;
|
|
||||||
|
|
||||||
auto rect = d->rect.adjusted(
|
|
||||||
-sz * aspect.x(), -sz * aspect.y(),
|
|
||||||
sz * aspect.x(), sz * aspect.y() );
|
|
||||||
|
|
||||||
auto offsetLength = d->material.offset.length();
|
|
||||||
|
|
||||||
rect = rect.adjusted(
|
|
||||||
-offsetLength * aspect.x(), -offsetLength * aspect.y(),
|
|
||||||
offsetLength * aspect.x(), offsetLength * aspect.y() );
|
|
||||||
|
|
||||||
QSGGeometry::updateTexturedRectGeometry(
|
QSGGeometry::updateTexturedRectGeometry(
|
||||||
&d->geometry, rect, QRectF( 0.0, 0.0, 1.0, 1.0 ) );
|
&d->geometry, d->rect, QRectF( -0.5, -0.5, 1.0, 1.0 ) );
|
||||||
|
|
||||||
markDirty( QSGNode::DirtyGeometry );
|
markDirty( QSGNode::DirtyGeometry );
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,7 +21,9 @@ class BoxShadowNode : public QSGGeometryNode
|
||||||
void setRect( const QRectF& );
|
void setRect( const QRectF& );
|
||||||
void setShape( const QskBoxShapeMetrics& );
|
void setShape( const QskBoxShapeMetrics& );
|
||||||
void setColor( const QColor& );
|
void setColor( const QColor& );
|
||||||
void setShadow( qreal extent, qreal dx, qreal dy );
|
void setBlurRadius( qreal );
|
||||||
|
|
||||||
|
void setClipRect( const QRectF& );
|
||||||
|
|
||||||
void updateGeometry();
|
void updateGeometry();
|
||||||
|
|
||||||
|
|
|
@ -40,6 +40,10 @@ namespace
|
||||||
{
|
{
|
||||||
const auto box = static_cast< const ShadowedBox* >( skinnable );
|
const auto box = static_cast< const ShadowedBox* >( skinnable );
|
||||||
|
|
||||||
|
const auto r = box->subControlRect( ShadowedBox::Panel );
|
||||||
|
if ( r.isEmpty() )
|
||||||
|
return nullptr;
|
||||||
|
|
||||||
switch ( nodeRole )
|
switch ( nodeRole )
|
||||||
{
|
{
|
||||||
case ShadowRole:
|
case ShadowRole:
|
||||||
|
@ -48,17 +52,14 @@ namespace
|
||||||
if ( shadowNode == nullptr )
|
if ( shadowNode == nullptr )
|
||||||
shadowNode = new BoxShadowNode();
|
shadowNode = new BoxShadowNode();
|
||||||
|
|
||||||
const auto& s = box->shadow();
|
const auto& shadowMetrics = box->shadow();
|
||||||
const qreal dx = s.extent + s.xOffset;
|
|
||||||
const qreal dy = s.extent + s.yOffset;
|
|
||||||
|
|
||||||
auto r = box->subControlRect( ShadowedBox::Panel );
|
shadowNode->setRect( shadowMetrics.shadowRect( r ) );
|
||||||
r.adjust( -dx, -dy, dx, dy );
|
|
||||||
|
|
||||||
shadowNode->setRect( r );
|
|
||||||
shadowNode->setShape( box->shape() );
|
shadowNode->setShape( box->shape() );
|
||||||
shadowNode->setShadow( s.extent, s.xOffset, s.yOffset );
|
shadowNode->setBlurRadius( shadowMetrics.blurRadius() );
|
||||||
shadowNode->setColor( box->shadowColor() );
|
shadowNode->setColor( box->shadowColor() );
|
||||||
|
shadowNode->setClipRect( r );
|
||||||
|
|
||||||
shadowNode->updateGeometry();
|
shadowNode->updateGeometry();
|
||||||
|
|
||||||
return shadowNode;
|
return shadowNode;
|
||||||
|
@ -69,10 +70,10 @@ namespace
|
||||||
if ( boxNode == nullptr )
|
if ( boxNode == nullptr )
|
||||||
boxNode = new QskBoxNode();
|
boxNode = new QskBoxNode();
|
||||||
|
|
||||||
const QRectF r = box->subControlRect( ShadowedBox::Panel );
|
const auto r = box->subControlRect( ShadowedBox::Panel );
|
||||||
|
|
||||||
boxNode->setBoxData( r, box->shape(), QskBoxBorderMetrics(),
|
boxNode->setBoxData( r, box->shape(), box->borderWidth(),
|
||||||
QskBoxBorderColors(), box->gradient() );
|
box->borderColor(), box->gradient() );
|
||||||
|
|
||||||
return boxNode;
|
return boxNode;
|
||||||
}
|
}
|
||||||
|
@ -96,13 +97,13 @@ ShadowedBox::~ShadowedBox()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
void ShadowedBox::setShadow( const Shadow& shadow )
|
void ShadowedBox::setShadow( const QskShadowMetrics& shadow )
|
||||||
{
|
{
|
||||||
m_shadow = shadow;
|
m_shadow = shadow;
|
||||||
update();
|
update();
|
||||||
}
|
}
|
||||||
|
|
||||||
const ShadowedBox::Shadow& ShadowedBox::shadow() const
|
const QskShadowMetrics& ShadowedBox::shadow() const
|
||||||
{
|
{
|
||||||
return m_shadow;
|
return m_shadow;
|
||||||
}
|
}
|
||||||
|
@ -140,4 +141,26 @@ const QskBoxShapeMetrics& ShadowedBox::shape() const
|
||||||
return m_shape;
|
return m_shape;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ShadowedBox::setBorderWidth( qreal width )
|
||||||
|
{
|
||||||
|
m_borderWidth = qMax( width, 0.0 );
|
||||||
|
update();
|
||||||
|
}
|
||||||
|
|
||||||
|
qreal ShadowedBox::borderWidth() const
|
||||||
|
{
|
||||||
|
return m_borderWidth;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ShadowedBox::setBorderColor( const QColor& color )
|
||||||
|
{
|
||||||
|
m_borderColor = color;
|
||||||
|
update();
|
||||||
|
}
|
||||||
|
|
||||||
|
QColor ShadowedBox::borderColor() const
|
||||||
|
{
|
||||||
|
return m_borderColor;
|
||||||
|
}
|
||||||
|
|
||||||
#include "moc_ShadowedBox.cpp"
|
#include "moc_ShadowedBox.cpp"
|
||||||
|
|
|
@ -7,6 +7,7 @@
|
||||||
|
|
||||||
#include <QskControl.h>
|
#include <QskControl.h>
|
||||||
#include <QskBoxShapeMetrics.h>
|
#include <QskBoxShapeMetrics.h>
|
||||||
|
#include <QskShadowMetrics.h>
|
||||||
|
|
||||||
class QskGradient;
|
class QskGradient;
|
||||||
|
|
||||||
|
@ -17,19 +18,11 @@ class ShadowedBox : public QskControl
|
||||||
public:
|
public:
|
||||||
QSK_SUBCONTROLS( Panel )
|
QSK_SUBCONTROLS( Panel )
|
||||||
|
|
||||||
class Shadow
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
qreal extent = 0.0;
|
|
||||||
qreal xOffset = 0.0;
|
|
||||||
qreal yOffset = 0.0;
|
|
||||||
};
|
|
||||||
|
|
||||||
ShadowedBox(QQuickItem* parent = nullptr);
|
ShadowedBox(QQuickItem* parent = nullptr);
|
||||||
~ShadowedBox() override;
|
~ShadowedBox() override;
|
||||||
|
|
||||||
void setShadow( const Shadow& );
|
void setShadow( const QskShadowMetrics& );
|
||||||
const Shadow& shadow() const;
|
const QskShadowMetrics& shadow() const;
|
||||||
|
|
||||||
void setGradient( const QskGradient& );
|
void setGradient( const QskGradient& );
|
||||||
const QskGradient& gradient() const;
|
const QskGradient& gradient() const;
|
||||||
|
@ -40,9 +33,19 @@ class ShadowedBox : public QskControl
|
||||||
void setShape( const QskBoxShapeMetrics& );
|
void setShape( const QskBoxShapeMetrics& );
|
||||||
const QskBoxShapeMetrics& shape() const;
|
const QskBoxShapeMetrics& shape() const;
|
||||||
|
|
||||||
|
void setBorderWidth( qreal width );
|
||||||
|
qreal borderWidth() const;
|
||||||
|
|
||||||
|
void setBorderColor( const QColor& );
|
||||||
|
QColor borderColor() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Shadow m_shadow;
|
QskShadowMetrics m_shadow;
|
||||||
QColor m_shadowColor = Qt::black;
|
QColor m_shadowColor = Qt::black;
|
||||||
|
|
||||||
QskGradient m_gradient;
|
QskGradient m_gradient;
|
||||||
QskBoxShapeMetrics m_shape;
|
QskBoxShapeMetrics m_shape;
|
||||||
|
|
||||||
|
qreal m_borderWidth = 0.0;
|
||||||
|
QColor m_borderColor = Qt::black;
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,18 +1,7 @@
|
||||||
/*
|
|
||||||
Heavily inspired by code from the kirigami project:
|
|
||||||
Copyright 2020 Arjen Hiemstra <ahiemstra@heimr.nl>
|
|
||||||
License: LGPL-2.0-or-later
|
|
||||||
|
|
||||||
https://iquilezles.org/www/articles/distfunctions2d/distfunctions2d.htm
|
|
||||||
Copyright: 2017 Inigo Quilez
|
|
||||||
License: MIT
|
|
||||||
*/
|
|
||||||
|
|
||||||
uniform lowp float opacity;
|
uniform lowp float opacity;
|
||||||
uniform lowp float extent;
|
uniform lowp float blurExtent;
|
||||||
uniform lowp vec4 radius;
|
uniform lowp vec4 radius;
|
||||||
uniform lowp vec4 color;
|
uniform lowp vec4 color;
|
||||||
uniform lowp vec2 offset;
|
|
||||||
uniform lowp vec2 aspect;
|
uniform lowp vec2 aspect;
|
||||||
|
|
||||||
varying lowp vec2 coord;
|
varying lowp vec2 coord;
|
||||||
|
@ -25,48 +14,29 @@ lowp float effectiveRadius( in lowp vec4 radii, in lowp vec2 point )
|
||||||
return ( point.y > 0.0) ? radii.z : radii.w;
|
return ( point.y > 0.0) ? radii.z : radii.w;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool isInside( in lowp vec2 point, in lowp vec2 size, in lowp vec4 radii )
|
|
||||||
{
|
|
||||||
lowp float r = effectiveRadius( radii, point );
|
|
||||||
lowp vec2 d = abs(point) - size + r;
|
|
||||||
|
|
||||||
lowp float l = min( max(d.x, d.y), 0.0) + length( max(d, 0.0) ) - r;
|
|
||||||
return l <= 0.0;
|
|
||||||
}
|
|
||||||
|
|
||||||
lowp float shadowAt(
|
|
||||||
in lowp vec2 point, in lowp vec2 size, in lowp vec4 radii )
|
|
||||||
{
|
|
||||||
lowp float r = effectiveRadius( radii, point );
|
|
||||||
lowp vec2 d = abs(point) - size + r;
|
|
||||||
|
|
||||||
return min( max(d.x, d.y), 0.0) + length( max(d, 0.0) ) - r;
|
|
||||||
}
|
|
||||||
|
|
||||||
void main()
|
void main()
|
||||||
{
|
{
|
||||||
lowp vec4 col = vec4(0.0);
|
lowp vec4 col = vec4(0.0);
|
||||||
|
|
||||||
if ( extent > 0.0 && opacity > 0.0 )
|
if ( opacity > 0.0 )
|
||||||
{
|
|
||||||
lowp float t = 1.0 + 2.0 * length( offset ) + extent;
|
|
||||||
|
|
||||||
if ( !isInside( coord, aspect / t, radius / t) )
|
|
||||||
{
|
{
|
||||||
const lowp float minRadius = 0.05;
|
const lowp float minRadius = 0.05;
|
||||||
lowp float e2 = 0.5 * extent;
|
|
||||||
|
|
||||||
lowp vec4 f = minRadius / max( radius, minRadius );
|
lowp float e2 = 0.5 * blurExtent;
|
||||||
lowp vec4 r = radius + e2 * f;
|
lowp float r = 2.0 * effectiveRadius( radius, coord );
|
||||||
|
|
||||||
lowp float shadow = shadowAt(
|
lowp float f = minRadius / max( r, minRadius );
|
||||||
coord - 2.0 * offset / t, aspect / t, r / t);
|
|
||||||
|
r += e2 * f;
|
||||||
|
|
||||||
|
lowp vec2 d = r + blurExtent - aspect * ( 1.0 - abs( 2.0 * coord ) );
|
||||||
|
lowp float l = min( max(d.x, d.y), 0.0) + length( max(d, 0.0) );
|
||||||
|
|
||||||
|
lowp float shadow = l - r;
|
||||||
|
|
||||||
lowp float v = smoothstep( -e2, e2, shadow );
|
lowp float v = smoothstep( -e2, e2, shadow );
|
||||||
|
|
||||||
col = mix( color, vec4(0.0), v ) * opacity;
|
col = mix( color, vec4(0.0), v ) * opacity;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
gl_FragColor = col;
|
gl_FragColor = col;
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,6 +8,6 @@ varying mediump vec2 coord;
|
||||||
|
|
||||||
void main()
|
void main()
|
||||||
{
|
{
|
||||||
coord = ( -1.0 + 2.0 * in_coord ) * aspect;
|
coord = in_coord;
|
||||||
gl_Position = matrix * in_vertex;
|
gl_Position = matrix * in_vertex;
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,6 +5,8 @@
|
||||||
|
|
||||||
#include "ShadowedBox.h"
|
#include "ShadowedBox.h"
|
||||||
|
|
||||||
|
#include <SkinnyShortcut.h>
|
||||||
|
|
||||||
#include <QGuiApplication>
|
#include <QGuiApplication>
|
||||||
#include <QskObjectCounter.h>
|
#include <QskObjectCounter.h>
|
||||||
#include <QskWindow.h>
|
#include <QskWindow.h>
|
||||||
|
@ -18,15 +20,26 @@ class Box : public ShadowedBox
|
||||||
Box( QQuickItem* parent = nullptr )
|
Box( QQuickItem* parent = nullptr )
|
||||||
: ShadowedBox( parent )
|
: ShadowedBox( parent )
|
||||||
{
|
{
|
||||||
Shadow shadow;
|
const qreal w = 10;
|
||||||
shadow.extent = 10;
|
|
||||||
shadow.xOffset = 20.0;
|
QskShadowMetrics shadow;
|
||||||
shadow.yOffset = 20.0;
|
//shadow.setOffset( 20.0, 20.0 );
|
||||||
|
shadow.setSpreadRadius( w );
|
||||||
|
shadow.setBlurRadius( w );
|
||||||
|
|
||||||
setShadow( shadow );
|
setShadow( shadow );
|
||||||
setShadowColor( Qt::black );
|
setShadowColor( Qt::black );
|
||||||
setGradient( Qt::darkRed );
|
|
||||||
setShape( QskBoxShapeMetrics( 5, 10, 15, 20 ) );
|
QColor c( Qt::darkRed );
|
||||||
|
#if 0
|
||||||
|
c.setAlpha( 100 );
|
||||||
|
#endif
|
||||||
|
|
||||||
|
setGradient( c );
|
||||||
|
setShape( QskBoxShapeMetrics( 40, 10, 15, 5 ) );
|
||||||
|
|
||||||
|
setBorderWidth( w );
|
||||||
|
setBorderColor( Qt::blue );
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -38,6 +51,8 @@ int main( int argc, char* argv[] )
|
||||||
|
|
||||||
QGuiApplication app( argc, argv );
|
QGuiApplication app( argc, argv );
|
||||||
|
|
||||||
|
SkinnyShortcut::enable( SkinnyShortcut::AllShortcuts );
|
||||||
|
|
||||||
auto layout = new QskLinearBox();
|
auto layout = new QskLinearBox();
|
||||||
layout->setPanel( true );
|
layout->setPanel( true );
|
||||||
#if 1
|
#if 1
|
||||||
|
|
|
@ -73,11 +73,14 @@ QVariant QskShadowMetrics::interpolate(
|
||||||
|
|
||||||
QRectF QskShadowMetrics::shadowRect( const QRectF& sourceRect ) const
|
QRectF QskShadowMetrics::shadowRect( const QRectF& sourceRect ) const
|
||||||
{
|
{
|
||||||
|
const auto metrics = toAbsolute( sourceRect.size() );
|
||||||
|
const auto extent = metrics.m_spreadRadius + metrics.m_blurRadius;
|
||||||
|
|
||||||
return QRectF(
|
return QRectF(
|
||||||
sourceRect.x() + m_offset.x() - m_spreadRadius,
|
sourceRect.x() + metrics.m_offset.x() - extent,
|
||||||
sourceRect.y() + m_offset.y() - m_spreadRadius,
|
sourceRect.y() + metrics.m_offset.y() - extent,
|
||||||
sourceRect.width() + 2 * m_spreadRadius,
|
sourceRect.width() + 2 * extent,
|
||||||
sourceRect.height() + 2 * m_spreadRadius );
|
sourceRect.height() + 2 * extent );
|
||||||
}
|
}
|
||||||
|
|
||||||
uint QskShadowMetrics::hash( uint seed ) const noexcept
|
uint QskShadowMetrics::hash( uint seed ) const noexcept
|
||||||
|
|
Loading…
Reference in New Issue