Line data Source code
1 : /*
2 : * SPDX-License-Identifier: GPL-3.0-only
3 : * MuseScore-CLA-applies
4 : *
5 : * MuseScore Studio
6 : * Music Composition & Notation
7 : *
8 : * Copyright (C) 2021 MuseScore Limited and others
9 : *
10 : * This program is free software: you can redistribute it and/or modify
11 : * it under the terms of the GNU General Public License version 3 as
12 : * published by the Free Software Foundation.
13 : *
14 : * This program is distributed in the hope that it will be useful,
15 : * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 : * GNU General Public License for more details.
18 : *
19 : * You should have received a copy of the GNU General Public License
20 : * along with this program. If not, see <https://www.gnu.org/licenses/>.
21 : */
22 :
23 : #pragma once
24 :
25 : #include <QObject>
26 : #include <QQmlParserStatus>
27 : #include <QQuickItem>
28 : #include <QMap>
29 :
30 : #include <qqmlintegration.h>
31 :
32 : #include "accessibility/iaccessible.h"
33 : #include "modularity/ioc.h"
34 : #include "accessibility/iaccessibilitycontroller.h"
35 :
36 : #define STATE_PROPERTY(P, S) \
37 : Q_PROPERTY(bool P READ P WRITE set_##P NOTIFY stateChanged FINAL) \
38 : bool P() const { return m_state.value(S, false); } \
39 : void set_##P(bool arg) { setState(S, arg); } \
40 :
41 : namespace muse::ui {
42 : namespace MUAccessible {
43 : Q_NAMESPACE;
44 : QML_ELEMENT;
45 :
46 : //! NOTE Please sync with accessibility::IAccessible::Role (src/framework/accessibility/iaccessible.h)
47 : enum Role {
48 : NoRole = 0,
49 : Application,
50 : Dialog,
51 : Panel,
52 : StaticText,
53 : EditableText,
54 : SilentRole,
55 : Button,
56 : CheckBox,
57 : RadioButton,
58 : ComboBox,
59 : List,
60 : ListItem,
61 : MenuItem,
62 : SpinBox,
63 : Range,
64 : Group,
65 : Table,
66 : ColumnHeader,
67 : RowHeader,
68 : Column,
69 : Row,
70 : Cell,
71 : Information,
72 : ElementOnScore
73 : };
74 0 : Q_ENUM_NS(Role)
75 : }
76 :
77 : class AccessibleItem : public QObject, public QQmlParserStatus, public accessibility::IAccessible, public Contextable
78 : {
79 : Q_OBJECT
80 : QML_ELEMENT;
81 :
82 : Q_PROPERTY(muse::ui::AccessibleItem * accessibleParent
83 : READ accessibleParent_property WRITE setAccessibleParent NOTIFY accessiblePrnChanged)
84 : Q_PROPERTY(muse::ui::MUAccessible::Role role READ role WRITE setRole NOTIFY roleChanged)
85 : Q_PROPERTY(QString name READ name WRITE setName NOTIFY nameChanged)
86 : Q_PROPERTY(QString description READ description WRITE setDescription NOTIFY descriptionChanged)
87 :
88 : Q_PROPERTY(QVariant value READ value WRITE setValue NOTIFY valueChanged)
89 : Q_PROPERTY(QVariant maximumValue READ maximumValue WRITE setMaximumValue NOTIFY maximumValueChanged)
90 : Q_PROPERTY(QVariant minimumValue READ minimumValue WRITE setMinimumValue NOTIFY minimumValueChanged)
91 : Q_PROPERTY(QVariant stepSize READ stepSize WRITE setStepSize NOTIFY stepSizeChanged)
92 :
93 : Q_PROPERTY(QString text READ text WRITE setText NOTIFY textChanged)
94 : Q_PROPERTY(QString selectedText READ selectedText WRITE setSelectedText NOTIFY selectedTextChanged)
95 : Q_PROPERTY(int selectionStart READ selectionStart WRITE setSelectionStart NOTIFY selectionStartChanged)
96 : Q_PROPERTY(int selectionEnd READ selectionEnd WRITE setSelectionEnd NOTIFY selectionEndChanged)
97 : Q_PROPERTY(int cursorPosition READ cursorPosition WRITE setCursorPosition NOTIFY cursorPositionChanged)
98 :
99 : Q_PROPERTY(int row READ row WRITE setRow NOTIFY rowChanged)
100 :
101 : Q_PROPERTY(bool ignored READ ignored WRITE setIgnored NOTIFY ignoredChanged)
102 : Q_PROPERTY(QQuickItem * visualItem READ visualItem WRITE setVisualItem NOTIFY visualItemChanged)
103 :
104 : Q_PROPERTY(QWindow * window READ window WRITE setWindow NOTIFY windowChanged)
105 :
106 : Q_INTERFACES(QQmlParserStatus)
107 :
108 : ContextInject<accessibility::IAccessibilityController> accessibilityController = { this };
109 :
110 : public:
111 0 : STATE_PROPERTY(enabled, State::Enabled)
112 0 : STATE_PROPERTY(selected, State::Selected)
113 0 : STATE_PROPERTY(focused, State::Focused)
114 0 : STATE_PROPERTY(checked, State::Checked)
115 :
116 : AccessibleItem(QObject* parent = nullptr);
117 : explicit AccessibleItem(const muse::modularity::ContextPtr& iocCtx, QObject* parent = nullptr);
118 : ~AccessibleItem();
119 :
120 : // IAccessible
121 : const IAccessible* accessibleParent() const override;
122 : size_t accessibleChildCount() const override;
123 : IAccessible* accessibleChild(size_t i) const override;
124 : QWindow* accessibleWindow() const override;
125 : muse::modularity::ContextPtr iocContext() const override;
126 :
127 : IAccessible::Role accessibleRole() const override;
128 : QString accessibleName() const override;
129 : QString accessibleDescription() const override;
130 : bool accessibleState(State st) const override;
131 : QRect accessibleRect() const override;
132 : bool accessibleIgnored() const override;
133 :
134 : // Value Interface
135 : QVariant accessibleValue() const override;
136 : QVariant accessibleMaximumValue() const override;
137 : QVariant accessibleMinimumValue() const override;
138 : QVariant accessibleValueStepSize() const override;
139 :
140 : // Text Interface
141 : void accessibleSelection(int selectionIndex, int* startOffset, int* endOffset) const override;
142 : int accessibleSelectionCount() const override;
143 :
144 : int accessibleCursorPosition() const override;
145 :
146 : QString accessibleText(int startOffset, int endOffset) const override;
147 : QString accessibleTextBeforeOffset(int offset, TextBoundaryType boundaryType, int* startOffset, int* endOffset) const override;
148 : QString accessibleTextAfterOffset(int offset, TextBoundaryType boundaryType, int* startOffset, int* endOffset) const override;
149 : QString accessibleTextAtOffset(int offset, TextBoundaryType boundaryType, int* startOffset, int* endOffset) const override;
150 : int accessibleCharacterCount() const override;
151 :
152 : // ListView item Interface
153 : int accessibleRowIndex() const override;
154 :
155 : async::Channel<Property, Val> accessiblePropertyChanged() const override;
156 :
157 : void setState(State st, bool arg) override;
158 : async::Channel<State, bool> accessibleStateChanged() const override;
159 : // -----
160 :
161 : // QQmlParserStatus
162 : void classBegin() override;
163 : void componentComplete() override;
164 :
165 : AccessibleItem* accessibleParent_property() const;
166 : MUAccessible::Role role() const;
167 : QString name() const;
168 : QString description() const;
169 :
170 : QVariant value() const;
171 : QVariant maximumValue() const;
172 : QVariant minimumValue() const;
173 : QVariant stepSize() const;
174 :
175 : QString text() const;
176 : QString selectedText() const;
177 : int selectionStart() const;
178 : int selectionEnd() const;
179 : int cursorPosition() const;
180 :
181 : int row() const;
182 :
183 : bool ignored() const;
184 : QQuickItem* visualItem() const;
185 :
186 : QWindow* window() const;
187 :
188 : public slots:
189 : void setAccessibleParent(ui::AccessibleItem* p);
190 : void setRole(MUAccessible::Role role);
191 : void setName(QString name);
192 : void setDescription(QString description);
193 : void setValue(QVariant value);
194 : void setMaximumValue(QVariant maximumValue);
195 : void setMinimumValue(QVariant minimumValue);
196 : void setStepSize(QVariant stepSize);
197 : void setText(const QString& text);
198 : void setSelectedText(const QString& selectedText);
199 : void setSelectionStart(int selectionStart);
200 : void setSelectionEnd(int selectionEnd);
201 : void setCursorPosition(int cursorPosition);
202 : void setRow(int row);
203 : void setIgnored(bool ignored);
204 : void setVisualItem(QQuickItem* item);
205 : void setWindow(QWindow* window);
206 :
207 : signals:
208 : void accessiblePrnChanged();
209 : void roleChanged(MUAccessible::Role role);
210 : void nameChanged(QString name);
211 : void descriptionChanged(QString description);
212 : void valueChanged(QVariant value);
213 : void maximumValueChanged(QVariant maximumValue);
214 : void minimumValueChanged(QVariant minimumValue);
215 : void stepSizeChanged(QVariant stepSize);
216 : void textChanged();
217 : void selectedTextChanged();
218 : void selectionStartChanged();
219 : void selectionEndChanged();
220 : void cursorPositionChanged();
221 : void rowChanged();
222 : void ignoredChanged(bool ignored);
223 : void visualItemChanged(QQuickItem* item);
224 : void stateChanged();
225 : void windowChanged();
226 :
227 : private:
228 : const IAccessible* accessibleRoot() const;
229 :
230 : void addChild(AccessibleItem* item);
231 : void removeChild(AccessibleItem* item);
232 :
233 : QQuickItem* resolveVisualItem() const;
234 :
235 : AccessibleItem* m_accessibleParent = nullptr;
236 : QList<AccessibleItem*> m_children;
237 : MUAccessible::Role m_role = MUAccessible::NoRole;
238 : QString m_name;
239 : QString m_description;
240 : QVariant m_value;
241 : QVariant m_maximumValue;
242 : QVariant m_minimumValue;
243 : QVariant m_stepSize;
244 : QString m_text;
245 : QString m_selectedText;
246 : int m_selectionStart = 0;
247 : int m_selectionEnd = 0;
248 : int m_cursorPosition = 0;
249 : int m_row = 0;
250 : bool m_ignored = false;
251 : QQuickItem* m_visualItem = nullptr;
252 : QWindow* m_window = nullptr;
253 : QMap<State, bool> m_state;
254 : async::Channel<Property, Val> m_accessiblePropertyChanged;
255 : async::Channel<State, bool> m_accessibleStateChanged;
256 : };
257 : }
|