#include "WDraggableSpinBox.h" #include #include #include #include WDraggableSpinBox::WDraggableSpinBox(QWidget *parent) : QDoubleSpinBox(parent) { mBeingDragged = false; mDefaultValue = 0; mMinDecimals = 1; mTrimTrailingZeroes = true; setMinimum(-1000000.0); setMaximum(1000000.0); lineEdit()->installEventFilter(this); } WDraggableSpinBox::~WDraggableSpinBox() { } void WDraggableSpinBox::mousePressEvent(QMouseEvent *pEvent) { if (pEvent->button() == Qt::LeftButton) { mBeingDragged = true; mBeenDragged = false; mLastY = QCursor::pos().y(); } } void WDraggableSpinBox::mouseReleaseEvent(QMouseEvent *Event) { mBeingDragged = false; setCursor(Qt::ArrowCursor); if (Event->button() == Qt::LeftButton) { if (!mBeenDragged) { if (Event->y() <= height() / 2) stepUp(); else stepDown(); } } else if (Event->button() == Qt::RightButton) { setValue(mDefaultValue); } } void WDraggableSpinBox::mouseMoveEvent(QMouseEvent*) { if (mBeingDragged) { QPoint cursorPos = QCursor::pos(); // Update value double DragAmount = (singleStep() / 10.0) * (mLastY - cursorPos.y()); setValue(value() + DragAmount); // Wrap cursor int screenHeight = QApplication::desktop()->screenGeometry().height(); if (cursorPos.y() == screenHeight - 1) QCursor::setPos(cursorPos.x(), 1); if (cursorPos.y() == 0) QCursor::setPos(cursorPos.x(), screenHeight - 2); // Set cursor shape if (DragAmount != 0) { mBeenDragged = true; setCursor(Qt::SizeVerCursor); } // Update last Y mLastY = QCursor::pos().y(); } } void WDraggableSpinBox::wheelEvent(QWheelEvent *pEvent) { if (!hasFocus()) pEvent->ignore(); else QDoubleSpinBox::wheelEvent(pEvent); } bool WDraggableSpinBox::eventFilter(QObject *, QEvent *pEvent) { if (pEvent->type() == QEvent::MouseButtonPress) setFocus(); return false; } QString WDraggableSpinBox::textFromValue(double val) const { QString str = QString::number(val, 'f', decimals()); int decIndex = str.indexOf('.'); int numDecs; if (decIndex == -1) numDecs = 0; else numDecs = str.size() - decIndex - 1; if (numDecs < mMinDecimals) { int size = str.size() + mMinDecimals + 1; str.reserve(size); str += '.'; for (int iDec = 0; iDec < mMinDecimals; iDec++) str += '0'; } else if ((numDecs > mMinDecimals) && mTrimTrailingZeroes) { while (numDecs > mMinDecimals) { if (str.endsWith('0')) { str.chop(1); numDecs--; } else if (str.endsWith('.')) { str.chop(1); break; } else break; } } return str; } void WDraggableSpinBox::SetDefaultValue(double value) { mDefaultValue = value; } void WDraggableSpinBox::SetMinDecimals(int dec) { mMinDecimals = dec; } void WDraggableSpinBox::TrimTrailingZeroes(bool trim) { mTrimTrailingZeroes = trim; }