Slightly improved style of box for premium accounts limits.

Added an icon for the info bubble.
Added a gradient color to selected account.
Respected an order of accounts from settings.
This commit is contained in:
23rd 2022-06-02 01:21:26 +03:00
parent c138c74ab3
commit 9e4d47dcc0
10 changed files with 77 additions and 44 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 663 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

View file

@ -1096,6 +1096,7 @@ premiumIconFolders: icon {{ "limits/folders", settingsIconFg }};
premiumIconGroups: icon {{ "limits/groups", settingsIconFg }};
premiumIconLinks: icon {{ "limits/links", settingsIconFg }};
premiumIconPins: icon {{ "limits/pins", settingsIconFg }};
premiumIconAccounts: icon {{ "limits/accounts", settingsIconFg }};
premiumAccountsCheckbox: RoundImageCheckbox(defaultPeerListCheckbox) {
imageRadius: 27px;

View file

@ -26,6 +26,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "data/data_session.h"
#include "lang/lang_keys.h"
#include "settings/settings_common.h"
#include "settings/settings_information.h" // Settings::OrderedAccounts().
#include "settings/settings_premium.h"
#include "base/unixtime.h"
#include "apiwrap.h"
@ -888,7 +889,7 @@ void AccountsLimitBox(
const auto defaultLimit = Main::Domain::kMaxAccounts;
const auto premiumLimit = Main::Domain::kPremiumMaxAccounts;
const auto &accounts = session->domain().accounts();
const auto accounts = Settings::OrderedAccounts();
const auto current = int(accounts.size());
auto text = tr::lng_accounts_limit1(
@ -909,7 +910,7 @@ void AccountsLimitBox(
current,
(current == premiumLimit) ? premiumLimit : (current * 2),
std::nullopt,
&st::premiumIconFiles);
&st::premiumIconAccounts);
Settings::AddSkip(top, st::premiumLineTextSkip);
Ui::Premium::AddLimitRow(top, 0, std::nullopt, defaultLimit);
Settings::AddSkip(top, st::premiumInfographicPadding.bottom());
@ -935,9 +936,8 @@ void AccountsLimitBox(
box->addButton(tr::lng_continue(), [=]() mutable {
const auto ref = QString();
const auto &accounts = session->domain().accounts();
const auto wasAccount = &session->account();
const auto nowAccount = accounts[group->value()].account.get();
const auto nowAccount = accounts[group->value()];
if (wasAccount == nowAccount) {
Settings::ShowPremium(session, ref);
return;
@ -967,9 +967,8 @@ void AccountsLimitBox(
auto &&entries = ranges::views::all(
accounts
) | ranges::views::transform([&](
const Main::Domain::AccountWithIndex &d) {
const auto user = d.account->session().user();
) | ranges::views::transform([&](not_null<Main::Account*> account) {
const auto user = account->session().user();
return Args::Entry{ user->name, PaintUserpicCallback(user, false) };
});

View file

@ -619,29 +619,6 @@ void SetupAccountsWrap(
return result;
}
[[nodiscard]] std::vector<not_null<Main::Account*>> OrderedAccounts() {
using namespace Main;
const auto order = Core::App().settings().accountsOrder();
auto accounts = ranges::views::all(
Core::App().domain().accounts()
) | ranges::views::transform([](const Domain::AccountWithIndex &a) {
return not_null{ a.account.get() };
}) | ranges::to_vector;
ranges::stable_sort(accounts, [&](
not_null<Account*> a,
not_null<Account*> b) {
const auto aIt = a->sessionExists()
? ranges::find(order, a->session().uniqueId())
: end(order);
const auto bIt = b->sessionExists()
? ranges::find(order, b->session().uniqueId())
: end(order);
return aIt < bIt;
});
return accounts;
}
AccountsList::AccountsList(
not_null<Ui::VerticalLayout*> container,
not_null<Window::SessionController*> controller)
@ -853,6 +830,29 @@ AccountsEvents SetupAccounts(
};
}
std::vector<not_null<Main::Account*>> OrderedAccounts() {
using namespace Main;
const auto order = Core::App().settings().accountsOrder();
auto accounts = ranges::views::all(
Core::App().domain().accounts()
) | ranges::views::transform([](const Domain::AccountWithIndex &a) {
return not_null{ a.account.get() };
}) | ranges::to_vector;
ranges::stable_sort(accounts, [&](
not_null<Account*> a,
not_null<Account*> b) {
const auto aIt = a->sessionExists()
? ranges::find(order, a->session().uniqueId())
: end(order);
const auto bIt = b->sessionExists()
? ranges::find(order, b->session().uniqueId())
: end(order);
return aIt < bIt;
});
return accounts;
}
Dialogs::Ui::UnreadBadgeStyle BadgeStyle() {
auto result = Dialogs::Ui::UnreadBadgeStyle();
result.font = st::mainMenuBadgeFont;

View file

@ -13,6 +13,10 @@ namespace Dialogs::Ui {
struct UnreadBadgeStyle;
} // namespace Dialogs::Ui
namespace Main {
class Account;
} // namespace Main
namespace Settings {
class Information : public Section<Information> {
@ -35,6 +39,7 @@ AccountsEvents SetupAccounts(
not_null<Ui::VerticalLayout*> container,
not_null<Window::SessionController*> controller);
[[nodiscard]] std::vector<not_null<::Main::Account*>> OrderedAccounts();
[[nodiscard]] Dialogs::Ui::UnreadBadgeStyle BadgeStyle();
struct UnreadBadge {

View file

@ -683,7 +683,7 @@ void AddAccountsRow(
const auto width = widget->width();
const auto photoLeft = (width - (imageRadius * 2)) / 2;
const auto photoTop = checkSelectWidth;
auto &account = state->accounts[index];
const auto &account = state->accounts[index];
account.checkbox.paint(p, photoLeft, photoTop, width);
const auto &badgeSize = account.badge.size()
@ -719,10 +719,18 @@ void AddAccountsRow(
const auto count = state->accounts.size();
const auto columnWidth = size.width() / count;
for (auto i = 0; i < count; i++) {
state->accounts[i].widget->resize(columnWidth, size.height());
auto &account = state->accounts[i];
account.widget->resize(columnWidth, size.height());
const auto left = columnWidth * i;
state->accounts[i].widget->moveToLeft(left, 0);
state->accounts[i].badge = cacheBadge(left + columnWidth / 2);
account.widget->moveToLeft(left, 0);
account.badge = cacheBadge(left + columnWidth / 2);
const auto photoWidth = ((imageRadius + checkSelectWidth) * 2);
account.checkbox.setColorOverride(QBrush(
ComputeGradient(
container,
left + (columnWidth - photoWidth) / 2,
photoWidth)));
}
}, container->lifetime());
}

View file

@ -258,7 +258,7 @@ RoundCheckbox::RoundCheckbox(const style::RoundCheckbox &st, Fn<void()> updateCa
, _updateCallback(updateCallback) {
}
void RoundCheckbox::paint(Painter &p, int x, int y, int outerWidth, float64 masterScale) {
void RoundCheckbox::paint(Painter &p, int x, int y, int outerWidth, float64 masterScale) const {
if (!_st.size
|| (!_checkedProgress.animating()
&& !_checked
@ -361,7 +361,7 @@ RoundImageCheckbox::RoundImageCheckbox(const style::RoundImageCheckbox &st, Fn<v
, _check(_st.check, _updateCallback) {
}
void RoundImageCheckbox::paint(Painter &p, int x, int y, int outerWidth) {
void RoundImageCheckbox::paint(Painter &p, int x, int y, int outerWidth) const {
auto selectionLevel = _selection.value(checked() ? 1. : 0.);
if (_selection.animating()) {
auto userpicRadius = qRound(kWideScale * (_st.imageRadius + (_st.imageSmallRadius - _st.imageRadius) * selectionLevel));
@ -374,9 +374,6 @@ void RoundImageCheckbox::paint(Painter &p, int x, int y, int outerWidth) {
PainterHighQualityEnabler hq(p);
p.drawPixmapLeft(to, outerWidth, _wideCache, from);
} else {
if (!_wideCache.isNull()) {
_wideCache = QPixmap();
}
auto userpicRadius = checked() ? _st.imageSmallRadius : _st.imageRadius;
auto userpicShift = _st.imageRadius - userpicRadius;
auto userpicLeft = x + userpicShift;
@ -388,8 +385,9 @@ void RoundImageCheckbox::paint(Painter &p, int x, int y, int outerWidth) {
PainterHighQualityEnabler hq(p);
p.setOpacity(std::clamp(selectionLevel, 0., 1.));
p.setBrush(Qt::NoBrush);
auto pen = _st.selectFg->p;
pen.setWidth(_st.selectWidth);
const auto pen = QPen(
_fgOverride ? (*_fgOverride) : _st.selectFg->b,
_st.selectWidth);
p.setPen(pen);
p.drawEllipse(style::rtlrect(x, y, _st.imageRadius * 2, _st.imageRadius * 2, outerWidth));
p.setOpacity(1.);
@ -416,7 +414,21 @@ void RoundImageCheckbox::setChecked(bool newChecked, anim::type animated) {
}
if (animated == anim::type::normal) {
prepareWideCache();
_selection.start(_updateCallback, checked() ? 0 : 1, checked() ? 1 : 0, _st.selectDuration, anim::bumpy(1.25));
const auto from = checked() ? 0. : 1.;
const auto to = checked() ? 1. : 0.;
_selection.start(
[=](float64 value) {
if (_updateCallback) {
_updateCallback();
}
if (value == to) {
_wideCache = QPixmap();
}
},
from,
to,
_st.selectDuration,
anim::bumpy(1.25));
} else {
_selection.stop();
}
@ -439,4 +451,8 @@ void RoundImageCheckbox::prepareWideCache() {
}
}
void RoundImageCheckbox::setColorOverride(std::optional<QBrush> fg) {
_fgOverride = fg;
}
} // namespace Ui

View file

@ -16,7 +16,7 @@ class RoundCheckbox {
public:
RoundCheckbox(const style::RoundCheckbox &st, Fn<void()> updateCallback);
void paint(Painter &p, int x, int y, int outerWidth, float64 masterScale = 1.);
void paint(Painter &p, int x, int y, int outerWidth, float64 masterScale = 1.) const;
void setDisplayInactive(bool displayInactive);
bool checked() const {
@ -47,9 +47,11 @@ public:
using PaintRoundImage = Fn<void(Painter &p, int x, int y, int outerWidth, int size)>;
RoundImageCheckbox(const style::RoundImageCheckbox &st, Fn<void()> updateCallback, PaintRoundImage &&paintRoundImage);
void paint(Painter &p, int x, int y, int outerWidth);
void paint(Painter &p, int x, int y, int outerWidth) const;
float64 checkedAnimationRatio() const;
void setColorOverride(std::optional<QBrush> fg);
bool checked() const {
return _check.checked();
}
@ -73,6 +75,8 @@ private:
RoundCheckbox _check;
std::optional<QBrush> _fgOverride;
};
} // namespace Ui