CursorDecorator is not a regular window, you can actually think of it as a container to other windgets. You wont be able to resize or move it with your mouse inside game- you can only do this via code. I didnt mention that but you also have to clean up after youre done using this window or else SlateApplication will crash. To remove window from memory you just call RequestWindowDestroy on a window in your end game code or in Widget’s destructor. I prepared a sample code presenting usage of this method. This is just a simple widget - SMyOverlay
, that extends SOverlay
widget and controls behaviour of mentioned window. All you have to do is call GEngine->GameViewport->AddViewportWidgetContent(SAssignNew(OverlayWidget, SMyOverlay));
somewhere in you game begin code and then call OverlayWidget->SetWindowContainerVisibility(true/false)
to show or hide window whenever you want.
Code should be easy to understand but if you have any problems let me know.
#pragma once
#include "Slate.h"
class SMyOverlay : public SOverlay
{
public:
SLATE_BEGIN_ARGS(SMyOverlay)
{}
SLATE_SUPPORTS_SLOT(SOverlay::FOverlaySlot)
SLATE_END_ARGS()
~SMyOverlay()
{
// REMEMBER TO CLEAN UP ! ! !
if (WindowContainer.IsValid())
{
WindowContainer->RequestDestroyWindow();
}
WindowContainer.Reset();
}
void Construct(const FArguments& InArgs)
{
WindowContainer = SWindow::MakeCursorDecorator();
FSlateApplication::Get().AddWindow(WindowContainer.ToSharedRef(), false);
WindowContainer->SetContent(
// Im using Stooltip only because it looks nicer than empty window
SNew(SToolTip)
.Content()
[
// Add whetever you want here
SNew(STextBlock)
.Text(FText::FromString("Window Container Text"))
]);
const int32 NumSlots = InArgs.Slots.Num();
for (int32 SlotIndex = 0; SlotIndex < NumSlots; ++SlotIndex)
{
Children.Add(InArgs.Slots[SlotIndex]);
}
// uncomment to show window after construction
//WindowContainer->ShowWindow();
}
virtual FReply OnMouseMove(const FGeometry& MyGeometry, const FPointerEvent& MouseEvent) OVERRIDE
{
if (WindowContainer.IsValid())
{
// Update WindowContainers location, you can add offsets to mouse position here
WindowContainer->MoveWindowTo(MouseEvent.GetScreenSpacePosition() + FSlateApplication::Get().GetCursorSize());
}
return SOverlay::OnMouseMove(MyGeometry, MouseEvent);
}
void SetWindowContainerVisibility(bool NewVis)
{
if (WindowContainer.IsValid())
{
// change WindowContainer's visibility
NewVis ? WindowContainer->ShowWindow() : WindowContainer->HideWindow();
}
}
private:
TSharedPtr<SWindow> WindowContainer;
};