summaryrefslogtreecommitdiff
path: root/Source/Core/DolphinQt/Config/ToolTipControls/ToolTipWidget.h
blob: 94cd88b87e22eeeb796aec096e4ea563659969f1 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
// Copyright 2020 Dolphin Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later

#pragma once

#include <optional>

#include <QString>

#include "DolphinQt/Config/ToolTipControls/BalloonTip.h"

class QEnterEvent;
class QEvent;
class QHideEvent;
class QTimerEvent;

constexpr int TOOLTIP_DELAY = 300;

template <class Derived>
class ToolTipWidget : public Derived
{
public:
  using Derived::Derived;

  void SetTitle(QString title) { m_title = std::move(title); }

  void SetDescription(QString description) { m_description = std::move(description); }

private:
  void enterEvent(QEnterEvent* const event) override
  {
    // If the timer is already running, or the cursor is reentering the ToolTipWidget after having
    // hovered over the BalloonTip, don't start a new timer.
    if (!m_timer_id && !BalloonTip::IsWidgetBalloonTipActive(*this))
      m_timer_id = this->startTimer(TOOLTIP_DELAY);

    Derived::enterEvent(event);
  }

  void leaveEvent(QEvent* const event) override
  {
    // If the cursor would still be inside the ToolTipWidget but the BalloonTip is covering that
    // part of it, keep the BalloonTip open. In that case the BalloonTip will then track the cursor
    // and close itself if it leaves the bounding box of this ToolTipWidget.
    if (!BalloonTip::IsCursorInsideWidgetBoundingBox(*this) || !BalloonTip::IsCursorOnBalloonTip())
      KillTimerAndHideBalloon();

    Derived::leaveEvent(event);
  }

  void hideEvent(QHideEvent* const event) override
  {
    KillTimerAndHideBalloon();

    Derived::hideEvent(event);
  }

  void timerEvent(QTimerEvent* const event) override
  {
    this->killTimer(*m_timer_id);
    m_timer_id.reset();

    BalloonTip::ShowBalloon(m_title, m_description,
                            this->parentWidget()->mapToGlobal(GetToolTipPosition()), this);

    Derived::timerEvent(event);
  }

  virtual QPoint GetToolTipPosition() const = 0;

  void KillTimerAndHideBalloon()
  {
    if (m_timer_id)
    {
      this->killTimer(*m_timer_id);
      m_timer_id.reset();
    }
    BalloonTip::HideBalloon();
  }

  std::optional<int> m_timer_id;
  QString m_title;
  QString m_description;
};