Allow scrolling themes list.

This commit is contained in:
John Preston 2021-09-28 18:53:34 +04:00
parent a8efd0ef3d
commit 1424ea3540
2 changed files with 73 additions and 12 deletions

View File

@ -29,6 +29,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "styles/style_settings.h" #include "styles/style_settings.h"
#include "styles/style_window.h" #include "styles/style_window.h"
#include <QtWidgets/QApplication>
namespace Ui { namespace Ui {
namespace { namespace {
@ -174,13 +176,15 @@ void ChooseThemeController::init(rpl::producer<QSize> outer) {
} }
const auto skip = st::normalFont->spacew * 2; const auto skip = st::normalFont->spacew * 2;
_wrap->insert( const auto titleWrap = _wrap->insert(
0, 0,
object_ptr<FlatLabel>( object_ptr<FixedHeightWidget>(
_wrap.get(), _wrap.get(),
skip + st::boxTitle.style.font->height));
auto title = CreateChild<FlatLabel>(
titleWrap,
tr::lng_chat_theme_title(), tr::lng_chat_theme_title(),
st::boxTitle), st::boxTitle);
style::margins{ skip * 2, skip, skip * 2, 0 });
_wrap->paintRequest( _wrap->paintRequest(
) | rpl::start_with_next([=](QRect clip) { ) | rpl::start_with_next([=](QRect clip) {
QPainter(_wrap.get()).fillRect(clip, st::windowBg); QPainter(_wrap.get()).fillRect(clip, st::windowBg);
@ -189,6 +193,11 @@ void ChooseThemeController::init(rpl::producer<QSize> outer) {
initButtons(); initButtons();
initList(); initList();
_inner->positionValue(
) | rpl::start_with_next([=](QPoint position) {
title->move(std::max(position.x(), skip) + skip, skip);
}, title->lifetime());
std::move( std::move(
outer outer
) | rpl::start_with_next([=](QSize outer) { ) | rpl::start_with_next([=](QSize outer) {
@ -341,13 +350,32 @@ void ChooseThemeController::initList() {
const auto type = event->type(); const auto type = event->type();
if (type == QEvent::MouseMove) { if (type == QEvent::MouseMove) {
const auto mouse = static_cast<QMouseEvent*>(event.get()); const auto mouse = static_cast<QMouseEvent*>(event.get());
const auto skip = _inner->width() - _content->width();
if (skip <= 0) {
_dragStartPosition = _pressPosition = std::nullopt;
} else if (_pressPosition.has_value()
&& ((mouse->globalPos() - *_pressPosition).manhattanLength()
>= QApplication::startDragDistance())) {
_dragStartPosition = base::take(_pressPosition);
_dragStartInnerLeft = _inner->x();
}
if (_dragStartPosition.has_value()) {
const auto shift = mouse->globalPos().x()
- _dragStartPosition->x();
updateInnerLeft(_dragStartInnerLeft + shift);
} else {
_inner->setCursor(byPoint(mouse->pos()) _inner->setCursor(byPoint(mouse->pos())
? style::cur_pointer ? style::cur_pointer
: style::cur_default); : style::cur_default);
}
} else if (type == QEvent::MouseButtonPress) { } else if (type == QEvent::MouseButtonPress) {
const auto mouse = static_cast<QMouseEvent*>(event.get()); const auto mouse = static_cast<QMouseEvent*>(event.get());
if (mouse->button() == Qt::LeftButton) {
_pressPosition = mouse->globalPos();
}
_pressed = chosenText(byPoint(mouse->pos())); _pressed = chosenText(byPoint(mouse->pos()));
} else if (type == QEvent::MouseButtonRelease) { } else if (type == QEvent::MouseButtonRelease) {
_pressPosition = _dragStartPosition = std::nullopt;
const auto mouse = static_cast<QMouseEvent*>(event.get()); const auto mouse = static_cast<QMouseEvent*>(event.get());
const auto entry = byPoint(mouse->pos()); const auto entry = byPoint(mouse->pos());
const auto chosen = chosenText(entry); const auto chosen = chosenText(entry);
@ -364,6 +392,18 @@ void ChooseThemeController::initList() {
_inner->update(); _inner->update();
} }
_pressed = QString(); _pressed = QString();
} else if (type == QEvent::Wheel) {
const auto wheel = static_cast<QWheelEvent*>(event.get());
const auto was = _inner->x();
updateInnerLeft((wheel->angleDelta().x() != 0)
? (was + (wheel->pixelDelta().x()
? wheel->pixelDelta().x()
: wheel->angleDelta().x()))
: (wheel->angleDelta().y() != 0)
? (was + (wheel->pixelDelta().y()
? wheel->pixelDelta().y()
: wheel->angleDelta().y()))
: was);
} }
}, lifetime()); }, lifetime());
@ -377,6 +417,21 @@ void ChooseThemeController::initList() {
} }
} }
}, lifetime()); }, lifetime());
rpl::combine(
_content->widthValue(),
_inner->widthValue()
) | rpl::start_with_next([=] {
updateInnerLeft(_inner->x());
}, lifetime());
}
void ChooseThemeController::updateInnerLeft(int now) {
const auto skip = _content->width() - _inner->width();
const auto clamped = (skip >= 0)
? (skip / 2)
: std::clamp(now, skip, 0);
_inner->move(clamped, 0);
} }
void ChooseThemeController::close() { void ChooseThemeController::close() {
@ -425,13 +480,14 @@ void ChooseThemeController::fill(
const auto full = single.width() * count + skip * (count + 1); const auto full = single.width() * count + skip * (count + 1);
_inner->resize(full, skip + single.height() + skip); _inner->resize(full, skip + single.height() + skip);
const auto initial = Ui::Emoji::Find(_peer->themeEmoji()); const auto initialSelected = Ui::Emoji::Find(_peer->themeEmoji());
_dark.value( _dark.value(
) | rpl::start_with_next([=](bool dark) { ) | rpl::start_with_next([=](bool dark) {
clearCurrentBackgroundState(); clearCurrentBackgroundState();
if (_chosen.isEmpty() && initial) { const auto initialSelect = (_chosen.isEmpty() && initialSelected);
_chosen = initial->text(); if (initialSelect) {
_chosen = initialSelected->text();
} }
_cachingLifetime.destroy(); _cachingLifetime.destroy();
@ -457,11 +513,12 @@ void ChooseThemeController::fill(
} }
const auto &used = dark ? theme.dark : theme.light; const auto &used = dark ? theme.dark : theme.light;
const auto id = used.id; const auto id = used.id;
const auto isChosen = (_chosen == emoji->text());
_entries.push_back({ _entries.push_back({
.id = id, .id = id,
.emoji = emoji, .emoji = emoji,
.geometry = QRect(QPoint(x, skip), single), .geometry = QRect(QPoint(x, skip), single),
.chosen = (_chosen == emoji->text()), .chosen = isChosen,
}); });
_controller->cachedChatThemeValue( _controller->cachedChatThemeValue(
used used

View File

@ -53,6 +53,7 @@ private:
void clearCurrentBackgroundState(); void clearCurrentBackgroundState();
void paintEntry(QPainter &p, const Entry &entry); void paintEntry(QPainter &p, const Entry &entry);
void updateInnerLeft(int now);
[[nodiscard]] Entry *findChosen(); [[nodiscard]] Entry *findChosen();
[[nodiscard]] const Entry *findChosen() const; [[nodiscard]] const Entry *findChosen() const;
@ -67,6 +68,9 @@ private:
std::vector<Entry> _entries; std::vector<Entry> _entries;
QString _pressed; QString _pressed;
QString _chosen; QString _chosen;
std::optional<QPoint> _pressPosition;
std::optional<QPoint> _dragStartPosition;
int _dragStartInnerLeft = 0;
rpl::variable<bool> _shouldBeShown = false; rpl::variable<bool> _shouldBeShown = false;
rpl::variable<bool> _forceHidden = false; rpl::variable<bool> _forceHidden = false;