2
0
mirror of https://github.com/kotatogram/kotatogram-desktop synced 2025-08-31 14:45:14 +00:00

First version on loading themes is ready.

This commit is contained in:
John Preston
2016-10-28 15:44:28 +03:00
parent b2414939c9
commit dbb6371e67
89 changed files with 4686 additions and 795 deletions

View File

@@ -62,6 +62,8 @@ public:
Plus,
Minus,
Equals,
And,
Or,
Name, // [0-9a-zA-Z_]+ with at least one letter.
};
Type type;
@@ -144,6 +146,8 @@ private:
{ '+', Type::Plus },
{ '-', Type::Minus },
{ '=', Type::Equals },
{ '&', Type::And },
{ '|', Type::Or },
};
};

View File

@@ -41,6 +41,54 @@ namespace {
constexpr int kErrorBadIconSize = 861;
constexpr int kErrorBadIconFormat = 862;
// crc32 hash, taken somewhere from the internet
class Crc32Table {
public:
Crc32Table() {
quint32 poly = 0x04c11db7;
for (auto i = 0; i != 256; ++i) {
_data[i] = reflect(i, 8) << 24;
for (auto j = 0; j != 8; ++j) {
_data[i] = (_data[i] << 1) ^ (_data[i] & (1 << 31) ? poly : 0);
}
_data[i] = reflect(_data[i], 32);
}
}
inline quint32 operator[](int index) const {
return _data[index];
}
private:
quint32 reflect(quint32 val, char ch) {
quint32 result = 0;
for (int i = 1; i < (ch + 1); ++i) {
if (val & 1) {
result |= 1 << (ch - i);
}
val >>= 1;
}
return result;
}
quint32 _data[256];
};
qint32 hashCrc32(const void *data, int len) {
static Crc32Table table;
const uchar *buffer = static_cast<const uchar *>(data);
quint32 crc = 0xffffffff;
for (int i = 0; i != len; ++i) {
crc = (crc >> 8) ^ table[(crc & 0xFF) ^ buffer[i]];
}
return static_cast<qint32>(crc ^ 0xffffffff);
}
char hexChar(uchar ch) {
if (ch < 10) {
return '0' + ch;
@@ -118,13 +166,38 @@ QString pxValueName(int value) {
return result + QString::number(value);
}
QString moduleBaseName(const structure::Module &module) {
auto moduleInfo = QFileInfo(module.filepath());
auto moduleIsPalette = (moduleInfo.suffix() == "palette");
return moduleIsPalette ? "palette" : "style_" + moduleInfo.baseName();
}
QChar paletteColorPart(uchar part) {
part = (part & 0x0F);
if (part >= 10) {
return 'a' + (part - 10);
}
return '0' + part;
}
QString paletteColorComponent(uchar value) {
return QString() + paletteColorPart(value >> 4) + paletteColorPart(value);
}
QString paletteColorValue(const structure::data::color &value) {
auto result = paletteColorComponent(value.red) + paletteColorComponent(value.green) + paletteColorComponent(value.blue);
if (value.alpha != 255) result += paletteColorComponent(value.alpha);
return result;
}
} // namespace
Generator::Generator(const structure::Module &module, const QString &destBasePath, const common::ProjectInfo &project)
Generator::Generator(const structure::Module &module, const QString &destBasePath, const common::ProjectInfo &project, bool isPalette)
: module_(module)
, basePath_(destBasePath)
, baseName_(QFileInfo(basePath_).baseName())
, project_(project) {
, project_(project)
, isPalette_(isPalette) {
}
bool Generator::writeHeader() {
@@ -164,8 +237,13 @@ public:\n\
}\n\
};\n\
Module_" << baseName_ << " registrator;\n";
if (!writeVariableDefinitions()) {
return false;
if (isPalette_) {
source_->newline();
source_->stream() << "style::palette _palette;\n";
} else {
if (!writeVariableDefinitions()) {
return false;
}
}
source_->newline().popNamespace();
@@ -174,8 +252,11 @@ Module_" << baseName_ << " registrator;\n";
return false;
}
source_->popNamespace().newline();
source_->newline().pushNamespace("style").pushNamespace("internal").newline();
source_->popNamespace().newline().pushNamespace("style");
if (isPalette_) {
writeSetPaletteColor();
}
source_->pushNamespace("internal").newline();
if (!writeVariableInit()) {
return false;
}
@@ -329,12 +410,84 @@ bool Generator::writeHeaderStyleNamespace() {
if (!writeStructsDefinitions()) {
return false;
}
} else if (isPalette_) {
if (!wroteForwardDeclarations) {
header_->newline();
}
if (!writePaletteDefinition()) {
return false;
}
}
header_->popNamespace().newline();
return true;
}
bool Generator::writePaletteDefinition() {
header_->stream() << "\
class palette {\n\
public:\n\
QByteArray save() const;\n\
bool load(const QByteArray &cache);\n\
bool setColor(QLatin1String name, uchar r, uchar g, uchar b, uchar a);\n\
bool setColor(QLatin1String name, QLatin1String from);\n\
\n\
// Created not inited, should be finalized before usage.\n\
void finalize();\n\
\n";
QByteArray checksumString;
int indexInPalette = 0;
if (!module_.enumVariables([this, &indexInPalette, &checksumString](const Variable &value) -> bool {
auto name = value.name.back();
if (value.value.type().tag != structure::TypeTag::Color) {
return false;
}
auto type = typeToString(value.value.type());
auto index = (indexInPalette++);
header_->stream() << "\tinline const " << type << " &" << name << "() const { return _colors[" << index << "]; };\n";
checksumString.append(':' + name);
return true;
})) return false;
auto checksum = hashCrc32(checksumString.constData(), checksumString.size());
auto count = indexInPalette;
auto type = typeToString({ structure::TypeTag::Color });
header_->stream() << "\
\n\
static constexpr int32 kChecksum = " << checksum << ";\n\
\n\
private:\n\
struct TempColorData { uchar r, g, b, a; };\n\
void compute(int index, int fallbackIndex, TempColorData data);\n\
\n\
enum class Status {\n\
Initial,\n\
Loaded,\n\
Fallback,\n\
};\n\
\n\
" << type << " _colors[" << count << "] = { Qt::Uninitialized };\n\
Status _status[" << count << "] = { Status::Initial };\n\
\n\
};\n\
\n\
namespace main_palette {\n\
\n\
QByteArray save();\n\
bool load(const QByteArray &cache);\n\
bool setColor(QLatin1String name, uchar r, uchar g, uchar b, uchar a);\n\
bool setColor(QLatin1String name, QLatin1String from);\n\
\n\
} // namespace main_palette\n\
\n";
header_->newline();
return true;
}
bool Generator::writeStructsForwardDeclarations() {
bool hasNoExternalStructs = module_.enumVariables([this](const Variable &value) -> bool {
if (value.value.type().tag == structure::TypeTag::Struct) {
@@ -411,7 +564,7 @@ bool Generator::writeIncludesInSource() {
}
bool result = module_.enumIncludes([this](const Module &module) -> bool {
source_->include("style_" + QFileInfo(module.filepath()).baseName() + ".h");
source_->include(moduleBaseName(module) + ".h");
return true;
});
source_->newline();
@@ -441,19 +594,189 @@ bool Generator::writeRefsDefinition() {
return true;
}
source_->newline();
bool result = module_.enumVariables([this](const Variable &variable) -> bool {
auto name = variable.name.back();
auto type = typeToString(variable.value.type());
if (type.isEmpty()) {
return false;
}
source_->stream() << "const " << type << " &" << name << "(_" << name << ");\n";
source_->stream() << "const " << type << " &" << name << "(";
if (isPalette_) {
source_->stream() << "_palette." << name << "()";
} else {
source_->stream() << "_" << name;
}
source_->stream() << ");\n";
return true;
});
return result;
}
bool Generator::writeSetPaletteColor() {
source_->newline();
source_->stream() << "void palette::finalize() {\n";
int indexInPalette = 0;
bool result = module_.enumVariables([this, &indexInPalette](const Variable &variable) -> bool {
auto name = variable.name.back();
auto index = indexInPalette++;
paletteIndices_[name] = index;
if (variable.value.type().tag != structure::TypeTag::Color) {
return false;
}
auto color = variable.value.Color();
auto fallbackIndex = paletteIndices_.value(variable.value.Color().fallback, -1);
source_->stream() << "\tcompute(" << index << ", " << fallbackIndex << ", {" << color.red << ", " << color.green << ", " << color.blue << ", " << color.alpha << "});\n";
return true;
});
auto count = indexInPalette;
source_->stream() << "\
}\n\
\n\
void palette::compute(int index, int fallbackIndex, TempColorData data) {\n\
if (_status[index] == Status::Initial) {\n\
if (fallbackIndex >= 0 && _status[fallbackIndex] != Status::Initial) {\n\
_status[index] = Status::Fallback;\n\
_colors[index] = _colors[fallbackIndex];\n\
} else {\n\
_colors[index] = { data.r, data.g, data.b, data.a };\n\
}\n\
}\n\
}\n";
source_->newline().pushNamespace().newline();
source_->stream() << "\
int getPaletteIndex(QLatin1String name) {\n\
auto size = name.size();\n\
auto data = name.data();\n";
int already = 0;
QString prefix;
QString tabs;
for (auto i = paletteIndices_.end(), b = paletteIndices_.begin(); i != b;) {
--i;
auto name = i.key();
auto index = i.value();
auto prev = i;
auto next = (i == b) ? QString() : (--prev).key();
while ((prefix.size() > name.size()) || (!prefix.isEmpty() && prefix.mid(0, already - 1) != name.mid(0, already - 1))) {
source_->stream() << "\n" << tabs << "};";
prefix.chop(1);
tabs.chop(1);
--already;
}
if (!prefix.isEmpty() && prefix[already - 1] != name[already - 1]) {
source_->stream() << "\n" << tabs << "case '" << name[already - 1] << "':";
prefix[already - 1] = name[already - 1];
}
while (name.size() > already) {
if (name.mid(0, already) != next.mid(0, already)) {
break;
} else if (next.size() <= already) {
source_->stream() << "\n" << tabs << "\tif (size == " << name.size() << ")";
break;
}
source_->stream() << "\n" << tabs << "\tif (size > " << already << ") switch (data[" << already << "]) {\n";
prefix.append(name[already]);
tabs.append('\t');
++already;
source_->stream() << tabs << "case '" << name[already - 1] << "':";
}
if (name.size() == already || name.mid(0, already) != next.mid(0, already)) {
source_->stream() << " return (size == " << name.size();
if (name.size() != already) {
source_->stream() << " && ";
}
} else {
source_->stream() << " return (";
}
if (already != name.size()) {
source_->stream() << "!memcmp(data + " << already << ", \"" << name.mid(already) << "\", " << (name.size() - already) << ")";
}
source_->stream() << ") ? " << index << " : -1;";
}
while (!prefix.isEmpty()) {
source_->stream() << "\n" << tabs << "};";
prefix.chop(1);
tabs.chop(1);
--already;
}
source_->stream() << "\
\n\
return -1;\n\
}\n";
source_->newline().popNamespace().newline();
source_->stream() << "\
QByteArray palette::save() const {\n\
auto result = QByteArray(" << (count * 4) << ", Qt::Uninitialized);\n\
for (auto i = 0, index = 0; i != " << count << "; ++i) {\n\
result[index++] = static_cast<uchar>(_colors[i]->c.red());\n\
result[index++] = static_cast<uchar>(_colors[i]->c.green());\n\
result[index++] = static_cast<uchar>(_colors[i]->c.blue());\n\
result[index++] = static_cast<uchar>(_colors[i]->c.alpha());\n\
}\n\
return result;\n\
}\n\
\n\
bool palette::load(const QByteArray &cache) {\n\
if (cache.size() != " << (count * 4) << ") return false;\n\
\n\
auto p = reinterpret_cast<const uchar*>(cache.constData());\n\
for (auto i = 0; i != " << count << "; ++i) {\n\
_colors[i] = { p[i * 4 + 0], p[i * 4 + 1], p[i * 4 + 2], p[i * 4 + 3] };\n\
_status[i] = Status::Loaded;\n\
}\n\
return true;\n\
}\n\
\n\
bool palette::setColor(QLatin1String name, uchar r, uchar g, uchar b, uchar a) {\n\
auto index = getPaletteIndex(name);\n\
if (index >= 0) {\n\
_colors[index] = { r, g, b, a };\n\
_status[index] = Status::Loaded;\n\
return true;\n\
}\n\
return false;\n\
}\n\
\n\
bool palette::setColor(QLatin1String name, QLatin1String from) {\n\
auto nameIndex = getPaletteIndex(name);\n\
auto fromIndex = getPaletteIndex(from);\n\
if (nameIndex >= 0 && fromIndex >= 0 && _status[fromIndex] == Status::Loaded) {\n\
_colors[nameIndex] = _colors[fromIndex];\n\
_status[nameIndex] = Status::Loaded;\n\
return true;\n\
}\n\
return false;\n\
}\n\
\n\
namespace main_palette {\n\
\n\
QByteArray save() {\n\
return _palette.save();\n\
}\n\
\n\
bool load(const QByteArray &cache) {\n\
return _palette.load(cache);\n\
}\n\
\n\
bool setColor(QLatin1String name, uchar r, uchar g, uchar b, uchar a) {\n\
return _palette.setColor(name, r, g, b, a);\n\
}\n\
\n\
bool setColor(QLatin1String name, QLatin1String from) {\n\
return _palette.setColor(name, from);\n\
}\n\
\n\
} // namespace main_palette\n\
\n";
return result;
}
bool Generator::writeVariableInit() {
if (!module_.hasVariables()) {
return true;
@@ -486,7 +809,7 @@ void init_" << baseName_ << "() {\n\
bool writtenAtLeastOne = false;
bool result = module_.enumIncludes([this,&writtenAtLeastOne](const Module &module) -> bool {
if (module.hasVariables()) {
source_->stream() << "\tinit_style_" + QFileInfo(module.filepath()).baseName() + "();\n";
source_->stream() << "\tinit_" + moduleBaseName(module) + "();\n";
writtenAtLeastOne = true;
}
return true;
@@ -509,7 +832,9 @@ void init_" << baseName_ << "() {\n\
source_->newline();
}
bool result = module_.enumVariables([this](const Variable &variable) -> bool {
if (isPalette_) {
source_->stream() << "\t_palette.finalize();\n";
} else if (!module_.enumVariables([this](const Variable &variable) -> bool {
auto name = variable.name.back();
auto value = valueAssignmentCode(variable.value);
if (value.isEmpty()) {
@@ -517,11 +842,12 @@ void init_" << baseName_ << "() {\n\
}
source_->stream() << "\t_" << name << " = " << value << ";\n";
return true;
});
})) {
return false;
}
source_->stream() << "\
}\n\n";
return result;
return true;
}
bool Generator::writePxValuesInit() {
@@ -629,7 +955,6 @@ QByteArray iconMaskValuePng(const QString &filepath) {
{
QBuffer buffer(&result);
composed.save(&buffer, "PNG");
// composed.save(filePath + "@final.png", "PNG");
}
return result;
}
@@ -735,5 +1060,87 @@ bool Generator::collectUniqueValues() {
return module_.enumVariables(collector);
}
bool Generator::writeSampleTheme(const QString &filepath) {
QByteArray content;
QTextStream stream(&content);
stream << "\
//\n\
// This is a sample Telegram Desktop theme file.\n\
// It was generated from the 'colors.palette' style file.\n\
//\n\
// To create a theme with a background image included you should\n\
// put two files in a .zip archive:\n\
//\n\
// First one is the color scheme like the one you're viewing\n\
// right now, this file should be named 'colors.tdesktop-theme'.\n\
//\n\
// Second one should be the background image and it can be named\n\
// 'background.jpg', 'background.png', 'tiled.jpg' or 'tiled.png'.\n\
// You should name it 'background' (if you'd like it not to be tiled),\n\
// or it can be named 'tiled' (if you'd like it to be tiled).\n\
//\n\
// After that you need to change the extension of your .zip archive\n\
// to 'tdesktop-theme', so you'll have:\n\
//\n\
// mytheme.tdesktop-theme\n\
// |-colors.tdesktop-theme\n\
// |-background.jpg (or tiled.jpg, background.png, tiled.png)\n\
//\n\n";
QList<structure::FullName> names;
module_.enumVariables([this, &names](const Variable &variable) -> bool {
names.push_back(variable.name);
return true;
});
bool result = module_.enumVariables([this, &names, &stream](const Variable &variable) -> bool {
auto name = variable.name.back();
if (variable.value.type().tag != structure::TypeTag::Color) {
return false;
}
auto color = variable.value.Color();
auto colorString = paletteColorValue(color);
auto fallbackIndex = paletteIndices_.value(variable.value.Color().fallback, -1);
if (fallbackIndex >= 0) {
auto fallbackVariable = module_.findVariableInModule(names[fallbackIndex], module_);
if (!fallbackVariable || fallbackVariable->value.type().tag != structure::TypeTag::Color) {
return false;
}
auto fallbackName = fallbackVariable->name.back();
auto fallbackColor = fallbackVariable->value.Color();
if (colorString == paletteColorValue(fallbackColor)) {
stream << name << ": " << fallbackName << ";\n";
} else {
stream << name << ": #" << colorString << "; // " << fallbackName << ";\n";
}
} else {
stream << name << ": #" << colorString << ";\n";
}
return true;
});
if (!result) {
return result;
}
stream.flush();
QFile file(filepath);
if (file.open(QIODevice::ReadOnly)) {
if (file.readAll() == content) {
file.close();
return true;
}
file.close();
}
if (!file.open(QIODevice::WriteOnly)) {
return false;
}
if (file.write(content) != content.size()) {
return false;
}
return true;
}
} // namespace style
} // namespace codegen

View File

@@ -34,12 +34,13 @@ class Module;
class Generator {
public:
Generator(const structure::Module &module, const QString &destBasePath, const common::ProjectInfo &project);
Generator(const structure::Module &module, const QString &destBasePath, const common::ProjectInfo &project, bool isPalette);
Generator(const Generator &other) = delete;
Generator &operator=(const Generator &other) = delete;
bool writeHeader();
bool writeSource();
bool writeSampleTheme(const QString &filepath);
private:
QString typeToString(structure::Type type) const;
@@ -49,11 +50,13 @@ private:
bool writeHeaderStyleNamespace();
bool writeStructsForwardDeclarations();
bool writeStructsDefinitions();
bool writePaletteDefinition();
bool writeRefsDeclarations();
bool writeIncludesInSource();
bool writeVariableDefinitions();
bool writeRefsDefinition();
bool writeSetPaletteColor();
bool writeVariableInit();
bool writePxValuesInit();
bool writeFontFamiliesInit();
@@ -66,10 +69,12 @@ private:
QString basePath_, baseName_;
const common::ProjectInfo &project_;
std::unique_ptr<common::CppFile> source_, header_;
bool isPalette_ = false;
QMap<int, bool> pxValues_;
QMap<std::string, int> fontFamilies_;
QMap<QString, int> iconMasks_; // icon file -> index
QMap<QString, int> paletteIndices_;
std::vector<int> scales = { 4, 5, 6, 8 }; // scale / 4 gives our 1.00, 1.25, 1.50, 2.00
std::vector<const char *>scaleNames = { "dbisOne", "dbisOneAndQuarter", "dbisOneAndHalf", "dbisTwo" };

View File

@@ -41,16 +41,12 @@ using common::logError;
Options parseOptions() {
Options result;
auto args(QCoreApplication::instance()->arguments());
auto args = QCoreApplication::instance()->arguments();
for (int i = 1, count = args.size(); i < count; ++i) { // skip first
const auto &arg(args.at(i));
// Rebuild all dependencies
if (arg == "--rebuild") {
result.rebuildDependencies = true;
auto &arg = args.at(i);
// Include paths
} else if (arg == "-I") {
if (arg == "-I") {
if (++i == count) {
logError(kErrorIncludePathExpected, "Command Line") << "include path expected after -I";
return Options();
@@ -96,6 +92,7 @@ Options parseOptions() {
logError(kErrorInputPathExpected, "Command Line") << "input path expected";
return Options();
}
result.isPalette = (QFileInfo(result.inputPath).suffix() == "palette");
return result;
}

View File

@@ -30,7 +30,7 @@ struct Options {
QStringList includePaths = { "." };
QString outputPath = ".";
QString inputPath;
bool rebuildDependencies = false;
bool isPalette = false;
};
// Parsing failed if inputPath is empty in the result.

View File

@@ -77,6 +77,10 @@ bool isValidColor(const QString &str) {
return true;
}
uchar toGray(uchar r, uchar g, uchar b) {
return qMax(qMin(int(0.21 * r + 0.72 * g + 0.07 * b), 255), 0);
}
uchar readHexUchar(QChar ch) {
auto code = ch.unicode();
return (code >= '0' && code <= '9') ? ((code - '0') & 0xFF) : ((code + 10 - 'a') & 0xFF);
@@ -86,7 +90,7 @@ uchar readHexUchar(QChar char1, QChar char2) {
return ((readHexUchar(char1) & 0x0F) << 4) | (readHexUchar(char2) & 0x0F);
}
structure::data::color convertWebColor(const QString &str) {
structure::data::color convertWebColor(const QString &str, const QString &fallback = QString()) {
uchar r = 0, g = 0, b = 0, a = 255;
if (isValidColor(str)) {
r = readHexUchar(str.at(0), str.at(1));
@@ -96,7 +100,7 @@ structure::data::color convertWebColor(const QString &str) {
a = readHexUchar(str.at(6), str.at(7));
}
}
return { r, g, b, a };
return { r, g, b, a, fallback };
}
structure::data::color convertIntColor(int r, int g, int b, int a) {
@@ -216,6 +220,11 @@ ParsedFile::ModulePtr ParsedFile::readIncluded() {
}
structure::Struct ParsedFile::readStruct(const QString &name) {
if (options_.isPalette) {
logErrorUnexpectedToken() << "unique color variable for the palette";
return {};
}
structure::Struct result = { composeFullName(name) };
do {
if (auto fieldName = file_.getToken(BasicType::Name)) {
@@ -236,6 +245,10 @@ structure::Variable ParsedFile::readVariable(const QString &name) {
structure::Variable result = { composeFullName(name) };
if (auto value = readValue()) {
result.value = value;
if (options_.isPalette && value.type().tag != structure::TypeTag::Color) {
logErrorUnexpectedToken() << "unique color variable for the palette";
return {};
}
if (value.type().tag != structure::TypeTag::Struct || !value.copyOf().empty()) {
assertNextToken(BasicType::Semicolon);
}
@@ -491,14 +504,35 @@ structure::Value ParsedFile::readStringValue() {
structure::Value ParsedFile::readColorValue() {
if (auto numberSign = file_.getToken(BasicType::Number)) {
auto color = file_.getAnyToken();
if (color.type == BasicType::Int || color.type == BasicType::Name) {
auto chars = tokenValue(color).toLower();
if (isValidColor(chars)) {
return { convertWebColor(chars) };
if (options_.isPalette || true) { // enable for now
auto color = file_.getAnyToken();
if (color.type == BasicType::Int || color.type == BasicType::Name) {
auto chars = tokenValue(color).toLower();
if (isValidColor(chars)) {
if (auto fallbackSeparator = file_.getToken(BasicType::Or)) {
if (options_.isPalette) {
if (auto fallbackName = file_.getToken(BasicType::Name)) {
structure::FullName name = { tokenValue(fallbackName) };
if (auto variable = module_->findVariableInModule(name, *module_)) {
return { convertWebColor(chars, tokenValue(fallbackName)) };
} else {
logError(kErrorIdentifierNotFound) << "fallback color name";
}
} else {
logErrorUnexpectedToken() << "fallback color name";
}
} else {
logErrorUnexpectedToken() << "';', color fallbacks are only allowed in palette module";
}
} else {
return { convertWebColor(chars) };
}
}
} else {
logErrorUnexpectedToken() << "color value in #ccc, #ccca, #cccccc or #ccccccaa format";
}
} else {
logErrorUnexpectedToken() << "color value in #ccc, #ccca, #cccccc or #ccccccaa format";
logErrorUnexpectedToken() << "color value alias, unique color values are only allowed in palette module";
}
}
return {};
@@ -815,6 +849,7 @@ Options ParsedFile::includedOptions(const QString &filepath) {
auto result = options_;
result.inputPath = filepath;
result.includePaths[0] = QFileInfo(filePath_).dir().absolutePath();
result.isPalette = (QFileInfo(filepath).suffix() == "palette");
return result;
}

View File

@@ -49,14 +49,7 @@ int Processor::launch() {
}
auto module = parser_->getResult();
if (options_.rebuildDependencies) {
bool result = module->enumIncludes([this](const structure::Module &included) -> bool {
return write(included);
});
if (!result) {
return -1;
}
} else if (!write(*module)) {
if (!write(*module)) {
return -1;
}
@@ -72,7 +65,7 @@ bool Processor::write(const structure::Module &module) const {
}
QFileInfo srcFile(module.filepath());
QString dstFilePath = dir.absolutePath() + '/' + destFileBaseName(module);
QString dstFilePath = dir.absolutePath() + '/' + (options_.isPalette ? "palette" : destFileBaseName(module));
common::ProjectInfo project = {
"codegen_style",
@@ -81,13 +74,17 @@ bool Processor::write(const structure::Module &module) const {
forceReGenerate
};
Generator generator(module, dstFilePath, project);
Generator generator(module, dstFilePath, project, options_.isPalette);
if (!generator.writeHeader()) {
return false;
}
if (!generator.writeSource()) {
return false;
}
auto themePath = srcFile.absoluteDir().absolutePath() + "/sample.tdesktop-theme";
if (options_.isPalette && !generator.writeSampleTheme(themePath)) {
return false;
}
return true;
}

View File

@@ -91,6 +91,7 @@ struct size {
struct color {
uchar red, green, blue, alpha;
QString fallback;
};
struct margins {