on xenial help sign in
fix preview background positioning

- don't explicitly take originY into account as it's already in there implicitly - make sure we don't split the openeffect in a place where it can be covered by the header. Approved by PS Jenkins bot, Albert Astals Cid.

commite0ae96b38f40ada399663bfbb3eef5adf81e3a23 authorMichael Zanetti <michael.zanetti@canonical.com> dateTue 19 Nov 2013, 10:44 (13 years ago) parentf67edec76547e7
6 files changed+185−7
Dash/GenericScopeView.qml+12−5 plugins/ListViewWithPageHeader/listviewwithpageheader.cpp+7 plugins/ListViewWithPageHeader/listviewwithpageheader.h+4 tests/plugins/ListViewWithPageHeader/CMakeLists.txt+7 tests/plugins/ListViewWithPageHeader/tst_listviewwithpageheaderqml.qml+138 tests/qmltests/Dash/tst_GenericScopeView.qml+17−2
Dash/GenericScopeView.qml+12−5
@@ -175,7 +175,7 @@ FocusScope {
175175 target: rendererLoader.item
176176 onClicked: {
177177 // Prepare the preview in case activate() triggers a preview only
178− effect.positionPx = mapToItem(categoryView, 0, itemY).y
178+ effect.positionPx = Math.max(mapToItem(categoryView, 0, itemY).y, pageHeader.height + categoryView.stickyHeaderHeight);
179179 previewListView.categoryId = categoryId
180180 previewListView.categoryDelegate = rendererLoader.item
181181 previewListView.model = target.model;
@@ -196,7 +196,7 @@ FocusScope {
196196 }
197197 }
198198 onPressAndHold: {
199− effect.positionPx = mapToItem(categoryView, 0, itemY).y
199+ effect.positionPx = Math.max(mapToItem(categoryView, 0, itemY).y, pageHeader.height + categoryView.stickyHeaderHeight);
200200 previewListView.categoryId = categoryId
201201 previewListView.categoryDelegate = rendererLoader.item
202202 previewListView.model = target.model;
@@ -438,12 +438,19 @@ FocusScope {
438438
439439 if (!init && model !== undefined) {
440440 var item = model.get(currentIndex)
441− scopeView.scope.preview( item.uri, item.icon, item.category, 0, item.mimetype, item.title, item.comment, item.dndUri, item.metadata)
441+ scopeView.scope.preview(item.uri, item.icon, item.category, 0, item.mimetype, item.title, item.comment, item.dndUri, item.metadata)
442442 }
443443
444444 var itemY = categoryView.contentItem.mapFromItem(categoryDelegate.currentItem).y;
445+
446+ // Find new contentY and effect.postionPx
445447 var newContentY = itemY - effect.positionPx - categoryDelegate.verticalSpacing;
446− var effectAdjust = effect.positionPx;
448+
449+ // Make sure the item is not covered by a header. Move the effect split down if necessary
450+ var headerHeight = pageHeader.height + categoryView.stickyHeaderHeight;
451+ var effectAdjust = Math.max(effect.positionPx, headerHeight);
452+
453+ // Make sure we don't overscroll the listview. If yes, adjust effect position
447454 if (newContentY < 0) {
448455 effectAdjust += newContentY;
449456 newContentY = 0;
@@ -454,7 +461,7 @@ FocusScope {
454461 }
455462
456463 effect.positionPx = effectAdjust;
457− categoryView.contentY = newContentY - categoryView.originY;
464+ categoryView.contentY = newContentY;
458465 }
459466
460467 property bool open: false
plugins/ListViewWithPageHeader/listviewwithpageheader.cpp+7
@@ -287,10 +287,12 @@ void ListViewWithPageHeader::setSectionDelegate(QQmlComponent *delegate)
287287 m_topSectionItem = getSectionItem(QString());
288288 m_topSectionItem->setZ(3);
289289 QQuickItemPrivate::get(m_topSectionItem)->setCulled(true);
290+ connect(m_topSectionItem, SIGNAL(heightChanged()), SIGNAL(stickyHeaderHeightChanged()));
290291
291292 // TODO create sections for existing items
292293
293294 Q_EMIT sectionDelegateChanged();
295+ Q_EMIT stickyHeaderHeightChanged();
294296 }
295297}
296298
@@ -326,6 +328,11 @@ void ListViewWithPageHeader::setForceNoClip(bool noClip)
326328 }
327329}
328330
331+int ListViewWithPageHeader::stickyHeaderHeight() const
332+{
333+ return m_topSectionItem ? m_topSectionItem->height() : 0;
334+}
335+
329336void ListViewWithPageHeader::positionAtBeginning()
330337{
331338 if (m_delegateModel->count() <= 0)
plugins/ListViewWithPageHeader/listviewwithpageheader.h+4
@@ -60,6 +60,7 @@ class ListViewWithPageHeader : public QQuickFlickable, public QQuickItemChangeLi
6060 Q_PROPERTY(QQmlComponent *sectionDelegate READ sectionDelegate WRITE setSectionDelegate NOTIFY sectionDelegateChanged)
6161 Q_PROPERTY(QString sectionProperty READ sectionProperty WRITE setSectionProperty NOTIFY sectionPropertyChanged)
6262 Q_PROPERTY(bool forceNoClip READ forceNoClip WRITE setForceNoClip NOTIFY forceNoClipChanged)
63+ Q_PROPERTY(int stickyHeaderHeight READ stickyHeaderHeight NOTIFY stickyHeaderHeightChanged)
6364
6465 friend class ListViewWithPageHeaderTest;
6566 friend class ListViewWithPageHeaderTestSection;
@@ -87,6 +88,8 @@ public:
8788 bool forceNoClip() const;
8889 void setForceNoClip(bool noClip);
8990
91+ int stickyHeaderHeight() const;
92+
9093 Q_INVOKABLE void positionAtBeginning();
9194 Q_INVOKABLE void showHeader();
9295 Q_INVOKABLE QQuickItem *item(int modelIndex) const;
@@ -104,6 +107,7 @@ Q_SIGNALS:
104107 void sectionDelegateChanged();
105108 void sectionPropertyChanged();
106109 void forceNoClipChanged();
110+ void stickyHeaderHeightChanged();
107111
108112protected:
109113 void componentComplete();
tests/plugins/ListViewWithPageHeader/CMakeLists.txt+7
@@ -1,3 +1,6 @@
1+# add_qml_test macro
2+include(QmlTest)
3+
14# There's no cmake var for v8 include path :-/
25# so create one
36LIST(GET Qt5Core_INCLUDE_DIRS 0 QtCoreDir0)
@@ -37,6 +40,10 @@ qt5_use_modules(listviewwithpageheadertestsectionexternalmodelExec Test Core Qml
3740target_link_libraries(listviewwithpageheadertestsectionexternalmodelExec ${Qt5Gui_LIBRARIES} ${Qt5Quick_LIBRARIES})
3841add_custom_target(testlistviewwithpageheadersectionexternalmodel ${CMAKE_CURRENT_BINARY_DIR}/listviewwithpageheadertestsectionexternalmodelExec -o ${CMAKE_BINARY_DIR}/testlistviewwithpageheadersectionexternalmodel.xml,xunitxml -o -,txt)
3942
43+set(qmltest_DEFAULT_NO_ADD_TEST TRUE)
44+add_qml_test(. listviewwithpageheaderqml IMPORT_PATHS ${CMAKE_BINARY_DIR}/plugins)
45+
4046add_dependencies(qmluitests testlistviewwithpageheader)
4147add_dependencies(qmluitests testlistviewwithpageheadersection)
4248add_dependencies(qmluitests testlistviewwithpageheadersectionexternalmodel)
49+add_dependencies(qmluitests testlistviewwithpageheaderqml)
tests/plugins/ListViewWithPageHeader/tst_listviewwithpageheaderqml.qmlnew file+138
@@ -0,0 +1,138 @@
1+/*
2+ * Copyright (C) 2013 Canonical, Ltd.
3+ *
4+ * This program is free software; you can redistribute it and/or modify
5+ * it under the terms of the GNU 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 General Public License for more details.
12+ *
13+ * You should have received a copy of the GNU General Public License
14+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
15+ */
16+
17+import QtQuick 2.0
18+import QtTest 1.0
19+import ListViewWithPageHeader 0.1
20+
21+Rectangle {
22+ width: 300
23+ height: 542
24+ color: "lightblue"
25+
26+ ListModel {
27+ id: model
28+
29+ function insertItem(index, size, type) {
30+ insert(index, { size: size, type: type });
31+ }
32+
33+ function removeItems(index, count) {
34+ remove(index, count);
35+ }
36+
37+ function moveItems(indexFrom, indexTo, count) {
38+ move(indexFrom, indexTo, count);
39+ }
40+
41+ ListElement { type: "Agressive"; size: 150 }
42+ ListElement { type: "Regular"; size: 200 }
43+ ListElement { type: "Mild"; size: 350 }
44+ ListElement { type: "Bold"; size: 350 }
45+ ListElement { type: "Bold"; size: 350 }
46+ ListElement { type: "Lazy"; size: 350 }
47+ }
48+
49+ ListViewWithPageHeader {
50+ id: listView
51+ width: parent.width
52+ anchors.top: parent.top
53+ anchors.bottom: parent.bottom
54+ model: model
55+ delegate: Rectangle {
56+ property bool timerDone: false
57+ width: parent.width - 20
58+ x: 10
59+ color: index % 2 == 0 ? "red" : "blue"
60+ height: size
61+ Text {
62+ text: index
63+ }
64+ }
65+
66+ pageHeader: Rectangle {
67+ color: "transparent"
68+ width: parent.width
69+ height: 50
70+ implicitHeight: 50
71+ Text {
72+ anchors.fill: parent
73+ text: "APPS"
74+ font.pixelSize: 40
75+ }
76+ }
77+
78+ sectionProperty: "type"
79+
80+ property int sectionHeaderHeight: 40
81+ sectionDelegate: Component {
82+ id: sectionHeaderComponent
83+ Rectangle {
84+ color: "green"
85+ height: listView.sectionHeaderHeight
86+ Text { text: section; font.pixelSize: 34 }
87+ anchors { left: parent.left; right: parent.right }
88+ }
89+ }
90+ }
91+
92+ Component {
93+ id: otherSectionHeaderComponent
94+ Rectangle {
95+ color: "green"
96+ height: 50
97+ Text { text: section; font.pixelSize: 34 }
98+ anchors { left: parent.left; right: parent.right }
99+ }
100+ }
101+
102+ SignalSpy {
103+ id: stickyHeaderHeigthSpy
104+ target: listView
105+ signalName: "stickyHeaderHeightChanged"
106+ }
107+
108+ TestCase {
109+ name: "ListViewWithPageHeaderTest"
110+ when: windowShown
111+
112+ function test_stickyHeaderHeightNewHeader() {
113+ stickyHeaderHeigthSpy.clear();
114+ compare(listView.stickyHeaderHeight, 40);
115+
116+ listView.sectionDelegate = otherSectionHeaderComponent;
117+ compare(listView.stickyHeaderHeight, 50);
118+ compare(stickyHeaderHeigthSpy.count, 1);
119+
120+ listView.sectionDelegate = sectionHeaderComponent;
121+ compare(listView.stickyHeaderHeight, 40);
122+ compare(stickyHeaderHeigthSpy.count, 2);
123+ }
124+
125+ function test_stickyHeaderHeightGrowingHeader() {
126+ stickyHeaderHeigthSpy.clear();
127+
128+ compare(listView.stickyHeaderHeight, 40);
129+
130+ listView.sectionHeaderHeight = 60;
131+ compare(listView.stickyHeaderHeight, 60);
132+ compare(stickyHeaderHeigthSpy.count, 1);
133+
134+ // Restore height for other tests
135+ listView.sectionHeaderHeight = 40;
136+ }
137+ }
138+}
tests/qmltests/Dash/tst_GenericScopeView.qml+17−2
@@ -132,7 +132,23 @@ Item {
132132 tryCompare(previewListView, "open", false);
133133 }
134134
135− function test_previewCycleOne() {
135+ function test_hiddenPreviewOpen() {
136+ var categoryListView = findChild(genericScopeView, "categoryListView");
137+ categoryListView.positionAtBeginning();
138+ waitForRendering(categoryListView);
139+ categoryListView.flick(0, -units.gu(80));
140+ tryCompare(categoryListView.flicking, false);
141+
142+ var tile = findChild(genericScopeView, "delegate0");
143+ mouseClick(tile, tile.width / 2, tile.height - 1);
144+ var openEffect = findChild(genericScopeView, "openEffect");
145+ tryCompare(openEffect, "gap", 1);
146+
147+ var pageHeader = findChild(genericScopeView, "pageHeader");
148+ verify(openEffect.positionPx >= pageHeader.height + categoryListView.stickyHeaderHeight);
149+ }
150+
151+ function test_previewCycle() {
136152 var previewListView = findChild(genericScopeView, "previewListView");
137153 tryCompare(previewListView, "open", false);
138154
@@ -173,7 +189,6 @@ Item {
173189
174190 checkArrowPosition(i);
175191 }
176−
177192 closePreview();
178193 }
179194