Changed spinboxes to be more standard UX.

This commit is contained in:
Leonardo Zide
2025-07-20 18:05:06 -07:00
parent 611d0424ed
commit 0472885e43
4 changed files with 124 additions and 156 deletions
+110 -146
View File
@@ -9,13 +9,13 @@ lcDoubleSpinBox::lcDoubleSpinBox(QWidget* Parent)
{
lineEdit()->installEventFilter(this);
connect(this, QOverload<double>::of(&QDoubleSpinBox::valueChanged), this, &lcDoubleSpinBox::ValueChanged);
connect(lineEdit(), &QLineEdit::returnPressed, this, &lcDoubleSpinBox::ReturnPressed);
}
void lcDoubleSpinBox::SetValue(double Value)
{
if (!hasFocus())
mInitialValue = Value;
mModified = false;
setValue(Value);
}
@@ -48,31 +48,46 @@ void lcDoubleSpinBox::SetSnap(lcFloatPropertySnap Snap)
}
}
void lcDoubleSpinBox::ShowLadderWidget()
{
lcLadderWidget* LadderWidget = new lcLadderWidget(this, mSnap);
mLadderWidgetInitialValue = value();
connect(LadderWidget, &lcLadderWidget::EditingCanceled, this, &lcDoubleSpinBox::LadderWidgetCanceled);
LadderWidget->Show();
}
void lcDoubleSpinBox::LadderWidgetCanceled()
{
setValue(mLadderWidgetInitialValue);
}
QString lcDoubleSpinBox::textFromValue(double Value) const
{
return lcFormatValueLocalized(Value);
}
void lcDoubleSpinBox::ValueChanged()
{
mModified = true;
}
void lcDoubleSpinBox::CancelEditing()
{
if (value() == mInitialValue)
return;
emit EditingCanceled();
setValue(mInitialValue);
if (mModified)
{
emit EditingCanceled();
}
}
void lcDoubleSpinBox::FinishEditing()
{
if (value() == mInitialValue)
return;
emit EditingFinished();
mInitialValue = value();
clearFocus();
if (mModified)
{
emit EditingFinished();
}
}
void lcDoubleSpinBox::ReturnPressed()
@@ -80,128 +95,14 @@ void lcDoubleSpinBox::ReturnPressed()
FinishEditing();
}
void lcDoubleSpinBox::HandleMousePressEvent(QMouseEvent* MouseEvent)
{
if (MouseEvent->buttons() == Qt::LeftButton)
{
mDragMode = DragMode::Start;
mLastPosition = GetGlobalMousePosition(MouseEvent);
}
else
{
if (mDragMode == DragMode::Value)
CancelEditing();
if (mDragMode != DragMode::None)
{
mDragMode = DragMode::None;
return;
}
if (MouseEvent->buttons() == Qt::MiddleButton)
{
lcLadderWidget* LadderWidget = new lcLadderWidget(this, mSnap);
connect(LadderWidget, &lcLadderWidget::EditingCanceled, this, &lcDoubleSpinBox::CancelEditing);
connect(LadderWidget, &lcLadderWidget::EditingFinished, this, &lcDoubleSpinBox::FinishEditing);
mInitialValue = value();
LadderWidget->Show();
}
}
}
bool lcDoubleSpinBox::HandleMouseMoveEvent(QMouseEvent* MouseEvent, QObject* Object)
{
if (mDragMode != DragMode::None)
{
if (mDragMode == DragMode::Start)
{
if (lineEdit()->selectionLength() > 0 && Object != this)
{
mDragMode = DragMode::None;
}
else
{
QPoint Position = GetGlobalMousePosition(MouseEvent);
if (abs(mLastPosition.y() - Position.y()) > 3)
{
mDragMode = DragMode::Value;
mLastPosition = QCursor::pos();
}
}
}
if (mDragMode == DragMode::Value)
{
QPoint Position = QCursor::pos();
stepBy(mLastPosition.y() - Position.y());
QScreen* Screen = QGuiApplication::screenAt(mapToGlobal(QPoint(width() / 2, height() / 2)));
if (Screen)
{
int ScreenHeight = Screen->geometry().height();
if (Position.y() <= 0)
{
Position.setY(ScreenHeight - 2);
QCursor::setPos(Position);
}
else if (Position.y() >= ScreenHeight - 1)
{
Position.setY(1);
QCursor::setPos(Position);
}
}
mLastPosition = Position;
MouseEvent->accept();
return true;
}
}
return false;
}
void lcDoubleSpinBox::HandleMouseReleaseEvent(QMouseEvent* MouseEvent)
{
Q_UNUSED(MouseEvent);
if (mDragMode == DragMode::Value)
FinishEditing();
mDragMode = DragMode::None;
}
bool lcDoubleSpinBox::eventFilter(QObject* Object, QEvent* Event)
{
switch (Event->type())
if (mDragMode == DragMode::None && Event->type() == QEvent::MouseButtonPress && Object == lineEdit())
{
case QEvent::MouseButtonPress:
if (Object == lineEdit())
HandleMousePressEvent(reinterpret_cast<QMouseEvent*>(Event));
break;
QMouseEvent* MouseEvent = reinterpret_cast<QMouseEvent*>(Event);
case QEvent::MouseMove:
if (Object == lineEdit())
HandleMouseMoveEvent(reinterpret_cast<QMouseEvent*>(Event), Object);
break;
case QEvent::MouseButtonRelease:
if (Object == lineEdit())
HandleMouseReleaseEvent(reinterpret_cast<QMouseEvent*>(Event));
break;
default:
break;
if (MouseEvent->buttons() == Qt::MiddleButton)
ShowLadderWidget();
}
return QDoubleSpinBox::eventFilter(Object, Event);
@@ -209,25 +110,82 @@ bool lcDoubleSpinBox::eventFilter(QObject* Object, QEvent* Event)
void lcDoubleSpinBox::mousePressEvent(QMouseEvent* MouseEvent)
{
HandleMousePressEvent(MouseEvent);
if (mDragMode == DragMode::Dragging)
{
if (MouseEvent->buttons() != Qt::LeftButton)
{
CancelEditing();
double InitialValue = value();
mDragMode = DragMode::None;
}
}
else if (mDragMode == DragMode::None)
{
if (MouseEvent->buttons() == Qt::LeftButton)
{
mDragMode = DragMode::Start;
mLastPosition = GetGlobalMousePosition(MouseEvent);
}
else if (MouseEvent->buttons() == Qt::MiddleButton)
{
ShowLadderWidget();
}
}
else
{
mDragMode = DragMode::None;
}
QDoubleSpinBox::mousePressEvent(MouseEvent);
if (value() != InitialValue)
FinishEditing();
}
void lcDoubleSpinBox::mouseMoveEvent(QMouseEvent* MouseEvent)
{
if (!HandleMouseMoveEvent(MouseEvent, this))
QDoubleSpinBox::mouseMoveEvent(MouseEvent);
if (mDragMode == DragMode::Dragging)
{
QPoint Position = QCursor::pos();
stepBy(mLastPosition.y() - Position.y());
QScreen* Screen = QGuiApplication::screenAt(Position);
if (Screen)
{
int ScreenHeight = Screen->geometry().height();
if (Position.y() <= 0)
{
Position.setY(ScreenHeight - 2);
QCursor::setPos(Position);
}
else if (Position.y() >= ScreenHeight - 1)
{
Position.setY(1);
QCursor::setPos(Position);
}
}
mLastPosition = Position;
}
else if (mDragMode == DragMode::Start)
{
QPoint Position = GetGlobalMousePosition(MouseEvent);
if (abs(mLastPosition.y() - Position.y()) > 3)
{
mDragMode = DragMode::Dragging;
mLastPosition = QCursor::pos();
}
}
QDoubleSpinBox::mouseMoveEvent(MouseEvent);
}
void lcDoubleSpinBox::mouseReleaseEvent(QMouseEvent* MouseEvent)
{
HandleMouseReleaseEvent(MouseEvent);
mDragMode = DragMode::None;
QDoubleSpinBox::mouseReleaseEvent(MouseEvent);
}
@@ -240,8 +198,7 @@ bool lcDoubleSpinBox::event(QEvent* Event)
if (KeyEvent->key() == Qt::Key_Escape)
{
if (mDragMode == DragMode::Value)
CancelEditing();
CancelEditing();
mDragMode = DragMode::None;
@@ -253,6 +210,7 @@ bool lcDoubleSpinBox::event(QEvent* Event)
else if (KeyEvent->key() == Qt::Key_Return || KeyEvent->key() == Qt::Key_Enter)
{
FinishEditing();
KeyEvent->accept();
return true;
@@ -262,10 +220,16 @@ bool lcDoubleSpinBox::event(QEvent* Event)
return QDoubleSpinBox::event(Event);
}
void lcDoubleSpinBox::focusInEvent(QFocusEvent* FocusEvent)
{
mModified = false;
QDoubleSpinBox::focusInEvent(FocusEvent);
}
void lcDoubleSpinBox::focusOutEvent(QFocusEvent* FocusEvent)
{
if (value() != mInitialValue)
CancelEditing();
FinishEditing();
QDoubleSpinBox::focusOutEvent(FocusEvent);
}
+8 -6
View File
@@ -19,6 +19,7 @@ public:
void mousePressEvent(QMouseEvent* MouseEvent) override;
void mouseMoveEvent(QMouseEvent* MouseEvent) override;
void mouseReleaseEvent(QMouseEvent* MouseEvent) override;
void focusInEvent(QFocusEvent* FocusEvent) override;
void focusOutEvent(QFocusEvent* FocusEvent) override;
signals:
@@ -26,13 +27,17 @@ signals:
void EditingFinished();
protected slots:
void ValueChanged();
void CancelEditing();
void FinishEditing();
void ReturnPressed();
void LadderWidgetCanceled();
protected:
bool event(QEvent* Event) override;
void ShowLadderWidget();
static QPoint GetGlobalMousePosition(QMouseEvent* MouseEvent)
{
#if (QT_VERSION < QT_VERSION_CHECK(6, 0, 0))
@@ -42,18 +47,15 @@ protected:
#endif
}
void HandleMousePressEvent(QMouseEvent* MouseEvent);
bool HandleMouseMoveEvent(QMouseEvent* MouseEvent, QObject* Object);
void HandleMouseReleaseEvent(QMouseEvent* MouseEvent);
enum class DragMode
{
None,
Start,
Value
Dragging
};
double mInitialValue = 0.0;
bool mModified = false;
double mLadderWidgetInitialValue = 0.0;
QPoint mLastPosition;
DragMode mDragMode = DragMode::None;
lcFloatPropertySnap mSnap = lcFloatPropertySnap::Auto;
+3 -3
View File
@@ -215,14 +215,14 @@ void lcMinifigDialog::on_TemplateComboBox_currentIndexChanged(const QString& Tem
mMinifigWizard->SetColorIndex(PartIdx, lcGetColorIndex(Template.ColorCodes[PartIdx]));
mColorPickers[PartIdx]->SetCurrentColorCode(Template.ColorCodes[PartIdx]);
QDoubleSpinBox* AngleSpinBox = mSpinBoxes[PartIdx];
lcDoubleSpinBox* AngleSpinBox = mSpinBoxes[PartIdx];
if (AngleSpinBox)
{
QSignalBlocker AngleBlocker(AngleSpinBox);
mMinifigWizard->SetAngle(PartIdx, Template.Angles[PartIdx]);
AngleSpinBox->setValue(Template.Angles[PartIdx]);
AngleSpinBox->SetValue(Template.Angles[PartIdx]);
}
}
@@ -402,7 +402,7 @@ void lcMinifigDialog::ColorChanged(int Index)
void lcMinifigDialog::AngleChanged(double Value)
{
std::array<QDoubleSpinBox*, LC_MFW_NUMITEMS>::iterator Search = std::find(mSpinBoxes.begin(), mSpinBoxes.end(), sender());
std::array<lcDoubleSpinBox*, LC_MFW_NUMITEMS>::iterator Search = std::find(mSpinBoxes.begin(), mSpinBoxes.end(), sender());
if (Search == mSpinBoxes.end())
return;
+3 -1
View File
@@ -1,7 +1,9 @@
#pragma once
#include "minifig.h"
class lcColorPicker;
class lcDoubleSpinBox;
namespace Ui
{
@@ -36,7 +38,7 @@ protected:
lcView* mView;
std::array<QToolButton*, LC_MFW_NUMITEMS> mPieceButtons;
std::array<lcColorPicker*, LC_MFW_NUMITEMS> mColorPickers;
std::array<QDoubleSpinBox*, LC_MFW_NUMITEMS> mSpinBoxes;
std::array<lcDoubleSpinBox*, LC_MFW_NUMITEMS> mSpinBoxes;
QString mCurrentTemplateName;
bool mCurrentTemplateModified = false;