on xenial help sign in
secondary indicator actions
commit46b3d1f777203ad89263a28e18faea0f4434d3fc authorNick Dedekind <nick.dedekind@canonical.com> dateMon 4 Jan 2016, 14:04 (11 years ago) parent88c6f00
6 files changed+156−15
plugins/Unity/Indicators/modelactionrootstate.cpp+75 plugins/Unity/Indicators/modelactionrootstate.h+14−3 qml/Components/VolumeControl.qml−5 qml/Panel/IndicatorItem.qml+56−6 qml/Panel/Indicators/IndicatorBase.qml+1−1 tests/mocks/Unity/Indicators/ModelActionRootState.qml+10
plugins/Unity/Indicators/modelactionrootstate.cpp+75
@@ -32,6 +32,7 @@ extern "C" {
3232ModelActionRootState::ModelActionRootState(QObject *parent)
3333 : RootStateObject(parent),
3434 m_menu(nullptr)
35+ , m_reentryGuard(false)
3536{
3637}
3738
@@ -62,6 +63,7 @@ void ModelActionRootState::setMenu(UnityMenuModel* menu)
6263 connect(m_menu, &UnityMenuModel::destroyed, this, &ModelActionRootState::reset);
6364 }
6465 updateActionState();
66+ updateOtherActions();
6567 Q_EMIT menuChanged();
6668
6769 if (wasValid != valid())
@@ -69,6 +71,21 @@ void ModelActionRootState::setMenu(UnityMenuModel* menu)
6971 }
7072}
7173
74+QString ModelActionRootState::secondaryAction() const
75+{
76+ return m_secondaryAction;
77+}
78+
79+QString ModelActionRootState::scrollAction() const
80+{
81+ return m_scrollAction;
82+}
83+
84+QString ModelActionRootState::submenuAction() const
85+{
86+ return m_submenuAction;
87+}
88+
7289bool ModelActionRootState::valid() const
7390{
7491 return !currentState().empty();
@@ -79,6 +96,7 @@ void ModelActionRootState::onModelRowsAdded(const QModelIndex& parent, int start
7996 Q_UNUSED(parent);
8097 if (start == 0 && end >= 0) {
8198 updateActionState();
99+ updateOtherActions();
82100 }
83101}
84102
@@ -87,6 +105,7 @@ void ModelActionRootState::onModelRowsRemoved(const QModelIndex& parent, int sta
87105 Q_UNUSED(parent);
88106 if (start == 0 && end >= 0) {
89107 updateActionState();
108+ updateOtherActions();
90109 }
91110}
92111
@@ -99,6 +118,7 @@ void ModelActionRootState::onModelDataChanged(const QModelIndex& topLeft, const
99118
100119 if (topLeft.row() <= 0 && bottomRight.row() >= 0) {
101120 updateActionState();
121+ updateOtherActions();
102122 }
103123}
104124
@@ -108,10 +128,15 @@ void ModelActionRootState::reset()
108128
109129 Q_EMIT menuChanged();
110130 setCurrentState(QVariantMap());
131+
132+ updateOtherActions();
111133}
112134
113135void ModelActionRootState::updateActionState()
114136{
137+ if (m_reentryGuard) return;
138+ m_reentryGuard = true;
139+
115140 if (m_menu && m_menu->rowCount() > 0) {
116141 ActionStateParser* oldParser = m_menu->actionStateParser();
117142 m_menu->setActionStateParser(&m_parser);
@@ -126,4 +151,54 @@ void ModelActionRootState::updateActionState()
126151 }
127152 // else if m_menu->rowCount() == 0, let's leave existing cache in place
128153 // until the new menu comes in, to avoid flashing the UI empty for a moment
154+
155+ m_reentryGuard = false;
156+}
157+
158+void ModelActionRootState::updateOtherActions()
159+{
160+ if (m_reentryGuard) return;
161+ m_reentryGuard = true;
162+
163+ if (m_menu && m_menu->rowCount() > 0) {
164+ QVariantMap map;
165+ map[QStringLiteral("submenu-action")] = QLatin1String("string");
166+ map[QStringLiteral("x-canonical-scroll-action")] = QLatin1String("string");
167+ map[QStringLiteral("x-canonical-secondary-action")] = QLatin1String("string");
168+ m_menu->loadExtendedAttributes(0, map);
169+ QVariantMap extMap = m_menu->get(0, "ext").toMap();
170+
171+ QString secondaryAction = extMap[QStringLiteral("xCanonicalSecondaryAction")].toString();
172+ if (m_secondaryAction != secondaryAction) {
173+ m_secondaryAction = secondaryAction;
174+ Q_EMIT secondaryActionChanged();
175+ }
176+
177+ QString scrollAction = extMap[QStringLiteral("xCanonicalScrollAction")].toString();
178+ if (m_scrollAction != scrollAction) {
179+ m_scrollAction = scrollAction;
180+ Q_EMIT scrollActionChanged();
181+ }
182+
183+ QString submenuAction = extMap[QStringLiteral("submenuAction")].toString();
184+ if (m_submenuAction != submenuAction) {
185+ m_submenuAction = submenuAction;
186+ Q_EMIT submenuActionChanged();
187+ }
188+ } else {
189+ if (!m_secondaryAction.isEmpty()) {
190+ m_secondaryAction.clear();
191+ Q_EMIT secondaryActionChanged();
192+ }
193+ if (!m_scrollAction.isEmpty()) {
194+ m_scrollAction.clear();
195+ Q_EMIT scrollActionChanged();
196+ }
197+ if (!m_submenuAction.isEmpty()) {
198+ m_submenuAction.clear();
199+ Q_EMIT submenuActionChanged();
200+ }
201+ }
202+
203+ m_reentryGuard = false;
129204}
plugins/Unity/Indicators/modelactionrootstate.h+14−3
@@ -30,6 +30,9 @@ class UNITYINDICATORS_EXPORT ModelActionRootState : public RootStateObject
3030{
3131 Q_OBJECT
3232 Q_PROPERTY(UnityMenuModel* menu READ menu WRITE setMenu NOTIFY menuChanged)
33+ Q_PROPERTY(QString secondaryAction READ secondaryAction NOTIFY secondaryActionChanged)
34+ Q_PROPERTY(QString scrollAction READ scrollAction NOTIFY scrollActionChanged)
35+ Q_PROPERTY(QString submenuAction READ submenuAction NOTIFY submenuActionChanged)
3336public:
3437 ModelActionRootState(QObject *parent = 0);
3538 virtual ~ModelActionRootState();
@@ -37,14 +40,17 @@ public:
3740 UnityMenuModel* menu() const;
3841 void setMenu(UnityMenuModel* menu);
3942
40− int index() const;
41− void setIndex(int index);
43+ QString secondaryAction() const;
44+ QString scrollAction() const;
45+ QString submenuAction() const;
4246
4347 bool valid() const override;
4448
4549Q_SIGNALS:
4650 void menuChanged();
47− void indexChanged();
51+ void secondaryActionChanged();
52+ void scrollActionChanged();
53+ void submenuActionChanged();
4854
4955private Q_SLOTS:
5056 void onModelRowsAdded(const QModelIndex& parent, int start, int end);
@@ -54,8 +60,13 @@ private Q_SLOTS:
5460
5561private:
5662 void updateActionState();
63+ void updateOtherActions();
5764
5865 UnityMenuModel* m_menu;
66+ QString m_secondaryAction;
67+ QString m_scrollAction;
68+ QString m_submenuAction;
69+ bool m_reentryGuard;
5970};
6071
6172#endif // MODELACTIONROOTSTATE_H
qml/Components/VolumeControl.qml−5
@@ -28,10 +28,6 @@ Item {
2828 readonly property int stepDown: -1
2929
3030 property var indicators // passed from Shell.qml
31− readonly property bool showNotification: indicators && indicators.fullyOpened && indicators.currentIndicator === "indicator-sound"
32− onShowNotificationChanged: { // disallow the volume notification when using the slider, lpbug#1484126
33− actionGroup.indicatorsAction.updateState(root.showNotification);
34− }
3531
3632 GlobalShortcut {
3733 id: muteShortcut
@@ -47,7 +43,6 @@ Item {
4743
4844 property variant actionObject: action("volume")
4945 property variant muteActionObject: indicators.indicatorsModel.profile === "desktop" ? action("mute") : action("silent-mode")
50− property variant indicatorsAction: action("indicator-shown")
5146 }
5247
5348 function volumeUp() {
qml/Panel/IndicatorItem.qml+56−6
@@ -17,6 +17,7 @@
1717import QtQuick 2.4
1818import Ubuntu.Components 1.3
1919import Ubuntu.Settings.Components 0.1
20+import QMenuModel 0.1
2021import "Indicators"
2122
2223IndicatorDelegate {
@@ -36,13 +37,24 @@ IndicatorDelegate {
3637 return "#ffffff";
3738 }
3839
39− signal clicked()
40−
4140 implicitWidth: mainItems.width
4241
4342 MouseArea {
43+ readonly property int stepUp: 1
44+ readonly property int stepDown: -1
45+
4446 anchors.fill: parent
45− onClicked: parent.clicked()
47+ acceptedButtons: Qt.MiddleButton
48+ onClicked: {
49+ if ((!expanded || selected) && secondaryAction.valid) {
50+ secondaryAction.activate();
51+ }
52+ }
53+ onWheel: {
54+ if ((!expanded || selected) && scrollAction.valid) {
55+ scrollAction.activate(wheel.angleDelta.y > 0 ? stepUp : stepDown);
56+ }
57+ }
4658 }
4759
4860 Item {
@@ -152,9 +164,6 @@ IndicatorDelegate {
152164 }
153165
154166 StateGroup {
155− id: d
156− property bool useFallbackIcon: false
157−
158167 states: [
159168 State {
160169 name: "minimised"
@@ -251,4 +260,45 @@ IndicatorDelegate {
251260 rightLabel = rootActionState.rightLabel ? rootActionState.rightLabel : "";
252261 icons = rootActionState.icons;
253262 }
263+
264+ QtObject {
265+ id: d
266+
267+ property bool useFallbackIcon: false
268+ property var shouldIndicatorBeShown: undefined
269+
270+ onShouldIndicatorBeShownChanged: {
271+ if (shouldIndicatorBeShown !== undefined) {
272+ submenuAction.changeState(shouldIndicatorBeShown);
273+ }
274+ }
275+ }
276+
277+ UnityMenuAction {
278+ id: secondaryAction
279+ model: menuModel
280+ index: 0
281+ name: rootActionState.secondaryAction
282+ }
283+
284+ UnityMenuAction {
285+ id: scrollAction
286+ model: menuModel
287+ index: 0
288+ name: rootActionState.scrollAction
289+ }
290+
291+ UnityMenuAction {
292+ id: submenuAction
293+ model: menuModel
294+ index: 0
295+ name: rootActionState.submenuAction
296+ }
297+
298+ Binding {
299+ target: d
300+ property: "shouldIndicatorBeShown"
301+ when: submenuAction.valid
302+ value: root.selected && root.expanded
303+ }
254304}
qml/Panel/Indicators/IndicatorBase.qml+1−1
@@ -31,7 +31,7 @@ Item {
3131 property string rootMenuType: "com.canonical.indicator.root"
3232
3333 property alias menuModel: cachedModel.model
34− property alias rootActionState: rootAction
34+ readonly property alias rootActionState: rootAction
3535
3636 SharedUnityMenuModel {
3737 id: cachedModel
tests/mocks/Unity/Indicators/ModelActionRootState.qml+10
@@ -30,10 +30,20 @@ Item {
3030 property bool indicatorVisible: cachedState && cachedState.hasOwnProperty("visible") ? cachedState["visible"] : true
3131
3232 property var cachedState: menu ? menu.get(0, "actionState") : undefined
33+ property string submenuAction: {
34+ if (!menu) return "";
35+ var ext = menu.get(0, "ext");
36+ var submenuVar = ext ? ext["submenu-action"] : undefined;
37+ return submenuVar ? submenuVar : ""
38+ }
3339 Connections {
3440 target: menu
3541 onModelDataChanged: {
3642 cachedState = menu.get(0, "actionState");
43+
44+ var ext = menu.get(0, "ext");
45+ var submenuVar = ext ? ext["submenu-action"] : undefined;
46+ submenuAction = submenuVar ? submenuVar : ""
3747 }
3848 }
3949