Files
integration/Source/Integration/LuprexViewportClient.cpp

63 lines
2.1 KiB
C++

////////////////////////////////////////////////////////////
//
// LuprexViewportClient.cpp
//
////////////////////////////////////////////////////////////
#include "LuprexViewportClient.h"
#include "Common.h"
#include "PlayerControllerBase.h"
#include "Engine/GameInstance.h"
#include "Framework/Application/SlateApplication.h"
#include "Layout/WidgetPath.h"
#include "Widgets/SViewport.h"
UlxViewportClient::UlxViewportClient(const FObjectInitializer &ObjectInitializer)
: Super(ObjectInitializer)
{
UE_LOG(LogLuprexIntegration, Display, TEXT("UlxViewportClient constructed"));
}
bool UlxViewportClient::InputKey(const FInputKeyEventArgs &EventArgs)
{
UE_LOG(LogLuprexIntegration, Display, TEXT("UlxViewportClient::InputKey key=%s event=%d"),
*EventArgs.Key.ToString(), (int32)EventArgs.Event);
// Only act on left mouse button presses that bubbled up to the
// viewport unhandled. Walk the widget path under the cursor and
// find the nearest focusable ancestor of whatever was hit. If it
// isn't the game viewport itself, hand it to the player controller
// to apply on its next UpdateInputMode pass; that's the point in
// the frame where we can override SViewport's own click-focus
// behaviour without fighting it.
if ((EventArgs.Event == IE_Pressed) && (EventArgs.Key == EKeys::LeftMouseButton))
{
FSlateApplication &Slate = FSlateApplication::Get();
FVector2D MousePos = Slate.GetCursorPos();
FWidgetPath Path = Slate.LocateWindowUnderMouse(
MousePos, Slate.GetInteractiveTopLevelWindows());
if (Path.IsValid())
{
TSharedPtr<SViewport> ViewportWidget = GetGameViewportWidget();
for (int32 Idx = Path.Widgets.Num() - 1; Idx >= 0; --Idx)
{
TSharedRef<SWidget> Widget = Path.Widgets[Idx].Widget;
if (!Widget->SupportsKeyboardFocus()) continue;
if (ViewportWidget.IsValid() && Widget == ViewportWidget) break;
if (UGameInstance *GI = GetGameInstance())
{
if (AlxPlayerControllerBase *PC = Cast<AlxPlayerControllerBase>(
GI->GetFirstLocalPlayerController(GetWorld())))
{
PC->ClickToFocus(Widget);
}
}
break;
}
}
}
return Super::InputKey(EventArgs);
}