mirror of
https://github.com/AyuGram/AyuGramDesktop.git
synced 2025-04-16 14:17:12 +02:00
Reuse filters slider scroll for search.
This commit is contained in:
parent
5072e95f16
commit
04e9eed88d
8 changed files with 104 additions and 60 deletions
|
@ -689,7 +689,11 @@ recentPeersSpecialName: PeerListItem(recentPeersItem) {
|
|||
namePosition: point(64px, 19px);
|
||||
}
|
||||
|
||||
dialogsTabsScroll: ScrollArea(defaultScrollArea) {
|
||||
barHidden: true;
|
||||
}
|
||||
dialogsSearchTabs: SettingsSlider(defaultSettingsSlider) {
|
||||
padding: 8px;
|
||||
height: 33px;
|
||||
barTop: 30px;
|
||||
barSkip: 0px;
|
||||
|
@ -707,7 +711,6 @@ dialogsSearchTabs: SettingsSlider(defaultSettingsSlider) {
|
|||
rippleBgActive: lightButtonBgOver;
|
||||
ripple: defaultRippleAnimation;
|
||||
}
|
||||
dialogsSearchTabsPadding: 8px;
|
||||
|
||||
chatsFiltersTabs: SettingsSlider(dialogsSearchTabs) {
|
||||
rippleBottomSkip: 0px;
|
||||
|
|
|
@ -1292,7 +1292,11 @@ Suggestions::Suggestions(
|
|||
RecentPeersList recentPeers)
|
||||
: RpWidget(parent)
|
||||
, _controller(controller)
|
||||
, _tabs(std::make_unique<Ui::SettingsSlider>(this, st::dialogsSearchTabs))
|
||||
, _tabsScroll(
|
||||
std::make_unique<Ui::ScrollArea>(this, st::dialogsTabsScroll, true))
|
||||
, _tabs(
|
||||
_tabsScroll->setOwnedWidget(
|
||||
object_ptr<Ui::SettingsSlider>(this, st::dialogsSearchTabs)))
|
||||
, _chatsScroll(std::make_unique<Ui::ElasticScroll>(this))
|
||||
, _chatsContent(
|
||||
_chatsScroll->setOwnedWidget(object_ptr<Ui::VerticalLayout>(this)))
|
||||
|
@ -1314,7 +1318,6 @@ Suggestions::Suggestions(
|
|||
_appsScroll->setOwnedWidget(object_ptr<Ui::VerticalLayout>(this)))
|
||||
, _recentApps(setupRecentApps())
|
||||
, _popularApps(setupPopularApps()) {
|
||||
|
||||
setupTabs();
|
||||
setupChats();
|
||||
setupChannels();
|
||||
|
@ -1324,10 +1327,46 @@ Suggestions::Suggestions(
|
|||
Suggestions::~Suggestions() = default;
|
||||
|
||||
void Suggestions::setupTabs() {
|
||||
_tabsScroll->setCustomWheelProcess([=](not_null<QWheelEvent*> e) {
|
||||
const auto pixelDelta = e->pixelDelta();
|
||||
const auto angleDelta = e->angleDelta();
|
||||
if (std::abs(pixelDelta.x()) + std::abs(angleDelta.x())) {
|
||||
return false;
|
||||
}
|
||||
const auto y = pixelDelta.y() ? pixelDelta.y() : angleDelta.y();
|
||||
_tabsScroll->scrollToX(_tabsScroll->scrollLeft() - y);
|
||||
return true;
|
||||
});
|
||||
|
||||
const auto scrollToIndex = [=](int index, anim::type type) {
|
||||
const auto to = index
|
||||
? (_tabs->centerOfSection(index) - _tabsScroll->width() / 2)
|
||||
: 0;
|
||||
_tabsScrollAnimation.stop();
|
||||
if (type == anim::type::instant) {
|
||||
_tabsScroll->scrollToX(to);
|
||||
} else {
|
||||
_tabsScrollAnimation.start(
|
||||
[=](float64 v) { _tabsScroll->scrollToX(v); },
|
||||
_tabsScroll->scrollLeft(),
|
||||
std::min(to, _tabsScroll->scrollLeftMax()),
|
||||
st::defaultTabsSlider.duration);
|
||||
}
|
||||
};
|
||||
rpl::single(-1) | rpl::then(
|
||||
_tabs->sectionActivated()
|
||||
) | rpl::combine_previous(
|
||||
) | rpl::start_with_next([=](int was, int index) {
|
||||
if (was != index) {
|
||||
scrollToIndex(index, anim::type::normal);
|
||||
}
|
||||
}, _tabs->lifetime());
|
||||
|
||||
const auto shadow = Ui::CreateChild<Ui::PlainShadow>(this);
|
||||
shadow->lower();
|
||||
|
||||
_tabs->move(st::dialogsSearchTabsPadding, 0);
|
||||
_tabsScroll->move(0, 0);
|
||||
_tabs->move(0, 0);
|
||||
rpl::combine(
|
||||
widthValue(),
|
||||
_tabs->heightValue()
|
||||
|
@ -1338,11 +1377,12 @@ void Suggestions::setupTabs() {
|
|||
|
||||
shadow->showOn(_tabs->shownValue());
|
||||
|
||||
_tabs->setSections({
|
||||
auto sections = std::vector<QString>{
|
||||
tr::lng_recent_chats(tr::now),
|
||||
tr::lng_recent_channels(tr::now),
|
||||
tr::lng_recent_apps(tr::now),
|
||||
});
|
||||
};
|
||||
_tabs->setSections(sections);
|
||||
_tabs->sectionActivated(
|
||||
) | rpl::start_with_next([=](int section) {
|
||||
switchTab(section == 2
|
||||
|
@ -1808,7 +1848,7 @@ void Suggestions::startShownAnimation(bool shown, Fn<void()> finish) {
|
|||
resize(now, height());
|
||||
}
|
||||
}
|
||||
_tabs->hide();
|
||||
_tabsScroll->hide();
|
||||
_chatsScroll->hide();
|
||||
_channelsScroll->hide();
|
||||
_appsScroll->hide();
|
||||
|
@ -1823,7 +1863,7 @@ void Suggestions::finishShow() {
|
|||
_shownAnimation.stop();
|
||||
_cache = QPixmap();
|
||||
|
||||
_tabs->show();
|
||||
_tabsScroll->show();
|
||||
const auto tab = _tab.current();
|
||||
_chatsScroll->setVisible(tab == Tab::Chats);
|
||||
_channelsScroll->setVisible(tab == Tab::Channels);
|
||||
|
@ -1864,8 +1904,10 @@ void Suggestions::paintEvent(QPaintEvent *e) {
|
|||
|
||||
void Suggestions::resizeEvent(QResizeEvent *e) {
|
||||
const auto w = std::max(width(), st::columnMinimalWidthLeft);
|
||||
_tabs->resizeToWidth(w);
|
||||
_tabs->fitWidthToSections();
|
||||
|
||||
const auto tabs = _tabs->height();
|
||||
_tabsScroll->setGeometry(0, 0, w, tabs);
|
||||
|
||||
_chatsScroll->setGeometry(0, tabs, w, height() - tabs);
|
||||
_chatsContent->resizeToWidth(w);
|
||||
|
|
|
@ -24,6 +24,7 @@ class Session;
|
|||
|
||||
namespace Ui {
|
||||
class BoxContent;
|
||||
class ScrollArea;
|
||||
class ElasticScroll;
|
||||
class SettingsSlider;
|
||||
class VerticalLayout;
|
||||
|
@ -169,7 +170,9 @@ private:
|
|||
|
||||
const not_null<Window::SessionController*> _controller;
|
||||
|
||||
const std::unique_ptr<Ui::SettingsSlider> _tabs;
|
||||
const std::unique_ptr<Ui::ScrollArea> _tabsScroll;
|
||||
const not_null<Ui::SettingsSlider*> _tabs;
|
||||
Ui::Animations::Simple _tabsScrollAnimation;
|
||||
rpl::variable<Tab> _tab = Tab::Chats;
|
||||
|
||||
const std::unique_ptr<Ui::ElasticScroll> _chatsScroll;
|
||||
|
|
|
@ -15,18 +15,6 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
#include <QScrollBar>
|
||||
|
||||
namespace Ui {
|
||||
namespace {
|
||||
|
||||
[[nodiscard]] QMouseEvent TranslatedMouseEvent(QMouseEvent *e) {
|
||||
return QMouseEvent(
|
||||
e->type(),
|
||||
e->pos() + QPoint(-st::dialogsSearchTabsPadding, 0),
|
||||
e->button(),
|
||||
e->buttons(),
|
||||
e->modifiers());
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
ChatsFiltersTabs::ChatsFiltersTabs(
|
||||
not_null<Ui::RpWidget*> parent,
|
||||
|
@ -77,22 +65,9 @@ bool ChatsFiltersTabs::setSectionsAndCheckChanged(
|
|||
return changed;
|
||||
}
|
||||
|
||||
int ChatsFiltersTabs::centerOfSection(int section) const {
|
||||
const auto widths = countSectionsWidths(0);
|
||||
auto result = 0;
|
||||
if (section >= 0 && section < widths.size()) {
|
||||
for (auto i = 0; i < section; i++) {
|
||||
result += widths[i];
|
||||
}
|
||||
result += widths[section] / 2;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
void ChatsFiltersTabs::fitWidthToSections() {
|
||||
const auto widths = countSectionsWidths(0);
|
||||
const auto sliderPadding = st::dialogsSearchTabsPadding;
|
||||
resizeToWidth(ranges::accumulate(widths, .0) + sliderPadding * 2);
|
||||
SettingsSlider::fitWidthToSections();
|
||||
|
||||
_lockedFromX = calculateLockedFromX();
|
||||
|
||||
{
|
||||
|
@ -197,8 +172,6 @@ void ChatsFiltersTabs::paintEvent(QPaintEvent *e) {
|
|||
const auto range = getCurrentActiveRange();
|
||||
const auto activeIndex = activeSection();
|
||||
|
||||
p.translate(st::dialogsSearchTabsPadding, 0);
|
||||
|
||||
auto index = 0;
|
||||
auto raisedIndex = -1;
|
||||
auto activeHorizontalShift = 0;
|
||||
|
@ -310,32 +283,29 @@ void ChatsFiltersTabs::paintEvent(QPaintEvent *e) {
|
|||
}
|
||||
|
||||
void ChatsFiltersTabs::mousePressEvent(QMouseEvent *e) {
|
||||
auto m = TranslatedMouseEvent(e);
|
||||
const auto mouseButton = m.button();
|
||||
const auto mouseButton = e->button();
|
||||
if (mouseButton == Qt::MouseButton::LeftButton) {
|
||||
_lockedPressed = (m.pos().x() >= _lockedFromX);
|
||||
_lockedPressed = (e->pos().x() >= _lockedFromX);
|
||||
if (_lockedPressed) {
|
||||
Ui::RpWidget::mousePressEvent(&m);
|
||||
Ui::RpWidget::mousePressEvent(e);
|
||||
} else {
|
||||
Ui::SettingsSlider::mousePressEvent(&m);
|
||||
Ui::SettingsSlider::mousePressEvent(e);
|
||||
}
|
||||
} else {
|
||||
Ui::RpWidget::mousePressEvent(&m);
|
||||
Ui::RpWidget::mousePressEvent(e);
|
||||
}
|
||||
}
|
||||
|
||||
void ChatsFiltersTabs::mouseMoveEvent(QMouseEvent *e) {
|
||||
auto m = TranslatedMouseEvent(e);
|
||||
if (_reordering) {
|
||||
Ui::RpWidget::mouseMoveEvent(&m);
|
||||
Ui::RpWidget::mouseMoveEvent(e);
|
||||
} else {
|
||||
Ui::SettingsSlider::mouseMoveEvent(&m);
|
||||
Ui::SettingsSlider::mouseMoveEvent(e);
|
||||
}
|
||||
}
|
||||
|
||||
void ChatsFiltersTabs::mouseReleaseEvent(QMouseEvent *e) {
|
||||
auto m = TranslatedMouseEvent(e);
|
||||
const auto mouseButton = m.button();
|
||||
const auto mouseButton = e->button();
|
||||
if (mouseButton == Qt::MouseButton::LeftButton) {
|
||||
if (base::take(_lockedPressed)) {
|
||||
_lockedPressed = false;
|
||||
|
@ -348,16 +318,16 @@ void ChatsFiltersTabs::mouseReleaseEvent(QMouseEvent *e) {
|
|||
}
|
||||
}
|
||||
} else {
|
||||
Ui::SettingsSlider::mouseReleaseEvent(&m);
|
||||
Ui::SettingsSlider::mouseReleaseEvent(e);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
Ui::RpWidget::mouseReleaseEvent(&m);
|
||||
Ui::RpWidget::mouseReleaseEvent(e);
|
||||
}
|
||||
}
|
||||
|
||||
void ChatsFiltersTabs::contextMenuEvent(QContextMenuEvent *e) {
|
||||
const auto pos = e->pos() + QPoint(-st::dialogsSearchTabsPadding, 0);
|
||||
const auto pos = e->pos();
|
||||
if (pos.x() >= _lockedFromX) {
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -29,8 +29,7 @@ public:
|
|||
|
||||
bool setSectionsAndCheckChanged(std::vector<QString> &§ions);
|
||||
|
||||
[[nodiscard]] int centerOfSection(int section) const;
|
||||
void fitWidthToSections();
|
||||
void fitWidthToSections() override;
|
||||
void setUnreadCount(int index, int unreadCount, bool muted);
|
||||
void setLockedFrom(int index);
|
||||
|
||||
|
|
|
@ -180,7 +180,6 @@ not_null<Ui::RpWidget*> AddChatFiltersTabsStrip(
|
|||
Window::SessionController *controller,
|
||||
bool trackActiveFilterAndUnreadAndReorder) {
|
||||
|
||||
const auto &scrollSt = st::defaultScrollArea;
|
||||
const auto wrap = Ui::CreateChild<Ui::SlideWrap<Ui::RpWidget>>(
|
||||
parent,
|
||||
object_ptr<Ui::RpWidget>(parent));
|
||||
|
@ -194,7 +193,7 @@ not_null<Ui::RpWidget*> AddChatFiltersTabsStrip(
|
|||
const auto container = wrap->entity();
|
||||
const auto scroll = Ui::CreateChild<Ui::ScrollArea>(
|
||||
container,
|
||||
scrollSt,
|
||||
st::dialogsTabsScroll,
|
||||
true);
|
||||
const auto slider = scroll->setOwnedWidget(
|
||||
object_ptr<Ui::ChatsFiltersTabs>(
|
||||
|
@ -457,7 +456,7 @@ not_null<Ui::RpWidget*> AddChatFiltersTabsStrip(
|
|||
parent->widthValue() | rpl::filter(rpl::mappers::_1 > 0),
|
||||
slider->heightValue() | rpl::filter(rpl::mappers::_1 > 0)
|
||||
) | rpl::start_with_next([=](int w, int h) {
|
||||
scroll->resize(w, h + scrollSt.deltax * 4);
|
||||
scroll->resize(w, h);
|
||||
container->resize(w, h);
|
||||
wrap->resize(w, h);
|
||||
}, wrap->lifetime());
|
||||
|
|
|
@ -242,6 +242,27 @@ SettingsSlider::SettingsSlider(
|
|||
setSelectOnPress(_st.ripple.showDuration == 0);
|
||||
}
|
||||
|
||||
const style::SettingsSlider &SettingsSlider::st() const {
|
||||
return _st;
|
||||
}
|
||||
|
||||
int SettingsSlider::centerOfSection(int section) const {
|
||||
const auto widths = countSectionsWidths(0);
|
||||
auto result = 0;
|
||||
if (section >= 0 && section < widths.size()) {
|
||||
for (auto i = 0; i < section; i++) {
|
||||
result += widths[i];
|
||||
}
|
||||
result += widths[section] / 2;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
void SettingsSlider::fitWidthToSections() {
|
||||
const auto widths = countSectionsWidths(0);
|
||||
resizeToWidth(ranges::accumulate(widths, .0) + _st.padding * 2);
|
||||
}
|
||||
|
||||
void SettingsSlider::setRippleTopRoundRadius(int radius) {
|
||||
_rippleTopRoundRadius = radius;
|
||||
}
|
||||
|
@ -263,7 +284,7 @@ void SettingsSlider::resizeSections(int newWidth) {
|
|||
const auto sectionWidths = countSectionsWidths(newWidth);
|
||||
|
||||
auto skip = 0;
|
||||
auto x = 0.;
|
||||
auto x = _st.padding * 1.;
|
||||
auto sectionWidth = sectionWidths.begin();
|
||||
enumerateSections([&](Section §ion) {
|
||||
Expects(sectionWidth != sectionWidths.end());
|
||||
|
@ -280,7 +301,9 @@ void SettingsSlider::resizeSections(int newWidth) {
|
|||
|
||||
std::vector<float64> SettingsSlider::countSectionsWidths(int newWidth) const {
|
||||
const auto count = getSectionsCount();
|
||||
const auto sectionsWidth = newWidth - (count - 1) * _st.barSkip;
|
||||
const auto sectionsWidth = newWidth
|
||||
- 2 * _st.padding
|
||||
- (count - 1) * _st.barSkip;
|
||||
const auto sectionWidth = sectionsWidth / float64(count);
|
||||
|
||||
auto result = std::vector<float64>(count, sectionWidth);
|
||||
|
|
|
@ -130,6 +130,11 @@ public:
|
|||
QWidget *parent,
|
||||
const style::SettingsSlider &st = st::defaultSettingsSlider);
|
||||
|
||||
[[nodiscard]] const style::SettingsSlider &st() const;
|
||||
|
||||
[[nodiscard]] int centerOfSection(int section) const;
|
||||
virtual void fitWidthToSections();
|
||||
|
||||
void setRippleTopRoundRadius(int radius);
|
||||
|
||||
protected:
|
||||
|
|
Loading…
Add table
Reference in a new issue