00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016 #include "Panner.h"
00017
00018 #include <QMouseEvent>
00019 #include <QPaintEvent>
00020 #include <QWheelEvent>
00021 #include <QPainter>
00022
00023 #include <iostream>
00024 #include <cmath>
00025
00026 Panner::Panner(QWidget *parent) :
00027 QWidget(parent),
00028 m_rectX(0),
00029 m_rectY(0),
00030 m_rectWidth(1),
00031 m_rectHeight(1),
00032 m_scrollUnit(0),
00033 m_defaultCentreX(0),
00034 m_defaultCentreY(0),
00035 m_defaultsSet(false),
00036 m_thumbColour(palette().highlightedText().color()),
00037 m_backgroundAlpha(255),
00038 m_thumbAlpha(255),
00039 m_clicked(false)
00040 {
00041 }
00042
00043 Panner::~Panner()
00044 {
00045 }
00046
00047 void
00048 Panner::setAlpha(int backgroundAlpha, int thumbAlpha)
00049 {
00050 m_backgroundAlpha = backgroundAlpha;
00051 m_thumbAlpha = thumbAlpha;
00052 }
00053
00054 void
00055 Panner::setScrollUnit(float unit)
00056 {
00057 m_scrollUnit = unit;
00058 }
00059
00060 void
00061 Panner::scroll(bool up)
00062 {
00063 float unit = m_scrollUnit;
00064 if (unit == 0.f) {
00065 unit = float(m_rectHeight) / (6 * float(height()));
00066 if (unit < 0.01) unit = 0.01;
00067 }
00068
00069 if (!up) {
00070 m_rectY += unit;
00071 } else {
00072 m_rectY -= unit;
00073 }
00074
00075 normalise();
00076 emitAndUpdate();
00077 }
00078
00079 void
00080 Panner::mousePressEvent(QMouseEvent *e)
00081 {
00082 if (e->button() == Qt::MidButton ||
00083 ((e->button() == Qt::LeftButton) &&
00084 (e->modifiers() & Qt::ControlModifier))) {
00085 resetToDefault();
00086 } else if (e->button() == Qt::LeftButton) {
00087 m_clicked = true;
00088 m_clickPos = e->pos();
00089 m_dragStartX = m_rectX;
00090 m_dragStartY = m_rectY;
00091 }
00092 }
00093
00094 void
00095 Panner::mouseDoubleClickEvent(QMouseEvent *e)
00096 {
00097 if (e->button() != Qt::LeftButton) {
00098 return;
00099 }
00100
00101 emit doubleClicked();
00102 }
00103
00104 void
00105 Panner::mouseMoveEvent(QMouseEvent *e)
00106 {
00107 if (!m_clicked) return;
00108
00109 float dx = float(e->pos().x() - m_clickPos.x()) / float(width());
00110 float dy = float(e->pos().y() - m_clickPos.y()) / float(height());
00111
00112 m_rectX = m_dragStartX + dx;
00113 m_rectY = m_dragStartY + dy;
00114
00115 normalise();
00116 repaint();
00117 emit rectExtentsChanged(m_rectX, m_rectY, m_rectWidth, m_rectHeight);
00118 emit rectCentreMoved(centreX(), centreY());
00119 }
00120
00121 void
00122 Panner::mouseReleaseEvent(QMouseEvent *e)
00123 {
00124 if (!m_clicked) return;
00125
00126 mouseMoveEvent(e);
00127 m_clicked = false;
00128 }
00129
00130 void
00131 Panner::wheelEvent(QWheelEvent *e)
00132 {
00133 scroll(e->delta() > 0);
00134 }
00135
00136 void
00137 Panner::enterEvent(QEvent *)
00138 {
00139 emit mouseEntered();
00140 }
00141
00142 void
00143 Panner::leaveEvent(QEvent *)
00144 {
00145 emit mouseLeft();
00146 }
00147
00148 void
00149 Panner::paintEvent(QPaintEvent *)
00150 {
00151 QPainter paint(this);
00152 paint.setRenderHint(QPainter::Antialiasing, false);
00153
00154 QColor bg(palette().background().color());
00155 bg.setAlpha(m_backgroundAlpha);
00156
00157 paint.setPen(palette().dark().color());
00158 paint.setBrush(bg);
00159 paint.drawRect(0, 0, width(), height());
00160
00161 QColor hl(m_thumbColour);
00162 hl.setAlpha(m_thumbAlpha);
00163
00164 paint.setBrush(hl);
00165
00166 paint.drawRect(lrintf(width() * m_rectX),
00167 lrintf(height() * m_rectY),
00168 lrintf(width() * m_rectWidth),
00169 lrintf(height() * m_rectHeight));
00170 }
00171
00172 void
00173 Panner::normalise()
00174 {
00175 if (m_rectWidth > 1.0) m_rectWidth = 1.0;
00176 if (m_rectHeight > 1.0) m_rectHeight = 1.0;
00177 if (m_rectX + m_rectWidth > 1.0) m_rectX = 1.0 - m_rectWidth;
00178 if (m_rectX < 0) m_rectX = 0;
00179 if (m_rectY + m_rectHeight > 1.0) m_rectY = 1.0 - m_rectHeight;
00180 if (m_rectY < 0) m_rectY = 0;
00181
00182 if (!m_defaultsSet) {
00183 m_defaultCentreX = centreX();
00184 m_defaultCentreY = centreY();
00185 m_defaultsSet = true;
00186 }
00187 }
00188
00189 void
00190 Panner::emitAndUpdate()
00191 {
00192 emit rectExtentsChanged(m_rectX, m_rectY, m_rectWidth, m_rectHeight);
00193 emit rectCentreMoved(centreX(), centreY());
00194 update();
00195 }
00196
00197 void
00198 Panner::getRectExtents(float &x0, float &y0, float &width, float &height)
00199 {
00200 x0 = m_rectX;
00201 y0 = m_rectY;
00202 width = m_rectWidth;
00203 height = m_rectHeight;
00204 }
00205
00206 void
00207 Panner::setRectExtents(float x0, float y0, float width, float height)
00208 {
00209
00210
00211
00212 if (m_rectX == x0 &&
00213 m_rectY == y0 &&
00214 m_rectWidth == width &&
00215 m_rectHeight == height) {
00216 return;
00217 }
00218
00219 m_rectX = x0;
00220 m_rectY = y0;
00221 m_rectWidth = width;
00222 m_rectHeight = height;
00223
00224 normalise();
00225 emitAndUpdate();
00226 }
00227
00228 void
00229 Panner::setRectWidth(float width)
00230 {
00231 if (m_rectWidth == width) return;
00232 m_rectWidth = width;
00233 normalise();
00234 emitAndUpdate();
00235 }
00236
00237 void
00238 Panner::setRectHeight(float height)
00239 {
00240 if (m_rectHeight == height) return;
00241 m_rectHeight = height;
00242 normalise();
00243 emitAndUpdate();
00244 }
00245
00246 void
00247 Panner::setRectCentreX(float x)
00248 {
00249 float x0 = x - m_rectWidth/2;
00250 if (x0 == m_rectX) return;
00251 m_rectX = x0;
00252 normalise();
00253 emitAndUpdate();
00254 }
00255
00256 void
00257 Panner::setRectCentreY(float y)
00258 {
00259 float y0 = y - m_rectHeight/2;
00260 if (y0 == m_rectY) return;
00261 m_rectY = y0;
00262 normalise();
00263 emitAndUpdate();
00264 }
00265
00266 QSize
00267 Panner::sizeHint() const
00268 {
00269 return QSize(30, 30);
00270 }
00271
00272 void
00273 Panner::setDefaultRectCentre(float cx, float cy)
00274 {
00275 m_defaultCentreX = cx;
00276 m_defaultCentreY = cy;
00277 m_defaultsSet = true;
00278 }
00279
00280 void
00281 Panner::resetToDefault()
00282 {
00283 float x0 = m_defaultCentreX - m_rectWidth/2;
00284 float y0 = m_defaultCentreY - m_rectHeight/2;
00285 if (x0 == m_rectX && y0 == m_rectY) return;
00286 m_rectX = x0;
00287 m_rectY = y0;
00288 normalise();
00289 emitAndUpdate();
00290 }
00291
00292