diff options
Diffstat (limited to 'scene')
-rw-r--r-- | scene/2d/joints_2d.cpp | 107 | ||||
-rw-r--r-- | scene/2d/joints_2d.h | 13 | ||||
-rw-r--r-- | scene/3d/arvr_nodes.cpp | 30 | ||||
-rw-r--r-- | scene/3d/arvr_nodes.h | 3 | ||||
-rw-r--r-- | scene/3d/gi_probe.cpp | 21 | ||||
-rw-r--r-- | scene/3d/gi_probe.h | 8 | ||||
-rw-r--r-- | scene/3d/physics_joint.cpp | 31 | ||||
-rw-r--r-- | scene/animation/animation_player.cpp | 1 | ||||
-rw-r--r-- | scene/gui/line_edit.cpp | 111 | ||||
-rw-r--r-- | scene/gui/line_edit.h | 14 | ||||
-rw-r--r-- | scene/gui/rich_text_label.cpp | 6 | ||||
-rw-r--r-- | scene/gui/tab_container.cpp | 7 | ||||
-rw-r--r-- | scene/gui/text_edit.cpp | 200 | ||||
-rw-r--r-- | scene/gui/text_edit.h | 9 | ||||
-rw-r--r-- | scene/gui/tree.cpp | 20 | ||||
-rw-r--r-- | scene/gui/tree.h | 1 | ||||
-rw-r--r-- | scene/gui/viewport_container.cpp | 35 | ||||
-rw-r--r-- | scene/gui/viewport_container.h | 4 | ||||
-rw-r--r-- | scene/main/http_request.cpp | 1 | ||||
-rw-r--r-- | scene/register_scene_types.cpp | 1 | ||||
-rw-r--r-- | scene/resources/texture.cpp | 23 | ||||
-rw-r--r-- | scene/resources/texture.h | 4 | ||||
-rw-r--r-- | scene/resources/video_stream.h | 2 |
23 files changed, 455 insertions, 197 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/3d/arvr_nodes.cpp b/scene/3d/arvr_nodes.cpp index 064a249190..e1e0b9b1ce 100644 --- a/scene/3d/arvr_nodes.cpp +++ b/scene/3d/arvr_nodes.cpp @@ -231,7 +231,7 @@ void ARVRController::_notification(int p_what) { void ARVRController::_bind_methods() { ClassDB::bind_method(D_METHOD("set_controller_id", "controller_id"), &ARVRController::set_controller_id); ClassDB::bind_method(D_METHOD("get_controller_id"), &ARVRController::get_controller_id); - ADD_PROPERTY(PropertyInfo(Variant::INT, "controller_id"), "set_controller_id", "get_controller_id"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "controller_id", PROPERTY_HINT_RANGE, "1,32,1"), "set_controller_id", "get_controller_id"); ClassDB::bind_method(D_METHOD("get_controller_name"), &ARVRController::get_controller_name); // passthroughs to information about our related joystick @@ -242,6 +242,10 @@ void ARVRController::_bind_methods() { ClassDB::bind_method(D_METHOD("get_is_active"), &ARVRController::get_is_active); ClassDB::bind_method(D_METHOD("get_hand"), &ARVRController::get_hand); + ClassDB::bind_method(D_METHOD("get_rumble"), &ARVRController::get_rumble); + ClassDB::bind_method(D_METHOD("set_rumble", "rumble"), &ARVRController::set_rumble); + ADD_PROPERTY(PropertyInfo(Variant::REAL, "rumble", PROPERTY_HINT_RANGE, "0.0,1.0,0.01"), "set_rumble", "get_rumble"); + ADD_SIGNAL(MethodInfo("button_pressed", PropertyInfo(Variant::INT, "button"))); ADD_SIGNAL(MethodInfo("button_release", PropertyInfo(Variant::INT, "button"))); }; @@ -299,6 +303,30 @@ float ARVRController::get_joystick_axis(int p_axis) const { return Input::get_singleton()->get_joy_axis(joy_id, p_axis); }; +real_t ARVRController::get_rumble() const { + // get our ARVRServer + ARVRServer *arvr_server = ARVRServer::get_singleton(); + ERR_FAIL_NULL_V(arvr_server, 0.0); + + ARVRPositionalTracker *tracker = arvr_server->find_by_type_and_id(ARVRServer::TRACKER_CONTROLLER, controller_id); + if (tracker == NULL) { + return 0.0; + }; + + return tracker->get_rumble(); +}; + +void ARVRController::set_rumble(real_t p_rumble) { + // get our ARVRServer + ARVRServer *arvr_server = ARVRServer::get_singleton(); + ERR_FAIL_NULL(arvr_server); + + ARVRPositionalTracker *tracker = arvr_server->find_by_type_and_id(ARVRServer::TRACKER_CONTROLLER, controller_id); + if (tracker != NULL) { + tracker->set_rumble(p_rumble); + }; +}; + bool ARVRController::get_is_active() const { return is_active; }; diff --git a/scene/3d/arvr_nodes.h b/scene/3d/arvr_nodes.h index e0ccfab58b..6e940351f2 100644 --- a/scene/3d/arvr_nodes.h +++ b/scene/3d/arvr_nodes.h @@ -89,6 +89,9 @@ public: int is_button_pressed(int p_button) const; float get_joystick_axis(int p_axis) const; + real_t get_rumble() const; + void set_rumble(real_t p_rumble); + bool get_is_active() const; ARVRPositionalTracker::TrackerHand get_hand() const; 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/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/animation/animation_player.cpp b/scene/animation/animation_player.cpp index 0f631c69b6..80b7748078 100644 --- a/scene/animation/animation_player.cpp +++ b/scene/animation/animation_player.cpp @@ -202,7 +202,6 @@ void AnimationPlayer::_notification(int p_what) { if (!Engine::get_singleton()->is_editor_hint() && animation_set.has(autoplay)) { play(autoplay); - set_autoplay(""); //this line is the fix for autoplay issues with animatio _animation_process(0); } } 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/rich_text_label.cpp b/scene/gui/rich_text_label.cpp index ad519d8d0c..798acb9d52 100644 --- a/scene/gui/rich_text_label.cpp +++ b/scene/gui/rich_text_label.cpp @@ -526,6 +526,9 @@ int RichTextLabel::_process_line(ItemFrame *p_frame, const Vector2 &p_ofs, int & nonblank_line_count += _process_line(frame, p_ofs + offset + draw_ofs + Vector2(0, yofs), ly, table->columns[column].width, i, PROCESS_DRAW, cfont, ccolor); } else if (p_mode == PROCESS_POINTER) { _process_line(frame, p_ofs + offset + draw_ofs + Vector2(0, yofs), ly, table->columns[column].width, i, PROCESS_POINTER, cfont, ccolor, p_click_pos, r_click_item, r_click_char, r_outside); + if (r_click_item && *r_click_item) { + RETURN; // exit early + } } } @@ -1195,8 +1198,9 @@ void RichTextLabel::add_newline() { return; ItemNewline *item = memnew(ItemNewline); item->line = current_frame->lines.size(); - current_frame->lines.resize(current_frame->lines.size() + 1); _add_item(item, false); + current_frame->lines.resize(current_frame->lines.size() + 1); + _invalidate_current_line(current_frame); } bool RichTextLabel::remove_line(const int p_line) { 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 acf6d55eb5..7d200a799b 100644 --- a/scene/gui/text_edit.cpp +++ b/scene/gui/text_edit.cpp @@ -376,24 +376,116 @@ void TextEdit::_update_scrollbars() { void TextEdit::_click_selection_held() { if (Input::get_singleton()->is_mouse_button_pressed(BUTTON_LEFT) && selection.selecting_mode != Selection::MODE_NONE) { + switch (selection.selecting_mode) { + case Selection::MODE_POINTER: { + _update_selection_mode_pointer(); + } break; + case Selection::MODE_WORD: { + _update_selection_mode_word(); + } break; + case Selection::MODE_LINE: { + _update_selection_mode_line(); + } break; + default: { + break; + } + } + } else { + click_select_held->stop(); + } +} - Point2 mp = Input::get_singleton()->get_mouse_position() - get_global_position(); +void TextEdit::_update_selection_mode_pointer() { + Point2 mp = Input::get_singleton()->get_mouse_position() - get_global_position(); - int row, col; - _get_mouse_pos(Point2i(mp.x, mp.y), row, col); + int row, col; + _get_mouse_pos(Point2i(mp.x, mp.y), row, col); - select(selection.selecting_line, selection.selecting_column, row, col); + select(selection.selecting_line, selection.selecting_column, row, col); - cursor_set_line(row); - cursor_set_column(col); - update(); + cursor_set_line(row); + cursor_set_column(col); + update(); + + click_select_held->start(); +} + +void TextEdit::_update_selection_mode_word() { + Point2 mp = Input::get_singleton()->get_mouse_position() - get_global_position(); - click_select_held->start(); + int row, col; + _get_mouse_pos(Point2i(mp.x, mp.y), row, col); + String line = text[row]; + int beg = CLAMP(col, 0, line.length()); + // if its the first selection and on whitespace make sure we grab the word instead.. + if (!selection.active) { + while (beg > 0 && line[beg] <= 32) { + beg--; + } + } + int end = beg; + bool symbol = beg < line.length() && _is_symbol(line[beg]); + + // get the word end and begin points + while (beg > 0 && line[beg - 1] > 32 && (symbol == _is_symbol(line[beg - 1]))) { + beg--; + } + while (end < line.length() && line[end + 1] > 32 && (symbol == _is_symbol(line[end + 1]))) { + end++; + } + if (end < line.length()) { + end += 1; + } + + // inital selection + if (!selection.active) { + select(row, beg, row, end); + selection.selecting_column = beg; + selection.selected_word_beg = beg; + selection.selected_word_end = end; + selection.selected_word_origin = beg; + cursor_set_column(selection.to_column); } else { + if ((col <= selection.selected_word_origin && row == selection.selecting_line) || row < selection.selecting_line) { + selection.selecting_column = selection.selected_word_end; + select(row, beg, selection.selecting_line, selection.selected_word_end); + cursor_set_column(selection.from_column); + } else { + selection.selecting_column = selection.selected_word_beg; + select(selection.selecting_line, selection.selected_word_beg, row, end); + cursor_set_column(selection.to_column); + } + } + cursor_set_line(row); - click_select_held->stop(); + update(); + click_select_held->start(); +} + +void TextEdit::_update_selection_mode_line() { + Point2 mp = Input::get_singleton()->get_mouse_position() - get_global_position(); + + int row, col; + _get_mouse_pos(Point2i(mp.x, mp.y), row, col); + + col = 0; + if (row < selection.selecting_line) { + // cursor is above us + cursor_set_line(row - 1); + selection.selecting_column = text[selection.selecting_line].length(); + } else { + // cursor is below us + cursor_set_line(row + 1); + selection.selecting_column = 0; + col = text[row].length(); } + cursor_set_column(0); + + select(selection.selecting_line, selection.selecting_column, row, col); + update(); + + click_select_held->start(); } void TextEdit::_notification(int p_what) { @@ -1759,36 +1851,15 @@ void TextEdit::_gui_input(const Ref<InputEvent> &p_gui_input) { if (!mb->is_doubleclick() && (OS::get_singleton()->get_ticks_msec() - last_dblclk) < 600 && cursor.line == prev_line) { //tripleclick select line - select(cursor.line, 0, cursor.line, text[cursor.line].length()); - selection.selecting_column = 0; + selection.selecting_mode = Selection::MODE_LINE; + _update_selection_mode_line(); last_dblclk = 0; } else if (mb->is_doubleclick() && text[cursor.line].length()) { //doubleclick select world - String s = text[cursor.line]; - int beg = CLAMP(cursor.column, 0, s.length()); - int end = beg; - - if (s[beg] > 32 || beg == s.length()) { - - bool symbol = beg < s.length() && _is_symbol(s[beg]); //not sure if right but most editors behave like this - - while (beg > 0 && s[beg - 1] > 32 && (symbol == _is_symbol(s[beg - 1]))) { - beg--; - } - while (end < s.length() && s[end + 1] > 32 && (symbol == _is_symbol(s[end + 1]))) { - end++; - } - - if (end < s.length()) - end += 1; - - select(cursor.line, beg, cursor.line, end); - - selection.selecting_column = beg; - } - + selection.selecting_mode = Selection::MODE_WORD; + _update_selection_mode_word(); last_dblclk = OS::get_singleton()->get_ticks_msec(); } @@ -1833,21 +1904,21 @@ void TextEdit::_gui_input(const Ref<InputEvent> &p_gui_input) { } if (mm->get_button_mask() & BUTTON_MASK_LEFT && get_viewport()->gui_get_drag_data() == Variant()) { //ignore if dragging + _reset_caret_blink_timer(); - if (selection.selecting_mode != Selection::MODE_NONE) { - - _reset_caret_blink_timer(); - - int row, col; - _get_mouse_pos(mm->get_position(), row, col); - - select(selection.selecting_line, selection.selecting_column, row, col); - - cursor_set_line(row); - cursor_set_column(col); - update(); - - click_select_held->start(); + switch (selection.selecting_mode) { + case Selection::MODE_POINTER: { + _update_selection_mode_pointer(); + } break; + case Selection::MODE_WORD: { + _update_selection_mode_word(); + } break; + case Selection::MODE_LINE: { + _update_selection_mode_line(); + } break; + default: { + break; + } } } } @@ -2188,7 +2259,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 +2275,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 +2283,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 != "") { @@ -2848,19 +2918,19 @@ void TextEdit::_gui_input(const Ref<InputEvent> &p_gui_input) { if (scancode_handled) accept_event(); /* - if (!scancode_handled && !k->get_command() && !k->get_alt()) { + if (!scancode_handled && !k->get_command() && !k->get_alt()) { if (k->get_unicode()>=32) { - if (readonly) + if (readonly) break; - accept_event(); + accept_event(); } else { - break; + break; + } } - } */ if (k->get_scancode() == KEY_INSERT) { set_insert_mode(!insert_mode); @@ -3252,11 +3322,11 @@ void TextEdit::adjust_viewport_to_cursor() { update(); /* - get_range()->set_max(text.size()); + get_range()->set_max(text.size()); - get_range()->set_page(get_visible_rows()); + get_range()->set_page(get_visible_rows()); - get_range()->set((int)cursor.line_ofs); + get_range()->set((int)cursor.line_ofs); */ } @@ -4489,7 +4559,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(); @@ -4810,8 +4886,8 @@ void TextEdit::_bind_methods() { BIND_ENUM_CONSTANT(SEARCH_BACKWARDS); /* - ClassDB::bind_method(D_METHOD("delete_char"),&TextEdit::delete_char); - ClassDB::bind_method(D_METHOD("delete_line"),&TextEdit::delete_line); + ClassDB::bind_method(D_METHOD("delete_char"),&TextEdit::delete_char); + ClassDB::bind_method(D_METHOD("delete_line"),&TextEdit::delete_line); */ ClassDB::bind_method(D_METHOD("set_text", "text"), &TextEdit::set_text); diff --git a/scene/gui/text_edit.h b/scene/gui/text_edit.h index b4b14d0139..81310b7c10 100644 --- a/scene/gui/text_edit.h +++ b/scene/gui/text_edit.h @@ -51,11 +51,14 @@ class TextEdit : public Control { MODE_NONE, MODE_SHIFT, - MODE_POINTER + MODE_POINTER, + MODE_WORD, + MODE_LINE }; Mode selecting_mode; int selecting_line, selecting_column; + int selected_word_beg, selected_word_end, selected_word_origin; bool selecting_text; bool active; @@ -305,6 +308,10 @@ class TextEdit : public Control { void _v_scroll_input(); void _click_selection_held(); + void _update_selection_mode_pointer(); + void _update_selection_mode_word(); + void _update_selection_mode_line(); + void _pre_shift_selection(); void _post_shift_selection(); diff --git a/scene/gui/tree.cpp b/scene/gui/tree.cpp index 5c6f2b0d01..f2e5919b5f 100644 --- a/scene/gui/tree.cpp +++ b/scene/gui/tree.cpp @@ -3332,6 +3332,26 @@ Point2 Tree::get_scroll() const { return ofs; } +void Tree::scroll_to_item(TreeItem *p_item) { + + if (!is_visible_in_tree()) { + + // hack to work around crash in get_item_rect() if Tree is not in tree. + return; + } + + // make sure the scrollbar min and max are up to date with latest changes. + update_scrollbars(); + + const Rect2 r = get_item_rect(p_item); + + if (r.position.y < v_scroll->get_value()) { + v_scroll->set_value(r.position.y); + } else if (r.position.y + r.size.y + 2 * cache.vseparation > v_scroll->get_value() + get_size().y) { + v_scroll->set_value(r.position.y + r.size.y + 2 * cache.vseparation - get_size().y); + } +} + TreeItem *Tree::_search_item_text(TreeItem *p_at, const String &p_find, int *r_col, bool p_selectable, bool p_backwards) { while (p_at) { diff --git a/scene/gui/tree.h b/scene/gui/tree.h index 2ee91a8b73..64d6016942 100644 --- a/scene/gui/tree.h +++ b/scene/gui/tree.h @@ -570,6 +570,7 @@ public: TreeItem *search_item_text(const String &p_find, int *r_col = NULL, bool p_selectable = false); Point2 get_scroll() const; + void scroll_to_item(TreeItem *p_item); void set_cursor_can_exit_tree(bool p_enable); bool can_cursor_exit_tree() const; 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/main/http_request.cpp b/scene/main/http_request.cpp index 1e1e4f2d5f..672e893f1b 100644 --- a/scene/main/http_request.cpp +++ b/scene/main/http_request.cpp @@ -579,6 +579,7 @@ HTTPRequest::HTTPRequest() { client.instance(); use_threads = false; thread_done = false; + downloaded = 0; body_size_limit = -1; file = NULL; status = HTTPClient::STATUS_DISCONNECTED; diff --git a/scene/register_scene_types.cpp b/scene/register_scene_types.cpp index 4d3e2c709c..eaa16069cf 100644 --- a/scene/register_scene_types.cpp +++ b/scene/register_scene_types.cpp @@ -542,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>(); diff --git a/scene/resources/texture.cpp b/scene/resources/texture.cpp index 467f059fd3..162edd0d1c 100644 --- a/scene/resources/texture.cpp +++ b/scene/resources/texture.cpp @@ -866,6 +866,18 @@ Rect2 AtlasTexture::get_margin() const { return margin; } +void AtlasTexture::set_filter_clip(const bool p_enable) { + + filter_clip = p_enable; + emit_changed(); + _change_notify("filter_clip"); +} + +bool AtlasTexture::has_filter_clip() const { + + return filter_clip; +} + void AtlasTexture::_bind_methods() { ClassDB::bind_method(D_METHOD("set_atlas", "atlas"), &AtlasTexture::set_atlas); @@ -877,9 +889,13 @@ void AtlasTexture::_bind_methods() { ClassDB::bind_method(D_METHOD("set_margin", "margin"), &AtlasTexture::set_margin); ClassDB::bind_method(D_METHOD("get_margin"), &AtlasTexture::get_margin); + ClassDB::bind_method(D_METHOD("set_filter_clip", "enable"), &AtlasTexture::set_filter_clip); + ClassDB::bind_method(D_METHOD("has_filter_clip"), &AtlasTexture::has_filter_clip); + ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "atlas", PROPERTY_HINT_RESOURCE_TYPE, "Texture"), "set_atlas", "get_atlas"); ADD_PROPERTY(PropertyInfo(Variant::RECT2, "region"), "set_region", "get_region"); ADD_PROPERTY(PropertyInfo(Variant::RECT2, "margin"), "set_margin", "get_margin"); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "filter_clip"), "set_filter_clip", "has_filter_clip"); } void AtlasTexture::draw(RID p_canvas_item, const Point2 &p_pos, const Color &p_modulate, bool p_transpose, const Ref<Texture> &p_normal_map) const { @@ -898,7 +914,7 @@ void AtlasTexture::draw(RID p_canvas_item, const Point2 &p_pos, const Color &p_m } RID normal_rid = p_normal_map.is_valid() ? p_normal_map->get_rid() : RID(); - VS::get_singleton()->canvas_item_add_texture_rect_region(p_canvas_item, Rect2(p_pos + margin.position, rc.size), atlas->get_rid(), rc, p_modulate, p_transpose, normal_rid); + VS::get_singleton()->canvas_item_add_texture_rect_region(p_canvas_item, Rect2(p_pos + margin.position, rc.size), atlas->get_rid(), rc, p_modulate, p_transpose, normal_rid, filter_clip); } void AtlasTexture::draw_rect(RID p_canvas_item, const Rect2 &p_rect, bool p_tile, const Color &p_modulate, bool p_transpose, const Ref<Texture> &p_normal_map) const { @@ -920,7 +936,7 @@ void AtlasTexture::draw_rect(RID p_canvas_item, const Rect2 &p_rect, bool p_tile Rect2 dr(p_rect.position + margin.position * scale, rc.size * scale); RID normal_rid = p_normal_map.is_valid() ? p_normal_map->get_rid() : RID(); - VS::get_singleton()->canvas_item_add_texture_rect_region(p_canvas_item, dr, atlas->get_rid(), rc, p_modulate, p_transpose, normal_rid); + VS::get_singleton()->canvas_item_add_texture_rect_region(p_canvas_item, dr, atlas->get_rid(), rc, p_modulate, p_transpose, normal_rid, filter_clip); } void AtlasTexture::draw_rect_region(RID p_canvas_item, const Rect2 &p_rect, const Rect2 &p_src_rect, const Color &p_modulate, bool p_transpose, const Ref<Texture> &p_normal_map, bool p_clip_uv) const { @@ -951,7 +967,7 @@ void AtlasTexture::draw_rect_region(RID p_canvas_item, const Rect2 &p_rect, cons Rect2 dr(p_rect.position + ofs * scale, src_c.size * scale); RID normal_rid = p_normal_map.is_valid() ? p_normal_map->get_rid() : RID(); - VS::get_singleton()->canvas_item_add_texture_rect_region(p_canvas_item, dr, atlas->get_rid(), src_c, p_modulate, p_transpose, normal_rid, p_clip_uv); + VS::get_singleton()->canvas_item_add_texture_rect_region(p_canvas_item, dr, atlas->get_rid(), src_c, p_modulate, p_transpose, normal_rid, filter_clip); } bool AtlasTexture::get_rect_region(const Rect2 &p_rect, const Rect2 &p_src_rect, Rect2 &r_rect, Rect2 &r_src_rect) const { @@ -987,6 +1003,7 @@ bool AtlasTexture::get_rect_region(const Rect2 &p_rect, const Rect2 &p_src_rect, } AtlasTexture::AtlasTexture() { + filter_clip = false; } ////////////////////////////////////////// diff --git a/scene/resources/texture.h b/scene/resources/texture.h index 207436e4a7..ee54156647 100644 --- a/scene/resources/texture.h +++ b/scene/resources/texture.h @@ -237,6 +237,7 @@ protected: Ref<Texture> atlas; Rect2 region; Rect2 margin; + bool filter_clip; static void _bind_methods(); @@ -259,6 +260,9 @@ public: void set_margin(const Rect2 &p_margin); Rect2 get_margin() const; + void set_filter_clip(const bool p_enable); + bool has_filter_clip() const; + virtual void draw(RID p_canvas_item, const Point2 &p_pos, const Color &p_modulate = Color(1, 1, 1), bool p_transpose = false, const Ref<Texture> &p_normal_map = Ref<Texture>()) const; virtual void draw_rect(RID p_canvas_item, const Rect2 &p_rect, bool p_tile = false, const Color &p_modulate = Color(1, 1, 1), bool p_transpose = false, const Ref<Texture> &p_normal_map = Ref<Texture>()) const; virtual void draw_rect_region(RID p_canvas_item, const Rect2 &p_rect, const Rect2 &p_src_rect, const Color &p_modulate = Color(1, 1, 1), bool p_transpose = false, const Ref<Texture> &p_normal_map = Ref<Texture>(), bool p_clip_uv = true) const; 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; |