diff options
Diffstat (limited to 'editor')
-rw-r--r-- | editor/code_editor.cpp | 263 | ||||
-rw-r--r-- | editor/plugins/animation_player_editor_plugin.cpp | 4 | ||||
-rw-r--r-- | editor/plugins/node_3d_editor_plugin.cpp | 16 | ||||
-rw-r--r-- | editor/plugins/node_3d_editor_plugin.h | 2 | ||||
-rw-r--r-- | editor/shader_globals_editor.cpp | 43 |
5 files changed, 179 insertions, 149 deletions
diff --git a/editor/code_editor.cpp b/editor/code_editor.cpp index 65cb083ac7..926c01b334 100644 --- a/editor/code_editor.cpp +++ b/editor/code_editor.cpp @@ -33,6 +33,7 @@ #include "core/input/input.h" #include "core/os/keyboard.h" #include "core/string/string_builder.h" +#include "core/templates/pair.h" #include "editor/editor_scale.h" #include "editor/editor_settings.h" #include "editor/plugins/script_editor_plugin.h" @@ -1290,90 +1291,98 @@ void CodeTextEditor::convert_case(CaseStyle p_case) { void CodeTextEditor::move_lines_up() { text_editor->begin_complex_operation(); - Vector<int> carets_to_remove; - Vector<int> caret_edit_order = text_editor->get_caret_index_edit_order(); + + // Lists of carets representing each group + Vector<Vector<int>> caret_groups; + Vector<Pair<int, int>> group_borders; + + // Search for groups of carets and their selections residing on the same lines for (int i = 0; i < caret_edit_order.size(); i++) { int c = caret_edit_order[i]; - int cl = text_editor->get_caret_line(c); - bool swaped_caret = false; - for (int j = i + 1; j < caret_edit_order.size(); j++) { - if (text_editor->has_selection(caret_edit_order[j])) { - if (text_editor->get_selection_from_line() == cl) { - carets_to_remove.push_back(caret_edit_order[j]); - continue; - } + Vector<int> new_group{ c }; + Pair<int, int> group_border; + if (text_editor->has_selection(c)) { + group_border.first = text_editor->get_selection_from_line(c); + group_border.second = text_editor->get_selection_to_line(c); + } else { + group_border.first = text_editor->get_caret_line(c); + group_border.second = text_editor->get_caret_line(c); + } - if (text_editor->get_selection_to_line() == cl) { - if (text_editor->has_selection(c)) { - if (text_editor->get_selection_to_line(c) != cl) { - text_editor->select(cl + 1, 0, text_editor->get_selection_to_line(c), text_editor->get_selection_to_column(c), c); - break; - } - } + for (int j = i; j < caret_edit_order.size() - 1; j++) { + int c_current = caret_edit_order[j]; + int c_next = caret_edit_order[j + 1]; - carets_to_remove.push_back(c); - i = j - 1; - swaped_caret = true; - break; - } + int next_start_pos = text_editor->has_selection(c_next) ? text_editor->get_selection_from_line(c_next) : text_editor->get_caret_line(c_next); + int next_end_pos = text_editor->has_selection(c_next) ? text_editor->get_selection_to_line(c_next) : text_editor->get_caret_line(c_next); + + int current_start_pos = text_editor->has_selection(c_current) ? text_editor->get_selection_from_line(c_current) : text_editor->get_caret_line(c_current); + + i = j; + if (next_end_pos != current_start_pos && next_end_pos + 1 != current_start_pos) { break; } - - if (text_editor->get_caret_line(caret_edit_order[j]) == cl) { - carets_to_remove.push_back(caret_edit_order[j]); - i = j; - continue; + group_border.first = next_start_pos; + new_group.push_back(c_next); + // If the last caret is added to the current group there is no need to process it again + if (j + 1 == caret_edit_order.size() - 1) { + i++; } - break; } + group_borders.push_back(group_border); + caret_groups.push_back(new_group); + } - if (swaped_caret) { + for (int i = group_borders.size() - 1; i >= 0; i--) { + if (group_borders[i].first - 1 < 0) { continue; } - if (text_editor->has_selection(c)) { + // If the group starts overlapping with the upper group don't move it + if (i < group_borders.size() - 1 && group_borders[i].first - 1 <= group_borders[i + 1].second) { + continue; + } + + // We have to remember caret positions and selections prior to line swapping + Vector<Vector<int>> caret_group_parameters; + + for (int j = 0; j < caret_groups[i].size(); j++) { + int c = caret_groups[i][j]; + int cursor_line = text_editor->get_caret_line(c); + int cursor_column = text_editor->get_caret_column(c); + + if (!text_editor->has_selection(c)) { + caret_group_parameters.push_back(Vector<int>{ -1, -1, -1, -1, cursor_line, cursor_column }); + continue; + } int from_line = text_editor->get_selection_from_line(c); int from_col = text_editor->get_selection_from_column(c); int to_line = text_editor->get_selection_to_line(c); int to_column = text_editor->get_selection_to_column(c); - int cursor_line = text_editor->get_caret_line(c); - - for (int j = from_line; j <= to_line; j++) { - int line_id = j; - int next_id = j - 1; + caret_group_parameters.push_back(Vector<int>{ from_line, from_col, to_line, to_column, cursor_line, cursor_column }); + } - if (line_id == 0 || next_id < 0) { - return; - } + for (int line_id = group_borders[i].first; line_id <= group_borders[i].second; line_id++) { + text_editor->unfold_line(line_id); + text_editor->unfold_line(line_id - 1); - text_editor->unfold_line(line_id); - text_editor->unfold_line(next_id); + text_editor->swap_lines(line_id - 1, line_id); + } - text_editor->swap_lines(line_id, next_id); - text_editor->set_caret_line(next_id, c == 0, true, 0, c); - } - int from_line_up = from_line > 0 ? from_line - 1 : from_line; - int to_line_up = to_line > 0 ? to_line - 1 : to_line; - int cursor_line_up = cursor_line > 0 ? cursor_line - 1 : cursor_line; - text_editor->select(from_line_up, from_col, to_line_up, to_column, c); - text_editor->set_caret_line(cursor_line_up, c == 0, true, 0, c); - } else { - int line_id = text_editor->get_caret_line(c); - int next_id = line_id - 1; + for (int j = 0; j < caret_groups[i].size(); j++) { + int c = caret_groups[i][j]; + Vector<int> caret_parameters = caret_group_parameters[j]; + text_editor->set_caret_line(caret_parameters[4] - 1, c == 0, true, 0, c); + text_editor->set_caret_column(caret_parameters[5], c == 0, c); - if (line_id == 0 || next_id < 0) { - return; + if (caret_parameters[0] >= 0) { + text_editor->select(caret_parameters[0] - 1, caret_parameters[1], caret_parameters[2] - 1, caret_parameters[3], c); } - - text_editor->unfold_line(line_id); - text_editor->unfold_line(next_id); - - text_editor->swap_lines(line_id, next_id); - text_editor->set_caret_line(next_id, c == 0, true, 0, c); } } + text_editor->end_complex_operation(); text_editor->merge_overlapping_carets(); text_editor->queue_redraw(); @@ -1382,95 +1391,97 @@ void CodeTextEditor::move_lines_up() { void CodeTextEditor::move_lines_down() { text_editor->begin_complex_operation(); - Vector<int> carets_to_remove; - Vector<int> caret_edit_order = text_editor->get_caret_index_edit_order(); + + // Lists of carets representing each group + Vector<Vector<int>> caret_groups; + Vector<Pair<int, int>> group_borders; + + // Search for groups of carets and their selections residing on the same lines for (int i = 0; i < caret_edit_order.size(); i++) { int c = caret_edit_order[i]; - int cl = text_editor->get_caret_line(c); - bool swaped_caret = false; - for (int j = i + 1; j < caret_edit_order.size(); j++) { - if (text_editor->has_selection(caret_edit_order[j])) { - if (text_editor->get_selection_from_line() == cl) { - carets_to_remove.push_back(caret_edit_order[j]); - continue; - } + Vector<int> new_group{ c }; + Pair<int, int> group_border; + if (text_editor->has_selection(c)) { + group_border.first = text_editor->get_selection_from_line(c); + group_border.second = text_editor->get_selection_to_line(c); + } else { + group_border.first = text_editor->get_caret_line(c); + group_border.second = text_editor->get_caret_line(c); + } - if (text_editor->get_selection_to_line() == cl) { - if (text_editor->has_selection(c)) { - if (text_editor->get_selection_to_line(c) != cl) { - text_editor->select(cl + 1, 0, text_editor->get_selection_to_line(c), text_editor->get_selection_to_column(c), c); - break; - } - } + for (int j = i; j < caret_edit_order.size() - 1; j++) { + int c_current = caret_edit_order[j]; + int c_next = caret_edit_order[j + 1]; - carets_to_remove.push_back(c); - i = j - 1; - swaped_caret = true; - break; + int next_start_pos = text_editor->has_selection(c_next) ? text_editor->get_selection_from_line(c_next) : text_editor->get_caret_line(c_next); + int next_end_pos = text_editor->has_selection(c_next) ? text_editor->get_selection_to_line(c_next) : text_editor->get_caret_line(c_next); + + int current_start_pos = text_editor->has_selection(c_current) ? text_editor->get_selection_from_line(c_current) : text_editor->get_caret_line(c_current); + + i = j; + if (next_end_pos == current_start_pos || next_end_pos + 1 == current_start_pos) { + group_border.first = next_start_pos; + new_group.push_back(c_next); + // If the last caret is added to the current group there is no need to process it again + if (j + 1 == caret_edit_order.size() - 1) { + i++; } + } else { break; } - - if (text_editor->get_caret_line(caret_edit_order[j]) == cl) { - carets_to_remove.push_back(caret_edit_order[j]); - i = j; - continue; - } - break; } + group_borders.push_back(group_border); + caret_groups.push_back(new_group); + } - if (swaped_caret) { + for (int i = 0; i < group_borders.size(); i++) { + if (group_borders[i].second + 1 > text_editor->get_line_count() - 1) { continue; } - if (text_editor->has_selection(c)) { - int from_line = text_editor->get_selection_from_line(c); - int from_col = text_editor->get_selection_from_column(c); - int to_line = text_editor->get_selection_to_line(c); - int to_column = text_editor->get_selection_to_column(c); - int cursor_line = text_editor->get_caret_line(c); - - for (int l = to_line; l >= from_line; l--) { - int line_id = l; - int next_id = l + 1; - - if (line_id == text_editor->get_line_count() - 1 || next_id > text_editor->get_line_count()) { - continue; - } - - text_editor->unfold_line(line_id); - text_editor->unfold_line(next_id); + // If the group starts overlapping with the upper group don't move it + if (i > 0 && group_borders[i].second + 1 >= group_borders[i - 1].first) { + continue; + } - text_editor->swap_lines(line_id, next_id); - text_editor->set_caret_line(next_id, c == 0, true, 0, c); - } - int from_line_down = from_line < text_editor->get_line_count() ? from_line + 1 : from_line; - int to_line_down = to_line < text_editor->get_line_count() ? to_line + 1 : to_line; - int cursor_line_down = cursor_line < text_editor->get_line_count() ? cursor_line + 1 : cursor_line; - text_editor->select(from_line_down, from_col, to_line_down, to_column, c); - text_editor->set_caret_line(cursor_line_down, c == 0, true, 0, c); - } else { - int line_id = text_editor->get_caret_line(c); - int next_id = line_id + 1; + // We have to remember caret positions and selections prior to line swapping + Vector<Vector<int>> caret_group_parameters; - if (line_id == text_editor->get_line_count() - 1 || next_id > text_editor->get_line_count()) { - continue; + for (int j = 0; j < caret_groups[i].size(); j++) { + int c = caret_groups[i][j]; + int cursor_line = text_editor->get_caret_line(c); + int cursor_column = text_editor->get_caret_column(c); + + if (text_editor->has_selection(c)) { + int from_line = text_editor->get_selection_from_line(c); + int from_col = text_editor->get_selection_from_column(c); + int to_line = text_editor->get_selection_to_line(c); + int to_column = text_editor->get_selection_to_column(c); + caret_group_parameters.push_back(Vector<int>{ from_line, from_col, to_line, to_column, cursor_line, cursor_column }); + } else { + caret_group_parameters.push_back(Vector<int>{ -1, -1, -1, -1, cursor_line, cursor_column }); } + } + for (int line_id = group_borders[i].second; line_id >= group_borders[i].first; line_id--) { text_editor->unfold_line(line_id); - text_editor->unfold_line(next_id); + text_editor->unfold_line(line_id + 1); - text_editor->swap_lines(line_id, next_id); - text_editor->set_caret_line(next_id, c == 0, true, 0, c); + text_editor->swap_lines(line_id + 1, line_id); } - } - // Sort and remove backwards to preserve indexes. - carets_to_remove.sort(); - for (int i = carets_to_remove.size() - 1; i >= 0; i--) { - text_editor->remove_caret(carets_to_remove[i]); + for (int j = 0; j < caret_groups[i].size(); j++) { + int c = caret_groups[i][j]; + Vector<int> caret_parameters = caret_group_parameters[j]; + text_editor->set_caret_line(caret_parameters[4] + 1, c == 0, true, 0, c); + text_editor->set_caret_column(caret_parameters[5], c == 0, c); + + if (caret_parameters[0] >= 0) { + text_editor->select(caret_parameters[0] + 1, caret_parameters[1], caret_parameters[2] + 1, caret_parameters[3], c); + } + } } text_editor->merge_overlapping_carets(); diff --git a/editor/plugins/animation_player_editor_plugin.cpp b/editor/plugins/animation_player_editor_plugin.cpp index 338688f274..5183a738ae 100644 --- a/editor/plugins/animation_player_editor_plugin.cpp +++ b/editor/plugins/animation_player_editor_plugin.cpp @@ -216,8 +216,8 @@ void AnimationPlayerEditor::_play_from_pressed() { player->stop(); //so it won't blend with itself } ERR_FAIL_COND_EDMSG(!_validate_tracks(player->get_animation(current)), "Animation tracks may have any invalid key, abort playing."); - player->play(current); player->seek(time); + player->play(current); } //unstop @@ -254,8 +254,8 @@ void AnimationPlayerEditor::_play_bw_from_pressed() { player->stop(); //so it won't blend with itself } ERR_FAIL_COND_EDMSG(!_validate_tracks(player->get_animation(current)), "Animation tracks may have any invalid key, abort playing."); - player->play(current, -1, -1, true); player->seek(time); + player->play(current, -1, -1, true); } //unstop diff --git a/editor/plugins/node_3d_editor_plugin.cpp b/editor/plugins/node_3d_editor_plugin.cpp index 4194fd831b..c97de80a76 100644 --- a/editor/plugins/node_3d_editor_plugin.cpp +++ b/editor/plugins/node_3d_editor_plugin.cpp @@ -92,6 +92,9 @@ void ViewportNavigationControl::_notification(int p_what) { if (!is_connected("mouse_exited", callable_mp(this, &ViewportNavigationControl::_on_mouse_exited))) { connect("mouse_exited", callable_mp(this, &ViewportNavigationControl::_on_mouse_exited)); } + if (!is_connected("mouse_entered", callable_mp(this, &ViewportNavigationControl::_on_mouse_entered))) { + connect("mouse_entered", callable_mp(this, &ViewportNavigationControl::_on_mouse_entered)); + } } break; case NOTIFICATION_DRAW: { @@ -112,7 +115,7 @@ void ViewportNavigationControl::_draw() { float radius = get_size().x / 2.0; const bool focused = focused_index != -1; - draw_circle(center, radius, Color(0.5, 0.5, 0.5, focused ? 0.25 : 0.05)); + draw_circle(center, radius, Color(0.5, 0.5, 0.5, focused || hovered ? 0.35 : 0.15)); const Color c = focused ? Color(0.9, 0.9, 0.9, 0.9) : Color(0.5, 0.5, 0.5, 0.25); @@ -123,6 +126,9 @@ void ViewportNavigationControl::_draw() { } void ViewportNavigationControl::_process_click(int p_index, Vector2 p_position, bool p_pressed) { + hovered = false; + queue_redraw(); + if (focused_index != -1 && focused_index != p_index) { return; } @@ -233,7 +239,13 @@ void ViewportNavigationControl::_update_navigation() { } } +void ViewportNavigationControl::_on_mouse_entered() { + hovered = true; + queue_redraw(); +} + void ViewportNavigationControl::_on_mouse_exited() { + hovered = false; queue_redraw(); } @@ -5133,7 +5145,7 @@ Node3DEditorViewport::Node3DEditorViewport(Node3DEditor *p_spatial_editor, int p // Prevent visible spacing between frame time labels. top_right_vbox->add_theme_constant_override("separation", 0); - const int navigation_control_size = 200; + const int navigation_control_size = 150; position_control = memnew(ViewportNavigationControl); position_control->set_navigation_mode(Node3DEditorViewport::NAVIGATION_MOVE); diff --git a/editor/plugins/node_3d_editor_plugin.h b/editor/plugins/node_3d_editor_plugin.h index 04fc030f2b..ed555d86c3 100644 --- a/editor/plugins/node_3d_editor_plugin.h +++ b/editor/plugins/node_3d_editor_plugin.h @@ -930,6 +930,7 @@ class ViewportNavigationControl : public Control { Node3DEditorViewport *viewport = nullptr; Vector2i focused_mouse_start; Vector2 focused_pos; + bool hovered = false; int focused_index = -1; Node3DEditorViewport::NavigationMode nav_mode = Node3DEditorViewport::NavigationMode::NAVIGATION_NONE; @@ -939,6 +940,7 @@ protected: void _notification(int p_what); virtual void gui_input(const Ref<InputEvent> &p_event) override; void _draw(); + void _on_mouse_entered(); void _on_mouse_exited(); void _process_click(int p_index, Vector2 p_position, bool p_pressed); void _process_drag(int p_index, Vector2 p_position, Vector2 p_relative_position); diff --git a/editor/shader_globals_editor.cpp b/editor/shader_globals_editor.cpp index 22a1d49422..b778262fed 100644 --- a/editor/shader_globals_editor.cpp +++ b/editor/shader_globals_editor.cpp @@ -69,28 +69,12 @@ static const char *global_var_type_names[RS::GLOBAL_VAR_TYPE_MAX] = { class ShaderGlobalsEditorInterface : public Object { GDCLASS(ShaderGlobalsEditorInterface, Object) - void _var_changed() { - emit_signal(SNAME("var_changed")); - } - -protected: - static void _bind_methods() { - ClassDB::bind_method("_var_changed", &ShaderGlobalsEditorInterface::_var_changed); - ADD_SIGNAL(MethodInfo("var_changed")); - } - - bool _set(const StringName &p_name, const Variant &p_value) { - Variant existing = RS::get_singleton()->global_shader_parameter_get(p_name); - - if (existing.get_type() == Variant::NIL) { - return false; - } - + void _set_var(const StringName &p_name, const Variant &p_value, const Variant &p_prev_value) { Ref<EditorUndoRedoManager> &undo_redo = EditorNode::get_undo_redo(); undo_redo->create_action(TTR("Set Shader Global Variable")); undo_redo->add_do_method(RS::get_singleton(), "global_shader_parameter_set", p_name, p_value); - undo_redo->add_undo_method(RS::get_singleton(), "global_shader_parameter_set", p_name, existing); + undo_redo->add_undo_method(RS::get_singleton(), "global_shader_parameter_set", p_name, p_prev_value); RS::GlobalShaderParameterType type = RS::get_singleton()->global_shader_parameter_get_type(p_name); Dictionary gv; gv["type"] = global_var_type_names[type]; @@ -111,8 +95,29 @@ protected: undo_redo->add_do_method(this, "_var_changed"); undo_redo->add_undo_method(this, "_var_changed"); block_update = true; - undo_redo->commit_action(false); + undo_redo->commit_action(); block_update = false; + } + + void _var_changed() { + emit_signal(SNAME("var_changed")); + } + +protected: + static void _bind_methods() { + ClassDB::bind_method("_set_var", &ShaderGlobalsEditorInterface::_set_var); + ClassDB::bind_method("_var_changed", &ShaderGlobalsEditorInterface::_var_changed); + ADD_SIGNAL(MethodInfo("var_changed")); + } + + bool _set(const StringName &p_name, const Variant &p_value) { + Variant existing = RS::get_singleton()->global_shader_parameter_get(p_name); + + if (existing.get_type() == Variant::NIL) { + return false; + } + + call_deferred("_set_var", p_name, p_value, existing); return true; } |