Save wallpaper information.

This commit is contained in:
John Preston 2019-01-16 21:26:26 +04:00
parent b8cb792831
commit 466c6da5e3
8 changed files with 211 additions and 159 deletions

View file

@ -3071,12 +3071,27 @@ void Session::setWallpapers(const QVector<MTPWallPaper> &data, int32 hash) {
_wallpapers.clear(); _wallpapers.clear();
_wallpapers.reserve(data.size() + 1); _wallpapers.reserve(data.size() + 1);
const auto defaultBackground = Images::Create(
qsl(":/gui/art/bg.jpg"),
"JPG");
if (defaultBackground) {
_wallpapers.push_back({
Window::Theme::kDefaultBackground,
0ULL, // access_hash
MTPDwallPaper::Flags(0),
QString(), // slug
defaultBackground
});
}
const auto oldBackground = Images::Create( const auto oldBackground = Images::Create(
qsl(":/gui/art/bg_initial.jpg"), qsl(":/gui/art/bg_initial.jpg"),
"JPG"); "JPG");
if (oldBackground) { if (oldBackground) {
_wallpapers.push_back({ _wallpapers.push_back({
Window::Theme::kInitialBackground, Window::Theme::kInitialBackground,
0ULL, // access_hash
MTPDwallPaper::Flags(0),
QString(), // slug
oldBackground oldBackground
}); });
} }
@ -3086,6 +3101,9 @@ void Session::setWallpapers(const QVector<MTPWallPaper> &data, int32 hash) {
if (document->checkWallPaperProperties()) { if (document->checkWallPaperProperties()) {
_wallpapers.push_back({ _wallpapers.push_back({
paper.vid.v, paper.vid.v,
paper.vaccess_hash.v,
paper.vflags.v,
qs(paper.vslug),
document->thumb, document->thumb,
document, document,
}); });

View file

@ -51,11 +51,7 @@ class Feed;
enum class FeedUpdateFlag; enum class FeedUpdateFlag;
struct FeedUpdate; struct FeedUpdate;
struct WallPaper { struct WallPaper;
WallPaperId id = WallPaperId();
ImagePtr thumb;
DocumentData *document = nullptr;
};
class Session final { class Session final {
public: public:

View file

@ -1508,14 +1508,14 @@ void MainWidget::setGeneratedBackground(QImage &&image) {
using namespace Window::Theme; using namespace Window::Theme;
if (image.isNull()) { if (image.isNull()) {
Background()->setImage(kDefaultBackground); Background()->setImage({ kDefaultBackground });
} else if (false } else if (false
|| _background->data.id == kInitialBackground || _background->data.id == kInitialBackground
|| _background->data.id == kDefaultBackground) { || _background->data.id == kDefaultBackground) {
Background()->setImage(_background->data.id); Background()->setImage(_background->data);
} else { } else {
Background()->setImage( Background()->setImage(
_background->data.id, _background->data,
std::move(image)); std::move(image));
} }
const auto tile = (_background->data.id == kInitialBackground); const auto tile = (_background->data.id == kInitialBackground);

View file

@ -358,7 +358,7 @@ void DefaultTheme::checkedChangedHook(anim::type animated) {
} }
void ChooseFromFile(not_null<QWidget*> parent) { void ChooseFromFile(not_null<QWidget*> parent) {
const auto imgExtensions = cImgExtensions(); const auto &imgExtensions = cImgExtensions();
auto filters = QStringList( auto filters = QStringList(
qsl("Theme files (*.tdesktop-theme *.tdesktop-palette *") qsl("Theme files (*.tdesktop-theme *.tdesktop-palette *")
+ imgExtensions.join(qsl(" *")) + imgExtensions.join(qsl(" *"))
@ -401,7 +401,7 @@ void ChooseFromFile(not_null<QWidget*> parent) {
} }
Window::Theme::Background()->setImage( Window::Theme::Background()->setImage(
Window::Theme::kCustomBackground, { Window::Theme::kCustomBackground },
std::move(image)); std::move(image));
Window::Theme::Background()->setTile(false); Window::Theme::Background()->setTile(false);
}; };

View file

@ -3956,7 +3956,7 @@ void readSavedGifs() {
} }
} }
void writeBackground(WallPaperId id, const QImage &img) { void writeBackground(const Data::WallPaper &paper, const QImage &img) {
if (!_working() || !_backgroundCanWrite) { if (!_working() || !_backgroundCanWrite) {
return; return;
} }
@ -3982,12 +3982,17 @@ void writeBackground(WallPaperId id, const QImage &img) {
_writeMap(WriteMapWhen::Fast); _writeMap(WriteMapWhen::Fast);
} }
quint32 size = sizeof(qint32) quint32 size = sizeof(qint32)
+ sizeof(quint64) + 2 * sizeof(quint64)
+ sizeof(quint32)
+ Serialize::stringSize(paper.slug)
+ Serialize::bytearraySize(bmp); + Serialize::bytearraySize(bmp);
EncryptedDescriptor data(size); EncryptedDescriptor data(size);
data.stream data.stream
<< qint32(Window::Theme::internal::kLegacyBackgroundId) << qint32(Window::Theme::details::kLegacyBackgroundId)
<< quint64(id) << quint64(paper.id)
<< quint64(paper.accessHash)
<< quint32(paper.flags.value())
<< paper.slug
<< bmp; << bmp;
FileWriteDescriptor file(backgroundKey); FileWriteDescriptor file(backgroundKey);
@ -4010,13 +4015,24 @@ bool readBackground() {
} }
QByteArray bmpData; QByteArray bmpData;
qint32 legacyId; qint32 legacyId = 0;
quint64 id; quint64 id = 0;
quint64 accessHash = 0;
quint32 flags = 0;
QString slug;
bg.stream >> legacyId; bg.stream >> legacyId;
if (legacyId == Window::Theme::internal::kLegacyBackgroundId) { if (legacyId == Window::Theme::details::kLegacyBackgroundId) {
bg.stream >> id; bg.stream
>> id
>> accessHash
>> flags
>> slug;
} else { } else {
id = Window::Theme::internal::FromLegacyBackgroundId(legacyId); id = Window::Theme::details::FromLegacyBackgroundId(legacyId);
accessHash = 0;
if (id != Window::Theme::kCustomBackground) {
flags = static_cast<quint32>(MTPDwallPaper::Flag::f_default);
}
} }
bg.stream >> bmpData; bg.stream >> bmpData;
auto oldEmptyImage = (bg.stream.status() != QDataStream::Ok); auto oldEmptyImage = (bg.stream.status() != QDataStream::Ok);
@ -4025,16 +4041,16 @@ bool readBackground() {
|| id == Window::Theme::kDefaultBackground) { || id == Window::Theme::kDefaultBackground) {
_backgroundCanWrite = false; _backgroundCanWrite = false;
if (oldEmptyImage || bg.version < 8005) { if (oldEmptyImage || bg.version < 8005) {
Window::Theme::Background()->setImage(Window::Theme::kDefaultBackground); Window::Theme::Background()->setImage({ Window::Theme::kDefaultBackground });
Window::Theme::Background()->setTile(false); Window::Theme::Background()->setTile(false);
} else { } else {
Window::Theme::Background()->setImage(id); Window::Theme::Background()->setImage({ id });
} }
_backgroundCanWrite = true; _backgroundCanWrite = true;
return true; return true;
} else if (id == Window::Theme::kThemeBackground && bmpData.isEmpty()) { } else if (id == Window::Theme::kThemeBackground && bmpData.isEmpty()) {
_backgroundCanWrite = false; _backgroundCanWrite = false;
Window::Theme::Background()->setImage(id); Window::Theme::Background()->setImage({ id });
_backgroundCanWrite = true; _backgroundCanWrite = true;
return true; return true;
} }
@ -4047,7 +4063,12 @@ bool readBackground() {
#endif // OS_MAC_OLD #endif // OS_MAC_OLD
if (reader.read(&image)) { if (reader.read(&image)) {
_backgroundCanWrite = false; _backgroundCanWrite = false;
Window::Theme::Background()->setImage(id, std::move(image)); Window::Theme::Background()->setImage({
id,
accessHash,
MTPDwallPaper::Flags::from_raw(flags),
slug
}, std::move(image));
_backgroundCanWrite = true; _backgroundCanWrite = true;
return true; return true;
} }

View file

@ -12,6 +12,10 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "storage/localimageloader.h" #include "storage/localimageloader.h"
#include "auth_session.h" #include "auth_session.h"
namespace Data {
struct WallPaper;
} // namespace Data
namespace Lang { namespace Lang {
struct Language; struct Language;
} // namespace Lang } // namespace Lang
@ -136,7 +140,7 @@ void writeSavedGifs();
void readSavedGifs(); void readSavedGifs();
int32 countSavedGifsHash(); int32 countSavedGifsHash();
void writeBackground(WallPaperId id, const QImage &img); void writeBackground(const Data::WallPaper &paper, const QImage &img);
bool readBackground(); bool readBackground();
void writeTheme(const Window::Theme::Saved &saved); void writeTheme(const Window::Theme::Saved &saved);

View file

@ -27,26 +27,20 @@ constexpr auto kThemeSchemeSizeLimit = 1024 * 1024;
constexpr auto kMinimumTiledSize = 512; constexpr auto kMinimumTiledSize = 512;
constexpr auto kNightThemeFile = str_const(":/gui/night.tdesktop-theme"); constexpr auto kNightThemeFile = str_const(":/gui/night.tdesktop-theme");
struct Data { struct Applying {
struct Applying { QString pathRelative;
QString pathRelative; QString pathAbsolute;
QString pathAbsolute; QByteArray content;
QByteArray content; QByteArray paletteForRevert;
QByteArray paletteForRevert; Cached cached;
Cached cached; Fn<void()> overrideKeep;
Fn<void()> overrideKeep;
};
ChatBackground background;
Applying applying;
}; };
NeverFreedPointer<Data> instance;
NeverFreedPointer<ChatBackground> GlobalBackground;
Applying GlobalApplying;
inline bool AreTestingTheme() { inline bool AreTestingTheme() {
if (instance) { return !GlobalApplying.paletteForRevert.isEmpty();
return !instance->applying.paletteForRevert.isEmpty();
}
return false;
}; };
QByteArray readThemeContent(const QString &path) { QByteArray readThemeContent(const QString &path) {
@ -348,15 +342,15 @@ void adjustColor(style::color color, float64 hue, float64 saturation) {
void WriteAppliedTheme() { void WriteAppliedTheme() {
auto saved = Saved(); auto saved = Saved();
saved.pathRelative = instance->applying.pathRelative; saved.pathRelative = GlobalApplying.pathRelative;
saved.pathAbsolute = instance->applying.pathAbsolute; saved.pathAbsolute = GlobalApplying.pathAbsolute;
saved.content = std::move(instance->applying.content); saved.content = std::move(GlobalApplying.content);
saved.cache = std::move(instance->applying.cached); saved.cache = std::move(GlobalApplying.cached);
Local::writeTheme(saved); Local::writeTheme(saved);
} }
void ClearApplying() { void ClearApplying() {
instance->applying = Data::Applying(); GlobalApplying = Applying();
} }
} // namespace } // namespace
@ -382,51 +376,59 @@ void ChatBackground::setThemeData(QImage &&themeImage, bool themeTile) {
} }
void ChatBackground::start() { void ChatBackground::start() {
if (_id == internal::kUninitializedBackground) { if (_paper.id == details::kUninitializedBackground) {
if (!Local::readBackground()) { if (!Local::readBackground()) {
setImage(kThemeBackground); setImage({ kThemeBackground });
} }
} }
} }
void ChatBackground::setImage(WallPaperId id, QImage &&image) { void ChatBackground::setImage(
auto needResetAdjustable = (id == kDefaultBackground) const Data::WallPaper &paper,
&& (_id != kDefaultBackground) QImage &&image) {
const auto needResetAdjustable = (paper.id == kDefaultBackground)
&& (id() != kDefaultBackground)
&& !nightMode() && !nightMode()
&& _themeAbsolutePath.isEmpty(); && _themeAbsolutePath.isEmpty();
if (id == kThemeBackground && _themeImage.isNull()) { if (paper.id == kThemeBackground && _themeImage.isNull()) {
id = kDefaultBackground; _paper = { kDefaultBackground };
} else if (needResetAdjustable) { } else {
// If we had a default color theme with non-default background, _paper = paper;
// and we switch to default background we must somehow switch from if (needResetAdjustable) {
// adjusted service colors to default (non-adjusted) service colors. // If we had a default color theme with non-default background,
// The only way to do that right now is through full palette reset. // and we switch to default background we must somehow switch from
restoreAdjustableColors(); // adjusted service colors to default (non-adjusted) service colors.
// The only way to do that right now is through full palette reset.
restoreAdjustableColors();
}
} }
_id = id; if (_paper.id == kThemeBackground) {
if (_id == kThemeBackground) {
(nightMode() ? _tileNightValue : _tileDayValue) = _themeTile; (nightMode() ? _tileNightValue : _tileDayValue) = _themeTile;
setPreparedImage(QImage(_themeImage)); setPreparedImage(QImage(_themeImage));
} else if (_id == internal::kTestingThemeBackground } else if (id() == details::kTestingThemeBackground
|| _id == internal::kTestingDefaultBackground || id() == details::kTestingDefaultBackground
|| _id == internal::kTestingEditorBackground) { || id() == details::kTestingEditorBackground) {
if (_id == internal::kTestingDefaultBackground || image.isNull()) { if (id() == details::kTestingDefaultBackground || image.isNull()) {
image.load(qsl(":/gui/art/bg.jpg")); image.load(qsl(":/gui/art/bg.jpg"));
_id = internal::kTestingDefaultBackground; _paper = { details::kTestingDefaultBackground };
} }
setPreparedImage(std::move(image)); setPreparedImage(std::move(image));
} else { } else {
if (_id == kInitialBackground) { if (id() == kInitialBackground) {
image.load(qsl(":/gui/art/bg_initial.jpg")); image.load(qsl(":/gui/art/bg_initial.jpg"));
const auto scale = cScale() * cIntRetinaFactor(); const auto scale = cScale() * cIntRetinaFactor();
if (scale != 100) { if (scale != 100) {
image = image.scaledToWidth(ConvertScale(image.width(), scale), Qt::SmoothTransformation); image = image.scaledToWidth(ConvertScale(image.width(), scale), Qt::SmoothTransformation);
} }
} else if (_id == kDefaultBackground || image.isNull()) { } else if (id() == kDefaultBackground || image.isNull()) {
_id = kDefaultBackground; _paper = { kDefaultBackground };
image.load(qsl(":/gui/art/bg.jpg")); image.load(qsl(":/gui/art/bg.jpg"));
} }
Local::writeBackground(_id, (_id == kDefaultBackground || _id == kInitialBackground) ? QImage() : image); Local::writeBackground(
_paper,
((id() == kDefaultBackground || id() == kInitialBackground)
? QImage()
: image));
setPreparedImage(prepareBackgroundImage(std::move(image))); setPreparedImage(prepareBackgroundImage(std::move(image)));
} }
Assert(!_pixmap.isNull() && !_pixmapForTiled.isNull()); Assert(!_pixmap.isNull() && !_pixmapForTiled.isNull());
@ -441,18 +443,18 @@ void ChatBackground::setPreparedImage(QImage &&image) {
image = std::move(image).convertToFormat(QImage::Format_ARGB32_Premultiplied); image = std::move(image).convertToFormat(QImage::Format_ARGB32_Premultiplied);
image.setDevicePixelRatio(cRetinaFactor()); image.setDevicePixelRatio(cRetinaFactor());
auto adjustColors = [&] { const auto adjustColors = [&] {
const auto usingThemeBackground = [&] { const auto usingThemeBackground = [&] {
return (_id == kThemeBackground) return (id() == kThemeBackground)
|| (_id == internal::kTestingThemeBackground); || (id() == details::kTestingThemeBackground);
}; };
const auto usingDefaultBackground = [&] { const auto usingDefaultBackground = [&] {
return (_id == kDefaultBackground) return (id() == kDefaultBackground)
|| (_id == internal::kTestingDefaultBackground); || (id() == details::kTestingDefaultBackground);
}; };
const auto testingPalette = [&] { const auto testingPalette = [&] {
const auto path = AreTestingTheme() const auto path = AreTestingTheme()
? instance->applying.pathAbsolute ? GlobalApplying.pathAbsolute
: _themeAbsolutePath; : _themeAbsolutePath;
return IsPaletteTestingPath(path); return IsPaletteTestingPath(path);
}; };
@ -529,7 +531,7 @@ void ChatBackground::adjustPaletteUsingBackground(const QImage &img) {
} }
WallPaperId ChatBackground::id() const { WallPaperId ChatBackground::id() const {
return _id; return _paper.id;
} }
bool ChatBackground::tile() const { bool ChatBackground::tile() const {
@ -537,8 +539,8 @@ bool ChatBackground::tile() const {
} }
bool ChatBackground::tileDay() const { bool ChatBackground::tileDay() const {
if (_id == internal::kTestingThemeBackground || if (id() == details::kTestingThemeBackground ||
_id == internal::kTestingDefaultBackground) { id() == details::kTestingDefaultBackground) {
if (!nightMode()) { if (!nightMode()) {
return _tileForRevert; return _tileForRevert;
} }
@ -547,8 +549,8 @@ bool ChatBackground::tileDay() const {
} }
bool ChatBackground::tileNight() const { bool ChatBackground::tileNight() const {
if (_id == internal::kTestingThemeBackground || if (id() == details::kTestingThemeBackground ||
_id == internal::kTestingDefaultBackground) { id() == details::kTestingDefaultBackground) {
if (nightMode()) { if (nightMode()) {
return _tileForRevert; return _tileForRevert;
} }
@ -573,8 +575,8 @@ void ChatBackground::setTile(bool tile) {
setTileDayValue(tile); setTileDayValue(tile);
} }
if (this->tile() != old) { if (this->tile() != old) {
if (_id != internal::kTestingThemeBackground if (id() != details::kTestingThemeBackground
&& _id != internal::kTestingDefaultBackground) { && id() != details::kTestingDefaultBackground) {
Local::writeUserSettings(); Local::writeUserSettings();
} }
notify(BackgroundUpdate(BackgroundUpdate::Type::Changed, tile)); notify(BackgroundUpdate(BackgroundUpdate::Type::Changed, tile));
@ -600,19 +602,19 @@ QString ChatBackground::themeAbsolutePath() const {
} }
void ChatBackground::reset() { void ChatBackground::reset() {
if (_id == internal::kTestingThemeBackground if (id() == details::kTestingThemeBackground
|| _id == internal::kTestingDefaultBackground) { || id() == details::kTestingDefaultBackground) {
if (_themeImage.isNull()) { if (_themeImage.isNull()) {
_idForRevert = kDefaultBackground; _paperForRevert = { kDefaultBackground };
_imageForRevert = QImage(); _imageForRevert = QImage();
_tileForRevert = false; _tileForRevert = false;
} else { } else {
_idForRevert = kThemeBackground; _paperForRevert = { kThemeBackground };
_imageForRevert = _themeImage; _imageForRevert = _themeImage;
_tileForRevert = _themeTile; _tileForRevert = _themeTile;
} }
} else { } else {
setImage(kThemeBackground); setImage({ kThemeBackground });
restoreAdjustableColors(); restoreAdjustableColors();
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);
@ -621,9 +623,9 @@ void ChatBackground::reset() {
void ChatBackground::saveForRevert() { void ChatBackground::saveForRevert() {
ensureStarted(); ensureStarted();
if (_id != internal::kTestingThemeBackground if (id() != details::kTestingThemeBackground
&& _id != internal::kTestingDefaultBackground) { && id() != details::kTestingDefaultBackground) {
_idForRevert = _id; _paperForRevert = _paper;
_imageForRevert = std::move(_pixmap).toImage(); _imageForRevert = std::move(_pixmap).toImage();
_tileForRevert = tile(); _tileForRevert = tile();
} }
@ -647,23 +649,23 @@ void ChatBackground::setTestingTheme(Instance &&theme) {
saveAdjustableColors(); saveAdjustableColors();
auto switchToThemeBackground = !theme.background.isNull() auto switchToThemeBackground = !theme.background.isNull()
|| (_id == kThemeBackground) || (id() == kThemeBackground)
|| (_id == kDefaultBackground || (id() == kDefaultBackground
&& !nightMode() && !nightMode()
&& _themeAbsolutePath.isEmpty()); && _themeAbsolutePath.isEmpty());
if (AreTestingTheme() && IsPaletteTestingPath(instance->applying.pathAbsolute)) { if (AreTestingTheme() && IsPaletteTestingPath(GlobalApplying.pathAbsolute)) {
// Grab current background image if it is not already custom // Grab current background image if it is not already custom
if (_id != kCustomBackground) { if (id() != kCustomBackground) {
saveForRevert(); saveForRevert();
setImage(internal::kTestingEditorBackground, std::move(_pixmap).toImage()); setImage({ details::kTestingEditorBackground }, std::move(_pixmap).toImage());
} }
} else if (switchToThemeBackground) { } else if (switchToThemeBackground) {
saveForRevert(); saveForRevert();
setImage(internal::kTestingThemeBackground, std::move(theme.background)); setImage({ details::kTestingThemeBackground }, std::move(theme.background));
setTile(theme.tiled); setTile(theme.tiled);
} else { } else {
// Apply current background image so that service bg colors are recounted. // Apply current background image so that service bg colors are recounted.
setImage(_id, std::move(_pixmap).toImage()); setImage(_paper, std::move(_pixmap).toImage());
} }
notify(BackgroundUpdate(BackgroundUpdate::Type::TestingTheme, tile()), true); notify(BackgroundUpdate(BackgroundUpdate::Type::TestingTheme, tile()), true);
} }
@ -673,29 +675,29 @@ void ChatBackground::setTestingDefaultTheme() {
saveAdjustableColors(); saveAdjustableColors();
saveForRevert(); saveForRevert();
setImage(internal::kTestingDefaultBackground); setImage({ details::kTestingDefaultBackground });
setTile(false); setTile(false);
notify(BackgroundUpdate(BackgroundUpdate::Type::TestingTheme, tile()), true); notify(BackgroundUpdate(BackgroundUpdate::Type::TestingTheme, tile()), true);
} }
void ChatBackground::keepApplied(const QString &path, bool write) { void ChatBackground::keepApplied(const QString &path, bool write) {
setThemeAbsolutePath(path); setThemeAbsolutePath(path);
if (_id == internal::kTestingEditorBackground) { if (id() == details::kTestingEditorBackground) {
_id = kCustomBackground; _paper = { kCustomBackground };
_themeImage = QImage(); _themeImage = QImage();
_themeTile = false; _themeTile = false;
if (write) { if (write) {
writeNewBackgroundSettings(); writeNewBackgroundSettings();
} }
} else if (_id == internal::kTestingThemeBackground) { } else if (id() == details::kTestingThemeBackground) {
_id = kThemeBackground; _paper = { kThemeBackground };
_themeImage = _pixmap.toImage(); _themeImage = _pixmap.toImage();
_themeTile = tile(); _themeTile = tile();
if (write) { if (write) {
writeNewBackgroundSettings(); writeNewBackgroundSettings();
} }
} else if (_id == internal::kTestingDefaultBackground) { } else if (id() == details::kTestingDefaultBackground) {
_id = kDefaultBackground; _paper = { kDefaultBackground };
_themeImage = QImage(); _themeImage = QImage();
_themeTile = false; _themeTile = false;
if (write) { if (write) {
@ -709,16 +711,16 @@ bool ChatBackground::isNonDefaultThemeOrBackground() {
start(); start();
return nightMode() return nightMode()
? (_themeAbsolutePath != NightThemePath() ? (_themeAbsolutePath != NightThemePath()
|| _id != kThemeBackground) || id() != kThemeBackground)
: (!_themeAbsolutePath.isEmpty() : (!_themeAbsolutePath.isEmpty()
|| _id != kDefaultBackground); || id() != kDefaultBackground);
} }
bool ChatBackground::isNonDefaultBackground() { bool ChatBackground::isNonDefaultBackground() {
start(); start();
return _themeAbsolutePath.isEmpty() return _themeAbsolutePath.isEmpty()
? (_id != kDefaultBackground) ? (id() != kDefaultBackground)
: (_id != kThemeBackground); : (id() != kThemeBackground);
} }
void ChatBackground::writeNewBackgroundSettings() { void ChatBackground::writeNewBackgroundSettings() {
@ -726,21 +728,21 @@ void ChatBackground::writeNewBackgroundSettings() {
Local::writeUserSettings(); Local::writeUserSettings();
} }
Local::writeBackground( Local::writeBackground(
_id, _paper,
((_id == kThemeBackground || _id == kDefaultBackground) ((id() == kThemeBackground || id() == kDefaultBackground)
? QImage() ? QImage()
: _pixmap.toImage())); : _pixmap.toImage()));
} }
void ChatBackground::revert() { void ChatBackground::revert() {
if (_id == internal::kTestingThemeBackground if (id() == details::kTestingThemeBackground
|| _id == internal::kTestingDefaultBackground || id() == details::kTestingDefaultBackground
|| _id == internal::kTestingEditorBackground) { || id() == details::kTestingEditorBackground) {
setTile(_tileForRevert); setTile(_tileForRevert);
setImage(_idForRevert, std::move(_imageForRevert)); setImage(_paperForRevert, std::move(_imageForRevert));
} else { } else {
// Apply current background image so that service bg colors are recounted. // Apply current background image so that service bg colors are recounted.
setImage(_id, std::move(_pixmap).toImage()); setImage(_paper, std::move(_pixmap).toImage());
} }
notify(BackgroundUpdate(BackgroundUpdate::Type::RevertingTheme, tile()), true); notify(BackgroundUpdate(BackgroundUpdate::Type::RevertingTheme, tile()), true);
} }
@ -791,7 +793,7 @@ void ChatBackground::toggleNightMode(std::optional<QString> themePath) {
// Theme editor could have already reverted the testing of this toggle. // Theme editor could have already reverted the testing of this toggle.
if (AreTestingTheme()) { if (AreTestingTheme()) {
instance->applying.overrideKeep = [=] { GlobalApplying.overrideKeep = [=] {
_nightMode = newNightMode; _nightMode = newNightMode;
// Restore the value, it was set inside theme testing. // Restore the value, it was set inside theme testing.
@ -808,15 +810,15 @@ void ChatBackground::toggleNightMode(std::optional<QString> themePath) {
} }
Local::writeSettings(); Local::writeSettings();
if (!settingDefault && !Local::readBackground()) { if (!settingDefault && !Local::readBackground()) {
setImage(kThemeBackground); setImage({ kThemeBackground });
} }
}; };
} }
} }
ChatBackground *Background() { ChatBackground *Background() {
instance.createIfNull(); GlobalBackground.createIfNull();
return &instance->background; return GlobalBackground.data();
} }
bool Load(Saved &&saved) { bool Load(Saved &&saved) {
@ -827,7 +829,7 @@ bool Load(Saved &&saved) {
return false; return false;
} }
instance.createIfNull(); GlobalBackground.createIfNull();
if (loadThemeFromCache(saved.content, saved.cache)) { if (loadThemeFromCache(saved.content, saved.cache)) {
Background()->setThemeAbsolutePath(saved.pathAbsolute); Background()->setThemeAbsolutePath(saved.pathAbsolute);
return true; return true;
@ -842,7 +844,8 @@ bool Load(Saved &&saved) {
} }
void Unload() { void Unload() {
instance.clear(); GlobalBackground.clear();
GlobalApplying = Applying();
} }
bool Apply(const QString &filepath) { bool Apply(const QString &filepath) {
@ -853,13 +856,12 @@ bool Apply(const QString &filepath) {
} }
bool Apply(std::unique_ptr<Preview> preview) { bool Apply(std::unique_ptr<Preview> preview) {
instance.createIfNull(); GlobalApplying.pathRelative = std::move(preview->pathRelative);
instance->applying.pathRelative = std::move(preview->pathRelative); GlobalApplying.pathAbsolute = std::move(preview->pathAbsolute);
instance->applying.pathAbsolute = std::move(preview->pathAbsolute); GlobalApplying.content = std::move(preview->content);
instance->applying.content = std::move(preview->content); GlobalApplying.cached = std::move(preview->instance.cached);
instance->applying.cached = std::move(preview->instance.cached); if (GlobalApplying.paletteForRevert.isEmpty()) {
if (instance->applying.paletteForRevert.isEmpty()) { GlobalApplying.paletteForRevert = style::main_palette::save();
instance->applying.paletteForRevert = style::main_palette::save();
} }
Background()->setTestingTheme(std::move(preview->instance)); Background()->setTestingTheme(std::move(preview->instance));
return true; return true;
@ -871,13 +873,12 @@ void ApplyDefaultWithPath(const QString &themePath) {
Apply(std::move(preview)); Apply(std::move(preview));
} }
} else { } else {
instance.createIfNull(); GlobalApplying.pathRelative = QString();
instance->applying.pathRelative = QString(); GlobalApplying.pathAbsolute = QString();
instance->applying.pathAbsolute = QString(); GlobalApplying.content = QByteArray();
instance->applying.content = QByteArray(); GlobalApplying.cached = Cached();
instance->applying.cached = Cached(); if (GlobalApplying.paletteForRevert.isEmpty()) {
if (instance->applying.paletteForRevert.isEmpty()) { GlobalApplying.paletteForRevert = style::main_palette::save();
instance->applying.paletteForRevert = style::main_palette::save();
} }
Background()->setTestingDefaultTheme(); Background()->setTestingDefaultTheme();
} }
@ -892,17 +893,16 @@ bool ApplyEditedPalette(const QString &path, const QByteArray &content) {
out.cached.paletteChecksum = style::palette::Checksum(); out.cached.paletteChecksum = style::palette::Checksum();
out.cached.contentChecksum = hashCrc32(content.constData(), content.size()); out.cached.contentChecksum = hashCrc32(content.constData(), content.size());
instance.createIfNull(); GlobalApplying.pathRelative = path.isEmpty()
instance->applying.pathRelative = path.isEmpty()
? QString() ? QString()
: QDir().relativeFilePath(path); : QDir().relativeFilePath(path);
instance->applying.pathAbsolute = path.isEmpty() GlobalApplying.pathAbsolute = path.isEmpty()
? QString() ? QString()
: QFileInfo(path).absoluteFilePath(); : QFileInfo(path).absoluteFilePath();
instance->applying.content = content; GlobalApplying.content = content;
instance->applying.cached = out.cached; GlobalApplying.cached = out.cached;
if (instance->applying.paletteForRevert.isEmpty()) { if (GlobalApplying.paletteForRevert.isEmpty()) {
instance->applying.paletteForRevert = style::main_palette::save(); GlobalApplying.paletteForRevert = style::main_palette::save();
} }
Background()->setTestingTheme(std::move(out)); Background()->setTestingTheme(std::move(out));
KeepApplied(); KeepApplied();
@ -912,15 +912,15 @@ bool ApplyEditedPalette(const QString &path, const QByteArray &content) {
void KeepApplied() { void KeepApplied() {
if (!AreTestingTheme()) { if (!AreTestingTheme()) {
return; return;
} else if (instance->applying.overrideKeep) { } else if (GlobalApplying.overrideKeep) {
// This callback will be destroyed while running. // This callback will be destroyed while running.
// And it won't be able to safely access captures after that. // And it won't be able to safely access captures after that.
// So we save it on stack for the time while it is running. // So we save it on stack for the time while it is running.
const auto saved = base::take(instance->applying.overrideKeep); const auto onstack = base::take(GlobalApplying.overrideKeep);
saved(); onstack();
return; return;
} }
const auto path = instance->applying.pathAbsolute; const auto path = GlobalApplying.pathAbsolute;
WriteAppliedTheme(); WriteAppliedTheme();
ClearApplying(); ClearApplying();
Background()->keepApplied(path, true); Background()->keepApplied(path, true);
@ -930,7 +930,7 @@ void Revert() {
if (!AreTestingTheme()) { if (!AreTestingTheme()) {
return; return;
} }
style::main_palette::load(instance->applying.paletteForRevert); style::main_palette::load(GlobalApplying.paletteForRevert);
Background()->saveAdjustableColors(); Background()->saveAdjustableColors();
ClearApplying(); ClearApplying();
@ -946,11 +946,11 @@ bool IsNonDefaultBackground() {
} }
bool IsNightMode() { bool IsNightMode() {
return instance ? Background()->nightMode() : false; return GlobalBackground ? Background()->nightMode() : false;
} }
void SetNightModeValue(bool nightMode) { void SetNightModeValue(bool nightMode) {
if (instance || nightMode) { if (GlobalBackground || nightMode) {
Background()->setNightModeValue(nightMode); Background()->setNightModeValue(nightMode);
} }
} }

View file

@ -7,9 +7,22 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
*/ */
#pragma once #pragma once
namespace Data {
struct WallPaper {
WallPaperId id = WallPaperId();
uint64 accessHash = 0;
MTPDwallPaper::Flags flags;
QString slug;
ImagePtr thumb;
DocumentData *document = nullptr;
};
} // namespace Data
namespace Window { namespace Window {
namespace Theme { namespace Theme {
namespace internal { namespace details {
constexpr auto FromLegacyBackgroundId(int32 legacyId) -> WallPaperId { constexpr auto FromLegacyBackgroundId(int32 legacyId) -> WallPaperId {
return uint64(0xFFFFFFFF00000000ULL) | uint64(uint32(legacyId)); return uint64(0xFFFFFFFF00000000ULL) | uint64(uint32(legacyId));
@ -21,12 +34,12 @@ constexpr auto kTestingDefaultBackground = FromLegacyBackgroundId(-665);
constexpr auto kTestingEditorBackground = FromLegacyBackgroundId(-664); constexpr auto kTestingEditorBackground = FromLegacyBackgroundId(-664);
constexpr auto kLegacyBackgroundId = int32(-111); constexpr auto kLegacyBackgroundId = int32(-111);
} // namespace internal } // namespace details
constexpr auto kThemeBackground = internal::FromLegacyBackgroundId(-2); constexpr auto kThemeBackground = details::FromLegacyBackgroundId(-2);
constexpr auto kCustomBackground = internal::FromLegacyBackgroundId(-1); constexpr auto kCustomBackground = details::FromLegacyBackgroundId(-1);
constexpr auto kInitialBackground = internal::FromLegacyBackgroundId(0); constexpr auto kInitialBackground = details::FromLegacyBackgroundId(0);
constexpr auto kDefaultBackground = internal::FromLegacyBackgroundId(105); constexpr auto kDefaultBackground = details::FromLegacyBackgroundId(105);
struct Cached { struct Cached {
QByteArray colors; QByteArray colors;
@ -103,7 +116,7 @@ public:
// This method is setting the default (themed) image if none was set yet. // This method is setting the default (themed) image if none was set yet.
void start(); void start();
void setImage(WallPaperId id, QImage &&image = QImage()); void setImage(const Data::WallPaper &paper, QImage &&image = QImage());
void setTile(bool tile); void setTile(bool tile);
void setTileDayValue(bool tile); void setTileDayValue(bool tile);
void setTileNightValue(bool tile); void setTileNightValue(bool tile);
@ -157,7 +170,7 @@ private:
friend void KeepApplied(); friend void KeepApplied();
friend bool IsNonDefaultBackground(); friend bool IsNonDefaultBackground();
WallPaperId _id = internal::kUninitializedBackground; Data::WallPaper _paper = { details::kUninitializedBackground };
QPixmap _pixmap; QPixmap _pixmap;
QPixmap _pixmapForTiled; QPixmap _pixmapForTiled;
bool _nightMode = false; bool _nightMode = false;
@ -168,7 +181,7 @@ private:
QImage _themeImage; QImage _themeImage;
bool _themeTile = false; bool _themeTile = false;
WallPaperId _idForRevert = internal::kUninitializedBackground; Data::WallPaper _paperForRevert = { details::kUninitializedBackground };
QImage _imageForRevert; QImage _imageForRevert;
bool _tileForRevert = false; bool _tileForRevert = false;