Save custom app icon color with digest to settings.

This commit is contained in:
John Preston 2022-02-08 16:18:51 +03:00
parent 2ae5fc0fac
commit a7958f5235
4 changed files with 84 additions and 10 deletions

View File

@ -66,6 +66,21 @@ constexpr auto kRecentEmojiLimit = 42;
return result; return result;
} }
[[nodiscard]] quint32 SerializeColor(QColor color) {
return (quint32(std::clamp(color.alpha(), 0, 255)) << 24)
| (quint32(std::clamp(color.red(), 0, 255)) << 16)
| (quint32(std::clamp(color.green(), 0, 255)) << 8)
| quint32(std::clamp(color.blue(), 0, 255));
}
[[nodiscard]] QColor DeserializeColor(quint32 value) {
return QColor(
(value >> 16) & 0xFF,
(value >> 8) & 0xFF,
value & 0xFF,
(value >> 24) & 0xFF);
}
} // namespace } // namespace
Settings::Settings() Settings::Settings()
@ -236,6 +251,10 @@ QByteArray Settings::serialize() const {
for (const auto &id : _accountsOrder) { for (const auto &id : _accountsOrder) {
stream << quint64(id); stream << quint64(id);
} }
stream
<< SerializeColor(_customAppIcon.color)
<< quint64(_customAppIcon.digest);
} }
return result; return result;
} }
@ -325,6 +344,8 @@ void Settings::addFromSerialized(const QByteArray &serialized) {
qint32 macWarnBeforeQuit = _macWarnBeforeQuit ? 1 : 0; qint32 macWarnBeforeQuit = _macWarnBeforeQuit ? 1 : 0;
qint32 accountsOrderCount = 0; qint32 accountsOrderCount = 0;
std::vector<uint64> accountsOrder; std::vector<uint64> accountsOrder;
quint32 customAppIconColor = SerializeColor(_customAppIcon.color);
quint64 customAppIconDigest = _customAppIcon.digest;
stream >> themesAccentColors; stream >> themesAccentColors;
if (!stream.atEnd()) { if (!stream.atEnd()) {
@ -506,6 +527,11 @@ void Settings::addFromSerialized(const QByteArray &serialized) {
} }
} }
} }
if (!stream.atEnd()) {
stream
>> customAppIconColor
>> customAppIconDigest;
}
if (stream.status() != QDataStream::Ok) { if (stream.status() != QDataStream::Ok) {
LOG(("App Error: " LOG(("App Error: "
"Bad data for Core::Settings::constructFromSerialized()")); "Bad data for Core::Settings::constructFromSerialized()"));
@ -662,6 +688,7 @@ void Settings::addFromSerialized(const QByteArray &serialized) {
case Media::Player::OrderMode::Shuffle: _playerOrderMode = uncheckedPlayerOrderMode; break; case Media::Player::OrderMode::Shuffle: _playerOrderMode = uncheckedPlayerOrderMode; break;
} }
_macWarnBeforeQuit = macWarnBeforeQuit ? 1 : 0; _macWarnBeforeQuit = macWarnBeforeQuit ? 1 : 0;
_customAppIcon = { DeserializeColor(customAppIconColor), customAppIconDigest };
} }
QString Settings::getSoundPath(const QString &key) const { QString Settings::getSoundPath(const QString &key) const {

View File

@ -51,6 +51,11 @@ struct WindowPosition {
int h = 0; int h = 0;
}; };
struct CustomAppIcon {
QColor color;
uint64 digest = 0;
};
class Settings final { class Settings final {
public: public:
enum class ScreenCorner { enum class ScreenCorner {
@ -669,6 +674,12 @@ public:
[[nodiscard]] bool macWarnBeforeQuit() const { [[nodiscard]] bool macWarnBeforeQuit() const {
return _macWarnBeforeQuit; return _macWarnBeforeQuit;
} }
void setCustomAppIcon(CustomAppIcon icon) {
_customAppIcon = icon;
}
[[nodiscard]] CustomAppIcon customAppIcon() const {
return _customAppIcon;
}
[[nodiscard]] static bool ThirdColumnByDefault(); [[nodiscard]] static bool ThirdColumnByDefault();
[[nodiscard]] static float64 DefaultDialogsWidthRatio(); [[nodiscard]] static float64 DefaultDialogsWidthRatio();
@ -775,6 +786,7 @@ private:
rpl::variable<Media::Player::OrderMode> _playerOrderMode; rpl::variable<Media::Player::OrderMode> _playerOrderMode;
bool _macWarnBeforeQuit = true; bool _macWarnBeforeQuit = true;
std::vector<uint64> _accountsOrder; std::vector<uint64> _accountsOrder;
CustomAppIcon _customAppIcon;
bool _tabbedReplacedWithInfo = false; // per-window bool _tabbedReplacedWithInfo = false; // per-window
rpl::event_stream<bool> _tabbedReplacedWithInfoValue; // per-window rpl::event_stream<bool> _tabbedReplacedWithInfoValue; // per-window

View File

@ -286,8 +286,6 @@ void ColorsPalette::show(
int selected, int selected,
int customLightnessMin, int customLightnessMin,
int customLightnessMax) { int customLightnessMax) {
Expects(selected >= 0 && selected < colors.size());
_outer->show(anim::type::instant); _outer->show(anim::type::instant);
while (_buttons.size() > colors.size()) { while (_buttons.size() > colors.size()) {
@ -1029,23 +1027,51 @@ void SetupAppIcon(
not_null<Ui::VerticalLayout*> container) { not_null<Ui::VerticalLayout*> container) {
AddSkip(container, st::settingsPrivacySkip); AddSkip(container, st::settingsPrivacySkip);
AddSubsectionTitle(container, rpl::single(u"App Icon"_q)); container->add(
object_ptr<Ui::FlatLabel>(
container,
rpl::single(u"App Icon"_q),
st::settingsSubsectionTitle),
(st::settingsSubsectionTitlePadding
- QMargins(0, 0, 0, st::settingsSubsectionTitlePadding.bottom())));
const auto palette = Ui::CreateChild<ColorsPalette>( const auto palette = Ui::CreateChild<ColorsPalette>(
container.get(), container.get(),
container.get()); container.get());
auto list = Window::Theme::DefaultAccentColors(
Window::Theme::EmbeddedType::Night);
const auto original = QColor(29, 148, 208); const auto original = QColor(29, 148, 208);
list[0] = original; const auto refresh = [=](uint64 currentDigest) {
palette->show(std::move(list), 0, 0, 255); auto list = Window::Theme::DefaultAccentColors(
Window::Theme::EmbeddedType::Night);
list[0] = original;
const auto current = Core::App().settings().customAppIcon();
const auto selected = !currentDigest
? 0
: (currentDigest != current.digest)
? -1
: std::min(
int(ranges::find(list, current.color) - begin(list)),
int(size(list)) - 1);
if (selected == size(list) - 1) {
list[selected] = current.color;
}
palette->show(std::move(list), selected, 0, 255);
};
refresh(base::CurrentCustomAppIconDigest().value_or(0));
const auto logo = QImage(":/gui/art/logo_256.png").convertToFormat( const auto logo = QImage(":/gui/art/logo_256.png").convertToFormat(
QImage::Format_ARGB32); QImage::Format_ARGB32);
palette->selected( palette->selected(
) | rpl::start_with_next([=](QColor color) { ) | rpl::start_with_next([=](QColor color) {
if (color == original) { if (color == original) {
base::ClearCustomAppIcon(); const auto success = base::ClearCustomAppIcon();
if (success) {
Core::App().settings().setCustomAppIcon({});
Core::App().saveSettingsDelayed();
refresh(0);
}
Ui::Toast::Show(success
? "Icon cleared. Restarting the Dock."
: "Icon clear failed. See log.txt for details.");
} else { } else {
auto colorizer = style::colorizer{ auto colorizer = style::colorizer{
.hueThreshold = 64, .hueThreshold = 64,
@ -1060,11 +1086,20 @@ void SetupAppIcon(
&colorizer.now.value); &colorizer.now.value);
auto image = logo; auto image = logo;
style::colorize(image, colorizer); style::colorize(image, colorizer);
base::SetCustomAppIcon(std::move(image)); const auto digest = base::SetCustomAppIcon(std::move(image));
if (digest) {
Core::App().settings().setCustomAppIcon({ color, *digest });
Core::App().saveSettingsDelayed();
refresh(*digest);
}
Ui::Toast::Show(digest
? "Icon updated. Restarting the Dock."
: "Icon update failed. See log.txt for details.");
} }
}, container->lifetime()); }, container->lifetime());
AddSkip(container); AddSkip(container);
AddDivider(container);
} }
#endif // Q_OS_MAC && !OS_MAC_STORE #endif // Q_OS_MAC && !OS_MAC_STORE

@ -1 +1 @@
Subproject commit 7253d8f09883df51705c358b1f8ff50ba7eda8e6 Subproject commit 2461c5ad4a929825ff79bc94172334306176f328