00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include "kxyselector.h"
00021 #include <QStyle>
00022 #include <QPainter>
00023 #include <QStyleOptionFrame>
00024 #include <QMouseEvent>
00025 #include <kdebug.h>
00026
00027
00028
00029
00030
00031
00032
00033 class KXYSelector::Private
00034 {
00035 public:
00036 Private(KXYSelector *q):
00037 q(q),
00038 xPos(0),
00039 yPos(0),
00040 minX(0),
00041 maxX(100),
00042 minY(0),
00043 maxY(100),
00044 m_markerColor(Qt::white)
00045 {}
00046
00047 void setValues(int _xPos, int _yPos);
00048
00049 KXYSelector *q;
00050 int px;
00051 int py;
00052 int xPos;
00053 int yPos;
00054 int minX;
00055 int maxX;
00056 int minY;
00057 int maxY;
00058 QColor m_markerColor;
00059 };
00060
00061 KXYSelector::KXYSelector( QWidget *parent )
00062 : QWidget( parent )
00063 , d(new Private(this))
00064 {
00065 }
00066
00067
00068 KXYSelector::~KXYSelector()
00069 {
00070 delete d;
00071 }
00072
00073 int KXYSelector::xValue() const
00074 {
00075 return d->xPos;
00076 }
00077
00078 int KXYSelector::yValue() const
00079 {
00080 return d->yPos;
00081 }
00082
00083 void KXYSelector::setRange( int _minX, int _minY, int _maxX, int _maxY )
00084 {
00085 if (_maxX == _minX) {
00086 kWarning() << "KXYSelector::setRange invalid range: " << _maxX << " == " << _minX << " (for X) ";
00087 return;
00088 }
00089 if (_maxY == _minY) {
00090 kWarning() << "KXYSelector::setRange invalid range: " << _maxY << " == " << _minY << " (for Y) ";
00091 return;
00092 }
00093
00094
00095 int w = style()->pixelMetric(QStyle::PM_DefaultFrameWidth);
00096 d->px = w;
00097 d->py = w;
00098 d->minX = _minX;
00099 d->minY = _minY;
00100 d->maxX = _maxX;
00101 d->maxY = _maxY;
00102 }
00103
00104 void KXYSelector::setXValue( int _xPos )
00105 {
00106 setValues(_xPos, d->yPos);
00107 }
00108
00109 void KXYSelector::setYValue( int _yPos )
00110 {
00111 setValues(d->xPos, _yPos);
00112 }
00113
00114 void KXYSelector::setValues( int _xPos, int _yPos )
00115 {
00116 d->setValues(_xPos, _yPos);
00117 }
00118
00119 void KXYSelector::Private::setValues(int _xPos, int _yPos )
00120 {
00121 int w = q->style()->pixelMetric(QStyle::PM_DefaultFrameWidth);
00122
00123 xPos = _xPos;
00124 yPos = _yPos;
00125
00126 if ( xPos > maxX )
00127 xPos = maxX;
00128 else if ( xPos < minX )
00129 xPos = minX;
00130
00131 if ( yPos > maxY )
00132 yPos = maxY;
00133 else if ( yPos < minY )
00134 yPos = minY;
00135
00136 Q_ASSERT(maxX != minX);
00137 int xp = w + (q->width() - 2 * w) * xPos / (maxX - minX);
00138
00139 Q_ASSERT(maxY != minY);
00140 int yp = q->height() - w - (q->height() - 2 * w) * yPos / (maxY - minY);
00141
00142 q->setPosition( xp, yp );
00143 }
00144
00145 void KXYSelector::setMarkerColor( const QColor &col )
00146 {
00147 d->m_markerColor = col;
00148 }
00149
00150 QRect KXYSelector::contentsRect() const
00151 {
00152 int w = style()->pixelMetric(QStyle::PM_DefaultFrameWidth);
00153 return rect().adjusted(w, w, -w, -w);
00154 }
00155
00156 QSize KXYSelector::minimumSizeHint() const
00157 {
00158 int w = style()->pixelMetric(QStyle::PM_DefaultFrameWidth);
00159 return QSize( 2 * w, 2 * w );
00160 }
00161
00162 void KXYSelector::paintEvent( QPaintEvent * )
00163 {
00164 QStyleOptionFrame opt;
00165 opt.initFrom(this);
00166
00167 QPainter painter;
00168 painter.begin( this );
00169
00170 drawContents( &painter );
00171 drawMarker( &painter, d->px, d->py );
00172
00173 style()->drawPrimitive( QStyle::PE_Frame, &opt, &painter, this );
00174
00175 painter.end();
00176 }
00177
00178 void KXYSelector::mousePressEvent( QMouseEvent *e )
00179 {
00180 mouseMoveEvent( e );
00181 }
00182
00183 void KXYSelector::mouseMoveEvent( QMouseEvent *e )
00184 {
00185 int xVal, yVal;
00186 int w = style()->pixelMetric( QStyle::PM_DefaultFrameWidth );
00187 valuesFromPosition( e->pos().x() - w, e->pos().y() - w, xVal, yVal );
00188 setValues( xVal, yVal );
00189
00190 emit valueChanged( d->xPos, d->yPos );
00191 }
00192
00193 void KXYSelector::wheelEvent( QWheelEvent *e )
00194 {
00195 if ( e->orientation() == Qt::Horizontal )
00196 setValues( xValue() + e->delta()/120, yValue() );
00197 else
00198 setValues( xValue(), yValue() + e->delta()/120 );
00199
00200 emit valueChanged( d->xPos, d->yPos );
00201 }
00202
00203 void KXYSelector::valuesFromPosition( int x, int y, int &xVal, int &yVal ) const
00204 {
00205 int w = style()->pixelMetric( QStyle::PM_DefaultFrameWidth );
00206
00207 xVal = ( ( d->maxX - d->minX ) * ( x - w ) ) / ( width() - 2 * w );
00208 yVal = d->maxY - ( ( ( d->maxY - d->minY ) * (y - w) ) / ( height() - 2 * w ) );
00209
00210 if ( xVal > d->maxX )
00211 xVal = d->maxX;
00212 else if ( xVal < d->minX )
00213 xVal = d->minX;
00214
00215 if ( yVal > d->maxY )
00216 yVal = d->maxY;
00217 else if ( yVal < d->minY )
00218 yVal = d->minY;
00219 }
00220
00221 void KXYSelector::setPosition( int xp, int yp )
00222 {
00223 int w = style()->pixelMetric( QStyle::PM_DefaultFrameWidth );
00224
00225 if ( xp < w )
00226 xp = w;
00227 else if ( xp > width() - w )
00228 xp = width() - w;
00229
00230 if ( yp < w )
00231 yp = w;
00232 else if ( yp > height() - w )
00233 yp = height() - w;
00234
00235 d->px = xp;
00236 d->py = yp;
00237
00238 update();
00239 }
00240
00241 void KXYSelector::drawContents( QPainter * )
00242 {}
00243
00244
00245 void KXYSelector::drawMarker( QPainter *p, int xp, int yp )
00246 {
00247 QPen pen( d->m_markerColor );
00248 p->setPen( pen );
00249
00250
00251
00252
00253
00254
00255
00256 p->drawEllipse(xp - 4, yp - 4, 8, 8);
00257 }
00258
00259
00260
00261 #include "kxyselector.moc"