PrimeWorldEditor/src/Editor/Widgets/WDraggableSpinBox.cpp

167 lines
3.4 KiB
C++

#include "WDraggableSpinBox.h"
#include <QApplication>
#include <QDesktopWidget>
#include <QLineEdit>
#include <QMouseEvent>
#include <QScreen>
WDraggableSpinBox::WDraggableSpinBox(QWidget *parent)
: QDoubleSpinBox(parent)
, mBeingDragged(false)
, mDefaultValue(0)
, mMinDecimals(1)
, mTrimTrailingZeroes(true)
{
setMinimum(-1000000.0);
setMaximum(1000000.0);
setDecimals(6);
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 *pEvent)
{
mBeingDragged = false;
setCursor(Qt::ArrowCursor);
if (pEvent->button() == Qt::LeftButton)
{
if (!mBeenDragged)
{
if (pEvent->y() <= height() / 2)
stepUp();
else
stepDown();
}
}
else if (pEvent->button() == Qt::RightButton)
{
setValue(mDefaultValue);
}
emit editingFinished();
}
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::primaryScreen()->geometry().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;
}
bool WDraggableSpinBox::IsBeingDragged()
{
return mBeingDragged;
}
void WDraggableSpinBox::SetDefaultValue(double Value)
{
mDefaultValue = Value;
}
void WDraggableSpinBox::SetMinDecimals(int Dec)
{
mMinDecimals = Dec;
}
void WDraggableSpinBox::TrimTrailingZeroes(bool Trim)
{
mTrimTrailingZeroes = Trim;
}