feat: icon picker

Inspired by Forkgram's icon changer
Need to refactor a bit later
This commit is contained in:
ZavaruKitsu 2023-09-01 17:17:16 +03:00
parent ca9feab071
commit 649e0b0412
42 changed files with 309 additions and 24 deletions

View file

@ -50,6 +50,7 @@ If you enjoy using **AyuGram** and want to send us a tip, here's how you can do
- [Telegram Desktop](https://github.com/telegramdesktop/tdesktop)
- [Kotatogram](https://github.com/kotatogram/kotatogram-desktop)
- [64Gram](https://github.com/TDesktop-x64/tdesktop)
- [Forkgram](https://github.com/forkgram/tdesktop)
- [SQLite](https://github.com/sqlite/sqlite)
- [sqlite_orm](https://github.com/fnc12/sqlite_orm)

View file

@ -106,8 +106,12 @@ PRIVATE
ayu/utils/telegram_helpers.h
ayu/ui/ayu_lottie.cpp
ayu/ui/ayu_lottie.h
ayu/ui/ayu_assets.cpp
ayu/ui/ayu_assets.h
ayu/ui/utils/ayu_profile_values.cpp
ayu/ui/utils/ayu_profile_values.h
ayu/ui/settings/icon_picker.cpp
ayu/ui/settings/icon_picker.h
ayu/ui/settings/settings_ayu.cpp
ayu/ui/settings/settings_ayu.h
ayu/ui/context_menu/context_menu.cpp
@ -1514,6 +1518,8 @@ endif()
nice_target_sources(Telegram ${res_loc}
PRIVATE
qrc/ayu/ayu.qrc
qrc/emoji_1.qrc
qrc/emoji_2.qrc
qrc/emoji_3.qrc

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.2 KiB

After

Width:  |  Height:  |  Size: 6.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.3 KiB

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 507 B

After

Width:  |  Height:  |  Size: 832 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 921 B

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 108 KiB

After

Width:  |  Height:  |  Size: 8.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.3 KiB

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 13 KiB

After

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 921 B

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.7 KiB

After

Width:  |  Height:  |  Size: 3.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 KiB

After

Width:  |  Height:  |  Size: 2.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.5 KiB

After

Width:  |  Height:  |  Size: 5.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 13 KiB

After

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 72 KiB

After

Width:  |  Height:  |  Size: 58 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.7 KiB

After

Width:  |  Height:  |  Size: 3.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.3 KiB

After

Width:  |  Height:  |  Size: 6.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 72 KiB

After

Width:  |  Height:  |  Size: 58 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.3 KiB

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.3 KiB

After

Width:  |  Height:  |  Size: 9.7 KiB

View file

@ -0,0 +1,8 @@
<RCC>
<qresource prefix="/gui">
<file alias="art/ayu/alt/logo256.png">../../art/ayu/alt/logo256.png</file>
<file alias="art/ayu/alt/logo256_no_margin.png">../../art/ayu/alt/logo256_no_margin.png</file>
<file alias="art/ayu/nothing/logo256.png">../../art/ayu/nothing/logo256.png</file>
<file alias="art/ayu/nothing/logo256_no_margin.png">../../art/ayu/nothing/logo256_no_margin.png</file>
</qresource>
</RCC>

View file

@ -229,6 +229,11 @@ namespace AyuSettings
copyUsernameAsLink = val;
}
void AyuGramSettings::set_appIcon(QString val)
{
appIcon = std::move(val);
}
void AyuGramSettings::set_deletedMark(QString val)
{
deletedMark = std::move(val);

View file

@ -14,6 +14,10 @@
namespace AyuSettings
{
const auto DEFAULT_ICON = QString("default");
const auto ALT_ICON = QString("alt");
const auto NOTHING_ICON = QString("nothing");
class AyuGramSettings
{
public:
@ -40,6 +44,7 @@ namespace AyuSettings
copyUsernameAsLink = true;
// ~ Customization
appIcon = DEFAULT_ICON;
deletedMark = "🧹";
editedMark = tr::lng_edited(tr::now);
recentStickersCount = 20;
@ -74,6 +79,7 @@ namespace AyuSettings
bool disableStories;
bool localPremium;
bool copyUsernameAsLink;
QString appIcon;
QString deletedMark;
QString editedMark;
int recentStickersCount;
@ -114,6 +120,8 @@ namespace AyuSettings
void set_copyUsernameAsLink(bool val);
void set_appIcon(QString val);
void set_deletedMark(QString val);
void set_editedMark(QString val);
@ -150,6 +158,7 @@ namespace AyuSettings
disableStories,
localPremium,
copyUsernameAsLink,
appIcon,
deletedMark,
editedMark,
recentStickersCount,
@ -174,7 +183,6 @@ namespace AyuSettings
rpl::producer<int> get_showPeerIdReactive();
// computed fields
bool get_ghostModeEnabled();
rpl::producer<bool> get_ghostModeEnabledReactive();

View file

@ -0,0 +1,89 @@
// This is the source code of AyuGram for Desktop.
//
// We do not and cannot prevent the use of our code,
// but be respectful and credit the original author.
//
// Copyright @Radolyn, 2023
#include "ayu_assets.h"
#include "ayu/ayu_settings.h"
QString LAST_LOADED_NAME;
QImage LAST_LOADED;
QImage LAST_LOADED_NO_MARGIN;
void loadIcons()
{
auto settings = &AyuSettings::getInstance();
if (LAST_LOADED_NAME != settings->appIcon)
{
LAST_LOADED_NAME = settings->appIcon;
if (settings->appIcon == AyuSettings::DEFAULT_ICON)
{
LAST_LOADED = logo();
LAST_LOADED_NO_MARGIN = logoNoMargin();
}
else if (settings->appIcon == AyuSettings::ALT_ICON)
{
LAST_LOADED = logoAlt();
LAST_LOADED_NO_MARGIN = logoAltNoMargin();
}
else if (settings->appIcon == AyuSettings::NOTHING_ICON)
{
LAST_LOADED = logoNothing();
LAST_LOADED_NO_MARGIN = logoNothingNoMargin();
}
else
{
LAST_LOADED = logo();
LAST_LOADED_NO_MARGIN = logoNoMargin();
}
}
}
QImage logo()
{
return QImage(qsl(":/gui/art/logo_256.png"));
}
QImage logoNoMargin()
{
return QImage(qsl(":/gui/art/logo_256_no_margin.png"));
}
QImage logoAlt()
{
return QImage(qsl(":/gui/art/ayu/alt/logo256.png"));
}
QImage logoAltNoMargin()
{
return QImage(qsl(":/gui/art/ayu/alt/logo256_no_margin.png"));
}
QImage logoNothing()
{
return QImage(qsl(":/gui/art/ayu/nothing/logo256.png"));
}
QImage logoNothingNoMargin()
{
return QImage(qsl(":/gui/art/ayu/nothing/logo256_no_margin.png"));
}
QString currentAppLogoName()
{
return LAST_LOADED_NAME;
}
QImage currentAppLogo()
{
loadIcons();
return LAST_LOADED;
}
QImage currentAppLogoNoMargin()
{
loadIcons();
return LAST_LOADED_NO_MARGIN;
}

View file

@ -0,0 +1,21 @@
// This is the source code of AyuGram for Desktop.
//
// We do not and cannot prevent the use of our code,
// but be respectful and credit the original author.
//
// Copyright @Radolyn, 2023
#pragma once
QImage logo();
QImage logoNoMargin();
QImage logoAlt();
QImage logoAltNoMargin();
QImage logoNothing();
QImage logoNothingNoMargin();
QString currentAppLogoName();
QImage currentAppLogo();
QImage currentAppLogoNoMargin();

View file

@ -1,3 +1,12 @@
/*
* This is the source code of AyuGram for Desktop.
*
* We do not and cannot prevent the use of our code,
* but be respectful and credit the original author.
*
* Copyright @Radolyn, 2023
*/
using "ui/colors.palette";
using "ui/widgets/widgets.style";

View file

@ -7,10 +7,12 @@
#include "ayu_lottie.h"
namespace AyuUi {
std::unique_ptr<Lottie::Icon> getLottie(const QString& text) {
namespace AyuUi
{
std::unique_ptr<Lottie::Icon> getLottie(const QString& text)
{
// todo: some kind of mapping
// Lottie::MakeIcon({.json = QString(), .sizeOverride = {24, 24}});
return nullptr;
}
}
}

View file

@ -9,6 +9,7 @@
#include "lottie/lottie_icon.h"
namespace AyuUi {
namespace AyuUi
{
std::unique_ptr<Lottie::Icon> getLottie(const QString& text);
}

View file

@ -0,0 +1,14 @@
/*
* This is the source code of AyuGram for Desktop.
*
* We do not and cannot prevent the use of our code,
* but be respectful and credit the original author.
*
* Copyright @Radolyn, 2023
*/
using "ui/basic.style";
using "ui/colors.palette";
using "ui/widgets/widgets.style";
iconPreviewStroke: activeButtonBg;

View file

@ -0,0 +1,85 @@
// This is the source code of AyuGram for Desktop.
//
// We do not and cannot prevent the use of our code,
// but be respectful and credit the original author.
//
// Copyright @Radolyn, 2023
#include "icon_picker.h"
#include "ayu/ayu_settings.h"
#include "core/application.h"
#include "styles/style_layers.h"
#include "ayu/ui/ayu_assets.h"
#include "main/main_domain.h"
#include "styles/style_ayu_styles.h"
#include "ui/painter.h"
#include "window/main_window.h"
void drawIcon(QPainter& p, const QImage& icon, int offset, bool selected)
{
if (selected)
{
p.save();
p.setPen(QPen(st::iconPreviewStroke, 2));
p.drawEllipse(offset + 2, 2, 68, 68);
p.restore();
}
auto rect = QRect(offset + 4, 4, 64, 64);
p.drawImage(rect, icon);
}
IconPicker::IconPicker(QWidget* parent) : RpWidget(parent)
{
setMinimumSize(st::boxWidth, 72);
}
void IconPicker::paintEvent(QPaintEvent* e)
{
Painter p(this);
PainterHighQualityEnabler hq(p);
auto icon1 = logo().scaled(64, 64, Qt::KeepAspectRatio, Qt::SmoothTransformation);
auto icon2 = logoAlt().scaled(64, 64, Qt::KeepAspectRatio, Qt::SmoothTransformation);
auto icon3 = logoNothing().scaled(64, 64, Qt::KeepAspectRatio, Qt::SmoothTransformation);
// todo: center
drawIcon(p, icon1, 0, currentAppLogoName() == AyuSettings::DEFAULT_ICON);
drawIcon(p, icon2, 0 + 64 + 16, currentAppLogoName() == AyuSettings::ALT_ICON);
drawIcon(p, icon3, 0 + 64 + 16 + 64 + 16, currentAppLogoName() == AyuSettings::NOTHING_ICON);
}
void IconPicker::mousePressEvent(QMouseEvent* e)
{
auto settings = &AyuSettings::getInstance();
auto changed = false;
auto x = e->pos().x();
if (x <= 64 && settings->appIcon != AyuSettings::DEFAULT_ICON)
{
settings->set_appIcon(AyuSettings::DEFAULT_ICON);
changed = true;
}
else if (x >= 64 + 16 && x <= 64 + 16 + 64 && settings->appIcon != AyuSettings::ALT_ICON)
{
settings->set_appIcon(AyuSettings::ALT_ICON);
changed = true;
}
else if (x >= 64 + 16 + 64 + 16 && x < 64 + 16 + 64 + 16 + 64 && settings->appIcon != AyuSettings::NOTHING_ICON)
{
settings->set_appIcon(AyuSettings::NOTHING_ICON);
changed = true;
}
if (changed)
{
AyuSettings::save();
Window::OverrideApplicationIcon(currentAppLogo());
Core::App().refreshApplicationIcon();
Core::App().domain().notifyUnreadBadgeChanged();
repaint();
}
}

View file

@ -0,0 +1,20 @@
// This is the source code of AyuGram for Desktop.
//
// We do not and cannot prevent the use of our code,
// but be respectful and credit the original author.
//
// Copyright @Radolyn, 2023
#pragma once
#include "ui/rp_widget.h"
class IconPicker : public Ui::RpWidget
{
public:
IconPicker(QWidget* parent);
protected:
void paintEvent(QPaintEvent* e) override;
void mousePressEvent(QMouseEvent* e) override;
};

View file

@ -34,6 +34,7 @@
#include "styles/style_settings.h"
#include "styles/style_widgets.h"
#include "icon_picker.h"
#include "ui/painter.h"
#include "ui/boxes/confirm_box.h"
#include "ui/boxes/single_choice_box.h"
@ -626,6 +627,13 @@ namespace Settings
}, container->lifetime());
}
void Ayu::SetupAppIcon(not_null<Ui::VerticalLayout*> container)
{
container->add(
object_ptr<IconPicker>(container),
st::settingsSubsectionTitlePadding);
}
void Ayu::SetupCustomization(not_null<Ui::VerticalLayout*> container,
not_null<Window::SessionController*> controller)
{
@ -633,6 +641,8 @@ namespace Settings
AddSubsectionTitle(container, tr::ayu_CustomizationHeader());
SetupAppIcon(container);
auto btn = AddButtonWithLabel(
container,
tr::ayu_DeletedMarkText(),

View file

@ -44,6 +44,8 @@ namespace Settings
void SetupQoLToggles(not_null<Ui::VerticalLayout*> container);
void SetupAppIcon(not_null<Ui::VerticalLayout*> container);
void SetupCustomization(not_null<Ui::VerticalLayout*> container,
not_null<Window::SessionController*> controller);

View file

@ -24,6 +24,10 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include <private/qguiapplication_p.h>
#include <private/qhighdpiscaling_p.h>
// AyuGram includes
#include "ayu/ui/ayu_assets.h"
namespace Platform {
namespace {
@ -37,6 +41,12 @@ constexpr auto kTooltipDelay = crl::time(10000);
static constexpr auto kCount = 3;
static auto ScaledLogo = std::array<QImage, kCount>();
static auto ScaledLogoNoMargin = std::array<QImage, kCount>();
static auto lastUsedIcon = currentAppLogoName();
if (lastUsedIcon != currentAppLogoName()) {
ScaledLogo = std::array<QImage, kCount>();
ScaledLogoNoMargin = std::array<QImage, kCount>();
}
struct Dimensions {
int index = 0;

View file

@ -52,6 +52,10 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include <kurlmimedata.h>
// AyuGram includes
#include "ayu/ui/ayu_assets.h"
namespace Window {
namespace {
@ -74,14 +78,12 @@ using Core::WindowPosition;
} // namespace
const QImage &Logo() {
static const auto result = QImage(u":/gui/art/logo_256.png"_q);
return result;
QImage Logo() {
return currentAppLogo();
}
const QImage &LogoNoMargin() {
static const auto result = QImage(u":/gui/art/logo_256_no_margin.png"_q);
return result;
QImage LogoNoMargin() {
return currentAppLogoNoMargin();
}
void ConvertIconToBlack(QImage &image) {
@ -136,16 +138,7 @@ void OverrideApplicationIcon(QImage image) {
}
QIcon CreateOfficialIcon(Main::Session *session) {
const auto support = (session && session->supportMode());
if (!support) {
return QIcon();
}
auto overriden = OverridenIcon();
auto image = overriden.isNull()
? Platform::DefaultApplicationIcon()
: overriden;
ConvertIconToBlack(image);
return QIcon(Ui::PixmapFromImage(std::move(image)));
return QIcon(Ui::PixmapFromImage(currentAppLogo()));
}
QIcon CreateIcon(Main::Session *session, bool returnNullIfDefault) {

View file

@ -35,8 +35,8 @@ class SessionController;
class TitleWidget;
struct TermsLock;
[[nodiscard]] const QImage &Logo();
[[nodiscard]] const QImage &LogoNoMargin();
[[nodiscard]] QImage Logo();
[[nodiscard]] QImage LogoNoMargin();
void OverrideApplicationIcon(QImage image);
[[nodiscard]] QIcon CreateIcon(
Main::Session *session = nullptr,

View file

@ -13,6 +13,7 @@ include(cmake/generate_numbers.cmake)
set(style_files
ayu/ui/ayu_icons.style
ayu/ui/ayu_styles.style
ui/td_common.style
ui/filter_icons.style

2
cmake

@ -1 +1 @@
Subproject commit bd556e2a16d34ad876054fb3ab25e83481af652a
Subproject commit 797fa772cd95f5eb087c95e9ff619c9888ad8604