2023-01-05 13:25:55 +01:00
/**************************************************************************/
/* sprite_frames_editor_plugin.cpp */
/**************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
/* https://godotengine.org */
/**************************************************************************/
/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
/* "Software"), to deal in the Software without restriction, including */
/* without limitation the rights to use, copy, modify, merge, publish, */
/* distribute, sublicense, and/or sell copies of the Software, and to */
/* permit persons to whom the Software is furnished to do so, subject to */
/* the following conditions: */
/* */
/* The above copyright notice and this permission notice shall be */
/* included in all copies or substantial portions of the Software. */
/* */
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/**************************************************************************/
2018-01-05 00:50:27 +01:00
2014-02-10 02:10:30 +01:00
# include "sprite_frames_editor_plugin.h"
2020-11-07 23:33:38 +01:00
# include "core/config/project_settings.h"
2018-09-11 18:13:45 +02:00
# include "core/io/resource_loader.h"
2021-01-12 00:51:59 +01:00
# include "core/os/keyboard.h"
2022-02-12 02:46:22 +01:00
# include "editor/editor_file_dialog.h"
2022-11-19 12:45:49 +01:00
# include "editor/editor_file_system.h"
2022-02-12 02:46:22 +01:00
# include "editor/editor_node.h"
2019-12-24 08:17:23 +01:00
# include "editor/editor_scale.h"
2017-03-05 14:21:25 +01:00
# include "editor/editor_settings.h"
2022-03-25 18:06:46 +01:00
# include "editor/editor_undo_redo_manager.h"
2022-02-12 02:46:22 +01:00
# include "editor/scene_tree_dock.h"
2016-06-29 22:51:10 +02:00
# include "scene/3d/sprite_3d.h"
2019-12-24 08:17:23 +01:00
# include "scene/gui/center_container.h"
2020-08-13 13:15:08 +02:00
# include "scene/gui/margin_container.h"
# include "scene/gui/panel_container.h"
2022-11-19 12:45:49 +01:00
# include "scene/gui/separator.h"
2014-02-10 02:10:30 +01:00
2022-04-09 11:30:00 +02:00
static void _draw_shadowed_line ( Control * p_control , const Point2 & p_from , const Size2 & p_size , const Size2 & p_shadow_offset , Color p_color , Color p_shadow_color ) {
p_control - > draw_line ( p_from , p_from + p_size , p_color ) ;
p_control - > draw_line ( p_from + p_shadow_offset , p_from + p_size + p_shadow_offset , p_shadow_color ) ;
}
2019-04-14 03:15:31 +02:00
void SpriteFramesEditor : : _open_sprite_sheet ( ) {
file_split_sheet - > clear_filters ( ) ;
List < String > extensions ;
2019-06-11 20:43:37 +02:00
ResourceLoader : : get_recognized_extensions_for_type ( " Texture2D " , & extensions ) ;
2019-04-14 03:15:31 +02:00
for ( int i = 0 ; i < extensions . size ( ) ; i + + ) {
file_split_sheet - > add_filter ( " *. " + extensions [ i ] ) ;
}
2020-07-11 18:45:19 +02:00
file_split_sheet - > popup_file_dialog ( ) ;
2019-04-14 03:15:31 +02:00
}
2021-09-07 15:27:19 +02:00
int SpriteFramesEditor : : _sheet_preview_position_to_frame_index ( const Point2 & p_position ) {
2022-04-09 11:30:00 +02:00
const Size2i offset = _get_offset ( ) ;
const Size2i frame_size = _get_frame_size ( ) ;
const Size2i separation = _get_separation ( ) ;
const Size2i block_size = frame_size + separation ;
const Point2i position = p_position / sheet_zoom - offset ;
2021-09-07 15:27:19 +02:00
2022-10-30 21:26:58 +01:00
if ( position . x < 0 | | position . y < 0 ) {
return - 1 ; // Out of bounds.
}
if ( position . x % block_size . x > = frame_size . x | | position . y % block_size . y > = frame_size . y ) {
2022-04-09 11:30:00 +02:00
return - 1 ; // Gap between frames.
2021-09-07 15:27:19 +02:00
}
2022-04-09 11:30:00 +02:00
const Point2i frame = position / block_size ;
const Size2i frame_count = _get_frame_count ( ) ;
2022-10-30 21:26:58 +01:00
if ( frame . x > = frame_count . x | | frame . y > = frame_count . y ) {
return - 1 ; // Out of bounds.
2021-09-07 15:27:19 +02:00
}
2022-04-09 11:30:00 +02:00
return frame_count . x * frame . y + frame . x ;
2021-09-07 15:27:19 +02:00
}
2019-04-14 03:15:31 +02:00
void SpriteFramesEditor : : _sheet_preview_draw ( ) {
2022-04-09 11:30:00 +02:00
const Size2i frame_count = _get_frame_count ( ) ;
const Size2i separation = _get_separation ( ) ;
const Size2 draw_offset = Size2 ( _get_offset ( ) ) * sheet_zoom ;
const Size2 draw_sep = Size2 ( separation ) * sheet_zoom ;
const Size2 draw_frame_size = Size2 ( _get_frame_size ( ) ) * sheet_zoom ;
const Size2 draw_size = draw_frame_size * frame_count + draw_sep * ( frame_count - Size2i ( 1 , 1 ) ) ;
const Color line_color = Color ( 1 , 1 , 1 , 0.3 ) ;
const Color shadow_color = Color ( 0 , 0 , 0 , 0.3 ) ;
// Vertical lines.
_draw_shadowed_line ( split_sheet_preview , draw_offset , Vector2 ( 0 , draw_size . y ) , Vector2 ( 1 , 0 ) , line_color , shadow_color ) ;
for ( int i = 0 ; i < frame_count . x - 1 ; i + + ) {
const Point2 start = draw_offset + Vector2 ( i * draw_sep . x + ( i + 1 ) * draw_frame_size . x , 0 ) ;
if ( separation . x = = 0 ) {
_draw_shadowed_line ( split_sheet_preview , start , Vector2 ( 0 , draw_size . y ) , Vector2 ( 1 , 0 ) , line_color , shadow_color ) ;
} else {
const Size2 size = Size2 ( draw_sep . x , draw_size . y ) ;
split_sheet_preview - > draw_rect ( Rect2 ( start , size ) , line_color ) ;
}
2021-07-21 01:01:08 +02:00
}
2022-04-09 11:30:00 +02:00
_draw_shadowed_line ( split_sheet_preview , draw_offset + Vector2 ( draw_size . x , 0 ) , Vector2 ( 0 , draw_size . y ) , Vector2 ( 1 , 0 ) , line_color , shadow_color ) ;
// Horizontal lines.
_draw_shadowed_line ( split_sheet_preview , draw_offset , Vector2 ( draw_size . x , 0 ) , Vector2 ( 0 , 1 ) , line_color , shadow_color ) ;
for ( int i = 0 ; i < frame_count . y - 1 ; i + + ) {
const Point2 start = draw_offset + Vector2 ( 0 , i * draw_sep . y + ( i + 1 ) * draw_frame_size . y ) ;
if ( separation . y = = 0 ) {
_draw_shadowed_line ( split_sheet_preview , start , Vector2 ( draw_size . x , 0 ) , Vector2 ( 0 , 1 ) , line_color , shadow_color ) ;
} else {
const Size2 size = Size2 ( draw_size . x , draw_sep . y ) ;
split_sheet_preview - > draw_rect ( Rect2 ( start , size ) , line_color ) ;
}
2019-04-14 03:15:31 +02:00
}
2022-04-09 11:30:00 +02:00
_draw_shadowed_line ( split_sheet_preview , draw_offset + Vector2 ( 0 , draw_size . y ) , Vector2 ( draw_size . x , 0 ) , Vector2 ( 0 , 1 ) , line_color , shadow_color ) ;
2019-04-14 03:15:31 +02:00
2019-05-11 22:18:12 +02:00
if ( frames_selected . size ( ) = = 0 ) {
2020-12-14 19:37:30 +01:00
split_sheet_dialog - > get_ok_button ( ) - > set_disabled ( true ) ;
2022-07-08 02:31:19 +02:00
split_sheet_dialog - > set_ok_button_text ( TTR ( " No Frames Selected " ) ) ;
2019-05-11 22:18:12 +02:00
return ;
}
2022-04-09 11:30:00 +02:00
Color accent = get_theme_color ( " accent_color " , " Editor " ) ;
2019-04-14 03:15:31 +02:00
2022-05-19 01:43:40 +02:00
for ( const int & E : frames_selected ) {
const int idx = E ;
2022-04-09 11:30:00 +02:00
const int x = idx % frame_count . x ;
const int y = idx / frame_count . x ;
const Point2 pos = draw_offset + Point2 ( x , y ) * ( draw_frame_size + draw_sep ) ;
split_sheet_preview - > draw_rect ( Rect2 ( pos + Size2 ( 5 , 5 ) , draw_frame_size - Size2 ( 10 , 10 ) ) , Color ( 0 , 0 , 0 , 0.35 ) , true ) ;
split_sheet_preview - > draw_rect ( Rect2 ( pos , draw_frame_size ) , Color ( 0 , 0 , 0 , 1 ) , false ) ;
split_sheet_preview - > draw_rect ( Rect2 ( pos + Size2 ( 1 , 1 ) , draw_frame_size - Size2 ( 2 , 2 ) ) , Color ( 0 , 0 , 0 , 1 ) , false ) ;
split_sheet_preview - > draw_rect ( Rect2 ( pos + Size2 ( 2 , 2 ) , draw_frame_size - Size2 ( 4 , 4 ) ) , accent , false ) ;
split_sheet_preview - > draw_rect ( Rect2 ( pos + Size2 ( 3 , 3 ) , draw_frame_size - Size2 ( 6 , 6 ) ) , accent , false ) ;
split_sheet_preview - > draw_rect ( Rect2 ( pos + Size2 ( 4 , 4 ) , draw_frame_size - Size2 ( 8 , 8 ) ) , Color ( 0 , 0 , 0 , 1 ) , false ) ;
split_sheet_preview - > draw_rect ( Rect2 ( pos + Size2 ( 5 , 5 ) , draw_frame_size - Size2 ( 10 , 10 ) ) , Color ( 0 , 0 , 0 , 1 ) , false ) ;
2019-04-14 03:15:31 +02:00
}
2020-12-14 19:37:30 +01:00
split_sheet_dialog - > get_ok_button ( ) - > set_disabled ( false ) ;
2022-07-08 02:31:19 +02:00
split_sheet_dialog - > set_ok_button_text ( vformat ( TTR ( " Add %d Frame(s) " ) , frames_selected . size ( ) ) ) ;
2019-04-14 03:15:31 +02:00
}
2020-05-14 14:29:06 +02:00
2019-04-14 03:15:31 +02:00
void SpriteFramesEditor : : _sheet_preview_input ( const Ref < InputEvent > & p_event ) {
2021-04-11 18:53:23 +02:00
const Ref < InputEventMouseButton > mb = p_event ;
2021-08-13 23:31:57 +02:00
if ( mb . is_valid ( ) & & mb - > is_pressed ( ) & & mb - > get_button_index ( ) = = MouseButton : : LEFT ) {
2021-09-07 15:27:19 +02:00
const int idx = _sheet_preview_position_to_frame_index ( mb - > get_position ( ) ) ;
if ( idx ! = - 1 ) {
if ( mb - > is_shift_pressed ( ) & & last_frame_selected > = 0 ) {
//select multiple
int from = idx ;
int to = last_frame_selected ;
if ( from > to ) {
SWAP ( from , to ) ;
}
2019-04-14 03:15:31 +02:00
2021-09-07 15:27:19 +02:00
for ( int i = from ; i < = to ; i + + ) {
// Prevent double-toggling the same frame when moving the mouse when the mouse button is still held.
frames_toggled_by_mouse_hover . insert ( idx ) ;
2019-04-14 03:15:31 +02:00
2021-09-07 15:27:19 +02:00
if ( mb - > is_ctrl_pressed ( ) ) {
frames_selected . erase ( i ) ;
} else {
frames_selected . insert ( i ) ;
}
}
} else {
2021-04-11 18:53:23 +02:00
// Prevent double-toggling the same frame when moving the mouse when the mouse button is still held.
frames_toggled_by_mouse_hover . insert ( idx ) ;
2021-09-07 15:27:19 +02:00
if ( frames_selected . has ( idx ) ) {
frames_selected . erase ( idx ) ;
2019-04-14 03:15:31 +02:00
} else {
2021-09-07 15:27:19 +02:00
frames_selected . insert ( idx ) ;
2019-04-14 03:15:31 +02:00
}
}
}
2021-09-07 15:27:19 +02:00
if ( last_frame_selected ! = idx | | idx ! = - 1 ) {
last_frame_selected = idx ;
2022-08-13 23:21:24 +02:00
split_sheet_preview - > queue_redraw ( ) ;
2021-09-07 15:27:19 +02:00
}
2019-04-14 03:15:31 +02:00
}
2021-04-11 18:53:23 +02:00
2021-08-13 23:31:57 +02:00
if ( mb . is_valid ( ) & & ! mb - > is_pressed ( ) & & mb - > get_button_index ( ) = = MouseButton : : LEFT ) {
2021-04-11 18:53:23 +02:00
frames_toggled_by_mouse_hover . clear ( ) ;
}
const Ref < InputEventMouseMotion > mm = p_event ;
2023-01-08 00:55:54 +01:00
if ( mm . is_valid ( ) & & ( mm - > get_button_mask ( ) . has_flag ( MouseButtonMask : : LEFT ) ) ) {
2021-04-11 18:53:23 +02:00
// Select by holding down the mouse button on frames.
2021-09-07 15:27:19 +02:00
const int idx = _sheet_preview_position_to_frame_index ( mm - > get_position ( ) ) ;
2021-04-11 18:53:23 +02:00
2021-09-07 15:27:19 +02:00
if ( idx ! = - 1 & & ! frames_toggled_by_mouse_hover . has ( idx ) ) {
2021-04-11 18:53:23 +02:00
// Only allow toggling each tile once per mouse hold.
// Otherwise, the selection would constantly "flicker" in and out when moving the mouse cursor.
// The mouse button must be released before it can be toggled again.
frames_toggled_by_mouse_hover . insert ( idx ) ;
if ( frames_selected . has ( idx ) ) {
frames_selected . erase ( idx ) ;
} else {
frames_selected . insert ( idx ) ;
}
last_frame_selected = idx ;
2022-08-13 23:21:24 +02:00
split_sheet_preview - > queue_redraw ( ) ;
2021-04-11 18:53:23 +02:00
}
}
2019-04-14 03:15:31 +02:00
}
2020-08-13 13:15:08 +02:00
void SpriteFramesEditor : : _sheet_scroll_input ( const Ref < InputEvent > & p_event ) {
const Ref < InputEventMouseButton > mb = p_event ;
if ( mb . is_valid ( ) ) {
// Zoom in/out using Ctrl + mouse wheel. This is done on the ScrollContainer
// to allow performing this action anywhere, even if the cursor isn't
// hovering the texture in the workspace.
2021-08-13 23:31:57 +02:00
if ( mb - > get_button_index ( ) = = MouseButton : : WHEEL_UP & & mb - > is_pressed ( ) & & mb - > is_ctrl_pressed ( ) ) {
2022-03-14 14:19:35 +01:00
_sheet_zoom_on_position ( scale_ratio , mb - > get_position ( ) ) ;
2020-08-13 13:15:08 +02:00
// Don't scroll up after zooming in.
2022-03-14 14:19:35 +01:00
split_sheet_scroll - > accept_event ( ) ;
2021-08-13 23:31:57 +02:00
} else if ( mb - > get_button_index ( ) = = MouseButton : : WHEEL_DOWN & & mb - > is_pressed ( ) & & mb - > is_ctrl_pressed ( ) ) {
2022-03-14 14:19:35 +01:00
_sheet_zoom_on_position ( 1 / scale_ratio , mb - > get_position ( ) ) ;
2020-08-13 13:15:08 +02:00
// Don't scroll down after zooming out.
2022-03-14 14:19:35 +01:00
split_sheet_scroll - > accept_event ( ) ;
2020-08-13 13:15:08 +02:00
}
}
2022-03-14 14:19:35 +01:00
const Ref < InputEventMouseMotion > mm = p_event ;
2023-01-08 00:55:54 +01:00
if ( mm . is_valid ( ) & & mm - > get_button_mask ( ) . has_flag ( MouseButtonMask : : MIDDLE ) ) {
2022-03-14 14:19:35 +01:00
const Vector2 dragged = Input : : get_singleton ( ) - > warp_mouse_motion ( mm , split_sheet_scroll - > get_global_rect ( ) ) ;
split_sheet_scroll - > set_h_scroll ( split_sheet_scroll - > get_h_scroll ( ) - dragged . x ) ;
split_sheet_scroll - > set_v_scroll ( split_sheet_scroll - > get_v_scroll ( ) - dragged . y ) ;
}
2020-08-13 13:15:08 +02:00
}
2019-04-14 03:15:31 +02:00
void SpriteFramesEditor : : _sheet_add_frames ( ) {
2022-04-09 11:30:00 +02:00
const Size2i frame_count = _get_frame_count ( ) ;
const Size2i frame_size = _get_frame_size ( ) ;
const Size2i offset = _get_offset ( ) ;
const Size2i separation = _get_separation ( ) ;
2019-04-14 03:15:31 +02:00
2022-12-23 23:53:16 +01:00
EditorUndoRedoManager * undo_redo = EditorUndoRedoManager : : get_singleton ( ) ;
2019-04-14 03:15:31 +02:00
undo_redo - > create_action ( TTR ( " Add Frame " ) ) ;
int fc = frames - > get_frame_count ( edited_anim ) ;
2022-05-19 01:43:40 +02:00
for ( const int & E : frames_selected ) {
int idx = E ;
2022-04-09 11:30:00 +02:00
const Point2 frame_coords ( idx % frame_count . x , idx / frame_count . x ) ;
2021-07-29 20:18:39 +02:00
2019-04-14 03:15:31 +02:00
Ref < AtlasTexture > at ;
2021-06-18 00:03:09 +02:00
at . instantiate ( ) ;
2019-04-14 03:15:31 +02:00
at - > set_atlas ( split_sheet_preview - > get_texture ( ) ) ;
2022-04-09 11:30:00 +02:00
at - > set_region ( Rect2 ( offset + frame_coords * ( frame_size + separation ) , frame_size ) ) ;
2019-04-14 03:15:31 +02:00
2022-11-26 15:00:38 +01:00
undo_redo - > add_do_method ( frames , " add_frame " , edited_anim , at , 1.0 , - 1 ) ;
2019-04-14 03:15:31 +02:00
undo_redo - > add_undo_method ( frames , " remove_frame " , edited_anim , fc ) ;
}
undo_redo - > add_do_method ( this , " _update_library " ) ;
undo_redo - > add_undo_method ( this , " _update_library " ) ;
undo_redo - > commit_action ( ) ;
}
2022-03-14 14:19:35 +01:00
void SpriteFramesEditor : : _sheet_zoom_on_position ( float p_zoom , const Vector2 & p_position ) {
const float old_zoom = sheet_zoom ;
sheet_zoom = CLAMP ( sheet_zoom * p_zoom , min_sheet_zoom , max_sheet_zoom ) ;
const Size2 texture_size = split_sheet_preview - > get_texture ( ) - > get_size ( ) ;
split_sheet_preview - > set_custom_minimum_size ( texture_size * sheet_zoom ) ;
Vector2 offset = Vector2 ( split_sheet_scroll - > get_h_scroll ( ) , split_sheet_scroll - > get_v_scroll ( ) ) ;
offset = ( offset + p_position ) / old_zoom * sheet_zoom - p_position ;
split_sheet_scroll - > set_h_scroll ( offset . x ) ;
split_sheet_scroll - > set_v_scroll ( offset . y ) ;
}
2020-08-13 13:15:08 +02:00
void SpriteFramesEditor : : _sheet_zoom_in ( ) {
2022-03-14 14:19:35 +01:00
_sheet_zoom_on_position ( scale_ratio , Vector2 ( ) ) ;
2020-08-13 13:15:08 +02:00
}
void SpriteFramesEditor : : _sheet_zoom_out ( ) {
2022-03-14 14:19:35 +01:00
_sheet_zoom_on_position ( 1 / scale_ratio , Vector2 ( ) ) ;
2020-08-13 13:15:08 +02:00
}
void SpriteFramesEditor : : _sheet_zoom_reset ( ) {
2021-03-12 19:05:45 +01:00
// Default the zoom to match the editor scale, but don't dezoom on editor scales below 100% to prevent pixel art from looking bad.
2021-05-23 01:03:52 +02:00
sheet_zoom = MAX ( 1.0f , EDSCALE ) ;
2020-08-13 13:15:08 +02:00
Size2 texture_size = split_sheet_preview - > get_texture ( ) - > get_size ( ) ;
split_sheet_preview - > set_custom_minimum_size ( texture_size * sheet_zoom ) ;
}
2019-04-14 08:24:22 +02:00
void SpriteFramesEditor : : _sheet_select_clear_all_frames ( ) {
bool should_clear = true ;
for ( int i = 0 ; i < split_sheet_h - > get_value ( ) * split_sheet_v - > get_value ( ) ; i + + ) {
if ( ! frames_selected . has ( i ) ) {
frames_selected . insert ( i ) ;
should_clear = false ;
}
}
if ( should_clear ) {
frames_selected . clear ( ) ;
}
2022-08-13 23:21:24 +02:00
split_sheet_preview - > queue_redraw ( ) ;
2019-04-14 08:24:22 +02:00
}
2022-04-09 11:30:00 +02:00
void SpriteFramesEditor : : _sheet_spin_changed ( double p_value , int p_dominant_param ) {
if ( updating_split_settings ) {
return ;
}
updating_split_settings = true ;
if ( p_dominant_param ! = PARAM_USE_CURRENT ) {
dominant_param = p_dominant_param ;
}
const Size2i texture_size = split_sheet_preview - > get_texture ( ) - > get_size ( ) ;
const Size2i size = texture_size - _get_offset ( ) ;
switch ( dominant_param ) {
case PARAM_SIZE : {
const Size2i frame_size = _get_frame_size ( ) ;
const Size2i offset_max = texture_size - frame_size ;
split_sheet_offset_x - > set_max ( offset_max . x ) ;
split_sheet_offset_y - > set_max ( offset_max . y ) ;
const Size2i sep_max = size - frame_size * 2 ;
split_sheet_sep_x - > set_max ( sep_max . x ) ;
split_sheet_sep_y - > set_max ( sep_max . y ) ;
const Size2i separation = _get_separation ( ) ;
const Size2i count = ( size + separation ) / ( frame_size + separation ) ;
split_sheet_h - > set_value ( count . x ) ;
split_sheet_v - > set_value ( count . y ) ;
} break ;
case PARAM_FRAME_COUNT : {
const Size2i count = _get_frame_count ( ) ;
const Size2i offset_max = texture_size - count ;
split_sheet_offset_x - > set_max ( offset_max . x ) ;
split_sheet_offset_y - > set_max ( offset_max . y ) ;
const Size2i gap_count = count - Size2i ( 1 , 1 ) ;
split_sheet_sep_x - > set_max ( gap_count . x = = 0 ? size . x : ( size . x - count . x ) / gap_count . x ) ;
split_sheet_sep_y - > set_max ( gap_count . y = = 0 ? size . y : ( size . y - count . y ) / gap_count . y ) ;
const Size2i separation = _get_separation ( ) ;
const Size2i frame_size = ( size - separation * gap_count ) / count ;
split_sheet_size_x - > set_value ( frame_size . x ) ;
split_sheet_size_y - > set_value ( frame_size . y ) ;
} break ;
}
updating_split_settings = false ;
2019-04-14 03:15:31 +02:00
frames_selected . clear ( ) ;
last_frame_selected = - 1 ;
2022-08-13 23:21:24 +02:00
split_sheet_preview - > queue_redraw ( ) ;
2019-04-14 03:15:31 +02:00
}
void SpriteFramesEditor : : _prepare_sprite_sheet ( const String & p_file ) {
2022-02-06 23:39:04 +01:00
Ref < Texture2D > texture = ResourceLoader : : load ( p_file ) ;
2022-11-26 15:00:38 +01:00
if ( texture . is_null ( ) ) {
2019-12-27 03:31:55 +01:00
EditorNode : : get_singleton ( ) - > show_warning ( TTR ( " Unable to load images " ) ) ;
2022-11-26 15:00:38 +01:00
ERR_FAIL_COND ( texture . is_null ( ) ) ;
2019-04-14 03:15:31 +02:00
}
frames_selected . clear ( ) ;
last_frame_selected = - 1 ;
2021-05-23 01:03:52 +02:00
bool new_texture = texture ! = split_sheet_preview - > get_texture ( ) ;
2019-04-14 03:15:31 +02:00
split_sheet_preview - > set_texture ( texture ) ;
2020-08-13 13:15:08 +02:00
if ( new_texture ) {
2022-04-09 11:30:00 +02:00
// Reset spin max.
const Size2i size = texture - > get_size ( ) ;
split_sheet_size_x - > set_max ( size . x ) ;
split_sheet_size_y - > set_max ( size . y ) ;
split_sheet_sep_x - > set_max ( size . x ) ;
split_sheet_sep_y - > set_max ( size . y ) ;
split_sheet_offset_x - > set_max ( size . x ) ;
split_sheet_offset_y - > set_max ( size . y ) ;
// Different texture, reset to 4x4.
dominant_param = PARAM_FRAME_COUNT ;
updating_split_settings = true ;
2020-08-13 13:15:08 +02:00
split_sheet_h - > set_value ( 4 ) ;
split_sheet_v - > set_value ( 4 ) ;
2022-04-09 11:30:00 +02:00
split_sheet_size_x - > set_value ( size . x / 4 ) ;
split_sheet_size_y - > set_value ( size . y / 4 ) ;
split_sheet_sep_x - > set_value ( 0 ) ;
split_sheet_sep_y - > set_value ( 0 ) ;
split_sheet_offset_x - > set_value ( 0 ) ;
split_sheet_offset_y - > set_value ( 0 ) ;
updating_split_settings = false ;
// Reset zoom.
2020-08-13 13:15:08 +02:00
_sheet_zoom_reset ( ) ;
}
2019-04-14 03:15:31 +02:00
split_sheet_dialog - > popup_centered_ratio ( 0.65 ) ;
}
2014-02-10 02:10:30 +01:00
void SpriteFramesEditor : : _notification ( int p_what ) {
2019-04-14 08:24:22 +02:00
switch ( p_what ) {
2022-08-29 11:04:31 +02:00
case NOTIFICATION_ENTER_TREE :
2022-03-14 14:19:35 +01:00
case NOTIFICATION_THEME_CHANGED : {
2021-07-17 23:22:52 +02:00
load - > set_icon ( get_theme_icon ( SNAME ( " Load " ) , SNAME ( " EditorIcons " ) ) ) ;
load_sheet - > set_icon ( get_theme_icon ( SNAME ( " SpriteSheet " ) , SNAME ( " EditorIcons " ) ) ) ;
copy - > set_icon ( get_theme_icon ( SNAME ( " ActionCopy " ) , SNAME ( " EditorIcons " ) ) ) ;
paste - > set_icon ( get_theme_icon ( SNAME ( " ActionPaste " ) , SNAME ( " EditorIcons " ) ) ) ;
2022-09-24 10:01:52 +02:00
empty_before - > set_icon ( get_theme_icon ( SNAME ( " InsertBefore " ) , SNAME ( " EditorIcons " ) ) ) ;
empty_after - > set_icon ( get_theme_icon ( SNAME ( " InsertAfter " ) , SNAME ( " EditorIcons " ) ) ) ;
2021-07-17 23:22:52 +02:00
move_up - > set_icon ( get_theme_icon ( SNAME ( " MoveLeft " ) , SNAME ( " EditorIcons " ) ) ) ;
move_down - > set_icon ( get_theme_icon ( SNAME ( " MoveRight " ) , SNAME ( " EditorIcons " ) ) ) ;
2022-09-24 10:01:52 +02:00
delete_frame - > set_icon ( get_theme_icon ( SNAME ( " Remove " ) , SNAME ( " EditorIcons " ) ) ) ;
2021-07-17 23:22:52 +02:00
zoom_out - > set_icon ( get_theme_icon ( SNAME ( " ZoomLess " ) , SNAME ( " EditorIcons " ) ) ) ;
zoom_reset - > set_icon ( get_theme_icon ( SNAME ( " ZoomReset " ) , SNAME ( " EditorIcons " ) ) ) ;
zoom_in - > set_icon ( get_theme_icon ( SNAME ( " ZoomMore " ) , SNAME ( " EditorIcons " ) ) ) ;
2022-09-24 10:01:52 +02:00
add_anim - > set_icon ( get_theme_icon ( SNAME ( " New " ) , SNAME ( " EditorIcons " ) ) ) ;
delete_anim - > set_icon ( get_theme_icon ( SNAME ( " Remove " ) , SNAME ( " EditorIcons " ) ) ) ;
2021-06-10 15:42:55 +02:00
anim_search_box - > set_right_icon ( get_theme_icon ( SNAME ( " Search " ) , SNAME ( " EditorIcons " ) ) ) ;
2021-07-17 23:22:52 +02:00
split_sheet_zoom_out - > set_icon ( get_theme_icon ( SNAME ( " ZoomLess " ) , SNAME ( " EditorIcons " ) ) ) ;
split_sheet_zoom_reset - > set_icon ( get_theme_icon ( SNAME ( " ZoomReset " ) , SNAME ( " EditorIcons " ) ) ) ;
split_sheet_zoom_in - > set_icon ( get_theme_icon ( SNAME ( " ZoomMore " ) , SNAME ( " EditorIcons " ) ) ) ;
2022-09-06 19:09:32 +02:00
split_sheet_scroll - > add_theme_style_override ( " panel " , get_theme_stylebox ( SNAME ( " panel " ) , SNAME ( " Tree " ) ) ) ;
2019-04-14 08:24:22 +02:00
} break ;
2022-03-14 14:19:35 +01:00
2019-04-14 08:24:22 +02:00
case NOTIFICATION_READY : {
2022-02-08 10:14:58 +01:00
add_theme_constant_override ( " autohide " , 1 ) ; // Fixes the dragger always showing up.
2019-04-14 08:24:22 +02:00
} break ;
2014-02-10 02:10:30 +01:00
}
}
2020-02-17 22:06:54 +01:00
void SpriteFramesEditor : : _file_load_request ( const Vector < String > & p_path , int p_at_pos ) {
2016-05-15 04:48:23 +02:00
ERR_FAIL_COND ( ! frames - > has_animation ( edited_anim ) ) ;
2014-02-10 02:10:30 +01:00
2020-03-17 07:33:00 +01:00
List < Ref < Texture2D > > resources ;
2014-02-10 02:10:30 +01:00
for ( int i = 0 ; i < p_path . size ( ) ; i + + ) {
2019-06-11 20:43:37 +02:00
Ref < Texture2D > resource ;
2014-02-10 02:10:30 +01:00
resource = ResourceLoader : : load ( p_path [ i ] ) ;
if ( resource . is_null ( ) ) {
2016-05-04 03:25:37 +02:00
dialog - > set_text ( TTR ( " ERROR: Couldn't load frame resource! " ) ) ;
dialog - > set_title ( TTR ( " Error! " ) ) ;
2019-04-14 03:15:31 +02:00
2016-05-21 01:18:35 +02:00
//dialog->get_cancel()->set_text("Close");
2022-07-08 02:31:19 +02:00
dialog - > set_ok_button_text ( TTR ( " Close " ) ) ;
2020-03-06 18:00:16 +01:00
dialog - > popup_centered ( ) ;
2014-02-10 02:10:30 +01:00
return ; ///beh should show an error i guess
}
resources . push_back ( resource ) ;
}
2020-12-15 13:04:21 +01:00
if ( resources . is_empty ( ) ) {
2014-02-10 02:10:30 +01:00
return ;
}
2022-12-23 23:53:16 +01:00
EditorUndoRedoManager * undo_redo = EditorUndoRedoManager : : get_singleton ( ) ;
2016-05-04 03:25:37 +02:00
undo_redo - > create_action ( TTR ( " Add Frame " ) ) ;
2016-05-15 04:48:23 +02:00
int fc = frames - > get_frame_count ( edited_anim ) ;
int count = 0 ;
2014-02-10 02:10:30 +01:00
2021-07-26 17:50:35 +02:00
for ( const Ref < Texture2D > & E : resources ) {
2022-11-26 15:00:38 +01:00
undo_redo - > add_do_method ( frames , " add_frame " , edited_anim , E , 1.0 , p_at_pos = = - 1 ? - 1 : p_at_pos + count ) ;
2016-05-15 04:48:23 +02:00
undo_redo - > add_undo_method ( frames , " remove_frame " , edited_anim , p_at_pos = = - 1 ? fc : p_at_pos ) ;
count + + ;
2014-02-10 02:10:30 +01:00
}
undo_redo - > add_do_method ( this , " _update_library " ) ;
undo_redo - > add_undo_method ( this , " _update_library " ) ;
undo_redo - > commit_action ( ) ;
}
2022-04-09 11:30:00 +02:00
Size2i SpriteFramesEditor : : _get_frame_count ( ) const {
return Size2i ( split_sheet_h - > get_value ( ) , split_sheet_v - > get_value ( ) ) ;
}
Size2i SpriteFramesEditor : : _get_frame_size ( ) const {
return Size2i ( split_sheet_size_x - > get_value ( ) , split_sheet_size_y - > get_value ( ) ) ;
}
Size2i SpriteFramesEditor : : _get_offset ( ) const {
return Size2i ( split_sheet_offset_x - > get_value ( ) , split_sheet_offset_y - > get_value ( ) ) ;
}
Size2i SpriteFramesEditor : : _get_separation ( ) const {
return Size2i ( split_sheet_sep_x - > get_value ( ) , split_sheet_sep_y - > get_value ( ) ) ;
}
2014-02-10 02:10:30 +01:00
void SpriteFramesEditor : : _load_pressed ( ) {
2016-05-15 04:48:23 +02:00
ERR_FAIL_COND ( ! frames - > has_animation ( edited_anim ) ) ;
2014-02-10 02:10:30 +01:00
loading_scene = false ;
file - > clear_filters ( ) ;
List < String > extensions ;
2019-06-11 20:43:37 +02:00
ResourceLoader : : get_recognized_extensions_for_type ( " Texture2D " , & extensions ) ;
2020-05-14 16:41:43 +02:00
for ( int i = 0 ; i < extensions . size ( ) ; i + + ) {
2014-02-10 02:10:30 +01:00
file - > add_filter ( " *. " + extensions [ i ] ) ;
2020-05-14 16:41:43 +02:00
}
2014-02-10 02:10:30 +01:00
2020-03-06 18:00:16 +01:00
file - > set_file_mode ( EditorFileDialog : : FILE_MODE_OPEN_FILES ) ;
2020-07-11 18:45:19 +02:00
file - > popup_file_dialog ( ) ;
2014-02-10 02:10:30 +01:00
}
void SpriteFramesEditor : : _paste_pressed ( ) {
2016-05-15 04:48:23 +02:00
ERR_FAIL_COND ( ! frames - > has_animation ( edited_anim ) ) ;
2022-11-26 15:00:38 +01:00
Ref < Texture2D > texture ;
float duration = 1.0 ;
Ref < EditorSpriteFramesFrame > frame = EditorSettings : : get_singleton ( ) - > get_resource_clipboard ( ) ;
if ( frame . is_valid ( ) ) {
texture = frame - > texture ;
duration = frame - > duration ;
} else {
texture = EditorSettings : : get_singleton ( ) - > get_resource_clipboard ( ) ;
}
if ( texture . is_null ( ) ) {
2016-05-04 03:25:37 +02:00
dialog - > set_text ( TTR ( " Resource clipboard is empty or not a texture! " ) ) ;
dialog - > set_title ( TTR ( " Error! " ) ) ;
2016-05-21 01:18:35 +02:00
//dialog->get_cancel()->set_text("Close");
2022-07-08 02:31:19 +02:00
dialog - > set_ok_button_text ( TTR ( " Close " ) ) ;
2020-03-06 18:00:16 +01:00
dialog - > popup_centered ( ) ;
2014-02-10 02:10:30 +01:00
return ; ///beh should show an error i guess
}
2022-12-23 23:53:16 +01:00
EditorUndoRedoManager * undo_redo = EditorUndoRedoManager : : get_singleton ( ) ;
2016-05-04 03:25:37 +02:00
undo_redo - > create_action ( TTR ( " Paste Frame " ) ) ;
2022-11-26 15:00:38 +01:00
undo_redo - > add_do_method ( frames , " add_frame " , edited_anim , texture , duration ) ;
2016-05-15 04:48:23 +02:00
undo_redo - > add_undo_method ( frames , " remove_frame " , edited_anim , frames - > get_frame_count ( edited_anim ) ) ;
2014-02-10 02:10:30 +01:00
undo_redo - > add_do_method ( this , " _update_library " ) ;
undo_redo - > add_undo_method ( this , " _update_library " ) ;
undo_redo - > commit_action ( ) ;
}
2017-10-27 06:25:13 +02:00
void SpriteFramesEditor : : _copy_pressed ( ) {
ERR_FAIL_COND ( ! frames - > has_animation ( edited_anim ) ) ;
2022-11-26 15:00:38 +01:00
if ( frame_list - > get_current ( ) < 0 ) {
2017-10-27 06:25:13 +02:00
return ;
2020-05-14 16:41:43 +02:00
}
2022-11-26 15:00:38 +01:00
Ref < Texture2D > texture = frames - > get_frame_texture ( edited_anim , frame_list - > get_current ( ) ) ;
if ( texture . is_null ( ) ) {
2017-10-27 06:25:13 +02:00
return ;
}
2022-11-26 15:00:38 +01:00
Ref < EditorSpriteFramesFrame > frame = memnew ( EditorSpriteFramesFrame ) ;
frame - > texture = texture ;
frame - > duration = frames - > get_frame_duration ( edited_anim , frame_list - > get_current ( ) ) ;
EditorSettings : : get_singleton ( ) - > set_resource_clipboard ( frame ) ;
2017-10-27 06:25:13 +02:00
}
2014-02-10 02:10:30 +01:00
void SpriteFramesEditor : : _empty_pressed ( ) {
2016-05-15 04:48:23 +02:00
ERR_FAIL_COND ( ! frames - > has_animation ( edited_anim ) ) ;
2014-02-10 02:10:30 +01:00
int from = - 1 ;
2022-11-26 15:00:38 +01:00
if ( frame_list - > get_current ( ) > = 0 ) {
from = frame_list - > get_current ( ) ;
2014-02-10 02:10:30 +01:00
sel = from ;
} else {
2016-05-15 04:48:23 +02:00
from = frames - > get_frame_count ( edited_anim ) ;
2014-02-10 02:10:30 +01:00
}
2022-11-26 15:00:38 +01:00
Ref < Texture2D > texture ;
2014-02-10 02:10:30 +01:00
2022-12-23 23:53:16 +01:00
EditorUndoRedoManager * undo_redo = EditorUndoRedoManager : : get_singleton ( ) ;
2016-05-04 03:25:37 +02:00
undo_redo - > create_action ( TTR ( " Add Empty " ) ) ;
2022-11-26 15:00:38 +01:00
undo_redo - > add_do_method ( frames , " add_frame " , edited_anim , texture , 1.0 , from ) ;
2016-05-15 04:48:23 +02:00
undo_redo - > add_undo_method ( frames , " remove_frame " , edited_anim , from ) ;
2014-02-10 02:10:30 +01:00
undo_redo - > add_do_method ( this , " _update_library " ) ;
undo_redo - > add_undo_method ( this , " _update_library " ) ;
undo_redo - > commit_action ( ) ;
}
2015-04-02 12:22:17 +02:00
void SpriteFramesEditor : : _empty2_pressed ( ) {
2016-05-15 04:48:23 +02:00
ERR_FAIL_COND ( ! frames - > has_animation ( edited_anim ) ) ;
2015-04-02 12:22:17 +02:00
int from = - 1 ;
2022-11-26 15:00:38 +01:00
if ( frame_list - > get_current ( ) > = 0 ) {
from = frame_list - > get_current ( ) ;
2015-04-02 12:22:17 +02:00
sel = from ;
} else {
2016-05-15 04:48:23 +02:00
from = frames - > get_frame_count ( edited_anim ) ;
2015-04-02 12:22:17 +02:00
}
2022-11-26 15:00:38 +01:00
Ref < Texture2D > texture ;
2015-04-02 12:22:17 +02:00
2022-12-23 23:53:16 +01:00
EditorUndoRedoManager * undo_redo = EditorUndoRedoManager : : get_singleton ( ) ;
2016-05-04 03:25:37 +02:00
undo_redo - > create_action ( TTR ( " Add Empty " ) ) ;
2022-11-26 15:00:38 +01:00
undo_redo - > add_do_method ( frames , " add_frame " , edited_anim , texture , 1.0 , from + 1 ) ;
2016-05-15 04:48:23 +02:00
undo_redo - > add_undo_method ( frames , " remove_frame " , edited_anim , from + 1 ) ;
2015-04-02 12:22:17 +02:00
undo_redo - > add_do_method ( this , " _update_library " ) ;
undo_redo - > add_undo_method ( this , " _update_library " ) ;
undo_redo - > commit_action ( ) ;
}
2014-02-10 02:10:30 +01:00
void SpriteFramesEditor : : _up_pressed ( ) {
2016-05-15 04:48:23 +02:00
ERR_FAIL_COND ( ! frames - > has_animation ( edited_anim ) ) ;
2022-11-26 15:00:38 +01:00
if ( frame_list - > get_current ( ) < 0 ) {
2014-02-10 02:10:30 +01:00
return ;
2020-05-14 16:41:43 +02:00
}
2016-05-15 04:48:23 +02:00
2022-11-26 15:00:38 +01:00
int to_move = frame_list - > get_current ( ) ;
2020-05-14 16:41:43 +02:00
if ( to_move < 1 ) {
2014-02-10 02:10:30 +01:00
return ;
2020-05-14 16:41:43 +02:00
}
2014-02-10 02:10:30 +01:00
sel = to_move ;
sel - = 1 ;
2022-12-23 23:53:16 +01:00
EditorUndoRedoManager * undo_redo = EditorUndoRedoManager : : get_singleton ( ) ;
2022-11-26 15:00:38 +01:00
undo_redo - > create_action ( TTR ( " Move Frame " ) ) ;
undo_redo - > add_do_method ( frames , " set_frame " , edited_anim , to_move , frames - > get_frame_texture ( edited_anim , to_move - 1 ) , frames - > get_frame_duration ( edited_anim , to_move - 1 ) ) ;
undo_redo - > add_do_method ( frames , " set_frame " , edited_anim , to_move - 1 , frames - > get_frame_texture ( edited_anim , to_move ) , frames - > get_frame_duration ( edited_anim , to_move ) ) ;
undo_redo - > add_undo_method ( frames , " set_frame " , edited_anim , to_move , frames - > get_frame_texture ( edited_anim , to_move ) , frames - > get_frame_duration ( edited_anim , to_move ) ) ;
undo_redo - > add_undo_method ( frames , " set_frame " , edited_anim , to_move - 1 , frames - > get_frame_texture ( edited_anim , to_move - 1 ) , frames - > get_frame_duration ( edited_anim , to_move - 1 ) ) ;
2014-02-10 02:10:30 +01:00
undo_redo - > add_do_method ( this , " _update_library " ) ;
undo_redo - > add_undo_method ( this , " _update_library " ) ;
undo_redo - > commit_action ( ) ;
}
void SpriteFramesEditor : : _down_pressed ( ) {
2016-05-15 04:48:23 +02:00
ERR_FAIL_COND ( ! frames - > has_animation ( edited_anim ) ) ;
2022-11-26 15:00:38 +01:00
if ( frame_list - > get_current ( ) < 0 ) {
2014-02-10 02:10:30 +01:00
return ;
2020-05-14 16:41:43 +02:00
}
2016-05-15 04:48:23 +02:00
2022-11-26 15:00:38 +01:00
int to_move = frame_list - > get_current ( ) ;
2020-05-14 16:41:43 +02:00
if ( to_move < 0 | | to_move > = frames - > get_frame_count ( edited_anim ) - 1 ) {
2014-02-10 02:10:30 +01:00
return ;
2020-05-14 16:41:43 +02:00
}
2014-02-10 02:10:30 +01:00
sel = to_move ;
sel + = 1 ;
2022-12-23 23:53:16 +01:00
EditorUndoRedoManager * undo_redo = EditorUndoRedoManager : : get_singleton ( ) ;
2022-11-26 15:00:38 +01:00
undo_redo - > create_action ( TTR ( " Move Frame " ) ) ;
undo_redo - > add_do_method ( frames , " set_frame " , edited_anim , to_move , frames - > get_frame_texture ( edited_anim , to_move + 1 ) , frames - > get_frame_duration ( edited_anim , to_move + 1 ) ) ;
undo_redo - > add_do_method ( frames , " set_frame " , edited_anim , to_move + 1 , frames - > get_frame_texture ( edited_anim , to_move ) , frames - > get_frame_duration ( edited_anim , to_move ) ) ;
undo_redo - > add_undo_method ( frames , " set_frame " , edited_anim , to_move , frames - > get_frame_texture ( edited_anim , to_move ) , frames - > get_frame_duration ( edited_anim , to_move ) ) ;
undo_redo - > add_undo_method ( frames , " set_frame " , edited_anim , to_move + 1 , frames - > get_frame_texture ( edited_anim , to_move + 1 ) , frames - > get_frame_duration ( edited_anim , to_move + 1 ) ) ;
2014-02-10 02:10:30 +01:00
undo_redo - > add_do_method ( this , " _update_library " ) ;
undo_redo - > add_undo_method ( this , " _update_library " ) ;
undo_redo - > commit_action ( ) ;
}
void SpriteFramesEditor : : _delete_pressed ( ) {
2017-09-02 18:35:42 +02:00
ERR_FAIL_COND ( ! frames - > has_animation ( edited_anim ) ) ;
2022-11-26 15:00:38 +01:00
if ( frame_list - > get_current ( ) < 0 ) {
2014-02-10 02:10:30 +01:00
return ;
2020-05-14 16:41:43 +02:00
}
2017-09-02 18:35:42 +02:00
2022-11-26 15:00:38 +01:00
int to_delete = frame_list - > get_current ( ) ;
2017-09-02 18:35:42 +02:00
if ( to_delete < 0 | | to_delete > = frames - > get_frame_count ( edited_anim ) ) {
return ;
}
2022-12-23 23:53:16 +01:00
EditorUndoRedoManager * undo_redo = EditorUndoRedoManager : : get_singleton ( ) ;
2017-09-02 18:35:42 +02:00
undo_redo - > create_action ( TTR ( " Delete Resource " ) ) ;
undo_redo - > add_do_method ( frames , " remove_frame " , edited_anim , to_delete ) ;
2022-11-26 15:00:38 +01:00
undo_redo - > add_undo_method ( frames , " add_frame " , edited_anim , frames - > get_frame_texture ( edited_anim , to_delete ) , frames - > get_frame_duration ( edited_anim , to_delete ) , to_delete ) ;
2017-09-02 18:35:42 +02:00
undo_redo - > add_do_method ( this , " _update_library " ) ;
undo_redo - > add_undo_method ( this , " _update_library " ) ;
undo_redo - > commit_action ( ) ;
2014-02-10 02:10:30 +01:00
}
2016-05-15 04:48:23 +02:00
void SpriteFramesEditor : : _animation_select ( ) {
2020-05-14 16:41:43 +02:00
if ( updating ) {
2016-05-15 04:48:23 +02:00
return ;
2020-05-14 16:41:43 +02:00
}
2016-05-15 04:48:23 +02:00
2019-09-06 11:07:36 +02:00
if ( frames - > has_animation ( edited_anim ) ) {
2020-07-24 20:07:57 +02:00
double value = anim_speed - > get_line_edit ( ) - > get_text ( ) . to_float ( ) ;
2021-05-20 12:04:41 +02:00
if ( ! Math : : is_equal_approx ( value , ( double ) frames - > get_animation_speed ( edited_anim ) ) ) {
2022-11-26 15:00:38 +01:00
_animation_speed_changed ( value ) ;
2020-05-14 16:41:43 +02:00
}
2019-09-06 11:07:36 +02:00
}
2019-05-07 00:42:32 +02:00
2016-05-15 04:48:23 +02:00
TreeItem * selected = animations - > get_selected ( ) ;
ERR_FAIL_COND ( ! selected ) ;
edited_anim = selected - > get_text ( 0 ) ;
_update_library ( true ) ;
}
2016-06-29 22:51:10 +02:00
static void _find_anim_sprites ( Node * p_node , List < Node * > * r_nodes , Ref < SpriteFrames > p_sfames ) {
Node * edited = EditorNode : : get_singleton ( ) - > get_edited_scene ( ) ;
2020-05-14 16:41:43 +02:00
if ( ! edited ) {
2016-06-29 22:51:10 +02:00
return ;
2020-05-14 16:41:43 +02:00
}
if ( p_node ! = edited & & p_node - > get_owner ( ) ! = edited ) {
2016-06-29 22:51:10 +02:00
return ;
2020-05-14 16:41:43 +02:00
}
2016-06-29 22:51:10 +02:00
{
2020-03-26 22:49:16 +01:00
AnimatedSprite2D * as = Object : : cast_to < AnimatedSprite2D > ( p_node ) ;
2016-06-29 22:51:10 +02:00
if ( as & & as - > get_sprite_frames ( ) = = p_sfames ) {
r_nodes - > push_back ( p_node ) ;
}
}
{
2017-08-24 22:58:51 +02:00
AnimatedSprite3D * as = Object : : cast_to < AnimatedSprite3D > ( p_node ) ;
2016-06-29 22:51:10 +02:00
if ( as & & as - > get_sprite_frames ( ) = = p_sfames ) {
r_nodes - > push_back ( p_node ) ;
}
}
for ( int i = 0 ; i < p_node - > get_child_count ( ) ; i + + ) {
_find_anim_sprites ( p_node - > get_child ( i ) , r_nodes , p_sfames ) ;
}
}
2016-05-15 04:48:23 +02:00
void SpriteFramesEditor : : _animation_name_edited ( ) {
2020-05-14 16:41:43 +02:00
if ( updating ) {
2016-05-15 04:48:23 +02:00
return ;
2020-05-14 16:41:43 +02:00
}
2016-05-15 04:48:23 +02:00
2020-05-14 16:41:43 +02:00
if ( ! frames - > has_animation ( edited_anim ) ) {
2016-05-15 04:48:23 +02:00
return ;
2020-05-14 16:41:43 +02:00
}
2016-05-15 04:48:23 +02:00
TreeItem * edited = animations - > get_edited ( ) ;
2020-05-14 16:41:43 +02:00
if ( ! edited ) {
2016-05-15 04:48:23 +02:00
return ;
2020-05-14 16:41:43 +02:00
}
2016-05-15 04:48:23 +02:00
String new_name = edited - > get_text ( 0 ) ;
2020-05-14 16:41:43 +02:00
if ( new_name = = String ( edited_anim ) ) {
2016-05-15 04:48:23 +02:00
return ;
2020-05-14 16:41:43 +02:00
}
2016-05-15 04:48:23 +02:00
new_name = new_name . replace ( " / " , " _ " ) . replace ( " , " , " " ) ;
String name = new_name ;
int counter = 0 ;
while ( frames - > has_animation ( name ) ) {
counter + + ;
name = new_name + " " + itos ( counter ) ;
}
2016-06-29 22:51:10 +02:00
List < Node * > nodes ;
_find_anim_sprites ( EditorNode : : get_singleton ( ) - > get_edited_scene ( ) , & nodes , Ref < SpriteFrames > ( frames ) ) ;
2022-12-23 23:53:16 +01:00
EditorUndoRedoManager * undo_redo = EditorUndoRedoManager : : get_singleton ( ) ;
2016-05-15 04:48:23 +02:00
undo_redo - > create_action ( TTR ( " Rename Animation " ) ) ;
undo_redo - > add_do_method ( frames , " rename_animation " , edited_anim , name ) ;
undo_redo - > add_undo_method ( frames , " rename_animation " , name , edited_anim ) ;
2016-06-29 22:51:10 +02:00
2021-07-16 05:45:57 +02:00
for ( Node * E : nodes ) {
String current = E - > call ( " get_animation " ) ;
undo_redo - > add_do_method ( E , " set_animation " , name ) ;
undo_redo - > add_undo_method ( E , " set_animation " , edited_anim ) ;
2016-06-29 22:51:10 +02:00
}
2016-05-15 04:48:23 +02:00
undo_redo - > add_do_method ( this , " _update_library " ) ;
undo_redo - > add_undo_method ( this , " _update_library " ) ;
2021-06-10 15:42:55 +02:00
edited_anim = name ;
2016-05-15 04:48:23 +02:00
undo_redo - > commit_action ( ) ;
}
2019-09-06 11:07:36 +02:00
2016-05-15 04:48:23 +02:00
void SpriteFramesEditor : : _animation_add ( ) {
2021-05-09 09:06:37 +02:00
String name = " new_animation " ;
2016-05-15 04:48:23 +02:00
int counter = 0 ;
while ( frames - > has_animation ( name ) ) {
counter + + ;
2021-05-09 09:06:37 +02:00
name = vformat ( " new_animation_%d " , counter ) ;
2016-05-15 04:48:23 +02:00
}
2016-06-29 22:51:10 +02:00
List < Node * > nodes ;
_find_anim_sprites ( EditorNode : : get_singleton ( ) - > get_edited_scene ( ) , & nodes , Ref < SpriteFrames > ( frames ) ) ;
2022-12-23 23:53:16 +01:00
EditorUndoRedoManager * undo_redo = EditorUndoRedoManager : : get_singleton ( ) ;
2016-05-15 04:48:23 +02:00
undo_redo - > create_action ( TTR ( " Add Animation " ) ) ;
undo_redo - > add_do_method ( frames , " add_animation " , name ) ;
undo_redo - > add_undo_method ( frames , " remove_animation " , name ) ;
undo_redo - > add_do_method ( this , " _update_library " ) ;
undo_redo - > add_undo_method ( this , " _update_library " ) ;
2021-07-16 05:45:57 +02:00
for ( Node * E : nodes ) {
String current = E - > call ( " get_animation " ) ;
undo_redo - > add_do_method ( E , " set_animation " , name ) ;
undo_redo - > add_undo_method ( E , " set_animation " , current ) ;
2016-06-29 22:51:10 +02:00
}
2017-11-01 20:40:58 +01:00
edited_anim = name ;
2016-05-15 04:48:23 +02:00
undo_redo - > commit_action ( ) ;
2017-11-27 02:54:26 +01:00
animations - > grab_focus ( ) ;
2016-05-15 04:48:23 +02:00
}
2019-09-06 11:07:36 +02:00
2016-05-15 04:48:23 +02:00
void SpriteFramesEditor : : _animation_remove ( ) {
2020-05-14 16:41:43 +02:00
if ( updating ) {
2016-05-15 04:48:23 +02:00
return ;
2020-05-14 16:41:43 +02:00
}
2016-05-15 04:48:23 +02:00
2020-05-14 16:41:43 +02:00
if ( ! frames - > has_animation ( edited_anim ) ) {
2016-05-15 04:48:23 +02:00
return ;
2020-05-14 16:41:43 +02:00
}
2016-05-15 04:48:23 +02:00
2019-09-06 11:07:36 +02:00
delete_dialog - > set_text ( TTR ( " Delete Animation? " ) ) ;
2020-03-06 18:00:16 +01:00
delete_dialog - > popup_centered ( ) ;
2019-09-06 11:07:36 +02:00
}
void SpriteFramesEditor : : _animation_remove_confirmed ( ) {
2022-12-23 23:53:16 +01:00
EditorUndoRedoManager * undo_redo = EditorUndoRedoManager : : get_singleton ( ) ;
2016-05-15 04:48:23 +02:00
undo_redo - > create_action ( TTR ( " Remove Animation " ) ) ;
undo_redo - > add_do_method ( frames , " remove_animation " , edited_anim ) ;
undo_redo - > add_undo_method ( frames , " add_animation " , edited_anim ) ;
undo_redo - > add_undo_method ( frames , " set_animation_speed " , edited_anim , frames - > get_animation_speed ( edited_anim ) ) ;
undo_redo - > add_undo_method ( frames , " set_animation_loop " , edited_anim , frames - > get_animation_loop ( edited_anim ) ) ;
int fc = frames - > get_frame_count ( edited_anim ) ;
for ( int i = 0 ; i < fc ; i + + ) {
2022-11-26 15:00:38 +01:00
Ref < Texture2D > texture = frames - > get_frame_texture ( edited_anim , i ) ;
float duration = frames - > get_frame_duration ( edited_anim , i ) ;
undo_redo - > add_undo_method ( frames , " add_frame " , edited_anim , texture , duration ) ;
2016-05-15 04:48:23 +02:00
}
undo_redo - > add_do_method ( this , " _update_library " ) ;
undo_redo - > add_undo_method ( this , " _update_library " ) ;
2019-09-06 11:07:36 +02:00
edited_anim = StringName ( ) ;
2016-05-15 04:48:23 +02:00
undo_redo - > commit_action ( ) ;
}
2021-06-10 15:42:55 +02:00
void SpriteFramesEditor : : _animation_search_text_changed ( const String & p_text ) {
_update_library ( ) ;
}
2016-05-15 04:48:23 +02:00
void SpriteFramesEditor : : _animation_loop_changed ( ) {
2020-05-14 16:41:43 +02:00
if ( updating ) {
2016-05-15 04:48:23 +02:00
return ;
2020-05-14 16:41:43 +02:00
}
2016-05-15 04:48:23 +02:00
2022-12-23 23:53:16 +01:00
EditorUndoRedoManager * undo_redo = EditorUndoRedoManager : : get_singleton ( ) ;
2016-05-15 04:48:23 +02:00
undo_redo - > create_action ( TTR ( " Change Animation Loop " ) ) ;
undo_redo - > add_do_method ( frames , " set_animation_loop " , edited_anim , anim_loop - > is_pressed ( ) ) ;
undo_redo - > add_undo_method ( frames , " set_animation_loop " , edited_anim , frames - > get_animation_loop ( edited_anim ) ) ;
undo_redo - > add_do_method ( this , " _update_library " , true ) ;
undo_redo - > add_undo_method ( this , " _update_library " , true ) ;
undo_redo - > commit_action ( ) ;
}
2022-11-26 15:00:38 +01:00
void SpriteFramesEditor : : _animation_speed_changed ( double p_value ) {
2020-05-14 16:41:43 +02:00
if ( updating ) {
2016-05-15 04:48:23 +02:00
return ;
2020-05-14 16:41:43 +02:00
}
2016-05-15 04:48:23 +02:00
2022-12-23 23:53:16 +01:00
EditorUndoRedoManager * undo_redo = EditorUndoRedoManager : : get_singleton ( ) ;
2016-08-17 22:14:51 +02:00
undo_redo - > create_action ( TTR ( " Change Animation FPS " ) , UndoRedo : : MERGE_ENDS ) ;
2016-05-15 04:48:23 +02:00
undo_redo - > add_do_method ( frames , " set_animation_speed " , edited_anim , p_value ) ;
undo_redo - > add_undo_method ( frames , " set_animation_speed " , edited_anim , frames - > get_animation_speed ( edited_anim ) ) ;
undo_redo - > add_do_method ( this , " _update_library " , true ) ;
undo_redo - > add_undo_method ( this , " _update_library " , true ) ;
undo_redo - > commit_action ( ) ;
}
2022-11-26 15:00:38 +01:00
void SpriteFramesEditor : : _frame_list_gui_input ( const Ref < InputEvent > & p_event ) {
2020-08-13 13:15:08 +02:00
const Ref < InputEventMouseButton > mb = p_event ;
if ( mb . is_valid ( ) ) {
2021-08-13 23:31:57 +02:00
if ( mb - > get_button_index ( ) = = MouseButton : : WHEEL_UP & & mb - > is_pressed ( ) & & mb - > is_ctrl_pressed ( ) ) {
2020-08-13 13:15:08 +02:00
_zoom_in ( ) ;
// Don't scroll up after zooming in.
accept_event ( ) ;
2021-08-13 23:31:57 +02:00
} else if ( mb - > get_button_index ( ) = = MouseButton : : WHEEL_DOWN & & mb - > is_pressed ( ) & & mb - > is_ctrl_pressed ( ) ) {
2020-08-13 13:15:08 +02:00
_zoom_out ( ) ;
// Don't scroll down after zooming out.
accept_event ( ) ;
}
}
}
2022-11-26 15:00:38 +01:00
void SpriteFramesEditor : : _frame_list_item_selected ( int p_index ) {
if ( updating ) {
return ;
}
sel = p_index ;
updating = true ;
frame_duration - > set_value ( frames - > get_frame_duration ( edited_anim , p_index ) ) ;
updating = false ;
}
void SpriteFramesEditor : : _frame_duration_changed ( double p_value ) {
if ( updating ) {
return ;
}
int index = frame_list - > get_current ( ) ;
if ( index < 0 ) {
return ;
}
sel = index ;
Ref < Texture2D > texture = frames - > get_frame_texture ( edited_anim , index ) ;
float old_duration = frames - > get_frame_duration ( edited_anim , index ) ;
2022-12-23 23:53:16 +01:00
EditorUndoRedoManager * undo_redo = EditorUndoRedoManager : : get_singleton ( ) ;
2022-11-26 15:00:38 +01:00
undo_redo - > create_action ( TTR ( " Set Frame Duration " ) ) ;
undo_redo - > add_do_method ( frames , " set_frame " , edited_anim , index , texture , p_value ) ;
undo_redo - > add_undo_method ( frames , " set_frame " , edited_anim , index , texture , old_duration ) ;
undo_redo - > add_do_method ( this , " _update_library " ) ;
undo_redo - > add_undo_method ( this , " _update_library " ) ;
undo_redo - > commit_action ( ) ;
}
2020-08-13 13:15:08 +02:00
void SpriteFramesEditor : : _zoom_in ( ) {
// Do not zoom in or out with no visible frames
if ( frames - > get_frame_count ( edited_anim ) < = 0 ) {
return ;
}
if ( thumbnail_zoom < max_thumbnail_zoom ) {
thumbnail_zoom * = scale_ratio ;
int thumbnail_size = ( int ) ( thumbnail_default_size * thumbnail_zoom ) ;
2022-11-26 15:00:38 +01:00
frame_list - > set_fixed_column_width ( thumbnail_size * 3 / 2 ) ;
frame_list - > set_fixed_icon_size ( Size2 ( thumbnail_size , thumbnail_size ) ) ;
2020-08-13 13:15:08 +02:00
}
}
void SpriteFramesEditor : : _zoom_out ( ) {
// Do not zoom in or out with no visible frames
if ( frames - > get_frame_count ( edited_anim ) < = 0 ) {
return ;
}
if ( thumbnail_zoom > min_thumbnail_zoom ) {
thumbnail_zoom / = scale_ratio ;
int thumbnail_size = ( int ) ( thumbnail_default_size * thumbnail_zoom ) ;
2022-11-26 15:00:38 +01:00
frame_list - > set_fixed_column_width ( thumbnail_size * 3 / 2 ) ;
frame_list - > set_fixed_icon_size ( Size2 ( thumbnail_size , thumbnail_size ) ) ;
2020-08-13 13:15:08 +02:00
}
}
void SpriteFramesEditor : : _zoom_reset ( ) {
2021-05-23 01:03:52 +02:00
thumbnail_zoom = MAX ( 1.0f , EDSCALE ) ;
2022-11-26 15:00:38 +01:00
frame_list - > set_fixed_column_width ( thumbnail_default_size * 3 / 2 ) ;
frame_list - > set_fixed_icon_size ( Size2 ( thumbnail_default_size , thumbnail_default_size ) ) ;
2020-08-13 13:15:08 +02:00
}
2016-05-15 04:48:23 +02:00
void SpriteFramesEditor : : _update_library ( bool p_skip_selector ) {
updating = true ;
2022-11-26 15:00:38 +01:00
frame_duration - > set_value ( 1.0 ) ; // Default.
2016-05-15 04:48:23 +02:00
if ( ! p_skip_selector ) {
animations - > clear ( ) ;
TreeItem * anim_root = animations - > create_item ( ) ;
List < StringName > anim_names ;
frames - > get_animation_list ( & anim_names ) ;
anim_names . sort_custom < StringName : : AlphCompare > ( ) ;
2021-06-10 15:42:55 +02:00
bool searching = anim_search_box - > get_text ( ) . size ( ) ;
String searched_string = searching ? anim_search_box - > get_text ( ) . to_lower ( ) : String ( ) ;
2021-07-24 15:46:25 +02:00
for ( const StringName & E : anim_names ) {
2021-07-16 05:45:57 +02:00
String name = E ;
2016-05-15 04:48:23 +02:00
2021-06-10 15:42:55 +02:00
if ( searching & & name . to_lower ( ) . find ( searched_string ) < 0 ) {
continue ;
}
2016-05-15 04:48:23 +02:00
TreeItem * it = animations - > create_item ( anim_root ) ;
it - > set_metadata ( 0 , name ) ;
it - > set_text ( 0 , name ) ;
it - > set_editable ( 0 , true ) ;
2021-07-16 05:45:57 +02:00
if ( E = = edited_anim ) {
2016-05-15 04:48:23 +02:00
it - > select ( 0 ) ;
}
}
}
2022-11-26 15:00:38 +01:00
frame_list - > clear ( ) ;
2014-02-10 02:10:30 +01:00
2016-05-15 04:48:23 +02:00
if ( ! frames - > has_animation ( edited_anim ) ) {
updating = false ;
return ;
}
2020-05-14 16:41:43 +02:00
if ( sel > = frames - > get_frame_count ( edited_anim ) ) {
2016-05-15 04:48:23 +02:00
sel = frames - > get_frame_count ( edited_anim ) - 1 ;
2020-05-14 16:41:43 +02:00
} else if ( sel < 0 & & frames - > get_frame_count ( edited_anim ) ) {
2017-03-05 16:44:50 +01:00
sel = 0 ;
2020-05-14 16:41:43 +02:00
}
2016-05-15 04:48:23 +02:00
for ( int i = 0 ; i < frames - > get_frame_count ( edited_anim ) ; i + + ) {
String name ;
2022-11-26 15:00:38 +01:00
Ref < Texture2D > texture = frames - > get_frame_texture ( edited_anim , i ) ;
float duration = frames - > get_frame_duration ( edited_anim , i ) ;
String duration_string ;
if ( duration ! = 1.0f ) {
duration_string = String : : utf8 ( " [ × " ) + String : : num_real ( frames - > get_frame_duration ( edited_anim , i ) ) + " ] " ;
}
2014-02-10 02:10:30 +01:00
2022-11-26 15:00:38 +01:00
if ( texture . is_null ( ) ) {
name = itos ( i ) + " : " + TTR ( " (empty) " ) + duration_string ;
2014-02-10 02:10:30 +01:00
} else {
2022-11-26 15:00:38 +01:00
name = itos ( i ) + " : " + texture - > get_name ( ) + duration_string ;
2014-02-10 02:10:30 +01:00
}
2016-05-15 04:48:23 +02:00
2022-11-26 15:00:38 +01:00
frame_list - > add_item ( name , texture ) ;
if ( texture . is_valid ( ) ) {
String tooltip = texture - > get_path ( ) ;
2022-01-22 17:03:37 +01:00
// Frame is often saved as an AtlasTexture subresource within a scene/resource file,
// thus its path might be not what the user is looking for. So we're also showing
// subsequent source texture paths.
String prefix = String : : utf8 ( " ┖╴ " ) ;
2022-11-26 15:00:38 +01:00
Ref < AtlasTexture > at = texture ;
2022-01-22 17:03:37 +01:00
while ( at . is_valid ( ) & & at - > get_atlas ( ) . is_valid ( ) ) {
tooltip + = " \n " + prefix + at - > get_atlas ( ) - > get_path ( ) ;
prefix = " " + prefix ;
at = at - > get_atlas ( ) ;
}
2022-11-26 15:00:38 +01:00
frame_list - > set_item_tooltip ( - 1 , tooltip ) ;
2020-05-14 16:41:43 +02:00
}
if ( sel = = i ) {
2022-11-26 15:00:38 +01:00
frame_list - > select ( frame_list - > get_item_count ( ) - 1 ) ;
frame_duration - > set_value ( frames - > get_frame_duration ( edited_anim , i ) ) ;
2020-05-14 16:41:43 +02:00
}
2014-02-10 02:10:30 +01:00
}
2017-01-04 05:16:14 +01:00
anim_speed - > set_value ( frames - > get_animation_speed ( edited_anim ) ) ;
2016-05-15 04:48:23 +02:00
anim_loop - > set_pressed ( frames - > get_animation_loop ( edited_anim ) ) ;
updating = false ;
2014-02-10 02:10:30 +01:00
}
void SpriteFramesEditor : : edit ( SpriteFrames * p_frames ) {
2022-09-06 15:47:13 +02:00
bool new_read_only_state = false ;
if ( p_frames ) {
new_read_only_state = EditorNode : : get_singleton ( ) - > is_resource_read_only ( p_frames ) ;
}
if ( frames = = p_frames & & new_read_only_state = = read_only ) {
2016-05-15 04:48:23 +02:00
return ;
2020-05-14 16:41:43 +02:00
}
2016-05-15 04:48:23 +02:00
2014-02-10 02:10:30 +01:00
frames = p_frames ;
2022-09-06 15:47:13 +02:00
read_only = new_read_only_state ;
2014-02-10 02:10:30 +01:00
if ( p_frames ) {
2016-05-15 04:48:23 +02:00
if ( ! p_frames - > has_animation ( edited_anim ) ) {
List < StringName > anim_names ;
frames - > get_animation_list ( & anim_names ) ;
anim_names . sort_custom < StringName : : AlphCompare > ( ) ;
if ( anim_names . size ( ) ) {
edited_anim = anim_names . front ( ) - > get ( ) ;
} else {
edited_anim = StringName ( ) ;
}
}
2014-02-10 02:10:30 +01:00
_update_library ( ) ;
2020-08-13 13:15:08 +02:00
// Clear zoom and split sheet texture
split_sheet_preview - > set_texture ( Ref < Texture2D > ( ) ) ;
_zoom_reset ( ) ;
2014-02-10 02:10:30 +01:00
} else {
hide ( ) ;
}
2022-09-06 15:47:13 +02:00
2022-09-24 10:01:52 +02:00
add_anim - > set_disabled ( read_only ) ;
delete_anim - > set_disabled ( read_only ) ;
2022-09-06 15:47:13 +02:00
anim_speed - > set_editable ( ! read_only ) ;
anim_loop - > set_disabled ( read_only ) ;
load - > set_disabled ( read_only ) ;
load_sheet - > set_disabled ( read_only ) ;
copy - > set_disabled ( read_only ) ;
paste - > set_disabled ( read_only ) ;
2022-09-24 10:01:52 +02:00
empty_before - > set_disabled ( read_only ) ;
empty_after - > set_disabled ( read_only ) ;
2022-09-06 15:47:13 +02:00
move_up - > set_disabled ( read_only ) ;
move_down - > set_disabled ( read_only ) ;
2022-09-24 10:01:52 +02:00
delete_frame - > set_disabled ( read_only ) ;
2014-02-10 02:10:30 +01:00
}
2016-05-15 04:48:23 +02:00
Variant SpriteFramesEditor : : get_drag_data_fw ( const Point2 & p_point , Control * p_from ) {
2022-09-06 15:47:13 +02:00
if ( read_only ) {
return false ;
}
2020-05-14 16:41:43 +02:00
if ( ! frames - > has_animation ( edited_anim ) ) {
2016-05-15 04:48:23 +02:00
return false ;
2020-05-14 16:41:43 +02:00
}
2016-05-15 04:48:23 +02:00
2022-11-26 15:00:38 +01:00
int idx = frame_list - > get_item_at_position ( p_point , true ) ;
2016-05-15 04:48:23 +02:00
2020-05-14 16:41:43 +02:00
if ( idx < 0 | | idx > = frames - > get_frame_count ( edited_anim ) ) {
2016-05-15 04:48:23 +02:00
return Variant ( ) ;
2020-05-14 16:41:43 +02:00
}
2016-05-15 04:48:23 +02:00
2022-11-26 15:00:38 +01:00
Ref < Resource > frame = frames - > get_frame_texture ( edited_anim , idx ) ;
2016-05-15 04:48:23 +02:00
2020-05-14 16:41:43 +02:00
if ( frame . is_null ( ) ) {
2016-05-15 04:48:23 +02:00
return Variant ( ) ;
2020-05-14 16:41:43 +02:00
}
2016-05-15 04:48:23 +02:00
2019-09-06 01:53:37 +02:00
Dictionary drag_data = EditorNode : : get_singleton ( ) - > drag_resource ( frame , p_from ) ;
2019-11-22 08:35:03 +01:00
drag_data [ " frame " ] = idx ; // store the frame, in case we want to reorder frames inside 'drop_data_fw'
2019-09-06 01:53:37 +02:00
return drag_data ;
2016-05-15 04:48:23 +02:00
}
bool SpriteFramesEditor : : can_drop_data_fw ( const Point2 & p_point , const Variant & p_data , Control * p_from ) const {
2022-09-06 15:47:13 +02:00
if ( read_only ) {
return false ;
}
2016-05-15 04:48:23 +02:00
Dictionary d = p_data ;
2020-05-14 16:41:43 +02:00
if ( ! d . has ( " type " ) ) {
2016-05-15 04:48:23 +02:00
return false ;
2020-05-14 16:41:43 +02:00
}
2016-05-15 04:48:23 +02:00
2019-09-06 01:53:37 +02:00
// reordering frames
2022-11-26 15:00:38 +01:00
if ( d . has ( " from " ) & & ( Object * ) ( d [ " from " ] ) = = frame_list ) {
2019-09-06 01:53:37 +02:00
return true ;
2020-05-14 16:41:43 +02:00
}
2016-05-15 04:48:23 +02:00
if ( String ( d [ " type " ] ) = = " resource " & & d . has ( " resource " ) ) {
2022-05-03 01:43:50 +02:00
Ref < Resource > r = d [ " resource " ] ;
2016-05-15 04:48:23 +02:00
2019-06-11 20:43:37 +02:00
Ref < Texture2D > texture = r ;
2016-05-15 04:48:23 +02:00
if ( texture . is_valid ( ) ) {
return true ;
}
}
if ( String ( d [ " type " ] ) = = " files " ) {
Vector < String > files = d [ " files " ] ;
2020-05-14 16:41:43 +02:00
if ( files . size ( ) = = 0 ) {
2016-05-15 04:48:23 +02:00
return false ;
2020-05-14 16:41:43 +02:00
}
2016-05-15 04:48:23 +02:00
for ( int i = 0 ; i < files . size ( ) ; i + + ) {
2022-09-29 11:53:28 +02:00
String f = files [ i ] ;
String ftype = EditorFileSystem : : get_singleton ( ) - > get_file_type ( f ) ;
2016-05-15 04:48:23 +02:00
2019-06-11 20:43:37 +02:00
if ( ! ClassDB : : is_parent_class ( ftype , " Texture2D " ) ) {
2016-05-15 04:48:23 +02:00
return false ;
}
}
return true ;
}
return false ;
}
void SpriteFramesEditor : : drop_data_fw ( const Point2 & p_point , const Variant & p_data , Control * p_from ) {
2020-05-14 16:41:43 +02:00
if ( ! can_drop_data_fw ( p_point , p_data , p_from ) ) {
2016-05-15 04:48:23 +02:00
return ;
2020-05-14 16:41:43 +02:00
}
2016-05-15 04:48:23 +02:00
Dictionary d = p_data ;
2020-05-14 16:41:43 +02:00
if ( ! d . has ( " type " ) ) {
2016-05-15 04:48:23 +02:00
return ;
2020-05-14 16:41:43 +02:00
}
2016-05-15 04:48:23 +02:00
2022-11-26 15:00:38 +01:00
int at_pos = frame_list - > get_item_at_position ( p_point , true ) ;
2016-05-15 04:48:23 +02:00
if ( String ( d [ " type " ] ) = = " resource " & & d . has ( " resource " ) ) {
2022-05-03 01:43:50 +02:00
Ref < Resource > r = d [ " resource " ] ;
2016-05-15 04:48:23 +02:00
2019-06-11 20:43:37 +02:00
Ref < Texture2D > texture = r ;
2016-05-15 04:48:23 +02:00
if ( texture . is_valid ( ) ) {
2019-09-06 01:53:37 +02:00
bool reorder = false ;
2022-11-26 15:00:38 +01:00
if ( d . has ( " from " ) & & ( Object * ) ( d [ " from " ] ) = = frame_list ) {
2019-09-06 01:53:37 +02:00
reorder = true ;
2020-05-14 16:41:43 +02:00
}
2019-09-06 01:53:37 +02:00
2022-12-23 23:53:16 +01:00
EditorUndoRedoManager * undo_redo = EditorUndoRedoManager : : get_singleton ( ) ;
2019-09-06 01:53:37 +02:00
if ( reorder ) { //drop is from reordering frames
int from_frame = - 1 ;
2022-11-26 15:00:38 +01:00
float duration = 1.0 ;
2020-05-14 16:41:43 +02:00
if ( d . has ( " frame " ) ) {
2019-09-06 01:53:37 +02:00
from_frame = d [ " frame " ] ;
2022-11-26 15:00:38 +01:00
duration = frames - > get_frame_duration ( edited_anim , from_frame ) ;
2020-05-14 16:41:43 +02:00
}
2019-09-06 01:53:37 +02:00
undo_redo - > create_action ( TTR ( " Move Frame " ) ) ;
undo_redo - > add_do_method ( frames , " remove_frame " , edited_anim , from_frame = = - 1 ? frames - > get_frame_count ( edited_anim ) : from_frame ) ;
2022-11-26 15:00:38 +01:00
undo_redo - > add_do_method ( frames , " add_frame " , edited_anim , texture , duration , at_pos = = - 1 ? - 1 : at_pos ) ;
2019-09-06 01:53:37 +02:00
undo_redo - > add_undo_method ( frames , " remove_frame " , edited_anim , at_pos = = - 1 ? frames - > get_frame_count ( edited_anim ) - 1 : at_pos ) ;
2022-11-26 15:00:38 +01:00
undo_redo - > add_undo_method ( frames , " add_frame " , edited_anim , texture , duration , from_frame ) ;
2019-09-06 01:53:37 +02:00
undo_redo - > add_do_method ( this , " _update_library " ) ;
undo_redo - > add_undo_method ( this , " _update_library " ) ;
undo_redo - > commit_action ( ) ;
} else {
undo_redo - > create_action ( TTR ( " Add Frame " ) ) ;
2022-11-26 15:00:38 +01:00
undo_redo - > add_do_method ( frames , " add_frame " , edited_anim , texture , 1.0 , at_pos = = - 1 ? - 1 : at_pos ) ;
2019-09-06 01:53:37 +02:00
undo_redo - > add_undo_method ( frames , " remove_frame " , edited_anim , at_pos = = - 1 ? frames - > get_frame_count ( edited_anim ) : at_pos ) ;
undo_redo - > add_do_method ( this , " _update_library " ) ;
undo_redo - > add_undo_method ( this , " _update_library " ) ;
undo_redo - > commit_action ( ) ;
}
2016-05-15 04:48:23 +02:00
}
}
if ( String ( d [ " type " ] ) = = " files " ) {
2020-02-17 22:06:54 +01:00
Vector < String > files = d [ " files " ] ;
2016-05-15 04:48:23 +02:00
2021-08-13 23:31:57 +02:00
if ( Input : : get_singleton ( ) - > is_key_pressed ( Key : : CTRL ) ) {
2021-01-12 00:51:59 +01:00
_prepare_sprite_sheet ( files [ 0 ] ) ;
} else {
_file_load_request ( files , at_pos ) ;
}
2016-05-15 04:48:23 +02:00
}
}
2014-02-10 02:10:30 +01:00
void SpriteFramesEditor : : _bind_methods ( ) {
2017-02-13 12:47:24 +01:00
ClassDB : : bind_method ( D_METHOD ( " _update_library " , " skipsel " ) , & SpriteFramesEditor : : _update_library , DEFVAL ( false ) ) ;
2014-02-10 02:10:30 +01:00
}
SpriteFramesEditor : : SpriteFramesEditor ( ) {
2016-05-15 04:48:23 +02:00
VBoxContainer * vbc_animlist = memnew ( VBoxContainer ) ;
2019-02-08 01:54:59 +01:00
add_child ( vbc_animlist ) ;
2017-10-12 20:59:25 +02:00
vbc_animlist - > set_custom_minimum_size ( Size2 ( 150 , 0 ) * EDSCALE ) ;
2016-05-15 04:48:23 +02:00
VBoxContainer * sub_vb = memnew ( VBoxContainer ) ;
2019-02-08 01:54:59 +01:00
vbc_animlist - > add_margin_child ( TTR ( " Animations: " ) , sub_vb , true ) ;
2016-05-15 04:48:23 +02:00
sub_vb - > set_v_size_flags ( SIZE_EXPAND_FILL ) ;
HBoxContainer * hbc_animlist = memnew ( HBoxContainer ) ;
sub_vb - > add_child ( hbc_animlist ) ;
2022-09-24 10:01:52 +02:00
add_anim = memnew ( Button ) ;
add_anim - > set_flat ( true ) ;
hbc_animlist - > add_child ( add_anim ) ;
add_anim - > connect ( " pressed " , callable_mp ( this , & SpriteFramesEditor : : _animation_add ) ) ;
2016-05-15 04:48:23 +02:00
2022-09-24 10:01:52 +02:00
delete_anim = memnew ( Button ) ;
delete_anim - > set_flat ( true ) ;
hbc_animlist - > add_child ( delete_anim ) ;
delete_anim - > set_disabled ( true ) ;
delete_anim - > connect ( " pressed " , callable_mp ( this , & SpriteFramesEditor : : _animation_remove ) ) ;
2016-05-15 04:48:23 +02:00
2021-06-10 15:42:55 +02:00
anim_search_box = memnew ( LineEdit ) ;
hbc_animlist - > add_child ( anim_search_box ) ;
anim_search_box - > set_h_size_flags ( SIZE_EXPAND_FILL ) ;
2022-07-19 03:15:50 +02:00
anim_search_box - > set_placeholder ( TTR ( " Filter Animations " ) ) ;
2021-06-10 15:42:55 +02:00
anim_search_box - > set_clear_button_enabled ( true ) ;
anim_search_box - > connect ( " text_changed " , callable_mp ( this , & SpriteFramesEditor : : _animation_search_text_changed ) ) ;
2016-05-15 04:48:23 +02:00
animations = memnew ( Tree ) ;
sub_vb - > add_child ( animations ) ;
animations - > set_v_size_flags ( SIZE_EXPAND_FILL ) ;
animations - > set_hide_root ( true ) ;
2020-02-21 18:28:45 +01:00
animations - > connect ( " cell_selected " , callable_mp ( this , & SpriteFramesEditor : : _animation_select ) ) ;
animations - > connect ( " item_edited " , callable_mp ( this , & SpriteFramesEditor : : _animation_name_edited ) ) ;
2017-08-18 23:19:12 +02:00
animations - > set_allow_reselect ( true ) ;
2016-05-15 04:48:23 +02:00
2022-09-24 10:01:52 +02:00
add_anim - > set_shortcut_context ( animations ) ;
add_anim - > set_shortcut ( ED_SHORTCUT ( " sprite_frames/new_animation " , TTR ( " Add Animation " ) , KeyModifierMask : : CMD_OR_CTRL | Key : : N ) ) ;
delete_anim - > set_shortcut_context ( animations ) ;
delete_anim - > set_shortcut ( ED_SHORTCUT ( " sprite_frames/delete_animation " , TTR ( " Delete Animation " ) , Key : : KEY_DELETE ) ) ;
2020-08-05 17:25:41 +02:00
HBoxContainer * hbc_anim_speed = memnew ( HBoxContainer ) ;
hbc_anim_speed - > add_child ( memnew ( Label ( TTR ( " Speed: " ) ) ) ) ;
vbc_animlist - > add_child ( hbc_anim_speed ) ;
2016-05-15 04:48:23 +02:00
anim_speed = memnew ( SpinBox ) ;
2020-08-05 17:25:41 +02:00
anim_speed - > set_suffix ( TTR ( " FPS " ) ) ;
2016-05-15 04:48:23 +02:00
anim_speed - > set_min ( 0 ) ;
2022-11-26 15:00:38 +01:00
anim_speed - > set_max ( 120 ) ;
2016-05-15 04:48:23 +02:00
anim_speed - > set_step ( 0.01 ) ;
2020-08-05 17:25:41 +02:00
anim_speed - > set_h_size_flags ( SIZE_EXPAND_FILL ) ;
hbc_anim_speed - > add_child ( anim_speed ) ;
2022-11-26 15:00:38 +01:00
anim_speed - > connect ( " value_changed " , callable_mp ( this , & SpriteFramesEditor : : _animation_speed_changed ) ) ;
2016-05-15 04:48:23 +02:00
anim_loop = memnew ( CheckButton ) ;
anim_loop - > set_text ( TTR ( " Loop " ) ) ;
vbc_animlist - > add_child ( anim_loop ) ;
2020-02-21 18:28:45 +01:00
anim_loop - > connect ( " pressed " , callable_mp ( this , & SpriteFramesEditor : : _animation_loop_changed ) ) ;
2016-05-15 04:48:23 +02:00
2014-02-10 02:10:30 +01:00
VBoxContainer * vbc = memnew ( VBoxContainer ) ;
2019-02-08 01:54:59 +01:00
add_child ( vbc ) ;
2016-05-15 04:48:23 +02:00
vbc - > set_h_size_flags ( SIZE_EXPAND_FILL ) ;
sub_vb = memnew ( VBoxContainer ) ;
2019-02-08 01:54:59 +01:00
vbc - > add_margin_child ( TTR ( " Animation Frames: " ) , sub_vb , true ) ;
2014-02-10 02:10:30 +01:00
HBoxContainer * hbc = memnew ( HBoxContainer ) ;
2016-05-15 04:48:23 +02:00
sub_vb - > add_child ( hbc ) ;
2020-06-19 20:49:04 +02:00
load = memnew ( Button ) ;
load - > set_flat ( true ) ;
2014-02-10 02:10:30 +01:00
hbc - > add_child ( load ) ;
2020-06-19 20:49:04 +02:00
load_sheet = memnew ( Button ) ;
load_sheet - > set_flat ( true ) ;
2019-04-14 03:15:31 +02:00
hbc - > add_child ( load_sheet ) ;
hbc - > add_child ( memnew ( VSeparator ) ) ;
2020-06-19 20:49:04 +02:00
copy = memnew ( Button ) ;
copy - > set_flat ( true ) ;
2017-10-27 06:25:13 +02:00
hbc - > add_child ( copy ) ;
2020-06-19 20:49:04 +02:00
paste = memnew ( Button ) ;
paste - > set_flat ( true ) ;
2014-02-10 02:10:30 +01:00
hbc - > add_child ( paste ) ;
2019-09-06 11:07:36 +02:00
hbc - > add_child ( memnew ( VSeparator ) ) ;
2019-04-14 03:15:31 +02:00
2022-09-24 10:01:52 +02:00
empty_before = memnew ( Button ) ;
empty_before - > set_flat ( true ) ;
hbc - > add_child ( empty_before ) ;
2014-02-10 02:10:30 +01:00
2022-09-24 10:01:52 +02:00
empty_after = memnew ( Button ) ;
empty_after - > set_flat ( true ) ;
hbc - > add_child ( empty_after ) ;
2015-04-02 12:22:17 +02:00
2019-04-14 03:15:31 +02:00
hbc - > add_child ( memnew ( VSeparator ) ) ;
2018-04-17 19:43:08 +02:00
2020-06-19 20:49:04 +02:00
move_up = memnew ( Button ) ;
move_up - > set_flat ( true ) ;
2014-02-10 02:10:30 +01:00
hbc - > add_child ( move_up ) ;
2020-06-19 20:49:04 +02:00
move_down = memnew ( Button ) ;
move_down - > set_flat ( true ) ;
2014-02-10 02:10:30 +01:00
hbc - > add_child ( move_down ) ;
2022-09-24 10:01:52 +02:00
delete_frame = memnew ( Button ) ;
delete_frame - > set_flat ( true ) ;
hbc - > add_child ( delete_frame ) ;
2014-02-10 02:10:30 +01:00
2022-11-26 15:00:38 +01:00
hbc - > add_child ( memnew ( VSeparator ) ) ;
Label * label = memnew ( Label ) ;
label - > set_text ( TTR ( " Frame Duration: " ) ) ;
hbc - > add_child ( label ) ;
frame_duration = memnew ( SpinBox ) ;
frame_duration - > set_prefix ( String : : utf8 ( " × " ) ) ;
frame_duration - > set_min ( 0 ) ;
frame_duration - > set_max ( 10 ) ;
frame_duration - > set_step ( 0.01 ) ;
frame_duration - > set_allow_greater ( true ) ;
hbc - > add_child ( frame_duration ) ;
2020-08-13 13:15:08 +02:00
hbc - > add_spacer ( ) ;
zoom_out = memnew ( Button ) ;
zoom_out - > connect ( " pressed " , callable_mp ( this , & SpriteFramesEditor : : _zoom_out ) ) ;
zoom_out - > set_flat ( true ) ;
2022-08-25 12:42:17 +02:00
zoom_out - > set_tooltip_text ( TTR ( " Zoom Out " ) ) ;
2020-08-13 13:15:08 +02:00
hbc - > add_child ( zoom_out ) ;
2021-05-23 01:03:52 +02:00
zoom_reset = memnew ( Button ) ;
zoom_reset - > connect ( " pressed " , callable_mp ( this , & SpriteFramesEditor : : _zoom_reset ) ) ;
zoom_reset - > set_flat ( true ) ;
2022-08-25 12:42:17 +02:00
zoom_reset - > set_tooltip_text ( TTR ( " Zoom Reset " ) ) ;
2021-05-23 01:03:52 +02:00
hbc - > add_child ( zoom_reset ) ;
2020-08-13 13:15:08 +02:00
zoom_in = memnew ( Button ) ;
zoom_in - > connect ( " pressed " , callable_mp ( this , & SpriteFramesEditor : : _zoom_in ) ) ;
zoom_in - > set_flat ( true ) ;
2022-08-25 12:42:17 +02:00
zoom_in - > set_tooltip_text ( TTR ( " Zoom In " ) ) ;
2020-08-13 13:15:08 +02:00
hbc - > add_child ( zoom_in ) ;
2015-06-06 14:44:38 +02:00
file = memnew ( EditorFileDialog ) ;
2014-02-10 02:10:30 +01:00
add_child ( file ) ;
2022-11-26 15:00:38 +01:00
frame_list = memnew ( ItemList ) ;
frame_list - > set_v_size_flags ( SIZE_EXPAND_FILL ) ;
frame_list - > set_icon_mode ( ItemList : : ICON_MODE_TOP ) ;
2016-05-15 04:48:23 +02:00
2022-11-26 15:00:38 +01:00
frame_list - > set_max_columns ( 0 ) ;
frame_list - > set_icon_mode ( ItemList : : ICON_MODE_TOP ) ;
frame_list - > set_max_text_lines ( 2 ) ;
2023-01-14 03:37:19 +01:00
SET_DRAG_FORWARDING_GCD ( frame_list , SpriteFramesEditor ) ;
2022-11-26 15:00:38 +01:00
frame_list - > connect ( " gui_input " , callable_mp ( this , & SpriteFramesEditor : : _frame_list_gui_input ) ) ;
frame_list - > connect ( " item_selected " , callable_mp ( this , & SpriteFramesEditor : : _frame_list_item_selected ) ) ;
2016-05-15 04:48:23 +02:00
2022-11-26 15:00:38 +01:00
sub_vb - > add_child ( frame_list ) ;
2014-02-10 02:10:30 +01:00
dialog = memnew ( AcceptDialog ) ;
add_child ( dialog ) ;
2017-03-05 16:44:50 +01:00
2020-02-21 18:28:45 +01:00
load - > connect ( " pressed " , callable_mp ( this , & SpriteFramesEditor : : _load_pressed ) ) ;
load_sheet - > connect ( " pressed " , callable_mp ( this , & SpriteFramesEditor : : _open_sprite_sheet ) ) ;
2022-09-24 10:01:52 +02:00
delete_frame - > connect ( " pressed " , callable_mp ( this , & SpriteFramesEditor : : _delete_pressed ) ) ;
2020-02-21 18:28:45 +01:00
copy - > connect ( " pressed " , callable_mp ( this , & SpriteFramesEditor : : _copy_pressed ) ) ;
paste - > connect ( " pressed " , callable_mp ( this , & SpriteFramesEditor : : _paste_pressed ) ) ;
2022-09-24 10:01:52 +02:00
empty_before - > connect ( " pressed " , callable_mp ( this , & SpriteFramesEditor : : _empty_pressed ) ) ;
empty_after - > connect ( " pressed " , callable_mp ( this , & SpriteFramesEditor : : _empty2_pressed ) ) ;
2020-02-21 18:28:45 +01:00
move_up - > connect ( " pressed " , callable_mp ( this , & SpriteFramesEditor : : _up_pressed ) ) ;
move_down - > connect ( " pressed " , callable_mp ( this , & SpriteFramesEditor : : _down_pressed ) ) ;
2022-09-24 10:01:52 +02:00
2022-11-26 15:00:38 +01:00
load - > set_shortcut_context ( frame_list ) ;
2022-09-24 10:01:52 +02:00
load - > set_shortcut ( ED_SHORTCUT ( " sprite_frames/load_from_file " , TTR ( " Add frame from file " ) , KeyModifierMask : : CMD_OR_CTRL | Key : : O ) ) ;
2022-11-26 15:00:38 +01:00
load_sheet - > set_shortcut_context ( frame_list ) ;
2022-09-24 10:01:52 +02:00
load_sheet - > set_shortcut ( ED_SHORTCUT ( " sprite_frames/load_from_sheet " , TTR ( " Add frames from sprite sheet " ) , KeyModifierMask : : CMD_OR_CTRL | KeyModifierMask : : SHIFT | Key : : O ) ) ;
2022-11-26 15:00:38 +01:00
delete_frame - > set_shortcut_context ( frame_list ) ;
2022-09-24 10:01:52 +02:00
delete_frame - > set_shortcut ( ED_SHORTCUT ( " sprite_frames/delete " , TTR ( " Delete Frame " ) , Key : : KEY_DELETE ) ) ;
2022-11-26 15:00:38 +01:00
copy - > set_shortcut_context ( frame_list ) ;
2022-09-24 10:01:52 +02:00
copy - > set_shortcut ( ED_SHORTCUT ( " sprite_frames/copy " , TTR ( " Copy Frame " ) , KeyModifierMask : : CMD_OR_CTRL | Key : : C ) ) ;
2022-11-26 15:00:38 +01:00
paste - > set_shortcut_context ( frame_list ) ;
2022-09-24 10:01:52 +02:00
paste - > set_shortcut ( ED_SHORTCUT ( " sprite_frames/paste " , TTR ( " Paste Frame " ) , KeyModifierMask : : CMD_OR_CTRL | Key : : V ) ) ;
2022-11-26 15:00:38 +01:00
empty_before - > set_shortcut_context ( frame_list ) ;
2022-09-24 10:01:52 +02:00
empty_before - > set_shortcut ( ED_SHORTCUT ( " sprite_frames/empty_before " , TTR ( " Insert Empty (Before Selected) " ) , KeyModifierMask : : ALT | Key : : LEFT ) ) ;
2022-11-26 15:00:38 +01:00
empty_after - > set_shortcut_context ( frame_list ) ;
2022-09-24 10:01:52 +02:00
empty_after - > set_shortcut ( ED_SHORTCUT ( " sprite_frames/empty_after " , TTR ( " Insert Empty (After Selected) " ) , KeyModifierMask : : ALT | Key : : RIGHT ) ) ;
2022-11-26 15:00:38 +01:00
move_up - > set_shortcut_context ( frame_list ) ;
2022-09-24 10:01:52 +02:00
move_up - > set_shortcut ( ED_SHORTCUT ( " sprite_frames/move_left " , TTR ( " Move Frame Left " ) , KeyModifierMask : : CMD_OR_CTRL | Key : : LEFT ) ) ;
2022-11-26 15:00:38 +01:00
move_down - > set_shortcut_context ( frame_list ) ;
2022-09-24 10:01:52 +02:00
move_down - > set_shortcut ( ED_SHORTCUT ( " sprite_frames/move_right " , TTR ( " Move Frame Right " ) , KeyModifierMask : : CMD_OR_CTRL | Key : : RIGHT ) ) ;
2022-11-26 15:00:38 +01:00
zoom_out - > set_shortcut_context ( frame_list ) ;
2022-09-24 10:01:52 +02:00
zoom_out - > set_shortcut ( ED_SHORTCUT_ARRAY ( " sprite_frames/zoom_out " , TTR ( " Zoom Out " ) ,
{ int32_t ( KeyModifierMask : : CMD_OR_CTRL | Key : : MINUS ) , int32_t ( KeyModifierMask : : CMD_OR_CTRL | Key : : KP_SUBTRACT ) } ) ) ;
2022-11-26 15:00:38 +01:00
zoom_in - > set_shortcut_context ( frame_list ) ;
2022-09-24 10:01:52 +02:00
zoom_in - > set_shortcut ( ED_SHORTCUT_ARRAY ( " sprite_frames/zoom_in " , TTR ( " Zoom In " ) ,
{ int32_t ( KeyModifierMask : : CMD_OR_CTRL | Key : : EQUAL ) , int32_t ( KeyModifierMask : : CMD_OR_CTRL | Key : : KP_ADD ) } ) ) ;
2022-07-28 22:56:41 +02:00
file - > connect ( " files_selected " , callable_mp ( this , & SpriteFramesEditor : : _file_load_request ) . bind ( - 1 ) ) ;
2022-11-26 15:00:38 +01:00
frame_duration - > connect ( " value_changed " , callable_mp ( this , & SpriteFramesEditor : : _frame_duration_changed ) ) ;
2014-02-10 02:10:30 +01:00
loading_scene = false ;
sel = - 1 ;
2016-05-15 04:48:23 +02:00
updating = false ;
edited_anim = " default " ;
2019-04-14 03:15:31 +02:00
2019-09-06 11:07:36 +02:00
delete_dialog = memnew ( ConfirmationDialog ) ;
add_child ( delete_dialog ) ;
2020-02-21 18:28:45 +01:00
delete_dialog - > connect ( " confirmed " , callable_mp ( this , & SpriteFramesEditor : : _animation_remove_confirmed ) ) ;
2019-09-06 11:07:36 +02:00
2019-04-14 03:15:31 +02:00
split_sheet_dialog = memnew ( ConfirmationDialog ) ;
add_child ( split_sheet_dialog ) ;
VBoxContainer * split_sheet_vb = memnew ( VBoxContainer ) ;
split_sheet_dialog - > add_child ( split_sheet_vb ) ;
split_sheet_dialog - > set_title ( TTR ( " Select Frames " ) ) ;
2020-02-21 18:28:45 +01:00
split_sheet_dialog - > connect ( " confirmed " , callable_mp ( this , & SpriteFramesEditor : : _sheet_add_frames ) ) ;
2019-04-14 03:15:31 +02:00
HBoxContainer * split_sheet_hb = memnew ( HBoxContainer ) ;
2019-04-14 08:24:22 +02:00
2022-04-09 11:30:00 +02:00
split_sheet_hb - > add_child ( memnew ( Label ( TTR ( " Horizontal: " ) ) ) ) ;
2019-04-14 03:15:31 +02:00
split_sheet_h = memnew ( SpinBox ) ;
split_sheet_h - > set_min ( 1 ) ;
split_sheet_h - > set_max ( 128 ) ;
split_sheet_h - > set_step ( 1 ) ;
split_sheet_hb - > add_child ( split_sheet_h ) ;
2022-07-28 22:56:41 +02:00
split_sheet_h - > connect ( " value_changed " , callable_mp ( this , & SpriteFramesEditor : : _sheet_spin_changed ) . bind ( PARAM_FRAME_COUNT ) ) ;
2019-04-14 03:15:31 +02:00
2022-04-09 11:30:00 +02:00
split_sheet_hb - > add_child ( memnew ( Label ( TTR ( " Vertical: " ) ) ) ) ;
2019-04-14 03:15:31 +02:00
split_sheet_v = memnew ( SpinBox ) ;
split_sheet_v - > set_min ( 1 ) ;
split_sheet_v - > set_max ( 128 ) ;
split_sheet_v - > set_step ( 1 ) ;
split_sheet_hb - > add_child ( split_sheet_v ) ;
2022-07-28 22:56:41 +02:00
split_sheet_v - > connect ( " value_changed " , callable_mp ( this , & SpriteFramesEditor : : _sheet_spin_changed ) . bind ( PARAM_FRAME_COUNT ) ) ;
2022-04-09 11:30:00 +02:00
split_sheet_hb - > add_child ( memnew ( VSeparator ) ) ;
split_sheet_hb - > add_child ( memnew ( Label ( TTR ( " Size: " ) ) ) ) ;
split_sheet_size_x = memnew ( SpinBox ) ;
split_sheet_size_x - > set_min ( 1 ) ;
split_sheet_size_x - > set_step ( 1 ) ;
split_sheet_size_x - > set_suffix ( " px " ) ;
2022-07-28 22:56:41 +02:00
split_sheet_size_x - > connect ( " value_changed " , callable_mp ( this , & SpriteFramesEditor : : _sheet_spin_changed ) . bind ( PARAM_SIZE ) ) ;
2022-04-09 11:30:00 +02:00
split_sheet_hb - > add_child ( split_sheet_size_x ) ;
split_sheet_size_y = memnew ( SpinBox ) ;
split_sheet_size_y - > set_min ( 1 ) ;
split_sheet_size_y - > set_step ( 1 ) ;
split_sheet_size_y - > set_suffix ( " px " ) ;
2022-07-28 22:56:41 +02:00
split_sheet_size_y - > connect ( " value_changed " , callable_mp ( this , & SpriteFramesEditor : : _sheet_spin_changed ) . bind ( PARAM_SIZE ) ) ;
2022-04-09 11:30:00 +02:00
split_sheet_hb - > add_child ( split_sheet_size_y ) ;
split_sheet_hb - > add_child ( memnew ( VSeparator ) ) ;
split_sheet_hb - > add_child ( memnew ( Label ( TTR ( " Separation: " ) ) ) ) ;
split_sheet_sep_x = memnew ( SpinBox ) ;
split_sheet_sep_x - > set_min ( 0 ) ;
split_sheet_sep_x - > set_step ( 1 ) ;
split_sheet_sep_x - > set_suffix ( " px " ) ;
2022-07-28 22:56:41 +02:00
split_sheet_sep_x - > connect ( " value_changed " , callable_mp ( this , & SpriteFramesEditor : : _sheet_spin_changed ) . bind ( PARAM_USE_CURRENT ) ) ;
2022-04-09 11:30:00 +02:00
split_sheet_hb - > add_child ( split_sheet_sep_x ) ;
split_sheet_sep_y = memnew ( SpinBox ) ;
split_sheet_sep_y - > set_min ( 0 ) ;
split_sheet_sep_y - > set_step ( 1 ) ;
split_sheet_sep_y - > set_suffix ( " px " ) ;
2022-07-28 22:56:41 +02:00
split_sheet_sep_y - > connect ( " value_changed " , callable_mp ( this , & SpriteFramesEditor : : _sheet_spin_changed ) . bind ( PARAM_USE_CURRENT ) ) ;
2022-04-09 11:30:00 +02:00
split_sheet_hb - > add_child ( split_sheet_sep_y ) ;
split_sheet_hb - > add_child ( memnew ( VSeparator ) ) ;
split_sheet_hb - > add_child ( memnew ( Label ( TTR ( " Offset: " ) ) ) ) ;
split_sheet_offset_x = memnew ( SpinBox ) ;
split_sheet_offset_x - > set_min ( 0 ) ;
split_sheet_offset_x - > set_step ( 1 ) ;
split_sheet_offset_x - > set_suffix ( " px " ) ;
2022-07-28 22:56:41 +02:00
split_sheet_offset_x - > connect ( " value_changed " , callable_mp ( this , & SpriteFramesEditor : : _sheet_spin_changed ) . bind ( PARAM_USE_CURRENT ) ) ;
2022-04-09 11:30:00 +02:00
split_sheet_hb - > add_child ( split_sheet_offset_x ) ;
split_sheet_offset_y = memnew ( SpinBox ) ;
split_sheet_offset_y - > set_min ( 0 ) ;
split_sheet_offset_y - > set_step ( 1 ) ;
split_sheet_offset_y - > set_suffix ( " px " ) ;
2022-07-28 22:56:41 +02:00
split_sheet_offset_y - > connect ( " value_changed " , callable_mp ( this , & SpriteFramesEditor : : _sheet_spin_changed ) . bind ( PARAM_USE_CURRENT ) ) ;
2022-04-09 11:30:00 +02:00
split_sheet_hb - > add_child ( split_sheet_offset_y ) ;
2019-04-14 03:15:31 +02:00
2019-04-14 08:24:22 +02:00
split_sheet_hb - > add_spacer ( ) ;
Button * select_clear_all = memnew ( Button ) ;
select_clear_all - > set_text ( TTR ( " Select/Clear All Frames " ) ) ;
2020-02-21 18:28:45 +01:00
select_clear_all - > connect ( " pressed " , callable_mp ( this , & SpriteFramesEditor : : _sheet_select_clear_all_frames ) ) ;
2019-04-14 08:24:22 +02:00
split_sheet_hb - > add_child ( select_clear_all ) ;
split_sheet_vb - > add_child ( split_sheet_hb ) ;
2020-08-13 13:15:08 +02:00
PanelContainer * split_sheet_panel = memnew ( PanelContainer ) ;
split_sheet_panel - > set_h_size_flags ( SIZE_EXPAND_FILL ) ;
split_sheet_panel - > set_v_size_flags ( SIZE_EXPAND_FILL ) ;
split_sheet_vb - > add_child ( split_sheet_panel ) ;
2019-04-14 08:24:22 +02:00
split_sheet_preview = memnew ( TextureRect ) ;
2022-02-25 01:19:24 +01:00
split_sheet_preview - > set_expand_mode ( TextureRect : : EXPAND_IGNORE_SIZE ) ;
2019-04-14 08:24:22 +02:00
split_sheet_preview - > set_mouse_filter ( MOUSE_FILTER_PASS ) ;
2020-02-21 18:28:45 +01:00
split_sheet_preview - > connect ( " draw " , callable_mp ( this , & SpriteFramesEditor : : _sheet_preview_draw ) ) ;
split_sheet_preview - > connect ( " gui_input " , callable_mp ( this , & SpriteFramesEditor : : _sheet_preview_input ) ) ;
2019-04-14 08:24:22 +02:00
2021-05-23 01:03:52 +02:00
split_sheet_scroll = memnew ( ScrollContainer ) ;
split_sheet_scroll - > connect ( " gui_input " , callable_mp ( this , & SpriteFramesEditor : : _sheet_scroll_input ) ) ;
split_sheet_panel - > add_child ( split_sheet_scroll ) ;
2019-04-14 08:24:22 +02:00
CenterContainer * cc = memnew ( CenterContainer ) ;
cc - > add_child ( split_sheet_preview ) ;
cc - > set_h_size_flags ( SIZE_EXPAND_FILL ) ;
cc - > set_v_size_flags ( SIZE_EXPAND_FILL ) ;
2021-05-23 01:03:52 +02:00
split_sheet_scroll - > add_child ( cc ) ;
2019-04-14 08:24:22 +02:00
2020-08-13 13:15:08 +02:00
MarginContainer * split_sheet_zoom_margin = memnew ( MarginContainer ) ;
split_sheet_panel - > add_child ( split_sheet_zoom_margin ) ;
split_sheet_zoom_margin - > set_h_size_flags ( 0 ) ;
split_sheet_zoom_margin - > set_v_size_flags ( 0 ) ;
2022-02-08 10:14:58 +01:00
split_sheet_zoom_margin - > add_theme_constant_override ( " margin_top " , 5 ) ;
split_sheet_zoom_margin - > add_theme_constant_override ( " margin_left " , 5 ) ;
2020-08-13 13:15:08 +02:00
HBoxContainer * split_sheet_zoom_hb = memnew ( HBoxContainer ) ;
split_sheet_zoom_margin - > add_child ( split_sheet_zoom_hb ) ;
split_sheet_zoom_out = memnew ( Button ) ;
split_sheet_zoom_out - > set_flat ( true ) ;
split_sheet_zoom_out - > set_focus_mode ( FOCUS_NONE ) ;
2022-08-25 12:42:17 +02:00
split_sheet_zoom_out - > set_tooltip_text ( TTR ( " Zoom Out " ) ) ;
2020-08-13 13:15:08 +02:00
split_sheet_zoom_out - > connect ( " pressed " , callable_mp ( this , & SpriteFramesEditor : : _sheet_zoom_out ) ) ;
split_sheet_zoom_hb - > add_child ( split_sheet_zoom_out ) ;
2021-05-23 01:03:52 +02:00
split_sheet_zoom_reset = memnew ( Button ) ;
split_sheet_zoom_reset - > set_flat ( true ) ;
split_sheet_zoom_reset - > set_focus_mode ( FOCUS_NONE ) ;
2022-08-25 12:42:17 +02:00
split_sheet_zoom_reset - > set_tooltip_text ( TTR ( " Zoom Reset " ) ) ;
2021-05-23 01:03:52 +02:00
split_sheet_zoom_reset - > connect ( " pressed " , callable_mp ( this , & SpriteFramesEditor : : _sheet_zoom_reset ) ) ;
split_sheet_zoom_hb - > add_child ( split_sheet_zoom_reset ) ;
2020-08-13 13:15:08 +02:00
split_sheet_zoom_in = memnew ( Button ) ;
split_sheet_zoom_in - > set_flat ( true ) ;
split_sheet_zoom_in - > set_focus_mode ( FOCUS_NONE ) ;
2022-08-25 12:42:17 +02:00
split_sheet_zoom_in - > set_tooltip_text ( TTR ( " Zoom In " ) ) ;
2020-08-13 13:15:08 +02:00
split_sheet_zoom_in - > connect ( " pressed " , callable_mp ( this , & SpriteFramesEditor : : _sheet_zoom_in ) ) ;
split_sheet_zoom_hb - > add_child ( split_sheet_zoom_in ) ;
2019-04-14 03:15:31 +02:00
file_split_sheet = memnew ( EditorFileDialog ) ;
2019-04-14 08:24:22 +02:00
file_split_sheet - > set_title ( TTR ( " Create Frames from Sprite Sheet " ) ) ;
2020-03-06 18:00:16 +01:00
file_split_sheet - > set_file_mode ( EditorFileDialog : : FILE_MODE_OPEN_FILE ) ;
2019-04-14 03:15:31 +02:00
add_child ( file_split_sheet ) ;
2020-02-21 18:28:45 +01:00
file_split_sheet - > connect ( " file_selected " , callable_mp ( this , & SpriteFramesEditor : : _prepare_sprite_sheet ) ) ;
2020-08-13 13:15:08 +02:00
// Config scale.
scale_ratio = 1.2f ;
2021-05-23 01:03:52 +02:00
thumbnail_default_size = 96 * MAX ( 1 , EDSCALE ) ;
thumbnail_zoom = MAX ( 1.0f , EDSCALE ) ;
max_thumbnail_zoom = 8.0f * MAX ( 1.0f , EDSCALE ) ;
min_thumbnail_zoom = 0.1f * MAX ( 1.0f , EDSCALE ) ;
2021-03-12 19:05:45 +01:00
// Default the zoom to match the editor scale, but don't dezoom on editor scales below 100% to prevent pixel art from looking bad.
2021-05-23 01:03:52 +02:00
sheet_zoom = MAX ( 1.0f , EDSCALE ) ;
max_sheet_zoom = 16.0f * MAX ( 1.0f , EDSCALE ) ;
min_sheet_zoom = 0.01f * MAX ( 1.0f , EDSCALE ) ;
2020-08-13 13:15:08 +02:00
_zoom_reset ( ) ;
2021-06-10 15:42:55 +02:00
// Ensure the anim search box is wide enough by default.
2022-11-14 18:52:29 +01:00
// Not by setting its minimum size so it can still be shrunk if desired.
2021-06-10 15:42:55 +02:00
set_split_offset ( 56 * EDSCALE ) ;
2014-02-10 02:10:30 +01:00
}
void SpriteFramesEditorPlugin : : edit ( Object * p_object ) {
2018-10-11 17:03:14 +02:00
SpriteFrames * s ;
2020-03-26 22:49:16 +01:00
AnimatedSprite2D * animated_sprite = Object : : cast_to < AnimatedSprite2D > ( p_object ) ;
2018-10-11 17:03:14 +02:00
if ( animated_sprite ) {
s = * animated_sprite - > get_sprite_frames ( ) ;
} else {
2020-03-26 22:49:16 +01:00
AnimatedSprite3D * animated_sprite_3d = Object : : cast_to < AnimatedSprite3D > ( p_object ) ;
if ( animated_sprite_3d ) {
s = * animated_sprite_3d - > get_sprite_frames ( ) ;
} else {
s = Object : : cast_to < SpriteFrames > ( p_object ) ;
}
2018-10-11 17:03:14 +02:00
}
2014-02-10 02:10:30 +01:00
frames_editor - > edit ( s ) ;
}
bool SpriteFramesEditorPlugin : : handles ( Object * p_object ) const {
2020-03-26 22:49:16 +01:00
AnimatedSprite2D * animated_sprite = Object : : cast_to < AnimatedSprite2D > ( p_object ) ;
AnimatedSprite3D * animated_sprite_3d = Object : : cast_to < AnimatedSprite3D > ( p_object ) ;
2018-10-11 17:03:14 +02:00
if ( animated_sprite & & * animated_sprite - > get_sprite_frames ( ) ) {
return true ;
2020-03-26 22:49:16 +01:00
} else if ( animated_sprite_3d & & * animated_sprite_3d - > get_sprite_frames ( ) ) {
return true ;
2018-10-11 17:03:14 +02:00
} else {
return p_object - > is_class ( " SpriteFrames " ) ;
}
2014-02-10 02:10:30 +01:00
}
void SpriteFramesEditorPlugin : : make_visible ( bool p_visible ) {
if ( p_visible ) {
2016-01-18 00:03:57 +01:00
button - > show ( ) ;
2022-01-27 10:36:51 +01:00
EditorNode : : get_singleton ( ) - > make_bottom_panel_item_visible ( frames_editor ) ;
2014-02-10 02:10:30 +01:00
} else {
2016-01-18 00:03:57 +01:00
button - > hide ( ) ;
2020-05-14 16:41:43 +02:00
if ( frames_editor - > is_visible_in_tree ( ) ) {
2022-01-27 10:36:51 +01:00
EditorNode : : get_singleton ( ) - > hide_bottom_panel ( ) ;
2020-05-14 16:41:43 +02:00
}
2014-02-10 02:10:30 +01:00
}
}
2022-01-27 10:36:51 +01:00
SpriteFramesEditorPlugin : : SpriteFramesEditorPlugin ( ) {
2014-02-10 02:10:30 +01:00
frames_editor = memnew ( SpriteFramesEditor ) ;
2017-10-13 23:39:17 +02:00
frames_editor - > set_custom_minimum_size ( Size2 ( 0 , 300 ) * EDSCALE ) ;
2022-01-27 10:36:51 +01:00
button = EditorNode : : get_singleton ( ) - > add_bottom_panel_item ( TTR ( " SpriteFrames " ) , frames_editor ) ;
2016-01-18 00:03:57 +01:00
button - > hide ( ) ;
2014-02-10 02:10:30 +01:00
}
SpriteFramesEditorPlugin : : ~ SpriteFramesEditorPlugin ( ) {
}