Box renderer: Support border gradients (#158)
* QskBoxBorderColors: Use gradients instead of colors * QskBoxBorderColors: rename API * render gradients on borders * boxes example: Also draw gradient borders * calculate proper numbers of needed border colors * fixup with example * support rounded corners * support more colors in rounded color gradients I THINK WE DON'T REALLY NEED THIS COMMIT * We don't need this commit either * Revert "We don't need this commit either" This reverts commit 2dc38064f7fee1d0505262fe5cebcf9e1fb16cea. * Revert "support more colors in rounded color gradients" This reverts commit 5754d2d0773d8273d42ae1775b53d40f5e6af26a. * fix borders for rect ellipses * play around a bit * small fixes * some helper stuff and missing stuff * user border colors * close to something working somehow * works a bit better * put it into an own function * rearrange a bit * something's off * still off, but seems like we need an additional line * works but hackish * now it works * bring back samples * correction * pimp up example * fix normal rendering * some more debugging etc. * turn around gradients * turn around rectangular gradients as well * turn around easier * more test cases * fix fill case * more test cases * clean up a bit * clean up example * clean up some more * incorporate feedback from Uwe * fix bug when using horizontal gradients
This commit is contained in:
parent
4c7c369477
commit
ac8ef9cd5a
@ -80,23 +80,23 @@ void Box::setBorder( BorderType type, QskRgbPalette::Theme theme )
|
||||
break;
|
||||
|
||||
case Flat:
|
||||
setBorderColor( mid );
|
||||
setBorderGradient( mid );
|
||||
break;
|
||||
|
||||
case Raised1:
|
||||
setBorderColors( light, light, dark, dark );
|
||||
setBorderGradients( light, light, dark, dark );
|
||||
break;
|
||||
|
||||
case Sunken1:
|
||||
setBorderColors( dark, dark, light, light );
|
||||
setBorderGradients( dark, dark, light, light );
|
||||
break;
|
||||
|
||||
case Raised2:
|
||||
setBorderColors( mid, light, mid, dark );
|
||||
setBorderGradients( mid, light, mid, dark );
|
||||
break;
|
||||
|
||||
case Sunken2:
|
||||
setBorderColors( mid, dark, mid, light );
|
||||
setBorderGradients( mid, dark, mid, light );
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -117,16 +117,16 @@ void Box::setShape( qreal radiusX, qreal radiusY, Qt::SizeMode sizeMode )
|
||||
QskBoxShapeMetrics( radiusX, radiusY, sizeMode ) );
|
||||
}
|
||||
|
||||
void Box::setBorderColors( const QColor& left, const QColor& top,
|
||||
const QColor& right, const QColor& bottom )
|
||||
void Box::setBorderGradients( const QskGradient& left, const QskGradient& top,
|
||||
const QskGradient& right, const QskGradient& bottom )
|
||||
{
|
||||
QskBoxBorderColors colors( left, top, right, bottom );
|
||||
setBoxBorderColorsHint( QskBox::Panel, colors );
|
||||
}
|
||||
|
||||
void Box::setBorderColor( const QColor& color )
|
||||
void Box::setBorderGradient( const QskGradient& gradient )
|
||||
{
|
||||
setBoxBorderColorsHint( QskBox::Panel, color );
|
||||
setBoxBorderColorsHint( QskBox::Panel, gradient );
|
||||
}
|
||||
|
||||
void Box::setBorderWidth( qreal left, qreal top, qreal right, qreal bottom )
|
||||
|
@ -39,9 +39,9 @@ class Box : public QskBox
|
||||
void setShape( qreal radius, Qt::SizeMode );
|
||||
void setShape( qreal radiusX, qreal radiusY, Qt::SizeMode );
|
||||
|
||||
void setBorderColor( const QColor& );
|
||||
void setBorderColors( const QColor& left, const QColor& top,
|
||||
const QColor& right, const QColor& bottom );
|
||||
void setBorderGradient( const QskGradient& );
|
||||
void setBorderGradients( const QskGradient& left, const QskGradient& top,
|
||||
const QskGradient& right, const QskGradient& bottom );
|
||||
|
||||
void setBorderWidth( int );
|
||||
void setBorderWidth( qreal left, qreal top, qreal right, qreal bottom );
|
||||
|
@ -232,25 +232,25 @@ static void addRectangles10( QskLinearBox* parent )
|
||||
|
||||
box = new Box( parent );
|
||||
box->setBorderWidth( 10 );
|
||||
box->setBorderColor( borderTheme );
|
||||
box->setBorderGradient( borderTheme );
|
||||
box->setGradient( QskGradient::Diagonal, "DeepPink", "DarkOrange", "HotPink" );
|
||||
|
||||
box = new Box( parent );
|
||||
box->setShape( 100, Qt::RelativeSize );
|
||||
box->setBorderWidth( 5 );
|
||||
box->setBorderColor( borderTheme );
|
||||
box->setBorderGradient( borderTheme );
|
||||
box->setGradient( QskGradient::Vertical, "DeepPink", "DarkOrange", "HotPink" );
|
||||
|
||||
box = new Box( parent );
|
||||
box->setShape( 100, Qt::RelativeSize );
|
||||
box->setBorderWidth( 5 );
|
||||
box->setBorderColor( borderTheme );
|
||||
box->setBorderGradient( borderTheme );
|
||||
box->setGradient( QskGradient::Diagonal, "DeepPink", "DarkOrange", "HotPink" );
|
||||
|
||||
box = new Box( parent );
|
||||
box->setShape( 100, Qt::RelativeSize );
|
||||
box->setBorderWidth( 5, 20, 30, 5 );
|
||||
box->setBorderColor( borderTheme );
|
||||
box->setBorderGradient( borderTheme );
|
||||
box->setGradient( QskGradient::Vertical, "DeepPink", "DarkOrange", "HotPink" );
|
||||
}
|
||||
|
||||
@ -333,32 +333,127 @@ static void addRectanglesRest( QskLinearBox* parent )
|
||||
|
||||
box = new Box( parent );
|
||||
box->setBorderWidth( 20, 0, 40, 0 );
|
||||
box->setBorderColor( "DarkSeaGreen" );
|
||||
box->setBorderGradient( { "DarkSeaGreen" } );
|
||||
|
||||
box = new Box( parent );
|
||||
box->setShape( 40, Qt::RelativeSize );
|
||||
box->setBorderWidth( 20, 10, 30, 15 );
|
||||
box->setBorderColor( "DarkOrange" );
|
||||
box->setBorderGradient( { "DarkOrange" } );
|
||||
box->setGradient( QskGradient::Vertical, "LightSteelBlue", "SteelBlue" );
|
||||
|
||||
box = new Box( parent );
|
||||
box->setBorderWidth( 20, 0, 10, 20 );
|
||||
box->setBorderColor( "MediumSeaGreen" );
|
||||
box->setBorderGradient( { "MediumSeaGreen" } );
|
||||
box->setGradient( "DodgerBlue" );
|
||||
|
||||
box = new Box( parent );
|
||||
box->setShape( 20, Qt::AbsoluteSize );
|
||||
box->setBorderWidth( 2, 10, 40, 2 );
|
||||
box->setBorderColor( "Crimson" );
|
||||
box->setBorderGradient( { "Crimson" } );
|
||||
box->setGradient( QskRgb::WhiteSmoke );
|
||||
|
||||
box = new Box( parent );
|
||||
box->setShape( 100, Qt::RelativeSize );
|
||||
box->setBorderWidth( 5, 20, 5, 0 );
|
||||
box->setBorderColor( "CadetBlue" );
|
||||
box->setBorderGradient( { "CadetBlue" } );
|
||||
box->setGradient( QskGradient::Vertical, "Gainsboro", "Seashell", "LightGray" );
|
||||
}
|
||||
|
||||
static void addColoredBorderRectangles1( QskLinearBox* parent, bool rounded, Box::FillType fillType )
|
||||
{
|
||||
auto* box = new Box( parent );
|
||||
box->setBorderWidth( 20 );
|
||||
QskGradient gradient1( Qt::Vertical, { { 0.0, Qt::blue },
|
||||
{ 0.9, Qt::yellow },
|
||||
{ 1.0, Qt::darkRed } } );
|
||||
QskGradient gradient2( Qt::Vertical, { { 0.0, Qt::black },
|
||||
{ 0.3, Qt::white },
|
||||
{ 0.7, Qt::white },
|
||||
{ 1.0, Qt::black } } );
|
||||
QskGradient gradient3( Qt::green );
|
||||
QskGradient gradient4( Qt::Vertical, Qt::magenta, Qt::cyan );
|
||||
box->setBorderGradients( gradient1, gradient2, gradient3, gradient4 );
|
||||
|
||||
if( fillType != Box::Unfilled )
|
||||
box->setBackground( fillType, QskRgbPalette::Indigo );
|
||||
|
||||
if( rounded )
|
||||
box->setShape( 30, Qt::AbsoluteSize );
|
||||
}
|
||||
|
||||
static void addColoredBorderRectangles2( QskLinearBox* parent, bool rounded, Box::FillType fillType )
|
||||
{
|
||||
Box* box = new Box( parent );
|
||||
box->setBorderWidth( 20 );
|
||||
box->setBorderGradients( Qt::red, Qt::green, Qt::blue, Qt::yellow );
|
||||
|
||||
if( fillType != Box::Unfilled )
|
||||
box->setBackground( fillType, QskRgbPalette::Indigo );
|
||||
|
||||
if( rounded )
|
||||
box->setShape( 30, Qt::AbsoluteSize );
|
||||
}
|
||||
|
||||
static void addColoredBorderRectangles3( QskLinearBox* parent, bool rounded, Box::FillType fillType )
|
||||
{
|
||||
Box* box = new Box( parent );
|
||||
box->setBorderWidth( 20 );
|
||||
QskGradient gradient1( Qt::Vertical, { { 0.0, Qt::yellow },
|
||||
{ 0.2, Qt::gray },
|
||||
{ 0.6, Qt::magenta },
|
||||
{ 1.0, Qt::green } } );
|
||||
QskGradient gradient2( Qt::Vertical, { { 0.0, Qt::darkYellow },
|
||||
{ 0.2, Qt::cyan },
|
||||
{ 1.0, Qt::darkMagenta } } );
|
||||
QskGradient gradient3( Qt::Vertical, { { 0.0, Qt::red },
|
||||
{ 0.25, Qt::green },
|
||||
{ 0.5, Qt::blue },
|
||||
{ 0.75, Qt::magenta },
|
||||
{ 1.0, Qt::cyan } } );
|
||||
QskGradient gradient4( Qt::Vertical, { { 0.0, Qt::red },
|
||||
{ 0.3, Qt::green },
|
||||
{ 0.7, Qt::blue },
|
||||
{ 1.0, Qt::cyan } } );
|
||||
box->setBorderGradients( gradient3, gradient3, gradient3, gradient3 );
|
||||
|
||||
if( fillType != Box::Unfilled )
|
||||
box->setBackground( fillType, QskRgbPalette::Indigo );
|
||||
|
||||
if( rounded )
|
||||
box->setShape( 30, Qt::AbsoluteSize );
|
||||
}
|
||||
|
||||
static void addColoredBorderRectangles4( QskLinearBox* parent, bool rounded, Box::FillType fillType )
|
||||
{
|
||||
Box* box = new Box( parent );
|
||||
box->setBorderWidth( 20 );
|
||||
QskGradient gradient( Qt::Vertical, Qt::magenta, Qt::cyan );
|
||||
box->setBorderGradients( gradient, gradient, gradient, gradient );
|
||||
|
||||
if( fillType != Box::Unfilled )
|
||||
box->setBackground( fillType, QskRgbPalette::Indigo );
|
||||
|
||||
if( rounded )
|
||||
box->setShape( 30, Qt::AbsoluteSize );
|
||||
}
|
||||
|
||||
static void addColoredBorderRectangles5( QskLinearBox* parent, bool rounded, Box::FillType fillType )
|
||||
{
|
||||
Box* box = new Box( parent );
|
||||
box->setBorderWidth( 20 );
|
||||
QskGradient gradient( Qt::Vertical, { { 0.0, Qt::black },
|
||||
{ 0.3, Qt::white },
|
||||
{ 0.7, Qt::white },
|
||||
{ 1.0, Qt::black } } );
|
||||
box->setBorderGradients( gradient, gradient, gradient, gradient );
|
||||
|
||||
if( fillType != Box::Unfilled )
|
||||
box->setBackground( fillType, QskRgbPalette::Indigo );
|
||||
|
||||
if( rounded )
|
||||
box->setShape( { 10, 20, 20, 40 } );
|
||||
}
|
||||
|
||||
class TabView : public QskTabView
|
||||
{
|
||||
public:
|
||||
@ -399,6 +494,45 @@ class TabView : public QskTabView
|
||||
addTab( tab4 );
|
||||
//setCurrentIndex( count() - 1 ); // setCurrentTab( tab4 ) -> TODO
|
||||
#endif
|
||||
|
||||
auto* tab5 = new QskLinearBox( Qt::Horizontal, 5 );
|
||||
addColoredBorderRectangles1( tab5, false, Box::Unfilled );
|
||||
addColoredBorderRectangles2( tab5, false, Box::Unfilled );
|
||||
addColoredBorderRectangles3( tab5, false, Box::Unfilled );
|
||||
addColoredBorderRectangles4( tab5, false, Box::Unfilled );
|
||||
addColoredBorderRectangles5( tab5, false, Box::Unfilled );
|
||||
|
||||
addColoredBorderRectangles1( tab5, true, Box::Unfilled );
|
||||
addColoredBorderRectangles2( tab5, true, Box::Unfilled );
|
||||
addColoredBorderRectangles3( tab5, true, Box::Unfilled );
|
||||
addColoredBorderRectangles4( tab5, true, Box::Unfilled );
|
||||
addColoredBorderRectangles5( tab5, true, Box::Unfilled );
|
||||
|
||||
addColoredBorderRectangles1( tab5, false, Box::Horizontal );
|
||||
addColoredBorderRectangles2( tab5, false, Box::Horizontal );
|
||||
addColoredBorderRectangles3( tab5, false, Box::Horizontal );
|
||||
addColoredBorderRectangles4( tab5, false, Box::Horizontal );
|
||||
addColoredBorderRectangles5( tab5, false, Box::Horizontal );
|
||||
|
||||
addColoredBorderRectangles1( tab5, true, Box::Horizontal );
|
||||
addColoredBorderRectangles2( tab5, true, Box::Horizontal );
|
||||
addColoredBorderRectangles3( tab5, true, Box::Horizontal );
|
||||
addColoredBorderRectangles4( tab5, true, Box::Horizontal );
|
||||
addColoredBorderRectangles5( tab5, true, Box::Horizontal );
|
||||
|
||||
addColoredBorderRectangles1( tab5, false, Box::Vertical );
|
||||
addColoredBorderRectangles2( tab5, false, Box::Vertical );
|
||||
addColoredBorderRectangles3( tab5, false, Box::Vertical );
|
||||
addColoredBorderRectangles4( tab5, false, Box::Vertical );
|
||||
addColoredBorderRectangles5( tab5, false, Box::Vertical );
|
||||
|
||||
addColoredBorderRectangles1( tab5, true, Box::Vertical );
|
||||
addColoredBorderRectangles2( tab5, true, Box::Vertical );
|
||||
addColoredBorderRectangles3( tab5, true, Box::Vertical );
|
||||
addColoredBorderRectangles4( tab5, true, Box::Vertical );
|
||||
addColoredBorderRectangles5( tab5, true, Box::Vertical );
|
||||
|
||||
addTab( tab5 );
|
||||
}
|
||||
|
||||
private:
|
||||
|
@ -602,7 +602,7 @@ void Editor::setupTabButton()
|
||||
QskBoxBorderColors borderColors( QskRgb::White );
|
||||
setBoxBorderColors( aspect, borderColors );
|
||||
|
||||
borderColors.setColorsAt( edge, m_pal.accentColor );
|
||||
borderColors.setGradientAt( edge, m_pal.accentColor );
|
||||
for ( auto state : { Q::Checked, Q::Pressed, Q::Hovered } )
|
||||
setBoxBorderColors( aspect | state, borderColors );
|
||||
}
|
||||
@ -750,8 +750,8 @@ void Editor::setupSubWindow()
|
||||
setGradient( Q::Panel, m_pal.baseColor );
|
||||
|
||||
QskBoxBorderColors colors;
|
||||
colors.setColorsAt( Qt::TopEdge | Qt::LeftEdge, m_pal.lighter125 );
|
||||
colors.setColorsAt( Qt::RightEdge | Qt::BottomEdge, m_pal.darker200 );
|
||||
colors.setGradientAt( Qt::TopEdge | Qt::LeftEdge, m_pal.lighter125 );
|
||||
colors.setGradientAt( Qt::RightEdge | Qt::BottomEdge, m_pal.darker200 );
|
||||
|
||||
setBoxBorderColors( Q::Panel, colors );
|
||||
|
||||
|
@ -198,23 +198,23 @@ void Editor::setButton( QskAspect aspect, PanelStyle style, qreal border )
|
||||
{
|
||||
case Raised:
|
||||
{
|
||||
borderColors.setColorsAt( Qt::TopEdge | Qt::LeftEdge, m_pal.lighter135 );
|
||||
borderColors.setColorsAt( Qt::RightEdge | Qt::BottomEdge, m_pal.darker200 );
|
||||
borderColors.setGradientAt( Qt::TopEdge | Qt::LeftEdge, m_pal.lighter135 );
|
||||
borderColors.setGradientAt( Qt::RightEdge | Qt::BottomEdge, m_pal.darker200 );
|
||||
gradient.setColors( m_pal.lighter125, m_pal.lighter110 );
|
||||
|
||||
break;
|
||||
}
|
||||
case Sunken:
|
||||
{
|
||||
borderColors.setColorsAt( Qt::TopEdge | Qt::LeftEdge, m_pal.darker200 );
|
||||
borderColors.setColorsAt( Qt::RightEdge | Qt::BottomEdge, m_pal.lighter135 );
|
||||
borderColors.setGradientAt( Qt::TopEdge | Qt::LeftEdge, m_pal.darker200 );
|
||||
borderColors.setGradientAt( Qt::RightEdge | Qt::BottomEdge, m_pal.lighter135 );
|
||||
gradient.setColors( m_pal.lighter110, m_pal.lighter125 );
|
||||
|
||||
break;
|
||||
}
|
||||
case Plain:
|
||||
{
|
||||
borderColors.setColors( m_pal.darker125 );
|
||||
borderColors.setGradients( m_pal.darker125 );
|
||||
gradient.setColor( m_pal.lighter125 );
|
||||
|
||||
break;
|
||||
@ -225,7 +225,7 @@ void Editor::setButton( QskAspect aspect, PanelStyle style, qreal border )
|
||||
QColor noColor( m_pal.theme );
|
||||
noColor.setAlpha( 0 );
|
||||
|
||||
borderColors.setColors( noColor );
|
||||
borderColors.setGradients( noColor );
|
||||
gradient.setColor( noColor );
|
||||
|
||||
if ( style == NoPanel )
|
||||
@ -859,8 +859,8 @@ void Editor::setupSubWindow()
|
||||
setBoxShape( Q::Panel, radius, radius, 0, 0, Qt::AbsoluteSize );
|
||||
|
||||
QskBoxBorderColors borderColors;
|
||||
borderColors.setColorsAt( Qt::TopEdge | Qt::LeftEdge, m_pal.lighter125 );
|
||||
borderColors.setColorsAt( Qt::RightEdge | Qt::BottomEdge, m_pal.darker200 );
|
||||
borderColors.setGradientAt( Qt::TopEdge | Qt::LeftEdge, m_pal.lighter125 );
|
||||
borderColors.setGradientAt( Qt::RightEdge | Qt::BottomEdge, m_pal.darker200 );
|
||||
|
||||
setBoxBorderColors( Q::Panel, borderColors );
|
||||
setGradient( Q::Panel, m_pal.lighter135 );
|
||||
|
@ -15,28 +15,26 @@ static void qskRegisterBoxBorderColors()
|
||||
|
||||
QMetaType::registerConverter< QColor, QskBoxBorderColors >(
|
||||
[]( const QColor& color ) { return QskBoxBorderColors( color ); } );
|
||||
|
||||
QMetaType::registerConverter< QskGradient, QskBoxBorderColors >(
|
||||
[]( const QskGradient& gradient ) { return QskBoxBorderColors( gradient ); } );
|
||||
}
|
||||
|
||||
Q_CONSTRUCTOR_FUNCTION( qskRegisterBoxBorderColors )
|
||||
|
||||
static inline bool qskIsVisble( const QColor& c )
|
||||
static inline void qskSetGradients( const QskGradient& gradient, QskGradient* gradients )
|
||||
{
|
||||
return c.isValid() && ( c.alpha() > 0 );
|
||||
gradients[ 0 ] = gradients[ 1 ] = gradients[ 2 ] = gradients[ 3 ] = gradient;
|
||||
}
|
||||
|
||||
static inline void qskSetColors( const QColor& c, QColor* colors )
|
||||
static inline void qskSetGradients(
|
||||
const QskGradient& left, const QskGradient& top,
|
||||
const QskGradient& right, const QskGradient& bottom, QskGradient* gradients )
|
||||
{
|
||||
colors[ 0 ] = colors[ 1 ] = colors[ 2 ] = colors[ 3 ] = c.toRgb();
|
||||
}
|
||||
|
||||
static inline void qskSetColors(
|
||||
const QColor& left, const QColor& top,
|
||||
const QColor& right, const QColor& bottom, QColor* colors )
|
||||
{
|
||||
colors[ Qsk::Left ] = left.toRgb();
|
||||
colors[ Qsk::Top ] = top.toRgb();
|
||||
colors[ Qsk::Right ] = right.toRgb();
|
||||
colors[ Qsk::Bottom ] = bottom.toRgb();
|
||||
gradients[ Qsk::Left ] = left;
|
||||
gradients[ Qsk::Top ] = top;
|
||||
gradients[ Qsk::Right ] = right;
|
||||
gradients[ Qsk::Bottom ] = bottom;
|
||||
}
|
||||
|
||||
QskBoxBorderColors::QskBoxBorderColors()
|
||||
@ -44,15 +42,20 @@ QskBoxBorderColors::QskBoxBorderColors()
|
||||
}
|
||||
|
||||
QskBoxBorderColors::QskBoxBorderColors(
|
||||
const QColor& left, const QColor& top,
|
||||
const QColor& right, const QColor& bottom )
|
||||
const QskGradient& left, const QskGradient& top,
|
||||
const QskGradient& right, const QskGradient& bottom )
|
||||
{
|
||||
qskSetColors( left, top, right, bottom, m_colors );
|
||||
qskSetGradients( left, top, right, bottom, m_gradients );
|
||||
}
|
||||
|
||||
QskBoxBorderColors::QskBoxBorderColors( const QColor& color )
|
||||
{
|
||||
qskSetColors( color, m_colors );
|
||||
qskSetGradients( color, m_gradients );
|
||||
}
|
||||
|
||||
QskBoxBorderColors::QskBoxBorderColors( const QskGradient& gradient )
|
||||
{
|
||||
qskSetGradients( gradient, m_gradients );
|
||||
}
|
||||
|
||||
QskBoxBorderColors::~QskBoxBorderColors()
|
||||
@ -61,88 +64,85 @@ QskBoxBorderColors::~QskBoxBorderColors()
|
||||
|
||||
bool QskBoxBorderColors::operator==( const QskBoxBorderColors& other ) const
|
||||
{
|
||||
return ( m_colors[ 0 ] == other.m_colors[ 0 ] ) &&
|
||||
( m_colors[ 1 ] == other.m_colors[ 1 ] ) &&
|
||||
( m_colors[ 2 ] == other.m_colors[ 2 ] ) &&
|
||||
( m_colors[ 3 ] == other.m_colors[ 3 ] );
|
||||
return ( m_gradients[ 0 ] == other.m_gradients[ 0 ] ) &&
|
||||
( m_gradients[ 1 ] == other.m_gradients[ 1 ] ) &&
|
||||
( m_gradients[ 2 ] == other.m_gradients[ 2 ] ) &&
|
||||
( m_gradients[ 3 ] == other.m_gradients[ 3 ] );
|
||||
}
|
||||
|
||||
void QskBoxBorderColors::setAlpha( int alpha )
|
||||
{
|
||||
for ( int i = 0; i < 4; i++ )
|
||||
{
|
||||
if ( m_colors[ i ].isValid() && m_colors[ i ].alpha() )
|
||||
m_colors[ i ].setAlpha( alpha );
|
||||
if ( m_gradients[ i ].isValid() )
|
||||
m_gradients[ i ].setAlpha( alpha );
|
||||
}
|
||||
}
|
||||
|
||||
void QskBoxBorderColors::setColors( const QColor& color )
|
||||
void QskBoxBorderColors::setGradients( const QskGradient& gradient )
|
||||
{
|
||||
qskSetColors( color, m_colors );
|
||||
qskSetGradients( gradient, m_gradients );
|
||||
}
|
||||
|
||||
void QskBoxBorderColors::setColors(
|
||||
const QColor& left, const QColor& top,
|
||||
const QColor& right, const QColor& bottom )
|
||||
void QskBoxBorderColors::setGradients( const QskGradient& left, const QskGradient& top,
|
||||
const QskGradient& right, const QskGradient& bottom )
|
||||
{
|
||||
qskSetColors( left, top, right, bottom, m_colors );
|
||||
qskSetGradients( left, top, right, bottom, m_gradients );
|
||||
}
|
||||
|
||||
void QskBoxBorderColors::setColor(
|
||||
Qsk::Position position, const QColor& color )
|
||||
void QskBoxBorderColors::setGradient( Qsk::Position position, const QskGradient& gradient )
|
||||
{
|
||||
m_colors[ position ] = color.toRgb();
|
||||
m_gradients[ position ] = gradient;
|
||||
}
|
||||
|
||||
void QskBoxBorderColors::setColorsAt( Qt::Edges edges, const QColor& color )
|
||||
void QskBoxBorderColors::setGradientAt( Qt::Edges edges, const QskGradient& gradient )
|
||||
{
|
||||
const QColor c = color.toRgb();
|
||||
|
||||
if ( edges & Qt::TopEdge )
|
||||
m_colors[ Qsk::Top ] = c;
|
||||
m_gradients[ Qsk::Top ] = gradient;
|
||||
|
||||
if ( edges & Qt::LeftEdge )
|
||||
m_colors[ Qsk::Left ] = c;
|
||||
m_gradients[ Qsk::Left ] = gradient;
|
||||
|
||||
if ( edges & Qt::RightEdge )
|
||||
m_colors[ Qsk::Right ] = c;
|
||||
m_gradients[ Qsk::Right ] = gradient;
|
||||
|
||||
if ( edges & Qt::BottomEdge )
|
||||
m_colors[ Qsk::Bottom ] = c;
|
||||
m_gradients[ Qsk::Bottom ] = gradient;
|
||||
}
|
||||
|
||||
QColor QskBoxBorderColors::colorAt( Qt::Edge edge ) const
|
||||
const QskGradient& QskBoxBorderColors::gradientAt( Qt::Edge edge ) const
|
||||
{
|
||||
switch ( edge )
|
||||
{
|
||||
case Qt::TopEdge:
|
||||
return m_colors[ Qsk::Top ];
|
||||
return m_gradients[ Qsk::Top ];
|
||||
|
||||
case Qt::LeftEdge:
|
||||
return m_colors[ Qsk::Left ];
|
||||
return m_gradients[ Qsk::Left ];
|
||||
|
||||
case Qt::RightEdge:
|
||||
return m_colors[ Qsk::Right ];
|
||||
return m_gradients[ Qsk::Right ];
|
||||
|
||||
case Qt::BottomEdge:
|
||||
return m_colors[ Qsk::Bottom ];
|
||||
return m_gradients[ Qsk::Bottom ];
|
||||
}
|
||||
|
||||
return QColor();
|
||||
static QskGradient noGradient;
|
||||
return noGradient;
|
||||
}
|
||||
|
||||
bool QskBoxBorderColors::isVisible() const
|
||||
{
|
||||
if ( qskIsVisble( m_colors[ 0 ] ) )
|
||||
if ( m_gradients[ 0 ].isVisible() )
|
||||
return true;
|
||||
|
||||
if ( qskIsVisble( m_colors[ 1 ] ) )
|
||||
if ( m_gradients[ 1 ].isVisible() )
|
||||
return true;
|
||||
|
||||
if ( qskIsVisble( m_colors[ 2 ] ) )
|
||||
if ( m_gradients[ 2 ].isVisible() )
|
||||
return true;
|
||||
|
||||
if ( qskIsVisble( m_colors[ 3 ] ) )
|
||||
if ( m_gradients[ 3 ].isVisible() )
|
||||
return true;
|
||||
|
||||
return false;
|
||||
@ -150,16 +150,19 @@ bool QskBoxBorderColors::isVisible() const
|
||||
|
||||
bool QskBoxBorderColors::isMonochrome() const
|
||||
{
|
||||
if ( m_colors[ 1 ] != m_colors[ 0 ] )
|
||||
if ( m_gradients[ 1 ] != m_gradients[ 0 ] )
|
||||
return false;
|
||||
|
||||
if ( m_colors[ 2 ] != m_colors[ 1 ] )
|
||||
if ( m_gradients[ 2 ] != m_gradients[ 1 ] )
|
||||
return false;
|
||||
|
||||
if ( m_colors[ 3 ] != m_colors[ 2 ] )
|
||||
if ( m_gradients[ 3 ] != m_gradients[ 2 ] )
|
||||
return false;
|
||||
|
||||
return true;
|
||||
return m_gradients[ 0 ].isMonochrome()
|
||||
&& m_gradients[ 1 ].isMonochrome()
|
||||
&& m_gradients[ 2 ].isMonochrome()
|
||||
&& m_gradients[ 3 ].isMonochrome();
|
||||
}
|
||||
|
||||
QskBoxBorderColors QskBoxBorderColors::interpolated(
|
||||
@ -169,8 +172,8 @@ QskBoxBorderColors QskBoxBorderColors::interpolated(
|
||||
|
||||
for ( size_t i = 0; i < 4; i++ )
|
||||
{
|
||||
colors.m_colors[ i ] = QskRgb::interpolated(
|
||||
m_colors[ i ], to.m_colors[ i ], ratio );
|
||||
colors.m_gradients[ i ] = colors.m_gradients[ i ].interpolated(
|
||||
to.m_gradients[ i ], ratio );
|
||||
}
|
||||
|
||||
return colors;
|
||||
@ -184,30 +187,18 @@ QVariant QskBoxBorderColors::interpolate(
|
||||
|
||||
uint QskBoxBorderColors::hash( uint seed ) const
|
||||
{
|
||||
const QRgb rgb[] =
|
||||
{
|
||||
m_colors[ 0 ].rgba(),
|
||||
m_colors[ 1 ].rgba(),
|
||||
m_colors[ 2 ].rgba(),
|
||||
m_colors[ 3 ].rgba(),
|
||||
};
|
||||
uint h = m_gradients[ 0 ].hash( seed );
|
||||
h = m_gradients[ 1 ].hash( h );
|
||||
h = m_gradients[ 2 ].hash( h );
|
||||
h = m_gradients[ 3 ].hash( h );
|
||||
|
||||
return qHashBits( rgb, sizeof( rgb ), seed );
|
||||
return h;
|
||||
}
|
||||
|
||||
#ifndef QT_NO_DEBUG_STREAM
|
||||
|
||||
#include <qdebug.h>
|
||||
|
||||
static inline void qskDebugColor( QDebug debug, const QColor& c )
|
||||
{
|
||||
debug << '('
|
||||
<< c.red() << ','
|
||||
<< c.green() << ','
|
||||
<< c.blue() << ','
|
||||
<< c.alpha() << ')';
|
||||
}
|
||||
|
||||
QDebug operator<<( QDebug debug, const QskBoxBorderColors& colors )
|
||||
{
|
||||
QDebugStateSaver saver( debug );
|
||||
@ -215,17 +206,13 @@ QDebug operator<<( QDebug debug, const QskBoxBorderColors& colors )
|
||||
|
||||
debug << "BoxBorderColors" << '(';
|
||||
|
||||
debug << " L";
|
||||
qskDebugColor( debug, colors.color( Qsk::Left ) );
|
||||
debug << " L" << colors.gradient( Qsk::Left );
|
||||
|
||||
debug << ", T";
|
||||
qskDebugColor( debug, colors.color( Qsk::Top ) );
|
||||
debug << ", T" << colors.gradient( Qsk::Top );
|
||||
|
||||
debug << ", R";
|
||||
qskDebugColor( debug, colors.color( Qsk::Right ) );
|
||||
debug << ", R" << colors.gradient( Qsk::Right );
|
||||
|
||||
debug << ", B";
|
||||
qskDebugColor( debug, colors.color( Qsk::Bottom ) );
|
||||
debug << ", B" << colors.gradient( Qsk::Bottom );
|
||||
|
||||
debug << " )";
|
||||
|
||||
|
@ -6,6 +6,7 @@
|
||||
#ifndef QSK_BOX_BORDER_COLORS_H
|
||||
#define QSK_BOX_BORDER_COLORS_H
|
||||
|
||||
#include "QskGradient.h"
|
||||
#include "QskNamespace.h"
|
||||
|
||||
#include <qcolor.h>
|
||||
@ -18,12 +19,13 @@ class QSK_EXPORT QskBoxBorderColors
|
||||
public:
|
||||
QskBoxBorderColors();
|
||||
|
||||
QskBoxBorderColors( const QColor& left, const QColor& top,
|
||||
const QColor& right, const QColor& bottom );
|
||||
QskBoxBorderColors( const QskGradient& left, const QskGradient& top,
|
||||
const QskGradient& right, const QskGradient& bottom );
|
||||
|
||||
QskBoxBorderColors( Qt::GlobalColor );
|
||||
QskBoxBorderColors( QRgb );
|
||||
QskBoxBorderColors( const QColor& );
|
||||
QskBoxBorderColors( const QskGradient& );
|
||||
|
||||
~QskBoxBorderColors();
|
||||
|
||||
@ -32,17 +34,15 @@ class QSK_EXPORT QskBoxBorderColors
|
||||
|
||||
void setAlpha( int alpha );
|
||||
|
||||
void setColors( const QColor& );
|
||||
void setColors( const QColor& left, const QColor& top,
|
||||
const QColor& right, const QColor& bottom );
|
||||
void setGradients( const QskGradient& );
|
||||
void setGradients( const QskGradient& left, const QskGradient& top,
|
||||
const QskGradient& right, const QskGradient& bottom );
|
||||
|
||||
void setColor( Qsk::Position, const QColor& );
|
||||
QColor color( Qsk::Position ) const;
|
||||
void setGradient( Qsk::Position, const QskGradient& );
|
||||
QskGradient gradient( Qsk::Position ) const;
|
||||
|
||||
void setColorsAt( Qt::Edges, const QColor& );
|
||||
QColor colorAt( Qt::Edge ) const;
|
||||
|
||||
QRgb rgb( Qsk::Position ) const;
|
||||
void setGradientAt( Qt::Edges, const QskGradient& );
|
||||
const QskGradient& gradientAt( Qt::Edge ) const;
|
||||
|
||||
QskBoxBorderColors interpolated( const QskBoxBorderColors&, qreal value ) const;
|
||||
|
||||
@ -55,8 +55,7 @@ class QSK_EXPORT QskBoxBorderColors
|
||||
bool isVisible() const;
|
||||
|
||||
private:
|
||||
// should be stored as QRgb
|
||||
QColor m_colors[ 4 ];
|
||||
QskGradient m_gradients[ 4 ];
|
||||
};
|
||||
|
||||
inline QskBoxBorderColors::QskBoxBorderColors( Qt::GlobalColor color )
|
||||
@ -74,14 +73,9 @@ inline bool QskBoxBorderColors::operator!=( const QskBoxBorderColors& other ) co
|
||||
return !( *this == other );
|
||||
}
|
||||
|
||||
inline QColor QskBoxBorderColors::color( Qsk::Position position ) const
|
||||
inline QskGradient QskBoxBorderColors::gradient( Qsk::Position position ) const
|
||||
{
|
||||
return m_colors[ position ];
|
||||
}
|
||||
|
||||
inline QRgb QskBoxBorderColors::rgb( Qsk::Position position ) const
|
||||
{
|
||||
return m_colors[ position ].rgba();
|
||||
return m_gradients[ position ];
|
||||
}
|
||||
|
||||
#ifndef QT_NO_DEBUG_STREAM
|
||||
|
@ -472,8 +472,8 @@ void QskSkinHintTableEditor::setBoxBorderColors(
|
||||
}
|
||||
|
||||
void QskSkinHintTableEditor::setBoxBorderColors(QskAspect aspect,
|
||||
const QColor& left, const QColor& top, const QColor& right, const QColor& bottom,
|
||||
QskStateCombination combination )
|
||||
const QskGradient& left, const QskGradient& top, const QskGradient& right,
|
||||
const QskGradient& bottom, QskStateCombination combination )
|
||||
{
|
||||
setColorHint( aspectBorder( aspect ),
|
||||
QskBoxBorderColors( left, top, right, bottom ),
|
||||
|
@ -227,7 +227,8 @@ class QSK_EXPORT QskSkinHintTableEditor
|
||||
const QskBoxBorderColors&, QskStateCombination = QskStateCombination() );
|
||||
|
||||
void setBoxBorderColors( QskAspect,
|
||||
const QColor& left, const QColor& top, const QColor& right, const QColor& bottom,
|
||||
const QskGradient& left, const QskGradient& top,
|
||||
const QskGradient& right, const QskGradient& bottom,
|
||||
QskStateCombination = QskStateCombination() );
|
||||
|
||||
void removeBoxBorderColors( QskAspect, QskStateCombination = QskStateCombination() );
|
||||
|
@ -117,7 +117,8 @@ void QskBoxNode::setBoxData( const QRectF& rect,
|
||||
{
|
||||
if ( isFillMonochrome && isBorderMonochrome )
|
||||
{
|
||||
if ( borderColors.color( Qsk::Left ) == fillGradient.startColor() )
|
||||
if ( borderColors.gradient( Qsk::Left ).startColor()
|
||||
== fillGradient.startColor() )
|
||||
{
|
||||
// we can draw border and background in one
|
||||
hasBorder = false;
|
||||
@ -171,7 +172,7 @@ void QskBoxNode::setBoxData( const QRectF& rect,
|
||||
}
|
||||
else
|
||||
{
|
||||
flatMaterial->setColor( borderColors.color( Qsk::Left ).rgba() );
|
||||
flatMaterial->setColor( borderColors.gradient( Qsk::Left ).startColor().rgba() );
|
||||
renderer.renderBorder( m_rect, shape, borderMetrics, *geometry() );
|
||||
}
|
||||
}
|
||||
|
@ -97,6 +97,26 @@ namespace
|
||||
int m_stepCount;
|
||||
bool m_inverted;
|
||||
};
|
||||
|
||||
int additionalGradientStops( const QskGradient& gradient )
|
||||
{
|
||||
return qMax( 0, gradient.stops().count() - 2 );
|
||||
}
|
||||
|
||||
static inline QRgb qskRgbGradientStart( const QskGradient& gradient )
|
||||
{
|
||||
return gradient.startColor().rgba();
|
||||
}
|
||||
|
||||
static inline QRgb qskRgbGradientEnd( const QskGradient& gradient )
|
||||
{
|
||||
return gradient.endColor().rgba();
|
||||
}
|
||||
|
||||
static inline QRgb qskRgbBorder( const QskBoxBorderColors& borderColors )
|
||||
{
|
||||
return qskRgbGradientStart( borderColors.gradient( Qsk::Left ) );
|
||||
}
|
||||
}
|
||||
|
||||
namespace
|
||||
@ -488,6 +508,7 @@ namespace
|
||||
{
|
||||
public:
|
||||
static inline constexpr Color colorAt( int ) { return Color(); }
|
||||
inline QskGradient gradient() const { return QskGradient(); }
|
||||
};
|
||||
|
||||
class BorderMapSolid
|
||||
@ -499,6 +520,7 @@ namespace
|
||||
}
|
||||
|
||||
inline Color colorAt( int ) const { return m_color; }
|
||||
inline QskGradient gradient() const { return QskGradient(); }
|
||||
|
||||
const Color m_color;
|
||||
};
|
||||
@ -506,10 +528,11 @@ namespace
|
||||
class BorderMapGradient
|
||||
{
|
||||
public:
|
||||
inline BorderMapGradient( int stepCount, QRgb rgb1, QRgb rgb2 )
|
||||
inline BorderMapGradient( int stepCount, QRgb rgb1, QRgb rgb2, const QskGradient& gradient )
|
||||
: m_stepCount( stepCount )
|
||||
, m_color1( rgb1 )
|
||||
, m_color2( rgb2 )
|
||||
, m_gradient( gradient )
|
||||
{
|
||||
}
|
||||
|
||||
@ -518,9 +541,15 @@ namespace
|
||||
return m_color1.interpolatedTo( m_color2, step / m_stepCount );
|
||||
}
|
||||
|
||||
inline QskGradient gradient() const
|
||||
{
|
||||
return m_gradient;
|
||||
}
|
||||
|
||||
private:
|
||||
const qreal m_stepCount;
|
||||
const Color m_color1, m_color2;
|
||||
const QskGradient m_gradient;
|
||||
};
|
||||
|
||||
template< class Line, class BorderValues >
|
||||
@ -532,6 +561,27 @@ namespace
|
||||
{
|
||||
}
|
||||
|
||||
void addAdditionalLines( float x11, float y11, float x12, float y12, // start line
|
||||
float x21,float y21, float x22, float y22, // end line
|
||||
const QskGradient& gradient, Line* lines )
|
||||
{
|
||||
int additionalStopCount = additionalGradientStops( gradient );
|
||||
|
||||
auto s = gradient.stops();
|
||||
|
||||
for( int i = 1; i <= additionalStopCount; ++i )
|
||||
{
|
||||
auto p = ( 1 - s.at( i ).position() );
|
||||
float xStart = x11 + p * ( x21 - x11 ),
|
||||
yStart = y11 + p * ( y21 - y11 ),
|
||||
xEnd = x12 + p * ( x22 - x12 ),
|
||||
yEnd = y12 + p * ( y22 - y12 );
|
||||
|
||||
lines[ additionalStopCount - i + 1 ].setLine( xStart, yStart,
|
||||
xEnd, yEnd, s.at( i ).color() );
|
||||
}
|
||||
}
|
||||
|
||||
template< class BorderMap, class FillMap >
|
||||
inline void createLines( Qt::Orientation orientation, Line* borderLines,
|
||||
const BorderMap& borderMapTL, const BorderMap& borderMapTR,
|
||||
@ -555,9 +605,12 @@ namespace
|
||||
if ( borderLines )
|
||||
{
|
||||
linesBR = borderLines;
|
||||
linesTR = linesBR + numCornerLines;
|
||||
linesTL = linesTR + numCornerLines;
|
||||
linesBL = linesTL + numCornerLines;
|
||||
linesTR = linesBR + numCornerLines
|
||||
+ additionalGradientStops( borderMapBR.gradient() );
|
||||
linesTL = linesTR + numCornerLines
|
||||
+ additionalGradientStops( borderMapTR.gradient() );
|
||||
linesBL = linesTL + numCornerLines
|
||||
+ additionalGradientStops( borderMapTL.gradient() );
|
||||
}
|
||||
|
||||
if ( fillLines )
|
||||
@ -571,9 +624,12 @@ namespace
|
||||
if ( borderLines )
|
||||
{
|
||||
linesTR = borderLines + 1;
|
||||
linesTL = linesTR + numCornerLines;
|
||||
linesBL = linesTL + numCornerLines;
|
||||
linesBR = linesBL + numCornerLines;
|
||||
linesTL = linesTR + numCornerLines
|
||||
+ additionalGradientStops( borderMapTR.gradient() );
|
||||
linesBL = linesTL + numCornerLines
|
||||
+ additionalGradientStops( borderMapTL.gradient() );
|
||||
linesBR = linesBL + numCornerLines
|
||||
+ additionalGradientStops( borderMapBL.gradient() );
|
||||
}
|
||||
|
||||
if ( fillLines )
|
||||
@ -641,6 +697,83 @@ namespace
|
||||
c[ corner ].centerY + v.dy2( corner ),
|
||||
borderMapBR.colorAt( j ) );
|
||||
}
|
||||
|
||||
// at the beginning and end of the loop we can add
|
||||
// additional lines for border gradients:
|
||||
|
||||
if( j == 0 )
|
||||
{
|
||||
if( additionalGradientStops( borderMapTR.gradient() ) > 0 )
|
||||
{
|
||||
float x1TR = c[ TopRight ].centerX + v.dx1( TopRight ),
|
||||
y1TR = c[ TopRight ].centerY - v.dy1( TopRight ),
|
||||
x2TR = c[ TopRight ].centerX + v.dx2( TopRight ),
|
||||
y2TR = c[ TopRight ].centerY - v.dy2( TopRight ),
|
||||
|
||||
x1TL = c[ TopLeft ].centerX - v.dx1( TopLeft ),
|
||||
y1TL = c[ TopLeft ].centerY - v.dy1( TopLeft ),
|
||||
x2TL = c[ TopLeft ].centerX - v.dx2( TopLeft ),
|
||||
y2TL = c[ TopLeft ].centerY - v.dy2( TopLeft );
|
||||
|
||||
addAdditionalLines( x1TR, y1TR, x2TR, y2TR,
|
||||
x1TL, y1TL, x2TL, y2TL,
|
||||
borderMapTR.gradient(), linesTR + k );
|
||||
}
|
||||
|
||||
if( additionalGradientStops( borderMapBL.gradient() ) > 0 )
|
||||
{
|
||||
float x1BL = c[ BottomLeft ].centerX - v.dx1( BottomLeft ),
|
||||
y1BL = c[ BottomLeft ].centerY + v.dy1( BottomLeft ),
|
||||
x2BL = c[ BottomLeft ].centerX - v.dx2( BottomLeft ),
|
||||
y2BL = c[ BottomLeft ].centerY + v.dy2( BottomLeft ),
|
||||
|
||||
x1BR = c[ BottomRight ].centerX + v.dx1( BottomRight ),
|
||||
y1BR = c[ BottomRight ].centerY + v.dy1( BottomRight ),
|
||||
x2BR = c[ BottomRight ].centerX + v.dx2( BottomRight ),
|
||||
y2BR = c[ BottomRight ].centerY + v.dy2( BottomRight );
|
||||
|
||||
addAdditionalLines( x1BL, y1BL, x2BL, y2BL,
|
||||
x1BR, y1BR, x2BR, y2BR,
|
||||
borderMapBL.gradient(), linesBL + k );
|
||||
}
|
||||
}
|
||||
|
||||
if( j == numCornerLines - 1 )
|
||||
{
|
||||
if( additionalGradientStops( borderMapTL.gradient() ) > 0 )
|
||||
{
|
||||
float x1TL = c[ TopLeft ].centerX - v.dx1( TopLeft ),
|
||||
y1TL = c[ TopLeft ].centerY - v.dy1( TopLeft ),
|
||||
x2TL = c[ TopLeft ].centerX - v.dx2( TopLeft ),
|
||||
y2TL = c[ TopLeft ].centerY - v.dy2( TopLeft ),
|
||||
|
||||
x1BL = c[ BottomLeft ].centerX - v.dx1( BottomLeft ),
|
||||
y1BL = c[ BottomLeft ].centerY + v.dy1( BottomLeft ),
|
||||
x2BL = c[ BottomLeft ].centerX - v.dx2( BottomLeft ),
|
||||
y2BL = c[ BottomLeft ].centerY + v.dy2( BottomLeft );
|
||||
|
||||
addAdditionalLines( x1TL, y1TL, x2TL, y2TL,
|
||||
x1BL, y1BL, x2BL, y2BL,
|
||||
borderMapTL.gradient(), linesTL + j );
|
||||
}
|
||||
|
||||
if( additionalGradientStops( borderMapBR.gradient() ) > 0 )
|
||||
{
|
||||
float x1BR = c[ BottomRight ].centerX + v.dx1( BottomRight ),
|
||||
y1BR = c[ BottomRight ].centerY + v.dy1( BottomRight ),
|
||||
x2BR = c[ BottomRight ].centerX + v.dx2( BottomRight ),
|
||||
y2BR = c[ BottomRight ].centerY + v.dy2( BottomRight ),
|
||||
|
||||
x1TR = c[ TopRight ].centerX + v.dx1( TopRight ),
|
||||
y1TR = c[ TopRight ].centerY - v.dy1( TopRight ),
|
||||
x2TR = c[ TopRight ].centerX + v.dx2( TopRight ),
|
||||
y2TR = c[ TopRight ].centerY - v.dy2( TopRight );
|
||||
|
||||
addAdditionalLines( x1BR, y1BR, x2BR, y2BR,
|
||||
x1TR, y1TR, x2TR, y2TR,
|
||||
borderMapBR.gradient(), linesBR + j );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( fillLines )
|
||||
@ -689,7 +822,12 @@ namespace
|
||||
#if 1
|
||||
if ( borderLines )
|
||||
{
|
||||
const int k = 4 * numCornerLines;
|
||||
const int additionalStops =
|
||||
additionalGradientStops( borderMapBR.gradient() )
|
||||
+ additionalGradientStops( borderMapTR.gradient() )
|
||||
+ additionalGradientStops( borderMapTL.gradient() )
|
||||
+ additionalGradientStops( borderMapBL.gradient() );
|
||||
const int k = 4 * numCornerLines + additionalStops;
|
||||
|
||||
if ( orientation == Qt::Vertical )
|
||||
borderLines[ k ] = borderLines[ 0 ];
|
||||
@ -859,17 +997,24 @@ static inline void qskRenderBorder( const QskBoxRenderer::Metrics& metrics,
|
||||
|
||||
if ( colors.isMonochrome() )
|
||||
{
|
||||
qskRenderBorderLines( metrics, orientation, line, BorderMapSolid( c.rgb( Qsk::Left ) ) );
|
||||
qskRenderBorderLines( metrics, orientation, line, BorderMapSolid( qskRgbBorder( c ) ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
const int stepCount = metrics.corner[ 0 ].stepCount;
|
||||
|
||||
auto left = c.gradient( Qsk::Left ), top = c.gradient( Qsk::Top ),
|
||||
right = c.gradient( Qsk::Right ), bottom = c.gradient( Qsk::Bottom );
|
||||
|
||||
qskRenderBorderLines( metrics, orientation, line,
|
||||
BorderMapGradient( stepCount, c.rgb( Qsk::Top ), c.rgb( Qsk::Left ) ),
|
||||
BorderMapGradient( stepCount, c.rgb( Qsk::Right ), c.rgb( Qsk::Top ) ),
|
||||
BorderMapGradient( stepCount, c.rgb( Qsk::Left ), c.rgb( Qsk::Bottom ) ),
|
||||
BorderMapGradient( stepCount, c.rgb( Qsk::Bottom ), c.rgb( Qsk::Right ) ) );
|
||||
BorderMapGradient( stepCount, qskRgbGradientStart( top ),
|
||||
qskRgbGradientEnd( left ), left ),
|
||||
BorderMapGradient( stepCount, qskRgbGradientStart( right ),
|
||||
qskRgbGradientEnd( top ), top ),
|
||||
BorderMapGradient( stepCount, qskRgbGradientStart( left ),
|
||||
qskRgbGradientEnd( bottom ), bottom ),
|
||||
BorderMapGradient( stepCount, qskRgbGradientStart( bottom ),
|
||||
qskRgbGradientEnd( right ), right ) );
|
||||
}
|
||||
}
|
||||
|
||||
@ -899,7 +1044,7 @@ static inline void qskRenderBoxRandom(
|
||||
|
||||
if ( bc.isMonochrome() )
|
||||
{
|
||||
const BorderMapSolid borderMap( bc.rgb( Qsk::Left ) );
|
||||
const BorderMapSolid borderMap( qskRgbBorder( bc.gradient( Qsk::Left ) ) );
|
||||
|
||||
if ( gradient.isMonochrome() )
|
||||
{
|
||||
@ -918,10 +1063,17 @@ static inline void qskRenderBoxRandom(
|
||||
{
|
||||
const int n = metrics.corner[ 0 ].stepCount;
|
||||
|
||||
const BorderMapGradient tl( n, bc.rgb( Qsk::Top ), bc.rgb( Qsk::Left ) );
|
||||
const BorderMapGradient tr( n, bc.rgb( Qsk::Right ), bc.rgb( Qsk::Top ) );
|
||||
const BorderMapGradient bl( n, bc.rgb( Qsk::Left ), bc.rgb( Qsk::Bottom ) );
|
||||
const BorderMapGradient br( n, bc.rgb( Qsk::Bottom ), bc.rgb( Qsk::Right ) );
|
||||
auto left = bc.gradient( Qsk::Left ), top = bc.gradient( Qsk::Top ),
|
||||
right = bc.gradient( Qsk::Right ), bottom = bc.gradient( Qsk::Bottom );
|
||||
|
||||
const BorderMapGradient tl( n, qskRgbGradientStart( top.startColor() ),
|
||||
qskRgbGradientEnd( left.endColor() ), left );
|
||||
const BorderMapGradient tr( n, qskRgbGradientStart( right ),
|
||||
qskRgbGradientEnd( top ), top );
|
||||
const BorderMapGradient bl( n, qskRgbGradientStart( left ),
|
||||
qskRgbGradientEnd( bottom ), bottom );
|
||||
const BorderMapGradient br( n, qskRgbGradientStart( bottom ),
|
||||
qskRgbGradientEnd( right ), right );
|
||||
|
||||
if ( gradient.isMonochrome() )
|
||||
{
|
||||
@ -1207,9 +1359,20 @@ void QskBoxRenderer::renderRectellipse( const QRectF& rect,
|
||||
const int stepCount = metrics.corner[ 0 ].stepCount;
|
||||
|
||||
int borderLineCount = 0;
|
||||
|
||||
if ( borderColors.isVisible() && metrics.innerQuad != metrics.outerQuad )
|
||||
{
|
||||
borderLineCount = 4 * ( stepCount + 1 ) + 1;
|
||||
|
||||
const int additionalLines =
|
||||
additionalGradientStops( borderColors.gradient( Qsk::Left ) )
|
||||
+ additionalGradientStops( borderColors.gradient( Qsk::Top ) )
|
||||
+ additionalGradientStops( borderColors.gradient( Qsk::Right ) )
|
||||
+ additionalGradientStops( borderColors.gradient( Qsk::Bottom ) );
|
||||
|
||||
borderLineCount += additionalLines;
|
||||
}
|
||||
|
||||
int lineCount = borderLineCount + fillLineCount;
|
||||
|
||||
bool extraLine = false;
|
||||
|
@ -422,28 +422,63 @@ static inline void qskCreateBorder(
|
||||
const QskBoxRenderer::Quad& out, const QskBoxRenderer::Quad& in,
|
||||
const QskBoxBorderColors& colors, Line* line )
|
||||
{
|
||||
const Color colorLeft = colors.rgb( Qsk::Left );
|
||||
const Color colorRight = colors.rgb( Qsk::Right );
|
||||
const Color colorTop = colors.rgb( Qsk::Top );
|
||||
const Color colorBottom = colors.rgb( Qsk::Bottom );
|
||||
const QskGradient gradientLeft = colors.gradient( Qsk::Left );
|
||||
const QskGradient gradientRight = colors.gradient( Qsk::Right );
|
||||
const QskGradient gradientTop = colors.gradient( Qsk::Top );
|
||||
const QskGradient gradientBottom = colors.gradient( Qsk::Bottom );
|
||||
|
||||
( line++ )->setLine( in.right, in.bottom, out.right, out.bottom, colorBottom );
|
||||
( line++ )->setLine( in.left, in.bottom, out.left, out.bottom, colorBottom );
|
||||
// qdebug
|
||||
|
||||
if ( colorLeft != colorBottom )
|
||||
( line++ )->setLine( in.left, in.bottom, out.left, out.bottom, colorLeft );
|
||||
const qreal dx1 = in.right - in.left;
|
||||
const qreal dx2 = out.right - out.left;
|
||||
const qreal dy1 = in.top - in.bottom;
|
||||
const qreal dy2 = out.top - out.bottom;
|
||||
|
||||
( line++ )->setLine( in.left, in.top, out.left, out.top, colorLeft );
|
||||
for( const auto& stop : gradientBottom.stops() )
|
||||
{
|
||||
const Color c( stop.color() );
|
||||
const qreal x1 = in.right - stop.position() * dx1;
|
||||
const qreal x2 = out.right - stop.position() * dx2;
|
||||
const qreal y1 = in.bottom;
|
||||
const qreal y2 = out.bottom;
|
||||
|
||||
if ( colorTop != colorLeft )
|
||||
( line++ )->setLine( in.left, in.top, out.left, out.top, colorTop );
|
||||
( line++ )->setLine( x1, y1, x2, y2, c );
|
||||
}
|
||||
|
||||
( line++ )->setLine( in.right, in.top, out.right, out.top, colorTop );
|
||||
for( const auto& stop : gradientLeft.stops() )
|
||||
{
|
||||
const Color c( stop.color() );
|
||||
const qreal x1 = in.left;
|
||||
const qreal x2 = out.left;
|
||||
const qreal y1 = in.bottom + stop.position() * dy1;
|
||||
const qreal y2 = out.bottom + stop.position() * dy2;
|
||||
|
||||
if ( colorRight != colorTop )
|
||||
( line++ )->setLine( in.right, in.top, out.right, out.top, colorRight );
|
||||
( line++ )->setLine( x1, y1, x2, y2, c );
|
||||
}
|
||||
|
||||
( line++ )->setLine( in.right, in.bottom, out.right, out.bottom, colorRight );
|
||||
for( const auto& stop : gradientTop.stops() )
|
||||
{
|
||||
const Color c( stop.color() );
|
||||
const qreal x1 = in.left + stop.position() * dx1;
|
||||
const qreal x2 = out.left + stop.position() * dx2;
|
||||
const qreal y1 = in.top;
|
||||
const qreal y2 = out.top;
|
||||
|
||||
( line++ )->setLine( x1, y1, x2, y2, c );
|
||||
}
|
||||
|
||||
for( const auto& stop : gradientRight.stops() )
|
||||
{
|
||||
const Color c( stop.color() );
|
||||
const qreal x1 = in.right;
|
||||
const qreal x2 = out.right;
|
||||
// ( 1 - stop.position() ) because we want to make the gradients go
|
||||
// around the border clock-wise:
|
||||
const qreal y1 = in.bottom + ( 1 - stop.position() ) * dy1;
|
||||
const qreal y2 = out.bottom + ( 1 - stop.position() ) * dy2;
|
||||
|
||||
( line++ )->setLine( x1, y1, x2, y2, c );
|
||||
}
|
||||
}
|
||||
|
||||
void QskBoxRenderer::renderRectBorder(
|
||||
@ -533,14 +568,15 @@ void QskBoxRenderer::renderRect(
|
||||
// we might need extra lines to separate colors
|
||||
// at the non closing corners
|
||||
|
||||
if ( bc.color( Qsk::Left ) != bc.color( Qsk::Bottom ) )
|
||||
borderLineCount++;
|
||||
// ### As an optimization we could check orientation and colors
|
||||
// to test whether colors are the same
|
||||
const int additionalLines = -1
|
||||
+ bc.gradient( Qsk::Left ).stops().count() - 1
|
||||
+ bc.gradient( Qsk::Top ).stops().count() - 1
|
||||
+ bc.gradient( Qsk::Right ).stops().count() - 1
|
||||
+ bc.gradient( Qsk::Bottom ).stops().count() - 1;
|
||||
|
||||
if ( bc.color( Qsk::Top ) != bc.color( Qsk::Left ) )
|
||||
borderLineCount++;
|
||||
|
||||
if ( bc.color( Qsk::Right ) != bc.color( Qsk::Top ) )
|
||||
borderLineCount++;
|
||||
borderLineCount += qMax( additionalLines, 0 );
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -587,7 +623,7 @@ void QskBoxRenderer::renderRect(
|
||||
auto fillLines = line + fillLineCount;
|
||||
|
||||
if ( bc.isMonochrome() )
|
||||
qskCreateBorderMonochrome( rect, in, bc.rgb( Qsk::Left ), fillLines );
|
||||
qskCreateBorderMonochrome( rect, in, bc.gradient( Qsk::Left ).startColor().rgba(), fillLines );
|
||||
else
|
||||
qskCreateBorder( rect, in, bc, fillLines );
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user