Added ability to set pinned items for vertical layout reorder.
This commit is contained in:
parent
060eb63ce8
commit
e2304a3c76
2 changed files with 40 additions and 1 deletions
|
|
@ -75,6 +75,24 @@ void VerticalLayoutReorder::start() {
|
|||
}
|
||||
}
|
||||
|
||||
void VerticalLayoutReorder::addPinnedInterval(int from, int length) {
|
||||
_pinnedIntervals.push_back({ from, length });
|
||||
}
|
||||
|
||||
void VerticalLayoutReorder::clearPinnedIntervals() {
|
||||
_pinnedIntervals.clear();
|
||||
}
|
||||
|
||||
bool VerticalLayoutReorder::Interval::isIn(int index) const {
|
||||
return (index >= from) && (index < (from + length));
|
||||
}
|
||||
|
||||
bool VerticalLayoutReorder::isIndexPinned(int index) const {
|
||||
return ranges::any_of(_pinnedIntervals, [&](const Interval &i) {
|
||||
return i.isIn(index);
|
||||
});
|
||||
}
|
||||
|
||||
void VerticalLayoutReorder::mouseMove(
|
||||
not_null<RpWidget*> widget,
|
||||
QPoint position) {
|
||||
|
|
@ -105,6 +123,9 @@ void VerticalLayoutReorder::checkForStart(QPoint position) {
|
|||
}
|
||||
|
||||
void VerticalLayoutReorder::updateOrder(int index, QPoint position) {
|
||||
if (isIndexPinned(index)) {
|
||||
return;
|
||||
}
|
||||
const auto shift = position.y() - _currentStart;
|
||||
auto ¤t = _entries[index];
|
||||
current.shiftAnimation.stop();
|
||||
|
|
@ -120,6 +141,9 @@ void VerticalLayoutReorder::updateOrder(int index, QPoint position) {
|
|||
if (shift > 0) {
|
||||
auto top = current.widget->y() - shift;
|
||||
for (auto next = index + 1; next != count; ++next) {
|
||||
if (isIndexPinned(next)) {
|
||||
return;
|
||||
}
|
||||
const auto &entry = _entries[next];
|
||||
top += entry.widget->height();
|
||||
if (currentMiddle < top) {
|
||||
|
|
@ -137,6 +161,9 @@ void VerticalLayoutReorder::updateOrder(int index, QPoint position) {
|
|||
moveToShift(next, 0);
|
||||
}
|
||||
for (auto prev = index - 1; prev >= 0; --prev) {
|
||||
if (isIndexPinned(prev)) {
|
||||
return;
|
||||
}
|
||||
const auto &entry = _entries[prev];
|
||||
if (currentMiddle >= entry.widget->y() - entry.shift + currentHeight) {
|
||||
moveToShift(prev, 0);
|
||||
|
|
|
|||
|
|
@ -36,6 +36,8 @@ public:
|
|||
void start();
|
||||
void cancel();
|
||||
void finishReordering();
|
||||
void addPinnedInterval(int from, int length);
|
||||
void clearPinnedIntervals();
|
||||
[[nodiscard]] rpl::producer<Single> updates() const;
|
||||
|
||||
private:
|
||||
|
|
@ -46,6 +48,12 @@ private:
|
|||
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(
|
||||
|
|
@ -66,13 +74,17 @@ private:
|
|||
|
||||
void updateScrollCallback();
|
||||
void checkForScrollAnimation();
|
||||
int deltaFromEdge();
|
||||
[[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;
|
||||
|
||||
RpWidget *_currentWidget = nullptr;
|
||||
int _currentStart = 0;
|
||||
int _currentDesiredIndex = 0;
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue