1
/**************************************************************************\
3
* This file is part of the Coin 3D visualization library.
4
* Copyright (C) 1998-2003 by Systems in Motion. All rights reserved.
6
* This library is free software; you can redistribute it and/or
7
* modify it under the terms of the GNU General Public License
8
* ("GPL") version 2 as published by the Free Software Foundation.
9
* See the file LICENSE.GPL at the root directory of this source
10
* distribution for additional information about the GNU GPL.
12
* For using Coin with software that can not be combined with the GNU
13
* GPL, and for taking advantage of the additional benefits of our
14
* support services, please contact Systems in Motion about acquiring
15
* a Coin Professional Edition License.
17
* See <URL:http://www.coin3d.org> for more information.
19
* Systems in Motion, Teknobyen, Abels Gate 5, 7030 Trondheim, NORWAY.
20
* <URL:http://www.sim.no>.
22
\**************************************************************************/
25
// FIXME: should strongly consider making the thumbwheel a public
26
// class, as we've had several requests for it. 20020226 mortene.
33
#include <qdrawutil.h>
36
#include <qmetaobject.h>
37
#include <Inventor/Qt/widgets/moc_SoQtThumbWheel.icc>
39
#include <Inventor/SbBasic.h>
40
#include <Inventor/errors/SoDebugError.h>
43
#include <Inventor/Qt/widgets/SoAnyThumbWheel.h>
44
#include <Inventor/Qt/widgets/SoQtThumbWheel.h>
46
// *************************************************************************
48
static const int SHADEBORDERWIDTH = 0;
50
SoQtThumbWheel::SoQtThumbWheel(QWidget * parent,
52
: QWidget(parent, name)
54
this->constructor(SoQtThumbWheel::Vertical);
57
SoQtThumbWheel::SoQtThumbWheel(Orientation orientation,
60
: QWidget(parent, name)
62
this->constructor(orientation);
66
SoQtThumbWheel::constructor(Orientation orientation)
68
this->orient = orientation;
69
this->state = SoQtThumbWheel::Idle;
70
this->wheelValue = this->tempWheelValue = 0.0f;
71
this->wheel = new SoAnyThumbWheel;
72
this->wheel->setMovement(SoAnyThumbWheel::UNIFORM);
73
this->wheel->setGraphicsByteOrder(SoAnyThumbWheel::ARGB);
76
this->currentPixmap = -1;
79
SoQtThumbWheel::~SoQtThumbWheel()
83
for (int i = 0; i < this->numPixmaps; i++)
84
delete this->pixmaps[i];
85
delete [] this->pixmaps;
90
SoQtThumbWheel::setOrientation(Orientation orientation)
92
this->orient = orientation;
97
SoQtThumbWheel::paintEvent(QPaintEvent * event)
100
QRect paintRect = event->rect();
101
p.setClipRect(paintRect);
102
QColorGroup g = this->colorGroup();
105
if (this->orient == SoQtThumbWheel::Vertical) {
106
w = this->width() - 12;
107
d = this->height() - 6;
109
w = this->height() - 12;
110
d = this->width() - 6;
113
// Handle resizing to too small dimensions gracefully.
114
if ((d <= 0) || (w <= 0)) return;
116
this->initWheel(d, w);
118
int pixmap = this->wheel->getBitmapForValue(this->tempWheelValue,
119
(this->state == SoQtThumbWheel::Disabled) ?
120
SoAnyThumbWheel::DISABLED : SoAnyThumbWheel::ENABLED);
122
QRect widgetrect(0, 0, this->width(), this->height());
123
QRect wheelrect(widgetrect);
125
if (this->orient == Vertical) {
126
wheelrect.setTop( wheelrect.top() + 2);
127
wheelrect.setBottom(wheelrect.bottom() - 2);
128
wheelrect.setLeft( wheelrect.left() + 5);
129
wheelrect.setRight( wheelrect.right() - 5);
131
wheelrect.setTop( wheelrect.top() + 5);
132
wheelrect.setBottom(wheelrect.bottom() - 5);
133
wheelrect.setLeft( wheelrect.left() + 2);
134
wheelrect.setRight( wheelrect.right() - 2);
137
qDrawPlainRect(&p, wheelrect.left(), wheelrect.top(), wheelrect.width(),
138
wheelrect.height(), QColor(0, 0, 0), 1);
140
wheelrect.setTop( wheelrect.top() + 1);
141
wheelrect.setBottom(wheelrect.bottom() - 1);
142
wheelrect.setLeft( wheelrect.left() + 1);
143
wheelrect.setRight( wheelrect.right() - 1);
144
// wheelrect is now wheel-only
146
if (this->orient == Vertical)
147
bitBlt(this, wheelrect.left(), wheelrect.top(), this->pixmaps[pixmap],
148
0, 0, w, d, CopyROP);
150
bitBlt(this, wheelrect.left(), wheelrect.top(), this->pixmaps[pixmap],
151
0, 0, d, w, CopyROP);
152
this->currentPixmap = pixmap;
160
SoQtThumbWheel::mousePressEvent(QMouseEvent * event)
162
if (this->state != SoQtThumbWheel::Idle)
165
if (event->button() != LeftButton)
169
if (this->orient == Vertical) {
170
wheel.setLeft(SHADEBORDERWIDTH + 3);
171
wheel.setTop(SHADEBORDERWIDTH + 6);
172
wheel.setRight(this->width() - SHADEBORDERWIDTH - 3);
173
wheel.setBottom(this->height() - SHADEBORDERWIDTH - 6);
175
wheel.setLeft(SHADEBORDERWIDTH + 6);
176
wheel.setTop(SHADEBORDERWIDTH + 3);
177
wheel.setRight(this->width() - SHADEBORDERWIDTH - 6);
178
wheel.setBottom(this->height() - SHADEBORDERWIDTH - 3);
181
if (! wheel.contains(event->pos()))
184
this->state = SoQtThumbWheel::Dragging;
186
if (this->orient == SoQtThumbWheel::Vertical)
187
this->mouseDownPos = event->pos().y() - SHADEBORDERWIDTH - 6;
189
this->mouseDownPos = event->pos().x() - SHADEBORDERWIDTH - 6;
191
this->mouseLastPos = this->mouseDownPos;
201
SoQtThumbWheel::mouseMoveEvent(QMouseEvent * event)
203
if (this->state != SoQtThumbWheel::Dragging)
206
if (this->orient == SoQtThumbWheel::Vertical)
207
this->mouseLastPos = event->pos().y() - SHADEBORDERWIDTH - 6;
209
this->mouseLastPos = event->pos().x() - SHADEBORDERWIDTH - 6;
212
this->tempWheelValue = this->wheel->calculateValue(this->wheelValue,
213
this->mouseDownPos, this->mouseLastPos - this->mouseDownPos);
215
emit wheelMoved(this->tempWheelValue);
217
this->repaint(FALSE);
225
SoQtThumbWheel::mouseReleaseEvent(QMouseEvent * event)
227
if (this->state != SoQtThumbWheel::Dragging)
230
if (event->button() != LeftButton)
233
this->wheelValue = this->tempWheelValue;
234
this->mouseLastPos = this->mouseDownPos;
235
this->state = SoQtThumbWheel::Idle;
236
emit wheelReleased();
241
SoQtThumbWheel::getNormalizedValue(int pos) const
243
int relativepos = pos - this->mouseDownPos;
244
return (float) relativepos / (float)this->getWheelLength() * 2.0f;
250
SoQtThumbWheel::getWheelLength(void) const
252
return this->orient == SoQtThumbWheel::Vertical ?
253
this->height() : this->width();
259
SoQtThumbWheel::orientedCoord(const QPoint &p) const
261
return (this->orient == SoQtThumbWheel::Horizontal) ? p.x() : p.y();
266
SoQtThumbWheel::sizeHint(void) const
268
const int length = 122;
271
if (this->orient == SoQtThumbWheel::Horizontal)
272
return QSize(length, thick);
274
return QSize(thick, length);
277
SoQtThumbWheel::Orientation
278
SoQtThumbWheel::orientation(void) const
284
SoQtThumbWheel::value(void) const
286
return this->wheelValue;
289
// *************************************************************************
292
SoQtThumbWheel::initWheel(int diameter, int width)
295
this->wheel->getSize(d, w);
296
if (d == diameter && w == width) return;
298
this->wheel->setSize(diameter, width);
301
int pheight = diameter;
302
if (this->orient == Horizontal) {
307
if (this->pixmaps != NULL) {
308
for (int i = 0; i < this->numPixmaps; i++)
309
delete this->pixmaps[i];
310
delete [] this->pixmaps;
313
this->numPixmaps = this->wheel->getNumBitmaps();
314
this->pixmaps = new QPixmap * [this->numPixmaps];
315
QImage image(pwidth, pheight, 32);
316
for (int i = 0; i < this->numPixmaps; i++) {
317
this->wheel->drawBitmap(i, image.bits(), (this->orient == Vertical) ?
318
SoAnyThumbWheel::VERTICAL : SoAnyThumbWheel::HORIZONTAL);
319
this->pixmaps[i] = new QPixmap(QSize(pwidth, pheight));
320
bool s = this->pixmaps[i]->convertFromImage(image);
321
if (!s && SOQT_DEBUG) {
322
SoDebugError::post("SoQtThumbWheel::initWheel",
323
"Could not convert QImage to QPixmap, "
324
"for unknown reason.");
329
// *************************************************************************
332
SoQtThumbWheel::setEnabled(bool enable)
335
this->state = SoQtThumbWheel::Idle;
337
this->state = SoQtThumbWheel::Disabled;
338
this->repaint(FALSE);
342
SoQtThumbWheel::isEnabled(void) const
344
return (this->state != SoQtThumbWheel::Disabled);
348
SoQtThumbWheel::setValue(float value)
350
this->wheelValue = this->tempWheelValue = value;
351
this->mouseDownPos = this->mouseLastPos;
352
this->repaint(FALSE);
355
// *************************************************************************
358
SoQtThumbWheel::setRangeBoundaryHandling(boundaryHandling handling)
362
this->wheel->setBoundaryHandling(SoAnyThumbWheel::CLAMP);
365
this->wheel->setBoundaryHandling(SoAnyThumbWheel::MODULATE);
368
this->wheel->setBoundaryHandling(SoAnyThumbWheel::ACCUMULATE);
371
assert(0 && "impossible");
375
// *************************************************************************
377
SoQtThumbWheel::boundaryHandling
378
SoQtThumbWheel::getRangeBoundaryHandling(void) const
380
switch (this->wheel->getBoundaryHandling()) {
381
case SoAnyThumbWheel::CLAMP:
383
case SoAnyThumbWheel::MODULATE:
385
case SoAnyThumbWheel::ACCUMULATE:
388
assert(0 && "impossible");
390
return CLAMP; // never reached
393
// *************************************************************************