mirror of
https://github.com/kevinporetti/UnrealImGui.git
synced 2025-01-18 08:20:32 +00:00
Added support for DPI scaling in ImGui, with scaling in Slate remaining as an alternative:
- The old DPI Scale setting was replaced by DPI Scaling Info, which contains information about scale and method of scaling. - ImGui Context Manager handles scaling in ImGui by scaling all styles, rebuilding fonts using a different size, and raising OnFontAtlasBuilt event. - ImGui Module Manager uses OnFontAtlasBuilt event to rebuild font textures. - The update policy in Texture Manager was loosened to update existing resources rather than throwing an exception. This is less strict but it is now more useful since our main texture can now change. The throwing behavior used in the public interface is now handled before calling to the Texture Manager.
This commit is contained in:
parent
8de65f3d34
commit
9d4eb74bf0
@ -6,6 +6,7 @@
|
|||||||
|
|
||||||
#include "ImGuiDelegatesContainer.h"
|
#include "ImGuiDelegatesContainer.h"
|
||||||
#include "ImGuiImplementation.h"
|
#include "ImGuiImplementation.h"
|
||||||
|
#include "ImGuiModuleSettings.h"
|
||||||
#include "Utilities/ScopeGuards.h"
|
#include "Utilities/ScopeGuards.h"
|
||||||
#include "Utilities/WorldContext.h"
|
#include "Utilities/WorldContext.h"
|
||||||
#include "Utilities/WorldContextIndex.h"
|
#include "Utilities/WorldContextIndex.h"
|
||||||
@ -59,11 +60,13 @@ namespace
|
|||||||
#endif // WITH_EDITOR
|
#endif // WITH_EDITOR
|
||||||
}
|
}
|
||||||
|
|
||||||
FImGuiContextManager::FImGuiContextManager()
|
FImGuiContextManager::FImGuiContextManager(FImGuiModuleSettings& InSettings)
|
||||||
|
: Settings(InSettings)
|
||||||
{
|
{
|
||||||
unsigned char* Pixels;
|
Settings.OnDPIScaleChangedDelegate.AddRaw(this, &FImGuiContextManager::SetDPIScale);
|
||||||
int Width, Height, Bpp;
|
|
||||||
FontAtlas.GetTexDataAsRGBA32(&Pixels, &Width, &Height, &Bpp);
|
SetDPIScale(Settings.GetDPIScaleInfo());
|
||||||
|
BuildFontAtlas();
|
||||||
|
|
||||||
FWorldDelegates::OnWorldTickStart.AddRaw(this, &FImGuiContextManager::OnWorldTickStart);
|
FWorldDelegates::OnWorldTickStart.AddRaw(this, &FImGuiContextManager::OnWorldTickStart);
|
||||||
#if ENGINE_COMPATIBILITY_WITH_WORLD_POST_ACTOR_TICK
|
#if ENGINE_COMPATIBILITY_WITH_WORLD_POST_ACTOR_TICK
|
||||||
@ -73,6 +76,8 @@ FImGuiContextManager::FImGuiContextManager()
|
|||||||
|
|
||||||
FImGuiContextManager::~FImGuiContextManager()
|
FImGuiContextManager::~FImGuiContextManager()
|
||||||
{
|
{
|
||||||
|
Settings.OnDPIScaleChangedDelegate.RemoveAll(this);
|
||||||
|
|
||||||
// Order matters because contexts can be created during World Tick Start events.
|
// Order matters because contexts can be created during World Tick Start events.
|
||||||
FWorldDelegates::OnWorldTickStart.RemoveAll(this);
|
FWorldDelegates::OnWorldTickStart.RemoveAll(this);
|
||||||
#if ENGINE_COMPATIBILITY_WITH_WORLD_POST_ACTOR_TICK
|
#if ENGINE_COMPATIBILITY_WITH_WORLD_POST_ACTOR_TICK
|
||||||
@ -98,6 +103,13 @@ void FImGuiContextManager::Tick(float DeltaSeconds)
|
|||||||
FImGuiDelegatesContainer::Get().OnWorldDebug(Pair.Key).Clear();
|
FImGuiDelegatesContainer::Get().OnWorldDebug(Pair.Key).Clear();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Once all context tick they should use new fonts and we can release the old resources. Extra countdown is added
|
||||||
|
// wait for contexts that ticked outside of this function, before rebuilding fonts.
|
||||||
|
if (FontResourcesReleaseCountdown > 0 && !--FontResourcesReleaseCountdown)
|
||||||
|
{
|
||||||
|
FontResourcesToRelease.Empty();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#if ENGINE_COMPATIBILITY_LEGACY_WORLD_ACTOR_TICK
|
#if ENGINE_COMPATIBILITY_LEGACY_WORLD_ACTOR_TICK
|
||||||
@ -142,8 +154,8 @@ FImGuiContextManager::FContextData& FImGuiContextManager::GetEditorContextData()
|
|||||||
|
|
||||||
if (UNLIKELY(!Data))
|
if (UNLIKELY(!Data))
|
||||||
{
|
{
|
||||||
Data = &Contexts.Emplace(Utilities::EDITOR_CONTEXT_INDEX, FContextData{ GetEditorContextName(), Utilities::EDITOR_CONTEXT_INDEX, DrawMultiContextEvent, FontAtlas, -1 });
|
Data = &Contexts.Emplace(Utilities::EDITOR_CONTEXT_INDEX, FContextData{ GetEditorContextName(), Utilities::EDITOR_CONTEXT_INDEX, OnDrawMultiContext, FontAtlas, -1 });
|
||||||
ContextProxyCreatedEvent.Broadcast(Utilities::EDITOR_CONTEXT_INDEX, *Data->ContextProxy);
|
OnContextProxyCreated.Broadcast(Utilities::EDITOR_CONTEXT_INDEX, *Data->ContextProxy);
|
||||||
}
|
}
|
||||||
|
|
||||||
return *Data;
|
return *Data;
|
||||||
@ -199,8 +211,8 @@ FImGuiContextManager::FContextData& FImGuiContextManager::GetWorldContextData(co
|
|||||||
#if WITH_EDITOR
|
#if WITH_EDITOR
|
||||||
if (UNLIKELY(!Data))
|
if (UNLIKELY(!Data))
|
||||||
{
|
{
|
||||||
Data = &Contexts.Emplace(Index, FContextData{ GetWorldContextName(World), Index, DrawMultiContextEvent, FontAtlas, WorldContext->PIEInstance });
|
Data = &Contexts.Emplace(Index, FContextData{ GetWorldContextName(World), Index, OnDrawMultiContext, FontAtlas, WorldContext->PIEInstance });
|
||||||
ContextProxyCreatedEvent.Broadcast(Index, *Data->ContextProxy);
|
OnContextProxyCreated.Broadcast(Index, *Data->ContextProxy);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -221,3 +233,95 @@ FImGuiContextManager::FContextData& FImGuiContextManager::GetWorldContextData(co
|
|||||||
}
|
}
|
||||||
return *Data;
|
return *Data;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct FGuardContext
|
||||||
|
{
|
||||||
|
FGuardContext()
|
||||||
|
: OldContext(ImGui::GetCurrentContext())
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
~FGuardContext()
|
||||||
|
{
|
||||||
|
if (bRestore)
|
||||||
|
{
|
||||||
|
ImGui::SetCurrentContext(OldContext);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
FGuardContext(FGuardContext&& Other)
|
||||||
|
: OldContext(MoveTemp(Other.OldContext))
|
||||||
|
{
|
||||||
|
Other.bRestore = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
FGuardContext& operator=(FGuardContext&&) = delete;
|
||||||
|
|
||||||
|
FGuardContext(const FGuardContext&) = delete;
|
||||||
|
FGuardContext& operator=(const FGuardContext&) = delete;
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
ImGuiContext* OldContext = nullptr;
|
||||||
|
bool bRestore = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
void FImGuiContextManager::SetDPIScale(const FImGuiDPIScaleInfo& ScaleInfo)
|
||||||
|
{
|
||||||
|
const float Scale = ScaleInfo.GetImGuiScale();
|
||||||
|
if (DPIScale != Scale)
|
||||||
|
{
|
||||||
|
DPIScale = Scale;
|
||||||
|
|
||||||
|
// Only rebuild font atlas if it is already built. Otherwise allow the other logic to pick a moment.
|
||||||
|
if (FontAtlas.IsBuilt())
|
||||||
|
{
|
||||||
|
RebuildFontAtlas();
|
||||||
|
}
|
||||||
|
|
||||||
|
for (auto& Pair : Contexts)
|
||||||
|
{
|
||||||
|
if (Pair.Value.ContextProxy)
|
||||||
|
{
|
||||||
|
ImGuiStyle NewStyle = ImGuiStyle();
|
||||||
|
NewStyle.ScaleAllSizes(DPIScale);
|
||||||
|
|
||||||
|
FGuardContext GuardContext;
|
||||||
|
Pair.Value.ContextProxy->SetAsCurrent();
|
||||||
|
ImGui::GetStyle() = MoveTemp(NewStyle);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void FImGuiContextManager::BuildFontAtlas()
|
||||||
|
{
|
||||||
|
if (!FontAtlas.IsBuilt())
|
||||||
|
{
|
||||||
|
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);
|
||||||
|
|
||||||
|
OnFontAtlasBuilt.Broadcast();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void FImGuiContextManager::RebuildFontAtlas()
|
||||||
|
{
|
||||||
|
if (FontAtlas.IsBuilt())
|
||||||
|
{
|
||||||
|
// Keep the old resources alive for a few frames to give all contexts a chance to bind to new ones.
|
||||||
|
FontResourcesToRelease.Add(TUniquePtr<ImFontAtlas>(new ImFontAtlas()));
|
||||||
|
Swap(*FontResourcesToRelease.Last(), FontAtlas);
|
||||||
|
|
||||||
|
// Typically, one frame should be enough but since we allow for custom ticking, we need at least to frames to
|
||||||
|
// wait for contexts that already ticked and will not do that before the end of the next tick of this manager.
|
||||||
|
FontResourcesReleaseCountdown = 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
BuildFontAtlas();
|
||||||
|
}
|
||||||
|
@ -5,6 +5,8 @@
|
|||||||
#include "ImGuiContextProxy.h"
|
#include "ImGuiContextProxy.h"
|
||||||
|
|
||||||
|
|
||||||
|
class FImGuiModuleSettings;
|
||||||
|
|
||||||
// TODO: It might be useful to broadcast FContextProxyCreatedDelegate to users, to support similar cases to our ImGui
|
// TODO: It might be useful to broadcast FContextProxyCreatedDelegate to users, to support similar cases to our ImGui
|
||||||
// demo, but we would need to remove from that interface internal classes.
|
// demo, but we would need to remove from that interface internal classes.
|
||||||
|
|
||||||
@ -18,7 +20,7 @@ class FImGuiContextManager
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
FImGuiContextManager();
|
FImGuiContextManager(FImGuiModuleSettings& InSettings);
|
||||||
|
|
||||||
FImGuiContextManager(const FImGuiContextManager&) = delete;
|
FImGuiContextManager(const FImGuiContextManager&) = delete;
|
||||||
FImGuiContextManager& operator=(const FImGuiContextManager&) = delete;
|
FImGuiContextManager& operator=(const FImGuiContextManager&) = delete;
|
||||||
@ -31,7 +33,6 @@ public:
|
|||||||
ImFontAtlas& GetFontAtlas() { return FontAtlas; }
|
ImFontAtlas& GetFontAtlas() { return FontAtlas; }
|
||||||
const ImFontAtlas& GetFontAtlas() const { return FontAtlas; }
|
const ImFontAtlas& GetFontAtlas() const { return FontAtlas; }
|
||||||
|
|
||||||
|
|
||||||
#if WITH_EDITOR
|
#if WITH_EDITOR
|
||||||
// Get or create editor ImGui context proxy.
|
// Get or create editor ImGui context proxy.
|
||||||
FORCEINLINE FImGuiContextProxy& GetEditorContextProxy() { return *GetEditorContextData().ContextProxy; }
|
FORCEINLINE FImGuiContextProxy& GetEditorContextProxy() { return *GetEditorContextData().ContextProxy; }
|
||||||
@ -57,10 +58,13 @@ public:
|
|||||||
|
|
||||||
// Delegate called for all contexts in manager, right after calling context specific draw event. Allows listeners
|
// Delegate called for all contexts in manager, right after calling context specific draw event. Allows listeners
|
||||||
// draw the same content to multiple contexts.
|
// draw the same content to multiple contexts.
|
||||||
FSimpleMulticastDelegate& OnDrawMultiContext() { return DrawMultiContextEvent; }
|
FSimpleMulticastDelegate OnDrawMultiContext;
|
||||||
|
|
||||||
// Delegate called when new context proxy is created.
|
// Delegate called when a new context proxy is created.
|
||||||
FContextProxyCreatedDelegate& OnContextProxyCreated() { return ContextProxyCreatedEvent; }
|
FContextProxyCreatedDelegate OnContextProxyCreated;
|
||||||
|
|
||||||
|
// Delegate called after font atlas is built.
|
||||||
|
FSimpleMulticastDelegate OnFontAtlasBuilt;
|
||||||
|
|
||||||
void Tick(float DeltaSeconds);
|
void Tick(float DeltaSeconds);
|
||||||
|
|
||||||
@ -99,11 +103,17 @@ private:
|
|||||||
|
|
||||||
FContextData& GetWorldContextData(const UWorld& World, int32* OutContextIndex = nullptr);
|
FContextData& GetWorldContextData(const UWorld& World, int32* OutContextIndex = nullptr);
|
||||||
|
|
||||||
|
void SetDPIScale(const FImGuiDPIScaleInfo& ScaleInfo);
|
||||||
|
void BuildFontAtlas();
|
||||||
|
void RebuildFontAtlas();
|
||||||
|
|
||||||
TMap<int32, FContextData> Contexts;
|
TMap<int32, FContextData> Contexts;
|
||||||
|
|
||||||
FSimpleMulticastDelegate DrawMultiContextEvent;
|
|
||||||
|
|
||||||
FContextProxyCreatedDelegate ContextProxyCreatedEvent;
|
|
||||||
|
|
||||||
ImFontAtlas FontAtlas;
|
ImFontAtlas FontAtlas;
|
||||||
|
TArray<TUniquePtr<ImFontAtlas>> FontResourcesToRelease;
|
||||||
|
|
||||||
|
FImGuiModuleSettings& Settings;
|
||||||
|
|
||||||
|
float DPIScale = -1.f;
|
||||||
|
int32 FontResourcesReleaseCountdown = 0;
|
||||||
};
|
};
|
||||||
|
@ -95,7 +95,7 @@ FImGuiDelegateHandle FImGuiModule::AddMultiContextImGuiDelegate(const FImGuiDele
|
|||||||
#else
|
#else
|
||||||
checkf(ImGuiModuleManager, TEXT("Null pointer to internal module implementation. Is module available?"));
|
checkf(ImGuiModuleManager, TEXT("Null pointer to internal module implementation. Is module available?"));
|
||||||
|
|
||||||
return { ImGuiModuleManager->GetContextManager().OnDrawMultiContext().Add(Delegate), EDelegateCategory::MultiContext };
|
return { ImGuiModuleManager->GetContextManager().OnDrawMultiContext.Add(Delegate), EDelegateCategory::MultiContext };
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -115,7 +115,7 @@ void FImGuiModule::RemoveImGuiDelegate(const FImGuiDelegateHandle& Handle)
|
|||||||
{
|
{
|
||||||
if (Handle.Category == EDelegateCategory::MultiContext)
|
if (Handle.Category == EDelegateCategory::MultiContext)
|
||||||
{
|
{
|
||||||
ImGuiModuleManager->GetContextManager().OnDrawMultiContext().Remove(Handle.Handle);
|
ImGuiModuleManager->GetContextManager().OnDrawMultiContext.Remove(Handle.Handle);
|
||||||
}
|
}
|
||||||
else if (auto* Proxy = ImGuiModuleManager->GetContextManager().GetContextProxy(Handle.Index))
|
else if (auto* Proxy = ImGuiModuleManager->GetContextManager().GetContextProxy(Handle.Index))
|
||||||
{
|
{
|
||||||
@ -135,7 +135,13 @@ FImGuiTextureHandle FImGuiModule::FindTextureHandle(const FName& Name)
|
|||||||
|
|
||||||
FImGuiTextureHandle FImGuiModule::RegisterTexture(const FName& Name, class UTexture2D* Texture, bool bMakeUnique)
|
FImGuiTextureHandle FImGuiModule::RegisterTexture(const FName& Name, class UTexture2D* Texture, bool bMakeUnique)
|
||||||
{
|
{
|
||||||
const TextureIndex Index = ImGuiModuleManager->GetTextureManager().CreateTextureResources(Name, Texture, bMakeUnique);
|
FTextureManager& TextureManager = ImGuiModuleManager->GetTextureManager();
|
||||||
|
|
||||||
|
checkf(!bMakeUnique || TextureManager.FindTextureIndex(Name) == INDEX_NONE,
|
||||||
|
TEXT("Trying to register a texture with a name '%s' that is already used. Chose a different name ")
|
||||||
|
TEXT("or use bMakeUnique false, to update existing texture resources."), *Name.ToString());
|
||||||
|
|
||||||
|
const TextureIndex Index = TextureManager.CreateTextureResources(Name, Texture);
|
||||||
return FImGuiTextureHandle{ Name, ImGuiInterops::ToImTextureID(Index) };
|
return FImGuiTextureHandle{ Name, ImGuiInterops::ToImTextureID(Index) };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -15,14 +15,18 @@
|
|||||||
// High enough z-order guarantees that ImGui output is rendered on top of the game UI.
|
// High enough z-order guarantees that ImGui output is rendered on top of the game UI.
|
||||||
constexpr int32 IMGUI_WIDGET_Z_ORDER = 10000;
|
constexpr int32 IMGUI_WIDGET_Z_ORDER = 10000;
|
||||||
|
|
||||||
|
// Module texture names.
|
||||||
|
const static FName PlainTextureName = "ImGuiModule_Plain";
|
||||||
|
const static FName FontAtlasTextureName = "ImGuiModule_FontAtlas";
|
||||||
|
|
||||||
FImGuiModuleManager::FImGuiModuleManager()
|
FImGuiModuleManager::FImGuiModuleManager()
|
||||||
: Commands(Properties)
|
: Commands(Properties)
|
||||||
, Settings(Properties, Commands)
|
, Settings(Properties, Commands)
|
||||||
, ImGuiDemo(Properties)
|
, ImGuiDemo(Properties)
|
||||||
|
, ContextManager(Settings)
|
||||||
{
|
{
|
||||||
// Register in context manager to get information whenever a new context proxy is created.
|
// Register in context manager to get information whenever a new context proxy is created.
|
||||||
ContextManager.OnContextProxyCreated().AddRaw(this, &FImGuiModuleManager::OnContextProxyCreated);
|
ContextManager.OnContextProxyCreated.AddRaw(this, &FImGuiModuleManager::OnContextProxyCreated);
|
||||||
|
|
||||||
// Typically we will use viewport created events to add widget to new game viewports.
|
// Typically we will use viewport created events to add widget to new game viewports.
|
||||||
ViewportCreatedHandle = UGameViewportClient::OnViewportCreated().AddRaw(this, &FImGuiModuleManager::OnViewportCreated);
|
ViewportCreatedHandle = UGameViewportClient::OnViewportCreated().AddRaw(this, &FImGuiModuleManager::OnViewportCreated);
|
||||||
@ -43,6 +47,8 @@ FImGuiModuleManager::FImGuiModuleManager()
|
|||||||
|
|
||||||
FImGuiModuleManager::~FImGuiModuleManager()
|
FImGuiModuleManager::~FImGuiModuleManager()
|
||||||
{
|
{
|
||||||
|
ContextManager.OnFontAtlasBuilt.RemoveAll(this);
|
||||||
|
|
||||||
// We are no longer interested with adding widgets to viewports.
|
// We are no longer interested with adding widgets to viewports.
|
||||||
if (ViewportCreatedHandle.IsValid())
|
if (ViewportCreatedHandle.IsValid())
|
||||||
{
|
{
|
||||||
@ -80,22 +86,30 @@ void FImGuiModuleManager::LoadTextures()
|
|||||||
TextureManager.InitializeErrorTexture(FColor::Magenta);
|
TextureManager.InitializeErrorTexture(FColor::Magenta);
|
||||||
|
|
||||||
// Create an empty texture at index 0. We will use it for ImGui outputs with null texture id.
|
// Create an empty texture at index 0. We will use it for ImGui outputs with null texture id.
|
||||||
TextureManager.CreatePlainTexture(FName{ "ImGuiModule_Plain" }, 2, 2, FColor::White);
|
TextureManager.CreatePlainTexture(PlainTextureName, 2, 2, FColor::White);
|
||||||
|
|
||||||
// Create a font atlas texture.
|
// Register for atlas built events, so we can rebuild textures.
|
||||||
ImFontAtlas& Fonts = ContextManager.GetFontAtlas();
|
ContextManager.OnFontAtlasBuilt.AddRaw(this, &FImGuiModuleManager::BuildFontAtlasTexture);
|
||||||
|
|
||||||
unsigned char* Pixels;
|
BuildFontAtlasTexture();
|
||||||
int Width, Height, Bpp;
|
|
||||||
Fonts.GetTexDataAsRGBA32(&Pixels, &Width, &Height, &Bpp);
|
|
||||||
|
|
||||||
TextureIndex FontsTexureIndex = TextureManager.CreateTexture(FName{ "ImGuiModule_FontAtlas" }, Width, Height, Bpp, Pixels);
|
|
||||||
|
|
||||||
// Set font texture index in ImGui.
|
|
||||||
Fonts.TexID = ImGuiInterops::ToImTextureID(FontsTexureIndex);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void FImGuiModuleManager::BuildFontAtlasTexture()
|
||||||
|
{
|
||||||
|
// Create a font atlas texture.
|
||||||
|
ImFontAtlas& Fonts = ContextManager.GetFontAtlas();
|
||||||
|
|
||||||
|
unsigned char* Pixels;
|
||||||
|
int Width, Height, Bpp;
|
||||||
|
Fonts.GetTexDataAsRGBA32(&Pixels, &Width, &Height, &Bpp);
|
||||||
|
|
||||||
|
const TextureIndex FontsTexureIndex = TextureManager.CreateTexture(FontAtlasTextureName, Width, Height, Bpp, Pixels);
|
||||||
|
|
||||||
|
// Set the font texture index in the ImGui.
|
||||||
|
Fonts.TexID = ImGuiInterops::ToImTextureID(FontsTexureIndex);
|
||||||
|
}
|
||||||
|
|
||||||
void FImGuiModuleManager::RegisterTick()
|
void FImGuiModuleManager::RegisterTick()
|
||||||
{
|
{
|
||||||
// Slate Post-Tick is a good moment to end and advance ImGui frame as it minimises a tearing.
|
// Slate Post-Tick is a good moment to end and advance ImGui frame as it minimises a tearing.
|
||||||
|
@ -46,6 +46,7 @@ private:
|
|||||||
FImGuiModuleManager& operator=(FImGuiModuleManager&&) = delete;
|
FImGuiModuleManager& operator=(FImGuiModuleManager&&) = delete;
|
||||||
|
|
||||||
void LoadTextures();
|
void LoadTextures();
|
||||||
|
void BuildFontAtlasTexture();
|
||||||
|
|
||||||
bool IsTickRegistered() { return TickDelegateHandle.IsValid(); }
|
bool IsTickRegistered() { return TickDelegateHandle.IsValid(); }
|
||||||
void RegisterTick();
|
void RegisterTick();
|
||||||
|
@ -104,7 +104,7 @@ void FImGuiModuleSettings::UpdateSettings()
|
|||||||
SetUseSoftwareCursor(SettingsObject->bUseSoftwareCursor);
|
SetUseSoftwareCursor(SettingsObject->bUseSoftwareCursor);
|
||||||
SetToggleInputKey(SettingsObject->ToggleInput);
|
SetToggleInputKey(SettingsObject->ToggleInput);
|
||||||
SetCanvasSizeInfo(SettingsObject->CanvasSize);
|
SetCanvasSizeInfo(SettingsObject->CanvasSize);
|
||||||
SetDPIScale(SettingsObject->DPIScale);
|
SetDPIScaleInfo(SettingsObject->DPIScale);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -167,16 +167,16 @@ void FImGuiModuleSettings::SetCanvasSizeInfo(const FImGuiCanvasSizeInfo& CanvasS
|
|||||||
if (CanvasSize != CanvasSizeInfo)
|
if (CanvasSize != CanvasSizeInfo)
|
||||||
{
|
{
|
||||||
CanvasSize = CanvasSizeInfo;
|
CanvasSize = CanvasSizeInfo;
|
||||||
OnCanvasSizeInfoChangeDelegate.Broadcast(CanvasSize);
|
OnCanvasSizeChangedDelegate.Broadcast(CanvasSize);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void FImGuiModuleSettings::SetDPIScale(float Scale)
|
void FImGuiModuleSettings::SetDPIScaleInfo(const FImGuiDPIScaleInfo& ScaleInfo)
|
||||||
{
|
{
|
||||||
if (DPIScale != Scale)
|
if (DPIScale != ScaleInfo)
|
||||||
{
|
{
|
||||||
DPIScale = Scale;
|
DPIScale = ScaleInfo;
|
||||||
OnDPIScaleChangeDelegate.Broadcast(DPIScale);
|
OnDPIScaleChangedDelegate.Broadcast(DPIScale);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -88,6 +88,49 @@ struct FImGuiCanvasSizeInfo
|
|||||||
bool operator!=(const FImGuiCanvasSizeInfo& Other) const { return !(*this == Other); }
|
bool operator!=(const FImGuiCanvasSizeInfo& Other) const { return !(*this == Other); }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
UENUM(BlueprintType)
|
||||||
|
enum class EImGuiDPIScaleMethod : uint8
|
||||||
|
{
|
||||||
|
ImGui UMETA(DisplayName = "ImGui", ToolTip = "Scale ImGui fonts and styles."),
|
||||||
|
Slate UMETA(ToolTip = "Scale in Slate. ImGui canvas size will be adjusted to get the screen size that is the same as defined in the Canvas Size property.")
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Struct with DPI scale data.
|
||||||
|
*/
|
||||||
|
USTRUCT()
|
||||||
|
struct FImGuiDPIScaleInfo
|
||||||
|
{
|
||||||
|
GENERATED_BODY()
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
|
// Whether to scale in ImGui or in Slate. Scaling in ImGui gives better looking results but Slate might be a better
|
||||||
|
// option when layouts do not account for different fonts and styles. When scaling in Slate, ImGui canvas size will
|
||||||
|
// be adjusted to get the screen size that is the same as defined in the Canvas Size property.
|
||||||
|
UPROPERTY(EditAnywhere, Category = "DPI Scale")
|
||||||
|
EImGuiDPIScaleMethod ScalingMethod = EImGuiDPIScaleMethod::ImGui;
|
||||||
|
|
||||||
|
// Fixed scale.
|
||||||
|
UPROPERTY(EditAnywhere, Category = "DPI Scale", meta = (ClampMin = 0, UIMin = 0))
|
||||||
|
float Scale = 1.f;
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
float GetImGuiScale() const { return ShouldScaleInSlate() ? 1.f : Scale; }
|
||||||
|
|
||||||
|
float GetSlateScale() const { return ShouldScaleInSlate() ? Scale : 1.f; }
|
||||||
|
|
||||||
|
bool ShouldScaleInSlate() const { return ScalingMethod == EImGuiDPIScaleMethod::Slate; }
|
||||||
|
|
||||||
|
bool operator==(const FImGuiDPIScaleInfo& Other) const
|
||||||
|
{
|
||||||
|
return (Scale == Other.Scale) && (ScalingMethod == Other.ScalingMethod);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool operator!=(const FImGuiDPIScaleInfo& Other) const { return !(*this == Other); }
|
||||||
|
};
|
||||||
|
|
||||||
// UObject used for loading and saving ImGui settings. To access actual settings use FImGuiModuleSettings interface.
|
// UObject used for loading and saving ImGui settings. To access actual settings use FImGuiModuleSettings interface.
|
||||||
UCLASS(config=ImGui, defaultconfig)
|
UCLASS(config=ImGui, defaultconfig)
|
||||||
class UImGuiSettings : public UObject
|
class UImGuiSettings : public UObject
|
||||||
@ -148,13 +191,9 @@ protected:
|
|||||||
UPROPERTY(EditAnywhere, config, Category = "Canvas Size")
|
UPROPERTY(EditAnywhere, config, Category = "Canvas Size")
|
||||||
FImGuiCanvasSizeInfo CanvasSize;
|
FImGuiCanvasSizeInfo CanvasSize;
|
||||||
|
|
||||||
// DPI scale for the ImGui widgets.
|
// Setup DPI Scale.
|
||||||
//
|
UPROPERTY(EditAnywhere, config, Category = "DPI Scale", Meta = (ShowOnlyInnerProperties))
|
||||||
// Note that when this scale is other than 1.0, canvas size will be scaled before it is passed to the ImGui.
|
FImGuiDPIScaleInfo DPIScale;
|
||||||
// It will be scaled to keep the same screen size as defined by the Canvas Size property. If the default
|
|
||||||
// canvas size is 3840x2160 and the DPI scale is 2.0, the size passed to the ImGui will be 1920x1080.
|
|
||||||
UPROPERTY(EditAnywhere, Category = "DPI Scale", meta = (ClampMin = 0, UIMin = 0))
|
|
||||||
float DPIScale = 1.f;
|
|
||||||
|
|
||||||
// Deprecated name for ToggleInput. Kept temporarily to automatically move old configuration.
|
// Deprecated name for ToggleInput. Kept temporarily to automatically move old configuration.
|
||||||
UPROPERTY(config)
|
UPROPERTY(config)
|
||||||
@ -178,9 +217,9 @@ public:
|
|||||||
|
|
||||||
// Generic delegate used to notify changes of boolean properties.
|
// Generic delegate used to notify changes of boolean properties.
|
||||||
DECLARE_MULTICAST_DELEGATE_OneParam(FBoolChangeDelegate, bool);
|
DECLARE_MULTICAST_DELEGATE_OneParam(FBoolChangeDelegate, bool);
|
||||||
DECLARE_MULTICAST_DELEGATE_OneParam(FFloatChangeDelegate, float);
|
|
||||||
DECLARE_MULTICAST_DELEGATE_OneParam(FStringClassReferenceChangeDelegate, const FStringClassReference&);
|
DECLARE_MULTICAST_DELEGATE_OneParam(FStringClassReferenceChangeDelegate, const FStringClassReference&);
|
||||||
DECLARE_MULTICAST_DELEGATE_OneParam(FImGuiCanvasSizeInfoChangeDelegate, const FImGuiCanvasSizeInfo&);
|
DECLARE_MULTICAST_DELEGATE_OneParam(FImGuiCanvasSizeInfoChangeDelegate, const FImGuiCanvasSizeInfo&);
|
||||||
|
DECLARE_MULTICAST_DELEGATE_OneParam(FImGuiDPIScaleInfoChangeDelegate, const FImGuiDPIScaleInfo&);
|
||||||
|
|
||||||
// Constructor for ImGui module settings. It will bind to instances of module properties and commands and will
|
// Constructor for ImGui module settings. It will bind to instances of module properties and commands and will
|
||||||
// update them every time when settings are changed.
|
// update them every time when settings are changed.
|
||||||
@ -206,8 +245,8 @@ public:
|
|||||||
// Get the information how to calculate the canvas size.
|
// Get the information how to calculate the canvas size.
|
||||||
const FImGuiCanvasSizeInfo& GetCanvasSizeInfo() const { return CanvasSize; }
|
const FImGuiCanvasSizeInfo& GetCanvasSizeInfo() const { return CanvasSize; }
|
||||||
|
|
||||||
// Get the DPI Scale.
|
// Get the DPI Scale information.
|
||||||
float GetDPIScale() const { return DPIScale; }
|
const FImGuiDPIScaleInfo& GetDPIScaleInfo() const { return DPIScale; }
|
||||||
|
|
||||||
// Delegate raised when ImGui Input Handle is changed.
|
// Delegate raised when ImGui Input Handle is changed.
|
||||||
FStringClassReferenceChangeDelegate OnImGuiInputHandlerClassChanged;
|
FStringClassReferenceChangeDelegate OnImGuiInputHandlerClassChanged;
|
||||||
@ -216,10 +255,10 @@ public:
|
|||||||
FBoolChangeDelegate OnUseSoftwareCursorChanged;
|
FBoolChangeDelegate OnUseSoftwareCursorChanged;
|
||||||
|
|
||||||
// Delegate raised when information how to calculate the canvas size is changed.
|
// Delegate raised when information how to calculate the canvas size is changed.
|
||||||
FImGuiCanvasSizeInfoChangeDelegate OnCanvasSizeInfoChangeDelegate;
|
FImGuiCanvasSizeInfoChangeDelegate OnCanvasSizeChangedDelegate;
|
||||||
|
|
||||||
// Delegate raised when the DPI scale is changed.
|
// Delegate raised when the DPI scale is changed.
|
||||||
FFloatChangeDelegate OnDPIScaleChangeDelegate;
|
FImGuiDPIScaleInfoChangeDelegate OnDPIScaleChangedDelegate;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
@ -232,7 +271,7 @@ private:
|
|||||||
void SetUseSoftwareCursor(bool bUse);
|
void SetUseSoftwareCursor(bool bUse);
|
||||||
void SetToggleInputKey(const FImGuiKeyInfo& KeyInfo);
|
void SetToggleInputKey(const FImGuiKeyInfo& KeyInfo);
|
||||||
void SetCanvasSizeInfo(const FImGuiCanvasSizeInfo& CanvasSizeInfo);
|
void SetCanvasSizeInfo(const FImGuiCanvasSizeInfo& CanvasSizeInfo);
|
||||||
void SetDPIScale(float DPIScale);
|
void SetDPIScaleInfo(const FImGuiDPIScaleInfo& ScaleInfo);
|
||||||
|
|
||||||
#if WITH_EDITOR
|
#if WITH_EDITOR
|
||||||
void OnPropertyChanged(class UObject* ObjectBeingModified, struct FPropertyChangedEvent& PropertyChangedEvent);
|
void OnPropertyChanged(class UObject* ObjectBeingModified, struct FPropertyChangedEvent& PropertyChangedEvent);
|
||||||
@ -244,7 +283,7 @@ private:
|
|||||||
FStringClassReference ImGuiInputHandlerClass;
|
FStringClassReference ImGuiInputHandlerClass;
|
||||||
FImGuiKeyInfo ToggleInputKey;
|
FImGuiKeyInfo ToggleInputKey;
|
||||||
FImGuiCanvasSizeInfo CanvasSize;
|
FImGuiCanvasSizeInfo CanvasSize;
|
||||||
float DPIScale = 1.f;
|
FImGuiDPIScaleInfo DPIScale;
|
||||||
bool bShareKeyboardInput = false;
|
bool bShareKeyboardInput = false;
|
||||||
bool bShareGamepadInput = false;
|
bool bShareGamepadInput = false;
|
||||||
bool bShareMouseInput = false;
|
bool bShareMouseInput = false;
|
||||||
|
@ -15,7 +15,6 @@ void FTextureManager::InitializeErrorTexture(const FColor& Color)
|
|||||||
TextureIndex FTextureManager::CreateTexture(const FName& Name, int32 Width, int32 Height, uint32 SrcBpp, uint8* SrcData, TFunction<void(uint8*)> SrcDataCleanup)
|
TextureIndex FTextureManager::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."));
|
checkf(Name != NAME_None, TEXT("Trying to create a texture with a name 'NAME_None' is not allowed."));
|
||||||
checkf(FindTextureIndex(Name) == INDEX_NONE, TEXT("Trying to create texture using name '%s' that is already registered."), *Name.ToString());
|
|
||||||
|
|
||||||
return CreateTextureInternal(Name, Width, Height, SrcBpp, SrcData, SrcDataCleanup);
|
return CreateTextureInternal(Name, Width, Height, SrcBpp, SrcData, SrcDataCleanup);
|
||||||
}
|
}
|
||||||
@ -23,24 +22,17 @@ TextureIndex FTextureManager::CreateTexture(const FName& Name, int32 Width, int3
|
|||||||
TextureIndex FTextureManager::CreatePlainTexture(const FName& Name, int32 Width, int32 Height, FColor Color)
|
TextureIndex FTextureManager::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."));
|
checkf(Name != NAME_None, TEXT("Trying to create a texture with a name 'NAME_None' is not allowed."));
|
||||||
checkf(FindTextureIndex(Name) == INDEX_NONE, TEXT("Trying to create texture using name '%s' that is already registered."), *Name.ToString());
|
|
||||||
|
|
||||||
return CreatePlainTextureInternal(Name, Width, Height, Color);
|
return CreatePlainTextureInternal(Name, Width, Height, Color);
|
||||||
}
|
}
|
||||||
|
|
||||||
TextureIndex FTextureManager::CreateTextureResources(const FName& Name, UTexture2D* Texture, bool bMakeUnique)
|
TextureIndex FTextureManager::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(Name != NAME_None, TEXT("Trying to create texture resources with a name 'NAME_None' is not allowed."));
|
||||||
checkf(Texture, TEXT("Null Texture."));
|
checkf(Texture, TEXT("Null Texture."));
|
||||||
|
|
||||||
if (bMakeUnique)
|
|
||||||
{
|
|
||||||
checkf(FindTextureIndex(Name) == INDEX_NONE, TEXT("Trying to create texture resources using name '%s' that is already registered.")
|
|
||||||
TEXT(" Consider using different name or set bMakeUnique parameter to false."), *Name.ToString());
|
|
||||||
}
|
|
||||||
|
|
||||||
// Create an entry for the texture.
|
// Create an entry for the texture.
|
||||||
return AddTextureEntry(Name, Texture, false, true);
|
return AddTextureEntry(Name, Texture, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
void FTextureManager::ReleaseTextureResources(TextureIndex Index)
|
void FTextureManager::ReleaseTextureResources(TextureIndex Index)
|
||||||
@ -75,7 +67,7 @@ TextureIndex FTextureManager::CreateTextureInternal(const FName& Name, int32 Wid
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
return AddTextureEntry(Name, Texture, true, false);
|
return AddTextureEntry(Name, Texture, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -94,18 +86,18 @@ TextureIndex FTextureManager::CreatePlainTextureInternal(const FName& Name, int3
|
|||||||
return CreateTextureInternal(Name, Width, Height, Bpp, SrcData, SrcDataCleanup);
|
return CreateTextureInternal(Name, Width, Height, Bpp, SrcData, SrcDataCleanup);
|
||||||
}
|
}
|
||||||
|
|
||||||
TextureIndex FTextureManager::AddTextureEntry(const FName& Name, UTexture2D* Texture, bool bAddToRoot, bool bUpdate)
|
TextureIndex FTextureManager::AddTextureEntry(const FName& Name, UTexture2D* Texture, bool bAddToRoot)
|
||||||
{
|
{
|
||||||
// If we update try to find entry with that name.
|
// Try to find an entry with that name.
|
||||||
TextureIndex Index = bUpdate ? FindTextureIndex(Name) : INDEX_NONE;
|
TextureIndex Index = FindTextureIndex(Name);
|
||||||
|
|
||||||
// If we didn't find, try to find and entry to reuse.
|
// If this is a new name, try to find an entry to reuse.
|
||||||
if (Index == INDEX_NONE)
|
if (Index == INDEX_NONE)
|
||||||
{
|
{
|
||||||
Index = FindTextureIndex(NAME_None);
|
Index = FindTextureIndex(NAME_None);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Either update/reuse entry or add a new one.
|
// Either update/reuse an entry or add a new one.
|
||||||
if (Index != INDEX_NONE)
|
if (Index != INDEX_NONE)
|
||||||
{
|
{
|
||||||
TextureResources[Index] = { Name, Texture, bAddToRoot };
|
TextureResources[Index] = { Name, Texture, bAddToRoot };
|
||||||
|
@ -60,7 +60,7 @@ public:
|
|||||||
return IsValidTexture(Index) ? TextureResources[Index].ResourceHandle : ErrorTexture.ResourceHandle;
|
return IsValidTexture(Index) ? TextureResources[Index].ResourceHandle : ErrorTexture.ResourceHandle;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create a texture from raw data. Throws exception if there is already a texture with that name.
|
// Create a texture from raw data.
|
||||||
// @param Name - The texture name
|
// @param Name - The texture name
|
||||||
// @param Width - The texture width
|
// @param Width - The texture width
|
||||||
// @param Height - The texture height
|
// @param Height - The texture height
|
||||||
@ -70,7 +70,7 @@ public:
|
|||||||
// @returns The index of a texture that was created
|
// @returns The index of a texture that was created
|
||||||
TextureIndex CreateTexture(const FName& Name, int32 Width, int32 Height, uint32 SrcBpp, uint8* SrcData, TFunction<void(uint8*)> SrcDataCleanup = [](uint8*) {});
|
TextureIndex CreateTexture(const FName& Name, int32 Width, int32 Height, uint32 SrcBpp, uint8* SrcData, TFunction<void(uint8*)> SrcDataCleanup = [](uint8*) {});
|
||||||
|
|
||||||
// Create a plain texture. Throws exception if there is already a texture with that name.
|
// Create a plain texture.
|
||||||
// @param Name - The texture name
|
// @param Name - The texture name
|
||||||
// @param Width - The texture width
|
// @param Width - The texture width
|
||||||
// @param Height - The texture height
|
// @param Height - The texture height
|
||||||
@ -78,16 +78,11 @@ public:
|
|||||||
// @returns The index of a texture that was created
|
// @returns The index of a texture that was created
|
||||||
TextureIndex CreatePlainTexture(const FName& Name, int32 Width, int32 Height, FColor Color);
|
TextureIndex CreatePlainTexture(const FName& Name, int32 Width, int32 Height, FColor Color);
|
||||||
|
|
||||||
// Create Slate resources to an existing texture, managed externally. As part of an external interface it allows
|
// Create Slate resources to an existing texture, managed externally.
|
||||||
// to loosen resource verification policy. By default (consistently with other create function) it protects from
|
|
||||||
// creating resources with name that is already registered. If bMakeUnique is false, then existing resources are
|
|
||||||
// updated/replaced. Throws exception, if name argument is NAME_None or texture is null.
|
|
||||||
// @param Name - The texture name
|
// @param Name - The texture name
|
||||||
// @param Texture - The texture
|
// @param Texture - The texture
|
||||||
// @param bMakeUnique - If true (default) and there is already a texture with given name, then exception is thrown,
|
|
||||||
// otherwise existing resources are updated.
|
|
||||||
// @returns The index to created/updated texture resources
|
// @returns The index to created/updated texture resources
|
||||||
TextureIndex CreateTextureResources(const FName& Name, UTexture2D* Texture, bool bMakeUnique = true);
|
TextureIndex CreateTextureResources(const FName& Name, UTexture2D* Texture);
|
||||||
|
|
||||||
// Release resources for given texture. Ignores invalid indices.
|
// Release resources for given texture. Ignores invalid indices.
|
||||||
// @param Index - The index of a texture resources
|
// @param Index - The index of a texture resources
|
||||||
@ -110,7 +105,7 @@ private:
|
|||||||
// @param Texture - The texture
|
// @param Texture - The texture
|
||||||
// @param bAddToRoot - If true, we should add texture to root to prevent garbage collection (use for own textures)
|
// @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
|
// @returns The index of the entry that we created or reused
|
||||||
TextureIndex AddTextureEntry(const FName& Name, UTexture2D* Texture, bool bAddToRoot, bool bUpdate);
|
TextureIndex 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).
|
// Check whether index is in range allocated for TextureResources (it doesn't mean that resources are valid).
|
||||||
FORCEINLINE bool IsInRange(TextureIndex Index) const
|
FORCEINLINE bool IsInRange(TextureIndex Index) const
|
||||||
|
@ -23,10 +23,10 @@ void SImGuiLayout::Construct(const FArguments& InArgs)
|
|||||||
if (ModuleManager)
|
if (ModuleManager)
|
||||||
{
|
{
|
||||||
auto& Settings = ModuleManager->GetSettings();
|
auto& Settings = ModuleManager->GetSettings();
|
||||||
SetDPIScale(Settings.GetDPIScale());
|
SetDPIScale(Settings.GetDPIScaleInfo());
|
||||||
if (!Settings.OnDPIScaleChangeDelegate.IsBoundToObject(this))
|
if (!Settings.OnDPIScaleChangedDelegate.IsBoundToObject(this))
|
||||||
{
|
{
|
||||||
Settings.OnDPIScaleChangeDelegate.AddRaw(this, &SImGuiLayout::SetDPIScale);
|
Settings.OnDPIScaleChangedDelegate.AddRaw(this, &SImGuiLayout::SetDPIScale);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -71,7 +71,7 @@ SImGuiLayout::~SImGuiLayout()
|
|||||||
{
|
{
|
||||||
if (ModuleManager)
|
if (ModuleManager)
|
||||||
{
|
{
|
||||||
ModuleManager->GetSettings().OnDPIScaleChangeDelegate.RemoveAll(this);
|
ModuleManager->GetSettings().OnDPIScaleChangedDelegate.RemoveAll(this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -31,8 +31,7 @@ public:
|
|||||||
private:
|
private:
|
||||||
|
|
||||||
float GetDPIScale() const { return DPIScale; }
|
float GetDPIScale() const { return DPIScale; }
|
||||||
void SetDPIScale(float Scale) { DPIScale = Scale; }
|
void SetDPIScale(const FImGuiDPIScaleInfo& ScaleInfo) { DPIScale = ScaleInfo.GetSlateScale(); }
|
||||||
|
|
||||||
|
|
||||||
FImGuiModuleManager* ModuleManager = nullptr;
|
FImGuiModuleManager* ModuleManager = nullptr;
|
||||||
TWeakObjectPtr<UGameViewportClient> GameViewport;
|
TWeakObjectPtr<UGameViewportClient> GameViewport;
|
||||||
|
@ -84,7 +84,7 @@ void SImGuiWidget::Construct(const FArguments& InArgs)
|
|||||||
const auto& Settings = ModuleManager->GetSettings();
|
const auto& Settings = ModuleManager->GetSettings();
|
||||||
SetHideMouseCursor(Settings.UseSoftwareCursor());
|
SetHideMouseCursor(Settings.UseSoftwareCursor());
|
||||||
CreateInputHandler(Settings.GetImGuiInputHandlerClass());
|
CreateInputHandler(Settings.GetImGuiInputHandlerClass());
|
||||||
SetDPIScale(Settings.GetDPIScale());
|
SetDPIScale(Settings.GetDPIScaleInfo());
|
||||||
SetCanvasSizeInfo(Settings.GetCanvasSizeInfo());
|
SetCanvasSizeInfo(Settings.GetCanvasSizeInfo());
|
||||||
|
|
||||||
// Initialize state.
|
// Initialize state.
|
||||||
@ -284,13 +284,13 @@ void SImGuiWidget::RegisterImGuiSettingsDelegates()
|
|||||||
{
|
{
|
||||||
Settings.OnUseSoftwareCursorChanged.AddRaw(this, &SImGuiWidget::SetHideMouseCursor);
|
Settings.OnUseSoftwareCursorChanged.AddRaw(this, &SImGuiWidget::SetHideMouseCursor);
|
||||||
}
|
}
|
||||||
if (!Settings.OnDPIScaleChangeDelegate.IsBoundToObject(this))
|
if (!Settings.OnDPIScaleChangedDelegate.IsBoundToObject(this))
|
||||||
{
|
{
|
||||||
Settings.OnDPIScaleChangeDelegate.AddRaw(this, &SImGuiWidget::SetDPIScale);
|
Settings.OnDPIScaleChangedDelegate.AddRaw(this, &SImGuiWidget::SetDPIScale);
|
||||||
}
|
}
|
||||||
if (!Settings.OnCanvasSizeInfoChangeDelegate.IsBoundToObject(this))
|
if (!Settings.OnCanvasSizeChangedDelegate.IsBoundToObject(this))
|
||||||
{
|
{
|
||||||
Settings.OnCanvasSizeInfoChangeDelegate.AddRaw(this, &SImGuiWidget::SetCanvasSizeInfo);
|
Settings.OnCanvasSizeChangedDelegate.AddRaw(this, &SImGuiWidget::SetCanvasSizeInfo);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -300,8 +300,8 @@ void SImGuiWidget::UnregisterImGuiSettingsDelegates()
|
|||||||
|
|
||||||
Settings.OnImGuiInputHandlerClassChanged.RemoveAll(this);
|
Settings.OnImGuiInputHandlerClassChanged.RemoveAll(this);
|
||||||
Settings.OnUseSoftwareCursorChanged.RemoveAll(this);
|
Settings.OnUseSoftwareCursorChanged.RemoveAll(this);
|
||||||
Settings.OnDPIScaleChangeDelegate.RemoveAll(this);
|
Settings.OnDPIScaleChangedDelegate.RemoveAll(this);
|
||||||
Settings.OnCanvasSizeInfoChangeDelegate.RemoveAll(this);
|
Settings.OnCanvasSizeChangedDelegate.RemoveAll(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SImGuiWidget::SetHideMouseCursor(bool bHide)
|
void SImGuiWidget::SetHideMouseCursor(bool bHide)
|
||||||
@ -509,8 +509,9 @@ void SImGuiWidget::HandleWindowFocusLost()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void SImGuiWidget::SetDPIScale(float Scale)
|
void SImGuiWidget::SetDPIScale(const FImGuiDPIScaleInfo& ScaleInfo)
|
||||||
{
|
{
|
||||||
|
const float Scale = ScaleInfo.GetSlateScale();
|
||||||
if (DPIScale != Scale)
|
if (DPIScale != Scale)
|
||||||
{
|
{
|
||||||
DPIScale = Scale;
|
DPIScale = Scale;
|
||||||
|
@ -103,7 +103,7 @@ private:
|
|||||||
void UpdateTransparentMouseInput(const FGeometry& AllottedGeometry);
|
void UpdateTransparentMouseInput(const FGeometry& AllottedGeometry);
|
||||||
void HandleWindowFocusLost();
|
void HandleWindowFocusLost();
|
||||||
|
|
||||||
void SetDPIScale(float Scale);
|
void SetDPIScale(const FImGuiDPIScaleInfo& ScaleInfo);
|
||||||
|
|
||||||
void SetCanvasSizeInfo(const FImGuiCanvasSizeInfo& CanvasSizeInfo);
|
void SetCanvasSizeInfo(const FImGuiCanvasSizeInfo& CanvasSizeInfo);
|
||||||
void UpdateCanvasSize();
|
void UpdateCanvasSize();
|
||||||
|
Loading…
Reference in New Issue
Block a user