Skip to content

Commit

Permalink
Upgraded to ImGui 1.61:
Browse files Browse the repository at this point in the history
- Upgraded ImGui framework to 1.61 WIP, which adds a few improvements to context management.
- Removed from plugin implementation all the references to default ImGui context.
- Removed from ImGui Context Proxy destructor code switching to default ImGui context (there is no default context and decision is left for a higher level manager when to switch and to what context).
- Added own font atlas that is shared by all contexts and used explicitly to create Slate resources.
- Removed from ImGui Context Proxy workaround that was previously needed for copying cursor data to dynamically created contexts.
- Removed explicit saving of context settings before its destruction as this is now handled in ImGui::DestroyContext().
- Reimplemented ImGuiImplementation::GetCursorData() to use new interface.
  • Loading branch information
segross committed May 9, 2018
1 parent fa32fd9 commit 413b4f4
Show file tree
Hide file tree
Showing 22 changed files with 7,064 additions and 2,727 deletions.
10 changes: 4 additions & 6 deletions Source/ImGui/Private/ImGuiContextManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -79,8 +79,6 @@ FImGuiContextManager::~FImGuiContextManager()
{
// Order matters because contexts can be created during World Tick Start events.
FWorldDelegates::OnWorldTickStart.RemoveAll(this);
Contexts.Empty();
ImGui::Shutdown();
}

void FImGuiContextManager::Tick(float DeltaSeconds)
Expand Down Expand Up @@ -118,7 +116,7 @@ FImGuiContextManager::FContextData& FImGuiContextManager::GetEditorContextData()

if (UNLIKELY(!Data))
{
Data = &Contexts.Emplace(Utilities::EDITOR_CONTEXT_INDEX, FContextData{ GetEditorContextName(), Utilities::EDITOR_CONTEXT_INDEX, DrawMultiContextEvent, ImGuiDemo, -1 });
Data = &Contexts.Emplace(Utilities::EDITOR_CONTEXT_INDEX, FContextData{ GetEditorContextName(), Utilities::EDITOR_CONTEXT_INDEX, DrawMultiContextEvent, FontAtlas, ImGuiDemo, -1 });
}

return *Data;
Expand All @@ -132,7 +130,7 @@ FImGuiContextManager::FContextData& FImGuiContextManager::GetStandaloneWorldCont

if (UNLIKELY(!Data))
{
Data = &Contexts.Emplace(Utilities::STANDALONE_GAME_CONTEXT_INDEX, FContextData{ GetWorldContextName(), Utilities::STANDALONE_GAME_CONTEXT_INDEX, DrawMultiContextEvent, ImGuiDemo });
Data = &Contexts.Emplace(Utilities::STANDALONE_GAME_CONTEXT_INDEX, FContextData{ GetWorldContextName(), Utilities::STANDALONE_GAME_CONTEXT_INDEX, DrawMultiContextEvent, FontAtlas, ImGuiDemo });
}

return *Data;
Expand Down Expand Up @@ -172,7 +170,7 @@ FImGuiContextManager::FContextData& FImGuiContextManager::GetWorldContextData(co
#if WITH_EDITOR
if (UNLIKELY(!Data))
{
Data = &Contexts.Emplace(Index, FContextData{ GetWorldContextName(World), Index, DrawMultiContextEvent, ImGuiDemo, WorldContext->PIEInstance });
Data = &Contexts.Emplace(Index, FContextData{ GetWorldContextName(World), Index, DrawMultiContextEvent, FontAtlas, ImGuiDemo, WorldContext->PIEInstance });
}
else
{
Expand All @@ -182,7 +180,7 @@ FImGuiContextManager::FContextData& FImGuiContextManager::GetWorldContextData(co
#else
if (UNLIKELY(!Data))
{
Data = &Contexts.Emplace(Index, FContextData{ GetWorldContextName(World), Index, DrawMultiContextEvent, ImGuiDemo });
Data = &Contexts.Emplace(Index, FContextData{ GetWorldContextName(World), Index, DrawMultiContextEvent, FontAtlas, ImGuiDemo });
}
#endif

Expand Down
14 changes: 10 additions & 4 deletions Source/ImGui/Private/ImGuiContextManager.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,10 @@ class FImGuiContextManager

~FImGuiContextManager();

ImFontAtlas& GetFontAtlas() { return FontAtlas; }
const ImFontAtlas& GetFontAtlas() const { return FontAtlas; }


#if WITH_EDITOR
// Get or create editor ImGui context proxy.
FORCEINLINE FImGuiContextProxy& GetEditorContextProxy() { return GetEditorContextData().ContextProxy; }
Expand Down Expand Up @@ -56,9 +60,9 @@ class FImGuiContextManager

struct FContextData
{
FContextData(const FString& ContextName, int32 ContextIndex, FSimpleMulticastDelegate& SharedDrawEvent, FImGuiDemo& Demo, int32 InPIEInstance = -1)
FContextData(const FString& ContextName, int32 ContextIndex, FSimpleMulticastDelegate& SharedDrawEvent, ImFontAtlas& FontAtlas, FImGuiDemo& Demo, int32 InPIEInstance = -1)
: PIEInstance(InPIEInstance)
, ContextProxy(ContextName, &SharedDrawEvent)
, ContextProxy(ContextName, &SharedDrawEvent, &FontAtlas)
{
ContextProxy.OnDraw().AddLambda([&Demo, ContextIndex]() { Demo.DrawControls(ContextIndex); });
}
Expand All @@ -73,8 +77,8 @@ class FImGuiContextManager

struct FContextData
{
FContextData(const FString& ContextName, int32 ContextIndex, FSimpleMulticastDelegate& SharedDrawEvent, FImGuiDemo& Demo)
: ContextProxy(ContextName, &SharedDrawEvent)
FContextData(const FString& ContextName, int32 ContextIndex, FSimpleMulticastDelegate& SharedDrawEvent, ImFontAtlas& FontAtlas, FImGuiDemo& Demo)
: ContextProxy(ContextName, &SharedDrawEvent, &FontAtlas)
{
ContextProxy.OnDraw().AddLambda([&Demo, ContextIndex]() { Demo.DrawControls(ContextIndex); });
}
Expand Down Expand Up @@ -103,4 +107,6 @@ class FImGuiContextManager
FImGuiDemo ImGuiDemo;

FSimpleMulticastDelegate DrawMultiContextEvent;

ImFontAtlas FontAtlas;
};
25 changes: 4 additions & 21 deletions Source/ImGui/Private/ImGuiContextProxy.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -44,13 +44,13 @@ namespace
}
}

FImGuiContextProxy::FImGuiContextProxy(const FString& InName, FSimpleMulticastDelegate* InSharedDrawEvent)
FImGuiContextProxy::FImGuiContextProxy(const FString& InName, FSimpleMulticastDelegate* InSharedDrawEvent, ImFontAtlas* InFontAtlas)
: Name(InName)
, SharedDrawEvent(InSharedDrawEvent)
, IniFilename(TCHAR_TO_ANSI(*GetIniFile(InName)))
{
// Create context.
Context = TUniquePtr<ImGuiContext>(ImGui::CreateContext());
Context = TUniquePtr<ImGuiContext>(ImGui::CreateContext(InFontAtlas));

// Set this context in ImGui for initialization (any allocations will be tracked in this context).
SetAsCurrent();
Expand All @@ -65,20 +65,6 @@ FImGuiContextProxy::FImGuiContextProxy(const FString& InName, FSimpleMulticastDe
IO.DisplaySize = { DEFAULT_CANVAS_WIDTH, DEFAULT_CANVAS_HEIGHT };
DisplaySize = ImGuiInterops::ToVector2D(IO.DisplaySize);

// When GetTexData is called for the first time it builds atlas texture and copies mouse cursor data to context.
// When multiple contexts share atlas then only the first one will get mouse data. A simple workaround is to use
// a temporary atlas if shared one is already built.
unsigned char* Pixels;
const bool bIsAltasBuilt = IO.Fonts->TexPixelsAlpha8 != nullptr;
if (bIsAltasBuilt)
{
ImFontAtlas().GetTexDataAsRGBA32(&Pixels, nullptr, nullptr);
}
else
{
IO.Fonts->GetTexDataAsRGBA32(&Pixels, nullptr, nullptr);
}

// Initialize key mapping, so context can correctly interpret input state.
ImGuiInterops::SetUnrealKeyMap(IO);

Expand All @@ -91,15 +77,12 @@ FImGuiContextProxy::~FImGuiContextProxy()
{
if (Context)
{
// Set this context in ImGui for de-initialization (any de-allocations will be tracked in this context).
// Setting this as a current context is still required in the current framework version to properly shutdown
// and save data.
SetAsCurrent();

// Save context data and destroy.
ImGuiImplementation::SaveCurrentContextIniSettings(IniFilename.c_str());
ImGui::DestroyContext(Context.Release());

// Set default context in ImGui to keep global context pointer valid.
ImGui::SetCurrentContext(&ImGuiImplementation::GetDefaultContext());
}
}

Expand Down
2 changes: 1 addition & 1 deletion Source/ImGui/Private/ImGuiContextProxy.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ class FImGuiContextProxy
{
public:

FImGuiContextProxy(const FString& Name, FSimpleMulticastDelegate* InSharedDrawEvent);
FImGuiContextProxy(const FString& Name, FSimpleMulticastDelegate* InSharedDrawEvent, ImFontAtlas* InFontAtlas);
~FImGuiContextProxy();

FImGuiContextProxy(const FImGuiContextProxy&) = delete;
Expand Down
29 changes: 9 additions & 20 deletions Source/ImGui/Private/ImGuiImplementation.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,29 +32,18 @@

namespace ImGuiImplementation
{
// This is exposing ImGui default context for the whole module.
// This is assuming that we don't define custom GImGui and therefore have GImDefaultContext defined in imgui.cpp.
ImGuiContext& GetDefaultContext()
bool GetCursorData(ImGuiMouseCursor CursorType, FVector2D& OutSize, FVector2D& OutUVMin, FVector2D& OutUVMax, FVector2D& OutOutlineUVMin, FVector2D& OutOutlineUVMax)
{
return GImDefaultContext;
}

void SaveCurrentContextIniSettings(const char* Filename)
{
SaveIniSettingsToDisk(Filename);
}

bool GetCursorData(int CursorType, FVector2D& OutSize, FVector2D& OutUVMin, FVector2D& OutUVMax, FVector2D& OutOutlineUVMin, FVector2D& OutOutlineUVMax)
{
if (static_cast<unsigned>(CursorType) < static_cast<unsigned>(ImGuiMouseCursor_Count_))
ImFontAtlas* FontAtlas = ImGui::GetIO().Fonts;
ImVec2 Offset, Size, UV[4];
if (FontAtlas && FontAtlas->GetMouseCursorTexData(CursorType, &Offset, &Size, &UV[0], &UV[2]))
{
using namespace ImGuiInterops;
ImGuiMouseCursorData& CursorData = GImGui->MouseCursorData[CursorType];
OutSize = ToVector2D(CursorData.Size);
OutUVMin = ToVector2D(CursorData.TexUvMin[0]);
OutUVMax = ToVector2D(CursorData.TexUvMax[0]);
OutOutlineUVMin = ToVector2D(CursorData.TexUvMin[1]);
OutOutlineUVMax = ToVector2D(CursorData.TexUvMax[1]);
OutSize = ToVector2D(Size);
OutUVMin = ToVector2D(UV[0]);
OutUVMax = ToVector2D(UV[1]);
OutOutlineUVMin = ToVector2D(UV[2]);
OutOutlineUVMax = ToVector2D(UV[3]);
return true;
}
else
Expand Down
8 changes: 1 addition & 7 deletions Source/ImGui/Private/ImGuiImplementation.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,6 @@
// Gives access to selected ImGui implementation features.
namespace ImGuiImplementation
{
// Get default context created by ImGui framework.
ImGuiContext& GetDefaultContext();

// Save current context settings.
void SaveCurrentContextIniSettings(const char* Filename);

// Get specific cursor data.
bool GetCursorData(int CursorType, FVector2D& OutSize, FVector2D& OutUVMin, FVector2D& OutUVMax, FVector2D& OutOutlineUVMin, FVector2D& OutOutlineUVMax);
bool GetCursorData(ImGuiMouseCursor CursorType, FVector2D& OutSize, FVector2D& OutUVMin, FVector2D& OutUVMax, FVector2D& OutOutlineUVMin, FVector2D& OutOutlineUVMax);
}
2 changes: 1 addition & 1 deletion Source/ImGui/Private/ImGuiInteroperability.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,7 @@ namespace ImGuiInterops
return EMouseCursor::Default;
case ImGuiMouseCursor_TextInput:
return EMouseCursor::TextEditBeam;
case ImGuiMouseCursor_Move:
case ImGuiMouseCursor_ResizeAll:
return EMouseCursor::CardinalCross;
case ImGuiMouseCursor_ResizeNS:
return EMouseCursor::ResizeUpDown;
Expand Down
7 changes: 3 additions & 4 deletions Source/ImGui/Private/ImGuiModuleManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -76,17 +76,16 @@ void FImGuiModuleManager::LoadTextures()
TextureManager.CreatePlainTexture(FName{ "ImGuiModule_Plain" }, 2, 2, FColor::White);

// Create a font atlas texture.
ImFontAtlas* Fonts = ImGui::GetIO().Fonts;
checkf(Fonts, TEXT("Invalid font atlas."));
ImFontAtlas& Fonts = ContextManager.GetFontAtlas();

unsigned char* Pixels;
int Width, Height, Bpp;
Fonts->GetTexDataAsRGBA32(&Pixels, &Width, &Height, &Bpp);
Fonts.GetTexDataAsRGBA32(&Pixels, &Width, &Height, &Bpp);

TextureIndex FontsTexureIndex = TextureManager.CreateTexture(FName{ "ImGuiModule_FontAtlas" }, Width, Height, Bpp, Pixels, false);

// Set font texture index in ImGui.
Fonts->TexID = ImGuiInterops::ToImTextureID(FontsTexureIndex);
Fonts.TexID = ImGuiInterops::ToImTextureID(FontsTexureIndex);
}

void FImGuiModuleManager::RegisterTick()
Expand Down
4 changes: 2 additions & 2 deletions Source/ImGui/Private/SImGuiWidget.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -692,7 +692,7 @@ bool SImGuiWidget::InFrameGrabbingRange(const FVector2D& Position, float Scale,

// Get the grab range based on cursor shape.
FVector2D Size, UVMin, UVMax, OutlineUVMin, OutlineUVMax;
const float Range = ImGuiImplementation::GetCursorData(ImGuiMouseCursor_Move, Size, UVMin, UVMax, OutlineUVMin, OutlineUVMax)
const float Range = ImGuiImplementation::GetCursorData(ImGuiMouseCursor_ResizeAll, Size, UVMin, UVMax, OutlineUVMin, OutlineUVMax)
? Size.GetMax() * 0.5f + 5.f : 25.f;

return (Position - ViewportCenter).GetAbsMax() <= Range;
Expand Down Expand Up @@ -887,7 +887,7 @@ int32 SImGuiWidget::OnPaint(const FPaintArgs& Args, const FGeometry& AllottedGeo

// Draw a movement gizmo (using ImGui move cursor).
FVector2D Size, UVMin, UVMax, OutlineUVMin, OutlineUVMax;
if (ImGuiImplementation::GetCursorData(ImGuiMouseCursor_Move, Size, UVMin, UVMax, OutlineUVMin, OutlineUVMax))
if (ImGuiImplementation::GetCursorData(ImGuiMouseCursor_ResizeAll, Size, UVMin, UVMax, OutlineUVMin, OutlineUVMax))
{
const TextureIndex FontAtlasIndex = ModuleManager->GetTextureManager().FindTextureIndex(FName{ FontAtlasTextureName });
if (FontAtlasIndex != INDEX_NONE)
Expand Down
Loading

0 comments on commit 413b4f4

Please sign in to comment.