1
0
mirror of https://github.com/godotengine/godot.git synced 2025-11-30 16:26:50 +00:00
This commit is contained in:
Juan Linietsky
2015-10-17 10:30:08 -03:00
75 changed files with 3541 additions and 504 deletions

Binary file not shown.

View File

@@ -0,0 +1,142 @@
# Translations template for PROJECT.
# Copyright (C) 2015 ORGANIZATION
# This file is distributed under the same license as the PROJECT project.
# FIRST AUTHOR <EMAIL@ADDRESS>, 2015.
#
msgid ""
msgstr ""
"Project-Id-Version: makedocs\n"
"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n"
"POT-Creation-Date: 2015-10-07 11:47-0600\n"
"PO-Revision-Date: 2015-10-07 13:10-0600\n"
"Last-Translator: Jorge Araya Navarro <elcorreo@deshackra.com>\n"
"Language-Team: \n"
"Language: es\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Generated-By: Babel 2.0\n"
"X-Generator: Poedit 1.8.4\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
#: makedocs.py:74
msgid ""
"\"<code>{gclass}</code>(Go to page of class {gclass})\":/class_{lkclass}"
msgstr ""
"\"<code>{gclass}</code>(Ir a la pagina de la clase {gclass})\":/"
"class_{lkclass}"
#: makedocs.py:76
msgid ""
"\"<code>{gclass}.{method}</code>(Go to page {gclass}, section {method})\":/"
"class_{lkclass}#{lkmethod}"
msgstr ""
"\"<code>{gclass}.{method}</code>(Ir a la pagina {gclass}, sección "
"{method})\":/class_{lkclass}#{lkmethod}"
#: makedocs.py:79
msgid "\"<code>{method}</code>(Jump to method {method})\":#{lkmethod}"
msgstr "\"<code>{method}</code>(Saltar al método {method})\":#{lkmethod}"
#: makedocs.py:81
msgid " \"{rtype}(Go to page of class {rtype})\":/class_{link} "
msgstr " \"{rtype}(Ir a la pagina de la clase {rtype})\":/class_{link} "
#: makedocs.py:82
msgid ""
"\"*{funcname}*(Jump to description for node {funcname})\":#{link} <b>(</b> "
msgstr ""
"\"*{funcname}*(Saltar a la descripción para el nodo {funcname})\":#{link} "
"<b>(</b> "
#: makedocs.py:87
msgid "h4. Inherits: "
msgstr "h4. Hereda de: "
#: makedocs.py:232
msgid "<doc>'s version attribute missing"
msgstr "El atributo version de <doc> no existe"
#: makedocs.py:246
msgid "|_. Index symbol |_. Class name |_. Index symbol |_. Class name |\n"
msgstr ""
"|_. Índice de símbolo |_. Nombre de la clase |_. Índice de símbolo |_. "
"Nombre de la clase |\n"
#: makedocs.py:305
msgid ""
"h4. Category: {}\n"
"\n"
msgstr ""
"h4. Categoría: {}\n"
"\n"
#: makedocs.py:310
msgid ""
"h2. Brief Description\n"
"\n"
msgstr ""
"h2. Descripción breve\n"
"\n"
#: makedocs.py:312
msgid ""
"\"read more\":#more\n"
"\n"
msgstr ""
"\"Leer más\":#more\n"
"\n"
#: makedocs.py:317
msgid ""
"\n"
"h3. Member Functions\n"
"\n"
msgstr ""
"\n"
"h3. Funciones miembro\n"
"\n"
#: makedocs.py:323
msgid ""
"\n"
"h3. Signals\n"
"\n"
msgstr ""
"\n"
"h3. Señales\n"
"\n"
#: makedocs.py:331
msgid ""
"\n"
"h3. Numeric Constants\n"
"\n"
msgstr ""
"\n"
"h3. Constantes numéricas\n"
"\n"
#: makedocs.py:347
msgid ""
"\n"
"h3(#more). Description\n"
"\n"
msgstr ""
"\n"
"h3(#more). Descripción\n"
"\n"
#: makedocs.py:351
msgid "_Nothing here, yet..._\n"
msgstr "_Aún nada por aquí..._\n"
#: makedocs.py:355
msgid ""
"\n"
"h3. Member Function Description\n"
"\n"
msgstr ""
"\n"
"h3. Descripción de las funciones miembro\n"
"\n"

108
tools/docdump/makedocs.pot Normal file
View File

@@ -0,0 +1,108 @@
# Translations template for PROJECT.
# Copyright (C) 2015 ORGANIZATION
# This file is distributed under the same license as the PROJECT project.
# FIRST AUTHOR <EMAIL@ADDRESS>, 2015.
#
#, fuzzy
msgid ""
msgstr ""
"Project-Id-Version: makedocs 0.1\n"
"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n"
"POT-Creation-Date: 2015-10-07 11:47-0600\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Generated-By: Babel 2.0\n"
"X-Generator: Poedit 1.8.4\n"
#: makedocs.py:74
msgid "\"<code>{gclass}</code>(Go to page of class {gclass})\":/class_{lkclass}"
msgstr ""
#: makedocs.py:76
msgid "\"<code>{gclass}.{method}</code>(Go to page {gclass}, section {method})\":/class_{lkclass}#{lkmethod}"
msgstr ""
#: makedocs.py:79
msgid "\"<code>{method}</code>(Jump to method {method})\":#{lkmethod}"
msgstr ""
#: makedocs.py:81
msgid " \"{rtype}(Go to page of class {rtype})\":/class_{link} "
msgstr ""
#: makedocs.py:82
msgid "\"*{funcname}*(Jump to description for node {funcname})\":#{link} <b>(</b> "
msgstr ""
#: makedocs.py:87
msgid "h4. Inherits: "
msgstr ""
#: makedocs.py:232
msgid "<doc>'s version attribute missing"
msgstr ""
#: makedocs.py:246
msgid "|_. Index symbol |_. Class name |_. Index symbol |_. Class name |\n"
msgstr ""
#: makedocs.py:305
msgid ""
"h4. Category: {}\n"
"\n"
msgstr ""
#: makedocs.py:310
msgid ""
"h2. Brief Description\n"
"\n"
msgstr ""
#: makedocs.py:312
msgid ""
"\"read more\":#more\n"
"\n"
msgstr ""
#: makedocs.py:317
msgid ""
"\n"
"h3. Member Functions\n"
"\n"
msgstr ""
#: makedocs.py:323
msgid ""
"\n"
"h3. Signals\n"
"\n"
msgstr ""
#: makedocs.py:331
msgid ""
"\n"
"h3. Numeric Constants\n"
"\n"
msgstr ""
#: makedocs.py:347
msgid ""
"\n"
"h3(#more). Description\n"
"\n"
msgstr ""
#: makedocs.py:351
msgid "_Nothing here, yet..._\n"
msgstr ""
#: makedocs.py:355
msgid ""
"\n"
"h3. Member Function Description\n"
"\n"
msgstr ""

382
tools/docdump/makedocs.py Normal file
View File

@@ -0,0 +1,382 @@
#!/usr/bin/python3
# -*- coding: utf-8 -*-
#
# makedocs.py: Generate documentation for Open Project Wiki
# Copyright (c) 2007-2015 Juan Linietsky, Ariel Manzur.
# Contributor: Jorge Araya Navarro <elcorreo@deshackra.com>
#
# IMPORTANT NOTICE:
# If you are going to modify anything from this file, please be sure to follow
# the Style Guide for Python Code or often called "PEP8". To do this
# automagically just install autopep8:
#
# $ sudo pip3 install autopep8
#
# and run:
#
# $ autopep8 makedocs.py
#
# Before committing your changes. Also be sure to delete any trailing
# whitespace you may left.
#
# TODO:
# * Refactor code.
# * Adapt this script for generating content in other markup formats like
# DokuWiki, Markdown, etc.
#
# Also check other TODO entries in this script for more information on what is
# left to do.
import argparse
import gettext
import logging
import re
from itertools import zip_longest
from os import path, listdir
from xml.etree import ElementTree
# add an option to change the verbosity
logging.basicConfig(level=logging.INFO)
def getxmlfloc():
""" Returns the supposed location of the XML file
"""
filepath = path.dirname(path.abspath(__file__))
return path.join(filepath, "class_list.xml")
def langavailable():
""" Return a list of languages available for translation
"""
filepath = path.join(
path.dirname(path.abspath(__file__)), "locales")
files = listdir(filepath)
choices = [x for x in files]
choices.insert(0, "none")
return choices
desc = "Generates documentation from a XML file to different markup languages"
parser = argparse.ArgumentParser(description=desc)
parser.add_argument("--input", dest="xmlfp", default=getxmlfloc(),
help="Input XML file, default: {}".format(getxmlfloc()))
parser.add_argument("--output-dir", dest="outputdir", required=True,
help="Output directory for generated files")
parser.add_argument("--language", choices=langavailable(), default="none",
help=("Choose the language of translation"
" for the output files. Default is English (none). "
"Note: This is NOT for the documentation itself!"))
# TODO: add an option for outputting different markup formats
args = parser.parse_args()
# Let's check if the file and output directory exists
if not path.isfile(args.xmlfp):
logging.critical("File not found: {}".format(args.xmlfp))
exit(1)
elif not path.isdir(args.outputdir):
logging.critical("Path does not exist: {}".format(args.outputdir))
exit(1)
_ = gettext.gettext
if args.language != "none":
lang = gettext.translation(domain="makedocs",
localedir="locales",
languages=[args.language])
lang.install()
_ = lang.gettext
# Strings
C_LINK = _("\"<code>{gclass}</code>(Go to page of class"
" {gclass})\":/class_{lkclass}")
MC_LINK = _("\"<code>{gclass}.{method}</code>(Go "
"to page {gclass}, section {method})\""
":/class_{lkclass}#{lkmethod}")
TM_JUMP = _("\"<code>{method}</code>(Jump to method"
" {method})\":#{lkmethod}")
GTC_LINK = _(" \"{rtype}(Go to page of class {rtype})\":/class_{link} ")
DFN_JUMP = _("\"*{funcname}*(Jump to description for"
" node {funcname})\":#{link} <b>(</b> ")
M_ARG_DEFAULT = C_LINK + " {name}={default}"
M_ARG = C_LINK + " {name}"
OPENPROJ_INH = _("h4. Inherits: ") + C_LINK + "\n\n"
def tb(string):
""" Return a byte representation of a string
"""
return bytes(string, "UTF-8")
def sortkey(c):
""" Symbols are first, letters second
"""
if "_" == c.attrib["name"][0]:
return "A"
else:
return c.attrib["name"]
def toOP(text):
""" Convert commands in text to Open Project commands
"""
# TODO: Make this capture content between [command] ... [/command]
groups = re.finditer((r'\[html (?P<command>/?\w+/?)(\]| |=)?(\]| |=)?(?P<a'
'rg>\w+)?(\]| |=)?(?P<value>"[^"]+")?/?\]'), text)
alignstr = ""
for group in groups:
gd = group.groupdict()
if gd["command"] == "br/":
text = text.replace(group.group(0), "\n\n", 1)
elif gd["command"] == "div":
if gd["value"] == '"center"':
alignstr = ("{display:block; margin-left:auto;"
" margin-right:auto;}")
elif gd["value"] == '"left"':
alignstr = "<"
elif gd["value"] == '"right"':
alignstr = ">"
text = text.replace(group.group(0), "\n\n", 1)
elif gd["command"] == "/div":
alignstr = ""
text = text.replace(group.group(0), "\n\n", 1)
elif gd["command"] == "img":
text = text.replace(group.group(0), "!{align}{src}!".format(
align=alignstr, src=gd["value"].strip('"')), 1)
elif gd["command"] == "b" or gd["command"] == "/b":
text = text.replace(group.group(0), "*", 1)
elif gd["command"] == "i" or gd["command"] == "/i":
text = text.replace(group.group(0), "_", 1)
elif gd["command"] == "u" or gd["command"] == "/u":
text = text.replace(group.group(0), "+", 1)
# Process other non-html commands
groups = re.finditer((r'\[method ((?P<class>[aA0-zZ9_]+)(?:\.))'
r'?(?P<method>[aA0-zZ9_]+)\]'), text)
for group in groups:
gd = group.groupdict()
if gd["class"]:
replacewith = (MC_LINK.format(gclass=gd["class"],
method=gd["method"],
lkclass=gd["class"].lower(),
lkmethod=gd["method"].lower()))
else:
# The method is located in the same wiki page
replacewith = (TM_JUMP.format(method=gd["method"],
lkmethod=gd["method"].lower()))
text = text.replace(group.group(0), replacewith, 1)
# Finally, [Classes] are around brackets, make them direct links
groups = re.finditer(r'\[(?P<class>[az0-AZ0_]+)\]', text)
for group in groups:
gd = group.groupdict()
replacewith = (C_LINK.
format(gclass=gd["class"],
lkclass=gd["class"].lower()))
text = text.replace(group.group(0), replacewith, 1)
return text + "\n\n"
def mkfn(node, is_signal=False):
""" Return a string containing a unsorted item for a function
"""
finalstr = ""
name = node.attrib["name"]
rtype = node.find("return")
if rtype:
rtype = rtype.attrib["type"]
else:
rtype = "void"
# write the return type and the function name first
finalstr += "* "
# return type
if not is_signal:
if rtype != "void":
finalstr += GTC_LINK.format(
rtype=rtype,
link=rtype.lower())
else:
finalstr += " void "
# function name
if not is_signal:
finalstr += DFN_JUMP.format(
funcname=name,
link=name.lower())
else:
# Signals have no description
finalstr += "*{funcname}* <b>(</b>".format(funcname=name)
# loop for the arguments of the function, if any
args = []
for arg in sorted(
node.iter(tag="argument"),
key=lambda a: int(a.attrib["index"])):
ntype = arg.attrib["type"]
nname = arg.attrib["name"]
if "default" in arg.attrib:
args.insert(-1, M_ARG_DEFAULT.format(
gclass=ntype,
lkclass=ntype.lower(),
name=nname,
default=arg.attrib["default"]))
else:
# No default value present
args.insert(-1, M_ARG.format(gclass=ntype,
lkclass=ntype.lower(), name=nname))
# join the arguments together
finalstr += ", ".join(args)
# and, close the function with a )
finalstr += " <b>)</b>"
# write the qualifier, if any
if "qualifiers" in node.attrib:
qualifier = node.attrib["qualifiers"]
finalstr += " " + qualifier
finalstr += "\n"
return finalstr
# Let's begin
tree = ElementTree.parse(args.xmlfp)
root = tree.getroot()
# Check version attribute exists in <doc>
if "version" not in root.attrib:
logging.critical(_("<doc>'s version attribute missing"))
exit(1)
version = root.attrib["version"]
classes = sorted(root, key=sortkey)
# first column is always longer, second column of classes should be shorter
zclasses = zip_longest(classes[:int(len(classes) / 2 + 1)],
classes[int(len(classes) / 2 + 1):],
fillvalue="")
# We write the class_list file and also each class file at once
with open(path.join(args.outputdir, "class_list.txt"), "wb") as fcl:
# Write header of table
fcl.write(tb("|^.\n"))
fcl.write(tb(_("|_. Index symbol |_. Class name "
"|_. Index symbol |_. Class name |\n")))
fcl.write(tb("|-.\n"))
indexletterl = ""
indexletterr = ""
for gdclassl, gdclassr in zclasses:
# write a row #
# write the index symbol column, left
if indexletterl != gdclassl.attrib["name"][0]:
indexletterl = gdclassl.attrib["name"][0]
fcl.write(tb("| *{}* |".format(indexletterl.upper())))
else:
# empty cell
fcl.write(tb("| |"))
# write the class name column, left
fcl.write(tb(C_LINK.format(
gclass=gdclassl.attrib["name"],
lkclass=gdclassl.attrib["name"].lower())))
# write the index symbol column, right
if isinstance(gdclassr, ElementTree.Element):
if indexletterr != gdclassr.attrib["name"][0]:
indexletterr = gdclassr.attrib["name"][0]
fcl.write(tb("| *{}* |".format(indexletterr.upper())))
else:
# empty cell
fcl.write(tb("| |"))
# We are dealing with an empty string
else:
# two empty cell
fcl.write(tb("| | |\n"))
# We won't get the name of the class since there is no ElementTree
# object for the right side of the tuple, so we iterate the next
# tuple instead
continue
# write the class name column (if any), right
fcl.write(tb(C_LINK.format(
gclass=gdclassl.attrib["name"],
lkclass=gdclassl.attrib["name"].lower()) + "|\n"))
# row written #
# now, let's write each class page for each class
for gdclass in [gdclassl, gdclassr]:
if not isinstance(gdclass, ElementTree.Element):
continue
classname = gdclass.attrib["name"]
with open(path.join(args.outputdir, "{}.txt".format(
classname.lower())), "wb") as clsf:
# First level header with the name of the class
clsf.write(tb("h1. {}\n\n".format(classname)))
# lay the attributes
if "inherits" in gdclass.attrib:
inh = gdclass.attrib["inherits"].strip()
clsf.write(tb(OPENPROJ_INH.format(gclass=inh,
lkclass=inh.lower())))
if "category" in gdclass.attrib:
clsf.write(tb(_("h4. Category: {}\n\n").
format(gdclass.attrib["category"].strip())))
# lay child nodes
briefd = gdclass.find("brief_description")
if briefd.text.strip():
clsf.write(tb(_("h2. Brief Description\n\n")))
clsf.write(tb(toOP(briefd.text.strip()) +
_("\"read more\":#more\n\n")))
# Write the list of member functions of this class
methods = gdclass.find("methods")
if methods and len(methods) > 0:
clsf.write(tb(_("\nh3. Member Functions\n\n")))
for method in methods.iter(tag='method'):
clsf.write(tb(mkfn(method)))
signals = gdclass.find("signals")
if signals and len(signals) > 0:
clsf.write(tb(_("\nh3. Signals\n\n")))
for signal in signals.iter(tag='signal'):
clsf.write(tb(mkfn(signal, True)))
# TODO: <members> tag is necessary to process? it does not
# exists in class_list.xml file.
consts = gdclass.find("constants")
if consts and len(consts) > 0:
clsf.write(tb(_("\nh3. Numeric Constants\n\n")))
for const in sorted(consts, key=lambda k:
k.attrib["name"]):
if const.text.strip():
clsf.write(tb("* *{name}* = *{value}* - {desc}\n".
format(
name=const.attrib["name"],
value=const.attrib["value"],
desc=const.text.strip())))
else:
# Constant have no description
clsf.write(tb("* *{name}* = *{value}*\n".
format(
name=const.attrib["name"],
value=const.attrib["value"])))
descrip = gdclass.find("description")
clsf.write(tb(_("\nh3(#more). Description\n\n")))
if descrip.text:
clsf.write(tb(descrip.text.strip() + "\n"))
else:
clsf.write(tb(_("_Nothing here, yet..._\n")))
# and finally, the description for each method
if methods and len(methods) > 0:
clsf.write(tb(_("\nh3. Member Function Description\n\n")))
for method in methods.iter(tag='method'):
clsf.write(tb("h4(#{n}). {name}\n\n".format(
n=method.attrib["name"].lower(),
name=method.attrib["name"])))
clsf.write(tb(mkfn(method) + "\n"))
clsf.write(tb(toOP(method.find(
"description").text.strip())))

View File

@@ -547,6 +547,7 @@ Error EditorHelp::_goto_desc(const String& p_class,bool p_update_history,int p_v
class_desc->pop();
class_desc->add_newline();
class_desc->add_newline();
class_desc->add_newline();
}
@@ -563,6 +564,7 @@ Error EditorHelp::_goto_desc(const String& p_class,bool p_update_history,int p_v
_add_text(cd.brief_description);
class_desc->add_newline();
class_desc->add_newline();
class_desc->add_newline();
}
bool method_descr=false;
@@ -637,7 +639,6 @@ Error EditorHelp::_goto_desc(const String& p_class,bool p_update_history,int p_v
if (cd.properties.size()) {
class_desc->push_color(EditorSettings::get_singleton()->get("text_editor/keyword_color"));
class_desc->push_font(doc_title_font);
class_desc->add_text("Members:");
@@ -715,9 +716,10 @@ Error EditorHelp::_goto_desc(const String& p_class,bool p_update_history,int p_v
class_desc->add_newline();
}
class_desc->add_newline();
class_desc->pop();
class_desc->add_newline();
class_desc->add_newline();
}
if (cd.signals.size()) {
@@ -779,6 +781,7 @@ Error EditorHelp::_goto_desc(const String& p_class,bool p_update_history,int p_v
class_desc->pop();
class_desc->add_newline();
class_desc->add_newline();
}
@@ -823,6 +826,7 @@ Error EditorHelp::_goto_desc(const String& p_class,bool p_update_history,int p_v
class_desc->pop();
class_desc->add_newline();
class_desc->add_newline();
}
@@ -830,17 +834,18 @@ Error EditorHelp::_goto_desc(const String& p_class,bool p_update_history,int p_v
if (cd.description!="") {
description_line=class_desc->get_line_count()-2;
class_desc->push_color(EditorSettings::get_singleton()->get("text_editor/keyword_color"));
class_desc->push_font(doc_title_font);
class_desc->add_text("Description:");
class_desc->pop();
class_desc->pop();
class_desc->add_newline();
class_desc->add_newline();
_add_text(cd.description);
class_desc->add_newline();
class_desc->add_newline();
class_desc->add_newline();
}
if (method_descr) {
@@ -853,12 +858,16 @@ Error EditorHelp::_goto_desc(const String& p_class,bool p_update_history,int p_v
class_desc->add_newline();
class_desc->add_newline();
class_desc->push_indent(1);
for(int i=0;i<cd.methods.size();i++) {
method_line[cd.methods[i].name]=class_desc->get_line_count()-2;
if( cd.methods[i].description != "") {
class_desc->add_newline();
}
class_desc->push_font(doc_code_font);
_add_type(cd.methods[i].return_type);
@@ -899,9 +908,12 @@ Error EditorHelp::_goto_desc(const String& p_class,bool p_update_history,int p_v
class_desc->pop();
class_desc->add_newline();
class_desc->add_newline();
_add_text(cd.methods[i].description);
if( cd.methods[i].description != "") {
class_desc->add_text(" ");
_add_text(cd.methods[i].description);
class_desc->add_newline();
class_desc->add_newline();
}
class_desc->add_newline();
class_desc->add_newline();
@@ -1392,6 +1404,8 @@ EditorHelp::EditorHelp(EditorNode *p_editor) {
PanelContainer *pc = memnew( PanelContainer );
Ref<StyleBoxFlat> style( memnew( StyleBoxFlat ) );
style->set_bg_color( EditorSettings::get_singleton()->get("text_editor/background_color") );
style->set_default_margin(MARGIN_LEFT,20);
style->set_default_margin(MARGIN_TOP,20);
pc->add_style_override("panel", style); //get_stylebox("normal","TextEdit"));
h_split->add_child(pc);
class_desc = memnew( RichTextLabel );

View File

@@ -1108,6 +1108,11 @@ void EditorNode::_dialog_action(String p_file) {
push_item(res.operator->() );
} break;
case FILE_NEW_INHERITED_SCENE: {
load_scene(p_file,false,true);
} break;
case FILE_OPEN_SCENE: {
@@ -1931,6 +1936,7 @@ void EditorNode::_menu_option_confirm(int p_option,bool p_confirmed) {
} break;
case FILE_NEW_INHERITED_SCENE:
case FILE_OPEN_SCENE: {
@@ -1951,7 +1957,7 @@ void EditorNode::_menu_option_confirm(int p_option,bool p_confirmed) {
if (scene) {
file->set_current_path(scene->get_filename());
};
file->set_title("Open Scene");
file->set_title(p_option==FILE_OPEN_SCENE?"Open Scene":"Open Base Scene");
file->popup_centered_ratio();
} break;
@@ -3312,7 +3318,7 @@ void EditorNode::fix_dependencies(const String& p_for_file) {
dependency_fixer->edit(p_for_file);
}
Error EditorNode::load_scene(const String& p_scene, bool p_ignore_broken_deps) {
Error EditorNode::load_scene(const String& p_scene, bool p_ignore_broken_deps,bool p_set_inherited) {
if (!is_inside_tree()) {
defer_load_scene = p_scene;
@@ -3442,6 +3448,13 @@ Error EditorNode::load_scene(const String& p_scene, bool p_ignore_broken_deps) {
}
*/
if (p_set_inherited) {
Ref<SceneState> state = sdata->get_state();
state->set_path(lpath);
new_scene->set_scene_inherited_state(state);
}
set_edited_scene(new_scene);
_get_scene_metadata();
/*
@@ -4404,6 +4417,7 @@ void EditorNode::_scene_tab_changed(int p_tab) {
EditorNode::EditorNode() {
EditorHelp::generate_doc(); //before any editor classes are crated
SceneState::set_disable_placeholders(true);
InputDefault *id = Input::get_singleton()->cast_to<InputDefault>();
@@ -4794,6 +4808,7 @@ EditorNode::EditorNode() {
file_menu->set_tooltip("Operations with scene files.");
p=file_menu->get_popup();
p->add_item("New Scene",FILE_NEW_SCENE);
p->add_item("New Inherited Scene..",FILE_NEW_INHERITED_SCENE);
p->add_item("Open Scene..",FILE_OPEN_SCENE,KEY_MASK_CMD+KEY_O);
p->add_separator();
p->add_item("Save Scene",FILE_SAVE_SCENE,KEY_MASK_CMD+KEY_S);

View File

@@ -107,6 +107,7 @@ class EditorNode : public Node {
enum MenuOptions {
FILE_NEW_SCENE,
FILE_NEW_INHERITED_SCENE,
FILE_OPEN_SCENE,
FILE_SAVE_SCENE,
FILE_SAVE_AS_SCENE,
@@ -565,7 +566,7 @@ public:
void fix_dependencies(const String& p_for_file);
void clear_scene() { _cleanup_scene(); }
Error load_scene(const String& p_scene,bool p_ignore_broken_deps=false);
Error load_scene(const String& p_scene, bool p_ignore_broken_deps=false, bool p_set_inherited=false);
Error load_resource(const String& p_scene);
bool is_scene_open(const String& p_path);

View File

@@ -74,6 +74,7 @@ void EditorPlugin::add_custom_control(CustomControlContainer p_location,Control
case CONTAINER_CANVAS_EDITOR_SIDE: {
CanvasItemEditor::get_singleton()->get_palette_split()->add_child(p_control);
CanvasItemEditor::get_singleton()->get_palette_split()->move_child(p_control,0);
} break;
case CONTAINER_CANVAS_EDITOR_BOTTOM: {

View File

@@ -710,7 +710,7 @@ void EditorSampleImportPlugin::_compress_ima_adpcm(const Vector<float>& p_data,D
*(out++) =0;
for (i=0;i<datalen;i++) {
int step,diff,vpdiff,signed_nibble,p,mask;
int step,diff,vpdiff,mask;
uint8_t nibble;
int16_t xm_sample;

View File

@@ -42,6 +42,8 @@
#include "multi_node_edit.h"
#include "array_property_edit.h"
#include "editor_help.h"
#include "scene/resources/packed_scene.h"
void CustomPropertyEditor::_notification(int p_what) {
@@ -1655,25 +1657,101 @@ CustomPropertyEditor::CustomPropertyEditor() {
menu->connect("item_pressed",this,"_menu_option");
}
bool PropertyEditor::_might_be_in_instance() {
Node *PropertyEditor::get_instanced_node() {
//this sucks badly
if (!obj)
return NULL;
Node *node = obj->cast_to<Node>();
Node* edited_scene =EditorNode::get_singleton()->get_edited_scene();
bool might_be=false;
while(node) {
if (node->get_scene_instance_state().is_valid()) {
might_be=true;
break;
}
if (node==edited_scene) {
if (node->get_scene_inherited_state().is_valid()) {
might_be=true;
break;
}
might_be=false;
break;
}
node=node->get_owner();
}
return might_be;
}
bool PropertyEditor::_get_instanced_node_original_property(const StringName& p_prop,Variant& value) {
Node *node = obj->cast_to<Node>();
if (!node)
return NULL;
return false;
if (node->get_filename()=="")
return NULL;
Node *orig=node;
if (!node->get_owner())
return NULL; //scene root i guess
Node* edited_scene =EditorNode::get_singleton()->get_edited_scene();
return node;
bool found=false;
// print_line("for prop - "+String(p_prop));
while(node) {
Ref<SceneState> ss;
if (node==edited_scene) {
ss=node->get_scene_inherited_state();
} else {
ss=node->get_scene_instance_state();
}
// print_line("at - "+String(edited_scene->get_path_to(node)));
if (ss.is_valid()) {
NodePath np = node->get_path_to(orig);
int node_idx = ss->find_node_by_path(np);
// print_line("\t valid, nodeidx "+itos(node_idx));
if (node_idx>=0) {
bool lfound=false;
Variant lvar;
lvar=ss->get_property_value(node_idx,p_prop,lfound);
if (lfound) {
found=true;
value=lvar;
// print_line("\t found value "+String(value));
}
}
}
if (node==edited_scene) {
//just in case
break;
}
node=node->get_owner();
}
return found;
}
bool PropertyEditor::_is_property_different(const Variant& p_current, const Variant& p_orig,int p_usage) {
if (p_orig.get_type()==Variant::NIL) {
//special cases
if (p_current.is_zero() && p_usage&PROPERTY_USAGE_STORE_IF_NONZERO)
return false;
if (p_current.is_one() && p_usage&PROPERTY_USAGE_STORE_IF_NONONE)
return false;
}
return bool(Variant::evaluate(Variant::OP_NOT_EQUAL,p_current,p_orig));
}
TreeItem *PropertyEditor::find_item(TreeItem *p_item,const String& p_name) {
@@ -1910,6 +1988,8 @@ void PropertyEditor::set_item_text(TreeItem *p_item, int p_type, const String& p
}
void PropertyEditor::_notification(int p_what) {
if (p_what==NOTIFICATION_ENTER_TREE) {
@@ -1950,12 +2030,16 @@ void PropertyEditor::_notification(int p_what) {
if (!item)
continue;
if (get_instanced_node()) {
if (_might_be_in_instance()) {
Dictionary d = get_instanced_node()->get_instance_state();
if (d.has(*k)) {
Variant vorig;
Dictionary d=item->get_metadata(0);
int usage = d.has("usage")?int(int(d["usage"])&(PROPERTY_USAGE_STORE_IF_NONONE|PROPERTY_USAGE_STORE_IF_NONZERO)):0;
if (_get_instanced_node_original_property(*k,vorig) || usage) {
Variant v = obj->get(*k);
Variant vorig = d[*k];
int found=-1;
for(int i=0;i<item->get_button_count(1);i++) {
@@ -1966,7 +2050,7 @@ void PropertyEditor::_notification(int p_what) {
}
}
bool changed = ! (v==vorig);
bool changed = _is_property_different(v,vorig,usage);
if ((found!=-1)!=changed) {
@@ -2049,12 +2133,14 @@ void PropertyEditor::_refresh_item(TreeItem *p_item) {
if (name!=String()) {
if (get_instanced_node()) {
if (_might_be_in_instance()) {
Dictionary d = get_instanced_node()->get_instance_state();
if (d.has(name)) {
Variant vorig;
Dictionary d=p_item->get_metadata(0);
int usage = d.has("usage")?int(int(d["usage"])&(PROPERTY_USAGE_STORE_IF_NONONE|PROPERTY_USAGE_STORE_IF_NONZERO)):0;
if (_get_instanced_node_original_property(name,vorig) || usage) {
Variant v = obj->get(name);
Variant vorig = d[name];
int found=-1;
for(int i=0;i<p_item->get_button_count(1);i++) {
@@ -2065,7 +2151,7 @@ void PropertyEditor::_refresh_item(TreeItem *p_item) {
}
}
bool changed = ! (v==vorig);
bool changed = _is_property_different(v,vorig,usage);
if ((found!=-1)!=changed) {
@@ -2326,7 +2412,8 @@ void PropertyEditor::update_tree() {
d["type"]=(int)p.type;
d["hint"]=(int)p.hint;
d["hint_text"]=p.hint_string;
d["usage"]=(int)p.usage;
item->set_metadata( 0, d );
item->set_metadata( 1, p.name );
@@ -2777,14 +2864,17 @@ void PropertyEditor::update_tree() {
}
}
if (get_instanced_node()) {
if (_might_be_in_instance()) {
Dictionary d = get_instanced_node()->get_instance_state();
if (d.has(p.name)) {
Variant vorig;
Dictionary d=item->get_metadata(0);
int usage = d.has("usage")?int(int(d["usage"])&(PROPERTY_USAGE_STORE_IF_NONONE|PROPERTY_USAGE_STORE_IF_NONZERO)):0;
if (_get_instanced_node_original_property(p.name,vorig) || usage) {
Variant v = obj->get(p.name);
Variant vorig = d[p.name];
if (! (v==vorig)) {
if (_is_property_different(v,vorig,usage)) {
//print_line("FOR "+String(p.name)+" RELOAD WITH: "+String(v)+"("+Variant::get_type_name(v.get_type())+")=="+String(vorig)+"("+Variant::get_type_name(vorig.get_type())+")");
item->add_button(1,get_icon("Reload","EditorIcons"),3);
}
}
@@ -3081,17 +3171,18 @@ void PropertyEditor::_edit_button(Object *p_item, int p_column, int p_button) {
call_deferred("_set_range_def",ti,prop,ti->get_range(p_column)+1.0);
} else if (p_button==3) {
if (!get_instanced_node())
if (!_might_be_in_instance())
return;
if (!d.has("name"))
return;
String prop=d["name"];
Dictionary d2 = get_instanced_node()->get_instance_state();
if (d2.has(prop)) {
Variant vorig;
_edit_set(prop,d2[prop]);
if (_get_instanced_node_original_property(prop,vorig)) {
_edit_set(prop,vorig);
}
} else {

View File

@@ -121,6 +121,7 @@ class CustomPropertyEditor : public Popup {
void show_value_editors(int p_amount);
void config_value_editors(int p_amount, int p_columns,int p_label_w,const List<String>& p_strings);
void config_action_buttons(const List<String>& p_strings);
protected:
void _notification(int p_what);
@@ -184,13 +185,17 @@ class PropertyEditor : public Control {
virtual void _changed_callback(Object *p_changed,const char * p_what);
virtual void _changed_callbacks(Object *p_changed,const String& p_callback);
void _edit_button(Object *p_item, int p_column, int p_button);
void _node_removed(Node *p_node);
void _edit_set(const String& p_name, const Variant& p_value);
void _draw_flags(Object *ti,const Rect2& p_rect);
Node *get_instanced_node();
bool _might_be_in_instance();
bool _get_instanced_node_original_property(const StringName& p_prop,Variant& value);
bool _is_property_different(const Variant& p_current, const Variant& p_orig,int p_usage=0);
void _refresh_item(TreeItem *p_item);
void _set_range_def(Object *p_item, String prop, float p_frame);

View File

@@ -103,6 +103,7 @@ ReparentDialog::ReparentDialog() {
add_child(node_only);
node_only->hide();
tree->set_show_enabled_subscene(true);
//vbc->add_margin_child("Options:",node_only);;

View File

@@ -36,8 +36,8 @@
#include "script_editor_debugger.h"
#include "tools/editor/plugins/script_editor_plugin.h"
#include "multi_node_edit.h"
void SceneTreeDock::_unhandled_key_input(InputEvent p_event) {
void SceneTreeDock::_unhandled_key_input(InputEvent p_event) {
uint32_t sc = p_event.key.get_scancode_with_modifiers();
if (!p_event.key.pressed || p_event.key.echo)
@@ -71,7 +71,7 @@ Node* SceneTreeDock::instance(const String& p_file) {
Node*instanced_scene=NULL;
Ref<PackedScene> sdata = ResourceLoader::load(p_file);
if (sdata.is_valid())
instanced_scene=sdata->instance();
instanced_scene=sdata->instance(true);
if (!instanced_scene) {
@@ -96,7 +96,7 @@ Node* SceneTreeDock::instance(const String& p_file) {
}
}
instanced_scene->generate_instance_state();
//instanced_scene->generate_instance_state();
instanced_scene->set_filename( Globals::get_singleton()->localize_path(p_file) );
editor_data->get_undo_redo().create_action("Instance Scene");
@@ -158,8 +158,8 @@ void SceneTreeDock::_tool_selected(int p_tool, bool p_confirm_override) {
case TOOL_NEW: {
if (!_validate_no_foreign())
break;
//if (!_validate_no_foreign())
// break;
create_dialog->popup_centered_ratio();
} break;
case TOOL_INSTANCE: {
@@ -176,8 +176,8 @@ void SceneTreeDock::_tool_selected(int p_tool, bool p_confirm_override) {
break;
}
if (!_validate_no_foreign())
break;
//if (!_validate_no_foreign())
// break;
file->set_mode(EditorFileDialog::MODE_OPEN_FILE);
List<String> extensions;
@@ -202,8 +202,8 @@ void SceneTreeDock::_tool_selected(int p_tool, bool p_confirm_override) {
if (!current)
break;
if (!_validate_no_foreign())
break;
//if (!_validate_no_foreign())
// break;
connect_dialog->popup_centered_ratio();
connect_dialog->set_node(current);
@@ -213,8 +213,8 @@ void SceneTreeDock::_tool_selected(int p_tool, bool p_confirm_override) {
Node *current = scene_tree->get_selected();
if (!current)
break;
if (!_validate_no_foreign())
break;
//if (!_validate_no_foreign())
// break;
groups_editor->set_current(current);
groups_editor->popup_centered_ratio();
} break;
@@ -224,8 +224,8 @@ void SceneTreeDock::_tool_selected(int p_tool, bool p_confirm_override) {
if (!selected)
break;
if (!_validate_no_foreign())
break;
//if (!_validate_no_foreign())
// break;
Ref<Script> existing = selected->get_script();
if (existing.is_valid())
@@ -573,9 +573,9 @@ Node *SceneTreeDock::_duplicate(Node *p_node, Map<Node*,Node*> &duplimap) {
Ref<PackedScene> sd = ResourceLoader::load( p_node->get_filename() );
ERR_FAIL_COND_V(!sd.is_valid(),NULL);
node = sd->instance();
node = sd->instance(true);
ERR_FAIL_COND_V(!node,NULL);
node->generate_instance_state();
//node->generate_instance_state();
} else {
Object *obj = ObjectTypeDB::instance(p_node->get_type());
ERR_FAIL_COND_V(!obj,NULL);
@@ -874,6 +874,16 @@ bool SceneTreeDock::_validate_no_foreign() {
return false;
}
if (edited_scene->get_scene_instance_state().is_valid() && edited_scene->get_scene_instance_state()->find_node_by_path(edited_scene->get_path_to(E->get()))>=0) {
accept->get_ok()->set_text("Makes Sense!");
accept->set_text("Can't operate on nodes the current scene inherits from!");
accept->popup_centered_minsize();
return false;
}
}
return true;
@@ -1078,14 +1088,15 @@ void SceneTreeDock::_delete_confirm() {
void SceneTreeDock::_update_tool_buttons() {
Node *sel = scene_tree->get_selected();
bool disable = !sel || (sel!=edited_scene && sel->get_owner()!=edited_scene);
bool disable = !sel || (sel!=edited_scene && sel->get_owner()!=edited_scene) || (edited_scene->get_scene_instance_state().is_valid() && edited_scene->get_scene_instance_state()->find_node_by_path(edited_scene->get_path_to(sel))>=0);
bool disable_root = disable || sel->get_parent()==scene_root;
bool disable_edit = !sel;
tool_buttons[TOOL_INSTANCE]->set_disabled(disable);
tool_buttons[TOOL_INSTANCE]->set_disabled(disable_edit);
tool_buttons[TOOL_REPLACE]->set_disabled(disable);
tool_buttons[TOOL_CONNECT]->set_disabled(disable);
tool_buttons[TOOL_GROUP]->set_disabled(disable);
tool_buttons[TOOL_SCRIPT]->set_disabled(disable);
tool_buttons[TOOL_CONNECT]->set_disabled(disable_edit);
tool_buttons[TOOL_GROUP]->set_disabled(disable_edit);
tool_buttons[TOOL_SCRIPT]->set_disabled(disable_edit);
tool_buttons[TOOL_MOVE_UP]->set_disabled(disable_root);
tool_buttons[TOOL_MOVE_DOWN]->set_disabled(disable_root);
tool_buttons[TOOL_DUPLICATE]->set_disabled(disable_root);

View File

@@ -34,6 +34,8 @@
#include "scene/main/viewport.h"
#include "tools/editor/plugins/canvas_item_editor_plugin.h"
#include "scene/resources/packed_scene.h"
Node *SceneTreeEditor::get_scene_node() {
ERR_FAIL_COND_V(!is_inside_tree(),NULL);
@@ -57,22 +59,58 @@ void SceneTreeEditor::_subscene_option(int p_idx) {
switch(p_idx) {
case SCENE_MENU_SHOW_CHILDREN: {
case SCENE_MENU_EDITABLE_CHILDREN: {
if (node->has_meta("__editor_show_subtree")) {
instance_menu->set_item_checked(0,true);
node->set_meta("__editor_show_subtree",Variant());
_update_tree();
} else {
node->set_meta("__editor_show_subtree",true);
_update_tree();
bool editable = EditorNode::get_singleton()->get_edited_scene()->is_editable_instance(node);
editable = !editable;
//node->set_instance_children_editable(editable);
EditorNode::get_singleton()->get_edited_scene()->set_editable_instance(node,editable);
instance_menu->set_item_checked(0,editable);
if (editable) {
node->set_scene_instance_load_placeholder(false);
instance_menu->set_item_checked(1,false);
}
_update_tree();
} break;
case SCENE_MENU_USE_PLACEHOLDER: {
bool placeholder = node->get_scene_instance_load_placeholder();
placeholder = !placeholder;
//node->set_instance_children_editable(editable);
if (placeholder) {
EditorNode::get_singleton()->get_edited_scene()->set_editable_instance(node,false);
}
node->set_scene_instance_load_placeholder(placeholder);
instance_menu->set_item_checked(0,false);
instance_menu->set_item_checked(1,placeholder);
_update_tree();
} break;
case SCENE_MENU_OPEN: {
emit_signal("open",node->get_filename());
} break;
case SCENE_MENU_CLEAR_INHERITANCE: {
clear_inherit_confirm->popup_centered_minsize();
} break;
case SCENE_MENU_OPEN_INHERITED: {
if (node && node->get_scene_inherited_state().is_valid()) {
emit_signal("open",node->get_scene_inherited_state()->get_path());
}
} break;
case SCENE_MENU_CLEAR_INHERITANCE_CONFIRM: {
if (node && node->get_scene_inherited_state().is_valid()) {
node->set_scene_inherited_state(Ref<SceneState>());
update_tree();
EditorNode::get_singleton()->get_property_editor()->update_tree();
}
} break;
}
@@ -94,15 +132,33 @@ void SceneTreeEditor::_cell_button_pressed(Object *p_item,int p_column,int p_id)
Rect2 item_rect = tree->get_item_rect(item,0);
item_rect.pos.y-=tree->get_scroll().y;
item_rect.pos+=tree->get_global_pos();
instance_menu->set_pos(item_rect.pos+Vector2(0,item_rect.size.y));
instance_menu->set_size(Vector2(item_rect.size.x,0));
if (n->has_meta("__editor_show_subtree"))
instance_menu->set_item_checked(0,true);
else
instance_menu->set_item_checked(0,false);
instance_menu->popup();
instance_node=n->get_instance_ID();
if (n==get_scene_node()) {
inheritance_menu->set_pos(item_rect.pos+Vector2(0,item_rect.size.y));
inheritance_menu->set_size(Vector2(item_rect.size.x,0));
inheritance_menu->popup();
instance_node=n->get_instance_ID();
} else {
instance_menu->set_pos(item_rect.pos+Vector2(0,item_rect.size.y));
instance_menu->set_size(Vector2(item_rect.size.x,0));
if (EditorNode::get_singleton()->get_edited_scene()->is_editable_instance(n))
instance_menu->set_item_checked(0,true);
else
instance_menu->set_item_checked(0,false);
if (n->get_owner()==get_scene_node()) {
instance_menu->set_item_checked(1,n->get_scene_instance_load_placeholder());
instance_menu->set_item_disabled(1,false);
} else {
instance_menu->set_item_checked(1,false);
instance_menu->set_item_disabled(1,true);
}
instance_menu->popup();
instance_node=n->get_instance_ID();
}
//emit_signal("open",n->get_filename());
} else if (p_id==BUTTON_SCRIPT) {
RefPtr script=n->get_script();
@@ -168,15 +224,17 @@ void SceneTreeEditor::_add_nodes(Node *p_node,TreeItem *p_parent) {
bool part_of_subscene=false;
if (!display_foreign && p_node->get_owner()!=get_scene_node() && p_node!=get_scene_node()) {
if (!display_foreign && p_node->get_owner()!=get_scene_node() && p_node!=get_scene_node()) {
if ((show_enabled_subscene || can_open_instance) && p_node->get_owner() && p_node->get_owner()->get_owner()==get_scene_node() && p_node->get_owner()->has_meta("__editor_show_subtree")) {
if ((show_enabled_subscene || can_open_instance) && p_node->get_owner() && (get_scene_node()->is_editable_instance(p_node->get_owner()))) {
part_of_subscene=true;
//allow
} else {
return;
}
} else {
part_of_subscene = get_scene_node()->get_scene_inherited_state().is_valid() && get_scene_node()->get_scene_inherited_state()->find_node_by_path(get_scene_node()->get_path_to(p_node))>=0;
}
TreeItem *item = tree->create_item(p_parent);
@@ -199,6 +257,7 @@ void SceneTreeEditor::_add_nodes(Node *p_node,TreeItem *p_parent) {
icon=get_icon( (has_icon(p_node->get_type(),"EditorIcons")?p_node->get_type():String("Object")),"EditorIcons");
item->set_icon(0, icon );
item->set_metadata( 0,p_node->get_path() );
if (part_of_subscene) {
//item->set_selectable(0,marked_selectable);
@@ -221,7 +280,10 @@ void SceneTreeEditor::_add_nodes(Node *p_node,TreeItem *p_parent) {
}
}
if (p_node!=get_scene_node() && p_node->get_filename()!="" && can_open_instance) {
if (p_node==get_scene_node() && p_node->get_scene_inherited_state().is_valid()) {
item->add_button(0,get_icon("InstanceOptions","EditorIcons"),BUTTON_SUBSCENE);
item->set_tooltip(0,"Inherits: "+p_node->get_scene_inherited_state()->get_path()+"\nType: "+p_node->get_type());
} else if (p_node!=get_scene_node() && p_node->get_filename()!="" && can_open_instance) {
item->add_button(0,get_icon("InstanceOptions","EditorIcons"),BUTTON_SUBSCENE);
item->set_tooltip(0,"Instance: "+p_node->get_filename()+"\nType: "+p_node->get_type());
@@ -487,8 +549,11 @@ void SceneTreeEditor::_notification(int p_what) {
get_tree()->connect("tree_changed",this,"_tree_changed");
get_tree()->connect("node_removed",this,"_node_removed");
instance_menu->set_item_icon(2,get_icon("Load","EditorIcons"));
instance_menu->set_item_icon(3,get_icon("Load","EditorIcons"));
tree->connect("item_collapsed",this,"_cell_collapsed");
inheritance_menu->set_item_icon(2,get_icon("Load","EditorIcons"));
clear_inherit_confirm->connect("confirmed",this,"_subscene_option",varray(SCENE_MENU_CLEAR_INHERITANCE_CONFIRM));
// get_scene()->connect("tree_changed",this,"_tree_changed",Vector<Variant>(),CONNECT_DEFERRED);
// get_scene()->connect("node_removed",this,"_node_removed",Vector<Variant>(),CONNECT_DEFERRED);
@@ -499,6 +564,7 @@ void SceneTreeEditor::_notification(int p_what) {
get_tree()->disconnect("tree_changed",this,"_tree_changed");
get_tree()->disconnect("node_removed",this,"_node_removed");
tree->disconnect("item_collapsed",this,"_cell_collapsed");
clear_inherit_confirm->disconnect("confirmed",this,"_subscene_option");
_update_tree();
}
@@ -788,12 +854,27 @@ SceneTreeEditor::SceneTreeEditor(bool p_label,bool p_can_rename, bool p_can_open
blocked=0;
instance_menu = memnew( PopupMenu );
instance_menu->add_check_item("Show Children",SCENE_MENU_SHOW_CHILDREN);
instance_menu->add_check_item("Editable Children",SCENE_MENU_EDITABLE_CHILDREN);
instance_menu->add_check_item("Load As Placeholder",SCENE_MENU_USE_PLACEHOLDER);
instance_menu->add_separator();
instance_menu->add_item("Open in Editor",SCENE_MENU_OPEN);
instance_menu->connect("item_pressed",this,"_subscene_option");
add_child(instance_menu);
inheritance_menu = memnew( PopupMenu );
inheritance_menu->add_item("Clear Inheritance",SCENE_MENU_CLEAR_INHERITANCE);
inheritance_menu->add_separator();
inheritance_menu->add_item("Open in Editor",SCENE_MENU_OPEN_INHERITED);
inheritance_menu->connect("item_pressed",this,"_subscene_option");
add_child(inheritance_menu);
clear_inherit_confirm = memnew( ConfirmationDialog );
clear_inherit_confirm->set_text("Clear Inheritance? (No Undo!)");
clear_inherit_confirm->get_ok()->set_text("Clear!");
add_child(clear_inherit_confirm);
}

View File

@@ -52,16 +52,22 @@ class SceneTreeEditor : public Control {
};
enum {
SCENE_MENU_SHOW_CHILDREN,
SCENE_MENU_EDITABLE_CHILDREN,
SCENE_MENU_USE_PLACEHOLDER,
SCENE_MENU_OPEN,
SCENE_MENU_CLEAR_INHERITANCE,
SCENE_MENU_OPEN_INHERITED,
SCENE_MENU_CLEAR_INHERITANCE_CONFIRM,
};
Tree *tree;
Node *selected;
PopupMenu *instance_menu;
PopupMenu *inheritance_menu;
ObjectID instance_node;
AcceptDialog *error;
ConfirmationDialog *clear_inherit_confirm;
int blocked;

View File

@@ -104,11 +104,6 @@ class ExportDAE(bpy.types.Operator, ExportHelper):
description="Export only objects on the active layers.",
default=True,
)
use_exclude_ctrl_bones = BoolProperty(
name="Exclude Control Bones",
description="Exclude skeleton bones with names that begin with 'ctrl'.",
default=True,
)
use_anim = BoolProperty(
name="Export Animation",
description="Export keyframe animation",