diff options
Diffstat (limited to 'editor/animation_editor.cpp')
-rw-r--r-- | editor/animation_editor.cpp | 1615 |
1 files changed, 813 insertions, 802 deletions
diff --git a/editor/animation_editor.cpp b/editor/animation_editor.cpp index 63ed27e60c..1798e66e8a 100644 --- a/editor/animation_editor.cpp +++ b/editor/animation_editor.cpp @@ -76,7 +76,7 @@ private: Ref<StyleBox> sb = get_stylebox("normal", "LineEdit"); sb->draw(ci, r); r.size -= sb->get_minimum_size(); - r.pos += sb->get_offset(); + r.position += sb->get_offset(); //VisualServer::get_singleton()->canvas_item_add Ref<Font> f = get_font("font", "Label"); @@ -111,7 +111,7 @@ private: 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); + VisualServer::get_singleton()->canvas_item_add_line(ci, r.position + Point2(iflp * r.size.width, prev * r.size.height), r.position + Point2(ifl * r.size.width, h * r.size.height), mcolor); prev = h; } @@ -138,7 +138,7 @@ private: 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); + VisualServer::get_singleton()->canvas_item_add_line(ci, r.position + Point2(iflp * r.size.width, prev * r.size.height), r.position + Point2(ifl * r.size.width, h * r.size.height), color); prev = h; } } @@ -154,13 +154,15 @@ private: } } - void _gui_input(const InputEvent &p_ev) { - if (p_ev.type == InputEvent::MOUSE_MOTION && p_ev.mouse_motion.button_mask & BUTTON_MASK_LEFT) { + void _gui_input(const Ref<InputEvent> &p_ev) { + + Ref<InputEventMouseMotion> mm = p_ev; + if (mm.is_valid() && mm->get_button_mask() & BUTTON_MASK_LEFT) { if (mode == MODE_DISABLED) return; - float rel = p_ev.mouse_motion.relative_x; + float rel = mm->get_relative().x; if (rel == 0) return; @@ -1035,7 +1037,7 @@ void AnimationKeyEditor::_track_pos_draw() { //draw position 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), get_color("animation_editor_track_pos", "Editor")); + track_pos->draw_line(ofs + Point2(pixel, 0), ofs + Point2(pixel, size.height), get_color("highlight_color", "Editor")); } } @@ -1089,12 +1091,12 @@ void AnimationKeyEditor::_track_editor_draw() { 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", "Editor"); - Color timecolor = get_color("animation_editor_time", "Editor"); + Color sepcolor = get_color("light_color_1", "Editor"); + Color timecolor = get_color("dark_color_2", "Editor"); Color hover_color = Color(1, 1, 1, 0.05); Color select_color = Color(1, 1, 1, 0.1); Color invalid_path_color = Color(1, 0.6, 0.4, 0.5); - Color track_select_color = Color::html("ffbd8e8e"); + Color track_select_color = get_color("highlight_color", "Editor"); Ref<Texture> remove_icon = get_icon("Remove", "EditorIcons"); Ref<Texture> move_up_icon = get_icon("MoveUp", "EditorIcons"); @@ -1154,9 +1156,8 @@ void AnimationKeyEditor::_track_editor_draw() { int settings_limit = size.width - right_separator_ofs; int name_limit = settings_limit * name_column_ratio; - Color line_color = get_color("animation_editor_line", "Editor"); - te->draw_line(ofs + Point2(name_limit, 0), ofs + Point2(name_limit, size.height), line_color); - te->draw_line(ofs + Point2(settings_limit, 0), ofs + Point2(settings_limit, size.height), line_color); + te->draw_line(ofs + Point2(name_limit, 0), ofs + Point2(name_limit, size.height), color); + te->draw_line(ofs + Point2(settings_limit, 0), ofs + Point2(settings_limit, size.height), color); te->draw_texture(hsize_icon, ofs + Point2(name_limit - hsize_icon->get_width() - hsep, (h - hsize_icon->get_height()) / 2)); te->draw_line(ofs + Point2(0, h), ofs + Point2(size.width, h), color); @@ -1179,11 +1180,7 @@ void AnimationKeyEditor::_track_editor_draw() { 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; - notimecol.b = notimecol.r; - notimecol.a = timecolor.a; + Color notimecol = get_color("light_color_1", "Editor"); { @@ -1483,7 +1480,9 @@ void AnimationKeyEditor::_track_editor_draw() { switch (click.click) { case ClickOver::CLICK_SELECT_KEYS: { - te->draw_rect(Rect2(click.at, click.to - click.at), get_color("animation_editor_selection_rect", "Editor")); + Color box_color = get_color("highlight_color", "Editor"); + box_color.a = 0.35; + te->draw_rect(Rect2(click.at, click.to - click.at), box_color); } break; case ClickOver::CLICK_MOVE_KEYS: { @@ -1749,7 +1748,7 @@ void AnimationKeyEditor::_anim_delete_keys() { } } -void AnimationKeyEditor::_track_editor_gui_input(const InputEvent &p_input) { +void AnimationKeyEditor::_track_editor_gui_input(const Ref<InputEvent> &p_input) { Control *te = track_editor; Ref<StyleBox> style = get_stylebox("normal", "TextEdit"); @@ -1807,1073 +1806,1083 @@ void AnimationKeyEditor::_track_editor_gui_input(const InputEvent &p_input) { int settings_limit = size.width - right_separator_ofs; int name_limit = settings_limit * name_column_ratio; - switch (p_input.type) { + Ref<InputEventKey> key = p_input; + if (key.is_valid()) { - case InputEvent::KEY: { + if (key->get_scancode() == KEY_D && key->is_pressed() && key->get_command()) { - if (p_input.key.scancode == KEY_D && p_input.key.pressed && p_input.key.mod.command) { + if (key->get_shift()) + _menu_track(TRACK_MENU_DUPLICATE_TRANSPOSE); + else + _menu_track(TRACK_MENU_DUPLICATE); - if (p_input.key.mod.shift) - _menu_track(TRACK_MENU_DUPLICATE_TRANSPOSE); - else - _menu_track(TRACK_MENU_DUPLICATE); + accept_event(); - accept_event(); + } else if (key->get_scancode() == KEY_DELETE && key->is_pressed() && click.click == ClickOver::CLICK_NONE) { - } else if (p_input.key.scancode == KEY_DELETE && p_input.key.pressed && click.click == ClickOver::CLICK_NONE) { + _anim_delete_keys(); + } else if (animation.is_valid() && animation->get_track_count() > 0) { - _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 (key->is_pressed() && (key->is_action("ui_up") || key->is_action("ui_page_up"))) { - if (p_input.is_action("ui_up")) - selected_track--; - if (v_scroll->is_visible_in_tree() && p_input.is_action("ui_page_up")) - selected_track--; + if (key->is_action("ui_up")) + selected_track--; + if (v_scroll->is_visible_in_tree() && key->is_action("ui_page_up")) + selected_track--; - if (selected_track < 0) - selected_track = 0; + if (selected_track < 0) + selected_track = 0; - if (v_scroll->is_visible_in_tree()) { - if (v_scroll->get_value() > selected_track) - v_scroll->set_value(selected_track); - } - - track_editor->update(); - accept_event(); + if (v_scroll->is_visible_in_tree()) { + if (v_scroll->get_value() > selected_track) + v_scroll->set_value(selected_track); } - if (p_input.is_pressed() && (p_input.is_action("ui_down") || p_input.is_action("ui_page_down"))) { + track_editor->update(); + accept_event(); + } - if (p_input.is_action("ui_down")) - selected_track++; - else if (v_scroll->is_visible_in_tree() && p_input.is_action("ui_page_down")) - selected_track += v_scroll->get_page(); + if (key->is_pressed() && (key->is_action("ui_down") || key->is_action("ui_page_down"))) { - if (selected_track >= animation->get_track_count()) - selected_track = animation->get_track_count() - 1; + if (key->is_action("ui_down")) + selected_track++; + else if (v_scroll->is_visible_in_tree() && key->is_action("ui_page_down")) + selected_track += v_scroll->get_page(); - 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); - } + if (selected_track >= animation->get_track_count()) + selected_track = animation->get_track_count() - 1; - track_editor->update(); - accept_event(); + 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(); + accept_event(); } + } + } - } break; - case InputEvent::MOUSE_BUTTON: { + Ref<InputEventMouseButton> mb = p_input; - const InputEventMouseButton &mb = p_input.mouse_button; + if (mb.is_valid()) { - if (mb.button_index == BUTTON_WHEEL_UP && mb.pressed) { + if (mb->get_button_index() == BUTTON_WHEEL_UP && mb->is_pressed()) { - 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->get_command()) { - if (mb.button_index == BUTTON_WHEEL_DOWN && mb.pressed) { + zoom->set_value(zoom->get_value() + zoom->get_step()); + } else { - 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); - } + v_scroll->set_value(v_scroll->get_value() - v_scroll->get_page() * mb->get_factor() / 8); } + } - if (mb.button_index == BUTTON_RIGHT && mb.pressed) { + if (mb->get_button_index() == BUTTON_WHEEL_DOWN && mb->is_pressed()) { - Point2 mpos = Point2(mb.x, mb.y) - ofs; + if (mb->get_command()) { - 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; + zoom->set_value(zoom->get_value() - zoom->get_step()); + } else { - if (mpos.y < h) { - return; - } + v_scroll->set_value(v_scroll->get_value() + v_scroll->get_page() * mb->get_factor() / 8); + } + } - mpos.y -= h; + if (mb->get_button_index() == BUTTON_WHEEL_RIGHT && mb->is_pressed()) { - int idx = mpos.y / h; - idx += v_scroll->get_value(); - if (idx < 0 || idx >= animation->get_track_count()) - break; + h_scroll->set_value(h_scroll->get_value() - h_scroll->get_page() * mb->get_factor() / 8); + } - 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; + if (mb->get_button_index() == BUTTON_WHEEL_LEFT && mb->is_pressed()) { - int kidx = animation->track_find_key(idx, pos); - int kidx_n = kidx + 1; - int key = -1; + v_scroll->set_value(v_scroll->get_value() + v_scroll->get_page() * mb->get_factor() / 8); + } - if (kidx >= 0 && kidx < animation->track_get_key_count(idx)) { + if (mb->get_button_index() == BUTTON_RIGHT && mb->is_pressed()) { - float kpos = animation->track_get_key_time(idx, kidx); - if (ABS(pos - kpos) <= w_time) { + Point2 mpos = mb->get_position() - ofs; - key = kidx; - } - } + 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 = mb->get_position() - ofs; - if (key == -1 && kidx_n >= 0 && kidx_n < animation->track_get_key_count(idx)) { + if (mpos.y < h) { + return; + } - float kpos = animation->track_get_key_time(idx, kidx_n); - if (ABS(pos - kpos) <= w_time) { + mpos.y -= h; - key = kidx_n; - } - } + int idx = mpos.y / h; + idx += v_scroll->get_value(); + if (idx < 0 || idx >= animation->get_track_count()) + return; - if (key == -1) { + 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; - 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; + 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; } + } - 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 (key == -1 && kidx_n >= 0 && kidx_n < animation->track_get_key_count(idx)) { - if (!mb.mod.shift && !selection.has(sk)) - _clear_selection(); + float kpos = animation->track_get_key_time(idx, kidx_n); + if (ABS(pos - kpos) <= w_time) { + + key = kidx_n; + } + } - selection.insert(sk, ki); + if (key == -1) { - click.click = ClickOver::CLICK_MOVE_KEYS; - click.at = Point2(mb.x, mb.y); + click.click = ClickOver::CLICK_SELECT_KEYS; + click.at = mb->get_position(); click.to = click.at; - update(); + click.shift = mb->get_shift(); selected_track = idx; track_editor->update(); - - if (_edit_if_single_selection() && mb.mod.command) { - edit_button->set_pressed(true); - key_editor_tab->show(); - } + //drag select region + return; } - } - 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); + SelectedKey sk; + sk.track = idx; + sk.key = key; + KeyInfo ki; + ki.pos = animation->track_get_key_time(idx, key); + click.shift = mb->get_shift(); + click.selk = sk; - track_menu->set_position(te->get_global_position() + mpos); + if (!mb->get_shift() && !selection.has(sk)) + _clear_selection(); - interp_editing = -1; - cont_editing = -1; - wrap_editing = -1; + selection.insert(sk, ki); - track_menu->popup(); + click.click = ClickOver::CLICK_MOVE_KEYS; + click.at = mb->get_position(); + click.to = click.at; + update(); + selected_track = idx; + track_editor->update(); + + if (_edit_if_single_selection() && mb->get_command()) { + edit_button->set_pressed(true); + key_editor_tab->show(); + } } } - if (mb.button_index == BUTTON_LEFT && !(mb.button_mask & ~BUTTON_MASK_LEFT)) { + 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); - if (mb.pressed) { + track_menu->set_position(te->get_global_position() + mpos); - Point2 mpos = Point2(mb.x, mb.y) - ofs; + interp_editing = -1; + cont_editing = -1; + wrap_editing = -1; - if (mpos.y < h) { + track_menu->popup(); + } + } - if (mpos.x < name_limit && mpos.x > (name_limit - hsep - hsize_icon->get_width())) { + if (mb->get_button_index() == BUTTON_LEFT && !(mb->get_button_mask() & ~BUTTON_MASK_LEFT)) { - click.click = ClickOver::CLICK_RESIZE_NAMES; - click.at = Point2(mb.x, mb.y); - click.to = click.at; - click.at.y = name_limit; - } + if (mb->is_pressed()) { - if (mpos.x >= name_limit && mpos.x < settings_limit) { - //seek - //int zoomw = settings_limit-name_limit; - float scale = _get_zoom_scale(); - float pos = h_scroll->get_value() + (mpos.x - name_limit) / scale; - if (animation->get_step()) - pos = Math::stepify(pos, animation->get_step()); - - if (pos < 0) - pos = 0; - if (pos >= animation->get_length()) - pos = animation->get_length(); - timeline_pos = pos; - click.click = ClickOver::CLICK_DRAG_TIMELINE; - click.at = Point2(mb.x, mb.y); - click.to = click.at; - emit_signal("timeline_changed", pos, false); - } + Point2 mpos = mb->get_position() - ofs; - return; - } + if (mpos.y < h) { - mpos.y -= h; + if (mpos.x < name_limit && mpos.x > (name_limit - hsep - hsize_icon->get_width())) { - int idx = mpos.y / h; - idx += v_scroll->get_value(); - if (idx < 0) - break; + click.click = ClickOver::CLICK_RESIZE_NAMES; + click.at = mb->get_position(); + click.to = click.at; + click.at.y = name_limit; + } - if (idx >= animation->get_track_count()) { + if (mpos.x >= name_limit && mpos.x < settings_limit) { + //seek + //int zoomw = settings_limit-name_limit; + float scale = _get_zoom_scale(); + float pos = h_scroll->get_value() + (mpos.x - name_limit) / scale; + if (animation->get_step()) + pos = Math::stepify(pos, animation->get_step()); - if (mpos.x >= name_limit && mpos.x < settings_limit) { + if (pos < 0) + pos = 0; + if (pos >= animation->get_length()) + pos = animation->get_length(); + timeline_pos = pos; + click.click = ClickOver::CLICK_DRAG_TIMELINE; + click.at = mb->get_position(); + click.to = click.at; + emit_signal("timeline_changed", pos, false); + } - click.click = ClickOver::CLICK_SELECT_KEYS; - click.at = Point2(mb.x, mb.y); - click.to = click.at; - //drag select region - } + return; + } - break; - } + mpos.y -= h; - if (mpos.x < name_limit) { - //name column + int idx = mpos.y / h; + idx += v_scroll->get_value(); + if (idx < 0) + return; - // area - if (idx != selected_track) { + if (idx >= animation->get_track_count()) { - selected_track = idx; - track_editor->update(); - break; - } + if (mpos.x >= name_limit && mpos.x < settings_limit) { - Rect2 area(ofs.x, ofs.y + ((int(mpos.y) / h) + 1) * h, name_limit, h); - track_name->set_text(animation->track_get_path(idx)); - track_name->set_position(te->get_global_position() + area.pos); - track_name->set_size(area.size); - track_name->show_modal(); - track_name->grab_focus(); - track_name->select_all(); - track_name_editing = idx; + click.click = ClickOver::CLICK_SELECT_KEYS; + click.at = mb->get_position(); + click.to = click.at; + //drag select region + } - } else if (mpos.x < settings_limit) { + return; + } - 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; + if (mpos.x < name_limit) { + //name column - int kidx = animation->track_find_key(idx, pos); - int kidx_n = kidx + 1; - int key = -1; + // area + if (idx != selected_track) { - if (kidx >= 0 && kidx < animation->track_get_key_count(idx)) { + selected_track = idx; + track_editor->update(); + return; + } - float kpos = animation->track_get_key_time(idx, kidx); - if (ABS(pos - kpos) <= w_time) { + Rect2 area(ofs.x, ofs.y + ((int(mpos.y) / h) + 1) * h, name_limit, h); + track_name->set_text(animation->track_get_path(idx)); + track_name->set_position(te->get_global_position() + area.position); + track_name->set_size(area.size); + track_name->show_modal(); + track_name->grab_focus(); + track_name->select_all(); + track_name_editing = idx; - key = kidx; - } - } + } else if (mpos.x < settings_limit) { - if (key == -1 && kidx_n >= 0 && kidx_n < animation->track_get_key_count(idx)) { + 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; - float kpos = animation->track_get_key_time(idx, kidx_n); - if (ABS(pos - kpos) <= w_time) { + int kidx = animation->track_find_key(idx, pos); + int kidx_n = kidx + 1; + int key = -1; - key = kidx_n; - } - } + if (kidx >= 0 && kidx < animation->track_get_key_count(idx)) { - if (key == -1) { + float kpos = animation->track_get_key_time(idx, kidx); + if (ABS(pos - kpos) <= w_time) { - 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; + key = kidx; } + } - 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 (key == -1 && kidx_n >= 0 && kidx_n < animation->track_get_key_count(idx)) { - if (!mb.mod.shift && !selection.has(sk)) - _clear_selection(); + float kpos = animation->track_get_key_time(idx, kidx_n); + if (ABS(pos - kpos) <= w_time) { - selection.insert(sk, ki); + key = kidx_n; + } + } + + if (key == -1) { - click.click = ClickOver::CLICK_MOVE_KEYS; - click.at = Point2(mb.x, mb.y); + click.click = ClickOver::CLICK_SELECT_KEYS; + click.at = mb->get_position(); click.to = click.at; - update(); + click.shift = mb->get_shift(); selected_track = idx; track_editor->update(); + //drag select region + return; + } - if (_edit_if_single_selection() && mb.mod.command) { - edit_button->set_pressed(true); - key_editor_tab->show(); - } - } else { - //button column - int ofsx = size.width - mpos.x; - if (ofsx < 0) - break; - /* - if (ofsx < remove_icon->get_width()) { + SelectedKey sk; + sk.track = idx; + sk.key = key; + KeyInfo ki; + ki.pos = animation->track_get_key_time(idx, key); + click.shift = mb->get_shift(); + click.selk = sk; - undo_redo->create_action("Remove Anim Track"); - undo_redo->add_do_method(animation.ptr(),"remove_track",idx); - undo_redo->add_undo_method(animation.ptr(),"add_track",animation->track_get_type(idx),idx); - undo_redo->add_undo_method(animation.ptr(),"track_set_path",idx,animation->track_get_path(idx)); - //todo interpolation - for(int i=0;i<animation->track_get_key_count(idx);i++) { + if (!mb->get_shift() && !selection.has(sk)) + _clear_selection(); - Variant v = animation->track_get_key_value(idx,i); - float time = animation->track_get_key_time(idx,i); - float trans = animation->track_get_key_transition(idx,i); + selection.insert(sk, ki); - undo_redo->add_undo_method(animation.ptr(),"track_insert_key",idx,time,v); - undo_redo->add_undo_method(animation.ptr(),"track_set_key_transition",idx,i,trans); + click.click = ClickOver::CLICK_MOVE_KEYS; + click.at = mb->get_position(); + click.to = click.at; + update(); + selected_track = idx; + track_editor->update(); - } + if (_edit_if_single_selection() && mb->get_command()) { + edit_button->set_pressed(true); + key_editor_tab->show(); + } + } else { + //button column + int ofsx = size.width - mpos.x; + if (ofsx < 0) + return; + /* + if (ofsx < remove_icon->get_width()) { - 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->create_action("Remove Anim Track"); + undo_redo->add_do_method(animation.ptr(),"remove_track",idx); + undo_redo->add_undo_method(animation.ptr(),"add_track",animation->track_get_type(idx),idx); + undo_redo->add_undo_method(animation.ptr(),"track_set_path",idx,animation->track_get_path(idx)); + //todo interpolation + for(int i=0;i<animation->track_get_key_count(idx);i++) { - } + Variant v = animation->track_get_key_value(idx,i); + float time = animation->track_get_key_time(idx,i); + float trans = animation->track_get_key_transition(idx,i); - undo_redo->commit_action(); + undo_redo->add_undo_method(animation.ptr(),"track_insert_key",idx,time,v); + undo_redo->add_undo_method(animation.ptr(),"track_set_key_transition",idx,i,trans); - - return; } - ofsx-=hsep+remove_icon->get_width(); - - if (ofsx < move_down_icon->get_width()) { + 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)); - if (idx < animation->get_track_count() -1) { - undo_redo->create_action("Move Anim Track Down"); - undo_redo->add_do_method(animation.ptr(),"track_move_up",idx); - undo_redo->add_undo_method(animation.ptr(),"track_move_down",idx+1); - undo_redo->commit_action(); - } - return; } - ofsx-=hsep+move_down_icon->get_width(); + undo_redo->commit_action(); - if (ofsx < move_up_icon->get_width()) { - if (idx >0) { - undo_redo->create_action("Move Anim Track Up"); - undo_redo->add_do_method(animation.ptr(),"track_move_down",idx); - undo_redo->add_undo_method(animation.ptr(),"track_move_up",idx-1); - undo_redo->commit_action(); - } - return; - } + return; + } + ofsx-=hsep+remove_icon->get_width(); - ofsx-=hsep*3+move_up_icon->get_width(); - */ + if (ofsx < move_down_icon->get_width()) { + + if (idx < animation->get_track_count() -1) { + undo_redo->create_action("Move Anim Track Down"); + undo_redo->add_do_method(animation.ptr(),"track_move_up",idx); + undo_redo->add_undo_method(animation.ptr(),"track_move_down",idx+1); + undo_redo->commit_action(); + } + return; + } - if (ofsx < track_ofs[1]) { + ofsx-=hsep+move_down_icon->get_width(); - 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]); - } + if (ofsx < move_up_icon->get_width()) { - int popup_y = ofs.y + ((int(mpos.y) / h) + 2) * h; - int popup_x = size.width - track_ofs[1]; + if (idx >0) { + undo_redo->create_action("Move Anim Track Up"); + undo_redo->add_do_method(animation.ptr(),"track_move_down",idx); + undo_redo->add_undo_method(animation.ptr(),"track_move_up",idx-1); + undo_redo->commit_action(); + } + return; + } - track_menu->set_position(te->get_global_position() + Point2(popup_x, popup_y)); - wrap_editing = idx; - interp_editing = -1; - cont_editing = -1; + ofsx-=hsep*3+move_up_icon->get_width(); + */ - track_menu->popup(); + if (ofsx < track_ofs[1]) { - return; + 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]); } - if (ofsx < track_ofs[2]) { + int popup_y = ofs.y + ((int(mpos.y) / h) + 2) * h; + int popup_x = size.width - track_ofs[1]; - track_menu->clear(); - track_menu->set_size(Point2(1, 1)); - static const char *interp_name[3] = { "Nearest", "Linear", "Cubic" }; - for (int i = 0; i < 3; i++) { - track_menu->add_icon_item(interp_icon[i], interp_name[i]); - } + track_menu->set_position(te->get_global_position() + Point2(popup_x, popup_y)); - int popup_y = ofs.y + ((int(mpos.y) / h) + 2) * h; - int popup_x = size.width - track_ofs[2]; + wrap_editing = idx; + interp_editing = -1; + cont_editing = -1; - track_menu->set_position(te->get_global_position() + Point2(popup_x, popup_y)); + track_menu->popup(); - interp_editing = idx; - cont_editing = -1; - wrap_editing = -1; + return; + } - track_menu->popup(); + if (ofsx < track_ofs[2]) { - return; + track_menu->clear(); + track_menu->set_size(Point2(1, 1)); + static const char *interp_name[3] = { "Nearest", "Linear", "Cubic" }; + for (int i = 0; i < 3; i++) { + track_menu->add_icon_item(interp_icon[i], interp_name[i]); } - if (ofsx < track_ofs[3]) { + int popup_y = ofs.y + ((int(mpos.y) / h) + 2) * h; + int popup_x = size.width - track_ofs[2]; - track_menu->clear(); - track_menu->set_size(Point2(1, 1)); - 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]); - } + track_menu->set_position(te->get_global_position() + Point2(popup_x, popup_y)); - int popup_y = ofs.y + ((int(mpos.y) / h) + 2) * h; - int popup_x = size.width - track_ofs[3]; + interp_editing = idx; + cont_editing = -1; + wrap_editing = -1; - track_menu->set_position(te->get_global_position() + Point2(popup_x, popup_y)); + track_menu->popup(); - interp_editing = -1; - wrap_editing = -1; - cont_editing = idx; + return; + } - track_menu->popup(); + if (ofsx < track_ofs[3]) { - return; + track_menu->clear(); + track_menu->set_size(Point2(1, 1)); + 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]); } - if (ofsx < track_ofs[4]) { + int popup_y = ofs.y + ((int(mpos.y) / h) + 2) * h; + int popup_x = size.width - track_ofs[3]; - Animation::TrackType tt = animation->track_get_type(idx); + track_menu->set_position(te->get_global_position() + Point2(popup_x, popup_y)); - float pos = timeline_pos; - int existing = animation->track_find_key(idx, pos, true); + interp_editing = -1; + wrap_editing = -1; + cont_editing = idx; - Variant newval; + track_menu->popup(); - if (tt == Animation::TYPE_TRANSFORM) { - Dictionary d; - d["loc"] = Vector3(); - d["rot"] = Quat(); - d["scale"] = Vector3(); - newval = d; + return; + } - } else if (tt == Animation::TYPE_METHOD) { + if (ofsx < track_ofs[4]) { - Dictionary d; - d["method"] = ""; - d["args"] = Vector<Variant>(); + Animation::TrackType tt = animation->track_get_type(idx); - newval = d; - } else if (tt == Animation::TYPE_VALUE) { + float pos = timeline_pos; + int existing = animation->track_find_key(idx, pos, true); - NodePath np; - PropertyInfo inf = _find_hint_for_track(idx, np); - if (inf.type != Variant::NIL) { + Variant newval; - Variant::CallError err; - newval = Variant::construct(inf.type, NULL, 0, err); - } + if (tt == Animation::TYPE_TRANSFORM) { + Dictionary d; + d["loc"] = Vector3(); + d["rot"] = Quat(); + d["scale"] = Vector3(); + newval = d; - if (newval.get_type() == Variant::NIL) { - //popup a new type - cvi_track = idx; - cvi_pos = pos; + } else if (tt == Animation::TYPE_METHOD) { - type_menu->set_position(get_global_position() + mpos + ofs); - type_menu->popup(); - return; - } - } + Dictionary d; + d["method"] = ""; + d["args"] = Vector<Variant>(); - undo_redo->create_action(TTR("Anim Add Key")); + newval = d; + } else if (tt == Animation::TYPE_VALUE) { - undo_redo->add_do_method(animation.ptr(), "track_insert_key", idx, pos, newval, 1); - undo_redo->add_undo_method(animation.ptr(), "track_remove_key_at_pos", idx, pos); + NodePath np; + PropertyInfo inf = _find_hint_for_track(idx, np); + if (inf.type != Variant::NIL) { - if (existing != -1) { - Variant v = animation->track_get_key_value(idx, existing); - float trans = animation->track_get_key_transition(idx, existing); - undo_redo->add_undo_method(animation.ptr(), "track_insert_key", idx, pos, v, trans); + Variant::CallError err; + newval = Variant::construct(inf.type, NULL, 0, err); } - undo_redo->commit_action(); + if (newval.get_type() == Variant::NIL) { + //popup a new type + cvi_track = idx; + cvi_pos = pos; - return; + type_menu->set_position(get_global_position() + mpos + ofs); + type_menu->popup(); + return; + } } - } - } else { + undo_redo->create_action(TTR("Anim Add Key")); - switch (click.click) { - case ClickOver::CLICK_SELECT_KEYS: { + undo_redo->add_do_method(animation.ptr(), "track_insert_key", idx, pos, newval, 1); + undo_redo->add_undo_method(animation.ptr(), "track_remove_key_at_pos", idx, pos); - float zoom_scale = _get_zoom_scale(); - float keys_from = h_scroll->get_value(); - float keys_to = keys_from + (settings_limit - name_limit) / zoom_scale; + if (existing != -1) { + Variant v = animation->track_get_key_value(idx, existing); + float trans = animation->track_get_key_transition(idx, existing); + undo_redo->add_undo_method(animation.ptr(), "track_insert_key", idx, pos, v, trans); + } - float from_time = keys_from + (click.at.x - (name_limit + ofs.x)) / zoom_scale; - float to_time = keys_from + (click.to.x - (name_limit + ofs.x)) / zoom_scale; + undo_redo->commit_action(); - if (to_time < from_time) - SWAP(from_time, to_time); + return; + } + } - if (from_time > keys_to || to_time < keys_from) - break; + } else { - if (from_time < keys_from) - from_time = keys_from; + switch (click.click) { + case ClickOver::CLICK_SELECT_KEYS: { - if (to_time >= keys_to) - to_time = keys_to; + float zoom_scale = _get_zoom_scale(); + float keys_from = h_scroll->get_value(); + float keys_to = keys_from + (settings_limit - name_limit) / zoom_scale; - 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; + float from_time = keys_from + (click.at.x - (name_limit + ofs.x)) / zoom_scale; + float to_time = keys_from + (click.to.x - (name_limit + ofs.x)) / zoom_scale; - if (to_track < from_track) { + if (to_time < from_time) + SWAP(from_time, to_time); - SWAP(from_track, to_track); - SWAP(from_mod, to_mod); - } + if (from_time > keys_to || to_time < keys_from) + break; - if ((from_mod > (h / 2)) && ((click.at.y - ofs.y) >= (h + sep))) { - from_track++; - } + if (from_time < keys_from) + from_time = keys_from; - if (to_mod < h / 2) { - to_track--; - } + if (to_time >= keys_to) + to_time = keys_to; - if (from_track > to_track) { - if (!click.shift) - _clear_selection(); - _edit_if_single_selection(); - break; - } + 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; + + if (to_track < from_track) { - 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; + SWAP(from_track, to_track); + SWAP(from_mod, to_mod); + } - tracks_from = 0; + if ((from_mod > (h / 2)) && ((click.at.y - ofs.y) >= (h + sep))) { + from_track++; + } + + if (to_mod < h / 2) { + to_track--; + } + + if (from_track > to_track) { + if (!click.shift) + _clear_selection(); + _edit_if_single_selection(); + break; + } + + 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; - if (to_track > tracks_to) - to_track = tracks_to; - if (from_track < tracks_from) - from_track = tracks_from; - - if (from_track > tracks_to || to_track < tracks_from) { - if (!click.shift) - _clear_selection(); - _edit_if_single_selection(); - break; - } + tracks_from = 0; + tracks_to = animation->get_track_count() - 1; + if (to_track > tracks_to) + to_track = tracks_to; + if (from_track < tracks_from) + from_track = tracks_from; + + if (from_track > tracks_to || to_track < tracks_from) { if (!click.shift) _clear_selection(); + _edit_if_single_selection(); + break; + } - int higher_track = 0x7FFFFFFF; - for (int i = from_track; i <= to_track; i++) { + if (!click.shift) + _clear_selection(); - int kc = animation->track_get_key_count(i); - for (int j = 0; j < kc; j++) { + int higher_track = 0x7FFFFFFF; + for (int i = from_track; i <= to_track; i++) { - float t = animation->track_get_key_time(i, j); - if (t < from_time) - continue; - if (t > to_time) - break; + int kc = animation->track_get_key_count(i); + for (int j = 0; j < kc; j++) { - if (i < higher_track) - higher_track = i; + float t = animation->track_get_key_time(i, j); + if (t < from_time) + continue; + if (t > to_time) + break; - SelectedKey sk; - sk.track = i; - sk.key = j; - KeyInfo ki; - ki.pos = t; - selection[sk] = ki; - } - } + if (i < higher_track) + higher_track = i; - if (higher_track != 0x7FFFFFFF) { - selected_track = higher_track; - track_editor->update(); + SelectedKey sk; + sk.track = i; + sk.key = j; + KeyInfo ki; + ki.pos = t; + selection[sk] = ki; } + } - _edit_if_single_selection(); + if (higher_track != 0x7FFFFFFF) { + selected_track = higher_track; + track_editor->update(); + } - } break; - case ClickOver::CLICK_MOVE_KEYS: { + _edit_if_single_selection(); - if (selection.empty()) - break; - if (click.at == click.to) { + } break; + case ClickOver::CLICK_MOVE_KEYS: { - if (!click.shift) { + if (selection.empty()) + break; + if (click.at == click.to) { - KeyInfo ki = selection[click.selk]; - _clear_selection(); - selection[click.selk] = ki; - _edit_if_single_selection(); - } + if (!click.shift) { - break; + KeyInfo ki = selection[click.selk]; + _clear_selection(); + selection[click.selk] = ki; + _edit_if_single_selection(); } - float from_t = 1e20; + break; + } - for (Map<SelectedKey, KeyInfo>::Element *E = selection.front(); E; E = E->next()) { - float t = animation->track_get_key_time(E->key().track, E->key().key); - if (t < from_t) - from_t = t; - } + float from_t = 1e20; - float motion = from_t + (click.to.x - click.at.x) / _get_zoom_scale(); - if (step->get_value()) - motion = Math::stepify(motion, step->get_value()); + for (Map<SelectedKey, KeyInfo>::Element *E = selection.front(); E; E = E->next()) { + float t = animation->track_get_key_time(E->key().track, E->key().key); + if (t < from_t) + from_t = t; + } - undo_redo->create_action(TTR("Anim Move Keys")); + float motion = from_t + (click.to.x - click.at.x) / _get_zoom_scale(); + if (step->get_value()) + motion = Math::stepify(motion, step->get_value()); - List<_AnimMoveRestore> to_restore; + undo_redo->create_action(TTR("Anim Move Keys")); - // 1-remove the keys - for (Map<SelectedKey, KeyInfo>::Element *E = selection.back(); E; E = E->prev()) { + List<_AnimMoveRestore> to_restore; - undo_redo->add_do_method(animation.ptr(), "track_remove_key", E->key().track, E->key().key); - } - // 2- remove overlapped keys - for (Map<SelectedKey, KeyInfo>::Element *E = selection.back(); E; E = E->prev()) { + // 1-remove the keys + for (Map<SelectedKey, KeyInfo>::Element *E = selection.back(); E; E = E->prev()) { - float newtime = E->get().pos - from_t + motion; - int idx = animation->track_find_key(E->key().track, newtime, true); - if (idx == -1) - continue; - SelectedKey sk; - sk.key = idx; - sk.track = E->key().track; - if (selection.has(sk)) - continue; //already in selection, don't save + undo_redo->add_do_method(animation.ptr(), "track_remove_key", E->key().track, E->key().key); + } + // 2- remove overlapped keys + for (Map<SelectedKey, KeyInfo>::Element *E = selection.back(); E; E = E->prev()) { + + float newtime = E->get().pos - from_t + motion; + int idx = animation->track_find_key(E->key().track, newtime, true); + if (idx == -1) + continue; + SelectedKey sk; + sk.key = idx; + sk.track = E->key().track; + if (selection.has(sk)) + continue; //already in selection, don't save + + undo_redo->add_do_method(animation.ptr(), "track_remove_key_at_pos", E->key().track, newtime); + _AnimMoveRestore amr; + + amr.key = animation->track_get_key_value(E->key().track, idx); + amr.track = E->key().track; + amr.time = newtime; + amr.transition = animation->track_get_key_transition(E->key().track, idx); + + to_restore.push_back(amr); + } - undo_redo->add_do_method(animation.ptr(), "track_remove_key_at_pos", E->key().track, newtime); - _AnimMoveRestore amr; + // 3-move the keys (re insert them) + for (Map<SelectedKey, KeyInfo>::Element *E = selection.back(); E; E = E->prev()) { - amr.key = animation->track_get_key_value(E->key().track, idx); - amr.track = E->key().track; - amr.time = newtime; - amr.transition = animation->track_get_key_transition(E->key().track, idx); + float newpos = E->get().pos - from_t + motion; + /* + if (newpos<0) + continue; //no add at the beginning + */ + 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)); + } - to_restore.push_back(amr); - } + // 4-(undo) remove inserted keys + for (Map<SelectedKey, KeyInfo>::Element *E = selection.back(); E; E = E->prev()) { - // 3-move the keys (re insert them) - 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 + */ + undo_redo->add_undo_method(animation.ptr(), "track_remove_key_at_pos", E->key().track, newpos); + } - float newpos = E->get().pos - from_t + motion; - /* - if (newpos<0) - continue; //no add at the beginning - */ - 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)); - } + // 5-(undo) reinsert keys + for (Map<SelectedKey, KeyInfo>::Element *E = selection.back(); E; E = E->prev()) { - // 4-(undo) remove inserted keys - for (Map<SelectedKey, KeyInfo>::Element *E = selection.back(); E; E = E->prev()) { + 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)); + } - float newpos = E->get().pos + -from_t + motion; - /* - 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); - } + // 6-(undo) reinsert overlapped keys + for (List<_AnimMoveRestore>::Element *E = to_restore.front(); E; E = E->next()) { - // 5-(undo) reinsert keys - for (Map<SelectedKey, KeyInfo>::Element *E = selection.back(); E; E = E->prev()) { + _AnimMoveRestore &amr = E->get(); + undo_redo->add_undo_method(animation.ptr(), "track_insert_key", amr.track, amr.time, amr.key, amr.transition); + } - 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)); - } + // 6-(undo) reinsert overlapped keys + for (List<_AnimMoveRestore>::Element *E = to_restore.front(); E; E = E->next()) { - // 6-(undo) reinsert overlapped keys - for (List<_AnimMoveRestore>::Element *E = to_restore.front(); E; E = E->next()) { + _AnimMoveRestore &amr = E->get(); + undo_redo->add_undo_method(animation.ptr(), "track_insert_key", amr.track, amr.time, amr.key, amr.transition); + } - _AnimMoveRestore &amr = E->get(); - undo_redo->add_undo_method(animation.ptr(), "track_insert_key", amr.track, amr.time, amr.key, amr.transition); - } + undo_redo->add_do_method(this, "_clear_selection_for_anim", animation); + undo_redo->add_undo_method(this, "_clear_selection_for_anim", animation); - // 6-(undo) reinsert overlapped keys - for (List<_AnimMoveRestore>::Element *E = to_restore.front(); E; E = E->next()) { + // 7-reselect - _AnimMoveRestore &amr = E->get(); - undo_redo->add_undo_method(animation.ptr(), "track_insert_key", amr.track, amr.time, amr.key, amr.transition); - } + for (Map<SelectedKey, KeyInfo>::Element *E = selection.back(); E; E = E->prev()) { - undo_redo->add_do_method(this, "_clear_selection_for_anim", animation); - undo_redo->add_undo_method(this, "_clear_selection_for_anim", animation); + 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_undo_method(this, "_select_at_anim", animation, E->key().track, oldpos); + } - // 7-reselect + undo_redo->commit_action(); + _edit_if_single_selection(); - for (Map<SelectedKey, KeyInfo>::Element *E = selection.back(); E; E = E->prev()) { + } break; + default: {} + } - 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_undo_method(this, "_select_at_anim", animation, E->key().track, oldpos); - } + //button released + click.click = ClickOver::CLICK_NONE; + track_editor->update(); + } + } + } - undo_redo->commit_action(); - _edit_if_single_selection(); + Ref<InputEventMouseMotion> mm = p_input; - } break; - default: {} - } + if (mm.is_valid()) { - //button released - click.click = ClickOver::CLICK_NONE; - track_editor->update(); - } - } + mouse_over.over = MouseOver::OVER_NONE; + mouse_over.track = -1; + te->update(); + track_editor->set_tooltip(""); - } break; + if (!track_editor->has_focus() && (!get_focus_owner() || !get_focus_owner()->is_text_field())) + track_editor->call_deferred("grab_focus"); - case InputEvent::MOUSE_MOTION: { + if (click.click != ClickOver::CLICK_NONE) { - const InputEventMouseMotion &mb = p_input.mouse_motion; + switch (click.click) { + case ClickOver::CLICK_RESIZE_NAMES: { - mouse_over.over = MouseOver::OVER_NONE; - mouse_over.track = -1; - te->update(); - track_editor->set_tooltip(""); + float base = click.at.y; + float clickp = click.at.x - ofs.x; + float dif = base - clickp; - if (!track_editor->has_focus() && (!get_focus_owner() || !get_focus_owner()->is_text_field())) - track_editor->call_deferred("grab_focus"); + float target = mm->get_position().x + dif - ofs.x; - if (click.click != ClickOver::CLICK_NONE) { + float ratio = target / settings_limit; - switch (click.click) { - case ClickOver::CLICK_RESIZE_NAMES: { + if (ratio > 0.9) + ratio = 0.9; + else if (ratio < 0.2) + ratio = 0.2; - float base = click.at.y; - float clickp = click.at.x - ofs.x; - float dif = base - clickp; + name_column_ratio = ratio; - float target = mb.x + dif - ofs.x; + } break; + case ClickOver::CLICK_DRAG_TIMELINE: { - float ratio = target / settings_limit; + Point2 mpos = mm->get_position() - ofs; + /* + if (mpos.x<name_limit) + mpos.x=name_limit; + if (mpos.x>settings_limit) + mpos.x=settings_limit; + */ - if (ratio > 0.9) - ratio = 0.9; - else if (ratio < 0.2) - ratio = 0.2; + //int zoomw = settings_limit-name_limit; + float scale = _get_zoom_scale(); + float pos = h_scroll->get_value() + (mpos.x - name_limit) / scale; + if (animation->get_step()) { + pos = Math::stepify(pos, animation->get_step()); + } + if (pos < 0) + pos = 0; + if (pos >= animation->get_length()) + pos = animation->get_length(); + + 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); + } - name_column_ratio = ratio; + timeline_pos = pos; + emit_signal("timeline_changed", pos, true); - } break; - case ClickOver::CLICK_DRAG_TIMELINE: { - - Point2 mpos = Point2(mb.x, mb.y) - ofs; - /* - if (mpos.x<name_limit) - mpos.x=name_limit; - if (mpos.x>settings_limit) - mpos.x=settings_limit; - */ + } break; + case ClickOver::CLICK_SELECT_KEYS: { - //int zoomw = settings_limit-name_limit; - float scale = _get_zoom_scale(); - float pos = h_scroll->get_value() + (mpos.x - name_limit) / scale; - if (animation->get_step()) { - pos = Math::stepify(pos, animation->get_step()); - } - if (pos < 0) - pos = 0; - if (pos >= animation->get_length()) - pos = animation->get_length(); + click.to = mm->get_position(); + if (click.to.y < h && click.at.y > h && mm->get_relative().y < 0) { - 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); - } + 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 && mm->get_relative().y > 0) { - timeline_pos = pos; - emit_signal("timeline_changed", pos, true); + 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; + } - } break; - case ClickOver::CLICK_SELECT_KEYS: { + } break; + case ClickOver::CLICK_MOVE_KEYS: { - click.to = Point2(mb.x, mb.y); - if (click.to.y < h && click.at.y > h && mb.relative_y < 0) { + click.to = mm->get_position(); + } break; + default: {} + } - 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) { + return; + } else if (mm->get_button_mask() & BUTTON_MASK_MIDDLE) { - 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; - } + int rel = mm->get_relative().x; + float relf = rel / _get_zoom_scale(); + h_scroll->set_value(h_scroll->get_value() - relf); + } - } break; - case ClickOver::CLICK_MOVE_KEYS: { + if (mm->get_button_mask() == 0) { - click.to = Point2(mb.x, mb.y); - } break; - default: {} - } + Point2 mpos = mm->get_position() - ofs; + if (mpos.y < h) { +#if 0 + //seek + //int zoomw = settings_limit-name_limit; + float scale = _get_zoom_scale(); + float pos = h_scroll->get_val() + (mpos.y-name_limit) / scale; + if (pos<0 ) + pos=0; + if (pos>=animation->get_length()) + pos=animation->get_length(); + timeline->set_val(pos); +#endif return; - } else if (mb.button_mask & BUTTON_MASK_MIDDLE) { - - int rel = mb.relative_x; - float relf = rel / _get_zoom_scale(); - h_scroll->set_value(h_scroll->get_value() - relf); } - if (mb.button_mask == 0) { + mpos.y -= h; - Point2 mpos = Point2(mb.x, mb.y) - ofs; + int idx = mpos.y / h; + idx += v_scroll->get_value(); + if (idx < 0 || idx >= animation->get_track_count()) + return; - if (mpos.y < h) { -#if 0 - //seek - //int zoomw = settings_limit-name_limit; - float scale = _get_zoom_scale(); - float pos = h_scroll->get_val() + (mpos.y-name_limit) / scale; - if (pos<0 ) - pos=0; - if (pos>=animation->get_length()) - pos=animation->get_length(); - timeline->set_val(pos); -#endif - return; - } + mouse_over.track = idx; - mpos.y -= h; + if (mpos.x < name_limit) { + //name column - int idx = mpos.y / h; - idx += v_scroll->get_value(); - if (idx < 0 || idx >= animation->get_track_count()) - break; + mouse_over.over = MouseOver::OVER_NAME; - mouse_over.track = idx; + } else if (mpos.x < settings_limit) { - if (mpos.x < name_limit) { - //name column + 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; - mouse_over.over = MouseOver::OVER_NAME; + int kidx = animation->track_find_key(idx, pos); + int kidx_n = kidx + 1; - } else if (mpos.x < settings_limit) { + bool found = false; - 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; + if (kidx >= 0 && kidx < animation->track_get_key_count(idx)) { - int kidx = animation->track_find_key(idx, pos); - int kidx_n = kidx + 1; + float kpos = animation->track_get_key_time(idx, kidx); + if (ABS(pos - kpos) <= w_time) { - bool found = false; + mouse_over.over = MouseOver::OVER_KEY; + mouse_over.track = idx; + mouse_over.over_key = kidx; + found = true; + } + } - if (kidx >= 0 && kidx < animation->track_get_key_count(idx)) { + if (!found && kidx_n >= 0 && kidx_n < animation->track_get_key_count(idx)) { - float kpos = animation->track_get_key_time(idx, kidx); - if (ABS(pos - kpos) <= w_time) { + float kpos = animation->track_get_key_time(idx, kidx_n); + if (ABS(pos - kpos) <= w_time) { - mouse_over.over = MouseOver::OVER_KEY; - mouse_over.track = idx; - mouse_over.over_key = kidx; - found = true; - } + mouse_over.over = MouseOver::OVER_KEY; + mouse_over.track = idx; + mouse_over.over_key = kidx_n; + found = true; } + } - if (!found && kidx_n >= 0 && kidx_n < animation->track_get_key_count(idx)) { + if (found) { - float kpos = animation->track_get_key_time(idx, kidx_n); - if (ABS(pos - kpos) <= w_time) { + String text; + text = "time: " + rtos(animation->track_get_key_time(idx, mouse_over.over_key)) + "\n"; - mouse_over.over = MouseOver::OVER_KEY; - mouse_over.track = idx; - mouse_over.over_key = kidx_n; - found = true; - } - } + switch (animation->track_get_type(idx)) { - if (found) { - - String text; - text = "time: " + rtos(animation->track_get_key_time(idx, mouse_over.over_key)) + "\n"; - - switch (animation->track_get_type(idx)) { - - case Animation::TYPE_TRANSFORM: { - - Dictionary d = animation->track_get_key_value(idx, mouse_over.over_key); - if (d.has("loc")) - text += "loc: " + String(d["loc"]) + "\n"; - if (d.has("rot")) - text += "rot: " + String(d["rot"]) + "\n"; - if (d.has("scale")) - text += "scale: " + String(d["scale"]) + "\n"; - } break; - case Animation::TYPE_VALUE: { - - Variant v = animation->track_get_key_value(idx, mouse_over.over_key); - //text+="value: "+String(v)+"\n"; - - bool prop_exists = false; - Variant::Type valid_type = Variant::NIL; - Object *obj = NULL; - - RES res; - Node *node = root->get_node_and_resource(animation->track_get_path(idx), res); - - if (res.is_valid()) { - obj = res.ptr(); - } else if (node) { - obj = node; - } - - if (obj) { - valid_type = obj->get_static_property_type(animation->track_get_path(idx).get_property(), &prop_exists); - } - - text += "type: " + Variant::get_type_name(v.get_type()) + "\n"; - if (prop_exists && !Variant::can_convert(v.get_type(), valid_type)) { - text += "value: " + String(v) + " (Invalid, expected type: " + Variant::get_type_name(valid_type) + ")\n"; - } else { - text += "value: " + String(v) + "\n"; - } - - } break; - case Animation::TYPE_METHOD: { - - Dictionary d = animation->track_get_key_value(idx, mouse_over.over_key); - if (d.has("method")) - text += String(d["method"]); - text += "("; - Vector<Variant> args; - if (d.has("args")) - args = d["args"]; - for (int i = 0; i < args.size(); i++) { - - if (i > 0) - text += ", "; - text += String(args[i]); - } - text += ")\n"; - - } break; - } - text += "easing: " + rtos(animation->track_get_key_transition(idx, mouse_over.over_key)); + case Animation::TYPE_TRANSFORM: { - track_editor->set_tooltip(text); - return; - } + Dictionary d = animation->track_get_key_value(idx, mouse_over.over_key); + if (d.has("loc")) + text += "loc: " + String(d["loc"]) + "\n"; + if (d.has("rot")) + text += "rot: " + String(d["rot"]) + "\n"; + if (d.has("scale")) + text += "scale: " + String(d["scale"]) + "\n"; + } break; + case Animation::TYPE_VALUE: { - } else { - //button column - int ofsx = size.width - mpos.x; - if (ofsx < 0) - break; - /* - if (ofsx < remove_icon->get_width()) { + Variant v = animation->track_get_key_value(idx, mouse_over.over_key); + //text+="value: "+String(v)+"\n"; - mouse_over.over=MouseOver::OVER_REMOVE; + bool prop_exists = false; + Variant::Type valid_type = Variant::NIL; + Object *obj = NULL; - return; - } + RES res; + Node *node = root->get_node_and_resource(animation->track_get_path(idx), res); - ofsx-=hsep+remove_icon->get_width(); + if (res.is_valid()) { + obj = res.ptr(); + } else if (node) { + obj = node; + } - if (ofsx < move_down_icon->get_width()) { + if (obj) { + valid_type = obj->get_static_property_type(animation->track_get_path(idx).get_property(), &prop_exists); + } - mouse_over.over=MouseOver::OVER_DOWN; - return; + text += "type: " + Variant::get_type_name(v.get_type()) + "\n"; + if (prop_exists && !Variant::can_convert(v.get_type(), valid_type)) { + text += "value: " + String(v) + " (Invalid, expected type: " + Variant::get_type_name(valid_type) + ")\n"; + } else { + text += "value: " + String(v) + "\n"; + } + + } break; + case Animation::TYPE_METHOD: { + + Dictionary d = animation->track_get_key_value(idx, mouse_over.over_key); + if (d.has("method")) + text += String(d["method"]); + text += "("; + Vector<Variant> args; + if (d.has("args")) + args = d["args"]; + for (int i = 0; i < args.size(); i++) { + + if (i > 0) + text += ", "; + text += String(args[i]); + } + text += ")\n"; + + } break; } + text += "easing: " + rtos(animation->track_get_key_transition(idx, mouse_over.over_key)); - ofsx-=hsep+move_down_icon->get_width(); + track_editor->set_tooltip(text); + return; + } - if (ofsx < move_up_icon->get_width()) { + } else { + //button column + int ofsx = size.width - mpos.x; + if (ofsx < 0) + return; + /* + if (ofsx < remove_icon->get_width()) { - mouse_over.over=MouseOver::OVER_UP; - return; - } + mouse_over.over=MouseOver::OVER_REMOVE; - ofsx-=hsep*3+move_up_icon->get_width(); + return; + } - */ + ofsx-=hsep+remove_icon->get_width(); - if (ofsx < down_icon->get_width() + wrap_icon[0]->get_width() + hsep * 3) { + if (ofsx < move_down_icon->get_width()) { - mouse_over.over = MouseOver::OVER_WRAP; - return; - } + mouse_over.over=MouseOver::OVER_DOWN; + return; + } - ofsx -= hsep * 3 + wrap_icon[0]->get_width() + down_icon->get_width(); + ofsx-=hsep+move_down_icon->get_width(); - if (ofsx < down_icon->get_width() + interp_icon[0]->get_width() + hsep * 3) { + if (ofsx < move_up_icon->get_width()) { - mouse_over.over = MouseOver::OVER_INTERP; - return; - } + mouse_over.over=MouseOver::OVER_UP; + return; + } - ofsx -= hsep * 2 + interp_icon[0]->get_width() + down_icon->get_width(); + ofsx-=hsep*3+move_up_icon->get_width(); - if (ofsx < down_icon->get_width() + cont_icon[0]->get_width() + hsep * 3) { +*/ - mouse_over.over = MouseOver::OVER_VALUE; - return; - } + if (ofsx < down_icon->get_width() + wrap_icon[0]->get_width() + hsep * 3) { - ofsx -= hsep * 3 + cont_icon[0]->get_width() + down_icon->get_width(); + mouse_over.over = MouseOver::OVER_WRAP; + return; + } - if (ofsx < add_key_icon->get_width()) { + ofsx -= hsep * 3 + wrap_icon[0]->get_width() + down_icon->get_width(); - mouse_over.over = MouseOver::OVER_ADD_KEY; - return; - } + if (ofsx < down_icon->get_width() + interp_icon[0]->get_width() + hsep * 3) { + + mouse_over.over = MouseOver::OVER_INTERP; + return; } - } - } break; + ofsx -= hsep * 2 + interp_icon[0]->get_width() + down_icon->get_width(); + + if (ofsx < down_icon->get_width() + cont_icon[0]->get_width() + hsep * 3) { + + mouse_over.over = MouseOver::OVER_VALUE; + return; + } + + ofsx -= hsep * 3 + cont_icon[0]->get_width() + down_icon->get_width(); + + if (ofsx < add_key_icon->get_width()) { + + mouse_over.over = MouseOver::OVER_ADD_KEY; + return; + } + } + } } } @@ -2891,6 +2900,8 @@ void AnimationKeyEditor::_notification(int p_what) { key_editor->edit(key_edit); zoomicon->set_texture(get_icon("Zoom", "EditorIcons")); + zoomicon->set_custom_minimum_size(Size2(24 * EDSCALE, 0)); + zoomicon->set_stretch_mode(TextureRect::STRETCH_KEEP_CENTERED); menu_add_track->set_icon(get_icon("AddTrack", "EditorIcons")); menu_add_track->get_popup()->add_icon_item(get_icon("KeyValue", "EditorIcons"), "Add Normal Track", ADD_TRACK_MENU_ADD_VALUE_TRACK); @@ -3753,7 +3764,6 @@ AnimationKeyEditor::AnimationKeyEditor() { //add_child(menu); zoomicon = memnew(TextureRect); - zoomicon->set_stretch_mode(TextureRect::STRETCH_KEEP_CENTERED); hb->add_child(zoomicon); zoomicon->set_tooltip(TTR("Animation zoom.")); @@ -3929,6 +3939,7 @@ AnimationKeyEditor::AnimationKeyEditor() { v_scroll->set_value(0); key_editor_tab = memnew(TabContainer); + key_editor_tab->set_tab_align(TabContainer::ALIGN_LEFT); hb->add_child(key_editor_tab); key_editor_tab->set_custom_minimum_size(Size2(200, 0)); |