-project settings are saved when changed

-load() was in the GDScript docs but missing in the scripting-different music for platformer 2D and 3D
-fix how documentation is generated, built in doc browser should be always up to date
-copypaste, scrolling, etc in  builtin doc
-built-in scripts get saved now (though debugger may not always work on them)
-Theme can be set to controls as a property
This commit is contained in:
Juan Linietsky 2014-02-15 21:16:33 -03:00
parent 9afdb3e0ad
commit 8c1731b679
26 changed files with 92600 additions and 188275 deletions

View File

@ -29,6 +29,8 @@
#include "compression.h"
#include "fastlz.h"
#include "zlib.h"
#include "zip_io.h"
#include "os/copymem.h"
int Compression::compress(uint8_t *p_dst, const uint8_t *p_src, int p_src_size,Mode p_mode) {
@ -46,6 +48,27 @@ int Compression::compress(uint8_t *p_dst, const uint8_t *p_src, int p_src_size,M
}
} break;
case MODE_DEFLATE: {
z_stream strm;
strm.zalloc = zipio_alloc;
strm.zfree = zipio_free;
strm.opaque = Z_NULL;
int err = deflateInit(&strm,Z_DEFAULT_COMPRESSION);
if (err==Z_OK)
return -1;
strm.avail_in=p_src_size;
int aout = deflateBound(&strm,p_src_size);;
strm.avail_out=aout;
strm.next_in=(Bytef*)p_src;
strm.next_out=p_dst;
deflate(&strm,Z_FINISH);
aout = aout - strm.avail_out;
deflateEnd(&strm);
return aout;
} break;
}
ERR_FAIL_V(-1);
@ -63,6 +86,19 @@ int Compression::get_max_compressed_buffer_size(int p_src_size,Mode p_mode){
return ss;
} break;
case MODE_DEFLATE: {
z_stream strm;
strm.zalloc = zipio_alloc;
strm.zfree = zipio_free;
strm.opaque = Z_NULL;
int err = deflateInit(&strm,Z_DEFAULT_COMPRESSION);
if (err==Z_OK)
return -1;
int aout = deflateBound(&strm,p_src_size);
deflateEnd(&strm);
return aout;
} break;
}
ERR_FAIL_V(-1);
@ -85,6 +121,27 @@ void Compression::decompress(uint8_t *p_dst, int p_dst_max_size, const uint8_t *
}
return;
} break;
case MODE_DEFLATE: {
z_stream strm;
strm.zalloc = zipio_alloc;
strm.zfree = zipio_free;
strm.opaque = Z_NULL;
strm.avail_in= 0;
strm.next_in=Z_NULL;
int err = inflateInit(&strm);
ERR_FAIL_COND(err!=Z_OK);
strm.avail_in=p_src_size;
strm.avail_out=p_dst_max_size;
strm.next_in=(Bytef*)p_src;
strm.next_out=p_dst;
err = inflate(&strm,Z_FINISH);
inflateEnd(&strm);
ERR_FAIL_COND(err!=Z_STREAM_END);
return;
} break;
}
ERR_FAIL();

View File

@ -392,7 +392,8 @@ void XMLParser::_bind_methods() {
ObjectTypeDB::bind_method(_MD("get_current_line"),&XMLParser::get_current_line);
ObjectTypeDB::bind_method(_MD("skip_section"),&XMLParser::skip_section);
ObjectTypeDB::bind_method(_MD("seek"),&XMLParser::seek);
ObjectTypeDB::bind_method(_MD("open"),&XMLParser::open);
ObjectTypeDB::bind_method(_MD("open","file"),&XMLParser::open);
ObjectTypeDB::bind_method(_MD("open_buffer","buffer"),&XMLParser::open_buffer);
BIND_CONSTANT( NODE_NONE );
BIND_CONSTANT( NODE_ELEMENT );
@ -493,6 +494,19 @@ bool XMLParser::is_empty() const {
return node_empty;
}
Error XMLParser::open_buffer(const Vector<uint8_t>& p_buffer) {
ERR_FAIL_COND_V(p_buffer.size()==0,ERR_INVALID_DATA);
length = p_buffer.size();
data = memnew_arr( char, length+1);
copymem(data,p_buffer.ptr(),length);
data[length]=0;
P=data;
return OK;
}
Error XMLParser::open(const String& p_path) {
Error err;

View File

@ -113,6 +113,8 @@ public:
Error seek(uint64_t p_pos);
Error open(const String& p_path);
Error open_buffer(const Vector<uint8_t>& p_buffer);
void close();
XMLParser();

View File

@ -32,7 +32,7 @@
#include "io/zip.h"
#include "io/unzip.h"
#include "os/file_access.h"
//#include "copymem.h"
#include "os/copymem.h"
static void* zipio_open(void* data, const char* p_fname, int mode) {

View File

@ -797,7 +797,6 @@ bool Main::start() {
bool editor=false;
String doc_tool;
String doc_header;
bool doc_base=true;
String game_path;
String script;
@ -820,10 +819,6 @@ bool Main::start() {
doc_tool=args[i+1];
i++;
} else if (args[i]=="-docheader" && i <(args.size()-1)) {
doc_header=args[i+1];
i++;
}else if (args[i]=="-nodocbase") {
doc_base=false;
@ -899,9 +894,6 @@ bool Main::start() {
}
if (doc_header.length())
doc.save_compressed_header(doc_header);
else
doc.save(doc_tool);
return false;

View File

@ -392,6 +392,8 @@ static int button_mask=0;
// ev.mouse_motion.relative_x=[event deltaX];
// ev.mouse_motion.relative_y=[event deltaY];
OS_OSX::singleton->input->set_mouse_pos(Point2(mouse_x,mouse_y));
OS_OSX::singleton->push_input(ev);

View File

@ -2796,6 +2796,7 @@ void Control::_bind_methods() {
ADD_PROPERTYNZ( PropertyInfo(Variant::INT,"size_flags/horizontal", PROPERTY_HINT_FLAGS, "Expand,Fill"), _SCS("set_h_size_flags"),_SCS("get_h_size_flags") );
ADD_PROPERTYNZ( PropertyInfo(Variant::INT,"size_flags/vertical", PROPERTY_HINT_FLAGS, "Expand,Fill"), _SCS("set_v_size_flags"),_SCS("get_v_size_flags") );
ADD_PROPERTY( PropertyInfo(Variant::INT,"size_flags/stretch_ratio", PROPERTY_HINT_RANGE, "1,128,0.01"), _SCS("set_stretch_ratio"),_SCS("get_stretch_ratio") );
ADD_PROPERTYNZ( PropertyInfo(Variant::OBJECT,"theme/theme", PROPERTY_HINT_RESOURCE_TYPE, "Theme"), _SCS("set_theme"),_SCS("get_theme") );
BIND_CONSTANT( ANCHOR_BEGIN );
BIND_CONSTANT( ANCHOR_END );

View File

@ -27,9 +27,9 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
#include "rich_text_label.h"
#include "scene/scene_string_names.h"e"
#include "scene/scene_string_names.h"
#include "os/keyboard.h"
#include "os/os.h"
RichTextLabel::Item *RichTextLabel::_get_next_item(Item* p_item) {
if (p_item->subitems.size()) {
@ -455,11 +455,18 @@ void RichTextLabel::_notification(int p_what) {
_validate_line_caches();
_update_scroll();
RID ci=get_canvas_item();
Size2 size = get_size();
VisualServer::get_singleton()->canvas_item_set_clip(ci,true);
if (has_focus()) {
VisualServer::get_singleton()->canvas_item_add_clip_ignore(ci,true);
draw_style_box(get_stylebox("focus"),Rect2(Point2(),size));
VisualServer::get_singleton()->canvas_item_add_clip_ignore(ci,false);
}
int ofs = vscroll->get_val();
//todo, change to binary search
@ -608,6 +615,60 @@ void RichTextLabel::_input_event(InputEvent p_event) {
vscroll->set_val( vscroll->get_val()+vscroll->get_page()/8 );
}
} break;
case InputEvent::KEY: {
const InputEventKey &k=p_event.key;
if (k.pressed) {
bool handled=true;
switch(k.scancode) {
case KEY_PAGEUP: {
if (vscroll->is_visible())
vscroll->set_val( vscroll->get_val() - vscroll->get_page() );
} break;
case KEY_PAGEDOWN: {
if (vscroll->is_visible())
vscroll->set_val( vscroll->get_val() + vscroll->get_page() );
} break;
case KEY_UP: {
if (vscroll->is_visible())
vscroll->set_val( vscroll->get_val() - get_font("default_font")->get_height() );
} break;
case KEY_DOWN: {
if (vscroll->is_visible())
vscroll->set_val( vscroll->get_val() + get_font("default_font")->get_height() );
} break;
case KEY_HOME: {
if (vscroll->is_visible())
vscroll->set_val( 0 );
} break;
case KEY_END: {
if (vscroll->is_visible())
vscroll->set_val( vscroll->get_max() );
} break;
case KEY_INSERT:
case KEY_C: {
if (k.mod.command) {
selection_copy();
} else {
handled=false;
}
} break;
default: handled=false;
}
if (handled)
accept_event();
}
} break;
case InputEvent::MOUSE_MOTION: {
if (first_invalid_line<lines.size())
@ -1300,6 +1361,9 @@ void RichTextLabel::set_selection_enabled(bool p_enabled) {
selection.active=false;
update();
}
set_focus_mode(FOCUS_NONE);
} else {
set_focus_mode(FOCUS_ALL);
}
}
@ -1368,6 +1432,46 @@ bool RichTextLabel::search(const String& p_string,bool p_from_selection) {
}
void RichTextLabel::selection_copy() {
if (!selection.enabled)
return;
String text;
RichTextLabel::Item *item=selection.from;
while(item) {
if (item->type==ITEM_TEXT) {
String itext = static_cast<ItemText*>(item)->text;
if (item==selection.from && item==selection.to) {
text+=itext.substr(selection.from_char,selection.to_char-selection.from_char+1);
} else if (item==selection.from) {
text+=itext.substr(selection.from_char,itext.size());
} else if (item==selection.to) {
text+=itext.substr(0,selection.to_char+1);
} else {
text+=itext;
}
} else if (item->type==ITEM_NEWLINE) {
text+="\n";
}
if (item==selection.to)
break;
item=_get_next_item(item);
}
if (text!="") {
OS::get_singleton()->set_clipboard(text);
print_line("COPY: "+text);
}
}
bool RichTextLabel::is_selection_enabled() const {
return selection.enabled;

View File

@ -289,6 +289,7 @@ public:
void set_selection_enabled(bool p_enabled);
bool is_selection_enabled() const;
void selection_copy();
Error parse_bbcode(const String& p_bbcode);
Error append_bbcode(const String& p_bbcode);

View File

@ -533,6 +533,7 @@ void make_default_theme() {
t->set_color("font_color_selected","RichTextLabel", font_color_selection );
t->set_color("selection_color","RichTextLabel", Color(0.1,0.1,1,0.8) );
t->set_constant("line_separation","RichTextLabel", 1 );
t->set_stylebox("focus","RichTextLabel", focus );
t->set_constant("separation","HBoxContainer",4);

View File

@ -88,6 +88,7 @@ const char *GDFunctions::get_func_name(Function p_func) {
"printerr",
"printraw",
"range",
"load",
"inst2dict",
"dict2inst",
"print_stack",
@ -668,6 +669,16 @@ void GDFunctions::call(Function p_func,const Variant **p_args,int p_arg_count,Va
}
} break;
case RESOURCE_LOAD: {
VALIDATE_ARG_COUNT(1);
if (p_args[0]->get_type()!=Variant::STRING) {
r_error.error=Variant::CallError::CALL_ERROR_INVALID_ARGUMENT;
r_error.argument=0;
r_ret=Variant();
}
r_ret=ResourceLoader::load(*p_args[0]);
}
case INST2DICT: {
VALIDATE_ARG_COUNT(1);
@ -1170,6 +1181,12 @@ MethodInfo GDFunctions::get_info(Function p_func) {
mi.return_val.type=Variant::ARRAY;
return mi;
} break;
case RESOURCE_LOAD: {
MethodInfo mi("load",PropertyInfo(Variant::STRING,"path"));
mi.return_val.type=Variant::OBJECT;
return mi;
} break;
case INST2DICT: {
MethodInfo mi("inst2dict",PropertyInfo(Variant::OBJECT,"inst"));

View File

@ -85,6 +85,7 @@ public:
TEXT_PRINTERR,
TEXT_PRINTRAW,
GEN_RANGE,
RESOURCE_LOAD,
INST2DICT,
DICT2INST,
PRINT_STACK,

View File

@ -557,7 +557,7 @@ GDParser::Node* GDParser::_parse_expression(Node *p_parent,bool p_static,bool p_
//indexing using "."
if (tokenizer.get_token(1)!=GDTokenizer::TK_IDENTIFIER) {
if (tokenizer.get_token(1)!=GDTokenizer::TK_IDENTIFIER && tokenizer.get_token(1)!=GDTokenizer::TK_BUILT_IN_FUNC ) {
_set_error("Expected identifier as member");
return NULL;
} else if (tokenizer.get_token(2)==GDTokenizer::TK_PARENTHESIS_OPEN) {
@ -566,7 +566,13 @@ GDParser::Node* GDParser::_parse_expression(Node *p_parent,bool p_static,bool p_
op->op=OperatorNode::OP_CALL;
IdentifierNode * id = alloc_node<IdentifierNode>();
if (tokenizer.get_token(1)==GDTokenizer::TK_BUILT_IN_FUNC ) {
//small hack so built in funcs don't obfuscate methods
id->name=GDFunctions::get_func_name(tokenizer.get_token_built_in_func(1));
} else {
id->name=tokenizer.get_token_identifier(1);
}
op->arguments.push_back(expr); // call what
op->arguments.push_back(id); // call func

View File

@ -1524,21 +1524,21 @@ bool GDScript::_get(const StringName& p_name,Variant &r_ret) const {
top=top->_base;
}
return false;
}
if (p_name=="script/source") {
if (p_name==GDScriptLanguage::get_singleton()->strings._script_source) {
r_ret=get_source_code();
return true;
}
}
return true;
return false;
}
bool GDScript::_set(const StringName& p_name, const Variant& p_value) {
if (p_name=="script/source") {
if (p_name==GDScriptLanguage::get_singleton()->strings._script_source) {
set_source_code(p_value);
reload();
@ -2115,6 +2115,7 @@ GDScriptLanguage::GDScriptLanguage() {
strings._set= StaticCString::create("_set");
strings._get= StaticCString::create("_get");
strings._get_property_list= StaticCString::create("_get_property_list");
strings._script_source=StaticCString::create("script/source");
_debug_parse_err_line=-1;
_debug_parse_err_file="";

View File

@ -219,6 +219,7 @@ friend class GDFunctions;
virtual void _placeholder_erased(PlaceHolderScriptInstance *p_placeholder);
#endif
protected:
bool _get(const StringName& p_name,Variant &r_ret) const;
bool _set(const StringName& p_name, const Variant& p_value);
@ -392,6 +393,7 @@ public:
StringName _set;
StringName _get;
StringName _get_property_list;
StringName _script_source;
} strings;

View File

@ -28,12 +28,13 @@
/*************************************************************************/
#include "version.h"
#include "doc_data.h"
#include "io/xml_parser.h"
#include "global_constants.h"
#include "globals.h"
#include "script_language.h"
#include "io/marshalls.h"
#include "io/compression.h"
void DocData::merge_from(const DocData& p_data) {
for( Map<String,ClassDoc>::Element *E=class_list.front();E;E=E->next()) {
@ -601,10 +602,15 @@ static Error _parse_methods(Ref<XMLParser>& parser,Vector<DocData::MethodDoc>& m
Error DocData::load(const String& p_path) {
Ref<XMLParser> parser=memnew(XMLParser);
Error err = parser->open(p_path);
if (err)
return err;
return _load(parser);
}
Error DocData::_load(Ref<XMLParser> parser) {
Error err=OK;
while((err=parser->read())==OK) {
@ -891,221 +897,20 @@ Error DocData::save(const String& p_path) {
return OK;
}
static void add_to_arr(Vector<uint8_t>& p_arr,const Variant& p_var) {
int from = p_arr.size();
int len;
Error err =encode_variant(p_var,NULL,len);
ERR_FAIL_COND(err!=OK);
p_arr.resize(from+len);
encode_variant(p_var,&p_arr[from],len);
}
Error DocData::save_compressed_header(const String& p_path) {
Vector<uint8_t> data;
add_to_arr(data,version);
add_to_arr(data,class_list.size());
for (Map<String,ClassDoc>::Element *E=class_list.front();E;E=E->next()) {
ClassDoc &cd=E->get();
add_to_arr(data,cd.name);
add_to_arr(data,cd.inherits);
add_to_arr(data,cd.category);
add_to_arr(data,cd.brief_description);
add_to_arr(data,cd.description);
add_to_arr(data,cd.methods.size());
for(int i=0;i<cd.methods.size();i++) {
MethodDoc &md=cd.methods[i];
add_to_arr(data,md.name);
add_to_arr(data,md.return_type);
add_to_arr(data,md.qualifiers);
add_to_arr(data,md.description);
add_to_arr(data,md.arguments.size());
for(int j=0;j<md.arguments.size();j++) {
ArgumentDoc &ad=md.arguments[j];
add_to_arr(data,ad.name);
add_to_arr(data,ad.type);
add_to_arr(data,ad.default_value);
}
}
add_to_arr(data,cd.signals.size());
for(int i=0;i<cd.signals.size();i++) {
MethodDoc &md=cd.signals[i];
add_to_arr(data,md.name);
add_to_arr(data,md.return_type);
add_to_arr(data,md.qualifiers);
add_to_arr(data,md.description);
add_to_arr(data,md.arguments.size());
for(int j=0;j<md.arguments.size();j++) {
ArgumentDoc &ad=md.arguments[j];
add_to_arr(data,ad.name);
add_to_arr(data,ad.type);
add_to_arr(data,ad.default_value);
}
}
add_to_arr(data,cd.properties.size());
for(int i=0;i<cd.properties.size();i++) {
PropertyDoc &pd=cd.properties[i];
add_to_arr(data,pd.name);
add_to_arr(data,pd.type);
add_to_arr(data,pd.description);
}
add_to_arr(data,cd.constants.size());
for(int i=0;i<cd.constants.size();i++) {
ConstantDoc &kd=cd.constants[i];
add_to_arr(data,kd.name);
add_to_arr(data,kd.value);
add_to_arr(data,kd.description);
}
}
Vector<uint8_t> cdata;
cdata.resize( Compression::get_max_compressed_buffer_size(data.size()) );
int res = Compression::compress(cdata.ptr(),data.ptr(),data.size());
cdata.resize(res);
print_line("orig size: "+itos(data.size()));
print_line("comp size: "+itos(cdata.size()));
Error err;
FileAccess *f = FileAccess::open(p_path,FileAccess::WRITE,&err);
if (err!=OK) {
ERR_FAIL_COND_V(err,err);
}
f->store_line("/* This file is generated, do not edit */");
f->store_line("#ifndef DOC_DATA_COMPRESSED_H");
f->store_line("#define DOC_DATA_COMPRESSED_H");
f->store_line("");
f->store_line("static const int _doc_data_compressed_size="+itos(cdata.size())+";");
f->store_line("static const int _doc_data_uncompressed_size="+itos(data.size())+";");
f->store_line("static const unsigned char _doc_data_compressed[]={");
for(int i=0;i<cdata.size();i++)
f->store_line(itos(cdata[i])+",");
f->store_line("};");
f->store_line("");
f->store_line("#endif");
memdelete(f);
return OK;
}
static Variant get_data(int& ofs, const Vector<uint8_t>& p_array) {
int len;
Variant r;
decode_variant(r,&p_array[ofs],p_array.size()-ofs,&len);
ofs+=len;
return r;
}
Error DocData::load_compressed(const uint8_t *p_data, int p_compressed_size, int p_uncompressed_size) {
Vector<uint8_t> data;
data.resize(p_uncompressed_size);
Compression::decompress(data.ptr(),p_uncompressed_size,p_data,p_compressed_size);
Compression::decompress(data.ptr(),p_uncompressed_size,p_data,p_compressed_size,Compression::MODE_DEFLATE);
class_list.clear();
int ofs=0;
version=get_data(ofs,data);
int ccount=get_data(ofs,data);
for(int i=0;i<ccount;i++) {
ClassDoc cd;
cd.name=get_data(ofs,data);
cd.inherits=get_data(ofs,data);
cd.category=get_data(ofs,data);
cd.brief_description=get_data(ofs,data);
cd.description=get_data(ofs,data);
int mc = get_data(ofs,data);
for(int j=0;j<mc;j++) {
MethodDoc md;
md.name=get_data(ofs,data);
md.return_type=get_data(ofs,data);
md.qualifiers=get_data(ofs,data);
md.description=get_data(ofs,data);
int ac=get_data(ofs,data);
for(int k=0;k<ac;k++) {
ArgumentDoc ad;
ad.name=get_data(ofs,data);
ad.type=get_data(ofs,data);
ad.default_value=get_data(ofs,data);
md.arguments.push_back(ad);
}
cd.methods.push_back(md);
}
int sc = get_data(ofs,data);
for(int j=0;j<sc;j++) {
MethodDoc md;
md.name=get_data(ofs,data);
md.return_type=get_data(ofs,data);
md.qualifiers=get_data(ofs,data);
md.description=get_data(ofs,data);
int ac=get_data(ofs,data);
for(int k=0;k<ac;k++) {
ArgumentDoc ad;
ad.name=get_data(ofs,data);
ad.type=get_data(ofs,data);
ad.default_value=get_data(ofs,data);
md.arguments.push_back(ad);
}
cd.signals.push_back(md);
}
int pc = get_data(ofs,data);
for(int j=0;j<pc;j++) {
PropertyDoc pd;
pd.name=get_data(ofs,data);
pd.type=get_data(ofs,data);
pd.description=get_data(ofs,data);
cd.properties.push_back(pd);
}
int kc = get_data(ofs,data);
for(int j=0;j<kc;j++) {
ConstantDoc kd;
kd.name=get_data(ofs,data);
kd.value=get_data(ofs,data);
kd.description=get_data(ofs,data);
cd.constants.push_back(kd);
}
class_list[cd.name]=cd;
}
Ref<XMLParser> parser = memnew( XMLParser );
Error err = parser->open_buffer(data);
if (err)
return err;
_load(parser);
return OK;

View File

@ -32,6 +32,7 @@
#include "variant.h"
#include "map.h"
#include "io/xml_parser.h"
class DocData {
public:
@ -82,6 +83,8 @@ public:
String version;
Map<String,ClassDoc> class_list;
Error _load(Ref<XMLParser> parser);
public:
@ -90,7 +93,6 @@ public:
Error load(const String& p_path);
Error save(const String& p_path);
Error save_compressed_header(const String& p_path);
Error load_compressed(const uint8_t *p_data, int p_compressed_size, int p_uncompressed_size);

View File

@ -1,5 +1,35 @@
Import('env')
def make_doc_header(target,source,env):
src = source[0].srcnode().abspath
dst = target[0].srcnode().abspath
f = open(src,"rb")
g = open(dst,"wb")
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 _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(str(ord(buf[i]))+",\n")
g.write("};\n")
g.write("#endif")
if (env["tools"]=="yes"):
reg_exporters_inc='#include "register_exporters.h"\n'
@ -12,7 +42,10 @@ if (env["tools"]=="yes"):
f = open("register_exporters.cpp","wb")
f.write(reg_exporters_inc)
f.write(reg_exporters)
env.Depends("#tools/editor/doc_data_compressed.h","#doc/base/classes.xml")
env.Command("#tools/editor/doc_data_compressed.h","#doc/base/classes.xml",make_doc_header)
#make_doc_header(env.File("#tools/editor/doc_data_raw.h").srcnode().abspath,env.File("#doc/base/classes.xml").srcnode().abspath,env)
env.add_source_files(env.tool_sources,"*.cpp")
Export('env')

File diff suppressed because it is too large Load Diff

View File

@ -31,6 +31,9 @@
#include "editor_settings.h"
#include "os/keyboard.h"
#include "doc_data_compressed.h"
DocData *EditorHelp::doc=NULL;
void EditorHelp::_unhandled_key_input(const InputEvent& p_ev) {
if (is_visible() && p_ev.key.mod.control && p_ev.key.scancode==KEY_F) {
@ -167,7 +170,7 @@ void EditorHelp::_scroll_changed(double p_scroll) {
void EditorHelp::_goto_desc(const String& p_class,bool p_update_history,int p_vscr) {
ERR_FAIL_COND(!doc.class_list.has(p_class));
ERR_FAIL_COND(!doc->class_list.has(p_class));
if (tree_item_map.has(p_class)) {
@ -203,7 +206,7 @@ void EditorHelp::_goto_desc(const String& p_class,bool p_update_history,int p_vs
edited_class->show();
DocData::ClassDoc &cd=doc.class_list[p_class];
DocData::ClassDoc &cd=doc->class_list[p_class];
Color h_color;
@ -630,7 +633,7 @@ void EditorHelp::_add_text(const String& p_bbcode) {
class_desc->pop();
pos=brk_end+1;
} else if (doc.class_list.has(tag)) {
} else if (doc->class_list.has(tag)) {
class_desc->push_meta("#"+tag);
@ -796,7 +799,7 @@ void EditorHelp::add_type(const String& p_type,HashMap<String,TreeItem*>& p_type
// if (!ObjectTypeDB::is_type(p_type,base) || p_type==base)
// return;
String inherits=doc.class_list[p_type].inherits;
String inherits=doc->class_list[p_type].inherits;
TreeItem *parent=p_root;
@ -814,7 +817,7 @@ void EditorHelp::add_type(const String& p_type,HashMap<String,TreeItem*>& p_type
TreeItem *item = class_list->create_item(parent);
item->set_metadata(0,p_type);
item->set_tooltip(0,doc.class_list[p_type].brief_description);
item->set_tooltip(0,doc->class_list[p_type].brief_description);
item->set_text(0,p_type);
@ -841,7 +844,7 @@ void EditorHelp::_update_doc() {
class_list->set_hide_root(true);
List<String>::Element *I=type_list.front();
for(Map<String,DocData::ClassDoc>::Element *E=doc.class_list.front();E;E=E->next()) {
for(Map<String,DocData::ClassDoc>::Element *E=doc->class_list.front();E;E=E->next()) {
add_type(E->key(),tree_item_map,root);
@ -849,6 +852,18 @@ void EditorHelp::_update_doc() {
}
void EditorHelp::generate_doc() {
doc = memnew( DocData );
doc->generate(true);
DocData compdoc;
compdoc.load_compressed(_doc_data_compressed,_doc_data_compressed_size,_doc_data_uncompressed_size);
doc->merge_from(compdoc); //ensure all is up to date
}
void EditorHelp::_notification(int p_what) {
@ -856,7 +871,6 @@ void EditorHelp::_notification(int p_what) {
case NOTIFICATION_READY: {
doc.load_compressed(_doc_data_compressed,_doc_data_compressed_size,_doc_data_uncompressed_size);
forward->set_icon(get_icon("Forward","EditorIcons"));
back->set_icon(get_icon("Back","EditorIcons"));
@ -983,7 +997,10 @@ EditorHelp::EditorHelp(EditorNode *p_editor) {
// prev_search_page=-1;
}
EditorHelp::~EditorHelp() {
if (doc)
memdelete(doc);
}
void EditorHelpPlugin::edit(Object *p_object) {

View File

@ -79,7 +79,7 @@ class EditorHelp : public VBoxContainer {
RichTextLabel *class_desc;
HSplitContainer *h_split;
DocData doc;
static DocData *doc;
Button *class_list_button;
Button *edited_class;
@ -119,7 +119,10 @@ protected:
static void _bind_methods();
public:
static void generate_doc();
EditorHelp(EditorNode *p_editor=NULL);
~EditorHelp();
};

View File

@ -3165,6 +3165,7 @@ Error EditorNode::export_platform(const String& p_platform, const String& p_path
EditorNode::EditorNode() {
EditorHelp::generate_doc(); //before any editor classes are crated
singleton=this;

View File

@ -113,6 +113,8 @@ void ProjectSettings::_action_persist_toggle() {
undo_redo->add_undo_method(Globals::get_singleton(),"set_persisting",name,prev);
undo_redo->add_do_method(this,"_update_actions");
undo_redo->add_undo_method(this,"_update_actions");
undo_redo->add_do_method(this,"_settings_changed");
undo_redo->add_undo_method(this,"_settings_changed");
undo_redo->commit_action();
setting=false;
@ -614,7 +616,13 @@ void ProjectSettings::_action_add() {
void ProjectSettings::_item_checked(const String& p_item, bool p_check) {
Globals::get_singleton()->set_persisting(p_item,p_check);
undo_redo->create_action("Toggle Persisting");
undo_redo->add_do_method(Globals::get_singleton(),"set_persisting",p_item,p_check);
undo_redo->add_undo_method(Globals::get_singleton(),"set_persisting",p_item,!p_check);
undo_redo->add_do_method(this,"_settings_changed");
undo_redo->add_undo_method(this,"_settings_changed");
undo_redo->commit_action();
}
@ -754,6 +762,8 @@ void ProjectSettings::_autoload_add() {
undo_redo->add_do_method(Globals::get_singleton(),"set_persisting",name,true);
undo_redo->add_do_method(this,"_update_autoload");
undo_redo->add_undo_method(this,"_update_autoload");
undo_redo->add_do_method(this,"_settings_changed");
undo_redo->add_undo_method(this,"_settings_changed");
undo_redo->commit_action();
//autoload_file_open->popup_centered_ratio();
@ -770,6 +780,8 @@ void ProjectSettings::_autoload_delete(Object *p_item,int p_column, int p_button
undo_redo->add_undo_method(Globals::get_singleton(),"set_persisting",name,true);
undo_redo->add_do_method(this,"_update_autoload");
undo_redo->add_undo_method(this,"_update_autoload");
undo_redo->add_do_method(this,"_settings_changed");
undo_redo->add_undo_method(this,"_settings_changed");
undo_redo->commit_action();
}
@ -1269,7 +1281,7 @@ ProjectSettings::ProjectSettings(EditorData *p_data) {
del->connect("pressed",this,"_item_del");
Button *save = memnew( Button );
props_base->add_child(save);
//props_base->add_child(save);
save->set_anchor(MARGIN_LEFT,ANCHOR_END);
save->set_anchor(MARGIN_RIGHT,ANCHOR_END);
save->set_anchor(MARGIN_TOP,ANCHOR_END);

View File

@ -0,0 +1,23 @@
Godot Author's Own Collada Exporter
-----------------------------------
1) Copy the "io_scene_dae" directory to wherever blender stores the
scripts/addons folder (You will see many other io_scene_blahblah like
folders). Copy the entire dir, not just the contents, make it just like
the others.
2) Go to Blender settings and enable the "Khronos Collada" plugin
3) Enjoy proper Collada export.
4) If it's broken, you can:
a) Flame the Blender developers in their mailing list for changing
the API every month.
b) Flame the Blender developers for not giving a home to this script
and mantaining it themselves, instead choosing to use the huge,
bloated and buggy OpenCollada based implementation that is as big
as Blender itself, while this script is a little over 1000 lines
of code, works better and has more features.
c) Cry to the poor Godot developers who are busy enough to fix it,
because they are good people and will fix it for you anyway (submit
an issue to github).
d) Be a Hero, save the day, fix it yourself and submit a pull request to
github with the changes.

View File

@ -1,209 +0,0 @@
def tw(f,t,st):
for x in range(t):
f.write("\t")
nl = True
if st[-1] == "#":
nl = False
st = st[:-1]
f.write(st)
if nl:
f.write("\n")
def write_property_lua(f, tab, name, value, pref = ""):
tw(f, tab, '%s{ name = "%s",' % (pref, name))
tab = tab + 1
if (type(value)==str):
tw(f, tab, 'value = "%s",' % value)
tw(f, t, 'type = "string",')
elif (type(value)==bool):
if (value):
tw(f, tab, 'value = true,')
else:
tw(f, tab, 'value = false,')
tw(f, t, 'type = "bool",')
elif (type(value)==int):
tw(f, t, 'type = "int",')
tw(f, tab, 'value = %d,' % value)
elif (type(value)==float):
tw(f, t, 'type = "real",')
tw(f, tab, 'value = %f,' % value)
elif (type(value)==dict):
tw(f, t, 'type = "dictionary",')
for x in value:
write_property_lua(f,tab,x,value[x])
elif (isinstance(value,ObjectTree)):
if (not value._resource):
print("ERROR: Not a resource!!")
tw(f, tab-1, "},")
return
tw(f, tab, 'type = "resource",')
tw(f, tab, 'resource_type = "%s",' % value._type)
if (value._res_path!=""):
tw(f, tab, 'path = "%s",' % value._res_path)
else:
tw(f, tab, "value = {")
tab = tab + 1
tw(f, tab, 'type = "%s",' % value._type)
for x in value._properties:
write_property_lua(f,tab,x[0],x[1])
tab = tab - 1
tw(f, tab, "},")
elif (isinstance(value,Color)):
tw(f, tab, 'type = "color",')
tw(f, tab, 'value = { %.20f, %.20f, %.20f, %.20f },' % (value.r, value.g, value.b, value.a))
elif (isinstance(value,Vector3)):
tw(f, tab, 'type = "vector3",')
tw(f, tab, 'value = { %.20f, %.20f, %.20f },' % (value.x, value.y, value.z))
elif (isinstance(value,Quat)):
tw(f, tab, 'type = "quaternion",')
tw(f, tab, 'value = { %.20f, %.20f, %.20f, %.20f },' % (value.x, value.y, value.z, value.w))
elif (isinstance(value,Matrix4x3)): # wtf, blender matrix?
tw(f, tab, 'type = "transform",')
tw(f, tab, 'value = { #')
for i in range(3):
for j in range(3):
f.write("%.20f, " % value.m[j][i])
for i in range(3):
f.write("%.20f, " % value.m[i][3])
f.write("},\n")
elif (type(value)==list):
if (len(value)==0):
tw(f, tab-1, "},")
return
first=value[0]
if (type(first)==int):
tw(f, tab, 'type = "int_array",')
tw(f, tab, 'value = #')
for i in range(len(value)):
f.write("%d, " % value[i])
f.write("},\n")
elif (type(first)==float):
tw(f, tab, 'type = "real_array",')
tw(f, tab, 'value = #')
for i in range(len(value)):
f.write("%.20f, " % value[i])
f.write("},\n")
elif (type(first)==str):
tw(f, tab, 'type = "string_array",')
tw(f, tab, 'value = #')
for i in range(len(value)):
f.write('"%s", ' % value[i])
f.write("},\n")
elif (isinstance(first,Vector3)):
tw(f, tab, 'type = "vector3_array",')
tw(f, tab, 'value = #')
for i in range(len(value)):
f.write("{ %.20f, %.20f, %.20f }, " % (value[i].x, value[i].y, value[i].z))
f.write("},\n")
elif (isinstance(first,Color)):
tw(f, tab, 'type = "color_array",')
tw(f, tab, 'value = #')
for i in range(len(value)):
f.write("{ %.20f, %.20f, %.20f, %.20f }, " % (value[i].r, value[i].g, value[i].b, value[i].a))
f.write("},\n")
elif (type(first)==dict):
tw(f, tab, 'type = "dict_array",')
tw(f, tab, 'value = {')
for i in range(len(value)):
write_property_lua(f,tab+1,str(i+1),value[i])
tw(f, tab, '},')
tw(f, tab-1, "},")
def write_node_lua(f,tab,tree,path):
tw(f, tab, '{ type = "%s",')
if not tree._resource:
tw(f, tab+1, 'meta = {')
write_property_lua(f, tab+3, "name", tree._name)
if path != "":
write_property_lua(f, tab+3, "path", path)
tw(f, tab+1, '},')
tw(f, tab+1, "properties = {,")
for x in tree._properties:
write_property_lua(f,tab+2,x[0],x[1])
tw(f, tab+1, "},")
tw(f, tab, '},')
if (path==""):
path="."
else:
if (path=="."):
path=tree._name
else:
path=path+"/"+tree._name
#path="."
for x in tree._children:
write_node_lua(f,tab,x,path)
def write(tree,fname):
f=open(fname,"wb")
f.write("return = {\n")
f.write('\tmagic = "SCENE",\n')
tab = 1
write_node_lua(f,tab,tree,"")
f.write("}\n\n")

File diff suppressed because it is too large Load Diff