From 6120786ddc349acfd6eed0d4083774c29845baf7 Mon Sep 17 00:00:00 2001 From: passivestar <60579014+passivestar@users.noreply.github.com> Date: Tue, 25 Jun 2024 02:38:46 +0400 Subject: [PATCH] Allow theming animation editor --- editor/animation_bezier_editor.cpp | 143 ++++++------- editor/animation_track_editor.cpp | 271 ++++++++++++++----------- editor/animation_track_editor.h | 1 + editor/themes/editor_theme_manager.cpp | 65 ++++++ 4 files changed, 291 insertions(+), 189 deletions(-) diff --git a/editor/animation_bezier_editor.cpp b/editor/animation_bezier_editor.cpp index f74bdd8bb9f..5196857240c 100644 --- a/editor/animation_bezier_editor.cpp +++ b/editor/animation_bezier_editor.cpp @@ -54,7 +54,7 @@ void AnimationBezierTrackEdit::_draw_track(int p_track, const Color &p_color) { int limit = timeline->get_name_limit(); int right_limit = get_size().width; - //selection may have altered the order of keys + // Selection may have altered the order of keys. RBMap key_order; for (int i = 0; i < animation->track_get_key_count(p_track); i++) { @@ -111,11 +111,11 @@ void AnimationBezierTrackEdit::_draw_track(int p_track, const Color &p_color) { int to_x = (offset_n - timeline->get_value()) * scale + limit; int point_end = to_x; - if (from_x > right_limit) { //not visible + if (from_x > right_limit) { // Not visible. continue; } - if (to_x < limit) { //not visible + if (to_x < limit) { // Not visible. continue; } @@ -132,15 +132,15 @@ void AnimationBezierTrackEdit::_draw_track(int p_track, const Color &p_color) { float h; if (j == point_end) { - h = end.y; //make sure it always connects + h = end.y; // Make sure it always connects. } else if (j == point_start) { - h = start.y; //make sure it always connects - } else { //custom interpolation, used because it needs to show paths affected by moving the selection or handles + h = start.y; // Make sure it always connects. + } else { // Custom interpolation, used because it needs to show paths affected by moving the selection or handles. int iterations = 10; float low = 0; float high = 1; - //narrow high and low as much as possible + // Narrow high and low as much as possible. for (int k = 0; k < iterations; k++) { float middle = (low + high) / 2.0; @@ -153,7 +153,7 @@ void AnimationBezierTrackEdit::_draw_track(int p_track, const Color &p_color) { } } - //interpolate the result: + // Interpolate the result. Vector2 low_pos = start.bezier_interpolate(out_handle, in_handle, end, low); Vector2 high_pos = start.bezier_interpolate(out_handle, in_handle, end, high); @@ -236,27 +236,29 @@ void AnimationBezierTrackEdit::_notification(int p_what) { int limit = timeline->get_name_limit(); + 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")); + + const Color h_line_color = get_theme_color(SNAME("h_line_color"), SNAME("AnimationBezierTrackEdit")); + const Color v_line_color = get_theme_color(SNAME("v_line_color"), SNAME("AnimationBezierTrackEdit")); + const Color focus_color = get_theme_color(SNAME("focus_color"), SNAME("AnimationBezierTrackEdit")); + const Color track_focus_color = get_theme_color(SNAME("track_focus_color"), SNAME("AnimationBezierTrackEdit")); + + const int h_separation = get_theme_constant(SNAME("h_separation"), SNAME("AnimationBezierTrackEdit")); + const int v_separation = get_theme_constant(SNAME("h_separation"), SNAME("AnimationBezierTrackEdit")); + if (has_focus()) { - Color accent = get_theme_color(SNAME("accent_color"), EditorStringName(Editor)); - accent.a *= 0.7; - draw_rect(Rect2(Point2(), get_size()), accent, false, Math::round(EDSCALE)); + draw_rect(Rect2(Point2(), get_size()), focus_color, false, Math::round(EDSCALE)); } - Ref font = get_theme_font(SceneStringName(font), SNAME("Label")); - int font_size = get_theme_font_size(SceneStringName(font_size), SNAME("Label")); - Color color = get_theme_color(SceneStringName(font_color), SNAME("Label")); - int hsep = get_theme_constant(SNAME("h_separation"), SNAME("ItemList")); - int vsep = get_theme_constant(SNAME("v_separation"), SNAME("ItemList")); - Color linecolor = color; - linecolor.a = 0.2; - - draw_line(Point2(limit, 0), Point2(limit, get_size().height), linecolor, Math::round(EDSCALE)); + 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 = vsep; + track_v_scroll_max = v_separation; - int vofs = vsep + track_v_scroll; + int vofs = v_separation + track_v_scroll; int margin = 0; RBMap subtrack_colors; @@ -286,7 +288,7 @@ void AnimationBezierTrackEdit::_notification(int p_what) { Vector tracks = E.value; - // NAMES AND ICON + // Names and icon. { NodePath path = animation->track_get_path(tracks[0]); @@ -304,15 +306,15 @@ void AnimationBezierTrackEdit::_notification(int p_what) { Ref icon = EditorNode::get_singleton()->get_object_icon(node, "Node"); text = node->get_name(); - ofs += hsep; + ofs += h_separation; TextLine text_buf = TextLine(text, font, font_size); - text_buf.set_width(limit - ofs - icon->get_width() - hsep); + text_buf.set_width(limit - ofs - icon->get_width() - h_separation); int h = MAX(text_buf.get_size().y, icon->get_height()); draw_texture(icon, Point2(ofs, vofs + int(h - icon->get_height()) / 2.0)); - ofs += icon->get_width(); + ofs += icon->get_width() + h_separation; margin = icon->get_width(); @@ -320,31 +322,31 @@ void AnimationBezierTrackEdit::_notification(int p_what) { string_pos = string_pos.floor(); text_buf.draw(get_canvas_item(), string_pos, color); - vofs += h + vsep; - track_v_scroll_max += h + vsep; + vofs += h + v_separation; + track_v_scroll_max += h + v_separation; } } - Color dc = get_theme_color(SNAME("font_disabled_color"), EditorStringName(Editor)); + const Color dc = get_theme_color(SNAME("font_disabled_color"), EditorStringName(Editor)); Ref remove = get_editor_theme_icon(SNAME("Remove")); - float remove_hpos = limit - hsep - remove->get_width(); + float remove_hpos = limit - h_separation - remove->get_width(); Ref lock = get_editor_theme_icon(SNAME("Lock")); Ref unlock = get_editor_theme_icon(SNAME("Unlock")); - float lock_hpos = remove_hpos - hsep - lock->get_width(); + float lock_hpos = remove_hpos - h_separation - lock->get_width(); Ref visibility_visible = get_editor_theme_icon(SNAME("GuiVisibilityVisible")); Ref visibility_hidden = get_editor_theme_icon(SNAME("GuiVisibilityHidden")); - float visibility_hpos = lock_hpos - hsep - visibility_visible->get_width(); + float visibility_hpos = lock_hpos - h_separation - visibility_visible->get_width(); Ref solo = get_editor_theme_icon(SNAME("AudioBusSolo")); - float solo_hpos = visibility_hpos - hsep - solo->get_width(); + float solo_hpos = visibility_hpos - h_separation - solo->get_width(); - float buttons_width = remove->get_width() + lock->get_width() + visibility_visible->get_width() + solo->get_width() + hsep * 3; + float buttons_width = remove->get_width() + lock->get_width() + visibility_visible->get_width() + solo->get_width() + h_separation * 3; for (int i = 0; i < tracks.size(); ++i) { - // RELATED TRACKS TITLES + // Related track titles. int current_track = tracks[i]; @@ -353,9 +355,9 @@ void AnimationBezierTrackEdit::_notification(int p_what) { Color cc = color; TextLine text_buf = TextLine(path, font, font_size); - text_buf.set_width(limit - margin - buttons_width); + text_buf.set_width(limit - margin - buttons_width - h_separation * 2); - Rect2 rect = Rect2(margin, vofs, solo_hpos - hsep - solo->get_width(), text_buf.get_size().y + vsep); + Rect2 rect = Rect2(margin, vofs, solo_hpos - h_separation - solo->get_width(), text_buf.get_size().y + v_separation); cc.a *= 0.7; float h; @@ -381,14 +383,12 @@ void AnimationBezierTrackEdit::_notification(int p_what) { track_color.set_hsv(h, 0.2, 0.8); } track_color.a = 0.5; - draw_rect(Rect2(0, vofs, margin - hsep, text_buf.get_size().y * 0.8), track_color); + draw_rect(Rect2(0, vofs, margin - h_separation, text_buf.get_size().y * 0.8), track_color); subtrack_colors[current_track] = track_color; subtracks[current_track] = rect; } else { - Color ac = get_theme_color(SNAME("accent_color"), EditorStringName(Editor)); - ac.a = 0.5; - draw_rect(rect, ac); + draw_rect(rect, track_focus_color); if (locked_tracks.has(selected_track)) { selected_track_color.set_hsv(h, 0.0, 0.4); } else { @@ -396,7 +396,7 @@ void AnimationBezierTrackEdit::_notification(int p_what) { } } - Vector2 string_pos = Point2(margin, vofs); + Vector2 string_pos = Point2(margin + h_separation, vofs); text_buf.draw(get_canvas_item(), string_pos, cc); float icon_start_height = vofs + rect.size.y / 2.0; @@ -432,15 +432,16 @@ void AnimationBezierTrackEdit::_notification(int p_what) { subtrack_icons[current_track] = track_icons; - vofs += text_buf.get_size().y + vsep; - track_v_scroll_max += text_buf.get_size().y + vsep; + vofs += text_buf.get_size().y + v_separation; + track_v_scroll_max += text_buf.get_size().y + v_separation; } } - Color accent = get_theme_color(SNAME("accent_color"), EditorStringName(Editor)); + const Color accent = get_theme_color(SNAME("accent_color"), EditorStringName(Editor)); - { //guides - float min_left_scale = font->get_height(font_size) + vsep; + // Guides. + { + float min_left_scale = font->get_height(font_size) + v_separation; float scale = (min_left_scale * 2) * timeline_v_zoom; float step = Math::pow(10.0, Math::round(Math::log(scale / 5.0) / Math::log(10.0))) * 5.0; @@ -462,7 +463,7 @@ void AnimationBezierTrackEdit::_notification(int p_what) { iv -= 1; } if (!first && iv != prev_iv) { - Color lc = linecolor; + Color lc = h_line_color; lc.a *= 0.5; draw_line(Point2(limit, i), Point2(right_limit, i), lc, Math::round(EDSCALE)); Color c = color; @@ -475,8 +476,8 @@ void AnimationBezierTrackEdit::_notification(int p_what) { } } - { //draw OTHER curves - + // Draw other curves. + { float scale = timeline->get_zoom_scale(); Ref point = get_editor_theme_icon(SNAME("KeyValue")); for (const KeyValue &E : subtrack_colors) { @@ -498,12 +499,12 @@ void AnimationBezierTrackEdit::_notification(int p_what) { } if (track_count > 0 && !hidden_tracks.has(selected_track)) { - //draw edited curve + // Draw edited curve. _draw_track(selected_track, selected_track_color); } } - //draw editor handles + // Draw editor handles. { edit_points.clear(); float scale = timeline->get_zoom_scale(); @@ -644,12 +645,12 @@ bool AnimationBezierTrackEdit::_is_track_displayed(int p_track_index) { // Check if the curves for a track are displayed in the editor (not hidden). Includes the check on the track visibility. bool AnimationBezierTrackEdit::_is_track_curves_displayed(int p_track_index) { - //Is the track is visible in the editor? + // Is the track is visible in the editor? if (!_is_track_displayed(p_track_index)) { return false; } - //And curves visible? + // And curves visible? if (hidden_tracks.has(p_track_index)) { return false; } @@ -698,7 +699,7 @@ void AnimationBezierTrackEdit::_play_position_draw() { int px = (-timeline->get_value() + play_position_pos) * scale + limit; if (px >= limit && px < (get_size().width)) { - Color color = get_theme_color(SNAME("accent_color"), EditorStringName(Editor)); + const Color color = get_theme_color(SNAME("accent_color"), EditorStringName(Editor)); play_position->draw_line(Point2(px, 0), Point2(px, h), color, Math::round(2 * EDSCALE)); } } @@ -1218,7 +1219,7 @@ void AnimationBezierTrackEdit::gui_input(const Ref &p_event) { } } - //insert new point + // Insert new point. if (mb->get_position().x >= limit && mb->get_position().x < get_size().width && mb->is_command_or_control_pressed()) { float h = (get_size().height / 2.0 - mb->get_position().y) * timeline_v_zoom + timeline_v_scroll; Array new_point = animation->make_default_bezier_key(h); @@ -1234,7 +1235,7 @@ void AnimationBezierTrackEdit::gui_input(const Ref &p_event) { undo_redo->add_undo_method(animation.ptr(), "track_remove_key_at_time", selected_track, time); undo_redo->commit_action(); - //then attempt to move + // Then attempt to move. int index = animation->track_find_key(selected_track, time, Animation::FIND_MODE_APPROX); ERR_FAIL_COND(index == -1); _clear_selection(); @@ -1252,7 +1253,7 @@ void AnimationBezierTrackEdit::gui_input(const Ref &p_event) { return; } - //box select + // Box select. if (mb->get_position().x >= limit && mb->get_position().x < get_size().width) { box_selecting_attempt = true; box_selecting = false; @@ -1264,7 +1265,7 @@ void AnimationBezierTrackEdit::gui_input(const Ref &p_event) { if (box_selecting_attempt && mb.is_valid() && !mb->is_pressed() && mb->get_button_index() == MouseButton::LEFT) { if (box_selecting) { - //do actual select + // Do actual select. if (!box_selecting_add) { _clear_selection(); } @@ -1292,13 +1293,13 @@ void AnimationBezierTrackEdit::gui_input(const Ref &p_event) { } } } else { - _clear_selection(); //clicked and nothing happened, so clear the selection + _clear_selection(); // Clicked and nothing happened, so clear the selection. - //select by clicking on curve + // Select by clicking on curve. int track_count = animation->get_track_count(); real_t animation_length = animation->get_length(); - animation->set_length(real_t(INT_MAX)); //bezier_track_interpolate doesn't find keys if they exist beyond anim length + animation->set_length(real_t(INT_MAX)); // bezier_track_interpolate doesn't find keys if they exist beyond anim length. real_t time = ((mb->get_position().x - limit) / timeline->get_zoom_scale()) + timeline->get_value(); @@ -1334,11 +1335,11 @@ void AnimationBezierTrackEdit::gui_input(const Ref &p_event) { List to_restore; List to_restore_handle_modes; - // 1-remove the keys + // 1 - Remove the keys. for (SelectionSet::Element *E = selection.back(); E; E = E->prev()) { undo_redo->add_do_method(animation.ptr(), "track_remove_key", E->get().first, E->get().second); } - // 2- remove overlapped keys + // 2 - Remove overlapped keys. for (SelectionSet::Element *E = selection.back(); E; E = E->prev()) { real_t newtime = animation->track_get_key_time(E->get().first, E->get().second) + moving_selection_offset.x; @@ -1348,7 +1349,7 @@ void AnimationBezierTrackEdit::gui_input(const Ref &p_event) { } if (selection.has(IntPair(E->get().first, idx))) { - continue; //already in selection, don't save + continue; // Already in selection, don't save. } undo_redo->add_do_method(animation.ptr(), "track_remove_key_at_time", E->get().first, newtime); @@ -1362,7 +1363,7 @@ void AnimationBezierTrackEdit::gui_input(const Ref &p_event) { to_restore_handle_modes.push_back(animation->bezier_track_get_key_handle_mode(E->get().first, idx)); } - // 3-move the keys (re insert them) + // 3 - Move the keys (re-insert them). for (SelectionSet::Element *E = selection.back(); E; E = E->prev()) { real_t newpos = animation->track_get_key_time(E->get().first, E->get().second) + moving_selection_offset.x; Array key = animation->track_get_key_value(E->get().first, E->get().second); @@ -1381,13 +1382,13 @@ void AnimationBezierTrackEdit::gui_input(const Ref &p_event) { animation->bezier_track_get_key_handle_mode(E->get().first, E->get().second)); } - // 4-(undo) remove inserted keys + // 4 - (undo) Remove inserted keys. for (SelectionSet::Element *E = selection.back(); E; E = E->prev()) { real_t newpos = animation->track_get_key_time(E->get().first, E->get().second) + moving_selection_offset.x; undo_redo->add_undo_method(animation.ptr(), "track_remove_key_at_time", E->get().first, newpos); } - // 5-(undo) reinsert keys + // 5 - (undo) Reinsert keys. for (SelectionSet::Element *E = selection.back(); E; E = E->prev()) { real_t oldpos = animation->track_get_key_time(E->get().first, E->get().second); Array key = animation->track_get_key_value(E->get().first, E->get().second); @@ -1403,7 +1404,7 @@ void AnimationBezierTrackEdit::gui_input(const Ref &p_event) { animation->bezier_track_get_key_handle_mode(E->get().first, E->get().second)); } - // 6-(undo) reinsert overlapped keys + // 6 - (undo) Reinsert overlapped keys. List::ConstIterator restore_itr = to_restore.begin(); List::ConstIterator handle_itr = to_restore_handle_modes.begin(); for (; restore_itr != to_restore.end() && handle_itr != to_restore_handle_modes.end(); ++restore_itr, ++handle_itr) { @@ -1425,7 +1426,7 @@ void AnimationBezierTrackEdit::gui_input(const Ref &p_event) { undo_redo->add_do_method(this, "_clear_selection_for_anim", animation); undo_redo->add_undo_method(this, "_clear_selection_for_anim", animation); - // 7-reselect + // 7 - Reselect. int i = 0; for (SelectionSet::Element *E = selection.back(); E; E = E->prev()) { real_t oldpos = animation->track_get_key_time(E->get().first, E->get().second); @@ -1491,7 +1492,7 @@ void AnimationBezierTrackEdit::gui_input(const Ref &p_event) { box_selection_to = mm->get_position(); if (get_local_mouse_position().y < 0) { - //avoid cursor from going too above, so it does not lose focus with viewport + // Avoid cursor from going too above, so it does not lose focus with viewport. warp_mouse(Vector2(get_local_mouse_position().x, 0)); } queue_redraw(); diff --git a/editor/animation_track_editor.cpp b/editor/animation_track_editor.cpp index c59c9379055..1f0ad134513 100644 --- a/editor/animation_track_editor.cpp +++ b/editor/animation_track_editor.cpp @@ -1376,14 +1376,16 @@ void AnimationTimelineEdit::_anim_loop_pressed() { } int AnimationTimelineEdit::get_buttons_width() const { - Ref interp_mode = get_editor_theme_icon(SNAME("TrackContinuous")); - Ref interp_type = get_editor_theme_icon(SNAME("InterpRaw")); - Ref loop_type = get_editor_theme_icon(SNAME("InterpWrapClamp")); - Ref remove_icon = get_editor_theme_icon(SNAME("Remove")); - Ref down_icon = get_theme_icon(SNAME("select_arrow"), SNAME("Tree")); + const Ref interp_mode = get_editor_theme_icon(SNAME("TrackContinuous")); + const Ref interp_type = get_editor_theme_icon(SNAME("InterpRaw")); + const Ref loop_type = get_editor_theme_icon(SNAME("InterpWrapClamp")); + const Ref remove_icon = get_editor_theme_icon(SNAME("Remove")); + const Ref down_icon = get_theme_icon(SNAME("select_arrow"), SNAME("Tree")); + + const int h_separation = get_theme_constant(SNAME("h_separation"), SNAME("AnimationTrackEdit")); int total_w = interp_mode->get_width() + interp_type->get_width() + loop_type->get_width() + remove_icon->get_width(); - total_w += (down_icon->get_width() + 4 * EDSCALE) * 4; + total_w += (down_icon->get_width() + h_separation) * 4; return total_w; } @@ -1391,7 +1393,7 @@ int AnimationTimelineEdit::get_buttons_width() const { int AnimationTimelineEdit::get_name_limit() const { Ref hsize_icon = get_editor_theme_icon(SNAME("Hsize")); - int limit = MAX(name_limit, add_track->get_minimum_size().width + hsize_icon->get_width()); + int limit = MAX(name_limit, add_track->get_minimum_size().width + hsize_icon->get_width() + 8 * EDSCALE); limit = MIN(limit, get_size().width - get_buttons_width() - 1); @@ -1436,9 +1438,24 @@ void AnimationTimelineEdit::_notification(int p_what) { return; } - Ref font = get_theme_font(SceneStringName(font), SNAME("Label")); - int font_size = get_theme_font_size(SceneStringName(font_size), SNAME("Label")); - Color color = get_theme_color(SceneStringName(font_color), SNAME("Label")); + const Ref font = get_theme_font(SceneStringName(font), SNAME("Label")); + const int font_size = get_theme_font_size(SceneStringName(font_size), SNAME("Label")); + + const Ref &stylebox_time_unavailable = get_theme_stylebox(SNAME("time_unavailable"), SNAME("AnimationTimelineEdit")); + const Ref &stylebox_time_available = get_theme_stylebox(SNAME("time_available"), SNAME("AnimationTimelineEdit")); + + const Color v_line_primary_color = get_theme_color(SNAME("v_line_primary_color"), SNAME("AnimationTimelineEdit")); + const Color v_line_secondary_color = get_theme_color(SNAME("v_line_secondary_color"), SNAME("AnimationTimelineEdit")); + const Color h_line_color = get_theme_color(SNAME("h_line_color"), SNAME("AnimationTimelineEdit")); + const Color font_primary_color = get_theme_color(SNAME("font_primary_color"), SNAME("AnimationTimelineEdit")); + const Color font_secondary_color = get_theme_color(SNAME("font_secondary_color"), SNAME("AnimationTimelineEdit")); + + const int v_line_primary_margin = get_theme_constant(SNAME("v_line_primary_margin"), SNAME("AnimationTimelineEdit")); + const int v_line_secondary_margin = get_theme_constant(SNAME("v_line_secondary_margin"), SNAME("AnimationTimelineEdit")); + const int v_line_primary_width = get_theme_constant(SNAME("v_line_primary_width"), SNAME("AnimationTimelineEdit")); + const int v_line_secondary_width = get_theme_constant(SNAME("v_line_secondary_width"), SNAME("AnimationTimelineEdit")); + 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; float scale = get_zoom_scale(); @@ -1450,7 +1467,7 @@ void AnimationTimelineEdit::_notification(int p_what) { } Ref hsize_icon = get_editor_theme_icon(SNAME("Hsize")); - hsize_rect = Rect2(get_name_limit() - hsize_icon->get_width() - 2 * EDSCALE, (get_size().height - hsize_icon->get_height()) / 2, hsize_icon->get_width(), hsize_icon->get_height()); + hsize_rect = Rect2(get_name_limit() - hsize_icon->get_width() - 8 * EDSCALE, (get_size().height - hsize_icon->get_height()) / 2, hsize_icon->get_width(), hsize_icon->get_height()); draw_texture(hsize_icon, hsize_rect.position); { @@ -1495,14 +1512,9 @@ void AnimationTimelineEdit::_notification(int p_what) { int end_px = (l - get_value()) * scale; int begin_px = -get_value() * scale; - Color notimecol = get_theme_color(SNAME("dark_color_2"), EditorStringName(Editor)); - Color timecolor = color; - timecolor.a = 0.2; - Color linecolor = color; - linecolor.a = 0.2; { - draw_rect(Rect2(Point2(get_name_limit(), 0), Point2(zoomw - 1, h)), notimecol); + 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) { @@ -1512,13 +1524,9 @@ void AnimationTimelineEdit::_notification(int p_what) { end_px = zoomw; } - draw_rect(Rect2(Point2(get_name_limit() + begin_px, 0), Point2(end_px - begin_px, h)), timecolor); + draw_style_box(stylebox_time_available, Rect2(Point2(get_name_limit() + begin_px, 0), Point2(end_px - begin_px, h))); } } - - Color color_time_sec = color; - Color color_time_dec = color; - color_time_dec.a *= 0.5; #define SC_ADJ 100 int dec = 1; int step = 1; @@ -1573,10 +1581,17 @@ void AnimationTimelineEdit::_notification(int p_what) { bool sub = Math::floor(prev) == Math::floor(pos); if (frame != prev_frame && i >= prev_frame_ofs) { - draw_line(Point2(get_name_limit() + i, 0), Point2(get_name_limit() + i, h), linecolor, Math::round(EDSCALE)); + int line_margin = sub ? v_line_secondary_margin : v_line_primary_margin; + int line_width = sub ? v_line_secondary_width : v_line_primary_width; + Color line_color = sub ? v_line_secondary_color : v_line_primary_color; - draw_string(font, Point2(get_name_limit() + i + 3 * EDSCALE, (h - font->get_height(font_size)) / 2 + font->get_ascent(font_size)).floor(), itos(frame), HORIZONTAL_ALIGNMENT_LEFT, zoomw - i, font_size, sub ? color_time_dec : color_time_sec); - prev_frame_ofs = i + font->get_string_size(itos(frame), HORIZONTAL_ALIGNMENT_LEFT, -1, font_size).x + 5 * EDSCALE; + draw_line(Point2(get_name_limit() + i, 0 + line_margin), Point2(get_name_limit() + i, h - line_margin), line_color, line_width); + + int text_margin = sub ? text_secondary_margin : text_primary_margin; + + draw_string(font, Point2(get_name_limit() + i + text_margin, (h - font->get_height(font_size)) / 2 + font->get_ascent(font_size)).floor(), itos(frame), HORIZONTAL_ALIGNMENT_LEFT, zoomw - i, font_size, sub ? font_secondary_color : font_primary_color); + + prev_frame_ofs = i + font->get_string_size(itos(frame), HORIZONTAL_ALIGNMENT_LEFT, -1, font_size).x + text_margin; } } } @@ -1592,13 +1607,20 @@ void AnimationTimelineEdit::_notification(int p_what) { if ((sc / step) != (prev_sc / step) || (prev_sc < 0 && sc >= 0)) { int scd = sc < 0 ? prev_sc : sc; - draw_line(Point2(get_name_limit() + i, 0), Point2(get_name_limit() + i, h), linecolor, Math::round(EDSCALE)); - draw_string(font, Point2(get_name_limit() + i + 3, (h - font->get_height(font_size)) / 2 + font->get_ascent(font_size)).floor(), String::num((scd - (scd % step)) / double(SC_ADJ), decimals), HORIZONTAL_ALIGNMENT_LEFT, zoomw - i, font_size, sub ? color_time_dec : color_time_sec); + int line_margin = sub ? v_line_secondary_margin : v_line_primary_margin; + int line_width = sub ? v_line_secondary_width : v_line_primary_width; + Color line_color = sub ? v_line_secondary_color : v_line_primary_color; + + draw_line(Point2(get_name_limit() + i, 0 + line_margin), Point2(get_name_limit() + i, h - line_margin), line_color, line_width); + + int text_margin = sub ? text_secondary_margin : text_primary_margin; + + draw_string(font, Point2(get_name_limit() + i + text_margin, (h - font->get_height(font_size)) / 2 + font->get_ascent(font_size)).floor(), String::num((scd - (scd % step)) / double(SC_ADJ), decimals), HORIZONTAL_ALIGNMENT_LEFT, zoomw - i, font_size, sub ? font_secondary_color : font_primary_color); } } } - draw_line(Vector2(0, get_size().height), get_size(), linecolor, Math::round(EDSCALE)); + draw_line(Vector2(0, get_size().height), get_size(), h_line_color, Math::round(EDSCALE)); update_values(); } break; } @@ -1628,10 +1650,10 @@ void AnimationTimelineEdit::set_animation(const Ref &p_animation, boo Size2 AnimationTimelineEdit::get_minimum_size() const { Size2 ms = add_track->get_minimum_size(); - Ref font = get_theme_font(SceneStringName(font), SNAME("Label")); - int font_size = get_theme_font_size(SceneStringName(font_size), SNAME("Label")); + const Ref font = get_theme_font(SceneStringName(font), SNAME("Label")); + const int font_size = get_theme_font_size(SceneStringName(font_size), SNAME("Label")); ms.height = MAX(ms.height, font->get_height(font_size)); - ms.width = get_buttons_width() + add_track->get_minimum_size().width + get_editor_theme_icon(SNAME("Hsize"))->get_width() + 2; + ms.width = get_buttons_width() + add_track->get_minimum_size().width + get_editor_theme_icon(SNAME("Hsize"))->get_width() + 2 + 8 * EDSCALE; return ms; } @@ -1967,46 +1989,49 @@ void AnimationTrackEdit::_notification(int p_what) { int limit = timeline->get_name_limit(); + const Ref &stylebox_odd = get_theme_stylebox(SNAME("odd"), SNAME("AnimationTrackEdit")); + const Ref &stylebox_focus = get_theme_stylebox(SNAME("focus"), SNAME("AnimationTrackEdit")); + const Ref &stylebox_hover = get_theme_stylebox(SNAME("hover"), SNAME("AnimationTrackEdit")); + + const Color h_line_color = get_theme_color(SNAME("h_line_color"), SNAME("AnimationTrackEdit")); + const int h_separation = get_theme_constant(SNAME("h_separation"), SNAME("AnimationTrackEdit")); + const int outer_margin = get_theme_constant(SNAME("outer_margin"), SNAME("AnimationTrackEdit")); + if (track % 2 == 1) { // Draw a background over odd lines to make long lists of tracks easier to read. - draw_rect(Rect2(Point2(1 * EDSCALE, 0), get_size() - Size2(1 * EDSCALE, 0)), Color(0.5, 0.5, 0.5, 0.05)); + draw_style_box(stylebox_odd, Rect2(Point2(1 * EDSCALE, 0), get_size() - Size2(1 * EDSCALE, 0))); } if (hovered) { // Draw hover feedback. - draw_rect(Rect2(Point2(1 * EDSCALE, 0), get_size() - Size2(1 * EDSCALE, 0)), Color(0.5, 0.5, 0.5, 0.1)); + draw_style_box(stylebox_hover, Rect2(Point2(1 * EDSCALE, 0), get_size() - Size2(1 * EDSCALE, 0))); } if (has_focus()) { - Color accent = get_theme_color(SNAME("accent_color"), EditorStringName(Editor)); - accent.a *= 0.7; // Offside so the horizontal sides aren't cutoff. - draw_style_box(get_theme_stylebox(SNAME("Focus"), EditorStringName(EditorStyles)), Rect2(Point2(1 * EDSCALE, 0), get_size() - Size2(1 * EDSCALE, 0))); + draw_style_box(stylebox_focus, Rect2(Point2(1 * EDSCALE, 0), get_size() - Size2(1 * EDSCALE, 0))); } - Ref font = get_theme_font(SceneStringName(font), SNAME("Label")); - int font_size = get_theme_font_size(SceneStringName(font_size), SNAME("Label")); - Color color = get_theme_color(SceneStringName(font_color), SNAME("Label")); - int hsep = get_theme_constant(SNAME("h_separation"), SNAME("ItemList")); - Color linecolor = color; - linecolor.a = 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")); - Color dc = get_theme_color(SNAME("font_disabled_color"), EditorStringName(Editor)); + const Color dc = get_theme_color(SNAME("font_disabled_color"), EditorStringName(Editor)); - // NAMES AND ICONS // + // Names and icons. { Ref check = animation->track_is_enabled(track) ? get_theme_icon(SNAME("checked"), SNAME("CheckBox")) : get_theme_icon(SNAME("unchecked"), SNAME("CheckBox")); - int ofs = in_group ? check->get_width() : 0; // Not the best reference for margin but.. + int ofs = in_group ? outer_margin : 0; - check_rect = Rect2(Point2(ofs, int(get_size().height - check->get_height()) / 2), check->get_size()); + check_rect = Rect2(Point2(ofs, (get_size().height - check->get_height()) / 2).round(), check->get_size()); draw_texture(check, check_rect.position); - ofs += check->get_width() + hsep; + ofs += check->get_width() + h_separation; Ref key_type_icon = _get_key_type_icon(); - draw_texture(key_type_icon, Point2(ofs, int(get_size().height - key_type_icon->get_height()) / 2)); - ofs += key_type_icon->get_width() + hsep; + draw_texture(key_type_icon, Point2(ofs, (get_size().height - key_type_icon->get_height()) / 2).round()); + ofs += key_type_icon->get_width() + h_separation; NodePath anim_path = animation->track_get_path(track); Node *node = nullptr; @@ -2035,11 +2060,11 @@ void AnimationTrackEdit::_notification(int p_what) { Ref icon = EditorNode::get_singleton()->get_object_icon(node, "Node"); const Vector2 icon_size = Vector2(1, 1) * get_theme_constant(SNAME("class_icon_size"), EditorStringName(Editor)); - draw_texture_rect(icon, Rect2(Point2(ofs, int(get_size().height - icon_size.y) / 2), icon_size)); + draw_texture_rect(icon, Rect2(Point2(ofs, (get_size().height - icon_size.y) / 2).round(), icon_size)); icon_cache = icon; text = String() + node->get_name() + ":" + anim_path.get_concatenated_subnames(); - ofs += hsep; + ofs += h_separation; ofs += icon_size.x; } else { @@ -2050,22 +2075,22 @@ void AnimationTrackEdit::_notification(int p_what) { path_cache = text; - path_rect = Rect2(ofs, 0, limit - ofs - hsep, get_size().height); + path_rect = Rect2(ofs, 0, limit - ofs - h_separation, get_size().height); Vector2 string_pos = Point2(ofs, (get_size().height - font->get_height(font_size)) / 2 + font->get_ascent(font_size)); string_pos = string_pos.floor(); - draw_string(font, string_pos, text, HORIZONTAL_ALIGNMENT_LEFT, limit - ofs - hsep, font_size, text_color); + draw_string(font, string_pos, text, HORIZONTAL_ALIGNMENT_LEFT, limit - ofs - h_separation, font_size, text_color); - draw_line(Point2(limit, 0), Point2(limit, get_size().height), linecolor, Math::round(EDSCALE)); + draw_line(Point2(limit, 0), Point2(limit, get_size().height), h_line_color, Math::round(EDSCALE)); } - // KEYFRAMES // + // Keyframes. - draw_bg(limit, get_size().width - timeline->get_buttons_width()); + draw_bg(limit, get_size().width - timeline->get_buttons_width() - outer_margin); { float scale = timeline->get_zoom_scale(); - int limit_end = get_size().width - timeline->get_buttons_width(); + 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(); @@ -2087,9 +2112,9 @@ void AnimationTrackEdit::_notification(int p_what) { } } - draw_fg(limit, get_size().width - timeline->get_buttons_width()); + draw_fg(limit, get_size().width - timeline->get_buttons_width() - outer_margin); - // BUTTONS // + // Buttons. { Ref wrap_icon[2] = { @@ -2113,13 +2138,13 @@ void AnimationTrackEdit::_notification(int p_what) { get_editor_theme_icon(SNAME("UseBlendDisable")), }; - int ofs = get_size().width - timeline->get_buttons_width(); + int ofs = get_size().width - timeline->get_buttons_width() - outer_margin; - Ref down_icon = get_theme_icon(SNAME("select_arrow"), SNAME("Tree")); + const Ref down_icon = get_theme_icon(SNAME("select_arrow"), SNAME("Tree")); - draw_line(Point2(ofs, 0), Point2(ofs, get_size().height), linecolor, Math::round(EDSCALE)); + draw_line(Point2(ofs, 0), Point2(ofs, get_size().height), h_line_color, Math::round(EDSCALE)); - ofs += hsep; + ofs += h_separation; { // Callmode. @@ -2134,7 +2159,7 @@ void AnimationTrackEdit::_notification(int p_what) { Ref update_icon = cont_icon[update_mode]; update_mode_rect.position.x = ofs; - update_mode_rect.position.y = int(get_size().height - update_icon->get_height()) / 2; + update_mode_rect.position.y = Math::round((get_size().height - update_icon->get_height()) / 2); update_mode_rect.size = update_icon->get_size(); if (!animation->track_is_compressed(track) && animation->track_get_type(track) == Animation::TYPE_VALUE) { @@ -2149,12 +2174,12 @@ void AnimationTrackEdit::_notification(int p_what) { update_mode_rect.position.y = 0; update_mode_rect.size.y = get_size().height; - ofs += update_icon->get_width() + hsep / 2; - update_mode_rect.size.x += hsep / 2; + ofs += update_icon->get_width() + h_separation / 2; + update_mode_rect.size.x += h_separation / 2; if (!read_only) { if (animation->track_get_type(track) == Animation::TYPE_VALUE || animation->track_get_type(track) == Animation::TYPE_AUDIO) { - draw_texture(down_icon, Vector2(ofs, int(get_size().height - down_icon->get_height()) / 2)); + draw_texture(down_icon, Vector2(ofs, (get_size().height - down_icon->get_height()) / 2).round()); update_mode_rect.size.x += down_icon->get_width(); } else if (animation->track_get_type(track) == Animation::TYPE_BEZIER) { update_mode_rect.size.x += down_icon->get_width(); @@ -2167,8 +2192,8 @@ void AnimationTrackEdit::_notification(int p_what) { } ofs += down_icon->get_width(); - draw_line(Point2(ofs + hsep * 0.5, 0), Point2(ofs + hsep * 0.5, get_size().height), linecolor, Math::round(EDSCALE)); - ofs += hsep; + draw_line(Point2(ofs + h_separation * 0.5, 0), Point2(ofs + h_separation * 0.5, get_size().height), h_line_color, Math::round(EDSCALE)); + ofs += h_separation; } { @@ -2179,7 +2204,7 @@ void AnimationTrackEdit::_notification(int p_what) { Ref icon = interp_icon[interp_mode]; interp_mode_rect.position.x = ofs; - interp_mode_rect.position.y = int(get_size().height - icon->get_height()) / 2; + interp_mode_rect.position.y = Math::round((get_size().height - icon->get_height()) / 2); interp_mode_rect.size = icon->get_size(); if (!animation->track_is_compressed(track) && (animation->track_get_type(track) == Animation::TYPE_VALUE || animation->track_get_type(track) == Animation::TYPE_BLEND_SHAPE || animation->track_get_type(track) == Animation::TYPE_POSITION_3D || animation->track_get_type(track) == Animation::TYPE_SCALE_3D || animation->track_get_type(track) == Animation::TYPE_ROTATION_3D)) { @@ -2189,19 +2214,19 @@ void AnimationTrackEdit::_notification(int p_what) { interp_mode_rect.position.y = 0; interp_mode_rect.size.y = get_size().height; - ofs += icon->get_width() + hsep / 2; - interp_mode_rect.size.x += hsep / 2; + ofs += icon->get_width() + h_separation / 2; + interp_mode_rect.size.x += h_separation / 2; if (!read_only && !animation->track_is_compressed(track) && (animation->track_get_type(track) == Animation::TYPE_VALUE || animation->track_get_type(track) == Animation::TYPE_BLEND_SHAPE || animation->track_get_type(track) == Animation::TYPE_POSITION_3D || animation->track_get_type(track) == Animation::TYPE_SCALE_3D || animation->track_get_type(track) == Animation::TYPE_ROTATION_3D)) { - draw_texture(down_icon, Vector2(ofs, int(get_size().height - down_icon->get_height()) / 2)); + draw_texture(down_icon, Vector2(ofs, (get_size().height - down_icon->get_height()) / 2).round()); interp_mode_rect.size.x += down_icon->get_width(); } else { interp_mode_rect = Rect2(); } ofs += down_icon->get_width(); - draw_line(Point2(ofs + hsep * 0.5, 0), Point2(ofs + hsep * 0.5, get_size().height), linecolor, Math::round(EDSCALE)); - ofs += hsep; + draw_line(Point2(ofs + h_separation * 0.5, 0), Point2(ofs + h_separation * 0.5, get_size().height), h_line_color, Math::round(EDSCALE)); + ofs += h_separation; } { @@ -2212,7 +2237,7 @@ void AnimationTrackEdit::_notification(int p_what) { Ref icon = wrap_icon[loop_wrap ? 1 : 0]; loop_wrap_rect.position.x = ofs; - loop_wrap_rect.position.y = int(get_size().height - icon->get_height()) / 2; + loop_wrap_rect.position.y = Math::round((get_size().height - icon->get_height()) / 2); loop_wrap_rect.size = icon->get_size(); if (!animation->track_is_compressed(track) && (animation->track_get_type(track) == Animation::TYPE_VALUE || animation->track_get_type(track) == Animation::TYPE_BLEND_SHAPE || animation->track_get_type(track) == Animation::TYPE_POSITION_3D || animation->track_get_type(track) == Animation::TYPE_SCALE_3D || animation->track_get_type(track) == Animation::TYPE_ROTATION_3D)) { @@ -2222,19 +2247,19 @@ void AnimationTrackEdit::_notification(int p_what) { loop_wrap_rect.position.y = 0; loop_wrap_rect.size.y = get_size().height; - ofs += icon->get_width() + hsep / 2; - loop_wrap_rect.size.x += hsep / 2; + ofs += icon->get_width() + h_separation / 2; + loop_wrap_rect.size.x += h_separation / 2; if (!read_only && !animation->track_is_compressed(track) && (animation->track_get_type(track) == Animation::TYPE_VALUE || animation->track_get_type(track) == Animation::TYPE_BLEND_SHAPE || animation->track_get_type(track) == Animation::TYPE_POSITION_3D || animation->track_get_type(track) == Animation::TYPE_SCALE_3D || animation->track_get_type(track) == Animation::TYPE_ROTATION_3D)) { - draw_texture(down_icon, Vector2(ofs, int(get_size().height - down_icon->get_height()) / 2)); + draw_texture(down_icon, Vector2(ofs, (get_size().height - down_icon->get_height()) / 2).round()); loop_wrap_rect.size.x += down_icon->get_width(); } else { loop_wrap_rect = Rect2(); } ofs += down_icon->get_width(); - draw_line(Point2(ofs + hsep * 0.5, 0), Point2(ofs + hsep * 0.5, get_size().height), linecolor, Math::round(EDSCALE)); - ofs += hsep; + draw_line(Point2(ofs + h_separation * 0.5, 0), Point2(ofs + h_separation * 0.5, get_size().height), h_line_color, Math::round(EDSCALE)); + ofs += h_separation; } { @@ -2242,8 +2267,8 @@ void AnimationTrackEdit::_notification(int p_what) { Ref icon = get_editor_theme_icon(animation->track_is_compressed(track) ? SNAME("Lock") : SNAME("Remove")); - remove_rect.position.x = ofs + ((get_size().width - ofs) - icon->get_width()); - remove_rect.position.y = int(get_size().height - icon->get_height()) / 2; + remove_rect.position.x = ofs + ((get_size().width - ofs) - icon->get_width()) - outer_margin; + remove_rect.position.y = Math::round((get_size().height - icon->get_height()) / 2); remove_rect.size = icon->get_size(); if (read_only) { @@ -2255,9 +2280,9 @@ void AnimationTrackEdit::_notification(int p_what) { } if (in_group) { - draw_line(Vector2(timeline->get_name_limit(), get_size().height), get_size(), linecolor, Math::round(EDSCALE)); + draw_line(Vector2(timeline->get_name_limit(), get_size().height), get_size(), h_line_color, Math::round(EDSCALE)); } else { - draw_line(Vector2(0, get_size().height), get_size(), linecolor, Math::round(EDSCALE)); + draw_line(Vector2(0, get_size().height), get_size(), h_line_color, Math::round(EDSCALE)); } if (dropping_at != 0) { @@ -2358,11 +2383,11 @@ void AnimationTrackEdit::draw_key(int p_index, float p_pixels_sec, int p_x, bool } } - Vector2 ofs(p_x - icon_to_draw->get_width() / 2, int(get_size().height - icon_to_draw->get_height()) / 2); + Vector2 ofs(p_x - icon_to_draw->get_width() / 2, (get_size().height - icon_to_draw->get_height()) / 2); if (animation->track_get_type(track) == Animation::TYPE_METHOD) { - Ref font = get_theme_font(SceneStringName(font), SNAME("Label")); - int font_size = get_theme_font_size(SceneStringName(font_size), SNAME("Label")); + const Ref font = get_theme_font(SceneStringName(font), SNAME("Label")); + const int font_size = get_theme_font_size(SceneStringName(font_size), SNAME("Label")); Color color = get_theme_color(SceneStringName(font_color), SNAME("Label")); color.a = 0.5; @@ -2486,9 +2511,9 @@ NodePath AnimationTrackEdit::get_path() const { Size2 AnimationTrackEdit::get_minimum_size() const { Ref texture = get_editor_theme_icon(SNAME("Object")); - Ref font = get_theme_font(SceneStringName(font), SNAME("Label")); - int font_size = get_theme_font_size(SceneStringName(font_size), SNAME("Label")); - int separation = get_theme_constant(SNAME("v_separation"), SNAME("ItemList")); + const Ref font = get_theme_font(SceneStringName(font), SNAME("Label")); + const int font_size = get_theme_font_size(SceneStringName(font_size), SNAME("Label")); + const int separation = get_theme_constant(SNAME("v_separation"), SNAME("ItemList")); int max_h = MAX(texture->get_height(), font->get_height(font_size)); max_h = MAX(max_h, get_key_height()); @@ -2977,7 +3002,7 @@ void AnimationTrackEdit::gui_input(const Ref &p_event) { } path->set_text(animation->track_get_path(track)); - Vector2 theme_ofs = path->get_theme_stylebox(CoreStringName(normal), SNAME("LineEdit"))->get_offset(); + const Vector2 theme_ofs = path->get_theme_stylebox(CoreStringName(normal), SNAME("LineEdit"))->get_offset(); moving_selection_attempt = false; moving_selection = false; @@ -3419,11 +3444,19 @@ void AnimationTrackEditGroup::_notification(int p_what) { } break; case NOTIFICATION_DRAW: { - Ref font = get_theme_font(SceneStringName(font), SNAME("Label")); - int font_size = get_theme_font_size(SceneStringName(font_size), SNAME("Label")); - int separation = get_theme_constant(SNAME("h_separation"), SNAME("ItemList")); + const Ref font = get_theme_font(SceneStringName(font), SNAME("Label")); + const int font_size = get_theme_font_size(SceneStringName(font_size), SNAME("Label")); 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")); + const Color v_line_color = get_theme_color(SNAME("v_line_color"), SNAME("AnimationTrackEditGroup")); + const int h_separation = get_theme_constant(SNAME("h_separation"), SNAME("AnimationTrackEditGroup")); + if (root) { Node *n = root->get_node_or_null(node); if (n && EditorNode::get_singleton()->get_editor_selection()->is_selected(n)) { @@ -3431,25 +3464,21 @@ void AnimationTrackEditGroup::_notification(int p_what) { } } - Color bgcol = get_theme_color(SNAME("dark_color_2"), EditorStringName(Editor)); - bgcol.a *= 0.6; - draw_rect(Rect2(Point2(), get_size()), bgcol); - Color linecolor = color; - linecolor.a = 0.2; + draw_style_box(stylebox_header, Rect2(Point2(), get_size())); - draw_line(Point2(), Point2(get_size().width, 0), linecolor, Math::round(EDSCALE)); - draw_line(Point2(timeline->get_name_limit(), 0), Point2(timeline->get_name_limit(), get_size().height), linecolor, 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), linecolor, 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)); - int ofs = 0; - draw_texture_rect(icon, Rect2(Point2(ofs, int(get_size().height - icon_size.y) / 2), icon_size)); - ofs += separation + icon_size.x; - draw_string(font, Point2(ofs, int(get_size().height - font->get_height(font_size)) / 2 + font->get_ascent(font_size)), node_name, HORIZONTAL_ALIGNMENT_LEFT, timeline->get_name_limit() - ofs, font_size, color); + 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)); + ofs += h_separation + icon_size.x; + 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())) { - Color accent = get_theme_color(SNAME("accent_color"), EditorStringName(Editor)); + 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)); } } break; @@ -3484,11 +3513,14 @@ void AnimationTrackEditGroup::set_type_and_name(const Ref &p_type, co } Size2 AnimationTrackEditGroup::get_minimum_size() const { - Ref font = get_theme_font(SceneStringName(font), SNAME("Label")); - int font_size = get_theme_font_size(SceneStringName(font_size), SNAME("Label")); - int separation = get_theme_constant(SNAME("v_separation"), SNAME("ItemList")); + const Ref font = get_theme_font(SceneStringName(font), SNAME("Label")); + const int font_size = get_theme_font_size(SceneStringName(font_size), SNAME("Label")); + const int separation = get_theme_constant(SNAME("v_separation"), SNAME("ItemList")); - return Vector2(0, MAX(font->get_height(font_size), icon_size.y) + separation); + const Ref &header_style = get_theme_stylebox(SNAME("header"), SNAME("AnimationTrackEditGroup")); + const int content_margin = header_style->get_content_margin(SIDE_TOP) + header_style->get_content_margin(SIDE_BOTTOM); + + return Vector2(0, MAX(font->get_height(font_size), icon_size.y) + separation + content_margin); } void AnimationTrackEditGroup::set_timeline(AnimationTimelineEdit *p_timeline) { @@ -4891,6 +4923,12 @@ void AnimationTrackEditor::_notification(int p_what) { edit->get_popup()->set_item_icon(edit->get_popup()->get_item_index(EDIT_APPLY_RESET), get_editor_theme_icon(SNAME("Reload"))); auto_fit->set_icon(get_editor_theme_icon(SNAME("AnimationAutoFit"))); auto_fit_bezier->set_icon(get_editor_theme_icon(SNAME("AnimationAutoFitBezier"))); + + const int timeline_separation = get_theme_constant(SNAME("timeline_v_separation"), SNAME("AnimationTrackEditor")); + timeline_vbox->add_theme_constant_override("separation", timeline_separation); + + const int track_separation = get_theme_constant(SNAME("track_v_separation"), SNAME("AnimationTrackEditor")); + track_vbox->add_theme_constant_override("separation", track_separation); } break; case NOTIFICATION_READY: { @@ -6389,7 +6427,7 @@ void AnimationTrackEditor::_edit_menu_pressed(int p_option) { undo_redo->add_do_method(this, "_clear_selection_for_anim", animation); undo_redo->add_undo_method(this, "_clear_selection_for_anim", animation); - // 7-reselect. + // 7 - Reselect. for (RBMap::Element *E = selection.back(); E; E = E->prev()) { float oldpos = E->get().pos; float newpos = NEW_POS(oldpos); @@ -7182,11 +7220,10 @@ AnimationTrackEditor::AnimationTrackEditor() { main_panel->add_child(timeline_scroll); timeline_scroll->set_v_size_flags(SIZE_EXPAND_FILL); - VBoxContainer *timeline_vbox = memnew(VBoxContainer); + timeline_vbox = memnew(VBoxContainer); timeline_scroll->add_child(timeline_vbox); timeline_vbox->set_v_size_flags(SIZE_EXPAND_FILL); timeline_vbox->set_h_size_flags(SIZE_EXPAND_FILL); - timeline_vbox->add_theme_constant_override("separation", 0); info_message = memnew(Label); info_message->set_text(TTR("Select an AnimationPlayer node to create and edit animations.")); @@ -7239,7 +7276,6 @@ AnimationTrackEditor::AnimationTrackEditor() { scroll->add_child(track_vbox); track_vbox->set_h_size_flags(SIZE_EXPAND_FILL); scroll->set_horizontal_scroll_mode(ScrollContainer::SCROLL_MODE_DISABLED); - track_vbox->add_theme_constant_override("separation", 0); HBoxContainer *bottom_hb = memnew(HBoxContainer); add_child(bottom_hb); @@ -7585,7 +7621,6 @@ AnimationTrackEditor::AnimationTrackEditor() { bake_grid->add_child(memnew(Label(TTR("FPS:")))); bake_grid->add_child(bake_fps); - // track_copy_dialog = memnew(ConfirmationDialog); add_child(track_copy_dialog); track_copy_dialog->set_title(TTR("Select Tracks to Copy")); @@ -7617,7 +7652,7 @@ AnimationTrackEditor::~AnimationTrackEditor() { } } -// AnimationTrackKeyEditEditorPlugin +// AnimationTrackKeyEditEditorPlugin. void AnimationTrackKeyEditEditor::_time_edit_entered() { int key = animation->track_find_key(track, key_ofs, Animation::FIND_MODE_APPROX); diff --git a/editor/animation_track_editor.h b/editor/animation_track_editor.h index 4c7c1a58f83..59ee6535ac2 100644 --- a/editor/animation_track_editor.h +++ b/editor/animation_track_editor.h @@ -400,6 +400,7 @@ class AnimationTrackEditor : public VBoxContainer { ScrollContainer *scroll = nullptr; VBoxContainer *track_vbox = nullptr; AnimationBezierTrackEdit *bezier_edit = nullptr; + VBoxContainer *timeline_vbox = nullptr; Label *info_message = nullptr; diff --git a/editor/themes/editor_theme_manager.cpp b/editor/themes/editor_theme_manager.cpp index b271970f219..9237a62a742 100644 --- a/editor/themes/editor_theme_manager.cpp +++ b/editor/themes/editor_theme_manager.cpp @@ -2233,6 +2233,71 @@ void EditorThemeManager::_populate_editor_styles(const Ref &p_theme p_theme->set_stylebox("DictionaryAddItem0", EditorStringName(EditorStyles), style_dictionary_add_item); } + // Animation Editor. + { + // Timeline general. + p_theme->set_constant("timeline_v_separation", "AnimationTrackEditor", 0); + p_theme->set_constant("track_v_separation", "AnimationTrackEditor", 0); + + // AnimationTimelineEdit. + // "primary" is used for integer timeline values, "secondary" for decimals. + + Ref style_time_unavailable = make_flat_stylebox(p_config.dark_color_2, 0, 0, 0, 0, 0); + Ref style_time_available = make_flat_stylebox(p_config.font_color * Color(1, 1, 1, 0.2), 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); + + p_theme->set_color("v_line_primary_color", "AnimationTimelineEdit", p_config.font_color * Color(1, 1, 1, 0.2)); + p_theme->set_color("v_line_secondary_color", "AnimationTimelineEdit", p_config.font_color * Color(1, 1, 1, 0.2)); + p_theme->set_color("h_line_color", "AnimationTimelineEdit", p_config.font_color * Color(1, 1, 1, 0.2)); + p_theme->set_color("font_primary_color", "AnimationTimelineEdit", p_config.font_color); + p_theme->set_color("font_secondary_color", "AnimationTimelineEdit", p_config.font_color * Color(1, 1, 1, 0.5)); + + p_theme->set_constant("v_line_primary_margin", "AnimationTimelineEdit", 0); + p_theme->set_constant("v_line_secondary_margin", "AnimationTimelineEdit", 0); + p_theme->set_constant("v_line_primary_width", "AnimationTimelineEdit", 1 * EDSCALE); + p_theme->set_constant("v_line_secondary_width", "AnimationTimelineEdit", 1 * EDSCALE); + p_theme->set_constant("text_primary_margin", "AnimationTimelineEdit", 3 * EDSCALE); + p_theme->set_constant("text_secondary_margin", "AnimationTimelineEdit", 3 * EDSCALE); + + // AnimationTrackEdit. + + Ref style_animation_track_odd = make_flat_stylebox(Color(0.5, 0.5, 0.5, 0.05), 0, 0, 0, 0, p_config.corner_radius); + Ref style_animation_track_hover = make_flat_stylebox(Color(0.5, 0.5, 0.5, 0.1), 0, 0, 0, 0, p_config.corner_radius); + + p_theme->set_stylebox("odd", "AnimationTrackEdit", style_animation_track_odd); + p_theme->set_stylebox("hover", "AnimationTrackEdit", style_animation_track_hover); + p_theme->set_stylebox("focus", "AnimationTrackEdit", p_config.button_style_focus); + + p_theme->set_color("h_line_color", "AnimationTrackEdit", p_config.font_color * Color(1, 1, 1, 0.2)); + + p_theme->set_constant("h_separation", "AnimationTrackEdit", (p_config.increased_margin + 2) * EDSCALE); + p_theme->set_constant("outer_margin", "AnimationTrackEdit", p_config.increased_margin * 6 * EDSCALE); + + // AnimationTrackEditGroup. + + Ref style_animation_track_header = make_flat_stylebox(p_config.dark_color_2 * Color(1, 1, 1, 0.6), p_config.increased_margin * 3, 0, 0, 0, p_config.corner_radius); + + p_theme->set_stylebox("header", "AnimationTrackEditGroup", style_animation_track_header); + + p_theme->set_color("h_line_color", "AnimationTrackEditGroup", p_config.font_color * Color(1, 1, 1, 0.2)); + p_theme->set_color("v_line_color", "AnimationTrackEditGroup", p_config.font_color * Color(1, 1, 1, 0.2)); + + p_theme->set_constant("h_separation", "AnimationTrackEditGroup", (p_config.increased_margin + 2) * EDSCALE); + p_theme->set_constant("v_separation", "AnimationTrackEditGroup", 0); + + // AnimationBezierTrackEdit. + + p_theme->set_color("focus_color", "AnimationBezierTrackEdit", p_config.accent_color * Color(1, 1, 1, 0.7)); + p_theme->set_color("track_focus_color", "AnimationBezierTrackEdit", p_config.accent_color * Color(1, 1, 1, 0.5)); + p_theme->set_color("h_line_color", "AnimationBezierTrackEdit", p_config.font_color * Color(1, 1, 1, 0.2)); + p_theme->set_color("v_line_color", "AnimationBezierTrackEdit", p_config.font_color * Color(1, 1, 1, 0.2)); + + p_theme->set_constant("h_separation", "AnimationBezierTrackEdit", (p_config.increased_margin + 2) * EDSCALE); + p_theme->set_constant("v_separation", "AnimationBezierTrackEdit", p_config.forced_even_separation * EDSCALE); + } + // Editor help. { Ref style_editor_help = p_config.base_style->duplicate();