2
* KMix -- KDE's full featured mini mixer
5
* Copyright (C) 2000 Stefan Schimanski <1Stein@gmx.de>
7
* This program is free software; you can redistribute it and/or
8
* modify it under the terms of the GNU Library General Public
9
* License as published by the Free Software Foundation; either
10
* version 2 of the License, or (at your option) any later version.
12
* This program is distributed in the hope that it will be useful,
13
* but WITHOUT ANY WARRANTY; without even the implied warranty of
14
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15
* Library General Public License for more details.
17
* You should have received a copy of the GNU Library General Public
18
* License along with this program; if not, write to the Free
19
* Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
31
#include <QMouseEvent>
33
#include <QStyleOptionSlider>
35
#include "kglobalsettings.h"
36
#include "ksmallslider.h"
38
KSmallSlider::KSmallSlider( int minValue, int maxValue, int pageStep,
39
int value, Qt::Orientation orientation,
40
QWidget *parent, const char * /*name*/ )
41
: QAbstractSlider( parent )
44
setOrientation(orientation);
45
setRange(minValue, maxValue);
47
setPageStep(pageStep);
52
void KSmallSlider::init()
55
setFocusPolicy( Qt::TabFocus );
57
colHigh = QColor(0,255,0);
58
colLow = QColor(255,0,0);
59
colBack = QColor(0,0,0);
61
grayHigh = QColor(255,255,255);
62
grayLow = QColor(128,128,128);
63
grayBack = QColor(0,0,0);
66
int KSmallSlider::positionFromValue( int v ) const
68
return positionFromValue( v, available() );
71
int KSmallSlider::valueFromPosition( int p ) const
73
if ( orientation() == Qt::Vertical ) {
74
// Coordiante System starts at TopLeft, but the slider values increase from Bottom to Top
75
// Thus "revert" the position
76
int avail = available();
77
return valueFromPosition( avail - p, avail );
80
// Horizontal everything is fine. Slider values match with Coordinate System
81
return valueFromPosition( p, available() );
85
/* postionFromValue() discontinued in in Qt4 => taken from Qt3 */
86
int KSmallSlider::positionFromValue( int logical_val, int span ) const
88
if ( span <= 0 || logical_val < minimum() || maximum() <= minimum() )
90
if ( logical_val > maximum() )
93
uint range = maximum() - minimum();
94
uint p = logical_val - minimum();
96
if ( range > (uint)INT_MAX/4096 ) {
97
const int scale = 4096*2;
98
return ( (p/scale) * span ) / (range/scale);
99
// ### the above line is probably not 100% correct
100
// ### but fixing it isn't worth the extreme pain...
101
} else if ( range > (uint)span ) {
102
return (2*p*span + range) / (2*range);
104
uint div = span / range;
105
uint mod = span % range;
106
return p*div + (2*p*mod + range) / (2*range);
108
//equiv. to (p*span)/range + 0.5
109
// no overflow because of this implicit assumption:
113
/* valueFromPositon() discontinued in in Qt4 => taken from Qt3 */
114
int KSmallSlider::valueFromPosition( int pos, int span ) const
116
if ( span <= 0 || pos <= 0 )
121
uint range = maximum() - minimum();
123
if ( (uint)span > range )
124
return minimum() + (2*pos*range + span) / (2*span);
126
uint div = range / span;
127
uint mod = range % span;
128
return minimum() + pos*div + (2*pos*mod + span) / (2*span);
130
// equiv. to minimum() + (pos*range)/span + 0.5
131
// no overflow because of this implicit assumption:
132
// pos <= span < sqrt(INT_MAX+0.0625)+0.25 ~ sqrt(INT_MAX)
136
void KSmallSlider::resizeEvent( QResizeEvent * )
139
//QWidget::resizeEvent( ev );
142
// Returns the really available space for the slider. If there is no space, 0 is returned;
143
int KSmallSlider::available() const
146
if ( orientation() == Qt::Vertical) {
147
available = height();
152
if ( available > 1 ) {
166
void gradient( QPainter &p, bool hor, const QRect &rect, const QColor &ca, const QColor &cb, int /*ncols*/)
168
int rDiff, gDiff, bDiff;
169
int rca, gca, bca, rcb, gcb, bcb;
173
if ((rect.width()<=0) || (rect.height()<=0)) return;
175
rDiff = (rcb = cb.red()) - (rca = ca.red());
176
gDiff = (gcb = cb.green()) - (gca = ca.green());
177
bDiff = (bcb = cb.blue()) - (bca = ca.blue());
179
register int rl = rca << 16;
180
register int gl = gca << 16;
181
register int bl = bca << 16;
183
int rcdelta = ((1<<16) / ((!hor) ? rect.height() : rect.width())) * rDiff;
184
int gcdelta = ((1<<16) / ((!hor) ? rect.height() : rect.width())) * gDiff;
185
int bcdelta = ((1<<16) / ((!hor) ? rect.height() : rect.width())) * bDiff;
187
// these for-loops could be merged, but the if's in the inner loop
188
// would make it slow
191
for ( y = rect.top(); y <= rect.bottom(); y++ ) {
196
p.setPen(QColor(rl>>16, gl>>16, bl>>16));
197
p.drawLine(rect.left(), y, rect.right(), y);
201
for( x = rect.left(); x <= rect.right(); x++) {
206
p.setPen(QColor(rl>>16, gl>>16, bl>>16));
207
p.drawLine(x, rect.top(), x, rect.bottom());
212
QColor interpolate( const QColor& low, const QColor& high, int percent ) {
213
if ( percent<=0 ) return low; else
214
if ( percent>=100 ) return high; else
216
low.red() + (high.red()-low.red()) * percent/100,
217
low.green() + (high.green()-low.green()) * percent/100,
218
low.blue() + (high.blue()-low.blue()) * percent/100 );
223
void KSmallSlider::paintEvent( QPaintEvent * )
225
// kDebug(67100) << "KSmallSlider::paintEvent: width() = " << width() << ", height() = " << height();
228
int sliderPos = positionFromValue( QAbstractSlider::value() );
230
// ------------------------ draw 3d border ---------------------------------------------
231
QStyleOptionSlider option;
233
style()->drawPrimitive ( QStyle::PE_Frame, &option, &p );
236
// ------------------------ draw lower/left part ----------------------------------------
237
if ( width()>2 && height()>2 )
239
if ( orientation() == Qt::Horizontal ) {
240
QRect outer = QRect( 1, 1, sliderPos, height() - 2 );
241
// kDebug(67100) << "KSmallSlider::paintEvent: outer = " << outer;
244
gradient( p, true, outer, grayLow,
245
interpolate( grayLow, grayHigh, 100*sliderPos/(width()-2) ),
248
gradient( p, true, outer, colLow,
249
interpolate( colLow, colHigh, 100*sliderPos/(width()-2) ),
253
QRect outer = QRect( 1, height()-sliderPos-1, width() - 2, sliderPos-1 );
255
kDebug(67100) << "KSmallSlider::paintEvent: sliderPos=" << sliderPos
256
<< "height()=" << height()
257
<< "width()=" << width()
258
<< "outer = " << outer << endl;
261
gradient( p, false, outer,
262
interpolate( grayLow, grayHigh, 100*sliderPos/(height()-2) ),
265
gradient( p, false, outer,
266
interpolate( colLow, colHigh, 100*sliderPos/(height()-2) ),
270
// -------- draw upper/right part --------------------------------------------------
272
if ( orientation() == Qt::Vertical ) {
273
inner = QRect( 1, 1, width() - 2, height() - 2 -sliderPos );
276
inner = QRect( sliderPos + 1, 1, width() - 2 - sliderPos, height() - 2 );
280
p.setBrush( grayBack );
281
p.setPen( grayBack );
283
p.setBrush( colBack );
290
void KSmallSlider::mousePressEvent( QMouseEvent *e )
294
if ( e->button() == Qt::RightButton ) {
298
int pos = goodPart( e->pos() );
302
void KSmallSlider::mouseMoveEvent( QMouseEvent *e )
304
int pos = goodPart( e->pos() );
309
void KSmallSlider::wheelEvent( QWheelEvent * e)
311
// kDebug(67100) << "KSmallslider::wheelEvent()";
312
int inc = ( maximum() - minimum() ) / 20;
316
//kDebug(67100) << "KSmallslider::wheelEvent() inc=" << inc << "delta=" << e->delta();
317
if ( e->delta() > 0 ) {
318
setValue( QAbstractSlider::value() + inc );
321
setValue( QAbstractSlider::value() - inc );
323
e->accept(); // Accept the event
325
// Hint: Qt autmatically triggers a valueChange() when we do setValue()
331
* Moves slider to a dedicated position. If the value has changed
333
void KSmallSlider::moveSlider( int pos )
336
int newPos = qMin( a, qMax( 0, pos ) ); // keep it inside the available bounds of the slider
337
int newVal = valueFromPosition( newPos );
339
if ( newVal != value() ) {
341
// probably done by Qt: emit valueChanged( value() ); // Only for external use
342
// probably we need update() here
348
int KSmallSlider::goodPart( const QPoint &p ) const
350
if ( orientation() == Qt::Vertical ) {
358
/***************** SIZE STUFF START ***************/
359
QSize KSmallSlider::sizeHint() const
362
const int length = 25;
363
const int thick = 10;
365
if ( orientation() == Qt::Vertical )
366
return QSize( thick, length );
368
return QSize( length, thick );
372
QSize KSmallSlider::minimumSizeHint() const
379
QSizePolicy KSmallSlider::sizePolicy() const
382
if ( orientation() == Qt::Vertical ) {
383
//kDebug(67100) << "KSmallSlider::sizePolicy() vertical value=(Fixed,MinimumExpanding)\n";
384
return QSizePolicy( QSizePolicy::Fixed, QSizePolicy::Expanding );
387
//kDebug(67100) << "KSmallSlider::sizePolicy() horizontal value=(MinimumExpanding,Fixed)\n";
388
return QSizePolicy( QSizePolicy::Expanding, QSizePolicy::Fixed );
391
/***************** SIZE STUFF END ***************/
395
void KSmallSlider::setGray( bool value )
405
bool KSmallSlider::gray() const
410
void KSmallSlider::setColors( QColor high, QColor low, QColor back )
419
void KSmallSlider::setGrayColors( QColor high, QColor low, QColor back )
428
#include "ksmallslider.moc"