on xenial help sign in
Implement launcher tooltips.

Approved by: Michał Sawicz

commit381271b9ded7abfb044d0b32d241226c3bdb45ce authorAndrea Azzarone <azzaronea@gmail.com> dateTue 29 Nov 2016, 09:40 (10 years ago) parent243b443b852b1e
5 files changed+243−3
debian/control+2 qml/Launcher/LauncherDelegate.qml+1 qml/Launcher/LauncherPanel.qml+79−3 qml/Launcher/Tooltip.qml+72 tests/qmltests/Launcher/tst_Launcher.qml+89
debian/control+2
@@ -49,6 +49,7 @@ Build-Depends: cmake,
4949 python3-all:any,
5050 python3-setuptools,
5151 qml-module-qt-labs-folderlistmodel,
52+ qml-module-qtqml-statemachine,
5253 qml-module-qtmultimedia (>= 5.4.1-1ubuntu19~overlay2),
5354 qml-module-qtquick-layouts,
5455 qml-module-qtquick-xmllistmodel,
@@ -121,6 +122,7 @@ Depends: dmz-cursor-theme,
121122 qmenumodel-qml (>= 0.2.10),
122123 qml-module-biometryd,
123124 qml-module-qt-labs-folderlistmodel,
125+ qml-module-qtqml-statemachine,
124126 qml-module-qtquick-xmllistmodel,
125127 qml-module-qtsysteminfo,
126128 qml-module-ubuntu-web,
qml/Launcher/LauncherDelegate.qml+1
@@ -22,6 +22,7 @@ Item {
2222
2323 property int itemIndex: 0
2424 property string iconName
25+ property string name
2526 property int count: 0
2627 property bool countVisible: false
2728 property int progress: -1
qml/Launcher/LauncherPanel.qml+79−3
@@ -15,6 +15,7 @@
1515 */
1616
1717import QtQuick 2.4
18+import QtQml.StateMachine 1.0 as DSM
1819import Ubuntu.Components 1.3
1920import Unity.Launcher 0.1
2021import Ubuntu.Components.Popups 1.3
@@ -31,7 +32,7 @@ Rectangle {
3132 property bool dragging: false
3233 property bool moving: launcherListView.moving || launcherListView.flicking
3334 property bool preventHiding: moving || dndArea.draggedIndex >= 0 || quickList.state === "open" || dndArea.pressed
34− || mouseEventEater.containsMouse || dashItem.hovered
35+ || dndArea.containsMouse || dashItem.hovered
3536 property int highlightIndex: -2
3637 property bool shortcutHintsShown: false
3738
@@ -40,7 +41,7 @@ Rectangle {
4041 signal kbdNavigationCancelled()
4142
4243 onXChanged: {
43− if (quickList.state == "open") {
44+ if (quickList.state === "open") {
4445 quickList.state = ""
4546 }
4647 }
@@ -69,7 +70,6 @@ Rectangle {
6970 id: mouseEventEater
7071 anchors.fill: parent
7172 acceptedButtons: Qt.AllButtons
72− hoverEnabled: true
7373 onWheel: wheel.accepted = true;
7474 }
7575
@@ -225,6 +225,7 @@ Rectangle {
225225 // the right app when running autopilot tests for
226226 // multiple apps.
227227 readonly property string appId: model.appId
228+ name: model.name
228229 itemIndex: index
229230 itemHeight: launcherListView.itemHeight
230231 itemWidth: launcherListView.itemWidth
@@ -399,6 +400,7 @@ Rectangle {
399400 id: dndArea
400401 objectName: "dndArea"
401402 acceptedButtons: Qt.LeftButton | Qt.RightButton
403+ hoverEnabled: true
402404 anchors {
403405 fill: parent
404406 topMargin: launcherListView.topMargin
@@ -829,4 +831,78 @@ Rectangle {
829831 }
830832 }
831833 }
834+
835+ Tooltip {
836+ id: tooltipShape
837+ objectName: "tooltipShape"
838+
839+ visible: tooltipShownState.active
840+ rotation: root.rotation
841+ y: itemCenter - (height / 2)
842+
843+ anchors {
844+ left: root.inverted ? undefined : parent.right
845+ right: root.inverted ? parent.left : undefined
846+ margins: units.gu(1)
847+ }
848+
849+ readonly property var hoveredItem: dndArea.containsMouse ? launcherListView.itemAt(dndArea.mouseX, dndArea.mouseY + launcherListView.realContentY) : null
850+ readonly property int itemCenter: !hoveredItem ? 0 : root.mapFromItem(hoveredItem, 0, 0).y + (hoveredItem.height / 2) + hoveredItem.offset
851+
852+ text: !hoveredItem ? "" : hoveredItem.name
853+ }
854+
855+ DSM.StateMachine {
856+ id: tooltipStateMachine
857+ initialState: tooltipHiddenState
858+ running: true
859+
860+ DSM.State {
861+ id: tooltipHiddenState
862+
863+ DSM.SignalTransition {
864+ targetState: tooltipShownState
865+ signal: tooltipShape.hoveredItemChanged
866+ // !dndArea.pressed allows us to filter out touch input events
867+ guard: tooltipShape.hoveredItem !== null && !dndArea.pressed && !root.moving
868+ }
869+ }
870+
871+ DSM.State {
872+ id: tooltipShownState
873+
874+ DSM.SignalTransition {
875+ targetState: tooltipHiddenState
876+ signal: tooltipShape.hoveredItemChanged
877+ guard: tooltipShape.hoveredItem === null
878+ }
879+
880+ DSM.SignalTransition {
881+ targetState: tooltipDismissedState
882+ signal: dndArea.onPressed
883+ }
884+
885+ DSM.SignalTransition {
886+ targetState: tooltipDismissedState
887+ signal: quickList.stateChanged
888+ guard: quickList.state === "open"
889+ }
890+ }
891+
892+ DSM.State {
893+ id: tooltipDismissedState
894+
895+ DSM.SignalTransition {
896+ targetState: tooltipHiddenState
897+ signal: dndArea.positionChanged
898+ guard: quickList.state != "open" && !dndArea.pressed && !dndArea.moving
899+ }
900+
901+ DSM.SignalTransition {
902+ targetState: tooltipHiddenState
903+ signal: dndArea.exited
904+ guard: quickList.state != "open"
905+ }
906+ }
907+ }
832908}
qml/Launcher/Tooltip.qmlnew file+72
@@ -0,0 +1,72 @@
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+
20+UbuntuShape {
21+ id: root
22+
23+ // This property holds the delay (milliseconds) after which the tool tip is shown.
24+ // A tooltip with a negative delay is shown immediately. The default value is 500 ms.
25+ property int delay: 500
26+
27+ // This property holds the text shown on the tool tip.
28+ property alias text: label.text
29+
30+ aspect: UbuntuShape.Flat
31+ color: theme.palette.normal.background
32+ width: label.implicitWidth + units.gu(4)
33+ height: label.implicitHeight + units.gu(2)
34+ opacity: 0
35+
36+ Image {
37+ anchors {
38+ right: parent.left
39+ rightMargin: -units.dp(4)
40+ verticalCenter: parent.verticalCenter
41+ }
42+ source: "graphics/quicklist_tooltip.png"
43+ rotation: 90
44+ }
45+
46+ Label {
47+ id: label
48+ anchors.centerIn: parent
49+ color: theme.palette.normal.backgroundText
50+ }
51+
52+ states: [
53+ State {
54+ name: "visible"
55+ when: root.visible
56+ PropertyChanges {
57+ target: root
58+ opacity: 0.95
59+ }
60+ }
61+ ]
62+
63+ transitions: [
64+ Transition {
65+ from: ""; to: "visible"
66+ SequentialAnimation {
67+ PauseAnimation { duration: root.delay }
68+ UbuntuNumberAnimation { target: root; property: "opacity"; duration: UbuntuAnimation.BriskDuration }
69+ }
70+ }
71+ ]
72+}
tests/qmltests/Launcher/tst_Launcher.qml+89
@@ -1369,6 +1369,95 @@ Rectangle {
13691369 tryCompare(clickThroughSpy, "count", 0);
13701370 }
13711371
1372+ function test_tooltip() {
1373+ launcher.lockedVisible = true;
1374+ revealByEdgePush();
1375+
1376+ var item = findChild(launcher, "launcherDelegate0");
1377+ var tooltipShape = findChild(launcher, "tooltipShape");
1378+
1379+ // Initial state
1380+ tryCompare(tooltipShape, "visible", false);
1381+ tryCompare(tooltipShape, "opacity", .0);
1382+
1383+ // Move the mouse on the launcher icon
1384+ mouseMove(item, item.width / 2, item.height / 2, 10);
1385+ mouseMove(item, item.width / 2 + 1, item.height / 2, 10);
1386+ tryCompare(tooltipShape, "visible", true);
1387+ tryCompare(tooltipShape, "opacity", .95);
1388+
1389+ // Move the mouse away
1390+ mouseMove(root, root.width, root.height / 2, 10);
1391+ tryCompare(tooltipShape, "visible", false);
1392+ tryCompare(tooltipShape, "opacity", .0);
1393+ }
1394+
1395+ function test_quicklist_dismisses_tooltip() {
1396+ launcher.lockedVisible = true;
1397+ revealByEdgePush();
1398+
1399+ var item = findChild(launcher, "launcherDelegate0");
1400+ var tooltipShape = findChild(launcher, "tooltipShape");
1401+ var quickListShape = findChild(launcher, "quickListShape");
1402+
1403+ // Initial state
1404+ tryCompare(tooltipShape, "visible", false);
1405+ tryCompare(tooltipShape, "opacity", .0);
1406+
1407+ // Move the mouse on the launcher icon
1408+ mouseMove(item, item.width / 2, item.height / 2, 10);
1409+ mouseMove(item, item.width / 2 + 1, item.height / 2, 10);
1410+ tryCompare(tooltipShape, "visible", true);
1411+ tryCompare(tooltipShape, "opacity", .95);
1412+
1413+ // Right click to show the quicklist
1414+ mouseClick(item, item.width / 2, item.height / 2, Qt.RightButton);
1415+ tryCompare(quickListShape, "visible", true);
1416+ tryCompare(tooltipShape, "visible", false);
1417+ tryCompare(tooltipShape, "opacity", .0);
1418+
1419+ // Left click hides the quicklist, tooltip is still dismissed
1420+ mouseClick(item, item.width / 2, item.height / 2, Qt.LefftButton);
1421+ tryCompare(quickListShape, "visible", false);
1422+ tryCompare(tooltipShape, "visible", false);
1423+ tryCompare(tooltipShape, "opacity", .0);
1424+
1425+ // Mouse motion should should show tooltip again
1426+ mouseMove(item, item.width / 2, item.height / 2, 10);
1427+ mouseMove(item, item.width / 2 + 1, item.height / 2, 10);
1428+ tryCompare(tooltipShape, "visible", true);
1429+ tryCompare(tooltipShape, "opacity", .95);
1430+ }
1431+
1432+ function test_click_dismisses_tooltip() {
1433+ launcher.lockedVisible = true;
1434+ revealByEdgePush();
1435+
1436+ var item = findChild(launcher, "launcherDelegate0");
1437+ var tooltipShape = findChild(launcher, "tooltipShape");
1438+
1439+ // Initial state
1440+ tryCompare(tooltipShape, "visible", false);
1441+ tryCompare(tooltipShape, "opacity", .0);
1442+
1443+ // Move the mouse on the launcher icon
1444+ mouseMove(item, item.width / 2, item.height / 2, 10);
1445+ mouseMove(item, item.width / 2 + 1, item.height / 2, 10);
1446+ tryCompare(tooltipShape, "visible", true);
1447+ tryCompare(tooltipShape, "opacity", .95);
1448+
1449+ // Left click should dismiss the tooltip
1450+ mouseClick(item, item.width / 2 + 1, item.height / 2, Qt.LeftButton);
1451+ tryCompare(tooltipShape, "visible", false);
1452+ tryCompare(tooltipShape, "opacity", .0);
1453+
1454+ // Mouse motion should should show tooltip again
1455+ mouseMove(item, item.width / 2, item.height / 2, 10);
1456+ mouseMove(item, item.width / 2 + 1, item.height / 2, 10);
1457+ tryCompare(tooltipShape, "visible", true);
1458+ tryCompare(tooltipShape, "opacity", .95);
1459+ }
1460+
13721461 function test_launcherEnabledSetting() {
13731462 launcher.available = true;
13741463