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

Code before:
Point2 GradientTexture2DEditorRect::_get_handle_position(const Handle p_handle) {
	// Get the handle's mouse position in pixels relative to offset.
	return (p_handle == HANDLE_FILL_FROM ? texture->get_fill_from() : texture->get_fill_to()).clamp(Vector2(), Vector2(1, 1)) * size;
}

void GradientTexture2DEditorRect::_update_fill_position() {
	if (handle == HANDLE_NONE) {
		return;
	}

	// Update the texture's fill_from/fill_to property based on mouse input.
	Vector2 percent = ((get_local_mouse_position() - offset) / size).clamp(Vector2(), Vector2(1, 1));
	if (snap_enabled) {
		percent = (percent - Vector2(0.5, 0.5)).snapped(Vector2(snap_size, snap_size)) + Vector2(0.5, 0.5);
	}

	String property_name = handle == HANDLE_FILL_FROM ? "fill_from" : "fill_to";

	EditorUndoRedoManager *undo_redo = EditorUndoRedoManager::get_singleton();
	undo_redo->create_action(vformat(TTR("Set %s"), property_name), UndoRedo::MERGE_ENDS);
	undo_redo->add_do_property(texture.ptr(), property_name, percent);
	undo_redo->add_undo_property(texture.ptr(), property_name, handle == HANDLE_FILL_FROM ? texture->get_fill_from() : texture->get_fill_to());
	undo_redo->commit_action();
}

void GradientTexture2DEditorRect::gui_input(const Ref<InputEvent> &p_event) {
	// Grab/release handle.
	const Ref<InputEventMouseButton> mb = p_event;
	if (mb.is_valid() && mb->get_button_index() == MouseButton::LEFT) {
		if (mb->is_pressed()) {
			Point2 mouse_position = mb->get_position() - offset;
			if (Rect2(_get_handle_position(HANDLE_FILL_FROM).round() - handle_size / 2, handle_size).has_point(mouse_position)) {
				handle = HANDLE_FILL_FROM;
			} else if (Rect2(_get_handle_position(HANDLE_FILL_TO).round() - handle_size / 2, handle_size).has_point(mouse_position)) {
				handle = HANDLE_FILL_TO;
			} else {
				handle = HANDLE_NONE;
			}
		} else {
			_update_fill_position();
			handle = HANDLE_NONE;
		}
	}

	// Move handle.
	const Ref<InputEventMouseMotion> mm = p_event;
	if (mm.is_valid()) {
		_update_fill_position();
	}
}


Review comment (suggestion):
```suggestion
	const StringName property_name = (grabbed == HANDLE_FROM) ? "fill_from" : "fill_to";
```

Code after:
void GradientTexture2DEdit::_on_mouse_exited() {
	if (hovered != HANDLE_NONE) {
		hovered = HANDLE_NONE;
		queue_redraw();
	}
}

Point2 GradientTexture2DEdit::_get_handle_pos(const Handle p_handle) {
	// Get the handle's mouse position in pixels relative to offset.
	return (p_handle == HANDLE_FROM ? texture->get_fill_from() : texture->get_fill_to()).clamp(Vector2(), Vector2(1, 1)) * size;
}

GradientTexture2DEdit::Handle GradientTexture2DEdit::get_handle_at(const Vector2 &p_pos) {
	Point2 from_pos = _get_handle_pos(HANDLE_FROM);
	Point2 to_pos = _get_handle_pos(HANDLE_TO);
	// If both handles are at the position, grab the one that's closer.
	if (p_pos.distance_squared_to(from_pos) < p_pos.distance_squared_to(to_pos)) {
		return Rect2(from_pos.round() - handle_size / 2, handle_size).has_point(p_pos) ? HANDLE_FROM : HANDLE_NONE;
	} else {
		return Rect2(to_pos.round() - handle_size / 2, handle_size).has_point(p_pos) ? HANDLE_TO : HANDLE_NONE;
	}
}

void GradientTexture2DEdit::set_fill_pos(const Vector2 &p_pos) {
	if (p_pos.is_equal_approx(initial_grab_pos)) {
		return;
	}

	const StringName property_name = (grabbed == HANDLE_FROM) ? "fill_from" : "fill_to";
	EditorUndoRedoManager *undo_redo = EditorUndoRedoManager::get_singleton();
	undo_redo->create_action(TTR("Move GradientTexture2D Fill Point"));
	undo_redo->add_do_property(texture.ptr(), property_name, p_pos);
	undo_redo->add_undo_property(texture.ptr(), property_name, initial_grab_pos);
	undo_redo->commit_action();
}

void GradientTexture2DEdit::gui_input(const Ref<InputEvent> &p_event) {
	const Ref<InputEventMouseButton> mb = p_event;
	if (mb.is_valid()) {
		if (mb->get_button_index() == MouseButton::LEFT) {
			if (mb->is_pressed()) {
				grabbed = get_handle_at(mb->get_position() - offset);

				if (grabbed != HANDLE_NONE) {
					initial_grab_pos = _get_handle_pos(grabbed) / size;
					queue_redraw();
				}
			} else {
				// Release the handle.
				if (grabbed != HANDLE_NONE) {
					set_fill_pos(_get_handle_pos(grabbed) / size);