Line data Source code
1 : /*
2 : * SPDX-License-Identifier: GPL-3.0-only
3 : * MuseScore-CLA-applies
4 : *
5 : * MuseScore Studio
6 : * Music Composition & Notation
7 : *
8 : * Copyright (C) 2021 MuseScore Limited and others
9 : *
10 : * This program is free software: you can redistribute it and/or modify
11 : * it under the terms of the GNU General Public License version 3 as
12 : * published by the Free Software Foundation.
13 : *
14 : * This program is distributed in the hope that it will be useful,
15 : * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 : * GNU General Public License for more details.
18 : *
19 : * You should have received a copy of the GNU General Public License
20 : * along with this program. If not, see <https://www.gnu.org/licenses/>.
21 : */
22 : #include "qmltooltip.h"
23 :
24 : #include <QGuiApplication>
25 :
26 : using namespace muse::ui;
27 :
28 4 : QmlToolTip::QmlToolTip(QObject* parent, const modularity::ContextPtr& iocCtx)
29 4 : : QObject(parent), Contextable(iocCtx)
30 : {
31 4 : connect(&m_openTimer, &QTimer::timeout, this, &QmlToolTip::doShow);
32 :
33 4 : m_closeTimer.setSingleShot(true);
34 4 : connect(&m_closeTimer, &QTimer::timeout, this, &QmlToolTip::doHide);
35 :
36 4 : qApp->installEventFilter(this);
37 4 : }
38 :
39 4 : void QmlToolTip::show(QQuickItem* item, const QString& title, const QString& description, const QString& shortcut)
40 : {
41 4 : if (item == m_item) {
42 0 : m_closeTimer.stop();
43 0 : return;
44 : }
45 :
46 4 : m_title = title;
47 4 : m_description = description;
48 4 : m_shortcut = shortcut;
49 :
50 4 : bool toolTipNotOpened = m_item == nullptr;
51 4 : bool openTimerStarted = m_openTimer.isActive();
52 :
53 4 : m_item = item;
54 4 : m_shouldBeClosed = false;
55 :
56 4 : if (m_item) {
57 4 : connect(m_item, &QObject::destroyed, this, &QmlToolTip::onItemDestruction);
58 : }
59 :
60 4 : if (toolTipNotOpened || openTimerStarted) {
61 4 : m_openTimer.start(uiConfiguration()->tooltipDelay());
62 : } else {
63 0 : doShow();
64 : }
65 : }
66 :
67 2 : void QmlToolTip::hide(QQuickItem* item, bool force)
68 : {
69 2 : if (m_item != item) {
70 0 : return;
71 : }
72 :
73 2 : m_shouldBeClosed = true;
74 :
75 2 : if (force) {
76 2 : doHide();
77 2 : return;
78 : }
79 :
80 0 : m_closeTimer.start(uiConfiguration()->tooltipDelay());
81 : }
82 :
83 0 : void QmlToolTip::close()
84 : {
85 0 : m_shouldBeClosed = true;
86 0 : doHide();
87 0 : }
88 :
89 2 : void QmlToolTip::doShow()
90 : {
91 2 : m_openTimer.stop();
92 2 : m_closeTimer.stop();
93 :
94 2 : if (!m_item) {
95 0 : return;
96 : }
97 :
98 2 : if (m_shouldBeClosed) {
99 0 : clear();
100 0 : return;
101 : }
102 :
103 2 : emit showToolTip(m_item, m_title, m_description, m_shortcut);
104 : }
105 :
106 2 : void QmlToolTip::onItemDestruction()
107 : {
108 2 : m_shouldBeClosed = true;
109 2 : doHide();
110 2 : }
111 :
112 4 : void QmlToolTip::doHide()
113 : {
114 4 : if (!m_shouldBeClosed) {
115 0 : return;
116 : }
117 :
118 4 : m_openTimer.stop();
119 4 : m_closeTimer.stop();
120 :
121 4 : clear();
122 :
123 4 : emit hideToolTip();
124 : }
125 :
126 185 : bool QmlToolTip::eventFilter(QObject*, QEvent* event)
127 : {
128 185 : if (event->type() == QEvent::Wheel) {
129 0 : m_shouldBeClosed = true;
130 0 : doHide();
131 : }
132 :
133 185 : return false;
134 : }
135 :
136 4 : void QmlToolTip::clear()
137 : {
138 4 : if (m_item) {
139 4 : disconnect(m_item, &QObject::destroyed, this, &QmlToolTip::onItemDestruction);
140 : }
141 :
142 4 : m_item = nullptr;
143 4 : m_title = QString();
144 4 : m_description = QString();
145 4 : m_shortcut = QString();
146 :
147 4 : m_shouldBeClosed = false;
148 4 : }
|