Repository: godotengine/godot
File: editor/plugins/polygon_2d_editor_plugin.cpp (C++)

Code before:
}

void Polygon2DEditor::_uv_scroll_changed(real_t) {
	if (updating_uv_scroll) {
		return;
	}

	uv_draw_ofs.x = uv_hscroll->get_value();
	uv_draw_ofs.y = uv_vscroll->get_value();
	uv_draw_zoom = uv_zoom->get_value();
	uv_edit_draw->queue_redraw();
}

void Polygon2DEditor::_uv_draw() {
	if (!uv_edit->is_visible() || !_get_node()) {
		return;
	}

	Ref<Texture2D> base_tex = node->get_texture();
	if (base_tex.is_null()) {
		return;
	}

	String warning;

	Transform2D mtx;
	mtx.columns[2] = -uv_draw_ofs;
	mtx.scale_basis(Vector2(uv_draw_zoom, uv_draw_zoom));

	// Draw texture as a background if editing uvs or no uv mapping exist.
	if (uv_edit_mode[0]->is_pressed() || uv_mode == UV_MODE_CREATE || node->get_polygon().is_empty() || node->get_uv().size() != node->get_polygon().size()) {
		Transform2D texture_transform = Transform2D(node->get_texture_rotation(), node->get_texture_offset());
		texture_transform.scale(node->get_texture_scale());
		texture_transform.affine_invert();
		RS::get_singleton()->canvas_item_add_set_transform(uv_edit_draw->get_canvas_item(), mtx * texture_transform);
		uv_edit_draw->draw_texture(base_tex, Point2());
		RS::get_singleton()->canvas_item_add_set_transform(uv_edit_draw->get_canvas_item(), Transform2D());
		preview_polygon->hide();
	} else {
		preview_polygon->set_transform(mtx);
		// Keep in sync with newly added Polygon2D properties (when relevant).
		preview_polygon->set_texture(node->get_texture());
		preview_polygon->set_texture_offset(node->get_texture_offset());
		preview_polygon->set_texture_rotation(node->get_texture_rotation());
		preview_polygon->set_texture_scale(node->get_texture_scale());
		preview_polygon->set_texture_filter(node->get_texture_filter_in_tree());
		preview_polygon->set_texture_repeat(node->get_texture_repeat_in_tree());
		preview_polygon->set_polygon(node->get_polygon());
		preview_polygon->set_uv(node->get_uv());
		preview_polygon->set_invert(node->get_invert());
		preview_polygon->set_invert_border(node->get_invert_border());

Review comment (suggestion):
```suggestion
void Polygon2DEditor::_update_zoom_and_pan(bool p_zoom_at_center) {
```

Code after:
	Size2 offset = (texture_size - uv_edit_draw->get_size() / uv_draw_zoom) / 2;
	uv_hscroll->set_value_no_signal(offset.x);
	uv_vscroll->set_value_no_signal(offset.y);
	_update_zoom_and_pan(false);
}

void Polygon2DEditor::_uv_pan_callback(Vector2 p_scroll_vec, Ref<InputEvent> p_event) {
	uv_hscroll->set_value_no_signal(uv_hscroll->get_value() - p_scroll_vec.x / uv_draw_zoom);
	uv_vscroll->set_value_no_signal(uv_vscroll->get_value() - p_scroll_vec.y / uv_draw_zoom);
	_update_zoom_and_pan(false);
}

void Polygon2DEditor::_uv_zoom_callback(float p_zoom_factor, Vector2 p_origin, Ref<InputEvent> p_event) {
	zoom_widget->set_zoom(uv_draw_zoom * p_zoom_factor);
	uv_draw_ofs += p_origin / uv_draw_zoom - p_origin / zoom_widget->get_zoom();
	uv_hscroll->set_value_no_signal(uv_draw_ofs.x);
	uv_vscroll->set_value_no_signal(uv_draw_ofs.y);
	_update_zoom_and_pan(false);
}

void Polygon2DEditor::_update_zoom_and_pan(bool p_zoom_at_center) {
	uv_draw_ofs = Vector2(uv_hscroll->get_value(), uv_vscroll->get_value());
	real_t previous_zoom = uv_draw_zoom;
	uv_draw_zoom = zoom_widget->get_zoom();
	if (p_zoom_at_center) {
		Vector2 center = uv_edit_draw->get_size() / 2;
		uv_draw_ofs += center / previous_zoom - center / uv_draw_zoom;
	}

	Point2 min_corner;
	Point2 max_corner;
	if (node->get_texture().is_valid()) {
		max_corner += node->get_texture()->get_size();
	}

	Vector<Vector2> points = uv_edit_mode[0]->is_pressed() ? node->get_uv() : node->get_polygon();
	for (int i = 0; i < points.size(); i++) {
		min_corner = min_corner.min(points[i]);
		max_corner = max_corner.max(points[i]);
	}
	Size2 page_size = uv_edit_draw->get_size() / uv_draw_zoom;
	Vector2 margin = Vector2(50, 50) * EDSCALE / uv_draw_zoom;
	min_corner -= page_size - margin;
	max_corner += page_size - margin;

	uv_hscroll->set_block_signals(true);
	uv_hscroll->set_min(min_corner.x);
	uv_hscroll->set_max(max_corner.x);
	uv_hscroll->set_page(page_size.x);
	uv_hscroll->set_value(uv_draw_ofs.x);
	uv_hscroll->set_block_signals(false);