mirror of
https://github.com/Ed94/Cog.git
synced 2026-08-04 14:48:45 +00:00
CogImGui: Add imgui viewport support
This commit is contained in:
Binary file not shown.
@@ -228,7 +228,7 @@ void FCogEngineWindow_Collisions::RenderContent()
|
|||||||
case 2:
|
case 2:
|
||||||
{
|
{
|
||||||
FVector Direction;
|
FVector Direction;
|
||||||
UGameplayStatics::DeprojectScreenToWorld(PlayerController, FCogImguiHelper::ToVector2D(ImGui::GetMousePos()), QueryStart, Direction);
|
UGameplayStatics::DeprojectScreenToWorld(PlayerController, FCogImguiHelper::ToFVector2D(ImGui::GetMousePos()), QueryStart, Direction);
|
||||||
QueryEnd = QueryStart + Direction * Config->QueryDistance;
|
QueryEnd = QueryStart + Direction * Config->QueryDistance;
|
||||||
QueryRadius = Config->QueryThickness;
|
QueryRadius = Config->QueryThickness;
|
||||||
break;
|
break;
|
||||||
|
|||||||
@@ -4,6 +4,7 @@
|
|||||||
#include "CogDebugSettings.h"
|
#include "CogDebugSettings.h"
|
||||||
#include "CogEngineReplicator.h"
|
#include "CogEngineReplicator.h"
|
||||||
#include "CogImguiModule.h"
|
#include "CogImguiModule.h"
|
||||||
|
#include "CogImguiHelper.h"
|
||||||
#include "CogImguiInputHelper.h"
|
#include "CogImguiInputHelper.h"
|
||||||
#include "CogWindowManager.h"
|
#include "CogWindowManager.h"
|
||||||
#include "CogWindowWidgets.h"
|
#include "CogWindowWidgets.h"
|
||||||
@@ -136,8 +137,8 @@ void FCogEngineWindow_Selection::ToggleSelectionMode()
|
|||||||
void FCogEngineWindow_Selection::ActivateSelectionMode()
|
void FCogEngineWindow_Selection::ActivateSelectionMode()
|
||||||
{
|
{
|
||||||
bSelectionModeActive = true;
|
bSelectionModeActive = true;
|
||||||
bIsInputEnabledBeforeEnteringSelectionMode = GetOwner()->GetImGuiWidget()->GetEnableInput();
|
bIsInputEnabledBeforeEnteringSelectionMode = GetOwner()->GetContext().GetEnableInput();
|
||||||
GetOwner()->GetImGuiWidget()->SetEnableInput(true);
|
GetOwner()->GetContext().SetEnableInput(true);
|
||||||
GetOwner()->SetHideAllWindows(true);
|
GetOwner()->SetHideAllWindows(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -158,7 +159,7 @@ void FCogEngineWindow_Selection::DeactivateSelectionMode()
|
|||||||
// When in selection mode we need imgui to have the input focus
|
// When in selection mode we need imgui to have the input focus
|
||||||
// When leaving selection mode we want to leave it as is was before
|
// When leaving selection mode we want to leave it as is was before
|
||||||
//--------------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------------
|
||||||
GetOwner()->GetImGuiWidget()->SetEnableInput(bIsInputEnabledBeforeEnteringSelectionMode);
|
GetOwner()->GetContext().SetEnableInput(bIsInputEnabledBeforeEnteringSelectionMode);
|
||||||
|
|
||||||
GetOwner()->SetHideAllWindows(false);
|
GetOwner()->SetHideAllWindows(false);
|
||||||
}
|
}
|
||||||
@@ -393,15 +394,23 @@ void FCogEngineWindow_Selection::TickSelectionMode()
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
ImDrawList* DrawList = ImGui::GetBackgroundDrawList();
|
ImGuiViewport* Viewport = ImGui::GetMainViewport();
|
||||||
DrawList->AddRect(ImVec2(0, 0), ImGui::GetIO().DisplaySize, IM_COL32(255, 0, 0, 128), 0.0f, 0, 20.0f);
|
if (Viewport == nullptr)
|
||||||
FCogWindowWidgets::AddTextWithShadow(DrawList, ImVec2(20, 20), IM_COL32(255, 255, 255, 255), "Picking Mode. \n[LMB] Pick \n[RMB] Cancel");
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const ImVec2 ViewportPos = Viewport->Pos;
|
||||||
|
const ImVec2 ViewportSize = Viewport->Size;
|
||||||
|
ImDrawList* DrawList = ImGui::GetBackgroundDrawList(Viewport);
|
||||||
|
DrawList->AddRect(ViewportPos, ViewportPos + ViewportSize, IM_COL32(255, 0, 0, 128), 0.0f, 0, 20.0f);
|
||||||
|
FCogWindowWidgets::AddTextWithShadow(DrawList, ViewportPos + ImVec2(20, 20), IM_COL32(255, 255, 255, 255), "Picking Mode. \n[LMB] Pick \n[RMB] Cancel");
|
||||||
|
|
||||||
TSubclassOf<AActor> SelectedActorClass = GetSelectedActorClass();
|
TSubclassOf<AActor> SelectedActorClass = GetSelectedActorClass();
|
||||||
|
|
||||||
AActor* HoveredActor = nullptr;
|
AActor* HoveredActor = nullptr;
|
||||||
FVector WorldOrigin, WorldDirection;
|
FVector WorldOrigin, WorldDirection;
|
||||||
if (UGameplayStatics::DeprojectScreenToWorld(PlayerController, FCogImguiHelper::ToVector2D(ImGui::GetMousePos()), WorldOrigin, WorldDirection))
|
if (UGameplayStatics::DeprojectScreenToWorld(PlayerController, FCogImguiHelper::ToFVector2D(ImGui::GetMousePos() - ViewportPos), WorldOrigin, WorldDirection))
|
||||||
{
|
{
|
||||||
//--------------------------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------------------------
|
||||||
// Prioritize another actor than the selected actor unless we only touch the selected actor.
|
// Prioritize another actor than the selected actor unless we only touch the selected actor.
|
||||||
@@ -463,7 +472,13 @@ void FCogEngineWindow_Selection::DrawActorFrame(const AActor& Actor)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
ImDrawList* DrawList = ImGui::GetBackgroundDrawList();
|
ImGuiViewport* Viewport = ImGui::GetMainViewport();
|
||||||
|
if (Viewport == nullptr)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
ImDrawList* DrawList = ImGui::GetBackgroundDrawList(Viewport);
|
||||||
|
|
||||||
FVector BoxOrigin, BoxExtent;
|
FVector BoxOrigin, BoxExtent;
|
||||||
|
|
||||||
@@ -502,8 +517,8 @@ void FCogEngineWindow_Selection::DrawActorFrame(const AActor& Actor)
|
|||||||
if (ComputeBoundingBoxScreenPosition(PlayerController, BoxOrigin, BoxExtent, ScreenPosMin, ScreenPosMax))
|
if (ComputeBoundingBoxScreenPosition(PlayerController, BoxOrigin, BoxExtent, ScreenPosMin, ScreenPosMax))
|
||||||
{
|
{
|
||||||
const ImU32 Color = (&Actor == GetSelection()) ? IM_COL32(255, 255, 255, 255) : IM_COL32(255, 255, 255, 128);
|
const ImU32 Color = (&Actor == GetSelection()) ? IM_COL32(255, 255, 255, 255) : IM_COL32(255, 255, 255, 128);
|
||||||
DrawList->AddRect(FCogImguiHelper::ToImVec2(ScreenPosMin), FCogImguiHelper::ToImVec2(ScreenPosMax), Color, 0.0f, 0, 1.0f);
|
DrawList->AddRect(FCogImguiHelper::ToImVec2(ScreenPosMin) + Viewport->Pos, FCogImguiHelper::ToImVec2(ScreenPosMax) + Viewport->Pos, Color, 0.0f, 0, 1.0f);
|
||||||
FCogWindowWidgets::AddTextWithShadow(DrawList, FCogImguiHelper::ToImVec2(ScreenPosMin + FVector2D(0, -14.0f)), Color, TCHAR_TO_ANSI(*GetActorName(Actor)));
|
FCogWindowWidgets::AddTextWithShadow(DrawList, FCogImguiHelper::ToImVec2(ScreenPosMin + FVector2D(0, -14.0f)) + Viewport->Pos, Color, TCHAR_TO_ANSI(*GetActorName(Actor)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,105 @@
|
|||||||
|
#include "CogEngineWindow_Slate.h"
|
||||||
|
|
||||||
|
#include "CogImguiHelper.h"
|
||||||
|
#include "Framework/Application/SlateApplication.h"
|
||||||
|
#include "Framework/Application/SlateUser.h"
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------------------------------------------------------------
|
||||||
|
void FCogEngineWindow_Slate::RenderHelp()
|
||||||
|
{
|
||||||
|
ImGui::Text(
|
||||||
|
"This window displays slate debug info. "
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------------------------------------------------------------
|
||||||
|
void FCogEngineWindow_Slate::RenderContent()
|
||||||
|
{
|
||||||
|
Super::RenderContent();
|
||||||
|
|
||||||
|
|
||||||
|
if (FSlateApplication::IsInitialized() == false)
|
||||||
|
{
|
||||||
|
ImGui::Text("Not initialized");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
FSlateApplication& SlateApp = FSlateApplication::Get();
|
||||||
|
|
||||||
|
static int32 SelectedUserIndex = 0;
|
||||||
|
|
||||||
|
ImGui::SetNextItemWidth(-1);
|
||||||
|
if (ImGui::BeginCombo("##User", TCHAR_TO_ANSI(*FString::Printf(TEXT("%d"), SelectedUserIndex))))
|
||||||
|
{
|
||||||
|
SlateApp.ForEachUser([this](FSlateUser& User)
|
||||||
|
{
|
||||||
|
if (ImGui::Selectable(TCHAR_TO_ANSI(*FString::Printf(TEXT("%d"), SelectedUserIndex)), false))
|
||||||
|
{
|
||||||
|
SelectedUserIndex = User.GetUserIndex();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
ImGui::EndCombo();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (TSharedPtr<FSlateUser> User = SlateApp.GetUser(SelectedUserIndex))
|
||||||
|
{
|
||||||
|
RenderUser(*User.Get());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------------------------------------------------------------
|
||||||
|
void FCogEngineWindow_Slate::RenderUser(FSlateUser& User)
|
||||||
|
{
|
||||||
|
|
||||||
|
if (ImGui::BeginTable("SlateUser", 2, ImGuiTableFlags_Borders))
|
||||||
|
{
|
||||||
|
const ImVec4 LabelColor(1.0f, 1.0f, 1.0f, 0.5f);
|
||||||
|
|
||||||
|
ImGui::TableSetupColumn("Property");
|
||||||
|
ImGui::TableSetupColumn("Value");
|
||||||
|
|
||||||
|
|
||||||
|
//------------------------
|
||||||
|
// Focused Widget
|
||||||
|
//------------------------
|
||||||
|
ImGui::TableNextRow();
|
||||||
|
ImGui::TableNextColumn();
|
||||||
|
ImGui::TextColored(LabelColor, "Focused Widget");
|
||||||
|
ImGui::TableNextColumn();
|
||||||
|
FString FocusedWidgetText = "None";
|
||||||
|
if (TSharedPtr<SWidget> FocusedWidget = User.GetFocusedWidget())
|
||||||
|
{
|
||||||
|
FocusedWidgetText = FocusedWidget->ToString();
|
||||||
|
}
|
||||||
|
ImGui::Text("%s", TCHAR_TO_ANSI(*FocusedWidgetText));
|
||||||
|
|
||||||
|
//------------------------
|
||||||
|
// Cursor Captor
|
||||||
|
//------------------------
|
||||||
|
ImGui::TableNextRow();
|
||||||
|
ImGui::TableNextColumn();
|
||||||
|
ImGui::TextColored(LabelColor, "Cursor Captor");
|
||||||
|
ImGui::TableNextColumn();
|
||||||
|
FString CursorCaptoreWidgetText = "None";
|
||||||
|
if (TSharedPtr<SWidget> CursorCaptoreWidget = User.GetCursorCaptor())
|
||||||
|
{
|
||||||
|
CursorCaptoreWidgetText = CursorCaptoreWidget->ToString();
|
||||||
|
}
|
||||||
|
ImGui::Text("%s", TCHAR_TO_ANSI(*CursorCaptoreWidgetText));
|
||||||
|
|
||||||
|
//------------------------
|
||||||
|
// Cursor Position
|
||||||
|
//------------------------
|
||||||
|
ImGui::TableNextRow();
|
||||||
|
ImGui::TableNextColumn();
|
||||||
|
ImGui::TextColored(LabelColor, "Cursor Position");
|
||||||
|
ImGui::TableNextColumn();
|
||||||
|
ImVec2 CursorPosition = FCogImguiHelper::ToImVec2(User.GetCursorPosition());
|
||||||
|
ImGui::InputFloat2("##Cursor Position", &CursorPosition.x, "%0.0f");
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
ImGui::EndTable();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,22 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "CoreMinimal.h"
|
||||||
|
#include "CogWindow.h"
|
||||||
|
|
||||||
|
class FSlateUser;
|
||||||
|
|
||||||
|
class COGENGINE_API FCogEngineWindow_Slate : public FCogWindow
|
||||||
|
{
|
||||||
|
typedef FCogWindow Super;
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
|
virtual void RenderHelp() override;
|
||||||
|
|
||||||
|
virtual void RenderContent() override;
|
||||||
|
|
||||||
|
virtual void RenderUser(FSlateUser& User);
|
||||||
|
|
||||||
|
};
|
||||||
@@ -3,9 +3,11 @@
|
|||||||
#include "CogImguiHelper.h"
|
#include "CogImguiHelper.h"
|
||||||
#include "CogImguiInputHelper.h"
|
#include "CogImguiInputHelper.h"
|
||||||
#include "CogImguiWidget.h"
|
#include "CogImguiWidget.h"
|
||||||
|
#include "CogImguiContext.h"
|
||||||
#include "GameFramework/InputSettings.h"
|
#include "GameFramework/InputSettings.h"
|
||||||
#include "GameFramework/PlayerInput.h"
|
#include "GameFramework/PlayerInput.h"
|
||||||
#include "imgui.h"
|
#include "imgui.h"
|
||||||
|
#include "imgui_internal.h"
|
||||||
#include "Slate/SGameLayerManager.h"
|
#include "Slate/SGameLayerManager.h"
|
||||||
|
|
||||||
#if WITH_EDITOR
|
#if WITH_EDITOR
|
||||||
@@ -16,9 +18,10 @@ constexpr bool ForwardEvent = false;
|
|||||||
constexpr bool TerminateEvent = true;
|
constexpr bool TerminateEvent = true;
|
||||||
|
|
||||||
//--------------------------------------------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------------------------------------------
|
||||||
FImGuiInputProcessor::FImGuiInputProcessor(UPlayerInput* InPlayerInput, SCogImguiWidget* InMainWidget)
|
FImGuiInputProcessor::FImGuiInputProcessor(UPlayerInput* InPlayerInput, FCogImguiContext* InContext, SCogImguiWidget* InMainWidget)
|
||||||
{
|
{
|
||||||
PlayerInput = InPlayerInput;
|
PlayerInput = InPlayerInput;
|
||||||
|
Context = InContext;
|
||||||
MainWidget = InMainWidget;
|
MainWidget = InMainWidget;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -43,14 +46,16 @@ void FImGuiInputProcessor::Tick(const float DeltaTime, FSlateApplication& SlateA
|
|||||||
|
|
||||||
AddMousePosEvent(SlateApp.GetCursorPos());
|
AddMousePosEvent(SlateApp.GetCursorPos());
|
||||||
|
|
||||||
if ((IO.ConfigFlags & ImGuiConfigFlags_NoMouse) == 0)
|
const bool bHasMouse = (IO.ConfigFlags & ImGuiConfigFlags_NoMouse) == 0;
|
||||||
|
const bool bUpdateMouseMouseCursor = (IO.ConfigFlags & ImGuiConfigFlags_NoMouseCursorChange) == 0;
|
||||||
|
if (bHasMouse && bUpdateMouseMouseCursor)
|
||||||
{
|
{
|
||||||
SlateCursor->SetType(FCogImguiInputHelper::ToSlateMouseCursor(ImGui::GetMouseCursor()));
|
SlateCursor->SetType(FCogImguiInputHelper::ToSlateMouseCursor(ImGui::GetMouseCursor()));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (IO.WantSetMousePos)
|
if (IO.WantSetMousePos)
|
||||||
{
|
{
|
||||||
SlateApp.SetCursorPos(FCogImguiHelper::ToVector2D(IO.MousePos));
|
SlateApp.SetCursorPos(FCogImguiHelper::ToFVector2D(IO.MousePos));
|
||||||
//UE_LOG(LogCogImGui, VeryVerbose, TEXT("FImGuiInputProcessor::Tick | SetCursorPos"));
|
//UE_LOG(LogCogImGui, VeryVerbose, TEXT("FImGuiInputProcessor::Tick | SetCursorPos"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -175,7 +180,7 @@ bool FImGuiInputProcessor::HandleMouseMoveEvent(FSlateApplication& SlateApp, con
|
|||||||
{
|
{
|
||||||
AddMousePosEvent(Event.GetScreenSpacePosition());
|
AddMousePosEvent(Event.GetScreenSpacePosition());
|
||||||
|
|
||||||
if (MainWidget->GetEnableInput() && MainWidget->GetShareMouse() == false)
|
if (Context->GetEnableInput() && Context->GetShareMouse() == false && IsMouseInsideMainViewport())
|
||||||
{
|
{
|
||||||
return TerminateEvent;
|
return TerminateEvent;
|
||||||
}
|
}
|
||||||
@@ -211,7 +216,7 @@ bool FImGuiInputProcessor::HandleMouseButtonEvent(FSlateApplication& SlateApp, c
|
|||||||
const uint32 Button = ToImGuiMouseButton(Event.GetEffectingButton());
|
const uint32 Button = ToImGuiMouseButton(Event.GetEffectingButton());
|
||||||
IO.AddMouseButtonEvent(Button, IsButtonDown);
|
IO.AddMouseButtonEvent(Button, IsButtonDown);
|
||||||
|
|
||||||
if (MainWidget->GetEnableInput() && MainWidget->GetShareMouse() == false)
|
if (Context->GetEnableInput() && Context->GetShareMouse() == false && IsMouseInsideMainViewport())
|
||||||
{
|
{
|
||||||
const bool Result = TerminateEvent;
|
const bool Result = TerminateEvent;
|
||||||
UE_LOG(LogCogImGui, VeryVerbose, TEXT("FImGuiInputProcessor::HandleMouseButtonEvent | Button:%d | IsButtonDown:%d | WantCaptureMouse:%d | TerminateEvent:%d | ShareMouse == false"), Button, IsButtonDown, IO.WantCaptureMouse, Result);
|
UE_LOG(LogCogImGui, VeryVerbose, TEXT("FImGuiInputProcessor::HandleMouseButtonEvent | Button:%d | IsButtonDown:%d | WantCaptureMouse:%d | TerminateEvent:%d | ShareMouse == false"), Button, IsButtonDown, IO.WantCaptureMouse, Result);
|
||||||
@@ -237,6 +242,19 @@ void FImGuiInputProcessor::AddMousePosEvent(const FVector2D& MousePosition) cons
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------------------------------------------------------------
|
||||||
|
bool FImGuiInputProcessor::IsMouseInsideMainViewport()
|
||||||
|
{
|
||||||
|
if (ImGuiViewportP* Viewport = (ImGuiViewportP*)ImGui::GetMainViewport())
|
||||||
|
{
|
||||||
|
ImGuiIO& IO = ImGui::GetIO();
|
||||||
|
const bool Result = Viewport->GetMainRect().Contains(IO.MousePos);
|
||||||
|
return Result;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
//--------------------------------------------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------------------------------------------
|
||||||
bool FImGuiInputProcessor::HandleMouseWheelOrGestureEvent(FSlateApplication& SlateApp, const FPointerEvent& Event, const FPointerEvent* GestureEvent)
|
bool FImGuiInputProcessor::HandleMouseWheelOrGestureEvent(FSlateApplication& SlateApp, const FPointerEvent& Event, const FPointerEvent* GestureEvent)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -0,0 +1,726 @@
|
|||||||
|
#include "CogImGuiContext.h"
|
||||||
|
|
||||||
|
#include "CogImguiHelper.h"
|
||||||
|
#include "CogImguiInputHelper.h"
|
||||||
|
#include "CogImguiInputProcessor.h"
|
||||||
|
#include "CogImguiWidget.h"
|
||||||
|
#include "Engine/Console.h"
|
||||||
|
#include "Engine/LocalPlayer.h"
|
||||||
|
#include "Framework/Application/SlateApplication.h"
|
||||||
|
#include "Framework/Application/SlateUser.h"
|
||||||
|
#include "GameFramework/PlayerController.h"
|
||||||
|
#include "GameFramework/PlayerInput.h"
|
||||||
|
#include "imgui.h"
|
||||||
|
#include "imgui_internal.h"
|
||||||
|
#include "implot.h"
|
||||||
|
#include "TextureResource.h"
|
||||||
|
#include "Widgets/SViewport.h"
|
||||||
|
#include "Widgets/SWindow.h"
|
||||||
|
|
||||||
|
static UPlayerInput* GetPlayerInput(const UWorld* World);
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------------------------------------------------------------
|
||||||
|
void FCogImguiContext::Initialize()
|
||||||
|
{
|
||||||
|
IMGUI_CHECKVERSION();
|
||||||
|
|
||||||
|
if (FSlateApplication::IsInitialized() == false)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
FSlateApplication& SlateApp = FSlateApplication::Get();
|
||||||
|
|
||||||
|
GameViewport = GEngine->GameViewport;
|
||||||
|
|
||||||
|
SAssignNew(MainWidget, SCogImguiWidget)
|
||||||
|
.Context(this);
|
||||||
|
|
||||||
|
GameViewport->AddViewportWidgetContent(MainWidget.ToSharedRef(), TNumericLimits<int32>::Max());
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------
|
||||||
|
// Register input processor to forward input events to imgui
|
||||||
|
//--------------------------------------------------------------------
|
||||||
|
if (FSlateApplication::IsInitialized())
|
||||||
|
{
|
||||||
|
UPlayerInput* PlayerInput = FCogImguiInputHelper::GetPlayerInput(*GameViewport->GetWorld());
|
||||||
|
InputProcessor = MakeShared<FImGuiInputProcessor>(PlayerInput, this, MainWidget.Get());
|
||||||
|
FSlateApplication::Get().RegisterInputPreProcessor(InputProcessor.ToSharedRef(), 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
ImGuiContext = ImGui::CreateContext();
|
||||||
|
PlotContext = ImPlot::CreateContext();
|
||||||
|
ImPlot::SetImGuiContext(ImGuiContext);
|
||||||
|
|
||||||
|
ImGuiIO& IO = ImGui::GetIO();
|
||||||
|
IO.UserData = this;
|
||||||
|
|
||||||
|
IO.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard;
|
||||||
|
IO.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad;
|
||||||
|
IO.ConfigFlags |= ImGuiConfigFlags_NavNoCaptureKeyboard;
|
||||||
|
IO.ConfigFlags |= ImGuiConfigFlags_NavEnableSetMousePos;
|
||||||
|
IO.ConfigFlags |= ImGuiConfigFlags_DockingEnable;
|
||||||
|
|
||||||
|
IO.BackendFlags |= ImGuiBackendFlags_HasMouseCursors;
|
||||||
|
IO.BackendFlags |= ImGuiBackendFlags_HasSetMousePos;
|
||||||
|
IO.BackendFlags |= ImGuiBackendFlags_PlatformHasViewports;
|
||||||
|
IO.BackendFlags |= ImGuiBackendFlags_HasMouseHoveredViewport;
|
||||||
|
IO.BackendFlags |= ImGuiBackendFlags_RendererHasViewports;
|
||||||
|
IO.BackendFlags |= ImGuiBackendFlags_RendererHasVtxOffset;
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
//--------------------------------------------------------------------
|
||||||
|
ImGuiViewport* MainViewport = ImGui::GetMainViewport();
|
||||||
|
FImGuiViewportData* ViewportData = new FImGuiViewportData();
|
||||||
|
MainViewport->PlatformUserData = ViewportData;
|
||||||
|
ViewportData->Window = SlateApp.GetActiveTopLevelWindow();
|
||||||
|
ViewportData->Context = this;
|
||||||
|
ViewportData->Widget = MainWidget;
|
||||||
|
|
||||||
|
const char* InitFilenameTemp = TCHAR_TO_ANSI(*FCogImguiHelper::GetIniFilePath("imgui"));
|
||||||
|
ImStrncpy(IniFilename, InitFilenameTemp, IM_ARRAYSIZE(IniFilename));
|
||||||
|
IO.IniFilename = IniFilename;
|
||||||
|
|
||||||
|
ImGuiPlatformIO& PlatformIO = ImGui::GetPlatformIO();
|
||||||
|
PlatformIO.Platform_CreateWindow = ImGui_CreateWindow;
|
||||||
|
PlatformIO.Platform_DestroyWindow = ImGui_DestroyWindow;
|
||||||
|
PlatformIO.Platform_ShowWindow = ImGui_ShowWindow;
|
||||||
|
PlatformIO.Platform_SetWindowPos = ImGui_SetWindowPos;
|
||||||
|
PlatformIO.Platform_GetWindowPos = ImGui_GetWindowPos;
|
||||||
|
PlatformIO.Platform_SetWindowSize = ImGui_SetWindowSize;
|
||||||
|
PlatformIO.Platform_GetWindowSize = ImGui_GetWindowSize;
|
||||||
|
PlatformIO.Platform_SetWindowFocus = ImGui_SetWindowFocus;
|
||||||
|
PlatformIO.Platform_GetWindowFocus = ImGui_GetWindowFocus;
|
||||||
|
PlatformIO.Platform_GetWindowMinimized = ImGui_GetWindowMinimized;
|
||||||
|
PlatformIO.Platform_SetWindowTitle = ImGui_SetWindowTitle;
|
||||||
|
PlatformIO.Platform_SetWindowAlpha = ImGui_SetWindowAlpha;
|
||||||
|
PlatformIO.Platform_RenderWindow = ImGui_RenderWindow;
|
||||||
|
|
||||||
|
if (const TSharedPtr<GenericApplication> PlatformApplication = SlateApp.GetPlatformApplication())
|
||||||
|
{
|
||||||
|
FDisplayMetrics DisplayMetrics;
|
||||||
|
PlatformApplication->GetInitialDisplayMetrics(DisplayMetrics);
|
||||||
|
PlatformApplication->OnDisplayMetricsChanged().AddRaw(this, &FCogImguiContext::OnDisplayMetricsChanged);
|
||||||
|
OnDisplayMetricsChanged(DisplayMetrics);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------------------------------------------------------------
|
||||||
|
void FCogImguiContext::Shutdown()
|
||||||
|
{
|
||||||
|
ImGuiViewport* MainViewport = ImGui::GetMainViewport();
|
||||||
|
if (const FImGuiViewportData* ViewportData = static_cast<FImGuiViewportData*>(MainViewport->PlatformUserData))
|
||||||
|
{
|
||||||
|
delete ViewportData;
|
||||||
|
MainViewport->PlatformUserData = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (FSlateApplication::IsInitialized())
|
||||||
|
{
|
||||||
|
FSlateApplication& SlateApp = FSlateApplication::Get();
|
||||||
|
|
||||||
|
if (InputProcessor.IsValid())
|
||||||
|
{
|
||||||
|
SlateApp.UnregisterInputPreProcessor(InputProcessor);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (const TSharedPtr<GenericApplication> PlatformApplication = SlateApp.GetPlatformApplication())
|
||||||
|
{
|
||||||
|
PlatformApplication->OnDisplayMetricsChanged().RemoveAll(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (PlotContext)
|
||||||
|
{
|
||||||
|
ImPlot::DestroyContext(PlotContext);
|
||||||
|
PlotContext = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ImGuiContext)
|
||||||
|
{
|
||||||
|
ImGui::DestroyContext(ImGuiContext);
|
||||||
|
ImGuiContext = nullptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------------------------------------------------------------
|
||||||
|
void FCogImguiContext::OnDisplayMetricsChanged(const FDisplayMetrics& DisplayMetrics) const
|
||||||
|
{
|
||||||
|
ImGuiPlatformIO& PlatformIO = ImGui::GetPlatformIO();
|
||||||
|
PlatformIO.Monitors.resize(0);
|
||||||
|
|
||||||
|
for (const FMonitorInfo& Monitor : DisplayMetrics.MonitorInfo)
|
||||||
|
{
|
||||||
|
ImGuiPlatformMonitor ImGuiMonitor;
|
||||||
|
ImGuiMonitor.MainPos = ImVec2(Monitor.DisplayRect.Left, Monitor.DisplayRect.Top);
|
||||||
|
ImGuiMonitor.MainSize = ImVec2(Monitor.DisplayRect.Right - Monitor.DisplayRect.Left, Monitor.DisplayRect.Bottom - Monitor.DisplayRect.Top);
|
||||||
|
ImGuiMonitor.WorkPos = ImVec2(Monitor.WorkArea.Left, Monitor.WorkArea.Top);
|
||||||
|
ImGuiMonitor.WorkSize = ImVec2(Monitor.WorkArea.Right - Monitor.WorkArea.Left, Monitor.WorkArea.Bottom - Monitor.WorkArea.Top);
|
||||||
|
ImGuiMonitor.DpiScale = Monitor.DPI;
|
||||||
|
|
||||||
|
if (Monitor.bIsPrimary)
|
||||||
|
{
|
||||||
|
PlatformIO.Monitors.push_front(ImGuiMonitor);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
PlatformIO.Monitors.push_back(ImGuiMonitor);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------------------------------------------------------------
|
||||||
|
void FCogImguiContext::BeginFrame(float InDeltaTime)
|
||||||
|
{
|
||||||
|
ImGui::SetCurrentContext(ImGuiContext);
|
||||||
|
ImPlot::SetImGuiContext(ImGuiContext);
|
||||||
|
ImPlot::SetCurrentContext(PlotContext);
|
||||||
|
|
||||||
|
ImGuiIO& IO = ImGui::GetIO();
|
||||||
|
IO.DeltaTime = InDeltaTime;
|
||||||
|
IO.DisplaySize = FCogImguiHelper::ToImVec2(MainWidget->GetTickSpaceGeometry().GetAbsoluteSize());
|
||||||
|
|
||||||
|
//-------------------------------------------------------------------------------------------------------
|
||||||
|
// Build font
|
||||||
|
//-------------------------------------------------------------------------------------------------------
|
||||||
|
if (IO.Fonts->IsBuilt() == false || FontAtlasTexturePtr.IsValid() == false)
|
||||||
|
{
|
||||||
|
BuildFont();
|
||||||
|
}
|
||||||
|
|
||||||
|
//-------------------------------------------------------------------------------------------------------
|
||||||
|
// Update which viewport is under the mouse
|
||||||
|
//-------------------------------------------------------------------------------------------------------
|
||||||
|
ImGuiID MouseViewportId = 0;
|
||||||
|
|
||||||
|
FSlateApplication& SlateApp = FSlateApplication::Get();
|
||||||
|
FWidgetPath WidgetsUnderCursor = SlateApp.LocateWindowUnderMouse(SlateApp.GetCursorPos(), SlateApp.GetInteractiveTopLevelWindows());
|
||||||
|
if (WidgetsUnderCursor.IsValid())
|
||||||
|
{
|
||||||
|
TSharedRef<SWindow> Window = WidgetsUnderCursor.GetWindow();
|
||||||
|
ImGuiID* ViewportId = WindowToViewportMap.Find(Window);
|
||||||
|
|
||||||
|
if (ViewportId != nullptr)
|
||||||
|
{
|
||||||
|
MouseViewportId = *ViewportId;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
MouseViewportId = ImGui::GetMainViewport()->ID;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
IO.AddMouseViewportEvent(MouseViewportId);
|
||||||
|
|
||||||
|
//-------------------------------------------------------------------------------------------------------
|
||||||
|
// Refresh modifiers otherwise, when pressing ALT-TAB, the Alt modifier is always true
|
||||||
|
//-------------------------------------------------------------------------------------------------------
|
||||||
|
FModifierKeysState ModifierKeys = FSlateApplication::Get().GetModifierKeys();
|
||||||
|
if (ModifierKeys.IsControlDown() != IO.KeyCtrl) { IO.AddKeyEvent(ImGuiMod_Ctrl, ModifierKeys.IsControlDown()); }
|
||||||
|
if (ModifierKeys.IsShiftDown() != IO.KeyShift) { IO.AddKeyEvent(ImGuiMod_Shift, ModifierKeys.IsShiftDown()); }
|
||||||
|
if (ModifierKeys.IsAltDown() != IO.KeyAlt) { IO.AddKeyEvent(ImGuiMod_Alt, ModifierKeys.IsAltDown()); }
|
||||||
|
if (ModifierKeys.IsCommandDown() != IO.KeySuper) { IO.AddKeyEvent(ImGuiMod_Super, ModifierKeys.IsCommandDown()); }
|
||||||
|
|
||||||
|
|
||||||
|
//-------------------------------------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
//-------------------------------------------------------------------------------------------------------
|
||||||
|
if (bEnableInput)
|
||||||
|
{
|
||||||
|
IO.ConfigFlags &= ~ImGuiConfigFlags_NoMouse;
|
||||||
|
|
||||||
|
TryReleaseGameMouseCapture();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
IO.ConfigFlags |= ImGuiConfigFlags_NoMouse;
|
||||||
|
}
|
||||||
|
|
||||||
|
//-------------------------------------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
//-------------------------------------------------------------------------------------------------------
|
||||||
|
const bool bHasMouse = (IO.ConfigFlags & ImGuiConfigFlags_NoMouse) == 0;
|
||||||
|
const bool bUpdateMouseMouseCursor = (IO.ConfigFlags & ImGuiConfigFlags_NoMouseCursorChange) == 0;
|
||||||
|
if (bHasMouse && bUpdateMouseMouseCursor)
|
||||||
|
{
|
||||||
|
MainWidget->SetCursor(FCogImguiInputHelper::ToSlateMouseCursor(ImGui::GetMouseCursor()));
|
||||||
|
}
|
||||||
|
|
||||||
|
//-------------------------------------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
//-------------------------------------------------------------------------------------------------------
|
||||||
|
if (bRefreshDPIScale)
|
||||||
|
{
|
||||||
|
RefreshDPIScale();
|
||||||
|
}
|
||||||
|
|
||||||
|
ImGui::NewFrame();
|
||||||
|
|
||||||
|
DrawDebug();
|
||||||
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------------------------------------------------------------
|
||||||
|
void FCogImguiContext::EndFrame()
|
||||||
|
{
|
||||||
|
ImGui::Render();
|
||||||
|
ImGui_RenderWindow(ImGui::GetMainViewport(), nullptr);
|
||||||
|
|
||||||
|
ImGui::UpdatePlatformWindows();
|
||||||
|
ImGui::RenderPlatformWindowsDefault();
|
||||||
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------------------------------------------------------------
|
||||||
|
void FCogImguiContext::ImGui_CreateWindow(ImGuiViewport* Viewport)
|
||||||
|
{
|
||||||
|
if (Viewport->ParentViewportId == 0)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
ImGuiViewport* ParentViewport = ImGui::FindViewportByID(Viewport->ParentViewportId);
|
||||||
|
if (ParentViewport == nullptr)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const FImGuiViewportData* ParentViewportData = static_cast<FImGuiViewportData*>(ParentViewport->PlatformUserData);
|
||||||
|
if (ParentViewportData == nullptr)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
FCogImguiContext* Context = ParentViewportData->Context.Get();
|
||||||
|
|
||||||
|
const bool bTooltipWindow = (Viewport->Flags & ImGuiViewportFlags_TopMost);
|
||||||
|
const bool bPopupWindow = (Viewport->Flags & ImGuiViewportFlags_NoTaskBarIcon);
|
||||||
|
|
||||||
|
static FWindowStyle WindowStyle = FWindowStyle()
|
||||||
|
.SetActiveTitleBrush(FSlateNoResource())
|
||||||
|
.SetInactiveTitleBrush(FSlateNoResource())
|
||||||
|
.SetFlashTitleBrush(FSlateNoResource())
|
||||||
|
.SetOutlineBrush(FSlateNoResource())
|
||||||
|
.SetBorderBrush(FSlateNoResource())
|
||||||
|
.SetBackgroundBrush(FSlateNoResource())
|
||||||
|
.SetChildBackgroundBrush(FSlateNoResource());
|
||||||
|
|
||||||
|
TSharedPtr<SCogImguiWidget> Widget;
|
||||||
|
|
||||||
|
const TSharedRef<SWindow> Window =
|
||||||
|
SNew(SWindow)
|
||||||
|
.Type(bTooltipWindow ? EWindowType::ToolTip : EWindowType::Normal)
|
||||||
|
.Style(&WindowStyle)
|
||||||
|
.ScreenPosition(FCogImguiHelper::ToFVector2D(Viewport->Pos))
|
||||||
|
.ClientSize(FCogImguiHelper::ToFVector2D(Viewport->Size))
|
||||||
|
.SupportsTransparency(EWindowTransparency::PerWindow)
|
||||||
|
.SizingRule(ESizingRule::UserSized)
|
||||||
|
.IsPopupWindow(bTooltipWindow || bPopupWindow)
|
||||||
|
.IsTopmostWindow(bTooltipWindow)
|
||||||
|
.FocusWhenFirstShown(!(Viewport->Flags & ImGuiViewportFlags_NoFocusOnAppearing))
|
||||||
|
.HasCloseButton(false)
|
||||||
|
.SupportsMaximize(false)
|
||||||
|
.SupportsMinimize(false)
|
||||||
|
.CreateTitleBar(false)
|
||||||
|
.LayoutBorder(0)
|
||||||
|
.UserResizeBorder(0)
|
||||||
|
.UseOSWindowBorder(false)
|
||||||
|
[
|
||||||
|
SAssignNew(Widget, SCogImguiWidget)
|
||||||
|
.Context(Context)
|
||||||
|
];
|
||||||
|
|
||||||
|
if (ParentViewportData->Window.IsValid())
|
||||||
|
{
|
||||||
|
FSlateApplication::Get().AddWindowAsNativeChild(Window, ParentViewportData->Window.Pin().ToSharedRef());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
FSlateApplication::Get().AddWindow(Window);
|
||||||
|
}
|
||||||
|
|
||||||
|
FImGuiViewportData* ViewportData = new FImGuiViewportData();
|
||||||
|
Viewport->PlatformUserData = ViewportData;
|
||||||
|
ViewportData->Context = ParentViewportData->Context;
|
||||||
|
ViewportData->Widget = Widget;
|
||||||
|
ViewportData->Window = Window;
|
||||||
|
|
||||||
|
ParentViewportData->Context->WindowToViewportMap.Add(Window, Viewport->ID);
|
||||||
|
|
||||||
|
Viewport->PlatformRequestResize = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------------------------------------------------------------
|
||||||
|
void FCogImguiContext::ImGui_DestroyWindow(ImGuiViewport* Viewport)
|
||||||
|
{
|
||||||
|
FImGuiViewportData* ViewportData = static_cast<FImGuiViewportData*>(Viewport->PlatformUserData);
|
||||||
|
if (ViewportData == nullptr)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((Viewport->Flags & ImGuiViewportFlags_OwnedByApp))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
ViewportData->Context->WindowToViewportMap.Remove(ViewportData->Window);
|
||||||
|
|
||||||
|
if (const TSharedPtr<SWindow> Window = ViewportData->Window.Pin())
|
||||||
|
{
|
||||||
|
Window->RequestDestroyWindow();
|
||||||
|
}
|
||||||
|
|
||||||
|
delete ViewportData;
|
||||||
|
Viewport->PlatformUserData = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------------------------------------------------------------
|
||||||
|
void FCogImguiContext::ImGui_ShowWindow(ImGuiViewport* Viewport)
|
||||||
|
{
|
||||||
|
if (const FImGuiViewportData* ViewportData = static_cast<FImGuiViewportData*>(Viewport->PlatformUserData))
|
||||||
|
{
|
||||||
|
if (const TSharedPtr<SWindow> Window = ViewportData->Window.Pin())
|
||||||
|
{
|
||||||
|
Window->ShowWindow();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------------------------------------------------------------
|
||||||
|
void FCogImguiContext::ImGui_SetWindowPos(ImGuiViewport* Viewport, ImVec2 Pos)
|
||||||
|
{
|
||||||
|
if (const FImGuiViewportData* ViewportData = static_cast<FImGuiViewportData*>(Viewport->PlatformUserData))
|
||||||
|
{
|
||||||
|
if (const TSharedPtr<SWindow> Window = ViewportData->Window.Pin())
|
||||||
|
{
|
||||||
|
Window->MoveWindowTo(FCogImguiHelper::ToFVector2D(Pos));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------------------------------------------------------------
|
||||||
|
ImVec2 FCogImguiContext::ImGui_GetWindowPos(ImGuiViewport* Viewport)
|
||||||
|
{
|
||||||
|
if (const FImGuiViewportData* ViewportData = static_cast<FImGuiViewportData*>(Viewport->PlatformUserData))
|
||||||
|
{
|
||||||
|
if (const TSharedPtr<SCogImguiWidget> Widget = ViewportData->Widget.Pin())
|
||||||
|
{
|
||||||
|
return FCogImguiHelper::ToImVec2(Widget->GetTickSpaceGeometry().GetAbsolutePosition());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return ImVec2(0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------------------------------------------------------------
|
||||||
|
void FCogImguiContext::ImGui_SetWindowSize(ImGuiViewport* Viewport, ImVec2 Size)
|
||||||
|
{
|
||||||
|
if (const FImGuiViewportData* ViewportData = static_cast<FImGuiViewportData*>(Viewport->PlatformUserData))
|
||||||
|
{
|
||||||
|
if (const TSharedPtr<SWindow> Window = ViewportData->Window.Pin())
|
||||||
|
{
|
||||||
|
Window->Resize(FCogImguiHelper::ToFVector2D(Size));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------------------------------------------------------------
|
||||||
|
ImVec2 FCogImguiContext::ImGui_GetWindowSize(ImGuiViewport* Viewport)
|
||||||
|
{
|
||||||
|
if (const FImGuiViewportData* ViewportData = static_cast<FImGuiViewportData*>(Viewport->PlatformUserData))
|
||||||
|
{
|
||||||
|
if (const TSharedPtr<SCogImguiWidget> Widget = ViewportData->Widget.Pin())
|
||||||
|
{
|
||||||
|
return FCogImguiHelper::ToImVec2(Widget->GetTickSpaceGeometry().GetAbsoluteSize());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return ImVec2(0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------------------------------------------------------------
|
||||||
|
void FCogImguiContext::ImGui_SetWindowFocus(ImGuiViewport* Viewport)
|
||||||
|
{
|
||||||
|
if (const FImGuiViewportData* ViewportData = static_cast<FImGuiViewportData*>(Viewport->PlatformUserData))
|
||||||
|
{
|
||||||
|
if (const TSharedPtr<SWindow> Window = ViewportData->Window.Pin())
|
||||||
|
{
|
||||||
|
if (const TSharedPtr<FGenericWindow> NativeWindow = Window->GetNativeWindow())
|
||||||
|
{
|
||||||
|
NativeWindow->BringToFront();
|
||||||
|
NativeWindow->SetWindowFocus();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------------------------------------------------------------
|
||||||
|
bool FCogImguiContext::ImGui_GetWindowFocus(ImGuiViewport* Viewport)
|
||||||
|
{
|
||||||
|
if (const FImGuiViewportData* ViewportData = static_cast<FImGuiViewportData*>(Viewport->PlatformUserData))
|
||||||
|
{
|
||||||
|
if (const TSharedPtr<SWindow> Window = ViewportData->Window.Pin())
|
||||||
|
{
|
||||||
|
if (const TSharedPtr<FGenericWindow> NativeWindow = Window->GetNativeWindow())
|
||||||
|
{
|
||||||
|
return NativeWindow->IsForegroundWindow();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------------------------------------------------------------
|
||||||
|
bool FCogImguiContext::ImGui_GetWindowMinimized(ImGuiViewport* Viewport)
|
||||||
|
{
|
||||||
|
if (const FImGuiViewportData* ViewportData = static_cast<FImGuiViewportData*>(Viewport->PlatformUserData))
|
||||||
|
{
|
||||||
|
if (const TSharedPtr<SWindow> Window = ViewportData->Window.Pin())
|
||||||
|
{
|
||||||
|
return Window->IsWindowMinimized();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------------------------------------------------------------
|
||||||
|
void FCogImguiContext::ImGui_SetWindowTitle(ImGuiViewport* Viewport, const char* TitleAnsi)
|
||||||
|
{
|
||||||
|
if (const FImGuiViewportData* ViewportData = static_cast<FImGuiViewportData*>(Viewport->PlatformUserData))
|
||||||
|
{
|
||||||
|
if (const TSharedPtr<SWindow> Window = ViewportData->Window.Pin())
|
||||||
|
{
|
||||||
|
Window->SetTitle(FText::FromString(ANSI_TO_TCHAR(TitleAnsi)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------------------------------------------------------------
|
||||||
|
void FCogImguiContext::ImGui_SetWindowAlpha(ImGuiViewport* Viewport, float Alpha)
|
||||||
|
{
|
||||||
|
if (const FImGuiViewportData* ViewportData = static_cast<FImGuiViewportData*>(Viewport->PlatformUserData))
|
||||||
|
{
|
||||||
|
if (const TSharedPtr<SWindow> Window = ViewportData->Window.Pin())
|
||||||
|
{
|
||||||
|
Window->SetOpacity(Alpha);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------------------------------------------------------------
|
||||||
|
void FCogImguiContext::ImGui_RenderWindow(ImGuiViewport* Viewport, void* Data)
|
||||||
|
{
|
||||||
|
if (const FImGuiViewportData* ViewportData = static_cast<FImGuiViewportData*>(Viewport->PlatformUserData))
|
||||||
|
{
|
||||||
|
if (const TSharedPtr<SCogImguiWidget> Widget = ViewportData->Widget.Pin())
|
||||||
|
{
|
||||||
|
Widget->SetDrawData(Viewport->DrawData);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------------------------------------------------------------
|
||||||
|
static UPlayerInput* GetPlayerInput(const UWorld* World)
|
||||||
|
{
|
||||||
|
if (World == nullptr)
|
||||||
|
{
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
APlayerController* PlayerController = nullptr;
|
||||||
|
for (FConstPlayerControllerIterator Iterator = World->GetPlayerControllerIterator(); Iterator; ++Iterator)
|
||||||
|
{
|
||||||
|
APlayerController* ItPlayerController = Iterator->Get();
|
||||||
|
if (ItPlayerController->IsLocalController())
|
||||||
|
{
|
||||||
|
PlayerController = ItPlayerController;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (PlayerController == nullptr)
|
||||||
|
{
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
UPlayerInput* PlayerInput = PlayerController->PlayerInput;
|
||||||
|
return PlayerInput;
|
||||||
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------------------------------------------------------------
|
||||||
|
void FCogImguiContext::SetEnableInput(bool Value)
|
||||||
|
{
|
||||||
|
bEnableInput = Value;
|
||||||
|
|
||||||
|
if (bEnableInput == false)
|
||||||
|
{
|
||||||
|
TryGiveMouseCaptureBackToGame();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------------------------------------------------------------
|
||||||
|
void FCogImguiContext::SetShareMouse(bool Value)
|
||||||
|
{
|
||||||
|
bShareMouse = Value;
|
||||||
|
|
||||||
|
if (bEnableInput == false)
|
||||||
|
{
|
||||||
|
TryGiveMouseCaptureBackToGame();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------------------------------------------------------------
|
||||||
|
void FCogImguiContext::TryReleaseGameMouseCapture()
|
||||||
|
{
|
||||||
|
if (bShareMouse)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (TSharedPtr<FSlateUser> User = FSlateApplication::Get().GetCursorUser())
|
||||||
|
{
|
||||||
|
if (User->HasCursorCapture())
|
||||||
|
{
|
||||||
|
PreviousMouseCaptor = User->GetCursorCaptor();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ULocalPlayer* LocalPlayer = GetLocalPlayer())
|
||||||
|
{
|
||||||
|
LocalPlayer->GetSlateOperations()
|
||||||
|
.ReleaseMouseLock()
|
||||||
|
.ReleaseMouseCapture();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------------------------------------------------------------
|
||||||
|
void FCogImguiContext::TryGiveMouseCaptureBackToGame()
|
||||||
|
{
|
||||||
|
if (PreviousMouseCaptor.IsValid() == false)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
TSharedRef<SWidget> PreviousMouseCaptorRef = PreviousMouseCaptor.Pin().ToSharedRef();
|
||||||
|
|
||||||
|
if (ULocalPlayer* LocalPlayer = GetLocalPlayer())
|
||||||
|
{
|
||||||
|
LocalPlayer->GetSlateOperations().CaptureMouse(PreviousMouseCaptorRef);
|
||||||
|
}
|
||||||
|
|
||||||
|
PreviousMouseCaptor.Reset();
|
||||||
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------------------------------------------------------------
|
||||||
|
void FCogImguiContext::SetDPIScale(float Value)
|
||||||
|
{
|
||||||
|
if (DpiScale == Value)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
DpiScale = Value;
|
||||||
|
bRefreshDPIScale = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------------------------------------------------------------
|
||||||
|
void FCogImguiContext::RefreshDPIScale()
|
||||||
|
{
|
||||||
|
bRefreshDPIScale = false;
|
||||||
|
|
||||||
|
BuildFont();
|
||||||
|
|
||||||
|
ImGuiStyle NewStyle = ImGuiStyle();
|
||||||
|
ImGui::GetStyle() = MoveTemp(NewStyle);
|
||||||
|
NewStyle.ScaleAllSizes(DpiScale);
|
||||||
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------------------------------------------------------------
|
||||||
|
void FCogImguiContext::BuildFont()
|
||||||
|
{
|
||||||
|
ImGuiIO& IO = ImGui::GetIO();
|
||||||
|
IO.Fonts->Clear();
|
||||||
|
|
||||||
|
ImFontConfig FontConfig;
|
||||||
|
FontConfig.SizePixels = FMath::RoundFromZero(13.f * DpiScale);
|
||||||
|
IO.Fonts->AddFontDefault(&FontConfig);
|
||||||
|
|
||||||
|
uint8* TextureDataRaw;
|
||||||
|
int32 TextureWidth, TextureHeight, BytesPerPixel;
|
||||||
|
IO.Fonts->GetTexDataAsRGBA32(&TextureDataRaw, &TextureWidth, &TextureHeight, &BytesPerPixel);
|
||||||
|
|
||||||
|
UTexture2D* FontAtlasTexture = UTexture2D::CreateTransient(TextureWidth, TextureHeight, PF_R8G8B8A8, TEXT("ImGuiFontAtlas"));
|
||||||
|
FontAtlasTexture->Filter = TF_Bilinear;
|
||||||
|
FontAtlasTexture->AddressX = TA_Wrap;
|
||||||
|
FontAtlasTexture->AddressY = TA_Wrap;
|
||||||
|
|
||||||
|
uint8* FontAtlasTextureData = static_cast<uint8*>(FontAtlasTexture->GetPlatformData()->Mips[0].BulkData.Lock(LOCK_READ_WRITE));
|
||||||
|
FMemory::Memcpy(FontAtlasTextureData, TextureDataRaw, TextureWidth * TextureHeight * BytesPerPixel);
|
||||||
|
FontAtlasTexture->GetPlatformData()->Mips[0].BulkData.Unlock();
|
||||||
|
FontAtlasTexture->UpdateResource();
|
||||||
|
|
||||||
|
IO.Fonts->SetTexID(FontAtlasTexture);
|
||||||
|
FontAtlasTexturePtr.Reset(FontAtlasTexture);
|
||||||
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------------------------------------------------------------
|
||||||
|
bool FCogImguiContext::IsConsoleOpened() const
|
||||||
|
{
|
||||||
|
return GameViewport->ViewportConsole && GameViewport->ViewportConsole->ConsoleState != NAME_None;
|
||||||
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------------------------------------------------------------
|
||||||
|
void FCogImguiContext::DrawDebug()
|
||||||
|
{
|
||||||
|
if (ImGui::Begin("ImGui Integration Debug"))
|
||||||
|
{
|
||||||
|
ImGui::BeginDisabled();
|
||||||
|
|
||||||
|
ImVec2 AbsPos = FCogImguiHelper::ToImVec2(MainWidget->GetTickSpaceGeometry().GetAbsolutePosition());
|
||||||
|
ImGui::InputFloat2("Widget Abs Pos", &AbsPos.x, "%0.1f");
|
||||||
|
|
||||||
|
ImVec2 AbsSize = FCogImguiHelper::ToImVec2(MainWidget->GetTickSpaceGeometry().GetAbsoluteSize());
|
||||||
|
ImGui::InputFloat2("Widget Abs Size", &AbsSize.x, "%0.1f");
|
||||||
|
|
||||||
|
ImVec2 LocalSize = FCogImguiHelper::ToImVec2(MainWidget->GetTickSpaceGeometry().GetLocalSize());
|
||||||
|
ImGui::InputFloat2("Widget Local Size", &LocalSize.x, "%0.1f");
|
||||||
|
|
||||||
|
FSlateApplication& SlateApp = FSlateApplication::Get();
|
||||||
|
ImVec2 MousePosition = FCogImguiHelper::ToImVec2(SlateApp.GetCursorPos());
|
||||||
|
ImGui::InputFloat2("Mouse", &MousePosition.x, "%0.1f");
|
||||||
|
|
||||||
|
ImGuiIO& IO = ImGui::GetIO();
|
||||||
|
ImGui::InputFloat2("ImGui Mouse", &IO.MousePos.x, "%0.1f");
|
||||||
|
|
||||||
|
FString Focus = "None";
|
||||||
|
if (TSharedPtr<SWidget> KeyboardFocusedWidget = SlateApp.GetKeyboardFocusedWidget())
|
||||||
|
{
|
||||||
|
Focus = KeyboardFocusedWidget->ToString();
|
||||||
|
}
|
||||||
|
static char Buffer[256] = "";
|
||||||
|
ImStrncpy(Buffer, TCHAR_TO_ANSI(*Focus), IM_ARRAYSIZE(Buffer));
|
||||||
|
ImGui::InputText("Keyboard Focus", Buffer, IM_ARRAYSIZE(Buffer));
|
||||||
|
|
||||||
|
ImGui::EndDisabled();
|
||||||
|
}
|
||||||
|
ImGui::End();
|
||||||
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------------------------------------------------------------
|
||||||
|
ULocalPlayer* FCogImguiContext::GetLocalPlayer() const
|
||||||
|
{
|
||||||
|
if (GameViewport == nullptr)
|
||||||
|
{
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
UWorld* World = GameViewport->GetWorld();
|
||||||
|
if (World == nullptr)
|
||||||
|
{
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
ULocalPlayer* LocalPlayer = World->GetFirstLocalPlayerFromController();
|
||||||
|
return LocalPlayer;
|
||||||
|
}
|
||||||
@@ -1,66 +1,28 @@
|
|||||||
#include "CogImguiDrawList.h"
|
#include "CogImguiDrawList.h"
|
||||||
|
|
||||||
|
#include "CogImguiHelper.h"
|
||||||
|
|
||||||
//--------------------------------------------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------------------------------------------
|
||||||
void FCogImguiDrawList::CopyVertexData(TArray<FSlateVertex>& OutVertexBuffer, const FTransform2D& Transform) const
|
FCogImguiDrawList::FCogImguiDrawList(ImDrawList* Source)
|
||||||
{
|
{
|
||||||
// Reset and reserve space in destination buffer.
|
VtxBuffer.swap(Source->VtxBuffer);
|
||||||
OutVertexBuffer.SetNumUninitialized(ImGuiVertexBuffer.Size, false);
|
IdxBuffer.swap(Source->IdxBuffer);
|
||||||
|
CmdBuffer.swap(Source->CmdBuffer);
|
||||||
// Transform and copy vertex data.
|
Flags = Source->Flags;
|
||||||
for (int Idx = 0; Idx < ImGuiVertexBuffer.Size; Idx++)
|
|
||||||
{
|
|
||||||
const ImDrawVert& ImGuiVertex = ImGuiVertexBuffer[Idx];
|
|
||||||
FSlateVertex& SlateVertex = OutVertexBuffer[Idx];
|
|
||||||
|
|
||||||
// Final UV is calculated in shader as XY * ZW, so we need set all components.
|
|
||||||
SlateVertex.TexCoords[0] = ImGuiVertex.uv.x;
|
|
||||||
SlateVertex.TexCoords[1] = ImGuiVertex.uv.y;
|
|
||||||
SlateVertex.TexCoords[2] = SlateVertex.TexCoords[3] = 1.f;
|
|
||||||
|
|
||||||
const FVector2D VertexPosition = Transform.TransformPoint(FCogImguiHelper::ToVector2D(ImGuiVertex.pos));
|
|
||||||
SlateVertex.Position[0] = VertexPosition.X;
|
|
||||||
SlateVertex.Position[1] = VertexPosition.Y;
|
|
||||||
|
|
||||||
// Unpack ImU32 color.
|
|
||||||
SlateVertex.Color = FCogImguiHelper::UnpackImU32Color(ImGuiVertex.col);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//--------------------------------------------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------------------------------------------
|
||||||
FCogImguiDrawList::DrawCommand FCogImguiDrawList::GetCommand(int CommandCount, const FTransform2D& Transform) const
|
FCogImguiDrawData::FCogImguiDrawData(const ImDrawData* Source)
|
||||||
{
|
{
|
||||||
const ImDrawCmd& ImGuiCommand = ImGuiCommandBuffer[CommandCount];
|
bValid = Source->Valid;
|
||||||
return
|
|
||||||
{
|
|
||||||
ImGuiCommand.ElemCount,
|
|
||||||
TransformRect(Transform, FCogImguiHelper::ToSlateRect(ImGuiCommand.ClipRect)),
|
|
||||||
FCogImguiHelper::ToTextureIndex(ImGuiCommand.TextureId)
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
//--------------------------------------------------------------------------------------------------------------------------
|
TotalIdxCount = Source->TotalIdxCount;
|
||||||
void FCogImguiDrawList::CopyIndexData(TArray<SlateIndex>& OutIndexBuffer, const int32 StartIndex, const int32 NumElements) const
|
TotalVtxCount = Source->TotalVtxCount;
|
||||||
{
|
|
||||||
// Reset buffer.
|
|
||||||
OutIndexBuffer.SetNumUninitialized(NumElements, false);
|
|
||||||
|
|
||||||
// Copy elements (slow copy because of different sizes of ImDrawIdx and SlateIndex and because SlateIndex can
|
DrawLists.SetNumUninitialized(Source->CmdListsCount);
|
||||||
// have different size on different platforms).
|
ConstructItems<FCogImguiDrawList>(DrawLists.GetData(), Source->CmdLists.Data, Source->CmdListsCount);
|
||||||
for (int i = 0; i < NumElements; i++)
|
|
||||||
{
|
|
||||||
OutIndexBuffer[i] = ImGuiIndexBuffer[StartIndex + i];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//--------------------------------------------------------------------------------------------------------------------------
|
DisplayPos = FCogImguiHelper::ToFVector2f(Source->DisplayPos);
|
||||||
void FCogImguiDrawList::TransferDrawData(ImDrawList& Src)
|
DisplaySize = FCogImguiHelper::ToFVector2f(Source->DisplaySize);
|
||||||
{
|
FrameBufferScale = FCogImguiHelper::ToFVector2f(Source->FramebufferScale);
|
||||||
// Move data from source to this list.
|
|
||||||
Src.CmdBuffer.swap(ImGuiCommandBuffer);
|
|
||||||
Src.IdxBuffer.swap(ImGuiIndexBuffer);
|
|
||||||
Src.VtxBuffer.swap(ImGuiVertexBuffer);
|
|
||||||
|
|
||||||
// ImGui seems to clear draw lists in every frame, but since source list can contain pointers to buffers that
|
|
||||||
// we just swapped, it is better to clear explicitly here.
|
|
||||||
Src._ResetForNewFrame();
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -31,7 +31,7 @@ ImGuiWindow* FCogImguiHelper::GetCurrentWindow()
|
|||||||
}
|
}
|
||||||
|
|
||||||
//--------------------------------------------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------------------------------------------
|
||||||
FColor FCogImguiHelper::UnpackImU32Color(ImU32 Color)
|
FColor FCogImguiHelper::ToFColor(ImU32 Color)
|
||||||
{
|
{
|
||||||
return FColor
|
return FColor
|
||||||
{
|
{
|
||||||
@@ -49,7 +49,13 @@ FSlateRect FCogImguiHelper::ToSlateRect(const ImVec4& Value)
|
|||||||
}
|
}
|
||||||
|
|
||||||
//--------------------------------------------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------------------------------------------
|
||||||
FVector2D FCogImguiHelper::ToVector2D(const ImVec2& Value)
|
FVector2f FCogImguiHelper::ToFVector2f(const ImVec2& Value)
|
||||||
|
{
|
||||||
|
return FVector2f(Value.x, Value.y);
|
||||||
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------------------------------------------------------------
|
||||||
|
FVector2D FCogImguiHelper::ToFVector2D(const ImVec2& Value)
|
||||||
{
|
{
|
||||||
return FVector2D(Value.x, Value.y);
|
return FVector2D(Value.x, Value.y);
|
||||||
}
|
}
|
||||||
@@ -90,7 +96,6 @@ ImVec4 FCogImguiHelper::ToImVec4(const FVector4f& Value)
|
|||||||
return ImVec4(Value.X, Value.Y, Value.Z, Value.W);
|
return ImVec4(Value.X, Value.Y, Value.Z, Value.W);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//--------------------------------------------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------------------------------------------
|
||||||
ImU32 FCogImguiHelper::ToImU32(const FColor& Value)
|
ImU32 FCogImguiHelper::ToImU32(const FColor& Value)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,18 +1,11 @@
|
|||||||
#include "CogImguiModule.h"
|
#include "CogImguiModule.h"
|
||||||
|
|
||||||
#include "CogImguiWidget.h"
|
#include "imgui.h"
|
||||||
#include "Engine/Engine.h"
|
|
||||||
#include "Engine/GameViewportClient.h"
|
|
||||||
#include "HAL/LowLevelMemTracker.h"
|
#include "HAL/LowLevelMemTracker.h"
|
||||||
#include "HAL/UnrealMemory.h"
|
#include "HAL/UnrealMemory.h"
|
||||||
#include "Widgets/Layout/SScaleBox.h"
|
|
||||||
|
|
||||||
#define LOCTEXT_NAMESPACE "FCogImguiModule"
|
#define LOCTEXT_NAMESPACE "FCogImguiModule"
|
||||||
|
|
||||||
//--------------------------------------------------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
constexpr int32 Cog_ZOrder = 10000;
|
|
||||||
|
|
||||||
//--------------------------------------------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------------------------------------------
|
||||||
static void* ImGui_MemAlloc(size_t Size, void* UserData)
|
static void* ImGui_MemAlloc(size_t Size, void* UserData)
|
||||||
{
|
{
|
||||||
@@ -37,64 +30,6 @@ void FCogImguiModule::ShutdownModule()
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
//--------------------------------------------------------------------------------------------------------------------------
|
|
||||||
void FCogImguiModule::Initialize()
|
|
||||||
{
|
|
||||||
TextureManager.InitializeErrorTexture();
|
|
||||||
TextureManager.CreatePlainTexture("ImGuiModule_Plain", 2, 2, FColor::White);
|
|
||||||
|
|
||||||
unsigned char* Pixels;
|
|
||||||
int Width, Height, Bpp;
|
|
||||||
|
|
||||||
DefaultFontAtlas.Clear();
|
|
||||||
DefaultFontAtlas.GetTexDataAsRGBA32(&Pixels, &Width, &Height, &Bpp);
|
|
||||||
const CogTextureIndex FontsTexureIndex = TextureManager.CreateTexture("ImGuiModule_FontAtlas", Width, Height, Bpp, Pixels);
|
|
||||||
DefaultFontAtlas.TexID = FCogImguiHelper::ToImTextureID(FontsTexureIndex);
|
|
||||||
}
|
|
||||||
|
|
||||||
//--------------------------------------------------------------------------------------------------------------------------
|
|
||||||
TSharedPtr<SCogImguiWidget> FCogImguiModule::CreateImGuiWidget(UGameViewportClient* GameViewport, FCogImguiRenderFunction Render, ImFontAtlas* FontAtlas /*= nullptr*/)
|
|
||||||
{
|
|
||||||
if (bIsInitialized == false)
|
|
||||||
{
|
|
||||||
Initialize();
|
|
||||||
bIsInitialized = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (FontAtlas == nullptr)
|
|
||||||
{
|
|
||||||
FontAtlas = &DefaultFontAtlas;
|
|
||||||
}
|
|
||||||
|
|
||||||
TSharedPtr<SCogImguiWidget> ImguiWidget;
|
|
||||||
SAssignNew(ImguiWidget, SCogImguiWidget)
|
|
||||||
.GameViewport(GameViewport)
|
|
||||||
.FontAtlas(FontAtlas)
|
|
||||||
.Render(Render);
|
|
||||||
|
|
||||||
GameViewport->AddViewportWidgetContent(ImguiWidget.ToSharedRef(), TNumericLimits<int32>::Max());
|
|
||||||
|
|
||||||
return ImguiWidget;
|
|
||||||
}
|
|
||||||
|
|
||||||
//--------------------------------------------------------------------------------------------------------------------------
|
|
||||||
void FCogImguiModule::DestroyImGuiWidget(TSharedPtr<SCogImguiWidget> ImGuiWidget)
|
|
||||||
{
|
|
||||||
UGameViewportClient* Viewport = ImGuiWidget->GetGameViewport().Get();
|
|
||||||
if (Viewport == nullptr)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
TSharedPtr<SWidget> ParentWidget = ImGuiWidget->GetParentWidget();
|
|
||||||
if (ParentWidget.IsValid() == false)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
Viewport->RemoveViewportWidgetContent(ParentWidget.ToSharedRef());
|
|
||||||
}
|
|
||||||
|
|
||||||
//--------------------------------------------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------------------------------------------
|
||||||
#undef LOCTEXT_NAMESPACE
|
#undef LOCTEXT_NAMESPACE
|
||||||
|
|
||||||
|
|||||||
@@ -1,195 +0,0 @@
|
|||||||
#include "CogImguiTextureManager.h"
|
|
||||||
|
|
||||||
#include "Framework/Application/SlateApplication.h"
|
|
||||||
|
|
||||||
//--------------------------------------------------------------------------------------------------------------------------
|
|
||||||
void FCogImguiTextureManager::InitializeErrorTexture()
|
|
||||||
{
|
|
||||||
CreatePlainTextureInternal(NAME_ErrorTexture, 2, 2, FColor::Magenta);
|
|
||||||
}
|
|
||||||
|
|
||||||
//--------------------------------------------------------------------------------------------------------------------------
|
|
||||||
CogTextureIndex FCogImguiTextureManager::CreateTexture(const FName& Name, int32 Width, int32 Height, uint32 SrcBpp, uint8* SrcData, TFunction<void(uint8*)> SrcDataCleanup)
|
|
||||||
{
|
|
||||||
checkf(Name != NAME_None, TEXT("Trying to create a texture with a name 'NAME_None' is not allowed."));
|
|
||||||
|
|
||||||
return CreateTextureInternal(Name, Width, Height, SrcBpp, SrcData, SrcDataCleanup);
|
|
||||||
}
|
|
||||||
|
|
||||||
//--------------------------------------------------------------------------------------------------------------------------
|
|
||||||
CogTextureIndex FCogImguiTextureManager::CreatePlainTexture(const FName& Name, int32 Width, int32 Height, FColor Color)
|
|
||||||
{
|
|
||||||
checkf(Name != NAME_None, TEXT("Trying to create a texture with a name 'NAME_None' is not allowed."));
|
|
||||||
|
|
||||||
return CreatePlainTextureInternal(Name, Width, Height, Color);
|
|
||||||
}
|
|
||||||
|
|
||||||
//--------------------------------------------------------------------------------------------------------------------------
|
|
||||||
CogTextureIndex FCogImguiTextureManager::CreateTextureResources(const FName& Name, UTexture2D* Texture)
|
|
||||||
{
|
|
||||||
checkf(Name != NAME_None, TEXT("Trying to create texture resources with a name 'NAME_None' is not allowed."));
|
|
||||||
checkf(Texture, TEXT("Null Texture."));
|
|
||||||
|
|
||||||
// Create an entry for the texture.
|
|
||||||
return AddTextureEntry(Name, Texture, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
//--------------------------------------------------------------------------------------------------------------------------
|
|
||||||
void FCogImguiTextureManager::ReleaseTextureResources(CogTextureIndex Index)
|
|
||||||
{
|
|
||||||
checkf(IsInRange(Index), TEXT("Invalid texture index %d. Texture resources array has %d entries total."), Index, TextureResources.Num());
|
|
||||||
|
|
||||||
TextureResources[Index] = {};
|
|
||||||
}
|
|
||||||
|
|
||||||
//--------------------------------------------------------------------------------------------------------------------------
|
|
||||||
CogTextureIndex FCogImguiTextureManager::CreateTextureInternal(const FName& Name, int32 Width, int32 Height, uint32 SrcBpp, uint8* SrcData, TFunction<void(uint8*)> SrcDataCleanup)
|
|
||||||
{
|
|
||||||
// Create a texture.
|
|
||||||
UTexture2D* Texture = UTexture2D::CreateTransient(Width, Height);
|
|
||||||
|
|
||||||
// Create a new resource for that texture.
|
|
||||||
Texture->UpdateResource();
|
|
||||||
|
|
||||||
// Update texture data.
|
|
||||||
FUpdateTextureRegion2D* TextureRegion = new FUpdateTextureRegion2D(0, 0, 0, 0, Width, Height);
|
|
||||||
auto DataCleanup = [SrcDataCleanup](uint8* Data, const FUpdateTextureRegion2D* UpdateRegion)
|
|
||||||
{
|
|
||||||
SrcDataCleanup(Data);
|
|
||||||
delete UpdateRegion;
|
|
||||||
};
|
|
||||||
Texture->UpdateTextureRegions(0, 1u, TextureRegion, SrcBpp * Width, SrcBpp, SrcData, DataCleanup);
|
|
||||||
|
|
||||||
// Create an entry for the texture.
|
|
||||||
if (Name == NAME_ErrorTexture)
|
|
||||||
{
|
|
||||||
ErrorTexture = { Name, Texture, true };
|
|
||||||
return INDEX_ErrorTexture;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return AddTextureEntry(Name, Texture, true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//--------------------------------------------------------------------------------------------------------------------------
|
|
||||||
CogTextureIndex FCogImguiTextureManager::CreatePlainTextureInternal(const FName& Name, int32 Width, int32 Height, const FColor& Color)
|
|
||||||
{
|
|
||||||
// Create buffer with raw data.
|
|
||||||
const uint32 ColorPacked = Color.ToPackedARGB();
|
|
||||||
const uint32 Bpp = sizeof(ColorPacked);
|
|
||||||
const uint32 SizeInPixels = Width * Height;
|
|
||||||
const uint32 SizeInBytes = SizeInPixels * Bpp;
|
|
||||||
uint8* SrcData = new uint8[SizeInBytes];
|
|
||||||
std::fill(reinterpret_cast<uint32*>(SrcData), reinterpret_cast<uint32*>(SrcData) + SizeInPixels, ColorPacked);
|
|
||||||
auto SrcDataCleanup = [](uint8* Data) { delete[] Data; };
|
|
||||||
|
|
||||||
// Create new texture from raw data.
|
|
||||||
return CreateTextureInternal(Name, Width, Height, Bpp, SrcData, SrcDataCleanup);
|
|
||||||
}
|
|
||||||
|
|
||||||
//--------------------------------------------------------------------------------------------------------------------------
|
|
||||||
CogTextureIndex FCogImguiTextureManager::AddTextureEntry(const FName& Name, UTexture2D* Texture, bool bAddToRoot)
|
|
||||||
{
|
|
||||||
// Try to find an entry with that name.
|
|
||||||
CogTextureIndex Index = FindTextureIndex(Name);
|
|
||||||
|
|
||||||
// If this is a new name, try to find an entry to reuse.
|
|
||||||
if (Index == INDEX_NONE)
|
|
||||||
{
|
|
||||||
Index = FindTextureIndex(NAME_None);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Either update/reuse an entry or add a new one.
|
|
||||||
if (Index != INDEX_NONE)
|
|
||||||
{
|
|
||||||
TextureResources[Index] = { Name, Texture, bAddToRoot };
|
|
||||||
return Index;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return TextureResources.Emplace(Name, Texture, bAddToRoot);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//--------------------------------------------------------------------------------------------------------------------------
|
|
||||||
FCogImguiTextureManager::FTextureEntry::FTextureEntry(const FName& InName, UTexture2D* InTexture, bool bAddToRoot)
|
|
||||||
: Name(InName)
|
|
||||||
{
|
|
||||||
checkf(InTexture, TEXT("Null texture."));
|
|
||||||
|
|
||||||
if (bAddToRoot)
|
|
||||||
{
|
|
||||||
// Get pointer only for textures that we added to root, so we can later release them.
|
|
||||||
Texture = InTexture;
|
|
||||||
// Add texture to the root to prevent garbage collection.
|
|
||||||
InTexture->AddToRoot();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Create brush and resource handle for input texture.
|
|
||||||
Brush.SetResourceObject(InTexture);
|
|
||||||
CachedResourceHandle = FSlateApplication::Get().GetRenderer()->GetResourceHandle(Brush);
|
|
||||||
}
|
|
||||||
|
|
||||||
//--------------------------------------------------------------------------------------------------------------------------
|
|
||||||
FCogImguiTextureManager::FTextureEntry::~FTextureEntry()
|
|
||||||
{
|
|
||||||
Reset(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
//--------------------------------------------------------------------------------------------------------------------------
|
|
||||||
FCogImguiTextureManager::FTextureEntry& FCogImguiTextureManager::FTextureEntry::operator=(FTextureEntry&& Other)
|
|
||||||
{
|
|
||||||
// Release old resources if allocated.
|
|
||||||
Reset(true);
|
|
||||||
|
|
||||||
// Move data and ownership to this instance.
|
|
||||||
Name = MoveTemp(Other.Name);
|
|
||||||
Texture = MoveTemp(Other.Texture);
|
|
||||||
Brush = MoveTemp(Other.Brush);
|
|
||||||
CachedResourceHandle = MoveTemp(Other.CachedResourceHandle);
|
|
||||||
|
|
||||||
// Reset the other entry (without releasing resources which are already moved to this instance) to remove tracks
|
|
||||||
// of ownership and mark it as empty/reusable.
|
|
||||||
Other.Reset(false);
|
|
||||||
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
//--------------------------------------------------------------------------------------------------------------------------
|
|
||||||
const FSlateResourceHandle& FCogImguiTextureManager::FTextureEntry::GetResourceHandle() const
|
|
||||||
{
|
|
||||||
if (!CachedResourceHandle.IsValid() && Brush.HasUObject())
|
|
||||||
{
|
|
||||||
CachedResourceHandle = FSlateApplication::Get().GetRenderer()->GetResourceHandle(Brush);
|
|
||||||
}
|
|
||||||
return CachedResourceHandle;
|
|
||||||
}
|
|
||||||
|
|
||||||
//--------------------------------------------------------------------------------------------------------------------------
|
|
||||||
void FCogImguiTextureManager::FTextureEntry::Reset(bool bReleaseResources)
|
|
||||||
{
|
|
||||||
if (bReleaseResources)
|
|
||||||
{
|
|
||||||
// Release brush.
|
|
||||||
if (Brush.HasUObject() && FSlateApplication::IsInitialized())
|
|
||||||
{
|
|
||||||
FSlateApplication::Get().GetRenderer()->ReleaseDynamicResource(Brush);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Remove texture from root to allow for garbage collection (it might be invalid, if we never set it
|
|
||||||
// or this is an application shutdown).
|
|
||||||
if (Texture.IsValid())
|
|
||||||
{
|
|
||||||
Texture->RemoveFromRoot();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// We use empty name to mark unused entries.
|
|
||||||
Name = NAME_None;
|
|
||||||
|
|
||||||
// Clean fields to make sure that we don't reference released or moved resources.
|
|
||||||
Texture.Reset();
|
|
||||||
Brush = FSlateNoResource();
|
|
||||||
CachedResourceHandle = FSlateResourceHandle();
|
|
||||||
}
|
|
||||||
@@ -1,227 +1,32 @@
|
|||||||
#include "CogImguiWidget.h"
|
#include "CogImguiWidget.h"
|
||||||
|
|
||||||
#include "CogImguiInputHelper.h"
|
#include "CogImguiInputHelper.h"
|
||||||
#include "CogImguiInputHelper.h"
|
|
||||||
#include "CogImGuiInputProcessor.h"
|
|
||||||
#include "CogImguiModule.h"
|
#include "CogImguiModule.h"
|
||||||
#include "CogImguiModule.h"
|
|
||||||
#include "CogImguiTextureManager.h"
|
|
||||||
#include "CogImguiWidget.h"
|
#include "CogImguiWidget.h"
|
||||||
#include "Engine/Console.h"
|
|
||||||
#include "Engine/GameViewportClient.h"
|
|
||||||
#include "Engine/LocalPlayer.h"
|
|
||||||
#include "Framework/Application/SlateApplication.h"
|
|
||||||
#include "GameFramework/PlayerController.h"
|
|
||||||
#include "imgui.h"
|
#include "imgui.h"
|
||||||
#include "imgui_internal.h"
|
|
||||||
#include "implot.h"
|
|
||||||
#include "SlateOptMacros.h"
|
#include "SlateOptMacros.h"
|
||||||
#include "UnrealClient.h"
|
|
||||||
#include "Widgets/Layout/SBorder.h"
|
|
||||||
#include "Widgets/Layout/SBox.h"
|
|
||||||
#include "Widgets/SViewport.h"
|
|
||||||
|
|
||||||
//--------------------------------------------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------------------------------------------
|
||||||
BEGIN_SLATE_FUNCTION_BUILD_OPTIMIZATION
|
BEGIN_SLATE_FUNCTION_BUILD_OPTIMIZATION
|
||||||
void SCogImguiWidget::Construct(const FArguments& InArgs)
|
void SCogImguiWidget::Construct(const FArguments& InArgs)
|
||||||
{
|
{
|
||||||
checkf(InArgs._GameViewport, TEXT("Null Game Viewport argument"));
|
Context = InArgs._Context;
|
||||||
|
|
||||||
GameViewport = InArgs._GameViewport;
|
|
||||||
FontAtlas = InArgs._FontAtlas;
|
|
||||||
Render = InArgs._Render;
|
|
||||||
|
|
||||||
SetVisibility(EVisibility::SelfHitTestInvisible);
|
SetVisibility(EVisibility::SelfHitTestInvisible);
|
||||||
|
|
||||||
ImGuiContext = ImGui::CreateContext(FontAtlas);
|
|
||||||
ImPlotContext = ImPlot::CreateContext();
|
|
||||||
ImPlot::SetImGuiContext(ImGuiContext);
|
|
||||||
|
|
||||||
const char* InitFilenameTemp = TCHAR_TO_ANSI(*FCogImguiHelper::GetIniFilePath("imgui"));
|
|
||||||
ImStrncpy(IniFilename, InitFilenameTemp, IM_ARRAYSIZE(IniFilename));
|
|
||||||
|
|
||||||
ImGuiIO& IO = ImGui::GetIO();
|
|
||||||
IO.IniFilename = IniFilename;
|
|
||||||
IO.DisplaySize = ImVec2(100, 100);
|
|
||||||
IO.ConfigFlags |= ImGuiConfigFlags_DockingEnable;
|
|
||||||
IO.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard;
|
|
||||||
IO.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad;
|
|
||||||
IO.ConfigFlags |= ImGuiConfigFlags_NavNoCaptureKeyboard;
|
|
||||||
|
|
||||||
//--------------------------------------------------------------------
|
|
||||||
// Register input processor to forward input events to imgui
|
|
||||||
//--------------------------------------------------------------------
|
|
||||||
if (FSlateApplication::IsInitialized())
|
|
||||||
{
|
|
||||||
UPlayerInput* PlayerInput = FCogImguiInputHelper::GetPlayerInput(*GameViewport->GetWorld());
|
|
||||||
InputProcessor = MakeShared<FImGuiInputProcessor>(PlayerInput, this);
|
|
||||||
FSlateApplication::Get().RegisterInputPreProcessor(InputProcessor.ToSharedRef(), 0);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
END_SLATE_FUNCTION_BUILD_OPTIMIZATION
|
END_SLATE_FUNCTION_BUILD_OPTIMIZATION
|
||||||
|
|
||||||
//--------------------------------------------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------------------------------------------
|
||||||
SCogImguiWidget::~SCogImguiWidget()
|
SCogImguiWidget::~SCogImguiWidget()
|
||||||
{
|
{
|
||||||
if (FSlateApplication::IsInitialized())
|
|
||||||
{
|
|
||||||
if (InputProcessor.IsValid())
|
|
||||||
{
|
|
||||||
FSlateApplication::Get().UnregisterInputPreProcessor(InputProcessor);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
DestroyImGuiContext();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//--------------------------------------------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------------------------------------------
|
||||||
void SCogImguiWidget::DestroyImGuiContext()
|
void SCogImguiWidget::SetDrawData(const ImDrawData* InDrawData)
|
||||||
{
|
{
|
||||||
if (ImPlotContext != nullptr)
|
DrawData = FCogImguiDrawData(InDrawData);
|
||||||
{
|
|
||||||
ImPlot::DestroyContext(ImPlotContext);
|
|
||||||
ImPlotContext = nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ImGuiContext != nullptr)
|
|
||||||
{
|
|
||||||
ImGui::DestroyContext(ImGuiContext);
|
|
||||||
ImGuiContext = nullptr;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//--------------------------------------------------------------------------------------------------------------------------
|
|
||||||
void SCogImguiWidget::Tick(const FGeometry& AllottedGeometry, const double InCurrentTime, const float InDeltaTime)
|
|
||||||
{
|
|
||||||
Super::Tick(AllottedGeometry, InCurrentTime, InDeltaTime);
|
|
||||||
|
|
||||||
TickKeyModifiers();
|
|
||||||
TickFocus();
|
|
||||||
TickImGui(InDeltaTime);
|
|
||||||
}
|
|
||||||
|
|
||||||
//--------------------------------------------------------------------------------------------------------------------------
|
|
||||||
void SCogImguiWidget::TickKeyModifiers()
|
|
||||||
{
|
|
||||||
//-------------------------------------------------------------------------------------------------------
|
|
||||||
// Refresh modifiers otherwise, when pressing ALT-TAB, the Alt modifier is always true
|
|
||||||
//-------------------------------------------------------------------------------------------------------
|
|
||||||
FModifierKeysState ModifierKeys = FSlateApplication::Get().GetModifierKeys();
|
|
||||||
|
|
||||||
ImGuiIO& IO = ImGui::GetIO();
|
|
||||||
if (ModifierKeys.IsControlDown() != IO.KeyCtrl) { IO.AddKeyEvent(ImGuiMod_Ctrl, ModifierKeys.IsControlDown()); }
|
|
||||||
if (ModifierKeys.IsShiftDown() != IO.KeyShift) { IO.AddKeyEvent(ImGuiMod_Shift, ModifierKeys.IsShiftDown()); }
|
|
||||||
if (ModifierKeys.IsAltDown() != IO.KeyAlt) { IO.AddKeyEvent(ImGuiMod_Alt, ModifierKeys.IsAltDown()); }
|
|
||||||
if (ModifierKeys.IsCommandDown() != IO.KeySuper) { IO.AddKeyEvent(ImGuiMod_Super, ModifierKeys.IsCommandDown()); }
|
|
||||||
}
|
|
||||||
|
|
||||||
//--------------------------------------------------------------------------------------------------------------------------
|
|
||||||
void SCogImguiWidget::TickImGui(float InDeltaTime)
|
|
||||||
{
|
|
||||||
if (ImGuiContext == nullptr)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
ImGui::SetCurrentContext(ImGuiContext);
|
|
||||||
ImPlot::SetImGuiContext(ImGuiContext);
|
|
||||||
ImPlot::SetCurrentContext(ImPlotContext);
|
|
||||||
|
|
||||||
ImGuiIO& IO = ImGui::GetIO();
|
|
||||||
IO.DeltaTime = FApp::GetDeltaTime();
|
|
||||||
IO.DisplaySize = FCogImguiHelper::ToImVec2(GetTickSpaceGeometry().GetAbsoluteSize());
|
|
||||||
|
|
||||||
ImGui::NewFrame();
|
|
||||||
|
|
||||||
Render(InDeltaTime);
|
|
||||||
//DrawDebug();
|
|
||||||
|
|
||||||
ImGui::Render();
|
|
||||||
|
|
||||||
if ((IO.ConfigFlags & ImGuiConfigFlags_NoMouse) == 0)
|
|
||||||
{
|
|
||||||
SetCursor(FCogImguiInputHelper::ToSlateMouseCursor(ImGui::GetMouseCursor()));
|
|
||||||
}
|
|
||||||
|
|
||||||
ImDrawData* DrawData = ImGui::GetDrawData();
|
|
||||||
if (DrawData && DrawData->CmdListsCount > 0)
|
|
||||||
{
|
|
||||||
DrawLists.SetNum(DrawData->CmdListsCount, false);
|
|
||||||
for (int i = 0; i < DrawData->CmdListsCount; i++)
|
|
||||||
{
|
|
||||||
DrawLists[i].TransferDrawData(*DrawData->CmdLists[i]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
DrawLists.Empty();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//--------------------------------------------------------------------------------------------------------------------------
|
|
||||||
void SCogImguiWidget::TickFocus()
|
|
||||||
{
|
|
||||||
if (bEnableInput)
|
|
||||||
{
|
|
||||||
const auto& ViewportWidget = GameViewport->GetGameViewportWidget();
|
|
||||||
if (!HasKeyboardFocus() && !IsConsoleOpened() && (ViewportWidget->HasKeyboardFocus() || ViewportWidget->HasFocusedDescendants()))
|
|
||||||
{
|
|
||||||
TakeFocus();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//--------------------------------------------------------------------------------------------------------------------------
|
|
||||||
void SCogImguiWidget::TakeFocus()
|
|
||||||
{
|
|
||||||
FSlateApplication& SlateApplication = FSlateApplication::Get();
|
|
||||||
|
|
||||||
PreviousUserFocusedWidget = SlateApplication.GetUserFocusedWidget(SlateApplication.GetUserIndexForKeyboard());
|
|
||||||
|
|
||||||
if (ULocalPlayer* LocalPlayer = GetLocalPlayer())
|
|
||||||
{
|
|
||||||
TSharedRef<SWidget> FocusWidget = SharedThis(this);
|
|
||||||
LocalPlayer->GetSlateOperations().CaptureMouse(FocusWidget);
|
|
||||||
LocalPlayer->GetSlateOperations().SetUserFocus(FocusWidget);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
SlateApplication.SetKeyboardFocus(SharedThis(this));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//--------------------------------------------------------------------------------------------------------------------------
|
|
||||||
void SCogImguiWidget::ReturnFocus()
|
|
||||||
{
|
|
||||||
if (HasKeyboardFocus())
|
|
||||||
{
|
|
||||||
auto FocusWidgetPtr = PreviousUserFocusedWidget.IsValid()
|
|
||||||
? PreviousUserFocusedWidget.Pin()
|
|
||||||
: GameViewport->GetGameViewportWidget();
|
|
||||||
|
|
||||||
if (ULocalPlayer* LocalPlayer = GetLocalPlayer())
|
|
||||||
{
|
|
||||||
auto FocusWidgetRef = FocusWidgetPtr.ToSharedRef();
|
|
||||||
|
|
||||||
if (FocusWidgetPtr == GameViewport->GetGameViewportWidget())
|
|
||||||
{
|
|
||||||
LocalPlayer->GetSlateOperations().CaptureMouse(FocusWidgetRef);
|
|
||||||
}
|
|
||||||
|
|
||||||
LocalPlayer->GetSlateOperations().SetUserFocus(FocusWidgetRef);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
FSlateApplication& SlateApplication = FSlateApplication::Get();
|
|
||||||
SlateApplication.ResetToDefaultPointerInputSettings();
|
|
||||||
SlateApplication.SetUserFocus(SlateApplication.GetUserIndexForKeyboard(), FocusWidgetPtr);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
PreviousUserFocusedWidget.Reset();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//--------------------------------------------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------------------------------------------
|
||||||
int32 SCogImguiWidget::OnPaint(
|
int32 SCogImguiWidget::OnPaint(
|
||||||
const FPaintArgs& Args,
|
const FPaintArgs& Args,
|
||||||
@@ -233,36 +38,56 @@ int32 SCogImguiWidget::OnPaint(
|
|||||||
bool bParentEnabled) const
|
bool bParentEnabled) const
|
||||||
{
|
{
|
||||||
|
|
||||||
const FSlateRenderTransform& WidgetToScreen = AllottedGeometry.GetAccumulatedRenderTransform().GetTranslation();
|
const FSlateRenderTransform Transform(FCogImguiHelper::RoundTranslation(AllottedGeometry.GetAccumulatedRenderTransform().GetTranslation() - FVector2d(DrawData.DisplayPos)));
|
||||||
const FSlateRenderTransform ImGuiToScreen = FCogImguiHelper::RoundTranslation(ImGuiRenderTransform.Concatenate(WidgetToScreen));
|
|
||||||
|
|
||||||
FCogImguiTextureManager& TextureManager = FCogImguiModule::Get().GetTextureManager();
|
FSlateBrush TextureBrush;
|
||||||
|
for (const FCogImguiDrawList& DrawList : DrawData.DrawLists)
|
||||||
for (const auto& DrawList : DrawLists)
|
|
||||||
{
|
{
|
||||||
DrawList.CopyVertexData(VertexBuffer, ImGuiToScreen);
|
TArray<FSlateVertex> Vertices;
|
||||||
|
Vertices.SetNumUninitialized(DrawList.VtxBuffer.Size);
|
||||||
int IndexBufferOffset = 0;
|
for (int32 BufferIdx = 0; BufferIdx < Vertices.Num(); ++BufferIdx)
|
||||||
for (int i = 0; i < DrawList.NumCommands(); i++)
|
|
||||||
{
|
{
|
||||||
const auto& DrawCommand = DrawList.GetCommand(i, ImGuiToScreen);
|
const ImDrawVert& Vtx = DrawList.VtxBuffer.Data[BufferIdx];
|
||||||
|
Vertices[BufferIdx] = FSlateVertex::Make<ESlateVertexRounding::Disabled>(Transform, FCogImguiHelper::ToFVector2f(Vtx.pos), FCogImguiHelper::ToFVector2f(Vtx.uv), FVector2f::UnitVector, FCogImguiHelper::ToFColor(Vtx.col));
|
||||||
|
}
|
||||||
|
|
||||||
DrawList.CopyIndexData(IndexBuffer, IndexBufferOffset, DrawCommand.NumElements);
|
TArray<SlateIndex> Indices;
|
||||||
|
Indices.SetNumUninitialized(DrawList.IdxBuffer.Size);
|
||||||
|
for (int32 BufferIdx = 0; BufferIdx < Indices.Num(); ++BufferIdx)
|
||||||
|
{
|
||||||
|
Indices[BufferIdx] = DrawList.IdxBuffer.Data[BufferIdx];
|
||||||
|
}
|
||||||
|
|
||||||
// Advance offset by number of copied elements to position it for the next command.
|
for (const ImDrawCmd& DrawCmd : DrawList.CmdBuffer)
|
||||||
IndexBufferOffset += DrawCommand.NumElements;
|
{
|
||||||
|
TArray VerticesSlice(Vertices.GetData() + DrawCmd.VtxOffset, Vertices.Num() - DrawCmd.VtxOffset);
|
||||||
|
TArray IndicesSlice(Indices.GetData() + DrawCmd.IdxOffset, DrawCmd.ElemCount);
|
||||||
|
|
||||||
// Get texture resource handle for this draw command (null index will be also mapped to a valid texture).
|
UTexture2D* Texture = DrawCmd.GetTexID();
|
||||||
const FSlateResourceHandle& Handle = TextureManager.GetTextureHandle(DrawCommand.TextureId);
|
if (TextureBrush.GetResourceObject() != Texture)
|
||||||
|
{
|
||||||
|
TextureBrush.SetResourceObject(Texture);
|
||||||
|
if (IsValid(Texture))
|
||||||
|
{
|
||||||
|
TextureBrush.ImageSize.X = Texture->GetSizeX();
|
||||||
|
TextureBrush.ImageSize.Y = Texture->GetSizeY();
|
||||||
|
TextureBrush.ImageType = ESlateBrushImageType::FullColor;
|
||||||
|
TextureBrush.DrawAs = ESlateBrushDrawType::Image;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
TextureBrush.ImageSize.X = 0;
|
||||||
|
TextureBrush.ImageSize.Y = 0;
|
||||||
|
TextureBrush.ImageType = ESlateBrushImageType::NoImage;
|
||||||
|
TextureBrush.DrawAs = ESlateBrushDrawType::NoDrawType;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Transform clipping rectangle to screen space and apply to elements that we draw.
|
FSlateRect ClipRect(DrawCmd.ClipRect.x, DrawCmd.ClipRect.y, DrawCmd.ClipRect.z, DrawCmd.ClipRect.w);
|
||||||
const FSlateRect ClippingRect = DrawCommand.ClippingRect.IntersectionWith(MyClippingRect);
|
ClipRect = TransformRect(Transform, ClipRect);
|
||||||
|
|
||||||
OutDrawElements.PushClip(FSlateClippingZone{ ClippingRect });
|
|
||||||
|
|
||||||
// Add elements to the list.
|
|
||||||
FSlateDrawElement::MakeCustomVerts(OutDrawElements, LayerId, Handle, VertexBuffer, IndexBuffer, nullptr, 0, 0);
|
|
||||||
|
|
||||||
|
OutDrawElements.PushClip(FSlateClippingZone(ClipRect));
|
||||||
|
FSlateDrawElement::MakeCustomVerts(OutDrawElements, LayerId, TextureBrush.GetRenderingResource(), VerticesSlice, IndicesSlice, nullptr, 0, 0);
|
||||||
OutDrawElements.PopClip();
|
OutDrawElements.PopClip();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -274,128 +99,22 @@ int32 SCogImguiWidget::OnPaint(
|
|||||||
FVector2D SCogImguiWidget::ComputeDesiredSize(float Scale) const
|
FVector2D SCogImguiWidget::ComputeDesiredSize(float Scale) const
|
||||||
{
|
{
|
||||||
return FVector2D::ZeroVector;
|
return FVector2D::ZeroVector;
|
||||||
//return Super::ComputeDesiredSize(Scale);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//--------------------------------------------------------------------------------------------------------------------------
|
////--------------------------------------------------------------------------------------------------------------------------
|
||||||
ULocalPlayer* SCogImguiWidget::GetLocalPlayer() const
|
//FReply SCogImguiWidget::OnFocusReceived(const FGeometry& MyGeometry, const FFocusEvent& FocusEvent)
|
||||||
{
|
//{
|
||||||
if (GameViewport.IsValid() == false)
|
// if (bEnableInput == false)
|
||||||
{
|
// {
|
||||||
return nullptr;
|
// return FReply::Unhandled();
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
UWorld* World = GameViewport->GetWorld();
|
// Super::OnFocusReceived(MyGeometry, FocusEvent);
|
||||||
if (World == nullptr)
|
//
|
||||||
{
|
// FSlateApplication::Get().ResetToDefaultPointerInputSettings();
|
||||||
return nullptr;
|
//
|
||||||
}
|
// return FReply::Handled();
|
||||||
|
//}
|
||||||
ULocalPlayer* LocalPlayer = World->GetFirstLocalPlayerFromController();
|
|
||||||
return LocalPlayer;
|
|
||||||
}
|
|
||||||
|
|
||||||
//--------------------------------------------------------------------------------------------------------------------------
|
|
||||||
FVector2D SCogImguiWidget::TransformScreenPointToImGui(const FGeometry& MyGeometry, const FVector2D& Point) const
|
|
||||||
{
|
|
||||||
const FSlateRenderTransform ImGuiToScreen = MyGeometry.GetAccumulatedRenderTransform();
|
|
||||||
return ImGuiToScreen.Inverse().TransformPoint(Point);
|
|
||||||
}
|
|
||||||
|
|
||||||
//--------------------------------------------------------------------------------------------------------------------------
|
|
||||||
bool SCogImguiWidget::IsConsoleOpened() const
|
|
||||||
{
|
|
||||||
return GameViewport->ViewportConsole && GameViewport->ViewportConsole->ConsoleState != NAME_None;
|
|
||||||
}
|
|
||||||
|
|
||||||
//--------------------------------------------------------------------------------------------------------------------------
|
|
||||||
bool SCogImguiWidget::IsCurrentContext() const
|
|
||||||
{
|
|
||||||
return ImGui::GetCurrentContext() == ImGuiContext;
|
|
||||||
}
|
|
||||||
|
|
||||||
//--------------------------------------------------------------------------------------------------------------------------
|
|
||||||
void SCogImguiWidget::SetAsCurrentContext()
|
|
||||||
{
|
|
||||||
ImGui::SetCurrentContext(ImGuiContext);
|
|
||||||
}
|
|
||||||
|
|
||||||
//--------------------------------------------------------------------------------------------------------------------------
|
|
||||||
void SCogImguiWidget::SetEnableInput(bool Value)
|
|
||||||
{
|
|
||||||
bEnableInput = Value;
|
|
||||||
|
|
||||||
if (bEnableInput)
|
|
||||||
{
|
|
||||||
TakeFocus();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
ReturnFocus();
|
|
||||||
}
|
|
||||||
|
|
||||||
ImGuiIO& IO = ImGui::GetIO();
|
|
||||||
if (bEnableInput)
|
|
||||||
{
|
|
||||||
IO.ConfigFlags &= ~ImGuiConfigFlags_NoMouse;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
IO.ConfigFlags |= ImGuiConfigFlags_NoMouse;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//--------------------------------------------------------------------------------------------------------------------------
|
|
||||||
void SCogImguiWidget::SetDPIScale(float Value)
|
|
||||||
{
|
|
||||||
if (DpiScale == Value)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
DpiScale = Value;
|
|
||||||
OnDpiChanged();
|
|
||||||
}
|
|
||||||
|
|
||||||
//--------------------------------------------------------------------------------------------------------------------------
|
|
||||||
void SCogImguiWidget::OnDpiChanged()
|
|
||||||
{
|
|
||||||
if (FontAtlas == nullptr)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
FontAtlas->Clear();
|
|
||||||
|
|
||||||
ImFontConfig FontConfig = {};
|
|
||||||
FontConfig.SizePixels = FMath::RoundFromZero(13.f * DpiScale);
|
|
||||||
FontAtlas->AddFontDefault(&FontConfig);
|
|
||||||
|
|
||||||
unsigned char* Pixels;
|
|
||||||
int Width, Height, Bpp;
|
|
||||||
FontAtlas->GetTexDataAsRGBA32(&Pixels, &Width, &Height, &Bpp);
|
|
||||||
const CogTextureIndex FontsTexureIndex = FCogImguiModule::Get().GetTextureManager().CreateTexture("xx", Width, Height, Bpp, Pixels);
|
|
||||||
FontAtlas->TexID = FCogImguiHelper::ToImTextureID(FontsTexureIndex);
|
|
||||||
|
|
||||||
ImGuiStyle NewStyle = ImGuiStyle();
|
|
||||||
ImGui::GetStyle() = MoveTemp(NewStyle);
|
|
||||||
NewStyle.ScaleAllSizes(DpiScale);
|
|
||||||
}
|
|
||||||
|
|
||||||
//--------------------------------------------------------------------------------------------------------------------------
|
|
||||||
FReply SCogImguiWidget::OnFocusReceived(const FGeometry& MyGeometry, const FFocusEvent& FocusEvent)
|
|
||||||
{
|
|
||||||
if (bEnableInput == false)
|
|
||||||
{
|
|
||||||
return FReply::Unhandled();
|
|
||||||
}
|
|
||||||
|
|
||||||
Super::OnFocusReceived(MyGeometry, FocusEvent);
|
|
||||||
|
|
||||||
FSlateApplication::Get().ResetToDefaultPointerInputSettings();
|
|
||||||
|
|
||||||
return FReply::Handled();
|
|
||||||
}
|
|
||||||
|
|
||||||
//--------------------------------------------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------------------------------------------
|
||||||
FReply SCogImguiWidget::OnKeyChar(const FGeometry& MyGeometry, const FCharacterEvent& CharacterEvent)
|
FReply SCogImguiWidget::OnKeyChar(const FGeometry& MyGeometry, const FCharacterEvent& CharacterEvent)
|
||||||
@@ -408,33 +127,4 @@ FReply SCogImguiWidget::OnKeyChar(const FGeometry& MyGeometry, const FCharacterE
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//--------------------------------------------------------------------------------------------------------------------------
|
|
||||||
void SCogImguiWidget::DrawDebug()
|
|
||||||
{
|
|
||||||
if (ImGui::Begin("ImGui Integration Debug"))
|
|
||||||
{
|
|
||||||
ImGui::BeginDisabled();
|
|
||||||
|
|
||||||
ImVec2 AbsPos = FCogImguiHelper::ToImVec2(GetTickSpaceGeometry().GetAbsolutePosition());
|
|
||||||
ImGui::InputFloat2("Widget Abs Pos", &AbsPos.x, "%0.1f");
|
|
||||||
|
|
||||||
ImVec2 AbsSize = FCogImguiHelper::ToImVec2(GetTickSpaceGeometry().GetAbsoluteSize());
|
|
||||||
ImGui::InputFloat2("Widget Abs Size", &AbsSize.x, "%0.1f");
|
|
||||||
|
|
||||||
ImVec2 LocalSize = FCogImguiHelper::ToImVec2(GetTickSpaceGeometry().GetLocalSize());
|
|
||||||
ImGui::InputFloat2("Widget Local Size", &LocalSize.x, "%0.1f");
|
|
||||||
|
|
||||||
FSlateApplication& SlateApp = FSlateApplication::Get();
|
|
||||||
ImVec2 MousePosition = FCogImguiHelper::ToImVec2(SlateApp.GetCursorPos());
|
|
||||||
ImGui::InputFloat2("Mouse", &MousePosition.x, "%0.1f");
|
|
||||||
|
|
||||||
ImGuiIO& IO = ImGui::GetIO();
|
|
||||||
ImGui::InputFloat2("ImGui Mouse", &IO.MousePos.x, "%0.1f");
|
|
||||||
|
|
||||||
ImGui::EndDisabled();
|
|
||||||
}
|
|
||||||
ImGui::End();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
#include "Framework/Application/IInputProcessor.h"
|
#include "Framework/Application/IInputProcessor.h"
|
||||||
|
|
||||||
|
class FCogImguiContext;
|
||||||
class SCogImguiWidget;
|
class SCogImguiWidget;
|
||||||
class UPlayerInput;
|
class UPlayerInput;
|
||||||
enum ImGuiKey : int;
|
enum ImGuiKey : int;
|
||||||
@@ -11,7 +12,7 @@ class FImGuiInputProcessor : public IInputProcessor
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
FImGuiInputProcessor(UPlayerInput* InPlayerInput, SCogImguiWidget* InWidget);
|
FImGuiInputProcessor(UPlayerInput* InPlayerInput, FCogImguiContext* InContext, SCogImguiWidget* InWidget);
|
||||||
|
|
||||||
virtual void Tick(const float DeltaTime, FSlateApplication& SlateApp, TSharedRef<ICursor> SlateCursor) override;
|
virtual void Tick(const float DeltaTime, FSlateApplication& SlateApp, TSharedRef<ICursor> SlateCursor) override;
|
||||||
|
|
||||||
@@ -37,6 +38,8 @@ protected:
|
|||||||
|
|
||||||
bool HandleMouseButtonEvent(FSlateApplication& SlateApp, const FPointerEvent& Event, bool IsButtonDown);
|
bool HandleMouseButtonEvent(FSlateApplication& SlateApp, const FPointerEvent& Event, bool IsButtonDown);
|
||||||
|
|
||||||
|
bool IsMouseInsideMainViewport();
|
||||||
|
|
||||||
void AddMousePosEvent(const FVector2D& MousePosition) const;
|
void AddMousePosEvent(const FVector2D& MousePosition) const;
|
||||||
|
|
||||||
bool IsKeyBoundToCommand(const FKeyEvent& KeyEvent);
|
bool IsKeyBoundToCommand(const FKeyEvent& KeyEvent);
|
||||||
@@ -51,6 +54,8 @@ protected:
|
|||||||
|
|
||||||
static uint32 ToImGuiMouseButton(const FKey& MouseButton);
|
static uint32 ToImGuiMouseButton(const FKey& MouseButton);
|
||||||
|
|
||||||
|
TObjectPtr<FCogImguiContext> Context = nullptr;
|
||||||
|
|
||||||
TObjectPtr<UPlayerInput> PlayerInput = nullptr;
|
TObjectPtr<UPlayerInput> PlayerInput = nullptr;
|
||||||
|
|
||||||
TObjectPtr<SCogImguiWidget> MainWidget = nullptr;
|
TObjectPtr<SCogImguiWidget> MainWidget = nullptr;
|
||||||
|
|||||||
@@ -0,0 +1,117 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "CoreMinimal.h"
|
||||||
|
#include "Engine/Texture2D.h"
|
||||||
|
#include "Templates/SharedPointer.h"
|
||||||
|
#include "UObject/StrongObjectPtr.h"
|
||||||
|
#include "imgui.h"
|
||||||
|
|
||||||
|
class FCogImguiContext;
|
||||||
|
class IInputProcessor;
|
||||||
|
class SCogImguiWidget;
|
||||||
|
class SCogImguiWidget;
|
||||||
|
class SWindow;
|
||||||
|
class UGameViewportClient;
|
||||||
|
struct FDisplayMetrics;
|
||||||
|
struct ImPlotContext;
|
||||||
|
|
||||||
|
struct COGIMGUI_API FImGuiViewportData
|
||||||
|
{
|
||||||
|
TWeakPtr<SWindow> Window = nullptr;
|
||||||
|
TObjectPtr<FCogImguiContext> Context = nullptr;
|
||||||
|
TWeakPtr<SCogImguiWidget> Widget = nullptr;
|
||||||
|
};
|
||||||
|
|
||||||
|
class COGIMGUI_API FCogImguiContext : public TSharedFromThis<FCogImguiContext>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
void Initialize();
|
||||||
|
|
||||||
|
void Shutdown();
|
||||||
|
|
||||||
|
bool GetEnableInput() const { return bEnableInput; }
|
||||||
|
|
||||||
|
void SetEnableInput(bool Value);
|
||||||
|
|
||||||
|
bool GetShareMouse() const { return bShareMouse; }
|
||||||
|
|
||||||
|
void SetShareMouse(bool Value);
|
||||||
|
|
||||||
|
void BeginFrame(float InDeltaTime);
|
||||||
|
|
||||||
|
void EndFrame();
|
||||||
|
|
||||||
|
float GetDpiScale() const { return DpiScale; }
|
||||||
|
|
||||||
|
void SetDPIScale(float Value);
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
void OnDisplayMetricsChanged(const FDisplayMetrics& DisplayMetrics) const;
|
||||||
|
|
||||||
|
bool IsConsoleOpened() const;
|
||||||
|
|
||||||
|
void DrawDebug();
|
||||||
|
|
||||||
|
void TryGiveMouseCaptureBackToGame();
|
||||||
|
|
||||||
|
void TryReleaseGameMouseCapture();
|
||||||
|
|
||||||
|
void RefreshDPIScale();
|
||||||
|
|
||||||
|
void BuildFont();
|
||||||
|
|
||||||
|
ULocalPlayer* GetLocalPlayer() const;
|
||||||
|
|
||||||
|
static void ImGui_CreateWindow(ImGuiViewport* Viewport);
|
||||||
|
|
||||||
|
static void ImGui_DestroyWindow(ImGuiViewport* Viewport);
|
||||||
|
|
||||||
|
static void ImGui_ShowWindow(ImGuiViewport* Viewport);
|
||||||
|
|
||||||
|
static void ImGui_SetWindowPos(ImGuiViewport* Viewport, ImVec2 Pos);
|
||||||
|
|
||||||
|
static ImVec2 ImGui_GetWindowPos(ImGuiViewport* Viewport);
|
||||||
|
|
||||||
|
static void ImGui_SetWindowSize(ImGuiViewport* Viewport, ImVec2 Size);
|
||||||
|
|
||||||
|
static ImVec2 ImGui_GetWindowSize(ImGuiViewport* Viewport);
|
||||||
|
|
||||||
|
static void ImGui_SetWindowFocus(ImGuiViewport* Viewport);
|
||||||
|
|
||||||
|
static bool ImGui_GetWindowFocus(ImGuiViewport* Viewport);
|
||||||
|
|
||||||
|
static bool ImGui_GetWindowMinimized(ImGuiViewport* Viewport);
|
||||||
|
|
||||||
|
static void ImGui_SetWindowTitle(ImGuiViewport* Viewport, const char* TitleAnsi);
|
||||||
|
|
||||||
|
static void ImGui_SetWindowAlpha(ImGuiViewport* Viewport, float Alpha);
|
||||||
|
|
||||||
|
static void ImGui_RenderWindow(ImGuiViewport* Viewport, void* Data);
|
||||||
|
|
||||||
|
TMap<TWeakPtr<SWindow>, ImGuiID> WindowToViewportMap;
|
||||||
|
|
||||||
|
TSharedPtr<IInputProcessor> InputProcessor = nullptr;
|
||||||
|
|
||||||
|
TStrongObjectPtr<UTexture2D> FontAtlasTexturePtr = nullptr;
|
||||||
|
|
||||||
|
TSharedPtr<SCogImguiWidget> MainWidget = nullptr;
|
||||||
|
|
||||||
|
TWeakPtr<SWidget> PreviousMouseCaptor = nullptr;
|
||||||
|
|
||||||
|
TObjectPtr<UGameViewportClient> GameViewport = nullptr;
|
||||||
|
|
||||||
|
ImGuiContext* ImGuiContext = nullptr;
|
||||||
|
|
||||||
|
ImPlotContext* PlotContext = nullptr;
|
||||||
|
|
||||||
|
char IniFilename[512] = {};
|
||||||
|
|
||||||
|
bool bEnableInput = false;
|
||||||
|
|
||||||
|
bool bShareMouse = true;
|
||||||
|
|
||||||
|
float DpiScale = 1.f;
|
||||||
|
|
||||||
|
bool bRefreshDPIScale = false;
|
||||||
|
};
|
||||||
@@ -6,44 +6,39 @@
|
|||||||
#include "Rendering/RenderingCommon.h"
|
#include "Rendering/RenderingCommon.h"
|
||||||
|
|
||||||
//--------------------------------------------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------------------------------------------
|
||||||
class FCogImguiDrawList
|
struct FCogImguiDrawList
|
||||||
{
|
{
|
||||||
public:
|
FCogImguiDrawList() {};
|
||||||
|
|
||||||
|
FCogImguiDrawList(ImDrawList* Source);
|
||||||
|
|
||||||
struct DrawCommand
|
ImVector<ImDrawVert> VtxBuffer;
|
||||||
{
|
|
||||||
uint32 NumElements;
|
ImVector<ImDrawIdx> IdxBuffer;
|
||||||
FSlateRect ClippingRect;
|
|
||||||
CogTextureIndex TextureId;
|
ImVector<ImDrawCmd> CmdBuffer;
|
||||||
};
|
|
||||||
|
|
||||||
// Get the number of draw commands in this list.
|
ImDrawListFlags Flags = ImDrawListFlags_None;
|
||||||
FORCEINLINE int NumCommands() const { return ImGuiCommandBuffer.Size; }
|
|
||||||
|
|
||||||
// Get the draw command by number.
|
|
||||||
// @param CommandNb - Number of draw command
|
|
||||||
// @param Transform - Transform to apply to clipping rectangle
|
|
||||||
// @returns Draw command data
|
|
||||||
DrawCommand GetCommand(int CommandCount, const FTransform2D& Transform) const;
|
|
||||||
|
|
||||||
// Transform and copy vertex data to target buffer (old data in the target buffer are replaced).
|
|
||||||
// @param OutVertexBuffer - Destination buffer
|
|
||||||
// @param Transform - Transform to apply to all vertices
|
|
||||||
void CopyVertexData(TArray<FSlateVertex>& OutVertexBuffer, const FTransform2D& Transform) const;
|
|
||||||
|
|
||||||
// Transform and copy index data to target buffer (old data in the target buffer are replaced).
|
|
||||||
// Internal index buffer contains enough data to match the sum of NumElements from all draw commands.
|
|
||||||
// @param OutIndexBuffer - Destination buffer
|
|
||||||
// @param StartIndex - Start copying source data starting from this index
|
|
||||||
// @param NumElements - How many elements we want to copy
|
|
||||||
void CopyIndexData(TArray<SlateIndex>& OutIndexBuffer, const int32 StartIndex, const int32 NumElements) const;
|
|
||||||
|
|
||||||
// Transfers data from ImGui source list to this object. Leaves source cleared.
|
|
||||||
void TransferDrawData(ImDrawList& Src);
|
|
||||||
|
|
||||||
private:
|
|
||||||
|
|
||||||
ImVector<ImDrawCmd> ImGuiCommandBuffer;
|
|
||||||
ImVector<ImDrawIdx> ImGuiIndexBuffer;
|
|
||||||
ImVector<ImDrawVert> ImGuiVertexBuffer;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------------------------------------------------------------
|
||||||
|
struct FCogImguiDrawData
|
||||||
|
{
|
||||||
|
FCogImguiDrawData() {};
|
||||||
|
|
||||||
|
FCogImguiDrawData(const ImDrawData* Source);
|
||||||
|
|
||||||
|
bool bValid = false;
|
||||||
|
|
||||||
|
int32 TotalIdxCount = 0;
|
||||||
|
|
||||||
|
int32 TotalVtxCount = 0;
|
||||||
|
|
||||||
|
TArray<FCogImguiDrawList> DrawLists;
|
||||||
|
|
||||||
|
FVector2f DisplayPos = FVector2f::ZeroVector;
|
||||||
|
|
||||||
|
FVector2f DisplaySize = FVector2f::ZeroVector;
|
||||||
|
|
||||||
|
FVector2f FrameBufferScale = FVector2f::ZeroVector;
|
||||||
|
};
|
||||||
@@ -20,11 +20,13 @@ public:
|
|||||||
|
|
||||||
static ImGuiWindow* GetCurrentWindow();
|
static ImGuiWindow* GetCurrentWindow();
|
||||||
|
|
||||||
static FColor UnpackImU32Color(ImU32 Color);
|
static FColor ToFColor(ImU32 Color);
|
||||||
|
|
||||||
static FSlateRect ToSlateRect(const ImVec4& Value);
|
static FSlateRect ToSlateRect(const ImVec4& Value);
|
||||||
|
|
||||||
static FVector2D ToVector2D(const ImVec2& Value);
|
static FVector2f ToFVector2f(const ImVec2& Value);
|
||||||
|
|
||||||
|
static FVector2D ToFVector2D(const ImVec2& Value);
|
||||||
|
|
||||||
static ImVec2 ToImVec2(const FVector2D& Value);
|
static ImVec2 ToImVec2(const FVector2D& Value);
|
||||||
|
|
||||||
|
|||||||
@@ -1,10 +1,6 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "CoreMinimal.h"
|
#include "CoreMinimal.h"
|
||||||
#include "CogImguiWidget.h"
|
|
||||||
#include "CogImguiKeyInfo.h"
|
|
||||||
#include "CogImguiTextureManager.h"
|
|
||||||
#include "imgui.h"
|
|
||||||
#include "Modules/ModuleManager.h"
|
#include "Modules/ModuleManager.h"
|
||||||
|
|
||||||
class COGIMGUI_API FCogImguiModule : public IModuleInterface
|
class COGIMGUI_API FCogImguiModule : public IModuleInterface
|
||||||
@@ -22,22 +18,6 @@ public:
|
|||||||
virtual void StartupModule() override;
|
virtual void StartupModule() override;
|
||||||
virtual void ShutdownModule() override;
|
virtual void ShutdownModule() override;
|
||||||
|
|
||||||
//----------------------------------------------------------------------------------------------------------------------
|
|
||||||
TSharedPtr<SCogImguiWidget> CreateImGuiWidget(UGameViewportClient* GameViewport, FCogImguiRenderFunction Render, ImFontAtlas* FontAtlas = nullptr);
|
|
||||||
|
|
||||||
void DestroyImGuiWidget(TSharedPtr<SCogImguiWidget> ImGuiWidget);
|
|
||||||
|
|
||||||
FCogImguiTextureManager& GetTextureManager() { return TextureManager; }
|
|
||||||
|
|
||||||
ImFontAtlas& GetDefaultFontAtlas() { return DefaultFontAtlas; }
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
void Initialize();
|
|
||||||
|
|
||||||
FCogImguiTextureManager TextureManager;
|
|
||||||
|
|
||||||
ImFontAtlas DefaultFontAtlas;
|
|
||||||
|
|
||||||
bool bIsInitialized = false;
|
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,147 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include "CoreMinimal.h"
|
|
||||||
#include "CogImguiHelper.h"
|
|
||||||
#include "Engine/Texture2D.h"
|
|
||||||
#include "Styling/SlateBrush.h"
|
|
||||||
#include "Textures/SlateShaderResource.h"
|
|
||||||
#include "UObject/WeakObjectPtr.h"
|
|
||||||
|
|
||||||
//--------------------------------------------------------------------------------------------------------------------------
|
|
||||||
class FCogImguiTextureManager
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
|
|
||||||
// Creates an empty manager.
|
|
||||||
FCogImguiTextureManager() = default;
|
|
||||||
|
|
||||||
// Copying is disabled to protected resource ownership.
|
|
||||||
FCogImguiTextureManager(const FCogImguiTextureManager&) = delete;
|
|
||||||
FCogImguiTextureManager& operator=(const FCogImguiTextureManager&) = delete;
|
|
||||||
|
|
||||||
// Moving transfers ownership and leaves source empty.
|
|
||||||
FCogImguiTextureManager(FCogImguiTextureManager&&) = delete;
|
|
||||||
FCogImguiTextureManager& operator=(FCogImguiTextureManager&&) = delete;
|
|
||||||
|
|
||||||
void InitializeErrorTexture();
|
|
||||||
|
|
||||||
// Find texture index by name.
|
|
||||||
// @param Name - The name of a texture to find
|
|
||||||
// @returns The index of a texture with given name or INDEX_NONE if there is no such texture
|
|
||||||
CogTextureIndex FindTextureIndex(const FName& Name) const
|
|
||||||
{
|
|
||||||
return TextureResources.IndexOfByPredicate([&](const auto& Entry) { return Entry.GetName() == Name; });
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get the name of a texture at given index. Returns NAME_None, if index is out of range.
|
|
||||||
// @param Index - Index of a texture
|
|
||||||
// @returns The name of a texture at given index or NAME_None if index is out of range.
|
|
||||||
FName GetTextureName(CogTextureIndex Index) const
|
|
||||||
{
|
|
||||||
return IsInRange(Index) ? TextureResources[Index].GetName() : NAME_None;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get the Slate Resource Handle to a texture at given index. If index is out of range or resources are not valid
|
|
||||||
// it returns a handle to the error texture.
|
|
||||||
// @param Index - Index of a texture
|
|
||||||
// @returns The Slate Resource Handle for a texture at given index or to error texture, if no valid resources were
|
|
||||||
// found at given index
|
|
||||||
const FSlateResourceHandle& GetTextureHandle(CogTextureIndex Index) const
|
|
||||||
{
|
|
||||||
return IsValidTexture(Index) ? TextureResources[Index].GetResourceHandle() : ErrorTexture.GetResourceHandle();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Create a texture from raw data.
|
|
||||||
// @param Name - The texture name
|
|
||||||
// @param Width - The texture width
|
|
||||||
// @param Height - The texture height
|
|
||||||
// @param SrcBpp - The size in bytes of one pixel
|
|
||||||
// @param SrcData - The source data
|
|
||||||
// @param SrcDataCleanup - Optional function called to release source data after texture is created (only needed, if data need to be released)
|
|
||||||
// @returns The index of a texture that was created
|
|
||||||
CogTextureIndex CreateTexture(const FName& Name, int32 Width, int32 Height, uint32 SrcBpp, uint8* SrcData, TFunction<void(uint8*)> SrcDataCleanup = [](uint8*) {});
|
|
||||||
|
|
||||||
// Create a plain texture.
|
|
||||||
// @param Name - The texture name
|
|
||||||
// @param Width - The texture width
|
|
||||||
// @param Height - The texture height
|
|
||||||
// @param Color - The texture color
|
|
||||||
// @returns The index of a texture that was created
|
|
||||||
CogTextureIndex CreatePlainTexture(const FName& Name, int32 Width, int32 Height, FColor Color);
|
|
||||||
|
|
||||||
// Create Slate resources to an existing texture, managed externally.
|
|
||||||
// @param Name - The texture name
|
|
||||||
// @param Texture - The texture
|
|
||||||
// @returns The index to created/updated texture resources
|
|
||||||
CogTextureIndex CreateTextureResources(const FName& Name, UTexture2D* Texture);
|
|
||||||
|
|
||||||
// Release resources for given texture. Ignores invalid indices.
|
|
||||||
// @param Index - The index of a texture resources
|
|
||||||
void ReleaseTextureResources(CogTextureIndex Index);
|
|
||||||
|
|
||||||
private:
|
|
||||||
|
|
||||||
// See CreateTexture for general description.
|
|
||||||
// Internal implementations doesn't validate name or resource uniqueness. Instead it uses NAME_ErrorTexture
|
|
||||||
// (aka NAME_None) and INDEX_ErrorTexture (aka INDEX_NONE) to identify ErrorTexture.
|
|
||||||
CogTextureIndex CreateTextureInternal(const FName& Name, int32 Width, int32 Height, uint32 SrcBpp, uint8* SrcData, TFunction<void(uint8*)> SrcDataCleanup = [](uint8*) {});
|
|
||||||
|
|
||||||
// See CreatePlainTexture for general description.
|
|
||||||
// Internal implementations doesn't validate name or resource uniqueness. Instead it uses NAME_ErrorTexture
|
|
||||||
// (aka NAME_None) and INDEX_ErrorTexture (aka INDEX_NONE) to identify ErrorTexture.
|
|
||||||
CogTextureIndex CreatePlainTextureInternal(const FName& Name, int32 Width, int32 Height, const FColor& Color);
|
|
||||||
|
|
||||||
// Add or reuse texture entry.
|
|
||||||
// @param Name - The texture name
|
|
||||||
// @param Texture - The texture
|
|
||||||
// @param bAddToRoot - If true, we should add texture to root to prevent garbage collection (use for own textures)
|
|
||||||
// @returns The index of the entry that we created or reused
|
|
||||||
CogTextureIndex AddTextureEntry(const FName& Name, UTexture2D* Texture, bool bAddToRoot);
|
|
||||||
|
|
||||||
// Check whether index is in range allocated for TextureResources (it doesn't mean that resources are valid).
|
|
||||||
FORCEINLINE bool IsInRange(CogTextureIndex Index) const
|
|
||||||
{
|
|
||||||
return static_cast<uint32>(Index) < static_cast<uint32>(TextureResources.Num());
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check whether index is in range and whether texture resources are valid (using NAME_None sentinel).
|
|
||||||
FORCEINLINE bool IsValidTexture(CogTextureIndex Index) const
|
|
||||||
{
|
|
||||||
return IsInRange(Index) && TextureResources[Index].GetName() != NAME_None;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Entry for texture resources. Only supports explicit construction.
|
|
||||||
struct FTextureEntry
|
|
||||||
{
|
|
||||||
FTextureEntry() = default;
|
|
||||||
FTextureEntry(const FName& InName, UTexture2D* InTexture, bool bAddToRoot);
|
|
||||||
~FTextureEntry();
|
|
||||||
|
|
||||||
// Copying is not supported.
|
|
||||||
FTextureEntry(const FTextureEntry&) = delete;
|
|
||||||
FTextureEntry& operator=(const FTextureEntry&) = delete;
|
|
||||||
|
|
||||||
// We rely on TArray and don't implement custom move constructor...
|
|
||||||
FTextureEntry(FTextureEntry&&) = delete;
|
|
||||||
// ... but we need move assignment to support reusing entries.
|
|
||||||
FTextureEntry& operator=(FTextureEntry&& Other);
|
|
||||||
|
|
||||||
const FName& GetName() const { return Name; }
|
|
||||||
const FSlateResourceHandle& GetResourceHandle() const;
|
|
||||||
|
|
||||||
private:
|
|
||||||
|
|
||||||
void Reset(bool bReleaseResources);
|
|
||||||
|
|
||||||
FName Name = NAME_None;
|
|
||||||
mutable FSlateResourceHandle CachedResourceHandle;
|
|
||||||
TWeakObjectPtr<UTexture2D> Texture;
|
|
||||||
FSlateBrush Brush;
|
|
||||||
};
|
|
||||||
|
|
||||||
TArray<FTextureEntry> TextureResources;
|
|
||||||
FTextureEntry ErrorTexture;
|
|
||||||
|
|
||||||
static constexpr EName NAME_ErrorTexture = NAME_None;
|
|
||||||
static constexpr CogTextureIndex INDEX_ErrorTexture = INDEX_NONE;
|
|
||||||
};
|
|
||||||
@@ -7,14 +7,8 @@
|
|||||||
#include "Widgets/DeclarativeSyntaxSupport.h"
|
#include "Widgets/DeclarativeSyntaxSupport.h"
|
||||||
#include "Widgets/SLeafWidget.h"
|
#include "Widgets/SLeafWidget.h"
|
||||||
|
|
||||||
class IInputProcessor;
|
class FCogImguiContext;
|
||||||
class UGameViewportClient;
|
class UGameViewportClient;
|
||||||
class ULocalPlayer;
|
|
||||||
struct ImFontAtlas;
|
|
||||||
struct ImGuiContext;
|
|
||||||
struct ImPlotContext;
|
|
||||||
|
|
||||||
using FCogImguiRenderFunction = TFunction<void(float DeltaTime)>;
|
|
||||||
|
|
||||||
//--------------------------------------------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------------------------------------------
|
||||||
class COGIMGUI_API SCogImguiWidget : public SLeafWidget
|
class COGIMGUI_API SCogImguiWidget : public SLeafWidget
|
||||||
@@ -24,81 +18,26 @@ class COGIMGUI_API SCogImguiWidget : public SLeafWidget
|
|||||||
public:
|
public:
|
||||||
|
|
||||||
SLATE_BEGIN_ARGS(SCogImguiWidget) {}
|
SLATE_BEGIN_ARGS(SCogImguiWidget) {}
|
||||||
SLATE_ARGUMENT(UGameViewportClient*, GameViewport)
|
SLATE_ARGUMENT(FCogImguiContext*, Context)
|
||||||
SLATE_ARGUMENT(ImFontAtlas*, FontAtlas)
|
|
||||||
SLATE_ARGUMENT(FCogImguiRenderFunction, Render)
|
|
||||||
SLATE_END_ARGS()
|
SLATE_END_ARGS()
|
||||||
|
|
||||||
void Construct(const FArguments& InArgs);
|
void Construct(const FArguments& InArgs);
|
||||||
|
|
||||||
~SCogImguiWidget();
|
~SCogImguiWidget();
|
||||||
|
|
||||||
//----------------------------------------------------------------------------------------------------
|
|
||||||
// SWidget overrides
|
|
||||||
//----------------------------------------------------------------------------------------------------
|
|
||||||
virtual void Tick(const FGeometry& AllottedGeometry, const double InCurrentTime, const float InDeltaTime) override;
|
|
||||||
|
|
||||||
virtual int32 OnPaint(const FPaintArgs& Args, const FGeometry& AllottedGeometry, const FSlateRect& MyClippingRect, FSlateWindowElementList& OutDrawElements, int32 LayerId, const FWidgetStyle& WidgetStyle, bool bParentEnabled) const override;
|
virtual int32 OnPaint(const FPaintArgs& Args, const FGeometry& AllottedGeometry, const FSlateRect& MyClippingRect, FSlateWindowElementList& OutDrawElements, int32 LayerId, const FWidgetStyle& WidgetStyle, bool bParentEnabled) const override;
|
||||||
|
|
||||||
virtual bool SupportsKeyboardFocus() const override { return true; }
|
virtual bool SupportsKeyboardFocus() const override { return true; }
|
||||||
|
|
||||||
virtual FReply OnKeyChar(const FGeometry& MyGeometry, const FCharacterEvent& CharacterEvent) override;
|
virtual FReply OnKeyChar(const FGeometry& MyGeometry, const FCharacterEvent& CharacterEvent) override;
|
||||||
|
|
||||||
virtual FReply OnFocusReceived(const FGeometry& MyGeometry, const FFocusEvent& FocusEvent) override;
|
|
||||||
|
|
||||||
virtual FVector2D ComputeDesiredSize(float Scale) const override;
|
virtual FVector2D ComputeDesiredSize(float Scale) const override;
|
||||||
|
|
||||||
ULocalPlayer* GetLocalPlayer() const;
|
void SetDrawData(const ImDrawData* InDrawData);
|
||||||
|
|
||||||
bool GetEnableInput() const { return bEnableInput; }
|
|
||||||
|
|
||||||
void SetEnableInput(bool Value);
|
|
||||||
|
|
||||||
bool GetShareMouse() const { return bShareMouse; }
|
|
||||||
|
|
||||||
void SetShareMouse(bool Value) { bShareMouse = Value; }
|
|
||||||
|
|
||||||
float GetDpiScale() const { return DpiScale; }
|
|
||||||
|
|
||||||
void SetDPIScale(float Value);
|
|
||||||
|
|
||||||
bool IsCurrentContext() const;
|
|
||||||
|
|
||||||
void SetAsCurrentContext();
|
|
||||||
|
|
||||||
TWeakObjectPtr<UGameViewportClient> GetGameViewport() const { return GameViewport; }
|
|
||||||
|
|
||||||
void DestroyImGuiContext();
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
FVector2D TransformScreenPointToImGui(const FGeometry& MyGeometry, const FVector2D& Point) const;
|
TObjectPtr<FCogImguiContext> Context = nullptr;
|
||||||
|
|
||||||
virtual void TickKeyModifiers();
|
|
||||||
|
|
||||||
virtual void TickImGui(float InDeltaTime);
|
|
||||||
|
|
||||||
virtual void TickFocus();
|
|
||||||
|
|
||||||
virtual void TakeFocus();
|
|
||||||
|
|
||||||
virtual void ReturnFocus();
|
|
||||||
|
|
||||||
virtual void OnDpiChanged();
|
|
||||||
|
|
||||||
virtual bool IsConsoleOpened() const;
|
|
||||||
|
|
||||||
virtual void DrawDebug();
|
|
||||||
|
|
||||||
TWeakObjectPtr<UGameViewportClient> GameViewport;
|
|
||||||
|
|
||||||
ImFontAtlas* FontAtlas = nullptr;
|
|
||||||
|
|
||||||
TWeakPtr<SWidget> PreviousUserFocusedWidget;
|
|
||||||
|
|
||||||
bool bEnableInput = false;
|
|
||||||
|
|
||||||
bool bShareMouse = true;
|
|
||||||
|
|
||||||
FSlateRenderTransform ImGuiRenderTransform;
|
FSlateRenderTransform ImGuiRenderTransform;
|
||||||
|
|
||||||
@@ -106,17 +45,5 @@ protected:
|
|||||||
|
|
||||||
mutable TArray<SlateIndex> IndexBuffer;
|
mutable TArray<SlateIndex> IndexBuffer;
|
||||||
|
|
||||||
TArray<FCogImguiDrawList> DrawLists;
|
FCogImguiDrawData DrawData;
|
||||||
|
|
||||||
ImGuiContext* ImGuiContext = nullptr;
|
|
||||||
|
|
||||||
ImPlotContext* ImPlotContext = nullptr;
|
|
||||||
|
|
||||||
FCogImguiRenderFunction Render;
|
|
||||||
|
|
||||||
float DpiScale = 1.f;
|
|
||||||
|
|
||||||
char IniFilename[512];
|
|
||||||
|
|
||||||
TSharedPtr<IInputProcessor> InputProcessor = nullptr;
|
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
#include "CogDebugDraw.h"
|
#include "CogDebugDraw.h"
|
||||||
#include "CogDebugSettings.h"
|
#include "CogDebugSettings.h"
|
||||||
|
#include "CogWindow_Settings.h"
|
||||||
#include "CogWindowManager.h"
|
#include "CogWindowManager.h"
|
||||||
#include "CogWindowWidgets.h"
|
#include "CogWindowWidgets.h"
|
||||||
#include "Engine/World.h"
|
#include "Engine/World.h"
|
||||||
@@ -75,7 +76,7 @@ void FCogWindow::Render(float DeltaTime)
|
|||||||
ImGui::PopStyleVar(1);
|
ImGui::PopStyleVar(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (GetOwner()->GetShowHelp())
|
if (GetOwner()->GetSettingsWindow()->GetSettingsConfig()->bShowHelp)
|
||||||
{
|
{
|
||||||
if (ImGui::IsItemHovered())
|
if (ImGui::IsItemHovered())
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
#include "CogWindowManager.h"
|
#include "CogWindowManager.h"
|
||||||
|
|
||||||
#include "CogDebugDrawImGui.h"
|
#include "CogDebugDrawImGui.h"
|
||||||
|
#include "CogImguiHelper.h"
|
||||||
#include "CogImguiInputHelper.h"
|
#include "CogImguiInputHelper.h"
|
||||||
#include "CogImguiModule.h"
|
#include "CogImguiModule.h"
|
||||||
#include "CogWindow_Inputs.h"
|
|
||||||
#include "CogWindow_Layouts.h"
|
#include "CogWindow_Layouts.h"
|
||||||
#include "CogWindow_Settings.h"
|
#include "CogWindow_Settings.h"
|
||||||
#include "CogWindow_Spacing.h"
|
#include "CogWindow_Spacing.h"
|
||||||
@@ -41,7 +41,7 @@ void UCogWindowManager::PostInitProperties()
|
|||||||
//--------------------------------------------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------------------------------------------
|
||||||
void UCogWindowManager::InitializeInternal()
|
void UCogWindowManager::InitializeInternal()
|
||||||
{
|
{
|
||||||
ImGuiWidget = FCogImguiModule::Get().CreateImGuiWidget(GEngine->GameViewport, [this](float DeltaTime) { Render(DeltaTime); });
|
Context.Initialize();
|
||||||
|
|
||||||
ImGuiSettingsHandler IniHandler;
|
ImGuiSettingsHandler IniHandler;
|
||||||
IniHandler.TypeName = "Cog";
|
IniHandler.TypeName = "Cog";
|
||||||
@@ -59,7 +59,6 @@ void UCogWindowManager::InitializeInternal()
|
|||||||
SpaceWindows.Add(AddWindow<FCogWindow_Spacing>("Spacing 3", false));
|
SpaceWindows.Add(AddWindow<FCogWindow_Spacing>("Spacing 3", false));
|
||||||
SpaceWindows.Add(AddWindow<FCogWindow_Spacing>("Spacing 4", false));
|
SpaceWindows.Add(AddWindow<FCogWindow_Spacing>("Spacing 4", false));
|
||||||
|
|
||||||
InputsWindow = AddWindow<FCogWindow_Inputs>("Window.Inputs", false);
|
|
||||||
LayoutsWindow = AddWindow<FCogWindow_Layouts>("Window.Layouts", false);
|
LayoutsWindow = AddWindow<FCogWindow_Layouts>("Window.Layouts", false);
|
||||||
SettingsWindow = AddWindow<FCogWindow_Settings>("Window.Settings", false);
|
SettingsWindow = AddWindow<FCogWindow_Settings>("Window.Settings", false);
|
||||||
|
|
||||||
@@ -86,7 +85,8 @@ void UCogWindowManager::InitializeInternal()
|
|||||||
TEXT("Save the layout. Cog.SaveLayout <Index>"),
|
TEXT("Save the layout. Cog.SaveLayout <Index>"),
|
||||||
FConsoleCommandWithArgsDelegate::CreateLambda([this](const TArray<FString>& Args) { if (Args.Num() > 0) { SaveLayout(FCString::Atoi(*Args[0])); }}),
|
FConsoleCommandWithArgsDelegate::CreateLambda([this](const TArray<FString>& Args) { if (Args.Num() > 0) { SaveLayout(FCString::Atoi(*Args[0])); }}),
|
||||||
ECVF_Cheat));
|
ECVF_Cheat));
|
||||||
|
|
||||||
|
IsInitialized = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
//--------------------------------------------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------------------------------------------
|
||||||
@@ -105,7 +105,7 @@ void UCogWindowManager::Shutdown()
|
|||||||
// Destroy ImGui before destroying the windows to make sure
|
// Destroy ImGui before destroying the windows to make sure
|
||||||
// imgui serialize their visibility state in imgui.ini
|
// imgui serialize their visibility state in imgui.ini
|
||||||
//------------------------------------------------------------
|
//------------------------------------------------------------
|
||||||
ImGuiWidget->DestroyImGuiContext();
|
Context.Shutdown();
|
||||||
|
|
||||||
SaveConfig();
|
SaveConfig();
|
||||||
|
|
||||||
@@ -125,8 +125,6 @@ void UCogWindowManager::Shutdown()
|
|||||||
{
|
{
|
||||||
IConsoleManager::Get().UnregisterConsoleObject(ConsoleCommand);
|
IConsoleManager::Get().UnregisterConsoleObject(ConsoleCommand);
|
||||||
}
|
}
|
||||||
|
|
||||||
FCogImguiModule::Get().DestroyImGuiWidget(ImGuiWidget);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//--------------------------------------------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------------------------------------------
|
||||||
@@ -137,7 +135,7 @@ void UCogWindowManager::Tick(float DeltaTime)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ImGuiWidget.IsValid() == false)
|
if (IsInitialized == false)
|
||||||
{
|
{
|
||||||
InitializeInternal();
|
InitializeInternal();
|
||||||
}
|
}
|
||||||
@@ -149,16 +147,14 @@ void UCogWindowManager::Tick(float DeltaTime)
|
|||||||
LayoutToLoad = -1;
|
LayoutToLoad = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (bRefreshDPIScale)
|
|
||||||
{
|
|
||||||
RefreshDPIScale();
|
|
||||||
bRefreshDPIScale = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (FCogWindow* Window : Windows)
|
for (FCogWindow* Window : Windows)
|
||||||
{
|
{
|
||||||
Window->GameTick(DeltaTime);
|
Window->GameTick(DeltaTime);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Context.BeginFrame(DeltaTime);
|
||||||
|
Render(DeltaTime);
|
||||||
|
Context.EndFrame();
|
||||||
}
|
}
|
||||||
|
|
||||||
//--------------------------------------------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------------------------------------------
|
||||||
@@ -168,7 +164,7 @@ void UCogWindowManager::Render(float DeltaTime)
|
|||||||
ImGui::DockSpaceOverViewport(0, ImGuiDockNodeFlags_PassthruCentralNode | ImGuiDockNodeFlags_NoDockingInCentralNode | ImGuiDockNodeFlags_AutoHideTabBar);
|
ImGui::DockSpaceOverViewport(0, ImGuiDockNodeFlags_PassthruCentralNode | ImGuiDockNodeFlags_NoDockingInCentralNode | ImGuiDockNodeFlags_AutoHideTabBar);
|
||||||
ImGui::PopStyleColor(1);
|
ImGui::PopStyleColor(1);
|
||||||
|
|
||||||
bool bCompactSaved = bCompactMode;
|
bool bCompactSaved = SettingsWindow->GetSettingsConfig()->bCompactMode;
|
||||||
if (bCompactSaved)
|
if (bCompactSaved)
|
||||||
{
|
{
|
||||||
FCogWindowWidgets::PushStyleCompact();
|
FCogWindowWidgets::PushStyleCompact();
|
||||||
@@ -176,7 +172,7 @@ void UCogWindowManager::Render(float DeltaTime)
|
|||||||
|
|
||||||
if (bHideAllWindows == false)
|
if (bHideAllWindows == false)
|
||||||
{
|
{
|
||||||
if (ImGuiWidget->GetEnableInput() || bHideMainMenuOnGameInput == false)
|
if (Context.GetEnableInput())
|
||||||
{
|
{
|
||||||
RenderMainMenu();
|
RenderMainMenu();
|
||||||
}
|
}
|
||||||
@@ -188,7 +184,7 @@ void UCogWindowManager::Render(float DeltaTime)
|
|||||||
|
|
||||||
if (Window->GetIsVisible() && bHideAllWindows == false)
|
if (Window->GetIsVisible() && bHideAllWindows == false)
|
||||||
{
|
{
|
||||||
if (bTransparentMode)
|
if (SettingsWindow->GetSettingsConfig()->bTransparentMode)
|
||||||
{
|
{
|
||||||
ImGui::SetNextWindowBgAlpha(0.35f);
|
ImGui::SetNextWindowBgAlpha(0.35f);
|
||||||
}
|
}
|
||||||
@@ -202,8 +198,6 @@ void UCogWindowManager::Render(float DeltaTime)
|
|||||||
FCogWindowWidgets::PopStyleCompact();
|
FCogWindowWidgets::PopStyleCompact();
|
||||||
}
|
}
|
||||||
|
|
||||||
TickDPI();
|
|
||||||
|
|
||||||
FCogDebugDrawImGui::Draw();
|
FCogDebugDrawImGui::Draw();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -354,8 +348,6 @@ void UCogWindowManager::RenderMainMenu()
|
|||||||
|
|
||||||
ImGui::Separator();
|
ImGui::Separator();
|
||||||
|
|
||||||
RenderMenuItem(*InputsWindow, "Inputs");
|
|
||||||
|
|
||||||
RenderMenuItem(*LayoutsWindow, "Layouts");
|
RenderMenuItem(*LayoutsWindow, "Layouts");
|
||||||
|
|
||||||
RenderMenuItem(*SettingsWindow, "Settings");
|
RenderMenuItem(*SettingsWindow, "Settings");
|
||||||
@@ -508,7 +500,7 @@ void UCogWindowManager::RenderOptionMenu(UCogWindowManager::FMenu& Menu)
|
|||||||
//--------------------------------------------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------------------------------------------
|
||||||
void UCogWindowManager::RenderMenuItem(FCogWindow& Window, const char* MenuItemName)
|
void UCogWindowManager::RenderMenuItem(FCogWindow& Window, const char* MenuItemName)
|
||||||
{
|
{
|
||||||
if (bShowWindowsInMainMenu)
|
if (SettingsWindow->GetSettingsConfig()->bShowWindowsInMainMenu)
|
||||||
{
|
{
|
||||||
ImGui::SetNextWindowSizeConstraints(
|
ImGui::SetNextWindowSizeConstraints(
|
||||||
ImVec2(FCogWindowWidgets::GetFontWidth() * 40, ImGui::GetTextLineHeightWithSpacing() * 5),
|
ImVec2(FCogWindowWidgets::GetFontWidth() * 40, ImGui::GetTextLineHeightWithSpacing() * 5),
|
||||||
@@ -535,31 +527,7 @@ void UCogWindowManager::RenderMenuItem(FCogWindow& Window, const char* MenuItemN
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//--------------------------------------------------------------------------------------------------------------------------
|
|
||||||
void UCogWindowManager::TickDPI()
|
|
||||||
{
|
|
||||||
const float MouseWheel = ImGui::GetIO().MouseWheel;
|
|
||||||
const bool IsControlDown = ImGui::GetIO().KeyCtrl;
|
|
||||||
if (IsControlDown && MouseWheel != 0)
|
|
||||||
{
|
|
||||||
SetDPIScale(FMath::Clamp(DPIScale + (MouseWheel > 0 ? 0.1f : -0.1f), 0.5f, 2.0f));
|
|
||||||
}
|
|
||||||
|
|
||||||
const bool IsMiddleMouseClicked = ImGui::GetIO().MouseClicked[2];
|
|
||||||
if (IsControlDown && IsMiddleMouseClicked)
|
|
||||||
{
|
|
||||||
SetDPIScale(1.0f);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//--------------------------------------------------------------------------------------------------------------------------
|
|
||||||
void UCogWindowManager::RefreshDPIScale()
|
|
||||||
{
|
|
||||||
if (SCogImguiWidget* Widget = ImGuiWidget.Get())
|
|
||||||
{
|
|
||||||
Widget->SetDPIScale(DPIScale);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//--------------------------------------------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------------------------------------------
|
||||||
void UCogWindowManager::SettingsHandler_ClearAll(ImGuiContext* Context, ImGuiSettingsHandler* Handler)
|
void UCogWindowManager::SettingsHandler_ClearAll(ImGuiContext* Context, ImGuiSettingsHandler* Handler)
|
||||||
@@ -652,18 +620,6 @@ void UCogWindowManager::SettingsHandler_WriteAll(ImGuiContext* Context, ImGuiSet
|
|||||||
Buffer->append("\n");
|
Buffer->append("\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
//--------------------------------------------------------------------------------------------------------------------------
|
|
||||||
void UCogWindowManager::SetDPIScale(float Value)
|
|
||||||
{
|
|
||||||
if (DPIScale == Value)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
DPIScale = Value;
|
|
||||||
bRefreshDPIScale = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
//--------------------------------------------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------------------------------------------
|
||||||
void UCogWindowManager::ResetAllWindowsConfig()
|
void UCogWindowManager::ResetAllWindowsConfig()
|
||||||
{
|
{
|
||||||
@@ -786,5 +742,5 @@ const UObject* UCogWindowManager::GetAsset(const TSubclassOf<UObject> AssetClass
|
|||||||
void UCogWindowManager::ToggleInputMode()
|
void UCogWindowManager::ToggleInputMode()
|
||||||
{
|
{
|
||||||
UE_LOG(LogCogImGui, Verbose, TEXT("UCogWindowManager::ToggleInputMode"));
|
UE_LOG(LogCogImGui, Verbose, TEXT("UCogWindowManager::ToggleInputMode"));
|
||||||
ImGuiWidget->SetEnableInput(!ImGuiWidget->GetEnableInput());
|
Context.SetEnableInput(!Context.GetEnableInput());
|
||||||
}
|
}
|
||||||
@@ -1,89 +1,2 @@
|
|||||||
#include "CogWindow_Inputs.h"
|
#include "CogWindow_Inputs.h"
|
||||||
|
|
||||||
#include "CogImguiInputHelper.h"
|
|
||||||
#include "CogImguiWidget.h"
|
|
||||||
#include "CogWindowManager.h"
|
|
||||||
#include "CogWindowWidgets.h"
|
|
||||||
#include "InputCoreTypes.h"
|
|
||||||
#include "imgui.h"
|
|
||||||
|
|
||||||
//--------------------------------------------------------------------------------------------------------------------------
|
|
||||||
void FCogWindow_Inputs::Initialize()
|
|
||||||
{
|
|
||||||
Super::Initialize();
|
|
||||||
|
|
||||||
bHasMenu = false;
|
|
||||||
|
|
||||||
Config = GetConfig<UCogEngineConfig_Inputs>();
|
|
||||||
|
|
||||||
SCogImguiWidget* ImGuiWidget = GetOwner()->GetImGuiWidget().Get();
|
|
||||||
ImGuiWidget->SetEnableInput(Config->bEnableInput);
|
|
||||||
|
|
||||||
ImGuiIO& IO = ImGui::GetIO();
|
|
||||||
FCogImguiHelper::SetFlags(IO.ConfigFlags, ImGuiConfigFlags_NavEnableKeyboard, Config->bNavEnableKeyboard);
|
|
||||||
FCogImguiHelper::SetFlags(IO.ConfigFlags, ImGuiConfigFlags_NavEnableGamepad, Config->bNavEnableGamepad);
|
|
||||||
FCogImguiHelper::SetFlags(IO.ConfigFlags, ImGuiConfigFlags_NavNoCaptureKeyboard, Config->bNavNoCaptureInput);
|
|
||||||
}
|
|
||||||
|
|
||||||
//--------------------------------------------------------------------------------------------------------------------------
|
|
||||||
void FCogWindow_Inputs::PreSaveConfig()
|
|
||||||
{
|
|
||||||
Super::PreSaveConfig();
|
|
||||||
|
|
||||||
ImGuiIO& IO = ImGui::GetIO();
|
|
||||||
Config->bNavEnableKeyboard = IO.ConfigFlags & ImGuiConfigFlags_NavEnableKeyboard;
|
|
||||||
Config->bNavEnableGamepad = IO.ConfigFlags & ImGuiConfigFlags_NavEnableGamepad;
|
|
||||||
Config->bNavNoCaptureInput = IO.ConfigFlags & ImGuiConfigFlags_NavNoCaptureKeyboard;
|
|
||||||
|
|
||||||
if (SCogImguiWidget* ImGuiWidget = GetOwner()->GetImGuiWidget().Get())
|
|
||||||
{
|
|
||||||
Config->bEnableInput = ImGuiWidget->GetEnableInput();
|
|
||||||
Config->bShareMouse = ImGuiWidget->GetShareMouse();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//--------------------------------------------------------------------------------------------------------------------------
|
|
||||||
void FCogWindow_Inputs::RenderContent()
|
|
||||||
{
|
|
||||||
const UPlayerInput* PlayerInput = FCogImguiInputHelper::GetPlayerInput(*GetWorld());
|
|
||||||
if (PlayerInput == nullptr)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
SCogImguiWidget* ImGuiWidget = GetOwner()->GetImGuiWidget().Get();
|
|
||||||
if (ImGuiWidget == nullptr)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool bEnableInput = ImGuiWidget->GetEnableInput();
|
|
||||||
if (ImGui::Checkbox("Enable Input", &bEnableInput))
|
|
||||||
{
|
|
||||||
ImGuiWidget->SetEnableInput(bEnableInput);
|
|
||||||
}
|
|
||||||
|
|
||||||
const char* ShortcutText = TCHAR_TO_ANSI(*FCogImguiInputHelper::CommandToString(PlayerInput, UCogWindowManager::ToggleInputCommand));
|
|
||||||
const float ShortcutWidth = (ShortcutText && ShortcutText[0]) ? ImGui::CalcTextSize(ShortcutText, NULL).x : 0.0f;
|
|
||||||
if (ShortcutWidth > 0.0f)
|
|
||||||
{
|
|
||||||
ImGui::SameLine();
|
|
||||||
ImGui::SetCursorPosX(ImGui::GetWindowContentRegionMax().x - ShortcutWidth);
|
|
||||||
ImGui::PushStyleColor(ImGuiCol_Text, ImGui::GetStyle().Colors[ImGuiCol_TextDisabled]);
|
|
||||||
ImGui::Text(ShortcutText);
|
|
||||||
ImGui::PopStyleColor();
|
|
||||||
}
|
|
||||||
|
|
||||||
ImGui::Separator();
|
|
||||||
|
|
||||||
bool bShareMouse = ImGuiWidget->GetShareMouse();
|
|
||||||
if (ImGui::Checkbox("Share Mouse", &bShareMouse))
|
|
||||||
{
|
|
||||||
ImGuiWidget->SetShareMouse(bShareMouse);
|
|
||||||
}
|
|
||||||
|
|
||||||
ImGuiIO& IO = ImGui::GetIO();
|
|
||||||
ImGui::CheckboxFlags("Keyboard Navigation", &IO.ConfigFlags, ImGuiConfigFlags_NavEnableKeyboard);
|
|
||||||
ImGui::CheckboxFlags("Gamepad Navigation", &IO.ConfigFlags, ImGuiConfigFlags_NavEnableGamepad);
|
|
||||||
ImGui::CheckboxFlags("Navigation No Capture", &IO.ConfigFlags, ImGuiConfigFlags_NavNoCaptureKeyboard);
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -1,8 +1,12 @@
|
|||||||
#include "CogWindow_Settings.h"
|
#include "CogWindow_Settings.h"
|
||||||
|
|
||||||
|
#include "CogImguiHelper.h"
|
||||||
|
#include "CogImguiInputHelper.h"
|
||||||
#include "CogImguiModule.h"
|
#include "CogImguiModule.h"
|
||||||
|
#include "CogImguiWidget.h"
|
||||||
#include "CogWindowManager.h"
|
#include "CogWindowManager.h"
|
||||||
#include "CogWindowWidgets.h"
|
#include "CogWindowWidgets.h"
|
||||||
|
#include "imgui.h"
|
||||||
#include "InputCoreTypes.h"
|
#include "InputCoreTypes.h"
|
||||||
|
|
||||||
//--------------------------------------------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------------------------------------------
|
||||||
@@ -11,17 +15,86 @@ void FCogWindow_Settings::Initialize()
|
|||||||
Super::Initialize();
|
Super::Initialize();
|
||||||
|
|
||||||
bHasMenu = false;
|
bHasMenu = false;
|
||||||
|
|
||||||
|
Config = GetConfig<UCogWindowConfig_Settings>();
|
||||||
|
|
||||||
|
ImGuiIO& IO = ImGui::GetIO();
|
||||||
|
FCogImguiHelper::SetFlags(IO.ConfigFlags, ImGuiConfigFlags_ViewportsEnable, Config->bEnableViewports);
|
||||||
|
|
||||||
|
GetOwner()->GetContext().SetDPIScale(Config->DPIScale);
|
||||||
|
|
||||||
|
FCogImguiContext& Context = GetOwner()->GetContext();
|
||||||
|
Context.SetEnableInput(Config->bEnableInput);
|
||||||
|
Context.SetShareMouse(Config->bShareMouse);
|
||||||
|
|
||||||
|
FCogImguiHelper::SetFlags(IO.ConfigFlags, ImGuiConfigFlags_NavEnableKeyboard, Config->bNavEnableKeyboard);
|
||||||
|
FCogImguiHelper::SetFlags(IO.ConfigFlags, ImGuiConfigFlags_NavEnableGamepad, Config->bNavEnableGamepad);
|
||||||
|
FCogImguiHelper::SetFlags(IO.ConfigFlags, ImGuiConfigFlags_NavNoCaptureKeyboard, Config->bNavNoCaptureInput);
|
||||||
|
FCogImguiHelper::SetFlags(IO.ConfigFlags, ImGuiConfigFlags_NoMouseCursorChange, Config->bNoMouseCursorChange);
|
||||||
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------------------------------------------------------------
|
||||||
|
void FCogWindow_Settings::PreSaveConfig()
|
||||||
|
{
|
||||||
|
Super::PreSaveConfig();
|
||||||
|
|
||||||
|
ImGuiIO& IO = ImGui::GetIO();
|
||||||
|
Config->bNavEnableKeyboard = IO.ConfigFlags & ImGuiConfigFlags_NavEnableKeyboard;
|
||||||
|
Config->bNavEnableGamepad = IO.ConfigFlags & ImGuiConfigFlags_NavEnableGamepad;
|
||||||
|
Config->bNavNoCaptureInput = IO.ConfigFlags & ImGuiConfigFlags_NavNoCaptureKeyboard;
|
||||||
|
Config->bNoMouseCursorChange = IO.ConfigFlags & ImGuiConfigFlags_NoMouseCursorChange;
|
||||||
|
|
||||||
|
const FCogImguiContext& Context = GetOwner()->GetContext();
|
||||||
|
Config->bEnableInput = Context.GetEnableInput();
|
||||||
|
Config->bShareMouse = Context.GetShareMouse();
|
||||||
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------------------------------------------------------------
|
||||||
|
void FCogWindow_Settings::ResetConfig()
|
||||||
|
{
|
||||||
|
Super::ResetConfig();
|
||||||
|
|
||||||
|
Config->Reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
//--------------------------------------------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------------------------------------------
|
||||||
void FCogWindow_Settings::RenderContent()
|
void FCogWindow_Settings::RenderContent()
|
||||||
{
|
{
|
||||||
|
const UPlayerInput* PlayerInput = FCogImguiInputHelper::GetPlayerInput(*GetWorld());
|
||||||
|
if (PlayerInput == nullptr)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
ImGuiIO& IO = ImGui::GetIO();
|
||||||
|
|
||||||
|
FCogImguiContext& Context = GetOwner()->GetContext();
|
||||||
|
bool bEnableInput = Context.GetEnableInput();
|
||||||
|
if (ImGui::Checkbox("Enable Input", &bEnableInput))
|
||||||
|
{
|
||||||
|
Context.SetEnableInput(bEnableInput);
|
||||||
|
}
|
||||||
|
|
||||||
|
const char* ShortcutText = TCHAR_TO_ANSI(*FCogImguiInputHelper::CommandToString(PlayerInput, UCogWindowManager::ToggleInputCommand));
|
||||||
|
const float ShortcutWidth = (ShortcutText && ShortcutText[0]) ? ImGui::CalcTextSize(ShortcutText, NULL).x : 0.0f;
|
||||||
|
if (ShortcutWidth > 0.0f)
|
||||||
|
{
|
||||||
|
ImGui::SameLine();
|
||||||
|
ImGui::SetCursorPosX(ImGui::GetWindowContentRegionMax().x - ShortcutWidth);
|
||||||
|
ImGui::PushStyleColor(ImGuiCol_Text, ImGui::GetStyle().Colors[ImGuiCol_TextDisabled]);
|
||||||
|
ImGui::Text(ShortcutText);
|
||||||
|
ImGui::PopStyleColor();
|
||||||
|
}
|
||||||
|
|
||||||
|
ImGui::Separator();
|
||||||
|
|
||||||
FCogWindowWidgets::SetNextItemToShortWidth();
|
FCogWindowWidgets::SetNextItemToShortWidth();
|
||||||
ImGui::SliderFloat("DPI Scale", &GetOwner()->DPIScale, 0.5f, 2.0f, "%.1f");
|
ImGui::SliderFloat("DPI Scale", &Config->DPIScale, 0.5f, 2.0f, "%.1f");
|
||||||
if (ImGui::IsItemDeactivatedAfterEdit())
|
if (ImGui::IsItemDeactivatedAfterEdit())
|
||||||
{
|
{
|
||||||
GetOwner()->bRefreshDPIScale = true;
|
SetDPIScale(Config->DPIScale);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ImGui::IsItemHovered())
|
if (ImGui::IsItemHovered())
|
||||||
{
|
{
|
||||||
ImGui::BeginTooltip();
|
ImGui::BeginTooltip();
|
||||||
@@ -30,20 +103,63 @@ void FCogWindow_Settings::RenderContent()
|
|||||||
ImGui::EndTooltip();
|
ImGui::EndTooltip();
|
||||||
}
|
}
|
||||||
|
|
||||||
ImGui::Checkbox("Compact Mode", &GetOwner()->bCompactMode);
|
ImGui::Separator();
|
||||||
|
|
||||||
ImGui::Checkbox("Show Windows In Main Menu", &GetOwner()->bShowWindowsInMainMenu);
|
if (ImGui::Checkbox("Enable Viewports", &Config->bEnableViewports))
|
||||||
|
{
|
||||||
|
FCogImguiHelper::SetFlags(IO.ConfigFlags, ImGuiConfigFlags_ViewportsEnable, Config->bEnableViewports);
|
||||||
|
}
|
||||||
|
|
||||||
ImGui::Checkbox("Hide Main Menu On Game Input", &GetOwner()->bHideMainMenuOnGameInput);
|
ImGui::Checkbox("Compact Mode", &Config->bCompactMode);
|
||||||
|
|
||||||
ImGui::Checkbox("Show Window Help", &GetOwner()->bShowHelp);
|
ImGui::Checkbox("Show Windows In Main Menu", &Config->bShowWindowsInMainMenu);
|
||||||
|
|
||||||
|
ImGui::Checkbox("Show Window Help", &Config->bShowHelp);
|
||||||
|
|
||||||
|
ImGui::Separator();
|
||||||
|
|
||||||
|
bool bShareMouse = Context.GetShareMouse();
|
||||||
|
if (ImGui::Checkbox("Share Mouse", &bShareMouse))
|
||||||
|
{
|
||||||
|
Context.SetShareMouse(bShareMouse);
|
||||||
|
}
|
||||||
|
|
||||||
|
ImGui::CheckboxFlags("Keyboard Navigation", &IO.ConfigFlags, ImGuiConfigFlags_NavEnableKeyboard);
|
||||||
|
ImGui::CheckboxFlags("Gamepad Navigation", &IO.ConfigFlags, ImGuiConfigFlags_NavEnableGamepad);
|
||||||
|
ImGui::CheckboxFlags("Navigation No Capture", &IO.ConfigFlags, ImGuiConfigFlags_NavNoCaptureKeyboard);
|
||||||
|
ImGui::CheckboxFlags("No Mouse Cursor Change", &IO.ConfigFlags, ImGuiConfigFlags_NoMouseCursorChange);
|
||||||
|
|
||||||
ImGui::Separator();
|
ImGui::Separator();
|
||||||
|
|
||||||
ImGui::Spacing();
|
|
||||||
ImGui::Spacing();
|
|
||||||
if (ImGui::Button("Reset All Windows Config"))
|
if (ImGui::Button("Reset All Windows Config"))
|
||||||
{
|
{
|
||||||
GetOwner()->ResetAllWindowsConfig();
|
GetOwner()->ResetAllWindowsConfig();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------------------------------------------------------------
|
||||||
|
void FCogWindow_Settings::RenderTick(float DeltaTime)
|
||||||
|
{
|
||||||
|
Super::RenderTick(DeltaTime);
|
||||||
|
|
||||||
|
const float MouseWheel = ImGui::GetIO().MouseWheel;
|
||||||
|
const bool IsControlDown = ImGui::GetIO().KeyCtrl;
|
||||||
|
if (IsControlDown && MouseWheel != 0)
|
||||||
|
{
|
||||||
|
SetDPIScale(FMath::Clamp(Config->DPIScale + (MouseWheel > 0 ? 0.1f : -0.1f), 0.5f, 2.0f));
|
||||||
|
}
|
||||||
|
|
||||||
|
const bool IsMiddleMouseClicked = ImGui::GetIO().MouseClicked[2];
|
||||||
|
if (IsControlDown && IsMiddleMouseClicked)
|
||||||
|
{
|
||||||
|
SetDPIScale(1.0f);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------------------------------------------------------------
|
||||||
|
void FCogWindow_Settings::SetDPIScale(float Value)
|
||||||
|
{
|
||||||
|
Config->DPIScale = Value;
|
||||||
|
GetOwner()->GetContext().SetDPIScale(Config->DPIScale);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,12 +1,11 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "CoreMinimal.h"
|
#include "CoreMinimal.h"
|
||||||
#include "CogImguiWidget.h"
|
#include "CogImguiContext.h"
|
||||||
#include "imgui.h"
|
#include "imgui.h"
|
||||||
#include "CogWindowManager.generated.h"
|
#include "CogWindowManager.generated.h"
|
||||||
|
|
||||||
class FCogWindow;
|
class FCogWindow;
|
||||||
class FCogWindow_Inputs;
|
|
||||||
class FCogWindow_Layouts;
|
class FCogWindow_Layouts;
|
||||||
class FCogWindow_Settings;
|
class FCogWindow_Settings;
|
||||||
class IConsoleObject;
|
class IConsoleObject;
|
||||||
@@ -55,26 +54,12 @@ public:
|
|||||||
|
|
||||||
virtual void SetHideAllWindows(bool Value);
|
virtual void SetHideAllWindows(bool Value);
|
||||||
|
|
||||||
virtual float GetDPIScale() const { return DPIScale; }
|
|
||||||
|
|
||||||
virtual void SetDPIScale(float Value);
|
|
||||||
|
|
||||||
virtual bool GetCompactMode() const { return bCompactMode; }
|
|
||||||
|
|
||||||
virtual void SetCompactMode(bool Value) { bCompactMode = Value; }
|
|
||||||
|
|
||||||
virtual bool GetShowHelp() const { return bShowHelp; }
|
|
||||||
|
|
||||||
virtual void SetShowHelp(bool Value) { bShowHelp = Value; }
|
|
||||||
|
|
||||||
virtual bool GetPreviewWindowsInMenu() const { return bShowWindowsInMainMenu; }
|
|
||||||
|
|
||||||
virtual void SetPreviewWindowsInMenu(bool Value) { bShowWindowsInMainMenu = Value; }
|
|
||||||
|
|
||||||
virtual void ResetAllWindowsConfig();
|
virtual void ResetAllWindowsConfig();
|
||||||
|
|
||||||
virtual bool RegisterDefaultCommandBindings();
|
virtual bool RegisterDefaultCommandBindings();
|
||||||
|
|
||||||
|
const FCogWindow_Settings* GetSettingsWindow() const { return SettingsWindow; }
|
||||||
|
|
||||||
UCogWindowConfig* GetConfig(const TSubclassOf<UCogWindowConfig> ConfigClass);
|
UCogWindowConfig* GetConfig(const TSubclassOf<UCogWindowConfig> ConfigClass);
|
||||||
|
|
||||||
template<class T>
|
template<class T>
|
||||||
@@ -85,7 +70,9 @@ public:
|
|||||||
template<typename T>
|
template<typename T>
|
||||||
T* GetAsset();
|
T* GetAsset();
|
||||||
|
|
||||||
TSharedPtr<SCogImguiWidget> GetImGuiWidget() const { return ImGuiWidget; }
|
const FCogImguiContext& GetContext() const { return Context; }
|
||||||
|
|
||||||
|
FCogImguiContext& GetContext() { return Context; }
|
||||||
|
|
||||||
static void AddCommand(UPlayerInput* PlayerInput, const FString& Command, const FKey& Key);
|
static void AddCommand(UPlayerInput* PlayerInput, const FString& Command, const FKey& Key);
|
||||||
|
|
||||||
@@ -93,7 +80,6 @@ public:
|
|||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
friend class FCogWindow_Inputs;
|
|
||||||
friend class FCogWindow_Layouts;
|
friend class FCogWindow_Layouts;
|
||||||
friend class FCogWindow_Settings;
|
friend class FCogWindow_Settings;
|
||||||
|
|
||||||
@@ -106,8 +92,6 @@ protected:
|
|||||||
|
|
||||||
virtual void InitializeInternal();
|
virtual void InitializeInternal();
|
||||||
|
|
||||||
virtual void RefreshDPIScale();
|
|
||||||
|
|
||||||
virtual void RenderMainMenu();
|
virtual void RenderMainMenu();
|
||||||
|
|
||||||
virtual FMenu* AddMenu(const FString& Name);
|
virtual FMenu* AddMenu(const FString& Name);
|
||||||
@@ -116,8 +100,6 @@ protected:
|
|||||||
|
|
||||||
virtual void RenderMenuItem(FCogWindow& Window, const char* MenuItemName);
|
virtual void RenderMenuItem(FCogWindow& Window, const char* MenuItemName);
|
||||||
|
|
||||||
virtual void TickDPI();
|
|
||||||
|
|
||||||
virtual void ToggleInputMode();
|
virtual void ToggleInputMode();
|
||||||
|
|
||||||
static void SettingsHandler_ClearAll(ImGuiContext* ctx, ImGuiSettingsHandler*);
|
static void SettingsHandler_ClearAll(ImGuiContext* ctx, ImGuiSettingsHandler*);
|
||||||
@@ -144,37 +126,10 @@ protected:
|
|||||||
UPROPERTY()
|
UPROPERTY()
|
||||||
mutable TArray<const UObject*> Assets;
|
mutable TArray<const UObject*> Assets;
|
||||||
|
|
||||||
UPROPERTY(Config)
|
|
||||||
bool bCompactMode = false;
|
|
||||||
|
|
||||||
UPROPERTY(Config)
|
|
||||||
bool bTransparentMode = false;
|
|
||||||
|
|
||||||
UPROPERTY(Config)
|
|
||||||
float DPIScale = 1.0f;
|
|
||||||
|
|
||||||
UPROPERTY(Config)
|
|
||||||
bool bShowHelp = true;
|
|
||||||
|
|
||||||
UPROPERTY(Config)
|
|
||||||
bool bShowWindowsInMainMenu = true;
|
|
||||||
|
|
||||||
UPROPERTY(Config)
|
UPROPERTY(Config)
|
||||||
bool bRegisterDefaultCommands = true;
|
bool bRegisterDefaultCommands = true;
|
||||||
|
|
||||||
UPROPERTY(Config)
|
FCogImguiContext Context;
|
||||||
bool bAuthorizeInactiveInput = true;
|
|
||||||
|
|
||||||
UPROPERTY(Config)
|
|
||||||
bool bAuthorizeExclusiveInput = true;
|
|
||||||
|
|
||||||
UPROPERTY(Config)
|
|
||||||
bool bAuthorizeSharedInput = true;
|
|
||||||
|
|
||||||
UPROPERTY(Config)
|
|
||||||
bool bHideMainMenuOnGameInput = true;
|
|
||||||
|
|
||||||
TSharedPtr<SCogImguiWidget> ImGuiWidget = nullptr;
|
|
||||||
|
|
||||||
TArray<FCogWindow*> Windows;
|
TArray<FCogWindow*> Windows;
|
||||||
|
|
||||||
@@ -184,8 +139,6 @@ protected:
|
|||||||
|
|
||||||
TArray<FCogWindow*> SpaceWindows;
|
TArray<FCogWindow*> SpaceWindows;
|
||||||
|
|
||||||
FCogWindow_Inputs* InputsWindow = nullptr;
|
|
||||||
|
|
||||||
FCogWindow_Settings* SettingsWindow = nullptr;
|
FCogWindow_Settings* SettingsWindow = nullptr;
|
||||||
|
|
||||||
FCogWindow_Layouts* LayoutsWindow = nullptr;
|
FCogWindow_Layouts* LayoutsWindow = nullptr;
|
||||||
@@ -198,7 +151,7 @@ protected:
|
|||||||
|
|
||||||
bool bHideAllWindows = false;
|
bool bHideAllWindows = false;
|
||||||
|
|
||||||
bool bRefreshDPIScale = false;
|
bool IsInitialized = false;
|
||||||
|
|
||||||
TArray<IConsoleObject*> ConsoleCommands;
|
TArray<IConsoleObject*> ConsoleCommands;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,60 +1 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "CoreMinimal.h"
|
|
||||||
#include "CogWindow.h"
|
|
||||||
#include "CogWindowConfig.h"
|
|
||||||
#include "CogWindow_Inputs.generated.h"
|
|
||||||
|
|
||||||
class UCogEngineConfig_Inputs;
|
|
||||||
|
|
||||||
class COGWINDOW_API FCogWindow_Inputs : public FCogWindow
|
|
||||||
{
|
|
||||||
typedef FCogWindow Super;
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
virtual void Initialize() override;
|
|
||||||
|
|
||||||
virtual void PreSaveConfig() override;
|
|
||||||
|
|
||||||
protected:
|
|
||||||
|
|
||||||
virtual void RenderContent() override;
|
|
||||||
|
|
||||||
TObjectPtr<UCogEngineConfig_Inputs> Config = nullptr;
|
|
||||||
};
|
|
||||||
|
|
||||||
//--------------------------------------------------------------------------------------------------------------------------
|
|
||||||
UCLASS(Config = Cog)
|
|
||||||
class UCogEngineConfig_Inputs : public UCogWindowConfig
|
|
||||||
{
|
|
||||||
GENERATED_BODY()
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
UPROPERTY(Config)
|
|
||||||
bool bEnableInput = false;
|
|
||||||
|
|
||||||
UPROPERTY(Config)
|
|
||||||
bool bShareMouse = true;
|
|
||||||
|
|
||||||
UPROPERTY(Config)
|
|
||||||
bool bNavEnableKeyboard = true;
|
|
||||||
|
|
||||||
UPROPERTY(Config)
|
|
||||||
bool bNavEnableGamepad = true;
|
|
||||||
|
|
||||||
UPROPERTY(Config)
|
|
||||||
bool bNavNoCaptureInput = true;
|
|
||||||
|
|
||||||
virtual void Reset() override
|
|
||||||
{
|
|
||||||
Super::Reset();
|
|
||||||
|
|
||||||
bEnableInput = false;
|
|
||||||
bShareMouse = true;
|
|
||||||
bNavEnableKeyboard = true;
|
|
||||||
bNavEnableGamepad = true;
|
|
||||||
bNavNoCaptureInput = true;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
@@ -2,7 +2,12 @@
|
|||||||
|
|
||||||
#include "CoreMinimal.h"
|
#include "CoreMinimal.h"
|
||||||
#include "CogWindow.h"
|
#include "CogWindow.h"
|
||||||
|
#include "CogWindowConfig.h"
|
||||||
|
#include "CogWindow_Settings.generated.h"
|
||||||
|
|
||||||
|
class UCogEngineConfig_Settings;
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------------------------------------------------------------
|
||||||
class COGWINDOW_API FCogWindow_Settings : public FCogWindow
|
class COGWINDOW_API FCogWindow_Settings : public FCogWindow
|
||||||
{
|
{
|
||||||
typedef FCogWindow Super;
|
typedef FCogWindow Super;
|
||||||
@@ -11,7 +16,83 @@ public:
|
|||||||
|
|
||||||
virtual void Initialize() override;
|
virtual void Initialize() override;
|
||||||
|
|
||||||
|
virtual void RenderTick(float DeltaTime) override;
|
||||||
|
|
||||||
|
const UCogWindowConfig_Settings* GetSettingsConfig() const { return Config; }
|
||||||
|
|
||||||
|
void SetDPIScale(float Value);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
virtual void RenderContent() override;
|
virtual void RenderContent() override;
|
||||||
|
|
||||||
|
virtual void PreSaveConfig() override;
|
||||||
|
|
||||||
|
virtual void ResetConfig() override;
|
||||||
|
|
||||||
|
TObjectPtr<UCogWindowConfig_Settings> Config = nullptr;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------------------------------------------------------------
|
||||||
|
UCLASS(Config = Cog)
|
||||||
|
class UCogWindowConfig_Settings : public UCogWindowConfig
|
||||||
|
{
|
||||||
|
GENERATED_BODY()
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
UPROPERTY(Config)
|
||||||
|
float DPIScale = 1.0f;
|
||||||
|
|
||||||
|
UPROPERTY(Config)
|
||||||
|
bool bEnableViewports = false;
|
||||||
|
|
||||||
|
UPROPERTY(Config)
|
||||||
|
bool bCompactMode = false;
|
||||||
|
|
||||||
|
UPROPERTY(Config)
|
||||||
|
bool bTransparentMode = false;
|
||||||
|
|
||||||
|
UPROPERTY(Config)
|
||||||
|
bool bShowHelp = true;
|
||||||
|
|
||||||
|
UPROPERTY(Config)
|
||||||
|
bool bShowWindowsInMainMenu = true;
|
||||||
|
|
||||||
|
UPROPERTY(Config)
|
||||||
|
bool bEnableInput = false;
|
||||||
|
|
||||||
|
UPROPERTY(Config)
|
||||||
|
bool bShareMouse = true;
|
||||||
|
|
||||||
|
UPROPERTY(Config)
|
||||||
|
bool bNavEnableKeyboard = true;
|
||||||
|
|
||||||
|
UPROPERTY(Config)
|
||||||
|
bool bNavEnableGamepad = true;
|
||||||
|
|
||||||
|
UPROPERTY(Config)
|
||||||
|
bool bNavNoCaptureInput = true;
|
||||||
|
|
||||||
|
UPROPERTY(Config)
|
||||||
|
bool bNoMouseCursorChange = false;
|
||||||
|
|
||||||
|
virtual void Reset() override
|
||||||
|
{
|
||||||
|
Super::Reset();
|
||||||
|
|
||||||
|
DPIScale = 1.0f;
|
||||||
|
bEnableViewports = false;
|
||||||
|
bCompactMode = false;
|
||||||
|
bTransparentMode = false;
|
||||||
|
bShowHelp = true;
|
||||||
|
bShowWindowsInMainMenu = true;
|
||||||
|
bEnableInput = false;
|
||||||
|
bShareMouse = true;
|
||||||
|
bNavEnableKeyboard = true;
|
||||||
|
bNavEnableGamepad = true;
|
||||||
|
bNavNoCaptureInput = true;
|
||||||
|
bNoMouseCursorChange = false;
|
||||||
|
}
|
||||||
|
};
|
||||||
@@ -36,6 +36,7 @@
|
|||||||
#include "CogEngineWindow_Scalability.h"
|
#include "CogEngineWindow_Scalability.h"
|
||||||
#include "CogEngineWindow_Selection.h"
|
#include "CogEngineWindow_Selection.h"
|
||||||
#include "CogEngineWindow_Skeleton.h"
|
#include "CogEngineWindow_Skeleton.h"
|
||||||
|
#include "CogEngineWindow_Slate.h"
|
||||||
#include "CogEngineWindow_Spawns.h"
|
#include "CogEngineWindow_Spawns.h"
|
||||||
#include "CogEngineWindow_Stats.h"
|
#include "CogEngineWindow_Stats.h"
|
||||||
#include "CogEngineWindow_TimeScale.h"
|
#include "CogEngineWindow_TimeScale.h"
|
||||||
@@ -162,6 +163,8 @@ void ACogSampleGameState::InitializeCog()
|
|||||||
|
|
||||||
CogWindowManager->AddWindow<FCogEngineWindow_Skeleton>("Engine.Skeleton");
|
CogWindowManager->AddWindow<FCogEngineWindow_Skeleton>("Engine.Skeleton");
|
||||||
|
|
||||||
|
CogWindowManager->AddWindow<FCogEngineWindow_Slate>("Engine.Slate");
|
||||||
|
|
||||||
CogWindowManager->AddWindow<FCogEngineWindow_Spawns>("Engine.Spawns");
|
CogWindowManager->AddWindow<FCogEngineWindow_Spawns>("Engine.Spawns");
|
||||||
|
|
||||||
FCogEngineWindow_Stats* StatsWindow = CogWindowManager->AddWindow<FCogEngineWindow_Stats>("Engine.Stats");
|
FCogEngineWindow_Stats* StatsWindow = CogWindowManager->AddWindow<FCogEngineWindow_Stats>("Engine.Stats");
|
||||||
|
|||||||
Reference in New Issue
Block a user