menu_item_base.cpp 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119
  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. #include "ui/widgets/menu/menu_item_base.h"
  8. namespace Ui::Menu {
  9. ItemBase::ItemBase(
  10. not_null<RpWidget*> parent,
  11. const style::Menu &st)
  12. : RippleButton(parent, st.ripple) {
  13. }
  14. void ItemBase::setSelected(
  15. bool selected,
  16. TriggeredSource source) {
  17. if (selected && !isEnabled()) {
  18. return;
  19. }
  20. if (_selected.current() != selected) {
  21. setMouseTracking(!selected);
  22. _lastTriggeredSource = source;
  23. _selected = selected;
  24. update();
  25. }
  26. }
  27. bool ItemBase::isSelected() const {
  28. return _selected.current();
  29. }
  30. rpl::producer<CallbackData> ItemBase::selects() const {
  31. return _selected.changes(
  32. ) | rpl::map([=](bool selected) -> CallbackData {
  33. return { action(), y(), _lastTriggeredSource, _index, selected };
  34. });
  35. }
  36. TriggeredSource ItemBase::lastTriggeredSource() const {
  37. return _lastTriggeredSource;
  38. }
  39. int ItemBase::index() const {
  40. return _index;
  41. }
  42. void ItemBase::setIndex(int index) {
  43. _index = index;
  44. }
  45. void ItemBase::setClicked(TriggeredSource source) {
  46. if (isEnabled()) {
  47. _lastTriggeredSource = source;
  48. _clicks.fire({});
  49. }
  50. }
  51. rpl::producer<CallbackData> ItemBase::clicks() const {
  52. return rpl::merge(
  53. AbstractButton::clicks() | rpl::to_empty,
  54. _clicks.events()
  55. ) | rpl::filter([=] {
  56. return isEnabled() && !AbstractButton::isDisabled();
  57. }) | rpl::map([=]() -> CallbackData {
  58. return { action(), y(), _lastTriggeredSource, _index, true };
  59. });
  60. }
  61. rpl::producer<int> ItemBase::minWidthValue() const {
  62. return _minWidth.value();
  63. }
  64. int ItemBase::minWidth() const {
  65. return _minWidth.current();
  66. }
  67. void ItemBase::initResizeHook(rpl::producer<QSize> &&size) {
  68. std::move(
  69. size
  70. ) | rpl::start_with_next([=](QSize s) {
  71. resize(s.width(), contentHeight());
  72. }, lifetime());
  73. }
  74. void ItemBase::setMinWidth(int w) {
  75. _minWidth = w;
  76. }
  77. void ItemBase::finishAnimating() {
  78. RippleButton::finishAnimating();
  79. }
  80. void ItemBase::enableMouseSelecting() {
  81. enableMouseSelecting(this);
  82. }
  83. void ItemBase::enableMouseSelecting(not_null<RpWidget*> widget) {
  84. widget->events(
  85. ) | rpl::start_with_next([=](not_null<QEvent*> e) {
  86. const auto type = e->type();
  87. if (((type == QEvent::Leave)
  88. || (type == QEvent::Enter)
  89. || (type == QEvent::MouseMove)) && action()->isEnabled()) {
  90. setSelected(e->type() != QEvent::Leave);
  91. } else if ((type == QEvent::MouseButtonRelease)
  92. && isEnabled()
  93. && isSelected()) {
  94. const auto point = mapFromGlobal(QCursor::pos());
  95. if (!rect().contains(point)) {
  96. setSelected(false);
  97. }
  98. }
  99. }, lifetime());
  100. }
  101. } // namespace Ui::Menu