Merge pull request #10447 from Paulb23/smooth_scrolling
Added smooth scrolling to TextEdit
This commit is contained in:
commit
395544b4d0
6 changed files with 149 additions and 8 deletions
|
@ -1087,6 +1087,7 @@ void CodeTextEditor::update_editor_settings() {
|
||||||
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->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"));
|
||||||
}
|
}
|
||||||
|
|
||||||
void CodeTextEditor::set_error(const String &p_error) {
|
void CodeTextEditor::set_error(const String &p_error) {
|
||||||
|
|
|
@ -615,6 +615,7 @@ void EditorSettings::_load_defaults(Ref<ConfigFile> p_extra_config) {
|
||||||
set("text_editor/line_numbers/line_length_guideline_column", 80);
|
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");
|
||||||
|
|
||||||
|
set("text_editor/open_scripts/smooth_scrolling", true);
|
||||||
set("text_editor/open_scripts/show_members_overview", true);
|
set("text_editor/open_scripts/show_members_overview", true);
|
||||||
|
|
||||||
set("text_editor/files/trim_trailing_whitespace_on_save", false);
|
set("text_editor/files/trim_trailing_whitespace_on_save", false);
|
||||||
|
|
|
@ -98,7 +98,18 @@ void ScrollBar::_gui_input(Ref<InputEvent> p_event) {
|
||||||
|
|
||||||
if (ofs < grabber_ofs) {
|
if (ofs < grabber_ofs) {
|
||||||
|
|
||||||
set_value(get_value() - get_page());
|
if (scrolling) {
|
||||||
|
target_scroll = target_scroll - get_page();
|
||||||
|
} else {
|
||||||
|
target_scroll = get_value() - get_page();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (smooth_scroll_enabled) {
|
||||||
|
scrolling = true;
|
||||||
|
set_fixed_process(true);
|
||||||
|
} else {
|
||||||
|
set_value(target_scroll);
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -111,8 +122,18 @@ void ScrollBar::_gui_input(Ref<InputEvent> p_event) {
|
||||||
drag.value_at_click = get_as_ratio();
|
drag.value_at_click = get_as_ratio();
|
||||||
update();
|
update();
|
||||||
} else {
|
} else {
|
||||||
|
if (scrolling) {
|
||||||
|
target_scroll = target_scroll + get_page();
|
||||||
|
} else {
|
||||||
|
target_scroll = get_value() + get_page();
|
||||||
|
}
|
||||||
|
|
||||||
set_value(get_value() + get_page());
|
if (smooth_scroll_enabled) {
|
||||||
|
scrolling = true;
|
||||||
|
set_fixed_process(true);
|
||||||
|
} else {
|
||||||
|
set_value(target_scroll);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
@ -311,7 +332,22 @@ void ScrollBar::_notification(int p_what) {
|
||||||
|
|
||||||
if (p_what == NOTIFICATION_FIXED_PROCESS) {
|
if (p_what == NOTIFICATION_FIXED_PROCESS) {
|
||||||
|
|
||||||
if (drag_slave_touching) {
|
if (scrolling) {
|
||||||
|
if (get_value() != target_scroll) {
|
||||||
|
double target = target_scroll - get_value();
|
||||||
|
double dist = sqrt(target * target);
|
||||||
|
double vel = ((target / dist) * 500) * get_fixed_process_delta_time();
|
||||||
|
|
||||||
|
if (vel >= dist) {
|
||||||
|
set_value(target_scroll);
|
||||||
|
} else {
|
||||||
|
set_value(get_value() + vel);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
scrolling = false;
|
||||||
|
set_fixed_process(false);
|
||||||
|
}
|
||||||
|
} else if (drag_slave_touching) {
|
||||||
|
|
||||||
if (drag_slave_touching_deaccel) {
|
if (drag_slave_touching_deaccel) {
|
||||||
|
|
||||||
|
@ -639,6 +675,14 @@ NodePath ScrollBar::get_drag_slave() const {
|
||||||
return drag_slave_path;
|
return drag_slave_path;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ScrollBar::set_smooth_scroll_enabled(bool p_enable) {
|
||||||
|
smooth_scroll_enabled = p_enable;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ScrollBar::is_smooth_scroll_enabled() const {
|
||||||
|
return smooth_scroll_enabled;
|
||||||
|
}
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
|
|
||||||
void ScrollBar::mouse_button(const Point2& p_pos, int b->get_button_index(),bool b->is_pressed(),int p_modifier_mask) {
|
void ScrollBar::mouse_button(const Point2& p_pos, int b->get_button_index(),bool b->is_pressed(),int p_modifier_mask) {
|
||||||
|
@ -795,6 +839,10 @@ ScrollBar::ScrollBar(Orientation p_orientation) {
|
||||||
drag_slave_touching = false;
|
drag_slave_touching = false;
|
||||||
drag_slave_touching_deaccel = false;
|
drag_slave_touching_deaccel = false;
|
||||||
|
|
||||||
|
scrolling = false;
|
||||||
|
target_scroll = 0;
|
||||||
|
smooth_scroll_enabled = false;
|
||||||
|
|
||||||
if (focus_by_default)
|
if (focus_by_default)
|
||||||
set_focus_mode(FOCUS_ALL);
|
set_focus_mode(FOCUS_ALL);
|
||||||
set_step(0);
|
set_step(0);
|
||||||
|
|
|
@ -83,6 +83,10 @@ class ScrollBar : public Range {
|
||||||
bool drag_slave_touching_deaccel;
|
bool drag_slave_touching_deaccel;
|
||||||
bool click_handled;
|
bool click_handled;
|
||||||
|
|
||||||
|
bool scrolling;
|
||||||
|
double target_scroll;
|
||||||
|
bool smooth_scroll_enabled;
|
||||||
|
|
||||||
void _drag_slave_exit();
|
void _drag_slave_exit();
|
||||||
void _drag_slave_input(const Ref<InputEvent> &p_input);
|
void _drag_slave_input(const Ref<InputEvent> &p_input);
|
||||||
|
|
||||||
|
@ -100,6 +104,9 @@ public:
|
||||||
void set_drag_slave(const NodePath &p_path);
|
void set_drag_slave(const NodePath &p_path);
|
||||||
NodePath get_drag_slave() const;
|
NodePath get_drag_slave() const;
|
||||||
|
|
||||||
|
void set_smooth_scroll_enabled(bool p_enable);
|
||||||
|
bool is_smooth_scroll_enabled() const;
|
||||||
|
|
||||||
virtual Size2 get_minimum_size() const;
|
virtual Size2 get_minimum_size() const;
|
||||||
ScrollBar(Orientation p_orientation = VERTICAL);
|
ScrollBar(Orientation p_orientation = VERTICAL);
|
||||||
~ScrollBar();
|
~ScrollBar();
|
||||||
|
|
|
@ -338,6 +338,11 @@ void TextEdit::_update_scrollbars() {
|
||||||
v_scroll->show();
|
v_scroll->show();
|
||||||
v_scroll->set_max(total_rows);
|
v_scroll->set_max(total_rows);
|
||||||
v_scroll->set_page(visible_rows);
|
v_scroll->set_page(visible_rows);
|
||||||
|
if (smooth_scroll_enabled) {
|
||||||
|
v_scroll->set_step(0.25);
|
||||||
|
} else {
|
||||||
|
v_scroll->set_step(1);
|
||||||
|
}
|
||||||
|
|
||||||
if (fabs(v_scroll->get_value() - (double)cursor.line_ofs) >= 1) {
|
if (fabs(v_scroll->get_value() - (double)cursor.line_ofs) >= 1) {
|
||||||
v_scroll->set_value(cursor.line_ofs);
|
v_scroll->set_value(cursor.line_ofs);
|
||||||
|
@ -420,6 +425,24 @@ void TextEdit::_notification(int p_what) {
|
||||||
draw_caret = false;
|
draw_caret = false;
|
||||||
update();
|
update();
|
||||||
} break;
|
} break;
|
||||||
|
case NOTIFICATION_FIXED_PROCESS: {
|
||||||
|
if (scrolling && v_scroll->get_value() != target_v_scroll) {
|
||||||
|
double target_y = target_v_scroll - v_scroll->get_value();
|
||||||
|
double dist = sqrt(target_y * target_y);
|
||||||
|
double vel = ((target_y / dist) * 50) * get_fixed_process_delta_time();
|
||||||
|
|
||||||
|
if (vel >= dist) {
|
||||||
|
v_scroll->set_value(target_v_scroll);
|
||||||
|
scrolling = false;
|
||||||
|
set_fixed_process(false);
|
||||||
|
} else {
|
||||||
|
v_scroll->set_value(v_scroll->get_value() + vel);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
scrolling = false;
|
||||||
|
set_fixed_process(false);
|
||||||
|
}
|
||||||
|
} break;
|
||||||
case NOTIFICATION_DRAW: {
|
case NOTIFICATION_DRAW: {
|
||||||
|
|
||||||
if ((!has_focus() && !menu->has_focus()) || !window_has_focus) {
|
if ((!has_focus() && !menu->has_focus()) || !window_has_focus) {
|
||||||
|
@ -454,6 +477,7 @@ void TextEdit::_notification(int p_what) {
|
||||||
_update_scrollbars();
|
_update_scrollbars();
|
||||||
|
|
||||||
RID ci = get_canvas_item();
|
RID ci = get_canvas_item();
|
||||||
|
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;
|
||||||
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:
|
||||||
|
@ -674,7 +698,11 @@ void TextEdit::_notification(int p_what) {
|
||||||
|
|
||||||
int char_margin = xmargin_beg - cursor.x_ofs;
|
int char_margin = xmargin_beg - cursor.x_ofs;
|
||||||
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) {
|
||||||
|
ofs_y -= (v_scroll->get_value() - cursor.line_ofs) * get_row_height();
|
||||||
|
}
|
||||||
|
|
||||||
bool prev_is_char = false;
|
bool prev_is_char = false;
|
||||||
bool prev_is_number = false;
|
bool prev_is_number = false;
|
||||||
bool in_keyword = false;
|
bool in_keyword = false;
|
||||||
|
@ -1500,7 +1528,7 @@ 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;
|
int row = cursor.line_ofs + (rows + (v_scroll->get_value() - cursor.line_ofs));
|
||||||
|
|
||||||
if (row < 0)
|
if (row < 0)
|
||||||
row = 0;
|
row = 0;
|
||||||
|
@ -1566,10 +1594,43 @@ 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()) {
|
||||||
v_scroll->set_value(v_scroll->get_value() - (3 * mb->get_factor()));
|
if (scrolling) {
|
||||||
|
target_v_scroll = (target_v_scroll - (3 * mb->get_factor()));
|
||||||
|
} else {
|
||||||
|
target_v_scroll = (v_scroll->get_value() - (3 * mb->get_factor()));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (smooth_scroll_enabled) {
|
||||||
|
if (target_v_scroll <= 0) {
|
||||||
|
target_v_scroll = 0;
|
||||||
|
}
|
||||||
|
scrolling = true;
|
||||||
|
set_fixed_process(true);
|
||||||
|
} else {
|
||||||
|
v_scroll->set_value(target_v_scroll);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (mb->get_button_index() == BUTTON_WHEEL_DOWN && !mb->get_command()) {
|
if (mb->get_button_index() == BUTTON_WHEEL_DOWN && !mb->get_command()) {
|
||||||
v_scroll->set_value(v_scroll->get_value() + (3 * mb->get_factor()));
|
if (scrolling) {
|
||||||
|
target_v_scroll = (target_v_scroll + (3 * mb->get_factor()));
|
||||||
|
} else {
|
||||||
|
target_v_scroll = (v_scroll->get_value() + (3 * mb->get_factor()));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (smooth_scroll_enabled) {
|
||||||
|
int max_v_scroll = get_line_count() - 1;
|
||||||
|
if (!scroll_past_end_of_file_enabled) {
|
||||||
|
max_v_scroll -= get_visible_rows() - 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (target_v_scroll > max_v_scroll) {
|
||||||
|
target_v_scroll = max_v_scroll;
|
||||||
|
}
|
||||||
|
scrolling = true;
|
||||||
|
set_fixed_process(true);
|
||||||
|
} else {
|
||||||
|
v_scroll->set_value(target_v_scroll);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (mb->get_button_index() == BUTTON_WHEEL_LEFT) {
|
if (mb->get_button_index() == BUTTON_WHEEL_LEFT) {
|
||||||
h_scroll->set_value(h_scroll->get_value() - (100 * mb->get_factor()));
|
h_scroll->set_value(h_scroll->get_value() - (100 * mb->get_factor()));
|
||||||
|
@ -3092,7 +3153,7 @@ int TextEdit::get_visible_rows() const {
|
||||||
int total = cache.size.height;
|
int total = cache.size.height;
|
||||||
total -= cache.style_normal->get_minimum_size().height;
|
total -= cache.style_normal->get_minimum_size().height;
|
||||||
total /= get_row_height();
|
total /= get_row_height();
|
||||||
return total;
|
return total + 1;
|
||||||
}
|
}
|
||||||
void TextEdit::adjust_viewport_to_cursor() {
|
void TextEdit::adjust_viewport_to_cursor() {
|
||||||
|
|
||||||
|
@ -4194,6 +4255,15 @@ void TextEdit::set_h_scroll(int p_scroll) {
|
||||||
h_scroll->set_value(p_scroll);
|
h_scroll->set_value(p_scroll);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void TextEdit::set_smooth_scroll_enabled(bool p_enable) {
|
||||||
|
v_scroll->set_smooth_scroll_enabled(p_enable);
|
||||||
|
smooth_scroll_enabled = p_enable;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool TextEdit::is_smooth_scroll_enabled() const {
|
||||||
|
return smooth_scroll_enabled;
|
||||||
|
}
|
||||||
|
|
||||||
void TextEdit::set_completion(bool p_enabled, const Vector<String> &p_prefixes) {
|
void TextEdit::set_completion(bool p_enabled, const Vector<String> &p_prefixes) {
|
||||||
|
|
||||||
completion_prefixes.clear();
|
completion_prefixes.clear();
|
||||||
|
@ -4694,6 +4764,9 @@ void TextEdit::_bind_methods() {
|
||||||
ClassDB::bind_method(D_METHOD("set_syntax_coloring", "enable"), &TextEdit::set_syntax_coloring);
|
ClassDB::bind_method(D_METHOD("set_syntax_coloring", "enable"), &TextEdit::set_syntax_coloring);
|
||||||
ClassDB::bind_method(D_METHOD("is_syntax_coloring_enabled"), &TextEdit::is_syntax_coloring_enabled);
|
ClassDB::bind_method(D_METHOD("is_syntax_coloring_enabled"), &TextEdit::is_syntax_coloring_enabled);
|
||||||
|
|
||||||
|
ClassDB::bind_method(D_METHOD("set_smooth_scroll_enable", "enable"), &TextEdit::set_smooth_scroll_enabled);
|
||||||
|
ClassDB::bind_method(D_METHOD("is_smooth_scroll_enabled"), &TextEdit::is_smooth_scroll_enabled);
|
||||||
|
|
||||||
ClassDB::bind_method(D_METHOD("add_keyword_color", "keyword", "color"), &TextEdit::add_keyword_color);
|
ClassDB::bind_method(D_METHOD("add_keyword_color", "keyword", "color"), &TextEdit::add_keyword_color);
|
||||||
ClassDB::bind_method(D_METHOD("add_color_region", "begin_key", "end_key", "color", "line_only"), &TextEdit::add_color_region, DEFVAL(false));
|
ClassDB::bind_method(D_METHOD("add_color_region", "begin_key", "end_key", "color", "line_only"), &TextEdit::add_color_region, DEFVAL(false));
|
||||||
ClassDB::bind_method(D_METHOD("clear_colors"), &TextEdit::clear_colors);
|
ClassDB::bind_method(D_METHOD("clear_colors"), &TextEdit::clear_colors);
|
||||||
|
@ -4703,6 +4776,7 @@ void TextEdit::_bind_methods() {
|
||||||
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "syntax_highlighting"), "set_syntax_coloring", "is_syntax_coloring_enabled");
|
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "syntax_highlighting"), "set_syntax_coloring", "is_syntax_coloring_enabled");
|
||||||
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "show_line_numbers"), "set_show_line_numbers", "is_show_line_numbers_enabled");
|
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "show_line_numbers"), "set_show_line_numbers", "is_show_line_numbers_enabled");
|
||||||
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "highlight_all_occurrences"), "set_highlight_all_occurrences", "is_highlight_all_occurrences_enabled");
|
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "highlight_all_occurrences"), "set_highlight_all_occurrences", "is_highlight_all_occurrences_enabled");
|
||||||
|
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "smooth_scrolling"), "set_smooth_scroll_enable", "is_smooth_scroll_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");
|
||||||
|
@ -4839,6 +4913,9 @@ TextEdit::TextEdit() {
|
||||||
insert_mode = false;
|
insert_mode = false;
|
||||||
window_has_focus = true;
|
window_has_focus = true;
|
||||||
select_identifiers_enabled = false;
|
select_identifiers_enabled = false;
|
||||||
|
smooth_scroll_enabled = false;
|
||||||
|
scrolling = false;
|
||||||
|
target_v_scroll = 0;
|
||||||
|
|
||||||
raised_from_completion = false;
|
raised_from_completion = false;
|
||||||
|
|
||||||
|
|
|
@ -256,6 +256,10 @@ class TextEdit : public Control {
|
||||||
bool insert_mode;
|
bool insert_mode;
|
||||||
bool select_identifiers_enabled;
|
bool select_identifiers_enabled;
|
||||||
|
|
||||||
|
bool smooth_scroll_enabled;
|
||||||
|
bool scrolling;
|
||||||
|
float target_v_scroll;
|
||||||
|
|
||||||
bool raised_from_completion;
|
bool raised_from_completion;
|
||||||
|
|
||||||
String highlighted_word;
|
String highlighted_word;
|
||||||
|
@ -487,6 +491,9 @@ public:
|
||||||
int get_h_scroll() const;
|
int get_h_scroll() const;
|
||||||
void set_h_scroll(int p_scroll);
|
void set_h_scroll(int p_scroll);
|
||||||
|
|
||||||
|
void set_smooth_scroll_enabled(bool p_enable);
|
||||||
|
bool is_smooth_scroll_enabled() const;
|
||||||
|
|
||||||
uint32_t get_version() const;
|
uint32_t get_version() const;
|
||||||
uint32_t get_saved_version() const;
|
uint32_t get_saved_version() const;
|
||||||
void tag_saved_version();
|
void tag_saved_version();
|
||||||
|
|
Loading…
Reference in a new issue