diff options
Diffstat (limited to 'tools/editor/animation_editor.cpp')
| -rw-r--r-- | tools/editor/animation_editor.cpp | 819 |
1 files changed, 519 insertions, 300 deletions
diff --git a/tools/editor/animation_editor.cpp b/tools/editor/animation_editor.cpp index 08b90b5408..cb95f5fb7d 100644 --- a/tools/editor/animation_editor.cpp +++ b/tools/editor/animation_editor.cpp @@ -5,7 +5,7 @@ /* GODOT ENGINE */ /* http://www.godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2016 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -48,7 +48,7 @@ class AnimationCurveEdit : public Control { - OBJ_TYPE( AnimationCurveEdit, Control ); + GDCLASS( AnimationCurveEdit, Control ); public: enum Mode { MODE_DISABLED, @@ -85,7 +85,6 @@ private: int points = 48; if (mode==MODE_MULTIPLE) { - int max_draw = 16; Color mcolor=color; mcolor.a*=0.3; @@ -158,7 +157,7 @@ private: } } - void _input_event(const InputEvent& p_ev) { + void _gui_input(const InputEvent& p_ev) { if (p_ev.type==InputEvent::MOUSE_MOTION && p_ev.mouse_motion.button_mask&BUTTON_MASK_LEFT) { if (mode==MODE_DISABLED) @@ -199,8 +198,8 @@ public: static void _bind_methods() { - // ObjectTypeDB::bind_method("_update_obj",&AnimationKeyEdit::_update_obj); - ObjectTypeDB::bind_method("_input_event",&AnimationCurveEdit::_input_event); + //ClassDB::bind_method("_update_obj",&AnimationKeyEdit::_update_obj); + ClassDB::bind_method("_gui_input",&AnimationCurveEdit::_gui_input); ADD_SIGNAL(MethodInfo("transition_changed")); } @@ -244,15 +243,15 @@ public: class AnimationKeyEdit : public Object { - OBJ_TYPE(AnimationKeyEdit,Object); + GDCLASS(AnimationKeyEdit,Object); public: bool setting; bool hidden; static void _bind_methods() { - ObjectTypeDB::bind_method("_update_obj",&AnimationKeyEdit::_update_obj); - ObjectTypeDB::bind_method("_key_ofs_changed",&AnimationKeyEdit::_key_ofs_changed); + ClassDB::bind_method("_update_obj",&AnimationKeyEdit::_update_obj); + ClassDB::bind_method("_key_ofs_changed",&AnimationKeyEdit::_key_ofs_changed); } //PopupDialog *ke_dialog; @@ -317,7 +316,7 @@ public: int existing = animation->track_find_key(track,new_time,true); setting=true; - undo_redo->create_action(TTR("Move Add Key"),false); + undo_redo->create_action(TTR("Move Add Key"),UndoRedo::MERGE_ENDS); Variant val = animation->track_get_key_value(track,key); float trans = animation->track_get_key_transition(track,key); @@ -345,7 +344,7 @@ public: float val = p_value; float prev_val = animation->track_get_key_transition(track,key); setting=true; - undo_redo->create_action(TTR("Anim Change Transition"),true); + undo_redo->create_action(TTR("Anim Change Transition"),UndoRedo::MERGE_ENDS); undo_redo->add_do_method(animation.ptr(),"track_set_key_transition",track,key,val); undo_redo->add_undo_method(animation.ptr(),"track_set_key_transition",track,key,prev_val); undo_redo->add_do_method(this,"_update_obj",animation); @@ -388,7 +387,7 @@ public: } setting=true; - undo_redo->create_action(TTR("Anim Change Value"),true); + undo_redo->create_action(TTR("Anim Change Value"),UndoRedo::MERGE_ENDS); Variant prev = animation->track_get_key_value(track,key); undo_redo->add_do_method(animation.ptr(),"track_set_key_value",track,key,value); undo_redo->add_undo_method(animation.ptr(),"track_set_key_value",track,key,prev); @@ -464,7 +463,11 @@ public: } } - undo_redo->create_action(TTR("Anim Change Call"),mergeable); + if (mergeable) + undo_redo->create_action(TTR("Anim Change Call"),UndoRedo::MERGE_ENDS); + else + undo_redo->create_action(TTR("Anim Change Call")); + Variant prev = animation->track_get_key_value(track,key); setting=true; undo_redo->add_do_method(animation.ptr(),"track_set_key_value",track,key,d_new); @@ -609,7 +612,7 @@ public: if (res.is_valid()) { hint=PROPERTY_HINT_RESOURCE_TYPE; - hint_string=res->get_type(); + hint_string=res->get_class(); } } @@ -644,8 +647,10 @@ public: } break; } - //if (animation->track_get_type(track)!=Animation::TYPE_METHOD) - // p_list->push_back( PropertyInfo( Variant::REAL, "easing", PROPERTY_HINT_EXP_EASING)); + /* + if (animation->track_get_type(track)!=Animation::TYPE_METHOD) + p_list->push_back( PropertyInfo( Variant::REAL, "easing", PROPERTY_HINT_EXP_EASING)); + */ } UndoRedo *undo_redo; @@ -694,11 +699,103 @@ void AnimationKeyEditor::_menu_add_track(int p_type) { } } +void AnimationKeyEditor::_anim_duplicate_keys(bool transpose) { + //duplicait! + if (selection.size() && animation.is_valid() && selected_track>=0 && selected_track<animation->get_track_count()) { + + int top_track=0x7FFFFFFF; + float top_time = 1e10; + for(Map<SelectedKey,KeyInfo>::Element *E=selection.back();E;E=E->prev()) { + + const SelectedKey &sk = E->key(); + + float t = animation->track_get_key_time(sk.track,sk.key); + if (t<top_time) + top_time=t; + if (sk.track<top_track) + top_track=sk.track; + + } + ERR_FAIL_COND( top_track == 0x7FFFFFFF || top_time==1e10 ); + + // + + int start_track = transpose ? selected_track : top_track; + + undo_redo->create_action(TTR("Anim Duplicate Keys")); + + List<Pair<int,float> > new_selection_values; + + for(Map<SelectedKey,KeyInfo>::Element *E=selection.back();E;E=E->prev()) { + + const SelectedKey &sk = E->key(); + + float t = animation->track_get_key_time(sk.track,sk.key); + + float dst_time = t+(timeline_pos - top_time); + int dst_track = sk.track + (start_track - top_track); + + if (dst_track < 0 || dst_track>= animation->get_track_count()) + continue; + + if (animation->track_get_type(dst_track) != animation->track_get_type(sk.track)) + continue; + + int existing_idx = animation->track_find_key(dst_track,dst_time,true); + + undo_redo->add_do_method(animation.ptr(),"track_insert_key",dst_track,dst_time,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_remove_key_at_pos",dst_track,dst_time); + + Pair<int,float> p; + p.first=dst_track; + p.second=dst_time; + new_selection_values.push_back( p ); + + if (existing_idx!=-1) { + + undo_redo->add_undo_method(animation.ptr(),"track_insert_key",dst_track,dst_time,animation->track_get_key_value(dst_track,existing_idx),animation->track_get_key_transition(dst_track,existing_idx)); + + } + + } + + undo_redo->commit_action(); + + //reselect duplicated + + Map<SelectedKey,KeyInfo> new_selection; + for (List<Pair<int,float> >::Element *E=new_selection_values.front();E;E=E->next()) { + + int track=E->get().first; + float time = E->get().second; + + int existing_idx = animation->track_find_key(track,time,true); + + if (existing_idx==-1) + continue; + SelectedKey sk2; + sk2.track=track; + sk2.key=existing_idx; + + KeyInfo ki; + ki.pos=time; + + new_selection[sk2]=ki; + + } + + + selection=new_selection; + track_editor->update(); + _edit_if_single_selection(); + + } +} + void AnimationKeyEditor::_menu_track(int p_type) { ERR_FAIL_COND(!animation.is_valid()); - last_menu_track_opt=p_type; switch(p_type) { @@ -754,7 +851,7 @@ void AnimationKeyEditor::_menu_track(int p_type) { undo_redo->add_undo_method(animation.ptr(),"track_set_interpolation_type",idx,animation->track_get_interpolation_type(idx)); if (animation->track_get_type(idx)==Animation::TYPE_VALUE) { - undo_redo->add_undo_method(animation.ptr(),"value_track_set_continuous",idx,animation->value_track_is_continuous(idx)); + undo_redo->add_undo_method(animation.ptr(),"value_track_set_update_mode",idx,animation->value_track_get_update_mode(idx)); } @@ -766,108 +863,7 @@ void AnimationKeyEditor::_menu_track(int p_type) { case TRACK_MENU_DUPLICATE: case TRACK_MENU_DUPLICATE_TRANSPOSE: { - - //duplicait! - if (selection.size() && animation.is_valid() && selected_track>=0 && selected_track<animation->get_track_count()) { - - - int top_track=0x7FFFFFFF; - float top_time = 1e10; - for(Map<SelectedKey,KeyInfo>::Element *E=selection.back();E;E=E->prev()) { - - const SelectedKey &sk = E->key(); - - float t = animation->track_get_key_time(sk.track,sk.key); - if (t<top_time) - top_time=t; - if (sk.track<top_track) - top_track=sk.track; - - - } - ERR_FAIL_COND( top_track == 0x7FFFFFFF || top_time==1e10 ); - - // - - int start_track = p_type==TRACK_MENU_DUPLICATE_TRANSPOSE ? selected_track : top_track; - - - undo_redo->create_action(TTR("Anim Duplicate Keys")); - - List<Pair<int,float> > new_selection_values; - - for(Map<SelectedKey,KeyInfo>::Element *E=selection.back();E;E=E->prev()) { - - const SelectedKey &sk = E->key(); - - float t = animation->track_get_key_time(sk.track,sk.key); - - float dst_time = t+(timeline_pos - top_time); - int dst_track = sk.track + (start_track - top_track); - - if (dst_track < 0 || dst_track>= animation->get_track_count()) - continue; - - if (animation->track_get_type(dst_track) != animation->track_get_type(sk.track)) - continue; - - int existing_idx = animation->track_find_key(dst_track,dst_time,true); - - undo_redo->add_do_method(animation.ptr(),"track_insert_key",dst_track,dst_time,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_remove_key_at_pos",dst_track,dst_time); - - Pair<int,float> p; - p.first=dst_track; - p.second=dst_time; - new_selection_values.push_back( p ); - - if (existing_idx!=-1) { - - undo_redo->add_undo_method(animation.ptr(),"track_insert_key",dst_track,dst_time,animation->track_get_key_value(dst_track,existing_idx),animation->track_get_key_transition(dst_track,existing_idx)); - - } - - - - } - - undo_redo->commit_action(); - - //reselect duplicated - - Map<SelectedKey,KeyInfo> new_selection; - for (List<Pair<int,float> >::Element *E=new_selection_values.front();E;E=E->next()) { - - - int track=E->get().first; - float time = E->get().second; - - int existing_idx = animation->track_find_key(track,time,true); - - if (existing_idx==-1) - continue; - SelectedKey sk2; - sk2.track=track; - sk2.key=existing_idx; - - KeyInfo ki; - ki.pos=time; - - - new_selection[sk2]=ki; - - - } - - - selection=new_selection; - track_editor->update(); - _edit_if_single_selection(); - - - } - - + _anim_duplicate_keys(p_type==TRACK_MENU_DUPLICATE_TRANSPOSE); } break; case TRACK_MENU_SET_ALL_TRANS_LINEAR: case TRACK_MENU_SET_ALL_TRANS_CONSTANT: @@ -918,7 +914,7 @@ void AnimationKeyEditor::_menu_track(int p_type) { pos=animation->get_length(); timeline_pos=pos; track_pos->update(); - emit_signal("timeline_changed",pos); + emit_signal("timeline_changed",pos,true); } break; case TRACK_MENU_PREV_STEP: { @@ -934,7 +930,7 @@ void AnimationKeyEditor::_menu_track(int p_type) { pos=0; timeline_pos=pos; track_pos->update(); - emit_signal("timeline_changed",pos); + emit_signal("timeline_changed",pos,true); } break; @@ -1046,7 +1042,7 @@ void AnimationKeyEditor::_animation_optimize() { - animation->optimize(optimize_linear_error->get_val(),optimize_angular_error->get_val(),optimize_max_angle->get_val()); + animation->optimize(optimize_linear_error->get_value(),optimize_angular_error->get_value(),optimize_max_angle->get_value()); track_editor->update(); undo_redo->clear_history(); @@ -1055,7 +1051,7 @@ void AnimationKeyEditor::_animation_optimize() { float AnimationKeyEditor::_get_zoom_scale() const { - float zv = zoom->get_val(); + float zv = zoom->get_value(); if (zv<1) { zv = 1.0-zv; return Math::pow(1.0+zv,8.0)*100; @@ -1078,7 +1074,7 @@ void AnimationKeyEditor::_track_pos_draw() { int settings_limit = size.width - right_data_size_cache; int name_limit = settings_limit * name_column_ratio; - float keys_from= h_scroll->get_val(); + float keys_from= h_scroll->get_value(); float zoom_scale = _get_zoom_scale(); float keys_to=keys_from+(settings_limit-name_limit) / zoom_scale; @@ -1087,7 +1083,7 @@ void AnimationKeyEditor::_track_pos_draw() { //will move to separate control! (for speedup) if (timeline_pos >= keys_from && timeline_pos<keys_to) { //draw position - int pixel = (timeline_pos - h_scroll->get_val()) * zoom_scale; + int pixel = (timeline_pos - h_scroll->get_value()) * zoom_scale; pixel+=name_limit; track_pos->draw_line(ofs+Point2(pixel,0),ofs+Point2(pixel,size.height),Color(1,0.3,0.3,0.8)); @@ -1096,7 +1092,6 @@ void AnimationKeyEditor::_track_pos_draw() { void AnimationKeyEditor::_track_editor_draw() { - VisualServer::get_singleton()->canvas_item_set_clip(track_editor->get_canvas_item(),true); if (animation.is_valid() && animation->get_track_count()) { if (selected_track < 0) @@ -1163,14 +1158,21 @@ void AnimationKeyEditor::_track_editor_draw() { Ref<Texture> add_key_icon = get_icon("TrackAddKey","EditorIcons"); Ref<Texture> add_key_icon_hl = get_icon("TrackAddKeyHl","EditorIcons"); Ref<Texture> down_icon = get_icon("select_arrow","Tree"); + + Ref<Texture> wrap_icon[2]={ + get_icon("InterpWrapClamp","EditorIcons"), + get_icon("InterpWrapLoop","EditorIcons"), + }; + Ref<Texture> interp_icon[3]={ get_icon("InterpRaw","EditorIcons"), get_icon("InterpLinear","EditorIcons"), get_icon("InterpCubic","EditorIcons") }; Ref<Texture> cont_icon[3]={ + get_icon("TrackContinuous","EditorIcons"), get_icon("TrackDiscrete","EditorIcons"), - get_icon("TrackContinuous","EditorIcons") + get_icon("TrackTrigger","EditorIcons") }; Ref<Texture> type_icon[3]={ get_icon("KeyValue","EditorIcons"), @@ -1186,7 +1188,7 @@ void AnimationKeyEditor::_track_editor_draw() { Ref<Texture> type_hover=get_icon("KeyHover","EditorIcons"); Ref<Texture> type_selected=get_icon("KeySelected","EditorIcons"); - int right_separator_ofs = down_icon->get_width() *2 + add_key_icon->get_width() + interp_icon[0]->get_width() + cont_icon[0]->get_width() + hsep*7; + int right_separator_ofs = down_icon->get_width() *3 + add_key_icon->get_width() + interp_icon[0]->get_width() + wrap_icon[0]->get_width() + cont_icon[0]->get_width() + hsep*9; int h = font->get_height()+sep; @@ -1232,8 +1234,8 @@ void AnimationKeyEditor::_track_editor_draw() { if (l<=0) l=0.001; //avoid crashor - int end_px = (l - h_scroll->get_val()) * scale; - int begin_px = -h_scroll->get_val() * scale; + int end_px = (l - h_scroll->get_value()) * scale; + int begin_px = -h_scroll->get_value() * scale; Color notimecol; notimecol.r=timecolor.gray(); notimecol.g=notimecol.r; @@ -1259,7 +1261,7 @@ void AnimationKeyEditor::_track_editor_draw() { - keys_from= h_scroll->get_val(); + keys_from= h_scroll->get_value(); keys_to=keys_from+zoomw / scale; { @@ -1336,8 +1338,8 @@ void AnimationKeyEditor::_track_editor_draw() { for(int i=0;i<zoomw;i++) { - float pos = h_scroll->get_val() + double(i)/scale; - float prev = h_scroll->get_val() + (double(i)-1.0)/scale; + float pos = h_scroll->get_value() + double(i)/scale; + float prev = h_scroll->get_value() + (double(i)-1.0)/scale; int sc = int(Math::floor(pos*SC_ADJ)); @@ -1355,14 +1357,13 @@ void AnimationKeyEditor::_track_editor_draw() { } } - Color sep_color=color; color.a*=0.5; 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_value() + i; if (idx>=animation->get_track_count()) break; int y = h+i*h+sep; @@ -1427,6 +1428,20 @@ void AnimationKeyEditor::_track_editor_draw() { icon_ofs.x-=hsep; */ + track_ofs[0]=size.width-icon_ofs.x; + icon_ofs.x-=down_icon->get_width(); + te->draw_texture(down_icon,icon_ofs); + + int wrap_type = animation->track_get_interpolation_loop_wrap(idx)?1:0; + icon_ofs.x-=hsep; + icon_ofs.x-=wrap_icon[wrap_type]->get_width(); + te->draw_texture(wrap_icon[wrap_type],icon_ofs); + + icon_ofs.x-=hsep; + te->draw_line(Point2(icon_ofs.x,ofs.y+y),Point2(icon_ofs.x,ofs.y+y+h),sepcolor); + + track_ofs[1]=size.width-icon_ofs.x; + icon_ofs.x-=down_icon->get_width(); te->draw_texture(down_icon,icon_ofs); @@ -1439,18 +1454,20 @@ void AnimationKeyEditor::_track_editor_draw() { icon_ofs.x-=hsep; te->draw_line(Point2(icon_ofs.x,ofs.y+y),Point2(icon_ofs.x,ofs.y+y+h),sepcolor); + track_ofs[2]=size.width-icon_ofs.x; + if (animation->track_get_type(idx)==Animation::TYPE_VALUE) { - int continuous = animation->value_track_is_continuous(idx)?1:0; + int umode = animation->value_track_get_update_mode(idx); icon_ofs.x-=hsep; icon_ofs.x-=down_icon->get_width(); te->draw_texture(down_icon,icon_ofs); icon_ofs.x-=hsep; - icon_ofs.x-=cont_icon[continuous]->get_width(); - te->draw_texture(cont_icon[continuous],icon_ofs); + icon_ofs.x-=cont_icon[umode]->get_width(); + te->draw_texture(cont_icon[umode],icon_ofs); } else { icon_ofs.x -= hsep*2 + cont_icon[0]->get_width() + down_icon->get_width(); @@ -1459,10 +1476,14 @@ void AnimationKeyEditor::_track_editor_draw() { icon_ofs.x-=hsep; te->draw_line(Point2(icon_ofs.x,ofs.y+y),Point2(icon_ofs.x,ofs.y+y+h),sepcolor); + track_ofs[3]=size.width-icon_ofs.x; + icon_ofs.x-=hsep; icon_ofs.x-=add_key_icon->get_width(); te->draw_texture((mouse_over.over==MouseOver::OVER_ADD_KEY && mouse_over.track==idx)?add_key_icon_hl:add_key_icon,icon_ofs); + track_ofs[4]=size.width-icon_ofs.x; + //draw the keys; int tt = animation->track_get_type(idx); float key_vofs = Math::floor((h - type_icon[tt]->get_height())/2); @@ -1558,14 +1579,14 @@ void AnimationKeyEditor::_track_editor_draw() { } float motion = from_t+(click.to.x - click.at.x)/zoom_scale; - if (step->get_val()) - motion = Math::stepify(motion,step->get_val()); + if (step->get_value()) + motion = Math::stepify(motion,step->get_value()); for(Map<SelectedKey,KeyInfo>::Element *E=selection.front();E;E=E->next()) { int idx = E->key().track; - int i = idx-v_scroll->get_val(); + int i = idx-v_scroll->get_value(); if (i<0 || i>=fit) continue; int y = h+i*h+sep; @@ -1619,16 +1640,32 @@ void AnimationKeyEditor::_track_menu_selected(int p_idx) { undo_redo->add_do_method(animation.ptr(),"track_set_interpolation_type",interp_editing,p_idx); undo_redo->add_undo_method(animation.ptr(),"track_set_interpolation_type",interp_editing,animation->track_get_interpolation_type(interp_editing)); undo_redo->commit_action(); - } - - if (cont_editing!=-1) { + } else if (cont_editing!=-1) { ERR_FAIL_INDEX(cont_editing,animation->get_track_count()); undo_redo->create_action(TTR("Anim Track Change Value Mode")); - undo_redo->add_do_method(animation.ptr(),"value_track_set_continuous",cont_editing,p_idx); - undo_redo->add_undo_method(animation.ptr(),"value_track_set_continuous",cont_editing,animation->value_track_is_continuous(cont_editing)); + undo_redo->add_do_method(animation.ptr(),"value_track_set_update_mode",cont_editing,p_idx); + undo_redo->add_undo_method(animation.ptr(),"value_track_set_update_mode",cont_editing,animation->value_track_get_update_mode(cont_editing)); + undo_redo->commit_action(); + } else if (wrap_editing!=-1) { + + ERR_FAIL_INDEX(wrap_editing,animation->get_track_count()); + + undo_redo->create_action(TTR("Anim Track Change Wrap Mode")); + undo_redo->add_do_method(animation.ptr(),"track_set_interpolation_loop_wrap",wrap_editing,p_idx?true:false); + undo_redo->add_undo_method(animation.ptr(),"track_set_interpolation_loop_wrap",wrap_editing,animation->track_get_interpolation_loop_wrap(wrap_editing)); undo_redo->commit_action(); + } else { + switch (p_idx) { + + case RIGHT_MENU_DUPLICATE: + _anim_duplicate_keys(); break; + case RIGHT_MENU_DUPLICATE_TRANSPOSE: + _anim_duplicate_keys(true); break; + case RIGHT_MENU_REMOVE: + _anim_delete_keys(); break; + } } } @@ -1717,9 +1754,9 @@ void AnimationKeyEditor::_curve_transition_changed(float p_what) { if (selection.size()==0) return; if (selection.size()==1) - undo_redo->create_action(TTR("Edit Node Curve"),true); + undo_redo->create_action(TTR("Edit Node Curve"),UndoRedo::MERGE_ENDS); else - undo_redo->create_action(TTR("Edit Selection Curve"),true); + undo_redo->create_action(TTR("Edit Selection Curve"),UndoRedo::MERGE_ENDS); for(Map<SelectedKey,KeyInfo>::Element *E=selection.front();E;E=E->next()) { @@ -1790,7 +1827,26 @@ bool AnimationKeyEditor::_edit_if_single_selection() { } -void AnimationKeyEditor::_track_editor_input_event(const InputEvent& p_input) { +void AnimationKeyEditor::_anim_delete_keys() { + if (selection.size()) { + undo_redo->create_action(TTR("Anim Delete Keys")); + + for(Map<SelectedKey,KeyInfo>::Element *E=selection.back();E;E=E->prev()) { + + undo_redo->add_do_method(animation.ptr(),"track_remove_key",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(); + //selection.clear(); + accept_event(); + _edit_if_single_selection(); + } +} + +void AnimationKeyEditor::_track_editor_gui_input(const InputEvent& p_input) { Control *te=track_editor; Ref<StyleBox> style = get_stylebox("normal","TextEdit"); @@ -1805,8 +1861,6 @@ void AnimationKeyEditor::_track_editor_input_event(const InputEvent& p_input) { Ref<Font> font = te->get_font("font","Tree"); int sep = get_constant("vseparation","Tree"); int hsep = get_constant("hseparation","Tree"); - Color color = get_color("font_color","Tree"); - Color sepcolor = get_color("guide_color","Tree"); Ref<Texture> remove_icon = get_icon("Remove","EditorIcons"); Ref<Texture> move_up_icon = get_icon("MoveUp","EditorIcons"); Ref<Texture> move_down_icon = get_icon("MoveDown","EditorIcons"); @@ -1814,21 +1868,26 @@ void AnimationKeyEditor::_track_editor_input_event(const InputEvent& p_input) { Ref<Texture> hsize_icon = get_icon("Hsize","EditorIcons"); Ref<Texture> add_key_icon = get_icon("TrackAddKey","EditorIcons"); + Ref<Texture> wrap_icon[2]={ + get_icon("InterpWrapClamp","EditorIcons"), + get_icon("InterpWrapLoop","EditorIcons"), + }; Ref<Texture> interp_icon[3]={ get_icon("InterpRaw","EditorIcons"), get_icon("InterpLinear","EditorIcons"), get_icon("InterpCubic","EditorIcons") }; Ref<Texture> cont_icon[3]={ + get_icon("TrackContinuous","EditorIcons"), get_icon("TrackDiscrete","EditorIcons"), - get_icon("TrackContinuous","EditorIcons") + get_icon("TrackTrigger","EditorIcons") }; Ref<Texture> type_icon[3]={ get_icon("KeyValue","EditorIcons"), get_icon("KeyXform","EditorIcons"), get_icon("KeyCall","EditorIcons") }; - int right_separator_ofs = down_icon->get_width() *2 + add_key_icon->get_width() + interp_icon[0]->get_width() + cont_icon[0]->get_width() + hsep*7; + int right_separator_ofs = down_icon->get_width() *3 + add_key_icon->get_width() + interp_icon[0]->get_width() + wrap_icon[0]->get_width() + cont_icon[0]->get_width() + hsep*9; int h = font->get_height()+sep; @@ -1861,38 +1920,23 @@ void AnimationKeyEditor::_track_editor_input_event(const InputEvent& p_input) { } else if (p_input.key.scancode==KEY_DELETE && p_input.key.pressed && click.click==ClickOver::CLICK_NONE) { - if (selection.size()) { - undo_redo->create_action(TTR("Anim Delete Keys")); - - for(Map<SelectedKey,KeyInfo>::Element *E=selection.back();E;E=E->prev()) { - - undo_redo->add_do_method(animation.ptr(),"track_remove_key",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(); - //selection.clear(); - accept_event(); - _edit_if_single_selection(); - } + _anim_delete_keys(); } else if (animation.is_valid() && animation->get_track_count()>0) { if (p_input.is_pressed() && (p_input.is_action("ui_up") || p_input.is_action("ui_page_up"))) { if (p_input.is_action("ui_up")) selected_track--; - if (v_scroll->is_visible() && p_input.is_action("ui_page_up")) + if (v_scroll->is_visible_in_tree() && p_input.is_action("ui_page_up")) selected_track--; if (selected_track<0) selected_track=0; - if (v_scroll->is_visible()) { - if (v_scroll->get_val() > selected_track) - v_scroll->set_val(selected_track); + if (v_scroll->is_visible_in_tree()) { + if (v_scroll->get_value() > selected_track) + v_scroll->set_value(selected_track); } @@ -1905,14 +1949,14 @@ void AnimationKeyEditor::_track_editor_input_event(const InputEvent& p_input) { if (p_input.is_action("ui_down")) selected_track++; - else if (v_scroll->is_visible() && p_input.is_action("ui_page_down")) + else if (v_scroll->is_visible_in_tree() && p_input.is_action("ui_page_down")) selected_track+=v_scroll->get_page(); if (selected_track >= animation->get_track_count()) selected_track=animation->get_track_count()-1; - if (v_scroll->is_visible() && v_scroll->get_page()+v_scroll->get_val() < selected_track+1) { - v_scroll->set_val(selected_track-v_scroll->get_page()+1); + if (v_scroll->is_visible_in_tree() && v_scroll->get_page()+v_scroll->get_value() < selected_track+1) { + v_scroll->set_value(selected_track-v_scroll->get_page()+1); } track_editor->update(); @@ -1928,12 +1972,131 @@ void AnimationKeyEditor::_track_editor_input_event(const InputEvent& p_input) { if (mb.button_index==BUTTON_WHEEL_UP && mb.pressed) { - v_scroll->set_val( v_scroll->get_val() - v_scroll->get_page() / 8 ); + if (mb.mod.command) { + zoom->set_value(zoom->get_value() + zoom->get_step()); + } else { + v_scroll->set_value( v_scroll->get_value() - v_scroll->get_page() / 8 ); + } } if (mb.button_index==BUTTON_WHEEL_DOWN && mb.pressed) { - v_scroll->set_val( v_scroll->get_val() + v_scroll->get_page() / 8 ); + if (mb.mod.command) { + zoom->set_value(zoom->get_value() - zoom->get_step()); + } else { + v_scroll->set_value( v_scroll->get_value() + v_scroll->get_page() / 8 ); + } + } + + if (mb.button_index==BUTTON_RIGHT && mb.pressed) { + + Point2 mpos = Point2(mb.x,mb.y)-ofs; + + if (selection.size() == 0) { + // Auto-select on right-click if nothing is selected + // Note: This code is pretty much duplicated from the left click code, + // both codes could be moved into a function to avoid the duplicated code. + Point2 mpos = Point2(mb.x,mb.y)-ofs; + + if (mpos.y < h ) { + return; + } + + mpos.y -= h; + + int idx = mpos.y / h; + idx+=v_scroll->get_value(); + if (idx <0 || idx>=animation->get_track_count()) + break; + + if (mpos.x < name_limit) { + } else if (mpos.x < settings_limit) { + float pos = mpos.x - name_limit; + pos/=_get_zoom_scale(); + pos+=h_scroll->get_value(); + float w_time = (type_icon[0]->get_width() / _get_zoom_scale())/2.0; + + int kidx = animation->track_find_key(idx,pos); + int kidx_n = kidx+1; + int key=-1; + + if (kidx>=0 && kidx<animation->track_get_key_count(idx)) { + + float kpos = animation->track_get_key_time(idx,kidx); + if (ABS(pos-kpos)<=w_time) { + + key=kidx; + } + } + + if (key==-1 && kidx_n>=0 && kidx_n<animation->track_get_key_count(idx)) { + + float kpos = animation->track_get_key_time(idx,kidx_n); + if (ABS(pos-kpos)<=w_time) { + + key=kidx_n; + } + } + + if (key==-1) { + + click.click=ClickOver::CLICK_SELECT_KEYS; + click.at=Point2(mb.x,mb.y); + click.to=click.at; + click.shift=mb.mod.shift; + selected_track=idx; + track_editor->update(); + //drag select region + return; + + } + + + + SelectedKey sk; + sk.track=idx; + sk.key=key; + KeyInfo ki; + ki.pos= animation->track_get_key_time(idx,key); + click.shift=mb.mod.shift; + click.selk=sk; + + + if (!mb.mod.shift && !selection.has(sk)) + _clear_selection(); + + selection.insert(sk,ki); + + click.click=ClickOver::CLICK_MOVE_KEYS; + click.at=Point2(mb.x,mb.y); + click.to=click.at; + update(); + selected_track=idx; + track_editor->update(); + + if (_edit_if_single_selection() && mb.mod.command) { + edit_button->set_pressed(true); + key_editor_tab->show(); + } + } + } + + if (selection.size()) { + // User has right clicked and we have a selection, show a popup menu with options + track_menu->clear(); + track_menu->set_size(Point2(1,1)); + track_menu->add_item(TTR("Duplicate Selection"), RIGHT_MENU_DUPLICATE); + track_menu->add_item(TTR("Duplicate Transposed"), RIGHT_MENU_DUPLICATE_TRANSPOSE); + track_menu->add_item(TTR("Remove Selection"), RIGHT_MENU_REMOVE); + + track_menu->set_pos(te->get_global_pos()+mpos); + + interp_editing=-1; + cont_editing=-1; + wrap_editing=-1; + + track_menu->popup(); + } } if (mb.button_index==BUTTON_LEFT && !(mb.button_mask&~BUTTON_MASK_LEFT)) { @@ -1960,7 +2123,7 @@ void AnimationKeyEditor::_track_editor_input_event(const InputEvent& p_input) { //seek //int zoomw = settings_limit-name_limit; float scale = _get_zoom_scale(); - float pos = h_scroll->get_val() + (mpos.x-name_limit) / scale; + float pos = h_scroll->get_value() + (mpos.x-name_limit) / scale; if (animation->get_step()) pos=Math::stepify(pos,animation->get_step()); @@ -1972,7 +2135,7 @@ void AnimationKeyEditor::_track_editor_input_event(const InputEvent& p_input) { click.click=ClickOver::CLICK_DRAG_TIMELINE; click.at=Point2(mb.x,mb.y); click.to=click.at; - emit_signal("timeline_changed",pos); + emit_signal("timeline_changed",pos,false); } @@ -1982,7 +2145,7 @@ void AnimationKeyEditor::_track_editor_input_event(const InputEvent& p_input) { mpos.y -= h; int idx = mpos.y / h; - idx+=v_scroll->get_val(); + idx+=v_scroll->get_value(); if (idx <0) break; @@ -2023,7 +2186,7 @@ void AnimationKeyEditor::_track_editor_input_event(const InputEvent& p_input) { float pos = mpos.x - name_limit; pos/=_get_zoom_scale(); - pos+=h_scroll->get_val(); + pos+=h_scroll->get_value(); float w_time = (type_icon[0]->get_width() / _get_zoom_scale())/2.0; int kidx = animation->track_find_key(idx,pos); @@ -2154,7 +2317,33 @@ void AnimationKeyEditor::_track_editor_input_event(const InputEvent& p_input) { ofsx-=hsep*3+move_up_icon->get_width(); */ - if (ofsx < down_icon->get_width() + interp_icon[0]->get_width() + hsep*2) { + + if (ofsx < track_ofs[1]) { + + track_menu->clear(); + track_menu->set_size(Point2(1,1)); + static const char *interp_name[2]={"Clamp Loop Interp","Wrap Loop Interp"}; + for(int i=0;i<2;i++) { + track_menu->add_icon_item(wrap_icon[i],interp_name[i]); + } + + int popup_y = ofs.y+((int(mpos.y)/h)+2)*h; + int popup_x = size.width-track_ofs[1]; + + track_menu->set_pos(te->get_global_pos()+Point2(popup_x,popup_y)); + + + wrap_editing=idx; + interp_editing=-1; + cont_editing=-1; + + track_menu->popup(); + + return; + } + + + if (ofsx < track_ofs[2]) { track_menu->clear(); track_menu->set_size(Point2(1,1)); @@ -2163,39 +2352,38 @@ void AnimationKeyEditor::_track_editor_input_event(const InputEvent& p_input) { track_menu->add_icon_item(interp_icon[i],interp_name[i]); } - int lofs = remove_icon->get_width() + move_up_icon->get_width() + move_down_icon->get_width() + down_icon->get_width() *2 + hsep*7;//interp_icon[0]->get_width() + cont_icon[0]->get_width() ; int popup_y = ofs.y+((int(mpos.y)/h)+2)*h; - int popup_x = ofs.x+size.width-lofs; + int popup_x = size.width-track_ofs[2]; track_menu->set_pos(te->get_global_pos()+Point2(popup_x,popup_y)); interp_editing=idx; cont_editing=-1; + wrap_editing=-1; track_menu->popup(); return; } - ofsx-=hsep*2+interp_icon[0]->get_width()+down_icon->get_width(); - - if (ofsx < down_icon->get_width() + cont_icon[0]->get_width()) { + if (ofsx < track_ofs[3]) { track_menu->clear(); track_menu->set_size(Point2(1,1)); - static const char *cont_name[3]={"Discrete","Continuous"}; - for(int i=0;i<2;i++) { + String cont_name[3]={TTR("Continuous"),TTR("Discrete"),TTR("Trigger")}; + for(int i=0;i<3;i++) { track_menu->add_icon_item(cont_icon[i],cont_name[i]); } - int lofs = settings_limit; + int popup_y = ofs.y+((int(mpos.y)/h)+2)*h; - int popup_x = ofs.x+lofs; + int popup_x = size.width-track_ofs[3]; track_menu->set_pos(te->get_global_pos()+Point2(popup_x,popup_y)); interp_editing=-1; + wrap_editing=-1; cont_editing=idx; track_menu->popup(); @@ -2203,9 +2391,7 @@ void AnimationKeyEditor::_track_editor_input_event(const InputEvent& p_input) { return; } - ofsx-=hsep*3+cont_icon[0]->get_width()+down_icon->get_width(); - - if (ofsx < add_key_icon->get_width()) { + if (ofsx < track_ofs[4]) { Animation::TrackType tt = animation->track_get_type(idx); @@ -2280,7 +2466,7 @@ void AnimationKeyEditor::_track_editor_input_event(const InputEvent& p_input) { float zoom_scale=_get_zoom_scale(); - float keys_from = h_scroll->get_val(); + float keys_from = h_scroll->get_value(); float keys_to = keys_from + (settings_limit-name_limit) / zoom_scale; float from_time = keys_from + ( click.at.x - (name_limit+ofs.x)) / zoom_scale; @@ -2300,8 +2486,8 @@ void AnimationKeyEditor::_track_editor_input_event(const InputEvent& p_input) { to_time = keys_to; - int from_track = int(click.at.y-ofs.y-h-sep) / h + v_scroll->get_val(); - int to_track = int(click.to.y-ofs.y-h-sep) / h + v_scroll->get_val(); + int from_track = int(click.at.y-ofs.y-h-sep) / h + v_scroll->get_value(); + int to_track = int(click.to.y-ofs.y-h-sep) / h + v_scroll->get_value(); int from_mod = int(click.at.y-ofs.y-sep) % h; int to_mod = int(click.to.y-ofs.y-sep) % h; @@ -2329,8 +2515,8 @@ void AnimationKeyEditor::_track_editor_input_event(const InputEvent& p_input) { break; } - int tracks_from = v_scroll->get_val(); - int tracks_to = v_scroll->get_val()+fit-1; + int tracks_from = v_scroll->get_value(); + int tracks_to = v_scroll->get_value()+fit-1; if (tracks_to>=animation->get_track_count()) tracks_to=animation->get_track_count()-1; @@ -2413,8 +2599,8 @@ void AnimationKeyEditor::_track_editor_input_event(const InputEvent& p_input) { } float motion = from_t+(click.to.x - click.at.x)/_get_zoom_scale(); - if (step->get_val()) - motion = Math::stepify(motion,step->get_val()); + if (step->get_value()) + motion = Math::stepify(motion,step->get_value()); @@ -2457,8 +2643,10 @@ void AnimationKeyEditor::_track_editor_input_event(const InputEvent& p_input) { for(Map<SelectedKey,KeyInfo>::Element *E=selection.back();E;E=E->prev()) { float newpos=E->get().pos-from_t+motion; - //if (newpos<0) - // continue; //no add at the begining + /* + if (newpos<0) + continue; //no add at the begining + */ undo_redo->add_do_method(animation.ptr(),"track_insert_key",E->key().track,newpos,animation->track_get_key_value(E->key().track,E->key().key),animation->track_get_key_transition(E->key().track,E->key().key)); } @@ -2467,8 +2655,10 @@ void AnimationKeyEditor::_track_editor_input_event(const InputEvent& p_input) { for(Map<SelectedKey,KeyInfo>::Element *E=selection.back();E;E=E->prev()) { float newpos=E->get().pos+-from_t+motion; - //if (newpos<0) - // continue; //no remove what no inserted + /* + if (newpos<0) + continue; //no remove what no inserted + */ undo_redo->add_undo_method(animation.ptr(),"track_remove_key_at_pos",E->key().track,newpos); } @@ -2506,7 +2696,7 @@ void AnimationKeyEditor::_track_editor_input_event(const InputEvent& p_input) { float oldpos=E->get().pos; float newpos=oldpos-from_t+motion; //if (newpos>=0) - undo_redo->add_do_method(this,"_select_at_anim",animation,E->key().track,newpos); + undo_redo->add_do_method(this,"_select_at_anim",animation,E->key().track,newpos); undo_redo->add_undo_method(this,"_select_at_anim",animation,E->key().track,oldpos); } @@ -2577,7 +2767,7 @@ void AnimationKeyEditor::_track_editor_input_event(const InputEvent& p_input) { //int zoomw = settings_limit-name_limit; float scale = _get_zoom_scale(); - float pos = h_scroll->get_val() + (mpos.x-name_limit) / scale; + float pos = h_scroll->get_value() + (mpos.x-name_limit) / scale; if (animation->get_step()) { pos=Math::stepify(pos,animation->get_step()); @@ -2587,14 +2777,14 @@ void AnimationKeyEditor::_track_editor_input_event(const InputEvent& p_input) { if (pos>=animation->get_length()) pos=animation->get_length(); - if (pos < h_scroll->get_val()) { - h_scroll->set_val(pos); - } else if (pos > h_scroll->get_val() + (settings_limit - name_limit) / scale) { - h_scroll->set_val( pos - (settings_limit - name_limit) / scale ); + if (pos < h_scroll->get_value()) { + h_scroll->set_value(pos); + } else if (pos > h_scroll->get_value() + (settings_limit - name_limit) / scale) { + h_scroll->set_value( pos - (settings_limit - name_limit) / scale ); } timeline_pos=pos; - emit_signal("timeline_changed",pos); + emit_signal("timeline_changed",pos,true); @@ -2604,18 +2794,18 @@ void AnimationKeyEditor::_track_editor_input_event(const InputEvent& p_input) { click.to=Point2(mb.x,mb.y); if (click.to.y<h && click.at.y>h && mb.relative_y<0) { - float prev = v_scroll->get_val(); - v_scroll->set_val( v_scroll->get_val() -1 ); - if (prev!=v_scroll->get_val()) + float prev = v_scroll->get_value(); + v_scroll->set_value( v_scroll->get_value() -1 ); + if (prev!=v_scroll->get_value()) click.at.y+=h; } if (click.to.y>size.height && click.at.y<size.height && mb.relative_y>0) { - float prev = v_scroll->get_val(); - v_scroll->set_val( v_scroll->get_val() +1 ); - if (prev!=v_scroll->get_val()) + float prev = v_scroll->get_value(); + v_scroll->set_value( v_scroll->get_value() +1 ); + if (prev!=v_scroll->get_value()) click.at.y-=h; } @@ -2632,7 +2822,7 @@ void AnimationKeyEditor::_track_editor_input_event(const InputEvent& p_input) { int rel = mb.relative_x; float relf = rel / _get_zoom_scale(); - h_scroll->set_val( h_scroll->get_val() - relf ); + h_scroll->set_value( h_scroll->get_value() - relf ); } if (mb.button_mask==0) { @@ -2658,7 +2848,7 @@ void AnimationKeyEditor::_track_editor_input_event(const InputEvent& p_input) { mpos.y -= h; int idx = mpos.y / h; - idx+=v_scroll->get_val(); + idx+=v_scroll->get_value(); if (idx <0 || idx>=animation->get_track_count()) break; @@ -2674,7 +2864,7 @@ void AnimationKeyEditor::_track_editor_input_event(const InputEvent& p_input) { float pos = mpos.x - name_limit; pos/=_get_zoom_scale(); - pos+=h_scroll->get_val(); + pos+=h_scroll->get_value(); float w_time = (type_icon[0]->get_width() / _get_zoom_scale())/2.0; int kidx = animation->track_find_key(idx,pos); @@ -2817,7 +3007,15 @@ void AnimationKeyEditor::_track_editor_input_event(const InputEvent& p_input) { */ - if (ofsx < down_icon->get_width() + interp_icon[0]->get_width() + hsep*2) { + if (ofsx < down_icon->get_width() + wrap_icon[0]->get_width() + hsep*3) { + + mouse_over.over=MouseOver::OVER_WRAP; + return; + } + + ofsx-=hsep*3+wrap_icon[0]->get_width() + down_icon->get_width(); + + if (ofsx < down_icon->get_width() + interp_icon[0]->get_width() + hsep*3) { mouse_over.over=MouseOver::OVER_INTERP; return; @@ -2889,7 +3087,7 @@ void AnimationKeyEditor::_notification(int p_what) { tpp->add_item(TTR("In-Out"),TRACK_MENU_SET_ALL_TRANS_INOUT); tpp->add_item(TTR("Out-In"),TRACK_MENU_SET_ALL_TRANS_OUTIN); tpp->set_name(TTR("Transitions")); - tpp->connect("item_pressed",this,"_menu_track"); + tpp->connect("id_pressed",this,"_menu_track"); optimize_dialog->connect("confirmed",this,"_animation_optimize"); menu_track->get_popup()->add_child(tpp); @@ -2940,17 +3138,23 @@ void AnimationKeyEditor::_notification(int p_what) { get_icon("InterpCubic","EditorIcons") }; Ref<Texture> cont_icon[3]={ + get_icon("TrackContinuous","EditorIcons"), get_icon("TrackDiscrete","EditorIcons"), - get_icon("TrackContinuous","EditorIcons") + get_icon("TrackTrigger","EditorIcons") + }; + + Ref<Texture> wrap_icon[2]={ + get_icon("InterpWrapClamp","EditorIcons"), + get_icon("InterpWrapLoop","EditorIcons"), }; //right_data_size_cache = remove_icon->get_width() + move_up_icon->get_width() + move_down_icon->get_width() + down_icon->get_width() *2 + interp_icon[0]->get_width() + cont_icon[0]->get_width() + add_key_icon->get_width() + hsep*11; - right_data_size_cache = down_icon->get_width() *2 + add_key_icon->get_width() + interp_icon[0]->get_width() + cont_icon[0]->get_width() + hsep*7; + right_data_size_cache = down_icon->get_width() *3 + add_key_icon->get_width() + interp_icon[0]->get_width() + cont_icon[0]->get_width() + wrap_icon[0]->get_width() + hsep*8; } call_select->connect("selected",this,"_add_call_track"); -// rename_anim->set_icon( get_icon("Rename","EditorIcons") ); + //rename_anim->set_icon( get_icon("Rename","EditorIcons") ); /* edit_anim->set_icon( get_icon("Edit","EditorIcons") ); blend_anim->set_icon( get_icon("Blend","EditorIcons") ); @@ -2958,8 +3162,8 @@ void AnimationKeyEditor::_notification(int p_what) { stop->set_icon( get_icon("Stop","EditorIcons") ); pause->set_icon( get_icon("Pause","EditorIcons") ); */ -// menu->set_icon(get_icon("Animation","EditorIcons")); -// play->set_icon(get_icon("AnimationPlay","EditorIcons")); + //menu->set_icon(get_icon("Animation","EditorIcons")); + //play->set_icon(get_icon("AnimationPlay","EditorIcons")); //menu->set_icon(get_icon("Animation","EditorIcons")); _update_menu(); @@ -2988,8 +3192,8 @@ void AnimationKeyEditor::_update_paths() { //timeline->set_max(animation->get_length()); //timeline->set_step(0.01); track_editor->update(); - length->set_val(animation->get_length()); - step->set_val(animation->get_step()); + length->set_value(animation->get_length()); + step->set_value(animation->get_step()); } } @@ -3004,12 +3208,11 @@ void AnimationKeyEditor::_update_menu() { updating=true; - bool empty= !animation.is_valid(); if (animation.is_valid()) { - length->set_val(animation->get_length()); + length->set_value(animation->get_length()); loop->set_pressed(animation->has_loop()); - step->set_val(animation->get_step()); + step->set_value(animation->get_step()); } track_editor->update(); @@ -3051,12 +3254,12 @@ void AnimationKeyEditor::set_animation(const Ref<Animation>& p_anim) { void AnimationKeyEditor::set_root(Node *p_root) { if (root) - root->disconnect("exit_tree",this,"_root_removed"); + root->disconnect("tree_exited",this,"_root_removed"); root=p_root; if (root) - root->connect("exit_tree",this,"_root_removed",make_binds(),CONNECT_ONESHOT); + root->connect("tree_exited",this,"_root_removed",make_binds(),CONNECT_ONESHOT); } @@ -3073,7 +3276,7 @@ Node *AnimationKeyEditor::get_root() const { void AnimationKeyEditor::update_keying() { - bool keying_enabled=is_visible() && animation.is_valid(); + bool keying_enabled=is_visible_in_tree() && animation.is_valid(); if (keying_enabled==keying) return; @@ -3092,14 +3295,14 @@ bool AnimationKeyEditor::has_keying() const { void AnimationKeyEditor::_query_insert(const InsertData& p_id) { - if (insert_frame!=OS::get_singleton()->get_frames_drawn()) { + if (insert_frame!=Engine::get_singleton()->get_frames_drawn()) { //clear insert list for the frame if frame changed - if (insert_confirm->is_visible()) + if (insert_confirm->is_visible_in_tree()) return; //do nothing insert_data.clear(); insert_query=false; } - insert_frame=OS::get_singleton()->get_frames_drawn(); + insert_frame=Engine::get_singleton()->get_frames_drawn(); for (List<InsertData>::Element *E=insert_data.front();E;E=E->next()) { //prevent insertion of multiple tracks @@ -3110,7 +3313,7 @@ void AnimationKeyEditor::_query_insert(const InsertData& p_id) { insert_data.push_back(p_id); if (p_id.track_idx==-1) { - if (bool(EDITOR_DEF("animation/confirm_insert_track",true))) { + if (bool(EDITOR_DEF("editors/animation/confirm_insert_track",true))) { //potential new key, does not exist if (insert_data.size()==1) insert_confirm->set_text(vformat(TTR("Create NEW track for %s and insert key?"),p_id.query)); @@ -3311,7 +3514,7 @@ int AnimationKeyEditor::_confirm_insert(InsertData p_id,int p_last_track) { created=true; undo_redo->create_action(TTR("Anim Insert Track & Key")); - bool continuous=false; + Animation::UpdateMode update_mode=Animation::UPDATE_DISCRETE; if (p_id.type==Animation::TYPE_VALUE) { //wants a new tack @@ -3324,16 +3527,21 @@ int AnimationKeyEditor::_confirm_insert(InsertData p_id,int p_last_track) { PropertyInfo h = _find_hint_for_track(animation->get_track_count()-1,np); animation->remove_track(animation->get_track_count()-1); //hack - - continuous = - h.type==Variant::REAL || + if ( h.type==Variant::REAL || h.type==Variant::VECTOR2 || h.type==Variant::RECT2 || h.type==Variant::VECTOR3 || - h.type==Variant::_AABB || + h.type==Variant::RECT3 || h.type==Variant::QUAT || h.type==Variant::COLOR || - h.type==Variant::TRANSFORM ; + h.type==Variant::TRANSFORM ) { + + update_mode=Animation::UPDATE_CONTINUOUS; + } + + if (h.usage&PROPERTY_USAGE_ANIMATE_AS_TRIGGER) { + update_mode=Animation::UPDATE_TRIGGER; + } } } @@ -3342,7 +3550,7 @@ int AnimationKeyEditor::_confirm_insert(InsertData p_id,int p_last_track) { undo_redo->add_do_method(animation.ptr(),"add_track",p_id.type); undo_redo->add_do_method(animation.ptr(),"track_set_path",p_id.track_idx,p_id.path); if (p_id.type==Animation::TYPE_VALUE) - undo_redo->add_do_method(animation.ptr(),"value_track_set_continuous",p_id.track_idx,continuous); + undo_redo->add_do_method(animation.ptr(),"value_track_set_update_mode",p_id.track_idx,update_mode); } else { undo_redo->create_action(TTR("Anim Insert Key")); @@ -3536,7 +3744,7 @@ void AnimationKeyEditor::_insert_delay() { pos=animation->get_length(); timeline_pos=pos; track_pos->update(); - emit_signal("timeline_changed",pos); + emit_signal("timeline_changed",pos,true); } insert_queue=false; } @@ -3582,7 +3790,7 @@ void AnimationKeyEditor::_scale() { } - float s = scale->get_val(); + float s = scale->get_value(); if (s==0) { ERR_PRINT("Can't scale to 0"); } @@ -3713,53 +3921,53 @@ void AnimationKeyEditor::cleanup() { void AnimationKeyEditor::_bind_methods() { - ObjectTypeDB::bind_method(_MD("_root_removed"),&AnimationKeyEditor::_root_removed); - ObjectTypeDB::bind_method(_MD("_scale"),&AnimationKeyEditor::_scale); - ObjectTypeDB::bind_method(_MD("set_root"),&AnimationKeyEditor::set_root); + ClassDB::bind_method(_MD("_root_removed"),&AnimationKeyEditor::_root_removed); + ClassDB::bind_method(_MD("_scale"),&AnimationKeyEditor::_scale); + ClassDB::bind_method(_MD("set_root"),&AnimationKeyEditor::set_root); -// ObjectTypeDB::bind_method(_MD("_confirm_insert"),&AnimationKeyEditor::_confirm_insert); - ObjectTypeDB::bind_method(_MD("_confirm_insert_list"),&AnimationKeyEditor::_confirm_insert_list); + //ClassDB::bind_method(_MD("_confirm_insert"),&AnimationKeyEditor::_confirm_insert); + ClassDB::bind_method(_MD("_confirm_insert_list"),&AnimationKeyEditor::_confirm_insert_list); - ObjectTypeDB::bind_method(_MD("_update_paths"),&AnimationKeyEditor::_update_paths); - ObjectTypeDB::bind_method(_MD("_track_editor_draw"),&AnimationKeyEditor::_track_editor_draw); + ClassDB::bind_method(_MD("_update_paths"),&AnimationKeyEditor::_update_paths); + ClassDB::bind_method(_MD("_track_editor_draw"),&AnimationKeyEditor::_track_editor_draw); - ObjectTypeDB::bind_method(_MD("_animation_changed"),&AnimationKeyEditor::_animation_changed); - ObjectTypeDB::bind_method(_MD("_scroll_changed"),&AnimationKeyEditor::_scroll_changed); - ObjectTypeDB::bind_method(_MD("_track_editor_input_event"),&AnimationKeyEditor::_track_editor_input_event); - ObjectTypeDB::bind_method(_MD("_track_name_changed"),&AnimationKeyEditor::_track_name_changed); - ObjectTypeDB::bind_method(_MD("_track_menu_selected"),&AnimationKeyEditor::_track_menu_selected); - ObjectTypeDB::bind_method(_MD("_menu_add_track"),&AnimationKeyEditor::_menu_add_track); - ObjectTypeDB::bind_method(_MD("_menu_track"),&AnimationKeyEditor::_menu_track); - ObjectTypeDB::bind_method(_MD("_clear_selection_for_anim"),&AnimationKeyEditor::_clear_selection_for_anim); - ObjectTypeDB::bind_method(_MD("_select_at_anim"),&AnimationKeyEditor::_select_at_anim); - ObjectTypeDB::bind_method(_MD("_track_pos_draw"),&AnimationKeyEditor::_track_pos_draw); - ObjectTypeDB::bind_method(_MD("_insert_delay"),&AnimationKeyEditor::_insert_delay); - ObjectTypeDB::bind_method(_MD("_step_changed"),&AnimationKeyEditor::_step_changed); + ClassDB::bind_method(_MD("_animation_changed"),&AnimationKeyEditor::_animation_changed); + ClassDB::bind_method(_MD("_scroll_changed"),&AnimationKeyEditor::_scroll_changed); + ClassDB::bind_method(_MD("_track_editor_gui_input"),&AnimationKeyEditor::_track_editor_gui_input); + ClassDB::bind_method(_MD("_track_name_changed"),&AnimationKeyEditor::_track_name_changed); + ClassDB::bind_method(_MD("_track_menu_selected"),&AnimationKeyEditor::_track_menu_selected); + ClassDB::bind_method(_MD("_menu_add_track"),&AnimationKeyEditor::_menu_add_track); + ClassDB::bind_method(_MD("_menu_track"),&AnimationKeyEditor::_menu_track); + ClassDB::bind_method(_MD("_clear_selection_for_anim"),&AnimationKeyEditor::_clear_selection_for_anim); + ClassDB::bind_method(_MD("_select_at_anim"),&AnimationKeyEditor::_select_at_anim); + ClassDB::bind_method(_MD("_track_pos_draw"),&AnimationKeyEditor::_track_pos_draw); + ClassDB::bind_method(_MD("_insert_delay"),&AnimationKeyEditor::_insert_delay); + ClassDB::bind_method(_MD("_step_changed"),&AnimationKeyEditor::_step_changed); - ObjectTypeDB::bind_method(_MD("_animation_loop_changed"),&AnimationKeyEditor::_animation_loop_changed); - ObjectTypeDB::bind_method(_MD("_animation_len_changed"),&AnimationKeyEditor::_animation_len_changed); - ObjectTypeDB::bind_method(_MD("_create_value_item"),&AnimationKeyEditor::_create_value_item); - ObjectTypeDB::bind_method(_MD("_pane_drag"),&AnimationKeyEditor::_pane_drag); + ClassDB::bind_method(_MD("_animation_loop_changed"),&AnimationKeyEditor::_animation_loop_changed); + ClassDB::bind_method(_MD("_animation_len_changed"),&AnimationKeyEditor::_animation_len_changed); + ClassDB::bind_method(_MD("_create_value_item"),&AnimationKeyEditor::_create_value_item); + ClassDB::bind_method(_MD("_pane_drag"),&AnimationKeyEditor::_pane_drag); - ObjectTypeDB::bind_method(_MD("_animation_len_update"),&AnimationKeyEditor::_animation_len_update); + ClassDB::bind_method(_MD("_animation_len_update"),&AnimationKeyEditor::_animation_len_update); - ObjectTypeDB::bind_method(_MD("set_animation"),&AnimationKeyEditor::set_animation); - 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); - ObjectTypeDB::bind_method(_MD("_add_call_track"),&AnimationKeyEditor::_add_call_track); + ClassDB::bind_method(_MD("set_animation"),&AnimationKeyEditor::set_animation); + ClassDB::bind_method(_MD("_animation_optimize"),&AnimationKeyEditor::_animation_optimize); + ClassDB::bind_method(_MD("_curve_transition_changed"),&AnimationKeyEditor::_curve_transition_changed); + ClassDB::bind_method(_MD("_toggle_edit_curves"),&AnimationKeyEditor::_toggle_edit_curves); + ClassDB::bind_method(_MD("_add_call_track"),&AnimationKeyEditor::_add_call_track); ADD_SIGNAL( MethodInfo("resource_selected", PropertyInfo( Variant::OBJECT, "res"),PropertyInfo( Variant::STRING, "prop") ) ); ADD_SIGNAL( MethodInfo("keying_changed" ) ); - ADD_SIGNAL( MethodInfo("timeline_changed", PropertyInfo(Variant::REAL,"pos") ) ); + ADD_SIGNAL( MethodInfo("timeline_changed", PropertyInfo(Variant::REAL,"pos"), PropertyInfo(Variant::BOOL,"drag") ) ); ADD_SIGNAL( MethodInfo("animation_len_changed", PropertyInfo(Variant::REAL,"len") ) ); ADD_SIGNAL( MethodInfo("animation_step_changed", PropertyInfo(Variant::REAL,"step") ) ); ADD_SIGNAL( MethodInfo("key_edited", PropertyInfo(Variant::INT,"track"), PropertyInfo(Variant::INT,"key") ) ); @@ -3786,7 +3994,7 @@ AnimationKeyEditor::AnimationKeyEditor() { h_scroll = memnew( HScrollBar ); h_scroll->connect("value_changed",this,"_scroll_changed"); add_child(h_scroll); - h_scroll->set_val(0); + h_scroll->set_value(0); HBoxContainer *hb = memnew( HBoxContainer ); @@ -3799,7 +4007,7 @@ AnimationKeyEditor::AnimationKeyEditor() { //menu->set_pos(Point2()); //add_child(menu); - zoomicon = memnew( TextureFrame ); + zoomicon = memnew( TextureRect ); hb->add_child(zoomicon); zoomicon->set_tooltip(TTR("Animation zoom.")); @@ -3808,7 +4016,7 @@ AnimationKeyEditor::AnimationKeyEditor() { zoom->set_step(0.01); zoom->set_min(0.0); zoom->set_max(2.0); - zoom->set_val(1.0); + zoom->set_value(1.0); zoom->set_h_size_flags(SIZE_EXPAND_FILL); zoom->set_stretch_ratio(2); hb->add_child(zoom); @@ -3840,7 +4048,7 @@ AnimationKeyEditor::AnimationKeyEditor() { step->set_min(0.00); step->set_max(128); step->set_step(0.01); - step->set_val(0.0); + step->set_value(0.0); step->set_h_size_flags(SIZE_EXPAND_FILL); step->set_stretch_ratio(1); step->set_tooltip(TTR("Cursor step snap (in seconds).")); @@ -3858,7 +4066,7 @@ AnimationKeyEditor::AnimationKeyEditor() { menu_add_track = memnew( MenuButton ); hb->add_child(menu_add_track); - menu_add_track->get_popup()->connect("item_pressed",this,"_menu_add_track"); + menu_add_track->get_popup()->connect("id_pressed",this,"_menu_add_track"); menu_add_track->set_tooltip(TTR("Add new tracks.")); move_up_button = memnew( ToolButton ); @@ -3886,7 +4094,7 @@ AnimationKeyEditor::AnimationKeyEditor() { menu_track = memnew( MenuButton ); hb->add_child(menu_track); - menu_track->get_popup()->connect("item_pressed",this,"_menu_track"); + menu_track->get_popup()->connect("id_pressed",this,"_menu_track"); menu_track->set_tooltip(TTR("Track tools")); edit_button = memnew( ToolButton ); @@ -3902,18 +4110,18 @@ AnimationKeyEditor::AnimationKeyEditor() { optimize_dialog->set_title(TTR("Anim. Optimizer")); VBoxContainer *optimize_vb = memnew( VBoxContainer ); optimize_dialog->add_child(optimize_vb); - optimize_dialog->set_child_rect(optimize_vb); + optimize_linear_error = memnew( SpinBox ); optimize_linear_error->set_max(1.0); optimize_linear_error->set_min(0.001); optimize_linear_error->set_step(0.001); - optimize_linear_error->set_val(0.05); + optimize_linear_error->set_value(0.05); optimize_vb->add_margin_child(TTR("Max. Linear Error:"),optimize_linear_error); optimize_angular_error = memnew( SpinBox ); optimize_angular_error->set_max(1.0); optimize_angular_error->set_min(0.001); optimize_angular_error->set_step(0.001); - optimize_angular_error->set_val(0.01); + optimize_angular_error->set_value(0.01); optimize_vb->add_margin_child(TTR("Max. Angular Error:"),optimize_angular_error); optimize_max_angle = memnew( SpinBox ); @@ -3921,7 +4129,7 @@ AnimationKeyEditor::AnimationKeyEditor() { optimize_max_angle->set_max(360.0); optimize_max_angle->set_min(0.0); optimize_max_angle->set_step(0.1); - optimize_max_angle->set_val(22); + optimize_max_angle->set_value(22); optimize_dialog->get_ok()->set_text(TTR("Optimize")); @@ -3941,9 +4149,9 @@ AnimationKeyEditor::AnimationKeyEditor() { /* l = memnew( Label ); l->set_text("Base: "); l->set_pos(Point2(0,3)); -// dr_panel->add_child(l);*/ + //dr_panel->add_child(l);*/ -// menu->get_popup()->connect("item_pressed",this,"_menu_callback"); + //menu->get_popup()->connect("id_pressed",this,"_menu_callback"); hb = memnew( HBoxContainer); @@ -3954,22 +4162,32 @@ AnimationKeyEditor::AnimationKeyEditor() { track_editor = memnew( Control ); track_editor->connect("draw",this,"_track_editor_draw"); hb->add_child(track_editor); - track_editor->connect("input_event",this,"_track_editor_input_event"); + track_editor->connect("gui_input",this,"_track_editor_gui_input"); track_editor->set_focus_mode(Control::FOCUS_ALL); track_editor->set_h_size_flags(SIZE_EXPAND_FILL); + track_pos = memnew( Control ); track_pos->set_area_as_parent_rect(); - track_pos->set_ignore_mouse(true); + track_pos->set_mouse_filter(MOUSE_FILTER_IGNORE); track_editor->add_child(track_pos); track_pos->connect("draw",this,"_track_pos_draw"); + select_anim_warning = memnew( Label ); + track_editor->add_child(select_anim_warning); + select_anim_warning->set_area_as_parent_rect(); + select_anim_warning->set_text(TTR("Select an AnimationPlayer from the Scene Tree to edit animations.")); + select_anim_warning->set_autowrap(true); + select_anim_warning->set_align(Label::ALIGN_CENTER); + select_anim_warning->set_valign(Label::VALIGN_CENTER); + + v_scroll = memnew( VScrollBar ); hb->add_child(v_scroll); v_scroll->connect("value_changed",this,"_scroll_changed"); - v_scroll->set_val(0); + v_scroll->set_value(0); key_editor_tab = memnew(TabContainer); hb->add_child(key_editor_tab); @@ -3989,7 +4207,7 @@ AnimationKeyEditor::AnimationKeyEditor() { 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"); + type_menu->connect("id_pressed",this,"_create_value_item"); VBoxContainer *curve_vb = memnew( VBoxContainer ); curve_vb->set_name(TTR("Transition")); @@ -4028,7 +4246,7 @@ AnimationKeyEditor::AnimationKeyEditor() { track_name->connect("text_entered",this,"_track_name_changed"); track_menu = memnew( PopupMenu ); add_child(track_menu); - track_menu->connect("item_pressed",this,"_track_menu_selected"); + track_menu->connect("id_pressed",this,"_track_menu_selected"); key_editor_tab->hide(); @@ -4060,7 +4278,7 @@ AnimationKeyEditor::AnimationKeyEditor() { scale_dialog = memnew( ConfirmationDialog ); VBoxContainer *vbc = memnew( VBoxContainer ); scale_dialog->add_child(vbc); - scale_dialog->set_child_rect(vbc); + scale = memnew( SpinBox ); scale->set_min(-99999); scale->set_max(99999); @@ -4077,7 +4295,7 @@ AnimationKeyEditor::AnimationKeyEditor() { add_child(cleanup_dialog); VBoxContainer *cleanup_vb = memnew( VBoxContainer ); cleanup_dialog->add_child(cleanup_vb); - cleanup_dialog->set_child_rect(cleanup_vb); + cleanup_keys = memnew( CheckButton ); cleanup_keys->set_text(TTR("Remove invalid keys")); cleanup_keys->set_pressed(true); @@ -4099,6 +4317,7 @@ AnimationKeyEditor::AnimationKeyEditor() { add_constant_override("separation",get_constant("separation","VBoxContainer")); + track_editor->set_clip_contents(true); } |