diff options
Diffstat (limited to 'scene/gui')
-rw-r--r-- | scene/gui/color_picker.cpp | 27 | ||||
-rw-r--r-- | scene/gui/color_picker.h | 4 | ||||
-rw-r--r-- | scene/gui/control.cpp | 176 | ||||
-rw-r--r-- | scene/gui/control.h | 22 | ||||
-rw-r--r-- | scene/gui/item_list.cpp | 1 | ||||
-rw-r--r-- | scene/gui/rich_text_label.cpp | 2 | ||||
-rw-r--r-- | scene/gui/text_edit.cpp | 44 |
7 files changed, 141 insertions, 135 deletions
diff --git a/scene/gui/color_picker.cpp b/scene/gui/color_picker.cpp index 34891832e2..f8c188d33d 100644 --- a/scene/gui/color_picker.cpp +++ b/scene/gui/color_picker.cpp @@ -242,6 +242,14 @@ bool ColorPicker::is_raw_mode() const { return raw_mode_enabled; } +void ColorPicker::set_deferred_mode(bool p_enabled) { + deferred_mode_enabled = p_enabled; +} + +bool ColorPicker::is_deferred_mode() const { + return deferred_mode_enabled; +} + void ColorPicker::_update_text_value() { bool visible = true; if (text_is_constructor) { @@ -328,7 +336,11 @@ void ColorPicker::_uv_input(const Ref<InputEvent> &p_event) { last_hsv = color; set_pick_color(color); _update_color(); + if (!deferred_mode_enabled) + emit_signal("color_changed", color); + } else if (deferred_mode_enabled && !bev->is_pressed() && bev->get_button_index() == BUTTON_LEFT) { emit_signal("color_changed", color); + changing_color = false; } else { changing_color = false; } @@ -347,7 +359,8 @@ void ColorPicker::_uv_input(const Ref<InputEvent> &p_event) { last_hsv = color; set_pick_color(color); _update_color(); - emit_signal("color_changed", color); + if (!deferred_mode_enabled) + emit_signal("color_changed", color); } } @@ -368,7 +381,10 @@ void ColorPicker::_w_input(const Ref<InputEvent> &p_event) { last_hsv = color; set_pick_color(color); _update_color(); - emit_signal("color_changed", color); + if (!deferred_mode_enabled) + emit_signal("color_changed", color); + else if (!bev->is_pressed() && bev->get_button_index() == BUTTON_LEFT) + emit_signal("color_changed", color); } Ref<InputEventMouseMotion> mev = p_event; @@ -383,7 +399,8 @@ void ColorPicker::_w_input(const Ref<InputEvent> &p_event) { last_hsv = color; set_pick_color(color); _update_color(); - emit_signal("color_changed", color); + if (!deferred_mode_enabled) + emit_signal("color_changed", color); } } @@ -500,6 +517,8 @@ void ColorPicker::_bind_methods() { ClassDB::bind_method(D_METHOD("get_pick_color"), &ColorPicker::get_pick_color); ClassDB::bind_method(D_METHOD("set_raw_mode", "mode"), &ColorPicker::set_raw_mode); ClassDB::bind_method(D_METHOD("is_raw_mode"), &ColorPicker::is_raw_mode); + ClassDB::bind_method(D_METHOD("set_deferred_mode", "mode"), &ColorPicker::set_deferred_mode); + ClassDB::bind_method(D_METHOD("is_deferred_mode"), &ColorPicker::is_deferred_mode); ClassDB::bind_method(D_METHOD("set_edit_alpha", "show"), &ColorPicker::set_edit_alpha); ClassDB::bind_method(D_METHOD("is_editing_alpha"), &ColorPicker::is_editing_alpha); ClassDB::bind_method(D_METHOD("add_preset", "color"), &ColorPicker::add_preset); @@ -522,6 +541,7 @@ void ColorPicker::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::COLOR, "color"), "set_pick_color", "get_pick_color"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "edit_alpha"), "set_edit_alpha", "is_editing_alpha"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "raw_mode"), "set_raw_mode", "is_raw_mode"); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "deferred_mode"), "set_deferred_mode", "is_deferred_mode"); ADD_SIGNAL(MethodInfo("color_changed", PropertyInfo(Variant::COLOR, "color"))); } @@ -533,6 +553,7 @@ ColorPicker::ColorPicker() : edit_alpha = true; text_is_constructor = false; raw_mode_enabled = false; + deferred_mode_enabled = false; changing_color = false; screen = NULL; diff --git a/scene/gui/color_picker.h b/scene/gui/color_picker.h index 6b63e5fe60..c8d8e1aa8a 100644 --- a/scene/gui/color_picker.h +++ b/scene/gui/color_picker.h @@ -67,6 +67,7 @@ private: Color color; bool raw_mode_enabled; + bool deferred_mode_enabled; bool updating; bool changing_color; float h, s, v; @@ -107,6 +108,9 @@ public: void set_raw_mode(bool p_enabled); bool is_raw_mode() const; + void set_deferred_mode(bool p_enabled); + bool is_deferred_mode() const; + void set_focus_on_line_edit(); ColorPicker(); diff --git a/scene/gui/control.cpp b/scene/gui/control.cpp index 18a0cd13d9..289924976d 100644 --- a/scene/gui/control.cpp +++ b/scene/gui/control.cpp @@ -160,9 +160,16 @@ void Control::_update_minimum_size_cache() { Size2 minsize = get_minimum_size(); minsize.x = MAX(minsize.x, data.custom_minimum_size.x); minsize.y = MAX(minsize.y, data.custom_minimum_size.y); + + bool size_changed = false; + if (data.minimum_size_cache != minsize) + size_changed = true; + data.minimum_size_cache = minsize; data.minimum_size_valid = true; - minimum_size_changed(); + + if (size_changed) + minimum_size_changed(); } Size2 Control::get_combined_minimum_size() const { @@ -1267,21 +1274,23 @@ bool Control::has_constant(const StringName &p_name, const StringName &p_type) c return Theme::get_default()->has_constant(p_name, type); } -Size2 Control::get_parent_area_size() const { - - ERR_FAIL_COND_V(!is_inside_tree(), Size2()); - - Size2 parent_size; +Rect2 Control::get_parent_anchorable_rect() const { + if (!is_inside_tree()) + return Rect2(); + Rect2 parent_rect; if (data.parent_canvas_item) { - - parent_size = data.parent_canvas_item->_edit_get_rect().size; + parent_rect = data.parent_canvas_item->get_anchorable_rect(); } else { - - parent_size = get_viewport()->get_visible_rect().size; + parent_rect = get_viewport()->get_visible_rect(); } - return parent_size; + return parent_rect; +} + +Size2 Control::get_parent_area_size() const { + + return get_parent_anchorable_rect().size; } void Control::_size_changed() { @@ -1289,13 +1298,13 @@ void Control::_size_changed() { if (!is_inside_tree()) return; - Size2 parent_size = get_parent_area_size(); + Rect2 parent_rect = get_parent_anchorable_rect(); float margin_pos[4]; for (int i = 0; i < 4; i++) { - float area = parent_size[i & 1]; + float area = parent_rect.size[i & 1]; margin_pos[i] = data.margin[i] + (data.anchor[i] * area); } @@ -1349,43 +1358,9 @@ void Control::_size_changed() { } } -float Control::_get_parent_range(int p_idx) const { - - if (!is_inside_tree()) { - - return 0; - } - if (data.parent_canvas_item) { - - return data.parent_canvas_item->_edit_get_rect().size[p_idx & 1]; - } else { - return get_viewport()->get_visible_rect().size[p_idx & 1]; - } - - return 0; -} - -float Control::_get_range(int p_idx) const { - - p_idx &= 1; - - float parent_range = _get_parent_range(p_idx); - float from = _a2s(data.margin[p_idx], data.anchor[p_idx], parent_range); - float to = _a2s(data.margin[p_idx + 2], data.anchor[p_idx + 2], parent_range); - - return to - from; -} - -float Control::_s2a(float p_val, float p_anchor, float p_range) const { - return p_val - (p_anchor * p_range); -} - -float Control::_a2s(float p_val, float p_anchor, float p_range) const { - return Math::floor(p_val + (p_anchor * p_range)); -} - void Control::set_anchor(Margin p_margin, float p_anchor, bool p_keep_margin, bool p_push_opposite_anchor) { - float parent_range = _get_parent_range((p_margin == MARGIN_LEFT || p_margin == MARGIN_RIGHT) ? 0 : 1); + Rect2 parent_rect = get_parent_anchorable_rect(); + float parent_range = (p_margin == MARGIN_LEFT || p_margin == MARGIN_RIGHT) ? parent_rect.size.x : parent_rect.size.y; float previous_margin_pos = data.margin[p_margin] + data.anchor[p_margin] * parent_range; float previous_opposite_margin_pos = data.margin[(p_margin + 2) % 4] + data.anchor[(p_margin + 2) % 4] * parent_range; @@ -1401,9 +1376,9 @@ void Control::set_anchor(Margin p_margin, float p_anchor, bool p_keep_margin, bo } if (!p_keep_margin) { - data.margin[p_margin] = _s2a(previous_margin_pos, data.anchor[p_margin], parent_range); + data.margin[p_margin] = previous_margin_pos - data.anchor[p_margin] * parent_range; if (p_push_opposite_anchor) { - data.margin[(p_margin + 2) % 4] = _s2a(previous_opposite_margin_pos, data.anchor[(p_margin + 2) % 4], parent_range); + data.margin[(p_margin + 2) % 4] = previous_opposite_margin_pos - data.anchor[(p_margin + 2) % 4] * parent_range; } } if (is_inside_tree()) { @@ -1557,8 +1532,7 @@ void Control::set_margins_preset(LayoutPreset p_preset, LayoutPresetMode p_resiz new_size.y = min_size.y; } - float pw = _get_parent_range(0); - float ph = _get_parent_range(1); + Rect2 parent_rect = get_parent_anchorable_rect(); //Left switch (p_preset) { @@ -1570,21 +1544,21 @@ void Control::set_margins_preset(LayoutPreset p_preset, LayoutPresetMode p_resiz case PRESET_LEFT_WIDE: case PRESET_HCENTER_WIDE: case PRESET_WIDE: - data.margin[0] = pw * (0.0 - data.anchor[0]) + p_margin; + data.margin[0] = parent_rect.size.x * (0.0 - data.anchor[0]) + p_margin + parent_rect.position.x; break; case PRESET_CENTER_TOP: case PRESET_CENTER_BOTTOM: case PRESET_CENTER: case PRESET_VCENTER_WIDE: - data.margin[0] = pw * (0.5 - data.anchor[0]) - new_size.x / 2; + data.margin[0] = parent_rect.size.x * (0.5 - data.anchor[0]) - new_size.x / 2 + parent_rect.position.x; break; case PRESET_TOP_RIGHT: case PRESET_BOTTOM_RIGHT: case PRESET_CENTER_RIGHT: case PRESET_RIGHT_WIDE: - data.margin[0] = pw * (1.0 - data.anchor[0]) - new_size.x - p_margin; + data.margin[0] = parent_rect.size.x * (1.0 - data.anchor[0]) - new_size.x - p_margin + parent_rect.position.x; break; } @@ -1598,21 +1572,21 @@ void Control::set_margins_preset(LayoutPreset p_preset, LayoutPresetMode p_resiz case PRESET_TOP_WIDE: case PRESET_VCENTER_WIDE: case PRESET_WIDE: - data.margin[1] = ph * (0.0 - data.anchor[1]) + p_margin; + data.margin[1] = parent_rect.size.y * (0.0 - data.anchor[1]) + p_margin + parent_rect.position.y; break; case PRESET_CENTER_LEFT: case PRESET_CENTER_RIGHT: case PRESET_CENTER: case PRESET_HCENTER_WIDE: - data.margin[1] = ph * (0.5 - data.anchor[1]) - new_size.y / 2; + data.margin[1] = parent_rect.size.y * (0.5 - data.anchor[1]) - new_size.y / 2 + parent_rect.position.y; break; case PRESET_BOTTOM_LEFT: case PRESET_BOTTOM_RIGHT: case PRESET_CENTER_BOTTOM: case PRESET_BOTTOM_WIDE: - data.margin[1] = ph * (1.0 - data.anchor[1]) - new_size.y - p_margin; + data.margin[1] = parent_rect.size.y * (1.0 - data.anchor[1]) - new_size.y - p_margin + parent_rect.position.y; break; } @@ -1622,14 +1596,14 @@ void Control::set_margins_preset(LayoutPreset p_preset, LayoutPresetMode p_resiz case PRESET_BOTTOM_LEFT: case PRESET_CENTER_LEFT: case PRESET_LEFT_WIDE: - data.margin[2] = pw * (0.0 - data.anchor[2]) + new_size.x + p_margin; + data.margin[2] = parent_rect.size.x * (0.0 - data.anchor[2]) + new_size.x + p_margin + parent_rect.position.x; break; case PRESET_CENTER_TOP: case PRESET_CENTER_BOTTOM: case PRESET_CENTER: case PRESET_VCENTER_WIDE: - data.margin[2] = pw * (0.5 - data.anchor[2]) + new_size.x / 2; + data.margin[2] = parent_rect.size.x * (0.5 - data.anchor[2]) + new_size.x / 2 + parent_rect.position.x; break; case PRESET_TOP_RIGHT: @@ -1640,7 +1614,7 @@ void Control::set_margins_preset(LayoutPreset p_preset, LayoutPresetMode p_resiz case PRESET_BOTTOM_WIDE: case PRESET_HCENTER_WIDE: case PRESET_WIDE: - data.margin[2] = pw * (1.0 - data.anchor[2]) - p_margin; + data.margin[2] = parent_rect.size.x * (1.0 - data.anchor[2]) - p_margin + parent_rect.position.x; break; } @@ -1650,14 +1624,14 @@ void Control::set_margins_preset(LayoutPreset p_preset, LayoutPresetMode p_resiz case PRESET_TOP_RIGHT: case PRESET_CENTER_TOP: case PRESET_TOP_WIDE: - data.margin[3] = ph * (0.0 - data.anchor[3]) + new_size.y + p_margin; + data.margin[3] = parent_rect.size.y * (0.0 - data.anchor[3]) + new_size.y + p_margin + parent_rect.position.y; break; case PRESET_CENTER_LEFT: case PRESET_CENTER_RIGHT: case PRESET_CENTER: case PRESET_HCENTER_WIDE: - data.margin[3] = ph * (0.5 - data.anchor[3]) + new_size.y / 2; + data.margin[3] = parent_rect.size.y * (0.5 - data.anchor[3]) + new_size.y / 2 + parent_rect.position.y; break; case PRESET_BOTTOM_LEFT: @@ -1668,7 +1642,7 @@ void Control::set_margins_preset(LayoutPreset p_preset, LayoutPresetMode p_resiz case PRESET_BOTTOM_WIDE: case PRESET_VCENTER_WIDE: case PRESET_WIDE: - data.margin[3] = ph * (1.0 - data.anchor[3]) - p_margin; + data.margin[3] = parent_rect.size.y * (1.0 - data.anchor[3]) - p_margin + parent_rect.position.y; break; } @@ -1747,31 +1721,29 @@ void Control::set_global_position(const Point2 &p_point) { set_position(inv.xform(p_point)); } -void Control::set_position(const Size2 &p_point) { - - float pw = _get_parent_range(0); - float ph = _get_parent_range(1); +Rect2 Control::_compute_child_rect(const float p_anchors[4], const float p_margins[4]) const { - float x = _a2s(data.margin[0], data.anchor[0], pw); - float y = _a2s(data.margin[1], data.anchor[1], ph); - float x2 = _a2s(data.margin[2], data.anchor[2], pw); - float y2 = _a2s(data.margin[3], data.anchor[3], ph); + Rect2 anchorable = get_parent_anchorable_rect(); + Rect2 result = anchorable; + for (int i = 0; i < 4; i++) { + result.grow_margin((Margin)i, p_anchors[i] * anchorable.get_size()[i % 2] + p_margins[i]); + } - Size2 ret = Size2(x2 - x, y2 - y); - Size2 min = get_combined_minimum_size(); + return result; +} - Size2 size = Size2(MAX(min.width, ret.width), MAX(min.height, ret.height)); - float w = size.x; - float h = size.y; +void Control::_compute_margins(Rect2 p_rect, const float p_anchors[4], float (&r_margins)[4]) { - x = p_point.x; - y = p_point.y; + Size2 parent_rect_size = get_parent_anchorable_rect().size; + r_margins[0] = Math::floor(p_rect.position.x - (p_anchors[0] * parent_rect_size.x)); + r_margins[1] = Math::floor(p_rect.position.y - (p_anchors[1] * parent_rect_size.y)); + r_margins[2] = Math::floor(p_rect.position.x + p_rect.size.x - (p_anchors[2] * parent_rect_size.x)); + r_margins[3] = Math::floor(p_rect.position.y + p_rect.size.y - (p_anchors[3] * parent_rect_size.y)); +} - data.margin[0] = _s2a(x, data.anchor[0], pw); - data.margin[1] = _s2a(y, data.anchor[1], ph); - data.margin[2] = _s2a(x + w, data.anchor[2], pw); - data.margin[3] = _s2a(y + h, data.anchor[3], ph); +void Control::set_position(const Size2 &p_point) { + _compute_margins(Rect2(p_point, data.size_cache), data.anchor, data.margin); _size_changed(); } @@ -1784,18 +1756,7 @@ void Control::set_size(const Size2 &p_size) { if (new_size.y < min.y) new_size.y = min.y; - float pw = _get_parent_range(0); - float ph = _get_parent_range(1); - - float x = _a2s(data.margin[0], data.anchor[0], pw); - float y = _a2s(data.margin[1], data.anchor[1], ph); - - float w = new_size.width; - float h = new_size.height; - - data.margin[2] = _s2a(x + w, data.anchor[2], pw); - data.margin[3] = _s2a(y + h, data.anchor[3], ph); - + _compute_margins(Rect2(data.pos_cache, new_size), data.anchor, data.margin); _size_changed(); } @@ -1826,6 +1787,11 @@ Rect2 Control::get_rect() const { return Rect2(get_position(), get_size()); } +Rect2 Control::get_anchorable_rect() const { + + return Rect2(Point2(), get_size()); +} + void Control::add_icon_override(const StringName &p_name, const Ref<Texture> &p_icon) { ERR_FAIL_COND(p_icon.is_null()); @@ -2325,12 +2291,11 @@ Control *Control::_get_focus_neighbour(Margin p_margin, int p_count) { Point2 points[4]; Transform2D xform = get_global_transform(); - Rect2 rect = _edit_get_rect(); - points[0] = xform.xform(rect.position); - points[1] = xform.xform(rect.position + Point2(rect.size.x, 0)); - points[2] = xform.xform(rect.position + rect.size); - points[3] = xform.xform(rect.position + Point2(0, rect.size.y)); + points[0] = xform.xform(Point2()); + points[1] = xform.xform(Point2(get_size().x, 0)); + points[2] = xform.xform(get_size()); + points[3] = xform.xform(Point2(0, get_size().y)); const Vector2 dir[4] = { Vector2(-1, 0), @@ -2384,12 +2349,11 @@ void Control::_window_find_focus_neighbour(const Vector2 &p_dir, Node *p_at, con Point2 points[4]; Transform2D xform = c->get_global_transform(); - Rect2 rect = c->_edit_get_rect(); - points[0] = xform.xform(rect.position); - points[1] = xform.xform(rect.position + Point2(rect.size.x, 0)); - points[2] = xform.xform(rect.position + rect.size); - points[3] = xform.xform(rect.position + Point2(0, rect.size.y)); + points[0] = xform.xform(Point2()); + points[1] = xform.xform(Point2(get_size().x, 0)); + points[2] = xform.xform(get_size()); + points[3] = xform.xform(Point2(0, get_size().y)); float min = 1e7; diff --git a/scene/gui/control.h b/scene/gui/control.h index 9124256624..fa5274d854 100644 --- a/scene/gui/control.h +++ b/scene/gui/control.h @@ -202,12 +202,12 @@ private: NodePath focus_next; NodePath focus_prev; - HashMap<StringName, Ref<Texture>, StringNameHasher> icon_override; - HashMap<StringName, Ref<Shader>, StringNameHasher> shader_override; - HashMap<StringName, Ref<StyleBox>, StringNameHasher> style_override; - HashMap<StringName, Ref<Font>, StringNameHasher> font_override; - HashMap<StringName, Color, StringNameHasher> color_override; - HashMap<StringName, int, StringNameHasher> constant_override; + HashMap<StringName, Ref<Texture> > icon_override; + HashMap<StringName, Ref<Shader> > shader_override; + HashMap<StringName, Ref<StyleBox> > style_override; + HashMap<StringName, Ref<Font> > font_override; + HashMap<StringName, Color> color_override; + HashMap<StringName, int> constant_override; Map<Ref<Font>, int> font_refcount; } data; @@ -220,10 +220,6 @@ private: void _set_anchor(Margin p_margin, float p_anchor); - float _get_parent_range(int p_idx) const; - float _get_range(int p_idx) const; - float _s2a(float p_val, float p_anchor, float p_range) const; - float _a2s(float p_val, float p_anchor, float p_range) const; void _propagate_theme_changed(CanvasItem *p_at, Control *p_owner, bool p_assign = true); void _theme_changed(); @@ -233,6 +229,9 @@ private: void _update_scroll(); void _resize(const Size2 &p_size); + Rect2 _compute_child_rect(const float p_anchors[4], const float p_margins[4]) const; + void _compute_margins(Rect2 p_rect, const float p_anchors[4], float (&r_margins)[4]); + void _size_changed(); String _get_tooltip() const; @@ -283,6 +282,7 @@ public: }; + /* EDITOR */ virtual Dictionary _edit_get_state() const; virtual void _edit_set_state(const Dictionary &p_state); @@ -358,6 +358,7 @@ public: Rect2 get_rect() const; Rect2 get_global_rect() const; Rect2 get_window_rect() const; ///< use with care, as it blocks waiting for the visual server + Rect2 get_anchorable_rect() const; void set_rotation(float p_radians); void set_rotation_degrees(float p_degrees); @@ -465,6 +466,7 @@ public: bool is_toplevel_control() const; Size2 get_parent_area_size() const; + Rect2 get_parent_anchorable_rect() const; void grab_click_focus(); diff --git a/scene/gui/item_list.cpp b/scene/gui/item_list.cpp index 57b9a9a11b..72ed0e9b81 100644 --- a/scene/gui/item_list.cpp +++ b/scene/gui/item_list.cpp @@ -942,6 +942,7 @@ void ItemList::_notification(int p_what) { } } + minimum_size_changed(); shape_changed = false; } diff --git a/scene/gui/rich_text_label.cpp b/scene/gui/rich_text_label.cpp index f34559fc8d..ce2e3538da 100644 --- a/scene/gui/rich_text_label.cpp +++ b/scene/gui/rich_text_label.cpp @@ -324,7 +324,7 @@ int RichTextLabel::_process_line(ItemFrame *p_frame, const Vector2 &p_ofs, int & color = _find_color(text, p_base_color); font_color_shadow = _find_color(text, p_font_color_shadow); underline = _find_underline(text); - if (_find_meta(text, &meta)) { + if (_find_meta(text, &meta) && underline_meta) { underline = true; } diff --git a/scene/gui/text_edit.cpp b/scene/gui/text_edit.cpp index 215ba0271f..327c236f8c 100644 --- a/scene/gui/text_edit.cpp +++ b/scene/gui/text_edit.cpp @@ -426,6 +426,9 @@ void TextEdit::_update_scrollbars() { void TextEdit::_click_selection_held() { + // Warning: is_mouse_button_pressed(BUTTON_LEFT) returns false for double+ clicks, so this doesn't work for MODE_WORD + // and MODE_LINE. However, moving the mouse triggers _gui_input, which calls these functions too, so that's not a huge problem. + // I'm unsure if there's an actual fix that doesn't have a ton of side effects. if (Input::get_singleton()->is_mouse_button_pressed(BUTTON_LEFT) && selection.selecting_mode != Selection::MODE_NONE) { switch (selection.selecting_mode) { case Selection::MODE_POINTER: { @@ -455,7 +458,7 @@ void TextEdit::_update_selection_mode_pointer() { select(selection.selecting_line, selection.selecting_column, row, col); cursor_set_line(row, false); - cursor_set_column(col, false); + cursor_set_column(col); update(); click_select_held->start(); @@ -496,21 +499,24 @@ void TextEdit::_update_selection_mode_word() { selection.selected_word_beg = beg; selection.selected_word_end = end; selection.selected_word_origin = beg; + cursor_set_line(selection.to_line, false); cursor_set_column(selection.to_column); } else { if ((col <= selection.selected_word_origin && row == selection.selecting_line) || row < selection.selecting_line) { selection.selecting_column = selection.selected_word_end; select(row, beg, selection.selecting_line, selection.selected_word_end); + cursor_set_line(selection.from_line, false); cursor_set_column(selection.from_column); } else { selection.selecting_column = selection.selected_word_beg; select(selection.selecting_line, selection.selected_word_beg, row, end); + cursor_set_line(selection.to_line, false); cursor_set_column(selection.to_column); } } - cursor_set_line(row, false); update(); + click_select_held->start(); } @@ -531,7 +537,7 @@ void TextEdit::_update_selection_mode_line() { selection.selecting_column = 0; col = text[row].length(); } - cursor_set_column(0, false); + cursor_set_column(0); select(selection.selecting_line, selection.selecting_column, row, col); update(); @@ -1660,14 +1666,17 @@ void TextEdit::_get_mouse_pos(const Point2i &p_mouse, int &r_row, int &r_col) co rows /= get_row_height(); rows += get_v_scroll_offset(); int first_vis_line = get_first_visible_line(); + int last_vis_line = get_last_visible_line(); int row = first_vis_line + Math::floor(rows); int wrap_index = 0; if (is_wrap_enabled() || is_hiding_enabled()) { - int f_ofs = num_lines_from_rows(first_vis_line, cursor.wrap_ofs, rows + 1, wrap_index) - 1; - row = first_vis_line + f_ofs; - row = CLAMP(row, 0, get_last_visible_line() + 1); + int f_ofs = num_lines_from_rows(first_vis_line, cursor.wrap_ofs, rows + (1 * SGN(rows)), wrap_index) - 1; + if (rows < 0) + row = first_vis_line - f_ofs; + else + row = first_vis_line + f_ofs; } if (row < 0) @@ -5765,18 +5774,23 @@ String TextEdit::get_word_at_pos(const Vector2 &p_pos) const { if (select_word(s, col, beg, end)) { bool inside_quotes = false; + char selected_quote = '\0'; int qbegin = 0, qend = 0; for (int i = 0; i < s.length(); i++) { - if (s[i] == '"') { - if (inside_quotes) { - qend = i; - inside_quotes = false; - if (col >= qbegin && col <= qend) { - return s.substr(qbegin, qend - qbegin); + if (s[i] == '"' || s[i] == '\'') { + if (i == 0 || s[i - 1] != '\\') { + if (inside_quotes && selected_quote == s[i]) { + qend = i; + inside_quotes = false; + selected_quote = '\0'; + if (col >= qbegin && col <= qend) { + return s.substr(qbegin, qend - qbegin); + } + } else if (!inside_quotes) { + qbegin = i + 1; + inside_quotes = true; + selected_quote = s[i]; } - } else { - qbegin = i + 1; - inside_quotes = true; } } } |