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(
|
void VerticalLayoutReorder::mouseMove(
|
||||||
not_null<RpWidget*> widget,
|
not_null<RpWidget*> widget,
|
||||||
QPoint position) {
|
QPoint position) {
|
||||||
|
|
@ -105,6 +123,9 @@ void VerticalLayoutReorder::checkForStart(QPoint position) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void VerticalLayoutReorder::updateOrder(int index, QPoint position) {
|
void VerticalLayoutReorder::updateOrder(int index, QPoint position) {
|
||||||
|
if (isIndexPinned(index)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
const auto shift = position.y() - _currentStart;
|
const auto shift = position.y() - _currentStart;
|
||||||
auto ¤t = _entries[index];
|
auto ¤t = _entries[index];
|
||||||
current.shiftAnimation.stop();
|
current.shiftAnimation.stop();
|
||||||
|
|
@ -120,6 +141,9 @@ void VerticalLayoutReorder::updateOrder(int index, QPoint position) {
|
||||||
if (shift > 0) {
|
if (shift > 0) {
|
||||||
auto top = current.widget->y() - shift;
|
auto top = current.widget->y() - shift;
|
||||||
for (auto next = index + 1; next != count; ++next) {
|
for (auto next = index + 1; next != count; ++next) {
|
||||||
|
if (isIndexPinned(next)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
const auto &entry = _entries[next];
|
const auto &entry = _entries[next];
|
||||||
top += entry.widget->height();
|
top += entry.widget->height();
|
||||||
if (currentMiddle < top) {
|
if (currentMiddle < top) {
|
||||||
|
|
@ -137,6 +161,9 @@ void VerticalLayoutReorder::updateOrder(int index, QPoint position) {
|
||||||
moveToShift(next, 0);
|
moveToShift(next, 0);
|
||||||
}
|
}
|
||||||
for (auto prev = index - 1; prev >= 0; --prev) {
|
for (auto prev = index - 1; prev >= 0; --prev) {
|
||||||
|
if (isIndexPinned(prev)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
const auto &entry = _entries[prev];
|
const auto &entry = _entries[prev];
|
||||||
if (currentMiddle >= entry.widget->y() - entry.shift + currentHeight) {
|
if (currentMiddle >= entry.widget->y() - entry.shift + currentHeight) {
|
||||||
moveToShift(prev, 0);
|
moveToShift(prev, 0);
|
||||||
|
|
|
||||||
|
|
@ -36,6 +36,8 @@ public:
|
||||||
void start();
|
void start();
|
||||||
void cancel();
|
void cancel();
|
||||||
void finishReordering();
|
void finishReordering();
|
||||||
|
void addPinnedInterval(int from, int length);
|
||||||
|
void clearPinnedIntervals();
|
||||||
[[nodiscard]] rpl::producer<Single> updates() const;
|
[[nodiscard]] rpl::producer<Single> updates() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
@ -46,6 +48,12 @@ private:
|
||||||
int finalShift = 0;
|
int finalShift = 0;
|
||||||
int deltaShift = 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 mouseMove(not_null<RpWidget*> widget, QPoint position);
|
||||||
void mousePress(
|
void mousePress(
|
||||||
|
|
@ -66,13 +74,17 @@ private:
|
||||||
|
|
||||||
void updateScrollCallback();
|
void updateScrollCallback();
|
||||||
void checkForScrollAnimation();
|
void checkForScrollAnimation();
|
||||||
int deltaFromEdge();
|
[[nodiscard]] int deltaFromEdge();
|
||||||
|
|
||||||
|
[[nodiscard]] bool isIndexPinned(int index) const;
|
||||||
|
|
||||||
const not_null<Ui::VerticalLayout*> _layout;
|
const not_null<Ui::VerticalLayout*> _layout;
|
||||||
Ui::ScrollArea *_scroll = nullptr;
|
Ui::ScrollArea *_scroll = nullptr;
|
||||||
|
|
||||||
Ui::Animations::Basic _scrollAnimation;
|
Ui::Animations::Basic _scrollAnimation;
|
||||||
|
|
||||||
|
std::vector<Interval> _pinnedIntervals;
|
||||||
|
|
||||||
RpWidget *_currentWidget = nullptr;
|
RpWidget *_currentWidget = nullptr;
|
||||||
int _currentStart = 0;
|
int _currentStart = 0;
|
||||||
int _currentDesiredIndex = 0;
|
int _currentDesiredIndex = 0;
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue