mirror of
https://bitbucket.org/smil3y/kdelibs.git
synced 2025-02-24 10:52:49 +00:00
446 lines
11 KiB
C++
446 lines
11 KiB
C++
![]() |
/* This file is part of the KDE libraries
|
||
|
Copyright (C) 1997 Martin Jones (mjones@kde.org)
|
||
|
|
||
|
This library is free software; you can redistribute it and/or
|
||
|
modify it under the terms of the GNU Library General Public
|
||
|
License as published by the Free Software Foundation; either
|
||
|
version 2 of the License, or (at your option) any later version.
|
||
|
|
||
|
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 "kselector.h"
|
||
|
|
||
|
#include <QImage>
|
||
|
#include <QPainter>
|
||
|
#include <QPaintEvent>
|
||
|
#include <QPixmap>
|
||
|
#include <QStyle>
|
||
|
#include <QStyleOption>
|
||
|
|
||
|
#include "kcolorhelpers_p.h"
|
||
|
|
||
|
using KDEPrivate::fillOpaqueRect;
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
/*
|
||
|
* 1D value selector with contents drawn by derived class.
|
||
|
* See KColorDialog for example.
|
||
|
*/
|
||
|
|
||
|
#define ARROWSIZE 5
|
||
|
|
||
|
class KSelector::Private
|
||
|
{
|
||
|
public:
|
||
|
Private()
|
||
|
{
|
||
|
arrowPE = QStyle::PE_IndicatorArrowLeft;
|
||
|
m_indent = true;
|
||
|
}
|
||
|
|
||
|
bool m_indent;
|
||
|
QStyle::PrimitiveElement arrowPE;
|
||
|
};
|
||
|
|
||
|
class KGradientSelector::KGradientSelectorPrivate
|
||
|
{
|
||
|
public:
|
||
|
KGradientSelectorPrivate(KGradientSelector *q): q(q) {}
|
||
|
|
||
|
KGradientSelector *q;
|
||
|
QLinearGradient gradient;
|
||
|
QString text1;
|
||
|
QString text2;
|
||
|
};
|
||
|
|
||
|
KSelector::KSelector( QWidget *parent )
|
||
|
: QAbstractSlider( parent )
|
||
|
, d(new Private)
|
||
|
{
|
||
|
setOrientation(Qt::Horizontal);
|
||
|
}
|
||
|
|
||
|
KSelector::KSelector( Qt::Orientation o, QWidget *parent )
|
||
|
: QAbstractSlider( parent )
|
||
|
, d(new Private)
|
||
|
{
|
||
|
setOrientation(o);
|
||
|
if(o == Qt::Horizontal)
|
||
|
setArrowDirection(Qt::UpArrow);
|
||
|
}
|
||
|
|
||
|
KSelector::~KSelector()
|
||
|
{
|
||
|
delete d;
|
||
|
}
|
||
|
|
||
|
void KSelector::setIndent( bool i )
|
||
|
{
|
||
|
d->m_indent = i;
|
||
|
}
|
||
|
|
||
|
bool KSelector::indent() const
|
||
|
{
|
||
|
return d->m_indent;
|
||
|
}
|
||
|
|
||
|
QRect KSelector::contentsRect() const
|
||
|
{
|
||
|
int w = indent() ? style()->pixelMetric( QStyle::PM_DefaultFrameWidth ) : 0;
|
||
|
//TODO: is the height:width ratio of an indicator arrow always 2:1? hm.
|
||
|
int iw = (w < ARROWSIZE) ? ARROWSIZE : w;
|
||
|
|
||
|
if ( orientation() == Qt::Vertical ) {
|
||
|
if ( arrowDirection() == Qt::RightArrow ) {
|
||
|
return QRect( w + ARROWSIZE, iw,
|
||
|
width() - w*2 - ARROWSIZE,
|
||
|
height() - iw*2 );
|
||
|
} else {
|
||
|
return QRect( w, iw,
|
||
|
width() - w*2 - ARROWSIZE,
|
||
|
height() - iw*2 );
|
||
|
}
|
||
|
} else { // Qt::Horizontal
|
||
|
if ( arrowDirection() == Qt::UpArrow ) {
|
||
|
return QRect( iw, w,
|
||
|
width() - 2*iw,
|
||
|
height() - w*2 - ARROWSIZE );
|
||
|
} else {
|
||
|
return QRect( iw, w + ARROWSIZE,
|
||
|
width() - 2*iw,
|
||
|
height() - w*2 - ARROWSIZE );
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void KSelector::paintEvent( QPaintEvent * )
|
||
|
{
|
||
|
QPainter painter;
|
||
|
int w = style()->pixelMetric( QStyle::PM_DefaultFrameWidth );
|
||
|
int iw = (w < ARROWSIZE) ? ARROWSIZE : w;
|
||
|
|
||
|
painter.begin( this );
|
||
|
|
||
|
drawContents( &painter );
|
||
|
|
||
|
QBrush brush;
|
||
|
|
||
|
QPoint pos = calcArrowPos( value() );
|
||
|
drawArrow( &painter, pos );
|
||
|
|
||
|
if ( indent() )
|
||
|
{
|
||
|
QStyleOptionFrame opt;
|
||
|
opt.initFrom( this );
|
||
|
opt.state = QStyle::State_Sunken;
|
||
|
if ( orientation() == Qt::Vertical )
|
||
|
opt.rect.adjust( 0, iw - w, -5, w - iw );
|
||
|
else
|
||
|
opt.rect.adjust(iw - w, 0, w - iw, -5);
|
||
|
QBrush oldBrush = painter.brush();
|
||
|
painter.setBrush( Qt::NoBrush );
|
||
|
style()->drawPrimitive( QStyle::PE_Frame, &opt, &painter, this );
|
||
|
painter.setBrush( oldBrush );
|
||
|
}
|
||
|
|
||
|
|
||
|
painter.end();
|
||
|
}
|
||
|
|
||
|
void KSelector::mousePressEvent( QMouseEvent *e )
|
||
|
{
|
||
|
setSliderDown(true);
|
||
|
moveArrow( e->pos() );
|
||
|
}
|
||
|
|
||
|
void KSelector::mouseMoveEvent( QMouseEvent *e )
|
||
|
{
|
||
|
moveArrow( e->pos() );
|
||
|
}
|
||
|
|
||
|
void KSelector::mouseReleaseEvent( QMouseEvent *e )
|
||
|
{
|
||
|
moveArrow( e->pos() );
|
||
|
setSliderDown(false);
|
||
|
}
|
||
|
|
||
|
void KSelector::wheelEvent( QWheelEvent *e )
|
||
|
{
|
||
|
int val = value() + e->delta()/120;
|
||
|
setSliderDown(true);
|
||
|
setValue( val );
|
||
|
setSliderDown(false);
|
||
|
}
|
||
|
|
||
|
void KSelector::moveArrow( const QPoint &pos )
|
||
|
{
|
||
|
int val;
|
||
|
int w = style()->pixelMetric(QStyle::PM_DefaultFrameWidth);
|
||
|
int iw = (w < ARROWSIZE) ? ARROWSIZE : w;
|
||
|
|
||
|
if ( orientation() == Qt::Vertical )
|
||
|
val = ( maximum() - minimum() ) * (height() - pos.y() - iw)
|
||
|
/ (height() - iw * 2) + minimum();
|
||
|
else
|
||
|
val = ( maximum() - minimum() ) * ( pos.x() - iw)
|
||
|
/ (width() - iw * 2) + minimum();
|
||
|
|
||
|
setValue( val );
|
||
|
update();
|
||
|
}
|
||
|
|
||
|
QPoint KSelector::calcArrowPos( int val )
|
||
|
{
|
||
|
QPoint p;
|
||
|
int w = style()->pixelMetric( QStyle::PM_DefaultFrameWidth );
|
||
|
int iw = ( w < ARROWSIZE ) ? ARROWSIZE : w;
|
||
|
|
||
|
if ( orientation() == Qt::Vertical )
|
||
|
{
|
||
|
p.setY( height() - iw - 1 - (height() - 2 * iw - 1) * val / ( maximum() - minimum() ) );
|
||
|
|
||
|
if ( d->arrowPE == QStyle::PE_IndicatorArrowRight ) {
|
||
|
p.setX( 0 );
|
||
|
} else {
|
||
|
p.setX( width() - 5 );
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
p.setX( iw + (width() - 2 * iw - 1) * val / ( maximum() - minimum() ) );
|
||
|
|
||
|
if ( d->arrowPE == QStyle::PE_IndicatorArrowDown ) {
|
||
|
p.setY( 0 );
|
||
|
} else {
|
||
|
p.setY( height() - 5 );
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return p;
|
||
|
}
|
||
|
|
||
|
void KSelector::setArrowDirection( Qt::ArrowType direction )
|
||
|
{
|
||
|
switch ( direction ) {
|
||
|
case Qt::UpArrow:
|
||
|
if ( orientation() == Qt::Horizontal ) {
|
||
|
d->arrowPE = QStyle::PE_IndicatorArrowUp;
|
||
|
} else {
|
||
|
d->arrowPE = QStyle::PE_IndicatorArrowLeft;
|
||
|
}
|
||
|
break;
|
||
|
case Qt::DownArrow:
|
||
|
if ( orientation() == Qt::Horizontal ) {
|
||
|
d->arrowPE = QStyle::PE_IndicatorArrowDown;
|
||
|
} else {
|
||
|
d->arrowPE = QStyle::PE_IndicatorArrowRight;
|
||
|
}
|
||
|
break;
|
||
|
case Qt::LeftArrow:
|
||
|
if ( orientation() == Qt::Vertical ) {
|
||
|
d->arrowPE = QStyle::PE_IndicatorArrowLeft;
|
||
|
} else {
|
||
|
d->arrowPE = QStyle::PE_IndicatorArrowDown;
|
||
|
}
|
||
|
break;
|
||
|
case Qt::RightArrow:
|
||
|
if ( orientation() == Qt::Vertical ) {
|
||
|
d->arrowPE = QStyle::PE_IndicatorArrowRight;
|
||
|
} else {
|
||
|
d->arrowPE = QStyle::PE_IndicatorArrowUp;
|
||
|
}
|
||
|
break;
|
||
|
|
||
|
case Qt::NoArrow:
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
Qt::ArrowType KSelector::arrowDirection() const
|
||
|
{
|
||
|
switch ( d->arrowPE ) {
|
||
|
case QStyle::PE_IndicatorArrowUp:
|
||
|
return Qt::UpArrow;
|
||
|
break;
|
||
|
case QStyle::PE_IndicatorArrowDown:
|
||
|
return Qt::DownArrow;
|
||
|
break;
|
||
|
case QStyle::PE_IndicatorArrowRight:
|
||
|
return Qt::RightArrow;
|
||
|
break;
|
||
|
case QStyle::PE_IndicatorArrowLeft:
|
||
|
default:
|
||
|
return Qt::LeftArrow;
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void KSelector::drawContents( QPainter * )
|
||
|
{}
|
||
|
|
||
|
void KSelector::drawArrow( QPainter *painter, const QPoint &pos )
|
||
|
{
|
||
|
painter->setPen( QPen() );
|
||
|
painter->setBrush( QBrush( palette().color(QPalette::ButtonText) ) );
|
||
|
|
||
|
QStyleOption o;
|
||
|
|
||
|
if ( orientation() == Qt::Vertical ) {
|
||
|
o.rect = QRect( pos.x(), pos.y() - ARROWSIZE / 2,
|
||
|
ARROWSIZE, ARROWSIZE );
|
||
|
} else {
|
||
|
o.rect = QRect( pos.x() - ARROWSIZE / 2, pos.y(),
|
||
|
ARROWSIZE, ARROWSIZE );
|
||
|
|
||
|
}
|
||
|
style()->drawPrimitive( d->arrowPE, &o, painter, this );
|
||
|
}
|
||
|
|
||
|
//----------------------------------------------------------------------------
|
||
|
|
||
|
KGradientSelector::KGradientSelector( QWidget *parent )
|
||
|
: KSelector( parent ), d(new KGradientSelectorPrivate(this))
|
||
|
{
|
||
|
}
|
||
|
|
||
|
|
||
|
KGradientSelector::KGradientSelector( Qt::Orientation o, QWidget *parent )
|
||
|
: KSelector( o, parent ), d(new KGradientSelectorPrivate(this))
|
||
|
{
|
||
|
}
|
||
|
|
||
|
|
||
|
KGradientSelector::~KGradientSelector()
|
||
|
{
|
||
|
delete d;
|
||
|
}
|
||
|
|
||
|
|
||
|
void KGradientSelector::drawContents( QPainter *painter )
|
||
|
{
|
||
|
d->gradient.setStart(contentsRect().topLeft());
|
||
|
if (orientation() == Qt::Vertical) {
|
||
|
d->gradient.setFinalStop(contentsRect().bottomLeft());
|
||
|
} else {
|
||
|
d->gradient.setFinalStop(contentsRect().topRight());
|
||
|
}
|
||
|
QBrush gradientBrush(d->gradient);
|
||
|
|
||
|
fillOpaqueRect(painter, contentsRect(), gradientBrush);
|
||
|
|
||
|
if ( orientation() == Qt::Vertical )
|
||
|
{
|
||
|
int yPos = contentsRect().top() + painter->fontMetrics().ascent() + 2;
|
||
|
int xPos = contentsRect().left() + (contentsRect().width() -
|
||
|
painter->fontMetrics().width( d->text2 )) / 2;
|
||
|
QPen pen( qGray(firstColor().rgb()) > 180 ? Qt::black : Qt::white );
|
||
|
painter->setPen( pen );
|
||
|
painter->drawText( xPos, yPos, d->text2 );
|
||
|
|
||
|
yPos = contentsRect().bottom() - painter->fontMetrics().descent() - 2;
|
||
|
xPos = contentsRect().left() + (contentsRect().width() -
|
||
|
painter->fontMetrics().width( d->text1 )) / 2;
|
||
|
pen.setColor( qGray(secondColor().rgb()) > 180 ? Qt::black : Qt::white );
|
||
|
painter->setPen( pen );
|
||
|
painter->drawText( xPos, yPos, d->text1 );
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
int yPos = contentsRect().bottom()-painter->fontMetrics().descent()-2;
|
||
|
|
||
|
QPen pen( qGray(firstColor().rgb()) > 180 ? Qt::black : Qt::white );
|
||
|
painter->setPen( pen );
|
||
|
painter->drawText( contentsRect().left() + 2, yPos, d->text1 );
|
||
|
|
||
|
pen.setColor( qGray(secondColor().rgb()) > 180 ? Qt::black : Qt::white );
|
||
|
painter->setPen( pen );
|
||
|
painter->drawText( contentsRect().right() -
|
||
|
painter->fontMetrics().width( d->text2 ) - 2, yPos, d->text2 );
|
||
|
}
|
||
|
}
|
||
|
|
||
|
QSize KGradientSelector::minimumSize() const
|
||
|
{
|
||
|
return sizeHint();
|
||
|
}
|
||
|
|
||
|
void KGradientSelector::setStops( const QGradientStops &stops )
|
||
|
{
|
||
|
d->gradient.setStops(stops);
|
||
|
update();
|
||
|
}
|
||
|
|
||
|
QGradientStops KGradientSelector::stops() const
|
||
|
{
|
||
|
return d->gradient.stops();
|
||
|
}
|
||
|
|
||
|
void KGradientSelector::setColors( const QColor &col1, const QColor &col2 )
|
||
|
{
|
||
|
d->gradient.setColorAt(0.0, col1);
|
||
|
d->gradient.setColorAt(1.0, col2);
|
||
|
update();
|
||
|
}
|
||
|
|
||
|
void KGradientSelector::setText( const QString &t1, const QString &t2 )
|
||
|
{
|
||
|
d->text1 = t1;
|
||
|
d->text2 = t2;
|
||
|
update();
|
||
|
}
|
||
|
|
||
|
void KGradientSelector::setFirstColor( const QColor &col )
|
||
|
{
|
||
|
d->gradient.setColorAt(0.0, col);
|
||
|
update();
|
||
|
}
|
||
|
|
||
|
void KGradientSelector::setSecondColor( const QColor &col )
|
||
|
{
|
||
|
d->gradient.setColorAt(1.0, col);
|
||
|
update();
|
||
|
}
|
||
|
|
||
|
void KGradientSelector::setFirstText( const QString &t )
|
||
|
{
|
||
|
d->text1 = t;
|
||
|
update();
|
||
|
}
|
||
|
|
||
|
void KGradientSelector::setSecondText( const QString &t )
|
||
|
{
|
||
|
d->text2 = t;
|
||
|
update();
|
||
|
}
|
||
|
|
||
|
QColor KGradientSelector::firstColor() const
|
||
|
{
|
||
|
return d->gradient.stops().first().second;
|
||
|
}
|
||
|
|
||
|
QColor KGradientSelector::secondColor() const
|
||
|
{
|
||
|
return d->gradient.stops().last().second;
|
||
|
}
|
||
|
|
||
|
QString KGradientSelector::firstText() const
|
||
|
{
|
||
|
return d->text1;
|
||
|
}
|
||
|
|
||
|
QString KGradientSelector::secondText() const
|
||
|
{
|
||
|
return d->text2;
|
||
|
}
|
||
|
|
||
|
#include "kselector.moc"
|