├── .gitignore
├── Resources
└── Icon128.png
├── Source
├── ImGui
│ ├── Private
│ │ ├── Utilities
│ │ │ ├── DebugExecBindings.h
│ │ │ ├── WorldContext.cpp
│ │ │ ├── WorldContext.h
│ │ │ ├── WorldContextIndex.h
│ │ │ ├── Arrays.h
│ │ │ ├── RedirectingHandle.h
│ │ │ ├── DebugExecBindings.cpp
│ │ │ └── Range.h
│ │ ├── ImGuiImplementation.h
│ │ ├── ImGuiModuleDebug.h
│ │ ├── ImGuiInputHandlerFactory.h
│ │ ├── ImGuiDemo.h
│ │ ├── Editor
│ │ │ ├── ImGuiEditor.h
│ │ │ ├── ImGuiKeyInfoCustomization.h
│ │ │ ├── ImGuiCanvasSizeInfoCustomization.h
│ │ │ ├── ImGuiEditor.cpp
│ │ │ ├── ImGuiCanvasSizeInfoCustomization.cpp
│ │ │ └── ImGuiKeyInfoCustomization.cpp
│ │ ├── ImGuiTextureHandle.cpp
│ │ ├── ImGuiDelegates.cpp
│ │ ├── Widgets
│ │ │ ├── SImGuiLayout.h
│ │ │ ├── SImGuiLayout.cpp
│ │ │ ├── SImGuiCanvasControl.h
│ │ │ └── SImGuiWidget.h
│ │ ├── ImGuiInputHandlerFactory.cpp
│ │ ├── ImGuiModuleCommands.h
│ │ ├── ImGuiDelegatesContainer.h
│ │ ├── VersionCompatibility.h
│ │ ├── ImGuiImplementation.cpp
│ │ ├── ImGuiInputState.cpp
│ │ ├── ImGuiDelegatesContainer.cpp
│ │ ├── ImGuiDrawData.cpp
│ │ ├── ImGuiDrawData.h
│ │ ├── ImGuiDemo.cpp
│ │ ├── ImGuiModuleManager.h
│ │ ├── ImGuiModuleCommands.cpp
│ │ ├── ImGuiContextProxy.h
│ │ ├── ImGuiContextManager.h
│ │ ├── ImGuiInteroperability.h
│ │ ├── ImGuiModuleSettings.cpp
│ │ ├── TextureManager.cpp
│ │ ├── TextureManager.h
│ │ ├── ImGuiModuleManager.cpp
│ │ ├── ImGuiContextProxy.cpp
│ │ └── ImGuiInputState.h
│ ├── Public
│ │ ├── ImGuiTextureHandle.h
│ │ ├── ImGuiModuleProperties.h
│ │ ├── ImGuiDelegates.h
│ │ ├── ImGuiInputHandler.h
│ │ └── ImGuiModule.h
│ └── ImGui.Build.cs
└── ThirdParty
│ └── ImGuiLibrary
│ ├── ImGuiLibrary.Build.cs
│ ├── ImGuiLibrary.tps
│ ├── LICENSE.txt
│ ├── Docs
│ └── BACKENDS.md
│ └── Include
│ └── imconfig.h
├── ImGui.uplugin
├── LICENSE
├── CHANGES.md
└── README.md
/.gitignore:
--------------------------------------------------------------------------------
1 | /Binaries/
2 | /Intermediate/
3 |
--------------------------------------------------------------------------------
/Resources/Icon128.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/benui-dev/UnrealImGui/HEAD/Resources/Icon128.png
--------------------------------------------------------------------------------
/Source/ImGui/Private/Utilities/DebugExecBindings.h:
--------------------------------------------------------------------------------
1 | // Distributed under the MIT License (MIT) (see accompanying LICENSE file)
2 |
3 | #pragma once
4 |
5 | class FString;
6 | struct FImGuiKeyInfo;
7 |
8 | namespace DebugExecBindings
9 | {
10 | void UpdatePlayerInputs(const FImGuiKeyInfo& KeyInfo, const FString& Command);
11 | }
12 |
--------------------------------------------------------------------------------
/Source/ThirdParty/ImGuiLibrary/ImGuiLibrary.Build.cs:
--------------------------------------------------------------------------------
1 | using UnrealBuildTool;
2 |
3 | public class ImGuiLibrary : ModuleRules
4 | {
5 | #if WITH_FORWARDED_MODULE_RULES_CTOR
6 | public ImGuiLibrary(ReadOnlyTargetRules Target) : base(Target)
7 | #else
8 | public ImGuiLibrary(TargetInfo Target)
9 | #endif
10 | {
11 | Type = ModuleType.External;
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/Source/ThirdParty/ImGuiLibrary/ImGuiLibrary.tps:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Dear ImGui source files re-packaged to be included in Unreal Engine. Original Omar Cornut's repository can be found at https://github.com/ocornut/imgui.
5 |
6 |
7 |
--------------------------------------------------------------------------------
/Source/ImGui/Private/ImGuiImplementation.h:
--------------------------------------------------------------------------------
1 | // Distributed under the MIT License (MIT) (see accompanying LICENSE file)
2 |
3 | #pragma once
4 |
5 | struct FImGuiContextHandle;
6 |
7 | // Gives access to selected ImGui implementation features.
8 | namespace ImGuiImplementation
9 | {
10 | #if WITH_EDITOR
11 | // Get the handle to the ImGui Context pointer.
12 | FImGuiContextHandle& GetContextHandle();
13 |
14 | // Set the ImGui Context pointer handle.
15 | void SetParentContextHandle(FImGuiContextHandle& Parent);
16 | #endif // WITH_EDITOR
17 | }
18 |
--------------------------------------------------------------------------------
/Source/ImGui/Private/ImGuiModuleDebug.h:
--------------------------------------------------------------------------------
1 | // Distributed under the MIT License (MIT) (see accompanying LICENSE file)
2 |
3 | #pragma once
4 |
5 | #include
6 |
7 |
8 | // Module-wide debug symbols and loggers.
9 |
10 |
11 | // If enabled, it activates debug code and console variables that in normal usage are hidden.
12 | #define IMGUI_MODULE_DEVELOPER 0
13 |
14 |
15 | // Input Handler logger (used also in non-developer mode to raise problems with handler extensions).
16 | DECLARE_LOG_CATEGORY_EXTERN(LogImGuiInputHandler, Warning, All);
17 |
--------------------------------------------------------------------------------
/ImGui.uplugin:
--------------------------------------------------------------------------------
1 | {
2 | "FileVersion": 3,
3 | "Version": 1,
4 | "VersionName": "1.22",
5 | "FriendlyName": "ImGui",
6 | "Description": "",
7 | "Category": "Debug",
8 | "CreatedBy": "",
9 | "CreatedByURL": "",
10 | "DocsURL": "",
11 | "MarketplaceURL": "",
12 | "SupportURL": "",
13 | "CanContainContent": false,
14 | "IsBetaVersion": false,
15 | "Installed": false,
16 | "Modules": [
17 | {
18 | "Name": "ImGui",
19 | "Type": "DeveloperTool",
20 | "LoadingPhase": "PreDefault"
21 | }
22 | ],
23 | "Plugins": [
24 | {
25 | "Name": "EnhancedInput",
26 | "Enabled": true
27 | }
28 | ]
29 | }
--------------------------------------------------------------------------------
/Source/ImGui/Private/ImGuiInputHandlerFactory.h:
--------------------------------------------------------------------------------
1 | // Distributed under the MIT License (MIT) (see accompanying LICENSE file)
2 |
3 | #pragma once
4 |
5 | #include "ImGuiModuleSettings.h"
6 |
7 |
8 | class FImGuiModuleManager;
9 | class UGameViewportClient;
10 | class UImGuiInputHandler;
11 |
12 | class FImGuiInputHandlerFactory
13 | {
14 | public:
15 |
16 | static UImGuiInputHandler* NewHandler(const FSoftClassPath& HandlerClassReference, FImGuiModuleManager* ModuleManager, UGameViewportClient* GameViewport, int32 ContextIndex);
17 |
18 | static void ReleaseHandler(UImGuiInputHandler* Handler);
19 | };
20 |
--------------------------------------------------------------------------------
/Source/ImGui/Private/Utilities/WorldContext.cpp:
--------------------------------------------------------------------------------
1 | // Distributed under the MIT License (MIT) (see accompanying LICENSE file)
2 |
3 | #include "WorldContext.h"
4 |
5 |
6 | namespace Utilities
7 | {
8 | const FWorldContext* GetWorldContextFromNetMode(ENetMode NetMode)
9 | {
10 | checkf(GEngine, TEXT("GEngine required to get list of worlds."));
11 |
12 | for (const FWorldContext& WorldContext : GEngine->GetWorldContexts())
13 | {
14 | if (WorldContext.World() && WorldContext.World()->GetNetMode() == NetMode)
15 | {
16 | return &WorldContext;
17 | }
18 | }
19 |
20 | return nullptr;
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/Source/ImGui/Private/ImGuiDemo.h:
--------------------------------------------------------------------------------
1 | // Distributed under the MIT License (MIT) (see accompanying LICENSE file)
2 |
3 | #pragma once
4 |
5 | #include
6 |
7 | #include
8 |
9 | class FImGuiModuleProperties;
10 |
11 | // Widget drawing ImGui demo.
12 | class FImGuiDemo
13 | {
14 | public:
15 |
16 | FImGuiDemo(FImGuiModuleProperties& InProperties)
17 | : Properties(InProperties)
18 | {
19 | }
20 |
21 | void DrawControls(int32 ContextIndex);
22 |
23 | private:
24 |
25 | FImGuiModuleProperties& Properties;
26 |
27 | ImVec4 ClearColor = ImColor{ 114, 144, 154 };
28 |
29 | int32 ShowDemoWindowMask = 0;
30 | int32 ShowAnotherWindowMask = 0;
31 |
32 | int32 DemoWindowCounter = 0;
33 | uint32 LastDemoWindowFrameNumber = 0;
34 | };
35 |
--------------------------------------------------------------------------------
/Source/ImGui/Private/Editor/ImGuiEditor.h:
--------------------------------------------------------------------------------
1 | // Copyright 1998-2018 Epic Games, Inc. All Rights Reserved.
2 |
3 | #pragma once
4 |
5 | #if WITH_EDITOR
6 |
7 | #include
8 |
9 |
10 | // Registers module's settings in editor (due to a small size of this code we don't use a separate editor module).
11 | class FImGuiEditor
12 | {
13 | public:
14 |
15 | FImGuiEditor();
16 | ~FImGuiEditor();
17 |
18 | private:
19 |
20 | bool IsRegistrationCompleted() const { return bSettingsRegistered && bCustomPropertyTypeLayoutsRegistered; }
21 |
22 | void Register();
23 | void Unregister();
24 |
25 | void CreateRegistrator();
26 | void ReleaseRegistrator();
27 |
28 | FDelegateHandle RegistratorHandle;
29 |
30 | bool bSettingsRegistered = false;
31 | bool bCustomPropertyTypeLayoutsRegistered = false;
32 | };
33 |
34 | #endif // WITH_EDITOR
35 |
--------------------------------------------------------------------------------
/Source/ImGui/Private/Editor/ImGuiKeyInfoCustomization.h:
--------------------------------------------------------------------------------
1 | // Copyright 1998-2018 Epic Games, Inc. All Rights Reserved.
2 |
3 | #pragma once
4 |
5 | #if WITH_EDITOR
6 |
7 | #include
8 | #include
9 |
10 |
11 | // Property type customization for FImGuiKeyInfo.
12 | class FImGuiKeyInfoCustomization : public IPropertyTypeCustomization
13 | {
14 | public:
15 | static TSharedRef MakeInstance();
16 |
17 | // IPropertyTypeCustomization interface
18 | virtual void CustomizeHeader(TSharedRef InStructPropertyHandle, FDetailWidgetRow& HeaderRow, IPropertyTypeCustomizationUtils& StructCustomizationUtils) override;
19 | virtual void CustomizeChildren(TSharedRef InStructPropertyHandle, IDetailChildrenBuilder& StructBuilder, IPropertyTypeCustomizationUtils& StructCustomizationUtils) override;
20 | };
21 |
22 | #endif // WITH_EDITOR
23 |
--------------------------------------------------------------------------------
/Source/ImGui/Private/Editor/ImGuiCanvasSizeInfoCustomization.h:
--------------------------------------------------------------------------------
1 | // Copyright 1998-2018 Epic Games, Inc. All Rights Reserved.
2 |
3 | #pragma once
4 |
5 | #if WITH_EDITOR
6 |
7 | #include
8 | #include
9 |
10 |
11 | // Property type customization for FImGuiCanvasSizeInfo.
12 | class FImGuiCanvasSizeInfoCustomization : public IPropertyTypeCustomization
13 | {
14 | public:
15 | static TSharedRef MakeInstance();
16 |
17 | // IPropertyTypeCustomization interface
18 | virtual void CustomizeHeader(TSharedRef InStructPropertyHandle, FDetailWidgetRow& HeaderRow, IPropertyTypeCustomizationUtils& StructCustomizationUtils) override;
19 | virtual void CustomizeChildren(TSharedRef InStructPropertyHandle, IDetailChildrenBuilder& StructBuilder, IPropertyTypeCustomizationUtils& StructCustomizationUtils) override;
20 | };
21 |
22 | #endif // WITH_EDITOR
23 |
--------------------------------------------------------------------------------
/Source/ImGui/Private/ImGuiTextureHandle.cpp:
--------------------------------------------------------------------------------
1 | // Distributed under the MIT License (MIT) (see accompanying LICENSE file)
2 |
3 | #include "ImGuiTextureHandle.h"
4 |
5 | #include "ImGuiInteroperability.h"
6 |
7 |
8 | FImGuiTextureHandle::FImGuiTextureHandle()
9 | : FImGuiTextureHandle(NAME_None, ImGuiInterops::ToImTextureID(INDEX_NONE))
10 | {
11 | }
12 |
13 | FImGuiTextureHandle::FImGuiTextureHandle(const FName& InName, ImTextureID InTextureId)
14 | : Name(InName)
15 | , TextureId(InTextureId)
16 | {
17 | const TextureIndex Index = ImGuiInterops::ToTextureIndex(TextureId);
18 | checkf((Index == INDEX_NONE) == (Name == NAME_None),
19 | TEXT("Mismatch between Name and TextureId parameters, with only one indicating a null handle.")
20 | TEXT(" Name = '%s', TextureIndex(TextureId) = %d"), *Name.ToString(), Index);
21 | }
22 |
23 | // FImGuiTextureHandle::HasValidEntry() is implemented in ImGuiModule.cpp to get access to FImGuiModuleManager instance
24 | // without referencing in this class.
25 |
--------------------------------------------------------------------------------
/Source/ImGui/Private/ImGuiDelegates.cpp:
--------------------------------------------------------------------------------
1 | // Distributed under the MIT License (MIT) (see accompanying LICENSE file)
2 |
3 | #include "ImGuiDelegates.h"
4 | #include "ImGuiDelegatesContainer.h"
5 |
6 | #include
7 |
8 |
9 | FSimpleMulticastDelegate& FImGuiDelegates::OnWorldEarlyDebug()
10 | {
11 | return OnWorldEarlyDebug(GWorld);
12 | }
13 |
14 | FSimpleMulticastDelegate& FImGuiDelegates::OnWorldEarlyDebug(UWorld* World)
15 | {
16 | return FImGuiDelegatesContainer::Get().OnWorldEarlyDebug(World);
17 | }
18 |
19 | FSimpleMulticastDelegate& FImGuiDelegates::OnMultiContextEarlyDebug()
20 | {
21 | return FImGuiDelegatesContainer::Get().OnMultiContextEarlyDebug();
22 | }
23 |
24 | FSimpleMulticastDelegate& FImGuiDelegates::OnWorldDebug()
25 | {
26 | return OnWorldDebug(GWorld);
27 | }
28 |
29 | FSimpleMulticastDelegate& FImGuiDelegates::OnWorldDebug(UWorld* World)
30 | {
31 | return FImGuiDelegatesContainer::Get().OnWorldDebug(World);
32 | }
33 |
34 | FSimpleMulticastDelegate& FImGuiDelegates::OnMultiContextDebug()
35 | {
36 | return FImGuiDelegatesContainer::Get().OnMultiContextDebug();
37 | }
38 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2017-2021 Sebastian Gross
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/Source/ThirdParty/ImGuiLibrary/LICENSE.txt:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2014-2022 Omar Cornut
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/Source/ImGui/Private/Widgets/SImGuiLayout.h:
--------------------------------------------------------------------------------
1 | // Distributed under the MIT License (MIT) (see accompanying LICENSE file)
2 |
3 | #pragma once
4 |
5 | #include
6 | #include
7 | #include
8 |
9 |
10 | class FImGuiModuleManager;
11 | class UGameViewportClient;
12 | struct FImGuiDPIScaleInfo;
13 |
14 | // Layout preset for ImGui Widget.
15 | class SImGuiLayout : public SCompoundWidget
16 | {
17 | typedef SCompoundWidget Super;
18 |
19 | public:
20 |
21 | SLATE_BEGIN_ARGS(SImGuiLayout)
22 | {}
23 | SLATE_ARGUMENT(FImGuiModuleManager*, ModuleManager)
24 | SLATE_ARGUMENT(UGameViewportClient*, GameViewport)
25 | SLATE_ARGUMENT(int32, ContextIndex)
26 | SLATE_END_ARGS()
27 |
28 | void Construct(const FArguments& InArgs);
29 |
30 | ~SImGuiLayout();
31 |
32 | const TWeakObjectPtr& GetGameViewport() const { return GameViewport; }
33 |
34 | private:
35 |
36 | float GetDPIScale() const { return DPIScale; }
37 | void SetDPIScale(const FImGuiDPIScaleInfo& ScaleInfo);
38 |
39 | FImGuiModuleManager* ModuleManager = nullptr;
40 | TWeakObjectPtr GameViewport;
41 |
42 | float DPIScale = 1.f;
43 | };
44 |
--------------------------------------------------------------------------------
/Source/ImGui/Private/Utilities/WorldContext.h:
--------------------------------------------------------------------------------
1 | // Distributed under the MIT License (MIT) (see accompanying LICENSE file)
2 |
3 | #pragma once
4 |
5 | #include
6 | #include
7 | #include
8 | #include
9 |
10 |
11 | // Utilities helping to get a World Context.
12 |
13 | namespace Utilities
14 | {
15 | template
16 | FORCEINLINE const FWorldContext* GetWorldContext(const T* Obj);
17 |
18 | FORCEINLINE const FWorldContext* GetWorldContext(const UGameInstance& GameInstance)
19 | {
20 | return GameInstance.GetWorldContext();
21 | }
22 |
23 | template
24 | FORCEINLINE const FWorldContext* GetWorldContext(const TWeakObjectPtr& Obj)
25 | {
26 | return Obj.IsValid() ? GetWorldContext(*Obj.Get()) : nullptr;
27 | }
28 |
29 | FORCEINLINE const FWorldContext* GetWorldContext(const UGameViewportClient& GameViewportClient)
30 | {
31 | return GetWorldContext(GameViewportClient.GetGameInstance());
32 | }
33 |
34 | FORCEINLINE const FWorldContext* GetWorldContext(const UWorld& World)
35 | {
36 | return GetWorldContext(World.GetGameInstance());
37 | }
38 |
39 | template
40 | FORCEINLINE const FWorldContext* GetWorldContext(const T* Obj)
41 | {
42 | return Obj ? GetWorldContext(*Obj) : nullptr;
43 | }
44 |
45 | const FWorldContext* GetWorldContextFromNetMode(ENetMode NetMode);
46 | }
47 |
--------------------------------------------------------------------------------
/Source/ImGui/Private/ImGuiInputHandlerFactory.cpp:
--------------------------------------------------------------------------------
1 | // Distributed under the MIT License (MIT) (see accompanying LICENSE file)
2 |
3 | #include "ImGuiInputHandlerFactory.h"
4 | #include "ImGuiInputHandler.h"
5 |
6 | #include "ImGuiModuleDebug.h"
7 |
8 | #include
9 | #include
10 |
11 |
12 | UImGuiInputHandler* FImGuiInputHandlerFactory::NewHandler(const FSoftClassPath& HandlerClassReference, FImGuiModuleManager* ModuleManager, UGameViewportClient* GameViewport, int32 ContextIndex)
13 | {
14 | UClass* HandlerClass = nullptr;
15 | if (HandlerClassReference.IsValid())
16 | {
17 | HandlerClass = HandlerClassReference.TryLoadClass();
18 |
19 | if (!HandlerClass)
20 | {
21 | UE_LOG(LogImGuiInputHandler, Error, TEXT("Couldn't load ImGui Input Handler class '%s'."), *HandlerClassReference.ToString());
22 | }
23 | }
24 |
25 | if (!HandlerClass)
26 | {
27 | HandlerClass = UImGuiInputHandler::StaticClass();
28 | }
29 |
30 | UImGuiInputHandler* Handler = NewObject(GameViewport, HandlerClass);
31 | if (Handler)
32 | {
33 | Handler->Initialize(ModuleManager, GameViewport, ContextIndex);
34 | Handler->AddToRoot();
35 | }
36 | else
37 | {
38 | UE_LOG(LogImGuiInputHandler, Error, TEXT("Failed attempt to create Input Handler: HandlerClass = %s."), *GetNameSafe(HandlerClass));
39 | }
40 |
41 | return Handler;
42 | }
43 |
44 | void FImGuiInputHandlerFactory::ReleaseHandler(UImGuiInputHandler* Handler)
45 | {
46 | if (Handler)
47 | {
48 | Handler->RemoveFromRoot();
49 | }
50 | }
51 |
--------------------------------------------------------------------------------
/Source/ImGui/Private/ImGuiModuleCommands.h:
--------------------------------------------------------------------------------
1 | // Distributed under the MIT License (MIT) (see accompanying LICENSE file)
2 |
3 | #pragma once
4 |
5 | #include
6 |
7 |
8 | struct FImGuiKeyInfo;
9 | class FImGuiModuleProperties;
10 |
11 | // Manges ImGui module console commands.
12 | class FImGuiModuleCommands
13 | {
14 | public:
15 |
16 | static const TCHAR* const ToggleInput;
17 | static const TCHAR* const ToggleKeyboardNavigation;
18 | static const TCHAR* const ToggleGamepadNavigation;
19 | static const TCHAR* const ToggleKeyboardInputSharing;
20 | static const TCHAR* const ToggleGamepadInputSharing;
21 | static const TCHAR* const ToggleMouseInputSharing;
22 | static const TCHAR* const SetMouseInputSharing;
23 | static const TCHAR* const ToggleDemo;
24 |
25 | FImGuiModuleCommands(FImGuiModuleProperties& InProperties);
26 |
27 | void SetKeyBinding(const TCHAR* CommandName, const FImGuiKeyInfo& KeyInfo);
28 |
29 | private:
30 |
31 | void ToggleInputImpl();
32 | void ToggleKeyboardNavigationImpl();
33 | void ToggleGamepadNavigationImpl();
34 | void ToggleKeyboardInputSharingImpl();
35 | void ToggleGamepadInputSharingImpl();
36 | void ToggleMouseInputSharingImpl();
37 | void SetMouseInputSharingImpl(const TArray< FString >& Args);
38 | void ToggleDemoImpl();
39 |
40 | FImGuiModuleProperties& Properties;
41 |
42 | FAutoConsoleCommand ToggleInputCommand;
43 | FAutoConsoleCommand ToggleKeyboardNavigationCommand;
44 | FAutoConsoleCommand ToggleGamepadNavigationCommand;
45 | FAutoConsoleCommand ToggleKeyboardInputSharingCommand;
46 | FAutoConsoleCommand ToggleGamepadInputSharingCommand;
47 | FAutoConsoleCommand ToggleMouseInputSharingCommand;
48 | FAutoConsoleCommand SetMouseInputSharingCommand;
49 | FAutoConsoleCommand ToggleDemoCommand;
50 | };
51 |
--------------------------------------------------------------------------------
/Source/ImGui/Private/Utilities/WorldContextIndex.h:
--------------------------------------------------------------------------------
1 | // Distributed under the MIT License (MIT) (see accompanying LICENSE file)
2 |
3 | #pragma once
4 |
5 | #include "Utilities/WorldContext.h"
6 |
7 |
8 | // Utilities mapping worlds to indices that we use to identify ImGui contexts.
9 |
10 | namespace Utilities
11 | {
12 | // Invalid context index for parameters that cannot be resolved to a valid world.
13 | static constexpr int32 INVALID_CONTEXT_INDEX = -10;
14 |
15 | // Standalone context index.
16 | static constexpr int32 STANDALONE_GAME_CONTEXT_INDEX = -2;
17 |
18 | #if WITH_EDITOR
19 |
20 | // Editor context index. We are lacking flexibility here, so we might need to change it somehow.
21 | static constexpr int32 EDITOR_CONTEXT_INDEX = -1;
22 |
23 | FORCEINLINE int32 GetWorldContextIndex(const FWorldContext& WorldContext)
24 | {
25 | switch (WorldContext.WorldType)
26 | {
27 | case EWorldType::PIE:
28 | return WorldContext.PIEInstance;
29 | case EWorldType::Game:
30 | return STANDALONE_GAME_CONTEXT_INDEX;
31 | case EWorldType::Editor:
32 | return EDITOR_CONTEXT_INDEX;
33 | default:
34 | return INVALID_CONTEXT_INDEX;
35 | }
36 | }
37 |
38 | template
39 | FORCEINLINE int32 GetWorldContextIndex(const T& Obj)
40 | {
41 | const FWorldContext* WorldContext = GetWorldContext(Obj);
42 | return WorldContext ? GetWorldContextIndex(*WorldContext) : INVALID_CONTEXT_INDEX;
43 | }
44 |
45 | FORCEINLINE int32 GetWorldContextIndex(const UWorld& World)
46 | {
47 | return (World.WorldType == EWorldType::Editor) ? EDITOR_CONTEXT_INDEX : GetWorldContextIndex(World.GetGameInstance());
48 | }
49 |
50 | FORCEINLINE int32 GetWorldContextIndex(const UWorld* World)
51 | {
52 | return World ? GetWorldContextIndex(*World) : INVALID_CONTEXT_INDEX;
53 | }
54 |
55 | #else
56 |
57 | template
58 | constexpr int32 GetWorldContextIndex(const T&)
59 | {
60 | // The only option is standalone game with one context.
61 | return STANDALONE_GAME_CONTEXT_INDEX;
62 | }
63 |
64 | #endif // #if WITH_EDITOR
65 | }
66 |
--------------------------------------------------------------------------------
/Source/ImGui/Private/Utilities/Arrays.h:
--------------------------------------------------------------------------------
1 | // Distributed under the MIT License (MIT) (see accompanying LICENSE file)
2 |
3 | #pragma once
4 |
5 | #include "Range.h"
6 |
7 | #include
8 | #include
9 | #include
10 |
11 |
12 | // Utilities to work with one-dimensional, statically bound arrays. Code relying on those utilities should work without
13 | // modifications with fixed-sized arrays (currently used in ImGui) and with standard arrays.
14 |
15 | namespace Utilities
16 | {
17 | //====================================================================================================
18 | // Helper functions
19 | //====================================================================================================
20 |
21 | // Function to determine number of elements in fixed size array.
22 | template
23 | constexpr std::size_t GetArraySize(const T(&)[N])
24 | {
25 | return N;
26 | }
27 |
28 | // Function to determine number of elements in std array.
29 | template
30 | constexpr std::size_t GetArraySize(const std::array&)
31 | {
32 | return N;
33 | }
34 |
35 |
36 | //====================================================================================================
37 | // Traits
38 | //====================================================================================================
39 |
40 | template
41 | struct ArraySize;
42 |
43 | // Struct to determine number of elements in fixed size array.
44 | template
45 | struct ArraySize : std::extent
46 | {
47 | };
48 |
49 | // Struct to determine number of elements in std array.
50 | template
51 | struct ArraySize> : std::tuple_size>
52 | {
53 | };
54 |
55 |
56 | //====================================================================================================
57 | // Ranges
58 | //====================================================================================================
59 |
60 | // Array indices range. Limited by 0 and array size.
61 | template
62 | using TArrayIndexRange = TBoundedRange::value>;
63 | }
64 |
--------------------------------------------------------------------------------
/Source/ImGui/Private/ImGuiDelegatesContainer.h:
--------------------------------------------------------------------------------
1 | // Distributed under the MIT License (MIT) (see accompanying LICENSE file)
2 |
3 | #pragma once
4 |
5 | #include
6 | #include
7 |
8 |
9 | #if WITH_EDITOR
10 | struct FImGuiDelegatesContainerHandle;
11 | #endif
12 |
13 | struct FImGuiDelegatesContainer
14 | {
15 | public:
16 |
17 | // Get the current instance (can change during hot-reloading).
18 | static FImGuiDelegatesContainer& Get();
19 |
20 | #if WITH_EDITOR
21 | // Get the handle to the container instance (can attach to other handles in hot-reloaded modules).
22 | static FImGuiDelegatesContainerHandle& GetHandle();
23 |
24 | // Redirect to the other container and if this one is still active move its data to the other one.
25 | static void MoveContainer(FImGuiDelegatesContainerHandle& OtherContainerHandle);
26 | #endif
27 |
28 | // Get delegate to ImGui world early debug event from known world instance.
29 | FSimpleMulticastDelegate& OnWorldEarlyDebug(UWorld* World) { return OnWorldEarlyDebug(GetContextIndex(World)); }
30 |
31 | // Get delegate to ImGui world early debug event from known context index.
32 | FSimpleMulticastDelegate& OnWorldEarlyDebug(int32 ContextIndex) { return WorldEarlyDebugDelegates.FindOrAdd(ContextIndex); }
33 |
34 | // Get delegate to ImGui multi-context early debug event.
35 | FSimpleMulticastDelegate& OnMultiContextEarlyDebug() { return MultiContextEarlyDebugDelegate; }
36 |
37 | // Get delegate to ImGui world debug event from known world instance.
38 | FSimpleMulticastDelegate& OnWorldDebug(UWorld* World) { return OnWorldDebug(GetContextIndex(World)); }
39 |
40 | // Get delegate to ImGui world debug event from known context index.
41 | FSimpleMulticastDelegate& OnWorldDebug(int32 ContextIndex) { return WorldDebugDelegates.FindOrAdd(ContextIndex); }
42 |
43 | // Get delegate to ImGui multi-context debug event.
44 | FSimpleMulticastDelegate& OnMultiContextDebug() { return MultiContextDebugDelegate; }
45 |
46 | private:
47 |
48 | int32 GetContextIndex(UWorld* World);
49 |
50 | void Clear();
51 |
52 | TMap WorldEarlyDebugDelegates;
53 | TMap WorldDebugDelegates;
54 | FSimpleMulticastDelegate MultiContextEarlyDebugDelegate;
55 | FSimpleMulticastDelegate MultiContextDebugDelegate;
56 | };
57 |
--------------------------------------------------------------------------------
/Source/ImGui/Private/VersionCompatibility.h:
--------------------------------------------------------------------------------
1 | // Distributed under the MIT License (MIT) (see accompanying LICENSE file)
2 |
3 | #include
4 |
5 | #define BELOW_ENGINE_VERSION(Major, Minor) (ENGINE_MAJOR_VERSION < (Major) || (ENGINE_MAJOR_VERSION == (Major) && ENGINE_MINOR_VERSION < (Minor)))
6 | #define FROM_ENGINE_VERSION(Major, Minor) !BELOW_ENGINE_VERSION(Major, Minor)
7 |
8 |
9 | // One place to define compatibility with older engine versions.
10 |
11 |
12 | // Starting from version 4.17, Slate has an improved clipping API. Old version required to specify per-vertex clipping
13 | // rectangle and unofficial GSlateScissorRect to correctly clip custom vertices made with FSlateDrawElement.
14 | #define ENGINE_COMPATIBILITY_LEGACY_CLIPPING_API BELOW_ENGINE_VERSION(4, 17)
15 |
16 | // Starting from version 4.18, FPaths::GameSavedDir() has been superseded by FPaths::ProjectSavedDir().
17 | #define ENGINE_COMPATIBILITY_LEGACY_SAVED_DIR BELOW_ENGINE_VERSION(4, 18)
18 |
19 | // Starting from version 4.18, we have support for dual key bindings.
20 | #define ENGINE_COMPATIBILITY_SINGLE_KEY_BINDING BELOW_ENGINE_VERSION(4, 18)
21 |
22 | // Starting from version 4.18, FStringClassReference is replaced by FSoftClassPath. The new header contains a typedef
23 | // that renames FStringClassReference to FSoftClassPath, so it is still possible tu use the old type name in code.
24 | // The old header forwards to the new one but if used it outputs a warning, so we want to avoid it.
25 | #define ENGINE_COMPATIBILITY_LEGACY_STRING_CLASS_REF BELOW_ENGINE_VERSION(4, 18)
26 |
27 | // Starting from version 4.18, engine has a world post actor tick event which if available, provides a good opportunity
28 | // to call debug delegates after world actors are already updated.
29 | #define ENGINE_COMPATIBILITY_WITH_WORLD_POST_ACTOR_TICK FROM_ENGINE_VERSION(4, 18)
30 |
31 | // Starting from version 4.24, world actor tick event has additional world parameter.
32 | #define ENGINE_COMPATIBILITY_LEGACY_WORLD_ACTOR_TICK BELOW_ENGINE_VERSION(4, 24)
33 |
34 | // Starting from version 4.26, FKey::IsFloatAxis and FKey::IsVectorAxis are deprecated and replaced with FKey::IsAxis[1|2|3]D methods.
35 | #define ENGINE_COMPATIBILITY_LEGACY_KEY_AXIS_API BELOW_ENGINE_VERSION(4, 26)
36 |
37 | #define ENGINE_COMPATIBILITY_LEGACY_VECTOR2F BELOW_ENGINE_VERSION(5, 0)
38 |
--------------------------------------------------------------------------------
/Source/ImGui/Public/ImGuiTextureHandle.h:
--------------------------------------------------------------------------------
1 | // Distributed under the MIT License (MIT) (see accompanying LICENSE file)
2 |
3 | #pragma once
4 |
5 | #include
6 |
7 | #include
8 |
9 |
10 | /**
11 | * Handle to texture resources registered in module instance. Returned after successful texture registration.
12 | * Can be implicitly converted to ImTextureID making it possible to use it directly with ImGui interface.
13 | * Once texture is not needed handle can be used to release resources.
14 | */
15 | class IMGUI_API FImGuiTextureHandle
16 | {
17 | public:
18 |
19 | /** Creates an empty (null and not valid) texture handle. */
20 | FImGuiTextureHandle();
21 |
22 | /**
23 | * Checks whether this handle is null. Can be used as a quick test whether it points to any resources but it does
24 | * not check whether those resources are valid (see @ IsValid).
25 | *
26 | * @returns True, if this handle is null (Name is NAME_None and TextureId is invalid) and false otherwise.
27 | */
28 | bool IsNull() const { return Name == NAME_None; }
29 |
30 | /**
31 | * Checks whether this handle is not null and valid. Valid handle points to valid texture resources.
32 | * It is slower but safer test, more useful when there is no guarantee that resources haven't been released.
33 | *
34 | * @returns True, if this handle is not null and valid, false otherwise.
35 | */
36 | bool IsValid() const { return !IsNull() && HasValidEntry(); }
37 |
38 | /** Get the name of the texture resources (NAME_None if handle is null). */
39 | const FName& GetName() const { return Name; }
40 |
41 | /** Get the ImGui texture id for this texture (invalid if handle is null). */
42 | ImTextureID GetTextureId() const { return TextureId; }
43 |
44 | /** Implicit conversion to ImTextureID. */
45 | operator ImTextureID() const { return GetTextureId(); }
46 |
47 | private:
48 |
49 | /**
50 | * Creates a texture handle with known name and texture id.
51 | * @param InName - Name of the texture
52 | * @param InTextureId - ImGui id of texture
53 | */
54 | FImGuiTextureHandle(const FName& InName, ImTextureID InTextureId);
55 |
56 | /** Checks if texture manager has entry that matches this name and texture id index. */
57 | bool HasValidEntry() const;
58 |
59 | FName Name;
60 | ImTextureID TextureId;
61 |
62 | // Give module class a private access, so it can create valid handles.
63 | friend class FImGuiModule;
64 | };
65 |
--------------------------------------------------------------------------------
/Source/ImGui/Private/ImGuiImplementation.cpp:
--------------------------------------------------------------------------------
1 | // Distributed under the MIT License (MIT) (see accompanying LICENSE file)
2 |
3 | #include "ImGuiImplementation.h"
4 |
5 | #include
6 |
7 | // For convenience and easy access to the ImGui source code, we build it as part of this module.
8 | // We don't need to define IMGUI_API manually because it is already done for this module.
9 | // UE 5.1 stopped defining PLATFORM_XBOXONE, so be safe if not defined
10 | #if !defined(PLATFORM_XBOXONE)
11 | #define PLATFORM_XBOXONE 0
12 | #endif
13 | #if PLATFORM_XBOXONE
14 | // Disable Win32 functions used in ImGui and not supported on XBox.
15 | #define IMGUI_DISABLE_WIN32_DEFAULT_CLIPBOARD_FUNCTIONS
16 | #define IMGUI_DISABLE_WIN32_DEFAULT_IME_FUNCTIONS
17 | #endif // PLATFORM_XBOXONE
18 |
19 | #if PLATFORM_WINDOWS
20 | #include
21 | #endif // PLATFORM_WINDOWS
22 |
23 | #if WITH_EDITOR
24 |
25 | #include "ImGuiModule.h"
26 | #include "Utilities/RedirectingHandle.h"
27 |
28 | // Redirecting handle which will automatically bind to another one, if a different instance of the module is loaded.
29 | struct FImGuiContextHandle : public Utilities::TRedirectingHandle
30 | {
31 | FImGuiContextHandle(ImGuiContext*& InDefaultContext)
32 | : Utilities::TRedirectingHandle(InDefaultContext)
33 | {
34 | if (FImGuiModule* Module = FModuleManager::GetModulePtr("ImGui"))
35 | {
36 | SetParent(Module->ImGuiContextHandle);
37 | }
38 | }
39 | };
40 |
41 | static ImGuiContext* ImGuiContextPtr = nullptr;
42 | static FImGuiContextHandle ImGuiContextPtrHandle(ImGuiContextPtr);
43 |
44 | // Get the global ImGui context pointer (GImGui) indirectly to allow redirections in obsolete modules.
45 | #define GImGui (ImGuiContextPtrHandle.Get())
46 | #endif // WITH_EDITOR
47 |
48 | #include "imgui.cpp"
49 | #include "imgui_demo.cpp"
50 | #include "imgui_draw.cpp"
51 | #include "imgui_widgets.cpp"
52 |
53 | #include "imgui_tables.cpp"
54 |
55 | #if PLATFORM_WINDOWS
56 | #include
57 | #endif // PLATFORM_WINDOWS
58 |
59 | #include "ImGuiInteroperability.h"
60 |
61 |
62 | namespace ImGuiImplementation
63 | {
64 | #if WITH_EDITOR
65 | FImGuiContextHandle& GetContextHandle()
66 | {
67 | return ImGuiContextPtrHandle;
68 | }
69 |
70 | void SetParentContextHandle(FImGuiContextHandle& Parent)
71 | {
72 | ImGuiContextPtrHandle.SetParent(&Parent);
73 | }
74 | #endif // WITH_EDITOR
75 | }
76 |
--------------------------------------------------------------------------------
/Source/ImGui/Private/Widgets/SImGuiLayout.cpp:
--------------------------------------------------------------------------------
1 | // Distributed under the MIT License (MIT) (see accompanying LICENSE file)
2 |
3 | #include "SImGuiLayout.h"
4 | #include "SImGuiWidget.h"
5 |
6 | #include "ImGuiModuleManager.h"
7 | #include "ImGuiModuleSettings.h"
8 |
9 | #include
10 | #include
11 | #include
12 | #include
13 |
14 |
15 | BEGIN_SLATE_FUNCTION_BUILD_OPTIMIZATION
16 | void SImGuiLayout::Construct(const FArguments& InArgs)
17 | {
18 | checkf(InArgs._GameViewport, TEXT("Null Game Viewport argument"));
19 |
20 | ModuleManager = InArgs._ModuleManager;
21 | GameViewport = InArgs._GameViewport;
22 |
23 | if (ModuleManager)
24 | {
25 | auto& Settings = ModuleManager->GetSettings();
26 | SetDPIScale(Settings.GetDPIScaleInfo());
27 | if (!Settings.OnDPIScaleChangedDelegate.IsBoundToObject(this))
28 | {
29 | Settings.OnDPIScaleChangedDelegate.AddRaw(this, &SImGuiLayout::SetDPIScale);
30 | }
31 | }
32 |
33 | ChildSlot
34 | [
35 | // Remove accumulated scale to manually control how we draw data.
36 | SNew(SScaleBox)
37 | .IgnoreInheritedScale(true)
38 | .HAlign(HAlign_Fill)
39 | .VAlign(VAlign_Fill)
40 | .Visibility(EVisibility::SelfHitTestInvisible)
41 | [
42 | // Apply custom scale if needed.
43 | SNew(SDPIScaler)
44 | .DPIScale(TAttribute(this, &SImGuiLayout::GetDPIScale))
45 | .Visibility(EVisibility::SelfHitTestInvisible)
46 | [
47 | SNew(SConstraintCanvas)
48 | + SConstraintCanvas::Slot()
49 | .Anchors(FAnchors(0.f, 0.f, 1.f, 1.f))
50 | .AutoSize(true)
51 | .Offset(FMargin(1.f, 1.f, 0.f, 1.f))
52 | .Alignment(FVector2D::ZeroVector)
53 | [
54 | SNew(SImGuiWidget)
55 | .ModuleManager(InArgs._ModuleManager)
56 | .GameViewport(InArgs._GameViewport)
57 | .ContextIndex(InArgs._ContextIndex)
58 | #if !ENGINE_COMPATIBILITY_LEGACY_CLIPPING_API
59 | // To correctly clip borders. Using SScissorRectBox in older versions seems to be not necessary.
60 | .Clipping(EWidgetClipping::ClipToBounds)
61 | #endif
62 | ]
63 | ]
64 | ]
65 | ];
66 |
67 | SetVisibility(EVisibility::SelfHitTestInvisible);
68 | }
69 |
70 | SImGuiLayout::~SImGuiLayout()
71 | {
72 | if (ModuleManager)
73 | {
74 | ModuleManager->GetSettings().OnDPIScaleChangedDelegate.RemoveAll(this);
75 | }
76 | }
77 |
78 | END_SLATE_FUNCTION_BUILD_OPTIMIZATION
79 |
80 | void SImGuiLayout::SetDPIScale(const FImGuiDPIScaleInfo& ScaleInfo)
81 | {
82 | DPIScale = ScaleInfo.GetSlateScale();
83 | }
84 |
--------------------------------------------------------------------------------
/Source/ImGui/Private/Utilities/RedirectingHandle.h:
--------------------------------------------------------------------------------
1 | // Distributed under the MIT License (MIT) (see accompanying LICENSE file)
2 |
3 | #pragma once
4 |
5 | #include
6 | #include
7 |
8 |
9 | namespace Utilities
10 | {
11 | // Handle initialized as a pointer to a default value, but can be redirected to follow other handles.
12 | // When detached, it will revert to the default value. Intended for cross-module redirections.
13 | template
14 | struct TRedirectingHandle
15 | {
16 | TRedirectingHandle(T& InDefaultValue)
17 | : Handle(&InDefaultValue)
18 | , DefaultHandle(&InDefaultValue)
19 | {
20 | }
21 |
22 | ~TRedirectingHandle()
23 | {
24 | // Broadcast null pointer as a request to detach.
25 | OnRedirectionUpdate.Broadcast(nullptr);
26 | }
27 |
28 | // Check whether this handle points to the default value.
29 | bool IsDefault() const
30 | {
31 | return (Handle == DefaultHandle);
32 | }
33 |
34 | // Get the current value.
35 | T& Get() const
36 | {
37 | return *Handle;
38 | }
39 |
40 | // Set the other handle as a parent to this one. Passing null or itself will result with detaching from
41 | // the current parent (if any) and reverting back to the default value.
42 | void SetParent(TRedirectingHandle* InParent)
43 | {
44 | if (InParent != Parent)
45 | {
46 | if (Parent)
47 | {
48 | Parent->OnRedirectionUpdate.RemoveAll(this);
49 | }
50 |
51 | // Protecting from setting itself as a parent.
52 | Parent = (InParent != this) ? InParent : nullptr;
53 |
54 | if (Parent)
55 | {
56 | Parent->OnRedirectionUpdate.AddRaw(this, &TRedirectingHandle::UpdateRedirection);
57 | }
58 |
59 | SetHandle((Parent) ? Parent->Handle : DefaultHandle);
60 | }
61 | }
62 |
63 | protected:
64 |
65 | void UpdateRedirection(T* InHandle)
66 | {
67 | if (InHandle)
68 | {
69 | SetHandle(InHandle);
70 | }
71 | else
72 | {
73 | // Interpreting null as a signal to detach.
74 | SetParent(nullptr);
75 | }
76 | }
77 |
78 | void SetHandle(T* InHandle)
79 | {
80 | if (InHandle != Handle)
81 | {
82 | Handle = InHandle;
83 | OnRedirectionUpdate.Broadcast(Handle);
84 | }
85 | }
86 |
87 | T* Handle;
88 | T* DefaultHandle;
89 |
90 | TRedirectingHandle* Parent = nullptr;
91 |
92 | // Event with a new handle value or null pointer as a signal to detach.
93 | DECLARE_MULTICAST_DELEGATE_OneParam(FRedirectionUpdateDelegate, T*);
94 | FRedirectionUpdateDelegate OnRedirectionUpdate;
95 | };
96 | }
97 |
--------------------------------------------------------------------------------
/Source/ImGui/Private/ImGuiInputState.cpp:
--------------------------------------------------------------------------------
1 | // Distributed under the MIT License (MIT) (see accompanying LICENSE file)
2 |
3 | #include "ImGuiInputState.h"
4 |
5 | #include
6 | #include
7 | #include
8 |
9 |
10 | FImGuiInputState::FImGuiInputState()
11 | {
12 | Reset();
13 | }
14 |
15 | void FImGuiInputState::AddCharacter(TCHAR Char)
16 | {
17 | InputCharacters.Add(Char);
18 | }
19 |
20 | void FImGuiInputState::SetKeyDown(uint32 KeyIndex, bool bIsDown)
21 | {
22 | if (KeyIndex < Utilities::GetArraySize(KeysDown))
23 | {
24 | if (KeysDown[KeyIndex] != bIsDown)
25 | {
26 | KeysDown[KeyIndex] = bIsDown;
27 | KeysUpdateRange.AddPosition(KeyIndex);
28 | }
29 | }
30 | }
31 |
32 | void FImGuiInputState::SetMouseDown(uint32 MouseIndex, bool bIsDown)
33 | {
34 | if (MouseIndex < Utilities::GetArraySize(MouseButtonsDown))
35 | {
36 | if (MouseButtonsDown[MouseIndex] != bIsDown)
37 | {
38 | MouseButtonsDown[MouseIndex] = bIsDown;
39 | MouseButtonsUpdateRange.AddPosition(MouseIndex);
40 | }
41 | }
42 | }
43 |
44 | void FImGuiInputState::ClearUpdateState()
45 | {
46 | ClearCharacters();
47 |
48 | KeyDownEvents.Reset();
49 | KeyUpEvents.Reset();
50 |
51 | KeysUpdateRange.SetEmpty();
52 | MouseButtonsUpdateRange.SetEmpty();
53 |
54 | MouseWheelDelta = 0.f;
55 |
56 | bTouchProcessed = bTouchDown;
57 | }
58 |
59 | void FImGuiInputState::ClearCharacters()
60 | {
61 | InputCharacters.Empty();
62 | }
63 |
64 | void FImGuiInputState::ClearKeys()
65 | {
66 | using std::fill;
67 | fill(KeysDown, &KeysDown[Utilities::GetArraySize(KeysDown)], false);
68 |
69 | // Mark the whole array as dirty because potentially each entry could be affected.
70 | KeysUpdateRange.SetFull();
71 | }
72 |
73 | void FImGuiInputState::ClearMouseButtons()
74 | {
75 | using std::fill;
76 | fill(MouseButtonsDown, &MouseButtonsDown[Utilities::GetArraySize(MouseButtonsDown)], false);
77 |
78 | // Mark the whole array as dirty because potentially each entry could be affected.
79 | MouseButtonsUpdateRange.SetFull();
80 | }
81 |
82 | void FImGuiInputState::ClearMouseAnalogue()
83 | {
84 | MousePosition = FVector2D::ZeroVector;
85 | MouseWheelDelta = 0.f;
86 | }
87 |
88 | void FImGuiInputState::ClearModifierKeys()
89 | {
90 | bIsControlDown = false;
91 | bIsShiftDown = false;
92 | bIsAltDown = false;
93 | }
94 |
95 | void FImGuiInputState::ClearNavigationInputs()
96 | {
97 | using std::fill;
98 | fill(NavigationInputs, &NavigationInputs[Utilities::GetArraySize(NavigationInputs)], 0.f);
99 | }
100 |
101 |
--------------------------------------------------------------------------------
/Source/ImGui/Private/ImGuiDelegatesContainer.cpp:
--------------------------------------------------------------------------------
1 | // Distributed under the MIT License (MIT) (see accompanying LICENSE file)
2 |
3 | #include "ImGuiDelegatesContainer.h"
4 |
5 | #include "ImGuiModule.h"
6 | #include "Utilities/WorldContextIndex.h"
7 |
8 |
9 | #if !WITH_EDITOR
10 | //
11 | // Non-editor version without container redirection
12 | //
13 |
14 | FImGuiDelegatesContainer& FImGuiDelegatesContainer::Get()
15 | {
16 | static FImGuiDelegatesContainer* Container = new FImGuiDelegatesContainer();
17 | return *Container;
18 | }
19 |
20 | #endif // !WITH_EDITOR
21 |
22 |
23 | #if WITH_EDITOR
24 | //
25 | // Editor version supporting container redirection needed for hot-reloading
26 | //
27 |
28 | #include "Utilities/RedirectingHandle.h"
29 |
30 | // Redirecting handle which will always bind to a container from the currently loaded module.
31 | struct FImGuiDelegatesContainerHandle : Utilities::TRedirectingHandle
32 | {
33 | FImGuiDelegatesContainerHandle(FImGuiDelegatesContainer& InDefaultContainer)
34 | : Utilities::TRedirectingHandle(InDefaultContainer)
35 | {
36 | if (FImGuiModule* Module = FModuleManager::GetModulePtr("ImGui"))
37 | {
38 | SetParent(Module->DelegatesContainerHandle);
39 | }
40 | }
41 | };
42 |
43 | FImGuiDelegatesContainer& FImGuiDelegatesContainer::Get()
44 | {
45 | return GetHandle().Get();
46 | }
47 |
48 | FImGuiDelegatesContainerHandle& FImGuiDelegatesContainer::GetHandle()
49 | {
50 | struct FContainerInstance
51 | {
52 | FContainerInstance() : Container(), Handle(Container) {}
53 | FImGuiDelegatesContainer Container;
54 | FImGuiDelegatesContainerHandle Handle;
55 | };
56 | static FContainerInstance* Instance = new FContainerInstance();
57 | return Instance->Handle;
58 | }
59 |
60 | void FImGuiDelegatesContainer::MoveContainer(FImGuiDelegatesContainerHandle& OtherContainerHandle)
61 | {
62 | // Only move data if pointer points to default instance, otherwise our data has already been moved and we only
63 | // keep pointer to a more recent version.
64 | if (GetHandle().IsDefault())
65 | {
66 | OtherContainerHandle.Get() = MoveTemp(GetHandle().Get());
67 | GetHandle().Get().Clear();
68 | }
69 |
70 | // Update pointer to the most recent version.
71 | GetHandle().SetParent(&OtherContainerHandle);
72 | }
73 |
74 | #endif // WITH_EDITOR
75 |
76 |
77 | int32 FImGuiDelegatesContainer::GetContextIndex(UWorld* World)
78 | {
79 | return Utilities::GetWorldContextIndex(*World);
80 | }
81 |
82 | void FImGuiDelegatesContainer::Clear()
83 | {
84 | WorldEarlyDebugDelegates.Empty();
85 | WorldDebugDelegates.Empty();
86 | MultiContextEarlyDebugDelegate.Clear();
87 | MultiContextDebugDelegate.Clear();
88 | }
89 |
--------------------------------------------------------------------------------
/Source/ImGui/Private/ImGuiDrawData.cpp:
--------------------------------------------------------------------------------
1 | // Distributed under the MIT License (MIT) (see accompanying LICENSE file)
2 |
3 | #include "ImGuiDrawData.h"
4 |
5 |
6 | #if ENGINE_COMPATIBILITY_LEGACY_CLIPPING_API
7 | void FImGuiDrawList::CopyVertexData(TArray& OutVertexBuffer, const FTransform2D& Transform, const FSlateRotatedRect& VertexClippingRect) const
8 | #else
9 | void FImGuiDrawList::CopyVertexData(TArray& OutVertexBuffer, const FTransform2D& Transform) const
10 | #endif // ENGINE_COMPATIBILITY_LEGACY_CLIPPING_API
11 | {
12 | // Reset and reserve space in destination buffer.
13 | OutVertexBuffer.SetNumUninitialized(ImGuiVertexBuffer.Size, false);
14 |
15 | // Transform and copy vertex data.
16 | for (int Idx = 0; Idx < ImGuiVertexBuffer.Size; Idx++)
17 | {
18 | const ImDrawVert& ImGuiVertex = ImGuiVertexBuffer[Idx];
19 | FSlateVertex& SlateVertex = OutVertexBuffer[Idx];
20 |
21 | // Final UV is calculated in shader as XY * ZW, so we need set all components.
22 | SlateVertex.TexCoords[0] = ImGuiVertex.uv.x;
23 | SlateVertex.TexCoords[1] = ImGuiVertex.uv.y;
24 | SlateVertex.TexCoords[2] = SlateVertex.TexCoords[3] = 1.f;
25 |
26 | #if ENGINE_COMPATIBILITY_LEGACY_CLIPPING_API
27 | const FVector2D VertexPosition = Transform.TransformPoint(ImGuiInterops::ToVector2D(ImGuiVertex.pos));
28 | SlateVertex.Position[0] = VertexPosition.X;
29 | SlateVertex.Position[1] = VertexPosition.Y;
30 | SlateVertex.ClipRect = VertexClippingRect;
31 | #else
32 | #if ENGINE_COMPATIBILITY_LEGACY_VECTOR2F
33 | SlateVertex.Position = Transform.TransformPoint(ImGuiInterops::ToVector2D(ImGuiVertex.pos));
34 | #else
35 | SlateVertex.Position = (FVector2f)Transform.TransformPoint(ImGuiInterops::ToVector2D(ImGuiVertex.pos));
36 | #endif // ENGINE_COMPATIBILITY_LEGACY_VECTOR2F
37 | #endif // ENGINE_COMPATIBILITY_LEGACY_CLIPPING_API
38 |
39 | // Unpack ImU32 color.
40 | SlateVertex.Color = ImGuiInterops::UnpackImU32Color(ImGuiVertex.col);
41 | }
42 | }
43 |
44 | void FImGuiDrawList::CopyIndexData(TArray& OutIndexBuffer, const int32 StartIndex, const int32 NumElements) const
45 | {
46 | // Reset buffer.
47 | OutIndexBuffer.SetNumUninitialized(NumElements, false);
48 |
49 | // Copy elements (slow copy because of different sizes of ImDrawIdx and SlateIndex and because SlateIndex can
50 | // have different size on different platforms).
51 | for (int i = 0; i < NumElements; i++)
52 | {
53 | OutIndexBuffer[i] = ImGuiIndexBuffer[StartIndex + i];
54 | }
55 | }
56 |
57 | void FImGuiDrawList::TransferDrawData(ImDrawList& Src)
58 | {
59 | // Move data from source to this list.
60 | Src.CmdBuffer.swap(ImGuiCommandBuffer);
61 | Src.IdxBuffer.swap(ImGuiIndexBuffer);
62 | Src.VtxBuffer.swap(ImGuiVertexBuffer);
63 | }
64 |
--------------------------------------------------------------------------------
/Source/ImGui/ImGui.Build.cs:
--------------------------------------------------------------------------------
1 | // Distributed under the MIT License (MIT) (see accompanying LICENSE file)
2 |
3 | using System.Collections.Generic;
4 | using System.IO;
5 | using UnrealBuildTool;
6 |
7 | public class ImGui : ModuleRules
8 | {
9 | #if WITH_FORWARDED_MODULE_RULES_CTOR
10 | public ImGui(ReadOnlyTargetRules Target) : base(Target)
11 | #else
12 | public ImGui(TargetInfo Target)
13 | #endif
14 | {
15 |
16 | #if WITH_FORWARDED_MODULE_RULES_CTOR
17 | bool bBuildEditor = Target.bBuildEditor;
18 | #else
19 | bool bBuildEditor = (Target.Type == TargetRules.TargetType.Editor);
20 | #endif
21 |
22 | // Developer modules are automatically loaded only in editor builds but can be stripped out from other builds.
23 | // Enable runtime loader, if you want this module to be automatically loaded in runtime builds (monolithic).
24 | bool bEnableRuntimeLoader = true;
25 |
26 | PCHUsage = PCHUsageMode.UseExplicitOrSharedPCHs;
27 |
28 | #if UE_4_24_OR_LATER
29 | bLegacyPublicIncludePaths = false;
30 | ShadowVariableWarningLevel = WarningLevel.Error;
31 | bTreatAsEngineModule = true;
32 | #endif
33 |
34 | PublicIncludePaths.AddRange(
35 | new string[] {
36 | Path.Combine(ModuleDirectory, "../ThirdParty/ImGuiLibrary/Include"),
37 | // ... add public include paths required here ...
38 | }
39 | );
40 |
41 |
42 | PrivateIncludePaths.AddRange(
43 | new string[] {
44 | "ImGui/Private",
45 | "ThirdParty/ImGuiLibrary/Private",
46 | // ... add other private include paths required here ...
47 | }
48 | );
49 |
50 |
51 | PublicDependencyModuleNames.AddRange(
52 | new string[]
53 | {
54 | "Core",
55 | "Projects"
56 | // ... add other public dependencies that you statically link with here ...
57 | }
58 | );
59 |
60 |
61 | PrivateDependencyModuleNames.AddRange(
62 | new string[]
63 | {
64 | "CoreUObject",
65 | "EnhancedInput",
66 | "Engine",
67 | "InputCore",
68 | "Slate",
69 | "SlateCore"
70 | // ... add private dependencies that you statically link with here ...
71 | }
72 | );
73 |
74 |
75 | if (bBuildEditor)
76 | {
77 | PrivateDependencyModuleNames.AddRange(
78 | new string[]
79 | {
80 | "EditorStyle",
81 | "Settings",
82 | "UnrealEd",
83 | }
84 | );
85 | }
86 |
87 |
88 | DynamicallyLoadedModuleNames.AddRange(
89 | new string[]
90 | {
91 | // ... add any modules that your module loads dynamically here ...
92 | }
93 | );
94 |
95 |
96 | #if !UE_4_19_OR_LATER
97 | List PrivateDefinitions = Definitions;
98 | #endif
99 |
100 | PrivateDefinitions.Add(string.Format("RUNTIME_LOADER_ENABLED={0}", bEnableRuntimeLoader ? 1 : 0));
101 | }
102 | }
103 |
--------------------------------------------------------------------------------
/Source/ImGui/Private/ImGuiDrawData.h:
--------------------------------------------------------------------------------
1 | // Distributed under the MIT License (MIT) (see accompanying LICENSE file)
2 |
3 | #pragma once
4 |
5 | #include "ImGuiInteroperability.h"
6 | #include "VersionCompatibility.h"
7 |
8 | #include
9 |
10 | #include
11 |
12 |
13 | // ImGui draw command data transformed for Slate.
14 | struct FImGuiDrawCommand
15 | {
16 | uint32 NumElements;
17 | FSlateRect ClippingRect;
18 | TextureIndex TextureId;
19 | };
20 |
21 | // Wraps raw ImGui draw list data in utilities that transform them for Slate.
22 | class FImGuiDrawList
23 | {
24 | public:
25 |
26 | // Get the number of draw commands in this list.
27 | FORCEINLINE int NumCommands() const { return ImGuiCommandBuffer.Size; }
28 |
29 | // Get the draw command by number.
30 | // @param CommandNb - Number of draw command
31 | // @param Transform - Transform to apply to clipping rectangle
32 | // @returns Draw command data
33 | FImGuiDrawCommand GetCommand(int CommandNb, const FTransform2D& Transform) const
34 | {
35 | const ImDrawCmd& ImGuiCommand = ImGuiCommandBuffer[CommandNb];
36 | return { ImGuiCommand.ElemCount, TransformRect(Transform, ImGuiInterops::ToSlateRect(ImGuiCommand.ClipRect)),
37 | ImGuiInterops::ToTextureIndex(ImGuiCommand.TextureId) };
38 | }
39 |
40 | #if ENGINE_COMPATIBILITY_LEGACY_CLIPPING_API
41 | // Transform and copy vertex data to target buffer (old data in the target buffer are replaced).
42 | // @param OutVertexBuffer - Destination buffer
43 | // @param Transform - Transform to apply to all vertices
44 | // @param VertexClippingRect - Clipping rectangle for transformed Slate vertices
45 | void CopyVertexData(TArray& OutVertexBuffer, const FTransform2D& Transform, const FSlateRotatedRect& VertexClippingRect) const;
46 | #else
47 | // Transform and copy vertex data to target buffer (old data in the target buffer are replaced).
48 | // @param OutVertexBuffer - Destination buffer
49 | // @param Transform - Transform to apply to all vertices
50 | void CopyVertexData(TArray& OutVertexBuffer, const FTransform2D& Transform) const;
51 | #endif // ENGINE_COMPATIBILITY_LEGACY_CLIPPING_API
52 |
53 | // Transform and copy index data to target buffer (old data in the target buffer are replaced).
54 | // Internal index buffer contains enough data to match the sum of NumElements from all draw commands.
55 | // @param OutIndexBuffer - Destination buffer
56 | // @param StartIndex - Start copying source data starting from this index
57 | // @param NumElements - How many elements we want to copy
58 | void CopyIndexData(TArray& OutIndexBuffer, const int32 StartIndex, const int32 NumElements) const;
59 |
60 | // Transfers data from ImGui source list to this object. Leaves source cleared.
61 | void TransferDrawData(ImDrawList& Src);
62 |
63 | private:
64 |
65 | ImVector ImGuiCommandBuffer;
66 | ImVector ImGuiIndexBuffer;
67 | ImVector ImGuiVertexBuffer;
68 | };
69 |
--------------------------------------------------------------------------------
/Source/ImGui/Private/ImGuiDemo.cpp:
--------------------------------------------------------------------------------
1 | // Distributed under the MIT License (MIT) (see accompanying LICENSE file)
2 |
3 | #include "ImGuiDemo.h"
4 |
5 | #include "ImGuiModuleProperties.h"
6 |
7 | #include
8 |
9 |
10 | // Demo copied (with minor modifications) from ImGui examples. See https://github.com/ocornut/imgui.
11 | void FImGuiDemo::DrawControls(int32 ContextIndex)
12 | {
13 | if (Properties.ShowDemo())
14 | {
15 | const int32 ContextBit = ContextIndex < 0 ? 0 : 1 << ContextIndex;
16 |
17 | // 1. Show a simple window
18 | // Tip: if we don't call ImGui::Begin()/ImGui::End() the widgets appears in a window automatically called "Debug"
19 | {
20 | static float f = 0.0f;
21 | ImGui::Text("Hello, world!");
22 | ImGui::SliderFloat("float", &f, 0.0f, 1.0f);
23 | ImGui::ColorEdit3("clear color", (float*)&ClearColor);
24 |
25 | if (ContextBit)
26 | {
27 | if (ImGui::Button("Demo Window")) ShowDemoWindowMask ^= ContextBit;
28 | if (ImGui::Button("Another Window")) ShowAnotherWindowMask ^= ContextBit;
29 | }
30 | ImGui::Text("Application average %.3f ms/frame (%.1f FPS)", 1000.0f / ImGui::GetIO().Framerate, ImGui::GetIO().Framerate);
31 | }
32 |
33 | // 2. Show another simple window, this time using an explicit Begin/End pair
34 | if (ShowAnotherWindowMask & ContextBit)
35 | {
36 | ImGui::SetNextWindowSize(ImVec2(200, 100), ImGuiCond_FirstUseEver);
37 | ImGui::Begin("Another Window");
38 | ImGui::Text("Hello");
39 | ImGui::End();
40 | }
41 |
42 | // 3. Show the ImGui test window. Most of the sample code is in ImGui::ShowTestWindow()
43 | if (ShowDemoWindowMask & ContextBit)
44 | {
45 | // If more than one demo window is opened display warning about running ImGui examples in multiple contexts.
46 |
47 | // For everything, but the first windows in this frame we assume warning.
48 | bool bWarning = true;
49 | if (GFrameNumber > LastDemoWindowFrameNumber)
50 | {
51 | // If this is the first window in this frame, then we need to look at the last frame to see whether
52 | // there were more than one windows. Higher frame distance automatically means that there were not.
53 | bWarning = ((GFrameNumber - LastDemoWindowFrameNumber) == 1) && (DemoWindowCounter > 1);
54 |
55 | LastDemoWindowFrameNumber = GFrameNumber;
56 | DemoWindowCounter = 0;
57 | }
58 |
59 | DemoWindowCounter++;
60 |
61 | if (bWarning)
62 | {
63 | ImGui::Spacing();
64 |
65 | ImGui::PushStyleColor(ImGuiCol_Text, { 1.f, 1.f, 0.5f, 1.f });
66 | ImGui::TextWrapped("Demo Window is opened in more than one context, some of the ImGui examples may not work correctly.");
67 | ImGui::PopStyleColor();
68 |
69 | if (ImGui::IsItemHovered())
70 | {
71 | ImGui::SetTooltip(
72 | "Some of the ImGui examples that use static variables may not work correctly\n"
73 | "when run concurrently in multiple contexts.\n"
74 | "If you have a problem with an example try to run it in one context only.");
75 | }
76 | }
77 |
78 | // Draw demo window.
79 | ImGui::SetNextWindowPos(ImVec2(650, 20), ImGuiCond_FirstUseEver);
80 | ImGui::ShowDemoWindow();
81 | }
82 | }
83 | }
84 |
--------------------------------------------------------------------------------
/Source/ImGui/Private/ImGuiModuleManager.h:
--------------------------------------------------------------------------------
1 | // Distributed under the MIT License (MIT) (see accompanying LICENSE file)
2 |
3 | #pragma once
4 |
5 | #include "ImGuiContextManager.h"
6 | #include "ImGuiDemo.h"
7 | #include "ImGuiModuleCommands.h"
8 | #include "ImGuiModuleProperties.h"
9 | #include "ImGuiModuleSettings.h"
10 | #include "TextureManager.h"
11 | #include "Widgets/SImGuiLayout.h"
12 |
13 |
14 | // Central manager that implements module logic. It initializes and controls remaining module components.
15 | class FImGuiModuleManager
16 | {
17 | // Allow module to control life-cycle of this class.
18 | friend class FImGuiModule;
19 |
20 | public:
21 |
22 | // Get interface to module settings.
23 | FImGuiModuleSettings& GetSettings() { return Settings; }
24 |
25 | // Get interface to module state properties.
26 | FImGuiModuleProperties& GetProperties() { return Properties; }
27 |
28 | // Get ImGui contexts manager.
29 | FImGuiContextManager& GetContextManager() { return ContextManager; }
30 |
31 | // Get texture resources manager.
32 | FTextureManager& GetTextureManager() { return TextureManager; }
33 |
34 | // Event called right after ImGui is updated, to give other subsystems chance to react.
35 | FSimpleMulticastDelegate& OnPostImGuiUpdate() { return PostImGuiUpdateEvent; }
36 |
37 | void RebuildFontAtlas();
38 |
39 | private:
40 |
41 | FImGuiModuleManager();
42 | ~FImGuiModuleManager();
43 |
44 | FImGuiModuleManager(const FImGuiModuleManager&) = delete;
45 | FImGuiModuleManager& operator=(const FImGuiModuleManager&) = delete;
46 |
47 | FImGuiModuleManager(FImGuiModuleManager&&) = delete;
48 | FImGuiModuleManager& operator=(FImGuiModuleManager&&) = delete;
49 |
50 | void LoadTextures();
51 | void BuildFontAtlasTexture();
52 |
53 | bool IsTickRegistered() { return TickDelegateHandle.IsValid(); }
54 | void RegisterTick();
55 | void UnregisterTick();
56 |
57 | void CreateTickInitializer();
58 | void ReleaseTickInitializer();
59 |
60 | void Tick(float DeltaSeconds);
61 |
62 | void OnViewportCreated();
63 |
64 | void AddWidgetToViewport(UGameViewportClient* GameViewport);
65 | void AddWidgetsToActiveViewports();
66 |
67 | void OnContextProxyCreated(int32 ContextIndex, FImGuiContextProxy& ContextProxy);
68 |
69 | // Event that we call after ImGui is updated.
70 | FSimpleMulticastDelegate PostImGuiUpdateEvent;
71 |
72 | // Collection of module state properties.
73 | FImGuiModuleProperties Properties;
74 |
75 | // Tying module console commands to life-cycle of this manager and module.
76 | FImGuiModuleCommands Commands;
77 |
78 | // ImGui settings proxy (valid in every loading stage).
79 | FImGuiModuleSettings Settings;
80 |
81 | // Widget that we add to all created contexts to draw ImGui demo.
82 | FImGuiDemo ImGuiDemo;
83 |
84 | // Manager for ImGui contexts.
85 | FImGuiContextManager ContextManager;
86 |
87 | // Manager for textures resources.
88 | FTextureManager TextureManager;
89 |
90 | // Slate widgets that we created.
91 | TArray> Widgets;
92 |
93 | FDelegateHandle TickInitializerHandle;
94 | FDelegateHandle TickDelegateHandle;
95 | FDelegateHandle ViewportCreatedHandle;
96 |
97 | bool bTexturesLoaded = false;
98 | };
99 |
--------------------------------------------------------------------------------
/Source/ImGui/Private/Utilities/DebugExecBindings.cpp:
--------------------------------------------------------------------------------
1 | // Distributed under the MIT License (MIT) (see accompanying LICENSE file)
2 |
3 | #include "DebugExecBindings.h"
4 |
5 | #include "ImGuiModuleSettings.h"
6 |
7 | #include
8 | #include
9 |
10 | #include "EnhancedPlayerInput.h"
11 |
12 |
13 | namespace
14 | {
15 | FKeyBind CreateKeyBind(const FImGuiKeyInfo& KeyInfo, const FString& Command)
16 | {
17 | FKeyBind KeyBind;
18 | KeyBind.Command = Command;
19 | KeyBind.Key = KeyInfo.Key;
20 | KeyBind.bDisabled = false;
21 |
22 | #define FILL_MODIFIER_DATA(KeyInfoProperty, BindProperty, BindIgnoreProperty)\
23 | if (KeyInfo.KeyInfoProperty == ECheckBoxState::Undetermined)\
24 | {\
25 | KeyBind.BindProperty = KeyBind.BindIgnoreProperty = false;\
26 | }\
27 | else\
28 | {\
29 | KeyBind.BindProperty = (KeyInfo.KeyInfoProperty == ECheckBoxState::Checked);\
30 | KeyBind.BindIgnoreProperty = !KeyBind.BindProperty;\
31 | }
32 |
33 | FILL_MODIFIER_DATA(Shift, Shift, bIgnoreShift);
34 | FILL_MODIFIER_DATA(Ctrl, Control, bIgnoreCtrl);
35 | FILL_MODIFIER_DATA(Alt, Alt, bIgnoreAlt);
36 | FILL_MODIFIER_DATA(Cmd, Cmd, bIgnoreCmd);
37 |
38 | #undef FILL_MODIFIER_DATA
39 |
40 | return KeyBind;
41 | }
42 |
43 | bool IsBindable(const FKey& Key)
44 | {
45 | #if ENGINE_COMPATIBILITY_LEGACY_KEY_AXIS_API
46 | return Key.IsValid() && Key != EKeys::AnyKey && !Key.IsFloatAxis() && !Key.IsVectorAxis()
47 | && !Key.IsGamepadKey() && !Key.IsModifierKey() && !Key.IsMouseButton();
48 | #else
49 | return Key.IsValid() && Key != EKeys::AnyKey && !Key.IsAxis1D() && !Key.IsAxis2D()
50 | && !Key.IsAxis3D() && !Key.IsGamepadKey() && !Key.IsModifierKey() && !Key.IsMouseButton();
51 | #endif
52 | }
53 |
54 | void UpdatePlayerInput(UEnhancedPlayerInput* PlayerInput, const FKeyBind& KeyBind)
55 | {
56 | const int32 Index = PlayerInput->DebugExecBindings.IndexOfByPredicate([&](const FKeyBind& PlayerKeyBind)
57 | {
58 | return PlayerKeyBind.Command.Equals(KeyBind.Command, ESearchCase::IgnoreCase);
59 | });
60 |
61 | if (IsBindable(KeyBind.Key))
62 | {
63 | if (Index != INDEX_NONE)
64 | {
65 | PlayerInput->DebugExecBindings[Index] = KeyBind;
66 | }
67 | else
68 | {
69 | PlayerInput->DebugExecBindings.Add(KeyBind);
70 | }
71 | }
72 | else
73 | {
74 | if (Index != INDEX_NONE)
75 | {
76 | PlayerInput->DebugExecBindings.RemoveAt(Index);
77 | }
78 | }
79 | }
80 | }
81 |
82 | namespace DebugExecBindings
83 | {
84 | void UpdatePlayerInputs(const FImGuiKeyInfo& KeyInfo, const FString& Command)
85 | {
86 | checkf(!Command.IsEmpty(), TEXT("Empty command."));
87 |
88 | const FKeyBind KeyBind = CreateKeyBind(KeyInfo, Command);
89 |
90 | // Update default player input, so changes will be visible in all PIE sessions created after this point.
91 | if (UEnhancedPlayerInput* DefaultPlayerInput = GetMutableDefault())
92 | {
93 | UpdatePlayerInput(DefaultPlayerInput, KeyBind);
94 | }
95 |
96 | // Update all existing player inputs to see changes in running PIE session.
97 | for (TObjectIterator It; It; ++It)
98 | {
99 | UpdatePlayerInput(*It, KeyBind);
100 | }
101 | }
102 | }
103 |
--------------------------------------------------------------------------------
/Source/ImGui/Public/ImGuiModuleProperties.h:
--------------------------------------------------------------------------------
1 | // Distributed under the MIT License (MIT) (see accompanying LICENSE file)
2 |
3 | #pragma once
4 |
5 | struct ImFontConfig;
6 |
7 | /** Properties that define state of the ImGui module. */
8 | class IMGUI_API FImGuiModuleProperties
9 | {
10 | public:
11 |
12 | /** Check whether input is enabled. */
13 | bool IsInputEnabled() const { return bInputEnabled; }
14 |
15 | /** Enable or disable ImGui input. */
16 | void SetInputEnabled(bool bEnabled) { bInputEnabled = bEnabled; }
17 |
18 | /** Toggle ImGui input. */
19 | void ToggleInput() { SetInputEnabled(!IsInputEnabled()); }
20 |
21 | /** Check whether keyboard navigation is enabled. */
22 | bool IsKeyboardNavigationEnabled() const { return bKeyboardNavigationEnabled; }
23 |
24 | /** Enable or disable keyboard navigation. */
25 | void SetKeyboardNavigationEnabled(bool bEnabled) { bKeyboardNavigationEnabled = bEnabled; }
26 |
27 | /** Toggle keyboard navigation. */
28 | void ToggleKeyboardNavigation() { SetKeyboardNavigationEnabled(!IsKeyboardNavigationEnabled()); }
29 |
30 | /** Check whether gamepad navigation is enabled. */
31 | bool IsGamepadNavigationEnabled() const { return bGamepadNavigationEnabled; }
32 |
33 | /** Enable or disable gamepad navigation. */
34 | void SetGamepadNavigationEnabled(bool bEnabled) { bGamepadNavigationEnabled = bEnabled; }
35 |
36 | /** Toggle gamepad navigation. */
37 | void ToggleGamepadNavigation() { SetGamepadNavigationEnabled(!IsGamepadNavigationEnabled()); }
38 |
39 | /** Check whether keyboard input is shared with game. */
40 | bool IsKeyboardInputShared() const { return bKeyboardInputShared; }
41 |
42 | /** Set whether keyboard input should be shared with game. */
43 | void SetKeyboardInputShared(bool bShared) { bKeyboardInputShared = bShared; }
44 |
45 | /** Toggle whether keyboard input should be shared with game. */
46 | void ToggleKeyboardInputSharing() { SetKeyboardInputShared(!IsKeyboardInputShared()); }
47 |
48 | /** Check whether gamepad input is shared with game. */
49 | bool IsGamepadInputShared() const { return bGamepadInputShared; }
50 |
51 | /** Set whether gamepad input should be shared with game. */
52 | void SetGamepadInputShared(bool bShared) { bGamepadInputShared = bShared; }
53 |
54 | /** Toggle whether gamepad input should be shared with game. */
55 | void ToggleGamepadInputSharing() { SetGamepadInputShared(!IsGamepadInputShared()); }
56 |
57 | /** Check whether mouse input is shared with game. */
58 | bool IsMouseInputShared() const { return bMouseInputShared; }
59 |
60 | /** Set whether mouse input should be shared with game. */
61 | void SetMouseInputShared(bool bShared) { bMouseInputShared = bShared; }
62 |
63 | /** Toggle whether mouse input should be shared with game. */
64 | void ToggleMouseInputSharing() { SetMouseInputShared(!IsMouseInputShared()); }
65 |
66 | /** Check whether ImGui demo is visible. */
67 | bool ShowDemo() const { return bShowDemo; }
68 |
69 | /** Show or hide ImGui demo. */
70 | void SetShowDemo(bool bShow) { bShowDemo = bShow; }
71 |
72 | /** Toggle ImGui demo. */
73 | void ToggleDemo() { SetShowDemo(!ShowDemo()); }
74 |
75 | /** Adds a new font to initialize */
76 | void AddCustomFont(FName FontName, TSharedPtr Font) { CustomFonts.Emplace(FontName, Font); }
77 |
78 | /** Removes a font from the custom font list */
79 | void RemoveCustomFont(FName FontName) { CustomFonts.Remove(FontName); }
80 |
81 | /** Gets the map of registered custom fonts */
82 | TMap>& GetCustomFonts() { return CustomFonts; }
83 |
84 | private:
85 |
86 | bool bInputEnabled = false;
87 |
88 | bool bKeyboardNavigationEnabled = false;
89 | bool bGamepadNavigationEnabled = false;
90 |
91 | bool bKeyboardInputShared = false;
92 | bool bGamepadInputShared = false;
93 | bool bMouseInputShared = false;
94 |
95 | bool bShowDemo = false;
96 |
97 | TMap> CustomFonts;
98 | };
99 |
--------------------------------------------------------------------------------
/Source/ImGui/Private/Editor/ImGuiEditor.cpp:
--------------------------------------------------------------------------------
1 | // Distributed under the MIT License (MIT) (see accompanying LICENSE file)
2 |
3 | #include "ImGuiEditor.h"
4 |
5 | #if WITH_EDITOR
6 |
7 | #include "ImGuiCanvasSizeInfoCustomization.h"
8 | #include "ImGuiKeyInfoCustomization.h"
9 | #include "ImGuiModuleSettings.h"
10 |
11 | #include
12 | #include
13 |
14 |
15 | #define LOCTEXT_NAMESPACE "ImGuiEditor"
16 |
17 | #define SETTINGS_CONTAINER TEXT("Project"), TEXT("Plugins"), TEXT("ImGui")
18 |
19 |
20 | namespace
21 | {
22 | ISettingsModule* GetSettingsModule()
23 | {
24 | return FModuleManager::GetModulePtr("Settings");
25 | }
26 |
27 | FPropertyEditorModule* GetPropertyEditorModule()
28 | {
29 | return FModuleManager::GetModulePtr("PropertyEditor");
30 | }
31 | }
32 |
33 | FImGuiEditor::FImGuiEditor()
34 | {
35 | Register();
36 |
37 | // As a side effect of being part of the ImGui module, we need to support deferred registration (only executed if
38 | // module is loaded manually at the very early stage).
39 | if (!IsRegistrationCompleted())
40 | {
41 | CreateRegistrator();
42 | }
43 | }
44 |
45 | FImGuiEditor::~FImGuiEditor()
46 | {
47 | Unregister();
48 | }
49 |
50 | void FImGuiEditor::Register()
51 | {
52 | // Only register after UImGuiSettings class is initialized (necessary to check in early loading stages).
53 | if (!bSettingsRegistered && UImGuiSettings::Get())
54 | {
55 | if (ISettingsModule* SettingsModule = GetSettingsModule())
56 | {
57 | bSettingsRegistered = true;
58 |
59 | SettingsModule->RegisterSettings(SETTINGS_CONTAINER,
60 | LOCTEXT("ImGuiSettingsName", "ImGui"),
61 | LOCTEXT("ImGuiSettingsDescription", "Configure the Unreal ImGui plugin."),
62 | UImGuiSettings::Get());
63 | }
64 | }
65 |
66 | if (!bCustomPropertyTypeLayoutsRegistered)
67 | {
68 | if (FPropertyEditorModule* PropertyModule = GetPropertyEditorModule())
69 | {
70 | bCustomPropertyTypeLayoutsRegistered = true;
71 |
72 | PropertyModule->RegisterCustomPropertyTypeLayout("ImGuiCanvasSizeInfo",
73 | FOnGetPropertyTypeCustomizationInstance::CreateStatic(&FImGuiCanvasSizeInfoCustomization::MakeInstance));
74 | PropertyModule->RegisterCustomPropertyTypeLayout("ImGuiKeyInfo",
75 | FOnGetPropertyTypeCustomizationInstance::CreateStatic(&FImGuiKeyInfoCustomization::MakeInstance));
76 | }
77 | }
78 | }
79 |
80 | void FImGuiEditor::Unregister()
81 | {
82 | if (bSettingsRegistered)
83 | {
84 | bSettingsRegistered = false;
85 |
86 | if (ISettingsModule* SettingsModule = GetSettingsModule())
87 | {
88 | SettingsModule->UnregisterSettings(SETTINGS_CONTAINER);
89 | }
90 | }
91 |
92 | if (bCustomPropertyTypeLayoutsRegistered)
93 | {
94 | bCustomPropertyTypeLayoutsRegistered = false;
95 |
96 | if (FPropertyEditorModule* PropertyModule = GetPropertyEditorModule())
97 | {
98 | PropertyModule->UnregisterCustomPropertyTypeLayout("ImGuiCanvasSizeInfo");
99 | PropertyModule->UnregisterCustomPropertyTypeLayout("ImGuiKeyInfo");
100 | }
101 | }
102 | }
103 |
104 | void FImGuiEditor::CreateRegistrator()
105 | {
106 | if (!RegistratorHandle.IsValid())
107 | {
108 | RegistratorHandle = FModuleManager::Get().OnModulesChanged().AddLambda([this](FName Name, EModuleChangeReason Reason)
109 | {
110 | if (Reason == EModuleChangeReason::ModuleLoaded)
111 | {
112 | Register();
113 | }
114 |
115 | if (IsRegistrationCompleted())
116 | {
117 | ReleaseRegistrator();
118 | }
119 | });
120 | }
121 | }
122 |
123 | void FImGuiEditor::ReleaseRegistrator()
124 | {
125 | if (RegistratorHandle.IsValid())
126 | {
127 | FModuleManager::Get().OnModulesChanged().Remove(RegistratorHandle);
128 | RegistratorHandle.Reset();
129 | }
130 | }
131 |
132 |
133 | #undef SETTINGS_CONTAINER
134 | #undef LOCTEXT_NAMESPACE
135 |
136 | #endif // WITH_EDITOR
137 |
--------------------------------------------------------------------------------
/Source/ImGui/Private/ImGuiModuleCommands.cpp:
--------------------------------------------------------------------------------
1 | // Distributed under the MIT License (MIT) (see accompanying LICENSE file)
2 |
3 | #include "ImGuiModuleCommands.h"
4 |
5 | #include "ImGuiModuleProperties.h"
6 | #include "Utilities/DebugExecBindings.h"
7 |
8 |
9 | const TCHAR* const FImGuiModuleCommands::ToggleInput = TEXT("ImGui.ToggleInput");
10 | const TCHAR* const FImGuiModuleCommands::ToggleKeyboardNavigation = TEXT("ImGui.ToggleKeyboardNavigation");
11 | const TCHAR* const FImGuiModuleCommands::ToggleGamepadNavigation = TEXT("ImGui.ToggleGamepadNavigation");
12 | const TCHAR* const FImGuiModuleCommands::ToggleKeyboardInputSharing = TEXT("ImGui.ToggleKeyboardInputSharing");
13 | const TCHAR* const FImGuiModuleCommands::ToggleGamepadInputSharing = TEXT("ImGui.ToggleGamepadInputSharing");
14 | const TCHAR* const FImGuiModuleCommands::ToggleMouseInputSharing = TEXT("ImGui.ToggleMouseInputSharing");
15 | const TCHAR* const FImGuiModuleCommands::SetMouseInputSharing = TEXT("ImGui.SetMouseInputSharing");
16 | const TCHAR* const FImGuiModuleCommands::ToggleDemo = TEXT("ImGui.ToggleDemo");
17 |
18 | FImGuiModuleCommands::FImGuiModuleCommands(FImGuiModuleProperties& InProperties)
19 | : Properties(InProperties)
20 | , ToggleInputCommand(ToggleInput,
21 | TEXT("Toggle ImGui input mode."),
22 | FConsoleCommandDelegate::CreateRaw(this, &FImGuiModuleCommands::ToggleInputImpl))
23 | , ToggleKeyboardNavigationCommand(ToggleKeyboardNavigation,
24 | TEXT("Toggle ImGui keyboard navigation."),
25 | FConsoleCommandDelegate::CreateRaw(this, &FImGuiModuleCommands::ToggleKeyboardNavigationImpl))
26 | , ToggleGamepadNavigationCommand(ToggleGamepadNavigation,
27 | TEXT("Toggle ImGui gamepad navigation."),
28 | FConsoleCommandDelegate::CreateRaw(this, &FImGuiModuleCommands::ToggleGamepadNavigationImpl))
29 | , ToggleKeyboardInputSharingCommand(ToggleKeyboardInputSharing,
30 | TEXT("Toggle ImGui keyboard input sharing."),
31 | FConsoleCommandDelegate::CreateRaw(this, &FImGuiModuleCommands::ToggleKeyboardInputSharingImpl))
32 | , ToggleGamepadInputSharingCommand(ToggleGamepadInputSharing,
33 | TEXT("Toggle ImGui gamepad input sharing."),
34 | FConsoleCommandDelegate::CreateRaw(this, &FImGuiModuleCommands::ToggleGamepadInputSharingImpl))
35 | , ToggleMouseInputSharingCommand(ToggleMouseInputSharing,
36 | TEXT("Toggle ImGui mouse input sharing."),
37 | FConsoleCommandDelegate::CreateRaw(this, &FImGuiModuleCommands::ToggleMouseInputSharingImpl))
38 | , SetMouseInputSharingCommand(SetMouseInputSharing,
39 | TEXT("Toggle ImGui mouse input sharing."),
40 | FConsoleCommandWithArgsDelegate::CreateRaw(this, &FImGuiModuleCommands::SetMouseInputSharingImpl))
41 | , ToggleDemoCommand(ToggleDemo,
42 | TEXT("Toggle ImGui demo."),
43 | FConsoleCommandDelegate::CreateRaw(this, &FImGuiModuleCommands::ToggleDemoImpl))
44 | {
45 | }
46 |
47 | void FImGuiModuleCommands::SetKeyBinding(const TCHAR* CommandName, const FImGuiKeyInfo& KeyInfo)
48 | {
49 | DebugExecBindings::UpdatePlayerInputs(KeyInfo, CommandName);
50 | }
51 |
52 | void FImGuiModuleCommands::ToggleInputImpl()
53 | {
54 | Properties.ToggleInput();
55 | }
56 |
57 | void FImGuiModuleCommands::ToggleKeyboardNavigationImpl()
58 | {
59 | Properties.ToggleKeyboardNavigation();
60 | }
61 |
62 | void FImGuiModuleCommands::ToggleGamepadNavigationImpl()
63 | {
64 | Properties.ToggleGamepadNavigation();
65 | }
66 |
67 | void FImGuiModuleCommands::ToggleKeyboardInputSharingImpl()
68 | {
69 | Properties.ToggleKeyboardInputSharing();
70 | }
71 |
72 | void FImGuiModuleCommands::ToggleGamepadInputSharingImpl()
73 | {
74 | Properties.ToggleGamepadInputSharing();
75 | }
76 |
77 | void FImGuiModuleCommands::ToggleMouseInputSharingImpl()
78 | {
79 | Properties.ToggleMouseInputSharing();
80 | }
81 |
82 | void FImGuiModuleCommands::SetMouseInputSharingImpl(const TArray& Args)
83 | {
84 | bool bIsEnabled = false;
85 | if (Args.Num() > 0)
86 | {
87 | LexFromString(bIsEnabled, *Args[0]);
88 | }
89 | Properties.SetMouseInputShared(bIsEnabled);
90 | }
91 |
92 | void FImGuiModuleCommands::ToggleDemoImpl()
93 | {
94 | Properties.ToggleDemo();
95 | }
96 |
--------------------------------------------------------------------------------
/Source/ImGui/Public/ImGuiDelegates.h:
--------------------------------------------------------------------------------
1 | // Distributed under the MIT License (MIT) (see accompanying LICENSE file)
2 |
3 | #pragma once
4 |
5 | #include
6 |
7 |
8 | class UWorld;
9 |
10 | /**
11 | * Delegates to ImGui debug events. World delegates are called once per frame during world updates and have invocation
12 | * lists cleared after their worlds become invalid. Multi-context delegates are called once for every updated world.
13 | * Early debug delegates are called during world tick start and debug delegates are called during world post actor tick
14 | * or in engine versions below 4.18 during world tick start.
15 | *
16 | * Order of events is defined in a way that multi-context delegates can be used to draw headers and/or footers:
17 | * multi-context early debug, world early debug, world debug, multi-context debug.
18 | */
19 | class IMGUI_API FImGuiDelegates
20 | {
21 | public:
22 |
23 | /**
24 | * Get a delegate to ImGui world early debug event for current world (GWorld).
25 | * @returns Simple multicast delegate to debug events called once per frame to debug current world
26 | */
27 | static FSimpleMulticastDelegate& OnWorldEarlyDebug();
28 |
29 | /**
30 | * Get a delegate to ImGui world early debug event for given world.
31 | * @param World - World for which we need a delegate
32 | * @returns Simple multicast delegate to debug events called once per frame to debug given world
33 | */
34 | static FSimpleMulticastDelegate& OnWorldEarlyDebug(UWorld* World);
35 |
36 | /**
37 | * Get a delegate to ImGui multi-context early debug event.
38 | * @returns Simple multicast delegate to debug events called once per frame for every world to debug
39 | */
40 | static FSimpleMulticastDelegate& OnMultiContextEarlyDebug();
41 |
42 | /**
43 | * Get a delegate to ImGui world debug event for current world (GWorld).
44 | * @returns Simple multicast delegate to debug events called once per frame to debug current world
45 | */
46 | static FSimpleMulticastDelegate& OnWorldDebug();
47 |
48 | /**
49 | * Get a delegate to ImGui world debug event for given world.
50 | * @param World - World for which we need a delegate
51 | * @returns Simple multicast delegate to debug events called once per frame to debug given world
52 | */
53 | static FSimpleMulticastDelegate& OnWorldDebug(UWorld* World);
54 |
55 | /**
56 | * Get a delegate to ImGui multi-context debug event.
57 | * @returns Simple multicast delegate to debug events called once per frame for every world to debug
58 | */
59 | static FSimpleMulticastDelegate& OnMultiContextDebug();
60 | };
61 |
62 |
63 | /** Enable to support legacy ImGui delegates API. */
64 | #define IMGUI_WITH_OBSOLETE_DELEGATES 1
65 |
66 | #if IMGUI_WITH_OBSOLETE_DELEGATES
67 |
68 | /** Delegate that allows to subscribe for ImGui events. */
69 | typedef FSimpleMulticastDelegate::FDelegate FImGuiDelegate;
70 |
71 | /**
72 | * Handle to ImGui delegate. Contains additional information locating delegates in different contexts.
73 | */
74 | class FImGuiDelegateHandle
75 | {
76 | public:
77 |
78 | FImGuiDelegateHandle() = default;
79 |
80 | bool IsValid() const
81 | {
82 | return Handle.IsValid();
83 | }
84 |
85 | void Reset()
86 | {
87 | Handle.Reset();
88 | Index = 0;
89 | }
90 |
91 | private:
92 |
93 | FImGuiDelegateHandle(const FDelegateHandle& InHandle, int32 InCategory, int32 InIndex = 0)
94 | : Handle(InHandle)
95 | , Category(InCategory)
96 | , Index(InIndex)
97 | {
98 | }
99 |
100 | friend bool operator==(const FImGuiDelegateHandle& Lhs, const FImGuiDelegateHandle& Rhs)
101 | {
102 | return Lhs.Handle == Rhs.Handle && Lhs.Category == Rhs.Category && Lhs.Index == Rhs.Index;
103 | }
104 |
105 | friend bool operator!=(const FImGuiDelegateHandle& Lhs, const FImGuiDelegateHandle& Rhs)
106 | {
107 | return !(Lhs == Rhs);
108 | }
109 |
110 | FDelegateHandle Handle;
111 | int32 Category = 0;
112 | int32 Index = 0;
113 |
114 | friend class FImGuiModule;
115 | };
116 |
117 | #endif // IMGUI_WITH_OBSOLETE_DELEGATES
118 |
--------------------------------------------------------------------------------
/Source/ImGui/Private/ImGuiContextProxy.h:
--------------------------------------------------------------------------------
1 | // Distributed under the MIT License (MIT) (see accompanying LICENSE file)
2 |
3 | #pragma once
4 |
5 | #include "ImGuiDrawData.h"
6 | #include "ImGuiInputState.h"
7 | #include "Utilities/WorldContextIndex.h"
8 |
9 | #include
10 |
11 | #include
12 |
13 | #include
14 |
15 |
16 | // Represents a single ImGui context. All the context updates should be done through this proxy. During update it
17 | // broadcasts draw events to allow listeners draw their controls. After update it stores draw data.
18 | class FImGuiContextProxy
19 | {
20 | public:
21 |
22 | FImGuiContextProxy(const FString& Name, int32 InContextIndex, ImFontAtlas* InFontAtlas, float InDPIScale);
23 | ~FImGuiContextProxy();
24 |
25 | FImGuiContextProxy(const FImGuiContextProxy&) = delete;
26 | FImGuiContextProxy& operator=(const FImGuiContextProxy&) = delete;
27 |
28 | FImGuiContextProxy(FImGuiContextProxy&&) = delete;
29 | FImGuiContextProxy& operator=(FImGuiContextProxy&&) = delete;
30 |
31 | // Get the name of this context.
32 | const FString& GetName() const { return Name; }
33 |
34 | // Get draw data from the last frame.
35 | const TArray& GetDrawData() const { return DrawLists; }
36 |
37 | // Get input state used by this context.
38 | FImGuiInputState& GetInputState() { return InputState; }
39 | const FImGuiInputState& GetInputState() const { return InputState; }
40 |
41 | // Is this context the current ImGui context.
42 | bool IsCurrentContext() const { return ImGui::GetCurrentContext() == Context; }
43 |
44 | // Set this context as current ImGui context.
45 | void SetAsCurrent() { ImGui::SetCurrentContext(Context); }
46 |
47 | // Get the desired context display size.
48 | const FVector2D& GetDisplaySize() const { return DisplaySize; }
49 |
50 | // Set the desired context display size.
51 | void SetDisplaySize(const FVector2D& Size) { DisplaySize = Size; }
52 |
53 | // Reset the desired context display size to default size.
54 | void ResetDisplaySize();
55 |
56 | // Get the DPI scale set for this context.
57 | float GetDPIScale() const { return DPIScale; }
58 |
59 | // Set the DPI scale for this context.
60 | void SetDPIScale(float Scale);
61 |
62 | // Whether this context has an active item (read once per frame during context update).
63 | bool HasActiveItem() const { return bHasActiveItem; }
64 |
65 | // Whether ImGui will use the mouse inputs (read once per frame during context update).
66 | bool WantsMouseCapture() const { return bWantsMouseCapture; }
67 |
68 | // Cursor type desired by this context (updated once per frame during context update).
69 | EMouseCursor::Type GetMouseCursor() const { return MouseCursor; }
70 |
71 | // Internal draw event used to draw module's examples and debug widgets. Unlike the delegates container, it is not
72 | // passed when the module is reloaded, so all objects that are unloaded with the module should register here.
73 | FSimpleMulticastDelegate& OnDraw() { return DrawEvent; }
74 |
75 | // Call early debug events to allow listeners draw their debug widgets.
76 | void DrawEarlyDebug();
77 |
78 | // Call debug events to allow listeners draw their debug widgets.
79 | void DrawDebug();
80 |
81 | // Tick to advance context to the next frame. Only one call per frame will be processed.
82 | void Tick(float DeltaSeconds);
83 |
84 | private:
85 |
86 | void BeginFrame(float DeltaTime = 1.f / 60.f);
87 | void EndFrame();
88 |
89 | void UpdateDrawData(ImDrawData* DrawData);
90 |
91 | void BroadcastWorldEarlyDebug();
92 | void BroadcastMultiContextEarlyDebug();
93 |
94 | void BroadcastWorldDebug();
95 | void BroadcastMultiContextDebug();
96 |
97 | ImGuiContext* Context;
98 |
99 | FVector2D DisplaySize = FVector2D::ZeroVector;
100 | float DPIScale = 1.f;
101 |
102 | EMouseCursor::Type MouseCursor = EMouseCursor::None;
103 | bool bHasActiveItem = false;
104 | bool bWantsMouseCapture = false;
105 |
106 | bool bIsFrameStarted = false;
107 | bool bIsDrawEarlyDebugCalled = false;
108 | bool bIsDrawDebugCalled = false;
109 |
110 | FImGuiInputState InputState;
111 |
112 | TArray DrawLists;
113 |
114 | FString Name;
115 | int32 ContextIndex = Utilities::INVALID_CONTEXT_INDEX;
116 |
117 | uint32 LastFrameNumber = 0;
118 |
119 | FSimpleMulticastDelegate DrawEvent;
120 |
121 | std::string IniFilename;
122 | };
123 |
--------------------------------------------------------------------------------
/Source/ImGui/Private/Utilities/Range.h:
--------------------------------------------------------------------------------
1 | // Distributed under the MIT License (MIT) (see accompanying LICENSE file)
2 |
3 | #pragma once
4 |
5 | #include
6 |
7 |
8 | namespace Utilities
9 | {
10 | //====================================================================================================
11 | // Range
12 | //====================================================================================================
13 |
14 | template
15 | class TRange
16 | {
17 | public:
18 |
19 | TRange() {}
20 |
21 | TRange(const T& RangeBegin, const T& RangeEnd) { SetRange(RangeBegin, RangeEnd); }
22 |
23 | const T& GetBegin() const { return Begin; }
24 | const T& GetEnd() const { return End; }
25 |
26 | bool IsEmpty() const { return Begin == End; }
27 |
28 | void SetEmpty() { Begin = End = T(); }
29 |
30 | void SetRange(const T& RangeBegin, const T& RangeEnd)
31 | {
32 | checkf(RangeBegin <= RangeEnd, TEXT("Invalid arguments: RangeBegin > RangeEnd."));
33 | Begin = RangeBegin;
34 | End = RangeEnd;
35 | }
36 |
37 | void AddPosition(const T& Position)
38 | {
39 | AddRangeUnchecked(Position, Position + 1);
40 | }
41 |
42 | void AddRange(const T& RangeBegin, const T& RangeEnd)
43 | {
44 | checkf(RangeBegin <= RangeEnd, TEXT("Invalid arguments: RangeBegin > RangeEnd."));
45 | AddRangeUnchecked(RangeBegin, RangeEnd);
46 | }
47 |
48 | private:
49 |
50 | void AddRangeUnchecked(const T& RangeBegin, const T& RangeEnd)
51 | {
52 | if (IsEmpty())
53 | {
54 | Begin = RangeBegin;
55 | End = RangeEnd;
56 | }
57 | else
58 | {
59 | if (Begin > RangeBegin)
60 | {
61 | Begin = RangeBegin;
62 | }
63 |
64 | if (End < RangeEnd)
65 | {
66 | End = RangeEnd;
67 | }
68 | }
69 | }
70 |
71 | T Begin = T();
72 | T End = T();
73 | };
74 |
75 |
76 | // Enable range-based loops
77 |
78 | template
79 | const T& begin(const TRange& Range)
80 | {
81 | return Range.GetBegin();
82 | }
83 |
84 | template
85 | const T& end(const TRange& Range)
86 | {
87 | return Range.GetEnd();
88 | }
89 |
90 |
91 | //====================================================================================================
92 | // Bounded Range
93 | //====================================================================================================
94 |
95 | template
96 | class TBoundedRange
97 | {
98 | public:
99 |
100 | constexpr const T& GetLowerBound() const { return BeginBound; }
101 | constexpr const T& GetUpperBound() const { return EndBound; }
102 |
103 | const T& GetBegin() const { return Begin; }
104 | const T& GetEnd() const { return End; }
105 |
106 | bool IsEmpty() const { return Begin == End; }
107 |
108 | void SetEmpty() { Begin = End = BeginBound; }
109 |
110 | void SetFull()
111 | {
112 | Begin = BeginBound;
113 | End = EndBound;
114 | }
115 |
116 | void AddPosition(const T& Position)
117 | {
118 | checkf(Position >= BeginBound && Position < EndBound, TEXT("Position out of range."));
119 |
120 | AddRangeUnchecked(Position, Position + 1);
121 | }
122 |
123 | void AddRange(const T& RangeBegin, const T& RangeEnd)
124 | {
125 | checkf(RangeBegin <= RangeEnd, TEXT("Invalid arguments: RangeBegin > MaxPosition."));
126 | checkf(RangeBegin >= BeginBound, TEXT("RangeBegin out of range."));
127 | checkf(RangeBegin <= EndBound, TEXT("RangeEnd out of range."));
128 |
129 | AddRangeUnchecked(RangeBegin, RangeEnd);
130 | }
131 |
132 | private:
133 |
134 | void AddRangeUnchecked(const T& RangeBegin, const T& RangeEnd)
135 | {
136 | if (IsEmpty())
137 | {
138 | Begin = RangeBegin;
139 | End = RangeEnd;
140 | }
141 | else
142 | {
143 | if (Begin > RangeBegin)
144 | {
145 | Begin = RangeBegin;
146 | }
147 |
148 | if (End < RangeEnd)
149 | {
150 | End = RangeEnd;
151 | }
152 | }
153 | }
154 |
155 | T Begin = EndBound;
156 | T End = BeginBound;
157 | };
158 |
159 |
160 | // Enable range-based loops
161 |
162 | template
163 | const T& begin(const TBoundedRange& Range)
164 | {
165 | return Range.GetBegin();
166 | }
167 |
168 | template
169 | const T& end(const TBoundedRange& Range)
170 | {
171 | return Range.GetEnd();
172 | }
173 | }
174 |
--------------------------------------------------------------------------------
/Source/ImGui/Private/ImGuiContextManager.h:
--------------------------------------------------------------------------------
1 | // Distributed under the MIT License (MIT) (see accompanying LICENSE file)
2 |
3 | #pragma once
4 |
5 | #include "ImGuiContextProxy.h"
6 | #include "VersionCompatibility.h"
7 |
8 |
9 | class FImGuiModuleSettings;
10 | struct FImGuiDPIScaleInfo;
11 |
12 | // TODO: It might be useful to broadcast FContextProxyCreatedDelegate to users, to support similar cases to our ImGui
13 | // demo, but we would need to remove from that interface internal classes.
14 |
15 | // Delegate called when new context proxy is created.
16 | // @param ContextIndex - Index for that world
17 | // @param ContextProxy - Created context proxy
18 | DECLARE_MULTICAST_DELEGATE_TwoParams(FContextProxyCreatedDelegate, int32, FImGuiContextProxy&);
19 |
20 | // Manages ImGui context proxies.
21 | class FImGuiContextManager
22 | {
23 | public:
24 |
25 | FImGuiContextManager(FImGuiModuleSettings& InSettings);
26 |
27 | FImGuiContextManager(const FImGuiContextManager&) = delete;
28 | FImGuiContextManager& operator=(const FImGuiContextManager&) = delete;
29 |
30 | FImGuiContextManager(FImGuiContextManager&&) = delete;
31 | FImGuiContextManager& operator=(FImGuiContextManager&&) = delete;
32 |
33 | ~FImGuiContextManager();
34 |
35 | ImFontAtlas& GetFontAtlas() { return FontAtlas; }
36 | const ImFontAtlas& GetFontAtlas() const { return FontAtlas; }
37 |
38 | #if WITH_EDITOR
39 | // Get or create editor ImGui context proxy.
40 | FORCEINLINE FImGuiContextProxy& GetEditorContextProxy() { return *GetEditorContextData().ContextProxy; }
41 | #endif
42 |
43 | #if !WITH_EDITOR
44 | // Get or create standalone game ImGui context proxy.
45 | FORCEINLINE FImGuiContextProxy& GetWorldContextProxy() { return *GetStandaloneWorldContextData().ContextProxy; }
46 | #endif
47 |
48 | // Get or create ImGui context proxy for given world.
49 | FORCEINLINE FImGuiContextProxy& GetWorldContextProxy(const UWorld& World) { return *GetWorldContextData(World).ContextProxy; }
50 |
51 | // Get or create ImGui context proxy for given world. Additionally get context index for that proxy.
52 | FORCEINLINE FImGuiContextProxy& GetWorldContextProxy(const UWorld& World, int32& OutContextIndex) { return *GetWorldContextData(World, &OutContextIndex).ContextProxy; }
53 |
54 | // Get context proxy by index, or null if context with that index doesn't exist.
55 | FORCEINLINE FImGuiContextProxy* GetContextProxy(int32 ContextIndex)
56 | {
57 | FContextData* Data = Contexts.Find(ContextIndex);
58 | return Data ? Data->ContextProxy.Get() : nullptr;
59 | }
60 |
61 | // Delegate called when a new context proxy is created.
62 | FContextProxyCreatedDelegate OnContextProxyCreated;
63 |
64 | // Delegate called after font atlas is built.
65 | FSimpleMulticastDelegate OnFontAtlasBuilt;
66 |
67 | void Tick(float DeltaSeconds);
68 |
69 | void RebuildFontAtlas();
70 |
71 | private:
72 |
73 | struct FContextData
74 | {
75 | FContextData(const FString& ContextName, int32 ContextIndex, ImFontAtlas& FontAtlas, float DPIScale, int32 InPIEInstance = -1)
76 | : PIEInstance(InPIEInstance)
77 | , ContextProxy(new FImGuiContextProxy(ContextName, ContextIndex, &FontAtlas, DPIScale))
78 | {
79 | }
80 |
81 | FORCEINLINE bool CanTick() const { return PIEInstance < 0 || GEngine->GetWorldContextFromPIEInstance(PIEInstance); }
82 |
83 | int32 PIEInstance = -1;
84 | TUniquePtr ContextProxy;
85 | };
86 |
87 | #if ENGINE_COMPATIBILITY_LEGACY_WORLD_ACTOR_TICK
88 | void OnWorldTickStart(ELevelTick TickType, float DeltaSeconds);
89 | #endif
90 | void OnWorldTickStart(UWorld* World, ELevelTick TickType, float DeltaSeconds);
91 |
92 | #if ENGINE_COMPATIBILITY_WITH_WORLD_POST_ACTOR_TICK
93 | void OnWorldPostActorTick(UWorld* World, ELevelTick TickType, float DeltaSeconds);
94 | #endif
95 |
96 | #if WITH_EDITOR
97 | FContextData& GetEditorContextData();
98 | #endif
99 |
100 | #if !WITH_EDITOR
101 | FContextData& GetStandaloneWorldContextData();
102 | #endif
103 |
104 | FContextData& GetWorldContextData(const UWorld& World, int32* OutContextIndex = nullptr);
105 |
106 | void SetDPIScale(const FImGuiDPIScaleInfo& ScaleInfo);
107 | void BuildFontAtlas(const TMap>& CustomFontConfigs = {});
108 |
109 | TMap Contexts;
110 |
111 | ImFontAtlas FontAtlas;
112 | TArray> FontResourcesToRelease;
113 |
114 | FImGuiModuleSettings& Settings;
115 |
116 | float DPIScale = -1.f;
117 | int32 FontResourcesReleaseCountdown = 0;
118 | };
119 |
--------------------------------------------------------------------------------
/Source/ImGui/Private/Widgets/SImGuiCanvasControl.h:
--------------------------------------------------------------------------------
1 | // Distributed under the MIT License (MIT) (see accompanying LICENSE file)
2 |
3 | #pragma once
4 |
5 | #include "ImGuiInputState.h"
6 | #include "ImGuiModuleSettings.h"
7 |
8 | #include
9 | #include
10 | #include
11 |
12 |
13 | // Widget that controls transform of ImGui canvas/space.
14 | // When active, additionally it shows boundaries of ImGui canvas and default visible area.
15 | // TODO: Bind to ImGui context or properties to dynamically read canvas size.
16 | // TODO: Bind to properties to allow configure colors.
17 | class SImGuiCanvasControl : public SLeafWidget
18 | {
19 | typedef SLeafWidget Super;
20 |
21 | public:
22 |
23 | DECLARE_DELEGATE_OneParam(FOnTransformChanged, const FSlateRenderTransform&);
24 |
25 | SLATE_BEGIN_ARGS(SImGuiCanvasControl)
26 | {}
27 | SLATE_EVENT(FOnTransformChanged, OnTransformChanged)
28 | SLATE_END_ARGS()
29 |
30 | void Construct(const FArguments& InArgs);
31 |
32 | bool IsActive() const { return bActive; }
33 | void SetActive(bool bInActive);
34 |
35 | const FSlateRenderTransform& GetTransform() const { return Transform; }
36 |
37 | //----------------------------------------------------------------------------------------------------
38 | // SWidget overrides
39 | //----------------------------------------------------------------------------------------------------
40 |
41 | virtual void Tick(const FGeometry& AllottedGeometry, const double InCurrentTime, const float InDeltaTime) override;
42 |
43 | virtual FReply OnMouseButtonDown(const FGeometry& MyGeometry, const FPointerEvent& MouseEvent) override;
44 |
45 | virtual FReply OnMouseButtonUp(const FGeometry& MyGeometry, const FPointerEvent& MouseEvent) override;
46 |
47 | virtual FReply OnMouseWheel(const FGeometry& MyGeometry, const FPointerEvent& MouseEvent) override;
48 |
49 | virtual FReply OnDragDetected(const FGeometry& MyGeometry, const FPointerEvent& MouseEvent) override;
50 |
51 | virtual FReply OnDragOver(const FGeometry& MyGeometry, const FDragDropEvent& DragDropEvent) override;
52 |
53 | virtual FReply OnDrop(const FGeometry& MyGeometry, const FDragDropEvent& DragDropEvent) override;
54 |
55 | virtual FVector2D ComputeDesiredSize(float InScale) const override;
56 |
57 | virtual int32 OnPaint(const FPaintArgs& Args, const FGeometry& AllottedGeometry, const FSlateRect& MyCullingRect, FSlateWindowElementList& OutDrawElements, int32 LayerId, const FWidgetStyle& InWidgetStyle, bool bParentEnabled) const override;
58 |
59 | private:
60 |
61 | enum class EDragRequest : uint8
62 | {
63 | None,
64 | Content,
65 | Canvas
66 | };
67 |
68 | void UpdateVisibility();
69 |
70 | void Zoom(const FGeometry& MyGeometry, const float Delta, const FVector2D& MousePosition);
71 |
72 | void UpdateRenderTransform();
73 |
74 | float GetMinScale(const FGeometry& MyGeometry);
75 |
76 | mutable FSlateBorderBrush CanvasBorderBrush = FSlateBorderBrush("SImGuiCanvasControl-CanvasBorder", FMargin(0.f, 0.f, 1.f, 1.f), FLinearColor::White);
77 | mutable FSlateBorderBrush FrameBorderBrush = FSlateBorderBrush("SImGuiCanvasControl-FrameBorder", FMargin(0.f, 0.f, 1.f, 1.f), FLinearColor::White);
78 |
79 | FOnTransformChanged OnTransformChanged;
80 |
81 | // Transform from ImGui space.
82 | FSlateRenderTransform Transform;
83 |
84 | // Offset of the ImGui content in ImGui space.
85 | FVector2D ContentOffset = FVector2D::ZeroVector;
86 |
87 | // Offset of the ImGui canvas in widget local space.
88 | FVector2D CanvasOffset = FVector2D::ZeroVector;
89 |
90 | // Scale of the ImGui canvas in widget local space.
91 | float CanvasScale = 1.f;
92 |
93 | // Opacity scaling visibility of elements during blending.
94 | float Opacity = 1.f;
95 |
96 | // Whether this widget is active. While active, widget allows to modify transform of ImGui canvas, shows its
97 | // boundaries and default visible area.
98 | bool bActive = false;
99 |
100 | // Whether we are blending out after widget was deactivated. While blending out, widget is visible but it doesn't
101 | // process inputs anymore.
102 | bool bBlendingOut = false;
103 |
104 | // Request is set on mouse button press before drag operation is started. It remains valid until activating button
105 | // is released or until drag operation is finished or until it is replaced by alternative request.
106 | // Highlights are bound to requests, what means that they can also be activated before drag operation is started.
107 | EDragRequest DragRequest = EDragRequest::None;
108 | };
109 |
--------------------------------------------------------------------------------
/Source/ImGui/Private/ImGuiInteroperability.h:
--------------------------------------------------------------------------------
1 | // Distributed under the MIT License (MIT) (see accompanying LICENSE file)
2 |
3 | #pragma once
4 |
5 | #include "TextureManager.h"
6 |
7 | #include
8 | #include
9 |
10 | #include
11 |
12 |
13 | class FImGuiInputState;
14 |
15 | // Utilities to help standardise operations between Unreal and ImGui.
16 | namespace ImGuiInterops
17 | {
18 | //====================================================================================================
19 | // ImGui Types
20 | //====================================================================================================
21 |
22 | namespace ImGuiTypes
23 | {
24 | using FMouseButtonsArray = decltype(ImGuiIO::MouseDown);
25 | using FKeysArray = decltype(ImGuiIO::KeysDown);
26 | using FNavInputArray = decltype(ImGuiIO::NavInputs);
27 |
28 | using FKeyMap = decltype(ImGuiIO::KeyMap);
29 | }
30 |
31 |
32 | //====================================================================================================
33 | // Input Mapping
34 | //====================================================================================================
35 |
36 | // Set in ImGui IO mapping to recognize indices generated from Unreal input events.
37 | void SetUnrealKeyMap(ImGuiIO& IO);
38 |
39 | // Map FKey to index in keys buffer.
40 | uint32 GetKeyIndex(const FKey& Key);
41 |
42 | // Map key event to index in keys buffer.
43 | uint32 GetKeyIndex(const FKeyEvent& KeyEvent);
44 |
45 | // Map mouse FKey to index in mouse buttons buffer.
46 | uint32 GetMouseIndex(const FKey& MouseButton);
47 |
48 | // Map pointer event to index in mouse buttons buffer.
49 | FORCEINLINE uint32 GetMouseIndex(const FPointerEvent& MouseEvent)
50 | {
51 | return GetMouseIndex(MouseEvent.GetEffectingButton());
52 | }
53 |
54 | // Convert from ImGuiMouseCursor type to EMouseCursor.
55 | EMouseCursor::Type ToSlateMouseCursor(ImGuiMouseCursor MouseCursor);
56 |
57 | // Set in the target array navigation input corresponding to gamepad key.
58 | // @param NavInputs - Target array
59 | // @param Key - Gamepad key mapped to navigation input (non-mapped keys will be ignored)
60 | // @param bIsDown - True, if key is down
61 | void SetGamepadNavigationKey(ImGuiTypes::FNavInputArray& NavInputs, const FKey& Key, bool bIsDown);
62 |
63 | // Set in the target array navigation input corresponding to gamepad axis.
64 | // @param NavInputs - Target array
65 | // @param Key - Gamepad axis key mapped to navigation input (non-axis or non-mapped inputs will be ignored)
66 | // @param Value - Axis value (-1..1 values from Unreal are mapped to separate ImGui axes with values in range 0..1)
67 | void SetGamepadNavigationAxis(ImGuiTypes::FNavInputArray& NavInputs, const FKey& Key, float Value);
68 |
69 |
70 | //====================================================================================================
71 | // Input State Copying
72 | //====================================================================================================
73 |
74 | // Copy input to ImGui IO.
75 | // @param IO - Target ImGui IO
76 | // @param InputState - Input state to copy
77 | void CopyInput(ImGuiIO& IO, const FImGuiInputState& InputState);
78 |
79 |
80 | //====================================================================================================
81 | // Conversions
82 | //====================================================================================================
83 |
84 | // Convert from ImGui packed color to FColor.
85 | FORCEINLINE FColor UnpackImU32Color(ImU32 Color)
86 | {
87 | // We use IM_COL32_R/G/B/A_SHIFT macros to support different ImGui configurations.
88 | return FColor{ (uint8)((Color >> IM_COL32_R_SHIFT) & 0xFF), (uint8)((Color >> IM_COL32_G_SHIFT) & 0xFF),
89 | (uint8)((Color >> IM_COL32_B_SHIFT) & 0xFF), (uint8)((Color >> IM_COL32_A_SHIFT) & 0xFF) };
90 | }
91 |
92 | // Convert from ImVec4 rectangle to FSlateRect.
93 | FORCEINLINE FSlateRect ToSlateRect(const ImVec4& ImGuiRect)
94 | {
95 | return FSlateRect{ ImGuiRect.x, ImGuiRect.y, ImGuiRect.z, ImGuiRect.w };
96 | }
97 |
98 | // Convert from ImVec2 rectangle to FVector2D.
99 | FORCEINLINE FVector2D ToVector2D(const ImVec2& ImGuiVector)
100 | {
101 | return FVector2D{ ImGuiVector.x, ImGuiVector.y };
102 | }
103 |
104 | // Convert from ImGui Texture Id to Texture Index that we use for texture resources.
105 | FORCEINLINE TextureIndex ToTextureIndex(ImTextureID Index)
106 | {
107 | return static_cast(reinterpret_cast(Index));
108 | }
109 |
110 | // Convert from Texture Index to ImGui Texture Id that we pass to ImGui.
111 | FORCEINLINE ImTextureID ToImTextureID(TextureIndex Index)
112 | {
113 | return reinterpret_cast(static_cast(Index));
114 | }
115 | }
116 |
--------------------------------------------------------------------------------
/Source/ImGui/Private/Editor/ImGuiCanvasSizeInfoCustomization.cpp:
--------------------------------------------------------------------------------
1 | // Distributed under the MIT License (MIT) (see accompanying LICENSE file)
2 |
3 | #include "ImGuiCanvasSizeInfoCustomization.h"
4 |
5 | #if WITH_EDITOR
6 |
7 | #include "ImGuiModuleSettings.h"
8 |
9 | #include
10 |
11 |
12 | #define LOCTEXT_NAMESPACE "ImGuiEditor"
13 |
14 |
15 | namespace
16 | {
17 | EImGuiCanvasSizeType GetCanvasSizeTypeEnumValue(const TSharedPtr& TypeHandle)
18 | {
19 | uint8 ValueAsByte = 0;
20 | if (TypeHandle.IsValid())
21 | {
22 | TypeHandle->GetValue(ValueAsByte);
23 | }
24 | return static_cast(ValueAsByte);
25 | }
26 |
27 | bool IsAny(const TSharedPtr& TypeHandle, EImGuiCanvasSizeType Value)
28 | {
29 | return GetCanvasSizeTypeEnumValue(TypeHandle) == Value;
30 | }
31 |
32 | template
33 | bool IsAny(const TSharedPtr& TypeHandle, EImGuiCanvasSizeType First, TRest... Rest)
34 | {
35 | return IsAny(TypeHandle, First) || IsAny(TypeHandle, Rest...);
36 | }
37 |
38 | float ShowToHeight(bool bShow)
39 | {
40 | return bShow ? 0.f /* Infinity */ : SMALL_NUMBER;
41 | }
42 |
43 | EVisibility ShowToVisibility(bool bShow)
44 | {
45 | return bShow ? EVisibility::SelfHitTestInvisible : EVisibility::Hidden;
46 | }
47 | }
48 |
49 | //----------------------------------------------------------------------------------------------------
50 | // FImGuiKeyInfoCustomization implementation
51 | //----------------------------------------------------------------------------------------------------
52 |
53 | TSharedRef FImGuiCanvasSizeInfoCustomization::MakeInstance()
54 | {
55 | return MakeShareable(new FImGuiCanvasSizeInfoCustomization);
56 | }
57 |
58 | void FImGuiCanvasSizeInfoCustomization::CustomizeHeader(TSharedRef InStructPropertyHandle, FDetailWidgetRow& HeaderRow, IPropertyTypeCustomizationUtils& StructCustomizationUtils)
59 | {
60 | TSharedPtr TypeHandle = InStructPropertyHandle->GetChildHandle(GET_MEMBER_NAME_CHECKED(FImGuiCanvasSizeInfo, SizeType));
61 | TSharedPtr WidthHandle = InStructPropertyHandle->GetChildHandle(GET_MEMBER_NAME_CHECKED(FImGuiCanvasSizeInfo, Width));
62 | TSharedPtr HeightHandle = InStructPropertyHandle->GetChildHandle(GET_MEMBER_NAME_CHECKED(FImGuiCanvasSizeInfo, Height));
63 | TSharedPtr ExtendToViewportHandle = InStructPropertyHandle->GetChildHandle(GET_MEMBER_NAME_CHECKED(FImGuiCanvasSizeInfo, bExtendToViewport));
64 |
65 | #define ADD_DIMENSION_SLOT(Handle, LPadding) \
66 | + SHorizontalBox::Slot()\
67 | .Padding(LPadding, 0.f, 0.f, 0.f)\
68 | .HAlign(HAlign_Fill)\
69 | .MaxWidth(80.f)\
70 | [\
71 | SNew(SVerticalBox)\
72 | + SVerticalBox::Slot()\
73 | .AutoHeight()\
74 | [\
75 | Handle->CreatePropertyNameWidget()\
76 | ]\
77 | + SVerticalBox::Slot()\
78 | .HAlign(HAlign_Fill)\
79 | .AutoHeight()\
80 | [\
81 | Handle->CreatePropertyValueWidget()\
82 | ]\
83 | ]
84 |
85 | auto SizeRowHeight = TAttribute::Create([TypeHandle]()
86 | {
87 | return ShowToHeight(IsAny(TypeHandle, EImGuiCanvasSizeType::Custom));
88 | });
89 |
90 | auto SizeRowVisibility = TAttribute::Create([TypeHandle]()
91 | {
92 | return ShowToVisibility(IsAny(TypeHandle, EImGuiCanvasSizeType::Custom));
93 | });
94 |
95 | auto ExtendRowHeight = TAttribute::Create([TypeHandle]()
96 | {
97 | return ShowToHeight(IsAny(TypeHandle, EImGuiCanvasSizeType::Custom, EImGuiCanvasSizeType::Desktop));
98 | });
99 |
100 | auto ExtendRowVisibility = TAttribute::Create([TypeHandle]()
101 | {
102 | return ShowToVisibility(IsAny(TypeHandle, EImGuiCanvasSizeType::Custom, EImGuiCanvasSizeType::Desktop));
103 | });
104 |
105 | HeaderRow
106 | .NameContent()
107 | [
108 | InStructPropertyHandle->CreatePropertyNameWidget()
109 | ]
110 | .ValueContent()
111 | .MinDesiredWidth(168.f)
112 | [
113 | SNew(SVerticalBox)
114 | + SVerticalBox::Slot()
115 | .AutoHeight()
116 | [
117 | TypeHandle->CreatePropertyValueWidget()
118 | ]
119 | + SVerticalBox::Slot()
120 | .AutoHeight()
121 | .MaxHeight(SizeRowHeight)
122 | [
123 | SNew(SHorizontalBox)
124 | .Visibility(SizeRowVisibility)
125 | ADD_DIMENSION_SLOT(WidthHandle, 0.f)
126 | ADD_DIMENSION_SLOT(HeightHandle, 6.f)
127 | ]
128 | + SVerticalBox::Slot()
129 | .AutoHeight()
130 | .MaxHeight(ExtendRowHeight)
131 | [
132 | SNew(SHorizontalBox)
133 | .Visibility(ExtendRowVisibility)
134 | + SHorizontalBox::Slot()
135 | .AutoWidth()
136 | [
137 | ExtendToViewportHandle->CreatePropertyValueWidget()
138 | ]
139 | + SHorizontalBox::Slot()
140 | .Padding(4.f, 0.f, 0.f, 0.f)
141 | .AutoWidth()
142 | [
143 | ExtendToViewportHandle->CreatePropertyNameWidget()
144 | ]
145 | ]
146 | ];
147 |
148 | #undef ADD_DIMENSION_SLOT
149 | }
150 |
151 | void FImGuiCanvasSizeInfoCustomization::CustomizeChildren(TSharedRef InStructPropertyHandle, IDetailChildrenBuilder& StructBuilder, IPropertyTypeCustomizationUtils& StructCustomizationUtils)
152 | {
153 | }
154 |
155 |
156 | #undef LOCTEXT_NAMESPACE
157 |
158 | #endif // WITH_EDITOR
159 |
--------------------------------------------------------------------------------
/Source/ImGui/Private/Widgets/SImGuiWidget.h:
--------------------------------------------------------------------------------
1 | // Distributed under the MIT License (MIT) (see accompanying LICENSE file)
2 |
3 | #pragma once
4 |
5 | #include "ImGuiModuleDebug.h"
6 | #include "ImGuiModuleSettings.h"
7 |
8 | #include
9 | #include
10 | #include
11 | #include
12 |
13 |
14 | // Hide ImGui Widget debug in non-developer mode.
15 | #define IMGUI_WIDGET_DEBUG IMGUI_MODULE_DEVELOPER
16 |
17 | class FImGuiModuleManager;
18 | class SImGuiCanvasControl;
19 | class UImGuiInputHandler;
20 |
21 | class UGameViewportClient;
22 | class ULocalPlayer;
23 |
24 | // Slate widget for rendering ImGui output and storing Slate inputs.
25 | class SImGuiWidget : public SCompoundWidget
26 | {
27 | typedef SCompoundWidget Super;
28 |
29 | public:
30 |
31 | SLATE_BEGIN_ARGS(SImGuiWidget)
32 | {}
33 | SLATE_ARGUMENT(FImGuiModuleManager*, ModuleManager)
34 | SLATE_ARGUMENT(UGameViewportClient*, GameViewport)
35 | SLATE_ARGUMENT(int32, ContextIndex)
36 | SLATE_END_ARGS()
37 |
38 | void Construct(const FArguments& InArgs);
39 |
40 | ~SImGuiWidget();
41 |
42 | // Get index of the context that this widget is targeting.
43 | int32 GetContextIndex() const { return ContextIndex; }
44 |
45 | //----------------------------------------------------------------------------------------------------
46 | // SWidget overrides
47 | //----------------------------------------------------------------------------------------------------
48 |
49 | virtual void Tick(const FGeometry& AllottedGeometry, const double InCurrentTime, const float InDeltaTime) override;
50 |
51 | virtual bool SupportsKeyboardFocus() const override { return bInputEnabled && !IsConsoleOpened(); }
52 |
53 | virtual FReply OnKeyChar(const FGeometry& MyGeometry, const FCharacterEvent& CharacterEvent) override;
54 |
55 | virtual FReply OnKeyDown(const FGeometry& MyGeometry, const FKeyEvent& KeyEvent) override;
56 |
57 | virtual FReply OnKeyUp(const FGeometry& MyGeometry, const FKeyEvent& KeyEvent) override;
58 |
59 | virtual FReply OnAnalogValueChanged(const FGeometry& MyGeometry, const FAnalogInputEvent& AnalogInputEvent) override;
60 |
61 | virtual FReply OnMouseButtonDown(const FGeometry& MyGeometry, const FPointerEvent& MouseEvent) override;
62 |
63 | virtual FReply OnMouseButtonDoubleClick(const FGeometry& MyGeometry, const FPointerEvent& MouseEvent) override;
64 |
65 | virtual FReply OnMouseButtonUp(const FGeometry& MyGeometry, const FPointerEvent& MouseEvent) override;
66 |
67 | virtual FReply OnMouseWheel(const FGeometry& MyGeometry, const FPointerEvent& MouseEvent) override;
68 |
69 | virtual FReply OnMouseMove(const FGeometry& MyGeometry, const FPointerEvent& MouseEvent) override;
70 |
71 | virtual FReply OnFocusReceived(const FGeometry& MyGeometry, const FFocusEvent& FocusEvent) override;
72 |
73 | virtual void OnFocusLost(const FFocusEvent& FocusEvent) override;
74 |
75 | virtual void OnMouseEnter(const FGeometry& MyGeometry, const FPointerEvent& MouseEvent) override;
76 |
77 | virtual void OnMouseLeave(const FPointerEvent& MouseEvent) override;
78 |
79 | virtual FReply OnTouchStarted(const FGeometry& MyGeometry, const FPointerEvent& TouchEvent) override;
80 |
81 | virtual FReply OnTouchMoved(const FGeometry& MyGeometry, const FPointerEvent& TouchEvent) override;
82 |
83 | virtual FReply OnTouchEnded(const FGeometry& MyGeometry, const FPointerEvent& TouchEvent) override;
84 |
85 | private:
86 |
87 | void CreateInputHandler(const FSoftClassPath& HandlerClassReference);
88 | void ReleaseInputHandler();
89 |
90 | void RegisterImGuiSettingsDelegates();
91 | void UnregisterImGuiSettingsDelegates();
92 |
93 | void SetHideMouseCursor(bool bHide);
94 |
95 | bool IsConsoleOpened() const;
96 |
97 | // Update visibility based on input state.
98 | void UpdateVisibility();
99 |
100 | // Update cursor based on input state.
101 | void UpdateMouseCursor();
102 |
103 | ULocalPlayer* GetLocalPlayer() const;
104 | void TakeFocus();
105 | void ReturnFocus();
106 |
107 | // Update input state.
108 | void UpdateInputState();
109 | void UpdateTransparentMouseInput(const FGeometry& AllottedGeometry);
110 | void HandleWindowFocusLost();
111 |
112 | void SetDPIScale(const FImGuiDPIScaleInfo& ScaleInfo);
113 |
114 | void SetCanvasSizeInfo(const FImGuiCanvasSizeInfo& CanvasSizeInfo);
115 | void UpdateCanvasSize();
116 |
117 | void UpdateCanvasControlMode(const FInputEvent& InputEvent);
118 |
119 | void OnPostImGuiUpdate();
120 |
121 | FVector2D TransformScreenPointToImGui(const FGeometry& MyGeometry, const FVector2D& Point) const;
122 |
123 | virtual int32 OnPaint(const FPaintArgs& Args, const FGeometry& AllottedGeometry, const FSlateRect& MyClippingRect, FSlateWindowElementList& OutDrawElements, int32 LayerId, const FWidgetStyle& WidgetStyle, bool bParentEnabled) const override;
124 |
125 | virtual FVector2D ComputeDesiredSize(float) const override;
126 |
127 | void SetImGuiTransform(const FSlateRenderTransform& Transform) { ImGuiTransform = Transform; }
128 |
129 | #if IMGUI_WIDGET_DEBUG
130 | void OnDebugDraw();
131 | #endif // IMGUI_WIDGET_DEBUG
132 |
133 | FImGuiModuleManager* ModuleManager = nullptr;
134 | TWeakObjectPtr GameViewport;
135 | TWeakObjectPtr InputHandler;
136 |
137 | FSlateRenderTransform ImGuiTransform;
138 | FSlateRenderTransform ImGuiRenderTransform;
139 |
140 | mutable TArray VertexBuffer;
141 | mutable TArray IndexBuffer;
142 |
143 | int32 ContextIndex = 0;
144 |
145 | FVector2D MinCanvasSize = FVector2D::ZeroVector;
146 | FVector2D CanvasSize = FVector2D::ZeroVector;
147 |
148 | float DPIScale = 1.f;
149 |
150 | bool bInputEnabled = false;
151 | bool bForegroundWindow = false;
152 | bool bHideMouseCursor = true;
153 | bool bTransparentMouseInput = false;
154 | bool bAdaptiveCanvasSize = false;
155 | bool bUpdateCanvasSize = false;
156 | bool bCanvasControlEnabled = false;
157 |
158 | TSharedPtr CanvasControlWidget;
159 | TWeakPtr PreviousUserFocusedWidget;
160 | };
161 |
--------------------------------------------------------------------------------
/Source/ImGui/Private/Editor/ImGuiKeyInfoCustomization.cpp:
--------------------------------------------------------------------------------
1 | // Distributed under the MIT License (MIT) (see accompanying LICENSE file)
2 |
3 | #include "ImGuiKeyInfoCustomization.h"
4 |
5 | #if WITH_EDITOR
6 |
7 | #include "ImGuiModuleSettings.h"
8 |
9 | #include
10 | #include
11 | #include
12 | #include
13 |
14 |
15 | #define LOCTEXT_NAMESPACE "ImGuiEditor"
16 |
17 |
18 | //----------------------------------------------------------------------------------------------------
19 | // Helper widgets
20 | //----------------------------------------------------------------------------------------------------
21 |
22 | namespace
23 | {
24 | class SPropertyKeySelector : public SCompoundWidget
25 | {
26 | public:
27 | SLATE_BEGIN_ARGS(SPropertyKeySelector)
28 | {}
29 | SLATE_ARGUMENT(TSharedPtr, KeyHandle)
30 | SLATE_ATTRIBUTE(FSlateFontInfo, Font)
31 | SLATE_END_ARGS()
32 |
33 | void Construct(const FArguments& InArgs)
34 | {
35 | KeyHandle = InArgs._KeyHandle;
36 |
37 | ChildSlot
38 | [
39 | SNew(SKeySelector)
40 | .CurrentKey(this, &SPropertyKeySelector::GetCurrentKey)
41 | .OnKeyChanged(this, &SPropertyKeySelector::OnKeyChanged)
42 | .Font(InArgs._Font)
43 | ];
44 | }
45 |
46 | TOptional GetCurrentKey() const
47 | {
48 | TArray RawPtrs;
49 | KeyHandle->AccessRawData(RawPtrs);
50 |
51 | if (RawPtrs.Num())
52 | {
53 | FKey* KeyPtr = static_cast(RawPtrs[0]);
54 |
55 | if (KeyPtr)
56 | {
57 | for (int32 Index = 1; Index < RawPtrs.Num(); Index++)
58 | {
59 | if (*static_cast(RawPtrs[Index]) != *KeyPtr)
60 | {
61 | return TOptional();
62 | }
63 | }
64 |
65 | return *KeyPtr;
66 | }
67 | }
68 |
69 | return FKey();
70 | }
71 |
72 | void OnKeyChanged(TSharedPtr SelectedKey)
73 | {
74 | KeyHandle->SetValueFromFormattedString(SelectedKey->ToString());
75 | }
76 |
77 | private:
78 |
79 | TSharedPtr KeyHandle;
80 | };
81 |
82 | class SPropertyTriStateCheckBox : public SCompoundWidget
83 | {
84 | public:
85 |
86 | using FCheckBoxStateRaw = std::underlying_type::type;
87 |
88 | SLATE_BEGIN_ARGS(SPropertyTriStateCheckBox)
89 | {}
90 | SLATE_ARGUMENT(TSharedPtr, PropertyHandle)
91 | SLATE_END_ARGS()
92 |
93 | void Construct(const FArguments& InArgs)
94 | {
95 | PropertyHandle = InArgs._PropertyHandle;
96 |
97 | // We are abusing SCheckBox a bit but our GetPropertyValue with custom OnCheckBoxStateChanged implementation
98 | // gives a checkbox that allows to cycle between all three states.
99 | ChildSlot
100 | [
101 | SNew(SCheckBox)
102 | .IsChecked(this, &SPropertyTriStateCheckBox::GetPropertyValue)
103 | .OnCheckStateChanged(this, &SPropertyTriStateCheckBox::OnCheckBoxStateChanged)
104 | ];
105 | }
106 |
107 | FCheckBoxStateRaw GetPropertyRawValue() const
108 | {
109 | FCheckBoxStateRaw Value;
110 | PropertyHandle.Get()->GetValue(Value);
111 | return Value;
112 | }
113 |
114 | ECheckBoxState GetPropertyValue() const
115 | {
116 | return static_cast(GetPropertyRawValue());
117 | }
118 |
119 | void OnCheckBoxStateChanged(ECheckBoxState State)
120 | {
121 | const FCheckBoxStateRaw PrevEnumValue = (GetPropertyRawValue() + 2) % 3;
122 | PropertyHandle.Get()->SetValue(PrevEnumValue);
123 | }
124 |
125 | private:
126 |
127 | TSharedPtr PropertyHandle;
128 | };
129 | }
130 |
131 |
132 | //----------------------------------------------------------------------------------------------------
133 | // FImGuiKeyInfoCustomization implementation
134 | //----------------------------------------------------------------------------------------------------
135 |
136 | namespace InputConstants
137 | {
138 | static const FMargin PropertyPadding(0.0f, 0.0f, 4.0f, 0.0f);
139 | }
140 |
141 | TSharedRef FImGuiKeyInfoCustomization::MakeInstance()
142 | {
143 | return MakeShareable(new FImGuiKeyInfoCustomization);
144 | }
145 |
146 | void FImGuiKeyInfoCustomization::CustomizeHeader(TSharedRef InStructPropertyHandle, FDetailWidgetRow& HeaderRow, IPropertyTypeCustomizationUtils& StructCustomizationUtils)
147 | {
148 | TSharedPtr KeyHandle = InStructPropertyHandle->GetChildHandle(GET_MEMBER_NAME_CHECKED(FImGuiKeyInfo, Key));
149 | TSharedPtr ShiftHandle = InStructPropertyHandle->GetChildHandle(GET_MEMBER_NAME_CHECKED(FImGuiKeyInfo, Shift));
150 | TSharedPtr CtrlHandle = InStructPropertyHandle->GetChildHandle(GET_MEMBER_NAME_CHECKED(FImGuiKeyInfo, Ctrl));
151 | TSharedPtr AltHandle = InStructPropertyHandle->GetChildHandle(GET_MEMBER_NAME_CHECKED(FImGuiKeyInfo, Alt));
152 | TSharedPtr CmdHandle = InStructPropertyHandle->GetChildHandle(GET_MEMBER_NAME_CHECKED(FImGuiKeyInfo, Cmd));
153 |
154 | #define ADD_CHECK_BOX_SLOT(Handle) \
155 | + SHorizontalBox::Slot()\
156 | .Padding(InputConstants::PropertyPadding)\
157 | .HAlign(HAlign_Left)\
158 | .VAlign(VAlign_Center)\
159 | .AutoWidth()\
160 | [\
161 | Handle->CreatePropertyNameWidget()\
162 | ]\
163 | + SHorizontalBox::Slot()\
164 | .Padding(InputConstants::PropertyPadding)\
165 | .HAlign(HAlign_Left)\
166 | .VAlign(VAlign_Center)\
167 | .AutoWidth()\
168 | [\
169 | SNew(SPropertyTriStateCheckBox).PropertyHandle(Handle)\
170 | ]
171 |
172 | HeaderRow
173 | .NameContent()
174 | [
175 | InStructPropertyHandle->CreatePropertyNameWidget()
176 | ]
177 | .ValueContent()
178 | .MaxDesiredWidth(400.f)
179 | [
180 | SNew(SHorizontalBox)
181 | + SHorizontalBox::Slot()
182 | .Padding(InputConstants::PropertyPadding)
183 | .AutoWidth()
184 | [
185 | SNew(SBox)
186 | .WidthOverride(200.f)
187 | [
188 | SNew(SPropertyKeySelector)
189 | .KeyHandle(KeyHandle)
190 | .Font(StructCustomizationUtils.GetRegularFont())
191 | ]
192 | ]
193 | ADD_CHECK_BOX_SLOT(ShiftHandle)
194 | ADD_CHECK_BOX_SLOT(CtrlHandle)
195 | ADD_CHECK_BOX_SLOT(AltHandle)
196 | ADD_CHECK_BOX_SLOT(CmdHandle)
197 | ];
198 |
199 | #undef ADD_CHECK_BOX_SLOT
200 | }
201 |
202 | void FImGuiKeyInfoCustomization::CustomizeChildren(TSharedRef InStructPropertyHandle, IDetailChildrenBuilder& StructBuilder, IPropertyTypeCustomizationUtils& StructCustomizationUtils)
203 | {
204 | }
205 |
206 |
207 | #undef LOCTEXT_NAMESPACE
208 |
209 | #endif // WITH_EDITOR
210 |
--------------------------------------------------------------------------------
/Source/ImGui/Private/ImGuiModuleSettings.cpp:
--------------------------------------------------------------------------------
1 | // Distributed under the MIT License (MIT) (see accompanying LICENSE file)
2 |
3 | #include "ImGuiModuleSettings.h"
4 |
5 | #include "ImGuiModuleCommands.h"
6 | #include "ImGuiModuleProperties.h"
7 |
8 | #include
9 | #include
10 | #include
11 |
12 |
13 | //====================================================================================================
14 | // FImGuiDPIScaleInfo
15 | //====================================================================================================
16 |
17 | FImGuiDPIScaleInfo::FImGuiDPIScaleInfo()
18 | {
19 | if (FRichCurve* Curve = DPICurve.GetRichCurve())
20 | {
21 | Curve->AddKey( 0.0f, 1.f);
22 |
23 | Curve->AddKey(2159.5f, 1.f);
24 | Curve->AddKey(2160.0f, 2.f);
25 |
26 | Curve->AddKey(4319.5f, 2.f);
27 | Curve->AddKey(4320.0f, 4.f);
28 | }
29 | }
30 |
31 | float FImGuiDPIScaleInfo::CalculateResolutionBasedScale() const
32 | {
33 | float ResolutionBasedScale = 1.f;
34 | if (bScaleWithCurve && GEngine && GEngine->GameUserSettings)
35 | {
36 | if (const FRichCurve* Curve = DPICurve.GetRichCurveConst())
37 | {
38 | ResolutionBasedScale *= Curve->Eval((float)GEngine->GameUserSettings->GetDesktopResolution().Y, 1.f);
39 | }
40 | }
41 | return ResolutionBasedScale;
42 | }
43 |
44 | //====================================================================================================
45 | // UImGuiSettings
46 | //====================================================================================================
47 |
48 | UImGuiSettings* UImGuiSettings::DefaultInstance = nullptr;
49 |
50 | FSimpleMulticastDelegate UImGuiSettings::OnSettingsLoaded;
51 |
52 | void UImGuiSettings::PostInitProperties()
53 | {
54 | Super::PostInitProperties();
55 |
56 | if (IsTemplate())
57 | {
58 | DefaultInstance = this;
59 | OnSettingsLoaded.Broadcast();
60 | }
61 | }
62 |
63 | void UImGuiSettings::BeginDestroy()
64 | {
65 | Super::BeginDestroy();
66 |
67 | if (DefaultInstance == this)
68 | {
69 | DefaultInstance = nullptr;
70 | }
71 | }
72 |
73 | //====================================================================================================
74 | // FImGuiModuleSettings
75 | //====================================================================================================
76 |
77 | FImGuiModuleSettings::FImGuiModuleSettings(FImGuiModuleProperties& InProperties, FImGuiModuleCommands& InCommands)
78 | : Properties(InProperties)
79 | , Commands(InCommands)
80 | {
81 | #if WITH_EDITOR
82 | FCoreUObjectDelegates::OnObjectPropertyChanged.AddRaw(this, &FImGuiModuleSettings::OnPropertyChanged);
83 | #endif
84 |
85 | // Delegate initializer to support settings loaded after this object creation (in stand-alone builds) and potential
86 | // reloading of settings.
87 | UImGuiSettings::OnSettingsLoaded.AddRaw(this, &FImGuiModuleSettings::InitializeAllSettings);
88 |
89 | // Call initializer to support settings already loaded (editor).
90 | InitializeAllSettings();
91 | }
92 |
93 | FImGuiModuleSettings::~FImGuiModuleSettings()
94 | {
95 |
96 | UImGuiSettings::OnSettingsLoaded.RemoveAll(this);
97 |
98 | #if WITH_EDITOR
99 | FCoreUObjectDelegates::OnObjectPropertyChanged.RemoveAll(this);
100 | #endif
101 | }
102 |
103 | void FImGuiModuleSettings::InitializeAllSettings()
104 | {
105 | UpdateSettings();
106 | UpdateDPIScaleInfo();
107 | }
108 |
109 | void FImGuiModuleSettings::UpdateSettings()
110 | {
111 | if (UImGuiSettings* SettingsObject = UImGuiSettings::Get())
112 | {
113 | SetImGuiInputHandlerClass(SettingsObject->ImGuiInputHandlerClass);
114 | SetShareKeyboardInput(SettingsObject->bShareKeyboardInput);
115 | SetShareGamepadInput(SettingsObject->bShareGamepadInput);
116 | SetShareMouseInput(SettingsObject->bShareMouseInput);
117 | SetUseSoftwareCursor(SettingsObject->bUseSoftwareCursor);
118 | SetToggleInputKey(SettingsObject->ToggleInput);
119 | SetCanvasSizeInfo(SettingsObject->CanvasSize);
120 | }
121 | }
122 |
123 | void FImGuiModuleSettings::UpdateDPIScaleInfo()
124 | {
125 | if (UImGuiSettings* SettingsObject = UImGuiSettings::Get())
126 | {
127 | SetDPIScaleInfo(SettingsObject->DPIScale);
128 | }
129 | }
130 |
131 | void FImGuiModuleSettings::SetImGuiInputHandlerClass(const FSoftClassPath& ClassReference)
132 | {
133 | if (ImGuiInputHandlerClass != ClassReference)
134 | {
135 | ImGuiInputHandlerClass = ClassReference;
136 | OnImGuiInputHandlerClassChanged.Broadcast(ClassReference);
137 | }
138 | }
139 |
140 | void FImGuiModuleSettings::SetShareKeyboardInput(bool bShare)
141 | {
142 | if (bShareKeyboardInput != bShare)
143 | {
144 | bShareKeyboardInput = bShare;
145 | Properties.SetKeyboardInputShared(bShare);
146 | }
147 | }
148 |
149 | void FImGuiModuleSettings::SetShareGamepadInput(bool bShare)
150 | {
151 | if (bShareGamepadInput != bShare)
152 | {
153 | bShareGamepadInput = bShare;
154 | Properties.SetGamepadInputShared(bShare);
155 | }
156 | }
157 |
158 | void FImGuiModuleSettings::SetShareMouseInput(bool bShare)
159 | {
160 | if (bShareMouseInput != bShare)
161 | {
162 | bShareMouseInput = bShare;
163 | Properties.SetMouseInputShared(bShare);
164 | }
165 | }
166 |
167 | void FImGuiModuleSettings::SetUseSoftwareCursor(bool bUse)
168 | {
169 | if (bUseSoftwareCursor != bUse)
170 | {
171 | bUseSoftwareCursor = bUse;
172 | OnUseSoftwareCursorChanged.Broadcast(bUse);
173 | }
174 | }
175 |
176 | void FImGuiModuleSettings::SetToggleInputKey(const FImGuiKeyInfo& KeyInfo)
177 | {
178 | if (ToggleInputKey != KeyInfo)
179 | {
180 | ToggleInputKey = KeyInfo;
181 | Commands.SetKeyBinding(FImGuiModuleCommands::ToggleInput, ToggleInputKey);
182 | }
183 | }
184 |
185 | void FImGuiModuleSettings::SetCanvasSizeInfo(const FImGuiCanvasSizeInfo& CanvasSizeInfo)
186 | {
187 | if (CanvasSize != CanvasSizeInfo)
188 | {
189 | CanvasSize = CanvasSizeInfo;
190 | OnCanvasSizeChangedDelegate.Broadcast(CanvasSize);
191 | }
192 | }
193 |
194 | void FImGuiModuleSettings::SetDPIScaleInfo(const FImGuiDPIScaleInfo& ScaleInfo)
195 | {
196 | DPIScale = ScaleInfo;
197 | OnDPIScaleChangedDelegate.Broadcast(DPIScale);
198 | }
199 |
200 | #if WITH_EDITOR
201 |
202 | void FImGuiModuleSettings::OnPropertyChanged(class UObject* ObjectBeingModified, struct FPropertyChangedEvent& PropertyChangedEvent)
203 | {
204 | if (ObjectBeingModified == UImGuiSettings::Get())
205 | {
206 | UpdateSettings();
207 | if (PropertyChangedEvent.MemberProperty
208 | && (PropertyChangedEvent.MemberProperty->GetFName() == GET_MEMBER_NAME_CHECKED(FImGuiModuleSettings, DPIScale)))
209 | {
210 | UpdateDPIScaleInfo();
211 | }
212 | }
213 | }
214 |
215 | #endif // WITH_EDITOR
216 |
--------------------------------------------------------------------------------
/Source/ImGui/Public/ImGuiInputHandler.h:
--------------------------------------------------------------------------------
1 | // Distributed under the MIT License (MIT) (see accompanying LICENSE file)
2 |
3 | #pragma once
4 |
5 | #include
6 | #include
7 | #include
8 | #include
9 |
10 | #include "ImGuiInputHandler.generated.h"
11 |
12 |
13 | class FImGuiModuleManager;
14 | class UGameViewportClient;
15 |
16 | struct FAnalogInputEvent;
17 | struct FCharacterEvent;
18 | struct FKeyEvent;
19 |
20 | #if WITH_EDITOR
21 | class FUICommandInfo;
22 | #endif // WITH_EDITOR
23 |
24 |
25 | /**
26 | * Handles input and sends it to the input state, which is copied to the ImGui IO at the beginning of the frame.
27 | * Implementation of the input handler can be changed in the ImGui project settings by changing ImGuiInputHandlerClass.
28 | */
29 | UCLASS()
30 | class IMGUI_API UImGuiInputHandler : public UObject
31 | {
32 | GENERATED_BODY()
33 |
34 | public:
35 |
36 | /**
37 | * Called to handle character events.
38 | * @returns Response whether the event was handled
39 | */
40 | virtual FReply OnKeyChar(const struct FCharacterEvent& CharacterEvent);
41 |
42 | /**
43 | * Called to handle key down events.
44 | * @returns Response whether the event was handled
45 | */
46 | virtual FReply OnKeyDown(const FKeyEvent& KeyEvent);
47 |
48 | /**
49 | * Called to handle key up events.
50 | * @returns Response whether the event was handled
51 | */
52 | virtual FReply OnKeyUp(const FKeyEvent& KeyEvent);
53 |
54 | /**
55 | * Called to handle analog value change events.
56 | * @returns Response whether the event was handled
57 | */
58 | virtual FReply OnAnalogValueChanged(const FAnalogInputEvent& AnalogInputEvent);
59 |
60 | /**
61 | * Called to handle mouse button down events.
62 | * @returns Response whether the event was handled
63 | */
64 | virtual FReply OnMouseButtonDown(const FPointerEvent& MouseEvent);
65 |
66 | /**
67 | * Called to handle mouse button double-click events.
68 | * @returns Response whether the event was handled
69 | */
70 | virtual FReply OnMouseButtonDoubleClick(const FPointerEvent& MouseEvent);
71 |
72 | /**
73 | * Called to handle mouse button up events.
74 | * @returns Response whether the event was handled
75 | */
76 | virtual FReply OnMouseButtonUp(const FPointerEvent& MouseEvent);
77 |
78 | /**
79 | * Called to handle mouse wheel events.
80 | * @returns Response whether the event was handled
81 | */
82 | virtual FReply OnMouseWheel(const FPointerEvent& MouseEvent);
83 |
84 | /**
85 | * Called to handle mouse move events.
86 | * @param MousePosition Mouse position (in ImGui space)
87 | * @param MouseEvent Optional mouse event passed from Slate
88 | * @returns Response whether the event was handled
89 | */
90 | virtual FReply OnMouseMove(const FVector2D& MousePosition, const FPointerEvent& MouseEvent);
91 | virtual FReply OnMouseMove(const FVector2D& MousePosition);
92 |
93 | /**
94 | * Called to handle touch started event.
95 | * @param TouchPosition Touch position (in ImGui space)
96 | * @param TouchEvent Touch event passed from Slate
97 | * @returns Response whether the event was handled
98 | */
99 | virtual FReply OnTouchStarted(const FVector2D& TouchPosition, const FPointerEvent& TouchEvent);
100 |
101 | /**
102 | * Called to handle touch moved event.
103 | * @param TouchPosition Touch position (in ImGui space)
104 | * @param TouchEvent Touch event passed from Slate
105 | * @returns Response whether the event was handled
106 | */
107 | virtual FReply OnTouchMoved(const FVector2D& TouchPosition, const FPointerEvent& TouchEvent);
108 |
109 | /**
110 | * Called to handle touch ended event.
111 | * @param TouchPosition Touch position (in ImGui space)
112 | * @param TouchEvent Touch event passed from Slate
113 | * @returns Response whether the event was handled
114 | */
115 | virtual FReply OnTouchEnded(const FVector2D& TouchPosition, const FPointerEvent& TouchEvent);
116 |
117 | /** Called to handle activation of the keyboard input. */
118 | virtual void OnKeyboardInputEnabled();
119 |
120 | /** Called to handle deactivation of the keyboard input. */
121 | virtual void OnKeyboardInputDisabled();
122 |
123 | /** Called to handle activation of the gamepad input. */
124 | virtual void OnGamepadInputEnabled();
125 |
126 | /** Called to handle deactivation of the gamepad input. */
127 | virtual void OnGamepadInputDisabled();
128 |
129 | /** Called to handle activation of the mouse input. */
130 | virtual void OnMouseInputEnabled();
131 |
132 | /** Called to handle deactivation of the mouse input. */
133 | virtual void OnMouseInputDisabled();
134 |
135 | protected:
136 |
137 | /** Copy state of modifier keys to input state. */
138 | void CopyModifierKeys(const FInputEvent& InputEvent);
139 |
140 | /**
141 | * Checks whether this is a key event that can open console.
142 | * @param KeyEvent - Key event to test.
143 | * @returns True, if this key event can open console.
144 | */
145 | bool IsConsoleEvent(const FKeyEvent& KeyEvent) const;
146 |
147 | #if WITH_EDITOR
148 | /**
149 | * Checks whether this is a key event that can stop PIE session.
150 | * @param KeyEvent - Key event to test.
151 | * @returns True, if this key event can stop PIE session.
152 | */
153 | bool IsStopPlaySessionEvent(const FKeyEvent& KeyEvent) const;
154 | #endif
155 |
156 | /**
157 | * Checks whether this key event can toggle ImGui input (as defined in settings).
158 | * @param KeyEvent - Key event to test.
159 | * @returns True, if this key is bound to 'ImGui.ToggleInput' command that switches ImGui input mode.
160 | */
161 | bool IsToggleInputEvent(const FKeyEvent& KeyEvent) const;
162 |
163 | /**
164 | * Checks whether corresponding ImGui context has an active item (holding cursor focus).
165 | * @returns True, if corresponding context has an active item.
166 | */
167 | bool HasImGuiActiveItem() const;
168 |
169 | private:
170 |
171 | void UpdateInputStatePointer();
172 |
173 | void OnSoftwareCursorChanged(bool);
174 |
175 | void OnPostImGuiUpdate();
176 |
177 | void Initialize(FImGuiModuleManager* InModuleManager, UGameViewportClient* InGameViewport, int32 InContextIndex);
178 |
179 | virtual void BeginDestroy() override;
180 |
181 | class FImGuiInputState* InputState = nullptr;
182 |
183 | bool bMouseInputEnabled = false;
184 | bool bKeyboardInputEnabled = false;
185 | bool bGamepadInputEnabled = false;
186 |
187 | FImGuiModuleManager* ModuleManager = nullptr;
188 |
189 | TWeakObjectPtr GameViewport;
190 |
191 | int32 ContextIndex = -1;
192 |
193 | #if WITH_EDITOR
194 | TSharedPtr StopPlaySessionCommandInfo;
195 | #endif
196 |
197 | friend class FImGuiInputHandlerFactory;
198 | };
199 |
--------------------------------------------------------------------------------
/Source/ImGui/Private/TextureManager.cpp:
--------------------------------------------------------------------------------
1 | // Distributed under the MIT License (MIT) (see accompanying LICENSE file)
2 |
3 | #include "TextureManager.h"
4 | #include "RHITypes.h"
5 | #include
6 | #include
7 |
8 | #include
9 |
10 |
11 | void FTextureManager::InitializeErrorTexture(const FColor& Color)
12 | {
13 | CreatePlainTextureInternal(NAME_ErrorTexture, 2, 2, Color);
14 | }
15 |
16 | TextureIndex FTextureManager::CreateTexture(const FName& Name, int32 Width, int32 Height, uint32 SrcBpp, uint8* SrcData, TFunction SrcDataCleanup)
17 | {
18 | checkf(Name != NAME_None, TEXT("Trying to create a texture with a name 'NAME_None' is not allowed."));
19 |
20 | return CreateTextureInternal(Name, Width, Height, SrcBpp, SrcData, SrcDataCleanup);
21 | }
22 |
23 | TextureIndex FTextureManager::CreatePlainTexture(const FName& Name, int32 Width, int32 Height, FColor Color)
24 | {
25 | checkf(Name != NAME_None, TEXT("Trying to create a texture with a name 'NAME_None' is not allowed."));
26 |
27 | return CreatePlainTextureInternal(Name, Width, Height, Color);
28 | }
29 |
30 | TextureIndex FTextureManager::CreateTextureResources(const FName& Name, UTexture* Texture)
31 | {
32 | checkf(Name != NAME_None, TEXT("Trying to create texture resources with a name 'NAME_None' is not allowed."));
33 | checkf(Texture, TEXT("Null Texture."));
34 |
35 | // Create an entry for the texture.
36 | return AddTextureEntry(Name, Texture, false);
37 | }
38 |
39 | void FTextureManager::ReleaseTextureResources(TextureIndex Index)
40 | {
41 | checkf(IsInRange(Index), TEXT("Invalid texture index %d. Texture resources array has %d entries total."), Index, TextureResources.Num());
42 |
43 | TextureResources[Index] = {};
44 | }
45 |
46 | TextureIndex FTextureManager::CreateTextureInternal(const FName& Name, int32 Width, int32 Height, uint32 SrcBpp, uint8* SrcData, TFunction SrcDataCleanup)
47 | {
48 | // Create a texture.
49 | UTexture2D* Texture = UTexture2D::CreateTransient(Width, Height);
50 |
51 | // Create a new resource for that texture.
52 | Texture->UpdateResource();
53 |
54 | // Update texture data.
55 | FUpdateTextureRegion2D* TextureRegion = new FUpdateTextureRegion2D(0, 0, 0, 0, Width, Height);
56 | auto DataCleanup = [SrcDataCleanup](uint8* Data, const FUpdateTextureRegion2D* UpdateRegion)
57 | {
58 | SrcDataCleanup(Data);
59 | delete UpdateRegion;
60 | };
61 | Texture->UpdateTextureRegions(0, 1u, TextureRegion, SrcBpp * Width, SrcBpp, SrcData, DataCleanup);
62 |
63 | // Create an entry for the texture.
64 | if (Name == NAME_ErrorTexture)
65 | {
66 | ErrorTexture = { Name, Texture, true };
67 | return INDEX_ErrorTexture;
68 | }
69 | else
70 | {
71 | return AddTextureEntry(Name, Texture, true);
72 | }
73 | }
74 |
75 | TextureIndex FTextureManager::CreatePlainTextureInternal(const FName& Name, int32 Width, int32 Height, const FColor& Color)
76 | {
77 | // Create buffer with raw data.
78 | const uint32 ColorPacked = Color.ToPackedARGB();
79 | const uint32 Bpp = sizeof(ColorPacked);
80 | const uint32 SizeInPixels = Width * Height;
81 | const uint32 SizeInBytes = SizeInPixels * Bpp;
82 | uint8* SrcData = new uint8[SizeInBytes];
83 | std::fill(reinterpret_cast(SrcData), reinterpret_cast(SrcData) + SizeInPixels, ColorPacked);
84 | auto SrcDataCleanup = [](uint8* Data) { delete[] Data; };
85 |
86 | // Create new texture from raw data.
87 | return CreateTextureInternal(Name, Width, Height, Bpp, SrcData, SrcDataCleanup);
88 | }
89 |
90 | TextureIndex FTextureManager::AddTextureEntry(const FName& Name, UTexture* Texture, bool bAddToRoot)
91 | {
92 | // Try to find an entry with that name.
93 | TextureIndex Index = FindTextureIndex(Name);
94 |
95 | // If this is a new name, try to find an entry to reuse.
96 | if (Index == INDEX_NONE)
97 | {
98 | Index = FindTextureIndex(NAME_None);
99 | }
100 |
101 | // Either update/reuse an entry or add a new one.
102 | if (Index != INDEX_NONE)
103 | {
104 | TextureResources[Index] = { Name, Texture, bAddToRoot };
105 | return Index;
106 | }
107 | else
108 | {
109 | return TextureResources.Emplace(Name, Texture, bAddToRoot);
110 | }
111 | }
112 |
113 | FTextureManager::FTextureEntry::FTextureEntry(const FName& InName, UTexture* InTexture, bool bAddToRoot)
114 | : Name(InName)
115 | {
116 | checkf(InTexture, TEXT("Null texture."));
117 |
118 | if (bAddToRoot)
119 | {
120 | // Get pointer only for textures that we added to root, so we can later release them.
121 | Texture = InTexture;
122 | // Add texture to the root to prevent garbage collection.
123 | InTexture->AddToRoot();
124 | }
125 |
126 | // Create brush and resource handle for input texture.
127 | Brush.SetResourceObject(InTexture);
128 | CachedResourceHandle = FSlateApplication::Get().GetRenderer()->GetResourceHandle(Brush);
129 | }
130 |
131 | FTextureManager::FTextureEntry::~FTextureEntry()
132 | {
133 | Reset(true);
134 | }
135 |
136 | FTextureManager::FTextureEntry& FTextureManager::FTextureEntry::operator=(FTextureEntry&& Other)
137 | {
138 | // Release old resources if allocated.
139 | Reset(true);
140 |
141 | // Move data and ownership to this instance.
142 | Name = MoveTemp(Other.Name);
143 | Texture = MoveTemp(Other.Texture);
144 | Brush = MoveTemp(Other.Brush);
145 | CachedResourceHandle = MoveTemp(Other.CachedResourceHandle);
146 |
147 | // Reset the other entry (without releasing resources which are already moved to this instance) to remove tracks
148 | // of ownership and mark it as empty/reusable.
149 | Other.Reset(false);
150 |
151 | return *this;
152 | }
153 |
154 | const FSlateResourceHandle& FTextureManager::FTextureEntry::GetResourceHandle() const
155 | {
156 | if (!CachedResourceHandle.IsValid() && Brush.HasUObject())
157 | {
158 | CachedResourceHandle = FSlateApplication::Get().GetRenderer()->GetResourceHandle(Brush);
159 | }
160 | return CachedResourceHandle;
161 | }
162 |
163 | void FTextureManager::FTextureEntry::Reset(bool bReleaseResources)
164 | {
165 | if (bReleaseResources)
166 | {
167 | // Release brush.
168 | if (Brush.HasUObject() && FSlateApplication::IsInitialized())
169 | {
170 | FSlateApplication::Get().GetRenderer()->ReleaseDynamicResource(Brush);
171 | }
172 |
173 | // Remove texture from root to allow for garbage collection (it might be invalid, if we never set it
174 | // or this is an application shutdown).
175 | if (Texture.IsValid())
176 | {
177 | Texture->RemoveFromRoot();
178 | }
179 | }
180 |
181 | // We use empty name to mark unused entries.
182 | Name = NAME_None;
183 |
184 | // Clean fields to make sure that we don't reference released or moved resources.
185 | Texture.Reset();
186 | Brush = FSlateNoResource();
187 | CachedResourceHandle = FSlateResourceHandle();
188 | }
189 |
--------------------------------------------------------------------------------
/Source/ImGui/Private/TextureManager.h:
--------------------------------------------------------------------------------
1 | // Distributed under the MIT License (MIT) (see accompanying LICENSE file)
2 |
3 | #pragma once
4 |
5 | #include
6 | #include
7 | #include
8 |
9 |
10 | class UTexture2D;
11 |
12 | // Index type to be used as a texture handle.
13 | using TextureIndex = int32;
14 |
15 | // Manager for textures resources which can be referenced by a unique name or index.
16 | // Name is primarily for lookup and index provides a direct access to resources.
17 | class FTextureManager
18 | {
19 | public:
20 |
21 | // Creates an empty manager.
22 | FTextureManager() = default;
23 |
24 | // Copying is disabled to protected resource ownership.
25 | FTextureManager(const FTextureManager&) = delete;
26 | FTextureManager& operator=(const FTextureManager&) = delete;
27 |
28 | // Moving transfers ownership and leaves source empty.
29 | FTextureManager(FTextureManager&&) = delete;
30 | FTextureManager& operator=(FTextureManager&&) = delete;
31 |
32 | // Initialize error texture that will be used for rendering textures without registered resources. Can be called
33 | // multiple time, if color needs to be changed.
34 | // Note: Because of any-time module loading and lazy resources initialization goals we can't simply call it from
35 | // constructor.
36 | // @param Color - The color of the error texture
37 | void InitializeErrorTexture(const FColor& Color);
38 |
39 | // Find texture index by name.
40 | // @param Name - The name of a texture to find
41 | // @returns The index of a texture with given name or INDEX_NONE if there is no such texture
42 | TextureIndex FindTextureIndex(const FName& Name) const
43 | {
44 | return TextureResources.IndexOfByPredicate([&](const auto& Entry) { return Entry.GetName() == Name; });
45 | }
46 |
47 | // Get the name of a texture at given index. Returns NAME_None, if index is out of range.
48 | // @param Index - Index of a texture
49 | // @returns The name of a texture at given index or NAME_None if index is out of range.
50 | FName GetTextureName(TextureIndex Index) const
51 | {
52 | return IsInRange(Index) ? TextureResources[Index].GetName() : NAME_None;
53 | }
54 |
55 | // Get the Slate Resource Handle to a texture at given index. If index is out of range or resources are not valid
56 | // it returns a handle to the error texture.
57 | // @param Index - Index of a texture
58 | // @returns The Slate Resource Handle for a texture at given index or to error texture, if no valid resources were
59 | // found at given index
60 | const FSlateResourceHandle& GetTextureHandle(TextureIndex Index) const
61 | {
62 | return IsValidTexture(Index) ? TextureResources[Index].GetResourceHandle() : ErrorTexture.GetResourceHandle();
63 | }
64 |
65 | // Create a texture from raw data.
66 | // @param Name - The texture name
67 | // @param Width - The texture width
68 | // @param Height - The texture height
69 | // @param SrcBpp - The size in bytes of one pixel
70 | // @param SrcData - The source data
71 | // @param SrcDataCleanup - Optional function called to release source data after texture is created (only needed, if data need to be released)
72 | // @returns The index of a texture that was created
73 | TextureIndex CreateTexture(const FName& Name, int32 Width, int32 Height, uint32 SrcBpp, uint8* SrcData, TFunction SrcDataCleanup = [](uint8*) {});
74 |
75 | // Create a plain texture.
76 | // @param Name - The texture name
77 | // @param Width - The texture width
78 | // @param Height - The texture height
79 | // @param Color - The texture color
80 | // @returns The index of a texture that was created
81 | TextureIndex CreatePlainTexture(const FName& Name, int32 Width, int32 Height, FColor Color);
82 |
83 | // Create Slate resources to an existing texture, managed externally.
84 | // @param Name - The texture name
85 | // @param Texture - The texture
86 | // @returns The index to created/updated texture resources
87 | TextureIndex CreateTextureResources(const FName& Name, UTexture* Texture);
88 |
89 | // Release resources for given texture. Ignores invalid indices.
90 | // @param Index - The index of a texture resources
91 | void ReleaseTextureResources(TextureIndex Index);
92 |
93 | private:
94 |
95 | // See CreateTexture for general description.
96 | // Internal implementations doesn't validate name or resource uniqueness. Instead it uses NAME_ErrorTexture
97 | // (aka NAME_None) and INDEX_ErrorTexture (aka INDEX_NONE) to identify ErrorTexture.
98 | TextureIndex CreateTextureInternal(const FName& Name, int32 Width, int32 Height, uint32 SrcBpp, uint8* SrcData, TFunction SrcDataCleanup = [](uint8*) {});
99 |
100 | // See CreatePlainTexture for general description.
101 | // Internal implementations doesn't validate name or resource uniqueness. Instead it uses NAME_ErrorTexture
102 | // (aka NAME_None) and INDEX_ErrorTexture (aka INDEX_NONE) to identify ErrorTexture.
103 | TextureIndex CreatePlainTextureInternal(const FName& Name, int32 Width, int32 Height, const FColor& Color);
104 |
105 | // Add or reuse texture entry.
106 | // @param Name - The texture name
107 | // @param Texture - The texture
108 | // @param bAddToRoot - If true, we should add texture to root to prevent garbage collection (use for own textures)
109 | // @returns The index of the entry that we created or reused
110 | TextureIndex AddTextureEntry(const FName& Name, UTexture* Texture, bool bAddToRoot);
111 |
112 | // Check whether index is in range allocated for TextureResources (it doesn't mean that resources are valid).
113 | FORCEINLINE bool IsInRange(TextureIndex Index) const
114 | {
115 | return static_cast(Index) < static_cast(TextureResources.Num());
116 | }
117 |
118 | // Check whether index is in range and whether texture resources are valid (using NAME_None sentinel).
119 | FORCEINLINE bool IsValidTexture(TextureIndex Index) const
120 | {
121 | return IsInRange(Index) && TextureResources[Index].GetName() != NAME_None;
122 | }
123 |
124 | // Entry for texture resources. Only supports explicit construction.
125 | struct FTextureEntry
126 | {
127 | FTextureEntry() = default;
128 | FTextureEntry(const FName& InName, UTexture* InTexture, bool bAddToRoot);
129 | ~FTextureEntry();
130 |
131 | // Copying is not supported.
132 | FTextureEntry(const FTextureEntry&) = delete;
133 | FTextureEntry& operator=(const FTextureEntry&) = delete;
134 |
135 | // We rely on TArray and don't implement custom move constructor...
136 | FTextureEntry(FTextureEntry&&) = delete;
137 | // ... but we need move assignment to support reusing entries.
138 | FTextureEntry& operator=(FTextureEntry&& Other);
139 |
140 | const FName& GetName() const { return Name; }
141 | const FSlateResourceHandle& GetResourceHandle() const;
142 |
143 | private:
144 |
145 | void Reset(bool bReleaseResources);
146 |
147 | FName Name = NAME_None;
148 | mutable FSlateResourceHandle CachedResourceHandle;
149 | TWeakObjectPtr Texture;
150 | FSlateBrush Brush;
151 | };
152 |
153 | TArray TextureResources;
154 | FTextureEntry ErrorTexture;
155 |
156 | static constexpr EName NAME_ErrorTexture = NAME_None;
157 | static constexpr TextureIndex INDEX_ErrorTexture = INDEX_NONE;
158 | };
159 |
--------------------------------------------------------------------------------
/Source/ImGui/Public/ImGuiModule.h:
--------------------------------------------------------------------------------
1 | // Distributed under the MIT License (MIT) (see accompanying LICENSE file)
2 |
3 | #pragma once
4 |
5 | #include "ImGuiDelegates.h"
6 | #include "ImGuiModuleProperties.h"
7 | #include "ImGuiTextureHandle.h"
8 |
9 | #include
10 |
11 |
12 | class FImGuiModule : public IModuleInterface
13 | {
14 | public:
15 |
16 | /**
17 | * Singleton-like access to this module's interface. This is just for convenience!
18 | * Beware of calling this during the shutdown phase, though. Your module might have been unloaded already.
19 | *
20 | * @return Returns singleton instance, loading the module on demand if needed
21 | */
22 | static inline FImGuiModule& Get()
23 | {
24 | return FModuleManager::LoadModuleChecked("ImGui");
25 | }
26 |
27 | /**
28 | * Checks to see if this module is loaded and ready. It is only valid to call Get() if IsAvailable() returns true.
29 | *
30 | * @return True if the module is loaded and ready to use
31 | */
32 | static inline bool IsAvailable()
33 | {
34 | return FModuleManager::Get().IsModuleLoaded("ImGui");
35 | }
36 |
37 | #if IMGUI_WITH_OBSOLETE_DELEGATES
38 |
39 | #if WITH_EDITOR
40 | /**
41 | * Add a delegate called at the end of editor debug frame to draw debug controls in its ImGui context, creating
42 | * that context on demand.
43 | *
44 | * @param Delegate - Delegate that we want to add (@see FImGuiDelegate::Create...)
45 | * @returns Returns handle that can be used to remove delegate (@see RemoveImGuiDelegate)
46 | */
47 | virtual FImGuiDelegateHandle AddEditorImGuiDelegate(const FImGuiDelegate& Delegate);
48 | #endif
49 |
50 | /**
51 | * Add a delegate called at the end of current world debug frame to draw debug controls in its ImGui context,
52 | * creating that context on demand.
53 | * This function will throw if called outside of a world context (i.e. current world cannot be found).
54 | *
55 | * @param Delegate - Delegate that we want to add (@see FImGuiDelegate::Create...)
56 | * @returns Returns handle that can be used to remove delegate (@see RemoveImGuiDelegate)
57 | */
58 | virtual FImGuiDelegateHandle AddWorldImGuiDelegate(const FImGuiDelegate& Delegate);
59 |
60 | /**
61 | * Add a delegate called at the end of a specific world's debug frame to draw debug controls in its ImGui context,
62 | * creating that context on demand.
63 | *
64 | * @param World - A specific world to add the delegate to to
65 | * @param Delegate - Delegate that we want to add (@see FImGuiDelegate::Create...)
66 | * @returns Returns handle that can be used to remove delegate (@see RemoveImGuiDelegate)
67 | */
68 | virtual FImGuiDelegateHandle AddWorldImGuiDelegate(const UWorld* World, const FImGuiDelegate& Delegate);
69 |
70 | /**
71 | * Add shared delegate called for each ImGui context at the end of debug frame, after calling context specific
72 | * delegate. This delegate will be used for any ImGui context, created before or after it is registered.
73 | *
74 | * @param Delegate - Delegate that we want to add (@see FImGuiDelegate::Create...)
75 | * @returns Returns handle that can be used to remove delegate (@see RemoveImGuiDelegate)
76 | */
77 | virtual FImGuiDelegateHandle AddMultiContextImGuiDelegate(const FImGuiDelegate& Delegate);
78 |
79 | /**
80 | * Remove delegate added with any version of Add...ImGuiDelegate
81 | *
82 | * @param Handle - Delegate handle that was returned by adding function
83 | */
84 | virtual void RemoveImGuiDelegate(const FImGuiDelegateHandle& Handle);
85 |
86 | #endif // #if IMGUI_WITH_OBSOLETE_DELEGATES
87 |
88 | /**
89 | * If it exists, get a handle to the texture with given resource name.
90 | *
91 | * @param Name - Resource name of a texture to find
92 | * @returns Handle to a registered texture or invalid handle if resources could not be found or were not valid
93 | */
94 | virtual FImGuiTextureHandle FindTextureHandle(const FName& Name);
95 |
96 | /**
97 | * Register texture and create its Slate resources. If texture with that name already exists then it may be updated
98 | * or if bMakeUnique is true, exception will be thrown. Throws exception, if name argument is NAME_None or texture
99 | * is null.
100 | *
101 | * Note, that updating texture resources doesn't invalidate already existing handles and returned handle will have
102 | * the same value.
103 | *
104 | * @param Name - Resource name for the texture that needs to be registered or updated
105 | * @param Texture - Texture for which we want to create or update Slate resources
106 | * @param bMakeUnique - If false then existing resources are updated/overwritten (default). If true, then stricter
107 | * policy is applied and if resource with that name exists then exception is thrown.
108 | * @returns Handle to the texture resources, which can be used to release allocated resources and as an argument to
109 | * relevant ImGui functions
110 | */
111 | virtual FImGuiTextureHandle RegisterTexture(const FName& Name, class UTexture* Texture, bool bMakeUnique = false);
112 |
113 | /**
114 | * Unregister texture and release its Slate resources. If handle is null or not valid, this function fails silently
115 | * (for definition of 'valid' look @ FImGuiTextureHandle).
116 | *
117 | * @returns ImGui Texture Handle to texture that needs to be unregistered
118 | */
119 | virtual void ReleaseTexture(const FImGuiTextureHandle& Handle);
120 |
121 | virtual void RebuildFontAtlas();
122 |
123 | /**
124 | * Get ImGui module properties.
125 | *
126 | * @returns Reference to an instance of ImGui module properties that allows to read and/or modify module state.
127 | */
128 | virtual FImGuiModuleProperties& GetProperties();
129 | virtual const FImGuiModuleProperties& GetProperties() const;
130 |
131 | /**
132 | * DEPRECIATED: Please use GetProperties() as this function is scheduled for removal.
133 | * Check whether Input Mode is enabled (tests ImGui.InputEnabled console variable).
134 | *
135 | * @returns True, if Input Mode is enabled (ImGui.InputEnabled != 0) and false otherwise.
136 | */
137 | virtual bool IsInputMode() const;
138 |
139 | /**
140 | * DEPRECIATED: Please use GetProperties() as this function is scheduled for removal.
141 | * Set Input Mode state (sets ImGui.InputEnabled console variable, so it can be used together with a console).
142 | *
143 | * @param bEnabled - Whether Input Mode should be enabled (ImGui.InputEnabled = 1) or not (ImGui.InputEnabled = 0).
144 | */
145 | virtual void SetInputMode(bool bEnabled);
146 |
147 | /**
148 | * DEPRECIATED: Please use GetProperties() as this function is scheduled for removal.
149 | * Toggle Input Mode state (changes ImGui.InputEnabled console variable).
150 | */
151 | virtual void ToggleInputMode();
152 |
153 | /**
154 | * DEPRECIATED: Please use GetProperties() as this function is scheduled for removal.
155 | * Check whether ImGui Demo is shown (tests ImGui.ShowDemo console variable).
156 | *
157 | * @returns True, if demo is shown (ImGui.ShowDemo != 0) and false otherwise.
158 | */
159 | virtual bool IsShowingDemo() const;
160 |
161 | /**
162 | * DEPRECIATED: Please use GetProperties() as this function is scheduled for removal.
163 | * Set whether to show ImGui Demo (sets ImGui.ShowDemo console variable, so it can be used together with a console).
164 | *
165 | * @param bShow - Whether to show ImGui Demo (ImGui.ShowDemo = 1) or not (ImGui.ShowDemo = 0).
166 | */
167 | virtual void SetShowDemo(bool bShow);
168 |
169 | /**
170 | * DEPRECIATED: Please use GetProperties() as this function is scheduled for removal.
171 | * Toggle ImGui Demo (changes ImGui.ShowDemo console variable).
172 | */
173 | virtual void ToggleShowDemo();
174 |
175 | /** IModuleInterface implementation */
176 | virtual void StartupModule() override;
177 | virtual void ShutdownModule() override;
178 |
179 | private:
180 | #if WITH_EDITOR
181 | virtual void SetProperties(const FImGuiModuleProperties& Properties);
182 | struct FImGuiContextHandle* ImGuiContextHandle = nullptr;
183 | struct FImGuiDelegatesContainerHandle* DelegatesContainerHandle = nullptr;
184 | friend struct FImGuiContextHandle;
185 | friend struct FImGuiDelegatesContainerHandle;
186 | #endif
187 | };
188 |
--------------------------------------------------------------------------------
/Source/ImGui/Private/ImGuiModuleManager.cpp:
--------------------------------------------------------------------------------
1 | // Distributed under the MIT License (MIT) (see accompanying LICENSE file)
2 |
3 | #include "ImGuiModuleManager.h"
4 |
5 | #include "ImGuiInteroperability.h"
6 | #include "Utilities/WorldContextIndex.h"
7 |
8 | #include
9 | #include
10 |
11 | #include
12 |
13 |
14 | // High enough z-order guarantees that ImGui output is rendered on top of the game UI.
15 | constexpr int32 IMGUI_WIDGET_Z_ORDER = 10000;
16 |
17 | // Module texture names.
18 | const static FName PlainTextureName = "ImGuiModule_Plain";
19 | const static FName FontAtlasTextureName = "ImGuiModule_FontAtlas";
20 |
21 | FImGuiModuleManager::FImGuiModuleManager()
22 | : Commands(Properties)
23 | , Settings(Properties, Commands)
24 | , ImGuiDemo(Properties)
25 | , ContextManager(Settings)
26 | {
27 | // Register in context manager to get information whenever a new context proxy is created.
28 | ContextManager.OnContextProxyCreated.AddRaw(this, &FImGuiModuleManager::OnContextProxyCreated);
29 |
30 | // Typically we will use viewport created events to add widget to new game viewports.
31 | ViewportCreatedHandle = UGameViewportClient::OnViewportCreated().AddRaw(this, &FImGuiModuleManager::OnViewportCreated);
32 |
33 | // Try to register tick delegate (it may fail if Slate application isn't yet ready).
34 | RegisterTick();
35 |
36 | // If we failed to register, create an initializer that will do it later.
37 | if (!IsTickRegistered())
38 | {
39 | CreateTickInitializer();
40 | }
41 |
42 | // We need to add widgets to active game viewports as they won't generate on-created events. This is especially
43 | // important during hot-reloading.
44 | AddWidgetsToActiveViewports();
45 | }
46 |
47 | FImGuiModuleManager::~FImGuiModuleManager()
48 | {
49 | ContextManager.OnFontAtlasBuilt.RemoveAll(this);
50 |
51 | // We are no longer interested with adding widgets to viewports.
52 | if (ViewportCreatedHandle.IsValid())
53 | {
54 | UGameViewportClient::OnViewportCreated().Remove(ViewportCreatedHandle);
55 | ViewportCreatedHandle.Reset();
56 | }
57 |
58 | // Remove still active widgets (important during hot-reloading).
59 | for (auto& Widget : Widgets)
60 | {
61 | auto SharedWidget = Widget.Pin();
62 | if (SharedWidget.IsValid())
63 | {
64 | auto& WidgetGameViewport = SharedWidget->GetGameViewport();
65 | if (WidgetGameViewport.IsValid())
66 | {
67 | WidgetGameViewport->RemoveViewportWidgetContent(SharedWidget.ToSharedRef());
68 | }
69 | }
70 | }
71 |
72 | // Deactivate this manager.
73 | ReleaseTickInitializer();
74 | UnregisterTick();
75 | }
76 |
77 | void FImGuiModuleManager::RebuildFontAtlas()
78 | {
79 | ContextManager.RebuildFontAtlas();
80 | }
81 |
82 | void FImGuiModuleManager::LoadTextures()
83 | {
84 | checkf(FSlateApplication::IsInitialized(), TEXT("Slate should be initialized before we can create textures."));
85 |
86 | if (!bTexturesLoaded)
87 | {
88 | bTexturesLoaded = true;
89 |
90 | TextureManager.InitializeErrorTexture(FColor::Magenta);
91 |
92 | // Create an empty texture at index 0. We will use it for ImGui outputs with null texture id.
93 | TextureManager.CreatePlainTexture(PlainTextureName, 2, 2, FColor::White);
94 |
95 | // Register for atlas built events, so we can rebuild textures.
96 | ContextManager.OnFontAtlasBuilt.AddRaw(this, &FImGuiModuleManager::BuildFontAtlasTexture);
97 |
98 | BuildFontAtlasTexture();
99 | }
100 | }
101 |
102 | void FImGuiModuleManager::BuildFontAtlasTexture()
103 | {
104 | // Create a font atlas texture.
105 | ImFontAtlas& Fonts = ContextManager.GetFontAtlas();
106 |
107 | unsigned char* Pixels;
108 | int Width, Height, Bpp;
109 | Fonts.GetTexDataAsRGBA32(&Pixels, &Width, &Height, &Bpp);
110 |
111 | const TextureIndex FontsTexureIndex = TextureManager.CreateTexture(FontAtlasTextureName, Width, Height, Bpp, Pixels);
112 |
113 | // Set the font texture index in the ImGui.
114 | Fonts.TexID = ImGuiInterops::ToImTextureID(FontsTexureIndex);
115 | }
116 |
117 | void FImGuiModuleManager::RegisterTick()
118 | {
119 | // Slate Post-Tick is a good moment to end and advance ImGui frame as it minimises a tearing.
120 | if (!TickDelegateHandle.IsValid() && FSlateApplication::IsInitialized())
121 | {
122 | TickDelegateHandle = FSlateApplication::Get().OnPostTick().AddRaw(this, &FImGuiModuleManager::Tick);
123 | }
124 | }
125 |
126 | void FImGuiModuleManager::UnregisterTick()
127 | {
128 | if (TickDelegateHandle.IsValid())
129 | {
130 | if (FSlateApplication::IsInitialized())
131 | {
132 | FSlateApplication::Get().OnPostTick().Remove(TickDelegateHandle);
133 | }
134 | TickDelegateHandle.Reset();
135 | }
136 | }
137 |
138 | void FImGuiModuleManager::CreateTickInitializer()
139 | {
140 | if (!TickInitializerHandle.IsValid())
141 | {
142 | // Try to register tick delegate until we finally succeed.
143 |
144 | TickInitializerHandle = FModuleManager::Get().OnModulesChanged().AddLambda([this](FName Name, EModuleChangeReason Reason)
145 | {
146 | if (Reason == EModuleChangeReason::ModuleLoaded)
147 | {
148 | RegisterTick();
149 | }
150 |
151 | if (IsTickRegistered())
152 | {
153 | ReleaseTickInitializer();
154 | }
155 | });
156 | }
157 | }
158 |
159 | void FImGuiModuleManager::ReleaseTickInitializer()
160 | {
161 | if (TickInitializerHandle.IsValid())
162 | {
163 | FModuleManager::Get().OnModulesChanged().Remove(TickInitializerHandle);
164 | TickInitializerHandle.Reset();
165 | }
166 | }
167 |
168 | void FImGuiModuleManager::Tick(float DeltaSeconds)
169 | {
170 | if (IsInGameThread())
171 | {
172 | // Update context manager to advance all ImGui contexts to the next frame.
173 | ContextManager.Tick(DeltaSeconds);
174 |
175 | // Inform that we finished updating ImGui, so other subsystems can react.
176 | PostImGuiUpdateEvent.Broadcast();
177 | }
178 | }
179 |
180 | void FImGuiModuleManager::OnViewportCreated()
181 | {
182 | checkf(FSlateApplication::IsInitialized(), TEXT("We expect Slate to be initialized when game viewport is created."));
183 |
184 | // Create widget to viewport responsible for this event.
185 | AddWidgetToViewport(GEngine->GameViewport);
186 | }
187 |
188 | void FImGuiModuleManager::AddWidgetToViewport(UGameViewportClient* GameViewport)
189 | {
190 | checkf(GameViewport, TEXT("Null game viewport."));
191 | checkf(FSlateApplication::IsInitialized(), TEXT("Slate should be initialized before we can add widget to game viewports."));
192 |
193 | // Make sure that we have a context for this viewport's world and get its index.
194 | int32 ContextIndex;
195 | auto& ContextProxy = ContextManager.GetWorldContextProxy(*GameViewport->GetWorld(), ContextIndex);
196 |
197 | // Make sure that textures are loaded before the first Slate widget is created.
198 | LoadTextures();
199 |
200 | // Create and initialize the widget.
201 | TSharedPtr SharedWidget;
202 | SAssignNew(SharedWidget, SImGuiLayout).ModuleManager(this).GameViewport(GameViewport).ContextIndex(ContextIndex);
203 |
204 | GameViewport->AddViewportWidgetContent(SharedWidget.ToSharedRef(), IMGUI_WIDGET_Z_ORDER);
205 |
206 | // We transfer widget ownerships to viewports but we keep weak references in case we need to manually detach active
207 | // widgets during module shutdown (important during hot-reloading).
208 | if (TWeakPtr* Slot = Widgets.FindByPredicate([](auto& Widget) { return !Widget.IsValid(); }))
209 | {
210 | *Slot = SharedWidget;
211 | }
212 | else
213 | {
214 | Widgets.Emplace(SharedWidget);
215 | }
216 | }
217 |
218 | void FImGuiModuleManager::AddWidgetsToActiveViewports()
219 | {
220 | if (FSlateApplication::IsInitialized() && GEngine)
221 | {
222 | // Loop as long as we have a valid viewport or until we detect a cycle.
223 | UGameViewportClient* GameViewport = GEngine->GameViewport;
224 | while (GameViewport)
225 | {
226 | AddWidgetToViewport(GameViewport);
227 |
228 | GameViewport = GEngine->GetNextPIEViewport(GameViewport);
229 | if (GameViewport == GEngine->GameViewport)
230 | {
231 | break;
232 | }
233 | }
234 | }
235 | }
236 |
237 | void FImGuiModuleManager::OnContextProxyCreated(int32 ContextIndex, FImGuiContextProxy& ContextProxy)
238 | {
239 | ContextProxy.OnDraw().AddLambda([this, ContextIndex]() { ImGuiDemo.DrawControls(ContextIndex); });
240 | }
241 |
--------------------------------------------------------------------------------
/Source/ImGui/Private/ImGuiContextProxy.cpp:
--------------------------------------------------------------------------------
1 | // Distributed under the MIT License (MIT) (see accompanying LICENSE file)
2 |
3 | #include "ImGuiContextProxy.h"
4 |
5 | #include "ImGuiDelegatesContainer.h"
6 | #include "ImGuiImplementation.h"
7 | #include "ImGuiInteroperability.h"
8 | #include "Utilities/Arrays.h"
9 | #include "VersionCompatibility.h"
10 |
11 | #include
12 | #include
13 |
14 |
15 | static constexpr float DEFAULT_CANVAS_WIDTH = 3840.f;
16 | static constexpr float DEFAULT_CANVAS_HEIGHT = 2160.f;
17 |
18 |
19 | namespace
20 | {
21 | FString GetSaveDirectory()
22 | {
23 | #if ENGINE_COMPATIBILITY_LEGACY_SAVED_DIR
24 | const FString SavedDir = FPaths::GameSavedDir();
25 | #else
26 | const FString SavedDir = FPaths::ProjectSavedDir();
27 | #endif
28 |
29 | FString Directory = FPaths::Combine(*SavedDir, TEXT("ImGui"));
30 |
31 | // Make sure that directory is created.
32 | IPlatformFile::GetPlatformPhysical().CreateDirectory(*Directory);
33 |
34 | return Directory;
35 | }
36 |
37 | FString GetIniFile(const FString& Name)
38 | {
39 | static FString SaveDirectory = GetSaveDirectory();
40 | return FPaths::Combine(SaveDirectory, Name + TEXT(".ini"));
41 | }
42 |
43 | struct FGuardCurrentContext
44 | {
45 | FGuardCurrentContext()
46 | : OldContext(ImGui::GetCurrentContext())
47 | {
48 | }
49 |
50 | ~FGuardCurrentContext()
51 | {
52 | if (bRestore)
53 | {
54 | ImGui::SetCurrentContext(OldContext);
55 | }
56 | }
57 |
58 | FGuardCurrentContext(FGuardCurrentContext&& Other)
59 | : OldContext(MoveTemp(Other.OldContext))
60 | {
61 | Other.bRestore = false;
62 | }
63 |
64 | FGuardCurrentContext& operator=(FGuardCurrentContext&&) = delete;
65 |
66 | FGuardCurrentContext(const FGuardCurrentContext&) = delete;
67 | FGuardCurrentContext& operator=(const FGuardCurrentContext&) = delete;
68 |
69 | private:
70 |
71 | ImGuiContext* OldContext = nullptr;
72 | bool bRestore = true;
73 | };
74 | }
75 |
76 | FImGuiContextProxy::FImGuiContextProxy(const FString& InName, int32 InContextIndex, ImFontAtlas* InFontAtlas, float InDPIScale)
77 | : Name(InName)
78 | , ContextIndex(InContextIndex)
79 | , IniFilename(TCHAR_TO_ANSI(*GetIniFile(InName)))
80 | {
81 | // Create context.
82 | Context = ImGui::CreateContext(InFontAtlas);
83 |
84 | // Set this context in ImGui for initialization (any allocations will be tracked in this context).
85 | SetAsCurrent();
86 |
87 | // Start initialization.
88 | ImGuiIO& IO = ImGui::GetIO();
89 |
90 | // Set session data storage.
91 | IO.IniFilename = IniFilename.c_str();
92 |
93 | // Start with the default canvas size.
94 | ResetDisplaySize();
95 | IO.DisplaySize = {(float)DisplaySize.X, (float)DisplaySize.Y};
96 |
97 | // Set the initial DPI scale.
98 | SetDPIScale(InDPIScale);
99 |
100 | // Initialize key mapping, so context can correctly interpret input state.
101 | ImGuiInterops::SetUnrealKeyMap(IO);
102 |
103 | // Begin frame to complete context initialization (this is to avoid problems with other systems calling to ImGui
104 | // during startup).
105 | BeginFrame();
106 | }
107 |
108 | FImGuiContextProxy::~FImGuiContextProxy()
109 | {
110 | if (Context)
111 | {
112 | // It seems that to properly shutdown context we need to set it as the current one (at least in this framework
113 | // version), even though we can pass it to the destroy function.
114 | SetAsCurrent();
115 |
116 | // Save context data and destroy.
117 | ImGui::DestroyContext(Context);
118 | }
119 | }
120 |
121 | void FImGuiContextProxy::ResetDisplaySize()
122 | {
123 | DisplaySize = { DEFAULT_CANVAS_WIDTH, DEFAULT_CANVAS_HEIGHT };
124 | }
125 |
126 | void FImGuiContextProxy::SetDPIScale(float Scale)
127 | {
128 | if (DPIScale != Scale)
129 | {
130 | DPIScale = Scale;
131 |
132 | ImGuiStyle NewStyle = ImGuiStyle();
133 | NewStyle.ScaleAllSizes(Scale);
134 |
135 | FGuardCurrentContext GuardContext;
136 | SetAsCurrent();
137 | ImGui::GetStyle() = MoveTemp(NewStyle);
138 | }
139 | }
140 |
141 | void FImGuiContextProxy::DrawEarlyDebug()
142 | {
143 | if (bIsFrameStarted && !bIsDrawEarlyDebugCalled)
144 | {
145 | bIsDrawEarlyDebugCalled = true;
146 |
147 | SetAsCurrent();
148 |
149 | // Delegates called in order specified in FImGuiDelegates.
150 | BroadcastMultiContextEarlyDebug();
151 | BroadcastWorldEarlyDebug();
152 | }
153 | }
154 |
155 | void FImGuiContextProxy::DrawDebug()
156 | {
157 | if (bIsFrameStarted && !bIsDrawDebugCalled)
158 | {
159 | bIsDrawDebugCalled = true;
160 |
161 | // Make sure that early debug is always called first to guarantee order specified in FImGuiDelegates.
162 | DrawEarlyDebug();
163 |
164 | SetAsCurrent();
165 |
166 | // Delegates called in order specified in FImGuiDelegates.
167 | BroadcastWorldDebug();
168 | BroadcastMultiContextDebug();
169 | }
170 | }
171 |
172 | void FImGuiContextProxy::Tick(float DeltaSeconds)
173 | {
174 | // Making sure that we tick only once per frame.
175 | if (LastFrameNumber < GFrameNumber)
176 | {
177 | LastFrameNumber = GFrameNumber;
178 |
179 | SetAsCurrent();
180 |
181 | if (bIsFrameStarted)
182 | {
183 | // Make sure that draw events are called before the end of the frame.
184 | DrawDebug();
185 |
186 | // Ending frame will produce render output that we capture and store for later use. This also puts context to
187 | // state in which it does not allow to draw controls, so we want to immediately start a new frame.
188 | EndFrame();
189 | }
190 |
191 | // Update context information (some data need to be collected before starting a new frame while some other data
192 | // may need to be collected after).
193 | bHasActiveItem = ImGui::IsAnyItemActive();
194 | MouseCursor = ImGuiInterops::ToSlateMouseCursor(ImGui::GetMouseCursor());
195 |
196 | // Begin a new frame and set the context back to a state in which it allows to draw controls.
197 | BeginFrame(DeltaSeconds);
198 |
199 | // Update remaining context information.
200 | bWantsMouseCapture = ImGui::GetIO().WantCaptureMouse;
201 | }
202 | }
203 |
204 | void FImGuiContextProxy::BeginFrame(float DeltaTime)
205 | {
206 | if (!bIsFrameStarted)
207 | {
208 | ImGuiIO& IO = ImGui::GetIO();
209 | IO.DeltaTime = DeltaTime;
210 |
211 | ImGuiInterops::CopyInput(IO, InputState);
212 | InputState.ClearUpdateState();
213 |
214 | IO.DisplaySize = { (float)DisplaySize.X, (float)DisplaySize.Y };
215 |
216 | ImGui::NewFrame();
217 |
218 | bIsFrameStarted = true;
219 | bIsDrawEarlyDebugCalled = false;
220 | bIsDrawDebugCalled = false;
221 | }
222 | }
223 |
224 | void FImGuiContextProxy::EndFrame()
225 | {
226 | if (bIsFrameStarted)
227 | {
228 | // Prepare draw data (after this call we cannot draw to this context until we start a new frame).
229 | ImGui::Render();
230 |
231 | // Update our draw data, so we can use them later during Slate rendering while ImGui is in the middle of the
232 | // next frame.
233 | UpdateDrawData(ImGui::GetDrawData());
234 |
235 | bIsFrameStarted = false;
236 | }
237 | }
238 |
239 | void FImGuiContextProxy::UpdateDrawData(ImDrawData* DrawData)
240 | {
241 | if (DrawData && DrawData->CmdListsCount > 0)
242 | {
243 | DrawLists.SetNum(DrawData->CmdListsCount, false);
244 |
245 | for (int Index = 0; Index < DrawData->CmdListsCount; Index++)
246 | {
247 | DrawLists[Index].TransferDrawData(*DrawData->CmdLists[Index]);
248 | }
249 | }
250 | else
251 | {
252 | // If we are not rendering then this might be a good moment to empty the array.
253 | DrawLists.Empty();
254 | }
255 | }
256 |
257 | void FImGuiContextProxy::BroadcastWorldEarlyDebug()
258 | {
259 | if (ContextIndex != Utilities::INVALID_CONTEXT_INDEX)
260 | {
261 | FSimpleMulticastDelegate& WorldEarlyDebugEvent = FImGuiDelegatesContainer::Get().OnWorldEarlyDebug(ContextIndex);
262 | if (WorldEarlyDebugEvent.IsBound())
263 | {
264 | WorldEarlyDebugEvent.Broadcast();
265 | }
266 | }
267 | }
268 |
269 | void FImGuiContextProxy::BroadcastMultiContextEarlyDebug()
270 | {
271 | FSimpleMulticastDelegate& MultiContextEarlyDebugEvent = FImGuiDelegatesContainer::Get().OnMultiContextEarlyDebug();
272 | if (MultiContextEarlyDebugEvent.IsBound())
273 | {
274 | MultiContextEarlyDebugEvent.Broadcast();
275 | }
276 | }
277 |
278 | void FImGuiContextProxy::BroadcastWorldDebug()
279 | {
280 | if (DrawEvent.IsBound())
281 | {
282 | DrawEvent.Broadcast();
283 | }
284 |
285 | if (ContextIndex != Utilities::INVALID_CONTEXT_INDEX)
286 | {
287 | FSimpleMulticastDelegate& WorldDebugEvent = FImGuiDelegatesContainer::Get().OnWorldDebug(ContextIndex);
288 | if (WorldDebugEvent.IsBound())
289 | {
290 | WorldDebugEvent.Broadcast();
291 | }
292 | }
293 | }
294 |
295 | void FImGuiContextProxy::BroadcastMultiContextDebug()
296 | {
297 | FSimpleMulticastDelegate& MultiContextDebugEvent = FImGuiDelegatesContainer::Get().OnMultiContextDebug();
298 | if (MultiContextDebugEvent.IsBound())
299 | {
300 | MultiContextDebugEvent.Broadcast();
301 | }
302 | }
303 |
--------------------------------------------------------------------------------
/CHANGES.md:
--------------------------------------------------------------------------------
1 | This is only a summary provided to give a quick overview of changes. It does not list details which can be found in commit messages. If you think that more detailed changelog would be beneficiary, please raise it as an issue.
2 |
3 | Versions marked as 'unofficial' are labelled only for the needs of this changelog. Officially I maintain version numbers since 2019/04, starting from version 1.14. If you have any of the earlier commits then you will see plugin signed as a version 1.0.
4 |
5 | Change History
6 | --------------
7 |
8 | Version: 1.22 (2021/04)
9 | - Fixed potential for initialization fiasco when using delegates container.
10 | - Fixed bug in code protecting redirecting handles from self-referencing.
11 | - Fixed cached resource handles getting invalid after reloading texture resources.
12 |
13 | Version: 1.21 (2020/07-09)
14 | Improving stability
15 | - Fixed a crash in the input handler caused by invalidated by hot-reload instance trying to unregister a delegate.
16 | - Improved hot-reload stability and support for reloading after recompiling outside of the editor. Both methods should be equally supported and work together.
17 | - Improved behaviour of delegates when hot-reloading.
18 | - Changed context index mapping to fix issues with multi-PIE debugging in 4.25.
19 | - Fixed Linux crash caused by wrong mapping of key codes.
20 |
21 | Version: 1.20 (2020/06)
22 | Transition to IWYU and maintenance:
23 | - Replaced includes of monolithic headers.
24 | - Removed explicit PCH and switched to IWYU-style PCH model.
25 | - Fixed includes to compile without explicit PCH in non-unity mode.
26 | - Fixed a few issues causing compilation errors in older engine versions.
27 | - Fixed debug code to compile on platforms using other than char or wchar_t characters.
28 | - Fixed issues in recently added DPI scaling.
29 | - Cleaned obsolete and unused code.
30 | - Replaced custom scope guards with the template provided by the engine.
31 |
32 | Version: 1.19 (2020/03-06)
33 | - Integrated fix for issue with ImGui popup/modal windows not being able to be closed in transparent mouse input mode.
34 | - Integrated first version of Adaptive Canvas Size.
35 | - Added different options to define canvas size, with Adaptive Canvas Size being one of the options (viewport).
36 | - Added option for DPI scaling.
37 |
38 | Version: 1.18 (2020/01)
39 | - Updated to engine version 4.24.
40 | - Updated to ImGui version 1.74.
41 |
42 | Version: 1.17 (2019/04)
43 | - Added experimental support for touch input.
44 | - Integrated fixes allowing to build this as an engine plugin:
45 | - Added support for sharing with game mouse input.
46 | - Refactorization of input handling, with changes in SImGuiWidget and compatibility breaking changes in UImGuiInputHandler.
47 |
48 | Version: 1.16 (2019/05)
49 | - Fixed issue with SImGuiLayout blocking mouse input for other Slate widgets, which was introduced by refactorization of widgets (version 1.14, commit c144658f).
50 |
51 | Version: 1.15 (2019/04)
52 | - Added new FImGuiDelegates interface for ImGui debug delegates.
53 | - Added code preserving delegates during hot-reloading and moving them to a new module.
54 | - DEPRECIATED old FImGuiModule delegates interface and FImGuiDelegateHandle.
55 | - Delegates registered with depreciated interface are redirected and get benefit of being preserved during hot-reloading. This can be controlled with IMGUI_REDIRECT_OBSOLETE_DELEGATES.
56 | - Added IMGUI_WITH_OBSOLETE_DELEGATES allowing to strip depreciated interface from builds (that interface will be officially removed in one of later releases).
57 | - Added new ImGui early debug delegates called during world tick start.
58 | - Delegates are called in fixed order: multi-context early debug, world early debug (called during world tick start), world debug, multi-context debug (called during world post actor tick or if not available, during world tick start).
59 | - Removed from build script configuration of debug delegates.
60 |
61 | Version: 1.14 (2019/03)
62 | - Added SImGuiLayout to resets layout for SImGuiWidget.
63 | - Refactored rendering in SImGuiWidget to take advantage of layout reset.
64 | - Reworked ImGui canvas dragging and scaling and moved it to SImGuiCanvasControl.
65 | - Removed dependency on ImGui internal cursor data.
66 |
67 | Version: 1.13 (unofficial) (2019/03)
68 | - Fixed mapping from FKey to ImGui key index to gracefully handle unsupported keys and work on platforms that do not support all the keys defined in ImGui key map.
69 | - Fixed non-unity compile warnings and errors.
70 |
71 | Version: 1.12 (unofficial) (2018/12)
72 | - Added support for sharing with game keyboard and gamepad input.
73 | - Added FImGuiModuleSettings to handle delayed loading of UImGuiSettings and serve as settings proxy for other classes.
74 |
75 | Version: 1.11 (unofficial) (2018/10-11)
76 | - Moved ImGui Draw events to be called at the end of the world update during post actor tick event. Only available in UE 4.18 or later, with old behaviour available as an option.
77 | - Replaced console variable based configuration of ImGui Draw events with macros.
78 | - Replaced console variable based configuration of software cursor with a setting.
79 | - Console variables and logging that are primarily focused on module development are hidden by default and can be enabled by setting IMGUI_MODULE_DEVELOPER to 1.
80 | - Replaced console variables with module properties and settings.
81 | - Added console commands to control module properties.
82 | - Added support to preserve and move module properties to hot-reloaded module.
83 | - Moved properties to public interface.
84 | - Added FImGuiModule interface to access properties instance.
85 | - DEPRECIATED FImGuiModule functions to modify single properties.
86 |
87 | Version: 1.10 (unofficial) (2018/10)
88 | - Changed module type to 'Developer' to make it easier strip it from shipping or other builds.
89 | - Added runtime loader to allow automatically load developer module in runtime builds.
90 |
91 | Version: 1.09 (unofficial) (2018/08-09)
92 | - Added interface to register user textures for use in ImGui.
93 | - Fixed bad deallocation in Texture Manager.
94 | - Updated to ImGui 1.61.
95 | - Updated to UE 4.20.
96 |
97 | Version: 1.08 (unofficial) (2018/07-08)
98 | - Added ImGui Input Handler to allow to customization of input handling.
99 | - Added ImGui settings with editor page in project properties.
100 | - Added command to switch input mode with configurable key binding.
101 | - Added backward compatibility macros.
102 | - Fixed hot-reloading issues with using ImGui implementation.
103 |
104 | Version: 1.07 (unofficial) (2018/05)
105 | - Improved initialization to allow loading module in any loading phase.
106 |
107 | Version: 1.06 (unofficial) (2018/05)
108 | - Updated to ImGui 1.61
109 | - Added support for gamepad and keyboard navigation.
110 |
111 | Version: 1.05 (unofficial) (2018/04)
112 | - Added mode to scale and drag ImGui canvas.
113 | - Using ImGui internal cursor data to draw drag icon.
114 |
115 | Version: 1.04 (unofficial) (2018/03)
116 | - Minimised lag between ending ImGui frame and rendering draw data in Slate.
117 | - Moved ImGui Draw event to be called during world tick start with configuration to use old behaviour.
118 |
119 | Version: 1.03 (unofficial) (2018/01-03)
120 | - Fixed warnings and errors found in non-unity, Linux, PS4 or XBox builds.
121 | - Added configuration to choose between hardware and software cursor with hardware cursor used by default.
122 |
123 | Version: 1.02 (unofficial) (2018/01)
124 | - Updated to ImGui 1.53.
125 | - Fixed problems with ImGui Demo working in multi-context environment.
126 | - Added FImGuiModule interface to change input mode and demo visibility.
127 | - Fixed input state issues after application loses focus.
128 | - Added input state debugging and `ImGui.Debug.Input` console variable to switch it.
129 |
130 | Version: 1.01 (unofficial) (2017/10)
131 | - Added `ImGui.ShowDemo` console variable to show/hide ImGui demo.
132 | - Added automatic switching to right ImGui context at the beginning of the world tick.
133 | - Updated to UE 4.18
134 |
135 | Version: <=1.00 (unofficial) (2017/04-10)
136 | - Added ImGui source code as an external module to expose it in IDE.
137 | - Integrated ImGui source code to build as part of the ImGui module.
138 | - Added FImGuiModule to implement ImGui module interface.
139 | - Added FImGuiModuleManager to control other module components.
140 | - Added FTextureManager to manage texture resources and map them to ImTextureID.
141 | - Added SImGuiWidget to handle Slate input and render in Slate ImGui draw data.
142 | - Added FImGuiInputState to collect and store input before it can be copied to ImGui IO.
143 | - Added FContextProxy to represent a single ImGui context.
144 | - Added FImGuiContextManager to create and manage ImGui context proxies.
145 | - Added Multi-PIE support with each PIE instance getting a dedicated ImGui context proxy, input state and widget.
146 | - Added `ImGui.InputEnabled` console variable to control whether input mode is enabled.
147 | - Added widget debugging and `ImGui.Debug.Widget` console variable to switch it.
148 | - Added ImGui software cursor.
149 | - Added support for session reloading with ini file names based on world type and PIE index.
150 | - Added FImGuiModule interface to register ImGui delegates called to draw ImGui controls.
151 |
--------------------------------------------------------------------------------
/Source/ThirdParty/ImGuiLibrary/Docs/BACKENDS.md:
--------------------------------------------------------------------------------
1 | _(You may browse this at https://github.com/ocornut/imgui/blob/master/docs/BACKENDS.md or view this file with any Markdown viewer)_
2 |
3 | ## Dear ImGui: Backends
4 |
5 | **The backends/ folder contains backends for popular platforms/graphics API, which you can use in
6 | your application or engine to easily integrate Dear ImGui.** Each backend is typically self-contained in a pair of files: imgui_impl_XXXX.cpp + imgui_impl_XXXX.h.
7 |
8 | - The 'Platform' backends are in charge of: mouse/keyboard/gamepad inputs, cursor shape, timing, windowing.
9 | e.g. Windows ([imgui_impl_win32.cpp](https://github.com/ocornut/imgui/blob/master/backends/imgui_impl_win32.cpp)), GLFW ([imgui_impl_glfw.cpp](https://github.com/ocornut/imgui/blob/master/backends/imgui_impl_glfw.cpp)), SDL2 ([imgui_impl_sdl.cpp](https://github.com/ocornut/imgui/blob/master/backends/imgui_impl_sdl.cpp)), etc.
10 |
11 | - The 'Renderer' backends are in charge of: creating atlas texture, rendering imgui draw data.
12 | e.g. DirectX11 ([imgui_impl_dx11.cpp](https://github.com/ocornut/imgui/blob/master/backends/imgui_impl_dx11.cpp)), OpenGL/WebGL ([imgui_impl_opengl3.cpp](https://github.com/ocornut/imgui/blob/master/backends/imgui_impl_opengl3.cpp)), Vulkan ([imgui_impl_vulkan.cpp](https://github.com/ocornut/imgui/blob/master/backends/imgui_impl_vulkan.cpp)), etc.
13 |
14 | - For some high-level frameworks, a single backend usually handle both 'Platform' and 'Renderer' parts.
15 | e.g. Allegro 5 ([imgui_impl_allegro5.cpp](https://github.com/ocornut/imgui/blob/master/backends/imgui_impl_allegro5.cpp)). If you end up creating a custom backend for your engine, you may want to do the same.
16 |
17 | An application usually combines 1 Platform backend + 1 Renderer backend + main Dear ImGui sources.
18 | For example, the [example_win32_directx11](https://github.com/ocornut/imgui/tree/master/examples/example_win32_directx11) application combines imgui_impl_win32.cpp + imgui_impl_dx11.cpp. There are 20+ examples in the [examples/](https://github.com/ocornut/imgui/blob/master/examples/) folder. See [EXAMPLES.MD](https://github.com/ocornut/imgui/blob/master/docs/EXAMPLES.md) for details.
19 |
20 | **Once Dear ImGui is setup and running, run and refer to `ImGui::ShowDemoWindow()` in imgui_demo.cpp for usage of the end-user API.**
21 |
22 |
23 | ### What are backends
24 |
25 | Dear ImGui is highly portable and only requires a few things to run and render, typically:
26 |
27 | - Required: providing mouse/keyboard inputs (fed into the `ImGuiIO` structure).
28 | - Required: uploading the font atlas texture into graphics memory.
29 | - Required: rendering indexed textured triangles with a clipping rectangle.
30 |
31 | Extra features are opt-in, our backends try to support as many as possible:
32 |
33 | - Optional: custom texture binding support.
34 | - Optional: clipboard support.
35 | - Optional: gamepad support.
36 | - Optional: mouse cursor shape support.
37 | - Optional: IME support.
38 | - Optional: multi-viewports support.
39 | etc.
40 |
41 | This is essentially what each backend is doing + obligatory portability cruft. Using default backends ensure you can get all those features including the ones that would be harder to implement on your side (e.g. multi-viewports support).
42 |
43 | It is important to understand the difference between the core Dear ImGui library (files in the root folder)
44 | and backends which we are describing here (backends/ folder).
45 |
46 | - Some issues may only be backend or platform specific.
47 | - You should be able to write backends for pretty much any platform and any 3D graphics API.
48 | e.g. you can get creative and use software rendering or render remotely on a different machine.
49 |
50 |
51 | ### Integrating a backend
52 |
53 | See "Getting Started" section of [EXAMPLES.MD](https://github.com/ocornut/imgui/blob/master/docs/EXAMPLES.md) for more details.
54 |
55 |
56 | ### List of backends
57 |
58 | In the [backends/](https://github.com/ocornut/imgui/blob/master/backends) folder:
59 |
60 | List of Platforms Backends:
61 |
62 | imgui_impl_android.cpp ; Android native app API
63 | imgui_impl_glfw.cpp ; GLFW (Windows, macOS, Linux, etc.) http://www.glfw.org/
64 | imgui_impl_osx.mm ; macOS native API (not as feature complete as glfw/sdl backends)
65 | imgui_impl_sdl.cpp ; SDL2 (Windows, macOS, Linux, iOS, Android) https://www.libsdl.org
66 | imgui_impl_win32.cpp ; Win32 native API (Windows)
67 | imgui_impl_glut.cpp ; GLUT/FreeGLUT (this is prehistoric software and absolutely not recommended today!)
68 |
69 | List of Renderer Backends:
70 |
71 | imgui_impl_dx9.cpp ; DirectX9
72 | imgui_impl_dx10.cpp ; DirectX10
73 | imgui_impl_dx11.cpp ; DirectX11
74 | imgui_impl_dx12.cpp ; DirectX12
75 | imgui_impl_metal.mm ; Metal (with ObjC)
76 | imgui_impl_opengl2.cpp ; OpenGL 2 (legacy, fixed pipeline <- don't use with modern OpenGL context)
77 | imgui_impl_opengl3.cpp ; OpenGL 3/4, OpenGL ES 2, OpenGL ES 3 (modern programmable pipeline)
78 | imgui_impl_sdlrenderer.cpp; SDL_Renderer (optional component of SDL2 available from SDL 2.0.18+)
79 | imgui_impl_vulkan.cpp ; Vulkan
80 | imgui_impl_wgpu.cpp ; WebGPU
81 |
82 | List of high-level Frameworks Backends (combining Platform + Renderer):
83 |
84 | imgui_impl_allegro5.cpp
85 |
86 | Emscripten is also supported.
87 | The [example_emscripten_opengl3](https://github.com/ocornut/imgui/tree/master/examples/example_emscripten_opengl3) app uses imgui_impl_sdl.cpp + imgui_impl_opengl3.cpp, but other combos are possible.
88 |
89 | ### Backends for third-party frameworks, graphics API or other languages
90 |
91 | See https://github.com/ocornut/imgui/wiki/Bindings for the full list (e.g. Adventure Game Studio, Cinder, Cocos2d-x, Game Maker Studio2, Godot, LÖVE+LUA, Magnum, Monogame, Ogre, openFrameworks, OpenSceneGraph, SFML, Sokol, Unity, Unreal Engine and many others).
92 |
93 | ### Recommended Backends
94 |
95 | If you are not sure which backend to use, the recommended platform/frameworks for portable applications:
96 |
97 | |Library |Website |Backend |Note |
98 | |--------|--------|--------|-----|
99 | | GLFW | https://github.com/glfw/glfw | imgui_impl_glfw.cpp | |
100 | | SDL2 | https://www.libsdl.org | imgui_impl_sdl.cpp | |
101 | | Sokol | https://github.com/floooh/sokol | [util/sokol_imgui.h](https://github.com/floooh/sokol/blob/master/util/sokol_imgui.h) | Lower-level than GLFW/SDL |
102 |
103 |
104 | ### Using a custom engine?
105 |
106 | You will likely be tempted to start by rewrite your own backend using your own custom/high-level facilities...
107 | Think twice!
108 |
109 | If you are new to Dear ImGui, first try using the existing backends as-is.
110 | You will save lots of time integrating the library.
111 | You can LATER decide to rewrite yourself a custom backend if you really need to.
112 | In most situations, custom backends have less features and more bugs than the standard backends we provide.
113 | If you want portability, you can use multiple backends and choose between them either at compile time
114 | or at runtime.
115 |
116 | **Example A**: your engine is built over Windows + DirectX11 but you have your own high-level rendering
117 | system layered over DirectX11.
118 | Suggestion: try using imgui_impl_win32.cpp + imgui_impl_dx11.cpp first.
119 | Once it works, if you really need it you can replace the imgui_impl_dx11.cpp code with a
120 | custom renderer using your own rendering functions, and keep using the standard Win32 code etc.
121 |
122 | **Example B**: your engine runs on Windows, Mac, Linux and uses DirectX11, Metal, Vulkan respectively.
123 | Suggestion: use multiple generic backends!
124 | Once it works, if you really need it you can replace parts of backends with your own abstractions.
125 |
126 | **Example C**: your engine runs on platforms we can't provide public backends for (e.g. PS4/PS5, Switch),
127 | and you have high-level systems everywhere.
128 | Suggestion: try using a non-portable backend first (e.g. win32 + underlying graphics API) to get
129 | your desktop builds working first. This will get you running faster and get your acquainted with
130 | how Dear ImGui works and is setup. You can then rewrite a custom backend using your own engine API...
131 |
132 | Generally:
133 | It is unlikely you will add value to your project by creating your own backend.
134 |
135 | Also:
136 | The [multi-viewports feature](https://github.com/ocornut/imgui/issues/1542) of the 'docking' branch allows
137 | Dear ImGui windows to be seamlessly detached from the main application window. This is achieved using an
138 | extra layer to the Platform and Renderer backends, which allows Dear ImGui to communicate platform-specific
139 | requests such as: "create an additional OS window", "create a render context", "get the OS position of this
140 | window" etc. See 'ImGuiPlatformIO' for details.
141 | Supporting the multi-viewports feature correctly using 100% of your own abstractions is more difficult
142 | than supporting single-viewport.
143 | If you decide to use unmodified imgui_impl_XXXX.cpp files, you can automatically benefit from
144 | improvements and fixes related to viewports and platform windows without extra work on your side.
145 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | NOTICE
2 | ======
3 |
4 | This branch is no longer maintained, I would pick a different branch.
5 |
6 |
7 | Unreal ImGui
8 | ============
9 | [](LICENSE.md)
10 |
11 | Unreal ImGui is an Unreal Engine 4 plug-in that integrates [Dear ImGui](https://github.com/ocornut/imgui) developed by Omar Cornut.
12 |
13 | Dear ImGui is an immediate-mode graphical user interface library that is very lightweight and easy to use. It can be very useful when creating debugging tools.
14 |
15 | :stop_button: Read Me First
16 | ---------------------------
17 | Please note that this is a forked project from [https://github.com/segross/UnrealImGui](https://github.com/segross/UnrealImGui). I do not take credit for the work he's put into making Dear ImGui work in Unreal Engine. The work I've done to this fork is listed below.
18 |
19 | I've removed large portions of this readme.md to keep redundant information between the base project and this fork to a minimum. If you wish to read the original readme.md, please see this link: [UnrealImGui ReadMe.md](https://github.com/segross/UnrealImGui/blob/master/README.md).
20 |
21 | Also note that the NetImGui branch is not up to date with any of this fork's changes.
22 |
23 | Fork Additions/Fixes
24 | --------------------
25 | - Updated core source files for Unreal Engine 5.
26 | - Updated Dear ImGui to 1.87.
27 | - Added ImPlot v0.13 WIP.
28 | - `ImGui::IsKey*` now functional with all known ImGui keys.
29 | - Updated input handling flow to be [standard compliant](https://github.com/ocornut/imgui/issues/4921) with Dear ImGui 1.87 which makes ImGui react better at low FPS. Will add `IMGUI_DISABLE_OBSOLETE_KEYIO` preprocessor once I've ripped out old style input.
30 | - Allowed `UTexture` for Texture Manager so render targets can also be rendered to quads rather than just being limited to using `UTexture2D` instances.
31 | - Added the ability to instruct ImGui context to build custom fonts (like FontAwesome).
32 |
33 | Status
34 | ------
35 | UnrealImGui Version: 1.22
36 |
37 | ImGui version: 1.87
38 |
39 | ImPlot version: v0.13 WIP
40 |
41 | Supported Unreal Engine version: 5.0*
42 |
43 | \* *The original repository has support for later versions of UE4. I've not tested this fork on UE4 variants, I only know it works for UE5 currently.*
44 |
45 | How to Set up
46 | -------------
47 | On top of reading the base repository's [How to Set up](https://github.com/segross/UnrealImGui/blob/master/README.md#how-to-set-up) segment, you'll need to add the following line to your `[GameName].Build.cs` file otherwise you'll get linking errors:
48 |
49 | ```cpp
50 | // Tell the compiler we want to import the ImPlot symbols when linking against ImGui plugin
51 | PrivateDefinitions.Add(string.Format("IMPLOT_API=DLLIMPORT"));
52 | ```
53 |
54 | # Additional Knowledge
55 |
56 | ## Using ImPlot
57 |
58 | It's pretty easy to use ImPlot, it's pretty much the same drill as using Dear ImGui with the UnrealImGui plugin. You can see documentation on how to use ImPlot here: [ImPlot](https://github.com/epezent/implot).
59 |
60 | The only thing you won't need to do is call the `ImPlot::CreateContext()` and `ImPlot::DestroyContext` routines as they're already called when ImGui's context is created within UnrealImGui's guts.
61 |
62 | ## Drawing a UTextureRenderTarget2D
63 |
64 | One might want to render viewports into the world in an ImGui window. You can do this pretty simply by generating a `UTextureRenderTarget2D` then assigning that to a `ASceneCapture2D` actor in your world. Here's some sample code for generating an correctly managing the `UTextureRenderTarget2D`:
65 | ```cpp
66 | void Init()
67 | {
68 | TextureRenderTarget = NewObject();
69 | if(IsValid(TextureRenderTarget))
70 | {
71 | TextureRenderTarget->InitAutoFormat(512, 512);
72 | TextureRenderTarget->UpdateResourceImmediate(true);
73 | }
74 |
75 | // ... Generate a unique TextureName here
76 | // Register this render target as an ImGui interop handled texture
77 | ImGuiTextureHandle = FImGuiModule::Get().FindTextureHandle(TextureName);
78 | if(!ImGuiTextureHandle.IsValid())
79 | {
80 | if(IsValid(TextureRenderTarget))
81 | {
82 | ImGuiTextureHandle = FImGuiModule::Get().RegisterTexture(TextureName, TextureRenderTarget, true);
83 | }
84 | }
85 | }
86 |
87 | ~Class()
88 | {
89 | // Requires releasing to avoid memory leak
90 | FImGuiModule::Get().ReleaseTexture(ImGuiTextureHandle);
91 | }
92 |
93 | void Render()
94 | {
95 | // Actually submit the draw command to ImGui to render the quad with the texture
96 | if(ImGuiTextureHandle.IsValid())
97 | {
98 | ImGui::Image(ImGuiTextureHandle.GetTextureId(), {512.f, 512.f});
99 | }
100 | }
101 | ```
102 |
103 | Then generating the `ASceneCapture2D`:
104 | ```cpp
105 | void Init()
106 | {
107 | FActorSpawnParameters SpawnInfo;
108 | SceneCapture2D = World->SpawnActor(FVector::ZeroVector, FRotator::ZeroRotator, SpawnInfo);
109 | SceneCaptureComponent2D->TextureTarget = TextureRenderTarget;
110 | SceneCaptureComponent2D->UpdateContent();
111 |
112 | // Need to use this in order to force capture to use tone curve and also set alpha to scene alpha (1)
113 | SceneCaptureComponent2D->CaptureSource = ESceneCaptureSource::SCS_FinalToneCurveHDR;
114 | }
115 | ```
116 |
117 | ### Troubleshooting
118 | If you're using a scene capture and your quad is not drawing at all, make sure your scene capture "Capture Source" is set to "Final Color (with tone curve) in Linear sRGB gamut" to avoid alpha being set to 0 (since there's no way to instruct ImGui to ignore alpha without modding the core UnrealImGui plugin).
119 |
120 | If you're getting crashes or seg faults during rendering, make sure you're using `UPROPERTY()` on your class variables!
121 |
122 | ## Adding custom fonts
123 | ### FontAwesome
124 | Adding custom fonts is fairly simple. As a more complex and more commonly done, we're going to embed and build FontAwesome 6 into the font atlas. First thing you'll need is a binary C version of the FontAwesome font along with the necessary [companion descriptors](https://github.com/juliettef/IconFontCppHeaders/blob/main/IconsFontAwesome6.h). The descriptors are pre-generated, however if you have a new version of FA you wish to use, then use the Python script in that repository. As for the binary C, you'll need to compile Dear ImGui's [binary_to_compressed_c.cpp](https://github.com/ocornut/imgui/blob/master/misc/fonts/binary_to_compressed_c.cpp).
125 |
126 | Once you have the necessary files, you'll need to encode your FontAwesome font using the command:
127 | ```
128 | binary_to_compressed_c.exe -nocompress fa-solid-900.ttf FontAwesomeFont > FontAwesomeFont.h
129 | ```
130 | The only mandatory field here is `-nocompress` as this instructs the encoder to create an uncompressed binary file (1:1) since currently there's no immediate support for compressed fonts.
131 |
132 | Move over your descriptors and your binary C font file to an appropriate location for inclusion in your Unreal Engine project. The following code is how to instruct ImGui to build the font atlas with your FontAwesome font:
133 |
134 | ```cpp
135 | #include "FontAwesomeFont.h"
136 | #include "IconsFontAwesome6.h"
137 |
138 | // Add FontAwesome font glyphs from memory
139 | if(TSharedPtr FAFontConfig = MakeShareable(new ImFontConfig()))
140 | {
141 | static const ImWchar IconRange[] = { ICON_MIN_FA, ICON_MAX_FA, 0 };
142 |
143 | FAFontConfig->FontDataOwnedByAtlas = false; // Global font data lifetime
144 | FAFontConfig->FontData = (void*)FontAwesomeData; // Declared in binary C .h file
145 | FAFontConfig->FontDataSize = FontAwesomeSize; // Declared in binary C .h file
146 | FAFontConfig->SizePixels = 16;
147 | FAFontConfig->MergeMode = true; // Forces ImGui to place this font into the same atlas as the previous font
148 | FAFontConfig->GlyphRanges = IconRange; // Required; instructs ImGui to use these glyphs
149 | FAFontConfig->GlyphMinAdvanceX = 16.f; // Use for monospaced icons
150 | FAFontConfig->PixelSnapH = true; // Better rendering (align to pixel grid)
151 | FAFontConfig->GlyphOffset = {0, 3}; // Moves icons around, for alignment with general typesets
152 |
153 | FImGuiModule::Get().GetProperties().AddCustomFont("FontAwesome", FAFontConfig);
154 | FImGuiModule::Get().RebuildFontAtlas();
155 | }
156 | ```
157 |
158 | That's it. Make sure you execute the above code once at the beginning of the first ImGui frame (or at any point of your framework where the ImGui context has been initialized correctly) and it should build the main atlas with FontAwesome inside it. ImFontConfig lifetime is currently managed via reference counting (`TSharedPtr`).
159 |
160 | ### Using the icons
161 | ```cpp
162 | #include "IconsFontAwesome6.h"
163 |
164 | void OnPaint()
165 | {
166 | ImGui::Text(ICON_FA_AWARD);
167 | }
168 | ```
169 |
170 | Pretty simple. Building FStrings that incorporate FontAwesome icons however gets a little trickier:
171 | ```cpp
172 | FString Str = "Hello " + FString(UTF8_TO_TCHAR(ICON_FA_WAVE_SQUARE)) " World";
173 | ImGui::TextUnformatted(TCHAR_TO_UTF8(*Str));
174 | ```
175 |
176 | ### More info
177 | - [Dear ImGui: Using Fonts](https://github.com/ocornut/imgui/blob/master/docs/FONTS.md)
178 | - [IconFontCppHeaders](https://github.com/juliettef/IconFontCppHeaders)
179 | - [FontAwesome with general Dear ImGui](https://pixtur.github.io/mkdocs-for-imgui/site/FONTS/)
180 |
181 | # Misc
182 |
183 | See also
184 | --------
185 | - [Original Project by segross](https://github.com/segross/UnrealImGui)
186 | - [Dear ImGui](https://github.com/ocornut/imgui)
187 | - [ImPlot](https://github.com/epezent/implot)
188 |
189 |
190 | License
191 | -------
192 | Unreal ImGui (and this fork) is licensed under the MIT License, see LICENSE for more information.
193 |
--------------------------------------------------------------------------------
/Source/ImGui/Private/ImGuiInputState.h:
--------------------------------------------------------------------------------
1 | // Distributed under the MIT License (MIT) (see accompanying LICENSE file)
2 |
3 | #pragma once
4 |
5 | #include "ImGuiInteroperability.h"
6 | #include "Utilities/Arrays.h"
7 |
8 | #include
9 |
10 |
11 | // Collects and stores input state and updates for ImGui IO.
12 | class FImGuiInputState
13 | {
14 | public:
15 |
16 | // Characters buffer.
17 | using FCharactersBuffer = TArray>;
18 |
19 | // Array for mouse button states.
20 | using FMouseButtonsArray = ImGuiInterops::ImGuiTypes::FMouseButtonsArray;
21 |
22 | // Array for key states.
23 | using FKeysArray = ImGuiInterops::ImGuiTypes::FKeysArray;
24 |
25 | // Array for navigation input states.
26 | using FNavInputArray = ImGuiInterops::ImGuiTypes::FNavInputArray;
27 |
28 | // Pair of indices defining range in mouse buttons array.
29 | using FMouseButtonsIndexRange = Utilities::TArrayIndexRange;
30 |
31 | // Pair of indices defining range in keys array.
32 | using FKeysIndexRange = Utilities::TArrayIndexRange;
33 |
34 | // Create empty state with whole range instance with the whole update state marked as dirty.
35 | FImGuiInputState();
36 |
37 | // Get reference to input characters buffer.
38 | const FCharactersBuffer& GetCharacters() const { return InputCharacters; }
39 |
40 | // Add a character to the characters buffer. We can store and send to ImGui up to 16 characters per frame. Any
41 | // character beyond that limit will be discarded.
42 | // @param Char - Character to add
43 | void AddCharacter(TCHAR Char);
44 |
45 | // Get reference to the array with key down states.
46 | const FKeysArray& GetKeys() const { return KeysDown; }
47 |
48 | // Get possibly empty range of indices bounding dirty part of the keys array.
49 | const FKeysIndexRange& GetKeysUpdateRange() const { return KeysUpdateRange; }
50 |
51 | // Change state of the key in the keys array and expand range bounding dirty part of the array.
52 | // @param KeyEvent - Key event representing the key
53 | // @param bIsDown - True, if key is down
54 | void SetKeyDown(const FKeyEvent& KeyEvent, bool bIsDown) { SetKeyDown(ImGuiInterops::GetKeyIndex(KeyEvent), bIsDown); }
55 |
56 | // Change state of the key in the keys array and expand range bounding dirty part of the array.
57 | // @param Key - Keyboard key
58 | // @param bIsDown - True, if key is down
59 | void SetKeyDown(const FKey& Key, bool bIsDown) { SetKeyDown(ImGuiInterops::GetKeyIndex(Key), bIsDown); }
60 |
61 | // Get reference to the array with mouse button down states.
62 | const FMouseButtonsArray& GetMouseButtons() const { return MouseButtonsDown; }
63 |
64 | // Get possibly empty range of indices bounding dirty part of the mouse buttons array.
65 | const FMouseButtonsIndexRange& GetMouseButtonsUpdateRange() const { return MouseButtonsUpdateRange; }
66 |
67 | // Change state of the button in the mouse buttons array and expand range bounding dirty part of the array.
68 | // @param MouseEvent - Mouse event representing mouse button
69 | // @param bIsDown - True, if button is down
70 | void SetMouseDown(const FPointerEvent& MouseEvent, bool bIsDown) { SetMouseDown(ImGuiInterops::GetMouseIndex(MouseEvent), bIsDown); }
71 |
72 | // Change state of the button in the mouse buttons array and expand range bounding dirty part of the array.
73 | // @param MouseButton - Mouse button key
74 | // @param bIsDown - True, if button is down
75 | void SetMouseDown(const FKey& MouseButton, bool bIsDown) { SetMouseDown(ImGuiInterops::GetMouseIndex(MouseButton), bIsDown); }
76 |
77 | // Get mouse wheel delta accumulated during the last frame.
78 | float GetMouseWheelDelta() const { return MouseWheelDelta; }
79 |
80 | // Add mouse wheel delta.
81 | // @param DeltaValue - Mouse wheel delta to add
82 | void AddMouseWheelDelta(float DeltaValue) { MouseWheelDelta += DeltaValue; }
83 |
84 | // Get the mouse position.
85 | const FVector2D& GetMousePosition() const { return MousePosition; }
86 |
87 | // Set the mouse position.
88 | // @param Position - Mouse position
89 | void SetMousePosition(const FVector2D& Position) { MousePosition = Position; }
90 |
91 | // Check whether input has active mouse pointer.
92 | bool HasMousePointer() const { return bHasMousePointer; }
93 |
94 | // Set whether input has active mouse pointer.
95 | // @param bHasPointer - True, if input has active mouse pointer
96 | void SetMousePointer(bool bInHasMousePointer) { bHasMousePointer = bInHasMousePointer; }
97 |
98 | // Check whether touch input is in progress. True, after touch is started until one frame after it has ended.
99 | // One frame delay is used to process mouse release in ImGui since touch-down is simulated with mouse-down.
100 | bool IsTouchActive() const { return bTouchDown || bTouchProcessed; }
101 |
102 | // Check whether touch input is down.
103 | bool IsTouchDown() const { return bTouchDown; }
104 |
105 | // Set whether touch input is down.
106 | // @param bIsDown - True, if touch is down (or started) and false, if touch is up (or ended)
107 | void SetTouchDown(bool bIsDown) { bTouchDown = bIsDown; }
108 |
109 | // Get the touch position.
110 | const FVector2D& GetTouchPosition() const { return TouchPosition; }
111 |
112 | // Set the touch position.
113 | // @param Position - Touch position
114 | void SetTouchPosition(const FVector2D& Position) { TouchPosition = Position; }
115 |
116 | // Get Control down state.
117 | bool IsControlDown() const { return bIsControlDown; }
118 |
119 | // Set Control down state.
120 | // @param bIsDown - True, if Control is down
121 | void SetControlDown(bool bIsDown) { bIsControlDown = bIsDown; }
122 |
123 | // Get Shift down state.
124 | bool IsShiftDown() const { return bIsShiftDown; }
125 |
126 | // Set Shift down state.
127 | // @param bIsDown - True, if Shift is down
128 | void SetShiftDown(bool bIsDown) { bIsShiftDown = bIsDown; }
129 |
130 | // Get Alt down state.
131 | bool IsAltDown() const { return bIsAltDown; }
132 |
133 | // Set Alt down state.
134 | // @param bIsDown - True, if Alt is down
135 | void SetAltDown(bool bIsDown) { bIsAltDown = bIsDown; }
136 |
137 | // Get reference to the array with navigation input states.
138 | const FNavInputArray& GetNavigationInputs() const { return NavigationInputs; }
139 |
140 | // Change state of the navigation input associated with this gamepad key.
141 | // @param KeyEvent - Key event with gamepad key input
142 | // @param bIsDown - True, if key is down
143 | void SetGamepadNavigationKey(const FKeyEvent& KeyEvent, bool bIsDown) { ImGuiInterops::SetGamepadNavigationKey(NavigationInputs, KeyEvent.GetKey(), bIsDown); }
144 |
145 | // Change state of the navigation input associated with this gamepad axis.
146 | // @param AnalogInputEvent - Analogue input event with gamepad axis input
147 | // @param Value - Analogue value that should be set for this axis
148 | void SetGamepadNavigationAxis(const FAnalogInputEvent& AnalogInputEvent, float Value) { ImGuiInterops::SetGamepadNavigationAxis(NavigationInputs, AnalogInputEvent.GetKey(), Value); }
149 |
150 | // Check whether keyboard navigation is enabled.
151 | bool IsKeyboardNavigationEnabled() const { return bKeyboardNavigationEnabled; }
152 |
153 | // Set whether keyboard navigation is enabled.
154 | // @param bEnabled - True, if navigation is enabled
155 | void SetKeyboardNavigationEnabled(bool bEnabled) { bKeyboardNavigationEnabled = bEnabled; }
156 |
157 | // Check whether gamepad navigation is enabled.
158 | bool IsGamepadNavigationEnabled() const { return bGamepadNavigationEnabled; }
159 |
160 | // Set whether gamepad navigation is enabled.
161 | // @param bEnabled - True, if navigation is enabled
162 | void SetGamepadNavigationEnabled(bool bEnabled) { bGamepadNavigationEnabled = bEnabled; }
163 |
164 | // Check whether gamepad is attached.
165 | bool HasGamepad() const { return bHasGamepad; }
166 |
167 | // Set whether gamepad is attached.
168 | // @param bInHasGamepad - True, if gamepad is attached
169 | void SetGamepad(bool bInHasGamepad) { bHasGamepad = bInHasGamepad; }
170 |
171 | // Reset the whole input state and mark it as dirty.
172 | void Reset()
173 | {
174 | ResetKeyboard();
175 | ResetMouse();
176 | ResetGamepadNavigation();
177 | }
178 |
179 | // Reset the keyboard input state and mark it as dirty.
180 | void ResetKeyboard()
181 | {
182 | ClearCharacters();
183 | ClearKeys();
184 | ClearModifierKeys();
185 | }
186 |
187 | // Reset the mouse input state and mark it as dirty.
188 | void ResetMouse()
189 | {
190 | ClearMouseButtons();
191 | ClearMouseAnalogue();
192 | }
193 |
194 | // Reset the gamepad navigation state.
195 | void ResetGamepadNavigation()
196 | {
197 | ClearNavigationInputs();
198 | }
199 |
200 | // Clear part of the state that is meant to be updated in every frame like: accumulators, buffers, navigation data
201 | // and information about dirty parts of keys or mouse buttons arrays.
202 | void ClearUpdateState();
203 |
204 | TMap KeyDownEvents;
205 | TMap KeyUpEvents;
206 |
207 | private:
208 |
209 | void SetKeyDown(uint32 KeyIndex, bool bIsDown);
210 | void SetMouseDown(uint32 MouseIndex, bool IsDown);
211 |
212 | void ClearCharacters();
213 | void ClearKeys();
214 | void ClearMouseButtons();
215 | void ClearMouseAnalogue();
216 | void ClearModifierKeys();
217 | void ClearNavigationInputs();
218 |
219 | FVector2D MousePosition = FVector2D::ZeroVector;
220 | FVector2D TouchPosition = FVector2D::ZeroVector;
221 | float MouseWheelDelta = 0.f;
222 |
223 | FMouseButtonsArray MouseButtonsDown;
224 | FMouseButtonsIndexRange MouseButtonsUpdateRange;
225 |
226 | FCharactersBuffer InputCharacters;
227 |
228 | FKeysArray KeysDown;
229 | FKeysIndexRange KeysUpdateRange;
230 |
231 | FNavInputArray NavigationInputs;
232 |
233 | bool bHasMousePointer = false;
234 | bool bTouchDown = false;
235 | bool bTouchProcessed = false;
236 |
237 | bool bIsControlDown = false;
238 | bool bIsShiftDown = false;
239 | bool bIsAltDown = false;
240 |
241 | bool bKeyboardNavigationEnabled = false;
242 | bool bGamepadNavigationEnabled = false;
243 | bool bHasGamepad = false;
244 | };
245 |
--------------------------------------------------------------------------------
/Source/ThirdParty/ImGuiLibrary/Include/imconfig.h:
--------------------------------------------------------------------------------
1 | //-----------------------------------------------------------------------------
2 | // COMPILE-TIME OPTIONS FOR DEAR IMGUI
3 | // Runtime options (clipboard callbacks, enabling various features, etc.) can generally be set via the ImGuiIO structure.
4 | // You can use ImGui::SetAllocatorFunctions() before calling ImGui::CreateContext() to rewire memory allocation functions.
5 | //-----------------------------------------------------------------------------
6 | // A) You may edit imconfig.h (and not overwrite it when updating Dear ImGui, or maintain a patch/rebased branch with your modifications to it)
7 | // B) or '#define IMGUI_USER_CONFIG "my_imgui_config.h"' in your project and then add directives in your own file without touching this template.
8 | //-----------------------------------------------------------------------------
9 | // You need to make sure that configuration settings are defined consistently _everywhere_ Dear ImGui is used, which include the imgui*.cpp
10 | // files but also _any_ of your code that uses Dear ImGui. This is because some compile-time options have an affect on data structures.
11 | // Defining those options in imconfig.h will ensure every compilation unit gets to see the same data structure layouts.
12 | // Call IMGUI_CHECKVERSION() from your .cpp files to verify that the data structures your files are using are matching the ones imgui.cpp is using.
13 | //-----------------------------------------------------------------------------
14 |
15 | #pragma once
16 |
17 | //---- Define assertion handler. Defaults to calling assert().
18 | // If your macro uses multiple statements, make sure is enclosed in a 'do { .. } while (0)' block so it can be used as a single statement.
19 | //#define IM_ASSERT(_EXPR) MyAssert(_EXPR)
20 | //#define IM_ASSERT(_EXPR) ((void)(_EXPR)) // Disable asserts
21 |
22 | //---- Define attributes of all API symbols declarations, e.g. for DLL under Windows
23 | // Using Dear ImGui via a shared library is not recommended, because of function call overhead and because we don't guarantee backward nor forward ABI compatibility.
24 | // DLL users: heaps and globals are not shared across DLL boundaries! You will need to call SetCurrentContext() + SetAllocatorFunctions()
25 | // for each static/DLL boundary you are calling from. Read "Context and Memory Allocators" section of imgui.cpp for more details.
26 | //#define IMGUI_API __declspec( dllexport )
27 | //#define IMGUI_API __declspec( dllimport )
28 |
29 | //---- Don't define obsolete functions/enums/behaviors. Consider enabling from time to time after updating to avoid using soon-to-be obsolete function/names.
30 | //#define IMGUI_DISABLE_OBSOLETE_FUNCTIONS
31 | //#define IMGUI_DISABLE_OBSOLETE_KEYIO // 1.87: disable legacy io.KeyMap[]+io.KeysDown[] in favor io.AddKeyEvent(). This will be folded into IMGUI_DISABLE_OBSOLETE_FUNCTIONS in a few versions.
32 |
33 | //---- Disable all of Dear ImGui or don't implement standard windows.
34 | // It is very strongly recommended to NOT disable the demo windows during development. Please read comments in imgui_demo.cpp.
35 | //#define IMGUI_DISABLE // Disable everything: all headers and source files will be empty.
36 | //#define IMGUI_DISABLE_DEMO_WINDOWS // Disable demo windows: ShowDemoWindow()/ShowStyleEditor() will be empty. Not recommended.
37 | //#define IMGUI_DISABLE_METRICS_WINDOW // Disable metrics/debugger and other debug tools: ShowMetricsWindow() and ShowStackToolWindow() will be empty.
38 |
39 | //---- Don't implement some functions to reduce linkage requirements.
40 | //#define IMGUI_DISABLE_WIN32_DEFAULT_CLIPBOARD_FUNCTIONS // [Win32] Don't implement default clipboard handler. Won't use and link with OpenClipboard/GetClipboardData/CloseClipboard etc. (user32.lib/.a, kernel32.lib/.a)
41 | //#define IMGUI_ENABLE_WIN32_DEFAULT_IME_FUNCTIONS // [Win32] [Default with Visual Studio] Implement default IME handler (require imm32.lib/.a, auto-link for Visual Studio, -limm32 on command-line for MinGW)
42 | //#define IMGUI_DISABLE_WIN32_DEFAULT_IME_FUNCTIONS // [Win32] [Default with non-Visual Studio compilers] Don't implement default IME handler (won't require imm32.lib/.a)
43 | //#define IMGUI_DISABLE_WIN32_FUNCTIONS // [Win32] Won't use and link with any Win32 function (clipboard, ime).
44 | //#define IMGUI_ENABLE_OSX_DEFAULT_CLIPBOARD_FUNCTIONS // [OSX] Implement default OSX clipboard handler (need to link with '-framework ApplicationServices', this is why this is not the default).
45 | //#define IMGUI_DISABLE_DEFAULT_FORMAT_FUNCTIONS // Don't implement ImFormatString/ImFormatStringV so you can implement them yourself (e.g. if you don't want to link with vsnprintf)
46 | //#define IMGUI_DISABLE_DEFAULT_MATH_FUNCTIONS // Don't implement ImFabs/ImSqrt/ImPow/ImFmod/ImCos/ImSin/ImAcos/ImAtan2 so you can implement them yourself.
47 | //#define IMGUI_DISABLE_FILE_FUNCTIONS // Don't implement ImFileOpen/ImFileClose/ImFileRead/ImFileWrite and ImFileHandle at all (replace them with dummies)
48 | //#define IMGUI_DISABLE_DEFAULT_FILE_FUNCTIONS // Don't implement ImFileOpen/ImFileClose/ImFileRead/ImFileWrite and ImFileHandle so you can implement them yourself if you don't want to link with fopen/fclose/fread/fwrite. This will also disable the LogToTTY() function.
49 | //#define IMGUI_DISABLE_DEFAULT_ALLOCATORS // Don't implement default allocators calling malloc()/free() to avoid linking with them. You will need to call ImGui::SetAllocatorFunctions().
50 | //#define IMGUI_DISABLE_SSE // Disable use of SSE intrinsics even if available
51 |
52 | //---- Include imgui_user.h at the end of imgui.h as a convenience
53 | //#define IMGUI_INCLUDE_IMGUI_USER_H
54 |
55 | //---- Pack colors to BGRA8 instead of RGBA8 (to avoid converting from one to another)
56 | //#define IMGUI_USE_BGRA_PACKED_COLOR
57 |
58 | //---- Use 32-bit for ImWchar (default is 16-bit) to support unicode planes 1-16. (e.g. point beyond 0xFFFF like emoticons, dingbats, symbols, shapes, ancient languages, etc...)
59 | //#define IMGUI_USE_WCHAR32
60 |
61 | //---- Avoid multiple STB libraries implementations, or redefine path/filenames to prioritize another version
62 | // By default the embedded implementations are declared static and not available outside of Dear ImGui sources files.
63 | //#define IMGUI_STB_TRUETYPE_FILENAME "my_folder/stb_truetype.h"
64 | //#define IMGUI_STB_RECT_PACK_FILENAME "my_folder/stb_rect_pack.h"
65 | //#define IMGUI_DISABLE_STB_TRUETYPE_IMPLEMENTATION
66 | //#define IMGUI_DISABLE_STB_RECT_PACK_IMPLEMENTATION
67 |
68 | //---- Use stb_printf's faster implementation of vsnprintf instead of the one from libc (unless IMGUI_DISABLE_DEFAULT_FORMAT_FUNCTIONS is defined)
69 | // Requires 'stb_sprintf.h' to be available in the include path. Compatibility checks of arguments and formats done by clang and GCC will be disabled in order to support the extra formats provided by STB sprintf.
70 | // #define IMGUI_USE_STB_SPRINTF
71 |
72 | //---- Use FreeType to build and rasterize the font atlas (instead of stb_truetype which is embedded by default in Dear ImGui)
73 | // Requires FreeType headers to be available in the include path. Requires program to be compiled with 'misc/freetype/imgui_freetype.cpp' (in this repository) + the FreeType library (not provided).
74 | // On Windows you may use vcpkg with 'vcpkg install freetype --triplet=x64-windows' + 'vcpkg integrate install'.
75 | //#define IMGUI_ENABLE_FREETYPE
76 |
77 | //---- Use stb_truetype to build and rasterize the font atlas (default)
78 | // The only purpose of this define is if you want force compilation of the stb_truetype backend ALONG with the FreeType backend.
79 | //#define IMGUI_ENABLE_STB_TRUETYPE
80 |
81 | //---- Define constructor and implicit cast operators to convert back<>forth between your math types and ImVec2/ImVec4.
82 | // This will be inlined as part of ImVec2 and ImVec4 class declarations.
83 | /*
84 | #define IM_VEC2_CLASS_EXTRA \
85 | ImVec2(const MyVec2& f) { x = f.x; y = f.y; } \
86 | operator MyVec2() const { return MyVec2(x,y); }
87 |
88 | #define IM_VEC4_CLASS_EXTRA \
89 | ImVec4(const MyVec4& f) { x = f.x; y = f.y; z = f.z; w = f.w; } \
90 | operator MyVec4() const { return MyVec4(x,y,z,w); }
91 | */
92 |
93 | //---- Use 32-bit vertex indices (default is 16-bit) is one way to allow large meshes with more than 64K vertices.
94 | // Your renderer backend will need to support it (most example renderer backends support both 16/32-bit indices).
95 | // Another way to allow large meshes while keeping 16-bit indices is to handle ImDrawCmd::VtxOffset in your renderer.
96 | // Read about ImGuiBackendFlags_RendererHasVtxOffset for details.
97 | //#define ImDrawIdx unsigned int
98 |
99 | //---- Override ImDrawCallback signature (will need to modify renderer backends accordingly)
100 | //struct ImDrawList;
101 | //struct ImDrawCmd;
102 | //typedef void (*MyImDrawCallback)(const ImDrawList* draw_list, const ImDrawCmd* cmd, void* my_renderer_user_data);
103 | //#define ImDrawCallback MyImDrawCallback
104 |
105 | //---- Debug Tools: Macro to break in Debugger
106 | // (use 'Metrics->Tools->Item Picker' to pick widgets with the mouse and break into them for easy debugging.)
107 | //#define IM_DEBUG_BREAK IM_ASSERT(0)
108 | //#define IM_DEBUG_BREAK __debugbreak()
109 |
110 | //---- Debug Tools: Have the Item Picker break in the ItemAdd() function instead of ItemHoverable(),
111 | // (which comes earlier in the code, will catch a few extra items, allow picking items other than Hovered one.)
112 | // This adds a small runtime cost which is why it is not enabled by default.
113 | //#define IMGUI_DEBUG_TOOL_ITEM_PICKER_EX
114 |
115 | //---- Debug Tools: Enable slower asserts
116 | //#define IMGUI_DEBUG_PARANOID
117 |
118 | //---- Tip: You can add extra functions within the ImGui:: namespace, here or in your own headers files.
119 | /*
120 | namespace ImGui
121 | {
122 | void MyFunction(const char* name, const MyMatrix44& v);
123 | }
124 | */
125 |
--------------------------------------------------------------------------------