Skip to content

Commit ed24c15

Browse files
committed
Use spin boxes for float properties.
1 parent 6f30ad2 commit ed24c15

File tree

7 files changed

+424
-28
lines changed

7 files changed

+424
-28
lines changed

common/lc_doublespinbox.cpp

Lines changed: 211 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,211 @@
1+
#include "lc_global.h"
2+
#include "lc_doublespinbox.h"
3+
#include "lc_qutils.h"
4+
5+
lcDoubleSpinBox::lcDoubleSpinBox(QWidget* Parent)
6+
: QDoubleSpinBox(Parent)
7+
{
8+
lineEdit()->installEventFilter(this);
9+
10+
connect(lineEdit(), &QLineEdit::returnPressed, this, &lcDoubleSpinBox::ReturnPressed);
11+
}
12+
13+
void lcDoubleSpinBox::SetValue(double Value)
14+
{
15+
if (!hasFocus())
16+
mInitialValue = Value;
17+
18+
setValue(Value);
19+
}
20+
21+
QString lcDoubleSpinBox::textFromValue(double Value) const
22+
{
23+
return lcFormatValueLocalized(Value);
24+
}
25+
26+
void lcDoubleSpinBox::CancelEditing()
27+
{
28+
emit EditingCanceled();
29+
30+
setValue(mInitialValue);
31+
}
32+
33+
void lcDoubleSpinBox::FinishEditing()
34+
{
35+
if (value() == mInitialValue)
36+
return;
37+
38+
emit EditingFinished();
39+
40+
mInitialValue = value();
41+
}
42+
43+
void lcDoubleSpinBox::ReturnPressed()
44+
{
45+
FinishEditing();
46+
clearFocus();
47+
}
48+
49+
void lcDoubleSpinBox::HandleMousePressEvent(QMouseEvent* MouseEvent)
50+
{
51+
if (MouseEvent->buttons() == Qt::LeftButton)
52+
{
53+
mDragMode = DragMode::Start;
54+
mLastPosition = GetGlobalMousePosition(MouseEvent);
55+
}
56+
else
57+
{
58+
if (mDragMode == DragMode::Value)
59+
CancelEditing();
60+
61+
mDragMode = DragMode::None;
62+
}
63+
}
64+
65+
bool lcDoubleSpinBox::HandleMouseMoveEvent(QMouseEvent* MouseEvent, QObject* Object)
66+
{
67+
if (mDragMode != DragMode::None)
68+
{
69+
if (mDragMode == DragMode::Start)
70+
{
71+
if (lineEdit()->selectionLength() > 0 && Object != this)
72+
{
73+
mDragMode = DragMode::None;
74+
}
75+
else
76+
{
77+
QPoint Position = GetGlobalMousePosition(MouseEvent);
78+
79+
if (abs(mLastPosition.y() - Position.y()) > 3)
80+
{
81+
mDragMode = DragMode::Value;
82+
mLastPosition = QCursor::pos();
83+
}
84+
}
85+
}
86+
87+
if (mDragMode == DragMode::Value)
88+
{
89+
QPoint Position = QCursor::pos();
90+
91+
stepBy(mLastPosition.y() - Position.y());
92+
93+
QScreen* Screen = QGuiApplication::screenAt(mapToGlobal(QPoint(width() / 2, height() / 2)));
94+
95+
if (Screen)
96+
{
97+
int ScreenHeight = Screen->geometry().height();
98+
99+
if (Position.y() <= 0)
100+
{
101+
Position.setY(ScreenHeight - 2);
102+
103+
QCursor::setPos(Position);
104+
}
105+
else if (Position.y() >= ScreenHeight - 1)
106+
{
107+
Position.setY(1);
108+
109+
QCursor::setPos(Position);
110+
}
111+
}
112+
113+
mLastPosition = Position;
114+
115+
MouseEvent->accept();
116+
117+
return true;
118+
}
119+
}
120+
121+
return false;
122+
}
123+
124+
void lcDoubleSpinBox::HandleMouseReleaseEvent(QMouseEvent* MouseEvent)
125+
{
126+
Q_UNUSED(MouseEvent);
127+
128+
if (mDragMode == DragMode::Value)
129+
{
130+
FinishEditing();
131+
132+
clearFocus();
133+
}
134+
135+
mDragMode = DragMode::None;
136+
}
137+
138+
bool lcDoubleSpinBox::eventFilter(QObject* Object, QEvent* Event)
139+
{
140+
switch (Event->type())
141+
{
142+
case QEvent::MouseButtonPress:
143+
if (Object == lineEdit())
144+
HandleMousePressEvent(reinterpret_cast<QMouseEvent*>(Event));
145+
break;
146+
147+
case QEvent::MouseMove:
148+
if (Object == lineEdit())
149+
HandleMouseMoveEvent(reinterpret_cast<QMouseEvent*>(Event), Object);
150+
break;
151+
152+
case QEvent::MouseButtonRelease:
153+
if (Object == lineEdit())
154+
HandleMouseReleaseEvent(reinterpret_cast<QMouseEvent*>(Event));
155+
break;
156+
157+
default:
158+
break;
159+
}
160+
161+
return QDoubleSpinBox::eventFilter(Object, Event);
162+
}
163+
164+
void lcDoubleSpinBox::mousePressEvent(QMouseEvent* MouseEvent)
165+
{
166+
HandleMousePressEvent(MouseEvent);
167+
168+
QDoubleSpinBox::mousePressEvent(MouseEvent);
169+
}
170+
171+
void lcDoubleSpinBox::mouseMoveEvent(QMouseEvent* MouseEvent)
172+
{
173+
if (!HandleMouseMoveEvent(MouseEvent, this))
174+
QDoubleSpinBox::mouseMoveEvent(MouseEvent);
175+
}
176+
177+
void lcDoubleSpinBox::mouseReleaseEvent(QMouseEvent* MouseEvent)
178+
{
179+
HandleMouseReleaseEvent(MouseEvent);
180+
181+
QDoubleSpinBox::mouseReleaseEvent(MouseEvent);
182+
}
183+
184+
bool lcDoubleSpinBox::event(QEvent* Event)
185+
{
186+
if (Event->type() == QEvent::ShortcutOverride)
187+
{
188+
QKeyEvent* KeyEvent = static_cast<QKeyEvent*>(Event);
189+
190+
if (KeyEvent->key() == Qt::Key_Escape)
191+
{
192+
if (mDragMode == DragMode::Value)
193+
CancelEditing();
194+
195+
mDragMode = DragMode::None;
196+
197+
clearFocus();
198+
KeyEvent->accept();
199+
}
200+
}
201+
202+
return QDoubleSpinBox::event(Event);
203+
}
204+
205+
void lcDoubleSpinBox::focusOutEvent(QFocusEvent* FocusEvent)
206+
{
207+
if (value() != mInitialValue)
208+
CancelEditing();
209+
210+
QDoubleSpinBox::focusOutEvent(FocusEvent);
211+
}

common/lc_doublespinbox.h

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
#pragma once
2+
3+
class lcDoubleSpinBox : public QDoubleSpinBox
4+
{
5+
Q_OBJECT
6+
7+
public:
8+
lcDoubleSpinBox(QWidget* Parent);
9+
virtual ~lcDoubleSpinBox() = default;
10+
11+
void SetValue(double Value);
12+
13+
QString textFromValue(double Value) const override;
14+
bool eventFilter(QObject* Object, QEvent* Event) override;
15+
16+
void mousePressEvent(QMouseEvent* MouseEvent) override;
17+
void mouseMoveEvent(QMouseEvent* MouseEvent) override;
18+
void mouseReleaseEvent(QMouseEvent* MouseEvent) override;
19+
void focusOutEvent(QFocusEvent* FocusEvent) override;
20+
21+
signals:
22+
void EditingCanceled();
23+
void EditingFinished();
24+
25+
protected slots:
26+
void CancelEditing();
27+
void FinishEditing();
28+
void ReturnPressed();
29+
30+
protected:
31+
bool event(QEvent* Event) override;
32+
33+
static QPoint GetGlobalMousePosition(QMouseEvent* MouseEvent)
34+
{
35+
#if (QT_VERSION < QT_VERSION_CHECK(6, 0, 0))
36+
return MouseEvent->globalPos();
37+
#else
38+
return MouseEvent->globalPosition().toPoint();
39+
#endif
40+
}
41+
42+
void HandleMousePressEvent(QMouseEvent* MouseEvent);
43+
bool HandleMouseMoveEvent(QMouseEvent* MouseEvent, QObject* Object);
44+
void HandleMouseReleaseEvent(QMouseEvent* MouseEvent);
45+
46+
enum class DragMode
47+
{
48+
None,
49+
Start,
50+
Value
51+
};
52+
53+
double mInitialValue = 0.0;
54+
QPoint mLastPosition;
55+
DragMode mDragMode = DragMode::None;
56+
};

0 commit comments

Comments
 (0)