📄 intspinbox.cpp
字号:
/* ---------------------------------------------------------------------- * Implemention of class SpinWidget intspinbox.cpp * ---------------------------------------------------------------------- * This file is part of Valkyrie, a front-end for Valgrind * Copyright (c) 2000-2006, OpenWorks LLP <info@open-works.co.uk> * This program is released under the terms of the GNU GPL v.2 * See the file LICENSE.GPL for the full license details. */#include <qapplication.h>#include <qpainter.h>#include <qstyle.h>#include <qpixmap.h>#include "intspinbox.h"#include "vk_utils.h"/* class SpinWidget ---------------------------------------------------- */SpinWidget::SpinWidget( QWidget* parent, const char* name ) : QWidget( parent, name ){ upEnabled = true; downEnabled = true; ed = 0; timerUp = 0; theButton = 0; buttonDown = 0; connect( &auRepTimer, SIGNAL( timeout() ), this, SLOT( timerDone() ) ); setFocusPolicy( StrongFocus ); arrange(); updateDisplay();}QRect SpinWidget::UpRect() const { return upRect; }void SpinWidget::startTimer( int msec ) { auRepTimer.start( msec, true ); }void SpinWidget::startTimer( bool up, int msec ) { timerUp = up; startTimer( msec ); }void SpinWidget::stopTimer() { auRepTimer.stop(); }void SpinWidget::setEditWidget( QWidget* w ){ if ( w ) { w->reparent( this, QPoint( 0, 0 ) ); setFocusProxy( w ); } ed = w; arrange(); updateDisplay();}QRect SpinWidget::querySubControlMetrics ( QStyle::SubControl sc ){ int fw = style().pixelMetric( QStyle::PM_SpinBoxFrameWidth, this); QSize buttSize; buttSize.setHeight( this->height()/2 - fw ); if ( buttSize.height() < 8 ) buttSize.setHeight( 8 ); /* 8/5 = 1.6 => approximate golden mean */ // buttSize.setWidth( QMIN( buttSize.height() * 8 / 5, this->width() / 4 ) ); buttSize.setWidth( buttSize.height() * 8 / 5 ); /* Ensure we're not smaller than the smallest allowable size: */ buttSize = buttSize.expandedTo( QApplication::globalStrut() ); int top = fw; int buttLeft = this->width() - fw - buttSize.width(); int left = fw; int edWidth = buttLeft - fw; switch ( sc ) { case QStyle::SC_SpinWidgetUp: return QRect(buttLeft, top, buttSize.width(), buttSize.height()); case QStyle::SC_SpinWidgetDown: return QRect(buttLeft, top + buttSize.height(), buttSize.width(), buttSize.height()); case QStyle::SC_SpinWidgetButtonField: return QRect(buttLeft, top, buttSize.width(), this->height() - 2*fw); case QStyle::SC_SpinWidgetEditField: return QRect(left, fw, edWidth, this->height() - 2*fw); case QStyle::SC_SpinWidgetFrame: return this->rect(); default: break; } return QRect();}void SpinWidget::arrange(){ QRect mr_up = querySubControlMetrics( QStyle::SC_SpinWidgetUp ); upRect = QStyle::visualRect( mr_up, this ); QRect mr_down = querySubControlMetrics( QStyle::SC_SpinWidgetDown ); downRect = QStyle::visualRect( mr_down, this ); if ( ed ) { QRect mr_ed = querySubControlMetrics( QStyle::SC_SpinWidgetEditField ); ed->setGeometry( QStyle::visualRect( mr_ed, this ) ); }}void SpinWidget::stepUp(){ emit stepUpPressed(); }void SpinWidget::stepDown(){ emit stepDownPressed(); }void SpinWidget::timerDone(){ QTimer::singleShot( 1, this, SLOT( timerDoneEx() ) ); }void SpinWidget::timerDoneEx(){ if ( !buttonDown ) return; if ( timerUp ) stepUp(); else stepDown(); startTimer( 100 );}void SpinWidget::windowActivationChange( bool oldActive ){ if ( oldActive && buttonDown ) { stopTimer(); buttonDown = 0; theButton = 0; } QWidget::windowActivationChange( oldActive );}void SpinWidget::resizeEvent( QResizeEvent* ){ arrange(); }void SpinWidget::mousePressEvent( QMouseEvent *e ){ if ( e->button() != LeftButton ) { stopTimer(); buttonDown = 0; theButton = 0; repaint( downRect.unite( upRect ), false ); return; } uint oldButtonDown = buttonDown; if ( downRect.contains( e->pos() ) && downEnabled ) buttonDown = 1; else if ( upRect.contains( e->pos() ) && upEnabled ) buttonDown = 2; else buttonDown = 0; theButton = buttonDown; if ( oldButtonDown != buttonDown ) { if ( !buttonDown ) { repaint( downRect.unite( upRect ), false ); } else if ( buttonDown & 1 ) { repaint( downRect, false ); stepDown(); startTimer( false, 300 ); } else if ( buttonDown & 2 ) { repaint( upRect, false ); stepUp(); startTimer( true, 300 ); } }}void SpinWidget::mouseReleaseEvent( QMouseEvent *e ){ if ( e->button() != LeftButton ) return; uint oldButtonDown = theButton; theButton = 0; if ( oldButtonDown != theButton ) { if ( oldButtonDown & 1 ) repaint( downRect, false ); else if ( oldButtonDown & 2 ) repaint( upRect, false ); } stopTimer(); buttonDown = 0;}void SpinWidget::mouseMoveEvent( QMouseEvent *e ){ if ( !(e->state() & LeftButton ) ) return; uint oldButtonDown = theButton; if ( oldButtonDown & 1 && !downRect.contains( e->pos() ) ) { stopTimer(); theButton = 0; repaint( downRect, false ); } else if ( oldButtonDown & 2 && !upRect.contains( e->pos() ) ) { stopTimer(); theButton = 0; repaint( upRect, false ); } else if ( !oldButtonDown && upRect.contains( e->pos() ) && buttonDown & 2 ) { startTimer( 500 ); theButton = 2; repaint( upRect, false ); } else if ( !oldButtonDown && downRect.contains( e->pos() ) && buttonDown & 1 ) { startTimer( 500 ); theButton = 1; repaint( downRect, false ); }}void SpinWidget::paintEvent( QPaintEvent * ){ QPainter p( this ); QStyle::SFlags flags = QStyle::Style_Default; if ( isEnabled() ) flags |= QStyle::Style_Enabled; if ( hasFocus() || focusProxy() && focusProxy()->hasFocus() ) flags |= QStyle::Style_HasFocus; QStyle::SCFlags active; if ( theButton & 1 ) active = QStyle::SC_SpinWidgetDown; else if ( theButton & 2 ) active = QStyle::SC_SpinWidgetUp; else active = QStyle::SC_None; QRect mr = style().querySubControlMetrics( QStyle::CC_SpinWidget, this, QStyle::SC_SpinWidgetFrame ); QRect fr = QStyle::visualRect( mr, this ); QStyle::PrimitiveElement pe; QStyle::SCFlags controls = QStyle::SC_All; if ( controls & QStyle::SC_SpinWidgetFrame ) { /* draw a rectangle with two pixel line width */ int x = fr.x(); int y = fr.y(); int w = fr.width(); int h = fr.height(); QColor c1 = colorGroup().dark(); QColor c2 = colorGroup().light(); QColor c3 = colorGroup().shadow(); QColor c4 = colorGroup().midlight(); if ( w < 2 || h < 2 ) /* can't do anything with that */ return; QPen oldPen = p.pen(); QPointArray a( 3 ); a.setPoints( 3, x, y+h-2, x, y, x+w-2, y ); p.setPen( c1 ); p.drawPolyline( a ); a.setPoints( 3, x, y+h-1, x+w-1, y+h-1, x+w-1, y ); p.setPen( c2 ); p.drawPolyline( a ); if ( w > 4 && h > 4 ) { a.setPoints( 3, x+1, y+h-3, x+1, y+1, x+w-3, y+1 ); p.setPen( c3 ); p.drawPolyline( a ); a.setPoints( 3, x+1, y+h-2, x+w-2, y+h-2, x+w-2, y+1 ); p.setPen( c4 ); p.drawPolyline( a ); } p.setPen( oldPen ); } if ( controls & QStyle::SC_SpinWidgetUp ) { flags = QStyle::Style_Default | QStyle::Style_Enabled; if ( active == QStyle::SC_SpinWidgetUp ) { flags |= QStyle::Style_On; flags |= QStyle::Style_Sunken; } else flags |= QStyle::Style_Raised; pe = QStyle::PE_SpinWidgetUp; QRect re = upRect; QColorGroup ucg = upEnabled ? colorGroup() : palette().disabled(); style().drawPrimitive( QStyle::PE_ButtonBevel, &p, re, ucg, flags ); style().drawPrimitive( pe, &p, re, ucg, flags ); } if ( controls & QStyle::SC_SpinWidgetDown ) { flags = QStyle::Style_Default | QStyle::Style_Enabled; if ( active == QStyle::SC_SpinWidgetDown ) { flags |= QStyle::Style_On; flags |= QStyle::Style_Sunken; } else flags |= QStyle::Style_Raised; pe = QStyle::PE_SpinWidgetDown; QRect re = downRect; QColorGroup dcg = downEnabled ? colorGroup() : palette().disabled(); style().drawPrimitive( QStyle::PE_ButtonBevel, &p, re, dcg, flags ); style().drawPrimitive( pe, &p, re, dcg, flags ); }}int SpinWidget::downRectWidth() const{ return downRect.width(); }void SpinWidget::updateDisplay(){ if ( !isEnabled() ) { upEnabled = false; downEnabled = false; } if ( theButton & 1 && ( downEnabled ) == 0 ) { theButton &= ~1; buttonDown &= ~1; } if ( theButton & 2 && ( upEnabled ) == 0 ) { theButton &= ~2; buttonDown &= ~2; } repaint( false );}void SpinWidget::setUpEnabled( bool on ){ if ( (bool)upEnabled != on ) { upEnabled = on; updateDisplay(); }}void SpinWidget::setDownEnabled( bool on ){ if ( (bool)downEnabled != on ) { downEnabled = on; updateDisplay(); }}/* class NumberSection --------------------------------------------- */#define MAX_POW 20static int powers[MAX_POW+1] = { 1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048, 4096, 8192, 16384, 32768, 65536, 131072, 262144, 524288, 1048576};NumberSection::NumberSection( int idx/*=-1*/, QString sep_char/*=" : "*/ ){ sep = sep_char; secIndex = idx; selStart = 0; selEnd = 0;}/* if a value of 0 is passed for step, then we are using powers of two, not lineStep, as the value-to-increment/decrement. */void NumberSection::setValues( int _min, int _max, int _val, int _step ) { usePowers = (_step == 0); if ( !usePowers ) { min = _min; max = _max; val = _val; step = _step; } else { /* min,max,val will be used as powers of 2... */ /* preset boundary min/max, then find user-set min/max */ min = 0; max = MAX_POW; min = getPowIndex( _min ); vk_assert(min != -1); max = getPowIndex( _max ); vk_assert(max != -1); val = getPowIndex( _val ); vk_assert(val != -1); step = 1; }}int NumberSection::getPowIndex( int v ){ for ( int i=min; i<=max; i++ ) { if ( v == powers[i] ) return i; } return -1;}void NumberSection::setSelectionStart( int s ) { selStart = s; }void NumberSection::setSelectionEnd( int s ){ selEnd = s; }int NumberSection::index() const{ return secIndex; }int NumberSection::selectionStart() const{ return selStart; }int NumberSection::selectionEnd() const{ return selEnd; }bool NumberSection::usesPowers(){ return usePowers; }QString NumberSection::separator() const{ return sep; }int NumberSection::minVal(){ return ( usePowers) ? powers[min] : min; }int NumberSection::maxVal(){ return ( usePowers) ? powers[max] : max; }int NumberSection::value(){ return ( usePowers ) ? powers[val] : val; }void NumberSection::setValue( int v ){ if ( !usePowers ) val = v; else { val = getPowIndex( v ); val = ( val == -1 ) ? min : val; }}void NumberSection::stepUp() { if ( val+step > max ) val = min; else val = val+step;}void NumberSection::stepDown() { if ( val-step < min ) val = max; else val = val-step;}bool NumberSection::withinRange( int num ){ bool ok = false; if ( !usePowers ) { ok = ( (num >= min) && (num <= max) ); } else { int v = getPowIndex( num ); ok = ( (v >= min) && (v <= max) ); } return ok;}/* class Editor -------------------------------------------------------- */Editor::~Editor(){ if ( pmBuf ) delete pmBuf;}Editor::Editor( IntSpin * parent, const char * name ) : QWidget( parent, name, #if (QT_VERSION-0 >= 0x030200) WNoAutoErase )#else // QT_VERSION < 3.2 WResizeNoErase | WRepaintNoErase )#endif{ cw = parent; pmBuf = 0; pmDirty = true;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -