summaryrefslogtreecommitdiff
path: root/scene/gui
diff options
context:
space:
mode:
Diffstat (limited to 'scene/gui')
-rw-r--r--scene/gui/color_picker.cpp347
-rw-r--r--scene/gui/color_picker.h49
-rw-r--r--scene/gui/container.cpp12
-rw-r--r--scene/gui/container.h2
-rw-r--r--scene/gui/control.cpp25
-rw-r--r--scene/gui/control.h2
-rw-r--r--scene/gui/gradient_edit.cpp2
-rw-r--r--scene/gui/item_list.cpp4
-rw-r--r--scene/gui/line_edit.cpp353
-rw-r--r--scene/gui/line_edit.h50
-rw-r--r--scene/gui/range.cpp16
-rw-r--r--scene/gui/range.h2
-rw-r--r--scene/gui/rich_text_label.cpp16
-rw-r--r--scene/gui/rich_text_label.h2
-rw-r--r--scene/gui/scroll_container.cpp127
-rw-r--r--scene/gui/scroll_container.h24
-rw-r--r--scene/gui/text_edit.cpp48
-rw-r--r--scene/gui/tree.cpp12
-rw-r--r--scene/gui/tree.h2
19 files changed, 682 insertions, 413 deletions
diff --git a/scene/gui/color_picker.cpp b/scene/gui/color_picker.cpp
index 78524a856a..b78f9cad24 100644
--- a/scene/gui/color_picker.cpp
+++ b/scene/gui/color_picker.cpp
@@ -143,6 +143,30 @@ void ColorPicker::_update_controls() {
scroll[3]->hide();
labels[3]->hide();
}
+
+ switch (picker_type) {
+ case SHAPE_HSV_RECTANGLE:
+ wheel_edit->hide();
+ w_edit->show();
+ uv_edit->show();
+ break;
+ case SHAPE_HSV_WHEEL:
+ wheel_edit->show();
+ w_edit->hide();
+ uv_edit->hide();
+
+ wheel->set_material(wheel_mat);
+ break;
+ case SHAPE_VHS_CIRCLE:
+ wheel_edit->show();
+ w_edit->show();
+ uv_edit->hide();
+
+ wheel->set_material(circle_mat);
+ break;
+ default: {
+ }
+ }
}
void ColorPicker::_set_pick_color(const Color &p_color, bool p_update_sliders) {
@@ -267,6 +291,8 @@ void ColorPicker::_update_color(bool p_update_sliders) {
for (int i = 0; i < 4; i++) {
scroll[i]->update();
}
+ wheel->update();
+ wheel_uv->update();
updating = false;
}
@@ -309,6 +335,18 @@ Color ColorPicker::get_pick_color() const {
return color;
}
+void ColorPicker::set_picker_shape(PickerShapeType p_picker_type) {
+ ERR_FAIL_INDEX(p_picker_type, SHAPE_MAX);
+ picker_type = p_picker_type;
+
+ _update_controls();
+ _update_color();
+}
+
+ColorPicker::PickerShapeType ColorPicker::get_picker_shape() const {
+ return picker_type;
+}
+
void ColorPicker::add_preset(const Color &p_color) {
if (presets.find(p_color)) {
presets.move_to_back(presets.find(p_color));
@@ -421,7 +459,7 @@ void ColorPicker::_update_text_value() {
}
void ColorPicker::_sample_draw() {
- const Rect2 r = Rect2(Point2(), Size2(uv_edit->get_size().width, sample->get_size().height * 0.95));
+ const Rect2 r = Rect2(Point2(), Size2(sample->get_size().width, sample->get_size().height * 0.95));
if (color.a < 1.0) {
sample->draw_texture_rect(get_theme_icon("preset_bg", "ColorPicker"), r, true);
@@ -441,42 +479,131 @@ void ColorPicker::_hsv_draw(int p_which, Control *c) {
}
if (p_which == 0) {
Vector<Point2> points;
- points.push_back(Vector2());
- points.push_back(Vector2(c->get_size().x, 0));
- points.push_back(c->get_size());
- points.push_back(Vector2(0, c->get_size().y));
Vector<Color> colors;
- colors.push_back(Color(1, 1, 1, 1));
- colors.push_back(Color(1, 1, 1, 1));
- colors.push_back(Color(0, 0, 0, 1));
- colors.push_back(Color(0, 0, 0, 1));
- c->draw_polygon(points, colors);
Vector<Color> colors2;
Color col = color;
+ Vector2 center = c->get_size() / 2.0;
+
+ switch (picker_type) {
+ case SHAPE_HSV_WHEEL: {
+ points.resize(4);
+ colors.resize(4);
+ colors2.resize(4);
+ real_t ring_radius_x = Math_SQRT12 * c->get_size().width * 0.42;
+ real_t ring_radius_y = Math_SQRT12 * c->get_size().height * 0.42;
+
+ points.set(0, center - Vector2(ring_radius_x, ring_radius_y));
+ points.set(1, center + Vector2(ring_radius_x, -ring_radius_y));
+ points.set(2, center + Vector2(ring_radius_x, ring_radius_y));
+ points.set(3, center + Vector2(-ring_radius_x, ring_radius_y));
+ colors.set(0, Color(1, 1, 1, 1));
+ colors.set(1, Color(1, 1, 1, 1));
+ colors.set(2, Color(0, 0, 0, 1));
+ colors.set(3, Color(0, 0, 0, 1));
+ c->draw_polygon(points, colors);
+
+ col.set_hsv(h, 1, 1);
+ col.a = 0;
+ colors2.set(0, col);
+ col.a = 1;
+ colors2.set(1, col);
+ col.set_hsv(h, 1, 0);
+ colors2.set(2, col);
+ col.a = 0;
+ colors2.set(3, col);
+ c->draw_polygon(points, colors2);
+ break;
+ }
+ case SHAPE_HSV_RECTANGLE: {
+ points.resize(4);
+ colors.resize(4);
+ colors2.resize(4);
+ points.set(0, Vector2());
+ points.set(1, Vector2(c->get_size().x, 0));
+ points.set(2, c->get_size());
+ points.set(3, Vector2(0, c->get_size().y));
+ colors.set(0, Color(1, 1, 1, 1));
+ colors.set(1, Color(1, 1, 1, 1));
+ colors.set(2, Color(0, 0, 0, 1));
+ colors.set(3, Color(0, 0, 0, 1));
+ c->draw_polygon(points, colors);
+ col = color;
+ col.set_hsv(h, 1, 1);
+ col.a = 0;
+ colors2.set(0, col);
+ col.a = 1;
+ colors2.set(1, col);
+ col.set_hsv(h, 1, 0);
+ colors2.set(2, col);
+ col.a = 0;
+ colors2.set(3, col);
+ c->draw_polygon(points, colors2);
+ break;
+ }
+ default: {
+ }
+ }
+ Ref<Texture2D> cursor = get_theme_icon("picker_cursor", "ColorPicker");
+ int x;
+ int y;
+ if (picker_type == SHAPE_VHS_CIRCLE) {
+ x = center.x + (center.x * Math::cos(h * Math_TAU) * s) - (cursor->get_width() / 2);
+ y = center.y + (center.y * Math::sin(h * Math_TAU) * s) - (cursor->get_height() / 2);
+ } else {
+ real_t corner_x = (c == wheel_uv) ? center.x - Math_SQRT12 * c->get_size().width * 0.42 : 0;
+ real_t corner_y = (c == wheel_uv) ? center.y - Math_SQRT12 * c->get_size().height * 0.42 : 0;
+
+ Size2 real_size(c->get_size().x - corner_x * 2, c->get_size().y - corner_y * 2);
+ x = CLAMP(real_size.x * s, 0, real_size.x) + corner_x - (cursor->get_width() / 2);
+ y = CLAMP(real_size.y - real_size.y * v, 0, real_size.y) + corner_y - (cursor->get_height() / 2);
+ }
+ c->draw_texture(cursor, Point2(x, y));
+
col.set_hsv(h, 1, 1);
- col.a = 0;
- colors2.push_back(col);
- col.a = 1;
- colors2.push_back(col);
- col.set_hsv(h, 1, 0);
- colors2.push_back(col);
- col.a = 0;
- colors2.push_back(col);
- c->draw_polygon(points, colors2);
- int x = CLAMP(c->get_size().x * s, 0, c->get_size().x);
- int y = CLAMP(c->get_size().y - c->get_size().y * v, 0, c->get_size().y);
- col = color;
- col.a = 1;
- c->draw_line(Point2(x, 0), Point2(x, c->get_size().y), col.inverted());
- c->draw_line(Point2(0, y), Point2(c->get_size().x, y), col.inverted());
- c->draw_line(Point2(x, y), Point2(x, y), Color(1, 1, 1), 2);
+ if (picker_type == SHAPE_HSV_WHEEL) {
+ points.resize(4);
+ double h1 = h - (0.5 / 360);
+ double h2 = h + (0.5 / 360);
+ points.set(0, Point2(center.x + (center.x * Math::cos(h1 * Math_TAU)), center.y + (center.y * Math::sin(h1 * Math_TAU))));
+ points.set(1, Point2(center.x + (center.x * Math::cos(h1 * Math_TAU) * 0.84), center.y + (center.y * Math::sin(h1 * Math_TAU) * 0.84)));
+ points.set(2, Point2(center.x + (center.x * Math::cos(h2 * Math_TAU)), center.y + (center.y * Math::sin(h2 * Math_TAU))));
+ points.set(3, Point2(center.x + (center.x * Math::cos(h2 * Math_TAU) * 0.84), center.y + (center.y * Math::sin(h2 * Math_TAU) * 0.84)));
+ c->draw_multiline(points, col.inverted());
+ }
+
} else if (p_which == 1) {
- Ref<Texture2D> hue = get_theme_icon("color_hue", "ColorPicker");
- c->draw_texture_rect(hue, Rect2(Point2(), c->get_size()));
- int y = c->get_size().y - c->get_size().y * (1.0 - h);
- Color col = Color();
- col.set_hsv(h, 1, 1);
- c->draw_line(Point2(0, y), Point2(c->get_size().x, y), col.inverted());
+ if (picker_type == SHAPE_HSV_RECTANGLE) {
+ Ref<Texture2D> hue = get_theme_icon("color_hue", "ColorPicker");
+ c->draw_texture_rect(hue, Rect2(Point2(), c->get_size()));
+ int y = c->get_size().y - c->get_size().y * (1.0 - h);
+ Color col;
+ col.set_hsv(h, 1, 1);
+ c->draw_line(Point2(0, y), Point2(c->get_size().x, y), col.inverted());
+ } else if (picker_type == SHAPE_VHS_CIRCLE) {
+ Vector<Point2> points;
+ Vector<Color> colors;
+ Color col;
+ col.set_hsv(h, s, 1);
+ points.resize(4);
+ colors.resize(4);
+ points.set(0, Vector2());
+ points.set(1, Vector2(c->get_size().x, 0));
+ points.set(2, c->get_size());
+ points.set(3, Vector2(0, c->get_size().y));
+ colors.set(0, col);
+ colors.set(1, col);
+ colors.set(2, Color(0, 0, 0));
+ colors.set(3, Color(0, 0, 0));
+ c->draw_polygon(points, colors);
+ int y = c->get_size().y - c->get_size().y * CLAMP(v, 0, 1);
+ col.set_hsv(h, 1, v);
+ c->draw_line(Point2(0, y), Point2(c->get_size().x, y), col.inverted());
+ }
+ } else if (p_which == 2) {
+ c->draw_rect(Rect2(Point2(), c->get_size()), Color(1, 1, 1));
+ if (picker_type == SHAPE_VHS_CIRCLE) {
+ circle_mat->set_shader_param("v", v);
+ }
}
}
@@ -543,16 +670,51 @@ void ColorPicker::_slider_draw(int p_which) {
scroll[p_which]->draw_polygon(pos, col);
}
-void ColorPicker::_uv_input(const Ref<InputEvent> &p_event) {
+void ColorPicker::_uv_input(const Ref<InputEvent> &p_event, Control *c) {
Ref<InputEventMouseButton> bev = p_event;
if (bev.is_valid()) {
if (bev->is_pressed() && bev->get_button_index() == MOUSE_BUTTON_LEFT) {
+ Vector2 center = c->get_size() / 2.0;
+ if (picker_type == SHAPE_VHS_CIRCLE) {
+ real_t dist = center.distance_to(bev->get_position());
+
+ if (dist <= center.x) {
+ real_t rad = Math::atan2(bev->get_position().y - center.y, bev->get_position().x - center.x);
+ h = ((rad >= 0) ? rad : (Math_TAU + rad)) / Math_TAU;
+ s = CLAMP(dist / center.x, 0, 1);
+ } else {
+ return;
+ }
+ } else {
+ real_t corner_x = (c == wheel_uv) ? center.x - Math_SQRT12 * c->get_size().width * 0.42 : 0;
+ real_t corner_y = (c == wheel_uv) ? center.y - Math_SQRT12 * c->get_size().height * 0.42 : 0;
+ Size2 real_size(c->get_size().x - corner_x * 2, c->get_size().y - corner_y * 2);
+
+ if (bev->get_position().x < corner_x || bev->get_position().x > c->get_size().x - corner_x ||
+ bev->get_position().y < corner_y || bev->get_position().y > c->get_size().y - corner_y) {
+ {
+ real_t dist = center.distance_to(bev->get_position());
+
+ if (dist >= center.x * 0.84 && dist <= center.x) {
+ real_t rad = Math::atan2(bev->get_position().y - center.y, bev->get_position().x - center.x);
+ h = ((rad >= 0) ? rad : (Math_TAU + rad)) / Math_TAU;
+ spinning = true;
+ } else {
+ return;
+ }
+ }
+ }
+
+ if (!spinning) {
+ real_t x = CLAMP(bev->get_position().x, corner_x, c->get_size().x - corner_x);
+ real_t y = CLAMP(bev->get_position().y, corner_x, c->get_size().y - corner_y);
+
+ s = (x - c->get_position().x - corner_x) / real_size.x;
+ v = 1.0 - (y - c->get_position().y - corner_y) / real_size.y;
+ }
+ }
changing_color = true;
- float x = CLAMP((float)bev->get_position().x, 0, uv_edit->get_size().width);
- float y = CLAMP((float)bev->get_position().y, 0, uv_edit->get_size().height);
- s = x / uv_edit->get_size().width;
- v = 1.0 - y / uv_edit->get_size().height;
color.set_hsv(h, s, v, color.a);
last_hsv = color;
set_pick_color(color);
@@ -563,8 +725,10 @@ void ColorPicker::_uv_input(const Ref<InputEvent> &p_event) {
} else if (deferred_mode_enabled && !bev->is_pressed() && bev->get_button_index() == MOUSE_BUTTON_LEFT) {
emit_signal("color_changed", color);
changing_color = false;
+ spinning = false;
} else {
changing_color = false;
+ spinning = false;
}
}
@@ -574,10 +738,30 @@ void ColorPicker::_uv_input(const Ref<InputEvent> &p_event) {
if (!changing_color) {
return;
}
- float x = CLAMP((float)mev->get_position().x, 0, uv_edit->get_size().width);
- float y = CLAMP((float)mev->get_position().y, 0, uv_edit->get_size().height);
- s = x / uv_edit->get_size().width;
- v = 1.0 - y / uv_edit->get_size().height;
+
+ Vector2 center = c->get_size() / 2.0;
+ if (picker_type == SHAPE_VHS_CIRCLE) {
+ real_t dist = center.distance_to(mev->get_position());
+ real_t rad = Math::atan2(mev->get_position().y - center.y, mev->get_position().x - center.x);
+ h = ((rad >= 0) ? rad : (Math_TAU + rad)) / Math_TAU;
+ s = CLAMP(dist / center.x, 0, 1);
+ } else {
+ if (spinning) {
+ real_t rad = Math::atan2(mev->get_position().y - center.y, mev->get_position().x - center.x);
+ h = ((rad >= 0) ? rad : (Math_TAU + rad)) / Math_TAU;
+ } else {
+ real_t corner_x = (c == wheel_uv) ? center.x - Math_SQRT12 * c->get_size().width * 0.42 : 0;
+ real_t corner_y = (c == wheel_uv) ? center.y - Math_SQRT12 * c->get_size().height * 0.42 : 0;
+ Size2 real_size(c->get_size().x - corner_x * 2, c->get_size().y - corner_y * 2);
+
+ real_t x = CLAMP(mev->get_position().x, corner_x, c->get_size().x - corner_x);
+ real_t y = CLAMP(mev->get_position().y, corner_x, c->get_size().y - corner_y);
+
+ s = (x - corner_x) / real_size.x;
+ v = 1.0 - (y - corner_y) / real_size.y;
+ }
+ }
+
color.set_hsv(h, s, v, color.a);
last_hsv = color;
set_pick_color(color);
@@ -595,7 +779,11 @@ void ColorPicker::_w_input(const Ref<InputEvent> &p_event) {
if (bev->is_pressed() && bev->get_button_index() == MOUSE_BUTTON_LEFT) {
changing_color = true;
float y = CLAMP((float)bev->get_position().y, 0, w_edit->get_size().height);
- h = y / w_edit->get_size().height;
+ if (picker_type == SHAPE_VHS_CIRCLE) {
+ v = 1.0 - (y / w_edit->get_size().height);
+ } else {
+ h = y / w_edit->get_size().height;
+ }
} else {
changing_color = false;
}
@@ -617,7 +805,11 @@ void ColorPicker::_w_input(const Ref<InputEvent> &p_event) {
return;
}
float y = CLAMP((float)mev->get_position().y, 0, w_edit->get_size().height);
- h = y / w_edit->get_size().height;
+ if (picker_type == SHAPE_VHS_CIRCLE) {
+ v = 1.0 - (y / w_edit->get_size().height);
+ } else {
+ h = y / w_edit->get_size().height;
+ }
color.set_hsv(h, s, v, color.a);
last_hsv = color;
set_pick_color(color);
@@ -801,18 +993,25 @@ void ColorPicker::_bind_methods() {
ClassDB::bind_method(D_METHOD("add_preset", "color"), &ColorPicker::add_preset);
ClassDB::bind_method(D_METHOD("erase_preset", "color"), &ColorPicker::erase_preset);
ClassDB::bind_method(D_METHOD("get_presets"), &ColorPicker::get_presets);
+ ClassDB::bind_method(D_METHOD("set_picker_shape", "picker"), &ColorPicker::set_picker_shape);
+ ClassDB::bind_method(D_METHOD("get_picker_shape"), &ColorPicker::get_picker_shape);
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, "hsv_mode"), "set_hsv_mode", "is_hsv_mode");
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_PROPERTY(PropertyInfo(Variant::INT, "picker_shape", PROPERTY_HINT_ENUM, "HSV Rectangle,HSV Rectangle Wheel,VHS Circle"), "set_picker_shape", "get_picker_shape");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "presets_enabled"), "set_presets_enabled", "are_presets_enabled");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "presets_visible"), "set_presets_visible", "are_presets_visible");
ADD_SIGNAL(MethodInfo("color_changed", PropertyInfo(Variant::COLOR, "color")));
ADD_SIGNAL(MethodInfo("preset_added", PropertyInfo(Variant::COLOR, "color")));
ADD_SIGNAL(MethodInfo("preset_removed", PropertyInfo(Variant::COLOR, "color")));
+
+ BIND_ENUM_CONSTANT(SHAPE_HSV_RECTANGLE);
+ BIND_ENUM_CONSTANT(SHAPE_HSV_WHEEL);
+ BIND_ENUM_CONSTANT(SHAPE_VHS_CIRCLE);
}
ColorPicker::ColorPicker() :
@@ -821,32 +1020,21 @@ ColorPicker::ColorPicker() :
add_child(hb_edit);
hb_edit->set_v_size_flags(SIZE_EXPAND_FILL);
- uv_edit = memnew(Control);
hb_edit->add_child(uv_edit);
- uv_edit->connect("gui_input", callable_mp(this, &ColorPicker::_uv_input));
+ uv_edit->connect("gui_input", callable_mp(this, &ColorPicker::_uv_input), make_binds(uv_edit));
uv_edit->set_mouse_filter(MOUSE_FILTER_PASS);
uv_edit->set_h_size_flags(SIZE_EXPAND_FILL);
uv_edit->set_v_size_flags(SIZE_EXPAND_FILL);
uv_edit->set_custom_minimum_size(Size2(get_theme_constant("sv_width"), get_theme_constant("sv_height")));
uv_edit->connect("draw", callable_mp(this, &ColorPicker::_hsv_draw), make_binds(0, uv_edit));
- w_edit = memnew(Control);
- hb_edit->add_child(w_edit);
- w_edit->set_custom_minimum_size(Size2(get_theme_constant("h_width"), 0));
- w_edit->set_h_size_flags(SIZE_FILL);
- w_edit->set_v_size_flags(SIZE_EXPAND_FILL);
- w_edit->connect("gui_input", callable_mp(this, &ColorPicker::_w_input));
- w_edit->connect("draw", callable_mp(this, &ColorPicker::_hsv_draw), make_binds(1, w_edit));
-
HBoxContainer *hb_smpl = memnew(HBoxContainer);
add_child(hb_smpl);
- sample = memnew(TextureRect);
hb_smpl->add_child(sample);
sample->set_h_size_flags(SIZE_EXPAND_FILL);
sample->connect("draw", callable_mp(this, &ColorPicker::_sample_draw));
- btn_pick = memnew(Button);
btn_pick->set_flat(true);
hb_smpl->add_child(btn_pick);
btn_pick->set_toggle_mode(true);
@@ -896,17 +1084,14 @@ ColorPicker::ColorPicker() :
HBoxContainer *hhb = memnew(HBoxContainer);
vbr->add_child(hhb);
- btn_hsv = memnew(CheckButton);
hhb->add_child(btn_hsv);
btn_hsv->set_text(RTR("HSV"));
btn_hsv->connect("toggled", callable_mp(this, &ColorPicker::set_hsv_mode));
- btn_raw = memnew(CheckButton);
hhb->add_child(btn_raw);
btn_raw->set_text(RTR("Raw"));
btn_raw->connect("toggled", callable_mp(this, &ColorPicker::set_raw_mode));
- text_type = memnew(Button);
hhb->add_child(text_type);
text_type->set_text("#");
text_type->set_tooltip(TTR("Switch between hexadecimal and code values."));
@@ -920,34 +1105,68 @@ ColorPicker::ColorPicker() :
text_type->set_mouse_filter(MOUSE_FILTER_IGNORE);
}
- c_text = memnew(LineEdit);
hhb->add_child(c_text);
c_text->set_h_size_flags(SIZE_EXPAND_FILL);
c_text->connect("text_entered", callable_mp(this, &ColorPicker::_html_entered));
c_text->connect("focus_entered", callable_mp(this, &ColorPicker::_focus_enter));
c_text->connect("focus_exited", callable_mp(this, &ColorPicker::_html_focus_exit));
+ wheel_edit->set_h_size_flags(SIZE_EXPAND_FILL);
+ wheel_edit->set_v_size_flags(SIZE_EXPAND_FILL);
+ wheel_edit->set_custom_minimum_size(Size2(get_theme_constant("sv_width"), get_theme_constant("sv_height")));
+ hb_edit->add_child(wheel_edit);
+
+ wheel_mat.instance();
+ circle_mat.instance();
+
+ Ref<Shader> wheel_shader(memnew(Shader));
+ wheel_shader->set_code("shader_type canvas_item;const float TAU=6.28318530718;void fragment(){float x=UV.x-0.5;float y=UV.y-0.5;float a=atan(y,x);x+=0.001;y+=0.001;float b=float(sqrt(x*x+y*y)<0.5)*float(sqrt(x*x+y*y)>0.42);x-=0.002;float b2=float(sqrt(x*x+y*y)<0.5)*float(sqrt(x*x+y*y)>0.42);y-=0.002;float b3=float(sqrt(x*x+y*y)<0.5)*float(sqrt(x*x+y*y)>0.42);x+=0.002;float b4=float(sqrt(x*x+y*y)<0.5)*float(sqrt(x*x+y*y)>0.42);COLOR=vec4(clamp((abs(fract(((a-TAU)/TAU)+vec3(3.0,2.0,1.0)/3.0)*6.0-3.0)-1.0),0.0,1.0),(b+b2+b3+b4)/4.00);}");
+ wheel_mat->set_shader(wheel_shader);
+
+ Ref<Shader> circle_shader(memnew(Shader));
+ circle_shader->set_code("shader_type canvas_item;const float TAU=6.28318530718;uniform float v=1.0;void fragment(){float x=UV.x-0.5;float y=UV.y-0.5;float a=atan(y,x);x+=0.001;y+=0.001;float b=float(sqrt(x*x+y*y)<0.5);x-=0.002;float b2=float(sqrt(x*x+y*y)<0.5);y-=0.002;float b3=float(sqrt(x*x+y*y)<0.5);x+=0.002;float b4=float(sqrt(x*x+y*y)<0.5);COLOR=vec4(mix(vec3(1.0),clamp(abs(fract(vec3((a-TAU)/TAU)+vec3(1.0,2.0/3.0,1.0/3.0))*6.0-vec3(3.0))-vec3(1.0),0.0,1.0),((float(sqrt(x*x+y*y))*2.0))/1.0)*vec3(v),(b+b2+b3+b4)/4.00);}");
+ circle_mat->set_shader(circle_shader);
+
+ MarginContainer *wheel_margin(memnew(MarginContainer));
+#ifdef TOOLS_ENABLED
+ wheel_margin->add_theme_constant_override("margin_bottom", 8 * EDSCALE);
+#else
+ wheel_margin->add_theme_constant_override("margin_bottom", 8);
+#endif
+ wheel_edit->add_child(wheel_margin);
+
+ wheel_margin->add_child(wheel);
+ wheel->set_mouse_filter(MOUSE_FILTER_PASS);
+ wheel->connect("draw", callable_mp(this, &ColorPicker::_hsv_draw), make_binds(2, wheel));
+
+ wheel_margin->add_child(wheel_uv);
+ wheel_uv->connect("gui_input", callable_mp(this, &ColorPicker::_uv_input), make_binds(wheel_uv));
+ wheel_uv->connect("draw", callable_mp(this, &ColorPicker::_hsv_draw), make_binds(0, wheel_uv));
+
+ hb_edit->add_child(w_edit);
+ w_edit->set_custom_minimum_size(Size2(get_theme_constant("h_width"), 0));
+ w_edit->set_h_size_flags(SIZE_FILL);
+ w_edit->set_v_size_flags(SIZE_EXPAND_FILL);
+ w_edit->connect("gui_input", callable_mp(this, &ColorPicker::_w_input));
+ w_edit->connect("draw", callable_mp(this, &ColorPicker::_hsv_draw), make_binds(1, w_edit));
+
+ picker_type = SHAPE_HSV_RECTANGLE;
_update_controls();
updating = false;
set_pick_color(Color(1, 1, 1));
- preset_separator = memnew(HSeparator);
add_child(preset_separator);
- preset_container = memnew(HBoxContainer);
preset_container->set_h_size_flags(SIZE_EXPAND_FILL);
add_child(preset_container);
- preset = memnew(TextureRect);
preset_container->add_child(preset);
preset->connect("gui_input", callable_mp(this, &ColorPicker::_preset_input));
preset->connect("draw", callable_mp(this, &ColorPicker::_update_presets));
- preset_container2 = memnew(HBoxContainer);
preset_container2->set_h_size_flags(SIZE_EXPAND_FILL);
add_child(preset_container2);
- bt_add_preset = memnew(Button);
preset_container2->add_child(bt_add_preset);
bt_add_preset->set_tooltip(RTR("Add current color as a preset."));
bt_add_preset->connect("pressed", callable_mp(this, &ColorPicker::_add_preset_pressed));
diff --git a/scene/gui/color_picker.h b/scene/gui/color_picker.h
index 24e1746c41..a0d2aa95ca 100644
--- a/scene/gui/color_picker.h
+++ b/scene/gui/color_picker.h
@@ -31,6 +31,7 @@
#ifndef COLOR_PICKER_H
#define COLOR_PICKER_H
+#include "scene/gui/aspect_ratio_container.h"
#include "scene/gui/box_container.h"
#include "scene/gui/button.h"
#include "scene/gui/check_button.h"
@@ -45,29 +46,44 @@
class ColorPicker : public BoxContainer {
GDCLASS(ColorPicker, BoxContainer);
+public:
+ enum PickerShapeType {
+ SHAPE_HSV_RECTANGLE,
+ SHAPE_HSV_WHEEL,
+ SHAPE_VHS_CIRCLE,
+
+ SHAPE_MAX
+ };
+
private:
Control *screen = nullptr;
- Control *uv_edit;
- Control *w_edit;
- TextureRect *sample;
- TextureRect *preset;
- HBoxContainer *preset_container;
- HBoxContainer *preset_container2;
- HSeparator *preset_separator;
- Button *bt_add_preset;
+ Control *uv_edit = memnew(Control);
+ Control *w_edit = memnew(Control);
+ AspectRatioContainer *wheel_edit = memnew(AspectRatioContainer);
+ Ref<ShaderMaterial> wheel_mat;
+ Ref<ShaderMaterial> circle_mat;
+ Control *wheel = memnew(Control);
+ Control *wheel_uv = memnew(Control);
+ TextureRect *sample = memnew(TextureRect);
+ TextureRect *preset = memnew(TextureRect);
+ HBoxContainer *preset_container = memnew(HBoxContainer);
+ HBoxContainer *preset_container2 = memnew(HBoxContainer);
+ HSeparator *preset_separator = memnew(HSeparator);
+ Button *bt_add_preset = memnew(Button);
List<Color> presets;
- Button *btn_pick;
- CheckButton *btn_hsv;
- CheckButton *btn_raw;
+ Button *btn_pick = memnew(Button);
+ CheckButton *btn_hsv = memnew(CheckButton);
+ CheckButton *btn_raw = memnew(CheckButton);
HSlider *scroll[4];
SpinBox *values[4];
Label *labels[4];
- Button *text_type;
- LineEdit *c_text;
+ Button *text_type = memnew(Button);
+ LineEdit *c_text = memnew(LineEdit);
bool edit_alpha = true;
Size2i ms;
bool text_is_constructor = false;
int presets_per_row = 0;
+ PickerShapeType picker_type = SHAPE_HSV_WHEEL;
Color color;
bool raw_mode_enabled = false;
@@ -75,6 +91,7 @@ private:
bool deferred_mode_enabled = false;
bool updating = true;
bool changing_color = false;
+ bool spinning = false;
bool presets_enabled = true;
bool presets_visible = true;
float h = 0.0;
@@ -93,7 +110,7 @@ private:
void _hsv_draw(int p_which, Control *c);
void _slider_draw(int p_which);
- void _uv_input(const Ref<InputEvent> &p_event);
+ void _uv_input(const Ref<InputEvent> &p_event, Control *c);
void _w_input(const Ref<InputEvent> &p_event);
void _preset_input(const Ref<InputEvent> &p_event);
void _screen_input(const Ref<InputEvent> &p_event);
@@ -115,6 +132,9 @@ public:
void set_pick_color(const Color &p_color);
Color get_pick_color() const;
+ void set_picker_shape(PickerShapeType p_picker_type);
+ PickerShapeType get_picker_shape() const;
+
void add_preset(const Color &p_color);
void erase_preset(const Color &p_color);
PackedColorArray get_presets() const;
@@ -175,4 +195,5 @@ public:
ColorPickerButton();
};
+VARIANT_ENUM_CAST(ColorPicker::PickerShapeType);
#endif // COLOR_PICKER_H
diff --git a/scene/gui/container.cpp b/scene/gui/container.cpp
index 2e6b798eea..dea69aae6b 100644
--- a/scene/gui/container.cpp
+++ b/scene/gui/container.cpp
@@ -159,16 +159,14 @@ void Container::_notification(int p_what) {
}
}
-String Container::get_configuration_warning() const {
- String warning = Control::get_configuration_warning();
+TypedArray<String> Container::get_configuration_warnings() const {
+ TypedArray<String> warnings = Control::get_configuration_warnings();
if (get_class() == "Container" && get_script().is_null()) {
- if (!warning.is_empty()) {
- warning += "\n\n";
- }
- warning += TTR("Container by itself serves no purpose unless a script configures its children placement behavior.\nIf you don't intend to add a script, use a plain Control node instead.");
+ warnings.push_back(TTR("Container by itself serves no purpose unless a script configures its children placement behavior.\nIf you don't intend to add a script, use a plain Control node instead."));
}
- return warning;
+
+ return warnings;
}
void Container::_bind_methods() {
diff --git a/scene/gui/container.h b/scene/gui/container.h
index a4f392a3ae..bce3085f0c 100644
--- a/scene/gui/container.h
+++ b/scene/gui/container.h
@@ -56,7 +56,7 @@ public:
void fit_child_in_rect(Control *p_child, const Rect2 &p_rect);
- virtual String get_configuration_warning() const override;
+ TypedArray<String> get_configuration_warnings() const override;
Container();
};
diff --git a/scene/gui/control.cpp b/scene/gui/control.cpp
index 300201c0db..191f94b2b8 100644
--- a/scene/gui/control.cpp
+++ b/scene/gui/control.cpp
@@ -2183,7 +2183,7 @@ Ref<Theme> Control::get_theme() const {
void Control::set_tooltip(const String &p_tooltip) {
data.tooltip = p_tooltip;
- update_configuration_warning();
+ update_configuration_warnings();
}
String Control::get_tooltip(const Point2 &p_pos) const {
@@ -2468,7 +2468,7 @@ int Control::get_v_size_flags() const {
void Control::set_mouse_filter(MouseFilter p_filter) {
ERR_FAIL_INDEX(p_filter, 3);
data.mouse_filter = p_filter;
- update_configuration_warning();
+ update_configuration_warnings();
}
Control::MouseFilter Control::get_mouse_filter() const {
@@ -2688,15 +2688,15 @@ void Control::get_argument_options(const StringName &p_function, int p_idx, List
if (p_idx == 0) {
List<StringName> sn;
String pf = p_function;
- if (pf == "add_color_override" || pf == "has_color" || pf == "has_color_override" || pf == "get_color") {
+ if (pf == "add_theme_color_override" || pf == "has_theme_color" || pf == "has_theme_color_override" || pf == "get_theme_color") {
Theme::get_default()->get_color_list(get_class(), &sn);
- } else if (pf == "add_style_override" || pf == "has_style" || pf == "has_style_override" || pf == "get_style") {
+ } else if (pf == "add_theme_style_override" || pf == "has_theme_style" || pf == "has_theme_style_override" || pf == "get_theme_style") {
Theme::get_default()->get_stylebox_list(get_class(), &sn);
- } else if (pf == "add_font_override" || pf == "has_font" || pf == "has_font_override" || pf == "get_font") {
+ } else if (pf == "add_theme_font_override" || pf == "has_theme_font" || pf == "has_theme_font_override" || pf == "get_theme_font") {
Theme::get_default()->get_font_list(get_class(), &sn);
- } else if (pf == "add_font_size_override" || pf == "has_font_size" || pf == "has_font_size_override" || pf == "get_font_size") {
+ } else if (pf == "add_theme_font_size_override" || pf == "has_theme_font_size" || pf == "has_theme_font_size_override" || pf == "get_theme_font_size") {
Theme::get_default()->get_font_size_list(get_class(), &sn);
- } else if (pf == "add_constant_override" || pf == "has_constant" || pf == "has_constant_override" || pf == "get_constant") {
+ } else if (pf == "add_theme_constant_override" || pf == "has_theme_constant" || pf == "has_theme_constant_override" || pf == "get_theme_constant") {
Theme::get_default()->get_constant_list(get_class(), &sn);
}
@@ -2707,17 +2707,14 @@ void Control::get_argument_options(const StringName &p_function, int p_idx, List
}
}
-String Control::get_configuration_warning() const {
- String warning = CanvasItem::get_configuration_warning();
+TypedArray<String> Control::get_configuration_warnings() const {
+ TypedArray<String> warnings = Node::get_configuration_warnings();
if (data.mouse_filter == MOUSE_FILTER_IGNORE && data.tooltip != "") {
- if (!warning.is_empty()) {
- warning += "\n\n";
- }
- warning += TTR("The Hint Tooltip won't be displayed as the control's Mouse Filter is set to \"Ignore\". To solve this, set the Mouse Filter to \"Stop\" or \"Pass\".");
+ warnings.push_back(TTR("The Hint Tooltip won't be displayed as the control's Mouse Filter is set to \"Ignore\". To solve this, set the Mouse Filter to \"Stop\" or \"Pass\"."));
}
- return warning;
+ return warnings;
}
void Control::set_clip_contents(bool p_clip) {
diff --git a/scene/gui/control.h b/scene/gui/control.h
index 184b2df6d3..1f397df589 100644
--- a/scene/gui/control.h
+++ b/scene/gui/control.h
@@ -524,7 +524,7 @@ public:
bool is_visibility_clip_disabled() const;
virtual void get_argument_options(const StringName &p_function, int p_idx, List<String> *r_options) const override;
- virtual String get_configuration_warning() const override;
+ TypedArray<String> get_configuration_warnings() const override;
Control() {}
};
diff --git a/scene/gui/gradient_edit.cpp b/scene/gui/gradient_edit.cpp
index e72709e847..ebefb2938f 100644
--- a/scene/gui/gradient_edit.cpp
+++ b/scene/gui/gradient_edit.cpp
@@ -107,7 +107,7 @@ void GradientEdit::_gui_input(const Ref<InputEvent> &p_event) {
Ref<InputEventMouseButton> mb = p_event;
//Show color picker on double click.
- if (mb.is_valid() && mb->get_button_index() == 1 && mb->is_doubleclick() && mb->is_pressed()) {
+ if (mb.is_valid() && mb->get_button_index() == 1 && mb->is_double_click() && mb->is_pressed()) {
grabbed = _get_point_from_pos(mb->get_position().x);
_show_color_picker();
accept_event();
diff --git a/scene/gui/item_list.cpp b/scene/gui/item_list.cpp
index 86d070f9b1..4fddb4b661 100644
--- a/scene/gui/item_list.cpp
+++ b/scene/gui/item_list.cpp
@@ -600,7 +600,7 @@ void ItemList::_gui_input(const Ref<InputEvent> &p_event) {
emit_signal("item_rmb_selected", i, get_local_mouse_position());
}
} else {
- if (!mb->is_doubleclick() && !mb->get_command() && select_mode == SELECT_MULTI && items[i].selectable && !items[i].disabled && items[i].selected && mb->get_button_index() == MOUSE_BUTTON_LEFT) {
+ if (!mb->is_double_click() && !mb->get_command() && select_mode == SELECT_MULTI && items[i].selectable && !items[i].disabled && items[i].selected && mb->get_button_index() == MOUSE_BUTTON_LEFT) {
defer_select_single = i;
return;
}
@@ -622,7 +622,7 @@ void ItemList::_gui_input(const Ref<InputEvent> &p_event) {
if (mb->get_button_index() == MOUSE_BUTTON_RIGHT) {
emit_signal("item_rmb_selected", i, get_local_mouse_position());
- } else if (/*select_mode==SELECT_SINGLE &&*/ mb->is_doubleclick()) {
+ } else if (/*select_mode==SELECT_SINGLE &&*/ mb->is_double_click()) {
emit_signal("item_activated", i);
}
}
diff --git a/scene/gui/line_edit.cpp b/scene/gui/line_edit.cpp
index 2d8eb3191c..eb836b3bf7 100644
--- a/scene/gui/line_edit.cpp
+++ b/scene/gui/line_edit.cpp
@@ -51,13 +51,13 @@ void LineEdit::_swap_current_input_direction() {
} else {
input_direction = TEXT_DIRECTION_LTR;
}
- set_cursor_position(get_cursor_position());
+ set_caret_column(get_caret_column());
update();
}
-void LineEdit::_move_cursor_left(bool p_select, bool p_move_by_word) {
+void LineEdit::_move_caret_left(bool p_select, bool p_move_by_word) {
if (selection.enabled && !p_select) {
- set_cursor_position(selection.begin);
+ set_caret_column(selection.begin);
deselect();
return;
}
@@ -65,7 +65,7 @@ void LineEdit::_move_cursor_left(bool p_select, bool p_move_by_word) {
shift_selection_check_pre(p_select);
if (p_move_by_word) {
- int cc = cursor_pos;
+ int cc = caret_column;
Vector<Vector2i> words = TS->shaped_text_get_word_breaks(text_rid);
for (int i = words.size() - 1; i >= 0; i--) {
@@ -75,21 +75,21 @@ void LineEdit::_move_cursor_left(bool p_select, bool p_move_by_word) {
}
}
- set_cursor_position(cc);
+ set_caret_column(cc);
} else {
- if (mid_grapheme_caret_enabled) {
- set_cursor_position(get_cursor_position() - 1);
+ if (caret_mid_grapheme_enabled) {
+ set_caret_column(get_caret_column() - 1);
} else {
- set_cursor_position(TS->shaped_text_prev_grapheme_pos(text_rid, get_cursor_position()));
+ set_caret_column(TS->shaped_text_prev_grapheme_pos(text_rid, get_caret_column()));
}
}
shift_selection_check_post(p_select);
}
-void LineEdit::_move_cursor_right(bool p_select, bool p_move_by_word) {
+void LineEdit::_move_caret_right(bool p_select, bool p_move_by_word) {
if (selection.enabled && !p_select) {
- set_cursor_position(selection.end);
+ set_caret_column(selection.end);
deselect();
return;
}
@@ -97,7 +97,7 @@ void LineEdit::_move_cursor_right(bool p_select, bool p_move_by_word) {
shift_selection_check_pre(p_select);
if (p_move_by_word) {
- int cc = cursor_pos;
+ int cc = caret_column;
Vector<Vector2i> words = TS->shaped_text_get_word_breaks(text_rid);
for (int i = 0; i < words.size(); i++) {
@@ -107,27 +107,27 @@ void LineEdit::_move_cursor_right(bool p_select, bool p_move_by_word) {
}
}
- set_cursor_position(cc);
+ set_caret_column(cc);
} else {
- if (mid_grapheme_caret_enabled) {
- set_cursor_position(get_cursor_position() + 1);
+ if (caret_mid_grapheme_enabled) {
+ set_caret_column(get_caret_column() + 1);
} else {
- set_cursor_position(TS->shaped_text_next_grapheme_pos(text_rid, get_cursor_position()));
+ set_caret_column(TS->shaped_text_next_grapheme_pos(text_rid, get_caret_column()));
}
}
shift_selection_check_post(p_select);
}
-void LineEdit::_move_cursor_start(bool p_select) {
+void LineEdit::_move_caret_start(bool p_select) {
shift_selection_check_pre(p_select);
- set_cursor_position(0);
+ set_caret_column(0);
shift_selection_check_post(p_select);
}
-void LineEdit::_move_cursor_end(bool p_select) {
+void LineEdit::_move_caret_end(bool p_select) {
shift_selection_check_pre(p_select);
- set_cursor_position(text.length());
+ set_caret_column(text.length());
shift_selection_check_post(p_select);
}
@@ -138,7 +138,7 @@ void LineEdit::_backspace(bool p_word, bool p_all_to_left) {
if (p_all_to_left) {
deselect();
- text = text.substr(0, cursor_pos);
+ text = text.substr(0, caret_column);
_text_changed();
return;
}
@@ -149,18 +149,19 @@ void LineEdit::_backspace(bool p_word, bool p_all_to_left) {
}
if (p_word) {
- int cc = cursor_pos;
+ int cc = caret_column;
Vector<Vector2i> words = TS->shaped_text_get_word_breaks(text_rid);
for (int i = words.size() - 1; i >= 0; i--) {
if (words[i].x < cc) {
cc = words[i].x;
+ break;
}
}
- delete_text(cc, cursor_pos);
+ delete_text(cc, caret_column);
- set_cursor_position(cc);
+ set_caret_column(cc);
} else {
delete_char();
}
@@ -173,9 +174,9 @@ void LineEdit::_delete(bool p_word, bool p_all_to_right) {
if (p_all_to_right) {
deselect();
- text = text.substr(cursor_pos, text.length() - cursor_pos);
+ text = text.substr(caret_column, text.length() - caret_column);
_shape();
- set_cursor_position(0);
+ set_caret_column(0);
_text_changed();
return;
}
@@ -187,12 +188,12 @@ void LineEdit::_delete(bool p_word, bool p_all_to_right) {
int text_len = text.length();
- if (cursor_pos == text_len) {
+ if (caret_column == text_len) {
return; // Nothing to do.
}
if (p_word) {
- int cc = cursor_pos;
+ int cc = caret_column;
Vector<Vector2i> words = TS->shaped_text_get_word_breaks(text_rid);
for (int i = 0; i < words.size(); i++) {
if (words[i].y > cc) {
@@ -201,15 +202,16 @@ void LineEdit::_delete(bool p_word, bool p_all_to_right) {
}
}
- delete_text(cursor_pos, cc);
+ delete_text(caret_column, cc);
+ set_caret_column(caret_column);
} else {
- if (mid_grapheme_caret_enabled) {
- set_cursor_position(cursor_pos + 1);
+ if (caret_mid_grapheme_enabled) {
+ set_caret_column(caret_column + 1);
delete_char();
} else {
- int cc = cursor_pos;
- set_cursor_position(TS->shaped_text_next_grapheme_pos(text_rid, cursor_pos));
- delete_text(cc, cursor_pos);
+ int cc = caret_column;
+ set_caret_column(TS->shaped_text_next_grapheme_pos(text_rid, caret_column));
+ delete_text(cc, caret_column);
}
}
}
@@ -250,33 +252,33 @@ void LineEdit::_gui_input(Ref<InputEvent> p_event) {
shift_selection_check_pre(b->get_shift());
- set_cursor_at_pixel_pos(b->get_position().x);
+ set_caret_at_pixel_pos(b->get_position().x);
if (b->get_shift()) {
- selection_fill_at_cursor();
+ selection_fill_at_caret();
selection.creating = true;
} else {
if (selecting_enabled) {
- if (!b->is_doubleclick() && (OS::get_singleton()->get_ticks_msec() - selection.last_dblclk) < 600) {
+ if (!b->is_double_click() && (OS::get_singleton()->get_ticks_msec() - selection.last_dblclk) < 600) {
// Triple-click select all.
selection.enabled = true;
selection.begin = 0;
selection.end = text.length();
- selection.doubleclick = true;
+ selection.double_click = true;
selection.last_dblclk = 0;
- cursor_pos = selection.begin;
- } else if (b->is_doubleclick()) {
+ caret_column = selection.begin;
+ } else if (b->is_double_click()) {
// Double-click select word.
Vector<Vector2i> words = TS->shaped_text_get_word_breaks(text_rid);
for (int i = 0; i < words.size(); i++) {
- if (words[i].x < cursor_pos && words[i].y > cursor_pos) {
+ if (words[i].x < caret_column && words[i].y > caret_column) {
selection.enabled = true;
selection.begin = words[i].x;
selection.end = words[i].y;
- selection.doubleclick = true;
+ selection.double_click = true;
selection.last_dblclk = OS::get_singleton()->get_ticks_msec();
- cursor_pos = selection.end;
+ caret_column = selection.end;
break;
}
}
@@ -285,9 +287,9 @@ void LineEdit::_gui_input(Ref<InputEvent> p_event) {
selection.drag_attempt = false;
- if ((cursor_pos < selection.begin) || (cursor_pos > selection.end) || !selection.enabled) {
+ if ((caret_column < selection.begin) || (caret_column > selection.end) || !selection.enabled) {
deselect();
- selection.cursor_start = cursor_pos;
+ selection.start_column = caret_column;
selection.creating = true;
} else if (selection.enabled) {
selection.drag_attempt = true;
@@ -306,11 +308,11 @@ void LineEdit::_gui_input(Ref<InputEvent> p_event) {
}
}
- if ((!selection.creating) && (!selection.doubleclick)) {
+ if ((!selection.creating) && (!selection.double_click)) {
deselect();
}
selection.creating = false;
- selection.doubleclick = false;
+ selection.double_click = false;
show_virtual_keyboard();
}
@@ -331,8 +333,8 @@ void LineEdit::_gui_input(Ref<InputEvent> p_event) {
if (m->get_button_mask() & MOUSE_BUTTON_LEFT) {
if (selection.creating) {
- set_cursor_at_pixel_pos(m->get_position().x);
- selection_fill_at_cursor();
+ set_caret_at_pixel_pos(m->get_position().x);
+ selection_fill_at_caret();
}
}
}
@@ -346,7 +348,7 @@ void LineEdit::_gui_input(Ref<InputEvent> p_event) {
if (context_menu_enabled) {
if (k->is_action("ui_menu", true)) {
- Point2 pos = Point2(get_cursor_pixel_pos().x, (get_size().y + get_theme_font("font")->get_height(get_theme_font_size("font_size"))) / 2);
+ Point2 pos = Point2(get_caret_pixel_pos().x, (get_size().y + get_theme_font("font")->get_height(get_theme_font_size("font_size"))) / 2);
menu->set_position(get_global_transform().xform(pos));
menu->set_size(Vector2(1, 1));
_generate_context_menu();
@@ -445,34 +447,34 @@ void LineEdit::_gui_input(Ref<InputEvent> p_event) {
k->set_shift(false);
if (k->is_action("ui_text_caret_word_left", true)) {
- _move_cursor_left(shift_pressed, true);
+ _move_caret_left(shift_pressed, true);
accept_event();
return;
}
if (k->is_action("ui_text_caret_left", true)) {
- _move_cursor_left(shift_pressed);
+ _move_caret_left(shift_pressed);
accept_event();
return;
}
if (k->is_action("ui_text_caret_word_right", true)) {
- _move_cursor_right(shift_pressed, true);
+ _move_caret_right(shift_pressed, true);
accept_event();
return;
}
if (k->is_action("ui_text_caret_right", true)) {
- _move_cursor_right(shift_pressed, false);
+ _move_caret_right(shift_pressed, false);
accept_event();
return;
}
// Up = Home, Down = End
if (k->is_action("ui_text_caret_up", true) || k->is_action("ui_text_caret_line_start", true) || k->is_action("ui_text_caret_page_up", true)) {
- _move_cursor_start(shift_pressed);
+ _move_caret_start(shift_pressed);
accept_event();
return;
}
if (k->is_action("ui_text_caret_down", true) || k->is_action("ui_text_caret_line_end", true) || k->is_action("ui_text_caret_page_down", true)) {
- _move_cursor_end(shift_pressed);
+ _move_caret_end(shift_pressed);
accept_event();
return;
}
@@ -495,7 +497,7 @@ void LineEdit::_gui_input(Ref<InputEvent> p_event) {
selection_delete();
char32_t ucodestr[2] = { (char32_t)k->get_unicode(), 0 };
int prev_len = text.length();
- append_at_cursor(ucodestr);
+ insert_text_at_caret(ucodestr);
if (text.length() != prev_len) {
_text_changed();
}
@@ -542,15 +544,15 @@ void LineEdit::drop_data(const Point2 &p_point, const Variant &p_data) {
Control::drop_data(p_point, p_data);
if (p_data.get_type() == Variant::STRING) {
- set_cursor_at_pixel_pos(p_point.x);
+ set_caret_at_pixel_pos(p_point.x);
int selected = selection.end - selection.begin;
text.erase(selection.begin, selected);
_shape();
- append_at_cursor(p_data);
- selection.begin = cursor_pos - selected;
- selection.end = cursor_pos;
+ insert_text_at_caret(p_data);
+ selection.begin = caret_column - selected;
+ selection.end = caret_column;
}
}
@@ -575,8 +577,8 @@ void LineEdit::_notification(int p_what) {
#ifdef TOOLS_ENABLED
case NOTIFICATION_ENTER_TREE: {
if (Engine::get_singleton()->is_editor_hint() && !get_tree()->is_node_being_edited(this)) {
- cursor_set_blink_enabled(EDITOR_DEF("text_editor/cursor/caret_blink", false));
- cursor_set_blink_speed(EDITOR_DEF("text_editor/cursor/caret_blink_speed", 0.65));
+ set_caret_blink_enabled(EDITOR_DEF("text_editor/cursor/caret_blink", false));
+ set_caret_blink_speed(EDITOR_DEF("text_editor/cursor/caret_blink_speed", 0.65));
if (!EditorSettings::get_singleton()->is_connected("settings_changed", callable_mp(this, &LineEdit::_editor_settings_changed))) {
EditorSettings::get_singleton()->connect("settings_changed", callable_mp(this, &LineEdit::_editor_settings_changed));
@@ -587,7 +589,7 @@ void LineEdit::_notification(int p_what) {
case NOTIFICATION_RESIZED: {
_fit_to_width();
scroll_offset = 0;
- set_cursor_position(get_cursor_position());
+ set_caret_column(get_caret_column());
} break;
case NOTIFICATION_LAYOUT_DIRECTION_CHANGED:
case NOTIFICATION_THEME_CHANGED: {
@@ -674,7 +676,7 @@ void LineEdit::_notification(int p_what) {
Color selection_color = get_theme_color("selection_color");
Color font_color = is_editable() ? get_theme_color("font_color") : get_theme_color("font_uneditable_color");
Color font_selected_color = get_theme_color("font_selected_color");
- Color cursor_color = get_theme_color("cursor_color");
+ Color caret_color = get_theme_color("caret_color");
// Draw placeholder color.
if (using_placeholder) {
@@ -778,7 +780,7 @@ void LineEdit::_notification(int p_what) {
// Normal caret.
Rect2 l_caret, t_caret;
TextServer::Direction l_dir, t_dir;
- TS->shaped_text_get_carets(text_rid, cursor_pos, l_caret, l_dir, t_caret, t_dir);
+ TS->shaped_text_get_carets(text_rid, caret_column, l_caret, l_dir, t_caret, t_dir);
if (l_caret == Rect2() && t_caret == Rect2()) {
// No carets, add one at the start.
@@ -791,28 +793,28 @@ void LineEdit::_notification(int p_what) {
l_dir = TextServer::DIRECTION_LTR;
l_caret = Rect2(Vector2(x_ofs, y), Size2(caret_width, h));
}
- RenderingServer::get_singleton()->canvas_item_add_rect(ci, l_caret, cursor_color);
+ RenderingServer::get_singleton()->canvas_item_add_rect(ci, l_caret, caret_color);
} else {
if (l_caret != Rect2() && l_dir == TextServer::DIRECTION_AUTO) {
// Draw extra marker on top of mid caret.
Rect2 trect = Rect2(l_caret.position.x - 3 * caret_width, l_caret.position.y, 6 * caret_width, caret_width);
trect.position += ofs;
- RenderingServer::get_singleton()->canvas_item_add_rect(ci, trect, cursor_color);
+ RenderingServer::get_singleton()->canvas_item_add_rect(ci, trect, caret_color);
}
l_caret.position += ofs;
l_caret.size.x = caret_width;
- RenderingServer::get_singleton()->canvas_item_add_rect(ci, l_caret, cursor_color);
+ RenderingServer::get_singleton()->canvas_item_add_rect(ci, l_caret, caret_color);
t_caret.position += ofs;
t_caret.size.x = caret_width;
- RenderingServer::get_singleton()->canvas_item_add_rect(ci, t_caret, cursor_color);
+ RenderingServer::get_singleton()->canvas_item_add_rect(ci, t_caret, caret_color);
}
} else {
{
// IME intermediate text range.
- Vector<Vector2> sel = TS->shaped_text_get_selection(text_rid, cursor_pos, cursor_pos + ime_text.length());
+ Vector<Vector2> sel = TS->shaped_text_get_selection(text_rid, caret_column, caret_column + ime_text.length());
for (int i = 0; i < sel.size(); i++) {
Rect2 rect = Rect2(sel[i].x + ofs.x, ofs.y, sel[i].y - sel[i].x, text_height);
if (rect.position.x + rect.size.x <= x_ofs || rect.position.x > ofs_max) {
@@ -825,12 +827,12 @@ void LineEdit::_notification(int p_what) {
rect.size.x = ofs_max - rect.position.x;
}
rect.size.y = caret_width;
- RenderingServer::get_singleton()->canvas_item_add_rect(ci, rect, cursor_color);
+ RenderingServer::get_singleton()->canvas_item_add_rect(ci, rect, caret_color);
}
}
{
// IME caret.
- Vector<Vector2> sel = TS->shaped_text_get_selection(text_rid, cursor_pos + ime_selection.x, cursor_pos + ime_selection.x + ime_selection.y);
+ Vector<Vector2> sel = TS->shaped_text_get_selection(text_rid, caret_column + ime_selection.x, caret_column + ime_selection.x + ime_selection.y);
for (int i = 0; i < sel.size(); i++) {
Rect2 rect = Rect2(sel[i].x + ofs.x, ofs.y, sel[i].y - sel[i].x, text_height);
if (rect.position.x + rect.size.x <= x_ofs || rect.position.x > ofs_max) {
@@ -843,7 +845,7 @@ void LineEdit::_notification(int p_what) {
rect.size.x = ofs_max - rect.position.x;
}
rect.size.y = caret_width * 3;
- RenderingServer::get_singleton()->canvas_item_add_rect(ci, rect, cursor_color);
+ RenderingServer::get_singleton()->canvas_item_add_rect(ci, rect, caret_color);
}
}
}
@@ -869,8 +871,8 @@ void LineEdit::_notification(int p_what) {
if (get_viewport()->get_window_id() != DisplayServer::INVALID_WINDOW_ID && DisplayServer::get_singleton()->has_feature(DisplayServer::FEATURE_IME)) {
DisplayServer::get_singleton()->window_set_ime_active(true, get_viewport()->get_window_id());
- Point2 cursor_pos = Point2(get_cursor_position(), 1) * get_minimum_size().height;
- DisplayServer::get_singleton()->window_set_ime_position(get_global_position() + cursor_pos, get_viewport()->get_window_id());
+ Point2 caret_column = Point2(get_caret_column(), 1) * get_minimum_size().height;
+ DisplayServer::get_singleton()->window_set_ime_position(get_global_position() + caret_column, get_viewport()->get_window_id());
}
show_virtual_keyboard();
@@ -887,7 +889,7 @@ void LineEdit::_notification(int p_what) {
ime_text = "";
ime_selection = Point2();
_shape();
- set_cursor_position(cursor_pos); // Update scroll_offset
+ set_caret_column(caret_column); // Update scroll_offset
if (DisplayServer::get_singleton()->has_feature(DisplayServer::FEATURE_VIRTUAL_KEYBOARD) && virtual_keyboard_enabled) {
DisplayServer::get_singleton()->virtual_keyboard_hide();
@@ -899,7 +901,7 @@ void LineEdit::_notification(int p_what) {
ime_text = DisplayServer::get_singleton()->ime_get_text();
ime_selection = DisplayServer::get_singleton()->ime_get_selection();
_shape();
- set_cursor_position(cursor_pos); // Update scroll_offset
+ set_caret_column(caret_column); // Update scroll_offset
update();
}
@@ -933,7 +935,7 @@ void LineEdit::paste_text() {
if (selection.enabled) {
selection_delete();
}
- append_at_cursor(paste_buffer);
+ insert_text_at_caret(paste_buffer);
if (!text_changed_dirty) {
if (is_inside_tree() && text.length() != prev_len) {
@@ -961,7 +963,7 @@ void LineEdit::undo() {
TextOperation op = undo_stack_pos->get();
text = op.text;
scroll_offset = op.scroll_offset;
- set_cursor_position(op.cursor_pos);
+ set_caret_column(op.caret_column);
_shape();
_emit_text_change();
@@ -982,7 +984,7 @@ void LineEdit::redo() {
TextOperation op = undo_stack_pos->get();
text = op.text;
scroll_offset = op.scroll_offset;
- set_cursor_position(op.cursor_pos);
+ set_caret_column(op.caret_column);
_shape();
_emit_text_change();
@@ -990,7 +992,7 @@ void LineEdit::redo() {
void LineEdit::shift_selection_check_pre(bool p_shift) {
if (!selection.enabled && p_shift) {
- selection.cursor_start = cursor_pos;
+ selection.start_column = caret_column;
}
if (!p_shift) {
deselect();
@@ -999,11 +1001,11 @@ void LineEdit::shift_selection_check_pre(bool p_shift) {
void LineEdit::shift_selection_check_post(bool p_shift) {
if (p_shift) {
- selection_fill_at_cursor();
+ selection_fill_at_caret();
}
}
-void LineEdit::set_cursor_at_pixel_pos(int p_x) {
+void LineEdit::set_caret_at_pixel_pos(int p_x) {
Ref<StyleBox> style = get_theme_stylebox("normal");
bool rtl = is_layout_rtl();
@@ -1048,10 +1050,10 @@ void LineEdit::set_cursor_at_pixel_pos(int p_x) {
}
int ofs = TS->shaped_text_hit_test_position(text_rid, p_x - x_ofs - scroll_offset);
- set_cursor_position(ofs);
+ set_caret_column(ofs);
}
-Vector2i LineEdit::get_cursor_pixel_pos() {
+Vector2i LineEdit::get_caret_pixel_pos() {
Ref<StyleBox> style = get_theme_stylebox("normal");
bool rtl = is_layout_rtl();
@@ -1100,9 +1102,9 @@ Vector2i LineEdit::get_cursor_pixel_pos() {
TextServer::Direction l_dir, t_dir;
// Get position of the start of caret.
if (ime_text.length() != 0 && ime_selection.x != 0) {
- TS->shaped_text_get_carets(text_rid, cursor_pos + ime_selection.x, l_caret, l_dir, t_caret, t_dir);
+ TS->shaped_text_get_carets(text_rid, caret_column + ime_selection.x, l_caret, l_dir, t_caret, t_dir);
} else {
- TS->shaped_text_get_carets(text_rid, cursor_pos, l_caret, l_dir, t_caret, t_dir);
+ TS->shaped_text_get_carets(text_rid, caret_column, l_caret, l_dir, t_caret, t_dir);
}
if ((l_caret != Rect2() && (l_dir == TextServer::DIRECTION_AUTO || l_dir == (TextServer::Direction)input_direction)) || (t_caret == Rect2())) {
@@ -1114,9 +1116,9 @@ Vector2i LineEdit::get_cursor_pixel_pos() {
// Get position of the end of caret.
if (ime_text.length() != 0) {
if (ime_selection.y != 0) {
- TS->shaped_text_get_carets(text_rid, cursor_pos + ime_selection.x + ime_selection.y, l_caret, l_dir, t_caret, t_dir);
+ TS->shaped_text_get_carets(text_rid, caret_column + ime_selection.x + ime_selection.y, l_caret, l_dir, t_caret, t_dir);
} else {
- TS->shaped_text_get_carets(text_rid, cursor_pos + ime_text.size(), l_caret, l_dir, t_caret, t_dir);
+ TS->shaped_text_get_carets(text_rid, caret_column + ime_text.size(), l_caret, l_dir, t_caret, t_dir);
}
if ((l_caret != Rect2() && (l_dir == TextServer::DIRECTION_AUTO || l_dir == (TextServer::Direction)input_direction)) || (t_caret == Rect2())) {
ret.y = x_ofs + l_caret.position.x + scroll_offset;
@@ -1130,19 +1132,19 @@ Vector2i LineEdit::get_cursor_pixel_pos() {
return ret;
}
-void LineEdit::set_mid_grapheme_caret_enabled(const bool p_enabled) {
- mid_grapheme_caret_enabled = p_enabled;
+void LineEdit::set_caret_mid_grapheme_enabled(const bool p_enabled) {
+ caret_mid_grapheme_enabled = p_enabled;
}
-bool LineEdit::get_mid_grapheme_caret_enabled() const {
- return mid_grapheme_caret_enabled;
+bool LineEdit::is_caret_mid_grapheme_enabled() const {
+ return caret_mid_grapheme_enabled;
}
-bool LineEdit::cursor_get_blink_enabled() const {
+bool LineEdit::is_caret_blink_enabled() const {
return caret_blink_enabled;
}
-void LineEdit::cursor_set_blink_enabled(const bool p_enabled) {
+void LineEdit::set_caret_blink_enabled(const bool p_enabled) {
caret_blink_enabled = p_enabled;
if (has_focus() || caret_force_displayed) {
@@ -1160,21 +1162,21 @@ void LineEdit::cursor_set_blink_enabled(const bool p_enabled) {
notify_property_list_changed();
}
-bool LineEdit::cursor_get_force_displayed() const {
+bool LineEdit::is_caret_force_displayed() const {
return caret_force_displayed;
}
-void LineEdit::cursor_set_force_displayed(const bool p_enabled) {
+void LineEdit::set_caret_force_displayed(const bool p_enabled) {
caret_force_displayed = p_enabled;
- cursor_set_blink_enabled(caret_blink_enabled);
+ set_caret_blink_enabled(caret_blink_enabled);
update();
}
-float LineEdit::cursor_get_blink_speed() const {
+float LineEdit::get_caret_blink_speed() const {
return caret_blink_timer->get_wait_time();
}
-void LineEdit::cursor_set_blink_speed(const float p_speed) {
+void LineEdit::set_caret_blink_speed(const float p_speed) {
ERR_FAIL_COND(p_speed <= 0);
caret_blink_timer->set_wait_time(p_speed);
}
@@ -1198,14 +1200,14 @@ void LineEdit::_toggle_draw_caret() {
}
void LineEdit::delete_char() {
- if ((text.length() <= 0) || (cursor_pos == 0)) {
+ if ((text.length() <= 0) || (caret_column == 0)) {
return;
}
- text.erase(cursor_pos - 1, 1);
+ text.erase(caret_column - 1, 1);
_shape();
- set_cursor_position(get_cursor_position() - 1);
+ set_caret_column(get_caret_column() - 1);
_text_changed();
}
@@ -1217,10 +1219,10 @@ void LineEdit::delete_text(int p_from_column, int p_to_column) {
text.erase(p_from_column, p_to_column - p_from_column);
_shape();
- cursor_pos -= CLAMP(cursor_pos - p_from_column, 0, p_to_column - p_from_column);
+ caret_column -= CLAMP(caret_column - p_from_column, 0, p_to_column - p_from_column);
- if (cursor_pos >= text.length()) {
- cursor_pos = text.length();
+ if (caret_column >= text.length()) {
+ caret_column = text.length();
}
if (!text_changed_dirty) {
@@ -1233,10 +1235,11 @@ void LineEdit::delete_text(int p_from_column, int p_to_column) {
void LineEdit::set_text(String p_text) {
clear_internal();
- append_at_cursor(p_text);
+ insert_text_at_caret(p_text);
+ _create_undo_state();
update();
- cursor_pos = 0;
+ caret_column = 0;
scroll_offset = 0;
}
@@ -1346,7 +1349,7 @@ void LineEdit::show_virtual_keyboard() {
if (selection.enabled) {
DisplayServer::get_singleton()->virtual_keyboard_show(text, get_global_rect(), false, max_length, selection.begin, selection.end);
} else {
- DisplayServer::get_singleton()->virtual_keyboard_show(text, get_global_rect(), false, max_length, cursor_pos);
+ DisplayServer::get_singleton()->virtual_keyboard_show(text, get_global_rect(), false, max_length, caret_column);
}
}
}
@@ -1375,16 +1378,16 @@ float LineEdit::get_placeholder_alpha() const {
return placeholder_alpha;
}
-void LineEdit::set_cursor_position(int p_pos) {
- if (p_pos > (int)text.length()) {
- p_pos = text.length();
+void LineEdit::set_caret_column(int p_column) {
+ if (p_column > (int)text.length()) {
+ p_column = text.length();
}
- if (p_pos < 0) {
- p_pos = 0;
+ if (p_column < 0) {
+ p_column = 0;
}
- cursor_pos = p_pos;
+ caret_column = p_column;
// Fit to window.
@@ -1439,7 +1442,7 @@ void LineEdit::set_cursor_position(int p_pos) {
}
// Note: Use two coordinates to fit IME input range.
- Vector2i primary_catret_offset = get_cursor_pixel_pos();
+ Vector2i primary_catret_offset = get_caret_pixel_pos();
if (MIN(primary_catret_offset.x, primary_catret_offset.y) <= x_ofs) {
scroll_offset += (x_ofs - MIN(primary_catret_offset.x, primary_catret_offset.y));
@@ -1451,8 +1454,8 @@ void LineEdit::set_cursor_position(int p_pos) {
update();
}
-int LineEdit::get_cursor_position() const {
- return cursor_pos;
+int LineEdit::get_caret_column() const {
+ return caret_column;
}
void LineEdit::set_scroll_offset(int p_pos) {
@@ -1466,17 +1469,17 @@ int LineEdit::get_scroll_offset() const {
return scroll_offset;
}
-void LineEdit::append_at_cursor(String p_text) {
+void LineEdit::insert_text_at_caret(String p_text) {
if ((max_length <= 0) || (text.length() + p_text.length() <= max_length)) {
- String pre = text.substr(0, cursor_pos);
- String post = text.substr(cursor_pos, text.length() - cursor_pos);
+ String pre = text.substr(0, caret_column);
+ String post = text.substr(caret_column, text.length() - caret_column);
text = pre + p_text + post;
_shape();
- TextServer::Direction dir = TS->shaped_text_get_dominant_direciton_in_range(text_rid, cursor_pos, cursor_pos + p_text.length());
+ TextServer::Direction dir = TS->shaped_text_get_dominant_direciton_in_range(text_rid, caret_column, caret_column + p_text.length());
if (dir != TextServer::DIRECTION_AUTO) {
input_direction = (TextDirection)dir;
}
- set_cursor_position(cursor_pos + p_text.length());
+ set_caret_column(caret_column + p_text.length());
} else {
emit_signal("text_change_rejected");
}
@@ -1485,7 +1488,7 @@ void LineEdit::append_at_cursor(String p_text) {
void LineEdit::clear_internal() {
deselect();
_clear_undo_stack();
- cursor_pos = 0;
+ caret_column = 0;
scroll_offset = 0;
undo_text = "";
text = "";
@@ -1505,7 +1508,7 @@ Size2 LineEdit::get_minimum_size() const {
min_size.width = get_theme_constant("minimum_character_width") * em_space_size;
if (expand_to_text_length) {
- // Add a space because some fonts are too exact, and because cursor needs a bit more when at the end.
+ // Add a space because some fonts are too exact, and because caret needs a bit more when at the end.
min_size.width = MAX(min_size.width, full_width + em_space_size);
}
@@ -1526,10 +1529,10 @@ Size2 LineEdit::get_minimum_size() const {
void LineEdit::deselect() {
selection.begin = 0;
selection.end = 0;
- selection.cursor_start = 0;
+ selection.start_column = 0;
selection.enabled = false;
selection.creating = false;
- selection.doubleclick = false;
+ selection.double_click = false;
update();
}
@@ -1551,13 +1554,13 @@ int LineEdit::get_max_length() const {
return max_length;
}
-void LineEdit::selection_fill_at_cursor() {
+void LineEdit::selection_fill_at_caret() {
if (!selecting_enabled) {
return;
}
- selection.begin = cursor_pos;
- selection.end = selection.cursor_start;
+ selection.begin = caret_column;
+ selection.end = selection.start_column;
if (selection.end < selection.begin) {
int aux = selection.end;
@@ -1656,7 +1659,7 @@ void LineEdit::select(int p_from, int p_to) {
selection.begin = p_from;
selection.end = p_to;
selection.creating = false;
- selection.doubleclick = false;
+ selection.double_click = false;
update();
}
@@ -1714,82 +1717,82 @@ void LineEdit::menu_option(int p_option) {
} break;
case MENU_INSERT_LRM: {
if (editable) {
- append_at_cursor(String::chr(0x200E));
+ insert_text_at_caret(String::chr(0x200E));
}
} break;
case MENU_INSERT_RLM: {
if (editable) {
- append_at_cursor(String::chr(0x200F));
+ insert_text_at_caret(String::chr(0x200F));
}
} break;
case MENU_INSERT_LRE: {
if (editable) {
- append_at_cursor(String::chr(0x202A));
+ insert_text_at_caret(String::chr(0x202A));
}
} break;
case MENU_INSERT_RLE: {
if (editable) {
- append_at_cursor(String::chr(0x202B));
+ insert_text_at_caret(String::chr(0x202B));
}
} break;
case MENU_INSERT_LRO: {
if (editable) {
- append_at_cursor(String::chr(0x202D));
+ insert_text_at_caret(String::chr(0x202D));
}
} break;
case MENU_INSERT_RLO: {
if (editable) {
- append_at_cursor(String::chr(0x202E));
+ insert_text_at_caret(String::chr(0x202E));
}
} break;
case MENU_INSERT_PDF: {
if (editable) {
- append_at_cursor(String::chr(0x202C));
+ insert_text_at_caret(String::chr(0x202C));
}
} break;
case MENU_INSERT_ALM: {
if (editable) {
- append_at_cursor(String::chr(0x061C));
+ insert_text_at_caret(String::chr(0x061C));
}
} break;
case MENU_INSERT_LRI: {
if (editable) {
- append_at_cursor(String::chr(0x2066));
+ insert_text_at_caret(String::chr(0x2066));
}
} break;
case MENU_INSERT_RLI: {
if (editable) {
- append_at_cursor(String::chr(0x2067));
+ insert_text_at_caret(String::chr(0x2067));
}
} break;
case MENU_INSERT_FSI: {
if (editable) {
- append_at_cursor(String::chr(0x2068));
+ insert_text_at_caret(String::chr(0x2068));
}
} break;
case MENU_INSERT_PDI: {
if (editable) {
- append_at_cursor(String::chr(0x2069));
+ insert_text_at_caret(String::chr(0x2069));
}
} break;
case MENU_INSERT_ZWJ: {
if (editable) {
- append_at_cursor(String::chr(0x200D));
+ insert_text_at_caret(String::chr(0x200D));
}
} break;
case MENU_INSERT_ZWNJ: {
if (editable) {
- append_at_cursor(String::chr(0x200C));
+ insert_text_at_caret(String::chr(0x200C));
}
} break;
case MENU_INSERT_WJ: {
if (editable) {
- append_at_cursor(String::chr(0x2060));
+ insert_text_at_caret(String::chr(0x2060));
}
} break;
case MENU_INSERT_SHY: {
if (editable) {
- append_at_cursor(String::chr(0x00AD));
+ insert_text_at_caret(String::chr(0x00AD));
}
}
}
@@ -1809,18 +1812,18 @@ PopupMenu *LineEdit::get_menu() const {
void LineEdit::_editor_settings_changed() {
#ifdef TOOLS_ENABLED
- cursor_set_blink_enabled(EDITOR_DEF("text_editor/cursor/caret_blink", false));
- cursor_set_blink_speed(EDITOR_DEF("text_editor/cursor/caret_blink_speed", 0.65));
+ set_caret_blink_enabled(EDITOR_DEF("text_editor/cursor/caret_blink", false));
+ set_caret_blink_speed(EDITOR_DEF("text_editor/cursor/caret_blink_speed", 0.65));
#endif
}
-void LineEdit::set_expand_to_text_length(bool p_enabled) {
+void LineEdit::set_expand_to_text_length_enabled(bool p_enabled) {
expand_to_text_length = p_enabled;
minimum_size_changed();
- set_cursor_position(cursor_pos);
+ set_caret_column(caret_column);
}
-bool LineEdit::get_expand_to_text_length() const {
+bool LineEdit::is_expand_to_text_length_enabled() const {
return expand_to_text_length;
}
@@ -1905,7 +1908,7 @@ void LineEdit::_shape() {
t = secret_character.repeat(text.length() + ime_text.length());
} else {
if (ime_text.length() > 0) {
- t = text.substr(0, cursor_pos) + ime_text + text.substr(cursor_pos, text.length());
+ t = text.substr(0, caret_column) + ime_text + text.substr(caret_column, text.length());
} else {
t = text;
}
@@ -1970,7 +1973,7 @@ void LineEdit::_clear_undo_stack() {
void LineEdit::_create_undo_state() {
TextOperation op;
op.text = text;
- op.cursor_pos = cursor_pos;
+ op.caret_column = caret_column;
op.scroll_offset = scroll_offset;
undo_stack.push_back(op);
}
@@ -2115,23 +2118,23 @@ void LineEdit::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_placeholder"), &LineEdit::get_placeholder);
ClassDB::bind_method(D_METHOD("set_placeholder_alpha", "alpha"), &LineEdit::set_placeholder_alpha);
ClassDB::bind_method(D_METHOD("get_placeholder_alpha"), &LineEdit::get_placeholder_alpha);
- ClassDB::bind_method(D_METHOD("set_cursor_position", "position"), &LineEdit::set_cursor_position);
- ClassDB::bind_method(D_METHOD("get_cursor_position"), &LineEdit::get_cursor_position);
+ ClassDB::bind_method(D_METHOD("set_caret_column", "position"), &LineEdit::set_caret_column);
+ ClassDB::bind_method(D_METHOD("get_caret_column"), &LineEdit::get_caret_column);
ClassDB::bind_method(D_METHOD("get_scroll_offset"), &LineEdit::get_scroll_offset);
- ClassDB::bind_method(D_METHOD("set_expand_to_text_length", "enabled"), &LineEdit::set_expand_to_text_length);
- ClassDB::bind_method(D_METHOD("get_expand_to_text_length"), &LineEdit::get_expand_to_text_length);
- ClassDB::bind_method(D_METHOD("cursor_set_blink_enabled", "enabled"), &LineEdit::cursor_set_blink_enabled);
- ClassDB::bind_method(D_METHOD("cursor_get_blink_enabled"), &LineEdit::cursor_get_blink_enabled);
- ClassDB::bind_method(D_METHOD("set_mid_grapheme_caret_enabled", "enabled"), &LineEdit::set_mid_grapheme_caret_enabled);
- ClassDB::bind_method(D_METHOD("get_mid_grapheme_caret_enabled"), &LineEdit::get_mid_grapheme_caret_enabled);
- ClassDB::bind_method(D_METHOD("cursor_set_force_displayed", "enabled"), &LineEdit::cursor_set_force_displayed);
- ClassDB::bind_method(D_METHOD("cursor_get_force_displayed"), &LineEdit::cursor_get_force_displayed);
- ClassDB::bind_method(D_METHOD("cursor_set_blink_speed", "blink_speed"), &LineEdit::cursor_set_blink_speed);
- ClassDB::bind_method(D_METHOD("cursor_get_blink_speed"), &LineEdit::cursor_get_blink_speed);
+ ClassDB::bind_method(D_METHOD("set_expand_to_text_length_enabled", "enabled"), &LineEdit::set_expand_to_text_length_enabled);
+ ClassDB::bind_method(D_METHOD("is_expand_to_text_length_enabled"), &LineEdit::is_expand_to_text_length_enabled);
+ ClassDB::bind_method(D_METHOD("set_caret_blink_enabled", "enabled"), &LineEdit::set_caret_blink_enabled);
+ ClassDB::bind_method(D_METHOD("is_caret_blink_enabled"), &LineEdit::is_caret_blink_enabled);
+ ClassDB::bind_method(D_METHOD("set_caret_mid_grapheme_enabled", "enabled"), &LineEdit::set_caret_mid_grapheme_enabled);
+ ClassDB::bind_method(D_METHOD("is_caret_mid_grapheme_enabled"), &LineEdit::is_caret_mid_grapheme_enabled);
+ ClassDB::bind_method(D_METHOD("set_caret_force_displayed", "enabled"), &LineEdit::set_caret_force_displayed);
+ ClassDB::bind_method(D_METHOD("is_caret_force_displayed"), &LineEdit::is_caret_force_displayed);
+ ClassDB::bind_method(D_METHOD("set_caret_blink_speed", "blink_speed"), &LineEdit::set_caret_blink_speed);
+ ClassDB::bind_method(D_METHOD("get_caret_blink_speed"), &LineEdit::get_caret_blink_speed);
ClassDB::bind_method(D_METHOD("set_max_length", "chars"), &LineEdit::set_max_length);
ClassDB::bind_method(D_METHOD("get_max_length"), &LineEdit::get_max_length);
- ClassDB::bind_method(D_METHOD("append_at_cursor", "text"), &LineEdit::append_at_cursor);
- ClassDB::bind_method(D_METHOD("delete_char_at_cursor"), &LineEdit::delete_char);
+ ClassDB::bind_method(D_METHOD("insert_text_at_caret", "text"), &LineEdit::insert_text_at_caret);
+ ClassDB::bind_method(D_METHOD("delete_char_at_caret"), &LineEdit::delete_char);
ClassDB::bind_method(D_METHOD("delete_text", "from_column", "to_column"), &LineEdit::delete_text);
ClassDB::bind_method(D_METHOD("set_editable", "enabled"), &LineEdit::set_editable);
ClassDB::bind_method(D_METHOD("is_editable"), &LineEdit::is_editable);
@@ -2199,7 +2202,7 @@ void LineEdit::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "editable"), "set_editable", "is_editable");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "secret"), "set_secret", "is_secret");
ADD_PROPERTY(PropertyInfo(Variant::STRING, "secret_character"), "set_secret_character", "get_secret_character");
- ADD_PROPERTY(PropertyInfo(Variant::BOOL, "expand_to_text_length"), "set_expand_to_text_length", "get_expand_to_text_length");
+ ADD_PROPERTY(PropertyInfo(Variant::BOOL, "expand_to_text_length"), "set_expand_to_text_length_enabled", "is_expand_to_text_length_enabled");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "context_menu_enabled"), "set_context_menu_enabled", "is_context_menu_enabled");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "virtual_keyboard_enabled"), "set_virtual_keyboard_enabled", "is_virtual_keyboard_enabled");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "clear_button_enabled"), "set_clear_button_enabled", "is_clear_button_enabled");
@@ -2216,11 +2219,11 @@ void LineEdit::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::STRING, "placeholder_text"), "set_placeholder", "get_placeholder");
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "placeholder_alpha", PROPERTY_HINT_RANGE, "0,1,0.001"), "set_placeholder_alpha", "get_placeholder_alpha");
ADD_GROUP("Caret", "caret_");
- ADD_PROPERTY(PropertyInfo(Variant::BOOL, "caret_blink"), "cursor_set_blink_enabled", "cursor_get_blink_enabled");
- ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "caret_blink_speed", PROPERTY_HINT_RANGE, "0.1,10,0.01"), "cursor_set_blink_speed", "cursor_get_blink_speed");
- ADD_PROPERTY(PropertyInfo(Variant::INT, "caret_position"), "set_cursor_position", "get_cursor_position");
- ADD_PROPERTY(PropertyInfo(Variant::BOOL, "caret_force_displayed"), "cursor_set_force_displayed", "cursor_get_force_displayed");
- ADD_PROPERTY(PropertyInfo(Variant::BOOL, "caret_mid_grapheme"), "set_mid_grapheme_caret_enabled", "get_mid_grapheme_caret_enabled");
+ ADD_PROPERTY(PropertyInfo(Variant::BOOL, "caret_blink"), "set_caret_blink_enabled", "is_caret_blink_enabled");
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "caret_blink_speed", PROPERTY_HINT_RANGE, "0.1,10,0.01"), "set_caret_blink_speed", "get_caret_blink_speed");
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "caret_column"), "set_caret_column", "get_caret_column");
+ ADD_PROPERTY(PropertyInfo(Variant::BOOL, "caret_force_displayed"), "set_caret_force_displayed", "is_caret_force_displayed");
+ ADD_PROPERTY(PropertyInfo(Variant::BOOL, "caret_mid_grapheme"), "set_caret_mid_grapheme_enabled", "is_caret_mid_grapheme_enabled");
}
LineEdit::LineEdit() {
@@ -2236,7 +2239,7 @@ LineEdit::LineEdit() {
add_child(caret_blink_timer);
caret_blink_timer->set_wait_time(0.65);
caret_blink_timer->connect("timeout", callable_mp(this, &LineEdit::_toggle_draw_caret));
- cursor_set_blink_enabled(false);
+ set_caret_blink_enabled(false);
menu = memnew(PopupMenu);
add_child(menu);
diff --git a/scene/gui/line_edit.h b/scene/gui/line_edit.h
index ef36377f2e..12fec2f98b 100644
--- a/scene/gui/line_edit.h
+++ b/scene/gui/line_edit.h
@@ -103,9 +103,9 @@ private:
PopupMenu *menu_dir = nullptr;
PopupMenu *menu_ctl = nullptr;
- bool mid_grapheme_caret_enabled = false;
+ bool caret_mid_grapheme_enabled = false;
- int cursor_pos = 0;
+ int caret_column = 0;
int scroll_offset = 0;
int max_length = 0; // 0 for no maximum.
@@ -131,16 +131,16 @@ private:
struct Selection {
int begin = 0;
int end = 0;
- int cursor_start = 0;
+ int start_column = 0;
bool enabled = false;
bool creating = false;
- bool doubleclick = false;
+ bool double_click = false;
bool drag_attempt = false;
uint64_t last_dblclk = 0;
} selection;
struct TextOperation {
- int cursor_pos = 0;
+ int caret_column = 0;
int scroll_offset = 0;
int cached_width = 0;
String text;
@@ -175,12 +175,12 @@ private:
void shift_selection_check_pre(bool);
void shift_selection_check_post(bool);
- void selection_fill_at_cursor();
+ void selection_fill_at_caret();
void set_scroll_offset(int p_pos);
int get_scroll_offset() const;
- void set_cursor_at_pixel_pos(int p_x);
- Vector2i get_cursor_pixel_pos();
+ void set_caret_at_pixel_pos(int p_x);
+ Vector2i get_caret_pixel_pos();
void _reset_caret_blink_timer();
void _toggle_draw_caret();
@@ -191,10 +191,10 @@ private:
void _editor_settings_changed();
void _swap_current_input_direction();
- void _move_cursor_left(bool p_select, bool p_move_by_word = false);
- void _move_cursor_right(bool p_select, bool p_move_by_word = false);
- void _move_cursor_start(bool p_select);
- void _move_cursor_end(bool p_select);
+ void _move_caret_left(bool p_select, bool p_move_by_word = false);
+ void _move_caret_right(bool p_select, bool p_move_by_word = false);
+ void _move_caret_start(bool p_select);
+ void _move_caret_end(bool p_select);
void _backspace(bool p_word = false, bool p_all_to_left = false);
void _delete(bool p_word = false, bool p_all_to_right = false);
@@ -259,26 +259,26 @@ public:
void set_placeholder_alpha(float p_alpha);
float get_placeholder_alpha() const;
- void set_cursor_position(int p_pos);
- int get_cursor_position() const;
+ void set_caret_column(int p_column);
+ int get_caret_column() const;
void set_max_length(int p_max_length);
int get_max_length() const;
- void append_at_cursor(String p_text);
+ void insert_text_at_caret(String p_text);
void clear();
- void set_mid_grapheme_caret_enabled(const bool p_enabled);
- bool get_mid_grapheme_caret_enabled() const;
+ void set_caret_mid_grapheme_enabled(const bool p_enabled);
+ bool is_caret_mid_grapheme_enabled() const;
- bool cursor_get_blink_enabled() const;
- void cursor_set_blink_enabled(const bool p_enabled);
+ bool is_caret_blink_enabled() const;
+ void set_caret_blink_enabled(const bool p_enabled);
- float cursor_get_blink_speed() const;
- void cursor_set_blink_speed(const float p_speed);
+ float get_caret_blink_speed() const;
+ void set_caret_blink_speed(const float p_speed);
- bool cursor_get_force_displayed() const;
- void cursor_set_force_displayed(const bool p_enabled);
+ void set_caret_force_displayed(const bool p_enabled);
+ bool is_caret_force_displayed() const;
void copy_text();
void cut_text();
@@ -297,8 +297,8 @@ public:
virtual Size2 get_minimum_size() const override;
- void set_expand_to_text_length(bool p_enabled);
- bool get_expand_to_text_length() const;
+ void set_expand_to_text_length_enabled(bool p_enabled);
+ bool is_expand_to_text_length_enabled() const;
void set_clear_button_enabled(bool p_enabled);
bool is_clear_button_enabled() const;
diff --git a/scene/gui/range.cpp b/scene/gui/range.cpp
index 86b775e795..adc1ed67ca 100644
--- a/scene/gui/range.cpp
+++ b/scene/gui/range.cpp
@@ -30,17 +30,14 @@
#include "range.h"
-String Range::get_configuration_warning() const {
- String warning = Control::get_configuration_warning();
+TypedArray<String> Range::get_configuration_warnings() const {
+ TypedArray<String> warnings = Node::get_configuration_warnings();
if (shared->exp_ratio && shared->min <= 0) {
- if (!warning.is_empty()) {
- warning += "\n\n";
- }
- warning += TTR("If \"Exp Edit\" is enabled, \"Min Value\" must be greater than 0.");
+ warnings.push_back(TTR("If \"Exp Edit\" is enabled, \"Min Value\" must be greater than 0."));
}
- return warning;
+ return warnings;
}
void Range::_value_changed_notify() {
@@ -106,7 +103,7 @@ void Range::set_min(double p_min) {
shared->emit_changed("min");
- update_configuration_warning();
+ update_configuration_warnings();
}
void Range::set_max(double p_max) {
@@ -181,7 +178,6 @@ double Range::get_as_ratio() const {
double v = Math::log(value) / Math::log((double)2);
return CLAMP((v - exp_min) / (exp_max - exp_min), 0, 1);
-
} else {
float value = CLAMP(get_value(), shared->min, shared->max);
return CLAMP((value - get_min()) / (get_max() - get_min()), 0, 1);
@@ -287,7 +283,7 @@ bool Range::is_using_rounded_values() const {
void Range::set_exp_ratio(bool p_enable) {
shared->exp_ratio = p_enable;
- update_configuration_warning();
+ update_configuration_warnings();
}
bool Range::is_ratio_exp() const {
diff --git a/scene/gui/range.h b/scene/gui/range.h
index 1072a109c6..7a129e88d6 100644
--- a/scene/gui/range.h
+++ b/scene/gui/range.h
@@ -97,7 +97,7 @@ public:
void share(Range *p_range);
void unshare();
- virtual String get_configuration_warning() const override;
+ TypedArray<String> get_configuration_warnings() const override;
Range();
~Range();
diff --git a/scene/gui/rich_text_label.cpp b/scene/gui/rich_text_label.cpp
index c763ae6bd6..e8a908c30e 100644
--- a/scene/gui/rich_text_label.cpp
+++ b/scene/gui/rich_text_label.cpp
@@ -1482,7 +1482,7 @@ void RichTextLabel::_gui_input(Ref<InputEvent> p_event) {
}
if (b->get_button_index() == MOUSE_BUTTON_LEFT) {
- if (b->is_pressed() && !b->is_doubleclick()) {
+ if (b->is_pressed() && !b->is_double_click()) {
scroll_updated = false;
ItemFrame *c_frame = nullptr;
int c_line = 0;
@@ -1514,8 +1514,8 @@ void RichTextLabel::_gui_input(Ref<InputEvent> p_event) {
}
}
}
- } else if (b->is_pressed() && b->is_doubleclick() && selection.enabled) {
- //doubleclick: select word
+ } else if (b->is_pressed() && b->is_double_click() && selection.enabled) {
+ //double_click: select word
ItemFrame *c_frame = nullptr;
int c_line = 0;
@@ -1549,7 +1549,7 @@ void RichTextLabel::_gui_input(Ref<InputEvent> p_event) {
} else if (!b->is_pressed()) {
selection.click_item = nullptr;
- if (!b->is_doubleclick() && !scroll_updated) {
+ if (!b->is_double_click() && !scroll_updated) {
Item *c_item = nullptr;
bool outside = true;
@@ -2612,6 +2612,14 @@ void RichTextLabel::pop() {
current = current->parent;
}
+// Creates a new line without adding an ItemNewline to the previous line.
+// Useful when wanting to calling remove_line and add a new line immediately after.
+void RichTextLabel::increment_line_count() {
+ _validate_line_caches(main);
+ current_frame->lines.resize(current_frame->lines.size() + 1);
+ _invalidate_current_line(current_frame);
+}
+
void RichTextLabel::clear() {
main->_clear_children();
current = main;
diff --git a/scene/gui/rich_text_label.h b/scene/gui/rich_text_label.h
index e3e457d1f2..afc88e070a 100644
--- a/scene/gui/rich_text_label.h
+++ b/scene/gui/rich_text_label.h
@@ -483,6 +483,8 @@ public:
void push_cell();
void pop();
+ void increment_line_count();
+
void clear();
void set_offset(int p_pixel);
diff --git a/scene/gui/scroll_container.cpp b/scene/gui/scroll_container.cpp
index 757a0841ea..67dcf458b0 100644
--- a/scene/gui/scroll_container.cpp
+++ b/scene/gui/scroll_container.cpp
@@ -299,7 +299,7 @@ void ScrollContainer::_update_dimensions() {
child_max_size.x = MAX(child_max_size.x, minsize.x);
child_max_size.y = MAX(child_max_size.y, minsize.y);
- Rect2 r = Rect2(-scroll, minsize);
+ Rect2 r = Rect2(-Size2(get_h_scroll(), get_v_scroll()), minsize);
if (!scroll_h || (!h_scroll->is_visible_in_tree() && c->get_h_size_flags() & SIZE_EXPAND)) {
r.position.x = 0;
if (c->get_h_size_flags() & SIZE_EXPAND) {
@@ -434,40 +434,16 @@ void ScrollContainer::update_scrollbars() {
Size2 min = child_max_size;
- bool hide_scroll_v = !scroll_v || min.height <= size.height;
- bool hide_scroll_h = !scroll_h || min.width <= size.width;
-
- v_scroll->set_max(min.height);
- if (hide_scroll_v) {
- v_scroll->set_page(size.height);
- v_scroll->hide();
- scroll.y = 0;
- } else {
- v_scroll->show();
- if (hide_scroll_h) {
- v_scroll->set_page(size.height);
- } else {
- v_scroll->set_page(size.height - hmin.height);
- }
-
- scroll.y = v_scroll->get_value();
- }
+ bool hide_scroll_h = !scroll_h || min.width <= size.width || !h_scroll_visible;
+ bool hide_scroll_v = !scroll_v || min.height <= size.height || !v_scroll_visible;
h_scroll->set_max(min.width);
- if (hide_scroll_h) {
- h_scroll->set_page(size.width);
- h_scroll->hide();
- scroll.x = 0;
- } else {
- h_scroll->show();
- if (hide_scroll_v) {
- h_scroll->set_page(size.width);
- } else {
- h_scroll->set_page(size.width - vmin.width);
- }
+ h_scroll->set_page(size.width - (hide_scroll_v ? 0 : vmin.width));
+ h_scroll->set_visible(!hide_scroll_h);
- scroll.x = h_scroll->get_value();
- }
+ v_scroll->set_max(min.height);
+ v_scroll->set_page(size.height - (hide_scroll_h ? 0 : hmin.height));
+ v_scroll->set_visible(!hide_scroll_v);
// Avoid scrollbar overlapping.
h_scroll->set_anchor_and_offset(SIDE_RIGHT, ANCHOR_END, hide_scroll_v ? 0 : -vmin.width);
@@ -475,13 +451,28 @@ void ScrollContainer::update_scrollbars() {
}
void ScrollContainer::_scroll_moved(float) {
- scroll.x = h_scroll->get_value();
- scroll.y = v_scroll->get_value();
queue_sort();
-
update();
};
+void ScrollContainer::set_h_scroll(int p_pos) {
+ h_scroll->set_value(p_pos);
+ _cancel_drag();
+}
+
+int ScrollContainer::get_h_scroll() const {
+ return h_scroll->get_value();
+}
+
+void ScrollContainer::set_v_scroll(int p_pos) {
+ v_scroll->set_value(p_pos);
+ _cancel_drag();
+}
+
+int ScrollContainer::get_v_scroll() const {
+ return v_scroll->get_value();
+}
+
void ScrollContainer::set_enable_h_scroll(bool p_enable) {
if (scroll_h == p_enable) {
return;
@@ -510,22 +501,30 @@ bool ScrollContainer::is_v_scroll_enabled() const {
return scroll_v;
}
-int ScrollContainer::get_v_scroll() const {
- return v_scroll->get_value();
+void ScrollContainer::set_h_scroll_visible(bool p_visible) {
+ if (h_scroll_visible == p_visible) {
+ return;
+ }
+
+ h_scroll_visible = p_visible;
+ update_scrollbars();
}
-void ScrollContainer::set_v_scroll(int p_pos) {
- v_scroll->set_value(p_pos);
- _cancel_drag();
+bool ScrollContainer::is_h_scroll_visible() const {
+ return h_scroll_visible;
}
-int ScrollContainer::get_h_scroll() const {
- return h_scroll->get_value();
+void ScrollContainer::set_v_scroll_visible(bool p_visible) {
+ if (v_scroll_visible == p_visible) {
+ return;
+ }
+
+ v_scroll_visible = p_visible;
+ update_scrollbars();
}
-void ScrollContainer::set_h_scroll(int p_pos) {
- h_scroll->set_value(p_pos);
- _cancel_drag();
+bool ScrollContainer::is_v_scroll_visible() const {
+ return v_scroll_visible;
}
int ScrollContainer::get_deadzone() const {
@@ -544,8 +543,8 @@ void ScrollContainer::set_follow_focus(bool p_follow) {
follow_focus = p_follow;
}
-String ScrollContainer::get_configuration_warning() const {
- String warning = Container::get_configuration_warning();
+TypedArray<String> ScrollContainer::get_configuration_warnings() const {
+ TypedArray<String> warnings = Container::get_configuration_warnings();
int found = 0;
@@ -565,12 +564,10 @@ String ScrollContainer::get_configuration_warning() const {
}
if (found != 1) {
- if (!warning.is_empty()) {
- warning += "\n\n";
- }
- warning += TTR("ScrollContainer is intended to work with a single child control.\nUse a container as child (VBox, HBox, etc.), or a Control and set the custom minimum size manually.");
+ warnings.push_back(TTR("ScrollContainer is intended to work with a single child control.\nUse a container as child (VBox, HBox, etc.), or a Control and set the custom minimum size manually."));
}
- return warning;
+
+ return warnings;
}
HScrollBar *ScrollContainer::get_h_scrollbar() {
@@ -583,17 +580,29 @@ VScrollBar *ScrollContainer::get_v_scrollbar() {
void ScrollContainer::_bind_methods() {
ClassDB::bind_method(D_METHOD("_gui_input"), &ScrollContainer::_gui_input);
- ClassDB::bind_method(D_METHOD("set_enable_h_scroll", "enable"), &ScrollContainer::set_enable_h_scroll);
- ClassDB::bind_method(D_METHOD("is_h_scroll_enabled"), &ScrollContainer::is_h_scroll_enabled);
- ClassDB::bind_method(D_METHOD("set_enable_v_scroll", "enable"), &ScrollContainer::set_enable_v_scroll);
- ClassDB::bind_method(D_METHOD("is_v_scroll_enabled"), &ScrollContainer::is_v_scroll_enabled);
ClassDB::bind_method(D_METHOD("_update_scrollbar_position"), &ScrollContainer::_update_scrollbar_position);
+
ClassDB::bind_method(D_METHOD("set_h_scroll", "value"), &ScrollContainer::set_h_scroll);
ClassDB::bind_method(D_METHOD("get_h_scroll"), &ScrollContainer::get_h_scroll);
+
ClassDB::bind_method(D_METHOD("set_v_scroll", "value"), &ScrollContainer::set_v_scroll);
ClassDB::bind_method(D_METHOD("get_v_scroll"), &ScrollContainer::get_v_scroll);
+
+ ClassDB::bind_method(D_METHOD("set_enable_h_scroll", "enable"), &ScrollContainer::set_enable_h_scroll);
+ ClassDB::bind_method(D_METHOD("is_h_scroll_enabled"), &ScrollContainer::is_h_scroll_enabled);
+
+ ClassDB::bind_method(D_METHOD("set_enable_v_scroll", "enable"), &ScrollContainer::set_enable_v_scroll);
+ ClassDB::bind_method(D_METHOD("is_v_scroll_enabled"), &ScrollContainer::is_v_scroll_enabled);
+
+ ClassDB::bind_method(D_METHOD("set_h_scroll_visible", "visible"), &ScrollContainer::set_h_scroll_visible);
+ ClassDB::bind_method(D_METHOD("is_h_scroll_visible"), &ScrollContainer::is_h_scroll_visible);
+
+ ClassDB::bind_method(D_METHOD("set_v_scroll_visible", "visible"), &ScrollContainer::set_v_scroll_visible);
+ ClassDB::bind_method(D_METHOD("is_v_scroll_visible"), &ScrollContainer::is_v_scroll_visible);
+
ClassDB::bind_method(D_METHOD("set_deadzone", "deadzone"), &ScrollContainer::set_deadzone);
ClassDB::bind_method(D_METHOD("get_deadzone"), &ScrollContainer::get_deadzone);
+
ClassDB::bind_method(D_METHOD("set_follow_focus", "enabled"), &ScrollContainer::set_follow_focus);
ClassDB::bind_method(D_METHOD("is_following_focus"), &ScrollContainer::is_following_focus);
@@ -606,10 +615,12 @@ void ScrollContainer::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "follow_focus"), "set_follow_focus", "is_following_focus");
ADD_GROUP("Scroll", "scroll_");
- ADD_PROPERTY(PropertyInfo(Variant::BOOL, "scroll_horizontal_enabled"), "set_enable_h_scroll", "is_h_scroll_enabled");
ADD_PROPERTY(PropertyInfo(Variant::INT, "scroll_horizontal"), "set_h_scroll", "get_h_scroll");
- ADD_PROPERTY(PropertyInfo(Variant::BOOL, "scroll_vertical_enabled"), "set_enable_v_scroll", "is_v_scroll_enabled");
ADD_PROPERTY(PropertyInfo(Variant::INT, "scroll_vertical"), "set_v_scroll", "get_v_scroll");
+ ADD_PROPERTY(PropertyInfo(Variant::BOOL, "scroll_horizontal_enabled"), "set_enable_h_scroll", "is_h_scroll_enabled");
+ ADD_PROPERTY(PropertyInfo(Variant::BOOL, "scroll_vertical_enabled"), "set_enable_v_scroll", "is_v_scroll_enabled");
+ ADD_PROPERTY(PropertyInfo(Variant::BOOL, "scroll_horizontal_visible"), "set_h_scroll_visible", "is_h_scroll_visible");
+ ADD_PROPERTY(PropertyInfo(Variant::BOOL, "scroll_vertical_visible"), "set_v_scroll_visible", "is_v_scroll_visible");
ADD_PROPERTY(PropertyInfo(Variant::INT, "scroll_deadzone"), "set_deadzone", "get_deadzone");
GLOBAL_DEF("gui/common/default_scroll_deadzone", 0);
diff --git a/scene/gui/scroll_container.h b/scene/gui/scroll_container.h
index 9d3ce39345..f61df70b85 100644
--- a/scene/gui/scroll_container.h
+++ b/scene/gui/scroll_container.h
@@ -42,7 +42,6 @@ class ScrollContainer : public Container {
VScrollBar *v_scroll;
Size2 child_max_size;
- Size2 scroll;
void update_scrollbars();
@@ -50,16 +49,17 @@ class ScrollContainer : public Container {
Vector2 drag_accum;
Vector2 drag_from;
Vector2 last_drag_accum;
- float last_drag_time = 0.0;
- float time_since_motion = 0.0;
+ float time_since_motion = 0.0f;
bool drag_touching = false;
bool drag_touching_deaccel = false;
- bool click_handled = false;
bool beyond_deadzone = false;
bool scroll_h = true;
bool scroll_v = true;
+ bool h_scroll_visible = true;
+ bool v_scroll_visible = true;
+
int deadzone = 0;
bool follow_focus = false;
@@ -80,11 +80,11 @@ protected:
void _ensure_focused_visible(Control *p_node);
public:
- int get_v_scroll() const;
- void set_v_scroll(int p_pos);
-
- int get_h_scroll() const;
void set_h_scroll(int p_pos);
+ int get_h_scroll() const;
+
+ void set_v_scroll(int p_pos);
+ int get_v_scroll() const;
void set_enable_h_scroll(bool p_enable);
bool is_h_scroll_enabled() const;
@@ -92,6 +92,12 @@ public:
void set_enable_v_scroll(bool p_enable);
bool is_v_scroll_enabled() const;
+ void set_h_scroll_visible(bool p_visible);
+ bool is_h_scroll_visible() const;
+
+ void set_v_scroll_visible(bool p_visible);
+ bool is_v_scroll_visible() const;
+
int get_deadzone() const;
void set_deadzone(int p_deadzone);
@@ -103,7 +109,7 @@ public:
virtual bool clips_input() const override;
- virtual String get_configuration_warning() const override;
+ TypedArray<String> get_configuration_warnings() const override;
ScrollContainer();
};
diff --git a/scene/gui/text_edit.cpp b/scene/gui/text_edit.cpp
index f54ab004c6..ded912591f 100644
--- a/scene/gui/text_edit.cpp
+++ b/scene/gui/text_edit.cpp
@@ -1973,7 +1973,7 @@ void TextEdit::backspace_at_cursor() {
}
}
- cursor_set_line(prev_line, true, true);
+ cursor_set_line(prev_line, false, true);
cursor_set_column(prev_column);
}
@@ -2054,6 +2054,7 @@ void TextEdit::indent_selected_lines_left() {
if (is_selection_active() && get_selection_to_column() == 0) {
end_line--;
}
+ String first_line_text = get_line(start_line);
String last_line_text = get_line(end_line);
for (int i = start_line; i <= end_line; i++) {
@@ -2078,10 +2079,17 @@ void TextEdit::indent_selected_lines_left() {
}
}
- // Fix selection and cursor being off by one on the last line.
- if (is_selection_active() && last_line_text != get_line(end_line)) {
- select(selection.from_line, selection.from_column - removed_characters,
- selection.to_line, initial_selection_end_column - removed_characters);
+ if (is_selection_active()) {
+ // Fix selection being off by one on the first line.
+ if (first_line_text != get_line(start_line)) {
+ select(selection.from_line, selection.from_column - removed_characters,
+ selection.to_line, initial_selection_end_column);
+ }
+ // Fix selection being off by one on the last line.
+ if (last_line_text != get_line(end_line)) {
+ select(selection.from_line, selection.from_column,
+ selection.to_line, initial_selection_end_column - removed_characters);
+ }
}
cursor_set_column(initial_cursor_column - removed_characters, false);
end_complex_operation();
@@ -2207,7 +2215,7 @@ void TextEdit::_new_line(bool p_split_current_line, bool p_above) {
if (!p_split_current_line) {
if (p_above) {
if (cursor.line > 0) {
- cursor_set_line(cursor.line - 1);
+ cursor_set_line(cursor.line - 1, false);
cursor_set_column(text[cursor.line].length());
} else {
cursor_set_column(0);
@@ -2223,7 +2231,7 @@ void TextEdit::_new_line(bool p_split_current_line, bool p_above) {
if (first_line) {
cursor_set_line(0);
} else if (brace_indent) {
- cursor_set_line(cursor.line - 1);
+ cursor_set_line(cursor.line - 1, false);
cursor_set_column(text[cursor.line].length());
}
end_complex_operation();
@@ -2573,7 +2581,7 @@ void TextEdit::_backspace(bool p_word, bool p_all_to_left) {
_remove_text(line, column, cursor.line, cursor.column);
- cursor_set_line(line);
+ cursor_set_line(line, false);
cursor_set_column(column);
} else {
// One character.
@@ -2640,7 +2648,7 @@ void TextEdit::_delete_selection() {
selection.active = false;
update();
_remove_text(selection.from_line, selection.from_column, selection.to_line, selection.to_column);
- cursor_set_line(selection.from_line, true, false);
+ cursor_set_line(selection.from_line, false, false);
cursor_set_column(selection.from_column);
update();
}
@@ -2895,7 +2903,7 @@ void TextEdit::_gui_input(const Ref<InputEvent> &p_gui_input) {
completion_current = completion_options[completion_index];
update();
- if (mb->is_doubleclick()) {
+ if (mb->is_double_click()) {
_confirm_completion();
}
}
@@ -3018,12 +3026,12 @@ void TextEdit::_gui_input(const Ref<InputEvent> &p_gui_input) {
selection.selecting_column = col;
}
- if (!mb->is_doubleclick() && (OS::get_singleton()->get_ticks_msec() - last_dblclk) < 600 && cursor.line == prev_line) {
+ if (!mb->is_double_click() && (OS::get_singleton()->get_ticks_msec() - last_dblclk) < 600 && cursor.line == prev_line) {
// Triple-click select line.
selection.selecting_mode = SelectionMode::SELECTION_MODE_LINE;
_update_selection_mode_line();
last_dblclk = 0;
- } else if (mb->is_doubleclick() && text[cursor.line].length()) {
+ } else if (mb->is_double_click() && text[cursor.line].length()) {
// Double-click select word.
selection.selecting_mode = SelectionMode::SELECTION_MODE_WORD;
_update_selection_mode_word();
@@ -3261,7 +3269,7 @@ void TextEdit::_gui_input(const Ref<InputEvent> &p_gui_input) {
accept_event();
return;
}
- if (k->is_action("ui_accept", true) || k->is_action("ui_text_completion_accept", true)) {
+ if (k->is_action("ui_text_completion_accept", true)) {
_confirm_completion();
accept_event();
return;
@@ -3851,7 +3859,7 @@ void TextEdit::_insert_text_at_cursor(const String &p_text) {
int new_column, new_line;
_insert_text(cursor.line, cursor.column, p_text, &new_line, &new_column);
_update_scrollbars();
- cursor_set_line(new_line);
+ cursor_set_line(new_line, false);
cursor_set_column(new_column);
update();
@@ -4425,7 +4433,7 @@ int TextEdit::get_column_x_offset_for_line(int p_char, int p_line) const {
void TextEdit::insert_text_at_cursor(const String &p_text) {
if (selection.active) {
- cursor_set_line(selection.from_line);
+ cursor_set_line(selection.from_line, false);
cursor_set_column(selection.from_column);
_remove_text(selection.from_line, selection.from_column, selection.to_line, selection.to_column);
@@ -5042,7 +5050,7 @@ void TextEdit::cut() {
DisplayServer::get_singleton()->clipboard_set(clipboard);
_remove_text(selection.from_line, selection.from_column, selection.to_line, selection.to_column);
- cursor_set_line(selection.from_line); // Set afterwards else it causes the view to be offset.
+ cursor_set_line(selection.from_line, false); // Set afterwards else it causes the view to be offset.
cursor_set_column(selection.from_column);
selection.active = false;
@@ -5078,7 +5086,7 @@ void TextEdit::paste() {
selection.active = false;
selection.selecting_mode = SelectionMode::SELECTION_MODE_NONE;
_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, false);
cursor_set_column(selection.from_column);
} else if (!cut_copy_line.is_empty() && cut_copy_line == clipboard) {
@@ -5817,11 +5825,11 @@ void TextEdit::undo() {
_update_scrollbars();
if (undo_stack_pos->get().type == TextOperation::TYPE_REMOVE) {
- cursor_set_line(undo_stack_pos->get().to_line);
+ cursor_set_line(undo_stack_pos->get().to_line, false);
cursor_set_column(undo_stack_pos->get().to_column);
_cancel_code_hint();
} else {
- cursor_set_line(undo_stack_pos->get().from_line);
+ cursor_set_line(undo_stack_pos->get().from_line, false);
cursor_set_column(undo_stack_pos->get().from_column);
}
update();
@@ -5856,7 +5864,7 @@ void TextEdit::redo() {
}
_update_scrollbars();
- cursor_set_line(undo_stack_pos->get().to_line);
+ cursor_set_line(undo_stack_pos->get().to_line, false);
cursor_set_column(undo_stack_pos->get().to_column);
undo_stack_pos = undo_stack_pos->next();
update();
diff --git a/scene/gui/tree.cpp b/scene/gui/tree.cpp
index 73fd9dbcd7..6404f6fc0d 100644
--- a/scene/gui/tree.cpp
+++ b/scene/gui/tree.cpp
@@ -1388,7 +1388,7 @@ int Tree::draw_item(const Point2i &p_pos, const Point2 &p_draw_ofs, const Size2
}
}
- if ((select_mode == SELECT_ROW && selected_item == p_item) || p_item->cells[i].selected) {
+ if ((select_mode == SELECT_ROW && selected_item == p_item) || p_item->cells[i].selected || !p_item->has_meta("__focus_rect")) {
Rect2i r(cell_rect.position, cell_rect.size);
p_item->set_meta("__focus_rect", Rect2(r.position, r.size));
@@ -1866,7 +1866,7 @@ void Tree::_range_click_timeout() {
}
}
-int Tree::propagate_mouse_event(const Point2i &p_pos, int x_ofs, int y_ofs, bool p_doubleclick, TreeItem *p_item, int p_button, const Ref<InputEventWithModifiers> &p_mod) {
+int Tree::propagate_mouse_event(const Point2i &p_pos, int x_ofs, int y_ofs, bool p_double_click, TreeItem *p_item, int p_button, const Ref<InputEventWithModifiers> &p_mod) {
int item_h = compute_item_height(p_item) + cache.vseparation;
bool skip = (p_item == root && hide_root);
@@ -1963,7 +1963,7 @@ int Tree::propagate_mouse_event(const Point2i &p_pos, int x_ofs, int y_ofs, bool
if (p_button == MOUSE_BUTTON_LEFT || (p_button == MOUSE_BUTTON_RIGHT && allow_rmb_select)) {
/* process selection */
- if (p_doubleclick && (!c.editable || c.mode == TreeItem::CELL_MODE_CUSTOM || c.mode == TreeItem::CELL_MODE_ICON /*|| c.mode==TreeItem::CELL_MODE_CHECK*/)) { //it's confusing for check
+ if (p_double_click && (!c.editable || c.mode == TreeItem::CELL_MODE_CUSTOM || c.mode == TreeItem::CELL_MODE_ICON /*|| c.mode==TreeItem::CELL_MODE_CHECK*/)) { //it's confusing for check
propagate_mouse_activated = true;
@@ -2167,7 +2167,7 @@ int Tree::propagate_mouse_event(const Point2i &p_pos, int x_ofs, int y_ofs, bool
TreeItem *c = p_item->children;
while (c) {
- int child_h = propagate_mouse_event(new_pos, x_ofs, y_ofs, p_doubleclick, c, p_button, p_mod);
+ int child_h = propagate_mouse_event(new_pos, x_ofs, y_ofs, p_double_click, c, p_button, p_mod);
if (child_h < 0) {
return -1; // break, stop propagating, no need to anymore
@@ -2846,7 +2846,7 @@ void Tree::_gui_input(Ref<InputEvent> p_event) {
propagate_mouse_activated = false;
blocked++;
- propagate_mouse_event(pos + cache.offset, 0, 0, b->is_doubleclick(), root, b->get_button_index(), b);
+ propagate_mouse_event(pos + cache.offset, 0, 0, b->is_double_click(), root, b->get_button_index(), b);
blocked--;
if (pressing_for_editor) {
@@ -4262,7 +4262,7 @@ void Tree::_bind_methods() {
ADD_SIGNAL(MethodInfo("item_custom_button_pressed"));
ADD_SIGNAL(MethodInfo("item_double_clicked"));
ADD_SIGNAL(MethodInfo("item_collapsed", PropertyInfo(Variant::OBJECT, "item", PROPERTY_HINT_RESOURCE_TYPE, "TreeItem")));
- //ADD_SIGNAL( MethodInfo("item_doubleclicked" ) );
+ //ADD_SIGNAL( MethodInfo("item_double_clicked" ) );
ADD_SIGNAL(MethodInfo("button_pressed", PropertyInfo(Variant::OBJECT, "item", PROPERTY_HINT_RESOURCE_TYPE, "TreeItem"), PropertyInfo(Variant::INT, "column"), PropertyInfo(Variant::INT, "id")));
ADD_SIGNAL(MethodInfo("custom_popup_edited", PropertyInfo(Variant::BOOL, "arrow_clicked")));
ADD_SIGNAL(MethodInfo("item_activated"));
diff --git a/scene/gui/tree.h b/scene/gui/tree.h
index d1407e24d4..a40817b752 100644
--- a/scene/gui/tree.h
+++ b/scene/gui/tree.h
@@ -390,7 +390,7 @@ private:
void draw_item_rect(TreeItem::Cell &p_cell, const Rect2i &p_rect, const Color &p_color, const Color &p_icon_color, int p_ol_size, const Color &p_ol_color);
int draw_item(const Point2i &p_pos, const Point2 &p_draw_ofs, const Size2 &p_draw_size, TreeItem *p_item);
void select_single_item(TreeItem *p_selected, TreeItem *p_current, int p_col, TreeItem *p_prev = nullptr, bool *r_in_range = nullptr, bool p_force_deselect = false);
- int propagate_mouse_event(const Point2i &p_pos, int x_ofs, int y_ofs, bool p_doubleclick, TreeItem *p_item, int p_button, const Ref<InputEventWithModifiers> &p_mod);
+ int propagate_mouse_event(const Point2i &p_pos, int x_ofs, int y_ofs, bool p_double_click, TreeItem *p_item, int p_button, const Ref<InputEventWithModifiers> &p_mod);
void _text_editor_enter(String p_text);
void _text_editor_modal_close();
void value_editor_changed(double p_value);