Allow scrolling themes list.
This commit is contained in:
parent
a8efd0ef3d
commit
1424ea3540
|
@ -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(),
|
||||||
tr::lng_chat_theme_title(),
|
skip + st::boxTitle.style.font->height));
|
||||||
st::boxTitle),
|
auto title = CreateChild<FlatLabel>(
|
||||||
style::margins{ skip * 2, skip, skip * 2, 0 });
|
titleWrap,
|
||||||
|
tr::lng_chat_theme_title(),
|
||||||
|
st::boxTitle);
|
||||||
_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());
|
||||||
_inner->setCursor(byPoint(mouse->pos())
|
const auto skip = _inner->width() - _content->width();
|
||||||
? style::cur_pointer
|
if (skip <= 0) {
|
||||||
: style::cur_default);
|
_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())
|
||||||
|
? style::cur_pointer
|
||||||
|
: 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
|
||||||
|
|
|
@ -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;
|
||||||
|
|
Loading…
Reference in New Issue