QmlMaterial 0.1.0
Loading...
Searching...
No Matches
combo_box.hpp
1#pragma once
2
3#include "qml_material/control/control.hpp"
4#include "qml_material/model/combo_box_model.hpp"
5#include <QQmlComponent>
6#include <QValidator>
7#include <QtQuick/private/qquicktextinput_p.h>
8
9namespace qml_material
10{
11
12class QML_MATERIAL_API ComboBox : public Control {
13 Q_OBJECT
14 QML_NAMED_ELEMENT(ComboBoxBase)
15 Q_PROPERTY(
16 bool popupVisible READ popupVisible WRITE setPopupVisible NOTIFY popupVisibleChanged FINAL)
17 Q_PROPERTY(bool popupActiveFocus READ popupActiveFocus WRITE setPopupActiveFocus NOTIFY
18 popupActiveFocusChanged FINAL)
19 Q_PROPERTY(int highlightedIndex READ highlightedIndex NOTIFY highlightedIndexChanged FINAL)
20 Q_PROPERTY(bool pressed READ isPressed WRITE setPressed NOTIFY pressedChanged FINAL)
21 Q_PROPERTY(bool down READ isDown WRITE setDown RESET resetDown NOTIFY downChanged FINAL)
22 Q_PROPERTY(
23 bool wheelEnabled READ wheelEnabled WRITE setWheelEnabled NOTIFY wheelEnabledChanged FINAL)
24 Q_PROPERTY(bool editable READ editable WRITE setEditable NOTIFY editableChanged FINAL)
25 Q_PROPERTY(QString editText READ editText WRITE setEditText RESET resetEditText NOTIFY
26 editTextChanged FINAL)
27 Q_PROPERTY(bool acceptableInput READ acceptableInput NOTIFY acceptableInputChanged BINDABLE
28 bindableAcceptableInput FINAL)
29 Q_PROPERTY(bool inputMethodComposing READ inputMethodComposing NOTIFY
30 inputMethodComposingChanged FINAL)
31 Q_PROPERTY(
32 QValidator* validator READ validator WRITE setValidator NOTIFY validatorChanged FINAL)
33 Q_PROPERTY(Qt::InputMethodHints inputMethodHints READ inputMethodHints WRITE setInputMethodHints
34 NOTIFY inputMethodHintsChanged FINAL)
35 Q_PROPERTY(bool selectTextByMouse READ selectTextByMouse WRITE setSelectTextByMouse NOTIFY
36 selectTextByMouseChanged FINAL)
37 Q_PROPERTY(QVariant model READ model WRITE setModel NOTIFY modelChanged FINAL)
38 Q_PROPERTY(QQmlComponent* delegate READ delegate WRITE setDelegate NOTIFY delegateChanged FINAL)
39 Q_PROPERTY(QObject* delegateModel READ delegateModel NOTIFY delegateModelChanged FINAL)
40 Q_PROPERTY(int count READ count NOTIFY countChanged FINAL)
41 Q_PROPERTY(QString textRole READ textRole WRITE setTextRole NOTIFY textRoleChanged FINAL)
42 Q_PROPERTY(QString valueRole READ valueRole WRITE setValueRole NOTIFY valueRoleChanged FINAL)
43 Q_PROPERTY(
44 int currentIndex READ currentIndex WRITE setCurrentIndex NOTIFY currentIndexChanged FINAL)
45 Q_PROPERTY(QVariant currentValue READ currentValue WRITE setCurrentValue NOTIFY
46 currentValueChanged FINAL)
47 Q_PROPERTY(QString currentText READ currentText NOTIFY currentTextChanged FINAL)
48 Q_PROPERTY(QString displayText READ displayText WRITE setDisplayText RESET resetDisplayText
49 NOTIFY displayTextChanged FINAL)
50public:
51 explicit ComboBox(QQuickItem* parent = nullptr);
52 ~ComboBox() override;
53 bool popupVisible() const { return m_popup_visible; }
54 void setPopupVisible(bool);
55 bool popupActiveFocus() const { return m_popup_focus; }
56 void setPopupActiveFocus(bool);
57 int highlightedIndex() const { return m_highlight; }
58 bool isPressed() const { return m_pressed; }
59 void setPressed(bool);
60 bool isDown() const { return m_down.value_or(m_pressed || m_popup_visible); }
61 void setDown(bool);
62 void resetDown();
63 Q_INVOKABLE void openPopup();
64 Q_INVOKABLE void closePopup(bool accept = false);
65 Q_INVOKABLE void highlightIndex(int);
66 Q_SIGNAL void popupVisibleChanged();
67 Q_SIGNAL void popupActiveFocusChanged();
68 Q_SIGNAL void highlightedIndexChanged();
69 Q_SIGNAL void highlighted(int index);
70 Q_SIGNAL void pressedChanged();
71 Q_SIGNAL void downChanged();
72 Q_SIGNAL void popupOpenRequested();
73 Q_SIGNAL void popupCloseRequested();
74 bool wheelEnabled() const { return m_wheel_enabled; }
75 void setWheelEnabled(bool);
76 Q_SIGNAL void wheelEnabledChanged();
77 Q_INVOKABLE int find(const QString&, Qt::MatchFlags flags = Qt::MatchExactly) const;
78 Q_INVOKABLE void incrementCurrentIndex();
79 Q_INVOKABLE void decrementCurrentIndex();
80 bool editable() const { return m_editable; }
81 void setEditable(bool);
82 QString editText() const { return m_edit_text; }
83 void setEditText(const QString&);
84 void resetEditText() { setEditText({}); }
85 bool acceptableInput() const;
86 QBindable<bool> bindableAcceptableInput() const { return QBindable<bool>(&m_acceptable); }
87 bool inputMethodComposing() const;
88 QValidator* validator() const { return m_validator; }
89 void setValidator(QValidator*);
90 Qt::InputMethodHints inputMethodHints() const { return m_input_hints; }
91 void setInputMethodHints(Qt::InputMethodHints);
92 bool selectTextByMouse() const { return m_select_by_mouse; }
93 void setSelectTextByMouse(bool);
94 Q_INVOKABLE void selectAll();
95 Q_INVOKABLE void acceptInput();
96 Q_SIGNAL void editableChanged();
97 Q_SIGNAL void editTextChanged();
98 Q_SIGNAL void acceptableInputChanged();
99 Q_SIGNAL void inputMethodComposingChanged();
100 Q_SIGNAL void validatorChanged();
101 Q_SIGNAL void inputMethodHintsChanged();
102 Q_SIGNAL void selectTextByMouseChanged();
103 Q_SIGNAL void accepted();
104 QVariant model() const;
105 void setModel(const QVariant&);
106 QQmlComponent* delegate() const;
107 void setDelegate(QQmlComponent*);
108 QObject* delegateModel() const;
109 int count() const;
110 QString textRole() const;
111 void setTextRole(const QString&);
112 QString valueRole() const;
113 void setValueRole(const QString&);
114 int currentIndex() const { return m_index; }
115 void setCurrentIndex(int);
116 QVariant currentValue() const { return m_value; }
117 void setCurrentValue(const QVariant&);
118 QString currentText() const { return m_text; }
119 QString displayText() const { return m_display; }
120 void setDisplayText(const QString&);
121 void resetDisplayText();
122 Q_INVOKABLE QString textAt(int) const;
123 Q_INVOKABLE QVariant valueAt(int) const;
124 Q_INVOKABLE int indexOfValue(const QVariant&) const;
125 Q_INVOKABLE void activateIndex(int);
126
127 Q_SIGNAL void modelChanged();
128 Q_SIGNAL void delegateChanged();
129 Q_SIGNAL void delegateModelChanged();
130 Q_SIGNAL void countChanged();
131 Q_SIGNAL void textRoleChanged();
132 Q_SIGNAL void valueRoleChanged();
133 Q_SIGNAL void currentIndexChanged();
134 Q_SIGNAL void currentValueChanged();
135 Q_SIGNAL void currentTextChanged();
136 Q_SIGNAL void displayTextChanged();
137 Q_SIGNAL void activated(int index);
138
139protected:
140 void classBegin() override;
141 void componentComplete() override;
142 void focusInEvent(QFocusEvent*) override;
143 void focusOutEvent(QFocusEvent*) override;
144 bool eventFilter(QObject*, QEvent*) override;
145 void keyPressEvent(QKeyEvent*) override;
146 void keyReleaseEvent(QKeyEvent*) override;
147 void mousePressEvent(QMouseEvent*) override;
148 void mouseMoveEvent(QMouseEvent*) override;
149 void mouseReleaseEvent(QMouseEvent*) override;
150 void mouseUngrabEvent() override;
151 void touchEvent(QTouchEvent*) override;
152 void touchUngrabEvent() override;
153 void wheelEvent(QWheelEvent*) override;
154 void inputMethodEvent(QInputMethodEvent*) override;
155
156private:
157 void delegateClicked();
158 void delegateHovered();
159 void setHighlight(int, bool notify = false);
160 void navigate(int);
161 void checkFocus();
162 void finishPointer(const QPointF&);
163 bool m_popup_visible = false;
164 bool m_popup_focus = false;
165 bool m_pressed = false;
166 bool m_pointer = false;
167 int m_touch_id = -1;
168 int m_highlight = -1;
169 std::optional<bool> m_down;
170 enum class Selection
171 {
172 None,
173 Index,
174 Value
175 };
176 void ensureModel();
177 void synchronize();
178 void publish(int, const QVariant&);
179 std::unique_ptr<ComboBoxModel> m_data;
180 Selection m_selection = Selection::None;
181 int m_index = -1;
182 QVariant m_value;
183 QString m_text, m_display;
184 std::optional<QString> m_explicit_display;
185 bool m_ready = false;
186 void attachEditor();
187 void updateEditText();
188 int match(int start, const QString&, Qt::MatchFlags) const;
189 void keySearch(const QString&);
190 bool m_wheel_enabled = false;
191 bool m_user_edit = false;
192 bool m_allow_complete = true;
193 void updateEditorState();
194 int findEditText(const QString&) const;
195 QPointer<QQuickTextInput> m_editor;
196 QList<QMetaObject::Connection> m_editor_connections;
197 QPointer<QValidator> m_validator;
198 QMetaObject::Connection m_validator_connection;
199 QString m_edit_text;
200 Qt::InputMethodHints m_input_hints = Qt::ImhNoPredictiveText;
201 bool m_editable = false;
202 bool m_select_by_mouse = false;
203 bool m_accepting = false;
204 Q_OBJECT_BINDABLE_PROPERTY_WITH_ARGS(ComboBox, bool, m_acceptable, true,
205 &ComboBox::acceptableInputChanged)
206 bool m_composing = false;
207};
208
209} // namespace qml_material