Improve theme applying.

This commit is contained in:
John Preston 2018-07-21 16:54:00 +03:00
parent cb338e330f
commit 6429e8b532
4 changed files with 100 additions and 48 deletions

View file

@ -1219,7 +1219,6 @@ void Messenger::loggedOut() {
_mediaView->clearData(); _mediaView->clearData();
} }
Local::reset(); Local::reset();
Window::Theme::Background()->reset();
cSetOtherOnline(0); cSetOtherOnline(0);
clearStorageImages(); clearStorageImages();

View file

@ -2689,6 +2689,7 @@ void reset() {
_installedStickersKey = _featuredStickersKey = _recentStickersKey = _favedStickersKey = _archivedStickersKey = 0; _installedStickersKey = _featuredStickersKey = _recentStickersKey = _favedStickersKey = _archivedStickersKey = 0;
_savedGifsKey = 0; _savedGifsKey = 0;
_backgroundKeyDay = _backgroundKeyNight = 0; _backgroundKeyDay = _backgroundKeyNight = 0;
Window::Theme::Background()->reset();
_userSettingsKey = _recentHashtagsAndBotsKey = _savedPeersKey = _exportSettingsKey = 0; _userSettingsKey = _recentHashtagsAndBotsKey = _savedPeersKey = _exportSettingsKey = 0;
_oldMapVersion = _oldSettingsVersion = 0; _oldMapVersion = _oldSettingsVersion = 0;
StoredAuthSessionCache.reset(); StoredAuthSessionCache.reset();
@ -4299,6 +4300,9 @@ QString loadThemeUsingKey(FileKey key) {
} }
void writeTheme(const Window::Theme::Saved &saved) { void writeTheme(const Window::Theme::Saved &saved) {
if (_themeKeyLegacy) {
return;
}
auto &themeKey = Window::Theme::IsNightMode() auto &themeKey = Window::Theme::IsNightMode()
? _themeKeyNight ? _themeKeyNight
: _themeKeyDay; : _themeKeyDay;

View file

@ -220,6 +220,7 @@ bool loadThemeFromCache(const QByteArray &content, const Cached &cache) {
if (!style::main_palette::load(cache.colors)) { if (!style::main_palette::load(cache.colors)) {
return false; return false;
} }
Background()->saveAdjustableColors();
if (!background.isNull()) { if (!background.isNull()) {
applyBackground(std::move(background), cache.tiled, nullptr); applyBackground(std::move(background), cache.tiled, nullptr);
} }
@ -280,6 +281,7 @@ bool loadTheme(const QByteArray &content, Cached &cache, Instance *out = nullptr
if (!loadColorScheme(schemeContent, out)) { if (!loadColorScheme(schemeContent, out)) {
return false; return false;
} }
Background()->saveAdjustableColors();
auto backgroundTiled = false; auto backgroundTiled = false;
auto backgroundContent = QByteArray(); auto backgroundContent = QByteArray();
@ -307,6 +309,7 @@ bool loadTheme(const QByteArray &content, Cached &cache, Instance *out = nullptr
if (!loadColorScheme(content, out)) { if (!loadColorScheme(content, out)) {
return false; return false;
} }
Background()->saveAdjustableColors();
} }
if (out) { if (out) {
cache.colors = out->palette.save(); cache.colors = out->palette.save();
@ -333,39 +336,6 @@ void adjustColor(style::color color, float64 hue, float64 saturation) {
color.set(original.red(), original.green(), original.blue(), original.alpha()); color.set(original.red(), original.green(), original.blue(), original.alpha());
} }
void adjustColorsUsingBackground(const QImage &img) {
Assert(img.format() == QImage::Format_ARGB32_Premultiplied);
uint64 components[3] = { 0 };
uint64 componentsScroll[3] = { 0 };
auto w = img.width();
auto h = img.height();
auto size = w * h;
if (auto pix = img.constBits()) {
for (auto i = 0, l = size * 4; i != l; i += 4) {
components[2] += pix[i + 0];
components[1] += pix[i + 1];
components[0] += pix[i + 2];
}
}
if (size) {
for (auto i = 0; i != 3; ++i) {
components[i] /= size;
}
}
auto bgColor = QColor(components[0], components[1], components[2]);
auto hue = bgColor.hslHueF();
auto saturation = bgColor.hslSaturationF();
adjustColor(st::msgServiceBg, hue, saturation);
adjustColor(st::msgServiceBgSelected, hue, saturation);
adjustColor(st::historyScroll.bg, hue, saturation);
adjustColor(st::historyScroll.bgOver, hue, saturation);
adjustColor(st::historyScroll.barBg, hue, saturation);
adjustColor(st::historyScroll.barBgOver, hue, saturation);
}
void ApplyDefaultWithNightMode(bool nightMode) { void ApplyDefaultWithNightMode(bool nightMode) {
if (nightMode) { if (nightMode) {
if (auto preview = PreviewFromFile(NightThemePath())) { if (auto preview = PreviewFromFile(NightThemePath())) {
@ -386,6 +356,21 @@ void ApplyDefaultWithNightMode(bool nightMode) {
} // namespace } // namespace
ChatBackground::AdjustableColor::AdjustableColor(style::color data)
: item(data)
, original(data->c) {
}
ChatBackground::ChatBackground() : _adjustableColors({
st::msgServiceBg,
st::msgServiceBgSelected,
st::historyScrollBg,
st::historyScrollBgOver,
st::historyScrollBarBg,
st::historyScrollBarBgOver }) {
saveAdjustableColors();
}
void ChatBackground::setThemeData(QImage &&themeImage, bool themeTile) { void ChatBackground::setThemeData(QImage &&themeImage, bool themeTile) {
_themeImage = prepareBackgroundImage(std::move(themeImage)); _themeImage = prepareBackgroundImage(std::move(themeImage));
_themeTile = themeTile; _themeTile = themeTile;
@ -400,18 +385,18 @@ void ChatBackground::start() {
} }
void ChatBackground::setImage(int32 id, QImage &&image) { void ChatBackground::setImage(int32 id, QImage &&image) {
auto resetPalette = (id == kDefaultBackground) auto needResetAdjustable = (id == kDefaultBackground)
&& (_id != kDefaultBackground) && (_id != kDefaultBackground)
&& !nightMode() && !nightMode()
&& _themeAbsolutePath.isEmpty(); && _themeAbsolutePath.isEmpty();
if (id == kThemeBackground && _themeImage.isNull()) { if (id == kThemeBackground && _themeImage.isNull()) {
id = kDefaultBackground; id = kDefaultBackground;
} else if (resetPalette) { } else if (needResetAdjustable) {
// If we had a default color theme with non-default background, // If we had a default color theme with non-default background,
// and we switch to default background we must somehow switch from // and we switch to default background we must somehow switch from
// adjusted service colors to default (non-adjusted) service colors. // adjusted service colors to default (non-adjusted) service colors.
// The only way to do that right now is through full palette reset. // The only way to do that right now is through full palette reset.
style::main_palette::reset(); restoreAdjustableColors();
} }
_id = id; _id = id;
if (_id == kThemeBackground) { if (_id == kThemeBackground) {
@ -442,7 +427,7 @@ void ChatBackground::setImage(int32 id, QImage &&image) {
} }
Assert(!_pixmap.isNull() && !_pixmapForTiled.isNull()); Assert(!_pixmap.isNull() && !_pixmapForTiled.isNull());
notify(BackgroundUpdate(BackgroundUpdate::Type::New, tile())); notify(BackgroundUpdate(BackgroundUpdate::Type::New, tile()));
if (resetPalette) { if (needResetAdjustable) {
notify(BackgroundUpdate(BackgroundUpdate::Type::TestingTheme, tile()), true); notify(BackgroundUpdate(BackgroundUpdate::Type::TestingTheme, tile()), true);
notify(BackgroundUpdate(BackgroundUpdate::Type::ApplyingTheme, tile()), true); notify(BackgroundUpdate(BackgroundUpdate::Type::ApplyingTheme, tile()), true);
} }
@ -476,7 +461,7 @@ void ChatBackground::setPreparedImage(QImage &&image) {
return !usingDefaultBackground(); return !usingDefaultBackground();
}(); }();
if (adjustColors) { if (adjustColors) {
adjustColorsUsingBackground(image); adjustPaletteUsingBackground(image);
} }
auto width = image.width(); auto width = image.width();
@ -509,6 +494,36 @@ void ChatBackground::setPreparedImage(QImage &&image) {
} }
} }
void ChatBackground::adjustPaletteUsingBackground(const QImage &img) {
Assert(img.format() == QImage::Format_ARGB32_Premultiplied);
uint64 components[3] = { 0 };
uint64 componentsScroll[3] = { 0 };
auto w = img.width();
auto h = img.height();
auto size = w * h;
if (auto pix = img.constBits()) {
for (auto i = 0, l = size * 4; i != l; i += 4) {
components[2] += pix[i + 0];
components[1] += pix[i + 1];
components[0] += pix[i + 2];
}
}
if (size) {
for (auto i = 0; i != 3; ++i) {
components[i] /= size;
}
}
auto bgColor = QColor(components[0], components[1], components[2]);
auto hue = bgColor.hslHueF();
auto saturation = bgColor.hslSaturationF();
for (const auto &color : _adjustableColors) {
adjustColor(color.item, hue, saturation);
}
}
int32 ChatBackground::id() const { int32 ChatBackground::id() const {
return _id; return _id;
} }
@ -594,6 +609,9 @@ void ChatBackground::reset() {
} }
} else { } else {
setImage(kThemeBackground); setImage(kThemeBackground);
restoreAdjustableColors();
notify(BackgroundUpdate(BackgroundUpdate::Type::TestingTheme, tile()), true);
notify(BackgroundUpdate(BackgroundUpdate::Type::ApplyingTheme, tile()), true);
} }
} }
@ -607,9 +625,24 @@ void ChatBackground::saveForRevert() {
} }
} }
void ChatBackground::setTestingTheme(Instance &&theme, ChangeMode mode) { void ChatBackground::saveAdjustableColors() {
for (auto &color : _adjustableColors) {
color.original = color.item->c;
}
}
void ChatBackground::restoreAdjustableColors() {
for (const auto &color : _adjustableColors) {
const auto value = color.original;
color.item.set(value.red(), value.green(), value.blue(), value.alpha());
}
}
void ChatBackground::setTestingTheme(Instance &&theme) {
style::main_palette::apply(theme.palette); style::main_palette::apply(theme.palette);
auto switchToThemeBackground = (mode == ChangeMode::SwitchToThemeBackground && !theme.background.isNull()) saveAdjustableColors();
auto switchToThemeBackground = !theme.background.isNull()
|| (_id == kThemeBackground) || (_id == kThemeBackground)
|| (_id == kDefaultBackground || (_id == kDefaultBackground
&& !nightMode() && !nightMode()
@ -633,6 +666,8 @@ void ChatBackground::setTestingTheme(Instance &&theme, ChangeMode mode) {
void ChatBackground::setTestingDefaultTheme() { void ChatBackground::setTestingDefaultTheme() {
style::main_palette::reset(); style::main_palette::reset();
saveAdjustableColors();
saveForRevert(); saveForRevert();
setImage(internal::kTestingDefaultBackground); setImage(internal::kTestingDefaultBackground);
setTile(false); setTile(false);
@ -666,7 +701,8 @@ void ChatBackground::keepApplied(const QString &path, bool write) {
notify(BackgroundUpdate(BackgroundUpdate::Type::ApplyingTheme, tile()), true); notify(BackgroundUpdate(BackgroundUpdate::Type::ApplyingTheme, tile()), true);
} }
bool ChatBackground::isNonDefaultThemeOrBackground() const { bool ChatBackground::isNonDefaultThemeOrBackground() {
start();
return nightMode() return nightMode()
? (_themeAbsolutePath != NightThemePath() ? (_themeAbsolutePath != NightThemePath()
|| _id != kThemeBackground) || _id != kThemeBackground)
@ -865,6 +901,8 @@ void Revert() {
return; return;
} }
style::main_palette::load(instance->applying.paletteForRevert); style::main_palette::load(instance->applying.paletteForRevert);
Background()->saveAdjustableColors();
instance->applying = Data::Applying(); instance->applying = Data::Applying();
Background()->revert(); Background()->revert();
} }

View file

@ -91,6 +91,8 @@ struct BackgroundUpdate {
class ChatBackground : public base::Observable<BackgroundUpdate> { class ChatBackground : public base::Observable<BackgroundUpdate> {
public: public:
ChatBackground();
// This method is allowed to (and should) be called before start(). // This method is allowed to (and should) be called before start().
void setThemeData(QImage &&themeImage, bool themeTile); void setThemeData(QImage &&themeImage, bool themeTile);
@ -104,11 +106,8 @@ public:
QString themeAbsolutePath() const; QString themeAbsolutePath() const;
void reset(); void reset();
enum class ChangeMode { void setTestingTheme(Instance &&theme);
SwitchToThemeBackground, void saveAdjustableColors();
LeaveCurrentCustomBackground,
};
void setTestingTheme(Instance &&theme, ChangeMode mode = ChangeMode::SwitchToThemeBackground);
void setTestingDefaultTheme(); void setTestingDefaultTheme();
void revert(); void revert();
@ -124,16 +123,26 @@ public:
bool tileNight() const; bool tileNight() const;
private: private:
struct AdjustableColor {
AdjustableColor(style::color data);
style::color item;
QColor original;
};
void ensureStarted(); void ensureStarted();
void saveForRevert(); void saveForRevert();
void setPreparedImage(QImage &&image); void setPreparedImage(QImage &&image);
void writeNewBackgroundSettings(); void writeNewBackgroundSettings();
void adjustPaletteUsingBackground(const QImage &img);
void restoreAdjustableColors();
void setNightModeValue(bool nightMode); void setNightModeValue(bool nightMode);
bool nightMode() const; bool nightMode() const;
void toggleNightMode(); void toggleNightMode();
void keepApplied(const QString &path, bool write); void keepApplied(const QString &path, bool write);
bool isNonDefaultThemeOrBackground() const; bool isNonDefaultThemeOrBackground();
friend bool IsNightMode(); friend bool IsNightMode();
friend void SetNightModeValue(bool nightMode); friend void SetNightModeValue(bool nightMode);
@ -156,6 +165,8 @@ private:
QImage _imageForRevert; QImage _imageForRevert;
bool _tileForRevert = false; bool _tileForRevert = false;
std::vector<AdjustableColor> _adjustableColors;
}; };
ChatBackground *Background(); ChatBackground *Background();