?? qslider.cpp
字號:
/****************************************************************************** $Id: qt/src/widgets/qslider.cpp 2.3.12 edited 2005-10-27 $**** Implementation of QSlider class**** Created : 961019**** Copyright (C) 1992-2000 Trolltech AS. All rights reserved.**** This file is part of the widgets module of the Qt GUI Toolkit.**** This file may be distributed under the terms of the Q Public License** as defined by Trolltech AS of Norway and appearing in the file** LICENSE.QPL included in the packaging of this file.**** This file may be distributed and/or modified under the terms of the** GNU General Public License version 2 as published by the Free Software** Foundation and appearing in the file LICENSE.GPL included in the** packaging of this file.**** Licensees holding valid Qt Enterprise Edition or Qt Professional Edition** licenses may use this file in accordance with the Qt Commercial License** Agreement provided with the Software.**** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.**** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for** information about Qt Commercial License Agreements.** See http://www.trolltech.com/qpl/ for QPL licensing information.** See http://www.trolltech.com/gpl/ for GPL licensing information.**** Contact info@trolltech.com if any conditions of this licensing are** not clear to you.************************************************************************/#include "qslider.h"#ifndef QT_NO_SLIDER#include "qpainter.h"#include "qdrawutil.h"#include "qtimer.h"#include "qbitmap.h"#include "qapplication.h"static const int motifBorder = 2;static const int thresholdTime = 500;static const int repeatTime = 100;static const bool funnyWindowsStyle = FALSE;static int sliderStartVal = 0; //##### class member?#ifdef QT_KEYPAD_MODEextern bool qt_modalEditingEnabled;#endif// NOT REVISED/*! \class QSlider qslider.h \brief The QSlider widget provides a vertical or horizontal slider. \ingroup basic The slider is the classic widget for controlling a bounded value. It lets the user move a slider along a horizontal or vertical groove, and translates the slider's position into an integer value in the legal range. QSlider inherits QRangeControl, which provides the "integer" side of the slider. setRange() and value() are likely to be used by practically all slider users; see the \l QRangeControl documentation for information about the many other functions that class provides. The main functions offered by the slider itself are tickmark and orientation control; you can use setTickmarks() to indicate where you want the tickmarks to be, setTickInterval() to indicate how many of them you want, and setOrientation() to indicate whether the slider is to e horizontal or vertical. A slider has a default focusPolicy() of \a WeakWheelFocus, i.e. it accepts focus on Tab and by using the mouse wheel, and a suitable keyboard interface. <img src=qslider-m.png> <img src=qslider-w.png> \sa QScrollBar QSpinBox <a href="guibooks.html#fowler">GUI Design Handbook: Slider</a>*//*! \enum QSlider::TickSetting This enum specifies where the tick marks are to be drawn, relative to the slider's groove and the handle the user moves. The possible values are \c NoMarks (no tickmarks are drawn), \c Above, \c Below, \c Left, \c Right and \c Both. \c NoMarks means to not draw any tickmarks; \c Both means to draw tickmarks on both sides of the groove. \c Above and \c Below mean to draw tickmarks above and below the (horizontal) slider. \c Left and \c Right mean to draw tickmarks to the left and right of the (vertical) slider.*//*! Constructs a vertical slider. The \e parent and \e name arguments are sent to the QWidget constructor.*/QSlider::QSlider( QWidget *parent, const char *name ) : QWidget( parent, name ){ orient = Vertical; init();}/*! Constructs a slider. The \e orientation must be QSlider::Vertical or QSlider::Horizontal. The \e parent and \e name arguments are sent to the QWidget constructor.*/QSlider::QSlider( Orientation orientation, QWidget *parent, const char *name ) : QWidget( parent, name ){ orient = orientation; init();}/*! Constructs a slider. \arg \e minValue is the minimum slider value. \arg \e maxValue is the maximum slider value. \arg \e step is the page step value. \arg \e value is the initial value. \arg \e orientation must be QSlider::Vertical or QSlider::Horizontal. The \e parent and \e name arguments are sent to the QWidget constructor.*/QSlider::QSlider( int minValue, int maxValue, int pageStep, int value, Orientation orientation, QWidget *parent, const char *name ) : QWidget( parent, name ), QRangeControl( minValue, maxValue, 1, pageStep, value ){ orient = orientation; init(); sliderVal = value;}void QSlider::init(){ extra = 0; timer = 0; sliderPos = 0; sliderVal = 0; clickOffset = 0; state = Idle; track = TRUE; ticks = NoMarks; tickInt = 0; setFocusPolicy( TabFocus ); initTicks();}/*! Does what's needed when someone changes the tickmark status*/void QSlider::initTicks(){ int space = (orient == Horizontal) ? height() : width(); if ( ticks == Both ) { tickOffset = ( space - thickness() ) / 2; } else if ( ticks == Above ) { tickOffset = space - thickness(); } else { tickOffset = 0; }}/*! Enables slider tracking if \e enable is TRUE, or disables tracking if \e enable is FALSE. If tracking is enabled (default), the slider emits the valueChanged() signal whenever the slider is being dragged. If tracking is disabled, the slider emits the valueChanged() signal when the user releases the mouse button (unless the value happens to be the same as before). \sa tracking()*/void QSlider::setTracking( bool enable ){ track = enable;}/*! \fn bool QSlider::tracking() const Returns TRUE if tracking is enabled, or FALSE if tracking is disabled. Tracking is initially enabled. \sa setTracking()*//*! \fn void QSlider::valueChanged( int value ) This signal is emitted when the slider value is changed, with the new slider value as an argument.*//*! \fn void QSlider::sliderPressed() This signal is emitted when the user presses the slider with the mouse.*//*! \fn void QSlider::sliderMoved( int value ) This signal is emitted when the slider is dragged, with the new slider value as an argument.*//*! \fn void QSlider::sliderReleased() This signal is emitted when the user releases the slider with the mouse.*//*! Calculates slider position corresponding to value \a v.*/int QSlider::positionFromValue( int v ) const{ int a = available(); return QRangeControl::positionFromValue( v, a );}/*! Returns the available space in which the slider can move.*/int QSlider::available() const{ int a; switch ( (GUIStyle)style() ) { case WindowsStyle: a = (orient == Horizontal) ? width() - style().sliderLength() : height() - style().sliderLength(); break; default: case MotifStyle: a = (orient == Horizontal) ? width() -style().sliderLength() - 2*motifBorder : height() - style().sliderLength() - 2*motifBorder; break; } return a;}/*! Calculates value corresponding to slider position \a p.*/int QSlider::valueFromPosition( int p ) const{ int a = available(); return QRangeControl::valueFromPosition( p, a );}/*! Implements the virtual QRangeControl function.*/void QSlider::rangeChange(){ int newPos = positionFromValue( value() ); if ( newPos != sliderPos ) { reallyMoveSlider( newPos ); }}/*! Implements the virtual QRangeControl function.*/void QSlider::valueChange(){ if ( sliderVal != value() ) { int newPos = positionFromValue( value() ); sliderVal = value(); reallyMoveSlider( newPos ); } emit valueChanged(value());}/*!\reimp*/void QSlider::resizeEvent( QResizeEvent * ){ rangeChange(); initTicks(); if ( autoMask() ) updateMask();}/*! Reimplements the virtual function QWidget::setPalette(). Sets the background color to the mid color for Motif style sliders.*/void QSlider::setPalette( const QPalette &p ){ QWidget::setPalette( p );}/*! Sets the slider orientation. The \e orientation must be QSlider::Vertical or QSlider::Horizontal. \sa orientation()*/void QSlider::setOrientation( Orientation orientation ){ orient = orientation; rangeChange(); update();}/*! \fn Orientation QSlider::orientation() const Returns the slider orientation; QSlider::Vertical or QSlider::Horizontal. \sa setOrientation()*//*! Returns the slider handle rectangle. (The actual moving-around thing.)*/QRect QSlider::sliderRect() const{ QRect r; switch ( (GUIStyle)style() ) { case WindowsStyle: if (orient == Horizontal ) r.setRect( sliderPos, tickOffset, style().sliderLength(), thickness() ); else r.setRect ( tickOffset, sliderPos, thickness(), style().sliderLength() ); break; default: case MotifStyle: if (orient == Horizontal ) r.setRect ( sliderPos + motifBorder, tickOffset + motifBorder, style().sliderLength(), thickness() - 2 * motifBorder ); else r.setRect ( tickOffset + motifBorder, sliderPos + motifBorder, thickness() - 2 * motifBorder, style().sliderLength() ); break; } return r;}/*! Paints the slider button using painter \a p with size, a colorgroup and position given by \a r. Reimplement this function to change the look of the slider button. Setting the colorgroup is useful to reuse the code to draw a mask if the slider supports transparceny. \sa setAutoMask(), updateMask()*/void QSlider::paintSlider( QPainter *p, const QColorGroup &g, const QRect &r ){ //####### should this one be removed? private? non-virtual? QPoint bo = p->brushOrigin(); p->setBrushOrigin(r.topLeft()); style().drawSlider( p, r.x(), r.y(), r.width(), r.height(), g, orient, ticks & Above, ticks & Below ); p->setBrushOrigin(bo);}/*! Performs the actual moving of the slider.*/void QSlider::reallyMoveSlider( int newPos ){ QRect oldR = sliderRect(); sliderPos = newPos; QRect newR = sliderRect(); //since sliderRect isn't virtual, I know that oldR and newR // are the same size. if ( orient == Horizontal ) { if ( oldR.left() < newR.left() ) oldR.setRight( QMIN ( oldR.right(), newR.left())); else //oldR.right() >= newR.right() oldR.setLeft( QMAX ( oldR.left(), newR.right())); } else { if ( oldR.top() < newR.top() ) oldR.setBottom( QMIN ( oldR.bottom(), newR.top())); else //oldR.bottom() >= newR.bottom() oldR.setTop( QMAX ( oldR.top(), newR.bottom())); } repaint( oldR ); repaint( newR, FALSE ); if ( autoMask() ) updateMask();}/*!\obsolete Draws the "groove" on which the slider moves, using the painter \a p. \a c gives the distance from the top (or left) edge of the widget to the center of the groove.*/void QSlider::drawWinGroove( QPainter *p, QCOORD c ){ if ( orient == Horizontal ) { qDrawWinPanel( p, 0, c - 2, width(), 4, colorGroup(), TRUE ); p->setPen( colorGroup().foreground() ); p->drawLine( 1, c - 1, width() - 3, c - 1 ); } else { qDrawWinPanel( p, c - 2, 0, 4, height(), colorGroup(), TRUE ); p->setPen( colorGroup().foreground() ); p->drawLine( c - 1, 1, c - 1, height() - 3 ); }}/*!\reimp*/void QSlider::paintEvent( QPaintEvent * ){ QPainter p( this ); const QRect & sliderR = sliderRect(); const QColorGroup & g = colorGroup(); int mid = thickness()/2; if ( ticks & Above ) mid += style().sliderLength() / 8; if ( ticks & Below ) mid -= style().sliderLength() / 8; if ( orient == Horizontal ) { style().drawSliderGroove(&p, 0, tickOffset, width(), thickness(), g, mid, Horizontal );// p.fillRect( 0, 0, width(), tickOffset, g.background() );// p.fillRect( 0, tickOffset + thickness(),// width(), height()/*###*/, g.background() ); erase( 0, 0, width(), tickOffset ); erase( 0, tickOffset + thickness(), width(), height() ); } else { style().drawSliderGroove( &p, tickOffset, 0, thickness(), height(), g, mid, Vertical );// p.fillRect( 0, 0, tickOffset, height(), g.background() );// p.fillRect( tickOffset + thickness(), 0,// width()/*###*/, height(), g.background() ); erase( 0, 0, tickOffset, height() ); erase( tickOffset + thickness(), 0, width()/*###*/, height() ); } int interval = tickInt; if ( interval <= 0 ) { interval = lineStep(); if ( positionFromValue( interval ) - positionFromValue( 0 ) < 3 ) interval = pageStep(); } if ( ticks & Above ) drawTicks( &p, g, 0, tickOffset - 2, interval ); if ( ticks & Below ) { int avail = (orient == Horizontal) ? height() : width(); avail -= tickOffset + thickness(); drawTicks( &p, g, tickOffset + thickness() + 1, avail - 2, interval ); } if ( hasFocus() ) { QRect r; if ( orient == Horizontal ) r.setRect( 0, tickOffset-1, width(), thickness()+2 ); else r.setRect( tickOffset-1, 0, thickness()+2, height() ); r = r.intersect( rect() ); if (style() == MotifStyle) style().drawFocusRect(&p, QRect(r.x()+1, r.y()+1, r.width()-2, r.height()-2), g); else style().drawFocusRect(&p, r, g); } paintSlider( &p, g, sliderR );}/*! Reimplementation of QWidget::updateMask(). Draws the mask of the slider when transparency is required. \sa QWidget::setAutoMask()*/void QSlider::updateMask(){ QBitmap bm( size() ); bm.fill( color0 ); { QPainter p( &bm, this ); QRect sliderR = sliderRect(); QColorGroup g(color1, color1, color1, color1, color1, color1, color1, color1, color0); int mid = tickOffset + thickness()/2; if ( ticks & Above ) mid += style().sliderLength() / 8; if ( ticks & Below ) mid -= style().sliderLength() / 8; if ( orient == Horizontal ) { style().drawSliderGrooveMask(&p, 0, tickOffset, width(), thickness(), mid, Horizontal ); } else { style().drawSliderGrooveMask( &p, tickOffset, 0, thickness(), height(), mid, Vertical ); } style().drawSliderMask( &p, sliderR.x(), sliderR.y(), sliderR.width(), sliderR.height(), orient, ticks & Above, ticks & Below ); int interval = tickInt; if ( interval <= 0 ) { interval = lineStep(); if ( positionFromValue( interval ) - positionFromValue( 0 ) < 3 ) interval = pageStep(); } if ( ticks & Above ) drawTicks( &p, g, 0, tickOffset - 2, interval ); if ( ticks & Below ) { int avail = (orient == Horizontal) ? height() : width(); avail -= tickOffset + thickness(); drawTicks( &p, g, tickOffset + thickness() + 1, avail - 2, interval ); } } setMask( bm );}/*!\reimp*/void QSlider::mousePressEvent( QMouseEvent *e ){ resetState(); sliderStartVal = sliderVal; QRect r = sliderRect(); if ( e->button() == RightButton ) { return; } else if ( r.contains( e->pos() ) ) { state = Dragging; clickOffset = (QCOORD)( goodPart( e->pos() ) - sliderPos ); emit sliderPressed(); } else if ( e->button() == MidButton ||
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -