Split out NoScroll classes from unrelated behavior

This commit is contained in:
GriffinR 2025-12-30 21:07:29 -05:00
parent 6a982402d9
commit d831af32a7
57 changed files with 433 additions and 451 deletions

View File

@ -81,6 +81,9 @@
<property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Where the connected map should be positioned relative to the current map.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="editable">
<bool>true</bool>
</property>
</widget>
</item>
<item row="0" column="1" colspan="2">
@ -88,6 +91,9 @@
<property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;The name of the map to connect to the current map.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="editable">
<bool>true</bool>
</property>
</widget>
</item>
<item row="2" column="1" colspan="2">
@ -117,12 +123,12 @@
<customwidget>
<class>NoScrollComboBox</class>
<extends>QComboBox</extends>
<header>noscrollcombobox.h</header>
<header>noscrollwidgets.h</header>
</customwidget>
<customwidget>
<class>NoScrollSpinBox</class>
<extends>QSpinBox</extends>
<header>noscrollspinbox.h</header>
<header>noscrollwidgets.h</header>
</customwidget>
</customwidgets>
<resources>

View File

@ -164,7 +164,7 @@
<customwidget>
<class>NoScrollComboBox</class>
<extends>QComboBox</extends>
<header>noscrollcombobox.h</header>
<header>noscrollwidgets.h</header>
</customwidget>
</customwidgets>
<resources/>

View File

@ -57,15 +57,9 @@
</item>
<item row="2" column="1">
<widget class="NoScrollComboBox" name="comboBox_Style">
<property name="editable">
<bool>false</bool>
</property>
<property name="sizeAdjustPolicy">
<enum>QComboBox::SizeAdjustPolicy::AdjustToContentsOnFirstShow</enum>
</property>
<property name="minimumContentsLength">
<number>0</number>
</property>
</widget>
</item>
<item row="2" column="0">
@ -254,12 +248,12 @@
<customwidget>
<class>NoScrollSpinBox</class>
<extends>QSpinBox</extends>
<header>noscrollspinbox.h</header>
<header>noscrollwidgets.h</header>
</customwidget>
<customwidget>
<class>NoScrollComboBox</class>
<extends>QComboBox</extends>
<header>noscrollcombobox.h</header>
<header>noscrollwidgets.h</header>
</customwidget>
<customwidget>
<class>ColorInputWidget</class>

View File

@ -1105,18 +1105,12 @@
</item>
<item row="1" column="1">
<widget class="NoScrollComboBox" name="comboBox_PrimaryTileset">
<property name="focusPolicy">
<enum>Qt::FocusPolicy::StrongFocus</enum>
</property>
<property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Primary Tileset&lt;/p&gt;&lt;p&gt;Defines the first 0x200 metatiles available for the map.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="editable">
<bool>true</bool>
</property>
<property name="minimumContentsLength">
<number>0</number>
</property>
</widget>
</item>
<item row="2" column="0">
@ -1128,24 +1122,18 @@
</item>
<item row="2" column="1">
<widget class="NoScrollComboBox" name="comboBox_SecondaryTileset">
<property name="focusPolicy">
<enum>Qt::FocusPolicy::StrongFocus</enum>
</property>
<property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Secondary Tileset&lt;/p&gt;&lt;p&gt;Defines the second 0x200 metatiles available for the map.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="editable">
<bool>true</bool>
</property>
<property name="minimumContentsLength">
<number>0</number>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="NoScrollComboBox" name="comboBox_LayoutSelector">
<property name="minimumContentsLength">
<number>0</number>
<property name="editable">
<bool>true</bool>
</property>
</widget>
</item>
@ -2720,9 +2708,6 @@
</item>
<item>
<widget class="NoScrollComboBox" name="comboBox_EncounterGroupLabel">
<property name="editable">
<bool>false</bool>
</property>
<property name="sizeAdjustPolicy">
<enum>QComboBox::SizeAdjustPolicy::AdjustToContents</enum>
</property>
@ -3274,7 +3259,7 @@
<customwidget>
<class>NoScrollComboBox</class>
<extends>QComboBox</extends>
<header>noscrollcombobox.h</header>
<header>noscrollwidgets.h</header>
</customwidget>
<customwidget>
<class>AdjustingStackedWidget</class>

View File

@ -239,12 +239,12 @@
<customwidget>
<class>NoScrollComboBox</class>
<extends>QComboBox</extends>
<header>noscrollcombobox.h</header>
<header>noscrollwidgets.h</header>
</customwidget>
<customwidget>
<class>NoScrollSpinBox</class>
<extends>QSpinBox</extends>
<header>noscrollspinbox.h</header>
<header>noscrollwidgets.h</header>
</customwidget>
</customwidgets>
<resources/>

View File

@ -40,6 +40,9 @@
</item>
<item row="0" column="1">
<widget class="NoScrollComboBox" name="comboBox_MapSelection">
<property name="editable">
<bool>true</bool>
</property>
<property name="insertPolicy">
<enum>QComboBox::InsertPolicy::NoInsert</enum>
</property>
@ -436,12 +439,12 @@
<customwidget>
<class>NoScrollComboBox</class>
<extends>QComboBox</extends>
<header>noscrollcombobox.h</header>
<header>noscrollwidgets.h</header>
</customwidget>
<customwidget>
<class>NoScrollSpinBox</class>
<extends>QSpinBox</extends>
<header>noscrollspinbox.h</header>
<header>noscrollwidgets.h</header>
</customwidget>
</customwidgets>
<resources/>

View File

@ -98,9 +98,6 @@
<property name="enabled">
<bool>false</bool>
</property>
<property name="editable">
<bool>false</bool>
</property>
</widget>
</item>
<item row="1" column="1">
@ -108,9 +105,6 @@
<property name="enabled">
<bool>false</bool>
</property>
<property name="editable">
<bool>false</bool>
</property>
</widget>
</item>
<item row="0" column="0">
@ -503,7 +497,7 @@
<customwidget>
<class>NoScrollComboBox</class>
<extends>QComboBox</extends>
<header>noscrollcombobox.h</header>
<header>noscrollwidgets.h</header>
</customwidget>
<customwidget>
<class>UIntSpinBox</class>

View File

@ -231,12 +231,12 @@
<customwidget>
<class>NoScrollComboBox</class>
<extends>QComboBox</extends>
<header>noscrollcombobox.h</header>
<header>noscrollwidgets.h</header>
</customwidget>
<customwidget>
<class>NoScrollSpinBox</class>
<extends>QSpinBox</extends>
<header>noscrollspinbox.h</header>
<header>noscrollwidgets.h</header>
</customwidget>
</customwidgets>
<resources/>

View File

@ -47,6 +47,9 @@
<property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;The name of the map to connect to the current map.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="editable">
<bool>true</bool>
</property>
</widget>
</item>
<item row="1" column="0">
@ -61,6 +64,9 @@
<property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Where the connected map should be positioned relative to the current map.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="editable">
<bool>true</bool>
</property>
</widget>
</item>
<item row="2" column="0" colspan="2">
@ -95,7 +101,7 @@
<customwidget>
<class>NoScrollComboBox</class>
<extends>QComboBox</extends>
<header>noscrollcombobox.h</header>
<header>noscrollwidgets.h</header>
</customwidget>
</customwidgets>
<resources/>

View File

@ -245,7 +245,7 @@
<customwidget>
<class>NoScrollComboBox</class>
<extends>QComboBox</extends>
<header>noscrollcombobox.h</header>
<header>noscrollwidgets.h</header>
</customwidget>
</customwidgets>
<resources/>

View File

@ -71,9 +71,6 @@
</item>
<item row="2" column="1">
<widget class="NoScrollComboBox" name="comboBox_Type">
<property name="editable">
<bool>false</bool>
</property>
<item>
<property name="text">
<string>Primary</string>
@ -151,7 +148,7 @@
<customwidget>
<class>NoScrollComboBox</class>
<extends>QComboBox</extends>
<header>noscrollcombobox.h</header>
<header>noscrollwidgets.h</header>
</customwidget>
</customwidgets>
<resources/>

View File

@ -144,7 +144,7 @@
<customwidget>
<class>NoScrollSpinBox</class>
<extends>QSpinBox</extends>
<header>noscrollspinbox.h</header>
<header>noscrollwidgets.h</header>
</customwidget>
</customwidgets>
<resources/>

View File

@ -93,9 +93,6 @@
</item>
<item row="4" column="1">
<widget class="NoScrollComboBox" name="comboBox_ApplicationTheme">
<property name="editable">
<bool>false</bool>
</property>
</widget>
</item>
<item row="5" column="0">
@ -110,9 +107,6 @@
<property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;The color space to use for exported images. If &amp;quot;---&amp;quot; is set, no color space will be used for the exported image. For details on each color space, see Qt's manual page for QColorSpace.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="editable">
<bool>false</bool>
</property>
</widget>
</item>
<item row="2" column="0" colspan="2">
@ -519,7 +513,7 @@
<customwidget>
<class>NoScrollComboBox</class>
<extends>QComboBox</extends>
<header>noscrollcombobox.h</header>
<header>noscrollwidgets.h</header>
</customwidget>
</customwidgets>
<resources/>

View File

@ -408,9 +408,6 @@
</item>
<item>
<widget class="NoScrollComboBox" name="comboBox_BaseGameVersion">
<property name="editable">
<bool>false</bool>
</property>
</widget>
</item>
<item>
@ -874,6 +871,9 @@
<property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;The default primary tileset to use for new maps/layouts.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="editable">
<bool>true</bool>
</property>
</widget>
</item>
<item row="1" column="0">
@ -888,6 +888,9 @@
<property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;The default secondary tileset to use for new maps/layouts.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="editable">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
@ -1128,9 +1131,6 @@
<property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;The number of bytes each metatile has for metatile attributes. This is the metadata about each metatile like behvior, layer type, etc.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="editable">
<bool>false</bool>
</property>
</widget>
</item>
<item row="7" column="0">
@ -1268,9 +1268,6 @@
<property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;The icon that will be displayed for the Events tab in the editor. If 'Automatic' is chosen, the icon will be a random player character from the project's base game version. If 'Custom' is chosen an image file path may be specified.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="editable">
<bool>false</bool>
</property>
</widget>
</item>
</layout>
@ -1466,7 +1463,11 @@
</widget>
</item>
<item row="1" column="0">
<widget class="NoScrollComboBox" name="comboBox_WarpBehaviors"/>
<widget class="NoScrollComboBox" name="comboBox_WarpBehaviors">
<property name="editable">
<bool>true</bool>
</property>
</widget>
</item>
<item row="4" column="0" colspan="3">
<widget class="NoScrollTextEdit" name="textEdit_WarpBehaviors">
@ -1892,7 +1893,7 @@
<customwidget>
<class>NoScrollComboBox</class>
<extends>QComboBox</extends>
<header>noscrollcombobox.h</header>
<header>noscrollwidgets.h</header>
</customwidget>
<customwidget>
<class>UIntSpinBox</class>
@ -1907,12 +1908,12 @@
<customwidget>
<class>NoScrollSpinBox</class>
<extends>QSpinBox</extends>
<header>noscrollspinbox.h</header>
<header>noscrollwidgets.h</header>
</customwidget>
<customwidget>
<class>NoScrollTextEdit</class>
<extends>QTextEdit</extends>
<header>noscrolltextedit.h</header>
<header>noscrollwidgets.h</header>
</customwidget>
</customwidgets>
<resources>

View File

@ -44,7 +44,7 @@
</widget>
</item>
<item>
<widget class="QComboBox" name="comboBox_regionSelector">
<widget class="NoScrollComboBox" name="comboBox_regionSelector">
<property name="sizeAdjustPolicy">
<enum>QComboBox::SizeAdjustPolicy::AdjustToContents</enum>
</property>
@ -739,7 +739,7 @@
</widget>
</item>
<item row="0" column="1">
<widget class="QComboBox" name="comboBox_layoutLayer"/>
<widget class="NoScrollComboBox" name="comboBox_layoutLayer"/>
</item>
</layout>
</widget>
@ -773,9 +773,6 @@
<property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;The section of the region map which the map is grouped under. This also determines the name of the map that is displayed when the player enters it.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="editable">
<bool>false</bool>
</property>
</widget>
</item>
<item row="0" column="0">
@ -922,9 +919,6 @@
<property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;The section of the region map which the map is grouped under. This also determines the name of the map that is display when the player enters it.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="editable">
<bool>false</bool>
</property>
</widget>
</item>
<item row="2" column="0">
@ -1171,12 +1165,12 @@
<customwidget>
<class>NoScrollComboBox</class>
<extends>QComboBox</extends>
<header>noscrollcombobox.h</header>
<header>noscrollwidgets.h</header>
</customwidget>
<customwidget>
<class>NoScrollSpinBox</class>
<extends>QSpinBox</extends>
<header>noscrollspinbox.h</header>
<header>noscrollwidgets.h</header>
</customwidget>
</customwidgets>
<resources/>

View File

@ -235,7 +235,7 @@
<customwidget>
<class>NoScrollSpinBox</class>
<extends>QSpinBox</extends>
<header>noscrollspinbox.h</header>
<header>noscrollwidgets.h</header>
</customwidget>
</customwidgets>
<resources/>

View File

@ -403,6 +403,9 @@
<property name="insertPolicy">
<enum>QComboBox::InsertPolicy::NoInsert</enum>
</property>
<property name="editable">
<bool>true</bool>
</property>
</widget>
</item>
<item>
@ -460,6 +463,9 @@
<property name="insertPolicy">
<enum>QComboBox::InsertPolicy::NoInsert</enum>
</property>
<property name="editable">
<bool>true</bool>
</property>
</widget>
</item>
<item>
@ -530,6 +536,9 @@
<property name="insertPolicy">
<enum>QComboBox::InsertPolicy::NoInsert</enum>
</property>
<property name="editable">
<bool>true</bool>
</property>
</widget>
</item>
<item>
@ -1144,7 +1153,7 @@
<customwidget>
<class>NoScrollComboBox</class>
<extends>QComboBox</extends>
<header>noscrollcombobox.h</header>
<header>noscrollwidgets.h</header>
</customwidget>
<customwidget>
<class>NoScrollGraphicsView</class>

View File

@ -43,7 +43,7 @@
</widget>
</item>
<item>
<widget class="QComboBox" name="comboBox_Theme"/>
<widget class="NoScrollComboBox" name="comboBox_Theme"/>
</item>
<item>
<spacer name="horizontalSpacer_2">
@ -140,10 +140,7 @@
</widget>
</item>
<item>
<widget class="QComboBox" name="comboBox_Group">
<property name="editable">
<bool>false</bool>
</property>
<widget class="NoScrollComboBox" name="comboBox_Group">
<property name="sizeAdjustPolicy">
<enum>QComboBox::AdjustToMinimumContentsLengthWithIcon</enum>
</property>
@ -240,7 +237,7 @@
<customwidget>
<class>NoScrollComboBox</class>
<extends>QComboBox</extends>
<header>noscrollcombobox.h</header>
<header>noscrollwidgets.h</header>
</customwidget>
</customwidgets>
<resources>

View File

@ -84,7 +84,7 @@
<customwidget>
<class>NoScrollComboBox</class>
<extends>QComboBox</extends>
<header>noscrollcombobox.h</header>
<header>noscrollwidgets.h</header>
</customwidget>
</customwidgets>
<resources>

View File

@ -245,7 +245,7 @@ private:
void displayConnection(MapConnection *connection);
void displayDivingConnection(MapConnection *connection);
void removeDivingMapPixmap(MapConnection *connection);
void onDivingMapEditingFinished(NoScrollComboBox* combo, const QString &direction);
void onDivingMapEditingFinished(ComboBox *combo, const QString &direction);
void updateDivingMapButton(QToolButton* button, const QString &mapName);
void updateEncounterFields(EncounterFields newFields);
QString getMovementPermissionText(uint16_t collision, uint16_t elevation);

32
include/ui/combobox.h Normal file
View File

@ -0,0 +1,32 @@
#ifndef COMBOBOX_H
#define COMBOBOX_H
#include <QComboBox>
// Contains our general-purpose additions to QComboBox
class ComboBox : public QComboBox
{
Q_OBJECT
public:
explicit ComboBox(QWidget *parent = nullptr);
void setTextItem(const QString &text);
void setNumberItem(int value);
void setHexItem(uint32_t value);
virtual void setEditable(bool editable);
virtual void setLineEdit(QLineEdit *edit);
void setClearButtonEnabled(bool enabled);
signals:
void editingFinished();
private:
void setItem(int index, const QString &text);
void initLineEdit(QLineEdit *edit);
};
#endif // COMBOBOX_H

View File

@ -2,7 +2,7 @@
#define DIVINGMAPPIXMAPITEM_H
#include "mapconnection.h"
#include "noscrollcombobox.h"
#include "combobox.h"
#include <QGraphicsPixmapItem>
#include <QPointer>
@ -11,7 +11,7 @@
class DivingMapPixmapItem : public QObject, public QGraphicsPixmapItem {
Q_OBJECT
public:
DivingMapPixmapItem(MapConnection *connection, NoScrollComboBox *combo);
DivingMapPixmapItem(MapConnection *connection, ComboBox *combo);
~DivingMapPixmapItem();
MapConnection* connection() const { return m_connection; }
@ -19,7 +19,7 @@ public:
private:
QPointer<MapConnection> m_connection;
QPointer<NoScrollComboBox> m_combo;
QPointer<ComboBox> m_combo;
void setComboText(const QString &text);
static QPixmap getBasePixmap(MapConnection* connection);

View File

@ -0,0 +1,24 @@
#ifndef EDITHISTORYSPINBOX_H
#define EDITHISTORYSPINBOX_H
#include "noscrollwidgets.h"
class EditHistorySpinBox : public NoScrollSpinBox
{
Q_OBJECT
public:
explicit EditHistorySpinBox(QWidget *parent = nullptr) : NoScrollSpinBox(parent) {}
void focusOutEvent(QFocusEvent *event) override {
m_actionId++;
NoScrollSpinBox::focusOutEvent(event);
}
unsigned getActionId() const { return m_actionId; }
private:
unsigned m_actionId{0};
};
#endif // EDITHISTORYSPINBOX_H

View File

@ -0,0 +1,22 @@
#ifndef EVENTCOMBOBOX_H
#define EVENTCOMBOBOX_H
#include "noscrollwidgets.h"
#include <QRegularExpression>
class EventComboBox : public NoScrollComboBox
{
Q_OBJECT
public:
explicit EventComboBox(QWidget *parent = nullptr) : NoScrollComboBox(parent) {
// Make speed a priority when loading comboboxes.
setMinimumContentsLength(24);// an arbitrary limit
setSizeAdjustPolicy(QComboBox::AdjustToMinimumContentsLengthWithIcon);
// In general, event combo boxes are always editable.
setEditable(true);
}
};
#endif // EVENTCOMBOBOX_H

View File

@ -2,18 +2,6 @@
#include <QEvent>
/// Prevent wheel scroll
class WheelFilter : public QObject {
Q_OBJECT
public:
WheelFilter(QObject *parent) : QObject(parent) {}
virtual ~WheelFilter() {}
bool eventFilter(QObject *obj, QEvent *event) override;
};
/// Ctrl+Wheel = zoom
class MapSceneEventFilter : public QObject {
Q_OBJECT

View File

@ -4,8 +4,8 @@
#include <QtWidgets>
#include "noscrollspinbox.h"
#include "noscrollcombobox.h"
#include "edithistoryspinbox.h"
#include "eventcombobox.h"
#include "mainwindow.h"
#include "events.h"
@ -40,8 +40,8 @@ public:
QSpinBox *spinner_id;
NoScrollSpinBox *spinner_x;
NoScrollSpinBox *spinner_y;
EditHistorySpinBox *spinner_x;
EditHistorySpinBox *spinner_y;
NoScrollSpinBox *spinner_z;
QLabel *hideable_label_z;
@ -58,10 +58,10 @@ protected:
bool connected = false;
QPointer<Project> project;
void populateDropdown(NoScrollComboBox * combo, const QStringList &items);
void populateScriptDropdown(NoScrollComboBox * combo, Project * project);
void populateMapNameDropdown(NoScrollComboBox * combo, Project * project);
void populateIdNameDropdown(NoScrollComboBox * combo, Project * project, const QString &mapName, Event::Group group);
void populateDropdown(EventComboBox * combo, const QStringList &items);
void populateScriptDropdown(EventComboBox * combo, Project * project);
void populateMapNameDropdown(EventComboBox * combo, Project * project);
void populateIdNameDropdown(EventComboBox * combo, Project * project, const QString &mapName, Event::Group group);
private:
Event *event;
@ -83,15 +83,15 @@ public:
public:
QLineEdit *line_edit_local_id;
NoScrollComboBox *combo_sprite;
NoScrollComboBox *combo_movement;
EventComboBox *combo_sprite;
EventComboBox *combo_movement;
NoScrollSpinBox *spinner_radius_x;
NoScrollSpinBox *spinner_radius_y;
NoScrollComboBox *combo_script;
EventComboBox *combo_script;
QToolButton *button_script;
NoScrollComboBox *combo_flag;
NoScrollComboBox *combo_trainer_type;
NoScrollComboBox *combo_radius_treeid;
EventComboBox *combo_flag;
EventComboBox *combo_trainer_type;
EventComboBox *combo_radius_treeid;
QCheckBox *check_in_connection;
private:
@ -114,9 +114,9 @@ public:
public:
QLineEdit *line_edit_local_id;
NoScrollComboBox *combo_sprite;
NoScrollComboBox *combo_target_id;
NoScrollComboBox *combo_target_map;
EventComboBox *combo_sprite;
EventComboBox *combo_target_id;
EventComboBox *combo_target_map;
private:
CloneObjectEvent *clone;
@ -140,8 +140,8 @@ public:
public:
QLineEdit *line_edit_id;
NoScrollComboBox *combo_dest_map;
NoScrollComboBox *combo_dest_warp;
EventComboBox *combo_dest_map;
EventComboBox *combo_dest_warp;
QPushButton *warning;
private:
@ -165,9 +165,9 @@ public:
virtual void populate(Project *project) override;
public:
NoScrollComboBox *combo_script;
NoScrollComboBox *combo_var;
NoScrollComboBox *combo_var_value;
EventComboBox *combo_script;
EventComboBox *combo_var;
EventComboBox *combo_var_value;
private:
TriggerEvent *trigger;
@ -188,7 +188,7 @@ public:
virtual void populate(Project *project) override;
public:
NoScrollComboBox *combo_weather;
EventComboBox *combo_weather;
private:
WeatherTriggerEvent *weatherTrigger;
@ -209,8 +209,8 @@ public:
virtual void populate(Project *project) override;
public:
NoScrollComboBox *combo_facing_dir;
NoScrollComboBox *combo_script;
EventComboBox *combo_facing_dir;
EventComboBox *combo_script;
private:
SignEvent *sign;
@ -233,8 +233,8 @@ public:
public:
QFrame *hideable_quantity;
QFrame *hideable_itemfinder;
NoScrollComboBox *combo_item;
NoScrollComboBox *combo_flag;
EventComboBox *combo_item;
EventComboBox *combo_flag;
NoScrollSpinBox *spinner_quantity;
QCheckBox *check_itemfinder;
@ -257,7 +257,7 @@ public:
virtual void populate(Project *project) override;
public:
NoScrollComboBox *combo_base_id;
EventComboBox *combo_base_id;
private:
SecretBaseEvent *secretBase;
@ -281,8 +281,8 @@ public:
QLineEdit *line_edit_id;
QFrame *hideable_respawn_map;
QFrame *hideable_respawn_npc;
NoScrollComboBox *combo_respawn_map;
NoScrollComboBox *combo_respawn_npc;
EventComboBox *combo_respawn_map;
EventComboBox *combo_respawn_npc;
private:
HealLocationEvent *healLocation;

View File

@ -1,6 +1,8 @@
#ifndef GRAPHICSVIEW_H
#define GRAPHICSVIEW_H
#include "noscrollwidgets.h"
#include <QGraphicsView>
#include <QMouseEvent>
@ -90,11 +92,8 @@ class NoScrollGraphicsView : public GraphicsView
{
Q_OBJECT
public:
NoScrollGraphicsView(QWidget *parent = nullptr) : GraphicsView(parent) {}
protected:
void wheelEvent(QWheelEvent *event) {
event->ignore();
NoScrollGraphicsView(QWidget *parent = nullptr) : GraphicsView(parent) {
NoScrollFilter::apply(this, false);
}
};

View File

@ -12,7 +12,7 @@
#include "mapheader.h"
#include "project.h"
#include "noscrollcombobox.h"
#include "combobox.h"
namespace Ui {
class MapHeaderForm;
@ -65,7 +65,7 @@ private:
QPointer<Project> m_project = nullptr;
bool m_allowProjectChanges = true;
void setText(NoScrollComboBox *combo, const QString &text) const;
void setText(ComboBox *combo, const QString &text) const;
void setText(QLineEdit *lineEdit, const QString &text) const;
void setLocations(const QStringList &locations);
void updateLocationName();

View File

@ -1,30 +0,0 @@
#ifndef NOSCROLLCOMBOBOX_H
#define NOSCROLLCOMBOBOX_H
#include <QComboBox>
class NoScrollComboBox : public QComboBox
{
Q_OBJECT
public:
explicit NoScrollComboBox(QWidget *parent = nullptr);
void wheelEvent(QWheelEvent *event);
void setTextItem(const QString &text);
void setNumberItem(int value);
void setHexItem(uint32_t value);
void setClearButtonEnabled(bool enabled);
void setEditable(bool editable);
void setLineEdit(QLineEdit *edit);
void setFocusedScrollingEnabled(bool enabled);
signals:
void editingFinished();
private:
void setItem(int index, const QString &text);
bool focusedScrollingEnabled = true;
};
#endif // NOSCROLLCOMBOBOX_H

View File

@ -1,22 +0,0 @@
#ifndef NOSCROLLSPINBOX_H
#define NOSCROLLSPINBOX_H
#include <QSpinBox>
class NoScrollSpinBox : public QSpinBox
{
Q_OBJECT
public:
explicit NoScrollSpinBox(QWidget *parent = nullptr);
void wheelEvent(QWheelEvent *event) override;
void focusOutEvent(QFocusEvent *event) override;
void setLineEditEnabled(bool enabled);
unsigned getActionId();
private:
};
#endif // NOSCROLLSPINBOX_H

View File

@ -1,25 +0,0 @@
#ifndef NOSCROLLTEXTEDIT_H
#define NOSCROLLTEXTEDIT_H
#include <QTextEdit>
#include <QWheelEvent>
class NoScrollTextEdit : public QTextEdit
{
Q_OBJECT
public:
explicit NoScrollTextEdit(const QString &text, QWidget *parent = nullptr) : QTextEdit(text, parent) {
setFocusPolicy(Qt::StrongFocus);
};
explicit NoScrollTextEdit(QWidget *parent = nullptr) : NoScrollTextEdit(QString(), parent) {};
virtual void wheelEvent(QWheelEvent *event) override {
if (hasFocus()) {
QTextEdit::wheelEvent(event);
} else {
event->ignore();
}
};
};
#endif // NOSCROLLTEXTEDIT_H

View File

@ -0,0 +1,79 @@
#ifndef NOSCROLLWIDGETS_H
#define NOSCROLLWIDGETS_H
#include "combobox.h"
#include <QSpinBox>
#include <QTextEdit>
/// Prevent widgets from stealing focus when a user scrolls past it.
/// Any QObject with this filter will never accept wheel events.
/// Any QWidget with this filter will only accept wheel events
/// if 'allowIfFocused' is 'true' and the widget has focus.
class NoScrollFilter : public QObject {
Q_OBJECT
public:
NoScrollFilter(QObject *parent, bool allowIfFocused)
: QObject(parent), m_allowIfFocused(allowIfFocused) {}
static NoScrollFilter* apply(QObject *target, bool allowIfFocused = true);
bool eventFilter(QObject *obj, QEvent *event) override;
void setAllowIfFocused(bool enabled) { m_allowIfFocused = enabled; }
private:
bool m_allowIfFocused;
};
class NoScrollComboBox : public ComboBox {
Q_OBJECT
public:
explicit NoScrollComboBox(QWidget *parent = nullptr) : ComboBox(parent) {
m_filter = NoScrollFilter::apply(this);
}
void setEditable(bool editable) override;
void setLineEdit(QLineEdit *edit) override;
void setAllowScrollingIfFocused(bool enabled) { if (m_filter) m_filter->setAllowIfFocused(enabled); }
private:
NoScrollFilter* m_filter = nullptr;
};
class NoScrollAbstractSpinBox : public QAbstractSpinBox {
Q_OBJECT
public:
explicit NoScrollAbstractSpinBox(QWidget *parent = nullptr) : QAbstractSpinBox(parent) {
NoScrollFilter::apply(this);
}
};
class NoScrollDoubleSpinBox : public QDoubleSpinBox {
Q_OBJECT
public:
explicit NoScrollDoubleSpinBox(QWidget *parent = nullptr) : QDoubleSpinBox(parent) {
NoScrollFilter::apply(this);
}
};
class NoScrollSpinBox : public QSpinBox {
Q_OBJECT
public:
explicit NoScrollSpinBox(QWidget *parent = nullptr) : QSpinBox(parent) {
NoScrollFilter::apply(this);
}
};
class NoScrollTextEdit : public QTextEdit {
Q_OBJECT
public:
explicit NoScrollTextEdit(const QString &text, QWidget *parent = nullptr) : QTextEdit(text, parent) {
NoScrollFilter::apply(this);
}
explicit NoScrollTextEdit(QWidget *parent = nullptr) : NoScrollTextEdit(QString(), parent) {}
};
#endif // NOSCROLLWIDGETS_H

View File

@ -4,7 +4,6 @@
#include <QMainWindow>
#include "config.h"
class NoScrollComboBox;
class QAbstractButton;

View File

@ -5,7 +5,6 @@
#include "project.h"
#include "ui_projectsettingseditor.h"
class NoScrollComboBox;
class QAbstractButton;

View File

@ -12,7 +12,7 @@
#include "metatilelayersitem.h"
#include "metatileimageexporter.h"
class NoScrollComboBox;
class ComboBox;
class Layout;
namespace Ui {
@ -136,7 +136,7 @@ private:
void commitMetatileChange(Metatile * prevMetatile);
void commitMetatileAndLabelChange(Metatile * prevMetatile, QString prevLabel);
uint32_t attributeNameToValue(Metatile::Attr attribute, const QString &text, bool *ok);
void commitAttributeFromComboBox(Metatile::Attr attribute, NoScrollComboBox *combo);
void commitAttributeFromComboBox(Metatile::Attr attribute, ComboBox *combo);
void onRawAttributesEdited();
void refreshMetatileAttributes();
void commitMetatileBehavior();

View File

@ -1,16 +1,15 @@
#ifndef UINTSPINBOX_H
#define UINTSPINBOX_H
#include <QAbstractSpinBox>
#include "noscrollwidgets.h"
#include <QLineEdit>
/*
QSpinBox stores minimum/maximum/value as ints. This class is a version of QAbstractSpinBox for values above 0x7FFFFFFF.
It minimally implements some QSpinBox-specific features like prefixes to simplify support for hex value input.
It also implements the scroll focus requirements of NoScrollSpinBox.
*/
class UIntSpinBox : public QAbstractSpinBox
class UIntSpinBox : public NoScrollAbstractSpinBox
{
Q_OBJECT
@ -48,7 +47,6 @@ private:
QString stripped(QString input) const;
virtual void stepBy(int steps) override;
virtual void wheelEvent(QWheelEvent *event) override;
virtual void focusOutEvent(QFocusEvent *event) override;
protected:

View File

@ -78,6 +78,7 @@ SOURCES += src/core/advancemapparser.cpp \
src/ui/aboutporymap.cpp \
src/ui/checkeredbgscene.cpp \
src/ui/colorinputwidget.cpp \
src/ui/combobox.cpp \
src/ui/connectionslistitem.cpp \
src/ui/customattributesdialog.cpp \
src/ui/customattributestable.cpp \
@ -121,8 +122,7 @@ SOURCES += src/core/advancemapparser.cpp \
src/ui/newlayoutform.cpp \
src/ui/newlocationdialog.cpp \
src/ui/newmapgroupdialog.cpp \
src/ui/noscrollcombobox.cpp \
src/ui/noscrollspinbox.cpp \
src/ui/noscrollwidgets.cpp \
src/ui/montabwidget.cpp \
src/ui/encountertablemodel.cpp \
src/ui/encountertabledelegates.cpp \
@ -195,12 +195,15 @@ HEADERS += include/core/advancemapparser.h \
include/lib/orderedjson.h \
include/ui/aboutporymap.h \
include/ui/checkeredbgscene.h \
include/ui/combobox.h \
include/ui/connectionslistitem.h \
include/ui/customattributesdialog.h \
include/ui/customattributestable.h \
include/ui/customscriptseditor.h \
include/ui/customscriptslistitem.h \
include/ui/divingmappixmapitem.h \
include/ui/edithistoryspinbox.h \
include/ui/eventcombobox.h \
include/ui/eventpixmapitem.h \
include/ui/bordermetatilespixmapitem.h \
include/ui/collisionpixmapitem.h \
@ -239,9 +242,7 @@ HEADERS += include/core/advancemapparser.h \
include/ui/newlayoutform.h \
include/ui/newlocationdialog.h \
include/ui/newmapgroupdialog.h \
include/ui/noscrollcombobox.h \
include/ui/noscrollspinbox.h \
include/ui/noscrolltextedit.h \
include/ui/noscrollwidgets.h \
include/ui/montabwidget.h \
include/ui/encountertablemodel.h \
include/ui/encountertabledelegates.h \

View File

@ -541,8 +541,6 @@ void Editor::configureEncounterJSON(QWidget *window) {
QVBoxLayout *slotChoiceLayout = new QVBoxLayout;
if (useGroups) {
auto groupCombo = new NoScrollComboBox;
groupCombo->setEditable(false);
groupCombo->setMinimumContentsLength(10);
connect(groupCombo, QOverload<const QString &>::of(&QComboBox::textActivated), [&tempFields, &currentField, &updateTotal, index](QString newGroupName) {
for (EncounterField &field : tempFields) {
if (field.name == currentField.name) {
@ -1035,7 +1033,7 @@ QString Editor::getDivingMapName(const QString &direction) const {
return (pixmapItem && pixmapItem->connection()) ? pixmapItem->connection()->targetMapName() : QString();
}
void Editor::onDivingMapEditingFinished(NoScrollComboBox *combo, const QString &direction) {
void Editor::onDivingMapEditingFinished(ComboBox *combo, const QString &direction) {
if (!setDivingMapName(combo->currentText(), direction)) {
// If user input was invalid, restore the combo to the previously-valid text.
combo->setTextItem(getDivingMapName(direction));

View File

@ -385,7 +385,7 @@ void MainWindow::initExtraSignals() {
connect(ui->action_NewMap, &QAction::triggered, this, &MainWindow::openNewMapDialog);
connect(ui->action_NewLayout, &QAction::triggered, this, &MainWindow::openNewLayoutDialog);
connect(ui->comboBox_LayoutSelector, &NoScrollComboBox::editingFinished, this, &MainWindow::onLayoutSelectorEditingFinished);
connect(ui->comboBox_LayoutSelector, &ComboBox::editingFinished, this, &MainWindow::onLayoutSelectorEditingFinished);
connect(ui->checkBox_smartPaths, &QCheckBox::toggled, this, &MainWindow::setSmartPathsEnabled);
connect(ui->checkBox_ToggleBorder, &QCheckBox::toggled, this, &MainWindow::setBorderVisibility);
connect(ui->checkBox_MirrorConnections, &QCheckBox::toggled, this, &MainWindow::setMirrorConnectionsEnabled);
@ -502,9 +502,9 @@ void MainWindow::initMiscHeapObjects() {
void MainWindow::initMapList() {
ui->mapListContainer->setCurrentIndex(porymapConfig.mapListTab);
WheelFilter *wheelFilter = new WheelFilter(this);
ui->mainTabBar->installEventFilter(wheelFilter);
ui->mapListContainer->tabBar()->installEventFilter(wheelFilter);
auto noScrollFilter = new NoScrollFilter(this, false);
ui->mainTabBar->installEventFilter(noScrollFilter);
ui->mapListContainer->tabBar()->installEventFilter(noScrollFilter);
// Create buttons for adding and removing items from the mapList
QFrame *buttonFrame = new QFrame(this->ui->mapListContainer);
@ -1455,13 +1455,13 @@ bool MainWindow::setProjectUI() {
ui->comboBox_DiveMap->clear();
ui->comboBox_DiveMap->addItems(project->mapNames());
ui->comboBox_DiveMap->setClearButtonEnabled(true);
ui->comboBox_DiveMap->setFocusedScrollingEnabled(false);
ui->comboBox_DiveMap->setAllowScrollingIfFocused(false);
const QSignalBlocker b_EmergeMap(ui->comboBox_EmergeMap);
ui->comboBox_EmergeMap->clear();
ui->comboBox_EmergeMap->addItems(project->mapNames());
ui->comboBox_EmergeMap->setClearButtonEnabled(true);
ui->comboBox_EmergeMap->setFocusedScrollingEnabled(false);
ui->comboBox_EmergeMap->setAllowScrollingIfFocused(false);
// Show/hide parts of the UI that are dependent on the user's project settings

69
src/ui/combobox.cpp Normal file
View File

@ -0,0 +1,69 @@
#include "combobox.h"
#include "utility.h"
#include <QCompleter>
ComboBox::ComboBox(QWidget *parent) : QComboBox(parent) {
// QComboBox (as of writing) has no 'editing finished' signal to capture
// changes made either through the text edit or the drop-down.
connect(this, QOverload<int>::of(&QComboBox::activated), this, &ComboBox::editingFinished);
}
void ComboBox::initLineEdit(QLineEdit *edit) {
if (!edit) return;
connect(edit, &QLineEdit::editingFinished, this, &ComboBox::editingFinished, Qt::UniqueConnection);
if (edit->completer()) {
// Allow items to be searched by any part of the word, displaying all matches.
// The default completer behavior is not particularly good, so we do this for all our combo boxes.
edit->completer()->setCompletionMode(QCompleter::PopupCompletion);
edit->completer()->setFilterMode(Qt::MatchContains);
}
}
void ComboBox::setEditable(bool editable) {
QComboBox::setEditable(editable);
// Changing editability will either create or destroy the line edit.
// If it was newly-created it needs to be connected.
if (editable) initLineEdit(lineEdit());
}
void ComboBox::setLineEdit(QLineEdit *edit) {
QComboBox::setLineEdit(edit);
initLineEdit(edit);
}
void ComboBox::setItem(int index, const QString &text) {
if (index >= 0) {
// Valid item
setCurrentIndex(index);
} else if (isEditable()) {
// Invalid item in editable box, just display the text
setCurrentText(text);
} else {
// Invalid item in uneditable box, display text as placeholder
// On Qt < 5.15 this will display an empty box
#if (QT_VERSION >= QT_VERSION_CHECK(5, 15, 0))
setPlaceholderText(text);
#endif
setCurrentIndex(index);
}
}
void ComboBox::setTextItem(const QString &text){
setItem(findText(text), text);
}
void ComboBox::setNumberItem(int value) {
setItem(findData(value), QString::number(value));
}
void ComboBox::setHexItem(uint32_t value) {
setItem(findData(value), Util::toHexString(value));
}
void ComboBox::setClearButtonEnabled(bool enabled) {
if (lineEdit()) lineEdit()->setClearButtonEnabled(enabled);
}

View File

@ -16,7 +16,6 @@ ConnectionsListItem::ConnectionsListItem(QWidget *parent, MapConnection * connec
// Direction
const QSignalBlocker b_Direction(ui->comboBox_Direction);
ui->comboBox_Direction->setMinimumContentsLength(0);
ui->comboBox_Direction->addItems(MapConnection::cardinalDirections);
ui->comboBox_Direction->installEventFilter(this);
@ -26,7 +25,7 @@ ConnectionsListItem::ConnectionsListItem(QWidget *parent, MapConnection * connec
const QSignalBlocker b_Map(ui->comboBox_Map);
ui->comboBox_Map->setMinimumContentsLength(6);
ui->comboBox_Map->addItems(mapNames);
ui->comboBox_Map->setFocusedScrollingEnabled(false); // Scrolling could cause rapid changes to many different maps
ui->comboBox_Map->setAllowScrollingIfFocused(false); // Scrolling could cause rapid changes to many different maps
ui->comboBox_Map->setInsertPolicy(QComboBox::NoInsert);
ui->comboBox_Map->installEventFilter(this);

View File

@ -16,7 +16,6 @@ CustomAttributesDialog::CustomAttributesDialog(CustomAttributesTable *table) :
// Type combo box
ui->comboBox_Type->addItems({"String", "Number", "Boolean"});
ui->comboBox_Type->setEditable(false);
// When the value type is changed, update the value input widget
connect(ui->comboBox_Type, QOverload<int>::of(&QComboBox::currentIndexChanged), this, &CustomAttributesDialog::setInputType);

View File

@ -1,6 +1,6 @@
#include "customattributestable.h"
#include "parseutil.h"
#include "noscrollspinbox.h"
#include "noscrollwidgets.h"
#include "utility.h"
#include <QHeaderView>
#include <QScrollBar>

View File

@ -1,7 +1,7 @@
#include "divingmappixmapitem.h"
#include "config.h"
DivingMapPixmapItem::DivingMapPixmapItem(MapConnection *connection, NoScrollComboBox *combo)
DivingMapPixmapItem::DivingMapPixmapItem(MapConnection *connection, ComboBox *combo)
: QGraphicsPixmapItem(getBasePixmap(connection))
{
m_connection = connection;

View File

@ -3,7 +3,7 @@
#include <QSpinBox>
#include "project.h"
#include "noscrollcombobox.h"
#include "noscrollwidgets.h"
@ -20,6 +20,7 @@ void SpeciesComboDelegate::paint(QPainter *painter, const QStyleOptionViewItem &
QWidget *SpeciesComboDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem &, const QModelIndex &) const {
NoScrollComboBox *editor = new NoScrollComboBox(parent);
editor->setEditable(true);
editor->setFrame(false);
editor->addItems(this->project->speciesNames);
return editor;

View File

@ -3,16 +3,6 @@
#include <QGraphicsSceneWheelEvent>
bool WheelFilter::eventFilter(QObject *, QEvent *event) {
if (event->type() == QEvent::Wheel) {
return true;
}
return false;
}
bool MapSceneEventFilter::eventFilter(QObject*, QEvent *event) {
if (event->type() == QEvent::GraphicsSceneWheel) {
QGraphicsSceneWheelEvent *wheelEvent = static_cast<QGraphicsSceneWheelEvent *>(event);

View File

@ -30,7 +30,7 @@ void EventFrame::setup() {
QHBoxLayout *l_layout_xyz = new QHBoxLayout();
// x spinner & label
this->spinner_x = new NoScrollSpinBox(this);
this->spinner_x = new EditHistorySpinBox(this);
this->spinner_x->setMinimum(numeric_limits<int16_t>::min());
this->spinner_x->setMaximum(numeric_limits<int16_t>::max());
@ -43,7 +43,7 @@ void EventFrame::setup() {
l_layout_xyz->addLayout(l_layout_x);
// y spinner & label
this->spinner_y = new NoScrollSpinBox(this);
this->spinner_y = new EditHistorySpinBox(this);
this->spinner_y->setMinimum(numeric_limits<int16_t>::min());
this->spinner_y->setMaximum(numeric_limits<int16_t>::max());
@ -114,7 +114,7 @@ void EventFrame::connectSignals(MainWindow *) {
}
});
connect(this->event->getPixmapItem(), &EventPixmapItem::xChanged, this->spinner_x, &NoScrollSpinBox::setValue);
connect(this->event->getPixmapItem(), &EventPixmapItem::xChanged, this->spinner_x, &EditHistorySpinBox::setValue);
this->spinner_y->disconnect();
connect(this->spinner_y, QOverload<int>::of(&QSpinBox::valueChanged), [this](int value) {
@ -123,7 +123,7 @@ void EventFrame::connectSignals(MainWindow *) {
this->event->getMap()->commit(new EventMove(QList<Event *>() << this->event, 0, delta, this->spinner_y->getActionId()));
}
});
connect(this->event->getPixmapItem(), &EventPixmapItem::yChanged, this->spinner_y, &NoScrollSpinBox::setValue);
connect(this->event->getPixmapItem(), &EventPixmapItem::yChanged, this->spinner_y, &EditHistorySpinBox::setValue);
this->spinner_z->disconnect();
connect(this->spinner_z, QOverload<int>::of(&QSpinBox::valueChanged), [this](int value) {
@ -181,7 +181,7 @@ void EventFrame::setActive(bool active) {
this->blockSignals(!active);
}
void EventFrame::populateDropdown(NoScrollComboBox * combo, const QStringList &items) {
void EventFrame::populateDropdown(EventComboBox * combo, const QStringList &items) {
// Set the items in the combo box. This may be called after the frame is initialized
// if the frame needs to be repopulated, so ensure the text in the combo is preserved
// and that we don't accidentally fire 'currentTextChanged'.
@ -192,7 +192,7 @@ void EventFrame::populateDropdown(NoScrollComboBox * combo, const QStringList &i
combo->setTextItem(savedText);
}
void EventFrame::populateScriptDropdown(NoScrollComboBox * combo, Project * project) {
void EventFrame::populateScriptDropdown(EventComboBox * combo, Project * project) {
// The script dropdown and autocomplete are populated with scripts used by the map's events and from its scripts file.
Map *map = this->event ? this->event->getMap() : nullptr;
if (!map)
@ -223,7 +223,7 @@ void EventFrame::populateScriptDropdown(NoScrollComboBox * combo, Project * proj
connect(map, &Map::scriptsModified, this, &EventFrame::invalidateValues, Qt::UniqueConnection);
}
void EventFrame::populateMapNameDropdown(NoScrollComboBox * combo, Project * project) {
void EventFrame::populateMapNameDropdown(EventComboBox * combo, Project * project) {
if (!project)
return;
@ -233,7 +233,7 @@ void EventFrame::populateMapNameDropdown(NoScrollComboBox * combo, Project * pro
connect(project, &Project::mapCreated, this, &EventFrame::invalidateValues, Qt::UniqueConnection);
}
void EventFrame::populateIdNameDropdown(NoScrollComboBox * combo, Project * project, const QString &mapName, Event::Group group) {
void EventFrame::populateIdNameDropdown(EventComboBox * combo, Project * project, const QString &mapName, Event::Group group) {
if (!project || !project->isKnownMap(mapName))
return;
@ -257,7 +257,7 @@ void ObjectFrame::setup() {
// sprite combo
QFormLayout *l_form_sprite = new QFormLayout();
this->combo_sprite = new NoScrollComboBox(this);
this->combo_sprite = new EventComboBox(this);
static const QString combo_sprite_toolTip = Util::toHtmlParagraph("The sprite graphics to use for this object.");
this->combo_sprite->setToolTip(combo_sprite_toolTip);
l_form_sprite->addRow("Sprite", this->combo_sprite);
@ -265,7 +265,7 @@ void ObjectFrame::setup() {
// movement
QFormLayout *l_form_movement = new QFormLayout();
this->combo_movement = new NoScrollComboBox(this);
this->combo_movement = new EventComboBox(this);
static const QString combo_movement_toolTip = Util::toHtmlParagraph("The object's natural movement behavior when the player is not interacting with it.");
this->combo_movement->setToolTip(combo_movement_toolTip);
l_form_movement->addRow("Movement", this->combo_movement);
@ -291,7 +291,7 @@ void ObjectFrame::setup() {
// script
QFormLayout *l_form_script = new QFormLayout();
this->combo_script = new NoScrollComboBox(this);
this->combo_script = new EventComboBox(this);
static const QString combo_script_toolTip = Util::toHtmlParagraph("The script that is executed with this event.");
this->combo_script->setToolTip(combo_script_toolTip);
@ -312,7 +312,7 @@ void ObjectFrame::setup() {
// event flag
QFormLayout *l_form_flag = new QFormLayout();
this->combo_flag = new NoScrollComboBox(this);
this->combo_flag = new EventComboBox(this);
static const QString combo_flag_toolTip = Util::toHtmlParagraph("The flag that hides the object when set.");
this->combo_flag->setToolTip(combo_flag_toolTip);
l_form_flag->addRow("Event Flag", this->combo_flag);
@ -320,7 +320,7 @@ void ObjectFrame::setup() {
// trainer type
QFormLayout *l_form_trainer = new QFormLayout();
this->combo_trainer_type = new NoScrollComboBox(this);
this->combo_trainer_type = new EventComboBox(this);
static const QString combo_trainer_type_toolTip = Util::toHtmlParagraph("The trainer type of this object event. If it is not a trainer, use NONE. "
"SEE ALL DIRECTIONS should only be used with a sight radius of 1.");
this->combo_trainer_type->setToolTip(combo_trainer_type_toolTip);
@ -329,7 +329,7 @@ void ObjectFrame::setup() {
// sight radius / berry tree id
QFormLayout *l_form_radius_treeid = new QFormLayout();
this->combo_radius_treeid = new NoScrollComboBox(this);
this->combo_radius_treeid = new EventComboBox(this);
static const QString combo_radius_treeid_toolTip = Util::toHtmlParagraph("The maximum sight range of a trainer, OR the unique id of the berry tree.");
this->combo_radius_treeid->setToolTip(combo_radius_treeid_toolTip);
l_form_radius_treeid->addRow("Sight Radius / Berry Tree ID", this->combo_radius_treeid);
@ -482,7 +482,7 @@ void CloneObjectFrame::setup() {
// sprite combo (edits disabled)
QFormLayout *l_form_sprite = new QFormLayout();
this->combo_sprite = new NoScrollComboBox(this);
this->combo_sprite = new EventComboBox(this);
static const QString combo_sprite_toolTip = Util::toHtmlParagraph("The sprite graphics to use for this object. This is updated automatically "
"to match the target object, and so can't be edited. By default the games "
"will get the graphics directly from the target object, so this field is ignored.");
@ -493,7 +493,7 @@ void CloneObjectFrame::setup() {
// clone map id combo
QFormLayout *l_form_dest_map = new QFormLayout();
this->combo_target_map = new NoScrollComboBox(this);
this->combo_target_map = new EventComboBox(this);
static const QString combo_target_map_toolTip = Util::toHtmlParagraph("The name of the map that the object being cloned is on.");
this->combo_target_map->setToolTip(combo_target_map_toolTip);
l_form_dest_map->addRow("Target Map", this->combo_target_map);
@ -501,7 +501,7 @@ void CloneObjectFrame::setup() {
// clone local id combo
QFormLayout *l_form_dest_id = new QFormLayout();
this->combo_target_id = new NoScrollComboBox(this);
this->combo_target_id = new EventComboBox(this);
static const QString combo_target_id_toolTip = Util::toHtmlParagraph("The Local ID name or number of the object being cloned.");
this->combo_target_id->setToolTip(combo_target_id_toolTip);
l_form_dest_id->addRow("Target Local ID", this->combo_target_id);
@ -599,7 +599,7 @@ void WarpFrame::setup() {
// desination map combo
QFormLayout *l_form_dest_map = new QFormLayout();
this->combo_dest_map = new NoScrollComboBox(this);
this->combo_dest_map = new EventComboBox(this);
static const QString combo_dest_map_toolTip = Util::toHtmlParagraph("The destination map name of the warp.");
this->combo_dest_map->setToolTip(combo_dest_map_toolTip);
l_form_dest_map->addRow("Destination Map", this->combo_dest_map);
@ -607,7 +607,7 @@ void WarpFrame::setup() {
// desination warp id
QFormLayout *l_form_dest_warp = new QFormLayout();
this->combo_dest_warp = new NoScrollComboBox(this);
this->combo_dest_warp = new EventComboBox(this);
static const QString combo_dest_warp_toolTip = Util::toHtmlParagraph("The warp id on the destination map.");
this->combo_dest_warp->setToolTip(combo_dest_warp_toolTip);
l_form_dest_warp->addRow("Destination Warp", this->combo_dest_warp);
@ -701,7 +701,7 @@ void TriggerFrame::setup() {
// script combo
QFormLayout *l_form_script = new QFormLayout();
this->combo_script = new NoScrollComboBox(this);
this->combo_script = new EventComboBox(this);
static const QString combo_script_toolTip = Util::toHtmlParagraph("The script that is executed with this event.");
this->combo_script->setToolTip(combo_script_toolTip);
l_form_script->addRow("Script", this->combo_script);
@ -709,7 +709,7 @@ void TriggerFrame::setup() {
// var combo
QFormLayout *l_form_var = new QFormLayout();
this->combo_var = new NoScrollComboBox(this);
this->combo_var = new EventComboBox(this);
static const QString combo_var_toolTip = Util::toHtmlParagraph("The variable by which the script is triggered. "
"The script is triggered when this variable's value matches 'Var Value'.");
this->combo_var->setToolTip(combo_var_toolTip);
@ -718,7 +718,7 @@ void TriggerFrame::setup() {
// var value combo
QFormLayout *l_form_var_val = new QFormLayout();
this->combo_var_value = new NoScrollComboBox(this);
this->combo_var_value = new EventComboBox(this);
static const QString combo_var_value_toolTip = Util::toHtmlParagraph("The variable's value that triggers the script.");
this->combo_var_value->setToolTip(combo_var_value_toolTip);
l_form_var_val->addRow("Var Value", this->combo_var_value);
@ -788,7 +788,7 @@ void WeatherTriggerFrame::setup() {
// weather combo
QFormLayout *l_form_weather = new QFormLayout();
this->combo_weather = new NoScrollComboBox(this);
this->combo_weather = new EventComboBox(this);
static const QString combo_weather_toolTip = Util::toHtmlParagraph("The weather that starts when the player steps on this spot.");
this->combo_weather->setToolTip(combo_weather_toolTip);
l_form_weather->addRow("Weather", this->combo_weather);
@ -837,7 +837,7 @@ void SignFrame::setup() {
// facing dir combo
QFormLayout *l_form_facing_dir = new QFormLayout();
this->combo_facing_dir = new NoScrollComboBox(this);
this->combo_facing_dir = new EventComboBox(this);
static const QString combo_facing_dir_toolTip = Util::toHtmlParagraph("The direction that the player must be facing to be able to interact with this event.");
this->combo_facing_dir->setToolTip(combo_facing_dir_toolTip);
l_form_facing_dir->addRow("Player Facing Direction", this->combo_facing_dir);
@ -845,7 +845,7 @@ void SignFrame::setup() {
// script combo
QFormLayout *l_form_script = new QFormLayout();
this->combo_script = new NoScrollComboBox(this);
this->combo_script = new EventComboBox(this);
static const QString combo_script_toolTip = Util::toHtmlParagraph("The script that is executed with this event.");
this->combo_script->setToolTip(combo_script_toolTip);
l_form_script->addRow("Script", this->combo_script);
@ -905,7 +905,7 @@ void HiddenItemFrame::setup() {
// item combo
QFormLayout *l_form_item = new QFormLayout();
this->combo_item = new NoScrollComboBox(this);
this->combo_item = new EventComboBox(this);
static const QString combo_item_toolTip = Util::toHtmlParagraph("The item to be given.");
this->combo_item->setToolTip(combo_item_toolTip);
l_form_item->addRow("Item", this->combo_item);
@ -913,7 +913,7 @@ void HiddenItemFrame::setup() {
// flag combo
QFormLayout *l_form_flag = new QFormLayout();
this->combo_flag = new NoScrollComboBox(this);
this->combo_flag = new EventComboBox(this);
static const QString combo_flag_toolTip = Util::toHtmlParagraph("The flag that is set when the hidden item is picked up.");
this->combo_flag->setToolTip(combo_flag_toolTip);
l_form_flag->addRow("Flag", this->combo_flag);
@ -1023,7 +1023,7 @@ void SecretBaseFrame::setup() {
// item combo
QFormLayout *l_form_base_id = new QFormLayout();
this->combo_base_id = new NoScrollComboBox(this);
this->combo_base_id = new EventComboBox(this);
static const QString combo_base_id_toolTip = Util::toHtmlParagraph("The secret base id that is inside this secret base entrance. "
"Secret base ids are meant to be unique to each and every secret base entrance.");
this->combo_base_id->setToolTip(combo_base_id_toolTip);
@ -1086,7 +1086,7 @@ void HealLocationFrame::setup() {
this->hideable_respawn_map = new QFrame;
QFormLayout *l_form_respawn_map = new QFormLayout(hideable_respawn_map);
l_form_respawn_map->setContentsMargins(0, 0, 0, 0);
this->combo_respawn_map = new NoScrollComboBox(hideable_respawn_map);
this->combo_respawn_map = new EventComboBox(hideable_respawn_map);
static const QString combo_respawn_map_toolTip = Util::toHtmlParagraph("The map where the player will respawn after whiteout.");
this->combo_respawn_map->setToolTip(combo_respawn_map_toolTip);
l_form_respawn_map->addRow("Respawn Map", this->combo_respawn_map);
@ -1096,7 +1096,7 @@ void HealLocationFrame::setup() {
this->hideable_respawn_npc = new QFrame;
QFormLayout *l_form_respawn_npc = new QFormLayout(hideable_respawn_npc);
l_form_respawn_npc->setContentsMargins(0, 0, 0, 0);
this->combo_respawn_npc = new NoScrollComboBox(hideable_respawn_npc);
this->combo_respawn_npc = new EventComboBox(hideable_respawn_npc);
static const QString combo_respawn_npc_toolTip = Util::toHtmlParagraph("The Local ID name or number of the NPC the player "
"interacts with upon respawning after whiteout.");
this->combo_respawn_npc->setToolTip(combo_respawn_npc_toolTip);

View File

@ -187,7 +187,7 @@ void MapHeaderForm::setAllowsEscaping(bool allowsEscaping) { ui->checkBox_
void MapHeaderForm::setFloorNumber(int floorNumber) { ui->spinBox_FloorNumber->setValue(floorNumber); }
// If we always call setText / setTextItem the user's cursor may move to the end of the text while they're typing.
void MapHeaderForm::setText(NoScrollComboBox *combo, const QString &text) const {
void MapHeaderForm::setText(ComboBox *combo, const QString &text) const {
if (combo->currentText() != text)
combo->setTextItem(text);
}

View File

@ -1,6 +1,6 @@
#include "montabwidget.h"
#include "noscrollcombobox.h"
#include "editor.h"
#include "noscrollwidgets.h"
#include "encountertablemodel.h"
#include "encountertabledelegates.h"
#include "eventfilters.h"
@ -15,7 +15,7 @@ MonTabWidget::MonTabWidget(Editor *editor, QWidget *parent) : QTabWidget(parent)
connect(this, &MonTabWidget::edited, this->editor, &Editor::wildMonTableEdited);
populate();
this->tabBar()->installEventFilter(new WheelFilter(this));
this->tabBar()->installEventFilter(new NoScrollFilter(this, false));
}
MonTabWidget::~MonTabWidget() {

View File

@ -1,97 +0,0 @@
#include "noscrollcombobox.h"
#include "utility.h"
#include <QCompleter>
#include <QLineEdit>
#include <QWheelEvent>
NoScrollComboBox::NoScrollComboBox(QWidget *parent)
: QComboBox(parent)
{
// Don't let scrolling hijack focus.
setFocusPolicy(Qt::StrongFocus);
// Make speed a priority when loading comboboxes.
setMinimumContentsLength(24);// an arbitrary limit
setSizeAdjustPolicy(QComboBox::AdjustToMinimumContentsLengthWithIcon);
// Allow items to be searched by any part of the word, displaying all matches.
setEditable(true);// can set to false manually when using
this->completer()->setCompletionMode(QCompleter::PopupCompletion);
this->completer()->setFilterMode(Qt::MatchContains);
static const QRegularExpression re("[^\\s]*");
QValidator *validator = new QRegularExpressionValidator(re, this);
this->setValidator(validator);
// QComboBox (as of writing) has no 'editing finished' signal to capture
// changes made either through the text edit or the drop-down.
connect(this, QOverload<int>::of(&QComboBox::activated), this, &NoScrollComboBox::editingFinished);
connect(this->lineEdit(), &QLineEdit::editingFinished, this, &NoScrollComboBox::editingFinished);
}
// On macOS QComboBox::setEditable and QComboBox::setLineEdit will override our changes to the focus policy, so we enforce it here.
void NoScrollComboBox::setEditable(bool editable) {
auto policy = focusPolicy();
QComboBox::setEditable(editable);
setFocusPolicy(policy);
}
void NoScrollComboBox::setLineEdit(QLineEdit *edit) {
auto policy = focusPolicy();
QComboBox::setLineEdit(edit);
setFocusPolicy(policy);
}
void NoScrollComboBox::wheelEvent(QWheelEvent *event)
{
// By default NoScrollComboBoxes will allow scrolling to modify its contents only when it explicitly has focus.
// If focusedScrollingEnabled is false it won't allow scrolling even with focus.
if (this->focusedScrollingEnabled && hasFocus()) {
QComboBox::wheelEvent(event);
} else {
event->ignore();
}
}
void NoScrollComboBox::setFocusedScrollingEnabled(bool enabled)
{
this->focusedScrollingEnabled = enabled;
}
void NoScrollComboBox::setItem(int index, const QString &text)
{
if (index >= 0) {
// Valid item
this->setCurrentIndex(index);
} else if (this->isEditable()) {
// Invalid item in editable box, just display the text
this->setCurrentText(text);
} else {
// Invalid item in uneditable box, display text as placeholder
// On Qt < 5.15 this will display an empty box
#if (QT_VERSION >= QT_VERSION_CHECK(5, 15, 0))
this->setPlaceholderText(text);
#endif
this->setCurrentIndex(index);
}
}
void NoScrollComboBox::setTextItem(const QString &text)
{
this->setItem(this->findText(text), text);
}
void NoScrollComboBox::setNumberItem(int value)
{
this->setItem(this->findData(value), QString::number(value));
}
void NoScrollComboBox::setHexItem(uint32_t value)
{
this->setItem(this->findData(value), Util::toHexString(value));
}
void NoScrollComboBox::setClearButtonEnabled(bool enabled) {
if (this->lineEdit())
this->lineEdit()->setClearButtonEnabled(enabled);
}

View File

@ -1,35 +0,0 @@
#include "noscrollspinbox.h"
#include <QWheelEvent>
#include <QLineEdit>
unsigned actionId = 0xffff;
NoScrollSpinBox::NoScrollSpinBox(QWidget *parent)
: QSpinBox(parent)
{
// Don't let scrolling hijack focus.
setFocusPolicy(Qt::StrongFocus);
}
void NoScrollSpinBox::wheelEvent(QWheelEvent *event)
{
// Only allow scrolling to modify contents when it explicitly has focus.
if (hasFocus()) {
QSpinBox::wheelEvent(event);
} else {
event->ignore();
}
}
void NoScrollSpinBox::focusOutEvent(QFocusEvent *event) {
actionId++;
QSpinBox::focusOutEvent(event);
}
void NoScrollSpinBox::setLineEditEnabled(bool enabled) {
this->lineEdit()->setReadOnly(!enabled);
}
unsigned NoScrollSpinBox::getActionId() {
return actionId;
}

View File

@ -0,0 +1,37 @@
#include "noscrollwidgets.h"
#include <QWheelEvent>
bool NoScrollFilter::eventFilter(QObject *object, QEvent *event) {
if (event->type() != QEvent::Wheel) return false;
if (m_allowIfFocused) {
auto widget = qobject_cast<QWidget*>(object);
if (widget && widget->hasFocus()) return false;
}
event->ignore();
return true;
}
NoScrollFilter* NoScrollFilter::apply(QObject *target, bool allowIfFocused) {
if (!target) return nullptr;
auto widget = qobject_cast<QWidget*>(target);
if (widget) widget->setFocusPolicy(Qt::StrongFocus);
auto filter = new NoScrollFilter(target, allowIfFocused);
target->installEventFilter(filter);
return filter;
}
// On macOS QComboBox::setEditable and QComboBox::setLineEdit will override our changes to the focus policy, so we enforce it here.
void NoScrollComboBox::setEditable(bool editable) {
auto policy = focusPolicy();
ComboBox::setEditable(editable);
setFocusPolicy(policy);
}
void NoScrollComboBox::setLineEdit(QLineEdit *edit) {
auto policy = focusPolicy();
ComboBox::setLineEdit(edit);
setFocusPolicy(policy);
}

View File

@ -1,6 +1,5 @@
#include "preferenceeditor.h"
#include "ui_preferenceeditor.h"
#include "noscrollcombobox.h"
#include "message.h"
#include <QAbstractButton>
@ -17,9 +16,6 @@ PreferenceEditor::PreferenceEditor(QWidget *parent) :
ui->setupUi(this);
setAttribute(Qt::WA_DeleteOnClose);
ui->comboBox_ColorSpace->setMinimumContentsLength(0);
ui->comboBox_ApplicationTheme->setMinimumContentsLength(0);
connect(ui->buttonBox, &QDialogButtonBox::clicked, this, &PreferenceEditor::dialogButtonClicked);
connect(ui->pushButton_CustomizeApplicationFont, &QPushButton::clicked, [this] {

View File

@ -1,6 +1,5 @@
#include "projectsettingseditor.h"
#include "config.h"
#include "noscrollcombobox.h"
#include "prefab.h"
#include "filedialog.h"
#include "newdefinedialog.h"
@ -80,7 +79,7 @@ void ProjectSettingsEditor::connectSignals() {
connect(ui->spinBox_TerrainTypeMask, &UIntSpinBox::textChanged, this, &ProjectSettingsEditor::updateAttributeMaskOverlapWarning);
// Record that there are unsaved changes if any of the settings are modified
for (auto combo : ui->centralwidget->findChildren<NoScrollComboBox *>()){
for (auto combo : ui->centralwidget->findChildren<ComboBox *>()){
// Changes to these two combo boxes are just for info display, don't mark as unsaved
if (combo != ui->comboBox_IconSpecies && combo != ui->comboBox_WarpBehaviors)
connect(combo, &QComboBox::currentTextChanged, this, &ProjectSettingsEditor::markEdited);

View File

@ -1102,10 +1102,10 @@ void RegionMapEditor::on_action_Swap_triggered() {
QFormLayout form(&popup);
QComboBox *oldSecBox = new QComboBox();
auto oldSecBox = new NoScrollComboBox();
oldSecBox->addItems(this->project->locationNames());
form.addRow(new QLabel("Map Section 1:"), oldSecBox);
QComboBox *newSecBox = new QComboBox();
auto newSecBox = new NoScrollComboBox();
newSecBox->addItems(this->project->locationNames());
form.addRow(new QLabel("Map Section 2:"), newSecBox);
@ -1141,10 +1141,10 @@ void RegionMapEditor::on_action_Replace_triggered() {
QFormLayout form(&popup);
QComboBox *oldSecBox = new QComboBox();
auto oldSecBox = new NoScrollComboBox();
oldSecBox->addItems(this->project->locationNames());
form.addRow(new QLabel("Old Map Section:"), oldSecBox);
QComboBox *newSecBox = new QComboBox();
auto newSecBox = new NoScrollComboBox();
newSecBox->addItems(this->project->locationNames());
form.addRow(new QLabel("New Map Section:"), newSecBox);

View File

@ -145,7 +145,6 @@ void TilesetEditor::initAttributesUi() {
for (auto i = project->metatileBehaviorMapInverse.constBegin(); i != project->metatileBehaviorMapInverse.constEnd(); i++) {
this->ui->comboBox_MetatileBehaviors->addItem(i.value(), i.key());
}
this->ui->comboBox_MetatileBehaviors->setMinimumContentsLength(0);
} else {
this->ui->frame_MetatileBehavior->setVisible(false);
}
@ -155,7 +154,6 @@ void TilesetEditor::initAttributesUi() {
for (auto i = project->terrainTypeToName.constBegin(); i != project->terrainTypeToName.constEnd(); i++) {
this->ui->comboBox_TerrainType->addItem(i.value(), i.key());
}
this->ui->comboBox_TerrainType->setMinimumContentsLength(0);
} else {
this->ui->frame_TerrainType->setVisible(false);
}
@ -165,7 +163,6 @@ void TilesetEditor::initAttributesUi() {
for (auto i = project->encounterTypeToName.constBegin(); i != project->encounterTypeToName.constEnd(); i++) {
this->ui->comboBox_EncounterType->addItem(i.value(), i.key());
}
this->ui->comboBox_EncounterType->setMinimumContentsLength(0);
} else {
this->ui->frame_EncounterType->setVisible(false);
}
@ -175,8 +172,6 @@ void TilesetEditor::initAttributesUi() {
this->ui->comboBox_LayerType->addItem("Normal - Middle/Top", Metatile::LayerType::Normal);
this->ui->comboBox_LayerType->addItem("Covered - Bottom/Middle", Metatile::LayerType::Covered);
this->ui->comboBox_LayerType->addItem("Split - Bottom/Top", Metatile::LayerType::Split);
this->ui->comboBox_LayerType->setEditable(false);
this->ui->comboBox_LayerType->setMinimumContentsLength(0);
if (!projectConfig.metatileLayerTypeMask) {
// User doesn't have triple layer metatiles, but has no layer type attribute.
// Porymap is still using the layer type value to render metatiles, and with
@ -668,7 +663,7 @@ uint32_t TilesetEditor::attributeNameToValue(Metatile::Attr attribute, const QSt
return text.toUInt(ok, 0);
}
void TilesetEditor::commitAttributeFromComboBox(Metatile::Attr attribute, NoScrollComboBox *combo) {
void TilesetEditor::commitAttributeFromComboBox(Metatile::Attr attribute, ComboBox *combo) {
if (!this->metatile) return;
bool ok;

View File

@ -1,8 +1,7 @@
#include "uintspinbox.h"
#include <QWheelEvent>
UIntSpinBox::UIntSpinBox(QWidget *parent)
: QAbstractSpinBox(parent),
: NoScrollAbstractSpinBox(parent),
m_minimum(0),
m_maximum(99),
m_value(m_minimum),
@ -11,9 +10,6 @@ UIntSpinBox::UIntSpinBox(QWidget *parent)
m_hasPadding(false),
m_numChars(2)
{
// Don't let scrolling hijack focus.
setFocusPolicy(Qt::StrongFocus);
this->updateEdit();
connect(lineEdit(), SIGNAL(textEdited(QString)), this, SLOT(onEditFinished()));
};
@ -193,15 +189,6 @@ QAbstractSpinBox::StepEnabled UIntSpinBox::stepEnabled() const {
return flags;
}
void UIntSpinBox::wheelEvent(QWheelEvent *event) {
// Only allow scrolling to modify contents when it explicitly has focus.
if (hasFocus()) {
QAbstractSpinBox::wheelEvent(event);
} else {
event->ignore();
}
}
void UIntSpinBox::focusOutEvent(QFocusEvent *event) {
this->updateEdit();
QAbstractSpinBox::focusOutEvent(event);