Draw a slate widget at mouse location

Hello every one… I want to replace my mouse cursor with a slate widget.

When I am using SCanvas, the location of the slate widget is appearing a lot off. Anyway how to do it?

IconLocation.Bind(this, &SCursorItemWidget::GetCursorLocation);

	ChildSlot
		[
			SNew(SCanvas)
			.Visibility(EVisibility::HitTestInvisible)
			+ SCanvas::Slot()
			.Position(IconLocation)
			.Size(FVector2D(64,64))
			.HAlign(HAlign_Center)
			.VAlign(VAlign_Center)
			[
                        ]
                ]

I am getting the mouse position with something like this

GameHUD->PC->GetMousePosition(MouseLoc.X, MouseLoc.Y);

But the mouse position is a lot off… Something similar to half of what it should be.

Image of what is wrong with .Position of canvas.

I am getting another problem. When I draw the mouse like this, any slate widget present below this is not responding to mouse clicks.

Hi,

So you want to spawn widget at mouse location or make it follow mouse cursor?

Either way, you dont have to use HUD/PlayerController to receive mouse position, try to use FSlateApplication::Get().GetCursorPos()

Cheers

Doesn’t work… Kind of works better than the previous thing but I think there is a factor which is missing.

UE 4.7 supports software cursors for Slate and UMG. There are settings for this where you can bind a widget blueprint to a cursor type (Project Settings → User Interface), but you can also do it in code via FViewport::MapCursor.

Are you trying to do a drag-and-drop? Slate has support for drag-and-drop already, including grabbing a widget for the drag. Slate - Drag & Drop - UI - Epic Developer Community Forums

Well dragging and dropping wont work for this exactly a lot of other things that are in work here.

Is that 4.7 change is currently in 4.7 preview? Any other method to do what I am looking for now?

It should be, if it isn’t then it must’ve been added after 4.7 was branched, so will be in 4.8 instead.

Your second video looks like your cursor position is in screen-space, rather than in the space of the widget you’re transforming against. You might want to take a look at FGeometry::AbsoluteToLocal to see if that can help you here (you’ll actually need to get the widget geometry somehow to perform an accurate transformation).

I couldn’t find any place where I could get the FGeometry.

There is a GetContentScale but I think that is different.

You can get widget geometry in Tick event. Simply override it in your widget and cache it in variable for further use.

So you have to add an FGeometry CachedGeometry member in your widget class and your tick event should look like this:

 virtual void Tick( const FGeometry& AllottedGeometry, const double InCurrentTime, const float InDeltaTime ) override
{
CachedGeometry = AllottedGeometry;
}

then you can use CachedGeometry.AbsoluteToLocal function wherever you want

Thank you problem solved. But I have a question for Jamie. When I am binding this way, there is a 1 second delay when the mouse move. Will that delay be present with the software cursor you mentioned?

Thanks so much, why this is not cached in the widgets? Anyhow, finally now I can scale things properly!