Skip to content

Commit

Permalink
Spin boxes and combo boxes ignore wheel events when not focused
Browse files Browse the repository at this point in the history
Otherwise it is too easy to accidentally trigger them while scrolling
through the Properties view.
  • Loading branch information
bjorn committed Oct 24, 2024
1 parent 98288b2 commit d64d03b
Show file tree
Hide file tree
Showing 4 changed files with 71 additions and 10 deletions.
4 changes: 2 additions & 2 deletions src/tiled/propertieswidget.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@
#include "objecttemplate.h"
#include "preferences.h"
#include "propertybrowser.h"
#include "propertyeditorwidgets.h"
#include "tilesetchanges.h"
#include "tilesetdocument.h"
#include "tilesetparametersedit.h"
Expand All @@ -50,7 +51,6 @@

#include <QAction>
#include <QCheckBox>
#include <QComboBox>
#include <QCoreApplication>
#include <QEvent>
#include <QFileInfo>
Expand Down Expand Up @@ -757,7 +757,7 @@ class ClassNameProperty : public StringProperty

QWidget *createEditor(QWidget *parent) override
{
auto editor = new QComboBox(parent);
auto editor = new ComboBox(parent);
editor->setEditable(true);
editor->lineEdit()->setPlaceholderText(placeholderText());
editor->addItems(classNamesFor(*mObject));
Expand Down
42 changes: 42 additions & 0 deletions src/tiled/propertyeditorwidgets.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -55,13 +55,36 @@ static QString removeRedundantTrialingZeros(const QString &text)
}


ComboBox::ComboBox(QWidget *parent)
: QComboBox(parent)
{
// Combo boxes in properties view don't adjust to their contents
setSizeAdjustPolicy(QComboBox::AdjustToMinimumContentsLengthWithIcon);

// Don't take focus by mouse wheel
if (focusPolicy() == Qt::WheelFocus)
setFocusPolicy(Qt::StrongFocus);
}

void ComboBox::wheelEvent(QWheelEvent *event)
{
if (!hasFocus())
event->ignore();
else
QComboBox::wheelEvent(event);
}


SpinBox::SpinBox(QWidget *parent)
: QSpinBox(parent)
{
// Allow the full range by default.
setRange(std::numeric_limits<int>::lowest(),
std::numeric_limits<int>::max());

// Don't take focus by mouse wheel
setFocusPolicy(Qt::StrongFocus);

// Don't respond to keyboard input immediately.
setKeyboardTracking(false);

Expand All @@ -77,6 +100,14 @@ QSize SpinBox::minimumSizeHint() const
return hint;
}

void SpinBox::wheelEvent(QWheelEvent *event)
{
if (!hasFocus())
event->ignore();
else
QSpinBox::wheelEvent(event);
}


DoubleSpinBox::DoubleSpinBox(QWidget *parent)
: QDoubleSpinBox(parent)
Expand All @@ -88,6 +119,9 @@ DoubleSpinBox::DoubleSpinBox(QWidget *parent)
// Increase possible precision.
setDecimals(9);

// Don't take focus by mouse wheel
setFocusPolicy(Qt::StrongFocus);

// Don't respond to keyboard input immediately.
setKeyboardTracking(false);

Expand All @@ -114,6 +148,14 @@ QString DoubleSpinBox::textFromValue(double val) const
return text;
}

void DoubleSpinBox::wheelEvent(QWheelEvent *event)
{
if (!hasFocus())
event->ignore();
else
QDoubleSpinBox::wheelEvent(event);
}


ResponsivePairswiseWidget::ResponsivePairswiseWidget(QWidget *parent)
: QWidget(parent)
Expand Down
26 changes: 24 additions & 2 deletions src/tiled/propertyeditorwidgets.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,16 +20,32 @@

#pragma once

#include <QComboBox>
#include <QLabel>
#include <QSpinBox>

class QLabel;

namespace Tiled {

/**
* A combo box that doesn't respond to wheel events when not focused.
*/
class ComboBox : public QComboBox
{
Q_OBJECT

public:
ComboBox(QWidget *parent = nullptr);

protected:
void wheelEvent(QWheelEvent *event) override;
};

/**
* A spin box that allows the full range by default and shrinks horizontally.
* It also doesn't adjust the horizontal size hint based on the maximum value.
* It also doesn't adjust the horizontal size hint based on the maximum value
* and doesn't respond to wheel events when not focused.
*/
class SpinBox : public QSpinBox
{
Expand All @@ -39,12 +55,15 @@ class SpinBox : public QSpinBox
SpinBox(QWidget *parent = nullptr);

QSize minimumSizeHint() const override;

protected:
void wheelEvent(QWheelEvent *event) override;
};

/**
* A double spin box that allows the full range by default and shrinks
* horizontally. It also doesn't adjust the horizontal size hint based on the
* maximum value.
* maximum value and doesn't respond to wheel events when not focused.
*
* The precision is increased to 9 decimal places. Redundant trailing 0's are
* removed.
Expand All @@ -58,6 +77,9 @@ class DoubleSpinBox : public QDoubleSpinBox

QSize minimumSizeHint() const override;
QString textFromValue(double val) const override;

protected:
void wheelEvent(QWheelEvent *event) override;
};

/**
Expand Down
9 changes: 3 additions & 6 deletions src/tiled/varianteditor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,6 @@

#include <QBoxLayout>
#include <QCheckBox>
#include <QComboBox>
#include <QFontComboBox>
#include <QGridLayout>
#include <QLabel>
Expand Down Expand Up @@ -496,14 +495,14 @@ QWidget *QtAlignmentProperty::createEditor(QWidget *parent)
auto verticalLabel = new ElidingLabel(tr("Vertical"), editor);
layout->addWidget(verticalLabel, 1, 0);

auto horizontalComboBox = new QComboBox(editor);
auto horizontalComboBox = new ComboBox(editor);
horizontalComboBox->addItem(tr("Left"), Qt::AlignLeft);
horizontalComboBox->addItem(tr("Center"), Qt::AlignHCenter);
horizontalComboBox->addItem(tr("Right"), Qt::AlignRight);
horizontalComboBox->addItem(tr("Justify"), Qt::AlignJustify);
layout->addWidget(horizontalComboBox, 0, 1);

auto verticalComboBox = new QComboBox(editor);
auto verticalComboBox = new ComboBox(editor);
verticalComboBox->addItem(tr("Top"), Qt::AlignTop);
verticalComboBox->addItem(tr("Center"), Qt::AlignVCenter);
verticalComboBox->addItem(tr("Bottom"), Qt::AlignBottom);
Expand Down Expand Up @@ -792,9 +791,7 @@ void VariantEditor::updatePropertyActions(const PropertyWidgets &widgets, Proper

QWidget *BaseEnumProperty::createEnumEditor(QWidget *parent)
{
auto editor = new QComboBox(parent);
// This allows the combo box to shrink horizontally.
editor->setSizeAdjustPolicy(QComboBox::AdjustToMinimumContentsLengthWithIcon);
auto editor = new ComboBox(parent);

for (qsizetype i = 0; i < m_enumData.names.size(); ++i) {
auto value = m_enumData.values.value(i, i);
Expand Down

0 comments on commit d64d03b

Please sign in to comment.