diff options
Diffstat (limited to 'editor')
-rw-r--r-- | editor/SCsub | 169 | ||||
-rw-r--r-- | editor/editor_builders.py | 412 | ||||
-rw-r--r-- | editor/editor_properties.cpp | 10 | ||||
-rw-r--r-- | editor/icons/SCsub | 90 | ||||
-rw-r--r-- | editor/icons/editor_icons_builders.py | 96 |
5 files changed, 543 insertions, 234 deletions
diff --git a/editor/SCsub b/editor/SCsub index a9343f7f36..4fa287c33b 100644 --- a/editor/SCsub +++ b/editor/SCsub @@ -5,149 +5,14 @@ env.editor_sources = [] import os import os.path -from compat import encode_utf8, byte_to_str, open_utf8, escape_string - -def make_certs_header(target, source, env): - - src = source[0].srcnode().abspath - dst = target[0].srcnode().abspath - f = open(src, "rb") - g = open_utf8(dst, "w") - buf = f.read() - decomp_size = len(buf) - import zlib - buf = zlib.compress(buf) - - g.write("/* THIS FILE IS GENERATED DO NOT EDIT */\n") - g.write("#ifndef _CERTS_RAW_H\n") - g.write("#define _CERTS_RAW_H\n") - g.write("static const int _certs_compressed_size = " + str(len(buf)) + ";\n") - g.write("static const int _certs_uncompressed_size = " + str(decomp_size) + ";\n") - g.write("static const unsigned char _certs_compressed[] = {\n") - for i in range(len(buf)): - g.write("\t" + byte_to_str(buf[i]) + ",\n") - g.write("};\n") - g.write("#endif") - - g.close() - f.close() - - -def make_doc_header(target, source, env): - - dst = target[0].srcnode().abspath - g = open_utf8(dst, "w") - buf = "" - docbegin = "" - docend = "" - for s in source: - src = s.srcnode().abspath - if not src.endswith(".xml"): - continue - with open_utf8(src, "r") as f: - content = f.read() - buf += content - - buf = encode_utf8(docbegin + buf + docend) - decomp_size = len(buf) - import zlib - buf = zlib.compress(buf) - - g.write("/* THIS FILE IS GENERATED DO NOT EDIT */\n") - g.write("#ifndef _DOC_DATA_RAW_H\n") - g.write("#define _DOC_DATA_RAW_H\n") - g.write("static const int _doc_data_compressed_size = " + str(len(buf)) + ";\n") - g.write("static const int _doc_data_uncompressed_size = " + str(decomp_size) + ";\n") - g.write("static const unsigned char _doc_data_compressed[] = {\n") - for i in range(len(buf)): - g.write("\t" + byte_to_str(buf[i]) + ",\n") - g.write("};\n") - - g.write("#endif") - - g.close() - - -def make_fonts_header(target, source, env): - - dst = target[0].srcnode().abspath - - g = open_utf8(dst, "w") - - g.write("/* THIS FILE IS GENERATED DO NOT EDIT */\n") - g.write("#ifndef _EDITOR_FONTS_H\n") - g.write("#define _EDITOR_FONTS_H\n") - - # saving uncompressed, since freetype will reference from memory pointer - xl_names = [] - for i in range(len(source)): - with open(source[i].srcnode().abspath, "rb")as f: - buf = f.read() - - name = os.path.splitext(os.path.basename(source[i].srcnode().abspath))[0] - - g.write("static const int _font_" + name + "_size = " + str(len(buf)) + ";\n") - g.write("static const unsigned char _font_" + name + "[] = {\n") - for i in range(len(buf)): - g.write("\t" + byte_to_str(buf[i]) + ",\n") - - g.write("};\n") - - g.write("#endif") - - g.close() - +from platform_methods import run_in_subprocess +from compat import open_utf8 +import editor_builders -def make_translations_header(target, source, env): - - dst = target[0].srcnode().abspath - - g = open_utf8(dst, "w") - - g.write("/* THIS FILE IS GENERATED DO NOT EDIT */\n") - g.write("#ifndef _EDITOR_TRANSLATIONS_H\n") - g.write("#define _EDITOR_TRANSLATIONS_H\n") - - import zlib - import os.path - - paths = [node.srcnode().abspath for node in source] - sorted_paths = sorted(paths, key=lambda path: os.path.splitext(os.path.basename(path))[0]) - - xl_names = [] - for i in range(len(sorted_paths)): - with open(sorted_paths[i], "rb") as f: - buf = f.read() - decomp_size = len(buf) - buf = zlib.compress(buf) - name = os.path.splitext(os.path.basename(sorted_paths[i]))[0] - - g.write("static const unsigned char _translation_" + name + "_compressed[] = {\n") - for i in range(len(buf)): - g.write("\t" + byte_to_str(buf[i]) + ",\n") - - g.write("};\n") - - xl_names.append([name, len(buf), str(decomp_size)]) - - g.write("struct EditorTranslationList {\n") - g.write("\tconst char* lang;\n") - g.write("\tint comp_size;\n") - g.write("\tint uncomp_size;\n") - g.write("\tconst unsigned char* data;\n") - g.write("};\n\n") - g.write("static EditorTranslationList _editor_translations[] = {\n") - for x in xl_names: - g.write("\t{ \"" + x[0] + "\", " + str(x[1]) + ", " + str(x[2]) + ", _translation_" + x[0] + "_compressed},\n") - g.write("\t{NULL, 0, 0, NULL}\n") - g.write("};\n") - - g.write("#endif") - - g.close() def _make_doc_data_class_path(to_path): - g = open_utf8(os.path.join(to_path,"doc_data_class_path.gen.h"), "w") + # NOTE: It is safe to generate this file here, since this is still executed serially + g = open_utf8(os.path.join(to_path, "doc_data_class_path.gen.h"), "w") g.write("static const int _doc_data_class_path_count = " + str(len(env.doc_class_path)) + ";\n") g.write("struct _DocDataClassPath { const char* name; const char* path; };\n") @@ -169,6 +34,8 @@ if env['tools']: reg_exporters += '\tregister_' + e + '_exporter();\n' reg_exporters_inc += '#include "platform/' + e + '/export/export.h"\n' reg_exporters += '}\n' + + # NOTE: It is safe to generate this file here, since this is still executed serially with open_utf8("register_exporters.gen.cpp", "w") as f: f.write(reg_exporters_inc) f.write(reg_exporters) @@ -192,24 +59,38 @@ if env['tools']: docs = sorted(docs) env.Depends("#editor/doc_data_compressed.gen.h", docs) - env.CommandNoCache("#editor/doc_data_compressed.gen.h", docs, make_doc_header) + env.CommandNoCache("#editor/doc_data_compressed.gen.h", docs, run_in_subprocess(editor_builders.make_doc_header)) + # Certificates env.Depends("#editor/certs_compressed.gen.h", "#thirdparty/certs/ca-certificates.crt") - env.CommandNoCache("#editor/certs_compressed.gen.h", "#thirdparty/certs/ca-certificates.crt", make_certs_header) + env.CommandNoCache("#editor/certs_compressed.gen.h", "#thirdparty/certs/ca-certificates.crt", run_in_subprocess(editor_builders.make_certs_header)) import glob + path = env.Dir('.').abspath # Translations tlist = glob.glob(path + "/translations/*.po") env.Depends('#editor/translations.gen.h', tlist) - env.CommandNoCache('#editor/translations.gen.h', tlist, make_translations_header) + env.CommandNoCache('#editor/translations.gen.h', tlist, run_in_subprocess(editor_builders.make_translations_header)) # Fonts flist = glob.glob(path + "/../thirdparty/fonts/*.ttf") flist.append(glob.glob(path + "/../thirdparty/fonts/*.otf")) env.Depends('#editor/builtin_fonts.gen.h', flist) - env.CommandNoCache('#editor/builtin_fonts.gen.h', flist, make_fonts_header) + env.CommandNoCache('#editor/builtin_fonts.gen.h', flist, run_in_subprocess(editor_builders.make_fonts_header)) + + # Authors + env.Depends('#editor/authors.gen.h', "../AUTHORS.md") + env.CommandNoCache('#editor/authors.gen.h', "../AUTHORS.md", run_in_subprocess(editor_builders.make_authors_header)) + + # Donors + env.Depends('#editor/donors.gen.h', "../DONORS.md") + env.CommandNoCache('#editor/donors.gen.h', "../DONORS.md", run_in_subprocess(editor_builders.make_donors_header)) + + # License + env.Depends('#editor/license.gen.h', ["../COPYRIGHT.txt", "../LICENSE.txt"]) + env.CommandNoCache('#editor/license.gen.h', ["../COPYRIGHT.txt", "../LICENSE.txt"], run_in_subprocess(editor_builders.make_license_header)) env.add_source_files(env.editor_sources, "*.cpp") env.add_source_files(env.editor_sources, ["#thirdparty/misc/clipper.cpp"]) diff --git a/editor/editor_builders.py b/editor/editor_builders.py new file mode 100644 index 0000000000..6c2f9e298e --- /dev/null +++ b/editor/editor_builders.py @@ -0,0 +1,412 @@ +"""Functions used to generate source files during build time + +All such functions are invoked in a subprocess on Windows to prevent build flakiness. + +""" +import os +import os.path +from platform_methods import subprocess_main +from compat import encode_utf8, byte_to_str, open_utf8, escape_string + + +def make_certs_header(target, source, env): + + src = source[0] + dst = target[0] + f = open(src, "rb") + g = open_utf8(dst, "w") + buf = f.read() + decomp_size = len(buf) + import zlib + buf = zlib.compress(buf) + + g.write("/* THIS FILE IS GENERATED DO NOT EDIT */\n") + g.write("#ifndef _CERTS_RAW_H\n") + g.write("#define _CERTS_RAW_H\n") + g.write("static const int _certs_compressed_size = " + str(len(buf)) + ";\n") + g.write("static const int _certs_uncompressed_size = " + str(decomp_size) + ";\n") + g.write("static const unsigned char _certs_compressed[] = {\n") + for i in range(len(buf)): + g.write("\t" + byte_to_str(buf[i]) + ",\n") + g.write("};\n") + g.write("#endif") + + g.close() + f.close() + + +def make_doc_header(target, source, env): + + dst = target[0] + g = open_utf8(dst, "w") + buf = "" + docbegin = "" + docend = "" + for src in source: + if not src.endswith(".xml"): + continue + with open_utf8(src, "r") as f: + content = f.read() + buf += content + + buf = encode_utf8(docbegin + buf + docend) + decomp_size = len(buf) + import zlib + buf = zlib.compress(buf) + + g.write("/* THIS FILE IS GENERATED DO NOT EDIT */\n") + g.write("#ifndef _DOC_DATA_RAW_H\n") + g.write("#define _DOC_DATA_RAW_H\n") + g.write("static const int _doc_data_compressed_size = " + str(len(buf)) + ";\n") + g.write("static const int _doc_data_uncompressed_size = " + str(decomp_size) + ";\n") + g.write("static const unsigned char _doc_data_compressed[] = {\n") + for i in range(len(buf)): + g.write("\t" + byte_to_str(buf[i]) + ",\n") + g.write("};\n") + + g.write("#endif") + + g.close() + + +def make_fonts_header(target, source, env): + + dst = target[0] + + g = open_utf8(dst, "w") + + g.write("/* THIS FILE IS GENERATED DO NOT EDIT */\n") + g.write("#ifndef _EDITOR_FONTS_H\n") + g.write("#define _EDITOR_FONTS_H\n") + + # saving uncompressed, since freetype will reference from memory pointer + xl_names = [] + for i in range(len(source)): + with open(source[i], "rb")as f: + buf = f.read() + + name = os.path.splitext(os.path.basename(source[i]))[0] + + g.write("static const int _font_" + name + "_size = " + str(len(buf)) + ";\n") + g.write("static const unsigned char _font_" + name + "[] = {\n") + for i in range(len(buf)): + g.write("\t" + byte_to_str(buf[i]) + ",\n") + + g.write("};\n") + + g.write("#endif") + + g.close() + + +def make_translations_header(target, source, env): + + dst = target[0] + + g = open_utf8(dst, "w") + + g.write("/* THIS FILE IS GENERATED DO NOT EDIT */\n") + g.write("#ifndef _EDITOR_TRANSLATIONS_H\n") + g.write("#define _EDITOR_TRANSLATIONS_H\n") + + import zlib + import os.path + + sorted_paths = sorted(source, key=lambda path: os.path.splitext(os.path.basename(path))[0]) + + xl_names = [] + for i in range(len(sorted_paths)): + with open(sorted_paths[i], "rb") as f: + buf = f.read() + decomp_size = len(buf) + buf = zlib.compress(buf) + name = os.path.splitext(os.path.basename(sorted_paths[i]))[0] + + g.write("static const unsigned char _translation_" + name + "_compressed[] = {\n") + for i in range(len(buf)): + g.write("\t" + byte_to_str(buf[i]) + ",\n") + + g.write("};\n") + + xl_names.append([name, len(buf), str(decomp_size)]) + + g.write("struct EditorTranslationList {\n") + g.write("\tconst char* lang;\n") + g.write("\tint comp_size;\n") + g.write("\tint uncomp_size;\n") + g.write("\tconst unsigned char* data;\n") + g.write("};\n\n") + g.write("static EditorTranslationList _editor_translations[] = {\n") + for x in xl_names: + g.write("\t{ \"" + x[0] + "\", " + str(x[1]) + ", " + str(x[2]) + ", _translation_" + x[0] + "_compressed},\n") + g.write("\t{NULL, 0, 0, NULL}\n") + g.write("};\n") + + g.write("#endif") + + g.close() + + +def make_authors_header(target, source, env): + + sections = ["Project Founders", "Lead Developer", "Project Manager", "Developers"] + sections_id = ["dev_founders", "dev_lead", "dev_manager", "dev_names"] + + src = source[0] + dst = target[0] + f = open_utf8(src, "r") + g = open_utf8(dst, "w") + + g.write("/* THIS FILE IS GENERATED DO NOT EDIT */\n") + g.write("#ifndef _EDITOR_AUTHORS_H\n") + g.write("#define _EDITOR_AUTHORS_H\n") + + current_section = "" + reading = False + + def close_section(): + g.write("\t0\n") + g.write("};\n") + + for line in f: + if reading: + if line.startswith(" "): + g.write("\t\"" + escape_string(line.strip()) + "\",\n") + continue + if line.startswith("## "): + if reading: + close_section() + reading = False + for i in range(len(sections)): + if line.strip().endswith(sections[i]): + current_section = escape_string(sections_id[i]) + reading = True + g.write("static const char *" + current_section + "[] = {\n") + break + + if reading: + close_section() + + g.write("#endif\n") + + g.close() + f.close() + +def make_donors_header(target, source, env): + + sections = ["Platinum sponsors", "Gold sponsors", "Mini sponsors", "Gold donors", "Silver donors", "Bronze donors"] + sections_id = ["donor_s_plat", "donor_s_gold", "donor_s_mini", "donor_gold", "donor_silver", "donor_bronze"] + + src = source[0] + dst = target[0] + f = open_utf8(src, "r") + g = open_utf8(dst, "w") + + g.write("/* THIS FILE IS GENERATED DO NOT EDIT */\n") + g.write("#ifndef _EDITOR_DONORS_H\n") + g.write("#define _EDITOR_DONORS_H\n") + + current_section = "" + reading = False + + def close_section(): + g.write("\t0\n") + g.write("};\n") + + for line in f: + if reading >= 0: + if line.startswith(" "): + g.write("\t\"" + escape_string(line.strip()) + "\",\n") + continue + if line.startswith("## "): + if reading: + close_section() + reading = False + for i in range(len(sections)): + if line.strip().endswith(sections[i]): + current_section = escape_string(sections_id[i]) + reading = True + g.write("static const char *" + current_section + "[] = {\n") + break + + if reading: + close_section() + + g.write("#endif\n") + + g.close() + f.close() + + +def make_license_header(target, source, env): + + src_copyright = source[0] + src_license = source[1] + dst = target[0] + f = open_utf8(src_license, "r") + fc = open_utf8(src_copyright, "r") + g = open_utf8(dst, "w") + + g.write("/* THIS FILE IS GENERATED DO NOT EDIT */\n") + g.write("#ifndef _EDITOR_LICENSE_H\n") + g.write("#define _EDITOR_LICENSE_H\n") + g.write("static const char *about_license =") + + for line in f: + escaped_string = escape_string(line.strip()) + g.write("\n\t\"" + escaped_string + "\\n\"") + + g.write(";\n") + + tp_current = 0 + tp_file = "" + tp_comment = "" + tp_copyright = "" + tp_license = "" + + tp_licensename = "" + tp_licensebody = "" + + tp = [] + tp_licensetext = [] + for line in fc: + if line.startswith("#"): + continue + + if line.startswith("Files:"): + tp_file = line[6:].strip() + tp_current = 1 + elif line.startswith("Comment:"): + tp_comment = line[8:].strip() + tp_current = 2 + elif line.startswith("Copyright:"): + tp_copyright = line[10:].strip() + tp_current = 3 + elif line.startswith("License:"): + if tp_current != 0: + tp_license = line[8:].strip() + tp_current = 4 + else: + tp_licensename = line[8:].strip() + tp_current = 5 + elif line.startswith(" "): + if tp_current == 1: + tp_file += "\n" + line.strip() + elif tp_current == 3: + tp_copyright += "\n" + line.strip() + elif tp_current == 5: + if line.strip() == ".": + tp_licensebody += "\n" + else: + tp_licensebody += line[1:] + else: + if tp_current != 0: + if tp_current == 5: + tp_licensetext.append([tp_licensename, tp_licensebody]) + + tp_licensename = "" + tp_licensebody = "" + else: + added = False + for i in tp: + if i[0] == tp_comment: + i[1].append([tp_file, tp_copyright, tp_license]) + added = True + break + if not added: + tp.append([tp_comment,[[tp_file, tp_copyright, tp_license]]]) + + tp_file = [] + tp_comment = "" + tp_copyright = [] + tp_license = "" + tp_current = 0 + + tp_licensetext.append([tp_licensename, tp_licensebody]) + + about_thirdparty = "" + about_tp_copyright_count = "" + about_tp_license = "" + about_tp_copyright = "" + about_tp_file = "" + + for i in tp: + about_thirdparty += "\t\"" + i[0] + "\",\n" + about_tp_copyright_count += str(len(i[1])) + ", " + for j in i[1]: + file_body = "" + copyright_body = "" + for k in j[0].split("\n"): + if file_body != "": + file_body += "\\n\"\n" + escaped_string = escape_string(k.strip()) + file_body += "\t\"" + escaped_string + for k in j[1].split("\n"): + if copyright_body != "": + copyright_body += "\\n\"\n" + escaped_string = escape_string(k.strip()) + copyright_body += "\t\"" + escaped_string + + about_tp_file += "\t" + file_body + "\",\n" + about_tp_copyright += "\t" + copyright_body + "\",\n" + about_tp_license += "\t\"" + j[2] + "\",\n" + + about_license_name = "" + about_license_body = "" + + for i in tp_licensetext: + body = "" + for j in i[1].split("\n"): + if body != "": + body += "\\n\"\n" + escaped_string = escape_string(j.strip()) + body += "\t\"" + escaped_string + + about_license_name += "\t\"" + i[0] + "\",\n" + about_license_body += "\t" + body + "\",\n" + + g.write("static const char *about_thirdparty[] = {\n") + g.write(about_thirdparty) + g.write("\t0\n") + g.write("};\n") + g.write("#define THIRDPARTY_COUNT " + str(len(tp)) + "\n") + + g.write("static const int about_tp_copyright_count[] = {\n\t") + g.write(about_tp_copyright_count) + g.write("0\n};\n") + + g.write("static const char *about_tp_file[] = {\n") + g.write(about_tp_file) + g.write("\t0\n") + g.write("};\n") + + g.write("static const char *about_tp_copyright[] = {\n") + g.write(about_tp_copyright) + g.write("\t0\n") + g.write("};\n") + + g.write("static const char *about_tp_license[] = {\n") + g.write(about_tp_license) + g.write("\t0\n") + g.write("};\n") + + g.write("static const char *about_license_name[] = {\n") + g.write(about_license_name) + g.write("\t0\n") + g.write("};\n") + g.write("#define LICENSE_COUNT " + str(len(tp_licensetext)) + "\n") + + g.write("static const char *about_license_body[] = {\n") + g.write(about_license_body) + g.write("\t0\n") + g.write("};\n") + + g.write("#endif\n") + + g.close() + fc.close() + f.close() + + +if __name__ == '__main__': + subprocess_main(globals()) diff --git a/editor/editor_properties.cpp b/editor/editor_properties.cpp index 4fae8467b4..79490f1c8e 100644 --- a/editor/editor_properties.cpp +++ b/editor/editor_properties.cpp @@ -568,6 +568,7 @@ public: uint32_t value; Vector<Rect2> flag_rects; Vector<String> names; + Vector<String> tooltips; virtual Size2 get_minimum_size() const { Ref<Font> font = get_font("font", "Label"); @@ -576,8 +577,8 @@ public: virtual String get_tooltip(const Point2 &p_pos) const { for (int i = 0; i < flag_rects.size(); i++) { - if (i < names.size() && flag_rects[i].has_point(p_pos)) { - return names[i]; + if (i < tooltips.size() && flag_rects[i].has_point(p_pos)) { + return tooltips[i]; } } return String(); @@ -681,6 +682,7 @@ void EditorPropertyLayers::setup(LayerType p_layer_type) { } Vector<String> names; + Vector<String> tooltips; for (int i = 0; i < 20; i++) { String name; @@ -692,12 +694,12 @@ void EditorPropertyLayers::setup(LayerType p_layer_type) { name = TTR("Layer") + " " + itos(i + 1); } - name += "\n" + vformat(TTR("Bit %d, value %d"), i, 1 << i); - names.push_back(name); + tooltips.push_back(name + "\n" + vformat(TTR("Bit %d, value %d"), i, 1 << i)); } grid->names = names; + grid->tooltips = tooltips; } void EditorPropertyLayers::_button_pressed() { diff --git a/editor/icons/SCsub b/editor/icons/SCsub index 7f94073e01..31bf8f116a 100644 --- a/editor/icons/SCsub +++ b/editor/icons/SCsub @@ -1,96 +1,14 @@ #!/usr/bin/env python Import('env') -from compat import StringIO +from platform_methods import run_in_subprocess +import editor_icons_builders -def make_editor_icons_action(target, source, env): - import os - - dst = target[0].srcnode().abspath - svg_icons = source - - icons_string = StringIO() - - for f in svg_icons: - - fname = str(f) - - icons_string.write('\t"') - - with open(fname, 'rb') as svgf: - b = svgf.read(1) - while(len(b) == 1): - icons_string.write("\\" + str(hex(ord(b)))[1:]) - b = svgf.read(1) - - - icons_string.write('"') - if fname != svg_icons[-1]: - icons_string.write(",") - icons_string.write('\n') - - s = StringIO() - s.write("/* THIS FILE IS GENERATED DO NOT EDIT */\n") - s.write("#ifndef _EDITOR_ICONS_H\n") - s.write("#define _EDITOR_ICONS_H\n") - s.write("static const int editor_icons_count = {};\n".format(len(svg_icons))) - s.write("static const char *editor_icons_sources[] = {\n") - s.write(icons_string.getvalue()) - s.write('};\n\n') - s.write("static const char *editor_icons_names[] = {\n") - - # this is used to store the indices of thumbnail icons - thumb_medium_indices = []; - thumb_big_indices = []; - index = 0 - for f in svg_icons: - - fname = str(f) - - icon_name = os.path.basename(fname)[5:-4].title().replace("_", "") - # some special cases - if icon_name in ['Int', 'Bool', 'Float']: - icon_name = icon_name.lower() - if icon_name.endswith("MediumThumb"): # don't know a better way to handle this - thumb_medium_indices.append(str(index)) - if icon_name.endswith("BigThumb"): # don't know a better way to handle this - thumb_big_indices.append(str(index)) - - s.write('\t"{0}"'.format(icon_name)) - - if fname != svg_icons[-1]: - s.write(",") - s.write('\n') - - index += 1 - - s.write('};\n') - - if thumb_medium_indices: - s.write("\n\n") - s.write("static const int editor_md_thumbs_count = {};\n".format(len(thumb_medium_indices))) - s.write("static const int editor_md_thumbs_indices[] = {") - s.write(", ".join(thumb_medium_indices)) - s.write("};\n") - if thumb_big_indices: - s.write("\n\n") - s.write("static const int editor_bg_thumbs_count = {};\n".format(len(thumb_big_indices))) - s.write("static const int editor_bg_thumbs_indices[] = {") - s.write(", ".join(thumb_big_indices)) - s.write("};\n") - - s.write("#endif\n") - - with open(dst, "w") as f: - f.write(s.getvalue()) - - s.close() - icons_string.close() - -make_editor_icons_builder = Builder(action=make_editor_icons_action, +make_editor_icons_builder = Builder(action=run_in_subprocess(editor_icons_builders.make_editor_icons_action), suffix='.h', src_suffix='.svg') + env['BUILDERS']['MakeEditorIconsBuilder'] = make_editor_icons_builder env.Alias('editor_icons', [env.MakeEditorIconsBuilder('#editor/editor_icons.gen.h', Glob("*.svg"))]) diff --git a/editor/icons/editor_icons_builders.py b/editor/icons/editor_icons_builders.py new file mode 100644 index 0000000000..dfd0802ce9 --- /dev/null +++ b/editor/icons/editor_icons_builders.py @@ -0,0 +1,96 @@ +"""Functions used to generate source files during build time + +All such functions are invoked in a subprocess on Windows to prevent build flakiness. + +""" +import os +from platform_methods import subprocess_main +from compat import StringIO + + +def make_editor_icons_action(target, source, env): + + dst = target[0] + svg_icons = source + + icons_string = StringIO() + + for f in svg_icons: + + fname = str(f) + + icons_string.write('\t"') + + with open(fname, 'rb') as svgf: + b = svgf.read(1) + while(len(b) == 1): + icons_string.write("\\" + str(hex(ord(b)))[1:]) + b = svgf.read(1) + + + icons_string.write('"') + if fname != svg_icons[-1]: + icons_string.write(",") + icons_string.write('\n') + + s = StringIO() + s.write("/* THIS FILE IS GENERATED DO NOT EDIT */\n") + s.write("#ifndef _EDITOR_ICONS_H\n") + s.write("#define _EDITOR_ICONS_H\n") + s.write("static const int editor_icons_count = {};\n".format(len(svg_icons))) + s.write("static const char *editor_icons_sources[] = {\n") + s.write(icons_string.getvalue()) + s.write('};\n\n') + s.write("static const char *editor_icons_names[] = {\n") + + # this is used to store the indices of thumbnail icons + thumb_medium_indices = []; + thumb_big_indices = []; + index = 0 + for f in svg_icons: + + fname = str(f) + + icon_name = os.path.basename(fname)[5:-4].title().replace("_", "") + # some special cases + if icon_name in ['Int', 'Bool', 'Float']: + icon_name = icon_name.lower() + if icon_name.endswith("MediumThumb"): # don't know a better way to handle this + thumb_medium_indices.append(str(index)) + if icon_name.endswith("BigThumb"): # don't know a better way to handle this + thumb_big_indices.append(str(index)) + + s.write('\t"{0}"'.format(icon_name)) + + if fname != svg_icons[-1]: + s.write(",") + s.write('\n') + + index += 1 + + s.write('};\n') + + if thumb_medium_indices: + s.write("\n\n") + s.write("static const int editor_md_thumbs_count = {};\n".format(len(thumb_medium_indices))) + s.write("static const int editor_md_thumbs_indices[] = {") + s.write(", ".join(thumb_medium_indices)) + s.write("};\n") + if thumb_big_indices: + s.write("\n\n") + s.write("static const int editor_bg_thumbs_count = {};\n".format(len(thumb_big_indices))) + s.write("static const int editor_bg_thumbs_indices[] = {") + s.write(", ".join(thumb_big_indices)) + s.write("};\n") + + s.write("#endif\n") + + with open(dst, "w") as f: + f.write(s.getvalue()) + + s.close() + icons_string.close() + + +if __name__ == '__main__': + subprocess_main(globals()) |