ronantakizawa/codereview-bench huggingface dataset:
Repository: godotengine/godot
File: scene/main/node.cpp (C++)

Code before:

			Variant value = N->get()->get(name).duplicate(true);

			if (E.usage & PROPERTY_USAGE_ALWAYS_DUPLICATE) {
				Resource *res = Object::cast_to<Resource>(value);
				if (res) { // Duplicate only if it's a resource
					current_node->set(name, res->duplicate());
				}

			} else {
				current_node->set(name, value);
			}
		}
	}

	if (get_name() != String()) {
		node->set_name(get_name());
	}

#ifdef TOOLS_ENABLED
	if ((p_flags & DUPLICATE_FROM_EDITOR) && r_duplimap) {
		r_duplimap->insert(this, node);
	}
#endif

	if (p_flags & DUPLICATE_GROUPS) {
		List<GroupInfo> gi;
		get_groups(&gi);
		for (const GroupInfo &E : gi) {
#ifdef TOOLS_ENABLED
			if ((p_flags & DUPLICATE_FROM_EDITOR) && !E.persistent) {
				continue;
			}
#endif

			node->add_to_group(E.name, E.persistent);
		}
	}

	for (int i = 0; i < get_child_count(); i++) {
		if (get_child(i)->data.parent_owned) {
			continue;
		}
		if (instantiated && get_child(i)->data.owner == this) {
			continue; //part of instance
		}

		Node *dup = get_child(i)->_duplicate(p_flags, r_duplimap);
		if (!dup) {
			memdelete(node);
			return nullptr;

Review comment (suggestion):
```suggestion
									arr[i] = current_node->get_node_or_null(get_path_to(property_node));
```

Code after:

	for (int i = 0; i < get_child_count(); i++) {
		if (get_child(i)->data.parent_owned) {
			continue;
		}
		if (instantiated && get_child(i)->data.owner == this) {
			continue; //part of instance
		}

		Node *dup = get_child(i)->_duplicate(p_flags, r_duplimap);
		if (!dup) {
			memdelete(node);
			return nullptr;
		}

		node->add_child(dup);
		if (i < node->get_child_count() - 1) {
			node->move_child(dup, i);
		}
	}

	for (const Node *&E : hidden_roots) {
		Node *parent = node->get_node(get_path_to(E->data.parent));
		if (!parent) {
			memdelete(node);
			return nullptr;
		}

		Node *dup = E->_duplicate(p_flags, r_duplimap);
		if (!dup) {
			memdelete(node);
			return nullptr;
		}

		parent->add_child(dup);
		int pos = E->get_index();

		if (pos < parent->get_child_count() - 1) {
			parent->move_child(dup, pos);
		}
	}

	for (List<const Node *>::Element *N = node_tree.front(); N; N = N->next()) {
		Node *current_node = node->get_node(get_path_to(N->get()));
		ERR_CONTINUE(!current_node);

		if (p_flags & DUPLICATE_SCRIPTS) {
			bool is_valid = false;
			Variant scr = N->get()->get(script_property_name, &is_valid);
			if (is_valid) {
				current_node->set(script_property_name, scr);
Repository: godotengine/godot
File: scene/main/node.cpp (C++)

Code before:
		N->get()->get_property_list(&plist);

		for (const PropertyInfo &E : plist) {
			if (!(E.usage & PROPERTY_USAGE_STORAGE)) {
				continue;
			}
			String name = E.name;
			if (name == script_property_name) {
				continue;
			}

			Variant value = N->get()->get(name).duplicate(true);

			if (E.usage & PROPERTY_USAGE_ALWAYS_DUPLICATE) {
				Resource *res = Object::cast_to<Resource>(value);
				if (res) { // Duplicate only if it's a resource
					current_node->set(name, res->duplicate());
				}

			} else {
				current_node->set(name, value);
			}
		}
	}

	if (get_name() != String()) {
		node->set_name(get_name());
	}

#ifdef TOOLS_ENABLED
	if ((p_flags & DUPLICATE_FROM_EDITOR) && r_duplimap) {
		r_duplimap->insert(this, node);
	}
#endif

	if (p_flags & DUPLICATE_GROUPS) {
		List<GroupInfo> gi;
		get_groups(&gi);
		for (const GroupInfo &E : gi) {
#ifdef TOOLS_ENABLED
			if ((p_flags & DUPLICATE_FROM_EDITOR) && !E.persistent) {
				continue;
			}
#endif

			node->add_to_group(E.name, E.persistent);
		}
	}

	for (int i = 0; i < get_child_count(); i++) {
		if (get_child(i)->data.parent_owned) {

Review comment (suggestion):
```suggestion
							value = current_node->get_node_or_null(get_path_to(property_node));
```

Code after:
		for (const GroupInfo &E : gi) {
#ifdef TOOLS_ENABLED
			if ((p_flags & DUPLICATE_FROM_EDITOR) && !E.persistent) {
				continue;
			}
#endif

			node->add_to_group(E.name, E.persistent);
		}
	}

	for (int i = 0; i < get_child_count(); i++) {
		if (get_child(i)->data.parent_owned) {
			continue;
		}
		if (instantiated && get_child(i)->data.owner == this) {
			continue; //part of instance
		}

		Node *dup = get_child(i)->_duplicate(p_flags, r_duplimap);
		if (!dup) {
			memdelete(node);
			return nullptr;
		}

		node->add_child(dup);
		if (i < node->get_child_count() - 1) {
			node->move_child(dup, i);
		}
	}

	for (const Node *&E : hidden_roots) {
		Node *parent = node->get_node(get_path_to(E->data.parent));
		if (!parent) {
			memdelete(node);
			return nullptr;
		}

		Node *dup = E->_duplicate(p_flags, r_duplimap);
		if (!dup) {
			memdelete(node);
			return nullptr;
		}

		parent->add_child(dup);
		int pos = E->get_index();

		if (pos < parent->get_child_count() - 1) {
			parent->move_child(dup, pos);
		}
	}
Repository: godotengine/godot
File: scene/main/node.cpp (C++)

Code before:

			if (E.usage & PROPERTY_USAGE_ALWAYS_DUPLICATE) {
				Resource *res = Object::cast_to<Resource>(value);
				if (res) { // Duplicate only if it's a resource
					current_node->set(name, res->duplicate());
				}

			} else {
				current_node->set(name, value);
			}
		}
	}

	if (get_name() != String()) {
		node->set_name(get_name());
	}

#ifdef TOOLS_ENABLED
	if ((p_flags & DUPLICATE_FROM_EDITOR) && r_duplimap) {
		r_duplimap->insert(this, node);
	}
#endif

	if (p_flags & DUPLICATE_GROUPS) {
		List<GroupInfo> gi;
		get_groups(&gi);
		for (const GroupInfo &E : gi) {
#ifdef TOOLS_ENABLED
			if ((p_flags & DUPLICATE_FROM_EDITOR) && !E.persistent) {
				continue;
			}
#endif

			node->add_to_group(E.name, E.persistent);
		}
	}

	for (int i = 0; i < get_child_count(); i++) {
		if (get_child(i)->data.parent_owned) {
			continue;
		}
		if (instantiated && get_child(i)->data.owner == this) {
			continue; //part of instance
		}

		Node *dup = get_child(i)->_duplicate(p_flags, r_duplimap);
		if (!dup) {
			memdelete(node);
			return nullptr;
		}


Review comment (suggestion):
Wouldn't this also need to recurse into deeper array levels, dictionaries, etc.? I think we have some code around to traverse a `Variant`. If not already there, I'd suggest adding something like `PropertyUtils::visit_objects(p_variant, p_visitor_callback)`.

Code after:
		if (get_child(i)->data.parent_owned) {
			continue;
		}
		if (instantiated && get_child(i)->data.owner == this) {
			continue; //part of instance
		}

		Node *dup = get_child(i)->_duplicate(p_flags, r_duplimap);
		if (!dup) {
			memdelete(node);
			return nullptr;
		}

		node->add_child(dup);
		if (i < node->get_child_count() - 1) {
			node->move_child(dup, i);
		}
	}

	for (const Node *&E : hidden_roots) {
		Node *parent = node->get_node(get_path_to(E->data.parent));
		if (!parent) {
			memdelete(node);
			return nullptr;
		}

		Node *dup = E->_duplicate(p_flags, r_duplimap);
		if (!dup) {
			memdelete(node);
			return nullptr;
		}

		parent->add_child(dup);
		int pos = E->get_index();

		if (pos < parent->get_child_count() - 1) {
			parent->move_child(dup, pos);
		}
	}

	for (List<const Node *>::Element *N = node_tree.front(); N; N = N->next()) {
		Node *current_node = node->get_node(get_path_to(N->get()));
		ERR_CONTINUE(!current_node);

		if (p_flags & DUPLICATE_SCRIPTS) {
			bool is_valid = false;
			Variant scr = N->get()->get(script_property_name, &is_valid);
			if (is_valid) {
				current_node->set(script_property_name, scr);
			}
		}
Repository: godotengine/godot
File: editor/plugins/polygon_2d_editor_plugin.h (C/C++)

Code before:
	int uv_create_prev_internal_vertices = 0;
	Array uv_create_bones_prev;
	Array polygons_prev;

	Vector2 uv_create_to;
	int point_drag_index;
	bool uv_drag;
	bool uv_create;
	Vector<int> polygon_create;
	UVMode uv_move_current;
	Vector2 uv_drag_from;
	bool updating_uv_scroll;

	AcceptDialog *error = nullptr;

	Button *button_uv = nullptr;

	bool use_snap;
	bool snap_show_grid;
	Vector2 snap_offset;
	Vector2 snap_step;

	virtual void _menu_option(int p_option) override;

	void _cancel_editing();
	void _update_polygon_editing_state();

	void _uv_scroll_changed(real_t);
	void _uv_input(const Ref<InputEvent> &p_input);
	void _uv_draw();
	void _uv_mode(int p_mode);

	void _set_use_snap(bool p_use);
	void _set_show_grid(bool p_show);
	void _set_snap_off_x(real_t p_val);
	void _set_snap_off_y(real_t p_val);
	void _set_snap_step_x(real_t p_val);
	void _set_snap_step_y(real_t p_val);

	void _uv_edit_mode_select(int p_mode);
	void _uv_edit_popup_hide();
	void _bone_paint_selected(int p_index);

	int _get_polygon_count() const override;

protected:
	virtual Node2D *_get_node() const override;
	virtual void _set_node(Node *p_polygon) override;

	virtual Vector2 _get_offset(int p_idx) const override;


Review comment (suggestion):
```suggestion
	void _update_zoom_and_pan(bool p_zoom_at_center);
```
Prefix arguments with `p_`

Code after:
	Array uv_create_bones_prev;
	Array polygons_prev;

	Vector2 uv_create_to;
	int point_drag_index;
	bool uv_drag;
	bool uv_create;
	Vector<int> polygon_create;
	UVMode uv_move_current;
	Vector2 uv_drag_from;

	AcceptDialog *error = nullptr;

	Button *button_uv = nullptr;

	bool use_snap;
	bool snap_show_grid;
	Vector2 snap_offset;
	Vector2 snap_step;

	virtual void _menu_option(int p_option) override;

	void _cancel_editing();
	void _update_polygon_editing_state();

	void _center_view();
	void _update_zoom_and_pan(bool p_zoom_at_center);
	void _uv_input(const Ref<InputEvent> &p_input);
	void _uv_draw();
	void _uv_mode(int p_mode);

	void _set_use_snap(bool p_use);
	void _set_show_grid(bool p_show);
	void _set_snap_off_x(real_t p_val);
	void _set_snap_off_y(real_t p_val);
	void _set_snap_step_x(real_t p_val);
	void _set_snap_step_y(real_t p_val);

	void _uv_edit_mode_select(int p_mode);
	void _uv_edit_popup_hide();
	void _bone_paint_selected(int p_index);

	int _get_polygon_count() const override;

protected:
	virtual Node2D *_get_node() const override;
	virtual void _set_node(Node *p_polygon) override;

	virtual Vector2 _get_offset(int p_idx) const override;

	virtual bool _has_uv() const override { return true; };
Repository: godotengine/godot
File: editor/plugins/polygon_2d_editor_plugin.h (C/C++)

Code before:
	SpinBox *bone_paint_radius = nullptr;
	Label *bone_paint_radius_label = nullptr;
	bool bone_painting;
	int bone_painting_bone = 0;
	Vector<float> prev_weights;
	Vector2 bone_paint_pos;
	AcceptDialog *grid_settings = nullptr;

	void _sync_bones();
	void _update_bone_list();

	Vector2 uv_draw_ofs;
	real_t uv_draw_zoom;
	Vector<Vector2> points_prev;
	Vector<Vector2> uv_create_uv_prev;
	Vector<Vector2> uv_create_poly_prev;
	Vector<Color> uv_create_colors_prev;
	int uv_create_prev_internal_vertices = 0;
	Array uv_create_bones_prev;
	Array polygons_prev;

	Vector2 uv_create_to;
	int point_drag_index;
	bool uv_drag;
	bool uv_create;
	Vector<int> polygon_create;
	UVMode uv_move_current;
	Vector2 uv_drag_from;
	bool updating_uv_scroll;

	AcceptDialog *error = nullptr;

	Button *button_uv = nullptr;

	bool use_snap;
	bool snap_show_grid;
	Vector2 snap_offset;
	Vector2 snap_step;

	virtual void _menu_option(int p_option) override;

	void _cancel_editing();
	void _update_polygon_editing_state();

	void _uv_scroll_changed(real_t);
	void _uv_input(const Ref<InputEvent> &p_input);
	void _uv_draw();
	void _uv_mode(int p_mode);

	void _set_use_snap(bool p_use);
	void _set_show_grid(bool p_show);

Review comment (suggestion):
This can be removed. Use `set_value_no_signal()` or `set_block_signals()` on the scrollbars.

Code after:
	Label *bone_paint_radius_label = nullptr;
	bool bone_painting;
	int bone_painting_bone = 0;
	Vector<float> prev_weights;
	Vector2 bone_paint_pos;
	AcceptDialog *grid_settings = nullptr;

	void _sync_bones();
	void _update_bone_list();

	Vector2 uv_draw_ofs;
	real_t uv_draw_zoom;
	Vector<Vector2> points_prev;
	Vector<Vector2> uv_create_uv_prev;
	Vector<Vector2> uv_create_poly_prev;
	Vector<Color> uv_create_colors_prev;
	int uv_create_prev_internal_vertices = 0;
	Array uv_create_bones_prev;
	Array polygons_prev;

	Vector2 uv_create_to;
	int point_drag_index;
	bool uv_drag;
	bool uv_create;
	Vector<int> polygon_create;
	UVMode uv_move_current;
	Vector2 uv_drag_from;

	AcceptDialog *error = nullptr;

	Button *button_uv = nullptr;

	bool use_snap;
	bool snap_show_grid;
	Vector2 snap_offset;
	Vector2 snap_step;

	virtual void _menu_option(int p_option) override;

	void _cancel_editing();
	void _update_polygon_editing_state();

	void _center_view();
	void _update_zoom_and_pan(bool p_zoom_at_center);
	void _uv_input(const Ref<InputEvent> &p_input);
	void _uv_draw();
	void _uv_mode(int p_mode);

	void _set_use_snap(bool p_use);
	void _set_show_grid(bool p_show);
	void _set_snap_off_x(real_t p_val);
Repository: godotengine/godot
File: platform/android/java/lib/src/org/godotengine/godot/input/GodotGestureHandler.kt (Kotlin)

Code before:
				event.isFromSource(InputDevice.SOURCE_MOUSE_RELATIVE)
			} else {
				false
			}
			GodotInputHandler.handleMouseEvent(
				event.actionMasked,
				MotionEvent.BUTTON_SECONDARY,
				event.x,
				event.y,
				0f,
				0f,
				false,
				sourceMouseRelative
			)
			return true
		}
		return false
	}

	override fun onDoubleTapEvent(event: MotionEvent): Boolean {
		if (event.actionMasked == MotionEvent.ACTION_UP) {
			nextDownIsDoubleTap = false
			GodotInputHandler.handleMotionEvent(event)
		} else if (event.actionMasked == MotionEvent.ACTION_MOVE && panningAndScalingEnabled == false) {
			GodotInputHandler.handleMotionEvent(event)
		}

		return true
	}

	override fun onDoubleTap(event: MotionEvent): Boolean {
		nextDownIsDoubleTap = true
		return true
	}

	override fun onScroll(
		originEvent: MotionEvent?,
		terminusEvent: MotionEvent,
		distanceX: Float,
		distanceY: Float
	): Boolean {
		if (scaleInProgress) {
			if (dragInProgress) {
				if (originEvent != null) {
					// Cancel the drag
					GodotInputHandler.handleMotionEvent(
						originEvent.source,
						MotionEvent.ACTION_CANCEL,
						originEvent.buttonState,
						originEvent.x,
						originEvent.y

Review comment (suggestion):
```suggestion
			if (lastDragX != event.getX(0) || lastDragY != event.getY(0)) {
```

Code after:
	}

	private fun onActionMove(event: MotionEvent): Boolean {
		if (contextClickInProgress) {
			val sourceMouseRelative = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
				event.isFromSource(InputDevice.SOURCE_MOUSE_RELATIVE)
			} else {
				false
			}
			GodotInputHandler.handleMouseEvent(
				event.actionMasked,
				MotionEvent.BUTTON_SECONDARY,
				event.x,
				event.y,
				0f,
				0f,
				false,
				sourceMouseRelative
			)
			return true
		} else if (!scaleInProgress) {
			// The 'onScroll' event is triggered with a long delay.
			// Force the 'InputEventScreenDrag' event earlier here.
			// We don't toggle 'dragInProgress' here so that the scaling logic can override the drag operation if needed.
			// Once the 'onScroll' event kicks-in, 'dragInProgress' will be properly set.
			if (lastDragX != event.getX(0) || lastDragY != event.getY(0)) {
				lastDragX = event.getX(0)
				lastDragY = event.getY(0)
				GodotInputHandler.handleMotionEvent(event)
				return true
			}
		}
		return false
	}

	override fun onDoubleTapEvent(event: MotionEvent): Boolean {
		if (event.actionMasked == MotionEvent.ACTION_UP) {
			nextDownIsDoubleTap = false
			GodotInputHandler.handleMotionEvent(event)
		} else if (event.actionMasked == MotionEvent.ACTION_MOVE && panningAndScalingEnabled == false) {
			GodotInputHandler.handleMotionEvent(event)
		}

		return true
	}

	override fun onDoubleTap(event: MotionEvent): Boolean {
		nextDownIsDoubleTap = true
		return true
	}
Repository: godotengine/godot
File: editor/plugins/sprite_2d_editor_plugin.h (C/C++)

Code before:
	MenuButton *options = nullptr;

	ConfirmationDialog *outline_dialog = nullptr;

	AcceptDialog *err_dialog = nullptr;

	ConfirmationDialog *debug_uv_dialog = nullptr;
	Control *debug_uv = nullptr;
	Vector<Vector2> uv_lines;
	Vector<Vector<Vector2>> outline_lines;
	Vector<Vector<Vector2>> computed_outline_lines;
	Vector<Vector2> computed_vertices;
	Vector<Vector2> computed_uv;
	Vector<int> computed_indices;

	SpinBox *simplification = nullptr;
	SpinBox *grow_pixels = nullptr;
	SpinBox *shrink_pixels = nullptr;
	Button *update_preview = nullptr;

	void _menu_option(int p_option);

	//void _create_uv_lines();
	friend class Sprite2DEditorPlugin;

	void _debug_uv_draw();
	void _popup_debug_uv_dialog();
	void _update_mesh_data();

	void _create_node();
	void _convert_to_mesh_2d_node();
	void _convert_to_polygon_2d_node();
	void _create_collision_polygon_2d_node();
	void _create_light_occluder_2d_node();

	void _add_as_sibling_or_child(Node *p_own_node, Node *p_new_node);

protected:
	void _node_removed(Node *p_node);
	void _notification(int p_what);
	static void _bind_methods();

public:
	void edit(Sprite2D *p_sprite);
	Sprite2DEditor();
};

class Sprite2DEditorPlugin : public EditorPlugin {
	GDCLASS(Sprite2DEditorPlugin, EditorPlugin);

	Sprite2DEditor *sprite_editor = nullptr;

Review comment (suggestion):
```suggestion
	real_t draw_zoom = 1.0;
	bool updating_zoom = false;
	bool center_on_draw = false;
```
Primitive types should be initialized.
`updating_zoom` could be removed like in #83731

Code after:

	Sprite2D *node = nullptr;

	MenuButton *options = nullptr;

	ConfirmationDialog *outline_dialog = nullptr;

	AcceptDialog *err_dialog = nullptr;

	ConfirmationDialog *debug_uv_dialog = nullptr;
	Panel *debug_uv = nullptr;
	Vector<Vector2> uv_lines;
	Vector<Vector<Vector2>> outline_lines;
	Vector<Vector<Vector2>> computed_outline_lines;
	Vector<Vector2> computed_vertices;
	Vector<Vector2> computed_uv;
	Vector<int> computed_indices;

	HScrollBar *h_scroll = nullptr;
	VScrollBar *v_scroll = nullptr;
	EditorZoomWidget *zoom_widget = nullptr;
	Ref<ViewPanner> panner;
	Vector2 draw_offset;
	real_t draw_zoom = 1.0;

	SpinBox *simplification = nullptr;
	SpinBox *grow_pixels = nullptr;
	SpinBox *shrink_pixels = nullptr;
	Button *update_preview = nullptr;

	void _menu_option(int p_option);

	//void _create_uv_lines();
	friend class Sprite2DEditorPlugin;

	void _debug_uv_input(const Ref<InputEvent> &p_input);
	void _debug_uv_draw();
	void _popup_debug_uv_dialog();
	void _center_view();
	void _pan_callback(Vector2 p_scroll_vec, Ref<InputEvent> p_event);
	void _zoom_callback(float p_zoom_factor, Vector2 p_origin, Ref<InputEvent> p_event);
	void _update_zoom_and_pan(bool p_zoom_at_center);
	void _update_mesh_data();

	void _create_node();
	void _convert_to_mesh_2d_node();
	void _convert_to_polygon_2d_node();
	void _create_collision_polygon_2d_node();
	void _create_light_occluder_2d_node();

	void _add_as_sibling_or_child(Node *p_own_node, Node *p_new_node);
Repository: godotengine/godot
File: editor/plugins/texture_region_editor_plugin.cpp (C++)

Code before:
	if (res_stylebox.is_valid()) {
		return res_stylebox->get_texture();
	}
	if (res_atlas_texture.is_valid()) {
		return res_atlas_texture->get_atlas();
	}

	return Ref<Texture2D>();
}

Rect2 TextureRegionEditor::_get_edited_object_region() const {
	Rect2 region;

	if (node_sprite_2d) {
		region = node_sprite_2d->get_region_rect();
	} else if (node_sprite_3d) {
		region = node_sprite_3d->get_region_rect();
	} else if (node_ninepatch) {
		region = node_ninepatch->get_region_rect();
	} else if (res_stylebox.is_valid()) {
		region = res_stylebox->get_region_rect();
	} else if (res_atlas_texture.is_valid()) {
		region = res_atlas_texture->get_region();
	}

	if (region == Rect2()) {
		region = Rect2(Vector2(), _get_edited_object_texture()->get_size());
	}

	return region;
}

void TextureRegionEditor::_texture_changed() {
	if (!is_visible()) {
		return;
	}
	_edit_region();
}

void TextureRegionEditor::_edit_region() {
	Ref<Texture2D> object_texture = _get_edited_object_texture();
	if (object_texture.is_null()) {
		_zoom_reset();
		hscroll->hide();
		vscroll->hide();
		texture_preview->queue_redraw();
		texture_overlay->queue_redraw();
		return;
	}

	CanvasItem::TextureFilter filter = CanvasItem::TEXTURE_FILTER_NEAREST_WITH_MIPMAPS;

Review comment (suggestion):
```suggestion
	const Ref<Texture2D> object_texture = _get_edited_object_texture();
```

Code after:
	if (res_stylebox.is_valid()) {
		return res_stylebox->get_texture();
	}
	if (res_atlas_texture.is_valid()) {
		return res_atlas_texture->get_atlas();
	}

	return Ref<Texture2D>();
}

Rect2 TextureRegionEditor::_get_edited_object_region() const {
	Rect2 region;

	if (node_sprite_2d) {
		region = node_sprite_2d->get_region_rect();
	} else if (node_sprite_3d) {
		region = node_sprite_3d->get_region_rect();
	} else if (node_ninepatch) {
		region = node_ninepatch->get_region_rect();
	} else if (res_stylebox.is_valid()) {
		region = res_stylebox->get_region_rect();
	} else if (res_atlas_texture.is_valid()) {
		region = res_atlas_texture->get_region();
	}

	const Ref<Texture2D> object_texture = _get_edited_object_texture();
	if (region == Rect2() && object_texture.is_valid()) {
		region = Rect2(Vector2(), object_texture->get_size());
	}

	return region;
}

void TextureRegionEditor::_texture_changed() {
	if (!is_visible()) {
		return;
	}
	_edit_region();
}

void TextureRegionEditor::_edit_region() {
	const Ref<Texture2D> object_texture = _get_edited_object_texture();
	if (object_texture.is_null()) {
		_zoom_reset();
		hscroll->hide();
		vscroll->hide();
		texture_preview->queue_redraw();
		texture_overlay->queue_redraw();
		return;
	}