~ubuntu-branches/ubuntu/natty/kdemultimedia/natty-proposed

« back to all changes in this revision

Viewing changes to kmix/ksmallslider.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Debian Qt/KDE Maintainers
  • Date: 2011-05-26 02:41:36 UTC
  • mfrom: (0.2.3 upstream)
  • mto: This revision was merged to the branch mainline in revision 108.
  • Revision ID: james.westby@ubuntu.com-20110526024136-jjwsigfy402jhupm
Tags: upstream-4.6.3
ImportĀ upstreamĀ versionĀ 4.6.3

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/*
2
 
 * KMix -- KDE's full featured mini mixer
3
 
 *
4
 
 *
5
 
 * Copyright (C) 2000 Stefan Schimanski <1Stein@gmx.de>
6
 
 *
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.
11
 
 *
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.
16
 
 *
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.
20
 
 */
21
 
 
22
 
// For INT_MAX
23
 
#include <limits.h>
24
 
 
25
 
#include <kdebug.h>
26
 
 
27
 
#include <QWidget>
28
 
#include <qpainter.h>
29
 
#include <QColor>
30
 
#include <qbrush.h>
31
 
#include <QMouseEvent>
32
 
#include <qstyle.h>
33
 
#include <QStyleOptionSlider>
34
 
 
35
 
#include "kglobalsettings.h"
36
 
#include "ksmallslider.h"
37
 
 
38
 
KSmallSlider::KSmallSlider( int minValue, int maxValue, int pageStep,
39
 
                  int value, Qt::Orientation orientation,
40
 
                  QWidget *parent, const char * /*name*/ )
41
 
    : QAbstractSlider( parent )
42
 
{
43
 
    init();
44
 
    setOrientation(orientation);
45
 
    setRange(minValue, maxValue);
46
 
    setSingleStep(1);
47
 
    setPageStep(pageStep);
48
 
    setValue(value);
49
 
         setTracking(true);
50
 
}
51
 
 
52
 
void KSmallSlider::init()
53
 
{
54
 
    grayed = false;
55
 
    setFocusPolicy( Qt::TabFocus  );
56
 
 
57
 
    colHigh = QColor(0,255,0);
58
 
    colLow = QColor(255,0,0);
59
 
    colBack = QColor(0,0,0);
60
 
 
61
 
    grayHigh = QColor(255,255,255);
62
 
    grayLow = QColor(128,128,128);
63
 
    grayBack = QColor(0,0,0);
64
 
}
65
 
 
66
 
int KSmallSlider::positionFromValue( int v ) const
67
 
{
68
 
    return positionFromValue( v, available() );
69
 
}
70
 
 
71
 
int KSmallSlider::valueFromPosition( int p ) const
72
 
{
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 );
78
 
    }
79
 
    else {
80
 
        // Horizontal everything is fine. Slider values match with Coordinate System
81
 
        return valueFromPosition( p, available() );
82
 
    }
83
 
}
84
 
 
85
 
/*  postionFromValue() discontinued in in Qt4 => taken from Qt3 */
86
 
int KSmallSlider::positionFromValue( int logical_val, int span ) const
87
 
{
88
 
    if ( span <= 0 || logical_val < minimum() || maximum() <= minimum() )
89
 
        return 0;
90
 
    if ( logical_val > maximum() )
91
 
        return span;
92
 
 
93
 
    uint range = maximum() - minimum();
94
 
    uint p = logical_val - minimum();
95
 
 
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);
103
 
    } else {
104
 
        uint div = span / range;
105
 
        uint mod = span % range;
106
 
        return p*div + (2*p*mod + range) / (2*range);
107
 
    }
108
 
    //equiv. to (p*span)/range + 0.5
109
 
    // no overflow because of this implicit assumption:
110
 
    // span <= 4096
111
 
}
112
 
 
113
 
/* valueFromPositon() discontinued in in Qt4 => taken from Qt3 */
114
 
int KSmallSlider::valueFromPosition( int pos, int span ) const
115
 
{
116
 
    if ( span <= 0 || pos <= 0 )
117
 
        return minimum();
118
 
    if ( pos >= span )
119
 
        return maximum();
120
 
 
121
 
    uint range = maximum() - minimum();
122
 
 
123
 
    if ( (uint)span > range )
124
 
        return  minimum() + (2*pos*range + span) / (2*span);
125
 
    else {
126
 
        uint div = range / span;
127
 
        uint mod = range % span;
128
 
        return  minimum() + pos*div + (2*pos*mod + span) / (2*span);
129
 
    }
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)
133
 
}
134
 
 
135
 
 
136
 
void KSmallSlider::resizeEvent( QResizeEvent * )
137
 
{
138
 
    update();
139
 
    //QWidget::resizeEvent( ev );
140
 
}
141
 
 
142
 
//  Returns the really available space for the slider. If there is no space, 0 is returned;
143
 
int KSmallSlider::available() const
144
 
{
145
 
    int available = 0;
146
 
    if ( orientation() == Qt::Vertical) {
147
 
        available = height();
148
 
    }
149
 
    else {
150
 
        available = width();
151
 
    }
152
 
    if ( available > 1 ) {
153
 
        available -= 2;
154
 
    }
155
 
    else {
156
 
        available = 0;
157
 
    }
158
 
    return available;
159
 
}
160
 
 
161
 
 
162
 
 
163
 
namespace
164
 
{
165
 
 
166
 
void gradient( QPainter &p, bool hor, const QRect &rect, const QColor &ca, const QColor &cb, int /*ncols*/)
167
 
{
168
 
   int rDiff, gDiff, bDiff;
169
 
   int rca, gca, bca, rcb, gcb, bcb;
170
 
 
171
 
   register int x, y;
172
 
 
173
 
   if ((rect.width()<=0) || (rect.height()<=0)) return;
174
 
 
175
 
   rDiff = (rcb = cb.red())   - (rca = ca.red());
176
 
   gDiff = (gcb = cb.green()) - (gca = ca.green());
177
 
   bDiff = (bcb = cb.blue())  - (bca = ca.blue());
178
 
 
179
 
   register int rl = rca << 16;
180
 
   register int gl = gca << 16;
181
 
   register int bl = bca << 16;
182
 
 
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;
186
 
 
187
 
   // these for-loops could be merged, but the if's in the inner loop
188
 
   // would make it slow
189
 
   if (!hor)
190
 
   {
191
 
      for ( y = rect.top(); y <= rect.bottom(); y++ ) {
192
 
         rl += rcdelta;
193
 
         gl += gcdelta;
194
 
         bl += bcdelta;
195
 
 
196
 
         p.setPen(QColor(rl>>16, gl>>16, bl>>16));
197
 
         p.drawLine(rect.left(), y, rect.right(), y);
198
 
      }
199
 
   } else
200
 
   {
201
 
      for( x = rect.left(); x <= rect.right(); x++) {
202
 
         rl += rcdelta;
203
 
         gl += gcdelta;
204
 
         bl += bcdelta;
205
 
 
206
 
         p.setPen(QColor(rl>>16, gl>>16, bl>>16));
207
 
         p.drawLine(x, rect.top(), x, rect.bottom());
208
 
      }
209
 
   }
210
 
}
211
 
 
212
 
QColor interpolate( QColor low, QColor high, int percent ) {
213
 
    if ( percent<=0 ) return low; else
214
 
    if ( percent>=100 ) return high; else
215
 
    return QColor(
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 );
219
 
}
220
 
 
221
 
}
222
 
 
223
 
void KSmallSlider::paintEvent( QPaintEvent * )
224
 
{
225
 
//    kDebug(67100) << "KSmallSlider::paintEvent: width() = " << width() << ", height() = " << height();
226
 
   QPainter p( this );
227
 
 
228
 
   int sliderPos = positionFromValue( QAbstractSlider::value() );
229
 
 
230
 
   // ------------------------ draw 3d border ---------------------------------------------
231
 
   QStyleOptionSlider option;
232
 
   option.init(this);
233
 
   style()->drawPrimitive ( QStyle::PE_Frame, &option, &p );
234
 
 
235
 
 
236
 
   // ------------------------ draw lower/left part ----------------------------------------
237
 
   if ( width()>2 && height()>2 )
238
 
   {
239
 
       if (  orientation() == Qt::Horizontal ) {
240
 
         QRect outer = QRect( 1, 1, sliderPos, height() - 2 );
241
 
//       kDebug(67100) << "KSmallSlider::paintEvent: outer = " << outer;
242
 
 
243
 
         if ( grayed )
244
 
             gradient( p, true, outer, grayLow,
245
 
                       interpolate( grayLow, grayHigh, 100*sliderPos/(width()-2) ),
246
 
                       32 );
247
 
         else
248
 
             gradient( p, true, outer, colLow,
249
 
                       interpolate( colLow, colHigh, 100*sliderPos/(width()-2) ),
250
 
                       32 );
251
 
      }
252
 
      else {
253
 
         QRect outer = QRect( 1, height()-sliderPos-1, width() - 2, sliderPos-1 );
254
 
/*
255
 
         kDebug(67100) << "KSmallSlider::paintEvent: sliderPos=" << sliderPos
256
 
                        << "height()=" << height()
257
 
                        << "width()=" << width()
258
 
                        << "outer = " << outer << endl;
259
 
*/
260
 
         if ( grayed )
261
 
             gradient( p, false, outer,
262
 
                       interpolate( grayLow, grayHigh, 100*sliderPos/(height()-2) ),
263
 
                       grayLow, 32 );
264
 
         else
265
 
             gradient( p, false, outer,
266
 
                       interpolate( colLow, colHigh, 100*sliderPos/(height()-2) ),
267
 
                       colLow, 32 );
268
 
      }
269
 
 
270
 
      // -------- draw upper/right part --------------------------------------------------
271
 
      QRect inner;
272
 
      if ( orientation() == Qt::Vertical ) {
273
 
          inner = QRect( 1, 1, width() - 2, height() - 2 -sliderPos );
274
 
      }
275
 
      else {
276
 
          inner = QRect( sliderPos + 1, 1, width() - 2 - sliderPos, height() - 2 );
277
 
      }
278
 
        
279
 
      if ( grayed ) {
280
 
          p.setBrush( grayBack );
281
 
          p.setPen( grayBack );
282
 
      } else {
283
 
          p.setBrush( colBack );
284
 
          p.setPen( colBack );
285
 
      }
286
 
      p.drawRect( inner );
287
 
   }
288
 
}
289
 
 
290
 
void KSmallSlider::mousePressEvent( QMouseEvent *e )
291
 
{
292
 
    //resetState();
293
 
 
294
 
   if ( e->button() == Qt::RightButton ) {
295
 
      return;
296
 
   }
297
 
 
298
 
   int pos = goodPart( e->pos() );
299
 
   moveSlider( pos );
300
 
}
301
 
 
302
 
void KSmallSlider::mouseMoveEvent( QMouseEvent *e )
303
 
{
304
 
    int pos = goodPart( e->pos() );
305
 
    moveSlider( pos );
306
 
}
307
 
 
308
 
/*
309
 
void KSmallSlider::wheelEvent( QWheelEvent * e)
310
 
{
311
 
//    kDebug(67100) << "KSmallslider::wheelEvent()";
312
 
    int inc = ( maximum() - minimum() ) / 20;
313
 
    if ( inc < 1)
314
 
        inc = 1;
315
 
 
316
 
    //kDebug(67100) << "KSmallslider::wheelEvent() inc=" << inc << "delta=" << e->delta();
317
 
    if ( e->delta() > 0 ) {
318
 
       setValue( QAbstractSlider::value() + inc );
319
 
    }
320
 
    else {
321
 
       setValue( QAbstractSlider::value() - inc );
322
 
    }
323
 
    e->accept(); // Accept the event
324
 
 
325
 
    // Hint: Qt autmatically triggers a valueChange() when we do setValue()
326
 
}
327
 
*/
328
 
 
329
 
 
330
 
/*
331
 
 * Moves slider to a dedicated position. If the value has changed
332
 
 */
333
 
void KSmallSlider::moveSlider( int pos )
334
 
{
335
 
    int  a = available();
336
 
    int newPos = qMin( a, qMax( 0, pos ) );  // keep it inside the available bounds of the slider
337
 
    int newVal = valueFromPosition( newPos );
338
 
 
339
 
    if ( newVal != value() ) {
340
 
        setValue( newVal );
341
 
        // probably done by Qt: emit valueChanged( value() ); //  Only for external use
342
 
        // probably we need update() here
343
 
    }
344
 
    update();
345
 
}
346
 
 
347
 
 
348
 
int KSmallSlider::goodPart( const QPoint &p ) const
349
 
{
350
 
    if ( orientation() == Qt::Vertical ) {
351
 
        return p.y() - 1;
352
 
    }
353
 
    else {
354
 
        return p.x() - 1;
355
 
    }
356
 
}
357
 
 
358
 
/***************** SIZE STUFF START ***************/
359
 
QSize KSmallSlider::sizeHint() const
360
 
{
361
 
    //constPolish();
362
 
    const int length = 25;
363
 
    const int thick  = 10;
364
 
 
365
 
    if (  orientation() == Qt::Vertical )
366
 
        return QSize( thick, length );
367
 
    else
368
 
        return QSize( length, thick );
369
 
}
370
 
 
371
 
 
372
 
QSize KSmallSlider::minimumSizeHint() const
373
 
{
374
 
    QSize s(10,10);
375
 
    return s;
376
 
}
377
 
 
378
 
 
379
 
QSizePolicy KSmallSlider::sizePolicy() const
380
 
{
381
 
 
382
 
    if ( orientation() == Qt::Vertical ) {
383
 
        //kDebug(67100) << "KSmallSlider::sizePolicy() vertical value=(Fixed,MinimumExpanding)\n";
384
 
        return QSizePolicy(  QSizePolicy::Fixed, QSizePolicy::Expanding );
385
 
    }
386
 
    else {
387
 
        //kDebug(67100) << "KSmallSlider::sizePolicy() horizontal value=(MinimumExpanding,Fixed)\n";
388
 
        return QSizePolicy( QSizePolicy::Expanding, QSizePolicy::Fixed );
389
 
    }
390
 
}
391
 
/***************** SIZE STUFF END ***************/
392
 
 
393
 
 
394
 
 
395
 
void KSmallSlider::setGray( bool value )
396
 
{
397
 
   if ( grayed!=value )
398
 
   {
399
 
      grayed = value;
400
 
      update();
401
 
      //repaint();
402
 
   }
403
 
}
404
 
 
405
 
bool KSmallSlider::gray() const
406
 
{
407
 
   return grayed;
408
 
}
409
 
 
410
 
void KSmallSlider::setColors( QColor high, QColor low, QColor back )
411
 
{
412
 
    colHigh = high;
413
 
    colLow = low;
414
 
    colBack = back;
415
 
    update();
416
 
    //repaint();
417
 
}
418
 
 
419
 
void KSmallSlider::setGrayColors( QColor high, QColor low, QColor back )
420
 
{
421
 
    grayHigh = high;
422
 
    grayLow = low;
423
 
    grayBack = back;
424
 
    update();
425
 
    //repaint();
426
 
}
427
 
 
428
 
#include "ksmallslider.moc"