mirror of https://github.com/procxx/kepka.git
Add a box for new theme creating.
This commit is contained in:
parent
1e3b72ab74
commit
4b045a602c
|
@ -338,6 +338,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
"lng_settings_bg_from_gallery" = "Choose from gallery";
|
"lng_settings_bg_from_gallery" = "Choose from gallery";
|
||||||
"lng_settings_bg_from_file" = "Choose from file";
|
"lng_settings_bg_from_file" = "Choose from file";
|
||||||
"lng_settings_bg_edit_theme" = "Launch theme editor";
|
"lng_settings_bg_edit_theme" = "Launch theme editor";
|
||||||
|
"lng_settings_bg_create_theme" = "Create new theme";
|
||||||
"lng_settings_bg_tile" = "Tile background";
|
"lng_settings_bg_tile" = "Tile background";
|
||||||
"lng_settings_adaptive_wide" = "Adaptive layout for wide screens";
|
"lng_settings_adaptive_wide" = "Adaptive layout for wide screens";
|
||||||
|
|
||||||
|
@ -1603,6 +1604,13 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
"lng_theme_editor_title" = "Edit color palette";
|
"lng_theme_editor_title" = "Edit color palette";
|
||||||
"lng_theme_editor_export_button" = "Export theme";
|
"lng_theme_editor_export_button" = "Export theme";
|
||||||
|
|
||||||
|
"lng_theme_editor_create_title" = "Create theme";
|
||||||
|
"lng_theme_editor_name" = "Theme name";
|
||||||
|
"lng_theme_editor_create_description" = "New theme will be based on your currently selected colors and wallpaper. Alternatively, you can import existing theme or color palette from file.";
|
||||||
|
"lng_theme_editor_import_existing" = "Import existing theme";
|
||||||
|
"lng_theme_editor_save_title" = "Save theme";
|
||||||
|
"lng_theme_editor_link_about" = "Your theme will be updated for all users each time you change it. Anyone can install it using this link.\n\nTheme links must be longer than 5 characters and use a-z, 0-9 and underscores.";
|
||||||
|
|
||||||
"lng_payments_not_supported" = "Sorry, Telegram Desktop doesn't support payments yet. Please use one of our mobile apps to do this.";
|
"lng_payments_not_supported" = "Sorry, Telegram Desktop doesn't support payments yet. Please use one of our mobile apps to do this.";
|
||||||
"lng_payments_receipt_label" = "Receipt";
|
"lng_payments_receipt_label" = "Receipt";
|
||||||
"lng_payments_receipt_label_test" = "Test receipt";
|
"lng_payments_receipt_label_test" = "Test receipt";
|
||||||
|
|
|
@ -0,0 +1,52 @@
|
||||||
|
/*
|
||||||
|
This file is part of Telegram Desktop,
|
||||||
|
the official desktop application for the Telegram messaging service.
|
||||||
|
|
||||||
|
For license and copyright information please follow this link:
|
||||||
|
https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
|
*/
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "base/optional.h"
|
||||||
|
#include "base/variant.h"
|
||||||
|
#include <rpl/map.h>
|
||||||
|
#include <rpl/producer.h>
|
||||||
|
|
||||||
|
namespace rpl {
|
||||||
|
|
||||||
|
template <
|
||||||
|
typename Value,
|
||||||
|
typename Error,
|
||||||
|
typename GeneratorTest,
|
||||||
|
typename GeneratorA,
|
||||||
|
typename GeneratorB>
|
||||||
|
inline auto conditional(
|
||||||
|
rpl::producer<bool, Error, GeneratorTest> &&test,
|
||||||
|
rpl::producer<Value, Error, GeneratorA> &&a,
|
||||||
|
rpl::producer<Value, Error, GeneratorB> &&b) {
|
||||||
|
return rpl::combine(
|
||||||
|
std::move(test),
|
||||||
|
std::move(a),
|
||||||
|
std::move(b)
|
||||||
|
) | rpl::map([](bool test, Value &&a, Value &&b) {
|
||||||
|
return test ? std::move(a) : std::move(b);
|
||||||
|
});
|
||||||
|
//struct conditional_state {
|
||||||
|
// std::optional<Value> a;
|
||||||
|
// std::optional<Value> b;
|
||||||
|
// char state = -1;
|
||||||
|
// int working = 3;
|
||||||
|
//};
|
||||||
|
//return rpl::make_producer<Value, Error>([
|
||||||
|
// test = std::move(test),
|
||||||
|
// a = std::move(a),
|
||||||
|
// b = std::move(b)
|
||||||
|
//](const auto &consumer) mutable {
|
||||||
|
// auto result = lifetime();
|
||||||
|
// const auto state = result.make_state<conditional_state>();
|
||||||
|
// result.add(std::move(test).start())
|
||||||
|
// return result;
|
||||||
|
//});
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace rpl
|
|
@ -32,6 +32,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#include <rpl/flatten_latest.h>
|
#include <rpl/flatten_latest.h>
|
||||||
#include <rpl/combine.h>
|
#include <rpl/combine.h>
|
||||||
#include <rpl/combine_previous.h>
|
#include <rpl/combine_previous.h>
|
||||||
|
#include <rpl/conditional.h>
|
||||||
#include <rpl/variable.h>
|
#include <rpl/variable.h>
|
||||||
|
|
||||||
#include <rpl/before_next.h>
|
#include <rpl/before_next.h>
|
||||||
|
|
|
@ -12,6 +12,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#include "boxes/auto_download_box.h"
|
#include "boxes/auto_download_box.h"
|
||||||
#include "boxes/stickers_box.h"
|
#include "boxes/stickers_box.h"
|
||||||
#include "boxes/background_box.h"
|
#include "boxes/background_box.h"
|
||||||
|
#include "boxes/generic_box.h"
|
||||||
#include "boxes/background_preview_box.h"
|
#include "boxes/background_preview_box.h"
|
||||||
#include "boxes/download_path_box.h"
|
#include "boxes/download_path_box.h"
|
||||||
#include "boxes/local_storage_box.h"
|
#include "boxes/local_storage_box.h"
|
||||||
|
@ -29,6 +30,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#include "window/themes/window_theme_editor.h"
|
#include "window/themes/window_theme_editor.h"
|
||||||
#include "window/themes/window_theme.h"
|
#include "window/themes/window_theme.h"
|
||||||
#include "window/themes/window_themes_embedded.h"
|
#include "window/themes/window_themes_embedded.h"
|
||||||
|
#include "window/themes/window_theme_create_box.h"
|
||||||
#include "window/window_session_controller.h"
|
#include "window/window_session_controller.h"
|
||||||
#include "info/profile/info_profile_button.h"
|
#include "info/profile/info_profile_button.h"
|
||||||
#include "storage/localstorage.h"
|
#include "storage/localstorage.h"
|
||||||
|
@ -727,7 +729,6 @@ void ChooseFromFile(
|
||||||
tr::lng_choose_image(tr::now),
|
tr::lng_choose_image(tr::now),
|
||||||
filters.join(qsl(";;")),
|
filters.join(qsl(";;")),
|
||||||
crl::guard(parent, callback));
|
crl::guard(parent, callback));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
QString DownloadPathText() {
|
QString DownloadPathText() {
|
||||||
|
@ -1242,7 +1243,9 @@ void SetupDefaultThemes(not_null<Ui::VerticalLayout*> container) {
|
||||||
AddSkip(container);
|
AddSkip(container);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SetupThemeOptions(not_null<Ui::VerticalLayout*> container) {
|
void SetupThemeOptions(
|
||||||
|
not_null<Window::SessionController*> controller,
|
||||||
|
not_null<Ui::VerticalLayout*> container) {
|
||||||
AddSkip(container, st::settingsPrivacySkip);
|
AddSkip(container, st::settingsPrivacySkip);
|
||||||
|
|
||||||
AddSubsectionTitle(container, tr::lng_settings_themes());
|
AddSubsectionTitle(container, tr::lng_settings_themes());
|
||||||
|
@ -1250,17 +1253,19 @@ void SetupThemeOptions(not_null<Ui::VerticalLayout*> container) {
|
||||||
AddSkip(container, st::settingsThemesTopSkip);
|
AddSkip(container, st::settingsThemesTopSkip);
|
||||||
SetupDefaultThemes(container);
|
SetupDefaultThemes(container);
|
||||||
AddSkip(container, st::settingsThemesBottomSkip);
|
AddSkip(container, st::settingsThemesBottomSkip);
|
||||||
|
auto canEdit = rpl::single(false);
|
||||||
AddButton(
|
AddButton(
|
||||||
container,
|
container,
|
||||||
|
rpl::conditional(
|
||||||
|
std::move(canEdit),
|
||||||
tr::lng_settings_bg_edit_theme(),
|
tr::lng_settings_bg_edit_theme(),
|
||||||
|
tr::lng_settings_bg_create_theme()),
|
||||||
st::settingsChatButton,
|
st::settingsChatButton,
|
||||||
&st::settingsIconThemes,
|
&st::settingsIconThemes,
|
||||||
st::settingsChatIconLeft
|
st::settingsChatIconLeft
|
||||||
)->addClickHandler(App::LambdaDelayed(
|
)->addClickHandler([=] {
|
||||||
st::settingsChatButton.ripple.hideDuration,
|
Ui::show(Box(Window::Theme::CreateBox, &controller->session()));
|
||||||
container,
|
});
|
||||||
[] { Window::Theme::Editor::Start(); }));
|
|
||||||
|
|
||||||
AddSkip(container);
|
AddSkip(container);
|
||||||
}
|
}
|
||||||
|
@ -1385,7 +1390,7 @@ Chat::Chat(QWidget *parent, not_null<Window::SessionController*> controller)
|
||||||
void Chat::setupContent(not_null<Window::SessionController*> controller) {
|
void Chat::setupContent(not_null<Window::SessionController*> controller) {
|
||||||
const auto content = Ui::CreateChild<Ui::VerticalLayout>(this);
|
const auto content = Ui::CreateChild<Ui::VerticalLayout>(this);
|
||||||
|
|
||||||
SetupThemeOptions(content);
|
SetupThemeOptions(controller, content);
|
||||||
SetupChatBackground(controller, content);
|
SetupChatBackground(controller, content);
|
||||||
SetupStickersEmoji(controller, content);
|
SetupStickersEmoji(controller, content);
|
||||||
SetupMessages(controller, content);
|
SetupMessages(controller, content);
|
||||||
|
|
|
@ -94,9 +94,6 @@ auto GenerateCodes() {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
codes.emplace(qsl("edittheme"), [](::Main::Session *session) {
|
|
||||||
Window::Theme::Editor::Start();
|
|
||||||
});
|
|
||||||
codes.emplace(qsl("videoplayer"), [](::Main::Session *session) {
|
codes.emplace(qsl("videoplayer"), [](::Main::Session *session) {
|
||||||
auto text = cUseExternalVideoPlayer() ? qsl("Use internal video player?") : qsl("Use external video player?");
|
auto text = cUseExternalVideoPlayer() ? qsl("Use internal video player?") : qsl("Use external video player?");
|
||||||
Ui::show(Box<ConfirmBox>(text, [] {
|
Ui::show(Box<ConfirmBox>(text, [] {
|
||||||
|
|
|
@ -51,6 +51,14 @@ inline bool AreTestingTheme() {
|
||||||
return !GlobalApplying.paletteForRevert.isEmpty();
|
return !GlobalApplying.paletteForRevert.isEmpty();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
[[nodiscard]] bool IsEditingTheme(const QString &path) {
|
||||||
|
static const auto kEditingPath = QFileInfo(
|
||||||
|
EditingPalettePath()
|
||||||
|
).absoluteFilePath();
|
||||||
|
return !path.compare(kEditingPath, Qt::CaseInsensitive)
|
||||||
|
&& QFileInfo(path).exists();
|
||||||
|
}
|
||||||
|
|
||||||
bool CalculateIsMonoColorImage(const QImage &image) {
|
bool CalculateIsMonoColorImage(const QImage &image) {
|
||||||
if (!image.isNull()) {
|
if (!image.isNull()) {
|
||||||
const auto bits = reinterpret_cast<const uint32*>(image.constBits());
|
const auto bits = reinterpret_cast<const uint32*>(image.constBits());
|
||||||
|
@ -441,7 +449,7 @@ void ChatBackground::checkUploadWallPaper() {
|
||||||
}
|
}
|
||||||
if (!Data::IsCustomWallPaper(_paper)
|
if (!Data::IsCustomWallPaper(_paper)
|
||||||
|| _original.isNull()
|
|| _original.isNull()
|
||||||
|| testingPalette()) {
|
|| isEditingTheme()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -631,7 +639,7 @@ bool ChatBackground::adjustPaletteRequired() {
|
||||||
|| Data::details::IsTestingDefaultWallPaper(_paper);
|
|| Data::details::IsTestingDefaultWallPaper(_paper);
|
||||||
};
|
};
|
||||||
|
|
||||||
if (testingPalette()) {
|
if (isEditingTheme()) {
|
||||||
return false;
|
return false;
|
||||||
} else if (isNonDefaultThemeOrBackground() || nightMode()) {
|
} else if (isNonDefaultThemeOrBackground() || nightMode()) {
|
||||||
return !usingThemeBackground();
|
return !usingThemeBackground();
|
||||||
|
@ -639,11 +647,11 @@ bool ChatBackground::adjustPaletteRequired() {
|
||||||
return !usingDefaultBackground();
|
return !usingDefaultBackground();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ChatBackground::testingPalette() const {
|
bool ChatBackground::isEditingTheme() const {
|
||||||
const auto path = AreTestingTheme()
|
const auto path = AreTestingTheme()
|
||||||
? GlobalApplying.pathAbsolute
|
? GlobalApplying.pathAbsolute
|
||||||
: _themeAbsolutePath;
|
: _themeAbsolutePath;
|
||||||
return IsPaletteTestingPath(path);
|
return IsEditingTheme(path);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ChatBackground::adjustPaletteUsingBackground(const QImage &image) {
|
void ChatBackground::adjustPaletteUsingBackground(const QImage &image) {
|
||||||
|
@ -801,8 +809,7 @@ void ChatBackground::setTestingTheme(Instance &&theme) {
|
||||||
|| (Data::IsDefaultWallPaper(_paper)
|
|| (Data::IsDefaultWallPaper(_paper)
|
||||||
&& !nightMode()
|
&& !nightMode()
|
||||||
&& _themeAbsolutePath.isEmpty());
|
&& _themeAbsolutePath.isEmpty());
|
||||||
if (AreTestingTheme()
|
if (AreTestingTheme() && isEditingTheme()) {
|
||||||
&& IsPaletteTestingPath(GlobalApplying.pathAbsolute)) {
|
|
||||||
// Grab current background image if it is not already custom
|
// Grab current background image if it is not already custom
|
||||||
// Use prepared pixmap, not original image, because we're
|
// Use prepared pixmap, not original image, because we're
|
||||||
// for sure switching to a non-pattern wall-paper (testing editor).
|
// for sure switching to a non-pattern wall-paper (testing editor).
|
||||||
|
@ -1137,11 +1144,8 @@ bool LoadFromFile(
|
||||||
return loadTheme(*outContent, out->cached, colorizer, out);
|
return loadTheme(*outContent, out->cached, colorizer, out);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool IsPaletteTestingPath(const QString &path) {
|
QString EditingPalettePath() {
|
||||||
if (path.endsWith(qstr(".tdesktop-palette"), Qt::CaseInsensitive)) {
|
return cWorkingDir() + "tdata/editing-theme.tdesktop-palette";
|
||||||
return QFileInfo(path).exists();
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
QColor CountAverageColor(const QImage &image) {
|
QColor CountAverageColor(const QImage &image) {
|
||||||
|
|
|
@ -62,11 +62,12 @@ void ToggleNightMode(const QString &themePath);
|
||||||
[[nodiscard]] bool IsNonDefaultBackground();
|
[[nodiscard]] bool IsNonDefaultBackground();
|
||||||
void Revert();
|
void Revert();
|
||||||
|
|
||||||
|
[[nodiscard]] QString EditingPalettePath();
|
||||||
|
|
||||||
bool LoadFromFile(
|
bool LoadFromFile(
|
||||||
const QString &file,
|
const QString &file,
|
||||||
Instance *out,
|
Instance *out,
|
||||||
QByteArray *outContent);
|
QByteArray *outContent);
|
||||||
bool IsPaletteTestingPath(const QString &path);
|
|
||||||
QColor CountAverageColor(const QImage &image);
|
QColor CountAverageColor(const QImage &image);
|
||||||
QColor AdjustedColor(QColor original, QColor background);
|
QColor AdjustedColor(QColor original, QColor background);
|
||||||
QImage ProcessBackgroundImage(QImage image);
|
QImage ProcessBackgroundImage(QImage image);
|
||||||
|
@ -83,7 +84,7 @@ struct BackgroundUpdate {
|
||||||
|
|
||||||
BackgroundUpdate(Type type, bool tiled) : type(type), tiled(tiled) {
|
BackgroundUpdate(Type type, bool tiled) : type(type), tiled(tiled) {
|
||||||
}
|
}
|
||||||
bool paletteChanged() const {
|
[[nodiscard]] bool paletteChanged() const {
|
||||||
return (type == Type::TestingTheme || type == Type::RevertingTheme);
|
return (type == Type::TestingTheme || type == Type::RevertingTheme);
|
||||||
}
|
}
|
||||||
Type type;
|
Type type;
|
||||||
|
@ -107,6 +108,7 @@ public:
|
||||||
void setTileNightValue(bool tile);
|
void setTileNightValue(bool tile);
|
||||||
void setThemeAbsolutePath(const QString &path);
|
void setThemeAbsolutePath(const QString &path);
|
||||||
[[nodiscard]] QString themeAbsolutePath() const;
|
[[nodiscard]] QString themeAbsolutePath() const;
|
||||||
|
[[nodiscard]] bool isEditingTheme() const;
|
||||||
void reset();
|
void reset();
|
||||||
|
|
||||||
void setTestingTheme(Instance &&theme);
|
void setTestingTheme(Instance &&theme);
|
||||||
|
@ -160,7 +162,6 @@ private:
|
||||||
[[nodiscard]] bool isNonDefaultThemeOrBackground();
|
[[nodiscard]] bool isNonDefaultThemeOrBackground();
|
||||||
[[nodiscard]] bool isNonDefaultBackground();
|
[[nodiscard]] bool isNonDefaultBackground();
|
||||||
void checkUploadWallPaper();
|
void checkUploadWallPaper();
|
||||||
[[nodiscard]] bool testingPalette() const;
|
|
||||||
|
|
||||||
friend bool IsNightMode();
|
friend bool IsNightMode();
|
||||||
friend void SetNightModeValue(bool nightMode);
|
friend void SetNightModeValue(bool nightMode);
|
||||||
|
|
|
@ -0,0 +1,148 @@
|
||||||
|
/*
|
||||||
|
This file is part of Telegram Desktop,
|
||||||
|
the official desktop application for the Telegram messaging service.
|
||||||
|
|
||||||
|
For license and copyright information please follow this link:
|
||||||
|
https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
|
*/
|
||||||
|
#include "window/themes/window_theme_create_box.h"
|
||||||
|
|
||||||
|
#include "window/themes/window_theme.h"
|
||||||
|
#include "window/themes/window_theme_editor.h"
|
||||||
|
#include "boxes/generic_box.h"
|
||||||
|
#include "boxes/confirm_box.h"
|
||||||
|
#include "ui/text/text_utilities.h"
|
||||||
|
#include "ui/widgets/input_fields.h"
|
||||||
|
#include "ui/widgets/labels.h"
|
||||||
|
#include "info/profile/info_profile_button.h"
|
||||||
|
#include "main/main_session.h"
|
||||||
|
#include "core/file_utilities.h"
|
||||||
|
#include "lang/lang_keys.h"
|
||||||
|
#include "storage/localstorage.h"
|
||||||
|
#include "mainwindow.h"
|
||||||
|
#include "styles/style_widgets.h"
|
||||||
|
#include "styles/style_window.h"
|
||||||
|
#include "styles/style_boxes.h"
|
||||||
|
|
||||||
|
namespace Window {
|
||||||
|
namespace Theme {
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
void ImportFromFile(
|
||||||
|
not_null<Main::Session*> session,
|
||||||
|
not_null<QWidget*> parent) {
|
||||||
|
const auto &imgExtensions = cImgExtensions();
|
||||||
|
auto filters = QStringList(
|
||||||
|
qsl("Theme files (*.tdesktop-theme *.tdesktop-palette)"));
|
||||||
|
filters.push_back(FileDialog::AllFilesFilter());
|
||||||
|
const auto callback = crl::guard(session, [=](
|
||||||
|
const FileDialog::OpenResult &result) {
|
||||||
|
if (result.paths.isEmpty()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
Window::Theme::Apply(result.paths.front());
|
||||||
|
});
|
||||||
|
FileDialog::GetOpenPath(
|
||||||
|
parent.get(),
|
||||||
|
tr::lng_choose_image(tr::now),
|
||||||
|
filters.join(qsl(";;")),
|
||||||
|
crl::guard(parent, callback));
|
||||||
|
}
|
||||||
|
|
||||||
|
QString BytesToUTF8(QLatin1String string) {
|
||||||
|
return QString::fromUtf8(string.data(), string.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
void WriteDefaultPalette(const QString &path) {
|
||||||
|
QFile f(path);
|
||||||
|
if (!f.open(QIODevice::WriteOnly)) {
|
||||||
|
LOG(("Theme Error: could not open '%1' for writing.").arg(path));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
QTextStream stream(&f);
|
||||||
|
stream.setCodec("UTF-8");
|
||||||
|
|
||||||
|
auto rows = style::main_palette::data();
|
||||||
|
for (const auto &row : std::as_const(rows)) {
|
||||||
|
stream
|
||||||
|
<< BytesToUTF8(row.name)
|
||||||
|
<< ": "
|
||||||
|
<< BytesToUTF8(row.value)
|
||||||
|
<< "; // "
|
||||||
|
<< BytesToUTF8(
|
||||||
|
row.description
|
||||||
|
).replace(
|
||||||
|
'\n',
|
||||||
|
' '
|
||||||
|
).replace(
|
||||||
|
'\r',
|
||||||
|
' ')
|
||||||
|
<< "\n";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void StartEditor(
|
||||||
|
not_null<Main::Session*> session,
|
||||||
|
const QString &title) {
|
||||||
|
const auto path = EditingPalettePath();
|
||||||
|
if (!Local::copyThemeColorsToPalette(path)) {
|
||||||
|
WriteDefaultPalette(path);
|
||||||
|
}
|
||||||
|
if (!Apply(path)) {
|
||||||
|
Ui::show(Box<InformBox>(tr::lng_theme_editor_error(tr::now)));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
KeepApplied();
|
||||||
|
if (const auto window = App::wnd()) {
|
||||||
|
window->showRightColumn(Box<Editor>());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
void CreateBox(not_null<GenericBox*> box, not_null<Main::Session*> session) {
|
||||||
|
box->setTitle(tr::lng_theme_editor_create_title(Ui::Text::WithEntities));
|
||||||
|
|
||||||
|
const auto name = box->addRow(object_ptr<Ui::InputField>(
|
||||||
|
box,
|
||||||
|
st::defaultInputField,
|
||||||
|
tr::lng_theme_editor_name()));
|
||||||
|
|
||||||
|
box->addRow(
|
||||||
|
object_ptr<Ui::FlatLabel>(
|
||||||
|
box,
|
||||||
|
tr::lng_theme_editor_create_description(),
|
||||||
|
st::boxDividerLabel),
|
||||||
|
style::margins(
|
||||||
|
st::boxRowPadding.left(),
|
||||||
|
st::boxRowPadding.left(),
|
||||||
|
st::boxRowPadding.right(),
|
||||||
|
st::boxRowPadding.right()));
|
||||||
|
|
||||||
|
box->addRow(
|
||||||
|
object_ptr<Info::Profile::Button>(
|
||||||
|
box,
|
||||||
|
tr::lng_theme_editor_import_existing() | Ui::Text::ToUpper(),
|
||||||
|
st::createThemeImportButton),
|
||||||
|
style::margins()
|
||||||
|
)->addClickHandler([=] {
|
||||||
|
ImportFromFile(session, box);
|
||||||
|
});
|
||||||
|
|
||||||
|
box->setFocusCallback([=] { name->setFocusFast(); });
|
||||||
|
|
||||||
|
box->addButton(tr::lng_box_done(), [=] {
|
||||||
|
const auto title = name->getLastText().trimmed();
|
||||||
|
if (title.isEmpty()) {
|
||||||
|
name->showError();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
box->closeBox();
|
||||||
|
StartEditor(session, title);
|
||||||
|
});
|
||||||
|
box->addButton(tr::lng_cancel(), [=] { box->closeBox(); });
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace Theme
|
||||||
|
} // namespace Window
|
|
@ -0,0 +1,22 @@
|
||||||
|
/*
|
||||||
|
This file is part of Telegram Desktop,
|
||||||
|
the official desktop application for the Telegram messaging service.
|
||||||
|
|
||||||
|
For license and copyright information please follow this link:
|
||||||
|
https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
|
*/
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
class GenericBox;
|
||||||
|
|
||||||
|
namespace Main {
|
||||||
|
class Session;
|
||||||
|
} // namespace Main
|
||||||
|
|
||||||
|
namespace Window {
|
||||||
|
namespace Theme {
|
||||||
|
|
||||||
|
void CreateBox(not_null<GenericBox*> box, not_null<Main::Session*> session);
|
||||||
|
|
||||||
|
} // namespace Theme
|
||||||
|
} // namespace Window
|
|
@ -637,22 +637,6 @@ void Editor::Inner::applyEditing(const QString &name, const QString ©Of, QCo
|
||||||
_paletteContent = newContent;
|
_paletteContent = newContent;
|
||||||
}
|
}
|
||||||
|
|
||||||
void writeDefaultPalette(const QString &path) {
|
|
||||||
QFile f(path);
|
|
||||||
if (!f.open(QIODevice::WriteOnly)) {
|
|
||||||
LOG(("Theme Error: could not open '%1' for writing.").arg(path));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
QTextStream stream(&f);
|
|
||||||
stream.setCodec("UTF-8");
|
|
||||||
|
|
||||||
auto rows = style::main_palette::data();
|
|
||||||
for_const (auto &row, rows) {
|
|
||||||
stream << bytesToUtf8(row.name) << ": " << bytesToUtf8(row.value) << "; // " << bytesToUtf8(row.description).replace('\n', ' ').replace('\r', ' ') << "\n";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ThemeExportBox::ThemeExportBox(QWidget*, const QByteArray &paletteContent, const QImage &background, const QByteArray &backgroundContent, bool tileBackground) : BoxContent()
|
ThemeExportBox::ThemeExportBox(QWidget*, const QByteArray &paletteContent, const QImage &background, const QByteArray &backgroundContent, bool tileBackground) : BoxContent()
|
||||||
, _paletteContent(paletteContent)
|
, _paletteContent(paletteContent)
|
||||||
, _background(background)
|
, _background(background)
|
||||||
|
@ -785,13 +769,15 @@ void ThemeExportBox::exportTheme() {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
Editor::Editor(QWidget*, const QString &path)
|
Editor::Editor(QWidget*)
|
||||||
: _scroll(this, st::themesScroll)
|
: _scroll(this, st::themesScroll)
|
||||||
, _close(this, st::contactsMultiSelect.fieldCancel)
|
, _close(this, st::contactsMultiSelect.fieldCancel)
|
||||||
, _select(this, st::contactsMultiSelect, tr::lng_country_ph())
|
, _select(this, st::contactsMultiSelect, tr::lng_country_ph())
|
||||||
, _leftShadow(this)
|
, _leftShadow(this)
|
||||||
, _topShadow(this)
|
, _topShadow(this)
|
||||||
, _export(this, tr::lng_theme_editor_export_button(tr::now).toUpper(), st::dialogsUpdateButton) {
|
, _export(this, tr::lng_theme_editor_export_button(tr::now).toUpper(), st::dialogsUpdateButton) {
|
||||||
|
const auto path = EditingPalettePath();
|
||||||
|
|
||||||
_inner = _scroll->setOwnedWidget(object_ptr<Inner>(this, path));
|
_inner = _scroll->setOwnedWidget(object_ptr<Inner>(this, path));
|
||||||
|
|
||||||
_export->setClickedCallback(_inner->exportCallback());
|
_export->setClickedCallback(_inner->exportCallback());
|
||||||
|
@ -880,32 +866,32 @@ void Editor::paintEvent(QPaintEvent *e) {
|
||||||
p.drawTextLeft(st::themeEditorMargin.left(), st::themeEditorMargin.top(), width(), tr::lng_theme_editor_title(tr::now));
|
p.drawTextLeft(st::themeEditorMargin.left(), st::themeEditorMargin.top(), width(), tr::lng_theme_editor_title(tr::now));
|
||||||
}
|
}
|
||||||
|
|
||||||
void Editor::Start() {
|
//void Editor::Start() {
|
||||||
const auto path = Background()->themeAbsolutePath();
|
// const auto path = Background()->themeAbsolutePath();
|
||||||
if (path.isEmpty() || !Window::Theme::IsPaletteTestingPath(path)) {
|
// if (!Window::Theme::IsPaletteTestingPath(path)) {
|
||||||
const auto start = [](const QString &path) {
|
// const auto start = [](const QString &path) {
|
||||||
if (!Local::copyThemeColorsToPalette(path)) {
|
// if (!Local::copyThemeColorsToPalette(path)) {
|
||||||
writeDefaultPalette(path);
|
// writeDefaultPalette(path);
|
||||||
}
|
// }
|
||||||
if (!Apply(path)) {
|
// if (!Apply(path)) {
|
||||||
Ui::show(Box<InformBox>(tr::lng_theme_editor_error(tr::now)));
|
// Ui::show(Box<InformBox>(tr::lng_theme_editor_error(tr::now)));
|
||||||
return;
|
// return;
|
||||||
}
|
// }
|
||||||
KeepApplied();
|
// KeepApplied();
|
||||||
if (auto window = App::wnd()) {
|
// if (auto window = App::wnd()) {
|
||||||
window->showRightColumn(Box<Editor>(path));
|
// window->showRightColumn(Box<Editor>(path));
|
||||||
}
|
// }
|
||||||
};
|
// };
|
||||||
FileDialog::GetWritePath(
|
// FileDialog::GetWritePath(
|
||||||
App::wnd(),
|
// App::wnd(),
|
||||||
tr::lng_theme_editor_save_palette(tr::now),
|
// tr::lng_theme_editor_save_palette(tr::now),
|
||||||
"Palette (*.tdesktop-palette)",
|
// "Palette (*.tdesktop-palette)",
|
||||||
"colors.tdesktop-palette",
|
// "colors.tdesktop-palette",
|
||||||
start);
|
// start);
|
||||||
} else if (auto window = App::wnd()) {
|
// } else if (auto window = App::wnd()) {
|
||||||
window->showRightColumn(Box<Editor>(path));
|
// window->showRightColumn(Box<Editor>(path));
|
||||||
}
|
// }
|
||||||
}
|
//}
|
||||||
|
|
||||||
void Editor::closeEditor() {
|
void Editor::closeEditor() {
|
||||||
if (auto window = App::wnd()) {
|
if (auto window = App::wnd()) {
|
||||||
|
|
|
@ -25,9 +25,7 @@ bool CopyColorsToPalette(
|
||||||
|
|
||||||
class Editor : public TWidget {
|
class Editor : public TWidget {
|
||||||
public:
|
public:
|
||||||
Editor(QWidget*, const QString &path);
|
explicit Editor(QWidget*);
|
||||||
|
|
||||||
static void Start();
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void paintEvent(QPaintEvent *e) override;
|
void paintEvent(QPaintEvent *e) override;
|
||||||
|
|
|
@ -296,6 +296,20 @@ windowOutdatedClose: IconButton(defaultIconButton) {
|
||||||
iconPosition: point(-1px, -1px);
|
iconPosition: point(-1px, -1px);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
createThemeImportButton: InfoProfileButton {
|
||||||
|
textFg: lightButtonFg;
|
||||||
|
textFgOver: lightButtonFgOver;
|
||||||
|
textBg: windowBg;
|
||||||
|
textBgOver: windowBgOver;
|
||||||
|
|
||||||
|
font: semiboldFont;
|
||||||
|
|
||||||
|
height: 20px;
|
||||||
|
padding: margins(23px, 10px, 23px, 8px);
|
||||||
|
|
||||||
|
ripple: defaultRippleAnimation;
|
||||||
|
}
|
||||||
|
|
||||||
// Mac specific
|
// Mac specific
|
||||||
|
|
||||||
macAccessoryWidth: 450.;
|
macAccessoryWidth: 450.;
|
||||||
|
|
|
@ -9,7 +9,10 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
|
|
||||||
#include "core/application.h"
|
#include "core/application.h"
|
||||||
#include "main/main_account.h"
|
#include "main/main_account.h"
|
||||||
|
#include "window/layer_widget.h"
|
||||||
#include "window/window_session_controller.h"
|
#include "window/window_session_controller.h"
|
||||||
|
#include "window/themes/window_theme.h"
|
||||||
|
#include "window/themes/window_theme_editor.h"
|
||||||
#include "mainwindow.h"
|
#include "mainwindow.h"
|
||||||
|
|
||||||
namespace Window {
|
namespace Window {
|
||||||
|
@ -35,6 +38,13 @@ Controller::~Controller() {
|
||||||
|
|
||||||
void Controller::firstShow() {
|
void Controller::firstShow() {
|
||||||
_widget.firstShow();
|
_widget.firstShow();
|
||||||
|
checkThemeEditor();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Controller::checkThemeEditor() {
|
||||||
|
if (Window::Theme::Background()->isEditingTheme()) {
|
||||||
|
_widget.showRightColumn(Box<Window::Theme::Editor>());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Controller::setupPasscodeLock() {
|
void Controller::setupPasscodeLock() {
|
||||||
|
|
|
@ -67,6 +67,7 @@ private:
|
||||||
object_ptr<BoxContent> content,
|
object_ptr<BoxContent> content,
|
||||||
LayerOptions options,
|
LayerOptions options,
|
||||||
anim::type animated);
|
anim::type animated);
|
||||||
|
void checkThemeEditor();
|
||||||
|
|
||||||
not_null<Main::Account*> _account;
|
not_null<Main::Account*> _account;
|
||||||
::MainWindow _widget;
|
::MainWindow _widget;
|
||||||
|
|
|
@ -889,6 +889,8 @@
|
||||||
<(src_loc)/window/window_top_bar_wrap.h
|
<(src_loc)/window/window_top_bar_wrap.h
|
||||||
<(src_loc)/window/themes/window_theme.cpp
|
<(src_loc)/window/themes/window_theme.cpp
|
||||||
<(src_loc)/window/themes/window_theme.h
|
<(src_loc)/window/themes/window_theme.h
|
||||||
|
<(src_loc)/window/themes/window_theme_create_box.cpp
|
||||||
|
<(src_loc)/window/themes/window_theme_create_box.h
|
||||||
<(src_loc)/window/themes/window_theme_editor.cpp
|
<(src_loc)/window/themes/window_theme_editor.cpp
|
||||||
<(src_loc)/window/themes/window_theme_editor.h
|
<(src_loc)/window/themes/window_theme_editor.h
|
||||||
<(src_loc)/window/themes/window_theme_editor_block.cpp
|
<(src_loc)/window/themes/window_theme_editor_block.cpp
|
||||||
|
|
|
@ -93,6 +93,7 @@
|
||||||
'<(src_loc)/rpl/combine.h',
|
'<(src_loc)/rpl/combine.h',
|
||||||
'<(src_loc)/rpl/combine_previous.h',
|
'<(src_loc)/rpl/combine_previous.h',
|
||||||
'<(src_loc)/rpl/complete.h',
|
'<(src_loc)/rpl/complete.h',
|
||||||
|
'<(src_loc)/rpl/conditional.h',
|
||||||
'<(src_loc)/rpl/consumer.h',
|
'<(src_loc)/rpl/consumer.h',
|
||||||
'<(src_loc)/rpl/deferred.h',
|
'<(src_loc)/rpl/deferred.h',
|
||||||
'<(src_loc)/rpl/distinct_until_changed.h',
|
'<(src_loc)/rpl/distinct_until_changed.h',
|
||||||
|
|
Loading…
Reference in New Issue