on xenial help sign in
Use a s StateMachine to handle tooltip logic.
commit0e4d9f5b043c0c5dcf6308c1f5f8a9ed84174d26 authorAndrea Azzarone <azzaronea@gmail.com> dateMon 26 Sep 2016, 13:58 (10 years ago) parentb568bb3
3 files changed+143−45
qml/Launcher/LauncherDelegate.qml+1 qml/Launcher/LauncherPanel.qml+79−44 tests/qmltests/Launcher/tst_Launcher.qml+63−1
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−44
@@ -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
@@ -44,9 +45,6 @@ Rectangle {
4445 if (quickList.state === "open") {
4546 quickList.state = ""
4647 }
47− if (tooltip.state === "open") {
48− quickList.state = ""
49− }
5048 }
5149
5250 function highlightNext() {
@@ -175,12 +173,6 @@ Rectangle {
175173 property real realContentY: contentY - originY + topMargin
176174 property int realItemHeight: itemHeight + spacing
177175
178− onRealContentYChanged : {
179− if (tooltip.state === "open") {
180− tooltip.state = "";
181− }
182− }
183−
184176 // In case the start dragging transition is running, we need to delay the
185177 // move because the displaced transition would clash with it and cause items
186178 // to be moved to wrong places
@@ -235,6 +227,7 @@ Rectangle {
235227 // the right app when running autopilot tests for
236228 // multiple apps.
237229 readonly property string appId: model.appId
230+ name: model.name
238231 itemIndex: index
239232 itemHeight: launcherListView.itemHeight
240233 itemWidth: launcherListView.itemWidth
@@ -431,20 +424,12 @@ Rectangle {
431424
432425 function processPress(mouse) {
433426 selectedItem = launcherListView.itemAt(mouse.x, mouse.y + launcherListView.realContentY)
434−
435− if (tooltip.state === "open") {
436− tooltip.state = "";
437− }
438427 }
439428
440429 onClicked: {
441430 var index = Math.floor((mouseY + launcherListView.realContentY) / launcherListView.realItemHeight);
442431 var clickedItem = launcherListView.itemAt(mouseX, mouseY + launcherListView.realContentY)
443432
444− if (tooltip.state === "open") {
445− tooltip.state = "";
446− }
447−
448433 // Check if we actually clicked an item or only at the spacing in between
449434 if (clickedItem === null) {
450435 return;
@@ -544,10 +529,6 @@ Rectangle {
544529 startY = mouse.y
545530 }
546531
547− onExited: {
548− tooltip.state = "";
549− }
550−
551532 onPositionChanged: {
552533 processPositionChanged(mouse)
553534 }
@@ -602,17 +583,6 @@ Rectangle {
602583 draggedIndex = newIndex
603584 }
604585 }
605− } else {
606− var index = Math.floor((mouse.y + launcherListView.realContentY) / launcherListView.realItemHeight);
607− var clickedItem = launcherListView.itemAt(mouse.x, mouse.y + launcherListView.realContentY);
608−
609− // Check if we actually hovered an item or only the spacing in between
610− if (clickedItem === null || mouse.buttons) {
611− tooltip.state = "";
612− return;
613− }
614−
615− tooltip.open(index);
616586 }
617587 }
618588 }
@@ -866,13 +836,15 @@ Rectangle {
866836 id: tooltipShape
867837 objectName: "tooltipShape"
868838 anchors.fill: tooltip
869− opacity: tooltip.state === "open" && quickList.state != "open" ? 0.95 : 0
839+ opacity: tooltipShownState.active ? 0.95 : 0
870840 visible: opacity > 0
871841 rotation: root.rotation
872842 aspect: UbuntuShape.Flat
873843
874844 Behavior on opacity {
875− UbuntuNumberAnimation {}
845+ UbuntuNumberAnimation {
846+ duration: UbuntuAnimation.BriskDuration
847+ }
876848 }
877849
878850 source: ShaderEffectSource {
@@ -896,6 +868,7 @@ Rectangle {
896868
897869 Rectangle {
898870 id: tooltip
871+ objectName: "tooltip"
899872
900873 color: theme.palette.normal.background
901874 visible: tooltipShape.visible
@@ -912,19 +885,17 @@ Rectangle {
912885 margins: units.gu(1)
913886 }
914887
915− property string text
916− property var item
888+ property var hoveredItem: dndArea.containsMouse ? launcherListView.itemAt(dndArea.mouseX, dndArea.mouseY + launcherListView.realContentY) : null
917889
918− property int itemCenter: item ? root.mapFromItem(tooltip.item, 0, 0).y + (item.height / 2) + tooltip.item.offset : units.gu(1)
890+ property int itemCenter
919891 property int offset: itemCenter + (height/2) + units.gu(1) > parent.height ? -itemCenter - (height/2) - units.gu(1) + parent.height :
920892 itemCenter - (height/2) < units.gu(1) ? (height/2) - itemCenter + units.gu(1) : 0
921893
922− function open(index) {
923− var itemPosition = index * launcherListView.itemHeight;
924− var height = launcherListView.height - launcherListView.topMargin - launcherListView.bottomMargin
925− item = launcherListView.itemAt(launcherListView.width / 2, itemPosition + launcherListView.itemHeight / 2);
926− tooltip.text = launcherListView.model.get(index).name;
927− tooltip.state = "open";
894+ onHoveredItemChanged : {
895+ if (hoveredItem != null && !root.moving) {
896+ itemCenter = root.mapFromItem(hoveredItem, 0, 0).y + (hoveredItem.height / 2) + hoveredItem.offset
897+ tooltipLabel.text = tooltip.hoveredItem.name
898+ }
928899 }
929900
930901 Label {
@@ -932,8 +903,72 @@ Rectangle {
932903 height: parent.height
933904 anchors.centerIn: parent
934905 verticalAlignment: Label.AlignVCenter
935− text: tooltip.text
936906 color: theme.palette.normal.backgroundText
937907 }
908+
909+ DSM.StateMachine {
910+ id: tooltipStateMachine
911+ initialState: tooltipHiddenState
912+ running: true
913+
914+ DSM.State {
915+ id: tooltipHiddenState
916+
917+ DSM.SignalTransition {
918+ targetState: tooltipShownState
919+ signal: tooltip.hoveredItemChanged
920+ // !dndArea.pressed allows us to filter out touch input events
921+ guard: tooltip.hoveredItem != null && !dndArea.pressed && !root.moving
922+ }
923+ }
924+
925+ DSM.State {
926+ id: tooltipShownState
927+
928+ DSM.SignalTransition {
929+ targetState: tooltipHiddenState
930+ signal: tooltip.hoveredItemChanged
931+ guard: tooltip.hoveredItem == null
932+ }
933+
934+ DSM.SignalTransition {
935+ targetState: tooltipHiddenState
936+ signal: dndArea.exited
937+ }
938+
939+ DSM.SignalTransition {
940+ targetState: tooltipDismissedState
941+ signal: dndArea.onPressed
942+ }
943+
944+ DSM.SignalTransition {
945+ targetState: tooltipDismissedState
946+ signal: quickList.stateChanged
947+ guard: quickList.state === "open"
948+ }
949+
950+ DSM.SignalTransition {
951+ targetState: tooltipDismissedState
952+ signal: root.movingChanged
953+ guard: root.moving
954+ }
955+ }
956+
957+ DSM.State {
958+ id: tooltipDismissedState
959+
960+ DSM.SignalTransition {
961+ targetState: tooltipHiddenState
962+ signal: dndArea.positionChanged
963+ guard: quickList.state != "open" && !dndArea.pressed && !dndArea.moving
964+ }
965+
966+ DSM.SignalTransition {
967+ targetState: tooltipHiddenState
968+ signal: dndArea.exited
969+ guard: quickList.state != "open"
970+ }
971+ }
972+ }
938973 }
939974}
tests/qmltests/Launcher/tst_Launcher.qml+63−1
@@ -1356,15 +1356,77 @@ Rectangle {
13561356
13571357 function test_tooltip() {
13581358 dragLauncherIntoView()
1359+
1360+ var item = findChild(launcher, "launcherDelegate0")
1361+ var tooltipShape = findChild(launcher, "tooltipShape")
1362+
1363+ // Make sure we don't start the test with the mouse hovering the launcher
1364+ mouseMove(root, root.width, root.height / 2)
1365+
1366+ // Initial state
1367+ compare(tooltipShape.visible, false)
1368+
1369+ // Move the mouse on the launcher icon
1370+ mouseMove(item, item.width / 2, item.height / 2)
1371+ mouseMove(item, item.width / 2 + 1, item.height / 2)
1372+ tryCompare(tooltipShape, "visible", true)
1373+
1374+ // Move the mouse away
1375+ mouseMove(root, root.width, root.height / 2)
1376+ tryCompare(tooltipShape, "visible", false)
1377+ }
1378+
1379+ function test_quicklist_dismiss_tooltip() {
1380+ dragLauncherIntoView()
1381+
1382+ var item = findChild(launcher, "launcherDelegate0")
1383+ var tooltipShape = findChild(launcher, "tooltipShape")
1384+ var quickListShape = findChild(launcher, "quickListShape")
1385+
1386+ // Make sure we don't start the test with the mouse hovering the launcher
1387+ mouseMove(root, root.width, root.height / 2)
1388+
1389+ // Initial state
1390+ compare(tooltipShape.visible, false)
1391+
1392+ var tooltip = findChild(launcher, "tooltip")
1393+
1394+
1395+ // Move the mouse on the launcher icon
1396+ mouseMove(item, item.width / 2, item.height / 2)
1397+ mouseMove(item, item.width / 2 + 1, item.height / 2)
1398+ tryCompare(tooltipShape, "visible", true)
1399+ console.log(tooltip.state)
1400+
1401+
1402+ // Right click to show the quicklist
1403+ mouseClick(item, item.width / 2, item.height / 2, Qt.RightButton)
1404+ tryCompare(quickListShape, "visible", true)
1405+
1406+ console.log(tooltip.state)
1407+ tryCompare(tooltipShape, "visible", false)
1408+ }
1409+
1410+ function test_click_dismiss_tooltip() {
1411+ dragLauncherIntoView()
1412+
13591413 var item = findChild(launcher, "launcherDelegate0")
13601414 var tooltipShape = findChild(launcher, "tooltipShape")
13611415
1416+ // Make sure we don't start the test with the mouse hovering the launcher
1417+ mouseMove(root, root.width, root.height / 2)
1418+
13621419 // Initial state
13631420 compare(tooltipShape.visible, false)
13641421
13651422 // Move the mouse on the launcher icon
1366− mouseMove(item, item.width / 2, item.height / 2, 2)
1423+ mouseMove(item, item.width / 2, item.height / 2)
1424+ mouseMove(item, item.width / 2 + 1, item.height / 2)
13671425 tryCompare(tooltipShape, "visible", true)
1426+
1427+ // Left click should dismiss the tooltip
1428+ mouseClick(item, item.width / 2, item.height / 2, Qt.LeftButton)
1429+ tryCompare(tooltipShape, "visible", false)
13681430 }
13691431 }
13701432}