mirror of
https://github.com/Ed94/Cog.git
synced 2026-06-13 00:01:37 -07: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:
|
||||
{
|
||||
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;
|
||||
QueryRadius = Config->QueryThickness;
|
||||
break;
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
#include "CogDebugSettings.h"
|
||||
#include "CogEngineReplicator.h"
|
||||
#include "CogImguiModule.h"
|
||||
#include "CogImguiHelper.h"
|
||||
#include "CogImguiInputHelper.h"
|
||||
#include "CogWindowManager.h"
|
||||
#include "CogWindowWidgets.h"
|
||||
@@ -136,8 +137,8 @@ void FCogEngineWindow_Selection::ToggleSelectionMode()
|
||||
void FCogEngineWindow_Selection::ActivateSelectionMode()
|
||||
{
|
||||
bSelectionModeActive = true;
|
||||
bIsInputEnabledBeforeEnteringSelectionMode = GetOwner()->GetImGuiWidget()->GetEnableInput();
|
||||
GetOwner()->GetImGuiWidget()->SetEnableInput(true);
|
||||
bIsInputEnabledBeforeEnteringSelectionMode = GetOwner()->GetContext().GetEnableInput();
|
||||
GetOwner()->GetContext().SetEnableInput(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 leaving selection mode we want to leave it as is was before
|
||||
//--------------------------------------------------------------------------------------------
|
||||
GetOwner()->GetImGuiWidget()->SetEnableInput(bIsInputEnabledBeforeEnteringSelectionMode);
|
||||
GetOwner()->GetContext().SetEnableInput(bIsInputEnabledBeforeEnteringSelectionMode);
|
||||
|
||||
GetOwner()->SetHideAllWindows(false);
|
||||
}
|
||||
@@ -393,15 +394,23 @@ void FCogEngineWindow_Selection::TickSelectionMode()
|
||||
return;
|
||||
}
|
||||
|
||||
ImDrawList* DrawList = ImGui::GetBackgroundDrawList();
|
||||
DrawList->AddRect(ImVec2(0, 0), ImGui::GetIO().DisplaySize, IM_COL32(255, 0, 0, 128), 0.0f, 0, 20.0f);
|
||||
FCogWindowWidgets::AddTextWithShadow(DrawList, ImVec2(20, 20), IM_COL32(255, 255, 255, 255), "Picking Mode. \n[LMB] Pick \n[RMB] Cancel");
|
||||
ImGuiViewport* Viewport = ImGui::GetMainViewport();
|
||||
if (Viewport == nullptr)
|
||||
{
|
||||
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();
|
||||
|
||||
AActor* HoveredActor = nullptr;
|
||||
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.
|
||||
@@ -463,7 +472,13 @@ void FCogEngineWindow_Selection::DrawActorFrame(const AActor& Actor)
|
||||
return;
|
||||
}
|
||||
|
||||
ImDrawList* DrawList = ImGui::GetBackgroundDrawList();
|
||||
ImGuiViewport* Viewport = ImGui::GetMainViewport();
|
||||
if (Viewport == nullptr)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
ImDrawList* DrawList = ImGui::GetBackgroundDrawList(Viewport);
|
||||
|
||||
FVector BoxOrigin, BoxExtent;
|
||||
|
||||
@@ -502,8 +517,8 @@ void FCogEngineWindow_Selection::DrawActorFrame(const AActor& Actor)
|
||||
if (ComputeBoundingBoxScreenPosition(PlayerController, BoxOrigin, BoxExtent, ScreenPosMin, ScreenPosMax))
|
||||
{
|
||||
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);
|
||||
FCogWindowWidgets::AddTextWithShadow(DrawList, FCogImguiHelper::ToImVec2(ScreenPosMin + FVector2D(0, -14.0f)), Color, TCHAR_TO_ANSI(*GetActorName(Actor)));
|
||||
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)) + 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 "CogImguiInputHelper.h"
|
||||
#include "CogImguiWidget.h"
|
||||
#include "CogImguiContext.h"
|
||||
#include "GameFramework/InputSettings.h"
|
||||
#include "GameFramework/PlayerInput.h"
|
||||
#include "imgui.h"
|
||||
#include "imgui_internal.h"
|
||||
#include "Slate/SGameLayerManager.h"
|
||||
|
||||
#if WITH_EDITOR
|
||||
@@ -16,9 +18,10 @@ constexpr bool ForwardEvent = false;
|
||||
constexpr bool TerminateEvent = true;
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------------------------
|
||||
FImGuiInputProcessor::FImGuiInputProcessor(UPlayerInput* InPlayerInput, SCogImguiWidget* InMainWidget)
|
||||
FImGuiInputProcessor::FImGuiInputProcessor(UPlayerInput* InPlayerInput, FCogImguiContext* InContext, SCogImguiWidget* InMainWidget)
|
||||
{
|
||||
PlayerInput = InPlayerInput;
|
||||
Context = InContext;
|
||||
MainWidget = InMainWidget;
|
||||
}
|
||||
|
||||
@@ -43,14 +46,16 @@ void FImGuiInputProcessor::Tick(const float DeltaTime, FSlateApplication& SlateA
|
||||
|
||||
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()));
|
||||
}
|
||||
|
||||
if (IO.WantSetMousePos)
|
||||
{
|
||||
SlateApp.SetCursorPos(FCogImguiHelper::ToVector2D(IO.MousePos));
|
||||
SlateApp.SetCursorPos(FCogImguiHelper::ToFVector2D(IO.MousePos));
|
||||
//UE_LOG(LogCogImGui, VeryVerbose, TEXT("FImGuiInputProcessor::Tick | SetCursorPos"));
|
||||
}
|
||||
}
|
||||
@@ -175,7 +180,7 @@ bool FImGuiInputProcessor::HandleMouseMoveEvent(FSlateApplication& SlateApp, con
|
||||
{
|
||||
AddMousePosEvent(Event.GetScreenSpacePosition());
|
||||
|
||||
if (MainWidget->GetEnableInput() && MainWidget->GetShareMouse() == false)
|
||||
if (Context->GetEnableInput() && Context->GetShareMouse() == false && IsMouseInsideMainViewport())
|
||||
{
|
||||
return TerminateEvent;
|
||||
}
|
||||
@@ -211,7 +216,7 @@ bool FImGuiInputProcessor::HandleMouseButtonEvent(FSlateApplication& SlateApp, c
|
||||
const uint32 Button = ToImGuiMouseButton(Event.GetEffectingButton());
|
||||
IO.AddMouseButtonEvent(Button, IsButtonDown);
|
||||
|
||||
if (MainWidget->GetEnableInput() && MainWidget->GetShareMouse() == false)
|
||||
if (Context->GetEnableInput() && Context->GetShareMouse() == false && IsMouseInsideMainViewport())
|
||||
{
|
||||
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);
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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 "CogImguiHelper.h"
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------------------------
|
||||
void FCogImguiDrawList::CopyVertexData(TArray<FSlateVertex>& OutVertexBuffer, const FTransform2D& Transform) const
|
||||
FCogImguiDrawList::FCogImguiDrawList(ImDrawList* Source)
|
||||
{
|
||||
// Reset and reserve space in destination buffer.
|
||||
OutVertexBuffer.SetNumUninitialized(ImGuiVertexBuffer.Size, false);
|
||||
|
||||
// Transform and copy vertex data.
|
||||
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);
|
||||
}
|
||||
VtxBuffer.swap(Source->VtxBuffer);
|
||||
IdxBuffer.swap(Source->IdxBuffer);
|
||||
CmdBuffer.swap(Source->CmdBuffer);
|
||||
Flags = Source->Flags;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------------------------
|
||||
FCogImguiDrawList::DrawCommand FCogImguiDrawList::GetCommand(int CommandCount, const FTransform2D& Transform) const
|
||||
FCogImguiDrawData::FCogImguiDrawData(const ImDrawData* Source)
|
||||
{
|
||||
const ImDrawCmd& ImGuiCommand = ImGuiCommandBuffer[CommandCount];
|
||||
return
|
||||
{
|
||||
ImGuiCommand.ElemCount,
|
||||
TransformRect(Transform, FCogImguiHelper::ToSlateRect(ImGuiCommand.ClipRect)),
|
||||
FCogImguiHelper::ToTextureIndex(ImGuiCommand.TextureId)
|
||||
};
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------------------------
|
||||
void FCogImguiDrawList::CopyIndexData(TArray<SlateIndex>& OutIndexBuffer, const int32 StartIndex, const int32 NumElements) const
|
||||
{
|
||||
// Reset buffer.
|
||||
OutIndexBuffer.SetNumUninitialized(NumElements, false);
|
||||
|
||||
// Copy elements (slow copy because of different sizes of ImDrawIdx and SlateIndex and because SlateIndex can
|
||||
// have different size on different platforms).
|
||||
for (int i = 0; i < NumElements; i++)
|
||||
{
|
||||
OutIndexBuffer[i] = ImGuiIndexBuffer[StartIndex + i];
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------------------------
|
||||
void FCogImguiDrawList::TransferDrawData(ImDrawList& Src)
|
||||
{
|
||||
// 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();
|
||||
bValid = Source->Valid;
|
||||
|
||||
TotalIdxCount = Source->TotalIdxCount;
|
||||
TotalVtxCount = Source->TotalVtxCount;
|
||||
|
||||
DrawLists.SetNumUninitialized(Source->CmdListsCount);
|
||||
ConstructItems<FCogImguiDrawList>(DrawLists.GetData(), Source->CmdLists.Data, Source->CmdListsCount);
|
||||
|
||||
DisplayPos = FCogImguiHelper::ToFVector2f(Source->DisplayPos);
|
||||
DisplaySize = FCogImguiHelper::ToFVector2f(Source->DisplaySize);
|
||||
FrameBufferScale = FCogImguiHelper::ToFVector2f(Source->FramebufferScale);
|
||||
}
|
||||
|
||||
@@ -31,7 +31,7 @@ ImGuiWindow* FCogImguiHelper::GetCurrentWindow()
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------------------------
|
||||
FColor FCogImguiHelper::UnpackImU32Color(ImU32 Color)
|
||||
FColor FCogImguiHelper::ToFColor(ImU32 Color)
|
||||
{
|
||||
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);
|
||||
}
|
||||
@@ -90,7 +96,6 @@ ImVec4 FCogImguiHelper::ToImVec4(const FVector4f& Value)
|
||||
return ImVec4(Value.X, Value.Y, Value.Z, Value.W);
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------------------------
|
||||
ImU32 FCogImguiHelper::ToImU32(const FColor& Value)
|
||||
{
|
||||
|
||||
@@ -1,18 +1,11 @@
|
||||
#include "CogImguiModule.h"
|
||||
|
||||
#include "CogImguiWidget.h"
|
||||
#include "Engine/Engine.h"
|
||||
#include "Engine/GameViewportClient.h"
|
||||
#include "imgui.h"
|
||||
#include "HAL/LowLevelMemTracker.h"
|
||||
#include "HAL/UnrealMemory.h"
|
||||
#include "Widgets/Layout/SScaleBox.h"
|
||||
|
||||
#define LOCTEXT_NAMESPACE "FCogImguiModule"
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
constexpr int32 Cog_ZOrder = 10000;
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------------------------
|
||||
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
|
||||
|
||||
|
||||
@@ -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 "CogImguiInputHelper.h"
|
||||
#include "CogImguiInputHelper.h"
|
||||
#include "CogImGuiInputProcessor.h"
|
||||
#include "CogImguiModule.h"
|
||||
#include "CogImguiModule.h"
|
||||
#include "CogImguiTextureManager.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_internal.h"
|
||||
#include "implot.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
|
||||
void SCogImguiWidget::Construct(const FArguments& InArgs)
|
||||
{
|
||||
checkf(InArgs._GameViewport, TEXT("Null Game Viewport argument"));
|
||||
|
||||
GameViewport = InArgs._GameViewport;
|
||||
FontAtlas = InArgs._FontAtlas;
|
||||
Render = InArgs._Render;
|
||||
Context = InArgs._Context;
|
||||
|
||||
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
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------------------------
|
||||
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)
|
||||
{
|
||||
ImPlot::DestroyContext(ImPlotContext);
|
||||
ImPlotContext = nullptr;
|
||||
}
|
||||
|
||||
if (ImGuiContext != nullptr)
|
||||
{
|
||||
ImGui::DestroyContext(ImGuiContext);
|
||||
ImGuiContext = nullptr;
|
||||
}
|
||||
DrawData = FCogImguiDrawData(InDrawData);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------------------------
|
||||
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(
|
||||
const FPaintArgs& Args,
|
||||
@@ -233,36 +38,56 @@ int32 SCogImguiWidget::OnPaint(
|
||||
bool bParentEnabled) const
|
||||
{
|
||||
|
||||
const FSlateRenderTransform& WidgetToScreen = AllottedGeometry.GetAccumulatedRenderTransform().GetTranslation();
|
||||
const FSlateRenderTransform ImGuiToScreen = FCogImguiHelper::RoundTranslation(ImGuiRenderTransform.Concatenate(WidgetToScreen));
|
||||
const FSlateRenderTransform Transform(FCogImguiHelper::RoundTranslation(AllottedGeometry.GetAccumulatedRenderTransform().GetTranslation() - FVector2d(DrawData.DisplayPos)));
|
||||
|
||||
FCogImguiTextureManager& TextureManager = FCogImguiModule::Get().GetTextureManager();
|
||||
|
||||
for (const auto& DrawList : DrawLists)
|
||||
FSlateBrush TextureBrush;
|
||||
for (const FCogImguiDrawList& DrawList : DrawData.DrawLists)
|
||||
{
|
||||
DrawList.CopyVertexData(VertexBuffer, ImGuiToScreen);
|
||||
|
||||
int IndexBufferOffset = 0;
|
||||
for (int i = 0; i < DrawList.NumCommands(); i++)
|
||||
TArray<FSlateVertex> Vertices;
|
||||
Vertices.SetNumUninitialized(DrawList.VtxBuffer.Size);
|
||||
for (int32 BufferIdx = 0; BufferIdx < Vertices.Num(); ++BufferIdx)
|
||||
{
|
||||
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.
|
||||
IndexBufferOffset += DrawCommand.NumElements;
|
||||
for (const ImDrawCmd& DrawCmd : DrawList.CmdBuffer)
|
||||
{
|
||||
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).
|
||||
const FSlateResourceHandle& Handle = TextureManager.GetTextureHandle(DrawCommand.TextureId);
|
||||
UTexture2D* Texture = DrawCmd.GetTexID();
|
||||
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.
|
||||
const FSlateRect ClippingRect = DrawCommand.ClippingRect.IntersectionWith(MyClippingRect);
|
||||
|
||||
OutDrawElements.PushClip(FSlateClippingZone{ ClippingRect });
|
||||
|
||||
// Add elements to the list.
|
||||
FSlateDrawElement::MakeCustomVerts(OutDrawElements, LayerId, Handle, VertexBuffer, IndexBuffer, nullptr, 0, 0);
|
||||
FSlateRect ClipRect(DrawCmd.ClipRect.x, DrawCmd.ClipRect.y, DrawCmd.ClipRect.z, DrawCmd.ClipRect.w);
|
||||
ClipRect = TransformRect(Transform, ClipRect);
|
||||
|
||||
OutDrawElements.PushClip(FSlateClippingZone(ClipRect));
|
||||
FSlateDrawElement::MakeCustomVerts(OutDrawElements, LayerId, TextureBrush.GetRenderingResource(), VerticesSlice, IndicesSlice, nullptr, 0, 0);
|
||||
OutDrawElements.PopClip();
|
||||
}
|
||||
}
|
||||
@@ -274,128 +99,22 @@ int32 SCogImguiWidget::OnPaint(
|
||||
FVector2D SCogImguiWidget::ComputeDesiredSize(float Scale) const
|
||||
{
|
||||
return FVector2D::ZeroVector;
|
||||
//return Super::ComputeDesiredSize(Scale);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------------------------
|
||||
ULocalPlayer* SCogImguiWidget::GetLocalPlayer() const
|
||||
{
|
||||
if (GameViewport.IsValid() == false)
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
UWorld* World = GameViewport->GetWorld();
|
||||
if (World == nullptr)
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
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::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)
|
||||
@@ -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"
|
||||
|
||||
class FCogImguiContext;
|
||||
class SCogImguiWidget;
|
||||
class UPlayerInput;
|
||||
enum ImGuiKey : int;
|
||||
@@ -11,7 +12,7 @@ class FImGuiInputProcessor : public IInputProcessor
|
||||
{
|
||||
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;
|
||||
|
||||
@@ -37,6 +38,8 @@ protected:
|
||||
|
||||
bool HandleMouseButtonEvent(FSlateApplication& SlateApp, const FPointerEvent& Event, bool IsButtonDown);
|
||||
|
||||
bool IsMouseInsideMainViewport();
|
||||
|
||||
void AddMousePosEvent(const FVector2D& MousePosition) const;
|
||||
|
||||
bool IsKeyBoundToCommand(const FKeyEvent& KeyEvent);
|
||||
@@ -51,6 +54,8 @@ protected:
|
||||
|
||||
static uint32 ToImGuiMouseButton(const FKey& MouseButton);
|
||||
|
||||
TObjectPtr<FCogImguiContext> Context = nullptr;
|
||||
|
||||
TObjectPtr<UPlayerInput> PlayerInput = 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"
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------------------------
|
||||
class FCogImguiDrawList
|
||||
struct FCogImguiDrawList
|
||||
{
|
||||
public:
|
||||
FCogImguiDrawList() {};
|
||||
|
||||
FCogImguiDrawList(ImDrawList* Source);
|
||||
|
||||
struct DrawCommand
|
||||
{
|
||||
uint32 NumElements;
|
||||
FSlateRect ClippingRect;
|
||||
CogTextureIndex TextureId;
|
||||
};
|
||||
ImVector<ImDrawVert> VtxBuffer;
|
||||
|
||||
ImVector<ImDrawIdx> IdxBuffer;
|
||||
|
||||
ImVector<ImDrawCmd> CmdBuffer;
|
||||
|
||||
// Get the number of draw commands in this list.
|
||||
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;
|
||||
ImDrawListFlags Flags = ImDrawListFlags_None;
|
||||
};
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------------------------
|
||||
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 FColor UnpackImU32Color(ImU32 Color);
|
||||
static FColor ToFColor(ImU32 Color);
|
||||
|
||||
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);
|
||||
|
||||
|
||||
@@ -1,10 +1,6 @@
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "CogImguiWidget.h"
|
||||
#include "CogImguiKeyInfo.h"
|
||||
#include "CogImguiTextureManager.h"
|
||||
#include "imgui.h"
|
||||
#include "Modules/ModuleManager.h"
|
||||
|
||||
class COGIMGUI_API FCogImguiModule : public IModuleInterface
|
||||
@@ -22,22 +18,6 @@ public:
|
||||
virtual void StartupModule() 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:
|
||||
|
||||
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/SLeafWidget.h"
|
||||
|
||||
class IInputProcessor;
|
||||
class FCogImguiContext;
|
||||
class UGameViewportClient;
|
||||
class ULocalPlayer;
|
||||
struct ImFontAtlas;
|
||||
struct ImGuiContext;
|
||||
struct ImPlotContext;
|
||||
|
||||
using FCogImguiRenderFunction = TFunction<void(float DeltaTime)>;
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------------------------
|
||||
class COGIMGUI_API SCogImguiWidget : public SLeafWidget
|
||||
@@ -24,81 +18,26 @@ class COGIMGUI_API SCogImguiWidget : public SLeafWidget
|
||||
public:
|
||||
|
||||
SLATE_BEGIN_ARGS(SCogImguiWidget) {}
|
||||
SLATE_ARGUMENT(UGameViewportClient*, GameViewport)
|
||||
SLATE_ARGUMENT(ImFontAtlas*, FontAtlas)
|
||||
SLATE_ARGUMENT(FCogImguiRenderFunction, Render)
|
||||
SLATE_ARGUMENT(FCogImguiContext*, Context)
|
||||
SLATE_END_ARGS()
|
||||
|
||||
void Construct(const FArguments& InArgs);
|
||||
|
||||
~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 bool SupportsKeyboardFocus() const override { return true; }
|
||||
|
||||
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;
|
||||
|
||||
ULocalPlayer* GetLocalPlayer() const;
|
||||
|
||||
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();
|
||||
void SetDrawData(const ImDrawData* InDrawData);
|
||||
|
||||
protected:
|
||||
|
||||
FVector2D TransformScreenPointToImGui(const FGeometry& MyGeometry, const FVector2D& Point) const;
|
||||
|
||||
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;
|
||||
TObjectPtr<FCogImguiContext> Context = nullptr;
|
||||
|
||||
FSlateRenderTransform ImGuiRenderTransform;
|
||||
|
||||
@@ -106,17 +45,5 @@ protected:
|
||||
|
||||
mutable TArray<SlateIndex> IndexBuffer;
|
||||
|
||||
TArray<FCogImguiDrawList> DrawLists;
|
||||
|
||||
ImGuiContext* ImGuiContext = nullptr;
|
||||
|
||||
ImPlotContext* ImPlotContext = nullptr;
|
||||
|
||||
FCogImguiRenderFunction Render;
|
||||
|
||||
float DpiScale = 1.f;
|
||||
|
||||
char IniFilename[512];
|
||||
|
||||
TSharedPtr<IInputProcessor> InputProcessor = nullptr;
|
||||
FCogImguiDrawData DrawData;
|
||||
};
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
#include "CogDebugDraw.h"
|
||||
#include "CogDebugSettings.h"
|
||||
#include "CogWindow_Settings.h"
|
||||
#include "CogWindowManager.h"
|
||||
#include "CogWindowWidgets.h"
|
||||
#include "Engine/World.h"
|
||||
@@ -75,7 +76,7 @@ void FCogWindow::Render(float DeltaTime)
|
||||
ImGui::PopStyleVar(1);
|
||||
}
|
||||
|
||||
if (GetOwner()->GetShowHelp())
|
||||
if (GetOwner()->GetSettingsWindow()->GetSettingsConfig()->bShowHelp)
|
||||
{
|
||||
if (ImGui::IsItemHovered())
|
||||
{
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
#include "CogWindowManager.h"
|
||||
|
||||
#include "CogDebugDrawImGui.h"
|
||||
#include "CogImguiHelper.h"
|
||||
#include "CogImguiInputHelper.h"
|
||||
#include "CogImguiModule.h"
|
||||
#include "CogWindow_Inputs.h"
|
||||
#include "CogWindow_Layouts.h"
|
||||
#include "CogWindow_Settings.h"
|
||||
#include "CogWindow_Spacing.h"
|
||||
@@ -41,7 +41,7 @@ void UCogWindowManager::PostInitProperties()
|
||||
//--------------------------------------------------------------------------------------------------------------------------
|
||||
void UCogWindowManager::InitializeInternal()
|
||||
{
|
||||
ImGuiWidget = FCogImguiModule::Get().CreateImGuiWidget(GEngine->GameViewport, [this](float DeltaTime) { Render(DeltaTime); });
|
||||
Context.Initialize();
|
||||
|
||||
ImGuiSettingsHandler IniHandler;
|
||||
IniHandler.TypeName = "Cog";
|
||||
@@ -59,7 +59,6 @@ void UCogWindowManager::InitializeInternal()
|
||||
SpaceWindows.Add(AddWindow<FCogWindow_Spacing>("Spacing 3", false));
|
||||
SpaceWindows.Add(AddWindow<FCogWindow_Spacing>("Spacing 4", false));
|
||||
|
||||
InputsWindow = AddWindow<FCogWindow_Inputs>("Window.Inputs", false);
|
||||
LayoutsWindow = AddWindow<FCogWindow_Layouts>("Window.Layouts", false);
|
||||
SettingsWindow = AddWindow<FCogWindow_Settings>("Window.Settings", false);
|
||||
|
||||
@@ -86,7 +85,8 @@ void UCogWindowManager::InitializeInternal()
|
||||
TEXT("Save the layout. Cog.SaveLayout <Index>"),
|
||||
FConsoleCommandWithArgsDelegate::CreateLambda([this](const TArray<FString>& Args) { if (Args.Num() > 0) { SaveLayout(FCString::Atoi(*Args[0])); }}),
|
||||
ECVF_Cheat));
|
||||
|
||||
|
||||
IsInitialized = true;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------------------------
|
||||
@@ -105,7 +105,7 @@ void UCogWindowManager::Shutdown()
|
||||
// Destroy ImGui before destroying the windows to make sure
|
||||
// imgui serialize their visibility state in imgui.ini
|
||||
//------------------------------------------------------------
|
||||
ImGuiWidget->DestroyImGuiContext();
|
||||
Context.Shutdown();
|
||||
|
||||
SaveConfig();
|
||||
|
||||
@@ -125,8 +125,6 @@ void UCogWindowManager::Shutdown()
|
||||
{
|
||||
IConsoleManager::Get().UnregisterConsoleObject(ConsoleCommand);
|
||||
}
|
||||
|
||||
FCogImguiModule::Get().DestroyImGuiWidget(ImGuiWidget);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------------------------
|
||||
@@ -137,7 +135,7 @@ void UCogWindowManager::Tick(float DeltaTime)
|
||||
return;
|
||||
}
|
||||
|
||||
if (ImGuiWidget.IsValid() == false)
|
||||
if (IsInitialized == false)
|
||||
{
|
||||
InitializeInternal();
|
||||
}
|
||||
@@ -149,16 +147,14 @@ void UCogWindowManager::Tick(float DeltaTime)
|
||||
LayoutToLoad = -1;
|
||||
}
|
||||
|
||||
if (bRefreshDPIScale)
|
||||
{
|
||||
RefreshDPIScale();
|
||||
bRefreshDPIScale = false;
|
||||
}
|
||||
|
||||
for (FCogWindow* Window : Windows)
|
||||
{
|
||||
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::PopStyleColor(1);
|
||||
|
||||
bool bCompactSaved = bCompactMode;
|
||||
bool bCompactSaved = SettingsWindow->GetSettingsConfig()->bCompactMode;
|
||||
if (bCompactSaved)
|
||||
{
|
||||
FCogWindowWidgets::PushStyleCompact();
|
||||
@@ -176,7 +172,7 @@ void UCogWindowManager::Render(float DeltaTime)
|
||||
|
||||
if (bHideAllWindows == false)
|
||||
{
|
||||
if (ImGuiWidget->GetEnableInput() || bHideMainMenuOnGameInput == false)
|
||||
if (Context.GetEnableInput())
|
||||
{
|
||||
RenderMainMenu();
|
||||
}
|
||||
@@ -188,7 +184,7 @@ void UCogWindowManager::Render(float DeltaTime)
|
||||
|
||||
if (Window->GetIsVisible() && bHideAllWindows == false)
|
||||
{
|
||||
if (bTransparentMode)
|
||||
if (SettingsWindow->GetSettingsConfig()->bTransparentMode)
|
||||
{
|
||||
ImGui::SetNextWindowBgAlpha(0.35f);
|
||||
}
|
||||
@@ -202,8 +198,6 @@ void UCogWindowManager::Render(float DeltaTime)
|
||||
FCogWindowWidgets::PopStyleCompact();
|
||||
}
|
||||
|
||||
TickDPI();
|
||||
|
||||
FCogDebugDrawImGui::Draw();
|
||||
}
|
||||
|
||||
@@ -354,8 +348,6 @@ void UCogWindowManager::RenderMainMenu()
|
||||
|
||||
ImGui::Separator();
|
||||
|
||||
RenderMenuItem(*InputsWindow, "Inputs");
|
||||
|
||||
RenderMenuItem(*LayoutsWindow, "Layouts");
|
||||
|
||||
RenderMenuItem(*SettingsWindow, "Settings");
|
||||
@@ -508,7 +500,7 @@ void UCogWindowManager::RenderOptionMenu(UCogWindowManager::FMenu& Menu)
|
||||
//--------------------------------------------------------------------------------------------------------------------------
|
||||
void UCogWindowManager::RenderMenuItem(FCogWindow& Window, const char* MenuItemName)
|
||||
{
|
||||
if (bShowWindowsInMainMenu)
|
||||
if (SettingsWindow->GetSettingsConfig()->bShowWindowsInMainMenu)
|
||||
{
|
||||
ImGui::SetNextWindowSizeConstraints(
|
||||
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)
|
||||
@@ -652,18 +620,6 @@ void UCogWindowManager::SettingsHandler_WriteAll(ImGuiContext* Context, ImGuiSet
|
||||
Buffer->append("\n");
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------------------------
|
||||
void UCogWindowManager::SetDPIScale(float Value)
|
||||
{
|
||||
if (DPIScale == Value)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
DPIScale = Value;
|
||||
bRefreshDPIScale = true;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------------------------
|
||||
void UCogWindowManager::ResetAllWindowsConfig()
|
||||
{
|
||||
@@ -786,5 +742,5 @@ const UObject* UCogWindowManager::GetAsset(const TSubclassOf<UObject> AssetClass
|
||||
void 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 "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 "CogImguiHelper.h"
|
||||
#include "CogImguiInputHelper.h"
|
||||
#include "CogImguiModule.h"
|
||||
#include "CogImguiWidget.h"
|
||||
#include "CogWindowManager.h"
|
||||
#include "CogWindowWidgets.h"
|
||||
#include "imgui.h"
|
||||
#include "InputCoreTypes.h"
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------------------------
|
||||
@@ -11,17 +15,86 @@ void FCogWindow_Settings::Initialize()
|
||||
Super::Initialize();
|
||||
|
||||
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()
|
||||
{
|
||||
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();
|
||||
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())
|
||||
{
|
||||
GetOwner()->bRefreshDPIScale = true;
|
||||
SetDPIScale(Config->DPIScale);
|
||||
}
|
||||
|
||||
if (ImGui::IsItemHovered())
|
||||
{
|
||||
ImGui::BeginTooltip();
|
||||
@@ -30,20 +103,63 @@ void FCogWindow_Settings::RenderContent()
|
||||
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::Spacing();
|
||||
ImGui::Spacing();
|
||||
if (ImGui::Button("Reset All Windows Config"))
|
||||
{
|
||||
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
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "CogImguiWidget.h"
|
||||
#include "CogImguiContext.h"
|
||||
#include "imgui.h"
|
||||
#include "CogWindowManager.generated.h"
|
||||
|
||||
class FCogWindow;
|
||||
class FCogWindow_Inputs;
|
||||
class FCogWindow_Layouts;
|
||||
class FCogWindow_Settings;
|
||||
class IConsoleObject;
|
||||
@@ -55,26 +54,12 @@ public:
|
||||
|
||||
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 bool RegisterDefaultCommandBindings();
|
||||
|
||||
const FCogWindow_Settings* GetSettingsWindow() const { return SettingsWindow; }
|
||||
|
||||
UCogWindowConfig* GetConfig(const TSubclassOf<UCogWindowConfig> ConfigClass);
|
||||
|
||||
template<class T>
|
||||
@@ -85,7 +70,9 @@ public:
|
||||
template<typename T>
|
||||
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);
|
||||
|
||||
@@ -93,7 +80,6 @@ public:
|
||||
|
||||
protected:
|
||||
|
||||
friend class FCogWindow_Inputs;
|
||||
friend class FCogWindow_Layouts;
|
||||
friend class FCogWindow_Settings;
|
||||
|
||||
@@ -106,8 +92,6 @@ protected:
|
||||
|
||||
virtual void InitializeInternal();
|
||||
|
||||
virtual void RefreshDPIScale();
|
||||
|
||||
virtual void RenderMainMenu();
|
||||
|
||||
virtual FMenu* AddMenu(const FString& Name);
|
||||
@@ -116,8 +100,6 @@ protected:
|
||||
|
||||
virtual void RenderMenuItem(FCogWindow& Window, const char* MenuItemName);
|
||||
|
||||
virtual void TickDPI();
|
||||
|
||||
virtual void ToggleInputMode();
|
||||
|
||||
static void SettingsHandler_ClearAll(ImGuiContext* ctx, ImGuiSettingsHandler*);
|
||||
@@ -144,37 +126,10 @@ protected:
|
||||
UPROPERTY()
|
||||
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)
|
||||
bool bRegisterDefaultCommands = true;
|
||||
|
||||
UPROPERTY(Config)
|
||||
bool bAuthorizeInactiveInput = true;
|
||||
|
||||
UPROPERTY(Config)
|
||||
bool bAuthorizeExclusiveInput = true;
|
||||
|
||||
UPROPERTY(Config)
|
||||
bool bAuthorizeSharedInput = true;
|
||||
|
||||
UPROPERTY(Config)
|
||||
bool bHideMainMenuOnGameInput = true;
|
||||
|
||||
TSharedPtr<SCogImguiWidget> ImGuiWidget = nullptr;
|
||||
FCogImguiContext Context;
|
||||
|
||||
TArray<FCogWindow*> Windows;
|
||||
|
||||
@@ -184,8 +139,6 @@ protected:
|
||||
|
||||
TArray<FCogWindow*> SpaceWindows;
|
||||
|
||||
FCogWindow_Inputs* InputsWindow = nullptr;
|
||||
|
||||
FCogWindow_Settings* SettingsWindow = nullptr;
|
||||
|
||||
FCogWindow_Layouts* LayoutsWindow = nullptr;
|
||||
@@ -198,7 +151,7 @@ protected:
|
||||
|
||||
bool bHideAllWindows = false;
|
||||
|
||||
bool bRefreshDPIScale = false;
|
||||
bool IsInitialized = false;
|
||||
|
||||
TArray<IConsoleObject*> ConsoleCommands;
|
||||
};
|
||||
|
||||
@@ -1,60 +1 @@
|
||||
#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 "CogWindow.h"
|
||||
#include "CogWindowConfig.h"
|
||||
#include "CogWindow_Settings.generated.h"
|
||||
|
||||
class UCogEngineConfig_Settings;
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------------------------
|
||||
class COGWINDOW_API FCogWindow_Settings : public FCogWindow
|
||||
{
|
||||
typedef FCogWindow Super;
|
||||
@@ -11,7 +16,83 @@ public:
|
||||
|
||||
virtual void Initialize() override;
|
||||
|
||||
virtual void RenderTick(float DeltaTime) override;
|
||||
|
||||
const UCogWindowConfig_Settings* GetSettingsConfig() const { return Config; }
|
||||
|
||||
void SetDPIScale(float Value);
|
||||
|
||||
protected:
|
||||
|
||||
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_Selection.h"
|
||||
#include "CogEngineWindow_Skeleton.h"
|
||||
#include "CogEngineWindow_Slate.h"
|
||||
#include "CogEngineWindow_Spawns.h"
|
||||
#include "CogEngineWindow_Stats.h"
|
||||
#include "CogEngineWindow_TimeScale.h"
|
||||
@@ -162,6 +163,8 @@ void ACogSampleGameState::InitializeCog()
|
||||
|
||||
CogWindowManager->AddWindow<FCogEngineWindow_Skeleton>("Engine.Skeleton");
|
||||
|
||||
CogWindowManager->AddWindow<FCogEngineWindow_Slate>("Engine.Slate");
|
||||
|
||||
CogWindowManager->AddWindow<FCogEngineWindow_Spawns>("Engine.Spawns");
|
||||
|
||||
FCogEngineWindow_Stats* StatsWindow = CogWindowManager->AddWindow<FCogEngineWindow_Stats>("Engine.Stats");
|
||||
|
||||
Reference in New Issue
Block a user