2010-05-02 18:50:01 +00:00
|
|
|
/*
|
|
|
|
* Copyright 2008 Long Huynh Huu <long.upcase@googlemail.com>
|
|
|
|
* Copyright 2007 Matthew Woehlke <mw_triad@users.sourceforge.net>
|
|
|
|
* Copyright 2007 Casper Boemann <cbr@boemann.dk>
|
|
|
|
*
|
|
|
|
* This library is free software; you can redistribute it and/or
|
|
|
|
* modify it under the terms of the GNU Library General Public
|
|
|
|
* License version 2 as published by the Free Software Foundation.
|
|
|
|
*
|
|
|
|
* This library is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
|
|
* Library General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU Library General Public License
|
|
|
|
* along with this library; see the file COPYING.LIB. If not, write to
|
|
|
|
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
|
|
|
* Boston, MA 02110-1301, USA.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include "oxygendecohelper.h"
|
|
|
|
|
|
|
|
#include <QtGui/QPainter>
|
2010-08-28 19:58:22 +00:00
|
|
|
#include <KColorUtils>
|
2010-09-16 01:24:56 +00:00
|
|
|
#include <KDebug>
|
|
|
|
|
2010-08-28 19:58:22 +00:00
|
|
|
#include <cmath>
|
2010-05-02 18:50:01 +00:00
|
|
|
|
|
|
|
namespace Oxygen
|
|
|
|
{
|
2010-08-28 19:58:22 +00:00
|
|
|
|
2010-05-02 18:50:01 +00:00
|
|
|
//______________________________________________________________________________
|
|
|
|
DecoHelper::DecoHelper(const QByteArray &componentName):
|
2010-09-16 01:24:56 +00:00
|
|
|
Helper(componentName),
|
2011-02-24 16:08:41 +00:00
|
|
|
_debugArea( KDebug::registerArea( "Oxygen (decoration)" ) )
|
2010-09-16 01:24:56 +00:00
|
|
|
|
2010-08-28 19:58:22 +00:00
|
|
|
{}
|
|
|
|
|
|
|
|
//______________________________________________________________________________
|
|
|
|
void DecoHelper::invalidateCaches( void )
|
|
|
|
{
|
|
|
|
// base class call
|
|
|
|
Helper::invalidateCaches();
|
|
|
|
|
|
|
|
// local caches
|
2011-09-15 19:55:52 +00:00
|
|
|
_windecoButtonCache.clear();
|
2011-02-24 16:08:41 +00:00
|
|
|
_titleBarTextColorCache.clear();
|
2011-04-28 15:28:46 +00:00
|
|
|
_buttonTextColorCache.clear();
|
2010-08-28 19:58:22 +00:00
|
|
|
|
|
|
|
}
|
2010-05-02 18:50:01 +00:00
|
|
|
|
|
|
|
//______________________________________________________________________________
|
2011-09-15 19:55:52 +00:00
|
|
|
QPixmap DecoHelper::windecoButton(const QColor &color, const QColor& glow, bool sunken, int size)
|
2010-05-02 18:50:01 +00:00
|
|
|
{
|
2011-09-15 19:55:52 +00:00
|
|
|
|
|
|
|
Oxygen::Cache<QPixmap>::Value* cache( _windecoButtonCache.get( color ) );
|
|
|
|
|
2012-08-29 12:51:14 +00:00
|
|
|
const quint64 key( ( colorKey(glow) << 32 ) | (sunken << 23 ) | size );
|
2011-09-15 19:55:52 +00:00
|
|
|
QPixmap *pixmap = cache->object( key );
|
2010-05-02 18:50:01 +00:00
|
|
|
|
2010-09-16 01:24:56 +00:00
|
|
|
if( !pixmap )
|
2010-05-02 18:50:01 +00:00
|
|
|
{
|
|
|
|
pixmap = new QPixmap(size, size);
|
|
|
|
pixmap->fill(Qt::transparent);
|
|
|
|
|
2010-09-16 01:24:56 +00:00
|
|
|
QPainter p( pixmap );
|
2010-05-02 18:50:01 +00:00
|
|
|
p.setRenderHints(QPainter::Antialiasing);
|
|
|
|
p.setPen(Qt::NoPen);
|
2011-09-19 13:31:18 +00:00
|
|
|
p.setWindow( 0, 0, 21, 21 );
|
2010-05-02 18:50:01 +00:00
|
|
|
|
2011-09-16 16:31:12 +00:00
|
|
|
// button shadow
|
|
|
|
if( color.isValid() )
|
|
|
|
{
|
|
|
|
p.save();
|
2011-09-20 07:14:24 +00:00
|
|
|
p.translate( 0, -1.4 );
|
|
|
|
drawShadow( p, calcShadowColor( color ), 21 );
|
2011-09-16 16:31:12 +00:00
|
|
|
p.restore();
|
|
|
|
}
|
|
|
|
|
2011-09-15 19:55:52 +00:00
|
|
|
// button glow
|
|
|
|
if( glow.isValid() )
|
2010-05-02 18:50:01 +00:00
|
|
|
{
|
2011-09-16 15:49:45 +00:00
|
|
|
p.save();
|
2011-09-19 14:23:29 +00:00
|
|
|
p.translate( 0, -1.4 );
|
2011-09-19 13:31:18 +00:00
|
|
|
drawOuterGlow( p, glow, 21 );
|
2011-09-16 15:49:45 +00:00
|
|
|
p.restore();
|
2010-05-02 18:50:01 +00:00
|
|
|
}
|
|
|
|
|
2011-09-15 19:55:52 +00:00
|
|
|
// button slab
|
2011-09-19 13:31:18 +00:00
|
|
|
p.setWindow( 0, 0, 18, 18 );
|
2011-09-15 19:55:52 +00:00
|
|
|
if( color.isValid() )
|
2010-05-02 18:50:01 +00:00
|
|
|
{
|
2011-09-16 15:49:45 +00:00
|
|
|
p.translate( 0, (0.5-0.668) );
|
2010-05-02 18:50:01 +00:00
|
|
|
|
2011-09-15 19:55:52 +00:00
|
|
|
const QColor light( calcLightColor(color) );
|
|
|
|
const QColor dark( calcDarkColor(color) );
|
2010-05-02 18:50:01 +00:00
|
|
|
|
2011-09-15 19:55:52 +00:00
|
|
|
{
|
|
|
|
//plain background
|
2011-09-16 15:19:02 +00:00
|
|
|
QLinearGradient lg( 0, 1.665, 0, (12.33+1.665) );
|
2011-09-15 19:55:52 +00:00
|
|
|
if( sunken )
|
|
|
|
{
|
|
|
|
lg.setColorAt( 1, light );
|
|
|
|
lg.setColorAt( 0, dark );
|
|
|
|
} else {
|
|
|
|
lg.setColorAt( 0, light );
|
|
|
|
lg.setColorAt( 1, dark );
|
|
|
|
}
|
|
|
|
|
2011-09-16 15:49:45 +00:00
|
|
|
const QRectF r( 0.5*(18-12.33), 1.665, 12.33, 12.33 );
|
2011-09-15 19:55:52 +00:00
|
|
|
p.setBrush( lg );
|
|
|
|
p.drawEllipse( r );
|
|
|
|
}
|
2010-05-02 18:50:01 +00:00
|
|
|
|
2011-09-15 19:55:52 +00:00
|
|
|
{
|
|
|
|
// outline circle
|
|
|
|
const qreal penWidth( 0.7 );
|
2011-09-16 15:19:02 +00:00
|
|
|
QLinearGradient lg( 0, 1.665, 0, (2.0*12.33+1.665) );
|
2011-09-15 19:55:52 +00:00
|
|
|
lg.setColorAt( 0, light );
|
|
|
|
lg.setColorAt( 1, dark );
|
2011-09-16 15:49:45 +00:00
|
|
|
const QRectF r( 0.5*(18-12.33+penWidth), (1.665+penWidth), (12.33-penWidth), (12.33-penWidth) );
|
2011-09-16 15:19:02 +00:00
|
|
|
p.setPen( QPen( lg, penWidth ) );
|
2011-09-15 19:55:52 +00:00
|
|
|
p.setBrush( Qt::NoBrush );
|
|
|
|
p.drawEllipse( r );
|
|
|
|
}
|
2010-05-02 18:50:01 +00:00
|
|
|
|
|
|
|
}
|
|
|
|
|
2011-09-15 19:55:52 +00:00
|
|
|
p.end();
|
|
|
|
cache->insert( key, pixmap );
|
2010-05-02 18:50:01 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return *pixmap;
|
|
|
|
}
|
2010-05-10 01:56:24 +00:00
|
|
|
|
|
|
|
//_______________________________________________________________________
|
|
|
|
QRegion DecoHelper::decoRoundedMask( const QRect& r, int left, int right, int top, int bottom ) const
|
|
|
|
{
|
|
|
|
// get rect geometry
|
|
|
|
int x, y, w, h;
|
|
|
|
r.getRect(&x, &y, &w, &h);
|
|
|
|
|
|
|
|
QRegion mask(x + 3*left, y + 0*top, w-3*(left+right), h-0*(top+bottom));
|
|
|
|
mask += QRegion(x + 0*left, y + 3*top, w-0*(left+right), h-3*(top+bottom));
|
|
|
|
mask += QRegion(x + 1*left, y + 1*top, w-1*(left+right), h-1*(top+bottom));
|
|
|
|
|
|
|
|
return mask;
|
|
|
|
}
|
2010-08-28 19:58:22 +00:00
|
|
|
|
|
|
|
//______________________________________________________________________________
|
|
|
|
const QColor& DecoHelper::inactiveTitleBarTextColor( const QPalette& palette )
|
|
|
|
{
|
|
|
|
|
2012-08-29 12:51:14 +00:00
|
|
|
const quint32 key( colorKey( palette.color(QPalette::Active, QPalette::Window) ) );
|
2011-02-24 16:08:41 +00:00
|
|
|
QColor* out( _titleBarTextColorCache.object( key ) );
|
2010-08-28 19:58:22 +00:00
|
|
|
if( !out )
|
|
|
|
{
|
|
|
|
|
|
|
|
// todo: reimplement cache
|
|
|
|
const QColor ab = palette.color(QPalette::Active, QPalette::Window);
|
|
|
|
const QColor af = palette.color(QPalette::Active, QPalette::WindowText);
|
|
|
|
const QColor nb = palette.color(QPalette::Inactive, QPalette::Window);
|
|
|
|
const QColor nf = palette.color(QPalette::Inactive, QPalette::WindowText);
|
|
|
|
out = new QColor( reduceContrast(nb, nf, qMax(qreal(2.5), KColorUtils::contrastRatio(ab, KColorUtils::mix(ab, af, 0.4)))) );
|
2011-02-24 16:08:41 +00:00
|
|
|
_titleBarTextColorCache.insert( key, out );
|
2010-08-28 19:58:22 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return *out;
|
|
|
|
}
|
|
|
|
|
2011-04-28 15:28:46 +00:00
|
|
|
|
|
|
|
//______________________________________________________________________________
|
|
|
|
const QColor& DecoHelper::inactiveButtonTextColor( const QPalette& palette )
|
|
|
|
{
|
|
|
|
|
2012-08-29 12:51:14 +00:00
|
|
|
const quint32 key( colorKey( palette.color(QPalette::Active, QPalette::Window) ) );
|
2011-04-28 15:28:46 +00:00
|
|
|
QColor* out( _buttonTextColorCache.object( key ) );
|
|
|
|
if( !out )
|
|
|
|
{
|
|
|
|
|
|
|
|
// todo: reimplement cache
|
|
|
|
const QColor ab = palette.color(QPalette::Active, QPalette::Button);
|
|
|
|
const QColor af = palette.color(QPalette::Active, QPalette::ButtonText);
|
|
|
|
const QColor nb = palette.color(QPalette::Inactive, QPalette::Button);
|
|
|
|
const QColor nf = palette.color(QPalette::Inactive, QPalette::ButtonText);
|
|
|
|
out = new QColor( reduceContrast(nb, nf, qMax(qreal(2.5), KColorUtils::contrastRatio(ab, KColorUtils::mix(ab, af, 0.4)))) );
|
|
|
|
_buttonTextColorCache.insert( key, out );
|
|
|
|
}
|
|
|
|
|
|
|
|
return *out;
|
|
|
|
}
|
|
|
|
|
2010-08-28 19:58:22 +00:00
|
|
|
//_________________________________________________________
|
|
|
|
QColor DecoHelper::reduceContrast(const QColor &c0, const QColor &c1, double t) const
|
|
|
|
{
|
|
|
|
const double s( KColorUtils::contrastRatio(c0, c1) );
|
2010-09-16 01:24:56 +00:00
|
|
|
if( s < t ) return c1;
|
2010-08-28 19:58:22 +00:00
|
|
|
|
|
|
|
double l(0);
|
|
|
|
double h(1.0);
|
|
|
|
double x(s);
|
|
|
|
double a;
|
|
|
|
QColor r( c1 );
|
|
|
|
for (int maxiter = 16; maxiter; --maxiter)
|
|
|
|
{
|
|
|
|
|
|
|
|
a = 0.5 * (l + h);
|
|
|
|
r = KColorUtils::mix(c0, c1, a);
|
|
|
|
x = KColorUtils::contrastRatio(c0, r);
|
|
|
|
|
2010-09-16 01:24:56 +00:00
|
|
|
if ( std::abs(x - t) < 0.01) break;
|
2010-08-28 19:58:22 +00:00
|
|
|
if (x > t) h = a;
|
|
|
|
else l = a;
|
|
|
|
}
|
|
|
|
|
|
|
|
return r;
|
|
|
|
}
|
|
|
|
|
2010-05-02 18:50:01 +00:00
|
|
|
}
|