Completed the support for plugins! It is not possible to add plugins.

Not all APIs are provided yet, please request whathever you are missing.
Some example plugins are provided in demos/plugins. Just copy them to a folder in your project named addons/ and then enable them from the project settings.
Have fun!
This commit is contained in:
Juan Linietsky 2016-02-27 23:10:44 -03:00
parent a97c1ca8f9
commit 6fc1c3a4d1
50 changed files with 2070 additions and 706 deletions

View file

@ -55,11 +55,17 @@ bool _ResourceLoader::has(const String &p_path) {
return ResourceCache::has(local_path);
};
Ref<ResourceImportMetadata> _ResourceLoader::load_import_metadata(const String& p_path) {
return ResourceLoader::load_import_metadata(p_path);
}
void _ResourceLoader::_bind_methods() {
ObjectTypeDB::bind_method(_MD("load_interactive:ResourceInteractiveLoader","path","type_hint"),&_ResourceLoader::load_interactive,DEFVAL(""));
ObjectTypeDB::bind_method(_MD("load:Resource","path","type_hint", "p_no_cache"),&_ResourceLoader::load,DEFVAL(""), DEFVAL(false));
ObjectTypeDB::bind_method(_MD("load_import_metadata:ResourceImportMetadata","path"),&_ResourceLoader::load_import_metadata);
ObjectTypeDB::bind_method(_MD("get_recognized_extensions_for_type","type"),&_ResourceLoader::get_recognized_extensions_for_type);
ObjectTypeDB::bind_method(_MD("set_abort_on_missing_resources","abort"),&_ResourceLoader::set_abort_on_missing_resources);
ObjectTypeDB::bind_method(_MD("get_dependencies","path"),&_ResourceLoader::get_dependencies);

View file

@ -26,6 +26,7 @@ public:
void set_abort_on_missing_resources(bool p_abort);
StringArray get_dependencies(const String& p_path);
bool has(const String& p_path);
Ref<ResourceImportMetadata> load_import_metadata(const String& p_path);
_ResourceLoader();
};

View file

@ -223,5 +223,10 @@ extern bool _err_error_exists;
} \
#define WARN_PRINTS(m_string) \
{ \
_err_print_error(FUNCTION_STR,__FILE__,__LINE__,String(m_string).utf8().get_data(),ERR_HANDLER_WARNING); \
_err_error_exists=false;\
} \
#endif

View file

@ -432,6 +432,7 @@ static _GlobalConstant _global_constants[]={
BIND_GLOBAL_CONSTANT( ERR_FILE_EOF ),
BIND_GLOBAL_CONSTANT( ERR_CANT_OPEN ), ///< Can't open a resource/socket/file
BIND_GLOBAL_CONSTANT( ERR_CANT_CREATE ),
BIND_GLOBAL_CONSTANT( ERR_PARSE_ERROR ),
BIND_GLOBAL_CONSTANT( ERROR_QUERY_FAILED ),
BIND_GLOBAL_CONSTANT( ERR_ALREADY_IN_USE ),
BIND_GLOBAL_CONSTANT( ERR_LOCKED ), ///< resource is locked

View file

@ -51,6 +51,7 @@
#include "packed_data_container.h"
#include "func_ref.h"
#include "input_map.h"
#include "undo_redo.h"
#ifdef XML_ENABLED
static ResourceFormatSaverXML *resource_saver_xml=NULL;
@ -128,7 +129,7 @@ void register_core_types() {
// ObjectTypeDB::register_type<OptimizedSaver>();
ObjectTypeDB::register_type<Translation>();
ObjectTypeDB::register_type<PHashTranslation>();
ObjectTypeDB::register_type<UndoRedo>();
ObjectTypeDB::register_type<HTTPClient>();
ObjectTypeDB::register_virtual_type<ResourceInteractiveLoader>();

Binary file not shown.

View file

@ -0,0 +1,23 @@
tool
extends EditorPlugin
var dock = null
func _enter_tree():
# When this plugin node enters tree, add the custom type
dock = preload("res://addons/custom_dock/custom_dock.scn").instance()
add_control_to_dock( DOCK_SLOT_LEFT_UL, dock )
func _exit_tree():
# Remove from docks (must be called so layout is updated and saved)
remove_control_from_docks(dock)
# Remove the node
dock.free()

View file

@ -0,0 +1,14 @@
[plugin]
name="Custom Dock"
description="Adds a new Customizable Dock"
author="Juan Linietsky"
version="1.0"
script="dock_plugin.gd"

View file

@ -0,0 +1,81 @@
tool
extends EditorImportPlugin
# Simple plugin that imports a text file with extension .mtxt
# which contains 3 integers in format R,G,B (0-255)
# (see example .mtxt in this folder)
# Imported file is converted to a material
var dialog = null
func get_name():
return "silly_material"
func get_visible_name():
return "Silly Material"
func import_dialog(path):
var md = null
if (path!=""):
md = ResourceLoader.load_import_metadata(path)
dialog.configure(self,path,md)
dialog.popup_centered()
func import(path,metadata):
assert(metadata.get_source_count() == 1)
var source = metadata.get_source_path(0)
var use_red_anyway = metadata.get_option("use_red_anyway")
var f = File.new()
var err = f.open(source,File.READ)
if (err!=OK):
return ERR_CANT_OPEN
var l = f.get_line()
f.close()
var channels = l.split(",")
if (channels.size()!=3):
return ERR_PARSE_ERROR
var color = Color8(int(channels[0]),int(channels[1]),int(channels[2]))
var material
if (ResourceLoader.has(path)):
# Material is in use, update it
material = ResourceLoader.load(path)
else:
# Material not in use, create
material = FixedMaterial.new()
if (use_red_anyway):
color=Color8(255,0,0)
material.set_parameter(FixedMaterial.PARAM_DIFFUSE,color)
# Make sure import metadata links to this plugin
metadata.set_editor("silly_material")
# Update the import metadata
material.set_import_metadata(metadata)
# Save
err = ResourceSaver.save(path,material)
return err
func config(base_control):
dialog = preload("res://addons/custom_import_plugin/material_dialog.tscn").instance()
base_control.add_child(dialog)

View file

@ -0,0 +1,67 @@
tool
extends ConfirmationDialog
var src_fs
var dst_fs
var import_plugin
func configure(p_import_plugin,path,metadata):
import_plugin=p_import_plugin
if (metadata):
# metadata from previous import exists, fill in fields
assert( metadata.get_source_count() > 0 )
# Always expand the source paths
var src_path = import_plugin.expand_source_path( metadata.get_source_path(0) )
get_node("src_file").set_text(src_path)
get_node("dst_file").set_text(path)
# Fill in from metadata options
get_node("use_red_anyway").set_pressed( metadata.get_option("use_red_anyway") )
func _ready():
src_fs = FileDialog.new()
src_fs.set_mode(FileDialog.MODE_OPEN_FILE)
src_fs.set_access(FileDialog.ACCESS_FILESYSTEM) #access all filesystem, not only res://
src_fs.add_filter("*.mtxt")
src_fs.connect("file_selected",self,"_on_src_selected")
add_child(src_fs)
dst_fs = EditorFileDialog.new()
dst_fs.set_mode(EditorFileDialog.MODE_SAVE_FILE)
dst_fs.add_filter("*.mtl") # Use binary extension always, text can't save metadata
dst_fs.connect("file_selected",self,"_on_dst_selected")
add_child(dst_fs)
set_hide_on_ok(true)
get_ok().set_text("Import!")
func _on_src_browse_pressed():
src_fs.popup_centered_ratio()
func _on_dst_browse_pressed():
dst_fs.popup_centered_ratio()
func _on_src_selected(path):
get_node("src_file").set_text(path)
func _on_dst_selected(path):
get_node("dst_file").set_text(path)
func _on_MaterialImport_confirmed():
# Create an import metadata
var imd = ResourceImportMetadata.new()
# Add the source files, always validate the source path
imd.add_source( import_plugin.validate_source_path( get_node("src_file").get_text() ))
# Add the options
imd.set_option( "use_red_anyway", get_node("use_red_anyway").is_pressed() )
# Perform regular import
var err = import_plugin.import( get_node("dst_file").get_text(), imd )
# Warn if error
if (err!=OK):
get_node("error").set_text("Error Importing!")
get_node("error").popup_centered_minsize()

View file

@ -0,0 +1,111 @@
[gd_scene load_steps=2 format=1]
[ext_resource path="res://addons/custom_import_plugin/material_dialog.gd" type="Script" id=1]
[node name="MaterialImport" type="ConfirmationDialog"]
margin/right = 276.0
margin/bottom = 154.0
focus/ignore_mouse = false
focus/stop_mouse = true
size_flags/horizontal = 2
size_flags/vertical = 2
popup/exclusive = false
window/title = "Silly Material Import"
dialog/hide_on_ok = true
script/script = ExtResource( 1 )
__meta__ = { "__editor_plugin_screen__":"Script" }
[node name="src_file" type="LineEdit" parent="."]
margin/left = 19.0
margin/top = 6.0
margin/right = 190.0
margin/bottom = 29.0
focus/ignore_mouse = false
focus/stop_mouse = true
size_flags/horizontal = 2
size_flags/vertical = 2
text = ""
max_length = 0
editable = true
secret = false
[node name="src_browse" type="Button" parent="."]
margin/left = 195.0
margin/top = 7.0
margin/right = 249.0
margin/bottom = 29.0
focus/ignore_mouse = false
focus/stop_mouse = true
size_flags/horizontal = 2
size_flags/vertical = 2
toggle_mode = false
text = "browse"
flat = false
[node name="dst_browse" type="Button" parent="."]
margin/left = 195.0
margin/top = 47.0
margin/right = 249.0
margin/bottom = 69.0
focus/ignore_mouse = false
focus/stop_mouse = true
size_flags/horizontal = 2
size_flags/vertical = 2
toggle_mode = false
text = "browse"
flat = false
[node name="dst_file" type="LineEdit" parent="."]
margin/left = 19.0
margin/top = 46.0
margin/right = 190.0
margin/bottom = 69.0
focus/ignore_mouse = false
focus/stop_mouse = true
size_flags/horizontal = 2
size_flags/vertical = 2
text = ""
max_length = 0
editable = true
secret = false
[node name="use_red_anyway" type="CheckBox" parent="."]
margin/left = 20.0
margin/top = 84.0
margin/right = 144.0
margin/bottom = 106.0
focus/ignore_mouse = false
focus/stop_mouse = true
size_flags/horizontal = 2
size_flags/vertical = 2
toggle_mode = true
text = "Use Red Anyway"
flat = false
align = 0
[node name="error" type="AcceptDialog" parent="."]
visibility/visible = false
margin/right = 40.0
margin/bottom = 40.0
focus/ignore_mouse = false
focus/stop_mouse = true
size_flags/horizontal = 2
size_flags/vertical = 2
popup/exclusive = false
window/title = "Alert!"
dialog/hide_on_ok = true
[connection signal="confirmed" from="." to="." method="_on_MaterialImport_confirmed"]
[connection signal="pressed" from="src_browse" to="." method="_on_src_browse_pressed"]
[connection signal="pressed" from="dst_browse" to="." method="_on_dst_browse_pressed"]

View file

@ -0,0 +1,22 @@
tool
extends EditorPlugin
var import_plugin
func _enter_tree():
import_plugin = preload("res://addons/custom_import_plugin/import_plugin.gd").new()
# pass the GUI base control, so the dialog has a parent node
import_plugin.config( get_base_control() )
add_import_plugin( import_plugin)
func _exit_tree():
remove_import_plugin( import_plugin )

View file

@ -0,0 +1,14 @@
[plugin]
name="Silly Material Importer"
description="Imports a 3D Material from an external text file"
author="Juan Linietsky"
version="1.0"
script="material_import.gd"

View file

@ -0,0 +1 @@
0,0,255

View file

@ -0,0 +1,12 @@
tool
extends Node2D
var heart = preload("res://addons/custom_node/heart.png")
func _draw():
draw_texture(heart,-heart.get_size()/2)
func _get_item_rect():
#override
return Rect2(-heart.get_size()/2,heart.get_size())

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 809 B

View file

@ -0,0 +1,18 @@
tool
extends EditorPlugin
func _enter_tree():
# When this plugin node enters tree, add the custom type
add_custom_type("Heart","Node2D",preload("res://addons/custom_node/heart.gd"),preload("res://addons/custom_node/heart_icon.png"))
func _exit_tree():
# When the plugin node exits the tree, remove the custom type
remove_custom_type("Heart")

View file

@ -0,0 +1,14 @@
[plugin]
name="Heart"
description="Adds a new Heart node in 2D"
author="Juan Linietsky"
version="1.0"
script="heart_plugin.gd"

13
demos/plugins/readme.txt Normal file
View file

@ -0,0 +1,13 @@
To install these, copy each of these folders to a folder:
addons/
inside your projects, example:
addons/custom_node
To distribute and install from UI, make a zip that contains the folder,
example:
zip -r custom_node.zip custom_node/*

File diff suppressed because it is too large Load diff

View file

@ -1481,6 +1481,11 @@ Variant GDScript::_new(const Variant** p_args,int p_argcount,Variant::CallError&
/* STEP 1, CREATE */
if (!valid) {
r_error.error=Variant::CallError::CALL_ERROR_INVALID_METHOD;
return Variant();
}
r_error.error=Variant::CallError::CALL_OK;
REF ref;
Object *owner=NULL;

View file

@ -190,7 +190,11 @@ void DocData::generate(bool p_basic_types) {
#ifdef DEBUG_METHODS_ENABLED
if (m && m->get_return_type()!=StringName())
method.return_type=m->get_return_type();
else if (arginfo.type!=Variant::NIL) // {
else if (method.name.find(":")!=-1) {
method.return_type=method.name.get_slice(":",1);
method.name=method.name.get_slice(":",0);
} else if (arginfo.type!=Variant::NIL) // {
#endif
method.return_type=(arginfo.hint==PROPERTY_HINT_RESOURCE_TYPE)?arginfo.hint_string:Variant::get_type_name(arginfo.type);
// }
@ -210,7 +214,7 @@ void DocData::generate(bool p_basic_types) {
} else if (arginfo.hint==PROPERTY_HINT_RESOURCE_TYPE) {
type_name=arginfo.hint_string;
} else if (arginfo.type==Variant::NIL)
type_name="var";
type_name="Variant";
else
type_name=Variant::get_type_name(arginfo.type);

View file

@ -171,6 +171,7 @@ void CreateDialog::_update_search() {
if (EditorNode::get_editor_data().get_custom_types().has(type)) {
//there are custom types based on this... cool.
//print_line("there are custom types");
const Vector<EditorData::CustomType> &ct = EditorNode::get_editor_data().get_custom_types()[type];
@ -259,7 +260,33 @@ Object *CreateDialog::instance_selected() {
TreeItem *selected = search_options->get_selected();
if (selected) {
return ObjectTypeDB::instance(selected->get_text(0));
String custom = selected->get_metadata(0);
if (custom!=String()) {
if (EditorNode::get_editor_data().get_custom_types().has(custom)) {
for(int i=0;i<EditorNode::get_editor_data().get_custom_types()[custom].size();i++) {
if (EditorNode::get_editor_data().get_custom_types()[custom][i].name==selected->get_text(0)) {
Ref<Texture> icon = EditorNode::get_editor_data().get_custom_types()[custom][i].icon;
Ref<Script> script = EditorNode::get_editor_data().get_custom_types()[custom][i].script;
String name = selected->get_text(0);
Object *ob = ObjectTypeDB::instance(custom);
ERR_FAIL_COND_V(!ob,NULL);
if (ob->is_type("Node")) {
ob->call("set_name",name);
}
ob->set_script(script.get_ref_ptr());
if (icon.is_valid())
ob->set_meta("_editor_icon",icon);
return ob;
}
}
}
} else {
return ObjectTypeDB::instance(selected->get_text(0));
}
}
return NULL;

View file

@ -422,6 +422,14 @@ void EditorData::add_editor_plugin(EditorPlugin *p_plugin) {
editor_plugins.push_back(p_plugin);
}
int EditorData::get_editor_plugin_count() const {
return editor_plugins.size();
}
EditorPlugin *EditorData::get_editor_plugin(int p_idx) {
ERR_FAIL_INDEX_V(p_idx,editor_plugins.size(),NULL);
return editor_plugins[p_idx];
}
void EditorData::add_custom_type(const String& p_type, const String& p_inherits,const Ref<Script>& p_script,const Ref<Texture>& p_icon ) {
@ -852,8 +860,8 @@ void EditorSelection::_bind_methods() {
ObjectTypeDB::bind_method(_MD("_node_removed"),&EditorSelection::_node_removed);
ObjectTypeDB::bind_method(_MD("clear"),&EditorSelection::clear);
ObjectTypeDB::bind_method(_MD("add_node","node"),&EditorSelection::add_node);
ObjectTypeDB::bind_method(_MD("remove_node","node"),&EditorSelection::remove_node);
ObjectTypeDB::bind_method(_MD("add_node","node:Node"),&EditorSelection::add_node);
ObjectTypeDB::bind_method(_MD("remove_node","node:Node"),&EditorSelection::remove_node);
ObjectTypeDB::bind_method(_MD("get_selected_nodes"),&EditorSelection::_get_selected_nodes);
ADD_SIGNAL( MethodInfo("selection_changed") );

View file

@ -165,6 +165,9 @@ public:
void add_editor_plugin(EditorPlugin *p_plugin);
void remove_editor_plugin(EditorPlugin *p_plugin);
int get_editor_plugin_count() const;
EditorPlugin *get_editor_plugin(int p_idx);
UndoRedo &get_undo_redo();
void save_editor_global_states();

View file

@ -1123,35 +1123,87 @@ void EditorHelp::_add_text(const String& p_bbcode) {
class_desc->push_indent(1);*/
int pos = 0;
String bbcode=p_bbcode.replace("\t"," ").replace("\r"," ").strip_edges();
//find double newlines, keep them
for(int i=0;i<bbcode.length();i++) {
//find valid newlines (double)
if (bbcode[i]=='\n') {
bool dnl=false;
int j=i+1;
for(;j<p_bbcode.length();j++) {
if (bbcode[j]==' ')
continue;
if (bbcode[j]=='\n') {
dnl=true;
break;
}
break;
}
if (dnl) {
bbcode[i]=0xFFFF;
i=j;
} else {
bbcode[i]=' ';
i=j-1;
}
}
}
//remove double spaces or spaces after newlines
for(int i=0;i<bbcode.length();i++) {
if (bbcode[i]==' ' || bbcode[i]==0xFFFF) {
for(int j=i+1;j<p_bbcode.length();j++) {
if (bbcode[j]==' ') {
bbcode.remove(j);
j--;
continue;
} else {
break;
}
}
}
}
//change newlines to double newlines
CharType dnls[2]={0xFFFF,0};
bbcode=bbcode.replace(dnls,"\n");
List<String> tag_stack;
while(pos < p_bbcode.length()) {
while(pos < bbcode.length()) {
int brk_pos = p_bbcode.find("[",pos);
int brk_pos = bbcode.find("[",pos);
if (brk_pos<0)
brk_pos=p_bbcode.length();
brk_pos=bbcode.length();
if (brk_pos > pos) {
class_desc->add_text(p_bbcode.substr(pos,brk_pos-pos));
class_desc->add_text(bbcode.substr(pos,brk_pos-pos));
}
if (brk_pos==p_bbcode.length())
if (brk_pos==bbcode.length())
break; //nothing else o add
int brk_end = p_bbcode.find("]",brk_pos+1);
int brk_end = bbcode.find("]",brk_pos+1);
if (brk_end==-1) {
//no close, add the rest
class_desc->add_text(p_bbcode.substr(brk_pos,p_bbcode.length()-brk_pos));
class_desc->add_text(bbcode.substr(brk_pos,bbcode.length()-brk_pos));
break;
}
String tag = p_bbcode.substr(brk_pos+1,brk_end-brk_pos-1);
String tag = bbcode.substr(brk_pos+1,brk_end-brk_pos-1);
if (tag.begins_with("/")) {
@ -1234,10 +1286,10 @@ void EditorHelp::_add_text(const String& p_bbcode) {
} else if (tag=="url") {
//use strikethrough (not supported underline instead)
int end=p_bbcode.find("[",brk_end);
int end=bbcode.find("[",brk_end);
if (end==-1)
end=p_bbcode.length();
String url = p_bbcode.substr(brk_end+1,end-brk_end-1);
end=bbcode.length();
String url = bbcode.substr(brk_end+1,end-brk_end-1);
class_desc->push_meta(url);
pos=brk_end+1;
@ -1251,10 +1303,10 @@ void EditorHelp::_add_text(const String& p_bbcode) {
} else if (tag=="img") {
//use strikethrough (not supported underline instead)
int end=p_bbcode.find("[",brk_end);
int end=bbcode.find("[",brk_end);
if (end==-1)
end=p_bbcode.length();
String image = p_bbcode.substr(brk_end+1,end-brk_end-1);
end=bbcode.length();
String image = bbcode.substr(brk_end+1,end-brk_end-1);
Ref<Texture> texture = ResourceLoader::load(base_path+"/"+image,"Texture");
if (texture.is_valid())

View file

@ -63,13 +63,30 @@ String EditorImportPlugin::expand_source_path(const String& p_path) {
}
}
String EditorImportPlugin::_validate_source_path(const String& p_path) {
return validate_source_path(p_path);
}
String EditorImportPlugin::_expand_source_path(const String& p_path) {
return expand_source_path(p_path);
}
void EditorImportPlugin::_bind_methods() {
ObjectTypeDB::bind_method(_MD("validate_source_path","path"),&EditorImportPlugin::_validate_source_path);
ObjectTypeDB::bind_method(_MD("expand_source_path","path"),&EditorImportPlugin::_expand_source_path);
ObjectTypeDB::add_virtual_method(get_type_static(),MethodInfo(Variant::STRING,"get_name"));
ObjectTypeDB::add_virtual_method(get_type_static(),MethodInfo(Variant::STRING,"get_visible_name"));
ObjectTypeDB::add_virtual_method(get_type_static(),MethodInfo("import_dialog",PropertyInfo(Variant::STRING,"from")));
ObjectTypeDB::add_virtual_method(get_type_static(),MethodInfo(Variant::INT,"import",PropertyInfo(Variant::STRING,"path"),PropertyInfo(Variant::OBJECT,"from",PROPERTY_HINT_RESOURCE_TYPE,"ResourceImportMetadata")));
ObjectTypeDB::add_virtual_method(get_type_static(),MethodInfo(Variant::RAW_ARRAY,"custom_export",PropertyInfo(Variant::STRING,"path")));
ObjectTypeDB::add_virtual_method(get_type_static(),MethodInfo(Variant::RAW_ARRAY,"custom_export",PropertyInfo(Variant::STRING,"path"),PropertyInfo(Variant::OBJECT,"platform",PROPERTY_HINT_RESOURCE_TYPE,"EditorExportPlatform")));
// BIND_VMETHOD( mi );
}
String EditorImportPlugin::get_name() const {
@ -113,8 +130,8 @@ Error EditorImportPlugin::import(const String& p_path, const Ref<ResourceImportM
Vector<uint8_t> EditorImportPlugin::custom_export(const String& p_path, const Ref<EditorExportPlatform> &p_platform) {
if (get_script_instance() && get_script_instance()->has_method("custom_export")) {
get_script_instance()->call("custom_export",p_path,p_platform);
if (get_script_instance() && get_script_instance()->has_method("_custom_export")) {
get_script_instance()->call("_custom_export",p_path,p_platform);
}
return Vector<uint8_t>();
@ -130,7 +147,7 @@ EditorImportPlugin::EditorImportPlugin() {
void EditorExportPlugin::_bind_methods() {
MethodInfo mi = MethodInfo("custom_export",PropertyInfo(Variant::STRING,"name"),PropertyInfo(Variant::OBJECT,"platform",PROPERTY_HINT_RESOURCE_TYPE,"EditorExportPlatform"));
MethodInfo mi = MethodInfo("custom_export:Variant",PropertyInfo(Variant::STRING,"name"),PropertyInfo(Variant::OBJECT,"platform",PROPERTY_HINT_RESOURCE_TYPE,"EditorExportPlatform"));
mi.return_val.type=Variant::RAW_ARRAY;
BIND_VMETHOD( mi );
@ -144,6 +161,9 @@ Vector<uint8_t> EditorExportPlugin::custom_export(String& p_path,const Ref<Edito
Variant d = get_script_instance()->call("custom_export",p_path,p_platform);
if (d.get_type()==Variant::NIL)
return Vector<uint8_t>();
if (d.get_type()==Variant::RAW_ARRAY)
return d;
ERR_FAIL_COND_V(d.get_type()!=Variant::DICTIONARY,Vector<uint8_t>());
Dictionary dict=d;
ERR_FAIL_COND_V(!dict.has("name"),Vector<uint8_t>());
@ -1458,11 +1478,14 @@ Ref<EditorImportPlugin> EditorImportExport::get_import_plugin_by_name(const Stri
void EditorImportExport::add_export_plugin(const Ref<EditorExportPlugin>& p_plugin) {
ERR_FAIL_COND( p_plugin.is_null() );
export_plugins.push_back(p_plugin);
}
void EditorImportExport::remove_export_plugin(const Ref<EditorExportPlugin>& p_plugin) {
ERR_FAIL_COND( p_plugin.is_null() );
export_plugins.erase(p_plugin);
}

View file

@ -46,6 +46,10 @@ protected:
static void _bind_methods();
String _validate_source_path(const String& p_path);
String _expand_source_path(const String& p_path);
public:

View file

@ -2952,16 +2952,109 @@ void EditorNode::remove_editor_plugin(EditorPlugin *p_editor) {
void EditorNode::add_editor_import_plugin(const Ref<EditorImportPlugin>& p_editor_import) {
ERR_FAIL_COND( p_editor_import.is_null() );
editor_import_export->add_import_plugin(p_editor_import);
_rebuild_import_menu();
}
void EditorNode::remove_editor_import_plugin(const Ref<EditorImportPlugin>& p_editor_import) {
ERR_FAIL_COND( p_editor_import.is_null() );
editor_import_export->remove_import_plugin(p_editor_import);
_rebuild_import_menu();
}
void EditorNode::_update_addon_config() {
if (_initializing_addons)
return;
Vector<String> enabled_addons;
for(Map<String,EditorPlugin*>::Element *E=plugin_addons.front();E;E=E->next()) {
enabled_addons.push_back(E->key());
}
if (enabled_addons.size()==0) {
Globals::get_singleton()->set("editor_plugins/enabled",Variant());
Globals::get_singleton()->set_persisting("editor_plugins/enabled",false);
} else {
Globals::get_singleton()->set("editor_plugins/enabled",enabled_addons);
Globals::get_singleton()->set_persisting("editor_plugins/enabled",true);
}
project_settings->queue_save();
}
void EditorNode::set_addon_plugin_enabled(const String& p_addon,bool p_enabled) {
ERR_FAIL_COND(p_enabled && plugin_addons.has(p_addon));
ERR_FAIL_COND(!p_enabled && !plugin_addons.has(p_addon));
if (!p_enabled) {
EditorPlugin *addon = plugin_addons[p_addon];
memdelete(addon); //bye
plugin_addons.erase(p_addon);
_update_addon_config();
return;
}
Ref<ConfigFile> cf;
cf.instance();
String addon_path = "res://addons/"+p_addon+"/plugin.cfg";
Error err = cf->load(addon_path);
if (err!=OK) {
show_warning("Unable to enable addon plugin at: '"+addon_path+"' parsing of config failed.");
return;
}
if (!cf->has_section_key("plugin","script")) {
show_warning("Unable to find script field for addon plugin at: 'res://addons/"+p_addon+"''.");
return;
}
String path = cf->get_value("plugin","script");
path="res://addons/"+p_addon+"/"+path;
Ref<Script> script = ResourceLoader::load(path);
if (script.is_null()) {
show_warning("Unable to load addon script from path: '"+path+"'.");
return;
}
//could check inheritance..
if (String(script->get_instance_base_type())!="EditorPlugin") {
show_warning("Unable to load addon script from path: '"+path+"' Base type is not EditorPlugin.");
return;
}
if (!script->is_tool()) {
show_warning("Unable to load addon script from path: '"+path+"' Script is does not support tool mode.");
return;
}
EditorPlugin *ep = memnew( EditorPlugin );
ep->set_script(script.get_ref_ptr());
plugin_addons[p_addon]=ep;
add_editor_plugin(ep);
_update_addon_config();
}
bool EditorNode::is_addon_plugin_enabled(const String& p_addon) const {
return plugin_addons.has(p_addon);
}
void EditorNode::_remove_edited_scene() {
int new_index = editor_data.get_edited_scene();
int old_index=new_index;
@ -3955,9 +4048,9 @@ void EditorNode::register_editor_types() {
ObjectTypeDB::register_type<EditorScript>();
ObjectTypeDB::register_type<EditorSelection>();
ObjectTypeDB::register_type<EditorFileDialog>();
ObjectTypeDB::register_type<EditorImportExport>();
//ObjectTypeDB::register_type<EditorImportExport>();
ObjectTypeDB::register_type<EditorSettings>();
ObjectTypeDB::register_type<UndoRedo>();
ObjectTypeDB::register_type<EditorSpatialGizmo>();
//ObjectTypeDB::register_type<EditorImporter>();
@ -4360,6 +4453,51 @@ void EditorNode::_load_docks() {
}
void EditorNode::_update_dock_slots_visibility() {
VSplitContainer*splits[DOCK_SLOT_MAX/2]={
left_l_vsplit,
left_r_vsplit,
right_l_vsplit,
right_r_vsplit,
};
HSplitContainer*h_splits[4]={
left_l_hsplit,
left_r_hsplit,
main_hsplit,
right_hsplit,
};
for(int i=0;i<DOCK_SLOT_MAX;i++) {
if (dock_slot[i]->get_tab_count())
dock_slot[i]->show();
else
dock_slot[i]->hide();
}
for(int i=0;i<DOCK_SLOT_MAX/2;i++) {
bool in_use = dock_slot[i*2+0]->get_tab_count() || dock_slot[i*2+1]->get_tab_count();
if (in_use)
splits[i]->show();
else
splits[i]->hide();
}
for(int i=0;i<DOCK_SLOT_MAX;i++) {
if (!dock_slot[i]->is_hidden() && dock_slot[i]->get_tab_count()) {
dock_slot[i]->set_current_tab(0);
}
}
}
void EditorNode::_load_docks_from_config(Ref<ConfigFile> p_layout, const String& p_section) {
for(int i=0;i<DOCK_SLOT_MAX;i++) {
@ -4697,6 +4835,31 @@ void EditorNode::_bottom_panel_switch(bool p_enable,int p_idx) {
}
}
void EditorNode::add_control_to_dock(DockSlot p_slot,Control* p_control) {
ERR_FAIL_INDEX(p_slot,DOCK_SLOT_MAX);
dock_slot[p_slot]->add_child(p_control);
_update_dock_slots_visibility();
}
void EditorNode::remove_control_from_dock(Control* p_control) {
Control *dock=NULL;
for(int i=0;i<DOCK_SLOT_MAX;i++) {
if (p_control->get_parent()==dock_slot[i]) {
dock=dock_slot[i];
break;
}
}
ERR_EXPLAIN("Control was not in dock");
ERR_FAIL_COND(!dock);
dock->remove_child(p_control);
_update_dock_slots_visibility();
}
void EditorNode::_bind_methods() {
@ -4787,6 +4950,7 @@ EditorNode::EditorNode() {
EditorHelp::generate_doc(); //before any editor classes are crated
SceneState::set_disable_placeholders(true);
InputDefault *id = Input::get_singleton()->cast_to<InputDefault>();
if (id) {
@ -4802,6 +4966,7 @@ EditorNode::EditorNode() {
singleton=this;
last_checked_version=0;
changing_scene=false;
_initializing_addons=false;
FileAccess::set_backup_save(true);
@ -6061,7 +6226,7 @@ EditorNode::EditorNode() {
}
EditorSettings::get_singleton()->enable_plugins();
Node::set_human_readable_collision_renaming(true);
@ -6077,6 +6242,19 @@ EditorNode::EditorNode() {
editor_data.set_edited_scene(0);
_update_scene_tabs();
{
_initializing_addons=true;
Vector<String> addons = Globals::get_singleton()->get("editor_plugins/enabled");
for(int i=0;i<addons.size();i++) {
set_addon_plugin_enabled(addons[i],true);
}
_initializing_addons=false;
}
_load_docks();

View file

@ -101,6 +101,19 @@ class EditorNode : public Node {
OBJ_TYPE( EditorNode, Node );
public:
enum DockSlot {
DOCK_SLOT_LEFT_UL,
DOCK_SLOT_LEFT_BL,
DOCK_SLOT_LEFT_UR,
DOCK_SLOT_LEFT_BR,
DOCK_SLOT_RIGHT_UL,
DOCK_SLOT_RIGHT_BL,
DOCK_SLOT_RIGHT_UR,
DOCK_SLOT_RIGHT_BR,
DOCK_SLOT_MAX
};
private:
enum {
HISTORY_SIZE=64
};
@ -182,17 +195,6 @@ class EditorNode : public Node {
OBJECT_METHOD_BASE=500
};
enum DockSlot {
DOCK_SLOT_LEFT_UL,
DOCK_SLOT_LEFT_BL,
DOCK_SLOT_LEFT_UR,
DOCK_SLOT_LEFT_BR,
DOCK_SLOT_RIGHT_UL,
DOCK_SLOT_RIGHT_BL,
DOCK_SLOT_RIGHT_UR,
DOCK_SLOT_RIGHT_BR,
DOCK_SLOT_MAX
};
//Node *edited_scene; //scene being edited
@ -479,6 +481,10 @@ class EditorNode : public Node {
Map<String,Ref<Texture> > icon_type_cache;
bool _initializing_addons;
Map<String,EditorPlugin*> plugin_addons;
static Ref<Texture> _file_dialog_get_icon(const String& p_path);
static void _file_dialog_register(FileDialog *p_dialog);
static void _file_dialog_unregister(FileDialog *p_dialog);
@ -541,6 +547,8 @@ class EditorNode : public Node {
void _load_docks();
void _save_docks_to_config(Ref<ConfigFile> p_layout, const String& p_section);
void _load_docks_from_config(Ref<ConfigFile> p_layout, const String& p_section);
void _update_dock_slots_visibility();
void _update_layouts_menu();
void _layout_menu_option(int p_idx);
@ -549,6 +557,9 @@ class EditorNode : public Node {
void _clear_search_box();
void _clear_undo_history();
void _update_addon_config();
protected:
void _notification(int p_what);
static void _bind_methods();
@ -570,9 +581,14 @@ public:
static void add_editor_plugin(EditorPlugin *p_editor);
static void remove_editor_plugin(EditorPlugin *p_editor);
void add_control_to_dock(DockSlot p_slot,Control* p_control);
void remove_control_from_dock(Control* p_control);
void add_editor_import_plugin(const Ref<EditorImportPlugin>& p_editor_import);
void remove_editor_import_plugin(const Ref<EditorImportPlugin>& p_editor_import);
void set_addon_plugin_enabled(const String& p_addon,bool p_enabled);
bool is_addon_plugin_enabled(const String &p_addon) const;
void edit_node(Node *p_node);
void edit_resource(const Ref<Resource>& p_resource);

View file

@ -48,6 +48,19 @@ void EditorPlugin::add_control_to_bottom_dock(Control *p_control, const String &
EditorNode::get_singleton()->add_bottom_panel_item(p_title,p_control);
}
void EditorPlugin::add_control_to_dock(DockSlot p_slot,Control *p_control) {
ERR_FAIL_NULL(p_control);
EditorNode::get_singleton()->add_control_to_dock(EditorNode::DockSlot(p_slot),p_control);
}
void EditorPlugin::remove_control_from_docks(Control *p_control) {
ERR_FAIL_NULL(p_control);
EditorNode::get_singleton()->remove_control_from_dock(p_control);
}
void EditorPlugin::add_control_to_container(CustomControlContainer p_location,Control *p_control) {
@ -94,9 +107,13 @@ void EditorPlugin::add_control_to_container(CustomControlContainer p_location,Co
}
}
bool EditorPlugin::create_spatial_gizmo(Spatial* p_spatial) {
Ref<SpatialEditorGizmo> EditorPlugin::create_spatial_gizmo(Spatial* p_spatial) {
//??
return false;
if (get_script_instance() && get_script_instance()->has_method("create_spatial_gizmo")) {
return get_script_instance()->call("create_spatial_gizmo",p_spatial);
}
return Ref<SpatialEditorGizmo>();
}
bool EditorPlugin::forward_input_event(const InputEvent& p_event) {
@ -218,27 +235,65 @@ EditorSelection* EditorPlugin::get_selection() {
return EditorNode::get_singleton()->get_editor_selection();
}
EditorImportExport *EditorPlugin::get_import_export() {
return EditorImportExport::get_singleton();
}
EditorSettings *EditorPlugin::get_editor_settings() {
return EditorSettings::get_singleton();
}
void EditorPlugin::add_import_plugin(const Ref<EditorImportPlugin>& p_editor_import) {
EditorNode::get_singleton()->add_editor_import_plugin(p_editor_import);
}
void EditorPlugin::remove_import_plugin(const Ref<EditorImportPlugin>& p_editor_import){
EditorNode::get_singleton()->remove_editor_import_plugin(p_editor_import);
}
void EditorPlugin::add_export_plugin(const Ref<EditorExportPlugin>& p_editor_export){
EditorImportExport::get_singleton()->add_export_plugin(p_editor_export);
}
void EditorPlugin::remove_export_plugin(const Ref<EditorExportPlugin>& p_editor_export){
EditorImportExport::get_singleton()->remove_export_plugin(p_editor_export);
}
Control *EditorPlugin::get_base_control() {
return EditorNode::get_singleton()->get_gui_base();
}
void EditorPlugin::_bind_methods() {
ObjectTypeDB::bind_method(_MD("add_control_to_container","container","control:Control"),&EditorPlugin::add_control_to_container);
ObjectTypeDB::bind_method(_MD("add_control_to_bottom_dock","control:Control","title"),&EditorPlugin::add_control_to_bottom_dock);
ObjectTypeDB::bind_method(_MD("add_control_to_dock","slot","control:Control"),&EditorPlugin::add_control_to_dock);
ObjectTypeDB::bind_method(_MD("remove_control_from_docks","control:Control"),&EditorPlugin::remove_control_from_docks);
ObjectTypeDB::bind_method(_MD("add_custom_type","type","base","script:Script","icon:Texture"),&EditorPlugin::add_custom_type);
ObjectTypeDB::bind_method(_MD("remove_custom_type","type"),&EditorPlugin::remove_custom_type);
ObjectTypeDB::bind_method(_MD("add_import_plugin","plugin:EditorImportPlugin"),&EditorPlugin::add_import_plugin);
ObjectTypeDB::bind_method(_MD("remove_import_plugin","plugin:EditorImportPlugin"),&EditorPlugin::remove_import_plugin);
ObjectTypeDB::bind_method(_MD("add_export_plugin","plugin:EditorExportPlugin"),&EditorPlugin::add_export_plugin);
ObjectTypeDB::bind_method(_MD("remove_export_plugin","plugin:EditorExportPlugin"),&EditorPlugin::remove_export_plugin);
ObjectTypeDB::bind_method(_MD("get_base_control:Control"),&EditorPlugin::get_base_control);
ObjectTypeDB::bind_method(_MD("get_undo_redo:UndoRedo"),&EditorPlugin::_get_undo_redo);
ObjectTypeDB::bind_method(_MD("get_selection:EditorSelection"),&EditorPlugin::get_selection);
ObjectTypeDB::bind_method(_MD("get_import_export:EditorImportExport"),&EditorPlugin::get_import_export);
ObjectTypeDB::bind_method(_MD("get_editor_settings:EditorSettings"),&EditorPlugin::get_import_export);
ObjectTypeDB::bind_method(_MD("get_editor_settings:EditorSettings"),&EditorPlugin::get_editor_settings);
ObjectTypeDB::add_virtual_method(get_type_static(),MethodInfo(Variant::BOOL,"forward_input_event",PropertyInfo(Variant::INPUT_EVENT,"event")));
ObjectTypeDB::add_virtual_method(get_type_static(),MethodInfo(Variant::BOOL,"forward_spatial_input_event",PropertyInfo(Variant::OBJECT,"camera",PROPERTY_HINT_RESOURCE_TYPE,"Camera"),PropertyInfo(Variant::INPUT_EVENT,"event")));
MethodInfo gizmo = MethodInfo(Variant::OBJECT,"create_spatial_gizmo",PropertyInfo(Variant::OBJECT,"for_spatial:Spatial"));
gizmo.return_val.hint=PROPERTY_HINT_RESOURCE_TYPE;
gizmo.return_val.hint_string="EditorSpatialGizmo";
ObjectTypeDB::add_virtual_method(get_type_static(),gizmo);
ObjectTypeDB::add_virtual_method(get_type_static(),MethodInfo(Variant::STRING,"get_name"));
ObjectTypeDB::add_virtual_method(get_type_static(),MethodInfo(Variant::BOOL,"has_main_screen"));
ObjectTypeDB::add_virtual_method(get_type_static(),MethodInfo("make_visible",PropertyInfo(Variant::BOOL,"visible")));
@ -257,6 +312,16 @@ void EditorPlugin::_bind_methods() {
BIND_CONSTANT( CONTAINER_CANVAS_EDITOR_MENU );
BIND_CONSTANT( CONTAINER_CANVAS_EDITOR_SIDE );
BIND_CONSTANT( DOCK_SLOT_LEFT_UL );
BIND_CONSTANT( DOCK_SLOT_LEFT_BL );
BIND_CONSTANT( DOCK_SLOT_LEFT_UR );
BIND_CONSTANT( DOCK_SLOT_LEFT_BR );
BIND_CONSTANT( DOCK_SLOT_RIGHT_UL );
BIND_CONSTANT( DOCK_SLOT_RIGHT_BL );
BIND_CONSTANT( DOCK_SLOT_RIGHT_UR );
BIND_CONSTANT( DOCK_SLOT_RIGHT_BR );
BIND_CONSTANT( DOCK_SLOT_MAX );
}
EditorPlugin::EditorPlugin()

View file

@ -43,6 +43,9 @@ class Camera;
class EditorSelection;
class EditorImportExport;
class EditorSettings;
class SpatialEditorGizmo;
class EditorImportPlugin;
class EditorExportPlugin;
class EditorPlugin : public Node {
@ -73,12 +76,26 @@ public:
CONTAINER_CANVAS_EDITOR_BOTTOM
};
enum DockSlot {
DOCK_SLOT_LEFT_UL,
DOCK_SLOT_LEFT_BL,
DOCK_SLOT_LEFT_UR,
DOCK_SLOT_LEFT_BR,
DOCK_SLOT_RIGHT_UL,
DOCK_SLOT_RIGHT_BL,
DOCK_SLOT_RIGHT_UR,
DOCK_SLOT_RIGHT_BR,
DOCK_SLOT_MAX
};
//TODO: send a resoucre for editing to the editor node?
void add_control_to_container(CustomControlContainer p_location, Control *p_control);
void add_control_to_bottom_dock(Control *p_control, const String &p_title);
void add_control_to_dock(DockSlot p_slot,Control *p_control);
void remove_control_from_docks(Control *p_control);
virtual bool create_spatial_gizmo(Spatial* p_spatial);
virtual Ref<SpatialEditorGizmo> create_spatial_gizmo(Spatial* p_spatial);
virtual bool forward_input_event(const InputEvent& p_event);
virtual bool forward_spatial_input_event(Camera* p_camera,const InputEvent& p_event);
virtual String get_name() const;
@ -99,8 +116,16 @@ public:
virtual void edited_scene_changed(){}; // if changes are pending in editor, apply them
Control *get_base_control();
void add_import_plugin(const Ref<EditorImportPlugin>& p_editor_import);
void remove_import_plugin(const Ref<EditorImportPlugin>& p_editor_import);
void add_export_plugin(const Ref<EditorExportPlugin>& p_editor_export);
void remove_export_plugin(const Ref<EditorExportPlugin>& p_editor_export);
EditorSelection* get_selection();
EditorImportExport *get_import_export();
//EditorImportExport *get_import_export();
EditorSettings *get_editor_settings();
virtual void restore_global_state();
@ -112,6 +137,7 @@ public:
};
VARIANT_ENUM_CAST( EditorPlugin::CustomControlContainer );
VARIANT_ENUM_CAST( EditorPlugin::DockSlot );
typedef EditorPlugin* (*EditorPluginCreateFunc)(EditorNode *);

View file

@ -0,0 +1,188 @@
#include "editor_plugin_settings.h"
#include "scene/gui/margin_container.h"
#include "io/config_file.h"
#include "os/file_access.h"
#include "os/main_loop.h"
#include "globals.h"
#include "editor_node.h"
void EditorPluginSettings::_notification(int p_what) {
if (p_what==MainLoop::NOTIFICATION_WM_FOCUS_IN) {
update_plugins();
}
}
void EditorPluginSettings::update_plugins() {
plugin_list->clear();
DirAccess *da = DirAccess::create(DirAccess::ACCESS_RESOURCES);
Error err = da->change_dir("res://addons");
if (err!=OK) {
memdelete(da);
return;
}
updating=true;
TreeItem *root = plugin_list->create_item();
da->list_dir_begin();
String d = da->get_next();
Vector<String> plugins;
while(d!=String()) {
bool dir = da->current_is_dir();
String path = "res://addons/"+d+"/plugin.cfg";
if (dir && FileAccess::exists(path)) {
plugins.push_back(d);
}
d = da->get_next();
}
da->list_dir_end();
memdelete(da);
plugins.sort();
Vector<String> active_plugins = Globals::get_singleton()->get("plugins/active");
for(int i=0;i<plugins.size();i++) {
Ref<ConfigFile> cf;
cf.instance();
String path = "res://addons/"+plugins[i]+"/plugin.cfg";
Error err = cf->load(path);
if (err!=OK) {
WARN_PRINTS("Can't load plugin config: "+path);
} else if (!cf->has_section_key("plugin","name")) {
WARN_PRINTS("Plugin misses plugin/name: "+path);
} else if (!cf->has_section_key("plugin","author")) {
WARN_PRINTS("Plugin misses plugin/author: "+path);
} else if (!cf->has_section_key("plugin","version")) {
WARN_PRINTS("Plugin misses plugin/version: "+path);
} else if (!cf->has_section_key("plugin","description")) {
WARN_PRINTS("Plugin misses plugin/description: "+path);
} else if (!cf->has_section_key("plugin","script")) {
WARN_PRINTS("Plugin misses plugin/script: "+path);
} else {
String d = plugins[i];
String name = cf->get_value("plugin","name");
String author = cf->get_value("plugin","author");
String version = cf->get_value("plugin","version");
String description = cf->get_value("plugin","description");
String script = cf->get_value("plugin","script");
TreeItem *item = plugin_list->create_item(root);
item->set_text(0,name);
item->set_tooltip(0,"Name: "+name+"\nPath: "+path+"\nMain Script: "+script);
item->set_metadata(0,d);
item->set_text(1,version);
item->set_metadata(1,script);
item->set_text(2,author);
item->set_metadata(2,description);
item->set_cell_mode(3,TreeItem::CELL_MODE_RANGE);
item->set_range_config(3,0,1,1);
item->set_text(3,"Inactive,Active");
item->set_editable(3,true);
if (EditorNode::get_singleton()->is_addon_plugin_enabled(d)) {
item->set_custom_color(3,Color(0.2,1,0.2));
item->set_range(3,1);
} else {
item->set_custom_color(3,Color(1,0.2,0.2));
item->set_range(3,0);
}
}
}
updating=false;
}
void EditorPluginSettings::_plugin_activity_changed() {
if (updating)
return;
TreeItem *ti=plugin_list->get_edited();
ERR_FAIL_COND(!ti);
bool active = ti->get_range(3);
String name = ti->get_metadata(0);
EditorNode::get_singleton()->set_addon_plugin_enabled(name,active);
bool is_active = EditorNode::get_singleton()->is_addon_plugin_enabled(name);
if (is_active!=active) {
updating=true;
ti->set_range(3,is_active?1:0);
updating=false;
}
if (is_active)
ti->set_custom_color(3,Color(0.2,1,0.2));
else
ti->set_custom_color(3,Color(1,0.2,0.2));
}
void EditorPluginSettings::_bind_methods() {
ObjectTypeDB::bind_method("update_plugins",&EditorPluginSettings::update_plugins);
ObjectTypeDB::bind_method("_plugin_activity_changed",&EditorPluginSettings::_plugin_activity_changed);
}
EditorPluginSettings::EditorPluginSettings() {
HBoxContainer *title_hb = memnew( HBoxContainer );
title_hb->add_child(memnew( Label("Installed Plugins:")));
title_hb->add_spacer();
update_list = memnew( Button("Update") );
update_list->connect("pressed",this,"update_plugins");
title_hb->add_child(update_list);
add_child(title_hb);
plugin_list = memnew( Tree );
plugin_list->set_v_size_flags(SIZE_EXPAND_FILL);
plugin_list->set_columns(4);
plugin_list->set_column_titles_visible(true);
plugin_list->set_column_title(0,"Name:");
plugin_list->set_column_title(1,"Version:");
plugin_list->set_column_title(2,"Author:");
plugin_list->set_column_title(3,"Status:");
plugin_list->set_column_expand(0,true);
plugin_list->set_column_expand(1,false);
plugin_list->set_column_expand(2,false);
plugin_list->set_column_expand(3,false);
plugin_list->set_column_min_width(1,100);
plugin_list->set_column_min_width(2,250);
plugin_list->set_column_min_width(3,80);
plugin_list->set_hide_root(true);
plugin_list->connect("item_edited",this,"_plugin_activity_changed");
MarginContainer *mc = memnew( MarginContainer );
mc->add_child(plugin_list);
mc->set_v_size_flags(SIZE_EXPAND_FILL);
add_child(mc);
updating=false;
}

View file

@ -0,0 +1,35 @@
#ifndef EDITORPLUGINSETTINGS_H
#define EDITORPLUGINSETTINGS_H
#include "scene/gui/dialogs.h"
#include "property_editor.h"
#include "optimized_save_dialog.h"
#include "undo_redo.h"
#include "editor_data.h"
class EditorPluginSettings : public VBoxContainer {
OBJ_TYPE(EditorPluginSettings,VBoxContainer);
Button* update_list;
Tree *plugin_list;
bool updating;
void _plugin_activity_changed();
protected:
void _notification(int p_what);
static void _bind_methods();
public:
void update_plugins();
EditorPluginSettings();
};
#endif // EDITORPLUGINSETTINGS_H

View file

@ -228,13 +228,6 @@ void EditorSettings::create() {
dir->change_dir("..");
}
if (dir->change_dir("plugins")!=OK) {
dir->make_dir("plugins");
} else {
dir->change_dir("..");
}
if (dir->change_dir("config")!=OK) {
dir->make_dir("config");
} else {
@ -287,7 +280,6 @@ void EditorSettings::create() {
singleton->setup_network();
singleton->load_favorites();
singleton->scan_plugins();
return;
@ -312,7 +304,6 @@ void EditorSettings::create() {
singleton->settings_path=config_path+"/"+config_dir;
singleton->_load_defaults(extra_config);
singleton->setup_network();
singleton->scan_plugins();
}
@ -323,35 +314,6 @@ String EditorSettings::get_settings_path() const {
}
Error EditorSettings::_load_plugin(const String& p_path, Plugin &plugin) {
if (!FileAccess::exists(p_path))
return ERR_FILE_NOT_FOUND;
Ref<ConfigFile> cf = memnew(ConfigFile);
Error err = cf->load(p_path);
ERR_EXPLAIN("Error loading plugin description for: "+p_path);
ERR_FAIL_COND_V(err!=OK,ERR_CANT_OPEN);
plugin.instance=NULL;
ERR_FAIL_COND_V(!cf->has_section_key("plugin","name"),ERR_INVALID_DATA);
ERR_FAIL_COND_V(!cf->has_section_key("plugin","installs"),ERR_INVALID_DATA);
ERR_FAIL_COND_V(!cf->has_section_key("plugin","author"),ERR_INVALID_DATA);
ERR_FAIL_COND_V(!cf->has_section_key("plugin","version"),ERR_INVALID_DATA);
ERR_FAIL_COND_V(!cf->has_section_key("plugin","script"),ERR_INVALID_DATA);
plugin.name=cf->get_value("plugin","name");
plugin.author=cf->get_value("plugin","author");
plugin.version=cf->get_value("plugin","version");
plugin.script=cf->get_value("plugin","script");
if (cf->has_section_key("plugin","description"))
plugin.description=cf->get_value("plugin","description");
plugin.installs=cf->get_value("plugin","installs");
if (cf->has_section_key("plugin","install_files"))
plugin.install_files=cf->get_value("plugin","install_files");
return OK;
}
void EditorSettings::setup_network() {
@ -382,46 +344,6 @@ void EditorSettings::setup_network() {
}
void EditorSettings::scan_plugins() {
Map<String,Plugin> new_plugins;
new_plugins.clear();
DirAccess *d = DirAccess::create(DirAccess::ACCESS_FILESYSTEM);
Error err = d->change_dir(get_settings_path().plus_file("plugins"));
if (err!=OK) {
memdelete(d);
ERR_EXPLAIN("Plugin dir does not exist!")
ERR_FAIL_COND(err!=OK);
}
d->list_dir_begin();
String base = d->get_current_dir();
//print_line("list diring on: "+base);
while(true) {
String p = d->get_next();
if (p=="")
break;
if (!d->current_is_dir() || p.begins_with("."))
continue;
String cfpath=d->get_current_dir().plus_file(p+"/plugin.cfg");
Plugin plugin;
Error err = _load_plugin(cfpath,plugin);
ERR_CONTINUE(err!=OK);
if (plugins.has(p))
plugin.instance=plugins[p].instance;
new_plugins[p]=plugin;
}
plugins=new_plugins;
memdelete(d);
}
void EditorSettings::save() {
@ -623,148 +545,9 @@ void EditorSettings::add_property_hint(const PropertyInfo& p_hint) {
}
bool EditorSettings::is_plugin_enabled(const String& p_plugin) {
if (!has("_plugins/enabled"))
return false;
StringArray sa=get("_plugins/enabled");
for(int i=0;i<sa.size();i++) {
String plugin = sa[i];
if (!plugins.has(plugin))
continue;
if (plugin==p_plugin)
return true;
}
return false;
}
void EditorSettings::enable_plugins() {
// editor plugins
if (has("_plugins/enabled")) {
StringArray sa=get("_plugins/enabled");
for(int i=0;i<sa.size();i++) {
String plugin = sa[i];
if (!plugins.has(plugin))
continue;
if (plugins[plugin].installs)
continue; //not configured here
set_plugin_enabled(plugin,true);
}
}
// installed plugins
List<PropertyInfo> pi;
Globals::get_singleton()->get_property_list(&pi);
for (List<PropertyInfo>::Element *E=pi.front();E;E=E->next()) {
String p = E->get().name;
if (p.begins_with("plugins/")) {
load_installed_plugin(p.replace_first("plugins/",""));
}
}
}
void EditorSettings::load_installed_plugin(const String& p_plugin) {
ERR_FAIL_COND( !Globals::get_singleton()->has("plugins/"+p_plugin) );
String path = Globals::get_singleton()->get("plugins/"+p_plugin);
Plugin plugin;
Error err = _load_plugin(path.plus_file("plugin.cfg"),plugin);
if (err)
return;
print_line("installing plugin...");
EditorPlugin *ep=_load_plugin_editor(path.plus_file(plugin.script));
ERR_FAIL_COND(!ep);
print_line("load!");
EditorNode::add_editor_plugin(ep);
}
EditorPlugin *EditorSettings::_load_plugin_editor(const String& p_path) {
Ref<Script> script = ResourceLoader::load(p_path);
ERR_EXPLAIN("Invalid Script for plugin: "+p_path);
ERR_FAIL_COND_V(script.is_null(),NULL);
ERR_EXPLAIN("Script has errors: "+p_path);
ERR_FAIL_COND_V(!script->can_instance(),NULL);
ERR_EXPLAIN("Script does not inherit EditorPlugin: "+p_path);
ERR_FAIL_COND_V(script->get_instance_base_type().operator String()!="EditorPlugin",NULL);
EditorPlugin *ep = memnew( EditorPlugin );
ep->set_script(script.get_ref_ptr());
if (!ep->get_script_instance()) {
memdelete(ep);
ERR_EXPLAIN("Script could't load: "+p_path);
ERR_FAIL_V(NULL);
}
return ep;
}
void EditorSettings::set_plugin_enabled(const String& p_plugin, bool p_enabled) {
ERR_FAIL_COND(!plugins.has(p_plugin));
if (p_enabled == (plugins[p_plugin].instance!=NULL)) //already enabled or disabled
return;
print_line("REQUEST "+p_plugin+" to "+itos(p_enabled));
StringArray sa;
if (has("_plugins/enabled"))
sa=get("_plugins/enabled");
int idx=-1;
for(int i=0;i<sa.size();i++) {
if (sa[i]==p_plugin) {
idx=i;
break;
}
}
if (p_enabled) {
String ppath = get_settings_path().plus_file("plugins/"+p_plugin+"/"+plugins[p_plugin].script);
EditorPlugin *ep=_load_plugin_editor(ppath);
if (!ep)
return;
plugins[p_plugin].instance=ep;
EditorNode::add_editor_plugin(ep);
if (idx==-1)
sa.push_back(p_plugin);
} else {
print_line("DISABLING");
EditorNode::remove_editor_plugin(plugins[p_plugin].instance);
memdelete(plugins[p_plugin].instance);
plugins[p_plugin].instance=NULL;
if (idx!=-1)
sa.remove(idx);
}
if (sa.size()==0)
set("_plugins/enabled",Variant());
else
set("_plugins/enabled",sa);
}
void EditorSettings::set_favorite_dirs(const Vector<String>& p_favorites) {

View file

@ -57,7 +57,6 @@ public:
Vector<String> install_files;
};
private:
Map<String,Plugin> plugins;
struct VariantContainer {
int order;
@ -84,9 +83,6 @@ private:
Ref<Resource> clipboard;
EditorPlugin *_load_plugin_editor(const String& p_path);
Error _load_plugin(const String& p_path,Plugin& plugin);
void _load_defaults(Ref<ConfigFile> p_extra_config = NULL);
String project_config_path;
@ -111,10 +107,7 @@ public:
//String get_global_settings_path() const;
String get_project_settings_path() const;
const Map<String,Plugin>& get_plugins() const { return plugins; }
void scan_plugins();
void enable_plugins();
void setup_network();
void raise_order(const String& p_name);
@ -124,11 +117,6 @@ public:
void notify_changes();
void set_plugin_enabled(const String& p_plugin,bool p_enabled);
bool is_plugin_enabled(const String& p_plugin);
void load_installed_plugin(const String& p_plugin);
void set_resource_clipboard(const Ref<Resource>& p_resource) { clipboard=p_resource; }
Ref<Resource> get_resource_clipboard() const { return clipboard; }

View file

@ -540,7 +540,7 @@ class EditorFontImportDialog : public ConfirmationDialog {
return;
}
//_import_inc(dest->get_line_edit()->get_text());
_import_inc(dest->get_line_edit()->get_text());
hide();
}

View file

@ -57,11 +57,12 @@ void EditorScenePostImport::_bind_methods() {
}
Error EditorScenePostImport::post_import(Node* p_scene) {
Node *EditorScenePostImport::post_import(Node* p_scene) {
if (get_script_instance())
return Error(int(get_script_instance()->call("post_import",p_scene)));
return OK;
return get_script_instance()->call("post_import",p_scene);
return p_scene;
}
EditorScenePostImport::EditorScenePostImport() {
@ -2748,8 +2749,8 @@ Error EditorSceneImportPlugin::import2(Node *scene, const String& p_dest_path, c
if (post_import_script.is_valid()) {
err = post_import_script->post_import(scene);
if (err) {
scene = post_import_script->post_import(scene);
if (!scene) {
EditorNode::add_io_error("Error running Post-Import script: '"+post_import_script_path);
return err;
}

View file

@ -87,7 +87,7 @@ protected:
static void _bind_methods();
public:
virtual Error post_import(Node* p_scene);
virtual Node* post_import(Node* p_scene);
EditorScenePostImport();
};

View file

@ -267,17 +267,15 @@ PathSpatialGizmo::PathSpatialGizmo(Path* p_path){
}
bool PathEditorPlugin::create_spatial_gizmo(Spatial* p_spatial) {
Ref<SpatialEditorGizmo> PathEditorPlugin::create_spatial_gizmo(Spatial* p_spatial) {
if (p_spatial->cast_to<Path>()) {
Ref<PathSpatialGizmo> psg = memnew( PathSpatialGizmo(p_spatial->cast_to<Path>()));
p_spatial->set_gizmo(psg);
return true;
return memnew( PathSpatialGizmo(p_spatial->cast_to<Path>()));
}
return false;
return Ref<SpatialEditorGizmo>();
}
bool PathEditorPlugin::forward_spatial_input_event(Camera* p_camera,const InputEvent& p_event) {
@ -538,7 +536,7 @@ PathEditorPlugin::PathEditorPlugin(EditorNode *p_node) {
path_thin_material->set_flag(Material::FLAG_DOUBLE_SIDED,true);
path_thin_material->set_flag(Material::FLAG_UNSHADED,true);
SpatialEditor::get_singleton()->add_gizmo_plugin(this);
// SpatialEditor::get_singleton()->add_gizmo_plugin(this);
sep = memnew( VSeparator);
sep->hide();

View file

@ -32,9 +32,9 @@
#include "tools/editor/spatial_editor_gizmos.h"
#include "scene/3d/path.h"
class PathSpatialGizmo : public SpatialGizmoTool {
class PathSpatialGizmo : public EditorSpatialGizmo {
OBJ_TYPE(PathSpatialGizmo,SpatialGizmoTool);
OBJ_TYPE(PathSpatialGizmo,EditorSpatialGizmo);
Path* path;
mutable Vector3 original;
@ -83,7 +83,7 @@ public:
virtual bool forward_spatial_input_event(Camera* p_camera,const InputEvent& p_event);
// virtual bool forward_input_event(const InputEvent& p_event) { return collision_polygon_editor->forward_input_event(p_event); }
virtual bool create_spatial_gizmo(Spatial* p_spatial);
virtual Ref<SpatialEditorGizmo> create_spatial_gizmo(Spatial* p_spatial);
virtual String get_name() const { return "Path"; }
bool has_main_screen() const { return false; }
virtual void edit(Object *p_node);

View file

@ -3655,27 +3655,25 @@ void SpatialEditor::_request_gizmo(Object* p_obj) {
Spatial *sp=p_obj->cast_to<Spatial>();
if (!sp)
return;
if (editor->get_edited_scene() && (sp==editor->get_edited_scene() || sp->get_owner()==editor->get_edited_scene())) {
if (editor->get_edited_scene() && (sp==editor->get_edited_scene() || sp->get_owner()==editor->get_edited_scene() || editor->get_edited_scene()->is_editable_instance(sp->get_owner()))) {
Ref<SpatialEditorGizmo> seg = gizmos->get_gizmo(sp);
Ref<SpatialEditorGizmo> seg;
for(int i=0;i<EditorNode::get_singleton()->get_editor_data().get_editor_plugin_count();i++) {
seg = EditorNode::get_singleton()->get_editor_data().get_editor_plugin(i)->create_spatial_gizmo(sp);
if (seg.is_valid())
break;
}
if (!seg.is_valid()) {
seg = gizmos->get_gizmo(sp);
}
if (seg.is_valid()) {
sp->set_gizmo(seg);
}
for (List<EditorPlugin*>::Element *E=gizmo_plugins.front();E;E=E->next()) {
if (E->get()->create_spatial_gizmo(sp)) {
seg = sp->get_gizmo();
if (sp==selected && seg.is_valid()) {
seg->set_selected(true);
selected->update_gizmo();
}
return;
}
}
if (seg.is_valid() && sp==selected) {
seg->set_selected(true);
@ -3683,7 +3681,6 @@ void SpatialEditor::_request_gizmo(Object* p_obj) {
}
}
}
void SpatialEditor::_toggle_maximize_view(Object* p_viewport) {

View file

@ -457,8 +457,6 @@ private:
Ref<Environment> viewport_environment;
List<EditorPlugin*> gizmo_plugins;
Spatial *selected;
void _request_gizmo(Object* p_obj);
@ -518,8 +516,6 @@ public:
UndoRedo *get_undo_redo() { return undo_redo; }
void add_gizmo_plugin(EditorPlugin* p_plugin) { gizmo_plugins.push_back(p_plugin); }
void add_control_to_menu_panel(Control *p_control);
VSplitContainer *get_shader_split();

View file

@ -570,6 +570,7 @@ void ProjectSettings::popup_project_settings() {
globals_editor->edit(Globals::get_singleton());
_update_translations();
_update_autoload();
plugin_settings->update_plugins();
}
@ -739,6 +740,10 @@ void ProjectSettings::_settings_changed() {
timer->start();
}
void ProjectSettings::queue_save() {
_settings_changed();
}
void ProjectSettings::_copy_to_platform(int p_which) {
@ -1830,6 +1835,13 @@ ProjectSettings::ProjectSettings(EditorData *p_data) {
}
{
plugin_settings = memnew( EditorPluginSettings );
plugin_settings->set_name("Plugins");
tab_container->add_child(plugin_settings);
}
timer = memnew( Timer );
timer->set_wait_time(1.5);
timer->connect("timeout",Globals::get_singleton(),"save");

View file

@ -34,6 +34,9 @@
#include "optimized_save_dialog.h"
#include "undo_redo.h"
#include "editor_data.h"
#include "editor_plugin_settings.h"
//#include "project_export_settings.h"
class ProjectSettings : public AcceptDialog {
@ -89,6 +92,9 @@ class ProjectSettings : public AcceptDialog {
LineEdit *autoload_add_name;
LineEdit *autoload_add_path;
EditorPluginSettings *plugin_settings;
void _update_autoload();
void _autoload_file_callback(const String& p_path);
void _autoload_add();
@ -142,6 +148,8 @@ class ProjectSettings : public AcceptDialog {
void _toggle_search_bar(bool p_pressed);
void _clear_search_box();
ProjectSettings();
@ -157,6 +165,8 @@ public:
static ProjectSettings *get_singleton() { return singleton; }
void popup_project_settings();
void queue_save();
ProjectSettings(EditorData *p_data);
};

View file

@ -80,173 +80,6 @@ void EditorSettingsDialog::popup_edit_settings() {
}
void EditorSettingsDialog::_plugin_install() {
EditorSettings::Plugin plugin = EditorSettings::get_singleton()->get_plugins()[plugin_setting_edit];
DirAccess *da = DirAccess::create(DirAccess::ACCESS_RESOURCES);
da->change_dir("res://");
if (da->change_dir("plugins")!=OK) {
Error err = da->make_dir("plugins");
if (err)
memdelete(da);
ERR_FAIL_COND(err!=OK);
err = da->change_dir("plugins");
if (err)
memdelete(da);
ERR_FAIL_COND(err!=OK);
}
if (da->change_dir(plugin_setting_edit)!=OK) {
Error err = da->make_dir(plugin_setting_edit);
if (err)
memdelete(da);
ERR_FAIL_COND(err!=OK);
err = da->change_dir(plugin_setting_edit);
if (err)
memdelete(da);
ERR_FAIL_COND(err!=OK);
}
Vector<String> ifiles=plugin.install_files;
if (ifiles.find("plugin.cfg")==-1) {
ifiles.push_back("plugin.cfg");
}
if (ifiles.find(plugin.script)==-1) {
ifiles.push_back(plugin.script);
}
for(int i=0;i<ifiles.size();i++) {
String target = "res://plugins/"+plugin_setting_edit+"/"+ifiles[i];
Error err = da->copy(EditorSettings::get_singleton()->get_settings_path().plus_file("plugins/"+plugin_setting_edit+"/"+ifiles[i]),target);
if (err)
memdelete(da);
ERR_EXPLAIN("Error copying to file "+target);
ERR_FAIL_COND(err!=OK);
EditorFileSystem::get_singleton()->update_file(target);
}
memdelete(da);
Globals::get_singleton()->set("plugins/"+plugin_setting_edit,"res://plugins/"+plugin_setting_edit);
Globals::get_singleton()->set_persisting("plugins/"+plugin_setting_edit,true);
EditorSettings::get_singleton()->load_installed_plugin(plugin_setting_edit);
Globals::get_singleton()->save();
_update_plugins();
}
void EditorSettingsDialog::_rescan_plugins() {
EditorSettings::get_singleton()->scan_plugins();
_update_plugins();
}
void EditorSettingsDialog::_plugin_edited() {
if (updating)
return;
TreeItem *ti=plugins->get_edited();
if (!ti)
return;
String plugin = ti->get_metadata(0);
bool enabled = ti->is_checked(0);
EditorSettings::get_singleton()->set_plugin_enabled(plugin,enabled);
}
void EditorSettingsDialog::_plugin_settings(Object *p_obj,int p_cell,int p_index) {
TreeItem *ti=p_obj->cast_to<TreeItem>();
EditorSettings::Plugin plugin = EditorSettings::get_singleton()->get_plugins()[ti->get_metadata(0)];
plugin_description->clear();
plugin_description->parse_bbcode(plugin.description);
plugin_setting_edit = ti->get_metadata(0);
if (plugin.installs) {
if (Globals::get_singleton()->has("plugins/"+plugin_setting_edit))
plugin_setting->get_ok()->set_text("Re-Install to Project");
else
plugin_setting->get_ok()->set_text("Install to Project");
plugin_setting->get_ok()->show();
plugin_setting->get_cancel()->set_text("Close");
} else {
plugin_setting->get_ok()->hide();
plugin_setting->get_cancel()->set_text("Close");
}
plugin_setting->set_title(plugin.name);
plugin_setting->popup_centered(Size2(300,200));
}
void EditorSettingsDialog::_update_plugins() {
updating=true;
plugins->clear();
TreeItem *root = plugins->create_item(NULL);
plugins->set_hide_root(true);
Color sc = get_color("prop_subsection","Editor");
TreeItem *editor = plugins->create_item(root);
editor->set_text(0,"Editor Plugins");
editor->set_custom_bg_color(0,sc);
editor->set_custom_bg_color(1,sc);
editor->set_custom_bg_color(2,sc);
TreeItem *install = plugins->create_item(root);
install->set_text(0,"Installable Plugins");
install->set_custom_bg_color(0,sc);
install->set_custom_bg_color(1,sc);
install->set_custom_bg_color(2,sc);
for (const Map<String,EditorSettings::Plugin>::Element *E=EditorSettings::get_singleton()->get_plugins().front();E;E=E->next()) {
TreeItem *ti = plugins->create_item(E->get().installs?install:editor);
if (!E->get().installs) {
ti->set_cell_mode(0,TreeItem::CELL_MODE_CHECK);
ti->set_editable(0,true);
if (EditorSettings::get_singleton()->is_plugin_enabled(E->key()))
ti->set_checked(0,true);
ti->set_text(0,E->get().name);
} else {
if (Globals::get_singleton()->has("plugins/"+E->key())) {
ti->set_text(0,E->get().name+" (Installed)");
} else {
ti->set_text(0,E->get().name);
}
}
ti->add_button(0,get_icon("Tools","EditorIcons"),0);
ti->set_text(1,E->get().author);
ti->set_text(2,E->get().version);
ti->set_metadata(0,E->key());
}
if (!editor->get_children())
memdelete(editor);
if (!install->get_children())
memdelete(install);
updating=false;
}
void EditorSettingsDialog::_clear_search_box() {
@ -261,9 +94,7 @@ void EditorSettingsDialog::_notification(int p_what) {
if (p_what==NOTIFICATION_ENTER_TREE) {
rescan_plugins->set_icon(get_icon("Reload","EditorIcons"));
clear_button->set_icon(get_icon("Close","EditorIcons"));
_update_plugins();
}
}
@ -271,10 +102,6 @@ void EditorSettingsDialog::_bind_methods() {
ObjectTypeDB::bind_method(_MD("_settings_save"),&EditorSettingsDialog::_settings_save);
ObjectTypeDB::bind_method(_MD("_settings_changed"),&EditorSettingsDialog::_settings_changed);
ObjectTypeDB::bind_method(_MD("_rescan_plugins"),&EditorSettingsDialog::_rescan_plugins);
ObjectTypeDB::bind_method(_MD("_plugin_settings"),&EditorSettingsDialog::_plugin_settings);
ObjectTypeDB::bind_method(_MD("_plugin_edited"),&EditorSettingsDialog::_plugin_edited);
ObjectTypeDB::bind_method(_MD("_plugin_install"),&EditorSettingsDialog::_plugin_install);
ObjectTypeDB::bind_method(_MD("_clear_search_box"),&EditorSettingsDialog::_clear_search_box);
}
@ -324,32 +151,6 @@ EditorSettingsDialog::EditorSettingsDialog() {
//Button *load = memnew( Button );
//load->set_text("Load..");
//hbc->add_child(load);
Button *rescan = memnew( Button );
rescan_plugins=rescan;
rescan_plugins->connect("pressed",this,"_rescan_plugins");
hbc->add_child(rescan);
plugins = memnew( Tree );
MarginContainer *mc = memnew( MarginContainer);
vbc->add_child(mc);
mc->add_child(plugins);
mc->set_v_size_flags(SIZE_EXPAND_FILL);
plugins->set_columns(3);
plugins->set_column_title(0,"Name");
plugins->set_column_title(1,"Author");
plugins->set_column_title(2,"Version");
plugins->set_column_expand(2,false);
plugins->set_column_min_width(2,100);
plugins->set_column_titles_visible(true);
plugins->connect("button_pressed",this,"_plugin_settings");
plugins->connect("item_edited",this,"_plugin_edited");
plugin_setting = memnew( ConfirmationDialog );
add_child(plugin_setting);
plugin_description = memnew( RichTextLabel );
plugin_setting->add_child(plugin_description);
plugin_setting->set_child_rect(plugin_description);
plugin_setting->connect("confirmed",this,"_plugin_install");
//get_ok()->set_text("Apply");
@ -363,8 +164,6 @@ EditorSettingsDialog::EditorSettingsDialog() {
add_child(timer);
EditorSettings::get_singleton()->connect("settings_changed",this,"_settings_changed");
get_ok()->set_text("Close");
install_confirm = memnew( ConfirmationDialog );
add_child(install_confirm);
updating=false;

View file

@ -40,17 +40,10 @@ class EditorSettingsDialog : public AcceptDialog {
ConfirmationDialog *install_confirm;
bool updating;
ConfirmationDialog *plugin_setting;
String plugin_setting_edit;
RichTextLabel *plugin_description;
TabContainer *tabs;
Button *rescan_plugins;
Tree *plugins;
LineEdit *search_box;
ToolButton *clear_button;
SectionedPropertyEditor *property_editor;
@ -60,18 +53,11 @@ class EditorSettingsDialog : public AcceptDialog {
virtual void cancel_pressed();
virtual void ok_pressed();
void _plugin_edited();
void _plugin_settings(Object *p_obj,int p_cell,int p_index);
void _settings_changed();
void _settings_save();
void _plugin_install();
void _notification(int p_what);
void _rescan_plugins();
void _update_plugins();
void _clear_search_box();

View file

@ -43,7 +43,7 @@
#define HANDLE_HALF_SIZE 0.05
void SpatialGizmoTool::clear() {
void EditorSpatialGizmo::clear() {
for(int i=0;i<instances.size();i++) {
@ -61,7 +61,15 @@ void SpatialGizmoTool::clear() {
secondary_handles.clear();
}
void SpatialGizmoTool::Instance::create_instance(Spatial *p_base) {
void EditorSpatialGizmo::redraw() {
if (get_script_instance() && get_script_instance()->has_method("redraw"))
get_script_instance()->call("redraw");
}
void EditorSpatialGizmo::Instance::create_instance(Spatial *p_base) {
instance = VS::get_singleton()->instance_create2(mesh->get_rid(),p_base->get_world()->get_scenario());
VS::get_singleton()->instance_attach_object_instance_ID(instance,p_base->get_instance_ID());
@ -80,7 +88,7 @@ void SpatialGizmoTool::Instance::create_instance(Spatial *p_base) {
void SpatialGizmoTool::add_mesh(const Ref<Mesh>& p_mesh,bool p_billboard, const RID &p_skeleton) {
void EditorSpatialGizmo::add_mesh(const Ref<Mesh>& p_mesh,bool p_billboard, const RID &p_skeleton) {
ERR_FAIL_COND(!spatial_node);
Instance ins;
@ -97,7 +105,7 @@ void SpatialGizmoTool::add_mesh(const Ref<Mesh>& p_mesh,bool p_billboard, const
}
void SpatialGizmoTool::add_lines(const Vector<Vector3> &p_lines, const Ref<Material> &p_material,bool p_billboard){
void EditorSpatialGizmo::add_lines(const Vector<Vector3> &p_lines, const Ref<Material> &p_material,bool p_billboard){
ERR_FAIL_COND(!spatial_node);
Instance ins;
@ -150,7 +158,7 @@ void SpatialGizmoTool::add_lines(const Vector<Vector3> &p_lines, const Ref<Mater
}
void SpatialGizmoTool::add_unscaled_billboard(const Ref<Material>& p_material,float p_scale) {
void EditorSpatialGizmo::add_unscaled_billboard(const Ref<Material>& p_material,float p_scale) {
ERR_FAIL_COND(!spatial_node);
Instance ins;
@ -201,12 +209,12 @@ void SpatialGizmoTool::add_unscaled_billboard(const Ref<Material>& p_material,fl
}
void SpatialGizmoTool::add_collision_triangles(const Ref<TriangleMesh>& p_tmesh) {
void EditorSpatialGizmo::add_collision_triangles(const Ref<TriangleMesh>& p_tmesh) {
collision_mesh=p_tmesh;
}
void SpatialGizmoTool::add_collision_segments(const Vector<Vector3> &p_lines) {
void EditorSpatialGizmo::add_collision_segments(const Vector<Vector3> &p_lines) {
int from=collision_segments.size();
collision_segments.resize(from+p_lines.size());
@ -217,7 +225,7 @@ void SpatialGizmoTool::add_collision_segments(const Vector<Vector3> &p_lines) {
}
void SpatialGizmoTool::add_handles(const Vector<Vector3> &p_handles, bool p_billboard,bool p_secondary){
void EditorSpatialGizmo::add_handles(const Vector<Vector3> &p_handles, bool p_billboard,bool p_secondary){
billboard_handle=p_billboard;
@ -354,13 +362,14 @@ void SpatialGizmoTool::add_handles(const Vector<Vector3> &p_handles, bool p_bill
}
void SpatialGizmoTool::set_spatial_node(Spatial *p_node){
void EditorSpatialGizmo::set_spatial_node(Spatial *p_node){
ERR_FAIL_NULL(p_node);
spatial_node=p_node;
}
bool SpatialGizmoTool::intersect_frustum(const Camera *p_camera,const Vector<Plane> &p_frustum) {
bool EditorSpatialGizmo::intersect_frustum(const Camera *p_camera,const Vector<Plane> &p_frustum) {
ERR_FAIL_COND_V(!spatial_node,false);
ERR_FAIL_COND_V(!valid,false);
@ -401,7 +410,7 @@ bool SpatialGizmoTool::intersect_frustum(const Camera *p_camera,const Vector<Pla
}
bool SpatialGizmoTool::intersect_ray(const Camera *p_camera,const Point2& p_point, Vector3& r_pos, Vector3& r_normal,int *r_gizmo_handle,bool p_sec_first) {
bool EditorSpatialGizmo::intersect_ray(const Camera *p_camera,const Point2& p_point, Vector3& r_pos, Vector3& r_normal,int *r_gizmo_handle,bool p_sec_first) {
ERR_FAIL_COND_V(!spatial_node,false);
ERR_FAIL_COND_V(!valid,false);
@ -631,7 +640,7 @@ bool SpatialGizmoTool::intersect_ray(const Camera *p_camera,const Point2& p_poin
void SpatialGizmoTool::create() {
void EditorSpatialGizmo::create() {
ERR_FAIL_COND(!spatial_node);
ERR_FAIL_COND(valid);
@ -646,7 +655,7 @@ void SpatialGizmoTool::create() {
}
void SpatialGizmoTool::transform(){
void EditorSpatialGizmo::transform(){
ERR_FAIL_COND(!spatial_node);
ERR_FAIL_COND(!valid);
@ -657,7 +666,7 @@ void SpatialGizmoTool::transform(){
}
void SpatialGizmoTool::free(){
void EditorSpatialGizmo::free(){
ERR_FAIL_COND(!spatial_node);
ERR_FAIL_COND(!valid);
@ -675,19 +684,39 @@ void SpatialGizmoTool::free(){
}
void EditorSpatialGizmo::_bind_methods() {
SpatialGizmoTool::SpatialGizmoTool() {
ObjectTypeDB::bind_method(_MD("add_lines","lines","material:Material","billboard"),&EditorSpatialGizmo::add_lines,DEFVAL(false));
ObjectTypeDB::bind_method(_MD("add_mesh","mesh:Mesh","billboard","skeleton"),&EditorSpatialGizmo::add_mesh,DEFVAL(false),DEFVAL(RID()));
ObjectTypeDB::bind_method(_MD("add_collision_segments","segments"),&EditorSpatialGizmo::add_collision_segments);
ObjectTypeDB::bind_method(_MD("add_collision_triangles","triangles:TriangleMesh"),&EditorSpatialGizmo::add_collision_triangles);
ObjectTypeDB::bind_method(_MD("add_unscaled_billboard","material:Material","default_scale"),&EditorSpatialGizmo::add_unscaled_billboard,DEFVAL(1));
ObjectTypeDB::bind_method(_MD("add_handles","handles","billboard","secondary"),&EditorSpatialGizmo::add_handles,DEFVAL(false),DEFVAL(false));
ObjectTypeDB::bind_method(_MD("set_spatial_node","node:Spatial"),&EditorSpatialGizmo::_set_spatial_node);
BIND_VMETHOD( MethodInfo("redraw"));
BIND_VMETHOD( MethodInfo(Variant::STRING,"get_handle_name",PropertyInfo(Variant::INT,"index")));
{
BIND_VMETHOD( MethodInfo("get_handle_value:Variant",PropertyInfo(Variant::INT,"index")));
}
BIND_VMETHOD( MethodInfo("set_handle",PropertyInfo(Variant::INT,"index"),PropertyInfo(Variant::OBJECT,"camera:Camera"),PropertyInfo(Variant::VECTOR2,"point")));
MethodInfo cm = MethodInfo("commit_handle",PropertyInfo(Variant::INT,"index"),PropertyInfo(Variant::NIL,"restore:Variant"),PropertyInfo(Variant::BOOL,"cancel"));
cm.default_arguments.push_back(false);
BIND_VMETHOD( cm );
}
EditorSpatialGizmo::EditorSpatialGizmo() {
valid=false;
billboard_handle=false;
}
SpatialGizmoTool::~SpatialGizmoTool(){
EditorSpatialGizmo::~EditorSpatialGizmo(){
clear();
}
Vector3 SpatialGizmoTool::get_handle_pos(int p_idx) const {
Vector3 EditorSpatialGizmo::get_handle_pos(int p_idx) const {
ERR_FAIL_INDEX_V(p_idx,handles.size(),Vector3());

View file

@ -52,9 +52,9 @@
class Camera;
class SpatialGizmoTool : public SpatialEditorGizmo {
class EditorSpatialGizmo : public SpatialEditorGizmo {
OBJ_TYPE(SpatialGizmoTool,SpatialGizmo);
OBJ_TYPE(EditorSpatialGizmo,SpatialGizmo);
struct Instance{
@ -93,6 +93,8 @@ class SpatialGizmoTool : public SpatialEditorGizmo {
Spatial *base;
Vector<Instance> instances;
Spatial *spatial_node;
void _set_spatial_node(Node *p_node) { set_spatial_node(p_node->cast_to<Spatial>()); }
protected:
void add_lines(const Vector<Vector3> &p_lines,const Ref<Material>& p_material,bool p_billboard=false);
void add_mesh(const Ref<Mesh>& p_mesh,bool p_billboard=false,const RID& p_skeleton=RID());
@ -103,6 +105,7 @@ protected:
void set_spatial_node(Spatial *p_node);
static void _bind_methods();
public:
virtual Vector3 get_handle_pos(int p_idx) const;
@ -112,18 +115,18 @@ public:
void clear();
void create();
void transform();
//void redraw();
virtual void redraw();
void free();
SpatialGizmoTool();
~SpatialGizmoTool();
EditorSpatialGizmo();
~EditorSpatialGizmo();
};
class LightSpatialGizmo : public SpatialGizmoTool {
class LightSpatialGizmo : public EditorSpatialGizmo {
OBJ_TYPE(LightSpatialGizmo,SpatialGizmoTool);
OBJ_TYPE(LightSpatialGizmo,EditorSpatialGizmo);
Light* light;
@ -140,9 +143,9 @@ public:
};
class CameraSpatialGizmo : public SpatialGizmoTool {
class CameraSpatialGizmo : public EditorSpatialGizmo {
OBJ_TYPE(CameraSpatialGizmo,SpatialGizmoTool);
OBJ_TYPE(CameraSpatialGizmo,EditorSpatialGizmo);
Camera* camera;
@ -161,9 +164,9 @@ public:
class MeshInstanceSpatialGizmo : public SpatialGizmoTool {
class MeshInstanceSpatialGizmo : public EditorSpatialGizmo {
OBJ_TYPE(MeshInstanceSpatialGizmo,SpatialGizmoTool);
OBJ_TYPE(MeshInstanceSpatialGizmo,EditorSpatialGizmo);
MeshInstance* mesh;
@ -174,9 +177,9 @@ public:
};
class Position3DSpatialGizmo : public SpatialGizmoTool {
class Position3DSpatialGizmo : public EditorSpatialGizmo {
OBJ_TYPE(Position3DSpatialGizmo,SpatialGizmoTool);
OBJ_TYPE(Position3DSpatialGizmo,EditorSpatialGizmo);
Position3D* p3d;
@ -187,9 +190,9 @@ public:
};
class SkeletonSpatialGizmo : public SpatialGizmoTool {
class SkeletonSpatialGizmo : public EditorSpatialGizmo {
OBJ_TYPE(SkeletonSpatialGizmo,SpatialGizmoTool);
OBJ_TYPE(SkeletonSpatialGizmo,EditorSpatialGizmo);
Skeleton* skel;
@ -203,9 +206,9 @@ public:
class SpatialPlayerSpatialGizmo : public SpatialGizmoTool {
class SpatialPlayerSpatialGizmo : public EditorSpatialGizmo {
OBJ_TYPE(SpatialPlayerSpatialGizmo,SpatialGizmoTool);
OBJ_TYPE(SpatialPlayerSpatialGizmo,EditorSpatialGizmo);
SpatialPlayer* splayer;
@ -218,9 +221,9 @@ public:
class TestCubeSpatialGizmo : public SpatialGizmoTool {
class TestCubeSpatialGizmo : public EditorSpatialGizmo {
OBJ_TYPE(TestCubeSpatialGizmo,SpatialGizmoTool);
OBJ_TYPE(TestCubeSpatialGizmo,EditorSpatialGizmo);
TestCube* tc;
@ -231,9 +234,9 @@ public:
};
class RoomSpatialGizmo : public SpatialGizmoTool {
class RoomSpatialGizmo : public EditorSpatialGizmo {
OBJ_TYPE(RoomSpatialGizmo,SpatialGizmoTool);
OBJ_TYPE(RoomSpatialGizmo,EditorSpatialGizmo);
struct _EdgeKey {
@ -256,9 +259,9 @@ public:
};
class PortalSpatialGizmo : public SpatialGizmoTool {
class PortalSpatialGizmo : public EditorSpatialGizmo {
OBJ_TYPE(PortalSpatialGizmo,SpatialGizmoTool);
OBJ_TYPE(PortalSpatialGizmo,EditorSpatialGizmo);
Portal* portal;
@ -270,9 +273,9 @@ public:
};
class VisibilityNotifierGizmo : public SpatialGizmoTool {
class VisibilityNotifierGizmo : public EditorSpatialGizmo {
OBJ_TYPE(VisibilityNotifierGizmo ,SpatialGizmoTool);
OBJ_TYPE(VisibilityNotifierGizmo ,EditorSpatialGizmo);
VisibilityNotifier* notifier;
@ -291,9 +294,9 @@ public:
class CollisionShapeSpatialGizmo : public SpatialGizmoTool {
class CollisionShapeSpatialGizmo : public EditorSpatialGizmo {
OBJ_TYPE(CollisionShapeSpatialGizmo,SpatialGizmoTool);
OBJ_TYPE(CollisionShapeSpatialGizmo,EditorSpatialGizmo);
CollisionShape* cs;
@ -308,9 +311,9 @@ public:
};
class CollisionPolygonSpatialGizmo : public SpatialGizmoTool {
class CollisionPolygonSpatialGizmo : public EditorSpatialGizmo {
OBJ_TYPE(CollisionPolygonSpatialGizmo,SpatialGizmoTool);
OBJ_TYPE(CollisionPolygonSpatialGizmo,EditorSpatialGizmo);
CollisionPolygon* polygon;
@ -322,9 +325,9 @@ public:
};
class RayCastSpatialGizmo : public SpatialGizmoTool {
class RayCastSpatialGizmo : public EditorSpatialGizmo {
OBJ_TYPE(RayCastSpatialGizmo,SpatialGizmoTool);
OBJ_TYPE(RayCastSpatialGizmo,EditorSpatialGizmo);
RayCast* raycast;
@ -337,9 +340,9 @@ public:
class VehicleWheelSpatialGizmo : public SpatialGizmoTool {
class VehicleWheelSpatialGizmo : public EditorSpatialGizmo {
OBJ_TYPE(VehicleWheelSpatialGizmo,SpatialGizmoTool);
OBJ_TYPE(VehicleWheelSpatialGizmo,EditorSpatialGizmo);
VehicleWheel* car_wheel;
@ -351,9 +354,9 @@ public:
};
class NavigationMeshSpatialGizmo : public SpatialGizmoTool {
class NavigationMeshSpatialGizmo : public EditorSpatialGizmo {
OBJ_TYPE(NavigationMeshSpatialGizmo,SpatialGizmoTool);
OBJ_TYPE(NavigationMeshSpatialGizmo,EditorSpatialGizmo);
struct _EdgeKey {
@ -376,9 +379,9 @@ public:
};
class PinJointSpatialGizmo : public SpatialGizmoTool {
class PinJointSpatialGizmo : public EditorSpatialGizmo {
OBJ_TYPE(PinJointSpatialGizmo,SpatialGizmoTool);
OBJ_TYPE(PinJointSpatialGizmo,EditorSpatialGizmo);
PinJoint* p3d;
@ -390,9 +393,9 @@ public:
};
class HingeJointSpatialGizmo : public SpatialGizmoTool {
class HingeJointSpatialGizmo : public EditorSpatialGizmo {
OBJ_TYPE(HingeJointSpatialGizmo,SpatialGizmoTool);
OBJ_TYPE(HingeJointSpatialGizmo,EditorSpatialGizmo);
HingeJoint* p3d;
@ -403,9 +406,9 @@ public:
};
class SliderJointSpatialGizmo : public SpatialGizmoTool {
class SliderJointSpatialGizmo : public EditorSpatialGizmo {
OBJ_TYPE(SliderJointSpatialGizmo,SpatialGizmoTool);
OBJ_TYPE(SliderJointSpatialGizmo,EditorSpatialGizmo);
SliderJoint* p3d;
@ -416,9 +419,9 @@ public:
};
class ConeTwistJointSpatialGizmo : public SpatialGizmoTool {
class ConeTwistJointSpatialGizmo : public EditorSpatialGizmo {
OBJ_TYPE(ConeTwistJointSpatialGizmo,SpatialGizmoTool);
OBJ_TYPE(ConeTwistJointSpatialGizmo,EditorSpatialGizmo);
ConeTwistJoint* p3d;
@ -430,9 +433,9 @@ public:
};
class Generic6DOFJointSpatialGizmo : public SpatialGizmoTool {
class Generic6DOFJointSpatialGizmo : public EditorSpatialGizmo {
OBJ_TYPE(Generic6DOFJointSpatialGizmo,SpatialGizmoTool);
OBJ_TYPE(Generic6DOFJointSpatialGizmo,EditorSpatialGizmo);
Generic6DOFJoint* p3d;