Save custom app icon color with digest to settings.
This commit is contained in:
parent
2ae5fc0fac
commit
a7958f5235
|
@ -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 {
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
Loading…
Reference in New Issue