/* * KMix -- KDE's full featured mini mixer * * * Copyright (C) 2000 Stefan Schimanski <1Stein@gmx.de> * * This program 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 program 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 program; if not, write to the Free * Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include #include #include #include #include #include #include "tdeglobalsettings.h" #include "ksmallslider.h" /* static const TQColor mutedHighColor2 = "#FFFFFF"; static const TQColor mutedLowColor2 = "#808080"; static const TQColor backColor2 = "#000000"; */ KSmallSlider::KSmallSlider( TQWidget *parent, const char *name ) : TQWidget( parent, name ), _orientation( Qt::Vertical ) { init(); } KSmallSlider::KSmallSlider( Qt::Orientation orientation, TQWidget *parent, const char *name ) : TQWidget( parent, name ), _orientation( orientation ) { init(); } KSmallSlider::KSmallSlider( int minValue, int maxValue, int pageStep, int value, Qt::Orientation orientation, TQWidget *parent, const char *name ) : TQWidget( parent, name ), TQRangeControl( minValue, maxValue, 1, pageStep, value ), _orientation( orientation) { init(); // sliderVal = value; } void KSmallSlider::init() { // !! the following 2 values must be -1, to make sure the values are not the real values. // Otherwise some code below could determine that no change has happened and to send // no signals or to do no initial paint. // sliderPos = -1; // state = Idle; //track = TRUE; //setMouseTracking(true); grayed = false; setFocusPolicy( TQ_TabFocus ); colHigh = TQColor(0,255,0); colLow = TQColor(255,0,0); colBack = TQColor(0,0,0); grayHigh = TQColor(255,255,255); grayLow = TQColor(128,128,128); grayBack = TQColor(0,0,0); } /* void KSmallSlider::setTracking( bool enable ) { track = enable; } */ int KSmallSlider::positionFromValue( int v ) const { return TQRangeControl::positionFromValue( v, available() ); } int KSmallSlider::valueFromPosition( int p ) const { if ( _orientation == Qt::Vertical ) { // Coordiante System starts at TopLeft, but the slider values increase from Bottom to Top // Thus "revert" the position int avail = available(); return TQRangeControl::valueFromPosition( avail - p, avail ); } else { //Horizontal everything is fine. Slider values match with Coordinate System return TQRangeControl::valueFromPosition( p, available() ); } } void KSmallSlider::rangeChange() { /* int newPos = positionFromValue( TQRangeControl::value() ); if ( newPos != sliderPos ) { sliderPos = newPos; } */ update(); } void KSmallSlider::valueChange() { //kdDebug(67100) << "KSmallSlider::valueChange() value=" << value() << "\n"; update(); emit valueChanged(value()); /* if ( sliderVal != TQRangeControl::value() ) { //int newPos = positionFromValue( TQRangeControl::value() ); //sliderPos = newPos; sliderVal = TQRangeControl::value(); update(); emit valueChanged(value()); } */ } void KSmallSlider::resizeEvent( TQResizeEvent * ) { update(); //TQWidget::resizeEvent( ev ); } // Returns the really available space for the slider. If there is no space, 0 is returned; int KSmallSlider::available() const { int available = 0; if ( _orientation == Qt::Vertical) { available = height(); } else { available = width(); } if ( available > 1 ) { available -= 2; } else { available = 0; } return available; } namespace { void gradient( TQPainter &p, bool hor, const TQRect &rect, const TQColor &ca, const TQColor &cb, int /*ncols*/) { int rDiff, gDiff, bDiff; int rca, gca, bca, rcb, gcb, bcb; register int x, y; if ((rect.width()<=0) || (rect.height()<=0)) return; rDiff = (rcb = cb.red()) - (rca = ca.red()); gDiff = (gcb = cb.green()) - (gca = ca.green()); bDiff = (bcb = cb.blue()) - (bca = ca.blue()); register int rl = rca << 16; register int gl = gca << 16; register int bl = bca << 16; int rcdelta = ((1<<16) / ((!hor) ? rect.height() : rect.width())) * rDiff; int gcdelta = ((1<<16) / ((!hor) ? rect.height() : rect.width())) * gDiff; int bcdelta = ((1<<16) / ((!hor) ? rect.height() : rect.width())) * bDiff; // these for-loops could be merged, but the if's in the inner loop // would make it slow if (!hor) { for ( y = rect.top(); y <= rect.bottom(); y++ ) { rl += rcdelta; gl += gcdelta; bl += bcdelta; p.setPen(TQColor(rl>>16, gl>>16, bl>>16)); p.drawLine(rect.left(), y, rect.right(), y); } } else { for( x = rect.left(); x <= rect.right(); x++) { rl += rcdelta; gl += gcdelta; bl += bcdelta; p.setPen(TQColor(rl>>16, gl>>16, bl>>16)); p.drawLine(x, rect.top(), x, rect.bottom()); } } } TQColor interpolate( TQColor low, TQColor high, int percent ) { if ( percent<=0 ) return low; else if ( percent>=100 ) return high; else return TQColor( low.red() + (high.red()-low.red()) * percent/100, low.green() + (high.green()-low.green()) * percent/100, low.blue() + (high.blue()-low.blue()) * percent/100 ); } } void KSmallSlider::paintEvent( TQPaintEvent * ) { // kdDebug(67100) << "KSmallSlider::paintEvent: width() = " << width() << ", height() = " << height() << endl; TQPainter p( this ); int sliderPos = positionFromValue( TQRangeControl::value() ); // ------------------------ draw 3d border --------------------------------------------- style().tqdrawPrimitive ( TQStyle::PE_Panel, &p, TQRect( 0, 0, width(), height() ), colorGroup(), TRUE ); // ------------------------ draw lower/left part ---------------------------------------- if ( width()>2 && height()>2 ) { if ( _orientation == Qt::Horizontal ) { TQRect outer = TQRect( 1, 1, sliderPos, height() - 2 ); // kdDebug(67100) << "KSmallSlider::paintEvent: outer = " << outer << endl; if ( grayed ) gradient( p, true, outer, grayLow, interpolate( grayLow, grayHigh, 100*sliderPos/(width()-2) ), 32 ); else gradient( p, true, outer, colLow, interpolate( colLow, colHigh, 100*sliderPos/(width()-2) ), 32 ); } else { TQRect outer = TQRect( 1, height()-sliderPos-1, width() - 2, sliderPos-1 ); /* kdDebug(67100) << "KSmallSlider::paintEvent: sliderPos=" << sliderPos << "height()=" << height() << "width()=" << width() << "outer = " << outer << endl; */ if ( grayed ) gradient( p, false, outer, interpolate( grayLow, grayHigh, 100*sliderPos/(height()-2) ), grayLow, 32 ); else gradient( p, false, outer, interpolate( colLow, colHigh, 100*sliderPos/(height()-2) ), colLow, 32 ); } // -------- draw upper/right part -------------------------------------------------- TQRect inner; if ( _orientation == Qt::Vertical ) { inner = TQRect( 1, 1, width() - 2, height() - 2 -sliderPos ); } else { inner = TQRect( sliderPos + 1, 1, width() - 2 - sliderPos, height() - 2 ); } if ( grayed ) { p.setBrush( grayBack ); p.setPen( grayBack ); } else { p.setBrush( colBack ); p.setPen( colBack ); } p.drawRect( inner ); } } void KSmallSlider::mousePressEvent( TQMouseEvent *e ) { //resetState(); if ( e->button() == Qt::RightButton ) { return; } // state = Dragging; //emit sliderPressed(); int pos = goodPart( e->pos() ); moveSlider( pos ); } void KSmallSlider::mouseMoveEvent( TQMouseEvent *e ) { /* if ( state != Dragging ) return; */ int pos = goodPart( e->pos() ); moveSlider( pos ); } void KSmallSlider::wheelEvent( TQWheelEvent * e) { // kdDebug(67100) << "KSmallslider::wheelEvent()" << endl; /* Unfortunately KSmallSlider is no MixDeviceWidget, so we don't have access to * the MixDevice. */ int inc = ( maxValue() - minValue() ) / 20; if ( inc < 1) inc = 1; //kdDebug(67100) << "KSmallslider::wheelEvent() inc=" << inc << "delta=" << e->delta() << endl; if ( e->delta() > 0 ) { TQRangeControl::setValue( TQRangeControl::value() + inc ); } else { TQRangeControl::setValue( TQRangeControl::value() - inc ); } e->accept(); // Accept the event // Hint: TQt autmatically triggers a valueChange() when we do setValue() } void KSmallSlider::mouseReleaseEvent( TQMouseEvent * ) { //resetState(); } /* * Moves slider to a dedicated position. If the value has changed */ void KSmallSlider::moveSlider( int pos ) { int a = available(); int newPos = TQMIN( a, TQMAX( 0, pos ) ); // keep it inside the available bounds of the slider int newVal = valueFromPosition( newPos ); if ( newVal != TQRangeControl::value() ) { //TQRangeControl::directSetValue( sliderVal ); TQRangeControl::setValue( newVal ); emit valueChanged( value() ); // Only for external use } update(); } /* void KSmallSlider::resetState() { switch ( state ) { case Dragging: { TQRangeControl::setValue( valueFromPosition( sliderPos ) ); emit sliderReleased(); break; } case Idle: break; default: tqWarning("KSmallSlider: (%s) in wrong state", name( "unnamed" ) ); } state = Idle; } */ void KSmallSlider::setValue( int value ) { TQRangeControl::setValue( value ); } void KSmallSlider::addStep() { addPage(); } void KSmallSlider::subtractStep() { subtractPage(); } int KSmallSlider::goodPart( const TQPoint &p ) const { if ( _orientation == Qt::Vertical ) { return p.y() - 1; } else { return p.x() - 1; } } /***************** SIZE STUFF START ***************/ TQSize KSmallSlider::sizeHint() const { //constPolish(); const int length = 25; const int thick = 10; if ( _orientation == Qt::Vertical ) return TQSize( thick, length ); else return TQSize( length, thick ); } TQSize KSmallSlider::minimumSizeHint() const { TQSize s(10,10); return s; } TQSizePolicy KSmallSlider::sizePolicy() const { if ( _orientation == Qt::Vertical ) { //kdDebug(67100) << "KSmallSlider::sizePolicy() vertical value=(Fixed,MinimumExpanding)\n"; return TQSizePolicy( TQSizePolicy::Fixed, TQSizePolicy::Expanding ); } else { //kdDebug(67100) << "KSmallSlider::sizePolicy() horizontal value=(MinimumExpanding,Fixed)\n"; return TQSizePolicy( TQSizePolicy::Expanding, TQSizePolicy::Fixed ); } } /***************** SIZE STUFF END ***************/ int KSmallSlider::minValue() const { return TQRangeControl::minValue(); } int KSmallSlider::maxValue() const { return TQRangeControl::maxValue(); } int KSmallSlider::lineStep() const { return TQRangeControl::lineStep(); } int KSmallSlider::pageStep() const { return TQRangeControl::pageStep(); } void KSmallSlider::setLineStep( int i ) { setSteps( i, pageStep() ); } void KSmallSlider::setPageStep( int i ) { setSteps( lineStep(), i ); } // Only for external acces. You MUST use TQRangeControl::value() internally. int KSmallSlider::value() const { return TQRangeControl::value(); } /* void KSmallSlider::paletteChange ( const TQPalette &) { if ( grayed ) { setColors(mutedLowColor2, mutedHighColor2, backColor2 ); } else { // ignore the TQPalette and use the values from TDEGlobalSettings instead //const TQColorGroup& qcg = palette().active(); setColors(TDEGlobalSettings::baseColor(), TDEGlobalSettings::highlightColor(), backColor2 ); } } */ void KSmallSlider::setGray( bool value ) { if ( grayed!=value ) { grayed = value; update(); //repaint(); } } bool KSmallSlider::gray() const { return grayed; } void KSmallSlider::setColors( TQColor high, TQColor low, TQColor back ) { colHigh = high; colLow = low; colBack = back; update(); //repaint(); } void KSmallSlider::setGrayColors( TQColor high, TQColor low, TQColor back ) { grayHigh = high; grayLow = low; grayBack = back; update(); //repaint(); } #include "ksmallslider.moc"