Merge lp:~zsombi/ubuntu-ui-toolkit/combobutton into lp:ubuntu-ui-toolkit

Proposed by Zsombor Egri
Status: Superseded
Proposed branch: lp:~zsombi/ubuntu-ui-toolkit/combobutton
Merge into: lp:ubuntu-ui-toolkit
Diff against target: 1652 lines (+1381/-24)
19 files modified
components.api (+12/-0)
examples/ubuntu-ui-toolkit-gallery/Buttons.qml (+64/-0)
modules/Ubuntu/Components/Button.qml (+5/-0)
modules/Ubuntu/Components/ComboButton.qml (+383/-0)
modules/Ubuntu/Components/Themes/Ambiance/ButtonForeground.qml (+1/-0)
modules/Ubuntu/Components/Themes/Ambiance/ButtonStyle.qml (+14/-5)
modules/Ubuntu/Components/Themes/Ambiance/ComboButtonStyle.qml (+251/-0)
modules/Ubuntu/Components/Themes/Ambiance/qmldir (+1/-0)
modules/Ubuntu/Components/qmldir (+1/-0)
modules/Ubuntu/Test/UbuntuTestCase.qml (+69/-1)
modules/Ubuntu/Test/deployment.pri (+6/-1)
tests/autopilot/ubuntuuitoolkit/emulators.py (+26/-0)
tests/autopilot/ubuntuuitoolkit/tests/test_emulators.py (+45/-0)
tests/resources/buttons/ComboTest.qml (+147/-0)
tests/unit/runtest.sh (+1/-1)
tests/unit/tst_components/tst_button.qml (+4/-0)
tests/unit_x11/tst_components/tst_combobutton.qml (+246/-0)
tests/unit_x11/tst_components/tst_components.pro (+2/-1)
tests/unit_x11/tst_test/tst_ubuntutestcase.qml (+103/-15)
To merge this branch: bzr merge lp:~zsombi/ubuntu-ui-toolkit/combobutton
Reviewer Review Type Date Requested Status
PS Jenkins bot continuous-integration Approve
Tim Peeters Needs Fixing
Nekhelesh Ramananthan (community) Needs Information
Review via email: mp+207598@code.launchpad.net

This proposal has been superseded by a proposal from 2014-04-10.

Commit message

ComboButton component

To post a comment you must log in.
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
956. By Zsombor Egri

license added to test app

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
Nekhelesh Ramananthan (nik90) wrote :

Is there a design document describing the combo button behaviour and appearance?

review: Needs Information
Revision history for this message
Zsombor Egri (zsombi) wrote :

> Is there a design document describing the combo button behaviour and
> appearance?

The design is here http://design.ubuntu.com/apps/building-blocks/buttons, but the combo button design had been updated, and the site does not have the updated layouts yet.

957. By Zsombor Egri

trunk merge

958. By Zsombor Egri

use artworks instead of system icons

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
959. By Zsombor Egri

trunk merge

Revision history for this message
Tim Peeters (tpeeters) wrote :

I think the blue contents for the combobutton in the gallery is quite ugly:
http://ubuntuone.com/4jy8WPRYPLbLTez89wzqRh
also it does not really show how it should be used, with listitems that have alternative options to click on. Please change the example in the gallery.

I also don't really like the colors used in the button itself, but I guess we need design input for that.

Finally, the ^/V just "flips" when you click it, a rotation animation such as the ValueSelector has looks more sleek.

Revision history for this message
Tim Peeters (tpeeters) wrote :

I added an icon to the combobutton example:

            ComboButton {
                text: "Press me"
                objectName: "combobutton_collapsed"
                comboList: Rectangle {
                    height: units.gu(20)
                    width: parent.width
                    color: "blue"
                }
                iconSource: "call.png"

the icon gets aligned wrong, see http://ubuntuone.com/3LHlrfUwFssHkbx00v33Br

review: Needs Fixing
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
Zsombor Egri (zsombi) wrote :

> I think the blue contents for the combobutton in the gallery is quite ugly:
> http://ubuntuone.com/4jy8WPRYPLbLTez89wzqRh
> also it does not really show how it should be used, with listitems that have
> alternative options to click on. Please change the example in the gallery.

Agreed. I'll add a Column with items into it.
>
>
> I also don't really like the colors used in the button itself, but I guess we
> need design input for that.

The colors I got from design. We were supposed to get UI facelift again for all the components. If they don't like the design, they can change it. Actually I was thinking to expose these colors/font properties so user can customize them freely.

>
> Finally, the ^/V just "flips" when you click it, a rotation animation such as
> the ValueSelector has looks more sleek.

That's the point. The chevron should not be animated while the dropdown toggles. The maximum we could do is to fade the image transition, however atm we don't have separate up/down chevrons. But we can make one, so I'll update the UI.

Revision history for this message
Zsombor Egri (zsombi) wrote :

> I added an icon to the combobutton example:
>
> ComboButton {
> text: "Press me"
> objectName: "combobutton_collapsed"
> comboList: Rectangle {
> height: units.gu(20)
> width: parent.width
> color: "blue"
> }
> iconSource: "call.png"
>
> the icon gets aligned wrong, see http://ubuntuone.com/3LHlrfUwFssHkbx00v33Br

Fixed in revno 960

960. By Zsombor Egri

button face alignment when icon + text is present fixed; dropdown colors and button font properties exposed

961. By Zsombor Egri

fixing emulator errors

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
962. By Zsombor Egri

api file updated

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
963. By Zsombor Egri

staging merge

964. By Zsombor Egri

remove accidentally added tst_combobutton.qml from pro file

965. By Zsombor Egri

staging merge

966. By Zsombor Egri

autopilot fixes

967. By Zsombor Egri

color fix

968. By Zsombor Egri

review comments applied

969. By Zsombor Egri

stage merge

970. By Zsombor Egri

prereq merge

971. By Zsombor Egri

moving component to version 1.1

972. By Zsombor Egri

style documentation linked

973. By Zsombor Egri

Style API headline

974. By Zsombor Egri

prereq merge

975. By Zsombor Egri

Ubuntu.Components evolved to version 1.1, the rest are kept on 1.0 till we introduce new features there

976. By Zsombor Egri

prereq merge

977. By Zsombor Egri

prereq merge

978. By Zsombor Egri

staging merge

979. By Zsombor Egri

fixing test case

980. By Zsombor Egri

staging merge

981. By Zsombor Egri

typo fixed

982. By Zsombor Egri

staging merge

983. By Zsombor Egri

rogue file removed

Unmerged revisions

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'components.api'
--- components.api 2014-04-01 12:57:27 +0000
+++ components.api 2014-04-10 09:56:33 +0000
@@ -45,6 +45,16 @@
45 readonly property color coolGrey45 readonly property color coolGrey
46 property Gradient orangeGradient46 property Gradient orangeGradient
47 property Gradient greyGradient47 property Gradient greyGradient
48modules/Ubuntu/Components/ComboButton.qml
49Button
50 property bool expanded
51 property bool autoCollapse
52 property real collapsedHeight
53 property real expandedHeight
54 readonly property real comboListHeight
55 default property list<Item> comboList
56 property color dropdownColorPressed
57 property color dropdownColorReleased
48modules/Ubuntu/Components/CrossFadeImage.qml58modules/Ubuntu/Components/CrossFadeImage.qml
49Item59Item
50 property url source60 property url source
@@ -593,6 +603,8 @@
593 function findChild(obj,objectName)603 function findChild(obj,objectName)
594 function findInvisibleChild(obj,objectName)604 function findInvisibleChild(obj,objectName)
595 function mouseMoveSlowly(item,x,y,dx,dy,steps,stepdelay)605 function mouseMoveSlowly(item,x,y,dx,dy,steps,stepdelay)
606 function flick(item, x, y, dx, dy, pressTimeout, steps, button, modifiers, delay)
607 function mouseLongPress(item, x, y, button, modifiers, delay)
596 function tryCompareFunction(func, expectedResult, timeout)608 function tryCompareFunction(func, expectedResult, timeout)
597plugins.qmltypes609plugins.qmltypes
598 name: "InverseMouseAreaType"610 name: "InverseMouseAreaType"
599611
=== modified file 'examples/ubuntu-ui-toolkit-gallery/Buttons.qml'
--- examples/ubuntu-ui-toolkit-gallery/Buttons.qml 2014-03-04 12:16:38 +0000
+++ examples/ubuntu-ui-toolkit-gallery/Buttons.qml 2014-04-10 09:56:33 +0000
@@ -16,6 +16,7 @@
1616
17import QtQuick 2.017import QtQuick 2.0
18import Ubuntu.Components 0.118import Ubuntu.Components 0.1
19import Ubuntu.Components.ListItems 0.1
1920
20Template {21Template {
21 objectName: "buttonsTemplate"22 objectName: "buttonsTemplate"
@@ -80,4 +81,67 @@
80 }81 }
81 }82 }
82 }83 }
84
85 TemplateSection {
86 className: "ComboButton"
87
88 TemplateRow {
89 title: i18n.tr("Collapsed")
90
91 ComboButton {
92 text: "Press me"
93 objectName: "combobutton_collapsed"
94 comboList: UbuntuListView {
95 model: 10
96 delegate: Standard {
97 text: "item #" + modelData
98 }
99 }
100 }
101 }
102
103 TemplateRow {
104 title: i18n.tr("Icon")
105
106 ComboButton {
107 iconSource: "call.png"
108 comboList: UbuntuListView {
109 model: 10
110 delegate: Standard {
111 text: "item #" + modelData
112 }
113 }
114 }
115 }
116
117 TemplateRow {
118 title: i18n.tr("Icon+Text")
119
120 ComboButton {
121 text: "Answer"
122 iconSource: "call.png"
123 comboList: UbuntuListView {
124 model: 10
125 delegate: Standard {
126 text: "item #" + modelData
127 }
128 }
129 }
130 }
131 TemplateRow {
132 title: i18n.tr("Expanded")
133
134 ComboButton {
135 text: "Press me"
136 objectName: "combobutton_expanded"
137 expanded: true
138 comboList: UbuntuListView {
139 model: 10
140 delegate: Standard {
141 text: "item #" + modelData
142 }
143 }
144 }
145 }
146 }
83}147}
84148
=== modified file 'modules/Ubuntu/Components/Button.qml'
--- modules/Ubuntu/Components/Button.qml 2013-11-06 22:52:15 +0000
+++ modules/Ubuntu/Components/Button.qml 2014-04-10 09:56:33 +0000
@@ -83,6 +83,11 @@
83 property Gradient gradient: __styleInstance.defaultGradient83 property Gradient gradient: __styleInstance.defaultGradient
8484
85 /*!85 /*!
86 The font used for the button's text.
87 */
88 property font font: __styleInstance ? __styleInstance.defaultFont : Qt.font({family: "Ubuntu", pixelSize: FontUtils.sizeToPixels("medium")})
89
90 /*!
86 The source URL of the icon to display inside the button.91 The source URL of the icon to display inside the button.
87 Leave this value blank for a text-only button.92 Leave this value blank for a text-only button.
88 If \l action is set, the default iconSource is that of the action.93 If \l action is set, the default iconSource is that of the action.
8994
=== added file 'modules/Ubuntu/Components/ComboButton.qml'
--- modules/Ubuntu/Components/ComboButton.qml 1970-01-01 00:00:00 +0000
+++ modules/Ubuntu/Components/ComboButton.qml 2014-04-10 09:56:33 +0000
@@ -0,0 +1,383 @@
1/*
2 * Copyright 2014 Canonical Ltd.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU Lesser General Public License as published by
6 * the Free Software Foundation; version 3.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU Lesser General Public License for more details.
12 *
13 * You should have received a copy of the GNU Lesser General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
16
17import QtQuick 2.0
18import Ubuntu.Components.Popups 0.1
19import "mathUtils.js" as MathUtils
20
21/*!
22 \qmltype ComboButton
23 \inqmlmodule Ubuntu.Components 0.1
24 \ingroup ubuntu
25 \brief Ubuntu button providing a drop-down panel visualizing custom options.
26
27 The component is composed of three main blocks: \b {main button}, \b {dropdown}
28 and \b {combo list}.
29
30 The \a {main button} holds the main functionailty of the component, and it is
31 located at the left-top side of the expanded button. The \a clicked() signal
32 is triggered only when this button is pressed.
33
34 The \a {dropdown} is a button located on the top-right side of the expanded
35 component. Its functionality is to drive the component's expanded state.
36
37 The \a {combo list} is a panel showing the content specified in \l comboList
38 property when expanded. The content is stretched horizontally to the component's
39 width, and its height is controlled by the \l expandedHeight property as follows:
40 \list
41 \li If the content height is smaller than the value of \l expandedHeight, the combo
42 list will be expanded only to the height of the content.
43 \qml
44 import QtQuick 2.0
45 import Ubuntu.Components 0.1
46 ComboButton {
47 text: "smaller content"
48 Rectangle {
49 height: units.gu(5) // smaller than the default expandedHeight
50 color: "blue"
51 }
52 }
53 \endqml
54 \li If the content height is greater than \l expandedHeight, the combo list will
55 expand till the height specified by the property and the content will be
56 scrolled; in case the combo list content is one single Flickable, ListView,
57 GridView or PathView, the content scrolling will be provided by the content
58 itself.
59 \qml
60 import QtQuick 2.0
61 import Ubuntu.Components 0.1
62 ComboButton {
63 text: "long scrolled content"
64 Column {
65 Repeater {
66 model: 5
67 spacing: units.gu(1)
68 Rectangle {
69 height: units.gu(5)
70 color: "blue"
71 }
72 }
73 }
74 }
75 \endqml
76 \li In case the content is a single Flickable, ListView, GridView or PathView,
77 the content will be filling the entire combo list area defined.
78 \qml
79 import QtQuick 2.0
80 import Ubuntu.Components 0.1
81 import Ubuntu.Components.ListItems 0.1
82 ComboButton {
83 text: "listview"
84 ListView {
85 model: 10
86 delegate: Standard {
87 text: "Item #" + modelData
88 }
89 }
90 }
91 \endqml
92 \li Vertical anchoring of combo list content to its parent is not possible
93 as the expansion calculation is done based on the combo list content height.
94 If the content wants to take the size of the entire combo list, it should
95 bind its height to the \l comboListHeight property.
96 \qml
97 import QtQuick 2.0
98 import Ubuntu.Components 0.1
99 ComboButton {
100 id: combo
101 text: "smaller content"
102 Rectangle {
103 height: combo.comboListHeight
104 color: "blue"
105 }
106 }
107 \endqml
108 \li In case the expansion needs to be the size of the combo list content, the \l
109 expandedHeight should be set to -1.
110 \qml
111 import QtQuick 2.0
112 import Ubuntu.Components 0.1
113 ComboButton {
114 text: "auto-sized content"
115 expandedHeight: -1
116 Column {
117 Repeater {
118 model: 5
119 spacing: units.gu(1)
120 Rectangle {
121 height: units.gu(5)
122 color: "blue"
123 }
124 }
125 }
126 }
127 \endqml
128 \endlist
129
130 As combo list content is unknown for the component, eventual collapsing when
131 an action selected from the combo list holder must be driven manually. Also,
132 the default action of the main button can be changed in this way.
133
134 \qml
135 import QtQuick 2.0
136 import Ubuntu.Components 0.1
137
138 ComboButton {
139 id: combo
140 text: "Auto closing"
141 expanded: true
142 expandedHeight: units.gu(30)
143 UbuntuListView {
144 width: parent.width
145 height: combo.comboListHeight
146 model: 20
147 delegate: Standard {
148 text: "Action #" + modelData
149 onClicked: {
150 combo.text = text;
151 combo.expanded = false;
152 }
153 }
154 }
155 }
156 \endqml
157
158 The style of the component is defined in \l ComboButtonStyle.
159 */
160Button {
161 id: combo
162
163 /*!
164 Specifies whether the combo list is expanded or not. The default falue is
165 false.
166 */
167 property bool expanded: false
168
169 /*!
170 The property specifies whether to collapse the expanded combo list when
171 the main button is clicked. The default value is true.
172 */
173 property bool autoCollapse: true
174
175 /*!
176 The property holds the height of the component when collapsed. By default
177 the value is the implicit height of the component.
178 */
179 property real collapsedHeight: implicitHeight
180
181 /*!
182 The property holds the maximum height value the component should expand.
183 When setting the property, remember to take into account the \l collapsedHeight
184 value. The best practice is to use bind it with collapsedHeight.
185 \qml
186 ComboButton {
187 text: "altered expandedHeight"
188 expandedHeight: collapsedHeight + units.gu(25)
189 }
190 \endqml
191
192 A value of -1 will instruct the component to expand the combo list as
193 much as its content height is.
194
195 The default value is \l collapsedHeight + 19.5 GU.
196 \sa collapsedHeight
197 */
198 property real expandedHeight: collapsedHeight + units.gu(19.5)
199
200 /*!
201 The property holds the maximum combo list height allowed based on the
202 \l expandedHeight and \l collapsedHeight values. It is a convenience property
203 that can be used to size the combo list content.
204 \qml
205 import QtQuick 2.0
206 import Ubuntu.Components 0.1
207 import Ubuntu.Components.ListItems 0.1
208 ComboButton {
209 id: combo
210 text: "Full comboList size"
211 ListView {
212 anchors {
213 left: parent.left
214 right: parent.right
215 }
216 height: combo.comboListHeight
217 model: 20
218 delegate: Standard {
219 text: "Action #" + modelData
220 }
221 }
222 }
223 \endqml
224
225 \sa collapsedHeight, expandedHeight
226 */
227 readonly property real comboListHeight: (expandedHeight < 0) ?
228 comboListHolder.height :
229 (expandedHeight - collapsedHeight -
230 (combo.__styleInstance ? combo.__styleInstance.comboListMargin : 0))
231
232 /*!
233 \qmlproperty list<Item> comboList
234 \default
235 Property holding the list of items to be shown in the combo list. Being
236 a default property children items declared will land in the combo list.
237 \note The component is not responsible for layouting the content. It only
238 provides scrolling abilities for the case the content exceeds the defined
239 expanded height.
240 */
241 default property alias comboList: comboListHolder.data
242
243 /* ----------------- Color and font configurations ----------------- */
244 /*!
245 The property specifies the color of the dropdown button when expanded.
246 */
247 property color dropdownColorPressed: __styleInstance ? __styleInstance.defaultDropdownColorPressed : color
248
249 /*!
250 The property specifies the color of the dropdown button when collapsed.
251 */
252 property color dropdownColorReleased: __styleInstance ? __styleInstance.defaultDropdownColorReleased : color
253
254 style: Theme.createStyleComponent("ComboButtonStyle.qml", combo)
255
256 // auto-collapse
257 /*! \internal */
258 onClicked: {
259 if (autoCollapse) {
260 expanded = false;
261 }
262 }
263
264 Component.onCompleted: {
265 // update mouse area to report clicks only on the main button area
266 // area excluding dropDown button and combo list
267 // we must do separate bindings as __mouseArea is a read-only property
268 __mouseArea.anchors.fill = undefined;
269 __mouseArea.anchors.left = Qt.binding(function() {return combo.left;});
270 __mouseArea.anchors.top = Qt.binding(function() {return combo.top;});
271 __mouseArea.anchors.right = Qt.binding(function() {return combo.right;});
272 __mouseArea.anchors.rightMargin = Qt.binding(function() {return combo.__styleInstance.dropDownWidth + combo.__styleInstance.dropDownSeparatorWidth;});
273 __mouseArea.height = Qt.binding(function() {return collapsedHeight;});
274 // for autopilot, set the main button name
275 __mouseArea.objectName = "combobutton_mainbutton";
276
277 // bind a height calculation to avoid unwanted change
278 combo.height = Qt.binding(function() {return collapsedHeight + __styleInstance.comboListPanel.height});
279 }
280
281 // dropdown button
282 MouseArea {
283 id: dropDown
284 objectName: "combobutton_dropdown"
285 anchors {
286 right: parent.right
287 top: parent.top
288 }
289 width: combo.__styleInstance ? combo.__styleInstance.dropDownWidth : 0
290 height: combo.collapsedHeight
291 // open dropdown when pressed, not when clicked
292 onPressed: {
293 // toggle expanded
294 combo.expanded = !combo.expanded;
295 }
296 }
297
298 // expansion list
299 Flickable {
300 id: comboHolder
301 parent: combo.__styleInstance ? combo.__styleInstance.comboList : combo
302 anchors.fill: parent
303 interactive: combo.expanded && !contentIsFlickable() && (combo.expandedHeight > 0)
304 flickableDirection: Flickable.VerticalFlick
305 contentHeight: comboListHolder.height
306
307 // consider PathView as Flickable in this case as well!
308 function contentIsFlickable() {
309 return (comboListHolder.children.length === 1) &&
310 comboListHolder.children[0].hasOwnProperty("flicking");
311 }
312
313 Item {
314 id: comboListHolder
315 objectName: "combobutton_combolist"
316 anchors {
317 left: parent.left
318 right: parent.right
319 }
320
321 // stretch children width to holder's width
322 // must do binding to height manually to avoid binding loops caused
323 // by the vertical stretching when the component is a single flickable
324 property bool anchorFill: (combo.expandedHeight > 0 && comboHolder.contentIsFlickable())
325 onAnchorFillChanged: stretchChildren()
326 onChildrenChanged: stretchChildren()
327 function stretchChildren() {
328 for (var i in comboListHolder.children) {
329 var child = comboListHolder.children[i];
330 if (comboListHolder.anchorFill) {
331 child.anchors.left = undefined;
332 child.anchors.right = undefined;
333 child.anchors.fill = comboListHolder;
334 comboListHolder.height = Qt.binding(function() {
335 return combo.comboListHeight;
336 });
337 } else {
338 child.anchors.left = comboListHolder.left;
339 child.anchors.right = comboListHolder.right;
340 comboListHolder.height = Qt.binding(function() {
341 return comboListHolder.childrenRect.height;
342 });
343 }
344 }
345 }
346 }
347 }
348 Scrollbar {
349 flickableItem: comboHolder
350 }
351
352 // drive the expansion height of the combo list holder
353 Binding {
354 target: combo.__styleInstance.comboListPanel
355 property: "height"
356 value: {
357 if (!expanded) {
358 return 0;
359 }
360 if (comboListHolder.anchorFill) {
361 return combo.comboListHeight + combo.__styleInstance.comboListMargin;
362 }
363
364 var h = comboListHolder.height;
365 var max = combo.comboListHeight + combo.__styleInstance.comboListMargin;
366 if (combo.expandedHeight < 0) {
367 return max;
368 }
369
370 return MathUtils.clamp(h, 0, max);
371 }
372 }
373 // for testing purposes only
374 Binding {
375 target: combo.__styleInstance.comboListPanel
376 property: "objectName"
377 value: "combobutton_combopanel"
378 }
379
380 /*! \internal */
381 // on style change, update the visual's names so we can access it when testing
382 onStyleChanged: if (__styleInstance) __styleInstance.dropdownButtonVisuals.objectName = "combobutton_dropdow_visuals"
383}
0384
=== modified file 'modules/Ubuntu/Components/Themes/Ambiance/ButtonForeground.qml'
--- modules/Ubuntu/Components/Themes/Ambiance/ButtonForeground.qml 2013-07-01 22:26:49 +0000
+++ modules/Ubuntu/Components/Themes/Ambiance/ButtonForeground.qml 2014-04-10 09:56:33 +0000
@@ -30,6 +30,7 @@
30 property real spacing30 property real spacing
31 property bool hasIcon: iconSource != ""31 property bool hasIcon: iconSource != ""
32 property bool hasText: text != ""32 property bool hasText: text != ""
33 property alias font: label.font
3334
34 opacity: enabled ? 1.0 : 0.535 opacity: enabled ? 1.0 : 0.5
35 implicitHeight: Math.max(icon.height, label.height)36 implicitHeight: Math.max(icon.height, label.height)
3637
=== modified file 'modules/Ubuntu/Components/Themes/Ambiance/ButtonStyle.qml'
--- modules/Ubuntu/Components/Themes/Ambiance/ButtonStyle.qml 2014-02-04 22:07:10 +0000
+++ modules/Ubuntu/Components/Themes/Ambiance/ButtonStyle.qml 2014-04-10 09:56:33 +0000
@@ -26,7 +26,10 @@
26 property real minimumWidth: units.gu(10)26 property real minimumWidth: units.gu(10)
27 property real horizontalPadding: units.gu(1)27 property real horizontalPadding: units.gu(1)
28 property color defaultColor: UbuntuColors.orange28 property color defaultColor: UbuntuColors.orange
29 property font defaultFont: Qt.font({family: "Ubuntu", pixelSize: FontUtils.sizeToPixels("medium")})
29 property Gradient defaultGradient30 property Gradient defaultGradient
31 property real buttonFaceOffset: 0
32 property Item backgroundSource: null
3033
31 width: button.width34 width: button.width
32 height: button.height35 height: button.height
@@ -40,8 +43,9 @@
40 non-NOTIFYable properties. They cannot be written to so it is fine but43 non-NOTIFYable properties. They cannot be written to so it is fine but
41 the proxy avoids the warnings.44 the proxy avoids the warnings.
42 */45 */
46 property QtObject gradientProxy: gradientProxyObject
43 QtObject {47 QtObject {
44 id: gradientProxy48 id: gradientProxyObject
45 property color topColor49 property color topColor
46 property color bottomColor50 property color bottomColor
4751
@@ -67,7 +71,8 @@
67 id: background71 id: background
68 anchors.fill: parent72 anchors.fill: parent
69 borderSource: "radius_idle.sci"73 borderSource: "radius_idle.sci"
70 visible: color.a != 0.074 visible: (color.a != 0.0) || backgroundSource
75 image: backgroundSource
7176
72 // Color properties in a JS ternary operator don't work as expected in77 // Color properties in a JS ternary operator don't work as expected in
73 // QML because it overwrites alpha values with 1. A workaround is to use78 // QML because it overwrites alpha values with 1. A workaround is to use
@@ -75,8 +80,8 @@
75 // https://bugs.launchpad.net/ubuntu-ui-toolkit/+bug/1197802 and80 // https://bugs.launchpad.net/ubuntu-ui-toolkit/+bug/1197802 and
76 // https://bugreports.qt-project.org/browse/QTBUG-32238.81 // https://bugreports.qt-project.org/browse/QTBUG-32238.
77 function colorHack(color) { return Qt.rgba(color.r, color.g, color.b, color.a); }82 function colorHack(color) { return Qt.rgba(color.r, color.g, color.b, color.a); }
78 color: isGradient ? colorHack(gradientProxy.topColor) : colorHack(button.color)83 color: backgroundSource ? "#00000000" : (isGradient ? colorHack(gradientProxy.topColor) : colorHack(button.color))
79 gradientColor: isGradient ? colorHack(gradientProxy.bottomColor) : colorHack(button.color)84 gradientColor: backgroundSource ? "#00000000" : (isGradient ? colorHack(gradientProxy.bottomColor) : colorHack(button.color))
80 }85 }
8186
82 UbuntuShape {87 UbuntuShape {
@@ -98,7 +103,10 @@
98 ButtonForeground {103 ButtonForeground {
99 id: foreground104 id: foreground
100 width: parent.width - 2*horizontalPadding105 width: parent.width - 2*horizontalPadding
101 anchors.centerIn: parent106 anchors {
107 centerIn: parent
108 horizontalCenterOffset: buttonFaceOffset
109 }
102 text: button.text110 text: button.text
103 /* Pick either a clear or dark text color depending on the luminance of the111 /* Pick either a clear or dark text color depending on the luminance of the
104 background color to maintain good contrast (works in most cases)112 background color to maintain good contrast (works in most cases)
@@ -107,6 +115,7 @@
107 iconSource: button.iconSource115 iconSource: button.iconSource
108 iconPosition: button.iconPosition116 iconPosition: button.iconPosition
109 iconSize: units.gu(3)117 iconSize: units.gu(3)
118 font: button.font
110 spacing: horizontalPadding119 spacing: horizontalPadding
111 transformOrigin: Item.Top120 transformOrigin: Item.Top
112 scale: button.pressed ? 0.98 : 1.0121 scale: button.pressed ? 0.98 : 1.0
113122
=== added file 'modules/Ubuntu/Components/Themes/Ambiance/ComboButtonStyle.qml'
--- modules/Ubuntu/Components/Themes/Ambiance/ComboButtonStyle.qml 1970-01-01 00:00:00 +0000
+++ modules/Ubuntu/Components/Themes/Ambiance/ComboButtonStyle.qml 2014-04-10 09:56:33 +0000
@@ -0,0 +1,251 @@
1/*
2 * Copyright 2014 Canonical Ltd.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU Lesser General Public License as published by
6 * the Free Software Foundation; version 3.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU Lesser General Public License for more details.
12 *
13 * You should have received a copy of the GNU Lesser General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
16
17import QtQuick 2.0
18import Ubuntu.Components 0.1
19
20/*!
21 The component defines the style of the ComboButton component.
22 */
23Item {
24 id: comboStyle
25
26 /*!
27 Width of the drop down button.
28 */
29 property real dropDownWidth: units.gu(5)
30
31 /*!
32 Width of the dropdown button separator.
33 */
34 property real dropDownSeparatorWidth: units.dp(2)
35
36 /*!
37 Distance between the combo list and the main button.
38 */
39 property real comboListMargin: units.gu(0.8)
40
41 /*!
42 The item which will hold the combo list data.
43 */
44 property Item comboList: comboListContent
45
46 /*!
47 The item pointing to the panel holding the combo list and additional design
48 artifacts. It is used by the component to drive the expansion size.
49 */
50 property Item comboListPanel: panelItem
51
52 /*!
53 \qmlproperty color defaultColor
54 Default color for the main button.
55 */
56 property alias defaultColor: mainButton.defaultColor
57
58 /*!
59 \qmlproperty Gradient defaultGradient
60 Default gradient for the main button.
61 */
62 property alias defaultGradient: mainButton.defaultGradient
63
64 /*!
65 Default color for the dropdown button when released.
66 */
67 property color defaultDropdownColorReleased: defaultColor
68 /*!
69 Default color for dropdown button when pressed.
70 */
71 property color defaultDropdownColorPressed: Qt.rgba(0, 0, 0, 0.05)
72 /*!
73 Default button face font.
74 */
75 property alias defaultFont: mainButton.defaultFont
76
77 /*!
78 The property holds the Item implementing the visuals of the dropdown button.
79 */
80 property alias dropdownButtonVisuals: dropDownButton
81
82 width: combo.width
83 height: combo.collapsedHeight
84
85 /*! \internal */
86 property ComboButton combo: styledItem
87
88 implicitWidth: mainButton.implicitWidth
89 implicitHeight: mainButton.implicitHeight
90
91 LayoutMirroring.enabled: Qt.application.layoutDirection == Qt.RightToLeft
92 LayoutMirroring.childrenInherit: true
93
94 // Color properties in a JS ternary operator don't work as expected in
95 // QML because it overwrites alpha values with 1. A workaround is to use
96 // Qt.rgba(). For more information, see
97 // https://bugs.launchpad.net/ubuntu-ui-toolkit/+bug/1197802 and
98 // https://bugreports.qt-project.org/browse/QTBUG-32238.
99 /*! \internal */
100 function colorHack(color) { return Qt.rgba(color.r, color.g, color.b, color.a); }
101
102 ButtonStyle {
103 id: mainButton
104 anchors {
105 left: parent.left
106 top: parent.top
107 right: parent.right
108 }
109 height: combo.collapsedHeight
110 // overrides
111 backgroundSource: comboFace
112 buttonFaceOffset: -dropDownWidth/2 - dropDownSeparatorWidth
113 horizontalPadding: units.gu(4) - dropDownSeparatorWidth
114 minimumWidth: units.gu(36)
115
116 // FIXME: use hardcoded color while we get the theme palette updated
117 defaultColor: "#b2b2b2"
118 defaultGradient: null
119
120 // button face
121 ShaderEffectSource {
122 id: comboFace
123 sourceItem: content
124 hideSource: true
125 // FIXME: visible: false prevents rendering so make it a nearly
126 // transparent 1x1 pixel instead
127 opacity: 0.01
128 width: 1
129 height: 1
130 }
131
132 Item {
133 id: content
134 width: mainButton.width
135 height: mainButton.height
136
137 Rectangle {
138 anchors {
139 fill: parent
140 rightMargin: comboStyle.dropDownSeparatorWidth + comboStyle.dropDownWidth
141 }
142 color: combo.color
143 gradient: mainButton.isGradient ? combo.gradient : null
144 }
145
146 // distancer
147 Item {
148 anchors {
149 right: dropDownButton.right
150 top: parent.top
151 bottom: parent.bottom
152 }
153 width: comboStyle.dropDownSeparatorWidth
154 }
155
156 Rectangle {
157 id: dropDownButton
158 objectName: "combobutton_dropdown_visuals"
159 anchors {
160 right: parent.right
161 top: parent.top
162 bottom: parent.bottom
163 }
164 width: comboStyle.dropDownWidth
165 color: combo.expanded ? comboStyle.colorHack(combo.dropdownColorPressed) : comboStyle.colorHack(combo.dropdownColorReleased)
166 Image {
167 source: "artwork/chevron.png"
168 anchors.centerIn: parent
169 rotation: combo.expanded ? -90 : 90
170 }
171 }
172 }
173 }
174
175 Item {
176 id: panelItem
177 anchors {
178 left: parent.left
179 top: mainButton.bottom
180 right: parent.right
181 }
182 opacity: combo.expanded && (combo.comboList.length > 0)? 1.0 : 0.0
183
184 ShaderEffectSource {
185 id: listContent
186 sourceItem: comboListContent
187 hideSource: true
188 // FIXME: visible: false prevents rendering so make it a nearly
189 // transparent 1x1 pixel instead
190 opacity: 0.01
191 width: 1
192 height: 1
193 }
194 Rectangle {
195 id: comboListContent
196 anchors {
197 fill: parent
198 topMargin: comboListMargin
199 }
200 clip: true
201 color: comboStyle.dropDownColorPressed
202 }
203
204 BorderImage {
205 id: shadow
206 anchors {
207 fill: parent
208 leftMargin: -units.gu(0.5)
209 topMargin: comboListMargin - units.gu(0.5)
210 rightMargin: -units.gu(0.5)
211 bottomMargin: -units.gu(0.5)
212 }
213 source: "artwork/bubble_shadow.sci"
214 }
215 UbuntuShape {
216 id: shape
217 anchors {
218 fill: parent
219 topMargin: comboListMargin
220 }
221 visible: true
222 borderSource: "radius_idle.sci"
223 image: listContent
224 }
225
226 Image {
227 source: "artwork/bubble_arrow.png"
228 rotation: 180
229 anchors {
230 bottom: shape.top
231 bottomMargin: -1
232 right: parent.right
233 rightMargin: dropDownWidth / 2 - units.gu(0.5)
234 }
235
236 }
237
238 Behavior on height {
239 NumberAnimation {
240 duration: UbuntuAnimation.FastDuration
241 easing: UbuntuAnimation.StandardEasing
242 }
243 }
244 Behavior on opacity {
245 NumberAnimation {
246 duration: UbuntuAnimation.FastDuration
247 easing: UbuntuAnimation.StandardEasing
248 }
249 }
250 }
251}
0252
=== modified file 'modules/Ubuntu/Components/Themes/Ambiance/qmldir'
--- modules/Ubuntu/Components/Themes/Ambiance/qmldir 2013-12-04 10:47:19 +0000
+++ modules/Ubuntu/Components/Themes/Ambiance/qmldir 2014-04-10 09:56:33 +0000
@@ -26,3 +26,4 @@
26DialerStyle 0.1 DialerStyle.qml26DialerStyle 0.1 DialerStyle.qml
27DialerHandStyle 0.1 DialerHandStyle.qml27DialerHandStyle 0.1 DialerHandStyle.qml
28internal HighlightMagnifier HighlightMagnifier.qml28internal HighlightMagnifier HighlightMagnifier.qml
29ComboButtonStyle 0.1 ComboButtonStyle.qml
2930
=== modified file 'modules/Ubuntu/Components/qmldir'
--- modules/Ubuntu/Components/qmldir 2014-02-13 11:48:38 +0000
+++ modules/Ubuntu/Components/qmldir 2014-04-10 09:56:33 +0000
@@ -44,6 +44,7 @@
44ColorUtils 0.1 colorUtils.js44ColorUtils 0.1 colorUtils.js
45DateUtils 0.1 dateUtils.js45DateUtils 0.1 dateUtils.js
46UbuntuListView 0.1 UbuntuListView.qml46UbuntuListView 0.1 UbuntuListView.qml
47ComboButton 0.1 ComboButton.qml
4748
48internal TextCursor TextCursor.qml49internal TextCursor TextCursor.qml
49internal TextInputPopover TextInputPopover.qml50internal TextInputPopover TextInputPopover.qml
5051
=== modified file 'modules/Ubuntu/Test/UbuntuTestCase.qml'
--- modules/Ubuntu/Test/UbuntuTestCase.qml 2014-02-25 12:36:27 +0000
+++ modules/Ubuntu/Test/UbuntuTestCase.qml 2014-04-10 09:56:33 +0000
@@ -87,7 +87,75 @@
87 }87 }
88 }88 }
8989
90 /*!90 /*!
91 \qmlmethod UbuntuTestCase::flick(item, x, y, dx, dy, pressTimeout = -1, steps = -1, button = Qt.LeftButton, modifiers = Qt.NoModifiers, delay = -1)
92
93 The function produces a flick event when executed on Flickables. When used
94 on other components it provides the same functionality as \l mouseDrag()
95 function. The optional \a pressTimeout parameter can be used to introduce
96 a small delay between the mouse press and the first mouse move. Setting a
97 negative or zero value will disable the timeout.
98
99 The default flick velocity is built up using 5 move points. This can be altered
100 by setting a positive value to \a steps parameter. The bigger the number the
101 longer the flick will be. When a negative or zero value is given, the default
102 of 5 move points will be used.
103
104 \note The function can be used to select a text in a TextField or TextArea by
105 specifying at least 400 millisecods to \a pressTimeout.
106 */
107 function flick(item, x, y, dx, dy, pressTimeout, steps, button, modifiers, delay) {
108 if (item === undefined || item.x === undefined || item.y === undefined)
109 return
110 if (button === undefined)
111 button = Qt.LeftButton
112 if (modifiers === undefined)
113 modifiers = Qt.NoModifier
114 if (steps === undefined || steps <= 0)
115 steps = 4;
116 // make sure we have at least two move steps so the flick will be sensed
117 steps += 1;
118 if (delay === undefined)
119 delay = -1;
120
121 var ddx = dx / steps;
122 var ddy = dy / steps;
123
124 mousePress(item, x, y, button, modifiers, delay);
125 if (pressTimeout !== undefined && pressTimeout > 0) {
126 wait(pressTimeout);
127 }
128 for (var i = 1; i <= steps; i++) {
129 // mouse moves are all processed immediately, without delay in between events
130 mouseMove(item, x + i * ddx, y + i * ddy, -1, button);
131 }
132 mouseRelease(item, x + dx, y + dy, button, modifiers, delay);
133 // empty event buffer
134 wait(200);
135 }
136
137 /*!
138 \qmlmethod UbuntuTestCase::mouseLongPress(item, x, y, button = Qt.LeftButton, modifiers = Qt.NoModifiers, delay = -1)
139
140 Simulates a long press on a mouse \a button with an optional \a modifier
141 on an \a item. The position is defined by \a x and \a y. If \a delay is
142 specified, the test will wait the specified amount of milliseconds before
143 the press.
144
145 The position given by \a x and \a y is transformed from the co-ordinate
146 system of \a item into window co-ordinates and then delivered.
147 If \a item is obscured by another item, or a child of \a item occupies
148 that position, then the event will be delivered to the other item instead.
149
150 \sa mouseRelease(), mouseClick(), mouseDoubleClick(), mouseMove(), mouseDrag(), mouseWheel()
151 */
152 function mouseLongPress(item, x, y, button, modifiers, delay) {
153 mousePress(item, x, y, button, modifiers, delay);
154 // the delay is taken from QQuickMouseArea
155 wait(800);
156 }
157
158 /*!
91 Keeps executing a given parameter-less function until it returns the given159 Keeps executing a given parameter-less function until it returns the given
92 expected result or the timemout is reached (in which case a test failure160 expected result or the timemout is reached (in which case a test failure
93 is generated)161 is generated)
94162
=== modified file 'modules/Ubuntu/Test/deployment.pri'
--- modules/Ubuntu/Test/deployment.pri 2014-01-17 12:30:05 +0000
+++ modules/Ubuntu/Test/deployment.pri 2014-04-10 09:56:33 +0000
@@ -7,9 +7,14 @@
7# make found deployables visible in Qt Creator7# make found deployables visible in Qt Creator
8OTHER_FILES += $$QMLDIR_FILE8OTHER_FILES += $$QMLDIR_FILE
99
10QML_FILES = $$system(ls *.qml)
11JS_FILES = $$system(ls *.js)
12
10# define deployment for found deployables13# define deployment for found deployables
11qmldir_file.path = $$installPath14qmldir_file.path = $$installPath
12qmldir_file.files = $$QMLDIR_FILE15qmldir_file.files = $$QMLDIR_FILE
16qml_files.path = $$installPath
17qml_files.files = $$QML_FILES
13js_files.path = $$installPath18js_files.path = $$installPath
14js_files.files = $$JS_FILES19js_files.files = $$JS_FILES
1520
@@ -20,4 +25,4 @@
20# https://bugreports.qt-project.org/browse/QTBUG-3624325# https://bugreports.qt-project.org/browse/QTBUG-36243
21plugins_qmltypes.extra = $$[QT_INSTALL_BINS]/qmlplugindump -notrelocatable Ubuntu.Test 0.1 ../../ 2>/dev/null > $(INSTALL_ROOT)/$$installPath/plugins.qmltypes26plugins_qmltypes.extra = $$[QT_INSTALL_BINS]/qmlplugindump -notrelocatable Ubuntu.Test 0.1 ../../ 2>/dev/null > $(INSTALL_ROOT)/$$installPath/plugins.qmltypes
2227
23INSTALLS += qmldir_file plugins_qmltypes28INSTALLS += qmldir_file plugins_qmltypes qml_files js_files
2429
=== modified file 'tests/autopilot/ubuntuuitoolkit/emulators.py'
--- tests/autopilot/ubuntuuitoolkit/emulators.py 2014-04-08 14:46:25 +0000
+++ tests/autopilot/ubuntuuitoolkit/emulators.py 2014-04-10 09:56:33 +0000
@@ -470,6 +470,32 @@
470 self.checked.wait_for(not original_state, timeout)470 self.checked.wait_for(not original_state, timeout)
471471
472472
473class ComboButton(UbuntuUIToolkitEmulatorBase):
474 """ComboButton Autopilot emulator."""
475
476 def press_mainbutton(self):
477 """Presses the main button of the ComboBox."""
478 main_button = self.select_single(objectName="combobutton_mainbutton")
479 self.pointing_device.click_object(main_button)
480
481 def press_dropdown(self):
482 """Presses the dropdown button to togle combo list expansion."""
483 dropdown_button = self.select_single(objectName="combobutton_dropdown")
484 self.pointing_device.click_object(dropdown_button)
485
486 def expand(self):
487 """Expands a combo button by clicking on the dropdown button."""
488 if self.expanded:
489 return
490 self.press_dropdown()
491
492 def collapse(self):
493 """Collapses a combo button by clicking on the dropdown button."""
494 if not self.expanded:
495 return
496 self.press_dropdown()
497
498
473class TextField(UbuntuUIToolkitEmulatorBase):499class TextField(UbuntuUIToolkitEmulatorBase):
474 """TextField Autopilot emulator."""500 """TextField Autopilot emulator."""
475501
476502
=== modified file 'tests/autopilot/ubuntuuitoolkit/tests/test_emulators.py'
--- tests/autopilot/ubuntuuitoolkit/tests/test_emulators.py 2014-03-22 06:53:24 +0000
+++ tests/autopilot/ubuntuuitoolkit/tests/test_emulators.py 2014-04-10 09:56:33 +0000
@@ -1079,3 +1079,48 @@
1079 self.composer_sheet.cancel()1079 self.composer_sheet.cancel()
1080 self.assertEqual(self.label.text, 'Cancel selected.')1080 self.assertEqual(self.label.text, 'Cancel selected.')
1081 self._assert_composer_sheet_is_closed()1081 self._assert_composer_sheet_is_closed()
1082
1083
1084class ComboButtonTestCase(tests.QMLStringAppTestCase):
1085
1086 test_qml = ("""
1087import QtQuick 2.0
1088import Ubuntu.Components 0.1
1089import Ubuntu.Components.ListItems 0.1
1090
1091MainView {
1092 width: units.gu(40)
1093 height: units.gu(60)
1094
1095 Item {
1096 ComboButton {
1097 text: "main button"
1098 objectName: "combo_button"
1099 ListView {
1100 model: 10
1101 delegate: Standard {
1102 text: "Item #" + modelData
1103 }
1104 }
1105 }
1106 }
1107}
1108""")
1109
1110 def setUp(self):
1111 super(ComboButtonTestCase, self).setUp()
1112 self.combo = self.main_view.select_single(
1113 emulators.ComboButton, objectName="combo_button")
1114 self.assertFalse(self.combo.expanded)
1115
1116 def test_expand_collapse_combo(self):
1117 self.combo.expand()
1118 self.assertTrue(self.combo.expanded)
1119 self.combo.collapse()
1120 self.assertFalse(self.combo.expanded)
1121
1122 def test_autocollapse(self):
1123 self.combo.expand()
1124 self.assertTrue(self.combo.expanded)
1125 self.combo.press_mainbutton()
1126 self.assertFalse(self.combo.expanded)
10821127
=== added directory 'tests/resources/buttons'
=== added file 'tests/resources/buttons/ComboTest.qml'
--- tests/resources/buttons/ComboTest.qml 1970-01-01 00:00:00 +0000
+++ tests/resources/buttons/ComboTest.qml 2014-04-10 09:56:33 +0000
@@ -0,0 +1,147 @@
1/*
2 * Copyright 2014 Canonical Ltd.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU Lesser General Public License as published by
6 * the Free Software Foundation; version 3.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU Lesser General Public License for more details.
12 *
13 * You should have received a copy of the GNU Lesser General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 *
16 * Author: Zsombor Egri <zsombor.egri@canonical.com>
17 */
18import QtQuick 2.0
19import Ubuntu.Components 0.1
20import Ubuntu.Components.ListItems 0.1
21
22MainView {
23 width: units.gu(40)
24 height: units.gu(71)
25
26
27 Column {
28 anchors.fill: parent
29 spacing: units.gu(2)
30
31 ComboButton {
32 id: combo1
33 text: "collapsedHeight differs"
34 collapsedHeight: units.gu(6)
35 Rectangle {
36 color: "green"
37// height: combo1.comboListHeight
38 }
39 }
40
41 ComboButton {
42 text: "content is Rectangle > expanded"
43 Rectangle {
44 height: units.gu(40)
45 gradient: Gradient {
46 GradientStop {
47 position: 0.0
48 color: "red"
49 }
50 GradientStop {
51 position: 0.5
52 color: "green"
53 }
54 GradientStop {
55 position: 1.0
56 color: "blue"
57 }
58 }
59 }
60 }
61
62 ComboButton {
63 text: "comboList is Flickable"
64 Flickable {
65 id: flickable
66 objectName: "Flickable"
67 anchors {
68 left: parent.left
69 right: parent.right
70 top: parent.top
71 }
72 contentHeight: rect.height
73
74 Rectangle {
75 id: rect
76 width: parent.width
77 height: units.gu(40)
78 gradient: Gradient {
79 GradientStop {
80 position: 0.0
81 color: "red"
82 }
83 GradientStop {
84 position: 0.5
85 color: "green"
86 }
87 GradientStop {
88 position: 1.0
89 color: "blue"
90 }
91 }
92 }
93 }
94 }
95
96 ComboButton {
97 id: combo2
98 text: "comboList is ListView"
99 expanded: true
100 expandedHeight: units.gu(30)
101 UbuntuListView {
102 objectName: "ListView"
103 model: 20
104 delegate: Standard {
105 text: "Action #" + modelData
106 onClicked: {
107 combo2.text = text;
108 combo2.expanded = false
109 }
110 }
111 }
112 }
113
114 ComboButton {
115 id: combo3
116 text: "auto expandHeight"
117 expandedHeight: -1
118 Column {
119 id: column
120 anchors {
121 left: parent.left
122 right: parent.right
123 }
124 Rectangle {
125 width: parent.width
126 height: units.gu(6)
127 color: "red"
128 }
129 Rectangle {
130 width: parent.width
131 height: units.gu(6)
132 color: "green"
133 }
134 Rectangle {
135 width: parent.width
136 height: units.gu(6)
137 color: "blue"
138 }
139 Rectangle {
140 width: parent.width
141 height: units.gu(6)
142 color: "yellow"
143 }
144 }
145 }
146 }
147}
0148
=== modified file 'tests/unit/runtest.sh'
--- tests/unit/runtest.sh 2014-03-31 18:26:46 +0000
+++ tests/unit/runtest.sh 2014-04-10 09:56:33 +0000
@@ -33,7 +33,7 @@
33 if [ $_TARGET != $_TESTFILE ]; then33 if [ $_TARGET != $_TESTFILE ]; then
34 _CMD="$_CMD -input $_TESTFILE"34 _CMD="$_CMD -input $_TESTFILE"
35 fi35 fi
36 _CMD="$_CMD -maxwarnings 4"36 _CMD="$_CMD -maxwarnings 40"
37}37}
3838
39function execute_test_cmd {39function execute_test_cmd {
4040
=== modified file 'tests/unit/tst_components/tst_button.qml'
--- tests/unit/tst_components/tst_button.qml 2013-05-28 12:37:56 +0000
+++ tests/unit/tst_components/tst_button.qml 2014-04-10 09:56:33 +0000
@@ -53,6 +53,10 @@
53 compare(button.color,newColor,"Can set/get color")53 compare(button.color,newColor,"Can set/get color")
54 }54 }
5555
56 function test_font() {
57 verify(button.font === Qt.font({family: "Ubuntu", pixelSize: FontUtils.sizeToPixels("medium")}), "Default font differs");
58 }
59
56 function test_hovered() {60 function test_hovered() {
57 compare(button.hovered,false,"Hovered is boolean and false by default")61 compare(button.hovered,false,"Hovered is boolean and false by default")
58 }62 }
5963
=== added file 'tests/unit_x11/tst_components/tst_combobutton.qml'
--- tests/unit_x11/tst_components/tst_combobutton.qml 1970-01-01 00:00:00 +0000
+++ tests/unit_x11/tst_components/tst_combobutton.qml 2014-04-10 09:56:33 +0000
@@ -0,0 +1,246 @@
1/*
2 * Copyright 2014 Canonical Ltd.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU Lesser General Public License as published by
6 * the Free Software Foundation; version 3.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU Lesser General Public License for more details.
12 *
13 * You should have received a copy of the GNU Lesser General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
16
17import QtQuick 2.0
18import QtTest 1.0
19import Ubuntu.Test 0.1
20import Ubuntu.Components 0.1
21import Ubuntu.Components.ListItems 0.1
22
23Item {
24 width: units.gu(40)
25 height: units.gu(71)
26
27 Column {
28 ComboButton {
29 id: combo
30 }
31
32 ComboButton {
33 id: rectCombo
34
35 Rectangle {
36 id: rect
37 width: parent.width
38 height: units.gu(40)
39 gradient: Gradient {
40 GradientStop {
41 position: 0.0
42 color: "red"
43 }
44 GradientStop {
45 position: 0.5
46 color: "green"
47 }
48 GradientStop {
49 position: 1.0
50 color: "blue"
51 }
52 }
53 }
54 }
55
56 ComboButton {
57 id: columnCombo
58 expandedHeight: -1
59 Column {
60 id: column
61 anchors {
62 left: parent.left
63 right: parent.right
64 }
65 height: childrenRect.height
66 Repeater {
67 model: 5
68 Rectangle {
69 width: parent.width
70 height: units.gu(5)
71 color: Qt.rgba(Math.random(1), Math.random(1), Math.random(1), 1);
72 }
73 }
74 }
75 }
76
77 ComboButton {
78 id: longCombo
79 expandedHeight: units.gu(40)
80 Rectangle {
81 id: longRect
82 height: units.gu(10)
83 color: "cyan"
84 }
85 }
86
87 ComboButton {
88 id: listCombo
89 ListView {
90 id: list
91 model: 20
92 height: listCombo.comboListHeight
93 delegate: Standard {
94 text: modelData
95 }
96 }
97 }
98 }
99
100 SignalSpy { id: spy }
101
102 UbuntuTestCase {
103 name: "ComboButton"
104 when: windowShown
105
106 function cleanup() {
107 rectCombo.expanded =
108 columnCombo.expanded =
109 longCombo.expanded =
110 listCombo.expanded = false;
111 spy.clear();
112 spy.signalName = "";
113 spy.target = undefined;
114 }
115
116 function test_0_defaults() {
117 compare(combo.expanded, false, "not expanded by default");
118 compare(combo.autoCollapse, true, "automatically collapses");
119 compare(combo.collapsedHeight, combo.implicitHeight, "collapsedHeight is implicitHeight");
120 compare(combo.expandedHeight, combo.collapsedHeight + units.gu(19.5), "expanded height default");
121 var lheight = combo.expandedHeight - combo.collapsedHeight - combo.__styleInstance.comboListMargin;
122 compare(combo.comboListHeight, lheight, "comboListHeight default");
123 compare(combo.comboList.length, 0, "comboList is empty");
124 verify(combo.font === Qt.font({family: "Ubuntu", pixelSize: FontUtils.sizeToPixels("medium")}), "Default font differs.");
125 verify(combo.dropdownColorPressed === combo.__styleInstance.defaultDropdownColorPressed, "Default dropdown pressed color differs");
126 verify(combo.dropdownColorReleased === combo.__styleInstance.defaultDropdownColorReleased, "Default dropdown released color differs");
127 }
128
129 function test_dropdownColor() {
130 rectCombo.dropdownColorPressed = "red";
131 rectCombo.dropdownColorReleased = "green";
132 rectCombo.expanded = false;
133 var dropdownFace = findChild(rectCombo, "combobutton_dropdown_visuals");
134 verify(dropdownFace, "Dropdown button visuals cannot be reached");
135 verify(dropdownFace.color === rectCombo.dropdownColorReleased, "Dropdon color when collapsed wrong");
136 rectCombo.expanded = true;
137 waitForRendering(rectCombo);
138 verify(dropdownFace.color === rectCombo.dropdownColorPressed, "Dropdon color when expanded wrong");
139 }
140
141 function test_comboListWidth() {
142 var comboListHolder = findChild(rectCombo, "combobutton_combolist");
143 compare(rect.width, comboListHolder.width, "rectCombo list content width is not adjusted");
144 comboListHolder = findChild(columnCombo, "combobutton_combolist");
145 compare(column.width, comboListHolder.width, "columnCombo list content width is not adjusted");
146 comboListHolder = findChild(longCombo, "combobutton_combolist");
147 compare(longRect.width, comboListHolder.width, "longCombo list content width is not adjusted");
148 comboListHolder = findChild(listCombo, "combobutton_combolist");
149 compare(list.width, comboListHolder.width, "listCombo list content width is not adjusted");
150 }
151
152 function test_expandRectComboThroughProperty() {
153 rectCombo.expanded = true;
154 waitForRendering(rectCombo);
155 var comboListPanel = findChild(rectCombo, "combobutton_combopanel");
156 tryCompareFunction(function() { return comboListPanel.opacity}, 1.0);
157 }
158
159 function test_expandRectComboThroughClick() {
160 var dropDown = findChild(rectCombo, "combobutton_dropdown");
161 mouseClick(dropDown, dropDown.width / 2, dropDown.height / 2);
162 waitForRendering(rectCombo);
163 compare(rectCombo.expanded, true, "combo is not expanded");
164 var comboListPanel = findChild(rectCombo, "combobutton_combopanel");
165 tryCompareFunction(function() { return comboListPanel.opacity}, 1.0);
166 }
167
168 function test_autoCollapse() {
169 var dropDown = findChild(rectCombo, "combobutton_dropdown");
170 var comboListPanel = findChild(rectCombo, "combobutton_combopanel");
171 mouseClick(dropDown, dropDown.width / 2, dropDown.height / 2);
172 waitForRendering(rectCombo);
173 compare(rectCombo.expanded, true, "combo is not expanded");
174 tryCompareFunction(function() { return comboListPanel.opacity}, 1.0);
175
176 mouseClick(rectCombo, rectCombo.width / 2, rectCombo.collapsedHeight / 2);
177 waitForRendering(rectCombo);
178 compare(rectCombo.expanded, false, "combo is not collapsed");
179 tryCompareFunction(function() { return comboListPanel.opacity}, 0.0);
180 }
181
182 function test_flickRectCombo() {
183 var dropDown = findChild(rectCombo, "combobutton_dropdown");
184 var comboListPanel = findChild(rectCombo, "combobutton_combopanel");
185 var comboList = findChild(rectCombo, "combobutton_combolist");
186 mouseClick(dropDown, dropDown.width / 2, dropDown.height / 2);
187 waitForRendering(rectCombo);
188 tryCompareFunction(function() { return comboListPanel.opacity}, 1.0);
189 verify(comboList.height > rectCombo.expandedHeight);
190 // comboList flicker is the combolist parent's parent
191 var comboListFlicker = comboList.parent.parent;
192 compare(comboListFlicker.interactive, true, "combo list holder must be interactive");
193
194 // drag the rectangle, the Flickable should be moving
195 var x = comboListFlicker.width / 2;
196 var y = comboListFlicker.height / 2;
197 var dy = comboListFlicker.height / 6;
198 spy.target = comboListFlicker;
199 spy.signalName = "onMovementEnded";
200 mouseDrag(comboListFlicker, x, y, x, dy);
201 waitForRendering(comboListFlicker);
202 compare(spy.count, 1, "combo list content did not move");
203 }
204
205 function test_autoExpandHeight() {
206 var comboListPanel = findChild(columnCombo, "combobutton_combopanel");
207 var comboList = findChild(columnCombo, "combobutton_combolist");
208 columnCombo.expanded = true;
209 waitForRendering(columnCombo);
210 tryCompareFunction(function() { return comboListPanel.opacity}, 1.0);
211 var comboListFlicker = comboList.parent.parent;
212 compare(comboListFlicker.interactive, false, "combo list holder must not be interactive");
213 compare(comboListFlicker.height, columnCombo.comboListHeight, "combo list height differs from the holder height");
214 }
215
216 function test_emptyComboExpanded() {
217 var comboListPanel = findChild(combo, "combobutton_combopanel");
218 var comboList = findChild(combo, "combobutton_combolist");
219 combo.expanded = true;
220 waitForRendering(combo);
221 waitForRendering(comboListPanel);
222 tryCompareFunction(function() { return comboListPanel.opacity}, 0.0, 1000);
223 }
224
225 function test_longCombo() {
226 var comboListPanel = findChild(longCombo, "combobutton_combopanel");
227 var comboList = findChild(longCombo, "combobutton_combolist");
228 longCombo.expanded = true;
229 waitForRendering(longCombo);
230 waitForRendering(comboListPanel);
231 tryCompareFunction(function() { return comboListPanel.opacity}, 1.0);
232 verify(comboListPanel.height < longCombo.expandedHeight);
233 }
234
235 function test_listCombo() {
236 var comboListPanel = findChild(listCombo, "combobutton_combopanel");
237 var comboList = findChild(listCombo, "combobutton_combolist");
238 listCombo.expanded = true;
239 waitForRendering(listCombo);
240 waitForRendering(comboListPanel);
241 tryCompareFunction(function() { return comboListPanel.opacity}, 1.0);
242
243 compare(list.height, comboList.height, "list and comboList height differs");
244 }
245 }
246}
0247
=== modified file 'tests/unit_x11/tst_components/tst_components.pro'
--- tests/unit_x11/tst_components/tst_components.pro 2013-11-26 12:44:39 +0000
+++ tests/unit_x11/tst_components/tst_components.pro 2014-04-10 09:56:33 +0000
@@ -7,4 +7,5 @@
7SOURCES += tst_components.cpp tabsmodel.cpp7SOURCES += tst_components.cpp tabsmodel.cpp
8HEADERS += tabsmodel.h8HEADERS += tabsmodel.h
99
10OTHER_FILES += $$system(ls *.qml)10OTHER_FILES += $$system(ls *.qml) \
11 tst_combobutton.qml
1112
=== modified file 'tests/unit_x11/tst_test/tst_ubuntutestcase.qml'
--- tests/unit_x11/tst_test/tst_ubuntutestcase.qml 2014-02-13 10:27:14 +0000
+++ tests/unit_x11/tst_test/tst_ubuntutestcase.qml 2014-04-10 09:56:33 +0000
@@ -23,30 +23,57 @@
23 width: 80023 width: 800
24 height: 60024 height: 600
2525
26 MouseArea {26 Column {
27 id: mouseArea27 anchors.fill: parent
28 objectName: "myMouseArea"28 MouseArea {
29 anchors.fill: parent29 id: mouseArea
30 hoverEnabled: true30 objectName: "myMouseArea"
31 property int testX : 031 width: parent.width
32 property int testY : 032 height: 300
33 property int steps : 033 hoverEnabled: true
34 acceptedButtons: Qt.LeftButton | Qt.MiddleButton | Qt.RightButton
35 property int testX : 0
36 property int testY : 0
37 property int steps : 0
3438
35 onPositionChanged: {39 onPositionChanged: {
36 testX = mouseX;40 testX = mouseX;
37 testY = mouseY;41 testY = mouseY;
38 steps++;42 steps++;
39 }43 }
44 }
45 Flickable {
46 id: flicker
47 width: parent.width
48 height: 400
49 contentWidth: rect.width
50 contentHeight: rect.height
51 clip: true
52 Rectangle {
53 id: rect
54 color: "blue"
55 width: 1000
56 height: 1000
57 }
58 }
40 }59 }
41 60
42 UbuntuTestCase {61 UbuntuTestCase {
43 name: "TestTheUbuntuTestCase"62 name: "TestTheUbuntuTestCase"
44 when: windowShown63 when: windowShown
4564
65 function init() {
66 mouseArea.steps = 0;
67 }
68 function cleanup() {
69 movementSpy.clear();
70 longPressSpy.clear();
71 }
72
46 function test_mouseMoveSlowly() {73 function test_mouseMoveSlowly() {
47 mouseMoveSlowly(root,0,0,800,600,10,100);74 mouseMoveSlowly(root,0,0,800,300,10,100);
48 compare(mouseArea.testX,800);75 compare(mouseArea.testX,800);
49 compare(mouseArea.testY,600);76 compare(mouseArea.testY,300);
50 compare(mouseArea.steps,10);77 compare(mouseArea.steps,10);
51 }78 }
5279
@@ -58,5 +85,66 @@
58 child = findChild(root,"NoSuchChildHere");85 child = findChild(root,"NoSuchChildHere");
59 compare(child===null,true,"When there is no child, function should return null");86 compare(child===null,true,"When there is no child, function should return null");
60 }87 }
88
89 SignalSpy {
90 id: longPressSpy
91 target: mouseArea
92 signalName: "onPressAndHold"
93 }
94
95 function test_longPress_left() {
96 longPressSpy.clear();
97 mouseLongPress(mouseArea, mouseArea.width / 2, mouseArea.height / 2);
98 longPressSpy.wait();
99 // cleanup
100 mouseRelease(mouseArea, mouseArea.width / 2, mouseArea.height / 2);
101 }
102
103 function test_longPress_right() {
104 longPressSpy.clear();
105 mouseLongPress(mouseArea, mouseArea.width / 2, mouseArea.height / 2, Qt.RightButton);
106 longPressSpy.wait();
107 // cleanup
108 mouseRelease(mouseArea, mouseArea.width / 2, mouseArea.height / 2, Qt.RightButton);
109 }
110
111 function test_longPress_middle() {
112 longPressSpy.clear();
113 mouseLongPress(mouseArea, mouseArea.width / 2, mouseArea.height / 2, Qt.MiddleButton);
114 longPressSpy.wait();
115 // cleanup
116 mouseRelease(mouseArea, mouseArea.width / 2, mouseArea.height / 2, Qt.MiddleButton);
117 }
118
119 SignalSpy {
120 id: movementSpy
121 target: flicker
122 signalName: "onMovementEnded"
123 }
124
125 function test_flick_default() {
126 flick(flicker, 0, 0, flicker.width, flicker.height);
127 movementSpy.wait();
128 }
129 function test_flick_long() {
130 flick(flicker, 0, 0, flicker.width, flicker.height, -1, 10);
131 movementSpy.wait();
132 }
133 function test_flick_short() {
134 flick(flicker, 0, 0, flicker.width, flicker.height, -1, 1);
135 movementSpy.wait();
136 }
137 function test_flick_pressTimeout() {
138 flick(flicker, 0, 0, flicker.width, flicker.height, 400);
139 movementSpy.wait();
140 }
141 function test_flick_pressTimeout_short() {
142 flick(flicker, flicker.width, flicker.height, -flicker.width, -flicker.height, 400, 1);
143 movementSpy.wait();
144 }
145 function test_flick_pressTimeout_long() {
146 flick(flicker, flicker.width, flicker.height, -flicker.width, -flicker.height, 400, 100);
147 movementSpy.wait();
148 }
61 }149 }
62}150}

Subscribers

People subscribed via source and target branches

to status/vote changes: