diff --git a/editor/animation/animation_bezier_editor.cpp b/editor/animation/animation_bezier_editor.cpp index 8eb02500222..673c12eec46 100644 --- a/editor/animation/animation_bezier_editor.cpp +++ b/editor/animation/animation_bezier_editor.cpp @@ -307,13 +307,23 @@ void AnimationBezierTrackEdit::_notification(int p_what) { const String &lang = _get_locale(); if (has_focus(true)) { - draw_rect(Rect2(Point2(), get_size()), focus_color, false, Math::round(EDSCALE)); + draw_rect(Rect2(Point2(1, 1), get_size() - Point2(1, 1)), focus_color, false, Math::round(EDSCALE)); + } + + int right_limit = get_size().width; + + // Unavailable timeline. + { + int px = (editor->get_current_animation()->get_length() - timeline->get_value()) * timeline->get_zoom_scale() + timeline->get_name_limit(); + px = MAX(px, timeline->get_name_limit()); + Rect2 rect = Rect2(px, 0, right_limit - px, get_size().height); + if (rect.size.width > 0) { + draw_rect(rect, Color(0, 0, 0, 0.2)); + } } draw_line(Point2(limit, 0), Point2(limit, get_size().height), v_line_color, Math::round(EDSCALE)); - int right_limit = get_size().width; - track_v_scroll_max = v_separation; int vofs = v_separation + track_v_scroll; diff --git a/editor/animation/animation_track_editor.cpp b/editor/animation/animation_track_editor.cpp index 984b40ffc12..142d5cf233a 100644 --- a/editor/animation/animation_track_editor.cpp +++ b/editor/animation/animation_track_editor.cpp @@ -1436,8 +1436,9 @@ int AnimationTimelineEdit::get_buttons_width() const { const Ref down_icon = get_theme_icon(SNAME("select_arrow"), SNAME("Tree")); const int h_separation = get_theme_constant(SNAME("h_separation"), SNAME("AnimationTrackEdit")); + const int outer_margin = get_theme_constant(SNAME("outer_margin"), SNAME("AnimationTrackEdit")); - int total_w = interp_mode->get_width() + interp_type->get_width() + loop_type->get_width() + remove_icon->get_width(); + int total_w = interp_mode->get_width() + interp_type->get_width() + loop_type->get_width() + remove_icon->get_width() + outer_margin; total_w += (down_icon->get_width() + h_separation) * 4; return total_w; @@ -1472,6 +1473,8 @@ void AnimationTimelineEdit::_notification(int p_what) { add_track->get_popup()->add_icon_item(get_editor_theme_icon(SNAME("KeyBezier")), TTR("Bezier Curve Track...")); add_track->get_popup()->add_icon_item(get_editor_theme_icon(SNAME("KeyAudio")), TTR("Audio Playback Track...")); add_track->get_popup()->add_icon_item(get_editor_theme_icon(SNAME("KeyAnimation")), TTR("Animation Playback Track...")); + + timeline_resize_rect.size = get_editor_theme_icon(SNAME("TimelineHandle"))->get_size(); } break; case EditorSettings::NOTIFICATION_EDITOR_SETTINGS_CHANGED: { @@ -1502,8 +1505,6 @@ void AnimationTimelineEdit::_notification(int p_what) { } break; case NOTIFICATION_DRAW: { - int key_range = get_size().width - get_buttons_width() - get_name_limit(); - if (animation.is_null()) { return; } @@ -1527,7 +1528,7 @@ void AnimationTimelineEdit::_notification(int p_what) { const int text_primary_margin = get_theme_constant(SNAME("text_primary_margin"), SNAME("AnimationTimelineEdit")); const int text_secondary_margin = get_theme_constant(SNAME("text_secondary_margin"), SNAME("AnimationTimelineEdit")); - int zoomw = key_range; + int zoomw = get_size().width - get_buttons_width() - get_name_limit(); float scale = get_zoom_scale(); int h = get_size().height; @@ -1595,20 +1596,19 @@ void AnimationTimelineEdit::_notification(int p_what) { int end_px = (l - get_value()) * scale; int begin_px = -get_value() * scale; - { - draw_style_box(stylebox_time_unavailable, Rect2(Point2(get_name_limit(), 0), Point2(zoomw - 1, h))); + draw_style_box(stylebox_time_unavailable, Rect2(Point2(get_name_limit(), 0), Point2(zoomw - 1, h))); - if (begin_px < zoomw && end_px > 0) { - if (begin_px < 0) { - begin_px = 0; - } - if (end_px > zoomw) { - end_px = zoomw; - } - - draw_style_box(stylebox_time_available, Rect2(Point2(get_name_limit() + begin_px, 0), Point2(end_px - begin_px, h))); + if (begin_px < zoomw && end_px > 0) { + if (begin_px < 0) { + begin_px = 0; } + if (end_px > zoomw) { + end_px = zoomw; + } + + draw_style_box(stylebox_time_available, Rect2(Point2(get_name_limit() + begin_px, 0), Point2(end_px - begin_px, h))); } + #define SC_ADJ 100 int dec = 1; int step = 1; @@ -1708,8 +1708,23 @@ void AnimationTimelineEdit::_notification(int p_what) { } draw_line(Vector2(0, get_size().height), get_size(), h_line_color, Math::round(EDSCALE)); + + int px = get_name_limit() + end_px - timeline_resize_rect.size.width * 0.5; + timeline_resize_rect.position.x = px; + if (px >= get_name_limit() && px < zoomw + get_buttons_width()) { + draw_texture(get_editor_theme_icon(SNAME("TimelineHandle")), Point2(timeline_resize_rect.position.x, 0)); + } + update_values(); } break; + + case NOTIFICATION_WM_WINDOW_FOCUS_OUT: { + if (resizing_timeline) { + _commit_timeline_resize(); + } else if (dragging_hsize || dragging_timeline) { + _stop_dragging(); + } + } break; } } @@ -1817,6 +1832,10 @@ void AnimationTimelineEdit::set_track_edit(AnimationTrackEdit *p_track_edit) { track_edit = p_track_edit; } +void AnimationTimelineEdit::set_editor(AnimationTrackEditor *p_editor) { + editor = p_editor; +} + void AnimationTimelineEdit::set_play_position(float p_pos) { play_position_pos = p_pos; play_position->queue_redraw(); @@ -1902,41 +1921,55 @@ void AnimationTimelineEdit::gui_input(const Ref &p_event) { const Ref mb = p_event; - if (mb.is_valid() && mb->is_pressed() && mb->is_alt_pressed() && mb->get_button_index() == MouseButton::WHEEL_UP) { - if (track_edit) { - track_edit->get_editor()->goto_prev_step(true); + if (mb.is_valid()) { + if (mb->is_pressed() && mb->is_alt_pressed() && mb->get_button_index() == MouseButton::WHEEL_UP) { + if (track_edit) { + track_edit->get_editor()->goto_prev_step(true); + } + accept_event(); } - accept_event(); - } - if (mb.is_valid() && mb->is_pressed() && mb->is_alt_pressed() && mb->get_button_index() == MouseButton::WHEEL_DOWN) { - if (track_edit) { - track_edit->get_editor()->goto_next_step(true); + if (mb->is_pressed() && mb->is_alt_pressed() && mb->get_button_index() == MouseButton::WHEEL_DOWN) { + if (track_edit) { + track_edit->get_editor()->goto_next_step(true); + } + accept_event(); } - accept_event(); - } - if (mb.is_valid() && mb->is_pressed() && mb->get_button_index() == MouseButton::LEFT && hsize_rect.has_point(mb->get_position())) { - dragging_hsize = true; - dragging_hsize_from = mb->get_position().x; - dragging_hsize_at = name_limit; - } + if (!resizing_timeline && !dragging_hsize && mb->is_pressed() && mb->get_button_index() == MouseButton::LEFT) { + if (timeline_resize_rect.has_point(mb->get_position())) { + resizing_timeline = true; + timeline_resize_from = timeline_resize_rect.position.x + timeline_resize_rect.size.width / 2 - mb->get_position().x; + timeline_resize_at = animation->get_length(); + } else if (hsize_rect.has_point(mb->get_position())) { + dragging_hsize = true; + dragging_hsize_from = mb->get_position().x; + dragging_hsize_at = name_limit; + } + } - if (mb.is_valid() && !mb->is_pressed() && mb->get_button_index() == MouseButton::LEFT && dragging_hsize) { - dragging_hsize = false; - } - if (mb.is_valid() && mb->get_position().x > get_name_limit() && mb->get_position().x < (get_size().width - get_buttons_width())) { - if (!panner->is_panning() && mb->get_button_index() == MouseButton::LEFT) { + if (!resizing_timeline && !panner->is_panning() && mb->is_pressed() && mb->get_button_index() == MouseButton::LEFT && + mb->get_position().x > get_name_limit() && mb->get_position().x < (get_size().width - get_buttons_width())) { int x = mb->get_position().x - get_name_limit(); float ofs = x / get_zoom_scale() + get_value(); emit_signal(SNAME("timeline_changed"), ofs, mb->is_alt_pressed()); dragging_timeline = true; } - } - if (dragging_timeline && mb.is_valid() && mb->get_button_index() == MouseButton::LEFT && !mb->is_pressed()) { - dragging_timeline = false; + if (!mb->is_pressed() && mb->get_button_index() == MouseButton::LEFT) { + if (resizing_timeline) { + _commit_timeline_resize(); + } else if (dragging_hsize || dragging_timeline) { + _stop_dragging(); + } + } + + if (resizing_timeline && mb->is_pressed() && mb->get_button_index() == MouseButton::RIGHT) { + resizing_timeline = false; + // Undo changes. + animation->set_length(timeline_resize_at); + } } Ref mm = p_event; @@ -1952,8 +1985,11 @@ void AnimationTimelineEdit::gui_input(const Ref &p_event) { queue_redraw(); emit_signal(SNAME("name_limit_changed")); play_position->queue_redraw(); - } - if (dragging_timeline) { + } else if (resizing_timeline) { + int x = mm->get_position().x + timeline_resize_from - get_name_limit(); + float ofs = x / get_zoom_scale() + get_value(); + animation->set_length(editor->snap_time(ofs)); + } else if (dragging_timeline) { int x = mm->get_position().x - get_name_limit(); float ofs = x / get_zoom_scale() + get_value(); emit_signal(SNAME("timeline_changed"), ofs, mm->is_alt_pressed()); @@ -1961,9 +1997,25 @@ void AnimationTimelineEdit::gui_input(const Ref &p_event) { } } +void AnimationTimelineEdit::_commit_timeline_resize() { + if (animation->get_length() != timeline_resize_at) { + EditorUndoRedoManager *undo_redo = EditorUndoRedoManager::get_singleton(); + undo_redo->create_action(TTR("Change Animation Length")); + undo_redo->add_do_method(animation.ptr(), "set_length", animation->get_length()); + undo_redo->add_undo_method(animation.ptr(), "set_length", timeline_resize_at); + undo_redo->commit_action(false); + } + resizing_timeline = false; +} + +void AnimationTimelineEdit::_stop_dragging() { + dragging_hsize = false; + dragging_timeline = false; +} + Control::CursorShape AnimationTimelineEdit::get_cursor_shape(const Point2 &p_pos) const { - if (dragging_hsize || hsize_rect.has_point(p_pos)) { - // Indicate that the track name column's width can be adjusted + if (dragging_hsize || resizing_timeline || hsize_rect.has_point(p_pos) || timeline_resize_rect.has_point(p_pos)) { + // Indicate that the track name column's width and the timeline length can be adjusted. return Control::CURSOR_HSIZE; } else { return get_default_cursor_shape(); @@ -2133,6 +2185,19 @@ void AnimationTrackEdit::_notification(int p_what) { draw_style_box(stylebox_focus, Rect2(Point2(1 * EDSCALE, 0), get_size() - Size2(1 * EDSCALE, 0))); } + int limit_end = get_size().width - timeline->get_buttons_width(); + + // Unavailable timeline. + + { + int px = (animation->get_length() - timeline->get_value()) * timeline->get_zoom_scale() + timeline->get_name_limit(); + px = MAX(px, timeline->get_name_limit()); + Rect2 rect = Rect2(px, 0, limit_end - px, get_size().height); + if (rect.size.width > 0) { + draw_rect(rect, Color(0, 0, 0, 0.2)); + } + } + const Ref font = get_theme_font(SceneStringName(font), SNAME("Label")); const int font_size = get_theme_font_size(SceneStringName(font_size), SNAME("Label")); const Color color = get_theme_color(SceneStringName(font_color), SNAME("Label")); @@ -2210,7 +2275,6 @@ void AnimationTrackEdit::_notification(int p_what) { { float scale = timeline->get_zoom_scale(); - int limit_end = get_size().width - timeline->get_buttons_width(); PackedStringArray section = editor->get_selected_section(); if (section.size() == 2) { @@ -2255,20 +2319,21 @@ void AnimationTrackEdit::_notification(int p_what) { if (time >= 0) { float offset = time - timeline->get_value(); offset = offset * scale + limit; - Color marker_color = animation->get_marker_color(marker); - marker_color.a = 0.2; - draw_line(Point2(offset, 0), Point2(offset, get_size().height), marker_color, Math::round(EDSCALE)); + if (offset >= timeline->get_name_limit() && offset < limit_end) { + Color marker_color = animation->get_marker_color(marker); + marker_color.a = 0.2; + draw_line(Point2(offset, 0), Point2(offset, get_size().height), marker_color, Math::round(EDSCALE)); + } } } } // Keyframes. - draw_bg(limit, get_size().width - timeline->get_buttons_width() - outer_margin); + draw_bg(limit, limit_end); { float scale = timeline->get_zoom_scale(); - int limit_end = get_size().width - timeline->get_buttons_width() - outer_margin; for (int i = 0; i < animation->track_get_key_count(track); i++) { float offset = animation->track_get_key_time(track, i) - timeline->get_value(); @@ -2303,7 +2368,7 @@ void AnimationTrackEdit::_notification(int p_what) { } } - draw_fg(limit, get_size().width - timeline->get_buttons_width() - outer_margin); + draw_fg(limit, limit_end); // Buttons. @@ -2329,7 +2394,7 @@ void AnimationTrackEdit::_notification(int p_what) { get_editor_theme_icon(SNAME("UseBlendDisable")), }; - int ofs = get_size().width - timeline->get_buttons_width() - outer_margin; + int ofs = limit_end; const Ref down_icon = get_theme_icon(SNAME("select_arrow"), SNAME("Tree")); @@ -3218,9 +3283,6 @@ void AnimationTrackEdit::gui_input(const Ref &p_event) { } menu->reset_size(); - moving_selection_attempt = false; - moving_selection = false; - menu->set_position(get_screen_position() + get_local_mouse_position()); menu->popup(); @@ -3756,8 +3818,6 @@ void AnimationTrackEditGroup::_notification(int p_what) { Color color = get_theme_color(SceneStringName(font_color), SNAME("Label")); const Ref &stylebox_header = get_theme_stylebox(SNAME("header"), SNAME("AnimationTrackEditGroup")); - const int outer_margin = get_theme_constant(SNAME("outer_margin"), SNAME("AnimationTrackEdit")); - float v_margin_offset = stylebox_header->get_content_margin(SIDE_TOP) - stylebox_header->get_content_margin(SIDE_BOTTOM); const Color h_line_color = get_theme_color(SNAME("h_line_color"), SNAME("AnimationTrackEditGroup")); @@ -3783,12 +3843,23 @@ void AnimationTrackEditGroup::_notification(int p_what) { } int limit = timeline->get_name_limit(); + int limit_end = get_size().width - timeline->get_buttons_width(); + + // Unavailable timeline. + + { + int px = (editor->get_current_animation()->get_length() - timeline->get_value()) * timeline->get_zoom_scale() + timeline->get_name_limit(); + px = MAX(px, timeline->get_name_limit()); + Rect2 rect = Rect2(px, 0, limit_end - px, get_size().height); + if (rect.size.width > 0) { + draw_rect(rect, Color(0, 0, 0, 0.2)); + } + } // Section preview. { float scale = timeline->get_zoom_scale(); - int limit_end = get_size().width - timeline->get_buttons_width(); PackedStringArray section = editor->get_selected_section(); if (section.size() == 2) { @@ -3797,8 +3868,8 @@ void AnimationTrackEditGroup::_notification(int p_what) { double start_time = editor->get_current_animation()->get_marker_time(start_marker); double end_time = editor->get_current_animation()->get_marker_time(end_marker); - // When AnimationPlayer is playing, don't move the preview rect, so it still indicates the playback section. AnimationPlayer *player = AnimationPlayerEditor::get_singleton()->get_player(); + // When AnimationPlayer is playing, don't move the preview rect, so it still indicates the playback section. if (editor->is_marker_moving_selection() && !(player && player->is_playing())) { start_time += editor->get_marker_moving_selection_offset(); end_time += editor->get_marker_moving_selection_offset(); @@ -3833,16 +3904,18 @@ void AnimationTrackEditGroup::_notification(int p_what) { if (time >= 0) { float offset = time - timeline->get_value(); offset = offset * scale + limit; - Color marker_color = editor->get_current_animation()->get_marker_color(marker); - marker_color.a = 0.2; - draw_line(Point2(offset, 0), Point2(offset, get_size().height), marker_color, Math::round(EDSCALE)); + if (offset >= timeline->get_name_limit() && offset < limit_end) { + Color marker_color = editor->get_current_animation()->get_marker_color(marker); + marker_color.a = 0.2; + draw_line(Point2(offset, 0), Point2(offset, get_size().height), marker_color, Math::round(EDSCALE)); + } } } } draw_line(Point2(), Point2(get_size().width, 0), h_line_color, Math::round(EDSCALE)); draw_line(Point2(timeline->get_name_limit(), 0), Point2(timeline->get_name_limit(), get_size().height), v_line_color, Math::round(EDSCALE)); - draw_line(Point2(get_size().width - timeline->get_buttons_width() - outer_margin, 0), Point2(get_size().width - timeline->get_buttons_width() - outer_margin, get_size().height), v_line_color, Math::round(EDSCALE)); + draw_line(Point2(get_size().width - timeline->get_buttons_width(), 0), Point2(get_size().width - timeline->get_buttons_width(), get_size().height), v_line_color, Math::round(EDSCALE)); int ofs = stylebox_header->get_margin(SIDE_LEFT); draw_texture_rect(icon, Rect2(Point2(ofs, (get_size().height - icon_size.y) / 2 + v_margin_offset).round(), icon_size)); @@ -3850,8 +3923,7 @@ void AnimationTrackEditGroup::_notification(int p_what) { draw_string(font, Point2(ofs, (get_size().height - font->get_height(font_size)) / 2 + font->get_ascent(font_size) + v_margin_offset).round(), node_name, HORIZONTAL_ALIGNMENT_LEFT, timeline->get_name_limit() - ofs, font_size, color); int px = (-timeline->get_value() + timeline->get_play_position()) * timeline->get_zoom_scale() + timeline->get_name_limit(); - - if (px >= timeline->get_name_limit() && px < (get_size().width - timeline->get_buttons_width())) { + if (px >= timeline->get_name_limit() && px < limit_end) { const Color accent = get_theme_color(SNAME("accent_color"), EditorStringName(Editor)); draw_line(Point2(px, 0), Point2(px, get_size().height), accent, Math::round(2 * EDSCALE)); } @@ -7971,6 +8043,7 @@ AnimationTrackEditor::AnimationTrackEditor() { timeline = memnew(AnimationTimelineEdit); timeline_vbox->add_child(timeline); + timeline->set_editor(this); timeline->connect("timeline_changed", callable_mp(this, &AnimationTrackEditor::_timeline_changed)); timeline->connect("name_limit_changed", callable_mp(this, &AnimationTrackEditor::_name_limit_changed)); timeline->connect("track_added", callable_mp(this, &AnimationTrackEditor::_add_track)); @@ -8841,6 +8914,8 @@ void AnimationMarkerEdit::_notification(int p_what) { } int limit = timeline->get_name_limit(); + int limit_end = get_size().width - timeline->get_buttons_width(); + float scale = timeline->get_zoom_scale(); Ref font = get_theme_font(SceneStringName(font), SNAME("Label")); Color color = get_theme_color(SceneStringName(font_color), SNAME("Label")); @@ -8848,9 +8923,6 @@ void AnimationMarkerEdit::_notification(int p_what) { // SECTION PREVIEW // { - float scale = timeline->get_zoom_scale(); - int limit_end = get_size().width - timeline->get_buttons_width(); - PackedStringArray section = get_selected_section(); if (section.size() == 2) { StringName start_marker = section[0]; @@ -8886,9 +8958,6 @@ void AnimationMarkerEdit::_notification(int p_what) { draw_bg(limit, get_size().width - timeline->get_buttons_width()); { - float scale = timeline->get_zoom_scale(); - int limit_end = get_size().width - timeline->get_buttons_width(); - PackedStringArray names = animation->get_marker_names(); for (int i = 0; i < names.size(); i++) { StringName name = names[i]; @@ -8916,7 +8985,7 @@ void AnimationMarkerEdit::_notification(int p_what) { } } - draw_fg(limit, get_size().width - timeline->get_buttons_width()); + draw_fg(limit, limit_end); } break; case NOTIFICATION_MOUSE_ENTER: @@ -8970,6 +9039,37 @@ void AnimationMarkerEdit::gui_input(const Ref &p_event) { } } + // Check if moving markers or resizing the timeline first, so they can be canceled instead. + if (!moving_selection && !timeline->resizing_timeline && mb.is_valid() && mb->is_pressed() && mb->get_button_index() == MouseButton::RIGHT) { + Point2 pos = mb->get_position(); + if (pos.x >= timeline->get_name_limit() && pos.x <= get_size().width - timeline->get_buttons_width()) { + // Can do something with menu too! show insert key. + float offset = (pos.x - timeline->get_name_limit()) / timeline->get_zoom_scale(); + if (!read_only) { + bool selected = _try_select_at_ui_pos(pos, mb->is_command_or_control_pressed() || mb->is_shift_pressed(), false); + + menu->clear(); + menu->add_icon_item(get_editor_theme_icon(SNAME("Key")), TTR("Insert Marker..."), MENU_KEY_INSERT); + + if (selected || selection.size() > 0) { + menu->add_icon_item(get_editor_theme_icon(SNAME("Edit")), TTR("Rename Marker"), MENU_KEY_RENAME); + menu->add_icon_item(get_editor_theme_icon(SNAME("Remove")), TTR("Delete Marker(s)"), MENU_KEY_DELETE); + } + + menu->add_icon_item(get_editor_theme_icon(should_show_all_marker_names ? SNAME("GuiChecked") : SNAME("GuiUnchecked")), TTR("Show All Marker Names"), MENU_KEY_TOGGLE_MARKER_NAMES); + menu->reset_size(); + + menu->set_position(get_screen_position() + get_local_mouse_position()); + menu->popup(); + + insert_at_pos = offset + timeline->get_value(); + accept_event(); + + timeline->_stop_dragging(); + } + } + } + if (mb.is_valid() && moving_selection_attempt) { if (!mb->is_pressed() && mb->get_button_index() == MouseButton::LEFT) { moving_selection_attempt = false; @@ -9009,37 +9109,6 @@ void AnimationMarkerEdit::gui_input(const Ref &p_event) { } } - if (mb.is_valid() && mb->is_pressed() && mb->get_button_index() == MouseButton::RIGHT) { - Point2 pos = mb->get_position(); - if (pos.x >= timeline->get_name_limit() && pos.x <= get_size().width - timeline->get_buttons_width()) { - // Can do something with menu too! show insert key. - float offset = (pos.x - timeline->get_name_limit()) / timeline->get_zoom_scale(); - if (!read_only) { - bool selected = _try_select_at_ui_pos(pos, mb->is_command_or_control_pressed() || mb->is_shift_pressed(), false); - - menu->clear(); - menu->add_icon_item(get_editor_theme_icon(SNAME("Key")), TTR("Insert Marker..."), MENU_KEY_INSERT); - - if (selected || selection.size() > 0) { - menu->add_icon_item(get_editor_theme_icon(SNAME("Edit")), TTR("Rename Marker"), MENU_KEY_RENAME); - menu->add_icon_item(get_editor_theme_icon(SNAME("Remove")), TTR("Delete Marker(s)"), MENU_KEY_DELETE); - } - - menu->add_icon_item(get_editor_theme_icon(should_show_all_marker_names ? SNAME("GuiChecked") : SNAME("GuiUnchecked")), TTR("Show All Marker Names"), MENU_KEY_TOGGLE_MARKER_NAMES); - menu->reset_size(); - - moving_selection_attempt = false; - moving_selection = false; - - menu->set_position(get_screen_position() + get_local_mouse_position()); - menu->popup(); - - insert_at_pos = offset + timeline->get_value(); - accept_event(); - } - } - } - Ref mm = p_event; if (mm.is_valid()) { diff --git a/editor/animation/animation_track_editor.h b/editor/animation/animation_track_editor.h index 1e995297905..2dd16b0383f 100644 --- a/editor/animation/animation_track_editor.h +++ b/editor/animation/animation_track_editor.h @@ -187,6 +187,7 @@ class AnimationTimelineEdit : public Range { friend class AnimationBezierTrackEdit; friend class AnimationTrackEditor; + friend class AnimationMarkerEdit; static constexpr float SCROLL_ZOOM_FACTOR_IN = 1.02f; // Zoom factor per mouse scroll in the animation editor when zooming in. The closer to 1.0, the finer the control. static constexpr float SCROLL_ZOOM_FACTOR_OUT = 0.98f; // Zoom factor when zooming out. Similar to SCROLL_ZOOM_FACTOR_IN but less than 1.0. @@ -195,6 +196,7 @@ class AnimationTimelineEdit : public Range { bool read_only = false; AnimationTrackEdit *track_edit = nullptr; + AnimationTrackEditor *editor = nullptr; int name_limit = 0; Range *zoom = nullptr; Range *h_scroll = nullptr; @@ -225,6 +227,11 @@ class AnimationTimelineEdit : public Range { void _pan_callback(Vector2 p_scroll_vec, Ref p_event); void _zoom_callback(float p_zoom_factor, Vector2 p_origin, Ref p_event); + Rect2 timeline_resize_rect; + float timeline_resize_from = 0.0f; + float timeline_resize_at = 0.0f; + bool resizing_timeline = false; + bool dragging_timeline = false; bool dragging_hsize = false; float dragging_hsize_from = 0.0f; @@ -236,6 +243,8 @@ class AnimationTimelineEdit : public Range { bool zoom_callback_occurred = false; virtual void gui_input(const Ref &p_event) override; + void _commit_timeline_resize(); + void _stop_dragging(); void _track_added(int p_track); float _get_zoom_scale(double p_zoom_value) const; @@ -254,6 +263,7 @@ public: virtual Size2 get_minimum_size() const override; void set_animation(const Ref &p_animation, bool p_read_only); void set_track_edit(AnimationTrackEdit *p_track_edit); + void set_editor(AnimationTrackEditor *p_editor); void set_zoom(Range *p_zoom); Range *get_zoom() const { return zoom; } void auto_fit(); diff --git a/editor/icons/TimelineHandle.svg b/editor/icons/TimelineHandle.svg new file mode 100644 index 00000000000..01321db15e0 --- /dev/null +++ b/editor/icons/TimelineHandle.svg @@ -0,0 +1 @@ + diff --git a/editor/themes/theme_classic.cpp b/editor/themes/theme_classic.cpp index 3175420e5b9..551bc9edc80 100644 --- a/editor/themes/theme_classic.cpp +++ b/editor/themes/theme_classic.cpp @@ -2141,8 +2141,12 @@ void ThemeClassic::populate_editor_styles(const Ref &p_theme, Edito // AnimationTimelineEdit. // "primary" is used for integer timeline values, "secondary" for decimals. - Ref style_time_unavailable = EditorThemeManager::make_flat_stylebox(p_config.dark_color_2, 0, 0, 0, 0, 0); + Ref style_time_unavailable = EditorThemeManager::make_flat_stylebox(p_config.dark_color_3, 0, 0, 0, 0, 0); Ref style_time_available = EditorThemeManager::make_flat_stylebox(p_config.font_color * Color(1, 1, 1, 0.2), 0, 0, 0, 0, 0); + if (!p_config.dark_theme) { + style_time_unavailable = EditorThemeManager::make_flat_stylebox(p_config.font_color * Color(1, 1, 1, 0.2), 0, 0, 0, 0, 0); + style_time_available = EditorThemeManager::make_flat_stylebox(p_config.dark_color_3 * Color(1, 1, 1, 0.5), 0, 0, 0, 0, 0); + } p_theme->set_stylebox("time_unavailable", "AnimationTimelineEdit", style_time_unavailable); p_theme->set_stylebox("time_available", "AnimationTimelineEdit", style_time_available); diff --git a/editor/themes/theme_modern.cpp b/editor/themes/theme_modern.cpp index 1849e3d8529..0eca94568f8 100644 --- a/editor/themes/theme_modern.cpp +++ b/editor/themes/theme_modern.cpp @@ -2108,14 +2108,14 @@ void ThemeModern::populate_editor_styles(const Ref &p_theme, Editor // "primary" is used for integer timeline values, "secondary" for decimals. Ref style_time_available = p_config.base_style->duplicate(); - style_time_available->set_bg_color(p_config.surface_highest_color); + style_time_available->set_bg_color(p_config.dark_theme ? p_config.surface_highest_color : p_config.surface_high_color); if (p_config.draw_extra_borders) { style_time_available->set_border_width_all(Math::round(EDSCALE)); - style_time_available->set_border_color(p_config.extra_border_color_1); + style_time_available->set_border_color(p_config.extra_border_color_2); } Ref style_time_unavailable = p_config.base_style->duplicate(); - style_time_unavailable->set_bg_color(p_config.surface_high_color); + style_time_unavailable->set_bg_color(p_config.dark_theme ? p_config.surface_high_color : p_config.surface_highest_color); p_theme->set_stylebox("time_available", "AnimationTimelineEdit", style_time_available); p_theme->set_stylebox("time_unavailable", "AnimationTimelineEdit", style_time_unavailable);