Merge lp:~uriboni/unity-2d/launcher-autoscroll into lp:unity-2d/3.0

Proposed by Florian Boucault
Status: Merged
Approved by: Florian Boucault
Approved revision: 396
Merged at revision: 392
Proposed branch: lp:~uriboni/unity-2d/launcher-autoscroll
Merge into: lp:unity-2d/3.0
Diff against target: 198 lines (+146/-5)
2 files modified
launcher/AutoScrollingListView.qml (+132/-0)
launcher/Launcher.qml (+14/-5)
To merge this branch: bzr merge lp:~uriboni/unity-2d/launcher-autoscroll
Reviewer Review Type Date Requested Status
Florian Boucault (community) Approve
Review via email: mp+49990@code.launchpad.net

This proposal supersedes a proposal from 2011-02-14.

Description of the change

[launcher] Adds an autoscrolling feature to the launcher. It works by having two sensitive zones at the top and bottom of the launcher. When the mouse enters these zones, the laucher will scroll up or down if needed, until the mouse leaves the zone.

To post a comment you must log in.
Revision history for this message
Florian Boucault (fboucault) wrote : Posted in a previous version of this proposal

* First few pixels at the top are not triggering the autoscroll.
* Autoscrolling is active even though there is not enough content to fill the ListView (for example if you have around 5-8 applications in a medium resolution monitor, the trash will not be at the bottom though if you stick the mouse cursor at the bottom of the launcher, the autoscrolling is triggered).

review: Needs Fixing (functional)
Revision history for this message
Florian Boucault (fboucault) wrote : Posted in a previous version of this proposal

HACK about the mouse coordinates should be FIXME.

review: Needs Fixing
Revision history for this message
Florian Boucault (fboucault) wrote : Posted in a previous version of this proposal

"Implements a ListView that have two mouse sensitive areas"
should read
"ListView that has two mouse sensitive areas"

review: Needs Fixing
Revision history for this message
Florian Boucault (fboucault) wrote : Posted in a previous version of this proposal

After testing I think it would be better to have 'autoScrollSize' to be itemHeight / 2 instead of itemHeight / 3

review: Needs Fixing
Revision history for this message
Florian Boucault (fboucault) wrote : Posted in a previous version of this proposal

Sometimes the following WARNING is issued in the console:

AutoScrollingListView.qml:105 Insufficient Arguments

Revision history for this message
Florian Boucault (fboucault) wrote : Posted in a previous version of this proposal

While the workaround for the QML bug is essentially fine, it would have been simpler to write using property binding.

We do not have time to simplify it now, so let's keep it as is.

Revision history for this message
Florian Boucault (fboucault) wrote : Posted in a previous version of this proposal

Why do you need an extra property 'spacingSize'? Using 'spacing' is enough.

review: Needs Fixing
Revision history for this message
Florian Boucault (fboucault) wrote : Posted in a previous version of this proposal

"""
"Implements a ListView that have two mouse sensitive areas"
should read
"ListView that has two mouse sensitive areas"
"""

Quoting my previous comment here. You will notice that not only have I replaced the 'have' with 'has' but also I removed the 'Implements a'. It's a new class, we *know* it implements something.

review: Needs Fixing
Revision history for this message
Ugo Riboni (uriboni) wrote : Posted in a previous version of this proposal

Fixed the last remarks and made sure the autoscroll happens only when it needs to.
Also have a look at the padding stuff in commit 394, which to me seems a quite clean way of doing it, but comments always welcome.

Revision history for this message
Florian Boucault (fboucault) wrote : Posted in a previous version of this proposal

Good to go!

review: Approve
Revision history for this message
Florian Boucault (fboucault) wrote : Posted in a previous version of this proposal

No proposals found for merge of lp:~unity-2d-team/unity-2d/launcher-layout into lp:unity-2d.

Revision history for this message
Florian Boucault (fboucault) wrote :

Good to go, again.

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== added file 'launcher/AutoScrollingListView.qml'
2--- launcher/AutoScrollingListView.qml 1970-01-01 00:00:00 +0000
3+++ launcher/AutoScrollingListView.qml 2011-02-16 15:55:29 +0000
4@@ -0,0 +1,132 @@
5+import Qt 4.7
6+
7+/* AutoScrollingListView
8+
9+ ListView that has two mouse sensitive areas, one at the top and one at the bottom.
10+ While the cursors is in these areas the list automatically scrolls in the direction
11+ where the area is until the cursor exits the area or the scrolling reaches the edge.
12+
13+ In addition to this, it is possible to add padding at the top and/or bottom of the
14+ list that takes part in the scrolling (contrary to what would happen by adding this
15+ extra space using margins).
16+
17+ The property 'autoScrollSize' controls how tall are the two sensitive areas.
18+ The speed of the scrolling is controlled by 'autoScrollVelocity'.
19+ You can check if we are currently autoscrolling using the 'autoScrolling' property.
20+ The properties 'paddingTop' and 'paddingBottom' control the size of the padding.
21+*/
22+ListView {
23+ id: list
24+ property int autoScrollSize
25+ property real autoScrollVelocity
26+ property bool autoScrolling: scrollUp.running || scrollDown.running
27+ property int paddingTop: 0
28+ property int paddingBottom: 0
29+
30+ /* We implement the padding by adding an empty footer and header
31+ of the requested size. The header and footer are inside the ListView
32+ (contrary to the use of anchors.margins, which adds space outside).
33+ However they are not included in contentHeight, therefore we need to
34+ adjust the rest of the autoscrolling code to take them into account.
35+ */
36+ header: Item { height: list.paddingTop }
37+ footer: Item { height: list.paddingBottom }
38+
39+ /* This is necessary to initially scroll to a position where the header
40+ is visible. Otherwise the edge of the first item would be at the top
41+ of the list */
42+ contentY: 0 - paddingTop
43+
44+ MouseArea {
45+ id: scrollZoneTop
46+ width: parent.width
47+ height: autoScrollSize
48+ anchors.top: parent.top
49+ hoverEnabled: true
50+ }
51+
52+ MouseArea {
53+ id: scrollZoneBottom
54+ width: parent.width
55+ height: autoScrollSize
56+ anchors.bottom: parent.bottom
57+ hoverEnabled: true
58+ }
59+
60+ SmoothedAnimation {
61+ id: scrollUp
62+ target: list
63+ property: "contentY"
64+ to: 0 - paddingTop
65+ velocity: autoScrollVelocity
66+ running: scrollZoneTop.containsMouse
67+ }
68+
69+ SmoothedAnimation {
70+ id: scrollDown
71+ target: list
72+ property: "contentY"
73+ to: contentHeight + paddingBottom - height
74+ velocity: autoScrollVelocity
75+ running: scrollZoneBottom.containsMouse && contentHeight + paddingBottom > height
76+ }
77+
78+ /* The code below this comment is only needed as a workaround for a strange behavior
79+ (or bug) in QML. Essentially MouseEvents have an accepted property, but in most cases
80+ it doesn't matter what you set it to: the event is always accepted and not propagated
81+ further. This prevents mouse activity on the two MouseAreas to flow down to the list
82+ items. Therefore we need to forward the events we need (entered, exited, clicked).
83+ The QT bug reference is:
84+ http://bugreports.qt.nokia.com/browse/QTBUG-13007?focusedCommentId=137123
85+ */
86+ property variant itemBelow: null
87+
88+ Connections {
89+ target: scrollZoneTop
90+ onEntered: updateItemBelow(scrollZoneTop)
91+ onPositionChanged: updateItemBelow(scrollZoneTop)
92+ onClicked: forwardClick(scrollZoneTop, mouse)
93+ }
94+
95+ Connections {
96+ target: scrollZoneBottom
97+ onEntered: updateItemBelow(scrollZoneBottom)
98+ onPositionChanged: updateItemBelow(scrollZoneBottom)
99+ onClicked: forwardClick(scrollZoneBottom, mouse)
100+ }
101+
102+ onContentYChanged: updateItemBelow((scrollZoneBottom.containsMouse) ? scrollZoneBottom :
103+ (scrollZoneTop.containsMouse) ? scrollZoneTop : null)
104+
105+ function updateItemBelow(zone) {
106+ if (zone == null) return
107+ var point = zone.mapToItem(list.contentItem, zone.mouseX, zone.mouseY)
108+ var item = list.contentItem.childAt(point.x, point.y)
109+ /* Ignore header, footer and any item that doesn't have the signals
110+ we need to forward */
111+ if (item && (typeof(item.entered) != "function" ||
112+ typeof(item.exited) != "function")) item = null;
113+
114+ if (item == null) {
115+ if (itemBelow != null) {
116+ itemBelow.exited()
117+ itemBelow = null
118+ }
119+ } else {
120+ if (itemBelow != item && itemBelow != null) itemBelow.exited()
121+ item.entered()
122+ itemBelow = item
123+ }
124+ }
125+
126+ /* FIXME: We forward the click but the coordinates will be wrong since they are expressed in the
127+ coordinate system of the MouseArea where it happened. However they are readonly properties in
128+ the MouseEvent so we can't update them with the translated values.
129+ It should be ok for now since we don't use them for now.
130+ */
131+ function forwardClick(zone, mouse) {
132+ var point = zone.mapToItem(list.contentItem, zone.mouseX, zone.mouseY)
133+ var item = list.contentItem.childAt(point.x, point.y)
134+ if (item && typeof(item.clicked) == "function") item.clicked(mouse)
135+ }
136+}
137
138=== modified file 'launcher/Launcher.qml'
139--- launcher/Launcher.qml 2011-02-16 11:11:46 +0000
140+++ launcher/Launcher.qml 2011-02-16 15:55:29 +0000
141@@ -13,12 +13,18 @@
142 source: "artwork/background.png"
143 }
144
145- ListView {
146+ AutoScrollingListView {
147 id: list
148+
149 spacing: 5
150- anchors.topMargin: 5
151+ paddingTop: 5
152+ paddingBottom: 5
153+
154 anchors.fill: parent
155 focus: true
156+ property int itemHeight: 54
157+ autoScrollSize: itemHeight / 2
158+ autoScrollVelocity: 200
159
160 /* Keep a reference to the currently visible contextual menu */
161 property variant visibleMenu
162@@ -39,7 +45,7 @@
163 urgent: item.urgent
164 launching: item.launching
165 pips: Math.min(item.windowCount, 3)
166- tileSize: 54
167+ tileSize: list.itemHeight
168
169 /* Best way I could find to check if the item is an application or the
170 workspaces switcher. There may be something cleaner and better. */
171@@ -60,7 +66,9 @@
172 list.visibleMenu = item.menu
173 // The extra 4 pixels are needed to center exactly with the arrow
174 // that indicated the active tile.
175- item.menu.show(width, y + height / 2 - list.contentY + panel.y + 4)
176+ item.menu.show(width,
177+ y + height / 2 - list.contentY +
178+ panel.y - list.paddingTop + 4)
179 }
180
181 onClicked: {
182@@ -76,7 +84,7 @@
183
184 /* Display the tooltip when hovering the item only when the list
185 is not moving */
186- onEntered: if (!list.moving) showMenu()
187+ onEntered: if (!list.moving && !list.autoScrolling) showMenu()
188 onExited: {
189 /* When unfolded, leave enough time for the user to reach the
190 menu. Necessary because there is some void between the item
191@@ -91,6 +99,7 @@
192 Connections {
193 target: list
194 onMovementStarted: item.menu.hide()
195+ onAutoScrollingChanged: if (list.autoScrolling) item.menu.hide()
196 }
197
198 function setIconGeometry() {

Subscribers

People subscribed via source and target branches

to all changes: