Merge lp:~zsombi/ubuntu-ui-toolkit/cppAbstractButton into lp:ubuntu-ui-toolkit/staging
- cppAbstractButton
- Merge into staging
Status: | Merged | ||||||||
---|---|---|---|---|---|---|---|---|---|
Approved by: | Zsombor Egri | ||||||||
Approved revision: | 1638 | ||||||||
Merged at revision: | 1618 | ||||||||
Proposed branch: | lp:~zsombi/ubuntu-ui-toolkit/cppAbstractButton | ||||||||
Merge into: | lp:ubuntu-ui-toolkit/staging | ||||||||
Prerequisite: | lp:~zsombi/ubuntu-ui-toolkit/cppHaptics | ||||||||
Diff against target: |
807 lines (+449/-125) 21 files modified
components.api (+2/-2) src/Ubuntu/Components/1.3/AbstractButton.qml (+0/-109) src/Ubuntu/Components/1.3/Button.qml (+1/-1) src/Ubuntu/Components/1.3/ComboButton.qml (+1/-0) src/Ubuntu/Components/1.3/TextField.qml (+1/-1) src/Ubuntu/Components/ComponentModule.pro (+1/-2) src/Ubuntu/Components/ListItems/1.3/SingleControl.qml (+2/-1) src/Ubuntu/Components/plugin/plugin.cpp (+2/-0) src/Ubuntu/Components/plugin/plugin.pri (+4/-2) src/Ubuntu/Components/plugin/ucabstractbutton.cpp (+156/-0) src/Ubuntu/Components/plugin/ucabstractbutton.h (+64/-0) src/Ubuntu/Components/plugin/ucaction.cpp (+2/-1) src/Ubuntu/Components/plugin/ucactionitem.cpp (+15/-4) src/Ubuntu/Components/plugin/ucactionitem.h (+2/-0) src/Ubuntu/Components/qmldir (+0/-1) tests/unit/tst_components/tst_action.qml (+16/-0) tests/unit/tst_performance/AbstractButton13Grid.qml (+30/-0) tests/unit/tst_performance/AbstractButtonGrid.qml (+30/-0) tests/unit/tst_performance/tst_performance.cpp (+2/-0) tests/unit/tst_performance/tst_performance.pro (+3/-1) tests/unit_x11/tst_components/tst_abstractbutton13.qml (+115/-0) |
||||||||
To merge this branch: | bzr merge lp:~zsombi/ubuntu-ui-toolkit/cppAbstractButton | ||||||||
Related bugs: |
|
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
PS Jenkins bot | continuous-integration | Approve | |
Cris Dywan | Approve | ||
Tim Peeters | Approve | ||
Review via email: mp+268442@code.launchpad.net |
Commit message
AbstractButton to C++.
Description of the change
PS Jenkins bot (ps-jenkins) wrote : | # |
PS Jenkins bot (ps-jenkins) wrote : | # |
PASSED: Continuous integration, rev:1625
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
PS Jenkins bot (ps-jenkins) wrote : | # |
PASSED: Continuous integration, rev:1626
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
PS Jenkins bot (ps-jenkins) wrote : | # |
PASSED: Continuous integration, rev:1627
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
PS Jenkins bot (ps-jenkins) wrote : | # |
PASSED: Continuous integration, rev:1628
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
Tim Peeters (tpeeters) wrote : | # |
Why are you not importing the latest versions (not only of Ubuntu.Components, but also QtQuick and Ambience) in the performance tests?
686 === added file 'tests/
706 +import QtQuick 2.0
707 +import Ubuntu.Components 1.1
708 +import Ubuntu.
722 === modified file 'tests/
728 import QtQuick 2.0
729 -import Ubuntu.Components 1.1
730 +import Ubuntu.Components 1.3
731 import Ubuntu.
Tim Peeters (tpeeters) wrote : | # |
883 + // fixing bugs 1365471 and 1458028
884 + function test_no_
890 + // fixing bugs 1365471 and 1458028
891 + function test_pressAndHo
We have the policy to add _bugXXX to the function names. Let's do that here too because when a test starts to fail like that we can look up the bug immediately without going into the test code first.
Tim Peeters (tpeeters) wrote : | # |
351 === modified file 'src/Ubuntu/
360 + /*! \internal - overriding readonly pressed property due to the buggy pressed property exposure in former AbstractButton */
361 + property bool pressed: __mouseArea.pressed || (control && control.
I think we should override the property in Empty.qml instead to avoid problems in apps that have their own components deriving from Empty.
Tim Peeters (tpeeters) wrote : | # |
^maybe for 'hovered' too, to be sure.
Zsombor Egri (zsombi) wrote : | # |
> Why are you not importing the latest versions (not only of Ubuntu.Components,
> but also QtQuick and Ambience) in the performance tests?
>
> 686 === added file 'tests/
> 706 +import QtQuick 2.0
> 707 +import Ubuntu.Components 1.1
> 708 +import Ubuntu.
Copy-paste bug :)
>
> 722 === modified file 'tests/
> 728 import QtQuick 2.0
> 729 -import Ubuntu.Components 1.1
> 730 +import Ubuntu.Components 1.3
> 731 import Ubuntu.
This is the same reason we must get rid of the deprecation warnings... I'll roll this back
Zsombor Egri (zsombi) wrote : | # |
> 351 === modified file
> 'src/Ubuntu/
> 360 + /*! \internal - overriding readonly pressed property due to the
> buggy pressed property exposure in former AbstractButton */
> 361 + property bool pressed: __mouseArea.pressed || (control &&
> control.
>
>
> I think we should override the property in Empty.qml instead to avoid problems
> in apps that have their own components deriving from Empty.
Well, the property was there in SingleControl, so why would I move that to Empty?Beside, this should not happen according to the new design, so when you tap on a widget, that should not highlight the component.
Tim Peeters (tpeeters) wrote : | # |
> > 351 === modified file
> > 'src/Ubuntu/
> > 360 + /*! \internal - overriding readonly pressed property due to the
> > buggy pressed property exposure in former AbstractButton */
> > 361 + property bool pressed: __mouseArea.pressed || (control &&
> > control.
> >
> >
> > I think we should override the property in Empty.qml instead to avoid
> problems
> > in apps that have their own components deriving from Empty.
>
> Well, the property was there in SingleControl, so why would I move that to
> Empty?Beside, this should not happen according to the new design, so when you
> tap on a widget, that should not highlight the component.
Like SingleControl, custom list items may set the value of pressed. Making it read-only will break those custom list items. Of course we cannot be sure that this is (still) happening without checking the code of the apps.
Tim Peeters (tpeeters) wrote : | # |
Because it is cpp, the change will affect also 0.1-1.2... so it is dangerous.
PS Jenkins bot (ps-jenkins) wrote : | # |
PASSED: Continuous integration, rev:1630
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
Tim Peeters (tpeeters) wrote : | # |
Okay, looks good now.
Note that in all import versions we change the RW properties hovered and pressed to read-only. That makes sense (overriding the values of the properties would break the button's functionality), but before it lands we make sure that no apps are setting the properties.
Happroving.
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:1632
http://
Executed test runs:
FAILURE: http://
FAILURE: http://
FAILURE: http://
Click here to trigger a rebuild:
http://
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Autolanding.
More details in the following jenkins job:
http://
Executed test runs:
FAILURE: http://
FAILURE: http://
FAILURE: http://
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:1632
http://
Executed test runs:
FAILURE: http://
FAILURE: http://
FAILURE: http://
Click here to trigger a rebuild:
http://
- 1633. By Zsombor Egri
-
roll back AbstractButton for versions earlier than 1.3 to avoid API break
Cris Dywan (kalikiana) wrote : | # |
Leaving the 1.2 at QML is a good idea that I didn't consider an option. That way we're safe in terms of compatibility. Nice!
Let's see that the tests agree, too.
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:1633
http://
Executed test runs:
FAILURE: http://
FAILURE: http://
FAILURE: http://
Click here to trigger a rebuild:
http://
- 1634. By Zsombor Egri
-
documentation fix
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:1634
http://
Executed test runs:
UNSTABLE: http://
UNSTABLE: http://
deb: http://
UNSTABLE: http://
Click here to trigger a rebuild:
http://
Tim Peeters (tpeeters) wrote : | # |
there are some failures:
Test Result (2 failures / ±0)
components.
components.
- 1635. By Zsombor Egri
-
reverting unit test move for API 1.2
- 1636. By Zsombor Egri
-
separate 1.3 tests from earlier versions; add 1.3 performance tests
- 1637. By Zsombor Egri
-
overridden trigger() function support
PS Jenkins bot (ps-jenkins) wrote : | # |
PASSED: Continuous integration, rev:1637
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
Tim Peeters (tpeeters) wrote : | # |
222 === modified file 'src/Ubuntu/
223 --- src/Ubuntu/
224 +++ src/Ubuntu/
225 @@ -158,6 +158,10 @@
226 */
227 property real __contentsMargins: units.gu(2)
228
229 + // override pressed and hovered as those were declared writable
230 + property bool pressed: __mouseArea.pressed
231 + property bool hovered: __acceptEvents && __mouseArea.
232 +
do we still need this? 1.2 now has the old AbstractButton where those properties are already writable.
- 1638. By Zsombor Egri
-
revert unneeded 1.2 changes
PS Jenkins bot (ps-jenkins) wrote : | # |
PASSED: Continuous integration, rev:1638
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
Preview Diff
1 | === modified file 'components.api' |
2 | --- components.api 2015-08-20 08:10:44 +0000 |
3 | +++ components.api 2015-08-25 13:10:33 +0000 |
4 | @@ -4,10 +4,10 @@ |
5 | signal pressAndHold() |
6 | property bool pressed |
7 | Ubuntu.Components.AbstractButton 1.3: ActionItem |
8 | - property bool hovered |
9 | + readonly property bool hovered |
10 | signal clicked() |
11 | signal pressAndHold() |
12 | - property bool pressed |
13 | + readonly property bool pressed |
14 | Ubuntu.Components.Action 1.3 1.0 0.1: QtObject |
15 | property string description |
16 | property bool enabled |
17 | |
18 | === removed file 'src/Ubuntu/Components/1.3/AbstractButton.qml' |
19 | --- src/Ubuntu/Components/1.3/AbstractButton.qml 2015-04-25 08:54:58 +0000 |
20 | +++ src/Ubuntu/Components/1.3/AbstractButton.qml 1970-01-01 00:00:00 +0000 |
21 | @@ -1,109 +0,0 @@ |
22 | -/* |
23 | - * Copyright 2012 Canonical Ltd. |
24 | - * |
25 | - * This program is free software; you can redistribute it and/or modify |
26 | - * it under the terms of the GNU Lesser General Public License as published by |
27 | - * the Free Software Foundation; version 3. |
28 | - * |
29 | - * This program is distributed in the hope that it will be useful, |
30 | - * but WITHOUT ANY WARRANTY; without even the implied warranty of |
31 | - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
32 | - * GNU Lesser General Public License for more details. |
33 | - * |
34 | - * You should have received a copy of the GNU Lesser General Public License |
35 | - * along with this program. If not, see <http://www.gnu.org/licenses/>. |
36 | - */ |
37 | - |
38 | -import QtQuick 2.4 |
39 | -import Ubuntu.Components 1.3 |
40 | - |
41 | -/*! |
42 | - \qmlabstract AbstractButton |
43 | - \inqmlmodule Ubuntu.Components 1.1 |
44 | - \ingroup ubuntu |
45 | - \brief The AbstractButton class defines the behavior of the button. |
46 | - |
47 | - This class defines the behavior of the button: it defines the MouseArea |
48 | - and the states. |
49 | - All components deriving from this class support haptic feedback out of the box. |
50 | -*/ |
51 | -ActionItem { |
52 | - id: button |
53 | - |
54 | - /*! |
55 | - If an action is specified, the button's clicked signal will trigger the action. |
56 | - Subclasses of AbstractButton can use other properties of action (for example |
57 | - the text and iconName). |
58 | - \qmlproperty Action action |
59 | - */ |
60 | - |
61 | - /*! |
62 | - This handler is called when there is a mouse click on the button |
63 | - and the button is not disabled. If \b action is defined, |
64 | - the action will be triggered. |
65 | - */ |
66 | - signal clicked() |
67 | - |
68 | - /*! |
69 | - If a button is clicked, its triggered() signal will automatically be called. |
70 | - */ |
71 | - onClicked: button.trigger() |
72 | - |
73 | - Keys.onEnterPressed: clicked() |
74 | - Keys.onReturnPressed: clicked() |
75 | - |
76 | - /*! |
77 | - This handler is called when there is a long press. |
78 | - */ |
79 | - signal pressAndHold() |
80 | - |
81 | - /*! |
82 | - True if the user presses a mouse button in the button's mouse area. |
83 | - */ |
84 | - property bool pressed: mouseArea.pressed |
85 | - |
86 | - /*! |
87 | - True if the mouse cursor hovers over the button's mouse area. |
88 | - */ |
89 | - property bool hovered: __acceptEvents && mouseArea.containsMouse |
90 | - |
91 | - /*! |
92 | - \internal |
93 | - Disable or enable signal emition by default. |
94 | - Some classes want to emit the signal by themselves (ListItem.Standard) |
95 | - */ |
96 | - property bool __acceptEvents: true |
97 | - |
98 | - /*! |
99 | - \internal |
100 | - To get the properties of the mouse area in subclasses. |
101 | - */ |
102 | - property alias __mouseArea: mouseArea |
103 | - |
104 | - activeFocusOnPress: true |
105 | - |
106 | - MouseArea { |
107 | - id: mouseArea |
108 | - anchors.fill: parent |
109 | - // if mouseArea is given a new value, disable defaultMouseArea |
110 | - // as it might occlude the newly assigned mouse area. |
111 | - hoverEnabled: true |
112 | - |
113 | - // invoke Haptics singleton earlier than we press the button, |
114 | - // so we give some time for the singleton to sync settings with the service |
115 | - property bool hapticsEnabled: Haptics.enabled |
116 | - |
117 | - onClicked: { |
118 | - if (button.__acceptEvents) { |
119 | - // FIXME (Vivid) call this in the style rather than from AbstractButton |
120 | - Haptics.play(); |
121 | - button.clicked() |
122 | - } |
123 | - } |
124 | - onPressAndHold: { |
125 | - if (button.__acceptEvents) { |
126 | - button.pressAndHold() |
127 | - } |
128 | - } |
129 | - } |
130 | -} |
131 | |
132 | === modified file 'src/Ubuntu/Components/1.3/Button.qml' |
133 | --- src/Ubuntu/Components/1.3/Button.qml 2015-05-26 15:05:46 +0000 |
134 | +++ src/Ubuntu/Components/1.3/Button.qml 2015-08-25 13:10:33 +0000 |
135 | @@ -105,7 +105,7 @@ |
136 | /*! |
137 | The font used for the button's text. |
138 | */ |
139 | - property font font: __styleInstance ? __styleInstance.defaultFont : Qt.font({family: "Ubuntu", pixelSize: FontUtils.sizeToPixels("medium")}) |
140 | + property font font: __styleInstance.defaultFont |
141 | |
142 | /*! |
143 | The position of the icon relative to the text. Options |
144 | |
145 | === modified file 'src/Ubuntu/Components/1.3/ComboButton.qml' |
146 | --- src/Ubuntu/Components/1.3/ComboButton.qml 2015-05-21 10:50:35 +0000 |
147 | +++ src/Ubuntu/Components/1.3/ComboButton.qml 2015-08-25 13:10:33 +0000 |
148 | @@ -15,6 +15,7 @@ |
149 | */ |
150 | |
151 | import QtQuick 2.4 |
152 | +import Ubuntu.Components 1.3 |
153 | import Ubuntu.Components.Popups 1.3 |
154 | |
155 | /*! |
156 | |
157 | === modified file 'src/Ubuntu/Components/1.3/TextField.qml' |
158 | --- src/Ubuntu/Components/1.3/TextField.qml 2015-08-18 15:51:43 +0000 |
159 | +++ src/Ubuntu/Components/1.3/TextField.qml 2015-08-25 13:10:33 +0000 |
160 | @@ -896,7 +896,7 @@ |
161 | } |
162 | } |
163 | |
164 | - AbstractButton { |
165 | + Ubuntu.AbstractButton { |
166 | id: clearButton |
167 | objectName: "clear_button" |
168 | activeFocusOnPress: false |
169 | |
170 | === modified file 'src/Ubuntu/Components/ComponentModule.pro' |
171 | --- src/Ubuntu/Components/ComponentModule.pro 2015-08-19 08:57:18 +0000 |
172 | +++ src/Ubuntu/Components/ComponentModule.pro 2015-08-25 13:10:33 +0000 |
173 | @@ -80,8 +80,7 @@ |
174 | 1.2/UbuntuNumberAnimation.qml |
175 | |
176 | #1.3 |
177 | -QML_FILES += 1.3/AbstractButton.qml \ |
178 | - 1.3/ActionBar.qml \ |
179 | +QML_FILES += 1.3/ActionBar.qml \ |
180 | 1.3/ActionList.qml \ |
181 | 1.3/ActivityIndicator.qml \ |
182 | 1.3/AdaptivePageLayout.qml \ |
183 | |
184 | === modified file 'src/Ubuntu/Components/ListItems/1.3/SingleControl.qml' |
185 | --- src/Ubuntu/Components/ListItems/1.3/SingleControl.qml 2015-04-29 07:21:29 +0000 |
186 | +++ src/Ubuntu/Components/ListItems/1.3/SingleControl.qml 2015-08-25 13:10:33 +0000 |
187 | @@ -54,7 +54,8 @@ |
188 | |
189 | /*! \internal */ |
190 | onClicked: if (control && control.enabled && control.hasOwnProperty("clicked")) control.clicked() |
191 | - pressed: __mouseArea.pressed || (control && control.hasOwnProperty("pressed") && control.pressed) |
192 | + /*! \internal */ |
193 | + property bool pressed: __mouseArea.pressed || (control && control.hasOwnProperty("pressed") && control.pressed) |
194 | /*! \internal */ |
195 | onPressedChanged: if (control && control.enabled && control.hasOwnProperty("pressed")) control.pressed = singleControlListItem.pressed |
196 | |
197 | |
198 | === modified file 'src/Ubuntu/Components/plugin/plugin.cpp' |
199 | --- src/Ubuntu/Components/plugin/plugin.cpp 2015-08-19 08:44:45 +0000 |
200 | +++ src/Ubuntu/Components/plugin/plugin.cpp 2015-08-25 13:10:33 +0000 |
201 | @@ -64,6 +64,7 @@ |
202 | #include "ucnamespace.h" |
203 | #include "ucactionitem.h" |
204 | #include "uchaptics.h" |
205 | +#include "ucabstractbutton.h" |
206 | |
207 | #include <sys/types.h> |
208 | #include <unistd.h> |
209 | @@ -232,6 +233,7 @@ |
210 | qmlRegisterType<UCUbuntuShape, 2>(uri, 1, 3, "UbuntuShape"); |
211 | qmlRegisterType<UCProportionalShape>(uri, 1, 3, "ProportionalShape"); |
212 | qmlRegisterType<LiveTimer>(uri, 1, 3, "LiveTimer"); |
213 | + qmlRegisterType<UCAbstractButton>(uri, 1, 3, "AbstractButton"); |
214 | } |
215 | |
216 | void UbuntuComponentsPlugin::initializeEngine(QQmlEngine *engine, const char *uri) |
217 | |
218 | === modified file 'src/Ubuntu/Components/plugin/plugin.pri' |
219 | --- src/Ubuntu/Components/plugin/plugin.pri 2015-08-20 11:35:51 +0000 |
220 | +++ src/Ubuntu/Components/plugin/plugin.pri 2015-08-25 13:10:33 +0000 |
221 | @@ -82,7 +82,8 @@ |
222 | $$PWD/livetimer_p.h \ |
223 | $$PWD/timeutils_p.h \ |
224 | $$PWD/ucactionitem.h \ |
225 | - $$PWD/uchaptics.h |
226 | + $$PWD/uchaptics.h \ |
227 | + $$PWD/ucabstractbutton.h |
228 | |
229 | SOURCES += $$PWD/plugin.cpp \ |
230 | $$PWD/uctheme.cpp \ |
231 | @@ -136,7 +137,8 @@ |
232 | $$PWD/livetimer.cpp \ |
233 | $$PWD/livetimer_p.cpp \ |
234 | $$PWD/ucactionitem.cpp \ |
235 | - $$PWD/uchaptics.cpp |
236 | + $$PWD/uchaptics.cpp \ |
237 | + $$PWD/ucabstractbutton.cpp |
238 | |
239 | # adapters |
240 | SOURCES += $$PWD/adapters/alarmsadapter_organizer.cpp |
241 | |
242 | === added file 'src/Ubuntu/Components/plugin/ucabstractbutton.cpp' |
243 | --- src/Ubuntu/Components/plugin/ucabstractbutton.cpp 1970-01-01 00:00:00 +0000 |
244 | +++ src/Ubuntu/Components/plugin/ucabstractbutton.cpp 2015-08-25 13:10:33 +0000 |
245 | @@ -0,0 +1,156 @@ |
246 | +/* |
247 | + * Copyright 2015 Canonical Ltd. |
248 | + * |
249 | + * This program is free software; you can redistribute it and/or modify |
250 | + * it under the terms of the GNU Lesser General Public License as published by |
251 | + * the Free Software Foundation; version 3. |
252 | + * |
253 | + * This program is distributed in the hope that it will be useful, |
254 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
255 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
256 | + * GNU Lesser General Public License for more details. |
257 | + * |
258 | + * You should have received a copy of the GNU Lesser General Public License |
259 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
260 | + */ |
261 | + |
262 | +#include "ucabstractbutton.h" |
263 | +#include "uchaptics.h" |
264 | +#include <QtQuick/private/qquickitem_p.h> |
265 | +#include <QtQuick/private/qquickmousearea_p.h> |
266 | +#include <QtQml/private/qqmlglobal_p.h> |
267 | + |
268 | +/*! |
269 | + \qmltype AbstractButton |
270 | + \instantiates UCAbstractButton |
271 | + \inqmlmodule Ubuntu.Components 1.1 |
272 | + \ingroup ubuntu |
273 | + \brief The AbstractButton class defines the behavior of the button. |
274 | + |
275 | + This class defines the behavior of the button. All components deriving from |
276 | + this class support haptic feedback out of the box. |
277 | + |
278 | + If an action is specified, the button's clicked signal will trigger the action. |
279 | + Subclasses of AbstractButton can use other properties of action (for example |
280 | + the text and iconName). |
281 | +*/ |
282 | + |
283 | +/*! |
284 | + * |
285 | + * \qmlsignal AbstractButton::clicked() |
286 | + * This handler is called when there is a mouse click on the button and the button |
287 | + * is not disabled. If \l {ActionItem::action}{action} is defined, the action will be triggered. |
288 | + */ |
289 | + |
290 | +/*! |
291 | + * |
292 | + * \qmlsignal AbstractButton::pressAndHold() |
293 | + * This handler is called when there is a long press. |
294 | + */ |
295 | + |
296 | +UCAbstractButton::UCAbstractButton(QQuickItem *parent) |
297 | + : UCActionItem(parent) |
298 | + , m_mouseArea(new QQuickMouseArea) |
299 | + , m_acceptEvents(true) |
300 | +{ |
301 | + setActiveFocusOnPress(true); |
302 | +} |
303 | + |
304 | +bool UCAbstractButton::isPressAndHoldConnected() |
305 | +{ |
306 | + static QMetaMethod method = QMetaMethod::fromSignal(&UCAbstractButton::pressAndHold); |
307 | + static int signalIdx = QMetaObjectPrivate::signalIndex(method); |
308 | + return QObjectPrivate::get(this)->isSignalConnected(signalIdx); |
309 | +} |
310 | + |
311 | +void UCAbstractButton::classBegin() |
312 | +{ |
313 | + UCActionItem::classBegin(); |
314 | + |
315 | + // make sure we have the haptics set up! |
316 | + HapticsProxy::instance().initialize(); |
317 | + |
318 | + // set up mouse area |
319 | + QQml_setParent_noEvent(m_mouseArea, this); |
320 | + m_mouseArea->setParentItem(this); |
321 | + QQuickAnchors *anchors = QQuickItemPrivate::get(m_mouseArea)->anchors(); |
322 | + anchors->setFill(this); |
323 | + m_mouseArea->setHoverEnabled(true); |
324 | +} |
325 | + |
326 | +void UCAbstractButton::componentComplete() |
327 | +{ |
328 | + UCActionItem::componentComplete(); |
329 | + // connect to the right slot, using macros so we get the proper slot |
330 | + connect(this, SIGNAL(clicked()), this, SLOT(trigger())); |
331 | + |
332 | + // bind mouse area |
333 | + connect(m_mouseArea, &QQuickMouseArea::pressedChanged, this, &UCAbstractButton::pressedChanged); |
334 | + connect(m_mouseArea, &QQuickMouseArea::hoveredChanged, this, &UCAbstractButton::hoveredChanged); |
335 | + connect(m_mouseArea, SIGNAL(clicked(QQuickMouseEvent*)), this, SLOT(_q_mouseAreaClicked())); |
336 | + if (isPressAndHoldConnected()) { |
337 | + connect(m_mouseArea, SIGNAL(pressAndHold(QQuickMouseEvent*)), this, SLOT(_q_mouseAreaPressAndHold())); |
338 | + } |
339 | +} |
340 | + |
341 | +// handle mouseClicked with Haptics |
342 | +void UCAbstractButton::_q_mouseAreaClicked() |
343 | +{ |
344 | + // required by the deprecated ListItem module |
345 | + if (!m_acceptEvents) { |
346 | + return; |
347 | + } |
348 | + // play haptics |
349 | + HapticsProxy::instance().play(QVariant()); |
350 | + Q_EMIT clicked(); |
351 | +} |
352 | + |
353 | +// handle pressAndHold |
354 | +void UCAbstractButton::_q_mouseAreaPressAndHold() |
355 | +{ |
356 | + // required by the deprecated ListItem module |
357 | + if (!m_acceptEvents) { |
358 | + return; |
359 | + } |
360 | + Q_EMIT pressAndHold(); |
361 | +} |
362 | + |
363 | +// emit clicked when Enter/Return is pressed |
364 | +void UCAbstractButton::keyPressEvent(QKeyEvent *event) |
365 | +{ |
366 | + UCActionItem::keyPressEvent(event); |
367 | + |
368 | + switch (event->key()) { |
369 | + case Qt::Key_Enter: |
370 | + case Qt::Key_Return: |
371 | + // FIXME: space may also come here, however that depends on the button type |
372 | + // (i.e default Dialog btn) so we may need to add that to Button |
373 | + { |
374 | + Q_EMIT clicked(); |
375 | + break; |
376 | + } |
377 | + } |
378 | +} |
379 | + |
380 | +/*! |
381 | + * \qmlproperty bool AbstractButton::pressed |
382 | + * True if the user presses a mouse button in the button's mouse area. |
383 | + */ |
384 | +bool UCAbstractButton::pressed() const |
385 | +{ |
386 | + return m_mouseArea ? m_mouseArea->pressed() : false; |
387 | +} |
388 | + |
389 | +/*! |
390 | + * \qmlproperty bool AbstractButton::hovered |
391 | + * True if the mouse cursor hovers over the button's mouse area. |
392 | + */ |
393 | +bool UCAbstractButton::hovered() const |
394 | +{ |
395 | + return m_mouseArea ? m_mouseArea->hovered() : false; |
396 | +} |
397 | + |
398 | +QQuickMouseArea *UCAbstractButton::privateMouseArea() const |
399 | +{ |
400 | + return m_mouseArea; |
401 | +} |
402 | |
403 | === added file 'src/Ubuntu/Components/plugin/ucabstractbutton.h' |
404 | --- src/Ubuntu/Components/plugin/ucabstractbutton.h 1970-01-01 00:00:00 +0000 |
405 | +++ src/Ubuntu/Components/plugin/ucabstractbutton.h 2015-08-25 13:10:33 +0000 |
406 | @@ -0,0 +1,64 @@ |
407 | +/* |
408 | + * Copyright 2015 Canonical Ltd. |
409 | + * |
410 | + * This program is free software; you can redistribute it and/or modify |
411 | + * it under the terms of the GNU Lesser General Public License as published by |
412 | + * the Free Software Foundation; version 3. |
413 | + * |
414 | + * This program is distributed in the hope that it will be useful, |
415 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
416 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
417 | + * GNU Lesser General Public License for more details. |
418 | + * |
419 | + * You should have received a copy of the GNU Lesser General Public License |
420 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
421 | + */ |
422 | + |
423 | +#ifndef UCABSTRACTBUTTON_H |
424 | +#define UCABSTRACTBUTTON_H |
425 | + |
426 | +#include "ucactionitem.h" |
427 | + |
428 | +class QQuickMouseArea; |
429 | +class UCAbstractButton : public UCActionItem |
430 | +{ |
431 | + Q_OBJECT |
432 | + Q_PROPERTY(bool pressed READ pressed NOTIFY pressedChanged) |
433 | + Q_PROPERTY(bool hovered READ hovered NOTIFY hoveredChanged) |
434 | + |
435 | + // internal, declared to support the deprecated ListItem module |
436 | + Q_PROPERTY(bool __acceptEvents MEMBER m_acceptEvents) |
437 | + Q_PROPERTY(QQuickMouseArea *__mouseArea READ privateMouseArea CONSTANT) |
438 | +public: |
439 | + explicit UCAbstractButton(QQuickItem *parent = 0); |
440 | + |
441 | + bool pressed() const; |
442 | + bool hovered() const; |
443 | + |
444 | + bool privateAcceptEvents() const; |
445 | + void setPrivateAcceptEvents(bool accept); |
446 | + QQuickMouseArea *privateMouseArea() const; |
447 | + |
448 | +protected: |
449 | + void classBegin(); |
450 | + void componentComplete(); |
451 | + void keyPressEvent(QKeyEvent *key); |
452 | + |
453 | +Q_SIGNALS: |
454 | + void pressedChanged(); |
455 | + void hoveredChanged(); |
456 | + void clicked(); |
457 | + void pressAndHold(); |
458 | + |
459 | +protected Q_SLOTS: |
460 | + void _q_mouseAreaClicked(); |
461 | + void _q_mouseAreaPressAndHold(); |
462 | + |
463 | +protected: |
464 | + QQuickMouseArea *m_mouseArea; |
465 | + bool m_acceptEvents:1; |
466 | + |
467 | + bool isPressAndHoldConnected(); |
468 | +}; |
469 | + |
470 | +#endif // UCABSTRACTBUTTON_H |
471 | |
472 | === modified file 'src/Ubuntu/Components/plugin/ucaction.cpp' |
473 | --- src/Ubuntu/Components/plugin/ucaction.cpp 2015-08-18 15:51:43 +0000 |
474 | +++ src/Ubuntu/Components/plugin/ucaction.cpp 2015-08-25 13:10:33 +0000 |
475 | @@ -301,7 +301,8 @@ |
476 | return false; |
477 | } |
478 | |
479 | - trigger(); |
480 | + // do not call trigger() directly but invoke, as it may get overridden in QML |
481 | + metaObject()->invokeMethod(this, "trigger"); |
482 | return true; |
483 | } |
484 | |
485 | |
486 | === modified file 'src/Ubuntu/Components/plugin/ucactionitem.cpp' |
487 | --- src/Ubuntu/Components/plugin/ucactionitem.cpp 2015-08-19 06:56:56 +0000 |
488 | +++ src/Ubuntu/Components/plugin/ucactionitem.cpp 2015-08-25 13:10:33 +0000 |
489 | @@ -44,6 +44,17 @@ |
490 | connect(this, &UCActionItem::enabledChanged, this, &UCActionItem::_q_enabledChanged); |
491 | } |
492 | |
493 | +void UCActionItem::componentComplete() |
494 | +{ |
495 | + UCStyledItemBase::componentComplete(); |
496 | + // make sure we connect to the right signals, so we detach and re-attach actions |
497 | + // to make sure the SLOT macro picks up the custom trigger() slot |
498 | + if (m_action) { |
499 | + attachAction(false); |
500 | + attachAction(true); |
501 | + } |
502 | +} |
503 | + |
504 | void UCActionItem::_q_visibleChanged() |
505 | { |
506 | m_flags |= CustomVisible; |
507 | @@ -96,8 +107,8 @@ |
508 | void UCActionItem::attachAction(bool attach) |
509 | { |
510 | if (attach) { |
511 | - connect(this, &UCActionItem::triggered, |
512 | - m_action, &UCAction::triggered, Qt::DirectConnection); |
513 | + connect(this, SIGNAL(triggered(QVariant)), |
514 | + m_action, SLOT(trigger(QVariant)), Qt::DirectConnection); |
515 | connect(m_action, &UCAction::visibleChanged, |
516 | this, &UCActionItem::_q_updateVisible, Qt::DirectConnection); |
517 | connect(m_action, &UCAction::enabledChanged, |
518 | @@ -115,8 +126,8 @@ |
519 | this, &UCActionItem::iconNameChanged, Qt::DirectConnection); |
520 | } |
521 | } else { |
522 | - disconnect(this, &UCActionItem::triggered, |
523 | - m_action, &UCAction::triggered); |
524 | + disconnect(this, SIGNAL(triggered(QVariant)), |
525 | + m_action, SLOT(trigger(QVariant))); |
526 | disconnect(m_action, &UCAction::visibleChanged, |
527 | this, &UCActionItem::_q_updateVisible); |
528 | disconnect(m_action, &UCAction::enabledChanged, |
529 | |
530 | === modified file 'src/Ubuntu/Components/plugin/ucactionitem.h' |
531 | --- src/Ubuntu/Components/plugin/ucactionitem.h 2015-08-19 06:55:11 +0000 |
532 | +++ src/Ubuntu/Components/plugin/ucactionitem.h 2015-08-25 13:10:33 +0000 |
533 | @@ -70,6 +70,8 @@ |
534 | UCAction *m_action; |
535 | quint8 m_flags; |
536 | |
537 | + void componentComplete(); |
538 | + |
539 | void updateProperties(); |
540 | void attachAction(bool attach); |
541 | }; |
542 | |
543 | === modified file 'src/Ubuntu/Components/qmldir' |
544 | --- src/Ubuntu/Components/qmldir 2015-08-19 08:44:45 +0000 |
545 | +++ src/Ubuntu/Components/qmldir 2015-08-25 13:10:33 +0000 |
546 | @@ -115,7 +115,6 @@ |
547 | TabBar 1.3 1.3/TabBar.qml |
548 | Tabs 1.3 1.3/Tabs.qml |
549 | Label 1.3 1.3/Label.qml |
550 | -AbstractButton 1.3 1.3/AbstractButton.qml |
551 | ActivityIndicator 1.3 1.3/ActivityIndicator.qml |
552 | ProgressBar 1.3 1.3/ProgressBar.qml |
553 | TextField 1.3 1.3/TextField.qml |
554 | |
555 | === modified file 'tests/unit/tst_components/tst_action.qml' |
556 | --- tests/unit/tst_components/tst_action.qml 2015-07-09 17:55:03 +0000 |
557 | +++ tests/unit/tst_components/tst_action.qml 2015-08-25 13:10:33 +0000 |
558 | @@ -34,6 +34,11 @@ |
559 | return false; |
560 | } |
561 | |
562 | + function cleanup() { |
563 | + triggeredSignalSpy.target = action; |
564 | + triggeredSignalSpy.clear(); |
565 | + } |
566 | + |
567 | function initTestCase() { |
568 | compare(action.text, "", "text is empty string set by default") |
569 | compare(action.iconSource, "", "iconSource is empty string by default") |
570 | @@ -132,6 +137,12 @@ |
571 | verify(!data.inactive.active, "Context deactivation error"); |
572 | } |
573 | |
574 | + function test_overloaded_action_trigger() { |
575 | + triggeredSignalSpy.target = suppressTrigger; |
576 | + suppressTrigger.trigger(); |
577 | + compare(triggeredSignalSpy.count, 0, "Overloaded trigger should not trigger action"); |
578 | + } |
579 | + |
580 | Action { |
581 | id: action |
582 | } |
583 | @@ -185,4 +196,9 @@ |
584 | id: context2 |
585 | } |
586 | |
587 | + Action { |
588 | + id: suppressTrigger |
589 | + function trigger() {} |
590 | + } |
591 | + |
592 | } |
593 | |
594 | === added file 'tests/unit/tst_performance/AbstractButton13Grid.qml' |
595 | --- tests/unit/tst_performance/AbstractButton13Grid.qml 1970-01-01 00:00:00 +0000 |
596 | +++ tests/unit/tst_performance/AbstractButton13Grid.qml 2015-08-25 13:10:33 +0000 |
597 | @@ -0,0 +1,30 @@ |
598 | +/* |
599 | + * Copyright 2015 Canonical Ltd. |
600 | + * |
601 | + * This program is free software; you can redistribute it and/or modify |
602 | + * it under the terms of the GNU Lesser General Public License as published by |
603 | + * the Free Software Foundation; version 3. |
604 | + * |
605 | + * This program is distributed in the hope that it will be useful, |
606 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
607 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
608 | + * GNU Lesser General Public License for more details. |
609 | + * |
610 | + * You should have received a copy of the GNU Lesser General Public License |
611 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
612 | + */ |
613 | + |
614 | +import QtQuick 2.0 |
615 | +import Ubuntu.Components 1.3 |
616 | + |
617 | +Grid { |
618 | + width: 800 |
619 | + height: 600 |
620 | + rows: 16 |
621 | + columns: 16 |
622 | + Repeater { |
623 | + model: 16*16 |
624 | + AbstractButton { |
625 | + } |
626 | + } |
627 | +} |
628 | |
629 | === added file 'tests/unit/tst_performance/AbstractButtonGrid.qml' |
630 | --- tests/unit/tst_performance/AbstractButtonGrid.qml 1970-01-01 00:00:00 +0000 |
631 | +++ tests/unit/tst_performance/AbstractButtonGrid.qml 2015-08-25 13:10:33 +0000 |
632 | @@ -0,0 +1,30 @@ |
633 | +/* |
634 | + * Copyright 2015 Canonical Ltd. |
635 | + * |
636 | + * This program is free software; you can redistribute it and/or modify |
637 | + * it under the terms of the GNU Lesser General Public License as published by |
638 | + * the Free Software Foundation; version 3. |
639 | + * |
640 | + * This program is distributed in the hope that it will be useful, |
641 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
642 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
643 | + * GNU Lesser General Public License for more details. |
644 | + * |
645 | + * You should have received a copy of the GNU Lesser General Public License |
646 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
647 | + */ |
648 | + |
649 | +import QtQuick 2.0 |
650 | +import Ubuntu.Components 1.1 |
651 | + |
652 | +Grid { |
653 | + width: 800 |
654 | + height: 600 |
655 | + rows: 16 |
656 | + columns: 16 |
657 | + Repeater { |
658 | + model: 16*16 |
659 | + AbstractButton { |
660 | + } |
661 | + } |
662 | +} |
663 | |
664 | === modified file 'tests/unit/tst_performance/tst_performance.cpp' |
665 | --- tests/unit/tst_performance/tst_performance.cpp 2015-04-14 07:41:52 +0000 |
666 | +++ tests/unit/tst_performance/tst_performance.cpp 2015-08-25 13:10:33 +0000 |
667 | @@ -102,6 +102,8 @@ |
668 | QTest::addColumn<QString>("document"); |
669 | QTest::addColumn<QUrl>("theme"); |
670 | |
671 | + QTest::newRow("AbstractButton 1.2") << "AbstractButtonGrid.qml" << QUrl(); |
672 | + QTest::newRow("AbstractButton 1.3") << "AbstractButton13Grid.qml" << QUrl(); |
673 | QTest::newRow("grid with Rectangle") << "RectangleGrid.qml" << QUrl(); |
674 | QTest::newRow("grid with Text") << "TextGrid.qml" << QUrl(); |
675 | QTest::newRow("grid with Label") << "LabelGrid.qml" << QUrl(); |
676 | |
677 | === modified file 'tests/unit/tst_performance/tst_performance.pro' |
678 | --- tests/unit/tst_performance/tst_performance.pro 2015-04-01 08:33:53 +0000 |
679 | +++ tests/unit/tst_performance/tst_performance.pro 2015-08-25 13:10:33 +0000 |
680 | @@ -30,4 +30,6 @@ |
681 | Styling.qml \ |
682 | PaletteConfigurationOneColor.qml \ |
683 | PaletteConfigurationAllColors.qml \ |
684 | - StyledItemNewTheming.qml |
685 | + StyledItemNewTheming.qml \ |
686 | + AbstractButtonGrid.qml \ |
687 | + AbstractButton13Grid.qml |
688 | |
689 | === added file 'tests/unit_x11/tst_components/tst_abstractbutton13.qml' |
690 | --- tests/unit_x11/tst_components/tst_abstractbutton13.qml 1970-01-01 00:00:00 +0000 |
691 | +++ tests/unit_x11/tst_components/tst_abstractbutton13.qml 2015-08-25 13:10:33 +0000 |
692 | @@ -0,0 +1,115 @@ |
693 | +/* |
694 | + * Copyright 2012 Canonical Ltd. |
695 | + * |
696 | + * This program is free software; you can redistribute it and/or modify |
697 | + * it under the terms of the GNU Lesser General Public License as published by |
698 | + * the Free Software Foundation; version 3. |
699 | + * |
700 | + * This program is distributed in the hope that it will be useful, |
701 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
702 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
703 | + * GNU Lesser General Public License for more details. |
704 | + * |
705 | + * You should have received a copy of the GNU Lesser General Public License |
706 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
707 | + */ |
708 | + |
709 | +import QtQuick 2.0 |
710 | +import QtTest 1.0 |
711 | +import Ubuntu.Test 1.0 |
712 | +import Ubuntu.Components 1.3 |
713 | + |
714 | +Item { |
715 | + width: units.gu(40) |
716 | + height: units.gu(71) |
717 | + |
718 | + Column { |
719 | + AbstractButton { |
720 | + id: absButton |
721 | + width: units.gu(10) |
722 | + height: units.gu(10) |
723 | + } |
724 | + AbstractButton { |
725 | + id: absLongTap |
726 | + width: units.gu(10) |
727 | + height: width |
728 | + onPressAndHold: {} |
729 | + } |
730 | + AbstractButton { |
731 | + id: suppressTrigger |
732 | + width: units.gu(10) |
733 | + height: width |
734 | + function trigger() {} |
735 | + } |
736 | + } |
737 | + |
738 | + Action { |
739 | + id: action1 |
740 | + property int triggerCount: 0 |
741 | + onTriggered: triggerCount++ |
742 | + } |
743 | + |
744 | + SignalSpy { |
745 | + id: signalSpy |
746 | + target: absButton |
747 | + signalName: "clicked" |
748 | + } |
749 | + |
750 | + SignalSpy { |
751 | + id: pressAndHoldSpy |
752 | + target: absLongTap |
753 | + signalName: "pressAndHold" |
754 | + } |
755 | + |
756 | + SignalSpy { |
757 | + id: triggeredSpy |
758 | + signalName: "triggered" |
759 | + } |
760 | + |
761 | + UbuntuTestCase { |
762 | + name: "AbstractButtonAPI" |
763 | + when: windowShown |
764 | + |
765 | + function cleanup() { |
766 | + signalSpy.clear(); |
767 | + triggeredSpy.clear(); |
768 | + } |
769 | + |
770 | + function test_action() { |
771 | + compare(absButton.action, null,"Action is null by default") |
772 | + absButton.action = action1 |
773 | + compare(absButton.action, action1, "Action can be set") |
774 | + var numTriggers = action1.triggerCount |
775 | + absButton.clicked() |
776 | + compare(action1.triggerCount, numTriggers+1, "Button clicked triggers action") |
777 | + absButton.action = null |
778 | + } |
779 | + |
780 | + function test_custom_trigger_function() { |
781 | + suppressTrigger.action = action1; |
782 | + triggeredSpy.target = action1; |
783 | + mouseClick(suppressTrigger, centerOf(suppressTrigger).x, centerOf(suppressTrigger).y); |
784 | + compare(triggeredSpy.count, 0, "Trigger should be overridden"); |
785 | + } |
786 | + |
787 | + // fixing bugs 1365471 and 1458028 |
788 | + function test_no_pressAndHold_connected_clicks_bug1365471_bug1458028() { |
789 | + signalSpy.target = absButton; |
790 | + mouseLongPress(absButton, centerOf(absButton).x, centerOf(absButton).y); |
791 | + mouseRelease(absButton, centerOf(absButton).x, centerOf(absButton).y); |
792 | + signalSpy.wait(); |
793 | + } |
794 | + |
795 | + // fixing bugs 1365471 and 1458028 |
796 | + function test_pressAndHold_connected_suppresses_clicks_bug1365471_bug1458028() { |
797 | + function testFunc() {} |
798 | + signalSpy.target = absButton; |
799 | + absLongTap.pressAndHold.connect(testFunc); |
800 | + mouseLongPress(absLongTap, centerOf(absLongTap).x, centerOf(absLongTap).y); |
801 | + absLongTap.pressAndHold.disconnect(testFunc); |
802 | + pressAndHoldSpy.wait(); |
803 | + mouseRelease(absLongTap, centerOf(absLongTap).x, centerOf(absLongTap).y); |
804 | + compare(signalSpy.count, 0, "click() must be suppressed when pressAndHold handler is implemented"); |
805 | + } |
806 | + } |
807 | +} |
FAILED: Continuous integration, rev:1622 jenkins. qa.ubuntu. com/job/ ubuntu- sdk-team- ubuntu- ui-toolkit- staging- ci/2146/ jenkins. qa.ubuntu. com/job/ ubuntu- sdk-team- ubuntu- ui-toolkit- staging- vivid-amd64- ci/874 jenkins. qa.ubuntu. com/job/ ubuntu- sdk-team- ubuntu- ui-toolkit- staging- vivid-armhf- ci/876 jenkins. qa.ubuntu. com/job/ ubuntu- sdk-team- ubuntu- ui-toolkit- staging- vivid-armhf- ci/876/ artifact/ work/output/ *zip*/output. zip jenkins. qa.ubuntu. com/job/ ubuntu- sdk-team- ubuntu- ui-toolkit- staging- vivid-i386- ci/873
http://
Executed test runs:
UNSTABLE: http://
UNSTABLE: http://
deb: http://
UNSTABLE: http://
Click here to trigger a rebuild: s-jenkins. ubuntu- ci:8080/ job/ubuntu- sdk-team- ubuntu- ui-toolkit- staging- ci/2146/ rebuild
http://