click_handler.h 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155
  1. // This file is part of Desktop App Toolkit,
  2. // a set of libraries for developing nice desktop applications.
  3. //
  4. // For license and copyright information please follow this link:
  5. // https://github.com/desktop-app/legal/blob/master/LEGAL
  6. //
  7. #pragma once
  8. #include "base/basic_types.h"
  9. #include "base/flat_map.h"
  10. #include <QtCore/QVariant>
  11. class ClickHandler;
  12. using ClickHandlerPtr = std::shared_ptr<ClickHandler>;
  13. struct ClickContext {
  14. Qt::MouseButton button = Qt::LeftButton;
  15. QVariant other;
  16. };
  17. class ClickHandlerHost {
  18. protected:
  19. virtual void clickHandlerActiveChanged(const ClickHandlerPtr &action, bool active) {
  20. }
  21. virtual void clickHandlerPressedChanged(const ClickHandlerPtr &action, bool pressed) {
  22. }
  23. virtual ~ClickHandlerHost() = 0;
  24. friend class ClickHandler;
  25. };
  26. enum class EntityType : uchar;
  27. class ClickHandler {
  28. public:
  29. virtual ~ClickHandler() {
  30. }
  31. virtual void onClick(ClickContext context) const = 0;
  32. // Some sort of `id`, for text links contains urls.
  33. virtual QString url() const {
  34. return QString();
  35. }
  36. // What text to show in a tooltip when mouse is over that click handler as a link in Text.
  37. virtual QString tooltip() const {
  38. return QString();
  39. }
  40. // What to drop in the input fields when dragging that click handler as a link from Text.
  41. virtual QString dragText() const {
  42. return QString();
  43. }
  44. // Copy to clipboard support.
  45. virtual QString copyToClipboardText() const {
  46. return QString();
  47. }
  48. virtual QString copyToClipboardContextItemText() const {
  49. return QString();
  50. }
  51. // Entities in text support.
  52. struct TextEntity {
  53. EntityType type = EntityType();
  54. QString data;
  55. };
  56. virtual TextEntity getTextEntity() const;
  57. void setProperty(int id, QVariant value);
  58. [[nodiscard]] const QVariant &property(int id) const;
  59. // This method should be called on mouse over a click handler.
  60. // It returns true if the active handler was changed or false otherwise.
  61. static bool setActive(const ClickHandlerPtr &p, ClickHandlerHost *host = nullptr);
  62. // This method should be called when mouse leaves the host.
  63. // It returns true if the active handler was changed or false otherwise.
  64. static bool clearActive(ClickHandlerHost *host = nullptr);
  65. // This method should be called on mouse press event.
  66. static void pressed();
  67. // This method should be called on mouse release event.
  68. // The activated click handler (if any) is returned.
  69. static ClickHandlerPtr unpressed();
  70. static ClickHandlerPtr getActive();
  71. static ClickHandlerPtr getPressed();
  72. static bool showAsActive(const ClickHandlerPtr &p);
  73. static bool showAsPressed(const ClickHandlerPtr &p);
  74. static void hostDestroyed(ClickHandlerHost *host);
  75. private:
  76. static ClickHandlerHost *_activeHost;
  77. static ClickHandlerHost *_pressedHost;
  78. base::flat_map<int, QVariant> _properties;
  79. };
  80. class LeftButtonClickHandler : public ClickHandler {
  81. public:
  82. void onClick(ClickContext context) const override final {
  83. if (context.button == Qt::LeftButton) {
  84. onClickImpl();
  85. }
  86. }
  87. protected:
  88. virtual void onClickImpl() const = 0;
  89. };
  90. class GenericClickHandler : public ClickHandler {
  91. public:
  92. GenericClickHandler(Fn<void()> handler)
  93. : _handler([handler = std::move(handler)](ClickContext) { handler(); }) {
  94. }
  95. GenericClickHandler(Fn<void(ClickContext)> handler)
  96. : _handler(std::move(handler)) {
  97. }
  98. void onClick(ClickContext context) const override {
  99. if (_handler) {
  100. _handler(context);
  101. }
  102. }
  103. private:
  104. Fn<void(ClickContext)> _handler;
  105. };
  106. class LambdaClickHandler : public GenericClickHandler {
  107. public:
  108. using GenericClickHandler::GenericClickHandler;
  109. void onClick(ClickContext context) const override final {
  110. if (context.button == Qt::LeftButton) {
  111. GenericClickHandler::onClick(std::move(context));
  112. }
  113. }
  114. };
  115. void ActivateClickHandler(
  116. not_null<QWidget*> guard,
  117. ClickHandlerPtr handler,
  118. ClickContext context);
  119. void ActivateClickHandler(
  120. not_null<QWidget*> guard,
  121. ClickHandlerPtr handler,
  122. Qt::MouseButton button);