/* This file is part of Telegram Desktop, the official desktop application for the Telegram messaging service. For license and copyright information please follow this link: https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL */ #include "settings/settings_common.h" #include "apiwrap.h" #include "api/api_cloud_password.h" #include "settings/cloud_password/settings_cloud_password_email_confirm.h" #include "settings/settings_chat.h" #include "settings/settings_advanced.h" #include "settings/settings_information.h" #include "settings/settings_main.h" #include "settings/settings_notifications.h" #include "settings/settings_privacy_security.h" #include "settings/settings_folders.h" #include "settings/settings_calls.h" #include "settings/settings_experimental.h" #include "core/application.h" #include "core/core_cloud_password.h" #include "ui/wrap/padding_wrap.h" #include "ui/wrap/vertical_layout.h" #include "ui/widgets/labels.h" #include "ui/widgets/box_content_divider.h" #include "ui/widgets/buttons.h" #include "ui/widgets/continuous_sliders.h" #include "ui/widgets/menu/menu_add_action_callback.h" #include "ui/painter.h" #include "boxes/abstract_box.h" #include "boxes/sessions_box.h" #include "window/themes/window_theme_editor_box.h" #include "window/window_session_controller.h" #include "window/window_controller.h" #include "lang/lang_keys.h" #include "mainwindow.h" #include "main/main_session.h" #include "main/main_domain.h" #include "lottie/lottie_icon.h" #include "base/options.h" #include "styles/style_layers.h" #include "styles/style_settings.h" #include "styles/style_menu_icons.h" #include namespace Settings { namespace { base::options::toggle OptionMonoSettingsIcons({ .id = kOptionMonoSettingsIcons, .name = "Mono settings and menu icons", .description = "Use a single color for settings and main menu icons.", }); } // namespace const char kOptionMonoSettingsIcons[] = "mono-settings-icons"; Icon::Icon(IconDescriptor descriptor) : _icon(descriptor.icon) { const auto background = [&]() -> const style::color* { if (descriptor.type == IconType::Simple) { return nullptr; } else if (OptionMonoSettingsIcons.value()) { return &st::transparent; } else if (descriptor.color > 0) { const auto list = std::array{ &st::settingsIconBg1, &st::settingsIconBg2, &st::settingsIconBg3, &st::settingsIconBg4, &st::settingsIconBg5, &st::settingsIconBg6, (const style::color*)nullptr, &st::settingsIconBg8, &st::settingsIconBgArchive, }; Assert(descriptor.color < 10 && descriptor.color != 7); return list[descriptor.color - 1]; } return descriptor.background; }(); if (background) { const auto radius = (descriptor.type == IconType::Rounded) ? st::settingsIconRadius : (std::min(_icon->width(), _icon->height()) / 2); _background.emplace(radius, *background); } else if (const auto brush = descriptor.backgroundBrush) { const auto radius = (descriptor.type == IconType::Rounded) ? st::settingsIconRadius : (std::min(_icon->width(), _icon->height()) / 2); _backgroundBrush.emplace(radius, std::move(*brush)); } } void Icon::paint(QPainter &p, QPoint position) const { paint(p, position.x(), position.y()); } void Icon::paint(QPainter &p, int x, int y) const { if (_background) { _background->paint(p, { { x, y }, _icon->size() }); } else if (_backgroundBrush) { PainterHighQualityEnabler hq(p); p.setPen(Qt::NoPen); p.setBrush(_backgroundBrush->second); p.drawRoundedRect( QRect(QPoint(x, y), _icon->size()), _backgroundBrush->first, _backgroundBrush->first); } if (OptionMonoSettingsIcons.value()) { _icon->paint(p, { x, y }, 2 * x + _icon->width(), st::menuIconFg->c); } else { _icon->paint(p, { x, y }, 2 * x + _icon->width()); } } int Icon::width() const { return _icon->width(); } int Icon::height() const { return _icon->height(); } QSize Icon::size() const { return _icon->size(); } void AddSkip(not_null container) { AddSkip(container, st::settingsSectionSkip); } void AddSkip(not_null container, int skip) { container->add(object_ptr( container, skip)); } void AddDivider(not_null container) { container->add(object_ptr(container)); } void AddDividerText( not_null container, rpl::producer text) { container->add(object_ptr( container, object_ptr( container, std::move(text), st::boxDividerLabel), st::settingsDividerLabelPadding)); } void AddButtonIcon( not_null button, const style::SettingsButton &st, IconDescriptor &&descriptor) { Expects(descriptor.icon != nullptr); struct IconWidget { IconWidget(QWidget *parent, IconDescriptor &&descriptor) : widget(parent) , icon(std::move(descriptor)) { } Ui::RpWidget widget; Icon icon; }; const auto icon = button->lifetime().make_state( button, std::move(descriptor)); icon->widget.setAttribute(Qt::WA_TransparentForMouseEvents); icon->widget.resize(icon->icon.size()); button->sizeValue( ) | rpl::start_with_next([=, left = st.iconLeft](QSize size) { icon->widget.moveToLeft( left, (size.height() - icon->widget.height()) / 2, size.width()); }, icon->widget.lifetime()); icon->widget.paintRequest( ) | rpl::start_with_next([=] { auto p = QPainter(&icon->widget); icon->icon.paint(p, 0, 0); }, icon->widget.lifetime()); } object_ptr