on xenial help sign in
First go at slide-out animation for alerting/wobble of a launcher-icon.
68bf3b5Mirco Müller
plugins/Unity/Launcher/launchermodel.cpp+10
@@ -44,6 +44,8 @@ LauncherModel::LauncherModel(QObject *parent):
44
44
45 connect(m_settings, &GSettings::changed, this, &LauncherModel::refresh);
45 connect(m_settings, &GSettings::changed, this, &LauncherModel::refresh);
46
46
47+ m_alertIndex = -1;
48+
47 refresh();
49 refresh();
48}
50}
49
51
@@ -87,6 +89,14 @@ QVariant LauncherModel::data(const QModelIndex &index, int role) const
87 return QVariant();
89 return QVariant();
88}
90}
89
91
92+void LauncherModel::alert(const QString &appId) const {
93+ int index = findApplication(appId);
94+ if (index >= 0) {
95+ m_alertIndex = index;
96+ Q_EMIT alerting(m_alertIndex);
97+ }
98+}
99+
90unity::shell::launcher::LauncherItemInterface *LauncherModel::get(int index) const
100unity::shell::launcher::LauncherItemInterface *LauncherModel::get(int index) const
91{
101{
92 if (index < 0 || index >= m_list.count()) {
102 if (index < 0 || index >= m_list.count()) {
plugins/Unity/Launcher/launchermodel.h+3
@@ -45,6 +45,7 @@ public:
45
45
46 QVariant data(const QModelIndex &index, int role) const;
46 QVariant data(const QModelIndex &index, int role) const;
47
47
48+ Q_INVOKABLE void alert(const QString &appId) const;
48 Q_INVOKABLE unity::shell::launcher::LauncherItemInterface* get(int index) const;
49 Q_INVOKABLE unity::shell::launcher::LauncherItemInterface* get(int index) const;
49 Q_INVOKABLE void move(int oldIndex, int newIndex);
50 Q_INVOKABLE void move(int oldIndex, int newIndex);
50 Q_INVOKABLE void pin(const QString &appId, int index = -1);
51 Q_INVOKABLE void pin(const QString &appId, int index = -1);
@@ -85,6 +86,8 @@ private:
85 DBusInterface *m_dbusIface;
86 DBusInterface *m_dbusIface;
86 ASAdapter *m_asAdapter;
87 ASAdapter *m_asAdapter;
87
88
89+ int m_alertIndex;
90+
88 ApplicationManagerInterface *m_appManager;
91 ApplicationManagerInterface *m_appManager;
89
92
90 friend class LauncherModelTest;
93 friend class LauncherModelTest;
qml/Launcher/LauncherDelegate.qml+2−1
@@ -27,6 +27,7 @@ Item {
27 property bool itemFocused: false
27 property bool itemFocused: false
28 property real maxAngle: 0
28 property real maxAngle: 0
29 property bool inverted: false
29 property bool inverted: false
30+ property bool alerting: false
30
31
31 readonly property int effectiveHeight: Math.cos(angle * Math.PI / 180) * itemHeight
32 readonly property int effectiveHeight: Math.cos(angle * Math.PI / 180) * itemHeight
32 readonly property real foldedHeight: Math.cos(maxAngle * Math.PI / 180) * itemHeight
33 readonly property real foldedHeight: Math.cos(maxAngle * Math.PI / 180) * itemHeight
@@ -46,7 +47,7 @@ Item {
46 readonly property double angle: 5.0
47 readonly property double angle: 5.0
47 readonly property int duration: UbuntuAnimation.SnapDuration
48 readonly property int duration: UbuntuAnimation.SnapDuration
48
49
49− running: false
50+ running: alerting
50 loops: Animation.Infinite
51 loops: Animation.Infinite
51
52
52 NumberAnimation {
53 NumberAnimation {
qml/Launcher/LauncherPanel.qml+92
@@ -34,6 +34,7 @@ Rectangle {
34 property bool moving: launcherListView.moving || launcherListView.flicking
34 property bool moving: launcherListView.moving || launcherListView.flicking
35 property bool preventHiding: moving || dndArea.draggedIndex >= 0 || quickList.state === "open" || dndArea.pressed
35 property bool preventHiding: moving || dndArea.draggedIndex >= 0 || quickList.state === "open" || dndArea.pressed
36 property int highlightIndex: -1
36 property int highlightIndex: -1
37+ property int alertIndex: -1
37
38
38 signal applicationSelected(string appId)
39 signal applicationSelected(string appId)
39 signal showDashHome()
40 signal showDashHome()
@@ -44,6 +45,38 @@ Rectangle {
44 }
45 }
45 }
46 }
46
47
48+ onAlertIndexChanged: {
49+ if (alertIndex !== -1) {
50+ //unfold
51+
52+ panel.visible = true
53+ fakeAlertingItem.index = alertIndex
54+ fakeAlertingItem.iconName = launcherListView.model.get(alertIndex).icon
55+ fakeAlertingItem.y = alertIndex * fakeAlertingItem.itemHeight + launcherListView.anchors.topMargin + launcherListView.topMargin
56+ fakeAlertingItem.count = LauncherModel.get(alertIndex).count
57+ fakeAlertingItem.progress = LauncherModel.get(alertIndex).progress
58+ fakeAlertingItem.alerting = true
59+ fakeAlertingItem.visible = true
60+ if (launcher.state !== "visible") {
61+ fakeAlertingItem.reveal()
62+ }
63+ print("y = ", fakeAlertingItem.y)
64+ print("index = ", fakeAlertingItem.index)
65+ } else {
66+ // set real icon back to visible
67+
68+ // fold
69+
70+ // hide fake-alerting-icon
71+ fakeAlertingItem.alerting = false
72+
73+ if (launcher.state !== "visible") {
74+ fakeAlertingItem.hide()
75+ }
76+ //fakeAlertingItem.visible = false
77+ }
78+ }
79+
47 Column {
80 Column {
48 id: mainColumn
81 id: mainColumn
49 anchors {
82 anchors {
@@ -501,6 +534,65 @@ Rectangle {
501 to: 0
534 to: 0
502 }
535 }
503 }
536 }
537+
538+ LauncherDelegate {
539+ id: fakeAlertingItem
540+
541+ property int index
542+
543+ objectName: "fakeAlertingItem"
544+ visible: false
545+ itemWidth: launcherListView.itemWidth
546+ itemHeight: launcherListView.itemHeight
547+ height: itemHeight
548+ width: itemWidth
549+ rotation: root.rotation
550+ alerting: false
551+
552+ function reveal() {
553+ fakeAlertingItemReveal.start();
554+ }
555+
556+ function hide() {
557+ fakeAlertingItemHide.start();
558+ }
559+
560+ ParallelAnimation {
561+ id: fakeAlertingItemReveal
562+
563+ UbuntuNumberAnimation {
564+ target: fakeAlertingItem;
565+ properties: "angle, offset";
566+ to: 0
567+ }
568+
569+ UbuntuNumberAnimation {
570+ target: fakeAlertingItem;
571+ properties: "x";
572+ from: 0
573+ to: units.gu(1) + launcherListView.width * .5
574+ duration: UbuntuAnimation.BriskDuration
575+ }
576+ }
577+
578+ SequentialAnimation {
579+ id: fakeAlertingItemHide
580+
581+ UbuntuNumberAnimation {
582+ target: fakeAlertingItem;
583+ properties: "x";
584+ from: units.gu(1) + launcherListView.width * .5
585+ to: 0
586+ duration: UbuntuAnimation.BriskDuration
587+ }
588+
589+ PropertyAction {
590+ target: fakeAlertingItem
591+ properties: "visible"
592+ value: false
593+ }
594+ }
595+ }
504 }
596 }
505 }
597 }
506
598
tests/qmltests/Launcher/tst_Launcher.qml+28
@@ -93,6 +93,34 @@ Item {
93 onClicked: launcherLoader.item.inverted = !launcherLoader.item.inverted
93 onClicked: launcherLoader.item.inverted = !launcherLoader.item.inverted
94 Layout.fillWidth: true
94 Layout.fillWidth: true
95 }
95 }
96+
97+ Row {
98+ spacing: units.gu(1)
99+
100+ CheckBox {
101+ anchors.verticalCenter: parent.verticalCenter
102+ checked: false
103+ onClicked: {
104+ var panel = testCase.findChild(launcherLoader, "launcherPanel")
105+ panel.alertIndex = checked ? parseInt(iconIndex.displayText) : -1
106+ }
107+ }
108+
109+ Label {
110+ anchors.verticalCenter: parent.verticalCenter
111+ text: "wiggle of icon"
112+ }
113+
114+ TextArea {
115+ id: iconIndex
116+ anchors.verticalCenter: parent.verticalCenter
117+ width: units.gu(4)
118+ height: units.gu(4)
119+ autoSize: true
120+ text: "2"
121+ maximumLineCount: 1
122+ }
123+ }
96 }
124 }
97
125
98 SignalSpy {
126 SignalSpy {