Sure, here’s my code:
.h:
#pragma once
#include "Slate.h"
#include "SMySandboxActorsSubWidget.h"
class SMySandboxMainWidget : public SCompoundWidget
{
SLATE_BEGIN_ARGS(SMySandboxMainWidget)
: _OwnerHUD()
{}
/*See private declaration of OwnerHUD below.*/
SLATE_ARGUMENT(TWeakObjectPtr<AMyHUD>, OwnerHUD)
/** called when the button is clicked */
SLATE_EVENT(FOnClicked, OnClicked)
SLATE_END_ARGS()
public:
void Construct(const FArguments& InArgs);
/** mouse button down callback */
virtual FReply OnMouseButtonDown(const FGeometry& MyGeometry, const FPointerEvent& MouseEvent) OVERRIDE;
/** mouse button up callback */
virtual FReply OnMouseButtonUp(const FGeometry& MyGeometry, const FPointerEvent& MouseEvent) OVERRIDE;
FReply DrawActorsSubMenu();
FReply DrawPropertiesSubMenu();
FReply DrawSaveLoadSubMenu();
FReply HitTakeControl();
FReply HitQuitButton();
TSharedPtr<SMySandboxActorsSubWidget> ActorsSubMenu;
protected:
/** the delegate to execute when the button is clicked */
FOnClicked OnClicked;
// Main menu
TSharedPtr<SButton> TakeControlButton;
TSharedPtr<SButton> SaveLoadButton;
TSharedPtr<SButton> ExitButton;
TSharedPtr<SButton> PropertiesButton;
TSharedPtr<SButton> ActorsButton;
private:
// Pointer to our parent HUD
TWeakObjectPtr<class AMyHUD> OwnerHUD;
};
and my .cpp:
#include "MyGame.h"
#include "SMySandboxActorsSubWidget.h"
#include "SMySandboxMainWidget.h"
DEFINE_LOG_CATEGORY_STATIC(LogWidget, All, All)
void SMySandboxMainWidget::Construct(const FArguments& InArgs)
{
OwnerHUD = InArgs._OwnerHUD;
OnClicked = InArgs._OnClicked;
/////////
ChildSlot
.VAlign(VAlign_Fill)
.HAlign(HAlign_Fill)
SNew(SHorizontalBox)
+SHorizontalBox::Slot()
.AutoWidth()
.HAlign(HAlign_Left)
.VAlign(VAlign_Top)
SNew(SBorder)
.BorderImage(FCoreStyle::Get().GetBrush("NoBorder"))
.Padding(FMargin(0,0,0,0))
SAssignNew( ActorsButton, SButton )
.OnClicked(this, &SMySandboxMainWidget::DrawActorsSubMenu)
SNew(SBox)
SNew(STextBlock)
.ShadowColorAndOpacity(FLinearColor::Black)
.ColorAndOpacity(FLinearColor::White)
.ShadowOffset(FIntPoint(-1, 1))
.Font(FSlateFontInfo("Veranda", 20))
.Text(FText::FromString("ACTORS"))
]
]
]
]
// PROPERTIES
+SHorizontalBox::Slot()
.AutoWidth()
.HAlign(HAlign_Left)
.VAlign(VAlign_Top)
SNew(SBorder)
.BorderImage(FCoreStyle::Get().GetBrush("NoBorder"))
.Padding(FMargin(0,0,0,0))
SNew(SOverlay)
+SOverlay::Slot()
.HAlign(HAlign_Center)
.VAlign(VAlign_Center)
SAssignNew( PropertiesButton, SButton )
.OnClicked(this, &SMySandboxMainWidget::DrawPropertiesSubMenu)
SNew(SBox)
SNew(STextBlock)
.ShadowColorAndOpacity(FLinearColor::Black)
.ColorAndOpacity(FLinearColor::White)
.ShadowOffset(FIntPoint(-1, 1))
.Font(FSlateFontInfo("Veranda", 20))
.Text(FText::FromString("PROPERTIES"))
]
]
]
]
]
// SAVE/LOAD
+SHorizontalBox::Slot()
.AutoWidth()
.HAlign(HAlign_Left)
.VAlign(VAlign_Top)
SNew(SBorder)
.BorderImage(FCoreStyle::Get().GetBrush("NoBorder"))
.Padding(FMargin(0,0,0,0))
SNew(SOverlay)
+SOverlay::Slot()
.HAlign(HAlign_Center)
.VAlign(VAlign_Center)
SAssignNew( SaveLoadButton, SButton )
.OnClicked(this, &SMySandboxMainWidget::DrawSaveLoadSubMenu)
SNew(SBox)
SNew(STextBlock)
.ShadowColorAndOpacity(FLinearColor::Black)
.ColorAndOpacity(FLinearColor::White)
.ShadowOffset(FIntPoint(-1, 1))
.Font(FSlateFontInfo("Veranda", 20))
.Text(FText::FromString("SAVE/LOAD"))
]
]
]
]
]
// TAKE CONTROL
+SHorizontalBox::Slot()
.AutoWidth()
.HAlign(HAlign_Left)
.VAlign(VAlign_Top)
SNew(SBorder)
.BorderImage(FCoreStyle::Get().GetBrush("NoBorder"))
.Padding(FMargin(0,0,0,0))
SNew(SOverlay)
+SOverlay::Slot()
.HAlign(HAlign_Center)
.VAlign(VAlign_Center)
SAssignNew( TakeControlButton, SButton )
.OnClicked(this, &SMySandboxMainWidget::HitTakeControl)
SNew(SBox)
SNew(STextBlock)
.ShadowColorAndOpacity(FLinearColor::Black)
.ColorAndOpacity(FLinearColor::White)
.ShadowOffset(FIntPoint(-1, 1))
.Font(FSlateFontInfo("Veranda", 20))
.Text(FText::FromString("TAKE CONTROL"))
]
]
]
]
]
// EXIT
+SHorizontalBox::Slot()
.AutoWidth()
.HAlign(HAlign_Right)
.VAlign(VAlign_Top)
SNew(SBorder)
.BorderImage(FCoreStyle::Get().GetBrush("NoBorder"))
.Padding(FMargin(0,0,0,0))
SNew(SOverlay)
+SOverlay::Slot()
.HAlign(HAlign_Center)
.VAlign(VAlign_Center)
SAssignNew( ExitButton, SButton )
.OnClicked(this, &SMySandboxMainWidget::HitQuitButton)
SNew(SBox)
SNew(STextBlock)
.ShadowColorAndOpacity(FLinearColor::Black)
.ColorAndOpacity(FLinearColor::White)
.ShadowOffset(FIntPoint(-1, 1))
.Font(FSlateFontInfo("Veranda", 20))
.Text(FText::FromString("EXIT"))
]
]
]
]
]
];
// TOOLTIPS //
PropertiesButton->SetToolTip(
SNew(SToolTip)
SNew(STextBlock)
.Text(FText::FromString("Edit various properties of a selected actor."))
.Font(FSlateFontInfo(FPaths::EngineContentDir() / TEXT("Slate/Fonts/Roboto-Bold.ttf"), 12))
.ColorAndOpacity(FLinearColor(1,1,1,1))
.HighlightColor(FLinearColor(1,1,0,1))
.ShadowColorAndOpacity(FLinearColor::Black)
.ShadowOffset(FIntPoint(-2, 2))
]
);
TakeControlButton->SetToolTip(
SNew(SToolTip)
SNew(STextBlock)
.Text(FText::FromString("Drop in the level to test the level."))
.Font(FSlateFontInfo(FPaths::EngineContentDir() / TEXT("Slate/Fonts/Roboto-Bold.ttf"), 12))
.ColorAndOpacity(FLinearColor(1,1,1,1))
.HighlightColor(FLinearColor(1,1,0,1))
.ShadowColorAndOpacity(FLinearColor::Black)
.ShadowOffset(FIntPoint(-2, 2))
]
);
ExitButton->SetToolTip(
SNew(SToolTip)
SNew(STextBlock)
.Text(FText::FromString("Quit to the main menu."))
.Font(FSlateFontInfo(FPaths::EngineContentDir() / TEXT("Slate/Fonts/Roboto-Bold.ttf"), 12))
.ColorAndOpacity(FLinearColor(1,1,1,1))
.HighlightColor(FLinearColor(1,1,0,1))
.ShadowColorAndOpacity(FLinearColor::Black)
.ShadowOffset(FIntPoint(-2, 2))
]
);
}
FReply SMySandboxMainWidget::OnMouseButtonDown(const FGeometry& MyGeometry, const FPointerEvent& MouseEvent)
{
const FKey OurKey = MouseEvent.GetEffectingButton();
if(OurKey == EKeys::RightMouseButton)
{
SetVisibility(EVisibility::HitTestInvisible);
FSlateApplication::Get().SetFocusToGameViewport();
AMyPlayerController* PC = Cast<AMyPlayerController>(OwnerHUD->PlayerOwner);
if(PC)
{
AMyCharacterPlayer* Character = Cast<AMyCharacterPlayer>(PC->GetCharacter());
if(Character)
{
Character->OnStartFireSecondary();
UE_LOG( LogWidget, All, TEXT( "--- SetFocusToGameViewport" ));
return FReply::Handled();
}
}
}
return FReply::Handled();
}
FReply SMySandboxMainWidget::OnMouseButtonUp(const FGeometry& MyGeometry, const FPointerEvent& MouseEvent)
{
const FKey OurKey = MouseEvent.GetEffectingButton();
if(OurKey == EKeys::RightMouseButton)
{
AMyPlayerController* PC = Cast<AMyPlayerController>(OwnerHUD->PlayerOwner);
if(PC)
{
AMyCharacterPlayer* Character = Cast<AMyCharacterPlayer>(PC->GetCharacter());
if(Character)
{
Character->OnStopFireSecondary();
SetVisibility(EVisibility::Visible);
UE_LOG( LogWidget, All, TEXT( "--- Right Mouse Button Up!" ));
return FReply::Handled();
}
}
}
return FReply::Handled();
}
FReply SMySandboxMainWidget::DrawActorsSubMenu()
{
UE_LOG( LogWidget, All, TEXT( "--- Draw Actors Sub Menu" ));
if(!ActorsSubMenu.IsValid())
{
SAssignNew( ActorsSubMenu, SMySandboxActorsSubWidget )
.OwnerHUD(OwnerHUD);
}
if(ActorsSubMenu.IsValid())
{
GEngine->GameViewport->AddViewportWidgetContent( SNew(SWeakWidget).PossiblyNullContent(ActorsSubMenu.ToSharedRef()) );
ActorsSubMenu->SetVisibility(EVisibility::Visible);
}
return FReply::Handled();
}
FReply SMySandboxMainWidget::DrawPropertiesSubMenu()
{
UE_LOG( LogWidget, All, TEXT( "--- Draw Properties Sub Menu" ));
return FReply::Handled();
}
FReply SMySandboxMainWidget::DrawSaveLoadSubMenu()
{
UE_LOG( LogWidget, All, TEXT( "--- Draw Save/Load Sub Menu" ));
return FReply::Handled();
}
FReply SMySandboxMainWidget::HitTakeControl()
{
UE_LOG( LogWidget, All, TEXT( "--- Hit Take Control" ));
AMyPlayerController* PC = Cast<AMyPlayerController>(OwnerHUD->PlayerOwner);
if(PC)
{
AMyCharacterPlayer* Character = Cast<AMyCharacterPlayer>(PC->GetCharacter());
if(Character)
{
SetVisibility(EVisibility::Collapsed);
Character->SandboxSwitch();
return FReply::Handled();
}
}
return FReply::Handled();
}
FReply SMySandboxMainWidget::HitQuitButton()
{
UE_LOG( LogWidget, All, TEXT( "--- Hit QUIT BUTTON" ));
AMyPlayerController* PC = Cast<AMyPlayerController>(OwnerHUD->PlayerOwner);
if(PC)
{
PC->ConsoleCommand("quit");
}
return FReply::Handled();
}
In case your wondering about the above code, I’m using the RightMouseButton as camera movement when held down in my CharacterPlayer class so I was trying a work-around to re-enable that function whilst the Slate UI is on screen, but no joy.