mirror of
https://github.com/vale981/tdesktop
synced 2025-03-06 10:11:41 -05:00
Save wallpaper settings locally.
This commit is contained in:
parent
2f702148e3
commit
f506a5ea6c
14 changed files with 624 additions and 266 deletions
|
@ -884,24 +884,13 @@ void ApiWrap::requestWallPaper(
|
|||
)).done([=](const MTPWallPaper &result) {
|
||||
_wallPaperRequestId = 0;
|
||||
_wallPaperSlug = QString();
|
||||
result.match([&](const MTPDwallPaper &data) {
|
||||
const auto document = _session->data().processDocument(
|
||||
data.vdocument);
|
||||
if (document->checkWallPaperProperties()) {
|
||||
if (const auto paper = Data::WallPaper::Create(result)) {
|
||||
if (const auto done = base::take(_wallPaperDone)) {
|
||||
done({
|
||||
data.vid.v,
|
||||
data.vaccess_hash.v,
|
||||
data.vflags.v,
|
||||
qs(data.vslug),
|
||||
document->thumbnail(),
|
||||
document
|
||||
});
|
||||
done(*paper);
|
||||
}
|
||||
} else if (const auto fail = base::take(_wallPaperFail)) {
|
||||
fail(RPCError::Local("BAD_DOCUMENT", "In a wallpaper."));
|
||||
}
|
||||
});
|
||||
}).fail([=](const RPCError &error) {
|
||||
_wallPaperRequestId = 0;
|
||||
_wallPaperSlug = QString();
|
||||
|
|
|
@ -25,7 +25,7 @@ class mtpFileLoader;
|
|||
|
||||
namespace Data {
|
||||
struct UpdatedFileReferences;
|
||||
struct WallPaper;
|
||||
class WallPaper;
|
||||
} // namespace Data
|
||||
|
||||
namespace InlineBots {
|
||||
|
|
|
@ -95,11 +95,11 @@ QImage PrepareScaledFromFull(
|
|||
size);
|
||||
}
|
||||
|
||||
QPixmap PrepareScaledFromThumb(not_null<Image*> thumb) {
|
||||
QPixmap PrepareScaledFromThumb(not_null<Image*> thumb, bool good) {
|
||||
return thumb->loaded()
|
||||
? App::pixmapFromImageInPlace(PrepareScaledFromFull(
|
||||
thumb->original(),
|
||||
Images::Option::Blurred))
|
||||
good ? Images::Option(0) : Images::Option::Blurred))
|
||||
: QPixmap();
|
||||
}
|
||||
|
||||
|
@ -126,6 +126,11 @@ protected:
|
|||
|
||||
private:
|
||||
void updateWallpapers();
|
||||
void paintPaper(
|
||||
Painter &p,
|
||||
const Data::WallPaper &paper,
|
||||
int column,
|
||||
int row) const;
|
||||
|
||||
Fn<void(int index)> _backgroundChosenCallback;
|
||||
|
||||
|
@ -196,7 +201,7 @@ void BackgroundBox::Inner::updateWallpapers() {
|
|||
|
||||
const auto preload = kBackgroundsInRow * 3;
|
||||
for (const auto &paper : papers | ranges::view::take(preload)) {
|
||||
paper.thumb->load(Data::FileOrigin());
|
||||
paper.loadThumbnail();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -223,26 +228,34 @@ void BackgroundBox::Inner::paintEvent(QPaintEvent *e) {
|
|||
});
|
||||
if ((st::backgroundSize.height() + st::backgroundPadding) * (row + 1) <= r.top()) {
|
||||
continue;
|
||||
} else if ((st::backgroundSize.height() + st::backgroundPadding) * row >= r.top() + r.height()) {
|
||||
break;
|
||||
}
|
||||
paintPaper(p, paper, column, row);
|
||||
}
|
||||
}
|
||||
|
||||
paper.thumb->load(Data::FileOrigin());
|
||||
void BackgroundBox::Inner::paintPaper(
|
||||
Painter &p,
|
||||
const Data::WallPaper &paper,
|
||||
int column,
|
||||
int row) const {
|
||||
Expects(paper.thumbnail() != nullptr);
|
||||
|
||||
int x = st::backgroundPadding + column * (st::backgroundSize.width() + st::backgroundPadding);
|
||||
int y = st::backgroundPadding + row * (st::backgroundSize.height() + st::backgroundPadding);
|
||||
|
||||
const auto &pix = paper.thumb->pix(
|
||||
Data::FileOrigin(),
|
||||
const auto x = st::backgroundPadding + column * (st::backgroundSize.width() + st::backgroundPadding);
|
||||
const auto y = st::backgroundPadding + row * (st::backgroundSize.height() + st::backgroundPadding);
|
||||
const auto &pixmap = paper.thumbnail()->pix(
|
||||
paper.fileOrigin(),
|
||||
st::backgroundSize.width(),
|
||||
st::backgroundSize.height());
|
||||
p.drawPixmap(x, y, pix);
|
||||
p.drawPixmap(x, y, pixmap);
|
||||
|
||||
if (paper.id == Window::Theme::Background()->id()) {
|
||||
auto checkLeft = x + st::backgroundSize.width() - st::overviewCheckSkip - st::overviewCheck.size;
|
||||
auto checkTop = y + st::backgroundSize.height() - st::overviewCheckSkip - st::overviewCheck.size;
|
||||
if (paper.id() == Window::Theme::Background()->id()) {
|
||||
const auto checkLeft = x + st::backgroundSize.width() - st::overviewCheckSkip - st::overviewCheck.size;
|
||||
const auto checkTop = y + st::backgroundSize.height() - st::overviewCheckSkip - st::overviewCheck.size;
|
||||
_check->paint(p, getms(), checkLeft, checkTop, width());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void BackgroundBox::Inner::mouseMoveEvent(QMouseEvent *e) {
|
||||
const auto newOver = [&] {
|
||||
|
@ -300,6 +313,8 @@ BackgroundPreviewBox::BackgroundPreviewBox(
|
|||
true))
|
||||
, _paper(paper)
|
||||
, _radial(animation(this, &BackgroundPreviewBox::step_radial)) {
|
||||
Expects(_paper.thumbnail() != nullptr);
|
||||
|
||||
subscribe(Auth().downloaderTaskFinished(), [=] { update(); });
|
||||
}
|
||||
|
||||
|
@ -308,27 +323,18 @@ void BackgroundPreviewBox::prepare() {
|
|||
|
||||
addButton(langFactory(lng_background_apply), [=] { apply(); });
|
||||
addButton(langFactory(lng_cancel), [=] { closeBox(); });
|
||||
if (!_paper.slug.isEmpty()) {
|
||||
if (_paper.hasShareUrl()) {
|
||||
addLeftButton(langFactory(lng_background_share), [=] { share(); });
|
||||
}
|
||||
|
||||
_scaled = PrepareScaledFromThumb(_paper.thumb);
|
||||
_paper.loadThumbnail();
|
||||
_paper.loadDocument();
|
||||
if (_paper.document() && _paper.document()->loading()) {
|
||||
_radial.start(_paper.document()->progress());
|
||||
}
|
||||
setScaledFromThumb();
|
||||
checkLoadedDocument();
|
||||
|
||||
if (!_paper.thumb->loaded()) {
|
||||
_paper.thumb->loadEvenCancelled(Data::FileOriginWallpaper(
|
||||
_paper.id,
|
||||
_paper.accessHash));
|
||||
}
|
||||
if (_paper.document) {
|
||||
_paper.document->save(Data::FileOriginWallpaper(
|
||||
_paper.id,
|
||||
_paper.accessHash), QString());
|
||||
if (_paper.document->loading()) {
|
||||
_radial.start(_paper.document->progress());
|
||||
}
|
||||
}
|
||||
|
||||
_text1->setDisplayDate(true);
|
||||
_text1->initDimensions();
|
||||
_text1->resizeGetHeight(st::boxWideWidth);
|
||||
|
@ -344,10 +350,7 @@ void BackgroundPreviewBox::apply() {
|
|||
}
|
||||
|
||||
void BackgroundPreviewBox::share() {
|
||||
Expects(!_paper.slug.isEmpty());
|
||||
|
||||
QApplication::clipboard()->setText(
|
||||
Core::App().createInternalLinkFull("bg/" + _paper.slug));
|
||||
QApplication::clipboard()->setText(_paper.shareUrl());
|
||||
Ui::Toast::Show(lang(lng_background_link_copied));
|
||||
}
|
||||
|
||||
|
@ -356,16 +359,13 @@ void BackgroundPreviewBox::paintEvent(QPaintEvent *e) {
|
|||
|
||||
const auto ms = getms();
|
||||
|
||||
if (const auto color = Window::Theme::GetWallPaperColor(_paper.slug)) {
|
||||
if (const auto color = _paper.backgroundColor()) {
|
||||
p.fillRect(e->rect(), *color);
|
||||
} else {
|
||||
if (_scaled.isNull()) {
|
||||
_scaled = PrepareScaledFromThumb(_paper.thumb);
|
||||
if (_scaled.isNull()) {
|
||||
if (_scaled.isNull() && !setScaledFromThumb()) {
|
||||
p.fillRect(e->rect(), st::boxBg);
|
||||
return;
|
||||
}
|
||||
}
|
||||
paintImage(p);
|
||||
paintRadial(p, ms);
|
||||
}
|
||||
|
@ -440,9 +440,9 @@ void BackgroundPreviewBox::paintTexts(Painter &p, TimeMs ms) {
|
|||
}
|
||||
|
||||
void BackgroundPreviewBox::step_radial(TimeMs ms, bool timer) {
|
||||
Expects(_paper.document != nullptr);
|
||||
Expects(_paper.document() != nullptr);
|
||||
|
||||
const auto document = _paper.document;
|
||||
const auto document = _paper.document();
|
||||
const auto wasAnimating = _radial.animating();
|
||||
const auto updated = _radial.update(
|
||||
document->progress(),
|
||||
|
@ -456,8 +456,15 @@ void BackgroundPreviewBox::step_radial(TimeMs ms, bool timer) {
|
|||
checkLoadedDocument();
|
||||
}
|
||||
|
||||
bool BackgroundPreviewBox::setScaledFromThumb() {
|
||||
_scaled = PrepareScaledFromThumb(
|
||||
_paper.thumbnail(),
|
||||
!_paper.document());
|
||||
return !_scaled.isNull();
|
||||
}
|
||||
|
||||
void BackgroundPreviewBox::checkLoadedDocument() {
|
||||
const auto document = _paper.document;
|
||||
const auto document = _paper.document();
|
||||
if (!document
|
||||
|| !document->loaded(DocumentData::FilePathResolveChecked)
|
||||
|| _generating) {
|
||||
|
@ -491,13 +498,8 @@ void BackgroundPreviewBox::checkLoadedDocument() {
|
|||
}
|
||||
|
||||
bool BackgroundPreviewBox::Start(const QString &slug, const QString &mode) {
|
||||
if (Window::Theme::GetWallPaperColor(slug)) {
|
||||
Ui::show(Box<BackgroundPreviewBox>(Data::WallPaper{
|
||||
Window::Theme::kCustomBackground,
|
||||
0ULL, // accessHash
|
||||
MTPDwallPaper::Flags(0),
|
||||
slug,
|
||||
}));
|
||||
if (const auto paper = Data::WallPaper::FromColorSlug(slug)) {
|
||||
Ui::show(Box<BackgroundPreviewBox>(*paper));
|
||||
return true;
|
||||
}
|
||||
if (!IsValidWallPaperSlug(slug)) {
|
||||
|
|
|
@ -66,6 +66,7 @@ private:
|
|||
QRect radialRect() const;
|
||||
|
||||
void checkLoadedDocument();
|
||||
bool setScaledFromThumb();
|
||||
void paintImage(Painter &p);
|
||||
void paintRadial(Painter &p, TimeMs ms);
|
||||
void paintTexts(Painter &p, TimeMs ms);
|
||||
|
|
|
@ -3070,41 +3070,23 @@ void Session::setWallpapers(const QVector<MTPWallPaper> &data, int32 hash) {
|
|||
qsl(":/gui/art/bg.jpg"),
|
||||
"JPG");
|
||||
if (defaultBackground) {
|
||||
_wallpapers.push_back({
|
||||
Window::Theme::kDefaultBackground,
|
||||
0ULL, // access_hash
|
||||
MTPDwallPaper::Flags(0),
|
||||
QString(), // slug
|
||||
defaultBackground.get()
|
||||
});
|
||||
_wallpapers.push_back(Data::DefaultWallPaper());
|
||||
_wallpapers.back().setLocalImageAsThumbnail(
|
||||
defaultBackground.get());
|
||||
}
|
||||
const auto oldBackground = Images::Create(
|
||||
qsl(":/gui/art/bg_initial.jpg"),
|
||||
"JPG");
|
||||
if (oldBackground) {
|
||||
_wallpapers.push_back({
|
||||
Window::Theme::kInitialBackground,
|
||||
0ULL, // access_hash
|
||||
MTPDwallPaper::Flags(0),
|
||||
QString(), // slug
|
||||
oldBackground.get()
|
||||
});
|
||||
_wallpapers.push_back(Data::Legacy1DefaultWallPaper());
|
||||
_wallpapers.back().setLocalImageAsThumbnail(oldBackground.get());
|
||||
}
|
||||
for (const auto &paper : data) {
|
||||
paper.match([&](const MTPDwallPaper &paper) {
|
||||
if (paper.is_pattern()) {
|
||||
return;
|
||||
}
|
||||
const auto document = processDocument(paper.vdocument);
|
||||
if (document->checkWallPaperProperties()) {
|
||||
_wallpapers.push_back({
|
||||
paper.vid.v,
|
||||
paper.vaccess_hash.v,
|
||||
paper.vflags.v,
|
||||
qs(paper.vslug),
|
||||
document->thumbnail(),
|
||||
document,
|
||||
});
|
||||
} else if (const auto parsed = Data::WallPaper::Create(paper)) {
|
||||
_wallpapers.push_back(*parsed);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
|
|
@ -51,7 +51,7 @@ class Feed;
|
|||
enum class FeedUpdateFlag;
|
||||
struct FeedUpdate;
|
||||
|
||||
struct WallPaper;
|
||||
class WallPaper;
|
||||
|
||||
class Session final {
|
||||
public:
|
||||
|
|
|
@ -345,10 +345,17 @@ StackItemSection::StackItemSection(
|
|||
}
|
||||
|
||||
struct MainWidget::SettingBackground {
|
||||
explicit SettingBackground(const Data::WallPaper &data);
|
||||
|
||||
Data::WallPaper data;
|
||||
base::binary_guard generating;
|
||||
};
|
||||
|
||||
MainWidget::SettingBackground::SettingBackground(
|
||||
const Data::WallPaper &data)
|
||||
: data(data) {
|
||||
}
|
||||
|
||||
MainWidget::MainWidget(
|
||||
QWidget *parent,
|
||||
not_null<Window::Controller*> controller)
|
||||
|
@ -1554,16 +1561,11 @@ void MainWidget::setChatBackground(
|
|||
return;
|
||||
}
|
||||
|
||||
_background = std::make_unique<SettingBackground>();
|
||||
_background->data = background;
|
||||
_background->data.document->save(
|
||||
Data::FileOriginWallpaper(
|
||||
_background->data.id,
|
||||
_background->data.accessHash),
|
||||
QString());
|
||||
_background = std::make_unique<SettingBackground>(background);
|
||||
_background->data.loadDocument();
|
||||
checkChatBackground();
|
||||
|
||||
const auto tile = (background.id == Window::Theme::kInitialBackground);
|
||||
const auto tile = Data::IsLegacy1DefaultWallPaper(background);
|
||||
using Update = Window::Theme::BackgroundUpdate;
|
||||
Window::Theme::Background()->notify(Update(Update::Type::Start, tile));
|
||||
}
|
||||
|
@ -1571,9 +1573,7 @@ void MainWidget::setChatBackground(
|
|||
bool MainWidget::isReadyChatBackground(
|
||||
const Data::WallPaper &background,
|
||||
const QImage &image) const {
|
||||
return !image.isNull()
|
||||
|| !background.document
|
||||
|| Window::Theme::GetWallPaperColor(background.slug);
|
||||
return !image.isNull() || !background.document();
|
||||
}
|
||||
|
||||
void MainWidget::setReadyChatBackground(
|
||||
|
@ -1582,22 +1582,22 @@ void MainWidget::setReadyChatBackground(
|
|||
using namespace Window::Theme;
|
||||
|
||||
if (image.isNull()
|
||||
&& !background.document
|
||||
&& background.thumb
|
||||
&& background.thumb->loaded()) {
|
||||
image = background.thumb->pixNoCache(Data::FileOrigin()).toImage();
|
||||
&& !background.document()
|
||||
&& background.thumbnail()
|
||||
&& background.thumbnail()->loaded()) {
|
||||
image = background.thumbnail()->original();
|
||||
}
|
||||
|
||||
const auto resetToDefault = image.isNull()
|
||||
&& !background.document
|
||||
&& !GetWallPaperColor(background.slug)
|
||||
&& (background.id != kInitialBackground);
|
||||
&& !background.document()
|
||||
&& !background.backgroundColor()
|
||||
&& !Data::IsLegacy1DefaultWallPaper(background);
|
||||
const auto ready = resetToDefault
|
||||
? Data::WallPaper{ kDefaultBackground }
|
||||
? Data::DefaultWallPaper()
|
||||
: background;
|
||||
|
||||
Background()->setImage(ready, std::move(image));
|
||||
const auto tile = (ready.id == kInitialBackground);
|
||||
const auto tile = Data::IsLegacy1DefaultWallPaper(ready);
|
||||
Background()->setTile(tile);
|
||||
Ui::ForceFullRepaint(this);
|
||||
}
|
||||
|
@ -1610,10 +1610,10 @@ float64 MainWidget::chatBackgroundProgress() const {
|
|||
if (_background) {
|
||||
if (_background->generating) {
|
||||
return 1.;
|
||||
} else if (_background->data.document) {
|
||||
return _background->data.document->progress();
|
||||
} else if (_background->data.thumb) {
|
||||
return _background->data.thumb->progress();
|
||||
} else if (const auto document = _background->data.document()) {
|
||||
return document->progress();
|
||||
} else if (const auto thumbnail = _background->data.thumbnail()) {
|
||||
return thumbnail->progress();
|
||||
}
|
||||
}
|
||||
return 1.;
|
||||
|
@ -1623,10 +1623,9 @@ void MainWidget::checkChatBackground() {
|
|||
if (!_background || _background->generating) {
|
||||
return;
|
||||
}
|
||||
const auto document = _background->data.document;
|
||||
if (document && !document->loaded()) {
|
||||
return;
|
||||
} else if (!document && !_background->data.thumb->loaded()) {
|
||||
const auto document = _background->data.document();
|
||||
Assert(document != nullptr);
|
||||
if (!document->loaded()) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -1634,14 +1633,14 @@ void MainWidget::checkChatBackground() {
|
|||
QImage &&image) {
|
||||
const auto background = base::take(_background);
|
||||
const auto ready = image.isNull()
|
||||
? Data::WallPaper{ Window::Theme::kDefaultBackground }
|
||||
? Data::DefaultWallPaper()
|
||||
: background->data;
|
||||
setChatBackground(ready, std::move(image));
|
||||
setReadyChatBackground(ready, std::move(image));
|
||||
});
|
||||
}
|
||||
|
||||
Image *MainWidget::newBackgroundThumb() {
|
||||
return _background ? _background->data.thumb : nullptr;
|
||||
return _background ? _background->data.thumbnail() : nullptr;
|
||||
}
|
||||
|
||||
void MainWidget::messageDataReceived(ChannelData *channel, MsgId msgId) {
|
||||
|
|
|
@ -27,7 +27,7 @@ struct PeerUpdate;
|
|||
} // namespace Notify
|
||||
|
||||
namespace Data {
|
||||
struct WallPaper;
|
||||
class WallPaper;
|
||||
} // namespace Data
|
||||
|
||||
namespace Dialogs {
|
||||
|
|
|
@ -410,7 +410,7 @@ void ChooseFromFile(not_null<QWidget*> parent) {
|
|||
}
|
||||
|
||||
Window::Theme::Background()->setImage(
|
||||
{ Window::Theme::kCustomBackground },
|
||||
Data::CustomWallPaper(),
|
||||
std::move(image));
|
||||
Window::Theme::Background()->setTile(false);
|
||||
};
|
||||
|
|
|
@ -49,6 +49,9 @@ constexpr auto kDefaultStickerInstallDate = TimeId(1);
|
|||
constexpr auto kProxyTypeShift = 1024;
|
||||
constexpr auto kWriteMapTimeout = TimeMs(1000);
|
||||
|
||||
constexpr auto kWallPaperLegacySerializeTagId = int32(-111);
|
||||
constexpr auto kWallPaperSerializeTagId = int32(-112);
|
||||
|
||||
constexpr auto kSinglePeerTypeUser = qint32(1);
|
||||
constexpr auto kSinglePeerTypeChat = qint32(2);
|
||||
constexpr auto kSinglePeerTypeChannel = qint32(3);
|
||||
|
@ -3982,19 +3985,23 @@ void writeBackground(const Data::WallPaper &paper, const QImage &img) {
|
|||
_mapChanged = true;
|
||||
_writeMap(WriteMapWhen::Fast);
|
||||
}
|
||||
const auto serialized = paper.serialize();
|
||||
quint32 size = sizeof(qint32)
|
||||
+ 2 * sizeof(quint64)
|
||||
+ sizeof(quint32)
|
||||
+ Serialize::stringSize(paper.slug)
|
||||
+ Serialize::bytearraySize(serialized)
|
||||
+ Serialize::bytearraySize(bmp);
|
||||
EncryptedDescriptor data(size);
|
||||
data.stream
|
||||
<< qint32(Window::Theme::details::kLegacyBackgroundId)
|
||||
<< quint64(paper.id)
|
||||
<< quint64(paper.accessHash)
|
||||
<< quint32(paper.flags.value())
|
||||
<< paper.slug
|
||||
<< qint32(kWallPaperSerializeTagId)
|
||||
<< serialized
|
||||
<< bmp;
|
||||
//+2 * sizeof(quint64)
|
||||
// + sizeof(quint32)
|
||||
// + Serialize::stringSize(paper.slug)
|
||||
|
||||
// << quint64(paper.id)
|
||||
// << quint64(paper.accessHash)
|
||||
// << quint32(paper.flags.value())
|
||||
// << paper.slug
|
||||
|
||||
FileWriteDescriptor file(backgroundKey);
|
||||
file.writeEncrypted(data);
|
||||
|
@ -4015,61 +4022,67 @@ bool readBackground() {
|
|||
return false;
|
||||
}
|
||||
|
||||
QByteArray bmpData;
|
||||
qint32 legacyId = 0;
|
||||
bg.stream >> legacyId;
|
||||
const auto paper = [&] {
|
||||
if (legacyId == kWallPaperLegacySerializeTagId) {
|
||||
quint64 id = 0;
|
||||
quint64 accessHash = 0;
|
||||
quint32 flags = 0;
|
||||
QString slug;
|
||||
bg.stream >> legacyId;
|
||||
if (legacyId == Window::Theme::details::kLegacyBackgroundId) {
|
||||
bg.stream
|
||||
>> id
|
||||
>> accessHash
|
||||
>> flags
|
||||
>> slug;
|
||||
return Data::WallPaper::FromLegacySerialized(
|
||||
id,
|
||||
accessHash,
|
||||
flags,
|
||||
slug);
|
||||
} else if (legacyId == kWallPaperSerializeTagId) {
|
||||
QByteArray serialized;
|
||||
bg.stream >> serialized;
|
||||
return Data::WallPaper::FromSerialized(serialized);
|
||||
} else {
|
||||
id = Window::Theme::details::FromLegacyBackgroundId(legacyId);
|
||||
accessHash = 0;
|
||||
if (id != Window::Theme::kCustomBackground) {
|
||||
flags = static_cast<quint32>(MTPDwallPaper::Flag::f_default);
|
||||
return Data::WallPaper::FromLegacyId(legacyId);
|
||||
}
|
||||
}();
|
||||
if (bg.stream.status() != QDataStream::Ok || !paper) {
|
||||
return false;
|
||||
}
|
||||
bg.stream >> bmpData;
|
||||
auto oldEmptyImage = (bg.stream.status() != QDataStream::Ok);
|
||||
if (oldEmptyImage
|
||||
|| id == Window::Theme::kInitialBackground
|
||||
|| id == Window::Theme::kDefaultBackground) {
|
||||
|
||||
QByteArray bmp;
|
||||
bg.stream >> bmp;
|
||||
const auto isOldEmptyImage = (bg.stream.status() != QDataStream::Ok);
|
||||
if (isOldEmptyImage
|
||||
|| Data::IsLegacy1DefaultWallPaper(*paper)
|
||||
|| Data::IsDefaultWallPaper(*paper)) {
|
||||
_backgroundCanWrite = false;
|
||||
if (oldEmptyImage || bg.version < 8005) {
|
||||
Window::Theme::Background()->setImage({ Window::Theme::kDefaultBackground });
|
||||
if (isOldEmptyImage || bg.version < 8005) {
|
||||
Window::Theme::Background()->setImage(Data::DefaultWallPaper());
|
||||
Window::Theme::Background()->setTile(false);
|
||||
} else {
|
||||
Window::Theme::Background()->setImage({ id });
|
||||
Window::Theme::Background()->setImage(*paper);
|
||||
}
|
||||
_backgroundCanWrite = true;
|
||||
return true;
|
||||
} else if (id == Window::Theme::kThemeBackground && bmpData.isEmpty()) {
|
||||
} else if (Data::IsThemeWallPaper(*paper) && bmp.isEmpty()) {
|
||||
_backgroundCanWrite = false;
|
||||
Window::Theme::Background()->setImage({ id });
|
||||
Window::Theme::Background()->setImage(*paper);
|
||||
_backgroundCanWrite = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
QImage image;
|
||||
QBuffer buf(&bmpData);
|
||||
QImageReader reader(&buf);
|
||||
auto image = QImage();
|
||||
auto buffer = QBuffer(&bmp);
|
||||
auto reader = QImageReader(&buffer);
|
||||
#ifndef OS_MAC_OLD
|
||||
reader.setAutoTransform(true);
|
||||
#endif // OS_MAC_OLD
|
||||
if (reader.read(&image) || Window::Theme::GetWallPaperColor(slug)) {
|
||||
if (reader.read(&image) || paper->backgroundColor()) {
|
||||
_backgroundCanWrite = false;
|
||||
Window::Theme::Background()->setImage({
|
||||
id,
|
||||
accessHash,
|
||||
MTPDwallPaper::Flags::from_raw(flags),
|
||||
slug
|
||||
}, std::move(image));
|
||||
Window::Theme::Background()->setImage(*paper, std::move(image));
|
||||
_backgroundCanWrite = true;
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -13,7 +13,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
#include "auth_session.h"
|
||||
|
||||
namespace Data {
|
||||
struct WallPaper;
|
||||
class WallPaper;
|
||||
} // namespace Data
|
||||
|
||||
namespace Lang {
|
||||
|
|
|
@ -9,12 +9,333 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
|
||||
#include "window/themes/window_theme_preview.h"
|
||||
#include "mainwidget.h"
|
||||
#include "auth_session.h"
|
||||
#include "core/application.h"
|
||||
#include "storage/serialize_common.h"
|
||||
#include "data/data_document.h"
|
||||
#include "data/data_session.h"
|
||||
#include "storage/localstorage.h"
|
||||
#include "base/parse_helper.h"
|
||||
#include "base/zlib_help.h"
|
||||
#include "ui/image/image.h"
|
||||
#include "boxes/background_box.h"
|
||||
#include "styles/style_widgets.h"
|
||||
#include "styles/style_history.h"
|
||||
#include "boxes/background_box.h"
|
||||
|
||||
namespace Data {
|
||||
namespace {
|
||||
|
||||
constexpr auto FromLegacyBackgroundId(int32 legacyId) -> WallPaperId {
|
||||
return uint64(0xFFFFFFFF00000000ULL) | uint64(uint32(legacyId));
|
||||
}
|
||||
|
||||
constexpr auto kUninitializedBackground = FromLegacyBackgroundId(-999);
|
||||
constexpr auto kTestingThemeBackground = FromLegacyBackgroundId(-666);
|
||||
constexpr auto kTestingDefaultBackground = FromLegacyBackgroundId(-665);
|
||||
constexpr auto kTestingEditorBackground = FromLegacyBackgroundId(-664);
|
||||
constexpr auto kThemeBackground = FromLegacyBackgroundId(-2);
|
||||
constexpr auto kCustomBackground = FromLegacyBackgroundId(-1);
|
||||
constexpr auto kLegacy1DefaultBackground = FromLegacyBackgroundId(0);
|
||||
constexpr auto kDefaultBackground = FromLegacyBackgroundId(105);
|
||||
|
||||
[[nodiscard]] bool ValidateFlags(MTPDwallPaper::Flags flags) {
|
||||
using Flag = MTPDwallPaper::Flag;
|
||||
const auto all = Flag(0)
|
||||
| Flag::f_creator
|
||||
| Flag::f_default
|
||||
| Flag::f_pattern
|
||||
| Flag::f_settings;
|
||||
return !(flags & ~all);
|
||||
}
|
||||
|
||||
[[nodiscard]] bool ValidateFlags(MTPDwallPaperSettings::Flags flags) {
|
||||
using Flag = MTPDwallPaperSettings::Flag;
|
||||
const auto all = Flag(0)
|
||||
| Flag::f_background_color
|
||||
| Flag::f_blur
|
||||
| Flag::f_intensity
|
||||
| Flag::f_motion;
|
||||
return !(flags & ~all);
|
||||
}
|
||||
|
||||
quint32 SerializeMaybeColor(std::optional<QColor> color) {
|
||||
return color
|
||||
? ((quint32(std::clamp(color->red(), 0, 255)) << 16)
|
||||
| (quint32(std::clamp(color->green(), 0, 255)) << 8)
|
||||
| quint32(std::clamp(color->blue(), 0, 255)))
|
||||
: quint32(-1);
|
||||
}
|
||||
|
||||
std::optional<QColor> MaybeColorFromSerialized(quint32 serialized) {
|
||||
return (serialized == quint32(-1))
|
||||
? std::nullopt
|
||||
: std::make_optional(QColor(
|
||||
int((serialized >> 16) & 0xFFU),
|
||||
int((serialized >> 8) & 0xFFU),
|
||||
int(serialized & 0xFFU)));
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
WallPaper::WallPaper(WallPaperId id) : _id(id) {
|
||||
}
|
||||
|
||||
void WallPaper::setLocalImageAsThumbnail(not_null<Image*> image) {
|
||||
Expects(IsDefaultWallPaper(*this)
|
||||
|| IsLegacy1DefaultWallPaper(*this)
|
||||
|| IsCustomWallPaper(*this));
|
||||
Expects(_thumbnail == nullptr);
|
||||
|
||||
_thumbnail = image;
|
||||
}
|
||||
|
||||
WallPaperId WallPaper::id() const {
|
||||
return _id;
|
||||
}
|
||||
|
||||
std::optional<QColor> WallPaper::backgroundColor() const {
|
||||
return _backgroundColor;
|
||||
}
|
||||
|
||||
DocumentData *WallPaper::document() const {
|
||||
return _document;
|
||||
}
|
||||
|
||||
Image *WallPaper::thumbnail() const {
|
||||
return _thumbnail;
|
||||
}
|
||||
|
||||
bool WallPaper::hasShareUrl() const {
|
||||
return !_slug.isEmpty();
|
||||
}
|
||||
|
||||
QString WallPaper::shareUrl() const {
|
||||
return hasShareUrl()
|
||||
? Core::App().createInternalLinkFull("bg/" + _slug)
|
||||
: QString();
|
||||
}
|
||||
|
||||
void WallPaper::loadThumbnail() const {
|
||||
if (_thumbnail) {
|
||||
_thumbnail->load(fileOrigin());
|
||||
}
|
||||
}
|
||||
|
||||
void WallPaper::loadDocument() const {
|
||||
if (_document) {
|
||||
_document->save(fileOrigin(), QString());
|
||||
}
|
||||
}
|
||||
|
||||
FileOrigin WallPaper::fileOrigin() const {
|
||||
return FileOriginWallpaper(_id, _accessHash);
|
||||
}
|
||||
|
||||
std::optional<WallPaper> WallPaper::Create(const MTPWallPaper &data) {
|
||||
return data.match([](const MTPDwallPaper &data) {
|
||||
return Create(data);
|
||||
});
|
||||
}
|
||||
|
||||
std::optional<WallPaper> WallPaper::Create(const MTPDwallPaper &data) {
|
||||
const auto document = Auth().data().processDocument(
|
||||
data.vdocument);
|
||||
if (!document->checkWallPaperProperties()) {
|
||||
return std::nullopt;
|
||||
}
|
||||
auto result = WallPaper(data.vid.v);
|
||||
result._accessHash = data.vaccess_hash.v;
|
||||
result._flags = data.vflags.v;
|
||||
result._slug = qs(data.vslug);
|
||||
result._document = document;
|
||||
result._thumbnail = document->thumbnail();
|
||||
if (data.has_settings()) {
|
||||
data.vsettings.match([&](const MTPDwallPaperSettings &data) {
|
||||
result._settings = data.vflags.v;
|
||||
if (data.has_background_color()) {
|
||||
result._backgroundColor = MaybeColorFromSerialized(
|
||||
data.vbackground_color.v);
|
||||
}
|
||||
if (data.has_intensity()) {
|
||||
result._intensity = data.vintensity.v;
|
||||
}
|
||||
});
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
QByteArray WallPaper::serialize() const {
|
||||
auto size = sizeof(quint64) // _id
|
||||
+ sizeof(quint64) // _accessHash
|
||||
+ sizeof(qint32) // _flags
|
||||
+ Serialize::stringSize(_slug)
|
||||
+ sizeof(qint32) // _settings
|
||||
+ sizeof(quint32) // _backgroundColor
|
||||
+ sizeof(qint32); // _intensity
|
||||
|
||||
auto result = QByteArray();
|
||||
result.reserve(size);
|
||||
{
|
||||
auto stream = QDataStream(&result, QIODevice::WriteOnly);
|
||||
stream.setVersion(QDataStream::Qt_5_1);
|
||||
stream
|
||||
<< quint64(_id)
|
||||
<< quint64(_accessHash)
|
||||
<< qint32(_flags)
|
||||
<< _slug
|
||||
<< qint32(_settings)
|
||||
<< SerializeMaybeColor(_backgroundColor)
|
||||
<< qint32(_intensity);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
std::optional<WallPaper> WallPaper::FromSerialized(
|
||||
const QByteArray &serialized) {
|
||||
if (serialized.isEmpty()) {
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
auto id = quint64();
|
||||
auto accessHash = quint64();
|
||||
auto flags = qint32();
|
||||
auto slug = QString();
|
||||
auto settings = qint32();
|
||||
auto backgroundColor = quint32();
|
||||
auto intensity = qint32();
|
||||
auto documentId = quint64();
|
||||
|
||||
auto stream = QDataStream(serialized);
|
||||
stream.setVersion(QDataStream::Qt_5_1);
|
||||
stream
|
||||
>> id
|
||||
>> accessHash
|
||||
>> flags
|
||||
>> slug
|
||||
>> settings
|
||||
>> backgroundColor
|
||||
>> intensity
|
||||
>> documentId;
|
||||
if (stream.status() != QDataStream::Ok) {
|
||||
return std::nullopt;
|
||||
} else if (intensity < 0 || intensity > 100) {
|
||||
return std::nullopt;
|
||||
}
|
||||
auto result = WallPaper(id);
|
||||
result._accessHash = accessHash;
|
||||
result._flags = MTPDwallPaper::Flags::from_raw(flags);
|
||||
result._slug = slug;
|
||||
result._settings = MTPDwallPaperSettings::Flags::from_raw(settings);
|
||||
result._backgroundColor = MaybeColorFromSerialized(backgroundColor);
|
||||
result._intensity = intensity;
|
||||
if (!ValidateFlags(result._flags) || !ValidateFlags(result._settings)) {
|
||||
return std::nullopt;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
std::optional<WallPaper> WallPaper::FromLegacySerialized(
|
||||
quint64 id,
|
||||
quint64 accessHash,
|
||||
quint32 flags,
|
||||
QString slug) {
|
||||
auto result = WallPaper(id);
|
||||
result._accessHash = accessHash;
|
||||
result._flags = MTPDwallPaper::Flags::from_raw(flags);
|
||||
result._slug = slug;
|
||||
result._backgroundColor = Window::Theme::GetWallPaperColor(slug);
|
||||
if (!ValidateFlags(result._flags)) {
|
||||
return std::nullopt;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
std::optional<WallPaper> WallPaper::FromLegacyId(qint32 legacyId) {
|
||||
auto result = WallPaper(FromLegacyBackgroundId(legacyId));
|
||||
if (!IsCustomWallPaper(result)) {
|
||||
result._flags = MTPDwallPaper::Flag::f_default;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
std::optional<WallPaper> WallPaper::FromColorSlug(const QString &slug) {
|
||||
if (const auto color = Window::Theme::GetWallPaperColor(slug)) {
|
||||
auto result = CustomWallPaper();
|
||||
result._slug = slug;
|
||||
result._backgroundColor = color;
|
||||
return result;
|
||||
}
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
WallPaper ThemeWallPaper() {
|
||||
return WallPaper(kThemeBackground);
|
||||
}
|
||||
|
||||
bool IsThemeWallPaper(const WallPaper &paper) {
|
||||
return (paper.id() == kThemeBackground);
|
||||
}
|
||||
|
||||
WallPaper CustomWallPaper() {
|
||||
return WallPaper(kCustomBackground);
|
||||
}
|
||||
|
||||
bool IsCustomWallPaper(const WallPaper &paper) {
|
||||
return (paper.id() == kCustomBackground);
|
||||
}
|
||||
|
||||
WallPaper Legacy1DefaultWallPaper() {
|
||||
return WallPaper(kLegacy1DefaultBackground);
|
||||
}
|
||||
|
||||
bool IsLegacy1DefaultWallPaper(const WallPaper &paper) {
|
||||
return (paper.id() == kLegacy1DefaultBackground);
|
||||
}
|
||||
|
||||
WallPaper DefaultWallPaper() {
|
||||
return WallPaper(kDefaultBackground);
|
||||
}
|
||||
|
||||
bool IsDefaultWallPaper(const WallPaper &paper) {
|
||||
return (paper.id() == kDefaultBackground);
|
||||
}
|
||||
|
||||
namespace details {
|
||||
|
||||
WallPaper UninitializedWallPaper() {
|
||||
return WallPaper(kUninitializedBackground);
|
||||
}
|
||||
|
||||
bool IsUninitializedWallPaper(const WallPaper &paper) {
|
||||
return (paper.id() == kUninitializedBackground);
|
||||
}
|
||||
|
||||
WallPaper TestingThemeWallPaper() {
|
||||
return WallPaper(kTestingThemeBackground);
|
||||
}
|
||||
|
||||
bool IsTestingThemeWallPaper(const WallPaper &paper) {
|
||||
return (paper.id() == kTestingThemeBackground);
|
||||
}
|
||||
|
||||
WallPaper TestingDefaultWallPaper() {
|
||||
return WallPaper(kTestingDefaultBackground);
|
||||
}
|
||||
|
||||
bool IsTestingDefaultWallPaper(const WallPaper &paper) {
|
||||
return (paper.id() == kTestingDefaultBackground);
|
||||
}
|
||||
|
||||
WallPaper TestingEditorWallPaper() {
|
||||
return WallPaper(kTestingEditorBackground);
|
||||
}
|
||||
|
||||
bool IsTestingEditorWallPaper(const WallPaper &paper) {
|
||||
return (paper.id() == kTestingEditorBackground);
|
||||
}
|
||||
|
||||
} // namespace details
|
||||
} // namespace Data
|
||||
|
||||
namespace Window {
|
||||
namespace Theme {
|
||||
|
@ -376,9 +697,9 @@ void ChatBackground::setThemeData(QImage &&themeImage, bool themeTile) {
|
|||
}
|
||||
|
||||
void ChatBackground::start() {
|
||||
if (_paper.id == details::kUninitializedBackground) {
|
||||
if (Data::details::IsUninitializedWallPaper(_paper)) {
|
||||
if (!Local::readBackground()) {
|
||||
setImage({ kThemeBackground });
|
||||
setImage(Data::ThemeWallPaper());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -386,12 +707,12 @@ void ChatBackground::start() {
|
|||
void ChatBackground::setImage(
|
||||
const Data::WallPaper &paper,
|
||||
QImage &&image) {
|
||||
const auto needResetAdjustable = (paper.id == kDefaultBackground)
|
||||
&& (id() != kDefaultBackground)
|
||||
const auto needResetAdjustable = Data::IsDefaultWallPaper(paper)
|
||||
&& !Data::IsDefaultWallPaper(_paper)
|
||||
&& !nightMode()
|
||||
&& _themeAbsolutePath.isEmpty();
|
||||
if (paper.id == kThemeBackground && _themeImage.isNull()) {
|
||||
setPaper({ kDefaultBackground });
|
||||
if (Data::IsThemeWallPaper(paper) && _themeImage.isNull()) {
|
||||
setPaper(Data::DefaultWallPaper());
|
||||
} else {
|
||||
setPaper(paper);
|
||||
if (needResetAdjustable) {
|
||||
|
@ -402,19 +723,19 @@ void ChatBackground::setImage(
|
|||
restoreAdjustableColors();
|
||||
}
|
||||
}
|
||||
if (_paper.id == kThemeBackground) {
|
||||
if (Data::IsThemeWallPaper(_paper)) {
|
||||
(nightMode() ? _tileNightValue : _tileDayValue) = _themeTile;
|
||||
setPreparedImage(QImage(_themeImage));
|
||||
} else if (id() == details::kTestingThemeBackground
|
||||
|| id() == details::kTestingDefaultBackground
|
||||
|| id() == details::kTestingEditorBackground) {
|
||||
if (id() == details::kTestingDefaultBackground || image.isNull()) {
|
||||
} else if (Data::details::IsTestingThemeWallPaper(_paper)
|
||||
|| Data::details::IsTestingDefaultWallPaper(_paper)
|
||||
|| Data::details::IsTestingEditorWallPaper(_paper)) {
|
||||
if (Data::details::IsTestingDefaultWallPaper(_paper) || image.isNull()) {
|
||||
image.load(qsl(":/gui/art/bg.jpg"));
|
||||
setPaper({ details::kTestingDefaultBackground });
|
||||
setPaper(Data::details::TestingDefaultWallPaper());
|
||||
}
|
||||
setPreparedImage(prepareBackgroundImage(std::move(image)));
|
||||
} else {
|
||||
if (id() == kInitialBackground) {
|
||||
if (Data::IsLegacy1DefaultWallPaper(_paper)) {
|
||||
image.load(qsl(":/gui/art/bg_initial.jpg"));
|
||||
const auto scale = cScale() * cIntRetinaFactor();
|
||||
if (scale != 100) {
|
||||
|
@ -422,14 +743,15 @@ void ChatBackground::setImage(
|
|||
ConvertScale(image.width(), scale),
|
||||
Qt::SmoothTransformation);
|
||||
}
|
||||
} else if (id() == kDefaultBackground
|
||||
} else if (Data::IsDefaultWallPaper(_paper)
|
||||
|| (!color() && image.isNull())) {
|
||||
setPaper({ kDefaultBackground });
|
||||
setPaper(Data::DefaultWallPaper());
|
||||
image.load(qsl(":/gui/art/bg.jpg"));
|
||||
}
|
||||
Local::writeBackground(
|
||||
_paper,
|
||||
((id() == kDefaultBackground || id() == kInitialBackground)
|
||||
((Data::IsDefaultWallPaper(_paper)
|
||||
|| Data::IsLegacy1DefaultWallPaper(_paper))
|
||||
? QImage()
|
||||
: image));
|
||||
if (const auto fill = color()) {
|
||||
|
@ -490,17 +812,16 @@ void ChatBackground::setPreparedImage(QImage &&image) {
|
|||
|
||||
void ChatBackground::setPaper(const Data::WallPaper &paper) {
|
||||
_paper = paper;
|
||||
_paperColor = GetWallPaperColor(_paper.slug);
|
||||
}
|
||||
|
||||
bool ChatBackground::adjustPaletteRequired() {
|
||||
const auto usingThemeBackground = [&] {
|
||||
return (id() == kThemeBackground)
|
||||
|| (id() == details::kTestingThemeBackground);
|
||||
return Data::IsThemeWallPaper(_paper)
|
||||
|| Data::details::IsTestingThemeWallPaper(_paper);
|
||||
};
|
||||
const auto usingDefaultBackground = [&] {
|
||||
return (id() == kDefaultBackground)
|
||||
|| (id() == details::kTestingDefaultBackground);
|
||||
return Data::IsDefaultWallPaper(_paper)
|
||||
|| Data::details::IsTestingDefaultWallPaper(_paper);
|
||||
};
|
||||
const auto testingPalette = [&] {
|
||||
const auto path = AreTestingTheme()
|
||||
|
@ -551,10 +872,6 @@ void ChatBackground::adjustPaletteUsingColor(QColor color) {
|
|||
}
|
||||
}
|
||||
|
||||
WallPaperId ChatBackground::id() const {
|
||||
return _paper.id;
|
||||
}
|
||||
|
||||
QImage ChatBackground::createCurrentImage() const {
|
||||
if (const auto fill = color()) {
|
||||
auto result = QImage(
|
||||
|
@ -572,8 +889,8 @@ bool ChatBackground::tile() const {
|
|||
}
|
||||
|
||||
bool ChatBackground::tileDay() const {
|
||||
if (id() == details::kTestingThemeBackground ||
|
||||
id() == details::kTestingDefaultBackground) {
|
||||
if (Data::details::IsTestingThemeWallPaper(_paper) ||
|
||||
Data::details::IsTestingDefaultWallPaper(_paper)) {
|
||||
if (!nightMode()) {
|
||||
return _tileForRevert;
|
||||
}
|
||||
|
@ -582,8 +899,8 @@ bool ChatBackground::tileDay() const {
|
|||
}
|
||||
|
||||
bool ChatBackground::tileNight() const {
|
||||
if (id() == details::kTestingThemeBackground ||
|
||||
id() == details::kTestingDefaultBackground) {
|
||||
if (Data::details::IsTestingThemeWallPaper(_paper) ||
|
||||
Data::details::IsTestingDefaultWallPaper(_paper)) {
|
||||
if (nightMode()) {
|
||||
return _tileForRevert;
|
||||
}
|
||||
|
@ -608,8 +925,8 @@ void ChatBackground::setTile(bool tile) {
|
|||
setTileDayValue(tile);
|
||||
}
|
||||
if (this->tile() != old) {
|
||||
if (id() != details::kTestingThemeBackground
|
||||
&& id() != details::kTestingDefaultBackground) {
|
||||
if (!Data::details::IsTestingThemeWallPaper(_paper)
|
||||
&& !Data::details::IsTestingDefaultWallPaper(_paper)) {
|
||||
Local::writeUserSettings();
|
||||
}
|
||||
notify(BackgroundUpdate(BackgroundUpdate::Type::Changed, tile));
|
||||
|
@ -635,19 +952,19 @@ QString ChatBackground::themeAbsolutePath() const {
|
|||
}
|
||||
|
||||
void ChatBackground::reset() {
|
||||
if (id() == details::kTestingThemeBackground
|
||||
|| id() == details::kTestingDefaultBackground) {
|
||||
if (Data::details::IsTestingThemeWallPaper(_paper)
|
||||
|| Data::details::IsTestingDefaultWallPaper(_paper)) {
|
||||
if (_themeImage.isNull()) {
|
||||
_paperForRevert = { kDefaultBackground };
|
||||
_paperForRevert = Data::DefaultWallPaper();
|
||||
_imageForRevert = QImage();
|
||||
_tileForRevert = false;
|
||||
} else {
|
||||
_paperForRevert = { kThemeBackground };
|
||||
_paperForRevert = Data::ThemeWallPaper();
|
||||
_imageForRevert = _themeImage;
|
||||
_tileForRevert = _themeTile;
|
||||
}
|
||||
} else {
|
||||
setImage({ kThemeBackground });
|
||||
setImage(Data::ThemeWallPaper());
|
||||
restoreAdjustableColors();
|
||||
notify(BackgroundUpdate(BackgroundUpdate::Type::TestingTheme, tile()), true);
|
||||
notify(BackgroundUpdate(BackgroundUpdate::Type::ApplyingTheme, tile()), true);
|
||||
|
@ -656,8 +973,8 @@ void ChatBackground::reset() {
|
|||
|
||||
void ChatBackground::saveForRevert() {
|
||||
ensureStarted();
|
||||
if (id() != details::kTestingThemeBackground
|
||||
&& id() != details::kTestingDefaultBackground) {
|
||||
if (!Data::details::IsTestingThemeWallPaper(_paper)
|
||||
&& !Data::details::IsTestingDefaultWallPaper(_paper)) {
|
||||
_paperForRevert = _paper;
|
||||
_imageForRevert = std::move(_pixmap).toImage();
|
||||
_tileForRevert = tile();
|
||||
|
@ -682,19 +999,23 @@ void ChatBackground::setTestingTheme(Instance &&theme) {
|
|||
saveAdjustableColors();
|
||||
|
||||
auto switchToThemeBackground = !theme.background.isNull()
|
||||
|| (id() == kThemeBackground)
|
||||
|| (id() == kDefaultBackground
|
||||
|| Data::IsThemeWallPaper(_paper)
|
||||
|| (Data::IsDefaultWallPaper(_paper)
|
||||
&& !nightMode()
|
||||
&& _themeAbsolutePath.isEmpty());
|
||||
if (AreTestingTheme() && IsPaletteTestingPath(GlobalApplying.pathAbsolute)) {
|
||||
// Grab current background image if it is not already custom
|
||||
if (id() != kCustomBackground) {
|
||||
if (!Data::IsCustomWallPaper(_paper)) {
|
||||
saveForRevert();
|
||||
setImage({ details::kTestingEditorBackground }, std::move(_pixmap).toImage());
|
||||
setImage(
|
||||
Data::details::TestingEditorWallPaper(),
|
||||
std::move(_pixmap).toImage());
|
||||
}
|
||||
} else if (switchToThemeBackground) {
|
||||
saveForRevert();
|
||||
setImage({ details::kTestingThemeBackground }, std::move(theme.background));
|
||||
setImage(
|
||||
Data::details::TestingThemeWallPaper(),
|
||||
std::move(theme.background));
|
||||
setTile(theme.tiled);
|
||||
} else {
|
||||
// Apply current background image so that service bg colors are recounted.
|
||||
|
@ -708,29 +1029,29 @@ void ChatBackground::setTestingDefaultTheme() {
|
|||
saveAdjustableColors();
|
||||
|
||||
saveForRevert();
|
||||
setImage({ details::kTestingDefaultBackground });
|
||||
setImage(Data::details::TestingDefaultWallPaper());
|
||||
setTile(false);
|
||||
notify(BackgroundUpdate(BackgroundUpdate::Type::TestingTheme, tile()), true);
|
||||
}
|
||||
|
||||
void ChatBackground::keepApplied(const QString &path, bool write) {
|
||||
setThemeAbsolutePath(path);
|
||||
if (id() == details::kTestingEditorBackground) {
|
||||
setPaper({ kCustomBackground });
|
||||
if (Data::details::IsTestingEditorWallPaper(_paper)) {
|
||||
setPaper(Data::CustomWallPaper());
|
||||
_themeImage = QImage();
|
||||
_themeTile = false;
|
||||
if (write) {
|
||||
writeNewBackgroundSettings();
|
||||
}
|
||||
} else if (id() == details::kTestingThemeBackground) {
|
||||
setPaper({ kThemeBackground });
|
||||
} else if (Data::details::IsTestingThemeWallPaper(_paper)) {
|
||||
setPaper(Data::ThemeWallPaper());
|
||||
_themeImage = prepareBackgroundImage(_pixmap.toImage());
|
||||
_themeTile = tile();
|
||||
if (write) {
|
||||
writeNewBackgroundSettings();
|
||||
}
|
||||
} else if (id() == details::kTestingDefaultBackground) {
|
||||
setPaper({ kDefaultBackground });
|
||||
} else if (Data::details::IsTestingDefaultWallPaper(_paper)) {
|
||||
setPaper(Data::DefaultWallPaper());
|
||||
_themeImage = QImage();
|
||||
_themeTile = false;
|
||||
if (write) {
|
||||
|
@ -744,16 +1065,16 @@ bool ChatBackground::isNonDefaultThemeOrBackground() {
|
|||
start();
|
||||
return nightMode()
|
||||
? (_themeAbsolutePath != NightThemePath()
|
||||
|| id() != kThemeBackground)
|
||||
|| !Data::IsThemeWallPaper(_paper))
|
||||
: (!_themeAbsolutePath.isEmpty()
|
||||
|| id() != kDefaultBackground);
|
||||
|| !Data::IsDefaultWallPaper(_paper));
|
||||
}
|
||||
|
||||
bool ChatBackground::isNonDefaultBackground() {
|
||||
start();
|
||||
return _themeAbsolutePath.isEmpty()
|
||||
? (id() != kDefaultBackground)
|
||||
: (id() != kThemeBackground);
|
||||
? !Data::IsDefaultWallPaper(_paper)
|
||||
: !Data::IsThemeWallPaper(_paper);
|
||||
}
|
||||
|
||||
void ChatBackground::writeNewBackgroundSettings() {
|
||||
|
@ -762,15 +1083,16 @@ void ChatBackground::writeNewBackgroundSettings() {
|
|||
}
|
||||
Local::writeBackground(
|
||||
_paper,
|
||||
((id() == kThemeBackground || id() == kDefaultBackground)
|
||||
((Data::IsThemeWallPaper(_paper)
|
||||
|| Data::IsDefaultWallPaper(_paper))
|
||||
? QImage()
|
||||
: _pixmap.toImage()));
|
||||
}
|
||||
|
||||
void ChatBackground::revert() {
|
||||
if (id() == details::kTestingThemeBackground
|
||||
|| id() == details::kTestingDefaultBackground
|
||||
|| id() == details::kTestingEditorBackground) {
|
||||
if (Data::details::IsTestingThemeWallPaper(_paper)
|
||||
|| Data::details::IsTestingDefaultWallPaper(_paper)
|
||||
|| Data::details::IsTestingEditorWallPaper(_paper)) {
|
||||
setTile(_tileForRevert);
|
||||
setImage(_paperForRevert, std::move(_imageForRevert));
|
||||
} else {
|
||||
|
@ -843,7 +1165,7 @@ void ChatBackground::toggleNightMode(std::optional<QString> themePath) {
|
|||
}
|
||||
Local::writeSettings();
|
||||
if (!settingDefault && !Local::readBackground()) {
|
||||
setImage({ kThemeBackground });
|
||||
setImage(Data::ThemeWallPaper());
|
||||
}
|
||||
};
|
||||
}
|
||||
|
|
|
@ -11,37 +11,83 @@ class Image;
|
|||
|
||||
namespace Data {
|
||||
|
||||
struct WallPaper {
|
||||
WallPaperId id = WallPaperId();
|
||||
uint64 accessHash = 0;
|
||||
MTPDwallPaper::Flags flags;
|
||||
QString slug;
|
||||
Image *thumb = nullptr;
|
||||
DocumentData *document = nullptr;
|
||||
struct FileOrigin;
|
||||
|
||||
class WallPaper {
|
||||
public:
|
||||
explicit WallPaper(WallPaperId id);
|
||||
|
||||
void setLocalImageAsThumbnail(not_null<Image*> image);
|
||||
|
||||
[[nodiscard]] WallPaperId id() const;
|
||||
[[nodiscard]] std::optional<QColor> backgroundColor() const;
|
||||
[[nodiscard]] DocumentData *document() const;
|
||||
[[nodiscard]] Image *thumbnail() const;
|
||||
[[nodiscard]] bool hasShareUrl() const;
|
||||
[[nodiscard]] QString shareUrl() const;
|
||||
|
||||
void loadDocument() const;
|
||||
void loadThumbnail() const;
|
||||
[[nodiscard]] FileOrigin fileOrigin() const;
|
||||
|
||||
[[nodiscard]] static std::optional<WallPaper> Create(
|
||||
const MTPWallPaper &data);
|
||||
[[nodiscard]] static std::optional<WallPaper> Create(
|
||||
const MTPDwallPaper &data);
|
||||
|
||||
[[nodiscard]] QByteArray serialize() const;
|
||||
[[nodiscard]] static std::optional<WallPaper> FromSerialized(
|
||||
const QByteArray &serialized);
|
||||
[[nodiscard]] static std::optional<WallPaper> FromLegacySerialized(
|
||||
quint64 id,
|
||||
quint64 accessHash,
|
||||
quint32 flags,
|
||||
QString slug);
|
||||
[[nodiscard]] static std::optional<WallPaper> FromLegacyId(
|
||||
qint32 legacyId);
|
||||
[[nodiscard]] static std::optional<WallPaper> FromColorSlug(
|
||||
const QString &slug);
|
||||
|
||||
private:
|
||||
WallPaperId _id = WallPaperId();
|
||||
uint64 _accessHash = 0;
|
||||
MTPDwallPaper::Flags _flags;
|
||||
QString _slug;
|
||||
|
||||
MTPDwallPaperSettings::Flags _settings;
|
||||
std::optional<QColor> _backgroundColor;
|
||||
int _intensity = 40;
|
||||
|
||||
DocumentData *_document = nullptr;
|
||||
Image *_thumbnail = nullptr;
|
||||
|
||||
};
|
||||
|
||||
[[nodiscard]] WallPaper ThemeWallPaper();
|
||||
[[nodiscard]] bool IsThemeWallPaper(const WallPaper &paper);
|
||||
[[nodiscard]] WallPaper CustomWallPaper();
|
||||
[[nodiscard]] bool IsCustomWallPaper(const WallPaper &paper);
|
||||
[[nodiscard]] WallPaper Legacy1DefaultWallPaper();
|
||||
[[nodiscard]] bool IsLegacy1DefaultWallPaper(const WallPaper &paper);
|
||||
[[nodiscard]] WallPaper DefaultWallPaper();
|
||||
[[nodiscard]] bool IsDefaultWallPaper(const WallPaper &paper);
|
||||
|
||||
namespace details {
|
||||
|
||||
[[nodiscard]] WallPaper UninitializedWallPaper();
|
||||
[[nodiscard]] bool IsUninitializedWallPaper(const WallPaper &paper);
|
||||
[[nodiscard]] WallPaper TestingThemeWallPaper();
|
||||
[[nodiscard]] bool IsTestingThemeWallPaper(const WallPaper &paper);
|
||||
[[nodiscard]] WallPaper TestingDefaultWallPaper();
|
||||
[[nodiscard]] bool IsTestingDefaultWallPaper(const WallPaper &paper);
|
||||
[[nodiscard]] WallPaper TestingEditorWallPaper();
|
||||
[[nodiscard]] bool IsTestingEditorWallPaper(const WallPaper &paper);
|
||||
|
||||
} // namespace details
|
||||
} // namespace Data
|
||||
|
||||
namespace Window {
|
||||
namespace Theme {
|
||||
namespace details {
|
||||
|
||||
constexpr auto FromLegacyBackgroundId(int32 legacyId) -> WallPaperId {
|
||||
return uint64(0xFFFFFFFF00000000ULL) | uint64(uint32(legacyId));
|
||||
}
|
||||
|
||||
constexpr auto kUninitializedBackground = FromLegacyBackgroundId(-999);
|
||||
constexpr auto kTestingThemeBackground = FromLegacyBackgroundId(-666);
|
||||
constexpr auto kTestingDefaultBackground = FromLegacyBackgroundId(-665);
|
||||
constexpr auto kTestingEditorBackground = FromLegacyBackgroundId(-664);
|
||||
constexpr auto kLegacyBackgroundId = int32(-111);
|
||||
|
||||
} // namespace details
|
||||
|
||||
constexpr auto kThemeBackground = details::FromLegacyBackgroundId(-2);
|
||||
constexpr auto kCustomBackground = details::FromLegacyBackgroundId(-1);
|
||||
constexpr auto kInitialBackground = details::FromLegacyBackgroundId(0);
|
||||
constexpr auto kDefaultBackground = details::FromLegacyBackgroundId(105);
|
||||
|
||||
constexpr auto kMinimumTiledSize = 512;
|
||||
|
||||
|
@ -135,7 +181,9 @@ public:
|
|||
void setTestingDefaultTheme();
|
||||
void revert();
|
||||
|
||||
[[nodiscard]] WallPaperId id() const;
|
||||
[[nodiscard]] WallPaperId id() const {
|
||||
return _paper.id();
|
||||
}
|
||||
[[nodiscard]] const QPixmap &pixmap() const {
|
||||
return _pixmap;
|
||||
}
|
||||
|
@ -143,7 +191,7 @@ public:
|
|||
return _pixmapForTiled;
|
||||
}
|
||||
[[nodiscard]] std::optional<QColor> color() const {
|
||||
return _paperColor;
|
||||
return _paper.backgroundColor();
|
||||
}
|
||||
[[nodiscard]] QImage createCurrentImage() const;
|
||||
[[nodiscard]] bool tile() const;
|
||||
|
@ -183,7 +231,7 @@ private:
|
|||
friend void KeepApplied();
|
||||
friend bool IsNonDefaultBackground();
|
||||
|
||||
Data::WallPaper _paper = { details::kUninitializedBackground };
|
||||
Data::WallPaper _paper = Data::details::UninitializedWallPaper();
|
||||
std::optional<QColor> _paperColor;
|
||||
QPixmap _pixmap;
|
||||
QPixmap _pixmapForTiled;
|
||||
|
@ -195,7 +243,8 @@ private:
|
|||
QImage _themeImage;
|
||||
bool _themeTile = false;
|
||||
|
||||
Data::WallPaper _paperForRevert = { details::kUninitializedBackground };
|
||||
Data::WallPaper _paperForRevert
|
||||
= Data::details::UninitializedWallPaper();
|
||||
QImage _imageForRevert;
|
||||
bool _tileForRevert = false;
|
||||
|
||||
|
|
|
@ -395,7 +395,8 @@ void Generator::paintHistoryBackground() {
|
|||
auto background = _theme.background;
|
||||
auto tiled = _theme.tiled;
|
||||
if (background.isNull()) {
|
||||
if (_current.backgroundId == Window::Theme::kThemeBackground) {
|
||||
const auto fakePaper = Data::WallPaper(_current.backgroundId);
|
||||
if (Data::IsThemeWallPaper(fakePaper)) {
|
||||
background.load(qsl(":/gui/art/bg.jpg"));
|
||||
tiled = false;
|
||||
} else {
|
||||
|
|
Loading…
Add table
Reference in a new issue