2016-06-07 20:29:15 +02:00
/**************************************************************************/
/* asset_library_editor_plugin.cpp */
/**************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
/* https://godotengine.org */
/**************************************************************************/
/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
/* Copyright (c) 2007-2014 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. */
/**************************************************************************/
2018-01-05 00:50:27 +01:00
2016-06-07 20:29:15 +02:00
# include "asset_library_editor_plugin.h"
2017-01-16 08:04:19 +01:00
2020-04-28 15:19:37 +02:00
# include "core/input/input.h"
Refactor version macros and fix related bugs
The previous logic with VERSION_MKSTRING was a bit unwieldy, so there were
several places hardcoding their own variant of the version string, potentially
with bugs (e.g. forgetting the patch number when defined).
The new logic defines:
- VERSION_BRANCH, the main 'major.minor' version (e.g. 3.1)
- VERSION_NUMBER, which can be 'major.minor' or 'major.minor.patch',
depending on whether the latter is defined (e.g. 3.1.4)
- VERSION_FULL_CONFIG, which contains the version status (e.g. stable)
and the module-specific suffix (e.g. mono)
- VERSION_FULL_BUILD, same as above but with build/reference name
(e.g. official, custom_build, mageia, etc.)
Note: Slight change here, as the previous format had the build name
*before* the module-specific suffix; now it's after
- VERSION_FULL_NAME, same as before, so VERSION_FULL_BUILD prefixed
with "Godot v" for readability
Bugs fixed thanks to that:
- Export templates version matching now properly takes VERSION_PATCH
into account by relying on VERSION_FULL_CONFIG.
- ClassDB hash no longer takes the build name into account, but limits
itself to VERSION_FULL_CONFIG (build name is cosmetic, not relevant
for the API hash).
- Docs XML no longer hardcode the VERSION_STATUS, this was annoying.
- Small cleanup in Windows .rc file thanks to new macros.
2018-02-23 19:48:49 +01:00
# include "core/io/json.h"
2022-09-07 00:46:12 +02:00
# include "core/io/stream_peer_tls.h"
2019-11-22 00:39:39 +01:00
# include "core/os/keyboard.h"
Refactor version macros and fix related bugs
The previous logic with VERSION_MKSTRING was a bit unwieldy, so there were
several places hardcoding their own variant of the version string, potentially
with bugs (e.g. forgetting the patch number when defined).
The new logic defines:
- VERSION_BRANCH, the main 'major.minor' version (e.g. 3.1)
- VERSION_NUMBER, which can be 'major.minor' or 'major.minor.patch',
depending on whether the latter is defined (e.g. 3.1.4)
- VERSION_FULL_CONFIG, which contains the version status (e.g. stable)
and the module-specific suffix (e.g. mono)
- VERSION_FULL_BUILD, same as above but with build/reference name
(e.g. official, custom_build, mageia, etc.)
Note: Slight change here, as the previous format had the build name
*before* the module-specific suffix; now it's after
- VERSION_FULL_NAME, same as before, so VERSION_FULL_BUILD prefixed
with "Godot v" for readability
Bugs fixed thanks to that:
- Export templates version matching now properly takes VERSION_PATCH
into account by relying on VERSION_FULL_CONFIG.
- ClassDB hash no longer takes the build name into account, but limits
itself to VERSION_FULL_CONFIG (build name is cosmetic, not relevant
for the API hash).
- Docs XML no longer hardcode the VERSION_STATUS, this was annoying.
- Small cleanup in Windows .rc file thanks to new macros.
2018-02-23 19:48:49 +01:00
# include "core/version.h"
2019-10-09 16:11:04 +02:00
# include "editor/editor_node.h"
2022-02-14 14:00:03 +01:00
# include "editor/editor_paths.h"
2019-10-09 16:11:04 +02:00
# include "editor/editor_settings.h"
2023-08-13 02:33:39 +02:00
# include "editor/editor_string_names.h"
2023-04-07 18:59:49 +02:00
# include "editor/gui/editor_file_dialog.h"
2019-12-24 08:17:23 +01:00
# include "editor/project_settings_editor.h"
2024-01-15 13:14:55 +01:00
# include "editor/themes/editor_scale.h"
2022-11-19 12:45:49 +01:00
# include "scene/gui/menu_button.h"
2023-07-11 22:29:09 +02:00
# include "scene/resources/image_texture.h"
2017-11-09 11:55:30 +01:00
2021-12-09 04:34:32 +01:00
static inline void setup_http_request ( HTTPRequest * request ) {
request - > set_use_threads ( EDITOR_DEF ( " asset_library/use_threads " , true ) ) ;
2022-03-06 21:39:19 +01:00
const String proxy_host = EDITOR_GET ( " network/http_proxy/host " ) ;
const int proxy_port = EDITOR_GET ( " network/http_proxy/port " ) ;
2021-12-09 04:34:32 +01:00
request - > set_http_proxy ( proxy_host , proxy_port ) ;
request - > set_https_proxy ( proxy_host , proxy_port ) ;
}
2019-06-12 12:24:08 +02:00
void EditorAssetLibraryItem : : 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 , const String & p_cost ) {
2016-03-04 15:09:45 +01:00
title - > set_text ( p_title ) ;
asset_id = p_asset_id ;
category - > set_text ( p_category ) ;
category_id = p_category_id ;
author - > set_text ( p_author ) ;
author_id = p_author_id ;
price - > set_text ( p_cost ) ;
}
2023-10-01 01:16:39 +02:00
// TODO: Refactor this method to use the TextServer.
void EditorAssetLibraryItem : : clamp_width ( int p_max_width ) {
int text_pixel_width = title - > get_button_font ( ) . ptr ( ) - > get_string_size ( title - > get_text ( ) ) . x * EDSCALE ;
String full_text = title - > get_text ( ) ;
title - > set_tooltip_text ( full_text ) ;
if ( text_pixel_width > p_max_width ) {
// Truncate title text to within the current column width.
int max_length = p_max_width / ( text_pixel_width / full_text . length ( ) ) ;
String truncated_text = full_text . left ( max_length - 3 ) + " ... " ;
title - > set_text ( truncated_text ) ;
}
}
2019-06-11 20:43:37 +02:00
void EditorAssetLibraryItem : : set_image ( int p_type , int p_index , const Ref < Texture2D > & p_image ) {
2016-06-08 14:25:47 +02:00
ERR_FAIL_COND ( p_type ! = EditorAssetLibrary : : IMAGE_QUEUE_ICON ) ;
2016-03-04 15:09:45 +01:00
ERR_FAIL_COND ( p_index ! = 0 ) ;
2022-11-07 09:09:13 +01:00
icon - > set_texture_normal ( p_image ) ;
2016-03-04 15:09:45 +01:00
}
void EditorAssetLibraryItem : : _notification ( int p_what ) {
2022-02-16 03:44:22 +01:00
switch ( p_what ) {
case NOTIFICATION_ENTER_TREE : {
2023-08-13 02:33:39 +02:00
icon - > set_texture_normal ( get_editor_theme_icon ( SNAME ( " ProjectIconLoading " ) ) ) ;
2022-02-16 03:44:22 +01:00
category - > add_theme_color_override ( " font_color " , Color ( 0.5 , 0.5 , 0.5 ) ) ;
author - > add_theme_color_override ( " font_color " , Color ( 0.5 , 0.5 , 0.5 ) ) ;
price - > add_theme_color_override ( " font_color " , Color ( 0.5 , 0.5 , 0.5 ) ) ;
2024-02-11 03:45:05 +01:00
if ( author - > get_default_cursor_shape ( ) = = CURSOR_ARROW ) {
// Disable visible feedback if author link isn't clickable.
author - > add_theme_color_override ( " font_pressed_color " , Color ( 0.5 , 0.5 , 0.5 ) ) ;
author - > add_theme_color_override ( " font_hover_color " , Color ( 0.5 , 0.5 , 0.5 ) ) ;
}
2022-02-16 03:44:22 +01:00
} break ;
2016-03-04 15:09:45 +01:00
}
}
void EditorAssetLibraryItem : : _asset_clicked ( ) {
2021-07-17 23:22:52 +02:00
emit_signal ( SNAME ( " asset_selected " ) , asset_id ) ;
2016-03-04 15:09:45 +01:00
}
void EditorAssetLibraryItem : : _category_clicked ( ) {
2021-07-17 23:22:52 +02:00
emit_signal ( SNAME ( " category_selected " ) , category_id ) ;
2016-03-04 15:09:45 +01:00
}
2020-05-14 14:29:06 +02:00
2016-03-04 15:09:45 +01:00
void EditorAssetLibraryItem : : _author_clicked ( ) {
2024-02-11 03:45:05 +01:00
emit_signal ( SNAME ( " author_selected " ) , author - > get_text ( ) ) ;
2016-03-04 15:09:45 +01:00
}
void EditorAssetLibraryItem : : _bind_methods ( ) {
2017-01-03 03:03:46 +01:00
ClassDB : : bind_method ( " set_image " , & EditorAssetLibraryItem : : set_image ) ;
2016-03-04 15:09:45 +01:00
ADD_SIGNAL ( MethodInfo ( " asset_selected " ) ) ;
ADD_SIGNAL ( MethodInfo ( " category_selected " ) ) ;
ADD_SIGNAL ( MethodInfo ( " author_selected " ) ) ;
}
2024-02-11 03:45:05 +01:00
EditorAssetLibraryItem : : EditorAssetLibraryItem ( bool p_clickable ) {
2016-03-04 15:09:45 +01:00
Ref < StyleBoxEmpty > border ;
2021-06-18 00:03:09 +02:00
border . instantiate ( ) ;
2023-01-19 17:14:09 +01:00
border - > set_content_margin_all ( 5 * EDSCALE ) ;
2022-02-08 10:14:58 +01:00
add_theme_style_override ( " panel " , border ) ;
2016-03-04 15:09:45 +01:00
HBoxContainer * hb = memnew ( HBoxContainer ) ;
2019-08-28 06:27:26 +02:00
// Add some spacing to visually separate the icon from the asset details.
2022-02-08 10:14:58 +01:00
hb - > add_theme_constant_override ( " separation " , 15 * EDSCALE ) ;
2016-03-04 15:09:45 +01:00
add_child ( hb ) ;
icon = memnew ( TextureButton ) ;
2019-06-12 01:13:07 +02:00
icon - > set_custom_minimum_size ( Size2 ( 64 , 64 ) * EDSCALE ) ;
2016-03-04 15:09:45 +01:00
hb - > add_child ( icon ) ;
VBoxContainer * vb = memnew ( VBoxContainer ) ;
hb - > add_child ( vb ) ;
2020-03-06 18:00:16 +01:00
vb - > set_h_size_flags ( Control : : SIZE_EXPAND_FILL ) ;
2016-03-04 15:09:45 +01:00
title = memnew ( LinkButton ) ;
title - > set_underline_mode ( LinkButton : : UNDERLINE_MODE_ON_HOVER ) ;
vb - > add_child ( title ) ;
category = memnew ( LinkButton ) ;
category - > set_underline_mode ( LinkButton : : UNDERLINE_MODE_ON_HOVER ) ;
vb - > add_child ( category ) ;
2024-02-11 03:45:05 +01:00
HBoxContainer * author_price_hbox = memnew ( HBoxContainer ) ;
author_price_hbox - > add_theme_constant_override ( " separation " , 5 * EDSCALE ) ;
vb - > add_child ( author_price_hbox ) ;
2016-03-04 15:09:45 +01:00
author = memnew ( LinkButton ) ;
2024-02-11 03:45:05 +01:00
author - > set_tooltip_text ( TTR ( " Author " ) ) ;
author_price_hbox - > add_child ( author ) ;
author_price_hbox - > add_child ( memnew ( HSeparator ) ) ;
if ( p_clickable ) {
author - > set_underline_mode ( LinkButton : : UNDERLINE_MODE_ON_HOVER ) ;
icon - > set_default_cursor_shape ( CURSOR_POINTING_HAND ) ;
icon - > connect ( " pressed " , callable_mp ( this , & EditorAssetLibraryItem : : _asset_clicked ) ) ;
title - > connect ( " pressed " , callable_mp ( this , & EditorAssetLibraryItem : : _asset_clicked ) ) ;
category - > connect ( " pressed " , callable_mp ( this , & EditorAssetLibraryItem : : _category_clicked ) ) ;
author - > connect ( " pressed " , callable_mp ( this , & EditorAssetLibraryItem : : _author_clicked ) ) ;
} else {
title - > set_mouse_filter ( MOUSE_FILTER_IGNORE ) ;
category - > set_mouse_filter ( MOUSE_FILTER_IGNORE ) ;
author - > set_underline_mode ( LinkButton : : UNDERLINE_MODE_NEVER ) ;
author - > set_default_cursor_shape ( CURSOR_ARROW ) ;
}
Ref < StyleBoxEmpty > label_margin ;
label_margin . instantiate ( ) ;
label_margin - > set_content_margin_all ( 0 ) ;
2016-03-04 15:09:45 +01:00
price = memnew ( Label ) ;
2024-02-11 03:45:05 +01:00
price - > add_theme_style_override ( " normal " , label_margin ) ;
price - > set_tooltip_text ( TTR ( " License " ) ) ;
price - > set_mouse_filter ( MOUSE_FILTER_PASS ) ;
author_price_hbox - > add_child ( price ) ;
2016-03-04 15:09:45 +01:00
2024-02-11 03:45:05 +01:00
set_custom_minimum_size ( Size2 ( 250 , 80 ) * EDSCALE ) ;
2020-03-06 18:00:16 +01:00
set_h_size_flags ( Control : : SIZE_EXPAND_FILL ) ;
2016-03-04 15:09:45 +01:00
}
//////////////////////////////////////////////////////////////////////////////
2019-06-11 20:43:37 +02:00
void EditorAssetLibraryItemDescription : : set_image ( int p_type , int p_index , const Ref < Texture2D > & p_image ) {
2016-03-04 15:09:45 +01:00
switch ( p_type ) {
2016-06-08 14:25:47 +02:00
case EditorAssetLibrary : : IMAGE_QUEUE_ICON : {
2016-03-04 15:09:45 +01:00
item - > call ( " set_image " , p_type , p_index , p_image ) ;
2016-03-12 14:44:12 +01:00
icon = p_image ;
2016-03-04 15:09:45 +01:00
} break ;
2016-06-08 14:25:47 +02:00
case EditorAssetLibrary : : IMAGE_QUEUE_THUMBNAIL : {
2016-03-04 15:09:45 +01:00
for ( int i = 0 ; i < preview_images . size ( ) ; i + + ) {
if ( preview_images [ i ] . id = = p_index ) {
2018-05-11 19:28:17 +02:00
if ( preview_images [ i ] . is_video ) {
2023-08-13 02:33:39 +02:00
Ref < Image > overlay = previews - > get_editor_theme_icon ( SNAME ( " PlayOverlay " ) ) - > get_image ( ) ;
2021-03-28 13:32:17 +02:00
Ref < Image > thumbnail = p_image - > get_image ( ) ;
2019-01-27 17:39:16 +01:00
thumbnail = thumbnail - > duplicate ( ) ;
2022-07-09 22:43:34 +02:00
Point2i overlay_pos = Point2i ( ( thumbnail - > get_width ( ) - overlay - > get_width ( ) ) / 2 , ( thumbnail - > get_height ( ) - overlay - > get_height ( ) ) / 2 ) ;
2018-05-11 19:28:17 +02:00
2019-03-05 21:02:56 +01:00
// Overlay and thumbnail need the same format for `blend_rect` to work.
thumbnail - > convert ( Image : : FORMAT_RGBA8 ) ;
2018-05-11 19:28:17 +02:00
thumbnail - > blend_rect ( overlay , overlay - > get_used_rect ( ) , overlay_pos ) ;
2022-05-04 01:49:20 +02:00
preview_images [ i ] . button - > set_icon ( ImageTexture : : create_from_image ( thumbnail ) ) ;
2018-05-11 19:28:17 +02:00
2019-07-18 19:48:47 +02:00
// Make it clearer that clicking it will open an external link
2020-03-06 18:00:16 +01:00
preview_images [ i ] . button - > set_default_cursor_shape ( Control : : CURSOR_POINTING_HAND ) ;
2018-05-11 19:28:17 +02:00
} else {
preview_images [ i ] . button - > set_icon ( p_image ) ;
}
2016-06-07 20:29:15 +02:00
break ;
2016-03-04 15:09:45 +01:00
}
}
} break ;
2016-06-08 14:25:47 +02:00
case EditorAssetLibrary : : IMAGE_QUEUE_SCREENSHOT : {
2016-03-04 15:09:45 +01:00
for ( int i = 0 ; i < preview_images . size ( ) ; i + + ) {
2016-06-07 20:29:15 +02:00
if ( preview_images [ i ] . id = = p_index ) {
2018-07-25 03:11:03 +02:00
preview_images . write [ i ] . image = p_image ;
2016-06-07 20:29:15 +02:00
if ( preview_images [ i ] . button - > is_pressed ( ) ) {
_preview_click ( p_index ) ;
}
break ;
2016-03-04 15:09:45 +01:00
}
}
} break ;
}
}
2019-08-29 07:37:44 +02:00
2017-08-04 21:41:31 +02:00
void EditorAssetLibraryItemDescription : : _notification ( int p_what ) {
switch ( p_what ) {
2022-08-29 11:04:31 +02:00
case NOTIFICATION_ENTER_TREE :
2022-01-16 08:59:02 +01:00
case NOTIFICATION_THEME_CHANGED : {
2022-02-08 10:14:58 +01:00
previews_bg - > add_theme_style_override ( " panel " , previews - > get_theme_stylebox ( SNAME ( " normal " ) , SNAME ( " TextEdit " ) ) ) ;
2017-08-04 21:41:31 +02:00
} break ;
}
}
2019-08-29 07:37:44 +02:00
2016-06-08 14:25:47 +02:00
void EditorAssetLibraryItemDescription : : _bind_methods ( ) {
2017-02-13 12:47:24 +01:00
ClassDB : : bind_method ( D_METHOD ( " set_image " ) , & EditorAssetLibraryItemDescription : : set_image ) ;
2016-03-12 14:44:12 +01:00
}
2016-06-08 14:25:47 +02:00
void EditorAssetLibraryItemDescription : : _link_click ( const String & p_url ) {
2016-03-12 14:44:12 +01:00
ERR_FAIL_COND ( ! p_url . begins_with ( " http " ) ) ;
OS : : get_singleton ( ) - > shell_open ( p_url ) ;
2016-03-04 15:09:45 +01:00
}
2016-06-08 14:25:47 +02:00
void EditorAssetLibraryItemDescription : : _preview_click ( int p_id ) {
2016-06-07 20:29:15 +02:00
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 ) ;
2020-03-06 18:00:16 +01:00
child_controls_changed ( ) ;
2016-06-07 20:29:15 +02:00
}
} else {
_link_click ( preview_images [ i ] . video_link ) ;
}
} else {
preview_images [ i ] . button - > set_pressed ( false ) ;
}
}
}
2019-06-12 12:24:08 +02:00
void EditorAssetLibraryItemDescription : : 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 , 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 , const String & p_sha256_hash ) {
2016-03-12 14:44:12 +01:00
asset_id = p_asset_id ;
title = p_title ;
download_url = p_download_url ;
2016-06-21 14:38:29 +02:00
sha256 = p_sha256_hash ;
2019-06-12 12:24:08 +02:00
item - > configure ( p_title , p_asset_id , p_category , p_category_id , p_author , p_author_id , p_cost ) ;
2016-03-12 14:44:12 +01:00
description - > clear ( ) ;
2017-04-20 14:42:35 +02:00
description - > add_text ( TTR ( " Version: " ) + " " + p_version_string + " \n " ) ;
description - > add_text ( TTR ( " Contents: " ) + " " ) ;
2016-03-12 14:44:12 +01:00
description - > push_meta ( p_browse_url ) ;
2017-04-20 14:42:35 +02:00
description - > add_text ( TTR ( " View Files " ) ) ;
2016-03-12 14:44:12 +01:00
description - > pop ( ) ;
2017-04-20 14:42:35 +02:00
description - > add_text ( " \n " + TTR ( " Description: " ) + " \n \n " ) ;
2020-05-29 16:25:12 +02:00
description - > append_text ( p_description ) ;
2021-12-11 20:43:05 +01:00
description - > set_selection_enabled ( true ) ;
2023-02-28 14:19:48 +01:00
description - > set_context_menu_enabled ( true ) ;
2016-03-04 15:09:45 +01:00
set_title ( p_title ) ;
}
2016-06-08 14:25:47 +02:00
void EditorAssetLibraryItemDescription : : add_preview ( int p_id , bool p_video , const String & p_url ) {
2024-02-11 03:45:05 +01:00
if ( preview_images . is_empty ( ) ) {
previews_vbox - > show ( ) ;
}
2022-09-29 11:53:28 +02:00
Preview new_preview ;
new_preview . id = p_id ;
new_preview . video_link = p_url ;
new_preview . is_video = p_video ;
new_preview . button = memnew ( Button ) ;
2023-08-13 02:33:39 +02:00
new_preview . button - > set_icon ( previews - > get_editor_theme_icon ( SNAME ( " ThumbnailWait " ) ) ) ;
2022-09-29 11:53:28 +02:00
new_preview . button - > set_toggle_mode ( true ) ;
new_preview . button - > connect ( " pressed " , callable_mp ( this , & EditorAssetLibraryItemDescription : : _preview_click ) . bind ( p_id ) ) ;
preview_hb - > add_child ( new_preview . button ) ;
2016-06-07 20:29:15 +02:00
if ( ! p_video ) {
2023-08-13 02:33:39 +02:00
new_preview . image = previews - > get_editor_theme_icon ( SNAME ( " ThumbnailWait " ) ) ;
2016-06-07 20:29:15 +02:00
}
2022-09-29 11:53:28 +02:00
preview_images . push_back ( new_preview ) ;
2019-08-15 13:43:00 +02:00
if ( preview_images . size ( ) = = 1 & & ! p_video ) {
2016-06-07 20:29:15 +02:00
_preview_click ( p_id ) ;
}
2016-03-04 15:09:45 +01:00
}
2016-06-08 14:25:47 +02:00
EditorAssetLibraryItemDescription : : EditorAssetLibraryItemDescription ( ) {
2016-03-04 15:09:45 +01:00
HBoxContainer * hbox = memnew ( HBoxContainer ) ;
2019-08-28 06:27:26 +02:00
add_child ( hbox ) ;
2016-03-04 15:09:45 +01:00
VBoxContainer * desc_vbox = memnew ( VBoxContainer ) ;
hbox - > add_child ( desc_vbox ) ;
2022-02-08 10:14:58 +01:00
hbox - > add_theme_constant_override ( " separation " , 15 * EDSCALE ) ;
2016-03-04 15:09:45 +01:00
item = memnew ( EditorAssetLibraryItem ) ;
desc_vbox - > add_child ( item ) ;
2024-02-11 03:45:05 +01:00
desc_vbox - > set_custom_minimum_size ( Size2 ( 440 * EDSCALE , 440 * EDSCALE ) ) ;
2016-03-04 15:09:45 +01:00
description = memnew ( RichTextLabel ) ;
2019-08-29 07:37:44 +02:00
desc_vbox - > add_child ( description ) ;
2020-03-06 18:00:16 +01:00
description - > set_v_size_flags ( Control : : SIZE_EXPAND_FILL ) ;
2020-02-21 18:28:45 +01:00
description - > connect ( " meta_clicked " , callable_mp ( this , & EditorAssetLibraryItemDescription : : _link_click ) ) ;
2022-02-08 10:14:58 +01:00
description - > add_theme_constant_override ( " line_separation " , Math : : round ( 5 * EDSCALE ) ) ;
2016-03-04 15:09:45 +01:00
2024-02-11 03:45:05 +01:00
previews_vbox = memnew ( VBoxContainer ) ;
previews_vbox - > hide ( ) ; // Will be shown if we add any previews later.
2019-04-23 21:53:15 +02:00
hbox - > add_child ( previews_vbox ) ;
2022-02-08 10:14:58 +01:00
previews_vbox - > add_theme_constant_override ( " separation " , 15 * EDSCALE ) ;
2020-03-06 18:00:16 +01:00
previews_vbox - > set_v_size_flags ( Control : : SIZE_EXPAND_FILL ) ;
2022-07-01 16:17:40 +02:00
previews_vbox - > set_h_size_flags ( Control : : SIZE_EXPAND_FILL ) ;
2019-04-23 21:53:15 +02:00
2017-01-12 22:27:27 +01:00
preview = memnew ( TextureRect ) ;
2019-04-23 21:53:15 +02:00
previews_vbox - > add_child ( preview ) ;
2022-02-25 01:19:24 +01:00
preview - > set_expand_mode ( TextureRect : : EXPAND_IGNORE_SIZE ) ;
2019-08-28 06:27:26 +02:00
preview - > set_stretch_mode ( TextureRect : : STRETCH_KEEP_ASPECT_CENTERED ) ;
preview - > set_custom_minimum_size ( Size2 ( 640 * EDSCALE , 345 * EDSCALE ) ) ;
2022-07-01 16:17:40 +02:00
preview - > set_v_size_flags ( Control : : SIZE_EXPAND_FILL ) ;
preview - > set_h_size_flags ( Control : : SIZE_EXPAND_FILL ) ;
2016-03-04 15:09:45 +01:00
2017-08-04 21:41:31 +02:00
previews_bg = memnew ( PanelContainer ) ;
2019-04-23 21:53:15 +02:00
previews_vbox - > add_child ( previews_bg ) ;
previews_bg - > set_custom_minimum_size ( Size2 ( 640 * EDSCALE , 101 * EDSCALE ) ) ;
2016-03-04 15:09:45 +01:00
previews = memnew ( ScrollContainer ) ;
previews_bg - > add_child ( previews ) ;
2021-12-07 17:15:18 +01:00
previews - > set_vertical_scroll_mode ( ScrollContainer : : SCROLL_MODE_DISABLED ) ;
2016-03-04 15:09:45 +01:00
preview_hb = memnew ( HBoxContainer ) ;
2020-03-06 18:00:16 +01:00
preview_hb - > set_v_size_flags ( Control : : SIZE_EXPAND_FILL ) ;
2016-03-04 15:09:45 +01:00
previews - > add_child ( preview_hb ) ;
2022-07-08 02:31:19 +02:00
set_ok_button_text ( TTR ( " Download " ) ) ;
set_cancel_button_text ( TTR ( " Close " ) ) ;
2016-03-04 15:09:45 +01:00
}
2020-05-14 14:29:06 +02:00
2016-03-12 14:44:12 +01:00
///////////////////////////////////////////////////////////////////////////////////
2020-02-17 22:06:54 +01:00
void EditorAssetLibraryItemDownload : : _http_download_completed ( int p_status , int p_code , const PackedStringArray & headers , const PackedByteArray & p_data ) {
2016-03-12 14:44:12 +01:00
String error_text ;
switch ( p_status ) {
2019-08-08 09:06:26 +02:00
case HTTPRequest : : RESULT_CHUNKED_BODY_SIZE_MISMATCH :
2016-03-12 14:44:12 +01:00
case HTTPRequest : : RESULT_CONNECTION_ERROR :
2019-08-08 09:06:26 +02:00
case HTTPRequest : : RESULT_BODY_SIZE_LIMIT_EXCEEDED : {
2017-04-20 14:42:35 +02:00
error_text = TTR ( " Connection error, please try again. " ) ;
status - > set_text ( TTR ( " Can't connect. " ) ) ;
2016-03-12 14:44:12 +01:00
} break ;
2019-08-08 09:06:26 +02:00
case HTTPRequest : : RESULT_CANT_CONNECT :
2022-09-07 08:25:47 +02:00
case HTTPRequest : : RESULT_TLS_HANDSHAKE_ERROR : {
2017-04-20 14:42:35 +02:00
error_text = TTR ( " Can't connect to host: " ) + " " + host ;
status - > set_text ( TTR ( " Can't connect. " ) ) ;
2016-03-12 14:44:12 +01:00
} break ;
case HTTPRequest : : RESULT_NO_RESPONSE : {
2017-04-20 14:42:35 +02:00
error_text = TTR ( " No response from host: " ) + " " + host ;
status - > set_text ( TTR ( " No response. " ) ) ;
2016-03-12 14:44:12 +01:00
} break ;
2019-08-08 09:06:26 +02:00
case HTTPRequest : : RESULT_CANT_RESOLVE : {
error_text = TTR ( " Can't resolve hostname: " ) + " " + host ;
status - > set_text ( TTR ( " Can't resolve. " ) ) ;
} break ;
2016-03-12 14:44:12 +01:00
case HTTPRequest : : RESULT_REQUEST_FAILED : {
2017-04-20 14:42:35 +02:00
error_text = TTR ( " Request failed, return code: " ) + " " + itos ( p_code ) ;
2019-08-09 13:45:30 +02:00
status - > set_text ( TTR ( " Request failed. " ) ) ;
2016-03-12 14:44:12 +01:00
} break ;
2019-08-08 09:06:26 +02:00
case HTTPRequest : : RESULT_DOWNLOAD_FILE_CANT_OPEN :
case HTTPRequest : : RESULT_DOWNLOAD_FILE_WRITE_ERROR : {
2019-08-09 13:45:30 +02:00
error_text = TTR ( " Cannot save response to: " ) + " " + download - > get_download_file ( ) ;
2019-08-08 09:06:26 +02:00
status - > set_text ( TTR ( " Write error. " ) ) ;
} break ;
2016-03-12 14:44:12 +01:00
case HTTPRequest : : RESULT_REDIRECT_LIMIT_REACHED : {
2017-04-20 14:42:35 +02:00
error_text = TTR ( " Request failed, too many redirects " ) ;
2019-08-09 13:45:30 +02:00
status - > set_text ( TTR ( " Redirect loop. " ) ) ;
2016-03-12 14:44:12 +01:00
} break ;
2019-08-08 09:06:26 +02:00
case HTTPRequest : : RESULT_TIMEOUT : {
error_text = TTR ( " Request failed, timeout " ) ;
status - > set_text ( TTR ( " Timeout. " ) ) ;
} break ;
2016-03-12 14:44:12 +01:00
default : {
if ( p_code ! = 200 ) {
2017-04-20 14:42:35 +02:00
error_text = TTR ( " Request failed, return code: " ) + " " + itos ( p_code ) ;
status - > set_text ( TTR ( " Failed: " ) + " " + itos ( p_code ) ) ;
2021-12-09 10:42:46 +01:00
} else if ( ! sha256 . is_empty ( ) ) {
2016-06-21 14:38:29 +02:00
String download_sha256 = FileAccess : : get_sha256 ( download - > get_download_file ( ) ) ;
if ( sha256 ! = download_sha256 ) {
2017-04-20 14:42:35 +02:00
error_text = TTR ( " Bad download hash, assuming file has been tampered with. " ) + " \n " ;
error_text + = TTR ( " Expected: " ) + " " + sha256 + " \n " + TTR ( " Got: " ) + " " + download_sha256 ;
2021-02-17 02:00:22 +01:00
status - > set_text ( TTR ( " Failed SHA-256 hash check " ) ) ;
2016-06-21 14:38:29 +02:00
}
2016-03-12 14:44:12 +01:00
}
} break ;
}
2024-02-08 01:16:52 +01:00
// Make the progress bar invisible but don't reflow other Controls around it.
progress - > set_modulate ( Color ( 0 , 0 , 0 , 0 ) ) ;
progress - > set_indeterminate ( false ) ;
2021-12-09 10:42:46 +01:00
if ( ! error_text . is_empty ( ) ) {
2017-04-20 14:42:35 +02:00
download_error - > set_text ( TTR ( " Asset Download Error: " ) + " \n " + error_text ) ;
2020-03-06 18:00:16 +01:00
download_error - > popup_centered ( ) ;
2021-02-17 02:00:22 +01:00
// Let the user retry the download.
2022-01-19 02:37:38 +01:00
retry_button - > show ( ) ;
2016-03-12 14:44:12 +01:00
return ;
}
2022-01-19 02:37:38 +01:00
install_button - > set_disabled ( false ) ;
2022-01-19 17:16:17 +01:00
status - > set_text ( TTR ( " Ready to install! " ) ) ;
2016-03-12 14:44:12 +01:00
set_process ( false ) ;
2021-04-06 17:37:55 +02:00
// Automatically prompt for installation once the download is completed.
2022-01-19 02:37:38 +01:00
install ( ) ;
2016-03-12 14:44:12 +01:00
}
2019-06-11 20:43:37 +02:00
void EditorAssetLibraryItemDownload : : configure ( const String & p_title , int p_asset_id , const Ref < Texture2D > & p_preview , const String & p_download_url , const String & p_sha256_hash ) {
2016-03-12 14:44:12 +01:00
title - > set_text ( p_title ) ;
icon - > set_texture ( p_preview ) ;
asset_id = p_asset_id ;
2020-05-14 16:41:43 +02:00
if ( ! p_preview . is_valid ( ) ) {
2023-08-13 02:33:39 +02:00
icon - > set_texture ( get_editor_theme_icon ( SNAME ( " FileBrokenBigThumb " ) ) ) ;
2020-05-14 16:41:43 +02:00
}
2016-03-12 14:44:12 +01:00
host = p_download_url ;
2016-06-21 14:38:29 +02:00
sha256 = p_sha256_hash ;
2016-06-07 20:29:15 +02:00
_make_request ( ) ;
2016-03-12 14:44:12 +01:00
}
2016-06-08 14:25:47 +02:00
void EditorAssetLibraryItemDownload : : _notification ( int p_what ) {
2019-07-17 07:26:53 +02:00
switch ( p_what ) {
2022-01-16 08:59:02 +01:00
case NOTIFICATION_THEME_CHANGED : {
2022-02-08 10:14:58 +01:00
panel - > add_theme_style_override ( " panel " , get_theme_stylebox ( SNAME ( " panel " ) , SNAME ( " AssetLib " ) ) ) ;
status - > add_theme_color_override ( " font_color " , get_theme_color ( SNAME ( " status_color " ) , SNAME ( " AssetLib " ) ) ) ;
2022-11-07 09:09:13 +01:00
dismiss_button - > set_texture_normal ( get_theme_icon ( SNAME ( " dismiss " ) , SNAME ( " AssetLib " ) ) ) ;
2019-07-17 07:26:53 +02:00
} break ;
2022-02-16 03:44:22 +01:00
2019-07-17 07:26:53 +02:00
case NOTIFICATION_PROCESS : {
// Make the progress bar visible again when retrying the download.
progress - > set_modulate ( Color ( 1 , 1 , 1 , 1 ) ) ;
2016-07-24 19:37:26 +02:00
2019-07-17 07:26:53 +02:00
if ( download - > get_downloaded_bytes ( ) > 0 ) {
progress - > set_max ( download - > get_body_size ( ) ) ;
progress - > set_value ( download - > get_downloaded_bytes ( ) ) ;
2018-08-20 20:21:56 +02:00
}
2016-07-24 19:37:26 +02:00
2019-07-17 07:26:53 +02:00
int cstatus = download - > get_http_client_status ( ) ;
if ( cstatus = = HTTPClient : : STATUS_BODY ) {
if ( download - > get_body_size ( ) > 0 ) {
2024-02-08 01:16:52 +01:00
progress - > set_indeterminate ( false ) ;
2019-07-17 07:26:53 +02:00
status - > set_text ( vformat (
TTR ( " Downloading (%s / %s)... " ) ,
String : : humanize_size ( download - > get_downloaded_bytes ( ) ) ,
String : : humanize_size ( download - > get_body_size ( ) ) ) ) ;
} else {
2024-02-08 01:16:52 +01:00
progress - > set_indeterminate ( true ) ;
2020-01-18 12:51:20 +01:00
status - > set_text ( vformat (
TTR ( " Downloading... " ) + " (%s) " ,
String : : humanize_size ( download - > get_downloaded_bytes ( ) ) ) ) ;
2019-07-17 07:26:53 +02:00
}
}
2016-03-12 14:44:12 +01:00
2019-07-17 07:26:53 +02:00
if ( cstatus ! = prev_status ) {
switch ( cstatus ) {
case HTTPClient : : STATUS_RESOLVING : {
status - > set_text ( TTR ( " Resolving... " ) ) ;
progress - > set_max ( 1 ) ;
progress - > set_value ( 0 ) ;
} break ;
case HTTPClient : : STATUS_CONNECTING : {
status - > set_text ( TTR ( " Connecting... " ) ) ;
progress - > set_max ( 1 ) ;
progress - > set_value ( 0 ) ;
} break ;
case HTTPClient : : STATUS_REQUESTING : {
status - > set_text ( TTR ( " Requesting... " ) ) ;
progress - > set_max ( 1 ) ;
progress - > set_value ( 0 ) ;
} break ;
default : {
}
2019-04-09 17:08:36 +02:00
}
2019-07-17 07:26:53 +02:00
prev_status = cstatus ;
2016-03-12 14:44:12 +01:00
}
2019-07-17 07:26:53 +02:00
} break ;
2016-03-12 14:44:12 +01:00
}
}
2020-05-14 14:29:06 +02:00
2016-06-08 14:25:47 +02:00
void EditorAssetLibraryItemDownload : : _close ( ) {
2019-08-09 13:45:30 +02:00
// Clean up downloaded file.
DirAccess : : remove_file_or_error ( download - > get_download_file ( ) ) ;
2022-10-24 23:07:02 +02:00
queue_free ( ) ;
2016-03-12 14:44:12 +01:00
}
2022-01-19 17:16:17 +01:00
bool EditorAssetLibraryItemDownload : : can_install ( ) const {
return ! install_button - > is_disabled ( ) ;
}
2022-01-19 02:37:38 +01:00
void EditorAssetLibraryItemDownload : : install ( ) {
2016-03-12 14:44:12 +01:00
String file = download - > get_download_file ( ) ;
2016-07-12 02:34:02 +02:00
if ( external_install ) {
2021-07-17 23:22:52 +02:00
emit_signal ( SNAME ( " install_asset " ) , file , title - > get_text ( ) ) ;
2016-07-12 02:34:02 +02:00
return ;
}
2021-04-06 17:37:55 +02:00
asset_installer - > set_asset_name ( title - > get_text ( ) ) ;
2023-09-08 20:01:26 +02:00
asset_installer - > open_asset ( file , true ) ;
2016-03-12 14:44:12 +01:00
}
2016-06-08 14:25:47 +02:00
void EditorAssetLibraryItemDownload : : _make_request ( ) {
2021-02-17 02:00:22 +01:00
// Hide the Retry button if we've just pressed it.
2022-01-19 02:37:38 +01:00
retry_button - > hide ( ) ;
2021-02-17 02:00:22 +01:00
2016-06-07 20:29:15 +02:00
download - > cancel_request ( ) ;
2022-08-30 02:34:01 +02:00
download - > set_download_file ( EditorPaths : : get_singleton ( ) - > get_cache_dir ( ) . path_join ( " tmp_asset_ " + itos ( asset_id ) ) + " .zip " ) ;
2016-07-24 21:09:43 +02:00
2016-06-07 20:29:15 +02:00
Error err = download - > request ( host ) ;
if ( err ! = OK ) {
2017-04-20 14:42:35 +02:00
status - > set_text ( TTR ( " Error making request " ) ) ;
2016-06-07 20:29:15 +02:00
} else {
2024-02-08 01:16:52 +01:00
progress - > set_indeterminate ( true ) ;
2016-06-07 20:29:15 +02:00
set_process ( true ) ;
}
}
2016-06-08 14:25:47 +02:00
void EditorAssetLibraryItemDownload : : _bind_methods ( ) {
2016-07-12 02:34:02 +02:00
ADD_SIGNAL ( MethodInfo ( " install_asset " , PropertyInfo ( Variant : : STRING , " zip_path " ) , PropertyInfo ( Variant : : STRING , " name " ) ) ) ;
2016-03-12 14:44:12 +01:00
}
2016-06-08 14:25:47 +02:00
EditorAssetLibraryItemDownload : : EditorAssetLibraryItemDownload ( ) {
2022-01-16 17:40:14 +01:00
panel = memnew ( PanelContainer ) ;
add_child ( panel ) ;
2016-03-12 14:44:12 +01:00
HBoxContainer * hb = memnew ( HBoxContainer ) ;
2022-01-16 17:40:14 +01:00
panel - > add_child ( hb ) ;
2017-01-12 22:27:27 +01:00
icon = memnew ( TextureRect ) ;
2022-01-19 02:37:38 +01:00
icon - > set_stretch_mode ( TextureRect : : STRETCH_KEEP_ASPECT_CENTERED ) ;
icon - > set_v_size_flags ( 0 ) ;
2016-03-12 14:44:12 +01:00
hb - > add_child ( icon ) ;
VBoxContainer * vb = memnew ( VBoxContainer ) ;
hb - > add_child ( vb ) ;
2020-03-06 18:00:16 +01:00
vb - > set_h_size_flags ( Control : : SIZE_EXPAND_FILL ) ;
2016-03-12 14:44:12 +01:00
HBoxContainer * title_hb = memnew ( HBoxContainer ) ;
vb - > add_child ( title_hb ) ;
title = memnew ( Label ) ;
title_hb - > add_child ( title ) ;
2020-03-06 18:00:16 +01:00
title - > set_h_size_flags ( Control : : SIZE_EXPAND_FILL ) ;
2016-03-12 14:44:12 +01:00
2022-01-19 02:37:38 +01:00
dismiss_button = memnew ( TextureButton ) ;
dismiss_button - > connect ( " pressed " , callable_mp ( this , & EditorAssetLibraryItemDownload : : _close ) ) ;
title_hb - > add_child ( dismiss_button ) ;
2016-03-12 14:44:12 +01:00
title - > set_clip_text ( true ) ;
vb - > add_spacer ( ) ;
2017-04-20 14:42:35 +02:00
status = memnew ( Label ( TTR ( " Idle " ) ) ) ;
2016-03-12 14:44:12 +01:00
vb - > add_child ( status ) ;
progress = memnew ( ProgressBar ) ;
2024-02-08 01:16:52 +01:00
progress - > set_editor_preview_indeterminate ( true ) ;
2016-03-12 14:44:12 +01:00
vb - > add_child ( progress ) ;
HBoxContainer * hb2 = memnew ( HBoxContainer ) ;
vb - > add_child ( hb2 ) ;
hb2 - > add_spacer ( ) ;
2022-01-19 02:37:38 +01:00
install_button = memnew ( Button ) ;
install_button - > set_text ( TTR ( " Install... " ) ) ;
install_button - > set_disabled ( true ) ;
install_button - > connect ( " pressed " , callable_mp ( this , & EditorAssetLibraryItemDownload : : install ) ) ;
2016-03-12 14:44:12 +01:00
2022-01-19 02:37:38 +01:00
retry_button = memnew ( Button ) ;
retry_button - > set_text ( TTR ( " Retry " ) ) ;
retry_button - > connect ( " pressed " , callable_mp ( this , & EditorAssetLibraryItemDownload : : _make_request ) ) ;
2021-02-17 02:00:22 +01:00
// Only show the Retry button in case of a failure.
2022-01-19 02:37:38 +01:00
retry_button - > hide ( ) ;
2016-06-07 20:29:15 +02:00
2022-01-19 02:37:38 +01:00
hb2 - > add_child ( retry_button ) ;
hb2 - > add_child ( install_button ) ;
2019-06-12 01:13:07 +02:00
set_custom_minimum_size ( Size2 ( 310 , 0 ) * EDSCALE ) ;
2016-03-12 14:44:12 +01:00
download = memnew ( HTTPRequest ) ;
2022-01-16 17:40:14 +01:00
panel - > add_child ( download ) ;
2020-02-21 18:28:45 +01:00
download - > connect ( " request_completed " , callable_mp ( this , & EditorAssetLibraryItemDownload : : _http_download_completed ) ) ;
2021-12-09 04:34:32 +01:00
setup_http_request ( download ) ;
2016-03-12 14:44:12 +01:00
download_error = memnew ( AcceptDialog ) ;
2022-01-16 17:40:14 +01:00
panel - > add_child ( download_error ) ;
2017-04-20 14:42:35 +02:00
download_error - > set_title ( TTR ( " Download Error " ) ) ;
2016-03-12 14:44:12 +01:00
asset_installer = memnew ( EditorAssetInstaller ) ;
2022-01-16 17:40:14 +01:00
panel - > add_child ( asset_installer ) ;
2020-02-21 18:28:45 +01:00
asset_installer - > connect ( " confirmed " , callable_mp ( this , & EditorAssetLibraryItemDownload : : _close ) ) ;
2016-03-12 14:44:12 +01:00
prev_status = - 1 ;
2016-07-12 02:34:02 +02:00
external_install = false ;
2016-03-12 14:44:12 +01:00
}
2016-03-04 15:09:45 +01:00
////////////////////////////////////////////////////////////////////////////////
2016-06-08 14:25:47 +02:00
void EditorAssetLibrary : : _notification ( int p_what ) {
2017-08-04 21:41:31 +02:00
switch ( p_what ) {
case NOTIFICATION_READY : {
2022-03-16 00:40:46 +01:00
add_theme_style_override ( " panel " , get_theme_stylebox ( SNAME ( " bg " ) , SNAME ( " AssetLib " ) ) ) ;
2022-04-10 20:52:55 +02:00
error_label - > move_to_front ( ) ;
2022-01-16 08:59:02 +01:00
} break ;
2022-02-16 03:44:22 +01:00
2022-08-29 11:04:31 +02:00
case NOTIFICATION_ENTER_TREE :
2022-01-16 08:59:02 +01:00
case NOTIFICATION_THEME_CHANGED : {
2023-08-13 02:33:39 +02:00
error_tr - > set_texture ( get_editor_theme_icon ( SNAME ( " Error " ) ) ) ;
filter - > set_right_icon ( get_editor_theme_icon ( SNAME ( " Search " ) ) ) ;
2022-09-06 19:09:32 +02:00
library_scroll_bg - > add_theme_style_override ( " panel " , get_theme_stylebox ( SNAME ( " panel " ) , SNAME ( " Tree " ) ) ) ;
downloads_scroll - > add_theme_style_override ( " panel " , get_theme_stylebox ( SNAME ( " panel " ) , SNAME ( " Tree " ) ) ) ;
2023-08-13 02:33:39 +02:00
error_label - > add_theme_color_override ( " color " , get_theme_color ( SNAME ( " error_color " ) , EditorStringName ( Editor ) ) ) ;
2017-08-04 21:41:31 +02:00
} break ;
2022-02-16 03:44:22 +01:00
2017-08-04 21:41:31 +02:00
case NOTIFICATION_VISIBILITY_CHANGED : {
2021-04-04 22:47:44 +02:00
if ( is_visible ( ) ) {
2022-09-06 07:13:03 +02:00
# ifndef ANDROID_ENABLED
2021-04-04 22:47:44 +02:00
// Focus the search box automatically when switching to the Templates tab (in the Project Manager)
// or switching to the AssetLib tab (in the editor).
// The Project Manager's project filter box is automatically focused in the project manager code.
filter - > grab_focus ( ) ;
2022-09-06 07:13:03 +02:00
# endif
2021-04-04 22:47:44 +02:00
if ( initial_loading ) {
_repository_changed ( 0 ) ; // Update when shown for the first time.
}
2017-08-04 21:41:31 +02:00
}
} break ;
2022-02-16 03:44:22 +01:00
2017-08-04 21:41:31 +02:00
case NOTIFICATION_PROCESS : {
HTTPClient : : Status s = request - > get_http_client_status ( ) ;
2019-08-24 03:04:59 +02:00
const bool loading = s ! = HTTPClient : : STATUS_DISCONNECTED ;
2016-03-05 16:24:12 +01:00
2019-08-24 03:04:59 +02:00
if ( loading ) {
library_scroll - > set_modulate ( Color ( 1 , 1 , 1 , 0.5 ) ) ;
} else {
library_scroll - > set_modulate ( Color ( 1 , 1 , 1 , 1 ) ) ;
2017-08-04 21:41:31 +02:00
}
2019-08-24 03:04:59 +02:00
const bool no_downloads = downloads_hb - > get_child_count ( ) = = 0 ;
2017-08-04 21:41:31 +02:00
if ( no_downloads = = downloads_scroll - > is_visible ( ) ) {
downloads_scroll - > set_visible ( ! no_downloads ) ;
}
} break ;
2022-02-16 03:44:22 +01:00
2022-07-02 22:15:42 +02:00
case NOTIFICATION_RESIZED : {
_update_asset_items_columns ( ) ;
} break ;
2021-03-13 22:55:59 +01:00
case EditorSettings : : NOTIFICATION_EDITOR_SETTINGS_CHANGED : {
2022-11-23 00:14:08 +01:00
if ( ! EditorSettings : : get_singleton ( ) - > check_changed_settings_in_group ( " asset_library " ) & &
2024-03-05 21:27:08 +01:00
! EditorSettings : : get_singleton ( ) - > check_changed_settings_in_group ( " network " ) ) {
2022-11-23 00:14:08 +01:00
break ;
}
2021-03-13 22:55:59 +01:00
_update_repository_options ( ) ;
2022-01-21 08:42:05 +01:00
setup_http_request ( request ) ;
2024-01-30 17:35:46 +01:00
const bool loading_blocked_new = ( ( int ) EDITOR_GET ( " network/connection/network_mode " ) = = EditorSettings : : NETWORK_OFFLINE ) ;
if ( loading_blocked_new ! = loading_blocked ) {
loading_blocked = loading_blocked_new ;
if ( ! loading_blocked & & is_visible ( ) ) {
_request_current_config ( ) ; // Reload config now that the network is available.
}
}
2021-03-13 22:55:59 +01:00
} break ;
}
}
void EditorAssetLibrary : : _update_repository_options ( ) {
Dictionary default_urls ;
2021-07-23 12:53:19 +02:00
default_urls [ " godotengine.org (Official) " ] = " https://godotengine.org/asset-library/api " ;
2021-03-13 22:55:59 +01:00
Dictionary available_urls = _EDITOR_DEF ( " asset_library/available_urls " , default_urls , true ) ;
repository - > clear ( ) ;
Array keys = available_urls . keys ( ) ;
2021-07-16 05:45:57 +02:00
for ( int i = 0 ; i < keys . size ( ) ; i + + ) {
2021-03-13 22:55:59 +01:00
String key = keys [ i ] ;
repository - > add_item ( key ) ;
repository - > set_item_metadata ( i , available_urls [ key ] ) ;
2016-03-04 15:09:45 +01:00
}
}
2022-01-11 14:59:52 +01:00
void EditorAssetLibrary : : shortcut_input ( const Ref < InputEvent > & p_event ) {
2021-04-05 08:52:21 +02:00
ERR_FAIL_COND ( p_event . is_null ( ) ) ;
2019-11-22 00:39:39 +01:00
const Ref < InputEventKey > key = p_event ;
if ( key . is_valid ( ) & & key - > is_pressed ( ) ) {
2022-09-10 21:40:45 +02:00
if ( key - > is_match ( InputEventKey : : create_reference ( KeyModifierMask : : CMD_OR_CTRL | Key : : F ) ) & & is_visible_in_tree ( ) ) {
2019-11-22 00:39:39 +01:00
filter - > grab_focus ( ) ;
filter - > select_all ( ) ;
accept_event ( ) ;
}
}
}
2016-06-08 14:25:47 +02:00
void EditorAssetLibrary : : _install_asset ( ) {
2023-09-09 17:24:40 +02:00
ERR_FAIL_NULL ( description ) ;
2016-03-12 14:44:12 +01:00
2022-01-19 02:37:38 +01:00
EditorAssetLibraryItemDownload * d = _get_asset_in_progress ( description - > get_asset_id ( ) ) ;
if ( d ) {
d - > install ( ) ;
return ;
2016-03-12 14:44:12 +01:00
}
2016-06-08 14:25:47 +02:00
EditorAssetLibraryItemDownload * download = memnew ( EditorAssetLibraryItemDownload ) ;
2016-03-12 14:44:12 +01:00
downloads_hb - > add_child ( download ) ;
2016-06-21 14:38:29 +02:00
download - > configure ( description - > get_title ( ) , description - > get_asset_id ( ) , description - > get_preview_icon ( ) , description - > get_download_url ( ) , description - > get_sha256 ( ) ) ;
2016-03-12 14:44:12 +01:00
2016-07-12 02:34:02 +02:00
if ( templates_only ) {
download - > set_external_install ( true ) ;
2020-02-21 18:28:45 +01:00
download - > connect ( " install_asset " , callable_mp ( this , & EditorAssetLibrary : : _install_external_asset ) ) ;
2016-07-12 02:34:02 +02:00
}
2016-03-12 14:44:12 +01:00
}
2016-06-08 14:25:47 +02:00
const char * EditorAssetLibrary : : sort_key [ SORT_MAX ] = {
2019-08-24 04:53:14 +02:00
" updated " ,
" updated " ,
2016-03-04 15:09:45 +01:00
" name " ,
2019-08-24 04:53:14 +02:00
" name " ,
" cost " ,
2016-03-04 15:09:45 +01:00
" cost " ,
} ;
2016-06-08 14:25:47 +02:00
const char * EditorAssetLibrary : : sort_text [ SORT_MAX ] = {
2019-12-13 09:07:45 +01:00
TTRC ( " Recently Updated " ) ,
TTRC ( " Least Recently Updated " ) ,
TTRC ( " Name (A-Z) " ) ,
TTRC ( " Name (Z-A) " ) ,
TTRC ( " License (A-Z) " ) , // "cost" stores the SPDX license name in the Godot Asset Library.
TTRC ( " License (Z-A) " ) , // "cost" stores the SPDX license name in the Godot Asset Library.
2016-03-04 15:09:45 +01:00
} ;
2016-06-21 15:29:49 +02:00
const char * EditorAssetLibrary : : support_key [ SUPPORT_MAX ] = {
" official " ,
" community " ,
2019-08-24 04:53:14 +02:00
" testing " ,
2016-06-21 15:29:49 +02:00
} ;
2022-12-31 05:50:12 +01:00
const char * EditorAssetLibrary : : support_text [ SUPPORT_MAX ] = {
TTRC ( " Official " ) ,
TTRC ( " Community " ) ,
TTRC ( " Testing " ) ,
} ;
2024-02-11 03:45:05 +01:00
void EditorAssetLibrary : : _select_author ( const String & p_author ) {
if ( ! host . contains ( " godotengine.org " ) ) {
// Don't open the link for alternative repositories.
return ;
}
OS : : get_singleton ( ) - > shell_open ( " https://godotengine.org/asset-library/asset?user= " + p_author . uri_encode ( ) ) ;
2016-03-04 15:09:45 +01:00
}
2016-06-08 14:25:47 +02:00
void EditorAssetLibrary : : _select_category ( int p_id ) {
2016-03-04 15:09:45 +01:00
for ( int i = 0 ; i < categories - > get_item_count ( ) ; i + + ) {
2020-05-14 16:41:43 +02:00
if ( i = = 0 ) {
2016-03-04 15:09:45 +01:00
continue ;
2020-05-14 16:41:43 +02:00
}
2016-03-04 15:09:45 +01:00
int id = categories - > get_item_metadata ( i ) ;
if ( id = = p_id ) {
categories - > select ( i ) ;
_search ( ) ;
break ;
}
}
}
2020-05-14 14:29:06 +02:00
2016-06-08 14:25:47 +02:00
void EditorAssetLibrary : : _select_asset ( int p_id ) {
2016-06-07 20:29:15 +02:00
_api_request ( " asset/ " + itos ( p_id ) , REQUESTING_ASSET ) ;
2016-03-04 15:09:45 +01:00
}
2024-01-26 20:33:22 +01:00
void EditorAssetLibrary : : _image_update ( bool p_use_cache , bool p_final , const PackedByteArray & p_data , int p_queue_id ) {
2016-06-07 20:29:15 +02:00
Object * obj = ObjectDB : : get_instance ( image_queue [ p_queue_id ] . target ) ;
2024-01-26 20:33:22 +01:00
if ( ! obj ) {
return ;
}
2016-06-07 20:29:15 +02:00
2024-01-26 20:33:22 +01:00
bool image_set = false ;
PackedByteArray image_data = p_data ;
2017-03-05 16:44:50 +01:00
2024-01-26 20:33:22 +01:00
if ( p_use_cache ) {
String cache_filename_base = EditorPaths : : get_singleton ( ) - > get_cache_dir ( ) . path_join ( " assetimage_ " + image_queue [ p_queue_id ] . image_url . md5_text ( ) ) ;
2017-03-05 16:44:50 +01:00
2024-01-26 20:33:22 +01:00
Ref < FileAccess > file = FileAccess : : open ( cache_filename_base + " .data " , FileAccess : : READ ) ;
if ( file . is_valid ( ) ) {
PackedByteArray cached_data ;
int len = file - > get_32 ( ) ;
cached_data . resize ( len ) ;
2017-03-05 16:44:50 +01:00
2024-01-26 20:33:22 +01:00
uint8_t * w = cached_data . ptrw ( ) ;
file - > get_buffer ( w , len ) ;
2017-03-05 16:44:50 +01:00
2024-01-26 20:33:22 +01:00
image_data = cached_data ;
}
}
int len = image_data . size ( ) ;
const uint8_t * r = image_data . ptr ( ) ;
Ref < Image > image = memnew ( Image ) ;
uint8_t png_signature [ 8 ] = { 137 , 80 , 78 , 71 , 13 , 10 , 26 , 10 } ;
uint8_t jpg_signature [ 3 ] = { 255 , 216 , 255 } ;
uint8_t webp_signature [ 4 ] = { 82 , 73 , 70 , 70 } ;
uint8_t bmp_signature [ 2 ] = { 66 , 77 } ;
if ( r ) {
Ref < Image > parsed_image ;
if ( ( memcmp ( & r [ 0 ] , & png_signature [ 0 ] , 8 ) = = 0 ) & & Image : : _png_mem_loader_func ) {
parsed_image = Image : : _png_mem_loader_func ( r , len ) ;
} else if ( ( memcmp ( & r [ 0 ] , & jpg_signature [ 0 ] , 3 ) = = 0 ) & & Image : : _jpg_mem_loader_func ) {
parsed_image = Image : : _jpg_mem_loader_func ( r , len ) ;
} else if ( ( memcmp ( & r [ 0 ] , & webp_signature [ 0 ] , 4 ) = = 0 ) & & Image : : _webp_mem_loader_func ) {
parsed_image = Image : : _webp_mem_loader_func ( r , len ) ;
} else if ( ( memcmp ( & r [ 0 ] , & bmp_signature [ 0 ] , 2 ) = = 0 ) & & Image : : _bmp_mem_loader_func ) {
parsed_image = Image : : _bmp_mem_loader_func ( r , len ) ;
} else if ( Image : : _svg_scalable_mem_loader_func ) {
parsed_image = Image : : _svg_scalable_mem_loader_func ( r , len , 1.0 ) ;
2016-06-07 20:29:15 +02:00
}
2017-03-05 16:44:50 +01:00
2024-01-26 20:33:22 +01:00
if ( parsed_image . is_null ( ) ) {
if ( is_print_verbose_enabled ( ) ) {
ERR_PRINT ( vformat ( " Asset Library: Invalid image downloaded from '%s' for asset # %d " , image_queue [ p_queue_id ] . image_url , image_queue [ p_queue_id ] . asset_id ) ) ;
2018-05-15 01:11:46 +02:00
}
2024-01-26 20:33:22 +01:00
} else {
image - > copy_internals_from ( parsed_image ) ;
2018-05-15 01:11:46 +02:00
}
2024-01-26 20:33:22 +01:00
}
2017-05-17 12:36:47 +02:00
2024-01-26 20:33:22 +01:00
if ( ! image - > is_empty ( ) ) {
switch ( image_queue [ p_queue_id ] . image_type ) {
case IMAGE_QUEUE_ICON :
image - > resize ( 64 * EDSCALE , 64 * EDSCALE , Image : : INTERPOLATE_LANCZOS ) ;
break ;
2017-11-18 12:20:26 +01:00
2024-01-26 20:33:22 +01:00
case IMAGE_QUEUE_THUMBNAIL : {
float max_height = 85 * EDSCALE ;
2017-11-18 12:20:26 +01:00
2024-01-26 20:33:22 +01:00
float scale_ratio = max_height / ( image - > get_height ( ) * EDSCALE ) ;
if ( scale_ratio < 1 ) {
image - > resize ( image - > get_width ( ) * EDSCALE * scale_ratio , image - > get_height ( ) * EDSCALE * scale_ratio , Image : : INTERPOLATE_LANCZOS ) ;
}
} break ;
2017-11-18 12:20:26 +01:00
2024-01-26 20:33:22 +01:00
case IMAGE_QUEUE_SCREENSHOT : {
float max_height = 397 * EDSCALE ;
2017-11-18 12:20:26 +01:00
2024-01-26 20:33:22 +01:00
float scale_ratio = max_height / ( image - > get_height ( ) * EDSCALE ) ;
if ( scale_ratio < 1 ) {
image - > resize ( image - > get_width ( ) * EDSCALE * scale_ratio , image - > get_height ( ) * EDSCALE * scale_ratio , Image : : INTERPOLATE_LANCZOS ) ;
}
} break ;
}
2016-06-07 20:29:15 +02:00
2024-01-26 20:33:22 +01:00
Ref < ImageTexture > tex = ImageTexture : : create_from_image ( image ) ;
2016-03-04 15:09:45 +01:00
2024-01-26 20:33:22 +01:00
obj - > call ( " set_image " , image_queue [ p_queue_id ] . image_type , image_queue [ p_queue_id ] . image_index , tex ) ;
image_set = true ;
}
2017-03-05 16:44:50 +01:00
2024-01-26 20:33:22 +01:00
if ( ! image_set & & p_final ) {
obj - > call ( " set_image " , image_queue [ p_queue_id ] . image_type , image_queue [ p_queue_id ] . image_index , get_editor_theme_icon ( SNAME ( " FileBrokenBigThumb " ) ) ) ;
2016-06-07 20:29:15 +02:00
}
}
2016-03-04 15:09:45 +01:00
2020-02-17 22:06:54 +01:00
void EditorAssetLibrary : : _image_request_completed ( int p_status , int p_code , const PackedStringArray & headers , const PackedByteArray & p_data , int p_queue_id ) {
2016-03-04 15:09:45 +01:00
ERR_FAIL_COND ( ! image_queue . has ( p_queue_id ) ) ;
2018-05-15 01:11:46 +02:00
if ( p_status = = HTTPRequest : : RESULT_SUCCESS & & p_code < HTTPClient : : RESPONSE_BAD_REQUEST ) {
2016-06-07 20:29:15 +02:00
if ( p_code ! = HTTPClient : : RESPONSE_NOT_MODIFIED ) {
for ( int i = 0 ; i < headers . size ( ) ; i + + ) {
if ( headers [ i ] . findn ( " ETag: " ) = = 0 ) { // Save etag
2022-08-30 02:34:01 +02:00
String cache_filename_base = EditorPaths : : get_singleton ( ) - > get_cache_dir ( ) . path_join ( " assetimage_ " + image_queue [ p_queue_id ] . image_url . md5_text ( ) ) ;
2016-06-07 20:29:15 +02:00
String new_etag = headers [ i ] . substr ( headers [ i ] . find ( " : " ) + 1 , headers [ i ] . length ( ) ) . strip_edges ( ) ;
2022-03-23 10:08:58 +01:00
Ref < FileAccess > file = FileAccess : : open ( cache_filename_base + " .etag " , FileAccess : : WRITE ) ;
if ( file . is_valid ( ) ) {
2016-06-07 20:29:15 +02:00
file - > store_line ( new_etag ) ;
}
2017-03-05 16:44:50 +01:00
2016-06-07 20:29:15 +02:00
int len = p_data . size ( ) ;
2020-02-17 22:06:54 +01:00
const uint8_t * r = p_data . ptr ( ) ;
2016-06-07 20:29:15 +02:00
file = FileAccess : : open ( cache_filename_base + " .data " , FileAccess : : WRITE ) ;
2022-03-23 10:08:58 +01:00
if ( file . is_valid ( ) ) {
2016-06-07 20:29:15 +02:00
file - > store_32 ( len ) ;
2020-02-17 22:06:54 +01:00
file - > store_buffer ( r , len ) ;
2016-06-07 20:29:15 +02:00
}
2017-03-05 16:44:50 +01:00
2016-06-07 20:29:15 +02:00
break ;
}
2016-03-04 15:09:45 +01:00
}
}
2016-06-07 20:29:15 +02:00
_image_update ( p_code = = HTTPClient : : RESPONSE_NOT_MODIFIED , true , p_data , p_queue_id ) ;
2017-03-05 16:44:50 +01:00
2016-03-04 15:09:45 +01:00
} else {
2024-01-26 20:33:22 +01:00
if ( is_print_verbose_enabled ( ) ) {
WARN_PRINT ( vformat ( " Asset Library: Error getting image from '%s' for asset # %d. " , image_queue [ p_queue_id ] . image_url , image_queue [ p_queue_id ] . asset_id ) ) ;
}
2016-06-07 20:29:15 +02:00
Object * obj = ObjectDB : : get_instance ( image_queue [ p_queue_id ] . target ) ;
if ( obj ) {
2023-08-13 02:33:39 +02:00
obj - > call ( " set_image " , image_queue [ p_queue_id ] . image_type , image_queue [ p_queue_id ] . image_index , get_editor_theme_icon ( SNAME ( " FileBrokenBigThumb " ) ) ) ;
2016-06-07 20:29:15 +02:00
}
2016-03-04 15:09:45 +01:00
}
2022-10-24 23:07:02 +02:00
image_queue [ p_queue_id ] . request - > queue_free ( ) ;
2016-03-04 15:09:45 +01:00
image_queue . erase ( p_queue_id ) ;
_update_image_queue ( ) ;
}
2016-06-08 14:25:47 +02:00
void EditorAssetLibrary : : _update_image_queue ( ) {
2019-08-27 19:41:49 +02:00
const int max_images = 6 ;
2016-03-04 15:09:45 +01:00
int current_images = 0 ;
List < int > to_delete ;
2021-08-09 22:13:42 +02:00
for ( KeyValue < int , ImageQueue > & E : image_queue ) {
if ( ! E . value . active & & current_images < max_images ) {
2022-08-30 02:34:01 +02:00
String cache_filename_base = EditorPaths : : get_singleton ( ) - > get_cache_dir ( ) . path_join ( " assetimage_ " + E . value . image_url . md5_text ( ) ) ;
2016-06-07 20:29:15 +02:00
Vector < String > headers ;
2017-03-05 16:44:50 +01:00
2016-06-07 20:29:15 +02:00
if ( FileAccess : : exists ( cache_filename_base + " .etag " ) & & FileAccess : : exists ( cache_filename_base + " .data " ) ) {
2022-03-23 10:08:58 +01:00
Ref < FileAccess > file = FileAccess : : open ( cache_filename_base + " .etag " , FileAccess : : READ ) ;
if ( file . is_valid ( ) ) {
2016-06-07 20:29:15 +02:00
headers . push_back ( " If-None-Match: " + file - > get_line ( ) ) ;
}
2016-03-04 15:09:45 +01:00
}
2021-08-09 22:13:42 +02:00
Error err = E . value . request - > request ( E . value . image_url , headers ) ;
2016-03-04 15:09:45 +01:00
if ( err ! = OK ) {
2021-08-09 22:13:42 +02:00
to_delete . push_back ( E . key ) ;
2016-03-04 15:09:45 +01:00
} else {
2021-08-09 22:13:42 +02:00
E . value . active = true ;
2016-03-04 15:09:45 +01:00
}
current_images + + ;
2021-08-09 22:13:42 +02:00
} else if ( E . value . active ) {
2016-03-04 15:09:45 +01:00
current_images + + ;
}
}
while ( to_delete . size ( ) ) {
2022-10-24 23:07:02 +02:00
image_queue [ to_delete . front ( ) - > get ( ) ] . request - > queue_free ( ) ;
2016-03-04 15:09:45 +01:00
image_queue . erase ( to_delete . front ( ) - > get ( ) ) ;
to_delete . pop_front ( ) ;
}
}
2024-01-26 20:33:22 +01:00
void EditorAssetLibrary : : _request_image ( ObjectID p_for , int p_asset_id , String p_image_url , ImageType p_type , int p_image_index ) {
// Remove extra spaces around the URL. This isn't strictly valid, but recoverable.
String trimmed_url = p_image_url . strip_edges ( ) ;
if ( trimmed_url ! = p_image_url & & is_print_verbose_enabled ( ) ) {
WARN_PRINT ( vformat ( " Asset Library: Badly formatted image URL '%s' for asset # %d. " , p_image_url , p_asset_id ) ) ;
}
// Validate the image URL first.
{
String url_scheme ;
String url_host ;
int url_port ;
String url_path ;
Error err = trimmed_url . parse_url ( url_scheme , url_host , url_port , url_path ) ;
if ( err ! = OK ) {
if ( is_print_verbose_enabled ( ) ) {
ERR_PRINT ( vformat ( " Asset Library: Invalid image URL '%s' for asset # %d. " , trimmed_url , p_asset_id ) ) ;
}
Object * obj = ObjectDB : : get_instance ( p_for ) ;
if ( obj ) {
obj - > call ( " set_image " , p_type , p_image_index , get_editor_theme_icon ( SNAME ( " FileBrokenBigThumb " ) ) ) ;
}
return ;
}
}
2016-03-04 15:09:45 +01:00
ImageQueue iq ;
2024-01-26 20:33:22 +01:00
iq . image_url = trimmed_url ;
2016-03-04 15:09:45 +01:00
iq . image_index = p_image_index ;
iq . image_type = p_type ;
iq . request = memnew ( HTTPRequest ) ;
2021-12-09 04:34:32 +01:00
setup_http_request ( iq . request ) ;
2016-03-04 15:09:45 +01:00
iq . target = p_for ;
2024-01-26 20:33:22 +01:00
iq . asset_id = p_asset_id ;
2016-03-04 15:09:45 +01:00
iq . queue_id = + + last_queue_id ;
iq . active = false ;
2022-07-28 22:56:41 +02:00
iq . request - > connect ( " request_completed " , callable_mp ( this , & EditorAssetLibrary : : _image_request_completed ) . bind ( iq . queue_id ) ) ;
2016-03-04 15:09:45 +01:00
image_queue [ iq . queue_id ] = iq ;
add_child ( iq . request ) ;
2020-02-17 22:06:54 +01:00
_image_update ( true , false , PackedByteArray ( ) , iq . queue_id ) ;
2016-03-04 15:09:45 +01:00
_update_image_queue ( ) ;
}
2016-06-08 14:25:47 +02:00
void EditorAssetLibrary : : _repository_changed ( int p_repository_id ) {
2024-01-30 17:35:46 +01:00
_set_library_message ( TTR ( " Loading... " ) ) ;
2022-05-04 11:49:11 +02:00
asset_top_page - > hide ( ) ;
asset_bottom_page - > hide ( ) ;
asset_items - > hide ( ) ;
filter - > set_editable ( false ) ;
sort - > set_disabled ( true ) ;
categories - > set_disabled ( true ) ;
support - > set_disabled ( true ) ;
2016-06-07 20:29:15 +02:00
host = repository - > get_item_metadata ( p_repository_id ) ;
2016-06-21 16:10:02 +02:00
if ( templates_only ) {
_api_request ( " configure " , REQUESTING_CONFIG , " ?type=project " ) ;
} else {
_api_request ( " configure " , REQUESTING_CONFIG ) ;
}
2016-06-07 20:29:15 +02:00
}
2016-03-04 15:09:45 +01:00
2016-06-21 15:29:49 +02:00
void EditorAssetLibrary : : _support_toggled ( int p_support ) {
support - > get_popup ( ) - > set_item_checked ( p_support , ! support - > get_popup ( ) - > is_item_checked ( p_support ) ) ;
2016-06-21 16:10:02 +02:00
_search ( ) ;
}
void EditorAssetLibrary : : _rerun_search ( int p_ignore ) {
_search ( ) ;
2016-06-21 15:29:49 +02:00
}
2016-06-08 14:25:47 +02:00
void EditorAssetLibrary : : _search ( int p_page ) {
2016-03-04 15:09:45 +01:00
String args ;
2016-06-21 16:10:02 +02:00
if ( templates_only ) {
args + = " ?type=project& " ;
} else {
args + = " ? " ;
}
args + = String ( ) + " sort= " + sort_key [ sort - > get_selected ( ) ] ;
Refactor version macros and fix related bugs
The previous logic with VERSION_MKSTRING was a bit unwieldy, so there were
several places hardcoding their own variant of the version string, potentially
with bugs (e.g. forgetting the patch number when defined).
The new logic defines:
- VERSION_BRANCH, the main 'major.minor' version (e.g. 3.1)
- VERSION_NUMBER, which can be 'major.minor' or 'major.minor.patch',
depending on whether the latter is defined (e.g. 3.1.4)
- VERSION_FULL_CONFIG, which contains the version status (e.g. stable)
and the module-specific suffix (e.g. mono)
- VERSION_FULL_BUILD, same as above but with build/reference name
(e.g. official, custom_build, mageia, etc.)
Note: Slight change here, as the previous format had the build name
*before* the module-specific suffix; now it's after
- VERSION_FULL_NAME, same as before, so VERSION_FULL_BUILD prefixed
with "Godot v" for readability
Bugs fixed thanks to that:
- Export templates version matching now properly takes VERSION_PATCH
into account by relying on VERSION_FULL_CONFIG.
- ClassDB hash no longer takes the build name into account, but limits
itself to VERSION_FULL_CONFIG (build name is cosmetic, not relevant
for the API hash).
- Docs XML no longer hardcode the VERSION_STATUS, this was annoying.
- Small cleanup in Windows .rc file thanks to new macros.
2018-02-23 19:48:49 +01:00
// We use the "branch" version, i.e. major.minor, as patch releases should be compatible
args + = " &godot_version= " + String ( VERSION_BRANCH ) ;
2017-11-09 11:55:30 +01:00
2016-06-21 15:29:49 +02:00
String support_list ;
for ( int i = 0 ; i < SUPPORT_MAX ; i + + ) {
if ( support - > get_popup ( ) - > is_item_checked ( i ) ) {
support_list + = String ( support_key [ i ] ) + " + " ;
}
}
2021-12-09 10:42:46 +01:00
if ( ! support_list . is_empty ( ) ) {
2016-06-21 15:29:49 +02:00
args + = " &support= " + support_list . substr ( 0 , support_list . length ( ) - 1 ) ;
}
2016-03-04 15:09:45 +01:00
if ( categories - > get_selected ( ) > 0 ) {
args + = " &category= " + itos ( categories - > get_item_metadata ( categories - > get_selected ( ) ) ) ;
}
2017-03-05 16:44:50 +01:00
2019-08-24 04:53:14 +02:00
// Sorting options with an odd index are always the reverse of the previous one
if ( sort - > get_selected ( ) % 2 = = 1 ) {
2016-06-07 20:29:15 +02:00
args + = " &reverse=true " ;
}
2017-03-05 16:44:50 +01:00
2021-12-09 10:42:46 +01:00
if ( ! filter - > get_text ( ) . is_empty ( ) ) {
2020-11-30 04:43:38 +01:00
args + = " &filter= " + filter - > get_text ( ) . uri_encode ( ) ;
2016-03-04 15:09:45 +01:00
}
if ( p_page > 0 ) {
args + = " &page= " + itos ( p_page ) ;
}
2016-06-07 20:29:15 +02:00
_api_request ( " asset " , REQUESTING_SEARCH , args ) ;
2016-03-04 15:09:45 +01:00
}
2020-09-29 12:43:38 +02:00
void EditorAssetLibrary : : _search_text_changed ( const String & p_text ) {
filter_debounce_timer - > start ( ) ;
}
void EditorAssetLibrary : : _filter_debounce_timer_timeout ( ) {
2017-12-09 22:56:38 +01:00
_search ( ) ;
}
2022-05-04 11:49:11 +02:00
void EditorAssetLibrary : : _request_current_config ( ) {
_repository_changed ( repository - > get_selected ( ) ) ;
}
2016-06-08 14:25:47 +02:00
HBoxContainer * EditorAssetLibrary : : _make_pages ( int p_page , int p_page_count , int p_page_len , int p_total_items , int p_current_items ) {
2016-03-04 15:09:45 +01:00
HBoxContainer * hbc = memnew ( HBoxContainer ) ;
2020-05-14 16:41:43 +02:00
if ( p_page_count < 2 ) {
2018-10-15 19:26:57 +02:00
return hbc ;
2020-05-14 16:41:43 +02:00
}
2018-10-15 19:26:57 +02:00
2016-03-04 15:09:45 +01:00
//do the mario
2023-10-01 01:16:39 +02:00
int from = p_page - ( 5 / EDSCALE ) ;
2020-05-14 16:41:43 +02:00
if ( from < 0 ) {
2016-03-04 15:09:45 +01:00
from = 0 ;
2020-05-14 16:41:43 +02:00
}
2023-10-01 01:16:39 +02:00
int to = from + ( 10 / EDSCALE ) ;
2020-05-14 16:41:43 +02:00
if ( to > p_page_count ) {
2016-06-07 20:29:15 +02:00
to = p_page_count ;
2020-05-14 16:41:43 +02:00
}
2016-03-04 15:09:45 +01:00
hbc - > add_spacer ( ) ;
2022-02-08 10:14:58 +01:00
hbc - > add_theme_constant_override ( " separation " , 5 * EDSCALE ) ;
2016-03-04 15:09:45 +01:00
2018-05-15 17:17:52 +02:00
Button * first = memnew ( Button ) ;
2022-03-24 06:48:07 +01:00
first - > set_text ( TTR ( " First " , " Pagination " ) ) ;
2024-01-30 17:35:46 +01:00
first - > set_theme_type_variation ( " PanelBackgroundButton " ) ;
2016-06-07 20:29:15 +02:00
if ( p_page ! = 0 ) {
2022-07-28 22:56:41 +02:00
first - > connect ( " pressed " , callable_mp ( this , & EditorAssetLibrary : : _search ) . bind ( 0 ) ) ;
2018-05-15 17:17:52 +02:00
} else {
first - > set_disabled ( true ) ;
first - > set_focus_mode ( Control : : FOCUS_NONE ) ;
2016-06-07 20:29:15 +02:00
}
2018-05-15 17:17:52 +02:00
hbc - > add_child ( first ) ;
2016-03-04 15:09:45 +01:00
2018-05-15 17:17:52 +02:00
Button * prev = memnew ( Button ) ;
2022-03-24 06:48:07 +01:00
prev - > set_text ( TTR ( " Previous " , " Pagination " ) ) ;
2024-01-30 17:35:46 +01:00
prev - > set_theme_type_variation ( " PanelBackgroundButton " ) ;
2016-03-04 15:09:45 +01:00
if ( p_page > 0 ) {
2022-07-28 22:56:41 +02:00
prev - > connect ( " pressed " , callable_mp ( this , & EditorAssetLibrary : : _search ) . bind ( p_page - 1 ) ) ;
2018-05-15 17:17:52 +02:00
} else {
prev - > set_disabled ( true ) ;
prev - > set_focus_mode ( Control : : FOCUS_NONE ) ;
2016-03-04 15:09:45 +01:00
}
2018-05-15 17:17:52 +02:00
hbc - > add_child ( prev ) ;
hbc - > add_child ( memnew ( VSeparator ) ) ;
2016-03-04 15:09:45 +01:00
2016-06-07 20:29:15 +02:00
for ( int i = from ; i < to ; i + + ) {
2024-01-30 17:35:46 +01:00
Button * current = memnew ( Button ) ;
// Add padding to make page number buttons easier to click.
current - > set_text ( vformat ( " %d " , i + 1 ) ) ;
current - > set_theme_type_variation ( " PanelBackgroundButton " ) ;
2016-03-04 15:09:45 +01:00
if ( i = = p_page ) {
2018-05-15 17:17:52 +02:00
current - > set_disabled ( true ) ;
current - > set_focus_mode ( Control : : FOCUS_NONE ) ;
2016-03-04 15:09:45 +01:00
} else {
2022-07-28 22:56:41 +02:00
current - > connect ( " pressed " , callable_mp ( this , & EditorAssetLibrary : : _search ) . bind ( i ) ) ;
2016-03-04 15:09:45 +01:00
}
2024-01-30 17:35:46 +01:00
hbc - > add_child ( current ) ;
2016-03-04 15:09:45 +01:00
}
2018-05-15 17:17:52 +02:00
Button * next = memnew ( Button ) ;
2022-03-24 06:48:07 +01:00
next - > set_text ( TTR ( " Next " , " Pagination " ) ) ;
2024-01-30 17:35:46 +01:00
next - > set_theme_type_variation ( " PanelBackgroundButton " ) ;
2016-06-07 20:29:15 +02:00
if ( p_page < p_page_count - 1 ) {
2022-07-28 22:56:41 +02:00
next - > connect ( " pressed " , callable_mp ( this , & EditorAssetLibrary : : _search ) . bind ( p_page + 1 ) ) ;
2018-05-15 17:17:52 +02:00
} else {
next - > set_disabled ( true ) ;
next - > set_focus_mode ( Control : : FOCUS_NONE ) ;
2016-03-04 15:09:45 +01:00
}
2018-05-15 17:17:52 +02:00
hbc - > add_child ( memnew ( VSeparator ) ) ;
hbc - > add_child ( next ) ;
2016-06-07 20:29:15 +02:00
2018-05-15 17:17:52 +02:00
Button * last = memnew ( Button ) ;
2022-03-24 06:48:07 +01:00
last - > set_text ( TTR ( " Last " , " Pagination " ) ) ;
2024-01-30 17:35:46 +01:00
last - > set_theme_type_variation ( " PanelBackgroundButton " ) ;
2016-06-07 20:29:15 +02:00
if ( p_page ! = p_page_count - 1 ) {
2022-07-28 22:56:41 +02:00
last - > connect ( " pressed " , callable_mp ( this , & EditorAssetLibrary : : _search ) . bind ( p_page_count - 1 ) ) ;
2018-05-15 17:17:52 +02:00
} else {
last - > set_disabled ( true ) ;
last - > set_focus_mode ( Control : : FOCUS_NONE ) ;
2016-06-07 20:29:15 +02:00
}
2018-05-15 17:17:52 +02:00
hbc - > add_child ( last ) ;
2016-03-04 15:09:45 +01:00
hbc - > add_spacer ( ) ;
return hbc ;
}
2016-06-08 14:25:47 +02:00
void EditorAssetLibrary : : _api_request ( const String & p_request , RequestType p_request_type , const String & p_arguments ) {
2016-03-04 15:09:45 +01:00
if ( requesting ! = REQUESTING_NONE ) {
request - > cancel_request ( ) ;
}
2024-01-30 17:35:46 +01:00
error_hb - > hide ( ) ;
2016-07-24 21:09:43 +02:00
2024-01-30 17:35:46 +01:00
if ( loading_blocked ) {
_set_library_message_with_action ( TTR ( " The Asset Library requires an online connection and involves sending data over the internet. " ) , TTR ( " Go Online " ) , callable_mp ( this , & EditorAssetLibrary : : _force_online_mode ) ) ;
return ;
}
2016-03-04 15:09:45 +01:00
2024-01-30 17:35:46 +01:00
requesting = p_request_type ;
2016-03-04 15:09:45 +01:00
request - > request ( host + " / " + p_request + p_arguments ) ;
}
2020-02-17 22:06:54 +01:00
void EditorAssetLibrary : : _http_request_completed ( int p_status , int p_code , const PackedStringArray & headers , const PackedByteArray & p_data ) {
2016-03-04 15:09:45 +01:00
String str ;
{
int datalen = p_data . size ( ) ;
2020-02-17 22:06:54 +01:00
const uint8_t * r = p_data . ptr ( ) ;
str . parse_utf8 ( ( const char * ) r , datalen ) ;
2016-03-04 15:09:45 +01:00
}
2016-03-05 16:24:12 +01:00
bool error_abort = true ;
switch ( p_status ) {
case HTTPRequest : : RESULT_CANT_RESOLVE : {
2017-04-20 14:42:35 +02:00
error_label - > set_text ( TTR ( " Can't resolve hostname: " ) + " " + host ) ;
2016-03-05 16:24:12 +01:00
} break ;
case HTTPRequest : : RESULT_BODY_SIZE_LIMIT_EXCEEDED :
case HTTPRequest : : RESULT_CONNECTION_ERROR :
case HTTPRequest : : RESULT_CHUNKED_BODY_SIZE_MISMATCH : {
2017-04-20 14:42:35 +02:00
error_label - > set_text ( TTR ( " Connection error, please try again. " ) ) ;
2016-03-05 16:24:12 +01:00
} break ;
2022-09-07 08:25:47 +02:00
case HTTPRequest : : RESULT_TLS_HANDSHAKE_ERROR :
2016-03-05 16:24:12 +01:00
case HTTPRequest : : RESULT_CANT_CONNECT : {
2017-04-20 14:42:35 +02:00
error_label - > set_text ( TTR ( " Can't connect to host: " ) + " " + host ) ;
2016-03-05 16:24:12 +01:00
} break ;
case HTTPRequest : : RESULT_NO_RESPONSE : {
2017-04-20 14:42:35 +02:00
error_label - > set_text ( TTR ( " No response from host: " ) + " " + host ) ;
2016-03-05 16:24:12 +01:00
} break ;
case HTTPRequest : : RESULT_REQUEST_FAILED : {
2017-04-20 14:42:35 +02:00
error_label - > set_text ( TTR ( " Request failed, return code: " ) + " " + itos ( p_code ) ) ;
2016-03-05 16:24:12 +01:00
} break ;
case HTTPRequest : : RESULT_REDIRECT_LIMIT_REACHED : {
2017-04-20 14:42:35 +02:00
error_label - > set_text ( TTR ( " Request failed, too many redirects " ) ) ;
2016-03-05 16:24:12 +01:00
} break ;
default : {
if ( p_code ! = 200 ) {
2017-04-20 14:42:35 +02:00
error_label - > set_text ( TTR ( " Request failed, return code: " ) + " " + itos ( p_code ) ) ;
2016-03-05 16:24:12 +01:00
} else {
error_abort = false ;
}
} break ;
}
if ( error_abort ) {
2022-05-04 11:49:11 +02:00
if ( requesting = = REQUESTING_CONFIG ) {
2024-01-30 17:35:46 +01:00
_set_library_message_with_action ( TTR ( " Failed to get repository configuration. " ) , TTR ( " Retry " ) , callable_mp ( this , & EditorAssetLibrary : : _request_current_config ) ) ;
2022-05-04 11:49:11 +02:00
}
2016-03-05 16:24:12 +01:00
error_hb - > show ( ) ;
return ;
}
2016-03-04 15:09:45 +01:00
Dictionary d ;
2017-01-09 02:40:00 +01:00
{
2020-12-29 19:12:33 +01:00
JSON json ;
json . parse ( str ) ;
d = json . get_data ( ) ;
2017-01-09 02:40:00 +01:00
}
2016-06-07 20:29:15 +02:00
RequestType requested = requesting ;
requesting = REQUESTING_NONE ;
switch ( requested ) {
case REQUESTING_CONFIG : {
categories - > clear ( ) ;
2017-04-20 14:42:35 +02:00
categories - > add_item ( TTR ( " All " ) ) ;
2016-06-07 20:29:15 +02:00
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 ] ;
2020-05-14 16:41:43 +02:00
if ( ! cat . has ( " name " ) | | ! cat . has ( " id " ) ) {
2016-06-07 20:29:15 +02:00
continue ;
2020-05-14 16:41:43 +02:00
}
2016-06-07 20:29:15 +02:00
String name = cat [ " name " ] ;
int id = cat [ " id " ] ;
categories - > add_item ( name ) ;
2022-03-12 01:06:45 +01:00
categories - > set_item_metadata ( - 1 , id ) ;
2016-06-07 20:29:15 +02:00
category_map [ cat [ " id " ] ] = name ;
}
2016-03-04 15:09:45 +01:00
}
2022-05-04 11:49:11 +02:00
filter - > set_editable ( true ) ;
sort - > set_disabled ( false ) ;
categories - > set_disabled ( false ) ;
support - > set_disabled ( false ) ;
2016-06-07 20:29:15 +02:00
_search ( ) ;
} break ;
case REQUESTING_SEARCH : {
2019-09-02 19:42:58 +02:00
initial_loading = false ;
2016-06-07 20:29:15 +02:00
if ( asset_items ) {
memdelete ( asset_items ) ;
}
2016-03-04 15:09:45 +01:00
2016-06-07 20:29:15 +02:00
if ( asset_top_page ) {
memdelete ( asset_top_page ) ;
}
2016-03-04 15:09:45 +01:00
2016-06-07 20:29:15 +02:00
if ( asset_bottom_page ) {
memdelete ( asset_bottom_page ) ;
}
2016-03-04 15:09:45 +01:00
2016-06-07 20:29:15 +02:00
int page = 0 ;
int pages = 1 ;
int page_len = 10 ;
int total_items = 1 ;
Array result ;
2016-03-04 15:09:45 +01:00
2016-06-07 20:29:15 +02:00
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 " ] ;
}
2016-03-04 15:09:45 +01:00
2016-06-07 20:29:15 +02:00
asset_top_page = _make_pages ( page , pages , page_len , total_items , result . size ( ) ) ;
library_vb - > add_child ( asset_top_page ) ;
2016-03-04 15:09:45 +01:00
2016-06-07 20:29:15 +02:00
asset_items = memnew ( GridContainer ) ;
2022-07-02 22:15:42 +02:00
_update_asset_items_columns ( ) ;
2022-04-14 23:20:28 +02:00
asset_items - > add_theme_constant_override ( " h_separation " , 10 * EDSCALE ) ;
asset_items - > add_theme_constant_override ( " v_separation " , 10 * EDSCALE ) ;
2016-03-04 15:09:45 +01:00
2016-06-07 20:29:15 +02:00
library_vb - > add_child ( asset_items ) ;
2016-03-04 15:09:45 +01:00
2016-06-07 20:29:15 +02:00
asset_bottom_page = _make_pages ( page , pages , page_len , total_items , result . size ( ) ) ;
library_vb - > add_child ( asset_bottom_page ) ;
2016-03-04 15:09:45 +01:00
2020-12-15 13:04:21 +01:00
if ( result . is_empty ( ) ) {
2022-12-31 05:50:12 +01:00
String support_list ;
for ( int i = 0 ; i < SUPPORT_MAX ; i + + ) {
if ( support - > get_popup ( ) - > is_item_checked ( i ) ) {
if ( ! support_list . is_empty ( ) ) {
support_list + = " , " ;
}
support_list + = TTRGET ( support_text [ i ] ) ;
}
}
if ( support_list . is_empty ( ) ) {
support_list = " - " ;
}
2021-12-09 10:42:46 +01:00
if ( ! filter - > get_text ( ) . is_empty ( ) ) {
2024-01-30 17:35:46 +01:00
_set_library_message (
2022-12-31 05:50:12 +01:00
vformat ( TTR ( " No results for \" %s \" for support level(s): %s. " ) , filter - > get_text ( ) , support_list ) ) ;
2020-02-23 20:55:55 +01:00
} else {
// No results, even though the user didn't search for anything specific.
// This is typically because the version number changed recently
// and no assets compatible with the new version have been published yet.
2024-01-30 17:35:46 +01:00
_set_library_message (
2022-12-31 05:50:12 +01:00
vformat ( TTR ( " No results compatible with %s %s for support level(s): %s. \n Check the enabled support levels using the 'Support' button in the top-right corner. " ) , String ( VERSION_SHORT_NAME ) . capitalize ( ) , String ( VERSION_BRANCH ) , support_list ) ) ;
2020-02-23 20:55:55 +01:00
}
2022-05-04 11:49:11 +02:00
} else {
2024-01-30 17:35:46 +01:00
library_message_box - > hide ( ) ;
2019-10-26 01:07:02 +02:00
}
2016-06-07 20:29:15 +02:00
for ( int i = 0 ; i < result . size ( ) ; i + + ) {
Dictionary r = result [ i ] ;
2016-03-04 15:09:45 +01:00
2016-06-07 20:29:15 +02:00
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 ( " cost " ) ) ;
2016-03-12 14:44:12 +01:00
2024-02-11 03:45:05 +01:00
EditorAssetLibraryItem * item = memnew ( EditorAssetLibraryItem ( true ) ) ;
2016-06-07 20:29:15 +02:00
asset_items - > add_child ( item ) ;
2019-06-12 12:24:08 +02:00
item - > configure ( r [ " title " ] , r [ " asset_id " ] , category_map [ r [ " category_id " ] ] , r [ " category_id " ] , r [ " author " ] , r [ " author_id " ] , r [ " cost " ] ) ;
2023-10-01 01:16:39 +02:00
item - > clamp_width ( asset_items_column_width ) ;
2020-02-21 18:28:45 +01:00
item - > connect ( " asset_selected " , callable_mp ( this , & EditorAssetLibrary : : _select_asset ) ) ;
item - > connect ( " author_selected " , callable_mp ( this , & EditorAssetLibrary : : _select_author ) ) ;
item - > connect ( " category_selected " , callable_mp ( this , & EditorAssetLibrary : : _select_category ) ) ;
2016-03-04 15:09:45 +01:00
2021-12-09 10:42:46 +01:00
if ( r . has ( " icon_url " ) & & ! r [ " icon_url " ] . operator String ( ) . is_empty ( ) ) {
2024-01-26 20:33:22 +01:00
_request_image ( item - > get_instance_id ( ) , r [ " asset_id " ] , r [ " icon_url " ] , IMAGE_QUEUE_ICON , 0 ) ;
2016-06-07 20:29:15 +02:00
}
}
2020-12-09 15:24:26 +01:00
2020-12-15 13:04:21 +01:00
if ( ! result . is_empty ( ) ) {
2020-12-09 15:24:26 +01:00
library_scroll - > set_v_scroll ( 0 ) ;
}
2016-06-07 20:29:15 +02:00
} 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 ( " cost " ) ) ;
ERR_FAIL_COND ( ! r . has ( " description " ) ) ;
ERR_FAIL_COND ( ! r . has ( " download_url " ) ) ;
2016-06-21 14:38:29 +02:00
ERR_FAIL_COND ( ! r . has ( " download_hash " ) ) ;
2016-06-07 20:29:15 +02:00
ERR_FAIL_COND ( ! r . has ( " browse_url " ) ) ;
if ( description ) {
memdelete ( description ) ;
}
2016-03-04 15:09:45 +01:00
2016-06-08 14:25:47 +02:00
description = memnew ( EditorAssetLibraryItemDescription ) ;
2016-06-07 20:29:15 +02:00
add_child ( description ) ;
2020-02-21 18:28:45 +01:00
description - > connect ( " confirmed " , callable_mp ( this , & EditorAssetLibrary : : _install_asset ) ) ;
2016-03-04 15:09:45 +01:00
2019-06-12 12:24:08 +02:00
description - > configure ( r [ " title " ] , r [ " asset_id " ] , category_map [ r [ " category_id " ] ] , r [ " category_id " ] , r [ " author " ] , r [ " author_id " ] , r [ " cost " ] , r [ " version " ] , r [ " version_string " ] , r [ " description " ] , r [ " download_url " ] , r [ " browse_url " ] , r [ " download_hash " ] ) ;
2016-03-04 15:09:45 +01:00
2022-01-19 02:37:38 +01:00
EditorAssetLibraryItemDownload * download_item = _get_asset_in_progress ( description - > get_asset_id ( ) ) ;
if ( download_item ) {
2022-01-19 17:16:17 +01:00
if ( download_item - > can_install ( ) ) {
2022-07-08 02:31:19 +02:00
description - > set_ok_button_text ( TTR ( " Install " ) ) ;
2022-01-19 17:16:17 +01:00
description - > get_ok_button ( ) - > set_disabled ( false ) ;
} else {
2022-07-08 02:31:19 +02:00
description - > set_ok_button_text ( TTR ( " Downloading... " ) ) ;
2022-01-19 17:16:17 +01:00
description - > get_ok_button ( ) - > set_disabled ( true ) ;
}
2022-01-19 02:37:38 +01:00
} else {
2022-07-08 02:31:19 +02:00
description - > set_ok_button_text ( TTR ( " Download " ) ) ;
2022-01-19 17:16:17 +01:00
description - > get_ok_button ( ) - > set_disabled ( false ) ;
2022-01-19 02:37:38 +01:00
}
2021-12-09 10:42:46 +01:00
if ( r . has ( " icon_url " ) & & ! r [ " icon_url " ] . operator String ( ) . is_empty ( ) ) {
2024-01-26 20:33:22 +01:00
_request_image ( description - > get_instance_id ( ) , r [ " asset_id " ] , r [ " icon_url " ] , IMAGE_QUEUE_ICON , 0 ) ;
2016-06-07 20:29:15 +02:00
}
2016-03-04 15:09:45 +01:00
2016-06-07 20:29:15 +02:00
if ( d . has ( " previews " ) ) {
Array previews = d [ " previews " ] ;
2016-03-04 15:09:45 +01:00
2016-06-07 20:29:15 +02:00
for ( int i = 0 ; i < previews . size ( ) ; i + + ) {
Dictionary p = previews [ i ] ;
2016-03-04 15:09:45 +01:00
2016-06-07 20:29:15 +02:00
ERR_CONTINUE ( ! p . has ( " type " ) ) ;
ERR_CONTINUE ( ! p . has ( " link " ) ) ;
2016-03-04 15:09:45 +01:00
2016-06-07 20:29:15 +02:00
bool is_video = p . has ( " type " ) & & String ( p [ " type " ] ) = = " video " ;
String video_url ;
if ( is_video & & p . has ( " link " ) ) {
video_url = p [ " link " ] ;
}
2016-03-04 15:09:45 +01:00
2016-06-07 20:29:15 +02:00
description - > add_preview ( i , is_video , video_url ) ;
2016-03-04 15:09:45 +01:00
2016-06-07 20:29:15 +02:00
if ( p . has ( " thumbnail " ) ) {
2024-01-26 20:33:22 +01:00
_request_image ( description - > get_instance_id ( ) , r [ " asset_id " ] , p [ " thumbnail " ] , IMAGE_QUEUE_THUMBNAIL , i ) ;
2016-06-07 20:29:15 +02:00
}
2019-07-18 19:48:47 +02:00
if ( ! is_video ) {
2024-01-26 20:33:22 +01:00
_request_image ( description - > get_instance_id ( ) , r [ " asset_id " ] , p [ " link " ] , IMAGE_QUEUE_SCREENSHOT , i ) ;
2016-06-07 20:29:15 +02:00
}
2016-03-04 15:09:45 +01:00
}
}
2024-02-11 03:45:05 +01:00
description - > popup_centered ( ) ;
2016-06-07 20:29:15 +02:00
} break ;
2020-05-10 13:00:47 +02:00
default :
break ;
2016-03-04 15:09:45 +01:00
}
}
2016-06-08 14:25:47 +02:00
void EditorAssetLibrary : : _asset_file_selected ( const String & p_file ) {
2016-03-12 14:44:12 +01:00
if ( asset_installer ) {
memdelete ( asset_installer ) ;
2020-04-02 01:20:12 +02:00
asset_installer = nullptr ;
2016-03-12 14:44:12 +01:00
}
asset_installer = memnew ( EditorAssetInstaller ) ;
2023-09-08 20:01:26 +02:00
asset_installer - > set_asset_name ( p_file ) ;
2016-03-12 14:44:12 +01:00
add_child ( asset_installer ) ;
2023-09-08 20:01:26 +02:00
asset_installer - > open_asset ( p_file ) ;
2016-03-12 14:44:12 +01:00
}
2016-06-08 14:25:47 +02:00
void EditorAssetLibrary : : _asset_open ( ) {
2020-07-11 18:45:19 +02:00
asset_open - > popup_file_dialog ( ) ;
2016-03-12 14:44:12 +01:00
}
2016-06-08 14:25:47 +02:00
void EditorAssetLibrary : : _manage_plugins ( ) {
2023-03-10 11:10:05 +01:00
ProjectSettingsEditor : : get_singleton ( ) - > popup_project_settings ( true ) ;
2017-07-19 22:00:46 +02:00
ProjectSettingsEditor : : get_singleton ( ) - > set_plugins_page ( ) ;
2016-03-12 14:44:12 +01:00
}
2022-01-19 02:37:38 +01:00
EditorAssetLibraryItemDownload * EditorAssetLibrary : : _get_asset_in_progress ( int p_asset_id ) const {
for ( int i = 0 ; i < downloads_hb - > get_child_count ( ) ; i + + ) {
EditorAssetLibraryItemDownload * d = Object : : cast_to < EditorAssetLibraryItemDownload > ( downloads_hb - > get_child ( i ) ) ;
if ( d & & d - > get_asset_id ( ) = = p_asset_id ) {
return d ;
}
}
return nullptr ;
}
2016-07-12 02:34:02 +02:00
void EditorAssetLibrary : : _install_external_asset ( String p_zip_path , String p_title ) {
2021-07-17 23:22:52 +02:00
emit_signal ( SNAME ( " install_asset " ) , p_zip_path , p_title ) ;
2016-07-12 02:34:02 +02:00
}
2022-07-02 22:15:42 +02:00
void EditorAssetLibrary : : _update_asset_items_columns ( ) {
int new_columns = get_size ( ) . x / ( 450.0 * EDSCALE ) ;
new_columns = MAX ( 1 , new_columns ) ;
if ( new_columns ! = asset_items - > get_columns ( ) ) {
asset_items - > set_columns ( new_columns ) ;
}
2023-10-01 01:16:39 +02:00
asset_items_column_width = ( get_size ( ) . x / new_columns ) - ( 100 * EDSCALE ) ;
2017-11-26 19:31:08 +01:00
}
2024-01-30 17:35:46 +01:00
void EditorAssetLibrary : : _set_library_message ( const String & p_message ) {
library_message - > set_text ( p_message ) ;
if ( library_message_action . is_valid ( ) ) {
library_message_button - > disconnect ( " pressed " , library_message_action ) ;
library_message_action = Callable ( ) ;
}
library_message_button - > hide ( ) ;
library_message_box - > show ( ) ;
}
void EditorAssetLibrary : : _set_library_message_with_action ( const String & p_message , const String & p_action_text , const Callable & p_action ) {
library_message - > set_text ( p_message ) ;
library_message_button - > set_text ( p_action_text ) ;
if ( library_message_action . is_valid ( ) ) {
library_message_button - > disconnect ( " pressed " , library_message_action ) ;
library_message_action = Callable ( ) ;
}
library_message_action = p_action ;
library_message_button - > connect ( " pressed " , library_message_action ) ;
library_message_button - > show ( ) ;
library_message_box - > show ( ) ;
}
void EditorAssetLibrary : : _force_online_mode ( ) {
EditorSettings : : get_singleton ( ) - > set_setting ( " network/connection/network_mode " , EditorSettings : : NETWORK_ONLINE ) ;
EditorSettings : : get_singleton ( ) - > notify_changes ( ) ;
EditorSettings : : get_singleton ( ) - > save ( ) ;
}
2022-07-02 22:15:42 +02:00
void EditorAssetLibrary : : disable_community_support ( ) {
support - > get_popup ( ) - > set_item_checked ( SUPPORT_COMMUNITY , false ) ;
2022-05-20 06:57:10 +02:00
}
2016-06-08 14:25:47 +02:00
void EditorAssetLibrary : : _bind_methods ( ) {
2016-07-12 02:34:02 +02:00
ADD_SIGNAL ( MethodInfo ( " install_asset " , PropertyInfo ( Variant : : STRING , " zip_path " ) , PropertyInfo ( Variant : : STRING , " name " ) ) ) ;
2016-03-04 15:09:45 +01:00
}
2016-06-08 14:25:47 +02:00
EditorAssetLibrary : : EditorAssetLibrary ( bool p_templates_only ) {
2019-02-16 16:01:20 +01:00
requesting = REQUESTING_NONE ;
2016-06-08 14:25:47 +02:00
templates_only = p_templates_only ;
2024-01-30 17:35:46 +01:00
loading_blocked = ( ( int ) EDITOR_GET ( " network/connection/network_mode " ) = = EditorSettings : : NETWORK_OFFLINE ) ;
2016-02-29 13:56:36 +01:00
2016-03-04 15:09:45 +01:00
VBoxContainer * library_main = memnew ( VBoxContainer ) ;
2016-03-12 14:44:12 +01:00
add_child ( library_main ) ;
2016-03-04 15:09:45 +01:00
2016-02-29 13:56:36 +01:00
HBoxContainer * search_hb = memnew ( HBoxContainer ) ;
2016-03-04 15:09:45 +01:00
library_main - > add_child ( search_hb ) ;
2022-02-08 10:14:58 +01:00
library_main - > add_theme_constant_override ( " separation " , 10 * EDSCALE ) ;
2016-02-29 13:56:36 +01:00
filter = memnew ( LineEdit ) ;
2021-04-04 22:47:44 +02:00
if ( templates_only ) {
2022-05-27 06:02:48 +02:00
filter - > set_placeholder ( TTR ( " Search Templates, Projects, and Demos " ) ) ;
2021-04-04 22:47:44 +02:00
} else {
2022-05-27 06:02:48 +02:00
filter - > set_placeholder ( TTR ( " Search Assets (Excluding Templates, Projects, and Demos) " ) ) ;
2021-04-04 22:47:44 +02:00
}
2022-01-16 08:59:02 +01:00
filter - > set_clear_button_enabled ( true ) ;
2016-02-29 13:56:36 +01:00
search_hb - > add_child ( filter ) ;
2020-03-06 18:00:16 +01:00
filter - > set_h_size_flags ( Control : : SIZE_EXPAND_FILL ) ;
2020-09-29 12:43:38 +02:00
filter - > connect ( " text_changed " , callable_mp ( this , & EditorAssetLibrary : : _search_text_changed ) ) ;
// Perform a search automatically if the user hasn't entered any text for a certain duration.
// This way, the user doesn't need to press Enter to initiate their search.
filter_debounce_timer = memnew ( Timer ) ;
filter_debounce_timer - > set_one_shot ( true ) ;
filter_debounce_timer - > set_wait_time ( 0.25 ) ;
filter_debounce_timer - > connect ( " timeout " , callable_mp ( this , & EditorAssetLibrary : : _filter_debounce_timer_timeout ) ) ;
search_hb - > add_child ( filter_debounce_timer ) ;
2016-03-12 14:44:12 +01:00
2020-05-14 16:41:43 +02:00
if ( ! p_templates_only ) {
2016-06-08 14:25:47 +02:00
search_hb - > add_child ( memnew ( VSeparator ) ) ;
2020-05-14 16:41:43 +02:00
}
2016-03-12 14:44:12 +01:00
Button * open_asset = memnew ( Button ) ;
2019-08-28 06:27:26 +02:00
open_asset - > set_text ( TTR ( " Import... " ) ) ;
2016-03-12 14:44:12 +01:00
search_hb - > add_child ( open_asset ) ;
2020-02-21 18:28:45 +01:00
open_asset - > connect ( " pressed " , callable_mp ( this , & EditorAssetLibrary : : _asset_open ) ) ;
2016-03-12 14:44:12 +01:00
Button * plugins = memnew ( Button ) ;
2019-08-28 06:27:26 +02:00
plugins - > set_text ( TTR ( " Plugins... " ) ) ;
2016-03-12 14:44:12 +01:00
search_hb - > add_child ( plugins ) ;
2020-02-21 18:28:45 +01:00
plugins - > connect ( " pressed " , callable_mp ( this , & EditorAssetLibrary : : _manage_plugins ) ) ;
2016-03-12 14:44:12 +01:00
2016-06-08 14:25:47 +02:00
if ( p_templates_only ) {
open_asset - > hide ( ) ;
plugins - > hide ( ) ;
}
2016-03-04 15:09:45 +01:00
HBoxContainer * search_hb2 = memnew ( HBoxContainer ) ;
library_main - > add_child ( search_hb2 ) ;
2016-05-19 00:08:12 +02:00
search_hb2 - > add_child ( memnew ( Label ( TTR ( " Sort: " ) + " " ) ) ) ;
2016-03-04 15:09:45 +01:00
sort = memnew ( OptionButton ) ;
for ( int i = 0 ; i < SORT_MAX ; i + + ) {
2019-12-13 09:07:45 +01:00
sort - > add_item ( TTRGET ( sort_text [ i ] ) ) ;
2016-03-04 15:09:45 +01:00
}
2016-02-29 13:56:36 +01:00
2016-03-04 15:09:45 +01:00
search_hb2 - > add_child ( sort ) ;
2020-03-06 18:00:16 +01:00
sort - > set_h_size_flags ( Control : : SIZE_EXPAND_FILL ) ;
2022-05-20 06:57:10 +02:00
sort - > set_clip_text ( true ) ;
2020-02-21 18:28:45 +01:00
sort - > connect ( " item_selected " , callable_mp ( this , & EditorAssetLibrary : : _rerun_search ) ) ;
2016-03-04 15:09:45 +01:00
search_hb2 - > add_child ( memnew ( VSeparator ) ) ;
2016-05-19 00:08:12 +02:00
search_hb2 - > add_child ( memnew ( Label ( TTR ( " Category: " ) + " " ) ) ) ;
2016-02-29 13:56:36 +01:00
categories = memnew ( OptionButton ) ;
2016-05-19 00:08:12 +02:00
categories - > add_item ( TTR ( " All " ) ) ;
2016-03-04 15:09:45 +01:00
search_hb2 - > add_child ( categories ) ;
2020-03-06 18:00:16 +01:00
categories - > set_h_size_flags ( Control : : SIZE_EXPAND_FILL ) ;
2022-05-20 06:57:10 +02:00
categories - > set_clip_text ( true ) ;
2020-02-21 18:28:45 +01:00
categories - > connect ( " item_selected " , callable_mp ( this , & EditorAssetLibrary : : _rerun_search ) ) ;
2016-02-29 13:56:36 +01:00
2016-03-04 15:09:45 +01:00
search_hb2 - > add_child ( memnew ( VSeparator ) ) ;
2016-05-19 00:08:12 +02:00
search_hb2 - > add_child ( memnew ( Label ( TTR ( " Site: " ) + " " ) ) ) ;
2016-03-04 15:09:45 +01:00
repository = memnew ( OptionButton ) ;
2021-03-13 22:55:59 +01:00
_update_repository_options ( ) ;
2017-11-09 11:55:30 +01:00
2020-02-21 18:28:45 +01:00
repository - > connect ( " item_selected " , callable_mp ( this , & EditorAssetLibrary : : _repository_changed ) ) ;
2016-06-07 20:29:15 +02:00
2016-03-04 15:09:45 +01:00
search_hb2 - > add_child ( repository ) ;
2020-03-06 18:00:16 +01:00
repository - > set_h_size_flags ( Control : : SIZE_EXPAND_FILL ) ;
2022-05-20 06:57:10 +02:00
repository - > set_clip_text ( true ) ;
2016-03-04 15:09:45 +01:00
2016-06-08 15:17:16 +02:00
search_hb2 - > add_child ( memnew ( VSeparator ) ) ;
support = memnew ( MenuButton ) ;
search_hb2 - > add_child ( support ) ;
2019-08-28 06:27:26 +02:00
support - > set_text ( TTR ( " Support " ) ) ;
2021-03-07 20:51:40 +01:00
support - > get_popup ( ) - > set_hide_on_checkable_item_selection ( false ) ;
2022-12-31 05:50:12 +01:00
support - > get_popup ( ) - > add_check_item ( TTRGET ( support_text [ SUPPORT_OFFICIAL ] ) , SUPPORT_OFFICIAL ) ;
support - > get_popup ( ) - > add_check_item ( TTRGET ( support_text [ SUPPORT_COMMUNITY ] ) , SUPPORT_COMMUNITY ) ;
support - > get_popup ( ) - > add_check_item ( TTRGET ( support_text [ SUPPORT_TESTING ] ) , SUPPORT_TESTING ) ;
2016-06-08 15:17:16 +02:00
support - > get_popup ( ) - > set_item_checked ( SUPPORT_OFFICIAL , true ) ;
support - > get_popup ( ) - > set_item_checked ( SUPPORT_COMMUNITY , true ) ;
2020-02-21 18:28:45 +01:00
support - > get_popup ( ) - > connect ( " id_pressed " , callable_mp ( this , & EditorAssetLibrary : : _support_toggled ) ) ;
2016-06-08 15:17:16 +02:00
2016-03-04 15:09:45 +01:00
/////////
2017-08-04 21:41:31 +02:00
library_scroll_bg = memnew ( PanelContainer ) ;
2016-03-04 15:09:45 +01:00
library_main - > add_child ( library_scroll_bg ) ;
2020-03-06 18:00:16 +01:00
library_scroll_bg - > set_v_size_flags ( Control : : SIZE_EXPAND_FILL ) ;
2016-03-04 15:09:45 +01:00
library_scroll = memnew ( ScrollContainer ) ;
2021-12-07 17:15:18 +01:00
library_scroll - > set_horizontal_scroll_mode ( ScrollContainer : : SCROLL_MODE_DISABLED ) ;
2016-03-04 15:09:45 +01:00
library_scroll_bg - > add_child ( library_scroll ) ;
Ref < StyleBoxEmpty > border2 ;
2021-06-18 00:03:09 +02:00
border2 . instantiate ( ) ;
2023-01-19 17:14:09 +01:00
border2 - > set_content_margin_individual ( 15 * EDSCALE , 15 * EDSCALE , 35 * EDSCALE , 15 * EDSCALE ) ;
2016-03-04 15:09:45 +01:00
PanelContainer * library_vb_border = memnew ( PanelContainer ) ;
library_scroll - > add_child ( library_vb_border ) ;
2022-02-08 10:14:58 +01:00
library_vb_border - > add_theme_style_override ( " panel " , border2 ) ;
2020-03-06 18:00:16 +01:00
library_vb_border - > set_h_size_flags ( Control : : SIZE_EXPAND_FILL ) ;
2016-03-04 15:09:45 +01:00
library_vb = memnew ( VBoxContainer ) ;
2020-03-06 18:00:16 +01:00
library_vb - > set_h_size_flags ( Control : : SIZE_EXPAND_FILL ) ;
2016-03-04 15:09:45 +01:00
library_vb_border - > add_child ( library_vb ) ;
2024-01-30 17:35:46 +01:00
library_message_box = memnew ( VBoxContainer ) ;
library_message_box - > hide ( ) ;
library_vb - > add_child ( library_message_box ) ;
2019-10-26 01:07:02 +02:00
2024-01-30 17:35:46 +01:00
library_message = memnew ( Label ) ;
library_message - > set_horizontal_alignment ( HORIZONTAL_ALIGNMENT_CENTER ) ;
library_message_box - > add_child ( library_message ) ;
2022-05-04 11:49:11 +02:00
2024-01-30 17:35:46 +01:00
library_message_button = memnew ( Button ) ;
library_message_button - > set_h_size_flags ( SIZE_SHRINK_CENTER ) ;
2024-01-30 17:35:46 +01:00
library_message_button - > set_theme_type_variation ( " PanelBackgroundButton " ) ;
2024-01-30 17:35:46 +01:00
library_message_box - > add_child ( library_message_button ) ;
2022-05-04 11:49:11 +02:00
2016-03-04 15:09:45 +01:00
asset_top_page = memnew ( HBoxContainer ) ;
library_vb - > add_child ( asset_top_page ) ;
asset_items = memnew ( GridContainer ) ;
2022-07-02 22:15:42 +02:00
_update_asset_items_columns ( ) ;
2022-04-14 23:20:28 +02:00
asset_items - > add_theme_constant_override ( " h_separation " , 10 * EDSCALE ) ;
asset_items - > add_theme_constant_override ( " v_separation " , 10 * EDSCALE ) ;
2016-03-04 15:09:45 +01:00
library_vb - > add_child ( asset_items ) ;
asset_bottom_page = memnew ( HBoxContainer ) ;
library_vb - > add_child ( asset_bottom_page ) ;
request = memnew ( HTTPRequest ) ;
add_child ( request ) ;
2021-12-09 04:34:32 +01:00
setup_http_request ( request ) ;
2020-02-21 18:28:45 +01:00
request - > connect ( " request_completed " , callable_mp ( this , & EditorAssetLibrary : : _http_request_completed ) ) ;
2016-02-29 13:56:36 +01:00
2016-03-04 15:09:45 +01:00
last_queue_id = 0 ;
2016-02-29 13:56:36 +01:00
2022-02-08 10:14:58 +01:00
library_vb - > add_theme_constant_override ( " separation " , 20 * EDSCALE ) ;
2016-02-29 13:56:36 +01:00
2016-03-05 16:24:12 +01:00
error_hb = memnew ( HBoxContainer ) ;
library_main - > add_child ( error_hb ) ;
error_label = memnew ( Label ) ;
error_hb - > add_child ( error_label ) ;
2018-02-25 17:04:16 +01:00
error_tr = memnew ( TextureRect ) ;
2019-12-16 02:24:02 +01:00
error_tr - > set_v_size_flags ( Control : : SIZE_SHRINK_CENTER ) ;
2018-02-25 17:04:16 +01:00
error_hb - > add_child ( error_tr ) ;
2016-03-05 16:24:12 +01:00
2020-04-02 01:20:12 +02:00
description = nullptr ;
2016-02-29 13:56:36 +01:00
2016-03-05 16:24:12 +01:00
set_process ( true ) ;
2022-01-11 14:59:52 +01:00
set_process_shortcut_input ( true ) ; // Global shortcuts since there is no main element to be focused.
2016-03-12 14:44:12 +01:00
downloads_scroll = memnew ( ScrollContainer ) ;
2021-12-07 17:15:18 +01:00
downloads_scroll - > set_vertical_scroll_mode ( ScrollContainer : : SCROLL_MODE_DISABLED ) ;
2016-03-12 14:44:12 +01:00
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 ) ;
2022-07-04 23:26:26 +02:00
asset_open - > add_filter ( " *.zip " , TTR ( " Assets ZIP File " ) ) ;
2020-03-06 18:00:16 +01:00
asset_open - > set_file_mode ( EditorFileDialog : : FILE_MODE_OPEN_FILE ) ;
2016-03-12 14:44:12 +01:00
add_child ( asset_open ) ;
2020-02-21 18:28:45 +01:00
asset_open - > connect ( " file_selected " , callable_mp ( this , & EditorAssetLibrary : : _asset_file_selected ) ) ;
2016-03-12 14:44:12 +01:00
2020-04-02 01:20:12 +02:00
asset_installer = nullptr ;
2016-02-29 13:56:36 +01:00
}
///////
2022-06-29 19:27:27 +02:00
bool AssetLibraryEditorPlugin : : is_available ( ) {
2022-08-28 20:27:45 +02:00
# ifdef WEB_ENABLED
2022-06-29 19:27:27 +02:00
// Asset Library can't work on Web editor for now as most assets are sourced
// directly from GitHub which does not set CORS.
return false ;
# else
2022-09-07 00:46:12 +02:00
return StreamPeerTLS : : is_available ( ) ;
2022-06-29 19:27:27 +02:00
# endif
}
2016-06-07 20:29:15 +02:00
void AssetLibraryEditorPlugin : : make_visible ( bool p_visible ) {
2016-02-29 13:56:36 +01:00
if ( p_visible ) {
addon_library - > show ( ) ;
} else {
addon_library - > hide ( ) ;
}
}
2022-01-27 10:36:51 +01:00
AssetLibraryEditorPlugin : : AssetLibraryEditorPlugin ( ) {
2016-06-08 14:25:47 +02:00
addon_library = memnew ( EditorAssetLibrary ) ;
2016-02-29 13:56:36 +01:00
addon_library - > set_v_size_flags ( Control : : SIZE_EXPAND_FILL ) ;
2022-09-07 01:30:54 +02:00
EditorNode : : get_singleton ( ) - > get_main_screen_control ( ) - > add_child ( addon_library ) ;
2022-03-19 01:02:57 +01:00
addon_library - > set_anchors_and_offsets_preset ( Control : : PRESET_FULL_RECT ) ;
2016-02-29 13:56:36 +01:00
addon_library - > hide ( ) ;
}
2016-06-07 20:29:15 +02:00
AssetLibraryEditorPlugin : : ~ AssetLibraryEditorPlugin ( ) {
2016-02-29 13:56:36 +01:00
}