on xenial help sign in
Expandable Filter Widget

Approved by: Andrea Cimitan, Pawel Stolowski

commitf61e91c94be411a103daf9d69389fac2957fd87d authorAlbert Astals Cid <albert.astals@canonical.com> dateWed 4 May 2016, 18:09 (10 years ago) parent9df9d620c028e3
13 files changed+334−17
debian/control+2−2 qml/Dash/Filters/FilterExpandableWidget.qml+96 qml/Dash/Filters/FilterWidget.qml+3 qml/Dash/Filters/FilterWidgetFactory.qml+2−1 tests/mocks/Unity/CMakeLists.txt+3−1 tests/mocks/Unity/fake_expandablefilterwidget.cpp+53 tests/mocks/Unity/fake_expandablefilterwidget.h+48 tests/mocks/Unity/fake_filters.cpp+19−8 tests/mocks/Unity/fake_filters.h+4−4 tests/mocks/Unity/fake_scope.cpp+2 tests/qmltests/CMakeLists.txt+1 tests/qmltests/Dash/Filters/tst_FilterExpandableWidget.qml+99 tests/qmltests/Dash/Filters/tst_FilterWidgetFactory.qml+2−1
debian/control+2−2
@@ -30,7 +30,7 @@ Build-Depends: cmake,
3030 libqt5xmlpatterns5-dev,
3131 libsystemsettings-dev,
3232 libudev-dev,
33− libunity-api-dev (>= 7.110),
33+ libunity-api-dev (>= 7.111),
3434 libusermetricsoutput1-dev,
3535# Need those X11 libs touch emulation from mouse events in manual QML tests on a X11 desktop
3636 libx11-dev[!armhf],
@@ -136,7 +136,7 @@ Depends: qml-module-qtquick-layouts,
136136 unity-application-impl-15,
137137 unity-notifications-impl-3,
138138 unity-plugin-scopes | unity-scopes-impl,
139− unity-scopes-impl-11,
139+ unity-scopes-impl-12,
140140 unity8-fake-env | unity-application-impl,
141141 ${misc:Depends},
142142Breaks: unity8 (<< 7.86),
qml/Dash/Filters/FilterExpandableWidget.qmlnew file+96
@@ -0,0 +1,96 @@
1+/*
2+ * Copyright (C) 2016 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.4
18+import Ubuntu.Components 1.3
19+import Ubuntu.Components.ListItems 1.3 as ListItems
20+
21+/*! Expandable Filter Widget. */
22+
23+FilterWidget {
24+ id: root
25+
26+ showsTitleOnItsOwn: true
27+
28+ implicitHeight: expandingItem.height
29+
30+ ListItems.Expandable {
31+ id: expandingItem
32+ objectName: "expandingItem"
33+
34+ expandedHeight: collapsedHeight + column.height
35+ anchors.left: parent.left
36+ anchors.right: parent.right
37+ showDivider: false
38+
39+ onClicked: {
40+ expanded = !expanded;
41+ forceActiveFocus();
42+ }
43+ __contentsMargins: 0
44+
45+ Item {
46+ id: titleHolder
47+ anchors.top: parent.top
48+ height: expandingItem.collapsedHeight
49+ anchors.left: parent.left
50+ anchors.right: parent.right
51+
52+ Label {
53+ anchors.left: parent.left
54+ anchors.leftMargin: units.gu(2)
55+ anchors.right: dropDown.left
56+ anchors.verticalCenter: parent.verticalCenter
57+ text: widgetData.title || ""
58+ }
59+
60+ Image {
61+ id: dropDown
62+ height: units.gu(3)
63+ fillMode: Image.PreserveAspectFit
64+ anchors.right: parent.right
65+ anchors.rightMargin: units.gu(2)
66+ anchors.verticalCenter: parent.verticalCenter
67+ source: expandingItem.expanded ? "image://theme/up" : "image://theme/down"
68+ }
69+ }
70+
71+ Column {
72+ id: column
73+ anchors.left: parent.left
74+ anchors.right: parent.right
75+ anchors.top: titleHolder.bottom
76+
77+ Repeater {
78+ id: repeater
79+ model: widgetData.filters
80+
81+ delegate: FilterWidgetFactory {
82+ width: parent.width
83+
84+ widgetId: id
85+ widgetType: type
86+ widgetData: filter
87+
88+ ListItems.ThinDivider {
89+ anchors.bottom: parent.bottom
90+ visible: index !== repeater.count - 1
91+ }
92+ }
93+ }
94+ }
95+ }
96+}
qml/Dash/Filters/FilterWidget.qml+3
@@ -25,5 +25,8 @@ Item {
2525 //! Variable used to contain widget's data
2626 property var widgetData: null
2727
28+ //! Does the widget show the title inside?
29+ property bool showsTitleOnItsOwn: false
30+
2831 objectName: widgetId
2932}
qml/Dash/Filters/FilterWidgetFactory.qml+2−1
@@ -35,7 +35,7 @@ Item {
3535
3636 Label {
3737 id: title
38− text: widgetData ? widgetData.title : ""
38+ text: widgetData && !(loader.item && loader.item.showsTitleOnItsOwn) ? widgetData.title : ""
3939 height: text != "" ? implicitHeight : 0
4040
4141 anchors {
@@ -68,6 +68,7 @@ Item {
6868 case Filters.OptionSelectorFilter: return "FilterOptionSelector.qml";
6969 case Filters.RangeInputFilter: return "FilterRangeInput.qml";
7070 case Filters.ValueSliderFilter: return "FilterValueSlider.qml";
71+ case Filters.ExpandableFilterWidget: return "FilterExpandableWidget.qml";
7172 default: return "";
7273 }
7374 }
tests/mocks/Unity/CMakeLists.txt+3−1
@@ -8,7 +8,7 @@ add_subdirectory(DashCommunicator)
88add_subdirectory(Screens)
99
1010pkg_search_module(GOBJECT gobject-2.0 REQUIRED)
11−pkg_check_modules(SCOPES_API REQUIRED unity-shell-scopes=11)
11+pkg_check_modules(SCOPES_API REQUIRED unity-shell-scopes=12)
1212
1313include_directories(
1414 ${CMAKE_CURRENT_BINARY_DIR}
@@ -34,6 +34,7 @@ set(UnityQML_SOURCES
3434 fake_optionselectoroptions.cpp
3535 fake_rangeinputfilter.cpp
3636 fake_valuesliderfilter.cpp
37+ fake_expandablefilterwidget.cpp
3738 fake_valueslidervalues.cpp
3839 fake_unity_plugin.cpp
3940 ${SCOPES_API_INCLUDEDIR}/unity/shell/scopes/CategoriesInterface.h
@@ -51,6 +52,7 @@ set(UnityQML_SOURCES
5152 ${SCOPES_API_INCLUDEDIR}/unity/shell/scopes/SettingsModelInterface.h
5253 ${SCOPES_API_INCLUDEDIR}/unity/shell/scopes/ValueSliderFilterInterface.h
5354 ${SCOPES_API_INCLUDEDIR}/unity/shell/scopes/ValueSliderValuesInterface.h
55+ ${SCOPES_API_INCLUDEDIR}/unity/shell/scopes/ExpandableFilterWidgetInterface.h
5456)
5557
5658# Workaround for gcc failure LP: #1417664
tests/mocks/Unity/fake_expandablefilterwidget.cppnew file+53
@@ -0,0 +1,53 @@
1+/*
2+ * Copyright (C) 2016 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+#include "fake_expandablefilterwidget.h"
18+
19+#include "fake_filters.h"
20+
21+FakeExpandbleFilterWidget::FakeExpandbleFilterWidget(const QString &id, const QString &tag, const QString &title, QObject* parent)
22+ : unity::shell::scopes::ExpandableFilterWidgetInterface(parent)
23+ , m_filterId(id)
24+ , m_filterTag(tag)
25+ , m_title(title)
26+{
27+ m_filters = new Filters(this);
28+}
29+
30+QString FakeExpandbleFilterWidget::filterId() const
31+{
32+ return m_filterId;
33+}
34+
35+QString FakeExpandbleFilterWidget::filterTag() const
36+{
37+ return m_filterTag;
38+}
39+
40+QString FakeExpandbleFilterWidget::title() const
41+{
42+ return m_title;
43+}
44+
45+unity::shell::scopes::FiltersInterface* FakeExpandbleFilterWidget::filters() const
46+{
47+ return m_filters;
48+}
49+
50+void FakeExpandbleFilterWidget::addFilter(unity::shell::scopes::FilterBaseInterface* f)
51+{
52+ m_filters->addFilter(f);
53+}
tests/mocks/Unity/fake_expandablefilterwidget.hnew file+48
@@ -0,0 +1,48 @@
1+/*
2+ * Copyright (C) 2016 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+#ifndef FAKE_EXPANDABLEFILTERWIDGET_H
18+#define FAKE_EXPANDABLEFILTERWIDGET_H
19+
20+#include <unity/shell/scopes/ExpandableFilterWidgetInterface.h>
21+
22+class Filters;
23+
24+class FakeExpandbleFilterWidget : public unity::shell::scopes::ExpandableFilterWidgetInterface
25+{
26+ Q_OBJECT
27+
28+public:
29+ FakeExpandbleFilterWidget(const QString &id, const QString &tag, const QString &title, QObject* parent);
30+
31+ QString filterId() const override;
32+ QString filterTag() const override;
33+ QString title() const override;
34+
35+ unity::shell::scopes::FiltersInterface* filters() const override;
36+
37+ // mock API
38+ void addFilter(unity::shell::scopes::FilterBaseInterface* f);
39+
40+private:
41+ QString m_filterId;
42+ QString m_filterTag;
43+ QString m_title;
44+
45+ Filters *m_filters;
46+};
47+
48+#endif
tests/mocks/Unity/fake_filters.cpp+19−8
@@ -19,10 +19,14 @@
1919#include "fake_optionselectorfilter.h"
2020#include "fake_rangeinputfilter.h"
2121#include "fake_valuesliderfilter.h"
22−#include "fake_scope.h"
22+#include "fake_expandablefilterwidget.h"
2323
24−Filters::Filters(Scope* parent)
24+Filters::Filters(QObject* parent)
2525 : unity::shell::scopes::FiltersInterface(parent)
26+{
27+}
28+
29+void Filters::addFakeFilters()
2630{
2731 addFilter(new FakeOptionSelectorFilter("OSF1", "Tag1", "Which Cake you like More", false, QStringList() << "cheese" << "carrot" << "chocolate", this));
2832
@@ -41,6 +45,11 @@ Filters::Filters(Scope* parent)
4145 addFilter(vsf);
4246
4347 addFilter(new FakeOptionSelectorFilter("OSF2", "Tag2", "Which Countries have you been to?", true, QStringList() << "Germany" << "UK" << "New Zealand", this));
48+
49+ auto expandableFilter = new FakeExpandbleFilterWidget("EFW", "Tag5", "Advanced Settings", this);
50+ expandableFilter->addFilter(new FakeValueSliderFilter("VS2", "Tag6", 15, 10, 150, labels, this));
51+
52+ addFilter(expandableFilter);
4453}
4554
4655void Filters::addFilter(unity::shell::scopes::FilterBaseInterface *f)
@@ -58,9 +67,10 @@ void Filters::addFilter(unity::shell::scopes::FilterBaseInterface *f)
5867 }
5968 break;
6069
61− case FiltersInterface::ValueSliderFilter: {
62− // Not counting value slider as active in the mock
63− }
70+ case FiltersInterface::ExpandableFilterWidget:
71+ // Can't be active
72+ case FiltersInterface::ValueSliderFilter:
73+ // Not counting value as active in the mock
6474
6575 case Invalid:
6676 break;
@@ -113,9 +123,10 @@ int Filters::activeFiltersCount() const
113123 }
114124 break;
115125
116− case FiltersInterface::ValueSliderFilter: {
117− // Not counting value slider as active in the mock
118− }
126+ case FiltersInterface::ExpandableFilterWidget:
127+ // Can't be active
128+ case FiltersInterface::ValueSliderFilter:
129+ // Not counting value as active in the mock
119130
120131 case Invalid:
121132 break;
tests/mocks/Unity/fake_filters.h+4−4
@@ -20,25 +20,25 @@
2020#include <unity/shell/scopes/FiltersInterface.h>
2121#include <unity/shell/scopes/FilterBaseInterface.h>
2222
23−class Scope;
24−
2523class Filters : public unity::shell::scopes::FiltersInterface
2624{
2725 Q_OBJECT
2826
2927public:
30− Filters(Scope* parent);
28+ Filters(QObject* parent);
3129
3230 int rowCount(const QModelIndex &parent) const override;
3331 QVariant data(const QModelIndex &index, int role) const override;
3432
33+ // Mock API
3534 int activeFiltersCount() const;
35+ void addFakeFilters();
36+ void addFilter(unity::shell::scopes::FilterBaseInterface* f);
3637
3738Q_SIGNALS:
3839 void activeFiltersCountChanged();
3940
4041private:
41− void addFilter(unity::shell::scopes::FilterBaseInterface* f);
4242
4343 QVector<unity::shell::scopes::FilterBaseInterface*> m_filters;
4444};
tests/mocks/Unity/fake_scope.cpp+2
@@ -49,6 +49,8 @@ Scope::Scope(QString const& id, QString const& name, bool favorite, Scopes* pare
4949 , m_filters(new Filters(this))
5050 , m_returnNullPreview(returnNullPreview)
5151{
52+ m_filters->addFakeFilters();
53+
5254 m_primaryNavigationFilter = new FakeOptionSelectorFilter("OSF3", "PFTag", "Which food you like More", false, QStringList() << "meat" << "vegetables", this);
5355 connect(m_filters, &Filters::activeFiltersCountChanged, this, &Scope::activeFiltersCountChanged);
5456}
tests/qmltests/CMakeLists.txt+1
@@ -57,6 +57,7 @@ add_unity8_qmltest(Dash/Filters FilterOptionSelector)
5757add_unity8_qmltest(Dash/Filters FilterRangeInput)
5858add_unity8_qmltest(Dash/Filters FilterValueSlider)
5959add_unity8_qmltest(Dash/Filters FilterWidgetFactory)
60+add_unity8_qmltest(Dash/Filters FilterExpandableWidget)
6061add_unity8_qmltest(Dash/ScopeSettings ScopeSettingBoolean)
6162add_unity8_qmltest(Dash/ScopeSettings ScopeSettingList)
6263add_unity8_qmltest(Dash/ScopeSettings ScopeSettingNumber)
tests/qmltests/Dash/Filters/tst_FilterExpandableWidget.qmlnew file+99
@@ -0,0 +1,99 @@
1+/*
2+ * Copyright 2016 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.4
18+import QtTest 1.0
19+import Ubuntu.Components 1.3
20+import "../../../../qml/Dash/Filters"
21+import Unity.Test 0.1 as UT
22+import Unity 0.2
23+
24+Rectangle {
25+ id: root
26+ width: units.gu(60)
27+ height: units.gu(80)
28+ color: theme.palette.selected.background
29+
30+ QtObject {
31+ id: widgetData1
32+
33+ property string title: "Expand me!"
34+ property ListModel filters: ListModel {
35+ dynamicRoles: true
36+ }
37+ }
38+
39+ QtObject {
40+ id: sliderObject
41+
42+ property string title
43+ property int value: 30
44+ property int minValue: 10
45+ property int maxValue: 150
46+
47+ property ListModel values: ListModel {
48+ ListElement {
49+ value: 10
50+ label: "10"
51+ }
52+ ListElement {
53+ value: 30
54+ label: "30"
55+ }
56+ ListElement {
57+ value: 100
58+ label: "100"
59+ }
60+ ListElement {
61+ value: 150
62+ label: "150"
63+ }
64+ }
65+ }
66+
67+ Component.onCompleted: {
68+ widgetData1.filters.append({"type": Filters.ValueSliderFilter, "filter": sliderObject, id: "trololo"});
69+ }
70+
71+ FilterWidgetFactory {
72+ id: factory
73+ widgetId: "testExpandableWidget"
74+ widgetType: Filters.ExpandableFilterWidget
75+ widgetData: widgetData1
76+ anchors {
77+ left: parent.left
78+ right: parent.right
79+ }
80+ height: implicitHeight
81+ clip: true
82+ }
83+
84+ UT.UnityTestCase {
85+ name: "FilterExpandableWidget"
86+ when: windowShown
87+
88+ function test_expandedChanges() {
89+ var expandingItem = findChild(factory, "expandingItem");
90+ verify(!expandingItem.expanded)
91+ compare(expandingItem.height, expandingItem.collapsedHeight)
92+ mouseClick(expandingItem);
93+ verify(expandingItem.expanded)
94+ tryCompare(expandingItem, "height", expandingItem.expandedHeight)
95+ verify(expandingItem.collapsedHeight < expandingItem.expandedHeight / 2);
96+ }
97+
98+ }
99+}
tests/qmltests/Dash/Filters/tst_FilterWidgetFactory.qml+2−1
@@ -43,7 +43,8 @@ Rectangle {
4343 return [
4444 { tag: "OptionSelector", type: Filters.OptionSelectorFilter, source: "FilterOptionSelector.qml" },
4545 { tag: "RangeInputFilter", type: Filters.RangeInputFilter, source: "FilterRangeInput.qml" },
46− { tag: "ValueSliderFilter", type: Filters.ValueSliderFilter, source: "FilterValueSlider.qml" }
46+ { tag: "ValueSliderFilter", type: Filters.ValueSliderFilter, source: "FilterValueSlider.qml" },
47+ { tag: "ExpandableFilter", type: Filters.ExpandableFilterWidget, source: "FilterExpandableWidget.qml" }
4748 ];
4849 }
4950