Add QStyle::SH_SpinBox_StepModifier style hint
This patch allows the developer to pick which keyboard modifier increases the number of steps a QAbstractSpinBox takes when the user interacts with it. The modifier can be either Qt::ControlModifier (default), Qt::ShiftModifier or Qt::NoModifier. Qt::NoModifier disables the step modifier. Note that on macOS, Control corresponds to the Command key. Holding the modifier increases the step rate when: - scrolling; - pressing the up/down keys; - pressing the spin box up/down buttons. [ChangeLog][QtWidgets][QStyle] QStyle::SH_SpinBox_StepModifier allows the developer to pick which keyboard modifier increases the number of steps a QAbstractSpinBox takes for the following interactions: scrolling, up/down keyboard keys and the spin box buttons. The Qt::ShiftModifier can now be used, or the feature can be disabled using Qt::NoModifier. Previously, only Qt::ControlModifier could be used as the modifier. Change-Id: Ib5518127e86a8f67798a9a1d6e860c6e35896e6f Reviewed-by: Richard Moe Gustavsen <richard.gustavsen@qt.io>
This commit is contained in:
parent
21291d78c5
commit
e40f23f098
@ -5306,6 +5306,9 @@ int QCommonStyle::styleHint(StyleHint sh, const QStyleOption *opt, const QWidget
|
||||
case SH_SpinBox_ButtonsInsideFrame:
|
||||
ret = true;
|
||||
break;
|
||||
case SH_SpinBox_StepModifier:
|
||||
ret = Qt::ControlModifier;
|
||||
break;
|
||||
default:
|
||||
ret = 0;
|
||||
break;
|
||||
|
@ -2001,6 +2001,13 @@ void QStyle::drawItemPixmap(QPainter *painter, const QRect &rect, int alignment,
|
||||
Determnines if the spin box buttons are inside the line edit frame.
|
||||
This enum value has been introduced in Qt 5.11.
|
||||
|
||||
\value SH_SpinBox_StepModifier
|
||||
Determines which Qt::KeyboardModifier increases the step rate of
|
||||
QAbstractSpinBox. Possible values are Qt::NoModifier,
|
||||
Qt::ControlModifier (default) or Qt::ShiftModifier. Qt::NoModifier
|
||||
disables this feature.
|
||||
This enum value has been introduced in Qt 5.12.
|
||||
|
||||
\sa styleHint()
|
||||
*/
|
||||
|
||||
|
@ -741,6 +741,7 @@ public:
|
||||
SH_Widget_Animation_Duration,
|
||||
SH_ComboBox_AllowWheelScrolling,
|
||||
SH_SpinBox_ButtonsInsideFrame,
|
||||
SH_SpinBox_StepModifier,
|
||||
// Add new style hint values here
|
||||
|
||||
SH_CustomBase = 0xf0000000
|
||||
|
@ -106,6 +106,10 @@ QT_BEGIN_NAMESPACE
|
||||
the spinbox buttons. Note that on macOS, Control corresponds to the
|
||||
Command key.
|
||||
|
||||
Since Qt 5.12, QStyle::SH_SpinBox_StepModifier can be used to select
|
||||
which Qt::KeyboardModifier increases the step rate. Qt::NoModifier
|
||||
disables this feature.
|
||||
|
||||
QAbstractSpinBox also provide a virtual function stepEnabled() to
|
||||
determine whether stepping up/down is allowed at any point. This
|
||||
function returns a bitset of StepEnabled.
|
||||
@ -840,6 +844,7 @@ void QAbstractSpinBox::changeEvent(QEvent *event)
|
||||
style()->styleHint(QStyle::SH_SpinBox_ClickAutoRepeatThreshold, 0, this);
|
||||
if (d->edit)
|
||||
d->edit->setFrame(!style()->styleHint(QStyle::SH_SpinBox_ButtonsInsideFrame, nullptr, this));
|
||||
d->stepModifier = static_cast<Qt::KeyboardModifier>(style()->styleHint(QStyle::SH_SpinBox_StepModifier, nullptr, this));
|
||||
d->reset();
|
||||
d->updateEditFieldGeometry();
|
||||
break;
|
||||
|
@ -114,6 +114,26 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
class StepModifierStyle : public QProxyStyle
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
using QProxyStyle::QProxyStyle;
|
||||
|
||||
int styleHint(QStyle::StyleHint hint, const QStyleOption *option = nullptr,
|
||||
const QWidget *widget = nullptr, QStyleHintReturn *returnData = nullptr) const override
|
||||
{
|
||||
switch (hint) {
|
||||
case QStyle::SH_SpinBox_StepModifier:
|
||||
return stepModifier;
|
||||
default:
|
||||
return QProxyStyle::styleHint(hint, option, widget, returnData);
|
||||
}
|
||||
}
|
||||
|
||||
Qt::KeyboardModifier stepModifier = Qt::ControlModifier;
|
||||
};
|
||||
|
||||
class tst_QDateTimeEdit : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
@ -295,6 +315,12 @@ static QLatin1String modifierToName(Qt::KeyboardModifier modifier)
|
||||
case Qt::ShiftModifier:
|
||||
return QLatin1Literal("Shift");
|
||||
break;
|
||||
case Qt::AltModifier:
|
||||
return QLatin1Literal("Alt");
|
||||
break;
|
||||
case Qt::MetaModifier:
|
||||
return QLatin1Literal("Meta");
|
||||
break;
|
||||
default:
|
||||
qFatal("Unexpected keyboard modifier");
|
||||
return QLatin1String();
|
||||
@ -3110,6 +3136,7 @@ void tst_QDateTimeEdit::wheelEvent_data()
|
||||
#if QT_CONFIG(wheelevent)
|
||||
QTest::addColumn<QPoint>("angleDelta");
|
||||
QTest::addColumn<int>("qt4Delta");
|
||||
QTest::addColumn<int>("stepModifier");
|
||||
QTest::addColumn<Qt::KeyboardModifiers>("modifiers");
|
||||
QTest::addColumn<Qt::MouseEventSource>("source");
|
||||
QTest::addColumn<QDateTimeEdit::Section>("section");
|
||||
@ -3121,8 +3148,14 @@ void tst_QDateTimeEdit::wheelEvent_data()
|
||||
const auto directions = {true, false};
|
||||
|
||||
const auto modifierList = {Qt::NoModifier,
|
||||
Qt::ShiftModifier,
|
||||
Qt::ControlModifier,
|
||||
Qt::ShiftModifier};
|
||||
Qt::AltModifier,
|
||||
Qt::MetaModifier};
|
||||
|
||||
const auto validStepModifierList = {Qt::NoModifier,
|
||||
Qt::ControlModifier,
|
||||
Qt::ShiftModifier};
|
||||
|
||||
const auto sources = {Qt::MouseEventNotSynthesized,
|
||||
Qt::MouseEventSynthesizedBySystem,
|
||||
@ -3148,73 +3181,82 @@ void tst_QDateTimeEdit::wheelEvent_data()
|
||||
if (modifierName.isEmpty())
|
||||
continue;
|
||||
|
||||
const int steps = (modifier & Qt::ControlModifier ? 10 : 1)
|
||||
* (up ? 1 : -1);
|
||||
for (auto stepModifier : validStepModifierList) {
|
||||
|
||||
for (auto source : sources) {
|
||||
const auto stepModifierName = modifierToName(stepModifier);
|
||||
if (stepModifierName.isEmpty())
|
||||
continue;
|
||||
|
||||
const int steps = (modifier & stepModifier ? 10 : 1)
|
||||
* (up ? 1 : -1);
|
||||
|
||||
for (auto source : sources) {
|
||||
|
||||
#ifdef Q_OS_MACOS
|
||||
QPoint angleDelta;
|
||||
if ((modifier & Qt::ShiftModifier) &&
|
||||
source == Qt::MouseEventNotSynthesized) {
|
||||
// On macOS the Shift modifier converts vertical
|
||||
// mouse wheel events to horizontal.
|
||||
angleDelta = { units, 0 };
|
||||
} else {
|
||||
// However, this is not the case for trackpad scroll
|
||||
// events.
|
||||
angleDelta = { 0, units };
|
||||
}
|
||||
QPoint angleDelta;
|
||||
if ((modifier & Qt::ShiftModifier) &&
|
||||
source == Qt::MouseEventNotSynthesized) {
|
||||
// On macOS the Shift modifier converts vertical
|
||||
// mouse wheel events to horizontal.
|
||||
angleDelta = { units, 0 };
|
||||
} else {
|
||||
// However, this is not the case for trackpad scroll
|
||||
// events.
|
||||
angleDelta = { 0, units };
|
||||
}
|
||||
#else
|
||||
const QPoint angleDelta(0, units);
|
||||
const QPoint angleDelta(0, units);
|
||||
#endif
|
||||
|
||||
QLatin1String sourceName;
|
||||
switch (source) {
|
||||
case Qt::MouseEventNotSynthesized:
|
||||
sourceName = QLatin1Literal("NotSynthesized");
|
||||
break;
|
||||
case Qt::MouseEventSynthesizedBySystem:
|
||||
sourceName = QLatin1Literal("SynthesizedBySystem");
|
||||
break;
|
||||
case Qt::MouseEventSynthesizedByQt:
|
||||
sourceName = QLatin1Literal("SynthesizedByQt");
|
||||
break;
|
||||
case Qt::MouseEventSynthesizedByApplication:
|
||||
sourceName = QLatin1Literal("SynthesizedByApplication");
|
||||
break;
|
||||
default:
|
||||
qFatal("Unexpected wheel event source");
|
||||
continue;
|
||||
}
|
||||
|
||||
for (const auto section : sections) {
|
||||
|
||||
DateList expectedDates;
|
||||
if (fraction)
|
||||
expectedDates << startDate;
|
||||
|
||||
const auto expectedDate = stepDate(startDate, section, steps);
|
||||
if (!expectedDate.isValid())
|
||||
QLatin1String sourceName;
|
||||
switch (source) {
|
||||
case Qt::MouseEventNotSynthesized:
|
||||
sourceName = QLatin1Literal("NotSynthesized");
|
||||
break;
|
||||
case Qt::MouseEventSynthesizedBySystem:
|
||||
sourceName = QLatin1Literal("SynthesizedBySystem");
|
||||
break;
|
||||
case Qt::MouseEventSynthesizedByQt:
|
||||
sourceName = QLatin1Literal("SynthesizedByQt");
|
||||
break;
|
||||
case Qt::MouseEventSynthesizedByApplication:
|
||||
sourceName = QLatin1Literal("SynthesizedByApplication");
|
||||
break;
|
||||
default:
|
||||
qFatal("Unexpected wheel event source");
|
||||
continue;
|
||||
}
|
||||
|
||||
expectedDates << expectedDate;
|
||||
for (const auto section : sections) {
|
||||
|
||||
const QLatin1String sectionName = sectionToName(section);
|
||||
DateList expectedDates;
|
||||
if (fraction)
|
||||
expectedDates << startDate;
|
||||
|
||||
QTest::addRow("%s%s%sWith%sKeyboardModifier%s",
|
||||
fraction ? "half" : "full",
|
||||
up ? "Up" : "Down",
|
||||
sectionName.latin1(),
|
||||
modifierName.latin1(),
|
||||
sourceName.latin1())
|
||||
<< angleDelta
|
||||
<< units
|
||||
<< modifiers
|
||||
<< source
|
||||
<< section
|
||||
<< startDate
|
||||
<< expectedDates;
|
||||
const auto expectedDate = stepDate(startDate, section, steps);
|
||||
if (!expectedDate.isValid())
|
||||
continue;
|
||||
|
||||
expectedDates << expectedDate;
|
||||
|
||||
const QLatin1String sectionName = sectionToName(section);
|
||||
|
||||
QTest::addRow("%s%s%s%sWith%sKeyboardModifier%s",
|
||||
fraction ? "half" : "full",
|
||||
up ? "Up" : "Down",
|
||||
stepModifierName.latin1(),
|
||||
sectionName.latin1(),
|
||||
modifierName.latin1(),
|
||||
sourceName.latin1())
|
||||
<< angleDelta
|
||||
<< units
|
||||
<< static_cast<int>(stepModifier)
|
||||
<< modifiers
|
||||
<< source
|
||||
<< section
|
||||
<< startDate
|
||||
<< expectedDates;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -3230,6 +3272,7 @@ void tst_QDateTimeEdit::wheelEvent()
|
||||
#if QT_CONFIG(wheelevent)
|
||||
QFETCH(QPoint, angleDelta);
|
||||
QFETCH(int, qt4Delta);
|
||||
QFETCH(int, stepModifier);
|
||||
QFETCH(Qt::KeyboardModifiers, modifiers);
|
||||
QFETCH(Qt::MouseEventSource, source);
|
||||
QFETCH(QDateTimeEdit::Section, section);
|
||||
@ -3240,6 +3283,11 @@ void tst_QDateTimeEdit::wheelEvent()
|
||||
edit.setDate(startDate);
|
||||
edit.setCurrentSection(section);
|
||||
|
||||
QScopedPointer<StepModifierStyle, QScopedPointerDeleteLater> style(
|
||||
new StepModifierStyle);
|
||||
style->stepModifier = static_cast<Qt::KeyboardModifier>(stepModifier);
|
||||
edit.setStyle(style.data());
|
||||
|
||||
QWheelEvent event(QPointF(), QPointF(), QPoint(), angleDelta, qt4Delta,
|
||||
Qt::Vertical, Qt::NoButton, modifiers, Qt::NoScrollPhase,
|
||||
source);
|
||||
@ -3977,6 +4025,7 @@ void tst_QDateTimeEdit::dateEditCorrectSectionSize()
|
||||
void tst_QDateTimeEdit::stepModifierKeys_data()
|
||||
{
|
||||
QTest::addColumn<QDate>("startDate");
|
||||
QTest::addColumn<int>("stepModifier");
|
||||
QTest::addColumn<QDateTimeEdit::Section>("section");
|
||||
QTest::addColumn<QTestEventList>("keys");
|
||||
QTest::addColumn<QDate>("expectedDate");
|
||||
@ -3984,8 +4033,14 @@ void tst_QDateTimeEdit::stepModifierKeys_data()
|
||||
const auto keyList = {Qt::Key_Up, Qt::Key_Down};
|
||||
|
||||
const auto modifierList = {Qt::NoModifier,
|
||||
Qt::ControlModifier,
|
||||
Qt::ShiftModifier};
|
||||
Qt::ShiftModifier,
|
||||
Qt::ControlModifier,
|
||||
Qt::AltModifier,
|
||||
Qt::MetaModifier};
|
||||
|
||||
const auto validStepModifierList = {Qt::NoModifier,
|
||||
Qt::ControlModifier,
|
||||
Qt::ShiftModifier};
|
||||
|
||||
const auto sections = {QDateTimeEdit::DaySection,
|
||||
QDateTimeEdit::MonthSection,
|
||||
@ -4007,25 +4062,34 @@ void tst_QDateTimeEdit::stepModifierKeys_data()
|
||||
if (modifierName.isEmpty())
|
||||
continue;
|
||||
|
||||
const int steps = (modifier & Qt::ControlModifier ? 10 : 1)
|
||||
* (up ? 1 : -1);
|
||||
for (auto stepModifier : validStepModifierList) {
|
||||
|
||||
for (const auto section : sections) {
|
||||
|
||||
const auto expectedDate = stepDate(startDate, section, steps);
|
||||
if (!expectedDate.isValid())
|
||||
const auto stepModifierName = modifierToName(stepModifier);
|
||||
if (stepModifierName.isEmpty())
|
||||
continue;
|
||||
|
||||
const auto sectionName = sectionToName(section);
|
||||
const int steps = (modifier & stepModifier ? 10 : 1)
|
||||
* (up ? 1 : -1);
|
||||
|
||||
QTest::addRow("%s%sWith%sKeyboardModifier",
|
||||
up ? "up" : "down",
|
||||
sectionName.latin1(),
|
||||
modifierName.latin1())
|
||||
<< startDate
|
||||
<< section
|
||||
<< keys
|
||||
<< expectedDate;
|
||||
for (const auto section : sections) {
|
||||
|
||||
const auto expectedDate = stepDate(startDate, section, steps);
|
||||
if (!expectedDate.isValid())
|
||||
continue;
|
||||
|
||||
const auto sectionName = sectionToName(section);
|
||||
|
||||
QTest::addRow("%s%s%sWith%sKeyboardModifier",
|
||||
up ? "up" : "down",
|
||||
stepModifierName.latin1(),
|
||||
sectionName.latin1(),
|
||||
modifierName.latin1())
|
||||
<< startDate
|
||||
<< static_cast<int>(stepModifier)
|
||||
<< section
|
||||
<< keys
|
||||
<< expectedDate;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -4034,6 +4098,7 @@ void tst_QDateTimeEdit::stepModifierKeys_data()
|
||||
void tst_QDateTimeEdit::stepModifierKeys()
|
||||
{
|
||||
QFETCH(QDate, startDate);
|
||||
QFETCH(int, stepModifier);
|
||||
QFETCH(QDateTimeEdit::Section, section);
|
||||
QFETCH(QTestEventList, keys);
|
||||
QFETCH(QDate, expectedDate);
|
||||
@ -4044,6 +4109,11 @@ void tst_QDateTimeEdit::stepModifierKeys()
|
||||
QVERIFY(QTest::qWaitForWindowActive(&edit));
|
||||
edit.setCurrentSection(section);
|
||||
|
||||
QScopedPointer<StepModifierStyle, QScopedPointerDeleteLater> style(
|
||||
new StepModifierStyle);
|
||||
style->stepModifier = static_cast<Qt::KeyboardModifier>(stepModifier);
|
||||
edit.setStyle(style.data());
|
||||
|
||||
QCOMPARE(edit.date(), startDate);
|
||||
keys.simulate(&edit);
|
||||
QCOMPARE(edit.date(), expectedDate);
|
||||
@ -4052,6 +4122,7 @@ void tst_QDateTimeEdit::stepModifierKeys()
|
||||
void tst_QDateTimeEdit::stepModifierButtons_data()
|
||||
{
|
||||
QTest::addColumn<QStyle::SubControl>("subControl");
|
||||
QTest::addColumn<int>("stepModifier");
|
||||
QTest::addColumn<Qt::KeyboardModifiers>("modifiers");
|
||||
QTest::addColumn<QDateTimeEdit::Section>("section");
|
||||
QTest::addColumn<QTime>("startTime");
|
||||
@ -4060,8 +4131,14 @@ void tst_QDateTimeEdit::stepModifierButtons_data()
|
||||
const auto subControls = {QStyle::SC_SpinBoxUp, QStyle::SC_SpinBoxDown};
|
||||
|
||||
const auto modifierList = {Qt::NoModifier,
|
||||
Qt::ControlModifier,
|
||||
Qt::ShiftModifier};
|
||||
Qt::ShiftModifier,
|
||||
Qt::ControlModifier,
|
||||
Qt::AltModifier,
|
||||
Qt::MetaModifier};
|
||||
|
||||
const auto validStepModifierList = {Qt::NoModifier,
|
||||
Qt::ControlModifier,
|
||||
Qt::ShiftModifier};
|
||||
|
||||
const auto sections = {QDateTimeEdit::SecondSection,
|
||||
QDateTimeEdit::MinuteSection,
|
||||
@ -4082,26 +4159,35 @@ void tst_QDateTimeEdit::stepModifierButtons_data()
|
||||
if (modifierName.isEmpty())
|
||||
continue;
|
||||
|
||||
const int steps = (modifier & Qt::ControlModifier ? 10 : 1)
|
||||
* (up ? 1 : -1);
|
||||
for (auto stepModifier : validStepModifierList) {
|
||||
|
||||
for (const auto section : sections) {
|
||||
|
||||
const auto expectedTime = stepTime(startTime, section, steps);
|
||||
if (!expectedTime.isValid())
|
||||
const auto stepModifierName = modifierToName(stepModifier);
|
||||
if (stepModifierName.isEmpty())
|
||||
continue;
|
||||
|
||||
const auto sectionName = sectionToName(section);
|
||||
const int steps = (modifier & stepModifier ? 10 : 1)
|
||||
* (up ? 1 : -1);
|
||||
|
||||
QTest::addRow("%s%sWith%sKeyboardModifier",
|
||||
up ? "up" : "down",
|
||||
sectionName.latin1(),
|
||||
modifierName.latin1())
|
||||
<< subControl
|
||||
<< modifiers
|
||||
<< section
|
||||
<< startTime
|
||||
<< expectedTime;
|
||||
for (const auto section : sections) {
|
||||
|
||||
const auto expectedTime = stepTime(startTime, section, steps);
|
||||
if (!expectedTime.isValid())
|
||||
continue;
|
||||
|
||||
const auto sectionName = sectionToName(section);
|
||||
|
||||
QTest::addRow("%s%s%sWith%sKeyboardModifier",
|
||||
up ? "up" : "down",
|
||||
stepModifierName.latin1(),
|
||||
sectionName.latin1(),
|
||||
modifierName.latin1())
|
||||
<< subControl
|
||||
<< static_cast<int>(stepModifier)
|
||||
<< modifiers
|
||||
<< section
|
||||
<< startTime
|
||||
<< expectedTime;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -4110,6 +4196,7 @@ void tst_QDateTimeEdit::stepModifierButtons_data()
|
||||
void tst_QDateTimeEdit::stepModifierButtons()
|
||||
{
|
||||
QFETCH(QStyle::SubControl, subControl);
|
||||
QFETCH(int, stepModifier);
|
||||
QFETCH(Qt::KeyboardModifiers, modifiers);
|
||||
QFETCH(QDateTimeEdit::Section, section);
|
||||
QFETCH(QTime, startTime);
|
||||
@ -4121,6 +4208,11 @@ void tst_QDateTimeEdit::stepModifierButtons()
|
||||
QVERIFY(QTest::qWaitForWindowActive(&edit));
|
||||
edit.setCurrentSection(section);
|
||||
|
||||
QScopedPointer<StepModifierStyle, QScopedPointerDeleteLater> style(
|
||||
new StepModifierStyle);
|
||||
style->stepModifier = static_cast<Qt::KeyboardModifier>(stepModifier);
|
||||
edit.setStyle(style.data());
|
||||
|
||||
QStyleOptionSpinBox spinBoxStyleOption;
|
||||
edit.initStyleOption(&spinBoxStyleOption);
|
||||
|
||||
@ -4135,14 +4227,21 @@ void tst_QDateTimeEdit::stepModifierButtons()
|
||||
void tst_QDateTimeEdit::stepModifierPressAndHold_data()
|
||||
{
|
||||
QTest::addColumn<QStyle::SubControl>("subControl");
|
||||
QTest::addColumn<int>("stepModifier");
|
||||
QTest::addColumn<Qt::KeyboardModifiers>("modifiers");
|
||||
QTest::addColumn<int>("expectedStepModifier");
|
||||
|
||||
const auto subControls = {QStyle::SC_SpinBoxUp, QStyle::SC_SpinBoxDown};
|
||||
|
||||
const auto modifierList = {Qt::NoModifier,
|
||||
Qt::ShiftModifier,
|
||||
Qt::ControlModifier,
|
||||
Qt::ShiftModifier};
|
||||
Qt::AltModifier,
|
||||
Qt::MetaModifier};
|
||||
|
||||
const auto validStepModifierList = {Qt::NoModifier,
|
||||
Qt::ControlModifier,
|
||||
Qt::ShiftModifier};
|
||||
|
||||
for (auto subControl : subControls) {
|
||||
|
||||
@ -4157,15 +4256,24 @@ void tst_QDateTimeEdit::stepModifierPressAndHold_data()
|
||||
if (modifierName.isEmpty())
|
||||
continue;
|
||||
|
||||
const int steps = (modifier & Qt::ControlModifier ? 10 : 1)
|
||||
* (up ? 1 : -1);
|
||||
for (auto stepModifier : validStepModifierList) {
|
||||
|
||||
QTest::addRow("%sWith%sKeyboardModifier",
|
||||
up ? "up" : "down",
|
||||
modifierName.latin1())
|
||||
<< subControl
|
||||
<< modifiers
|
||||
<< steps;
|
||||
const auto stepModifierName = modifierToName(stepModifier);
|
||||
if (stepModifierName.isEmpty())
|
||||
continue;
|
||||
|
||||
const int steps = (modifier & stepModifier ? 10 : 1)
|
||||
* (up ? 1 : -1);
|
||||
|
||||
QTest::addRow("%s%sWith%sKeyboardModifier",
|
||||
up ? "up" : "down",
|
||||
stepModifierName.latin1(),
|
||||
modifierName.latin1())
|
||||
<< subControl
|
||||
<< static_cast<int>(stepModifier)
|
||||
<< modifiers
|
||||
<< steps;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -4173,17 +4281,20 @@ void tst_QDateTimeEdit::stepModifierPressAndHold_data()
|
||||
void tst_QDateTimeEdit::stepModifierPressAndHold()
|
||||
{
|
||||
QFETCH(QStyle::SubControl, subControl);
|
||||
QFETCH(int, stepModifier);
|
||||
QFETCH(Qt::KeyboardModifiers, modifiers);
|
||||
QFETCH(int, expectedStepModifier);
|
||||
|
||||
const QDate startDate(2000, 1, 1);
|
||||
|
||||
EditorDateEdit edit(0);
|
||||
QScopedPointer<PressAndHoldStyle, QScopedPointerDeleteLater> pressAndHoldStyle(
|
||||
new PressAndHoldStyle);
|
||||
edit.setStyle(pressAndHoldStyle.data());
|
||||
edit.setDate(startDate);
|
||||
|
||||
QScopedPointer<StepModifierStyle, QScopedPointerDeleteLater> stepModifierStyle(
|
||||
new StepModifierStyle(new PressAndHoldStyle));
|
||||
stepModifierStyle->stepModifier = static_cast<Qt::KeyboardModifier>(stepModifier);
|
||||
edit.setStyle(stepModifierStyle.data());
|
||||
|
||||
QSignalSpy spy(&edit, &EditorDateEdit::dateChanged);
|
||||
|
||||
edit.show();
|
||||
|
@ -103,6 +103,26 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
class StepModifierStyle : public QProxyStyle
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
using QProxyStyle::QProxyStyle;
|
||||
|
||||
int styleHint(QStyle::StyleHint hint, const QStyleOption *option = nullptr,
|
||||
const QWidget *widget = nullptr, QStyleHintReturn *returnData = nullptr) const override
|
||||
{
|
||||
switch (hint) {
|
||||
case QStyle::SH_SpinBox_StepModifier:
|
||||
return stepModifier;
|
||||
default:
|
||||
return QProxyStyle::styleHint(hint, option, widget, returnData);
|
||||
}
|
||||
}
|
||||
|
||||
Qt::KeyboardModifier stepModifier = Qt::ControlModifier;
|
||||
};
|
||||
|
||||
|
||||
class tst_QDoubleSpinBox : public QObject
|
||||
{
|
||||
@ -209,6 +229,12 @@ static QLatin1String modifierToName(Qt::KeyboardModifier modifier)
|
||||
case Qt::ShiftModifier:
|
||||
return QLatin1Literal("Shift");
|
||||
break;
|
||||
case Qt::AltModifier:
|
||||
return QLatin1Literal("Alt");
|
||||
break;
|
||||
case Qt::MetaModifier:
|
||||
return QLatin1Literal("Meta");
|
||||
break;
|
||||
default:
|
||||
qFatal("Unexpected keyboard modifier");
|
||||
return QLatin1String();
|
||||
@ -1338,6 +1364,7 @@ void tst_QDoubleSpinBox::wheelEvents_data()
|
||||
#if QT_CONFIG(wheelevent)
|
||||
QTest::addColumn<QPoint>("angleDelta");
|
||||
QTest::addColumn<int>("qt4Delta");
|
||||
QTest::addColumn<int>("stepModifier");
|
||||
QTest::addColumn<Qt::KeyboardModifiers>("modifier");
|
||||
QTest::addColumn<Qt::MouseEventSource>("source");
|
||||
QTest::addColumn<double>("start");
|
||||
@ -1348,8 +1375,14 @@ void tst_QDoubleSpinBox::wheelEvents_data()
|
||||
const auto directions = {true, false};
|
||||
|
||||
const auto modifierList = {Qt::NoModifier,
|
||||
Qt::ShiftModifier,
|
||||
Qt::ControlModifier,
|
||||
Qt::ShiftModifier};
|
||||
Qt::AltModifier,
|
||||
Qt::MetaModifier};
|
||||
|
||||
const auto validStepModifierList = {Qt::NoModifier,
|
||||
Qt::ControlModifier,
|
||||
Qt::ShiftModifier};
|
||||
|
||||
const auto sources = {Qt::MouseEventNotSynthesized,
|
||||
Qt::MouseEventSynthesizedBySystem,
|
||||
@ -1371,62 +1404,71 @@ void tst_QDoubleSpinBox::wheelEvents_data()
|
||||
if (modifierName.isEmpty())
|
||||
continue;
|
||||
|
||||
const int steps = (modifier & Qt::ControlModifier ? 10 : 1)
|
||||
* (up ? 1 : -1);
|
||||
for (auto stepModifier : validStepModifierList) {
|
||||
|
||||
for (auto source : sources) {
|
||||
const auto stepModifierName = modifierToName(stepModifier);
|
||||
if (stepModifierName.isEmpty())
|
||||
continue;
|
||||
|
||||
const int steps = (modifier & stepModifier ? 10 : 1)
|
||||
* (up ? 1 : -1);
|
||||
|
||||
for (auto source : sources) {
|
||||
|
||||
#ifdef Q_OS_MACOS
|
||||
QPoint angleDelta;
|
||||
if ((modifier & Qt::ShiftModifier) &&
|
||||
source == Qt::MouseEventNotSynthesized) {
|
||||
// On macOS the Shift modifier converts vertical
|
||||
// mouse wheel events to horizontal.
|
||||
angleDelta = { units, 0 };
|
||||
} else {
|
||||
// However, this is not the case for trackpad scroll
|
||||
// events.
|
||||
angleDelta = { 0, units };
|
||||
}
|
||||
QPoint angleDelta;
|
||||
if ((modifier & Qt::ShiftModifier) &&
|
||||
source == Qt::MouseEventNotSynthesized) {
|
||||
// On macOS the Shift modifier converts vertical
|
||||
// mouse wheel events to horizontal.
|
||||
angleDelta = { units, 0 };
|
||||
} else {
|
||||
// However, this is not the case for trackpad scroll
|
||||
// events.
|
||||
angleDelta = { 0, units };
|
||||
}
|
||||
#else
|
||||
const QPoint angleDelta(0, units);
|
||||
const QPoint angleDelta(0, units);
|
||||
#endif
|
||||
|
||||
QLatin1String sourceName;
|
||||
switch (source) {
|
||||
case Qt::MouseEventNotSynthesized:
|
||||
sourceName = QLatin1Literal("NotSynthesized");
|
||||
break;
|
||||
case Qt::MouseEventSynthesizedBySystem:
|
||||
sourceName = QLatin1Literal("SynthesizedBySystem");
|
||||
break;
|
||||
case Qt::MouseEventSynthesizedByQt:
|
||||
sourceName = QLatin1Literal("SynthesizedByQt");
|
||||
break;
|
||||
case Qt::MouseEventSynthesizedByApplication:
|
||||
sourceName = QLatin1Literal("SynthesizedByApplication");
|
||||
break;
|
||||
default:
|
||||
qFatal("Unexpected wheel event source");
|
||||
continue;
|
||||
QLatin1String sourceName;
|
||||
switch (source) {
|
||||
case Qt::MouseEventNotSynthesized:
|
||||
sourceName = QLatin1Literal("NotSynthesized");
|
||||
break;
|
||||
case Qt::MouseEventSynthesizedBySystem:
|
||||
sourceName = QLatin1Literal("SynthesizedBySystem");
|
||||
break;
|
||||
case Qt::MouseEventSynthesizedByQt:
|
||||
sourceName = QLatin1Literal("SynthesizedByQt");
|
||||
break;
|
||||
case Qt::MouseEventSynthesizedByApplication:
|
||||
sourceName = QLatin1Literal("SynthesizedByApplication");
|
||||
break;
|
||||
default:
|
||||
qFatal("Unexpected wheel event source");
|
||||
continue;
|
||||
}
|
||||
|
||||
DoubleList expectedValues;
|
||||
if (fraction)
|
||||
expectedValues << startValue;
|
||||
expectedValues << startValue + steps;
|
||||
|
||||
QTest::addRow("%s%s%sWith%sKeyboardModifier%s",
|
||||
fraction ? "half" : "full",
|
||||
up ? "Up" : "Down",
|
||||
stepModifierName.latin1(),
|
||||
modifierName.latin1(),
|
||||
sourceName.latin1())
|
||||
<< angleDelta
|
||||
<< units
|
||||
<< static_cast<int>(stepModifier)
|
||||
<< modifiers
|
||||
<< source
|
||||
<< startValue
|
||||
<< expectedValues;
|
||||
}
|
||||
|
||||
DoubleList expectedValues;
|
||||
if (fraction)
|
||||
expectedValues << startValue;
|
||||
expectedValues << startValue + steps;
|
||||
|
||||
QTest::addRow("%s%sWith%sKeyboardModifier%s",
|
||||
fraction ? "half" : "full",
|
||||
up ? "Up" : "Down",
|
||||
modifierName.latin1(),
|
||||
sourceName.latin1())
|
||||
<< angleDelta
|
||||
<< units
|
||||
<< modifiers
|
||||
<< source
|
||||
<< startValue
|
||||
<< expectedValues;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1441,6 +1483,7 @@ void tst_QDoubleSpinBox::wheelEvents()
|
||||
#if QT_CONFIG(wheelevent)
|
||||
QFETCH(QPoint, angleDelta);
|
||||
QFETCH(int, qt4Delta);
|
||||
QFETCH(int, stepModifier);
|
||||
QFETCH(Qt::KeyboardModifiers, modifier);
|
||||
QFETCH(Qt::MouseEventSource, source);
|
||||
QFETCH(double, start);
|
||||
@ -1450,6 +1493,11 @@ void tst_QDoubleSpinBox::wheelEvents()
|
||||
spinBox.setRange(-20, 20);
|
||||
spinBox.setValue(start);
|
||||
|
||||
QScopedPointer<StepModifierStyle, QScopedPointerDeleteLater> style(
|
||||
new StepModifierStyle);
|
||||
style->stepModifier = static_cast<Qt::KeyboardModifier>(stepModifier);
|
||||
spinBox.setStyle(style.data());
|
||||
|
||||
QWheelEvent event(QPointF(), QPointF(), QPoint(), angleDelta, qt4Delta,
|
||||
Qt::Vertical, Qt::NoButton, modifier, Qt::NoScrollPhase,
|
||||
source);
|
||||
@ -1465,14 +1513,22 @@ void tst_QDoubleSpinBox::wheelEvents()
|
||||
void tst_QDoubleSpinBox::stepModifierKeys_data()
|
||||
{
|
||||
QTest::addColumn<double>("startValue");
|
||||
QTest::addColumn<int>("stepModifier");
|
||||
QTest::addColumn<QTestEventList>("keys");
|
||||
QTest::addColumn<double>("expectedValue");
|
||||
|
||||
const auto keyList = {Qt::Key_Up, Qt::Key_Down};
|
||||
|
||||
const auto modifierList = {Qt::NoModifier,
|
||||
Qt::ShiftModifier,
|
||||
Qt::ControlModifier,
|
||||
Qt::ShiftModifier};
|
||||
Qt::AltModifier,
|
||||
Qt::MetaModifier};
|
||||
|
||||
const auto validStepModifierList = {Qt::NoModifier,
|
||||
Qt::ControlModifier,
|
||||
Qt::ShiftModifier};
|
||||
|
||||
|
||||
for (auto key : keyList) {
|
||||
|
||||
@ -1490,17 +1546,26 @@ void tst_QDoubleSpinBox::stepModifierKeys_data()
|
||||
if (modifierName.isEmpty())
|
||||
continue;
|
||||
|
||||
const int steps = (modifier & Qt::ControlModifier ? 10 : 1)
|
||||
* (up ? 1 : -1);
|
||||
for (auto stepModifier : validStepModifierList) {
|
||||
|
||||
const double expectedValue = startValue + steps;
|
||||
const auto stepModifierName = modifierToName(stepModifier);
|
||||
if (stepModifierName.isEmpty())
|
||||
continue;
|
||||
|
||||
QTest::addRow("%sWith%sKeyboardModifier",
|
||||
up ? "up" : "down",
|
||||
modifierName.latin1())
|
||||
<< startValue
|
||||
<< keys
|
||||
<< expectedValue;
|
||||
const int steps = (modifier & stepModifier ? 10 : 1)
|
||||
* (up ? 1 : -1);
|
||||
|
||||
const double expectedValue = startValue + steps;
|
||||
|
||||
QTest::addRow("%s%sWith%sKeyboardModifier",
|
||||
up ? "up" : "down",
|
||||
stepModifierName.latin1(),
|
||||
modifierName.latin1())
|
||||
<< startValue
|
||||
<< static_cast<int>(stepModifier)
|
||||
<< keys
|
||||
<< expectedValue;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1508,11 +1573,18 @@ void tst_QDoubleSpinBox::stepModifierKeys_data()
|
||||
void tst_QDoubleSpinBox::stepModifierKeys()
|
||||
{
|
||||
QFETCH(double, startValue);
|
||||
QFETCH(int, stepModifier);
|
||||
QFETCH(QTestEventList, keys);
|
||||
QFETCH(double, expectedValue);
|
||||
|
||||
QDoubleSpinBox spin(0);
|
||||
spin.setValue(startValue);
|
||||
|
||||
QScopedPointer<StepModifierStyle, QScopedPointerDeleteLater> style(
|
||||
new StepModifierStyle);
|
||||
style->stepModifier = static_cast<Qt::KeyboardModifier>(stepModifier);
|
||||
spin.setStyle(style.data());
|
||||
|
||||
spin.show();
|
||||
QVERIFY(QTest::qWaitForWindowActive(&spin));
|
||||
|
||||
@ -1524,6 +1596,7 @@ void tst_QDoubleSpinBox::stepModifierKeys()
|
||||
void tst_QDoubleSpinBox::stepModifierButtons_data()
|
||||
{
|
||||
QTest::addColumn<QStyle::SubControl>("subControl");
|
||||
QTest::addColumn<int>("stepModifier");
|
||||
QTest::addColumn<Qt::KeyboardModifiers>("modifiers");
|
||||
QTest::addColumn<double>("startValue");
|
||||
QTest::addColumn<double>("expectedValue");
|
||||
@ -1531,8 +1604,14 @@ void tst_QDoubleSpinBox::stepModifierButtons_data()
|
||||
const auto subControls = {QStyle::SC_SpinBoxUp, QStyle::SC_SpinBoxDown};
|
||||
|
||||
const auto modifierList = {Qt::NoModifier,
|
||||
Qt::ControlModifier,
|
||||
Qt::ShiftModifier};
|
||||
Qt::ShiftModifier,
|
||||
Qt::ControlModifier,
|
||||
Qt::AltModifier,
|
||||
Qt::MetaModifier};
|
||||
|
||||
const auto validStepModifierList = {Qt::NoModifier,
|
||||
Qt::ControlModifier,
|
||||
Qt::ShiftModifier};
|
||||
|
||||
for (auto subControl : subControls) {
|
||||
|
||||
@ -1549,18 +1628,27 @@ void tst_QDoubleSpinBox::stepModifierButtons_data()
|
||||
if (modifierName.isEmpty())
|
||||
continue;
|
||||
|
||||
const int steps = (modifier & Qt::ControlModifier ? 10 : 1)
|
||||
* (up ? 1 : -1);
|
||||
for (auto stepModifier : validStepModifierList) {
|
||||
|
||||
const double expectedValue = startValue + steps;
|
||||
const auto stepModifierName = modifierToName(stepModifier);
|
||||
if (stepModifierName.isEmpty())
|
||||
continue;
|
||||
|
||||
QTest::addRow("%sWith%sKeyboardModifier",
|
||||
up ? "up" : "down",
|
||||
modifierName.latin1())
|
||||
<< subControl
|
||||
<< modifiers
|
||||
<< startValue
|
||||
<< expectedValue;
|
||||
const int steps = (modifier & stepModifier ? 10 : 1)
|
||||
* (up ? 1 : -1);
|
||||
|
||||
const double expectedValue = startValue + steps;
|
||||
|
||||
QTest::addRow("%s%sWith%sKeyboardModifier",
|
||||
up ? "up" : "down",
|
||||
stepModifierName.latin1(),
|
||||
modifierName.latin1())
|
||||
<< subControl
|
||||
<< static_cast<int>(stepModifier)
|
||||
<< modifiers
|
||||
<< startValue
|
||||
<< expectedValue;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1568,6 +1656,7 @@ void tst_QDoubleSpinBox::stepModifierButtons_data()
|
||||
void tst_QDoubleSpinBox::stepModifierButtons()
|
||||
{
|
||||
QFETCH(QStyle::SubControl, subControl);
|
||||
QFETCH(int, stepModifier);
|
||||
QFETCH(Qt::KeyboardModifiers, modifiers);
|
||||
QFETCH(double, startValue);
|
||||
QFETCH(double, expectedValue);
|
||||
@ -1575,6 +1664,12 @@ void tst_QDoubleSpinBox::stepModifierButtons()
|
||||
DoubleSpinBox spin(0);
|
||||
spin.setRange(-20, 20);
|
||||
spin.setValue(startValue);
|
||||
|
||||
QScopedPointer<StepModifierStyle, QScopedPointerDeleteLater> style(
|
||||
new StepModifierStyle);
|
||||
style->stepModifier = static_cast<Qt::KeyboardModifier>(stepModifier);
|
||||
spin.setStyle(style.data());
|
||||
|
||||
spin.show();
|
||||
QVERIFY(QTest::qWaitForWindowActive(&spin));
|
||||
|
||||
@ -1592,14 +1687,21 @@ void tst_QDoubleSpinBox::stepModifierButtons()
|
||||
void tst_QDoubleSpinBox::stepModifierPressAndHold_data()
|
||||
{
|
||||
QTest::addColumn<QStyle::SubControl>("subControl");
|
||||
QTest::addColumn<int>("stepModifier");
|
||||
QTest::addColumn<Qt::KeyboardModifiers>("modifiers");
|
||||
QTest::addColumn<int>("expectedStepModifier");
|
||||
|
||||
const auto subControls = {QStyle::SC_SpinBoxUp, QStyle::SC_SpinBoxDown};
|
||||
|
||||
const auto modifierList = {Qt::NoModifier,
|
||||
Qt::ShiftModifier,
|
||||
Qt::ControlModifier,
|
||||
Qt::ShiftModifier};
|
||||
Qt::AltModifier,
|
||||
Qt::MetaModifier};
|
||||
|
||||
const auto validStepModifierList = {Qt::NoModifier,
|
||||
Qt::ControlModifier,
|
||||
Qt::ShiftModifier};
|
||||
|
||||
for (auto subControl : subControls) {
|
||||
|
||||
@ -1614,15 +1716,24 @@ void tst_QDoubleSpinBox::stepModifierPressAndHold_data()
|
||||
if (modifierName.isEmpty())
|
||||
continue;
|
||||
|
||||
const int steps = (modifier & Qt::ControlModifier ? 10 : 1)
|
||||
* (up ? 1 : -1);
|
||||
for (auto stepModifier : validStepModifierList) {
|
||||
|
||||
QTest::addRow("%sWith%sKeyboardModifier",
|
||||
up ? "up" : "down",
|
||||
modifierName.latin1())
|
||||
<< subControl
|
||||
<< modifiers
|
||||
<< steps;
|
||||
const auto stepModifierName = modifierToName(stepModifier);
|
||||
if (stepModifierName.isEmpty())
|
||||
continue;
|
||||
|
||||
const int steps = (modifier & stepModifier ? 10 : 1)
|
||||
* (up ? 1 : -1);
|
||||
|
||||
QTest::addRow("%s%sWith%sKeyboardModifier",
|
||||
up ? "up" : "down",
|
||||
stepModifierName.latin1(),
|
||||
modifierName.latin1())
|
||||
<< subControl
|
||||
<< static_cast<int>(stepModifier)
|
||||
<< modifiers
|
||||
<< steps;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1630,16 +1741,19 @@ void tst_QDoubleSpinBox::stepModifierPressAndHold_data()
|
||||
void tst_QDoubleSpinBox::stepModifierPressAndHold()
|
||||
{
|
||||
QFETCH(QStyle::SubControl, subControl);
|
||||
QFETCH(int, stepModifier);
|
||||
QFETCH(Qt::KeyboardModifiers, modifiers);
|
||||
QFETCH(int, expectedStepModifier);
|
||||
|
||||
DoubleSpinBox spin(0);
|
||||
QScopedPointer<PressAndHoldStyle, QScopedPointerDeleteLater> pressAndHoldStyle(
|
||||
new PressAndHoldStyle);
|
||||
spin.setStyle(pressAndHoldStyle.data());
|
||||
spin.setRange(-100.0, 100.0);
|
||||
spin.setValue(0.0);
|
||||
|
||||
QScopedPointer<StepModifierStyle, QScopedPointerDeleteLater> stepModifierStyle(
|
||||
new StepModifierStyle(new PressAndHoldStyle));
|
||||
stepModifierStyle->stepModifier = static_cast<Qt::KeyboardModifier>(stepModifier);
|
||||
spin.setStyle(stepModifierStyle.data());
|
||||
|
||||
QSignalSpy spy(&spin, QOverload<double>::of(&DoubleSpinBox::valueChanged));
|
||||
|
||||
spin.show();
|
||||
|
@ -106,6 +106,26 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
class StepModifierStyle : public QProxyStyle
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
using QProxyStyle::QProxyStyle;
|
||||
|
||||
int styleHint(QStyle::StyleHint hint, const QStyleOption *option = nullptr,
|
||||
const QWidget *widget = nullptr, QStyleHintReturn *returnData = nullptr) const override
|
||||
{
|
||||
switch (hint) {
|
||||
case QStyle::SH_SpinBox_StepModifier:
|
||||
return stepModifier;
|
||||
default:
|
||||
return QProxyStyle::styleHint(hint, option, widget, returnData);
|
||||
}
|
||||
}
|
||||
|
||||
Qt::KeyboardModifier stepModifier = Qt::ControlModifier;
|
||||
};
|
||||
|
||||
class tst_QSpinBox : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
@ -208,6 +228,12 @@ static QLatin1String modifierToName(Qt::KeyboardModifier modifier)
|
||||
case Qt::ShiftModifier:
|
||||
return QLatin1Literal("Shift");
|
||||
break;
|
||||
case Qt::AltModifier:
|
||||
return QLatin1Literal("Alt");
|
||||
break;
|
||||
case Qt::MetaModifier:
|
||||
return QLatin1Literal("Meta");
|
||||
break;
|
||||
default:
|
||||
qFatal("Unexpected keyboard modifier");
|
||||
return QLatin1String();
|
||||
@ -1280,6 +1306,7 @@ void tst_QSpinBox::wheelEvents_data()
|
||||
#if QT_CONFIG(wheelevent)
|
||||
QTest::addColumn<QPoint>("angleDelta");
|
||||
QTest::addColumn<int>("qt4Delta");
|
||||
QTest::addColumn<int>("stepModifier");
|
||||
QTest::addColumn<Qt::KeyboardModifiers>("modifier");
|
||||
QTest::addColumn<Qt::MouseEventSource>("source");
|
||||
QTest::addColumn<int>("start");
|
||||
@ -1290,8 +1317,14 @@ void tst_QSpinBox::wheelEvents_data()
|
||||
const auto directions = {true, false};
|
||||
|
||||
const auto modifierList = {Qt::NoModifier,
|
||||
Qt::ShiftModifier,
|
||||
Qt::ControlModifier,
|
||||
Qt::ShiftModifier};
|
||||
Qt::AltModifier,
|
||||
Qt::MetaModifier};
|
||||
|
||||
const auto validStepModifierList = {Qt::NoModifier,
|
||||
Qt::ControlModifier,
|
||||
Qt::ShiftModifier};
|
||||
|
||||
const auto sources = {Qt::MouseEventNotSynthesized,
|
||||
Qt::MouseEventSynthesizedBySystem,
|
||||
@ -1313,62 +1346,71 @@ void tst_QSpinBox::wheelEvents_data()
|
||||
if (modifierName.isEmpty())
|
||||
continue;
|
||||
|
||||
const int steps = (modifier & Qt::ControlModifier ? 10 : 1)
|
||||
* (up ? 1 : -1);
|
||||
for (auto stepModifier : validStepModifierList) {
|
||||
|
||||
for (auto source : sources) {
|
||||
const auto stepModifierName = modifierToName(stepModifier);
|
||||
if (stepModifierName.isEmpty())
|
||||
continue;
|
||||
|
||||
const int steps = (modifier & stepModifier ? 10 : 1)
|
||||
* (up ? 1 : -1);
|
||||
|
||||
for (auto source : sources) {
|
||||
|
||||
#ifdef Q_OS_MACOS
|
||||
QPoint angleDelta;
|
||||
if ((modifier & Qt::ShiftModifier) &&
|
||||
source == Qt::MouseEventNotSynthesized) {
|
||||
// On macOS the Shift modifier converts vertical
|
||||
// mouse wheel events to horizontal.
|
||||
angleDelta = { units, 0 };
|
||||
} else {
|
||||
// However, this is not the case for trackpad scroll
|
||||
// events.
|
||||
angleDelta = { 0, units };
|
||||
}
|
||||
QPoint angleDelta;
|
||||
if ((modifier & Qt::ShiftModifier) &&
|
||||
source == Qt::MouseEventNotSynthesized) {
|
||||
// On macOS the Shift modifier converts vertical
|
||||
// mouse wheel events to horizontal.
|
||||
angleDelta = { units, 0 };
|
||||
} else {
|
||||
// However, this is not the case for trackpad scroll
|
||||
// events.
|
||||
angleDelta = { 0, units };
|
||||
}
|
||||
#else
|
||||
const QPoint angleDelta(0, units);
|
||||
const QPoint angleDelta(0, units);
|
||||
#endif
|
||||
|
||||
QLatin1String sourceName;
|
||||
switch (source) {
|
||||
case Qt::MouseEventNotSynthesized:
|
||||
sourceName = QLatin1Literal("NotSynthesized");
|
||||
break;
|
||||
case Qt::MouseEventSynthesizedBySystem:
|
||||
sourceName = QLatin1Literal("SynthesizedBySystem");
|
||||
break;
|
||||
case Qt::MouseEventSynthesizedByQt:
|
||||
sourceName = QLatin1Literal("SynthesizedByQt");
|
||||
break;
|
||||
case Qt::MouseEventSynthesizedByApplication:
|
||||
sourceName = QLatin1Literal("SynthesizedByApplication");
|
||||
break;
|
||||
default:
|
||||
qFatal("Unexpected wheel event source");
|
||||
continue;
|
||||
QLatin1String sourceName;
|
||||
switch (source) {
|
||||
case Qt::MouseEventNotSynthesized:
|
||||
sourceName = QLatin1Literal("NotSynthesized");
|
||||
break;
|
||||
case Qt::MouseEventSynthesizedBySystem:
|
||||
sourceName = QLatin1Literal("SynthesizedBySystem");
|
||||
break;
|
||||
case Qt::MouseEventSynthesizedByQt:
|
||||
sourceName = QLatin1Literal("SynthesizedByQt");
|
||||
break;
|
||||
case Qt::MouseEventSynthesizedByApplication:
|
||||
sourceName = QLatin1Literal("SynthesizedByApplication");
|
||||
break;
|
||||
default:
|
||||
qFatal("Unexpected wheel event source");
|
||||
continue;
|
||||
}
|
||||
|
||||
IntList expectedValues;
|
||||
if (fraction)
|
||||
expectedValues << startValue;
|
||||
expectedValues << startValue + steps;
|
||||
|
||||
QTest::addRow("%s%s%sWith%sKeyboardModifier%s",
|
||||
fraction ? "half" : "full",
|
||||
up ? "Up" : "Down",
|
||||
stepModifierName.latin1(),
|
||||
modifierName.latin1(),
|
||||
sourceName.latin1())
|
||||
<< angleDelta
|
||||
<< units
|
||||
<< static_cast<int>(stepModifier)
|
||||
<< modifiers
|
||||
<< source
|
||||
<< startValue
|
||||
<< expectedValues;
|
||||
}
|
||||
|
||||
IntList expectedValues;
|
||||
if (fraction)
|
||||
expectedValues << startValue;
|
||||
expectedValues << startValue + steps;
|
||||
|
||||
QTest::addRow("%s%sWith%sKeyboardModifier%s",
|
||||
fraction ? "half" : "full",
|
||||
up ? "Up" : "Down",
|
||||
modifierName.latin1(),
|
||||
sourceName.latin1())
|
||||
<< angleDelta
|
||||
<< units
|
||||
<< modifiers
|
||||
<< source
|
||||
<< startValue
|
||||
<< expectedValues;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1383,6 +1425,7 @@ void tst_QSpinBox::wheelEvents()
|
||||
#if QT_CONFIG(wheelevent)
|
||||
QFETCH(QPoint, angleDelta);
|
||||
QFETCH(int, qt4Delta);
|
||||
QFETCH(int, stepModifier);
|
||||
QFETCH(Qt::KeyboardModifiers, modifier);
|
||||
QFETCH(Qt::MouseEventSource, source);
|
||||
QFETCH(int, start);
|
||||
@ -1392,6 +1435,11 @@ void tst_QSpinBox::wheelEvents()
|
||||
spinBox.setRange(-20, 20);
|
||||
spinBox.setValue(start);
|
||||
|
||||
QScopedPointer<StepModifierStyle, QScopedPointerDeleteLater> style(
|
||||
new StepModifierStyle);
|
||||
style->stepModifier = static_cast<Qt::KeyboardModifier>(stepModifier);
|
||||
spinBox.setStyle(style.data());
|
||||
|
||||
QWheelEvent event(QPointF(), QPointF(), QPoint(), angleDelta, qt4Delta,
|
||||
Qt::Vertical, Qt::NoButton, modifier, Qt::NoScrollPhase,
|
||||
source);
|
||||
@ -1486,14 +1534,21 @@ void tst_QSpinBox::adaptiveDecimalStep()
|
||||
void tst_QSpinBox::stepModifierKeys_data()
|
||||
{
|
||||
QTest::addColumn<int>("startValue");
|
||||
QTest::addColumn<int>("stepModifier");
|
||||
QTest::addColumn<QTestEventList>("keys");
|
||||
QTest::addColumn<int>("expectedValue");
|
||||
|
||||
const auto keyList = {Qt::Key_Up, Qt::Key_Down};
|
||||
|
||||
const auto modifierList = {Qt::NoModifier,
|
||||
Qt::ShiftModifier,
|
||||
Qt::ControlModifier,
|
||||
Qt::ShiftModifier};
|
||||
Qt::AltModifier,
|
||||
Qt::MetaModifier};
|
||||
|
||||
const auto validStepModifierList = {Qt::NoModifier,
|
||||
Qt::ControlModifier,
|
||||
Qt::ShiftModifier};
|
||||
|
||||
for (auto key : keyList) {
|
||||
|
||||
@ -1511,17 +1566,26 @@ void tst_QSpinBox::stepModifierKeys_data()
|
||||
if (modifierName.isEmpty())
|
||||
continue;
|
||||
|
||||
const int steps = (modifier & Qt::ControlModifier ? 10 : 1)
|
||||
* (up ? 1 : -1);
|
||||
for (auto stepModifier : validStepModifierList) {
|
||||
|
||||
const int expectedValue = startValue + steps;
|
||||
const auto stepModifierName = modifierToName(stepModifier);
|
||||
if (stepModifierName.isEmpty())
|
||||
continue;
|
||||
|
||||
QTest::addRow("%sWith%sKeyboardModifier",
|
||||
up ? "up" : "down",
|
||||
modifierName.latin1())
|
||||
<< startValue
|
||||
<< keys
|
||||
<< expectedValue;
|
||||
const int steps = (modifier & stepModifier ? 10 : 1)
|
||||
* (up ? 1 : -1);
|
||||
|
||||
const int expectedValue = startValue + steps;
|
||||
|
||||
QTest::addRow("%s%sWith%sKeyboardModifier",
|
||||
up ? "up" : "down",
|
||||
stepModifierName.latin1(),
|
||||
modifierName.latin1())
|
||||
<< startValue
|
||||
<< static_cast<int>(stepModifier)
|
||||
<< keys
|
||||
<< expectedValue;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1529,11 +1593,18 @@ void tst_QSpinBox::stepModifierKeys_data()
|
||||
void tst_QSpinBox::stepModifierKeys()
|
||||
{
|
||||
QFETCH(int, startValue);
|
||||
QFETCH(int, stepModifier);
|
||||
QFETCH(QTestEventList, keys);
|
||||
QFETCH(int, expectedValue);
|
||||
|
||||
QSpinBox spin(0);
|
||||
spin.setValue(startValue);
|
||||
|
||||
QScopedPointer<StepModifierStyle, QScopedPointerDeleteLater> style(
|
||||
new StepModifierStyle);
|
||||
style->stepModifier = static_cast<Qt::KeyboardModifier>(stepModifier);
|
||||
spin.setStyle(style.data());
|
||||
|
||||
spin.show();
|
||||
QVERIFY(QTest::qWaitForWindowActive(&spin));
|
||||
|
||||
@ -1545,6 +1616,7 @@ void tst_QSpinBox::stepModifierKeys()
|
||||
void tst_QSpinBox::stepModifierButtons_data()
|
||||
{
|
||||
QTest::addColumn<QStyle::SubControl>("subControl");
|
||||
QTest::addColumn<int>("stepModifier");
|
||||
QTest::addColumn<Qt::KeyboardModifiers>("modifiers");
|
||||
QTest::addColumn<int>("startValue");
|
||||
QTest::addColumn<int>("expectedValue");
|
||||
@ -1552,8 +1624,14 @@ void tst_QSpinBox::stepModifierButtons_data()
|
||||
const auto subControls = {QStyle::SC_SpinBoxUp, QStyle::SC_SpinBoxDown};
|
||||
|
||||
const auto modifierList = {Qt::NoModifier,
|
||||
Qt::ShiftModifier,
|
||||
Qt::ControlModifier,
|
||||
Qt::ShiftModifier};
|
||||
Qt::AltModifier,
|
||||
Qt::MetaModifier};
|
||||
|
||||
const auto validStepModifierList = {Qt::NoModifier,
|
||||
Qt::ControlModifier,
|
||||
Qt::ShiftModifier};
|
||||
|
||||
for (auto subControl : subControls) {
|
||||
|
||||
@ -1570,18 +1648,27 @@ void tst_QSpinBox::stepModifierButtons_data()
|
||||
if (modifierName.isEmpty())
|
||||
continue;
|
||||
|
||||
const int steps = (modifier & Qt::ControlModifier ? 10 : 1)
|
||||
* (up ? 1 : -1);
|
||||
for (auto stepModifier : validStepModifierList) {
|
||||
|
||||
const int expectedValue = startValue + steps;
|
||||
const auto stepModifierName = modifierToName(stepModifier);
|
||||
if (stepModifierName.isEmpty())
|
||||
continue;
|
||||
|
||||
QTest::addRow("%sWith%sKeyboardModifier",
|
||||
up ? "up" : "down",
|
||||
modifierName.latin1())
|
||||
<< subControl
|
||||
<< modifiers
|
||||
<< startValue
|
||||
<< expectedValue;
|
||||
const int steps = (modifier & stepModifier ? 10 : 1)
|
||||
* (up ? 1 : -1);
|
||||
|
||||
const int expectedValue = startValue + steps;
|
||||
|
||||
QTest::addRow("%s%sWith%sKeyboardModifier",
|
||||
up ? "up" : "down",
|
||||
stepModifierName.latin1(),
|
||||
modifierName.latin1())
|
||||
<< subControl
|
||||
<< static_cast<int>(stepModifier)
|
||||
<< modifiers
|
||||
<< startValue
|
||||
<< expectedValue;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1589,6 +1676,7 @@ void tst_QSpinBox::stepModifierButtons_data()
|
||||
void tst_QSpinBox::stepModifierButtons()
|
||||
{
|
||||
QFETCH(QStyle::SubControl, subControl);
|
||||
QFETCH(int, stepModifier);
|
||||
QFETCH(Qt::KeyboardModifiers, modifiers);
|
||||
QFETCH(int, startValue);
|
||||
QFETCH(int, expectedValue);
|
||||
@ -1596,6 +1684,12 @@ void tst_QSpinBox::stepModifierButtons()
|
||||
SpinBox spin(0);
|
||||
spin.setRange(-20, 20);
|
||||
spin.setValue(startValue);
|
||||
|
||||
QScopedPointer<StepModifierStyle, QScopedPointerDeleteLater> style(
|
||||
new StepModifierStyle);
|
||||
style->stepModifier = static_cast<Qt::KeyboardModifier>(stepModifier);
|
||||
spin.setStyle(style.data());
|
||||
|
||||
spin.show();
|
||||
QVERIFY(QTest::qWaitForWindowActive(&spin));
|
||||
|
||||
@ -1613,14 +1707,21 @@ void tst_QSpinBox::stepModifierButtons()
|
||||
void tst_QSpinBox::stepModifierPressAndHold_data()
|
||||
{
|
||||
QTest::addColumn<QStyle::SubControl>("subControl");
|
||||
QTest::addColumn<int>("stepModifier");
|
||||
QTest::addColumn<Qt::KeyboardModifiers>("modifiers");
|
||||
QTest::addColumn<int>("expectedStepModifier");
|
||||
|
||||
const auto subControls = {QStyle::SC_SpinBoxUp, QStyle::SC_SpinBoxDown};
|
||||
|
||||
const auto modifierList = {Qt::NoModifier,
|
||||
Qt::ShiftModifier,
|
||||
Qt::ControlModifier,
|
||||
Qt::ShiftModifier};
|
||||
Qt::AltModifier,
|
||||
Qt::MetaModifier};
|
||||
|
||||
const auto validStepModifierList = {Qt::NoModifier,
|
||||
Qt::ControlModifier,
|
||||
Qt::ShiftModifier};
|
||||
|
||||
for (auto subControl : subControls) {
|
||||
|
||||
@ -1635,15 +1736,24 @@ void tst_QSpinBox::stepModifierPressAndHold_data()
|
||||
if (modifierName.isEmpty())
|
||||
continue;
|
||||
|
||||
const int steps = (modifier & Qt::ControlModifier ? 10 : 1)
|
||||
* (up ? 1 : -1);
|
||||
for (auto stepModifier : validStepModifierList) {
|
||||
|
||||
QTest::addRow("%sWith%sKeyboardModifier",
|
||||
up ? "up" : "down",
|
||||
modifierName.latin1())
|
||||
<< subControl
|
||||
<< modifiers
|
||||
<< steps;
|
||||
const auto stepModifierName = modifierToName(stepModifier);
|
||||
if (stepModifierName.isEmpty())
|
||||
continue;
|
||||
|
||||
const int steps = (modifier & stepModifier ? 10 : 1)
|
||||
* (up ? 1 : -1);
|
||||
|
||||
QTest::addRow("%s%sWith%sKeyboardModifier",
|
||||
up ? "up" : "down",
|
||||
stepModifierName.latin1(),
|
||||
modifierName.latin1())
|
||||
<< subControl
|
||||
<< static_cast<int>(stepModifier)
|
||||
<< modifiers
|
||||
<< steps;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1651,16 +1761,19 @@ void tst_QSpinBox::stepModifierPressAndHold_data()
|
||||
void tst_QSpinBox::stepModifierPressAndHold()
|
||||
{
|
||||
QFETCH(QStyle::SubControl, subControl);
|
||||
QFETCH(int, stepModifier);
|
||||
QFETCH(Qt::KeyboardModifiers, modifiers);
|
||||
QFETCH(int, expectedStepModifier);
|
||||
|
||||
SpinBox spin(0);
|
||||
QScopedPointer<PressAndHoldStyle, QScopedPointerDeleteLater> pressAndHoldStyle(
|
||||
new PressAndHoldStyle);
|
||||
spin.setStyle(pressAndHoldStyle.data());
|
||||
spin.setRange(-100, 100);
|
||||
spin.setValue(0);
|
||||
|
||||
QScopedPointer<StepModifierStyle, QScopedPointerDeleteLater> stepModifierStyle(
|
||||
new StepModifierStyle(new PressAndHoldStyle));
|
||||
stepModifierStyle->stepModifier = static_cast<Qt::KeyboardModifier>(stepModifier);
|
||||
spin.setStyle(stepModifierStyle.data());
|
||||
|
||||
QSignalSpy spy(&spin, QOverload<int>::of(&SpinBox::valueChanged));
|
||||
|
||||
spin.show();
|
||||
|
Loading…
x
Reference in New Issue
Block a user