2018-08-29 22:38:13 +02:00
/**************************************************************************/
/* animation_blend_space_1d_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_1d_editor.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-22 21:52:13 +02:00
# include "scene/animation/animation_blend_tree.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"
2023-10-02 13:43:08 +02:00
# include "scene/gui/line_edit.h"
2023-01-31 02:12:31 +09:00
# include "scene/gui/option_button.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"
2018-06-22 21:52:13 +02:00
2018-08-20 13:38:18 -03:00
StringName AnimationNodeBlendSpace1DEditor : : 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 21:52:13 +02:00
}
void AnimationNodeBlendSpace1DEditor : : _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-22 21:52:13 +02: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-22 21:52:13 +02:00
if ( selected_point ! = - 1 ) {
2022-05-04 06:31:53 +01:00
if ( ! read_only ) {
_erase_selected ( ) ;
}
2018-06-22 21:52:13 +02:00
accept_event ( ) ;
}
}
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 ( ) ;
2018-06-22 21:52:13 +02:00
2025-01-08 20:21:08 +08:00
LocalVector < StringName > classes ;
ClassDB : : get_inheriters_from_class ( " AnimationRootNode " , classes ) ;
2022-05-04 06:31:53 +01:00
classes . sort_custom < StringName : : AlphCompare > ( ) ;
2018-06-22 21:52:13 +02:00
2023-11-28 17:33:04 +01:00
menu - > add_submenu_node_item ( TTR ( " Add Animation " ) , animations_menu ) ;
2018-06-22 21:52:13 +02:00
2023-07-21 00:34:06 +09:00
List < StringName > names ;
tree - > get_animation_list ( & names ) ;
2018-06-22 21:52:13 +02:00
2023-07-21 00:34:06 +09:00
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-22 21:52:13 +02: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 ;
}
2018-06-22 21:52:13 +02:00
2022-05-04 06:31:53 +01:00
int idx = menu - > get_item_count ( ) ;
menu - > add_item ( vformat ( TTR ( " Add %s " ) , name ) , idx ) ;
menu - > set_item_metadata ( idx , E ) ;
}
2018-06-22 21:52:13 +02: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 ) ;
2018-08-20 13:38:18 -03:00
2022-05-04 06:31:53 +01:00
menu - > set_position ( blend_space_draw - > get_screen_position ( ) + mb - > get_position ( ) ) ;
menu - > reset_size ( ) ;
menu - > popup ( ) ;
2018-06-22 21:52:13 +02:00
2022-05-04 06:31:53 +01:00
add_point_pos = ( mb - > get_position ( ) / blend_space_draw - > get_size ( ) ) . x ;
add_point_pos * = ( blend_space - > get_max_space ( ) - blend_space - > get_min_space ( ) ) ;
add_point_pos + = blend_space - > get_min_space ( ) ;
2018-06-22 21:52:13 +02:00
2022-05-04 06:31:53 +01:00
if ( snap - > is_pressed ( ) ) {
add_point_pos = Math : : snapped ( add_point_pos , blend_space - > get_snap ( ) ) ;
}
2018-06-22 21:52:13 +02: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 ( ) ; // why not
2018-06-22 21:52:13 +02:00
// try to see if a point can be selected
selected_point = - 1 ;
_update_tool_erase ( ) ;
for ( int i = 0 ; i < points . size ( ) ; i + + ) {
if ( Math : : abs ( float ( points [ i ] - mb - > get_position ( ) . x ) ) < 10 * EDSCALE ) {
selected_point = i ;
Ref < AnimationNode > node = blend_space - > get_blend_point_node ( i ) ;
EditorNode : : get_singleton ( ) - > push_item ( node . ptr ( ) , " " , true ) ;
2025-08-22 00:47:23 +05:30
if ( mb - > is_double_click ( ) & & AnimationTreeEditor : : get_singleton ( ) - > can_edit ( node ) ) {
_open_editor ( ) ;
return ;
}
2018-06-22 21:52:13 +02:00
dragging_selected_attempt = true ;
drag_from = mb - > get_position ( ) ;
_update_tool_erase ( ) ;
_update_edited_point_pos ( ) ;
return ;
}
}
2025-08-30 17:56:36 +05:30
// If no point was selected, select host BlendSpace1D node.
if ( selected_point = = - 1 ) {
EditorNode : : get_singleton ( ) - > push_item ( blend_space . ptr ( ) , " " , true ) ;
}
2018-06-22 21:52:13 +02:00
}
2021-08-13 16:31:57 -05:00
if ( mb . is_valid ( ) & & ! mb - > is_pressed ( ) & & dragging_selected_attempt & & mb - > get_button_index ( ) = = MouseButton : : LEFT ) {
2022-05-04 06:31:53 +01:00
if ( ! read_only ) {
if ( dragging_selected ) {
// move
float point = blend_space - > get_blend_point_position ( selected_point ) ;
point + = drag_ofs . x ;
if ( snap - > is_pressed ( ) ) {
point = Math : : snapped ( point , blend_space - > get_snap ( ) ) ;
}
2018-06-22 21:52:13 +02:00
2022-05-04 06:31:53 +01:00
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-22 21:52:13 +02:00
}
2022-05-04 06:31:53 +01:00
dragging_selected_attempt = false ;
dragging_selected = false ;
2022-08-13 23:21:24 +02:00
blend_space_draw - > queue_redraw ( ) ;
2018-06-22 21:52:13 +02:00
}
}
// *set* the blend
2025-10-18 23:21:18 +03:00
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-22 21:52:13 +02:00
float blend_pos = mb - > get_position ( ) . x / blend_space_draw - > get_size ( ) . x ;
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 ) ;
2025-10-18 23:21:18 +03:00
dragging_blend_position = true ;
2022-08-13 23:21:24 +02:00
blend_space_draw - > queue_redraw ( ) ;
2018-06-22 21:52:13 +02:00
}
2025-10-18 23:21:18 +03:00
if ( mb . is_valid ( ) & & ! mb - > is_pressed ( ) & & dragging_blend_position & & mb - > get_button_index ( ) = = MouseButton : : LEFT ) {
dragging_blend_position = false ;
}
2018-06-22 21:52:13 +02:00
Ref < InputEventMouseMotion > mm = p_event ;
if ( mm . is_valid ( ) & & dragging_selected_attempt ) {
dragging_selected = true ;
drag_ofs = ( ( mm - > get_position ( ) - drag_from ) / blend_space_draw - > get_size ( ) ) * ( ( blend_space - > get_max_space ( ) - blend_space - > get_min_space ( ) ) * Vector2 ( 1 , 0 ) ) ;
2022-08-13 23:21:24 +02:00
blend_space_draw - > queue_redraw ( ) ;
2018-06-22 21:52:13 +02:00
_update_edited_point_pos ( ) ;
}
2025-10-18 23:21:18 +03:00
if ( mm . is_valid ( ) & & dragging_blend_position & & ! 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-22 21:52:13 +02:00
float blend_pos = mm - > get_position ( ) . x / blend_space_draw - > get_size ( ) . x ;
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-22 21:52:13 +02:00
}
}
void AnimationNodeBlendSpace1DEditor : : _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-22 21:52:13 +02: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-22 21:52:13 +02:00
Size2 s = blend_space_draw - > get_size ( ) ;
if ( blend_space_draw - > has_focus ( ) ) {
2023-08-13 02:33:39 +02:00
Color color = get_theme_color ( SNAME ( " accent_color " ) , EditorStringName ( Editor ) ) ;
2018-06-22 21:52:13 +02: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 , s . height - 1 ) , Point2 ( s . width - 1 , s . height - 1 ) , linecolor , Math : : round ( EDSCALE ) ) ;
2018-06-22 21:52:13 +02:00
if ( blend_space - > get_min_space ( ) < 0 ) {
float point = 0.0 ;
point = ( point - blend_space - > get_min_space ( ) ) / ( blend_space - > get_max_space ( ) - blend_space - > get_min_space ( ) ) ;
point * = s . width ;
float x = point ;
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-22 21:52:13 +02:00
}
if ( snap - > is_pressed ( ) ) {
linecolor_soft . a = linecolor . a * 0.1 ;
if ( blend_space - > get_snap ( ) > 0 ) {
int prev_idx = - 1 ;
for ( int i = 0 ; i < s . x ; i + + ) {
float v = blend_space - > get_min_space ( ) + i * ( blend_space - > get_max_space ( ) - blend_space - > get_min_space ( ) ) / s . x ;
int idx = int ( v / blend_space - > get_snap ( ) ) ;
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-22 21:52:13 +02:00
}
prev_idx = idx ;
}
}
}
points . clear ( ) ;
for ( int i = 0 ; i < blend_space - > get_blend_point_count ( ) ; i + + ) {
float 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 . x ;
if ( snap - > is_pressed ( ) ) {
point = Math : : snapped ( point , blend_space - > get_snap ( ) ) ;
}
2018-06-22 21:52:13 +02:00
}
}
point = ( point - blend_space - > get_min_space ( ) ) / ( blend_space - > get_max_space ( ) - blend_space - > get_min_space ( ) ) ;
point * = s . width ;
points . push_back ( point ) ;
Vector2 gui_point = Vector2 ( point , s . height / 2.0 ) ;
gui_point - = ( icon - > get_size ( ) / 2.0 ) ;
gui_point = gui_point . floor ( ) ;
if ( i = = selected_point ) {
blend_space_draw - > draw_texture ( icon_selected , gui_point ) ;
} else {
blend_space_draw - > draw_texture ( icon , gui_point ) ;
}
}
// blend 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-22 21:52:13 +02:00
} else {
color = linecolor ;
color . a * = 0.5 ;
}
2022-12-13 03:00:11 +09:00
float point = tree - > get ( get_blend_position_path ( ) ) ;
2018-08-20 13:38:18 -03:00
2018-06-22 21:52:13 +02:00
point = ( point - blend_space - > get_min_space ( ) ) / ( blend_space - > get_max_space ( ) - blend_space - > get_min_space ( ) ) ;
point * = s . width ;
Vector2 gui_point = Vector2 ( point , s . height / 2.0 ) ;
float mind = 5 * EDSCALE ;
float maxd = 15 * EDSCALE ;
2022-07-02 18:26:41 +02:00
blend_space_draw - > draw_line ( gui_point + Vector2 ( mind , 0 ) , gui_point + Vector2 ( maxd , 0 ) , color , Math : : round ( 2 * EDSCALE ) ) ;
blend_space_draw - > draw_line ( gui_point + Vector2 ( - mind , 0 ) , gui_point + Vector2 ( - maxd , 0 ) , color , Math : : round ( 2 * EDSCALE ) ) ;
blend_space_draw - > draw_line ( gui_point + Vector2 ( 0 , mind ) , gui_point + Vector2 ( 0 , maxd ) , color , Math : : round ( 2 * EDSCALE ) ) ;
blend_space_draw - > draw_line ( gui_point + Vector2 ( 0 , - mind ) , gui_point + Vector2 ( 0 , - maxd ) , color , Math : : round ( 2 * EDSCALE ) ) ;
2018-06-22 21:52:13 +02:00
}
}
void AnimationNodeBlendSpace1DEditor : : _update_space ( ) {
2020-05-14 16:41:43 +02:00
if ( updating ) {
2018-06-22 21:52:13 +02:00
return ;
2020-05-14 16:41:43 +02:00
}
2018-06-22 21:52:13 +02:00
updating = true ;
max_value - > set_value ( blend_space - > get_max_space ( ) ) ;
min_value - > set_value ( blend_space - > get_min_space ( ) ) ;
2022-06-29 15:35:29 +09:00
sync - > set_pressed ( blend_space - > is_using_sync ( ) ) ;
2023-01-31 02:12:31 +09:00
interpolation - > select ( blend_space - > get_blend_mode ( ) ) ;
2022-06-29 15:35:29 +09:00
2018-06-22 21:52:13 +02:00
label_value - > set_text ( blend_space - > get_value_label ( ) ) ;
snap_value - > set_value ( blend_space - > get_snap ( ) ) ;
2022-08-13 23:21:24 +02:00
blend_space_draw - > queue_redraw ( ) ;
2018-06-22 21:52:13 +02:00
updating = false ;
}
void AnimationNodeBlendSpace1DEditor : : _config_changed ( double ) {
2020-05-14 16:41:43 +02:00
if ( updating ) {
2018-06-22 21:52:13 +02:00
return ;
2020-05-14 16:41:43 +02:00
}
2018-06-22 21:52:13 +02: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 BlendSpace1D Config " ) ) ;
2018-06-22 21:52:13 +02:00
undo_redo - > add_do_method ( blend_space . ptr ( ) , " set_max_space " , max_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 " , min_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 " , snap_value - > 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 ( ) ) ;
2023-01-31 02:12:31 +09: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-22 21:52:13 +02: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-22 21:52:13 +02:00
}
void AnimationNodeBlendSpace1DEditor : : _labels_changed ( String ) {
2020-05-14 16:41:43 +02:00
if ( updating ) {
2018-06-22 21:52:13 +02:00
return ;
2020-05-14 16:41:43 +02:00
}
2018-06-22 21:52:13 +02: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 BlendSpace1D Labels " ) , UndoRedo : : MERGE_ENDS ) ;
2018-06-22 21:52:13 +02:00
undo_redo - > add_do_method ( blend_space . ptr ( ) , " set_value_label " , label_value - > get_text ( ) ) ;
undo_redo - > add_undo_method ( blend_space . ptr ( ) , " set_value_label " , blend_space - > get_value_label ( ) ) ;
undo_redo - > add_do_method ( this , " _update_space " ) ;
undo_redo - > add_undo_method ( this , " _update_space " ) ;
undo_redo - > commit_action ( ) ;
updating = false ;
}
void AnimationNodeBlendSpace1DEditor : : _snap_toggled ( ) {
2022-08-13 23:21:24 +02:00
blend_space_draw - > queue_redraw ( ) ;
2018-06-22 21:52:13 +02:00
}
2018-08-20 13:38:18 -03:00
void AnimationNodeBlendSpace1DEditor : : _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 21:52:13 +02:00
void AnimationNodeBlendSpace1DEditor : : _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 ) ;
2018-06-22 21:52:13 +02:00
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-22 21:52:13 +02:00
2018-08-20 13:38:18 -03:00
node = Ref < AnimationNode > ( an ) ;
}
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-22 21:52:13 +02: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-22 21:52:13 +02: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 ( ) ) ;
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-22 21:52:13 +02:00
}
void AnimationNodeBlendSpace1DEditor : : _add_animation_type ( int p_index ) {
Ref < AnimationNodeAnimation > anim ;
2021-06-17 16:03:09 -06:00
anim . instantiate ( ) ;
2018-06-22 21:52:13 +02: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-22 21:52:13 +02: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 ( ) ) ;
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-22 21:52:13 +02:00
}
void AnimationNodeBlendSpace1DEditor : : _tool_switch ( int p_tool ) {
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-22 21:52:13 +02:00
}
void AnimationNodeBlendSpace1DEditor : : _update_edited_point_pos ( ) {
2020-05-14 16:41:43 +02:00
if ( updating ) {
2018-06-22 21:52:13 +02:00
return ;
2020-05-14 16:41:43 +02:00
}
2018-06-22 21:52:13 +02:00
if ( selected_point > = 0 & & selected_point < blend_space - > get_blend_point_count ( ) ) {
float pos = blend_space - > get_blend_point_position ( selected_point ) ;
if ( dragging_selected ) {
pos + = drag_ofs . x ;
if ( snap - > is_pressed ( ) ) {
2020-12-21 18:02:57 +00:00
pos = Math : : snapped ( pos , blend_space - > get_snap ( ) ) ;
2018-06-22 21:52:13 +02:00
}
}
updating = true ;
edit_value - > set_value ( pos ) ;
updating = false ;
}
}
void AnimationNodeBlendSpace1DEditor : : _update_tool_erase ( ) {
bool point_valid = selected_point > = 0 & & selected_point < blend_space - > get_blend_point_count ( ) ;
2022-05-04 06:31:53 +01:00
tool_erase - > set_disabled ( ! point_valid | | read_only ) ;
2018-06-22 21:52:13 +02:00
if ( point_valid ) {
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-22 21:52:13 +02: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-22 21:52:13 +02:00
} else {
edit_hb - > hide ( ) ;
}
}
void AnimationNodeBlendSpace1DEditor : : _erase_selected ( ) {
if ( selected_point ! = - 1 ) {
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 ( " Remove BlendSpace1D Point " ) ) ;
2018-06-22 21:52:13 +02: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 ) ;
undo_redo - > add_do_method ( this , " _update_space " ) ;
undo_redo - > add_undo_method ( this , " _update_space " ) ;
undo_redo - > commit_action ( ) ;
2025-08-30 17:56:36 +05:30
// Return selection to host BlendSpace1D node.
EditorNode : : get_singleton ( ) - > push_item ( blend_space . ptr ( ) , " " , true ) ;
2018-06-22 21:52:13 +02:00
updating = false ;
2025-08-30 17:56:36 +05:30
_update_tool_erase ( ) ;
2018-06-22 21:52:13 +02:00
2022-08-13 23:21:24 +02:00
blend_space_draw - > queue_redraw ( ) ;
2018-06-22 21:52:13 +02:00
}
}
void AnimationNodeBlendSpace1DEditor : : _edit_point_pos ( double ) {
2020-05-14 16:41:43 +02:00
if ( updating ) {
2018-06-22 21:52:13 +02:00
return ;
2020-05-14 16:41:43 +02:00
}
2018-06-22 21:52:13 +02: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 BlendSpace1D Node Point " ) ) ;
2018-06-22 21:52:13 +02:00
undo_redo - > add_do_method ( blend_space . ptr ( ) , " set_blend_point_position " , selected_point , edit_value - > get_value ( ) ) ;
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 ;
2022-08-13 23:21:24 +02:00
blend_space_draw - > queue_redraw ( ) ;
2018-06-22 21:52:13 +02:00
}
void AnimationNodeBlendSpace1DEditor : : _open_editor ( ) {
if ( selected_point > = 0 & & selected_point < blend_space - > get_blend_point_count ( ) ) {
Ref < AnimationNode > an = blend_space - > get_blend_point_node ( selected_point ) ;
ERR_FAIL_COND ( an . is_null ( ) ) ;
2018-08-20 13:38:18 -03:00
AnimationTreeEditor : : get_singleton ( ) - > enter_editor ( itos ( selected_point ) ) ;
2018-06-22 21:52:13 +02:00
}
}
void AnimationNodeBlendSpace1DEditor : : _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_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 " ) ) ) ;
2023-01-31 02:12:31 +09: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 ( ) ;
2018-06-22 21:52:13 +02: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-22 21:52:13 +02: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-22 21:52:13 +02:00
}
void AnimationNodeBlendSpace1DEditor : : _bind_methods ( ) {
ClassDB : : bind_method ( " _update_space " , & AnimationNodeBlendSpace1DEditor : : _update_space ) ;
ClassDB : : bind_method ( " _update_tool_erase " , & AnimationNodeBlendSpace1DEditor : : _update_tool_erase ) ;
ClassDB : : bind_method ( " _update_edited_point_pos " , & AnimationNodeBlendSpace1DEditor : : _update_edited_point_pos ) ;
}
2018-08-20 13:38:18 -03:00
bool AnimationNodeBlendSpace1DEditor : : can_edit ( const Ref < AnimationNode > & p_node ) {
2018-08-21 21:28:06 +02:00
Ref < AnimationNodeBlendSpace1D > b1d = p_node ;
2018-08-20 13:38:18 -03:00
return b1d . is_valid ( ) ;
}
2018-06-22 21:52:13 +02:00
2018-08-20 13:38:18 -03:00
void AnimationNodeBlendSpace1DEditor : : edit ( const Ref < AnimationNode > & p_node ) {
2018-08-21 21:28:06 +02:00
blend_space = p_node ;
2022-05-04 06:31:53 +01:00
read_only = false ;
2018-08-20 13:38:18 -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 ) ;
2018-06-22 21:52:13 +02:00
_update_space ( ) ;
}
2022-05-04 06:31:53 +01:00
tool_create - > set_disabled ( read_only ) ;
edit_value - > set_editable ( ! read_only ) ;
label_value - > set_editable ( ! read_only ) ;
min_value - > set_editable ( ! read_only ) ;
max_value - > set_editable ( ! read_only ) ;
sync - > set_disabled ( read_only ) ;
2023-01-31 02:12:31 +09:00
interpolation - > set_disabled ( read_only ) ;
2018-06-22 21:52:13 +02:00
}
2020-04-02 01:20:12 +02:00
AnimationNodeBlendSpace1DEditor * AnimationNodeBlendSpace1DEditor : : singleton = nullptr ;
2018-06-22 21:52:13 +02:00
AnimationNodeBlendSpace1DEditor : : AnimationNodeBlendSpace1DEditor ( ) {
singleton = this ;
HBoxContainer * top_hb = memnew ( HBoxContainer ) ;
add_child ( top_hb ) ;
Ref < ButtonGroup > bg ;
2021-06-17 16:03:09 -06:00
bg . instantiate ( ) ;
2018-06-22 21:52:13 +02: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-22 21:52:13 +02: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 , & AnimationNodeBlendSpace1DEditor : : _tool_switch ) . bind ( 0 ) ) ;
2018-06-22 21:52:13 +02: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-22 21:52:13 +02: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 , & AnimationNodeBlendSpace1DEditor : : _tool_switch ) . bind ( 1 ) ) ;
2018-06-22 21:52:13 +02: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 , & AnimationNodeBlendSpace1DEditor : : _tool_switch ) . bind ( 2 ) ) ;
2018-06-22 21:52:13 +02: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-22 21:52:13 +02:00
top_hb - > add_child ( tool_erase ) ;
2022-08-25 12:42:17 +02:00
tool_erase - > set_tooltip_text ( TTR ( " Erase points. " ) ) ;
2024-05-14 09:40:21 +02:00
tool_erase - > connect ( SceneStringName ( pressed ) , callable_mp ( this , & AnimationNodeBlendSpace1DEditor : : _erase_selected ) ) ;
2018-06-22 21:52:13 +02: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-22 21:52:13 +02: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 , & AnimationNodeBlendSpace1DEditor : : _snap_toggled ) ) ;
2018-06-22 21:52:13 +02:00
snap_value = memnew ( SpinBox ) ;
top_hb - > add_child ( snap_value ) ;
snap_value - > set_min ( 0.01 ) ;
snap_value - > set_step ( 0.01 ) ;
snap_value - > set_max ( 1000 ) ;
2025-03-21 09:55:22 +02:00
snap_value - > set_accessibility_name ( TTRC ( " Grid Step " ) ) ;
2018-06-22 21:52:13 +02:00
2022-06-29 15:35:29 +09:00
top_hb - > add_child ( memnew ( VSeparator ) ) ;
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 , & AnimationNodeBlendSpace1DEditor : : _config_changed ) ) ;
2022-06-29 15:35:29 +09:00
2023-01-31 02:12:31 +09:00
top_hb - > add_child ( memnew ( VSeparator ) ) ;
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 , & AnimationNodeBlendSpace1DEditor : : _config_changed ) ) ;
2023-01-31 02:12:31 +09:00
2018-06-22 21:52:13 +02: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_value = memnew ( SpinBox ) ;
edit_hb - > add_child ( edit_value ) ;
edit_value - > set_min ( - 1000 ) ;
edit_value - > set_max ( 1000 ) ;
edit_value - > set_step ( 0.01 ) ;
2025-03-21 09:55:22 +02:00
edit_value - > set_accessibility_name ( TTRC ( " Blend Value " ) ) ;
2024-05-14 11:42:00 +02:00
edit_value - > connect ( SceneStringName ( value_changed ) , callable_mp ( this , & AnimationNodeBlendSpace1DEditor : : _edit_point_pos ) ) ;
2018-06-22 21:52:13 +02: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 , & AnimationNodeBlendSpace1DEditor : : _open_editor ) , CONNECT_DEFERRED ) ;
2018-06-22 21:52:13 +02:00
edit_hb - > hide ( ) ;
open_editor - > hide ( ) ;
VBoxContainer * main_vb = memnew ( VBoxContainer ) ;
add_child ( main_vb ) ;
main_vb - > set_v_size_flags ( SIZE_EXPAND_FILL ) ;
panel = memnew ( PanelContainer ) ;
panel - > set_clip_contents ( true ) ;
main_vb - > add_child ( panel ) ;
panel - > set_h_size_flags ( SIZE_EXPAND_FILL ) ;
panel - > set_v_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 , & AnimationNodeBlendSpace1DEditor : : _blend_space_gui_input ) ) ;
blend_space_draw - > connect ( SceneStringName ( draw ) , callable_mp ( this , & AnimationNodeBlendSpace1DEditor : : _blend_space_draw ) ) ;
2018-06-22 21:52:13 +02:00
blend_space_draw - > set_focus_mode ( FOCUS_ALL ) ;
panel - > add_child ( blend_space_draw ) ;
{
HBoxContainer * bottom_hb = memnew ( HBoxContainer ) ;
main_vb - > add_child ( bottom_hb ) ;
bottom_hb - > set_h_size_flags ( SIZE_EXPAND_FILL ) ;
min_value = memnew ( SpinBox ) ;
min_value - > set_min ( - 10000 ) ;
2019-11-26 10:25:41 +01:00
min_value - > set_max ( 0 ) ;
2018-06-22 21:52:13 +02:00
min_value - > set_step ( 0.01 ) ;
2025-03-21 09:55:22 +02:00
min_value - > set_accessibility_name ( TTRC ( " Min " ) ) ;
2018-06-22 21:52:13 +02:00
max_value = memnew ( SpinBox ) ;
max_value - > set_min ( 0.01 ) ;
2019-11-26 10:25:41 +01:00
max_value - > set_max ( 10000 ) ;
2018-06-22 21:52:13 +02:00
max_value - > set_step ( 0.01 ) ;
2025-03-21 09:55:22 +02:00
max_value - > set_accessibility_name ( TTRC ( " Max " ) ) ;
2018-06-22 21:52:13 +02:00
label_value = memnew ( LineEdit ) ;
2021-03-28 19:31:25 +01:00
label_value - > set_expand_to_text_length_enabled ( true ) ;
2025-03-21 09:55:22 +02:00
label_value - > set_accessibility_name ( TTRC ( " Value " ) ) ;
2018-06-22 21:52:13 +02:00
// now add
bottom_hb - > add_child ( min_value ) ;
bottom_hb - > add_spacer ( ) ;
bottom_hb - > add_child ( label_value ) ;
bottom_hb - > add_spacer ( ) ;
bottom_hb - > add_child ( max_value ) ;
}
2024-05-14 11:42:00 +02:00
snap_value - > connect ( SceneStringName ( value_changed ) , callable_mp ( this , & AnimationNodeBlendSpace1DEditor : : _config_changed ) ) ;
min_value - > connect ( SceneStringName ( value_changed ) , callable_mp ( this , & AnimationNodeBlendSpace1DEditor : : _config_changed ) ) ;
max_value - > connect ( SceneStringName ( value_changed ) , callable_mp ( this , & AnimationNodeBlendSpace1DEditor : : _config_changed ) ) ;
label_value - > connect ( SceneStringName ( text_changed ) , callable_mp ( this , & AnimationNodeBlendSpace1DEditor : : _labels_changed ) ) ;
2018-06-22 21:52:13 +02: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-22 21:52:13 +02:00
error_panel - > add_child ( error_label ) ;
2025-08-20 09:07:49 +05:30
error_panel - > hide ( ) ;
2018-06-22 21:52:13 +02:00
menu = memnew ( PopupMenu ) ;
add_child ( menu ) ;
2024-05-14 14:13:31 +02:00
menu - > connect ( SceneStringName ( id_pressed ) , callable_mp ( this , & AnimationNodeBlendSpace1DEditor : : _add_menu_type ) ) ;
2018-06-22 21:52:13 +02: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 , & AnimationNodeBlendSpace1DEditor : : _add_animation_type ) ) ;
2018-06-22 21:52:13 +02: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 , & AnimationNodeBlendSpace1DEditor : : _file_opened ) ) ;
2018-08-20 13:38:18 -03:00
2018-06-22 21:52:13 +02:00
set_custom_minimum_size ( Size2 ( 0 , 150 * EDSCALE ) ) ;
}