commit
d826b043ad
6 changed files with 683 additions and 141 deletions
|
@ -56,6 +56,7 @@ void GotoLineDialog::ok_pressed() {
|
||||||
|
|
||||||
if (get_line() < 1 || get_line() > text_editor->get_line_count())
|
if (get_line() < 1 || get_line() > text_editor->get_line_count())
|
||||||
return;
|
return;
|
||||||
|
text_editor->unfold_line(get_line() - 1);
|
||||||
text_editor->cursor_set_line(get_line() - 1);
|
text_editor->cursor_set_line(get_line() - 1);
|
||||||
hide();
|
hide();
|
||||||
}
|
}
|
||||||
|
@ -139,6 +140,7 @@ bool FindReplaceBar::_search(uint32_t p_flags, int p_from_line, int p_from_col)
|
||||||
|
|
||||||
if (found) {
|
if (found) {
|
||||||
if (!preserve_cursor) {
|
if (!preserve_cursor) {
|
||||||
|
text_edit->unfold_line(line);
|
||||||
text_edit->cursor_set_line(line, false);
|
text_edit->cursor_set_line(line, false);
|
||||||
text_edit->cursor_set_column(col + text.length(), false);
|
text_edit->cursor_set_column(col + text.length(), false);
|
||||||
text_edit->center_viewport_to_cursor();
|
text_edit->center_viewport_to_cursor();
|
||||||
|
@ -167,6 +169,7 @@ void FindReplaceBar::_replace() {
|
||||||
if (result_line != -1 && result_col != -1) {
|
if (result_line != -1 && result_col != -1) {
|
||||||
text_edit->begin_complex_operation();
|
text_edit->begin_complex_operation();
|
||||||
|
|
||||||
|
text_edit->unfold_line(result_line);
|
||||||
text_edit->select(result_line, result_col, result_line, result_col + get_search_text().length());
|
text_edit->select(result_line, result_col, result_line, result_col + get_search_text().length());
|
||||||
text_edit->insert_text_at_cursor(get_replace_text());
|
text_edit->insert_text_at_cursor(get_replace_text());
|
||||||
|
|
||||||
|
@ -214,6 +217,7 @@ void FindReplaceBar::_replace_all() {
|
||||||
|
|
||||||
prev_match = Point2i(result_line, result_col + replace_text.length());
|
prev_match = Point2i(result_line, result_col + replace_text.length());
|
||||||
|
|
||||||
|
text_edit->unfold_line(result_line);
|
||||||
text_edit->select(result_line, result_col, result_line, match_to.y);
|
text_edit->select(result_line, result_col, result_line, match_to.y);
|
||||||
|
|
||||||
if (selection_enabled && is_selection_only()) {
|
if (selection_enabled && is_selection_only()) {
|
||||||
|
@ -751,6 +755,7 @@ bool FindReplaceDialog::_search() {
|
||||||
|
|
||||||
if (found) {
|
if (found) {
|
||||||
// print_line("found");
|
// print_line("found");
|
||||||
|
text_edit->unfold_line(line);
|
||||||
text_edit->cursor_set_line(line);
|
text_edit->cursor_set_line(line);
|
||||||
if (is_backwards())
|
if (is_backwards())
|
||||||
text_edit->cursor_set_column(col);
|
text_edit->cursor_set_column(col);
|
||||||
|
@ -1093,6 +1098,8 @@ void CodeTextEditor::update_editor_settings() {
|
||||||
text_editor->cursor_set_blink_enabled(EditorSettings::get_singleton()->get("text_editor/cursor/caret_blink"));
|
text_editor->cursor_set_blink_enabled(EditorSettings::get_singleton()->get("text_editor/cursor/caret_blink"));
|
||||||
text_editor->cursor_set_blink_speed(EditorSettings::get_singleton()->get("text_editor/cursor/caret_blink_speed"));
|
text_editor->cursor_set_blink_speed(EditorSettings::get_singleton()->get("text_editor/cursor/caret_blink_speed"));
|
||||||
text_editor->set_draw_breakpoint_gutter(EditorSettings::get_singleton()->get("text_editor/line_numbers/show_breakpoint_gutter"));
|
text_editor->set_draw_breakpoint_gutter(EditorSettings::get_singleton()->get("text_editor/line_numbers/show_breakpoint_gutter"));
|
||||||
|
text_editor->set_hiding_enabled(EditorSettings::get_singleton()->get("text_editor/line_numbers/code_folding"));
|
||||||
|
text_editor->set_draw_fold_gutter(EditorSettings::get_singleton()->get("text_editor/line_numbers/code_folding"));
|
||||||
text_editor->cursor_set_block_mode(EditorSettings::get_singleton()->get("text_editor/cursor/block_caret"));
|
text_editor->cursor_set_block_mode(EditorSettings::get_singleton()->get("text_editor/cursor/block_caret"));
|
||||||
text_editor->set_smooth_scroll_enabled(EditorSettings::get_singleton()->get("text_editor/open_scripts/smooth_scrolling"));
|
text_editor->set_smooth_scroll_enabled(EditorSettings::get_singleton()->get("text_editor/open_scripts/smooth_scrolling"));
|
||||||
text_editor->set_v_scroll_speed(EditorSettings::get_singleton()->get("text_editor/open_scripts/v_scroll_speed"));
|
text_editor->set_v_scroll_speed(EditorSettings::get_singleton()->get("text_editor/open_scripts/v_scroll_speed"));
|
||||||
|
|
|
@ -334,6 +334,7 @@ void EditorSettings::_load_defaults(Ref<ConfigFile> p_extra_config) {
|
||||||
_initial_set("text_editor/line_numbers/show_line_numbers", true);
|
_initial_set("text_editor/line_numbers/show_line_numbers", true);
|
||||||
_initial_set("text_editor/line_numbers/line_numbers_zero_padded", false);
|
_initial_set("text_editor/line_numbers/line_numbers_zero_padded", false);
|
||||||
_initial_set("text_editor/line_numbers/show_breakpoint_gutter", true);
|
_initial_set("text_editor/line_numbers/show_breakpoint_gutter", true);
|
||||||
|
_initial_set("text_editor/line_numbers/code_folding", true);
|
||||||
_initial_set("text_editor/line_numbers/show_line_length_guideline", false);
|
_initial_set("text_editor/line_numbers/show_line_length_guideline", false);
|
||||||
_initial_set("text_editor/line_numbers/line_length_guideline_column", 80);
|
_initial_set("text_editor/line_numbers/line_length_guideline_column", 80);
|
||||||
hints["text_editor/line_numbers/line_length_guideline_column"] = PropertyInfo(Variant::INT, "text_editor/line_numbers/line_length_guideline_column", PROPERTY_HINT_RANGE, "20, 160, 10");
|
hints["text_editor/line_numbers/line_length_guideline_column"] = PropertyInfo(Variant::INT, "text_editor/line_numbers/line_length_guideline_column", PROPERTY_HINT_RANGE, "20, 160, 10");
|
||||||
|
|
|
@ -518,7 +518,9 @@ void ScriptTextEditor::tag_saved_version() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void ScriptTextEditor::goto_line(int p_line, bool p_with_error) {
|
void ScriptTextEditor::goto_line(int p_line, bool p_with_error) {
|
||||||
code_editor->get_text_edit()->call_deferred("cursor_set_line", p_line);
|
TextEdit *tx = code_editor->get_text_edit();
|
||||||
|
tx->unfold_line(p_line);
|
||||||
|
tx->call_deferred("cursor_set_line", p_line);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ScriptTextEditor::ensure_focus() {
|
void ScriptTextEditor::ensure_focus() {
|
||||||
|
@ -712,15 +714,6 @@ void ScriptTextEditor::_breakpoint_toggled(int p_row) {
|
||||||
ScriptEditor::get_singleton()->get_debugger()->set_breakpoint(script->get_path(), p_row + 1, code_editor->get_text_edit()->is_line_set_as_breakpoint(p_row));
|
ScriptEditor::get_singleton()->get_debugger()->set_breakpoint(script->get_path(), p_row + 1, code_editor->get_text_edit()->is_line_set_as_breakpoint(p_row));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void swap_lines(TextEdit *tx, int line1, int line2) {
|
|
||||||
String tmp = tx->get_line(line1);
|
|
||||||
String tmp2 = tx->get_line(line2);
|
|
||||||
tx->set_line(line2, tmp);
|
|
||||||
tx->set_line(line1, tmp2);
|
|
||||||
|
|
||||||
tx->cursor_set_line(line2);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ScriptTextEditor::_lookup_symbol(const String &p_symbol, int p_row, int p_column) {
|
void ScriptTextEditor::_lookup_symbol(const String &p_symbol, int p_row, int p_column) {
|
||||||
|
|
||||||
Node *base = get_tree()->get_edited_scene_root();
|
Node *base = get_tree()->get_edited_scene_root();
|
||||||
|
@ -799,39 +792,41 @@ void ScriptTextEditor::_lookup_symbol(const String &p_symbol, int p_row, int p_c
|
||||||
|
|
||||||
void ScriptTextEditor::_edit_option(int p_op) {
|
void ScriptTextEditor::_edit_option(int p_op) {
|
||||||
|
|
||||||
|
TextEdit *tx = code_editor->get_text_edit();
|
||||||
|
|
||||||
switch (p_op) {
|
switch (p_op) {
|
||||||
case EDIT_UNDO: {
|
case EDIT_UNDO: {
|
||||||
code_editor->get_text_edit()->undo();
|
|
||||||
code_editor->get_text_edit()->call_deferred("grab_focus");
|
tx->undo();
|
||||||
|
tx->call_deferred("grab_focus");
|
||||||
} break;
|
} break;
|
||||||
case EDIT_REDO: {
|
case EDIT_REDO: {
|
||||||
code_editor->get_text_edit()->redo();
|
|
||||||
code_editor->get_text_edit()->call_deferred("grab_focus");
|
tx->redo();
|
||||||
|
tx->call_deferred("grab_focus");
|
||||||
} break;
|
} break;
|
||||||
case EDIT_CUT: {
|
case EDIT_CUT: {
|
||||||
|
|
||||||
code_editor->get_text_edit()->cut();
|
tx->cut();
|
||||||
code_editor->get_text_edit()->call_deferred("grab_focus");
|
tx->call_deferred("grab_focus");
|
||||||
} break;
|
} break;
|
||||||
case EDIT_COPY: {
|
case EDIT_COPY: {
|
||||||
code_editor->get_text_edit()->copy();
|
|
||||||
code_editor->get_text_edit()->call_deferred("grab_focus");
|
|
||||||
|
|
||||||
|
tx->copy();
|
||||||
|
tx->call_deferred("grab_focus");
|
||||||
} break;
|
} break;
|
||||||
case EDIT_PASTE: {
|
case EDIT_PASTE: {
|
||||||
code_editor->get_text_edit()->paste();
|
|
||||||
code_editor->get_text_edit()->call_deferred("grab_focus");
|
|
||||||
|
|
||||||
|
tx->paste();
|
||||||
|
tx->call_deferred("grab_focus");
|
||||||
} break;
|
} break;
|
||||||
case EDIT_SELECT_ALL: {
|
case EDIT_SELECT_ALL: {
|
||||||
|
|
||||||
code_editor->get_text_edit()->select_all();
|
tx->select_all();
|
||||||
code_editor->get_text_edit()->call_deferred("grab_focus");
|
tx->call_deferred("grab_focus");
|
||||||
|
|
||||||
} break;
|
} break;
|
||||||
case EDIT_MOVE_LINE_UP: {
|
case EDIT_MOVE_LINE_UP: {
|
||||||
|
|
||||||
TextEdit *tx = code_editor->get_text_edit();
|
|
||||||
Ref<Script> scr = script;
|
Ref<Script> scr = script;
|
||||||
if (scr.is_null())
|
if (scr.is_null())
|
||||||
return;
|
return;
|
||||||
|
@ -850,6 +845,9 @@ void ScriptTextEditor::_edit_option(int p_op) {
|
||||||
if (line_id == 0 || next_id < 0)
|
if (line_id == 0 || next_id < 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
tx->unfold_line(line_id);
|
||||||
|
tx->unfold_line(next_id);
|
||||||
|
|
||||||
tx->swap_lines(line_id, next_id);
|
tx->swap_lines(line_id, next_id);
|
||||||
tx->cursor_set_line(next_id);
|
tx->cursor_set_line(next_id);
|
||||||
}
|
}
|
||||||
|
@ -863,16 +861,17 @@ void ScriptTextEditor::_edit_option(int p_op) {
|
||||||
if (line_id == 0 || next_id < 0)
|
if (line_id == 0 || next_id < 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
tx->unfold_line(line_id);
|
||||||
|
tx->unfold_line(next_id);
|
||||||
|
|
||||||
tx->swap_lines(line_id, next_id);
|
tx->swap_lines(line_id, next_id);
|
||||||
tx->cursor_set_line(next_id);
|
tx->cursor_set_line(next_id);
|
||||||
}
|
}
|
||||||
tx->end_complex_operation();
|
tx->end_complex_operation();
|
||||||
tx->update();
|
tx->update();
|
||||||
|
|
||||||
} break;
|
} break;
|
||||||
case EDIT_MOVE_LINE_DOWN: {
|
case EDIT_MOVE_LINE_DOWN: {
|
||||||
|
|
||||||
TextEdit *tx = code_editor->get_text_edit();
|
|
||||||
Ref<Script> scr = get_edited_script();
|
Ref<Script> scr = get_edited_script();
|
||||||
if (scr.is_null())
|
if (scr.is_null())
|
||||||
return;
|
return;
|
||||||
|
@ -891,6 +890,9 @@ void ScriptTextEditor::_edit_option(int p_op) {
|
||||||
if (line_id == tx->get_line_count() - 1 || next_id > tx->get_line_count())
|
if (line_id == tx->get_line_count() - 1 || next_id > tx->get_line_count())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
tx->unfold_line(line_id);
|
||||||
|
tx->unfold_line(next_id);
|
||||||
|
|
||||||
tx->swap_lines(line_id, next_id);
|
tx->swap_lines(line_id, next_id);
|
||||||
tx->cursor_set_line(next_id);
|
tx->cursor_set_line(next_id);
|
||||||
}
|
}
|
||||||
|
@ -904,6 +906,9 @@ void ScriptTextEditor::_edit_option(int p_op) {
|
||||||
if (line_id == tx->get_line_count() - 1 || next_id > tx->get_line_count())
|
if (line_id == tx->get_line_count() - 1 || next_id > tx->get_line_count())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
tx->unfold_line(line_id);
|
||||||
|
tx->unfold_line(next_id);
|
||||||
|
|
||||||
tx->swap_lines(line_id, next_id);
|
tx->swap_lines(line_id, next_id);
|
||||||
tx->cursor_set_line(next_id);
|
tx->cursor_set_line(next_id);
|
||||||
}
|
}
|
||||||
|
@ -913,7 +918,6 @@ void ScriptTextEditor::_edit_option(int p_op) {
|
||||||
} break;
|
} break;
|
||||||
case EDIT_INDENT_LEFT: {
|
case EDIT_INDENT_LEFT: {
|
||||||
|
|
||||||
TextEdit *tx = code_editor->get_text_edit();
|
|
||||||
Ref<Script> scr = get_edited_script();
|
Ref<Script> scr = get_edited_script();
|
||||||
if (scr.is_null())
|
if (scr.is_null())
|
||||||
return;
|
return;
|
||||||
|
@ -938,11 +942,9 @@ void ScriptTextEditor::_edit_option(int p_op) {
|
||||||
tx->end_complex_operation();
|
tx->end_complex_operation();
|
||||||
tx->update();
|
tx->update();
|
||||||
//tx->deselect();
|
//tx->deselect();
|
||||||
|
|
||||||
} break;
|
} break;
|
||||||
case EDIT_INDENT_RIGHT: {
|
case EDIT_INDENT_RIGHT: {
|
||||||
|
|
||||||
TextEdit *tx = code_editor->get_text_edit();
|
|
||||||
Ref<Script> scr = get_edited_script();
|
Ref<Script> scr = get_edited_script();
|
||||||
if (scr.is_null())
|
if (scr.is_null())
|
||||||
return;
|
return;
|
||||||
|
@ -959,11 +961,9 @@ void ScriptTextEditor::_edit_option(int p_op) {
|
||||||
tx->end_complex_operation();
|
tx->end_complex_operation();
|
||||||
tx->update();
|
tx->update();
|
||||||
//tx->deselect();
|
//tx->deselect();
|
||||||
|
|
||||||
} break;
|
} break;
|
||||||
case EDIT_DELETE_LINE: {
|
case EDIT_DELETE_LINE: {
|
||||||
|
|
||||||
TextEdit *tx = code_editor->get_text_edit();
|
|
||||||
Ref<Script> scr = get_edited_script();
|
Ref<Script> scr = get_edited_script();
|
||||||
if (scr.is_null())
|
if (scr.is_null())
|
||||||
return;
|
return;
|
||||||
|
@ -972,13 +972,12 @@ void ScriptTextEditor::_edit_option(int p_op) {
|
||||||
int line = tx->cursor_get_line();
|
int line = tx->cursor_get_line();
|
||||||
tx->set_line(tx->cursor_get_line(), "");
|
tx->set_line(tx->cursor_get_line(), "");
|
||||||
tx->backspace_at_cursor();
|
tx->backspace_at_cursor();
|
||||||
|
tx->unfold_line(line);
|
||||||
tx->cursor_set_line(line);
|
tx->cursor_set_line(line);
|
||||||
tx->end_complex_operation();
|
tx->end_complex_operation();
|
||||||
|
|
||||||
} break;
|
} break;
|
||||||
case EDIT_CLONE_DOWN: {
|
case EDIT_CLONE_DOWN: {
|
||||||
|
|
||||||
TextEdit *tx = code_editor->get_text_edit();
|
|
||||||
Ref<Script> scr = get_edited_script();
|
Ref<Script> scr = get_edited_script();
|
||||||
if (scr.is_null())
|
if (scr.is_null())
|
||||||
return;
|
return;
|
||||||
|
@ -997,6 +996,7 @@ void ScriptTextEditor::_edit_option(int p_op) {
|
||||||
tx->begin_complex_operation();
|
tx->begin_complex_operation();
|
||||||
for (int i = from_line; i <= to_line; i++) {
|
for (int i = from_line; i <= to_line; i++) {
|
||||||
|
|
||||||
|
tx->unfold_line(i);
|
||||||
if (i >= tx->get_line_count() - 1) {
|
if (i >= tx->get_line_count() - 1) {
|
||||||
tx->set_line(i, tx->get_line(i) + "\n");
|
tx->set_line(i, tx->get_line(i) + "\n");
|
||||||
}
|
}
|
||||||
|
@ -1012,11 +1012,29 @@ void ScriptTextEditor::_edit_option(int p_op) {
|
||||||
|
|
||||||
tx->end_complex_operation();
|
tx->end_complex_operation();
|
||||||
tx->update();
|
tx->update();
|
||||||
|
} break;
|
||||||
|
case EDIT_FOLD_LINE: {
|
||||||
|
|
||||||
|
tx->fold_line(tx->cursor_get_line());
|
||||||
|
tx->update();
|
||||||
|
} break;
|
||||||
|
case EDIT_UNFOLD_LINE: {
|
||||||
|
|
||||||
|
tx->unfold_line(tx->cursor_get_line());
|
||||||
|
tx->update();
|
||||||
|
} break;
|
||||||
|
case EDIT_FOLD_ALL_LINES: {
|
||||||
|
|
||||||
|
tx->fold_all_lines();
|
||||||
|
tx->update();
|
||||||
|
} break;
|
||||||
|
case EDIT_UNFOLD_ALL_LINES: {
|
||||||
|
|
||||||
|
tx->unhide_all_lines();
|
||||||
|
tx->update();
|
||||||
} break;
|
} break;
|
||||||
case EDIT_TOGGLE_COMMENT: {
|
case EDIT_TOGGLE_COMMENT: {
|
||||||
|
|
||||||
TextEdit *tx = code_editor->get_text_edit();
|
|
||||||
Ref<Script> scr = get_edited_script();
|
Ref<Script> scr = get_edited_script();
|
||||||
if (scr.is_null())
|
if (scr.is_null())
|
||||||
return;
|
return;
|
||||||
|
@ -1065,62 +1083,65 @@ void ScriptTextEditor::_edit_option(int p_op) {
|
||||||
tx->end_complex_operation();
|
tx->end_complex_operation();
|
||||||
tx->update();
|
tx->update();
|
||||||
//tx->deselect();
|
//tx->deselect();
|
||||||
|
|
||||||
} break;
|
} break;
|
||||||
case EDIT_COMPLETE: {
|
case EDIT_COMPLETE: {
|
||||||
|
|
||||||
code_editor->get_text_edit()->query_code_comple();
|
tx->query_code_comple();
|
||||||
|
|
||||||
} break;
|
} break;
|
||||||
case EDIT_AUTO_INDENT: {
|
case EDIT_AUTO_INDENT: {
|
||||||
|
|
||||||
TextEdit *te = code_editor->get_text_edit();
|
String text = tx->get_text();
|
||||||
String text = te->get_text();
|
|
||||||
Ref<Script> scr = get_edited_script();
|
Ref<Script> scr = get_edited_script();
|
||||||
if (scr.is_null())
|
if (scr.is_null())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
te->begin_complex_operation();
|
tx->begin_complex_operation();
|
||||||
int begin, end;
|
int begin, end;
|
||||||
if (te->is_selection_active()) {
|
if (tx->is_selection_active()) {
|
||||||
begin = te->get_selection_from_line();
|
begin = tx->get_selection_from_line();
|
||||||
end = te->get_selection_to_line();
|
end = tx->get_selection_to_line();
|
||||||
// ignore if the cursor is not past the first column
|
// ignore if the cursor is not past the first column
|
||||||
if (te->get_selection_to_column() == 0) {
|
if (tx->get_selection_to_column() == 0) {
|
||||||
end--;
|
end--;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
begin = 0;
|
begin = 0;
|
||||||
end = te->get_line_count() - 1;
|
end = tx->get_line_count() - 1;
|
||||||
}
|
}
|
||||||
scr->get_language()->auto_indent_code(text, begin, end);
|
scr->get_language()->auto_indent_code(text, begin, end);
|
||||||
Vector<String> lines = text.split("\n");
|
Vector<String> lines = text.split("\n");
|
||||||
for (int i = begin; i <= end; ++i) {
|
for (int i = begin; i <= end; ++i) {
|
||||||
te->set_line(i, lines[i]);
|
tx->set_line(i, lines[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
te->end_complex_operation();
|
tx->end_complex_operation();
|
||||||
|
|
||||||
} break;
|
} break;
|
||||||
case EDIT_TRIM_TRAILING_WHITESAPCE: {
|
case EDIT_TRIM_TRAILING_WHITESAPCE: {
|
||||||
|
|
||||||
trim_trailing_whitespace();
|
trim_trailing_whitespace();
|
||||||
} break;
|
} break;
|
||||||
case EDIT_CONVERT_INDENT_TO_SPACES: {
|
case EDIT_CONVERT_INDENT_TO_SPACES: {
|
||||||
|
|
||||||
convert_indent_to_spaces();
|
convert_indent_to_spaces();
|
||||||
} break;
|
} break;
|
||||||
case EDIT_CONVERT_INDENT_TO_TABS: {
|
case EDIT_CONVERT_INDENT_TO_TABS: {
|
||||||
|
|
||||||
convert_indent_to_tabs();
|
convert_indent_to_tabs();
|
||||||
} break;
|
} break;
|
||||||
case EDIT_PICK_COLOR: {
|
case EDIT_PICK_COLOR: {
|
||||||
|
|
||||||
color_panel->popup();
|
color_panel->popup();
|
||||||
} break;
|
} break;
|
||||||
case EDIT_TO_UPPERCASE: {
|
case EDIT_TO_UPPERCASE: {
|
||||||
|
|
||||||
_convert_case(UPPER);
|
_convert_case(UPPER);
|
||||||
} break;
|
} break;
|
||||||
case EDIT_TO_LOWERCASE: {
|
case EDIT_TO_LOWERCASE: {
|
||||||
|
|
||||||
_convert_case(LOWER);
|
_convert_case(LOWER);
|
||||||
} break;
|
} break;
|
||||||
case EDIT_CAPITALIZE: {
|
case EDIT_CAPITALIZE: {
|
||||||
|
|
||||||
_convert_case(CAPITALIZE);
|
_convert_case(CAPITALIZE);
|
||||||
} break;
|
} break;
|
||||||
case SEARCH_FIND: {
|
case SEARCH_FIND: {
|
||||||
|
@ -1145,41 +1166,47 @@ void ScriptTextEditor::_edit_option(int p_op) {
|
||||||
} break;
|
} break;
|
||||||
case SEARCH_GOTO_LINE: {
|
case SEARCH_GOTO_LINE: {
|
||||||
|
|
||||||
goto_line_dialog->popup_find_line(code_editor->get_text_edit());
|
goto_line_dialog->popup_find_line(tx);
|
||||||
} break;
|
} break;
|
||||||
case DEBUG_TOGGLE_BREAKPOINT: {
|
case DEBUG_TOGGLE_BREAKPOINT: {
|
||||||
int line = code_editor->get_text_edit()->cursor_get_line();
|
|
||||||
bool dobreak = !code_editor->get_text_edit()->is_line_set_as_breakpoint(line);
|
int line = tx->cursor_get_line();
|
||||||
code_editor->get_text_edit()->set_line_as_breakpoint(line, dobreak);
|
bool dobreak = !tx->is_line_set_as_breakpoint(line);
|
||||||
|
tx->set_line_as_breakpoint(line, dobreak);
|
||||||
ScriptEditor::get_singleton()->get_debugger()->set_breakpoint(get_edited_script()->get_path(), line + 1, dobreak);
|
ScriptEditor::get_singleton()->get_debugger()->set_breakpoint(get_edited_script()->get_path(), line + 1, dobreak);
|
||||||
} break;
|
} break;
|
||||||
case DEBUG_REMOVE_ALL_BREAKPOINTS: {
|
case DEBUG_REMOVE_ALL_BREAKPOINTS: {
|
||||||
|
|
||||||
List<int> bpoints;
|
List<int> bpoints;
|
||||||
code_editor->get_text_edit()->get_breakpoints(&bpoints);
|
tx->get_breakpoints(&bpoints);
|
||||||
|
|
||||||
for (List<int>::Element *E = bpoints.front(); E; E = E->next()) {
|
for (List<int>::Element *E = bpoints.front(); E; E = E->next()) {
|
||||||
int line = E->get();
|
int line = E->get();
|
||||||
bool dobreak = !code_editor->get_text_edit()->is_line_set_as_breakpoint(line);
|
bool dobreak = !tx->is_line_set_as_breakpoint(line);
|
||||||
code_editor->get_text_edit()->set_line_as_breakpoint(line, dobreak);
|
tx->set_line_as_breakpoint(line, dobreak);
|
||||||
ScriptEditor::get_singleton()->get_debugger()->set_breakpoint(get_edited_script()->get_path(), line + 1, dobreak);
|
ScriptEditor::get_singleton()->get_debugger()->set_breakpoint(get_edited_script()->get_path(), line + 1, dobreak);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
case DEBUG_GOTO_NEXT_BREAKPOINT: {
|
case DEBUG_GOTO_NEXT_BREAKPOINT: {
|
||||||
|
|
||||||
List<int> bpoints;
|
List<int> bpoints;
|
||||||
code_editor->get_text_edit()->get_breakpoints(&bpoints);
|
tx->get_breakpoints(&bpoints);
|
||||||
if (bpoints.size() <= 0) {
|
if (bpoints.size() <= 0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
int line = code_editor->get_text_edit()->cursor_get_line();
|
int line = tx->cursor_get_line();
|
||||||
|
|
||||||
// wrap around
|
// wrap around
|
||||||
if (line >= bpoints[bpoints.size() - 1]) {
|
if (line >= bpoints[bpoints.size() - 1]) {
|
||||||
code_editor->get_text_edit()->cursor_set_line(bpoints[0]);
|
tx->unfold_line(bpoints[0]);
|
||||||
|
tx->cursor_set_line(bpoints[0]);
|
||||||
} else {
|
} else {
|
||||||
for (List<int>::Element *E = bpoints.front(); E; E = E->next()) {
|
for (List<int>::Element *E = bpoints.front(); E; E = E->next()) {
|
||||||
int bline = E->get();
|
int bline = E->get();
|
||||||
if (bline > line) {
|
if (bline > line) {
|
||||||
code_editor->get_text_edit()->cursor_set_line(bline);
|
tx->unfold_line(bline);
|
||||||
|
tx->cursor_set_line(bline);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1187,21 +1214,24 @@ void ScriptTextEditor::_edit_option(int p_op) {
|
||||||
|
|
||||||
} break;
|
} break;
|
||||||
case DEBUG_GOTO_PREV_BREAKPOINT: {
|
case DEBUG_GOTO_PREV_BREAKPOINT: {
|
||||||
|
|
||||||
List<int> bpoints;
|
List<int> bpoints;
|
||||||
code_editor->get_text_edit()->get_breakpoints(&bpoints);
|
tx->get_breakpoints(&bpoints);
|
||||||
if (bpoints.size() <= 0) {
|
if (bpoints.size() <= 0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
int line = code_editor->get_text_edit()->cursor_get_line();
|
int line = tx->cursor_get_line();
|
||||||
// wrap around
|
// wrap around
|
||||||
if (line <= bpoints[0]) {
|
if (line <= bpoints[0]) {
|
||||||
code_editor->get_text_edit()->cursor_set_line(bpoints[bpoints.size() - 1]);
|
tx->unfold_line(bpoints[bpoints.size() - 1]);
|
||||||
|
tx->cursor_set_line(bpoints[bpoints.size() - 1]);
|
||||||
} else {
|
} else {
|
||||||
for (List<int>::Element *E = bpoints.back(); E; E = E->prev()) {
|
for (List<int>::Element *E = bpoints.back(); E; E = E->prev()) {
|
||||||
int bline = E->get();
|
int bline = E->get();
|
||||||
if (bline < line) {
|
if (bline < line) {
|
||||||
code_editor->get_text_edit()->cursor_set_line(bline);
|
tx->unfold_line(bline);
|
||||||
|
tx->cursor_set_line(bline);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1210,9 +1240,10 @@ void ScriptTextEditor::_edit_option(int p_op) {
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case HELP_CONTEXTUAL: {
|
case HELP_CONTEXTUAL: {
|
||||||
String text = code_editor->get_text_edit()->get_selection_text();
|
|
||||||
|
String text = tx->get_selection_text();
|
||||||
if (text == "")
|
if (text == "")
|
||||||
text = code_editor->get_text_edit()->get_word_under_cursor();
|
text = tx->get_word_under_cursor();
|
||||||
if (text != "") {
|
if (text != "") {
|
||||||
emit_signal("request_help_search", text);
|
emit_signal("request_help_search", text);
|
||||||
}
|
}
|
||||||
|
@ -1398,6 +1429,9 @@ void ScriptTextEditor::_text_edit_gui_input(const Ref<InputEvent> &ev) {
|
||||||
Vector2 mpos = mb->get_global_position() - tx->get_global_position();
|
Vector2 mpos = mb->get_global_position() - tx->get_global_position();
|
||||||
bool have_selection = (tx->get_selection_text().length() > 0);
|
bool have_selection = (tx->get_selection_text().length() > 0);
|
||||||
bool have_color = (tx->get_word_at_pos(mpos) == "Color");
|
bool have_color = (tx->get_word_at_pos(mpos) == "Color");
|
||||||
|
int fold_state = 0;
|
||||||
|
bool can_fold = tx->can_fold(row);
|
||||||
|
bool is_folded = tx->is_folded(row);
|
||||||
if (have_color) {
|
if (have_color) {
|
||||||
|
|
||||||
String line = tx->get_line(row);
|
String line = tx->get_line(row);
|
||||||
|
@ -1428,7 +1462,7 @@ void ScriptTextEditor::_text_edit_gui_input(const Ref<InputEvent> &ev) {
|
||||||
have_color = false;
|
have_color = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_make_context_menu(have_selection, have_color);
|
_make_context_menu(have_selection, have_color, can_fold, is_folded);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1447,7 +1481,7 @@ void ScriptTextEditor::_color_changed(const Color &p_color) {
|
||||||
code_editor->get_text_edit()->set_line(color_line, new_line);
|
code_editor->get_text_edit()->set_line(color_line, new_line);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ScriptTextEditor::_make_context_menu(bool p_selection, bool p_color) {
|
void ScriptTextEditor::_make_context_menu(bool p_selection, bool p_color, bool p_can_fold, bool p_is_folded) {
|
||||||
|
|
||||||
context_menu->clear();
|
context_menu->clear();
|
||||||
if (p_selection) {
|
if (p_selection) {
|
||||||
|
@ -1467,6 +1501,13 @@ void ScriptTextEditor::_make_context_menu(bool p_selection, bool p_color) {
|
||||||
context_menu->add_shortcut(ED_GET_SHORTCUT("script_text_editor/indent_right"), EDIT_INDENT_RIGHT);
|
context_menu->add_shortcut(ED_GET_SHORTCUT("script_text_editor/indent_right"), EDIT_INDENT_RIGHT);
|
||||||
context_menu->add_shortcut(ED_GET_SHORTCUT("script_text_editor/toggle_comment"), EDIT_TOGGLE_COMMENT);
|
context_menu->add_shortcut(ED_GET_SHORTCUT("script_text_editor/toggle_comment"), EDIT_TOGGLE_COMMENT);
|
||||||
}
|
}
|
||||||
|
if (p_can_fold) {
|
||||||
|
// can fold
|
||||||
|
context_menu->add_shortcut(ED_GET_SHORTCUT("script_text_editor/fold_line"), EDIT_FOLD_LINE);
|
||||||
|
} else if (p_is_folded) {
|
||||||
|
// can unfold
|
||||||
|
context_menu->add_shortcut(ED_GET_SHORTCUT("script_text_editor/unfold_line"), EDIT_UNFOLD_LINE);
|
||||||
|
}
|
||||||
if (p_color) {
|
if (p_color) {
|
||||||
context_menu->add_separator();
|
context_menu->add_separator();
|
||||||
context_menu->add_item(TTR("Pick Color"), EDIT_PICK_COLOR);
|
context_menu->add_item(TTR("Pick Color"), EDIT_PICK_COLOR);
|
||||||
|
@ -1530,6 +1571,10 @@ ScriptTextEditor::ScriptTextEditor() {
|
||||||
edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/delete_line"), EDIT_DELETE_LINE);
|
edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/delete_line"), EDIT_DELETE_LINE);
|
||||||
edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/toggle_comment"), EDIT_TOGGLE_COMMENT);
|
edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/toggle_comment"), EDIT_TOGGLE_COMMENT);
|
||||||
edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/clone_down"), EDIT_CLONE_DOWN);
|
edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/clone_down"), EDIT_CLONE_DOWN);
|
||||||
|
edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/fold_line"), EDIT_FOLD_LINE);
|
||||||
|
edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/fold_all_lines"), EDIT_FOLD_ALL_LINES);
|
||||||
|
edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/unfold_line"), EDIT_UNFOLD_LINE);
|
||||||
|
edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/unfold_all_lines"), EDIT_UNFOLD_ALL_LINES);
|
||||||
edit_menu->get_popup()->add_separator();
|
edit_menu->get_popup()->add_separator();
|
||||||
#ifdef OSX_ENABLED
|
#ifdef OSX_ENABLED
|
||||||
edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/complete_symbol"), EDIT_COMPLETE);
|
edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/complete_symbol"), EDIT_COMPLETE);
|
||||||
|
@ -1607,6 +1652,10 @@ void ScriptTextEditor::register_editor() {
|
||||||
ED_SHORTCUT("script_text_editor/indent_right", TTR("Indent Right"), 0);
|
ED_SHORTCUT("script_text_editor/indent_right", TTR("Indent Right"), 0);
|
||||||
ED_SHORTCUT("script_text_editor/toggle_comment", TTR("Toggle Comment"), KEY_MASK_CMD | KEY_K);
|
ED_SHORTCUT("script_text_editor/toggle_comment", TTR("Toggle Comment"), KEY_MASK_CMD | KEY_K);
|
||||||
ED_SHORTCUT("script_text_editor/clone_down", TTR("Clone Down"), KEY_MASK_CMD | KEY_B);
|
ED_SHORTCUT("script_text_editor/clone_down", TTR("Clone Down"), KEY_MASK_CMD | KEY_B);
|
||||||
|
ED_SHORTCUT("script_text_editor/fold_line", TTR("Fold Line"), KEY_MASK_ALT | KEY_LEFT);
|
||||||
|
ED_SHORTCUT("script_text_editor/unfold_line", TTR("Unfold Line"), KEY_MASK_ALT | KEY_RIGHT);
|
||||||
|
ED_SHORTCUT("script_text_editor/fold_all_lines", TTR("Fold All Lines"), 0);
|
||||||
|
ED_SHORTCUT("script_text_editor/unfold_all_lines", TTR("Unfold All Lines"), 0);
|
||||||
#ifdef OSX_ENABLED
|
#ifdef OSX_ENABLED
|
||||||
ED_SHORTCUT("script_text_editor/complete_symbol", TTR("Complete Symbol"), KEY_MASK_CTRL | KEY_SPACE);
|
ED_SHORTCUT("script_text_editor/complete_symbol", TTR("Complete Symbol"), KEY_MASK_CTRL | KEY_SPACE);
|
||||||
#else
|
#else
|
||||||
|
|
|
@ -91,6 +91,10 @@ class ScriptTextEditor : public ScriptEditorBase {
|
||||||
EDIT_TO_UPPERCASE,
|
EDIT_TO_UPPERCASE,
|
||||||
EDIT_TO_LOWERCASE,
|
EDIT_TO_LOWERCASE,
|
||||||
EDIT_CAPITALIZE,
|
EDIT_CAPITALIZE,
|
||||||
|
EDIT_FOLD_LINE,
|
||||||
|
EDIT_UNFOLD_LINE,
|
||||||
|
EDIT_FOLD_ALL_LINES,
|
||||||
|
EDIT_UNFOLD_ALL_LINES,
|
||||||
SEARCH_FIND,
|
SEARCH_FIND,
|
||||||
SEARCH_FIND_NEXT,
|
SEARCH_FIND_NEXT,
|
||||||
SEARCH_FIND_PREV,
|
SEARCH_FIND_PREV,
|
||||||
|
@ -118,7 +122,7 @@ protected:
|
||||||
static void _bind_methods();
|
static void _bind_methods();
|
||||||
|
|
||||||
void _edit_option(int p_op);
|
void _edit_option(int p_op);
|
||||||
void _make_context_menu(bool p_selection, bool p_color);
|
void _make_context_menu(bool p_selection, bool p_color, bool p_can_fold, bool p_is_folded);
|
||||||
void _text_edit_gui_input(const Ref<InputEvent> &ev);
|
void _text_edit_gui_input(const Ref<InputEvent> &ev);
|
||||||
void _color_changed(const Color &p_color);
|
void _color_changed(const Color &p_color);
|
||||||
|
|
||||||
|
|
|
@ -274,6 +274,7 @@ void TextEdit::Text::insert(int p_at, const String &p_text) {
|
||||||
Line line;
|
Line line;
|
||||||
line.marked = false;
|
line.marked = false;
|
||||||
line.breakpoint = false;
|
line.breakpoint = false;
|
||||||
|
line.hidden = false;
|
||||||
line.width_cache = -1;
|
line.width_cache = -1;
|
||||||
line.data = p_text;
|
line.data = p_text;
|
||||||
text.insert(p_at, line);
|
text.insert(p_at, line);
|
||||||
|
@ -297,9 +298,11 @@ void TextEdit::_update_scrollbars() {
|
||||||
|
|
||||||
int hscroll_rows = ((hmin.height - 1) / get_row_height()) + 1;
|
int hscroll_rows = ((hmin.height - 1) / get_row_height()) + 1;
|
||||||
int visible_rows = get_visible_rows();
|
int visible_rows = get_visible_rows();
|
||||||
int total_rows = text.size();
|
int num_rows = MAX(visible_rows, num_lines_from(CLAMP(cursor.line_ofs, 0, text.size() - 1), MIN(visible_rows, text.size() - 1 - cursor.line_ofs)));
|
||||||
|
|
||||||
|
int total_rows = (is_hiding_enabled() ? get_total_unhidden_rows() : text.size());
|
||||||
if (scroll_past_end_of_file_enabled) {
|
if (scroll_past_end_of_file_enabled) {
|
||||||
total_rows += get_visible_rows() - 1;
|
total_rows += visible_rows - 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int vscroll_pixels = v_scroll->get_combined_minimum_size().width;
|
int vscroll_pixels = v_scroll->get_combined_minimum_size().width;
|
||||||
|
@ -313,6 +316,10 @@ void TextEdit::_update_scrollbars() {
|
||||||
total_width += cache.breakpoint_gutter_width;
|
total_width += cache.breakpoint_gutter_width;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (draw_fold_gutter) {
|
||||||
|
total_width += cache.fold_gutter_width;
|
||||||
|
}
|
||||||
|
|
||||||
bool use_hscroll = true;
|
bool use_hscroll = true;
|
||||||
bool use_vscroll = true;
|
bool use_vscroll = true;
|
||||||
|
|
||||||
|
@ -347,12 +354,11 @@ void TextEdit::_update_scrollbars() {
|
||||||
v_scroll->set_step(1);
|
v_scroll->set_step(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fabs(v_scroll->get_value() - (double)cursor.line_ofs) >= 1) {
|
update_line_scroll_pos();
|
||||||
v_scroll->set_value(cursor.line_ofs);
|
|
||||||
}
|
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
cursor.line_ofs = 0;
|
cursor.line_ofs = 0;
|
||||||
|
line_scroll_pos = 0;
|
||||||
|
v_scroll->set_value(0);
|
||||||
v_scroll->hide();
|
v_scroll->hide();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -551,6 +557,13 @@ void TextEdit::_notification(int p_what) {
|
||||||
cache.breakpoint_gutter_width = 0;
|
cache.breakpoint_gutter_width = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (draw_fold_gutter) {
|
||||||
|
fold_gutter_width = (get_row_height() * 55) / 100;
|
||||||
|
cache.fold_gutter_width = fold_gutter_width;
|
||||||
|
} else {
|
||||||
|
cache.fold_gutter_width = 0;
|
||||||
|
}
|
||||||
|
|
||||||
int line_number_char_count = 0;
|
int line_number_char_count = 0;
|
||||||
|
|
||||||
{
|
{
|
||||||
|
@ -573,7 +586,7 @@ void TextEdit::_notification(int p_what) {
|
||||||
|
|
||||||
RID ci = get_canvas_item();
|
RID ci = get_canvas_item();
|
||||||
VisualServer::get_singleton()->canvas_item_set_clip(get_canvas_item(), true);
|
VisualServer::get_singleton()->canvas_item_set_clip(get_canvas_item(), true);
|
||||||
int xmargin_beg = cache.style_normal->get_margin(MARGIN_LEFT) + cache.line_number_w + cache.breakpoint_gutter_width;
|
int xmargin_beg = cache.style_normal->get_margin(MARGIN_LEFT) + cache.line_number_w + cache.breakpoint_gutter_width + cache.fold_gutter_width;
|
||||||
int xmargin_end = cache.size.width - cache.style_normal->get_margin(MARGIN_RIGHT);
|
int xmargin_end = cache.size.width - cache.style_normal->get_margin(MARGIN_RIGHT);
|
||||||
//let's do it easy for now:
|
//let's do it easy for now:
|
||||||
cache.style_normal->draw(ci, Rect2(Point2(), cache.size));
|
cache.style_normal->draw(ci, Rect2(Point2(), cache.size));
|
||||||
|
@ -780,10 +793,22 @@ void TextEdit::_notification(int p_what) {
|
||||||
String highlighted_text = get_selection_text();
|
String highlighted_text = get_selection_text();
|
||||||
|
|
||||||
String line_num_padding = line_numbers_zero_padded ? "0" : " ";
|
String line_num_padding = line_numbers_zero_padded ? "0" : " ";
|
||||||
|
update_line_scroll_pos();
|
||||||
|
|
||||||
|
int line = cursor.line_ofs - 1;
|
||||||
for (int i = 0; i < visible_rows; i++) {
|
for (int i = 0; i < visible_rows; i++) {
|
||||||
|
|
||||||
int line = i + cursor.line_ofs;
|
line++;
|
||||||
|
|
||||||
|
if (line < 0 || line >= (int)text.size())
|
||||||
|
continue;
|
||||||
|
|
||||||
|
while (is_line_hidden(line)) {
|
||||||
|
line++;
|
||||||
|
if (line < 0 || line >= (int)text.size()) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (line < 0 || line >= (int)text.size())
|
if (line < 0 || line >= (int)text.size())
|
||||||
continue;
|
continue;
|
||||||
|
@ -794,7 +819,7 @@ void TextEdit::_notification(int p_what) {
|
||||||
int char_ofs = 0;
|
int char_ofs = 0;
|
||||||
int ofs_y = (i * get_row_height() + cache.line_spacing / 2);
|
int ofs_y = (i * get_row_height() + cache.line_spacing / 2);
|
||||||
if (smooth_scroll_enabled) {
|
if (smooth_scroll_enabled) {
|
||||||
ofs_y -= (v_scroll->get_value() - cursor.line_ofs) * get_row_height();
|
ofs_y -= (v_scroll->get_value() - get_line_scroll_pos()) * get_row_height();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool prev_is_char = false;
|
bool prev_is_char = false;
|
||||||
|
@ -857,6 +882,21 @@ void TextEdit::_notification(int p_what) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// draw fold markers
|
||||||
|
if (draw_fold_gutter) {
|
||||||
|
int horizontal_gap = (cache.fold_gutter_width * 30) / 100;
|
||||||
|
int gutter_left = cache.style_normal->get_margin(MARGIN_LEFT) + cache.breakpoint_gutter_width + cache.line_number_w;
|
||||||
|
if (is_folded(line)) {
|
||||||
|
int xofs = horizontal_gap - (cache.can_fold_icon->get_width()) / 2;
|
||||||
|
int yofs = (get_row_height() - cache.folded_icon->get_height()) / 2;
|
||||||
|
cache.folded_icon->draw(ci, Point2(gutter_left + xofs, ofs_y + yofs), Color(0.8f, 0.8f, 0.8f, 0.8f));
|
||||||
|
} else if (can_fold(line)) {
|
||||||
|
int xofs = -cache.can_fold_icon->get_width() / 2 - horizontal_gap + 3;
|
||||||
|
int yofs = (get_row_height() - cache.can_fold_icon->get_height()) / 2;
|
||||||
|
cache.can_fold_icon->draw(ci, Point2(gutter_left + xofs, ofs_y + yofs), Color(0.8f, 0.8f, 0.8f, 0.8f));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (cache.line_number_w) {
|
if (cache.line_number_w) {
|
||||||
String fc = String::num(line + 1);
|
String fc = String::num(line + 1);
|
||||||
while (fc.length() < line_number_char_count) {
|
while (fc.length() < line_number_char_count) {
|
||||||
|
@ -1196,6 +1236,10 @@ void TextEdit::_notification(int p_what) {
|
||||||
}
|
}
|
||||||
|
|
||||||
char_ofs += char_w;
|
char_ofs += char_w;
|
||||||
|
|
||||||
|
if (j == str.length() - 1 && is_folded(line)) {
|
||||||
|
cache.folded_eol_icon->draw(ci, Point2(char_ofs + char_margin, ofs_y), Color(1, 1, 1, 1), true);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cursor.column == str.length() && cursor.line == line && (char_ofs + char_margin) >= xmargin_beg) {
|
if (cursor.column == str.length() && cursor.line == line && (char_ofs + char_margin) >= xmargin_beg) {
|
||||||
|
@ -1538,6 +1582,12 @@ void TextEdit::backspace_at_cursor() {
|
||||||
|
|
||||||
int prev_line = cursor.column ? cursor.line : cursor.line - 1;
|
int prev_line = cursor.column ? cursor.line : cursor.line - 1;
|
||||||
int prev_column = cursor.column ? (cursor.column - 1) : (text[cursor.line - 1].length());
|
int prev_column = cursor.column ? (cursor.column - 1) : (text[cursor.line - 1].length());
|
||||||
|
|
||||||
|
if (is_line_hidden(cursor.line))
|
||||||
|
set_line_as_hidden(prev_line, true);
|
||||||
|
if (is_line_set_as_breakpoint(cursor.line))
|
||||||
|
set_line_as_breakpoint(prev_line, true);
|
||||||
|
|
||||||
if (auto_brace_completion_enabled &&
|
if (auto_brace_completion_enabled &&
|
||||||
cursor.column > 0 &&
|
cursor.column > 0 &&
|
||||||
_is_pair_left_symbol(text[cursor.line][cursor.column - 1])) {
|
_is_pair_left_symbol(text[cursor.line][cursor.column - 1])) {
|
||||||
|
@ -1577,7 +1627,7 @@ void TextEdit::backspace_at_cursor() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
cursor_set_line(prev_line);
|
cursor_set_line(prev_line, true, true);
|
||||||
cursor_set_column(prev_column);
|
cursor_set_column(prev_column);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1651,10 +1701,18 @@ void TextEdit::_get_mouse_pos(const Point2i &p_mouse, int &r_row, int &r_col) co
|
||||||
float rows = p_mouse.y;
|
float rows = p_mouse.y;
|
||||||
rows -= cache.style_normal->get_margin(MARGIN_TOP);
|
rows -= cache.style_normal->get_margin(MARGIN_TOP);
|
||||||
rows /= get_row_height();
|
rows /= get_row_height();
|
||||||
int row = cursor.line_ofs + (rows + (v_scroll->get_value() - cursor.line_ofs));
|
int lsp = get_line_scroll_pos(true);
|
||||||
|
int row = cursor.line_ofs + (rows + (v_scroll->get_value() - lsp));
|
||||||
|
|
||||||
|
if (is_hiding_enabled()) {
|
||||||
|
// row will be offset by the hidden rows
|
||||||
|
int f_ofs = num_lines_from(CLAMP(cursor.line_ofs, 0, text.size() - 1), MIN(rows + 1, text.size() - cursor.line_ofs)) - 1;
|
||||||
|
row = cursor.line_ofs + (f_ofs + (v_scroll->get_value() - lsp));
|
||||||
|
row = CLAMP(row, 0, text.size() - num_lines_from(text.size() - 1, -1));
|
||||||
|
}
|
||||||
|
|
||||||
if (row < 0)
|
if (row < 0)
|
||||||
row = 0;
|
row = 0; //todo
|
||||||
|
|
||||||
int col = 0;
|
int col = 0;
|
||||||
|
|
||||||
|
@ -1664,7 +1722,7 @@ void TextEdit::_get_mouse_pos(const Point2i &p_mouse, int &r_row, int &r_col) co
|
||||||
col = text[row].size();
|
col = text[row].size();
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
col = p_mouse.x - (cache.style_normal->get_margin(MARGIN_LEFT) + cache.line_number_w + cache.breakpoint_gutter_width);
|
col = p_mouse.x - (cache.style_normal->get_margin(MARGIN_LEFT) + cache.line_number_w + cache.breakpoint_gutter_width + cache.fold_gutter_width);
|
||||||
col += cursor.x_ofs;
|
col += cursor.x_ofs;
|
||||||
col = get_char_pos_for(col, get_line(row));
|
col = get_char_pos_for(col, get_line(row));
|
||||||
}
|
}
|
||||||
|
@ -1717,10 +1775,11 @@ void TextEdit::_gui_input(const Ref<InputEvent> &p_gui_input) {
|
||||||
if (mb->is_pressed()) {
|
if (mb->is_pressed()) {
|
||||||
|
|
||||||
if (mb->get_button_index() == BUTTON_WHEEL_UP && !mb->get_command()) {
|
if (mb->get_button_index() == BUTTON_WHEEL_UP && !mb->get_command()) {
|
||||||
|
float scroll_factor = 3 * mb->get_factor();
|
||||||
if (scrolling) {
|
if (scrolling) {
|
||||||
target_v_scroll = (target_v_scroll - (3 * mb->get_factor()));
|
target_v_scroll = (target_v_scroll - scroll_factor);
|
||||||
} else {
|
} else {
|
||||||
target_v_scroll = (v_scroll->get_value() - (3 * mb->get_factor()));
|
target_v_scroll = (v_scroll->get_value() - scroll_factor);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (smooth_scroll_enabled) {
|
if (smooth_scroll_enabled) {
|
||||||
|
@ -1734,16 +1793,18 @@ void TextEdit::_gui_input(const Ref<InputEvent> &p_gui_input) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (mb->get_button_index() == BUTTON_WHEEL_DOWN && !mb->get_command()) {
|
if (mb->get_button_index() == BUTTON_WHEEL_DOWN && !mb->get_command()) {
|
||||||
|
float scroll_factor = 3 * mb->get_factor();
|
||||||
if (scrolling) {
|
if (scrolling) {
|
||||||
target_v_scroll = (target_v_scroll + (3 * mb->get_factor()));
|
target_v_scroll = (target_v_scroll + scroll_factor);
|
||||||
} else {
|
} else {
|
||||||
target_v_scroll = (v_scroll->get_value() + (3 * mb->get_factor()));
|
target_v_scroll = (v_scroll->get_value() + scroll_factor);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (smooth_scroll_enabled) {
|
if (smooth_scroll_enabled) {
|
||||||
int max_v_scroll = get_line_count() - 1;
|
int max_v_scroll = get_total_unhidden_rows();
|
||||||
if (!scroll_past_end_of_file_enabled) {
|
if (!scroll_past_end_of_file_enabled) {
|
||||||
max_v_scroll -= get_visible_rows() - 1;
|
max_v_scroll -= get_visible_rows();
|
||||||
|
max_v_scroll = CLAMP(max_v_scroll, 0, get_total_unhidden_rows());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (target_v_scroll > max_v_scroll) {
|
if (target_v_scroll > max_v_scroll) {
|
||||||
|
@ -1766,6 +1827,7 @@ void TextEdit::_gui_input(const Ref<InputEvent> &p_gui_input) {
|
||||||
_reset_caret_blink_timer();
|
_reset_caret_blink_timer();
|
||||||
|
|
||||||
int row, col;
|
int row, col;
|
||||||
|
update_line_scroll_pos();
|
||||||
_get_mouse_pos(Point2i(mb->get_position().x, mb->get_position().y), row, col);
|
_get_mouse_pos(Point2i(mb->get_position().x, mb->get_position().y), row, col);
|
||||||
|
|
||||||
if (mb->get_command() && highlighted_word != String()) {
|
if (mb->get_command() && highlighted_word != String()) {
|
||||||
|
@ -1784,10 +1846,35 @@ void TextEdit::_gui_input(const Ref<InputEvent> &p_gui_input) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// toggle fold on gutter click if can
|
||||||
|
if (draw_fold_gutter) {
|
||||||
|
|
||||||
|
int left_margin = cache.style_normal->get_margin(MARGIN_LEFT);
|
||||||
|
int gutter_left = left_margin + cache.breakpoint_gutter_width + cache.line_number_w;
|
||||||
|
if (mb->get_position().x > gutter_left - 6 && mb->get_position().x <= gutter_left + cache.fold_gutter_width - 3) {
|
||||||
|
if (is_folded(row)) {
|
||||||
|
unfold_line(row);
|
||||||
|
} else if (can_fold(row)) {
|
||||||
|
fold_line(row);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// unfold on folded icon click
|
||||||
|
if (is_folded(row)) {
|
||||||
|
int line_width = text.get_line_width(row);
|
||||||
|
line_width += cache.style_normal->get_margin(MARGIN_LEFT) + cache.line_number_w + cache.breakpoint_gutter_width + cache.fold_gutter_width - cursor.x_ofs;
|
||||||
|
if (mb->get_position().x > line_width - 3 && mb->get_position().x <= line_width + cache.folded_eol_icon->get_width() + 3) {
|
||||||
|
unfold_line(row);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
int prev_col = cursor.column;
|
int prev_col = cursor.column;
|
||||||
int prev_line = cursor.line;
|
int prev_line = cursor.line;
|
||||||
|
|
||||||
cursor_set_line(row);
|
cursor_set_line(row, true, false);
|
||||||
cursor_set_column(col);
|
cursor_set_column(col);
|
||||||
|
|
||||||
if (mb->get_shift() && (cursor.column != prev_col || cursor.line != prev_line)) {
|
if (mb->get_shift() && (cursor.column != prev_col || cursor.line != prev_line)) {
|
||||||
|
@ -2026,22 +2113,10 @@ void TextEdit::_gui_input(const Ref<InputEvent> &p_gui_input) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (k->get_scancode() == KEY_DOWN) {
|
|
||||||
|
|
||||||
if (completion_index < completion_options.size() - 1) {
|
|
||||||
completion_index++;
|
|
||||||
completion_current = completion_options[completion_index];
|
|
||||||
update();
|
|
||||||
}
|
|
||||||
accept_event();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (k->get_scancode() == KEY_KP_ENTER || k->get_scancode() == KEY_ENTER || k->get_scancode() == KEY_TAB) {
|
if (k->get_scancode() == KEY_KP_ENTER || k->get_scancode() == KEY_ENTER || k->get_scancode() == KEY_TAB) {
|
||||||
|
|
||||||
_confirm_completion();
|
_confirm_completion();
|
||||||
accept_event();
|
accept_event();
|
||||||
emit_signal("request_completion");
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2191,7 +2266,7 @@ void TextEdit::_gui_input(const Ref<InputEvent> &p_gui_input) {
|
||||||
selection.active = false;
|
selection.active = false;
|
||||||
update();
|
update();
|
||||||
_remove_text(selection.from_line, selection.from_column, selection.to_line, selection.to_column);
|
_remove_text(selection.from_line, selection.from_column, selection.to_line, selection.to_column);
|
||||||
cursor_set_line(selection.from_line);
|
cursor_set_line(selection.from_line, true, false);
|
||||||
cursor_set_column(selection.from_column);
|
cursor_set_column(selection.from_column);
|
||||||
update();
|
update();
|
||||||
}
|
}
|
||||||
|
@ -2241,6 +2316,9 @@ void TextEdit::_gui_input(const Ref<InputEvent> &p_gui_input) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (is_folded(cursor.line))
|
||||||
|
unfold_line(cursor.line);
|
||||||
|
|
||||||
bool brace_indent = false;
|
bool brace_indent = false;
|
||||||
|
|
||||||
// no need to indent if we are going upwards.
|
// no need to indent if we are going upwards.
|
||||||
|
@ -2391,6 +2469,8 @@ void TextEdit::_gui_input(const Ref<InputEvent> &p_gui_input) {
|
||||||
cursor_set_column(column);
|
cursor_set_column(column);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
if (cursor.line > 0 && is_line_hidden(cursor.line - 1))
|
||||||
|
unfold_line(cursor.line - 1);
|
||||||
backspace_at_cursor();
|
backspace_at_cursor();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2449,7 +2529,7 @@ void TextEdit::_gui_input(const Ref<InputEvent> &p_gui_input) {
|
||||||
} else if (cursor.column == 0) {
|
} else if (cursor.column == 0) {
|
||||||
|
|
||||||
if (cursor.line > 0) {
|
if (cursor.line > 0) {
|
||||||
cursor_set_line(cursor.line - 1);
|
cursor_set_line(cursor.line - num_lines_from(CLAMP(cursor.line - 1, 0, text.size() - 1), -1));
|
||||||
cursor_set_column(text[cursor.line].length());
|
cursor_set_column(text[cursor.line].length());
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -2512,7 +2592,7 @@ void TextEdit::_gui_input(const Ref<InputEvent> &p_gui_input) {
|
||||||
} else if (cursor.column == text[cursor.line].length()) {
|
} else if (cursor.column == text[cursor.line].length()) {
|
||||||
|
|
||||||
if (cursor.line < text.size() - 1) {
|
if (cursor.line < text.size() - 1) {
|
||||||
cursor_set_line(cursor.line + 1);
|
cursor_set_line(cursor_get_line() + num_lines_from(CLAMP(cursor.line + 1, 0, text.size() - 1), 1), true, false);
|
||||||
cursor_set_column(0);
|
cursor_set_column(0);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -2553,7 +2633,7 @@ void TextEdit::_gui_input(const Ref<InputEvent> &p_gui_input) {
|
||||||
cursor_set_line(0);
|
cursor_set_line(0);
|
||||||
else
|
else
|
||||||
#endif
|
#endif
|
||||||
cursor_set_line(cursor_get_line() - 1);
|
cursor_set_line(cursor_get_line() - num_lines_from(CLAMP(cursor.line - 1, 0, text.size() - 1), -1));
|
||||||
|
|
||||||
if (k->get_shift())
|
if (k->get_shift())
|
||||||
_post_shift_selection();
|
_post_shift_selection();
|
||||||
|
@ -2587,10 +2667,10 @@ void TextEdit::_gui_input(const Ref<InputEvent> &p_gui_input) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (k->get_command())
|
if (k->get_command())
|
||||||
cursor_set_line(text.size() - 1);
|
cursor_set_line(text.size() - 1, true, false);
|
||||||
else
|
else
|
||||||
#endif
|
#endif
|
||||||
cursor_set_line(cursor_get_line() + 1);
|
cursor_set_line(cursor_get_line() + num_lines_from(CLAMP(cursor.line + 1, 0, text.size() - 1), 1), true, false);
|
||||||
|
|
||||||
if (k->get_shift())
|
if (k->get_shift())
|
||||||
_post_shift_selection();
|
_post_shift_selection();
|
||||||
|
@ -2737,7 +2817,7 @@ void TextEdit::_gui_input(const Ref<InputEvent> &p_gui_input) {
|
||||||
if (k->get_shift())
|
if (k->get_shift())
|
||||||
_pre_shift_selection();
|
_pre_shift_selection();
|
||||||
|
|
||||||
cursor_set_line(text.size() - 1);
|
cursor_set_line(text.size() - 1, true, false);
|
||||||
|
|
||||||
if (k->get_shift())
|
if (k->get_shift())
|
||||||
_post_shift_selection();
|
_post_shift_selection();
|
||||||
|
@ -2752,7 +2832,7 @@ void TextEdit::_gui_input(const Ref<InputEvent> &p_gui_input) {
|
||||||
_pre_shift_selection();
|
_pre_shift_selection();
|
||||||
|
|
||||||
if (k->get_command())
|
if (k->get_command())
|
||||||
cursor_set_line(text.size() - 1);
|
cursor_set_line(text.size() - 1, true, false);
|
||||||
cursor_set_column(text[cursor.line].length());
|
cursor_set_column(text[cursor.line].length());
|
||||||
|
|
||||||
if (k->get_shift())
|
if (k->get_shift())
|
||||||
|
@ -2777,7 +2857,7 @@ void TextEdit::_gui_input(const Ref<InputEvent> &p_gui_input) {
|
||||||
if (k->get_shift())
|
if (k->get_shift())
|
||||||
_pre_shift_selection();
|
_pre_shift_selection();
|
||||||
|
|
||||||
cursor_set_line(cursor_get_line() - get_visible_rows());
|
cursor_set_line(cursor_get_line() - num_lines_from(cursor.line, -get_visible_rows()), true, false);
|
||||||
|
|
||||||
if (k->get_shift())
|
if (k->get_shift())
|
||||||
_post_shift_selection();
|
_post_shift_selection();
|
||||||
|
@ -2798,7 +2878,7 @@ void TextEdit::_gui_input(const Ref<InputEvent> &p_gui_input) {
|
||||||
if (k->get_shift())
|
if (k->get_shift())
|
||||||
_pre_shift_selection();
|
_pre_shift_selection();
|
||||||
|
|
||||||
cursor_set_line(cursor_get_line() + get_visible_rows());
|
cursor_set_line(cursor_get_line() + num_lines_from(cursor.line, get_visible_rows()), true, false);
|
||||||
|
|
||||||
if (k->get_shift())
|
if (k->get_shift())
|
||||||
_post_shift_selection();
|
_post_shift_selection();
|
||||||
|
@ -3016,8 +3096,9 @@ void TextEdit::_scroll_lines_up() {
|
||||||
}
|
}
|
||||||
|
|
||||||
// adjust the cursor
|
// adjust the cursor
|
||||||
if (cursor_get_line() >= (get_visible_rows() + get_v_scroll()) && !selection.active) {
|
int num_lines = num_lines_from(CLAMP(cursor.line_ofs, 0, text.size() - 1), get_visible_rows()) - 1;
|
||||||
cursor_set_line((get_visible_rows() + get_v_scroll()) - 1, false);
|
if (cursor.line >= cursor.line_ofs + num_lines && !selection.active) {
|
||||||
|
cursor_set_line(cursor.line_ofs + num_lines, false, false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3025,9 +3106,10 @@ void TextEdit::_scroll_lines_down() {
|
||||||
scrolling = false;
|
scrolling = false;
|
||||||
|
|
||||||
// calculate the maximum vertical scroll position
|
// calculate the maximum vertical scroll position
|
||||||
int max_v_scroll = get_line_count() - 1;
|
int max_v_scroll = get_total_unhidden_rows();
|
||||||
if (!scroll_past_end_of_file_enabled) {
|
if (!scroll_past_end_of_file_enabled) {
|
||||||
max_v_scroll -= get_visible_rows() - 1;
|
max_v_scroll -= get_visible_rows();
|
||||||
|
max_v_scroll = CLAMP(max_v_scroll, 0, get_total_unhidden_rows());
|
||||||
}
|
}
|
||||||
|
|
||||||
// adjust the vertical scroll
|
// adjust the vertical scroll
|
||||||
|
@ -3036,8 +3118,8 @@ void TextEdit::_scroll_lines_down() {
|
||||||
}
|
}
|
||||||
|
|
||||||
// adjust the cursor
|
// adjust the cursor
|
||||||
if ((cursor_get_line()) <= get_v_scroll() - 1 && !selection.active) {
|
if (cursor.line <= cursor.line_ofs - 1 && !selection.active) {
|
||||||
cursor_set_line(get_v_scroll(), false);
|
cursor_set_line(cursor.line_ofs, false, false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3082,6 +3164,15 @@ void TextEdit::_base_insert_text(int p_line, int p_char, const String &p_text, i
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// if we are just making a new empty line, reset breakpoints and hidden status
|
||||||
|
if (p_char == 0 && p_text.replace("\r", "") == "\n") {
|
||||||
|
|
||||||
|
text.set_breakpoint(p_line + 1, text.is_breakpoint(p_line));
|
||||||
|
text.set_hidden(p_line + 1, text.is_hidden(p_line));
|
||||||
|
text.set_breakpoint(p_line, false);
|
||||||
|
text.set_hidden(p_line, false);
|
||||||
|
}
|
||||||
|
|
||||||
r_end_line = p_line + substrings.size() - 1;
|
r_end_line = p_line + substrings.size() - 1;
|
||||||
r_end_column = text[r_end_line].length() - postinsert_text.length();
|
r_end_column = text[r_end_line].length() - postinsert_text.length();
|
||||||
|
|
||||||
|
@ -3280,6 +3371,7 @@ Size2 TextEdit::get_minimum_size() const {
|
||||||
|
|
||||||
return cache.style_normal->get_minimum_size();
|
return cache.style_normal->get_minimum_size();
|
||||||
}
|
}
|
||||||
|
|
||||||
int TextEdit::get_visible_rows() const {
|
int TextEdit::get_visible_rows() const {
|
||||||
|
|
||||||
int total = cache.size.height;
|
int total = cache.size.height;
|
||||||
|
@ -3287,31 +3379,81 @@ int TextEdit::get_visible_rows() const {
|
||||||
total /= get_row_height();
|
total /= get_row_height();
|
||||||
return total;
|
return total;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int TextEdit::get_total_unhidden_rows() const {
|
||||||
|
if (!is_hiding_enabled())
|
||||||
|
return text.size();
|
||||||
|
|
||||||
|
int total_unhidden = 0;
|
||||||
|
for (int i = 0; i < text.size(); i++) {
|
||||||
|
if (!text.is_hidden(i))
|
||||||
|
total_unhidden++;
|
||||||
|
}
|
||||||
|
return total_unhidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
double TextEdit::get_line_scroll_pos(bool p_recalculate) const {
|
||||||
|
|
||||||
|
if (!is_hiding_enabled())
|
||||||
|
return cursor.line_ofs;
|
||||||
|
if (!p_recalculate)
|
||||||
|
return line_scroll_pos;
|
||||||
|
|
||||||
|
// count num unhidden lines to the cursor line ofs
|
||||||
|
double new_line_scroll_pos = 0;
|
||||||
|
int to = CLAMP(cursor.line_ofs, 0, text.size() - 1);
|
||||||
|
for (int i = 0; i < to; i++) {
|
||||||
|
if (!text.is_hidden(i))
|
||||||
|
new_line_scroll_pos++;
|
||||||
|
}
|
||||||
|
return new_line_scroll_pos;
|
||||||
|
}
|
||||||
|
|
||||||
|
void TextEdit::update_line_scroll_pos() {
|
||||||
|
|
||||||
|
if (!is_hiding_enabled()) {
|
||||||
|
line_scroll_pos = cursor.line_ofs;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// count num unhidden lines to the cursor line ofs
|
||||||
|
double new_line_scroll_pos = 0;
|
||||||
|
int to = CLAMP(cursor.line_ofs, 0, text.size() - 1);
|
||||||
|
for (int i = 0; i < to; i++) {
|
||||||
|
if (!text.is_hidden(i))
|
||||||
|
new_line_scroll_pos++;
|
||||||
|
}
|
||||||
|
line_scroll_pos = new_line_scroll_pos;
|
||||||
|
}
|
||||||
|
|
||||||
void TextEdit::adjust_viewport_to_cursor() {
|
void TextEdit::adjust_viewport_to_cursor() {
|
||||||
scrolling = false;
|
scrolling = false;
|
||||||
|
|
||||||
if (cursor.line_ofs > cursor.line)
|
if (cursor.line_ofs > cursor.line) {
|
||||||
cursor.line_ofs = cursor.line;
|
cursor.line_ofs = cursor.line;
|
||||||
|
}
|
||||||
|
|
||||||
int visible_width = cache.size.width - cache.style_normal->get_minimum_size().width - cache.line_number_w - cache.breakpoint_gutter_width;
|
int visible_width = cache.size.width - cache.style_normal->get_minimum_size().width - cache.line_number_w - cache.breakpoint_gutter_width - cache.fold_gutter_width;
|
||||||
if (v_scroll->is_visible_in_tree())
|
if (v_scroll->is_visible_in_tree())
|
||||||
visible_width -= v_scroll->get_combined_minimum_size().width;
|
visible_width -= v_scroll->get_combined_minimum_size().width;
|
||||||
visible_width -= 20; // give it a little more space
|
visible_width -= 20; // give it a little more space
|
||||||
|
|
||||||
//printf("rowofs %i, visrows %i, cursor.line %i\n",cursor.line_ofs,get_visible_rows(),cursor.line);
|
|
||||||
|
|
||||||
int visible_rows = get_visible_rows();
|
int visible_rows = get_visible_rows();
|
||||||
if (h_scroll->is_visible_in_tree())
|
if (h_scroll->is_visible_in_tree())
|
||||||
visible_rows -= ((h_scroll->get_combined_minimum_size().height - 1) / get_row_height());
|
visible_rows -= ((h_scroll->get_combined_minimum_size().height - 1) / get_row_height());
|
||||||
|
int num_rows = num_lines_from(CLAMP(cursor.line_ofs, 0, text.size() - 1), MIN(visible_rows, text.size() - 1 - cursor.line_ofs));
|
||||||
|
|
||||||
if (cursor.line >= (cursor.line_ofs + visible_rows))
|
// if the cursor is off the screen
|
||||||
cursor.line_ofs = cursor.line - visible_rows;
|
if (cursor.line >= (cursor.line_ofs + MAX(num_rows, visible_rows))) {
|
||||||
if (cursor.line < cursor.line_ofs)
|
cursor.line_ofs = cursor.line - (num_lines_from(CLAMP(cursor.line, 0, text.size() - 1), -visible_rows) - 1);
|
||||||
|
}
|
||||||
|
if (cursor.line < cursor.line_ofs) {
|
||||||
cursor.line_ofs = cursor.line;
|
cursor.line_ofs = cursor.line;
|
||||||
|
}
|
||||||
|
|
||||||
if (cursor.line_ofs + visible_rows > text.size() && !scroll_past_end_of_file_enabled) {
|
// fixes deleting lines from moving the line ofs in a bad way
|
||||||
cursor.line_ofs = text.size() - visible_rows;
|
if (!scroll_past_end_of_file_enabled && get_total_unhidden_rows() > visible_rows && num_rows < visible_rows) {
|
||||||
v_scroll->set_value(text.size() - visible_rows);
|
cursor.line_ofs = text.size() - 1 - (num_lines_from(text.size() - 1, -visible_rows) - 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
int cursor_x = get_column_x_offset(cursor.column, text[cursor.line]);
|
int cursor_x = get_column_x_offset(cursor.column, text[cursor.line]);
|
||||||
|
@ -3322,6 +3464,8 @@ void TextEdit::adjust_viewport_to_cursor() {
|
||||||
if (cursor_x < cursor.x_ofs)
|
if (cursor_x < cursor.x_ofs)
|
||||||
cursor.x_ofs = cursor_x;
|
cursor.x_ofs = cursor_x;
|
||||||
|
|
||||||
|
update_line_scroll_pos();
|
||||||
|
v_scroll->set_value(get_line_scroll_pos() + 1);
|
||||||
update();
|
update();
|
||||||
/*
|
/*
|
||||||
get_range()->set_max(text.size());
|
get_range()->set_max(text.size());
|
||||||
|
@ -3338,7 +3482,10 @@ void TextEdit::center_viewport_to_cursor() {
|
||||||
if (cursor.line_ofs > cursor.line)
|
if (cursor.line_ofs > cursor.line)
|
||||||
cursor.line_ofs = cursor.line;
|
cursor.line_ofs = cursor.line;
|
||||||
|
|
||||||
int visible_width = cache.size.width - cache.style_normal->get_minimum_size().width - cache.line_number_w - cache.breakpoint_gutter_width;
|
if (is_line_hidden(cursor.line))
|
||||||
|
unfold_line(cursor.line);
|
||||||
|
|
||||||
|
int visible_width = cache.size.width - cache.style_normal->get_minimum_size().width - cache.line_number_w - cache.breakpoint_gutter_width - cache.fold_gutter_width;
|
||||||
if (v_scroll->is_visible_in_tree())
|
if (v_scroll->is_visible_in_tree())
|
||||||
visible_width -= v_scroll->get_combined_minimum_size().width;
|
visible_width -= v_scroll->get_combined_minimum_size().width;
|
||||||
visible_width -= 20; // give it a little more space
|
visible_width -= 20; // give it a little more space
|
||||||
|
@ -3347,9 +3494,8 @@ void TextEdit::center_viewport_to_cursor() {
|
||||||
if (h_scroll->is_visible_in_tree())
|
if (h_scroll->is_visible_in_tree())
|
||||||
visible_rows -= ((h_scroll->get_combined_minimum_size().height - 1) / get_row_height());
|
visible_rows -= ((h_scroll->get_combined_minimum_size().height - 1) / get_row_height());
|
||||||
|
|
||||||
int max_ofs = text.size() - (scroll_past_end_of_file_enabled ? 1 : visible_rows);
|
int max_ofs = text.size() - (scroll_past_end_of_file_enabled ? 1 : num_lines_from(text.size() - 1, -visible_rows));
|
||||||
cursor.line_ofs = CLAMP(cursor.line - (visible_rows / 2), 0, max_ofs);
|
cursor.line_ofs = CLAMP(cursor.line - num_lines_from(cursor.line - visible_rows / 2, -visible_rows / 2), 0, max_ofs);
|
||||||
|
|
||||||
int cursor_x = get_column_x_offset(cursor.column, text[cursor.line]);
|
int cursor_x = get_column_x_offset(cursor.column, text[cursor.line]);
|
||||||
|
|
||||||
if (cursor_x > (cursor.x_ofs + visible_width))
|
if (cursor_x > (cursor.x_ofs + visible_width))
|
||||||
|
@ -3358,6 +3504,9 @@ void TextEdit::center_viewport_to_cursor() {
|
||||||
if (cursor_x < cursor.x_ofs)
|
if (cursor_x < cursor.x_ofs)
|
||||||
cursor.x_ofs = cursor_x;
|
cursor.x_ofs = cursor_x;
|
||||||
|
|
||||||
|
update_line_scroll_pos();
|
||||||
|
v_scroll->set_value(get_line_scroll_pos());
|
||||||
|
|
||||||
update();
|
update();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3382,7 +3531,7 @@ void TextEdit::cursor_set_column(int p_col, bool p_adjust_viewport) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void TextEdit::cursor_set_line(int p_row, bool p_adjust_viewport) {
|
void TextEdit::cursor_set_line(int p_row, bool p_adjust_viewport, bool p_can_be_hidden) {
|
||||||
|
|
||||||
if (setting_row)
|
if (setting_row)
|
||||||
return;
|
return;
|
||||||
|
@ -3394,6 +3543,21 @@ void TextEdit::cursor_set_line(int p_row, bool p_adjust_viewport) {
|
||||||
if (p_row >= (int)text.size())
|
if (p_row >= (int)text.size())
|
||||||
p_row = (int)text.size() - 1;
|
p_row = (int)text.size() - 1;
|
||||||
|
|
||||||
|
if (!p_can_be_hidden) {
|
||||||
|
if (is_line_hidden(CLAMP(p_row, 0, text.size() - 1))) {
|
||||||
|
int move_down = num_lines_from(p_row, 1) - 1;
|
||||||
|
if (p_row + move_down <= text.size() - 1 && !is_line_hidden(p_row + move_down)) {
|
||||||
|
p_row += move_down;
|
||||||
|
} else {
|
||||||
|
int move_up = num_lines_from(p_row, -1) - 1;
|
||||||
|
if (p_row - move_up > 0 && !is_line_hidden(p_row - move_up)) {
|
||||||
|
p_row -= move_up;
|
||||||
|
} else {
|
||||||
|
WARN_PRINTS(("Cursor set to hidden line " + itos(p_row) + " and there are no nonhidden lines."));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
cursor.line = p_row;
|
cursor.line = p_row;
|
||||||
cursor.column = get_char_pos_for(cursor.last_fit_x, get_line(cursor.line));
|
cursor.column = get_char_pos_for(cursor.last_fit_x, get_line(cursor.line));
|
||||||
|
|
||||||
|
@ -3463,8 +3627,11 @@ void TextEdit::_scroll_moved(double p_to_val) {
|
||||||
|
|
||||||
if (h_scroll->is_visible_in_tree())
|
if (h_scroll->is_visible_in_tree())
|
||||||
cursor.x_ofs = h_scroll->get_value();
|
cursor.x_ofs = h_scroll->get_value();
|
||||||
if (v_scroll->is_visible_in_tree())
|
if (v_scroll->is_visible_in_tree()) {
|
||||||
cursor.line_ofs = v_scroll->get_value();
|
double val = v_scroll->get_value();
|
||||||
|
cursor.line_ofs = num_lines_from(0, (int)floor(val)) - 1;
|
||||||
|
line_scroll_pos = (int)floor(val);
|
||||||
|
}
|
||||||
update();
|
update();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3553,10 +3720,43 @@ Control::CursorShape TextEdit::get_cursor_shape(const Point2 &p_pos) const {
|
||||||
if (highlighted_word != String())
|
if (highlighted_word != String())
|
||||||
return CURSOR_POINTING_HAND;
|
return CURSOR_POINTING_HAND;
|
||||||
|
|
||||||
int gutter = cache.style_normal->get_margin(MARGIN_LEFT) + cache.line_number_w + cache.breakpoint_gutter_width;
|
int gutter = cache.style_normal->get_margin(MARGIN_LEFT) + cache.line_number_w + cache.breakpoint_gutter_width + cache.fold_gutter_width;
|
||||||
if ((completion_active && completion_rect.has_point(p_pos)) || p_pos.x < gutter) {
|
if ((completion_active && completion_rect.has_point(p_pos))) {
|
||||||
return CURSOR_ARROW;
|
return CURSOR_ARROW;
|
||||||
}
|
}
|
||||||
|
if (p_pos.x < gutter) {
|
||||||
|
|
||||||
|
int row, col;
|
||||||
|
_get_mouse_pos(p_pos, row, col);
|
||||||
|
int left_margin = cache.style_normal->get_margin(MARGIN_LEFT);
|
||||||
|
|
||||||
|
// breakpoint icon
|
||||||
|
if (draw_breakpoint_gutter && p_pos.x > left_margin && p_pos.x <= left_margin + cache.breakpoint_gutter_width + 3) {
|
||||||
|
return CURSOR_POINTING_HAND;
|
||||||
|
}
|
||||||
|
|
||||||
|
// fold icon
|
||||||
|
int gutter_left = left_margin + cache.breakpoint_gutter_width + cache.line_number_w;
|
||||||
|
if (draw_fold_gutter && p_pos.x > gutter_left - 6 && p_pos.x <= gutter_left + cache.fold_gutter_width - 3) {
|
||||||
|
if (is_folded(row) || can_fold(row))
|
||||||
|
return CURSOR_POINTING_HAND;
|
||||||
|
else
|
||||||
|
return CURSOR_ARROW;
|
||||||
|
}
|
||||||
|
return CURSOR_ARROW;
|
||||||
|
} else {
|
||||||
|
int row, col;
|
||||||
|
_get_mouse_pos(p_pos, row, col);
|
||||||
|
// eol fold icon
|
||||||
|
if (is_folded(row)) {
|
||||||
|
int line_width = text.get_line_width(row);
|
||||||
|
line_width += cache.style_normal->get_margin(MARGIN_LEFT) + cache.line_number_w + cache.breakpoint_gutter_width + cache.fold_gutter_width - cursor.x_ofs;
|
||||||
|
if (p_pos.x > line_width - 3 && p_pos.x <= line_width + cache.folded_eol_icon->get_width() + 3) {
|
||||||
|
return CURSOR_POINTING_HAND;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return CURSOR_IBEAM;
|
return CURSOR_IBEAM;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3570,6 +3770,7 @@ void TextEdit::set_text(String p_text) {
|
||||||
cursor.line = 0;
|
cursor.line = 0;
|
||||||
cursor.x_ofs = 0;
|
cursor.x_ofs = 0;
|
||||||
cursor.line_ofs = 0;
|
cursor.line_ofs = 0;
|
||||||
|
line_scroll_pos = 0;
|
||||||
cursor.last_fit_x = 0;
|
cursor.last_fit_x = 0;
|
||||||
cursor_set_line(0);
|
cursor_set_line(0);
|
||||||
cursor_set_column(0);
|
cursor_set_column(0);
|
||||||
|
@ -3655,6 +3856,7 @@ void TextEdit::_clear() {
|
||||||
cursor.line = 0;
|
cursor.line = 0;
|
||||||
cursor.x_ofs = 0;
|
cursor.x_ofs = 0;
|
||||||
cursor.line_ofs = 0;
|
cursor.line_ofs = 0;
|
||||||
|
line_scroll_pos = 0;
|
||||||
cursor.last_fit_x = 0;
|
cursor.last_fit_x = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3733,6 +3935,9 @@ void TextEdit::_update_caches() {
|
||||||
cache.line_spacing = get_constant("line_spacing");
|
cache.line_spacing = get_constant("line_spacing");
|
||||||
cache.row_height = cache.font->get_height() + cache.line_spacing;
|
cache.row_height = cache.font->get_height() + cache.line_spacing;
|
||||||
cache.tab_icon = get_icon("tab");
|
cache.tab_icon = get_icon("tab");
|
||||||
|
cache.folded_icon = get_icon("GuiTreeArrowRight", "EditorIcons");
|
||||||
|
cache.can_fold_icon = get_icon("GuiTreeArrowDown", "EditorIcons");
|
||||||
|
cache.folded_eol_icon = get_icon("GuiTabMenu", "EditorIcons");
|
||||||
text.set_font(cache.font);
|
text.set_font(cache.font);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4179,6 +4384,198 @@ void TextEdit::get_breakpoints(List<int> *p_breakpoints) const {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void TextEdit::set_line_as_hidden(int p_line, bool p_hidden) {
|
||||||
|
|
||||||
|
ERR_FAIL_INDEX(p_line, text.size());
|
||||||
|
if (is_hiding_enabled() || !p_hidden)
|
||||||
|
text.set_hidden(p_line, p_hidden);
|
||||||
|
update();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool TextEdit::is_line_hidden(int p_line) const {
|
||||||
|
|
||||||
|
ERR_FAIL_INDEX_V(p_line, text.size(), false);
|
||||||
|
return text.is_hidden(p_line);
|
||||||
|
}
|
||||||
|
|
||||||
|
void TextEdit::fold_all_lines() {
|
||||||
|
|
||||||
|
for (int i = 0; i < text.size(); i++) {
|
||||||
|
fold_line(i);
|
||||||
|
}
|
||||||
|
_update_scrollbars();
|
||||||
|
update();
|
||||||
|
}
|
||||||
|
|
||||||
|
void TextEdit::unhide_all_lines() {
|
||||||
|
|
||||||
|
for (int i = 0; i < text.size(); i++) {
|
||||||
|
text.set_hidden(i, false);
|
||||||
|
}
|
||||||
|
_update_scrollbars();
|
||||||
|
update();
|
||||||
|
}
|
||||||
|
|
||||||
|
int TextEdit::num_lines_from(int p_line_from, int unhidden_amount) const {
|
||||||
|
|
||||||
|
// returns the number of hidden and unhidden lines from p_line_from to p_line_from + amount of visible lines
|
||||||
|
ERR_FAIL_INDEX_V(p_line_from, text.size(), ABS(unhidden_amount));
|
||||||
|
|
||||||
|
if (!is_hiding_enabled())
|
||||||
|
return unhidden_amount;
|
||||||
|
int num_visible = 0;
|
||||||
|
int num_total = 0;
|
||||||
|
if (unhidden_amount >= 0) {
|
||||||
|
for (int i = p_line_from; i < text.size(); i++) {
|
||||||
|
num_total++;
|
||||||
|
if (!is_line_hidden(i))
|
||||||
|
num_visible++;
|
||||||
|
if (num_visible >= unhidden_amount)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
unhidden_amount = ABS(unhidden_amount);
|
||||||
|
for (int i = p_line_from; i >= 0; i--) {
|
||||||
|
num_total++;
|
||||||
|
if (!is_line_hidden(i))
|
||||||
|
num_visible++;
|
||||||
|
if (num_visible >= unhidden_amount)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return num_total;
|
||||||
|
}
|
||||||
|
|
||||||
|
int TextEdit::get_whitespace_level(int p_line) const {
|
||||||
|
|
||||||
|
ERR_FAIL_INDEX_V(p_line, text.size(), 0);
|
||||||
|
|
||||||
|
// counts number of tabs and spaces before line starts
|
||||||
|
int whitespace_count = 0;
|
||||||
|
int line_length = text[p_line].size();
|
||||||
|
for (int i = 0; i < line_length - 1; i++) {
|
||||||
|
if (text[p_line][i] == '\t') {
|
||||||
|
whitespace_count++;
|
||||||
|
} else if (text[p_line][i] == ' ') {
|
||||||
|
whitespace_count++;
|
||||||
|
} else if (text[p_line][i] == '#') {
|
||||||
|
break;
|
||||||
|
} else {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return whitespace_count;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool TextEdit::can_fold(int p_line) const {
|
||||||
|
|
||||||
|
ERR_FAIL_INDEX_V(p_line, text.size(), false);
|
||||||
|
if (!is_hiding_enabled())
|
||||||
|
return false;
|
||||||
|
if (p_line + 1 >= text.size())
|
||||||
|
return false;
|
||||||
|
if (text[p_line].size() == 0)
|
||||||
|
return false;
|
||||||
|
if (is_folded(p_line))
|
||||||
|
return false;
|
||||||
|
if (is_line_hidden(p_line))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
int start_indent = get_whitespace_level(p_line);
|
||||||
|
|
||||||
|
for (int i = p_line + 1; i < text.size(); i++) {
|
||||||
|
if (text[i].size() == 0)
|
||||||
|
continue;
|
||||||
|
int next_indent = get_whitespace_level(i);
|
||||||
|
if (next_indent > start_indent)
|
||||||
|
return true;
|
||||||
|
else
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool TextEdit::is_folded(int p_line) const {
|
||||||
|
|
||||||
|
ERR_FAIL_INDEX_V(p_line, text.size(), false);
|
||||||
|
if (p_line + 1 >= text.size() - 1)
|
||||||
|
return false;
|
||||||
|
if (!is_line_hidden(p_line) && is_line_hidden(p_line + 1))
|
||||||
|
return true;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void TextEdit::fold_line(int p_line) {
|
||||||
|
|
||||||
|
ERR_FAIL_INDEX(p_line, text.size());
|
||||||
|
if (!is_hiding_enabled())
|
||||||
|
return;
|
||||||
|
if (!can_fold(p_line))
|
||||||
|
return;
|
||||||
|
|
||||||
|
// hide lines below this one
|
||||||
|
int start_indent = get_whitespace_level(p_line);
|
||||||
|
for (int i = p_line + 1; i < text.size(); i++) {
|
||||||
|
int cur_indent = get_whitespace_level(i);
|
||||||
|
if (text[i].size() == 0 || cur_indent > start_indent) {
|
||||||
|
set_line_as_hidden(i, true);
|
||||||
|
} else {
|
||||||
|
// exclude trailing empty lines
|
||||||
|
for (int trail_i = i - 1; trail_i > p_line; trail_i--) {
|
||||||
|
if (text[trail_i].size() == 0)
|
||||||
|
set_line_as_hidden(trail_i, false);
|
||||||
|
else
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// fix selection
|
||||||
|
if (is_selection_active()) {
|
||||||
|
if (is_line_hidden(selection.from_line) && is_line_hidden(selection.to_line)) {
|
||||||
|
deselect();
|
||||||
|
} else if (is_line_hidden(selection.from_line)) {
|
||||||
|
select(p_line, 9999, selection.to_line, selection.to_column);
|
||||||
|
} else if (is_line_hidden(selection.to_line)) {
|
||||||
|
select(selection.from_line, selection.from_column, p_line, 9999);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// reset cursor
|
||||||
|
if (is_line_hidden(cursor.line)) {
|
||||||
|
cursor_set_line(p_line, false, false);
|
||||||
|
cursor_set_column(get_line(p_line).length(), false);
|
||||||
|
}
|
||||||
|
_update_scrollbars();
|
||||||
|
update();
|
||||||
|
}
|
||||||
|
|
||||||
|
void TextEdit::unfold_line(int p_line) {
|
||||||
|
|
||||||
|
ERR_FAIL_INDEX(p_line, text.size());
|
||||||
|
|
||||||
|
if (!is_folded(p_line) && !is_line_hidden(p_line))
|
||||||
|
return;
|
||||||
|
int fold_start = p_line;
|
||||||
|
for (fold_start = p_line; fold_start > 0; fold_start--) {
|
||||||
|
if (is_folded(fold_start))
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
fold_start = is_folded(fold_start) ? fold_start : p_line;
|
||||||
|
|
||||||
|
for (int i = fold_start + 1; i < text.size(); i++) {
|
||||||
|
if (is_line_hidden(i)) {
|
||||||
|
set_line_as_hidden(i, false);
|
||||||
|
} else {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_update_scrollbars();
|
||||||
|
update();
|
||||||
|
}
|
||||||
|
|
||||||
int TextEdit::get_line_count() const {
|
int TextEdit::get_line_count() const {
|
||||||
|
|
||||||
return text.size();
|
return text.size();
|
||||||
|
@ -4405,12 +4802,14 @@ void TextEdit::set_v_scroll(int p_scroll) {
|
||||||
p_scroll = 0;
|
p_scroll = 0;
|
||||||
}
|
}
|
||||||
if (!scroll_past_end_of_file_enabled) {
|
if (!scroll_past_end_of_file_enabled) {
|
||||||
if (p_scroll + get_visible_rows() > get_line_count()) {
|
if (p_scroll + get_visible_rows() > get_total_unhidden_rows()) {
|
||||||
p_scroll = get_line_count() - get_visible_rows();
|
int num_rows = num_lines_from(CLAMP(p_scroll, 0, text.size() - 1), MIN(get_visible_rows(), text.size() - 1 - p_scroll));
|
||||||
|
p_scroll = text.size() - num_rows;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
v_scroll->set_value(p_scroll);
|
v_scroll->set_value(p_scroll);
|
||||||
cursor.line_ofs = p_scroll;
|
cursor.line_ofs = num_lines_from(0, p_scroll);
|
||||||
|
line_scroll_pos = p_scroll;
|
||||||
}
|
}
|
||||||
|
|
||||||
int TextEdit::get_h_scroll() const {
|
int TextEdit::get_h_scroll() const {
|
||||||
|
@ -4772,7 +5171,7 @@ void TextEdit::set_line(int line, String new_text) {
|
||||||
|
|
||||||
void TextEdit::insert_at(const String &p_text, int at) {
|
void TextEdit::insert_at(const String &p_text, int at) {
|
||||||
cursor_set_column(0);
|
cursor_set_column(0);
|
||||||
cursor_set_line(at);
|
cursor_set_line(at, false, true);
|
||||||
_insert_text(at, 0, p_text + "\n");
|
_insert_text(at, 0, p_text + "\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4820,6 +5219,35 @@ int TextEdit::get_breakpoint_gutter_width() const {
|
||||||
return cache.breakpoint_gutter_width;
|
return cache.breakpoint_gutter_width;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void TextEdit::set_draw_fold_gutter(bool p_draw) {
|
||||||
|
draw_fold_gutter = p_draw;
|
||||||
|
update();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool TextEdit::is_drawing_fold_gutter() const {
|
||||||
|
return draw_fold_gutter;
|
||||||
|
}
|
||||||
|
|
||||||
|
void TextEdit::set_fold_gutter_width(int p_gutter_width) {
|
||||||
|
fold_gutter_width = p_gutter_width;
|
||||||
|
update();
|
||||||
|
}
|
||||||
|
|
||||||
|
int TextEdit::get_fold_gutter_width() const {
|
||||||
|
return cache.fold_gutter_width;
|
||||||
|
}
|
||||||
|
|
||||||
|
void TextEdit::set_hiding_enabled(int p_enabled) {
|
||||||
|
if (!p_enabled)
|
||||||
|
unhide_all_lines();
|
||||||
|
hiding_enabled = p_enabled;
|
||||||
|
update();
|
||||||
|
}
|
||||||
|
|
||||||
|
int TextEdit::is_hiding_enabled() const {
|
||||||
|
return hiding_enabled;
|
||||||
|
}
|
||||||
|
|
||||||
void TextEdit::set_highlight_current_line(bool p_enabled) {
|
void TextEdit::set_highlight_current_line(bool p_enabled) {
|
||||||
highlight_current_line = p_enabled;
|
highlight_current_line = p_enabled;
|
||||||
update();
|
update();
|
||||||
|
@ -4914,7 +5342,7 @@ void TextEdit::_bind_methods() {
|
||||||
ClassDB::bind_method(D_METHOD("get_line", "line"), &TextEdit::get_line);
|
ClassDB::bind_method(D_METHOD("get_line", "line"), &TextEdit::get_line);
|
||||||
|
|
||||||
ClassDB::bind_method(D_METHOD("cursor_set_column", "column", "adjust_viewport"), &TextEdit::cursor_set_column, DEFVAL(true));
|
ClassDB::bind_method(D_METHOD("cursor_set_column", "column", "adjust_viewport"), &TextEdit::cursor_set_column, DEFVAL(true));
|
||||||
ClassDB::bind_method(D_METHOD("cursor_set_line", "line", "adjust_viewport"), &TextEdit::cursor_set_line, DEFVAL(true));
|
ClassDB::bind_method(D_METHOD("cursor_set_line", "line", "adjust_viewport, can_be_hidden"), &TextEdit::cursor_set_line, DEFVAL(true), DEFVAL(true));
|
||||||
|
|
||||||
ClassDB::bind_method(D_METHOD("cursor_get_column"), &TextEdit::cursor_get_column);
|
ClassDB::bind_method(D_METHOD("cursor_get_column"), &TextEdit::cursor_get_column);
|
||||||
ClassDB::bind_method(D_METHOD("cursor_get_line"), &TextEdit::cursor_get_line);
|
ClassDB::bind_method(D_METHOD("cursor_get_line"), &TextEdit::cursor_get_line);
|
||||||
|
@ -4955,6 +5383,17 @@ void TextEdit::_bind_methods() {
|
||||||
ClassDB::bind_method(D_METHOD("set_show_line_numbers", "enable"), &TextEdit::set_show_line_numbers);
|
ClassDB::bind_method(D_METHOD("set_show_line_numbers", "enable"), &TextEdit::set_show_line_numbers);
|
||||||
ClassDB::bind_method(D_METHOD("is_show_line_numbers_enabled"), &TextEdit::is_show_line_numbers_enabled);
|
ClassDB::bind_method(D_METHOD("is_show_line_numbers_enabled"), &TextEdit::is_show_line_numbers_enabled);
|
||||||
|
|
||||||
|
ClassDB::bind_method(D_METHOD("set_hiding_enabled", "enable"), &TextEdit::set_hiding_enabled);
|
||||||
|
ClassDB::bind_method(D_METHOD("is_hiding_enabled"), &TextEdit::is_hiding_enabled);
|
||||||
|
ClassDB::bind_method(D_METHOD("set_line_as_hidden", "line", "enable"), &TextEdit::set_line_as_hidden);
|
||||||
|
ClassDB::bind_method(D_METHOD("is_line_hidden"), &TextEdit::is_line_hidden);
|
||||||
|
ClassDB::bind_method(D_METHOD("fold_all_lines"), &TextEdit::fold_all_lines);
|
||||||
|
ClassDB::bind_method(D_METHOD("unhide_all_lines"), &TextEdit::unhide_all_lines);
|
||||||
|
ClassDB::bind_method(D_METHOD("fold_line", "line"), &TextEdit::fold_line);
|
||||||
|
ClassDB::bind_method(D_METHOD("unfold_line", "line"), &TextEdit::unfold_line);
|
||||||
|
ClassDB::bind_method(D_METHOD("can_fold", "line"), &TextEdit::can_fold);
|
||||||
|
ClassDB::bind_method(D_METHOD("is_folded", "line"), &TextEdit::is_folded);
|
||||||
|
|
||||||
ClassDB::bind_method(D_METHOD("set_highlight_all_occurrences", "enable"), &TextEdit::set_highlight_all_occurrences);
|
ClassDB::bind_method(D_METHOD("set_highlight_all_occurrences", "enable"), &TextEdit::set_highlight_all_occurrences);
|
||||||
ClassDB::bind_method(D_METHOD("is_highlight_all_occurrences_enabled"), &TextEdit::is_highlight_all_occurrences_enabled);
|
ClassDB::bind_method(D_METHOD("is_highlight_all_occurrences_enabled"), &TextEdit::is_highlight_all_occurrences_enabled);
|
||||||
|
|
||||||
|
@ -4988,6 +5427,7 @@ void TextEdit::_bind_methods() {
|
||||||
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "context_menu_enabled"), "set_context_menu_enabled", "is_context_menu_enabled");
|
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "context_menu_enabled"), "set_context_menu_enabled", "is_context_menu_enabled");
|
||||||
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "smooth_scrolling"), "set_smooth_scroll_enable", "is_smooth_scroll_enabled");
|
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "smooth_scrolling"), "set_smooth_scroll_enable", "is_smooth_scroll_enabled");
|
||||||
ADD_PROPERTY(PropertyInfo(Variant::REAL, "v_scroll_speed"), "set_v_scroll_speed", "get_v_scroll_speed");
|
ADD_PROPERTY(PropertyInfo(Variant::REAL, "v_scroll_speed"), "set_v_scroll_speed", "get_v_scroll_speed");
|
||||||
|
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "hiding_enabled"), "set_hiding_enabled", "is_hiding_enabled");
|
||||||
|
|
||||||
ADD_GROUP("Caret", "caret_");
|
ADD_GROUP("Caret", "caret_");
|
||||||
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "caret_block_mode"), "cursor_set_block_mode", "cursor_is_block_mode");
|
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "caret_block_mode"), "cursor_set_block_mode", "cursor_is_block_mode");
|
||||||
|
@ -5029,6 +5469,8 @@ TextEdit::TextEdit() {
|
||||||
cache.line_number_w = 1;
|
cache.line_number_w = 1;
|
||||||
cache.breakpoint_gutter_width = 0;
|
cache.breakpoint_gutter_width = 0;
|
||||||
breakpoint_gutter_width = 0;
|
breakpoint_gutter_width = 0;
|
||||||
|
cache.fold_gutter_width = 0;
|
||||||
|
fold_gutter_width = 0;
|
||||||
|
|
||||||
indent_size = 4;
|
indent_size = 4;
|
||||||
text.set_indent_size(indent_size);
|
text.set_indent_size(indent_size);
|
||||||
|
@ -5098,6 +5540,8 @@ TextEdit::TextEdit() {
|
||||||
line_length_guideline = false;
|
line_length_guideline = false;
|
||||||
line_length_guideline_col = 80;
|
line_length_guideline_col = 80;
|
||||||
draw_breakpoint_gutter = false;
|
draw_breakpoint_gutter = false;
|
||||||
|
draw_fold_gutter = false;
|
||||||
|
hiding_enabled = false;
|
||||||
next_operation_is_complex = false;
|
next_operation_is_complex = false;
|
||||||
scroll_past_end_of_file_enabled = false;
|
scroll_past_end_of_file_enabled = false;
|
||||||
auto_brace_completion_enabled = false;
|
auto_brace_completion_enabled = false;
|
||||||
|
|
|
@ -73,6 +73,9 @@ class TextEdit : public Control {
|
||||||
struct Cache {
|
struct Cache {
|
||||||
|
|
||||||
Ref<Texture> tab_icon;
|
Ref<Texture> tab_icon;
|
||||||
|
Ref<Texture> can_fold_icon;
|
||||||
|
Ref<Texture> folded_icon;
|
||||||
|
Ref<Texture> folded_eol_icon;
|
||||||
Ref<StyleBox> style_normal;
|
Ref<StyleBox> style_normal;
|
||||||
Ref<StyleBox> style_focus;
|
Ref<StyleBox> style_focus;
|
||||||
Ref<Font> font;
|
Ref<Font> font;
|
||||||
|
@ -105,6 +108,7 @@ class TextEdit : public Control {
|
||||||
int line_spacing;
|
int line_spacing;
|
||||||
int line_number_w;
|
int line_number_w;
|
||||||
int breakpoint_gutter_width;
|
int breakpoint_gutter_width;
|
||||||
|
int fold_gutter_width;
|
||||||
Size2 size;
|
Size2 size;
|
||||||
} cache;
|
} cache;
|
||||||
|
|
||||||
|
@ -136,6 +140,7 @@ class TextEdit : public Control {
|
||||||
int width_cache : 24;
|
int width_cache : 24;
|
||||||
bool marked : 1;
|
bool marked : 1;
|
||||||
bool breakpoint : 1;
|
bool breakpoint : 1;
|
||||||
|
bool hidden : 1;
|
||||||
Map<int, ColorRegionInfo> region_info;
|
Map<int, ColorRegionInfo> region_info;
|
||||||
String data;
|
String data;
|
||||||
};
|
};
|
||||||
|
@ -160,6 +165,8 @@ class TextEdit : public Control {
|
||||||
bool is_marked(int p_line) const { return text[p_line].marked; }
|
bool is_marked(int p_line) const { return text[p_line].marked; }
|
||||||
void set_breakpoint(int p_line, bool p_breakpoint) { text[p_line].breakpoint = p_breakpoint; }
|
void set_breakpoint(int p_line, bool p_breakpoint) { text[p_line].breakpoint = p_breakpoint; }
|
||||||
bool is_breakpoint(int p_line) const { return text[p_line].breakpoint; }
|
bool is_breakpoint(int p_line) const { return text[p_line].breakpoint; }
|
||||||
|
void set_hidden(int p_line, bool p_hidden) { text[p_line].hidden = p_hidden; }
|
||||||
|
bool is_hidden(int p_line) const { return text[p_line].hidden; }
|
||||||
void insert(int p_at, const String &p_text);
|
void insert(int p_at, const String &p_text);
|
||||||
void remove(int p_at);
|
void remove(int p_at);
|
||||||
int size() const { return text.size(); }
|
int size() const { return text.size(); }
|
||||||
|
@ -251,6 +258,9 @@ class TextEdit : public Control {
|
||||||
int line_length_guideline_col;
|
int line_length_guideline_col;
|
||||||
bool draw_breakpoint_gutter;
|
bool draw_breakpoint_gutter;
|
||||||
int breakpoint_gutter_width;
|
int breakpoint_gutter_width;
|
||||||
|
bool draw_fold_gutter;
|
||||||
|
int fold_gutter_width;
|
||||||
|
bool hiding_enabled;
|
||||||
|
|
||||||
bool highlight_all_occurrences;
|
bool highlight_all_occurrences;
|
||||||
bool scroll_past_end_of_file_enabled;
|
bool scroll_past_end_of_file_enabled;
|
||||||
|
@ -293,9 +303,14 @@ class TextEdit : public Control {
|
||||||
int search_result_line;
|
int search_result_line;
|
||||||
int search_result_col;
|
int search_result_col;
|
||||||
|
|
||||||
|
double line_scroll_pos;
|
||||||
|
|
||||||
bool context_menu_enabled;
|
bool context_menu_enabled;
|
||||||
|
|
||||||
int get_visible_rows() const;
|
int get_visible_rows() const;
|
||||||
|
int get_total_unhidden_rows() const;
|
||||||
|
double get_line_scroll_pos(bool p_recalculate = false) const;
|
||||||
|
void update_line_scroll_pos();
|
||||||
|
|
||||||
int get_char_count();
|
int get_char_count();
|
||||||
|
|
||||||
|
@ -303,6 +318,7 @@ class TextEdit : public Control {
|
||||||
int get_column_x_offset(int p_char, String p_str);
|
int get_column_x_offset(int p_char, String p_str);
|
||||||
|
|
||||||
void adjust_viewport_to_cursor();
|
void adjust_viewport_to_cursor();
|
||||||
|
double get_scroll_line_diff() const;
|
||||||
void _scroll_moved(double);
|
void _scroll_moved(double);
|
||||||
void _update_scrollbars();
|
void _update_scrollbars();
|
||||||
void _v_scroll_input();
|
void _v_scroll_input();
|
||||||
|
@ -405,6 +421,18 @@ public:
|
||||||
void set_line_as_breakpoint(int p_line, bool p_breakpoint);
|
void set_line_as_breakpoint(int p_line, bool p_breakpoint);
|
||||||
bool is_line_set_as_breakpoint(int p_line) const;
|
bool is_line_set_as_breakpoint(int p_line) const;
|
||||||
void get_breakpoints(List<int> *p_breakpoints) const;
|
void get_breakpoints(List<int> *p_breakpoints) const;
|
||||||
|
|
||||||
|
void set_line_as_hidden(int p_line, bool p_hidden);
|
||||||
|
bool is_line_hidden(int p_line) const;
|
||||||
|
void fold_all_lines();
|
||||||
|
void unhide_all_lines();
|
||||||
|
int num_lines_from(int p_line_from, int unhidden_amount) const;
|
||||||
|
int get_whitespace_level(int p_line) const;
|
||||||
|
bool can_fold(int p_line) const;
|
||||||
|
bool is_folded(int p_line) const;
|
||||||
|
void fold_line(int p_line);
|
||||||
|
void unfold_line(int p_line);
|
||||||
|
|
||||||
String get_text();
|
String get_text();
|
||||||
String get_line(int line) const;
|
String get_line(int line) const;
|
||||||
void set_line(int line, String new_text);
|
void set_line(int line, String new_text);
|
||||||
|
@ -433,7 +461,7 @@ public:
|
||||||
void center_viewport_to_cursor();
|
void center_viewport_to_cursor();
|
||||||
|
|
||||||
void cursor_set_column(int p_col, bool p_adjust_viewport = true);
|
void cursor_set_column(int p_col, bool p_adjust_viewport = true);
|
||||||
void cursor_set_line(int p_row, bool p_adjust_viewport = true);
|
void cursor_set_line(int p_row, bool p_adjust_viewport = true, bool p_can_be_hidden = true);
|
||||||
|
|
||||||
int cursor_get_column() const;
|
int cursor_get_column() const;
|
||||||
int cursor_get_line() const;
|
int cursor_get_line() const;
|
||||||
|
@ -538,6 +566,15 @@ public:
|
||||||
void set_breakpoint_gutter_width(int p_gutter_width);
|
void set_breakpoint_gutter_width(int p_gutter_width);
|
||||||
int get_breakpoint_gutter_width() const;
|
int get_breakpoint_gutter_width() const;
|
||||||
|
|
||||||
|
void set_draw_fold_gutter(bool p_draw);
|
||||||
|
bool is_drawing_fold_gutter() const;
|
||||||
|
|
||||||
|
void set_fold_gutter_width(int p_gutter_width);
|
||||||
|
int get_fold_gutter_width() const;
|
||||||
|
|
||||||
|
void set_hiding_enabled(int p_enabled);
|
||||||
|
int is_hiding_enabled() const;
|
||||||
|
|
||||||
void set_tooltip_request_func(Object *p_obj, const StringName &p_function, const Variant &p_udata);
|
void set_tooltip_request_func(Object *p_obj, const StringName &p_function, const Variant &p_udata);
|
||||||
|
|
||||||
void set_completion(bool p_enabled, const Vector<String> &p_prefixes);
|
void set_completion(bool p_enabled, const Vector<String> &p_prefixes);
|
||||||
|
|
Loading…
Reference in a new issue