From bd9cc5c12c022c6c368b51eb0d28bd6b8f8ef0ee Mon Sep 17 00:00:00 2001
From: Adriano Rezende <adriano.1.rezende@nokia.com>
Date: Tue, 3 Jul 2012 12:40:41 +0200
Subject: [PATCH] Fix ToolTip and improve ButtonBehavior

Change-Id: I099aa93a8ee28c5e7e76ef8e316449266acbadd2
Reviewed-by: Jens Bache-Wiig <jens.bache-wiig@nokia.com>
---
 components/Button.qml                         |  8 ---
 components/CheckBox.qml                       |  2 +-
 components/ToolButton.qml                     |  8 ---
 components/private/BasicButton.qml            | 24 +++++----
 components/private/ButtonBehavior.qml         | 39 +++++----------
 ...iparea.cpp => qquickcomponentsprivate.cpp} | 50 ++++---------------
 ...ooltiparea.h => qquickcomponentsprivate.h} | 35 +++----------
 src/qstyleplugin.cpp                          | 12 ++++-
 src/src.pro                                   |  4 +-
 9 files changed, 58 insertions(+), 124 deletions(-)
 rename src/{qtooltiparea.cpp => qquickcomponentsprivate.cpp} (66%)
 rename src/{qtooltiparea.h => qquickcomponentsprivate.h} (71%)

diff --git a/components/Button.qml b/components/Button.qml
index 19dd394aa..10908b7f4 100644
--- a/components/Button.qml
+++ b/components/Button.qml
@@ -45,7 +45,6 @@ import QtDesktop 0.2
 BasicButton {
     id: button
 
-    property alias containsMouse: tooltip.containsMouse
     property bool defaultbutton: false
     property string styleHint
     property string text
@@ -55,13 +54,6 @@ BasicButton {
 
     Keys.onSpacePressed:animateClick()
 
-    TooltipArea {
-        // Note this will eat hover events
-        id: tooltip
-        anchors.fill: parent
-        text: button.tooltip
-    }
-
     delegate: StyleItem {
         id: styleitem
         anchors.fill: parent
diff --git a/components/CheckBox.qml b/components/CheckBox.qml
index a97e50525..c4c152dee 100644
--- a/components/CheckBox.qml
+++ b/components/CheckBox.qml
@@ -47,7 +47,7 @@ FocusScope {
 
     signal clicked
 
-    property alias pressed: behavior.pressed
+    property alias pressed: behavior.effectivePressed
     property alias checked: behavior.checked
     property alias containsMouse: behavior.containsMouse
 
diff --git a/components/ToolButton.qml b/components/ToolButton.qml
index 5952a6f43..55dd7bbc8 100644
--- a/components/ToolButton.qml
+++ b/components/ToolButton.qml
@@ -45,19 +45,11 @@ import "private" as Private
 Private.BasicButton {
     id:button
 
-    property alias containsMouse: tooltip.containsMouse
     property string iconName
     property string styleHint
     property url iconSource
     property string text
 
-    TooltipArea {
-        // Note this will eat hover events
-        id: tooltip
-        anchors.fill: parent
-        text: button.tooltip
-    }
-
     delegate: StyleItem {
         id: styleitem
         anchors.fill: parent
diff --git a/components/private/BasicButton.qml b/components/private/BasicButton.qml
index 2427060ce..daa17adfe 100644
--- a/components/private/BasicButton.qml
+++ b/components/private/BasicButton.qml
@@ -39,12 +39,13 @@
 ****************************************************************************/
 
 import QtQuick 2.0
+import QtDesktop.Internal 0.2 as Internal
 
 Item {
     id: button
 
     signal clicked
-    property alias pressed: behavior.pressed
+    property alias pressed: behavior.effectivePressed
     property alias containsMouse: behavior.containsMouse
     property alias checkable: behavior.checkable  // button toggles between checked and !checked
     property alias checked: behavior.checked
@@ -67,15 +68,15 @@ Item {
     implicitHeight: loader.item.implicitHeight
 
     function animateClick() {
-        behavior.pressed = true
-        behavior.clicked()
+        behavior.keyPressed = true
+        button.clicked()
         animateClickTimer.start()
     }
 
     Timer {
         id: animateClickTimer
         interval: 250
-        onTriggered: behavior.pressed = false
+        onTriggered: behavior.keyPressed = false
     }
 
     Loader {
@@ -90,13 +91,14 @@ Item {
         id: behavior
         anchors.fill: parent
         onClicked: button.clicked()
-        onPressedChanged: if (activeFocusOnPress) button.focus = true
-        onMouseMoved: {tiptimer.restart()}
-        Timer{
-            id: tiptimer
-            interval:1000
-            running:containsMouse && tooltip.length
-            onTriggered: button.toolTipTriggered()
+        onExited: Internal.hideToolTip()
+        onCanceled: Internal.hideToolTip()
+        onPressed: if (activeFocusOnPress) button.focus = true
+
+        Timer {
+            interval: 1000
+            running: containsMouse && !pressed && tooltip.length
+            onTriggered: Internal.showToolTip(behavior, Qt.point(behavior.mouseX, behavior.mouseY), tooltip)
         }
     }
 
diff --git a/components/private/ButtonBehavior.qml b/components/private/ButtonBehavior.qml
index 4942d62fd..fdf0c79c2 100644
--- a/components/private/ButtonBehavior.qml
+++ b/components/private/ButtonBehavior.qml
@@ -40,34 +40,21 @@
 
 import QtQuick 2.0
 
-Item {
-    id: behavior
-
-    signal clicked
-    property bool pressed: false    // Can't be alias of mouseArea.pressed because the latter is read-only
-    property alias containsMouse: mouseArea.containsMouse
+MouseArea {
     property bool checkable: false
     property bool checked: false
-    property bool triState: false
-    signal mouseMoved
+    property bool keyPressed: false
+    property bool effectivePressed: pressed && containsMouse || keyPressed
+
+    hoverEnabled: true
+
+    onCheckableChanged: {
+        if (!checkable)
+            checked = false;
+    }
 
-    onCheckableChanged: { if(!checkable) checked = false }
-    MouseArea {
-        id: mouseArea
-        anchors.fill: parent
-        hoverEnabled: true
-        onPositionChanged: behavior.mouseMoved()
-        onPressed: behavior.pressed = true  // needed when hover is enabled
-        onEntered: if(pressed && enabled) behavior.pressed = true
-        onExited: behavior.pressed = false
-        onCanceled: behavior.pressed = false    // mouse stolen e.g. by Flickable
-        onReleased: {
-            if(behavior.pressed && behavior.enabled) { // No click if release outside area
-                behavior.pressed = false
-                if(behavior.checkable)
-                    behavior.checked = !behavior.checked;
-                behavior.clicked()
-            }
-        }
+    onReleased: {
+        if (checkable && containsMouse)
+            checked = !checked;
     }
 }
diff --git a/src/qtooltiparea.cpp b/src/qquickcomponentsprivate.cpp
similarity index 66%
rename from src/qtooltiparea.cpp
rename to src/qquickcomponentsprivate.cpp
index 9b97d8fe5..2f424ca31 100644
--- a/src/qtooltiparea.cpp
+++ b/src/qquickcomponentsprivate.cpp
@@ -38,54 +38,26 @@
 **
 ****************************************************************************/
 
-#include "qtooltiparea.h"
-#include <QtWidgets/QToolTip>
-#include <QtWidgets/QApplication>
-#include <QtWidgets/QGraphicsSceneEvent>
+#include "qquickcomponentsprivate.h"
+#include <QToolTip>
+#include <QQuickCanvas>
 
-QTooltipArea::QTooltipArea(QQuickItem *parent) :
-    QQuickItem(parent),
-    m_containsMouse(false)
-{
-    setAcceptHoverEvents(true);
-    connect(&m_tiptimer, SIGNAL(timeout()), this, SLOT(timeout()));
-}
 
-void QTooltipArea::setText(const QString &t)
+QQuickComponentsPrivate::QQuickComponentsPrivate(QObject *parent)
+    : QObject(parent)
 {
-    if (t != m_text) {
-        m_text = t;
-        emit textChanged();
-    }
-}
 
-void QTooltipArea::showToolTip(const QString &str) const
-{
-    Q_UNUSED(str);
-    //QToolTip::showText(cursor().pos(), str);
 }
 
-void QTooltipArea::hoverEnterEvent(QHoverEvent *event)
-
+void QQuickComponentsPrivate::showToolTip(QQuickItem *item, const QPointF &pos, const QString &str)
 {
-    Q_UNUSED(event);
-    m_tiptimer.start(1000);
-
-    m_containsMouse = true;
-    emit containsMouseChanged();
-    //QQuickItem::hoverEnterEvent(event);
-}
+    if (!item || !item->canvas())
+        return;
 
-void QTooltipArea::hoverLeaveEvent(QHoverEvent *event)
-{
-    Q_UNUSED(event);
-    m_tiptimer.stop();
-    m_containsMouse = false;
-    emit containsMouseChanged();
-    //QQuickItem::hoverLeaveEvent(event);
+    QToolTip::showText(item->canvas()->mapToGlobal(item->mapToScene(pos).toPoint()), str);
 }
 
-void QTooltipArea::timeout()
+void QQuickComponentsPrivate::hideToolTip()
 {
-    showToolTip(m_text);
+    QToolTip::hideText();
 }
diff --git a/src/qtooltiparea.h b/src/qquickcomponentsprivate.h
similarity index 71%
rename from src/qtooltiparea.h
rename to src/qquickcomponentsprivate.h
index 5352ab941..2f9c9ecff 100644
--- a/src/qtooltiparea.h
+++ b/src/qquickcomponentsprivate.h
@@ -38,40 +38,21 @@
 **
 ****************************************************************************/
 
-#ifndef QTOOLTIPAREA_H
-#define QTOOLTIPAREA_H
+#ifndef QQUICKCOMPONENTSPRIVATE_H
+#define QQUICKCOMPONENTSPRIVATE_H
 
+#include <QObject>
 #include <QQuickItem>
-#include <QTimer>
-#include <QtWidgets/QGraphicsSceneHoverEvent>
 
-class QTooltipArea : public QQuickItem
+class QQuickComponentsPrivate : public QObject
 {
     Q_OBJECT
-    Q_PROPERTY(QString text READ text WRITE setText NOTIFY textChanged)
-    Q_PROPERTY(bool containsMouse READ containsMouse NOTIFY containsMouseChanged)
 
 public:
-    QTooltipArea(QQuickItem *parent = 0);
-    void setText(const QString &t);
-    QString text() const {return m_text;}
-    bool containsMouse() const {return m_containsMouse;}
-    void showToolTip(const QString &str) const;
-    void hoverEnterEvent(QHoverEvent *event);
-    void hoverLeaveEvent(QHoverEvent *event);
+    QQuickComponentsPrivate(QObject *parent = 0);
 
-public slots:
-    void timeout();
-
-signals:
-    void textChanged();
-    void containsMouseChanged();
-
-private:
-
-    QTimer m_tiptimer;
-    QString m_text;
-    bool m_containsMouse;
+    Q_INVOKABLE void showToolTip(QQuickItem *item, const QPointF &pos, const QString &text);
+    Q_INVOKABLE void hideToolTip();
 };
 
-#endif // QTOOLTIPAREA_H
+#endif
diff --git a/src/qstyleplugin.cpp b/src/qstyleplugin.cpp
index e375d2538..4cf7a825f 100644
--- a/src/qstyleplugin.cpp
+++ b/src/qstyleplugin.cpp
@@ -49,9 +49,9 @@
 #include "qdesktopitem.h"
 #include "qwheelarea.h"
 #include "qcursorarea.h"
-#include "qtooltiparea.h"
 #include "qtsplitterbase.h"
 #include "qquicklinearlayout.h"
+#include "qquickcomponentsprivate.h"
 #include <qqmlextensionplugin.h>
 
 #include <qqmlengine.h>
@@ -79,12 +79,20 @@ public:
     }
 };
 
+QObject *registerPrivateModule(QQmlEngine *engine, QJSEngine *jsEngine)
+{
+    Q_UNUSED(engine);
+    Q_UNUSED(jsEngine);
+    return new QQuickComponentsPrivate();
+}
 
 void StylePlugin::registerTypes(const char *uri)
 {
+    qmlRegisterModuleApi<QQuickComponentsPrivate>(QByteArray(uri) + ".Internal",
+                                                  0, 2, registerPrivateModule);
+
     qmlRegisterType<QStyleItem>(uri, 0, 2, "StyleItem");
     qmlRegisterType<QCursorArea>(uri, 0, 2, "CursorArea");
-    qmlRegisterType<QTooltipArea>(uri, 0, 2, "TooltipArea");
     qmlRegisterType<QRangeModel>(uri, 0, 2, "RangeModel");
     qmlRegisterType<QWheelArea>(uri, 0, 2, "WheelArea");
 
diff --git a/src/src.pro b/src/src.pro
index 353ab5ccb..54fe2cc34 100644
--- a/src/src.pro
+++ b/src/src.pro
@@ -25,7 +25,7 @@ HEADERS += qtmenu.h \
            qquicklayoutengine_p.h \
            qquicklayout.h \
            qquicklinearlayout.h \
-           qtooltiparea.h \
+           qquickcomponentsprivate.h \
            qtsplitterbase.h
 
 SOURCES += qtmenu.cpp \
@@ -39,10 +39,10 @@ SOURCES += qtmenu.cpp \
            qdesktopitem.cpp \
            qtoplevelwindow.cpp \
            qcursorarea.cpp \
-           qtooltiparea.cpp \
            qquicklayout.cpp \
            qquicklayoutengine.cpp \
            qquicklinearlayout.cpp \
+           qquickcomponentsprivate.cpp \
            qtsplitterbase.cpp
 
 TARGETPATH = QtDesktop/plugin
-- 
GitLab