improved animation editor
-same-value link keys -new layout -forward, backwards playback -integrated curve/property editor -auto increment sprite frame after insert -copy & paste animation resoucres
|  | @ -995,12 +995,44 @@ Variant Object::get_meta(const String& p_name) const { | ||||||
| 	return metadata[p_name]; | 	return metadata[p_name]; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | 
 | ||||||
| Array Object::_get_property_list_bind() const { | Array Object::_get_property_list_bind() const { | ||||||
| 
 | 
 | ||||||
| 	List<PropertyInfo> lpi; | 	List<PropertyInfo> lpi; | ||||||
| 	get_property_list(&lpi); | 	get_property_list(&lpi); | ||||||
| 	return convert_property_list(&lpi); | 	return convert_property_list(&lpi); | ||||||
| } | } | ||||||
|  | 
 | ||||||
|  | Array Object::_get_method_list_bind() const { | ||||||
|  | 
 | ||||||
|  | 	List<MethodInfo> ml; | ||||||
|  | 	get_method_list(&ml); | ||||||
|  | 	Array ret; | ||||||
|  | 
 | ||||||
|  | 	for(List<MethodInfo>::Element *E=ml.front();E;E=E->next()) { | ||||||
|  | 
 | ||||||
|  | 		Dictionary d; | ||||||
|  | 		d["name"]=E->get().name; | ||||||
|  | 		d["args"]=convert_property_list(&E->get().arguments); | ||||||
|  | 		Array da; | ||||||
|  | 		for(int i=0;i<E->get().default_arguments.size();i++) | ||||||
|  | 			da.push_back(E->get().default_arguments[i]); | ||||||
|  | 		d["default_args"]=da; | ||||||
|  | 		d["flags"]=E->get().flags; | ||||||
|  | 		d["id"]=E->get().id; | ||||||
|  | 		Dictionary r; | ||||||
|  | 		r["type"]=E->get().return_val.type; | ||||||
|  | 		r["hint"]=E->get().return_val.hint; | ||||||
|  | 		r["hint_string"]=E->get().return_val.hint_string; | ||||||
|  | 		d["return_type"]=r; | ||||||
|  | 		//va.push_back(d);
 | ||||||
|  | 		ret.push_back(d); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return ret; | ||||||
|  | 
 | ||||||
|  | } | ||||||
|  | 
 | ||||||
| DVector<String> Object::_get_meta_list_bind() const { | DVector<String> Object::_get_meta_list_bind() const { | ||||||
| 
 | 
 | ||||||
| 	DVector<String> _metaret; | 	DVector<String> _metaret; | ||||||
|  | @ -1439,6 +1471,7 @@ void Object::_bind_methods() { | ||||||
| 	ObjectTypeDB::bind_method(_MD("set","property","value"),&Object::_set_bind); | 	ObjectTypeDB::bind_method(_MD("set","property","value"),&Object::_set_bind); | ||||||
| 	ObjectTypeDB::bind_method(_MD("get","property"),&Object::_get_bind); | 	ObjectTypeDB::bind_method(_MD("get","property"),&Object::_get_bind); | ||||||
| 	ObjectTypeDB::bind_method(_MD("get_property_list"),&Object::_get_property_list_bind); | 	ObjectTypeDB::bind_method(_MD("get_property_list"),&Object::_get_property_list_bind); | ||||||
|  | 	ObjectTypeDB::bind_method(_MD("get_method_list"),&Object::_get_method_list_bind); | ||||||
| 	ObjectTypeDB::bind_method(_MD("notification","what"),&Object::notification,DEFVAL(false)); | 	ObjectTypeDB::bind_method(_MD("notification","what"),&Object::notification,DEFVAL(false)); | ||||||
| 	ObjectTypeDB::bind_method(_MD("get_instance_ID"),&Object::get_instance_ID); | 	ObjectTypeDB::bind_method(_MD("get_instance_ID"),&Object::get_instance_ID); | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -54,6 +54,7 @@ enum PropertyHint { | ||||||
| 	PROPERTY_HINT_ENUM, ///< hint_text= "val1,val2,val3,etc"
 | 	PROPERTY_HINT_ENUM, ///< hint_text= "val1,val2,val3,etc"
 | ||||||
| 	PROPERTY_HINT_EXP_EASING, /// exponential easing funciton (Math::ease)
 | 	PROPERTY_HINT_EXP_EASING, /// exponential easing funciton (Math::ease)
 | ||||||
| 	PROPERTY_HINT_LENGTH, ///< hint_text= "length" (as integer)
 | 	PROPERTY_HINT_LENGTH, ///< hint_text= "length" (as integer)
 | ||||||
|  | 	PROPERTY_HINT_SPRITE_FRAME, | ||||||
| 	PROPERTY_HINT_KEY_ACCEL, ///< hint_text= "length" (as integer)
 | 	PROPERTY_HINT_KEY_ACCEL, ///< hint_text= "length" (as integer)
 | ||||||
| 	PROPERTY_HINT_FLAGS, ///< hint_text= "flag1,flag2,etc" (as bit flags)
 | 	PROPERTY_HINT_FLAGS, ///< hint_text= "flag1,flag2,etc" (as bit flags)
 | ||||||
| 	PROPERTY_HINT_ALL_FLAGS, | 	PROPERTY_HINT_ALL_FLAGS, | ||||||
|  | @ -448,6 +449,7 @@ protected: | ||||||
| 
 | 
 | ||||||
| 	DVector<String> _get_meta_list_bind() const; | 	DVector<String> _get_meta_list_bind() const; | ||||||
| 	Array _get_property_list_bind() const; | 	Array _get_property_list_bind() const; | ||||||
|  | 	Array _get_method_list_bind() const; | ||||||
| 
 | 
 | ||||||
| public: //should be protected, but bug in clang++
 | public: //should be protected, but bug in clang++
 | ||||||
| 	static void initialize_type(); | 	static void initialize_type(); | ||||||
|  |  | ||||||
|  | @ -31,7 +31,20 @@ | ||||||
| 
 | 
 | ||||||
| void MainLoop::_bind_methods() { | void MainLoop::_bind_methods() { | ||||||
| 
 | 
 | ||||||
| 	ObjectTypeDB::bind_method("input_event",&MainLoop::input_event); | 	ObjectTypeDB::bind_method(_MD("input_event","ev"),&MainLoop::input_event); | ||||||
|  | 	ObjectTypeDB::bind_method(_MD("input_text","text"),&MainLoop::input_text); | ||||||
|  | 	ObjectTypeDB::bind_method(_MD("init"),&MainLoop::init); | ||||||
|  | 	ObjectTypeDB::bind_method(_MD("iteration","delta"),&MainLoop::iteration); | ||||||
|  | 	ObjectTypeDB::bind_method(_MD("idle","delta"),&MainLoop::idle); | ||||||
|  | 	ObjectTypeDB::bind_method(_MD("finish"),&MainLoop::finish); | ||||||
|  | 
 | ||||||
|  | 	BIND_VMETHOD( MethodInfo("_input_event",PropertyInfo(Variant::INPUT_EVENT,"ev")) ); | ||||||
|  | 	BIND_VMETHOD( MethodInfo("_input_text",PropertyInfo(Variant::STRING,"text")) ); | ||||||
|  | 	BIND_VMETHOD( MethodInfo("_initialize") ); | ||||||
|  | 	BIND_VMETHOD( MethodInfo("_iteration",PropertyInfo(Variant::REAL,"delta")) ); | ||||||
|  | 	BIND_VMETHOD( MethodInfo("_idle",PropertyInfo(Variant::REAL,"delta")) ); | ||||||
|  | 	BIND_VMETHOD( MethodInfo("_finalize") ); | ||||||
|  | 
 | ||||||
| 
 | 
 | ||||||
| 	BIND_CONSTANT(NOTIFICATION_WM_FOCUS_IN); | 	BIND_CONSTANT(NOTIFICATION_WM_FOCUS_IN); | ||||||
| 	BIND_CONSTANT(NOTIFICATION_WM_FOCUS_OUT); | 	BIND_CONSTANT(NOTIFICATION_WM_FOCUS_OUT); | ||||||
|  | @ -58,13 +71,15 @@ MainLoop::~MainLoop() | ||||||
| 
 | 
 | ||||||
| void MainLoop::input_text( const String& p_text ) { | void MainLoop::input_text( const String& p_text ) { | ||||||
| 
 | 
 | ||||||
|  | 	if (get_script_instance()) | ||||||
|  | 		get_script_instance()->call("_input_text",p_text); | ||||||
| 
 | 
 | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void MainLoop::input_event( const InputEvent& p_event ) { | void MainLoop::input_event( const InputEvent& p_event ) { | ||||||
| 
 | 
 | ||||||
| 	if (get_script_instance()) | 	if (get_script_instance()) | ||||||
| 		get_script_instance()->call("input_event",p_event); | 		get_script_instance()->call("_input_event",p_event); | ||||||
| 
 | 
 | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | @ -74,13 +89,13 @@ void MainLoop::init() { | ||||||
| 		set_script(init_script.get_ref_ptr()); | 		set_script(init_script.get_ref_ptr()); | ||||||
| 
 | 
 | ||||||
| 	if (get_script_instance()) | 	if (get_script_instance()) | ||||||
| 		get_script_instance()->call("init"); | 		get_script_instance()->call("_initialize"); | ||||||
| 
 | 
 | ||||||
| } | } | ||||||
| bool MainLoop::iteration(float p_time) { | bool MainLoop::iteration(float p_time) { | ||||||
| 
 | 
 | ||||||
| 	if (get_script_instance()) | 	if (get_script_instance()) | ||||||
| 		return get_script_instance()->call("iteration",p_time); | 		return get_script_instance()->call("_iteration",p_time); | ||||||
| 
 | 
 | ||||||
| 	return false; | 	return false; | ||||||
| 
 | 
 | ||||||
|  | @ -88,14 +103,14 @@ bool MainLoop::iteration(float p_time) { | ||||||
| bool MainLoop::idle(float p_time) { | bool MainLoop::idle(float p_time) { | ||||||
| 
 | 
 | ||||||
| 	if (get_script_instance()) | 	if (get_script_instance()) | ||||||
| 		return get_script_instance()->call("idle",p_time); | 		return get_script_instance()->call("_idle",p_time); | ||||||
| 
 | 
 | ||||||
| 	return false; | 	return false; | ||||||
| } | } | ||||||
| void MainLoop::finish() { | void MainLoop::finish() { | ||||||
| 
 | 
 | ||||||
| 	if (get_script_instance()) { | 	if (get_script_instance()) { | ||||||
| 		get_script_instance()->call("finish"); | 		get_script_instance()->call("_finalize"); | ||||||
| 		set_script(RefPtr()); //clear script
 | 		set_script(RefPtr()); //clear script
 | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -329,7 +329,7 @@ void AnimatedSprite::_bind_methods() { | ||||||
| 	ADD_SIGNAL(MethodInfo("frame_changed")); | 	ADD_SIGNAL(MethodInfo("frame_changed")); | ||||||
| 
 | 
 | ||||||
| 	ADD_PROPERTYNZ( PropertyInfo( Variant::OBJECT, "frames",PROPERTY_HINT_RESOURCE_TYPE,"SpriteFrames"), _SCS("set_sprite_frames"),_SCS("get_sprite_frames")); | 	ADD_PROPERTYNZ( PropertyInfo( Variant::OBJECT, "frames",PROPERTY_HINT_RESOURCE_TYPE,"SpriteFrames"), _SCS("set_sprite_frames"),_SCS("get_sprite_frames")); | ||||||
| 	ADD_PROPERTYNZ( PropertyInfo( Variant::INT, "frame"), _SCS("set_frame"),_SCS("get_frame")); | 	ADD_PROPERTYNZ( PropertyInfo( Variant::INT, "frame",PROPERTY_HINT_SPRITE_FRAME), _SCS("set_frame"),_SCS("get_frame")); | ||||||
| 	ADD_PROPERTY( PropertyInfo( Variant::BOOL, "centered"), _SCS("set_centered"),_SCS("is_centered")); | 	ADD_PROPERTY( PropertyInfo( Variant::BOOL, "centered"), _SCS("set_centered"),_SCS("is_centered")); | ||||||
| 	ADD_PROPERTYNZ( PropertyInfo( Variant::VECTOR2, "offset"), _SCS("set_offset"),_SCS("get_offset")); | 	ADD_PROPERTYNZ( PropertyInfo( Variant::VECTOR2, "offset"), _SCS("set_offset"),_SCS("get_offset")); | ||||||
| 	ADD_PROPERTY( PropertyInfo( Variant::BOOL, "flip_h"), _SCS("set_flip_h"),_SCS("is_flipped_h")); | 	ADD_PROPERTY( PropertyInfo( Variant::BOOL, "flip_h"), _SCS("set_flip_h"),_SCS("is_flipped_h")); | ||||||
|  |  | ||||||
|  | @ -320,7 +320,7 @@ void Sprite::_bind_methods() { | ||||||
| 	ADD_PROPERTY( PropertyInfo( Variant::BOOL, "flip_v"), _SCS("set_flip_v"),_SCS("is_flipped_v")); | 	ADD_PROPERTY( PropertyInfo( Variant::BOOL, "flip_v"), _SCS("set_flip_v"),_SCS("is_flipped_v")); | ||||||
| 	ADD_PROPERTY( PropertyInfo( Variant::INT, "vframes"), _SCS("set_vframes"),_SCS("get_vframes")); | 	ADD_PROPERTY( PropertyInfo( Variant::INT, "vframes"), _SCS("set_vframes"),_SCS("get_vframes")); | ||||||
| 	ADD_PROPERTY( PropertyInfo( Variant::INT, "hframes"), _SCS("set_hframes"),_SCS("get_hframes")); | 	ADD_PROPERTY( PropertyInfo( Variant::INT, "hframes"), _SCS("set_hframes"),_SCS("get_hframes")); | ||||||
| 	ADD_PROPERTY( PropertyInfo( Variant::INT, "frame"), _SCS("set_frame"),_SCS("get_frame")); | 	ADD_PROPERTY( PropertyInfo( Variant::INT, "frame",PROPERTY_HINT_SPRITE_FRAME), _SCS("set_frame"),_SCS("get_frame")); | ||||||
| 	ADD_PROPERTY( PropertyInfo( Variant::COLOR, "modulate"), _SCS("set_modulate"),_SCS("get_modulate")); | 	ADD_PROPERTY( PropertyInfo( Variant::COLOR, "modulate"), _SCS("set_modulate"),_SCS("get_modulate")); | ||||||
| 	ADD_PROPERTY( PropertyInfo( Variant::BOOL, "region"), _SCS("set_region"),_SCS("is_region")); | 	ADD_PROPERTY( PropertyInfo( Variant::BOOL, "region"), _SCS("set_region"),_SCS("is_region")); | ||||||
| 	ADD_PROPERTY( PropertyInfo( Variant::RECT2, "region_rect"), _SCS("set_region_rect"),_SCS("get_region_rect")); | 	ADD_PROPERTY( PropertyInfo( Variant::RECT2, "region_rect"), _SCS("set_region_rect"),_SCS("get_region_rect")); | ||||||
|  |  | ||||||
|  | @ -580,7 +580,7 @@ void Sprite3D::_bind_methods() { | ||||||
| 	ADD_PROPERTY( PropertyInfo( Variant::OBJECT, "texture", PROPERTY_HINT_RESOURCE_TYPE,"Texture"), _SCS("set_texture"),_SCS("get_texture")); | 	ADD_PROPERTY( PropertyInfo( Variant::OBJECT, "texture", PROPERTY_HINT_RESOURCE_TYPE,"Texture"), _SCS("set_texture"),_SCS("get_texture")); | ||||||
| 	ADD_PROPERTY( PropertyInfo( Variant::INT, "vframes"), _SCS("set_vframes"),_SCS("get_vframes")); | 	ADD_PROPERTY( PropertyInfo( Variant::INT, "vframes"), _SCS("set_vframes"),_SCS("get_vframes")); | ||||||
| 	ADD_PROPERTY( PropertyInfo( Variant::INT, "hframes"), _SCS("set_hframes"),_SCS("get_hframes")); | 	ADD_PROPERTY( PropertyInfo( Variant::INT, "hframes"), _SCS("set_hframes"),_SCS("get_hframes")); | ||||||
| 	ADD_PROPERTY( PropertyInfo( Variant::INT, "frame"), _SCS("set_frame"),_SCS("get_frame")); | 	ADD_PROPERTY( PropertyInfo( Variant::INT, "frame",PROPERTY_HINT_SPRITE_FRAME), _SCS("set_frame"),_SCS("get_frame")); | ||||||
| 	ADD_PROPERTY( PropertyInfo( Variant::BOOL, "region"), _SCS("set_region"),_SCS("is_region")); | 	ADD_PROPERTY( PropertyInfo( Variant::BOOL, "region"), _SCS("set_region"),_SCS("is_region")); | ||||||
| 	ADD_PROPERTY( PropertyInfo( Variant::RECT2, "region_rect"), _SCS("set_region_rect"),_SCS("get_region_rect")); | 	ADD_PROPERTY( PropertyInfo( Variant::RECT2, "region_rect"), _SCS("set_region_rect"),_SCS("get_region_rect")); | ||||||
| 
 | 
 | ||||||
|  | @ -727,7 +727,7 @@ void AnimatedSprite3D::_bind_methods(){ | ||||||
| 	ObjectTypeDB::bind_method(_MD("get_frame"),&AnimatedSprite3D::get_frame); | 	ObjectTypeDB::bind_method(_MD("get_frame"),&AnimatedSprite3D::get_frame); | ||||||
| 
 | 
 | ||||||
| 	ADD_PROPERTY( PropertyInfo( Variant::OBJECT, "frames", PROPERTY_HINT_RESOURCE_TYPE,"SpriteFrames"), _SCS("set_sprite_frames"),_SCS("get_sprite_frames")); | 	ADD_PROPERTY( PropertyInfo( Variant::OBJECT, "frames", PROPERTY_HINT_RESOURCE_TYPE,"SpriteFrames"), _SCS("set_sprite_frames"),_SCS("get_sprite_frames")); | ||||||
| 	ADD_PROPERTY( PropertyInfo( Variant::INT, "frame"), _SCS("set_frame"),_SCS("get_frame")); | 	ADD_PROPERTY( PropertyInfo( Variant::INT, "frame",PROPERTY_HINT_SPRITE_FRAME), _SCS("set_frame"),_SCS("get_frame")); | ||||||
| 
 | 
 | ||||||
| 	ADD_SIGNAL(MethodInfo("frame_changed")); | 	ADD_SIGNAL(MethodInfo("frame_changed")); | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -967,14 +967,16 @@ String AnimationPlayer::get_current_animation() const { | ||||||
| 
 | 
 | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void AnimationPlayer::stop() { | void AnimationPlayer::stop(bool p_reset) { | ||||||
| 	 | 	 | ||||||
| 	Playback &c=playback; | 	Playback &c=playback; | ||||||
| 	c.blend.clear(); | 	c.blend.clear(); | ||||||
| 	c.current.from=NULL; | 	if (p_reset) { | ||||||
|  | 		c.current.from=NULL; | ||||||
|  | 	} | ||||||
| 	_set_process(false); | 	_set_process(false); | ||||||
| 	queued.clear(); | 	queued.clear(); | ||||||
|     playing = false; | 	playing = false; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void AnimationPlayer::stop_all() { | void AnimationPlayer::stop_all() { | ||||||
|  | @ -1211,7 +1213,7 @@ void AnimationPlayer::_bind_methods() { | ||||||
| 	ObjectTypeDB::bind_method(_MD("get_default_blend_time"),&AnimationPlayer::get_default_blend_time); | 	ObjectTypeDB::bind_method(_MD("get_default_blend_time"),&AnimationPlayer::get_default_blend_time); | ||||||
| 
 | 
 | ||||||
| 	ObjectTypeDB::bind_method(_MD("play","name","custom_blend","custom_speed","from_end"),&AnimationPlayer::play,DEFVAL(""),DEFVAL(-1),DEFVAL(1.0),DEFVAL(false)); | 	ObjectTypeDB::bind_method(_MD("play","name","custom_blend","custom_speed","from_end"),&AnimationPlayer::play,DEFVAL(""),DEFVAL(-1),DEFVAL(1.0),DEFVAL(false)); | ||||||
| 	ObjectTypeDB::bind_method(_MD("stop"),&AnimationPlayer::stop); | 	ObjectTypeDB::bind_method(_MD("stop","reset"),&AnimationPlayer::stop,DEFVAL(true)); | ||||||
| 	ObjectTypeDB::bind_method(_MD("stop_all"),&AnimationPlayer::stop_all); | 	ObjectTypeDB::bind_method(_MD("stop_all"),&AnimationPlayer::stop_all); | ||||||
| 	ObjectTypeDB::bind_method(_MD("is_playing"),&AnimationPlayer::is_playing); | 	ObjectTypeDB::bind_method(_MD("is_playing"),&AnimationPlayer::is_playing); | ||||||
| 	ObjectTypeDB::bind_method(_MD("set_current_animation","anim"),&AnimationPlayer::set_current_animation); | 	ObjectTypeDB::bind_method(_MD("set_current_animation","anim"),&AnimationPlayer::set_current_animation); | ||||||
|  |  | ||||||
|  | @ -260,7 +260,7 @@ public: | ||||||
| 	void play(const StringName& p_name=StringName(),float p_custom_blend=-1,float p_custom_scale=1.0,bool p_from_end=false); | 	void play(const StringName& p_name=StringName(),float p_custom_blend=-1,float p_custom_scale=1.0,bool p_from_end=false); | ||||||
| 	void queue(const StringName& p_name); | 	void queue(const StringName& p_name); | ||||||
| 	void clear_queue(); | 	void clear_queue(); | ||||||
| 	void stop(); | 	void stop(bool p_reset=true); | ||||||
| 	bool is_playing() const; | 	bool is_playing() const; | ||||||
| 	String get_current_animation() const; | 	String get_current_animation() const; | ||||||
| 	void set_current_animation(const String& p_anim); | 	void set_current_animation(const String& p_anim); | ||||||
|  |  | ||||||
|  | @ -44,11 +44,207 @@ | ||||||
| */ | */ | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|  | class AnimationCurveEdit : public Control { | ||||||
|  | 	OBJ_TYPE( AnimationCurveEdit, Control ); | ||||||
|  | public: | ||||||
|  | 	enum Mode { | ||||||
|  | 		MODE_DISABLED, | ||||||
|  | 		MODE_SINGLE, | ||||||
|  | 		MODE_MULTIPLE | ||||||
|  | 	}; | ||||||
|  | private: | ||||||
|  | 
 | ||||||
|  | 	Set<float> multiples; | ||||||
|  | 	float transition; | ||||||
|  | 	Mode mode; | ||||||
|  | 
 | ||||||
|  | 	void _notification(int p_what) { | ||||||
|  | 
 | ||||||
|  | 		if (p_what==NOTIFICATION_DRAW) { | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | 			RID ci = get_canvas_item(); | ||||||
|  | 
 | ||||||
|  | 			Size2 s = get_size(); | ||||||
|  | 			Rect2 r(Point2(),s); | ||||||
|  | 
 | ||||||
|  | 			//r=r.grow(3);
 | ||||||
|  | 			Ref<StyleBox> sb = get_stylebox("normal","LineEdit"); | ||||||
|  | 			sb->draw(ci,r); | ||||||
|  | 			r.size-=sb->get_minimum_size(); | ||||||
|  | 			r.pos+=sb->get_offset(); | ||||||
|  | 			//VisualServer::get_singleton()->canvas_item_add
 | ||||||
|  | 
 | ||||||
|  | 			Ref<Font> f = get_font("font","Label"); | ||||||
|  | 			r=r.grow(-2); | ||||||
|  | 			Color color = get_color("font_color","Label"); | ||||||
|  | 
 | ||||||
|  | 			int points = 48; | ||||||
|  | 			if (mode==MODE_MULTIPLE) { | ||||||
|  | 
 | ||||||
|  | 				int max_draw = 16; | ||||||
|  | 				Color mcolor=color; | ||||||
|  | 				mcolor.a*=0.3; | ||||||
|  | 
 | ||||||
|  | 				Set<float>::Element *E=multiples.front(); | ||||||
|  | 				for(int j=0;j<16;j++) { | ||||||
|  | 
 | ||||||
|  | 					if (!E) | ||||||
|  | 						break; | ||||||
|  | 
 | ||||||
|  | 					float prev=1.0; | ||||||
|  | 					float exp=E->get(); | ||||||
|  | 					bool flip=false;//hint_text=="attenuation";
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | 					for(int i=1;i<=points;i++) { | ||||||
|  | 
 | ||||||
|  | 						float ifl = i/float(points); | ||||||
|  | 						float iflp = (i-1)/float(points); | ||||||
|  | 
 | ||||||
|  | 						float h = 1.0-Math::ease(ifl,exp); | ||||||
|  | 
 | ||||||
|  | 						if (flip) { | ||||||
|  | 							ifl=1.0-ifl; | ||||||
|  | 							iflp=1.0-iflp; | ||||||
|  | 						} | ||||||
|  | 
 | ||||||
|  | 						VisualServer::get_singleton()->canvas_item_add_line(ci,r.pos+Point2(iflp*r.size.width,prev*r.size.height),r.pos+Point2(ifl*r.size.width,h*r.size.height),mcolor); | ||||||
|  | 						prev=h; | ||||||
|  | 					} | ||||||
|  | 
 | ||||||
|  | 					E=E->next(); | ||||||
|  | 				} | ||||||
|  | 			} | ||||||
|  | 
 | ||||||
|  | 			float exp=transition; | ||||||
|  | 			if (mode!=MODE_DISABLED) { | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | 				float prev=1.0; | ||||||
|  | 
 | ||||||
|  | 				bool flip=false;//hint_text=="attenuation";
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | 				for(int i=1;i<=points;i++) { | ||||||
|  | 
 | ||||||
|  | 					float ifl = i/float(points); | ||||||
|  | 					float iflp = (i-1)/float(points); | ||||||
|  | 
 | ||||||
|  | 					float h = 1.0-Math::ease(ifl,exp); | ||||||
|  | 
 | ||||||
|  | 					if (flip) { | ||||||
|  | 						ifl=1.0-ifl; | ||||||
|  | 						iflp=1.0-iflp; | ||||||
|  | 					} | ||||||
|  | 
 | ||||||
|  | 					VisualServer::get_singleton()->canvas_item_add_line(ci,r.pos+Point2(iflp*r.size.width,prev*r.size.height),r.pos+Point2(ifl*r.size.width,h*r.size.height),color); | ||||||
|  | 					prev=h; | ||||||
|  | 				} | ||||||
|  | 			} | ||||||
|  | 
 | ||||||
|  | 			String txt=String::num(exp,2); | ||||||
|  | 			if (mode==MODE_DISABLED) { | ||||||
|  | 				txt="Disabled"; | ||||||
|  | 			} else if (mode==MODE_MULTIPLE) { | ||||||
|  | 				txt+=" - All Selection"; | ||||||
|  | 			} | ||||||
|  | 
 | ||||||
|  | 			f->draw(ci,Point2(10,10+f->get_ascent()),txt,color); | ||||||
|  | 
 | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	void _input_event(const InputEvent& p_ev) { | ||||||
|  | 		if (p_ev.type==InputEvent::MOUSE_MOTION && p_ev.mouse_motion.button_mask&BUTTON_MASK_LEFT) { | ||||||
|  | 
 | ||||||
|  | 			if (mode==MODE_DISABLED) | ||||||
|  | 				return; | ||||||
|  | 
 | ||||||
|  | 			float rel = p_ev.mouse_motion.relative_x; | ||||||
|  | 			if (rel==0) | ||||||
|  | 			    return; | ||||||
|  | 
 | ||||||
|  | 			bool flip=false; | ||||||
|  | 
 | ||||||
|  | 			if (flip) | ||||||
|  | 				rel=-rel; | ||||||
|  | 
 | ||||||
|  | 			float val = transition; | ||||||
|  | 			if (val==0) | ||||||
|  | 				return; | ||||||
|  | 			bool sg = val < 0; | ||||||
|  | 			val = Math::absf(val); | ||||||
|  | 
 | ||||||
|  | 			val = Math::log(val)/Math::log(2); | ||||||
|  | 			//logspace
 | ||||||
|  | 			val+=rel*0.05; | ||||||
|  | 			//
 | ||||||
|  | 
 | ||||||
|  | 			val = Math::pow(2,val); | ||||||
|  | 			if (sg) | ||||||
|  | 				val=-val; | ||||||
|  | 
 | ||||||
|  | 			transition=val; | ||||||
|  | 			update(); | ||||||
|  | 			//emit_signal("variant_changed");
 | ||||||
|  | 			emit_signal("transition_changed",transition); | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | public: | ||||||
|  | 
 | ||||||
|  | 	static void _bind_methods() { | ||||||
|  | 
 | ||||||
|  | 	//	ObjectTypeDB::bind_method("_update_obj",&AnimationKeyEdit::_update_obj);
 | ||||||
|  | 		ObjectTypeDB::bind_method("_input_event",&AnimationCurveEdit::_input_event); | ||||||
|  | 		ADD_SIGNAL(MethodInfo("transition_changed")); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	void set_mode(Mode p_mode) { | ||||||
|  | 
 | ||||||
|  | 		mode=p_mode; | ||||||
|  | 		update(); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	void clear_multiples() { multiples.clear(); update();} | ||||||
|  | 	void set_multiple(float p_transition) { | ||||||
|  | 
 | ||||||
|  | 		multiples.insert(p_transition); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	void set_transition(float p_transition) { | ||||||
|  | 		transition=p_transition; | ||||||
|  | 		update(); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	float get_transition() const { | ||||||
|  | 		return transition; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	void force_transition(float p_value) { | ||||||
|  | 		if (mode==MODE_DISABLED) | ||||||
|  | 			return; | ||||||
|  | 		transition=p_value; | ||||||
|  | 		emit_signal("transition_changed",p_value); | ||||||
|  | 		update(); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	AnimationCurveEdit() { | ||||||
|  | 
 | ||||||
|  | 		transition=1.0; | ||||||
|  | 		set_default_cursor_shape(CURSOR_HSPLIT); | ||||||
|  | 		mode=MODE_DISABLED; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | }; | ||||||
|  | 
 | ||||||
| class AnimationKeyEdit : public Object { | class AnimationKeyEdit : public Object { | ||||||
| 
 | 
 | ||||||
| 	OBJ_TYPE(AnimationKeyEdit,Object); | 	OBJ_TYPE(AnimationKeyEdit,Object); | ||||||
| public: | public: | ||||||
| 	bool setting; | 	bool setting; | ||||||
|  | 	bool hidden; | ||||||
| 
 | 
 | ||||||
| 	static void _bind_methods() { | 	static void _bind_methods() { | ||||||
| 
 | 
 | ||||||
|  | @ -56,12 +252,12 @@ public: | ||||||
| 		ObjectTypeDB::bind_method("_key_ofs_changed",&AnimationKeyEdit::_key_ofs_changed); | 		ObjectTypeDB::bind_method("_key_ofs_changed",&AnimationKeyEdit::_key_ofs_changed); | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	PopupDialog *ke_dialog; | 	//PopupDialog *ke_dialog;
 | ||||||
| 
 | 
 | ||||||
| 	void _update_obj(const Ref<Animation> &p_anim) { | 	void _update_obj(const Ref<Animation> &p_anim) { | ||||||
| 		if (setting) | 		if (setting) | ||||||
| 			return; | 			return; | ||||||
| 		if (!ke_dialog->is_visible()) | 		if (hidden) | ||||||
| 			return; | 			return; | ||||||
| 		if (!(animation==p_anim)) | 		if (!(animation==p_anim)) | ||||||
| 			return; | 			return; | ||||||
|  | @ -69,7 +265,7 @@ public: | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	void _key_ofs_changed(const Ref<Animation> &p_anim,float from, float to) { | 	void _key_ofs_changed(const Ref<Animation> &p_anim,float from, float to) { | ||||||
| 		if (!ke_dialog->is_visible()) | 		if (hidden) | ||||||
| 			return; | 			return; | ||||||
| 		if (!(animation==p_anim)) | 		if (!(animation==p_anim)) | ||||||
| 			return; | 			return; | ||||||
|  | @ -408,8 +604,8 @@ public: | ||||||
| 			} break; | 			} break; | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		if (animation->track_get_type(track)!=Animation::TYPE_METHOD) | 		//if (animation->track_get_type(track)!=Animation::TYPE_METHOD)
 | ||||||
| 			p_list->push_back( PropertyInfo( Variant::REAL, "easing", PROPERTY_HINT_EXP_EASING)); | 		//	p_list->push_back( PropertyInfo( Variant::REAL, "easing", PROPERTY_HINT_EXP_EASING));
 | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	UndoRedo *undo_redo; | 	UndoRedo *undo_redo; | ||||||
|  | @ -425,7 +621,7 @@ public: | ||||||
| 		_change_notify(); | 		_change_notify(); | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	AnimationKeyEdit() { key_ofs=0; track=-1; setting=false; } | 	AnimationKeyEdit() { hidden=true; key_ofs=0; track=-1; setting=false; } | ||||||
| 
 | 
 | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
|  | @ -610,6 +806,8 @@ void AnimationKeyEditor::_menu_track(int p_type) { | ||||||
| 
 | 
 | ||||||
| 				selection=new_selection; | 				selection=new_selection; | ||||||
| 				track_editor->update(); | 				track_editor->update(); | ||||||
|  | 				_edit_if_single_selection(); | ||||||
|  | 
 | ||||||
| 
 | 
 | ||||||
| 			} | 			} | ||||||
| 
 | 
 | ||||||
|  | @ -689,8 +887,31 @@ void AnimationKeyEditor::_menu_track(int p_type) { | ||||||
| 
 | 
 | ||||||
| 			optimize_dialog->popup_centered(Size2(250,180)); | 			optimize_dialog->popup_centered(Size2(250,180)); | ||||||
| 		} break; | 		} break; | ||||||
|  | 		case CURVE_SET_LINEAR: { | ||||||
|  | 			curve_edit->force_transition(1.0); | ||||||
| 
 | 
 | ||||||
|  | 		} break; | ||||||
|  | 		case CURVE_SET_IN: { | ||||||
| 
 | 
 | ||||||
|  | 			curve_edit->force_transition(4.0); | ||||||
|  | 
 | ||||||
|  | 		} break; | ||||||
|  | 		case CURVE_SET_OUT: { | ||||||
|  | 
 | ||||||
|  | 			curve_edit->force_transition(0.25); | ||||||
|  | 		} break; | ||||||
|  | 		case CURVE_SET_INOUT: { | ||||||
|  | 			curve_edit->force_transition(-4); | ||||||
|  | 
 | ||||||
|  | 		} break; | ||||||
|  | 		case CURVE_SET_OUTIN: { | ||||||
|  | 
 | ||||||
|  | 			curve_edit->force_transition(-0.25); | ||||||
|  | 		} break; | ||||||
|  | 		case CURVE_SET_CONSTANT: { | ||||||
|  | 
 | ||||||
|  | 			curve_edit->force_transition(0); | ||||||
|  | 		} break; | ||||||
| 
 | 
 | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
|  | @ -774,6 +995,7 @@ void AnimationKeyEditor::_track_editor_draw() { | ||||||
| 		h_scroll->hide(); | 		h_scroll->hide(); | ||||||
| 		menu_track->set_disabled(true); | 		menu_track->set_disabled(true); | ||||||
| 		edit_button->set_disabled(true); | 		edit_button->set_disabled(true); | ||||||
|  | 		key_editor_tab->hide(); | ||||||
| 		move_up_button->set_disabled(true); | 		move_up_button->set_disabled(true); | ||||||
| 		move_down_button->set_disabled(true); | 		move_down_button->set_disabled(true); | ||||||
| 		remove_button->set_disabled(true); | 		remove_button->set_disabled(true); | ||||||
|  | @ -785,6 +1007,8 @@ void AnimationKeyEditor::_track_editor_draw() { | ||||||
| 	move_up_button->set_disabled(false); | 	move_up_button->set_disabled(false); | ||||||
| 	move_down_button->set_disabled(false); | 	move_down_button->set_disabled(false); | ||||||
| 	remove_button->set_disabled(false); | 	remove_button->set_disabled(false); | ||||||
|  | 	if (edit_button->is_pressed()) | ||||||
|  | 		key_editor_tab->show(); | ||||||
| 
 | 
 | ||||||
| 	te_drawing=true; | 	te_drawing=true; | ||||||
| 
 | 
 | ||||||
|  | @ -1000,8 +1224,13 @@ void AnimationKeyEditor::_track_editor_draw() { | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
|  | 	Color sep_color=color; | ||||||
|  | 	color.a*=0.5; | ||||||
|  | 
 | ||||||
| 	for(int i=0;i<fit;i++) { | 	for(int i=0;i<fit;i++) { | ||||||
| 
 | 
 | ||||||
|  | 		//this code sucks, i always forget how it works
 | ||||||
|  | 
 | ||||||
| 		int idx = v_scroll->get_val() + i; | 		int idx = v_scroll->get_val() + i; | ||||||
| 		if (idx>=animation->get_track_count()) | 		if (idx>=animation->get_track_count()) | ||||||
| 			break; | 			break; | ||||||
|  | @ -1090,6 +1319,7 @@ void AnimationKeyEditor::_track_editor_draw() { | ||||||
| 		float key_hofs = -Math::floor(type_icon[tt]->get_height()/2); | 		float key_hofs = -Math::floor(type_icon[tt]->get_height()/2); | ||||||
| 
 | 
 | ||||||
| 		int kc=animation->track_get_key_count(idx); | 		int kc=animation->track_get_key_count(idx); | ||||||
|  | 		bool first=true; | ||||||
| 
 | 
 | ||||||
| 		for(int i=0;i<kc;i++) { | 		for(int i=0;i<kc;i++) { | ||||||
| 
 | 
 | ||||||
|  | @ -1116,7 +1346,22 @@ void AnimationKeyEditor::_track_editor_draw() { | ||||||
| 			if (mouse_over.over==MouseOver::OVER_KEY && mouse_over.track==idx && mouse_over.over_key==i) | 			if (mouse_over.over==MouseOver::OVER_KEY && mouse_over.track==idx && mouse_over.over_key==i) | ||||||
| 				tex=type_hover; | 				tex=type_hover; | ||||||
| 
 | 
 | ||||||
|  | 			Variant value = animation->track_get_key_value(idx,i); | ||||||
|  | 			if (first && i>0 && value==animation->track_get_key_value(idx,i-1)) { | ||||||
|  | 
 | ||||||
|  | 				te->draw_line(ofs+Vector2(name_limit,y+h/2),ofs+Point2(x,y+h/2),color); | ||||||
|  | 			} | ||||||
|  | 
 | ||||||
|  | 			if (i<kc-1 && value==animation->track_get_key_value(idx,i+1)) { | ||||||
|  | 				float x_n =  key_hofs + name_limit + (animation->track_get_key_time(idx,i+1)-keys_from)*zoom_scale; | ||||||
|  | 
 | ||||||
|  | 				x_n = MIN( x_n, settings_limit); | ||||||
|  | 				te->draw_line(ofs+Point2(x_n,y+h/2),ofs+Point2(x,y+h/2),color); | ||||||
|  | 
 | ||||||
|  | 			} | ||||||
|  | 
 | ||||||
| 			te->draw_texture(tex,ofs+Point2(x,y+key_vofs).floor()); | 			te->draw_texture(tex,ofs+Point2(x,y+key_vofs).floor()); | ||||||
|  | 			first=false; | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 	} | 	} | ||||||
|  | @ -1226,7 +1471,9 @@ void AnimationKeyEditor::_clear_selection_for_anim(const Ref<Animation>& p_anim) | ||||||
| 
 | 
 | ||||||
| 	if (!(animation==p_anim)) | 	if (!(animation==p_anim)) | ||||||
| 		return; | 		return; | ||||||
| 	selection.clear(); | 	//selection.clear();
 | ||||||
|  | 	_clear_selection(); | ||||||
|  | 
 | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void AnimationKeyEditor::_select_at_anim(const Ref<Animation>& p_anim,int p_track,float p_pos){ | void AnimationKeyEditor::_select_at_anim(const Ref<Animation>& p_anim,int p_track,float p_pos){ | ||||||
|  | @ -1244,6 +1491,7 @@ void AnimationKeyEditor::_select_at_anim(const Ref<Animation>& p_anim,int p_trac | ||||||
| 	ki.pos=p_pos; | 	ki.pos=p_pos; | ||||||
| 
 | 
 | ||||||
| 	selection.insert(sk,ki); | 	selection.insert(sk,ki); | ||||||
|  | 
 | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|  | @ -1283,6 +1531,83 @@ PropertyInfo AnimationKeyEditor::_find_hint_for_track(int p_idx) { | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|  | void AnimationKeyEditor::_curve_transition_changed(float p_what) { | ||||||
|  | 
 | ||||||
|  | 	if (selection.size()==0) | ||||||
|  | 		return; | ||||||
|  | 	if (selection.size()==1) | ||||||
|  | 		undo_redo->create_action("Edit Node Curve",true); | ||||||
|  | 	else | ||||||
|  | 		undo_redo->create_action("Edit Selection Curve",true); | ||||||
|  | 
 | ||||||
|  | 	for(Map<SelectedKey,KeyInfo>::Element *E=selection.front();E;E=E->next()) { | ||||||
|  | 
 | ||||||
|  | 		int track = E->key().track; | ||||||
|  | 		int key = E->key().key; | ||||||
|  | 		float prev_val = animation->track_get_key_transition(track,key); | ||||||
|  | 		undo_redo->add_do_method(animation.ptr(),"track_set_key_transition",track,key,p_what); | ||||||
|  | 		undo_redo->add_undo_method(animation.ptr(),"track_set_key_transition",track,key,prev_val); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	undo_redo->commit_action(); | ||||||
|  | 
 | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void AnimationKeyEditor::_toggle_edit_curves() { | ||||||
|  | 
 | ||||||
|  | 	if (edit_button->is_pressed()) | ||||||
|  | 		key_editor_tab->show(); | ||||||
|  | 	else | ||||||
|  | 		key_editor_tab->hide(); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | bool AnimationKeyEditor::_edit_if_single_selection() { | ||||||
|  | 
 | ||||||
|  | 	if (selection.size()!=1) { | ||||||
|  | 
 | ||||||
|  | 		if (selection.size()==0) { | ||||||
|  | 			curve_edit->set_mode(AnimationCurveEdit::MODE_DISABLED); | ||||||
|  | 			print_line("disable"); | ||||||
|  | 		} else { | ||||||
|  | 
 | ||||||
|  | 			curve_edit->set_mode(AnimationCurveEdit::MODE_MULTIPLE); | ||||||
|  | 			curve_edit->set_transition(1.0); | ||||||
|  | 			curve_edit->clear_multiples(); | ||||||
|  | 			//add all
 | ||||||
|  | 			for(Map<SelectedKey,KeyInfo>::Element *E=selection.front();E;E=E->next()) { | ||||||
|  | 
 | ||||||
|  | 				curve_edit->set_multiple(animation->track_get_key_transition(E->key().track,E->key().key)); | ||||||
|  | 			} | ||||||
|  | 			print_line("multiple"); | ||||||
|  | 
 | ||||||
|  | 		} | ||||||
|  | 		return false; | ||||||
|  | 	} | ||||||
|  | 	curve_edit->set_mode(AnimationCurveEdit::MODE_SINGLE); | ||||||
|  | 	print_line("regular"); | ||||||
|  | 
 | ||||||
|  | 	int idx = selection.front()->key().track; | ||||||
|  | 	int key = selection.front()->key().key; | ||||||
|  | 	{ | ||||||
|  | 
 | ||||||
|  | 		key_edit->animation=animation; | ||||||
|  | 		key_edit->track=idx; | ||||||
|  | 		key_edit->key_ofs=animation->track_get_key_time(idx,key); | ||||||
|  | 		key_edit->hint=_find_hint_for_track(idx); | ||||||
|  | 		key_edit->notify_change(); | ||||||
|  | 
 | ||||||
|  | 		curve_edit->set_transition(animation->track_get_key_transition(idx,key)); | ||||||
|  | 
 | ||||||
|  | 		/*key_edit_dialog->set_size( Size2( 200,200) );
 | ||||||
|  | 		key_edit_dialog->set_pos(  track_editor->get_global_pos() + ofs + mpos +Point2(-100,20)); | ||||||
|  | 		key_edit_dialog->popup();*/ | ||||||
|  | 
 | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return true; | ||||||
|  | 
 | ||||||
|  | } | ||||||
| 
 | 
 | ||||||
| void AnimationKeyEditor::_track_editor_input_event(const InputEvent& p_input) { | void AnimationKeyEditor::_track_editor_input_event(const InputEvent& p_input) { | ||||||
| 
 | 
 | ||||||
|  | @ -1364,9 +1689,12 @@ void AnimationKeyEditor::_track_editor_input_event(const InputEvent& p_input) { | ||||||
| 						undo_redo->add_undo_method(animation.ptr(),"track_insert_key",E->key().track,E->get().pos,animation->track_get_key_value(E->key().track,E->key().key),animation->track_get_key_transition(E->key().track,E->key().key)); | 						undo_redo->add_undo_method(animation.ptr(),"track_insert_key",E->key().track,E->get().pos,animation->track_get_key_value(E->key().track,E->key().key),animation->track_get_key_transition(E->key().track,E->key().key)); | ||||||
| 
 | 
 | ||||||
| 					} | 					} | ||||||
|  | 					undo_redo->add_do_method(this,"_clear_selection_for_anim",animation); | ||||||
|  | 					undo_redo->add_undo_method(this,"_clear_selection_for_anim",animation); | ||||||
| 					undo_redo->commit_action(); | 					undo_redo->commit_action(); | ||||||
| 					selection.clear(); | 					//selection.clear();
 | ||||||
| 					accept_event(); | 					accept_event(); | ||||||
|  | 					_edit_if_single_selection(); | ||||||
| 				} | 				} | ||||||
| 			} else if (animation.is_valid() && animation->get_track_count()>0) { | 			} else if (animation.is_valid() && animation->get_track_count()>0) { | ||||||
| 
 | 
 | ||||||
|  | @ -1552,20 +1880,7 @@ void AnimationKeyEditor::_track_editor_input_event(const InputEvent& p_input) { | ||||||
| 
 | 
 | ||||||
| 						} | 						} | ||||||
| 
 | 
 | ||||||
| 						if (mb.mod.command || edit_button->is_pressed()) { |  | ||||||
| 
 | 
 | ||||||
| 							key_edit->animation=animation; |  | ||||||
| 							key_edit->track=idx; |  | ||||||
| 							key_edit->key_ofs=animation->track_get_key_time(idx,key); |  | ||||||
| 							key_edit->hint=_find_hint_for_track(idx); |  | ||||||
| 
 |  | ||||||
| 							key_edit->notify_change();							 |  | ||||||
| 
 |  | ||||||
| 							key_edit_dialog->set_size( Size2( 200,200) ); |  | ||||||
| 							key_edit_dialog->set_pos(  track_editor->get_global_pos() + ofs + mpos +Point2(-100,20)); |  | ||||||
| 							key_edit_dialog->popup(); |  | ||||||
| 
 |  | ||||||
| 						} |  | ||||||
| 
 | 
 | ||||||
| 						SelectedKey sk; | 						SelectedKey sk; | ||||||
| 						sk.track=idx; | 						sk.track=idx; | ||||||
|  | @ -1577,7 +1892,7 @@ void AnimationKeyEditor::_track_editor_input_event(const InputEvent& p_input) { | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| 						if (!mb.mod.shift && !selection.has(sk)) | 						if (!mb.mod.shift && !selection.has(sk)) | ||||||
| 							selection.clear(); | 							_clear_selection(); | ||||||
| 
 | 
 | ||||||
| 						selection.insert(sk,ki); | 						selection.insert(sk,ki); | ||||||
| 
 | 
 | ||||||
|  | @ -1588,7 +1903,10 @@ void AnimationKeyEditor::_track_editor_input_event(const InputEvent& p_input) { | ||||||
| 						selected_track=idx; | 						selected_track=idx; | ||||||
| 						track_editor->update(); | 						track_editor->update(); | ||||||
| 
 | 
 | ||||||
| 
 | 						if (_edit_if_single_selection() && mb.mod.command) { | ||||||
|  | 							edit_button->set_pressed(true); | ||||||
|  | 							key_editor_tab->show(); | ||||||
|  | 						} | ||||||
| 					} else { | 					} else { | ||||||
| 						//button column
 | 						//button column
 | ||||||
| 						int ofsx = size.width - mpos.x; | 						int ofsx = size.width - mpos.x; | ||||||
|  | @ -1824,7 +2142,8 @@ void AnimationKeyEditor::_track_editor_input_event(const InputEvent& p_input) { | ||||||
| 
 | 
 | ||||||
| 							if (from_track>to_track) { | 							if (from_track>to_track) { | ||||||
| 								if (!click.shift) | 								if (!click.shift) | ||||||
| 									selection.clear(); | 									_clear_selection(); | ||||||
|  | 								_edit_if_single_selection(); | ||||||
| 								break; | 								break; | ||||||
| 							} | 							} | ||||||
| 
 | 
 | ||||||
|  | @ -1842,12 +2161,13 @@ void AnimationKeyEditor::_track_editor_input_event(const InputEvent& p_input) { | ||||||
| 
 | 
 | ||||||
| 							if (from_track > tracks_to  || to_track < tracks_from) { | 							if (from_track > tracks_to  || to_track < tracks_from) { | ||||||
| 								if (!click.shift) | 								if (!click.shift) | ||||||
| 									selection.clear(); | 									_clear_selection(); | ||||||
|  | 								_edit_if_single_selection(); | ||||||
| 								break; | 								break; | ||||||
| 							} | 							} | ||||||
| 
 | 
 | ||||||
| 							if (!click.shift) | 							if (!click.shift) | ||||||
| 								selection.clear(); | 								_clear_selection(); | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| 							int higher_track=0x7FFFFFFF; | 							int higher_track=0x7FFFFFFF; | ||||||
|  | @ -1880,6 +2200,8 @@ void AnimationKeyEditor::_track_editor_input_event(const InputEvent& p_input) { | ||||||
| 							} | 							} | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|  | 							_edit_if_single_selection(); | ||||||
|  | 
 | ||||||
| 
 | 
 | ||||||
| 						} break; | 						} break; | ||||||
| 						case ClickOver::CLICK_MOVE_KEYS: { | 						case ClickOver::CLICK_MOVE_KEYS: { | ||||||
|  | @ -1891,8 +2213,9 @@ void AnimationKeyEditor::_track_editor_input_event(const InputEvent& p_input) { | ||||||
| 								if (!click.shift) { | 								if (!click.shift) { | ||||||
| 
 | 
 | ||||||
| 									KeyInfo ki=selection[click.selk]; | 									KeyInfo ki=selection[click.selk]; | ||||||
| 									selection.clear(); | 									_clear_selection(); | ||||||
| 									selection[click.selk]=ki; | 									selection[click.selk]=ki; | ||||||
|  | 									_edit_if_single_selection(); | ||||||
| 								} | 								} | ||||||
| 
 | 
 | ||||||
| 								break; | 								break; | ||||||
|  | @ -2007,6 +2330,7 @@ void AnimationKeyEditor::_track_editor_input_event(const InputEvent& p_input) { | ||||||
| 							} | 							} | ||||||
| 
 | 
 | ||||||
| 							undo_redo->commit_action(); | 							undo_redo->commit_action(); | ||||||
|  | 							_edit_if_single_selection(); | ||||||
| 
 | 
 | ||||||
| 						} break; | 						} break; | ||||||
| 						default: {} | 						default: {} | ||||||
|  | @ -2348,20 +2672,33 @@ void AnimationKeyEditor::_notification(int p_what) { | ||||||
| 				optimize_dialog->connect("confirmed",this,"_animation_optimize"); | 				optimize_dialog->connect("confirmed",this,"_animation_optimize"); | ||||||
| 
 | 
 | ||||||
| 				menu_track->get_popup()->add_child(tpp); | 				menu_track->get_popup()->add_child(tpp); | ||||||
| 				menu_track->get_popup()->add_submenu_item("Set Transitions..","Transitions"); | 				//menu_track->get_popup()->add_submenu_item("Set Transitions..","Transitions");
 | ||||||
| 				menu_track->get_popup()->add_separator(); | 				//menu_track->get_popup()->add_separator();
 | ||||||
| 				menu_track->get_popup()->add_item("Optimize Animation",TRACK_MENU_OPTIMIZE); | 				menu_track->get_popup()->add_item("Optimize Animation",TRACK_MENU_OPTIMIZE); | ||||||
| 
 | 
 | ||||||
|  | 				curve_linear->set_icon(get_icon("CurveLinear","EditorIcons")); | ||||||
|  | 				curve_in->set_icon(get_icon("CurveIn","EditorIcons")); | ||||||
|  | 				curve_out->set_icon(get_icon("CurveOut","EditorIcons")); | ||||||
|  | 				curve_inout->set_icon(get_icon("CurveInOut","EditorIcons")); | ||||||
|  | 				curve_outin->set_icon(get_icon("CurveOutIn","EditorIcons")); | ||||||
|  | 				curve_constant->set_icon(get_icon("CurveConstant","EditorIcons")); | ||||||
| 
 | 
 | ||||||
| 
 | 				curve_linear->connect("pressed",this,"_menu_track",varray(CURVE_SET_LINEAR)); | ||||||
|  | 				curve_in->connect("pressed",this,"_menu_track",varray(CURVE_SET_IN)); | ||||||
|  | 				curve_out->connect("pressed",this,"_menu_track",varray(CURVE_SET_OUT)); | ||||||
|  | 				curve_inout->connect("pressed",this,"_menu_track",varray(CURVE_SET_INOUT)); | ||||||
|  | 				curve_outin->connect("pressed",this,"_menu_track",varray(CURVE_SET_OUTIN)); | ||||||
|  | 				curve_constant->connect("pressed",this,"_menu_track",varray(CURVE_SET_CONSTANT)); | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| 				move_up_button->set_icon(get_icon("MoveUp","EditorIcons")); | 				move_up_button->set_icon(get_icon("MoveUp","EditorIcons")); | ||||||
| 				move_down_button->set_icon(get_icon("MoveDown","EditorIcons")); | 				move_down_button->set_icon(get_icon("MoveDown","EditorIcons")); | ||||||
| 				remove_button->set_icon(get_icon("Remove","EditorIcons")); | 				remove_button->set_icon(get_icon("Remove","EditorIcons")); | ||||||
| 				edit_button->set_icon(get_icon("EditKey","EditorIcons")); | 				edit_button->set_icon(get_icon("EditKey","EditorIcons")); | ||||||
|  | 				edit_button->connect("pressed",this,"_toggle_edit_curves"); | ||||||
| 
 | 
 | ||||||
| 				loop->set_icon(get_icon("Loop","EditorIcons")); | 				loop->set_icon(get_icon("Loop","EditorIcons")); | ||||||
|  | 				curve_edit->connect("transition_changed",this,"_curve_transition_changed"); | ||||||
| 
 | 
 | ||||||
| 				//edit_button->add_color_override("font_color",get_color("font_color","Tree"));
 | 				//edit_button->add_color_override("font_color",get_color("font_color","Tree"));
 | ||||||
| 				//edit_button->add_color_override("font_color_hover",get_color("font_color","Tree"));
 | 				//edit_button->add_color_override("font_color_hover",get_color("font_color","Tree"));
 | ||||||
|  | @ -2456,6 +2793,17 @@ void AnimationKeyEditor::_update_menu() { | ||||||
| 	updating=false; | 	updating=false; | ||||||
| 
 | 
 | ||||||
| } | } | ||||||
|  | void AnimationKeyEditor::_clear_selection() { | ||||||
|  | 
 | ||||||
|  | 	selection.clear(); | ||||||
|  | 	key_edit->animation=Ref<Animation>(); | ||||||
|  | 	key_edit->track=0; | ||||||
|  | 	key_edit->key_ofs=0; | ||||||
|  | 	key_edit->hint=PropertyInfo(); | ||||||
|  | 	key_edit->notify_change(); | ||||||
|  | 
 | ||||||
|  | } | ||||||
|  | 
 | ||||||
| 
 | 
 | ||||||
| void AnimationKeyEditor::set_animation(const Ref<Animation>& p_anim) { | void AnimationKeyEditor::set_animation(const Ref<Animation>& p_anim) { | ||||||
| 
 | 
 | ||||||
|  | @ -2466,11 +2814,12 @@ void AnimationKeyEditor::set_animation(const Ref<Animation>& p_anim) { | ||||||
| 		animation->connect("changed",this,"_update_paths"); | 		animation->connect("changed",this,"_update_paths"); | ||||||
| 
 | 
 | ||||||
| 	timeline_pos=0; | 	timeline_pos=0; | ||||||
| 	selection.clear(); | 	_clear_selection(); | ||||||
| 	_update_paths(); | 	_update_paths(); | ||||||
| 
 | 
 | ||||||
| 	_update_menu(); | 	_update_menu(); | ||||||
| 	selected_track=-1; | 	selected_track=-1; | ||||||
|  | 	_edit_if_single_selection(); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void AnimationKeyEditor::set_root(Node *p_root) { | void AnimationKeyEditor::set_root(Node *p_root) { | ||||||
|  | @ -2591,6 +2940,7 @@ void AnimationKeyEditor::insert_transform_key(Spatial *p_node,const String& p_su | ||||||
| 	id.value=p_xform; | 	id.value=p_xform; | ||||||
| 	id.type=Animation::TYPE_TRANSFORM; | 	id.type=Animation::TYPE_TRANSFORM; | ||||||
| 	id.query="node '"+p_node->get_name()+"'"; | 	id.query="node '"+p_node->get_name()+"'"; | ||||||
|  | 	id.advance=false; | ||||||
| 
 | 
 | ||||||
| 	//dialog insert
 | 	//dialog insert
 | ||||||
| 
 | 
 | ||||||
|  | @ -2643,6 +2993,7 @@ void AnimationKeyEditor::insert_node_value_key(Node* p_node, const String& p_pro | ||||||
| 	id.value=p_value; | 	id.value=p_value; | ||||||
| 	id.type=Animation::TYPE_VALUE; | 	id.type=Animation::TYPE_VALUE; | ||||||
| 	id.query="property '"+p_property+"'"; | 	id.query="property '"+p_property+"'"; | ||||||
|  | 	id.advance=false; | ||||||
| 	//dialog insert
 | 	//dialog insert
 | ||||||
| 	_query_insert(id); | 	_query_insert(id); | ||||||
| 
 | 
 | ||||||
|  | @ -2650,7 +3001,7 @@ void AnimationKeyEditor::insert_node_value_key(Node* p_node, const String& p_pro | ||||||
| 
 | 
 | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void AnimationKeyEditor::insert_value_key(const String& p_property,const Variant& p_value) { | void AnimationKeyEditor::insert_value_key(const String& p_property,const Variant& p_value,bool p_advance) { | ||||||
| 
 | 
 | ||||||
| 	ERR_FAIL_COND(!root); | 	ERR_FAIL_COND(!root); | ||||||
| 	//let's build a node path
 | 	//let's build a node path
 | ||||||
|  | @ -2696,6 +3047,7 @@ void AnimationKeyEditor::insert_value_key(const String& p_property,const Variant | ||||||
| 	id.value=p_value; | 	id.value=p_value; | ||||||
| 	id.type=Animation::TYPE_VALUE; | 	id.type=Animation::TYPE_VALUE; | ||||||
| 	id.query="property '"+p_property+"'"; | 	id.query="property '"+p_property+"'"; | ||||||
|  | 	id.advance=p_advance; | ||||||
| 	//dialog insert
 | 	//dialog insert
 | ||||||
| 	_query_insert(id); | 	_query_insert(id); | ||||||
| 
 | 
 | ||||||
|  | @ -2928,13 +3280,31 @@ void AnimationKeyEditor::_insert_delay() { | ||||||
| 	undo_redo->create_action("Anim  Insert"); | 	undo_redo->create_action("Anim  Insert"); | ||||||
| 
 | 
 | ||||||
| 	int last_track = animation->get_track_count(); | 	int last_track = animation->get_track_count(); | ||||||
|  | 	bool advance=false; | ||||||
| 	while(insert_data.size()) { | 	while(insert_data.size()) { | ||||||
| 
 | 
 | ||||||
|  | 		if (insert_data.front()->get().advance) | ||||||
|  | 			advance=true; | ||||||
| 		last_track=_confirm_insert(insert_data.front()->get(),last_track); | 		last_track=_confirm_insert(insert_data.front()->get(),last_track); | ||||||
| 		insert_data.pop_front(); | 		insert_data.pop_front(); | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	undo_redo->commit_action(); | 	undo_redo->commit_action(); | ||||||
|  | 
 | ||||||
|  | 	if (advance) { | ||||||
|  | 		float step = animation->get_step(); | ||||||
|  | 		if (step==0) | ||||||
|  | 			step=1; | ||||||
|  | 
 | ||||||
|  | 		float pos=timeline_pos; | ||||||
|  | 
 | ||||||
|  | 		pos=Math::stepify(pos+step,step); | ||||||
|  | 		if (pos>animation->get_length()) | ||||||
|  | 			pos=animation->get_length(); | ||||||
|  | 		timeline_pos=pos; | ||||||
|  | 		track_pos->update(); | ||||||
|  | 		emit_signal("timeline_changed",pos); | ||||||
|  | 	} | ||||||
| 	insert_queue=false; | 	insert_queue=false; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | @ -3122,12 +3492,15 @@ void AnimationKeyEditor::_bind_methods() { | ||||||
| 
 | 
 | ||||||
| 	ObjectTypeDB::bind_method(_MD("set_animation"),&AnimationKeyEditor::set_animation); | 	ObjectTypeDB::bind_method(_MD("set_animation"),&AnimationKeyEditor::set_animation); | ||||||
| 	ObjectTypeDB::bind_method(_MD("_animation_optimize"),&AnimationKeyEditor::_animation_optimize); | 	ObjectTypeDB::bind_method(_MD("_animation_optimize"),&AnimationKeyEditor::_animation_optimize); | ||||||
|  | 	ObjectTypeDB::bind_method(_MD("_curve_transition_changed"),&AnimationKeyEditor::_curve_transition_changed); | ||||||
|  | 	ObjectTypeDB::bind_method(_MD("_toggle_edit_curves"),&AnimationKeyEditor::_toggle_edit_curves); | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| 	ADD_SIGNAL( MethodInfo("resource_selected", PropertyInfo( Variant::OBJECT, "res"),PropertyInfo( Variant::STRING, "prop") ) ); | 	ADD_SIGNAL( MethodInfo("resource_selected", PropertyInfo( Variant::OBJECT, "res"),PropertyInfo( Variant::STRING, "prop") ) ); | ||||||
| 	ADD_SIGNAL( MethodInfo("keying_changed" ) ); | 	ADD_SIGNAL( MethodInfo("keying_changed" ) ); | ||||||
| 	ADD_SIGNAL( MethodInfo("timeline_changed", PropertyInfo(Variant::REAL,"pos") ) ); | 	ADD_SIGNAL( MethodInfo("timeline_changed", PropertyInfo(Variant::REAL,"pos") ) ); | ||||||
| 	ADD_SIGNAL( MethodInfo("animation_len_changed", PropertyInfo(Variant::REAL,"len") ) ); | 	ADD_SIGNAL( MethodInfo("animation_len_changed", PropertyInfo(Variant::REAL,"len") ) ); | ||||||
|  | 	ADD_SIGNAL( MethodInfo("key_edited", PropertyInfo(Variant::INT,"track"), PropertyInfo(Variant::INT,"key") ) ); | ||||||
| 
 | 
 | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | @ -3219,12 +3592,6 @@ AnimationKeyEditor::AnimationKeyEditor(UndoRedo *p_undo_redo, EditorHistory *p_h | ||||||
| 
 | 
 | ||||||
| 	hb->add_child( memnew( VSeparator ) ); | 	hb->add_child( memnew( VSeparator ) ); | ||||||
| 
 | 
 | ||||||
| 	edit_button = memnew( ToolButton ); |  | ||||||
| 	edit_button->set_toggle_mode(true); |  | ||||||
| 	edit_button->set_focus_mode(FOCUS_NONE); |  | ||||||
| 	edit_button->set_disabled(true); |  | ||||||
| 	hb->add_child(edit_button); |  | ||||||
| 	edit_button->set_tooltip("Enable editing of individual keys by clicking them."); |  | ||||||
| 
 | 
 | ||||||
| 	move_up_button = memnew( ToolButton ); | 	move_up_button = memnew( ToolButton ); | ||||||
| 	hb->add_child(move_up_button); | 	hb->add_child(move_up_button); | ||||||
|  | @ -3247,6 +3614,15 @@ AnimationKeyEditor::AnimationKeyEditor(UndoRedo *p_undo_redo, EditorHistory *p_h | ||||||
| 	remove_button->set_disabled(true); | 	remove_button->set_disabled(true); | ||||||
| 	remove_button->set_tooltip("Remove selected track."); | 	remove_button->set_tooltip("Remove selected track."); | ||||||
| 
 | 
 | ||||||
|  | 	hb->add_child(memnew( VSeparator )); | ||||||
|  | 
 | ||||||
|  | 	edit_button = memnew( ToolButton ); | ||||||
|  | 	edit_button->set_toggle_mode(true); | ||||||
|  | 	edit_button->set_focus_mode(FOCUS_NONE); | ||||||
|  | 	edit_button->set_disabled(true); | ||||||
|  | 
 | ||||||
|  | 	hb->add_child(edit_button); | ||||||
|  | 	edit_button->set_tooltip("Enable editing of individual keys by clicking them."); | ||||||
| 
 | 
 | ||||||
| 	optimize_dialog = memnew( ConfirmationDialog ); | 	optimize_dialog = memnew( ConfirmationDialog ); | ||||||
| 	add_child(optimize_dialog); | 	add_child(optimize_dialog); | ||||||
|  | @ -3297,7 +3673,7 @@ AnimationKeyEditor::AnimationKeyEditor(UndoRedo *p_undo_redo, EditorHistory *p_h | ||||||
| //	menu->get_popup()->connect("item_pressed",this,"_menu_callback");
 | //	menu->get_popup()->connect("item_pressed",this,"_menu_callback");
 | ||||||
| 
 | 
 | ||||||
| 	ec = memnew (Control); | 	ec = memnew (Control); | ||||||
| 	ec->set_custom_minimum_size(Size2(0,50)); | 	ec->set_custom_minimum_size(Size2(0,150)); | ||||||
| 	add_child(ec); | 	add_child(ec); | ||||||
| 	ec->set_v_size_flags(SIZE_EXPAND_FILL); | 	ec->set_v_size_flags(SIZE_EXPAND_FILL); | ||||||
| 
 | 
 | ||||||
|  | @ -3313,6 +3689,7 @@ AnimationKeyEditor::AnimationKeyEditor(UndoRedo *p_undo_redo, EditorHistory *p_h | ||||||
| 	track_editor->set_focus_mode(Control::FOCUS_ALL); | 	track_editor->set_focus_mode(Control::FOCUS_ALL); | ||||||
| 	track_editor->set_h_size_flags(SIZE_EXPAND_FILL); | 	track_editor->set_h_size_flags(SIZE_EXPAND_FILL); | ||||||
| 
 | 
 | ||||||
|  | 
 | ||||||
| 	track_pos = memnew( Control ); | 	track_pos = memnew( Control ); | ||||||
| 	track_pos->set_area_as_parent_rect(); | 	track_pos->set_area_as_parent_rect(); | ||||||
| 	track_pos->set_ignore_mouse(true); | 	track_pos->set_ignore_mouse(true); | ||||||
|  | @ -3325,6 +3702,56 @@ AnimationKeyEditor::AnimationKeyEditor(UndoRedo *p_undo_redo, EditorHistory *p_h | ||||||
| 	v_scroll->connect("value_changed",this,"_scroll_changed"); | 	v_scroll->connect("value_changed",this,"_scroll_changed"); | ||||||
| 	v_scroll->set_val(0); | 	v_scroll->set_val(0); | ||||||
| 
 | 
 | ||||||
|  | 	key_editor_tab = memnew(TabContainer); | ||||||
|  | 	hb->add_child(key_editor_tab); | ||||||
|  | 	key_editor_tab->set_custom_minimum_size(Size2(200,0)); | ||||||
|  | 
 | ||||||
|  | 	key_editor = memnew( PropertyEditor ); | ||||||
|  | 	key_editor->set_area_as_parent_rect(); | ||||||
|  | 	key_editor->hide_top_label(); | ||||||
|  | 	key_editor->set_name("Key"); | ||||||
|  | 	key_editor_tab->add_child(key_editor); | ||||||
|  | 
 | ||||||
|  | 	key_edit = memnew( AnimationKeyEdit ); | ||||||
|  | 	key_edit->undo_redo=undo_redo; | ||||||
|  | 	//key_edit->ke_dialog=key_edit_dialog;
 | ||||||
|  | 	key_editor->edit(key_edit); | ||||||
|  | 	type_menu = memnew( PopupMenu ); | ||||||
|  | 	add_child(type_menu); | ||||||
|  | 	for(int i=0;i<Variant::VARIANT_MAX;i++) | ||||||
|  | 		type_menu->add_item(Variant::get_type_name(Variant::Type(i)),i); | ||||||
|  | 	type_menu->connect("item_pressed",this,"_create_value_item"); | ||||||
|  | 
 | ||||||
|  | 	VBoxContainer *curve_vb = memnew( VBoxContainer ); | ||||||
|  | 	curve_vb->set_name("Transition"); | ||||||
|  | 	HBoxContainer *curve_hb = memnew( HBoxContainer ); | ||||||
|  | 	curve_vb->add_child(curve_hb); | ||||||
|  | 
 | ||||||
|  | 	curve_linear = memnew( ToolButton ); | ||||||
|  | 	curve_linear->set_focus_mode(FOCUS_NONE); | ||||||
|  | 	curve_hb->add_child(curve_linear); | ||||||
|  | 	curve_in = memnew( ToolButton ); | ||||||
|  | 	curve_in->set_focus_mode(FOCUS_NONE); | ||||||
|  | 	curve_hb->add_child(curve_in); | ||||||
|  | 	curve_out = memnew( ToolButton ); | ||||||
|  | 	curve_out->set_focus_mode(FOCUS_NONE); | ||||||
|  | 	curve_hb->add_child(curve_out); | ||||||
|  | 	curve_inout = memnew( ToolButton ); | ||||||
|  | 	curve_inout->set_focus_mode(FOCUS_NONE); | ||||||
|  | 	curve_hb->add_child(curve_inout); | ||||||
|  | 	curve_outin = memnew( ToolButton ); | ||||||
|  | 	curve_outin->set_focus_mode(FOCUS_NONE); | ||||||
|  | 	curve_hb->add_child(curve_outin); | ||||||
|  | 	curve_constant = memnew( ToolButton ); | ||||||
|  | 	curve_constant->set_focus_mode(FOCUS_NONE); | ||||||
|  | 	curve_hb->add_child(curve_constant); | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | 	curve_edit = memnew( AnimationCurveEdit ); | ||||||
|  | 	curve_vb->add_child(curve_edit); | ||||||
|  | 	curve_edit->set_v_size_flags(SIZE_EXPAND_FILL); | ||||||
|  | 	key_editor_tab->add_child(curve_vb); | ||||||
|  | 
 | ||||||
| 	h_scroll = memnew( HScrollBar ); | 	h_scroll = memnew( HScrollBar ); | ||||||
| 	h_scroll->connect("value_changed",this,"_scroll_changed"); | 	h_scroll->connect("value_changed",this,"_scroll_changed"); | ||||||
| 	add_child(h_scroll); | 	add_child(h_scroll); | ||||||
|  | @ -3340,7 +3767,7 @@ AnimationKeyEditor::AnimationKeyEditor(UndoRedo *p_undo_redo, EditorHistory *p_h | ||||||
| 	add_child(track_menu); | 	add_child(track_menu); | ||||||
| 	track_menu->connect("item_pressed",this,"_track_menu_selected"); | 	track_menu->connect("item_pressed",this,"_track_menu_selected"); | ||||||
| 
 | 
 | ||||||
| 
 | 	key_editor_tab->hide(); | ||||||
| 
 | 
 | ||||||
| 	last_idx =1; | 	last_idx =1; | ||||||
| 
 | 
 | ||||||
|  | @ -3359,24 +3786,6 @@ AnimationKeyEditor::AnimationKeyEditor(UndoRedo *p_undo_redo, EditorHistory *p_h | ||||||
| 	timeline_pos=0; | 	timeline_pos=0; | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| 	key_edit_dialog = memnew( PopupDialog ); |  | ||||||
| 	key_editor = memnew( PropertyEditor ); |  | ||||||
| 	add_child(key_edit_dialog); |  | ||||||
| 	key_editor->set_area_as_parent_rect(); |  | ||||||
| 	key_editor->hide_top_label(); |  | ||||||
| 	for(int i=0;i<4;i++) |  | ||||||
| 		key_editor->set_margin(Margin(i),5); |  | ||||||
| 	key_edit_dialog->add_child(key_editor); |  | ||||||
| 
 |  | ||||||
| 	key_edit = memnew( AnimationKeyEdit ); |  | ||||||
| 	key_edit->undo_redo=undo_redo; |  | ||||||
| 	key_edit->ke_dialog=key_edit_dialog; |  | ||||||
| 	key_editor->edit(key_edit); |  | ||||||
| 	type_menu = memnew( PopupMenu ); |  | ||||||
| 	add_child(type_menu); |  | ||||||
| 	for(int i=0;i<Variant::VARIANT_MAX;i++) |  | ||||||
| 		type_menu->add_item(Variant::get_type_name(Variant::Type(i)),i); |  | ||||||
| 	type_menu->connect("item_pressed",this,"_create_value_item"); |  | ||||||
| 	keying=false; | 	keying=false; | ||||||
| 	insert_frame=0; | 	insert_frame=0; | ||||||
| 	insert_query=false; | 	insert_query=false; | ||||||
|  |  | ||||||
|  | @ -37,6 +37,7 @@ | ||||||
| #include "scene/gui/scroll_bar.h" | #include "scene/gui/scroll_bar.h" | ||||||
| #include "scene/gui/tool_button.h" | #include "scene/gui/tool_button.h" | ||||||
| #include "scene/gui/file_dialog.h" | #include "scene/gui/file_dialog.h" | ||||||
|  | #include "scene/gui/tab_container.h" | ||||||
| 
 | 
 | ||||||
| #include "scene/resources/animation.h" | #include "scene/resources/animation.h" | ||||||
| #include "scene/animation/animation_cache.h" | #include "scene/animation/animation_cache.h" | ||||||
|  | @ -46,6 +47,7 @@ | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| class AnimationKeyEdit; | class AnimationKeyEdit; | ||||||
|  | class AnimationCurveEdit; | ||||||
| 
 | 
 | ||||||
| class AnimationKeyEditor : public VBoxContainer  { | class AnimationKeyEditor : public VBoxContainer  { | ||||||
| 
 | 
 | ||||||
|  | @ -86,7 +88,13 @@ class AnimationKeyEditor : public VBoxContainer  { | ||||||
| 		TRACK_MENU_SET_ALL_TRANS_OUTIN, | 		TRACK_MENU_SET_ALL_TRANS_OUTIN, | ||||||
| 		TRACK_MENU_NEXT_STEP, | 		TRACK_MENU_NEXT_STEP, | ||||||
| 		TRACK_MENU_PREV_STEP, | 		TRACK_MENU_PREV_STEP, | ||||||
| 		TRACK_MENU_OPTIMIZE | 		TRACK_MENU_OPTIMIZE, | ||||||
|  | 		CURVE_SET_LINEAR, | ||||||
|  | 		CURVE_SET_IN, | ||||||
|  | 		CURVE_SET_OUT, | ||||||
|  | 		CURVE_SET_INOUT, | ||||||
|  | 		CURVE_SET_OUTIN, | ||||||
|  | 		CURVE_SET_CONSTANT | ||||||
| 	}; | 	}; | ||||||
| 
 | 
 | ||||||
| 	struct MouseOver { | 	struct MouseOver { | ||||||
|  | @ -169,6 +177,14 @@ class AnimationKeyEditor : public VBoxContainer  { | ||||||
| 	ToolButton *move_down_button; | 	ToolButton *move_down_button; | ||||||
| 	ToolButton *remove_button; | 	ToolButton *remove_button; | ||||||
| 
 | 
 | ||||||
|  | 	ToolButton *curve_linear; | ||||||
|  | 	ToolButton *curve_in; | ||||||
|  | 	ToolButton *curve_out; | ||||||
|  | 	ToolButton *curve_inout; | ||||||
|  | 	ToolButton *curve_outin; | ||||||
|  | 	ToolButton *curve_constant; | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
| 	ConfirmationDialog *optimize_dialog; | 	ConfirmationDialog *optimize_dialog; | ||||||
| 	SpinBox *optimize_linear_error; | 	SpinBox *optimize_linear_error; | ||||||
| 	SpinBox *optimize_angular_error; | 	SpinBox *optimize_angular_error; | ||||||
|  | @ -183,11 +199,11 @@ class AnimationKeyEditor : public VBoxContainer  { | ||||||
| 
 | 
 | ||||||
| 	Control *track_editor; | 	Control *track_editor; | ||||||
| 	Control *track_pos; | 	Control *track_pos; | ||||||
|  | 	TabContainer *key_editor_tab; | ||||||
| 
 | 
 | ||||||
| 	ConfirmationDialog *scale_dialog; | 	ConfirmationDialog *scale_dialog; | ||||||
| 	SpinBox *scale; | 	SpinBox *scale; | ||||||
| 
 | 
 | ||||||
| 	PopupDialog *key_edit_dialog; |  | ||||||
| 	PropertyEditor *key_editor;	 | 	PropertyEditor *key_editor;	 | ||||||
| 
 | 
 | ||||||
| 	Ref<Animation> animation; | 	Ref<Animation> animation; | ||||||
|  | @ -203,6 +219,7 @@ class AnimationKeyEditor : public VBoxContainer  { | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| 	AnimationKeyEdit *key_edit; | 	AnimationKeyEdit *key_edit; | ||||||
|  | 	AnimationCurveEdit *curve_edit; | ||||||
| 
 | 
 | ||||||
| 	bool inserting; | 	bool inserting; | ||||||
| 
 | 
 | ||||||
|  | @ -220,6 +237,7 @@ class AnimationKeyEditor : public VBoxContainer  { | ||||||
| 		int track_idx; | 		int track_idx; | ||||||
| 		Variant value; | 		Variant value; | ||||||
| 		String query; | 		String query; | ||||||
|  | 		bool advance; | ||||||
| 	};/* insert_data;*/ | 	};/* insert_data;*/ | ||||||
| 
 | 
 | ||||||
| 	bool insert_query; | 	bool insert_query; | ||||||
|  | @ -254,7 +272,7 @@ class AnimationKeyEditor : public VBoxContainer  { | ||||||
| 	void _scale(); | 	void _scale(); | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| 
 | 	void _clear_selection(); | ||||||
| 
 | 
 | ||||||
| 	//void _browse_path();
 | 	//void _browse_path();
 | ||||||
| 
 | 
 | ||||||
|  | @ -270,12 +288,15 @@ class AnimationKeyEditor : public VBoxContainer  { | ||||||
| 
 | 
 | ||||||
| 	void _clear_selection_for_anim(const Ref<Animation>& p_anim); | 	void _clear_selection_for_anim(const Ref<Animation>& p_anim); | ||||||
| 	void _select_at_anim(const Ref<Animation>& p_anim,int p_track,float p_pos); | 	void _select_at_anim(const Ref<Animation>& p_anim,int p_track,float p_pos); | ||||||
|  | 	void _curve_transition_changed(float p_what); | ||||||
| 
 | 
 | ||||||
| 	PropertyInfo _find_hint_for_track(int p_idx); | 	PropertyInfo _find_hint_for_track(int p_idx); | ||||||
| 
 | 
 | ||||||
| 	void _create_value_item(int p_type); | 	void _create_value_item(int p_type); | ||||||
| 	void _pane_drag(const Point2& p_delta); | 	void _pane_drag(const Point2& p_delta); | ||||||
|  | 	bool _edit_if_single_selection(); | ||||||
| 
 | 
 | ||||||
|  | 	void _toggle_edit_curves(); | ||||||
| 	void _animation_len_update(); | 	void _animation_len_update(); | ||||||
| 
 | 
 | ||||||
| 	void _root_removed(); | 	void _root_removed(); | ||||||
|  | @ -296,7 +317,7 @@ public: | ||||||
| 
 | 
 | ||||||
| 	void set_anim_pos(float p_pos); | 	void set_anim_pos(float p_pos); | ||||||
| 	void insert_node_value_key(Node* p_node, const String& p_property,const Variant& p_value,bool p_only_if_exists=false); | 	void insert_node_value_key(Node* p_node, const String& p_property,const Variant& p_value,bool p_only_if_exists=false); | ||||||
| 	void insert_value_key(const String& p_property,const Variant& p_value); | 	void insert_value_key(const String& p_property, const Variant& p_value, bool p_advance); | ||||||
| 	void insert_transform_key(Spatial *p_node,const String& p_sub,const Transform& p_xform); | 	void insert_transform_key(Spatial *p_node,const String& p_sub,const Transform& p_xform); | ||||||
| 
 | 
 | ||||||
| 	AnimationKeyEditor(UndoRedo *p_undo_redo, EditorHistory *p_history, EditorSelection *p_selection); | 	AnimationKeyEditor(UndoRedo *p_undo_redo, EditorHistory *p_history, EditorSelection *p_selection); | ||||||
|  |  | ||||||
|  | @ -989,6 +989,7 @@ EditorFileSystemDirectory *EditorFileSystem::get_path(const String& p_path) { | ||||||
| 
 | 
 | ||||||
| void EditorFileSystem::_resource_saved(const String& p_path){ | void EditorFileSystem::_resource_saved(const String& p_path){ | ||||||
| 
 | 
 | ||||||
|  | 	print_line("resource saved: "+p_path); | ||||||
| 	EditorFileSystem::get_singleton()->update_file(p_path); | 	EditorFileSystem::get_singleton()->update_file(p_path); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -2838,9 +2838,9 @@ void EditorNode::_instance_request(const String& p_path){ | ||||||
| 	request_instance_scene(p_path); | 	request_instance_scene(p_path); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void EditorNode::_property_keyed(const String& p_keyed,const Variant& p_value) { | void EditorNode::_property_keyed(const String& p_keyed,const Variant& p_value,bool p_advance) { | ||||||
| 
 | 
 | ||||||
| 	animation_editor->insert_value_key(p_keyed,p_value); | 	animation_editor->insert_value_key(p_keyed,p_value,p_advance); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void EditorNode::_transform_keyed(Object *sp,const String& p_sub,const Transform& p_key) { | void EditorNode::_transform_keyed(Object *sp,const String& p_sub,const Transform& p_key) { | ||||||
|  |  | ||||||
|  | @ -348,7 +348,7 @@ class EditorNode : public Node { | ||||||
| 
 | 
 | ||||||
| 	void _instance_request(const String& p_path); | 	void _instance_request(const String& p_path); | ||||||
| 
 | 
 | ||||||
| 	void _property_keyed(const String& p_keyed,const Variant& p_value); | 	void _property_keyed(const String& p_keyed, const Variant& p_value, bool p_advance); | ||||||
| 	void _transform_keyed(Object *sp,const String& p_sub,const Transform& p_key); | 	void _transform_keyed(Object *sp,const String& p_sub,const Transform& p_key); | ||||||
| 
 | 
 | ||||||
| 	void _update_keying(); | 	void _update_keying(); | ||||||
|  |  | ||||||
							
								
								
									
										
											BIN
										
									
								
								tools/editor/icons/icon_curve_constant.png
									
										
									
									
									
										Normal file
									
								
							
							
						
						| After Width: | Height: | Size: 222 B | 
							
								
								
									
										
											BIN
										
									
								
								tools/editor/icons/icon_curve_in.png
									
										
									
									
									
										Normal file
									
								
							
							
						
						| After Width: | Height: | Size: 319 B | 
							
								
								
									
										
											BIN
										
									
								
								tools/editor/icons/icon_curve_in_out.png
									
										
									
									
									
										Normal file
									
								
							
							
						
						| After Width: | Height: | Size: 326 B | 
							
								
								
									
										
											BIN
										
									
								
								tools/editor/icons/icon_curve_linear.png
									
										
									
									
									
										Normal file
									
								
							
							
						
						| After Width: | Height: | Size: 275 B | 
							
								
								
									
										
											BIN
										
									
								
								tools/editor/icons/icon_curve_out.png
									
										
									
									
									
										Normal file
									
								
							
							
						
						| After Width: | Height: | Size: 319 B | 
							
								
								
									
										
											BIN
										
									
								
								tools/editor/icons/icon_curve_out_in.png
									
										
									
									
									
										Normal file
									
								
							
							
						
						| After Width: | Height: | Size: 318 B | 
							
								
								
									
										
											BIN
										
									
								
								tools/editor/icons/icon_key_next.png
									
										
									
									
									
										Normal file
									
								
							
							
						
						| After Width: | Height: | Size: 499 B | 
| Before Width: | Height: | Size: 367 B After Width: | Height: | Size: 228 B | 
| Before Width: | Height: | Size: 256 B After Width: | Height: | Size: 260 B | 
							
								
								
									
										
											BIN
										
									
								
								tools/editor/icons/icon_play_backwards.png
									
										
									
									
									
										Normal file
									
								
							
							
						
						| After Width: | Height: | Size: 256 B | 
							
								
								
									
										
											BIN
										
									
								
								tools/editor/icons/icon_play_start.png
									
										
									
									
									
										Normal file
									
								
							
							
						
						| After Width: | Height: | Size: 282 B | 
							
								
								
									
										
											BIN
										
									
								
								tools/editor/icons/icon_play_start_backwards.png
									
										
									
									
									
										Normal file
									
								
							
							
						
						| After Width: | Height: | Size: 289 B | 
| Before Width: | Height: | Size: 138 B After Width: | Height: | Size: 236 B | 
|  | @ -28,7 +28,8 @@ | ||||||
| /*************************************************************************/ | /*************************************************************************/ | ||||||
| #include "animation_player_editor_plugin.h" | #include "animation_player_editor_plugin.h" | ||||||
| #include "io/resource_loader.h" | #include "io/resource_loader.h" | ||||||
| 
 | #include "os/keyboard.h" | ||||||
|  | #include "tools/editor/editor_settings.h" | ||||||
| 
 | 
 | ||||||
| void AnimationPlayerEditor::_node_removed(Node *p_node) { | void AnimationPlayerEditor::_node_removed(Node *p_node) { | ||||||
| 
 | 
 | ||||||
|  | @ -100,12 +101,18 @@ void AnimationPlayerEditor::_notification(int p_what) { | ||||||
| 		remove_anim->set_icon( get_icon("Del","EditorIcons") ); | 		remove_anim->set_icon( get_icon("Del","EditorIcons") ); | ||||||
| 		edit_anim->set_icon( get_icon("Edit","EditorIcons") ); | 		edit_anim->set_icon( get_icon("Edit","EditorIcons") ); | ||||||
| 		blend_anim->set_icon( get_icon("Blend","EditorIcons") ); | 		blend_anim->set_icon( get_icon("Blend","EditorIcons") ); | ||||||
| 		play->set_icon( get_icon("Play","EditorIcons") ); | 		play->set_icon( get_icon("PlayStart","EditorIcons") ); | ||||||
|  | 		play_from->set_icon( get_icon("Play","EditorIcons") ); | ||||||
|  | 		play_bw->set_icon( get_icon("PlayStartBackwards","EditorIcons") ); | ||||||
|  | 		play_bw_from->set_icon( get_icon("PlayBackwards","EditorIcons") ); | ||||||
|  | 
 | ||||||
| 		autoplay_icon=get_icon("AutoPlay","EditorIcons"); | 		autoplay_icon=get_icon("AutoPlay","EditorIcons"); | ||||||
| 		stop->set_icon( get_icon("Stop","EditorIcons") ); | 		stop->set_icon( get_icon("Stop","EditorIcons") ); | ||||||
| 		resource_edit_anim->set_icon( get_icon("EditResource","EditorIcons") ); | 		resource_edit_anim->set_icon( get_icon("EditResource","EditorIcons") ); | ||||||
| 		pin->set_normal_texture(get_icon("Pin","EditorIcons") ); | 		pin->set_normal_texture(get_icon("Pin","EditorIcons") ); | ||||||
| 		pin->set_pressed_texture( get_icon("PinPressed","EditorIcons") ); | 		pin->set_pressed_texture( get_icon("PinPressed","EditorIcons") ); | ||||||
|  | 		tool_anim->set_icon(get_icon("Tools","EditorIcons")); | ||||||
|  | 		tool_anim->get_popup()->connect("item_pressed",this,"_animation_tool_menu"); | ||||||
| 
 | 
 | ||||||
| 		blend_editor.next->connect("text_changed",this,"_blend_editor_next_changed"); | 		blend_editor.next->connect("text_changed",this,"_blend_editor_next_changed"); | ||||||
| 
 | 
 | ||||||
|  | @ -180,9 +187,82 @@ void AnimationPlayerEditor::_play_pressed() { | ||||||
| 	//unpause
 | 	//unpause
 | ||||||
| 	//pause->set_pressed(false);
 | 	//pause->set_pressed(false);
 | ||||||
| } | } | ||||||
|  | 
 | ||||||
|  | void AnimationPlayerEditor::_play_from_pressed() { | ||||||
|  | 
 | ||||||
|  | 	String current; | ||||||
|  | 	if (animation->get_selected()>=0 && animation->get_selected()<animation->get_item_count()) { | ||||||
|  | 
 | ||||||
|  | 		current = animation->get_item_text( animation->get_selected() ); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	if (current!="") { | ||||||
|  | 
 | ||||||
|  | 		float time = player->get_current_animation_pos(); | ||||||
|  | 
 | ||||||
|  | 		if (current==player->get_current_animation() && player->is_playing()) { | ||||||
|  | 
 | ||||||
|  | 			player->stop(); //so it wont blend with itself
 | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		player->play( current ); | ||||||
|  | 		player->seek(time); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	//unstop
 | ||||||
|  | 	stop->set_pressed(false); | ||||||
|  | 	//unpause
 | ||||||
|  | 	//pause->set_pressed(false);
 | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | void AnimationPlayerEditor::_play_bw_pressed() { | ||||||
|  | 
 | ||||||
|  | 	String current; | ||||||
|  | 	if (animation->get_selected()>=0 && animation->get_selected()<animation->get_item_count()) { | ||||||
|  | 
 | ||||||
|  | 		current = animation->get_item_text( animation->get_selected() ); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	if (current!="") { | ||||||
|  | 
 | ||||||
|  | 		if (current==player->get_current_animation()) | ||||||
|  | 			player->stop(); //so it wont blend with itself
 | ||||||
|  | 		player->play(current,-1,-1,true); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	//unstop
 | ||||||
|  | 	stop->set_pressed(false); | ||||||
|  | 	//unpause
 | ||||||
|  | 	//pause->set_pressed(false);
 | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void AnimationPlayerEditor::_play_bw_from_pressed() { | ||||||
|  | 
 | ||||||
|  | 	String current; | ||||||
|  | 	if (animation->get_selected()>=0 && animation->get_selected()<animation->get_item_count()) { | ||||||
|  | 
 | ||||||
|  | 		current = animation->get_item_text( animation->get_selected() ); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	if (current!="") { | ||||||
|  | 
 | ||||||
|  | 		float time = player->get_current_animation_pos(); | ||||||
|  | 		if (current==player->get_current_animation()) | ||||||
|  | 			player->stop(); //so it wont blend with itself
 | ||||||
|  | 
 | ||||||
|  | 		player->play(current,-1,-1,true); | ||||||
|  | 		player->seek(time); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	//unstop
 | ||||||
|  | 	stop->set_pressed(false); | ||||||
|  | 	//unpause
 | ||||||
|  | 	//pause->set_pressed(false);
 | ||||||
|  | } | ||||||
| void AnimationPlayerEditor::_stop_pressed() { | void AnimationPlayerEditor::_stop_pressed() { | ||||||
| 
 | 
 | ||||||
| 	player->stop(); | 	player->stop(false); | ||||||
| 	play->set_pressed(false); | 	play->set_pressed(false); | ||||||
| 	stop->set_pressed(true); | 	stop->set_pressed(true); | ||||||
| 	//pause->set_pressed(false);
 | 	//pause->set_pressed(false);
 | ||||||
|  | @ -598,6 +678,9 @@ void AnimationPlayerEditor::_update_player() { | ||||||
| 
 | 
 | ||||||
| 	stop->set_disabled(animlist.size()==0); | 	stop->set_disabled(animlist.size()==0); | ||||||
| 	play->set_disabled(animlist.size()==0); | 	play->set_disabled(animlist.size()==0); | ||||||
|  | 	play_bw->set_disabled(animlist.size()==0); | ||||||
|  | 	play_bw_from->set_disabled(animlist.size()==0); | ||||||
|  | 	play_from->set_disabled(animlist.size()==0); | ||||||
| 	autoplay->set_disabled(animlist.size()==0); | 	autoplay->set_disabled(animlist.size()==0); | ||||||
| 	duplicate_anim->set_disabled(animlist.size()==0); | 	duplicate_anim->set_disabled(animlist.size()==0); | ||||||
| 	rename_anim->set_disabled(animlist.size()==0); | 	rename_anim->set_disabled(animlist.size()==0); | ||||||
|  | @ -877,11 +960,108 @@ void AnimationPlayerEditor::_hide_anim_editors() { | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | 
 | ||||||
|  | void AnimationPlayerEditor::_animation_tool_menu(int p_option) { | ||||||
|  | 
 | ||||||
|  | 	switch(p_option) { | ||||||
|  | 
 | ||||||
|  | 		case TOOL_COPY_ANIM: { | ||||||
|  | 
 | ||||||
|  | 			if (!animation->get_item_count()) { | ||||||
|  | 				error_dialog->set_text("ERROR: No animation to copy!"); | ||||||
|  | 				error_dialog->popup_centered_minsize(); | ||||||
|  | 				return; | ||||||
|  | 			} | ||||||
|  | 
 | ||||||
|  | 			String current = animation->get_item_text(animation->get_selected()); | ||||||
|  | 			Ref<Animation> anim =  player->get_animation(current); | ||||||
|  | 			//editor->edit_resource(anim);
 | ||||||
|  | 			EditorSettings::get_singleton()->set_resource_clipboard(anim); | ||||||
|  | 
 | ||||||
|  | 		} break; | ||||||
|  | 		case TOOL_PASTE_ANIM: { | ||||||
|  | 
 | ||||||
|  | 			Ref<Animation> anim = EditorSettings::get_singleton()->get_resource_clipboard(); | ||||||
|  | 			if (!anim.is_valid()) { | ||||||
|  | 				error_dialog->set_text("ERROR: No animation resource on clipboard!"); | ||||||
|  | 				error_dialog->popup_centered_minsize(); | ||||||
|  | 				return; | ||||||
|  | 			} | ||||||
|  | 
 | ||||||
|  | 			String name = anim->get_name(); | ||||||
|  | 			if (name=="") { | ||||||
|  | 				name="Pasted Animation"; | ||||||
|  | 			} | ||||||
|  | 
 | ||||||
|  | 			int idx=1; | ||||||
|  | 			String base = name; | ||||||
|  | 			while (player->has_animation(name)) { | ||||||
|  | 
 | ||||||
|  | 				idx++; | ||||||
|  | 				name=base+" "+itos(idx); | ||||||
|  | 			} | ||||||
|  | 
 | ||||||
|  | 			undo_redo->create_action("Paste Animation"); | ||||||
|  | 			undo_redo->add_do_method(player,"add_animation",name,anim); | ||||||
|  | 			undo_redo->add_undo_method(player,"remove_animation",name); | ||||||
|  | 			undo_redo->add_do_method(this,"_animation_player_changed",player); | ||||||
|  | 			undo_redo->add_undo_method(this,"_animation_player_changed",player); | ||||||
|  | 			undo_redo->commit_action(); | ||||||
|  | 
 | ||||||
|  | 			_select_anim_by_name(name); | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | 		} break; | ||||||
|  | 		case TOOL_EDIT_RESOURCE: { | ||||||
|  | 
 | ||||||
|  | 			if (!animation->get_item_count()) { | ||||||
|  | 				error_dialog->set_text("ERROR: No animation to edit!"); | ||||||
|  | 				error_dialog->popup_centered_minsize(); | ||||||
|  | 				return; | ||||||
|  | 			} | ||||||
|  | 
 | ||||||
|  | 			String current = animation->get_item_text(animation->get_selected()); | ||||||
|  | 			Ref<Animation> anim =  player->get_animation(current); | ||||||
|  | 			editor->edit_resource(anim); | ||||||
|  | 
 | ||||||
|  | 		} break; | ||||||
|  | 
 | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void AnimationPlayerEditor::_unhandled_key_input(const InputEvent& p_ev) { | ||||||
|  | 
 | ||||||
|  | 	if (is_visible() && p_ev.type==InputEvent::KEY && p_ev.key.pressed && !p_ev.key.echo && !p_ev.key.mod.alt && !p_ev.key.mod.control && !p_ev.key.mod.meta) { | ||||||
|  | 
 | ||||||
|  | 		switch(p_ev.key.scancode) { | ||||||
|  | 
 | ||||||
|  | 			case KEY_A: { | ||||||
|  | 				if (!p_ev.key.mod.shift) | ||||||
|  | 					_play_bw_from_pressed(); | ||||||
|  | 				else | ||||||
|  | 					_play_bw_pressed(); | ||||||
|  | 			} break; | ||||||
|  | 			case KEY_S: { | ||||||
|  | 				_stop_pressed(); | ||||||
|  | 			} break; | ||||||
|  | 			case KEY_D: { | ||||||
|  | 				if (!p_ev.key.mod.shift) | ||||||
|  | 					_play_from_pressed(); | ||||||
|  | 				else | ||||||
|  | 					_play_pressed(); | ||||||
|  | 			} break; | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | 
 | ||||||
| void AnimationPlayerEditor::_bind_methods() { | void AnimationPlayerEditor::_bind_methods() { | ||||||
| 
 | 
 | ||||||
| 	ObjectTypeDB::bind_method(_MD("_input_event"),&AnimationPlayerEditor::_input_event); | 	ObjectTypeDB::bind_method(_MD("_input_event"),&AnimationPlayerEditor::_input_event); | ||||||
| 	ObjectTypeDB::bind_method(_MD("_node_removed"),&AnimationPlayerEditor::_node_removed); | 	ObjectTypeDB::bind_method(_MD("_node_removed"),&AnimationPlayerEditor::_node_removed); | ||||||
| 	ObjectTypeDB::bind_method(_MD("_play_pressed"),&AnimationPlayerEditor::_play_pressed); | 	ObjectTypeDB::bind_method(_MD("_play_pressed"),&AnimationPlayerEditor::_play_pressed); | ||||||
|  | 	ObjectTypeDB::bind_method(_MD("_play_from_pressed"),&AnimationPlayerEditor::_play_from_pressed); | ||||||
|  | 	ObjectTypeDB::bind_method(_MD("_play_bw_pressed"),&AnimationPlayerEditor::_play_bw_pressed); | ||||||
|  | 	ObjectTypeDB::bind_method(_MD("_play_bw_from_pressed"),&AnimationPlayerEditor::_play_bw_from_pressed); | ||||||
| 	ObjectTypeDB::bind_method(_MD("_stop_pressed"),&AnimationPlayerEditor::_stop_pressed); | 	ObjectTypeDB::bind_method(_MD("_stop_pressed"),&AnimationPlayerEditor::_stop_pressed); | ||||||
| 	ObjectTypeDB::bind_method(_MD("_autoplay_pressed"),&AnimationPlayerEditor::_autoplay_pressed); | 	ObjectTypeDB::bind_method(_MD("_autoplay_pressed"),&AnimationPlayerEditor::_autoplay_pressed); | ||||||
| 	ObjectTypeDB::bind_method(_MD("_pause_pressed"),&AnimationPlayerEditor::_pause_pressed); | 	ObjectTypeDB::bind_method(_MD("_pause_pressed"),&AnimationPlayerEditor::_pause_pressed); | ||||||
|  | @ -908,6 +1088,8 @@ void AnimationPlayerEditor::_bind_methods() { | ||||||
| 	ObjectTypeDB::bind_method(_MD("_hide_anim_editors"),&AnimationPlayerEditor::_hide_anim_editors); | 	ObjectTypeDB::bind_method(_MD("_hide_anim_editors"),&AnimationPlayerEditor::_hide_anim_editors); | ||||||
| 	ObjectTypeDB::bind_method(_MD("_animation_duplicate"),&AnimationPlayerEditor::_animation_duplicate); | 	ObjectTypeDB::bind_method(_MD("_animation_duplicate"),&AnimationPlayerEditor::_animation_duplicate); | ||||||
| 	ObjectTypeDB::bind_method(_MD("_blend_editor_next_changed"),&AnimationPlayerEditor::_blend_editor_next_changed); | 	ObjectTypeDB::bind_method(_MD("_blend_editor_next_changed"),&AnimationPlayerEditor::_blend_editor_next_changed); | ||||||
|  | 	ObjectTypeDB::bind_method(_MD("_unhandled_key_input"),&AnimationPlayerEditor::_unhandled_key_input); | ||||||
|  | 	ObjectTypeDB::bind_method(_MD("_animation_tool_menu"),&AnimationPlayerEditor::_animation_tool_menu); | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|  | @ -935,47 +1117,56 @@ AnimationPlayerEditor::AnimationPlayerEditor(EditorNode *p_editor) { | ||||||
| 	add_child(hb); | 	add_child(hb); | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| 	add_anim = memnew( Button ); | 	add_anim = memnew( ToolButton ); | ||||||
| 	add_anim->set_tooltip("Create new animation in player."); | 	add_anim->set_tooltip("Create new animation in player."); | ||||||
| 
 | 
 | ||||||
| 	hb->add_child(add_anim); | 	hb->add_child(add_anim); | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| 
 | 	load_anim = memnew( ToolButton ); | ||||||
| 	load_anim = memnew( Button ); |  | ||||||
| 	load_anim->set_tooltip("Load an animation from disk."); | 	load_anim->set_tooltip("Load an animation from disk."); | ||||||
| 	hb->add_child(load_anim); | 	hb->add_child(load_anim); | ||||||
| 
 | 
 | ||||||
| 	duplicate_anim = memnew( Button ); | 	duplicate_anim = memnew( ToolButton ); | ||||||
| 	hb->add_child(duplicate_anim); | 	hb->add_child(duplicate_anim); | ||||||
| 	duplicate_anim->set_tooltip("Duplicate Animation"); | 	duplicate_anim->set_tooltip("Duplicate Animation"); | ||||||
| 
 | 
 | ||||||
|  | 	rename_anim = memnew( ToolButton ); | ||||||
|  | 	hb->add_child(rename_anim); | ||||||
|  | 	rename_anim->set_tooltip("Rename Animation"); | ||||||
|  | 
 | ||||||
|  | 	remove_anim = memnew( ToolButton ); | ||||||
|  | 
 | ||||||
|  | 	hb->add_child(remove_anim); | ||||||
|  | 	remove_anim->set_tooltip("Remove Animation"); | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
| 	animation = memnew( OptionButton ); | 	animation = memnew( OptionButton ); | ||||||
| 	hb->add_child(animation); | 	hb->add_child(animation); | ||||||
| 	animation->set_h_size_flags(SIZE_EXPAND_FILL); | 	animation->set_h_size_flags(SIZE_EXPAND_FILL); | ||||||
| 	animation->set_tooltip("Display list of animations in player."); | 	animation->set_tooltip("Display list of animations in player."); | ||||||
| 
 | 
 | ||||||
| 	autoplay = memnew( Button ); | 	autoplay = memnew( ToolButton ); | ||||||
| 	hb->add_child(autoplay); | 	hb->add_child(autoplay); | ||||||
| 	autoplay->set_tooltip("Autoplay On Load"); | 	autoplay->set_tooltip("Autoplay On Load"); | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| 	rename_anim = memnew( Button ); |  | ||||||
| 	hb->add_child(rename_anim); |  | ||||||
| 	rename_anim->set_tooltip("Rename Animation"); |  | ||||||
| 
 | 
 | ||||||
| 	remove_anim = memnew( Button ); | 	blend_anim = memnew( ToolButton ); | ||||||
| 
 |  | ||||||
| 	hb->add_child(remove_anim); |  | ||||||
| 	remove_anim->set_tooltip("Remove Animation"); |  | ||||||
| 
 |  | ||||||
| 	blend_anim = memnew( Button ); |  | ||||||
| 	hb->add_child(blend_anim); | 	hb->add_child(blend_anim); | ||||||
| 	blend_anim->set_tooltip("Edit Target Blend Times"); | 	blend_anim->set_tooltip("Edit Target Blend Times"); | ||||||
| 
 | 
 | ||||||
|  | 	tool_anim = memnew( MenuButton); | ||||||
|  | 	//tool_anim->set_flat(false);
 | ||||||
|  | 	tool_anim->set_tooltip("Animation Tools"); | ||||||
|  | 	tool_anim->get_popup()->add_item("Copy Animation",TOOL_COPY_ANIM); | ||||||
|  | 	tool_anim->get_popup()->add_item("Paste Animation",TOOL_PASTE_ANIM); | ||||||
|  | 	//tool_anim->get_popup()->add_separator();
 | ||||||
|  | 	//tool_anim->get_popup()->add_item("Edit Anim Resource",TOOL_PASTE_ANIM);
 | ||||||
|  | 	hb->add_child(tool_anim); | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| 	edit_anim = memnew( Button ); | 	edit_anim = memnew( ToolButton ); | ||||||
| 	edit_anim->set_toggle_mode(true); | 	edit_anim->set_toggle_mode(true); | ||||||
| 	hb->add_child(edit_anim); | 	hb->add_child(edit_anim); | ||||||
| 	edit_anim->set_tooltip("Open animation editor.\nProperty editor will displays all editable keys too."); | 	edit_anim->set_tooltip("Open animation editor.\nProperty editor will displays all editable keys too."); | ||||||
|  | @ -984,15 +1175,29 @@ AnimationPlayerEditor::AnimationPlayerEditor(EditorNode *p_editor) { | ||||||
| 	hb = memnew (HBoxContainer); | 	hb = memnew (HBoxContainer); | ||||||
| 	add_child(hb); | 	add_child(hb); | ||||||
| 
 | 
 | ||||||
| 	play = memnew( Button ); | 	play_bw_from = memnew( ToolButton ); | ||||||
| 	play->set_tooltip("Play selected animation."); | 	play_bw_from->set_tooltip("Play backwards selected animation from current pos. (A)"); | ||||||
|  | 	hb->add_child(play_bw_from); | ||||||
| 
 | 
 | ||||||
| 	hb->add_child(play); | 	play_bw = memnew( ToolButton ); | ||||||
|  | 	play_bw->set_tooltip("Play backwards selected animation from end. (Shift+A)"); | ||||||
|  | 	hb->add_child(play_bw); | ||||||
| 
 | 
 | ||||||
| 	stop = memnew( Button ); | 	stop = memnew( ToolButton ); | ||||||
| 	stop->set_toggle_mode(true); | 	stop->set_toggle_mode(true); | ||||||
| 	hb->add_child(stop); | 	hb->add_child(stop); | ||||||
| 	play->set_tooltip("Stop animation playback."); | 	stop->set_tooltip("Stop animation playback. (S)"); | ||||||
|  | 
 | ||||||
|  | 	play = memnew( ToolButton ); | ||||||
|  | 	play->set_tooltip("Play selected animation from start. (Shift+D)"); | ||||||
|  | 	hb->add_child(play); | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | 	play_from = memnew( ToolButton ); | ||||||
|  | 	play_from->set_tooltip("Play selected animation from current pos. (D)"); | ||||||
|  | 	hb->add_child(play_from); | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
| 
 | 
 | ||||||
| 	//pause = memnew( Button );
 | 	//pause = memnew( Button );
 | ||||||
| 	//pause->set_toggle_mode(true);
 | 	//pause->set_toggle_mode(true);
 | ||||||
|  | @ -1024,6 +1229,7 @@ AnimationPlayerEditor::AnimationPlayerEditor(EditorNode *p_editor) { | ||||||
| 
 | 
 | ||||||
| 	resource_edit_anim= memnew( Button ); | 	resource_edit_anim= memnew( Button ); | ||||||
| 	hb->add_child(resource_edit_anim); | 	hb->add_child(resource_edit_anim); | ||||||
|  | 	resource_edit_anim->hide(); | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| 	file = memnew(FileDialog); | 	file = memnew(FileDialog); | ||||||
|  | @ -1074,7 +1280,10 @@ AnimationPlayerEditor::AnimationPlayerEditor(EditorNode *p_editor) { | ||||||
| 
 | 
 | ||||||
| 	autoplay->connect("pressed", this,"_autoplay_pressed"); | 	autoplay->connect("pressed", this,"_autoplay_pressed"); | ||||||
| 	autoplay->set_toggle_mode(true); | 	autoplay->set_toggle_mode(true); | ||||||
| 	play->connect("pressed", this,"_play_pressed");	 | 	play->connect("pressed", this,"_play_pressed"); | ||||||
|  | 	play_from->connect("pressed", this,"_play_from_pressed"); | ||||||
|  | 	play_bw->connect("pressed", this,"_play_bw_pressed"); | ||||||
|  | 	play_bw_from->connect("pressed", this,"_play_bw_from_pressed"); | ||||||
| 	stop->connect("pressed", this,"_stop_pressed"); | 	stop->connect("pressed", this,"_stop_pressed"); | ||||||
| 	//pause->connect("pressed", this,"_pause_pressed");
 | 	//pause->connect("pressed", this,"_pause_pressed");
 | ||||||
| 	add_anim->connect("pressed", this,"_animation_new"); | 	add_anim->connect("pressed", this,"_animation_new"); | ||||||
|  | @ -1104,6 +1313,8 @@ AnimationPlayerEditor::AnimationPlayerEditor(EditorNode *p_editor) { | ||||||
| 
 | 
 | ||||||
| 	renaming=false; | 	renaming=false; | ||||||
| 	last_active=false; | 	last_active=false; | ||||||
|  | 
 | ||||||
|  | 	set_process_unhandled_key_input(true); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -49,10 +49,19 @@ class AnimationPlayerEditor : public VBoxContainer { | ||||||
| 	EditorNode *editor; | 	EditorNode *editor; | ||||||
| 	AnimationPlayer *player; | 	AnimationPlayer *player; | ||||||
| 
 | 
 | ||||||
|  | 	enum { | ||||||
|  | 		TOOL_COPY_ANIM, | ||||||
|  | 		TOOL_PASTE_ANIM, | ||||||
|  | 		TOOL_EDIT_RESOURCE | ||||||
|  | 	}; | ||||||
| 
 | 
 | ||||||
| 	OptionButton *animation; | 	OptionButton *animation; | ||||||
| 	Button *stop; | 	Button *stop; | ||||||
| 	Button *play; | 	Button *play; | ||||||
|  | 	Button *play_from; | ||||||
|  | 	Button *play_bw; | ||||||
|  | 	Button *play_bw_from; | ||||||
|  | 
 | ||||||
| //	Button *pause;
 | //	Button *pause;
 | ||||||
| 	Button *add_anim; | 	Button *add_anim; | ||||||
| 	Button *autoplay; | 	Button *autoplay; | ||||||
|  | @ -63,6 +72,7 @@ class AnimationPlayerEditor : public VBoxContainer { | ||||||
| 	Button *load_anim; | 	Button *load_anim; | ||||||
| 	Button *blend_anim; | 	Button *blend_anim; | ||||||
| 	Button *remove_anim; | 	Button *remove_anim; | ||||||
|  | 	MenuButton *tool_anim; | ||||||
| 	TextureButton *pin; | 	TextureButton *pin; | ||||||
| 	Label *nodename; | 	Label *nodename; | ||||||
| 	SpinBox *frame; | 	SpinBox *frame; | ||||||
|  | @ -95,6 +105,9 @@ class AnimationPlayerEditor : public VBoxContainer { | ||||||
| 
 | 
 | ||||||
| 	void _select_anim_by_name(const String& p_anim); | 	void _select_anim_by_name(const String& p_anim); | ||||||
| 	void _play_pressed(); | 	void _play_pressed(); | ||||||
|  | 	void _play_from_pressed(); | ||||||
|  | 	void _play_bw_pressed(); | ||||||
|  | 	void _play_bw_from_pressed(); | ||||||
| 	void _autoplay_pressed(); | 	void _autoplay_pressed(); | ||||||
| 	void _stop_pressed(); | 	void _stop_pressed(); | ||||||
| 	void _pause_pressed(); | 	void _pause_pressed(); | ||||||
|  | @ -126,6 +139,8 @@ class AnimationPlayerEditor : public VBoxContainer { | ||||||
| 
 | 
 | ||||||
| 	void _animation_key_editor_seek(float p_pos); | 	void _animation_key_editor_seek(float p_pos); | ||||||
| 	void _animation_key_editor_anim_len_changed(float p_new); | 	void _animation_key_editor_anim_len_changed(float p_new); | ||||||
|  | 	void _unhandled_key_input(const InputEvent& p_ev); | ||||||
|  | 	void _animation_tool_menu(int p_option); | ||||||
| 
 | 
 | ||||||
| 	AnimationPlayerEditor(); | 	AnimationPlayerEditor(); | ||||||
| protected: | protected: | ||||||
|  |  | ||||||
|  | @ -2629,7 +2629,12 @@ void PropertyEditor::update_tree() { | ||||||
| 
 | 
 | ||||||
| 		if (keying) { | 		if (keying) { | ||||||
| 
 | 
 | ||||||
| 			item->add_button(1,get_icon("Key","EditorIcons"),2); | 			if (p.hint==PROPERTY_HINT_SPRITE_FRAME) { | ||||||
|  | 
 | ||||||
|  | 				item->add_button(1,get_icon("KeyNext","EditorIcons"),5); | ||||||
|  | 			} else { | ||||||
|  | 				item->add_button(1,get_icon("Key","EditorIcons"),2); | ||||||
|  | 			} | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		if (get_instanced_node()) { | 		if (get_instanced_node()) { | ||||||
|  | @ -2904,6 +2909,16 @@ void PropertyEditor::edit(Object* p_object) { | ||||||
| 	 | 	 | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | void PropertyEditor::_set_range_def(Object *p_item, String prop,float p_frame) { | ||||||
|  | 
 | ||||||
|  | 	TreeItem *ti = p_item->cast_to<TreeItem>(); | ||||||
|  | 	ERR_FAIL_COND(!ti); | ||||||
|  | 
 | ||||||
|  | 	ti->call_deferred("set_range",1, p_frame); | ||||||
|  | 	obj->call_deferred("set",prop,p_frame); | ||||||
|  | 
 | ||||||
|  | } | ||||||
|  | 
 | ||||||
| void PropertyEditor::_edit_button(Object *p_item, int p_column, int p_button) { | void PropertyEditor::_edit_button(Object *p_item, int p_column, int p_button) { | ||||||
| 	TreeItem *ti = p_item->cast_to<TreeItem>(); | 	TreeItem *ti = p_item->cast_to<TreeItem>(); | ||||||
| 	ERR_FAIL_COND(!ti); | 	ERR_FAIL_COND(!ti); | ||||||
|  | @ -2915,7 +2930,15 @@ void PropertyEditor::_edit_button(Object *p_item, int p_column, int p_button) { | ||||||
| 		if (!d.has("name")) | 		if (!d.has("name")) | ||||||
| 			return; | 			return; | ||||||
| 		String prop=d["name"]; | 		String prop=d["name"]; | ||||||
| 		emit_signal("property_keyed",prop,obj->get(prop)); | 		emit_signal("property_keyed",prop,obj->get(prop),false); | ||||||
|  | 	} else if (p_button==5) { | ||||||
|  | 		print_line("PB5"); | ||||||
|  | 		if (!d.has("name")) | ||||||
|  | 			return; | ||||||
|  | 		String prop=d["name"]; | ||||||
|  | 		emit_signal("property_keyed",prop,obj->get(prop),true); | ||||||
|  | 		//set_range(p_column, ti->get_range(p_column)+1.0 );
 | ||||||
|  | 		call_deferred("_set_range_def",ti,prop,ti->get_range(p_column)+1.0); | ||||||
| 	} else if (p_button==3) { | 	} else if (p_button==3) { | ||||||
| 
 | 
 | ||||||
| 		if (!get_instanced_node()) | 		if (!get_instanced_node()) | ||||||
|  | @ -3046,6 +3069,7 @@ void PropertyEditor::_bind_methods() { | ||||||
| 	ObjectTypeDB::bind_method( "_edit_button",&PropertyEditor::_edit_button); | 	ObjectTypeDB::bind_method( "_edit_button",&PropertyEditor::_edit_button); | ||||||
| 	ObjectTypeDB::bind_method( "_changed_callback",&PropertyEditor::_changed_callbacks); | 	ObjectTypeDB::bind_method( "_changed_callback",&PropertyEditor::_changed_callbacks); | ||||||
| 	ObjectTypeDB::bind_method( "_draw_flags",&PropertyEditor::_draw_flags); | 	ObjectTypeDB::bind_method( "_draw_flags",&PropertyEditor::_draw_flags); | ||||||
|  | 	ObjectTypeDB::bind_method( "_set_range_def",&PropertyEditor::_set_range_def); | ||||||
| 
 | 
 | ||||||
| 	ADD_SIGNAL( MethodInfo("property_toggled",PropertyInfo( Variant::STRING, "property"),PropertyInfo( Variant::BOOL, "value"))); | 	ADD_SIGNAL( MethodInfo("property_toggled",PropertyInfo( Variant::STRING, "property"),PropertyInfo( Variant::BOOL, "value"))); | ||||||
| 	ADD_SIGNAL( MethodInfo("resource_selected", PropertyInfo( Variant::OBJECT, "res"),PropertyInfo( Variant::STRING, "prop") ) ); | 	ADD_SIGNAL( MethodInfo("resource_selected", PropertyInfo( Variant::OBJECT, "res"),PropertyInfo( Variant::STRING, "prop") ) ); | ||||||
|  |  | ||||||
|  | @ -187,6 +187,7 @@ class PropertyEditor : public Control { | ||||||
| 
 | 
 | ||||||
| 	Node *get_instanced_node(); | 	Node *get_instanced_node(); | ||||||
| 	void _refresh_item(TreeItem *p_item); | 	void _refresh_item(TreeItem *p_item); | ||||||
|  | 	void _set_range_def(Object *p_item, String prop, float p_frame); | ||||||
| 
 | 
 | ||||||
| 	UndoRedo *undo_redo; | 	UndoRedo *undo_redo; | ||||||
| protected: | protected: | ||||||
|  |  | ||||||
 Juan Linietsky
						Juan Linietsky