2014-02-10 02:10:30 +01:00
/*************************************************************************/
/* property_editor.cpp */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
2017-08-27 14:16:55 +02:00
/* https://godotengine.org */
2014-02-10 02:10:30 +01:00
/*************************************************************************/
2018-01-01 14:40:08 +01:00
/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */
/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */
2014-02-10 02:10:30 +01:00
/* */
/* 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
2014-02-10 02:10:30 +01:00
# include "property_editor.h"
2017-01-16 08:04:19 +01:00
2017-08-26 17:46:49 +02:00
# include "core/class_db.h"
# include "core/io/image_loader.h"
# include "core/io/marshalls.h"
# include "core/io/resource_loader.h"
# include "core/os/input.h"
# include "core/os/keyboard.h"
# include "core/pair.h"
# include "core/print_string.h"
# include "core/project_settings.h"
# include "editor/array_property_edit.h"
# include "editor/create_dialog.h"
2017-10-17 16:39:31 +02:00
# include "editor/dictionary_property_edit.h"
2017-08-26 17:46:49 +02:00
# include "editor/editor_export.h"
# include "editor/editor_file_system.h"
# include "editor/editor_help.h"
# include "editor/editor_node.h"
# include "editor/editor_settings.h"
# include "editor/multi_node_edit.h"
# include "editor/property_selector.h"
2017-03-05 16:44:50 +01:00
# include "scene/gui/label.h"
# include "scene/main/viewport.h"
2014-02-10 02:10:30 +01:00
# include "scene/resources/font.h"
2015-10-10 14:09:09 +02:00
# include "scene/resources/packed_scene.h"
2017-03-05 16:44:50 +01:00
# include "scene/scene_string_names.h"
2014-02-10 02:10:30 +01:00
2017-09-22 14:20:28 +02:00
void EditorResourceConversionPlugin : : _bind_methods ( ) {
MethodInfo mi ;
mi . name = " _convert " ;
mi . return_val . type = Variant : : OBJECT ;
mi . return_val . class_name = " Resource " ;
mi . return_val . hint = PROPERTY_HINT_RESOURCE_TYPE ;
mi . return_val . hint_string = " Resource " ;
mi . arguments . push_back ( mi . return_val ) ;
mi . arguments [ 0 ] . name = " resource " ;
BIND_VMETHOD ( mi )
mi . name = " _handles " ;
mi . return_val = PropertyInfo ( Variant : : BOOL , " " ) ;
2017-12-10 15:10:54 +01:00
BIND_VMETHOD ( MethodInfo ( Variant : : STRING , " _converts_to " ) ) ;
2017-09-22 14:20:28 +02:00
}
String EditorResourceConversionPlugin : : converts_to ( ) const {
if ( get_script_instance ( ) )
return get_script_instance ( ) - > call ( " _converts_to " ) ;
return " " ;
}
bool EditorResourceConversionPlugin : : handles ( const Ref < Resource > & p_resource ) const {
if ( get_script_instance ( ) )
return get_script_instance ( ) - > call ( " _handles " , p_resource ) ;
return false ;
}
Ref < Resource > EditorResourceConversionPlugin : : convert ( const Ref < Resource > & p_resource ) {
if ( get_script_instance ( ) )
return get_script_instance ( ) - > call ( " _convert " , p_resource ) ;
return Ref < Resource > ( ) ;
}
2014-02-10 02:10:30 +01:00
void CustomPropertyEditor : : _notification ( int p_what ) {
2015-08-30 02:09:11 +02:00
2017-03-05 16:44:50 +01:00
if ( p_what = = NOTIFICATION_DRAW ) {
2015-08-30 02:09:11 +02:00
2014-02-10 02:10:30 +01:00
RID ci = get_canvas_item ( ) ;
2017-03-05 16:44:50 +01:00
get_stylebox ( " panel " , " PopupMenu " ) - > draw ( ci , Rect2 ( Point2 ( ) , get_size ( ) ) ) ;
2014-02-27 15:16:00 +01:00
}
2017-06-18 22:16:54 +02:00
if ( p_what = = MainLoop : : NOTIFICATION_WM_QUIT_REQUEST ) {
hide ( ) ;
}
2014-02-10 02:10:30 +01:00
}
void CustomPropertyEditor : : _menu_option ( int p_which ) {
2017-03-05 16:44:50 +01:00
switch ( type ) {
2014-02-10 02:10:30 +01:00
case Variant : : INT : {
2017-03-05 16:44:50 +01:00
if ( hint = = PROPERTY_HINT_FLAGS ) {
2014-02-10 02:10:30 +01:00
int val = v ;
2017-03-05 16:44:50 +01:00
if ( val & ( 1 < < p_which ) ) {
2014-02-10 02:10:30 +01:00
2017-03-05 16:44:50 +01:00
val & = ~ ( 1 < < p_which ) ;
2014-02-10 02:10:30 +01:00
} else {
2017-03-05 16:44:50 +01:00
val | = ( 1 < < p_which ) ;
2014-02-10 02:10:30 +01:00
}
2017-03-05 16:44:50 +01:00
v = val ;
2014-02-10 02:10:30 +01:00
emit_signal ( " variant_changed " ) ;
2017-03-05 16:44:50 +01:00
} else if ( hint = = PROPERTY_HINT_ENUM ) {
2016-08-26 22:34:25 +02:00
2017-03-05 16:44:50 +01:00
v = p_which ;
2016-08-26 22:34:25 +02:00
emit_signal ( " variant_changed " ) ;
2014-02-10 02:10:30 +01:00
}
} break ;
2016-08-31 17:49:45 +02:00
case Variant : : STRING : {
2017-03-05 16:44:50 +01:00
if ( hint = = PROPERTY_HINT_ENUM ) {
2016-08-31 17:49:45 +02:00
2017-03-05 16:44:50 +01:00
v = hint_text . get_slice ( " , " , p_which ) ;
2016-08-31 17:49:45 +02:00
emit_signal ( " variant_changed " ) ;
}
} break ;
2014-02-10 02:10:30 +01:00
case Variant : : OBJECT : {
2017-03-05 16:44:50 +01:00
switch ( p_which ) {
2014-02-10 02:10:30 +01:00
case OBJ_MENU_LOAD : {
2015-06-06 14:44:38 +02:00
file - > set_mode ( EditorFileDialog : : MODE_OPEN_FILE ) ;
2017-03-05 16:44:50 +01:00
String type = ( hint = = PROPERTY_HINT_RESOURCE_TYPE ) ? hint_text : String ( ) ;
2014-02-10 02:10:30 +01:00
2015-11-28 01:11:20 +01:00
List < String > extensions ;
2017-03-05 16:44:50 +01:00
for ( int i = 0 ; i < type . get_slice_count ( " , " ) ; i + + ) {
2015-11-28 01:11:20 +01:00
2017-03-05 16:44:50 +01:00
ResourceLoader : : get_recognized_extensions_for_type ( type . get_slice ( " , " , i ) , & extensions ) ;
2015-11-28 01:11:20 +01:00
}
Set < String > valid_extensions ;
2017-03-05 16:44:50 +01:00
for ( List < String > : : Element * E = extensions . front ( ) ; E ; E = E - > next ( ) ) {
2015-11-28 01:11:20 +01:00
valid_extensions . insert ( E - > get ( ) ) ;
}
file - > clear_filters ( ) ;
2017-03-05 16:44:50 +01:00
for ( Set < String > : : Element * E = valid_extensions . front ( ) ; E ; E = E - > next ( ) ) {
2014-02-10 02:10:30 +01:00
2017-03-05 16:44:50 +01:00
file - > add_filter ( " *. " + E - > get ( ) + " ; " + E - > get ( ) . to_upper ( ) ) ;
2014-02-10 02:10:30 +01:00
}
file - > popup_centered_ratio ( ) ;
} break ;
case OBJ_MENU_EDIT : {
2017-03-05 16:44:50 +01:00
RefPtr RefPtr = v ;
2014-02-10 02:10:30 +01:00
if ( ! RefPtr . is_null ( ) ) {
emit_signal ( " resource_edit_request " ) ;
hide ( ) ;
}
} break ;
case OBJ_MENU_CLEAR : {
2017-03-05 16:44:50 +01:00
v = Variant ( ) ;
2014-02-10 02:10:30 +01:00
emit_signal ( " variant_changed " ) ;
hide ( ) ;
} break ;
case OBJ_MENU_MAKE_UNIQUE : {
2017-03-05 16:44:50 +01:00
RefPtr RefPtr = v ;
2014-02-10 02:10:30 +01:00
Ref < Resource > res_orig = RefPtr ;
if ( res_orig . is_null ( ) )
return ;
List < PropertyInfo > property_list ;
res_orig - > get_property_list ( & property_list ) ;
2017-03-05 16:44:50 +01:00
List < Pair < String , Variant > > propvalues ;
2014-02-10 02:10:30 +01:00
2017-03-05 16:44:50 +01:00
for ( List < PropertyInfo > : : Element * E = property_list . front ( ) ; E ; E = E - > next ( ) ) {
2014-02-10 02:10:30 +01:00
2017-03-05 16:44:50 +01:00
Pair < String , Variant > p ;
2014-02-10 02:10:30 +01:00
PropertyInfo & pi = E - > get ( ) ;
2017-03-05 16:44:50 +01:00
if ( pi . usage & PROPERTY_USAGE_STORAGE ) {
2014-02-10 02:10:30 +01:00
2017-03-05 16:44:50 +01:00
p . first = pi . name ;
p . second = res_orig - > get ( pi . name ) ;
2014-02-10 02:10:30 +01:00
}
propvalues . push_back ( p ) ;
}
2017-01-03 03:03:46 +01:00
String orig_type = res_orig - > get_class ( ) ;
2015-01-03 20:52:37 +01:00
2017-03-05 16:44:50 +01:00
Object * inst = ClassDB : : instance ( orig_type ) ;
2014-02-10 02:10:30 +01:00
2017-08-24 22:58:51 +02:00
Ref < Resource > res = Ref < Resource > ( Object : : cast_to < Resource > ( inst ) ) ;
2014-02-10 02:10:30 +01:00
ERR_FAIL_COND ( res . is_null ( ) ) ;
2017-03-05 16:44:50 +01:00
for ( List < Pair < String , Variant > > : : Element * E = propvalues . front ( ) ; E ; E = E - > next ( ) ) {
2014-02-10 02:10:30 +01:00
2017-03-05 16:44:50 +01:00
Pair < String , Variant > & p = E - > get ( ) ;
res - > set ( p . first , p . second ) ;
2014-02-10 02:10:30 +01:00
}
2017-03-05 16:44:50 +01:00
v = res . get_ref_ptr ( ) ;
2014-02-10 02:10:30 +01:00
emit_signal ( " variant_changed " ) ;
hide ( ) ;
} break ;
case OBJ_MENU_COPY : {
EditorSettings : : get_singleton ( ) - > set_resource_clipboard ( v ) ;
} break ;
case OBJ_MENU_PASTE : {
2017-03-05 16:44:50 +01:00
v = EditorSettings : : get_singleton ( ) - > get_resource_clipboard ( ) ;
2014-02-10 02:10:30 +01:00
emit_signal ( " variant_changed " ) ;
} break ;
2016-09-13 00:31:07 +02:00
case OBJ_MENU_NEW_SCRIPT : {
2017-08-24 22:58:51 +02:00
if ( Object : : cast_to < Node > ( owner ) )
EditorNode : : get_singleton ( ) - > get_scene_tree_dock ( ) - > open_script_dialog ( Object : : cast_to < Node > ( owner ) ) ;
2016-09-13 00:31:07 +02:00
} break ;
2017-01-14 18:14:46 +01:00
case OBJ_MENU_SHOW_IN_FILE_SYSTEM : {
2017-03-05 16:44:50 +01:00
RES r = v ;
FileSystemDock * file_system_dock = EditorNode : : get_singleton ( ) - > get_filesystem_dock ( ) ;
2017-01-14 18:14:46 +01:00
file_system_dock - > navigate_to_path ( r - > get_path ( ) ) ;
// Ensure that the FileSystem dock is visible.
2017-03-05 16:44:50 +01:00
TabContainer * tab_container = ( TabContainer * ) file_system_dock - > get_parent_control ( ) ;
2017-01-14 18:14:46 +01:00
tab_container - > set_current_tab ( file_system_dock - > get_position_in_parent ( ) ) ;
} break ;
2014-02-10 02:10:30 +01:00
default : {
2017-09-22 14:20:28 +02:00
if ( p_which > = CONVERT_BASE_ID ) {
int to_type = p_which - CONVERT_BASE_ID ;
Vector < Ref < EditorResourceConversionPlugin > > conversions = EditorNode : : get_singleton ( ) - > find_resource_conversion_plugin ( RES ( v ) ) ;
ERR_FAIL_INDEX ( to_type , conversions . size ( ) ) ;
Ref < Resource > new_res = conversions [ to_type ] - > convert ( v ) ;
v = new_res ;
emit_signal ( " variant_changed " ) ;
break ;
}
2017-03-05 16:44:50 +01:00
ERR_FAIL_COND ( inheritors_array . empty ( ) ) ;
2014-02-10 02:10:30 +01:00
2017-03-05 16:44:50 +01:00
String intype = inheritors_array [ p_which - TYPE_BASE_ID ] ;
2015-01-03 20:52:37 +01:00
2017-03-05 16:44:50 +01:00
if ( intype = = " ViewportTexture " ) {
2017-01-10 05:04:31 +01:00
scene_tree - > set_title ( TTR ( " Pick a Viewport " ) ) ;
scene_tree - > popup_centered_ratio ( ) ;
2017-03-05 16:44:50 +01:00
picking_viewport = true ;
2017-01-10 05:04:31 +01:00
return ;
}
2017-01-03 03:03:46 +01:00
Object * obj = ClassDB : : instance ( intype ) ;
2018-02-25 01:41:26 +01:00
if ( ! obj ) {
obj = EditorNode : : get_editor_data ( ) . instance_custom_type ( intype , " Resource " ) ;
}
2017-03-05 16:44:50 +01:00
ERR_BREAK ( ! obj ) ;
2017-08-24 22:58:51 +02:00
Resource * res = Object : : cast_to < Resource > ( obj ) ;
2017-03-05 16:44:50 +01:00
ERR_BREAK ( ! res ) ;
if ( owner & & hint = = PROPERTY_HINT_RESOURCE_TYPE & & hint_text = = " Script " ) {
2016-08-08 06:21:22 +02:00
//make visual script the right type
2017-03-05 16:44:50 +01:00
res - > call ( " set_instance_base_type " , owner - > get_class ( ) ) ;
2016-08-08 06:21:22 +02:00
}
2014-02-10 02:10:30 +01:00
2017-03-05 16:44:50 +01:00
v = Ref < Resource > ( res ) . get_ref_ptr ( ) ;
2014-02-10 02:10:30 +01:00
emit_signal ( " variant_changed " ) ;
} break ;
}
} break ;
2017-03-05 16:44:50 +01:00
default : { }
2014-02-10 02:10:30 +01:00
}
}
2016-05-11 16:46:08 +02:00
void CustomPropertyEditor : : hide_menu ( ) {
menu - > hide ( ) ;
}
2014-02-10 02:10:30 +01:00
Variant CustomPropertyEditor : : get_variant ( ) const {
2015-08-30 02:09:11 +02:00
return v ;
2014-02-10 02:10:30 +01:00
}
2017-03-02 10:42:05 +01:00
2014-02-10 02:10:30 +01:00
String CustomPropertyEditor : : get_name ( ) const {
2015-08-30 02:09:11 +02:00
2014-02-10 02:10:30 +01:00
return name ;
}
2017-03-05 16:44:50 +01:00
bool CustomPropertyEditor : : edit ( Object * p_owner , const String & p_name , Variant : : Type p_type , const Variant & p_variant , int p_hint , String p_hint_text ) {
2014-02-10 02:10:30 +01:00
2017-03-05 16:44:50 +01:00
owner = p_owner ;
updating = true ;
name = p_name ;
v = p_variant ;
2017-03-02 10:42:05 +01:00
field_names . clear ( ) ;
2017-03-05 16:44:50 +01:00
hint = p_hint ;
hint_text = p_hint_text ;
2014-02-10 02:10:30 +01:00
type_button - > hide ( ) ;
2016-06-08 03:08:12 +02:00
if ( color_picker )
color_picker - > hide ( ) ;
2014-02-10 02:10:30 +01:00
texture_preview - > hide ( ) ;
inheritors_array . clear ( ) ;
text_edit - > hide ( ) ;
easing_draw - > hide ( ) ;
2015-08-30 02:09:11 +02:00
spinbox - > hide ( ) ;
slider - > hide ( ) ;
2017-12-25 11:31:53 +01:00
menu - > clear ( ) ;
menu - > set_size ( Size2 ( 1 , 1 ) * EDSCALE ) ;
2015-08-30 02:09:11 +02:00
2017-03-05 16:44:50 +01:00
for ( int i = 0 ; i < MAX_VALUE_EDITORS ; i + + ) {
2015-08-30 02:09:11 +02:00
2014-02-10 02:10:30 +01:00
value_editor [ i ] - > hide ( ) ;
value_label [ i ] - > hide ( ) ;
2017-03-05 16:44:50 +01:00
if ( i < 4 )
2016-01-23 15:20:54 +01:00
scroll [ i ] - > hide ( ) ;
2014-02-10 02:10:30 +01:00
}
2017-03-05 16:44:50 +01:00
for ( int i = 0 ; i < MAX_ACTION_BUTTONS ; i + + ) {
2015-08-30 02:09:11 +02:00
action_buttons [ i ] - > hide ( ) ;
2014-02-10 02:10:30 +01:00
}
2017-01-11 02:20:57 +01:00
checks20gc - > hide ( ) ;
2017-03-05 16:44:50 +01:00
for ( int i = 0 ; i < 20 ; i + + )
2014-02-10 02:10:30 +01:00
checks20 [ i ] - > hide ( ) ;
2017-03-05 16:44:50 +01:00
type = ( p_variant . get_type ( ) ! = Variant : : NIL & & p_variant . get_type ( ) ! = Variant : : _RID & & p_type ! = Variant : : OBJECT ) ? p_variant . get_type ( ) : p_type ;
2014-02-10 02:10:30 +01:00
2017-03-05 16:44:50 +01:00
switch ( type ) {
2015-08-30 02:09:11 +02:00
2016-08-26 22:34:25 +02:00
case Variant : : BOOL : {
2017-01-11 02:20:57 +01:00
checks20gc - > show ( ) ;
2017-03-05 16:44:50 +01:00
CheckBox * c = checks20 [ 0 ] ;
2016-08-26 22:34:25 +02:00
c - > set_text ( " True " ) ;
2017-08-08 04:55:24 +02:00
checks20gc - > set_position ( Vector2 ( 4 , 4 ) * EDSCALE ) ;
2016-08-26 22:34:25 +02:00
c - > set_pressed ( v ) ;
c - > show ( ) ;
2017-01-11 02:20:57 +01:00
checks20gc - > set_size ( checks20gc - > get_minimum_size ( ) ) ;
2017-05-09 19:35:48 +02:00
set_size ( checks20gc - > get_position ( ) + checks20gc - > get_size ( ) + c - > get_size ( ) + Vector2 ( 4 , 4 ) * EDSCALE ) ;
2016-08-26 22:34:25 +02:00
} break ;
2014-02-10 02:10:30 +01:00
case Variant : : INT :
case Variant : : REAL : {
2017-03-05 16:44:50 +01:00
if ( hint = = PROPERTY_HINT_RANGE ) {
2015-08-30 02:09:11 +02:00
int c = hint_text . get_slice_count ( " , " ) ;
2017-10-14 21:20:04 +02:00
float min = 0 , max = 100 , step = type = = Variant : : REAL ? .01 : 1 ;
2017-03-05 16:44:50 +01:00
if ( c > = 1 ) {
2015-08-30 02:09:11 +02:00
2017-03-05 16:44:50 +01:00
if ( ! hint_text . get_slice ( " , " , 0 ) . empty ( ) )
min = hint_text . get_slice ( " , " , 0 ) . to_double ( ) ;
2015-08-30 02:09:11 +02:00
}
2017-03-05 16:44:50 +01:00
if ( c > = 2 ) {
2015-08-30 02:09:11 +02:00
2017-03-05 16:44:50 +01:00
if ( ! hint_text . get_slice ( " , " , 1 ) . empty ( ) )
max = hint_text . get_slice ( " , " , 1 ) . to_double ( ) ;
2015-08-30 02:09:11 +02:00
}
2017-03-05 16:44:50 +01:00
if ( c > = 3 ) {
2015-08-30 02:09:11 +02:00
2017-03-05 16:44:50 +01:00
if ( ! hint_text . get_slice ( " , " , 2 ) . empty ( ) )
step = hint_text . get_slice ( " , " , 2 ) . to_double ( ) ;
2015-08-30 02:09:11 +02:00
}
2017-03-05 16:44:50 +01:00
if ( c > = 4 & & hint_text . get_slice ( " , " , 3 ) = = " slider " ) {
2015-08-30 02:09:11 +02:00
slider - > set_min ( min ) ;
slider - > set_max ( max ) ;
2016-10-10 12:20:52 +02:00
slider - > set_step ( step ) ;
2017-01-04 05:16:14 +01:00
slider - > set_value ( v ) ;
2015-08-30 02:09:11 +02:00
slider - > show ( ) ;
2017-03-05 16:44:50 +01:00
set_size ( Size2 ( 110 , 30 ) * EDSCALE ) ;
2015-08-30 02:09:11 +02:00
} else {
spinbox - > set_min ( min ) ;
spinbox - > set_max ( max ) ;
2016-10-10 12:20:52 +02:00
spinbox - > set_step ( step ) ;
2017-01-04 05:16:14 +01:00
spinbox - > set_value ( v ) ;
2015-08-30 02:09:11 +02:00
spinbox - > show ( ) ;
2017-03-05 16:44:50 +01:00
set_size ( Size2 ( 70 , 35 ) * EDSCALE ) ;
2015-08-30 02:09:11 +02:00
}
2017-03-05 16:44:50 +01:00
} else if ( hint = = PROPERTY_HINT_ENUM ) {
2016-08-26 22:34:25 +02:00
Vector < String > options = hint_text . split ( " , " ) ;
2017-03-05 16:44:50 +01:00
for ( int i = 0 ; i < options . size ( ) ; i + + ) {
2017-11-15 19:50:37 +01:00
if ( options [ i ] . find ( " : " ) ! = - 1 ) {
menu - > add_item ( options [ i ] . get_slicec ( ' : ' , 0 ) , options [ i ] . get_slicec ( ' : ' , 1 ) . to_int ( ) ) ;
} else {
menu - > add_item ( options [ i ] , i ) ;
}
2016-08-26 22:34:25 +02:00
}
2017-03-29 17:29:38 +02:00
menu - > set_position ( get_position ( ) ) ;
2016-08-26 22:34:25 +02:00
menu - > popup ( ) ;
hide ( ) ;
2017-03-05 16:44:50 +01:00
updating = false ;
2016-08-26 22:34:25 +02:00
return false ;
2017-03-05 16:44:50 +01:00
} else if ( hint = = PROPERTY_HINT_LAYERS_2D_PHYSICS | | hint = = PROPERTY_HINT_LAYERS_2D_RENDER | | hint = = PROPERTY_HINT_LAYERS_3D_PHYSICS | | hint = = PROPERTY_HINT_LAYERS_3D_RENDER ) {
2016-08-26 22:34:25 +02:00
2017-01-11 02:20:57 +01:00
String basename ;
switch ( hint ) {
2017-03-05 16:44:50 +01:00
case PROPERTY_HINT_LAYERS_2D_RENDER :
basename = " layer_names/2d_render " ;
break ;
case PROPERTY_HINT_LAYERS_2D_PHYSICS :
basename = " layer_names/2d_physics " ;
break ;
case PROPERTY_HINT_LAYERS_3D_RENDER :
basename = " layer_names/3d_render " ;
break ;
case PROPERTY_HINT_LAYERS_3D_PHYSICS :
basename = " layer_names/3d_physics " ;
break ;
2017-01-11 02:20:57 +01:00
}
checks20gc - > show ( ) ;
2014-02-10 02:10:30 +01:00
uint32_t flgs = v ;
2017-03-05 16:44:50 +01:00
for ( int i = 0 ; i < 2 ; i + + ) {
2014-02-10 02:10:30 +01:00
2017-03-05 16:44:50 +01:00
Point2 ofs ( 4 , 4 ) ;
ofs . y + = 22 * i ;
for ( int j = 0 ; j < 10 ; j + + ) {
2014-02-10 02:10:30 +01:00
2017-03-05 16:44:50 +01:00
int idx = i * 10 + j ;
CheckBox * c = checks20 [ idx ] ;
2017-07-19 22:00:46 +02:00
c - > set_text ( ProjectSettings : : get_singleton ( ) - > get ( basename + " /layer_ " + itos ( idx + 1 ) ) ) ;
2017-03-05 16:44:50 +01:00
c - > set_pressed ( flgs & ( 1 < < ( i * 10 + j ) ) ) ;
2014-02-10 02:10:30 +01:00
c - > show ( ) ;
}
}
2017-01-11 02:20:57 +01:00
show ( ) ;
2017-12-09 17:42:24 +01:00
checks20gc - > set_position ( Vector2 ( 4 , 4 ) * EDSCALE ) ;
2017-01-11 02:20:57 +01:00
checks20gc - > set_size ( checks20gc - > get_minimum_size ( ) ) ;
2017-03-29 17:29:38 +02:00
set_size ( Vector2 ( 4 , 4 ) * EDSCALE + checks20gc - > get_position ( ) + checks20gc - > get_size ( ) ) ;
2014-02-10 02:10:30 +01:00
2017-03-05 16:44:50 +01:00
} else if ( hint = = PROPERTY_HINT_EXP_EASING ) {
2014-02-10 02:10:30 +01:00
2017-08-08 04:55:24 +02:00
easing_draw - > set_anchor_and_margin ( MARGIN_LEFT , ANCHOR_BEGIN , 5 * EDSCALE ) ;
2017-07-06 09:16:27 +02:00
easing_draw - > set_anchor_and_margin ( MARGIN_RIGHT , ANCHOR_END , - 5 * EDSCALE ) ;
2017-08-08 04:55:24 +02:00
easing_draw - > set_anchor_and_margin ( MARGIN_TOP , ANCHOR_BEGIN , 5 * EDSCALE ) ;
2017-07-06 09:16:27 +02:00
easing_draw - > set_anchor_and_margin ( MARGIN_BOTTOM , ANCHOR_END , - 30 * EDSCALE ) ;
2017-08-08 04:55:24 +02:00
type_button - > set_anchor_and_margin ( MARGIN_LEFT , ANCHOR_BEGIN , 3 * EDSCALE ) ;
2017-07-06 09:16:27 +02:00
type_button - > set_anchor_and_margin ( MARGIN_RIGHT , ANCHOR_END , - 3 * EDSCALE ) ;
type_button - > set_anchor_and_margin ( MARGIN_TOP , ANCHOR_END , - 25 * EDSCALE ) ;
type_button - > set_anchor_and_margin ( MARGIN_BOTTOM , ANCHOR_END , - 7 * EDSCALE ) ;
2018-04-22 19:36:01 +02:00
type_button - > set_text ( TTR ( " Preset... " ) ) ;
2014-02-10 02:10:30 +01:00
type_button - > get_popup ( ) - > clear ( ) ;
2017-03-05 16:44:50 +01:00
type_button - > get_popup ( ) - > add_item ( TTR ( " Linear " ) , EASING_LINEAR ) ;
type_button - > get_popup ( ) - > add_item ( TTR ( " Ease In " ) , EASING_EASE_IN ) ;
type_button - > get_popup ( ) - > add_item ( TTR ( " Ease Out " ) , EASING_EASE_OUT ) ;
if ( hint_text ! = " attenuation " ) {
type_button - > get_popup ( ) - > add_item ( TTR ( " Zero " ) , EASING_ZERO ) ;
type_button - > get_popup ( ) - > add_item ( TTR ( " Easing In-Out " ) , EASING_IN_OUT ) ;
type_button - > get_popup ( ) - > add_item ( TTR ( " Easing Out-In " ) , EASING_OUT_IN ) ;
2014-02-10 02:10:30 +01:00
}
type_button - > show ( ) ;
easing_draw - > show ( ) ;
2017-03-05 16:44:50 +01:00
set_size ( Size2 ( 200 , 150 ) * EDSCALE ) ;
} else if ( hint = = PROPERTY_HINT_FLAGS ) {
2014-02-10 02:10:30 +01:00
Vector < String > flags = hint_text . split ( " , " ) ;
2017-03-05 16:44:50 +01:00
for ( int i = 0 ; i < flags . size ( ) ; i + + ) {
2014-02-10 02:10:30 +01:00
String flag = flags [ i ] ;
2017-03-05 16:44:50 +01:00
if ( flag = = " " )
2014-02-10 02:10:30 +01:00
continue ;
2017-03-05 16:44:50 +01:00
menu - > add_check_item ( flag , i ) ;
2014-02-10 02:10:30 +01:00
int f = v ;
2017-03-05 16:44:50 +01:00
if ( f & ( 1 < < i ) )
menu - > set_item_checked ( menu - > get_item_index ( i ) , true ) ;
2014-02-10 02:10:30 +01:00
}
2017-03-29 17:29:38 +02:00
menu - > set_position ( get_position ( ) ) ;
2014-02-10 02:10:30 +01:00
menu - > popup ( ) ;
hide ( ) ;
2017-03-05 16:44:50 +01:00
updating = false ;
2014-02-10 02:10:30 +01:00
return false ;
} else {
List < String > names ;
names . push_back ( " value: " ) ;
2017-03-05 16:44:50 +01:00
config_value_editors ( 1 , 1 , 50 , names ) ;
value_editor [ 0 ] - > set_text ( String : : num ( v ) ) ;
2014-02-10 02:10:30 +01:00
}
} break ;
case Variant : : STRING : {
2017-03-05 16:44:50 +01:00
if ( hint = = PROPERTY_HINT_FILE | | hint = = PROPERTY_HINT_GLOBAL_FILE ) {
2014-02-10 02:10:30 +01:00
List < String > names ;
2018-04-22 19:36:01 +02:00
names . push_back ( TTR ( " File... " ) ) ;
2016-05-04 03:25:37 +02:00
names . push_back ( TTR ( " Clear " ) ) ;
2014-02-10 02:10:30 +01:00
config_action_buttons ( names ) ;
2017-03-05 16:44:50 +01:00
} else if ( hint = = PROPERTY_HINT_DIR | | hint = = PROPERTY_HINT_GLOBAL_DIR ) {
2014-02-10 02:10:30 +01:00
List < String > names ;
2018-04-22 19:36:01 +02:00
names . push_back ( TTR ( " Dir... " ) ) ;
2016-05-04 03:25:37 +02:00
names . push_back ( TTR ( " Clear " ) ) ;
2014-02-10 02:10:30 +01:00
config_action_buttons ( names ) ;
2017-03-05 16:44:50 +01:00
} else if ( hint = = PROPERTY_HINT_ENUM ) {
2014-02-10 02:10:30 +01:00
2016-08-31 17:49:45 +02:00
Vector < String > options = hint_text . split ( " , " ) ;
2017-03-05 16:44:50 +01:00
for ( int i = 0 ; i < options . size ( ) ; i + + ) {
menu - > add_item ( options [ i ] , i ) ;
2016-08-31 17:49:45 +02:00
}
2017-03-29 17:29:38 +02:00
menu - > set_position ( get_position ( ) ) ;
2016-08-31 17:49:45 +02:00
menu - > popup ( ) ;
hide ( ) ;
2017-03-05 16:44:50 +01:00
updating = false ;
2016-08-31 17:49:45 +02:00
return false ;
2014-02-10 02:10:30 +01:00
2017-03-05 16:44:50 +01:00
} else if ( hint = = PROPERTY_HINT_MULTILINE_TEXT ) {
2014-02-10 02:10:30 +01:00
text_edit - > show ( ) ;
text_edit - > set_text ( v ) ;
2017-12-16 01:46:36 +01:00
text_edit - > deselect ( ) ;
2014-02-10 02:10:30 +01:00
2017-03-05 16:44:50 +01:00
int button_margin = get_constant ( " button_margin " , " Dialogs " ) ;
int margin = get_constant ( " margin " , " Dialogs " ) ;
2014-02-10 02:10:30 +01:00
2017-03-05 16:44:50 +01:00
action_buttons [ 0 ] - > set_anchor ( MARGIN_LEFT , ANCHOR_END ) ;
action_buttons [ 0 ] - > set_anchor ( MARGIN_TOP , ANCHOR_END ) ;
action_buttons [ 0 ] - > set_anchor ( MARGIN_RIGHT , ANCHOR_END ) ;
action_buttons [ 0 ] - > set_anchor ( MARGIN_BOTTOM , ANCHOR_END ) ;
2017-07-06 09:16:27 +02:00
action_buttons [ 0 ] - > set_begin ( Point2 ( - 70 * EDSCALE , - button_margin + 5 * EDSCALE ) ) ;
action_buttons [ 0 ] - > set_end ( Point2 ( - margin , - margin ) ) ;
2016-05-04 03:25:37 +02:00
action_buttons [ 0 ] - > set_text ( TTR ( " Close " ) ) ;
2014-02-10 02:10:30 +01:00
action_buttons [ 0 ] - > show ( ) ;
2017-03-05 16:44:50 +01:00
} else if ( hint = = PROPERTY_HINT_TYPE_STRING ) {
2016-08-03 16:28:20 +02:00
if ( ! create_dialog ) {
2017-03-05 16:44:50 +01:00
create_dialog = memnew ( CreateDialog ) ;
create_dialog - > connect ( " create " , this , " _create_dialog_callback " ) ;
2016-08-03 16:28:20 +02:00
add_child ( create_dialog ) ;
}
2017-03-05 16:44:50 +01:00
if ( hint_text ! = String ( ) ) {
2016-08-03 16:28:20 +02:00
create_dialog - > set_base_type ( hint_text ) ;
} else {
create_dialog - > set_base_type ( " Object " ) ;
}
2017-03-16 21:58:45 +01:00
create_dialog - > popup_create ( false ) ;
2016-08-03 16:28:20 +02:00
hide ( ) ;
2017-03-05 16:44:50 +01:00
updating = false ;
2016-08-24 00:29:07 +02:00
return false ;
2017-03-05 16:44:50 +01:00
} else if ( hint = = PROPERTY_HINT_METHOD_OF_VARIANT_TYPE ) {
# define MAKE_PROPSELECT \
if ( ! property_select ) { \
property_select = memnew ( PropertySelector ) ; \
property_select - > connect ( " selected " , this , " _create_selected_property " ) ; \
add_child ( property_select ) ; \
} \
hide ( ) ;
2016-08-24 00:29:07 +02:00
MAKE_PROPSELECT ;
2017-03-05 16:44:50 +01:00
Variant : : Type type = Variant : : NIL ;
for ( int i = 0 ; i < Variant : : VARIANT_MAX ; i + + ) {
if ( hint_text = = Variant : : get_type_name ( Variant : : Type ( i ) ) ) {
type = Variant : : Type ( i ) ;
2016-08-24 00:29:07 +02:00
}
}
if ( type )
2017-03-05 16:44:50 +01:00
property_select - > select_method_from_basic_type ( type , v ) ;
updating = false ;
2016-08-24 00:29:07 +02:00
return false ;
2017-03-05 16:44:50 +01:00
} else if ( hint = = PROPERTY_HINT_METHOD_OF_BASE_TYPE ) {
2016-08-24 00:29:07 +02:00
MAKE_PROPSELECT
2017-03-05 16:44:50 +01:00
property_select - > select_method_from_base_type ( hint_text , v ) ;
2016-08-24 00:29:07 +02:00
2017-03-05 16:44:50 +01:00
updating = false ;
2016-08-24 00:29:07 +02:00
return false ;
2017-03-05 16:44:50 +01:00
} else if ( hint = = PROPERTY_HINT_METHOD_OF_INSTANCE ) {
2016-08-24 00:29:07 +02:00
MAKE_PROPSELECT
Object * instance = ObjectDB : : get_instance ( hint_text . to_int64 ( ) ) ;
if ( instance )
2017-03-05 16:44:50 +01:00
property_select - > select_method_from_instance ( instance , v ) ;
updating = false ;
2016-08-24 00:29:07 +02:00
return false ;
2017-03-05 16:44:50 +01:00
} else if ( hint = = PROPERTY_HINT_METHOD_OF_SCRIPT ) {
2016-08-24 00:29:07 +02:00
MAKE_PROPSELECT
Object * obj = ObjectDB : : get_instance ( hint_text . to_int64 ( ) ) ;
2017-08-24 22:58:51 +02:00
if ( Object : : cast_to < Script > ( obj ) ) {
property_select - > select_method_from_script ( Object : : cast_to < Script > ( obj ) , v ) ;
2016-08-24 00:29:07 +02:00
}
2017-03-05 16:44:50 +01:00
updating = false ;
2016-08-24 00:29:07 +02:00
return false ;
2017-03-05 16:44:50 +01:00
} else if ( hint = = PROPERTY_HINT_PROPERTY_OF_VARIANT_TYPE ) {
2016-08-24 00:29:07 +02:00
MAKE_PROPSELECT
2017-03-05 16:44:50 +01:00
Variant : : Type type = Variant : : NIL ;
String tname = hint_text ;
if ( tname . find ( " . " ) ! = - 1 )
tname = tname . get_slice ( " . " , 0 ) ;
for ( int i = 0 ; i < Variant : : VARIANT_MAX ; i + + ) {
if ( tname = = Variant : : get_type_name ( Variant : : Type ( i ) ) ) {
type = Variant : : Type ( Variant : : Type ( i ) ) ;
2016-08-24 00:29:07 +02:00
}
}
2017-05-20 17:38:03 +02:00
2017-12-09 22:07:45 +01:00
if ( type ! = Variant : : NIL )
2017-05-20 17:38:03 +02:00
property_select - > select_property_from_basic_type ( type , v ) ;
2016-08-24 00:29:07 +02:00
2017-03-05 16:44:50 +01:00
updating = false ;
2016-08-24 00:29:07 +02:00
return false ;
2017-03-05 16:44:50 +01:00
} else if ( hint = = PROPERTY_HINT_PROPERTY_OF_BASE_TYPE ) {
2016-08-24 00:29:07 +02:00
MAKE_PROPSELECT
2017-03-05 16:44:50 +01:00
property_select - > select_property_from_base_type ( hint_text , v ) ;
2016-08-24 00:29:07 +02:00
2017-03-05 16:44:50 +01:00
updating = false ;
2016-08-24 00:29:07 +02:00
return false ;
2017-03-05 16:44:50 +01:00
} else if ( hint = = PROPERTY_HINT_PROPERTY_OF_INSTANCE ) {
2016-08-24 00:29:07 +02:00
2018-01-15 19:43:32 +01:00
MAKE_PROPSELECT
2016-08-24 00:29:07 +02:00
Object * instance = ObjectDB : : get_instance ( hint_text . to_int64 ( ) ) ;
if ( instance )
2017-03-05 16:44:50 +01:00
property_select - > select_property_from_instance ( instance , v ) ;
2016-08-24 00:29:07 +02:00
2017-03-05 16:44:50 +01:00
updating = false ;
2016-08-24 00:29:07 +02:00
return false ;
2017-03-05 16:44:50 +01:00
} else if ( hint = = PROPERTY_HINT_PROPERTY_OF_SCRIPT ) {
2016-08-24 00:29:07 +02:00
MAKE_PROPSELECT
Object * obj = ObjectDB : : get_instance ( hint_text . to_int64 ( ) ) ;
2017-08-24 22:58:51 +02:00
if ( Object : : cast_to < Script > ( obj ) ) {
property_select - > select_property_from_script ( Object : : cast_to < Script > ( obj ) , v ) ;
2016-08-24 00:29:07 +02:00
}
2017-03-05 16:44:50 +01:00
updating = false ;
2016-08-24 00:29:07 +02:00
return false ;
2014-02-10 02:10:30 +01:00
} else {
List < String > names ;
names . push_back ( " string: " ) ;
2017-03-05 16:44:50 +01:00
config_value_editors ( 1 , 1 , 50 , names ) ;
value_editor [ 0 ] - > set_text ( v ) ;
2014-02-10 02:10:30 +01:00
}
} break ;
case Variant : : VECTOR2 : {
2017-03-02 10:42:05 +01:00
field_names . push_back ( " x " ) ;
field_names . push_back ( " y " ) ;
2017-03-05 16:44:50 +01:00
config_value_editors ( 2 , 2 , 10 , field_names ) ;
Vector2 vec = v ;
value_editor [ 0 ] - > set_text ( String : : num ( vec . x ) ) ;
value_editor [ 1 ] - > set_text ( String : : num ( vec . y ) ) ;
2014-02-10 02:10:30 +01:00
} break ;
case Variant : : RECT2 : {
2017-03-02 10:42:05 +01:00
field_names . push_back ( " x " ) ;
field_names . push_back ( " y " ) ;
field_names . push_back ( " w " ) ;
field_names . push_back ( " h " ) ;
2017-03-05 16:44:50 +01:00
config_value_editors ( 4 , 4 , 10 , field_names ) ;
Rect2 r = v ;
2017-06-04 00:25:13 +02:00
value_editor [ 0 ] - > set_text ( String : : num ( r . position . x ) ) ;
value_editor [ 1 ] - > set_text ( String : : num ( r . position . y ) ) ;
2017-03-05 16:44:50 +01:00
value_editor [ 2 ] - > set_text ( String : : num ( r . size . x ) ) ;
value_editor [ 3 ] - > set_text ( String : : num ( r . size . y ) ) ;
2014-02-10 02:10:30 +01:00
} break ;
case Variant : : VECTOR3 : {
2015-08-30 02:09:11 +02:00
2017-03-02 10:42:05 +01:00
field_names . push_back ( " x " ) ;
field_names . push_back ( " y " ) ;
field_names . push_back ( " z " ) ;
2017-03-05 16:44:50 +01:00
config_value_editors ( 3 , 3 , 10 , field_names ) ;
Vector3 vec = v ;
value_editor [ 0 ] - > set_text ( String : : num ( vec . x ) ) ;
value_editor [ 1 ] - > set_text ( String : : num ( vec . y ) ) ;
value_editor [ 2 ] - > set_text ( String : : num ( vec . z ) ) ;
2014-02-10 02:10:30 +01:00
} break ;
case Variant : : PLANE : {
2015-08-30 02:09:11 +02:00
2017-03-02 10:42:05 +01:00
field_names . push_back ( " x " ) ;
field_names . push_back ( " y " ) ;
field_names . push_back ( " z " ) ;
field_names . push_back ( " d " ) ;
2017-03-05 16:44:50 +01:00
config_value_editors ( 4 , 4 , 10 , field_names ) ;
Plane plane = v ;
value_editor [ 0 ] - > set_text ( String : : num ( plane . normal . x ) ) ;
value_editor [ 1 ] - > set_text ( String : : num ( plane . normal . y ) ) ;
value_editor [ 2 ] - > set_text ( String : : num ( plane . normal . z ) ) ;
value_editor [ 3 ] - > set_text ( String : : num ( plane . d ) ) ;
2015-08-30 02:09:11 +02:00
2014-02-10 02:10:30 +01:00
} break ;
case Variant : : QUAT : {
2015-08-30 02:09:11 +02:00
2017-03-02 10:42:05 +01:00
field_names . push_back ( " x " ) ;
field_names . push_back ( " y " ) ;
field_names . push_back ( " z " ) ;
field_names . push_back ( " w " ) ;
2017-03-05 16:44:50 +01:00
config_value_editors ( 4 , 4 , 10 , field_names ) ;
Quat q = v ;
value_editor [ 0 ] - > set_text ( String : : num ( q . x ) ) ;
value_editor [ 1 ] - > set_text ( String : : num ( q . y ) ) ;
value_editor [ 2 ] - > set_text ( String : : num ( q . z ) ) ;
value_editor [ 3 ] - > set_text ( String : : num ( q . w ) ) ;
2014-02-10 02:10:30 +01:00
} break ;
2017-11-17 03:09:00 +01:00
case Variant : : AABB : {
2015-08-30 02:09:11 +02:00
2017-03-02 10:42:05 +01:00
field_names . push_back ( " px " ) ;
field_names . push_back ( " py " ) ;
field_names . push_back ( " pz " ) ;
field_names . push_back ( " sx " ) ;
field_names . push_back ( " sy " ) ;
field_names . push_back ( " sz " ) ;
2017-03-05 16:44:50 +01:00
config_value_editors ( 6 , 3 , 16 , field_names ) ;
2015-08-30 02:09:11 +02:00
2017-11-17 03:09:00 +01:00
AABB aabb = v ;
2017-06-06 20:33:51 +02:00
value_editor [ 0 ] - > set_text ( String : : num ( aabb . position . x ) ) ;
value_editor [ 1 ] - > set_text ( String : : num ( aabb . position . y ) ) ;
value_editor [ 2 ] - > set_text ( String : : num ( aabb . position . z ) ) ;
2017-03-05 16:44:50 +01:00
value_editor [ 3 ] - > set_text ( String : : num ( aabb . size . x ) ) ;
value_editor [ 4 ] - > set_text ( String : : num ( aabb . size . y ) ) ;
value_editor [ 5 ] - > set_text ( String : : num ( aabb . size . z ) ) ;
2015-08-30 02:09:11 +02:00
2014-02-10 02:10:30 +01:00
} break ;
2017-01-11 04:52:51 +01:00
case Variant : : TRANSFORM2D : {
2014-02-10 02:10:30 +01:00
2017-03-02 10:42:05 +01:00
field_names . push_back ( " xx " ) ;
field_names . push_back ( " xy " ) ;
field_names . push_back ( " yx " ) ;
field_names . push_back ( " yy " ) ;
field_names . push_back ( " ox " ) ;
field_names . push_back ( " oy " ) ;
2017-03-05 16:44:50 +01:00
config_value_editors ( 6 , 2 , 16 , field_names ) ;
2014-02-10 02:10:30 +01:00
2017-03-05 16:44:50 +01:00
Transform2D basis = v ;
for ( int i = 0 ; i < 6 ; i + + ) {
2014-02-10 02:10:30 +01:00
2017-03-05 16:44:50 +01:00
value_editor [ i ] - > set_text ( String : : num ( basis . elements [ i / 2 ] [ i % 2 ] ) ) ;
2014-02-10 02:10:30 +01:00
}
} break ;
2017-01-11 04:52:51 +01:00
case Variant : : BASIS : {
2015-08-30 02:09:11 +02:00
2017-03-02 10:42:05 +01:00
field_names . push_back ( " xx " ) ;
field_names . push_back ( " xy " ) ;
field_names . push_back ( " xz " ) ;
field_names . push_back ( " yx " ) ;
field_names . push_back ( " yy " ) ;
field_names . push_back ( " yz " ) ;
field_names . push_back ( " zx " ) ;
field_names . push_back ( " zy " ) ;
field_names . push_back ( " zz " ) ;
2017-03-05 16:44:50 +01:00
config_value_editors ( 9 , 3 , 16 , field_names ) ;
2015-08-30 02:09:11 +02:00
2017-03-05 16:44:50 +01:00
Basis basis = v ;
for ( int i = 0 ; i < 9 ; i + + ) {
2015-08-30 02:09:11 +02:00
2017-03-05 16:44:50 +01:00
value_editor [ i ] - > set_text ( String : : num ( basis . elements [ i / 3 ] [ i % 3 ] ) ) ;
2014-02-10 02:10:30 +01:00
}
2015-08-30 02:09:11 +02:00
2014-02-10 02:10:30 +01:00
} break ;
case Variant : : TRANSFORM : {
2015-08-30 02:09:11 +02:00
2017-03-02 10:42:05 +01:00
field_names . push_back ( " xx " ) ;
field_names . push_back ( " xy " ) ;
field_names . push_back ( " xz " ) ;
field_names . push_back ( " xo " ) ;
field_names . push_back ( " yx " ) ;
field_names . push_back ( " yy " ) ;
field_names . push_back ( " yz " ) ;
field_names . push_back ( " yo " ) ;
field_names . push_back ( " zx " ) ;
field_names . push_back ( " zy " ) ;
field_names . push_back ( " zz " ) ;
field_names . push_back ( " zo " ) ;
2017-03-05 16:44:50 +01:00
config_value_editors ( 12 , 4 , 16 , field_names ) ;
2015-08-30 02:09:11 +02:00
2017-03-05 16:44:50 +01:00
Transform tr = v ;
for ( int i = 0 ; i < 9 ; i + + ) {
2015-08-30 02:09:11 +02:00
2017-03-05 16:44:50 +01:00
value_editor [ ( i / 3 ) * 4 + i % 3 ] - > set_text ( String : : num ( tr . basis . elements [ i / 3 ] [ i % 3 ] ) ) ;
2014-02-10 02:10:30 +01:00
}
2015-08-30 02:09:11 +02:00
2017-03-05 16:44:50 +01:00
value_editor [ 3 ] - > set_text ( String : : num ( tr . origin . x ) ) ;
value_editor [ 7 ] - > set_text ( String : : num ( tr . origin . y ) ) ;
value_editor [ 11 ] - > set_text ( String : : num ( tr . origin . z ) ) ;
2015-08-30 02:09:11 +02:00
2014-02-10 02:10:30 +01:00
} break ;
case Variant : : COLOR : {
2015-08-30 02:09:11 +02:00
2016-06-08 03:08:12 +02:00
if ( ! color_picker ) {
//late init for performance
2017-03-05 16:44:50 +01:00
color_picker = memnew ( ColorPicker ) ;
2016-06-08 03:08:12 +02:00
add_child ( color_picker ) ;
color_picker - > hide ( ) ;
2017-03-05 16:44:50 +01:00
color_picker - > connect ( " color_changed " , this , " _color_changed " ) ;
2016-06-08 03:08:12 +02:00
}
2016-01-23 15:20:54 +01:00
2014-02-10 02:10:30 +01:00
color_picker - > show ( ) ;
2017-03-05 16:44:50 +01:00
color_picker - > set_edit_alpha ( hint ! = PROPERTY_HINT_COLOR_NO_ALPHA ) ;
2017-01-14 15:07:57 +01:00
color_picker - > set_pick_color ( v ) ;
2016-07-01 15:55:35 +02:00
color_picker - > set_focus_on_line_edit ( ) ;
2015-08-30 02:09:11 +02:00
2014-02-10 02:10:30 +01:00
} break ;
2015-08-30 02:09:11 +02:00
2014-02-10 02:10:30 +01:00
case Variant : : NODE_PATH : {
2015-08-30 02:09:11 +02:00
2014-02-10 02:10:30 +01:00
List < String > names ;
2016-05-04 03:25:37 +02:00
names . push_back ( TTR ( " Assign " ) ) ;
names . push_back ( TTR ( " Clear " ) ) ;
2017-08-02 19:40:17 +02:00
2017-10-06 21:24:00 +02:00
if ( owner & & owner - > is_class ( " Node " ) & & ( v . get_type ( ) = = Variant : : NODE_PATH ) & & Object : : cast_to < Node > ( owner ) - > has_node ( v ) )
2017-08-02 19:40:17 +02:00
names . push_back ( TTR ( " Select Node " ) ) ;
2014-02-10 02:10:30 +01:00
config_action_buttons ( names ) ;
} break ;
case Variant : : OBJECT : {
2015-08-30 02:09:11 +02:00
2017-03-05 16:44:50 +01:00
if ( hint ! = PROPERTY_HINT_RESOURCE_TYPE )
2014-02-10 02:10:30 +01:00
break ;
2017-08-24 22:58:51 +02:00
if ( p_name = = " script " & & hint_text = = " Script " & & Object : : cast_to < Node > ( owner ) ) {
2017-03-05 16:44:50 +01:00
menu - > add_icon_item ( get_icon ( " Script " , " EditorIcons " ) , TTR ( " New Script " ) , OBJ_MENU_NEW_SCRIPT ) ;
2016-09-13 00:31:07 +02:00
menu - > add_separator ( ) ;
2017-03-05 16:44:50 +01:00
} else if ( hint_text ! = " " ) {
int idx = 0 ;
2014-02-10 02:10:30 +01:00
2018-04-08 18:52:13 +02:00
Vector < EditorData : : CustomType > custom_resources ;
if ( EditorNode : : get_editor_data ( ) . get_custom_types ( ) . has ( " Resource " ) ) {
custom_resources = EditorNode : : get_editor_data ( ) . get_custom_types ( ) [ " Resource " ] ;
}
2017-03-05 16:44:50 +01:00
for ( int i = 0 ; i < hint_text . get_slice_count ( " , " ) ; i + + ) {
2014-02-10 02:10:30 +01:00
2017-03-05 16:44:50 +01:00
String base = hint_text . get_slice ( " , " , i ) ;
2014-02-10 02:10:30 +01:00
Set < String > valid_inheritors ;
valid_inheritors . insert ( base ) ;
2015-06-29 05:29:49 +02:00
List < StringName > inheritors ;
2017-03-05 16:44:50 +01:00
ClassDB : : get_inheriters_from_class ( base . strip_edges ( ) , & inheritors ) ;
2018-02-25 01:41:26 +01:00
for ( int i = 0 ; i < custom_resources . size ( ) ; i + + ) {
inheritors . push_back ( custom_resources [ i ] . name ) ;
}
2017-03-05 16:44:50 +01:00
List < StringName > : : Element * E = inheritors . front ( ) ;
while ( E ) {
2014-02-10 02:10:30 +01:00
valid_inheritors . insert ( E - > get ( ) ) ;
2017-03-05 16:44:50 +01:00
E = E - > next ( ) ;
2014-02-10 02:10:30 +01:00
}
2017-03-05 16:44:50 +01:00
for ( Set < String > : : Element * E = valid_inheritors . front ( ) ; E ; E = E - > next ( ) ) {
2014-02-10 02:10:30 +01:00
String t = E - > get ( ) ;
2018-02-25 01:41:26 +01:00
bool is_custom_resource = false ;
Ref < Texture > icon ;
if ( ! custom_resources . empty ( ) ) {
for ( int i = 0 ; i < custom_resources . size ( ) ; i + + ) {
if ( custom_resources [ i ] . name = = t ) {
is_custom_resource = true ;
if ( custom_resources [ i ] . icon . is_valid ( ) )
icon = custom_resources [ i ] . icon ;
break ;
}
}
}
if ( ! is_custom_resource & & ! ClassDB : : can_instance ( t ) )
2014-02-10 02:10:30 +01:00
continue ;
2018-02-25 01:41:26 +01:00
2014-02-10 02:10:30 +01:00
inheritors_array . push_back ( t ) ;
2017-03-05 16:44:50 +01:00
int id = TYPE_BASE_ID + idx ;
2014-02-10 02:10:30 +01:00
2018-02-25 01:41:26 +01:00
if ( ! icon . is_valid ( ) & & has_icon ( t , " EditorIcons " ) ) {
icon = get_icon ( t , " EditorIcons " ) ;
}
if ( icon . is_valid ( ) ) {
menu - > add_icon_item ( icon , vformat ( TTR ( " New %s " ) , t ) , id ) ;
2014-02-10 02:10:30 +01:00
} else {
2017-12-12 16:57:17 +01:00
menu - > add_item ( vformat ( TTR ( " New %s " ) , t ) , id ) ;
2014-02-10 02:10:30 +01:00
}
idx + + ;
}
}
if ( menu - > get_item_count ( ) )
menu - > add_separator ( ) ;
}
2017-09-15 04:36:48 +02:00
menu - > add_icon_item ( get_icon ( " Load " , " EditorIcons " ) , TTR ( " Load " ) , OBJ_MENU_LOAD ) ;
2014-02-10 02:10:30 +01:00
if ( ! RES ( v ) . is_null ( ) ) {
2017-09-15 04:36:48 +02:00
menu - > add_icon_item ( get_icon ( " Edit " , " EditorIcons " ) , TTR ( " Edit " ) , OBJ_MENU_EDIT ) ;
menu - > add_icon_item ( get_icon ( " Clear " , " EditorIcons " ) , TTR ( " Clear " ) , OBJ_MENU_CLEAR ) ;
menu - > add_icon_item ( get_icon ( " Duplicate " , " EditorIcons " ) , TTR ( " Make Unique " ) , OBJ_MENU_MAKE_UNIQUE ) ;
2017-01-14 18:14:46 +01:00
RES r = v ;
if ( r . is_valid ( ) & & r - > get_path ( ) . is_resource_file ( ) ) {
2014-02-10 02:10:30 +01:00
menu - > add_separator ( ) ;
2017-03-05 16:44:50 +01:00
menu - > add_item ( TTR ( " Show in File System " ) , OBJ_MENU_SHOW_IN_FILE_SYSTEM ) ;
2017-01-14 18:14:46 +01:00
}
2015-03-16 04:47:37 +01:00
} else {
2014-02-10 02:10:30 +01:00
}
2017-03-05 16:44:50 +01:00
RES cb = EditorSettings : : get_singleton ( ) - > get_resource_clipboard ( ) ;
bool paste_valid = false ;
2016-01-10 15:33:45 +01:00
if ( cb . is_valid ( ) ) {
2017-03-05 16:44:50 +01:00
if ( hint_text = = " " )
paste_valid = true ;
2016-01-10 15:33:45 +01:00
else
2017-03-05 16:44:50 +01:00
for ( int i = 0 ; i < hint_text . get_slice_count ( " , " ) ; i + + )
if ( ClassDB : : is_parent_class ( cb - > get_class ( ) , hint_text . get_slice ( " , " , i ) ) ) {
paste_valid = true ;
2016-01-10 15:33:45 +01:00
break ;
}
}
2014-02-10 02:10:30 +01:00
if ( ! RES ( v ) . is_null ( ) | | paste_valid ) {
menu - > add_separator ( ) ;
if ( ! RES ( v ) . is_null ( ) ) {
2017-03-05 16:44:50 +01:00
menu - > add_item ( TTR ( " Copy " ) , OBJ_MENU_COPY ) ;
2014-02-10 02:10:30 +01:00
}
if ( paste_valid ) {
2017-03-05 16:44:50 +01:00
menu - > add_item ( TTR ( " Paste " ) , OBJ_MENU_PASTE ) ;
2014-02-10 02:10:30 +01:00
}
}
2017-09-22 14:20:28 +02:00
if ( ! RES ( v ) . is_null ( ) ) {
Vector < Ref < EditorResourceConversionPlugin > > conversions = EditorNode : : get_singleton ( ) - > find_resource_conversion_plugin ( RES ( v ) ) ;
if ( conversions . size ( ) ) {
menu - > add_separator ( ) ;
}
for ( int i = 0 ; i < conversions . size ( ) ; i + + ) {
String what = conversions [ i ] - > converts_to ( ) ;
Ref < Texture > icon ;
if ( has_icon ( what , " EditorIcons " ) ) {
icon = get_icon ( what , " EditorIcons " ) ;
} else {
icon = get_icon ( what , " Resource " ) ;
}
menu - > add_icon_item ( icon , vformat ( TTR ( " Convert To %s " ) , what ) , CONVERT_BASE_ID + i ) ;
}
}
2017-03-29 17:29:38 +02:00
menu - > set_position ( get_position ( ) ) ;
2014-02-10 02:10:30 +01:00
menu - > popup ( ) ;
hide ( ) ;
2017-03-05 16:44:50 +01:00
updating = false ;
2014-02-10 02:10:30 +01:00
return false ;
} break ;
case Variant : : DICTIONARY : {
2015-08-30 02:09:11 +02:00
2014-02-10 02:10:30 +01:00
} break ;
2017-01-11 04:52:51 +01:00
case Variant : : POOL_BYTE_ARRAY : {
2015-08-30 02:09:11 +02:00
2014-02-10 02:10:30 +01:00
} break ;
2017-01-11 04:52:51 +01:00
case Variant : : POOL_INT_ARRAY : {
2015-08-30 02:09:11 +02:00
2014-02-10 02:10:30 +01:00
} break ;
2017-01-11 04:52:51 +01:00
case Variant : : POOL_REAL_ARRAY : {
2015-08-30 02:09:11 +02:00
2014-02-10 02:10:30 +01:00
} break ;
2017-01-11 04:52:51 +01:00
case Variant : : POOL_STRING_ARRAY : {
2015-08-30 02:09:11 +02:00
2014-02-10 02:10:30 +01:00
} break ;
2017-01-11 04:52:51 +01:00
case Variant : : POOL_VECTOR3_ARRAY : {
2015-08-30 02:09:11 +02:00
2014-02-10 02:10:30 +01:00
} break ;
2017-01-11 04:52:51 +01:00
case Variant : : POOL_COLOR_ARRAY : {
2015-08-30 02:09:11 +02:00
2014-02-10 02:10:30 +01:00
} break ;
default : { }
2015-08-30 02:09:11 +02:00
}
2017-03-05 16:44:50 +01:00
updating = false ;
2014-02-10 02:10:30 +01:00
return true ;
}
void CustomPropertyEditor : : _file_selected ( String p_file ) {
2017-03-05 16:44:50 +01:00
switch ( type ) {
2015-08-30 02:09:11 +02:00
2014-02-10 02:10:30 +01:00
case Variant : : STRING : {
2017-03-05 16:44:50 +01:00
if ( hint = = PROPERTY_HINT_FILE | | hint = = PROPERTY_HINT_DIR ) {
2014-02-10 02:10:30 +01:00
2017-07-19 22:00:46 +02:00
v = ProjectSettings : : get_singleton ( ) - > localize_path ( p_file ) ;
2014-02-10 02:10:30 +01:00
emit_signal ( " variant_changed " ) ;
hide ( ) ;
}
2017-03-05 16:44:50 +01:00
if ( hint = = PROPERTY_HINT_GLOBAL_FILE | | hint = = PROPERTY_HINT_GLOBAL_DIR ) {
2014-02-10 02:10:30 +01:00
2017-03-05 16:44:50 +01:00
v = p_file ;
2014-02-10 02:10:30 +01:00
emit_signal ( " variant_changed " ) ;
hide ( ) ;
}
} break ;
case Variant : : OBJECT : {
2017-03-05 16:44:50 +01:00
String type = ( hint = = PROPERTY_HINT_RESOURCE_TYPE ) ? hint_text : String ( ) ;
2014-02-10 02:10:30 +01:00
2017-03-05 16:44:50 +01:00
RES res = ResourceLoader : : load ( p_file , type ) ;
2014-02-10 02:10:30 +01:00
if ( res . is_null ( ) ) {
2016-05-04 03:25:37 +02:00
error - > set_text ( TTR ( " Error loading file: Not a resource! " ) ) ;
2015-04-08 19:02:13 +02:00
error - > popup_centered_minsize ( ) ;
2014-02-10 02:10:30 +01:00
break ;
}
2017-03-05 16:44:50 +01:00
v = res . get_ref_ptr ( ) ;
2014-02-10 02:10:30 +01:00
emit_signal ( " variant_changed " ) ;
hide ( ) ;
} break ;
default : { }
}
}
void CustomPropertyEditor : : _type_create_selected ( int p_idx ) {
2017-03-05 16:44:50 +01:00
if ( type = = Variant : : INT | | type = = Variant : : REAL ) {
2014-02-10 02:10:30 +01:00
2017-03-05 16:44:50 +01:00
float newval = 0 ;
switch ( p_idx ) {
2014-02-10 02:10:30 +01:00
case EASING_LINEAR : {
2017-03-05 16:44:50 +01:00
newval = 1 ;
2014-02-10 02:10:30 +01:00
} break ;
case EASING_EASE_IN : {
2017-03-05 16:44:50 +01:00
newval = 2.0 ;
2014-02-10 02:10:30 +01:00
} break ;
case EASING_EASE_OUT : {
2017-03-05 16:44:50 +01:00
newval = 0.5 ;
2014-02-10 02:10:30 +01:00
} break ;
case EASING_ZERO : {
2017-03-05 16:44:50 +01:00
newval = 0 ;
2014-02-10 02:10:30 +01:00
} break ;
case EASING_IN_OUT : {
2017-03-05 16:44:50 +01:00
newval = - 0.5 ;
2014-02-10 02:10:30 +01:00
} break ;
case EASING_OUT_IN : {
2017-03-05 16:44:50 +01:00
newval = - 2.0 ;
2014-02-10 02:10:30 +01:00
} break ;
}
2017-03-05 16:44:50 +01:00
v = newval ;
2014-02-10 02:10:30 +01:00
emit_signal ( " variant_changed " ) ;
easing_draw - > update ( ) ;
2017-03-05 16:44:50 +01:00
} else if ( type = = Variant : : OBJECT ) {
2014-02-10 02:10:30 +01:00
2017-03-05 16:44:50 +01:00
ERR_FAIL_INDEX ( p_idx , inheritors_array . size ( ) ) ;
2014-02-10 02:10:30 +01:00
2017-03-05 16:44:50 +01:00
String intype = inheritors_array [ p_idx ] ;
2014-02-10 02:10:30 +01:00
2017-01-03 03:03:46 +01:00
Object * obj = ClassDB : : instance ( intype ) ;
2014-02-10 02:10:30 +01:00
2018-02-25 01:41:26 +01:00
if ( ! obj ) {
obj = EditorNode : : get_editor_data ( ) . instance_custom_type ( intype , " Resource " ) ;
}
2017-03-05 16:44:50 +01:00
ERR_FAIL_COND ( ! obj ) ;
2014-02-10 02:10:30 +01:00
2017-08-24 22:58:51 +02:00
Resource * res = Object : : cast_to < Resource > ( obj ) ;
2017-03-05 16:44:50 +01:00
ERR_FAIL_COND ( ! res ) ;
2014-02-10 02:10:30 +01:00
2017-03-05 16:44:50 +01:00
v = Ref < Resource > ( res ) . get_ref_ptr ( ) ;
2014-02-10 02:10:30 +01:00
emit_signal ( " variant_changed " ) ;
hide ( ) ;
}
}
2017-03-05 16:44:50 +01:00
void CustomPropertyEditor : : _color_changed ( const Color & p_color ) {
2014-02-10 02:10:30 +01:00
2017-03-05 16:44:50 +01:00
v = p_color ;
2014-02-10 02:10:30 +01:00
emit_signal ( " variant_changed " ) ;
}
void CustomPropertyEditor : : _node_path_selected ( NodePath p_path ) {
2017-01-10 05:04:31 +01:00
if ( picking_viewport ) {
2017-03-05 16:44:50 +01:00
Node * to_node = get_node ( p_path ) ;
2017-08-24 22:58:51 +02:00
if ( ! Object : : cast_to < Viewport > ( to_node ) ) {
2017-08-23 22:25:14 +02:00
EditorNode : : get_singleton ( ) - > show_warning ( TTR ( " Selected node is not a Viewport! " ) ) ;
2017-01-10 05:04:31 +01:00
return ;
}
Ref < ViewportTexture > vt ;
vt . instance ( ) ;
vt - > set_viewport_path_in_scene ( get_tree ( ) - > get_edited_scene_root ( ) - > get_path_to ( to_node ) ) ;
vt - > setup_local_to_scene ( ) ;
2017-03-05 16:44:50 +01:00
v = vt ;
2017-01-10 05:04:31 +01:00
emit_signal ( " variant_changed " ) ;
return ;
}
2016-08-03 00:11:05 +02:00
2017-03-05 16:44:50 +01:00
if ( hint = = PROPERTY_HINT_NODE_PATH_TO_EDITED_NODE & & hint_text ! = String ( ) ) {
2016-08-03 00:11:05 +02:00
2017-03-05 16:44:50 +01:00
Node * node = get_node ( hint_text ) ;
2016-08-03 00:11:05 +02:00
if ( node ) {
2017-03-05 16:44:50 +01:00
Node * tonode = node - > get_node ( p_path ) ;
2016-08-03 00:11:05 +02:00
if ( tonode ) {
2017-03-05 16:44:50 +01:00
p_path = node - > get_path_to ( tonode ) ;
2016-08-03 00:11:05 +02:00
}
}
} else if ( owner ) {
2015-12-13 15:42:29 +01:00
2017-03-05 16:44:50 +01:00
Node * node = NULL ;
2015-12-13 15:42:29 +01:00
2017-03-05 16:44:50 +01:00
if ( owner - > is_class ( " Node " ) )
2017-08-24 22:58:51 +02:00
node = Object : : cast_to < Node > ( owner ) ;
2017-01-03 03:03:46 +01:00
else if ( owner - > is_class ( " ArrayPropertyEdit " ) )
2017-08-24 22:58:51 +02:00
node = Object : : cast_to < ArrayPropertyEdit > ( owner ) - > get_node ( ) ;
2017-10-17 16:39:31 +02:00
else if ( owner - > is_class ( " DictionaryPropertyEdit " ) )
node = Object : : cast_to < DictionaryPropertyEdit > ( owner ) - > get_node ( ) ;
2015-12-13 15:42:29 +01:00
if ( ! node ) {
2017-03-05 16:44:50 +01:00
v = p_path ;
2015-12-13 15:42:29 +01:00
emit_signal ( " variant_changed " ) ;
2016-01-02 14:47:50 +01:00
call_deferred ( " hide " ) ; //to not mess with dialogs
2015-12-13 15:42:29 +01:00
return ;
}
2014-02-10 02:10:30 +01:00
2017-03-05 16:44:50 +01:00
Node * tonode = node - > get_node ( p_path ) ;
2014-02-10 02:10:30 +01:00
if ( tonode ) {
2017-03-05 16:44:50 +01:00
p_path = node - > get_path_to ( tonode ) ;
2014-02-10 02:10:30 +01:00
}
}
2017-03-05 16:44:50 +01:00
v = p_path ;
2014-02-10 02:10:30 +01:00
emit_signal ( " variant_changed " ) ;
2016-01-02 14:47:50 +01:00
call_deferred ( " hide " ) ; //to not mess with dialogs
2014-02-10 02:10:30 +01:00
}
void CustomPropertyEditor : : _action_pressed ( int p_which ) {
2015-08-30 02:09:11 +02:00
if ( updating )
2014-02-10 02:10:30 +01:00
return ;
2015-08-30 02:09:11 +02:00
2017-03-05 16:44:50 +01:00
switch ( type ) {
2016-08-26 22:34:25 +02:00
case Variant : : BOOL : {
2017-03-05 16:44:50 +01:00
v = checks20 [ 0 ] - > is_pressed ( ) ;
2016-08-26 22:34:25 +02:00
emit_signal ( " variant_changed " ) ;
} break ;
2014-02-10 02:10:30 +01:00
case Variant : : INT : {
2017-03-05 16:44:50 +01:00
if ( hint = = PROPERTY_HINT_LAYERS_2D_PHYSICS | | hint = = PROPERTY_HINT_LAYERS_2D_RENDER | | hint = = PROPERTY_HINT_LAYERS_3D_PHYSICS | | hint = = PROPERTY_HINT_LAYERS_3D_RENDER ) {
2014-02-10 02:10:30 +01:00
uint32_t f = v ;
if ( checks20 [ p_which ] - > is_pressed ( ) )
2017-03-05 16:44:50 +01:00
f | = ( 1 < < p_which ) ;
2014-02-10 02:10:30 +01:00
else
2017-03-05 16:44:50 +01:00
f & = ~ ( 1 < < p_which ) ;
2014-02-10 02:10:30 +01:00
2017-03-05 16:44:50 +01:00
v = f ;
2014-02-10 02:10:30 +01:00
emit_signal ( " variant_changed " ) ;
}
} break ;
case Variant : : STRING : {
2017-03-05 16:44:50 +01:00
if ( hint = = PROPERTY_HINT_MULTILINE_TEXT ) {
2014-02-10 02:10:30 +01:00
hide ( ) ;
2017-03-05 16:44:50 +01:00
} else if ( hint = = PROPERTY_HINT_FILE | | hint = = PROPERTY_HINT_GLOBAL_FILE ) {
if ( p_which = = 0 ) {
2014-02-10 02:10:30 +01:00
2017-03-05 16:44:50 +01:00
if ( hint = = PROPERTY_HINT_FILE )
2015-06-06 14:44:38 +02:00
file - > set_access ( EditorFileDialog : : ACCESS_RESOURCES ) ;
2014-02-10 02:10:30 +01:00
else
2015-06-06 14:44:38 +02:00
file - > set_access ( EditorFileDialog : : ACCESS_FILESYSTEM ) ;
2014-02-10 02:10:30 +01:00
2015-06-06 14:44:38 +02:00
file - > set_mode ( EditorFileDialog : : MODE_OPEN_FILE ) ;
2014-02-10 02:10:30 +01:00
file - > clear_filters ( ) ;
file - > clear_filters ( ) ;
2017-03-05 16:44:50 +01:00
if ( hint_text ! = " " ) {
Vector < String > extensions = hint_text . split ( " , " ) ;
for ( int i = 0 ; i < extensions . size ( ) ; i + + ) {
2014-02-10 02:10:30 +01:00
2014-04-05 17:39:30 +02:00
String filter = extensions [ i ] ;
if ( filter . begins_with ( " . " ) )
2017-03-05 16:44:50 +01:00
filter = " * " + extensions [ i ] ;
2014-04-05 17:39:30 +02:00
else if ( ! filter . begins_with ( " * " ) )
2017-03-05 16:44:50 +01:00
filter = " *. " + extensions [ i ] ;
2014-02-10 02:10:30 +01:00
2017-03-05 16:44:50 +01:00
file - > add_filter ( filter + " ; " + extensions [ i ] . to_upper ( ) ) ;
2014-02-10 02:10:30 +01:00
}
}
file - > popup_centered_ratio ( ) ;
} else {
2017-03-05 16:44:50 +01:00
v = " " ;
2014-02-10 02:10:30 +01:00
emit_signal ( " variant_changed " ) ;
hide ( ) ;
}
2017-03-05 16:44:50 +01:00
} else if ( hint = = PROPERTY_HINT_DIR | | hint = = PROPERTY_HINT_GLOBAL_DIR ) {
2014-02-10 02:10:30 +01:00
2017-03-05 16:44:50 +01:00
if ( p_which = = 0 ) {
2014-02-10 02:10:30 +01:00
2017-03-05 16:44:50 +01:00
if ( hint = = PROPERTY_HINT_DIR )
2015-06-06 14:44:38 +02:00
file - > set_access ( EditorFileDialog : : ACCESS_RESOURCES ) ;
2014-02-10 02:10:30 +01:00
else
2015-06-06 14:44:38 +02:00
file - > set_access ( EditorFileDialog : : ACCESS_FILESYSTEM ) ;
file - > set_mode ( EditorFileDialog : : MODE_OPEN_DIR ) ;
2014-02-10 02:10:30 +01:00
file - > clear_filters ( ) ;
file - > popup_centered_ratio ( ) ;
} else {
2017-03-05 16:44:50 +01:00
v = " " ;
2014-02-10 02:10:30 +01:00
emit_signal ( " variant_changed " ) ;
hide ( ) ;
}
}
} break ;
case Variant : : NODE_PATH : {
2015-08-30 02:09:11 +02:00
2017-03-05 16:44:50 +01:00
if ( p_which = = 0 ) {
2014-02-10 02:10:30 +01:00
2017-03-05 16:44:50 +01:00
picking_viewport = false ;
2017-01-10 05:04:31 +01:00
scene_tree - > set_title ( TTR ( " Pick a Node " ) ) ;
2014-02-10 02:10:30 +01:00
scene_tree - > popup_centered_ratio ( ) ;
2017-03-05 16:44:50 +01:00
} else if ( p_which = = 1 ) {
2014-02-10 02:10:30 +01:00
2017-03-05 16:44:50 +01:00
v = NodePath ( ) ;
2014-02-10 02:10:30 +01:00
emit_signal ( " variant_changed " ) ;
2017-08-02 19:40:17 +02:00
hide ( ) ;
} else if ( p_which = = 2 ) {
2017-08-24 22:58:51 +02:00
if ( owner - > is_class ( " Node " ) & & ( v . get_type ( ) = = Variant : : NODE_PATH ) & & Object : : cast_to < Node > ( owner ) - > has_node ( v ) ) {
2017-08-02 19:40:17 +02:00
2017-08-24 22:58:51 +02:00
Node * target_node = Object : : cast_to < Node > ( owner ) - > get_node ( v ) ;
2017-08-02 19:40:17 +02:00
EditorNode : : get_singleton ( ) - > get_editor_selection ( ) - > clear ( ) ;
EditorNode : : get_singleton ( ) - > get_scene_tree_dock ( ) - > set_selected ( target_node ) ;
}
2016-01-02 14:47:50 +01:00
hide ( ) ;
2015-08-30 02:09:11 +02:00
}
2017-08-02 19:40:17 +02:00
2014-02-10 02:10:30 +01:00
} break ;
case Variant : : OBJECT : {
2015-08-30 02:09:11 +02:00
2017-03-05 16:44:50 +01:00
if ( p_which = = 0 ) {
2015-08-30 02:09:11 +02:00
2017-03-05 16:44:50 +01:00
ERR_FAIL_COND ( inheritors_array . empty ( ) ) ;
2015-01-03 20:52:37 +01:00
2017-03-05 16:44:50 +01:00
String intype = inheritors_array [ 0 ] ;
2014-02-10 02:10:30 +01:00
2017-03-05 16:44:50 +01:00
if ( hint = = PROPERTY_HINT_RESOURCE_TYPE ) {
2015-08-30 02:09:11 +02:00
2017-01-03 03:03:46 +01:00
Object * obj = ClassDB : : instance ( intype ) ;
2018-02-25 01:41:26 +01:00
if ( ! obj ) {
obj = EditorNode : : get_editor_data ( ) . instance_custom_type ( intype , " Resource " ) ;
}
2017-03-05 16:44:50 +01:00
ERR_BREAK ( ! obj ) ;
2017-08-24 22:58:51 +02:00
Resource * res = Object : : cast_to < Resource > ( obj ) ;
2017-03-05 16:44:50 +01:00
ERR_BREAK ( ! res ) ;
2015-08-30 02:09:11 +02:00
2017-03-05 16:44:50 +01:00
v = Ref < Resource > ( res ) . get_ref_ptr ( ) ;
2014-02-10 02:10:30 +01:00
emit_signal ( " variant_changed " ) ;
hide ( ) ;
}
2017-03-05 16:44:50 +01:00
} else if ( p_which = = 1 ) {
2015-08-30 02:09:11 +02:00
2015-06-06 14:44:38 +02:00
file - > set_access ( EditorFileDialog : : ACCESS_RESOURCES ) ;
file - > set_mode ( EditorFileDialog : : MODE_OPEN_FILE ) ;
2014-02-10 02:10:30 +01:00
List < String > extensions ;
2017-03-05 16:44:50 +01:00
String type = ( hint = = PROPERTY_HINT_RESOURCE_TYPE ) ? hint_text : String ( ) ;
2015-08-30 02:09:11 +02:00
2017-03-05 16:44:50 +01:00
ResourceLoader : : get_recognized_extensions_for_type ( type , & extensions ) ;
2014-02-10 02:10:30 +01:00
file - > clear_filters ( ) ;
2017-03-05 16:44:50 +01:00
for ( List < String > : : Element * E = extensions . front ( ) ; E ; E = E - > next ( ) ) {
2015-08-30 02:09:11 +02:00
2017-03-05 16:44:50 +01:00
file - > add_filter ( " *. " + E - > get ( ) + " ; " + E - > get ( ) . to_upper ( ) ) ;
2014-02-10 02:10:30 +01:00
}
2015-08-30 02:09:11 +02:00
2014-02-10 02:10:30 +01:00
file - > popup_centered_ratio ( ) ;
2015-08-30 02:09:11 +02:00
2017-03-05 16:44:50 +01:00
} else if ( p_which = = 2 ) {
2015-08-30 02:09:11 +02:00
2017-03-05 16:44:50 +01:00
RefPtr RefPtr = v ;
2014-02-10 02:10:30 +01:00
if ( ! RefPtr . is_null ( ) ) {
emit_signal ( " resource_edit_request " ) ;
2015-08-30 02:09:11 +02:00
hide ( ) ;
2014-02-10 02:10:30 +01:00
}
2015-08-30 02:09:11 +02:00
2017-03-05 16:44:50 +01:00
} else if ( p_which = = 3 ) {
2015-08-30 02:09:11 +02:00
2017-03-05 16:44:50 +01:00
v = Variant ( ) ;
2014-02-10 02:10:30 +01:00
emit_signal ( " variant_changed " ) ;
hide ( ) ;
2017-03-05 16:44:50 +01:00
} else if ( p_which = = 4 ) {
2014-02-10 02:10:30 +01:00
2017-03-05 16:44:50 +01:00
RefPtr RefPtr = v ;
2014-02-10 02:10:30 +01:00
Ref < Resource > res_orig = RefPtr ;
if ( res_orig . is_null ( ) )
return ;
List < PropertyInfo > property_list ;
res_orig - > get_property_list ( & property_list ) ;
2017-03-05 16:44:50 +01:00
List < Pair < String , Variant > > propvalues ;
2014-02-10 02:10:30 +01:00
2017-03-05 16:44:50 +01:00
for ( List < PropertyInfo > : : Element * E = property_list . front ( ) ; E ; E = E - > next ( ) ) {
2014-02-10 02:10:30 +01:00
2017-03-05 16:44:50 +01:00
Pair < String , Variant > p ;
2014-02-10 02:10:30 +01:00
PropertyInfo & pi = E - > get ( ) ;
2017-03-05 16:44:50 +01:00
if ( pi . usage & PROPERTY_USAGE_STORAGE ) {
2014-02-10 02:10:30 +01:00
2017-03-05 16:44:50 +01:00
p . first = pi . name ;
p . second = res_orig - > get ( pi . name ) ;
2014-02-10 02:10:30 +01:00
}
propvalues . push_back ( p ) ;
}
2017-03-05 16:44:50 +01:00
Ref < Resource > res = Ref < Resource > ( ClassDB : : instance ( res_orig - > get_class ( ) ) ) ;
2014-02-10 02:10:30 +01:00
ERR_FAIL_COND ( res . is_null ( ) ) ;
2017-03-05 16:44:50 +01:00
for ( List < Pair < String , Variant > > : : Element * E = propvalues . front ( ) ; E ; E = E - > next ( ) ) {
2014-02-10 02:10:30 +01:00
2017-03-05 16:44:50 +01:00
Pair < String , Variant > & p = E - > get ( ) ;
res - > set ( p . first , p . second ) ;
2014-02-10 02:10:30 +01:00
}
2017-03-05 16:44:50 +01:00
v = res . get_ref_ptr ( ) ;
2014-02-10 02:10:30 +01:00
emit_signal ( " variant_changed " ) ;
hide ( ) ;
}
2015-08-30 02:09:11 +02:00
2014-02-10 02:10:30 +01:00
} break ;
default : { } ;
}
}
2017-05-20 17:38:03 +02:00
void CustomPropertyEditor : : _drag_easing ( const Ref < InputEvent > & p_ev ) {
Ref < InputEventMouseMotion > mm = p_ev ;
2016-01-23 15:20:54 +01:00
2017-05-20 17:38:03 +02:00
if ( mm . is_valid ( ) & & mm - > get_button_mask ( ) & BUTTON_MASK_LEFT ) {
2014-02-10 02:10:30 +01:00
2017-05-20 17:38:03 +02:00
float rel = mm - > get_relative ( ) . x ;
2017-03-05 16:44:50 +01:00
if ( rel = = 0 )
2015-08-30 02:09:11 +02:00
return ;
2014-02-10 02:10:30 +01:00
2017-03-05 16:44:50 +01:00
bool flip = hint_text = = " attenuation " ;
2014-02-10 02:10:30 +01:00
if ( flip )
2017-03-05 16:44:50 +01:00
rel = - rel ;
2014-02-10 02:10:30 +01:00
float val = v ;
2017-03-05 16:44:50 +01:00
if ( val = = 0 )
2014-02-10 02:10:30 +01:00
return ;
bool sg = val < 0 ;
val = Math : : absf ( val ) ;
2017-03-05 16:44:50 +01:00
val = Math : : log ( val ) / Math : : log ( ( float ) 2.0 ) ;
2014-02-10 02:10:30 +01:00
//logspace
2017-03-05 16:44:50 +01:00
val + = rel * 0.05 ;
2014-02-10 02:10:30 +01:00
2017-03-05 16:44:50 +01:00
val = Math : : pow ( 2.0f , val ) ;
2014-02-10 02:10:30 +01:00
if ( sg )
2017-03-05 16:44:50 +01:00
val = - val ;
2014-02-10 02:10:30 +01:00
2017-03-05 16:44:50 +01:00
v = val ;
2014-02-10 02:10:30 +01:00
easing_draw - > update ( ) ;
emit_signal ( " variant_changed " ) ;
}
}
void CustomPropertyEditor : : _draw_easing ( ) {
RID ci = easing_draw - > get_canvas_item ( ) ;
Size2 s = easing_draw - > get_size ( ) ;
2017-03-05 16:44:50 +01:00
Rect2 r ( Point2 ( ) , s ) ;
r = r . grow ( 3 ) ;
get_stylebox ( " normal " , " LineEdit " ) - > draw ( ci , r ) ;
2014-02-10 02:10:30 +01:00
int points = 48 ;
2017-03-05 16:44:50 +01:00
float prev = 1.0 ;
float exp = v ;
bool flip = hint_text = = " attenuation " ;
2014-02-10 02:10:30 +01:00
2017-03-05 16:44:50 +01:00
Ref < Font > f = get_font ( " font " , " Label " ) ;
Color color = get_color ( " font_color " , " Label " ) ;
2014-02-10 02:10:30 +01:00
2017-03-05 16:44:50 +01:00
for ( int i = 1 ; i < = points ; i + + ) {
2014-02-10 02:10:30 +01:00
2017-03-05 16:44:50 +01:00
float ifl = i / float ( points ) ;
float iflp = ( i - 1 ) / float ( points ) ;
2014-02-10 02:10:30 +01:00
2017-03-05 16:44:50 +01:00
float h = 1.0 - Math : : ease ( ifl , exp ) ;
2014-02-10 02:10:30 +01:00
if ( flip ) {
2017-03-05 16:44:50 +01:00
ifl = 1.0 - ifl ;
iflp = 1.0 - iflp ;
2014-02-10 02:10:30 +01:00
}
2017-03-05 16:44:50 +01:00
VisualServer : : get_singleton ( ) - > canvas_item_add_line ( ci , Point2 ( iflp * s . width , prev * s . height ) , Point2 ( ifl * s . width , h * s . height ) , color ) ;
prev = h ;
2014-02-10 02:10:30 +01:00
}
2017-03-05 16:44:50 +01:00
f - > draw ( ci , Point2 ( 10 , 10 + f - > get_ascent ( ) ) , String : : num ( exp , 2 ) , color ) ;
2014-02-10 02:10:30 +01:00
}
void CustomPropertyEditor : : _text_edit_changed ( ) {
2017-03-05 16:44:50 +01:00
v = text_edit - > get_text ( ) ;
2014-02-10 02:10:30 +01:00
emit_signal ( " variant_changed " ) ;
}
2016-08-03 16:28:20 +02:00
void CustomPropertyEditor : : _create_dialog_callback ( ) {
2017-03-05 16:44:50 +01:00
v = create_dialog - > get_selected_type ( ) ;
2016-08-03 16:28:20 +02:00
emit_signal ( " variant_changed " ) ;
}
2017-03-05 16:44:50 +01:00
void CustomPropertyEditor : : _create_selected_property ( const String & p_prop ) {
2016-08-24 00:29:07 +02:00
2017-03-05 16:44:50 +01:00
v = p_prop ;
2016-08-24 00:29:07 +02:00
emit_signal ( " variant_changed " ) ;
}
2014-02-10 02:10:30 +01:00
void CustomPropertyEditor : : _modified ( String p_string ) {
2015-08-30 02:09:11 +02:00
2014-02-10 02:10:30 +01:00
if ( updating )
return ;
2017-08-26 17:46:49 +02:00
2017-03-05 16:44:50 +01:00
updating = true ;
switch ( type ) {
2016-08-04 03:06:39 +02:00
case Variant : : INT : {
if ( evaluator )
2017-03-05 16:44:50 +01:00
v = evaluator - > eval ( value_editor [ 0 ] - > get_text ( ) ) ;
2016-08-04 03:06:39 +02:00
else
2017-03-05 16:44:50 +01:00
v = value_editor [ 0 ] - > get_text ( ) . to_int ( ) ;
2016-08-04 03:06:39 +02:00
emit_signal ( " variant_changed " ) ;
} break ;
2014-02-10 02:10:30 +01:00
case Variant : : REAL : {
2017-03-05 16:44:50 +01:00
if ( hint ! = PROPERTY_HINT_EXP_EASING ) {
2016-05-01 10:33:32 +02:00
if ( evaluator )
2017-03-05 16:44:50 +01:00
v = evaluator - > eval ( value_editor [ 0 ] - > get_text ( ) ) ;
2016-05-01 10:33:32 +02:00
else
2017-03-05 16:44:50 +01:00
v = value_editor [ 0 ] - > get_text ( ) . to_double ( ) ;
2014-02-10 02:10:30 +01:00
emit_signal ( " variant_changed " ) ;
}
} break ;
case Variant : : STRING : {
2017-03-05 16:44:50 +01:00
v = value_editor [ 0 ] - > get_text ( ) ;
2014-02-10 02:10:30 +01:00
emit_signal ( " variant_changed " ) ;
} break ;
case Variant : : VECTOR2 : {
Vector2 vec ;
2016-05-01 10:33:32 +02:00
if ( evaluator ) {
2017-03-05 16:44:50 +01:00
vec . x = evaluator - > eval ( value_editor [ 0 ] - > get_text ( ) ) ;
vec . y = evaluator - > eval ( value_editor [ 1 ] - > get_text ( ) ) ;
2016-05-01 10:33:32 +02:00
} else {
2017-03-05 16:44:50 +01:00
vec . x = value_editor [ 0 ] - > get_text ( ) . to_double ( ) ;
vec . y = value_editor [ 1 ] - > get_text ( ) . to_double ( ) ;
2016-05-01 10:33:32 +02:00
}
2017-03-05 16:44:50 +01:00
v = vec ;
2017-03-02 10:42:05 +01:00
_emit_changed_whole_or_field ( ) ;
2014-02-10 02:10:30 +01:00
} break ;
case Variant : : RECT2 : {
Rect2 r2 ;
2016-05-01 10:33:32 +02:00
if ( evaluator ) {
2017-06-04 00:25:13 +02:00
r2 . position . x = evaluator - > eval ( value_editor [ 0 ] - > get_text ( ) ) ;
r2 . position . y = evaluator - > eval ( value_editor [ 1 ] - > get_text ( ) ) ;
2017-03-05 16:44:50 +01:00
r2 . size . x = evaluator - > eval ( value_editor [ 2 ] - > get_text ( ) ) ;
r2 . size . y = evaluator - > eval ( value_editor [ 3 ] - > get_text ( ) ) ;
2016-05-01 10:33:32 +02:00
} else {
2017-06-04 00:25:13 +02:00
r2 . position . x = value_editor [ 0 ] - > get_text ( ) . to_double ( ) ;
r2 . position . y = value_editor [ 1 ] - > get_text ( ) . to_double ( ) ;
2017-03-05 16:44:50 +01:00
r2 . size . x = value_editor [ 2 ] - > get_text ( ) . to_double ( ) ;
r2 . size . y = value_editor [ 3 ] - > get_text ( ) . to_double ( ) ;
2016-05-01 10:33:32 +02:00
}
2017-03-05 16:44:50 +01:00
v = r2 ;
2017-03-02 10:42:05 +01:00
_emit_changed_whole_or_field ( ) ;
2014-02-10 02:10:30 +01:00
} break ;
case Variant : : VECTOR3 : {
2015-08-30 02:09:11 +02:00
2014-02-10 02:10:30 +01:00
Vector3 vec ;
2016-05-01 10:33:32 +02:00
if ( evaluator ) {
2017-03-05 16:44:50 +01:00
vec . x = evaluator - > eval ( value_editor [ 0 ] - > get_text ( ) ) ;
vec . y = evaluator - > eval ( value_editor [ 1 ] - > get_text ( ) ) ;
vec . z = evaluator - > eval ( value_editor [ 2 ] - > get_text ( ) ) ;
2016-05-01 10:33:32 +02:00
} else {
2017-03-05 16:44:50 +01:00
vec . x = value_editor [ 0 ] - > get_text ( ) . to_double ( ) ;
vec . y = value_editor [ 1 ] - > get_text ( ) . to_double ( ) ;
vec . z = value_editor [ 2 ] - > get_text ( ) . to_double ( ) ;
2016-05-01 10:33:32 +02:00
}
2017-03-05 16:44:50 +01:00
v = vec ;
2017-03-02 10:42:05 +01:00
_emit_changed_whole_or_field ( ) ;
2015-08-30 02:09:11 +02:00
2014-02-10 02:10:30 +01:00
} break ;
case Variant : : PLANE : {
2015-08-30 02:09:11 +02:00
2014-02-10 02:10:30 +01:00
Plane pl ;
2016-05-01 10:33:32 +02:00
if ( evaluator ) {
2017-03-05 16:44:50 +01:00
pl . normal . x = evaluator - > eval ( value_editor [ 0 ] - > get_text ( ) ) ;
pl . normal . y = evaluator - > eval ( value_editor [ 1 ] - > get_text ( ) ) ;
pl . normal . z = evaluator - > eval ( value_editor [ 2 ] - > get_text ( ) ) ;
pl . d = evaluator - > eval ( value_editor [ 3 ] - > get_text ( ) ) ;
2016-05-01 10:33:32 +02:00
} else {
2017-03-05 16:44:50 +01:00
pl . normal . x = value_editor [ 0 ] - > get_text ( ) . to_double ( ) ;
pl . normal . y = value_editor [ 1 ] - > get_text ( ) . to_double ( ) ;
pl . normal . z = value_editor [ 2 ] - > get_text ( ) . to_double ( ) ;
pl . d = value_editor [ 3 ] - > get_text ( ) . to_double ( ) ;
2016-05-01 10:33:32 +02:00
}
2017-03-05 16:44:50 +01:00
v = pl ;
2017-03-02 10:42:05 +01:00
_emit_changed_whole_or_field ( ) ;
2015-08-30 02:09:11 +02:00
2014-02-10 02:10:30 +01:00
} break ;
case Variant : : QUAT : {
2015-08-30 02:09:11 +02:00
2014-02-10 02:10:30 +01:00
Quat q ;
2016-05-01 10:33:32 +02:00
if ( evaluator ) {
2017-03-05 16:44:50 +01:00
q . x = evaluator - > eval ( value_editor [ 0 ] - > get_text ( ) ) ;
q . y = evaluator - > eval ( value_editor [ 1 ] - > get_text ( ) ) ;
q . z = evaluator - > eval ( value_editor [ 2 ] - > get_text ( ) ) ;
q . w = evaluator - > eval ( value_editor [ 3 ] - > get_text ( ) ) ;
2016-05-01 10:33:32 +02:00
} else {
2017-03-05 16:44:50 +01:00
q . x = value_editor [ 0 ] - > get_text ( ) . to_double ( ) ;
q . y = value_editor [ 1 ] - > get_text ( ) . to_double ( ) ;
q . z = value_editor [ 2 ] - > get_text ( ) . to_double ( ) ;
q . w = value_editor [ 3 ] - > get_text ( ) . to_double ( ) ;
2016-05-01 10:33:32 +02:00
}
2017-03-05 16:44:50 +01:00
v = q ;
2017-03-02 10:42:05 +01:00
_emit_changed_whole_or_field ( ) ;
2015-08-30 02:09:11 +02:00
2014-02-10 02:10:30 +01:00
} break ;
2017-11-17 03:09:00 +01:00
case Variant : : AABB : {
2015-08-30 02:09:11 +02:00
2014-02-10 02:10:30 +01:00
Vector3 pos ;
Vector3 size ;
2015-08-30 02:09:11 +02:00
2016-05-01 10:33:32 +02:00
if ( evaluator ) {
2017-03-05 16:44:50 +01:00
pos . x = evaluator - > eval ( value_editor [ 0 ] - > get_text ( ) ) ;
pos . y = evaluator - > eval ( value_editor [ 1 ] - > get_text ( ) ) ;
pos . z = evaluator - > eval ( value_editor [ 2 ] - > get_text ( ) ) ;
size . x = evaluator - > eval ( value_editor [ 3 ] - > get_text ( ) ) ;
size . y = evaluator - > eval ( value_editor [ 4 ] - > get_text ( ) ) ;
size . z = evaluator - > eval ( value_editor [ 5 ] - > get_text ( ) ) ;
2016-05-01 10:33:32 +02:00
} else {
2017-03-05 16:44:50 +01:00
pos . x = value_editor [ 0 ] - > get_text ( ) . to_double ( ) ;
pos . y = value_editor [ 1 ] - > get_text ( ) . to_double ( ) ;
pos . z = value_editor [ 2 ] - > get_text ( ) . to_double ( ) ;
size . x = value_editor [ 3 ] - > get_text ( ) . to_double ( ) ;
size . y = value_editor [ 4 ] - > get_text ( ) . to_double ( ) ;
size . z = value_editor [ 5 ] - > get_text ( ) . to_double ( ) ;
2016-05-01 10:33:32 +02:00
}
2017-11-17 03:09:00 +01:00
v = AABB ( pos , size ) ;
2017-03-02 10:42:05 +01:00
_emit_changed_whole_or_field ( ) ;
2015-08-30 02:09:11 +02:00
2014-02-10 02:10:30 +01:00
} break ;
2017-01-11 04:52:51 +01:00
case Variant : : TRANSFORM2D : {
2014-02-10 02:10:30 +01:00
2017-01-11 04:52:51 +01:00
Transform2D m ;
2017-03-05 16:44:50 +01:00
for ( int i = 0 ; i < 6 ; i + + ) {
2016-05-01 10:33:32 +02:00
if ( evaluator ) {
2017-03-05 16:44:50 +01:00
m . elements [ i / 2 ] [ i % 2 ] = evaluator - > eval ( value_editor [ i ] - > get_text ( ) ) ;
2016-05-01 10:33:32 +02:00
} else {
2017-03-05 16:44:50 +01:00
m . elements [ i / 2 ] [ i % 2 ] = value_editor [ i ] - > get_text ( ) . to_double ( ) ;
2016-05-01 10:33:32 +02:00
}
2014-02-10 02:10:30 +01:00
}
2017-03-05 16:44:50 +01:00
v = m ;
2017-03-02 10:42:05 +01:00
_emit_changed_whole_or_field ( ) ;
2014-02-10 02:10:30 +01:00
} break ;
2017-01-11 04:52:51 +01:00
case Variant : : BASIS : {
2015-08-30 02:09:11 +02:00
2017-01-11 04:52:51 +01:00
Basis m ;
2017-03-05 16:44:50 +01:00
for ( int i = 0 ; i < 9 ; i + + ) {
2015-08-30 02:09:11 +02:00
2016-05-01 10:33:32 +02:00
if ( evaluator ) {
2017-03-05 16:44:50 +01:00
m . elements [ i / 3 ] [ i % 3 ] = evaluator - > eval ( value_editor [ i ] - > get_text ( ) ) ;
2016-05-01 10:33:32 +02:00
} else {
2017-03-05 16:44:50 +01:00
m . elements [ i / 3 ] [ i % 3 ] = value_editor [ i ] - > get_text ( ) . to_double ( ) ;
2016-05-01 10:33:32 +02:00
}
2014-02-10 02:10:30 +01:00
}
2015-08-30 02:09:11 +02:00
2017-03-05 16:44:50 +01:00
v = m ;
2017-03-02 10:42:05 +01:00
_emit_changed_whole_or_field ( ) ;
2015-08-30 02:09:11 +02:00
2014-02-10 02:10:30 +01:00
} break ;
case Variant : : TRANSFORM : {
2015-08-30 02:09:11 +02:00
2017-01-11 04:52:51 +01:00
Basis basis ;
2017-03-05 16:44:50 +01:00
for ( int i = 0 ; i < 9 ; i + + ) {
2015-08-30 02:09:11 +02:00
2016-05-01 10:33:32 +02:00
if ( evaluator ) {
2017-03-05 16:44:50 +01:00
basis . elements [ i / 3 ] [ i % 3 ] = evaluator - > eval ( value_editor [ ( i / 3 ) * 4 + i % 3 ] - > get_text ( ) ) ;
2016-05-01 10:33:32 +02:00
} else {
2017-03-05 16:44:50 +01:00
basis . elements [ i / 3 ] [ i % 3 ] = value_editor [ ( i / 3 ) * 4 + i % 3 ] - > get_text ( ) . to_double ( ) ;
2016-05-01 10:33:32 +02:00
}
2014-02-10 02:10:30 +01:00
}
2015-08-30 02:09:11 +02:00
2014-02-10 02:10:30 +01:00
Vector3 origin ;
2016-05-01 10:33:32 +02:00
if ( evaluator ) {
2017-03-05 16:44:50 +01:00
origin . x = evaluator - > eval ( value_editor [ 3 ] - > get_text ( ) ) ;
origin . y = evaluator - > eval ( value_editor [ 7 ] - > get_text ( ) ) ;
origin . z = evaluator - > eval ( value_editor [ 11 ] - > get_text ( ) ) ;
2016-05-01 10:33:32 +02:00
} else {
2017-03-05 16:44:50 +01:00
origin . x = value_editor [ 3 ] - > get_text ( ) . to_double ( ) ;
origin . y = value_editor [ 7 ] - > get_text ( ) . to_double ( ) ;
origin . z = value_editor [ 11 ] - > get_text ( ) . to_double ( ) ;
2016-05-01 10:33:32 +02:00
}
2015-08-30 02:09:11 +02:00
2017-03-05 16:44:50 +01:00
v = Transform ( basis , origin ) ;
2017-03-02 10:42:05 +01:00
_emit_changed_whole_or_field ( ) ;
2015-08-30 02:09:11 +02:00
2014-02-10 02:10:30 +01:00
} break ;
case Variant : : COLOR : {
2015-08-30 02:09:11 +02:00
2014-02-10 02:10:30 +01:00
} break ;
2015-08-30 02:09:11 +02:00
2014-02-10 02:10:30 +01:00
case Variant : : NODE_PATH : {
2015-08-30 02:09:11 +02:00
2017-03-05 16:44:50 +01:00
v = NodePath ( value_editor [ 0 ] - > get_text ( ) ) ;
2016-08-04 03:06:39 +02:00
emit_signal ( " variant_changed " ) ;
2014-02-10 02:10:30 +01:00
} break ;
case Variant : : DICTIONARY : {
2015-08-30 02:09:11 +02:00
2014-02-10 02:10:30 +01:00
} break ;
2017-01-11 04:52:51 +01:00
case Variant : : POOL_BYTE_ARRAY : {
2015-08-30 02:09:11 +02:00
2014-02-10 02:10:30 +01:00
} break ;
2017-01-11 04:52:51 +01:00
case Variant : : POOL_INT_ARRAY : {
2015-08-30 02:09:11 +02:00
2014-02-10 02:10:30 +01:00
} break ;
2017-01-11 04:52:51 +01:00
case Variant : : POOL_REAL_ARRAY : {
2015-08-30 02:09:11 +02:00
2014-02-10 02:10:30 +01:00
} break ;
2017-01-11 04:52:51 +01:00
case Variant : : POOL_STRING_ARRAY : {
2015-08-30 02:09:11 +02:00
2014-02-10 02:10:30 +01:00
} break ;
2017-01-11 04:52:51 +01:00
case Variant : : POOL_VECTOR3_ARRAY : {
2015-08-30 02:09:11 +02:00
2014-02-10 02:10:30 +01:00
} break ;
2017-01-11 04:52:51 +01:00
case Variant : : POOL_COLOR_ARRAY : {
2015-08-30 02:09:11 +02:00
2014-02-10 02:10:30 +01:00
} break ;
default : { }
2015-08-30 02:09:11 +02:00
}
2017-03-05 16:44:50 +01:00
updating = false ;
2014-02-10 02:10:30 +01:00
}
2017-03-02 10:42:05 +01:00
void CustomPropertyEditor : : _emit_changed_whole_or_field ( ) {
if ( ! Input : : get_singleton ( ) - > is_key_pressed ( KEY_SHIFT ) ) {
emit_signal ( " variant_changed " ) ;
} else {
2017-03-05 16:44:50 +01:00
emit_signal ( " variant_field_changed " , field_names [ focused_value_editor ] ) ;
2017-03-02 10:42:05 +01:00
}
}
2017-03-05 16:44:50 +01:00
void CustomPropertyEditor : : _range_modified ( double p_value ) {
v = p_value ;
2015-08-30 02:09:11 +02:00
emit_signal ( " variant_changed " ) ;
}
2014-02-27 15:16:00 +01:00
void CustomPropertyEditor : : _focus_enter ( ) {
2017-03-05 16:44:50 +01:00
switch ( type ) {
2014-02-27 15:16:00 +01:00
case Variant : : REAL :
case Variant : : STRING :
case Variant : : VECTOR2 :
case Variant : : RECT2 :
case Variant : : VECTOR3 :
case Variant : : PLANE :
case Variant : : QUAT :
2017-11-17 03:09:00 +01:00
case Variant : : AABB :
2017-01-11 04:52:51 +01:00
case Variant : : TRANSFORM2D :
case Variant : : BASIS :
2014-02-27 15:16:00 +01:00
case Variant : : TRANSFORM : {
2017-03-05 16:44:50 +01:00
for ( int i = 0 ; i < MAX_VALUE_EDITORS ; + + i ) {
2014-02-27 15:16:00 +01:00
if ( value_editor [ i ] - > has_focus ( ) ) {
2017-03-05 16:44:50 +01:00
focused_value_editor = i ;
2014-02-27 15:16:00 +01:00
value_editor [ i ] - > select_all ( ) ;
break ;
}
}
} break ;
default : { }
}
}
void CustomPropertyEditor : : _focus_exit ( ) {
2017-03-05 16:44:50 +01:00
switch ( type ) {
2014-02-27 15:16:00 +01:00
case Variant : : REAL :
case Variant : : STRING :
case Variant : : VECTOR2 :
case Variant : : RECT2 :
case Variant : : VECTOR3 :
case Variant : : PLANE :
case Variant : : QUAT :
2017-11-17 03:09:00 +01:00
case Variant : : AABB :
2017-01-11 04:52:51 +01:00
case Variant : : TRANSFORM2D :
case Variant : : BASIS :
2014-02-27 15:16:00 +01:00
case Variant : : TRANSFORM : {
2017-03-05 16:44:50 +01:00
for ( int i = 0 ; i < MAX_VALUE_EDITORS ; + + i ) {
2014-02-27 15:16:00 +01:00
value_editor [ i ] - > select ( 0 , 0 ) ;
}
} break ;
default : { }
}
}
2017-03-05 16:44:50 +01:00
void CustomPropertyEditor : : config_action_buttons ( const List < String > & p_strings ) {
2014-02-10 02:10:30 +01:00
2017-12-23 21:54:45 +01:00
Ref < StyleBox > sb = get_stylebox ( " panel " ) ;
int margin_top = sb - > get_margin ( MARGIN_TOP ) ;
int margin_left = sb - > get_margin ( MARGIN_LEFT ) ;
int margin_bottom = sb - > get_margin ( MARGIN_BOTTOM ) ;
int margin_right = sb - > get_margin ( MARGIN_RIGHT ) ;
2014-02-10 02:10:30 +01:00
2017-12-23 21:54:45 +01:00
int max_width = 0 ;
int height = 0 ;
2014-02-10 02:10:30 +01:00
2017-03-05 16:44:50 +01:00
for ( int i = 0 ; i < MAX_ACTION_BUTTONS ; i + + ) {
2015-08-30 02:09:11 +02:00
2017-03-05 16:44:50 +01:00
if ( i < p_strings . size ( ) ) {
2017-12-23 21:54:45 +01:00
2014-02-10 02:10:30 +01:00
action_buttons [ i ] - > show ( ) ;
2015-08-30 02:09:11 +02:00
action_buttons [ i ] - > set_text ( p_strings [ i ] ) ;
2017-12-23 21:54:45 +01:00
Size2 btn_m_size = action_buttons [ i ] - > get_minimum_size ( ) ;
if ( btn_m_size . width > max_width )
max_width = btn_m_size . width ;
2014-02-10 02:10:30 +01:00
} else {
action_buttons [ i ] - > hide ( ) ;
}
}
2017-12-23 21:54:45 +01:00
for ( int i = 0 ; i < p_strings . size ( ) ; i + + ) {
Size2 btn_m_size = action_buttons [ i ] - > get_size ( ) ;
action_buttons [ i ] - > set_position ( Point2 ( 0 , height ) + Point2 ( margin_left , margin_top ) ) ;
action_buttons [ i ] - > set_size ( Size2 ( max_width , btn_m_size . height ) ) ;
height + = btn_m_size . height ;
}
set_size ( Size2 ( max_width , height ) + Size2 ( margin_left + margin_right , margin_top + margin_bottom ) ) ;
2014-02-10 02:10:30 +01:00
}
2017-03-05 16:44:50 +01:00
void CustomPropertyEditor : : config_value_editors ( int p_amount , int p_columns , int p_label_w , const List < String > & p_strings ) {
2015-08-30 02:09:11 +02:00
2017-10-28 02:22:52 +02:00
int cell_width = 95 ;
int cell_height = 25 ;
int cell_margin = 5 ;
int hor_spacing = 5 ; // Spacing between labels and their values
2015-08-30 02:09:11 +02:00
2017-03-05 16:44:50 +01:00
int rows = ( ( p_amount - 1 ) / p_columns ) + 1 ;
2015-08-30 02:09:11 +02:00
2017-10-28 02:22:52 +02:00
set_size ( Size2 ( cell_margin + p_label_w + ( cell_width + cell_margin + p_label_w ) * p_columns , cell_margin + ( cell_height + cell_margin ) * rows ) * EDSCALE ) ;
2015-08-30 02:09:11 +02:00
2017-03-05 16:44:50 +01:00
for ( int i = 0 ; i < MAX_VALUE_EDITORS ; i + + ) {
2015-08-30 02:09:11 +02:00
2017-03-05 16:44:50 +01:00
int c = i % p_columns ;
int r = i / p_columns ;
2015-08-30 02:09:11 +02:00
2017-03-05 16:44:50 +01:00
if ( i < p_amount ) {
2014-02-10 02:10:30 +01:00
value_editor [ i ] - > show ( ) ;
value_label [ i ] - > show ( ) ;
2017-03-05 16:44:50 +01:00
value_label [ i ] - > set_text ( i < p_strings . size ( ) ? p_strings [ i ] : String ( " " ) ) ;
2017-10-28 02:22:52 +02:00
value_editor [ i ] - > set_position ( Point2 ( cell_margin + p_label_w + hor_spacing + ( cell_width + cell_margin + p_label_w + hor_spacing ) * c , cell_margin + ( cell_height + cell_margin ) * r ) * EDSCALE ) ;
2017-10-24 20:18:42 +02:00
value_editor [ i ] - > set_size ( Size2 ( cell_width , cell_height ) ) ;
2017-10-28 02:22:52 +02:00
value_label [ i ] - > set_position ( Point2 ( cell_margin + ( cell_width + cell_margin + p_label_w + hor_spacing ) * c , cell_margin + ( cell_height + cell_margin ) * r ) * EDSCALE ) ;
2014-02-10 02:10:30 +01:00
value_editor [ i ] - > set_editable ( ! read_only ) ;
} else {
value_editor [ i ] - > hide ( ) ;
value_label [ i ] - > hide ( ) ;
}
}
}
void CustomPropertyEditor : : _bind_methods ( ) {
2015-08-30 02:09:11 +02:00
2017-01-03 03:03:46 +01:00
ClassDB : : bind_method ( " _focus_enter " , & CustomPropertyEditor : : _focus_enter ) ;
ClassDB : : bind_method ( " _focus_exit " , & CustomPropertyEditor : : _focus_exit ) ;
2017-03-05 16:44:50 +01:00
ClassDB : : bind_method ( " _modified " , & CustomPropertyEditor : : _modified ) ;
2017-01-03 03:03:46 +01:00
ClassDB : : bind_method ( " _range_modified " , & CustomPropertyEditor : : _range_modified ) ;
2017-03-05 16:44:50 +01:00
ClassDB : : bind_method ( " _action_pressed " , & CustomPropertyEditor : : _action_pressed ) ;
ClassDB : : bind_method ( " _file_selected " , & CustomPropertyEditor : : _file_selected ) ;
ClassDB : : bind_method ( " _type_create_selected " , & CustomPropertyEditor : : _type_create_selected ) ;
ClassDB : : bind_method ( " _node_path_selected " , & CustomPropertyEditor : : _node_path_selected ) ;
ClassDB : : bind_method ( " _color_changed " , & CustomPropertyEditor : : _color_changed ) ;
ClassDB : : bind_method ( " _draw_easing " , & CustomPropertyEditor : : _draw_easing ) ;
ClassDB : : bind_method ( " _drag_easing " , & CustomPropertyEditor : : _drag_easing ) ;
ClassDB : : bind_method ( " _text_edit_changed " , & CustomPropertyEditor : : _text_edit_changed ) ;
ClassDB : : bind_method ( " _menu_option " , & CustomPropertyEditor : : _menu_option ) ;
ClassDB : : bind_method ( " _create_dialog_callback " , & CustomPropertyEditor : : _create_dialog_callback ) ;
ClassDB : : bind_method ( " _create_selected_property " , & CustomPropertyEditor : : _create_selected_property ) ;
ADD_SIGNAL ( MethodInfo ( " variant_changed " ) ) ;
ADD_SIGNAL ( MethodInfo ( " variant_field_changed " , PropertyInfo ( Variant : : STRING , " field " ) ) ) ;
ADD_SIGNAL ( MethodInfo ( " resource_edit_request " ) ) ;
2014-02-10 02:10:30 +01:00
}
CustomPropertyEditor : : CustomPropertyEditor ( ) {
2015-08-30 02:09:11 +02:00
2017-03-05 16:44:50 +01:00
read_only = false ;
updating = false ;
2015-08-30 02:09:11 +02:00
2017-03-05 16:44:50 +01:00
for ( int i = 0 ; i < MAX_VALUE_EDITORS ; i + + ) {
2015-08-30 02:09:11 +02:00
2017-03-05 16:44:50 +01:00
value_editor [ i ] = memnew ( LineEdit ) ;
add_child ( value_editor [ i ] ) ;
value_label [ i ] = memnew ( Label ) ;
add_child ( value_label [ i ] ) ;
2014-02-10 02:10:30 +01:00
value_editor [ i ] - > hide ( ) ;
value_label [ i ] - > hide ( ) ;
2017-03-05 16:44:50 +01:00
value_editor [ i ] - > connect ( " text_entered " , this , " _modified " ) ;
2017-01-12 04:51:08 +01:00
value_editor [ i ] - > connect ( " focus_entered " , this , " _focus_enter " ) ;
value_editor [ i ] - > connect ( " focus_exited " , this , " _focus_exit " ) ;
2014-02-10 02:10:30 +01:00
}
2017-03-05 16:44:50 +01:00
focused_value_editor = - 1 ;
2015-08-30 02:09:11 +02:00
2017-03-05 16:44:50 +01:00
for ( int i = 0 ; i < 4 ; i + + ) {
2016-01-23 15:20:54 +01:00
2017-03-05 16:44:50 +01:00
scroll [ i ] = memnew ( HScrollBar ) ;
2016-01-23 15:20:54 +01:00
scroll [ i ] - > hide ( ) ;
scroll [ i ] - > set_min ( 0 ) ;
scroll [ i ] - > set_max ( 1.0 ) ;
scroll [ i ] - > set_step ( 0.01 ) ;
add_child ( scroll [ i ] ) ;
}
2017-03-05 16:44:50 +01:00
checks20gc = memnew ( GridContainer ) ;
2017-01-11 02:20:57 +01:00
add_child ( checks20gc ) ;
checks20gc - > set_columns ( 11 ) ;
2017-03-05 16:44:50 +01:00
for ( int i = 0 ; i < 20 ; i + + ) {
if ( i = = 5 | | i = = 15 ) {
Control * space = memnew ( Control ) ;
space - > set_custom_minimum_size ( Size2 ( 20 , 0 ) * EDSCALE ) ;
2017-01-11 02:20:57 +01:00
checks20gc - > add_child ( space ) ;
}
2017-03-05 16:44:50 +01:00
checks20 [ i ] = memnew ( CheckBox ) ;
2014-05-14 06:22:15 +02:00
checks20 [ i ] - > set_toggle_mode ( true ) ;
2017-03-05 16:44:50 +01:00
checks20 [ i ] - > set_focus_mode ( FOCUS_NONE ) ;
2017-01-11 02:20:57 +01:00
checks20gc - > add_child ( checks20 [ i ] ) ;
2014-02-10 02:10:30 +01:00
checks20 [ i ] - > hide ( ) ;
2017-03-05 16:44:50 +01:00
checks20 [ i ] - > connect ( " pressed " , this , " _action_pressed " , make_binds ( i ) ) ;
checks20 [ i ] - > set_tooltip ( vformat ( TTR ( " Bit %d, val %d. " ) , i , 1 < < i ) ) ;
2014-02-10 02:10:30 +01:00
}
2017-03-05 16:44:50 +01:00
text_edit = memnew ( TextEdit ) ;
2014-02-10 02:10:30 +01:00
add_child ( text_edit ) ;
2017-09-22 00:12:33 +02:00
text_edit - > set_anchors_and_margins_preset ( Control : : PRESET_WIDE , Control : : PRESET_MODE_MINSIZE , 5 ) ;
2017-08-19 19:10:00 +02:00
text_edit - > set_margin ( MARGIN_BOTTOM , - 30 ) ;
2014-02-10 02:10:30 +01:00
text_edit - > hide ( ) ;
2017-03-05 16:44:50 +01:00
text_edit - > connect ( " text_changed " , this , " _text_edit_changed " ) ;
2014-02-10 02:10:30 +01:00
2017-03-05 16:44:50 +01:00
for ( int i = 0 ; i < MAX_ACTION_BUTTONS ; i + + ) {
2015-08-30 02:09:11 +02:00
2017-03-05 16:44:50 +01:00
action_buttons [ i ] = memnew ( Button ) ;
2015-08-30 02:09:11 +02:00
action_buttons [ i ] - > hide ( ) ;
2014-02-10 02:10:30 +01:00
add_child ( action_buttons [ i ] ) ;
Vector < Variant > binds ;
binds . push_back ( i ) ;
2017-03-05 16:44:50 +01:00
action_buttons [ i ] - > connect ( " pressed " , this , " _action_pressed " , binds ) ;
2017-12-23 21:54:45 +01:00
action_buttons [ i ] - > set_flat ( true ) ;
2014-02-10 02:10:30 +01:00
}
2015-08-30 02:09:11 +02:00
2017-03-05 16:44:50 +01:00
color_picker = NULL ;
2014-02-10 02:10:30 +01:00
set_as_toplevel ( true ) ;
2017-03-05 16:44:50 +01:00
file = memnew ( EditorFileDialog ) ;
2014-02-10 02:10:30 +01:00
add_child ( file ) ;
file - > hide ( ) ;
2015-08-30 02:09:11 +02:00
2017-03-05 16:44:50 +01:00
file - > connect ( " file_selected " , this , " _file_selected " ) ;
file - > connect ( " dir_selected " , this , " _file_selected " ) ;
2014-02-10 02:10:30 +01:00
2017-03-05 16:44:50 +01:00
error = memnew ( ConfirmationDialog ) ;
2016-05-04 03:25:37 +02:00
error - > set_title ( TTR ( " Error! " ) ) ;
2014-02-10 02:10:30 +01:00
add_child ( error ) ;
2015-08-30 02:09:11 +02:00
2017-03-05 16:44:50 +01:00
scene_tree = memnew ( SceneTreeDialog ) ;
2014-02-10 02:10:30 +01:00
add_child ( scene_tree ) ;
2017-03-05 16:44:50 +01:00
scene_tree - > connect ( " selected " , this , " _node_path_selected " ) ;
2015-06-22 05:03:19 +02:00
scene_tree - > get_scene_tree ( ) - > set_show_enabled_subscene ( true ) ;
2014-02-10 02:10:30 +01:00
2017-03-05 16:44:50 +01:00
texture_preview = memnew ( TextureRect ) ;
add_child ( texture_preview ) ;
2014-02-10 02:10:30 +01:00
texture_preview - > hide ( ) ;
2017-03-05 16:44:50 +01:00
easing_draw = memnew ( Control ) ;
2014-02-10 02:10:30 +01:00
add_child ( easing_draw ) ;
easing_draw - > hide ( ) ;
2017-03-05 16:44:50 +01:00
easing_draw - > connect ( " draw " , this , " _draw_easing " ) ;
easing_draw - > connect ( " gui_input " , this , " _drag_easing " ) ;
2014-02-10 02:10:30 +01:00
easing_draw - > set_default_cursor_shape ( Control : : CURSOR_MOVE ) ;
2017-07-29 12:38:16 +02:00
type_button = memnew ( MenuButton ) ;
add_child ( type_button ) ;
type_button - > hide ( ) ;
type_button - > get_popup ( ) - > connect ( " id_pressed " , this , " _type_create_selected " ) ;
2014-02-10 02:10:30 +01:00
menu = memnew ( PopupMenu ) ;
2017-11-22 09:43:40 +01:00
menu - > set_pass_on_modal_close_click ( false ) ;
2014-02-10 02:10:30 +01:00
add_child ( menu ) ;
2017-03-05 16:44:50 +01:00
menu - > connect ( " id_pressed " , this , " _menu_option " ) ;
2015-08-30 02:09:11 +02:00
2016-05-01 10:33:32 +02:00
evaluator = NULL ;
2017-03-05 16:44:50 +01:00
spinbox = memnew ( SpinBox ) ;
2015-08-30 02:09:11 +02:00
add_child ( spinbox ) ;
2017-09-22 00:12:33 +02:00
spinbox - > set_anchors_and_margins_preset ( Control : : PRESET_WIDE , Control : : PRESET_MODE_MINSIZE , 5 ) ;
2017-03-05 16:44:50 +01:00
spinbox - > connect ( " value_changed " , this , " _range_modified " ) ;
2015-08-30 02:09:11 +02:00
2017-03-05 16:44:50 +01:00
slider = memnew ( HSlider ) ;
2015-08-30 02:09:11 +02:00
add_child ( slider ) ;
2017-09-22 00:12:33 +02:00
slider - > set_anchors_and_margins_preset ( Control : : PRESET_WIDE , Control : : PRESET_MODE_MINSIZE , 5 ) ;
2017-03-05 16:44:50 +01:00
slider - > connect ( " value_changed " , this , " _range_modified " ) ;
2016-08-03 16:28:20 +02:00
create_dialog = NULL ;
2016-08-24 00:29:07 +02:00
property_select = NULL ;
2014-02-10 02:10:30 +01:00
}
2015-10-10 14:09:09 +02:00
bool PropertyEditor : : _might_be_in_instance ( ) {
2014-02-10 02:10:30 +01:00
if ( ! obj )
2016-05-01 10:33:32 +02:00
return false ;
2014-02-10 02:10:30 +01:00
2017-08-24 22:58:51 +02:00
Node * node = Object : : cast_to < Node > ( obj ) ;
2015-10-10 14:09:09 +02:00
2017-03-05 16:44:50 +01:00
Node * edited_scene = EditorNode : : get_singleton ( ) - > get_edited_scene ( ) ;
2015-10-10 14:09:09 +02:00
2017-03-05 16:44:50 +01:00
bool might_be = false ;
2015-10-10 14:09:09 +02:00
2017-03-05 16:44:50 +01:00
while ( node ) {
2015-10-10 14:09:09 +02:00
if ( node - > get_scene_instance_state ( ) . is_valid ( ) ) {
2017-03-05 16:44:50 +01:00
might_be = true ;
2015-10-10 14:09:09 +02:00
break ;
}
2017-03-05 16:44:50 +01:00
if ( node = = edited_scene ) {
2015-10-10 14:09:09 +02:00
if ( node - > get_scene_inherited_state ( ) . is_valid ( ) ) {
2017-03-05 16:44:50 +01:00
might_be = true ;
2015-10-10 14:09:09 +02:00
break ;
}
2017-03-05 16:44:50 +01:00
might_be = false ;
2015-10-10 14:09:09 +02:00
break ;
}
2017-03-05 16:44:50 +01:00
node = node - > get_owner ( ) ;
2015-10-10 14:09:09 +02:00
}
return might_be ;
}
2017-03-05 16:44:50 +01:00
bool PropertyEditor : : _get_instanced_node_original_property ( const StringName & p_prop , Variant & value ) {
2015-10-10 14:09:09 +02:00
2017-08-24 22:58:51 +02:00
Node * node = Object : : cast_to < Node > ( obj ) ;
2015-10-10 14:09:09 +02:00
2014-02-10 02:10:30 +01:00
if ( ! node )
2015-10-10 14:09:09 +02:00
return false ;
2014-02-10 02:10:30 +01:00
2017-03-05 16:44:50 +01:00
Node * orig = node ;
2015-10-10 14:09:09 +02:00
2017-03-05 16:44:50 +01:00
Node * edited_scene = EditorNode : : get_singleton ( ) - > get_edited_scene ( ) ;
2015-10-10 14:09:09 +02:00
2017-03-05 16:44:50 +01:00
bool found = false ;
2014-02-10 02:10:30 +01:00
2017-03-05 16:44:50 +01:00
while ( node ) {
2014-02-10 02:10:30 +01:00
2015-10-10 14:09:09 +02:00
Ref < SceneState > ss ;
2017-03-05 16:44:50 +01:00
if ( node = = edited_scene ) {
ss = node - > get_scene_inherited_state ( ) ;
2015-10-17 23:28:36 +02:00
2015-10-10 14:09:09 +02:00
} else {
2017-03-05 16:44:50 +01:00
ss = node - > get_scene_instance_state ( ) ;
2015-10-10 14:09:09 +02:00
}
if ( ss . is_valid ( ) ) {
2015-10-17 23:28:36 +02:00
2015-10-10 14:09:09 +02:00
NodePath np = node - > get_path_to ( orig ) ;
int node_idx = ss - > find_node_by_path ( np ) ;
2017-03-05 16:44:50 +01:00
if ( node_idx > = 0 ) {
bool lfound = false ;
2015-10-10 14:09:09 +02:00
Variant lvar ;
2017-03-05 16:44:50 +01:00
lvar = ss - > get_property_value ( node_idx , p_prop , lfound ) ;
2015-10-10 14:09:09 +02:00
if ( lfound ) {
2015-10-17 23:28:36 +02:00
2017-03-05 16:44:50 +01:00
found = true ;
value = lvar ;
2015-10-10 14:09:09 +02:00
}
}
}
2017-03-05 16:44:50 +01:00
if ( node = = edited_scene ) {
2015-10-10 14:09:09 +02:00
//just in case
break ;
}
2017-03-05 16:44:50 +01:00
node = node - > get_owner ( ) ;
2015-10-10 14:09:09 +02:00
}
return found ;
}
2017-03-05 16:44:50 +01:00
bool PropertyEditor : : _is_property_different ( const Variant & p_current , const Variant & p_orig , int p_usage ) {
2015-10-17 23:28:36 +02:00
{
2017-08-24 22:58:51 +02:00
Node * node = Object : : cast_to < Node > ( obj ) ;
2015-10-17 23:28:36 +02:00
if ( ! node )
return false ;
2017-03-05 16:44:50 +01:00
Node * edited_scene = EditorNode : : get_singleton ( ) - > get_edited_scene ( ) ;
bool found_state = false ;
2015-10-17 23:28:36 +02:00
2017-03-05 16:44:50 +01:00
while ( node ) {
2015-10-17 23:28:36 +02:00
Ref < SceneState > ss ;
2017-03-05 16:44:50 +01:00
if ( node = = edited_scene ) {
ss = node - > get_scene_inherited_state ( ) ;
2015-10-17 23:28:36 +02:00
} else {
2017-03-05 16:44:50 +01:00
ss = node - > get_scene_instance_state ( ) ;
2015-10-17 23:28:36 +02:00
}
if ( ss . is_valid ( ) ) {
2017-03-05 16:44:50 +01:00
found_state = true ;
2015-10-17 23:28:36 +02:00
}
2017-03-05 16:44:50 +01:00
if ( node = = edited_scene ) {
2015-10-17 23:28:36 +02:00
//just in case
break ;
}
2017-03-05 16:44:50 +01:00
node = node - > get_owner ( ) ;
2015-10-17 23:28:36 +02:00
}
if ( ! found_state )
return false ; //pointless to check if we are not comparing against anything.
}
2017-03-05 16:44:50 +01:00
if ( p_orig . get_type ( ) = = Variant : : NIL ) {
2015-10-17 23:28:36 +02:00
2015-10-10 14:09:09 +02:00
//special cases
2017-03-05 16:44:50 +01:00
if ( p_current . is_zero ( ) & & p_usage & PROPERTY_USAGE_STORE_IF_NONZERO )
2015-10-10 14:09:09 +02:00
return false ;
2017-03-05 16:44:50 +01:00
if ( p_current . is_one ( ) & & p_usage & PROPERTY_USAGE_STORE_IF_NONONE )
2015-10-10 14:09:09 +02:00
return false ;
}
2017-03-05 16:44:50 +01:00
if ( p_current . get_type ( ) = = Variant : : REAL & & p_orig . get_type ( ) = = Variant : : REAL ) {
2016-06-13 00:33:07 +02:00
float a = p_current ;
float b = p_orig ;
2017-03-05 16:44:50 +01:00
return Math : : abs ( a - b ) > CMP_EPSILON ; //this must be done because, as some scenes save as text, there might be a tiny difference in floats due to numerical error
2016-06-13 00:33:07 +02:00
}
2017-03-05 16:44:50 +01:00
return bool ( Variant : : evaluate ( Variant : : OP_NOT_EQUAL , p_current , p_orig ) ) ;
2014-02-10 02:10:30 +01:00
}
2017-12-04 14:17:58 +01:00
bool PropertyEditor : : _is_instanced_node_with_original_property_different ( const String & p_name , TreeItem * item ) {
bool mbi = _might_be_in_instance ( ) ;
if ( mbi ) {
Variant vorig ;
Dictionary d = item - > get_metadata ( 0 ) ;
int usage = d . has ( " usage " ) ? int ( int ( d [ " usage " ] ) & ( PROPERTY_USAGE_STORE_IF_NONONE | PROPERTY_USAGE_STORE_IF_NONZERO ) ) : 0 ;
if ( _get_instanced_node_original_property ( p_name , vorig ) | | usage ) {
Variant v = obj - > get ( p_name ) ;
if ( _is_property_different ( v , vorig , usage ) ) {
return true ;
}
}
}
return false ;
}
2017-03-05 16:44:50 +01:00
TreeItem * PropertyEditor : : find_item ( TreeItem * p_item , const String & p_name ) {
2015-08-30 02:09:11 +02:00
2014-02-10 02:10:30 +01:00
if ( ! p_item )
return NULL ;
2015-08-30 02:09:11 +02:00
2014-02-10 02:10:30 +01:00
String name = p_item - > get_metadata ( 1 ) ;
2015-08-30 02:09:11 +02:00
2017-03-05 16:44:50 +01:00
if ( name = = p_name ) {
2015-08-30 02:09:11 +02:00
2014-02-10 02:10:30 +01:00
return p_item ;
}
2015-08-30 02:09:11 +02:00
2017-03-05 16:44:50 +01:00
TreeItem * c = p_item - > get_children ( ) ;
2015-08-30 02:09:11 +02:00
2014-02-10 02:10:30 +01:00
while ( c ) {
2015-08-30 02:09:11 +02:00
2017-03-05 16:44:50 +01:00
TreeItem * found = find_item ( c , p_name ) ;
2014-02-10 02:10:30 +01:00
if ( found )
return found ;
2017-03-05 16:44:50 +01:00
c = c - > get_next ( ) ;
2014-02-10 02:10:30 +01:00
}
2015-08-30 02:09:11 +02:00
2014-02-10 02:10:30 +01:00
return NULL ;
}
2017-03-05 16:44:50 +01:00
void PropertyEditor : : _changed_callback ( Object * p_changed , const char * p_prop ) {
2014-02-10 02:10:30 +01:00
2017-03-05 16:44:50 +01:00
_changed_callbacks ( p_changed , p_prop ) ;
2014-02-10 02:10:30 +01:00
}
2017-03-05 16:44:50 +01:00
void PropertyEditor : : _changed_callbacks ( Object * p_changed , const String & p_prop ) {
2014-02-10 02:10:30 +01:00
2017-03-05 16:44:50 +01:00
if ( p_changed ! = obj )
2014-02-10 02:10:30 +01:00
return ;
if ( changing )
return ;
2017-03-05 16:44:50 +01:00
if ( p_prop = = String ( ) )
update_tree_pending = true ;
2014-02-10 02:10:30 +01:00
else {
2015-08-30 02:09:11 +02:00
2017-03-05 16:44:50 +01:00
pending [ p_prop ] = p_prop ;
2014-02-10 02:10:30 +01:00
}
}
2017-03-05 16:44:50 +01:00
void PropertyEditor : : update_property ( const String & p_prop ) {
2014-02-10 02:10:30 +01:00
if ( obj )
2017-03-05 16:44:50 +01:00
_changed_callbacks ( obj , p_prop ) ;
2014-02-10 02:10:30 +01:00
}
2017-03-05 16:44:50 +01:00
void PropertyEditor : : set_item_text ( TreeItem * p_item , int p_type , const String & p_name , int p_hint , const String & p_hint_text ) {
2014-02-10 02:10:30 +01:00
2017-03-05 16:44:50 +01:00
switch ( p_type ) {
2014-02-10 02:10:30 +01:00
case Variant : : BOOL : {
2017-03-05 16:44:50 +01:00
p_item - > set_checked ( 1 , obj - > get ( p_name ) ) ;
2014-02-10 02:10:30 +01:00
} break ;
case Variant : : REAL :
case Variant : : INT : {
2017-03-05 16:44:50 +01:00
if ( p_hint = = PROPERTY_HINT_LAYERS_2D_PHYSICS | | p_hint = = PROPERTY_HINT_LAYERS_2D_RENDER | | p_hint = = PROPERTY_HINT_LAYERS_3D_PHYSICS | | p_hint = = PROPERTY_HINT_LAYERS_3D_RENDER ) {
2014-02-10 02:10:30 +01:00
tree - > update ( ) ;
break ;
}
2017-03-05 16:44:50 +01:00
if ( p_hint = = PROPERTY_HINT_FLAGS ) {
2014-02-10 02:10:30 +01:00
Vector < String > values = p_hint_text . split ( " , " ) ;
String flags ;
int val = obj - > get ( p_name ) ;
2017-03-05 16:44:50 +01:00
for ( int i = 0 ; i < values . size ( ) ; i + + ) {
2014-02-10 02:10:30 +01:00
String v = values [ i ] ;
2017-03-05 16:44:50 +01:00
if ( v = = " " )
2014-02-10 02:10:30 +01:00
continue ;
2017-03-05 16:44:50 +01:00
if ( ! ( val & ( 1 < < i ) ) )
2014-02-10 02:10:30 +01:00
continue ;
2017-03-05 16:44:50 +01:00
if ( flags ! = " " )
flags + = " , " ;
flags + = v ;
2014-02-10 02:10:30 +01:00
}
2017-03-05 16:44:50 +01:00
p_item - > set_text ( 1 , flags ) ;
2014-02-10 02:10:30 +01:00
break ;
}
2017-03-05 16:44:50 +01:00
if ( p_hint = = PROPERTY_HINT_EXP_EASING ) {
2014-02-10 02:10:30 +01:00
2017-03-05 16:44:50 +01:00
p_item - > set_text ( 1 , String : : num ( obj - > get ( p_name ) , 2 ) ) ;
2014-02-10 02:10:30 +01:00
break ;
}
2017-03-05 16:44:50 +01:00
if ( p_type = = Variant : : REAL ) {
p_item - > set_range ( 1 , obj - > get ( p_name ) ) ;
2014-02-10 02:10:30 +01:00
} else {
2017-02-23 09:28:09 +01:00
/* FIXME: Why are both statements equal? */
2017-03-05 16:44:50 +01:00
p_item - > set_range ( 1 , obj - > get ( p_name ) ) ;
2014-02-10 02:10:30 +01:00
}
2017-03-05 16:44:50 +01:00
p_item - > set_editable ( 1 , ! read_only ) ;
2014-02-10 02:10:30 +01:00
} break ;
case Variant : : STRING :
2017-03-05 16:44:50 +01:00
if ( p_hint = = PROPERTY_HINT_TYPE_STRING ) {
2016-08-03 16:28:20 +02:00
2017-03-05 16:44:50 +01:00
p_item - > set_text ( 1 , obj - > get ( p_name ) ) ;
2016-08-03 16:28:20 +02:00
}
2017-03-05 16:44:50 +01:00
if ( p_hint = = PROPERTY_HINT_METHOD_OF_VARIANT_TYPE | |
p_hint = = PROPERTY_HINT_METHOD_OF_BASE_TYPE | |
p_hint = = PROPERTY_HINT_METHOD_OF_INSTANCE | |
p_hint = = PROPERTY_HINT_METHOD_OF_SCRIPT | |
p_hint = = PROPERTY_HINT_PROPERTY_OF_VARIANT_TYPE | |
p_hint = = PROPERTY_HINT_PROPERTY_OF_BASE_TYPE | |
p_hint = = PROPERTY_HINT_PROPERTY_OF_INSTANCE | |
p_hint = = PROPERTY_HINT_PROPERTY_OF_SCRIPT ) {
2016-08-24 00:29:07 +02:00
2017-03-05 16:44:50 +01:00
p_item - > set_text ( 1 , obj - > get ( p_name ) ) ;
2016-08-24 00:29:07 +02:00
}
2017-03-05 16:44:50 +01:00
if ( p_hint = = PROPERTY_HINT_ENUM ) {
2014-02-10 02:10:30 +01:00
Vector < String > strings = p_hint_text . split ( " , " ) ;
String current = obj - > get ( p_name ) ;
2017-03-05 16:44:50 +01:00
int idx = 0 ;
for ( int x = 0 ; x < strings . size ( ) ; x + + ) {
if ( strings [ x ] = = current ) {
idx = x ;
2014-02-10 02:10:30 +01:00
break ;
}
}
p_item - > set_text ( 1 , p_hint_text ) ;
2017-03-05 16:44:50 +01:00
p_item - > set_range ( 1 , idx ) ;
2014-02-10 02:10:30 +01:00
break ;
}
case Variant : : VECTOR3 :
case Variant : : QUAT :
case Variant : : VECTOR2 :
2017-11-17 03:09:00 +01:00
case Variant : : AABB :
2014-02-10 02:10:30 +01:00
case Variant : : RECT2 :
2017-01-11 04:52:51 +01:00
case Variant : : TRANSFORM2D :
case Variant : : BASIS :
2014-02-10 02:10:30 +01:00
case Variant : : TRANSFORM : {
2017-03-05 16:44:50 +01:00
p_item - > set_text ( 1 , obj - > get ( p_name ) ) ;
2014-02-10 02:10:30 +01:00
} break ;
case Variant : : COLOR : {
2017-01-15 17:46:42 +01:00
tree - > update ( ) ;
2014-02-10 02:10:30 +01:00
} break ;
case Variant : : NODE_PATH : {
2017-03-05 16:44:50 +01:00
p_item - > set_text ( 1 , obj - > get ( p_name ) ) ;
2014-02-10 02:10:30 +01:00
} break ;
case Variant : : OBJECT : {
2017-08-18 15:59:31 +02:00
Ref < EncodedObjectAsID > encoded = obj - > get ( p_name ) ; //for debugger and remote tools
if ( encoded . is_valid ( ) ) {
p_item - > set_text ( 1 , " Object: " + itos ( encoded - > get_object_id ( ) ) ) ;
p_item - > set_icon ( 1 , Ref < Texture > ( ) ) ;
p_item - > set_custom_as_button ( 1 , true ) ;
} else if ( obj - > get ( p_name ) . get_type ( ) = = Variant : : NIL | | obj - > get ( p_name ) . operator RefPtr ( ) . is_null ( ) ) {
2017-03-05 16:44:50 +01:00
p_item - > set_text ( 1 , " <null> " ) ;
p_item - > set_icon ( 1 , Ref < Texture > ( ) ) ;
2017-06-05 01:35:08 +02:00
p_item - > set_custom_as_button ( 1 , false ) ;
2014-02-10 02:10:30 +01:00
2014-06-15 04:10:45 +02:00
Dictionary d = p_item - > get_metadata ( 0 ) ;
2017-03-05 16:44:50 +01:00
int hint = d . has ( " hint " ) ? d [ " hint " ] . operator int ( ) : - 1 ;
String hint_text = d . has ( " hint_text " ) ? d [ " hint_text " ] : " " ;
if ( hint = = PROPERTY_HINT_RESOURCE_TYPE & & hint_text = = " Texture " ) {
p_item - > set_icon ( 1 , NULL ) ;
2014-06-15 04:10:45 +02:00
}
2014-02-10 02:10:30 +01:00
} else {
2017-06-05 01:35:08 +02:00
p_item - > set_custom_as_button ( 1 , true ) ;
2017-03-05 16:44:50 +01:00
RES res = obj - > get ( p_name ) . operator RefPtr ( ) ;
2017-01-03 03:03:46 +01:00
if ( res - > is_class ( " Texture " ) ) {
2017-01-05 23:41:36 +01:00
int tw = EditorSettings : : get_singleton ( ) - > get ( " docks/property_editor/texture_preview_width " ) ;
2017-04-11 13:22:57 +02:00
Vector2 size ( res - > call ( " get_width " ) , res - > call ( " get_height " ) ) ;
if ( size . width < size . height ) {
tw = MAX ( ( size . width / size . height ) * tw , 1 ) ;
}
2017-03-05 16:44:50 +01:00
p_item - > set_icon_max_width ( 1 , tw ) ;
p_item - > set_icon ( 1 , res ) ;
p_item - > set_text ( 1 , " " ) ;
2014-02-10 02:10:30 +01:00
} else if ( res - > get_name ( ) ! = " " ) {
p_item - > set_text ( 1 , res - > get_name ( ) ) ;
2017-03-05 16:44:50 +01:00
} else if ( res - > get_path ( ) ! = " " & & ! res - > get_path ( ) . begins_with ( " local:// " ) ) {
2014-02-10 02:10:30 +01:00
p_item - > set_text ( 1 , res - > get_path ( ) . get_file ( ) ) ;
} else {
2017-03-05 16:44:50 +01:00
p_item - > set_text ( 1 , " < " + res - > get_class ( ) + " > " ) ;
2014-02-10 02:10:30 +01:00
} ;
2015-03-02 04:54:10 +01:00
2015-03-16 04:47:37 +01:00
if ( res . is_valid ( ) & & res - > get_path ( ) . is_resource_file ( ) ) {
2017-03-05 16:44:50 +01:00
p_item - > set_tooltip ( 1 , res - > get_path ( ) ) ;
2015-03-16 04:47:37 +01:00
} else if ( res . is_valid ( ) ) {
2017-03-05 16:44:50 +01:00
p_item - > set_tooltip ( 1 , res - > get_name ( ) + " ( " + res - > get_class ( ) + " ) " ) ;
2015-03-16 04:47:37 +01:00
}
2017-03-05 16:44:50 +01:00
if ( has_icon ( res - > get_class ( ) , " EditorIcons " ) ) {
2015-03-16 04:47:37 +01:00
2017-03-05 16:44:50 +01:00
p_item - > set_icon ( 0 , get_icon ( res - > get_class ( ) , " EditorIcons " ) ) ;
2015-03-02 04:54:10 +01:00
} else {
Dictionary d = p_item - > get_metadata ( 0 ) ;
2017-03-05 16:44:50 +01:00
int hint = d . has ( " hint " ) ? d [ " hint " ] . operator int ( ) : - 1 ;
String hint_text = d . has ( " hint_text " ) ? d [ " hint_text " ] : " " ;
if ( hint = = PROPERTY_HINT_RESOURCE_TYPE ) {
2015-03-02 04:54:10 +01:00
2017-03-05 16:44:50 +01:00
if ( has_icon ( hint_text , " EditorIcons " ) ) {
2015-03-02 04:54:10 +01:00
2017-03-05 16:44:50 +01:00
p_item - > set_icon ( 0 , get_icon ( hint_text , " EditorIcons " ) ) ;
2015-03-02 04:54:10 +01:00
} else {
2017-03-05 16:44:50 +01:00
p_item - > set_icon ( 0 , get_icon ( " Object " , " EditorIcons " ) ) ;
2015-03-02 04:54:10 +01:00
}
}
}
2017-04-11 14:26:47 +02:00
if ( res - > is_class ( " Script " ) ) {
p_item - > set_text ( 1 , res - > get_path ( ) . get_file ( ) ) ;
} else if ( ! res - > is_class ( " Texture " ) ) {
2016-05-27 19:18:40 +02:00
//texture already previews via itself
2017-08-07 12:17:31 +02:00
EditorResourcePreview : : get_singleton ( ) - > queue_edited_resource_preview ( res , this , " _resource_preview_done " , p_item - > get_instance_id ( ) ) ;
2016-05-27 19:18:40 +02:00
}
2014-02-10 02:10:30 +01:00
}
} break ;
default : { } ;
}
}
2017-03-05 16:44:50 +01:00
void PropertyEditor : : _check_reload_status ( const String & p_name , TreeItem * item ) {
2015-10-10 14:09:09 +02:00
2017-03-05 16:44:50 +01:00
bool has_reload = false ;
int found = - 1 ;
bool is_disabled = false ;
2016-01-03 00:17:31 +01:00
2017-03-05 16:44:50 +01:00
for ( int i = 0 ; i < item - > get_button_count ( 1 ) ; i + + ) {
2016-01-03 00:17:31 +01:00
2017-03-05 16:44:50 +01:00
if ( item - > get_button_id ( 1 , i ) = = 3 ) {
found = i ;
is_disabled = item - > is_button_disabled ( 1 , i ) ;
2016-01-03 00:17:31 +01:00
break ;
}
}
2017-12-04 14:17:58 +01:00
if ( _is_instanced_node_with_original_property_different ( p_name , item ) ) {
has_reload = true ;
}
2017-03-05 16:44:50 +01:00
if ( obj - > call ( " property_can_revert " , p_name ) . operator bool ( ) ) {
2017-01-05 13:16:00 +01:00
2017-03-05 16:44:50 +01:00
has_reload = true ;
2017-01-05 13:16:00 +01:00
}
2016-01-03 00:17:31 +01:00
if ( ! has_reload & & ! obj - > get_script ( ) . is_null ( ) ) {
Ref < Script > scr = obj - > get_script ( ) ;
Variant orig_value ;
2017-03-05 16:44:50 +01:00
if ( scr - > get_property_default_value ( p_name , orig_value ) ) {
if ( orig_value ! = obj - > get ( p_name ) ) {
has_reload = true ;
2016-01-03 00:17:31 +01:00
}
}
}
2017-03-05 16:44:50 +01:00
if ( found ! = - 1 & & ! has_reload ) {
2016-02-03 00:44:42 +01:00
if ( ! is_disabled ) {
2017-03-05 16:44:50 +01:00
item - > erase_button ( 1 , found ) ;
if ( item - > get_cell_mode ( 1 ) = = TreeItem : : CELL_MODE_RANGE & & item - > get_text ( 1 ) = = String ( ) ) {
item - > add_button ( 1 , get_icon ( " ReloadEmpty " , " EditorIcons " ) , 3 , true ) ;
2016-02-03 00:44:42 +01:00
}
}
2017-03-05 16:44:50 +01:00
} else if ( found = = - 1 & & has_reload ) {
item - > add_button ( 1 , get_icon ( " ReloadSmall " , " EditorIcons " ) , 3 ) ;
} else if ( found ! = - 1 & & has_reload & & is_disabled ) {
item - > erase_button ( 1 , found ) ;
item - > add_button ( 1 , get_icon ( " ReloadSmall " , " EditorIcons " ) , 3 ) ;
2016-01-03 00:17:31 +01:00
}
}
2015-10-10 14:09:09 +02:00
2017-03-05 16:44:50 +01:00
bool PropertyEditor : : _is_drop_valid ( const Dictionary & p_drag_data , const Dictionary & p_item_data ) const {
2016-05-11 16:46:08 +02:00
Dictionary d = p_item_data ;
if ( d . has ( " type " ) ) {
int type = d [ " type " ] ;
2017-03-05 16:44:50 +01:00
if ( type = = Variant : : OBJECT & & d . has ( " hint " ) & & d . has ( " hint_text " ) & & int ( d [ " hint " ] ) = = PROPERTY_HINT_RESOURCE_TYPE ) {
2016-05-11 16:46:08 +02:00
2017-03-05 16:44:50 +01:00
String allowed_type = d [ " hint_text " ] ;
2016-05-11 16:46:08 +02:00
Dictionary drag_data = p_drag_data ;
2017-03-05 16:44:50 +01:00
if ( drag_data . has ( " type " ) & & String ( drag_data [ " type " ] ) = = " resource " ) {
2016-05-11 16:46:08 +02:00
Ref < Resource > res = drag_data [ " resource " ] ;
2017-03-05 16:44:50 +01:00
for ( int i = 0 ; i < allowed_type . get_slice_count ( " , " ) ; i + + ) {
String at = allowed_type . get_slice ( " , " , i ) . strip_edges ( ) ;
if ( res . is_valid ( ) & & ClassDB : : is_parent_class ( res - > get_class ( ) , at ) ) {
2016-05-11 16:46:08 +02:00
return true ;
}
}
}
2016-05-15 04:48:23 +02:00
2017-03-05 16:44:50 +01:00
if ( drag_data . has ( " type " ) & & String ( drag_data [ " type " ] ) = = " files " ) {
2016-05-11 16:46:08 +02:00
Vector < String > files = drag_data [ " files " ] ;
2017-03-05 16:44:50 +01:00
if ( files . size ( ) = = 1 ) {
2016-05-11 16:46:08 +02:00
String file = files [ 0 ] ;
String ftype = EditorFileSystem : : get_singleton ( ) - > get_file_type ( file ) ;
2017-08-15 21:27:15 +02:00
2017-03-05 16:44:50 +01:00
if ( ftype ! = " " ) {
2016-05-11 16:46:08 +02:00
2017-03-05 16:44:50 +01:00
for ( int i = 0 ; i < allowed_type . get_slice_count ( " , " ) ; i + + ) {
String at = allowed_type . get_slice ( " , " , i ) . strip_edges ( ) ;
if ( ClassDB : : is_parent_class ( ftype , at ) ) {
2016-05-11 16:46:08 +02:00
return true ;
}
}
}
}
}
}
}
return false ;
}
2017-03-05 16:44:50 +01:00
void PropertyEditor : : _mark_drop_fields ( TreeItem * p_at ) {
2016-05-11 16:46:08 +02:00
2017-03-05 16:44:50 +01:00
if ( _is_drop_valid ( get_viewport ( ) - > gui_get_drag_data ( ) , p_at - > get_metadata ( 0 ) ) )
2017-09-26 04:43:20 +02:00
p_at - > set_custom_bg_color ( 1 , get_color ( " accent_color " , " Editor " ) , true ) ;
2016-05-11 16:46:08 +02:00
if ( p_at - > get_children ( ) ) {
_mark_drop_fields ( p_at - > get_children ( ) ) ;
}
if ( p_at - > get_next ( ) ) {
_mark_drop_fields ( p_at - > get_next ( ) ) ;
}
}
2017-03-05 16:44:50 +01:00
Variant PropertyEditor : : get_drag_data_fw ( const Point2 & p_point , Control * p_from ) {
2016-05-11 16:46:08 +02:00
2017-09-10 15:37:49 +02:00
TreeItem * item = tree - > get_item_at_position ( p_point ) ;
2016-05-11 16:46:08 +02:00
if ( ! item )
return Variant ( ) ;
Dictionary d = item - > get_metadata ( 0 ) ;
if ( ! d . has ( " name " ) )
return Variant ( ) ;
2017-09-10 15:37:49 +02:00
int col = tree - > get_column_at_position ( p_point ) ;
2017-03-05 16:44:50 +01:00
if ( col = = 0 ) {
2016-08-03 16:28:20 +02:00
Dictionary dp ;
2017-03-05 16:44:50 +01:00
dp [ " type " ] = " obj_property " ;
dp [ " object " ] = obj ;
dp [ " property " ] = d [ " name " ] ;
dp [ " value " ] = obj - > get ( d [ " name " ] ) ;
2016-08-03 16:28:20 +02:00
2017-03-05 16:44:50 +01:00
Label * label = memnew ( Label ) ;
2016-08-03 16:28:20 +02:00
label - > set_text ( d [ " name " ] ) ;
set_drag_preview ( label ) ;
return dp ;
}
2016-05-11 16:46:08 +02:00
Variant val = obj - > get ( d [ " name " ] ) ;
2017-03-05 16:44:50 +01:00
if ( val . get_type ( ) = = Variant : : OBJECT ) {
2016-05-11 16:46:08 +02:00
RES res = val ;
if ( res . is_valid ( ) ) {
custom_editor - > hide_menu ( ) ;
2017-03-05 16:44:50 +01:00
return EditorNode : : get_singleton ( ) - > drag_resource ( res , p_from ) ;
2016-05-11 16:46:08 +02:00
}
}
return Variant ( ) ;
}
2017-03-05 16:44:50 +01:00
bool PropertyEditor : : can_drop_data_fw ( const Point2 & p_point , const Variant & p_data , Control * p_from ) const {
2016-05-11 16:46:08 +02:00
2017-09-10 15:37:49 +02:00
TreeItem * item = tree - > get_item_at_position ( p_point ) ;
2016-05-11 16:46:08 +02:00
if ( ! item )
return false ;
2017-09-10 15:37:49 +02:00
int col = tree - > get_column_at_position ( p_point ) ;
2017-03-05 16:44:50 +01:00
if ( col ! = 1 )
2016-05-11 16:46:08 +02:00
return false ;
2017-03-05 16:44:50 +01:00
return _is_drop_valid ( p_data , item - > get_metadata ( 0 ) ) ;
2016-05-11 16:46:08 +02:00
}
2017-03-05 16:44:50 +01:00
void PropertyEditor : : drop_data_fw ( const Point2 & p_point , const Variant & p_data , Control * p_from ) {
2016-05-11 16:46:08 +02:00
2017-09-10 15:37:49 +02:00
TreeItem * item = tree - > get_item_at_position ( p_point ) ;
2016-05-11 16:46:08 +02:00
if ( ! item )
return ;
2017-09-10 15:37:49 +02:00
int col = tree - > get_column_at_position ( p_point ) ;
2017-03-05 16:44:50 +01:00
if ( col ! = 1 )
2016-05-11 16:46:08 +02:00
return ;
2017-03-05 16:44:50 +01:00
if ( ! _is_drop_valid ( p_data , item - > get_metadata ( 0 ) ) )
2016-05-11 16:46:08 +02:00
return ;
Dictionary d = item - > get_metadata ( 0 ) ;
if ( ! d . has ( " name " ) )
return ;
2017-03-05 16:44:50 +01:00
String name = d [ " name " ] ;
2016-05-11 16:46:08 +02:00
Dictionary drag_data = p_data ;
2017-03-05 16:44:50 +01:00
if ( drag_data . has ( " type " ) & & String ( drag_data [ " type " ] ) = = " resource " ) {
2016-05-11 16:46:08 +02:00
Ref < Resource > res = drag_data [ " resource " ] ;
if ( res . is_valid ( ) ) {
2017-03-05 16:44:50 +01:00
_edit_set ( name , res ) ;
2016-05-11 16:46:08 +02:00
return ;
}
}
2017-03-05 16:44:50 +01:00
if ( drag_data . has ( " type " ) & & String ( drag_data [ " type " ] ) = = " files " ) {
2016-05-11 16:46:08 +02:00
Vector < String > files = drag_data [ " files " ] ;
2017-03-05 16:44:50 +01:00
if ( files . size ( ) = = 1 ) {
2016-05-11 16:46:08 +02:00
String file = files [ 0 ] ;
RES res = ResourceLoader : : load ( file ) ;
if ( res . is_valid ( ) ) {
2017-03-05 16:44:50 +01:00
_edit_set ( name , res ) ;
2016-05-11 16:46:08 +02:00
return ;
}
}
}
}
2017-03-05 16:44:50 +01:00
void PropertyEditor : : _clear_drop_fields ( TreeItem * p_at ) {
2016-05-11 16:46:08 +02:00
Dictionary d = p_at - > get_metadata ( 0 ) ;
if ( d . has ( " type " ) ) {
int type = d [ " type " ] ;
2017-03-05 16:44:50 +01:00
if ( type = = Variant : : OBJECT ) {
2016-05-11 16:46:08 +02:00
p_at - > clear_custom_bg_color ( 1 ) ;
}
}
if ( p_at - > get_children ( ) ) {
_clear_drop_fields ( p_at - > get_children ( ) ) ;
}
if ( p_at - > get_next ( ) ) {
_clear_drop_fields ( p_at - > get_next ( ) ) ;
}
}
2014-02-10 02:10:30 +01:00
void PropertyEditor : : _notification ( int p_what ) {
2017-03-05 16:44:50 +01:00
if ( p_what = = NOTIFICATION_ENTER_TREE ) {
2014-02-10 02:10:30 +01:00
2017-03-05 16:44:50 +01:00
get_tree ( ) - > connect ( " node_removed " , this , " _node_removed " ) ;
2014-02-10 02:10:30 +01:00
}
2017-03-05 16:44:50 +01:00
if ( p_what = = NOTIFICATION_EXIT_TREE ) {
2014-02-10 02:10:30 +01:00
2017-03-05 16:44:50 +01:00
get_tree ( ) - > disconnect ( " node_removed " , this , " _node_removed " ) ;
2014-02-10 02:10:30 +01:00
edit ( NULL ) ;
}
2017-03-05 16:44:50 +01:00
if ( p_what = = NOTIFICATION_DRAG_BEGIN ) {
2016-05-11 16:46:08 +02:00
2017-01-13 14:45:50 +01:00
if ( is_visible_in_tree ( ) & & tree - > get_root ( ) ) {
2016-05-11 16:46:08 +02:00
_mark_drop_fields ( tree - > get_root ( ) ) ;
}
}
2017-03-05 16:44:50 +01:00
if ( p_what = = NOTIFICATION_DRAG_END ) {
2017-01-13 14:45:50 +01:00
if ( is_visible_in_tree ( ) & & tree - > get_root ( ) ) {
2016-05-11 16:46:08 +02:00
_clear_drop_fields ( tree - > get_root ( ) ) ;
}
}
2017-09-30 16:19:07 +02:00
if ( p_what = = NOTIFICATION_PHYSICS_PROCESS ) {
2015-08-30 02:09:11 +02:00
2017-03-05 16:44:50 +01:00
if ( refresh_countdown > 0 ) {
2017-09-30 16:19:07 +02:00
refresh_countdown - = get_physics_process_delta_time ( ) ;
2017-03-05 16:44:50 +01:00
if ( refresh_countdown < = 0 ) {
2015-01-03 19:39:01 +01:00
TreeItem * root = tree - > get_root ( ) ;
_refresh_item ( root ) ;
}
}
2017-03-05 16:44:50 +01:00
changing = true ;
2015-08-30 02:09:11 +02:00
2014-02-10 02:10:30 +01:00
if ( update_tree_pending ) {
update_tree ( ) ;
2017-03-05 16:44:50 +01:00
update_tree_pending = false ;
2015-08-30 02:09:11 +02:00
2014-02-10 02:10:30 +01:00
} else {
2015-08-30 02:09:11 +02:00
2017-03-05 16:44:50 +01:00
const String * k = NULL ;
while ( ( k = pending . next ( k ) ) ) {
2015-08-30 02:09:11 +02:00
2017-03-05 16:44:50 +01:00
TreeItem * item = find_item ( tree - > get_root ( ) , * k ) ;
2014-02-10 02:10:30 +01:00
if ( ! item )
continue ;
2015-08-30 02:09:11 +02:00
2017-03-05 16:44:50 +01:00
_check_reload_status ( * k , item ) ;
2014-02-10 02:10:30 +01:00
2017-03-05 16:44:50 +01:00
Dictionary d = item - > get_metadata ( 0 ) ;
set_item_text ( item , d [ " type " ] , d [ " name " ] , d [ " hint " ] , d [ " hint_text " ] ) ;
2015-08-30 02:09:11 +02:00
}
2014-02-10 02:10:30 +01:00
}
2015-08-30 02:09:11 +02:00
2014-02-10 02:10:30 +01:00
pending . clear ( ) ;
2015-08-30 02:09:11 +02:00
2017-03-05 16:44:50 +01:00
changing = false ;
2014-02-10 02:10:30 +01:00
}
2017-05-02 22:13:12 +02:00
if ( p_what = = EditorSettings : : NOTIFICATION_EDITOR_SETTINGS_CHANGED ) {
update_tree ( ) ;
}
2014-02-10 02:10:30 +01:00
}
2017-06-25 22:30:28 +02:00
TreeItem * PropertyEditor : : get_parent_node ( String p_path , HashMap < String , TreeItem * > & item_paths , TreeItem * root , TreeItem * category ) {
2014-02-10 02:10:30 +01:00
2017-03-05 16:44:50 +01:00
TreeItem * item = NULL ;
2014-02-10 02:10:30 +01:00
2017-03-05 16:44:50 +01:00
if ( p_path = = " " ) {
2014-02-10 02:10:30 +01:00
2017-06-25 22:30:28 +02:00
item = category ? category : root ;
2014-02-10 02:10:30 +01:00
} else if ( item_paths . has ( p_path ) ) {
item = item_paths . get ( p_path ) ;
} else {
2017-06-25 22:30:28 +02:00
TreeItem * parent = get_parent_node ( p_path . left ( p_path . find_last ( " / " ) ) , item_paths , root , NULL ) ;
2017-03-05 16:44:50 +01:00
item = tree - > create_item ( parent ) ;
2014-02-10 02:10:30 +01:00
2017-03-05 16:44:50 +01:00
String name = ( p_path . find ( " / " ) ! = - 1 ) ? p_path . right ( p_path . find_last ( " / " ) + 1 ) : p_path ;
2017-04-26 13:41:41 +02:00
item - > set_text ( 0 , capitalize_paths ? name . capitalize ( ) : name ) ;
2014-02-10 02:10:30 +01:00
item - > set_tooltip ( 0 , p_path ) ;
2017-03-05 16:44:50 +01:00
if ( item - > get_parent ( ) ! = root ) {
item - > set_icon ( 0 , get_icon ( " Folder " , " EditorIcons " ) ) ;
2014-02-10 02:10:30 +01:00
}
2017-03-05 16:44:50 +01:00
item - > set_editable ( 0 , false ) ;
2017-06-25 22:30:28 +02:00
if ( ! subsection_selectable ) {
item - > set_expand_right ( 0 , true ) ;
}
2017-03-05 16:44:50 +01:00
item - > set_selectable ( 0 , subsection_selectable ) ;
item - > set_editable ( 1 , false ) ;
item - > set_selectable ( 1 , subsection_selectable ) ;
2014-02-10 02:10:30 +01:00
2017-12-18 15:14:27 +01:00
if ( use_folding ) {
2017-06-25 22:30:28 +02:00
if ( ! obj - > editor_is_section_unfolded ( p_path ) ) {
updating_folding = true ;
2017-12-06 23:06:18 +01:00
item - > set_collapsed ( true ) ;
2017-06-25 22:30:28 +02:00
updating_folding = false ;
}
item - > set_metadata ( 0 , p_path ) ;
2017-12-06 23:06:18 +01:00
foldable_property_cache . push_back ( p_path ) ;
2017-06-25 22:30:28 +02:00
}
2017-03-05 16:44:50 +01:00
if ( item - > get_parent ( ) = = root ) {
2014-02-10 02:10:30 +01:00
2017-03-05 16:44:50 +01:00
item - > set_custom_bg_color ( 0 , get_color ( " prop_subsection " , " Editor " ) ) ;
item - > set_custom_bg_color ( 1 , get_color ( " prop_subsection " , " Editor " ) ) ;
2014-02-10 02:10:30 +01:00
}
2017-03-05 16:44:50 +01:00
item_paths [ p_path ] = item ;
2014-02-10 02:10:30 +01:00
}
return item ;
}
2015-01-03 19:39:01 +01:00
void PropertyEditor : : _refresh_item ( TreeItem * p_item ) {
if ( ! p_item )
return ;
String name = p_item - > get_metadata ( 1 ) ;
2017-03-05 16:44:50 +01:00
if ( name ! = String ( ) ) {
2015-01-03 19:39:01 +01:00
2017-03-05 16:44:50 +01:00
_check_reload_status ( name , p_item ) ;
Dictionary d = p_item - > get_metadata ( 0 ) ;
set_item_text ( p_item , d [ " type " ] , d [ " name " ] , d [ " hint " ] , d [ " hint_text " ] ) ;
2015-01-03 19:39:01 +01:00
}
2017-03-05 16:44:50 +01:00
TreeItem * c = p_item - > get_children ( ) ;
2015-01-03 19:39:01 +01:00
while ( c ) {
_refresh_item ( c ) ;
2017-03-05 16:44:50 +01:00
c = c - > get_next ( ) ;
2015-01-03 19:39:01 +01:00
}
}
void PropertyEditor : : refresh ( ) {
2017-03-05 16:44:50 +01:00
if ( refresh_countdown > 0 )
2015-01-03 19:39:01 +01:00
return ;
2017-03-05 16:44:50 +01:00
refresh_countdown = EditorSettings : : get_singleton ( ) - > get ( " docks/property_editor/auto_refresh_interval " ) ;
2015-01-03 19:39:01 +01:00
}
2014-02-10 02:10:30 +01:00
void PropertyEditor : : update_tree ( ) {
tree - > clear ( ) ;
2017-12-06 23:06:18 +01:00
foldable_property_cache . clear ( ) ;
2014-02-10 02:10:30 +01:00
if ( ! obj )
return ;
2017-03-05 16:44:50 +01:00
HashMap < String , TreeItem * > item_path ;
2014-02-10 02:10:30 +01:00
TreeItem * root = tree - > create_item ( NULL ) ;
tree - > set_hide_root ( true ) ;
List < PropertyInfo > plist ;
2017-03-05 16:44:50 +01:00
obj - > get_property_list ( & plist , true ) ;
2014-02-10 02:10:30 +01:00
2017-03-05 16:44:50 +01:00
bool draw_red = false ;
2014-09-03 04:13:40 +02:00
{
2017-08-24 22:58:51 +02:00
Node * nod = Object : : cast_to < Node > ( obj ) ;
2014-09-03 04:13:40 +02:00
Node * es = EditorNode : : get_singleton ( ) - > get_edited_scene ( ) ;
2017-03-05 16:44:50 +01:00
if ( nod & & es ! = nod & & nod - > get_owner ( ) ! = es ) {
draw_red = true ;
2014-09-03 04:13:40 +02:00
}
}
2017-03-05 16:44:50 +01:00
Color sscolor = get_color ( " prop_subsection " , " Editor " ) ;
2014-09-03 04:13:40 +02:00
2017-03-05 16:44:50 +01:00
TreeItem * current_category = NULL ;
2014-02-10 02:10:30 +01:00
2015-11-21 17:42:15 +01:00
String filter = search_box ? search_box - > get_text ( ) : " " ;
2017-01-03 04:38:16 +01:00
String group ;
String group_base ;
2015-11-21 17:42:15 +01:00
2017-03-05 16:44:50 +01:00
for ( List < PropertyInfo > : : Element * I = plist . front ( ) ; I ; I = I - > next ( ) ) {
2014-02-10 02:10:30 +01:00
2017-03-05 16:44:50 +01:00
PropertyInfo & p = I - > get ( ) ;
2014-02-10 02:10:30 +01:00
//make sure the property can be edited
2017-03-05 16:44:50 +01:00
if ( p . usage & PROPERTY_USAGE_GROUP ) {
2017-01-03 04:38:16 +01:00
2017-03-05 16:44:50 +01:00
group = p . name ;
group_base = p . hint_string ;
2017-01-03 04:38:16 +01:00
continue ;
2017-03-05 16:44:50 +01:00
} else if ( p . usage & PROPERTY_USAGE_CATEGORY ) {
2017-01-03 04:38:16 +01:00
2017-03-05 16:44:50 +01:00
group = " " ;
group_base = " " ;
2014-02-10 02:10:30 +01:00
if ( ! show_categories )
continue ;
2017-03-05 16:44:50 +01:00
List < PropertyInfo > : : Element * N = I - > next ( ) ;
bool valid = true ;
2014-02-10 02:10:30 +01:00
//if no properties in category, skip
2017-03-05 16:44:50 +01:00
while ( N ) {
if ( N - > get ( ) . usage & PROPERTY_USAGE_EDITOR )
2014-02-10 02:10:30 +01:00
break ;
2017-03-05 16:44:50 +01:00
if ( N - > get ( ) . usage & PROPERTY_USAGE_CATEGORY ) {
valid = false ;
2014-02-10 02:10:30 +01:00
break ;
}
2017-03-05 16:44:50 +01:00
N = N - > next ( ) ;
2014-02-10 02:10:30 +01:00
}
if ( ! valid )
continue ; //empty, ignore
2017-03-05 16:44:50 +01:00
TreeItem * sep = tree - > create_item ( root ) ;
current_category = sep ;
String type = p . name ;
2017-12-09 22:07:45 +01:00
2017-06-25 22:30:28 +02:00
if ( has_icon ( type , " EditorIcons " ) )
sep - > set_icon ( 0 , get_icon ( type , " EditorIcons " ) ) ;
2014-02-10 02:10:30 +01:00
else
2017-06-25 22:30:28 +02:00
sep - > set_icon ( 0 , get_icon ( " Object " , " EditorIcons " ) ) ;
2017-03-05 16:44:50 +01:00
sep - > set_text ( 0 , type ) ;
2017-06-25 22:30:28 +02:00
sep - > set_expand_right ( 0 , true ) ;
2017-03-05 16:44:50 +01:00
sep - > set_selectable ( 0 , false ) ;
sep - > set_selectable ( 1 , false ) ;
sep - > set_custom_bg_color ( 0 , get_color ( " prop_category " , " Editor " ) ) ;
sep - > set_custom_bg_color ( 1 , get_color ( " prop_category " , " Editor " ) ) ;
2017-06-25 22:30:28 +02:00
sep - > set_text_align ( 0 , TreeItem : : ALIGN_CENTER ) ;
sep - > set_disable_folding ( true ) ;
2015-08-26 04:00:11 +02:00
if ( use_doc_hints ) {
2017-03-05 16:44:50 +01:00
StringName type = p . name ;
2015-08-26 04:00:11 +02:00
if ( ! class_descr_cache . has ( type ) ) {
String descr ;
2017-03-05 16:44:50 +01:00
DocData * dd = EditorHelp : : get_doc_data ( ) ;
Map < String , DocData : : ClassDoc > : : Element * E = dd - > class_list . find ( type ) ;
2015-08-26 04:00:11 +02:00
if ( E ) {
2017-03-05 16:44:50 +01:00
descr = E - > get ( ) . brief_description ;
2015-08-26 04:00:11 +02:00
}
2017-03-05 16:44:50 +01:00
class_descr_cache [ type ] = descr . word_wrap ( 80 ) ;
2015-08-26 04:00:11 +02:00
}
2017-12-12 16:57:17 +01:00
sep - > set_tooltip ( 0 , TTR ( " Class: " ) + " " + p . name + ( class_descr_cache [ type ] = = " " ? " " : " \n \n " + class_descr_cache [ type ] ) ) ;
2015-08-26 04:00:11 +02:00
}
2014-02-10 02:10:30 +01:00
continue ;
2017-08-26 17:46:49 +02:00
2017-03-05 16:44:50 +01:00
} else if ( ! ( p . usage & PROPERTY_USAGE_EDITOR ) )
2014-02-10 02:10:30 +01:00
continue ;
2017-03-05 16:44:50 +01:00
if ( hide_script & & p . name = = " script " )
2017-02-01 13:45:45 +01:00
continue ;
2017-03-05 16:44:50 +01:00
String basename = p . name ;
if ( group ! = " " ) {
if ( group_base ! = " " ) {
2017-01-03 04:38:16 +01:00
if ( basename . begins_with ( group_base ) ) {
2017-03-05 16:44:50 +01:00
basename = basename . replace_first ( group_base , " " ) ;
2017-06-25 23:57:28 +02:00
} else if ( group_base . begins_with ( basename ) ) {
//keep it, this is used pretty often
2017-01-03 04:38:16 +01:00
} else {
2017-03-05 16:44:50 +01:00
group = " " ; //no longer using group base, clear
2017-01-03 04:38:16 +01:00
}
}
}
2017-03-05 16:44:50 +01:00
if ( group ! = " " ) {
basename = group + " / " + basename ;
2017-01-03 04:38:16 +01:00
}
2017-03-05 16:44:50 +01:00
String name = ( basename . find ( " / " ) ! = - 1 ) ? basename . right ( basename . find_last ( " / " ) + 1 ) : basename ;
2015-11-21 17:42:15 +01:00
2017-07-19 22:00:46 +02:00
if ( capitalize_paths ) {
int dot = name . find ( " . " ) ;
if ( dot ! = - 1 ) {
String ov = name . right ( dot ) ;
name = name . substr ( 0 , dot ) ;
name = name . camelcase_to_underscore ( ) . capitalize ( ) ;
name + = ov ;
} else {
name = name . camelcase_to_underscore ( ) . capitalize ( ) ;
}
}
2015-11-21 17:42:15 +01:00
2017-03-05 16:44:50 +01:00
String path = basename . left ( basename . find_last ( " / " ) ) ;
2015-11-22 17:05:55 +01:00
2017-03-05 16:44:50 +01:00
if ( use_filter & & filter ! = " " ) {
2015-11-22 17:05:55 +01:00
String cat = path ;
if ( capitalize_paths )
cat = cat . capitalize ( ) ;
2016-06-12 18:43:31 +02:00
if ( ! filter . is_subsequence_ofi ( cat ) & & ! filter . is_subsequence_ofi ( name ) )
2015-11-22 17:05:55 +01:00
continue ;
}
2017-06-25 22:30:28 +02:00
TreeItem * parent = get_parent_node ( path , item_path , root , current_category ) ;
2014-02-10 02:10:30 +01:00
int level = 0 ;
2017-03-05 16:44:50 +01:00
if ( parent ! = root ) {
2014-02-10 02:10:30 +01:00
level + + ;
2017-03-05 16:44:50 +01:00
TreeItem * parent_lev = parent ;
while ( parent_lev - > get_parent ( ) ! = root ) {
parent_lev = parent_lev - > get_parent ( ) ;
2014-02-10 02:10:30 +01:00
level + + ;
}
}
2017-03-05 16:44:50 +01:00
if ( level > 4 )
level = 4 ;
2014-02-10 02:10:30 +01:00
Color col = sscolor ;
2017-03-05 16:44:50 +01:00
col . a = ( level / 4.0 ) * 0.7 ;
2014-02-10 02:10:30 +01:00
2017-03-05 16:44:50 +01:00
TreeItem * item = tree - > create_item ( parent ) ;
2014-02-10 02:10:30 +01:00
2017-03-05 16:44:50 +01:00
if ( level > 0 ) {
item - > set_custom_bg_color ( 0 , col ) ;
2014-02-10 02:10:30 +01:00
}
2017-03-05 16:44:50 +01:00
item - > set_editable ( 0 , false ) ;
2017-07-19 22:00:46 +02:00
item - > set_selectable ( 0 , property_selectable ) ;
2014-02-10 02:10:30 +01:00
2017-03-05 16:44:50 +01:00
if ( p . usage & PROPERTY_USAGE_CHECKABLE ) {
2014-02-10 02:10:30 +01:00
2017-03-05 16:44:50 +01:00
item - > set_cell_mode ( 0 , TreeItem : : CELL_MODE_CHECK ) ;
item - > set_selectable ( 0 , true ) ;
item - > set_editable ( 0 , true ) ;
item - > set_checked ( 0 , p . usage & PROPERTY_USAGE_CHECKED ) ;
2014-02-10 02:10:30 +01:00
}
2015-11-21 17:42:15 +01:00
item - > set_text ( 0 , name ) ;
2014-02-10 02:10:30 +01:00
item - > set_tooltip ( 0 , p . name ) ;
2017-07-19 22:00:46 +02:00
if ( name . find ( " . " ) ! = - 1 ) {
Color textcol = get_color ( " font_color " , " Tree " ) ;
textcol . a * = 0.5 ;
//override :D
item - > set_custom_color ( 0 , textcol ) ;
item - > set_custom_color ( 1 , textcol ) ;
Color iconcol ( 1 , 1 , 1 , 0.6 ) ;
item - > set_icon_color ( 0 , iconcol ) ;
item - > set_icon_color ( 1 , iconcol ) ;
}
2015-08-26 04:00:11 +02:00
if ( use_doc_hints ) {
2017-12-09 22:07:45 +01:00
StringName classname = obj - > get_class_name ( ) ;
StringName propname = p . name ;
String descr ;
bool found = false ;
2015-08-26 04:00:11 +02:00
2017-12-09 22:07:45 +01:00
Map < StringName , Map < StringName , String > > : : Element * E = descr_cache . find ( classname ) ;
if ( E ) {
Map < StringName , String > : : Element * F = E - > get ( ) . find ( propname ) ;
if ( F ) {
found = true ;
descr = F - > get ( ) ;
2015-08-26 04:00:11 +02:00
}
2017-12-09 22:07:45 +01:00
}
2015-08-26 04:00:11 +02:00
2017-12-09 22:07:45 +01:00
if ( ! found ) {
DocData * dd = EditorHelp : : get_doc_data ( ) ;
Map < String , DocData : : ClassDoc > : : Element * E = dd - > class_list . find ( classname ) ;
2017-12-15 17:28:22 +01:00
while ( E & & descr = = String ( ) ) {
2017-12-09 22:07:45 +01:00
for ( int i = 0 ; i < E - > get ( ) . properties . size ( ) ; i + + ) {
if ( E - > get ( ) . properties [ i ] . name = = propname . operator String ( ) ) {
descr = E - > get ( ) . properties [ i ] . description . strip_edges ( ) . word_wrap ( 80 ) ;
2017-12-15 17:28:22 +01:00
break ;
2015-08-26 04:00:11 +02:00
}
}
2017-12-15 17:28:22 +01:00
if ( ! E - > get ( ) . inherits . empty ( ) ) {
E = dd - > class_list . find ( E - > get ( ) . inherits ) ;
} else {
break ;
}
2015-08-26 04:00:11 +02:00
}
2017-12-09 22:07:45 +01:00
descr_cache [ classname ] [ propname ] = descr ;
2015-08-26 04:00:11 +02:00
}
2017-12-09 22:07:45 +01:00
2017-12-12 16:57:17 +01:00
item - > set_tooltip ( 0 , TTR ( " Property: " ) + " " + p . name + ( descr = = " " ? " " : " \n \n " + descr ) ) ;
2015-08-26 04:00:11 +02:00
}
2014-02-10 02:10:30 +01:00
Dictionary d ;
2017-03-05 16:44:50 +01:00
d [ " name " ] = p . name ;
d [ " type " ] = ( int ) p . type ;
d [ " hint " ] = ( int ) p . hint ;
d [ " hint_text " ] = p . hint_string ;
d [ " usage " ] = ( int ) p . usage ;
2015-08-30 02:09:11 +02:00
2017-03-05 16:44:50 +01:00
item - > set_metadata ( 0 , d ) ;
item - > set_metadata ( 1 , p . name ) ;
2014-09-03 04:13:40 +02:00
if ( draw_red )
2017-09-25 05:26:41 +02:00
item - > set_custom_color ( 0 , get_color ( " error_color " , " Editor " ) ) ;
2015-08-30 02:09:11 +02:00
2017-03-05 16:44:50 +01:00
if ( p . name = = selected_property ) {
2014-02-10 02:10:30 +01:00
item - > select ( 1 ) ;
}
2014-09-03 04:13:40 +02:00
2017-03-05 16:44:50 +01:00
switch ( p . type ) {
2014-02-10 02:10:30 +01:00
case Variant : : BOOL : {
2017-03-05 16:44:50 +01:00
item - > set_cell_mode ( 1 , TreeItem : : CELL_MODE_CHECK ) ;
2017-07-30 22:08:26 +02:00
item - > set_text ( 1 , TTR ( " On " ) ) ;
2016-09-19 23:41:48 +02:00
item - > set_tooltip ( 1 , obj - > get ( p . name ) ? " True " : " False " ) ;
2017-03-05 16:44:50 +01:00
item - > set_checked ( 1 , obj - > get ( p . name ) ) ;
2015-12-11 13:37:34 +01:00
if ( show_type_icons )
2017-12-18 15:14:27 +01:00
item - > set_icon ( 0 , get_icon ( " bool " , " EditorIcons " ) ) ;
2017-03-05 16:44:50 +01:00
item - > set_editable ( 1 , ! read_only ) ;
2014-02-10 02:10:30 +01:00
} break ;
case Variant : : REAL :
case Variant : : INT : {
2017-03-05 16:44:50 +01:00
if ( p . hint = = PROPERTY_HINT_EXP_EASING ) {
2014-02-10 02:10:30 +01:00
2017-03-05 16:44:50 +01:00
item - > set_cell_mode ( 1 , TreeItem : : CELL_MODE_CUSTOM ) ;
item - > set_text ( 1 , String : : num ( obj - > get ( p . name ) , 2 ) ) ;
item - > set_editable ( 1 , ! read_only ) ;
2015-12-11 13:37:34 +01:00
if ( show_type_icons )
2017-03-05 16:44:50 +01:00
item - > set_icon ( 0 , get_icon ( " Curve " , " EditorIcons " ) ) ;
2014-02-10 02:10:30 +01:00
break ;
}
2017-03-05 16:44:50 +01:00
if ( p . hint = = PROPERTY_HINT_LAYERS_2D_PHYSICS | | p . hint = = PROPERTY_HINT_LAYERS_2D_RENDER | | p . hint = = PROPERTY_HINT_LAYERS_3D_PHYSICS | | p . hint = = PROPERTY_HINT_LAYERS_3D_RENDER ) {
2014-02-10 02:10:30 +01:00
2017-03-05 16:44:50 +01:00
item - > set_cell_mode ( 1 , TreeItem : : CELL_MODE_CUSTOM ) ;
item - > set_editable ( 1 , ! read_only ) ;
item - > set_custom_draw ( 1 , this , " _draw_flags " ) ;
2014-02-10 02:10:30 +01:00
break ;
}
2017-03-05 16:44:50 +01:00
if ( p . hint = = PROPERTY_HINT_FLAGS ) {
2014-02-10 02:10:30 +01:00
2017-03-05 16:44:50 +01:00
item - > set_cell_mode ( 1 , TreeItem : : CELL_MODE_CUSTOM ) ;
item - > set_editable ( 1 , ! read_only ) ;
2014-02-10 02:10:30 +01:00
Vector < String > values = p . hint_string . split ( " , " ) ;
String flags ;
int val = obj - > get ( p . name ) ;
2017-03-05 16:44:50 +01:00
for ( int i = 0 ; i < values . size ( ) ; i + + ) {
2014-02-10 02:10:30 +01:00
String v = values [ i ] ;
2017-03-05 16:44:50 +01:00
if ( v = = " " )
2014-02-10 02:10:30 +01:00
continue ;
2017-03-05 16:44:50 +01:00
if ( ! ( val & ( 1 < < i ) ) )
2014-02-10 02:10:30 +01:00
continue ;
2017-03-05 16:44:50 +01:00
if ( flags ! = " " )
flags + = " , " ;
flags + = v ;
2014-02-10 02:10:30 +01:00
}
2017-03-05 16:44:50 +01:00
item - > set_text ( 1 , flags ) ;
2014-02-10 02:10:30 +01:00
break ;
}
2017-03-05 16:44:50 +01:00
if ( p . hint = = PROPERTY_HINT_ENUM )
item - > set_cell_mode ( 1 , TreeItem : : CELL_MODE_RANGE ) ;
2016-05-01 10:33:32 +02:00
else
2017-03-05 16:44:50 +01:00
item - > set_cell_mode ( 1 , TreeItem : : CELL_MODE_RANGE_EXPRESSION ) ;
2014-02-10 02:10:30 +01:00
2017-03-05 16:44:50 +01:00
if ( p . hint = = PROPERTY_HINT_SPRITE_FRAME | | p . hint = = PROPERTY_HINT_RANGE | | p . hint = = PROPERTY_HINT_EXP_RANGE ) {
2014-02-10 02:10:30 +01:00
int c = p . hint_string . get_slice_count ( " , " ) ;
2017-10-14 21:20:04 +02:00
float min = 0 , max = 100 , step = p . type = = Variant : : REAL ? .01 : 1 ;
2017-03-05 16:44:50 +01:00
if ( c > = 1 ) {
2014-02-10 02:10:30 +01:00
2017-03-05 16:44:50 +01:00
min = p . hint_string . get_slice ( " , " , 0 ) . to_double ( ) ;
2014-02-10 02:10:30 +01:00
}
2017-03-05 16:44:50 +01:00
if ( c > = 2 ) {
2014-02-10 02:10:30 +01:00
2017-03-05 16:44:50 +01:00
max = p . hint_string . get_slice ( " , " , 1 ) . to_double ( ) ;
2014-02-10 02:10:30 +01:00
}
2017-03-05 16:44:50 +01:00
if ( p . hint ! = PROPERTY_HINT_SPRITE_FRAME & & c > = 3 ) {
2014-02-10 02:10:30 +01:00
2017-03-05 16:44:50 +01:00
step = p . hint_string . get_slice ( " , " , 2 ) . to_double ( ) ;
2015-08-30 02:09:11 +02:00
}
2017-03-05 16:44:50 +01:00
item - > set_range_config ( 1 , min , max , step , p . hint = = PROPERTY_HINT_EXP_RANGE ) ;
} else if ( p . hint = = PROPERTY_HINT_ENUM ) {
2014-02-10 02:10:30 +01:00
2017-03-05 16:44:50 +01:00
item - > set_text ( 1 , p . hint_string ) ;
2015-12-11 13:37:34 +01:00
if ( show_type_icons )
2017-03-05 16:44:50 +01:00
item - > set_icon ( 0 , get_icon ( " Enum " , " EditorIcons " ) ) ;
item - > set_range ( 1 , obj - > get ( p . name ) ) ;
item - > set_editable ( 1 , ! read_only ) ;
2014-02-10 02:10:30 +01:00
break ;
2017-03-05 16:44:50 +01:00
} else if ( p . hint = = PROPERTY_HINT_OBJECT_ID ) {
2016-05-23 00:28:37 +02:00
2017-03-05 16:44:50 +01:00
item - > set_cell_mode ( 1 , TreeItem : : CELL_MODE_CUSTOM ) ;
2016-05-23 00:28:37 +02:00
2017-03-05 16:44:50 +01:00
String type = p . hint_string ;
if ( type = = " " )
type = " Object " ;
2016-05-23 00:28:37 +02:00
2017-03-05 16:44:50 +01:00
ObjectID id = obj - > get ( p . name ) ;
if ( id ! = 0 ) {
item - > set_text ( 1 , type + " ID: " + itos ( id ) ) ;
item - > add_button ( 1 , get_icon ( " EditResource " , " EditorIcons " ) ) ;
2016-05-23 00:28:37 +02:00
} else {
2017-12-02 10:58:58 +01:00
item - > set_text ( 1 , TTR ( " [Empty] " ) ) ;
2016-05-23 00:28:37 +02:00
}
2017-03-05 16:44:50 +01:00
if ( has_icon ( p . hint_string , " EditorIcons " ) ) {
type = p . hint_string ;
2016-05-23 00:28:37 +02:00
} else {
2017-03-05 16:44:50 +01:00
type = " Object " ;
2016-05-23 00:28:37 +02:00
}
2017-03-05 16:44:50 +01:00
item - > set_icon ( 0 , get_icon ( type , " EditorIcons " ) ) ;
2016-05-23 00:28:37 +02:00
break ;
2014-02-10 02:10:30 +01:00
} else {
if ( p . type = = Variant : : REAL ) {
2016-07-25 11:07:02 +02:00
item - > set_range_config ( 1 , - 16777216 , 16777216 , 0.001 ) ;
2014-02-10 02:10:30 +01:00
} else {
2016-07-25 11:07:02 +02:00
item - > set_range_config ( 1 , - 2147483647 , 2147483647 , 1 ) ;
2014-02-10 02:10:30 +01:00
}
} ;
2017-03-05 16:44:50 +01:00
if ( p . type = = Variant : : REAL ) {
2015-12-11 13:37:34 +01:00
if ( show_type_icons )
2017-12-18 15:14:27 +01:00
item - > set_icon ( 0 , get_icon ( " float " , " EditorIcons " ) ) ;
2017-03-05 16:44:50 +01:00
item - > set_range ( 1 , obj - > get ( p . name ) ) ;
2014-02-10 02:10:30 +01:00
} else {
2015-12-11 13:37:34 +01:00
if ( show_type_icons )
2017-12-18 15:14:27 +01:00
item - > set_icon ( 0 , get_icon ( " int " , " EditorIcons " ) ) ;
2017-03-05 16:44:50 +01:00
item - > set_range ( 1 , obj - > get ( p . name ) ) ;
2014-02-10 02:10:30 +01:00
}
2017-03-05 16:44:50 +01:00
item - > set_editable ( 1 , ! read_only ) ;
2014-02-10 02:10:30 +01:00
} break ;
case Variant : : STRING : {
switch ( p . hint ) {
case PROPERTY_HINT_DIR :
case PROPERTY_HINT_FILE :
case PROPERTY_HINT_GLOBAL_DIR :
case PROPERTY_HINT_GLOBAL_FILE : {
2017-03-05 16:44:50 +01:00
item - > set_cell_mode ( 1 , TreeItem : : CELL_MODE_STRING ) ;
item - > set_editable ( 1 , ! read_only ) ;
2015-12-11 13:37:34 +01:00
if ( show_type_icons )
2017-03-05 16:44:50 +01:00
item - > set_icon ( 0 , get_icon ( " File " , " EditorIcons " ) ) ;
item - > set_text ( 1 , obj - > get ( p . name ) ) ;
item - > add_button ( 1 , get_icon ( " Folder " , " EditorIcons " ) ) ;
2014-02-10 02:10:30 +01:00
} break ;
case PROPERTY_HINT_ENUM : {
2017-03-05 16:44:50 +01:00
item - > set_cell_mode ( 1 , TreeItem : : CELL_MODE_RANGE ) ;
2014-02-10 02:10:30 +01:00
Vector < String > strings = p . hint_string . split ( " , " ) ;
String current = obj - > get ( p . name ) ;
2017-03-05 16:44:50 +01:00
int idx = 0 ;
for ( int x = 0 ; x < strings . size ( ) ; x + + ) {
if ( strings [ x ] = = current ) {
idx = x ;
2014-02-10 02:10:30 +01:00
break ;
}
}
item - > set_text ( 1 , p . hint_string ) ;
2017-03-05 16:44:50 +01:00
item - > set_range ( 1 , idx ) ;
item - > set_editable ( 1 , ! read_only ) ;
2015-12-11 13:37:34 +01:00
if ( show_type_icons )
2017-03-05 16:44:50 +01:00
item - > set_icon ( 0 , get_icon ( " Enum " , " EditorIcons " ) ) ;
2014-02-10 02:10:30 +01:00
2016-08-03 16:28:20 +02:00
} break ;
2016-08-24 04:21:41 +02:00
case PROPERTY_HINT_METHOD_OF_VARIANT_TYPE : ///< a property of a type
2016-08-24 00:29:07 +02:00
case PROPERTY_HINT_METHOD_OF_BASE_TYPE : ///< a method of a base type
case PROPERTY_HINT_METHOD_OF_INSTANCE : ///< a method of an instance
case PROPERTY_HINT_METHOD_OF_SCRIPT : ///< a method of a script & base
case PROPERTY_HINT_PROPERTY_OF_VARIANT_TYPE : ///< a property of a type
case PROPERTY_HINT_PROPERTY_OF_BASE_TYPE : ///< a property of a base type
case PROPERTY_HINT_PROPERTY_OF_INSTANCE : ///< a property of an instance
case PROPERTY_HINT_PROPERTY_OF_SCRIPT : ///< a property of a script & base
2016-08-03 16:28:20 +02:00
case PROPERTY_HINT_TYPE_STRING : {
2017-03-05 16:44:50 +01:00
item - > set_cell_mode ( 1 , TreeItem : : CELL_MODE_CUSTOM ) ;
item - > set_editable ( 1 , ! read_only ) ;
2016-08-03 16:28:20 +02:00
if ( show_type_icons )
2017-03-05 16:44:50 +01:00
item - > set_icon ( 0 , get_icon ( " String " , " EditorIcons " ) ) ;
item - > set_text ( 1 , obj - > get ( p . name ) ) ;
2016-08-03 16:28:20 +02:00
2014-02-10 02:10:30 +01:00
} break ;
2016-08-24 00:29:07 +02:00
2014-02-10 02:10:30 +01:00
default : {
2017-03-05 16:44:50 +01:00
item - > set_cell_mode ( 1 , TreeItem : : CELL_MODE_STRING ) ;
item - > set_editable ( 1 , ! read_only ) ;
2015-12-11 13:37:34 +01:00
if ( show_type_icons )
2017-03-05 16:44:50 +01:00
item - > set_icon ( 0 , get_icon ( " String " , " EditorIcons " ) ) ;
item - > set_text ( 1 , obj - > get ( p . name ) ) ;
if ( p . hint = = PROPERTY_HINT_MULTILINE_TEXT )
item - > add_button ( 1 , get_icon ( " MultiLine " , " EditorIcons " ) ) ;
2014-02-10 02:10:30 +01:00
} break ;
}
} break ;
2015-08-26 01:45:51 +02:00
case Variant : : ARRAY : {
2017-03-05 16:44:50 +01:00
item - > set_cell_mode ( 1 , TreeItem : : CELL_MODE_CUSTOM ) ;
item - > add_button ( 1 , get_icon ( " EditResource " , " EditorIcons " ) ) ;
2015-08-26 01:45:51 +02:00
Variant v = obj - > get ( p . name ) ;
2016-10-26 13:38:41 +02:00
String type_name = " Array " ;
String type_name_suffix = " " ;
2017-03-05 16:44:50 +01:00
2016-10-26 13:38:41 +02:00
String hint = p . hint_string ;
2017-03-05 16:44:50 +01:00
while ( hint . begins_with ( itos ( Variant : : ARRAY ) + " : " ) ) {
2016-10-26 13:38:41 +02:00
type_name + = " <Array " ;
type_name_suffix + = " > " ;
2018-02-05 15:41:13 +01:00
hint = hint . right ( 2 ) ;
2016-10-26 13:38:41 +02:00
}
2017-03-05 16:44:50 +01:00
if ( hint . find ( " : " ) > = 0 ) {
2018-02-05 15:41:13 +01:00
int colon_pos = hint . find ( " : " ) ;
String hint_string = hint . right ( colon_pos + 1 ) ;
hint = hint . left ( colon_pos ) ;
PropertyHint property_hint = PROPERTY_HINT_NONE ;
2017-03-05 16:44:50 +01:00
if ( hint . find ( " / " ) > = 0 ) {
2018-02-05 15:41:13 +01:00
int slash_pos = hint . find ( " / " ) ;
property_hint = PropertyHint ( hint . right ( slash_pos + 1 ) . to_int ( ) ) ;
hint = hint . left ( slash_pos ) ;
}
if ( property_hint = = PROPERTY_HINT_RESOURCE_TYPE ) {
type_name + = " < " + hint_string ;
} else {
type_name + = " < " + Variant : : get_type_name ( Variant : : Type ( hint . to_int ( ) ) ) ;
2016-10-26 13:38:41 +02:00
}
type_name_suffix + = " > " ;
}
type_name + = type_name_suffix ;
2017-03-05 16:44:50 +01:00
2015-08-26 01:45:51 +02:00
if ( v . is_array ( ) )
2018-02-05 15:41:13 +01:00
item - > set_text ( 1 , type_name + " ( " + itos ( v . call ( " size " ) ) + " ) " ) ;
2015-08-26 01:45:51 +02:00
else
2018-02-05 15:41:13 +01:00
item - > set_text ( 1 , type_name + " () " ) ;
2015-08-26 01:45:51 +02:00
2017-03-05 16:44:50 +01:00
if ( show_type_icons )
2017-12-18 15:14:27 +01:00
item - > set_icon ( 0 , get_icon ( " PoolByteArray " , " EditorIcons " ) ) ;
2015-08-26 01:45:51 +02:00
2017-05-01 14:25:47 +02:00
} break ;
case Variant : : DICTIONARY : {
2017-10-17 16:39:31 +02:00
Variant v = obj - > get ( p . name ) ;
2017-05-01 14:25:47 +02:00
item - > set_cell_mode ( 1 , TreeItem : : CELL_MODE_STRING ) ;
2017-10-17 16:39:31 +02:00
item - > set_text ( 1 , String ( " Dictionary{ " ) + itos ( v . call ( " size " ) ) + " } " ) ;
item - > add_button ( 1 , get_icon ( " EditResource " , " EditorIcons " ) ) ;
if ( show_type_icons )
2017-12-18 15:14:27 +01:00
item - > set_icon ( 0 , get_icon ( " Dictionary " , " EditorIcons " ) ) ;
2017-05-01 14:25:47 +02:00
2015-08-26 01:45:51 +02:00
} break ;
2017-01-11 04:52:51 +01:00
case Variant : : POOL_INT_ARRAY : {
2014-02-10 02:10:30 +01:00
2017-03-05 16:44:50 +01:00
item - > set_cell_mode ( 1 , TreeItem : : CELL_MODE_CUSTOM ) ;
item - > add_button ( 1 , get_icon ( " EditResource " , " EditorIcons " ) ) ;
2015-08-26 01:45:51 +02:00
Variant v = obj - > get ( p . name ) ;
if ( v . is_array ( ) )
2017-03-05 16:44:50 +01:00
item - > set_text ( 1 , " IntArray[ " + itos ( v . call ( " size " ) ) + " ] " ) ;
2015-08-26 01:45:51 +02:00
else
2017-03-05 16:44:50 +01:00
item - > set_text ( 1 , " IntArray[] " ) ;
2015-12-11 13:37:34 +01:00
if ( show_type_icons )
2017-12-18 15:14:27 +01:00
item - > set_icon ( 0 , get_icon ( " PoolIntArray " , " EditorIcons " ) ) ;
2014-02-10 02:10:30 +01:00
} break ;
2017-01-11 04:52:51 +01:00
case Variant : : POOL_REAL_ARRAY : {
2014-02-10 02:10:30 +01:00
2017-03-05 16:44:50 +01:00
item - > set_cell_mode ( 1 , TreeItem : : CELL_MODE_CUSTOM ) ;
item - > add_button ( 1 , get_icon ( " EditResource " , " EditorIcons " ) ) ;
2015-08-26 01:45:51 +02:00
Variant v = obj - > get ( p . name ) ;
if ( v . is_array ( ) )
2017-03-05 16:44:50 +01:00
item - > set_text ( 1 , " FloatArray[ " + itos ( v . call ( " size " ) ) + " ] " ) ;
2015-08-26 01:45:51 +02:00
else
2017-03-05 16:44:50 +01:00
item - > set_text ( 1 , " FloatArray[] " ) ;
2015-12-11 13:37:34 +01:00
if ( show_type_icons )
2017-12-18 15:14:27 +01:00
item - > set_icon ( 0 , get_icon ( " PoolRealArray " , " EditorIcons " ) ) ;
2015-08-26 01:45:51 +02:00
2014-02-10 02:10:30 +01:00
} break ;
2017-01-11 04:52:51 +01:00
case Variant : : POOL_STRING_ARRAY : {
2014-02-10 02:10:30 +01:00
2017-03-05 16:44:50 +01:00
item - > set_cell_mode ( 1 , TreeItem : : CELL_MODE_CUSTOM ) ;
item - > add_button ( 1 , get_icon ( " EditResource " , " EditorIcons " ) ) ;
2015-08-26 01:45:51 +02:00
Variant v = obj - > get ( p . name ) ;
if ( v . is_array ( ) )
2017-03-05 16:44:50 +01:00
item - > set_text ( 1 , " String[ " + itos ( v . call ( " size " ) ) + " ] " ) ;
2015-08-26 01:45:51 +02:00
else
2017-03-05 16:44:50 +01:00
item - > set_text ( 1 , " String[] " ) ;
2015-12-11 13:37:34 +01:00
if ( show_type_icons )
2017-12-18 15:14:27 +01:00
item - > set_icon ( 0 , get_icon ( " PoolStringArray " , " EditorIcons " ) ) ;
2015-08-26 01:45:51 +02:00
2014-02-10 02:10:30 +01:00
} break ;
2017-01-11 04:52:51 +01:00
case Variant : : POOL_BYTE_ARRAY : {
2014-02-10 02:10:30 +01:00
2017-03-05 16:44:50 +01:00
item - > set_cell_mode ( 1 , TreeItem : : CELL_MODE_CUSTOM ) ;
item - > add_button ( 1 , get_icon ( " EditResource " , " EditorIcons " ) ) ;
2015-08-26 01:45:51 +02:00
Variant v = obj - > get ( p . name ) ;
if ( v . is_array ( ) )
2017-03-05 16:44:50 +01:00
item - > set_text ( 1 , " Byte[ " + itos ( v . call ( " size " ) ) + " ] " ) ;
2015-08-26 01:45:51 +02:00
else
2017-03-05 16:44:50 +01:00
item - > set_text ( 1 , " Byte[] " ) ;
2015-12-11 13:37:34 +01:00
if ( show_type_icons )
2017-12-18 15:14:27 +01:00
item - > set_icon ( 0 , get_icon ( " PoolByteArray " , " EditorIcons " ) ) ;
2015-08-26 01:45:51 +02:00
} break ;
2017-01-11 04:52:51 +01:00
case Variant : : POOL_VECTOR2_ARRAY : {
2015-08-26 01:45:51 +02:00
2017-03-05 16:44:50 +01:00
item - > set_cell_mode ( 1 , TreeItem : : CELL_MODE_CUSTOM ) ;
item - > add_button ( 1 , get_icon ( " EditResource " , " EditorIcons " ) ) ;
2015-08-26 01:45:51 +02:00
Variant v = obj - > get ( p . name ) ;
if ( v . is_array ( ) )
2017-03-05 16:44:50 +01:00
item - > set_text ( 1 , " Vector2[ " + itos ( v . call ( " size " ) ) + " ] " ) ;
2015-08-26 01:45:51 +02:00
else
2017-03-05 16:44:50 +01:00
item - > set_text ( 1 , " Vector2[] " ) ;
2015-12-11 13:37:34 +01:00
if ( show_type_icons )
2017-03-05 16:44:50 +01:00
item - > set_icon ( 0 , get_icon ( " Vector2 " , " EditorIcons " ) ) ;
2015-08-26 01:45:51 +02:00
} break ;
2017-01-11 04:52:51 +01:00
case Variant : : POOL_VECTOR3_ARRAY : {
2015-08-26 01:45:51 +02:00
2017-03-05 16:44:50 +01:00
item - > set_cell_mode ( 1 , TreeItem : : CELL_MODE_CUSTOM ) ;
item - > add_button ( 1 , get_icon ( " EditResource " , " EditorIcons " ) ) ;
2015-08-26 01:45:51 +02:00
Variant v = obj - > get ( p . name ) ;
if ( v . is_array ( ) )
2017-03-05 16:44:50 +01:00
item - > set_text ( 1 , " Vector3[ " + itos ( v . call ( " size " ) ) + " ] " ) ;
2015-08-26 01:45:51 +02:00
else
2017-03-05 16:44:50 +01:00
item - > set_text ( 1 , " Vector3[] " ) ;
2015-12-11 13:37:34 +01:00
if ( show_type_icons )
2017-12-18 15:14:27 +01:00
item - > set_icon ( 0 , get_icon ( " Vector3 " , " EditorIcons " ) ) ;
2015-08-26 01:45:51 +02:00
} break ;
2017-01-11 04:52:51 +01:00
case Variant : : POOL_COLOR_ARRAY : {
2015-08-26 01:45:51 +02:00
2017-03-05 16:44:50 +01:00
item - > set_cell_mode ( 1 , TreeItem : : CELL_MODE_CUSTOM ) ;
item - > add_button ( 1 , get_icon ( " EditResource " , " EditorIcons " ) ) ;
2015-08-26 01:45:51 +02:00
Variant v = obj - > get ( p . name ) ;
if ( v . is_array ( ) )
2017-03-05 16:44:50 +01:00
item - > set_text ( 1 , " Color[ " + itos ( v . call ( " size " ) ) + " ] " ) ;
2015-08-26 01:45:51 +02:00
else
2017-03-05 16:44:50 +01:00
item - > set_text ( 1 , " Color[] " ) ;
2015-12-11 13:37:34 +01:00
if ( show_type_icons )
2017-03-05 16:44:50 +01:00
item - > set_icon ( 0 , get_icon ( " Color " , " EditorIcons " ) ) ;
2015-08-26 01:45:51 +02:00
2014-02-10 02:10:30 +01:00
} break ;
case Variant : : VECTOR2 : {
2017-03-05 16:44:50 +01:00
item - > set_cell_mode ( 1 , TreeItem : : CELL_MODE_CUSTOM ) ;
item - > set_editable ( 1 , true ) ;
item - > set_text ( 1 , obj - > get ( p . name ) ) ;
2015-12-11 13:37:34 +01:00
if ( show_type_icons )
2017-03-05 16:44:50 +01:00
item - > set_icon ( 0 , get_icon ( " Vector2 " , " EditorIcons " ) ) ;
2014-02-10 02:10:30 +01:00
} break ;
case Variant : : RECT2 : {
2017-03-05 16:44:50 +01:00
item - > set_cell_mode ( 1 , TreeItem : : CELL_MODE_CUSTOM ) ;
item - > set_editable ( 1 , true ) ;
item - > set_text ( 1 , obj - > get ( p . name ) ) ;
2015-12-11 13:37:34 +01:00
if ( show_type_icons )
2017-03-05 16:44:50 +01:00
item - > set_icon ( 0 , get_icon ( " Rect2 " , " EditorIcons " ) ) ;
2014-02-10 02:10:30 +01:00
} break ;
case Variant : : VECTOR3 : {
2017-03-05 16:44:50 +01:00
item - > set_cell_mode ( 1 , TreeItem : : CELL_MODE_CUSTOM ) ;
item - > set_editable ( 1 , true ) ;
item - > set_text ( 1 , obj - > get ( p . name ) ) ;
2015-12-11 13:37:34 +01:00
if ( show_type_icons )
2017-12-18 15:14:27 +01:00
item - > set_icon ( 0 , get_icon ( " Vector3 " , " EditorIcons " ) ) ;
2014-02-10 02:10:30 +01:00
} break ;
2017-01-11 04:52:51 +01:00
case Variant : : TRANSFORM2D :
case Variant : : BASIS : {
2015-11-23 19:34:54 +01:00
2017-03-05 16:44:50 +01:00
item - > set_cell_mode ( 1 , TreeItem : : CELL_MODE_CUSTOM ) ;
item - > set_editable ( 1 , true ) ;
2015-11-23 19:34:54 +01:00
item - > set_text ( 1 , obj - > get ( p . name ) ) ;
2017-12-18 15:14:27 +01:00
2015-11-23 19:34:54 +01:00
} break ;
2014-02-10 02:10:30 +01:00
case Variant : : TRANSFORM : {
2017-03-05 16:44:50 +01:00
item - > set_cell_mode ( 1 , TreeItem : : CELL_MODE_CUSTOM ) ;
item - > set_editable ( 1 , true ) ;
item - > set_text ( 1 , obj - > get ( p . name ) ) ;
2015-12-11 13:37:34 +01:00
if ( show_type_icons )
2017-12-18 15:14:27 +01:00
item - > set_icon ( 0 , get_icon ( " Transform " , " EditorIcons " ) ) ;
2014-02-10 02:10:30 +01:00
} break ;
case Variant : : PLANE : {
2017-03-05 16:44:50 +01:00
item - > set_cell_mode ( 1 , TreeItem : : CELL_MODE_CUSTOM ) ;
item - > set_editable ( 1 , true ) ;
item - > set_text ( 1 , obj - > get ( p . name ) ) ;
2015-12-11 13:37:34 +01:00
if ( show_type_icons )
2017-03-05 16:44:50 +01:00
item - > set_icon ( 0 , get_icon ( " Plane " , " EditorIcons " ) ) ;
2014-02-10 02:10:30 +01:00
} break ;
2017-11-17 03:09:00 +01:00
case Variant : : AABB : {
2014-02-10 02:10:30 +01:00
2017-03-05 16:44:50 +01:00
item - > set_cell_mode ( 1 , TreeItem : : CELL_MODE_CUSTOM ) ;
item - > set_editable ( 1 , true ) ;
2017-11-17 03:09:00 +01:00
item - > set_text ( 1 , " AABB " ) ;
2015-12-11 13:37:34 +01:00
if ( show_type_icons )
2017-11-17 03:09:00 +01:00
item - > set_icon ( 0 , get_icon ( " AABB " , " EditorIcons " ) ) ;
2017-12-18 15:14:27 +01:00
2014-02-10 02:10:30 +01:00
} break ;
case Variant : : QUAT : {
2017-03-05 16:44:50 +01:00
item - > set_cell_mode ( 1 , TreeItem : : CELL_MODE_CUSTOM ) ;
item - > set_editable ( 1 , true ) ;
item - > set_text ( 1 , obj - > get ( p . name ) ) ;
2015-12-11 13:37:34 +01:00
if ( show_type_icons )
2017-03-05 16:44:50 +01:00
item - > set_icon ( 0 , get_icon ( " Quat " , " EditorIcons " ) ) ;
2014-02-10 02:10:30 +01:00
} break ;
case Variant : : COLOR : {
2017-03-05 16:44:50 +01:00
item - > set_cell_mode ( 1 , TreeItem : : CELL_MODE_CUSTOM ) ;
item - > set_editable ( 1 , ! read_only ) ;
item - > set_custom_draw ( 1 , this , " _draw_transparency " ) ;
2015-12-11 13:37:34 +01:00
if ( show_type_icons )
2017-03-05 16:44:50 +01:00
item - > set_icon ( 0 , get_icon ( " Color " , " EditorIcons " ) ) ;
2014-02-10 02:10:30 +01:00
} break ;
2015-08-30 02:09:11 +02:00
2014-02-10 02:10:30 +01:00
case Variant : : NODE_PATH : {
2016-10-11 23:14:03 +02:00
item - > set_cell_mode ( 1 , TreeItem : : CELL_MODE_STRING ) ;
2017-03-05 16:44:50 +01:00
item - > set_editable ( 1 , ! read_only ) ;
item - > set_text ( 1 , obj - > get ( p . name ) ) ;
2017-01-17 06:09:16 +01:00
item - > add_button ( 1 , get_icon ( " CopyNodePath " , " EditorIcons " ) ) ;
2017-12-18 15:14:27 +01:00
if ( show_type_icons )
item - > set_icon ( 0 , get_icon ( " NodePath " , " EditorIcons " ) ) ;
2014-02-10 02:10:30 +01:00
} break ;
case Variant : : OBJECT : {
2017-03-05 16:44:50 +01:00
item - > set_cell_mode ( 1 , TreeItem : : CELL_MODE_CUSTOM ) ;
item - > set_editable ( 1 , ! read_only ) ;
2014-02-10 02:10:30 +01:00
String type ;
2017-03-05 16:44:50 +01:00
if ( p . hint = = PROPERTY_HINT_RESOURCE_TYPE )
type = p . hint_string ;
2015-03-02 04:54:10 +01:00
2017-06-05 01:35:08 +02:00
RES res = obj - > get ( p . name ) . operator RefPtr ( ) ;
2017-10-17 16:39:31 +02:00
if ( type . begins_with ( " RES: " ) & & type ! = " RES: " ) { // Remote resources
res = ResourceLoader : : load ( type . substr ( 4 , type . length ( ) ) ) ;
}
2017-08-18 15:59:31 +02:00
Ref < EncodedObjectAsID > encoded = obj - > get ( p . name ) ; //for debugger and remote tools
if ( encoded . is_valid ( ) ) {
item - > set_text ( 1 , " Object: " + itos ( encoded - > get_object_id ( ) ) ) ;
item - > set_icon ( 1 , Ref < Texture > ( ) ) ;
item - > set_custom_as_button ( 1 , true ) ;
item - > set_editable ( 1 , true ) ;
} else if ( obj - > get ( p . name ) . get_type ( ) = = Variant : : NIL | | res . is_null ( ) ) {
2017-10-17 16:39:31 +02:00
2017-03-05 16:44:50 +01:00
item - > set_text ( 1 , " <null> " ) ;
item - > set_icon ( 1 , Ref < Texture > ( ) ) ;
2017-06-05 01:35:08 +02:00
item - > set_custom_as_button ( 1 , false ) ;
2014-02-10 02:10:30 +01:00
2017-06-05 01:35:08 +02:00
} else if ( res . is_valid ( ) ) {
item - > set_custom_as_button ( 1 , true ) ;
2014-02-10 02:10:30 +01:00
2017-01-03 03:03:46 +01:00
if ( res - > is_class ( " Texture " ) ) {
2017-01-05 23:41:36 +01:00
int tw = EditorSettings : : get_singleton ( ) - > get ( " docks/property_editor/texture_preview_width " ) ;
2017-04-11 13:22:57 +02:00
Vector2 size ( res - > call ( " get_width " ) , res - > call ( " get_height " ) ) ;
if ( size . width < size . height ) {
tw = MAX ( ( size . width / size . height ) * tw , 1 ) ;
}
2017-03-05 16:44:50 +01:00
item - > set_icon_max_width ( 1 , tw ) ;
item - > set_icon ( 1 , res ) ;
item - > set_text ( 1 , " " ) ;
2014-02-10 02:10:30 +01:00
} else if ( res - > get_name ( ) ! = " " ) {
item - > set_text ( 1 , res - > get_name ( ) ) ;
2017-03-05 16:44:50 +01:00
} else if ( res - > get_path ( ) ! = " " & & ! res - > get_path ( ) . begins_with ( " local:// " ) ) {
2014-02-10 02:10:30 +01:00
item - > set_text ( 1 , res - > get_path ( ) . get_file ( ) ) ;
} else {
2017-03-05 16:44:50 +01:00
item - > set_text ( 1 , " < " + res - > get_class ( ) + " > " ) ;
2016-07-06 19:04:21 +02:00
}
2014-02-10 02:10:30 +01:00
2017-03-05 16:44:50 +01:00
if ( has_icon ( res - > get_class ( ) , " EditorIcons " ) ) {
type = res - > get_class ( ) ;
2015-03-02 04:54:10 +01:00
}
2015-03-16 04:47:37 +01:00
if ( res . is_valid ( ) & & res - > get_path ( ) . is_resource_file ( ) ) {
2017-03-05 16:44:50 +01:00
item - > set_tooltip ( 1 , res - > get_path ( ) ) ;
2015-03-16 04:47:37 +01:00
} else if ( res . is_valid ( ) ) {
2017-03-05 16:44:50 +01:00
item - > set_tooltip ( 1 , res - > get_name ( ) + " ( " + res - > get_class ( ) + " ) " ) ;
2015-03-16 04:47:37 +01:00
}
2017-04-11 14:26:47 +02:00
if ( res - > is_class ( " Script " ) ) {
item - > set_text ( 1 , res - > get_path ( ) . get_file ( ) ) ;
} else if ( ! res - > is_class ( " Texture " ) ) {
2016-05-27 19:18:40 +02:00
//texture already previews via itself
2017-08-07 12:17:31 +02:00
EditorResourcePreview : : get_singleton ( ) - > queue_edited_resource_preview ( res , this , " _resource_preview_done " , item - > get_instance_id ( ) ) ;
2016-05-27 19:18:40 +02:00
}
2014-02-10 02:10:30 +01:00
}
2017-03-05 16:44:50 +01:00
if ( type ! = String ( ) ) {
if ( type . find ( " , " ) ! = - 1 )
type = type . get_slice ( " , " , 0 ) ;
if ( has_icon ( type , " EditorIcons " ) )
item - > set_icon ( 0 , get_icon ( type , " EditorIcons " ) ) ;
2014-02-10 02:10:30 +01:00
else
2017-03-05 16:44:50 +01:00
item - > set_icon ( 0 , get_icon ( " Object " , " EditorIcons " ) ) ;
2014-02-10 02:10:30 +01:00
}
} break ;
default : { } ;
}
if ( keying ) {
2017-03-05 16:44:50 +01:00
if ( p . hint = = PROPERTY_HINT_SPRITE_FRAME ) {
2015-05-25 06:46:45 +02:00
2017-03-05 16:44:50 +01:00
item - > add_button ( 1 , get_icon ( " KeyNext " , " EditorIcons " ) , 5 ) ;
2015-05-25 06:46:45 +02:00
} else {
2017-03-05 16:44:50 +01:00
item - > add_button ( 1 , get_icon ( " Key " , " EditorIcons " ) , 2 ) ;
2015-05-25 06:46:45 +02:00
}
2014-02-10 02:10:30 +01:00
}
2017-03-05 16:44:50 +01:00
bool has_reload = false ;
2016-02-03 00:44:42 +01:00
2017-12-04 14:17:58 +01:00
if ( _is_instanced_node_with_original_property_different ( p . name , item ) ) {
item - > add_button ( 1 , get_icon ( " ReloadSmall " , " EditorIcons " ) , 3 ) ;
has_reload = true ;
2014-02-10 02:10:30 +01:00
}
2017-03-05 16:44:50 +01:00
if ( obj - > call ( " property_can_revert " , p . name ) . operator bool ( ) ) {
2017-01-05 13:16:00 +01:00
2017-03-05 16:44:50 +01:00
item - > add_button ( 1 , get_icon ( " ReloadSmall " , " EditorIcons " ) , 3 ) ;
has_reload = true ;
2017-01-05 13:16:00 +01:00
}
2016-01-03 00:17:31 +01:00
if ( ! has_reload & & ! obj - > get_script ( ) . is_null ( ) ) {
Ref < Script > scr = obj - > get_script ( ) ;
Variant orig_value ;
2017-03-05 16:44:50 +01:00
if ( scr - > get_property_default_value ( p . name , orig_value ) ) {
if ( orig_value ! = obj - > get ( p . name ) ) {
item - > add_button ( 1 , get_icon ( " ReloadSmall " , " EditorIcons " ) , 3 ) ;
has_reload = true ;
2016-01-03 00:17:31 +01:00
}
}
}
2017-12-04 14:17:58 +01:00
if ( _might_be_in_instance ( ) & & ! has_reload & & item - > get_cell_mode ( 1 ) = = TreeItem : : CELL_MODE_RANGE & & item - > get_text ( 1 ) = = String ( ) ) {
2017-03-05 16:44:50 +01:00
item - > add_button ( 1 , get_icon ( " ReloadEmpty " , " EditorIcons " ) , 3 , true ) ;
2016-02-03 00:44:42 +01:00
}
2014-02-10 02:10:30 +01:00
}
}
2017-03-05 16:44:50 +01:00
void PropertyEditor : : _draw_transparency ( Object * t , const Rect2 & p_rect ) {
2017-01-15 17:46:42 +01:00
2017-08-24 22:58:51 +02:00
TreeItem * ti = Object : : cast_to < TreeItem > ( t ) ;
2017-01-15 17:46:42 +01:00
if ( ! ti )
2017-03-05 16:44:50 +01:00
return ;
2017-01-15 17:46:42 +01:00
2017-03-05 16:44:50 +01:00
Color color = obj - > get ( ti - > get_metadata ( 1 ) ) ;
2017-09-27 21:44:48 +02:00
Ref < Texture > arrow = tree - > get_icon ( " select_option " ) ;
2017-01-15 17:46:42 +01:00
// make a little space between consecutive color fields
2017-03-05 16:44:50 +01:00
Rect2 area = p_rect ;
2017-06-04 00:25:13 +02:00
area . position . y + = 1 ;
2017-03-05 16:44:50 +01:00
area . size . height - = 2 ;
area . size . width - = arrow - > get_size ( ) . width + 5 ;
2017-09-27 21:44:48 +02:00
tree - > draw_texture_rect ( get_icon ( " GuiMiniCheckerboard " , " EditorIcons " ) , area , true ) ;
2017-01-15 17:46:42 +01:00
tree - > draw_rect ( area , color ) ;
}
2017-06-25 22:30:28 +02:00
void PropertyEditor : : _item_folded ( Object * item_obj ) {
if ( updating_folding )
return ;
2017-08-24 22:58:51 +02:00
TreeItem * item = Object : : cast_to < TreeItem > ( item_obj ) ;
2017-06-25 22:30:28 +02:00
obj - > editor_set_section_unfold ( item - > get_metadata ( 0 ) , ! item - > is_collapsed ( ) ) ;
}
2014-02-10 02:10:30 +01:00
void PropertyEditor : : _item_selected ( ) {
TreeItem * item = tree - > get_selected ( ) ;
ERR_FAIL_COND ( ! item ) ;
2017-03-05 16:44:50 +01:00
selected_property = item - > get_metadata ( 1 ) ;
2014-02-10 02:10:30 +01:00
}
2017-08-10 21:02:19 +02:00
void PropertyEditor : : _item_rmb_edited ( ) {
_custom_editor_request ( true ) ;
}
2017-03-05 16:44:50 +01:00
void PropertyEditor : : _edit_set ( const String & p_name , const Variant & p_value , bool p_refresh_all , const String & p_changed_field ) {
2014-02-10 02:10:30 +01:00
if ( autoclear ) {
TreeItem * item = tree - > get_selected ( ) ;
2017-03-05 16:44:50 +01:00
if ( item & & item - > get_cell_mode ( 0 ) = = TreeItem : : CELL_MODE_CHECK ) {
2014-02-10 02:10:30 +01:00
2017-03-05 16:44:50 +01:00
item - > set_checked ( 0 , true ) ;
2014-02-10 02:10:30 +01:00
}
}
2017-10-17 16:39:31 +02:00
if ( ! undo_redo | | Object : : cast_to < ArrayPropertyEdit > ( obj ) | | Object : : cast_to < DictionaryPropertyEdit > ( obj ) ) { //kind of hacky
2014-02-10 02:10:30 +01:00
2017-03-05 16:44:50 +01:00
obj - > set ( p_name , p_value ) ;
2017-02-01 13:45:45 +01:00
if ( p_refresh_all )
2017-03-05 16:44:50 +01:00
_changed_callbacks ( obj , " " ) ;
2017-02-01 13:45:45 +01:00
else
2017-03-05 16:44:50 +01:00
_changed_callbacks ( obj , p_name ) ;
2017-02-01 13:45:45 +01:00
2017-03-05 16:44:50 +01:00
emit_signal ( _prop_edited , p_name ) ;
2014-02-10 02:10:30 +01:00
2017-08-24 22:58:51 +02:00
} else if ( Object : : cast_to < MultiNodeEdit > ( obj ) ) {
2014-02-10 02:10:30 +01:00
2017-08-24 22:58:51 +02:00
Object : : cast_to < MultiNodeEdit > ( obj ) - > set_property_field ( p_name , p_value , p_changed_field ) ;
2017-03-05 16:44:50 +01:00
_changed_callbacks ( obj , p_name ) ;
emit_signal ( _prop_edited , p_name ) ;
2014-02-10 02:10:30 +01:00
} else {
2017-03-05 16:44:50 +01:00
undo_redo - > create_action ( TTR ( " Set " ) + " " + p_name , UndoRedo : : MERGE_ENDS ) ;
undo_redo - > add_do_property ( obj , p_name , p_value ) ;
undo_redo - > add_undo_property ( obj , p_name , obj - > get ( p_name ) ) ;
2017-01-10 05:04:31 +01:00
2017-02-01 13:45:45 +01:00
if ( p_refresh_all ) {
2017-03-05 16:44:50 +01:00
undo_redo - > add_do_method ( this , " _changed_callback " , obj , " " ) ;
undo_redo - > add_undo_method ( this , " _changed_callback " , obj , " " ) ;
2017-02-01 13:45:45 +01:00
} else {
2017-01-10 05:04:31 +01:00
2017-03-05 16:44:50 +01:00
undo_redo - > add_do_method ( this , " _changed_callback " , obj , p_name ) ;
undo_redo - > add_undo_method ( this , " _changed_callback " , obj , p_name ) ;
2017-02-01 13:45:45 +01:00
}
2017-01-05 13:16:00 +01:00
2017-08-24 22:58:51 +02:00
Resource * r = Object : : cast_to < Resource > ( obj ) ;
2014-02-10 02:10:30 +01:00
if ( r ) {
2017-03-05 16:44:50 +01:00
if ( ! r - > is_edited ( ) & & String ( p_name ) ! = " resource/edited " ) {
undo_redo - > add_do_method ( r , " set_edited " , true ) ;
undo_redo - > add_undo_method ( r , " set_edited " , false ) ;
2014-02-10 02:10:30 +01:00
}
2017-01-10 05:04:31 +01:00
2017-03-05 16:44:50 +01:00
if ( String ( p_name ) = = " resource_local_to_scene " ) {
2017-01-10 05:04:31 +01:00
bool prev = obj - > get ( p_name ) ;
bool next = p_value ;
if ( next ) {
2017-03-05 16:44:50 +01:00
undo_redo - > add_do_method ( this , " setup_local_to_scene " ) ;
2017-01-10 05:04:31 +01:00
}
if ( prev ) {
2017-03-05 16:44:50 +01:00
undo_redo - > add_undo_method ( this , " setup_local_to_scene " ) ;
2017-01-10 05:04:31 +01:00
}
}
2014-02-10 02:10:30 +01:00
}
2017-03-05 16:44:50 +01:00
undo_redo - > add_do_method ( this , " emit_signal " , _prop_edited , p_name ) ;
undo_redo - > add_undo_method ( this , " emit_signal " , _prop_edited , p_name ) ;
2014-02-10 02:10:30 +01:00
undo_redo - > commit_action ( ) ;
}
}
void PropertyEditor : : _item_edited ( ) {
2017-03-05 16:44:50 +01:00
TreeItem * item = tree - > get_edited ( ) ;
2016-02-08 15:59:44 +01:00
if ( ! item )
return ; //it all happened too fast..
2014-02-10 02:10:30 +01:00
Dictionary d = item - > get_metadata ( 0 ) ;
2015-08-30 02:09:11 +02:00
2017-03-05 16:44:50 +01:00
String name = d [ " name " ] ;
2014-02-10 02:10:30 +01:00
2017-03-05 16:44:50 +01:00
if ( tree - > get_edited_column ( ) = = 0 ) {
2014-02-10 02:10:30 +01:00
//property checked
if ( autoclear ) {
if ( ! item - > is_checked ( 0 ) ) {
2017-03-05 16:44:50 +01:00
obj - > set ( name , Variant ( ) ) ;
2014-02-10 02:10:30 +01:00
update_property ( name ) ;
} else {
Variant : : CallError ce ;
2017-03-05 16:44:50 +01:00
obj - > set ( name , Variant : : construct ( Variant : : Type ( int ( d [ " type " ] ) ) , NULL , 0 , ce ) ) ;
2014-02-10 02:10:30 +01:00
}
} else {
2017-03-05 16:44:50 +01:00
emit_signal ( " property_toggled " , name , item - > is_checked ( 0 ) ) ;
2014-02-10 02:10:30 +01:00
}
return ;
}
2017-03-05 16:44:50 +01:00
if ( autoclear & & item - > get_cell_mode ( 0 ) = = TreeItem : : CELL_MODE_CHECK & & item - > get_cell_mode ( 1 ) ! = TreeItem : : CELL_MODE_CUSTOM ) {
item - > set_checked ( 0 , true ) ;
2014-02-10 02:10:30 +01:00
}
2017-03-05 16:44:50 +01:00
int type = d [ " type " ] ;
int hint = d [ " hint " ] ;
2017-02-01 13:45:45 +01:00
int usage = d [ " usage " ] ;
2017-03-05 16:44:50 +01:00
bool refresh_all = usage & PROPERTY_USAGE_UPDATE_ALL_IF_MODIFIED ;
2017-02-01 13:45:45 +01:00
2017-03-05 16:44:50 +01:00
String hint_text = d [ " hint_text " ] ;
switch ( type ) {
2015-08-30 02:09:11 +02:00
2014-02-10 02:10:30 +01:00
case Variant : : NIL : {
2015-08-30 02:09:11 +02:00
} break ;
2014-02-10 02:10:30 +01:00
case Variant : : BOOL : {
2015-08-30 02:09:11 +02:00
2016-09-19 23:41:48 +02:00
item - > set_tooltip ( 1 , item - > is_checked ( 1 ) ? " True " : " False " ) ;
2017-04-03 10:57:50 +02:00
_edit_set ( name , item - > is_checked ( 1 ) , refresh_all ) ;
2014-02-10 02:10:30 +01:00
} break ;
case Variant : : INT :
case Variant : : REAL : {
2017-03-05 16:44:50 +01:00
if ( hint = = PROPERTY_HINT_LAYERS_2D_PHYSICS | | hint = = PROPERTY_HINT_LAYERS_2D_RENDER | | hint = = PROPERTY_HINT_LAYERS_3D_PHYSICS | | hint = = PROPERTY_HINT_LAYERS_3D_RENDER )
2014-02-10 02:10:30 +01:00
break ;
2017-03-05 16:44:50 +01:00
if ( hint = = PROPERTY_HINT_EXP_EASING )
2014-02-10 02:10:30 +01:00
break ;
2017-03-05 16:44:50 +01:00
if ( hint = = PROPERTY_HINT_FLAGS )
2014-02-10 02:10:30 +01:00
break ;
2017-03-05 16:44:50 +01:00
if ( type = = Variant : : INT )
2017-08-06 14:32:52 +02:00
_edit_set ( name , int64_t ( round ( item - > get_range ( 1 ) ) ) , refresh_all ) ;
2014-02-10 02:10:30 +01:00
else
2017-03-05 16:44:50 +01:00
_edit_set ( name , item - > get_range ( 1 ) , refresh_all ) ;
2014-02-10 02:10:30 +01:00
} break ;
case Variant : : STRING : {
2015-08-30 02:09:11 +02:00
2017-03-05 16:44:50 +01:00
if ( hint = = PROPERTY_HINT_ENUM ) {
2014-02-10 02:10:30 +01:00
2017-03-05 16:44:50 +01:00
int idx = item - > get_range ( 1 ) ;
2014-02-10 02:10:30 +01:00
Vector < String > strings = hint_text . split ( " , " ) ;
String txt ;
2017-03-05 16:44:50 +01:00
if ( idx > = 0 & & idx < strings . size ( ) ) {
2014-02-10 02:10:30 +01:00
2017-03-05 16:44:50 +01:00
txt = strings [ idx ] ;
2014-02-10 02:10:30 +01:00
}
2017-03-05 16:44:50 +01:00
_edit_set ( name , txt , refresh_all ) ;
2014-02-10 02:10:30 +01:00
} else {
2017-03-05 16:44:50 +01:00
_edit_set ( name , item - > get_text ( 1 ) , refresh_all ) ;
2014-02-10 02:10:30 +01:00
}
} break ;
2015-08-30 02:09:11 +02:00
2017-12-06 21:36:34 +01:00
// math types
2014-02-10 02:10:30 +01:00
case Variant : : VECTOR3 : {
2015-08-30 02:09:11 +02:00
2014-02-10 02:10:30 +01:00
} break ;
case Variant : : PLANE : {
2015-08-30 02:09:11 +02:00
2014-02-10 02:10:30 +01:00
} break ;
case Variant : : QUAT : {
2015-08-30 02:09:11 +02:00
2014-02-10 02:10:30 +01:00
} break ;
2017-11-17 03:09:00 +01:00
case Variant : : AABB : {
2015-08-30 02:09:11 +02:00
2014-02-10 02:10:30 +01:00
} break ;
2017-01-11 04:52:51 +01:00
case Variant : : BASIS : {
2015-08-30 02:09:11 +02:00
2014-02-10 02:10:30 +01:00
} break ;
case Variant : : TRANSFORM : {
2015-08-30 02:09:11 +02:00
2014-02-10 02:10:30 +01:00
} break ;
case Variant : : COLOR : {
2017-08-26 17:46:49 +02:00
2014-02-10 02:10:30 +01:00
} break ;
2015-08-30 02:09:11 +02:00
2014-02-10 02:10:30 +01:00
case Variant : : NODE_PATH : {
2017-03-05 16:44:50 +01:00
_edit_set ( name , NodePath ( item - > get_text ( 1 ) ) , refresh_all ) ;
2015-08-30 02:09:11 +02:00
2017-06-05 01:35:08 +02:00
} break ;
case Variant : : OBJECT : {
if ( ! item - > is_custom_set_as_button ( 1 ) )
break ;
2017-08-18 15:59:31 +02:00
Ref < EncodedObjectAsID > encoded = obj - > get ( name ) ; //for debugger and remote tools
if ( encoded . is_valid ( ) ) {
emit_signal ( " object_id_selected " , encoded - > get_object_id ( ) ) ;
}
2017-06-05 01:35:08 +02:00
RES res = obj - > get ( name ) ;
if ( res . is_valid ( ) ) {
emit_signal ( " resource_selected " , res . get_ref_ptr ( ) , name ) ;
}
2014-02-10 02:10:30 +01:00
} break ;
case Variant : : DICTIONARY : {
2015-08-30 02:09:11 +02:00
2014-02-10 02:10:30 +01:00
} break ;
2015-08-30 02:09:11 +02:00
2017-03-05 16:44:50 +01:00
// arrays
2017-01-11 04:52:51 +01:00
case Variant : : POOL_BYTE_ARRAY : {
2015-08-30 02:09:11 +02:00
2014-02-10 02:10:30 +01:00
} break ;
2017-01-11 04:52:51 +01:00
case Variant : : POOL_INT_ARRAY : {
2015-08-30 02:09:11 +02:00
2014-02-10 02:10:30 +01:00
} break ;
2017-01-11 04:52:51 +01:00
case Variant : : POOL_REAL_ARRAY : {
2015-08-30 02:09:11 +02:00
2014-02-10 02:10:30 +01:00
} break ;
2017-01-11 04:52:51 +01:00
case Variant : : POOL_STRING_ARRAY : {
2015-08-30 02:09:11 +02:00
2014-02-10 02:10:30 +01:00
} break ;
2017-01-11 04:52:51 +01:00
case Variant : : POOL_VECTOR3_ARRAY : {
2015-08-30 02:09:11 +02:00
2014-02-10 02:10:30 +01:00
} break ;
2017-01-11 04:52:51 +01:00
case Variant : : POOL_COLOR_ARRAY : {
2015-08-30 02:09:11 +02:00
2014-02-10 02:10:30 +01:00
} break ;
} ;
}
void PropertyEditor : : _resource_edit_request ( ) {
2017-03-05 16:44:50 +01:00
RES res = custom_editor - > get_variant ( ) ;
2014-02-10 02:10:30 +01:00
if ( res . is_null ( ) )
return ;
2017-03-05 16:44:50 +01:00
String name = custom_editor - > get_name ( ) ;
2014-02-10 02:10:30 +01:00
2017-03-05 16:44:50 +01:00
emit_signal ( " resource_selected " , res . get_ref_ptr ( ) , name ) ;
2014-02-10 02:10:30 +01:00
}
void PropertyEditor : : _custom_editor_edited ( ) {
if ( ! obj )
return ;
_edit_set ( custom_editor - > get_name ( ) , custom_editor - > get_variant ( ) ) ;
}
2017-03-05 16:44:50 +01:00
void PropertyEditor : : _custom_editor_edited_field ( const String & p_field_name ) {
2017-03-02 10:42:05 +01:00
2017-03-05 16:44:50 +01:00
ERR_FAIL_COND ( p_field_name = = " " ) ;
2017-03-02 10:42:05 +01:00
if ( ! obj )
return ;
_edit_set ( custom_editor - > get_name ( ) , custom_editor - > get_variant ( ) , false , p_field_name ) ;
}
2014-02-10 02:10:30 +01:00
void PropertyEditor : : _custom_editor_request ( bool p_arrow ) {
2017-03-05 16:44:50 +01:00
TreeItem * item = tree - > get_edited ( ) ;
2014-02-10 02:10:30 +01:00
ERR_FAIL_COND ( ! item ) ;
Dictionary d = item - > get_metadata ( 0 ) ;
2017-03-05 16:44:50 +01:00
String name = d [ " name " ] ;
Variant : : Type type = Variant : : NIL ;
2014-02-10 02:10:30 +01:00
if ( d . has ( " type " ) )
2017-03-05 16:44:50 +01:00
type = ( Variant : : Type ) ( ( int ) ( d [ " type " ] ) ) ;
2014-02-10 02:10:30 +01:00
2017-03-05 16:44:50 +01:00
Variant v = obj - > get ( name ) ;
int hint = d . has ( " hint " ) ? d [ " hint " ] . operator int ( ) : - 1 ;
String hint_text = d . has ( " hint_text " ) ? d [ " hint_text " ] : " " ;
Rect2 where = tree - > get_custom_popup_rect ( ) ;
2017-06-04 00:25:13 +02:00
custom_editor - > set_position ( where . position ) ;
2014-02-10 02:10:30 +01:00
2017-03-05 16:44:50 +01:00
if ( custom_editor - > edit ( obj , name , type , v , hint , hint_text ) ) {
2014-02-10 02:10:30 +01:00
custom_editor - > popup ( ) ;
}
}
2017-03-05 16:44:50 +01:00
void PropertyEditor : : edit ( Object * p_object ) {
2015-08-30 02:09:11 +02:00
2017-03-05 16:44:50 +01:00
if ( obj = = p_object )
2014-02-10 02:10:30 +01:00
return ;
if ( obj ) {
2015-08-30 02:09:11 +02:00
2014-02-10 02:10:30 +01:00
obj - > remove_change_receptor ( this ) ;
}
2017-03-05 16:44:50 +01:00
obj = p_object ;
2016-05-01 10:33:32 +02:00
evaluator - > edit ( p_object ) ;
2014-02-10 02:10:30 +01:00
update_tree ( ) ;
2015-08-30 02:09:11 +02:00
2014-02-10 02:10:30 +01:00
if ( obj ) {
2015-08-30 02:09:11 +02:00
2014-02-10 02:10:30 +01:00
obj - > add_change_receptor ( this ) ;
}
}
2017-03-05 16:44:50 +01:00
void PropertyEditor : : _set_range_def ( Object * p_item , String prop , float p_frame ) {
2015-05-25 06:46:45 +02:00
2017-08-24 22:58:51 +02:00
TreeItem * ti = Object : : cast_to < TreeItem > ( p_item ) ;
2015-05-25 06:46:45 +02:00
ERR_FAIL_COND ( ! ti ) ;
2017-03-05 16:44:50 +01:00
ti - > call_deferred ( " set_range " , 1 , p_frame ) ;
obj - > call_deferred ( " set " , prop , p_frame ) ;
2015-05-25 06:46:45 +02:00
}
2014-02-10 02:10:30 +01:00
void PropertyEditor : : _edit_button ( Object * p_item , int p_column , int p_button ) {
2017-08-26 17:46:49 +02:00
2017-08-24 22:58:51 +02:00
TreeItem * ti = Object : : cast_to < TreeItem > ( p_item ) ;
2014-02-10 02:10:30 +01:00
ERR_FAIL_COND ( ! ti ) ;
Dictionary d = ti - > get_metadata ( 0 ) ;
2017-03-05 16:44:50 +01:00
if ( p_button = = 2 ) {
2014-02-10 02:10:30 +01:00
if ( ! d . has ( " name " ) )
return ;
2017-03-05 16:44:50 +01:00
String prop = d [ " name " ] ;
emit_signal ( " property_keyed " , prop , obj - > get ( prop ) , false ) ;
} else if ( p_button = = 5 ) {
2015-05-25 06:46:45 +02:00
print_line ( " PB5 " ) ;
if ( ! d . has ( " name " ) )
return ;
2017-03-05 16:44:50 +01:00
String prop = d [ " name " ] ;
emit_signal ( " property_keyed " , prop , obj - > get ( prop ) , true ) ;
call_deferred ( " _set_range_def " , ti , prop , ti - > get_range ( p_column ) + 1.0 ) ;
} else if ( p_button = = 3 ) {
2014-02-10 02:10:30 +01:00
if ( ! d . has ( " name " ) )
return ;
2017-03-05 16:44:50 +01:00
String prop = d [ " name " ] ;
2014-02-10 02:10:30 +01:00
2015-10-10 14:09:09 +02:00
Variant vorig ;
2017-03-05 16:44:50 +01:00
if ( _might_be_in_instance ( ) & & _get_instanced_node_original_property ( prop , vorig ) ) {
2014-02-10 02:10:30 +01:00
2018-03-09 20:16:08 +01:00
_edit_set ( prop , vorig . duplicate ( true ) ) ; // Set, making sure to duplicate arrays properly
2016-01-03 00:17:31 +01:00
return ;
2014-02-10 02:10:30 +01:00
}
2017-03-05 16:44:50 +01:00
if ( obj - > call ( " property_can_revert " , prop ) . operator bool ( ) ) {
Variant rev = obj - > call ( " property_get_revert " , prop ) ;
_edit_set ( prop , rev ) ;
2017-01-05 13:16:00 +01:00
}
2017-03-05 16:44:50 +01:00
if ( ! obj - > get_script ( ) . is_null ( ) ) {
2016-01-03 00:17:31 +01:00
Ref < Script > scr = obj - > get_script ( ) ;
Variant orig_value ;
2017-03-05 16:44:50 +01:00
if ( scr - > get_property_default_value ( prop , orig_value ) ) {
_edit_set ( prop , orig_value ) ;
2016-01-03 00:17:31 +01:00
}
}
2014-02-10 02:10:30 +01:00
} else {
Dictionary d = ti - > get_metadata ( 0 ) ;
if ( ! d . has ( " type " ) )
return ;
if ( ! d . has ( " hint " ) )
return ;
if ( ! d . has ( " name " ) )
return ;
if ( ! d . has ( " hint_text " ) )
return ;
int t = d [ " type " ] ;
int h = d [ " hint " ] ;
String n = d [ " name " ] ;
String ht = d [ " hint_text " ] ;
2017-03-05 16:44:50 +01:00
if ( t = = Variant : : NODE_PATH ) {
2016-10-11 23:14:03 +02:00
Variant v = obj - > get ( n ) ;
Rect2 where = tree - > get_item_rect ( ti , 1 ) ;
2017-06-04 00:25:13 +02:00
where . position - = tree - > get_scroll ( ) ;
2017-12-23 21:54:45 +01:00
where . position + = tree - > get_global_position ( ) + Point2 ( where . size . width , 0 ) ;
for ( int i = ti - > get_button_count ( p_column ) - 1 ; i > = p_button ; i - - )
where . position . x - = ti - > get_button ( p_column , i ) - > get_width ( ) ;
2017-06-04 00:25:13 +02:00
custom_editor - > set_position ( where . position ) ;
2017-12-23 21:54:45 +01:00
custom_editor - > edit ( obj , n , ( Variant : : Type ) t , v , h , ht ) ;
2016-10-11 23:14:03 +02:00
custom_editor - > popup ( ) ;
2017-03-05 16:44:50 +01:00
} else if ( t = = Variant : : STRING ) {
2014-02-10 02:10:30 +01:00
Variant v = obj - > get ( n ) ;
2017-03-05 16:44:50 +01:00
custom_editor - > edit ( obj , n , ( Variant : : Type ) t , v , h , ht ) ;
if ( h = = PROPERTY_HINT_FILE | | h = = PROPERTY_HINT_DIR | | h = = PROPERTY_HINT_GLOBAL_DIR | | h = = PROPERTY_HINT_GLOBAL_FILE ) {
2014-02-10 02:10:30 +01:00
2017-03-05 16:44:50 +01:00
Rect2 where = tree - > get_item_rect ( ti , 1 ) ;
2017-06-04 00:25:13 +02:00
where . position - = tree - > get_scroll ( ) ;
2017-12-23 21:54:45 +01:00
where . position + = tree - > get_global_position ( ) + Point2 ( where . size . width , 0 ) ;
for ( int i = ti - > get_button_count ( p_column ) - 1 ; i > = p_button ; i - - )
where . position . x - = ti - > get_button ( p_column , i ) - > get_width ( ) ;
2017-06-04 00:25:13 +02:00
custom_editor - > set_position ( where . position ) ;
2014-02-10 02:10:30 +01:00
custom_editor - > popup ( ) ;
} else {
custom_editor - > popup_centered_ratio ( ) ;
}
2017-03-05 16:44:50 +01:00
} else if ( t = = Variant : : OBJECT ) {
2014-02-10 02:10:30 +01:00
RES r = obj - > get ( n ) ;
if ( r . is_valid ( ) ) {
2017-03-05 16:44:50 +01:00
emit_signal ( " resource_selected " , r , n ) ;
2014-02-10 02:10:30 +01:00
}
2017-03-05 16:44:50 +01:00
} else if ( t = = Variant : : INT & & h = = PROPERTY_HINT_OBJECT_ID ) {
2016-05-23 00:28:37 +02:00
2017-03-05 16:44:50 +01:00
emit_signal ( " object_id_selected " , obj - > get ( n ) ) ;
2016-05-23 00:28:37 +02:00
2017-03-05 16:44:50 +01:00
} else if ( t = = Variant : : ARRAY | | t = = Variant : : POOL_INT_ARRAY | | t = = Variant : : POOL_REAL_ARRAY | | t = = Variant : : POOL_STRING_ARRAY | | t = = Variant : : POOL_VECTOR2_ARRAY | | t = = Variant : : POOL_VECTOR3_ARRAY | | t = = Variant : : POOL_COLOR_ARRAY | | t = = Variant : : POOL_BYTE_ARRAY ) {
2015-08-26 01:45:51 +02:00
Variant v = obj - > get ( n ) ;
2017-03-05 16:44:50 +01:00
if ( v . get_type ( ) ! = t ) {
2015-08-26 01:45:51 +02:00
Variant : : CallError ce ;
2017-03-05 16:44:50 +01:00
v = Variant : : construct ( Variant : : Type ( t ) , NULL , 0 , ce ) ;
2015-08-26 01:45:51 +02:00
}
2017-03-05 16:44:50 +01:00
Ref < ArrayPropertyEdit > ape = memnew ( ArrayPropertyEdit ) ;
ape - > edit ( obj , n , ht , Variant : : Type ( t ) ) ;
2015-08-26 01:45:51 +02:00
EditorNode : : get_singleton ( ) - > push_item ( ape . ptr ( ) ) ;
2017-10-17 16:39:31 +02:00
} else if ( t = = Variant : : DICTIONARY ) {
Variant v = obj - > get ( n ) ;
if ( v . get_type ( ) ! = t ) {
Variant : : CallError ce ;
v = Variant : : construct ( Variant : : Type ( t ) , NULL , 0 , ce ) ;
}
Ref < DictionaryPropertyEdit > dpe = memnew ( DictionaryPropertyEdit ) ;
dpe - > edit ( obj , n ) ;
EditorNode : : get_singleton ( ) - > push_item ( dpe . ptr ( ) ) ;
2014-02-10 02:10:30 +01:00
}
}
}
void PropertyEditor : : _node_removed ( Node * p_node ) {
2015-08-30 02:09:11 +02:00
2017-03-05 16:44:50 +01:00
if ( p_node = = obj ) {
2014-02-10 02:10:30 +01:00
edit ( NULL ) ;
}
}
void PropertyEditor : : set_keying ( bool p_active ) {
2017-03-05 16:44:50 +01:00
if ( keying = = p_active )
2014-02-10 02:10:30 +01:00
return ;
2017-03-05 16:44:50 +01:00
keying = p_active ;
2014-02-10 02:10:30 +01:00
update_tree ( ) ;
}
2017-08-12 18:52:50 +02:00
void PropertyEditor : : _draw_flags ( Object * p_object , const Rect2 & p_rect ) {
2014-02-10 02:10:30 +01:00
2017-08-24 22:58:51 +02:00
TreeItem * ti = Object : : cast_to < TreeItem > ( p_object ) ;
2014-02-10 02:10:30 +01:00
if ( ! ti )
return ;
Dictionary d = ti - > get_metadata ( 0 ) ;
if ( ! d . has ( " name " ) )
return ;
uint32_t f = obj - > get ( d [ " name " ] ) ;
2017-03-05 16:44:50 +01:00
int bsize = ( p_rect . size . height * 80 / 100 ) / 2 ;
2014-02-10 02:10:30 +01:00
2017-03-05 16:44:50 +01:00
int h = bsize * 2 + 1 ;
int vofs = ( p_rect . size . height - h ) / 2 ;
2014-02-10 02:10:30 +01:00
2017-03-05 16:44:50 +01:00
for ( int i = 0 ; i < 2 ; i + + ) {
2014-02-10 02:10:30 +01:00
2017-03-05 16:44:50 +01:00
Point2 ofs ( 4 , vofs ) ;
if ( i = = 1 )
ofs . y + = bsize + 1 ;
2014-02-10 02:10:30 +01:00
2017-06-04 00:25:13 +02:00
ofs + = p_rect . position ;
2017-03-05 16:44:50 +01:00
for ( int j = 0 ; j < 10 ; j + + ) {
2014-02-10 02:10:30 +01:00
2017-03-05 16:44:50 +01:00
Point2 o = ofs + Point2 ( j * ( bsize + 1 ) , 0 ) ;
if ( j > = 5 )
o . x + = 1 ;
2014-02-10 02:10:30 +01:00
2017-03-05 16:44:50 +01:00
uint32_t idx = i * 10 + j ;
bool on = f & ( 1 < < idx ) ;
tree - > draw_rect ( Rect2 ( o , Size2 ( bsize , bsize ) ) , Color ( 0 , 0 , 0 , on ? 0.8 : 0.3 ) ) ;
2014-02-10 02:10:30 +01:00
}
}
}
2017-03-05 16:44:50 +01:00
void PropertyEditor : : _filter_changed ( const String & p_text ) {
2015-11-21 17:42:15 +01:00
update_tree ( ) ;
}
2017-03-05 16:44:50 +01:00
void PropertyEditor : : _resource_preview_done ( const String & p_path , const Ref < Texture > & p_preview , Variant p_ud ) {
2016-05-27 19:18:40 +02:00
if ( p_preview . is_null ( ) )
return ; //don't bother with empty preview
ObjectID id = p_ud ;
Object * obj = ObjectDB : : get_instance ( id ) ;
if ( ! obj )
return ;
2017-08-24 22:58:51 +02:00
TreeItem * ti = Object : : cast_to < TreeItem > ( obj ) ;
2016-05-27 19:18:40 +02:00
ERR_FAIL_COND ( ! ti ) ;
2017-01-05 23:41:36 +01:00
int tw = EditorSettings : : get_singleton ( ) - > get ( " docks/property_editor/texture_preview_width " ) ;
2016-05-27 19:18:40 +02:00
2017-03-05 16:44:50 +01:00
ti - > set_icon ( 1 , p_preview ) ; //should be scaled I think?
ti - > set_icon_max_width ( 1 , tw ) ;
ti - > set_text ( 1 , " " ) ;
2016-05-27 19:18:40 +02:00
}
2014-02-10 02:10:30 +01:00
void PropertyEditor : : _bind_methods ( ) {
2017-03-05 16:44:50 +01:00
ClassDB : : bind_method ( " _item_edited " , & PropertyEditor : : _item_edited ) ;
ClassDB : : bind_method ( " _item_selected " , & PropertyEditor : : _item_selected ) ;
2017-08-10 21:02:19 +02:00
ClassDB : : bind_method ( " _item_rmb_edited " , & PropertyEditor : : _item_rmb_edited ) ;
2017-06-25 22:30:28 +02:00
ClassDB : : bind_method ( " _item_folded " , & PropertyEditor : : _item_folded ) ;
2017-03-05 16:44:50 +01:00
ClassDB : : bind_method ( " _custom_editor_request " , & PropertyEditor : : _custom_editor_request ) ;
ClassDB : : bind_method ( " _custom_editor_edited " , & PropertyEditor : : _custom_editor_edited ) ;
ClassDB : : bind_method ( " _custom_editor_edited_field " , & PropertyEditor : : _custom_editor_edited_field , DEFVAL ( " " ) ) ;
ClassDB : : bind_method ( " _resource_edit_request " , & PropertyEditor : : _resource_edit_request ) ;
ClassDB : : bind_method ( " _node_removed " , & PropertyEditor : : _node_removed ) ;
ClassDB : : bind_method ( " _edit_button " , & PropertyEditor : : _edit_button ) ;
ClassDB : : bind_method ( " _changed_callback " , & PropertyEditor : : _changed_callbacks ) ;
ClassDB : : bind_method ( " _draw_flags " , & PropertyEditor : : _draw_flags ) ;
ClassDB : : bind_method ( " _set_range_def " , & PropertyEditor : : _set_range_def ) ;
ClassDB : : bind_method ( " _filter_changed " , & PropertyEditor : : _filter_changed ) ;
ClassDB : : bind_method ( " update_tree " , & PropertyEditor : : update_tree ) ;
ClassDB : : bind_method ( " _resource_preview_done " , & PropertyEditor : : _resource_preview_done ) ;
ClassDB : : bind_method ( " refresh " , & PropertyEditor : : refresh ) ;
ClassDB : : bind_method ( " _draw_transparency " , & PropertyEditor : : _draw_transparency ) ;
2018-01-04 19:55:43 +01:00
ClassDB : : bind_method ( " edit " , & PropertyEditor : : edit ) ;
2017-01-03 03:03:46 +01:00
2017-02-13 12:47:24 +01:00
ClassDB : : bind_method ( D_METHOD ( " get_drag_data_fw " ) , & PropertyEditor : : get_drag_data_fw ) ;
ClassDB : : bind_method ( D_METHOD ( " can_drop_data_fw " ) , & PropertyEditor : : can_drop_data_fw ) ;
ClassDB : : bind_method ( D_METHOD ( " drop_data_fw " ) , & PropertyEditor : : drop_data_fw ) ;
2016-05-11 16:46:08 +02:00
2017-03-05 16:44:50 +01:00
ADD_SIGNAL ( MethodInfo ( " property_toggled " , PropertyInfo ( Variant : : STRING , " property " ) , PropertyInfo ( Variant : : BOOL , " value " ) ) ) ;
ADD_SIGNAL ( MethodInfo ( " resource_selected " , PropertyInfo ( Variant : : OBJECT , " res " ) , PropertyInfo ( Variant : : STRING , " prop " ) ) ) ;
ADD_SIGNAL ( MethodInfo ( " object_id_selected " , PropertyInfo ( Variant : : INT , " id " ) ) ) ;
ADD_SIGNAL ( MethodInfo ( " property_keyed " , PropertyInfo ( Variant : : STRING , " property " ) ) ) ;
ADD_SIGNAL ( MethodInfo ( " property_edited " , PropertyInfo ( Variant : : STRING , " property " ) ) ) ;
2014-02-10 02:10:30 +01:00
}
2018-05-15 22:12:35 +02:00
Tree * PropertyEditor : : get_property_tree ( ) {
2014-02-10 02:10:30 +01:00
return tree ;
}
2017-03-05 16:44:50 +01:00
Label * PropertyEditor : : get_top_label ( ) {
2014-02-10 02:10:30 +01:00
return top_label ;
}
void PropertyEditor : : hide_top_label ( ) {
top_label - > hide ( ) ;
2017-03-05 16:44:50 +01:00
tree - > set_begin ( Point2 ( 0 , 0 ) ) ;
2014-02-10 02:10:30 +01:00
}
String PropertyEditor : : get_selected_path ( ) const {
TreeItem * ti = tree - > get_selected ( ) ;
if ( ! ti )
return " " ;
Dictionary d = ti - > get_metadata ( 0 ) ;
if ( d . has ( " name " ) )
return d [ " name " ] ;
else
return " " ;
}
2017-04-26 13:41:41 +02:00
bool PropertyEditor : : is_capitalize_paths_enabled ( ) const {
return capitalize_paths ;
}
void PropertyEditor : : set_enable_capitalize_paths ( bool p_capitalize ) {
2014-02-10 02:10:30 +01:00
2017-03-05 16:44:50 +01:00
capitalize_paths = p_capitalize ;
2017-04-26 13:41:41 +02:00
update_tree_pending = true ;
2014-02-10 02:10:30 +01:00
}
void PropertyEditor : : set_autoclear ( bool p_enable ) {
2017-03-05 16:44:50 +01:00
autoclear = p_enable ;
2014-02-10 02:10:30 +01:00
}
void PropertyEditor : : set_show_categories ( bool p_show ) {
2017-03-05 16:44:50 +01:00
show_categories = p_show ;
2014-02-10 02:10:30 +01:00
update_tree ( ) ;
}
2015-11-21 17:42:15 +01:00
void PropertyEditor : : set_use_filter ( bool p_use ) {
2017-03-05 16:44:50 +01:00
if ( p_use = = use_filter )
2015-11-21 17:42:15 +01:00
return ;
2017-03-05 16:44:50 +01:00
use_filter = p_use ;
2015-11-21 17:42:15 +01:00
update_tree ( ) ;
}
2017-03-05 16:44:50 +01:00
void PropertyEditor : : register_text_enter ( Node * p_line_edit ) {
2015-11-21 17:42:15 +01:00
ERR_FAIL_NULL ( p_line_edit ) ;
2017-08-24 22:58:51 +02:00
search_box = Object : : cast_to < LineEdit > ( p_line_edit ) ;
2015-11-21 17:42:15 +01:00
if ( search_box )
2017-03-05 16:44:50 +01:00
search_box - > connect ( " text_changed " , this , " _filter_changed " ) ;
2015-12-03 18:59:59 +01:00
}
2015-11-21 17:42:15 +01:00
2017-07-19 22:00:46 +02:00
void PropertyEditor : : set_property_selectable ( bool p_selectable ) {
property_selectable = p_selectable ;
update_tree ( ) ;
}
2015-12-03 18:59:59 +01:00
void PropertyEditor : : set_subsection_selectable ( bool p_selectable ) {
2017-03-05 16:44:50 +01:00
if ( p_selectable = = subsection_selectable )
2015-12-03 18:59:59 +01:00
return ;
2017-03-05 16:44:50 +01:00
subsection_selectable = p_selectable ;
2015-12-03 18:59:59 +01:00
update_tree ( ) ;
2015-11-21 17:42:15 +01:00
}
2017-06-25 22:30:28 +02:00
void PropertyEditor : : set_use_folding ( bool p_enable ) {
use_folding = p_enable ;
tree - > set_hide_folding ( false ) ;
}
2017-12-06 23:06:18 +01:00
void PropertyEditor : : collapse_all_folding ( ) {
if ( ! obj )
return ;
for ( List < String > : : Element * E = foldable_property_cache . front ( ) ; E ; E = E - > next ( ) ) {
obj - > editor_set_section_unfold ( E - > get ( ) , false ) ;
}
2017-11-24 07:09:51 +01:00
update_tree ( ) ;
}
2017-12-06 23:06:18 +01:00
void PropertyEditor : : expand_all_folding ( ) {
2017-11-24 07:09:51 +01:00
2017-12-06 23:06:18 +01:00
if ( ! obj )
return ;
for ( List < String > : : Element * E = foldable_property_cache . front ( ) ; E ; E = E - > next ( ) ) {
obj - > editor_set_section_unfold ( E - > get ( ) , true ) ;
}
2017-11-24 07:09:51 +01:00
update_tree ( ) ;
}
2014-02-10 02:10:30 +01:00
PropertyEditor : : PropertyEditor ( ) {
2015-08-30 02:09:11 +02:00
2017-03-05 16:44:50 +01:00
_prop_edited = " property_edited " ;
2017-01-05 13:16:00 +01:00
2017-07-18 02:05:38 +02:00
hide_script = true ;
2017-06-25 22:30:28 +02:00
use_folding = false ;
2017-02-01 13:45:45 +01:00
2017-03-05 16:44:50 +01:00
undo_redo = NULL ;
obj = NULL ;
search_box = NULL ;
changing = false ;
update_tree_pending = false ;
2015-08-30 02:09:11 +02:00
2017-03-05 16:44:50 +01:00
top_label = memnew ( Label ) ;
2016-05-04 03:25:37 +02:00
top_label - > set_text ( TTR ( " Properties: " ) ) ;
2017-03-05 16:44:50 +01:00
top_label - > set_anchor ( MARGIN_RIGHT , ANCHOR_END ) ;
top_label - > set_begin ( Point2 ( 10 , 0 ) ) ;
top_label - > set_end ( Point2 ( 0 , 12 ) ) ;
2015-08-30 02:09:11 +02:00
add_child ( top_label ) ;
2017-03-05 16:44:50 +01:00
tree = memnew ( Tree ) ;
tree - > set_anchor ( MARGIN_RIGHT , ANCHOR_END ) ;
tree - > set_anchor ( MARGIN_BOTTOM , ANCHOR_END ) ;
tree - > set_begin ( Point2 ( 0 , 19 ) ) ;
tree - > set_end ( Point2 ( 0 , 0 ) ) ;
2015-08-30 02:09:11 +02:00
2014-02-10 02:10:30 +01:00
tree - > set_columns ( 2 ) ;
2017-03-05 16:44:50 +01:00
tree - > set_column_expand ( 0 , true ) ;
tree - > set_column_min_width ( 0 , 30 ) ;
tree - > set_column_expand ( 1 , true ) ;
tree - > set_column_min_width ( 1 , 18 ) ;
add_child ( tree ) ;
2015-08-30 02:09:11 +02:00
2017-03-05 16:44:50 +01:00
tree - > connect ( " item_edited " , this , " _item_edited " , varray ( ) , CONNECT_DEFERRED ) ;
2017-08-10 21:02:19 +02:00
tree - > connect ( " item_rmb_edited " , this , " _item_rmb_edited " ) ;
2017-03-05 16:44:50 +01:00
tree - > connect ( " cell_selected " , this , " _item_selected " ) ;
2017-06-25 22:30:28 +02:00
tree - > connect ( " item_collapsed " , this , " _item_folded " ) ;
2015-08-30 02:09:11 +02:00
2016-05-11 16:46:08 +02:00
tree - > set_drag_forwarding ( this ) ;
2017-09-30 16:19:07 +02:00
set_physics_process ( true ) ;
2015-08-30 02:09:11 +02:00
2017-03-05 16:44:50 +01:00
custom_editor = memnew ( CustomPropertyEditor ) ;
2017-11-22 09:43:40 +01:00
custom_editor - > set_pass_on_modal_close_click ( false ) ;
2014-02-10 02:10:30 +01:00
add_child ( custom_editor ) ;
2015-08-30 02:09:11 +02:00
2017-03-05 16:44:50 +01:00
tree - > connect ( " custom_popup_edited " , this , " _custom_editor_request " ) ;
tree - > connect ( " button_pressed " , this , " _edit_button " ) ;
custom_editor - > connect ( " variant_changed " , this , " _custom_editor_edited " ) ;
custom_editor - > connect ( " variant_field_changed " , this , " _custom_editor_edited_field " ) ;
custom_editor - > connect ( " resource_edit_request " , this , " _resource_edit_request " , make_binds ( ) , CONNECT_DEFERRED ) ;
2015-11-14 00:56:44 +01:00
tree - > set_hide_folding ( true ) ;
2015-08-30 02:09:11 +02:00
2017-03-05 16:44:50 +01:00
evaluator = memnew ( PropertyValueEvaluator ) ;
2016-05-01 10:33:32 +02:00
tree - > set_value_evaluator ( evaluator ) ;
custom_editor - > set_value_evaluator ( evaluator ) ;
2017-03-05 16:44:50 +01:00
capitalize_paths = true ;
autoclear = false ;
2015-02-28 09:28:26 +01:00
tree - > set_column_titles_visible ( false ) ;
2017-04-13 17:03:54 +02:00
tree - > add_constant_override ( " button_margin " , 0 ) ;
2014-02-10 02:10:30 +01:00
2017-03-05 16:44:50 +01:00
keying = false ;
read_only = false ;
show_categories = false ;
refresh_countdown = 0 ;
use_doc_hints = false ;
2017-06-25 22:30:28 +02:00
updating_folding = true ;
2017-03-05 16:44:50 +01:00
use_filter = false ;
subsection_selectable = false ;
2017-07-19 22:00:46 +02:00
property_selectable = false ;
2017-12-18 15:14:27 +01:00
show_type_icons = EDITOR_DEF ( " interface/editor/show_type_icons " , false ) ;
2014-02-10 02:10:30 +01:00
}
2017-03-05 16:44:50 +01:00
PropertyEditor : : ~ PropertyEditor ( ) {
2016-05-01 10:33:32 +02:00
memdelete ( evaluator ) ;
2014-02-10 02:10:30 +01:00
}
2015-12-16 03:39:36 +01:00
/////////////////////////////
class SectionedPropertyEditorFilter : public Object {
2017-03-05 16:44:50 +01:00
GDCLASS ( SectionedPropertyEditorFilter , Object ) ;
2015-12-16 03:39:36 +01:00
Object * edited ;
String section ;
2017-01-05 13:16:00 +01:00
bool allow_sub ;
2015-12-16 03:39:36 +01:00
2017-03-05 16:44:50 +01:00
bool _set ( const StringName & p_name , const Variant & p_value ) {
2015-12-16 03:39:36 +01:00
if ( ! edited )
return false ;
2017-03-05 16:44:50 +01:00
String name = p_name ;
if ( section ! = " " ) {
name = section + " / " + name ;
2015-12-16 03:39:36 +01:00
}
bool valid ;
2017-03-05 16:44:50 +01:00
edited - > set ( name , p_value , & valid ) ;
2015-12-16 03:39:36 +01:00
return valid ;
}
2017-03-05 16:44:50 +01:00
bool _get ( const StringName & p_name , Variant & r_ret ) const {
2015-12-16 03:39:36 +01:00
if ( ! edited )
return false ;
2017-03-05 16:44:50 +01:00
String name = p_name ;
if ( section ! = " " ) {
name = section + " / " + name ;
2015-12-16 03:39:36 +01:00
}
2017-03-05 16:44:50 +01:00
bool valid = false ;
2015-12-16 03:39:36 +01:00
2017-03-05 16:44:50 +01:00
r_ret = edited - > get ( name , & valid ) ;
2015-12-16 03:39:36 +01:00
return valid ;
}
2017-03-05 16:44:50 +01:00
void _get_property_list ( List < PropertyInfo > * p_list ) const {
2015-12-16 03:39:36 +01:00
if ( ! edited )
return ;
List < PropertyInfo > pinfo ;
edited - > get_property_list ( & pinfo ) ;
2017-03-05 16:44:50 +01:00
for ( List < PropertyInfo > : : Element * E = pinfo . front ( ) ; E ; E = E - > next ( ) ) {
2015-12-16 03:39:36 +01:00
2017-03-05 16:44:50 +01:00
PropertyInfo pi = E - > get ( ) ;
2015-12-16 03:39:36 +01:00
int sp = pi . name . find ( " / " ) ;
2017-12-09 23:46:38 +01:00
if ( pi . name = = " resource_path " | | pi . name = = " resource_name " | | pi . name = = " resource_local_to_scene " | | pi . name . begins_with ( " script/ " ) ) //skip resource stuff
2017-01-05 23:41:36 +01:00
continue ;
2017-03-05 16:44:50 +01:00
if ( sp = = - 1 ) {
2017-07-09 08:26:10 +02:00
pi . name = " global/ " + pi . name ;
2017-01-05 13:16:00 +01:00
}
2017-03-05 16:44:50 +01:00
if ( pi . name . begins_with ( section + " / " ) ) {
pi . name = pi . name . replace_first ( section + " / " , " " ) ;
if ( ! allow_sub & & pi . name . find ( " / " ) ! = - 1 )
2017-01-05 13:16:00 +01:00
continue ;
p_list - > push_back ( pi ) ;
2015-12-16 03:39:36 +01:00
}
}
}
2017-01-05 13:16:00 +01:00
2017-03-05 16:44:50 +01:00
bool property_can_revert ( const String & p_name ) {
2017-01-05 13:16:00 +01:00
2017-03-05 16:44:50 +01:00
return edited - > call ( " property_can_revert " , section + " / " + p_name ) ;
2017-01-05 13:16:00 +01:00
}
2017-03-05 16:44:50 +01:00
Variant property_get_revert ( const String & p_name ) {
2017-01-05 13:16:00 +01:00
2017-03-05 16:44:50 +01:00
return edited - > call ( " property_get_revert " , section + " / " + p_name ) ;
2017-01-05 13:16:00 +01:00
}
protected :
static void _bind_methods ( ) {
2017-03-05 16:44:50 +01:00
ClassDB : : bind_method ( " property_can_revert " , & SectionedPropertyEditorFilter : : property_can_revert ) ;
ClassDB : : bind_method ( " property_get_revert " , & SectionedPropertyEditorFilter : : property_get_revert ) ;
2017-01-05 13:16:00 +01:00
}
2015-12-16 03:39:36 +01:00
public :
2017-03-05 16:44:50 +01:00
void set_section ( const String & p_section , bool p_allow_sub ) {
2015-12-16 03:39:36 +01:00
2017-03-05 16:44:50 +01:00
section = p_section ;
allow_sub = p_allow_sub ;
2015-12-16 03:39:36 +01:00
_change_notify ( ) ;
}
2017-03-05 16:44:50 +01:00
void set_edited ( Object * p_edited ) {
edited = p_edited ;
2015-12-16 03:39:36 +01:00
_change_notify ( ) ;
}
SectionedPropertyEditorFilter ( ) {
2017-03-05 16:44:50 +01:00
edited = NULL ;
2015-12-16 03:39:36 +01:00
}
} ;
void SectionedPropertyEditor : : _bind_methods ( ) {
2017-03-05 16:44:50 +01:00
ClassDB : : bind_method ( " _section_selected " , & SectionedPropertyEditor : : _section_selected ) ;
2017-07-18 02:05:38 +02:00
ClassDB : : bind_method ( " _search_changed " , & SectionedPropertyEditor : : _search_changed ) ;
2016-07-07 15:10:12 +02:00
2017-01-03 03:03:46 +01:00
ClassDB : : bind_method ( " update_category_list " , & SectionedPropertyEditor : : update_category_list ) ;
2015-12-16 03:39:36 +01:00
}
2017-01-05 13:16:00 +01:00
void SectionedPropertyEditor : : _section_selected ( ) {
if ( ! sections - > get_selected ( ) )
return ;
2015-12-16 03:39:36 +01:00
2017-03-05 16:44:50 +01:00
filter - > set_section ( sections - > get_selected ( ) - > get_metadata ( 0 ) , sections - > get_selected ( ) - > get_children ( ) = = NULL ) ;
2015-12-16 03:39:36 +01:00
}
2017-03-05 16:44:50 +01:00
void SectionedPropertyEditor : : set_current_section ( const String & p_section ) {
2016-03-06 15:22:21 +01:00
2017-01-05 13:16:00 +01:00
if ( section_map . has ( p_section ) ) {
2017-01-14 18:03:38 +01:00
section_map [ p_section ] - > select ( 0 ) ;
2016-03-06 15:22:21 +01:00
}
}
2016-01-10 21:08:02 +01:00
String SectionedPropertyEditor : : get_current_section ( ) const {
2017-01-05 13:16:00 +01:00
if ( sections - > get_selected ( ) )
return sections - > get_selected ( ) - > get_metadata ( 0 ) ;
2016-03-06 15:22:21 +01:00
else
return " " ;
2016-01-10 21:08:02 +01:00
}
2017-03-05 16:44:50 +01:00
String SectionedPropertyEditor : : get_full_item_path ( const String & p_item ) {
2015-12-16 04:42:34 +01:00
2016-03-06 15:22:21 +01:00
String base = get_current_section ( ) ;
2017-03-05 16:44:50 +01:00
if ( base ! = " " )
return base + " / " + p_item ;
2015-12-16 04:42:34 +01:00
else
return p_item ;
}
2017-03-05 16:44:50 +01:00
void SectionedPropertyEditor : : edit ( Object * p_object ) {
2015-12-16 03:39:36 +01:00
2016-07-19 00:21:20 +02:00
if ( ! p_object ) {
obj = - 1 ;
2016-03-06 15:22:21 +01:00
sections - > clear ( ) ;
2016-07-19 00:21:20 +02:00
filter - > set_edited ( NULL ) ;
editor - > edit ( NULL ) ;
return ;
2016-03-06 15:22:21 +01:00
}
2017-08-07 12:17:31 +02:00
ObjectID id = p_object - > get_instance_id ( ) ;
2016-07-19 00:21:20 +02:00
if ( obj ! = id ) {
obj = id ;
update_category_list ( ) ;
2016-03-06 15:22:21 +01:00
2016-07-19 00:21:20 +02:00
filter - > set_edited ( p_object ) ;
editor - > edit ( filter ) ;
2016-03-06 15:22:21 +01:00
2017-01-05 13:16:00 +01:00
if ( sections - > get_root ( ) - > get_children ( ) ) {
sections - > get_root ( ) - > get_children ( ) - > select ( 0 ) ;
}
2016-07-19 00:21:20 +02:00
} else {
update_category_list ( ) ;
}
2016-03-06 15:22:21 +01:00
}
void SectionedPropertyEditor : : update_category_list ( ) {
2017-03-05 16:44:50 +01:00
String selected_category = get_current_section ( ) ;
2015-12-16 03:39:36 +01:00
sections - > clear ( ) ;
2016-03-06 15:22:21 +01:00
Object * o = ObjectDB : : get_instance ( obj ) ;
if ( ! o )
return ;
List < PropertyInfo > pinfo ;
o - > get_property_list ( & pinfo ) ;
2017-01-05 13:16:00 +01:00
section_map . clear ( ) ;
TreeItem * root = sections - > create_item ( ) ;
2017-03-05 16:44:50 +01:00
section_map [ " " ] = root ;
2017-01-05 13:16:00 +01:00
2017-03-05 16:44:50 +01:00
for ( List < PropertyInfo > : : Element * E = pinfo . front ( ) ; E ; E = E - > next ( ) ) {
2017-01-05 13:16:00 +01:00
2017-03-05 16:44:50 +01:00
PropertyInfo pi = E - > get ( ) ;
2015-12-16 03:39:36 +01:00
2017-03-05 16:44:50 +01:00
if ( pi . usage & PROPERTY_USAGE_CATEGORY )
2015-12-16 03:39:36 +01:00
continue ;
2017-03-05 16:44:50 +01:00
else if ( ! ( pi . usage & PROPERTY_USAGE_EDITOR ) )
2016-03-06 15:22:21 +01:00
continue ;
2017-12-09 23:46:38 +01:00
if ( pi . name . find ( " : " ) ! = - 1 | | pi . name = = " script " | | pi . name = = " resource_name " | | pi . name = = " resource_path " | | pi . name = = " resource_local_to_scene " )
2015-12-16 03:39:36 +01:00
continue ;
2017-07-18 02:05:38 +02:00
if ( search_box & & search_box - > get_text ( ) ! = String ( ) & & pi . name . findn ( search_box - > get_text ( ) ) = = - 1 )
continue ;
2015-12-16 03:39:36 +01:00
int sp = pi . name . find ( " / " ) ;
2017-03-05 16:44:50 +01:00
if ( sp = = - 1 )
pi . name = " Global/ " + pi . name ;
2017-01-05 13:16:00 +01:00
Vector < String > sectionarr = pi . name . split ( " / " ) ;
String metasection ;
2017-07-18 02:05:38 +02:00
int sc = MIN ( 2 , sectionarr . size ( ) - 1 ) ;
for ( int i = 0 ; i < sc ; i + + ) {
2017-01-05 13:16:00 +01:00
TreeItem * parent = section_map [ metasection ] ;
2017-12-11 12:59:33 +01:00
parent - > set_custom_bg_color ( 0 , get_color ( " prop_subsection " , " Editor " ) ) ;
2017-01-05 13:16:00 +01:00
2017-03-05 16:44:50 +01:00
if ( i > 0 ) {
metasection + = " / " + sectionarr [ i ] ;
2017-01-05 13:16:00 +01:00
} else {
2017-03-05 16:44:50 +01:00
metasection = sectionarr [ i ] ;
2015-12-16 03:39:36 +01:00
}
2017-01-05 13:16:00 +01:00
if ( ! section_map . has ( metasection ) ) {
TreeItem * ms = sections - > create_item ( parent ) ;
2017-03-05 16:44:50 +01:00
section_map [ metasection ] = ms ;
ms - > set_text ( 0 , sectionarr [ i ] . capitalize ( ) ) ;
ms - > set_metadata ( 0 , metasection ) ;
2017-07-18 02:05:38 +02:00
ms - > set_selectable ( 0 , false ) ;
}
if ( i = = sc - 1 ) {
//if it has children, make selectable
section_map [ metasection ] - > set_selectable ( 0 , true ) ;
2015-12-16 03:39:36 +01:00
}
}
}
2017-01-05 13:16:00 +01:00
if ( section_map . has ( selected_category ) ) {
section_map [ selected_category ] - > select ( 0 ) ;
}
2017-07-19 22:00:46 +02:00
editor - > update_tree ( ) ;
2015-12-16 03:39:36 +01:00
}
2017-07-18 02:05:38 +02:00
void SectionedPropertyEditor : : register_search_box ( LineEdit * p_box ) {
search_box = p_box ;
editor - > register_text_enter ( p_box ) ;
search_box - > connect ( " text_changed " , this , " _search_changed " ) ;
}
void SectionedPropertyEditor : : _search_changed ( const String & p_what ) {
update_category_list ( ) ;
}
2015-12-16 03:39:36 +01:00
PropertyEditor * SectionedPropertyEditor : : get_property_editor ( ) {
return editor ;
}
SectionedPropertyEditor : : SectionedPropertyEditor ( ) {
2016-07-19 00:21:20 +02:00
obj = - 1 ;
2017-07-18 02:05:38 +02:00
search_box = NULL ;
2017-12-21 16:00:25 +01:00
add_constant_override ( " autohide " , 1 ) ; // Fixes the dragger always showing up
2017-03-05 16:44:50 +01:00
VBoxContainer * left_vb = memnew ( VBoxContainer ) ;
2017-12-11 12:59:33 +01:00
left_vb - > set_custom_minimum_size ( Size2 ( 170 , 0 ) * EDSCALE ) ;
2015-12-16 04:08:50 +01:00
add_child ( left_vb ) ;
2017-03-05 16:44:50 +01:00
sections = memnew ( Tree ) ;
2015-12-16 04:08:50 +01:00
sections - > set_v_size_flags ( SIZE_EXPAND_FILL ) ;
2017-01-05 13:16:00 +01:00
sections - > set_hide_root ( true ) ;
2015-12-16 04:08:50 +01:00
2017-12-17 18:22:26 +01:00
left_vb - > add_child ( sections , true ) ;
2015-12-16 04:08:50 +01:00
2017-03-05 16:44:50 +01:00
VBoxContainer * right_vb = memnew ( VBoxContainer ) ;
2017-12-21 16:00:25 +01:00
right_vb - > set_custom_minimum_size ( Size2 ( 300 , 0 ) * EDSCALE ) ;
2015-12-16 04:08:50 +01:00
right_vb - > set_h_size_flags ( SIZE_EXPAND_FILL ) ;
add_child ( right_vb ) ;
2017-03-05 16:44:50 +01:00
filter = memnew ( SectionedPropertyEditorFilter ) ;
editor = memnew ( PropertyEditor ) ;
2015-12-16 04:08:50 +01:00
editor - > set_v_size_flags ( SIZE_EXPAND_FILL ) ;
2017-12-17 18:22:26 +01:00
right_vb - > add_child ( editor , true ) ;
2015-12-16 04:08:50 +01:00
2018-05-15 22:12:35 +02:00
editor - > get_property_tree ( ) - > set_column_titles_visible ( false ) ;
2016-01-23 23:51:51 +01:00
2015-12-16 03:39:36 +01:00
editor - > hide_top_label ( ) ;
2017-03-05 16:44:50 +01:00
sections - > connect ( " cell_selected " , this , " _section_selected " ) ;
2015-12-16 03:39:36 +01:00
}
SectionedPropertyEditor : : ~ SectionedPropertyEditor ( ) {
memdelete ( filter ) ;
}
2016-05-01 10:33:32 +02:00
2017-03-05 16:44:50 +01:00
double PropertyValueEvaluator : : eval ( const String & p_text ) {
2016-05-01 10:33:32 +02:00
2017-11-24 11:44:36 +01:00
// If range value contains a comma replace it with dot (issue #6028)
const String & p_new_text = p_text . replace ( " , " , " . " ) ;
2016-08-03 00:11:05 +02:00
if ( ! obj | | ! script_language )
2017-11-24 11:44:36 +01:00
return _default_eval ( p_new_text ) ;
2016-05-01 10:33:32 +02:00
2017-03-05 16:44:50 +01:00
Ref < Script > script = Ref < Script > ( script_language - > create_script ( ) ) ;
2017-11-24 11:44:36 +01:00
script - > set_source_code ( _build_script ( p_new_text ) ) ;
2016-05-01 10:33:32 +02:00
Error err = script - > reload ( ) ;
if ( err ) {
2017-11-24 11:44:36 +01:00
print_line ( " [PropertyValueEvaluator] Error loading script for expression: " + p_new_text ) ;
return _default_eval ( p_new_text ) ;
2016-05-01 10:33:32 +02:00
}
2017-08-17 02:17:18 +02:00
Object dummy ;
ScriptInstance * script_instance = script - > instance_create ( & dummy ) ;
2016-08-03 00:11:05 +02:00
if ( ! script_instance )
2017-11-24 11:44:36 +01:00
return _default_eval ( p_new_text ) ;
2016-05-01 10:33:32 +02:00
Variant : : CallError call_err ;
2017-08-17 02:17:18 +02:00
Variant arg = obj ;
const Variant * args [ ] = { & arg } ;
double result = script_instance - > call ( " eval " , args , 1 , call_err ) ;
2016-05-01 10:33:32 +02:00
if ( call_err . error = = Variant : : CallError : : CALL_OK ) {
return result ;
}
print_line ( " [PropertyValueEvaluator]: Error eval! Error code: " + itos ( call_err . error ) ) ;
2017-11-24 11:44:36 +01:00
return _default_eval ( p_new_text ) ;
2016-05-01 10:33:32 +02:00
}
void PropertyValueEvaluator : : edit ( Object * p_obj ) {
obj = p_obj ;
}
2017-03-05 16:44:50 +01:00
String PropertyValueEvaluator : : _build_script ( const String & p_text ) {
2017-08-26 17:46:49 +02:00
String script_text = " tool \n extends Object \n func eval(s): \n \t self = s \n \t return " + p_text . strip_edges ( ) + " \n " ;
2016-05-01 10:33:32 +02:00
return script_text ;
}
PropertyValueEvaluator : : PropertyValueEvaluator ( ) {
2017-03-05 16:44:50 +01:00
script_language = NULL ;
2016-08-03 00:11:05 +02:00
2017-03-05 16:44:50 +01:00
for ( int i = 0 ; i < ScriptServer : : get_language_count ( ) ; i + + ) {
if ( ScriptServer : : get_language ( i ) - > get_name ( ) = = " GDScript " ) {
script_language = ScriptServer : : get_language ( i ) ;
2016-08-03 00:11:05 +02:00
}
}
2016-05-01 10:33:32 +02:00
}
PropertyValueEvaluator : : ~ PropertyValueEvaluator ( ) {
}