From c305246d211c4be54eb1195eb96b7a44a92e1aae Mon Sep 17 00:00:00 2001 From: John Preston Date: Mon, 9 Mar 2020 13:04:00 +0400 Subject: [PATCH] Move sidebar mainmenu button outside the scroll. --- Telegram/SourceFiles/window/window.style | 49 ++++-- .../window/window_filters_menu.cpp | 156 ++++++++++-------- .../SourceFiles/window/window_filters_menu.h | 11 +- Telegram/lib_ui | 2 +- 4 files changed, 133 insertions(+), 85 deletions(-) diff --git a/Telegram/SourceFiles/window/window.style b/Telegram/SourceFiles/window/window.style index 8762e62a8..58080fa88 100644 --- a/Telegram/SourceFiles/window/window.style +++ b/Telegram/SourceFiles/window/window.style @@ -246,18 +246,43 @@ createThemeLink: InputField(defaultInputField) { } windowFiltersWidth: 72px; -windowFiltersMainMenu: icon {{ "dialogs_menu", sideBarIconFg }}; -windowFiltersMainMenuIconTop: 12px; -windowFiltersIconTop: 8px; -windowFiltersAll: icon {{ "filters_all", sideBarIconFg }}; -windowFiltersAllActive: icon {{ "filters_all_active", sideBarIconFgActive }}; -windowFiltersUnread: icon {{ "filters_unread", sideBarIconFg }}; -windowFiltersUnreadActive: icon {{ "filters_unread_active", sideBarIconFgActive }}; -windowFiltersUnmuted: icon {{ "filters_unmuted", sideBarIconFg }}; -windowFiltersUnmutedActive: icon {{ "filters_unmuted_active", sideBarIconFgActive }}; -windowFiltersCustom: icon {{ "filters_custom", sideBarIconFg }}; -windowFiltersCustomActive: icon {{ "filters_custom_active", sideBarIconFgActive }}; -windowFiltersSetup: icon {{ "filters_setup", sideBarIconFg }}; +windowFiltersButton: SideBarButton(defaultSideBarButton) { + textTop: 40px; + textSkip: 6px; + minHeight: 62px; + minTextWidth: 48px; + style: TextStyle(defaultTextStyle) { + font: font(11px semibold); + } + badgeStyle: TextStyle(defaultTextStyle) { + font: font(11px semibold); + } + iconPosition: point(-1px, 6px); +} +windowFiltersMainMenu: SideBarButton(windowFiltersButton) { + icon: icon {{ "dialogs_menu", sideBarIconFg }}; + iconPosition: point(-1px, -1px); + minHeight: 54px; +} +windowFiltersAll: SideBarButton(windowFiltersButton) { + icon: icon {{ "filters_all", sideBarIconFg }}; + iconActive: icon {{ "filters_all_active", sideBarIconFgActive }}; +} +windowFiltersUnread: SideBarButton(windowFiltersButton) { + icon: icon {{ "filters_unread", sideBarIconFg }}; + iconActive: icon {{ "filters_unread_active", sideBarIconFgActive }}; +} +windowFiltersUnmuted: SideBarButton(windowFiltersButton) { + icon: icon {{ "filters_unmuted", sideBarIconFg }}; + iconActive: icon {{ "filters_unmuted_active", sideBarIconFgActive }}; +} +windowFiltersCustom: SideBarButton(windowFiltersButton) { + icon: icon {{ "filters_custom", sideBarIconFg }}; + iconActive: icon {{ "filters_custom_active", sideBarIconFgActive }}; +} +windowFiltersSetup: SideBarButton(windowFiltersButton) { + icon: icon {{ "filters_setup", sideBarIconFg }}; +} // Mac specific diff --git a/Telegram/SourceFiles/window/window_filters_menu.cpp b/Telegram/SourceFiles/window/window_filters_menu.cpp index 63aa4ddea..5a0d4b194 100644 --- a/Telegram/SourceFiles/window/window_filters_menu.cpp +++ b/Telegram/SourceFiles/window/window_filters_menu.cpp @@ -43,23 +43,11 @@ enum class Type { return Type::Custom; } -[[nodiscard]] std::array ComputeIcons(Type type) { +[[nodiscard]] const style::SideBarButton &ComputeStyle(Type type) { switch (type) { - case Type::Unread: - return { - &st::windowFiltersUnread, - &st::windowFiltersUnreadActive - }; - case Type::Unmuted: - return { - &st::windowFiltersUnmuted, - &st::windowFiltersUnmutedActive - }; - case Type::Custom: - return { - &st::windowFiltersCustom, - &st::windowFiltersCustomActive - }; + case Type::Unread: return st::windowFiltersUnread; + case Type::Unmuted: return st::windowFiltersUnmuted; + case Type::Custom: return st::windowFiltersCustom; } Unexpected("Filter type in FiltersMenu::refresh."); } @@ -71,15 +59,46 @@ FiltersMenu::FiltersMenu( not_null session) : _session(session) , _parent(parent) -, _widget(_parent, st::defaultSideBarMenu) { +, _outer(_parent) +, _menu(&_outer, QString(), st::windowFiltersMainMenu) +, _scroll(&_outer) +, _container( + _scroll.setOwnedWidget( + object_ptr(&_scroll))) { setup(); } void FiltersMenu::setup() { + _outer.setAttribute(Qt::WA_OpaquePaintEvent); + _outer.show(); + _outer.paintRequest( + ) | rpl::start_with_next([=](QRect clip) { + const auto bottom = _scroll.y() + _container->height(); + const auto height = _outer.height() - bottom; + if (height <= 0) { + return; + } + const auto fill = clip.intersected( + QRect(0, bottom, _outer.width(), height)); + if (!fill.isEmpty()) { + auto p = QPainter(&_outer); + p.setPen(Qt::NoPen); + p.setBrush(st::windowFiltersAll.textBg); + p.drawRect(fill); + } + }, _outer.lifetime()); + _parent->heightValue( ) | rpl::start_with_next([=](int height) { - _widget.setGeometry({ 0, 0, st::windowFiltersWidth, height }); - }, _widget.lifetime()); + const auto width = st::windowFiltersWidth; + _outer.setGeometry({ 0, 0, width, height }); + _menu.resizeToWidth(width); + _menu.move(0, 0); + _scroll.setGeometry( + { 0, _menu.height(), width, height - _menu.height() }); + _container->resizeToWidth(width); + _container->move(0, 0); + }, _outer.lifetime()); const auto filters = &_session->session().data().chatsFilters(); rpl::single( @@ -88,66 +107,63 @@ void FiltersMenu::setup() { filters->changed() ) | rpl::start_with_next([=] { refresh(); - }, _widget.lifetime()); + }, _outer.lifetime()); + _activeFilterId = _session->activeChatsFilterCurrent(); _session->activeChatsFilter( - ) | rpl::start_with_next([=](FilterId id) { - _widget.setActive(QString::number(id)); - }, _widget.lifetime()); - - _widget.activateRequests( - ) | rpl::start_with_next([=](const QString &id) { - if (id == "main_menu") { - _session->widget()->showMainMenu(); - } else if (id == "setup") { - } else if (const auto filterId = id.toInt()) { - _session->setActiveChatsFilter(filterId); - } else { - _session->setActiveChatsFilter(0); + ) | rpl::filter([=](FilterId id) { + return id != _activeFilterId; + }) | rpl::start_with_next([=](FilterId id) { + const auto i = _filters.find(_activeFilterId); + if (i != end(_filters)) { + i->second->setActive(false); } - }, _widget.lifetime()); + _activeFilterId = id; + const auto j = _filters.find(_activeFilterId); + if (j != end(_filters)) { + j->second->setActive(true); + } + }, _outer.lifetime()); + + _menu.setClickedCallback([=] { + _session->widget()->showMainMenu(); + }); } void FiltersMenu::refresh() { - auto items = std::vector(); - items.push_back({ - "main_menu", - QString(), - QString(), - &st::windowFiltersMainMenu, - &st::windowFiltersMainMenu, - st::windowFiltersMainMenuIconTop - }); - items.push_back({ - QString::number(0), - "All Chats", - QString(), - &st::windowFiltersAll, - &st::windowFiltersAllActive, - st::windowFiltersIconTop - }); const auto filters = &_session->session().data().chatsFilters(); - for (const auto &filter : filters->list()) { - const auto type = ComputeType(filter); - const auto icons = ComputeIcons(type); - items.push_back({ - QString::number(filter.id()), - filter.title(), - QString(), - icons[0], - icons[1], - st::windowFiltersIconTop + auto now = base::flat_map>(); + const auto prepare = [&]( + FilterId id, + const QString &title, + const style::SideBarButton &st, + const QString &badge) { + auto button = base::unique_qptr(_container->add( + object_ptr( + _container, + title, + st))); + button->setBadge(badge); + button->setActive(_session->activeChatsFilterCurrent() == id); + button->setClickedCallback([=] { + if (id >= 0) { + _session->setActiveChatsFilter(id); + } else { + // #TODO filters + } }); + now.emplace(id, std::move(button)); + }; + prepare(0, "All chats", st::windowFiltersAll, QString()); + for (const auto filter : filters->list()) { + prepare( + filter.id(), + filter.title(), + ComputeStyle(ComputeType(filter)), + QString()); } - items.push_back({ - "setup", - "Setup", - QString(), - &st::windowFiltersSetup, - &st::windowFiltersSetup, - st::windowFiltersIconTop - }); - _widget.setItems(items); + prepare(-1, "Setup", st::windowFiltersSetup, QString()); + _filters = std::move(now); } } // namespace Window diff --git a/Telegram/SourceFiles/window/window_filters_menu.h b/Telegram/SourceFiles/window/window_filters_menu.h index 0555da74f..985fc9af2 100644 --- a/Telegram/SourceFiles/window/window_filters_menu.h +++ b/Telegram/SourceFiles/window/window_filters_menu.h @@ -7,7 +7,9 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL */ #pragma once -#include "ui/widgets/side_bar_menu.h" +#include "ui/widgets/side_bar_button.h" +#include "ui/widgets/scroll_area.h" +#include "ui/wrap/vertical_layout.h" namespace Window { @@ -25,7 +27,12 @@ private: const not_null _session; const not_null _parent; - Ui::SideBarMenu _widget; + Ui::RpWidget _outer; + Ui::SideBarButton _menu; + Ui::ScrollArea _scroll; + not_null _container; + base::flat_map> _filters; + FilterId _activeFilterId = 0; }; diff --git a/Telegram/lib_ui b/Telegram/lib_ui index 81e9a8083..1b673b7e4 160000 --- a/Telegram/lib_ui +++ b/Telegram/lib_ui @@ -1 +1 @@ -Subproject commit 81e9a80831555ae7908ee86fb15ea791fadd0891 +Subproject commit 1b673b7e406af46e931fd37feabaf9e277ada93b