summaryrefslogtreecommitdiff
path: root/scene
diff options
context:
space:
mode:
Diffstat (limited to 'scene')
-rw-r--r--scene/2d/joints_2d.cpp107
-rw-r--r--scene/2d/joints_2d.h13
-rw-r--r--scene/2d/navigation_polygon.cpp2
-rw-r--r--scene/3d/SCsub3
-rw-r--r--scene/3d/gi_probe.cpp21
-rw-r--r--scene/3d/gi_probe.h8
-rw-r--r--scene/3d/light.cpp6
-rw-r--r--scene/3d/physics_joint.cpp31
-rw-r--r--scene/gui/line_edit.cpp111
-rw-r--r--scene/gui/line_edit.h14
-rw-r--r--scene/gui/nine_patch_rect.cpp (renamed from scene/gui/patch_9_rect.cpp)4
-rw-r--r--scene/gui/nine_patch_rect.h (renamed from scene/gui/patch_9_rect.h)8
-rw-r--r--scene/gui/tab_container.cpp7
-rw-r--r--scene/gui/text_edit.cpp31
-rw-r--r--scene/gui/text_edit.h4
-rw-r--r--scene/gui/tree.cpp2
-rw-r--r--scene/gui/viewport_container.cpp35
-rw-r--r--scene/gui/viewport_container.h4
-rw-r--r--scene/register_scene_types.cpp12
-rw-r--r--scene/resources/material.cpp2
-rw-r--r--scene/resources/video_stream.h2
21 files changed, 274 insertions, 153 deletions
diff --git a/scene/2d/joints_2d.cpp b/scene/2d/joints_2d.cpp
index 69bad1623f..b98cdcc365 100644
--- a/scene/2d/joints_2d.cpp
+++ b/scene/2d/joints_2d.cpp
@@ -33,19 +33,49 @@
#include "physics_body_2d.h"
#include "servers/physics_2d_server.h"
-void Joint2D::_update_joint() {
-
- if (!is_inside_tree())
- return;
+void Joint2D::_update_joint(bool p_only_free) {
if (joint.is_valid()) {
+ if (ba.is_valid() && bb.is_valid())
+ Physics2DServer::get_singleton()->body_remove_collision_exception(ba, bb);
+
Physics2DServer::get_singleton()->free(joint);
+ joint = RID();
+ ba = RID();
+ bb = RID();
}
- joint = RID();
+ if (p_only_free || !is_inside_tree())
+ return;
+
+ Node *node_a = has_node(get_node_a()) ? get_node(get_node_a()) : (Node *)NULL;
+ Node *node_b = has_node(get_node_b()) ? get_node(get_node_b()) : (Node *)NULL;
+
+ if (!node_a || !node_b)
+ return;
+
+ PhysicsBody2D *body_a = Object::cast_to<PhysicsBody2D>(node_a);
+ PhysicsBody2D *body_b = Object::cast_to<PhysicsBody2D>(node_b);
+
+ if (!body_a || !body_b)
+ return;
+
+ if (!body_a) {
+ SWAP(body_a, body_b);
+ }
+
+ joint = _configure_joint(body_a, body_b);
+
+ if (!joint.is_valid())
+ return;
- joint = _configure_joint();
Physics2DServer::get_singleton()->get_singleton()->joint_set_param(joint, Physics2DServer::JOINT_PARAM_BIAS, bias);
+
+ ba = body_a->get_rid();
+ bb = body_b->get_rid();
+
+ if (exclude_from_collision)
+ Physics2DServer::get_singleton()->body_add_collision_exception(body_a->get_rid(), body_b->get_rid());
}
void Joint2D::set_node_a(const NodePath &p_node_a) {
@@ -83,9 +113,7 @@ void Joint2D::_notification(int p_what) {
} break;
case NOTIFICATION_EXIT_TREE: {
if (joint.is_valid()) {
-
- Physics2DServer::get_singleton()->free(joint);
- joint = RID();
+ _update_joint(true);
}
} break;
}
@@ -164,29 +192,8 @@ void PinJoint2D::_notification(int p_what) {
}
}
-RID PinJoint2D::_configure_joint() {
-
- Node *node_a = has_node(get_node_a()) ? get_node(get_node_a()) : (Node *)NULL;
- Node *node_b = has_node(get_node_b()) ? get_node(get_node_b()) : (Node *)NULL;
-
- if (!node_a && !node_b)
- return RID();
+RID PinJoint2D::_configure_joint(PhysicsBody2D *body_a, PhysicsBody2D *body_b) {
- PhysicsBody2D *body_a = Object::cast_to<PhysicsBody2D>(node_a);
- PhysicsBody2D *body_b = Object::cast_to<PhysicsBody2D>(node_b);
-
- if (!body_a && !body_b)
- return RID();
-
- if (!body_a) {
- SWAP(body_a, body_b);
- } else if (body_b) {
- //add a collision exception between both
- if (get_exclude_nodes_from_collision())
- Physics2DServer::get_singleton()->body_add_collision_exception(body_a->get_rid(), body_b->get_rid());
- else
- Physics2DServer::get_singleton()->body_remove_collision_exception(body_a->get_rid(), body_b->get_rid());
- }
RID pj = Physics2DServer::get_singleton()->pin_joint_create(get_global_transform().get_origin(), body_a->get_rid(), body_b ? body_b->get_rid() : RID());
Physics2DServer::get_singleton()->pin_joint_set_param(pj, Physics2DServer::PIN_JOINT_SOFTNESS, softness);
return pj;
@@ -241,24 +248,7 @@ void GrooveJoint2D::_notification(int p_what) {
}
}
-RID GrooveJoint2D::_configure_joint() {
-
- Node *node_a = has_node(get_node_a()) ? get_node(get_node_a()) : (Node *)NULL;
- Node *node_b = has_node(get_node_b()) ? get_node(get_node_b()) : (Node *)NULL;
-
- if (!node_a || !node_b)
- return RID();
-
- PhysicsBody2D *body_a = Object::cast_to<PhysicsBody2D>(node_a);
- PhysicsBody2D *body_b = Object::cast_to<PhysicsBody2D>(node_b);
-
- if (!body_a || !body_b)
- return RID();
-
- if (get_exclude_nodes_from_collision())
- Physics2DServer::get_singleton()->body_add_collision_exception(body_a->get_rid(), body_b->get_rid());
- else
- Physics2DServer::get_singleton()->body_remove_collision_exception(body_a->get_rid(), body_b->get_rid());
+RID GrooveJoint2D::_configure_joint(PhysicsBody2D *body_a, PhysicsBody2D *body_b) {
Transform2D gt = get_global_transform();
Vector2 groove_A1 = gt.get_origin();
@@ -330,24 +320,7 @@ void DampedSpringJoint2D::_notification(int p_what) {
}
}
-RID DampedSpringJoint2D::_configure_joint() {
-
- Node *node_a = has_node(get_node_a()) ? get_node(get_node_a()) : (Node *)NULL;
- Node *node_b = has_node(get_node_b()) ? get_node(get_node_b()) : (Node *)NULL;
-
- if (!node_a || !node_b)
- return RID();
-
- PhysicsBody2D *body_a = Object::cast_to<PhysicsBody2D>(node_a);
- PhysicsBody2D *body_b = Object::cast_to<PhysicsBody2D>(node_b);
-
- if (!body_a || !body_b)
- return RID();
-
- if (get_exclude_nodes_from_collision())
- Physics2DServer::get_singleton()->body_add_collision_exception(body_a->get_rid(), body_b->get_rid());
- else
- Physics2DServer::get_singleton()->body_remove_collision_exception(body_a->get_rid(), body_b->get_rid());
+RID DampedSpringJoint2D::_configure_joint(PhysicsBody2D *body_a, PhysicsBody2D *body_b) {
Transform2D gt = get_global_transform();
Vector2 anchor_A = gt.get_origin();
diff --git a/scene/2d/joints_2d.h b/scene/2d/joints_2d.h
index 685299abc6..a6292be51c 100644
--- a/scene/2d/joints_2d.h
+++ b/scene/2d/joints_2d.h
@@ -32,11 +32,14 @@
#include "node_2d.h"
+class PhysicsBody2D;
+
class Joint2D : public Node2D {
GDCLASS(Joint2D, Node2D);
RID joint;
+ RID ba, bb;
NodePath a;
NodePath b;
@@ -45,10 +48,10 @@ class Joint2D : public Node2D {
bool exclude_from_collision;
protected:
- void _update_joint();
+ void _update_joint(bool p_only_free = false);
void _notification(int p_what);
- virtual RID _configure_joint() = 0;
+ virtual RID _configure_joint(PhysicsBody2D *body_a, PhysicsBody2D *body_b) = 0;
static void _bind_methods();
@@ -77,7 +80,7 @@ class PinJoint2D : public Joint2D {
protected:
void _notification(int p_what);
- virtual RID _configure_joint();
+ virtual RID _configure_joint(PhysicsBody2D *body_a, PhysicsBody2D *body_b);
static void _bind_methods();
public:
@@ -96,7 +99,7 @@ class GrooveJoint2D : public Joint2D {
protected:
void _notification(int p_what);
- virtual RID _configure_joint();
+ virtual RID _configure_joint(PhysicsBody2D *body_a, PhysicsBody2D *body_b);
static void _bind_methods();
public:
@@ -120,7 +123,7 @@ class DampedSpringJoint2D : public Joint2D {
protected:
void _notification(int p_what);
- virtual RID _configure_joint();
+ virtual RID _configure_joint(PhysicsBody2D *body_a, PhysicsBody2D *body_b);
static void _bind_methods();
public:
diff --git a/scene/2d/navigation_polygon.cpp b/scene/2d/navigation_polygon.cpp
index 35f94bff59..c53241e985 100644
--- a/scene/2d/navigation_polygon.cpp
+++ b/scene/2d/navigation_polygon.cpp
@@ -452,7 +452,7 @@ String NavigationPolygonInstance::get_configuration_warning() const {
return String();
}
- c = Object::cast_to<Node2D>(get_parent());
+ c = Object::cast_to<Node2D>(c->get_parent());
}
return TTR("NavigationPolygonInstance must be a child or grandchild to a Navigation2D node. It only provides navigation data.");
diff --git a/scene/3d/SCsub b/scene/3d/SCsub
index 72739b527e..4008f4f196 100644
--- a/scene/3d/SCsub
+++ b/scene/3d/SCsub
@@ -7,6 +7,9 @@ if env['disable_3d']:
env.scene_sources.append("3d/spatial.cpp")
env.scene_sources.append("3d/skeleton.cpp")
+ env.scene_sources.append("3d/particles.cpp")
+ env.scene_sources.append("3d/visual_instance.cpp")
+ env.scene_sources.append("3d/scenario_fx.cpp")
else:
env.add_source_files(env.scene_sources, "*.cpp")
diff --git a/scene/3d/gi_probe.cpp b/scene/3d/gi_probe.cpp
index d5a030b35c..c0ca358717 100644
--- a/scene/3d/gi_probe.cpp
+++ b/scene/3d/gi_probe.cpp
@@ -1134,6 +1134,10 @@ void GIProbe::_find_meshes(Node *p_at_node, Baker *p_baker) {
}
}
+GIProbe::BakeBeginFunc GIProbe::bake_begin_function = NULL;
+GIProbe::BakeStepFunc GIProbe::bake_step_function = NULL;
+GIProbe::BakeEndFunc GIProbe::bake_end_function = NULL;
+
void GIProbe::bake(Node *p_from_node, bool p_create_visual_debug) {
Baker baker;
@@ -1177,14 +1181,25 @@ void GIProbe::bake(Node *p_from_node, bool p_create_visual_debug) {
_find_meshes(p_from_node ? p_from_node : get_parent(), &baker);
+ if (bake_begin_function) {
+ bake_begin_function(baker.mesh_list.size() + 1);
+ }
+
int pmc = 0;
for (List<Baker::PlotMesh>::Element *E = baker.mesh_list.front(); E; E = E->next()) {
- print_line("plotting mesh " + itos(pmc++) + "/" + itos(baker.mesh_list.size()));
+ if (bake_step_function) {
+ bake_step_function(pmc, RTR("Plotting Meshes") + " " + itos(pmc) + "/" + itos(baker.mesh_list.size()));
+ }
+
+ pmc++;
_plot_mesh(E->get().local_xform, E->get().mesh, &baker, E->get().instance_materials, E->get().override_material);
}
+ if (bake_step_function) {
+ bake_step_function(pmc++, RTR("Finishing Plot"));
+ }
_fixup_plot(0, 0, 0, 0, 0, &baker);
@@ -1282,6 +1297,10 @@ void GIProbe::bake(Node *p_from_node, bool p_create_visual_debug) {
set_probe_data(probe_data);
}
+
+ if (bake_end_function) {
+ bake_end_function();
+ }
}
void GIProbe::_debug_mesh(int p_idx, int p_level, const Rect3 &p_aabb, Ref<MultiMesh> &p_multimesh, int &idx, Baker *p_baker) {
diff --git a/scene/3d/gi_probe.h b/scene/3d/gi_probe.h
index 5a06984a47..50d0c33d4f 100644
--- a/scene/3d/gi_probe.h
+++ b/scene/3d/gi_probe.h
@@ -95,6 +95,10 @@ public:
};
+ typedef void (*BakeBeginFunc)(int);
+ typedef void (*BakeStepFunc)(int, const String &);
+ typedef void (*BakeEndFunc)();
+
private:
//stuff used for bake
struct Baker {
@@ -190,6 +194,10 @@ protected:
static void _bind_methods();
public:
+ static BakeBeginFunc bake_begin_function;
+ static BakeStepFunc bake_step_function;
+ static BakeEndFunc bake_end_function;
+
void set_probe_data(const Ref<GIProbeData> &p_data);
Ref<GIProbeData> get_probe_data() const;
diff --git a/scene/3d/light.cpp b/scene/3d/light.cpp
index e994f4c79e..02d10523e7 100644
--- a/scene/3d/light.cpp
+++ b/scene/3d/light.cpp
@@ -369,12 +369,6 @@ DirectionalLight::DirectionalLight()
set_shadow_depth_range(SHADOW_DEPTH_RANGE_STABLE);
blend_splits = false;
-
-#ifdef TOOLS_ENABLED
- if (Engine::get_singleton()->is_editor_hint())
- // Create light with a default natural "sun" orientation in editor, instead of looking horizontally on X
- set_rotation_in_degrees(Vector3(-50, 25, 30));
-#endif
}
void OmniLight::set_shadow_mode(ShadowMode p_mode) {
diff --git a/scene/3d/physics_joint.cpp b/scene/3d/physics_joint.cpp
index aa127ab79f..1d779d31fe 100644
--- a/scene/3d/physics_joint.cpp
+++ b/scene/3d/physics_joint.cpp
@@ -32,13 +32,8 @@
void Joint::_update_joint(bool p_only_free) {
if (joint.is_valid()) {
- if (ba.is_valid() && bb.is_valid()) {
-
- if (exclude_from_collision)
- PhysicsServer::get_singleton()->body_add_collision_exception(ba, bb);
- else
- PhysicsServer::get_singleton()->body_remove_collision_exception(ba, bb);
- }
+ if (ba.is_valid() && bb.is_valid())
+ PhysicsServer::get_singleton()->body_remove_collision_exception(ba, bb);
PhysicsServer::get_singleton()->free(joint);
joint = RID();
@@ -52,33 +47,31 @@ void Joint::_update_joint(bool p_only_free) {
Node *node_a = has_node(get_node_a()) ? get_node(get_node_a()) : (Node *)NULL;
Node *node_b = has_node(get_node_b()) ? get_node(get_node_b()) : (Node *)NULL;
- if (!node_a && !node_b)
+ if (!node_a || !node_b)
return;
PhysicsBody *body_a = Object::cast_to<PhysicsBody>(node_a);
PhysicsBody *body_b = Object::cast_to<PhysicsBody>(node_b);
- if (!body_a && !body_b)
+ if (!body_a || !body_b)
return;
if (!body_a) {
SWAP(body_a, body_b);
- } else if (body_b) {
- //add a collision exception between both
- PhysicsServer::get_singleton()->body_add_collision_exception(body_a->get_rid(), body_b->get_rid());
}
joint = _configure_joint(body_a, body_b);
- if (joint.is_valid())
- PhysicsServer::get_singleton()->joint_set_solver_priority(joint, solver_priority);
+ if (!joint.is_valid())
+ return;
+
+ PhysicsServer::get_singleton()->joint_set_solver_priority(joint, solver_priority);
- if (body_b && joint.is_valid()) {
+ ba = body_a->get_rid();
+ bb = body_b->get_rid();
- ba = body_a->get_rid();
- bb = body_b->get_rid();
+ if (exclude_from_collision)
PhysicsServer::get_singleton()->body_add_collision_exception(body_a->get_rid(), body_b->get_rid());
- }
}
void Joint::set_node_a(const NodePath &p_node_a) {
@@ -129,8 +122,6 @@ void Joint::_notification(int p_what) {
case NOTIFICATION_EXIT_TREE: {
if (joint.is_valid()) {
_update_joint(true);
- //PhysicsServer::get_singleton()->free(joint);
- joint = RID();
}
} break;
}
diff --git a/scene/gui/line_edit.cpp b/scene/gui/line_edit.cpp
index ed8eff436c..40e2dba6c2 100644
--- a/scene/gui/line_edit.cpp
+++ b/scene/gui/line_edit.cpp
@@ -161,13 +161,14 @@ void LineEdit::_gui_input(Ref<InputEvent> p_event) {
} break;
- case (KEY_Z): { // Simple One level undo
-
+ case (KEY_Z): { // undo / redo
if (editable) {
-
- undo();
+ if (k->get_shift()) {
+ redo();
+ } else {
+ undo();
+ }
}
-
} break;
case (KEY_U): { // Delete from start to cursor
@@ -175,7 +176,6 @@ void LineEdit::_gui_input(Ref<InputEvent> p_event) {
if (editable) {
selection_clear();
- undo_text = text;
text = text.substr(cursor_pos, text.length() - cursor_pos);
Ref<Font> font = get_font("font");
@@ -205,7 +205,6 @@ void LineEdit::_gui_input(Ref<InputEvent> p_event) {
if (editable) {
selection_clear();
- undo_text = text;
text = text.substr(0, cursor_pos);
_text_changed();
}
@@ -245,7 +244,6 @@ void LineEdit::_gui_input(Ref<InputEvent> p_event) {
break;
if (selection.enabled) {
- undo_text = text;
selection_delete();
break;
}
@@ -276,7 +274,6 @@ void LineEdit::_gui_input(Ref<InputEvent> p_event) {
set_cursor_position(cc);
} else {
- undo_text = text;
delete_char();
}
@@ -382,7 +379,6 @@ void LineEdit::_gui_input(Ref<InputEvent> p_event) {
}
if (selection.enabled) {
- undo_text = text;
selection_delete();
break;
}
@@ -417,7 +413,6 @@ void LineEdit::_gui_input(Ref<InputEvent> p_event) {
delete_text(cursor_pos, cc);
} else {
- undo_text = text;
set_cursor_position(cursor_pos + 1);
delete_char();
}
@@ -778,7 +773,6 @@ void LineEdit::copy_text() {
void LineEdit::cut_text() {
if (selection.enabled) {
- undo_text = text;
OS::get_singleton()->set_clipboard(text.substr(selection.begin, selection.end - selection.begin));
selection_delete();
}
@@ -798,23 +792,33 @@ void LineEdit::paste_text() {
}
void LineEdit::undo() {
-
- int old_cursor_pos = cursor_pos;
- text = undo_text;
-
- Ref<Font> font = get_font("font");
-
- cached_width = 0;
- for (int i = 0; i < text.length(); i++)
- cached_width += font->get_char_size(text[i]).width;
-
- if (old_cursor_pos > text.length()) {
- set_cursor_position(text.length());
- } else {
- set_cursor_position(old_cursor_pos);
+ if (undo_stack_pos == NULL) {
+ if (undo_stack.size() <= 1) {
+ return;
+ }
+ undo_stack_pos = undo_stack.back();
+ } else if (undo_stack_pos == undo_stack.front()) {
+ return;
}
+ undo_stack_pos = undo_stack_pos->prev();
+ TextOperation op = undo_stack_pos->get();
+ text = op.text;
+ set_cursor_position(op.cursor_pos);
+ _emit_text_change();
+}
- _text_changed();
+void LineEdit::redo() {
+ if (undo_stack_pos == NULL) {
+ return;
+ }
+ if (undo_stack_pos == undo_stack.back()) {
+ return;
+ }
+ undo_stack_pos = undo_stack_pos->next();
+ TextOperation op = undo_stack_pos->get();
+ text = op.text;
+ set_cursor_position(op.cursor_pos);
+ _emit_text_change();
}
void LineEdit::shift_selection_check_pre(bool p_shift) {
@@ -947,8 +951,6 @@ void LineEdit::delete_char() {
void LineEdit::delete_text(int p_from_column, int p_to_column) {
- undo_text = text;
-
if (text.size() > 0) {
Ref<Font> font = get_font("font");
if (font != NULL) {
@@ -1036,9 +1038,11 @@ void LineEdit::set_cursor_position(int p_pos) {
Ref<StyleBox> style = get_stylebox("normal");
Ref<Font> font = get_font("font");
- if (cursor_pos < window_pos) {
+ if (cursor_pos <= window_pos) {
/* Adjust window if cursor goes too much to the left */
- set_window_pos(cursor_pos);
+ if (window_pos > 0)
+ set_window_pos(window_pos - 1);
+
} else if (cursor_pos > window_pos) {
/* Adjust window if cursor goes too much to the right */
int window_width = get_size().width - style->get_minimum_size().width;
@@ -1086,8 +1090,6 @@ void LineEdit::append_at_cursor(String p_text) {
if ((max_length <= 0) || (text.length() + p_text.length() <= max_length)) {
- undo_text = text;
-
Ref<Font> font = get_font("font");
if (font != NULL) {
for (int i = 0; i < p_text.length(); i++)
@@ -1105,6 +1107,7 @@ void LineEdit::append_at_cursor(String p_text) {
void LineEdit::clear_internal() {
+ _clear_undo_stack();
cached_width = 0;
cursor_pos = 0;
window_pos = 0;
@@ -1275,6 +1278,11 @@ void LineEdit::menu_option(int p_option) {
undo();
}
} break;
+ case MENU_REDO: {
+ if (editable) {
+ redo();
+ }
+ }
}
}
@@ -1312,10 +1320,43 @@ void LineEdit::_text_changed() {
if (expand_to_text_length)
minimum_size_changed();
+ _emit_text_change();
+ _clear_redo();
+}
+
+void LineEdit::_emit_text_change() {
emit_signal("text_changed", text);
_change_notify("text");
}
+void LineEdit::_clear_redo() {
+ _create_undo_state();
+ if (undo_stack_pos == NULL) {
+ return;
+ }
+
+ undo_stack_pos = undo_stack_pos->next();
+ while (undo_stack_pos) {
+ List<TextOperation>::Element *elem = undo_stack_pos;
+ undo_stack_pos = undo_stack_pos->next();
+ undo_stack.erase(elem);
+ }
+ _create_undo_state();
+}
+
+void LineEdit::_clear_undo_stack() {
+ undo_stack.clear();
+ undo_stack_pos = NULL;
+ _create_undo_state();
+}
+
+void LineEdit::_create_undo_state() {
+ TextOperation op;
+ op.text = text;
+ op.cursor_pos = cursor_pos;
+ undo_stack.push_back(op);
+}
+
void LineEdit::_bind_methods() {
ClassDB::bind_method(D_METHOD("_toggle_draw_caret"), &LineEdit::_toggle_draw_caret);
@@ -1369,6 +1410,7 @@ void LineEdit::_bind_methods() {
BIND_ENUM_CONSTANT(MENU_CLEAR);
BIND_ENUM_CONSTANT(MENU_SELECT_ALL);
BIND_ENUM_CONSTANT(MENU_UNDO);
+ BIND_ENUM_CONSTANT(MENU_REDO);
BIND_ENUM_CONSTANT(MENU_MAX);
ADD_PROPERTYNZ(PropertyInfo(Variant::STRING, "text"), "set_text", "get_text");
@@ -1388,6 +1430,8 @@ void LineEdit::_bind_methods() {
LineEdit::LineEdit() {
+ undo_stack_pos = NULL;
+ _create_undo_state();
align = ALIGN_LEFT;
cached_width = 0;
cursor_pos = 0;
@@ -1421,6 +1465,7 @@ LineEdit::LineEdit() {
menu->add_item(TTR("Clear"), MENU_CLEAR);
menu->add_separator();
menu->add_item(TTR("Undo"), MENU_UNDO, KEY_MASK_CMD | KEY_Z);
+ menu->add_item(TTR("Redo"), MENU_REDO, KEY_MASK_CMD | KEY_MASK_SHIFT | KEY_Z);
menu->connect("id_pressed", this, "menu_option");
expand_to_text_length = false;
}
diff --git a/scene/gui/line_edit.h b/scene/gui/line_edit.h
index 661f9b60b9..bece29a37d 100644
--- a/scene/gui/line_edit.h
+++ b/scene/gui/line_edit.h
@@ -56,6 +56,7 @@ public:
MENU_CLEAR,
MENU_SELECT_ALL,
MENU_UNDO,
+ MENU_REDO,
MENU_MAX
};
@@ -92,10 +93,22 @@ private:
bool drag_attempt;
} selection;
+ struct TextOperation {
+ int cursor_pos;
+ String text;
+ };
+ List<TextOperation> undo_stack;
+ List<TextOperation>::Element *undo_stack_pos;
+
+ void _clear_undo_stack();
+ void _clear_redo();
+ void _create_undo_state();
+
Timer *caret_blink_timer;
static void _ime_text_callback(void *p_self, String p_text, Point2 p_selection);
void _text_changed();
+ void _emit_text_change();
bool expand_to_text_length;
bool caret_blink_enabled;
@@ -166,6 +179,7 @@ public:
void cut_text();
void paste_text();
void undo();
+ void redo();
void set_editable(bool p_editable);
bool is_editable() const;
diff --git a/scene/gui/patch_9_rect.cpp b/scene/gui/nine_patch_rect.cpp
index 92c34dd3f9..c02d80bba8 100644
--- a/scene/gui/patch_9_rect.cpp
+++ b/scene/gui/nine_patch_rect.cpp
@@ -1,5 +1,5 @@
/*************************************************************************/
-/* patch_9_rect.cpp */
+/* nine_patch_rect.cpp */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
@@ -27,7 +27,7 @@
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-#include "patch_9_rect.h"
+#include "nine_patch_rect.h"
#include "servers/visual_server.h"
diff --git a/scene/gui/patch_9_rect.h b/scene/gui/nine_patch_rect.h
index 808b7a1f5d..809daf9db3 100644
--- a/scene/gui/patch_9_rect.h
+++ b/scene/gui/nine_patch_rect.h
@@ -1,5 +1,5 @@
/*************************************************************************/
-/* patch_9_rect.h */
+/* nine_patch_rect.h */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
@@ -27,8 +27,8 @@
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-#ifndef PATCH_9_FRAME_H
-#define PATCH_9_FRAME_H
+#ifndef NINE_PATCH_RECT_H
+#define NINE_PATCH_RECT_H
#include "scene/gui/control.h"
/**
@@ -81,4 +81,4 @@ public:
};
VARIANT_ENUM_CAST(NinePatchRect::AxisStretchMode)
-#endif // PATCH_9_FRAME_H
+#endif // NINE_PATCH_RECT_H
diff --git a/scene/gui/tab_container.cpp b/scene/gui/tab_container.cpp
index cfe924ecd4..581034ddee 100644
--- a/scene/gui/tab_container.cpp
+++ b/scene/gui/tab_container.cpp
@@ -90,6 +90,10 @@ void TabContainer::_gui_input(const Ref<InputEvent> &p_event) {
return;
}
+ // Do not activate tabs when tabs is empty
+ if (get_tab_count() == 0)
+ return;
+
Vector<Control *> tabs = _get_tabs();
// Handle navigation buttons.
@@ -298,6 +302,8 @@ void TabContainer::_notification(int p_what) {
}
int TabContainer::_get_tab_width(int p_index) const {
+
+ ERR_FAIL_INDEX_V(p_index, get_tab_count(), 0);
Control *control = Object::cast_to<Control>(_get_tabs()[p_index]);
if (!control || control->is_set_as_toplevel())
return 0;
@@ -669,6 +675,7 @@ void TabContainer::_bind_methods() {
TabContainer::TabContainer() {
first_tab_cache = 0;
+ last_tab_cache = 0;
buttons_visible_cache = false;
tabs_ofs_cache = 0;
current = 0;
diff --git a/scene/gui/text_edit.cpp b/scene/gui/text_edit.cpp
index 977ba2da7c..ee7762b668 100644
--- a/scene/gui/text_edit.cpp
+++ b/scene/gui/text_edit.cpp
@@ -734,7 +734,7 @@ void TextEdit::_notification(int p_what) {
if (str.length() == 0) {
// draw line background if empty as we won't loop at at all
- if (line == cursor.line) {
+ if (line == cursor.line && highlight_current_line) {
VisualServer::get_singleton()->canvas_item_add_rect(ci, Rect2(0, ofs_y, xmargin_end, get_row_height()), cache.current_line_color);
}
@@ -965,7 +965,7 @@ void TextEdit::_notification(int p_what) {
//current line highlighting
bool in_selection = (selection.active && line >= selection.from_line && line <= selection.to_line && (line > selection.from_line || j >= selection.from_column) && (line < selection.to_line || j < selection.to_column));
- if (line == cursor.line) {
+ if (line == cursor.line && highlight_current_line) {
// if its the first char draw behind line numbers
if (j == 0) {
VisualServer::get_singleton()->canvas_item_add_rect(ci, Rect2(0, ofs_y, (char_ofs + char_margin), get_row_height()), cache.current_line_color);
@@ -2188,7 +2188,7 @@ void TextEdit::_gui_input(const Ref<InputEvent> &p_gui_input) {
}
}
}
-
+ begin_complex_operation();
bool first_line = false;
if (k->get_command()) {
if (k->get_shift()) {
@@ -2204,8 +2204,7 @@ void TextEdit::_gui_input(const Ref<InputEvent> &p_gui_input) {
}
}
- _insert_text_at_cursor(ins);
- _push_current_op();
+ insert_text_at_cursor(ins);
if (first_line) {
cursor_set_line(0);
@@ -2213,7 +2212,7 @@ void TextEdit::_gui_input(const Ref<InputEvent> &p_gui_input) {
cursor_set_line(cursor.line - 1);
cursor_set_column(text[cursor.line].length());
}
-
+ end_complex_operation();
} break;
case KEY_ESCAPE: {
if (completion_hint != "") {
@@ -4489,7 +4488,13 @@ void TextEdit::_update_completion_candidates() {
completion_index = 0;
completion_base = s;
Vector<float> sim_cache;
+ bool single_quote = s.begins_with("'");
+
for (int i = 0; i < completion_strings.size(); i++) {
+ if (single_quote && completion_strings[i].is_quoted()) {
+ completion_strings[i] = completion_strings[i].unquote().quote("'");
+ }
+
if (s == completion_strings[i]) {
// A perfect match, stop completion
_cancel_completion();
@@ -4732,6 +4737,15 @@ int TextEdit::get_breakpoint_gutter_width() const {
return cache.breakpoint_gutter_width;
}
+void TextEdit::set_highlight_current_line(bool p_enabled) {
+ highlight_current_line = p_enabled;
+ update();
+}
+
+bool TextEdit::is_highlight_current_line_enabled() const {
+ return highlight_current_line;
+}
+
bool TextEdit::is_text_field() const {
return true;
@@ -4859,6 +4873,9 @@ void TextEdit::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_syntax_coloring", "enable"), &TextEdit::set_syntax_coloring);
ClassDB::bind_method(D_METHOD("is_syntax_coloring_enabled"), &TextEdit::is_syntax_coloring_enabled);
+ ClassDB::bind_method(D_METHOD("set_highlight_current_line", "enabled"), &TextEdit::set_highlight_current_line);
+ ClassDB::bind_method(D_METHOD("is_highlight_current_line_enabled"), &TextEdit::is_highlight_current_line_enabled);
+
ClassDB::bind_method(D_METHOD("set_smooth_scroll_enable", "enable"), &TextEdit::set_smooth_scroll_enabled);
ClassDB::bind_method(D_METHOD("is_smooth_scroll_enabled"), &TextEdit::is_smooth_scroll_enabled);
ClassDB::bind_method(D_METHOD("set_v_scroll_speed", "speed"), &TextEdit::set_v_scroll_speed);
@@ -4870,6 +4887,7 @@ void TextEdit::_bind_methods() {
ClassDB::bind_method(D_METHOD("menu_option", "option"), &TextEdit::menu_option);
ClassDB::bind_method(D_METHOD("get_menu"), &TextEdit::get_menu);
+ ADD_PROPERTY(PropertyInfo(Variant::BOOL, "highlight_current_line"), "set_highlight_current_line", "is_highlight_current_line_enabled");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "syntax_highlighting"), "set_syntax_coloring", "is_syntax_coloring_enabled");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "show_line_numbers"), "set_show_line_numbers", "is_show_line_numbers_enabled");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "highlight_all_occurrences"), "set_highlight_all_occurrences", "is_highlight_all_occurrences_enabled");
@@ -4991,6 +5009,7 @@ TextEdit::TextEdit() {
auto_brace_completion_enabled = false;
brace_matching_enabled = false;
highlight_all_occurrences = false;
+ highlight_current_line = false;
indent_using_spaces = false;
space_indent = " ";
auto_indent = false;
diff --git a/scene/gui/text_edit.h b/scene/gui/text_edit.h
index 03f412729d..b4b14d0139 100644
--- a/scene/gui/text_edit.h
+++ b/scene/gui/text_edit.h
@@ -253,6 +253,7 @@ class TextEdit : public Control {
bool scroll_past_end_of_file_enabled;
bool auto_brace_completion_enabled;
bool brace_matching_enabled;
+ bool highlight_current_line;
bool auto_indent;
bool cut_copy_line;
bool insert_mode;
@@ -514,6 +515,9 @@ public:
void set_show_line_numbers(bool p_show);
bool is_show_line_numbers_enabled() const;
+ void set_highlight_current_line(bool p_enabled);
+ bool is_highlight_current_line_enabled() const;
+
void set_line_numbers_zero_padded(bool p_zero_padded);
void set_show_line_length_guideline(bool p_show);
diff --git a/scene/gui/tree.cpp b/scene/gui/tree.cpp
index 931dcfed91..5c6f2b0d01 100644
--- a/scene/gui/tree.cpp
+++ b/scene/gui/tree.cpp
@@ -1126,7 +1126,7 @@ int Tree::draw_item(const Point2i &p_pos, const Point2 &p_draw_ofs, const Size2
if (p_item->cells[i].selected && select_mode != SELECT_ROW) {
- Rect2i r(item_rect.position, item_rect.size);
+ Rect2i r(cell_rect.position, cell_rect.size);
if (p_item->cells[i].text.size() > 0) {
float icon_width = p_item->cells[i].get_icon_size().width;
r.position.x += icon_width;
diff --git a/scene/gui/viewport_container.cpp b/scene/gui/viewport_container.cpp
index c321b873fd..9244d8de2f 100644
--- a/scene/gui/viewport_container.cpp
+++ b/scene/gui/viewport_container.cpp
@@ -62,6 +62,34 @@ bool ViewportContainer::is_stretch_enabled() const {
return stretch;
}
+void ViewportContainer::set_stretch_shrink(int p_shrink) {
+
+ ERR_FAIL_COND(p_shrink < 1);
+ if (shrink == p_shrink)
+ return;
+
+ shrink = p_shrink;
+
+ if (!stretch)
+ return;
+
+ for (int i = 0; i < get_child_count(); i++) {
+
+ Viewport *c = Object::cast_to<Viewport>(get_child(i));
+ if (!c)
+ continue;
+
+ c->set_size(get_size() / shrink);
+ }
+
+ update();
+}
+
+int ViewportContainer::get_stretch_shrink() const {
+
+ return shrink;
+}
+
void ViewportContainer::_notification(int p_what) {
if (p_what == NOTIFICATION_RESIZED) {
@@ -75,7 +103,7 @@ void ViewportContainer::_notification(int p_what) {
if (!c)
continue;
- c->set_size(get_size());
+ c->set_size(get_size() / shrink);
}
}
@@ -115,10 +143,15 @@ void ViewportContainer::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_stretch", "enable"), &ViewportContainer::set_stretch);
ClassDB::bind_method(D_METHOD("is_stretch_enabled"), &ViewportContainer::is_stretch_enabled);
+ ClassDB::bind_method(D_METHOD("set_stretch_shrink", "amount"), &ViewportContainer::set_stretch_shrink);
+ ClassDB::bind_method(D_METHOD("get_stretch_shrink"), &ViewportContainer::get_stretch_shrink);
+
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "stretch"), "set_stretch", "is_stretch_enabled");
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "stretch_shrink"), "set_stretch_shrink", "get_stretch_shrink");
}
ViewportContainer::ViewportContainer() {
stretch = false;
+ shrink = 1;
}
diff --git a/scene/gui/viewport_container.h b/scene/gui/viewport_container.h
index 630523b5fb..ebf5869ed9 100644
--- a/scene/gui/viewport_container.h
+++ b/scene/gui/viewport_container.h
@@ -37,6 +37,7 @@ class ViewportContainer : public Container {
GDCLASS(ViewportContainer, Container);
bool stretch;
+ int shrink;
protected:
void _notification(int p_what);
@@ -46,6 +47,9 @@ public:
void set_stretch(bool p_enable);
bool is_stretch_enabled() const;
+ void set_stretch_shrink(int p_shrink);
+ int get_stretch_shrink() const;
+
virtual Size2 get_minimum_size() const;
ViewportContainer();
diff --git a/scene/register_scene_types.cpp b/scene/register_scene_types.cpp
index 75268aad1f..eaa16069cf 100644
--- a/scene/register_scene_types.cpp
+++ b/scene/register_scene_types.cpp
@@ -86,7 +86,7 @@
#include "scene/gui/option_button.h"
#include "scene/gui/panel.h"
#include "scene/gui/panel_container.h"
-#include "scene/gui/patch_9_rect.h"
+#include "scene/gui/nine_patch_rect.h"
#include "scene/gui/popup_menu.h"
#include "scene/gui/progress_bar.h"
#include "scene/gui/reference_rect.h"
@@ -152,6 +152,10 @@
#include "scene/resources/world_2d.h"
#include "scene/scene_string_names.h"
+#include "scene/3d/particles.h"
+#include "scene/3d/scenario_fx.h"
+#include "scene/3d/spatial.h"
+
#ifndef _3D_DISABLED
#include "scene/3d/area.h"
#include "scene/3d/arvr_nodes.h"
@@ -169,7 +173,6 @@
#include "scene/3d/multimesh_instance.h"
#include "scene/3d/navigation.h"
#include "scene/3d/navigation_mesh.h"
-#include "scene/3d/particles.h"
#include "scene/3d/path.h"
#include "scene/3d/physics_body.h"
#include "scene/3d/physics_joint.h"
@@ -180,9 +183,7 @@
#include "scene/3d/reflection_probe.h"
#include "scene/3d/remote_transform.h"
#include "scene/3d/room_instance.h"
-#include "scene/3d/scenario_fx.h"
#include "scene/3d/skeleton.h"
-#include "scene/3d/spatial.h"
#include "scene/3d/sprite_3d.h"
#include "scene/3d/vehicle_body.h"
#include "scene/3d/visibility_notifier.h"
@@ -541,6 +542,7 @@ void register_scene_types() {
ClassDB::register_class<StyleBoxEmpty>();
ClassDB::register_class<StyleBoxTexture>();
ClassDB::register_class<StyleBoxFlat>();
+ ClassDB::register_class<StyleBoxLine>();
ClassDB::register_class<Theme>();
ClassDB::register_class<PolygonPathFinder>();
@@ -551,7 +553,9 @@ void register_scene_types() {
ClassDB::register_class<AudioStreamPlayer>();
ClassDB::register_class<AudioStreamPlayer2D>();
+#ifndef _3D_DISABLED
ClassDB::register_class<AudioStreamPlayer3D>();
+#endif
ClassDB::register_virtual_class<VideoStream>();
ClassDB::register_class<AudioStreamSample>();
diff --git a/scene/resources/material.cpp b/scene/resources/material.cpp
index 898a594498..12434b39fa 100644
--- a/scene/resources/material.cpp
+++ b/scene/resources/material.cpp
@@ -1278,7 +1278,7 @@ void SpatialMaterial::_validate_property(PropertyInfo &property) const {
property.usage = 0;
}
- if (property.name == "proximity_fade_distacne" && !proximity_fade_enabled) {
+ if (property.name == "proximity_fade_distance" && !proximity_fade_enabled) {
property.usage = 0;
}
diff --git a/scene/resources/video_stream.h b/scene/resources/video_stream.h
index 0f07233185..3f79858056 100644
--- a/scene/resources/video_stream.h
+++ b/scene/resources/video_stream.h
@@ -60,7 +60,7 @@ public:
virtual void set_audio_track(int p_idx) = 0;
- //virtual int mix(int16_t* p_bufer,int p_frames)=0;
+ //virtual int mix(int16_t* p_buffer,int p_frames)=0;
virtual Ref<Texture> get_texture() = 0;
virtual void update(float p_delta) = 0;