|
@@ -1,4 +1,32 @@
|
|
|
-#include "addon_editor_plugin.h"
|
|
|
+/*************************************************************************/
|
|
|
+/* asset_library_editor_plugin.cpp */
|
|
|
+/*************************************************************************/
|
|
|
+/* This file is part of: */
|
|
|
+/* GODOT ENGINE */
|
|
|
+/* http://www.godotengine.org */
|
|
|
+/*************************************************************************/
|
|
|
+/* Copyright (c) 2007-2016 Juan Linietsky, Ariel Manzur. */
|
|
|
+/* */
|
|
|
+/* Permission is hereby granted, free of charge, to any person obtaining */
|
|
|
+/* a copy of this software and associated documentation files (the */
|
|
|
+/* "Software"), to deal in the Software without restriction, including */
|
|
|
+/* without limitation the rights to use, copy, modify, merge, publish, */
|
|
|
+/* distribute, sublicense, and/or sell copies of the Software, and to */
|
|
|
+/* permit persons to whom the Software is furnished to do so, subject to */
|
|
|
+/* the following conditions: */
|
|
|
+/* */
|
|
|
+/* The above copyright notice and this permission notice shall be */
|
|
|
+/* included in all copies or substantial portions of the Software. */
|
|
|
+/* */
|
|
|
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
|
|
|
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
|
|
|
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
|
|
|
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
|
|
|
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
|
|
|
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
|
|
|
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
|
|
+/*************************************************************************/
|
|
|
+#include "asset_library_editor_plugin.h"
|
|
|
#include "editor_node.h"
|
|
|
#include "editor_settings.h"
|
|
|
|
|
@@ -16,10 +44,10 @@ void EditorAssetLibraryItem::configure(const String& p_title,int p_asset_id,cons
|
|
|
price->set_text(p_cost);
|
|
|
|
|
|
for(int i=0;i<5;i++) {
|
|
|
- if (i>2)
|
|
|
- stars[i]->set_texture(get_icon("RatingNoStar","EditorIcons"));
|
|
|
- else
|
|
|
+ if (i<p_rating)
|
|
|
stars[i]->set_texture(get_icon("RatingStar","EditorIcons"));
|
|
|
+ else
|
|
|
+ stars[i]->set_texture(get_icon("RatingNoStar","EditorIcons"));
|
|
|
}
|
|
|
|
|
|
|
|
@@ -149,6 +177,7 @@ void EditorAddonLibraryItemDescription::set_image(int p_type,int p_index,const R
|
|
|
for(int i=0;i<preview_images.size();i++) {
|
|
|
if (preview_images[i].id==p_index) {
|
|
|
preview_images[i].button->set_icon(p_image);
|
|
|
+ break;
|
|
|
}
|
|
|
}
|
|
|
//item->call("set_image",p_type,p_index,p_image);
|
|
@@ -156,8 +185,12 @@ void EditorAddonLibraryItemDescription::set_image(int p_type,int p_index,const R
|
|
|
case EditorAddonLibrary::IMAGE_QUEUE_SCREENSHOT: {
|
|
|
|
|
|
for(int i=0;i<preview_images.size();i++) {
|
|
|
- if (preview_images[i].id==p_index && preview_images[i].button->is_pressed()) {
|
|
|
- preview->set_texture(p_image);
|
|
|
+ if (preview_images[i].id==p_index) {
|
|
|
+ preview_images[i].image = p_image;
|
|
|
+ if(preview_images[i].button->is_pressed()) {
|
|
|
+ _preview_click(p_index);
|
|
|
+ }
|
|
|
+ break;
|
|
|
}
|
|
|
}
|
|
|
//item->call("set_image",p_type,p_index,p_image);
|
|
@@ -168,29 +201,46 @@ 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);
|
|
|
+ ObjectTypeDB::bind_method(_MD("_preview_click"),&EditorAddonLibraryItemDescription::_preview_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_version,const String& p_description,const String& p_download_url,const String& p_browse_url) {
|
|
|
+void EditorAddonLibraryItemDescription::_preview_click(int p_id) {
|
|
|
+ for(int i=0;i<preview_images.size();i++) {
|
|
|
+ if(preview_images[i].id==p_id) {
|
|
|
+ preview_images[i].button->set_pressed(true);
|
|
|
+ if(!preview_images[i].is_video) {
|
|
|
+ if(preview_images[i].image.is_valid()) {
|
|
|
+ preview->set_texture(preview_images[i].image);
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ _link_click(preview_images[i].video_link);
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ preview_images[i].button->set_pressed(false);
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+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,int p_version,const String& p_version_string,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->clear();
|
|
|
- description->add_text("Version: "+p_version+"\n");
|
|
|
+ description->add_text("Version: "+p_version_string+"\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);
|
|
|
+ description->append_bbcode(p_description);
|
|
|
set_title(p_title);
|
|
|
}
|
|
|
|
|
@@ -199,13 +249,19 @@ void EditorAddonLibraryItemDescription::add_preview(int p_id, bool p_video,const
|
|
|
Preview preview;
|
|
|
preview.id=p_id;
|
|
|
preview.video_link=p_url;
|
|
|
+ preview.is_video=p_video;
|
|
|
preview.button = memnew( Button );
|
|
|
preview.button->set_flat(true);
|
|
|
preview.button->set_icon(get_icon("ThumbnailWait","EditorIcons"));
|
|
|
preview.button->set_toggle_mode(true);
|
|
|
+ preview.button->connect("pressed", this, "_preview_click", varray(p_id));
|
|
|
preview_hb->add_child(preview.button);
|
|
|
- if (preview_images.size()==0)
|
|
|
- preview.button->set_pressed(true);
|
|
|
+ if(!p_video) {
|
|
|
+ preview.image=get_icon("ThumbnailWait","EditorIcons");
|
|
|
+ }
|
|
|
+ if(preview_images.size()==0 && !p_video) {
|
|
|
+ _preview_click(p_id);
|
|
|
+ }
|
|
|
preview_images.push_back(preview);
|
|
|
}
|
|
|
|
|
@@ -257,7 +313,7 @@ EditorAddonLibraryItemDescription::EditorAddonLibraryItemDescription() {
|
|
|
|
|
|
previews->add_child(preview_hb);
|
|
|
get_ok()->set_text("Install");
|
|
|
- get_cancel()->set_text(TTR("Close"));
|
|
|
+ get_cancel()->set_text("Close");
|
|
|
|
|
|
|
|
|
|
|
@@ -337,14 +393,9 @@ void EditorAddonLibraryItemDownload::configure(const String& p_title,int p_asset
|
|
|
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"));
|
|
|
-
|
|
|
-
|
|
|
+ dismiss->set_normal_texture( get_icon("Close","EditorIcons"));
|
|
|
+ _make_request();
|
|
|
}
|
|
|
|
|
|
|
|
@@ -392,11 +443,23 @@ void EditorAddonLibraryItemDownload::_install() {
|
|
|
asset_installer->open(file,1);
|
|
|
}
|
|
|
|
|
|
+void EditorAddonLibraryItemDownload::_make_request() {
|
|
|
+ download->cancel_request();
|
|
|
+ download->set_download_file(EditorSettings::get_singleton()->get_settings_path().plus_file("tmp").plus_file("tmp_asset_"+itos(asset_id))+".zip");
|
|
|
+ Error err = download->request(host);
|
|
|
+ if(err!=OK) {
|
|
|
+ status->set_text("Error making request");
|
|
|
+ } else {
|
|
|
+ set_process(true);
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
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);
|
|
|
+ ObjectTypeDB::bind_method("_make_request",&EditorAddonLibraryItemDownload::_make_request);
|
|
|
|
|
|
}
|
|
|
|
|
@@ -442,6 +505,11 @@ EditorAddonLibraryItemDownload::EditorAddonLibraryItemDownload() {
|
|
|
install->set_disabled(true);
|
|
|
install->connect("pressed",this,"_install");
|
|
|
|
|
|
+ retry = memnew( Button );
|
|
|
+ retry->set_text("Retry");
|
|
|
+ retry->connect("pressed",this,"_make_request");
|
|
|
+
|
|
|
+ hb2->add_child(retry);
|
|
|
hb2->add_child(install);
|
|
|
set_custom_minimum_size(Size2(250,0));
|
|
|
|
|
@@ -472,7 +540,7 @@ void EditorAddonLibrary::_notification(int p_what) {
|
|
|
error_hb->add_child(tf);
|
|
|
error_label->raise();
|
|
|
|
|
|
- _api_request("api/configure");
|
|
|
+ _repository_changed(0);
|
|
|
}
|
|
|
|
|
|
if (p_what==NOTIFICATION_PROCESS) {
|
|
@@ -572,7 +640,7 @@ void EditorAddonLibrary::_select_category(int p_id){
|
|
|
}
|
|
|
void EditorAddonLibrary::_select_asset(int p_id){
|
|
|
|
|
|
- _api_request("api/asset","?id="+itos(p_id));
|
|
|
+ _api_request("asset/"+itos(p_id), REQUESTING_ASSET);
|
|
|
|
|
|
/*
|
|
|
if (description) {
|
|
@@ -585,33 +653,102 @@ void EditorAddonLibrary::_select_asset(int p_id){
|
|
|
description->popup_centered_minsize();*/
|
|
|
}
|
|
|
|
|
|
+void EditorAddonLibrary::_image_update(bool use_cache, bool final, const ByteArray& p_data, int p_queue_id) {
|
|
|
+ Object *obj = ObjectDB::get_instance(image_queue[p_queue_id].target);
|
|
|
+
|
|
|
+ if (obj) {
|
|
|
+ bool image_set = false;
|
|
|
+ ByteArray image_data = p_data;
|
|
|
+
|
|
|
+ if(use_cache) {
|
|
|
+ String cache_filename_base = EditorSettings::get_singleton()->get_settings_path().plus_file("tmp").plus_file("assetimage_"+image_queue[p_queue_id].image_url.md5_text());
|
|
|
+
|
|
|
+ FileAccess* file = FileAccess::open(cache_filename_base+".data", FileAccess::READ);
|
|
|
+
|
|
|
+ if(file) {
|
|
|
+ ByteArray cached_data;
|
|
|
+ int len=file->get_32();
|
|
|
+ cached_data.resize(len);
|
|
|
+
|
|
|
+ ByteArray::Write w=cached_data.write();
|
|
|
+ file->get_buffer(w.ptr(), len);
|
|
|
+
|
|
|
+ image_data = cached_data;
|
|
|
+ file->close();
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ int len=image_data.size();
|
|
|
+ ByteArray::Read r=image_data.read();
|
|
|
+ Image image(r.ptr(),len);
|
|
|
+ if (!image.empty()) {
|
|
|
+ float max_height = 10000;
|
|
|
+ switch(image_queue[p_queue_id].image_type) {
|
|
|
+ case IMAGE_QUEUE_ICON: max_height=80; break;
|
|
|
+ case IMAGE_QUEUE_THUMBNAIL: max_height=80; break;
|
|
|
+ case IMAGE_QUEUE_SCREENSHOT: max_height=345; break;
|
|
|
+ }
|
|
|
+ float scale_ratio = max_height / image.get_height();
|
|
|
+ if(scale_ratio < 1) {
|
|
|
+ image.resize(image.get_width() * scale_ratio, image.get_height() * scale_ratio, Image::INTERPOLATE_CUBIC);
|
|
|
+ }
|
|
|
+
|
|
|
+ Ref<ImageTexture> tex;
|
|
|
+ tex.instance();
|
|
|
+ tex->create_from_image(image);
|
|
|
|
|
|
+ obj->call("set_image",image_queue[p_queue_id].image_type,image_queue[p_queue_id].image_index,tex);
|
|
|
+ image_set = true;
|
|
|
+ }
|
|
|
+
|
|
|
+ if(!image_set && final) {
|
|
|
+ obj->call("set_image",image_queue[p_queue_id].image_type,image_queue[p_queue_id].image_index,get_icon("ErrorSign","EditorIcons"));
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
|
|
|
void EditorAddonLibrary::_image_request_completed(int p_status, int p_code, const StringArray& headers, const ByteArray& p_data,int p_queue_id) {
|
|
|
|
|
|
ERR_FAIL_COND( !image_queue.has(p_queue_id) );
|
|
|
|
|
|
if (p_status==HTTPRequest::RESULT_SUCCESS) {
|
|
|
-
|
|
|
-
|
|
|
+
|
|
|
print_line("GOT IMAGE YAY!");
|
|
|
- Object *obj = ObjectDB::get_instance(image_queue[p_queue_id].target);
|
|
|
-
|
|
|
- if (obj) {
|
|
|
- int len=p_data.size();
|
|
|
- ByteArray::Read r=p_data.read();
|
|
|
-
|
|
|
- Image image(r.ptr(),len);
|
|
|
- if (!image.empty()) {
|
|
|
- Ref<ImageTexture> tex;
|
|
|
- tex.instance();
|
|
|
- tex->create_from_image(image);
|
|
|
-
|
|
|
- obj->call("set_image",image_queue[p_queue_id].image_type,image_queue[p_queue_id].image_index,tex);
|
|
|
+
|
|
|
+ if(p_code != HTTPClient::RESPONSE_NOT_MODIFIED) {
|
|
|
+ for(int i=0;i<headers.size();i++) {
|
|
|
+ if (headers[i].findn("ETag:")==0) { // Save etag
|
|
|
+ String cache_filename_base = EditorSettings::get_singleton()->get_settings_path().plus_file("tmp").plus_file("assetimage_"+image_queue[p_queue_id].image_url.md5_text());
|
|
|
+ String new_etag = headers[i].substr(headers[i].find(":")+1,headers[i].length()).strip_edges();
|
|
|
+ FileAccess* file;
|
|
|
+
|
|
|
+ file = FileAccess::open(cache_filename_base+".etag", FileAccess::WRITE);
|
|
|
+ if(file) {
|
|
|
+ file->store_line(new_etag);
|
|
|
+ file->close();
|
|
|
+ }
|
|
|
+
|
|
|
+ int len=p_data.size();
|
|
|
+ ByteArray::Read r=p_data.read();
|
|
|
+ file = FileAccess::open(cache_filename_base+".data", FileAccess::WRITE);
|
|
|
+ if(file) {
|
|
|
+ file->store_32(len);
|
|
|
+ file->store_buffer(r.ptr(),len);
|
|
|
+ file->close();
|
|
|
+ }
|
|
|
+
|
|
|
+ break;
|
|
|
+ }
|
|
|
}
|
|
|
}
|
|
|
+ _image_update(p_code == HTTPClient::RESPONSE_NOT_MODIFIED, true, p_data, p_queue_id);
|
|
|
+
|
|
|
} else {
|
|
|
WARN_PRINTS("Error getting PNG file for asset id "+itos(image_queue[p_queue_id].asset_id));
|
|
|
+ Object *obj = ObjectDB::get_instance(image_queue[p_queue_id].target);
|
|
|
+ if (obj) {
|
|
|
+ obj->call("set_image",image_queue[p_queue_id].image_type,image_queue[p_queue_id].image_index,get_icon("ErrorSign","EditorIcons"));
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
image_queue[p_queue_id].request->queue_delete();;
|
|
@@ -629,16 +766,20 @@ void EditorAddonLibrary::_update_image_queue() {
|
|
|
List<int> to_delete;
|
|
|
for (Map<int,ImageQueue>::Element *E=image_queue.front();E;E=E->next()) {
|
|
|
if (!E->get().active && current_images<max_images) {
|
|
|
-
|
|
|
- String api;
|
|
|
- switch(E->get().image_type) {
|
|
|
- case IMAGE_QUEUE_ICON: api="api/icon/icon.png"; break;
|
|
|
- case IMAGE_QUEUE_SCREENSHOT: api="api/screenshot/screenshot.png"; break;
|
|
|
- case IMAGE_QUEUE_THUMBNAIL: api="api/thumbnail/thumbnail.png"; break;
|
|
|
+
|
|
|
+ String cache_filename_base = EditorSettings::get_singleton()->get_settings_path().plus_file("tmp").plus_file("assetimage_"+E->get().image_url.md5_text());
|
|
|
+ Vector<String> headers;
|
|
|
+
|
|
|
+ if(FileAccess::exists(cache_filename_base+".etag") && FileAccess::exists(cache_filename_base+".data")) {
|
|
|
+ FileAccess* file = FileAccess::open(cache_filename_base+".etag", FileAccess::READ);
|
|
|
+ if (file) {
|
|
|
+ headers.push_back("If-None-Match: " + file->get_line());
|
|
|
+ file->close();
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
print_line("REQUEST ICON FOR: "+itos(E->get().asset_id));
|
|
|
- Error err = E->get().request->request(host+"/"+api+"?asset_id="+itos(E->get().asset_id)+"&index="+itos(E->get().image_index));
|
|
|
+ Error err = E->get().request->request(E->get().image_url, headers);
|
|
|
if (err!=OK) {
|
|
|
to_delete.push_back(E->key());
|
|
|
} else {
|
|
@@ -657,11 +798,11 @@ void EditorAddonLibrary::_update_image_queue() {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-void EditorAddonLibrary::_request_image(ObjectID p_for,int p_asset_id,ImageType p_type,int p_image_index) {
|
|
|
+void EditorAddonLibrary::_request_image(ObjectID p_for,String p_image_url,ImageType p_type,int p_image_index) {
|
|
|
|
|
|
|
|
|
ImageQueue iq;
|
|
|
- iq.asset_id=p_asset_id;
|
|
|
+ iq.image_url=p_image_url;
|
|
|
iq.image_index=p_image_index;
|
|
|
iq.image_type=p_type;
|
|
|
iq.request = memnew( HTTPRequest );
|
|
@@ -676,11 +817,17 @@ void EditorAddonLibrary::_request_image(ObjectID p_for,int p_asset_id,ImageType
|
|
|
|
|
|
add_child(iq.request);
|
|
|
|
|
|
+ _image_update(true, false, ByteArray(), iq.queue_id);
|
|
|
_update_image_queue();
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
+void EditorAddonLibrary::_repository_changed(int p_repository_id) {
|
|
|
+ host=repository->get_item_metadata(p_repository_id);
|
|
|
+ print_line(".." + host);
|
|
|
+ _api_request("configure", REQUESTING_CONFIG);
|
|
|
+}
|
|
|
|
|
|
void EditorAddonLibrary::_search(int p_page) {
|
|
|
|
|
@@ -692,7 +839,12 @@ void EditorAddonLibrary::_search(int p_page) {
|
|
|
|
|
|
args+="&category="+itos(categories->get_item_metadata(categories->get_selected()));
|
|
|
}
|
|
|
+
|
|
|
+ if (reverse->is_pressed()) {
|
|
|
|
|
|
+ args+="&reverse=true";
|
|
|
+ }
|
|
|
+
|
|
|
if (filter->get_text()!=String()) {
|
|
|
args+="&filter="+filter->get_text().http_escape();
|
|
|
}
|
|
@@ -701,10 +853,10 @@ void EditorAddonLibrary::_search(int p_page) {
|
|
|
args+="&page="+itos(p_page);
|
|
|
}
|
|
|
|
|
|
- _api_request("api/search",args);
|
|
|
+ _api_request("asset",REQUESTING_SEARCH,args);
|
|
|
}
|
|
|
|
|
|
-HBoxContainer* EditorAddonLibrary::_make_pages(int p_page,int p_max_page,int p_page_len,int p_total_items,int p_current_items) {
|
|
|
+HBoxContainer* EditorAddonLibrary::_make_pages(int p_page,int p_page_count,int p_page_len,int p_total_items,int p_current_items) {
|
|
|
|
|
|
HBoxContainer * hbc = memnew( HBoxContainer );
|
|
|
|
|
@@ -713,20 +865,22 @@ HBoxContainer* EditorAddonLibrary::_make_pages(int p_page,int p_max_page,int p_p
|
|
|
if (from<0)
|
|
|
from=0;
|
|
|
int to = from+10;
|
|
|
- if (to>p_max_page)
|
|
|
- to=p_max_page;
|
|
|
+ if (to>p_page_count)
|
|
|
+ to=p_page_count;
|
|
|
|
|
|
Color gray = Color(0.65,0.65,0.65);
|
|
|
|
|
|
hbc->add_spacer();
|
|
|
hbc->add_constant_override("separation",10);
|
|
|
|
|
|
- LinkButton *first = memnew( LinkButton );
|
|
|
- first->set_text("first");
|
|
|
- first->add_color_override("font_color", gray );
|
|
|
- first->set_underline_mode(LinkButton::UNDERLINE_MODE_ON_HOVER);
|
|
|
- first->connect("pressed",this,"_search",varray(0));
|
|
|
- hbc->add_child(first);
|
|
|
+ if(p_page != 0) {
|
|
|
+ LinkButton *first = memnew( LinkButton );
|
|
|
+ first->set_text("first");
|
|
|
+ first->add_color_override("font_color", gray );
|
|
|
+ first->set_underline_mode(LinkButton::UNDERLINE_MODE_ON_HOVER);
|
|
|
+ first->connect("pressed",this,"_search",varray(0));
|
|
|
+ hbc->add_child(first);
|
|
|
+ }
|
|
|
|
|
|
if (p_page>0) {
|
|
|
LinkButton *prev = memnew( LinkButton );
|
|
@@ -737,19 +891,19 @@ HBoxContainer* EditorAddonLibrary::_make_pages(int p_page,int p_max_page,int p_p
|
|
|
hbc->add_child(prev);
|
|
|
}
|
|
|
|
|
|
- for(int i=from;i<=to;i++) {
|
|
|
+ for(int i=from;i<to;i++) {
|
|
|
|
|
|
if (i==p_page) {
|
|
|
|
|
|
Label *current = memnew(Label);
|
|
|
- current->set_text(itos(i));
|
|
|
+ current->set_text(itos(i+1));
|
|
|
hbc->add_child(current);
|
|
|
} else {
|
|
|
|
|
|
LinkButton *current = memnew( LinkButton );
|
|
|
current->add_color_override("font_color", gray );
|
|
|
current->set_underline_mode(LinkButton::UNDERLINE_MODE_ON_HOVER);
|
|
|
- current->set_text(itos(i));
|
|
|
+ current->set_text(itos(i+1));
|
|
|
current->connect("pressed",this,"_search",varray(i));
|
|
|
|
|
|
hbc->add_child(current);
|
|
@@ -757,7 +911,7 @@ HBoxContainer* EditorAddonLibrary::_make_pages(int p_page,int p_max_page,int p_p
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- if (p_page<p_max_page) {
|
|
|
+ if (p_page<p_page_count-1) {
|
|
|
LinkButton *next = memnew( LinkButton );
|
|
|
next->set_text("next");
|
|
|
next->add_color_override("font_color", gray );
|
|
@@ -766,12 +920,15 @@ HBoxContainer* EditorAddonLibrary::_make_pages(int p_page,int p_max_page,int p_p
|
|
|
|
|
|
hbc->add_child(next);
|
|
|
}
|
|
|
- LinkButton *last = memnew( LinkButton );
|
|
|
- last->set_text("last");
|
|
|
- last->add_color_override("font_color", gray );
|
|
|
- last->set_underline_mode(LinkButton::UNDERLINE_MODE_ON_HOVER);
|
|
|
- hbc->add_child(last);
|
|
|
- last->connect("pressed",this,"_search",varray(p_max_page));
|
|
|
+
|
|
|
+ if(p_page != p_page_count-1) {
|
|
|
+ LinkButton *last = memnew( LinkButton );
|
|
|
+ last->set_text("last");
|
|
|
+ last->add_color_override("font_color", gray );
|
|
|
+ last->set_underline_mode(LinkButton::UNDERLINE_MODE_ON_HOVER);
|
|
|
+ hbc->add_child(last);
|
|
|
+ last->connect("pressed",this,"_search",varray(p_page_count-1));
|
|
|
+ }
|
|
|
|
|
|
Label *totals = memnew( Label );
|
|
|
totals->set_text("( "+itos(from*p_page_len)+" - "+itos(from*p_page_len+p_current_items-1)+" / "+itos(p_total_items)+" )");
|
|
@@ -783,14 +940,14 @@ HBoxContainer* EditorAddonLibrary::_make_pages(int p_page,int p_max_page,int p_p
|
|
|
}
|
|
|
|
|
|
|
|
|
-void EditorAddonLibrary::_api_request(const String& p_request,const String& p_arguments) {
|
|
|
+void EditorAddonLibrary::_api_request(const String& p_request, RequestType p_request_type, const String& p_arguments) {
|
|
|
|
|
|
if (requesting!=REQUESTING_NONE) {
|
|
|
request->cancel_request();
|
|
|
}
|
|
|
+ requesting=p_request_type;
|
|
|
|
|
|
error_hb->hide();
|
|
|
- current_request=p_request;
|
|
|
request->request(host+"/"+p_request+p_arguments);
|
|
|
}
|
|
|
|
|
@@ -856,165 +1013,173 @@ void EditorAddonLibrary::_http_request_completed(int p_status, int p_code, const
|
|
|
|
|
|
print_line(Variant(d).get_construct_string());
|
|
|
|
|
|
- if (current_request=="api/configure") {
|
|
|
-
|
|
|
- categories->clear();
|
|
|
- categories->add_item("All");
|
|
|
- categories->set_item_metadata(0,0);
|
|
|
- if (d.has("categories")) {
|
|
|
- Array clist = d["categories"];
|
|
|
- for(int i=0;i<clist.size();i++) {
|
|
|
- Dictionary cat = clist[i];
|
|
|
- if (!cat.has("name") || !cat.has("id"))
|
|
|
- continue;
|
|
|
- String name=cat["name"];
|
|
|
- int id=cat["id"];
|
|
|
- categories->add_item(name);
|
|
|
- categories->set_item_metadata( categories->get_item_count() -1, id);
|
|
|
+ RequestType requested = requesting;
|
|
|
+ requesting=REQUESTING_NONE;
|
|
|
+
|
|
|
+ switch(requested) {
|
|
|
+ case REQUESTING_CONFIG: {
|
|
|
+
|
|
|
+ categories->clear();
|
|
|
+ categories->add_item("All");
|
|
|
+ categories->set_item_metadata(0,0);
|
|
|
+ if (d.has("categories")) {
|
|
|
+ Array clist = d["categories"];
|
|
|
+ for(int i=0;i<clist.size();i++) {
|
|
|
+ Dictionary cat = clist[i];
|
|
|
+ if (!cat.has("name") || !cat.has("id"))
|
|
|
+ continue;
|
|
|
+ String name=cat["name"];
|
|
|
+ int id=cat["id"];
|
|
|
+ categories->add_item(name);
|
|
|
+ categories->set_item_metadata( categories->get_item_count() -1, id);
|
|
|
+ category_map[cat["id"]] = name;
|
|
|
+ }
|
|
|
}
|
|
|
- }
|
|
|
|
|
|
- _search();
|
|
|
- } else if (current_request=="api/search") {
|
|
|
-
|
|
|
- if (asset_items) {
|
|
|
- memdelete(asset_items);
|
|
|
- }
|
|
|
-
|
|
|
- if (asset_top_page) {
|
|
|
- memdelete(asset_top_page);
|
|
|
- }
|
|
|
-
|
|
|
- if (asset_bottom_page) {
|
|
|
- memdelete(asset_bottom_page);
|
|
|
- }
|
|
|
-
|
|
|
- int page=0;
|
|
|
- int pages=1;
|
|
|
- int page_len=10;
|
|
|
- int total_items=1;
|
|
|
- Array result;
|
|
|
-
|
|
|
-
|
|
|
- if (d.has("page")) {
|
|
|
- page=d["page"];
|
|
|
- }
|
|
|
- if (d.has("pages")) {
|
|
|
- pages=d["pages"];
|
|
|
- }
|
|
|
- if (d.has("page_length")) {
|
|
|
- page_len=d["page_length"];
|
|
|
- }
|
|
|
- if (d.has("total")) {
|
|
|
- total_items=d["total"];
|
|
|
- }
|
|
|
- if (d.has("result")) {
|
|
|
- result=d["result"];
|
|
|
- }
|
|
|
-
|
|
|
- asset_top_page = _make_pages(page,pages,page_len,total_items,result.size());
|
|
|
- library_vb->add_child(asset_top_page);
|
|
|
+ _search();
|
|
|
+ } break;
|
|
|
+ case REQUESTING_SEARCH: {
|
|
|
+ if (asset_items) {
|
|
|
+ memdelete(asset_items);
|
|
|
+ }
|
|
|
|
|
|
- asset_items = memnew( GridContainer );
|
|
|
- asset_items->set_columns(2);
|
|
|
- asset_items->add_constant_override("hseparation",10);
|
|
|
- asset_items->add_constant_override("vseparation",10);
|
|
|
+ if (asset_top_page) {
|
|
|
+ memdelete(asset_top_page);
|
|
|
+ }
|
|
|
|
|
|
- library_vb->add_child(asset_items);
|
|
|
+ if (asset_bottom_page) {
|
|
|
+ memdelete(asset_bottom_page);
|
|
|
+ }
|
|
|
|
|
|
- asset_bottom_page = _make_pages(page,pages,page_len,total_items,result.size());
|
|
|
- library_vb->add_child(asset_bottom_page);
|
|
|
+ int page=0;
|
|
|
+ int pages=1;
|
|
|
+ int page_len=10;
|
|
|
+ int total_items=1;
|
|
|
+ Array result;
|
|
|
|
|
|
- for(int i=0;i<result.size();i++) {
|
|
|
|
|
|
- Dictionary r = result[i];
|
|
|
+ if (d.has("page")) {
|
|
|
+ page=d["page"];
|
|
|
+ }
|
|
|
+ if (d.has("pages")) {
|
|
|
+ pages=d["pages"];
|
|
|
+ }
|
|
|
+ if (d.has("page_length")) {
|
|
|
+ page_len=d["page_length"];
|
|
|
+ }
|
|
|
+ if (d.has("total")) {
|
|
|
+ total_items=d["total"];
|
|
|
+ }
|
|
|
+ if (d.has("result")) {
|
|
|
+ result=d["result"];
|
|
|
+ }
|
|
|
|
|
|
- ERR_CONTINUE(!r.has("title"));
|
|
|
- ERR_CONTINUE(!r.has("asset_id"));
|
|
|
- ERR_CONTINUE(!r.has("author"));
|
|
|
- ERR_CONTINUE(!r.has("author_id"));
|
|
|
- ERR_CONTINUE(!r.has("category"));
|
|
|
- ERR_CONTINUE(!r.has("category_id"));
|
|
|
- ERR_CONTINUE(!r.has("rating"));
|
|
|
- ERR_CONTINUE(!r.has("cost"));
|
|
|
+ asset_top_page = _make_pages(page,pages,page_len,total_items,result.size());
|
|
|
+ library_vb->add_child(asset_top_page);
|
|
|
|
|
|
+ asset_items = memnew( GridContainer );
|
|
|
+ asset_items->set_columns(2);
|
|
|
+ asset_items->add_constant_override("hseparation",10);
|
|
|
+ asset_items->add_constant_override("vseparation",10);
|
|
|
|
|
|
- EditorAssetLibraryItem *item = memnew( EditorAssetLibraryItem );
|
|
|
- asset_items->add_child(item);
|
|
|
- item->configure(r["title"],r["asset_id"],r["category"],r["category_id"],r["author"],r["author_id"],r["rating"],r["cost"]);
|
|
|
- item->connect("asset_selected",this,"_select_asset");
|
|
|
- item->connect("author_selected",this,"_select_author");
|
|
|
- item->connect("category_selected",this,"_category_selected");
|
|
|
+ library_vb->add_child(asset_items);
|
|
|
|
|
|
- _request_image(item->get_instance_ID(),r["asset_id"],IMAGE_QUEUE_ICON,0);
|
|
|
- }
|
|
|
- } else if (current_request=="api/asset") {
|
|
|
+ asset_bottom_page = _make_pages(page,pages,page_len,total_items,result.size());
|
|
|
+ library_vb->add_child(asset_bottom_page);
|
|
|
|
|
|
- ERR_FAIL_COND(!d.has("info"));
|
|
|
+ for(int i=0;i<result.size();i++) {
|
|
|
|
|
|
- Dictionary r = d["info"];
|
|
|
+ Dictionary r = result[i];
|
|
|
|
|
|
- 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_CONTINUE(!r.has("title"));
|
|
|
+ ERR_CONTINUE(!r.has("asset_id"));
|
|
|
+ ERR_CONTINUE(!r.has("author"));
|
|
|
+ ERR_CONTINUE(!r.has("author_id"));
|
|
|
+ ERR_CONTINUE(!r.has("category_id"));
|
|
|
+ ERR_FAIL_COND(!category_map.has(r["category_id"]));
|
|
|
+ ERR_CONTINUE(!r.has("rating"));
|
|
|
+ ERR_CONTINUE(!r.has("cost"));
|
|
|
|
|
|
- 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"));
|
|
|
|
|
|
+ EditorAssetLibraryItem *item = memnew( EditorAssetLibraryItem );
|
|
|
+ asset_items->add_child(item);
|
|
|
+ item->configure(r["title"],r["asset_id"],category_map[r["category_id"]],r["category_id"],r["author"],r["author_id"],r["rating"],r["cost"]);
|
|
|
+ item->connect("asset_selected",this,"_select_asset");
|
|
|
+ item->connect("author_selected",this,"_select_author");
|
|
|
+ item->connect("category_selected",this,"_select_category");
|
|
|
|
|
|
- if (description) {
|
|
|
- memdelete(description);
|
|
|
- }
|
|
|
+ if(r.has("icon_url") && r["icon_url"] != "") {
|
|
|
+ _request_image(item->get_instance_ID(),r["icon_url"],IMAGE_QUEUE_ICON,0);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ } break;
|
|
|
+ case REQUESTING_ASSET: {
|
|
|
+ Dictionary r = d;
|
|
|
+
|
|
|
+ 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("version_string"));
|
|
|
+ ERR_FAIL_COND(!r.has("category_id"));
|
|
|
+ ERR_FAIL_COND(!category_map.has(r["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);
|
|
|
+ }
|
|
|
|
|
|
- description = memnew( EditorAddonLibraryItemDescription );
|
|
|
- add_child(description);
|
|
|
- description->popup_centered_minsize();
|
|
|
- description->connect("confirmed",this,"_install_asset");
|
|
|
+ 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["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");*/
|
|
|
+ description->configure(r["title"],r["asset_id"],category_map[r["category_id"]],r["category_id"],r["author"],r["author_id"],r["rating"],r["cost"],r["version"],r["version_string"],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");*/
|
|
|
|
|
|
- _request_image(description->get_instance_ID(),r["asset_id"],IMAGE_QUEUE_ICON,0);
|
|
|
+ if(r.has("icon_url") && r["icon_url"] != "") {
|
|
|
+ _request_image(description->get_instance_ID(),r["icon_url"],IMAGE_QUEUE_ICON,0);
|
|
|
+ }
|
|
|
|
|
|
- if (d.has("previews")) {
|
|
|
- Array previews = d["previews"];
|
|
|
+ if (d.has("previews")) {
|
|
|
+ Array previews = d["previews"];
|
|
|
|
|
|
- for(int i=0;i<previews.size();i++) {
|
|
|
+ for(int i=0;i<previews.size();i++) {
|
|
|
|
|
|
|
|
|
- Dictionary p=previews[i];
|
|
|
+ Dictionary p=previews[i];
|
|
|
|
|
|
- ERR_CONTINUE(!p.has("id"));
|
|
|
+ ERR_CONTINUE(!p.has("type"));
|
|
|
+ ERR_CONTINUE(!p.has("link"));
|
|
|
|
|
|
- bool is_video=p.has("type") && String(p["type"])=="video";
|
|
|
- String video_url;
|
|
|
- if (is_video && p.has("link")) {
|
|
|
- video_url="link";
|
|
|
- }
|
|
|
+ bool is_video=p.has("type") && String(p["type"])=="video";
|
|
|
+ String video_url;
|
|
|
+ if (is_video && p.has("link")) {
|
|
|
+ video_url=p["link"];
|
|
|
+ }
|
|
|
|
|
|
- int id=p["id"];
|
|
|
+ description->add_preview(i,is_video,video_url);
|
|
|
|
|
|
- description->add_preview(id,is_video,video_url);
|
|
|
+ if(p.has("thumbnail")) {
|
|
|
+ _request_image(description->get_instance_ID(),p["thumbnail"],IMAGE_QUEUE_THUMBNAIL,i);
|
|
|
+ }
|
|
|
+ if(is_video) {
|
|
|
+ //_request_image(description->get_instance_ID(),p["link"],IMAGE_QUEUE_SCREENSHOT,i);
|
|
|
+ } else {
|
|
|
+ _request_image(description->get_instance_ID(),p["link"],IMAGE_QUEUE_SCREENSHOT,i);
|
|
|
+ }
|
|
|
|
|
|
- _request_image(description->get_instance_ID(),r["asset_id"],IMAGE_QUEUE_THUMBNAIL,id);
|
|
|
- if (i==0) {
|
|
|
- _request_image(description->get_instance_ID(),r["asset_id"],IMAGE_QUEUE_SCREENSHOT,id);
|
|
|
}
|
|
|
-
|
|
|
}
|
|
|
- }
|
|
|
+ } break;
|
|
|
+ default: break;
|
|
|
}
|
|
|
|
|
|
}
|
|
@@ -1059,6 +1224,7 @@ void EditorAddonLibrary::_bind_methods() {
|
|
|
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);
|
|
|
+ ObjectTypeDB::bind_method("_repository_changed",&EditorAddonLibrary::_repository_changed);
|
|
|
|
|
|
}
|
|
|
|
|
@@ -1090,19 +1256,19 @@ EditorAddonLibrary::EditorAddonLibrary() {
|
|
|
search_hb->add_child(filter);
|
|
|
filter->set_h_size_flags(SIZE_EXPAND_FILL);
|
|
|
filter->connect("text_entered",this,"_search");
|
|
|
- search = memnew( Button(TTR("Search")));
|
|
|
+ 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(TTR("Import"));
|
|
|
+ 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(TTR("Plugins"));
|
|
|
+ plugins->set_text("Plugins");
|
|
|
search_hb->add_child(plugins);
|
|
|
plugins->connect("pressed",this,"_manage_plugins");
|
|
|
|
|
@@ -1142,7 +1308,12 @@ EditorAddonLibrary::EditorAddonLibrary() {
|
|
|
search_hb2->add_child( memnew( Label(TTR("Site:")+" ")));
|
|
|
repository = memnew( OptionButton );
|
|
|
|
|
|
+ repository->add_item("Localhost"); // TODO: Maybe remove?
|
|
|
+ repository->set_item_metadata(0, "http://127.0.0.1/addonlib/api");
|
|
|
repository->add_item("Godot");
|
|
|
+ repository->set_item_metadata(1, "http://godotengine.org/addonlib/api");
|
|
|
+ repository->connect("item_selected",this,"_repository_changed");
|
|
|
+
|
|
|
search_hb2->add_child(repository);
|
|
|
repository->set_h_size_flags(SIZE_EXPAND_FILL);
|
|
|
|
|
@@ -1199,7 +1370,6 @@ EditorAddonLibrary::EditorAddonLibrary() {
|
|
|
add_child(request);
|
|
|
request->connect("request_completed",this,"_http_request_completed");
|
|
|
|
|
|
-
|
|
|
last_queue_id=0;
|
|
|
|
|
|
library_vb->add_constant_override("separation",20);
|
|
@@ -1218,8 +1388,6 @@ EditorAddonLibrary::EditorAddonLibrary() {
|
|
|
|
|
|
description = NULL;
|
|
|
|
|
|
- //host="http://localhost:8000";
|
|
|
- host="http://godotengine.org/addonlib";
|
|
|
set_process(true);
|
|
|
|
|
|
downloads_scroll = memnew( ScrollContainer );
|
|
@@ -1245,7 +1413,7 @@ EditorAddonLibrary::EditorAddonLibrary() {
|
|
|
///////
|
|
|
|
|
|
|
|
|
-void AddonEditorPlugin::make_visible(bool p_visible) {
|
|
|
+void AssetLibraryEditorPlugin::make_visible(bool p_visible) {
|
|
|
|
|
|
if (p_visible) {
|
|
|
|
|
@@ -1257,7 +1425,7 @@ void AddonEditorPlugin::make_visible(bool p_visible) {
|
|
|
|
|
|
}
|
|
|
|
|
|
-AddonEditorPlugin::AddonEditorPlugin(EditorNode *p_node) {
|
|
|
+AssetLibraryEditorPlugin::AssetLibraryEditorPlugin(EditorNode *p_node) {
|
|
|
|
|
|
editor=p_node;
|
|
|
addon_library = memnew( EditorAddonLibrary );
|
|
@@ -1268,6 +1436,6 @@ AddonEditorPlugin::AddonEditorPlugin(EditorNode *p_node) {
|
|
|
|
|
|
}
|
|
|
|
|
|
-AddonEditorPlugin::~AddonEditorPlugin() {
|
|
|
+AssetLibraryEditorPlugin::~AssetLibraryEditorPlugin() {
|
|
|
|
|
|
}
|