Implement animated VerticalLayout reordering.
This commit is contained in:
parent
b051948e69
commit
eaab3f9a8a
3 changed files with 65 additions and 6 deletions
|
|
@ -55,6 +55,7 @@ void VerticalLayout::setVerticalShift(int index, int shift) {
|
||||||
if (const auto delta = shift - row.verticalShift) {
|
if (const auto delta = shift - row.verticalShift) {
|
||||||
row.verticalShift = shift;
|
row.verticalShift = shift;
|
||||||
row.widget->move(row.widget->x(), row.widget->y() + delta);
|
row.widget->move(row.widget->x(), row.widget->y() + delta);
|
||||||
|
row.widget->update();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,7 @@
|
||||||
#include "ui/wrap/vertical_layout_reorder.h"
|
#include "ui/wrap/vertical_layout_reorder.h"
|
||||||
|
|
||||||
#include "ui/wrap/vertical_layout.h"
|
#include "ui/wrap/vertical_layout.h"
|
||||||
|
#include "styles/style_basic.h"
|
||||||
|
|
||||||
#include <QtGui/QtEvents>
|
#include <QtGui/QtEvents>
|
||||||
#include <QtWidgets/QApplication>
|
#include <QtWidgets/QApplication>
|
||||||
|
|
@ -95,7 +96,8 @@ void VerticalLayoutReorder::checkForStart(QPoint position) {
|
||||||
void VerticalLayoutReorder::updateOrder(int index, QPoint position) {
|
void VerticalLayoutReorder::updateOrder(int index, QPoint position) {
|
||||||
const auto shift = position.y() - _currentStart;
|
const auto shift = position.y() - _currentStart;
|
||||||
auto ¤t = _entries[index];
|
auto ¤t = _entries[index];
|
||||||
current.shift = shift;
|
current.shiftAnimation.stop();
|
||||||
|
current.shift = current.finalShift = shift;
|
||||||
_layout->setVerticalShift(index, shift);
|
_layout->setVerticalShift(index, shift);
|
||||||
|
|
||||||
const auto count = _entries.size();
|
const auto count = _entries.size();
|
||||||
|
|
@ -186,19 +188,69 @@ void VerticalLayoutReorder::finishCurrent() {
|
||||||
const auto widget = _currentWidget;
|
const auto widget = _currentWidget;
|
||||||
_currentState = State::Cancelled;
|
_currentState = State::Cancelled;
|
||||||
_currentWidget = nullptr;
|
_currentWidget = nullptr;
|
||||||
|
|
||||||
|
auto ¤t = _entries[index];
|
||||||
|
const auto height = current.widget->height();
|
||||||
|
if (index < result) {
|
||||||
|
auto sum = 0;
|
||||||
|
for (auto i = index; i != result; ++i) {
|
||||||
|
auto &entry = _entries[i + 1];
|
||||||
|
const auto widget = entry.widget;
|
||||||
|
entry.deltaShift += height;
|
||||||
|
updateShift(widget, i + 1);
|
||||||
|
sum += widget->height();
|
||||||
|
}
|
||||||
|
current.finalShift -= sum;
|
||||||
|
} else if (index > result) {
|
||||||
|
auto sum = 0;
|
||||||
|
for (auto i = result; i != index; ++i) {
|
||||||
|
auto &entry = _entries[i];
|
||||||
|
const auto widget = entry.widget;
|
||||||
|
entry.deltaShift -= height;
|
||||||
|
updateShift(widget, i);
|
||||||
|
sum += widget->height();
|
||||||
|
}
|
||||||
|
current.finalShift += sum;
|
||||||
|
}
|
||||||
|
base::reorder(_entries, index, result);
|
||||||
|
_layout->reorderRows(index, _currentDesiredIndex);
|
||||||
for (auto i = 0, count = int(_entries.size()); i != count; ++i) {
|
for (auto i = 0, count = int(_entries.size()); i != count; ++i) {
|
||||||
moveToShift(i, 0);
|
moveToShift(i, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
_layout->reorderRows(index, _currentDesiredIndex);
|
|
||||||
base::reorder(_entries, index, result);
|
|
||||||
|
|
||||||
_updates.fire({ widget, index, result, State::Applied });
|
_updates.fire({ widget, index, result, State::Applied });
|
||||||
}
|
}
|
||||||
|
|
||||||
void VerticalLayoutReorder::moveToShift(int index, int shift) {
|
void VerticalLayoutReorder::moveToShift(int index, int shift) {
|
||||||
_layout->setVerticalShift(index, shift);
|
auto &entry = _entries[index];
|
||||||
_entries[index].shift = shift;
|
if (entry.finalShift + entry.deltaShift == shift) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const auto widget = entry.widget;
|
||||||
|
entry.shiftAnimation.start(
|
||||||
|
[=] { updateShift(widget, index); },
|
||||||
|
entry.finalShift,
|
||||||
|
shift - entry.deltaShift,
|
||||||
|
st::slideWrapDuration);
|
||||||
|
entry.finalShift = shift - entry.deltaShift;
|
||||||
|
}
|
||||||
|
|
||||||
|
void VerticalLayoutReorder::updateShift(
|
||||||
|
not_null<RpWidget*> widget,
|
||||||
|
int indexHint) {
|
||||||
|
Expects(indexHint >= 0 && indexHint < _entries.size());
|
||||||
|
|
||||||
|
const auto index = (_entries[indexHint].widget == widget)
|
||||||
|
? indexHint
|
||||||
|
: indexOf(widget);
|
||||||
|
auto &entry = _entries[index];
|
||||||
|
entry.shift = std::round(entry.shiftAnimation.value(entry.finalShift))
|
||||||
|
+ entry.deltaShift;
|
||||||
|
if (entry.deltaShift && !entry.shiftAnimation.animating()) {
|
||||||
|
entry.finalShift += entry.deltaShift;
|
||||||
|
entry.deltaShift = 0;
|
||||||
|
}
|
||||||
|
_layout->setVerticalShift(index, entry.shift);
|
||||||
}
|
}
|
||||||
|
|
||||||
int VerticalLayoutReorder::indexOf(not_null<RpWidget*> widget) const {
|
int VerticalLayoutReorder::indexOf(not_null<RpWidget*> widget) const {
|
||||||
|
|
|
||||||
|
|
@ -6,6 +6,8 @@
|
||||||
//
|
//
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include "ui/effects/animations.h"
|
||||||
|
|
||||||
namespace Ui {
|
namespace Ui {
|
||||||
|
|
||||||
class RpWidget;
|
class RpWidget;
|
||||||
|
|
@ -34,7 +36,10 @@ public:
|
||||||
private:
|
private:
|
||||||
struct Entry {
|
struct Entry {
|
||||||
not_null<RpWidget*> widget;
|
not_null<RpWidget*> widget;
|
||||||
|
Ui::Animations::Simple shiftAnimation;
|
||||||
int shift = 0;
|
int shift = 0;
|
||||||
|
int finalShift = 0;
|
||||||
|
int deltaShift = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
void mouseMove(not_null<RpWidget*> widget, QPoint position);
|
void mouseMove(not_null<RpWidget*> widget, QPoint position);
|
||||||
|
|
@ -52,6 +57,7 @@ private:
|
||||||
|
|
||||||
[[nodiscard]] int indexOf(not_null<RpWidget*> widget) const;
|
[[nodiscard]] int indexOf(not_null<RpWidget*> widget) const;
|
||||||
void moveToShift(int index, int shift);
|
void moveToShift(int index, int shift);
|
||||||
|
void updateShift(not_null<RpWidget*> widget, int indexHint);
|
||||||
|
|
||||||
const not_null<Ui::VerticalLayout*> _layout;
|
const not_null<Ui::VerticalLayout*> _layout;
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue