102 lines
2.4 KiB
C++
102 lines
2.4 KiB
C++
// This file is part of Desktop App Toolkit,
|
|
// a set of libraries for developing nice desktop applications.
|
|
//
|
|
// For license and copyright information please follow this link:
|
|
// https://github.com/desktop-app/legal/blob/master/LEGAL
|
|
//
|
|
#pragma once
|
|
|
|
#include "ui/effects/animations.h"
|
|
#include "ui/widgets/scroll_area.h"
|
|
|
|
namespace Ui {
|
|
|
|
class RpWidget;
|
|
class VerticalLayout;
|
|
|
|
class VerticalLayoutReorder final {
|
|
public:
|
|
using ProxyCallback = Fn<not_null<Ui::RpWidget*>(int)>;
|
|
enum class State : uchar {
|
|
Started,
|
|
Applied,
|
|
Cancelled,
|
|
};
|
|
struct Single {
|
|
not_null<RpWidget*> widget;
|
|
int oldPosition = 0;
|
|
int newPosition = 0;
|
|
State state = State::Started;
|
|
};
|
|
|
|
VerticalLayoutReorder(
|
|
not_null<VerticalLayout*> layout,
|
|
not_null<ScrollArea*> scroll);
|
|
VerticalLayoutReorder(not_null<VerticalLayout*> layout);
|
|
|
|
void start();
|
|
void cancel();
|
|
void finishReordering();
|
|
void addPinnedInterval(int from, int length);
|
|
void clearPinnedIntervals();
|
|
void setMouseEventProxy(ProxyCallback callback);
|
|
[[nodiscard]] rpl::producer<Single> updates() const;
|
|
|
|
private:
|
|
struct Entry {
|
|
not_null<RpWidget*> widget;
|
|
Ui::Animations::Simple shiftAnimation;
|
|
int shift = 0;
|
|
int finalShift = 0;
|
|
int deltaShift = 0;
|
|
};
|
|
struct Interval {
|
|
[[nodiscard]] bool isIn(int index) const;
|
|
|
|
int from = 0;
|
|
int length = 0;
|
|
};
|
|
|
|
void mouseMove(not_null<RpWidget*> widget, QPoint position);
|
|
void mousePress(
|
|
not_null<RpWidget*> widget,
|
|
Qt::MouseButton button,
|
|
QPoint position);
|
|
void mouseRelease(Qt::MouseButton button);
|
|
|
|
void checkForStart(QPoint position);
|
|
void updateOrder(int index, QPoint position);
|
|
void cancelCurrent();
|
|
void finishCurrent();
|
|
void cancelCurrent(int index);
|
|
|
|
[[nodiscard]] int indexOf(not_null<RpWidget*> widget) const;
|
|
void moveToShift(int index, int shift);
|
|
void updateShift(not_null<RpWidget*> widget, int indexHint);
|
|
|
|
void updateScrollCallback();
|
|
void checkForScrollAnimation();
|
|
[[nodiscard]] int deltaFromEdge();
|
|
|
|
[[nodiscard]] bool isIndexPinned(int index) const;
|
|
|
|
const not_null<Ui::VerticalLayout*> _layout;
|
|
Ui::ScrollArea *_scroll = nullptr;
|
|
|
|
Ui::Animations::Basic _scrollAnimation;
|
|
|
|
std::vector<Interval> _pinnedIntervals;
|
|
|
|
ProxyCallback _proxyWidgetCallback = nullptr;
|
|
|
|
RpWidget *_currentWidget = nullptr;
|
|
int _currentStart = 0;
|
|
int _currentDesiredIndex = 0;
|
|
State _currentState = State::Cancelled;
|
|
std::vector<Entry> _entries;
|
|
rpl::event_stream<Single> _updates;
|
|
rpl::lifetime _lifetime;
|
|
|
|
};
|
|
|
|
} // namespace Ui
|