on xenial help sign in
some more fixes
cc1fa6aMichael Zanetti
plugins/Utils/appdrawerproxymodel.cpp+16−1
@@ -23,7 +23,7 @@ void AppDrawerProxyModel::setSource(QAbstractItemModel *source)
23 if (m_source != source) {
23 if (m_source != source) {
24 m_source = source;
24 m_source = source;
25 setSourceModel(m_source);
25 setSourceModel(m_source);
26− sort(0);
26+ setSortRole(m_sortBy == SortByAToZ ? AppDrawerModelInterface::RoleName : AppDrawerModelInterface::RoleUsage);
27 connect(m_source, &QAbstractItemModel::rowsRemoved, this, &AppDrawerProxyModel::invalidateFilter);
27 connect(m_source, &QAbstractItemModel::rowsRemoved, this, &AppDrawerProxyModel::invalidateFilter);
28 connect(m_source, &QAbstractItemModel::rowsInserted, this, &AppDrawerProxyModel::invalidateFilter);
28 connect(m_source, &QAbstractItemModel::rowsInserted, this, &AppDrawerProxyModel::invalidateFilter);
29 Q_EMIT sourceChanged();
29 Q_EMIT sourceChanged();
@@ -72,6 +72,21 @@ void AppDrawerProxyModel::setFilterString(const QString &filterString)
72 }
72 }
73}
73}
74
74
75+AppDrawerProxyModel::SortBy AppDrawerProxyModel::sortBy() const
76+{
77+ return m_sortBy;
78+}
79+
80+void AppDrawerProxyModel::setSortBy(AppDrawerProxyModel::SortBy sortBy)
81+{
82+ if (m_sortBy != sortBy) {
83+ m_sortBy = sortBy;
84+ Q_EMIT sortByChanged();
85+ setSortRole(m_sortBy == SortByAToZ ? AppDrawerModelInterface::RoleName : AppDrawerModelInterface::RoleUsage);
86+ sort(0);
87+ }
88+}
89+
75int AppDrawerProxyModel::count() const
90int AppDrawerProxyModel::count() const
76{
91{
77 return rowCount();
92 return rowCount();
plugins/Utils/appdrawerproxymodel.h+11
@@ -8,10 +8,12 @@ class AppDrawerProxyModel: public QSortFilterProxyModel
8{
8{
9 Q_OBJECT
9 Q_OBJECT
10 Q_ENUMS(GroupBy)
10 Q_ENUMS(GroupBy)
11+ Q_ENUMS(SortBy)
11 Q_PROPERTY(QAbstractItemModel* source READ source WRITE setSource NOTIFY sourceChanged)
12 Q_PROPERTY(QAbstractItemModel* source READ source WRITE setSource NOTIFY sourceChanged)
12 Q_PROPERTY(GroupBy group READ group WRITE setGroup NOTIFY groupChanged)
13 Q_PROPERTY(GroupBy group READ group WRITE setGroup NOTIFY groupChanged)
13 Q_PROPERTY(QString filterLetter READ filterLetter WRITE setFilterLetter NOTIFY filterLetterChanged)
14 Q_PROPERTY(QString filterLetter READ filterLetter WRITE setFilterLetter NOTIFY filterLetterChanged)
14 Q_PROPERTY(QString filterString READ filterString WRITE setFilterString NOTIFY filterStringChanged)
15 Q_PROPERTY(QString filterString READ filterString WRITE setFilterString NOTIFY filterStringChanged)
16+ Q_PROPERTY(SortBy sortBy READ sortBy WRITE setSortBy NOTIFY sortByChanged)
15 Q_PROPERTY(int count READ count NOTIFY countChanged)
17 Q_PROPERTY(int count READ count NOTIFY countChanged)
16
18
17public:
19public:
@@ -20,6 +22,10 @@ public:
20 GroupByAll,
22 GroupByAll,
21 GroupByAToZ
23 GroupByAToZ
22 };
24 };
25+ enum SortBy {
26+ SortByAToZ,
27+ SortByUsage
28+ };
23
29
24 AppDrawerProxyModel(QObject* parent = nullptr);
30 AppDrawerProxyModel(QObject* parent = nullptr);
25
31
@@ -35,6 +41,9 @@ public:
35 QString filterString() const;
41 QString filterString() const;
36 void setFilterString(const QString &filterString);
42 void setFilterString(const QString &filterString);
37
43
44+ SortBy sortBy() const;
45+ void setSortBy(SortBy sortBy);
46+
38 int count() const;
47 int count() const;
39
48
40 QVariant data(const QModelIndex &index, int role) const override;
49 QVariant data(const QModelIndex &index, int role) const override;
@@ -48,6 +57,7 @@ Q_SIGNALS:
48 void groupChanged();
57 void groupChanged();
49 void filterLetterChanged();
58 void filterLetterChanged();
50 void filterStringChanged();
59 void filterStringChanged();
60+ void sortByChanged();
51 void countChanged();
61 void countChanged();
52
62
53private:
63private:
@@ -55,4 +65,5 @@ private:
55 GroupBy m_group = GroupByNone;
65 GroupBy m_group = GroupByNone;
56 QString m_filterLetter;
66 QString m_filterLetter;
57 QString m_filterString;
67 QString m_filterString;
68+ SortBy m_sortBy = SortByAToZ;
58};
69};
qml/Launcher/Drawer.qml+41−3
@@ -12,6 +12,9 @@ FocusScope {
12
12
13 signal applicationSelected(string appId)
13 signal applicationSelected(string appId)
14
14
15+ property bool draggingHorizontally: false
16+ property int dragDistance: 0
17+
15 Rectangle {
18 Rectangle {
16 anchors.fill: parent
19 anchors.fill: parent
17 color: "#BF000000"
20 color: "#BF000000"
@@ -50,10 +53,10 @@ FocusScope {
50 width: parent.width
53 width: parent.width
51 actions: [
54 actions: [
52 Action {
55 Action {
53− text: i18n.tr("A-Z")
56+ text: i18n.ctr("Apps sorted alphabetically", "A-Z")
54 },
57 },
55 Action {
58 Action {
56− text: i18n.tr("Most used")
59+ text: i18n.ctr("Most used apps", "Most used")
57 }
60 }
58 ]
61 ]
59
62
@@ -72,6 +75,39 @@ FocusScope {
72 sourceComponent: sections.selectedIndex == 0 ? aToZComponent : mostUsedComponent
75 sourceComponent: sections.selectedIndex == 0 ? aToZComponent : mostUsedComponent
73 }
76 }
74
77
78+ MouseArea {
79+ parent: listLoader.item ? listLoader.item : null
80+ anchors.fill: parent
81+ propagateComposedEvents: true
82+ property int oldX: 0
83+ onPressed: {
84+ oldX = mouseX;
85+ }
86+ onMouseXChanged: {
87+ var diff = oldX - mouseX;
88+ root.draggingHorizontally |= diff > units.gu(2);
89+ if (!root.draggingHorizontally) {
90+ return;
91+ }
92+ propagateComposedEvents = false;
93+ parent.interactive = false;
94+ root.dragDistance += diff;
95+ oldX = mouseX
96+ }
97+ onReleased: {
98+ if (root.draggingHorizontally) {
99+ root.draggingHorizontally = false;
100+ parent.interactive = true;
101+ }
102+ reactivateTimer.start();
103+ }
104+ Timer {
105+ id: reactivateTimer
106+ interval: 0
107+ onTriggered: parent.propagateComposedEvents = true;
108+ }
109+ }
110+
75 Component {
111 Component {
76 id: mostUsedComponent
112 id: mostUsedComponent
77 ListView {
113 ListView {
@@ -89,6 +125,7 @@ FocusScope {
89 model: AppDrawerProxyModel {
125 model: AppDrawerProxyModel {
90 source: sortProxyModel
126 source: sortProxyModel
91 group: AppDrawerProxyModel.GroupByAll
127 group: AppDrawerProxyModel.GroupByAll
128+ sortBy: AppDrawerProxyModel.SortByUsage
92 }
129 }
93
130
94 delegate: UbuntuShape {
131 delegate: UbuntuShape {
@@ -98,6 +135,7 @@ FocusScope {
98 // NOTE: Cannot use gridView.rows here as it would evaluate to 0 at first and only update later,
135 // NOTE: Cannot use gridView.rows here as it would evaluate to 0 at first and only update later,
99 // which messes up the ListView.
136 // which messes up the ListView.
100 height: (Math.ceil(mostUsedGridView.model.count / mostUsedGridView.columns) * mostUsedGridView.delegateHeight) + units.gu(2)
137 height: (Math.ceil(mostUsedGridView.model.count / mostUsedGridView.columns) * mostUsedGridView.delegateHeight) + units.gu(2)
138+ enabled: parent.interactive
101
139
102 DrawerGridView {
140 DrawerGridView {
103 id: mostUsedGridView
141 id: mostUsedGridView
@@ -108,7 +146,6 @@ FocusScope {
108
146
109 model: sortProxyModel
147 model: sortProxyModel
110
148
111−
112 delegateWidth: units.gu(8)
149 delegateWidth: units.gu(8)
113 delegateHeight: units.gu(10)
150 delegateHeight: units.gu(10)
114 delegate: drawerDelegateComponent
151 delegate: drawerDelegateComponent
@@ -140,6 +177,7 @@ FocusScope {
140 width: parent.width
177 width: parent.width
141 color: "#20ffffff"
178 color: "#20ffffff"
142 aspect: UbuntuShape.Flat
179 aspect: UbuntuShape.Flat
180+ enabled: parent.interactive
143
181
144 // NOTE: Cannot use gridView.rows here as it would evaluate to 0 at first and only update later,
182 // NOTE: Cannot use gridView.rows here as it would evaluate to 0 at first and only update later,
145 // which messes up the ListView.
183 // which messes up the ListView.
qml/Launcher/Launcher.qml+17−27
@@ -295,16 +295,8 @@ FocusScope {
295 visible: enabled
295 visible: enabled
296 onPressed: {
296 onPressed: {
297 mouse.accepted = false;
297 mouse.accepted = false;
298− if (root.lockedVisible) {
299− if (root.state == "drawer") {
300− switchToNextState("visible")
301− }
302− } else {
303− if (root.state == "visible" || root.state == "drawer") {
304− panel.highlightIndex = -2;
298+ panel.highlightIndex = -2;
305− root.hide();
299+ root.hide();
306− }
307− }
308 }
300 }
309 }
301 }
310
302
@@ -360,22 +352,6 @@ FocusScope {
360 cached: drawer.moving
352 cached: drawer.moving
361 }
353 }
362
354
363− MouseArea {
364− anchors.fill: drawer
365− property int startX: 0
366− preventStealing: true
367−
368− onPressed: {
369− print("**** mouse pressed")
370− startX = mouseX
371− }
372−
373− onMouseXChanged: {
374− drawer.x += mouseX - startX
375− startX = mouseX
376− }
377− }
378−
379 Drawer {
355 Drawer {
380 id: drawer
356 id: drawer
381 anchors {
357 anchors {
@@ -394,8 +370,22 @@ FocusScope {
394 root.focus = false;
370 root.focus = false;
395 }
371 }
396
372
373+ onDragDistanceChanged: {
374+ x -= dragDistance;
375+ }
376+ onDraggingHorizontallyChanged: {
377+ if (!draggingHorizontally) {
378+ if (drawer.x < -units.gu(10)) {
379+ root.hide();
380+ } else {
381+ root.openDrawer();
382+ }
383+ }
384+ }
385+
386+
397 Behavior on x {
387 Behavior on x {
398− enabled: !dragArea.dragging && !launcherDragArea.drag.active// && panel.animate;
388+ enabled: !dragArea.dragging && !launcherDragArea.drag.active && !drawer.draggingHorizontally// && panel.animate;
399 NumberAnimation {
389 NumberAnimation {
400 duration: 300
390 duration: 300
401 easing.type: Easing.OutCubic
391 easing.type: Easing.OutCubic
qml/Launcher/MoreAppsHeader.qml+6−1
@@ -1,9 +1,14 @@
1import QtQuick 2.4
1import QtQuick 2.4
2import Ubuntu.Components 1.3
2import Ubuntu.Components 1.3
3
3
4−Item {
4+AbstractButton {
5 id: root
5 id: root
6
6
7+ onClicked: {
8+ // TODO: Make this point to the snappy store as soon as we stop landing to vivid
9+ Qt.openUrlExternally("scope://com.canonical.scopes.clickstore")
10+ }
11+
7 UbuntuShape {
12 UbuntuShape {
8 width: parent.width
13 width: parent.width
9 height: parent.height - units.gu(1)
14 height: parent.height - units.gu(1)
tests/mocks/Unity/Launcher/MockAppDrawerModel.cpp+5
@@ -1,6 +1,7 @@
1#include "MockAppDrawerModel.h"
1#include "MockAppDrawerModel.h"
2
2
3#include <QDebug>
3#include <QDebug>
4+#include <QDateTime>
4
5
5MockAppDrawerModel::MockAppDrawerModel(QObject *parent):
6MockAppDrawerModel::MockAppDrawerModel(QObject *parent):
6 AppDrawerModelInterface(parent)
7 AppDrawerModelInterface(parent)
@@ -32,6 +33,8 @@ MockAppDrawerModel::MockAppDrawerModel(QObject *parent):
32 item = new MockLauncherItem("libreoffice", "/usr/share/applications/libreoffice.desktop","Libre Office", "libreoffice", this);
33 item = new MockLauncherItem("libreoffice", "/usr/share/applications/libreoffice.desktop","Libre Office", "libreoffice", this);
33 m_list.append(item);
34 m_list.append(item);
34 qDebug() << "mock model created";
35 qDebug() << "mock model created";
36+
37+ qsrand(QDateTime::currentMSecsSinceEpoch() / 1000);
35}
38}
36
39
37int MockAppDrawerModel::rowCount(const QModelIndex &parent) const
40int MockAppDrawerModel::rowCount(const QModelIndex &parent) const
@@ -48,6 +51,8 @@ QVariant MockAppDrawerModel::data(const QModelIndex &index, int role) const
48 return m_list.at(index.row())->name();
51 return m_list.at(index.row())->name();
49 case RoleIcon:
52 case RoleIcon:
50 return m_list.at(index.row())->icon();
53 return m_list.at(index.row())->icon();
54+ case RoleUsage:
55+ return qrand();
51 }
56 }
52
57
53 return QVariant();
58 return QVariant();