mirror of
https://github.com/AyuGram/AyuGramDesktop.git
synced 2025-06-05 06:33:57 +02:00
Animate child topics list open / close.
This commit is contained in:
parent
468d01fc1a
commit
32491ead5e
8 changed files with 224 additions and 58 deletions
|
@ -141,7 +141,8 @@ int InnerWidget::FilterResult::bottom() const {
|
||||||
|
|
||||||
InnerWidget::InnerWidget(
|
InnerWidget::InnerWidget(
|
||||||
QWidget *parent,
|
QWidget *parent,
|
||||||
not_null<Window::SessionController*> controller)
|
not_null<Window::SessionController*> controller,
|
||||||
|
rpl::producer<ChildListShown> childListShown)
|
||||||
: RpWidget(parent)
|
: RpWidget(parent)
|
||||||
, _controller(controller)
|
, _controller(controller)
|
||||||
, _shownList(controller->session().data().chatsList()->indexed())
|
, _shownList(controller->session().data().chatsList()->indexed())
|
||||||
|
@ -153,7 +154,8 @@ InnerWidget::InnerWidget(
|
||||||
+ st::defaultDialogRow.photoSize
|
+ st::defaultDialogRow.photoSize
|
||||||
+ st::defaultDialogRow.padding.left())
|
+ st::defaultDialogRow.padding.left())
|
||||||
, _cancelSearchInChat(this, st::dialogsCancelSearchInPeer)
|
, _cancelSearchInChat(this, st::dialogsCancelSearchInPeer)
|
||||||
, _cancelSearchFromUser(this, st::dialogsCancelSearchInPeer) {
|
, _cancelSearchFromUser(this, st::dialogsCancelSearchInPeer)
|
||||||
|
, _childListShown(std::move(childListShown)) {
|
||||||
setAttribute(Qt::WA_OpaquePaintEvent, true);
|
setAttribute(Qt::WA_OpaquePaintEvent, true);
|
||||||
|
|
||||||
_cancelSearchInChat->hide();
|
_cancelSearchInChat->hide();
|
||||||
|
@ -546,7 +548,7 @@ void InnerWidget::paintEvent(QPaintEvent *e) {
|
||||||
const auto r = e->rect();
|
const auto r = e->rect();
|
||||||
auto dialogsClip = r;
|
auto dialogsClip = r;
|
||||||
const auto ms = crl::now();
|
const auto ms = crl::now();
|
||||||
const auto shownForum = _controller->shownForum().current();
|
const auto childListShown = _childListShown.current();
|
||||||
const auto paintRow = [&](
|
const auto paintRow = [&](
|
||||||
not_null<Row*> row,
|
not_null<Row*> row,
|
||||||
bool selected,
|
bool selected,
|
||||||
|
@ -558,23 +560,25 @@ void InnerWidget::paintEvent(QPaintEvent *e) {
|
||||||
if (forum && !_topicJumpCache) {
|
if (forum && !_topicJumpCache) {
|
||||||
_topicJumpCache = std::make_unique<Ui::TopicJumpCache>();
|
_topicJumpCache = std::make_unique<Ui::TopicJumpCache>();
|
||||||
}
|
}
|
||||||
const auto expanded = !active
|
|
||||||
|
const auto expanded = (!active
|
||||||
&& forum
|
&& forum
|
||||||
&& !_openedForum
|
&& (key.history()->peer->id == childListShown.peerId))
|
||||||
&& (key.history()->peer->forum() == shownForum);
|
? childListShown.shown
|
||||||
|
: 0.;
|
||||||
Ui::RowPainter::Paint(p, row, validateVideoUserpic(row), {
|
Ui::RowPainter::Paint(p, row, validateVideoUserpic(row), {
|
||||||
.st = (forum ? &st::forumDialogRow : _st.get()),
|
.st = (forum ? &st::forumDialogRow : _st.get()),
|
||||||
.topicJumpCache = _topicJumpCache.get(),
|
.topicJumpCache = _topicJumpCache.get(),
|
||||||
.folder = _openedFolder,
|
.folder = _openedFolder,
|
||||||
.forum = _openedForum,
|
.forum = _openedForum,
|
||||||
.filter = _filterId,
|
.filter = _filterId,
|
||||||
|
.topicsExpanded = expanded,
|
||||||
.now = ms,
|
.now = ms,
|
||||||
.width = fullWidth,
|
.width = fullWidth,
|
||||||
.active = active,
|
.active = active,
|
||||||
.selected = (_menuRow.key
|
.selected = (_menuRow.key
|
||||||
? (row->key() == _menuRow.key)
|
? (row->key() == _menuRow.key)
|
||||||
: selected),
|
: selected),
|
||||||
.topicsExpanded = expanded,
|
|
||||||
.topicJumpSelected = (selected
|
.topicJumpSelected = (selected
|
||||||
&& _selectedTopicJump
|
&& _selectedTopicJump
|
||||||
&& (!_pressed || _pressedTopicJump)),
|
&& (!_pressed || _pressedTopicJump)),
|
||||||
|
|
|
@ -83,9 +83,14 @@ enum class WidgetState {
|
||||||
|
|
||||||
class InnerWidget final : public Ui::RpWidget {
|
class InnerWidget final : public Ui::RpWidget {
|
||||||
public:
|
public:
|
||||||
|
struct ChildListShown {
|
||||||
|
PeerId peerId = 0;
|
||||||
|
float64 shown = 0.;
|
||||||
|
};
|
||||||
InnerWidget(
|
InnerWidget(
|
||||||
QWidget *parent,
|
QWidget *parent,
|
||||||
not_null<Window::SessionController*> controller);
|
not_null<Window::SessionController*> controller,
|
||||||
|
rpl::producer<ChildListShown> childListShown);
|
||||||
|
|
||||||
void searchReceived(
|
void searchReceived(
|
||||||
std::vector<not_null<HistoryItem*>> result,
|
std::vector<not_null<HistoryItem*>> result,
|
||||||
|
@ -490,6 +495,8 @@ private:
|
||||||
rpl::event_stream<QString> _completeHashtagRequests;
|
rpl::event_stream<QString> _completeHashtagRequests;
|
||||||
rpl::event_stream<> _refreshHashtagsRequests;
|
rpl::event_stream<> _refreshHashtagsRequests;
|
||||||
|
|
||||||
|
rpl::variable<ChildListShown> _childListShown;
|
||||||
|
|
||||||
base::unique_qptr<Ui::PopupMenu> _menu;
|
base::unique_qptr<Ui::PopupMenu> _menu;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
|
@ -202,7 +202,16 @@ Widget::Widget(
|
||||||
, _scrollToTop(_scroll, st::dialogsToUp)
|
, _scrollToTop(_scroll, st::dialogsToUp)
|
||||||
, _searchTimer([=] { searchMessages(); })
|
, _searchTimer([=] { searchMessages(); })
|
||||||
, _singleMessageSearch(&controller->session()) {
|
, _singleMessageSearch(&controller->session()) {
|
||||||
_inner = _scroll->setOwnedWidget(object_ptr<InnerWidget>(this, controller));
|
const auto makeChildListShown = [](PeerId peerId, float64 shown) {
|
||||||
|
return InnerWidget::ChildListShown{ peerId, shown };
|
||||||
|
};
|
||||||
|
_inner = _scroll->setOwnedWidget(object_ptr<InnerWidget>(
|
||||||
|
this,
|
||||||
|
controller,
|
||||||
|
rpl::combine(
|
||||||
|
_childListPeerId.value(),
|
||||||
|
_childListShown.value(),
|
||||||
|
makeChildListShown)));
|
||||||
|
|
||||||
_inner->updated(
|
_inner->updated(
|
||||||
) | rpl::start_with_next([=] {
|
) | rpl::start_with_next([=] {
|
||||||
|
@ -392,27 +401,29 @@ Widget::Widget(
|
||||||
setupSupportMode();
|
setupSupportMode();
|
||||||
setupScrollUpButton();
|
setupScrollUpButton();
|
||||||
|
|
||||||
changeOpenedFolder(
|
|
||||||
controller->openedFolder().current(),
|
|
||||||
anim::type::instant);
|
|
||||||
|
|
||||||
controller->openedFolder().changes(
|
|
||||||
) | rpl::start_with_next([=](Data::Folder *folder) {
|
|
||||||
changeOpenedFolder(folder, anim::type::normal);
|
|
||||||
}, lifetime());
|
|
||||||
|
|
||||||
if (_layout != Layout::Child) {
|
if (_layout != Layout::Child) {
|
||||||
|
changeOpenedFolder(
|
||||||
|
controller->openedFolder().current(),
|
||||||
|
anim::type::instant);
|
||||||
|
|
||||||
|
controller->openedFolder().changes(
|
||||||
|
) | rpl::start_with_next([=](Data::Folder *folder) {
|
||||||
|
changeOpenedFolder(folder, anim::type::normal);
|
||||||
|
}, lifetime());
|
||||||
|
|
||||||
controller->shownForum().changes(
|
controller->shownForum().changes(
|
||||||
) | rpl::filter(!rpl::mappers::_1) | rpl::start_with_next([=] {
|
) | rpl::filter(!rpl::mappers::_1) | rpl::start_with_next([=] {
|
||||||
if (_openedForum) {
|
if (_openedForum) {
|
||||||
changeOpenedForum(nullptr, anim::type::normal);
|
changeOpenedForum(nullptr, anim::type::normal);
|
||||||
} else if (_childList) {
|
} else if (_childList) {
|
||||||
_childList = nullptr;
|
closeChildList(anim::type::normal);
|
||||||
_childListShadow = nullptr;
|
|
||||||
updateControlsGeometry();
|
|
||||||
updateControlsVisibility(true);
|
|
||||||
}
|
}
|
||||||
}, lifetime());
|
}, lifetime());
|
||||||
|
|
||||||
|
_childListShown.changes(
|
||||||
|
) | rpl::start_with_next([=] {
|
||||||
|
updateControlsGeometry();
|
||||||
|
}, lifetime());
|
||||||
}
|
}
|
||||||
|
|
||||||
setupDownloadBar();
|
setupDownloadBar();
|
||||||
|
@ -440,9 +451,14 @@ void Widget::chosenRow(const ChosenRow &row) {
|
||||||
row.message.fullId.msg,
|
row.message.fullId.msg,
|
||||||
Window::SectionShow::Way::ClearStack);
|
Window::SectionShow::Way::ClearStack);
|
||||||
} else if (history && history->peer->isForum() && !row.message.fullId) {
|
} else if (history && history->peer->isForum() && !row.message.fullId) {
|
||||||
controller()->showForum(
|
const auto forum = history->peer->forum();
|
||||||
history->peer->forum(),
|
if (controller()->shownForum().current() == forum) {
|
||||||
Window::SectionShow().withChildColumn());
|
controller()->closeForum();
|
||||||
|
} else {
|
||||||
|
controller()->showForum(
|
||||||
|
forum,
|
||||||
|
Window::SectionShow().withChildColumn());
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
} else if (history) {
|
} else if (history) {
|
||||||
const auto peer = history->peer;
|
const auto peer = history->peer;
|
||||||
|
@ -468,15 +484,15 @@ void Widget::chosenRow(const ChosenRow &row) {
|
||||||
toSeparate();
|
toSeparate();
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
hideChildList();
|
|
||||||
controller()->showThread(
|
controller()->showThread(
|
||||||
history,
|
history,
|
||||||
showAtMsgId,
|
showAtMsgId,
|
||||||
Window::SectionShow::Way::ClearStack);
|
Window::SectionShow::Way::ClearStack);
|
||||||
|
hideChildList();
|
||||||
}
|
}
|
||||||
} else if (const auto folder = row.key.folder()) {
|
} else if (const auto folder = row.key.folder()) {
|
||||||
hideChildList();
|
|
||||||
controller()->openFolder(folder);
|
controller()->openFolder(folder);
|
||||||
|
hideChildList();
|
||||||
}
|
}
|
||||||
if (row.filteredRow && !session().supportMode()) {
|
if (row.filteredRow && !session().supportMode()) {
|
||||||
if (_subsectionTopBar) {
|
if (_subsectionTopBar) {
|
||||||
|
@ -735,6 +751,9 @@ void Widget::updateControlsVisibility(bool fast) {
|
||||||
_childList->show();
|
_childList->show();
|
||||||
_childListShadow->show();
|
_childListShadow->show();
|
||||||
}
|
}
|
||||||
|
if (_hideChildListCanvas) {
|
||||||
|
_hideChildListCanvas->show();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Widget::changeOpenedSubsection(
|
void Widget::changeOpenedSubsection(
|
||||||
|
@ -770,15 +789,24 @@ void Widget::changeOpenedSubsection(
|
||||||
}
|
}
|
||||||
|
|
||||||
void Widget::changeOpenedFolder(Data::Folder *folder, anim::type animated) {
|
void Widget::changeOpenedFolder(Data::Folder *folder, anim::type animated) {
|
||||||
|
if (_openedFolder == folder) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
changeOpenedSubsection([&] {
|
changeOpenedSubsection([&] {
|
||||||
|
closeChildList(anim::type::instant);
|
||||||
|
controller()->closeForum();
|
||||||
_openedFolder = folder;
|
_openedFolder = folder;
|
||||||
_inner->changeOpenedFolder(folder);
|
_inner->changeOpenedFolder(folder);
|
||||||
}, (folder != nullptr), animated);
|
}, (folder != nullptr), animated);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Widget::changeOpenedForum(Data::Forum *forum, anim::type animated) {
|
void Widget::changeOpenedForum(Data::Forum *forum, anim::type animated) {
|
||||||
|
if (_openedForum == forum) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
changeOpenedSubsection([&] {
|
changeOpenedSubsection([&] {
|
||||||
cancelSearch();
|
cancelSearch();
|
||||||
|
closeChildList(anim::type::instant);
|
||||||
_openedForum = forum;
|
_openedForum = forum;
|
||||||
_api.request(base::take(_topicSearchRequest)).cancel();
|
_api.request(base::take(_topicSearchRequest)).cancel();
|
||||||
_inner->changeOpenedForum(forum);
|
_inner->changeOpenedForum(forum);
|
||||||
|
@ -965,7 +993,9 @@ void Widget::checkUpdateStatus() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Widget::setInnerFocus() {
|
void Widget::setInnerFocus() {
|
||||||
if (!_openedFolder && !_openedForum) {
|
if (_childList) {
|
||||||
|
_childList->setInnerFocus();
|
||||||
|
} else if (!_openedFolder && !_openedForum) {
|
||||||
_filter->setFocus();
|
_filter->setFocus();
|
||||||
} else if (!_subsectionTopBar->searchSetFocus()) {
|
} else if (!_subsectionTopBar->searchSetFocus()) {
|
||||||
setFocus();
|
setFocus();
|
||||||
|
@ -1064,18 +1094,28 @@ void Widget::showFast() {
|
||||||
show();
|
show();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Widget::showAnimated(Window::SlideDirection direction, const Window::SectionSlideParams ¶ms) {
|
rpl::producer<float64> Widget::shownProgressValue() const {
|
||||||
|
return _shownProgressValue.value();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Widget::showAnimated(
|
||||||
|
Window::SlideDirection direction,
|
||||||
|
const Window::SectionSlideParams ¶ms) {
|
||||||
_showAnimation = nullptr;
|
_showAnimation = nullptr;
|
||||||
|
|
||||||
auto oldContentCache = params.oldContentCache;
|
auto oldContentCache = params.oldContentCache;
|
||||||
showFast();
|
showFast();
|
||||||
const auto content = controller()->content();
|
auto newContentCache = Ui::GrabWidget(this);
|
||||||
auto newContentCache = content->grabForShowAnimation(params);
|
|
||||||
|
|
||||||
if (_updateTelegram) {
|
if (_updateTelegram) {
|
||||||
_updateTelegram->hide();
|
_updateTelegram->hide();
|
||||||
}
|
}
|
||||||
_connecting->setForceHidden(true);
|
_connecting->setForceHidden(true);
|
||||||
|
if (_childList) {
|
||||||
|
_childList->hide();
|
||||||
|
_childListShadow->hide();
|
||||||
|
}
|
||||||
|
_shownProgressValue = 0.;
|
||||||
startSlideAnimation(
|
startSlideAnimation(
|
||||||
std::move(oldContentCache),
|
std::move(oldContentCache),
|
||||||
std::move(newContentCache),
|
std::move(newContentCache),
|
||||||
|
@ -1106,7 +1146,12 @@ void Widget::startSlideAnimation(
|
||||||
|
|
||||||
_showAnimation = std::make_unique<Window::SlideAnimation>();
|
_showAnimation = std::make_unique<Window::SlideAnimation>();
|
||||||
_showAnimation->setDirection(direction);
|
_showAnimation->setDirection(direction);
|
||||||
_showAnimation->setRepaintCallback([=] { update(); });
|
_showAnimation->setRepaintCallback([=] {
|
||||||
|
if (_shownProgressValue.current() < 1.) {
|
||||||
|
_shownProgressValue = _showAnimation->progress();
|
||||||
|
}
|
||||||
|
update();
|
||||||
|
});
|
||||||
_showAnimation->setFinishedCallback([=] { slideFinished(); });
|
_showAnimation->setFinishedCallback([=] { slideFinished(); });
|
||||||
_showAnimation->setPixmaps(oldContentCache, newContentCache);
|
_showAnimation->setPixmaps(oldContentCache, newContentCache);
|
||||||
_showAnimation->start();
|
_showAnimation->start();
|
||||||
|
@ -1122,6 +1167,7 @@ QRect Widget::floatPlayerAvailableRect() {
|
||||||
|
|
||||||
void Widget::slideFinished() {
|
void Widget::slideFinished() {
|
||||||
_showAnimation = nullptr;
|
_showAnimation = nullptr;
|
||||||
|
_shownProgressValue = 1.;
|
||||||
updateControlsVisibility(true);
|
updateControlsVisibility(true);
|
||||||
if ((!_subsectionTopBar || !_subsectionTopBar->searchHasFocus())
|
if ((!_subsectionTopBar || !_subsectionTopBar->searchHasFocus())
|
||||||
&& !_filter->hasFocus()) {
|
&& !_filter->hasFocus()) {
|
||||||
|
@ -1838,12 +1884,12 @@ void Widget::dropEvent(QDropEvent *e) {
|
||||||
const auto point = mapToGlobal(e->pos());
|
const auto point = mapToGlobal(e->pos());
|
||||||
if (const auto thread = _inner->updateFromParentDrag(point)) {
|
if (const auto thread = _inner->updateFromParentDrag(point)) {
|
||||||
e->acceptProposedAction();
|
e->acceptProposedAction();
|
||||||
if (!thread->owningHistory()->peer->isForum()) {
|
|
||||||
hideChildList();
|
|
||||||
}
|
|
||||||
controller()->content()->filesOrForwardDrop(
|
controller()->content()->filesOrForwardDrop(
|
||||||
thread,
|
thread,
|
||||||
e->mimeData());
|
e->mimeData());
|
||||||
|
if (!thread->owningHistory()->peer->isForum()) {
|
||||||
|
hideChildList();
|
||||||
|
}
|
||||||
controller()->widget()->raise();
|
controller()->widget()->raise();
|
||||||
controller()->widget()->activateWindow();
|
controller()->widget()->activateWindow();
|
||||||
}
|
}
|
||||||
|
@ -1902,6 +1948,22 @@ void Widget::showForum(
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
cancelSearch();
|
cancelSearch();
|
||||||
|
openChildList(forum, params);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Widget::openChildList(
|
||||||
|
not_null<Data::Forum*> forum,
|
||||||
|
const Window::SectionShow ¶ms) {
|
||||||
|
auto slide = Window::SectionSlideParams();
|
||||||
|
const auto animated = !_childList
|
||||||
|
&& (params.animated == anim::type::normal);
|
||||||
|
if (animated) {
|
||||||
|
_childListShown = 0.;
|
||||||
|
_hideChildListCanvas = nullptr;
|
||||||
|
slide.oldContentCache = Ui::GrabWidget(
|
||||||
|
this,
|
||||||
|
QRect(_narrowWidth, 0, width() - _narrowWidth, height()));
|
||||||
|
}
|
||||||
auto copy = params;
|
auto copy = params;
|
||||||
copy.childColumn = false;
|
copy.childColumn = false;
|
||||||
copy.animated = anim::type::instant;
|
copy.animated = anim::type::instant;
|
||||||
|
@ -1910,19 +1972,87 @@ void Widget::showForum(
|
||||||
controller(),
|
controller(),
|
||||||
Layout::Child);
|
Layout::Child);
|
||||||
_childList->showForum(forum, copy);
|
_childList->showForum(forum, copy);
|
||||||
|
_childListPeerId = forum->channel()->id;
|
||||||
|
|
||||||
_childListShadow = std::make_unique<Ui::RpWidget>(this);
|
_childListShadow = std::make_unique<Ui::RpWidget>(this);
|
||||||
_childListShadow->setAttribute(Qt::WA_TransparentForMouseEvents);
|
const auto shadow = _childListShadow.get();
|
||||||
_childListShadow->paintRequest(
|
const auto opacity = shadow->lifetime().make_state<float64>(0.);
|
||||||
|
shadow->setAttribute(Qt::WA_TransparentForMouseEvents);
|
||||||
|
shadow->paintRequest(
|
||||||
) | rpl::start_with_next([=] {
|
) | rpl::start_with_next([=] {
|
||||||
auto p = QPainter(_childListShadow.get());
|
auto p = QPainter(shadow);
|
||||||
|
p.setOpacity(*opacity);
|
||||||
st::slideShadow.fill(p, QRect(
|
st::slideShadow.fill(p, QRect(
|
||||||
_childListShadow->width() - st::slideShadow.width(),
|
shadow->width() - st::slideShadow.width(),
|
||||||
0,
|
0,
|
||||||
st::slideShadow.width(),
|
st::slideShadow.width(),
|
||||||
_childListShadow->height()));
|
shadow->height()));
|
||||||
}, _childListShadow->lifetime());
|
}, shadow->lifetime());
|
||||||
|
_childListShown.value() | rpl::start_with_next([=](float64 value) {
|
||||||
|
*opacity = value;
|
||||||
|
if (!value && _childListShadow.get() != shadow) {
|
||||||
|
delete shadow;
|
||||||
|
} else {
|
||||||
|
shadow->update();
|
||||||
|
}
|
||||||
|
}, shadow->lifetime());
|
||||||
|
|
||||||
updateControlsGeometry();
|
updateControlsGeometry();
|
||||||
updateControlsVisibility(true);
|
updateControlsVisibility(true);
|
||||||
|
|
||||||
|
if (animated) {
|
||||||
|
_childList->showAnimated(Window::SlideDirection::FromRight, slide);
|
||||||
|
_childListShown = _childList->shownProgressValue();
|
||||||
|
} else {
|
||||||
|
_childListShown = 1.;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Widget::closeChildList(anim::type animated) {
|
||||||
|
if (!_childList) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const auto geometry = _childList->geometry();
|
||||||
|
const auto shown = _childListShown.current();
|
||||||
|
auto oldContentCache = QPixmap();
|
||||||
|
auto animation = (Window::SlideAnimation*)nullptr;
|
||||||
|
if (animated == anim::type::normal) {
|
||||||
|
oldContentCache = Ui::GrabWidget(_childList.get());
|
||||||
|
_hideChildListCanvas = std::make_unique<Ui::RpWidget>(this);
|
||||||
|
_hideChildListCanvas->setGeometry(geometry);
|
||||||
|
animation = _hideChildListCanvas->lifetime().make_state<
|
||||||
|
Window::SlideAnimation
|
||||||
|
>();
|
||||||
|
_hideChildListCanvas->paintRequest(
|
||||||
|
) | rpl::start_with_next([=] {
|
||||||
|
QPainter p(_hideChildListCanvas.get());
|
||||||
|
animation->paintContents(p);
|
||||||
|
}, _hideChildListCanvas->lifetime());
|
||||||
|
}
|
||||||
|
_childList = nullptr;
|
||||||
|
_childListShown = 0.;
|
||||||
|
if (animated == anim::type::normal) {
|
||||||
|
_hideChildListCanvas->hide();
|
||||||
|
auto newContentCache = Ui::GrabWidget(this, geometry);
|
||||||
|
_hideChildListCanvas->show();
|
||||||
|
|
||||||
|
_childListShown = shown;
|
||||||
|
_childListShadow.release();
|
||||||
|
|
||||||
|
animation->setDirection(Window::SlideDirection::FromLeft);
|
||||||
|
animation->setRepaintCallback([=] {
|
||||||
|
_childListShown = (1. - animation->progress()) * shown;
|
||||||
|
_hideChildListCanvas->update();
|
||||||
|
});
|
||||||
|
animation->setFinishedCallback([=] {
|
||||||
|
_childListShown = 0.;
|
||||||
|
_hideChildListCanvas = nullptr;
|
||||||
|
});
|
||||||
|
animation->setPixmaps(oldContentCache, newContentCache);
|
||||||
|
animation->start();
|
||||||
|
} else {
|
||||||
|
_childListShadow = nullptr;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Widget::searchInChat(Key chat) {
|
void Widget::searchInChat(Key chat) {
|
||||||
|
@ -2162,12 +2292,16 @@ void Widget::updateSearchFromVisibility(bool fast) {
|
||||||
|
|
||||||
void Widget::updateControlsGeometry() {
|
void Widget::updateControlsGeometry() {
|
||||||
auto filterAreaTop = 0;
|
auto filterAreaTop = 0;
|
||||||
const auto usew = _childList ? _narrowWidth : width();
|
|
||||||
const auto childw = std::max(_narrowWidth, width() - usew);
|
const auto ratiow = anim::interpolate(
|
||||||
|
width(),
|
||||||
|
_narrowWidth,
|
||||||
|
_childListShown.current());
|
||||||
const auto smallw = st::columnMinimalWidthLeft - _narrowWidth;
|
const auto smallw = st::columnMinimalWidthLeft - _narrowWidth;
|
||||||
const auto smallLayoutRatio = (usew < smallw)
|
const auto smallLayoutRatio = (ratiow < smallw)
|
||||||
? ((smallw - usew) / float64(smallw - _narrowWidth))
|
? ((smallw - ratiow) / float64(smallw - _narrowWidth))
|
||||||
: 0.;
|
: 0.;
|
||||||
|
|
||||||
auto filterLeft = (controller()->filtersWidth()
|
auto filterLeft = (controller()->filtersWidth()
|
||||||
? st::dialogsFilterSkip
|
? st::dialogsFilterSkip
|
||||||
: (st::dialogsFilterPadding.x() + _mainMenuToggle->width()))
|
: (st::dialogsFilterPadding.x() + _mainMenuToggle->width()))
|
||||||
|
@ -2175,9 +2309,9 @@ void Widget::updateControlsGeometry() {
|
||||||
auto filterRight = (session().domain().local().hasLocalPasscode()
|
auto filterRight = (session().domain().local().hasLocalPasscode()
|
||||||
? (st::dialogsFilterPadding.x() + _lockUnlock->width())
|
? (st::dialogsFilterPadding.x() + _lockUnlock->width())
|
||||||
: st::dialogsFilterSkip) + st::dialogsFilterPadding.x();
|
: st::dialogsFilterSkip) + st::dialogsFilterPadding.x();
|
||||||
auto filterWidth = qMax(usew, smallw) - filterLeft - filterRight;
|
auto filterWidth = qMax(ratiow, smallw) - filterLeft - filterRight;
|
||||||
auto filterAreaHeight = st::topBarHeight;
|
auto filterAreaHeight = st::topBarHeight;
|
||||||
_searchControls->setGeometry(0, filterAreaTop, usew, filterAreaHeight);
|
_searchControls->setGeometry(0, filterAreaTop, ratiow, filterAreaHeight);
|
||||||
if (_subsectionTopBar) {
|
if (_subsectionTopBar) {
|
||||||
_subsectionTopBar->setGeometry(_searchControls->geometry());
|
_subsectionTopBar->setGeometry(_searchControls->geometry());
|
||||||
}
|
}
|
||||||
|
@ -2202,6 +2336,7 @@ void Widget::updateControlsGeometry() {
|
||||||
right -= _jumpToDate->width(); _jumpToDate->moveToLeft(right, _filter->y());
|
right -= _jumpToDate->width(); _jumpToDate->moveToLeft(right, _filter->y());
|
||||||
right -= _chooseFromUser->width(); _chooseFromUser->moveToLeft(right, _filter->y());
|
right -= _chooseFromUser->width(); _chooseFromUser->moveToLeft(right, _filter->y());
|
||||||
|
|
||||||
|
const auto usew = _childList ? _narrowWidth : width();
|
||||||
if (_forumTopShadow) {
|
if (_forumTopShadow) {
|
||||||
_forumTopShadow->setGeometry(
|
_forumTopShadow->setGeometry(
|
||||||
0,
|
0,
|
||||||
|
@ -2264,6 +2399,7 @@ void Widget::updateControlsGeometry() {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_childList) {
|
if (_childList) {
|
||||||
|
const auto childw = std::max(_narrowWidth, width() - usew);
|
||||||
_childList->setGeometryWithTopMoved(
|
_childList->setGeometryWithTopMoved(
|
||||||
{ width() - childw, 0, childw, height() },
|
{ width() - childw, 0, childw, height() },
|
||||||
_topDelta);
|
_topDelta);
|
||||||
|
|
|
@ -100,6 +100,7 @@ public:
|
||||||
Window::SlideDirection direction,
|
Window::SlideDirection direction,
|
||||||
const Window::SectionSlideParams ¶ms);
|
const Window::SectionSlideParams ¶ms);
|
||||||
void showFast();
|
void showFast();
|
||||||
|
[[nodiscard]] rpl::producer<float64> shownProgressValue() const;
|
||||||
|
|
||||||
void scrollToEntry(const RowDescriptor &entry);
|
void scrollToEntry(const RowDescriptor &entry);
|
||||||
|
|
||||||
|
@ -187,6 +188,11 @@ private:
|
||||||
QPixmap newContentCache,
|
QPixmap newContentCache,
|
||||||
Window::SlideDirection direction);
|
Window::SlideDirection direction);
|
||||||
|
|
||||||
|
void openChildList(
|
||||||
|
not_null<Data::Forum*> forum,
|
||||||
|
const Window::SectionShow ¶ms);
|
||||||
|
void closeChildList(anim::type animated);
|
||||||
|
|
||||||
void fullSearchRefreshOn(rpl::producer<> events);
|
void fullSearchRefreshOn(rpl::producer<> events);
|
||||||
void applyFilterUpdate(bool force = false);
|
void applyFilterUpdate(bool force = false);
|
||||||
void refreshLoadMoreButton(bool mayBlock, bool isBlocked);
|
void refreshLoadMoreButton(bool mayBlock, bool isBlocked);
|
||||||
|
@ -237,6 +243,7 @@ private:
|
||||||
|
|
||||||
Ui::Animations::Simple _scrollToAnimation;
|
Ui::Animations::Simple _scrollToAnimation;
|
||||||
std::unique_ptr<Window::SlideAnimation> _showAnimation;
|
std::unique_ptr<Window::SlideAnimation> _showAnimation;
|
||||||
|
rpl::variable<float64> _shownProgressValue;
|
||||||
|
|
||||||
Ui::Animations::Simple _scrollToTopShown;
|
Ui::Animations::Simple _scrollToTopShown;
|
||||||
object_ptr<Ui::HistoryDownButton> _scrollToTop;
|
object_ptr<Ui::HistoryDownButton> _scrollToTop;
|
||||||
|
@ -287,6 +294,9 @@ private:
|
||||||
|
|
||||||
std::unique_ptr<Widget> _childList;
|
std::unique_ptr<Widget> _childList;
|
||||||
std::unique_ptr<Ui::RpWidget> _childListShadow;
|
std::unique_ptr<Ui::RpWidget> _childListShadow;
|
||||||
|
rpl::variable<float64> _childListShown;
|
||||||
|
rpl::variable<PeerId> _childListPeerId;
|
||||||
|
std::unique_ptr<Ui::RpWidget> _hideChildListCanvas;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -186,17 +186,18 @@ int PaintBadges(
|
||||||
return (initial - right);
|
return (initial - right);
|
||||||
}
|
}
|
||||||
|
|
||||||
void PaintExpandedTopicsBar(QPainter &p) {
|
void PaintExpandedTopicsBar(QPainter &p, float64 progress) {
|
||||||
auto hq = PainterHighQualityEnabler(p);
|
auto hq = PainterHighQualityEnabler(p);
|
||||||
const auto radius = st::roundRadiusLarge;
|
const auto radius = st::roundRadiusLarge;
|
||||||
const auto width = st::forumDialogRow.padding.left() / 2;
|
const auto width = st::forumDialogRow.padding.left() / 2;
|
||||||
p.setPen(Qt::NoPen);
|
p.setPen(Qt::NoPen);
|
||||||
p.setBrush(st::dialogsBgActive);
|
p.setBrush(st::dialogsBgActive);
|
||||||
p.drawRoundedRect(
|
p.drawRoundedRect(
|
||||||
-3 * radius,
|
QRectF(
|
||||||
st::forumDialogRow.padding.top(),
|
-3. * radius - width * (1. - progress),
|
||||||
3 * radius + width,
|
st::forumDialogRow.padding.top(),
|
||||||
st::forumDialogRow.photoSize,
|
3. * radius + width,
|
||||||
|
st::forumDialogRow.photoSize),
|
||||||
radius,
|
radius,
|
||||||
radius);
|
radius);
|
||||||
}
|
}
|
||||||
|
@ -349,13 +350,13 @@ void PaintRow(
|
||||||
}
|
}
|
||||||
|
|
||||||
auto nameleft = context.st->nameLeft;
|
auto nameleft = context.st->nameLeft;
|
||||||
|
if (context.topicsExpanded > 0.) {
|
||||||
|
PaintExpandedTopicsBar(p, context.topicsExpanded);
|
||||||
|
}
|
||||||
if (context.narrow) {
|
if (context.narrow) {
|
||||||
if (!draft && item && !item->isEmpty()) {
|
if (!draft && item && !item->isEmpty()) {
|
||||||
PaintNarrowCounter(p, context, badgesState);
|
PaintNarrowCounter(p, context, badgesState);
|
||||||
}
|
}
|
||||||
if (context.topicsExpanded) {
|
|
||||||
PaintExpandedTopicsBar(p);
|
|
||||||
}
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -58,11 +58,11 @@ struct PaintContext {
|
||||||
Data::Folder *folder = nullptr;
|
Data::Folder *folder = nullptr;
|
||||||
Data::Forum *forum = nullptr;
|
Data::Forum *forum = nullptr;
|
||||||
FilterId filter = 0;
|
FilterId filter = 0;
|
||||||
|
float64 topicsExpanded = 0.;
|
||||||
crl::time now = 0;
|
crl::time now = 0;
|
||||||
int width = 0;
|
int width = 0;
|
||||||
bool active = false;
|
bool active = false;
|
||||||
bool selected = false;
|
bool selected = false;
|
||||||
bool topicsExpanded = false;
|
|
||||||
bool topicJumpSelected = false;
|
bool topicJumpSelected = false;
|
||||||
bool paused = false;
|
bool paused = false;
|
||||||
bool search = false;
|
bool search = false;
|
||||||
|
|
|
@ -141,6 +141,12 @@ void SlideAnimation::paintContents(QPainter &p) const {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
float64 SlideAnimation::progress() const {
|
||||||
|
const auto slideLeft = (_direction == SlideDirection::FromLeft);
|
||||||
|
const auto progress = _animation.value(slideLeft ? 0. : 1.);
|
||||||
|
return slideLeft ? (1. - progress) : progress;
|
||||||
|
}
|
||||||
|
|
||||||
void SlideAnimation::setDirection(SlideDirection direction) {
|
void SlideAnimation::setDirection(SlideDirection direction) {
|
||||||
_direction = direction;
|
_direction = direction;
|
||||||
}
|
}
|
||||||
|
@ -193,8 +199,8 @@ void SlideAnimation::start() {
|
||||||
void SlideAnimation::animationCallback() {
|
void SlideAnimation::animationCallback() {
|
||||||
_repaintCallback();
|
_repaintCallback();
|
||||||
if (!_animation.animating()) {
|
if (!_animation.animating()) {
|
||||||
if (_finishedCallback) {
|
if (const auto onstack = _finishedCallback) {
|
||||||
_finishedCallback();
|
onstack();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,6 +20,8 @@ class SlideAnimation {
|
||||||
public:
|
public:
|
||||||
void paintContents(QPainter &p) const;
|
void paintContents(QPainter &p) const;
|
||||||
|
|
||||||
|
[[nodiscard]] float64 progress() const;
|
||||||
|
|
||||||
void setDirection(SlideDirection direction);
|
void setDirection(SlideDirection direction);
|
||||||
void setPixmaps(
|
void setPixmaps(
|
||||||
const QPixmap &oldContentCache,
|
const QPixmap &oldContentCache,
|
||||||
|
|
Loading…
Add table
Reference in a new issue