summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--editor/editor_resource_picker.cpp8
-rw-r--r--editor/icons/AudioStreamPlayer.svg2
-rw-r--r--editor/icons/AudioStreamPlayer2D.svg2
-rw-r--r--editor/icons/AudioStreamPlayer3D.svg2
-rw-r--r--scene/gui/code_edit.cpp56
-rw-r--r--tests/scene/test_code_edit.h120
6 files changed, 159 insertions, 31 deletions
diff --git a/editor/editor_resource_picker.cpp b/editor/editor_resource_picker.cpp
index a895219e6f..4cd44e3020 100644
--- a/editor/editor_resource_picker.cpp
+++ b/editor/editor_resource_picker.cpp
@@ -1065,7 +1065,7 @@ EditorResourcePicker::EditorResourcePicker(bool p_hide_assign_button_controls) {
}
edit_button = memnew(Button);
- edit_button->set_flat(true);
+ edit_button->set_flat(false);
edit_button->set_toggle_mode(true);
edit_button->connect(SceneStringName(pressed), callable_mp(this, &EditorResourcePicker::_update_menu));
add_child(edit_button);
@@ -1268,8 +1268,6 @@ void EditorAudioStreamPicker::_preview_draw() {
if (audio_stream->get_length() > 0 && size.width > 0) {
rect.size.height *= 0.5;
- stream_preview_rect->draw_rect(rect, Color(0, 0, 0, 1));
-
Ref<AudioStreamPreview> preview = AudioStreamPreviewGenerator::get_singleton()->generate_preview(audio_stream);
float preview_len = preview->get_length();
@@ -1325,8 +1323,8 @@ void EditorAudioStreamPicker::_preview_draw() {
text = audio_stream->get_class().replace_first("AudioStream", "");
}
- stream_preview_rect->draw_texture(icon, Point2i(EDSCALE * 2, rect.position.y + (rect.size.height - icon->get_height()) / 2), icon_modulate);
- stream_preview_rect->draw_string(font, Point2i(EDSCALE * 2 + icon->get_width(), rect.position.y + font->get_ascent(font_size) + (rect.size.height - font->get_height(font_size)) / 2), text, HORIZONTAL_ALIGNMENT_CENTER, size.width - 4 * EDSCALE - icon->get_width());
+ stream_preview_rect->draw_texture(icon, Point2i(EDSCALE * 4, rect.position.y + (rect.size.height - icon->get_height()) / 2), icon_modulate);
+ stream_preview_rect->draw_string(font, Point2i(EDSCALE * 4 + icon->get_width(), rect.position.y + font->get_ascent(font_size) + (rect.size.height - font->get_height(font_size)) / 2), text, HORIZONTAL_ALIGNMENT_CENTER, size.width - 4 * EDSCALE - icon->get_width(), font_size, get_theme_color(SNAME("font_color"), EditorStringName(Editor)));
}
EditorAudioStreamPicker::EditorAudioStreamPicker() :
diff --git a/editor/icons/AudioStreamPlayer.svg b/editor/icons/AudioStreamPlayer.svg
index 98a1650f6f..a3c4ad8e35 100644
--- a/editor/icons/AudioStreamPlayer.svg
+++ b/editor/icons/AudioStreamPlayer.svg
@@ -1 +1 @@
-<svg xmlns="http://www.w3.org/2000/svg" xml:space="preserve" width="16" height="16" version="1.0" viewBox="0 0 2.4 2.4"><path fill="#e0e0e0" stroke="#e0e0e0" stroke-linejoin="round" stroke-width=".176" d="M1.382.335.777.858H.204v.673h.564l.614.531Z"/><path fill="none" stroke="#e0e0e0" stroke-linecap="round" stroke-width=".176" d="M1.718.572c.275.374.275.882 0 1.256M1.947.343c.402.5.402 1.213 0 1.714"/></svg> \ No newline at end of file
+<svg xmlns="http://www.w3.org/2000/svg" xml:space="preserve" width="16" height="16" version="1.0" viewBox="0 0 2.4 2.4"><path fill="#e0e0e0" stroke="#e0e0e0" stroke-linejoin="round" stroke-width=".176" d="M1.382.335.777.858H.204v.673h.564l.614.531Z"/><path fill="none" stroke="#e0e0e0" stroke-linecap="round" stroke-width=".176" d="M1.718.572a1.06 1.06 0 0 1 0 1.256M1.947.343c.402.5.402 1.213 0 1.714"/></svg> \ No newline at end of file
diff --git a/editor/icons/AudioStreamPlayer2D.svg b/editor/icons/AudioStreamPlayer2D.svg
index 3a5c5c29af..fa60e30238 100644
--- a/editor/icons/AudioStreamPlayer2D.svg
+++ b/editor/icons/AudioStreamPlayer2D.svg
@@ -1 +1 @@
-<svg xmlns="http://www.w3.org/2000/svg" xml:space="preserve" width="16" height="16" version="1.0" viewBox="0 0 2.4 2.4"><path fill="#8da5f3" stroke="#8da5f3" stroke-linejoin="round" stroke-width=".176" d="M1.382.335.777.858H.204v.673h.564l.614.531Z"/><path fill="none" stroke="#8da5f3" stroke-linecap="round" stroke-width=".176" d="M1.718.572c.275.374.275.882 0 1.256M1.947.343c.402.5.402 1.213 0 1.714"/></svg> \ No newline at end of file
+<svg xmlns="http://www.w3.org/2000/svg" xml:space="preserve" width="16" height="16" version="1.0" viewBox="0 0 2.4 2.4"><path fill="#8da5f3" stroke="#8da5f3" stroke-linejoin="round" stroke-width=".176" d="M1.382.335.777.858H.204v.673h.564l.614.531Z"/><path fill="none" stroke="#8da5f3" stroke-linecap="round" stroke-width=".176" d="M1.718.572a1.06 1.06 0 0 1 0 1.256M1.947.343c.402.5.402 1.213 0 1.714"/></svg> \ No newline at end of file
diff --git a/editor/icons/AudioStreamPlayer3D.svg b/editor/icons/AudioStreamPlayer3D.svg
index c0480d0c7d..f6be929e61 100644
--- a/editor/icons/AudioStreamPlayer3D.svg
+++ b/editor/icons/AudioStreamPlayer3D.svg
@@ -1 +1 @@
-<svg xmlns="http://www.w3.org/2000/svg" xml:space="preserve" width="16" height="16" version="1.0" viewBox="0 0 2.4 2.4"><path fill="#fc7f7f" stroke="#fc7f7f" stroke-linejoin="round" stroke-width=".176" d="M1.382.335.777.858H.204v.673h.564l.614.531Z"/><path fill="none" stroke="#fc7f7f" stroke-linecap="round" stroke-width=".176" d="M1.718.572c.275.374.275.882 0 1.256M1.947.343c.402.5.402 1.213 0 1.714"/></svg> \ No newline at end of file
+<svg xmlns="http://www.w3.org/2000/svg" xml:space="preserve" width="16" height="16" version="1.0" viewBox="0 0 2.4 2.4"><path fill="#fc7f7f" stroke="#fc7f7f" stroke-linejoin="round" stroke-width=".176" d="M1.382.335.777.858H.204v.673h.564l.614.531Z"/><path fill="none" stroke="#fc7f7f" stroke-linecap="round" stroke-width=".176" d="M1.718.572a1.06 1.06 0 0 1 0 1.256M1.947.343c.402.5.402 1.213 0 1.714"/></svg> \ No newline at end of file
diff --git a/scene/gui/code_edit.cpp b/scene/gui/code_edit.cpp
index 0bdb487300..c3c4b1d3fb 100644
--- a/scene/gui/code_edit.cpp
+++ b/scene/gui/code_edit.cpp
@@ -2331,18 +2331,19 @@ void CodeEdit::move_lines_up() {
unfold_line(line);
swap_lines(line - 1, line);
}
- }
-
- // Fix selection if it ended at column 0, since it wasn't moved.
- for (int i = 0; i < get_caret_count(); i++) {
- if (has_selection(i) && get_selection_to_column(i) == 0 && get_selection_to_line(i) != 0) {
- if (is_caret_after_selection_origin(i)) {
- set_caret_line(get_caret_line(i) - 1, false, true, -1, i);
- } else {
- set_selection_origin_line(get_selection_origin_line(i) - 1, true, -1, i);
+ // Fix selection if the last one ends at column 0, since it wasn't moved.
+ for (int i = 0; i < get_caret_count(); i++) {
+ if (has_selection(i) && get_selection_to_column(i) == 0 && get_selection_to_line(i) == line_range.y + 1) {
+ if (is_caret_after_selection_origin(i)) {
+ set_caret_line(get_caret_line(i) - 1, false, true, -1, i);
+ } else {
+ set_selection_origin_line(get_selection_origin_line(i) - 1, true, -1, i);
+ }
+ break;
}
}
}
+ adjust_viewport_to_caret();
end_multicaret_edit();
end_complex_operation();
@@ -2352,30 +2353,41 @@ void CodeEdit::move_lines_down() {
begin_complex_operation();
begin_multicaret_edit();
- Vector<Point2i> line_ranges = get_line_ranges_from_carets();
-
- // Fix selection if it ended at column 0, since it won't be moved.
- for (int i = 0; i < get_caret_count(); i++) {
- if (has_selection(i) && get_selection_to_column(i) == 0 && get_selection_to_line(i) != get_line_count() - 1) {
- if (is_caret_after_selection_origin(i)) {
- set_caret_line(get_caret_line(i) + 1, false, true, -1, i);
- } else {
- set_selection_origin_line(get_selection_origin_line(i) + 1, true, -1, i);
- }
- }
- }
-
// Move lines down by swapping each line with the one below it.
+ Vector<Point2i> line_ranges = get_line_ranges_from_carets();
+ // Reverse in case line ranges are adjacent, if the first ends at column 0.
+ line_ranges.reverse();
for (Point2i line_range : line_ranges) {
if (line_range.y == get_line_count() - 1) {
continue;
}
+ // Fix selection if the last one ends at column 0, since it won't be moved.
+ bool selection_to_line_at_end = false;
+ for (int i = 0; i < get_caret_count(); i++) {
+ if (has_selection(i) && get_selection_to_column(i) == 0 && get_selection_to_line(i) == line_range.y + 1) {
+ selection_to_line_at_end = get_selection_to_line(i) == get_line_count() - 1;
+ if (selection_to_line_at_end) {
+ break;
+ }
+ if (is_caret_after_selection_origin(i)) {
+ set_caret_line(get_caret_line(i) + 1, false, true, -1, i);
+ } else {
+ set_selection_origin_line(get_selection_origin_line(i) + 1, true, -1, i);
+ }
+ break;
+ }
+ }
+ if (selection_to_line_at_end) {
+ continue;
+ }
+
unfold_line(line_range.y + 1);
for (int line = line_range.y; line >= line_range.x; line--) {
unfold_line(line);
swap_lines(line + 1, line);
}
}
+ adjust_viewport_to_caret();
end_multicaret_edit();
end_complex_operation();
diff --git a/tests/scene/test_code_edit.h b/tests/scene/test_code_edit.h
index 317dbe9ab9..a166002cdd 100644
--- a/tests/scene/test_code_edit.h
+++ b/tests/scene/test_code_edit.h
@@ -4889,6 +4889,17 @@ TEST_CASE("[SceneTree][CodeEdit] text manipulation") {
CHECK(code_edit->get_caret_line() == 0);
CHECK(code_edit->get_caret_column() == 1);
+ // Does nothing at the first line when selection ends at column 0.
+ code_edit->set_text("test\nlines\nto\n\nmove\naround");
+ code_edit->select(0, 0, 1, 0);
+ code_edit->move_lines_up();
+ CHECK(code_edit->get_text() == "test\nlines\nto\n\nmove\naround");
+ CHECK(code_edit->has_selection());
+ CHECK(code_edit->get_selection_origin_line() == 0);
+ CHECK(code_edit->get_selection_origin_column() == 0);
+ CHECK(code_edit->get_caret_line() == 1);
+ CHECK(code_edit->get_caret_column() == 0);
+
// Works on empty line.
code_edit->set_text("test\nlines\nto\n\nmove\naround");
code_edit->set_caret_line(3);
@@ -4950,9 +4961,9 @@ TEST_CASE("[SceneTree][CodeEdit] text manipulation") {
CHECK_FALSE(code_edit->has_selection(2));
CHECK(code_edit->get_caret_line(2) == 3);
CHECK(code_edit->get_caret_column(2) == 4);
+ code_edit->remove_secondary_carets();
// Move multiple separate lines with multiple selections.
- code_edit->remove_secondary_carets();
code_edit->set_text("test\nlines\nto\n\nmove\naround");
code_edit->select(2, 2, 1, 4);
code_edit->add_caret(5, 0);
@@ -4970,6 +4981,44 @@ TEST_CASE("[SceneTree][CodeEdit] text manipulation") {
CHECK(code_edit->get_selection_origin_column(1) == 0);
CHECK(code_edit->get_caret_line(1) == 4);
CHECK(code_edit->get_caret_column(1) == 1);
+ code_edit->remove_secondary_carets();
+
+ // Move lines with adjacent selections that end at column 0.
+ code_edit->set_text("test\nlines\nto\n\nmove\naround");
+ code_edit->select(1, 2, 2, 0);
+ code_edit->add_caret(2, 2);
+ code_edit->select(2, 2, 3, 0, 1);
+ code_edit->move_lines_up();
+ CHECK(code_edit->get_text() == "lines\nto\ntest\n\nmove\naround");
+ CHECK(code_edit->get_caret_count() == 2);
+ CHECK(code_edit->has_selection(0));
+ CHECK(code_edit->get_selection_origin_line(0) == 0);
+ CHECK(code_edit->get_selection_origin_column(0) == 2);
+ CHECK(code_edit->get_caret_line(0) == 1);
+ CHECK(code_edit->get_caret_column(0) == 0);
+ CHECK(code_edit->has_selection(1));
+ CHECK(code_edit->get_selection_origin_line(1) == 1);
+ CHECK(code_edit->get_selection_origin_column(1) == 2);
+ CHECK(code_edit->get_caret_line(1) == 2);
+ CHECK(code_edit->get_caret_column(1) == 0);
+ code_edit->remove_secondary_carets();
+ code_edit->deselect();
+
+ code_edit->set_line_folding_enabled(true);
+
+ // Move line up into a folded region unfolds it.
+ code_edit->set_text("test\n\tline1 test\n\t\tline 2\ntest2");
+ code_edit->set_caret_line(3);
+ code_edit->set_caret_column(0);
+ code_edit->fold_line(0);
+ CHECK(code_edit->is_line_folded(0));
+ code_edit->move_lines_up();
+ CHECK(code_edit->get_caret_count() == 1);
+ CHECK_FALSE(code_edit->has_selection(0));
+ CHECK(code_edit->get_caret_line() == 2);
+ CHECK(code_edit->get_caret_column() == 0);
+ CHECK(code_edit->get_text() == "test\n\tline1 test\ntest2\n\t\tline 2");
+ CHECK_FALSE(code_edit->is_line_folded(0));
}
SUBCASE("[SceneTree][CodeEdit] move lines down") {
@@ -5004,6 +5053,17 @@ TEST_CASE("[SceneTree][CodeEdit] text manipulation") {
CHECK(code_edit->get_caret_line() == 5);
CHECK(code_edit->get_caret_column() == 1);
+ // Does nothing at the last line when selection ends at column 0.
+ code_edit->set_text("test\nlines\nto\n\nmove\naround");
+ code_edit->select(4, 0, 5, 0);
+ code_edit->move_lines_down();
+ CHECK(code_edit->get_text() == "test\nlines\nto\n\nmove\naround");
+ CHECK(code_edit->has_selection());
+ CHECK(code_edit->get_selection_origin_line() == 4);
+ CHECK(code_edit->get_selection_origin_column() == 0);
+ CHECK(code_edit->get_caret_line() == 5);
+ CHECK(code_edit->get_caret_column() == 0);
+
// Works on empty line.
code_edit->set_text("test\nlines\nto\n\nmove\naround");
code_edit->set_caret_line(3);
@@ -5085,6 +5145,64 @@ TEST_CASE("[SceneTree][CodeEdit] text manipulation") {
CHECK(code_edit->get_selection_origin_column(1) == 0);
CHECK(code_edit->get_caret_line(1) == 5);
CHECK(code_edit->get_caret_column(1) == 2);
+
+ // Move lines with adjacent selections that end at column 0.
+ code_edit->set_text("test\nlines\nto\n\nmove\naround");
+ code_edit->select(1, 2, 2, 0);
+ code_edit->add_caret(2, 2);
+ code_edit->select(2, 2, 3, 0, 1);
+ code_edit->move_lines_down();
+ CHECK(code_edit->get_text() == "test\n\nlines\nto\nmove\naround");
+ CHECK(code_edit->get_caret_count() == 2);
+ CHECK(code_edit->has_selection(0));
+ CHECK(code_edit->get_selection_origin_line(0) == 2);
+ CHECK(code_edit->get_selection_origin_column(0) == 2);
+ CHECK(code_edit->get_caret_line(0) == 3);
+ CHECK(code_edit->get_caret_column(0) == 0);
+ CHECK(code_edit->has_selection(1));
+ CHECK(code_edit->get_selection_origin_line(1) == 3);
+ CHECK(code_edit->get_selection_origin_column(1) == 2);
+ CHECK(code_edit->get_caret_line(1) == 4);
+ CHECK(code_edit->get_caret_column(1) == 0);
+ code_edit->remove_secondary_carets();
+
+ // Move lines with disconnected adjacent selections that end at column 0.
+ code_edit->set_text("test\nlines\nto\n\nmove\naround");
+ code_edit->select(0, 2, 1, 0);
+ code_edit->add_caret(2, 2);
+ code_edit->select(2, 0, 3, 0, 1);
+ code_edit->move_lines_down();
+ CHECK(code_edit->get_text() == "lines\ntest\n\nto\nmove\naround");
+ CHECK(code_edit->get_caret_count() == 2);
+ CHECK(code_edit->has_selection(0));
+ CHECK(code_edit->get_selection_origin_line(0) == 1);
+ CHECK(code_edit->get_selection_origin_column(0) == 2);
+ CHECK(code_edit->get_caret_line(0) == 2);
+ CHECK(code_edit->get_caret_column(0) == 0);
+ CHECK(code_edit->has_selection(1));
+ CHECK(code_edit->get_selection_origin_line(1) == 3);
+ CHECK(code_edit->get_selection_origin_column(1) == 0);
+ CHECK(code_edit->get_caret_line(1) == 4);
+ CHECK(code_edit->get_caret_column(1) == 0);
+ code_edit->remove_secondary_carets();
+ code_edit->deselect();
+
+ code_edit->set_line_folding_enabled(true);
+
+ // Move line down into a folded region unfolds it.
+ code_edit->set_text("test\ntest2\n\tline1 test\n\t\tline 2\ntest2");
+ code_edit->set_caret_line(0);
+ code_edit->set_caret_column(0);
+ code_edit->fold_line(1);
+ CHECK(code_edit->is_line_folded(1));
+ code_edit->move_lines_down();
+ CHECK(code_edit->get_caret_count() == 1);
+ CHECK_FALSE(code_edit->has_selection(0));
+ CHECK(code_edit->get_caret_line() == 1);
+ CHECK(code_edit->get_caret_column() == 0);
+ CHECK(code_edit->get_text() == "test2\ntest\n\tline1 test\n\t\tline 2\ntest2");
+ CHECK_FALSE(code_edit->is_line_folded(0));
+ CHECK_FALSE(code_edit->is_line_folded(1));
}
SUBCASE("[SceneTree][CodeEdit] delete lines") {