summaryrefslogtreecommitdiffstats
path: root/tools/editor/addon_editor_plugin.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'tools/editor/addon_editor_plugin.cpp')
-rw-r--r--tools/editor/addon_editor_plugin.cpp351
1 files changed, 331 insertions, 20 deletions
diff --git a/tools/editor/addon_editor_plugin.cpp b/tools/editor/addon_editor_plugin.cpp
index 82c2d3de64..4dfb8ff553 100644
--- a/tools/editor/addon_editor_plugin.cpp
+++ b/tools/editor/addon_editor_plugin.cpp
@@ -1,6 +1,6 @@
#include "addon_editor_plugin.h"
#include "editor_node.h"
-
+#include "editor_settings.h"
@@ -142,6 +142,7 @@ void EditorAddonLibraryItemDescription::set_image(int p_type,int p_index,const R
case EditorAddonLibrary::IMAGE_QUEUE_ICON: {
item->call("set_image",p_type,p_index,p_image);
+ icon=p_image;
} break;
case EditorAddonLibrary::IMAGE_QUEUE_THUMBNAIL: {
@@ -166,12 +167,30 @@ void EditorAddonLibraryItemDescription::set_image(int p_type,int p_index,const R
void EditorAddonLibraryItemDescription::_bind_methods() {
ObjectTypeDB::bind_method(_MD("set_image"),&EditorAddonLibraryItemDescription::set_image);
+ ObjectTypeDB::bind_method(_MD("_link_click"),&EditorAddonLibraryItemDescription::_link_click);
+
+}
+
+void EditorAddonLibraryItemDescription::_link_click(const String& p_url) {
+
+ ERR_FAIL_COND(!p_url.begins_with("http"));
+ OS::get_singleton()->shell_open(p_url);
}
-void EditorAddonLibraryItemDescription::configure(const String& p_title,int p_asset_id,const String& p_category,int p_category_id,const String& p_author,int p_author_id,int p_rating,const String& p_cost,const String& p_description) {
+void EditorAddonLibraryItemDescription::configure(const String& p_title,int p_asset_id,const String& p_category,int p_category_id,const String& p_author,int p_author_id,int p_rating,const String& p_cost,const String& p_version,const String& p_description,const String& p_download_url,const String& p_browse_url) {
+ asset_id=p_asset_id;
+ title=p_title;
+ download_url=p_download_url;
item->configure(p_title,p_asset_id,p_category,p_category_id,p_author,p_author_id,p_rating,p_cost);
- description->parse_bbcode(p_description);
+ description->clear();
+ description->add_text("Version: "+p_version+"\n");
+ description->add_text("Contents: ");
+ description->push_meta(p_browse_url);
+ description->add_text("View Files");
+ description->pop();
+ description->add_text("\nDescription:\n\n");
+ description->append_bbcode(p_description);
set_title(p_title);
}
@@ -215,6 +234,7 @@ EditorAddonLibraryItemDescription::EditorAddonLibraryItemDescription() {
desc_bg->set_v_size_flags(SIZE_EXPAND_FILL);
description = memnew( RichTextLabel );
+ description->connect("meta_clicked",this,"_link_click");
//desc_vbox->add_child(description);
desc_bg->add_child(description);
desc_bg->add_style_override("panel",get_stylebox("normal","TextEdit"));
@@ -242,6 +262,205 @@ EditorAddonLibraryItemDescription::EditorAddonLibraryItemDescription() {
}
+///////////////////////////////////////////////////////////////////////////////////
+
+void EditorAddonLibraryItemDownload::_http_download_completed(int p_status, int p_code, const StringArray& headers, const ByteArray& p_data) {
+
+
+ String error_text;
+
+ switch(p_status) {
+
+ case HTTPRequest::RESULT_CANT_RESOLVE: {
+ error_text=("Can't resolve hostname: "+host);
+ status->set_text("Can't resolve.");
+ } break;
+ case HTTPRequest::RESULT_BODY_SIZE_LIMIT_EXCEEDED:
+ case HTTPRequest::RESULT_CONNECTION_ERROR:
+ case HTTPRequest::RESULT_CHUNKED_BODY_SIZE_MISMATCH: {
+ error_text=("Connection error, please try again.");
+ status->set_text("Can't connect.");
+ } break;
+ case HTTPRequest::RESULT_SSL_HANDSHAKE_ERROR:
+ case HTTPRequest::RESULT_CANT_CONNECT: {
+ error_text=("Can't connect to host: "+host);
+ status->set_text("Can't connect.");
+ } break;
+ case HTTPRequest::RESULT_NO_RESPONSE: {
+ error_text=("No response from host: "+host);
+ status->set_text("No response.");
+ } break;
+ case HTTPRequest::RESULT_REQUEST_FAILED: {
+ error_text=("Request failed, return code: "+itos(p_code));
+ status->set_text("Req. Failed.");
+ } break;
+ case HTTPRequest::RESULT_REDIRECT_LIMIT_REACHED: {
+ error_text=("Request failed, too many redirects");
+ status->set_text("Redirect Loop.");
+ } break;
+ default: {
+ if (p_code!=200) {
+ error_text=("Request failed, return code: "+itos(p_code));
+ status->set_text("Failed: "+itos(p_code));
+ } else {
+
+ //all good
+ }
+ } break;
+
+ }
+
+ if (error_text!=String()) {
+ download_error->set_text("Asset Download Error:\n"+error_text);
+ download_error->popup_centered_minsize();
+ return;
+
+ }
+
+ progress->set_max( download->get_body_size() );
+ progress->set_val(download->get_downloaded_bytes());
+
+ print_line("max: "+itos(download->get_body_size())+" bytes: "+itos(download->get_downloaded_bytes()));
+ install->set_disabled(false);
+
+ status->set_text("Success!");
+ set_process(false);
+}
+
+
+void EditorAddonLibraryItemDownload::configure(const String& p_title,int p_asset_id,const Ref<Texture>& p_preview, const String& p_download_url) {
+
+ title->set_text(p_title);
+ icon->set_texture(p_preview);
+ asset_id=p_asset_id;
+ if (!p_preview.is_valid())
+ icon->set_texture(get_icon("GodotAssetDefault","EditorIcons"));
+
+ host=p_download_url;
+ set_process(true);
+ download->set_download_file(EditorSettings::get_singleton()->get_settings_path().plus_file("tmp").plus_file("tmp_asset_"+itos(p_asset_id))+".zip");
+ Error err = download->request(p_download_url);
+ ERR_FAIL_COND(err!=OK);
+ asset_installer->connect("confirmed",this,"_close");
+ dismiss->set_normal_texture(get_icon("Close","EditorIcons"));
+
+
+}
+
+
+void EditorAddonLibraryItemDownload::_notification(int p_what) {
+
+ if (p_what==NOTIFICATION_PROCESS) {
+
+ progress->set_max( download->get_body_size() );
+ progress->set_val(download->get_downloaded_bytes());
+
+ int cstatus = download->get_http_client_status();
+ if (cstatus!=prev_status) {
+ switch(cstatus) {
+
+ case HTTPClient::STATUS_RESOLVING: {
+ status->set_text("Resolving..");
+ } break;
+ case HTTPClient::STATUS_CONNECTING: {
+ status->set_text("Connecting..");
+ } break;
+ case HTTPClient::STATUS_REQUESTING: {
+ status->set_text("Requesting..");
+ } break;
+ case HTTPClient::STATUS_BODY: {
+ status->set_text("Downloading..");
+ } break;
+ default: {}
+ }
+ prev_status=cstatus;
+ }
+
+ }
+}
+void EditorAddonLibraryItemDownload::_close() {
+
+ DirAccess *da = DirAccess::create(DirAccess::ACCESS_FILESYSTEM);
+ da->remove(download->get_download_file()); //clean up removed file
+ memdelete(da);
+ queue_delete();
+}
+
+void EditorAddonLibraryItemDownload::_install() {
+
+ String file = download->get_download_file();
+ asset_installer->open(file,1);
+}
+
+void EditorAddonLibraryItemDownload::_bind_methods() {
+
+ ObjectTypeDB::bind_method("_http_download_completed",&EditorAddonLibraryItemDownload::_http_download_completed);
+ ObjectTypeDB::bind_method("_install",&EditorAddonLibraryItemDownload::_install);
+ ObjectTypeDB::bind_method("_close",&EditorAddonLibraryItemDownload::_close);
+
+}
+
+EditorAddonLibraryItemDownload::EditorAddonLibraryItemDownload() {
+
+ HBoxContainer *hb = memnew( HBoxContainer);
+ add_child(hb);
+ icon = memnew( TextureFrame );
+ hb->add_child(icon);
+
+ VBoxContainer *vb = memnew( VBoxContainer );
+ hb->add_child(vb);
+ vb->set_h_size_flags(SIZE_EXPAND_FILL);
+
+ HBoxContainer *title_hb = memnew( HBoxContainer);
+ vb->add_child(title_hb);
+ title = memnew( Label );
+ title_hb->add_child(title);
+ title->set_h_size_flags(SIZE_EXPAND_FILL);
+
+ dismiss = memnew( TextureButton );
+ dismiss->connect("pressed",this,"_close");
+ title_hb->add_child(dismiss);
+
+ title->set_clip_text(true);
+
+ vb->add_spacer();
+
+ status = memnew (Label("Idle"));
+ vb->add_child(status);
+ status->add_color_override("font_color", Color(0.5,0.5,0.5) );
+ progress = memnew( ProgressBar );
+ vb->add_child(progress);
+
+
+
+ HBoxContainer *hb2 = memnew( HBoxContainer );
+ vb->add_child(hb2);
+ hb2->add_spacer();
+
+ install = memnew( Button );
+ install->set_text("Install");
+ install->set_disabled(true);
+ install->connect("pressed",this,"_install");
+
+ hb2->add_child(install);
+ set_custom_minimum_size(Size2(250,0));
+
+ download = memnew( HTTPRequest );
+ add_child(download);
+ download->connect("request_completed",this,"_http_download_completed");
+
+ download_error = memnew( AcceptDialog );
+ add_child(download_error);
+ download_error->set_title("Download Error");
+
+ asset_installer = memnew( EditorAssetInstaller );
+ add_child(asset_installer);
+
+ prev_status=-1;
+
+
+}
+
////////////////////////////////////////////////////////////////////////////////
@@ -261,7 +480,7 @@ void EditorAddonLibrary::_notification(int p_what) {
HTTPClient::Status s = request->get_http_client_status();
bool visible = s!=HTTPClient::STATUS_DISCONNECTED;
- if (visible !=load_status->is_visible()) {
+ if (visible != !load_status->is_hidden()) {
load_status->set_hidden(!visible);
}
@@ -280,14 +499,41 @@ void EditorAddonLibrary::_notification(int p_what) {
case HTTPClient::STATUS_BODY: {
load_status->set_val(0.4);
} break;
+ default: {}
}
}
+
+ bool no_downloads = downloads_hb->get_child_count()==0;
+ if (no_downloads != downloads_scroll->is_hidden()) {
+ downloads_scroll->set_hidden(no_downloads);
+ }
}
}
+void EditorAddonLibrary::_install_asset() {
+
+ ERR_FAIL_COND(!description);
+
+ for(int i=0;i<downloads_hb->get_child_count();i++) {
+
+ EditorAddonLibraryItemDownload *d = downloads_hb->get_child(i)->cast_to<EditorAddonLibraryItemDownload>();
+ if (d && d->get_asset_id() == description->get_asset_id()) {
+
+ EditorNode::get_singleton()->show_warning("Download for this asset is already in progress!");
+ return;
+ }
+ }
+
+
+ EditorAddonLibraryItemDownload * download = memnew( EditorAddonLibraryItemDownload );
+ downloads_hb->add_child(download);
+ download->configure(description->get_title(),description->get_asset_id(),description->get_preview_icon(),description->get_download_url());
+
+}
+
const char* EditorAddonLibrary::sort_key[SORT_MAX]={
"rating",
"downloads",
@@ -708,15 +954,23 @@ void EditorAddonLibrary::_http_request_completed(int p_status, int p_code, const
Dictionary r = d["info"];
+ r["download_url"]="https://github.com/reduz/godot-test-addon/archive/master.zip";
+ r["browse_url"]="https://github.com/reduz/godot-test-addon";
+ r["version"]="1.1";
+
ERR_FAIL_COND(!r.has("title"));
ERR_FAIL_COND(!r.has("asset_id"));
ERR_FAIL_COND(!r.has("author"));
ERR_FAIL_COND(!r.has("author_id"));
+ ERR_FAIL_COND(!r.has("version"));
ERR_FAIL_COND(!r.has("category"));
ERR_FAIL_COND(!r.has("category_id"));
ERR_FAIL_COND(!r.has("rating"));
ERR_FAIL_COND(!r.has("cost"));
ERR_FAIL_COND(!r.has("description"));
+ ERR_FAIL_COND(!r.has("download_url"));
+ ERR_FAIL_COND(!r.has("browse_url"));
+
if (description) {
memdelete(description);
@@ -725,8 +979,9 @@ void EditorAddonLibrary::_http_request_completed(int p_status, int p_code, const
description = memnew( EditorAddonLibraryItemDescription );
add_child(description);
description->popup_centered_minsize();
+ description->connect("confirmed",this,"_install_asset");
- description->configure(r["title"],r["asset_id"],r["category"],r["category_id"],r["author"],r["author_id"],r["rating"],r["cost"],r["description"]);
+ description->configure(r["title"],r["asset_id"],r["category"],r["category_id"],r["author"],r["author_id"],r["rating"],r["cost"],r["version"],r["description"],r["download_url"],r["browse_url"]);
/*item->connect("asset_selected",this,"_select_asset");
item->connect("author_selected",this,"_select_author");
item->connect("category_selected",this,"_category_selected");*/
@@ -764,6 +1019,34 @@ void EditorAddonLibrary::_http_request_completed(int p_status, int p_code, const
}
+
+void EditorAddonLibrary::_asset_file_selected(const String& p_file) {
+
+ if (asset_installer) {
+ memdelete( asset_installer );
+ asset_installer=NULL;
+ }
+
+ asset_installer = memnew( EditorAssetInstaller );
+ add_child(asset_installer);
+ asset_installer->open(p_file);
+
+
+}
+
+void EditorAddonLibrary::_asset_open() {
+
+ asset_open->popup_centered_ratio();
+}
+
+void EditorAddonLibrary::_manage_plugins() {
+
+ ProjectSettings::get_singleton()->popup_project_settings();
+ ProjectSettings::get_singleton()->set_plugins_page();
+}
+
+
+
void EditorAddonLibrary::_bind_methods() {
ObjectTypeDB::bind_method("_http_request_completed",&EditorAddonLibrary::_http_request_completed);
@@ -772,40 +1055,35 @@ void EditorAddonLibrary::_bind_methods() {
ObjectTypeDB::bind_method("_select_category",&EditorAddonLibrary::_select_category);
ObjectTypeDB::bind_method("_image_request_completed",&EditorAddonLibrary::_image_request_completed);
ObjectTypeDB::bind_method("_search",&EditorAddonLibrary::_search,DEFVAL(0));
+ ObjectTypeDB::bind_method("_install_asset",&EditorAddonLibrary::_install_asset);
+ ObjectTypeDB::bind_method("_manage_plugins",&EditorAddonLibrary::_manage_plugins);
+ ObjectTypeDB::bind_method("_asset_open",&EditorAddonLibrary::_asset_open);
+ ObjectTypeDB::bind_method("_asset_file_selected",&EditorAddonLibrary::_asset_file_selected);
}
EditorAddonLibrary::EditorAddonLibrary() {
- tabs = memnew( TabContainer );
- tabs->set_v_size_flags(SIZE_EXPAND_FILL);
- add_child(tabs);
-
- installed = memnew( EditorPluginSettings );
- installed->set_name("Installed");
- tabs->add_child(installed);
Ref<StyleBoxEmpty> border;
border.instance();
border->set_default_margin(MARGIN_LEFT,15);
border->set_default_margin(MARGIN_RIGHT,15);
- border->set_default_margin(MARGIN_BOTTOM,15);
+ border->set_default_margin(MARGIN_BOTTOM,5);
border->set_default_margin(MARGIN_TOP,5);
- PanelContainer *margin_panel = memnew( PanelContainer );
-
- margin_panel->set_name("Online");
- margin_panel->add_style_override("panel",border);
- tabs->add_child(margin_panel);
+ add_style_override("panel",border);
VBoxContainer *library_main = memnew( VBoxContainer );
- margin_panel->add_child(library_main);
+ add_child(library_main);
HBoxContainer *search_hb = memnew( HBoxContainer );
library_main->add_child(search_hb);
- library_main->add_constant_override("separation",20);
+ library_main->add_constant_override("separation",10);
+
+
search_hb->add_child( memnew( Label("Search: ")));
filter =memnew( LineEdit );
@@ -815,6 +1093,20 @@ EditorAddonLibrary::EditorAddonLibrary() {
search = memnew( Button("Search"));
search->connect("pressed",this,"_search");
search_hb->add_child(search);
+
+ search_hb->add_child(memnew( VSeparator ));
+
+ Button * open_asset = memnew( Button );
+ open_asset->set_text("Import");
+ search_hb->add_child(open_asset);
+ open_asset->connect("pressed",this,"_asset_open");
+
+ Button * plugins = memnew( Button );
+ plugins->set_text("Plugins");
+ search_hb->add_child(plugins);
+ plugins->connect("pressed",this,"_manage_plugins");
+
+
library_vb->add_child(search_hb);
HBoxContainer *search_hb2 = memnew( HBoxContainer );
@@ -907,6 +1199,7 @@ EditorAddonLibrary::EditorAddonLibrary() {
add_child(request);
request->connect("request_completed",this,"_http_request_completed");
+
last_queue_id=0;
library_vb->add_constant_override("separation",20);
@@ -928,6 +1221,24 @@ EditorAddonLibrary::EditorAddonLibrary() {
//host="http://localhost:8000";
host="http://godotengine.org/addonlib";
set_process(true);
+
+ downloads_scroll = memnew( ScrollContainer );
+ downloads_scroll->set_enable_h_scroll(true);
+ downloads_scroll->set_enable_v_scroll(false);
+ library_main->add_child(downloads_scroll);
+ downloads_hb = memnew( HBoxContainer );
+ downloads_scroll->add_child(downloads_hb);
+
+ asset_open = memnew( EditorFileDialog );
+
+ asset_open->set_access(EditorFileDialog::ACCESS_FILESYSTEM);
+ asset_open->add_filter("*.zip ; Assets ZIP File");
+ asset_open->set_mode(EditorFileDialog::MODE_OPEN_FILE);
+ add_child(asset_open);
+ asset_open->connect("file_selected",this,"_asset_file_selected");
+
+ asset_installer=NULL;
+
}