2018-08-29 22:38:13 +02:00
/**************************************************************************/
/* animation_blend_space_2d_editor.cpp */
/**************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
/* https://godotengine.org */
/**************************************************************************/
/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
/* "Software"), to deal in the Software without restriction, including */
/* without limitation the rights to use, copy, modify, merge, publish, */
/* distribute, sublicense, and/or sell copies of the Software, and to */
/* permit persons to whom the Software is furnished to do so, subject to */
/* the following conditions: */
/* */
/* The above copyright notice and this permission notice shall be */
/* included in all copies or substantial portions of the Software. */
/* */
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/**************************************************************************/
2018-06-22 21:52:13 +02:00
# include "animation_blend_space_2d_editor.h"
2018-06-21 15:45:44 -03:00
# include "core/io/resource_loader.h"
2020-05-25 20:20:45 +03:00
# include "core/math/geometry_2d.h"
2018-09-11 18:13:45 +02:00
# include "core/os/keyboard.h"
2022-02-12 02:46:22 +01:00
# include "editor/editor_node.h"
2023-08-13 02:33:39 +02:00
# include "editor/editor_string_names.h"
2022-03-25 18:06:46 +01:00
# include "editor/editor_undo_redo_manager.h"
2023-04-07 18:59:49 +02:00
# include "editor/gui/editor_file_dialog.h"
2025-06-10 16:47:26 +02:00
# include "editor/settings/editor_settings.h"
2024-01-15 13:14:55 +01:00
# include "editor/themes/editor_scale.h"
2018-06-21 15:45:44 -03:00
# include "scene/animation/animation_blend_tree.h"
# include "scene/animation/animation_player.h"
2023-10-02 13:43:08 +02:00
# include "scene/gui/button.h"
2022-11-19 12:45:49 +01:00
# include "scene/gui/check_box.h"
2022-11-11 20:12:48 +01:00
# include "scene/gui/grid_container.h"
2023-10-02 13:43:08 +02:00
# include "scene/gui/line_edit.h"
2018-06-21 15:45:44 -03:00
# include "scene/gui/menu_button.h"
2022-11-19 12:45:49 +01:00
# include "scene/gui/option_button.h"
2018-06-21 15:45:44 -03:00
# include "scene/gui/panel.h"
2022-11-19 12:45:49 +01:00
# include "scene/gui/panel_container.h"
2023-10-02 13:43:08 +02:00
# include "scene/gui/separator.h"
# include "scene/gui/spin_box.h"
2020-03-03 22:51:12 -03:00
# include "scene/main/window.h"
2018-06-21 15:45:44 -03:00
2018-08-20 13:38:18 -03:00
bool AnimationNodeBlendSpace2DEditor : : can_edit ( const Ref < AnimationNode > & p_node ) {
2018-08-21 21:28:06 +02:00
Ref < AnimationNodeBlendSpace2D > bs2d = p_node ;
2018-08-20 13:38:18 -03:00
return bs2d . is_valid ( ) ;
}
2018-06-21 15:45:44 -03:00
2019-01-10 21:40:46 -03:00
void AnimationNodeBlendSpace2DEditor : : _blend_space_changed ( ) {
2022-08-13 23:21:24 +02:00
blend_space_draw - > queue_redraw ( ) ;
2019-01-10 21:40:46 -03:00
}
2018-08-20 13:38:18 -03:00
void AnimationNodeBlendSpace2DEditor : : edit ( const Ref < AnimationNode > & p_node ) {
2019-01-10 21:40:46 -03:00
if ( blend_space . is_valid ( ) ) {
2020-02-21 18:28:45 +01:00
blend_space - > disconnect ( " triangles_updated " , callable_mp ( this , & AnimationNodeBlendSpace2DEditor : : _blend_space_changed ) ) ;
2019-01-10 21:40:46 -03:00
}
2018-08-20 13:38:18 -03:00
blend_space = p_node ;
2022-05-04 06:31:53 +01:00
read_only = false ;
2018-06-21 18:08:11 -03:00
2024-08-25 14:15:10 +02:00
if ( blend_space . is_valid ( ) ) {
2022-05-04 06:31:53 +01:00
read_only = EditorNode : : get_singleton ( ) - > is_resource_read_only ( blend_space ) ;
2020-02-21 18:28:45 +01:00
blend_space - > connect ( " triangles_updated " , callable_mp ( this , & AnimationNodeBlendSpace2DEditor : : _blend_space_changed ) ) ;
2018-06-21 15:45:44 -03:00
_update_space ( ) ;
}
2022-05-04 06:31:53 +01:00
tool_create - > set_disabled ( read_only ) ;
max_x_value - > set_editable ( ! read_only ) ;
min_x_value - > set_editable ( ! read_only ) ;
max_y_value - > set_editable ( ! read_only ) ;
min_y_value - > set_editable ( ! read_only ) ;
label_x - > set_editable ( ! read_only ) ;
label_y - > set_editable ( ! read_only ) ;
edit_x - > set_editable ( ! read_only ) ;
edit_y - > set_editable ( ! read_only ) ;
tool_triangle - > set_disabled ( read_only ) ;
auto_triangles - > set_disabled ( read_only ) ;
sync - > set_disabled ( read_only ) ;
interpolation - > set_disabled ( read_only ) ;
2018-06-21 15:45:44 -03:00
}
2018-08-20 13:38:18 -03:00
StringName AnimationNodeBlendSpace2DEditor : : get_blend_position_path ( ) const {
2018-08-21 21:28:06 +02:00
StringName path = AnimationTreeEditor : : get_singleton ( ) - > get_base_path ( ) + " blend_position " ;
2018-08-20 13:38:18 -03:00
return path ;
}
2018-06-22 15:17:54 +02:00
void AnimationNodeBlendSpace2DEditor : : _blend_space_gui_input ( const Ref < InputEvent > & p_event ) {
2022-12-13 03:00:11 +09:00
AnimationTree * tree = AnimationTreeEditor : : get_singleton ( ) - > get_animation_tree ( ) ;
if ( ! tree ) {
return ;
}
2018-06-21 18:08:11 -03:00
Ref < InputEventKey > k = p_event ;
2021-08-13 16:31:57 -05:00
if ( tool_select - > is_pressed ( ) & & k . is_valid ( ) & & k - > is_pressed ( ) & & k - > get_keycode ( ) = = Key : : KEY_DELETE & & ! k - > is_echo ( ) ) {
2018-06-21 18:08:11 -03:00
if ( selected_point ! = - 1 | | selected_triangle ! = - 1 ) {
2022-05-04 06:31:53 +01:00
if ( ! read_only ) {
_erase_selected ( ) ;
}
2018-06-21 18:08:11 -03:00
accept_event ( ) ;
}
}
2018-06-21 15:45:44 -03:00
Ref < InputEventMouseButton > mb = p_event ;
2021-08-13 16:31:57 -05:00
if ( mb . is_valid ( ) & & mb - > is_pressed ( ) & & ( ( tool_select - > is_pressed ( ) & & mb - > get_button_index ( ) = = MouseButton : : RIGHT ) | | ( mb - > get_button_index ( ) = = MouseButton : : LEFT & & tool_create - > is_pressed ( ) ) ) ) {
2022-05-04 06:31:53 +01:00
if ( ! read_only ) {
2023-09-26 15:21:54 +02:00
menu - > clear ( false ) ;
2022-05-04 06:31:53 +01:00
animations_menu - > clear ( ) ;
animations_to_add . clear ( ) ;
2025-04-22 12:17:27 -04:00
2025-01-08 20:21:08 +08:00
LocalVector < StringName > classes ;
2025-04-22 12:17:27 -04:00
ClassDB : : get_inheriters_from_class ( " AnimationRootNode " , classes ) ;
2022-05-04 06:31:53 +01:00
classes . sort_custom < StringName : : AlphCompare > ( ) ;
2023-11-28 17:33:04 +01:00
menu - > add_submenu_node_item ( TTR ( " Add Animation " ) , animations_menu ) ;
2022-05-04 06:31:53 +01:00
2023-07-21 00:34:06 +09:00
List < StringName > names ;
tree - > get_animation_list ( & names ) ;
for ( const StringName & E : names ) {
animations_menu - > add_icon_item ( get_editor_theme_icon ( SNAME ( " Animation " ) ) , E ) ;
animations_to_add . push_back ( E ) ;
2018-06-21 15:45:44 -03:00
}
2022-05-04 06:31:53 +01:00
for ( const StringName & E : classes ) {
String name = String ( E ) . replace_first ( " AnimationNode " , " " ) ;
if ( name = = " Animation " | | name = = " StartState " | | name = = " EndState " ) {
continue ; // nope
}
int idx = menu - > get_item_count ( ) ;
menu - > add_item ( vformat ( TTR ( " Add %s " ) , name ) , idx ) ;
menu - > set_item_metadata ( idx , E ) ;
2020-05-14 16:41:43 +02:00
}
2018-06-21 15:45:44 -03:00
2022-05-04 06:31:53 +01:00
Ref < AnimationNode > clipb = EditorSettings : : get_singleton ( ) - > get_resource_clipboard ( ) ;
if ( clipb . is_valid ( ) ) {
menu - > add_separator ( ) ;
menu - > add_item ( TTR ( " Paste " ) , MENU_PASTE ) ;
}
2018-08-20 13:38:18 -03:00
menu - > add_separator ( ) ;
2022-05-04 06:31:53 +01:00
menu - > add_item ( TTR ( " Load... " ) , MENU_LOAD_FILE ) ;
menu - > set_position ( blend_space_draw - > get_screen_position ( ) + mb - > get_position ( ) ) ;
menu - > reset_size ( ) ;
menu - > popup ( ) ;
add_point_pos = ( mb - > get_position ( ) / blend_space_draw - > get_size ( ) ) ;
add_point_pos . y = 1.0 - add_point_pos . y ;
add_point_pos * = ( blend_space - > get_max_space ( ) - blend_space - > get_min_space ( ) ) ;
add_point_pos + = blend_space - > get_min_space ( ) ;
if ( snap - > is_pressed ( ) ) {
add_point_pos = add_point_pos . snapped ( blend_space - > get_snap ( ) ) ;
}
2018-06-21 15:45:44 -03:00
}
}
2025-08-20 05:37:13 +05:30
if ( mb . is_valid ( ) & & mb - > is_pressed ( ) & & tool_select - > is_pressed ( ) & & ! mb - > is_shift_pressed ( ) & & ! mb - > is_command_or_control_pressed ( ) & & mb - > get_button_index ( ) = = MouseButton : : LEFT ) {
2022-08-13 23:21:24 +02:00
blend_space_draw - > queue_redraw ( ) ; //update anyway
2018-06-21 15:45:44 -03:00
//try to see if a point can be selected
selected_point = - 1 ;
selected_triangle = - 1 ;
_update_tool_erase ( ) ;
for ( int i = 0 ; i < points . size ( ) ; i + + ) {
if ( points [ i ] . distance_to ( mb - > get_position ( ) ) < 10 * EDSCALE ) {
selected_point = i ;
Ref < AnimationNode > node = blend_space - > get_blend_point_node ( i ) ;
EditorNode : : get_singleton ( ) - > push_item ( node . ptr ( ) , " " , true ) ;
dragging_selected_attempt = true ;
drag_from = mb - > get_position ( ) ;
_update_tool_erase ( ) ;
_update_edited_point_pos ( ) ;
return ;
}
}
//then try to see if a triangle can be selected
2018-06-21 22:48:47 -03:00
if ( ! blend_space - > get_auto_triangles ( ) ) { //if autotriangles use, disable this
for ( int i = 0 ; i < blend_space - > get_triangle_count ( ) ; i + + ) {
Vector < Vector2 > triangle ;
for ( int j = 0 ; j < 3 ; j + + ) {
int idx = blend_space - > get_triangle_point ( i , j ) ;
ERR_FAIL_INDEX ( idx , points . size ( ) ) ;
triangle . push_back ( points [ idx ] ) ;
}
2018-06-21 15:45:44 -03:00
2020-05-25 20:20:45 +03:00
if ( Geometry2D : : is_point_in_triangle ( mb - > get_position ( ) , triangle [ 0 ] , triangle [ 1 ] , triangle [ 2 ] ) ) {
2018-06-21 22:48:47 -03:00
selected_triangle = i ;
_update_tool_erase ( ) ;
return ;
}
2018-06-21 15:45:44 -03:00
}
}
}
2021-08-13 16:31:57 -05:00
if ( mb . is_valid ( ) & & mb - > is_pressed ( ) & & tool_triangle - > is_pressed ( ) & & mb - > get_button_index ( ) = = MouseButton : : LEFT ) {
2022-08-13 23:21:24 +02:00
blend_space_draw - > queue_redraw ( ) ; //update anyway
2018-06-21 15:45:44 -03:00
//try to see if a point can be selected
selected_point = - 1 ;
for ( int i = 0 ; i < points . size ( ) ; i + + ) {
2022-02-02 00:04:13 +05:45
if ( making_triangle . has ( i ) ) {
2018-06-21 15:45:44 -03:00
continue ;
2020-05-14 16:41:43 +02:00
}
2018-06-21 15:45:44 -03:00
if ( points [ i ] . distance_to ( mb - > get_position ( ) ) < 10 * EDSCALE ) {
making_triangle . push_back ( i ) ;
if ( making_triangle . size ( ) = = 3 ) {
//add triangle!
if ( blend_space - > has_triangle ( making_triangle [ 0 ] , making_triangle [ 1 ] , making_triangle [ 2 ] ) ) {
making_triangle . clear ( ) ;
2019-03-25 01:54:29 +01:00
EditorNode : : get_singleton ( ) - > show_warning ( TTR ( " Triangle already exists. " ) ) ;
2018-06-21 15:45:44 -03:00
return ;
}
updating = true ;
2022-12-23 23:53:16 +01:00
EditorUndoRedoManager * undo_redo = EditorUndoRedoManager : : get_singleton ( ) ;
2019-02-21 16:41:01 -03:00
undo_redo - > create_action ( TTR ( " Add Triangle " ) ) ;
2018-06-21 18:08:11 -03:00
undo_redo - > add_do_method ( blend_space . ptr ( ) , " add_triangle " , making_triangle [ 0 ] , making_triangle [ 1 ] , making_triangle [ 2 ] ) ;
undo_redo - > add_undo_method ( blend_space . ptr ( ) , " remove_triangle " , blend_space - > get_triangle_count ( ) ) ;
2018-06-21 15:45:44 -03:00
undo_redo - > add_do_method ( this , " _update_space " ) ;
undo_redo - > add_undo_method ( this , " _update_space " ) ;
undo_redo - > commit_action ( ) ;
updating = false ;
making_triangle . clear ( ) ;
}
return ;
}
}
}
2021-08-13 16:31:57 -05:00
if ( mb . is_valid ( ) & & ! mb - > is_pressed ( ) & & dragging_selected_attempt & & mb - > get_button_index ( ) = = MouseButton : : LEFT ) {
2018-06-21 15:45:44 -03:00
if ( dragging_selected ) {
//move
Vector2 point = blend_space - > get_blend_point_position ( selected_point ) ;
point + = drag_ofs ;
if ( snap - > is_pressed ( ) ) {
2021-09-29 09:36:34 +05:45
point = point . snapped ( blend_space - > get_snap ( ) ) ;
2018-06-21 15:45:44 -03:00
}
2022-05-04 06:31:53 +01:00
if ( ! read_only ) {
updating = true ;
2022-12-23 23:53:16 +01:00
EditorUndoRedoManager * undo_redo = EditorUndoRedoManager : : get_singleton ( ) ;
2022-05-04 06:31:53 +01:00
undo_redo - > create_action ( TTR ( " Move Node Point " ) ) ;
undo_redo - > add_do_method ( blend_space . ptr ( ) , " set_blend_point_position " , selected_point , point ) ;
undo_redo - > add_undo_method ( blend_space . ptr ( ) , " set_blend_point_position " , selected_point , blend_space - > get_blend_point_position ( selected_point ) ) ;
undo_redo - > add_do_method ( this , " _update_space " ) ;
undo_redo - > add_undo_method ( this , " _update_space " ) ;
undo_redo - > add_do_method ( this , " _update_edited_point_pos " ) ;
undo_redo - > add_undo_method ( this , " _update_edited_point_pos " ) ;
undo_redo - > commit_action ( ) ;
updating = false ;
}
2018-06-21 15:45:44 -03:00
}
dragging_selected_attempt = false ;
dragging_selected = false ;
2022-08-13 23:21:24 +02:00
blend_space_draw - > queue_redraw ( ) ;
2018-06-21 15:45:44 -03:00
}
2025-08-20 05:37:13 +05:30
if ( mb . is_valid ( ) & & mb - > is_pressed ( ) & & ! dragging_selected_attempt & & ( ( tool_select - > is_pressed ( ) & & mb - > is_shift_pressed ( ) ) | | tool_blend - > is_pressed ( ) ) & & mb - > get_button_index ( ) = = MouseButton : : LEFT ) {
2018-06-21 15:45:44 -03:00
Vector2 blend_pos = ( mb - > get_position ( ) / blend_space_draw - > get_size ( ) ) ;
blend_pos . y = 1.0 - blend_pos . y ;
blend_pos * = ( blend_space - > get_max_space ( ) - blend_space - > get_min_space ( ) ) ;
blend_pos + = blend_space - > get_min_space ( ) ;
2022-12-13 03:00:11 +09:00
tree - > set ( get_blend_position_path ( ) , blend_pos ) ;
2018-08-20 13:38:18 -03:00
2022-08-13 23:21:24 +02:00
blend_space_draw - > queue_redraw ( ) ;
2018-06-21 15:45:44 -03:00
}
Ref < InputEventMouseMotion > mm = p_event ;
if ( mm . is_valid ( ) & & dragging_selected_attempt ) {
dragging_selected = true ;
2022-05-04 06:31:53 +01:00
if ( ! read_only ) {
drag_ofs = ( ( mm - > get_position ( ) - drag_from ) / blend_space_draw - > get_size ( ) ) * ( blend_space - > get_max_space ( ) - blend_space - > get_min_space ( ) ) * Vector2 ( 1 , - 1 ) ;
}
2022-08-13 23:21:24 +02:00
blend_space_draw - > queue_redraw ( ) ;
2018-06-21 15:45:44 -03:00
_update_edited_point_pos ( ) ;
}
if ( mm . is_valid ( ) & & tool_triangle - > is_pressed ( ) & & making_triangle . size ( ) ) {
2022-08-13 23:21:24 +02:00
blend_space_draw - > queue_redraw ( ) ;
2018-06-21 15:45:44 -03:00
}
if ( mm . is_valid ( ) & & ! tool_triangle - > is_pressed ( ) & & making_triangle . size ( ) ) {
making_triangle . clear ( ) ;
2022-08-13 23:21:24 +02:00
blend_space_draw - > queue_redraw ( ) ;
2018-06-21 15:45:44 -03:00
}
2025-08-20 05:37:13 +05:30
if ( mm . is_valid ( ) & & ! dragging_selected_attempt & & ( ( tool_select - > is_pressed ( ) & & mm - > is_shift_pressed ( ) ) | | tool_blend - > is_pressed ( ) ) & & ( mm - > get_button_mask ( ) . has_flag ( MouseButtonMask : : LEFT ) ) ) {
2018-06-21 15:45:44 -03:00
Vector2 blend_pos = ( mm - > get_position ( ) / blend_space_draw - > get_size ( ) ) ;
blend_pos . y = 1.0 - blend_pos . y ;
blend_pos * = ( blend_space - > get_max_space ( ) - blend_space - > get_min_space ( ) ) ;
blend_pos + = blend_space - > get_min_space ( ) ;
2022-12-13 03:00:11 +09:00
tree - > set ( get_blend_position_path ( ) , blend_pos ) ;
2018-08-20 13:38:18 -03:00
2022-08-13 23:21:24 +02:00
blend_space_draw - > queue_redraw ( ) ;
2018-06-21 15:45:44 -03:00
}
}
2018-08-20 13:38:18 -03:00
void AnimationNodeBlendSpace2DEditor : : _file_opened ( const String & p_file ) {
file_loaded = ResourceLoader : : load ( p_file ) ;
if ( file_loaded . is_valid ( ) ) {
_add_menu_type ( MENU_LOAD_FILE_CONFIRM ) ;
2020-10-06 22:44:09 -04:00
} else {
2022-08-07 17:32:59 -04:00
EditorNode : : get_singleton ( ) - > show_warning ( TTR ( " This type of node can't be used. Only animation nodes are allowed. " ) ) ;
2018-08-20 13:38:18 -03:00
}
}
2018-06-22 15:17:54 +02:00
void AnimationNodeBlendSpace2DEditor : : _add_menu_type ( int p_index ) {
2018-08-20 13:38:18 -03:00
Ref < AnimationRootNode > node ;
if ( p_index = = MENU_LOAD_FILE ) {
open_file - > clear_filters ( ) ;
List < String > filters ;
ResourceLoader : : get_recognized_extensions_for_type ( " AnimationRootNode " , & filters ) ;
2021-07-24 15:46:25 +02:00
for ( const String & E : filters ) {
2021-07-15 23:45:57 -04:00
open_file - > add_filter ( " *. " + E ) ;
2018-08-20 13:38:18 -03:00
}
2020-07-11 18:45:19 +02:00
open_file - > popup_file_dialog ( ) ;
2018-08-20 13:38:18 -03:00
return ;
} else if ( p_index = = MENU_LOAD_FILE_CONFIRM ) {
node = file_loaded ;
file_loaded . unref ( ) ;
} else if ( p_index = = MENU_PASTE ) {
node = EditorSettings : : get_singleton ( ) - > get_resource_clipboard ( ) ;
} else {
String type = menu - > get_item_metadata ( p_index ) ;
2021-06-17 16:03:09 -06:00
Object * obj = ClassDB : : instantiate ( type ) ;
2023-09-09 17:24:40 +02:00
ERR_FAIL_NULL ( obj ) ;
2018-08-20 13:38:18 -03:00
AnimationNode * an = Object : : cast_to < AnimationNode > ( obj ) ;
2023-09-09 17:24:40 +02:00
ERR_FAIL_NULL ( an ) ;
2018-06-21 18:46:17 -03:00
2018-08-20 13:38:18 -03:00
node = Ref < AnimationNode > ( an ) ;
}
2018-06-21 15:45:44 -03:00
2024-08-25 14:15:10 +02:00
if ( node . is_null ( ) ) {
2018-08-20 13:38:18 -03:00
EditorNode : : get_singleton ( ) - > show_warning ( TTR ( " This type of node can't be used. Only root nodes are allowed. " ) ) ;
return ;
}
2018-06-21 15:45:44 -03:00
updating = true ;
2022-12-23 23:53:16 +01:00
EditorUndoRedoManager * undo_redo = EditorUndoRedoManager : : get_singleton ( ) ;
2019-02-21 16:41:01 -03:00
undo_redo - > create_action ( TTR ( " Add Node Point " ) ) ;
2018-06-21 18:08:11 -03:00
undo_redo - > add_do_method ( blend_space . ptr ( ) , " add_blend_point " , node , add_point_pos ) ;
undo_redo - > add_undo_method ( blend_space . ptr ( ) , " remove_blend_point " , blend_space - > get_blend_point_count ( ) ) ;
2018-06-21 15:45:44 -03:00
undo_redo - > add_do_method ( this , " _update_space " ) ;
undo_redo - > add_undo_method ( this , " _update_space " ) ;
undo_redo - > commit_action ( ) ;
updating = false ;
2022-08-13 23:21:24 +02:00
blend_space_draw - > queue_redraw ( ) ;
2018-06-21 15:45:44 -03:00
}
2018-06-22 15:17:54 +02:00
void AnimationNodeBlendSpace2DEditor : : _add_animation_type ( int p_index ) {
2018-06-21 15:45:44 -03:00
Ref < AnimationNodeAnimation > anim ;
2021-06-17 16:03:09 -06:00
anim . instantiate ( ) ;
2018-06-21 15:45:44 -03:00
anim - > set_animation ( animations_to_add [ p_index ] ) ;
updating = true ;
2022-12-23 23:53:16 +01:00
EditorUndoRedoManager * undo_redo = EditorUndoRedoManager : : get_singleton ( ) ;
2019-02-21 16:41:01 -03:00
undo_redo - > create_action ( TTR ( " Add Animation Point " ) ) ;
2018-06-21 18:08:11 -03:00
undo_redo - > add_do_method ( blend_space . ptr ( ) , " add_blend_point " , anim , add_point_pos ) ;
undo_redo - > add_undo_method ( blend_space . ptr ( ) , " remove_blend_point " , blend_space - > get_blend_point_count ( ) ) ;
2018-06-21 15:45:44 -03:00
undo_redo - > add_do_method ( this , " _update_space " ) ;
undo_redo - > add_undo_method ( this , " _update_space " ) ;
undo_redo - > commit_action ( ) ;
updating = false ;
2022-08-13 23:21:24 +02:00
blend_space_draw - > queue_redraw ( ) ;
2018-06-21 15:45:44 -03:00
}
2018-06-22 15:17:54 +02:00
void AnimationNodeBlendSpace2DEditor : : _update_tool_erase ( ) {
2022-05-04 06:31:53 +01:00
tool_erase - > set_disabled (
( ! ( selected_point > = 0 & & selected_point < blend_space - > get_blend_point_count ( ) ) & & ! ( selected_triangle > = 0 & & selected_triangle < blend_space - > get_triangle_count ( ) ) ) | |
read_only ) ;
2018-06-21 15:45:44 -03:00
if ( selected_point > = 0 & & selected_point < blend_space - > get_blend_point_count ( ) ) {
Ref < AnimationNode > an = blend_space - > get_blend_point_node ( selected_point ) ;
2018-08-20 13:38:18 -03:00
if ( AnimationTreeEditor : : get_singleton ( ) - > can_edit ( an ) ) {
2018-06-21 15:45:44 -03:00
open_editor - > show ( ) ;
} else {
open_editor - > hide ( ) ;
}
2022-05-04 06:31:53 +01:00
if ( ! read_only ) {
edit_hb - > show ( ) ;
} else {
edit_hb - > hide ( ) ;
}
2018-06-21 15:45:44 -03:00
} else {
edit_hb - > hide ( ) ;
}
}
2018-06-22 15:17:54 +02:00
void AnimationNodeBlendSpace2DEditor : : _tool_switch ( int p_tool ) {
2018-06-21 15:45:44 -03:00
making_triangle . clear ( ) ;
2018-06-21 22:48:47 -03:00
if ( p_tool = = 2 ) {
2022-09-29 12:53:28 +03:00
Vector < Vector2 > bl_points ;
2018-06-21 22:48:47 -03:00
for ( int i = 0 ; i < blend_space - > get_blend_point_count ( ) ; i + + ) {
2022-09-29 12:53:28 +03:00
bl_points . push_back ( blend_space - > get_blend_point_position ( i ) ) ;
2018-06-21 22:48:47 -03:00
}
2022-09-29 12:53:28 +03:00
Vector < Delaunay2D : : Triangle > tr = Delaunay2D : : triangulate ( bl_points ) ;
2018-06-21 22:48:47 -03:00
for ( int i = 0 ; i < tr . size ( ) ; i + + ) {
blend_space - > add_triangle ( tr [ i ] . points [ 0 ] , tr [ i ] . points [ 1 ] , tr [ i ] . points [ 2 ] ) ;
}
}
2018-06-21 15:45:44 -03:00
if ( p_tool = = 0 ) {
tool_erase - > show ( ) ;
tool_erase_sep - > show ( ) ;
} else {
tool_erase - > hide ( ) ;
tool_erase_sep - > hide ( ) ;
}
_update_tool_erase ( ) ;
2022-08-13 23:21:24 +02:00
blend_space_draw - > queue_redraw ( ) ;
2018-06-21 15:45:44 -03:00
}
2018-06-22 15:17:54 +02:00
void AnimationNodeBlendSpace2DEditor : : _blend_space_draw ( ) {
2022-12-13 03:00:11 +09:00
AnimationTree * tree = AnimationTreeEditor : : get_singleton ( ) - > get_animation_tree ( ) ;
if ( ! tree ) {
return ;
}
2024-05-14 15:57:29 +02:00
Color linecolor = get_theme_color ( SceneStringName ( font_color ) , SNAME ( " Label " ) ) ;
2018-06-21 15:45:44 -03:00
Color linecolor_soft = linecolor ;
linecolor_soft . a * = 0.5 ;
2024-05-14 15:57:29 +02:00
Ref < Font > font = get_theme_font ( SceneStringName ( font ) , SNAME ( " Label " ) ) ;
int font_size = get_theme_font_size ( SceneStringName ( font_size ) , SNAME ( " Label " ) ) ;
2023-08-13 02:33:39 +02:00
Ref < Texture2D > icon = get_editor_theme_icon ( SNAME ( " KeyValue " ) ) ;
Ref < Texture2D > icon_selected = get_editor_theme_icon ( SNAME ( " KeySelected " ) ) ;
2018-06-21 15:45:44 -03:00
Size2 s = blend_space_draw - > get_size ( ) ;
2025-09-03 20:39:18 -03:00
if ( blend_space_draw - > has_focus ( true ) ) {
2023-08-13 02:33:39 +02:00
Color color = get_theme_color ( SNAME ( " accent_color " ) , EditorStringName ( Editor ) ) ;
2018-06-21 18:08:11 -03:00
blend_space_draw - > draw_rect ( Rect2 ( Point2 ( ) , s ) , color , false ) ;
}
2022-07-02 18:26:41 +02:00
blend_space_draw - > draw_line ( Point2 ( 1 , 0 ) , Point2 ( 1 , s . height - 1 ) , linecolor , Math : : round ( EDSCALE ) ) ;
blend_space_draw - > draw_line ( Point2 ( 1 , s . height - 1 ) , Point2 ( s . width - 1 , s . height - 1 ) , linecolor , Math : : round ( EDSCALE ) ) ;
2018-06-21 15:45:44 -03:00
2022-07-02 18:26:41 +02:00
blend_space_draw - > draw_line ( Point2 ( 0 , 0 ) , Point2 ( 5 * EDSCALE , 0 ) , linecolor , Math : : round ( EDSCALE ) ) ;
2018-06-21 15:45:44 -03:00
if ( blend_space - > get_min_space ( ) . y < 0 ) {
int y = ( blend_space - > get_max_space ( ) . y / ( blend_space - > get_max_space ( ) . y - blend_space - > get_min_space ( ) . y ) ) * s . height ;
2022-07-02 18:26:41 +02:00
blend_space_draw - > draw_line ( Point2 ( 0 , y ) , Point2 ( 5 * EDSCALE , y ) , linecolor , Math : : round ( EDSCALE ) ) ;
2021-11-24 20:58:47 -06:00
blend_space_draw - > draw_string ( font , Point2 ( 2 * EDSCALE , y - font - > get_height ( font_size ) + font - > get_ascent ( font_size ) ) , " 0 " , HORIZONTAL_ALIGNMENT_LEFT , - 1 , font_size , linecolor ) ;
2022-07-02 18:26:41 +02:00
blend_space_draw - > draw_line ( Point2 ( 5 * EDSCALE , y ) , Point2 ( s . width , y ) , linecolor_soft , Math : : round ( EDSCALE ) ) ;
2018-06-21 15:45:44 -03:00
}
if ( blend_space - > get_min_space ( ) . x < 0 ) {
2018-06-22 21:52:13 +02:00
int x = ( - blend_space - > get_min_space ( ) . x / ( blend_space - > get_max_space ( ) . x - blend_space - > get_min_space ( ) . x ) ) * s . width ;
2022-07-02 18:26:41 +02:00
blend_space_draw - > draw_line ( Point2 ( x , s . height - 1 ) , Point2 ( x , s . height - 5 * EDSCALE ) , linecolor , Math : : round ( EDSCALE ) ) ;
2021-11-24 20:58:47 -06:00
blend_space_draw - > draw_string ( font , Point2 ( x + 2 * EDSCALE , s . height - 2 * EDSCALE - font - > get_height ( font_size ) + font - > get_ascent ( font_size ) ) , " 0 " , HORIZONTAL_ALIGNMENT_LEFT , - 1 , font_size , linecolor ) ;
2022-07-02 18:26:41 +02:00
blend_space_draw - > draw_line ( Point2 ( x , s . height - 5 * EDSCALE ) , Point2 ( x , 0 ) , linecolor_soft , Math : : round ( EDSCALE ) ) ;
2018-06-21 15:45:44 -03:00
}
if ( snap - > is_pressed ( ) ) {
linecolor_soft . a = linecolor . a * 0.1 ;
if ( blend_space - > get_snap ( ) . x > 0 ) {
2018-10-04 13:04:58 +02:00
int prev_idx = 0 ;
2018-06-21 15:45:44 -03:00
for ( int i = 0 ; i < s . x ; i + + ) {
float v = blend_space - > get_min_space ( ) . x + i * ( blend_space - > get_max_space ( ) . x - blend_space - > get_min_space ( ) . x ) / s . x ;
int idx = int ( v / blend_space - > get_snap ( ) . x ) ;
if ( i > 0 & & prev_idx ! = idx ) {
2022-07-02 18:26:41 +02:00
blend_space_draw - > draw_line ( Point2 ( i , 0 ) , Point2 ( i , s . height ) , linecolor_soft , Math : : round ( EDSCALE ) ) ;
2018-06-21 15:45:44 -03:00
}
prev_idx = idx ;
}
}
if ( blend_space - > get_snap ( ) . y > 0 ) {
2018-10-04 13:04:58 +02:00
int prev_idx = 0 ;
2018-06-21 15:45:44 -03:00
for ( int i = 0 ; i < s . y ; i + + ) {
float v = blend_space - > get_max_space ( ) . y - i * ( blend_space - > get_max_space ( ) . y - blend_space - > get_min_space ( ) . y ) / s . y ;
int idx = int ( v / blend_space - > get_snap ( ) . y ) ;
if ( i > 0 & & prev_idx ! = idx ) {
2022-07-02 18:26:41 +02:00
blend_space_draw - > draw_line ( Point2 ( 0 , i ) , Point2 ( s . width , i ) , linecolor_soft , Math : : round ( EDSCALE ) ) ;
2018-06-21 15:45:44 -03:00
}
prev_idx = idx ;
}
}
}
//triangles first
for ( int i = 0 ; i < blend_space - > get_triangle_count ( ) ; i + + ) {
2022-09-29 12:53:28 +03:00
Vector < Vector2 > bl_points ;
bl_points . resize ( 3 ) ;
2018-06-21 15:45:44 -03:00
for ( int j = 0 ; j < 3 ; j + + ) {
int point_idx = blend_space - > get_triangle_point ( i , j ) ;
Vector2 point = blend_space - > get_blend_point_position ( point_idx ) ;
if ( dragging_selected & & selected_point = = point_idx ) {
point + = drag_ofs ;
if ( snap - > is_pressed ( ) ) {
2021-09-29 09:36:34 +05:45
point = point . snapped ( blend_space - > get_snap ( ) ) ;
2018-06-21 15:45:44 -03:00
}
}
point = ( point - blend_space - > get_min_space ( ) ) / ( blend_space - > get_max_space ( ) - blend_space - > get_min_space ( ) ) ;
point * = s ;
point . y = s . height - point . y ;
2022-09-29 12:53:28 +03:00
bl_points . write [ j ] = point ;
2018-06-21 15:45:44 -03:00
}
for ( int j = 0 ; j < 3 ; j + + ) {
2022-09-29 12:53:28 +03:00
blend_space_draw - > draw_line ( bl_points [ j ] , bl_points [ ( j + 1 ) % 3 ] , linecolor , Math : : round ( EDSCALE ) , true ) ;
2018-06-21 15:45:44 -03:00
}
Color color ;
if ( i = = selected_triangle ) {
2023-08-13 02:33:39 +02:00
color = get_theme_color ( SNAME ( " accent_color " ) , EditorStringName ( Editor ) ) ;
2018-06-21 15:45:44 -03:00
color . a * = 0.5 ;
} else {
color = linecolor ;
color . a * = 0.2 ;
}
2022-01-11 21:12:39 +05:45
Vector < Color > colors = {
color ,
color ,
color
} ;
2022-09-29 12:53:28 +03:00
blend_space_draw - > draw_primitive ( bl_points , colors , Vector < Vector2 > ( ) ) ;
2018-06-21 15:45:44 -03:00
}
points . clear ( ) ;
for ( int i = 0 ; i < blend_space - > get_blend_point_count ( ) ; i + + ) {
Vector2 point = blend_space - > get_blend_point_position ( i ) ;
2022-05-04 06:31:53 +01:00
if ( ! read_only ) {
if ( dragging_selected & & selected_point = = i ) {
point + = drag_ofs ;
if ( snap - > is_pressed ( ) ) {
point = point . snapped ( blend_space - > get_snap ( ) ) ;
}
2018-06-21 15:45:44 -03:00
}
}
point = ( point - blend_space - > get_min_space ( ) ) / ( blend_space - > get_max_space ( ) - blend_space - > get_min_space ( ) ) ;
point * = s ;
point . y = s . height - point . y ;
points . push_back ( point ) ;
point - = ( icon - > get_size ( ) / 2 ) ;
point = point . floor ( ) ;
if ( i = = selected_point ) {
blend_space_draw - > draw_texture ( icon_selected , point ) ;
} else {
blend_space_draw - > draw_texture ( icon , point ) ;
}
}
if ( making_triangle . size ( ) ) {
2022-09-29 12:53:28 +03:00
Vector < Vector2 > bl_points ;
2018-06-21 15:45:44 -03:00
for ( int i = 0 ; i < making_triangle . size ( ) ; i + + ) {
Vector2 point = blend_space - > get_blend_point_position ( making_triangle [ i ] ) ;
point = ( point - blend_space - > get_min_space ( ) ) / ( blend_space - > get_max_space ( ) - blend_space - > get_min_space ( ) ) ;
point * = s ;
point . y = s . height - point . y ;
2022-09-29 12:53:28 +03:00
bl_points . push_back ( point ) ;
2018-06-21 15:45:44 -03:00
}
2022-09-29 12:53:28 +03:00
for ( int i = 0 ; i < bl_points . size ( ) - 1 ; i + + ) {
blend_space_draw - > draw_line ( bl_points [ i ] , bl_points [ i + 1 ] , linecolor , Math : : round ( 2 * EDSCALE ) , true ) ;
2018-06-21 15:45:44 -03:00
}
2022-09-29 12:53:28 +03:00
blend_space_draw - > draw_line ( bl_points [ bl_points . size ( ) - 1 ] , blend_space_draw - > get_local_mouse_position ( ) , linecolor , Math : : round ( 2 * EDSCALE ) , true ) ;
2018-06-21 15:45:44 -03:00
}
///draw cursor position
{
Color color ;
if ( tool_blend - > is_pressed ( ) ) {
2023-08-13 02:33:39 +02:00
color = get_theme_color ( SNAME ( " accent_color " ) , EditorStringName ( Editor ) ) ;
2018-06-21 15:45:44 -03:00
} else {
color = linecolor ;
color . a * = 0.5 ;
}
2022-12-13 03:00:11 +09:00
Vector2 blend_pos = tree - > get ( get_blend_position_path ( ) ) ;
2018-08-20 13:38:18 -03:00
Vector2 point = blend_pos ;
2018-06-21 15:45:44 -03:00
point = ( point - blend_space - > get_min_space ( ) ) / ( blend_space - > get_max_space ( ) - blend_space - > get_min_space ( ) ) ;
point * = s ;
point . y = s . height - point . y ;
if ( blend_space - > get_triangle_count ( ) ) {
2018-08-20 13:38:18 -03:00
Vector2 closest = blend_space - > get_closest_point ( blend_pos ) ;
2018-06-21 15:45:44 -03:00
closest = ( closest - blend_space - > get_min_space ( ) ) / ( blend_space - > get_max_space ( ) - blend_space - > get_min_space ( ) ) ;
closest * = s ;
closest . y = s . height - closest . y ;
Color lcol = color ;
lcol . a * = 0.4 ;
2022-07-02 18:26:41 +02:00
blend_space_draw - > draw_line ( point , closest , lcol , Math : : round ( 2 * EDSCALE ) , true ) ;
2018-06-21 15:45:44 -03:00
}
float mind = 5 * EDSCALE ;
float maxd = 15 * EDSCALE ;
2022-07-02 18:26:41 +02:00
blend_space_draw - > draw_line ( point + Vector2 ( mind , 0 ) , point + Vector2 ( maxd , 0 ) , color , Math : : round ( 2 * EDSCALE ) ) ;
blend_space_draw - > draw_line ( point + Vector2 ( - mind , 0 ) , point + Vector2 ( - maxd , 0 ) , color , Math : : round ( 2 * EDSCALE ) ) ;
blend_space_draw - > draw_line ( point + Vector2 ( 0 , mind ) , point + Vector2 ( 0 , maxd ) , color , Math : : round ( 2 * EDSCALE ) ) ;
blend_space_draw - > draw_line ( point + Vector2 ( 0 , - mind ) , point + Vector2 ( 0 , - maxd ) , color , Math : : round ( 2 * EDSCALE ) ) ;
2018-06-21 15:45:44 -03:00
}
}
2018-06-22 15:17:54 +02:00
void AnimationNodeBlendSpace2DEditor : : _snap_toggled ( ) {
2022-08-13 23:21:24 +02:00
blend_space_draw - > queue_redraw ( ) ;
2018-06-21 15:45:44 -03:00
}
2018-06-22 15:17:54 +02:00
void AnimationNodeBlendSpace2DEditor : : _update_space ( ) {
2020-05-14 16:41:43 +02:00
if ( updating ) {
2018-06-21 15:45:44 -03:00
return ;
2020-05-14 16:41:43 +02:00
}
2018-06-21 15:45:44 -03:00
updating = true ;
2018-06-21 22:48:47 -03:00
if ( blend_space - > get_auto_triangles ( ) ) {
tool_triangle - > hide ( ) ;
} else {
tool_triangle - > show ( ) ;
}
auto_triangles - > set_pressed ( blend_space - > get_auto_triangles ( ) ) ;
2022-06-29 15:35:29 +09:00
sync - > set_pressed ( blend_space - > is_using_sync ( ) ) ;
2018-11-21 16:06:17 -03:00
interpolation - > select ( blend_space - > get_blend_mode ( ) ) ;
2018-06-21 15:45:44 -03:00
max_x_value - > set_value ( blend_space - > get_max_space ( ) . x ) ;
max_y_value - > set_value ( blend_space - > get_max_space ( ) . y ) ;
min_x_value - > set_value ( blend_space - > get_min_space ( ) . x ) ;
min_y_value - > set_value ( blend_space - > get_min_space ( ) . y ) ;
label_x - > set_text ( blend_space - > get_x_label ( ) ) ;
label_y - > set_text ( blend_space - > get_y_label ( ) ) ;
snap_x - > set_value ( blend_space - > get_snap ( ) . x ) ;
snap_y - > set_value ( blend_space - > get_snap ( ) . y ) ;
2022-08-13 23:21:24 +02:00
blend_space_draw - > queue_redraw ( ) ;
2018-06-21 15:45:44 -03:00
updating = false ;
}
2018-06-22 15:17:54 +02:00
void AnimationNodeBlendSpace2DEditor : : _config_changed ( double ) {
2020-05-14 16:41:43 +02:00
if ( updating ) {
2018-06-21 15:45:44 -03:00
return ;
2020-05-14 16:41:43 +02:00
}
2018-06-21 15:45:44 -03:00
updating = true ;
2022-12-23 23:53:16 +01:00
EditorUndoRedoManager * undo_redo = EditorUndoRedoManager : : get_singleton ( ) ;
2022-06-29 15:35:29 +09:00
undo_redo - > create_action ( TTR ( " Change BlendSpace2D Config " ) ) ;
2018-06-21 18:08:11 -03:00
undo_redo - > add_do_method ( blend_space . ptr ( ) , " set_max_space " , Vector2 ( max_x_value - > get_value ( ) , max_y_value - > get_value ( ) ) ) ;
undo_redo - > add_undo_method ( blend_space . ptr ( ) , " set_max_space " , blend_space - > get_max_space ( ) ) ;
undo_redo - > add_do_method ( blend_space . ptr ( ) , " set_min_space " , Vector2 ( min_x_value - > get_value ( ) , min_y_value - > get_value ( ) ) ) ;
undo_redo - > add_undo_method ( blend_space . ptr ( ) , " set_min_space " , blend_space - > get_min_space ( ) ) ;
undo_redo - > add_do_method ( blend_space . ptr ( ) , " set_snap " , Vector2 ( snap_x - > get_value ( ) , snap_y - > get_value ( ) ) ) ;
undo_redo - > add_undo_method ( blend_space . ptr ( ) , " set_snap " , blend_space - > get_snap ( ) ) ;
2022-06-29 15:35:29 +09:00
undo_redo - > add_do_method ( blend_space . ptr ( ) , " set_use_sync " , sync - > is_pressed ( ) ) ;
undo_redo - > add_undo_method ( blend_space . ptr ( ) , " set_use_sync " , blend_space - > is_using_sync ( ) ) ;
2018-11-21 16:06:17 -03:00
undo_redo - > add_do_method ( blend_space . ptr ( ) , " set_blend_mode " , interpolation - > get_selected ( ) ) ;
undo_redo - > add_undo_method ( blend_space . ptr ( ) , " set_blend_mode " , blend_space - > get_blend_mode ( ) ) ;
2018-06-21 15:45:44 -03:00
undo_redo - > add_do_method ( this , " _update_space " ) ;
undo_redo - > add_undo_method ( this , " _update_space " ) ;
undo_redo - > commit_action ( ) ;
updating = false ;
2022-08-13 23:21:24 +02:00
blend_space_draw - > queue_redraw ( ) ;
2018-06-21 15:45:44 -03:00
}
2018-06-22 15:17:54 +02:00
void AnimationNodeBlendSpace2DEditor : : _labels_changed ( String ) {
2020-05-14 16:41:43 +02:00
if ( updating ) {
2018-06-21 15:45:44 -03:00
return ;
2020-05-14 16:41:43 +02:00
}
2018-06-21 15:45:44 -03:00
updating = true ;
2022-12-23 23:53:16 +01:00
EditorUndoRedoManager * undo_redo = EditorUndoRedoManager : : get_singleton ( ) ;
2019-02-21 16:41:01 -03:00
undo_redo - > create_action ( TTR ( " Change BlendSpace2D Labels " ) , UndoRedo : : MERGE_ENDS ) ;
2018-06-21 18:08:11 -03:00
undo_redo - > add_do_method ( blend_space . ptr ( ) , " set_x_label " , label_x - > get_text ( ) ) ;
undo_redo - > add_undo_method ( blend_space . ptr ( ) , " set_x_label " , blend_space - > get_x_label ( ) ) ;
undo_redo - > add_do_method ( blend_space . ptr ( ) , " set_y_label " , label_y - > get_text ( ) ) ;
undo_redo - > add_undo_method ( blend_space . ptr ( ) , " set_y_label " , blend_space - > get_y_label ( ) ) ;
2018-06-21 15:45:44 -03:00
undo_redo - > add_do_method ( this , " _update_space " ) ;
undo_redo - > add_undo_method ( this , " _update_space " ) ;
undo_redo - > commit_action ( ) ;
updating = false ;
}
2018-06-22 15:17:54 +02:00
void AnimationNodeBlendSpace2DEditor : : _erase_selected ( ) {
2022-12-23 23:53:16 +01:00
EditorUndoRedoManager * undo_redo = EditorUndoRedoManager : : get_singleton ( ) ;
2018-06-21 15:45:44 -03:00
if ( selected_point ! = - 1 ) {
updating = true ;
2019-02-21 16:41:01 -03:00
undo_redo - > create_action ( TTR ( " Remove BlendSpace2D Point " ) ) ;
2018-06-21 18:08:11 -03:00
undo_redo - > add_do_method ( blend_space . ptr ( ) , " remove_blend_point " , selected_point ) ;
undo_redo - > add_undo_method ( blend_space . ptr ( ) , " add_blend_point " , blend_space - > get_blend_point_node ( selected_point ) , blend_space - > get_blend_point_position ( selected_point ) , selected_point ) ;
2018-06-21 15:45:44 -03:00
//restore triangles using this point
for ( int i = 0 ; i < blend_space - > get_triangle_count ( ) ; i + + ) {
for ( int j = 0 ; j < 3 ; j + + ) {
if ( blend_space - > get_triangle_point ( i , j ) = = selected_point ) {
2018-06-21 18:08:11 -03:00
undo_redo - > add_undo_method ( blend_space . ptr ( ) , " add_triangle " , blend_space - > get_triangle_point ( i , 0 ) , blend_space - > get_triangle_point ( i , 1 ) , blend_space - > get_triangle_point ( i , 2 ) , i ) ;
2018-06-21 15:45:44 -03:00
break ;
}
}
}
undo_redo - > add_do_method ( this , " _update_space " ) ;
undo_redo - > add_undo_method ( this , " _update_space " ) ;
undo_redo - > commit_action ( ) ;
updating = false ;
2022-08-13 23:21:24 +02:00
blend_space_draw - > queue_redraw ( ) ;
2018-06-21 15:45:44 -03:00
} else if ( selected_triangle ! = - 1 ) {
updating = true ;
2019-02-21 16:41:01 -03:00
undo_redo - > create_action ( TTR ( " Remove BlendSpace2D Triangle " ) ) ;
2018-06-21 18:08:11 -03:00
undo_redo - > add_do_method ( blend_space . ptr ( ) , " remove_triangle " , selected_triangle ) ;
undo_redo - > add_undo_method ( blend_space . ptr ( ) , " add_triangle " , blend_space - > get_triangle_point ( selected_triangle , 0 ) , blend_space - > get_triangle_point ( selected_triangle , 1 ) , blend_space - > get_triangle_point ( selected_triangle , 2 ) , selected_triangle ) ;
2018-06-21 15:45:44 -03:00
undo_redo - > add_do_method ( this , " _update_space " ) ;
undo_redo - > add_undo_method ( this , " _update_space " ) ;
undo_redo - > commit_action ( ) ;
updating = false ;
2022-08-13 23:21:24 +02:00
blend_space_draw - > queue_redraw ( ) ;
2018-06-21 15:45:44 -03:00
}
}
2018-06-22 15:17:54 +02:00
void AnimationNodeBlendSpace2DEditor : : _update_edited_point_pos ( ) {
2020-05-14 16:41:43 +02:00
if ( updating ) {
2018-06-21 15:45:44 -03:00
return ;
2020-05-14 16:41:43 +02:00
}
2018-06-21 15:45:44 -03:00
if ( selected_point > = 0 & & selected_point < blend_space - > get_blend_point_count ( ) ) {
Vector2 pos = blend_space - > get_blend_point_position ( selected_point ) ;
if ( dragging_selected ) {
pos + = drag_ofs ;
if ( snap - > is_pressed ( ) ) {
2021-09-29 09:36:34 +05:45
pos = pos . snapped ( blend_space - > get_snap ( ) ) ;
2018-06-21 15:45:44 -03:00
}
}
updating = true ;
edit_x - > set_value ( pos . x ) ;
edit_y - > set_value ( pos . y ) ;
updating = false ;
}
}
2018-06-22 15:17:54 +02:00
void AnimationNodeBlendSpace2DEditor : : _edit_point_pos ( double ) {
2020-05-14 16:41:43 +02:00
if ( updating ) {
2018-06-21 15:45:44 -03:00
return ;
2020-05-14 16:41:43 +02:00
}
2018-06-21 15:45:44 -03:00
updating = true ;
2022-12-23 23:53:16 +01:00
EditorUndoRedoManager * undo_redo = EditorUndoRedoManager : : get_singleton ( ) ;
2019-02-21 16:41:01 -03:00
undo_redo - > create_action ( TTR ( " Move Node Point " ) ) ;
2018-06-21 18:08:11 -03:00
undo_redo - > add_do_method ( blend_space . ptr ( ) , " set_blend_point_position " , selected_point , Vector2 ( edit_x - > get_value ( ) , edit_y - > get_value ( ) ) ) ;
undo_redo - > add_undo_method ( blend_space . ptr ( ) , " set_blend_point_position " , selected_point , blend_space - > get_blend_point_position ( selected_point ) ) ;
2018-06-21 15:45:44 -03:00
undo_redo - > add_do_method ( this , " _update_space " ) ;
undo_redo - > add_undo_method ( this , " _update_space " ) ;
undo_redo - > add_do_method ( this , " _update_edited_point_pos " ) ;
undo_redo - > add_undo_method ( this , " _update_edited_point_pos " ) ;
undo_redo - > commit_action ( ) ;
updating = false ;
2022-08-13 23:21:24 +02:00
blend_space_draw - > queue_redraw ( ) ;
2018-06-21 15:45:44 -03:00
}
2018-06-22 15:17:54 +02:00
void AnimationNodeBlendSpace2DEditor : : _notification ( int p_what ) {
2022-02-15 21:44:22 -05:00
switch ( p_what ) {
case NOTIFICATION_THEME_CHANGED : {
2024-05-14 15:50:53 +02:00
error_panel - > add_theme_style_override ( SceneStringName ( panel ) , get_theme_stylebox ( SceneStringName ( panel ) , SNAME ( " Tree " ) ) ) ;
2024-05-14 15:57:29 +02:00
error_label - > add_theme_color_override ( SceneStringName ( font_color ) , get_theme_color ( SNAME ( " error_color " ) , EditorStringName ( Editor ) ) ) ;
2024-05-14 15:50:53 +02:00
panel - > add_theme_style_override ( SceneStringName ( panel ) , get_theme_stylebox ( SceneStringName ( panel ) , SNAME ( " Tree " ) ) ) ;
2024-10-09 15:21:47 -07:00
tool_blend - > set_button_icon ( get_editor_theme_icon ( SNAME ( " EditPivot " ) ) ) ;
tool_select - > set_button_icon ( get_editor_theme_icon ( SNAME ( " ToolSelect " ) ) ) ;
tool_create - > set_button_icon ( get_editor_theme_icon ( SNAME ( " EditKey " ) ) ) ;
tool_triangle - > set_button_icon ( get_editor_theme_icon ( SNAME ( " ToolTriangle " ) ) ) ;
tool_erase - > set_button_icon ( get_editor_theme_icon ( SNAME ( " Remove " ) ) ) ;
snap - > set_button_icon ( get_editor_theme_icon ( SNAME ( " SnapGrid " ) ) ) ;
open_editor - > set_button_icon ( get_editor_theme_icon ( SNAME ( " Edit " ) ) ) ;
auto_triangles - > set_button_icon ( get_editor_theme_icon ( SNAME ( " AutoTriangle " ) ) ) ;
2022-02-15 21:44:22 -05:00
interpolation - > clear ( ) ;
2024-04-24 17:25:34 +08:00
interpolation - > add_icon_item ( get_editor_theme_icon ( SNAME ( " TrackContinuous " ) ) , TTR ( " Continuous " ) , 0 ) ;
interpolation - > add_icon_item ( get_editor_theme_icon ( SNAME ( " TrackDiscrete " ) ) , TTR ( " Discrete " ) , 1 ) ;
interpolation - > add_icon_item ( get_editor_theme_icon ( SNAME ( " TrackCapture " ) ) , TTR ( " Capture " ) , 2 ) ;
2022-02-15 21:44:22 -05:00
} break ;
case NOTIFICATION_PROCESS : {
2022-12-13 03:00:11 +09:00
AnimationTree * tree = AnimationTreeEditor : : get_singleton ( ) - > get_animation_tree ( ) ;
if ( ! tree ) {
return ;
}
2022-02-15 21:44:22 -05:00
String error ;
2025-06-12 23:53:43 +02:00
error = tree - > get_editor_error_message ( ) ;
if ( error . is_empty ( ) & & blend_space - > get_triangle_count ( ) = = 0 ) {
2022-02-15 21:44:22 -05:00
error = TTR ( " No triangles exist, so no blending can take place. " ) ;
}
2018-06-21 15:45:44 -03:00
2022-02-15 21:44:22 -05:00
if ( error ! = error_label - > get_text ( ) ) {
error_label - > set_text ( error ) ;
if ( ! error . is_empty ( ) ) {
error_panel - > show ( ) ;
} else {
error_panel - > hide ( ) ;
}
2018-06-21 15:45:44 -03:00
}
2022-02-15 21:44:22 -05:00
} break ;
2018-08-20 13:38:18 -03:00
2022-02-15 21:44:22 -05:00
case NOTIFICATION_VISIBILITY_CHANGED : {
set_process ( is_visible_in_tree ( ) ) ;
} break ;
2018-08-20 13:38:18 -03:00
}
2018-06-21 15:45:44 -03:00
}
2018-06-22 15:17:54 +02:00
void AnimationNodeBlendSpace2DEditor : : _open_editor ( ) {
2018-06-21 15:45:44 -03:00
if ( selected_point > = 0 & & selected_point < blend_space - > get_blend_point_count ( ) ) {
Ref < AnimationNode > an = blend_space - > get_blend_point_node ( selected_point ) ;
2018-08-20 13:38:18 -03:00
ERR_FAIL_COND ( an . is_null ( ) ) ;
AnimationTreeEditor : : get_singleton ( ) - > enter_editor ( itos ( selected_point ) ) ;
2018-06-21 15:45:44 -03:00
}
}
2018-06-22 15:17:54 +02:00
void AnimationNodeBlendSpace2DEditor : : _auto_triangles_toggled ( ) {
2022-12-23 23:53:16 +01:00
EditorUndoRedoManager * undo_redo = EditorUndoRedoManager : : get_singleton ( ) ;
2019-02-21 16:41:01 -03:00
undo_redo - > create_action ( TTR ( " Toggle Auto Triangles " ) ) ;
2018-06-21 22:48:47 -03:00
undo_redo - > add_do_method ( blend_space . ptr ( ) , " set_auto_triangles " , auto_triangles - > is_pressed ( ) ) ;
undo_redo - > add_undo_method ( blend_space . ptr ( ) , " set_auto_triangles " , blend_space - > get_auto_triangles ( ) ) ;
undo_redo - > add_do_method ( this , " _update_space " ) ;
undo_redo - > add_undo_method ( this , " _update_space " ) ;
undo_redo - > commit_action ( ) ;
}
2018-06-22 15:17:54 +02:00
void AnimationNodeBlendSpace2DEditor : : _bind_methods ( ) {
2018-06-22 21:52:13 +02:00
ClassDB : : bind_method ( " _update_space " , & AnimationNodeBlendSpace2DEditor : : _update_space ) ;
ClassDB : : bind_method ( " _update_tool_erase " , & AnimationNodeBlendSpace2DEditor : : _update_tool_erase ) ;
2018-06-21 15:45:44 -03:00
2018-06-22 21:52:13 +02:00
ClassDB : : bind_method ( " _update_edited_point_pos " , & AnimationNodeBlendSpace2DEditor : : _update_edited_point_pos ) ;
2018-06-21 15:45:44 -03:00
}
2020-04-02 01:20:12 +02:00
AnimationNodeBlendSpace2DEditor * AnimationNodeBlendSpace2DEditor : : singleton = nullptr ;
2018-06-21 15:45:44 -03:00
2018-06-22 15:17:54 +02:00
AnimationNodeBlendSpace2DEditor : : AnimationNodeBlendSpace2DEditor ( ) {
2018-06-21 15:45:44 -03:00
singleton = this ;
updating = false ;
HBoxContainer * top_hb = memnew ( HBoxContainer ) ;
add_child ( top_hb ) ;
Ref < ButtonGroup > bg ;
2021-06-17 16:03:09 -06:00
bg . instantiate ( ) ;
2018-06-21 15:45:44 -03:00
2020-06-19 20:49:04 +02:00
tool_select = memnew ( Button ) ;
2024-12-05 17:13:20 +03:00
tool_select - > set_theme_type_variation ( SceneStringName ( FlatButton ) ) ;
2018-06-21 15:45:44 -03:00
tool_select - > set_toggle_mode ( true ) ;
tool_select - > set_button_group ( bg ) ;
top_hb - > add_child ( tool_select ) ;
2025-08-20 05:37:13 +05:30
tool_select - > set_pressed ( true ) ;
tool_select - > set_tooltip_text ( TTR ( " Select and move points. \n RMB: Create point at position clicked. \n Shift+LMB+Drag: Set the blending position within the space. " ) ) ;
2024-05-14 09:40:21 +02:00
tool_select - > connect ( SceneStringName ( pressed ) , callable_mp ( this , & AnimationNodeBlendSpace2DEditor : : _tool_switch ) . bind ( 0 ) ) ;
2018-06-21 15:45:44 -03:00
2020-06-19 20:49:04 +02:00
tool_create = memnew ( Button ) ;
2024-12-05 17:13:20 +03:00
tool_create - > set_theme_type_variation ( SceneStringName ( FlatButton ) ) ;
2018-06-21 15:45:44 -03:00
tool_create - > set_toggle_mode ( true ) ;
tool_create - > set_button_group ( bg ) ;
top_hb - > add_child ( tool_create ) ;
2022-08-25 12:42:17 +02:00
tool_create - > set_tooltip_text ( TTR ( " Create points. " ) ) ;
2024-05-14 09:40:21 +02:00
tool_create - > connect ( SceneStringName ( pressed ) , callable_mp ( this , & AnimationNodeBlendSpace2DEditor : : _tool_switch ) . bind ( 1 ) ) ;
2018-06-21 15:45:44 -03:00
2025-08-20 05:37:13 +05:30
tool_blend = memnew ( Button ) ;
tool_blend - > set_theme_type_variation ( SceneStringName ( FlatButton ) ) ;
tool_blend - > set_toggle_mode ( true ) ;
tool_blend - > set_button_group ( bg ) ;
top_hb - > add_child ( tool_blend ) ;
tool_blend - > set_tooltip_text ( TTR ( " Set the blending position within the space. " ) ) ;
tool_blend - > connect ( SceneStringName ( pressed ) , callable_mp ( this , & AnimationNodeBlendSpace2DEditor : : _tool_switch ) . bind ( 2 ) ) ;
2020-06-19 20:49:04 +02:00
tool_triangle = memnew ( Button ) ;
2024-12-05 17:13:20 +03:00
tool_triangle - > set_theme_type_variation ( SceneStringName ( FlatButton ) ) ;
2018-06-21 15:45:44 -03:00
tool_triangle - > set_toggle_mode ( true ) ;
tool_triangle - > set_button_group ( bg ) ;
top_hb - > add_child ( tool_triangle ) ;
2022-08-25 12:42:17 +02:00
tool_triangle - > set_tooltip_text ( TTR ( " Create triangles by connecting points. " ) ) ;
2025-08-20 05:37:13 +05:30
tool_triangle - > connect ( SceneStringName ( pressed ) , callable_mp ( this , & AnimationNodeBlendSpace2DEditor : : _tool_switch ) . bind ( 3 ) ) ;
2018-06-21 15:45:44 -03:00
tool_erase_sep = memnew ( VSeparator ) ;
top_hb - > add_child ( tool_erase_sep ) ;
2020-06-19 20:49:04 +02:00
tool_erase = memnew ( Button ) ;
2024-12-05 17:13:20 +03:00
tool_erase - > set_theme_type_variation ( SceneStringName ( FlatButton ) ) ;
2018-06-21 15:45:44 -03:00
top_hb - > add_child ( tool_erase ) ;
2022-08-25 12:42:17 +02:00
tool_erase - > set_tooltip_text ( TTR ( " Erase points and triangles. " ) ) ;
2024-05-14 09:40:21 +02:00
tool_erase - > connect ( SceneStringName ( pressed ) , callable_mp ( this , & AnimationNodeBlendSpace2DEditor : : _erase_selected ) ) ;
2018-06-21 15:45:44 -03:00
tool_erase - > set_disabled ( true ) ;
top_hb - > add_child ( memnew ( VSeparator ) ) ;
2020-06-19 20:49:04 +02:00
auto_triangles = memnew ( Button ) ;
2024-12-05 17:13:20 +03:00
auto_triangles - > set_theme_type_variation ( SceneStringName ( FlatButton ) ) ;
2018-06-21 22:48:47 -03:00
top_hb - > add_child ( auto_triangles ) ;
2024-05-14 09:40:21 +02:00
auto_triangles - > connect ( SceneStringName ( pressed ) , callable_mp ( this , & AnimationNodeBlendSpace2DEditor : : _auto_triangles_toggled ) ) ;
2018-06-21 22:48:47 -03:00
auto_triangles - > set_toggle_mode ( true ) ;
2022-08-25 12:42:17 +02:00
auto_triangles - > set_tooltip_text ( TTR ( " Generate blend triangles automatically (instead of manually) " ) ) ;
2018-06-21 22:48:47 -03:00
top_hb - > add_child ( memnew ( VSeparator ) ) ;
2020-06-19 20:49:04 +02:00
snap = memnew ( Button ) ;
2024-12-05 17:13:20 +03:00
snap - > set_theme_type_variation ( SceneStringName ( FlatButton ) ) ;
2018-06-21 15:45:44 -03:00
snap - > set_toggle_mode ( true ) ;
top_hb - > add_child ( snap ) ;
snap - > set_pressed ( true ) ;
2022-08-25 12:42:17 +02:00
snap - > set_tooltip_text ( TTR ( " Enable snap and show grid. " ) ) ;
2024-05-14 09:40:21 +02:00
snap - > connect ( SceneStringName ( pressed ) , callable_mp ( this , & AnimationNodeBlendSpace2DEditor : : _snap_toggled ) ) ;
2018-06-21 15:45:44 -03:00
snap_x = memnew ( SpinBox ) ;
top_hb - > add_child ( snap_x ) ;
snap_x - > set_prefix ( " x: " ) ;
snap_x - > set_min ( 0.01 ) ;
snap_x - > set_step ( 0.01 ) ;
snap_x - > set_max ( 1000 ) ;
2025-03-21 09:55:22 +02:00
snap_x - > set_accessibility_name ( TTRC ( " Grid X Step " ) ) ;
2018-06-21 15:45:44 -03:00
snap_y = memnew ( SpinBox ) ;
top_hb - > add_child ( snap_y ) ;
snap_y - > set_prefix ( " y: " ) ;
snap_y - > set_min ( 0.01 ) ;
snap_y - > set_step ( 0.01 ) ;
snap_y - > set_max ( 1000 ) ;
2025-03-21 09:55:22 +02:00
snap_y - > set_accessibility_name ( TTRC ( " Grid Y Step " ) ) ;
2018-06-21 15:45:44 -03:00
2018-11-21 16:06:17 -03:00
top_hb - > add_child ( memnew ( VSeparator ) ) ;
2022-06-29 15:35:29 +09:00
top_hb - > add_child ( memnew ( Label ( TTR ( " Sync: " ) ) ) ) ;
sync = memnew ( CheckBox ) ;
top_hb - > add_child ( sync ) ;
2024-06-01 13:15:13 +03:00
sync - > connect ( SceneStringName ( toggled ) , callable_mp ( this , & AnimationNodeBlendSpace2DEditor : : _config_changed ) ) ;
2022-06-29 15:35:29 +09:00
top_hb - > add_child ( memnew ( VSeparator ) ) ;
2018-11-21 16:06:17 -03:00
top_hb - > add_child ( memnew ( Label ( TTR ( " Blend: " ) ) ) ) ;
interpolation = memnew ( OptionButton ) ;
top_hb - > add_child ( interpolation ) ;
2024-05-14 14:21:31 +02:00
interpolation - > connect ( SceneStringName ( item_selected ) , callable_mp ( this , & AnimationNodeBlendSpace2DEditor : : _config_changed ) ) ;
2018-11-21 16:06:17 -03:00
2018-06-21 15:45:44 -03:00
edit_hb = memnew ( HBoxContainer ) ;
top_hb - > add_child ( edit_hb ) ;
edit_hb - > add_child ( memnew ( VSeparator ) ) ;
edit_hb - > add_child ( memnew ( Label ( TTR ( " Point " ) ) ) ) ;
edit_x = memnew ( SpinBox ) ;
edit_hb - > add_child ( edit_x ) ;
edit_x - > set_min ( - 1000 ) ;
edit_x - > set_step ( 0.01 ) ;
edit_x - > set_max ( 1000 ) ;
2025-03-21 09:55:22 +02:00
edit_x - > set_accessibility_name ( TTRC ( " Blend X Value " ) ) ;
2024-05-14 11:42:00 +02:00
edit_x - > connect ( SceneStringName ( value_changed ) , callable_mp ( this , & AnimationNodeBlendSpace2DEditor : : _edit_point_pos ) ) ;
2018-06-21 15:45:44 -03:00
edit_y = memnew ( SpinBox ) ;
edit_hb - > add_child ( edit_y ) ;
edit_y - > set_min ( - 1000 ) ;
edit_y - > set_step ( 0.01 ) ;
edit_y - > set_max ( 1000 ) ;
2025-08-22 05:18:41 +05:30
edit_y - > set_accessibility_name ( TTRC ( " Blend Y Value " ) ) ;
2024-05-14 11:42:00 +02:00
edit_y - > connect ( SceneStringName ( value_changed ) , callable_mp ( this , & AnimationNodeBlendSpace2DEditor : : _edit_point_pos ) ) ;
2018-06-21 15:45:44 -03:00
open_editor = memnew ( Button ) ;
edit_hb - > add_child ( open_editor ) ;
open_editor - > set_text ( TTR ( " Open Editor " ) ) ;
2024-05-14 09:40:21 +02:00
open_editor - > connect ( SceneStringName ( pressed ) , callable_mp ( this , & AnimationNodeBlendSpace2DEditor : : _open_editor ) , CONNECT_DEFERRED ) ;
2018-06-21 15:45:44 -03:00
edit_hb - > hide ( ) ;
open_editor - > hide ( ) ;
HBoxContainer * main_hb = memnew ( HBoxContainer ) ;
add_child ( main_hb ) ;
main_hb - > set_v_size_flags ( SIZE_EXPAND_FILL ) ;
GridContainer * main_grid = memnew ( GridContainer ) ;
main_grid - > set_columns ( 2 ) ;
main_hb - > add_child ( main_grid ) ;
main_grid - > set_h_size_flags ( SIZE_EXPAND_FILL ) ;
{
VBoxContainer * left_vbox = memnew ( VBoxContainer ) ;
main_grid - > add_child ( left_vbox ) ;
left_vbox - > set_v_size_flags ( SIZE_EXPAND_FILL ) ;
max_y_value = memnew ( SpinBox ) ;
2025-03-21 09:55:22 +02:00
max_y_value - > set_accessibility_name ( TTRC ( " Max Y " ) ) ;
2018-06-21 15:45:44 -03:00
left_vbox - > add_child ( max_y_value ) ;
left_vbox - > add_spacer ( ) ;
label_y = memnew ( LineEdit ) ;
2025-03-21 09:55:22 +02:00
label_y - > set_accessibility_name ( TTRC ( " Y Value " ) ) ;
2018-06-21 15:45:44 -03:00
left_vbox - > add_child ( label_y ) ;
2021-03-28 19:31:25 +01:00
label_y - > set_expand_to_text_length_enabled ( true ) ;
2018-06-21 15:45:44 -03:00
left_vbox - > add_spacer ( ) ;
min_y_value = memnew ( SpinBox ) ;
2025-03-21 09:55:22 +02:00
min_y_value - > set_accessibility_name ( TTRC ( " Min Y " ) ) ;
2018-06-21 15:45:44 -03:00
left_vbox - > add_child ( min_y_value ) ;
max_y_value - > set_max ( 10000 ) ;
max_y_value - > set_min ( 0.01 ) ;
max_y_value - > set_step ( 0.01 ) ;
min_y_value - > set_min ( - 10000 ) ;
min_y_value - > set_max ( 0 ) ;
min_y_value - > set_step ( 0.01 ) ;
}
panel = memnew ( PanelContainer ) ;
panel - > set_clip_contents ( true ) ;
main_grid - > add_child ( panel ) ;
panel - > set_h_size_flags ( SIZE_EXPAND_FILL ) ;
blend_space_draw = memnew ( Control ) ;
2024-05-13 16:56:03 +02:00
blend_space_draw - > connect ( SceneStringName ( gui_input ) , callable_mp ( this , & AnimationNodeBlendSpace2DEditor : : _blend_space_gui_input ) ) ;
blend_space_draw - > connect ( SceneStringName ( draw ) , callable_mp ( this , & AnimationNodeBlendSpace2DEditor : : _blend_space_draw ) ) ;
2018-06-21 18:08:11 -03:00
blend_space_draw - > set_focus_mode ( FOCUS_ALL ) ;
2018-06-21 15:45:44 -03:00
panel - > add_child ( blend_space_draw ) ;
main_grid - > add_child ( memnew ( Control ) ) ; //empty bottom left
{
HBoxContainer * bottom_vbox = memnew ( HBoxContainer ) ;
main_grid - > add_child ( bottom_vbox ) ;
bottom_vbox - > set_h_size_flags ( SIZE_EXPAND_FILL ) ;
min_x_value = memnew ( SpinBox ) ;
2025-03-21 09:55:22 +02:00
min_x_value - > set_accessibility_name ( TTRC ( " Min X " ) ) ;
2018-06-21 15:45:44 -03:00
bottom_vbox - > add_child ( min_x_value ) ;
bottom_vbox - > add_spacer ( ) ;
label_x = memnew ( LineEdit ) ;
2025-08-22 05:18:41 +05:30
label_x - > set_accessibility_name ( TTRC ( " X Value " ) ) ;
2018-06-21 15:45:44 -03:00
bottom_vbox - > add_child ( label_x ) ;
2021-03-28 19:31:25 +01:00
label_x - > set_expand_to_text_length_enabled ( true ) ;
2018-06-21 15:45:44 -03:00
bottom_vbox - > add_spacer ( ) ;
max_x_value = memnew ( SpinBox ) ;
2025-08-22 05:18:41 +05:30
max_x_value - > set_accessibility_name ( TTRC ( " Max X " ) ) ;
2018-06-21 15:45:44 -03:00
bottom_vbox - > add_child ( max_x_value ) ;
max_x_value - > set_max ( 10000 ) ;
max_x_value - > set_min ( 0.01 ) ;
max_x_value - > set_step ( 0.01 ) ;
min_x_value - > set_min ( - 10000 ) ;
min_x_value - > set_max ( 0 ) ;
min_x_value - > set_step ( 0.01 ) ;
}
2024-05-14 11:42:00 +02:00
snap_x - > connect ( SceneStringName ( value_changed ) , callable_mp ( this , & AnimationNodeBlendSpace2DEditor : : _config_changed ) ) ;
snap_y - > connect ( SceneStringName ( value_changed ) , callable_mp ( this , & AnimationNodeBlendSpace2DEditor : : _config_changed ) ) ;
max_x_value - > connect ( SceneStringName ( value_changed ) , callable_mp ( this , & AnimationNodeBlendSpace2DEditor : : _config_changed ) ) ;
min_x_value - > connect ( SceneStringName ( value_changed ) , callable_mp ( this , & AnimationNodeBlendSpace2DEditor : : _config_changed ) ) ;
max_y_value - > connect ( SceneStringName ( value_changed ) , callable_mp ( this , & AnimationNodeBlendSpace2DEditor : : _config_changed ) ) ;
min_y_value - > connect ( SceneStringName ( value_changed ) , callable_mp ( this , & AnimationNodeBlendSpace2DEditor : : _config_changed ) ) ;
label_x - > connect ( SceneStringName ( text_changed ) , callable_mp ( this , & AnimationNodeBlendSpace2DEditor : : _labels_changed ) ) ;
label_y - > connect ( SceneStringName ( text_changed ) , callable_mp ( this , & AnimationNodeBlendSpace2DEditor : : _labels_changed ) ) ;
2018-06-21 15:45:44 -03:00
error_panel = memnew ( PanelContainer ) ;
add_child ( error_panel ) ;
error_label = memnew ( Label ) ;
2025-04-22 11:57:16 +03:00
error_label - > set_focus_mode ( FOCUS_ACCESSIBILITY ) ;
2018-06-21 15:45:44 -03:00
error_panel - > add_child ( error_label ) ;
2025-08-20 09:07:49 +05:30
error_panel - > hide ( ) ;
2018-06-21 15:45:44 -03:00
set_custom_minimum_size ( Size2 ( 0 , 300 * EDSCALE ) ) ;
menu = memnew ( PopupMenu ) ;
add_child ( menu ) ;
2024-05-14 14:13:31 +02:00
menu - > connect ( SceneStringName ( id_pressed ) , callable_mp ( this , & AnimationNodeBlendSpace2DEditor : : _add_menu_type ) ) ;
2018-06-21 15:45:44 -03:00
animations_menu = memnew ( PopupMenu ) ;
2024-01-23 18:29:45 -03:00
animations_menu - > set_auto_translate_mode ( AUTO_TRANSLATE_MODE_DISABLED ) ;
2023-11-28 17:33:04 +01:00
menu - > add_child ( animations_menu ) ;
2020-02-21 18:28:45 +01:00
animations_menu - > connect ( " index_pressed " , callable_mp ( this , & AnimationNodeBlendSpace2DEditor : : _add_animation_type ) ) ;
2018-06-21 15:45:44 -03:00
2018-08-20 13:38:18 -03:00
open_file = memnew ( EditorFileDialog ) ;
add_child ( open_file ) ;
open_file - > set_title ( TTR ( " Open Animation Node " ) ) ;
2020-03-06 14:00:16 -03:00
open_file - > set_file_mode ( EditorFileDialog : : FILE_MODE_OPEN_FILE ) ;
2020-02-21 18:28:45 +01:00
open_file - > connect ( " file_selected " , callable_mp ( this , & AnimationNodeBlendSpace2DEditor : : _file_opened ) ) ;
2018-08-20 13:38:18 -03:00
2018-06-21 15:45:44 -03:00
selected_point = - 1 ;
selected_triangle = - 1 ;
dragging_selected = false ;
dragging_selected_attempt = false ;
}