on xenial help sign in
Fix binding loop in FilterGrid height
commita14b4bb6f11f4220c8966185ed0bd960d1de6391 authorAlbert Astals <albert.astals@canonical.com> dateTue 29 Apr 2014, 15:19 (12 years ago) parenta6f2b2dcf638df
7 files changed+52−49
qml/Components/FilterGrid.qml+37−24 qml/Dash/CardFilterGrid.qml+3−8 qml/Dash/DashRenderer.qml+3−3 qml/Dash/GenericScopeView.qml+4−9 tests/autopilot/unity8/shell/tests/test_emulators.py+1−1 tests/qmltests/Components/tst_FilterGrid.qml+1−1 tests/qmltests/Dash/tst_GenericScopeView.qml+3−3
qml/Components/FilterGrid.qml+37−24
@@ -28,11 +28,6 @@ import "../Components"
2828Item {
2929 id: root
3030
31− /* If true, the number of elements displayed will be limited by collapsedRowCount.
32− If false, all elements will be displayed, effectively looking the same as a regular
33− ResponsiveGridView. */
34− property bool filter: true
35−
3631 /* Whether, when collapsed, a button should be displayed enabling the user to expand
3732 the grid to its full size. */
3833 readonly property bool expandable: model.count > rowsWhenCollapsed * iconTileGrid.columns
@@ -65,30 +60,48 @@ Item {
6560 readonly property alias pressDelay: iconTileGrid.pressDelay
6661 property alias highlightIndex: iconTileGrid.highlightIndex
6762 readonly property alias currentItem: iconTileGrid.currentItem
63+ readonly property alias filtered: d.filter
64+
65+ QtObject {
66+ id: d
67+ // We do have filter and collapsed properties because we need to decouple
68+ // the real filtering with the animation since the closing animation
69+ // i.e. setFilter(false. true) we still need to not be filtering until
70+ // the animation finishes otherwise we hide the items when the animation
71+ // is still running
72+ property bool filter: true
73+ property bool collapsed: true
74+ }
6875
69− height: !filterAnimation.running ? childrenRect.height : height
76+ height: d.collapsed ? root.collapsedHeight : root.uncollapsedHeight
7077 clip: filterAnimation.running
7178
72− NumberAnimation {
73− property bool filterEndValue
74− id: filterAnimation
75− target: root
76− property: "height"
77− to: filterEndValue ? root.collapsedHeight : root.uncollapsedHeight
78− // Duration and easing here match the ListViewWithPageHeader::m_contentYAnimation
79− // otherwise since both animations can run at the same time you'll get
80− // some visual weirdness.
81− duration: 200
82− easing.type: Easing.InOutQuad
83− onStopped: {
84− root.filter = filterEndValue;
79+ Behavior on height {
80+ id: heightBehaviour
81+ enabled: false
82+ NumberAnimation {
83+ id: filterAnimation
84+ // Duration and easing here match the ListViewWithPageHeader::m_contentYAnimation
85+ // otherwise since both animations can run at the same time you'll get
86+ // some visual weirdness.
87+ duration: 200
88+ easing.type: Easing.InOutQuad
89+ onRunningChanged: {
90+ if (!running) {
91+ d.filter = d.collapsed;
92+ }
93+ heightBehaviour.enabled = false;
94+ }
8595 }
8696 }
8797
88− function startFilterAnimation(filter) {
89− filterAnimation.filterEndValue = filter
90− filterAnimation.start();
91− }
98+ function setFilter(filter, animate) {
99+ heightBehaviour.enabled = animate;
100+ d.collapsed = filter;
101+ if (!animate || !filter) {
102+ d.filter = filter;
103+ }
104+ }
92105
93106 ResponsiveGridView {
94107 id: iconTileGrid
@@ -105,7 +118,7 @@ Item {
105118
106119 model: LimitProxyModel {
107120 model: root.model
108− limit: (filter && !filterAnimation.running) ? rowsWhenCollapsed * iconTileGrid.columns : -1
121+ limit: d.filter ? rowsWhenCollapsed * iconTileGrid.columns : -1
109122 }
110123 }
111124}
qml/Dash/CardFilterGrid.qml+3−8
@@ -28,9 +28,10 @@ DashRenderer {
2828 verticalSpacing: units.gu(1)
2929 currentItem: filterGrid.currentItem
3030 height: filterGrid.height
31+ filtered: filterGrid.filtered
3132
32− function startFilterAnimation(filter) {
33− filterGrid.startFilterAnimation(filter)
33+ function setFilter(filter, animate) {
34+ filterGrid.setFilter(filter, animate)
3435 }
3536
3637 FilterGrid {
@@ -41,7 +42,6 @@ DashRenderer {
4142 delegateHeight: cardTool.cardHeight
4243 verticalSpacing: genericFilterGrid.verticalSpacing
4344 model: genericFilterGrid.model
44− filter: genericFilterGrid.filter
4545 collapsedRowCount: Math.min(2, cardTool && cardTool.template && cardTool.template["collapsed-rows"] || 2)
4646 delegateCreationBegin: genericFilterGrid.delegateCreationBegin
4747 delegateCreationEnd: genericFilterGrid.delegateCreationEnd
@@ -66,10 +66,5 @@ DashRenderer {
6666 onPressAndHold: genericFilterGrid.pressAndHold(index, card.y)
6767 }
6868 }
69−
70− onFilterChanged: {
71− genericFilterGrid.filter = filter
72− filter = Qt.binding(function() { return genericFilterGrid.filter })
73− }
7469 }
7570}
qml/Dash/DashRenderer.qml+3−3
@@ -20,8 +20,8 @@ Item {
2020 // Can the item be expanded?
2121 property bool expandable: false
2222
23− // In case it can be expanded, should we filter it
24− property bool filter: true
23+ // In case it can be expanded, is it filtered
24+ property bool filtered: true
2525
2626 property int collapsedHeight: height
2727
@@ -58,6 +58,6 @@ Item {
5858 /// @param itemY is y of the held delegate
5959 signal pressAndHold(int index, real itemY)
6060
61− function startFilterAnimation(filter) {
61+ function setFilter(filter, animate) {
6262 }
6363}
qml/Dash/GenericScopeView.qml+4−9
@@ -122,7 +122,7 @@ FocusScope {
122122 showDivider: false
123123
124124 readonly property bool expandable: rendererLoader.item ? rendererLoader.item.expandable : false
125− readonly property bool filtered: rendererLoader.item ? rendererLoader.item.filter : true
125+ readonly property bool filtered: rendererLoader.item ? rendererLoader.item.filtered : true
126126 readonly property string category: categoryId
127127 readonly property var item: rendererLoader.item
128128
@@ -168,9 +168,7 @@ FocusScope {
168168 item.objectName = Qt.binding(function() { return categoryId })
169169 if (item.expandable) {
170170 var shouldFilter = categoryId != categoryView.expandedCategoryId;
171− if (shouldFilter != item.filter) {
172− item.filter = shouldFilter;
173− }
171+ item.setFilter(shouldFilter, false /*animate*/);
174172 }
175173 updateDelegateCreationRange();
176174 item.cardTool = cardTool;
@@ -219,11 +217,8 @@ FocusScope {
219217 var shrinkingVisible = shouldFilter && y + item.collapsedHeight < categoryView.height;
220218 var growingVisible = !shouldFilter && y + height < categoryView.height;
221219 if (!previewListView.open || !shouldFilter) {
222− if (shrinkingVisible || growingVisible) {
223− item.startFilterAnimation(shouldFilter)
224− } else {
225− item.filter = shouldFilter;
226− }
220+ var animate = shrinkingVisible || growingVisible;
221+ item.setFilter(shouldFilter, animate)
227222 if (!shouldFilter && !previewListView.open) {
228223 categoryView.maximizeVisibleArea(index, item.uncollapsedHeight);
229224 }
tests/autopilot/unity8/shell/tests/test_emulators.py+1−1
@@ -196,7 +196,7 @@ class DashAppsEmulatorTestCase(DashBaseTestCase):
196196 category)
197197 grid = category_element.select_single('CardFilterGrid')
198198 filtergrid = grid.select_single('FilterGrid')
199− if (grid.filter):
199+ if (grid.filtered):
200200 return filtergrid.collapsedRowCount * filtergrid.columns
201201 else:
202202 return filtergrid.uncollapsedRowCount * filtergrid.columns
tests/qmltests/Components/tst_FilterGrid.qml+1−1
@@ -50,6 +50,7 @@ Rectangle {
5050 CheckBox {
5151 id: filterCheckBox
5252 checked: true
53+ onCheckedChanged: filterGrid.setFilter(checked, false /*animate*/)
5354 }
5455 }
5556 }
@@ -99,7 +100,6 @@ Rectangle {
99100 maximumNumberOfColumns: 3
100101 collapsedRowCount:
101102 collapsedRowCountSelector.values[collapsedRowCountSelector.selectedIndex]
102− filter: filterCheckBox.checked
103103 minimumHorizontalSpacing: units.gu(1)
104104 delegateWidth: units.gu(6)
105105 delegateHeight: units.gu(6)
tests/qmltests/Dash/tst_GenericScopeView.qml+3−3
@@ -140,7 +140,7 @@ Item {
140140 mouseClick(header, header.width / 2, header.height / 2);
141141 tryCompareFunction(function() { middleHeight = category.height; return category.height > initialHeight; }, true);
142142 tryCompare(category, "filtered", false);
143− verify(category.height > middleHeight);
143+ tryCompareFunction(function() { return category.height > middleHeight; }, true);
144144
145145 mouseClick(header, header.width / 2, header.height / 2);
146146 verify(category.expandable);
@@ -165,7 +165,7 @@ Item {
165165
166166 mouseClick(header2, header2.width / 2, header2.height / 2);
167167 tryCompare(category2, "filtered", false);
168− tryCompare(category2FilterGrid, "filter", false);
168+ tryCompare(category2FilterGrid, "filtered", false);
169169
170170 categoryListView.positionAtBeginning();
171171
@@ -182,7 +182,7 @@ Item {
182182 mouseClick(header0, header0.width / 2, header0.height / 2);
183183 tryCompare(category0, "filtered", false);
184184 tryCompare(category2, "filtered", true);
185− tryCompare(category2FilterGrid, "filter", true);
185+ tryCompare(category2FilterGrid, "filtered", true);
186186 mouseClick(header0, header0.width / 2, header0.height / 2);
187187 tryCompare(category0, "filtered", true);
188188 tryCompare(category2, "filtered", true);