Improve chat theme selector design.
This commit is contained in:
parent
1b6b0c1732
commit
a27ef55ff8
|
@ -3653,9 +3653,10 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
"lng_filters_bar_view#other" = "Click here to view them";
|
"lng_filters_bar_view#other" = "Click here to view them";
|
||||||
|
|
||||||
"lng_chat_theme_change" = "Change colors";
|
"lng_chat_theme_change" = "Change colors";
|
||||||
|
"lng_chat_theme_wallpaper" = "Set Wallpaper";
|
||||||
"lng_chat_theme_none" = "No\nTheme";
|
"lng_chat_theme_none" = "No\nTheme";
|
||||||
"lng_chat_theme_apply" = "Apply Theme";
|
"lng_chat_theme_apply" = "Apply Theme";
|
||||||
"lng_chat_theme_title" = "Select theme";
|
"lng_chat_theme_title" = "Choose theme";
|
||||||
"lng_chat_theme_cant_voice" = "Sorry, you can't change the chat theme while you're having an unsent voice message.";
|
"lng_chat_theme_cant_voice" = "Sorry, you can't change the chat theme while you're having an unsent voice message.";
|
||||||
|
|
||||||
"lng_photo_editor_menu_delete" = "Delete";
|
"lng_photo_editor_menu_delete" = "Delete";
|
||||||
|
|
|
@ -269,6 +269,18 @@ settingsThemeMinSkip: 4px;
|
||||||
settingsThemeNotSupportedBg: windowBgOver;
|
settingsThemeNotSupportedBg: windowBgOver;
|
||||||
settingsThemeNotSupportedIcon: icon {{ "theme_preview", menuIconFg }};
|
settingsThemeNotSupportedIcon: icon {{ "theme_preview", menuIconFg }};
|
||||||
|
|
||||||
|
chatThemeTitlePadding: margins(22px, 13px, 22px, 9px);
|
||||||
|
chatThemePreviewSize: size(80px, 108px);
|
||||||
|
chatThemeBubbleSize: size(48px, 22px);
|
||||||
|
chatThemeBubbleRadius: 10px;
|
||||||
|
chatThemeBubblePosition: point(6px, 12px);
|
||||||
|
chatThemeBubbleSkip: 6px;
|
||||||
|
chatThemeEntrySkip: 10px;
|
||||||
|
chatThemeEntryMargin: margins(16px, 10px, 16px, 8px);
|
||||||
|
chatThemeEmptyPreviewTop: 16px;
|
||||||
|
chatThemeEmojiBottom: 12px;
|
||||||
|
chatThemeButtonMargin: margins(10px, 0px, 10px, 8px);
|
||||||
|
|
||||||
autoDownloadLimitButton: SettingsButton(settingsButtonNoIcon) {
|
autoDownloadLimitButton: SettingsButton(settingsButtonNoIcon) {
|
||||||
padding: margins(22px, 10px, 22px, 0px);
|
padding: margins(22px, 10px, 22px, 0px);
|
||||||
}
|
}
|
||||||
|
|
|
@ -41,7 +41,7 @@ const auto kDisableElement = [] { return u"disable"_q; };
|
||||||
[[nodiscard]] QImage GeneratePreview(not_null<Ui::ChatTheme*> theme) {
|
[[nodiscard]] QImage GeneratePreview(not_null<Ui::ChatTheme*> theme) {
|
||||||
const auto &background = theme->background();
|
const auto &background = theme->background();
|
||||||
const auto &colors = background.colors;
|
const auto &colors = background.colors;
|
||||||
const auto size = st::settingsThemePreviewSize;
|
const auto size = st::chatThemePreviewSize;
|
||||||
auto prepared = background.prepared;
|
auto prepared = background.prepared;
|
||||||
const auto paintPattern = [&](QPainter &p, bool inverted) {
|
const auto paintPattern = [&](QPainter &p, bool inverted) {
|
||||||
if (prepared.isNull()) {
|
if (prepared.isNull()) {
|
||||||
|
@ -91,16 +91,16 @@ const auto kDisableElement = [] { return u"disable"_q; };
|
||||||
const auto sent = QRect(
|
const auto sent = QRect(
|
||||||
QPoint(
|
QPoint(
|
||||||
(size.width()
|
(size.width()
|
||||||
- st::settingsThemeBubbleSize.width()
|
- st::chatThemeBubbleSize.width()
|
||||||
- st::settingsThemeBubblePosition.x()),
|
- st::chatThemeBubblePosition.x()),
|
||||||
st::settingsThemeBubblePosition.y()),
|
st::chatThemeBubblePosition.y()),
|
||||||
st::settingsThemeBubbleSize);
|
st::chatThemeBubbleSize);
|
||||||
const auto received = QRect(
|
const auto received = QRect(
|
||||||
st::settingsThemeBubblePosition.x(),
|
st::chatThemeBubblePosition.x(),
|
||||||
sent.y() + sent.height() + st::settingsThemeBubbleSkip,
|
sent.y() + sent.height() + st::chatThemeBubbleSkip,
|
||||||
sent.width(),
|
sent.width(),
|
||||||
sent.height());
|
sent.height());
|
||||||
const auto radius = st::settingsThemeBubbleRadius;
|
const auto radius = st::chatThemeBubbleRadius;
|
||||||
|
|
||||||
PainterHighQualityEnabler hq(p);
|
PainterHighQualityEnabler hq(p);
|
||||||
p.setPen(Qt::NoPen);
|
p.setPen(Qt::NoPen);
|
||||||
|
@ -124,7 +124,7 @@ const auto kDisableElement = [] { return u"disable"_q; };
|
||||||
|
|
||||||
[[nodiscard]] QImage GenerateEmptyPreview() {
|
[[nodiscard]] QImage GenerateEmptyPreview() {
|
||||||
auto result = QImage(
|
auto result = QImage(
|
||||||
st::settingsThemePreviewSize * style::DevicePixelRatio(),
|
st::chatThemePreviewSize * style::DevicePixelRatio(),
|
||||||
QImage::Format_ARGB32_Premultiplied);
|
QImage::Format_ARGB32_Premultiplied);
|
||||||
result.fill(st::settingsThemeNotSupportedBg->c);
|
result.fill(st::settingsThemeNotSupportedBg->c);
|
||||||
result.setDevicePixelRatio(style::DevicePixelRatio());
|
result.setDevicePixelRatio(style::DevicePixelRatio());
|
||||||
|
@ -132,9 +132,9 @@ const auto kDisableElement = [] { return u"disable"_q; };
|
||||||
auto p = QPainter(&result);
|
auto p = QPainter(&result);
|
||||||
p.setPen(st::menuIconFg);
|
p.setPen(st::menuIconFg);
|
||||||
p.setFont(st::semiboldFont);
|
p.setFont(st::semiboldFont);
|
||||||
const auto top = st::normalFont->height / 2;
|
const auto top = st::chatThemeEmptyPreviewTop;
|
||||||
const auto width = st::settingsThemePreviewSize.width();
|
const auto width = st::chatThemePreviewSize.width();
|
||||||
const auto height = st::settingsThemePreviewSize.height() - top;
|
const auto height = st::chatThemePreviewSize.height() - top;
|
||||||
p.drawText(
|
p.drawText(
|
||||||
QRect(0, top, width, height),
|
QRect(0, top, width, height),
|
||||||
tr::lng_chat_theme_none(tr::now),
|
tr::lng_chat_theme_none(tr::now),
|
||||||
|
@ -194,7 +194,8 @@ void ChooseThemeController::init(rpl::producer<QSize> outer) {
|
||||||
0,
|
0,
|
||||||
object_ptr<FixedHeightWidget>(
|
object_ptr<FixedHeightWidget>(
|
||||||
_wrap.get(),
|
_wrap.get(),
|
||||||
skip + st::boxTitle.style.font->height + skip));
|
st::boxTitle.style.font->height),
|
||||||
|
st::chatThemeTitlePadding);
|
||||||
auto title = CreateChild<FlatLabel>(
|
auto title = CreateChild<FlatLabel>(
|
||||||
titleWrap,
|
titleWrap,
|
||||||
tr::lng_chat_theme_title(),
|
tr::lng_chat_theme_title(),
|
||||||
|
@ -204,12 +205,23 @@ void ChooseThemeController::init(rpl::producer<QSize> outer) {
|
||||||
QPainter(_wrap.get()).fillRect(clip, st::windowBg);
|
QPainter(_wrap.get()).fillRect(clip, st::windowBg);
|
||||||
}, lifetime());
|
}, lifetime());
|
||||||
|
|
||||||
|
const auto close = Ui::CreateChild<Ui::IconButton>(
|
||||||
|
_wrap.get(),
|
||||||
|
st::boxTitleClose);
|
||||||
|
close->setClickedCallback([=] { this->close(); });
|
||||||
|
rpl::combine(
|
||||||
|
_wrap->widthValue(),
|
||||||
|
titleWrap->positionValue()
|
||||||
|
) | rpl::start_with_next([=](int width, QPoint position) {
|
||||||
|
close->moveToRight(0, 0, width);
|
||||||
|
}, close->lifetime());
|
||||||
|
|
||||||
initButtons();
|
initButtons();
|
||||||
initList();
|
initList();
|
||||||
|
|
||||||
_inner->positionValue(
|
_inner->positionValue(
|
||||||
) | rpl::start_with_next([=](QPoint position) {
|
) | rpl::start_with_next([=](QPoint position) {
|
||||||
title->move(std::max(position.x(), skip) + skip, skip);
|
title->move(std::max(position.x(), 0), 0);
|
||||||
}, title->lifetime());
|
}, title->lifetime());
|
||||||
|
|
||||||
std::move(
|
std::move(
|
||||||
|
@ -233,31 +245,28 @@ void ChooseThemeController::init(rpl::producer<QSize> outer) {
|
||||||
|
|
||||||
void ChooseThemeController::initButtons() {
|
void ChooseThemeController::initButtons() {
|
||||||
const auto controls = _wrap->add(object_ptr<RpWidget>(_wrap.get()));
|
const auto controls = _wrap->add(object_ptr<RpWidget>(_wrap.get()));
|
||||||
const auto cancel = CreateChild<RoundButton>(
|
|
||||||
controls,
|
|
||||||
tr::lng_cancel(),
|
|
||||||
st::defaultLightButton);
|
|
||||||
const auto apply = CreateChild<RoundButton>(
|
const auto apply = CreateChild<RoundButton>(
|
||||||
controls,
|
controls,
|
||||||
tr::lng_chat_theme_apply(),
|
tr::lng_chat_theme_apply(),
|
||||||
st::defaultActiveButton);
|
st::defaultLightButton);
|
||||||
|
apply->setTextTransform(Ui::RoundButton::TextTransform::NoTransform);
|
||||||
const auto choose = CreateChild<RoundButton>(
|
const auto choose = CreateChild<RoundButton>(
|
||||||
controls,
|
controls,
|
||||||
rpl::single(u"Change Wallpaper"_q),
|
rpl::single(u"Change Wallpaper"_q),
|
||||||
st::defaultActiveButton);
|
st::defaultLightButton);
|
||||||
const auto skip = st::normalFont->spacew * 2;
|
choose->setTextTransform(Ui::RoundButton::TextTransform::NoTransform);
|
||||||
|
|
||||||
|
const auto &margin = st::chatThemeButtonMargin;
|
||||||
controls->resize(
|
controls->resize(
|
||||||
skip + cancel->width() + skip + choose->width() + skip,
|
margin.left() + choose->width() + margin.right(),
|
||||||
apply->height() + skip * 2);
|
margin.top() + choose->height() + margin.bottom());
|
||||||
rpl::combine(
|
rpl::combine(
|
||||||
controls->widthValue(),
|
controls->widthValue(),
|
||||||
cancel->widthValue(),
|
|
||||||
apply->widthValue(),
|
apply->widthValue(),
|
||||||
choose->widthValue(),
|
choose->widthValue(),
|
||||||
_chosen.value()
|
_chosen.value()
|
||||||
) | rpl::start_with_next([=](
|
) | rpl::start_with_next([=](
|
||||||
int outer,
|
int outer,
|
||||||
int cancelWidth,
|
|
||||||
int applyWidth,
|
int applyWidth,
|
||||||
int chooseWidth,
|
int chooseWidth,
|
||||||
QString chosen) {
|
QString chosen) {
|
||||||
|
@ -268,13 +277,11 @@ void ChooseThemeController::initButtons() {
|
||||||
choose->setVisible(!changed);
|
choose->setVisible(!changed);
|
||||||
const auto shown = changed ? apply : choose;
|
const auto shown = changed ? apply : choose;
|
||||||
const auto shownWidth = changed ? applyWidth : chooseWidth;
|
const auto shownWidth = changed ? applyWidth : chooseWidth;
|
||||||
const auto inner = skip + cancelWidth + skip + shownWidth + skip;
|
const auto inner = margin.left() + shownWidth + margin.right();
|
||||||
const auto left = (outer - inner) / 2;
|
const auto left = (outer - inner) / 2;
|
||||||
cancel->moveToLeft(left, 0);
|
shown->moveToLeft(left, margin.top());
|
||||||
shown->moveToRight(left, 0);
|
|
||||||
}, controls->lifetime());
|
}, controls->lifetime());
|
||||||
|
|
||||||
cancel->setClickedCallback([=] { close(); });
|
|
||||||
apply->setClickedCallback([=] {
|
apply->setClickedCallback([=] {
|
||||||
if (const auto chosen = findChosen()) {
|
if (const auto chosen = findChosen()) {
|
||||||
const auto was = _peer->themeEmoji();
|
const auto was = _peer->themeEmoji();
|
||||||
|
@ -326,7 +333,7 @@ void ChooseThemeController::paintEntry(QPainter &p, const Entry &entry) {
|
||||||
const auto emojiTop = geometry.y()
|
const auto emojiTop = geometry.y()
|
||||||
+ geometry.height()
|
+ geometry.height()
|
||||||
- (size / factor)
|
- (size / factor)
|
||||||
- (st::normalFont->spacew * 2);
|
- st::chatThemeEmojiBottom;
|
||||||
Ui::Emoji::Draw(p, entry.emoji, size, emojiLeft, emojiTop);
|
Ui::Emoji::Draw(p, entry.emoji, size, emojiLeft, emojiTop);
|
||||||
|
|
||||||
if (entry.chosen) {
|
if (entry.chosen) {
|
||||||
|
@ -346,7 +353,9 @@ void ChooseThemeController::paintEntry(QPainter &p, const Entry &entry) {
|
||||||
void ChooseThemeController::initList() {
|
void ChooseThemeController::initList() {
|
||||||
_content->resize(
|
_content->resize(
|
||||||
_content->width(),
|
_content->width(),
|
||||||
8 * st::normalFont->spacew + st::settingsThemePreviewSize.height());
|
(st::chatThemeEntryMargin.top()
|
||||||
|
+ st::chatThemePreviewSize.height()
|
||||||
|
+ st::chatThemeEntryMargin.bottom()));
|
||||||
_inner->setMouseTracking(true);
|
_inner->setMouseTracking(true);
|
||||||
|
|
||||||
_inner->paintRequest(
|
_inner->paintRequest(
|
||||||
|
@ -524,10 +533,16 @@ void ChooseThemeController::fill(
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const auto count = int(themes.size()) + 1;
|
const auto count = int(themes.size()) + 1;
|
||||||
const auto single = st::settingsThemePreviewSize;
|
const auto single = st::chatThemePreviewSize;
|
||||||
const auto skip = st::normalFont->spacew * 2;
|
const auto skip = st::chatThemeEntrySkip;
|
||||||
const auto full = single.width() * count + skip * (count + 3);
|
const auto &margin = st::chatThemeEntryMargin;
|
||||||
_inner->resize(full, skip + single.height() + skip);
|
const auto full = margin.left()
|
||||||
|
+ single.width() * count
|
||||||
|
+ skip * (count - 1)
|
||||||
|
+ margin.right();
|
||||||
|
_inner->resize(
|
||||||
|
full,
|
||||||
|
margin.top() + single.height() + margin.bottom());
|
||||||
|
|
||||||
const auto initial = Ui::Emoji::Find(_peer->themeEmoji());
|
const auto initial = Ui::Emoji::Find(_peer->themeEmoji());
|
||||||
if (!initial) {
|
if (!initial) {
|
||||||
|
@ -543,11 +558,11 @@ void ChooseThemeController::fill(
|
||||||
|
|
||||||
_cachingLifetime.destroy();
|
_cachingLifetime.destroy();
|
||||||
const auto old = base::take(_entries);
|
const auto old = base::take(_entries);
|
||||||
auto x = skip * 2;
|
auto x = margin.left();
|
||||||
_entries.push_back({
|
_entries.push_back({
|
||||||
.preview = GenerateEmptyPreview(),
|
.preview = GenerateEmptyPreview(),
|
||||||
.emoji = _disabledEmoji,
|
.emoji = _disabledEmoji,
|
||||||
.geometry = QRect(QPoint(x, skip), single),
|
.geometry = QRect(QPoint(x, margin.top()), single),
|
||||||
.chosen = (_chosen.current() == kDisableElement()),
|
.chosen = (_chosen.current() == kDisableElement()),
|
||||||
});
|
});
|
||||||
Assert(_entries.front().emoji != nullptr);
|
Assert(_entries.front().emoji != nullptr);
|
||||||
|
|
|
@ -1038,7 +1038,7 @@ void Filler::addThemeEdit() {
|
||||||
}
|
}
|
||||||
const auto controller = _controller;
|
const auto controller = _controller;
|
||||||
_addAction(
|
_addAction(
|
||||||
tr::lng_chat_theme_change(tr::now),
|
tr::lng_chat_theme_wallpaper(tr::now),
|
||||||
[=] { controller->toggleChooseChatTheme(user); },
|
[=] { controller->toggleChooseChatTheme(user); },
|
||||||
&st::menuIconChangeColors);
|
&st::menuIconChangeColors);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user