vertical_layout_reorder.h 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102
  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 "ui/effects/animations.h"
  9. #include "ui/widgets/scroll_area.h"
  10. namespace Ui {
  11. class RpWidget;
  12. class VerticalLayout;
  13. class VerticalLayoutReorder final {
  14. public:
  15. using ProxyCallback = Fn<not_null<Ui::RpWidget*>(int)>;
  16. enum class State : uchar {
  17. Started,
  18. Applied,
  19. Cancelled,
  20. };
  21. struct Single {
  22. not_null<RpWidget*> widget;
  23. int oldPosition = 0;
  24. int newPosition = 0;
  25. State state = State::Started;
  26. };
  27. VerticalLayoutReorder(
  28. not_null<VerticalLayout*> layout,
  29. not_null<ScrollArea*> scroll);
  30. VerticalLayoutReorder(not_null<VerticalLayout*> layout);
  31. void start();
  32. void cancel();
  33. void finishReordering();
  34. void addPinnedInterval(int from, int length);
  35. void clearPinnedIntervals();
  36. void setMouseEventProxy(ProxyCallback callback);
  37. [[nodiscard]] rpl::producer<Single> updates() const;
  38. private:
  39. struct Entry {
  40. not_null<RpWidget*> widget;
  41. Ui::Animations::Simple shiftAnimation;
  42. int shift = 0;
  43. int finalShift = 0;
  44. int deltaShift = 0;
  45. };
  46. struct Interval {
  47. [[nodiscard]] bool isIn(int index) const;
  48. int from = 0;
  49. int length = 0;
  50. };
  51. void mouseMove(not_null<RpWidget*> widget, QPoint position);
  52. void mousePress(
  53. not_null<RpWidget*> widget,
  54. Qt::MouseButton button,
  55. QPoint position);
  56. void mouseRelease(Qt::MouseButton button);
  57. void checkForStart(QPoint position);
  58. void updateOrder(int index, QPoint position);
  59. void cancelCurrent();
  60. void finishCurrent();
  61. void cancelCurrent(int index);
  62. [[nodiscard]] int indexOf(not_null<RpWidget*> widget) const;
  63. void moveToShift(int index, int shift);
  64. void updateShift(not_null<RpWidget*> widget, int indexHint);
  65. void updateScrollCallback();
  66. void checkForScrollAnimation();
  67. [[nodiscard]] int deltaFromEdge();
  68. [[nodiscard]] bool isIndexPinned(int index) const;
  69. const not_null<Ui::VerticalLayout*> _layout;
  70. Ui::ScrollArea *_scroll = nullptr;
  71. Ui::Animations::Basic _scrollAnimation;
  72. std::vector<Interval> _pinnedIntervals;
  73. ProxyCallback _proxyWidgetCallback = nullptr;
  74. RpWidget *_currentWidget = nullptr;
  75. int _currentStart = 0;
  76. int _currentDesiredIndex = 0;
  77. State _currentState = State::Cancelled;
  78. std::vector<Entry> _entries;
  79. rpl::event_stream<Single> _updates;
  80. rpl::lifetime _lifetime;
  81. };
  82. } // namespace Ui