abstract_button.h 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116
  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 <rpl/event_stream.h>
  9. #include "ui/rp_widget.h"
  10. #include "base/flags.h"
  11. namespace Ui {
  12. class AbstractButton : public RpWidget {
  13. public:
  14. AbstractButton(QWidget *parent);
  15. [[nodiscard]] Qt::KeyboardModifiers clickModifiers() const {
  16. return _modifiers;
  17. }
  18. void setDisabled(bool disabled = true);
  19. virtual void clearState();
  20. [[nodiscard]] bool isOver() const {
  21. return _state & StateFlag::Over;
  22. }
  23. [[nodiscard]] bool isDown() const {
  24. return _state & StateFlag::Down;
  25. }
  26. [[nodiscard]] bool isDisabled() const {
  27. return _state & StateFlag::Disabled;
  28. }
  29. void setSynteticOver(bool over) {
  30. setOver(over, StateChangeSource::ByPress);
  31. }
  32. void setSynteticDown(bool down, Qt::MouseButton button = Qt::LeftButton) {
  33. setDown(down, StateChangeSource::ByPress, {}, button);
  34. }
  35. void setPointerCursor(bool enablePointerCursor);
  36. void setAcceptBoth(bool acceptBoth = true);
  37. void setClickedCallback(Fn<void()> callback) {
  38. _clickedCallback = std::move(callback);
  39. }
  40. rpl::producer<Qt::MouseButton> clicks() const {
  41. return _clicks.events();
  42. }
  43. template <typename Handler>
  44. void addClickHandler(Handler &&handler) {
  45. clicks(
  46. ) | rpl::start_with_next(
  47. std::forward<Handler>(handler),
  48. lifetime());
  49. }
  50. void clicked(Qt::KeyboardModifiers modifiers, Qt::MouseButton button);
  51. protected:
  52. void enterEventHook(QEnterEvent *e) override;
  53. void leaveEventHook(QEvent *e) override;
  54. void mousePressEvent(QMouseEvent *e) override;
  55. void mouseMoveEvent(QMouseEvent *e) override;
  56. void mouseReleaseEvent(QMouseEvent *e) override;
  57. protected:
  58. enum class StateFlag {
  59. None = 0,
  60. Over = (1 << 0),
  61. Down = (1 << 1),
  62. Disabled = (1 << 2),
  63. };
  64. friend constexpr bool is_flag_type(StateFlag) { return true; };
  65. using State = base::flags<StateFlag>;
  66. State state() const {
  67. return _state;
  68. }
  69. enum class StateChangeSource {
  70. ByUser = 0x00,
  71. ByPress = 0x01,
  72. ByHover = 0x02,
  73. };
  74. void setOver(bool over, StateChangeSource source = StateChangeSource::ByUser);
  75. bool setDown(
  76. bool down,
  77. StateChangeSource source,
  78. Qt::KeyboardModifiers modifiers,
  79. Qt::MouseButton button);
  80. virtual void onStateChanged(State was, StateChangeSource source) {
  81. }
  82. private:
  83. void updateCursor();
  84. void checkIfOver(QPoint localPos);
  85. State _state = StateFlag::None;
  86. Qt::KeyboardModifiers _modifiers;
  87. bool _enablePointerCursor = true;
  88. bool _pointerCursor = false;
  89. bool _acceptBoth = false;
  90. Fn<void()> _clickedCallback;
  91. rpl::event_stream<Qt::MouseButton> _clicks;
  92. };
  93. } // namespace Ui