Add UnrealImGui plugin

[git-p4: depot-paths = "//depot/main/": change = 78]
This commit is contained in:
Kevin Poretti 2021-05-30 15:50:11 -05:00
parent 4c1a7667a9
commit 845ce746ad
109 changed files with 51686 additions and 0 deletions

View File

@ -0,0 +1,2 @@
/Binaries/
/Intermediate/

View File

@ -0,0 +1,7 @@
{
"BuildId": "14830424",
"Modules":
{
"ImGui": "UE4Editor-ImGui.dll"
}
}

View File

@ -0,0 +1,150 @@
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.
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.
Change History
--------------
Version: 1.22 (2021/04)
- Fixed potential for initialization fiasco when using delegates container.
- Fixed bug in code protecting redirecting handles from self-referencing.
- Fixed cached resource handles getting invalid after reloading texture resources.
Version: 1.21 (2020/07-09)
Improving stability
- Fixed a crash in the input handler caused by invalidated by hot-reload instance trying to unregister a delegate.
- Improved hot-reload stability and support for reloading after recompiling outside of the editor. Both methods should be equally supported and work together.
- Improved behaviour of delegates when hot-reloading.
- Changed context index mapping to fix issues with multi-PIE debugging in 4.25.
- Fixed Linux crash caused by wrong mapping of key codes.
Version: 1.20 (2020/06)
Transition to IWYU and maintenance:
- Replaced includes of monolithic headers.
- Removed explicit PCH and switched to IWYU-style PCH model.
- Fixed includes to compile without explicit PCH in non-unity mode.
- Fixed a few issues causing compilation errors in older engine versions.
- Fixed debug code to compile on platforms using other than char or wchar_t characters.
- Fixed issues in recently added DPI scaling.
- Cleaned obsolete and unused code.
- Replaced custom scope guards with the template provided by the engine.
Version: 1.19 (2020/03-06)
- Integrated fix for issue with ImGui popup/modal windows not being able to be closed in transparent mouse input mode.
- Integrated first version of Adaptive Canvas Size.
- Added different options to define canvas size, with Adaptive Canvas Size being one of the options (viewport).
- Added option for DPI scaling.
Version: 1.18 (2020/01)
- Updated to engine version 4.24.
- Updated to ImGui version 1.74.
Version: 1.17 (2019/04)
- Added experimental support for touch input.
- Integrated fixes allowing to build this as an engine plugin:
- Added support for sharing with game mouse input.
- Refactorization of input handling, with changes in SImGuiWidget and compatibility breaking changes in UImGuiInputHandler.
Version: 1.16 (2019/05)
- Fixed issue with SImGuiLayout blocking mouse input for other Slate widgets, which was introduced by refactorization of widgets (version 1.14, commit c144658f).
Version: 1.15 (2019/04)
- Added new FImGuiDelegates interface for ImGui debug delegates.
- Added code preserving delegates during hot-reloading and moving them to a new module.
- DEPRECIATED old FImGuiModule delegates interface and FImGuiDelegateHandle.
- 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.
- Added IMGUI_WITH_OBSOLETE_DELEGATES allowing to strip depreciated interface from builds (that interface will be officially removed in one of later releases).
- Added new ImGui early debug delegates called during world tick start.
- 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).
- Removed from build script configuration of debug delegates.
Version: 1.14 (2019/03)
- Added SImGuiLayout to resets layout for SImGuiWidget.
- Refactored rendering in SImGuiWidget to take advantage of layout reset.
- Reworked ImGui canvas dragging and scaling and moved it to SImGuiCanvasControl.
- Removed dependency on ImGui internal cursor data.
Version: 1.13 (unofficial) (2019/03)
- 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.
- Fixed non-unity compile warnings and errors.
Version: 1.12 (unofficial) (2018/12)
- Added support for sharing with game keyboard and gamepad input.
- Added FImGuiModuleSettings to handle delayed loading of UImGuiSettings and serve as settings proxy for other classes.
Version: 1.11 (unofficial) (2018/10-11)
- 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.
- Replaced console variable based configuration of ImGui Draw events with macros.
- Replaced console variable based configuration of software cursor with a setting.
- 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.
- Replaced console variables with module properties and settings.
- Added console commands to control module properties.
- Added support to preserve and move module properties to hot-reloaded module.
- Moved properties to public interface.
- Added FImGuiModule interface to access properties instance.
- DEPRECIATED FImGuiModule functions to modify single properties.
Version: 1.10 (unofficial) (2018/10)
- Changed module type to 'Developer' to make it easier strip it from shipping or other builds.
- Added runtime loader to allow automatically load developer module in runtime builds.
Version: 1.09 (unofficial) (2018/08-09)
- Added interface to register user textures for use in ImGui.
- Fixed bad deallocation in Texture Manager.
- Updated to ImGui 1.61.
- Updated to UE 4.20.
Version: 1.08 (unofficial) (2018/07-08)
- Added ImGui Input Handler to allow to customization of input handling.
- Added ImGui settings with editor page in project properties.
- Added command to switch input mode with configurable key binding.
- Added backward compatibility macros.
- Fixed hot-reloading issues with using ImGui implementation.
Version: 1.07 (unofficial) (2018/05)
- Improved initialization to allow loading module in any loading phase.
Version: 1.06 (unofficial) (2018/05)
- Updated to ImGui 1.61
- Added support for gamepad and keyboard navigation.
Version: 1.05 (unofficial) (2018/04)
- Added mode to scale and drag ImGui canvas.
- Using ImGui internal cursor data to draw drag icon.
Version: 1.04 (unofficial) (2018/03)
- Minimised lag between ending ImGui frame and rendering draw data in Slate.
- Moved ImGui Draw event to be called during world tick start with configuration to use old behaviour.
Version: 1.03 (unofficial) (2018/01-03)
- Fixed warnings and errors found in non-unity, Linux, PS4 or XBox builds.
- Added configuration to choose between hardware and software cursor with hardware cursor used by default.
Version: 1.02 (unofficial) (2018/01)
- Updated to ImGui 1.53.
- Fixed problems with ImGui Demo working in multi-context environment.
- Added FImGuiModule interface to change input mode and demo visibility.
- Fixed input state issues after application loses focus.
- Added input state debugging and `ImGui.Debug.Input` console variable to switch it.
Version: 1.01 (unofficial) (2017/10)
- Added `ImGui.ShowDemo` console variable to show/hide ImGui demo.
- Added automatic switching to right ImGui context at the beginning of the world tick.
- Updated to UE 4.18
Version: <=1.00 (unofficial) (2017/04-10)
- Added ImGui source code as an external module to expose it in IDE.
- Integrated ImGui source code to build as part of the ImGui module.
- Added FImGuiModule to implement ImGui module interface.
- Added FImGuiModuleManager to control other module components.
- Added FTextureManager to manage texture resources and map them to ImTextureID.
- Added SImGuiWidget to handle Slate input and render in Slate ImGui draw data.
- Added FImGuiInputState to collect and store input before it can be copied to ImGui IO.
- Added FContextProxy to represent a single ImGui context.
- Added FImGuiContextManager to create and manage ImGui context proxies.
- Added Multi-PIE support with each PIE instance getting a dedicated ImGui context proxy, input state and widget.
- Added `ImGui.InputEnabled` console variable to control whether input mode is enabled.
- Added widget debugging and `ImGui.Debug.Widget` console variable to switch it.
- Added ImGui software cursor.
- Added support for session reloading with ini file names based on world type and PIE index.
- Added FImGuiModule interface to register ImGui delegates called to draw ImGui controls.

View File

@ -0,0 +1,23 @@
{
"FileVersion": 3,
"Version": 1,
"VersionName": "1.22",
"FriendlyName": "ImGui",
"Description": "",
"Category": "Debug",
"CreatedBy": "",
"CreatedByURL": "",
"DocsURL": "",
"MarketplaceURL": "",
"SupportURL": "",
"CanContainContent": false,
"IsBetaVersion": false,
"Installed": false,
"Modules": [
{
"Name": "ImGui",
"Type": "DeveloperTool",
"LoadingPhase": "PreDefault"
}
]
}

View File

@ -0,0 +1,275 @@
#undef IMGUI_API
#define IS_PROGRAM 0
#define UE_EDITOR 1
#define ENABLE_PGO_PROFILE 0
#define USE_VORBIS_FOR_STREAMING 1
#define USE_XMA2_FOR_STREAMING 1
#define WITH_DEV_AUTOMATION_TESTS 1
#define WITH_PERF_AUTOMATION_TESTS 1
#define UNICODE 1
#define _UNICODE 1
#define __UNREAL__ 1
#define IS_MONOLITHIC 0
#define WITH_ENGINE 1
#define WITH_UNREAL_DEVELOPER_TOOLS 1
#define WITH_APPLICATION_CORE 1
#define WITH_COREUOBJECT 1
#define USE_STATS_WITHOUT_ENGINE 0
#define WITH_PLUGIN_SUPPORT 0
#define WITH_ACCESSIBILITY 1
#define WITH_PERFCOUNTERS 1
#define USE_LOGGING_IN_SHIPPING 0
#define WITH_LOGGING_TO_MEMORY 0
#define USE_CACHE_FREED_OS_ALLOCS 1
#define USE_CHECKS_IN_SHIPPING 0
#define USE_ESTIMATED_UTCNOW 0
#define WITH_EDITOR 1
#define WITH_SERVER_CODE 1
#define WITH_PUSH_MODEL 1
#define WITH_CEF3 1
#define WITH_LIVE_CODING 1
#define UBT_MODULE_MANIFEST "UE4Editor.modules"
#define UBT_MODULE_MANIFEST_DEBUGGAME "UE4Editor-Win64-DebugGame.modules"
#define UBT_COMPILED_PLATFORM Win64
#define UBT_COMPILED_TARGET Editor
#define UE_APP_NAME "UE4Editor"
#define NDIS_MINIPORT_MAJOR_VERSION 0
#define WIN32 1
#define _WIN32_WINNT 0x0601
#define WINVER 0x0601
#define PLATFORM_WINDOWS 1
#define PLATFORM_MICROSOFT 1
#define OVERRIDE_PLATFORM_HEADER_NAME Windows
#define RHI_RAYTRACING 1
#define NDEBUG 1
#define UE_BUILD_DEVELOPMENT 1
#define UE_IS_ENGINE_MODULE 1
#define RUNTIME_LOADER_ENABLED 1
#define COREUOBJECT_API DLLIMPORT
#define UE_ENABLE_ICU 1
#define WITH_VS_PERF_PROFILER 0
#define WITH_DIRECTXMATH 0
#define WITH_MALLOC_STOMP 1
#define CORE_API DLLIMPORT
#define TRACELOG_API DLLIMPORT
#define INCLUDE_CHAOS 0
#define WITH_PHYSX 1
#define WITH_CHAOS 0
#define WITH_CHAOS_CLOTHING 0
#define WITH_CHAOS_NEEDS_TO_BE_FIXED 0
#define PHYSICS_INTERFACE_PHYSX 1
#define WITH_APEX 1
#define WITH_APEX_CLOTHING 1
#define WITH_CLOTH_COLLISION_DETECTION 1
#define WITH_PHYSX_COOKING 1
#define WITH_NVCLOTH 1
#define WITH_CUSTOM_SQ_STRUCTURE 0
#define WITH_IMMEDIATE_PHYSX 0
#define GPUPARTICLE_LOCAL_VF_ONLY 0
#define ENGINE_API DLLIMPORT
#define NETCORE_API DLLIMPORT
#define APPLICATIONCORE_API DLLIMPORT
#define RHI_API DLLIMPORT
#define JSON_API DLLIMPORT
#define WITH_FREETYPE 1
#define SLATECORE_API DLLIMPORT
#define INPUTCORE_API DLLIMPORT
#define SLATE_API DLLIMPORT
#define WITH_UNREALPNG 1
#define WITH_UNREALJPEG 1
#define WITH_LIBJPEGTURBO 1
#define WITH_UNREALEXR 1
#define IMAGEWRAPPER_API DLLIMPORT
#define MESSAGING_API DLLIMPORT
#define MESSAGINGCOMMON_API DLLIMPORT
#define RENDERCORE_API DLLIMPORT
#define ANALYTICSET_API DLLIMPORT
#define ANALYTICS_API DLLIMPORT
#define SOCKETS_PACKAGE 1
#define SOCKETS_API DLLIMPORT
#define NETCOMMON_API DLLIMPORT
#define ASSETREGISTRY_API DLLIMPORT
#define ENGINEMESSAGES_API DLLIMPORT
#define ENGINESETTINGS_API DLLIMPORT
#define SYNTHBENCHMARK_API DLLIMPORT
#define RENDERER_API DLLIMPORT
#define GAMEPLAYTAGS_API DLLIMPORT
#define PACKETHANDLER_API DLLIMPORT
#define RELIABILITYHANDLERCOMPONENT_API DLLIMPORT
#define AUDIOPLATFORMCONFIGURATION_API DLLIMPORT
#define MESHDESCRIPTION_API DLLIMPORT
#define STATICMESHDESCRIPTION_API DLLIMPORT
#define PAKFILE_API DLLIMPORT
#define RSA_API DLLIMPORT
#define NETWORKREPLAYSTREAMING_API DLLIMPORT
#define INCLUDE_CHAOS 0
#define WITH_PHYSX 1
#define WITH_CHAOS 0
#define WITH_CHAOS_CLOTHING 0
#define WITH_CHAOS_NEEDS_TO_BE_FIXED 0
#define PHYSICS_INTERFACE_PHYSX 1
#define WITH_APEX 1
#define WITH_APEX_CLOTHING 1
#define WITH_CLOTH_COLLISION_DETECTION 1
#define WITH_PHYSX_COOKING 1
#define WITH_NVCLOTH 1
#define WITH_CUSTOM_SQ_STRUCTURE 0
#define WITH_IMMEDIATE_PHYSX 0
#define PHYSICSCORE_API DLLIMPORT
#define DEVELOPERSETTINGS_API DLLIMPORT
#define COMPILE_WITHOUT_UNREAL_SUPPORT 0
#define INCLUDE_CHAOS 0
#define CHAOS_MEMORY_TRACKING 0
#define CHAOS_API DLLIMPORT
#define COMPILE_WITHOUT_UNREAL_SUPPORT 0
#define INCLUDE_CHAOS 0
#define CHAOS_CHECKED 0
#define CHAOSCORE_API DLLIMPORT
#define INTEL_ISPC 1
#define VORONOI_API DLLIMPORT
#define WITH_PHYSX_RELEASE 0
#define UE_PHYSX_SUFFIX PROFILE
#define UE_APEX_SUFFIX PROFILE
#define APEX_UE4 1
#define APEX_STATICALLY_LINKED 0
#define WITH_APEX_LEGACY 1
#define SIGNALPROCESSING_API DLLIMPORT
#define AUDIOEXTENSIONS_API DLLIMPORT
#define AUDIOMIXERCORE_API DLLIMPORT
#define PROPERTYACCESS_API DLLIMPORT
#define INCLUDE_CHAOS 0
#define WITH_PHYSX 1
#define WITH_CHAOS 0
#define WITH_CHAOS_CLOTHING 0
#define WITH_CHAOS_NEEDS_TO_BE_FIXED 0
#define PHYSICS_INTERFACE_PHYSX 1
#define WITH_APEX 1
#define WITH_APEX_CLOTHING 1
#define WITH_CLOTH_COLLISION_DETECTION 1
#define WITH_PHYSX_COOKING 1
#define WITH_NVCLOTH 1
#define WITH_CUSTOM_SQ_STRUCTURE 0
#define WITH_IMMEDIATE_PHYSX 0
#define WITH_RECAST 1
#define WITH_NAVMESH_SEGMENT_LINKS 1
#define WITH_NAVMESH_CLUSTER_LINKS 1
#define UNREALED_API DLLIMPORT
#define DIRECTORYWATCHER_API DLLIMPORT
#define DOCUMENTATION_API DLLIMPORT
#define READ_TARGET_ENABLED_PLUGINS_FROM_RECEIPT 1
#define LOAD_PLUGINS_FOR_TARGET_PLATFORMS 1
#define PROJECTS_API DLLIMPORT
#define SANDBOXFILE_API DLLIMPORT
#define EDITORSTYLE_API DLLIMPORT
#define SOURCE_CONTROL_WITH_SLATE 1
#define SOURCECONTROL_API DLLIMPORT
#define UNREALEDMESSAGES_API DLLIMPORT
#define GAMEPLAYDEBUGGER_API DLLIMPORT
#define BLUEPRINTGRAPH_API DLLIMPORT
#define EDITORSUBSYSTEM_API DLLIMPORT
#define HTTP_PACKAGE 1
#define CURL_ENABLE_DEBUG_CALLBACK 1
#define CURL_ENABLE_NO_TIMEOUTS_OPTION 1
#define WITH_WINHTTP 1
#define HTTP_API DLLIMPORT
#define UNREALAUDIO_API DLLIMPORT
#define FUNCTIONALTESTING_API DLLIMPORT
#define AUTOMATIONCONTROLLER_API DLLIMPORT
#define LOCALIZATION_API DLLIMPORT
#define WITH_SNDFILE_IO 1
#define AUDIOEDITOR_API DLLIMPORT
#define AUDIOMIXER_API DLLIMPORT
#define TARGETPLATFORM_API DLLIMPORT
#define LEVELEDITOR_API DLLIMPORT
#define SETTINGS_API DLLIMPORT
#define INTROTUTORIALS_API DLLIMPORT
#define HEADMOUNTEDDISPLAY_API DLLIMPORT
#define VREDITOR_API DLLIMPORT
#define COMMONMENUEXTENSIONS_API DLLIMPORT
#define INCLUDE_CHAOS 0
#define WITH_PHYSX 1
#define WITH_CHAOS 0
#define WITH_CHAOS_CLOTHING 0
#define WITH_CHAOS_NEEDS_TO_BE_FIXED 0
#define PHYSICS_INTERFACE_PHYSX 1
#define WITH_APEX 1
#define WITH_APEX_CLOTHING 1
#define WITH_CLOTH_COLLISION_DETECTION 1
#define WITH_PHYSX_COOKING 1
#define WITH_NVCLOTH 1
#define WITH_CUSTOM_SQ_STRUCTURE 0
#define WITH_IMMEDIATE_PHYSX 0
#define LANDSCAPE_API DLLIMPORT
#define PROPERTYEDITOR_API DLLIMPORT
#define ACTORPICKERMODE_API DLLIMPORT
#define SCENEDEPTHPICKERMODE_API DLLIMPORT
#define DETAILCUSTOMIZATIONS_API DLLIMPORT
#define CLASSVIEWER_API DLLIMPORT
#define GRAPHEDITOR_API DLLIMPORT
#define STRUCTVIEWER_API DLLIMPORT
#define CONTENTBROWSER_API DLLIMPORT
#define CONTENTBROWSERDATA_API DLLIMPORT
#define COLLECTIONMANAGER_API DLLIMPORT
#define UELIBSAMPLERATE_API DLLIMPORT
#define ENABLE_HTTP_FOR_NFS 1
#define NETWORKFILESYSTEM_API DLLIMPORT
#define UMG_API DLLIMPORT
#define MOVIESCENE_API DLLIMPORT
#define TIMEMANAGEMENT_API DLLIMPORT
#define MOVIESCENETRACKS_API DLLIMPORT
#define ANIMATIONCORE_API DLLIMPORT
#define PROPERTYPATH_API DLLIMPORT
#define INCLUDE_CHAOS 0
#define WITH_PHYSX 1
#define WITH_CHAOS 0
#define WITH_CHAOS_CLOTHING 0
#define WITH_CHAOS_NEEDS_TO_BE_FIXED 0
#define PHYSICS_INTERFACE_PHYSX 1
#define WITH_APEX 1
#define WITH_APEX_CLOTHING 1
#define WITH_CLOTH_COLLISION_DETECTION 1
#define WITH_PHYSX_COOKING 1
#define WITH_NVCLOTH 1
#define WITH_CUSTOM_SQ_STRUCTURE 0
#define WITH_IMMEDIATE_PHYSX 0
#define WITH_RECAST 1
#define WITH_NAVMESH_SEGMENT_LINKS 1
#define WITH_NAVMESH_CLUSTER_LINKS 1
#define NAVIGATIONSYSTEM_API DLLIMPORT
#define MESHBUILDER_API DLLIMPORT
#define MATERIALSHADERQUALITYSETTINGS_API DLLIMPORT
#define INTERACTIVETOOLSFRAMEWORK_API DLLIMPORT
#define TOOLMENUSEDITOR_API DLLIMPORT
#define TOOLMENUS_API DLLIMPORT
#define WITH_OGGVORBIS 1
#define XAUDIO2_API DLLIMPORT
#define AUDIOMIXERXAUDIO2_API DLLIMPORT
#define ASSETTAGSEDITOR_API DLLIMPORT
#define ADDCONTENTDIALOG_API DLLIMPORT
#define USE_EMBREE 1
#define MESHUTILITIES_API DLLIMPORT
#define MESHMERGEUTILITIES_API DLLIMPORT
#define HIERARCHICALLODUTILITIES_API DLLIMPORT
#define MESHREDUCTIONINTERFACE_API DLLIMPORT
#define ASSETTOOLS_API DLLIMPORT
#define KISMETCOMPILER_API DLLIMPORT
#define GAMEPLAYTASKS_API DLLIMPORT
#define WITH_RECAST 1
#define WITH_GAMEPLAY_DEBUGGER 1
#define AIMODULE_API DLLIMPORT
#define KISMET_API DLLIMPORT
#define INCLUDE_CHAOS 0
#define WITH_PHYSX 1
#define WITH_CHAOS 0
#define WITH_CHAOS_CLOTHING 0
#define WITH_CHAOS_NEEDS_TO_BE_FIXED 0
#define PHYSICS_INTERFACE_PHYSX 1
#define WITH_APEX 1
#define WITH_APEX_CLOTHING 1
#define WITH_CLOTH_COLLISION_DETECTION 1
#define WITH_PHYSX_COOKING 1
#define WITH_NVCLOTH 1
#define WITH_CUSTOM_SQ_STRUCTURE 0
#define WITH_IMMEDIATE_PHYSX 0
#define CLOTHINGSYSTEMRUNTIMEINTERFACE_API DLLIMPORT
#define IMGUI_API DLLEXPORT

View File

@ -0,0 +1,37 @@
{
"RemapUnityFiles":
{
"Module.ImGui.cpp.obj": [
"ImGuiCanvasSizeInfoCustomization.cpp.obj",
"ImGuiEditor.cpp.obj",
"ImGuiKeyInfoCustomization.cpp.obj",
"ImGuiContextManager.cpp.obj",
"ImGuiContextProxy.cpp.obj",
"ImGuiDelegates.cpp.obj",
"ImGuiDelegatesContainer.cpp.obj",
"ImGuiDemo.cpp.obj",
"ImGuiDrawData.cpp.obj",
"ImGuiImplementation.cpp.obj",
"ImGuiInputHandler.cpp.obj",
"ImGuiInputHandlerFactory.cpp.obj",
"ImGuiInputState.cpp.obj",
"ImGuiInteroperability.cpp.obj",
"ImGuiModule.cpp.obj",
"ImGuiModuleCommands.cpp.obj",
"ImGuiModuleManager.cpp.obj",
"ImGuiModuleSettings.cpp.obj",
"ImGuiTextureHandle.cpp.obj",
"TextureManager.cpp.obj",
"DebugExecBindings.cpp.obj",
"WorldContext.cpp.obj",
"SImGuiCanvasControl.cpp.obj",
"SImGuiLayout.cpp.obj",
"SImGuiWidget.cpp.obj"
],
"Module.ImGui.gen.cpp.obj": [
"ImGui.init.gen.cpp.obj",
"ImGuiInputHandler.gen.cpp.obj",
"ImGuiModuleSettings.gen.cpp.obj"
]
}
}

View File

@ -0,0 +1,26 @@
// This file is automatically generated at compile-time to include some subset of the user-created cpp files.
#include "Z:/Projects/Unreal/SwordNGun/SwordNGun/Plugins/UnrealImGui/Source/ImGui/Private/Editor/ImGuiCanvasSizeInfoCustomization.cpp"
#include "Z:/Projects/Unreal/SwordNGun/SwordNGun/Plugins/UnrealImGui/Source/ImGui/Private/Editor/ImGuiEditor.cpp"
#include "Z:/Projects/Unreal/SwordNGun/SwordNGun/Plugins/UnrealImGui/Source/ImGui/Private/Editor/ImGuiKeyInfoCustomization.cpp"
#include "Z:/Projects/Unreal/SwordNGun/SwordNGun/Plugins/UnrealImGui/Source/ImGui/Private/ImGuiContextManager.cpp"
#include "Z:/Projects/Unreal/SwordNGun/SwordNGun/Plugins/UnrealImGui/Source/ImGui/Private/ImGuiContextProxy.cpp"
#include "Z:/Projects/Unreal/SwordNGun/SwordNGun/Plugins/UnrealImGui/Source/ImGui/Private/ImGuiDelegates.cpp"
#include "Z:/Projects/Unreal/SwordNGun/SwordNGun/Plugins/UnrealImGui/Source/ImGui/Private/ImGuiDelegatesContainer.cpp"
#include "Z:/Projects/Unreal/SwordNGun/SwordNGun/Plugins/UnrealImGui/Source/ImGui/Private/ImGuiDemo.cpp"
#include "Z:/Projects/Unreal/SwordNGun/SwordNGun/Plugins/UnrealImGui/Source/ImGui/Private/ImGuiDrawData.cpp"
#include "Z:/Projects/Unreal/SwordNGun/SwordNGun/Plugins/UnrealImGui/Source/ImGui/Private/ImGuiImplementation.cpp"
#include "Z:/Projects/Unreal/SwordNGun/SwordNGun/Plugins/UnrealImGui/Source/ImGui/Private/ImGuiInputHandler.cpp"
#include "Z:/Projects/Unreal/SwordNGun/SwordNGun/Plugins/UnrealImGui/Source/ImGui/Private/ImGuiInputHandlerFactory.cpp"
#include "Z:/Projects/Unreal/SwordNGun/SwordNGun/Plugins/UnrealImGui/Source/ImGui/Private/ImGuiInputState.cpp"
#include "Z:/Projects/Unreal/SwordNGun/SwordNGun/Plugins/UnrealImGui/Source/ImGui/Private/ImGuiInteroperability.cpp"
#include "Z:/Projects/Unreal/SwordNGun/SwordNGun/Plugins/UnrealImGui/Source/ImGui/Private/ImGuiModule.cpp"
#include "Z:/Projects/Unreal/SwordNGun/SwordNGun/Plugins/UnrealImGui/Source/ImGui/Private/ImGuiModuleCommands.cpp"
#include "Z:/Projects/Unreal/SwordNGun/SwordNGun/Plugins/UnrealImGui/Source/ImGui/Private/ImGuiModuleManager.cpp"
#include "Z:/Projects/Unreal/SwordNGun/SwordNGun/Plugins/UnrealImGui/Source/ImGui/Private/ImGuiModuleSettings.cpp"
#include "Z:/Projects/Unreal/SwordNGun/SwordNGun/Plugins/UnrealImGui/Source/ImGui/Private/ImGuiTextureHandle.cpp"
#include "Z:/Projects/Unreal/SwordNGun/SwordNGun/Plugins/UnrealImGui/Source/ImGui/Private/TextureManager.cpp"
#include "Z:/Projects/Unreal/SwordNGun/SwordNGun/Plugins/UnrealImGui/Source/ImGui/Private/Utilities/DebugExecBindings.cpp"
#include "Z:/Projects/Unreal/SwordNGun/SwordNGun/Plugins/UnrealImGui/Source/ImGui/Private/Utilities/WorldContext.cpp"
#include "Z:/Projects/Unreal/SwordNGun/SwordNGun/Plugins/UnrealImGui/Source/ImGui/Private/Widgets/SImGuiCanvasControl.cpp"
#include "Z:/Projects/Unreal/SwordNGun/SwordNGun/Plugins/UnrealImGui/Source/ImGui/Private/Widgets/SImGuiLayout.cpp"
#include "Z:/Projects/Unreal/SwordNGun/SwordNGun/Plugins/UnrealImGui/Source/ImGui/Private/Widgets/SImGuiWidget.cpp"

View File

@ -0,0 +1,276 @@
/Zc:inline
/nologo
/Oi
/c
/Gw
/Gy
/Zm1000
/wd4819
/D_CRT_STDIO_LEGACY_WIDE_SPECIFIERS=1
/D_SILENCE_STDEXT_HASH_DEPRECATION_WARNINGS=1
/D_WINDLL
/D_DISABLE_EXTENDED_ALIGNED_STORAGE
/source-charset:utf-8
/execution-charset:utf-8
/Ob2
/Ox
/Ot
/GF
/errorReport:prompt
/EHsc
/Z7
/MD
/bigobj
/fp:fast
/Zo
/Zp8
/we4456
/we4458
/we4459
/wd4463
/wd4244
/wd4838
/I .
/I Z:\Projects\Unreal\SwordNGun\SwordNGun\Plugins\UnrealImGui\Source\ImGui\Private
/I Z:\Projects\Unreal\SwordNGun\SwordNGun\Plugins\UnrealImGui\Source\ThirdParty\ImGuiLibrary\Private
/I ..\Intermediate\Build\Win64\UE4Editor\Inc\CoreUObject
/I Runtime
/I Runtime\CoreUObject\Public
/I Runtime\TraceLog\Public
/I Runtime\Core\Public
/I ..\Intermediate\Build\Win64\UE4Editor\Inc\Engine
/I Runtime\Engine\Classes
/I Runtime\Engine\Public
/I ..\Intermediate\Build\Win64\UE4Editor\Inc\NetCore
/I Runtime\Net
/I Runtime\Net\Core\Classes
/I Runtime\Net\Core\Public
/I Runtime\ApplicationCore\Public
/I Runtime\RHI\Public
/I Runtime\Json\Public
/I ..\Intermediate\Build\Win64\UE4Editor\Inc\SlateCore
/I Runtime\SlateCore\Public
/I ..\Intermediate\Build\Win64\UE4Editor\Inc\InputCore
/I Runtime\InputCore\Classes
/I Runtime\InputCore\Public
/I ..\Intermediate\Build\Win64\UE4Editor\Inc\Slate
/I Runtime\Slate\Public
/I ..\Intermediate\Build\Win64\UE4Editor\Inc\ImageWrapper
/I Runtime\ImageWrapper\Public
/I Runtime\Messaging\Public
/I Runtime\MessagingCommon\Public
/I Runtime\RenderCore\Public
/I Runtime\Analytics
/I Runtime\Analytics\AnalyticsET\Public
/I Runtime\Analytics\Analytics\Public
/I Runtime\Sockets\Public
/I Runtime\Net\Common\Public
/I ..\Intermediate\Build\Win64\UE4Editor\Inc\AssetRegistry
/I Runtime\AssetRegistry\Public
/I ..\Intermediate\Build\Win64\UE4Editor\Inc\EngineMessages
/I Runtime\EngineMessages\Public
/I ..\Intermediate\Build\Win64\UE4Editor\Inc\EngineSettings
/I Runtime\EngineSettings\Classes
/I Runtime\EngineSettings\Public
/I Runtime\SynthBenchmark\Public
/I ..\Intermediate\Build\Win64\UE4Editor\Inc\Renderer
/I Runtime\Renderer\Public
/I ..\Intermediate\Build\Win64\UE4Editor\Inc\GameplayTags
/I Runtime\GameplayTags\Classes
/I Runtime\GameplayTags\Public
/I ..\Intermediate\Build\Win64\UE4Editor\Inc\PacketHandler
/I Runtime\PacketHandlers
/I Runtime\PacketHandlers\PacketHandler\Classes
/I Runtime\PacketHandlers\PacketHandler\Public
/I Runtime\PacketHandlers\ReliabilityHandlerComponent\Public
/I ..\Intermediate\Build\Win64\UE4Editor\Inc\AudioPlatformConfiguration
/I Runtime\AudioPlatformConfiguration\Public
/I ..\Intermediate\Build\Win64\UE4Editor\Inc\MeshDescription
/I Runtime\MeshDescription\Public
/I ..\Intermediate\Build\Win64\UE4Editor\Inc\StaticMeshDescription
/I Runtime\StaticMeshDescription\Public
/I Runtime\PakFile\Public
/I Runtime\RSA\Public
/I Runtime\NetworkReplayStreaming
/I Runtime\NetworkReplayStreaming\NetworkReplayStreaming\Public
/I ..\Intermediate\Build\Win64\UE4Editor\Inc\PhysicsCore
/I Runtime\PhysicsCore\Public
/I ..\Intermediate\Build\Win64\UE4Editor\Inc\DeveloperSettings
/I Runtime\DeveloperSettings\Public
/I ..\Intermediate\Build\Win64\UE4Editor\Inc\Chaos
/I Runtime\Experimental
/I Runtime\Experimental\Chaos\Public
/I Runtime\Experimental\ChaosCore\Public
/I ThirdParty\Intel
/I Runtime\Experimental\Voronoi\Public
/I ThirdParty
/I Runtime\SignalProcessing\Public
/I ..\Intermediate\Build\Win64\UE4Editor\Inc\AudioExtensions
/I Runtime\AudioExtensions\Public
/I Runtime\AudioMixerCore\Public
/I ..\Intermediate\Build\Win64\UE4Editor\Inc\PropertyAccess
/I Runtime\PropertyAccess\Public
/I ..\Intermediate\Build\Win64\UE4Editor\Inc\UnrealEd
/I Editor
/I Programs\UnrealLightmass\Public
/I Developer\Android\AndroidDeviceDetection\Public\Interfaces
/I Editor\UnrealEd\Classes
/I Editor\UnrealEd\Public
/I Developer
/I Developer\DirectoryWatcher\Public
/I Editor\Documentation\Public
/I Runtime\Projects\Public
/I Runtime\SandboxFile\Public
/I ..\Intermediate\Build\Win64\UE4Editor\Inc\EditorStyle
/I Editor\EditorStyle\Public
/I ..\Intermediate\Build\Win64\UE4Editor\Inc\SourceControl
/I Developer\SourceControl\Public
/I ..\Intermediate\Build\Win64\UE4Editor\Inc\UnrealEdMessages
/I Editor\UnrealEdMessages\Classes
/I Editor\UnrealEdMessages\Public
/I ..\Intermediate\Build\Win64\UE4Editor\Inc\GameplayDebugger
/I Developer\GameplayDebugger\Public
/I ..\Intermediate\Build\Win64\UE4Editor\Inc\BlueprintGraph
/I Editor\BlueprintGraph\Classes
/I Editor\BlueprintGraph\Public
/I ..\Intermediate\Build\Win64\UE4Editor\Inc\EditorSubsystem
/I Editor\EditorSubsystem\Public
/I Runtime\Online
/I Runtime\Online\HTTP\Public
/I Runtime\UnrealAudio\Public
/I ..\Intermediate\Build\Win64\UE4Editor\Inc\FunctionalTesting
/I Developer\FunctionalTesting\Classes
/I Developer\FunctionalTesting\Public
/I ..\Intermediate\Build\Win64\UE4Editor\Inc\AutomationController
/I Developer\AutomationController\Public
/I ..\Intermediate\Build\Win64\UE4Editor\Inc\Localization
/I Developer\Localization\Public
/I ..\Intermediate\Build\Win64\UE4Editor\Inc\AudioEditor
/I Editor\AudioEditor\Classes
/I Editor\AudioEditor\Public
/I ..\Intermediate\Build\Win64\UE4Editor\Inc\AudioMixer
/I Runtime\AudioMixer\Classes
/I Runtime\AudioMixer\Public
/I Developer\TargetPlatform\Public
/I ..\Intermediate\Build\Win64\UE4Editor\Inc\LevelEditor
/I Editor\LevelEditor\Public
/I Developer\Settings\Public
/I ..\Intermediate\Build\Win64\UE4Editor\Inc\IntroTutorials
/I Editor\IntroTutorials\Public
/I ..\Intermediate\Build\Win64\UE4Editor\Inc\HeadMountedDisplay
/I Runtime\HeadMountedDisplay\Public
/I ..\Intermediate\Build\Win64\UE4Editor\Inc\VREditor
/I Editor\VREditor
/I Editor\VREditor\Public
/I Editor\CommonMenuExtensions\Public
/I ..\Intermediate\Build\Win64\UE4Editor\Inc\Landscape
/I Runtime\Landscape\Classes
/I Runtime\Landscape\Public
/I ..\Intermediate\Build\Win64\UE4Editor\Inc\PropertyEditor
/I Editor\PropertyEditor\Public
/I Editor\ActorPickerMode\Public
/I Editor\SceneDepthPickerMode\Public
/I ..\Intermediate\Build\Win64\UE4Editor\Inc\DetailCustomizations
/I Editor\DetailCustomizations\Public
/I ..\Intermediate\Build\Win64\UE4Editor\Inc\ClassViewer
/I Editor\ClassViewer\Public
/I ..\Intermediate\Build\Win64\UE4Editor\Inc\GraphEditor
/I Editor\GraphEditor\Public
/I ..\Intermediate\Build\Win64\UE4Editor\Inc\StructViewer
/I Editor\StructViewer\Public
/I ..\Intermediate\Build\Win64\UE4Editor\Inc\ContentBrowser
/I Editor\ContentBrowser\Public
/I ..\Intermediate\Build\Win64\UE4Editor\Inc\ContentBrowserData
/I Editor\ContentBrowserData\Public
/I Developer\CollectionManager\Public
/I ThirdParty\libSampleRate\Public
/I Runtime\NetworkFileSystem\Public
/I ..\Intermediate\Build\Win64\UE4Editor\Inc\UMG
/I Runtime\UMG\Public
/I ..\Intermediate\Build\Win64\UE4Editor\Inc\MovieScene
/I Runtime\MovieScene\Public
/I ..\Intermediate\Build\Win64\UE4Editor\Inc\TimeManagement
/I Runtime\TimeManagement\Public
/I ..\Intermediate\Build\Win64\UE4Editor\Inc\MovieSceneTracks
/I Runtime\MovieSceneTracks\Public
/I ..\Intermediate\Build\Win64\UE4Editor\Inc\AnimationCore
/I Runtime\AnimationCore\Public
/I ..\Intermediate\Build\Win64\UE4Editor\Inc\PropertyPath
/I Runtime\PropertyPath\Public
/I ..\Intermediate\Build\Win64\UE4Editor\Inc\NavigationSystem
/I Runtime\NavigationSystem\Public
/I Developer\MeshBuilder\Public
/I ..\Intermediate\Build\Win64\UE4Editor\Inc\MaterialShaderQualitySettings
/I Runtime\MaterialShaderQualitySettings\Classes
/I ..\Intermediate\Build\Win64\UE4Editor\Inc\InteractiveToolsFramework
/I Runtime\Experimental\InteractiveToolsFramework\Public
/I ..\Intermediate\Build\Win64\UE4Editor\Inc\ToolMenusEditor
/I Editor\ToolMenusEditor\Public
/I ..\Intermediate\Build\Win64\UE4Editor\Inc\ToolMenus
/I Developer\ToolMenus\Public
/I Runtime\Windows
/I Runtime\Windows\XAudio2\Public
/I Editor\AssetTagsEditor\Public
/I ..\Intermediate\Build\Win64\UE4Editor\Inc\AddContentDialog
/I Editor\AddContentDialog\Public
/I ThirdParty\Intel\Embree\Embree2140\Win64\include
/I Developer\MeshUtilities\Public
/I Developer\MeshMergeUtilities\Public
/I Developer\HierarchicalLODUtilities\Public
/I Developer\MeshReductionInterface\Public
/I ..\Intermediate\Build\Win64\UE4Editor\Inc\AssetTools
/I Developer\AssetTools\Public
/I Editor\KismetCompiler\Public
/I ..\Intermediate\Build\Win64\UE4Editor\Inc\GameplayTasks
/I Runtime\GameplayTasks\Classes
/I Runtime\GameplayTasks\Public
/I ..\Intermediate\Build\Win64\UE4Editor\Inc\AIModule
/I Runtime\AIModule\Public
/I Runtime\AIModule\Classes
/I ..\Intermediate\Build\Win64\UE4Editor\Inc\Kismet
/I Editor\Kismet\Classes
/I Editor\Kismet\Public
/I ..\Intermediate\Build\Win64\UE4Editor\Inc\ClothingSystemRuntimeInterface
/I Runtime\ClothingSystemRuntimeInterface\Public
/I Z:\Projects\Unreal\SwordNGun\SwordNGun\Plugins\UnrealImGui\Intermediate\Build\Win64\UE4Editor\Inc\ImGui
/I Z:\Projects\Unreal\SwordNGun\SwordNGun\Plugins\UnrealImGui\Source
/I Z:\Projects\Unreal\SwordNGun\SwordNGun\Plugins\UnrealImGui\Source\ThirdParty\ImGuiLibrary\Include
/I Z:\Projects\Unreal\SwordNGun\SwordNGun\Plugins\UnrealImGui\Source\ImGui\Public
/I ThirdParty\PhysX3\PxShared\include
/I ThirdParty\PhysX3\PxShared\include\cudamanager
/I ThirdParty\PhysX3\PxShared\include\filebuf
/I ThirdParty\PhysX3\PxShared\include\foundation
/I ThirdParty\PhysX3\PxShared\include\pvd
/I ThirdParty\PhysX3\PxShared\include\task
/I ThirdParty\PhysX3\PhysX_3.4\Include
/I ThirdParty\PhysX3\PhysX_3.4\Include\cooking
/I ThirdParty\PhysX3\PhysX_3.4\Include\common
/I ThirdParty\PhysX3\PhysX_3.4\Include\extensions
/I ThirdParty\PhysX3\PhysX_3.4\Include\geometry
/I ThirdParty\PhysX3\APEX_1.4\include
/I ThirdParty\PhysX3\APEX_1.4\include\clothing
/I ThirdParty\PhysX3\APEX_1.4\include\nvparameterized
/I ThirdParty\PhysX3\APEX_1.4\include\legacy
/I ThirdParty\PhysX3\APEX_1.4\include\PhysX3
/I ThirdParty\PhysX3\APEX_1.4\common\include
/I ThirdParty\PhysX3\APEX_1.4\common\include\autogen
/I ThirdParty\PhysX3\APEX_1.4\framework\include
/I ThirdParty\PhysX3\APEX_1.4\framework\include\autogen
/I ThirdParty\PhysX3\APEX_1.4\shared\general\RenderDebug\public
/I ThirdParty\PhysX3\APEX_1.4\shared\general\PairFilter\include
/I ThirdParty\PhysX3\APEX_1.4\shared\internal\include
/I "C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.28.29910\INCLUDE"
/I "C:\Program Files (x86)\Windows Kits\NETFXSDK\4.8\include\um"
/I "C:\Program Files (x86)\Windows Kits\10\include\10.0.18362.0\ucrt"
/I "C:\Program Files (x86)\Windows Kits\10\include\10.0.18362.0\shared"
/I "C:\Program Files (x86)\Windows Kits\10\include\10.0.18362.0\um"
/I "C:\Program Files (x86)\Windows Kits\10\include\10.0.18362.0\winrt"
/FI"Z:\Projects\Unreal\SwordNGun\SwordNGun\Intermediate\Build\Win64\SwordNGunEditor\Development\UnrealEd\SharedPCH.UnrealEd.ShadowErrors.h"
/Yu"Z:\Projects\Unreal\SwordNGun\SwordNGun\Intermediate\Build\Win64\SwordNGunEditor\Development\UnrealEd\SharedPCH.UnrealEd.ShadowErrors.h"
/Fp"Z:\Projects\Unreal\SwordNGun\SwordNGun\Intermediate\Build\Win64\SwordNGunEditor\Development\UnrealEd\SharedPCH.UnrealEd.ShadowErrors.h.pch"
"Z:\Projects\Unreal\SwordNGun\SwordNGun\Plugins\UnrealImGui\Intermediate\Build\Win64\UE4Editor\Development\ImGui\Module.ImGui.cpp"
/FI"Z:\Projects\Unreal\SwordNGun\SwordNGun\Plugins\UnrealImGui\Intermediate\Build\Win64\UE4Editor\Development\ImGui\Definitions.ImGui.h"
/Fo"Z:\Projects\Unreal\SwordNGun\SwordNGun\Plugins\UnrealImGui\Intermediate\Build\Win64\UE4Editor\Development\ImGui\Module.ImGui.cpp.obj"
/TP
/GR-
/W4

View File

@ -0,0 +1,250 @@
Z:\Projects\Unreal\SwordNGun\SwordNGun\Plugins\UnrealImGui\Intermediate\Build\Win64\UE4Editor\Development\ImGui\Definitions.ImGui.h
Z:/Projects/Unreal/SwordNGun/SwordNGun/Plugins/UnrealImGui/Source/ImGui/Private/Editor/ImGuiCanvasSizeInfoCustomization.cpp
Z:\Projects\Unreal\SwordNGun\SwordNGun\Plugins\UnrealImGui\Source\ImGui\Private\Editor\ImGuiCanvasSizeInfoCustomization.h
Z:\Projects\Unreal\SwordNGun\SwordNGun\Plugins\UnrealImGui\Source\ImGui\Private\ImGuiModuleSettings.h
Z:\Projects\Unreal\SwordNGun\SwordNGun\Plugins\UnrealImGui\Source\ImGui\Private\VersionCompatibility.h
Z:\Projects\Unreal\SwordNGun\SwordNGun\Plugins\UnrealImGui\Intermediate\Build\Win64\UE4Editor\Inc\ImGui\ImGuiModuleSettings.generated.h
C:\Program Files\Epic Games\UE_4.26\Engine\Source\Editor\PropertyEditor\Public\PropertyCustomizationHelpers.h
C:\Program Files\Epic Games\UE_4.26\Engine\Source\Editor\PropertyEditor\Public\IDetailCustomNodeBuilder.h
C:\Program Files\Epic Games\UE_4.26\Engine\Source\Editor\PropertyEditor\Public\DetailWidgetRow.h
C:\Program Files\Epic Games\UE_4.26\Engine\Source\Editor\PropertyEditor\Public\SResetToDefaultMenu.h
C:\Program Files\Epic Games\UE_4.26\Engine\Source\Editor\ActorPickerMode\Public\ActorPickerMode.h
C:\Program Files\Epic Games\UE_4.26\Engine\Source\Editor\SceneDepthPickerMode\Public\SceneDepthPickerMode.h
C:\Program Files\Epic Games\UE_4.26\Engine\Source\Editor\PropertyEditor\Public\IDetailPropertyRow.h
Z:/Projects/Unreal/SwordNGun/SwordNGun/Plugins/UnrealImGui/Source/ImGui/Private/Editor/ImGuiEditor.cpp
Z:\Projects\Unreal\SwordNGun\SwordNGun\Plugins\UnrealImGui\Source\ImGui\Private\Editor\ImGuiEditor.h
Z:\Projects\Unreal\SwordNGun\SwordNGun\Plugins\UnrealImGui\Source\ImGui\Private\Editor\ImGuiKeyInfoCustomization.h
C:\Program Files\Epic Games\UE_4.26\Engine\Source\Developer\Settings\Public\ISettingsModule.h
Z:/Projects/Unreal/SwordNGun/SwordNGun/Plugins/UnrealImGui/Source/ImGui/Private/Editor/ImGuiKeyInfoCustomization.cpp
C:\Program Files\Epic Games\UE_4.26\Engine\Source\Editor\UnrealEd\Public\SKeySelector.h
Z:/Projects/Unreal/SwordNGun/SwordNGun/Plugins/UnrealImGui/Source/ImGui/Private/ImGuiContextManager.cpp
Z:\Projects\Unreal\SwordNGun\SwordNGun\Plugins\UnrealImGui\Source\ImGui\Private\ImGuiContextManager.h
Z:\Projects\Unreal\SwordNGun\SwordNGun\Plugins\UnrealImGui\Source\ImGui\Private\ImGuiContextProxy.h
Z:\Projects\Unreal\SwordNGun\SwordNGun\Plugins\UnrealImGui\Source\ImGui\Private\ImGuiDrawData.h
Z:\Projects\Unreal\SwordNGun\SwordNGun\Plugins\UnrealImGui\Source\ImGui\Private\ImGuiInteroperability.h
Z:\Projects\Unreal\SwordNGun\SwordNGun\Plugins\UnrealImGui\Source\ImGui\Private\TextureManager.h
Z:\Projects\Unreal\SwordNGun\SwordNGun\Plugins\UnrealImGui\Source\ThirdParty\ImGuiLibrary\Include\imgui.h
Z:\Projects\Unreal\SwordNGun\SwordNGun\Plugins\UnrealImGui\Source\ThirdParty\ImGuiLibrary\Include\imconfig.h
C:\Program Files (x86)\Windows Kits\10\include\10.0.18362.0\ucrt\assert.h
Z:\Projects\Unreal\SwordNGun\SwordNGun\Plugins\UnrealImGui\Source\ImGui\Private\VersionCompatibility.h
Z:\Projects\Unreal\SwordNGun\SwordNGun\Plugins\UnrealImGui\Source\ImGui\Private\ImGuiInputState.h
Z:\Projects\Unreal\SwordNGun\SwordNGun\Plugins\UnrealImGui\Source\ImGui\Private\Utilities/Arrays.h
Z:\Projects\Unreal\SwordNGun\SwordNGun\Plugins\UnrealImGui\Source\ImGui\Private\Utilities\Range.h
C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.28.29910\INCLUDE\utility
C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.28.29910\INCLUDE\array
C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.28.29910\INCLUDE\xutility
C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.28.29910\INCLUDE\iterator
C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.28.29910\INCLUDE\iosfwd
C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.28.29910\INCLUDE\cstdio
C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.28.29910\INCLUDE\cwchar
Z:\Projects\Unreal\SwordNGun\SwordNGun\Plugins\UnrealImGui\Source\ImGui\Private\Utilities/WorldContextIndex.h
Z:\Projects\Unreal\SwordNGun\SwordNGun\Plugins\UnrealImGui\Source\ImGui\Private\Utilities/WorldContext.h
C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.28.29910\INCLUDE\string
C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.28.29910\INCLUDE\xstring
C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.28.29910\INCLUDE\xmemory
C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.28.29910\INCLUDE\limits
C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.28.29910\INCLUDE\cfloat
C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.28.29910\INCLUDE\isa_availability.h
C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.28.29910\INCLUDE\cctype
Z:\Projects\Unreal\SwordNGun\SwordNGun\Plugins\UnrealImGui\Source\ImGui\Private\VersionCompatibility.h
Z:\Projects\Unreal\SwordNGun\SwordNGun\Plugins\UnrealImGui\Source\ImGui\Private\ImGuiDelegatesContainer.h
Z:\Projects\Unreal\SwordNGun\SwordNGun\Plugins\UnrealImGui\Source\ImGui\Private\ImGuiImplementation.h
Z:/Projects/Unreal/SwordNGun/SwordNGun/Plugins/UnrealImGui/Source/ImGui/Private/ImGuiContextProxy.cpp
Z:\Projects\Unreal\SwordNGun\SwordNGun\Plugins\UnrealImGui\Source\ImGui\Private\VersionCompatibility.h
Z:/Projects/Unreal/SwordNGun/SwordNGun/Plugins/UnrealImGui/Source/ImGui/Private/ImGuiDelegates.cpp
Z:\Projects\Unreal\SwordNGun\SwordNGun\Plugins\UnrealImGui\Source\ImGui\Public\ImGuiDelegates.h
Z:/Projects/Unreal/SwordNGun/SwordNGun/Plugins/UnrealImGui/Source/ImGui/Private/ImGuiDelegatesContainer.cpp
Z:\Projects\Unreal\SwordNGun\SwordNGun\Plugins\UnrealImGui\Source\ImGui\Public\ImGuiModule.h
Z:\Projects\Unreal\SwordNGun\SwordNGun\Plugins\UnrealImGui\Source\ImGui\Public\ImGuiModuleProperties.h
Z:\Projects\Unreal\SwordNGun\SwordNGun\Plugins\UnrealImGui\Source\ImGui\Public\ImGuiTextureHandle.h
Z:\Projects\Unreal\SwordNGun\SwordNGun\Plugins\UnrealImGui\Source\ImGui\Private\Utilities/RedirectingHandle.h
Z:/Projects/Unreal/SwordNGun/SwordNGun/Plugins/UnrealImGui/Source/ImGui/Private/ImGuiDemo.cpp
Z:\Projects\Unreal\SwordNGun\SwordNGun\Plugins\UnrealImGui\Source\ImGui\Private\ImGuiDemo.h
Z:/Projects/Unreal/SwordNGun/SwordNGun/Plugins/UnrealImGui/Source/ImGui/Private/ImGuiDrawData.cpp
Z:/Projects/Unreal/SwordNGun/SwordNGun/Plugins/UnrealImGui/Source/ImGui/Private/ImGuiImplementation.cpp
C:\Program Files\Epic Games\UE_4.26\Engine\Source\Runtime\Core\Public\Windows/AllowWindowsPlatformTypes.h
C:\Program Files\Epic Games\UE_4.26\Engine\Source\Runtime\Core\Public\Windows/WindowsHWrapper.h
C:\Program Files\Epic Games\UE_4.26\Engine\Source\Runtime\Core\Public\Windows/PreWindowsApi.h
C:\Program Files\Epic Games\UE_4.26\Engine\Source\Runtime\Core\Public\Windows/MinWindows.h
C:\Program Files (x86)\Windows Kits\10\include\10.0.18362.0\um\Windows.h
C:\Program Files (x86)\Windows Kits\10\include\10.0.18362.0\shared\sdkddkver.h
C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.28.29910\INCLUDE\excpt.h
C:\Program Files (x86)\Windows Kits\10\include\10.0.18362.0\shared\windef.h
C:\Program Files (x86)\Windows Kits\10\include\10.0.18362.0\shared\minwindef.h
C:\Program Files (x86)\Windows Kits\10\include\10.0.18362.0\um\winnt.h
C:\Program Files (x86)\Windows Kits\10\include\10.0.18362.0\shared\kernelspecs.h
C:\Program Files (x86)\Windows Kits\10\include\10.0.18362.0\shared\basetsd.h
C:\Program Files (x86)\Windows Kits\10\include\10.0.18362.0\shared\guiddef.h
C:\Program Files (x86)\Windows Kits\10\include\10.0.18362.0\shared\pshpack4.h
C:\Program Files (x86)\Windows Kits\10\include\10.0.18362.0\shared\poppack.h
C:\Program Files (x86)\Windows Kits\10\include\10.0.18362.0\shared\pshpack4.h
C:\Program Files (x86)\Windows Kits\10\include\10.0.18362.0\shared\poppack.h
C:\Program Files (x86)\Windows Kits\10\include\10.0.18362.0\shared\pshpack4.h
C:\Program Files (x86)\Windows Kits\10\include\10.0.18362.0\shared\pshpack2.h
C:\Program Files (x86)\Windows Kits\10\include\10.0.18362.0\shared\poppack.h
C:\Program Files (x86)\Windows Kits\10\include\10.0.18362.0\shared\pshpack2.h
C:\Program Files (x86)\Windows Kits\10\include\10.0.18362.0\shared\pshpack2.h
C:\Program Files (x86)\Windows Kits\10\include\10.0.18362.0\shared\poppack.h
C:\Program Files (x86)\Windows Kits\10\include\10.0.18362.0\shared\poppack.h
C:\Program Files (x86)\Windows Kits\10\include\10.0.18362.0\shared\pshpack8.h
C:\Program Files (x86)\Windows Kits\10\include\10.0.18362.0\shared\poppack.h
C:\Program Files (x86)\Windows Kits\10\include\10.0.18362.0\shared\pshpack1.h
C:\Program Files (x86)\Windows Kits\10\include\10.0.18362.0\shared\poppack.h
C:\Program Files (x86)\Windows Kits\10\include\10.0.18362.0\shared\pshpack1.h
C:\Program Files (x86)\Windows Kits\10\include\10.0.18362.0\shared\poppack.h
C:\Program Files (x86)\Windows Kits\10\include\10.0.18362.0\shared\poppack.h
C:\Program Files (x86)\Windows Kits\10\include\10.0.18362.0\shared\apiset.h
C:\Program Files (x86)\Windows Kits\10\include\10.0.18362.0\shared\ktmtypes.h
C:\Program Files (x86)\Windows Kits\10\include\10.0.18362.0\um\winbase.h
C:\Program Files (x86)\Windows Kits\10\include\10.0.18362.0\shared\apisetcconv.h
C:\Program Files (x86)\Windows Kits\10\include\10.0.18362.0\um\minwinbase.h
C:\Program Files (x86)\Windows Kits\10\include\10.0.18362.0\um\apiquery2.h
C:\Program Files (x86)\Windows Kits\10\include\10.0.18362.0\um\processenv.h
C:\Program Files (x86)\Windows Kits\10\include\10.0.18362.0\um\fileapifromapp.h
C:\Program Files (x86)\Windows Kits\10\include\10.0.18362.0\um\fileapi.h
C:\Program Files (x86)\Windows Kits\10\include\10.0.18362.0\um\debugapi.h
C:\Program Files (x86)\Windows Kits\10\include\10.0.18362.0\um\utilapiset.h
C:\Program Files (x86)\Windows Kits\10\include\10.0.18362.0\um\handleapi.h
C:\Program Files (x86)\Windows Kits\10\include\10.0.18362.0\um\errhandlingapi.h
C:\Program Files (x86)\Windows Kits\10\include\10.0.18362.0\um\fibersapi.h
C:\Program Files (x86)\Windows Kits\10\include\10.0.18362.0\um\namedpipeapi.h
C:\Program Files (x86)\Windows Kits\10\include\10.0.18362.0\um\profileapi.h
C:\Program Files (x86)\Windows Kits\10\include\10.0.18362.0\um\heapapi.h
C:\Program Files (x86)\Windows Kits\10\include\10.0.18362.0\um\ioapiset.h
C:\Program Files (x86)\Windows Kits\10\include\10.0.18362.0\um\synchapi.h
C:\Program Files (x86)\Windows Kits\10\include\10.0.18362.0\um\interlockedapi.h
C:\Program Files (x86)\Windows Kits\10\include\10.0.18362.0\um\processthreadsapi.h
C:\Program Files (x86)\Windows Kits\10\include\10.0.18362.0\um\sysinfoapi.h
C:\Program Files (x86)\Windows Kits\10\include\10.0.18362.0\um\memoryapi.h
C:\Program Files (x86)\Windows Kits\10\include\10.0.18362.0\um\enclaveapi.h
C:\Program Files (x86)\Windows Kits\10\include\10.0.18362.0\um\threadpoollegacyapiset.h
C:\Program Files (x86)\Windows Kits\10\include\10.0.18362.0\um\threadpoolapiset.h
C:\Program Files (x86)\Windows Kits\10\include\10.0.18362.0\um\jobapi.h
C:\Program Files (x86)\Windows Kits\10\include\10.0.18362.0\um\jobapi2.h
C:\Program Files (x86)\Windows Kits\10\include\10.0.18362.0\um\wow64apiset.h
C:\Program Files (x86)\Windows Kits\10\include\10.0.18362.0\um\libloaderapi.h
C:\Program Files (x86)\Windows Kits\10\include\10.0.18362.0\um\securitybaseapi.h
C:\Program Files (x86)\Windows Kits\10\include\10.0.18362.0\um\namespaceapi.h
C:\Program Files (x86)\Windows Kits\10\include\10.0.18362.0\um\systemtopologyapi.h
C:\Program Files (x86)\Windows Kits\10\include\10.0.18362.0\um\processtopologyapi.h
C:\Program Files (x86)\Windows Kits\10\include\10.0.18362.0\um\securityappcontainer.h
C:\Program Files (x86)\Windows Kits\10\include\10.0.18362.0\um\realtimeapiset.h
C:\Program Files (x86)\Windows Kits\10\include\10.0.18362.0\shared\winerror.h
C:\Program Files (x86)\Windows Kits\10\include\10.0.18362.0\um\timezoneapi.h
C:\Program Files (x86)\Windows Kits\10\include\10.0.18362.0\um\wingdi.h
C:\Program Files (x86)\Windows Kits\10\include\10.0.18362.0\shared\pshpack1.h
C:\Program Files (x86)\Windows Kits\10\include\10.0.18362.0\shared\poppack.h
C:\Program Files (x86)\Windows Kits\10\include\10.0.18362.0\shared\pshpack2.h
C:\Program Files (x86)\Windows Kits\10\include\10.0.18362.0\shared\poppack.h
C:\Program Files (x86)\Windows Kits\10\include\10.0.18362.0\shared\pshpack4.h
C:\Program Files (x86)\Windows Kits\10\include\10.0.18362.0\shared\poppack.h
C:\Program Files (x86)\Windows Kits\10\include\10.0.18362.0\shared\pshpack4.h
C:\Program Files (x86)\Windows Kits\10\include\10.0.18362.0\shared\poppack.h
C:\Program Files (x86)\Windows Kits\10\include\10.0.18362.0\um\winuser.h
C:\Program Files (x86)\Windows Kits\10\include\10.0.18362.0\shared\pshpack2.h
C:\Program Files (x86)\Windows Kits\10\include\10.0.18362.0\shared\poppack.h
C:\Program Files (x86)\Windows Kits\10\include\10.0.18362.0\shared\tvout.h
C:\Program Files (x86)\Windows Kits\10\include\10.0.18362.0\um\winnls.h
C:\Program Files (x86)\Windows Kits\10\include\10.0.18362.0\um\datetimeapi.h
C:\Program Files (x86)\Windows Kits\10\include\10.0.18362.0\um\stringapiset.h
C:\Program Files (x86)\Windows Kits\10\include\10.0.18362.0\um\winnls.h
C:\Program Files (x86)\Windows Kits\10\include\10.0.18362.0\um\wincon.h
C:\Program Files (x86)\Windows Kits\10\include\10.0.18362.0\um\wincontypes.h
C:\Program Files (x86)\Windows Kits\10\include\10.0.18362.0\um\consoleapi.h
C:\Program Files (x86)\Windows Kits\10\include\10.0.18362.0\um\consoleapi2.h
C:\Program Files (x86)\Windows Kits\10\include\10.0.18362.0\um\consoleapi3.h
C:\Program Files (x86)\Windows Kits\10\include\10.0.18362.0\um\winver.h
C:\Program Files (x86)\Windows Kits\10\include\10.0.18362.0\um\verrsrc.h
C:\Program Files (x86)\Windows Kits\10\include\10.0.18362.0\um\winreg.h
C:\Program Files (x86)\Windows Kits\10\include\10.0.18362.0\um\reason.h
C:\Program Files (x86)\Windows Kits\10\include\10.0.18362.0\um\winnetwk.h
C:\Program Files (x86)\Windows Kits\10\include\10.0.18362.0\shared\wnnc.h
C:\Program Files (x86)\Windows Kits\10\include\10.0.18362.0\shared\stralign.h
C:\Program Files (x86)\Windows Kits\10\include\10.0.18362.0\um\imm.h
C:\Program Files (x86)\Windows Kits\10\include\10.0.18362.0\um\ime_cmodes.h
C:\Program Files\Epic Games\UE_4.26\Engine\Source\Runtime\Core\Public\Windows/PostWindowsApi.h
Z:\Projects\Unreal\SwordNGun\SwordNGun\Plugins\UnrealImGui\Source\ThirdParty\ImGuiLibrary\Private\imgui.cpp
Z:\Projects\Unreal\SwordNGun\SwordNGun\Plugins\UnrealImGui\Source\ThirdParty\ImGuiLibrary\Private\imgui_internal.h
C:\Program Files (x86)\Windows Kits\10\include\10.0.18362.0\ucrt\math.h
Z:\Projects\Unreal\SwordNGun\SwordNGun\Plugins\UnrealImGui\Source\ThirdParty\ImGuiLibrary\Private\imstb_textedit.h
C:\Program Files (x86)\Windows Kits\10\include\10.0.18362.0\um\imm.h
Z:\Projects\Unreal\SwordNGun\SwordNGun\Plugins\UnrealImGui\Source\ThirdParty\ImGuiLibrary\Private\imgui_demo.cpp
C:\Program Files (x86)\Windows Kits\10\include\10.0.18362.0\ucrt\math.h
Z:\Projects\Unreal\SwordNGun\SwordNGun\Plugins\UnrealImGui\Source\ThirdParty\ImGuiLibrary\Private\imgui_draw.cpp
Z:\Projects\Unreal\SwordNGun\SwordNGun\Plugins\UnrealImGui\Source\ThirdParty\ImGuiLibrary\Private\imstb_rectpack.h
Z:\Projects\Unreal\SwordNGun\SwordNGun\Plugins\UnrealImGui\Source\ThirdParty\ImGuiLibrary\Private\imstb_truetype.h
C:\Program Files (x86)\Windows Kits\10\include\10.0.18362.0\ucrt\math.h
Z:\Projects\Unreal\SwordNGun\SwordNGun\Plugins\UnrealImGui\Source\ThirdParty\ImGuiLibrary\Private\imgui_widgets.cpp
Z:\Projects\Unreal\SwordNGun\SwordNGun\Plugins\UnrealImGui\Source\ThirdParty\ImGuiLibrary\Private\imstb_textedit.h
C:\Program Files\Epic Games\UE_4.26\Engine\Source\Runtime\Core\Public\Windows/HideWindowsPlatformTypes.h
Z:/Projects/Unreal/SwordNGun/SwordNGun/Plugins/UnrealImGui/Source/ImGui/Private/ImGuiInputHandler.cpp
Z:\Projects\Unreal\SwordNGun\SwordNGun\Plugins\UnrealImGui\Source\ImGui\Public\ImGuiInputHandler.h
Z:\Projects\Unreal\SwordNGun\SwordNGun\Plugins\UnrealImGui\Intermediate\Build\Win64\UE4Editor\Inc\ImGui\ImGuiInputHandler.generated.h
Z:\Projects\Unreal\SwordNGun\SwordNGun\Plugins\UnrealImGui\Source\ImGui\Private\ImGuiModuleDebug.h
Z:\Projects\Unreal\SwordNGun\SwordNGun\Plugins\UnrealImGui\Source\ImGui\Private\ImGuiModuleManager.h
Z:\Projects\Unreal\SwordNGun\SwordNGun\Plugins\UnrealImGui\Source\ImGui\Private\ImGuiModuleCommands.h
Z:\Projects\Unreal\SwordNGun\SwordNGun\Plugins\UnrealImGui\Source\ImGui\Private\Widgets/SImGuiLayout.h
Z:\Projects\Unreal\SwordNGun\SwordNGun\Plugins\UnrealImGui\Source\ImGui\Private\VersionCompatibility.h
C:\Program Files\Epic Games\UE_4.26\Engine\Source\Runtime\Engine\Classes\Engine/Console.h
C:\Program Files\Epic Games\UE_4.26\Engine\Source\Runtime\EngineSettings\Classes\ConsoleSettings.h
C:\Program Files\Epic Games\UE_4.26\Engine\Intermediate\Build\Win64\UE4Editor\Inc\EngineSettings\ConsoleSettings.generated.h
C:\Program Files\Epic Games\UE_4.26\Engine\Intermediate\Build\Win64\UE4Editor\Inc\Engine\Console.generated.h
C:\Program Files\Epic Games\UE_4.26\Engine\Source\Runtime\Engine\Classes\GameFramework/InputSettings.h
C:\Program Files\Epic Games\UE_4.26\Engine\Source\Runtime\Engine\Classes\GameFramework/PlayerInput.h
C:\Program Files\Epic Games\UE_4.26\Engine\Source\Runtime\Engine\Public\GestureRecognizer.h
C:\Program Files\Epic Games\UE_4.26\Engine\Source\Runtime\Engine\Public\KeyState.h
C:\Program Files\Epic Games\UE_4.26\Engine\Intermediate\Build\Win64\UE4Editor\Inc\Engine\PlayerInput.generated.h
C:\Program Files\Epic Games\UE_4.26\Engine\Source\Runtime\Engine\Classes\Components/InputComponent.h
C:\Program Files\Epic Games\UE_4.26\Engine\Intermediate\Build\Win64\UE4Editor\Inc\Engine\InputComponent.generated.h
C:\Program Files\Epic Games\UE_4.26\Engine\Intermediate\Build\Win64\UE4Editor\Inc\Engine\InputSettings.generated.h
C:\Program Files\Epic Games\UE_4.26\Engine\Source\Editor\UnrealEd\Public\Kismet2/DebuggerCommands.h
Z:/Projects/Unreal/SwordNGun/SwordNGun/Plugins/UnrealImGui/Source/ImGui/Private/ImGuiInputHandlerFactory.cpp
Z:\Projects\Unreal\SwordNGun\SwordNGun\Plugins\UnrealImGui\Source\ImGui\Private\ImGuiInputHandlerFactory.h
Z:/Projects/Unreal/SwordNGun/SwordNGun/Plugins/UnrealImGui/Source/ImGui/Private/ImGuiInputState.cpp
C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.28.29910\INCLUDE\algorithm
Z:/Projects/Unreal/SwordNGun/SwordNGun/Plugins/UnrealImGui/Source/ImGui/Private/ImGuiInteroperability.cpp
Z:/Projects/Unreal/SwordNGun/SwordNGun/Plugins/UnrealImGui/Source/ImGui/Private/ImGuiModule.cpp
C:\Program Files\Epic Games\UE_4.26\Engine\Source\Runtime\Projects\Public\Interfaces/IPluginManager.h
C:\Program Files\Epic Games\UE_4.26\Engine\Source\Runtime\Projects\Public\PluginDescriptor.h
C:\Program Files\Epic Games\UE_4.26\Engine\Source\Runtime\Projects\Public\ModuleDescriptor.h
C:\Program Files\Epic Games\UE_4.26\Engine\Source\Runtime\Json\Public\Serialization/JsonWriter.h
C:\Program Files\Epic Games\UE_4.26\Engine\Source\Runtime\Json\Public\Serialization/JsonTypes.h
C:\Program Files\Epic Games\UE_4.26\Engine\Source\Runtime\Projects\Public\CustomBuildSteps.h
C:\Program Files\Epic Games\UE_4.26\Engine\Source\Runtime\Projects\Public\LocalizationDescriptor.h
C:\Program Files\Epic Games\UE_4.26\Engine\Source\Runtime\Projects\Public\PluginReferenceDescriptor.h
Z:/Projects/Unreal/SwordNGun/SwordNGun/Plugins/UnrealImGui/Source/ImGui/Private/ImGuiModuleCommands.cpp
Z:\Projects\Unreal\SwordNGun\SwordNGun\Plugins\UnrealImGui\Source\ImGui\Private\Utilities/DebugExecBindings.h
Z:/Projects/Unreal/SwordNGun/SwordNGun/Plugins/UnrealImGui/Source/ImGui/Private/ImGuiModuleManager.cpp
Z:/Projects/Unreal/SwordNGun/SwordNGun/Plugins/UnrealImGui/Source/ImGui/Private/ImGuiModuleSettings.cpp
C:\Program Files\Epic Games\UE_4.26\Engine\Source\Runtime\Engine\Classes\GameFramework/GameUserSettings.h
C:\Program Files\Epic Games\UE_4.26\Engine\Source\Runtime\Engine\Public\Scalability.h
C:\Program Files\Epic Games\UE_4.26\Engine\Intermediate\Build\Win64\UE4Editor\Inc\Engine\GameUserSettings.generated.h
Z:/Projects/Unreal/SwordNGun/SwordNGun/Plugins/UnrealImGui/Source/ImGui/Private/ImGuiTextureHandle.cpp
Z:/Projects/Unreal/SwordNGun/SwordNGun/Plugins/UnrealImGui/Source/ImGui/Private/TextureManager.cpp
Z:/Projects/Unreal/SwordNGun/SwordNGun/Plugins/UnrealImGui/Source/ImGui/Private/Utilities/DebugExecBindings.cpp
Z:/Projects/Unreal/SwordNGun/SwordNGun/Plugins/UnrealImGui/Source/ImGui/Private/Utilities/WorldContext.cpp
Z:/Projects/Unreal/SwordNGun/SwordNGun/Plugins/UnrealImGui/Source/ImGui/Private/Widgets/SImGuiCanvasControl.cpp
Z:\Projects\Unreal\SwordNGun\SwordNGun\Plugins\UnrealImGui\Source\ImGui\Private\Widgets\SImGuiCanvasControl.h
C:\Program Files\Epic Games\UE_4.26\Engine\Source\Runtime\SlateCore\Public\Brushes/SlateBorderBrush.h
Z:\Projects\Unreal\SwordNGun\SwordNGun\Plugins\UnrealImGui\Source\ImGui\Private\VersionCompatibility.h
C:\Program Files\Epic Games\UE_4.26\Engine\Source\Runtime\Slate\Public\SlateOptMacros.h
Z:/Projects/Unreal/SwordNGun/SwordNGun/Plugins/UnrealImGui/Source/ImGui/Private/Widgets/SImGuiLayout.cpp
Z:\Projects\Unreal\SwordNGun\SwordNGun\Plugins\UnrealImGui\Source\ImGui\Private\Widgets\SImGuiWidget.h
C:\Program Files\Epic Games\UE_4.26\Engine\Source\Runtime\Slate\Public\Widgets/Layout/SConstraintCanvas.h
C:\Program Files\Epic Games\UE_4.26\Engine\Source\Runtime\Slate\Public\Widgets/Layout/Anchors.h
C:\Program Files\Epic Games\UE_4.26\Engine\Intermediate\Build\Win64\UE4Editor\Inc\Slate\Anchors.generated.h
C:\Program Files\Epic Games\UE_4.26\Engine\Source\Runtime\Slate\Public\Widgets/Layout/SDPIScaler.h
C:\Program Files\Epic Games\UE_4.26\Engine\Source\Runtime\Slate\Public\Widgets/Layout/SScaleBox.h
C:\Program Files\Epic Games\UE_4.26\Engine\Intermediate\Build\Win64\UE4Editor\Inc\Slate\SScaleBox.generated.h
Z:/Projects/Unreal/SwordNGun/SwordNGun/Plugins/UnrealImGui/Source/ImGui/Private/Widgets/SImGuiWidget.cpp
Z:\Projects\Unreal\SwordNGun\SwordNGun\Plugins\UnrealImGui\Source\ImGui\Private\VersionCompatibility.h
C:\Program Files\Epic Games\UE_4.26\Engine\Source\Runtime\Engine\Classes\Engine/LocalPlayer.h
C:\Program Files\Epic Games\UE_4.26\Engine\Source\Runtime\CoreUObject\Public\UObject/CoreOnline.h
C:\Program Files\Epic Games\UE_4.26\Engine\Source\Runtime\Engine\Classes\Engine/Player.h
C:\Program Files\Epic Games\UE_4.26\Engine\Intermediate\Build\Win64\UE4Editor\Inc\Engine\Player.generated.h
C:\Program Files\Epic Games\UE_4.26\Engine\Source\Runtime\Engine\Classes\GameFramework/OnlineReplStructs.h
C:\Program Files\Epic Games\UE_4.26\Engine\Intermediate\Build\Win64\UE4Editor\Inc\Engine\OnlineReplStructs.generated.h
C:\Program Files\Epic Games\UE_4.26\Engine\Source\Runtime\Engine\Public\Subsystems/LocalPlayerSubsystem.h
C:\Program Files\Epic Games\UE_4.26\Engine\Intermediate\Build\Win64\UE4Editor\Inc\Engine\LocalPlayerSubsystem.generated.h
C:\Program Files\Epic Games\UE_4.26\Engine\Intermediate\Build\Win64\UE4Editor\Inc\Engine\LocalPlayer.generated.h
C:\Program Files\Epic Games\UE_4.26\Engine\Source\Runtime\Slate\Public\Widgets/SViewport.h

View File

@ -0,0 +1,4 @@
// This file is automatically generated at compile-time to include some subset of the user-created cpp files.
#include "Z:/Projects/Unreal/SwordNGun/SwordNGun/Plugins/UnrealImGui/Intermediate/Build/Win64/UE4Editor/Inc/ImGui/ImGui.init.gen.cpp"
#include "Z:/Projects/Unreal/SwordNGun/SwordNGun/Plugins/UnrealImGui/Intermediate/Build/Win64/UE4Editor/Inc/ImGui/ImGuiInputHandler.gen.cpp"
#include "Z:/Projects/Unreal/SwordNGun/SwordNGun/Plugins/UnrealImGui/Intermediate/Build/Win64/UE4Editor/Inc/ImGui/ImGuiModuleSettings.gen.cpp"

View File

@ -0,0 +1,276 @@
/Zc:inline
/nologo
/Oi
/c
/Gw
/Gy
/Zm1000
/wd4819
/D_CRT_STDIO_LEGACY_WIDE_SPECIFIERS=1
/D_SILENCE_STDEXT_HASH_DEPRECATION_WARNINGS=1
/D_WINDLL
/D_DISABLE_EXTENDED_ALIGNED_STORAGE
/source-charset:utf-8
/execution-charset:utf-8
/Ob2
/Ox
/Ot
/GF
/errorReport:prompt
/EHsc
/Z7
/MD
/bigobj
/fp:fast
/Zo
/Zp8
/we4456
/we4458
/we4459
/wd4463
/wd4244
/wd4838
/I .
/I Z:\Projects\Unreal\SwordNGun\SwordNGun\Plugins\UnrealImGui\Source\ImGui\Private
/I Z:\Projects\Unreal\SwordNGun\SwordNGun\Plugins\UnrealImGui\Source\ThirdParty\ImGuiLibrary\Private
/I ..\Intermediate\Build\Win64\UE4Editor\Inc\CoreUObject
/I Runtime
/I Runtime\CoreUObject\Public
/I Runtime\TraceLog\Public
/I Runtime\Core\Public
/I ..\Intermediate\Build\Win64\UE4Editor\Inc\Engine
/I Runtime\Engine\Classes
/I Runtime\Engine\Public
/I ..\Intermediate\Build\Win64\UE4Editor\Inc\NetCore
/I Runtime\Net
/I Runtime\Net\Core\Classes
/I Runtime\Net\Core\Public
/I Runtime\ApplicationCore\Public
/I Runtime\RHI\Public
/I Runtime\Json\Public
/I ..\Intermediate\Build\Win64\UE4Editor\Inc\SlateCore
/I Runtime\SlateCore\Public
/I ..\Intermediate\Build\Win64\UE4Editor\Inc\InputCore
/I Runtime\InputCore\Classes
/I Runtime\InputCore\Public
/I ..\Intermediate\Build\Win64\UE4Editor\Inc\Slate
/I Runtime\Slate\Public
/I ..\Intermediate\Build\Win64\UE4Editor\Inc\ImageWrapper
/I Runtime\ImageWrapper\Public
/I Runtime\Messaging\Public
/I Runtime\MessagingCommon\Public
/I Runtime\RenderCore\Public
/I Runtime\Analytics
/I Runtime\Analytics\AnalyticsET\Public
/I Runtime\Analytics\Analytics\Public
/I Runtime\Sockets\Public
/I Runtime\Net\Common\Public
/I ..\Intermediate\Build\Win64\UE4Editor\Inc\AssetRegistry
/I Runtime\AssetRegistry\Public
/I ..\Intermediate\Build\Win64\UE4Editor\Inc\EngineMessages
/I Runtime\EngineMessages\Public
/I ..\Intermediate\Build\Win64\UE4Editor\Inc\EngineSettings
/I Runtime\EngineSettings\Classes
/I Runtime\EngineSettings\Public
/I Runtime\SynthBenchmark\Public
/I ..\Intermediate\Build\Win64\UE4Editor\Inc\Renderer
/I Runtime\Renderer\Public
/I ..\Intermediate\Build\Win64\UE4Editor\Inc\GameplayTags
/I Runtime\GameplayTags\Classes
/I Runtime\GameplayTags\Public
/I ..\Intermediate\Build\Win64\UE4Editor\Inc\PacketHandler
/I Runtime\PacketHandlers
/I Runtime\PacketHandlers\PacketHandler\Classes
/I Runtime\PacketHandlers\PacketHandler\Public
/I Runtime\PacketHandlers\ReliabilityHandlerComponent\Public
/I ..\Intermediate\Build\Win64\UE4Editor\Inc\AudioPlatformConfiguration
/I Runtime\AudioPlatformConfiguration\Public
/I ..\Intermediate\Build\Win64\UE4Editor\Inc\MeshDescription
/I Runtime\MeshDescription\Public
/I ..\Intermediate\Build\Win64\UE4Editor\Inc\StaticMeshDescription
/I Runtime\StaticMeshDescription\Public
/I Runtime\PakFile\Public
/I Runtime\RSA\Public
/I Runtime\NetworkReplayStreaming
/I Runtime\NetworkReplayStreaming\NetworkReplayStreaming\Public
/I ..\Intermediate\Build\Win64\UE4Editor\Inc\PhysicsCore
/I Runtime\PhysicsCore\Public
/I ..\Intermediate\Build\Win64\UE4Editor\Inc\DeveloperSettings
/I Runtime\DeveloperSettings\Public
/I ..\Intermediate\Build\Win64\UE4Editor\Inc\Chaos
/I Runtime\Experimental
/I Runtime\Experimental\Chaos\Public
/I Runtime\Experimental\ChaosCore\Public
/I ThirdParty\Intel
/I Runtime\Experimental\Voronoi\Public
/I ThirdParty
/I Runtime\SignalProcessing\Public
/I ..\Intermediate\Build\Win64\UE4Editor\Inc\AudioExtensions
/I Runtime\AudioExtensions\Public
/I Runtime\AudioMixerCore\Public
/I ..\Intermediate\Build\Win64\UE4Editor\Inc\PropertyAccess
/I Runtime\PropertyAccess\Public
/I ..\Intermediate\Build\Win64\UE4Editor\Inc\UnrealEd
/I Editor
/I Programs\UnrealLightmass\Public
/I Developer\Android\AndroidDeviceDetection\Public\Interfaces
/I Editor\UnrealEd\Classes
/I Editor\UnrealEd\Public
/I Developer
/I Developer\DirectoryWatcher\Public
/I Editor\Documentation\Public
/I Runtime\Projects\Public
/I Runtime\SandboxFile\Public
/I ..\Intermediate\Build\Win64\UE4Editor\Inc\EditorStyle
/I Editor\EditorStyle\Public
/I ..\Intermediate\Build\Win64\UE4Editor\Inc\SourceControl
/I Developer\SourceControl\Public
/I ..\Intermediate\Build\Win64\UE4Editor\Inc\UnrealEdMessages
/I Editor\UnrealEdMessages\Classes
/I Editor\UnrealEdMessages\Public
/I ..\Intermediate\Build\Win64\UE4Editor\Inc\GameplayDebugger
/I Developer\GameplayDebugger\Public
/I ..\Intermediate\Build\Win64\UE4Editor\Inc\BlueprintGraph
/I Editor\BlueprintGraph\Classes
/I Editor\BlueprintGraph\Public
/I ..\Intermediate\Build\Win64\UE4Editor\Inc\EditorSubsystem
/I Editor\EditorSubsystem\Public
/I Runtime\Online
/I Runtime\Online\HTTP\Public
/I Runtime\UnrealAudio\Public
/I ..\Intermediate\Build\Win64\UE4Editor\Inc\FunctionalTesting
/I Developer\FunctionalTesting\Classes
/I Developer\FunctionalTesting\Public
/I ..\Intermediate\Build\Win64\UE4Editor\Inc\AutomationController
/I Developer\AutomationController\Public
/I ..\Intermediate\Build\Win64\UE4Editor\Inc\Localization
/I Developer\Localization\Public
/I ..\Intermediate\Build\Win64\UE4Editor\Inc\AudioEditor
/I Editor\AudioEditor\Classes
/I Editor\AudioEditor\Public
/I ..\Intermediate\Build\Win64\UE4Editor\Inc\AudioMixer
/I Runtime\AudioMixer\Classes
/I Runtime\AudioMixer\Public
/I Developer\TargetPlatform\Public
/I ..\Intermediate\Build\Win64\UE4Editor\Inc\LevelEditor
/I Editor\LevelEditor\Public
/I Developer\Settings\Public
/I ..\Intermediate\Build\Win64\UE4Editor\Inc\IntroTutorials
/I Editor\IntroTutorials\Public
/I ..\Intermediate\Build\Win64\UE4Editor\Inc\HeadMountedDisplay
/I Runtime\HeadMountedDisplay\Public
/I ..\Intermediate\Build\Win64\UE4Editor\Inc\VREditor
/I Editor\VREditor
/I Editor\VREditor\Public
/I Editor\CommonMenuExtensions\Public
/I ..\Intermediate\Build\Win64\UE4Editor\Inc\Landscape
/I Runtime\Landscape\Classes
/I Runtime\Landscape\Public
/I ..\Intermediate\Build\Win64\UE4Editor\Inc\PropertyEditor
/I Editor\PropertyEditor\Public
/I Editor\ActorPickerMode\Public
/I Editor\SceneDepthPickerMode\Public
/I ..\Intermediate\Build\Win64\UE4Editor\Inc\DetailCustomizations
/I Editor\DetailCustomizations\Public
/I ..\Intermediate\Build\Win64\UE4Editor\Inc\ClassViewer
/I Editor\ClassViewer\Public
/I ..\Intermediate\Build\Win64\UE4Editor\Inc\GraphEditor
/I Editor\GraphEditor\Public
/I ..\Intermediate\Build\Win64\UE4Editor\Inc\StructViewer
/I Editor\StructViewer\Public
/I ..\Intermediate\Build\Win64\UE4Editor\Inc\ContentBrowser
/I Editor\ContentBrowser\Public
/I ..\Intermediate\Build\Win64\UE4Editor\Inc\ContentBrowserData
/I Editor\ContentBrowserData\Public
/I Developer\CollectionManager\Public
/I ThirdParty\libSampleRate\Public
/I Runtime\NetworkFileSystem\Public
/I ..\Intermediate\Build\Win64\UE4Editor\Inc\UMG
/I Runtime\UMG\Public
/I ..\Intermediate\Build\Win64\UE4Editor\Inc\MovieScene
/I Runtime\MovieScene\Public
/I ..\Intermediate\Build\Win64\UE4Editor\Inc\TimeManagement
/I Runtime\TimeManagement\Public
/I ..\Intermediate\Build\Win64\UE4Editor\Inc\MovieSceneTracks
/I Runtime\MovieSceneTracks\Public
/I ..\Intermediate\Build\Win64\UE4Editor\Inc\AnimationCore
/I Runtime\AnimationCore\Public
/I ..\Intermediate\Build\Win64\UE4Editor\Inc\PropertyPath
/I Runtime\PropertyPath\Public
/I ..\Intermediate\Build\Win64\UE4Editor\Inc\NavigationSystem
/I Runtime\NavigationSystem\Public
/I Developer\MeshBuilder\Public
/I ..\Intermediate\Build\Win64\UE4Editor\Inc\MaterialShaderQualitySettings
/I Runtime\MaterialShaderQualitySettings\Classes
/I ..\Intermediate\Build\Win64\UE4Editor\Inc\InteractiveToolsFramework
/I Runtime\Experimental\InteractiveToolsFramework\Public
/I ..\Intermediate\Build\Win64\UE4Editor\Inc\ToolMenusEditor
/I Editor\ToolMenusEditor\Public
/I ..\Intermediate\Build\Win64\UE4Editor\Inc\ToolMenus
/I Developer\ToolMenus\Public
/I Runtime\Windows
/I Runtime\Windows\XAudio2\Public
/I Editor\AssetTagsEditor\Public
/I ..\Intermediate\Build\Win64\UE4Editor\Inc\AddContentDialog
/I Editor\AddContentDialog\Public
/I ThirdParty\Intel\Embree\Embree2140\Win64\include
/I Developer\MeshUtilities\Public
/I Developer\MeshMergeUtilities\Public
/I Developer\HierarchicalLODUtilities\Public
/I Developer\MeshReductionInterface\Public
/I ..\Intermediate\Build\Win64\UE4Editor\Inc\AssetTools
/I Developer\AssetTools\Public
/I Editor\KismetCompiler\Public
/I ..\Intermediate\Build\Win64\UE4Editor\Inc\GameplayTasks
/I Runtime\GameplayTasks\Classes
/I Runtime\GameplayTasks\Public
/I ..\Intermediate\Build\Win64\UE4Editor\Inc\AIModule
/I Runtime\AIModule\Public
/I Runtime\AIModule\Classes
/I ..\Intermediate\Build\Win64\UE4Editor\Inc\Kismet
/I Editor\Kismet\Classes
/I Editor\Kismet\Public
/I ..\Intermediate\Build\Win64\UE4Editor\Inc\ClothingSystemRuntimeInterface
/I Runtime\ClothingSystemRuntimeInterface\Public
/I Z:\Projects\Unreal\SwordNGun\SwordNGun\Plugins\UnrealImGui\Intermediate\Build\Win64\UE4Editor\Inc\ImGui
/I Z:\Projects\Unreal\SwordNGun\SwordNGun\Plugins\UnrealImGui\Source
/I Z:\Projects\Unreal\SwordNGun\SwordNGun\Plugins\UnrealImGui\Source\ThirdParty\ImGuiLibrary\Include
/I Z:\Projects\Unreal\SwordNGun\SwordNGun\Plugins\UnrealImGui\Source\ImGui\Public
/I ThirdParty\PhysX3\PxShared\include
/I ThirdParty\PhysX3\PxShared\include\cudamanager
/I ThirdParty\PhysX3\PxShared\include\filebuf
/I ThirdParty\PhysX3\PxShared\include\foundation
/I ThirdParty\PhysX3\PxShared\include\pvd
/I ThirdParty\PhysX3\PxShared\include\task
/I ThirdParty\PhysX3\PhysX_3.4\Include
/I ThirdParty\PhysX3\PhysX_3.4\Include\cooking
/I ThirdParty\PhysX3\PhysX_3.4\Include\common
/I ThirdParty\PhysX3\PhysX_3.4\Include\extensions
/I ThirdParty\PhysX3\PhysX_3.4\Include\geometry
/I ThirdParty\PhysX3\APEX_1.4\include
/I ThirdParty\PhysX3\APEX_1.4\include\clothing
/I ThirdParty\PhysX3\APEX_1.4\include\nvparameterized
/I ThirdParty\PhysX3\APEX_1.4\include\legacy
/I ThirdParty\PhysX3\APEX_1.4\include\PhysX3
/I ThirdParty\PhysX3\APEX_1.4\common\include
/I ThirdParty\PhysX3\APEX_1.4\common\include\autogen
/I ThirdParty\PhysX3\APEX_1.4\framework\include
/I ThirdParty\PhysX3\APEX_1.4\framework\include\autogen
/I ThirdParty\PhysX3\APEX_1.4\shared\general\RenderDebug\public
/I ThirdParty\PhysX3\APEX_1.4\shared\general\PairFilter\include
/I ThirdParty\PhysX3\APEX_1.4\shared\internal\include
/I "C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.28.29910\INCLUDE"
/I "C:\Program Files (x86)\Windows Kits\NETFXSDK\4.8\include\um"
/I "C:\Program Files (x86)\Windows Kits\10\include\10.0.18362.0\ucrt"
/I "C:\Program Files (x86)\Windows Kits\10\include\10.0.18362.0\shared"
/I "C:\Program Files (x86)\Windows Kits\10\include\10.0.18362.0\um"
/I "C:\Program Files (x86)\Windows Kits\10\include\10.0.18362.0\winrt"
/FI"Z:\Projects\Unreal\SwordNGun\SwordNGun\Intermediate\Build\Win64\SwordNGunEditor\Development\UnrealEd\SharedPCH.UnrealEd.ShadowErrors.h"
/Yu"Z:\Projects\Unreal\SwordNGun\SwordNGun\Intermediate\Build\Win64\SwordNGunEditor\Development\UnrealEd\SharedPCH.UnrealEd.ShadowErrors.h"
/Fp"Z:\Projects\Unreal\SwordNGun\SwordNGun\Intermediate\Build\Win64\SwordNGunEditor\Development\UnrealEd\SharedPCH.UnrealEd.ShadowErrors.h.pch"
"Z:\Projects\Unreal\SwordNGun\SwordNGun\Plugins\UnrealImGui\Intermediate\Build\Win64\UE4Editor\Development\ImGui\Module.ImGui.gen.cpp"
/FI"Z:\Projects\Unreal\SwordNGun\SwordNGun\Plugins\UnrealImGui\Intermediate\Build\Win64\UE4Editor\Development\ImGui\Definitions.ImGui.h"
/Fo"Z:\Projects\Unreal\SwordNGun\SwordNGun\Plugins\UnrealImGui\Intermediate\Build\Win64\UE4Editor\Development\ImGui\Module.ImGui.gen.cpp.obj"
/TP
/GR-
/W4

View File

@ -0,0 +1,11 @@
Z:\Projects\Unreal\SwordNGun\SwordNGun\Plugins\UnrealImGui\Intermediate\Build\Win64\UE4Editor\Development\ImGui\Definitions.ImGui.h
Z:/Projects/Unreal/SwordNGun/SwordNGun/Plugins/UnrealImGui/Intermediate/Build/Win64/UE4Editor/Inc/ImGui/ImGui.init.gen.cpp
C:\Program Files\Epic Games\UE_4.26\Engine\Source\Runtime\CoreUObject\Public\UObject/GeneratedCppIncludes.h
C:\Program Files\Epic Games\UE_4.26\Engine\Source\Runtime\CoreUObject\Public\UObject/MetaData.h
Z:/Projects/Unreal/SwordNGun/SwordNGun/Plugins/UnrealImGui/Intermediate/Build/Win64/UE4Editor/Inc/ImGui/ImGuiInputHandler.gen.cpp
Z:\Projects\Unreal\SwordNGun\SwordNGun\Plugins\UnrealImGui\Source\ImGui/Public/ImGuiInputHandler.h
Z:\Projects\Unreal\SwordNGun\SwordNGun\Plugins\UnrealImGui\Intermediate\Build\Win64\UE4Editor\Inc\ImGui\ImGuiInputHandler.generated.h
Z:/Projects/Unreal/SwordNGun/SwordNGun/Plugins/UnrealImGui/Intermediate/Build/Win64/UE4Editor/Inc/ImGui/ImGuiModuleSettings.gen.cpp
Z:\Projects\Unreal\SwordNGun\SwordNGun\Plugins\UnrealImGui\Source\ImGui/Private/ImGuiModuleSettings.h
Z:\Projects\Unreal\SwordNGun\SwordNGun\Plugins\UnrealImGui\Source\ImGui\Private\VersionCompatibility.h
Z:\Projects\Unreal\SwordNGun\SwordNGun\Plugins\UnrealImGui\Intermediate\Build\Win64\UE4Editor\Inc\ImGui\ImGuiModuleSettings.generated.h

View File

@ -0,0 +1,78 @@
/MANIFEST:EMBED
/MANIFESTINPUT:"C:\Program Files\Epic Games\UE_4.26\Engine\Build\Windows\Resources\Default-Win64.manifest"
/NOLOGO
/DEBUG
/errorReport:prompt
/MACHINE:x64
/SUBSYSTEM:WINDOWS
/FIXED:No
/NXCOMPAT
/STACK:12000000
/DELAY:UNLOAD
/DLL
/PDBALTPATH:%_PDB%
/OPT:NOREF
/OPT:NOICF
/INCREMENTAL:NO
/ignore:4199
/ignore:4099
/DELAYLOAD:"d3d12.dll"
/DELAYLOAD:"DBGHELP.DLL"
/LIBPATH:"C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.28.29910\lib\x64"
/LIBPATH:"C:\Program Files (x86)\Windows Kits\NETFXSDK\4.8\lib\um\x64"
/LIBPATH:"C:\Program Files (x86)\Windows Kits\10\lib\10.0.18362.0\ucrt\x64"
/LIBPATH:"C:\Program Files (x86)\Windows Kits\10\lib\10.0.18362.0\um\x64"
/NODEFAULTLIB:"LIBCMT"
/NODEFAULTLIB:"LIBCPMT"
/NODEFAULTLIB:"LIBCMTD"
/NODEFAULTLIB:"LIBCPMTD"
/NODEFAULTLIB:"MSVCRTD"
/NODEFAULTLIB:"MSVCPRTD"
/NODEFAULTLIB:"LIBC"
/NODEFAULTLIB:"LIBCP"
/NODEFAULTLIB:"LIBCD"
/NODEFAULTLIB:"LIBCPD"
/FUNCTIONPADMIN
"Z:\Projects\Unreal\SwordNGun\SwordNGun\Intermediate\Build\Win64\SwordNGunEditor\Development\UnrealEd\SharedPCH.UnrealEd.ShadowErrors.h.obj"
"Z:\Projects\Unreal\SwordNGun\SwordNGun\Plugins\UnrealImGui\Intermediate\Build\Win64\UE4Editor\Development\ImGui\Module.ImGui.cpp.obj"
"Z:\Projects\Unreal\SwordNGun\SwordNGun\Plugins\UnrealImGui\Intermediate\Build\Win64\UE4Editor\Development\ImGui\Module.ImGui.gen.cpp.obj"
"Z:\Projects\Unreal\SwordNGun\SwordNGun\Plugins\UnrealImGui\Intermediate\Build\Win64\UE4Editor\Development\ImGui\Default.rc2.res"
"C:\Program Files\Epic Games\UE_4.26\Engine\Intermediate\Build\Win64\UE4Editor\Development\CoreUObject\UE4Editor-CoreUObject.lib"
"C:\Program Files\Epic Games\UE_4.26\Engine\Intermediate\Build\Win64\UE4Editor\Development\Engine\UE4Editor-Engine.lib"
"C:\Program Files\Epic Games\UE_4.26\Engine\Intermediate\Build\Win64\UE4Editor\Development\InputCore\UE4Editor-InputCore.lib"
"C:\Program Files\Epic Games\UE_4.26\Engine\Intermediate\Build\Win64\UE4Editor\Development\Slate\UE4Editor-Slate.lib"
"C:\Program Files\Epic Games\UE_4.26\Engine\Intermediate\Build\Win64\UE4Editor\Development\SlateCore\UE4Editor-SlateCore.lib"
"C:\Program Files\Epic Games\UE_4.26\Engine\Intermediate\Build\Win64\UE4Editor\Development\EditorStyle\UE4Editor-EditorStyle.lib"
"C:\Program Files\Epic Games\UE_4.26\Engine\Intermediate\Build\Win64\UE4Editor\Development\Settings\UE4Editor-Settings.lib"
"C:\Program Files\Epic Games\UE_4.26\Engine\Intermediate\Build\Win64\UE4Editor\Development\UnrealEd\UE4Editor-UnrealEd.lib"
"C:\Program Files\Epic Games\UE_4.26\Engine\Intermediate\Build\Win64\UE4Editor\Development\Core\UE4Editor-Core.lib"
"C:\Program Files\Epic Games\UE_4.26\Engine\Intermediate\Build\Win64\UE4Editor\Development\Projects\UE4Editor-Projects.lib"
"delayimp.lib"
"wininet.lib"
"rpcrt4.lib"
"ws2_32.lib"
"dbghelp.lib"
"comctl32.lib"
"Winmm.lib"
"kernel32.lib"
"user32.lib"
"gdi32.lib"
"winspool.lib"
"comdlg32.lib"
"advapi32.lib"
"shell32.lib"
"ole32.lib"
"oleaut32.lib"
"uuid.lib"
"odbc32.lib"
"odbccp32.lib"
"netapi32.lib"
"iphlpapi.lib"
"setupapi.lib"
"dwmapi.lib"
"imm32.lib"
/OUT:"Z:\Projects\Unreal\SwordNGun\SwordNGun\Plugins\UnrealImGui\Binaries\Win64\UE4Editor-ImGui.dll"
/IMPLIB:"Z:\Projects\Unreal\SwordNGun\SwordNGun\Plugins\UnrealImGui\Intermediate\Build\Win64\UE4Editor\Development\ImGui\UE4Editor-ImGui.suppressed.lib"
/PDB:"Z:\Projects\Unreal\SwordNGun\SwordNGun\Plugins\UnrealImGui\Binaries\Win64\UE4Editor-ImGui.pdb"
/ignore:4078
/INCLUDE:IMPLEMENT_MODULE_ImGui

View File

@ -0,0 +1,14 @@
/NOLOGO
/errorReport:prompt
/MACHINE:x64
/SUBSYSTEM:WINDOWS
/DEF
/NAME:"UE4Editor-ImGui.dll"
/IGNORE:4221
/NODEFAULTLIB
"Z:\Projects\Unreal\SwordNGun\SwordNGun\Intermediate\Build\Win64\SwordNGunEditor\Development\UnrealEd\SharedPCH.UnrealEd.ShadowErrors.h.obj"
"Z:\Projects\Unreal\SwordNGun\SwordNGun\Plugins\UnrealImGui\Intermediate\Build\Win64\UE4Editor\Development\ImGui\Module.ImGui.cpp.obj"
"Z:\Projects\Unreal\SwordNGun\SwordNGun\Plugins\UnrealImGui\Intermediate\Build\Win64\UE4Editor\Development\ImGui\Module.ImGui.gen.cpp.obj"
"Z:\Projects\Unreal\SwordNGun\SwordNGun\Plugins\UnrealImGui\Intermediate\Build\Win64\UE4Editor\Development\ImGui\Default.rc2.res"
/OUT:"Z:\Projects\Unreal\SwordNGun\SwordNGun\Plugins\UnrealImGui\Intermediate\Build\Win64\UE4Editor\Development\ImGui\UE4Editor-ImGui.lib"
/INCLUDE:IMPLEMENT_MODULE_ImGui

View File

@ -0,0 +1,35 @@
// Copyright Epic Games, Inc. All Rights Reserved.
/*===========================================================================
Generated code exported from UnrealHeaderTool.
DO NOT modify this manually! Edit the corresponding .h files instead!
===========================================================================*/
#include "UObject/GeneratedCppIncludes.h"
#ifdef _MSC_VER
#pragma warning (push)
#pragma warning (disable : 4883)
#endif
PRAGMA_DISABLE_DEPRECATION_WARNINGS
void EmptyLinkFunctionForGeneratedCodeImGui_init() {}
UPackage* Z_Construct_UPackage__Script_ImGui()
{
static UPackage* ReturnPackage = nullptr;
if (!ReturnPackage)
{
static const UE4CodeGen_Private::FPackageParams PackageParams = {
"/Script/ImGui",
nullptr,
0,
PKG_CompiledIn | 0x00000080,
0xC2DD766E,
0x2835A5A1,
METADATA_PARAMS(nullptr, 0)
};
UE4CodeGen_Private::ConstructUPackage(ReturnPackage, PackageParams);
}
return ReturnPackage;
}
PRAGMA_ENABLE_DEPRECATION_WARNINGS
#ifdef _MSC_VER
#pragma warning (pop)
#endif

View File

@ -0,0 +1,10 @@
// Copyright Epic Games, Inc. All Rights Reserved.
/*===========================================================================
Generated code exported from UnrealHeaderTool.
DO NOT modify this manually! Edit the corresponding .h files instead!
===========================================================================*/
#pragma once

View File

@ -0,0 +1,86 @@
// Copyright Epic Games, Inc. All Rights Reserved.
/*===========================================================================
Generated code exported from UnrealHeaderTool.
DO NOT modify this manually! Edit the corresponding .h files instead!
===========================================================================*/
#include "UObject/GeneratedCppIncludes.h"
#include "ImGui/Public/ImGuiInputHandler.h"
#ifdef _MSC_VER
#pragma warning (push)
#pragma warning (disable : 4883)
#endif
PRAGMA_DISABLE_DEPRECATION_WARNINGS
void EmptyLinkFunctionForGeneratedCodeImGuiInputHandler() {}
// Cross Module References
IMGUI_API UClass* Z_Construct_UClass_UImGuiInputHandler_NoRegister();
IMGUI_API UClass* Z_Construct_UClass_UImGuiInputHandler();
COREUOBJECT_API UClass* Z_Construct_UClass_UObject();
UPackage* Z_Construct_UPackage__Script_ImGui();
// End Cross Module References
void UImGuiInputHandler::StaticRegisterNativesUImGuiInputHandler()
{
}
UClass* Z_Construct_UClass_UImGuiInputHandler_NoRegister()
{
return UImGuiInputHandler::StaticClass();
}
struct Z_Construct_UClass_UImGuiInputHandler_Statics
{
static UObject* (*const DependentSingletons[])();
#if WITH_METADATA
static const UE4CodeGen_Private::FMetaDataPairParam Class_MetaDataParams[];
#endif
static const FCppClassTypeInfoStatic StaticCppClassTypeInfo;
static const UE4CodeGen_Private::FClassParams ClassParams;
};
UObject* (*const Z_Construct_UClass_UImGuiInputHandler_Statics::DependentSingletons[])() = {
(UObject* (*)())Z_Construct_UClass_UObject,
(UObject* (*)())Z_Construct_UPackage__Script_ImGui,
};
#if WITH_METADATA
const UE4CodeGen_Private::FMetaDataPairParam Z_Construct_UClass_UImGuiInputHandler_Statics::Class_MetaDataParams[] = {
{ "Comment", "/**\n * Handles input and sends it to the input state, which is copied to the ImGui IO at the beginning of the frame.\n * Implementation of the input handler can be changed in the ImGui project settings by changing ImGuiInputHandlerClass.\n */" },
{ "IncludePath", "ImGuiInputHandler.h" },
{ "ModuleRelativePath", "Public/ImGuiInputHandler.h" },
{ "ToolTip", "Handles input and sends it to the input state, which is copied to the ImGui IO at the beginning of the frame.\nImplementation of the input handler can be changed in the ImGui project settings by changing ImGuiInputHandlerClass." },
};
#endif
const FCppClassTypeInfoStatic Z_Construct_UClass_UImGuiInputHandler_Statics::StaticCppClassTypeInfo = {
TCppClassTypeTraits<UImGuiInputHandler>::IsAbstract,
};
const UE4CodeGen_Private::FClassParams Z_Construct_UClass_UImGuiInputHandler_Statics::ClassParams = {
&UImGuiInputHandler::StaticClass,
nullptr,
&StaticCppClassTypeInfo,
DependentSingletons,
nullptr,
nullptr,
nullptr,
UE_ARRAY_COUNT(DependentSingletons),
0,
0,
0,
0x001000A0u,
METADATA_PARAMS(Z_Construct_UClass_UImGuiInputHandler_Statics::Class_MetaDataParams, UE_ARRAY_COUNT(Z_Construct_UClass_UImGuiInputHandler_Statics::Class_MetaDataParams))
};
UClass* Z_Construct_UClass_UImGuiInputHandler()
{
static UClass* OuterClass = nullptr;
if (!OuterClass)
{
UE4CodeGen_Private::ConstructUClass(OuterClass, Z_Construct_UClass_UImGuiInputHandler_Statics::ClassParams);
}
return OuterClass;
}
IMPLEMENT_CLASS(UImGuiInputHandler, 3941432126);
template<> IMGUI_API UClass* StaticClass<UImGuiInputHandler>()
{
return UImGuiInputHandler::StaticClass();
}
static FCompiledInDefer Z_CompiledInDefer_UClass_UImGuiInputHandler(Z_Construct_UClass_UImGuiInputHandler, &UImGuiInputHandler::StaticClass, TEXT("/Script/ImGui"), TEXT("UImGuiInputHandler"), false, nullptr, nullptr, nullptr);
DEFINE_VTABLE_PTR_HELPER_CTOR(UImGuiInputHandler);
PRAGMA_ENABLE_DEPRECATION_WARNINGS
#ifdef _MSC_VER
#pragma warning (pop)
#endif

View File

@ -0,0 +1,95 @@
// Copyright Epic Games, Inc. All Rights Reserved.
/*===========================================================================
Generated code exported from UnrealHeaderTool.
DO NOT modify this manually! Edit the corresponding .h files instead!
===========================================================================*/
#include "UObject/ObjectMacros.h"
#include "UObject/ScriptMacros.h"
PRAGMA_DISABLE_DEPRECATION_WARNINGS
#ifdef IMGUI_ImGuiInputHandler_generated_h
#error "ImGuiInputHandler.generated.h already included, missing '#pragma once' in ImGuiInputHandler.h"
#endif
#define IMGUI_ImGuiInputHandler_generated_h
#define SwordNGun_Plugins_UnrealImGui_Source_ImGui_Public_ImGuiInputHandler_h_32_SPARSE_DATA
#define SwordNGun_Plugins_UnrealImGui_Source_ImGui_Public_ImGuiInputHandler_h_32_RPC_WRAPPERS
#define SwordNGun_Plugins_UnrealImGui_Source_ImGui_Public_ImGuiInputHandler_h_32_RPC_WRAPPERS_NO_PURE_DECLS
#define SwordNGun_Plugins_UnrealImGui_Source_ImGui_Public_ImGuiInputHandler_h_32_INCLASS_NO_PURE_DECLS \
private: \
static void StaticRegisterNativesUImGuiInputHandler(); \
friend struct Z_Construct_UClass_UImGuiInputHandler_Statics; \
public: \
DECLARE_CLASS(UImGuiInputHandler, UObject, COMPILED_IN_FLAGS(0), CASTCLASS_None, TEXT("/Script/ImGui"), NO_API) \
DECLARE_SERIALIZER(UImGuiInputHandler)
#define SwordNGun_Plugins_UnrealImGui_Source_ImGui_Public_ImGuiInputHandler_h_32_INCLASS \
private: \
static void StaticRegisterNativesUImGuiInputHandler(); \
friend struct Z_Construct_UClass_UImGuiInputHandler_Statics; \
public: \
DECLARE_CLASS(UImGuiInputHandler, UObject, COMPILED_IN_FLAGS(0), CASTCLASS_None, TEXT("/Script/ImGui"), NO_API) \
DECLARE_SERIALIZER(UImGuiInputHandler)
#define SwordNGun_Plugins_UnrealImGui_Source_ImGui_Public_ImGuiInputHandler_h_32_STANDARD_CONSTRUCTORS \
/** Standard constructor, called after all reflected properties have been initialized */ \
NO_API UImGuiInputHandler(const FObjectInitializer& ObjectInitializer = FObjectInitializer::Get()); \
DEFINE_DEFAULT_OBJECT_INITIALIZER_CONSTRUCTOR_CALL(UImGuiInputHandler) \
DECLARE_VTABLE_PTR_HELPER_CTOR(NO_API, UImGuiInputHandler); \
DEFINE_VTABLE_PTR_HELPER_CTOR_CALLER(UImGuiInputHandler); \
private: \
/** Private move- and copy-constructors, should never be used */ \
NO_API UImGuiInputHandler(UImGuiInputHandler&&); \
NO_API UImGuiInputHandler(const UImGuiInputHandler&); \
public:
#define SwordNGun_Plugins_UnrealImGui_Source_ImGui_Public_ImGuiInputHandler_h_32_ENHANCED_CONSTRUCTORS \
/** Standard constructor, called after all reflected properties have been initialized */ \
NO_API UImGuiInputHandler(const FObjectInitializer& ObjectInitializer = FObjectInitializer::Get()) : Super(ObjectInitializer) { }; \
private: \
/** Private move- and copy-constructors, should never be used */ \
NO_API UImGuiInputHandler(UImGuiInputHandler&&); \
NO_API UImGuiInputHandler(const UImGuiInputHandler&); \
public: \
DECLARE_VTABLE_PTR_HELPER_CTOR(NO_API, UImGuiInputHandler); \
DEFINE_VTABLE_PTR_HELPER_CTOR_CALLER(UImGuiInputHandler); \
DEFINE_DEFAULT_OBJECT_INITIALIZER_CONSTRUCTOR_CALL(UImGuiInputHandler)
#define SwordNGun_Plugins_UnrealImGui_Source_ImGui_Public_ImGuiInputHandler_h_32_PRIVATE_PROPERTY_OFFSET
#define SwordNGun_Plugins_UnrealImGui_Source_ImGui_Public_ImGuiInputHandler_h_29_PROLOG
#define SwordNGun_Plugins_UnrealImGui_Source_ImGui_Public_ImGuiInputHandler_h_32_GENERATED_BODY_LEGACY \
PRAGMA_DISABLE_DEPRECATION_WARNINGS \
public: \
SwordNGun_Plugins_UnrealImGui_Source_ImGui_Public_ImGuiInputHandler_h_32_PRIVATE_PROPERTY_OFFSET \
SwordNGun_Plugins_UnrealImGui_Source_ImGui_Public_ImGuiInputHandler_h_32_SPARSE_DATA \
SwordNGun_Plugins_UnrealImGui_Source_ImGui_Public_ImGuiInputHandler_h_32_RPC_WRAPPERS \
SwordNGun_Plugins_UnrealImGui_Source_ImGui_Public_ImGuiInputHandler_h_32_INCLASS \
SwordNGun_Plugins_UnrealImGui_Source_ImGui_Public_ImGuiInputHandler_h_32_STANDARD_CONSTRUCTORS \
public: \
PRAGMA_ENABLE_DEPRECATION_WARNINGS
#define SwordNGun_Plugins_UnrealImGui_Source_ImGui_Public_ImGuiInputHandler_h_32_GENERATED_BODY \
PRAGMA_DISABLE_DEPRECATION_WARNINGS \
public: \
SwordNGun_Plugins_UnrealImGui_Source_ImGui_Public_ImGuiInputHandler_h_32_PRIVATE_PROPERTY_OFFSET \
SwordNGun_Plugins_UnrealImGui_Source_ImGui_Public_ImGuiInputHandler_h_32_SPARSE_DATA \
SwordNGun_Plugins_UnrealImGui_Source_ImGui_Public_ImGuiInputHandler_h_32_RPC_WRAPPERS_NO_PURE_DECLS \
SwordNGun_Plugins_UnrealImGui_Source_ImGui_Public_ImGuiInputHandler_h_32_INCLASS_NO_PURE_DECLS \
SwordNGun_Plugins_UnrealImGui_Source_ImGui_Public_ImGuiInputHandler_h_32_ENHANCED_CONSTRUCTORS \
private: \
PRAGMA_ENABLE_DEPRECATION_WARNINGS
template<> IMGUI_API UClass* StaticClass<class UImGuiInputHandler>();
#undef CURRENT_FILE_ID
#define CURRENT_FILE_ID SwordNGun_Plugins_UnrealImGui_Source_ImGui_Public_ImGuiInputHandler_h
PRAGMA_ENABLE_DEPRECATION_WARNINGS

View File

@ -0,0 +1,778 @@
// Copyright Epic Games, Inc. All Rights Reserved.
/*===========================================================================
Generated code exported from UnrealHeaderTool.
DO NOT modify this manually! Edit the corresponding .h files instead!
===========================================================================*/
#include "UObject/GeneratedCppIncludes.h"
#include "ImGui/Private/ImGuiModuleSettings.h"
#ifdef _MSC_VER
#pragma warning (push)
#pragma warning (disable : 4883)
#endif
PRAGMA_DISABLE_DEPRECATION_WARNINGS
void EmptyLinkFunctionForGeneratedCodeImGuiModuleSettings() {}
// Cross Module References
IMGUI_API UEnum* Z_Construct_UEnum_ImGui_EImGuiDPIScaleMethod();
UPackage* Z_Construct_UPackage__Script_ImGui();
IMGUI_API UEnum* Z_Construct_UEnum_ImGui_EImGuiCanvasSizeType();
IMGUI_API UScriptStruct* Z_Construct_UScriptStruct_FImGuiDPIScaleInfo();
ENGINE_API UScriptStruct* Z_Construct_UScriptStruct_FRuntimeFloatCurve();
IMGUI_API UScriptStruct* Z_Construct_UScriptStruct_FImGuiCanvasSizeInfo();
IMGUI_API UScriptStruct* Z_Construct_UScriptStruct_FImGuiKeyInfo();
INPUTCORE_API UScriptStruct* Z_Construct_UScriptStruct_FKey();
SLATECORE_API UEnum* Z_Construct_UEnum_SlateCore_ECheckBoxState();
IMGUI_API UClass* Z_Construct_UClass_UImGuiSettings_NoRegister();
IMGUI_API UClass* Z_Construct_UClass_UImGuiSettings();
COREUOBJECT_API UClass* Z_Construct_UClass_UObject();
COREUOBJECT_API UScriptStruct* Z_Construct_UScriptStruct_FSoftClassPath();
// End Cross Module References
static UEnum* EImGuiDPIScaleMethod_StaticEnum()
{
static UEnum* Singleton = nullptr;
if (!Singleton)
{
Singleton = GetStaticEnum(Z_Construct_UEnum_ImGui_EImGuiDPIScaleMethod, Z_Construct_UPackage__Script_ImGui(), TEXT("EImGuiDPIScaleMethod"));
}
return Singleton;
}
template<> IMGUI_API UEnum* StaticEnum<EImGuiDPIScaleMethod>()
{
return EImGuiDPIScaleMethod_StaticEnum();
}
static FCompiledInDeferEnum Z_CompiledInDeferEnum_UEnum_EImGuiDPIScaleMethod(EImGuiDPIScaleMethod_StaticEnum, TEXT("/Script/ImGui"), TEXT("EImGuiDPIScaleMethod"), false, nullptr, nullptr);
uint32 Get_Z_Construct_UEnum_ImGui_EImGuiDPIScaleMethod_Hash() { return 1774743341U; }
UEnum* Z_Construct_UEnum_ImGui_EImGuiDPIScaleMethod()
{
#if WITH_HOT_RELOAD
UPackage* Outer = Z_Construct_UPackage__Script_ImGui();
static UEnum* ReturnEnum = FindExistingEnumIfHotReloadOrDynamic(Outer, TEXT("EImGuiDPIScaleMethod"), 0, Get_Z_Construct_UEnum_ImGui_EImGuiDPIScaleMethod_Hash(), false);
#else
static UEnum* ReturnEnum = nullptr;
#endif // WITH_HOT_RELOAD
if (!ReturnEnum)
{
static const UE4CodeGen_Private::FEnumeratorParam Enumerators[] = {
{ "EImGuiDPIScaleMethod::ImGui", (int64)EImGuiDPIScaleMethod::ImGui },
{ "EImGuiDPIScaleMethod::Slate", (int64)EImGuiDPIScaleMethod::Slate },
};
#if WITH_METADATA
const UE4CodeGen_Private::FMetaDataPairParam Enum_MetaDataParams[] = {
{ "BlueprintType", "true" },
{ "ImGui.DisplayName", "ImGui" },
{ "ImGui.Name", "EImGuiDPIScaleMethod::ImGui" },
{ "ImGui.ToolTip", "Scale ImGui fonts and styles." },
{ "ModuleRelativePath", "Private/ImGuiModuleSettings.h" },
{ "Slate.Name", "EImGuiDPIScaleMethod::Slate" },
{ "Slate.ToolTip", "Scale in Slate. ImGui canvas size will be adjusted to get the screen size that is the same as defined in the Canvas Size property." },
};
#endif
static const UE4CodeGen_Private::FEnumParams EnumParams = {
(UObject*(*)())Z_Construct_UPackage__Script_ImGui,
nullptr,
"EImGuiDPIScaleMethod",
"EImGuiDPIScaleMethod",
Enumerators,
UE_ARRAY_COUNT(Enumerators),
RF_Public|RF_Transient|RF_MarkAsNative,
EEnumFlags::None,
UE4CodeGen_Private::EDynamicType::NotDynamic,
(uint8)UEnum::ECppForm::EnumClass,
METADATA_PARAMS(Enum_MetaDataParams, UE_ARRAY_COUNT(Enum_MetaDataParams))
};
UE4CodeGen_Private::ConstructUEnum(ReturnEnum, EnumParams);
}
return ReturnEnum;
}
static UEnum* EImGuiCanvasSizeType_StaticEnum()
{
static UEnum* Singleton = nullptr;
if (!Singleton)
{
Singleton = GetStaticEnum(Z_Construct_UEnum_ImGui_EImGuiCanvasSizeType, Z_Construct_UPackage__Script_ImGui(), TEXT("EImGuiCanvasSizeType"));
}
return Singleton;
}
template<> IMGUI_API UEnum* StaticEnum<EImGuiCanvasSizeType>()
{
return EImGuiCanvasSizeType_StaticEnum();
}
static FCompiledInDeferEnum Z_CompiledInDeferEnum_UEnum_EImGuiCanvasSizeType(EImGuiCanvasSizeType_StaticEnum, TEXT("/Script/ImGui"), TEXT("EImGuiCanvasSizeType"), false, nullptr, nullptr);
uint32 Get_Z_Construct_UEnum_ImGui_EImGuiCanvasSizeType_Hash() { return 3553188282U; }
UEnum* Z_Construct_UEnum_ImGui_EImGuiCanvasSizeType()
{
#if WITH_HOT_RELOAD
UPackage* Outer = Z_Construct_UPackage__Script_ImGui();
static UEnum* ReturnEnum = FindExistingEnumIfHotReloadOrDynamic(Outer, TEXT("EImGuiCanvasSizeType"), 0, Get_Z_Construct_UEnum_ImGui_EImGuiCanvasSizeType_Hash(), false);
#else
static UEnum* ReturnEnum = nullptr;
#endif // WITH_HOT_RELOAD
if (!ReturnEnum)
{
static const UE4CodeGen_Private::FEnumeratorParam Enumerators[] = {
{ "EImGuiCanvasSizeType::Custom", (int64)EImGuiCanvasSizeType::Custom },
{ "EImGuiCanvasSizeType::Desktop", (int64)EImGuiCanvasSizeType::Desktop },
{ "EImGuiCanvasSizeType::Viewport", (int64)EImGuiCanvasSizeType::Viewport },
};
#if WITH_METADATA
const UE4CodeGen_Private::FMetaDataPairParam Enum_MetaDataParams[] = {
{ "BlueprintType", "true" },
{ "Custom.Name", "EImGuiCanvasSizeType::Custom" },
{ "Custom.ToolTip", "Canvas will have a custom width and height." },
{ "Desktop.Name", "EImGuiCanvasSizeType::Desktop" },
{ "Desktop.ToolTip", "Canvas will have the same width and height as the desktop." },
{ "ModuleRelativePath", "Private/ImGuiModuleSettings.h" },
{ "Viewport.Name", "EImGuiCanvasSizeType::Viewport" },
{ "Viewport.ToolTip", "Canvas will always have the same width and height as the viewport." },
};
#endif
static const UE4CodeGen_Private::FEnumParams EnumParams = {
(UObject*(*)())Z_Construct_UPackage__Script_ImGui,
nullptr,
"EImGuiCanvasSizeType",
"EImGuiCanvasSizeType",
Enumerators,
UE_ARRAY_COUNT(Enumerators),
RF_Public|RF_Transient|RF_MarkAsNative,
EEnumFlags::None,
UE4CodeGen_Private::EDynamicType::NotDynamic,
(uint8)UEnum::ECppForm::EnumClass,
METADATA_PARAMS(Enum_MetaDataParams, UE_ARRAY_COUNT(Enum_MetaDataParams))
};
UE4CodeGen_Private::ConstructUEnum(ReturnEnum, EnumParams);
}
return ReturnEnum;
}
class UScriptStruct* FImGuiDPIScaleInfo::StaticStruct()
{
static class UScriptStruct* Singleton = NULL;
if (!Singleton)
{
extern IMGUI_API uint32 Get_Z_Construct_UScriptStruct_FImGuiDPIScaleInfo_Hash();
Singleton = GetStaticStruct(Z_Construct_UScriptStruct_FImGuiDPIScaleInfo, Z_Construct_UPackage__Script_ImGui(), TEXT("ImGuiDPIScaleInfo"), sizeof(FImGuiDPIScaleInfo), Get_Z_Construct_UScriptStruct_FImGuiDPIScaleInfo_Hash());
}
return Singleton;
}
template<> IMGUI_API UScriptStruct* StaticStruct<FImGuiDPIScaleInfo>()
{
return FImGuiDPIScaleInfo::StaticStruct();
}
static FCompiledInDeferStruct Z_CompiledInDeferStruct_UScriptStruct_FImGuiDPIScaleInfo(FImGuiDPIScaleInfo::StaticStruct, TEXT("/Script/ImGui"), TEXT("ImGuiDPIScaleInfo"), false, nullptr, nullptr);
static struct FScriptStruct_ImGui_StaticRegisterNativesFImGuiDPIScaleInfo
{
FScriptStruct_ImGui_StaticRegisterNativesFImGuiDPIScaleInfo()
{
UScriptStruct::DeferCppStructOps(FName(TEXT("ImGuiDPIScaleInfo")),new UScriptStruct::TCppStructOps<FImGuiDPIScaleInfo>);
}
} ScriptStruct_ImGui_StaticRegisterNativesFImGuiDPIScaleInfo;
struct Z_Construct_UScriptStruct_FImGuiDPIScaleInfo_Statics
{
#if WITH_METADATA
static const UE4CodeGen_Private::FMetaDataPairParam Struct_MetaDataParams[];
#endif
static void* NewStructOps();
static const UE4CodeGen_Private::FBytePropertyParams NewProp_ScalingMethod_Underlying;
#if WITH_METADATA
static const UE4CodeGen_Private::FMetaDataPairParam NewProp_ScalingMethod_MetaData[];
#endif
static const UE4CodeGen_Private::FEnumPropertyParams NewProp_ScalingMethod;
#if WITH_METADATA
static const UE4CodeGen_Private::FMetaDataPairParam NewProp_Scale_MetaData[];
#endif
static const UE4CodeGen_Private::FFloatPropertyParams NewProp_Scale;
#if WITH_METADATA
static const UE4CodeGen_Private::FMetaDataPairParam NewProp_DPICurve_MetaData[];
#endif
static const UE4CodeGen_Private::FStructPropertyParams NewProp_DPICurve;
#if WITH_METADATA
static const UE4CodeGen_Private::FMetaDataPairParam NewProp_bScaleWithCurve_MetaData[];
#endif
static void NewProp_bScaleWithCurve_SetBit(void* Obj);
static const UE4CodeGen_Private::FBoolPropertyParams NewProp_bScaleWithCurve;
static const UE4CodeGen_Private::FPropertyParamsBase* const PropPointers[];
static const UE4CodeGen_Private::FStructParams ReturnStructParams;
};
#if WITH_METADATA
const UE4CodeGen_Private::FMetaDataPairParam Z_Construct_UScriptStruct_FImGuiDPIScaleInfo_Statics::Struct_MetaDataParams[] = {
{ "Comment", "/**\n * Struct with DPI scale data.\n */" },
{ "ModuleRelativePath", "Private/ImGuiModuleSettings.h" },
{ "ToolTip", "Struct with DPI scale data." },
};
#endif
void* Z_Construct_UScriptStruct_FImGuiDPIScaleInfo_Statics::NewStructOps()
{
return (UScriptStruct::ICppStructOps*)new UScriptStruct::TCppStructOps<FImGuiDPIScaleInfo>();
}
const UE4CodeGen_Private::FBytePropertyParams Z_Construct_UScriptStruct_FImGuiDPIScaleInfo_Statics::NewProp_ScalingMethod_Underlying = { "UnderlyingType", nullptr, (EPropertyFlags)0x0000000000000000, UE4CodeGen_Private::EPropertyGenFlags::Byte, RF_Public|RF_Transient|RF_MarkAsNative, 1, 0, nullptr, METADATA_PARAMS(nullptr, 0) };
#if WITH_METADATA
const UE4CodeGen_Private::FMetaDataPairParam Z_Construct_UScriptStruct_FImGuiDPIScaleInfo_Statics::NewProp_ScalingMethod_MetaData[] = {
{ "Category", "DPI Scale" },
{ "Comment", "// Whether to scale in ImGui or in Slate. Scaling in ImGui gives better looking results but Slate might be a better\n// option when layouts do not account for different fonts and styles. When scaling in Slate, ImGui canvas size will\n// be adjusted to get the screen size that is the same as defined in the Canvas Size property.\n" },
{ "ModuleRelativePath", "Private/ImGuiModuleSettings.h" },
{ "ToolTip", "Whether to scale in ImGui or in Slate. Scaling in ImGui gives better looking results but Slate might be a better\noption when layouts do not account for different fonts and styles. When scaling in Slate, ImGui canvas size will\nbe adjusted to get the screen size that is the same as defined in the Canvas Size property." },
};
#endif
const UE4CodeGen_Private::FEnumPropertyParams Z_Construct_UScriptStruct_FImGuiDPIScaleInfo_Statics::NewProp_ScalingMethod = { "ScalingMethod", nullptr, (EPropertyFlags)0x0020080000000001, UE4CodeGen_Private::EPropertyGenFlags::Enum, RF_Public|RF_Transient|RF_MarkAsNative, 1, STRUCT_OFFSET(FImGuiDPIScaleInfo, ScalingMethod), Z_Construct_UEnum_ImGui_EImGuiDPIScaleMethod, METADATA_PARAMS(Z_Construct_UScriptStruct_FImGuiDPIScaleInfo_Statics::NewProp_ScalingMethod_MetaData, UE_ARRAY_COUNT(Z_Construct_UScriptStruct_FImGuiDPIScaleInfo_Statics::NewProp_ScalingMethod_MetaData)) };
#if WITH_METADATA
const UE4CodeGen_Private::FMetaDataPairParam Z_Construct_UScriptStruct_FImGuiDPIScaleInfo_Statics::NewProp_Scale_MetaData[] = {
{ "Category", "DPI Scale" },
{ "ClampMin", "0" },
{ "Comment", "// An optional scale to apply on top or instead of the curve-based scale.\n" },
{ "ModuleRelativePath", "Private/ImGuiModuleSettings.h" },
{ "ToolTip", "An optional scale to apply on top or instead of the curve-based scale." },
{ "UIMin", "0" },
};
#endif
const UE4CodeGen_Private::FFloatPropertyParams Z_Construct_UScriptStruct_FImGuiDPIScaleInfo_Statics::NewProp_Scale = { "Scale", nullptr, (EPropertyFlags)0x0020080000000001, UE4CodeGen_Private::EPropertyGenFlags::Float, RF_Public|RF_Transient|RF_MarkAsNative, 1, STRUCT_OFFSET(FImGuiDPIScaleInfo, Scale), METADATA_PARAMS(Z_Construct_UScriptStruct_FImGuiDPIScaleInfo_Statics::NewProp_Scale_MetaData, UE_ARRAY_COUNT(Z_Construct_UScriptStruct_FImGuiDPIScaleInfo_Statics::NewProp_Scale_MetaData)) };
#if WITH_METADATA
const UE4CodeGen_Private::FMetaDataPairParam Z_Construct_UScriptStruct_FImGuiDPIScaleInfo_Statics::NewProp_DPICurve_MetaData[] = {
{ "Category", "DPI Scale" },
{ "Comment", "// Curve mapping resolution height to scale.\n" },
{ "EditCondition", "bScaleWithCurve" },
{ "ModuleRelativePath", "Private/ImGuiModuleSettings.h" },
{ "ToolTip", "Curve mapping resolution height to scale." },
{ "XAxisName", "Resolution Height" },
{ "YAxisName", "Scale" },
};
#endif
const UE4CodeGen_Private::FStructPropertyParams Z_Construct_UScriptStruct_FImGuiDPIScaleInfo_Statics::NewProp_DPICurve = { "DPICurve", nullptr, (EPropertyFlags)0x0020080000004001, UE4CodeGen_Private::EPropertyGenFlags::Struct, RF_Public|RF_Transient|RF_MarkAsNative, 1, STRUCT_OFFSET(FImGuiDPIScaleInfo, DPICurve), Z_Construct_UScriptStruct_FRuntimeFloatCurve, METADATA_PARAMS(Z_Construct_UScriptStruct_FImGuiDPIScaleInfo_Statics::NewProp_DPICurve_MetaData, UE_ARRAY_COUNT(Z_Construct_UScriptStruct_FImGuiDPIScaleInfo_Statics::NewProp_DPICurve_MetaData)) };
#if WITH_METADATA
const UE4CodeGen_Private::FMetaDataPairParam Z_Construct_UScriptStruct_FImGuiDPIScaleInfo_Statics::NewProp_bScaleWithCurve_MetaData[] = {
{ "Category", "DPI Scale" },
{ "Comment", "// Whether to use curve-based scaling. If enabled, Scale will be multiplied by a value read from the DPICurve.\n// If disabled, only the Scale property will be used.\n" },
{ "ModuleRelativePath", "Private/ImGuiModuleSettings.h" },
{ "ToolTip", "Whether to use curve-based scaling. If enabled, Scale will be multiplied by a value read from the DPICurve.\nIf disabled, only the Scale property will be used." },
};
#endif
void Z_Construct_UScriptStruct_FImGuiDPIScaleInfo_Statics::NewProp_bScaleWithCurve_SetBit(void* Obj)
{
((FImGuiDPIScaleInfo*)Obj)->bScaleWithCurve = 1;
}
const UE4CodeGen_Private::FBoolPropertyParams Z_Construct_UScriptStruct_FImGuiDPIScaleInfo_Statics::NewProp_bScaleWithCurve = { "bScaleWithCurve", nullptr, (EPropertyFlags)0x0020080000004001, UE4CodeGen_Private::EPropertyGenFlags::Bool | UE4CodeGen_Private::EPropertyGenFlags::NativeBool, RF_Public|RF_Transient|RF_MarkAsNative, 1, sizeof(bool), sizeof(FImGuiDPIScaleInfo), &Z_Construct_UScriptStruct_FImGuiDPIScaleInfo_Statics::NewProp_bScaleWithCurve_SetBit, METADATA_PARAMS(Z_Construct_UScriptStruct_FImGuiDPIScaleInfo_Statics::NewProp_bScaleWithCurve_MetaData, UE_ARRAY_COUNT(Z_Construct_UScriptStruct_FImGuiDPIScaleInfo_Statics::NewProp_bScaleWithCurve_MetaData)) };
const UE4CodeGen_Private::FPropertyParamsBase* const Z_Construct_UScriptStruct_FImGuiDPIScaleInfo_Statics::PropPointers[] = {
(const UE4CodeGen_Private::FPropertyParamsBase*)&Z_Construct_UScriptStruct_FImGuiDPIScaleInfo_Statics::NewProp_ScalingMethod_Underlying,
(const UE4CodeGen_Private::FPropertyParamsBase*)&Z_Construct_UScriptStruct_FImGuiDPIScaleInfo_Statics::NewProp_ScalingMethod,
(const UE4CodeGen_Private::FPropertyParamsBase*)&Z_Construct_UScriptStruct_FImGuiDPIScaleInfo_Statics::NewProp_Scale,
(const UE4CodeGen_Private::FPropertyParamsBase*)&Z_Construct_UScriptStruct_FImGuiDPIScaleInfo_Statics::NewProp_DPICurve,
(const UE4CodeGen_Private::FPropertyParamsBase*)&Z_Construct_UScriptStruct_FImGuiDPIScaleInfo_Statics::NewProp_bScaleWithCurve,
};
const UE4CodeGen_Private::FStructParams Z_Construct_UScriptStruct_FImGuiDPIScaleInfo_Statics::ReturnStructParams = {
(UObject* (*)())Z_Construct_UPackage__Script_ImGui,
nullptr,
&NewStructOps,
"ImGuiDPIScaleInfo",
sizeof(FImGuiDPIScaleInfo),
alignof(FImGuiDPIScaleInfo),
Z_Construct_UScriptStruct_FImGuiDPIScaleInfo_Statics::PropPointers,
UE_ARRAY_COUNT(Z_Construct_UScriptStruct_FImGuiDPIScaleInfo_Statics::PropPointers),
RF_Public|RF_Transient|RF_MarkAsNative,
EStructFlags(0x00000001),
METADATA_PARAMS(Z_Construct_UScriptStruct_FImGuiDPIScaleInfo_Statics::Struct_MetaDataParams, UE_ARRAY_COUNT(Z_Construct_UScriptStruct_FImGuiDPIScaleInfo_Statics::Struct_MetaDataParams))
};
UScriptStruct* Z_Construct_UScriptStruct_FImGuiDPIScaleInfo()
{
#if WITH_HOT_RELOAD
extern uint32 Get_Z_Construct_UScriptStruct_FImGuiDPIScaleInfo_Hash();
UPackage* Outer = Z_Construct_UPackage__Script_ImGui();
static UScriptStruct* ReturnStruct = FindExistingStructIfHotReloadOrDynamic(Outer, TEXT("ImGuiDPIScaleInfo"), sizeof(FImGuiDPIScaleInfo), Get_Z_Construct_UScriptStruct_FImGuiDPIScaleInfo_Hash(), false);
#else
static UScriptStruct* ReturnStruct = nullptr;
#endif
if (!ReturnStruct)
{
UE4CodeGen_Private::ConstructUScriptStruct(ReturnStruct, Z_Construct_UScriptStruct_FImGuiDPIScaleInfo_Statics::ReturnStructParams);
}
return ReturnStruct;
}
uint32 Get_Z_Construct_UScriptStruct_FImGuiDPIScaleInfo_Hash() { return 3642641870U; }
class UScriptStruct* FImGuiCanvasSizeInfo::StaticStruct()
{
static class UScriptStruct* Singleton = NULL;
if (!Singleton)
{
extern IMGUI_API uint32 Get_Z_Construct_UScriptStruct_FImGuiCanvasSizeInfo_Hash();
Singleton = GetStaticStruct(Z_Construct_UScriptStruct_FImGuiCanvasSizeInfo, Z_Construct_UPackage__Script_ImGui(), TEXT("ImGuiCanvasSizeInfo"), sizeof(FImGuiCanvasSizeInfo), Get_Z_Construct_UScriptStruct_FImGuiCanvasSizeInfo_Hash());
}
return Singleton;
}
template<> IMGUI_API UScriptStruct* StaticStruct<FImGuiCanvasSizeInfo>()
{
return FImGuiCanvasSizeInfo::StaticStruct();
}
static FCompiledInDeferStruct Z_CompiledInDeferStruct_UScriptStruct_FImGuiCanvasSizeInfo(FImGuiCanvasSizeInfo::StaticStruct, TEXT("/Script/ImGui"), TEXT("ImGuiCanvasSizeInfo"), false, nullptr, nullptr);
static struct FScriptStruct_ImGui_StaticRegisterNativesFImGuiCanvasSizeInfo
{
FScriptStruct_ImGui_StaticRegisterNativesFImGuiCanvasSizeInfo()
{
UScriptStruct::DeferCppStructOps(FName(TEXT("ImGuiCanvasSizeInfo")),new UScriptStruct::TCppStructOps<FImGuiCanvasSizeInfo>);
}
} ScriptStruct_ImGui_StaticRegisterNativesFImGuiCanvasSizeInfo;
struct Z_Construct_UScriptStruct_FImGuiCanvasSizeInfo_Statics
{
#if WITH_METADATA
static const UE4CodeGen_Private::FMetaDataPairParam Struct_MetaDataParams[];
#endif
static void* NewStructOps();
static const UE4CodeGen_Private::FBytePropertyParams NewProp_SizeType_Underlying;
#if WITH_METADATA
static const UE4CodeGen_Private::FMetaDataPairParam NewProp_SizeType_MetaData[];
#endif
static const UE4CodeGen_Private::FEnumPropertyParams NewProp_SizeType;
#if WITH_METADATA
static const UE4CodeGen_Private::FMetaDataPairParam NewProp_Width_MetaData[];
#endif
static const UE4CodeGen_Private::FIntPropertyParams NewProp_Width;
#if WITH_METADATA
static const UE4CodeGen_Private::FMetaDataPairParam NewProp_Height_MetaData[];
#endif
static const UE4CodeGen_Private::FIntPropertyParams NewProp_Height;
#if WITH_METADATA
static const UE4CodeGen_Private::FMetaDataPairParam NewProp_bExtendToViewport_MetaData[];
#endif
static void NewProp_bExtendToViewport_SetBit(void* Obj);
static const UE4CodeGen_Private::FBoolPropertyParams NewProp_bExtendToViewport;
static const UE4CodeGen_Private::FPropertyParamsBase* const PropPointers[];
static const UE4CodeGen_Private::FStructParams ReturnStructParams;
};
#if WITH_METADATA
const UE4CodeGen_Private::FMetaDataPairParam Z_Construct_UScriptStruct_FImGuiCanvasSizeInfo_Statics::Struct_MetaDataParams[] = {
{ "Comment", "/**\n * Struct with information how to calculate canvas size. \n */" },
{ "ModuleRelativePath", "Private/ImGuiModuleSettings.h" },
{ "ToolTip", "Struct with information how to calculate canvas size." },
};
#endif
void* Z_Construct_UScriptStruct_FImGuiCanvasSizeInfo_Statics::NewStructOps()
{
return (UScriptStruct::ICppStructOps*)new UScriptStruct::TCppStructOps<FImGuiCanvasSizeInfo>();
}
const UE4CodeGen_Private::FBytePropertyParams Z_Construct_UScriptStruct_FImGuiCanvasSizeInfo_Statics::NewProp_SizeType_Underlying = { "UnderlyingType", nullptr, (EPropertyFlags)0x0000000000000000, UE4CodeGen_Private::EPropertyGenFlags::Byte, RF_Public|RF_Transient|RF_MarkAsNative, 1, 0, nullptr, METADATA_PARAMS(nullptr, 0) };
#if WITH_METADATA
const UE4CodeGen_Private::FMetaDataPairParam Z_Construct_UScriptStruct_FImGuiCanvasSizeInfo_Statics::NewProp_SizeType_MetaData[] = {
{ "Category", "Canvas Size" },
{ "Comment", "// Select how to specify canvas size.\n" },
{ "ModuleRelativePath", "Private/ImGuiModuleSettings.h" },
{ "ToolTip", "Select how to specify canvas size." },
};
#endif
const UE4CodeGen_Private::FEnumPropertyParams Z_Construct_UScriptStruct_FImGuiCanvasSizeInfo_Statics::NewProp_SizeType = { "SizeType", nullptr, (EPropertyFlags)0x0010000000000001, UE4CodeGen_Private::EPropertyGenFlags::Enum, RF_Public|RF_Transient|RF_MarkAsNative, 1, STRUCT_OFFSET(FImGuiCanvasSizeInfo, SizeType), Z_Construct_UEnum_ImGui_EImGuiCanvasSizeType, METADATA_PARAMS(Z_Construct_UScriptStruct_FImGuiCanvasSizeInfo_Statics::NewProp_SizeType_MetaData, UE_ARRAY_COUNT(Z_Construct_UScriptStruct_FImGuiCanvasSizeInfo_Statics::NewProp_SizeType_MetaData)) };
#if WITH_METADATA
const UE4CodeGen_Private::FMetaDataPairParam Z_Construct_UScriptStruct_FImGuiCanvasSizeInfo_Statics::NewProp_Width_MetaData[] = {
{ "Category", "Canvas Size" },
{ "ClampMin", "0" },
{ "Comment", "// Custom canvas width.\n" },
{ "ModuleRelativePath", "Private/ImGuiModuleSettings.h" },
{ "ToolTip", "Custom canvas width." },
{ "UIMin", "0" },
};
#endif
const UE4CodeGen_Private::FIntPropertyParams Z_Construct_UScriptStruct_FImGuiCanvasSizeInfo_Statics::NewProp_Width = { "Width", nullptr, (EPropertyFlags)0x0010000000000001, UE4CodeGen_Private::EPropertyGenFlags::Int, RF_Public|RF_Transient|RF_MarkAsNative, 1, STRUCT_OFFSET(FImGuiCanvasSizeInfo, Width), METADATA_PARAMS(Z_Construct_UScriptStruct_FImGuiCanvasSizeInfo_Statics::NewProp_Width_MetaData, UE_ARRAY_COUNT(Z_Construct_UScriptStruct_FImGuiCanvasSizeInfo_Statics::NewProp_Width_MetaData)) };
#if WITH_METADATA
const UE4CodeGen_Private::FMetaDataPairParam Z_Construct_UScriptStruct_FImGuiCanvasSizeInfo_Statics::NewProp_Height_MetaData[] = {
{ "Category", "Canvas Size" },
{ "ClampMin", "0" },
{ "Comment", "// Custom canvas height.\n" },
{ "ModuleRelativePath", "Private/ImGuiModuleSettings.h" },
{ "ToolTip", "Custom canvas height." },
{ "UIMin", "0" },
};
#endif
const UE4CodeGen_Private::FIntPropertyParams Z_Construct_UScriptStruct_FImGuiCanvasSizeInfo_Statics::NewProp_Height = { "Height", nullptr, (EPropertyFlags)0x0010000000000001, UE4CodeGen_Private::EPropertyGenFlags::Int, RF_Public|RF_Transient|RF_MarkAsNative, 1, STRUCT_OFFSET(FImGuiCanvasSizeInfo, Height), METADATA_PARAMS(Z_Construct_UScriptStruct_FImGuiCanvasSizeInfo_Statics::NewProp_Height_MetaData, UE_ARRAY_COUNT(Z_Construct_UScriptStruct_FImGuiCanvasSizeInfo_Statics::NewProp_Height_MetaData)) };
#if WITH_METADATA
const UE4CodeGen_Private::FMetaDataPairParam Z_Construct_UScriptStruct_FImGuiCanvasSizeInfo_Statics::NewProp_bExtendToViewport_MetaData[] = {
{ "Category", "Canvas Size" },
{ "ClampMin", "0" },
{ "Comment", "// If this is true, canvas width or height may be extended, if the viewport size is larger.\n" },
{ "ModuleRelativePath", "Private/ImGuiModuleSettings.h" },
{ "ToolTip", "If this is true, canvas width or height may be extended, if the viewport size is larger." },
{ "UIMin", "0" },
};
#endif
void Z_Construct_UScriptStruct_FImGuiCanvasSizeInfo_Statics::NewProp_bExtendToViewport_SetBit(void* Obj)
{
((FImGuiCanvasSizeInfo*)Obj)->bExtendToViewport = 1;
}
const UE4CodeGen_Private::FBoolPropertyParams Z_Construct_UScriptStruct_FImGuiCanvasSizeInfo_Statics::NewProp_bExtendToViewport = { "bExtendToViewport", nullptr, (EPropertyFlags)0x0010000000000001, UE4CodeGen_Private::EPropertyGenFlags::Bool | UE4CodeGen_Private::EPropertyGenFlags::NativeBool, RF_Public|RF_Transient|RF_MarkAsNative, 1, sizeof(bool), sizeof(FImGuiCanvasSizeInfo), &Z_Construct_UScriptStruct_FImGuiCanvasSizeInfo_Statics::NewProp_bExtendToViewport_SetBit, METADATA_PARAMS(Z_Construct_UScriptStruct_FImGuiCanvasSizeInfo_Statics::NewProp_bExtendToViewport_MetaData, UE_ARRAY_COUNT(Z_Construct_UScriptStruct_FImGuiCanvasSizeInfo_Statics::NewProp_bExtendToViewport_MetaData)) };
const UE4CodeGen_Private::FPropertyParamsBase* const Z_Construct_UScriptStruct_FImGuiCanvasSizeInfo_Statics::PropPointers[] = {
(const UE4CodeGen_Private::FPropertyParamsBase*)&Z_Construct_UScriptStruct_FImGuiCanvasSizeInfo_Statics::NewProp_SizeType_Underlying,
(const UE4CodeGen_Private::FPropertyParamsBase*)&Z_Construct_UScriptStruct_FImGuiCanvasSizeInfo_Statics::NewProp_SizeType,
(const UE4CodeGen_Private::FPropertyParamsBase*)&Z_Construct_UScriptStruct_FImGuiCanvasSizeInfo_Statics::NewProp_Width,
(const UE4CodeGen_Private::FPropertyParamsBase*)&Z_Construct_UScriptStruct_FImGuiCanvasSizeInfo_Statics::NewProp_Height,
(const UE4CodeGen_Private::FPropertyParamsBase*)&Z_Construct_UScriptStruct_FImGuiCanvasSizeInfo_Statics::NewProp_bExtendToViewport,
};
const UE4CodeGen_Private::FStructParams Z_Construct_UScriptStruct_FImGuiCanvasSizeInfo_Statics::ReturnStructParams = {
(UObject* (*)())Z_Construct_UPackage__Script_ImGui,
nullptr,
&NewStructOps,
"ImGuiCanvasSizeInfo",
sizeof(FImGuiCanvasSizeInfo),
alignof(FImGuiCanvasSizeInfo),
Z_Construct_UScriptStruct_FImGuiCanvasSizeInfo_Statics::PropPointers,
UE_ARRAY_COUNT(Z_Construct_UScriptStruct_FImGuiCanvasSizeInfo_Statics::PropPointers),
RF_Public|RF_Transient|RF_MarkAsNative,
EStructFlags(0x00000001),
METADATA_PARAMS(Z_Construct_UScriptStruct_FImGuiCanvasSizeInfo_Statics::Struct_MetaDataParams, UE_ARRAY_COUNT(Z_Construct_UScriptStruct_FImGuiCanvasSizeInfo_Statics::Struct_MetaDataParams))
};
UScriptStruct* Z_Construct_UScriptStruct_FImGuiCanvasSizeInfo()
{
#if WITH_HOT_RELOAD
extern uint32 Get_Z_Construct_UScriptStruct_FImGuiCanvasSizeInfo_Hash();
UPackage* Outer = Z_Construct_UPackage__Script_ImGui();
static UScriptStruct* ReturnStruct = FindExistingStructIfHotReloadOrDynamic(Outer, TEXT("ImGuiCanvasSizeInfo"), sizeof(FImGuiCanvasSizeInfo), Get_Z_Construct_UScriptStruct_FImGuiCanvasSizeInfo_Hash(), false);
#else
static UScriptStruct* ReturnStruct = nullptr;
#endif
if (!ReturnStruct)
{
UE4CodeGen_Private::ConstructUScriptStruct(ReturnStruct, Z_Construct_UScriptStruct_FImGuiCanvasSizeInfo_Statics::ReturnStructParams);
}
return ReturnStruct;
}
uint32 Get_Z_Construct_UScriptStruct_FImGuiCanvasSizeInfo_Hash() { return 1208985022U; }
class UScriptStruct* FImGuiKeyInfo::StaticStruct()
{
static class UScriptStruct* Singleton = NULL;
if (!Singleton)
{
extern IMGUI_API uint32 Get_Z_Construct_UScriptStruct_FImGuiKeyInfo_Hash();
Singleton = GetStaticStruct(Z_Construct_UScriptStruct_FImGuiKeyInfo, Z_Construct_UPackage__Script_ImGui(), TEXT("ImGuiKeyInfo"), sizeof(FImGuiKeyInfo), Get_Z_Construct_UScriptStruct_FImGuiKeyInfo_Hash());
}
return Singleton;
}
template<> IMGUI_API UScriptStruct* StaticStruct<FImGuiKeyInfo>()
{
return FImGuiKeyInfo::StaticStruct();
}
static FCompiledInDeferStruct Z_CompiledInDeferStruct_UScriptStruct_FImGuiKeyInfo(FImGuiKeyInfo::StaticStruct, TEXT("/Script/ImGui"), TEXT("ImGuiKeyInfo"), false, nullptr, nullptr);
static struct FScriptStruct_ImGui_StaticRegisterNativesFImGuiKeyInfo
{
FScriptStruct_ImGui_StaticRegisterNativesFImGuiKeyInfo()
{
UScriptStruct::DeferCppStructOps(FName(TEXT("ImGuiKeyInfo")),new UScriptStruct::TCppStructOps<FImGuiKeyInfo>);
}
} ScriptStruct_ImGui_StaticRegisterNativesFImGuiKeyInfo;
struct Z_Construct_UScriptStruct_FImGuiKeyInfo_Statics
{
#if WITH_METADATA
static const UE4CodeGen_Private::FMetaDataPairParam Struct_MetaDataParams[];
#endif
static void* NewStructOps();
#if WITH_METADATA
static const UE4CodeGen_Private::FMetaDataPairParam NewProp_Key_MetaData[];
#endif
static const UE4CodeGen_Private::FStructPropertyParams NewProp_Key;
static const UE4CodeGen_Private::FBytePropertyParams NewProp_Shift_Underlying;
#if WITH_METADATA
static const UE4CodeGen_Private::FMetaDataPairParam NewProp_Shift_MetaData[];
#endif
static const UE4CodeGen_Private::FEnumPropertyParams NewProp_Shift;
static const UE4CodeGen_Private::FBytePropertyParams NewProp_Ctrl_Underlying;
#if WITH_METADATA
static const UE4CodeGen_Private::FMetaDataPairParam NewProp_Ctrl_MetaData[];
#endif
static const UE4CodeGen_Private::FEnumPropertyParams NewProp_Ctrl;
static const UE4CodeGen_Private::FBytePropertyParams NewProp_Alt_Underlying;
#if WITH_METADATA
static const UE4CodeGen_Private::FMetaDataPairParam NewProp_Alt_MetaData[];
#endif
static const UE4CodeGen_Private::FEnumPropertyParams NewProp_Alt;
static const UE4CodeGen_Private::FBytePropertyParams NewProp_Cmd_Underlying;
#if WITH_METADATA
static const UE4CodeGen_Private::FMetaDataPairParam NewProp_Cmd_MetaData[];
#endif
static const UE4CodeGen_Private::FEnumPropertyParams NewProp_Cmd;
static const UE4CodeGen_Private::FPropertyParamsBase* const PropPointers[];
static const UE4CodeGen_Private::FStructParams ReturnStructParams;
};
#if WITH_METADATA
const UE4CodeGen_Private::FMetaDataPairParam Z_Construct_UScriptStruct_FImGuiKeyInfo_Statics::Struct_MetaDataParams[] = {
{ "Comment", "/**\n * Struct containing key information that can be used for key binding. Using 'Undetermined' value for modifier keys\n * means that those keys should be ignored when testing for a match.\n */" },
{ "ModuleRelativePath", "Private/ImGuiModuleSettings.h" },
{ "ToolTip", "Struct containing key information that can be used for key binding. Using 'Undetermined' value for modifier keys\nmeans that those keys should be ignored when testing for a match." },
};
#endif
void* Z_Construct_UScriptStruct_FImGuiKeyInfo_Statics::NewStructOps()
{
return (UScriptStruct::ICppStructOps*)new UScriptStruct::TCppStructOps<FImGuiKeyInfo>();
}
#if WITH_METADATA
const UE4CodeGen_Private::FMetaDataPairParam Z_Construct_UScriptStruct_FImGuiKeyInfo_Statics::NewProp_Key_MetaData[] = {
{ "Category", "Input" },
{ "ModuleRelativePath", "Private/ImGuiModuleSettings.h" },
};
#endif
const UE4CodeGen_Private::FStructPropertyParams Z_Construct_UScriptStruct_FImGuiKeyInfo_Statics::NewProp_Key = { "Key", nullptr, (EPropertyFlags)0x0010000000000001, UE4CodeGen_Private::EPropertyGenFlags::Struct, RF_Public|RF_Transient|RF_MarkAsNative, 1, STRUCT_OFFSET(FImGuiKeyInfo, Key), Z_Construct_UScriptStruct_FKey, METADATA_PARAMS(Z_Construct_UScriptStruct_FImGuiKeyInfo_Statics::NewProp_Key_MetaData, UE_ARRAY_COUNT(Z_Construct_UScriptStruct_FImGuiKeyInfo_Statics::NewProp_Key_MetaData)) };
const UE4CodeGen_Private::FBytePropertyParams Z_Construct_UScriptStruct_FImGuiKeyInfo_Statics::NewProp_Shift_Underlying = { "UnderlyingType", nullptr, (EPropertyFlags)0x0000000000000000, UE4CodeGen_Private::EPropertyGenFlags::Byte, RF_Public|RF_Transient|RF_MarkAsNative, 1, 0, nullptr, METADATA_PARAMS(nullptr, 0) };
#if WITH_METADATA
const UE4CodeGen_Private::FMetaDataPairParam Z_Construct_UScriptStruct_FImGuiKeyInfo_Statics::NewProp_Shift_MetaData[] = {
{ "Category", "Input" },
{ "ModuleRelativePath", "Private/ImGuiModuleSettings.h" },
};
#endif
const UE4CodeGen_Private::FEnumPropertyParams Z_Construct_UScriptStruct_FImGuiKeyInfo_Statics::NewProp_Shift = { "Shift", nullptr, (EPropertyFlags)0x0010000000000001, UE4CodeGen_Private::EPropertyGenFlags::Enum, RF_Public|RF_Transient|RF_MarkAsNative, 1, STRUCT_OFFSET(FImGuiKeyInfo, Shift), Z_Construct_UEnum_SlateCore_ECheckBoxState, METADATA_PARAMS(Z_Construct_UScriptStruct_FImGuiKeyInfo_Statics::NewProp_Shift_MetaData, UE_ARRAY_COUNT(Z_Construct_UScriptStruct_FImGuiKeyInfo_Statics::NewProp_Shift_MetaData)) };
const UE4CodeGen_Private::FBytePropertyParams Z_Construct_UScriptStruct_FImGuiKeyInfo_Statics::NewProp_Ctrl_Underlying = { "UnderlyingType", nullptr, (EPropertyFlags)0x0000000000000000, UE4CodeGen_Private::EPropertyGenFlags::Byte, RF_Public|RF_Transient|RF_MarkAsNative, 1, 0, nullptr, METADATA_PARAMS(nullptr, 0) };
#if WITH_METADATA
const UE4CodeGen_Private::FMetaDataPairParam Z_Construct_UScriptStruct_FImGuiKeyInfo_Statics::NewProp_Ctrl_MetaData[] = {
{ "Category", "Input" },
{ "ModuleRelativePath", "Private/ImGuiModuleSettings.h" },
};
#endif
const UE4CodeGen_Private::FEnumPropertyParams Z_Construct_UScriptStruct_FImGuiKeyInfo_Statics::NewProp_Ctrl = { "Ctrl", nullptr, (EPropertyFlags)0x0010000000000001, UE4CodeGen_Private::EPropertyGenFlags::Enum, RF_Public|RF_Transient|RF_MarkAsNative, 1, STRUCT_OFFSET(FImGuiKeyInfo, Ctrl), Z_Construct_UEnum_SlateCore_ECheckBoxState, METADATA_PARAMS(Z_Construct_UScriptStruct_FImGuiKeyInfo_Statics::NewProp_Ctrl_MetaData, UE_ARRAY_COUNT(Z_Construct_UScriptStruct_FImGuiKeyInfo_Statics::NewProp_Ctrl_MetaData)) };
const UE4CodeGen_Private::FBytePropertyParams Z_Construct_UScriptStruct_FImGuiKeyInfo_Statics::NewProp_Alt_Underlying = { "UnderlyingType", nullptr, (EPropertyFlags)0x0000000000000000, UE4CodeGen_Private::EPropertyGenFlags::Byte, RF_Public|RF_Transient|RF_MarkAsNative, 1, 0, nullptr, METADATA_PARAMS(nullptr, 0) };
#if WITH_METADATA
const UE4CodeGen_Private::FMetaDataPairParam Z_Construct_UScriptStruct_FImGuiKeyInfo_Statics::NewProp_Alt_MetaData[] = {
{ "Category", "Input" },
{ "ModuleRelativePath", "Private/ImGuiModuleSettings.h" },
};
#endif
const UE4CodeGen_Private::FEnumPropertyParams Z_Construct_UScriptStruct_FImGuiKeyInfo_Statics::NewProp_Alt = { "Alt", nullptr, (EPropertyFlags)0x0010000000000001, UE4CodeGen_Private::EPropertyGenFlags::Enum, RF_Public|RF_Transient|RF_MarkAsNative, 1, STRUCT_OFFSET(FImGuiKeyInfo, Alt), Z_Construct_UEnum_SlateCore_ECheckBoxState, METADATA_PARAMS(Z_Construct_UScriptStruct_FImGuiKeyInfo_Statics::NewProp_Alt_MetaData, UE_ARRAY_COUNT(Z_Construct_UScriptStruct_FImGuiKeyInfo_Statics::NewProp_Alt_MetaData)) };
const UE4CodeGen_Private::FBytePropertyParams Z_Construct_UScriptStruct_FImGuiKeyInfo_Statics::NewProp_Cmd_Underlying = { "UnderlyingType", nullptr, (EPropertyFlags)0x0000000000000000, UE4CodeGen_Private::EPropertyGenFlags::Byte, RF_Public|RF_Transient|RF_MarkAsNative, 1, 0, nullptr, METADATA_PARAMS(nullptr, 0) };
#if WITH_METADATA
const UE4CodeGen_Private::FMetaDataPairParam Z_Construct_UScriptStruct_FImGuiKeyInfo_Statics::NewProp_Cmd_MetaData[] = {
{ "Category", "Input" },
{ "ModuleRelativePath", "Private/ImGuiModuleSettings.h" },
};
#endif
const UE4CodeGen_Private::FEnumPropertyParams Z_Construct_UScriptStruct_FImGuiKeyInfo_Statics::NewProp_Cmd = { "Cmd", nullptr, (EPropertyFlags)0x0010000000000001, UE4CodeGen_Private::EPropertyGenFlags::Enum, RF_Public|RF_Transient|RF_MarkAsNative, 1, STRUCT_OFFSET(FImGuiKeyInfo, Cmd), Z_Construct_UEnum_SlateCore_ECheckBoxState, METADATA_PARAMS(Z_Construct_UScriptStruct_FImGuiKeyInfo_Statics::NewProp_Cmd_MetaData, UE_ARRAY_COUNT(Z_Construct_UScriptStruct_FImGuiKeyInfo_Statics::NewProp_Cmd_MetaData)) };
const UE4CodeGen_Private::FPropertyParamsBase* const Z_Construct_UScriptStruct_FImGuiKeyInfo_Statics::PropPointers[] = {
(const UE4CodeGen_Private::FPropertyParamsBase*)&Z_Construct_UScriptStruct_FImGuiKeyInfo_Statics::NewProp_Key,
(const UE4CodeGen_Private::FPropertyParamsBase*)&Z_Construct_UScriptStruct_FImGuiKeyInfo_Statics::NewProp_Shift_Underlying,
(const UE4CodeGen_Private::FPropertyParamsBase*)&Z_Construct_UScriptStruct_FImGuiKeyInfo_Statics::NewProp_Shift,
(const UE4CodeGen_Private::FPropertyParamsBase*)&Z_Construct_UScriptStruct_FImGuiKeyInfo_Statics::NewProp_Ctrl_Underlying,
(const UE4CodeGen_Private::FPropertyParamsBase*)&Z_Construct_UScriptStruct_FImGuiKeyInfo_Statics::NewProp_Ctrl,
(const UE4CodeGen_Private::FPropertyParamsBase*)&Z_Construct_UScriptStruct_FImGuiKeyInfo_Statics::NewProp_Alt_Underlying,
(const UE4CodeGen_Private::FPropertyParamsBase*)&Z_Construct_UScriptStruct_FImGuiKeyInfo_Statics::NewProp_Alt,
(const UE4CodeGen_Private::FPropertyParamsBase*)&Z_Construct_UScriptStruct_FImGuiKeyInfo_Statics::NewProp_Cmd_Underlying,
(const UE4CodeGen_Private::FPropertyParamsBase*)&Z_Construct_UScriptStruct_FImGuiKeyInfo_Statics::NewProp_Cmd,
};
const UE4CodeGen_Private::FStructParams Z_Construct_UScriptStruct_FImGuiKeyInfo_Statics::ReturnStructParams = {
(UObject* (*)())Z_Construct_UPackage__Script_ImGui,
nullptr,
&NewStructOps,
"ImGuiKeyInfo",
sizeof(FImGuiKeyInfo),
alignof(FImGuiKeyInfo),
Z_Construct_UScriptStruct_FImGuiKeyInfo_Statics::PropPointers,
UE_ARRAY_COUNT(Z_Construct_UScriptStruct_FImGuiKeyInfo_Statics::PropPointers),
RF_Public|RF_Transient|RF_MarkAsNative,
EStructFlags(0x00000001),
METADATA_PARAMS(Z_Construct_UScriptStruct_FImGuiKeyInfo_Statics::Struct_MetaDataParams, UE_ARRAY_COUNT(Z_Construct_UScriptStruct_FImGuiKeyInfo_Statics::Struct_MetaDataParams))
};
UScriptStruct* Z_Construct_UScriptStruct_FImGuiKeyInfo()
{
#if WITH_HOT_RELOAD
extern uint32 Get_Z_Construct_UScriptStruct_FImGuiKeyInfo_Hash();
UPackage* Outer = Z_Construct_UPackage__Script_ImGui();
static UScriptStruct* ReturnStruct = FindExistingStructIfHotReloadOrDynamic(Outer, TEXT("ImGuiKeyInfo"), sizeof(FImGuiKeyInfo), Get_Z_Construct_UScriptStruct_FImGuiKeyInfo_Hash(), false);
#else
static UScriptStruct* ReturnStruct = nullptr;
#endif
if (!ReturnStruct)
{
UE4CodeGen_Private::ConstructUScriptStruct(ReturnStruct, Z_Construct_UScriptStruct_FImGuiKeyInfo_Statics::ReturnStructParams);
}
return ReturnStruct;
}
uint32 Get_Z_Construct_UScriptStruct_FImGuiKeyInfo_Hash() { return 1263491035U; }
void UImGuiSettings::StaticRegisterNativesUImGuiSettings()
{
}
UClass* Z_Construct_UClass_UImGuiSettings_NoRegister()
{
return UImGuiSettings::StaticClass();
}
struct Z_Construct_UClass_UImGuiSettings_Statics
{
static UObject* (*const DependentSingletons[])();
#if WITH_METADATA
static const UE4CodeGen_Private::FMetaDataPairParam Class_MetaDataParams[];
#endif
#if WITH_METADATA
static const UE4CodeGen_Private::FMetaDataPairParam NewProp_ImGuiInputHandlerClass_MetaData[];
#endif
static const UE4CodeGen_Private::FStructPropertyParams NewProp_ImGuiInputHandlerClass;
#if WITH_METADATA
static const UE4CodeGen_Private::FMetaDataPairParam NewProp_bShareKeyboardInput_MetaData[];
#endif
static void NewProp_bShareKeyboardInput_SetBit(void* Obj);
static const UE4CodeGen_Private::FBoolPropertyParams NewProp_bShareKeyboardInput;
#if WITH_METADATA
static const UE4CodeGen_Private::FMetaDataPairParam NewProp_bShareGamepadInput_MetaData[];
#endif
static void NewProp_bShareGamepadInput_SetBit(void* Obj);
static const UE4CodeGen_Private::FBoolPropertyParams NewProp_bShareGamepadInput;
#if WITH_METADATA
static const UE4CodeGen_Private::FMetaDataPairParam NewProp_bShareMouseInput_MetaData[];
#endif
static void NewProp_bShareMouseInput_SetBit(void* Obj);
static const UE4CodeGen_Private::FBoolPropertyParams NewProp_bShareMouseInput;
#if WITH_METADATA
static const UE4CodeGen_Private::FMetaDataPairParam NewProp_bUseSoftwareCursor_MetaData[];
#endif
static void NewProp_bUseSoftwareCursor_SetBit(void* Obj);
static const UE4CodeGen_Private::FBoolPropertyParams NewProp_bUseSoftwareCursor;
#if WITH_METADATA
static const UE4CodeGen_Private::FMetaDataPairParam NewProp_ToggleInput_MetaData[];
#endif
static const UE4CodeGen_Private::FStructPropertyParams NewProp_ToggleInput;
#if WITH_METADATA
static const UE4CodeGen_Private::FMetaDataPairParam NewProp_CanvasSize_MetaData[];
#endif
static const UE4CodeGen_Private::FStructPropertyParams NewProp_CanvasSize;
#if WITH_METADATA
static const UE4CodeGen_Private::FMetaDataPairParam NewProp_DPIScale_MetaData[];
#endif
static const UE4CodeGen_Private::FStructPropertyParams NewProp_DPIScale;
static const UE4CodeGen_Private::FPropertyParamsBase* const PropPointers[];
static const FCppClassTypeInfoStatic StaticCppClassTypeInfo;
static const UE4CodeGen_Private::FClassParams ClassParams;
};
UObject* (*const Z_Construct_UClass_UImGuiSettings_Statics::DependentSingletons[])() = {
(UObject* (*)())Z_Construct_UClass_UObject,
(UObject* (*)())Z_Construct_UPackage__Script_ImGui,
};
#if WITH_METADATA
const UE4CodeGen_Private::FMetaDataPairParam Z_Construct_UClass_UImGuiSettings_Statics::Class_MetaDataParams[] = {
{ "Comment", "// UObject used for loading and saving ImGui settings. To access actual settings use FImGuiModuleSettings interface.\n" },
{ "IncludePath", "ImGuiModuleSettings.h" },
{ "ModuleRelativePath", "Private/ImGuiModuleSettings.h" },
{ "ToolTip", "UObject used for loading and saving ImGui settings. To access actual settings use FImGuiModuleSettings interface." },
};
#endif
#if WITH_METADATA
const UE4CodeGen_Private::FMetaDataPairParam Z_Construct_UClass_UImGuiSettings_Statics::NewProp_ImGuiInputHandlerClass_MetaData[] = {
{ "Category", "Extensions" },
{ "Comment", "// Path to own implementation of ImGui Input Handler allowing to customize handling of keyboard and gamepad input.\n// If not set then default handler is used.\n" },
{ "MetaClass", "ImGuiInputHandler" },
{ "ModuleRelativePath", "Private/ImGuiModuleSettings.h" },
{ "ToolTip", "Path to own implementation of ImGui Input Handler allowing to customize handling of keyboard and gamepad input.\nIf not set then default handler is used." },
};
#endif
const UE4CodeGen_Private::FStructPropertyParams Z_Construct_UClass_UImGuiSettings_Statics::NewProp_ImGuiInputHandlerClass = { "ImGuiInputHandlerClass", nullptr, (EPropertyFlags)0x0020080000004001, UE4CodeGen_Private::EPropertyGenFlags::Struct, RF_Public|RF_Transient|RF_MarkAsNative, 1, STRUCT_OFFSET(UImGuiSettings, ImGuiInputHandlerClass), Z_Construct_UScriptStruct_FSoftClassPath, METADATA_PARAMS(Z_Construct_UClass_UImGuiSettings_Statics::NewProp_ImGuiInputHandlerClass_MetaData, UE_ARRAY_COUNT(Z_Construct_UClass_UImGuiSettings_Statics::NewProp_ImGuiInputHandlerClass_MetaData)) };
#if WITH_METADATA
const UE4CodeGen_Private::FMetaDataPairParam Z_Construct_UClass_UImGuiSettings_Statics::NewProp_bShareKeyboardInput_MetaData[] = {
{ "Category", "Input" },
{ "Comment", "// Whether ImGui should share keyboard input with game.\n// This defines initial behaviour which can be later changed using 'ImGui.ToggleKeyboardInputSharing' command or\n// module properties interface.\n" },
{ "ModuleRelativePath", "Private/ImGuiModuleSettings.h" },
{ "ToolTip", "Whether ImGui should share keyboard input with game.\nThis defines initial behaviour which can be later changed using 'ImGui.ToggleKeyboardInputSharing' command or\nmodule properties interface." },
};
#endif
void Z_Construct_UClass_UImGuiSettings_Statics::NewProp_bShareKeyboardInput_SetBit(void* Obj)
{
((UImGuiSettings*)Obj)->bShareKeyboardInput = 1;
}
const UE4CodeGen_Private::FBoolPropertyParams Z_Construct_UClass_UImGuiSettings_Statics::NewProp_bShareKeyboardInput = { "bShareKeyboardInput", nullptr, (EPropertyFlags)0x0020080000004001, UE4CodeGen_Private::EPropertyGenFlags::Bool | UE4CodeGen_Private::EPropertyGenFlags::NativeBool, RF_Public|RF_Transient|RF_MarkAsNative, 1, sizeof(bool), sizeof(UImGuiSettings), &Z_Construct_UClass_UImGuiSettings_Statics::NewProp_bShareKeyboardInput_SetBit, METADATA_PARAMS(Z_Construct_UClass_UImGuiSettings_Statics::NewProp_bShareKeyboardInput_MetaData, UE_ARRAY_COUNT(Z_Construct_UClass_UImGuiSettings_Statics::NewProp_bShareKeyboardInput_MetaData)) };
#if WITH_METADATA
const UE4CodeGen_Private::FMetaDataPairParam Z_Construct_UClass_UImGuiSettings_Statics::NewProp_bShareGamepadInput_MetaData[] = {
{ "Category", "Input" },
{ "Comment", "// Whether ImGui should share gamepad input with game.\n// This defines initial behaviour which can be later changed using 'ImGui.ToggleGamepadInputSharing' command or\n// module properties interface.\n" },
{ "ModuleRelativePath", "Private/ImGuiModuleSettings.h" },
{ "ToolTip", "Whether ImGui should share gamepad input with game.\nThis defines initial behaviour which can be later changed using 'ImGui.ToggleGamepadInputSharing' command or\nmodule properties interface." },
};
#endif
void Z_Construct_UClass_UImGuiSettings_Statics::NewProp_bShareGamepadInput_SetBit(void* Obj)
{
((UImGuiSettings*)Obj)->bShareGamepadInput = 1;
}
const UE4CodeGen_Private::FBoolPropertyParams Z_Construct_UClass_UImGuiSettings_Statics::NewProp_bShareGamepadInput = { "bShareGamepadInput", nullptr, (EPropertyFlags)0x0020080000004001, UE4CodeGen_Private::EPropertyGenFlags::Bool | UE4CodeGen_Private::EPropertyGenFlags::NativeBool, RF_Public|RF_Transient|RF_MarkAsNative, 1, sizeof(bool), sizeof(UImGuiSettings), &Z_Construct_UClass_UImGuiSettings_Statics::NewProp_bShareGamepadInput_SetBit, METADATA_PARAMS(Z_Construct_UClass_UImGuiSettings_Statics::NewProp_bShareGamepadInput_MetaData, UE_ARRAY_COUNT(Z_Construct_UClass_UImGuiSettings_Statics::NewProp_bShareGamepadInput_MetaData)) };
#if WITH_METADATA
const UE4CodeGen_Private::FMetaDataPairParam Z_Construct_UClass_UImGuiSettings_Statics::NewProp_bShareMouseInput_MetaData[] = {
{ "Category", "Input" },
{ "Comment", "// Whether ImGui should share mouse input with game.\n// This defines initial behaviour which can be later changed using 'ImGui.ToggleMouseInputSharing' command or\n// module properties interface.\n" },
{ "ModuleRelativePath", "Private/ImGuiModuleSettings.h" },
{ "ToolTip", "Whether ImGui should share mouse input with game.\nThis defines initial behaviour which can be later changed using 'ImGui.ToggleMouseInputSharing' command or\nmodule properties interface." },
};
#endif
void Z_Construct_UClass_UImGuiSettings_Statics::NewProp_bShareMouseInput_SetBit(void* Obj)
{
((UImGuiSettings*)Obj)->bShareMouseInput = 1;
}
const UE4CodeGen_Private::FBoolPropertyParams Z_Construct_UClass_UImGuiSettings_Statics::NewProp_bShareMouseInput = { "bShareMouseInput", nullptr, (EPropertyFlags)0x0020080000004001, UE4CodeGen_Private::EPropertyGenFlags::Bool | UE4CodeGen_Private::EPropertyGenFlags::NativeBool, RF_Public|RF_Transient|RF_MarkAsNative, 1, sizeof(bool), sizeof(UImGuiSettings), &Z_Construct_UClass_UImGuiSettings_Statics::NewProp_bShareMouseInput_SetBit, METADATA_PARAMS(Z_Construct_UClass_UImGuiSettings_Statics::NewProp_bShareMouseInput_MetaData, UE_ARRAY_COUNT(Z_Construct_UClass_UImGuiSettings_Statics::NewProp_bShareMouseInput_MetaData)) };
#if WITH_METADATA
const UE4CodeGen_Private::FMetaDataPairParam Z_Construct_UClass_UImGuiSettings_Statics::NewProp_bUseSoftwareCursor_MetaData[] = {
{ "Category", "Input" },
{ "Comment", "// If true, then in input mode ImGui will draw its own cursor in place of the hardware one.\n// When disabled (default) there is a noticeable difference between cursor position seen by ImGui and position on\n// the screen. Enabling this option removes that effect but with lower frame-rates UI becomes quickly unusable.\n" },
{ "ModuleRelativePath", "Private/ImGuiModuleSettings.h" },
{ "ToolTip", "If true, then in input mode ImGui will draw its own cursor in place of the hardware one.\nWhen disabled (default) there is a noticeable difference between cursor position seen by ImGui and position on\nthe screen. Enabling this option removes that effect but with lower frame-rates UI becomes quickly unusable." },
};
#endif
void Z_Construct_UClass_UImGuiSettings_Statics::NewProp_bUseSoftwareCursor_SetBit(void* Obj)
{
((UImGuiSettings*)Obj)->bUseSoftwareCursor = 1;
}
const UE4CodeGen_Private::FBoolPropertyParams Z_Construct_UClass_UImGuiSettings_Statics::NewProp_bUseSoftwareCursor = { "bUseSoftwareCursor", nullptr, (EPropertyFlags)0x00200c0000004001, UE4CodeGen_Private::EPropertyGenFlags::Bool | UE4CodeGen_Private::EPropertyGenFlags::NativeBool, RF_Public|RF_Transient|RF_MarkAsNative, 1, sizeof(bool), sizeof(UImGuiSettings), &Z_Construct_UClass_UImGuiSettings_Statics::NewProp_bUseSoftwareCursor_SetBit, METADATA_PARAMS(Z_Construct_UClass_UImGuiSettings_Statics::NewProp_bUseSoftwareCursor_MetaData, UE_ARRAY_COUNT(Z_Construct_UClass_UImGuiSettings_Statics::NewProp_bUseSoftwareCursor_MetaData)) };
#if WITH_METADATA
const UE4CodeGen_Private::FMetaDataPairParam Z_Construct_UClass_UImGuiSettings_Statics::NewProp_ToggleInput_MetaData[] = {
{ "Category", "Keyboard Shortcuts" },
{ "Comment", "// Define a shortcut key to 'ImGui.ToggleInput' command. Binding is only set if the key field is valid.\n// Note that modifier key properties can be set to one of the three values: undetermined means that state of the given\n// modifier is not important, checked means that it needs to be pressed and unchecked means that it cannot be pressed.\n//\n// This binding is using Player Input's DebugExecBindings which only works in non-shipment builds.\n" },
{ "ModuleRelativePath", "Private/ImGuiModuleSettings.h" },
{ "ToolTip", "Define a shortcut key to 'ImGui.ToggleInput' command. Binding is only set if the key field is valid.\nNote that modifier key properties can be set to one of the three values: undetermined means that state of the given\nmodifier is not important, checked means that it needs to be pressed and unchecked means that it cannot be pressed.\n\nThis binding is using Player Input's DebugExecBindings which only works in non-shipment builds." },
};
#endif
const UE4CodeGen_Private::FStructPropertyParams Z_Construct_UClass_UImGuiSettings_Statics::NewProp_ToggleInput = { "ToggleInput", nullptr, (EPropertyFlags)0x0020080000004001, UE4CodeGen_Private::EPropertyGenFlags::Struct, RF_Public|RF_Transient|RF_MarkAsNative, 1, STRUCT_OFFSET(UImGuiSettings, ToggleInput), Z_Construct_UScriptStruct_FImGuiKeyInfo, METADATA_PARAMS(Z_Construct_UClass_UImGuiSettings_Statics::NewProp_ToggleInput_MetaData, UE_ARRAY_COUNT(Z_Construct_UClass_UImGuiSettings_Statics::NewProp_ToggleInput_MetaData)) };
#if WITH_METADATA
const UE4CodeGen_Private::FMetaDataPairParam Z_Construct_UClass_UImGuiSettings_Statics::NewProp_CanvasSize_MetaData[] = {
{ "Category", "Canvas Size" },
{ "Comment", "// Chose how to define the ImGui canvas size. Select between custom, desktop and viewport.\n" },
{ "ModuleRelativePath", "Private/ImGuiModuleSettings.h" },
{ "ToolTip", "Chose how to define the ImGui canvas size. Select between custom, desktop and viewport." },
};
#endif
const UE4CodeGen_Private::FStructPropertyParams Z_Construct_UClass_UImGuiSettings_Statics::NewProp_CanvasSize = { "CanvasSize", nullptr, (EPropertyFlags)0x0020080000004001, UE4CodeGen_Private::EPropertyGenFlags::Struct, RF_Public|RF_Transient|RF_MarkAsNative, 1, STRUCT_OFFSET(UImGuiSettings, CanvasSize), Z_Construct_UScriptStruct_FImGuiCanvasSizeInfo, METADATA_PARAMS(Z_Construct_UClass_UImGuiSettings_Statics::NewProp_CanvasSize_MetaData, UE_ARRAY_COUNT(Z_Construct_UClass_UImGuiSettings_Statics::NewProp_CanvasSize_MetaData)) };
#if WITH_METADATA
const UE4CodeGen_Private::FMetaDataPairParam Z_Construct_UClass_UImGuiSettings_Statics::NewProp_DPIScale_MetaData[] = {
{ "Category", "DPI Scale" },
{ "Comment", "// Setup DPI Scale.\n" },
{ "ModuleRelativePath", "Private/ImGuiModuleSettings.h" },
{ "ShowOnlyInnerProperties", "" },
{ "ToolTip", "Setup DPI Scale." },
};
#endif
const UE4CodeGen_Private::FStructPropertyParams Z_Construct_UClass_UImGuiSettings_Statics::NewProp_DPIScale = { "DPIScale", nullptr, (EPropertyFlags)0x0020080000004001, UE4CodeGen_Private::EPropertyGenFlags::Struct, RF_Public|RF_Transient|RF_MarkAsNative, 1, STRUCT_OFFSET(UImGuiSettings, DPIScale), Z_Construct_UScriptStruct_FImGuiDPIScaleInfo, METADATA_PARAMS(Z_Construct_UClass_UImGuiSettings_Statics::NewProp_DPIScale_MetaData, UE_ARRAY_COUNT(Z_Construct_UClass_UImGuiSettings_Statics::NewProp_DPIScale_MetaData)) };
const UE4CodeGen_Private::FPropertyParamsBase* const Z_Construct_UClass_UImGuiSettings_Statics::PropPointers[] = {
(const UE4CodeGen_Private::FPropertyParamsBase*)&Z_Construct_UClass_UImGuiSettings_Statics::NewProp_ImGuiInputHandlerClass,
(const UE4CodeGen_Private::FPropertyParamsBase*)&Z_Construct_UClass_UImGuiSettings_Statics::NewProp_bShareKeyboardInput,
(const UE4CodeGen_Private::FPropertyParamsBase*)&Z_Construct_UClass_UImGuiSettings_Statics::NewProp_bShareGamepadInput,
(const UE4CodeGen_Private::FPropertyParamsBase*)&Z_Construct_UClass_UImGuiSettings_Statics::NewProp_bShareMouseInput,
(const UE4CodeGen_Private::FPropertyParamsBase*)&Z_Construct_UClass_UImGuiSettings_Statics::NewProp_bUseSoftwareCursor,
(const UE4CodeGen_Private::FPropertyParamsBase*)&Z_Construct_UClass_UImGuiSettings_Statics::NewProp_ToggleInput,
(const UE4CodeGen_Private::FPropertyParamsBase*)&Z_Construct_UClass_UImGuiSettings_Statics::NewProp_CanvasSize,
(const UE4CodeGen_Private::FPropertyParamsBase*)&Z_Construct_UClass_UImGuiSettings_Statics::NewProp_DPIScale,
};
const FCppClassTypeInfoStatic Z_Construct_UClass_UImGuiSettings_Statics::StaticCppClassTypeInfo = {
TCppClassTypeTraits<UImGuiSettings>::IsAbstract,
};
const UE4CodeGen_Private::FClassParams Z_Construct_UClass_UImGuiSettings_Statics::ClassParams = {
&UImGuiSettings::StaticClass,
"ImGui",
&StaticCppClassTypeInfo,
DependentSingletons,
nullptr,
Z_Construct_UClass_UImGuiSettings_Statics::PropPointers,
nullptr,
UE_ARRAY_COUNT(DependentSingletons),
0,
UE_ARRAY_COUNT(Z_Construct_UClass_UImGuiSettings_Statics::PropPointers),
0,
0x000000A6u,
METADATA_PARAMS(Z_Construct_UClass_UImGuiSettings_Statics::Class_MetaDataParams, UE_ARRAY_COUNT(Z_Construct_UClass_UImGuiSettings_Statics::Class_MetaDataParams))
};
UClass* Z_Construct_UClass_UImGuiSettings()
{
static UClass* OuterClass = nullptr;
if (!OuterClass)
{
UE4CodeGen_Private::ConstructUClass(OuterClass, Z_Construct_UClass_UImGuiSettings_Statics::ClassParams);
}
return OuterClass;
}
IMPLEMENT_CLASS(UImGuiSettings, 4004534048);
template<> IMGUI_API UClass* StaticClass<UImGuiSettings>()
{
return UImGuiSettings::StaticClass();
}
static FCompiledInDefer Z_CompiledInDefer_UClass_UImGuiSettings(Z_Construct_UClass_UImGuiSettings, &UImGuiSettings::StaticClass, TEXT("/Script/ImGui"), TEXT("UImGuiSettings"), false, nullptr, nullptr, nullptr);
DEFINE_VTABLE_PTR_HELPER_CTOR(UImGuiSettings);
PRAGMA_ENABLE_DEPRECATION_WARNINGS
#ifdef _MSC_VER
#pragma warning (pop)
#endif

View File

@ -0,0 +1,149 @@
// Copyright Epic Games, Inc. All Rights Reserved.
/*===========================================================================
Generated code exported from UnrealHeaderTool.
DO NOT modify this manually! Edit the corresponding .h files instead!
===========================================================================*/
#include "UObject/ObjectMacros.h"
#include "UObject/ScriptMacros.h"
PRAGMA_DISABLE_DEPRECATION_WARNINGS
#ifdef IMGUI_ImGuiModuleSettings_generated_h
#error "ImGuiModuleSettings.generated.h already included, missing '#pragma once' in ImGuiModuleSettings.h"
#endif
#define IMGUI_ImGuiModuleSettings_generated_h
#define SwordNGun_Plugins_UnrealImGui_Source_ImGui_Private_ImGuiModuleSettings_h_117_GENERATED_BODY \
friend struct Z_Construct_UScriptStruct_FImGuiDPIScaleInfo_Statics; \
IMGUI_API static class UScriptStruct* StaticStruct(); \
FORCEINLINE static uint32 __PPO__ScalingMethod() { return STRUCT_OFFSET(FImGuiDPIScaleInfo, ScalingMethod); } \
FORCEINLINE static uint32 __PPO__Scale() { return STRUCT_OFFSET(FImGuiDPIScaleInfo, Scale); } \
FORCEINLINE static uint32 __PPO__DPICurve() { return STRUCT_OFFSET(FImGuiDPIScaleInfo, DPICurve); } \
FORCEINLINE static uint32 __PPO__bScaleWithCurve() { return STRUCT_OFFSET(FImGuiDPIScaleInfo, bScaleWithCurve); }
template<> IMGUI_API UScriptStruct* StaticStruct<struct FImGuiDPIScaleInfo>();
#define SwordNGun_Plugins_UnrealImGui_Source_ImGui_Private_ImGuiModuleSettings_h_77_GENERATED_BODY \
friend struct Z_Construct_UScriptStruct_FImGuiCanvasSizeInfo_Statics; \
IMGUI_API static class UScriptStruct* StaticStruct();
template<> IMGUI_API UScriptStruct* StaticStruct<struct FImGuiCanvasSizeInfo>();
#define SwordNGun_Plugins_UnrealImGui_Source_ImGui_Private_ImGuiModuleSettings_h_31_GENERATED_BODY \
friend struct Z_Construct_UScriptStruct_FImGuiKeyInfo_Statics; \
IMGUI_API static class UScriptStruct* StaticStruct();
template<> IMGUI_API UScriptStruct* StaticStruct<struct FImGuiKeyInfo>();
#define SwordNGun_Plugins_UnrealImGui_Source_ImGui_Private_ImGuiModuleSettings_h_161_SPARSE_DATA
#define SwordNGun_Plugins_UnrealImGui_Source_ImGui_Private_ImGuiModuleSettings_h_161_RPC_WRAPPERS
#define SwordNGun_Plugins_UnrealImGui_Source_ImGui_Private_ImGuiModuleSettings_h_161_RPC_WRAPPERS_NO_PURE_DECLS
#define SwordNGun_Plugins_UnrealImGui_Source_ImGui_Private_ImGuiModuleSettings_h_161_INCLASS_NO_PURE_DECLS \
private: \
static void StaticRegisterNativesUImGuiSettings(); \
friend struct Z_Construct_UClass_UImGuiSettings_Statics; \
public: \
DECLARE_CLASS(UImGuiSettings, UObject, COMPILED_IN_FLAGS(0 | CLASS_DefaultConfig | CLASS_Config), CASTCLASS_None, TEXT("/Script/ImGui"), NO_API) \
DECLARE_SERIALIZER(UImGuiSettings) \
static const TCHAR* StaticConfigName() {return TEXT("ImGui");} \
#define SwordNGun_Plugins_UnrealImGui_Source_ImGui_Private_ImGuiModuleSettings_h_161_INCLASS \
private: \
static void StaticRegisterNativesUImGuiSettings(); \
friend struct Z_Construct_UClass_UImGuiSettings_Statics; \
public: \
DECLARE_CLASS(UImGuiSettings, UObject, COMPILED_IN_FLAGS(0 | CLASS_DefaultConfig | CLASS_Config), CASTCLASS_None, TEXT("/Script/ImGui"), NO_API) \
DECLARE_SERIALIZER(UImGuiSettings) \
static const TCHAR* StaticConfigName() {return TEXT("ImGui");} \
#define SwordNGun_Plugins_UnrealImGui_Source_ImGui_Private_ImGuiModuleSettings_h_161_STANDARD_CONSTRUCTORS \
/** Standard constructor, called after all reflected properties have been initialized */ \
NO_API UImGuiSettings(const FObjectInitializer& ObjectInitializer = FObjectInitializer::Get()); \
DEFINE_DEFAULT_OBJECT_INITIALIZER_CONSTRUCTOR_CALL(UImGuiSettings) \
DECLARE_VTABLE_PTR_HELPER_CTOR(NO_API, UImGuiSettings); \
DEFINE_VTABLE_PTR_HELPER_CTOR_CALLER(UImGuiSettings); \
private: \
/** Private move- and copy-constructors, should never be used */ \
NO_API UImGuiSettings(UImGuiSettings&&); \
NO_API UImGuiSettings(const UImGuiSettings&); \
public:
#define SwordNGun_Plugins_UnrealImGui_Source_ImGui_Private_ImGuiModuleSettings_h_161_ENHANCED_CONSTRUCTORS \
/** Standard constructor, called after all reflected properties have been initialized */ \
NO_API UImGuiSettings(const FObjectInitializer& ObjectInitializer = FObjectInitializer::Get()) : Super(ObjectInitializer) { }; \
private: \
/** Private move- and copy-constructors, should never be used */ \
NO_API UImGuiSettings(UImGuiSettings&&); \
NO_API UImGuiSettings(const UImGuiSettings&); \
public: \
DECLARE_VTABLE_PTR_HELPER_CTOR(NO_API, UImGuiSettings); \
DEFINE_VTABLE_PTR_HELPER_CTOR_CALLER(UImGuiSettings); \
DEFINE_DEFAULT_OBJECT_INITIALIZER_CONSTRUCTOR_CALL(UImGuiSettings)
#define SwordNGun_Plugins_UnrealImGui_Source_ImGui_Private_ImGuiModuleSettings_h_161_PRIVATE_PROPERTY_OFFSET \
FORCEINLINE static uint32 __PPO__ImGuiInputHandlerClass() { return STRUCT_OFFSET(UImGuiSettings, ImGuiInputHandlerClass); } \
FORCEINLINE static uint32 __PPO__bShareKeyboardInput() { return STRUCT_OFFSET(UImGuiSettings, bShareKeyboardInput); } \
FORCEINLINE static uint32 __PPO__bShareGamepadInput() { return STRUCT_OFFSET(UImGuiSettings, bShareGamepadInput); } \
FORCEINLINE static uint32 __PPO__bShareMouseInput() { return STRUCT_OFFSET(UImGuiSettings, bShareMouseInput); } \
FORCEINLINE static uint32 __PPO__bUseSoftwareCursor() { return STRUCT_OFFSET(UImGuiSettings, bUseSoftwareCursor); } \
FORCEINLINE static uint32 __PPO__ToggleInput() { return STRUCT_OFFSET(UImGuiSettings, ToggleInput); } \
FORCEINLINE static uint32 __PPO__CanvasSize() { return STRUCT_OFFSET(UImGuiSettings, CanvasSize); } \
FORCEINLINE static uint32 __PPO__DPIScale() { return STRUCT_OFFSET(UImGuiSettings, DPIScale); }
#define SwordNGun_Plugins_UnrealImGui_Source_ImGui_Private_ImGuiModuleSettings_h_158_PROLOG
#define SwordNGun_Plugins_UnrealImGui_Source_ImGui_Private_ImGuiModuleSettings_h_161_GENERATED_BODY_LEGACY \
PRAGMA_DISABLE_DEPRECATION_WARNINGS \
public: \
SwordNGun_Plugins_UnrealImGui_Source_ImGui_Private_ImGuiModuleSettings_h_161_PRIVATE_PROPERTY_OFFSET \
SwordNGun_Plugins_UnrealImGui_Source_ImGui_Private_ImGuiModuleSettings_h_161_SPARSE_DATA \
SwordNGun_Plugins_UnrealImGui_Source_ImGui_Private_ImGuiModuleSettings_h_161_RPC_WRAPPERS \
SwordNGun_Plugins_UnrealImGui_Source_ImGui_Private_ImGuiModuleSettings_h_161_INCLASS \
SwordNGun_Plugins_UnrealImGui_Source_ImGui_Private_ImGuiModuleSettings_h_161_STANDARD_CONSTRUCTORS \
public: \
PRAGMA_ENABLE_DEPRECATION_WARNINGS
#define SwordNGun_Plugins_UnrealImGui_Source_ImGui_Private_ImGuiModuleSettings_h_161_GENERATED_BODY \
PRAGMA_DISABLE_DEPRECATION_WARNINGS \
public: \
SwordNGun_Plugins_UnrealImGui_Source_ImGui_Private_ImGuiModuleSettings_h_161_PRIVATE_PROPERTY_OFFSET \
SwordNGun_Plugins_UnrealImGui_Source_ImGui_Private_ImGuiModuleSettings_h_161_SPARSE_DATA \
SwordNGun_Plugins_UnrealImGui_Source_ImGui_Private_ImGuiModuleSettings_h_161_RPC_WRAPPERS_NO_PURE_DECLS \
SwordNGun_Plugins_UnrealImGui_Source_ImGui_Private_ImGuiModuleSettings_h_161_INCLASS_NO_PURE_DECLS \
SwordNGun_Plugins_UnrealImGui_Source_ImGui_Private_ImGuiModuleSettings_h_161_ENHANCED_CONSTRUCTORS \
private: \
PRAGMA_ENABLE_DEPRECATION_WARNINGS
template<> IMGUI_API UClass* StaticClass<class UImGuiSettings>();
#undef CURRENT_FILE_ID
#define CURRENT_FILE_ID SwordNGun_Plugins_UnrealImGui_Source_ImGui_Private_ImGuiModuleSettings_h
#define FOREACH_ENUM_EIMGUIDPISCALEMETHOD(op) \
op(EImGuiDPIScaleMethod::ImGui) \
op(EImGuiDPIScaleMethod::Slate)
enum class EImGuiDPIScaleMethod : uint8;
template<> IMGUI_API UEnum* StaticEnum<EImGuiDPIScaleMethod>();
#define FOREACH_ENUM_EIMGUICANVASSIZETYPE(op) \
op(EImGuiCanvasSizeType::Custom) \
op(EImGuiCanvasSizeType::Desktop) \
op(EImGuiCanvasSizeType::Viewport)
enum class EImGuiCanvasSizeType : uint8;
template<> IMGUI_API UEnum* StaticEnum<EImGuiCanvasSizeType>();
PRAGMA_ENABLE_DEPRECATION_WARNINGS

View File

@ -0,0 +1,2 @@
Z:\Projects\Unreal\SwordNGun\SwordNGun\Plugins\UnrealImGui\Source\ImGui\Public\ImGuiInputHandler.h
Z:\Projects\Unreal\SwordNGun\SwordNGun\Plugins\UnrealImGui\Source\ImGui\Private\ImGuiModuleSettings.h

View File

@ -0,0 +1,21 @@
The MIT License (MIT)
Copyright (c) 2017-2021 Sebastian Gross
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

View File

@ -0,0 +1,297 @@
Unreal ImGui
============
[![MIT licensed](https://img.shields.io/badge/license-MIT-blue.svg)](LICENSE.md)
Unreal ImGui is an Unreal Engine 4 plug-in that integrates [Dear ImGui](https://github.com/ocornut/imgui) developed by Omar Cornut.
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.
Status
------
Version: 1.22
ImGui version: 1.74
Supported engine version: 4.26*
\* *Plugin has been tested and if necessary updated to compile and work with this engine version. As long as possible I will try to maintain backward compatibility of existing features and possibly but not necessarily when adding new features. When it comes to bare-bone ImGui version it should be at least backward compatible with the engine version 4.15. For NetImgui it needs to be determined.*
Current work
------------
Currently, I'm a little busy outside of this project so changes come slowly. But here is what to expect in the reasonably near future:
- Stability first, so fixes for more critical issues like an invalidation of handles after reloading texture resources will be pushed first. The same goes for merges.
- There are a few smaller issues that I'm aware of and that might be not reported but which I want to fix.
- ImGui needs to be updated.
- Smaller features might be slowly pushed but bigger ones will need to wait. The same goes for merges.
- There is a branch with NetImgui which is really good, and which will be eventually merged to master, but first I want to fix a few issues that I know about (some are discussed in thread #28). In the meantime, the NetImgui branch is pretty much ready to use.
About
-----
The main goal of this plugin is to provide a basic integration of the Dear ImGui which will be easy to use from the game code.
My main focus used to be on debugging and for that this plugin should work out of the box. It is possible to use it for different purposes but depending on the use case it may require some adaptations.
To support multi-PIE, each world gets its own ImGui context to which it can draw. All that is managed by the plugin in a way that should be invisible for the game code. I plan to extend it to allow own contexts and widgets but right now I don't have enough time to commit to that.
As of recently, the plugin has the *net_imgui* branch with an integration of the [NetImgui](https://github.com/sammyfreg/netImgui) developed by Sammyfreg. This is still experimental, but it is possible to already download and use it. Many thanks for the library and for the initial integration.
### Key features
- Multi-PIE support with each world getting its own ImGui context.
- Automatic switching between different ImGui contexts.
- Delegates for functions with ImGui content.
- Support for Unreal textures.
How to Set up
-------------
To use this plug-in, you will need a C++ Unreal project.
### Installation
Content of this repository needs to be placed in the *Plugins* directory under the project root: *[Project Root]/Plugins/ImGui/*. After you compile and run you should notice that *ImGui* module is now available.
Note that plugins can be also placed in the engine directory *[UE4 Root]/Engine/Plugins/* but I didn't try it with this project.
If you want to use NetImgui, instead of please look at the [How to Set up NetImgui](#how-to-set-up-netimgui).
### Setting module type
The *ImGui* module type is set to **Developer**, what means that if it is not referenced by other runtime modules, it can be automatically excluded from shipping builds. This is convenient when using this plugging for debugging but if you want to change it to other type, you can do it in module description section in `ImGui.uplugin` file.
**Developer** type was depreciated in UE 4.24. I keep it for backward compatibility while I can, but if you get a UBT warning about module type, simply change it to **DeveloperTool** or **Runtime**.
### Setting up module dependencies
To use ImGui in other modules you need to add it as a private or public dependency in their Build.cs files:
```C#
PrivateDependencyModuleNames.Add("ImGui");
```
or
```C#
PublicDependencyModuleNames.Add("ImGui");
```
You might also want to use ImGui only in certain builds:
```C#
if (Target.Configuration != UnrealTargetConfiguration.Shipping)
{
PrivateDependencyModuleNames.Add("ImGui");
}
```
### Conditional compilation
You can conditionally compile ImGui code by checking `IMGUI_API`:
```C++
#ifded IMGUI_API
#include <imgui.h>
#endif
// ... somewhere in your code
#ifded IMGUI_API
// ImGui code
#endif
```
Above code is fine but it requires wrapping include directives and does not follow the usual pattern used in Unreal. To improve that, you can add the following code to one of your headers (or a precompiled header, if you use one):
```C++
// ImGuiCommon.h
#pragma once
#ifdef IMGUI_API
#define WITH_IMGUI 1
#else
#define WITH_IMGUI 0
#endif // IMGUI_API
#if WITH_IMGUI
#include <imgui.h>
#endif // WITH_IMGUI
```
And then use it like this:
```C++
#include "ImGuiCommon.h"
// ... somewhere in your code
#if WITH_IMGUI
// ImGui code
#endif
```
How to Set up NetImgui
----------------------
To use NetImgui, use content of the *net_imgui* branch in place of *master*. This will be gradually merged into the *master* but until then you need to use that experimental branch.
Similarly like ImGui, NetImgui is built as part of the UnrealImGui plugin and no other integration steps are required.
To be able to connect to the Unreal editor or application that use NetImgui, you need to run a server (netImguiServer). Please, see the [NetImgui](https://github.com/sammyfreg/netImgui) page for instructions how to get it.
After launching the server for the first time, you need to add two client configurations, for ports 8889 and 8890. After that, you can either initialise connection from the server or set it to autoconnection mode. More info will be added later.
Once you establish connection, you can use a top bar to switch between contexts and modes. In standalone game it should be one context and in the editor one editor context, plus one for each PIE instance.
Please, note that all those features are experimental and might evolve. Any input is welcomed.
How to use it
-------------
### Using ImGui in code
ImGui can be used from functions registered as ImGui delegates or directly in game code. However, if code is running outside of the game thread or is executed outside of the world update scope, delegates are a better choice.
Delegates have an additional advantage that their content will work also when game is paused.
### ImGui Delegates
To use ImGui delegates, include `ImGuiDelegates.h`.
There are two major types of ImGui delegates: world and multi-context. First are created on demand for every world and are cleared once that world becomes invalid. They are designed to be used primarily by worlds objects. In opposition, multi-context delegates are called for every updated world, so the same code can be called multiple times per frame but in different contexts.
Delegates are called typically during world post actor tick event but they have alternative versions called during world tick start. In engine versions that does not support world post actor tick, that is below 4.18, all delegates are called during world tick start.
Delegates are called in order that allows multi-context delegates to add content before and after world objects:
- multi-context early debug
- world early debug
- world update
- world debug
- multi-context debug.
> `FImGuiModule` has delegates interface but it is depreciated and will be removed soon. Major issue with that interface is that it needs a module instance, what can be a problem when trying to register static objects. Additional issue is a requirement to always unregister with a handle.
### Multi-context
In multi-PIE sessions each world gets its own ImGui context which is selected at the beginning of the world update. All that happens in the background and should allow debug code to stay context agnostic.
If your content is rendered in the wrong context, try using one of the [ImGui delegates](#imgui-delegates) that should be always called after the right context is already set in ImGui.
### Using Unreal textures
Unreal ImGui allows to register textures in order to use them in ImGui. To do that, include `ImGuiModule.h` and use `FImGuiModule` interface.
After registration you will get a texture handle, declared in `ImGuiTextureHandle.h`, that you need to pass to the ImGui API.
```C++
// Texture handle defined like this
FImGuiTextureHandle TextureHandle;
// Registration and update
TextureHandle = FImGuiModule::Get().RegisterTexture("TextureName", Texture);
// Release
FImGuiModule::Get().ReleaseTexture(TextureHandle);
// Find by name
TextureHandle = FImGuiModule::Get().FindTextureHandle("TextureName");
// Example of usage (it is implicitly converted to ImTextureID)
ImGui::Image(TextureHandle, Size);
```
### Input mode
Right after the start ImGui will work in render-only mode. To interact with it, you need to activate input mode either by changing `Input Enabled` [property](#properties) from code, using `ImGui.ToggleInput` [command](#console-commands) or with a [keyboard shortcut](#keyboard-shortcuts).
#### Sharing input
It is possible to enable input sharing features to pass keyboard, gamepad or mouse events to the game. Note, that the original design assumed that plugin should consume all input to isolate debug from game. While sharing keyboard or gamepad is pretty straightforward and works by passing input events to the viewport, mouse sharing works in a bit different way. Since the ImGui widget overlays the whole viewport, widget needs to switch hit visibility and update position in the background. It might be possible to generate a custom collision geometry matching ImGui and simplifying working with mouse and touch inputs, but I don't plan to work on this right now.
The default behaviour can be configured in [input settings](#input) and changed during runtime by modifying `Keyboard Input Shared`, `Gamepad Input Shared` and `Mouse Input Shared` [properties](#properties) or `ImGui.ToggleKeyboardInputSharing`, `ImGui.ToggleGamepadInputSharing` and `ImGui.ToggleMouseInputSharing` [commands](#console-commands).
#### Keyboard and gamepad navigation
When using ImGui on consoles you most probably need to enable keyboard and/or gamepad navigaiton. Both are ImGui features that allow to use it without mouse. See ImGui documentation for more details.
You can toggle those features by changing `Keyboard Navigation` and `Gamepad Navigation` [properties](#properties) or using `ImGui.ToggleKeyboardNavigation`and `ImGui.ToggleGamepadNavigation` [commands](#console-commands).
#### Navigating around ImGui canvas
Most of the time ImGui canvas will be larger from the viewport. When ImGui is in the input mode, it is possible to change which part of the canvas should be visible on the screen. To do that press and hold `Left Shift` + `Left Alt` and use mouse to adjust.
- `Mouse Wheel` - Zoom in or out.
- `Right Mouse Button` - Drag canvas with ImGui content.
- `Middle Mouse Button` - Drag frame representing which part of the canvas will be visible after ending the navigation mode.
The orange rectangle represents a scaled viewport and the area that will be visible on the screen after releasing keys. Zooming will scale that box and dragging with the middle mouse button will move everything.
The black rectangle represents a canvas border. You can drag canvas using the right mouse button. Dragging canvas will add a render offset between ImGui content and the viewport.
> Image(s) needed.
### Properties
ImGui module has a set of properties that allow to modify its behaviour:
- `Input Enabled` - Whether ImGui should receive [input](#input-mode). It is possible to assign a [keyboard shortcut](#keyboard-shortcuts) to toggle this property.
- `Keyboard Navigation`- Whether ImGui [keyboard navigation feature](#keyboard-and-gamepad-navigation) is enabled.
- `Gamepad Navigation` - Whether ImGui [gamepad navigation feature](#keyboard-and-gamepad-navigation) is enabled.
- `Keyboard Input Shared` - Whether keyboard input should be [shared with the game](#sharing-input). Default behaviour can be configured in [input settings](#input).
- `Gamepad Input Shared` - Whether gamepad input should be [shared with the game](#sharing-input). Default behaviour can be configured in [input settings](#input).
- `Mouse Input Shared` - Whether mouse input should be [shared with the game](#sharing-input). Default behaviour can be configured in [input settings](#input).
- `Show Demo` - Whether to show ImGui demo.
All properties can be changed by corresponding [console commands](#console-commands) or from code.
You can get properties interface through the module instance:
```C++
FImGuiModule::Get().GetProperties();
```
### Console commands
- `ImGui.ToggleInput` - Toggle ImGui input mode. It is possible to assign a [keyboard shortcut](#keyboard-shortcuts) to this command.
- `ImGui.ToggleKeyboardNavigation` - Toggle ImGui keyboard navigation.
- `ImGui.ToggleGamepadNavigation` - Toggle ImGui gamepad navigation.
- `ImGui.ToggleKeyboardInputSharing` - Toggle ImGui keyboard input sharing.
- `ImGui.ToggleGamepadInputSharing` - Toggle ImGui gamepad input sharing.
- `ImGui.ToggleMouseInputSharing` - Toggle ImGui mouse input sharing.
- `ImGui.ToggleDemo` - Toggle ImGui demo.
### Console debug variables
There is a self-debug functionality build into this plugin. This is hidden by default as it is hardly useful outside of this pluguin. To enable it, go to `ImGuiModuleDebug.h` and change `IMGUI_MODULE_DEVELOPER`.
- `ImGui.Debug.Widget` - Show debug for SImGuiWidget.
- `ImGui.Debug.Input` - Show debug for input state.
### Settings
Plugin settings can be found in *Project Settings/Plugins/ImGui* panel. There is a bunch of properties allowing to tweak input handling, keyboard shortcuts (one for now), canvas size and DPI scale.
##### Extensions
- `ImGui Input Handler Class` - Path to own implementation of ImGui Input Handler that allows limited customization of the input handling. If not set, then the default implementation is used.
>*If you decide to implement an own handler, please keep in mind that I'm thinking about replacing it.*
##### Input
- `Share Keyboard Input` - Whether by default, ImGui should [share with game](#sharing-input) keyboard input.
- `Share Gamepad Input` - Whether by default, ImGui should [share with game](#sharing-input) gamepad input.
- `Share Mouse Input` - Whether by default, ImGui should [share with game](#sharing-input) mouse input.
- `Use Software Cursor` - Whether ImGui should draw its own cursor in place of the hardware one.
##### Keyboard shortcuts
- `Toggle Input` - Allows to define a shortcut key to a command that toggles the input mode. Note that this is using `DebugExecBindings` which is not available in shipping builds.
See also
--------
- [Dear ImGui](https://github.com/ocornut/imgui)
- [An Introduction to UE4 Plugins](https://wiki.unrealengine.com/An_Introduction_to_UE4_Plugins).
License
-------
Unreal ImGui is licensed under the MIT License, see LICENSE for more information.

BIN
SwordNGun/Plugins/UnrealImGui/Resources/Icon128.png (Stored with Git LFS) Normal file

Binary file not shown.

View File

@ -0,0 +1,101 @@
// Distributed under the MIT License (MIT) (see accompanying LICENSE file)
using System.Collections.Generic;
using System.IO;
using UnrealBuildTool;
public class ImGui : ModuleRules
{
#if WITH_FORWARDED_MODULE_RULES_CTOR
public ImGui(ReadOnlyTargetRules Target) : base(Target)
#else
public ImGui(TargetInfo Target)
#endif
{
#if WITH_FORWARDED_MODULE_RULES_CTOR
bool bBuildEditor = Target.bBuildEditor;
#else
bool bBuildEditor = (Target.Type == TargetRules.TargetType.Editor);
#endif
// Developer modules are automatically loaded only in editor builds but can be stripped out from other builds.
// Enable runtime loader, if you want this module to be automatically loaded in runtime builds (monolithic).
bool bEnableRuntimeLoader = true;
PCHUsage = PCHUsageMode.UseExplicitOrSharedPCHs;
#if UE_4_24_OR_LATER
bLegacyPublicIncludePaths = false;
ShadowVariableWarningLevel = WarningLevel.Error;
bTreatAsEngineModule = true;
#endif
PublicIncludePaths.AddRange(
new string[] {
Path.Combine(ModuleDirectory, "../ThirdParty/ImGuiLibrary/Include")
// ... add public include paths required here ...
}
);
PrivateIncludePaths.AddRange(
new string[] {
"ImGui/Private",
"ThirdParty/ImGuiLibrary/Private"
// ... add other private include paths required here ...
}
);
PublicDependencyModuleNames.AddRange(
new string[]
{
"Core",
"Projects"
// ... add other public dependencies that you statically link with here ...
}
);
PrivateDependencyModuleNames.AddRange(
new string[]
{
"CoreUObject",
"Engine",
"InputCore",
"Slate",
"SlateCore"
// ... add private dependencies that you statically link with here ...
}
);
if (bBuildEditor)
{
PrivateDependencyModuleNames.AddRange(
new string[]
{
"EditorStyle",
"Settings",
"UnrealEd",
}
);
}
DynamicallyLoadedModuleNames.AddRange(
new string[]
{
// ... add any modules that your module loads dynamically here ...
}
);
#if !UE_4_19_OR_LATER
List<string> PrivateDefinitions = Definitions;
#endif
PrivateDefinitions.Add(string.Format("RUNTIME_LOADER_ENABLED={0}", bEnableRuntimeLoader ? 1 : 0));
}
}

View File

@ -0,0 +1,158 @@
// Distributed under the MIT License (MIT) (see accompanying LICENSE file)
#include "ImGuiCanvasSizeInfoCustomization.h"
#if WITH_EDITOR
#include "ImGuiModuleSettings.h"
#include <PropertyCustomizationHelpers.h>
#define LOCTEXT_NAMESPACE "ImGuiEditor"
namespace
{
EImGuiCanvasSizeType GetCanvasSizeTypeEnumValue(const TSharedPtr<IPropertyHandle>& TypeHandle)
{
uint8 ValueAsByte = 0;
if (TypeHandle.IsValid())
{
TypeHandle->GetValue(ValueAsByte);
}
return static_cast<EImGuiCanvasSizeType>(ValueAsByte);
}
bool IsAny(const TSharedPtr<IPropertyHandle>& TypeHandle, EImGuiCanvasSizeType Value)
{
return GetCanvasSizeTypeEnumValue(TypeHandle) == Value;
}
template<typename... TRest>
bool IsAny(const TSharedPtr<IPropertyHandle>& TypeHandle, EImGuiCanvasSizeType First, TRest... Rest)
{
return IsAny(TypeHandle, First) || IsAny(TypeHandle, Rest...);
}
float ShowToHeight(bool bShow)
{
return bShow ? 0.f /* Infinity */ : SMALL_NUMBER;
}
EVisibility ShowToVisibility(bool bShow)
{
return bShow ? EVisibility::SelfHitTestInvisible : EVisibility::Hidden;
}
}
//----------------------------------------------------------------------------------------------------
// FImGuiKeyInfoCustomization implementation
//----------------------------------------------------------------------------------------------------
TSharedRef<IPropertyTypeCustomization> FImGuiCanvasSizeInfoCustomization::MakeInstance()
{
return MakeShareable(new FImGuiCanvasSizeInfoCustomization);
}
void FImGuiCanvasSizeInfoCustomization::CustomizeHeader(TSharedRef<IPropertyHandle> InStructPropertyHandle, FDetailWidgetRow& HeaderRow, IPropertyTypeCustomizationUtils& StructCustomizationUtils)
{
TSharedPtr<IPropertyHandle> TypeHandle = InStructPropertyHandle->GetChildHandle(GET_MEMBER_NAME_CHECKED(FImGuiCanvasSizeInfo, SizeType));
TSharedPtr<IPropertyHandle> WidthHandle = InStructPropertyHandle->GetChildHandle(GET_MEMBER_NAME_CHECKED(FImGuiCanvasSizeInfo, Width));
TSharedPtr<IPropertyHandle> HeightHandle = InStructPropertyHandle->GetChildHandle(GET_MEMBER_NAME_CHECKED(FImGuiCanvasSizeInfo, Height));
TSharedPtr<IPropertyHandle> ExtendToViewportHandle = InStructPropertyHandle->GetChildHandle(GET_MEMBER_NAME_CHECKED(FImGuiCanvasSizeInfo, bExtendToViewport));
#define ADD_DIMENSION_SLOT(Handle, LPadding) \
+ SHorizontalBox::Slot()\
.Padding(LPadding, 0.f, 0.f, 0.f)\
.HAlign(HAlign_Fill)\
.MaxWidth(80.f)\
[\
SNew(SVerticalBox)\
+ SVerticalBox::Slot()\
.AutoHeight()\
[\
Handle->CreatePropertyNameWidget()\
]\
+ SVerticalBox::Slot()\
.HAlign(HAlign_Fill)\
.AutoHeight()\
[\
Handle->CreatePropertyValueWidget()\
]\
]
auto SizeRowHeight = TAttribute<float>::Create([TypeHandle]()
{
return ShowToHeight(IsAny(TypeHandle, EImGuiCanvasSizeType::Custom));
});
auto SizeRowVisibility = TAttribute<EVisibility>::Create([TypeHandle]()
{
return ShowToVisibility(IsAny(TypeHandle, EImGuiCanvasSizeType::Custom));
});
auto ExtendRowHeight = TAttribute<float>::Create([TypeHandle]()
{
return ShowToHeight(IsAny(TypeHandle, EImGuiCanvasSizeType::Custom, EImGuiCanvasSizeType::Desktop));
});
auto ExtendRowVisibility = TAttribute<EVisibility>::Create([TypeHandle]()
{
return ShowToVisibility(IsAny(TypeHandle, EImGuiCanvasSizeType::Custom, EImGuiCanvasSizeType::Desktop));
});
HeaderRow
.NameContent()
[
InStructPropertyHandle->CreatePropertyNameWidget()
]
.ValueContent()
.MinDesiredWidth(168.f)
[
SNew(SVerticalBox)
+ SVerticalBox::Slot()
.AutoHeight()
[
TypeHandle->CreatePropertyValueWidget()
]
+ SVerticalBox::Slot()
.AutoHeight()
.MaxHeight(SizeRowHeight)
[
SNew(SHorizontalBox)
.Visibility(SizeRowVisibility)
ADD_DIMENSION_SLOT(WidthHandle, 0.f)
ADD_DIMENSION_SLOT(HeightHandle, 6.f)
]
+ SVerticalBox::Slot()
.AutoHeight()
.MaxHeight(ExtendRowHeight)
[
SNew(SHorizontalBox)
.Visibility(ExtendRowVisibility)
+ SHorizontalBox::Slot()
.AutoWidth()
[
ExtendToViewportHandle->CreatePropertyValueWidget()
]
+ SHorizontalBox::Slot()
.Padding(4.f, 0.f, 0.f, 0.f)
.AutoWidth()
[
ExtendToViewportHandle->CreatePropertyNameWidget()
]
]
];
#undef ADD_DIMENSION_SLOT
}
void FImGuiCanvasSizeInfoCustomization::CustomizeChildren(TSharedRef<IPropertyHandle> InStructPropertyHandle, IDetailChildrenBuilder& StructBuilder, IPropertyTypeCustomizationUtils& StructCustomizationUtils)
{
}
#undef LOCTEXT_NAMESPACE
#endif // WITH_EDITOR

View File

@ -0,0 +1,22 @@
// Copyright 1998-2018 Epic Games, Inc. All Rights Reserved.
#pragma once
#if WITH_EDITOR
#include <IPropertyTypeCustomization.h>
#include <PropertyHandle.h>
// Property type customization for FImGuiCanvasSizeInfo.
class FImGuiCanvasSizeInfoCustomization : public IPropertyTypeCustomization
{
public:
static TSharedRef<IPropertyTypeCustomization> MakeInstance();
// IPropertyTypeCustomization interface
virtual void CustomizeHeader(TSharedRef<IPropertyHandle> InStructPropertyHandle, FDetailWidgetRow& HeaderRow, IPropertyTypeCustomizationUtils& StructCustomizationUtils) override;
virtual void CustomizeChildren(TSharedRef<IPropertyHandle> InStructPropertyHandle, IDetailChildrenBuilder& StructBuilder, IPropertyTypeCustomizationUtils& StructCustomizationUtils) override;
};
#endif // WITH_EDITOR

View File

@ -0,0 +1,136 @@
// Distributed under the MIT License (MIT) (see accompanying LICENSE file)
#include "ImGuiEditor.h"
#if WITH_EDITOR
#include "ImGuiCanvasSizeInfoCustomization.h"
#include "ImGuiKeyInfoCustomization.h"
#include "ImGuiModuleSettings.h"
#include <ISettingsModule.h>
#include <Modules/ModuleManager.h>
#define LOCTEXT_NAMESPACE "ImGuiEditor"
#define SETTINGS_CONTAINER TEXT("Project"), TEXT("Plugins"), TEXT("ImGui")
namespace
{
ISettingsModule* GetSettingsModule()
{
return FModuleManager::GetModulePtr<ISettingsModule>("Settings");
}
FPropertyEditorModule* GetPropertyEditorModule()
{
return FModuleManager::GetModulePtr<FPropertyEditorModule>("PropertyEditor");
}
}
FImGuiEditor::FImGuiEditor()
{
Register();
// As a side effect of being part of the ImGui module, we need to support deferred registration (only executed if
// module is loaded manually at the very early stage).
if (!IsRegistrationCompleted())
{
CreateRegistrator();
}
}
FImGuiEditor::~FImGuiEditor()
{
Unregister();
}
void FImGuiEditor::Register()
{
// Only register after UImGuiSettings class is initialized (necessary to check in early loading stages).
if (!bSettingsRegistered && UImGuiSettings::Get())
{
if (ISettingsModule* SettingsModule = GetSettingsModule())
{
bSettingsRegistered = true;
SettingsModule->RegisterSettings(SETTINGS_CONTAINER,
LOCTEXT("ImGuiSettingsName", "ImGui"),
LOCTEXT("ImGuiSettingsDescription", "Configure the Unreal ImGui plugin."),
UImGuiSettings::Get());
}
}
if (!bCustomPropertyTypeLayoutsRegistered)
{
if (FPropertyEditorModule* PropertyModule = GetPropertyEditorModule())
{
bCustomPropertyTypeLayoutsRegistered = true;
PropertyModule->RegisterCustomPropertyTypeLayout("ImGuiCanvasSizeInfo",
FOnGetPropertyTypeCustomizationInstance::CreateStatic(&FImGuiCanvasSizeInfoCustomization::MakeInstance));
PropertyModule->RegisterCustomPropertyTypeLayout("ImGuiKeyInfo",
FOnGetPropertyTypeCustomizationInstance::CreateStatic(&FImGuiKeyInfoCustomization::MakeInstance));
}
}
}
void FImGuiEditor::Unregister()
{
if (bSettingsRegistered)
{
bSettingsRegistered = false;
if (ISettingsModule* SettingsModule = GetSettingsModule())
{
SettingsModule->UnregisterSettings(SETTINGS_CONTAINER);
}
}
if (bCustomPropertyTypeLayoutsRegistered)
{
bCustomPropertyTypeLayoutsRegistered = false;
if (FPropertyEditorModule* PropertyModule = GetPropertyEditorModule())
{
PropertyModule->UnregisterCustomPropertyTypeLayout("ImGuiCanvasSizeInfo");
PropertyModule->UnregisterCustomPropertyTypeLayout("ImGuiKeyInfo");
}
}
}
void FImGuiEditor::CreateRegistrator()
{
if (!RegistratorHandle.IsValid())
{
RegistratorHandle = FModuleManager::Get().OnModulesChanged().AddLambda([this](FName Name, EModuleChangeReason Reason)
{
if (Reason == EModuleChangeReason::ModuleLoaded)
{
Register();
}
if (IsRegistrationCompleted())
{
ReleaseRegistrator();
}
});
}
}
void FImGuiEditor::ReleaseRegistrator()
{
if (RegistratorHandle.IsValid())
{
FModuleManager::Get().OnModulesChanged().Remove(RegistratorHandle);
RegistratorHandle.Reset();
}
}
#undef SETTINGS_CONTAINER
#undef LOCTEXT_NAMESPACE
#endif // WITH_EDITOR

View File

@ -0,0 +1,34 @@
// Copyright 1998-2018 Epic Games, Inc. All Rights Reserved.
#pragma once
#if WITH_EDITOR
#include <Delegates/IDelegateInstance.h>
// Registers module's settings in editor (due to a small size of this code we don't use a separate editor module).
class FImGuiEditor
{
public:
FImGuiEditor();
~FImGuiEditor();
private:
bool IsRegistrationCompleted() const { return bSettingsRegistered && bCustomPropertyTypeLayoutsRegistered; }
void Register();
void Unregister();
void CreateRegistrator();
void ReleaseRegistrator();
FDelegateHandle RegistratorHandle;
bool bSettingsRegistered = false;
bool bCustomPropertyTypeLayoutsRegistered = false;
};
#endif // WITH_EDITOR

View File

@ -0,0 +1,209 @@
// Distributed under the MIT License (MIT) (see accompanying LICENSE file)
#include "ImGuiKeyInfoCustomization.h"
#if WITH_EDITOR
#include "ImGuiModuleSettings.h"
#include <PropertyCustomizationHelpers.h>
#include <SKeySelector.h>
#include <Widgets/SCompoundWidget.h>
#include <Widgets/Input/SCheckBox.h>
#define LOCTEXT_NAMESPACE "ImGuiEditor"
//----------------------------------------------------------------------------------------------------
// Helper widgets
//----------------------------------------------------------------------------------------------------
namespace
{
class SPropertyKeySelector : public SCompoundWidget
{
public:
SLATE_BEGIN_ARGS(SPropertyKeySelector)
{}
SLATE_ARGUMENT(TSharedPtr<IPropertyHandle>, KeyHandle)
SLATE_ATTRIBUTE(FSlateFontInfo, Font)
SLATE_END_ARGS()
void Construct(const FArguments& InArgs)
{
KeyHandle = InArgs._KeyHandle;
ChildSlot
[
SNew(SKeySelector)
.CurrentKey(this, &SPropertyKeySelector::GetCurrentKey)
.OnKeyChanged(this, &SPropertyKeySelector::OnKeyChanged)
.Font(InArgs._Font)
];
}
TOptional<FKey> GetCurrentKey() const
{
TArray<void*> RawPtrs;
KeyHandle->AccessRawData(RawPtrs);
if (RawPtrs.Num())
{
FKey* KeyPtr = static_cast<FKey*>(RawPtrs[0]);
if (KeyPtr)
{
for (int32 Index = 1; Index < RawPtrs.Num(); Index++)
{
if (*static_cast<FKey*>(RawPtrs[Index]) != *KeyPtr)
{
return TOptional<FKey>();
}
}
return *KeyPtr;
}
}
return FKey();
}
void OnKeyChanged(TSharedPtr<FKey> SelectedKey)
{
KeyHandle->SetValueFromFormattedString(SelectedKey->ToString());
}
private:
TSharedPtr<IPropertyHandle> KeyHandle;
};
class SPropertyTriStateCheckBox : public SCompoundWidget
{
public:
using FCheckBoxStateRaw = std::underlying_type<ECheckBoxState>::type;
SLATE_BEGIN_ARGS(SPropertyTriStateCheckBox)
{}
SLATE_ARGUMENT(TSharedPtr<IPropertyHandle>, PropertyHandle)
SLATE_END_ARGS()
void Construct(const FArguments& InArgs)
{
PropertyHandle = InArgs._PropertyHandle;
// We are abusing SCheckBox a bit but our GetPropertyValue with custom OnCheckBoxStateChanged implementation
// gives a checkbox that allows to cycle between all three states.
ChildSlot
[
SNew(SCheckBox)
.IsChecked(this, &SPropertyTriStateCheckBox::GetPropertyValue)
.OnCheckStateChanged(this, &SPropertyTriStateCheckBox::OnCheckBoxStateChanged)
];
}
FCheckBoxStateRaw GetPropertyRawValue() const
{
FCheckBoxStateRaw Value;
PropertyHandle.Get()->GetValue(Value);
return Value;
}
ECheckBoxState GetPropertyValue() const
{
return static_cast<ECheckBoxState>(GetPropertyRawValue());
}
void OnCheckBoxStateChanged(ECheckBoxState State)
{
const FCheckBoxStateRaw PrevEnumValue = (GetPropertyRawValue() + 2) % 3;
PropertyHandle.Get()->SetValue(PrevEnumValue);
}
private:
TSharedPtr<IPropertyHandle> PropertyHandle;
};
}
//----------------------------------------------------------------------------------------------------
// FImGuiKeyInfoCustomization implementation
//----------------------------------------------------------------------------------------------------
namespace InputConstants
{
static const FMargin PropertyPadding(0.0f, 0.0f, 4.0f, 0.0f);
}
TSharedRef<IPropertyTypeCustomization> FImGuiKeyInfoCustomization::MakeInstance()
{
return MakeShareable(new FImGuiKeyInfoCustomization);
}
void FImGuiKeyInfoCustomization::CustomizeHeader(TSharedRef<IPropertyHandle> InStructPropertyHandle, FDetailWidgetRow& HeaderRow, IPropertyTypeCustomizationUtils& StructCustomizationUtils)
{
TSharedPtr<IPropertyHandle> KeyHandle = InStructPropertyHandle->GetChildHandle(GET_MEMBER_NAME_CHECKED(FImGuiKeyInfo, Key));
TSharedPtr<IPropertyHandle> ShiftHandle = InStructPropertyHandle->GetChildHandle(GET_MEMBER_NAME_CHECKED(FImGuiKeyInfo, Shift));
TSharedPtr<IPropertyHandle> CtrlHandle = InStructPropertyHandle->GetChildHandle(GET_MEMBER_NAME_CHECKED(FImGuiKeyInfo, Ctrl));
TSharedPtr<IPropertyHandle> AltHandle = InStructPropertyHandle->GetChildHandle(GET_MEMBER_NAME_CHECKED(FImGuiKeyInfo, Alt));
TSharedPtr<IPropertyHandle> CmdHandle = InStructPropertyHandle->GetChildHandle(GET_MEMBER_NAME_CHECKED(FImGuiKeyInfo, Cmd));
#define ADD_CHECK_BOX_SLOT(Handle) \
+ SHorizontalBox::Slot()\
.Padding(InputConstants::PropertyPadding)\
.HAlign(HAlign_Left)\
.VAlign(VAlign_Center)\
.AutoWidth()\
[\
Handle->CreatePropertyNameWidget()\
]\
+ SHorizontalBox::Slot()\
.Padding(InputConstants::PropertyPadding)\
.HAlign(HAlign_Left)\
.VAlign(VAlign_Center)\
.AutoWidth()\
[\
SNew(SPropertyTriStateCheckBox).PropertyHandle(Handle)\
]
HeaderRow
.NameContent()
[
InStructPropertyHandle->CreatePropertyNameWidget()
]
.ValueContent()
.MaxDesiredWidth(400.f)
[
SNew(SHorizontalBox)
+ SHorizontalBox::Slot()
.Padding(InputConstants::PropertyPadding)
.AutoWidth()
[
SNew(SBox)
.WidthOverride(200.f)
[
SNew(SPropertyKeySelector)
.KeyHandle(KeyHandle)
.Font(StructCustomizationUtils.GetRegularFont())
]
]
ADD_CHECK_BOX_SLOT(ShiftHandle)
ADD_CHECK_BOX_SLOT(CtrlHandle)
ADD_CHECK_BOX_SLOT(AltHandle)
ADD_CHECK_BOX_SLOT(CmdHandle)
];
#undef ADD_CHECK_BOX_SLOT
}
void FImGuiKeyInfoCustomization::CustomizeChildren(TSharedRef<IPropertyHandle> InStructPropertyHandle, IDetailChildrenBuilder& StructBuilder, IPropertyTypeCustomizationUtils& StructCustomizationUtils)
{
}
#undef LOCTEXT_NAMESPACE
#endif // WITH_EDITOR

View File

@ -0,0 +1,22 @@
// Copyright 1998-2018 Epic Games, Inc. All Rights Reserved.
#pragma once
#if WITH_EDITOR
#include <IPropertyTypeCustomization.h>
#include <PropertyHandle.h>
// Property type customization for FImGuiKeyInfo.
class FImGuiKeyInfoCustomization : public IPropertyTypeCustomization
{
public:
static TSharedRef<IPropertyTypeCustomization> MakeInstance();
// IPropertyTypeCustomization interface
virtual void CustomizeHeader(TSharedRef<IPropertyHandle> InStructPropertyHandle, FDetailWidgetRow& HeaderRow, IPropertyTypeCustomizationUtils& StructCustomizationUtils) override;
virtual void CustomizeChildren(TSharedRef<IPropertyHandle> InStructPropertyHandle, IDetailChildrenBuilder& StructBuilder, IPropertyTypeCustomizationUtils& StructCustomizationUtils) override;
};
#endif // WITH_EDITOR

View File

@ -0,0 +1,287 @@
// Distributed under the MIT License (MIT) (see accompanying LICENSE file)
#include "ImGuiContextManager.h"
#include "ImGuiDelegatesContainer.h"
#include "ImGuiImplementation.h"
#include "ImGuiModuleSettings.h"
#include "Utilities/WorldContext.h"
#include "Utilities/WorldContextIndex.h"
#include <imgui.h>
// TODO: Refactor ImGui Context Manager, to handle different types of worlds.
namespace
{
#if WITH_EDITOR
// Name for editor ImGui context.
FORCEINLINE FString GetEditorContextName()
{
return TEXT("Editor");
}
// Name for world ImGui context.
FORCEINLINE FString GetWorldContextName(const UWorld& World)
{
using namespace Utilities;
const FWorldContext* WorldContext = GetWorldContext(World);
switch (WorldContext->WorldType)
{
case EWorldType::PIE:
return FString::Printf(TEXT("PIEContext%d"), GetWorldContextIndex(*WorldContext));
case EWorldType::Game:
return TEXT("Game");
case EWorldType::Editor:
return TEXT("Editor");
default:
return TEXT("Other");
}
}
#else
FORCEINLINE FString GetWorldContextName()
{
return TEXT("Game");
}
FORCEINLINE FString GetWorldContextName(const UWorld&)
{
return TEXT("Game");
}
#endif // WITH_EDITOR
}
FImGuiContextManager::FImGuiContextManager(FImGuiModuleSettings& InSettings)
: Settings(InSettings)
{
Settings.OnDPIScaleChangedDelegate.AddRaw(this, &FImGuiContextManager::SetDPIScale);
SetDPIScale(Settings.GetDPIScaleInfo());
BuildFontAtlas();
FWorldDelegates::OnWorldTickStart.AddRaw(this, &FImGuiContextManager::OnWorldTickStart);
#if ENGINE_COMPATIBILITY_WITH_WORLD_POST_ACTOR_TICK
FWorldDelegates::OnWorldPostActorTick.AddRaw(this, &FImGuiContextManager::OnWorldPostActorTick);
#endif
}
FImGuiContextManager::~FImGuiContextManager()
{
Settings.OnDPIScaleChangedDelegate.RemoveAll(this);
// Order matters because contexts can be created during World Tick Start events.
FWorldDelegates::OnWorldTickStart.RemoveAll(this);
#if ENGINE_COMPATIBILITY_WITH_WORLD_POST_ACTOR_TICK
FWorldDelegates::OnWorldPostActorTick.RemoveAll(this);
#endif
}
void FImGuiContextManager::Tick(float DeltaSeconds)
{
// In editor, worlds can get invalid. We could remove corresponding entries, but that would mean resetting ImGui
// context every time when PIE session is restarted. Instead we freeze contexts until their worlds are re-created.
for (auto& Pair : Contexts)
{
auto& ContextData = Pair.Value;
if (ContextData.CanTick())
{
ContextData.ContextProxy->Tick(DeltaSeconds);
}
else
{
// Clear to make sure that we don't store objects registered for world that is no longer valid.
FImGuiDelegatesContainer::Get().OnWorldDebug(Pair.Key).Clear();
}
}
// Once all context tick they should use new fonts and we can release the old resources. Extra countdown is added
// wait for contexts that ticked outside of this function, before rebuilding fonts.
if (FontResourcesReleaseCountdown > 0 && !--FontResourcesReleaseCountdown)
{
FontResourcesToRelease.Empty();
}
}
#if ENGINE_COMPATIBILITY_LEGACY_WORLD_ACTOR_TICK
void FImGuiContextManager::OnWorldTickStart(ELevelTick TickType, float DeltaSeconds)
{
OnWorldTickStart(GWorld, TickType, DeltaSeconds);
}
#endif
void FImGuiContextManager::OnWorldTickStart(UWorld* World, ELevelTick TickType, float DeltaSeconds)
{
if (World && (World->WorldType == EWorldType::Game || World->WorldType == EWorldType::PIE
|| World->WorldType == EWorldType::Editor))
{
FImGuiContextProxy& ContextProxy = GetWorldContextProxy(*World);
// Set as current, so we have right context ready when updating world objects.
ContextProxy.SetAsCurrent();
ContextProxy.DrawEarlyDebug();
#if !ENGINE_COMPATIBILITY_WITH_WORLD_POST_ACTOR_TICK
ContextProxy.DrawDebug();
#endif
}
}
#if ENGINE_COMPATIBILITY_WITH_WORLD_POST_ACTOR_TICK
void FImGuiContextManager::OnWorldPostActorTick(UWorld* World, ELevelTick TickType, float DeltaSeconds)
{
if (World && (World->WorldType == EWorldType::Game || World->WorldType == EWorldType::PIE
|| World->WorldType == EWorldType::Editor))
{
GetWorldContextProxy(*World).DrawDebug();
}
}
#endif // ENGINE_COMPATIBILITY_WITH_WORLD_POST_ACTOR_TICK
#if WITH_EDITOR
FImGuiContextManager::FContextData& FImGuiContextManager::GetEditorContextData()
{
FContextData* Data = Contexts.Find(Utilities::EDITOR_CONTEXT_INDEX);
if (UNLIKELY(!Data))
{
Data = &Contexts.Emplace(Utilities::EDITOR_CONTEXT_INDEX, FContextData{ GetEditorContextName(), Utilities::EDITOR_CONTEXT_INDEX, FontAtlas, DPIScale, -1 });
OnContextProxyCreated.Broadcast(Utilities::EDITOR_CONTEXT_INDEX, *Data->ContextProxy);
}
return *Data;
}
#endif // WITH_EDITOR
#if !WITH_EDITOR
FImGuiContextManager::FContextData& FImGuiContextManager::GetStandaloneWorldContextData()
{
FContextData* Data = Contexts.Find(Utilities::STANDALONE_GAME_CONTEXT_INDEX);
if (UNLIKELY(!Data))
{
Data = &Contexts.Emplace(Utilities::STANDALONE_GAME_CONTEXT_INDEX, FContextData{ GetWorldContextName(), Utilities::STANDALONE_GAME_CONTEXT_INDEX, FontAtlas, DPIScale });
OnContextProxyCreated.Broadcast(Utilities::STANDALONE_GAME_CONTEXT_INDEX, *Data->ContextProxy);
}
return *Data;
}
#endif // !WITH_EDITOR
FImGuiContextManager::FContextData& FImGuiContextManager::GetWorldContextData(const UWorld& World, int32* OutIndex)
{
using namespace Utilities;
#if WITH_EDITOR
// Default to editor context for anything other than a game world.
if (World.WorldType != EWorldType::Game && World.WorldType != EWorldType::PIE)
{
if (OutIndex)
{
*OutIndex = Utilities::EDITOR_CONTEXT_INDEX;
}
return GetEditorContextData();
}
#endif
const FWorldContext* WorldContext = GetWorldContext(World);
const int32 Index = GetWorldContextIndex(*WorldContext);
checkf(Index != Utilities::INVALID_CONTEXT_INDEX, TEXT("Couldn't find context index for world %s: WorldType = %d"),
*World.GetName(), static_cast<int32>(World.WorldType));
#if WITH_EDITOR
checkf(!GEngine->IsEditor() || Index != Utilities::EDITOR_CONTEXT_INDEX,
TEXT("Context index %d is reserved for editor and cannot be used for world %s: WorldType = %d, NetMode = %d"),
Index, *World.GetName(), static_cast<int32>(World.WorldType), static_cast<int32>(World.GetNetMode()));
#endif
FContextData* Data = Contexts.Find(Index);
#if WITH_EDITOR
if (UNLIKELY(!Data))
{
Data = &Contexts.Emplace(Index, FContextData{ GetWorldContextName(World), Index, FontAtlas, DPIScale, WorldContext->PIEInstance });
OnContextProxyCreated.Broadcast(Index, *Data->ContextProxy);
}
else
{
// Because we allow (for the sake of continuity) to map different PIE instances to the same index.
Data->PIEInstance = WorldContext->PIEInstance;
}
#else
if (UNLIKELY(!Data))
{
Data = &Contexts.Emplace(Index, FContextData{ GetWorldContextName(World), Index, FontAtlas, DPIScale });
OnContextProxyCreated.Broadcast(Index, *Data->ContextProxy);
}
#endif
if (OutIndex)
{
*OutIndex = Index;
}
return *Data;
}
void FImGuiContextManager::SetDPIScale(const FImGuiDPIScaleInfo& ScaleInfo)
{
const float Scale = ScaleInfo.GetImGuiScale();
if (DPIScale != Scale)
{
DPIScale = Scale;
// Only rebuild font atlas if it is already built. Otherwise allow the other logic to pick a moment.
if (FontAtlas.IsBuilt())
{
RebuildFontAtlas();
}
for (auto& Pair : Contexts)
{
if (Pair.Value.ContextProxy)
{
Pair.Value.ContextProxy->SetDPIScale(DPIScale);
}
}
}
}
void FImGuiContextManager::BuildFontAtlas()
{
if (!FontAtlas.IsBuilt())
{
ImFontConfig FontConfig = {};
FontConfig.SizePixels = FMath::RoundFromZero(13.f * DPIScale);
FontAtlas.AddFontDefault(&FontConfig);
unsigned char* Pixels;
int Width, Height, Bpp;
FontAtlas.GetTexDataAsRGBA32(&Pixels, &Width, &Height, &Bpp);
OnFontAtlasBuilt.Broadcast();
}
}
void FImGuiContextManager::RebuildFontAtlas()
{
if (FontAtlas.IsBuilt())
{
// Keep the old resources alive for a few frames to give all contexts a chance to bind to new ones.
FontResourcesToRelease.Add(TUniquePtr<ImFontAtlas>(new ImFontAtlas()));
Swap(*FontResourcesToRelease.Last(), FontAtlas);
// Typically, one frame should be enough but since we allow for custom ticking, we need at least to frames to
// wait for contexts that already ticked and will not do that before the end of the next tick of this manager.
FontResourcesReleaseCountdown = 3;
}
BuildFontAtlas();
}

View File

@ -0,0 +1,117 @@
// Distributed under the MIT License (MIT) (see accompanying LICENSE file)
#pragma once
#include "ImGuiContextProxy.h"
#include "VersionCompatibility.h"
class FImGuiModuleSettings;
struct FImGuiDPIScaleInfo;
// TODO: It might be useful to broadcast FContextProxyCreatedDelegate to users, to support similar cases to our ImGui
// demo, but we would need to remove from that interface internal classes.
// Delegate called when new context proxy is created.
// @param ContextIndex - Index for that world
// @param ContextProxy - Created context proxy
DECLARE_MULTICAST_DELEGATE_TwoParams(FContextProxyCreatedDelegate, int32, FImGuiContextProxy&);
// Manages ImGui context proxies.
class FImGuiContextManager
{
public:
FImGuiContextManager(FImGuiModuleSettings& InSettings);
FImGuiContextManager(const FImGuiContextManager&) = delete;
FImGuiContextManager& operator=(const FImGuiContextManager&) = delete;
FImGuiContextManager(FImGuiContextManager&&) = delete;
FImGuiContextManager& operator=(FImGuiContextManager&&) = delete;
~FImGuiContextManager();
ImFontAtlas& GetFontAtlas() { return FontAtlas; }
const ImFontAtlas& GetFontAtlas() const { return FontAtlas; }
#if WITH_EDITOR
// Get or create editor ImGui context proxy.
FORCEINLINE FImGuiContextProxy& GetEditorContextProxy() { return *GetEditorContextData().ContextProxy; }
#endif
#if !WITH_EDITOR
// Get or create standalone game ImGui context proxy.
FORCEINLINE FImGuiContextProxy& GetWorldContextProxy() { return *GetStandaloneWorldContextData().ContextProxy; }
#endif
// Get or create ImGui context proxy for given world.
FORCEINLINE FImGuiContextProxy& GetWorldContextProxy(const UWorld& World) { return *GetWorldContextData(World).ContextProxy; }
// Get or create ImGui context proxy for given world. Additionally get context index for that proxy.
FORCEINLINE FImGuiContextProxy& GetWorldContextProxy(const UWorld& World, int32& OutContextIndex) { return *GetWorldContextData(World, &OutContextIndex).ContextProxy; }
// Get context proxy by index, or null if context with that index doesn't exist.
FORCEINLINE FImGuiContextProxy* GetContextProxy(int32 ContextIndex)
{
FContextData* Data = Contexts.Find(ContextIndex);
return Data ? Data->ContextProxy.Get() : nullptr;
}
// Delegate called when a new context proxy is created.
FContextProxyCreatedDelegate OnContextProxyCreated;
// Delegate called after font atlas is built.
FSimpleMulticastDelegate OnFontAtlasBuilt;
void Tick(float DeltaSeconds);
private:
struct FContextData
{
FContextData(const FString& ContextName, int32 ContextIndex, ImFontAtlas& FontAtlas, float DPIScale, int32 InPIEInstance = -1)
: PIEInstance(InPIEInstance)
, ContextProxy(new FImGuiContextProxy(ContextName, ContextIndex, &FontAtlas, DPIScale))
{
}
FORCEINLINE bool CanTick() const { return PIEInstance < 0 || GEngine->GetWorldContextFromPIEInstance(PIEInstance); }
int32 PIEInstance = -1;
TUniquePtr<FImGuiContextProxy> ContextProxy;
};
#if ENGINE_COMPATIBILITY_LEGACY_WORLD_ACTOR_TICK
void OnWorldTickStart(ELevelTick TickType, float DeltaSeconds);
#endif
void OnWorldTickStart(UWorld* World, ELevelTick TickType, float DeltaSeconds);
#if ENGINE_COMPATIBILITY_WITH_WORLD_POST_ACTOR_TICK
void OnWorldPostActorTick(UWorld* World, ELevelTick TickType, float DeltaSeconds);
#endif
#if WITH_EDITOR
FContextData& GetEditorContextData();
#endif
#if !WITH_EDITOR
FContextData& GetStandaloneWorldContextData();
#endif
FContextData& GetWorldContextData(const UWorld& World, int32* OutContextIndex = nullptr);
void SetDPIScale(const FImGuiDPIScaleInfo& ScaleInfo);
void BuildFontAtlas();
void RebuildFontAtlas();
TMap<int32, FContextData> Contexts;
ImFontAtlas FontAtlas;
TArray<TUniquePtr<ImFontAtlas>> FontResourcesToRelease;
FImGuiModuleSettings& Settings;
float DPIScale = -1.f;
int32 FontResourcesReleaseCountdown = 0;
};

View File

@ -0,0 +1,302 @@
// Distributed under the MIT License (MIT) (see accompanying LICENSE file)
#include "ImGuiContextProxy.h"
#include "ImGuiDelegatesContainer.h"
#include "ImGuiImplementation.h"
#include "ImGuiInteroperability.h"
#include "Utilities/Arrays.h"
#include "VersionCompatibility.h"
#include <GenericPlatform/GenericPlatformFile.h>
#include <Misc/Paths.h>
static constexpr float DEFAULT_CANVAS_WIDTH = 3840.f;
static constexpr float DEFAULT_CANVAS_HEIGHT = 2160.f;
namespace
{
FString GetSaveDirectory()
{
#if ENGINE_COMPATIBILITY_LEGACY_SAVED_DIR
const FString SavedDir = FPaths::GameSavedDir();
#else
const FString SavedDir = FPaths::ProjectSavedDir();
#endif
FString Directory = FPaths::Combine(*SavedDir, TEXT("ImGui"));
// Make sure that directory is created.
IPlatformFile::GetPlatformPhysical().CreateDirectory(*Directory);
return Directory;
}
FString GetIniFile(const FString& Name)
{
static FString SaveDirectory = GetSaveDirectory();
return FPaths::Combine(SaveDirectory, Name + TEXT(".ini"));
}
struct FGuardCurrentContext
{
FGuardCurrentContext()
: OldContext(ImGui::GetCurrentContext())
{
}
~FGuardCurrentContext()
{
if (bRestore)
{
ImGui::SetCurrentContext(OldContext);
}
}
FGuardCurrentContext(FGuardCurrentContext&& Other)
: OldContext(MoveTemp(Other.OldContext))
{
Other.bRestore = false;
}
FGuardCurrentContext& operator=(FGuardCurrentContext&&) = delete;
FGuardCurrentContext(const FGuardCurrentContext&) = delete;
FGuardCurrentContext& operator=(const FGuardCurrentContext&) = delete;
private:
ImGuiContext* OldContext = nullptr;
bool bRestore = true;
};
}
FImGuiContextProxy::FImGuiContextProxy(const FString& InName, int32 InContextIndex, ImFontAtlas* InFontAtlas, float InDPIScale)
: Name(InName)
, ContextIndex(InContextIndex)
, IniFilename(TCHAR_TO_ANSI(*GetIniFile(InName)))
{
// Create context.
Context = ImGui::CreateContext(InFontAtlas);
// Set this context in ImGui for initialization (any allocations will be tracked in this context).
SetAsCurrent();
// Start initialization.
ImGuiIO& IO = ImGui::GetIO();
// Set session data storage.
IO.IniFilename = IniFilename.c_str();
// Start with the default canvas size.
ResetDisplaySize();
IO.DisplaySize = { DisplaySize.X, DisplaySize.Y };
// Set the initial DPI scale.
SetDPIScale(InDPIScale);
// Initialize key mapping, so context can correctly interpret input state.
ImGuiInterops::SetUnrealKeyMap(IO);
// Begin frame to complete context initialization (this is to avoid problems with other systems calling to ImGui
// during startup).
BeginFrame();
}
FImGuiContextProxy::~FImGuiContextProxy()
{
if (Context)
{
// It seems that to properly shutdown context we need to set it as the current one (at least in this framework
// version), even though we can pass it to the destroy function.
SetAsCurrent();
// Save context data and destroy.
ImGui::DestroyContext(Context);
}
}
void FImGuiContextProxy::ResetDisplaySize()
{
DisplaySize = { DEFAULT_CANVAS_WIDTH, DEFAULT_CANVAS_HEIGHT };
}
void FImGuiContextProxy::SetDPIScale(float Scale)
{
if (DPIScale != Scale)
{
DPIScale = Scale;
ImGuiStyle NewStyle = ImGuiStyle();
NewStyle.ScaleAllSizes(Scale);
FGuardCurrentContext GuardContext;
SetAsCurrent();
ImGui::GetStyle() = MoveTemp(NewStyle);
}
}
void FImGuiContextProxy::DrawEarlyDebug()
{
if (bIsFrameStarted && !bIsDrawEarlyDebugCalled)
{
bIsDrawEarlyDebugCalled = true;
SetAsCurrent();
// Delegates called in order specified in FImGuiDelegates.
BroadcastMultiContextEarlyDebug();
BroadcastWorldEarlyDebug();
}
}
void FImGuiContextProxy::DrawDebug()
{
if (bIsFrameStarted && !bIsDrawDebugCalled)
{
bIsDrawDebugCalled = true;
// Make sure that early debug is always called first to guarantee order specified in FImGuiDelegates.
DrawEarlyDebug();
SetAsCurrent();
// Delegates called in order specified in FImGuiDelegates.
BroadcastWorldDebug();
BroadcastMultiContextDebug();
}
}
void FImGuiContextProxy::Tick(float DeltaSeconds)
{
// Making sure that we tick only once per frame.
if (LastFrameNumber < GFrameNumber)
{
LastFrameNumber = GFrameNumber;
SetAsCurrent();
if (bIsFrameStarted)
{
// Make sure that draw events are called before the end of the frame.
DrawDebug();
// Ending frame will produce render output that we capture and store for later use. This also puts context to
// state in which it does not allow to draw controls, so we want to immediately start a new frame.
EndFrame();
}
// Update context information (some data need to be collected before starting a new frame while some other data
// may need to be collected after).
bHasActiveItem = ImGui::IsAnyItemActive();
MouseCursor = ImGuiInterops::ToSlateMouseCursor(ImGui::GetMouseCursor());
// Begin a new frame and set the context back to a state in which it allows to draw controls.
BeginFrame(DeltaSeconds);
// Update remaining context information.
bWantsMouseCapture = ImGui::GetIO().WantCaptureMouse;
}
}
void FImGuiContextProxy::BeginFrame(float DeltaTime)
{
if (!bIsFrameStarted)
{
ImGuiIO& IO = ImGui::GetIO();
IO.DeltaTime = DeltaTime;
ImGuiInterops::CopyInput(IO, InputState);
InputState.ClearUpdateState();
IO.DisplaySize = { DisplaySize.X, DisplaySize.Y };
ImGui::NewFrame();
bIsFrameStarted = true;
bIsDrawEarlyDebugCalled = false;
bIsDrawDebugCalled = false;
}
}
void FImGuiContextProxy::EndFrame()
{
if (bIsFrameStarted)
{
// Prepare draw data (after this call we cannot draw to this context until we start a new frame).
ImGui::Render();
// Update our draw data, so we can use them later during Slate rendering while ImGui is in the middle of the
// next frame.
UpdateDrawData(ImGui::GetDrawData());
bIsFrameStarted = false;
}
}
void FImGuiContextProxy::UpdateDrawData(ImDrawData* DrawData)
{
if (DrawData && DrawData->CmdListsCount > 0)
{
DrawLists.SetNum(DrawData->CmdListsCount, false);
for (int Index = 0; Index < DrawData->CmdListsCount; Index++)
{
DrawLists[Index].TransferDrawData(*DrawData->CmdLists[Index]);
}
}
else
{
// If we are not rendering then this might be a good moment to empty the array.
DrawLists.Empty();
}
}
void FImGuiContextProxy::BroadcastWorldEarlyDebug()
{
if (ContextIndex != Utilities::INVALID_CONTEXT_INDEX)
{
FSimpleMulticastDelegate& WorldEarlyDebugEvent = FImGuiDelegatesContainer::Get().OnWorldEarlyDebug(ContextIndex);
if (WorldEarlyDebugEvent.IsBound())
{
WorldEarlyDebugEvent.Broadcast();
}
}
}
void FImGuiContextProxy::BroadcastMultiContextEarlyDebug()
{
FSimpleMulticastDelegate& MultiContextEarlyDebugEvent = FImGuiDelegatesContainer::Get().OnMultiContextEarlyDebug();
if (MultiContextEarlyDebugEvent.IsBound())
{
MultiContextEarlyDebugEvent.Broadcast();
}
}
void FImGuiContextProxy::BroadcastWorldDebug()
{
if (DrawEvent.IsBound())
{
DrawEvent.Broadcast();
}
if (ContextIndex != Utilities::INVALID_CONTEXT_INDEX)
{
FSimpleMulticastDelegate& WorldDebugEvent = FImGuiDelegatesContainer::Get().OnWorldDebug(ContextIndex);
if (WorldDebugEvent.IsBound())
{
WorldDebugEvent.Broadcast();
}
}
}
void FImGuiContextProxy::BroadcastMultiContextDebug()
{
FSimpleMulticastDelegate& MultiContextDebugEvent = FImGuiDelegatesContainer::Get().OnMultiContextDebug();
if (MultiContextDebugEvent.IsBound())
{
MultiContextDebugEvent.Broadcast();
}
}

View File

@ -0,0 +1,122 @@
// Distributed under the MIT License (MIT) (see accompanying LICENSE file)
#pragma once
#include "ImGuiDrawData.h"
#include "ImGuiInputState.h"
#include "Utilities/WorldContextIndex.h"
#include <GenericPlatform/ICursor.h>
#include <imgui.h>
#include <string>
// Represents a single ImGui context. All the context updates should be done through this proxy. During update it
// broadcasts draw events to allow listeners draw their controls. After update it stores draw data.
class FImGuiContextProxy
{
public:
FImGuiContextProxy(const FString& Name, int32 InContextIndex, ImFontAtlas* InFontAtlas, float InDPIScale);
~FImGuiContextProxy();
FImGuiContextProxy(const FImGuiContextProxy&) = delete;
FImGuiContextProxy& operator=(const FImGuiContextProxy&) = delete;
FImGuiContextProxy(FImGuiContextProxy&&) = delete;
FImGuiContextProxy& operator=(FImGuiContextProxy&&) = delete;
// Get the name of this context.
const FString& GetName() const { return Name; }
// Get draw data from the last frame.
const TArray<FImGuiDrawList>& GetDrawData() const { return DrawLists; }
// Get input state used by this context.
FImGuiInputState& GetInputState() { return InputState; }
const FImGuiInputState& GetInputState() const { return InputState; }
// Is this context the current ImGui context.
bool IsCurrentContext() const { return ImGui::GetCurrentContext() == Context; }
// Set this context as current ImGui context.
void SetAsCurrent() { ImGui::SetCurrentContext(Context); }
// Get the desired context display size.
const FVector2D& GetDisplaySize() const { return DisplaySize; }
// Set the desired context display size.
void SetDisplaySize(const FVector2D& Size) { DisplaySize = Size; }
// Reset the desired context display size to default size.
void ResetDisplaySize();
// Get the DPI scale set for this context.
float GetDPIScale() const { return DPIScale; }
// Set the DPI scale for this context.
void SetDPIScale(float Scale);
// Whether this context has an active item (read once per frame during context update).
bool HasActiveItem() const { return bHasActiveItem; }
// Whether ImGui will use the mouse inputs (read once per frame during context update).
bool WantsMouseCapture() const { return bWantsMouseCapture; }
// Cursor type desired by this context (updated once per frame during context update).
EMouseCursor::Type GetMouseCursor() const { return MouseCursor; }
// Internal draw event used to draw module's examples and debug widgets. Unlike the delegates container, it is not
// passed when the module is reloaded, so all objects that are unloaded with the module should register here.
FSimpleMulticastDelegate& OnDraw() { return DrawEvent; }
// Call early debug events to allow listeners draw their debug widgets.
void DrawEarlyDebug();
// Call debug events to allow listeners draw their debug widgets.
void DrawDebug();
// Tick to advance context to the next frame. Only one call per frame will be processed.
void Tick(float DeltaSeconds);
private:
void BeginFrame(float DeltaTime = 1.f / 60.f);
void EndFrame();
void UpdateDrawData(ImDrawData* DrawData);
void BroadcastWorldEarlyDebug();
void BroadcastMultiContextEarlyDebug();
void BroadcastWorldDebug();
void BroadcastMultiContextDebug();
ImGuiContext* Context;
FVector2D DisplaySize = FVector2D::ZeroVector;
float DPIScale = 1.f;
EMouseCursor::Type MouseCursor = EMouseCursor::None;
bool bHasActiveItem = false;
bool bWantsMouseCapture = false;
bool bIsFrameStarted = false;
bool bIsDrawEarlyDebugCalled = false;
bool bIsDrawDebugCalled = false;
FImGuiInputState InputState;
TArray<FImGuiDrawList> DrawLists;
FString Name;
int32 ContextIndex = Utilities::INVALID_CONTEXT_INDEX;
uint32 LastFrameNumber = 0;
FSimpleMulticastDelegate DrawEvent;
std::string IniFilename;
};

View File

@ -0,0 +1,37 @@
// Distributed under the MIT License (MIT) (see accompanying LICENSE file)
#include "ImGuiDelegates.h"
#include "ImGuiDelegatesContainer.h"
#include <Engine/World.h>
FSimpleMulticastDelegate& FImGuiDelegates::OnWorldEarlyDebug()
{
return OnWorldEarlyDebug(GWorld);
}
FSimpleMulticastDelegate& FImGuiDelegates::OnWorldEarlyDebug(UWorld* World)
{
return FImGuiDelegatesContainer::Get().OnWorldEarlyDebug(World);
}
FSimpleMulticastDelegate& FImGuiDelegates::OnMultiContextEarlyDebug()
{
return FImGuiDelegatesContainer::Get().OnMultiContextEarlyDebug();
}
FSimpleMulticastDelegate& FImGuiDelegates::OnWorldDebug()
{
return OnWorldDebug(GWorld);
}
FSimpleMulticastDelegate& FImGuiDelegates::OnWorldDebug(UWorld* World)
{
return FImGuiDelegatesContainer::Get().OnWorldDebug(World);
}
FSimpleMulticastDelegate& FImGuiDelegates::OnMultiContextDebug()
{
return FImGuiDelegatesContainer::Get().OnMultiContextDebug();
}

View File

@ -0,0 +1,88 @@
// Distributed under the MIT License (MIT) (see accompanying LICENSE file)
#include "ImGuiDelegatesContainer.h"
#include "ImGuiModule.h"
#include "Utilities/WorldContextIndex.h"
#if !WITH_EDITOR
//
// Non-editor version without container redirection
//
FImGuiDelegatesContainer& FImGuiDelegatesContainer::Get()
{
static FImGuiDelegatesContainer* Container = new FImGuiDelegatesContainer();
return *Container;
}
#endif // !WITH_EDITOR
#if WITH_EDITOR
//
// Editor version supporting container redirection needed for hot-reloading
//
#include "Utilities/RedirectingHandle.h"
// Redirecting handle which will always bind to a container from the currently loaded module.
struct FImGuiDelegatesContainerHandle : Utilities::TRedirectingHandle<FImGuiDelegatesContainer>
{
FImGuiDelegatesContainerHandle(FImGuiDelegatesContainer& InDefaultContainer)
: Utilities::TRedirectingHandle<FImGuiDelegatesContainer>(InDefaultContainer)
{
if (FImGuiModule* Module = FModuleManager::GetModulePtr<FImGuiModule>("ImGui"))
{
SetParent(Module->DelegatesContainerHandle);
}
}
};
FImGuiDelegatesContainer& FImGuiDelegatesContainer::Get()
{
return GetHandle().Get();
}
FImGuiDelegatesContainerHandle& FImGuiDelegatesContainer::GetHandle()
{
struct FContainerInstance
{
FContainerInstance() : Container(), Handle(Container) {}
FImGuiDelegatesContainer Container;
FImGuiDelegatesContainerHandle Handle;
};
static FContainerInstance* Instance = new FContainerInstance();
return Instance->Handle;
}
void FImGuiDelegatesContainer::MoveContainer(FImGuiDelegatesContainerHandle& OtherContainerHandle)
{
// Only move data if pointer points to default instance, otherwise our data has already been moved and we only
// keep pointer to a more recent version.
if (GetHandle().IsDefault())
{
OtherContainerHandle.Get() = MoveTemp(GetHandle().Get());
GetHandle().Get().Clear();
}
// Update pointer to the most recent version.
GetHandle().SetParent(&OtherContainerHandle);
}
#endif // WITH_EDITOR
int32 FImGuiDelegatesContainer::GetContextIndex(UWorld* World)
{
return Utilities::GetWorldContextIndex(*World);
}
void FImGuiDelegatesContainer::Clear()
{
WorldEarlyDebugDelegates.Empty();
WorldDebugDelegates.Empty();
MultiContextEarlyDebugDelegate.Clear();
MultiContextDebugDelegate.Clear();
}

View File

@ -0,0 +1,56 @@
// Distributed under the MIT License (MIT) (see accompanying LICENSE file)
#pragma once
#include <Containers/Map.h>
#include <Delegates/Delegate.h>
#if WITH_EDITOR
struct FImGuiDelegatesContainerHandle;
#endif
struct FImGuiDelegatesContainer
{
public:
// Get the current instance (can change during hot-reloading).
static FImGuiDelegatesContainer& Get();
#if WITH_EDITOR
// Get the handle to the container instance (can attach to other handles in hot-reloaded modules).
static FImGuiDelegatesContainerHandle& GetHandle();
// Redirect to the other container and if this one is still active move its data to the other one.
static void MoveContainer(FImGuiDelegatesContainerHandle& OtherContainerHandle);
#endif
// Get delegate to ImGui world early debug event from known world instance.
FSimpleMulticastDelegate& OnWorldEarlyDebug(UWorld* World) { return OnWorldEarlyDebug(GetContextIndex(World)); }
// Get delegate to ImGui world early debug event from known context index.
FSimpleMulticastDelegate& OnWorldEarlyDebug(int32 ContextIndex) { return WorldEarlyDebugDelegates.FindOrAdd(ContextIndex); }
// Get delegate to ImGui multi-context early debug event.
FSimpleMulticastDelegate& OnMultiContextEarlyDebug() { return MultiContextEarlyDebugDelegate; }
// Get delegate to ImGui world debug event from known world instance.
FSimpleMulticastDelegate& OnWorldDebug(UWorld* World) { return OnWorldDebug(GetContextIndex(World)); }
// Get delegate to ImGui world debug event from known context index.
FSimpleMulticastDelegate& OnWorldDebug(int32 ContextIndex) { return WorldDebugDelegates.FindOrAdd(ContextIndex); }
// Get delegate to ImGui multi-context debug event.
FSimpleMulticastDelegate& OnMultiContextDebug() { return MultiContextDebugDelegate; }
private:
int32 GetContextIndex(UWorld* World);
void Clear();
TMap<int32, FSimpleMulticastDelegate> WorldEarlyDebugDelegates;
TMap<int32, FSimpleMulticastDelegate> WorldDebugDelegates;
FSimpleMulticastDelegate MultiContextEarlyDebugDelegate;
FSimpleMulticastDelegate MultiContextDebugDelegate;
};

View File

@ -0,0 +1,83 @@
// Distributed under the MIT License (MIT) (see accompanying LICENSE file)
#include "ImGuiDemo.h"
#include "ImGuiModuleProperties.h"
#include <CoreGlobals.h>
// Demo copied (with minor modifications) from ImGui examples. See https://github.com/ocornut/imgui.
void FImGuiDemo::DrawControls(int32 ContextIndex)
{
if (Properties.ShowDemo())
{
const int32 ContextBit = ContextIndex < 0 ? 0 : 1 << ContextIndex;
// 1. Show a simple window
// Tip: if we don't call ImGui::Begin()/ImGui::End() the widgets appears in a window automatically called "Debug"
{
static float f = 0.0f;
ImGui::Text("Hello, world!");
ImGui::SliderFloat("float", &f, 0.0f, 1.0f);
ImGui::ColorEdit3("clear color", (float*)&ClearColor);
if (ContextBit)
{
if (ImGui::Button("Demo Window")) ShowDemoWindowMask ^= ContextBit;
if (ImGui::Button("Another Window")) ShowAnotherWindowMask ^= ContextBit;
}
ImGui::Text("Application average %.3f ms/frame (%.1f FPS)", 1000.0f / ImGui::GetIO().Framerate, ImGui::GetIO().Framerate);
}
// 2. Show another simple window, this time using an explicit Begin/End pair
if (ShowAnotherWindowMask & ContextBit)
{
ImGui::SetNextWindowSize(ImVec2(200, 100), ImGuiCond_FirstUseEver);
ImGui::Begin("Another Window");
ImGui::Text("Hello");
ImGui::End();
}
// 3. Show the ImGui test window. Most of the sample code is in ImGui::ShowTestWindow()
if (ShowDemoWindowMask & ContextBit)
{
// If more than one demo window is opened display warning about running ImGui examples in multiple contexts.
// For everything, but the first windows in this frame we assume warning.
bool bWarning = true;
if (GFrameNumber > LastDemoWindowFrameNumber)
{
// If this is the first window in this frame, then we need to look at the last frame to see whether
// there were more than one windows. Higher frame distance automatically means that there were not.
bWarning = ((GFrameNumber - LastDemoWindowFrameNumber) == 1) && (DemoWindowCounter > 1);
LastDemoWindowFrameNumber = GFrameNumber;
DemoWindowCounter = 0;
}
DemoWindowCounter++;
if (bWarning)
{
ImGui::Spacing();
ImGui::PushStyleColor(ImGuiCol_Text, { 1.f, 1.f, 0.5f, 1.f });
ImGui::TextWrapped("Demo Window is opened in more than one context, some of the ImGui examples may not work correctly.");
ImGui::PopStyleColor();
if (ImGui::IsItemHovered())
{
ImGui::SetTooltip(
"Some of the ImGui examples that use static variables may not work correctly\n"
"when run concurrently in multiple contexts.\n"
"If you have a problem with an example try to run it in one context only.");
}
}
// Draw demo window.
ImGui::SetNextWindowPos(ImVec2(650, 20), ImGuiCond_FirstUseEver);
ImGui::ShowDemoWindow();
}
}
}

View File

@ -0,0 +1,34 @@
// Distributed under the MIT License (MIT) (see accompanying LICENSE file)
#pragma once
#include <CoreMinimal.h>
#include <imgui.h>
class FImGuiModuleProperties;
// Widget drawing ImGui demo.
class FImGuiDemo
{
public:
FImGuiDemo(FImGuiModuleProperties& InProperties)
: Properties(InProperties)
{
}
void DrawControls(int32 ContextIndex);
private:
FImGuiModuleProperties& Properties;
ImVec4 ClearColor = ImColor{ 114, 144, 154 };
int32 ShowDemoWindowMask = 0;
int32 ShowAnotherWindowMask = 0;
int32 DemoWindowCounter = 0;
uint32 LastDemoWindowFrameNumber = 0;
};

View File

@ -0,0 +1,63 @@
// Distributed under the MIT License (MIT) (see accompanying LICENSE file)
#include "ImGuiDrawData.h"
#if ENGINE_COMPATIBILITY_LEGACY_CLIPPING_API
void FImGuiDrawList::CopyVertexData(TArray<FSlateVertex>& OutVertexBuffer, const FTransform2D& Transform, const FSlateRotatedRect& VertexClippingRect) const
#else
void FImGuiDrawList::CopyVertexData(TArray<FSlateVertex>& OutVertexBuffer, const FTransform2D& Transform) const
#endif // ENGINE_COMPATIBILITY_LEGACY_CLIPPING_API
{
// Reset and reserve space in destination buffer.
OutVertexBuffer.SetNumUninitialized(ImGuiVertexBuffer.Size, false);
// Transform and copy vertex data.
for (int Idx = 0; Idx < ImGuiVertexBuffer.Size; Idx++)
{
const ImDrawVert& ImGuiVertex = ImGuiVertexBuffer[Idx];
FSlateVertex& SlateVertex = OutVertexBuffer[Idx];
// Final UV is calculated in shader as XY * ZW, so we need set all components.
SlateVertex.TexCoords[0] = ImGuiVertex.uv.x;
SlateVertex.TexCoords[1] = ImGuiVertex.uv.y;
SlateVertex.TexCoords[2] = SlateVertex.TexCoords[3] = 1.f;
#if ENGINE_COMPATIBILITY_LEGACY_CLIPPING_API
const FVector2D VertexPosition = Transform.TransformPoint(ImGuiInterops::ToVector2D(ImGuiVertex.pos));
SlateVertex.Position[0] = VertexPosition.X;
SlateVertex.Position[1] = VertexPosition.Y;
SlateVertex.ClipRect = VertexClippingRect;
#else
SlateVertex.Position = Transform.TransformPoint(ImGuiInterops::ToVector2D(ImGuiVertex.pos));
#endif // ENGINE_COMPATIBILITY_LEGACY_CLIPPING_API
// Unpack ImU32 color.
SlateVertex.Color = ImGuiInterops::UnpackImU32Color(ImGuiVertex.col);
}
}
void FImGuiDrawList::CopyIndexData(TArray<SlateIndex>& OutIndexBuffer, const int32 StartIndex, const int32 NumElements) const
{
// Reset buffer.
OutIndexBuffer.SetNumUninitialized(NumElements, false);
// Copy elements (slow copy because of different sizes of ImDrawIdx and SlateIndex and because SlateIndex can
// have different size on different platforms).
for (int i = 0; i < NumElements; i++)
{
OutIndexBuffer[i] = ImGuiIndexBuffer[StartIndex + i];
}
}
void FImGuiDrawList::TransferDrawData(ImDrawList& Src)
{
// Move data from source to this list.
Src.CmdBuffer.swap(ImGuiCommandBuffer);
Src.IdxBuffer.swap(ImGuiIndexBuffer);
Src.VtxBuffer.swap(ImGuiVertexBuffer);
// ImGui seems to clear draw lists in every frame, but since source list can contain pointers to buffers that
// we just swapped, it is better to clear explicitly here.
Src.Clear();
}

View File

@ -0,0 +1,68 @@
// Distributed under the MIT License (MIT) (see accompanying LICENSE file)
#pragma once
#include "ImGuiInteroperability.h"
#include "VersionCompatibility.h"
#include <Rendering/RenderingCommon.h>
#include <imgui.h>
// ImGui draw command data transformed for Slate.
struct FImGuiDrawCommand
{
uint32 NumElements;
FSlateRect ClippingRect;
TextureIndex TextureId;
};
// Wraps raw ImGui draw list data in utilities that transform them for Slate.
class FImGuiDrawList
{
public:
// Get the number of draw commands in this list.
FORCEINLINE int NumCommands() const { return ImGuiCommandBuffer.Size; }
// Get the draw command by number.
// @param CommandNb - Number of draw command
// @param Transform - Transform to apply to clipping rectangle
// @returns Draw command data
FImGuiDrawCommand GetCommand(int CommandNb, const FTransform2D& Transform) const
{
const ImDrawCmd& ImGuiCommand = ImGuiCommandBuffer[CommandNb];
return { ImGuiCommand.ElemCount, TransformRect(Transform, ImGuiInterops::ToSlateRect(ImGuiCommand.ClipRect)),
ImGuiInterops::ToTextureIndex(ImGuiCommand.TextureId) };
}
#if ENGINE_COMPATIBILITY_LEGACY_CLIPPING_API
// Transform and copy vertex data to target buffer (old data in the target buffer are replaced).
// @param OutVertexBuffer - Destination buffer
// @param Transform - Transform to apply to all vertices
// @param VertexClippingRect - Clipping rectangle for transformed Slate vertices
void CopyVertexData(TArray<FSlateVertex>& OutVertexBuffer, const FTransform2D& Transform, const FSlateRotatedRect& VertexClippingRect) const;
#else
// Transform and copy vertex data to target buffer (old data in the target buffer are replaced).
// @param OutVertexBuffer - Destination buffer
// @param Transform - Transform to apply to all vertices
void CopyVertexData(TArray<FSlateVertex>& OutVertexBuffer, const FTransform2D& Transform) const;
#endif // ENGINE_COMPATIBILITY_LEGACY_CLIPPING_API
// Transform and copy index data to target buffer (old data in the target buffer are replaced).
// Internal index buffer contains enough data to match the sum of NumElements from all draw commands.
// @param OutIndexBuffer - Destination buffer
// @param StartIndex - Start copying source data starting from this index
// @param NumElements - How many elements we want to copy
void CopyIndexData(TArray<SlateIndex>& OutIndexBuffer, const int32 StartIndex, const int32 NumElements) const;
// Transfers data from ImGui source list to this object. Leaves source cleared.
void TransferDrawData(ImDrawList& Src);
private:
ImVector<ImDrawCmd> ImGuiCommandBuffer;
ImVector<ImDrawIdx> ImGuiIndexBuffer;
ImVector<ImDrawVert> ImGuiVertexBuffer;
};

View File

@ -0,0 +1,70 @@
// Distributed under the MIT License (MIT) (see accompanying LICENSE file)
#include "ImGuiImplementation.h"
#include <CoreMinimal.h>
// For convenience and easy access to the ImGui source code, we build it as part of this module.
// We don't need to define IMGUI_API manually because it is already done for this module.
#if PLATFORM_XBOXONE
// Disable Win32 functions used in ImGui and not supported on XBox.
#define IMGUI_DISABLE_WIN32_DEFAULT_CLIPBOARD_FUNCTIONS
#define IMGUI_DISABLE_WIN32_DEFAULT_IME_FUNCTIONS
#endif // PLATFORM_XBOXONE
#if PLATFORM_WINDOWS
#include <Windows/AllowWindowsPlatformTypes.h>
#endif // PLATFORM_WINDOWS
#if WITH_EDITOR
#include "ImGuiModule.h"
#include "Utilities/RedirectingHandle.h"
// Redirecting handle which will automatically bind to another one, if a different instance of the module is loaded.
struct FImGuiContextHandle : public Utilities::TRedirectingHandle<ImGuiContext*>
{
FImGuiContextHandle(ImGuiContext*& InDefaultContext)
: Utilities::TRedirectingHandle<ImGuiContext*>(InDefaultContext)
{
if (FImGuiModule* Module = FModuleManager::GetModulePtr<FImGuiModule>("ImGui"))
{
SetParent(Module->ImGuiContextHandle);
}
}
};
static ImGuiContext* ImGuiContextPtr = nullptr;
static FImGuiContextHandle ImGuiContextPtrHandle(ImGuiContextPtr);
// Get the global ImGui context pointer (GImGui) indirectly to allow redirections in obsolete modules.
#define GImGui (ImGuiContextPtrHandle.Get())
#endif // WITH_EDITOR
#include "imgui.cpp"
#include "imgui_demo.cpp"
#include "imgui_draw.cpp"
#include "imgui_widgets.cpp"
#if PLATFORM_WINDOWS
#include <Windows/HideWindowsPlatformTypes.h>
#endif // PLATFORM_WINDOWS
#include "ImGuiInteroperability.h"
namespace ImGuiImplementation
{
#if WITH_EDITOR
FImGuiContextHandle& GetContextHandle()
{
return ImGuiContextPtrHandle;
}
void SetParentContextHandle(FImGuiContextHandle& Parent)
{
ImGuiContextPtrHandle.SetParent(&Parent);
}
#endif // WITH_EDITOR
}

View File

@ -0,0 +1,17 @@
// Distributed under the MIT License (MIT) (see accompanying LICENSE file)
#pragma once
struct FImGuiContextHandle;
// Gives access to selected ImGui implementation features.
namespace ImGuiImplementation
{
#if WITH_EDITOR
// Get the handle to the ImGui Context pointer.
FImGuiContextHandle& GetContextHandle();
// Set the ImGui Context pointer handle.
void SetParentContextHandle(FImGuiContextHandle& Parent);
#endif // WITH_EDITOR
}

View File

@ -0,0 +1,359 @@
// Distributed under the MIT License (MIT) (see accompanying LICENSE file)
#include "ImGuiInputHandler.h"
#include "ImGuiContextProxy.h"
#include "ImGuiInputState.h"
#include "ImGuiModuleDebug.h"
#include "ImGuiModuleManager.h"
#include "ImGuiModuleSettings.h"
#include "VersionCompatibility.h"
#include <Engine/Console.h>
#include <Framework/Application/SlateApplication.h>
#include <GameFramework/InputSettings.h>
#include <InputCoreTypes.h>
#include <Input/Events.h>
#if WITH_EDITOR
#include <Framework/Commands/InputBindingManager.h>
#include <Framework/Commands/InputChord.h>
#include <Kismet2/DebuggerCommands.h>
#endif // WITH_EDITOR
DEFINE_LOG_CATEGORY(LogImGuiInputHandler);
namespace
{
FReply ToReply(bool bConsume)
{
return bConsume ? FReply::Handled() : FReply::Unhandled();
}
}
FReply UImGuiInputHandler::OnKeyChar(const struct FCharacterEvent& CharacterEvent)
{
InputState->AddCharacter(CharacterEvent.GetCharacter());
return ToReply(!ModuleManager->GetProperties().IsKeyboardInputShared());
}
FReply UImGuiInputHandler::OnKeyDown(const FKeyEvent& KeyEvent)
{
if (KeyEvent.GetKey().IsGamepadKey())
{
bool bConsume = false;
if (InputState->IsGamepadNavigationEnabled())
{
InputState->SetGamepadNavigationKey(KeyEvent, true);
bConsume = !ModuleManager->GetProperties().IsGamepadInputShared();
}
return ToReply(bConsume);
}
else
{
// Ignore console events, so we don't block it from opening.
if (IsConsoleEvent(KeyEvent))
{
return ToReply(false);
}
#if WITH_EDITOR
// If there is no active ImGui control that would get precedence and this key event is bound to a stop play session
// command, then ignore that event and let the command execute.
if (!HasImGuiActiveItem() && IsStopPlaySessionEvent(KeyEvent))
{
return ToReply(false);
}
#endif // WITH_EDITOR
const bool bConsume = !ModuleManager->GetProperties().IsKeyboardInputShared();
// With shared input we can leave command bindings for DebugExec to handle, otherwise we need to do it here.
if (bConsume && IsToggleInputEvent(KeyEvent))
{
ModuleManager->GetProperties().ToggleInput();
}
InputState->SetKeyDown(KeyEvent, true);
CopyModifierKeys(KeyEvent);
return ToReply(bConsume);
}
}
FReply UImGuiInputHandler::OnKeyUp(const FKeyEvent& KeyEvent)
{
if (KeyEvent.GetKey().IsGamepadKey())
{
bool bConsume = false;
if (InputState->IsGamepadNavigationEnabled())
{
InputState->SetGamepadNavigationKey(KeyEvent, false);
bConsume = !ModuleManager->GetProperties().IsGamepadInputShared();
}
return ToReply(bConsume);
}
else
{
InputState->SetKeyDown(KeyEvent, false);
CopyModifierKeys(KeyEvent);
return ToReply(!ModuleManager->GetProperties().IsKeyboardInputShared());
}
}
FReply UImGuiInputHandler::OnAnalogValueChanged(const FAnalogInputEvent& AnalogInputEvent)
{
bool bConsume = false;
if (AnalogInputEvent.GetKey().IsGamepadKey() && InputState->IsGamepadNavigationEnabled())
{
InputState->SetGamepadNavigationAxis(AnalogInputEvent, AnalogInputEvent.GetAnalogValue());
bConsume = !ModuleManager->GetProperties().IsGamepadInputShared();
}
return ToReply(bConsume);
}
FReply UImGuiInputHandler::OnMouseButtonDown(const FPointerEvent& MouseEvent)
{
if (MouseEvent.IsTouchEvent())
{
return ToReply(false);
}
InputState->SetMouseDown(MouseEvent, true);
return ToReply(true);
}
FReply UImGuiInputHandler::OnMouseButtonDoubleClick(const FPointerEvent& MouseEvent)
{
InputState->SetMouseDown(MouseEvent, true);
return ToReply(true);
}
FReply UImGuiInputHandler::OnMouseButtonUp(const FPointerEvent& MouseEvent)
{
if (MouseEvent.IsTouchEvent())
{
return ToReply(false);
}
InputState->SetMouseDown(MouseEvent, false);
return ToReply(true);
}
FReply UImGuiInputHandler::OnMouseWheel(const FPointerEvent& MouseEvent)
{
InputState->AddMouseWheelDelta(MouseEvent.GetWheelDelta());
return ToReply(true);
}
FReply UImGuiInputHandler::OnMouseMove(const FVector2D& MousePosition, const FPointerEvent& MouseEvent)
{
if (MouseEvent.IsTouchEvent())
{
return ToReply(false);
}
return OnMouseMove(MousePosition);
}
FReply UImGuiInputHandler::OnMouseMove(const FVector2D& MousePosition)
{
InputState->SetMousePosition(MousePosition);
return ToReply(true);
}
FReply UImGuiInputHandler::OnTouchStarted(const FVector2D& CursorPosition, const FPointerEvent& TouchEvent)
{
InputState->SetTouchDown(true);
InputState->SetTouchPosition(CursorPosition);
return ToReply(true);
}
FReply UImGuiInputHandler::OnTouchMoved(const FVector2D& CursorPosition, const FPointerEvent& TouchEvent)
{
InputState->SetTouchPosition(CursorPosition);
return ToReply(true);
}
FReply UImGuiInputHandler::OnTouchEnded(const FVector2D& CursorPosition, const FPointerEvent& TouchEvent)
{
InputState->SetTouchDown(false);
return ToReply(true);
}
void UImGuiInputHandler::OnKeyboardInputEnabled()
{
bKeyboardInputEnabled = true;
}
void UImGuiInputHandler::OnKeyboardInputDisabled()
{
if (bKeyboardInputEnabled)
{
bKeyboardInputEnabled = false;
InputState->ResetKeyboard();
}
}
void UImGuiInputHandler::OnGamepadInputEnabled()
{
bGamepadInputEnabled = true;
}
void UImGuiInputHandler::OnGamepadInputDisabled()
{
if (bGamepadInputEnabled)
{
bGamepadInputEnabled = false;
InputState->ResetGamepadNavigation();
}
}
void UImGuiInputHandler::OnMouseInputEnabled()
{
if (!bMouseInputEnabled)
{
bMouseInputEnabled = true;
UpdateInputStatePointer();
}
}
void UImGuiInputHandler::OnMouseInputDisabled()
{
if (bMouseInputEnabled)
{
bMouseInputEnabled = false;
InputState->ResetMouse();
UpdateInputStatePointer();
}
}
void UImGuiInputHandler::CopyModifierKeys(const FInputEvent& InputEvent)
{
InputState->SetControlDown(InputEvent.IsControlDown());
InputState->SetShiftDown(InputEvent.IsShiftDown());
InputState->SetAltDown(InputEvent.IsAltDown());
}
bool UImGuiInputHandler::IsConsoleEvent(const FKeyEvent& KeyEvent) const
{
// Checking modifiers is based on console implementation.
const bool bModifierDown = KeyEvent.IsControlDown() || KeyEvent.IsShiftDown() || KeyEvent.IsAltDown() || KeyEvent.IsCommandDown();
return !bModifierDown && GetDefault<UInputSettings>()->ConsoleKeys.Contains(KeyEvent.GetKey());
}
#if WITH_EDITOR
bool UImGuiInputHandler::IsStopPlaySessionEvent(const FKeyEvent& KeyEvent) const
{
if (StopPlaySessionCommandInfo.IsValid())
{
const FInputChord InputChord(KeyEvent.GetKey(), KeyEvent.IsShiftDown(), KeyEvent.IsControlDown(), KeyEvent.IsAltDown(), KeyEvent.IsCommandDown());
#if ENGINE_COMPATIBILITY_SINGLE_KEY_BINDING
const bool bHasActiveChord = (InputChord == StopPlaySessionCommandInfo->GetActiveChord().Get());
#else
const bool bHasActiveChord = StopPlaySessionCommandInfo->HasActiveChord(InputChord);
#endif
return bHasActiveChord && FPlayWorldCommands::GlobalPlayWorldActions->CanExecuteAction(StopPlaySessionCommandInfo.ToSharedRef());
}
return false;
}
#endif // WITH_EDITOR
namespace
{
bool IsMatching(ECheckBoxState CheckBoxState, bool bValue)
{
return (CheckBoxState == ECheckBoxState::Undetermined) || ((CheckBoxState == ECheckBoxState::Checked) == bValue);
}
bool IsMatchingEvent(const FKeyEvent& KeyEvent, const FImGuiKeyInfo& KeyInfo)
{
return (KeyInfo.Key == KeyEvent.GetKey())
&& IsMatching(KeyInfo.Shift, KeyEvent.IsShiftDown())
&& IsMatching(KeyInfo.Ctrl, KeyEvent.IsControlDown())
&& IsMatching(KeyInfo.Alt, KeyEvent.IsAltDown())
&& IsMatching(KeyInfo.Cmd, KeyEvent.IsCommandDown());
}
}
bool UImGuiInputHandler::IsToggleInputEvent(const FKeyEvent& KeyEvent) const
{
return IsMatchingEvent(KeyEvent, ModuleManager->GetSettings().GetToggleInputKey());
}
bool UImGuiInputHandler::HasImGuiActiveItem() const
{
FImGuiContextProxy* ContextProxy = ModuleManager->GetContextManager().GetContextProxy(ContextIndex);
return ContextProxy && ContextProxy->HasActiveItem();
}
void UImGuiInputHandler::UpdateInputStatePointer()
{
InputState->SetMousePointer(bMouseInputEnabled && ModuleManager->GetSettings().UseSoftwareCursor());
}
void UImGuiInputHandler::OnSoftwareCursorChanged(bool)
{
UpdateInputStatePointer();
}
void UImGuiInputHandler::OnPostImGuiUpdate()
{
InputState->ClearUpdateState();
// TODO Replace with delegates after adding property change events.
InputState->SetKeyboardNavigationEnabled(ModuleManager->GetProperties().IsKeyboardNavigationEnabled());
InputState->SetGamepadNavigationEnabled(ModuleManager->GetProperties().IsGamepadNavigationEnabled());
const auto& PlatformApplication = FSlateApplication::Get().GetPlatformApplication();
InputState->SetGamepad(PlatformApplication.IsValid() && PlatformApplication->IsGamepadAttached());
}
void UImGuiInputHandler::Initialize(FImGuiModuleManager* InModuleManager, UGameViewportClient* InGameViewport, int32 InContextIndex)
{
ModuleManager = InModuleManager;
GameViewport = InGameViewport;
ContextIndex = InContextIndex;
auto* ContextProxy = ModuleManager->GetContextManager().GetContextProxy(ContextIndex);
checkf(ContextProxy, TEXT("Missing context during initialization of input handler: ContextIndex = %d"), ContextIndex);
InputState = &ContextProxy->GetInputState();
// Register to get post-update notifications, so we can clean frame updates.
ModuleManager->OnPostImGuiUpdate().AddUObject(this, &UImGuiInputHandler::OnPostImGuiUpdate);
auto& Settings = ModuleManager->GetSettings();
if (!Settings.OnUseSoftwareCursorChanged.IsBoundToObject(this))
{
Settings.OnUseSoftwareCursorChanged.AddUObject(this, &UImGuiInputHandler::OnSoftwareCursorChanged);
}
#if WITH_EDITOR
StopPlaySessionCommandInfo = FInputBindingManager::Get().FindCommandInContext("PlayWorld", "StopPlaySession");
if (!StopPlaySessionCommandInfo.IsValid())
{
UE_LOG(LogImGuiInputHandler, Warning, TEXT("Couldn't find 'StopPlaySession' in context 'PlayWorld'. ")
TEXT("PIE feature allowing execution of stop command in ImGui input mode will be disabled."));
}
#endif // WITH_EDITOR
}
void UImGuiInputHandler::BeginDestroy()
{
Super::BeginDestroy();
// To catch leftovers from modules shutdown during PIE session.
extern FImGuiModuleManager* ImGuiModuleManager;
if (ModuleManager && ModuleManager == ImGuiModuleManager)
{
ModuleManager->GetSettings().OnUseSoftwareCursorChanged.RemoveAll(this);
}
}

View File

@ -0,0 +1,50 @@
// Distributed under the MIT License (MIT) (see accompanying LICENSE file)
#include "ImGuiInputHandlerFactory.h"
#include "ImGuiInputHandler.h"
#include "ImGuiModuleDebug.h"
#include <Engine/GameViewportClient.h>
#include <InputCoreTypes.h>
UImGuiInputHandler* FImGuiInputHandlerFactory::NewHandler(const FStringClassReference& HandlerClassReference, FImGuiModuleManager* ModuleManager, UGameViewportClient* GameViewport, int32 ContextIndex)
{
UClass* HandlerClass = nullptr;
if (HandlerClassReference.IsValid())
{
HandlerClass = HandlerClassReference.TryLoadClass<UImGuiInputHandler>();
if (!HandlerClass)
{
UE_LOG(LogImGuiInputHandler, Error, TEXT("Couldn't load ImGui Input Handler class '%s'."), *HandlerClassReference.ToString());
}
}
if (!HandlerClass)
{
HandlerClass = UImGuiInputHandler::StaticClass();
}
UImGuiInputHandler* Handler = NewObject<UImGuiInputHandler>(GameViewport, HandlerClass);
if (Handler)
{
Handler->Initialize(ModuleManager, GameViewport, ContextIndex);
Handler->AddToRoot();
}
else
{
UE_LOG(LogImGuiInputHandler, Error, TEXT("Failed attempt to create Input Handler: HandlerClass = %s."), *GetNameSafe(HandlerClass));
}
return Handler;
}
void FImGuiInputHandlerFactory::ReleaseHandler(UImGuiInputHandler* Handler)
{
if (Handler)
{
Handler->RemoveFromRoot();
}
}

View File

@ -0,0 +1,19 @@
// Distributed under the MIT License (MIT) (see accompanying LICENSE file)
#pragma once
#include "ImGuiModuleSettings.h"
class FImGuiModuleManager;
class UGameViewportClient;
class UImGuiInputHandler;
class FImGuiInputHandlerFactory
{
public:
static UImGuiInputHandler* NewHandler(const FStringClassReference& HandlerClassReference, FImGuiModuleManager* ModuleManager, UGameViewportClient* GameViewport, int32 ContextIndex);
static void ReleaseHandler(UImGuiInputHandler* Handler);
};

View File

@ -0,0 +1,97 @@
// Distributed under the MIT License (MIT) (see accompanying LICENSE file)
#include "ImGuiInputState.h"
#include <algorithm>
#include <limits>
#include <type_traits>
FImGuiInputState::FImGuiInputState()
{
Reset();
}
void FImGuiInputState::AddCharacter(TCHAR Char)
{
InputCharacters.Add(Char);
}
void FImGuiInputState::SetKeyDown(uint32 KeyIndex, bool bIsDown)
{
if (KeyIndex < Utilities::GetArraySize(KeysDown))
{
if (KeysDown[KeyIndex] != bIsDown)
{
KeysDown[KeyIndex] = bIsDown;
KeysUpdateRange.AddPosition(KeyIndex);
}
}
}
void FImGuiInputState::SetMouseDown(uint32 MouseIndex, bool bIsDown)
{
if (MouseIndex < Utilities::GetArraySize(MouseButtonsDown))
{
if (MouseButtonsDown[MouseIndex] != bIsDown)
{
MouseButtonsDown[MouseIndex] = bIsDown;
MouseButtonsUpdateRange.AddPosition(MouseIndex);
}
}
}
void FImGuiInputState::ClearUpdateState()
{
ClearCharacters();
KeysUpdateRange.SetEmpty();
MouseButtonsUpdateRange.SetEmpty();
MouseWheelDelta = 0.f;
bTouchProcessed = bTouchDown;
}
void FImGuiInputState::ClearCharacters()
{
InputCharacters.Empty();
}
void FImGuiInputState::ClearKeys()
{
using std::fill;
fill(KeysDown, &KeysDown[Utilities::GetArraySize(KeysDown)], false);
// Mark the whole array as dirty because potentially each entry could be affected.
KeysUpdateRange.SetFull();
}
void FImGuiInputState::ClearMouseButtons()
{
using std::fill;
fill(MouseButtonsDown, &MouseButtonsDown[Utilities::GetArraySize(MouseButtonsDown)], false);
// Mark the whole array as dirty because potentially each entry could be affected.
MouseButtonsUpdateRange.SetFull();
}
void FImGuiInputState::ClearMouseAnalogue()
{
MousePosition = FVector2D::ZeroVector;
MouseWheelDelta = 0.f;
}
void FImGuiInputState::ClearModifierKeys()
{
bIsControlDown = false;
bIsShiftDown = false;
bIsAltDown = false;
}
void FImGuiInputState::ClearNavigationInputs()
{
using std::fill;
fill(NavigationInputs, &NavigationInputs[Utilities::GetArraySize(NavigationInputs)], 0.f);
}

View File

@ -0,0 +1,241 @@
// Distributed under the MIT License (MIT) (see accompanying LICENSE file)
#pragma once
#include "ImGuiInteroperability.h"
#include "Utilities/Arrays.h"
#include <Containers/Array.h>
// Collects and stores input state and updates for ImGui IO.
class FImGuiInputState
{
public:
// Characters buffer.
using FCharactersBuffer = TArray<TCHAR, TInlineAllocator<8>>;
// Array for mouse button states.
using FMouseButtonsArray = ImGuiInterops::ImGuiTypes::FMouseButtonsArray;
// Array for key states.
using FKeysArray = ImGuiInterops::ImGuiTypes::FKeysArray;
// Array for navigation input states.
using FNavInputArray = ImGuiInterops::ImGuiTypes::FNavInputArray;
// Pair of indices defining range in mouse buttons array.
using FMouseButtonsIndexRange = Utilities::TArrayIndexRange<FMouseButtonsArray, uint32>;
// Pair of indices defining range in keys array.
using FKeysIndexRange = Utilities::TArrayIndexRange<FKeysArray, uint32>;
// Create empty state with whole range instance with the whole update state marked as dirty.
FImGuiInputState();
// Get reference to input characters buffer.
const FCharactersBuffer& GetCharacters() const { return InputCharacters; }
// Add a character to the characters buffer. We can store and send to ImGui up to 16 characters per frame. Any
// character beyond that limit will be discarded.
// @param Char - Character to add
void AddCharacter(TCHAR Char);
// Get reference to the array with key down states.
const FKeysArray& GetKeys() const { return KeysDown; }
// Get possibly empty range of indices bounding dirty part of the keys array.
const FKeysIndexRange& GetKeysUpdateRange() const { return KeysUpdateRange; }
// Change state of the key in the keys array and expand range bounding dirty part of the array.
// @param KeyEvent - Key event representing the key
// @param bIsDown - True, if key is down
void SetKeyDown(const FKeyEvent& KeyEvent, bool bIsDown) { SetKeyDown(ImGuiInterops::GetKeyIndex(KeyEvent), bIsDown); }
// Change state of the key in the keys array and expand range bounding dirty part of the array.
// @param Key - Keyboard key
// @param bIsDown - True, if key is down
void SetKeyDown(const FKey& Key, bool bIsDown) { SetKeyDown(ImGuiInterops::GetKeyIndex(Key), bIsDown); }
// Get reference to the array with mouse button down states.
const FMouseButtonsArray& GetMouseButtons() const { return MouseButtonsDown; }
// Get possibly empty range of indices bounding dirty part of the mouse buttons array.
const FMouseButtonsIndexRange& GetMouseButtonsUpdateRange() const { return MouseButtonsUpdateRange; }
// Change state of the button in the mouse buttons array and expand range bounding dirty part of the array.
// @param MouseEvent - Mouse event representing mouse button
// @param bIsDown - True, if button is down
void SetMouseDown(const FPointerEvent& MouseEvent, bool bIsDown) { SetMouseDown(ImGuiInterops::GetMouseIndex(MouseEvent), bIsDown); }
// Change state of the button in the mouse buttons array and expand range bounding dirty part of the array.
// @param MouseButton - Mouse button key
// @param bIsDown - True, if button is down
void SetMouseDown(const FKey& MouseButton, bool bIsDown) { SetMouseDown(ImGuiInterops::GetMouseIndex(MouseButton), bIsDown); }
// Get mouse wheel delta accumulated during the last frame.
float GetMouseWheelDelta() const { return MouseWheelDelta; }
// Add mouse wheel delta.
// @param DeltaValue - Mouse wheel delta to add
void AddMouseWheelDelta(float DeltaValue) { MouseWheelDelta += DeltaValue; }
// Get the mouse position.
const FVector2D& GetMousePosition() const { return MousePosition; }
// Set the mouse position.
// @param Position - Mouse position
void SetMousePosition(const FVector2D& Position) { MousePosition = Position; }
// Check whether input has active mouse pointer.
bool HasMousePointer() const { return bHasMousePointer; }
// Set whether input has active mouse pointer.
// @param bHasPointer - True, if input has active mouse pointer
void SetMousePointer(bool bInHasMousePointer) { bHasMousePointer = bInHasMousePointer; }
// Check whether touch input is in progress. True, after touch is started until one frame after it has ended.
// One frame delay is used to process mouse release in ImGui since touch-down is simulated with mouse-down.
bool IsTouchActive() const { return bTouchDown || bTouchProcessed; }
// Check whether touch input is down.
bool IsTouchDown() const { return bTouchDown; }
// Set whether touch input is down.
// @param bIsDown - True, if touch is down (or started) and false, if touch is up (or ended)
void SetTouchDown(bool bIsDown) { bTouchDown = bIsDown; }
// Get the touch position.
const FVector2D& GetTouchPosition() const { return TouchPosition; }
// Set the touch position.
// @param Position - Touch position
void SetTouchPosition(const FVector2D& Position) { TouchPosition = Position; }
// Get Control down state.
bool IsControlDown() const { return bIsControlDown; }
// Set Control down state.
// @param bIsDown - True, if Control is down
void SetControlDown(bool bIsDown) { bIsControlDown = bIsDown; }
// Get Shift down state.
bool IsShiftDown() const { return bIsShiftDown; }
// Set Shift down state.
// @param bIsDown - True, if Shift is down
void SetShiftDown(bool bIsDown) { bIsShiftDown = bIsDown; }
// Get Alt down state.
bool IsAltDown() const { return bIsAltDown; }
// Set Alt down state.
// @param bIsDown - True, if Alt is down
void SetAltDown(bool bIsDown) { bIsAltDown = bIsDown; }
// Get reference to the array with navigation input states.
const FNavInputArray& GetNavigationInputs() const { return NavigationInputs; }
// Change state of the navigation input associated with this gamepad key.
// @param KeyEvent - Key event with gamepad key input
// @param bIsDown - True, if key is down
void SetGamepadNavigationKey(const FKeyEvent& KeyEvent, bool bIsDown) { ImGuiInterops::SetGamepadNavigationKey(NavigationInputs, KeyEvent.GetKey(), bIsDown); }
// Change state of the navigation input associated with this gamepad axis.
// @param AnalogInputEvent - Analogue input event with gamepad axis input
// @param Value - Analogue value that should be set for this axis
void SetGamepadNavigationAxis(const FAnalogInputEvent& AnalogInputEvent, float Value) { ImGuiInterops::SetGamepadNavigationAxis(NavigationInputs, AnalogInputEvent.GetKey(), Value); }
// Check whether keyboard navigation is enabled.
bool IsKeyboardNavigationEnabled() const { return bKeyboardNavigationEnabled; }
// Set whether keyboard navigation is enabled.
// @param bEnabled - True, if navigation is enabled
void SetKeyboardNavigationEnabled(bool bEnabled) { bKeyboardNavigationEnabled = bEnabled; }
// Check whether gamepad navigation is enabled.
bool IsGamepadNavigationEnabled() const { return bGamepadNavigationEnabled; }
// Set whether gamepad navigation is enabled.
// @param bEnabled - True, if navigation is enabled
void SetGamepadNavigationEnabled(bool bEnabled) { bGamepadNavigationEnabled = bEnabled; }
// Check whether gamepad is attached.
bool HasGamepad() const { return bHasGamepad; }
// Set whether gamepad is attached.
// @param bInHasGamepad - True, if gamepad is attached
void SetGamepad(bool bInHasGamepad) { bHasGamepad = bInHasGamepad; }
// Reset the whole input state and mark it as dirty.
void Reset()
{
ResetKeyboard();
ResetMouse();
ResetGamepadNavigation();
}
// Reset the keyboard input state and mark it as dirty.
void ResetKeyboard()
{
ClearCharacters();
ClearKeys();
ClearModifierKeys();
}
// Reset the mouse input state and mark it as dirty.
void ResetMouse()
{
ClearMouseButtons();
ClearMouseAnalogue();
}
// Reset the gamepad navigation state.
void ResetGamepadNavigation()
{
ClearNavigationInputs();
}
// Clear part of the state that is meant to be updated in every frame like: accumulators, buffers, navigation data
// and information about dirty parts of keys or mouse buttons arrays.
void ClearUpdateState();
private:
void SetKeyDown(uint32 KeyIndex, bool bIsDown);
void SetMouseDown(uint32 MouseIndex, bool IsDown);
void ClearCharacters();
void ClearKeys();
void ClearMouseButtons();
void ClearMouseAnalogue();
void ClearModifierKeys();
void ClearNavigationInputs();
FVector2D MousePosition = FVector2D::ZeroVector;
FVector2D TouchPosition = FVector2D::ZeroVector;
float MouseWheelDelta = 0.f;
FMouseButtonsArray MouseButtonsDown;
FMouseButtonsIndexRange MouseButtonsUpdateRange;
FCharactersBuffer InputCharacters;
FKeysArray KeysDown;
FKeysIndexRange KeysUpdateRange;
FNavInputArray NavigationInputs;
bool bHasMousePointer = false;
bool bTouchDown = false;
bool bTouchProcessed = false;
bool bIsControlDown = false;
bool bIsShiftDown = false;
bool bIsAltDown = false;
bool bKeyboardNavigationEnabled = false;
bool bGamepadNavigationEnabled = false;
bool bHasGamepad = false;
};

View File

@ -0,0 +1,350 @@
// Distributed under the MIT License (MIT) (see accompanying LICENSE file)
#include "ImGuiInteroperability.h"
#include "ImGuiInputState.h"
#include "Utilities/Arrays.h"
// If TCHAR is wider than ImWchar, enable or disable validation of input character before conversions.
#define VALIDATE_INPUT_CHARACTERS 1
#if VALIDATE_INPUT_CHARACTERS
DEFINE_LOG_CATEGORY_STATIC(LogImGuiInput, Warning, All);
#endif
namespace
{
//====================================================================================================
// Character conversion
//====================================================================================================
template<typename T, std::enable_if_t<(sizeof(T) <= sizeof(ImWchar)), T>* = nullptr>
ImWchar CastInputChar(T Char)
{
return static_cast<ImWchar>(Char);
}
template<typename T, std::enable_if_t<!(sizeof(T) <= sizeof(ImWchar)), T>* = nullptr>
ImWchar CastInputChar(T Char)
{
#if VALIDATE_INPUT_CHARACTERS
// We only need a runtime validation if TCHAR is wider than ImWchar.
// Signed and unsigned integral types with the same size as ImWchar should be safely converted. As long as the
// char value is in that range we can safely use it, otherwise we should log an error to notify about possible
// truncations.
static constexpr auto MinLimit = (std::numeric_limits<std::make_signed_t<ImWchar>>::min)();
static constexpr auto MaxLimit = (std::numeric_limits<std::make_unsigned_t<ImWchar>>::max)();
UE_CLOG(!(Char >= MinLimit && Char <= MaxLimit), LogImGuiInput, Error,
TEXT("TCHAR value '%c' (%#x) is out of range %d (%#x) to %u (%#x) that can be safely converted to ImWchar. ")
TEXT("If you wish to disable this validation, please set VALIDATE_INPUT_CHARACTERS in ImGuiInputState.cpp to 0."),
Char, Char, MinLimit, MinLimit, MaxLimit, MaxLimit);
#endif
return static_cast<ImWchar>(Char);
}
//====================================================================================================
// Copying Utilities
//====================================================================================================
// Copy all elements from source to destination array of the same size.
template<typename TArray>
void Copy(const TArray& Src, TArray& Dst)
{
using std::copy;
using std::begin;
using std::end;
copy(begin(Src), end(Src), begin(Dst));
}
// Copy subrange of source array to destination array of the same size.
template<typename TArray, typename SizeType>
void Copy(const TArray& Src, TArray& Dst, const Utilities::TArrayIndexRange<TArray, SizeType>& Range)
{
using std::copy;
using std::begin;
copy(begin(Src) + Range.GetBegin(), begin(Src) + Range.GetEnd(), begin(Dst) + Range.GetBegin());
}
// Copy number of elements from the beginning of source array to the beginning of destination array of the same size.
template<typename TArray, typename SizeType>
void Copy(const TArray& Src, TArray& Dst, SizeType Count)
{
checkf(Count < Utilities::ArraySize<TArray>::value, TEXT("Number of copied elements is larger than array size."));
using std::copy;
using std::begin;
copy(begin(Src), begin(Src) + Count, begin(Dst));
}
}
namespace ImGuiInterops
{
//====================================================================================================
// Input Mapping
//====================================================================================================
void SetUnrealKeyMap(ImGuiIO& IO)
{
struct FUnrealToImGuiMapping
{
FUnrealToImGuiMapping()
{
KeyMap[ImGuiKey_Tab] = GetKeyIndex(EKeys::Tab);
KeyMap[ImGuiKey_LeftArrow] = GetKeyIndex(EKeys::Left);
KeyMap[ImGuiKey_RightArrow] = GetKeyIndex(EKeys::Right);
KeyMap[ImGuiKey_UpArrow] = GetKeyIndex(EKeys::Up);
KeyMap[ImGuiKey_DownArrow] = GetKeyIndex(EKeys::Down);
KeyMap[ImGuiKey_PageUp] = GetKeyIndex(EKeys::PageUp);
KeyMap[ImGuiKey_PageDown] = GetKeyIndex(EKeys::PageDown);
KeyMap[ImGuiKey_Home] = GetKeyIndex(EKeys::Home);
KeyMap[ImGuiKey_End] = GetKeyIndex(EKeys::End);
KeyMap[ImGuiKey_Insert] = GetKeyIndex(EKeys::Insert);
KeyMap[ImGuiKey_Delete] = GetKeyIndex(EKeys::Delete);
KeyMap[ImGuiKey_Backspace] = GetKeyIndex(EKeys::BackSpace);
KeyMap[ImGuiKey_Space] = GetKeyIndex(EKeys::SpaceBar);
KeyMap[ImGuiKey_Enter] = GetKeyIndex(EKeys::Enter);
KeyMap[ImGuiKey_Escape] = GetKeyIndex(EKeys::Escape);
KeyMap[ImGuiKey_A] = GetKeyIndex(EKeys::A);
KeyMap[ImGuiKey_C] = GetKeyIndex(EKeys::C);
KeyMap[ImGuiKey_V] = GetKeyIndex(EKeys::V);
KeyMap[ImGuiKey_X] = GetKeyIndex(EKeys::X);
KeyMap[ImGuiKey_Y] = GetKeyIndex(EKeys::Y);
KeyMap[ImGuiKey_Z] = GetKeyIndex(EKeys::Z);
}
ImGuiTypes::FKeyMap KeyMap;
};
static const FUnrealToImGuiMapping Mapping;
Copy(Mapping.KeyMap, IO.KeyMap);
}
// Simple transform mapping key codes to 0-511 range used in ImGui.
// From what I can tell, on most supported platforms key codes should comfortably fit in that range anyway
// but the SDL key-codes used on Linux can go way out of this range (because of the extra flag). However,
// after this transform they should fit in the range without conflicts.
// NOTE: Should any of the platforms have other conflicts or any trouble with inputs, this is the likely
// candidate for change.
static uint32 MapKeyCode(uint32 KeyCode)
{
return (KeyCode < 512) ? KeyCode : 256 + (KeyCode % 256);
}
uint32 GetKeyIndex(const FKey& Key)
{
const uint32* pKeyCode = nullptr;
const uint32* pCharCode = nullptr;
FInputKeyManager::Get().GetCodesFromKey(Key, pKeyCode, pCharCode);
const uint32 KeyCode =
pKeyCode ? *pKeyCode
: pCharCode ? *pCharCode
: 0;
return MapKeyCode(KeyCode);
}
uint32 GetKeyIndex(const FKeyEvent& KeyEvent)
{
return MapKeyCode(KeyEvent.GetKeyCode());
}
uint32 GetMouseIndex(const FKey& MouseButton)
{
if (MouseButton == EKeys::LeftMouseButton)
{
return 0;
}
else if (MouseButton == EKeys::MiddleMouseButton)
{
return 2;
}
else if (MouseButton == EKeys::RightMouseButton)
{
return 1;
}
else if (MouseButton == EKeys::ThumbMouseButton)
{
return 3;
}
else if (MouseButton == EKeys::ThumbMouseButton2)
{
return 4;
}
return -1;
}
EMouseCursor::Type ToSlateMouseCursor(ImGuiMouseCursor MouseCursor)
{
switch (MouseCursor)
{
case ImGuiMouseCursor_Arrow:
return EMouseCursor::Default;
case ImGuiMouseCursor_TextInput:
return EMouseCursor::TextEditBeam;
case ImGuiMouseCursor_ResizeAll:
return EMouseCursor::CardinalCross;
case ImGuiMouseCursor_ResizeNS:
return EMouseCursor::ResizeUpDown;
case ImGuiMouseCursor_ResizeEW:
return EMouseCursor::ResizeLeftRight;
case ImGuiMouseCursor_ResizeNESW:
return EMouseCursor::ResizeSouthWest;
case ImGuiMouseCursor_ResizeNWSE:
return EMouseCursor::ResizeSouthEast;
case ImGuiMouseCursor_None:
default:
return EMouseCursor::None;
}
}
namespace
{
inline void UpdateKey(const FKey& Key, const FKey& KeyCondition, float& Value, bool bIsDown)
{
if (Key == KeyCondition)
{
Value = (bIsDown) ? 1.f : 0.f;
}
}
inline void UpdateAxisValues(float& Axis, float& Opposite, float Value)
{
constexpr float AxisInputThreshold = 0.166f;
// Filter out small values to avoid false positives (helpful in case of worn controllers).
Axis = FMath::Max(0.f, Value - AxisInputThreshold);
Opposite = 0.f;
}
inline void UpdateSymmetricAxis(const FKey& Key, const FKey& KeyCondition, float& Negative, float& Positive, float Value)
{
if (Key == KeyCondition)
{
if (Value < 0.f)
{
UpdateAxisValues(Negative, Positive, -Value);
}
else
{
UpdateAxisValues(Positive, Negative, Value);
}
}
}
}
void SetGamepadNavigationKey(ImGuiTypes::FNavInputArray& NavInputs, const FKey& Key, bool bIsDown)
{
#define MAP_KEY(KeyCondition, NavIndex) UpdateKey(Key, KeyCondition, NavInputs[NavIndex], bIsDown)
if (Key.IsGamepadKey())
{
MAP_KEY(EKeys::Gamepad_FaceButton_Bottom, ImGuiNavInput_Activate);
MAP_KEY(EKeys::Gamepad_FaceButton_Right, ImGuiNavInput_Cancel);
MAP_KEY(EKeys::Gamepad_FaceButton_Top, ImGuiNavInput_Input);
MAP_KEY(EKeys::Gamepad_FaceButton_Left, ImGuiNavInput_Menu);
MAP_KEY(EKeys::Gamepad_DPad_Left, ImGuiNavInput_DpadLeft);
MAP_KEY(EKeys::Gamepad_DPad_Right, ImGuiNavInput_DpadRight);
MAP_KEY(EKeys::Gamepad_DPad_Up, ImGuiNavInput_DpadUp);
MAP_KEY(EKeys::Gamepad_DPad_Down, ImGuiNavInput_DpadDown);
MAP_KEY(EKeys::Gamepad_LeftShoulder, ImGuiNavInput_FocusPrev);
MAP_KEY(EKeys::Gamepad_RightShoulder, ImGuiNavInput_FocusNext);
MAP_KEY(EKeys::Gamepad_LeftShoulder, ImGuiNavInput_TweakSlow);
MAP_KEY(EKeys::Gamepad_RightShoulder, ImGuiNavInput_TweakFast);
}
#undef MAP_KEY
}
void SetGamepadNavigationAxis(ImGuiTypes::FNavInputArray& NavInputs, const FKey& Key, float Value)
{
#define MAP_SYMMETRIC_AXIS(KeyCondition, NegNavIndex, PosNavIndex) UpdateSymmetricAxis(Key, KeyCondition, NavInputs[NegNavIndex], NavInputs[PosNavIndex], Value)
if (Key.IsGamepadKey())
{
MAP_SYMMETRIC_AXIS(EKeys::Gamepad_LeftX, ImGuiNavInput_LStickLeft, ImGuiNavInput_LStickRight);
MAP_SYMMETRIC_AXIS(EKeys::Gamepad_LeftY, ImGuiNavInput_LStickDown, ImGuiNavInput_LStickUp);
}
#undef MAP_SYMMETRIC_AXIS
}
//====================================================================================================
// Input State Copying
//====================================================================================================
template<typename TFlags, typename TFlag>
static inline constexpr void SetFlag(TFlags& Flags, TFlag Flag, bool bSet)
{
Flags = bSet ? Flags | Flag : Flags & ~Flag;
}
void CopyInput(ImGuiIO& IO, const FImGuiInputState& InputState)
{
static const uint32 LeftControl = GetKeyIndex(EKeys::LeftControl);
static const uint32 RightControl = GetKeyIndex(EKeys::RightControl);
static const uint32 LeftShift = GetKeyIndex(EKeys::LeftShift);
static const uint32 RightShift = GetKeyIndex(EKeys::RightShift);
static const uint32 LeftAlt = GetKeyIndex(EKeys::LeftAlt);
static const uint32 RightAlt = GetKeyIndex(EKeys::RightAlt);
// Copy key modifiers.
IO.KeyCtrl = InputState.IsControlDown();
IO.KeyShift = InputState.IsShiftDown();
IO.KeyAlt = InputState.IsAltDown();
IO.KeySuper = false;
// Copy buffers.
if (!InputState.GetKeysUpdateRange().IsEmpty())
{
Copy(InputState.GetKeys(), IO.KeysDown, InputState.GetKeysUpdateRange());
}
if (!InputState.GetMouseButtonsUpdateRange().IsEmpty())
{
Copy(InputState.GetMouseButtons(), IO.MouseDown, InputState.GetMouseButtonsUpdateRange());
}
for (const TCHAR Char : InputState.GetCharacters())
{
IO.AddInputCharacter(CastInputChar(Char));
}
if (InputState.IsGamepadNavigationEnabled() && InputState.HasGamepad())
{
Copy(InputState.GetNavigationInputs(), IO.NavInputs);
}
SetFlag(IO.ConfigFlags, ImGuiConfigFlags_NavEnableKeyboard, InputState.IsKeyboardNavigationEnabled());
SetFlag(IO.ConfigFlags, ImGuiConfigFlags_NavEnableGamepad, InputState.IsGamepadNavigationEnabled());
SetFlag(IO.BackendFlags, ImGuiBackendFlags_HasGamepad, InputState.HasGamepad());
// Check whether we need to draw cursor.
IO.MouseDrawCursor = InputState.HasMousePointer();
// If touch is enabled and active, give it a precedence.
if (InputState.IsTouchActive())
{
// Copy the touch position to mouse position.
IO.MousePos.x = InputState.GetTouchPosition().X;
IO.MousePos.y = InputState.GetTouchPosition().Y;
// With touch active one frame longer than it is down, we have one frame to processed touch up.
IO.MouseDown[0] = InputState.IsTouchDown();
}
else
{
// Copy the mouse position.
IO.MousePos.x = InputState.GetMousePosition().X;
IO.MousePos.y = InputState.GetMousePosition().Y;
// Copy mouse wheel delta.
IO.MouseWheel += InputState.GetMouseWheelDelta();
}
}
}

View File

@ -0,0 +1,115 @@
// Distributed under the MIT License (MIT) (see accompanying LICENSE file)
#pragma once
#include "TextureManager.h"
#include <GenericPlatform/ICursor.h>
#include <Input/Events.h>
#include <imgui.h>
class FImGuiInputState;
// Utilities to help standardise operations between Unreal and ImGui.
namespace ImGuiInterops
{
//====================================================================================================
// ImGui Types
//====================================================================================================
namespace ImGuiTypes
{
using FMouseButtonsArray = decltype(ImGuiIO::MouseDown);
using FKeysArray = decltype(ImGuiIO::KeysDown);
using FNavInputArray = decltype(ImGuiIO::NavInputs);
using FKeyMap = decltype(ImGuiIO::KeyMap);
}
//====================================================================================================
// Input Mapping
//====================================================================================================
// Set in ImGui IO mapping to recognize indices generated from Unreal input events.
void SetUnrealKeyMap(ImGuiIO& IO);
// Map FKey to index in keys buffer.
uint32 GetKeyIndex(const FKey& Key);
// Map key event to index in keys buffer.
uint32 GetKeyIndex(const FKeyEvent& KeyEvent);
// Map mouse FKey to index in mouse buttons buffer.
uint32 GetMouseIndex(const FKey& MouseButton);
// Map pointer event to index in mouse buttons buffer.
FORCEINLINE uint32 GetMouseIndex(const FPointerEvent& MouseEvent)
{
return GetMouseIndex(MouseEvent.GetEffectingButton());
}
// Convert from ImGuiMouseCursor type to EMouseCursor.
EMouseCursor::Type ToSlateMouseCursor(ImGuiMouseCursor MouseCursor);
// Set in the target array navigation input corresponding to gamepad key.
// @param NavInputs - Target array
// @param Key - Gamepad key mapped to navigation input (non-mapped keys will be ignored)
// @param bIsDown - True, if key is down
void SetGamepadNavigationKey(ImGuiTypes::FNavInputArray& NavInputs, const FKey& Key, bool bIsDown);
// Set in the target array navigation input corresponding to gamepad axis.
// @param NavInputs - Target array
// @param Key - Gamepad axis key mapped to navigation input (non-axis or non-mapped inputs will be ignored)
// @param Value - Axis value (-1..1 values from Unreal are mapped to separate ImGui axes with values in range 0..1)
void SetGamepadNavigationAxis(ImGuiTypes::FNavInputArray& NavInputs, const FKey& Key, float Value);
//====================================================================================================
// Input State Copying
//====================================================================================================
// Copy input to ImGui IO.
// @param IO - Target ImGui IO
// @param InputState - Input state to copy
void CopyInput(ImGuiIO& IO, const FImGuiInputState& InputState);
//====================================================================================================
// Conversions
//====================================================================================================
// Convert from ImGui packed color to FColor.
FORCEINLINE FColor UnpackImU32Color(ImU32 Color)
{
// We use IM_COL32_R/G/B/A_SHIFT macros to support different ImGui configurations.
return FColor{ (uint8)((Color >> IM_COL32_R_SHIFT) & 0xFF), (uint8)((Color >> IM_COL32_G_SHIFT) & 0xFF),
(uint8)((Color >> IM_COL32_B_SHIFT) & 0xFF), (uint8)((Color >> IM_COL32_A_SHIFT) & 0xFF) };
}
// Convert from ImVec4 rectangle to FSlateRect.
FORCEINLINE FSlateRect ToSlateRect(const ImVec4& ImGuiRect)
{
return FSlateRect{ ImGuiRect.x, ImGuiRect.y, ImGuiRect.z, ImGuiRect.w };
}
// Convert from ImVec2 rectangle to FVector2D.
FORCEINLINE FVector2D ToVector2D(const ImVec2& ImGuiVector)
{
return FVector2D{ ImGuiVector.x, ImGuiVector.y };
}
// Convert from ImGui Texture Id to Texture Index that we use for texture resources.
FORCEINLINE TextureIndex ToTextureIndex(ImTextureID Index)
{
return static_cast<TextureIndex>(reinterpret_cast<intptr_t>(Index));
}
// Convert from Texture Index to ImGui Texture Id that we pass to ImGui.
FORCEINLINE ImTextureID ToImTextureID(TextureIndex Index)
{
return reinterpret_cast<ImTextureID>(static_cast<intptr_t>(Index));
}
}

View File

@ -0,0 +1,310 @@
// Distributed under the MIT License (MIT) (see accompanying LICENSE file)
#include "ImGuiModule.h"
#include "ImGuiDelegatesContainer.h"
#include "ImGuiModuleManager.h"
#include "TextureManager.h"
#include "Utilities/WorldContext.h"
#include "Utilities/WorldContextIndex.h"
#if WITH_EDITOR
#include "ImGuiImplementation.h"
#include "Editor/ImGuiEditor.h"
#endif
#include <Interfaces/IPluginManager.h>
#define LOCTEXT_NAMESPACE "FImGuiModule"
struct EDelegateCategory
{
enum
{
// Default per-context draw events.
Default,
// Multi-context draw event defined in context manager.
MultiContext
};
};
FImGuiModuleManager* ImGuiModuleManager = nullptr;
#if WITH_EDITOR
static FImGuiEditor* ImGuiEditor = nullptr;
#endif
#if IMGUI_WITH_OBSOLETE_DELEGATES
#if WITH_EDITOR
FImGuiDelegateHandle FImGuiModule::AddEditorImGuiDelegate(const FImGuiDelegate& Delegate)
{
return { FImGuiDelegatesContainer::Get().OnWorldDebug(Utilities::EDITOR_CONTEXT_INDEX).Add(Delegate),
EDelegateCategory::Default, Utilities::EDITOR_CONTEXT_INDEX };
}
#endif
FImGuiDelegateHandle FImGuiModule::AddWorldImGuiDelegate(const FImGuiDelegate& Delegate)
{
const int32 ContextIndex = Utilities::GetWorldContextIndex((UWorld*)GWorld);
return { FImGuiDelegatesContainer::Get().OnWorldDebug(ContextIndex).Add(Delegate), EDelegateCategory::Default, ContextIndex };
}
FImGuiDelegateHandle FImGuiModule::AddMultiContextImGuiDelegate(const FImGuiDelegate& Delegate)
{
return { FImGuiDelegatesContainer::Get().OnMultiContextDebug().Add(Delegate), EDelegateCategory::MultiContext };
}
void FImGuiModule::RemoveImGuiDelegate(const FImGuiDelegateHandle& Handle)
{
if (Handle.Category == EDelegateCategory::MultiContext)
{
FImGuiDelegatesContainer::Get().OnMultiContextDebug().Remove(Handle.Handle);
}
else
{
FImGuiDelegatesContainer::Get().OnWorldDebug(Handle.Index).Remove(Handle.Handle);
}
}
#endif // IMGUI_WITH_OBSOLETE_DELEGATES
FImGuiTextureHandle FImGuiModule::FindTextureHandle(const FName& Name)
{
const TextureIndex Index = ImGuiModuleManager->GetTextureManager().FindTextureIndex(Name);
return (Index != INDEX_NONE) ? FImGuiTextureHandle{ Name, ImGuiInterops::ToImTextureID(Index) } : FImGuiTextureHandle{};
}
FImGuiTextureHandle FImGuiModule::RegisterTexture(const FName& Name, class UTexture2D* Texture, bool bMakeUnique)
{
FTextureManager& TextureManager = ImGuiModuleManager->GetTextureManager();
checkf(!bMakeUnique || TextureManager.FindTextureIndex(Name) == INDEX_NONE,
TEXT("Trying to register a texture with a name '%s' that is already used. Chose a different name ")
TEXT("or use bMakeUnique false, to update existing texture resources."), *Name.ToString());
const TextureIndex Index = TextureManager.CreateTextureResources(Name, Texture);
return FImGuiTextureHandle{ Name, ImGuiInterops::ToImTextureID(Index) };
}
void FImGuiModule::ReleaseTexture(const FImGuiTextureHandle& Handle)
{
if (Handle.IsValid())
{
ImGuiModuleManager->GetTextureManager().ReleaseTextureResources(ImGuiInterops::ToTextureIndex(Handle.GetTextureId()));
}
}
void FImGuiModule::StartupModule()
{
// Initialize handles to allow cross-module redirections. Other handles will always look for parents in the active
// module, which means that we can only redirect to started modules. We don't have to worry about self-referencing
// as local handles are guaranteed to be constructed before initializing pointers.
// This supports in-editor recompilation and hot-reloading after compiling from the command line. The latter method
// theoretically doesn't support plug-ins and will not load re-compiled module, but its handles will still redirect
// to the active one.
#if WITH_EDITOR
ImGuiContextHandle = &ImGuiImplementation::GetContextHandle();
DelegatesContainerHandle = &FImGuiDelegatesContainer::GetHandle();
#endif
// Create managers that implements module logic.
checkf(!ImGuiModuleManager, TEXT("Instance of the ImGui Module Manager already exists. Instance should be created only during module startup."));
ImGuiModuleManager = new FImGuiModuleManager();
#if WITH_EDITOR
checkf(!ImGuiEditor, TEXT("Instance of the ImGui Editor already exists. Instance should be created only during module startup."));
ImGuiEditor = new FImGuiEditor();
#endif
}
void FImGuiModule::ShutdownModule()
{
// In editor store data that we want to move to hot-reloaded module.
#if WITH_EDITOR
static bool bMoveProperties = true;
static FImGuiModuleProperties PropertiesToMove = ImGuiModuleManager->GetProperties();
#endif
// Before we shutdown we need to delete managers that will do all the necessary cleanup.
#if WITH_EDITOR
checkf(ImGuiEditor, TEXT("Null ImGui Editor. ImGui editor instance should be deleted during module shutdown."));
delete ImGuiEditor;
ImGuiEditor = nullptr;
#endif
checkf(ImGuiModuleManager, TEXT("Null ImGui Module Manager. Module manager instance should be deleted during module shutdown."));
delete ImGuiModuleManager;
ImGuiModuleManager = nullptr;
#if WITH_EDITOR
// When shutting down we leave the global ImGui context pointer and handle pointing to resources that are already
// deleted. This can cause troubles after hot-reload when code in other modules calls ImGui interface functions
// which are statically bound to the obsolete module. To keep ImGui code functional we can redirect context handle
// to point to the new module.
// When shutting down during hot-reloading, we might want to rewire handles used in statically bound functions
// or move data to a new module.
FModuleManager::Get().OnModulesChanged().AddLambda([this] (FName Name, EModuleChangeReason Reason)
{
if (Reason == EModuleChangeReason::ModuleLoaded && Name == "ImGui")
{
FImGuiModule& LoadedModule = FImGuiModule::Get();
if (&LoadedModule != this)
{
// Statically bound functions can be bound to the obsolete module, so we need to manually redirect.
if (LoadedModule.ImGuiContextHandle)
{
ImGuiImplementation::SetParentContextHandle(*LoadedModule.ImGuiContextHandle);
}
if (LoadedModule.DelegatesContainerHandle)
{
FImGuiDelegatesContainer::MoveContainer(*LoadedModule.DelegatesContainerHandle);
}
if (bMoveProperties)
{
bMoveProperties = false;
LoadedModule.SetProperties(PropertiesToMove);
}
}
}
});
#endif // WITH_EDITOR
}
#if WITH_EDITOR
void FImGuiModule::SetProperties(const FImGuiModuleProperties& Properties)
{
ImGuiModuleManager->GetProperties() = Properties;
}
#endif
FImGuiModuleProperties& FImGuiModule::GetProperties()
{
return ImGuiModuleManager->GetProperties();
}
const FImGuiModuleProperties& FImGuiModule::GetProperties() const
{
return ImGuiModuleManager->GetProperties();
}
bool FImGuiModule::IsInputMode() const
{
return ImGuiModuleManager && ImGuiModuleManager->GetProperties().IsInputEnabled();
}
void FImGuiModule::SetInputMode(bool bEnabled)
{
if (ImGuiModuleManager)
{
ImGuiModuleManager->GetProperties().SetInputEnabled(bEnabled);
}
}
void FImGuiModule::ToggleInputMode()
{
if (ImGuiModuleManager)
{
ImGuiModuleManager->GetProperties().ToggleInput();
}
}
bool FImGuiModule::IsShowingDemo() const
{
return ImGuiModuleManager && ImGuiModuleManager->GetProperties().ShowDemo();
}
void FImGuiModule::SetShowDemo(bool bShow)
{
if (ImGuiModuleManager)
{
ImGuiModuleManager->GetProperties().SetShowDemo(bShow);
}
}
void FImGuiModule::ToggleShowDemo()
{
if (ImGuiModuleManager)
{
ImGuiModuleManager->GetProperties().ToggleDemo();
}
}
//----------------------------------------------------------------------------------------------------
// Runtime loader
//----------------------------------------------------------------------------------------------------
#if !WITH_EDITOR && RUNTIME_LOADER_ENABLED
class FImGuiModuleLoader
{
FImGuiModuleLoader()
{
if (!Load())
{
FModuleManager::Get().OnModulesChanged().AddRaw(this, &FImGuiModuleLoader::LoadAndRelease);
}
}
// For different engine versions.
static FORCEINLINE bool IsValid(const TSharedPtr<IModuleInterface>& Ptr) { return Ptr.IsValid(); }
static FORCEINLINE bool IsValid(const IModuleInterface* const Ptr) { return Ptr != nullptr; }
bool Load()
{
return IsValid(FModuleManager::Get().LoadModule(ModuleName));
}
void LoadAndRelease(FName Name, EModuleChangeReason Reason)
{
// Avoid handling own load event.
if (Name != ModuleName)
{
// Try loading until success and then release.
if (Load())
{
FModuleManager::Get().OnModulesChanged().RemoveAll(this);
}
}
}
static FName ModuleName;
static FImGuiModuleLoader Instance;
};
FName FImGuiModuleLoader::ModuleName = "ImGui";
// In monolithic builds this will start loading process.
FImGuiModuleLoader FImGuiModuleLoader::Instance;
#endif // !WITH_EDITOR && RUNTIME_LOADER_ENABLED
//----------------------------------------------------------------------------------------------------
// Partial implementations of other classes that needs access to ImGuiModuleManager
//----------------------------------------------------------------------------------------------------
bool FImGuiTextureHandle::HasValidEntry() const
{
const TextureIndex Index = ImGuiInterops::ToTextureIndex(TextureId);
return Index != INDEX_NONE && ImGuiModuleManager && ImGuiModuleManager->GetTextureManager().GetTextureName(Index) == Name;
}
#undef LOCTEXT_NAMESPACE
IMPLEMENT_MODULE(FImGuiModule, ImGui)

View File

@ -0,0 +1,81 @@
// Distributed under the MIT License (MIT) (see accompanying LICENSE file)
#include "ImGuiModuleCommands.h"
#include "ImGuiModuleProperties.h"
#include "Utilities/DebugExecBindings.h"
const TCHAR* const FImGuiModuleCommands::ToggleInput = TEXT("ImGui.ToggleInput");
const TCHAR* const FImGuiModuleCommands::ToggleKeyboardNavigation = TEXT("ImGui.ToggleKeyboardNavigation");
const TCHAR* const FImGuiModuleCommands::ToggleGamepadNavigation = TEXT("ImGui.ToggleGamepadNavigation");
const TCHAR* const FImGuiModuleCommands::ToggleKeyboardInputSharing = TEXT("ImGui.ToggleKeyboardInputSharing");
const TCHAR* const FImGuiModuleCommands::ToggleGamepadInputSharing = TEXT("ImGui.ToggleGamepadInputSharing");
const TCHAR* const FImGuiModuleCommands::ToggleMouseInputSharing = TEXT("ImGui.ToggleMouseInputSharing");
const TCHAR* const FImGuiModuleCommands::ToggleDemo = TEXT("ImGui.ToggleDemo");
FImGuiModuleCommands::FImGuiModuleCommands(FImGuiModuleProperties& InProperties)
: Properties(InProperties)
, ToggleInputCommand(ToggleInput,
TEXT("Toggle ImGui input mode."),
FConsoleCommandDelegate::CreateRaw(this, &FImGuiModuleCommands::ToggleInputImpl))
, ToggleKeyboardNavigationCommand(ToggleKeyboardNavigation,
TEXT("Toggle ImGui keyboard navigation."),
FConsoleCommandDelegate::CreateRaw(this, &FImGuiModuleCommands::ToggleKeyboardNavigationImpl))
, ToggleGamepadNavigationCommand(ToggleGamepadNavigation,
TEXT("Toggle ImGui gamepad navigation."),
FConsoleCommandDelegate::CreateRaw(this, &FImGuiModuleCommands::ToggleGamepadNavigationImpl))
, ToggleKeyboardInputSharingCommand(ToggleKeyboardInputSharing,
TEXT("Toggle ImGui keyboard input sharing."),
FConsoleCommandDelegate::CreateRaw(this, &FImGuiModuleCommands::ToggleKeyboardInputSharingImpl))
, ToggleGamepadInputSharingCommand(ToggleGamepadInputSharing,
TEXT("Toggle ImGui gamepad input sharing."),
FConsoleCommandDelegate::CreateRaw(this, &FImGuiModuleCommands::ToggleGamepadInputSharingImpl))
, ToggleMouseInputSharingCommand(ToggleMouseInputSharing,
TEXT("Toggle ImGui mouse input sharing."),
FConsoleCommandDelegate::CreateRaw(this, &FImGuiModuleCommands::ToggleMouseInputSharingImpl))
, ToggleDemoCommand(ToggleDemo,
TEXT("Toggle ImGui demo."),
FConsoleCommandDelegate::CreateRaw(this, &FImGuiModuleCommands::ToggleDemoImpl))
{
}
void FImGuiModuleCommands::SetKeyBinding(const TCHAR* CommandName, const FImGuiKeyInfo& KeyInfo)
{
DebugExecBindings::UpdatePlayerInputs(KeyInfo, CommandName);
}
void FImGuiModuleCommands::ToggleInputImpl()
{
Properties.ToggleInput();
}
void FImGuiModuleCommands::ToggleKeyboardNavigationImpl()
{
Properties.ToggleKeyboardNavigation();
}
void FImGuiModuleCommands::ToggleGamepadNavigationImpl()
{
Properties.ToggleGamepadNavigation();
}
void FImGuiModuleCommands::ToggleKeyboardInputSharingImpl()
{
Properties.ToggleKeyboardInputSharing();
}
void FImGuiModuleCommands::ToggleGamepadInputSharingImpl()
{
Properties.ToggleGamepadInputSharing();
}
void FImGuiModuleCommands::ToggleMouseInputSharingImpl()
{
Properties.ToggleMouseInputSharing();
}
void FImGuiModuleCommands::ToggleDemoImpl()
{
Properties.ToggleDemo();
}

View File

@ -0,0 +1,47 @@
// Distributed under the MIT License (MIT) (see accompanying LICENSE file)
#pragma once
#include <HAL/IConsoleManager.h>
struct FImGuiKeyInfo;
class FImGuiModuleProperties;
// Manges ImGui module console commands.
class FImGuiModuleCommands
{
public:
static const TCHAR* const ToggleInput;
static const TCHAR* const ToggleKeyboardNavigation;
static const TCHAR* const ToggleGamepadNavigation;
static const TCHAR* const ToggleKeyboardInputSharing;
static const TCHAR* const ToggleGamepadInputSharing;
static const TCHAR* const ToggleMouseInputSharing;
static const TCHAR* const ToggleDemo;
FImGuiModuleCommands(FImGuiModuleProperties& InProperties);
void SetKeyBinding(const TCHAR* CommandName, const FImGuiKeyInfo& KeyInfo);
private:
void ToggleInputImpl();
void ToggleKeyboardNavigationImpl();
void ToggleGamepadNavigationImpl();
void ToggleKeyboardInputSharingImpl();
void ToggleGamepadInputSharingImpl();
void ToggleMouseInputSharingImpl();
void ToggleDemoImpl();
FImGuiModuleProperties& Properties;
FAutoConsoleCommand ToggleInputCommand;
FAutoConsoleCommand ToggleKeyboardNavigationCommand;
FAutoConsoleCommand ToggleGamepadNavigationCommand;
FAutoConsoleCommand ToggleKeyboardInputSharingCommand;
FAutoConsoleCommand ToggleGamepadInputSharingCommand;
FAutoConsoleCommand ToggleMouseInputSharingCommand;
FAutoConsoleCommand ToggleDemoCommand;
};

View File

@ -0,0 +1,16 @@
// Distributed under the MIT License (MIT) (see accompanying LICENSE file)
#pragma once
#include <Logging/LogMacros.h>
// Module-wide debug symbols and loggers.
// If enabled, it activates debug code and console variables that in normal usage are hidden.
#define IMGUI_MODULE_DEVELOPER 0
// Input Handler logger (used also in non-developer mode to raise problems with handler extensions).
DECLARE_LOG_CATEGORY_EXTERN(LogImGuiInputHandler, Warning, All);

View File

@ -0,0 +1,235 @@
// Distributed under the MIT License (MIT) (see accompanying LICENSE file)
#include "ImGuiModuleManager.h"
#include "ImGuiInteroperability.h"
#include "Utilities/WorldContextIndex.h"
#include <Framework/Application/SlateApplication.h>
#include <Modules/ModuleManager.h>
#include <imgui.h>
// High enough z-order guarantees that ImGui output is rendered on top of the game UI.
constexpr int32 IMGUI_WIDGET_Z_ORDER = 10000;
// Module texture names.
const static FName PlainTextureName = "ImGuiModule_Plain";
const static FName FontAtlasTextureName = "ImGuiModule_FontAtlas";
FImGuiModuleManager::FImGuiModuleManager()
: Commands(Properties)
, Settings(Properties, Commands)
, ImGuiDemo(Properties)
, ContextManager(Settings)
{
// Register in context manager to get information whenever a new context proxy is created.
ContextManager.OnContextProxyCreated.AddRaw(this, &FImGuiModuleManager::OnContextProxyCreated);
// Typically we will use viewport created events to add widget to new game viewports.
ViewportCreatedHandle = UGameViewportClient::OnViewportCreated().AddRaw(this, &FImGuiModuleManager::OnViewportCreated);
// Try to register tick delegate (it may fail if Slate application isn't yet ready).
RegisterTick();
// If we failed to register, create an initializer that will do it later.
if (!IsTickRegistered())
{
CreateTickInitializer();
}
// We need to add widgets to active game viewports as they won't generate on-created events. This is especially
// important during hot-reloading.
AddWidgetsToActiveViewports();
}
FImGuiModuleManager::~FImGuiModuleManager()
{
ContextManager.OnFontAtlasBuilt.RemoveAll(this);
// We are no longer interested with adding widgets to viewports.
if (ViewportCreatedHandle.IsValid())
{
UGameViewportClient::OnViewportCreated().Remove(ViewportCreatedHandle);
ViewportCreatedHandle.Reset();
}
// Remove still active widgets (important during hot-reloading).
for (auto& Widget : Widgets)
{
auto SharedWidget = Widget.Pin();
if (SharedWidget.IsValid())
{
auto& WidgetGameViewport = SharedWidget->GetGameViewport();
if (WidgetGameViewport.IsValid())
{
WidgetGameViewport->RemoveViewportWidgetContent(SharedWidget.ToSharedRef());
}
}
}
// Deactivate this manager.
ReleaseTickInitializer();
UnregisterTick();
}
void FImGuiModuleManager::LoadTextures()
{
checkf(FSlateApplication::IsInitialized(), TEXT("Slate should be initialized before we can create textures."));
if (!bTexturesLoaded)
{
bTexturesLoaded = true;
TextureManager.InitializeErrorTexture(FColor::Magenta);
// Create an empty texture at index 0. We will use it for ImGui outputs with null texture id.
TextureManager.CreatePlainTexture(PlainTextureName, 2, 2, FColor::White);
// Register for atlas built events, so we can rebuild textures.
ContextManager.OnFontAtlasBuilt.AddRaw(this, &FImGuiModuleManager::BuildFontAtlasTexture);
BuildFontAtlasTexture();
}
}
void FImGuiModuleManager::BuildFontAtlasTexture()
{
// Create a font atlas texture.
ImFontAtlas& Fonts = ContextManager.GetFontAtlas();
unsigned char* Pixels;
int Width, Height, Bpp;
Fonts.GetTexDataAsRGBA32(&Pixels, &Width, &Height, &Bpp);
const TextureIndex FontsTexureIndex = TextureManager.CreateTexture(FontAtlasTextureName, Width, Height, Bpp, Pixels);
// Set the font texture index in the ImGui.
Fonts.TexID = ImGuiInterops::ToImTextureID(FontsTexureIndex);
}
void FImGuiModuleManager::RegisterTick()
{
// Slate Post-Tick is a good moment to end and advance ImGui frame as it minimises a tearing.
if (!TickDelegateHandle.IsValid() && FSlateApplication::IsInitialized())
{
TickDelegateHandle = FSlateApplication::Get().OnPostTick().AddRaw(this, &FImGuiModuleManager::Tick);
}
}
void FImGuiModuleManager::UnregisterTick()
{
if (TickDelegateHandle.IsValid())
{
if (FSlateApplication::IsInitialized())
{
FSlateApplication::Get().OnPostTick().Remove(TickDelegateHandle);
}
TickDelegateHandle.Reset();
}
}
void FImGuiModuleManager::CreateTickInitializer()
{
if (!TickInitializerHandle.IsValid())
{
// Try to register tick delegate until we finally succeed.
TickInitializerHandle = FModuleManager::Get().OnModulesChanged().AddLambda([this](FName Name, EModuleChangeReason Reason)
{
if (Reason == EModuleChangeReason::ModuleLoaded)
{
RegisterTick();
}
if (IsTickRegistered())
{
ReleaseTickInitializer();
}
});
}
}
void FImGuiModuleManager::ReleaseTickInitializer()
{
if (TickInitializerHandle.IsValid())
{
FModuleManager::Get().OnModulesChanged().Remove(TickInitializerHandle);
TickInitializerHandle.Reset();
}
}
void FImGuiModuleManager::Tick(float DeltaSeconds)
{
if (IsInGameThread())
{
// Update context manager to advance all ImGui contexts to the next frame.
ContextManager.Tick(DeltaSeconds);
// Inform that we finished updating ImGui, so other subsystems can react.
PostImGuiUpdateEvent.Broadcast();
}
}
void FImGuiModuleManager::OnViewportCreated()
{
checkf(FSlateApplication::IsInitialized(), TEXT("We expect Slate to be initialized when game viewport is created."));
// Create widget to viewport responsible for this event.
AddWidgetToViewport(GEngine->GameViewport);
}
void FImGuiModuleManager::AddWidgetToViewport(UGameViewportClient* GameViewport)
{
checkf(GameViewport, TEXT("Null game viewport."));
checkf(FSlateApplication::IsInitialized(), TEXT("Slate should be initialized before we can add widget to game viewports."));
// Make sure that we have a context for this viewport's world and get its index.
int32 ContextIndex;
auto& ContextProxy = ContextManager.GetWorldContextProxy(*GameViewport->GetWorld(), ContextIndex);
// Make sure that textures are loaded before the first Slate widget is created.
LoadTextures();
// Create and initialize the widget.
TSharedPtr<SImGuiLayout> SharedWidget;
SAssignNew(SharedWidget, SImGuiLayout).ModuleManager(this).GameViewport(GameViewport).ContextIndex(ContextIndex);
GameViewport->AddViewportWidgetContent(SharedWidget.ToSharedRef(), IMGUI_WIDGET_Z_ORDER);
// We transfer widget ownerships to viewports but we keep weak references in case we need to manually detach active
// widgets during module shutdown (important during hot-reloading).
if (TWeakPtr<SImGuiLayout>* Slot = Widgets.FindByPredicate([](auto& Widget) { return !Widget.IsValid(); }))
{
*Slot = SharedWidget;
}
else
{
Widgets.Emplace(SharedWidget);
}
}
void FImGuiModuleManager::AddWidgetsToActiveViewports()
{
if (FSlateApplication::IsInitialized() && GEngine)
{
// Loop as long as we have a valid viewport or until we detect a cycle.
UGameViewportClient* GameViewport = GEngine->GameViewport;
while (GameViewport)
{
AddWidgetToViewport(GameViewport);
GameViewport = GEngine->GetNextPIEViewport(GameViewport);
if (GameViewport == GEngine->GameViewport)
{
break;
}
}
}
}
void FImGuiModuleManager::OnContextProxyCreated(int32 ContextIndex, FImGuiContextProxy& ContextProxy)
{
ContextProxy.OnDraw().AddLambda([this, ContextIndex]() { ImGuiDemo.DrawControls(ContextIndex); });
}

View File

@ -0,0 +1,96 @@
// Distributed under the MIT License (MIT) (see accompanying LICENSE file)
#pragma once
#include "ImGuiContextManager.h"
#include "ImGuiDemo.h"
#include "ImGuiModuleCommands.h"
#include "ImGuiModuleProperties.h"
#include "ImGuiModuleSettings.h"
#include "TextureManager.h"
#include "Widgets/SImGuiLayout.h"
// Central manager that implements module logic. It initializes and controls remaining module components.
class FImGuiModuleManager
{
// Allow module to control life-cycle of this class.
friend class FImGuiModule;
public:
// Get interface to module settings.
FImGuiModuleSettings& GetSettings() { return Settings; }
// Get interface to module state properties.
FImGuiModuleProperties& GetProperties() { return Properties; }
// Get ImGui contexts manager.
FImGuiContextManager& GetContextManager() { return ContextManager; }
// Get texture resources manager.
FTextureManager& GetTextureManager() { return TextureManager; }
// Event called right after ImGui is updated, to give other subsystems chance to react.
FSimpleMulticastDelegate& OnPostImGuiUpdate() { return PostImGuiUpdateEvent; }
private:
FImGuiModuleManager();
~FImGuiModuleManager();
FImGuiModuleManager(const FImGuiModuleManager&) = delete;
FImGuiModuleManager& operator=(const FImGuiModuleManager&) = delete;
FImGuiModuleManager(FImGuiModuleManager&&) = delete;
FImGuiModuleManager& operator=(FImGuiModuleManager&&) = delete;
void LoadTextures();
void BuildFontAtlasTexture();
bool IsTickRegistered() { return TickDelegateHandle.IsValid(); }
void RegisterTick();
void UnregisterTick();
void CreateTickInitializer();
void ReleaseTickInitializer();
void Tick(float DeltaSeconds);
void OnViewportCreated();
void AddWidgetToViewport(UGameViewportClient* GameViewport);
void AddWidgetsToActiveViewports();
void OnContextProxyCreated(int32 ContextIndex, FImGuiContextProxy& ContextProxy);
// Event that we call after ImGui is updated.
FSimpleMulticastDelegate PostImGuiUpdateEvent;
// Collection of module state properties.
FImGuiModuleProperties Properties;
// Tying module console commands to life-cycle of this manager and module.
FImGuiModuleCommands Commands;
// ImGui settings proxy (valid in every loading stage).
FImGuiModuleSettings Settings;
// Widget that we add to all created contexts to draw ImGui demo.
FImGuiDemo ImGuiDemo;
// Manager for ImGui contexts.
FImGuiContextManager ContextManager;
// Manager for textures resources.
FTextureManager TextureManager;
// Slate widgets that we created.
TArray<TWeakPtr<SImGuiLayout>> Widgets;
FDelegateHandle TickInitializerHandle;
FDelegateHandle TickDelegateHandle;
FDelegateHandle ViewportCreatedHandle;
bool bTexturesLoaded = false;
};

View File

@ -0,0 +1,215 @@
// Distributed under the MIT License (MIT) (see accompanying LICENSE file)
#include "ImGuiModuleSettings.h"
#include "ImGuiModuleCommands.h"
#include "ImGuiModuleProperties.h"
#include <Engine/Engine.h>
#include <GameFramework/GameUserSettings.h>
#include <Misc/ConfigCacheIni.h>
//====================================================================================================
// FImGuiDPIScaleInfo
//====================================================================================================
FImGuiDPIScaleInfo::FImGuiDPIScaleInfo()
{
if (FRichCurve* Curve = DPICurve.GetRichCurve())
{
Curve->AddKey( 0.0f, 1.f);
Curve->AddKey(2159.5f, 1.f);
Curve->AddKey(2160.0f, 2.f);
Curve->AddKey(4319.5f, 2.f);
Curve->AddKey(4320.0f, 4.f);
}
}
float FImGuiDPIScaleInfo::CalculateResolutionBasedScale() const
{
float ResolutionBasedScale = 1.f;
if (bScaleWithCurve && GEngine && GEngine->GameUserSettings)
{
if (const FRichCurve* Curve = DPICurve.GetRichCurveConst())
{
ResolutionBasedScale *= Curve->Eval((float)GEngine->GameUserSettings->GetDesktopResolution().Y, 1.f);
}
}
return ResolutionBasedScale;
}
//====================================================================================================
// UImGuiSettings
//====================================================================================================
UImGuiSettings* UImGuiSettings::DefaultInstance = nullptr;
FSimpleMulticastDelegate UImGuiSettings::OnSettingsLoaded;
void UImGuiSettings::PostInitProperties()
{
Super::PostInitProperties();
if (IsTemplate())
{
DefaultInstance = this;
OnSettingsLoaded.Broadcast();
}
}
void UImGuiSettings::BeginDestroy()
{
Super::BeginDestroy();
if (DefaultInstance == this)
{
DefaultInstance = nullptr;
}
}
//====================================================================================================
// FImGuiModuleSettings
//====================================================================================================
FImGuiModuleSettings::FImGuiModuleSettings(FImGuiModuleProperties& InProperties, FImGuiModuleCommands& InCommands)
: Properties(InProperties)
, Commands(InCommands)
{
#if WITH_EDITOR
FCoreUObjectDelegates::OnObjectPropertyChanged.AddRaw(this, &FImGuiModuleSettings::OnPropertyChanged);
#endif
// Delegate initializer to support settings loaded after this object creation (in stand-alone builds) and potential
// reloading of settings.
UImGuiSettings::OnSettingsLoaded.AddRaw(this, &FImGuiModuleSettings::InitializeAllSettings);
// Call initializer to support settings already loaded (editor).
InitializeAllSettings();
}
FImGuiModuleSettings::~FImGuiModuleSettings()
{
UImGuiSettings::OnSettingsLoaded.RemoveAll(this);
#if WITH_EDITOR
FCoreUObjectDelegates::OnObjectPropertyChanged.RemoveAll(this);
#endif
}
void FImGuiModuleSettings::InitializeAllSettings()
{
UpdateSettings();
UpdateDPIScaleInfo();
}
void FImGuiModuleSettings::UpdateSettings()
{
if (UImGuiSettings* SettingsObject = UImGuiSettings::Get())
{
SetImGuiInputHandlerClass(SettingsObject->ImGuiInputHandlerClass);
SetShareKeyboardInput(SettingsObject->bShareKeyboardInput);
SetShareGamepadInput(SettingsObject->bShareGamepadInput);
SetShareMouseInput(SettingsObject->bShareMouseInput);
SetUseSoftwareCursor(SettingsObject->bUseSoftwareCursor);
SetToggleInputKey(SettingsObject->ToggleInput);
SetCanvasSizeInfo(SettingsObject->CanvasSize);
}
}
void FImGuiModuleSettings::UpdateDPIScaleInfo()
{
if (UImGuiSettings* SettingsObject = UImGuiSettings::Get())
{
SetDPIScaleInfo(SettingsObject->DPIScale);
}
}
void FImGuiModuleSettings::SetImGuiInputHandlerClass(const FStringClassReference& ClassReference)
{
if (ImGuiInputHandlerClass != ClassReference)
{
ImGuiInputHandlerClass = ClassReference;
OnImGuiInputHandlerClassChanged.Broadcast(ClassReference);
}
}
void FImGuiModuleSettings::SetShareKeyboardInput(bool bShare)
{
if (bShareKeyboardInput != bShare)
{
bShareKeyboardInput = bShare;
Properties.SetKeyboardInputShared(bShare);
}
}
void FImGuiModuleSettings::SetShareGamepadInput(bool bShare)
{
if (bShareGamepadInput != bShare)
{
bShareGamepadInput = bShare;
Properties.SetGamepadInputShared(bShare);
}
}
void FImGuiModuleSettings::SetShareMouseInput(bool bShare)
{
if (bShareMouseInput != bShare)
{
bShareMouseInput = bShare;
Properties.SetMouseInputShared(bShare);
}
}
void FImGuiModuleSettings::SetUseSoftwareCursor(bool bUse)
{
if (bUseSoftwareCursor != bUse)
{
bUseSoftwareCursor = bUse;
OnUseSoftwareCursorChanged.Broadcast(bUse);
}
}
void FImGuiModuleSettings::SetToggleInputKey(const FImGuiKeyInfo& KeyInfo)
{
if (ToggleInputKey != KeyInfo)
{
ToggleInputKey = KeyInfo;
Commands.SetKeyBinding(FImGuiModuleCommands::ToggleInput, ToggleInputKey);
}
}
void FImGuiModuleSettings::SetCanvasSizeInfo(const FImGuiCanvasSizeInfo& CanvasSizeInfo)
{
if (CanvasSize != CanvasSizeInfo)
{
CanvasSize = CanvasSizeInfo;
OnCanvasSizeChangedDelegate.Broadcast(CanvasSize);
}
}
void FImGuiModuleSettings::SetDPIScaleInfo(const FImGuiDPIScaleInfo& ScaleInfo)
{
DPIScale = ScaleInfo;
OnDPIScaleChangedDelegate.Broadcast(DPIScale);
}
#if WITH_EDITOR
void FImGuiModuleSettings::OnPropertyChanged(class UObject* ObjectBeingModified, struct FPropertyChangedEvent& PropertyChangedEvent)
{
if (ObjectBeingModified == UImGuiSettings::Get())
{
UpdateSettings();
if (PropertyChangedEvent.MemberProperty
&& (PropertyChangedEvent.MemberProperty->GetFName() == GET_MEMBER_NAME_CHECKED(FImGuiModuleSettings, DPIScale)))
{
UpdateDPIScaleInfo();
}
}
}
#endif // WITH_EDITOR

View File

@ -0,0 +1,312 @@
// Copyright 1998-2018 Epic Games, Inc. All Rights Reserved.
#pragma once
#include "VersionCompatibility.h"
#include <Curves/CurveFloat.h>
#include <Delegates/Delegate.h>
#include <InputCoreTypes.h>
#include <Styling/SlateTypes.h>
#include <UObject/Object.h>
// We use FStringClassReference, which is supported by older and newer engine versions. Starting from 4.18, it is
// a typedef of FSoftClassPath, which is also recognized by UHT.
#if ENGINE_COMPATIBILITY_LEGACY_STRING_CLASS_REF
#include <StringClassReference.h>
#else
#include <UObject/SoftObjectPath.h>
#endif
#include "ImGuiModuleSettings.generated.h"
/**
* Struct containing key information that can be used for key binding. Using 'Undetermined' value for modifier keys
* means that those keys should be ignored when testing for a match.
*/
USTRUCT()
struct FImGuiKeyInfo
{
GENERATED_BODY()
UPROPERTY(EditAnywhere, Category = "Input")
FKey Key;
UPROPERTY(EditAnywhere, Category = "Input")
ECheckBoxState Shift = ECheckBoxState::Undetermined;
UPROPERTY(EditAnywhere, Category = "Input")
ECheckBoxState Ctrl = ECheckBoxState::Undetermined;
UPROPERTY(EditAnywhere, Category = "Input")
ECheckBoxState Alt = ECheckBoxState::Undetermined;
UPROPERTY(EditAnywhere, Category = "Input")
ECheckBoxState Cmd = ECheckBoxState::Undetermined;
friend bool operator==(const FImGuiKeyInfo& Lhs, const FImGuiKeyInfo& Rhs)
{
return Lhs.Key == Rhs.Key
&& Lhs.Shift == Rhs.Shift
&& Lhs.Ctrl == Rhs.Ctrl
&& Lhs.Alt == Rhs.Alt
&& Lhs.Cmd == Rhs.Cmd;
}
friend bool operator!=(const FImGuiKeyInfo& Lhs, const FImGuiKeyInfo& Rhs)
{
return !(Lhs == Rhs);
}
};
UENUM(BlueprintType)
enum class EImGuiCanvasSizeType : uint8
{
Custom UMETA(ToolTip = "Canvas will have a custom width and height."),
Desktop UMETA(ToolTip = "Canvas will have the same width and height as the desktop."),
Viewport UMETA(ToolTip = "Canvas will always have the same width and height as the viewport."),
};
/**
* Struct with information how to calculate canvas size.
*/
USTRUCT()
struct FImGuiCanvasSizeInfo
{
GENERATED_BODY()
// Select how to specify canvas size.
UPROPERTY(EditAnywhere, Category = "Canvas Size")
EImGuiCanvasSizeType SizeType = EImGuiCanvasSizeType::Desktop;
// Custom canvas width.
UPROPERTY(EditAnywhere, Category = "Canvas Size", meta = (ClampMin = 0, UIMin = 0))
int32 Width = 3840;
// Custom canvas height.
UPROPERTY(EditAnywhere, Category = "Canvas Size", meta = (ClampMin = 0, UIMin = 0))
int32 Height = 2160;
// If this is true, canvas width or height may be extended, if the viewport size is larger.
UPROPERTY(EditAnywhere, Category = "Canvas Size", meta = (ClampMin = 0, UIMin = 0))
bool bExtendToViewport = true;
bool operator==(const FImGuiCanvasSizeInfo& Other) const
{
return (SizeType == Other.SizeType) && (Width == Other.Width)
&& (Height == Other.Height) && (bExtendToViewport == Other.bExtendToViewport);
}
bool operator!=(const FImGuiCanvasSizeInfo& Other) const { return !(*this == Other); }
};
UENUM(BlueprintType)
enum class EImGuiDPIScaleMethod : uint8
{
ImGui UMETA(DisplayName = "ImGui", ToolTip = "Scale ImGui fonts and styles."),
Slate UMETA(ToolTip = "Scale in Slate. ImGui canvas size will be adjusted to get the screen size that is the same as defined in the Canvas Size property.")
};
/**
* Struct with DPI scale data.
*/
USTRUCT()
struct FImGuiDPIScaleInfo
{
GENERATED_BODY()
protected:
// Whether to scale in ImGui or in Slate. Scaling in ImGui gives better looking results but Slate might be a better
// option when layouts do not account for different fonts and styles. When scaling in Slate, ImGui canvas size will
// be adjusted to get the screen size that is the same as defined in the Canvas Size property.
UPROPERTY(EditAnywhere, Category = "DPI Scale")
EImGuiDPIScaleMethod ScalingMethod = EImGuiDPIScaleMethod::ImGui;
// An optional scale to apply on top or instead of the curve-based scale.
UPROPERTY(EditAnywhere, Category = "DPI Scale", meta = (ClampMin = 0, UIMin = 0))
float Scale = 1.f;
// Curve mapping resolution height to scale.
UPROPERTY(config, EditAnywhere, Category = "DPI Scale", meta = (XAxisName = "Resolution Height", YAxisName = "Scale", EditCondition = "bScaleWithCurve"))
FRuntimeFloatCurve DPICurve;
// Whether to use curve-based scaling. If enabled, Scale will be multiplied by a value read from the DPICurve.
// If disabled, only the Scale property will be used.
UPROPERTY(config, EditAnywhere, Category = "DPI Scale")
bool bScaleWithCurve = true;
public:
FImGuiDPIScaleInfo();
float GetImGuiScale() const { return ShouldScaleInSlate() ? 1.f : CalculateScale(); }
float GetSlateScale() const { return ShouldScaleInSlate() ? CalculateScale() : 1.f; }
bool ShouldScaleInSlate() const { return ScalingMethod == EImGuiDPIScaleMethod::Slate; }
private:
float CalculateScale() const { return Scale * CalculateResolutionBasedScale(); }
float CalculateResolutionBasedScale() const;
};
// UObject used for loading and saving ImGui settings. To access actual settings use FImGuiModuleSettings interface.
UCLASS(config=ImGui, defaultconfig)
class UImGuiSettings : public UObject
{
GENERATED_BODY()
public:
// Get default instance or null if it is not loaded.
static UImGuiSettings* Get() { return DefaultInstance; }
// Delegate raised when default instance is loaded.
static FSimpleMulticastDelegate OnSettingsLoaded;
virtual void PostInitProperties() override;
virtual void BeginDestroy() override;
protected:
// Path to own implementation of ImGui Input Handler allowing to customize handling of keyboard and gamepad input.
// If not set then default handler is used.
UPROPERTY(EditAnywhere, config, Category = "Extensions", meta = (MetaClass = "ImGuiInputHandler"))
FStringClassReference ImGuiInputHandlerClass;
// Whether ImGui should share keyboard input with game.
// This defines initial behaviour which can be later changed using 'ImGui.ToggleKeyboardInputSharing' command or
// module properties interface.
UPROPERTY(EditAnywhere, config, Category = "Input")
bool bShareKeyboardInput = false;
// Whether ImGui should share gamepad input with game.
// This defines initial behaviour which can be later changed using 'ImGui.ToggleGamepadInputSharing' command or
// module properties interface.
UPROPERTY(EditAnywhere, config, Category = "Input")
bool bShareGamepadInput = false;
// Whether ImGui should share mouse input with game.
// This defines initial behaviour which can be later changed using 'ImGui.ToggleMouseInputSharing' command or
// module properties interface.
UPROPERTY(EditAnywhere, config, Category = "Input")
bool bShareMouseInput = false;
// If true, then in input mode ImGui will draw its own cursor in place of the hardware one.
// When disabled (default) there is a noticeable difference between cursor position seen by ImGui and position on
// the screen. Enabling this option removes that effect but with lower frame-rates UI becomes quickly unusable.
UPROPERTY(EditAnywhere, config, Category = "Input", AdvancedDisplay)
bool bUseSoftwareCursor = false;
// Define a shortcut key to 'ImGui.ToggleInput' command. Binding is only set if the key field is valid.
// Note that modifier key properties can be set to one of the three values: undetermined means that state of the given
// modifier is not important, checked means that it needs to be pressed and unchecked means that it cannot be pressed.
//
// This binding is using Player Input's DebugExecBindings which only works in non-shipment builds.
UPROPERTY(EditAnywhere, config, Category = "Keyboard Shortcuts")
FImGuiKeyInfo ToggleInput;
// Chose how to define the ImGui canvas size. Select between custom, desktop and viewport.
UPROPERTY(EditAnywhere, config, Category = "Canvas Size")
FImGuiCanvasSizeInfo CanvasSize;
// Setup DPI Scale.
UPROPERTY(EditAnywhere, config, Category = "DPI Scale", Meta = (ShowOnlyInnerProperties))
FImGuiDPIScaleInfo DPIScale;
static UImGuiSettings* DefaultInstance;
friend class FImGuiModuleSettings;
};
class FImGuiModuleCommands;
class FImGuiModuleProperties;
// Interface for ImGui module settings. It shadows all the settings and keep them in sync after UImGuiSettings class is
// loaded, but it can also work before that time what simplifies workflow in early-loading scenarios.
// It binds to module properties and commands objects that need to be passed during construction.
class FImGuiModuleSettings
{
public:
// Generic delegate used to notify changes of boolean properties.
DECLARE_MULTICAST_DELEGATE_OneParam(FBoolChangeDelegate, bool);
DECLARE_MULTICAST_DELEGATE_OneParam(FStringClassReferenceChangeDelegate, const FStringClassReference&);
DECLARE_MULTICAST_DELEGATE_OneParam(FImGuiCanvasSizeInfoChangeDelegate, const FImGuiCanvasSizeInfo&);
DECLARE_MULTICAST_DELEGATE_OneParam(FImGuiDPIScaleInfoChangeDelegate, const FImGuiDPIScaleInfo&);
// Constructor for ImGui module settings. It will bind to instances of module properties and commands and will
// update them every time when settings are changed.
//
// @param InProperties - Instance of module properties that will be bound and updated by this object.
// @param InCommands - Instance of module commands that will be bound and updated by this object.
FImGuiModuleSettings(FImGuiModuleProperties& InProperties, FImGuiModuleCommands& InCommands);
~FImGuiModuleSettings();
// It doesn't offer interface for settings that define initial values for properties, as those are passed during
// start-up and should be accessed trough properties interface. Remaining settings can have getter and/or change
// event that are defined depending on needs.
// Get the path to custom implementation of ImGui Input Handler.
const FStringClassReference& GetImGuiInputHandlerClass() const { return ImGuiInputHandlerClass; }
// Get the software cursor configuration.
bool UseSoftwareCursor() const { return bUseSoftwareCursor; }
// Get the shortcut configuration for 'ImGui.ToggleInput' command.
const FImGuiKeyInfo& GetToggleInputKey() const { return ToggleInputKey; }
// Get the information how to calculate the canvas size.
const FImGuiCanvasSizeInfo& GetCanvasSizeInfo() const { return CanvasSize; }
// Get the DPI Scale information.
const FImGuiDPIScaleInfo& GetDPIScaleInfo() const { return DPIScale; }
// Delegate raised when ImGui Input Handle is changed.
FStringClassReferenceChangeDelegate OnImGuiInputHandlerClassChanged;
// Delegate raised when software cursor configuration is changed.
FBoolChangeDelegate OnUseSoftwareCursorChanged;
// Delegate raised when information how to calculate the canvas size is changed.
FImGuiCanvasSizeInfoChangeDelegate OnCanvasSizeChangedDelegate;
// Delegate raised when the DPI scale is changed.
FImGuiDPIScaleInfoChangeDelegate OnDPIScaleChangedDelegate;
private:
void InitializeAllSettings();
void UpdateSettings();
void UpdateDPIScaleInfo();
void SetImGuiInputHandlerClass(const FStringClassReference& ClassReference);
void SetShareKeyboardInput(bool bShare);
void SetShareGamepadInput(bool bShare);
void SetShareMouseInput(bool bShare);
void SetUseSoftwareCursor(bool bUse);
void SetToggleInputKey(const FImGuiKeyInfo& KeyInfo);
void SetCanvasSizeInfo(const FImGuiCanvasSizeInfo& CanvasSizeInfo);
void SetDPIScaleInfo(const FImGuiDPIScaleInfo& ScaleInfo);
#if WITH_EDITOR
void OnPropertyChanged(class UObject* ObjectBeingModified, struct FPropertyChangedEvent& PropertyChangedEvent);
#endif // WITH_EDITOR
FImGuiModuleProperties& Properties;
FImGuiModuleCommands& Commands;
FStringClassReference ImGuiInputHandlerClass;
FImGuiKeyInfo ToggleInputKey;
FImGuiCanvasSizeInfo CanvasSize;
FImGuiDPIScaleInfo DPIScale;
bool bShareKeyboardInput = false;
bool bShareGamepadInput = false;
bool bShareMouseInput = false;
bool bUseSoftwareCursor = false;
};

View File

@ -0,0 +1,24 @@
// Distributed under the MIT License (MIT) (see accompanying LICENSE file)
#include "ImGuiTextureHandle.h"
#include "ImGuiInteroperability.h"
FImGuiTextureHandle::FImGuiTextureHandle()
: FImGuiTextureHandle(NAME_None, ImGuiInterops::ToImTextureID(INDEX_NONE))
{
}
FImGuiTextureHandle::FImGuiTextureHandle(const FName& InName, ImTextureID InTextureId)
: Name(InName)
, TextureId(InTextureId)
{
const TextureIndex Index = ImGuiInterops::ToTextureIndex(TextureId);
checkf((Index == INDEX_NONE) == (Name == NAME_None),
TEXT("Mismatch between Name and TextureId parameters, with only one indicating a null handle.")
TEXT(" Name = '%s', TextureIndex(TextureId) = %d"), *Name.ToString(), Index);
}
// FImGuiTextureHandle::HasValidEntry() is implemented in ImGuiModule.cpp to get access to FImGuiModuleManager instance
// without referencing in this class.

View File

@ -0,0 +1,188 @@
// Distributed under the MIT License (MIT) (see accompanying LICENSE file)
#include "TextureManager.h"
#include <Engine/Texture2D.h>
#include <Framework/Application/SlateApplication.h>
#include <algorithm>
void FTextureManager::InitializeErrorTexture(const FColor& Color)
{
CreatePlainTextureInternal(NAME_ErrorTexture, 2, 2, Color);
}
TextureIndex FTextureManager::CreateTexture(const FName& Name, int32 Width, int32 Height, uint32 SrcBpp, uint8* SrcData, TFunction<void(uint8*)> SrcDataCleanup)
{
checkf(Name != NAME_None, TEXT("Trying to create a texture with a name 'NAME_None' is not allowed."));
return CreateTextureInternal(Name, Width, Height, SrcBpp, SrcData, SrcDataCleanup);
}
TextureIndex FTextureManager::CreatePlainTexture(const FName& Name, int32 Width, int32 Height, FColor Color)
{
checkf(Name != NAME_None, TEXT("Trying to create a texture with a name 'NAME_None' is not allowed."));
return CreatePlainTextureInternal(Name, Width, Height, Color);
}
TextureIndex FTextureManager::CreateTextureResources(const FName& Name, UTexture2D* Texture)
{
checkf(Name != NAME_None, TEXT("Trying to create texture resources with a name 'NAME_None' is not allowed."));
checkf(Texture, TEXT("Null Texture."));
// Create an entry for the texture.
return AddTextureEntry(Name, Texture, false);
}
void FTextureManager::ReleaseTextureResources(TextureIndex Index)
{
checkf(IsInRange(Index), TEXT("Invalid texture index %d. Texture resources array has %d entries total."), Index, TextureResources.Num());
TextureResources[Index] = {};
}
TextureIndex FTextureManager::CreateTextureInternal(const FName& Name, int32 Width, int32 Height, uint32 SrcBpp, uint8* SrcData, TFunction<void(uint8*)> SrcDataCleanup)
{
// Create a texture.
UTexture2D* Texture = UTexture2D::CreateTransient(Width, Height);
// Create a new resource for that texture.
Texture->UpdateResource();
// Update texture data.
FUpdateTextureRegion2D* TextureRegion = new FUpdateTextureRegion2D(0, 0, 0, 0, Width, Height);
auto DataCleanup = [SrcDataCleanup](uint8* Data, const FUpdateTextureRegion2D* UpdateRegion)
{
SrcDataCleanup(Data);
delete UpdateRegion;
};
Texture->UpdateTextureRegions(0, 1u, TextureRegion, SrcBpp * Width, SrcBpp, SrcData, DataCleanup);
// Create an entry for the texture.
if (Name == NAME_ErrorTexture)
{
ErrorTexture = { Name, Texture, true };
return INDEX_ErrorTexture;
}
else
{
return AddTextureEntry(Name, Texture, true);
}
}
TextureIndex FTextureManager::CreatePlainTextureInternal(const FName& Name, int32 Width, int32 Height, const FColor& Color)
{
// Create buffer with raw data.
const uint32 ColorPacked = Color.ToPackedARGB();
const uint32 Bpp = sizeof(ColorPacked);
const uint32 SizeInPixels = Width * Height;
const uint32 SizeInBytes = SizeInPixels * Bpp;
uint8* SrcData = new uint8[SizeInBytes];
std::fill(reinterpret_cast<uint32*>(SrcData), reinterpret_cast<uint32*>(SrcData) + SizeInPixels, ColorPacked);
auto SrcDataCleanup = [](uint8* Data) { delete[] Data; };
// Create new texture from raw data.
return CreateTextureInternal(Name, Width, Height, Bpp, SrcData, SrcDataCleanup);
}
TextureIndex FTextureManager::AddTextureEntry(const FName& Name, UTexture2D* Texture, bool bAddToRoot)
{
// Try to find an entry with that name.
TextureIndex Index = FindTextureIndex(Name);
// If this is a new name, try to find an entry to reuse.
if (Index == INDEX_NONE)
{
Index = FindTextureIndex(NAME_None);
}
// Either update/reuse an entry or add a new one.
if (Index != INDEX_NONE)
{
TextureResources[Index] = { Name, Texture, bAddToRoot };
return Index;
}
else
{
return TextureResources.Emplace(Name, Texture, bAddToRoot);
}
}
FTextureManager::FTextureEntry::FTextureEntry(const FName& InName, UTexture2D* InTexture, bool bAddToRoot)
: Name(InName)
{
checkf(InTexture, TEXT("Null texture."));
if (bAddToRoot)
{
// Get pointer only for textures that we added to root, so we can later release them.
Texture = InTexture;
// Add texture to the root to prevent garbage collection.
InTexture->AddToRoot();
}
// Create brush and resource handle for input texture.
Brush.SetResourceObject(InTexture);
CachedResourceHandle = FSlateApplication::Get().GetRenderer()->GetResourceHandle(Brush);
}
FTextureManager::FTextureEntry::~FTextureEntry()
{
Reset(true);
}
FTextureManager::FTextureEntry& FTextureManager::FTextureEntry::operator=(FTextureEntry&& Other)
{
// Release old resources if allocated.
Reset(true);
// Move data and ownership to this instance.
Name = MoveTemp(Other.Name);
Texture = MoveTemp(Other.Texture);
Brush = MoveTemp(Other.Brush);
CachedResourceHandle = MoveTemp(Other.CachedResourceHandle);
// Reset the other entry (without releasing resources which are already moved to this instance) to remove tracks
// of ownership and mark it as empty/reusable.
Other.Reset(false);
return *this;
}
const FSlateResourceHandle& FTextureManager::FTextureEntry::GetResourceHandle() const
{
if (!CachedResourceHandle.IsValid() && Brush.HasUObject())
{
CachedResourceHandle = FSlateApplication::Get().GetRenderer()->GetResourceHandle(Brush);
}
return CachedResourceHandle;
}
void FTextureManager::FTextureEntry::Reset(bool bReleaseResources)
{
if (bReleaseResources)
{
// Release brush.
if (Brush.HasUObject() && FSlateApplication::IsInitialized())
{
FSlateApplication::Get().GetRenderer()->ReleaseDynamicResource(Brush);
}
// Remove texture from root to allow for garbage collection (it might be invalid, if we never set it
// or this is an application shutdown).
if (Texture.IsValid())
{
Texture->RemoveFromRoot();
}
}
// We use empty name to mark unused entries.
Name = NAME_None;
// Clean fields to make sure that we don't reference released or moved resources.
Texture.Reset();
Brush = FSlateNoResource();
CachedResourceHandle = FSlateResourceHandle();
}

View File

@ -0,0 +1,158 @@
// Distributed under the MIT License (MIT) (see accompanying LICENSE file)
#pragma once
#include <Styling/SlateBrush.h>
#include <Textures/SlateShaderResource.h>
#include <UObject/WeakObjectPtr.h>
class UTexture2D;
// Index type to be used as a texture handle.
using TextureIndex = int32;
// Manager for textures resources which can be referenced by a unique name or index.
// Name is primarily for lookup and index provides a direct access to resources.
class FTextureManager
{
public:
// Creates an empty manager.
FTextureManager() = default;
// Copying is disabled to protected resource ownership.
FTextureManager(const FTextureManager&) = delete;
FTextureManager& operator=(const FTextureManager&) = delete;
// Moving transfers ownership and leaves source empty.
FTextureManager(FTextureManager&&) = delete;
FTextureManager& operator=(FTextureManager&&) = delete;
// Initialize error texture that will be used for rendering textures without registered resources. Can be called
// multiple time, if color needs to be changed.
// Note: Because of any-time module loading and lazy resources initialization goals we can't simply call it from
// constructor.
// @param Color - The color of the error texture
void InitializeErrorTexture(const FColor& Color);
// Find texture index by name.
// @param Name - The name of a texture to find
// @returns The index of a texture with given name or INDEX_NONE if there is no such texture
TextureIndex FindTextureIndex(const FName& Name) const
{
return TextureResources.IndexOfByPredicate([&](const auto& Entry) { return Entry.GetName() == Name; });
}
// Get the name of a texture at given index. Returns NAME_None, if index is out of range.
// @param Index - Index of a texture
// @returns The name of a texture at given index or NAME_None if index is out of range.
FName GetTextureName(TextureIndex Index) const
{
return IsInRange(Index) ? TextureResources[Index].GetName() : NAME_None;
}
// Get the Slate Resource Handle to a texture at given index. If index is out of range or resources are not valid
// it returns a handle to the error texture.
// @param Index - Index of a texture
// @returns The Slate Resource Handle for a texture at given index or to error texture, if no valid resources were
// found at given index
const FSlateResourceHandle& GetTextureHandle(TextureIndex Index) const
{
return IsValidTexture(Index) ? TextureResources[Index].GetResourceHandle() : ErrorTexture.GetResourceHandle();
}
// Create a texture from raw data.
// @param Name - The texture name
// @param Width - The texture width
// @param Height - The texture height
// @param SrcBpp - The size in bytes of one pixel
// @param SrcData - The source data
// @param SrcDataCleanup - Optional function called to release source data after texture is created (only needed, if data need to be released)
// @returns The index of a texture that was created
TextureIndex CreateTexture(const FName& Name, int32 Width, int32 Height, uint32 SrcBpp, uint8* SrcData, TFunction<void(uint8*)> SrcDataCleanup = [](uint8*) {});
// Create a plain texture.
// @param Name - The texture name
// @param Width - The texture width
// @param Height - The texture height
// @param Color - The texture color
// @returns The index of a texture that was created
TextureIndex CreatePlainTexture(const FName& Name, int32 Width, int32 Height, FColor Color);
// Create Slate resources to an existing texture, managed externally.
// @param Name - The texture name
// @param Texture - The texture
// @returns The index to created/updated texture resources
TextureIndex CreateTextureResources(const FName& Name, UTexture2D* Texture);
// Release resources for given texture. Ignores invalid indices.
// @param Index - The index of a texture resources
void ReleaseTextureResources(TextureIndex Index);
private:
// See CreateTexture for general description.
// Internal implementations doesn't validate name or resource uniqueness. Instead it uses NAME_ErrorTexture
// (aka NAME_None) and INDEX_ErrorTexture (aka INDEX_NONE) to identify ErrorTexture.
TextureIndex CreateTextureInternal(const FName& Name, int32 Width, int32 Height, uint32 SrcBpp, uint8* SrcData, TFunction<void(uint8*)> SrcDataCleanup = [](uint8*) {});
// See CreatePlainTexture for general description.
// Internal implementations doesn't validate name or resource uniqueness. Instead it uses NAME_ErrorTexture
// (aka NAME_None) and INDEX_ErrorTexture (aka INDEX_NONE) to identify ErrorTexture.
TextureIndex CreatePlainTextureInternal(const FName& Name, int32 Width, int32 Height, const FColor& Color);
// Add or reuse texture entry.
// @param Name - The texture name
// @param Texture - The texture
// @param bAddToRoot - If true, we should add texture to root to prevent garbage collection (use for own textures)
// @returns The index of the entry that we created or reused
TextureIndex AddTextureEntry(const FName& Name, UTexture2D* Texture, bool bAddToRoot);
// Check whether index is in range allocated for TextureResources (it doesn't mean that resources are valid).
FORCEINLINE bool IsInRange(TextureIndex Index) const
{
return static_cast<uint32>(Index) < static_cast<uint32>(TextureResources.Num());
}
// Check whether index is in range and whether texture resources are valid (using NAME_None sentinel).
FORCEINLINE bool IsValidTexture(TextureIndex Index) const
{
return IsInRange(Index) && TextureResources[Index].GetName() != NAME_None;
}
// Entry for texture resources. Only supports explicit construction.
struct FTextureEntry
{
FTextureEntry() = default;
FTextureEntry(const FName& InName, UTexture2D* InTexture, bool bAddToRoot);
~FTextureEntry();
// Copying is not supported.
FTextureEntry(const FTextureEntry&) = delete;
FTextureEntry& operator=(const FTextureEntry&) = delete;
// We rely on TArray and don't implement custom move constructor...
FTextureEntry(FTextureEntry&&) = delete;
// ... but we need move assignment to support reusing entries.
FTextureEntry& operator=(FTextureEntry&& Other);
const FName& GetName() const { return Name; }
const FSlateResourceHandle& GetResourceHandle() const;
private:
void Reset(bool bReleaseResources);
FName Name = NAME_None;
mutable FSlateResourceHandle CachedResourceHandle;
TWeakObjectPtr<UTexture2D> Texture;
FSlateBrush Brush;
};
TArray<FTextureEntry> TextureResources;
FTextureEntry ErrorTexture;
static constexpr EName NAME_ErrorTexture = NAME_None;
static constexpr TextureIndex INDEX_ErrorTexture = INDEX_NONE;
};

View File

@ -0,0 +1,63 @@
// Distributed under the MIT License (MIT) (see accompanying LICENSE file)
#pragma once
#include "Range.h"
#include <array>
#include <iterator>
#include <type_traits>
// Utilities to work with one-dimensional, statically bound arrays. Code relying on those utilities should work without
// modifications with fixed-sized arrays (currently used in ImGui) and with standard arrays.
namespace Utilities
{
//====================================================================================================
// Helper functions
//====================================================================================================
// Function to determine number of elements in fixed size array.
template<class T, std::size_t N>
constexpr std::size_t GetArraySize(const T(&)[N])
{
return N;
}
// Function to determine number of elements in std array.
template<class T, std::size_t N>
constexpr std::size_t GetArraySize(const std::array<T, N>&)
{
return N;
}
//====================================================================================================
// Traits
//====================================================================================================
template<typename TArray>
struct ArraySize;
// Struct to determine number of elements in fixed size array.
template<typename T, std::size_t N>
struct ArraySize<T[N]> : std::extent<T[N]>
{
};
// Struct to determine number of elements in std array.
template<typename T, std::size_t N>
struct ArraySize<std::array<T, N>> : std::tuple_size<std::array<T, N>>
{
};
//====================================================================================================
// Ranges
//====================================================================================================
// Array indices range. Limited by 0 and array size.
template<typename TArray, typename SizeType>
using TArrayIndexRange = TBoundedRange<SizeType, 0, ArraySize<TArray>::value>;
}

View File

@ -0,0 +1,100 @@
// Distributed under the MIT License (MIT) (see accompanying LICENSE file)
#include "DebugExecBindings.h"
#include "ImGuiModuleSettings.h"
#include <GameFramework/PlayerInput.h>
#include <UObject/UObjectIterator.h>
namespace
{
FKeyBind CreateKeyBind(const FImGuiKeyInfo& KeyInfo, const FString& Command)
{
FKeyBind KeyBind;
KeyBind.Command = Command;
KeyBind.Key = KeyInfo.Key;
KeyBind.bDisabled = false;
#define FILL_MODIFIER_DATA(KeyInfoProperty, BindProperty, BindIgnoreProperty)\
if (KeyInfo.KeyInfoProperty == ECheckBoxState::Undetermined)\
{\
KeyBind.BindProperty = KeyBind.BindIgnoreProperty = false;\
}\
else\
{\
KeyBind.BindProperty = (KeyInfo.KeyInfoProperty == ECheckBoxState::Checked);\
KeyBind.BindIgnoreProperty = !KeyBind.BindProperty;\
}
FILL_MODIFIER_DATA(Shift, Shift, bIgnoreShift);
FILL_MODIFIER_DATA(Ctrl, Control, bIgnoreCtrl);
FILL_MODIFIER_DATA(Alt, Alt, bIgnoreAlt);
FILL_MODIFIER_DATA(Cmd, Cmd, bIgnoreCmd);
#undef FILL_MODIFIER_DATA
return KeyBind;
}
bool IsBindable(const FKey& Key)
{
#if ENGINE_COMPATIBILITY_LEGACY_KEY_AXIS_API
return Key.IsValid() && Key != EKeys::AnyKey && !Key.IsFloatAxis() && !Key.IsVectorAxis()
&& !Key.IsGamepadKey() && !Key.IsModifierKey() && !Key.IsMouseButton();
#else
return Key.IsValid() && Key != EKeys::AnyKey && !Key.IsAxis1D() && !Key.IsAxis2D()
&& !Key.IsAxis3D() && !Key.IsGamepadKey() && !Key.IsModifierKey() && !Key.IsMouseButton();
#endif
}
void UpdatePlayerInput(UPlayerInput* PlayerInput, const FKeyBind& KeyBind)
{
const int32 Index = PlayerInput->DebugExecBindings.IndexOfByPredicate([&](const FKeyBind& PlayerKeyBind)
{
return PlayerKeyBind.Command.Equals(KeyBind.Command, ESearchCase::IgnoreCase);
});
if (IsBindable(KeyBind.Key))
{
if (Index != INDEX_NONE)
{
PlayerInput->DebugExecBindings[Index] = KeyBind;
}
else
{
PlayerInput->DebugExecBindings.Add(KeyBind);
}
}
else
{
if (Index != INDEX_NONE)
{
PlayerInput->DebugExecBindings.RemoveAt(Index);
}
}
}
}
namespace DebugExecBindings
{
void UpdatePlayerInputs(const FImGuiKeyInfo& KeyInfo, const FString& Command)
{
checkf(!Command.IsEmpty(), TEXT("Empty command."));
const FKeyBind KeyBind = CreateKeyBind(KeyInfo, Command);
// Update default player input, so changes will be visible in all PIE sessions created after this point.
if (UPlayerInput* DefaultPlayerInput = GetMutableDefault<UPlayerInput>())
{
UpdatePlayerInput(DefaultPlayerInput, KeyBind);
}
// Update all existing player inputs to see changes in running PIE session.
for (TObjectIterator<UPlayerInput> It; It; ++It)
{
UpdatePlayerInput(*It, KeyBind);
}
}
}

View File

@ -0,0 +1,11 @@
// Distributed under the MIT License (MIT) (see accompanying LICENSE file)
#pragma once
class FString;
struct FImGuiKeyInfo;
namespace DebugExecBindings
{
void UpdatePlayerInputs(const FImGuiKeyInfo& KeyInfo, const FString& Command);
}

View File

@ -0,0 +1,173 @@
// Distributed under the MIT License (MIT) (see accompanying LICENSE file)
#pragma once
#include <utility>
namespace Utilities
{
//====================================================================================================
// Range
//====================================================================================================
template<typename T>
class TRange
{
public:
TRange() {}
TRange(const T& RangeBegin, const T& RangeEnd) { SetRange(RangeBegin, RangeEnd); }
const T& GetBegin() const { return Begin; }
const T& GetEnd() const { return End; }
bool IsEmpty() const { return Begin == End; }
void SetEmpty() { Begin = End = T(); }
void SetRange(const T& RangeBegin, const T& RangeEnd)
{
checkf(RangeBegin <= RangeEnd, TEXT("Invalid arguments: RangeBegin > RangeEnd."));
Begin = RangeBegin;
End = RangeEnd;
}
void AddPosition(const T& Position)
{
AddRangeUnchecked(Position, Position + 1);
}
void AddRange(const T& RangeBegin, const T& RangeEnd)
{
checkf(RangeBegin <= RangeEnd, TEXT("Invalid arguments: RangeBegin > RangeEnd."));
AddRangeUnchecked(RangeBegin, RangeEnd);
}
private:
void AddRangeUnchecked(const T& RangeBegin, const T& RangeEnd)
{
if (IsEmpty())
{
Begin = RangeBegin;
End = RangeEnd;
}
else
{
if (Begin > RangeBegin)
{
Begin = RangeBegin;
}
if (End < RangeEnd)
{
End = RangeEnd;
}
}
}
T Begin = T();
T End = T();
};
// Enable range-based loops
template<typename T>
const T& begin(const TRange<T>& Range)
{
return Range.GetBegin();
}
template<typename T>
const T& end(const TRange<T>& Range)
{
return Range.GetEnd();
}
//====================================================================================================
// Bounded Range
//====================================================================================================
template<typename T, T BeginBound, T EndBound>
class TBoundedRange
{
public:
constexpr const T& GetLowerBound() const { return BeginBound; }
constexpr const T& GetUpperBound() const { return EndBound; }
const T& GetBegin() const { return Begin; }
const T& GetEnd() const { return End; }
bool IsEmpty() const { return Begin == End; }
void SetEmpty() { Begin = End = BeginBound; }
void SetFull()
{
Begin = BeginBound;
End = EndBound;
}
void AddPosition(const T& Position)
{
checkf(Position >= BeginBound && Position < EndBound, TEXT("Position out of range."));
AddRangeUnchecked(Position, Position + 1);
}
void AddRange(const T& RangeBegin, const T& RangeEnd)
{
checkf(RangeBegin <= RangeEnd, TEXT("Invalid arguments: RangeBegin > MaxPosition."));
checkf(RangeBegin >= BeginBound, TEXT("RangeBegin out of range."));
checkf(RangeBegin <= EndBound, TEXT("RangeEnd out of range."));
AddRangeUnchecked(RangeBegin, RangeEnd);
}
private:
void AddRangeUnchecked(const T& RangeBegin, const T& RangeEnd)
{
if (IsEmpty())
{
Begin = RangeBegin;
End = RangeEnd;
}
else
{
if (Begin > RangeBegin)
{
Begin = RangeBegin;
}
if (End < RangeEnd)
{
End = RangeEnd;
}
}
}
T Begin = EndBound;
T End = BeginBound;
};
// Enable range-based loops
template<typename T, T BeginBound, T EndBound>
const T& begin(const TBoundedRange<T, BeginBound, EndBound>& Range)
{
return Range.GetBegin();
}
template<typename T, T BeginBound, T EndBound>
const T& end(const TBoundedRange<T, BeginBound, EndBound>& Range)
{
return Range.GetEnd();
}
}

View File

@ -0,0 +1,96 @@
// Distributed under the MIT License (MIT) (see accompanying LICENSE file)
#pragma once
#include <Delegates/Delegate.h>
#include <Delegates/DelegateCombinations.h>
namespace Utilities
{
// Handle initialized as a pointer to a default value, but can be redirected to follow other handles.
// When detached, it will revert to the default value. Intended for cross-module redirections.
template<typename T>
struct TRedirectingHandle
{
TRedirectingHandle(T& InDefaultValue)
: Handle(&InDefaultValue)
, DefaultHandle(&InDefaultValue)
{
}
~TRedirectingHandle()
{
// Broadcast null pointer as a request to detach.
OnRedirectionUpdate.Broadcast(nullptr);
}
// Check whether this handle points to the default value.
bool IsDefault() const
{
return (Handle == DefaultHandle);
}
// Get the current value.
T& Get() const
{
return *Handle;
}
// Set the other handle as a parent to this one. Passing null or itself will result with detaching from
// the current parent (if any) and reverting back to the default value.
void SetParent(TRedirectingHandle* InParent)
{
if (InParent != Parent)
{
if (Parent)
{
Parent->OnRedirectionUpdate.RemoveAll(this);
}
// Protecting from setting itself as a parent.
Parent = (InParent != this) ? InParent : nullptr;
if (Parent)
{
Parent->OnRedirectionUpdate.AddRaw(this, &TRedirectingHandle::UpdateRedirection);
}
SetHandle((Parent) ? Parent->Handle : DefaultHandle);
}
}
protected:
void UpdateRedirection(T* InHandle)
{
if (InHandle)
{
SetHandle(InHandle);
}
else
{
// Interpreting null as a signal to detach.
SetParent(nullptr);
}
}
void SetHandle(T* InHandle)
{
if (InHandle != Handle)
{
Handle = InHandle;
OnRedirectionUpdate.Broadcast(Handle);
}
}
T* Handle;
T* DefaultHandle;
TRedirectingHandle* Parent = nullptr;
// Event with a new handle value or null pointer as a signal to detach.
DECLARE_MULTICAST_DELEGATE_OneParam(FRedirectionUpdateDelegate, T*);
FRedirectionUpdateDelegate OnRedirectionUpdate;
};
}

View File

@ -0,0 +1,22 @@
// Distributed under the MIT License (MIT) (see accompanying LICENSE file)
#include "WorldContext.h"
namespace Utilities
{
const FWorldContext* GetWorldContextFromNetMode(ENetMode NetMode)
{
checkf(GEngine, TEXT("GEngine required to get list of worlds."));
for (const FWorldContext& WorldContext : GEngine->GetWorldContexts())
{
if (WorldContext.World() && WorldContext.World()->GetNetMode() == NetMode)
{
return &WorldContext;
}
}
return nullptr;
}
}

View File

@ -0,0 +1,46 @@
// Distributed under the MIT License (MIT) (see accompanying LICENSE file)
#pragma once
#include <Engine/Engine.h>
#include <Engine/GameInstance.h>
#include <Engine/GameViewportClient.h>
#include <UObject/WeakObjectPtr.h>
// Utilities helping to get a World Context.
namespace Utilities
{
template<typename T>
FORCEINLINE const FWorldContext* GetWorldContext(const T* Obj);
FORCEINLINE const FWorldContext* GetWorldContext(const UGameInstance& GameInstance)
{
return GameInstance.GetWorldContext();
}
template<typename T>
FORCEINLINE const FWorldContext* GetWorldContext(const TWeakObjectPtr<T>& Obj)
{
return Obj.IsValid() ? GetWorldContext(*Obj.Get()) : nullptr;
}
FORCEINLINE const FWorldContext* GetWorldContext(const UGameViewportClient& GameViewportClient)
{
return GetWorldContext(GameViewportClient.GetGameInstance());
}
FORCEINLINE const FWorldContext* GetWorldContext(const UWorld& World)
{
return GetWorldContext(World.GetGameInstance());
}
template<typename T>
FORCEINLINE const FWorldContext* GetWorldContext(const T* Obj)
{
return Obj ? GetWorldContext(*Obj) : nullptr;
}
const FWorldContext* GetWorldContextFromNetMode(ENetMode NetMode);
}

View File

@ -0,0 +1,65 @@
// Distributed under the MIT License (MIT) (see accompanying LICENSE file)
#pragma once
#include "Utilities/WorldContext.h"
// Utilities mapping worlds to indices that we use to identify ImGui contexts.
namespace Utilities
{
// Invalid context index for parameters that cannot be resolved to a valid world.
static constexpr int32 INVALID_CONTEXT_INDEX = -10;
// Standalone context index.
static constexpr int32 STANDALONE_GAME_CONTEXT_INDEX = -2;
#if WITH_EDITOR
// Editor context index. We are lacking flexibility here, so we might need to change it somehow.
static constexpr int32 EDITOR_CONTEXT_INDEX = -1;
FORCEINLINE int32 GetWorldContextIndex(const FWorldContext& WorldContext)
{
switch (WorldContext.WorldType)
{
case EWorldType::PIE:
return WorldContext.PIEInstance;
case EWorldType::Game:
return STANDALONE_GAME_CONTEXT_INDEX;
case EWorldType::Editor:
return EDITOR_CONTEXT_INDEX;
default:
return INVALID_CONTEXT_INDEX;
}
}
template<typename T>
FORCEINLINE int32 GetWorldContextIndex(const T& Obj)
{
const FWorldContext* WorldContext = GetWorldContext(Obj);
return WorldContext ? GetWorldContextIndex(*WorldContext) : INVALID_CONTEXT_INDEX;
}
FORCEINLINE int32 GetWorldContextIndex(const UWorld& World)
{
return (World.WorldType == EWorldType::Editor) ? EDITOR_CONTEXT_INDEX : GetWorldContextIndex(World.GetGameInstance());
}
FORCEINLINE int32 GetWorldContextIndex(const UWorld* World)
{
return World ? GetWorldContextIndex(*World) : INVALID_CONTEXT_INDEX;
}
#else
template<typename T>
constexpr int32 GetWorldContextIndex(const T&)
{
// The only option is standalone game with one context.
return STANDALONE_GAME_CONTEXT_INDEX;
}
#endif // #if WITH_EDITOR
}

View File

@ -0,0 +1,35 @@
// Distributed under the MIT License (MIT) (see accompanying LICENSE file)
#include <Runtime/Launch/Resources/Version.h>
#define BELOW_ENGINE_VERSION(Major, Minor) (ENGINE_MAJOR_VERSION < (Major) || (ENGINE_MAJOR_VERSION == (Major) && ENGINE_MINOR_VERSION < (Minor)))
#define FROM_ENGINE_VERSION(Major, Minor) !BELOW_ENGINE_VERSION(Major, Minor)
// One place to define compatibility with older engine versions.
// Starting from version 4.17, Slate has an improved clipping API. Old version required to specify per-vertex clipping
// rectangle and unofficial GSlateScissorRect to correctly clip custom vertices made with FSlateDrawElement.
#define ENGINE_COMPATIBILITY_LEGACY_CLIPPING_API BELOW_ENGINE_VERSION(4, 17)
// Starting from version 4.18, FPaths::GameSavedDir() has been superseded by FPaths::ProjectSavedDir().
#define ENGINE_COMPATIBILITY_LEGACY_SAVED_DIR BELOW_ENGINE_VERSION(4, 18)
// Starting from version 4.18, we have support for dual key bindings.
#define ENGINE_COMPATIBILITY_SINGLE_KEY_BINDING BELOW_ENGINE_VERSION(4, 18)
// Starting from version 4.18, FStringClassReference is replaced by FSoftClassPath. The new header contains a typedef
// that renames FStringClassReference to FSoftClassPath, so it is still possible tu use the old type name in code.
// The old header forwards to the new one but if used it outputs a warning, so we want to avoid it.
#define ENGINE_COMPATIBILITY_LEGACY_STRING_CLASS_REF BELOW_ENGINE_VERSION(4, 18)
// Starting from version 4.18, engine has a world post actor tick event which if available, provides a good opportunity
// to call debug delegates after world actors are already updated.
#define ENGINE_COMPATIBILITY_WITH_WORLD_POST_ACTOR_TICK FROM_ENGINE_VERSION(4, 18)
// Starting from version 4.24, world actor tick event has additional world parameter.
#define ENGINE_COMPATIBILITY_LEGACY_WORLD_ACTOR_TICK BELOW_ENGINE_VERSION(4, 24)
// Starting from version 4.26, FKey::IsFloatAxis and FKey::IsVectorAxis are deprecated and replaced with FKey::IsAxis[1|2|3]D methods.
#define ENGINE_COMPATIBILITY_LEGACY_KEY_AXIS_API BELOW_ENGINE_VERSION(4, 26)

View File

@ -0,0 +1,352 @@
// Distributed under the MIT License (MIT) (see accompanying LICENSE file)
#include "SImGuiCanvasControl.h"
#include "VersionCompatibility.h"
#include <Rendering/DrawElements.h>
#include <SlateOptMacros.h>
namespace
{
// Mouse wheel to zoom ratio - how fast zoom changes with mouse wheel delta.
const float ZoomScrollSpeed = 0.03125f;
// Speed of blending out - how much zoom scale and canvas offset fades in every frame.
const float BlendOutSpeed = 0.25f;
// TODO: Move to settings
namespace Colors
{
const FLinearColor CanvasMargin = FColor(0, 4, 32, 64);
const FLinearColor CanvasBorder = FColor::Black.WithAlpha(127);
const FLinearColor CanvasBorderHighlight = FColor(16, 24, 64, 160);
const FLinearColor FrameBorder = FColor(222, 163, 9, 128);
const FLinearColor FrameBorderHighlight = FColor(255, 180, 10, 160);
}
// Defines type of drag operation.
enum class EDragType
{
Content,
Canvas
};
// Data for drag & drop operations. Calculations are made in widget where we have more straightforward access to data
// like geometry or scale.
class FImGuiDragDropOperation : public FDragDropOperation
{
public:
DRAG_DROP_OPERATOR_TYPE(FImGuiDragDropOperation, FDragDropOperation)
FImGuiDragDropOperation(const FVector2D& InPosition, const FVector2D& InOffset, EDragType InDragType)
: StartPosition(InPosition)
, StartOffset(InOffset)
, DragType(InDragType)
{
bCreateNewWindow = false;
MouseCursor = EMouseCursor::GrabHandClosed;
}
FVector2D StartPosition;
FVector2D StartOffset;
EDragType DragType;
};
}
BEGIN_SLATE_FUNCTION_BUILD_OPTIMIZATION
void SImGuiCanvasControl::Construct(const FArguments& InArgs)
{
OnTransformChanged = InArgs._OnTransformChanged;
UpdateVisibility();
}
END_SLATE_FUNCTION_BUILD_OPTIMIZATION
void SImGuiCanvasControl::SetActive(bool bInActive)
{
if (bActive != bInActive)
{
bActive = bInActive;
bBlendingOut = !bInActive;
if (bInActive)
{
Opacity = 1.f;
}
UpdateVisibility();
}
}
void SImGuiCanvasControl::Tick(const FGeometry& AllottedGeometry, const double InCurrentTime, const float InDeltaTime)
{
Super::Tick(AllottedGeometry, InCurrentTime, InDeltaTime);
if (bBlendingOut)
{
if (FMath::IsNearlyEqual(CanvasScale, 1.f, ZoomScrollSpeed) && CanvasOffset.IsNearlyZero(1.f))
{
CanvasOffset = FVector2D::ZeroVector;
CanvasScale = 1.f;
Opacity = 0.f;
bBlendingOut = false;
UpdateVisibility();
}
else
{
CanvasOffset = FMath::Lerp(CanvasOffset, FVector2D::ZeroVector, BlendOutSpeed);
CanvasScale = FMath::Lerp(CanvasScale, 1.f, BlendOutSpeed);
Opacity = FMath::Lerp(Opacity, 0.f, BlendOutSpeed);
}
UpdateRenderTransform();
}
}
FReply SImGuiCanvasControl::OnMouseButtonDown(const FGeometry& MyGeometry, const FPointerEvent& MouseEvent)
{
if (DragRequest == EDragRequest::None)
{
if (MouseEvent.GetEffectingButton() == EKeys::RightMouseButton)
{
DragRequest = EDragRequest::Content;
return FReply::Handled().DetectDrag(SharedThis(this), EKeys::RightMouseButton).CaptureMouse(SharedThis(this));
}
else if (MouseEvent.GetEffectingButton() == EKeys::MiddleMouseButton)
{
DragRequest = EDragRequest::Canvas;
return FReply::Handled().DetectDrag(SharedThis(this), EKeys::MiddleMouseButton).CaptureMouse(SharedThis(this));
}
}
return FReply::Unhandled();
}
FReply SImGuiCanvasControl::OnMouseButtonUp(const FGeometry& MyGeometry, const FPointerEvent& MouseEvent)
{
if (MouseEvent.GetEffectingButton() == EKeys::RightMouseButton)
{
if (DragRequest == EDragRequest::Content)
{
DragRequest = EDragRequest::None;
}
}
else if (MouseEvent.GetEffectingButton() == EKeys::MiddleMouseButton)
{
if (DragRequest == EDragRequest::Canvas)
{
DragRequest = EDragRequest::None;
}
}
return FReply::Unhandled();
}
FReply SImGuiCanvasControl::OnMouseWheel(const FGeometry& MyGeometry, const FPointerEvent& MouseEvent)
{
Zoom(MyGeometry, MouseEvent.GetWheelDelta() * ZoomScrollSpeed, MouseEvent.GetScreenSpacePosition());
return FReply::Unhandled();
}
FReply SImGuiCanvasControl::OnDragDetected(const FGeometry& MyGeometry, const FPointerEvent& MouseEvent)
{
if (DragRequest == EDragRequest::Content)
{
return FReply::Handled()
.BeginDragDrop(MakeShareable(new FImGuiDragDropOperation(
MouseEvent.GetScreenSpacePosition(), ContentOffset, EDragType::Content)))
.LockMouseToWidget(SharedThis(this));
}
else if (DragRequest == EDragRequest::Canvas)
{
return FReply::Handled()
.BeginDragDrop(MakeShareable(new FImGuiDragDropOperation(
MouseEvent.GetScreenSpacePosition(), CanvasOffset, EDragType::Canvas)))
.LockMouseToWidget(SharedThis(this));
}
else
{
return FReply::Unhandled();
}
}
FReply SImGuiCanvasControl::OnDragOver(const FGeometry& MyGeometry, const FDragDropEvent& DragDropEvent)
{
auto Operation = DragDropEvent.GetOperationAs<FImGuiDragDropOperation>();
if (Operation.IsValid())
{
const FSlateRenderTransform ScreenToWidget = MyGeometry.GetAccumulatedRenderTransform().Inverse();
const FVector2D DragDelta = ScreenToWidget.TransformVector(DragDropEvent.GetScreenSpacePosition() - Operation->StartPosition);
if (Operation->DragType == EDragType::Content)
{
// Content offset is in ImGui space, so we need to scale drag calculated in widget space.
ContentOffset = Operation->StartOffset + DragDelta / CanvasScale;
}
else
{
// Canvas offset is in widget space, so we can apply drag calculated in widget space directly.
CanvasOffset = Operation->StartOffset + DragDelta;
}
UpdateRenderTransform();
return FReply::Handled();
}
else
{
return FReply::Unhandled();
}
}
FReply SImGuiCanvasControl::SImGuiCanvasControl::OnDrop(const FGeometry& MyGeometry, const FDragDropEvent& DragDropEvent)
{
DragRequest = EDragRequest::None;
return FReply::Handled().ReleaseMouseLock();
}
FVector2D SImGuiCanvasControl::ComputeDesiredSize(float InScale) const
{
return FVector2D{ 3840.f, 2160.f } * InScale;
}
namespace
{
FORCEINLINE FMargin CalculateInset(const FSlateRect& From, const FSlateRect& To)
{
return { To.Left - From.Left, To.Top - From.Top, From.Right - To.Right, From.Bottom - To.Bottom };
}
FORCEINLINE FLinearColor ScaleAlpha(FLinearColor Color, float Scale)
{
Color.A *= Scale;
return Color;
}
FORCEINLINE FVector2D Round(const FVector2D& Vec)
{
return FVector2D{ FMath::FloorToFloat(Vec.X), FMath::FloorToFloat(Vec.Y) };
}
}
int32 SImGuiCanvasControl::OnPaint(const FPaintArgs& Args, const FGeometry& AllottedGeometry, const FSlateRect& MyCullingRect, FSlateWindowElementList& OutDrawElements, int32 LayerId, const FWidgetStyle& InWidgetStyle, bool bParentEnabled) const
{
const FPaintGeometry PaintGeometry = AllottedGeometry.ToPaintGeometry();
const FSlateRenderTransform& WidgetToScreen = AllottedGeometry.GetAccumulatedRenderTransform();
const FSlateRenderTransform ImGuiToScreen = Transform.Concatenate(WidgetToScreen);
const FSlateRect CanvasRect = FSlateRect(
ImGuiToScreen.TransformPoint(FVector2D::ZeroVector),
ImGuiToScreen.TransformPoint(ComputeDesiredSize(1.f)));
const FMargin CanvasMargin = CalculateInset(MyCullingRect, CanvasRect);
if (CanvasMargin.GetDesiredSize().SizeSquared() > 0.f)
{
CanvasBorderBrush.Margin = CanvasMargin;
const FLinearColor CanvasMarginColor = ScaleAlpha(Colors::CanvasMargin, Opacity);
const FLinearColor CanvasBorderColor = ScaleAlpha(DragRequest == EDragRequest::Content
? Colors::CanvasBorderHighlight : Colors::CanvasBorder, Opacity);
#if ENGINE_COMPATIBILITY_LEGACY_CLIPPING_API
FSlateDrawElement::MakeBox(OutDrawElements, LayerId, PaintGeometry, &CanvasBorderBrush, MyCullingRect,
ESlateDrawEffect::None, CanvasMarginColor);
FSlateDrawElement::MakeBox(OutDrawElements, LayerId, PaintGeometry, &CanvasBorderBrush,
CanvasRect.ExtendBy(1).IntersectionWith(MyCullingRect), ESlateDrawEffect::None, CanvasBorderColor);
#else
FSlateDrawElement::MakeBox(OutDrawElements, LayerId, PaintGeometry, &CanvasBorderBrush, ESlateDrawEffect::None,
CanvasMarginColor);
OutDrawElements.PushClip(FSlateClippingZone{ CanvasRect.ExtendBy(1) });
FSlateDrawElement::MakeBox(OutDrawElements, LayerId, PaintGeometry, &CanvasBorderBrush, ESlateDrawEffect::None,
CanvasBorderColor);
OutDrawElements.PopClip();
#endif
}
const FSlateRect FrameRect = FSlateRect::FromPointAndExtent(
WidgetToScreen.TransformPoint(Round(CanvasOffset)),
Round(MyCullingRect.GetSize() * CanvasScale));
const FMargin FrameMargin = CalculateInset(MyCullingRect, FrameRect);
if (FrameMargin.GetDesiredSize().SizeSquared() > 0.f)
{
FrameBorderBrush.Margin = FrameMargin;
const FLinearColor FrameBorderColor = ScaleAlpha(DragRequest == EDragRequest::Canvas
? Colors::FrameBorderHighlight : Colors::FrameBorder, Opacity);
#if ENGINE_COMPATIBILITY_LEGACY_CLIPPING_API
FSlateDrawElement::MakeBox(OutDrawElements, LayerId, PaintGeometry, &FrameBorderBrush,
FrameRect.ExtendBy(1).IntersectionWith(MyCullingRect), ESlateDrawEffect::None, FrameBorderColor);
#else
OutDrawElements.PushClip(FSlateClippingZone{ FrameRect.ExtendBy(1) });
FSlateDrawElement::MakeBox(OutDrawElements, LayerId, PaintGeometry, &FrameBorderBrush, ESlateDrawEffect::None,
FrameBorderColor);
OutDrawElements.PopClip();
#endif
}
return LayerId;
}
void SImGuiCanvasControl::UpdateVisibility()
{
SetVisibility(bActive ? EVisibility::Visible : bBlendingOut ? EVisibility::HitTestInvisible : EVisibility::Hidden);
}
void SImGuiCanvasControl::Zoom(const FGeometry& MyGeometry, const float Delta, const FVector2D& MousePosition)
{
// If blending out, then cancel.
bBlendingOut = false;
float OldCanvasScale = CanvasScale;
// Normalize scale to make sure that it changes in fixed steps and that we don't accumulate rounding errors.
// Normalizing before applying delta allows for scales that at the edges are not rounded to the closes step.
CanvasScale = FMath::RoundToFloat(CanvasScale / ZoomScrollSpeed) * ZoomScrollSpeed;
// Update the scale.
CanvasScale = FMath::Clamp(CanvasScale + Delta, GetMinScale(MyGeometry), 2.f);
// Update canvas offset to keep it fixed around pivot point.
if (CanvasScale != OldCanvasScale && OldCanvasScale != 0.f)
{
// Pivot points (in screen space):
// 1) Around mouse: MousePosition
// 2) Fixed in top-left corner: MyGeometry.GetLayoutBoundingRect().GetTopLeft()
// 3) Fixed in centre: MyGeometry.GetLayoutBoundingRect().GetCenter()
const FVector2D PivotPoint = MyGeometry.GetAccumulatedRenderTransform().Inverse().TransformPoint(MousePosition);
const FVector2D Pivot = PivotPoint - CanvasOffset;
CanvasOffset += Pivot * (OldCanvasScale - CanvasScale) / OldCanvasScale;
}
UpdateRenderTransform();
}
void SImGuiCanvasControl::UpdateRenderTransform()
{
const FVector2D RenderOffset = Round(ContentOffset * CanvasScale + CanvasOffset);
Transform = FSlateRenderTransform(CanvasScale, RenderOffset);
OnTransformChanged.ExecuteIfBound(Transform);
}
float SImGuiCanvasControl::GetMinScale(const FGeometry& MyGeometry)
{
#if FROM_ENGINE_VERSION(4, 17)
#define GET_BOUNDING_RECT GetLayoutBoundingRect
#else
#define GET_BOUNDING_RECT GetClippingRect
#endif
const FVector2D DefaultCanvasSize = MyGeometry.GetAccumulatedRenderTransform().TransformVector(ComputeDesiredSize(1.f));
const FVector2D WidgetSize = MyGeometry.GET_BOUNDING_RECT().GetSize();
return FMath::Min(WidgetSize.X / DefaultCanvasSize.X, WidgetSize.Y / DefaultCanvasSize.Y);
#undef GET_BOUNDING_RECT
}

View File

@ -0,0 +1,108 @@
// Distributed under the MIT License (MIT) (see accompanying LICENSE file)
#pragma once
#include "ImGuiInputState.h"
#include "ImGuiModuleSettings.h"
#include <Brushes/SlateBorderBrush.h>
#include <Widgets/DeclarativeSyntaxSupport.h>
#include <Widgets/SLeafWidget.h>
// Widget that controls transform of ImGui canvas/space.
// When active, additionally it shows boundaries of ImGui canvas and default visible area.
// TODO: Bind to ImGui context or properties to dynamically read canvas size.
// TODO: Bind to properties to allow configure colors.
class SImGuiCanvasControl : public SLeafWidget
{
typedef SLeafWidget Super;
public:
DECLARE_DELEGATE_OneParam(FOnTransformChanged, const FSlateRenderTransform&);
SLATE_BEGIN_ARGS(SImGuiCanvasControl)
{}
SLATE_EVENT(FOnTransformChanged, OnTransformChanged)
SLATE_END_ARGS()
void Construct(const FArguments& InArgs);
bool IsActive() const { return bActive; }
void SetActive(bool bInActive);
const FSlateRenderTransform& GetTransform() const { return Transform; }
//----------------------------------------------------------------------------------------------------
// SWidget overrides
//----------------------------------------------------------------------------------------------------
virtual void Tick(const FGeometry& AllottedGeometry, const double InCurrentTime, const float InDeltaTime) override;
virtual FReply OnMouseButtonDown(const FGeometry& MyGeometry, const FPointerEvent& MouseEvent) override;
virtual FReply OnMouseButtonUp(const FGeometry& MyGeometry, const FPointerEvent& MouseEvent) override;
virtual FReply OnMouseWheel(const FGeometry& MyGeometry, const FPointerEvent& MouseEvent) override;
virtual FReply OnDragDetected(const FGeometry& MyGeometry, const FPointerEvent& MouseEvent) override;
virtual FReply OnDragOver(const FGeometry& MyGeometry, const FDragDropEvent& DragDropEvent) override;
virtual FReply OnDrop(const FGeometry& MyGeometry, const FDragDropEvent& DragDropEvent) override;
virtual FVector2D ComputeDesiredSize(float InScale) const override;
virtual int32 OnPaint(const FPaintArgs& Args, const FGeometry& AllottedGeometry, const FSlateRect& MyCullingRect, FSlateWindowElementList& OutDrawElements, int32 LayerId, const FWidgetStyle& InWidgetStyle, bool bParentEnabled) const override;
private:
enum class EDragRequest : uint8
{
None,
Content,
Canvas
};
void UpdateVisibility();
void Zoom(const FGeometry& MyGeometry, const float Delta, const FVector2D& MousePosition);
void UpdateRenderTransform();
float GetMinScale(const FGeometry& MyGeometry);
mutable FSlateBorderBrush CanvasBorderBrush = FSlateBorderBrush("SImGuiCanvasControl-CanvasBorder", FMargin(0.f, 0.f, 1.f, 1.f), FLinearColor::White);
mutable FSlateBorderBrush FrameBorderBrush = FSlateBorderBrush("SImGuiCanvasControl-FrameBorder", FMargin(0.f, 0.f, 1.f, 1.f), FLinearColor::White);
FOnTransformChanged OnTransformChanged;
// Transform from ImGui space.
FSlateRenderTransform Transform;
// Offset of the ImGui content in ImGui space.
FVector2D ContentOffset = FVector2D::ZeroVector;
// Offset of the ImGui canvas in widget local space.
FVector2D CanvasOffset = FVector2D::ZeroVector;
// Scale of the ImGui canvas in widget local space.
float CanvasScale = 1.f;
// Opacity scaling visibility of elements during blending.
float Opacity = 1.f;
// Whether this widget is active. While active, widget allows to modify transform of ImGui canvas, shows its
// boundaries and default visible area.
bool bActive = false;
// Whether we are blending out after widget was deactivated. While blending out, widget is visible but it doesn't
// process inputs anymore.
bool bBlendingOut = false;
// Request is set on mouse button press before drag operation is started. It remains valid until activating button
// is released or until drag operation is finished or until it is replaced by alternative request.
// Highlights are bound to requests, what means that they can also be activated before drag operation is started.
EDragRequest DragRequest = EDragRequest::None;
};

View File

@ -0,0 +1,83 @@
// Distributed under the MIT License (MIT) (see accompanying LICENSE file)
#include "SImGuiLayout.h"
#include "SImGuiWidget.h"
#include "ImGuiModuleManager.h"
#include "ImGuiModuleSettings.h"
#include <SlateOptMacros.h>
#include <Widgets/Layout/SConstraintCanvas.h>
#include <Widgets/Layout/SDPIScaler.h>
#include <Widgets/Layout/SScaleBox.h>
BEGIN_SLATE_FUNCTION_BUILD_OPTIMIZATION
void SImGuiLayout::Construct(const FArguments& InArgs)
{
checkf(InArgs._GameViewport, TEXT("Null Game Viewport argument"));
ModuleManager = InArgs._ModuleManager;
GameViewport = InArgs._GameViewport;
if (ModuleManager)
{
auto& Settings = ModuleManager->GetSettings();
SetDPIScale(Settings.GetDPIScaleInfo());
if (!Settings.OnDPIScaleChangedDelegate.IsBoundToObject(this))
{
Settings.OnDPIScaleChangedDelegate.AddRaw(this, &SImGuiLayout::SetDPIScale);
}
}
ChildSlot
[
// Remove accumulated scale to manually control how we draw data.
SNew(SScaleBox)
.IgnoreInheritedScale(true)
.HAlign(HAlign_Fill)
.VAlign(VAlign_Fill)
.Visibility(EVisibility::SelfHitTestInvisible)
[
// Apply custom scale if needed.
SNew(SDPIScaler)
.DPIScale(TAttribute<float>(this, &SImGuiLayout::GetDPIScale))
.Visibility(EVisibility::SelfHitTestInvisible)
[
SNew(SConstraintCanvas)
+ SConstraintCanvas::Slot()
.Anchors(FAnchors(0.f, 0.f, 1.f, 1.f))
.AutoSize(true)
.Offset(FMargin(1.f, 1.f, 0.f, 1.f))
.Alignment(FVector2D::ZeroVector)
[
SNew(SImGuiWidget)
.ModuleManager(InArgs._ModuleManager)
.GameViewport(InArgs._GameViewport)
.ContextIndex(InArgs._ContextIndex)
#if !ENGINE_COMPATIBILITY_LEGACY_CLIPPING_API
// To correctly clip borders. Using SScissorRectBox in older versions seems to be not necessary.
.Clipping(EWidgetClipping::ClipToBounds)
#endif
]
]
]
];
SetVisibility(EVisibility::SelfHitTestInvisible);
}
SImGuiLayout::~SImGuiLayout()
{
if (ModuleManager)
{
ModuleManager->GetSettings().OnDPIScaleChangedDelegate.RemoveAll(this);
}
}
END_SLATE_FUNCTION_BUILD_OPTIMIZATION
void SImGuiLayout::SetDPIScale(const FImGuiDPIScaleInfo& ScaleInfo)
{
DPIScale = ScaleInfo.GetSlateScale();
}

View File

@ -0,0 +1,43 @@
// Distributed under the MIT License (MIT) (see accompanying LICENSE file)
#pragma once
#include <UObject/WeakObjectPtr.h>
#include <Widgets/DeclarativeSyntaxSupport.h>
#include <Widgets/SCompoundWidget.h>
class FImGuiModuleManager;
class UGameViewportClient;
struct FImGuiDPIScaleInfo;
// Layout preset for ImGui Widget.
class SImGuiLayout : public SCompoundWidget
{
typedef SCompoundWidget Super;
public:
SLATE_BEGIN_ARGS(SImGuiLayout)
{}
SLATE_ARGUMENT(FImGuiModuleManager*, ModuleManager)
SLATE_ARGUMENT(UGameViewportClient*, GameViewport)
SLATE_ARGUMENT(int32, ContextIndex)
SLATE_END_ARGS()
void Construct(const FArguments& InArgs);
~SImGuiLayout();
const TWeakObjectPtr<UGameViewportClient>& GetGameViewport() const { return GameViewport; }
private:
float GetDPIScale() const { return DPIScale; }
void SetDPIScale(const FImGuiDPIScaleInfo& ScaleInfo);
FImGuiModuleManager* ModuleManager = nullptr;
TWeakObjectPtr<UGameViewportClient> GameViewport;
float DPIScale = 1.f;
};

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,160 @@
// Distributed under the MIT License (MIT) (see accompanying LICENSE file)
#pragma once
#include "ImGuiModuleDebug.h"
#include "ImGuiModuleSettings.h"
#include <Rendering/RenderingCommon.h>
#include <UObject/WeakObjectPtr.h>
#include <Widgets/DeclarativeSyntaxSupport.h>
#include <Widgets/SCompoundWidget.h>
// Hide ImGui Widget debug in non-developer mode.
#define IMGUI_WIDGET_DEBUG IMGUI_MODULE_DEVELOPER
class FImGuiModuleManager;
class SImGuiCanvasControl;
class UImGuiInputHandler;
class UGameViewportClient;
class ULocalPlayer;
// Slate widget for rendering ImGui output and storing Slate inputs.
class SImGuiWidget : public SCompoundWidget
{
typedef SCompoundWidget Super;
public:
SLATE_BEGIN_ARGS(SImGuiWidget)
{}
SLATE_ARGUMENT(FImGuiModuleManager*, ModuleManager)
SLATE_ARGUMENT(UGameViewportClient*, GameViewport)
SLATE_ARGUMENT(int32, ContextIndex)
SLATE_END_ARGS()
void Construct(const FArguments& InArgs);
~SImGuiWidget();
// Get index of the context that this widget is targeting.
int32 GetContextIndex() const { return ContextIndex; }
//----------------------------------------------------------------------------------------------------
// SWidget overrides
//----------------------------------------------------------------------------------------------------
virtual void Tick(const FGeometry& AllottedGeometry, const double InCurrentTime, const float InDeltaTime) override;
virtual bool SupportsKeyboardFocus() const override { return bInputEnabled && !IsConsoleOpened(); }
virtual FReply OnKeyChar(const FGeometry& MyGeometry, const FCharacterEvent& CharacterEvent) override;
virtual FReply OnKeyDown(const FGeometry& MyGeometry, const FKeyEvent& KeyEvent) override;
virtual FReply OnKeyUp(const FGeometry& MyGeometry, const FKeyEvent& KeyEvent) override;
virtual FReply OnAnalogValueChanged(const FGeometry& MyGeometry, const FAnalogInputEvent& AnalogInputEvent) override;
virtual FReply OnMouseButtonDown(const FGeometry& MyGeometry, const FPointerEvent& MouseEvent) override;
virtual FReply OnMouseButtonDoubleClick(const FGeometry& MyGeometry, const FPointerEvent& MouseEvent) override;
virtual FReply OnMouseButtonUp(const FGeometry& MyGeometry, const FPointerEvent& MouseEvent) override;
virtual FReply OnMouseWheel(const FGeometry& MyGeometry, const FPointerEvent& MouseEvent) override;
virtual FReply OnMouseMove(const FGeometry& MyGeometry, const FPointerEvent& MouseEvent) override;
virtual FReply OnFocusReceived(const FGeometry& MyGeometry, const FFocusEvent& FocusEvent) override;
virtual void OnFocusLost(const FFocusEvent& FocusEvent) override;
virtual void OnMouseEnter(const FGeometry& MyGeometry, const FPointerEvent& MouseEvent) override;
virtual void OnMouseLeave(const FPointerEvent& MouseEvent) override;
virtual FReply OnTouchStarted(const FGeometry& MyGeometry, const FPointerEvent& TouchEvent) override;
virtual FReply OnTouchMoved(const FGeometry& MyGeometry, const FPointerEvent& TouchEvent) override;
virtual FReply OnTouchEnded(const FGeometry& MyGeometry, const FPointerEvent& TouchEvent) override;
private:
void CreateInputHandler(const FStringClassReference& HandlerClassReference);
void ReleaseInputHandler();
void RegisterImGuiSettingsDelegates();
void UnregisterImGuiSettingsDelegates();
void SetHideMouseCursor(bool bHide);
bool IsConsoleOpened() const;
// Update visibility based on input state.
void UpdateVisibility();
// Update cursor based on input state.
void UpdateMouseCursor();
ULocalPlayer* GetLocalPlayer() const;
void TakeFocus();
void ReturnFocus();
// Update input state.
void UpdateInputState();
void UpdateTransparentMouseInput(const FGeometry& AllottedGeometry);
void HandleWindowFocusLost();
void SetDPIScale(const FImGuiDPIScaleInfo& ScaleInfo);
void SetCanvasSizeInfo(const FImGuiCanvasSizeInfo& CanvasSizeInfo);
void UpdateCanvasSize();
void UpdateCanvasControlMode(const FInputEvent& InputEvent);
void OnPostImGuiUpdate();
FVector2D TransformScreenPointToImGui(const FGeometry& MyGeometry, const FVector2D& Point) const;
virtual int32 OnPaint(const FPaintArgs& Args, const FGeometry& AllottedGeometry, const FSlateRect& MyClippingRect, FSlateWindowElementList& OutDrawElements, int32 LayerId, const FWidgetStyle& WidgetStyle, bool bParentEnabled) const override;
virtual FVector2D ComputeDesiredSize(float) const override;
void SetImGuiTransform(const FSlateRenderTransform& Transform) { ImGuiTransform = Transform; }
#if IMGUI_WIDGET_DEBUG
void OnDebugDraw();
#endif // IMGUI_WIDGET_DEBUG
FImGuiModuleManager* ModuleManager = nullptr;
TWeakObjectPtr<UGameViewportClient> GameViewport;
TWeakObjectPtr<UImGuiInputHandler> InputHandler;
FSlateRenderTransform ImGuiTransform;
FSlateRenderTransform ImGuiRenderTransform;
mutable TArray<FSlateVertex> VertexBuffer;
mutable TArray<SlateIndex> IndexBuffer;
int32 ContextIndex = 0;
FVector2D MinCanvasSize = FVector2D::ZeroVector;
FVector2D CanvasSize = FVector2D::ZeroVector;
float DPIScale = 1.f;
bool bInputEnabled = false;
bool bForegroundWindow = false;
bool bHideMouseCursor = true;
bool bTransparentMouseInput = false;
bool bAdaptiveCanvasSize = false;
bool bUpdateCanvasSize = false;
bool bCanvasControlEnabled = false;
TSharedPtr<SImGuiCanvasControl> CanvasControlWidget;
TWeakPtr<SWidget> PreviousUserFocusedWidget;
};

View File

@ -0,0 +1,117 @@
// Distributed under the MIT License (MIT) (see accompanying LICENSE file)
#pragma once
#include <Delegates/Delegate.h>
class UWorld;
/**
* Delegates to ImGui debug events. World delegates are called once per frame during world updates and have invocation
* lists cleared after their worlds become invalid. Multi-context delegates are called once for every updated world.
* Early debug delegates are called during world tick start and debug delegates are called during world post actor tick
* or in engine versions below 4.18 during world tick start.
*
* Order of events is defined in a way that multi-context delegates can be used to draw headers and/or footers:
* multi-context early debug, world early debug, world debug, multi-context debug.
*/
class IMGUI_API FImGuiDelegates
{
public:
/**
* Get a delegate to ImGui world early debug event for current world (GWorld).
* @returns Simple multicast delegate to debug events called once per frame to debug current world
*/
static FSimpleMulticastDelegate& OnWorldEarlyDebug();
/**
* Get a delegate to ImGui world early debug event for given world.
* @param World - World for which we need a delegate
* @returns Simple multicast delegate to debug events called once per frame to debug given world
*/
static FSimpleMulticastDelegate& OnWorldEarlyDebug(UWorld* World);
/**
* Get a delegate to ImGui multi-context early debug event.
* @returns Simple multicast delegate to debug events called once per frame for every world to debug
*/
static FSimpleMulticastDelegate& OnMultiContextEarlyDebug();
/**
* Get a delegate to ImGui world debug event for current world (GWorld).
* @returns Simple multicast delegate to debug events called once per frame to debug current world
*/
static FSimpleMulticastDelegate& OnWorldDebug();
/**
* Get a delegate to ImGui world debug event for given world.
* @param World - World for which we need a delegate
* @returns Simple multicast delegate to debug events called once per frame to debug given world
*/
static FSimpleMulticastDelegate& OnWorldDebug(UWorld* World);
/**
* Get a delegate to ImGui multi-context debug event.
* @returns Simple multicast delegate to debug events called once per frame for every world to debug
*/
static FSimpleMulticastDelegate& OnMultiContextDebug();
};
/** Enable to support legacy ImGui delegates API. */
#define IMGUI_WITH_OBSOLETE_DELEGATES 1
#if IMGUI_WITH_OBSOLETE_DELEGATES
/** Delegate that allows to subscribe for ImGui events. */
typedef FSimpleMulticastDelegate::FDelegate FImGuiDelegate;
/**
* Handle to ImGui delegate. Contains additional information locating delegates in different contexts.
*/
class FImGuiDelegateHandle
{
public:
FImGuiDelegateHandle() = default;
bool IsValid() const
{
return Handle.IsValid();
}
void Reset()
{
Handle.Reset();
Index = 0;
}
private:
FImGuiDelegateHandle(const FDelegateHandle& InHandle, int32 InCategory, int32 InIndex = 0)
: Handle(InHandle)
, Category(InCategory)
, Index(InIndex)
{
}
friend bool operator==(const FImGuiDelegateHandle& Lhs, const FImGuiDelegateHandle& Rhs)
{
return Lhs.Handle == Rhs.Handle && Lhs.Category == Rhs.Category && Lhs.Index == Rhs.Index;
}
friend bool operator!=(const FImGuiDelegateHandle& Lhs, const FImGuiDelegateHandle& Rhs)
{
return !(Lhs == Rhs);
}
FDelegateHandle Handle;
int32 Category = 0;
int32 Index = 0;
friend class FImGuiModule;
};
#endif // IMGUI_WITH_OBSOLETE_DELEGATES

View File

@ -0,0 +1,198 @@
// Distributed under the MIT License (MIT) (see accompanying LICENSE file)
#pragma once
#include <CoreMinimal.h>
#include <Input/Reply.h>
#include <UObject/Object.h>
#include <UObject/WeakObjectPtr.h>
#include "ImGuiInputHandler.generated.h"
class FImGuiModuleManager;
class UGameViewportClient;
struct FAnalogInputEvent;
struct FCharacterEvent;
struct FKeyEvent;
#if WITH_EDITOR
class FUICommandInfo;
#endif // WITH_EDITOR
/**
* Handles input and sends it to the input state, which is copied to the ImGui IO at the beginning of the frame.
* Implementation of the input handler can be changed in the ImGui project settings by changing ImGuiInputHandlerClass.
*/
UCLASS()
class IMGUI_API UImGuiInputHandler : public UObject
{
GENERATED_BODY()
public:
/**
* Called to handle character events.
* @returns Response whether the event was handled
*/
virtual FReply OnKeyChar(const struct FCharacterEvent& CharacterEvent);
/**
* Called to handle key down events.
* @returns Response whether the event was handled
*/
virtual FReply OnKeyDown(const FKeyEvent& KeyEvent);
/**
* Called to handle key up events.
* @returns Response whether the event was handled
*/
virtual FReply OnKeyUp(const FKeyEvent& KeyEvent);
/**
* Called to handle analog value change events.
* @returns Response whether the event was handled
*/
virtual FReply OnAnalogValueChanged(const FAnalogInputEvent& AnalogInputEvent);
/**
* Called to handle mouse button down events.
* @returns Response whether the event was handled
*/
virtual FReply OnMouseButtonDown(const FPointerEvent& MouseEvent);
/**
* Called to handle mouse button double-click events.
* @returns Response whether the event was handled
*/
virtual FReply OnMouseButtonDoubleClick(const FPointerEvent& MouseEvent);
/**
* Called to handle mouse button up events.
* @returns Response whether the event was handled
*/
virtual FReply OnMouseButtonUp(const FPointerEvent& MouseEvent);
/**
* Called to handle mouse wheel events.
* @returns Response whether the event was handled
*/
virtual FReply OnMouseWheel(const FPointerEvent& MouseEvent);
/**
* Called to handle mouse move events.
* @param MousePosition Mouse position (in ImGui space)
* @param MouseEvent Optional mouse event passed from Slate
* @returns Response whether the event was handled
*/
virtual FReply OnMouseMove(const FVector2D& MousePosition, const FPointerEvent& MouseEvent);
virtual FReply OnMouseMove(const FVector2D& MousePosition);
/**
* Called to handle touch started event.
* @param TouchPosition Touch position (in ImGui space)
* @param TouchEvent Touch event passed from Slate
* @returns Response whether the event was handled
*/
virtual FReply OnTouchStarted(const FVector2D& TouchPosition, const FPointerEvent& TouchEvent);
/**
* Called to handle touch moved event.
* @param TouchPosition Touch position (in ImGui space)
* @param TouchEvent Touch event passed from Slate
* @returns Response whether the event was handled
*/
virtual FReply OnTouchMoved(const FVector2D& TouchPosition, const FPointerEvent& TouchEvent);
/**
* Called to handle touch ended event.
* @param TouchPosition Touch position (in ImGui space)
* @param TouchEvent Touch event passed from Slate
* @returns Response whether the event was handled
*/
virtual FReply OnTouchEnded(const FVector2D& TouchPosition, const FPointerEvent& TouchEvent);
/** Called to handle activation of the keyboard input. */
virtual void OnKeyboardInputEnabled();
/** Called to handle deactivation of the keyboard input. */
virtual void OnKeyboardInputDisabled();
/** Called to handle activation of the gamepad input. */
virtual void OnGamepadInputEnabled();
/** Called to handle deactivation of the gamepad input. */
virtual void OnGamepadInputDisabled();
/** Called to handle activation of the mouse input. */
virtual void OnMouseInputEnabled();
/** Called to handle deactivation of the mouse input. */
virtual void OnMouseInputDisabled();
protected:
/** Copy state of modifier keys to input state. */
void CopyModifierKeys(const FInputEvent& InputEvent);
/**
* Checks whether this is a key event that can open console.
* @param KeyEvent - Key event to test.
* @returns True, if this key event can open console.
*/
bool IsConsoleEvent(const FKeyEvent& KeyEvent) const;
#if WITH_EDITOR
/**
* Checks whether this is a key event that can stop PIE session.
* @param KeyEvent - Key event to test.
* @returns True, if this key event can stop PIE session.
*/
bool IsStopPlaySessionEvent(const FKeyEvent& KeyEvent) const;
#endif
/**
* Checks whether this key event can toggle ImGui input (as defined in settings).
* @param KeyEvent - Key event to test.
* @returns True, if this key is bound to 'ImGui.ToggleInput' command that switches ImGui input mode.
*/
bool IsToggleInputEvent(const FKeyEvent& KeyEvent) const;
/**
* Checks whether corresponding ImGui context has an active item (holding cursor focus).
* @returns True, if corresponding context has an active item.
*/
bool HasImGuiActiveItem() const;
private:
void UpdateInputStatePointer();
void OnSoftwareCursorChanged(bool);
void OnPostImGuiUpdate();
void Initialize(FImGuiModuleManager* InModuleManager, UGameViewportClient* InGameViewport, int32 InContextIndex);
virtual void BeginDestroy() override;
class FImGuiInputState* InputState = nullptr;
bool bMouseInputEnabled = false;
bool bKeyboardInputEnabled = false;
bool bGamepadInputEnabled = false;
FImGuiModuleManager* ModuleManager = nullptr;
TWeakObjectPtr<UGameViewportClient> GameViewport;
int32 ContextIndex = -1;
#if WITH_EDITOR
TSharedPtr<FUICommandInfo> StopPlaySessionCommandInfo;
#endif
friend class FImGuiInputHandlerFactory;
};

View File

@ -0,0 +1,176 @@
// Distributed under the MIT License (MIT) (see accompanying LICENSE file)
#pragma once
#include "ImGuiDelegates.h"
#include "ImGuiModuleProperties.h"
#include "ImGuiTextureHandle.h"
#include <Modules/ModuleManager.h>
class FImGuiModule : public IModuleInterface
{
public:
/**
* Singleton-like access to this module's interface. This is just for convenience!
* Beware of calling this during the shutdown phase, though. Your module might have been unloaded already.
*
* @return Returns singleton instance, loading the module on demand if needed
*/
static inline FImGuiModule& Get()
{
return FModuleManager::LoadModuleChecked<FImGuiModule>("ImGui");
}
/**
* Checks to see if this module is loaded and ready. It is only valid to call Get() if IsAvailable() returns true.
*
* @return True if the module is loaded and ready to use
*/
static inline bool IsAvailable()
{
return FModuleManager::Get().IsModuleLoaded("ImGui");
}
#if IMGUI_WITH_OBSOLETE_DELEGATES
#if WITH_EDITOR
/**
* Add a delegate called at the end of editor debug frame to draw debug controls in its ImGui context, creating
* that context on demand.
*
* @param Delegate - Delegate that we want to add (@see FImGuiDelegate::Create...)
* @returns Returns handle that can be used to remove delegate (@see RemoveImGuiDelegate)
*/
virtual FImGuiDelegateHandle AddEditorImGuiDelegate(const FImGuiDelegate& Delegate);
#endif
/**
* Add a delegate called at the end of current world debug frame to draw debug controls in its ImGui context,
* creating that context on demand.
* This function will throw if called outside of a world context (i.e. current world cannot be found).
*
* @param Delegate - Delegate that we want to add (@see FImGuiDelegate::Create...)
* @returns Returns handle that can be used to remove delegate (@see RemoveImGuiDelegate)
*/
virtual FImGuiDelegateHandle AddWorldImGuiDelegate(const FImGuiDelegate& Delegate);
/**
* Add shared delegate called for each ImGui context at the end of debug frame, after calling context specific
* delegate. This delegate will be used for any ImGui context, created before or after it is registered.
*
* @param Delegate - Delegate that we want to add (@see FImGuiDelegate::Create...)
* @returns Returns handle that can be used to remove delegate (@see RemoveImGuiDelegate)
*/
virtual FImGuiDelegateHandle AddMultiContextImGuiDelegate(const FImGuiDelegate& Delegate);
/**
* Remove delegate added with any version of Add...ImGuiDelegate
*
* @param Handle - Delegate handle that was returned by adding function
*/
virtual void RemoveImGuiDelegate(const FImGuiDelegateHandle& Handle);
#endif // #if IMGUI_WITH_OBSOLETE_DELEGATES
/**
* If it exists, get a handle to the texture with given resource name.
*
* @param Name - Resource name of a texture to find
* @returns Handle to a registered texture or invalid handle if resources could not be found or were not valid
*/
virtual FImGuiTextureHandle FindTextureHandle(const FName& Name);
/**
* Register texture and create its Slate resources. If texture with that name already exists then it may be updated
* or if bMakeUnique is true, exception will be thrown. Throws exception, if name argument is NAME_None or texture
* is null.
*
* Note, that updating texture resources doesn't invalidate already existing handles and returned handle will have
* the same value.
*
* @param Name - Resource name for the texture that needs to be registered or updated
* @param Texture - Texture for which we want to create or update Slate resources
* @param bMakeUnique - If false then existing resources are updated/overwritten (default). If true, then stricter
* policy is applied and if resource with that name exists then exception is thrown.
* @returns Handle to the texture resources, which can be used to release allocated resources and as an argument to
* relevant ImGui functions
*/
virtual FImGuiTextureHandle RegisterTexture(const FName& Name, class UTexture2D* Texture, bool bMakeUnique = false);
/**
* Unregister texture and release its Slate resources. If handle is null or not valid, this function fails silently
* (for definition of 'valid' look @ FImGuiTextureHandle).
*
* @returns ImGui Texture Handle to texture that needs to be unregistered
*/
virtual void ReleaseTexture(const FImGuiTextureHandle& Handle);
/**
* Get ImGui module properties.
*
* @returns Reference to an instance of ImGui module properties that allows to read and/or modify module state.
*/
virtual FImGuiModuleProperties& GetProperties();
virtual const FImGuiModuleProperties& GetProperties() const;
/**
* DEPRECIATED: Please use GetProperties() as this function is scheduled for removal.
* Check whether Input Mode is enabled (tests ImGui.InputEnabled console variable).
*
* @returns True, if Input Mode is enabled (ImGui.InputEnabled != 0) and false otherwise.
*/
virtual bool IsInputMode() const;
/**
* DEPRECIATED: Please use GetProperties() as this function is scheduled for removal.
* Set Input Mode state (sets ImGui.InputEnabled console variable, so it can be used together with a console).
*
* @param bEnabled - Whether Input Mode should be enabled (ImGui.InputEnabled = 1) or not (ImGui.InputEnabled = 0).
*/
virtual void SetInputMode(bool bEnabled);
/**
* DEPRECIATED: Please use GetProperties() as this function is scheduled for removal.
* Toggle Input Mode state (changes ImGui.InputEnabled console variable).
*/
virtual void ToggleInputMode();
/**
* DEPRECIATED: Please use GetProperties() as this function is scheduled for removal.
* Check whether ImGui Demo is shown (tests ImGui.ShowDemo console variable).
*
* @returns True, if demo is shown (ImGui.ShowDemo != 0) and false otherwise.
*/
virtual bool IsShowingDemo() const;
/**
* DEPRECIATED: Please use GetProperties() as this function is scheduled for removal.
* Set whether to show ImGui Demo (sets ImGui.ShowDemo console variable, so it can be used together with a console).
*
* @param bShow - Whether to show ImGui Demo (ImGui.ShowDemo = 1) or not (ImGui.ShowDemo = 0).
*/
virtual void SetShowDemo(bool bShow);
/**
* DEPRECIATED: Please use GetProperties() as this function is scheduled for removal.
* Toggle ImGui Demo (changes ImGui.ShowDemo console variable).
*/
virtual void ToggleShowDemo();
/** IModuleInterface implementation */
virtual void StartupModule() override;
virtual void ShutdownModule() override;
private:
#if WITH_EDITOR
virtual void SetProperties(const FImGuiModuleProperties& Properties);
struct FImGuiContextHandle* ImGuiContextHandle = nullptr;
struct FImGuiDelegatesContainerHandle* DelegatesContainerHandle = nullptr;
friend struct FImGuiContextHandle;
friend struct FImGuiDelegatesContainerHandle;
#endif
};

View File

@ -0,0 +1,86 @@
// Distributed under the MIT License (MIT) (see accompanying LICENSE file)
#pragma once
/** Properties that define state of the ImGui module. */
class IMGUI_API FImGuiModuleProperties
{
public:
/** Check whether input is enabled. */
bool IsInputEnabled() const { return bInputEnabled; }
/** Enable or disable ImGui input. */
void SetInputEnabled(bool bEnabled) { bInputEnabled = bEnabled; }
/** Toggle ImGui input. */
void ToggleInput() { SetInputEnabled(!IsInputEnabled()); }
/** Check whether keyboard navigation is enabled. */
bool IsKeyboardNavigationEnabled() const { return bKeyboardNavigationEnabled; }
/** Enable or disable keyboard navigation. */
void SetKeyboardNavigationEnabled(bool bEnabled) { bKeyboardNavigationEnabled = bEnabled; }
/** Toggle keyboard navigation. */
void ToggleKeyboardNavigation() { SetKeyboardNavigationEnabled(!IsKeyboardNavigationEnabled()); }
/** Check whether gamepad navigation is enabled. */
bool IsGamepadNavigationEnabled() const { return bGamepadNavigationEnabled; }
/** Enable or disable gamepad navigation. */
void SetGamepadNavigationEnabled(bool bEnabled) { bGamepadNavigationEnabled = bEnabled; }
/** Toggle gamepad navigation. */
void ToggleGamepadNavigation() { SetGamepadNavigationEnabled(!IsGamepadNavigationEnabled()); }
/** Check whether keyboard input is shared with game. */
bool IsKeyboardInputShared() const { return bKeyboardInputShared; }
/** Set whether keyboard input should be shared with game. */
void SetKeyboardInputShared(bool bShared) { bKeyboardInputShared = bShared; }
/** Toggle whether keyboard input should be shared with game. */
void ToggleKeyboardInputSharing() { SetKeyboardInputShared(!IsKeyboardInputShared()); }
/** Check whether gamepad input is shared with game. */
bool IsGamepadInputShared() const { return bGamepadInputShared; }
/** Set whether gamepad input should be shared with game. */
void SetGamepadInputShared(bool bShared) { bGamepadInputShared = bShared; }
/** Toggle whether gamepad input should be shared with game. */
void ToggleGamepadInputSharing() { SetGamepadInputShared(!IsGamepadInputShared()); }
/** Check whether mouse input is shared with game. */
bool IsMouseInputShared() const { return bMouseInputShared; }
/** Set whether mouse input should be shared with game. */
void SetMouseInputShared(bool bShared) { bMouseInputShared = bShared; }
/** Toggle whether mouse input should be shared with game. */
void ToggleMouseInputSharing() { SetMouseInputShared(!IsMouseInputShared()); }
/** Check whether ImGui demo is visible. */
bool ShowDemo() const { return bShowDemo; }
/** Show or hide ImGui demo. */
void SetShowDemo(bool bShow) { bShowDemo = bShow; }
/** Toggle ImGui demo. */
void ToggleDemo() { SetShowDemo(!ShowDemo()); }
private:
bool bInputEnabled = false;
bool bKeyboardNavigationEnabled = false;
bool bGamepadNavigationEnabled = false;
bool bKeyboardInputShared = false;
bool bGamepadInputShared = false;
bool bMouseInputShared = false;
bool bShowDemo = false;
};

View File

@ -0,0 +1,64 @@
// Distributed under the MIT License (MIT) (see accompanying LICENSE file)
#pragma once
#include <CoreMinimal.h>
#include <imgui.h>
/**
* Handle to texture resources registered in module instance. Returned after successful texture registration.
* Can be implicitly converted to ImTextureID making it possible to use it directly with ImGui interface.
* Once texture is not needed handle can be used to release resources.
*/
class IMGUI_API FImGuiTextureHandle
{
public:
/** Creates an empty (null and not valid) texture handle. */
FImGuiTextureHandle();
/**
* Checks whether this handle is null. Can be used as a quick test whether it points to any resources but it does
* not check whether those resources are valid (see @ IsValid).
*
* @returns True, if this handle is null (Name is NAME_None and TextureId is invalid) and false otherwise.
*/
bool IsNull() const { return Name == NAME_None; }
/**
* Checks whether this handle is not null and valid. Valid handle points to valid texture resources.
* It is slower but safer test, more useful when there is no guarantee that resources haven't been released.
*
* @returns True, if this handle is not null and valid, false otherwise.
*/
bool IsValid() const { return !IsNull() && HasValidEntry(); }
/** Get the name of the texture resources (NAME_None if handle is null). */
const FName& GetName() const { return Name; }
/** Get the ImGui texture id for this texture (invalid if handle is null). */
ImTextureID GetTextureId() const { return TextureId; }
/** Implicit conversion to ImTextureID. */
operator ImTextureID() const { return GetTextureId(); }
private:
/**
* Creates a texture handle with known name and texture id.
* @param InName - Name of the texture
* @param InTextureId - ImGui id of texture
*/
FImGuiTextureHandle(const FName& InName, ImTextureID InTextureId);
/** Checks if texture manager has entry that matches this name and texture id index. */
bool HasValidEntry() const;
FName Name;
ImTextureID TextureId;
// Give module class a private access, so it can create valid handles.
friend class FImGuiModule;
};

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,536 @@
# FAQ (Frequenty Asked Questions)
You may link to this document using short form:
https://www.dearimgui.org/faq
or its real address:
https://github.com/ocornut/imgui/blob/master/docs/FAQ.md
or view this file with any Markdown viewer.
## Index
| **Q&A: Basics** |
:---------------------------------------------------------- |
| [Where is the documentation?](#q-where-is-the-documentation) |
| [Which version should I get?](#q-which-version-should-i-get) |
| [Why the names "Dear ImGui" vs "ImGui"?](#q-why-the-names-dear-imgui-vs-imgui) |
| **Q&A: Concerns** |
| [Who uses Dear ImGui?](#q-who-uses-dear-imgui) |
| [Can you create elaborate/serious tools with Dear ImGui?](#q-can-you-create-elaborateserious-tools-with-dear-imgui) |
| [Can you reskin the look of Dear ImGui?](#q-can-you-reskin-the-look-of-dear-imgui) |
| [Why using C++ (as opposed to C)?](#q-why-using-c-as-opposed-to-c) |
| **Q&A: Integration** |
| [How can I tell whether to dispatch mouse/keyboard to Dear ImGui or to my application?](#q-how-can-i-tell-whether-to-dispatch-mousekeyboard-to-dear-imgui-or-to-my-application) |
| [How can I use this without a mouse, without a keyboard or without a screen? (gamepad, input share, remote display)](#q-how-can-i-use-this-without-a-mouse-without-a-keyboard-or-without-a-screen-gamepad-input-share-remote-display) |
| [I integrated Dear ImGui in my engine and the text or lines are blurry..](#q-i-integrated-dear-imgui-in-my-engine-and-the-text-or-lines-are-blurry) |
| [I integrated Dear ImGui in my engine and some elements are clipping or disappearing when I move windows around..](#q-i-integrated-dear-imgui-in-my-engine-and-some-elements-are-clipping-or-disappearing-when-i-move-windows-around) |
| **Q&A: Usage** |
| [Why are multiple widgets reacting when I interact with a single one?<br>How can I have multiple widgets with the same label or with an empty label?](#q-why-are-multiple-widgets-reacting-when-i-interact-with-a-single-one-q-how-can-i-have-multiple-widgets-with-the-same-label-or-with-an-empty-label) |
| [How can I display an image? What is ImTextureID, how does it work?](#q-how-can-i-display-an-image-what-is-imtextureid-how-does-it-work)|
| [How can I use my own math types instead of ImVec2/ImVec4?](#q-how-can-i-use-my-own-math-types-instead-of-imvec2imvec4) |
| [How can I interact with standard C++ types (such as std::string and std::vector)?](#q-how-can-i-interact-with-standard-c-types-such-as-stdstring-and-stdvector) |
| [How can I display custom shapes? (using low-level ImDrawList API)](#q-how-can-i-display-custom-shapes-using-low-level-imdrawlist-api) |
| **Q&A: Fonts, Text** |
| [How can I load a different font than the default?](#q-how-can-i-load-a-different-font-than-the-default) |
| [How can I easily use icons in my application?](#q-how-can-i-easily-use-icons-in-my-application) |
| [How can I load multiple fonts?](#q-how-can-i-load-multiple-fonts) |
| [How can I display and input non-Latin characters such as Chinese, Japanese, Korean, Cyrillic?](#q-how-can-i-display-and-input-non-latin-characters-such-as-chinese-japanese-korean-cyrillic) |
| **Q&A: Community** |
| [How can I help?](#q-how-can-i-help) |
# Q&A: Basics
### Q: Where is the documentation?
**This library is poorly documented at the moment and expects of the user to be acquainted with C/C++.**
- Run the examples/ and explore them.
- See demo code in [imgui_demo.cpp](https://github.com/ocornut/imgui/blob/master/imgui_demo.cpp) and particularly the `ImGui::ShowDemoWindow()` function.
- The demo covers most features of Dear ImGui, so you can read the code and see its output.
- See documentation and comments at the top of [imgui.cpp](https://github.com/ocornut/imgui/blob/master/imgui.cpp) + general API comments in [imgui.h](https://github.com/ocornut/imgui/blob/master/imgui.h).
- Dozens of standalone example applications using e.g. OpenGL/DirectX are provided in the [examples/](https://github.com/ocornut/imgui/blob/master/examples/) folder to explain how to integrate Dear ImGui with your own engine/application.
- Your programming IDE is your friend, find the type or function declaration to find comments associated to it.
---
### Q: Which version should I get?
I occasionally tag [Releases](https://github.com/ocornut/imgui/releases) but it is generally safe and recommended to sync to master/latest. The library is fairly stable and regressions tend to be fixed fast when reported.
You may also peak at the [docking](https://github.com/ocornut/imgui/tree/docking) branch which includes:
- [Docking/Merging features](https://github.com/ocornut/imgui/issues/2109)
- [Multi-viewport features](https://github.com/ocornut/imgui/issues/1542)
Many projects are using this branch and it is kept in sync with master regularly.
---
### Q: Why the names "Dear ImGui" vs "ImGui"?
**TL;DR: Please try to refer to this library as "Dear ImGui".**
The library started its life as "ImGui" due to the fact that I didn't give it a proper name when when I released 1.0, and had no particular expectation that it would take off. However, the term IMGUI (immediate-mode graphical user interface) was coined before and is being used in variety of other situations (e.g. Unity uses it own implementation of the IMGUI paradigm). To reduce the ambiguity without affecting existing code bases, I have decided on an alternate, longer name "Dear ImGui" that people can use to refer to this specific library.
##### [Return to Index](#index)
# Q&A: Concerns
### Q: Who uses Dear ImGui?
You may take a look at:
- [Quotes](https://github.com/ocornut/imgui/wiki/Quotes)
- [Software using Dear ImGui](https://github.com/ocornut/imgui/wiki/Software-using-dear-imgui)
- [Gallery](https://github.com/ocornut/imgui/issues/2847)
### Q: Can you create elaborate/serious tools with Dear ImGui?
Yes. People have written game editors, data browsers, debuggers, profilers and all sort of non-trivial tools with the library. In my experience the simplicity of the API is very empowering. Your UI runs close to your live data. Make the tools always-on and everybody in the team will be inclined to create new tools (as opposed to more "offline" UI toolkits where only a fraction of your team effectively creates tools). The list of sponsors below is also an indicator that serious game teams have been using the library.
Dear ImGui is very programmer centric and the immediate-mode GUI paradigm might require you to readjust some habits before you can realize its full potential. Dear ImGui is about making things that are simple, efficient and powerful.
Dear ImGui is built to be efficient and scalable toward the needs for AAA-quality applications running all day. The IMGUI paradigm offers different opportunities for optimization that the more typical RMGUI paradigm.
### Q: Can you reskin the look of Dear ImGui?
Somehow. You can alter the look of the interface to some degree: changing colors, sizes, padding, rounding, fonts. However, as Dear ImGui is designed and optimized to create debug tools, the amount of skinning you can apply is limited. There is only so much you can stray away from the default look and feel of the interface. Dear ImGui is NOT designed to create user interface for games, although with ingenious use of the low-level API you can do it.
A reasonably skinned application may look like (screenshot from [#2529](https://github.com/ocornut/imgui/issues/2529#issuecomment-524281119))
![minipars](https://user-images.githubusercontent.com/314805/63589441-d9794f00-c5b1-11e9-8d96-cfc1b93702f7.png)
### Q: Why using C++ (as opposed to C)?
Dear ImGui takes advantage of a few C++ languages features for convenience but nothing anywhere Boost insanity/quagmire. Dear ImGui does NOT require C++11 so it can be used with most old C++ compilers. Dear ImGui doesn't use any C++ header file. Language-wise, function overloading and default parameters are used to make the API easier to use and code more terse. Doing so I believe the API is sitting on a sweet spot and giving up on those features would make the API more cumbersome. Other features such as namespace, constructors and templates (in the case of the ImVector<> class) are also relied on as a convenience.
There is an auto-generated [c-api for Dear ImGui (cimgui)](https://github.com/cimgui/cimgui) by Sonoro1234 and Stephan Dilly. It is designed for creating binding to other languages. If possible, I would suggest using your target language functionalities to try replicating the function overloading and default parameters used in C++ else the API may be harder to use. Also see [Bindings](https://github.com/ocornut/imgui/wiki/Bindings) for various third-party bindings.
##### [Return to Index](#index)
# Q&A: Integration
### Q: How can I tell whether to dispatch mouse/keyboard to Dear ImGui or to my application?
You can read the `io.WantCaptureMouse`, `io.WantCaptureKeyboard` and `io.WantTextInput` flags from the ImGuiIO structure.
e.g. `if (ImGui::GetIO().WantCaptureMouse) { ... }`
- When `io.WantCaptureMouse` is set, imgui wants to use your mouse state, and you may want to discard/hide the inputs from the rest of your application.
- When `io.WantCaptureKeyboard` is set, imgui wants to use your keyboard state, and you may want to discard/hide the inputs from the rest of your application.
- When `io.WantTextInput` is set to may want to notify your OS to popup an on-screen keyboard, if available (e.g. on a mobile phone, or console OS).
**Note:** You should always pass your mouse/keyboard inputs to Dear ImGui, even when the io.WantCaptureXXX flag are set false.
This is because imgui needs to detect that you clicked in the void to unfocus its own windows.
**Note:** The `io.WantCaptureMouse` is more accurate that any manual attempt to "check if the mouse is hovering a window" (don't do that!). It handle mouse dragging correctly (both dragging that started over your application or over an imgui window) and handle e.g. modal windows blocking inputs. Those flags are updated by `ImGui::NewFrame()`. Preferably read the flags after calling NewFrame() if you can afford it, but reading them before is also perfectly fine, as the bool toggle fairly rarely. If you have on a touch device, you might find use for an early call to `UpdateHoveredWindowAndCaptureFlags()`.
**Note:** Text input widget releases focus on "Return KeyDown", so the subsequent "Return KeyUp" event that your application receive will typically have `io.WantCaptureKeyboard == false`. Depending on your application logic it may or not be inconvenient. You might want to track which key-downs were targeted for Dear ImGui, e.g. with an array of bool, and filter out the corresponding key-ups.)
---
### Q: How can I use this without a mouse, without a keyboard or without a screen? (gamepad, input share, remote display)
- You can control Dear ImGui with a gamepad. Read about navigation in "Using gamepad/keyboard navigation controls".
(short version: map gamepad inputs into the io.NavInputs[] array + set `io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad`).
- You can share your computer mouse seamlessly with your console/tablet/phone using [Synergy](https://symless.com/synergy)
This is the preferred solution for developer productivity.
In particular, the [micro-synergy-client repository](https://github.com/symless/micro-synergy-client) has simple
and portable source code (uSynergy.c/.h) for a small embeddable client that you can use on any platform to connect
to your host computer, based on the Synergy 1.x protocol. Make sure you download the Synergy 1 server on your computer.
Console SDK also sometimes provide equivalent tooling or wrapper for Synergy-like protocols.
- You may also use a third party solution such as [Remote ImGui](https://github.com/JordiRos/remoteimgui) or [imgui-ws](https://github.com/ggerganov/imgui-ws) which sends the vertices to render over the local network, allowing you to use Dear ImGui even on a screen-less machine. See Wiki index for most details.
- For touch inputs, you can increase the hit box of widgets (via the `style.TouchPadding` setting) to accommodate
for the lack of precision of touch inputs, but it is recommended you use a mouse or gamepad to allow optimizing
for screen real-estate and precision.
---
### Q: I integrated Dear ImGui in my engine and the text or lines are blurry..
In your Render function, try translating your projection matrix by (0.5f,0.5f) or (0.375f,0.375f).
Also make sure your orthographic projection matrix and io.DisplaySize matches your actual framebuffer dimension.
---
### Q: I integrated Dear ImGui in my engine and some elements are clipping or disappearing when I move windows around..
You are probably mishandling the clipping rectangles in your render function.
Rectangles provided by ImGui are defined as
`(x1=left,y1=top,x2=right,y2=bottom)`
and **NOT** as
`(x1,y1,width,height)`
##### [Return to Index](#index)
# Q&A: Usage
### Q: Why are multiple widgets reacting when I interact with a single one? <br>Q: How can I have multiple widgets with the same label or with an empty label?
A primer on labels and the ID Stack...
Dear ImGui internally need to uniquely identify UI elements.
Elements that are typically not clickable (such as calls to the Text functions) don't need an ID.
Interactive widgets (such as calls to Button buttons) need a unique ID.
Unique ID are used internally to track active widgets and occasionally associate state to widgets.
Unique ID are implicitly built from the hash of multiple elements that identify the "path" to the UI element.
- Unique ID are often derived from a string label:
```c
Button("OK"); // Label = "OK", ID = hash of (..., "OK")
Button("Cancel"); // Label = "Cancel", ID = hash of (..., "Cancel")
```
- ID are uniquely scoped within windows, tree nodes, etc. which all pushes to the ID stack. Having
two buttons labeled "OK" in different windows or different tree locations is fine.
We used "..." above to signify whatever was already pushed to the ID stack previously:
```c
Begin("MyWindow");
Button("OK"); // Label = "OK", ID = hash of ("MyWindow", "OK")
End();
Begin("MyOtherWindow");
Button("OK"); // Label = "OK", ID = hash of ("MyOtherWindow", "OK")
End();
```
- If you have a same ID twice in the same location, you'll have a conflict:
```c
Button("OK");
Button("OK"); // ID collision! Interacting with either button will trigger the first one.
```
Fear not! this is easy to solve and there are many ways to solve it!
- Solving ID conflict in a simple/local context:
When passing a label you can optionally specify extra ID information within string itself.
Use "##" to pass a complement to the ID that won't be visible to the end-user.
This helps solving the simple collision cases when you know e.g. at compilation time which items
are going to be created:
```c
Begin("MyWindow");
Button("Play"); // Label = "Play", ID = hash of ("MyWindow", "Play")
Button("Play##foo1"); // Label = "Play", ID = hash of ("MyWindow", "Play##foo1") // Different from above
Button("Play##foo2"); // Label = "Play", ID = hash of ("MyWindow", "Play##foo2") // Different from above
End();
```
- If you want to completely hide the label, but still need an ID:
```c
Checkbox("##On", &b); // Label = "", ID = hash of (..., "##On") // No visible label, just a checkbox!
```
- Occasionally/rarely you might want change a label while preserving a constant ID. This allows
you to animate labels. For example you may want to include varying information in a window title bar,
but windows are uniquely identified by their ID. Use "###" to pass a label that isn't part of ID:
```c
Button("Hello###ID"); // Label = "Hello", ID = hash of (..., "###ID")
Button("World###ID"); // Label = "World", ID = hash of (..., "###ID") // Same as above, even if the label looks different
sprintf(buf, "My game (%f FPS)###MyGame", fps);
Begin(buf); // Variable title, ID = hash of "MyGame"
```
- Solving ID conflict in a more general manner:
Use PushID() / PopID() to create scopes and manipulate the ID stack, as to avoid ID conflicts
within the same window. This is the most convenient way of distinguishing ID when iterating and
creating many UI elements programmatically.
You can push a pointer, a string or an integer value into the ID stack.
Remember that ID are formed from the concatenation of _everything_ pushed into the ID stack.
At each level of the stack we store the seed used for items at this level of the ID stack.
```c
Begin("Window");
for (int i = 0; i < 100; i++)
{
PushID(i); // Push i to the id tack
Button("Click"); // Label = "Click", ID = hash of ("Window", i, "Click")
PopID();
}
for (int i = 0; i < 100; i++)
{
MyObject* obj = Objects[i];
PushID(obj);
Button("Click"); // Label = "Click", ID = hash of ("Window", obj pointer, "Click")
PopID();
}
for (int i = 0; i < 100; i++)
{
MyObject* obj = Objects[i];
PushID(obj->Name);
Button("Click"); // Label = "Click", ID = hash of ("Window", obj->Name, "Click")
PopID();
}
End();
```
- You can stack multiple prefixes into the ID stack:
```c
Button("Click"); // Label = "Click", ID = hash of (..., "Click")
PushID("node");
Button("Click"); // Label = "Click", ID = hash of (..., "node", "Click")
PushID(my_ptr);
Button("Click"); // Label = "Click", ID = hash of (..., "node", my_ptr, "Click")
PopID();
PopID();
```
- Tree nodes implicitly creates a scope for you by calling PushID().
```c
Button("Click"); // Label = "Click", ID = hash of (..., "Click")
if (TreeNode("node")) // <-- this function call will do a PushID() for you (unless instructed not to, with a special flag)
{
Button("Click"); // Label = "Click", ID = hash of (..., "node", "Click")
TreePop();
}
```
- When working with trees, ID are used to preserve the open/close state of each tree node.
Depending on your use cases you may want to use strings, indices or pointers as ID.
e.g. when following a single pointer that may change over time, using a static string as ID
will preserve your node open/closed state when the targeted object change.
e.g. when displaying a list of objects, using indices or pointers as ID will preserve the
node open/closed state differently. See what makes more sense in your situation!
---
### Q: How can I display an image? What is ImTextureID, how does it work?
Short explanation:
- Please read Wiki entry for examples: https://github.com/ocornut/imgui/wiki/Image-Loading-and-Displaying-Examples
- You may use functions such as `ImGui::Image()`, `ImGui::ImageButton()` or lower-level `ImDrawList::AddImage()` to emit draw calls that will use your own textures.
- Actual textures are identified in a way that is up to the user/engine. Those identifiers are stored and passed as ImTextureID (void*) value.
- Loading image files from the disk and turning them into a texture is not within the scope of Dear ImGui (for a good reason).
**Please read documentations or tutorials on your graphics API to understand how to display textures on the screen before moving onward.**
Long explanation:
- Dear ImGui's job is to create "meshes", defined in a renderer-agnostic format made of draw commands and vertices. At the end of the frame those meshes (ImDrawList) will be displayed by your rendering function. They are made up of textured polygons and the code to render them is generally fairly short (a few dozen lines). In the examples/ folder we provide functions for popular graphics API (OpenGL, DirectX, etc.).
- Each rendering function decides on a data type to represent "textures". The concept of what is a "texture" is entirely tied to your underlying engine/graphics API.
We carry the information to identify a "texture" in the ImTextureID type.
ImTextureID is nothing more that a void*, aka 4/8 bytes worth of data: just enough to store 1 pointer or 1 integer of your choice.
Dear ImGui doesn't know or understand what you are storing in ImTextureID, it merely pass ImTextureID values until they reach your rendering function.
- In the [examples/](https://github.com/ocornut/imgui/tree/master/examples) bindings, for each graphics API binding we decided on a type that is likely to be a good representation for specifying an image from the end-user perspective. This is what the _examples_ rendering functions are using:
```
OpenGL:
- ImTextureID = GLuint
- See ImGui_ImplOpenGL3_RenderDrawData() function in imgui_impl_opengl3.cpp
DirectX9:
- ImTextureID = LPDIRECT3DTEXTURE9
- See ImGui_ImplDX9_RenderDrawData() function in imgui_impl_dx9.cpp
DirectX11:
- ImTextureID = ID3D11ShaderResourceView*
- See ImGui_ImplDX11_RenderDrawData() function in imgui_impl_dx11.cpp
DirectX12:
- ImTextureID = D3D12_GPU_DESCRIPTOR_HANDLE
- See ImGui_ImplDX12_RenderDrawData() function in imgui_impl_dx12.cpp
```
For example, in the OpenGL example binding we store raw OpenGL texture identifier (GLuint) inside ImTextureID.
Whereas in the DirectX11 example binding we store a pointer to ID3D11ShaderResourceView inside ImTextureID, which is a higher-level structure tying together both the texture and information about its format and how to read it.
- If you have a custom engine built over e.g. OpenGL, instead of passing GLuint around you may decide to use a high-level data type to carry information about the texture as well as how to display it (shaders, etc.). The decision of what to use as ImTextureID can always be made better knowing how your codebase is designed. If your engine has high-level data types for "textures" and "material" then you may want to use them.
If you are starting with OpenGL or DirectX or Vulkan and haven't built much of a rendering engine over them, keeping the default ImTextureID representation suggested by the example bindings is probably the best choice.
(Advanced users may also decide to keep a low-level type in ImTextureID, and use ImDrawList callback and pass information to their renderer)
User code may do:
```cpp
// Cast our texture type to ImTextureID / void*
MyTexture* texture = g_CoffeeTableTexture;
ImGui::Image((void*)texture, ImVec2(texture->Width, texture->Height));
```
The renderer function called after ImGui::Render() will receive that same value that the user code passed:
```cpp
// Cast ImTextureID / void* stored in the draw command as our texture type
MyTexture* texture = (MyTexture*)pcmd->TextureId;
MyEngineBindTexture2D(texture);
```
Once you understand this design you will understand that loading image files and turning them into displayable textures is not within the scope of Dear ImGui.
This is by design and is actually a good thing, because it means your code has full control over your data types and how you display them.
If you want to display an image file (e.g. PNG file) into the screen, please refer to documentation and tutorials for the graphics API you are using.
Refer to the Wiki to find simplified examples for loading textures with OpenGL, DirectX9 and DirectX11: https://github.com/ocornut/imgui/wiki/Image-Loading-and-Displaying-Examples
C/C++ tip: a void* is pointer-sized storage. You may safely store any pointer or integer into it by casting your value to ImTextureID / void*, and vice-versa.
Because both end-points (user code and rendering function) are under your control, you know exactly what is stored inside the ImTextureID / void*.
Examples:
```cpp
GLuint my_tex = XXX;
void* my_void_ptr;
my_void_ptr = (void*)(intptr_t)my_tex; // cast a GLuint into a void* (we don't take its address! we literally store the value inside the pointer)
my_tex = (GLuint)(intptr_t)my_void_ptr; // cast a void* into a GLuint
ID3D11ShaderResourceView* my_dx11_srv = XXX;
void* my_void_ptr;
my_void_ptr = (void*)my_dx11_srv; // cast a ID3D11ShaderResourceView* into an opaque void*
my_dx11_srv = (ID3D11ShaderResourceView*)my_void_ptr; // cast a void* into a ID3D11ShaderResourceView*
```
Finally, you may call ImGui::ShowMetricsWindow() to explore/visualize/understand how the ImDrawList are generated.
---
### Q: How can I use my own math types instead of ImVec2/ImVec4?
You can edit [imconfig.h](https://github.com/ocornut/imgui/blob/master/imconfig.h) and setup the IM_VEC2_CLASS_EXTRA/IM_VEC4_CLASS_EXTRA macros to add implicit type conversions.
This way you'll be able to use your own types everywhere, e.g. passing MyVector2 or glm::vec2 to ImGui functions instead of ImVec2.
---
### Q: How can I interact with standard C++ types (such as std::string and std::vector)?
- Being highly portable (bindings for several languages, frameworks, programming style, obscure or older platforms/compilers), and aiming for compatibility & performance suitable for every modern real-time game engines, dear imgui does not use any of std C++ types. We use raw types (e.g. char* instead of std::string) because they adapt to more use cases.
- To use ImGui::InputText() with a std::string or any resizable string class, see [misc/cpp/imgui_stdlib.h](https://github.com/ocornut/imgui/blob/master/misc/cpp/imgui_stdlib.h).
- To use combo boxes and list boxes with std::vector or any other data structure: the BeginCombo()/EndCombo() API
lets you iterate and submit items yourself, so does the ListBoxHeader()/ListBoxFooter() API.
Prefer using them over the old and awkward Combo()/ListBox() api.
- Generally for most high-level types you should be able to access the underlying data type.
You may write your own one-liner wrappers to facilitate user code (tip: add new functions in ImGui:: namespace from your code).
- Dear ImGui applications often need to make intensive use of strings. It is expected that many of the strings you will pass
to the API are raw literals (free in C/C++) or allocated in a manner that won't incur a large cost on your application.
Please bear in mind that using std::string on applications with large amount of UI may incur unsatisfactory performances.
Modern implementations of std::string often include small-string optimization (which is often a local buffer) but those
are not configurable and not the same across implementations.
- If you are finding your UI traversal cost to be too large, make sure your string usage is not leading to excessive amount
of heap allocations. Consider using literals, statically sized buffers and your own helper functions. A common pattern
is that you will need to build lots of strings on the fly, and their maximum length can be easily be scoped ahead.
One possible implementation of a helper to facilitate printf-style building of strings: https://github.com/ocornut/Str
This is a small helper where you can instance strings with configurable local buffers length. Many game engines will
provide similar or better string helpers.
---
### Q: How can I display custom shapes? (using low-level ImDrawList API)
- You can use the low-level `ImDrawList` api to render shapes within a window.
```
ImGui::Begin("My shapes");
ImDrawList* draw_list = ImGui::GetWindowDrawList();
// Get the current ImGui cursor position
ImVec2 p = ImGui::GetCursorScreenPos();
// Draw a red circle
draw_list->AddCircleFilled(ImVec2(p.x + 50, p.y + 50), 30.0f, IM_COL32(255, 0, 0, 255), 16);
// Draw a 3 pixel thick yellow line
draw_list->AddLine(ImVec2(p.x, p.y), ImVec2(p.x + 100.0f, p.y + 100.0f), IM_COL32(255, 255, 0, 255), 3.0f);
// Advance the ImGui cursor to claim space in the window (otherwise the window will appears small and needs to be resized)
ImGui::Dummy(ImVec2(200, 200));
ImGui::End();
```
![ImDrawList usage](https://raw.githubusercontent.com/wiki/ocornut/imgui/tutorials/CustomRendering01.png)
- Refer to "Demo > Examples > Custom Rendering" in the demo window and read the code of `ShowExampleAppCustomRendering()` in `imgui_demo.cpp` from more examples.
- To generate colors: you can use the macro `IM_COL32(255,255,255,255)` to generate them at compile time, or use `ImGui::GetColorU32(IM_COL32(255,255,255,255))` or `ImGui::GetColorU32(ImVec4(1.0f,1.0f,1.0f,1.0f))` to generate a color that is multiplied by the current value of `style.Alpha`.
- Math operators: if you have setup `IM_VEC2_CLASS_EXTRA` in `imconfig.h` to bind your own math types, you can use your own math types and their natural operators instead of ImVec2. ImVec2 by default doesn't export any math operators in the public API. You may use `#define IMGUI_DEFINE_MATH_OPERATORS` `#include "imgui_internal.h"` to use the internally defined math operators, but instead prefer using your own math library and set it up in `imconfig.h`.
- You can use `ImGui::GetBackgroundDrawList()` or `ImGui::GetForegroundDrawList()` to access draw lists which will be displayed behind and over every other dear imgui windows (one bg/fg drawlist per viewport). This is very convenient if you need to quickly display something on the screen that is not associated to a dear imgui window.
- You can also create your own dummy window and draw inside it. Call Begin() with the NoBackground | NoDecoration | NoSavedSettings | NoInputs flags (The `ImGuiWindowFlags_NoDecoration` flag itself is a shortcut for NoTitleBar | NoResize | NoScrollbar | NoCollapse). Then you can retrieve the ImDrawList* via GetWindowDrawList() and draw to it in any way you like.
- You can create your own ImDrawList instance. You'll need to initialize them with `ImGui::GetDrawListSharedData()`, or create your own instancing ImDrawListSharedData, and then call your renderer function with your own ImDrawList or ImDrawData data.
##### [Return to Index](#index)
# Q&A: Fonts, Text
### Q: How can I load a different font than the default?
Use the font atlas to load the TTF/OTF file you want:
```c
ImGuiIO& io = ImGui::GetIO();
io.Fonts->AddFontFromFileTTF("myfontfile.ttf", size_in_pixels);
io.Fonts->GetTexDataAsRGBA32() or GetTexDataAsAlpha8()
```
Default is ProggyClean.ttf, monospace, rendered at size 13, embedded in dear imgui's source code.
(Tip: monospace fonts are convenient because they allow to facilitate horizontal alignment directly at the string level.)
(Read the [docs/FONTS.txt](https://github.com/ocornut/imgui/blob/master/docs/FONTS.txt) file for more details about font loading.)
New programmers: remember that in C/C++ and most programming languages if you want to use a
backslash \ within a string literal, you need to write it double backslash "\\":
```c
io.Fonts->AddFontFromFileTTF("MyFolder\MyFont.ttf", size); // WRONG (you are escape the M here!)
io.Fonts->AddFontFromFileTTF("MyFolder\\MyFont.ttf", size; // CORRECT
io.Fonts->AddFontFromFileTTF("MyFolder/MyFont.ttf", size); // ALSO CORRECT
```
---
### Q: How can I easily use icons in my application?
The most convenient and practical way is to merge an icon font such as FontAwesome inside you
main font. Then you can refer to icons within your strings.
You may want to see ImFontConfig::GlyphMinAdvanceX to make your icon look monospace to facilitate alignment.
(Read the [docs/FONTS.txt](https://github.com/ocornut/imgui/blob/master/docs/FONTS.txt) file for more details about icons font loading.)
With some extra effort, you may use colorful icon by registering custom rectangle space inside the font atlas,
and copying your own graphics data into it. See docs/FONTS.txt about using the AddCustomRectFontGlyph API.
---
### Q: How can I load multiple fonts?
Use the font atlas to pack them into a single texture:
(Read the [docs/FONTS.txt](https://github.com/ocornut/imgui/blob/master/docs/FONTS.txt) file and the code in ImFontAtlas for more details.)
```cpp
ImGuiIO& io = ImGui::GetIO();
ImFont* font0 = io.Fonts->AddFontDefault();
ImFont* font1 = io.Fonts->AddFontFromFileTTF("myfontfile.ttf", size_in_pixels);
ImFont* font2 = io.Fonts->AddFontFromFileTTF("myfontfile2.ttf", size_in_pixels);
io.Fonts->GetTexDataAsRGBA32() or GetTexDataAsAlpha8()
// the first loaded font gets used by default
// use ImGui::PushFont()/ImGui::PopFont() to change the font at runtime
// Options
ImFontConfig config;
config.OversampleH = 2;
config.OversampleV = 1;
config.GlyphOffset.y -= 1.0f; // Move everything by 1 pixels up
config.GlyphExtraSpacing.x = 1.0f; // Increase spacing between characters
io.Fonts->AddFontFromFileTTF("myfontfile.ttf", size_pixels, &config);
// Combine multiple fonts into one (e.g. for icon fonts)
static ImWchar ranges[] = { 0xf000, 0xf3ff, 0 };
ImFontConfig config;
config.MergeMode = true;
io.Fonts->AddFontDefault();
io.Fonts->AddFontFromFileTTF("fontawesome-webfont.ttf", 16.0f, &config, ranges); // Merge icon font
io.Fonts->AddFontFromFileTTF("myfontfile.ttf", size_pixels, NULL, &config, io.Fonts->GetGlyphRangesJapanese()); // Merge japanese glyphs
```
---
### Q: How can I display and input non-Latin characters such as Chinese, Japanese, Korean, Cyrillic?
When loading a font, pass custom Unicode ranges to specify the glyphs to load.
```cpp
// Add default Japanese ranges
io.Fonts->AddFontFromFileTTF("myfontfile.ttf", size_in_pixels, NULL, io.Fonts->GetGlyphRangesJapanese());
// Or create your own custom ranges (e.g. for a game you can feed your entire game script and only build the characters the game need)
ImVector<ImWchar> ranges;
ImFontGlyphRangesBuilder builder;
builder.AddText("Hello world"); // Add a string (here "Hello world" contains 7 unique characters)
builder.AddChar(0x7262); // Add a specific character
builder.AddRanges(io.Fonts->GetGlyphRangesJapanese()); // Add one of the default ranges
builder.BuildRanges(&ranges); // Build the final result (ordered ranges with all the unique characters submitted)
io.Fonts->AddFontFromFileTTF("myfontfile.ttf", 16.0f, NULL, ranges.Data);
```
All your strings needs to use UTF-8 encoding. In C++11 you can encode a string literal in UTF-8
by using the u8"hello" syntax. Specifying literal in your source code using a local code page
(such as CP-923 for Japanese or CP-1251 for Cyrillic) will NOT work!
Otherwise you can convert yourself to UTF-8 or load text data from file already saved as UTF-8.
Text input: it is up to your application to pass the right character code by calling io.AddInputCharacter().
The applications in examples/ are doing that.
Windows: you can use the WM_CHAR or WM_UNICHAR or WM_IME_CHAR message (depending if your app is built using Unicode or MultiByte mode).
You may also use MultiByteToWideChar() or ToUnicode() to retrieve Unicode codepoints from MultiByte characters or keyboard state.
Windows: if your language is relying on an Input Method Editor (IME), you copy the HWND of your window to io.ImeWindowHandle in order for
the default implementation of io.ImeSetInputScreenPosFn() to set your Microsoft IME position correctly.
##### [Return to Index](#index)
# Q&A: Community
### Q: How can I help?
- If you are experienced with Dear ImGui and C++, look at the [GitHub Issues](https://github.com/ocornut/imgui/issues), look at the [Wiki](https://github.com/ocornut/imgui/wiki), read [docs/TODO.txt](https://github.com/ocornut/imgui/blob/master/docs/TODO.txt) and see how you want to help and can help!
- Businesses: convince your company to fund development via support contracts/sponsoring! This is among the most useful thing you can do for Dear ImGui. With increased funding we will be able to hire more people working on this project.
- Individuals: you can also become a [Patron](http://www.patreon.com/imgui) or donate on PayPal! See README.
- Disclose your usage of dear imgui via a dev blog post, a tweet, a screenshot, a mention somewhere etc.
You may post screenshot or links in the [gallery threads](https://github.com/ocornut/imgui/issues/2847). Visuals are ideal as they inspire other programmers.
But even without visuals, disclosing your use of dear imgui help the library grow credibility, and help other teams and programmers with taking decisions.
- If you have issues or if you need to hack into the library, even if you don't expect any support it is useful that you share your issues or sometimes incomplete pR.
##### [Return to Index](#index)

View File

@ -0,0 +1,376 @@
dear imgui
FONTS DOCUMENTATION
Also read https://www.dearimgui.org/faq for more fonts related infos.
The code in imgui.cpp embeds a copy of 'ProggyClean.ttf' (by Tristan Grimmer),
a 13 pixels high, pixel-perfect font used by default.
We embed it font in source code so you can use Dear ImGui without any file system access.
You may also load external .TTF/.OTF files.
The files in this folder are suggested fonts, provided as a convenience.
Please read the FAQ: https://www.dearimgui.org/faq
Please use the Discord server: http://discord.dearimgui.org and not the Github issue tracker for basic font loading questions.
---------------------------------------
INDEX:
---------------------------------------
- Readme First / FAQ
- Fonts Loading Instructions
- Using Icons
- Using FreeType rasterizer
- Building Custom Glyph Ranges
- Using custom colorful icons
- Embedding Fonts in Source Code
- Credits/Licences for fonts included in repository
- Fonts Links
---------------------------------------
README FIRST / FAQ
---------------------------------------
- You can use the style editor ImGui::ShowStyleEditor() in the "Fonts" section to browse your fonts
and understand what's going on if you have an issue.
- Fonts are rasterized in a single texture at the time of calling either of io.Fonts->GetTexDataAsAlpha8()/GetTexDataAsRGBA32()/Build().
- Make sure your font ranges data are persistent and available at the time the font atlas is being built.
- Use C++11 u8"my text" syntax to encode literal strings as UTF-8. e.g.:
u8"hello"
u8"こんにちは" // this will be encoded as UTF-8
- If you want to include a backslash \ character in your string literal, you need to double them e.g. "folder\\filename".
Read FAQ for details.
---------------------------------------
FONTS LOADING INSTRUCTIONS
---------------------------------------
Load default font:
ImGuiIO& io = ImGui::GetIO();
io.Fonts->AddFontDefault();
Load .TTF/.OTF file with:
ImGuiIO& io = ImGui::GetIO();
io.Fonts->AddFontFromFileTTF("font.ttf", size_pixels);
Load multiple fonts:
ImGuiIO& io = ImGui::GetIO();
ImFont* font1 = io.Fonts->AddFontFromFileTTF("font.ttf", size_pixels);
ImFont* font2 = io.Fonts->AddFontFromFileTTF("anotherfont.otf", size_pixels);
// Select font at runtime
ImGui::Text("Hello"); // use the default font (which is the first loaded font)
ImGui::PushFont(font2);
ImGui::Text("Hello with another font");
ImGui::PopFont();
For advanced options create a ImFontConfig structure and pass it to the AddFont function (it will be copied internally):
ImFontConfig config;
config.OversampleH = 2;
config.OversampleV = 1;
config.GlyphExtraSpacing.x = 1.0f;
ImFont* font = io.Fonts->AddFontFromFileTTF("font.ttf", size_pixels, &config);
Combine two fonts into one:
// Load a first font
ImFont* font = io.Fonts->AddFontDefault();
// Add character ranges and merge into the previous font
// The ranges array is not copied by the AddFont* functions and is used lazily
// so ensure it is available at the time of building or calling GetTexDataAsRGBA32().
static const ImWchar icons_ranges[] = { 0xf000, 0xf3ff, 0 }; // Will not be copied by AddFont* so keep in scope.
ImFontConfig config;
config.MergeMode = true;
io.Fonts->AddFontFromFileTTF("DroidSans.ttf", 18.0f, &config, io.Fonts->GetGlyphRangesJapanese());
io.Fonts->AddFontFromFileTTF("fontawesome-webfont.ttf", 18.0f, &config, icons_ranges);
io.Fonts->Build();
Font atlas is too large?
- If you have very large number of glyphs or multiple fonts, the texture may become too big for your graphics API.
- The typical result of failing to upload a texture is if every glyphs appears as white rectangles.
- In particular, using a large range such as GetGlyphRangesChineseSimplifiedCommon() is not recommended
unless you set OversampleH/OversampleV to 1 and use a small font size.
- Mind the fact that some graphics drivers have texture size limitation.
- If you are building a PC application, mind the fact that users may run on hardware with lower specs than yours.
Some solutions:
- 1) Reduce glyphs ranges by calculating them from source localization data.
You can use ImFontGlyphRangesBuilder for this purpose, this will be the biggest win!
- 2) You may reduce oversampling, e.g. config.OversampleH = config.OversampleV = 1, this will largely reduce your texture size.
- 3) Set io.Fonts.TexDesiredWidth to specify a texture width to minimize texture height (see comment in ImFontAtlas::Build function).
- 4) Set io.Fonts.Flags |= ImFontAtlasFlags_NoPowerOfTwoHeight; to disable rounding the texture height to the next power of two.
- Read about oversampling here: https://github.com/nothings/stb/blob/master/tests/oversample
Add a fourth parameter to bake specific font ranges only:
// Basic Latin, Extended Latin
io.Fonts->AddFontFromFileTTF("font.ttf", size_pixels, NULL, io.Fonts->GetGlyphRangesDefault());
// Default + Selection of 2500 Ideographs used by Simplified Chinese
io.Fonts->AddFontFromFileTTF("font.ttf", size_pixels, NULL, io.Fonts->GetGlyphRangesChineseSimplifiedCommon());
// Default + Hiragana, Katakana, Half-Width, Selection of 1946 Ideographs
io.Fonts->AddFontFromFileTTF("font.ttf", size_pixels, NULL, io.Fonts->GetGlyphRangesJapanese());
See "BUILDING CUSTOM GLYPH RANGES" section to create your own ranges.
Offset font vertically by altering the io.Font->DisplayOffset value:
ImFont* font = io.Fonts->AddFontFromFileTTF("font.ttf", size_pixels);
font->DisplayOffset.y = 1; // Render 1 pixel down
---------------------------------------
USING ICONS
---------------------------------------
Using an icon font (such as FontAwesome: http://fontawesome.io or OpenFontIcons. https://github.com/traverseda/OpenFontIcons)
is an easy and practical way to use icons in your Dear ImGui application.
A common pattern is to merge the icon font within your main font, so you can embed icons directly from your strings without
having to change fonts back and forth.
To refer to the icon UTF-8 codepoints from your C++ code, you may use those headers files created by Juliette Foucaut:
https://github.com/juliettef/IconFontCppHeaders
Those files contains a bunch of named #define which you can use to refer to specific icons of the font, e.g.:
#define ICON_FA_MUSIC "\xef\x80\x81"
#define ICON_FA_SEARCH "\xef\x80\x82"
Example Setup:
// Merge icons into default tool font
#include "IconsFontAwesome.h"
ImGuiIO& io = ImGui::GetIO();
io.Fonts->AddFontDefault();
ImFontConfig config;
config.MergeMode = true;
config.GlyphMinAdvanceX = 13.0f; // Use if you want to make the icon monospaced
static const ImWchar icon_ranges[] = { ICON_MIN_FA, ICON_MAX_FA, 0 };
io.Fonts->AddFontFromFileTTF("fonts/fontawesome-webfont.ttf", 13.0f, &config, icon_ranges);
Example Usage:
// Usage, e.g.
ImGui::Text("%s among %d items", ICON_FA_SEARCH, count);
ImGui::Button(ICON_FA_SEARCH " Search");
Important to understand: C string _literals_ can be concatenated at compilation time, e.g. "hello" " world"
ICON_FA_SEARCH is defined as a string literal so this is the same as "A" "B" becoming "AB"
See Links below for other icons fonts and related tools.
---------------------------------------
FREETYPE RASTERIZER, SMALL FONT SIZES
---------------------------------------
Dear ImGui uses imstb_truetype.h to rasterize fonts (with optional oversampling).
This technique and its implementation are not ideal for fonts rendered at _small sizes_, which may appear a
little blurry or hard to read.
There is an implementation of the ImFontAtlas builder using FreeType that you can use in the misc/freetype/ folder.
FreeType supports auto-hinting which tends to improve the readability of small fonts.
Note that this code currently creates textures that are unoptimally too large (could be fixed with some work).
Also note that correct sRGB space blending will have an important effect on your font rendering quality.
---------------------------------------
BUILDING CUSTOM GLYPH RANGES
---------------------------------------
You can use the ImFontGlyphRangesBuilder helper to create glyph ranges based on text input.
For example: for a game where your script is known, if you can feed your entire script to it and only build the characters the game needs.
ImVector<ImWchar> ranges;
ImFontGlyphRangesBuilder builder;
builder.AddText("Hello world"); // Add a string (here "Hello world" contains 7 unique characters)
builder.AddChar(0x7262); // Add a specific character
builder.AddRanges(io.Fonts->GetGlyphRangesJapanese()); // Add one of the default ranges
builder.BuildRanges(&ranges); // Build the final result (ordered ranges with all the unique characters submitted)
io.Fonts->AddFontFromFileTTF("myfontfile.ttf", size_in_pixels, NULL, ranges.Data);
io.Fonts->Build(); // Build the atlas while 'ranges' is still in scope and not deleted.
---------------------------------------
USING CUSTOM COLORFUL ICONS
---------------------------------------
(This is a BETA api, use if you are familiar with dear imgui and with your rendering back-end)
You can use the ImFontAtlas::AddCustomRect() and ImFontAtlas::AddCustomRectFontGlyph() api to register rectangles
that will be packed into the font atlas texture. Register them before building the atlas, then call Build().
You can then use ImFontAtlas::GetCustomRectByIndex(int) to query the position/size of your rectangle within the
texture, and blit/copy any graphics data of your choice into those rectangles.
Pseudo-code:
// Add font, then register two custom 13x13 rectangles mapped to glyph 'a' and 'b' of this font
ImFont* font = io.Fonts->AddFontDefault();
int rect_ids[2];
rect_ids[0] = io.Fonts->AddCustomRectFontGlyph(font, 'a', 13, 13, 13+1);
rect_ids[1] = io.Fonts->AddCustomRectFontGlyph(font, 'b', 13, 13, 13+1);
// Build atlas
io.Fonts->Build();
// Retrieve texture in RGBA format
unsigned char* tex_pixels = NULL;
int tex_width, tex_height;
io.Fonts->GetTexDataAsRGBA32(&tex_pixels, &tex_width, &tex_height);
for (int rect_n = 0; rect_n < IM_ARRAYSIZE(rect_ids); rect_n++)
{
int rect_id = rects_ids[rect_n];
if (const ImFontAtlas::CustomRect* rect = io.Fonts->GetCustomRectByIndex(rect_id))
{
// Fill the custom rectangle with red pixels (in reality you would draw/copy your bitmap data here!)
for (int y = 0; y < rect->Height; y++)
{
ImU32* p = (ImU32*)tex_pixels + (rect->Y + y) * tex_width + (rect->X);
for (int x = rect->Width; x > 0; x--)
*p++ = IM_COL32(255, 0, 0, 255);
}
}
}
---------------------------------------
EMBEDDING FONTS IN SOURCE CODE
---------------------------------------
Compile and use 'binary_to_compressed_c.cpp' to create a compressed C style array that you can embed in source code.
See the documentation in binary_to_compressed_c.cpp for instruction on how to use the tool.
You may find a precompiled version binary_to_compressed_c.exe for Windows instead of demo binaries package (see README).
The tool can optionally output Base85 encoding to reduce the size of _source code_ but the read-only arrays in the
actual binary will be about 20% bigger.
Then load the font with:
ImFont* font = io.Fonts->AddFontFromMemoryCompressedTTF(compressed_data, compressed_data_size, size_pixels, ...);
or:
ImFont* font = io.Fonts->AddFontFromMemoryCompressedBase85TTF(compressed_data_base85, size_pixels, ...);
---------------------------------------
CREDITS/LICENSES FOR FONTS INCLUDED IN REPOSITORY
---------------------------------------
Some fonts are available in the misc/fonts/ folder:
Roboto-Medium.ttf
Apache License 2.0
by Christian Robertson
https://fonts.google.com/specimen/Roboto
Cousine-Regular.ttf
by Steve Matteson
Digitized data copyright (c) 2010 Google Corporation.
Licensed under the SIL Open Font License, Version 1.1
https://fonts.google.com/specimen/Cousine
DroidSans.ttf
Copyright (c) Steve Matteson
Apache License, version 2.0
https://www.fontsquirrel.com/fonts/droid-sans
ProggyClean.ttf
Copyright (c) 2004, 2005 Tristan Grimmer
MIT License
recommended loading setting: Size = 13.0, DisplayOffset.Y = +1
http://www.proggyfonts.net/
ProggyTiny.ttf
Copyright (c) 2004, 2005 Tristan Grimmer
MIT License
recommended loading setting: Size = 10.0, DisplayOffset.Y = +1
http://www.proggyfonts.net/
Karla-Regular.ttf
Copyright (c) 2012, Jonathan Pinhorn
SIL OPEN FONT LICENSE Version 1.1
---------------------------------------
FONTS LINKS
---------------------------------------
ICON FONTS
C/C++ header for icon fonts (#define with code points to use in source code string literals)
https://github.com/juliettef/IconFontCppHeaders
FontAwesome
https://fortawesome.github.io/Font-Awesome
OpenFontIcons
https://github.com/traverseda/OpenFontIcons
Google Icon Fonts
https://design.google.com/icons/
Kenney Icon Font (Game Controller Icons)
https://github.com/nicodinh/kenney-icon-font
IcoMoon - Custom Icon font builder
https://icomoon.io/app
REGULAR FONTS
Google Noto Fonts (worldwide languages)
https://www.google.com/get/noto/
Open Sans Fonts
https://fonts.google.com/specimen/Open+Sans
(Japanese) M+ fonts by Coji Morishita are free
http://mplus-fonts.sourceforge.jp/mplus-outline-fonts/index-en.html
MONOSPACE FONTS (PIXEL PERFECT)
Proggy Fonts, by Tristan Grimmer
http://www.proggyfonts.net or http://upperbounds.net
Sweet16, Sweet16 Mono, by Martin Sedlak (Latin + Supplemental + Extended A)
https://github.com/kmar/Sweet16Font
Also include .inl file to use directly in dear imgui.
MONOSPACE FONTS (REGULAR)
Google Noto Mono Fonts
https://www.google.com/get/noto/
Typefaces for source code beautification
https://github.com/chrissimpkins/codeface
Programmation fonts
http://s9w.github.io/font_compare/
Inconsolata
http://www.levien.com/type/myfonts/inconsolata.html
Adobe Source Code Pro: Monospaced font family for user interface and coding environments
https://github.com/adobe-fonts/source-code-pro
Monospace/Fixed Width Programmer's Fonts
http://www.lowing.org/fonts/
Or use Arial Unicode or other Unicode fonts provided with Windows for full characters coverage (not sure of their licensing).

View File

@ -0,0 +1,237 @@
dear imgui
=====
[![Build Status](https://github.com/ocornut/imgui/workflows/build/badge.svg)](https://github.com/ocornut/imgui/actions?workflow=build)
[![Coverity Status](https://scan.coverity.com/projects/4720/badge.svg)](https://scan.coverity.com/projects/4720)
<sub>(This library is available under a free and permissive license, but needs financial support to sustain its continued improvements. In addition to maintenance and stability there are many desirable features yet to be added. If your company is using dear imgui, please consider reaching out. If you are an individual using dear imgui, please consider supporting the project via Patreon or PayPal.)</sub>
Businesses: support continued development via invoiced technical support, maintenance, sponsoring contracts:
<br>&nbsp;&nbsp;_E-mail: contact @ dearimgui dot org_
Individuals/hobbyists: support continued maintenance and development via the monthly Patreon:
<br>&nbsp;&nbsp;[![Patreon](https://raw.githubusercontent.com/wiki/ocornut/imgui/web/patreon_02.png)](http://www.patreon.com/imgui)
Individuals/hobbyists: support continued maintenance and development via PayPal:
<br>&nbsp;&nbsp;[![PayPal](https://www.paypalobjects.com/en_US/i/btn/btn_donate_LG.gif)](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=WGHNC6MBFLZ2S)
----
Dear ImGui is a **bloat-free graphical user interface library for C++**. It outputs optimized vertex buffers that you can render anytime in your 3D-pipeline enabled application. It is fast, portable, renderer agnostic and self-contained (no external dependencies).
Dear ImGui is designed to **enable fast iterations** and to **empower programmers** to create **content creation tools and visualization / debug tools** (as opposed to UI for the average end-user). It favors simplicity and productivity toward this goal, and lacks certain features normally found in more high-level libraries.
Dear ImGui is particularly suited to integration in games engine (for tooling), real-time 3D applications, fullscreen applications, embedded applications, or any applications on consoles platforms where operating system features are non-standard.
| [Usage](#usage) - [How it works](#how-it-works) - [Demo](#demo) - [Integration](#integration) |
:----------------------------------------------------------: |
| [Upcoming changes](#upcoming-changes) - [Gallery](#gallery) - [Support, FAQ](#support-frequently-asked-questions-faq) - [How to help](#how-to-help) - [Sponsors](#sponsors) - [Credits](#credits) - [License](#license) |
| [Wiki](https://github.com/ocornut/imgui/wiki) - [Language & frameworks bindings](https://github.com/ocornut/imgui/wiki/Bindings) - [Software using Dear ImGui](https://github.com/ocornut/imgui/wiki/Software-using-dear-imgui) - [User quotes](https://github.com/ocornut/imgui/wiki/Quotes) |
### Usage
**The core of Dear ImGui is self-contained within a few platform-agnostic files** which you can easily copy and compile into your application/engine. They are all the files in the root folder of the repository (imgui.cpp, imgui.h, imgui_demo.cpp, imgui_draw.cpp etc.).
**No specific build process is required**. You can add the .cpp files to your existing project.
You will need a backend to integrate Dear ImGui in your app. The backend passes mouse/keyboard/gamepad inputs and variety of settings to Dear ImGui, and is in charge of rendering the resulting vertices.
**Backends for a variety of graphics api and rendering platforms** are provided in the [examples/](https://github.com/ocornut/imgui/tree/master/examples) folder, along with example applications. See the [Integration](#integration) section of this document for details. You may also create your own backend. Anywhere where you can render textured triangles, you can render Dear ImGui.
After Dear ImGui is setup in your application, you can use it from \_anywhere\_ in your program loop:
Code:
```cp
ImGui::Text("Hello, world %d", 123);
if (ImGui::Button("Save"))
MySaveFunction();
ImGui::InputText("string", buf, IM_ARRAYSIZE(buf));
ImGui::SliderFloat("float", &f, 0.0f, 1.0f);
```
Result:
<br>![sample code output](https://raw.githubusercontent.com/wiki/ocornut/imgui/web/v160/code_sample_02.png)
<br>_(settings: Dark style (left), Light style (right) / Font: Roboto-Medium, 16px / Rounding: 5)_
Code:
```cpp
// Create a window called "My First Tool", with a menu bar.
ImGui::Begin("My First Tool", &my_tool_active, ImGuiWindowFlags_MenuBar);
if (ImGui::BeginMenuBar())
{
if (ImGui::BeginMenu("File"))
{
if (ImGui::MenuItem("Open..", "Ctrl+O")) { /* Do stuff */ }
if (ImGui::MenuItem("Save", "Ctrl+S")) { /* Do stuff */ }
if (ImGui::MenuItem("Close", "Ctrl+W")) { my_tool_active = false; }
ImGui::EndMenu();
}
ImGui::EndMenuBar();
}
// Edit a color (stored as ~4 floats)
ImGui::ColorEdit4("Color", my_color);
// Plot some values
const float my_values[] = { 0.2f, 0.1f, 1.0f, 0.5f, 0.9f, 2.2f };
ImGui::PlotLines("Frame Times", my_values, IM_ARRAYSIZE(my_values));
// Display contents in a scrolling region
ImGui::TextColored(ImVec4(1,1,0,1), "Important Stuff");
ImGui::BeginChild("Scrolling");
for (int n = 0; n < 50; n++)
ImGui::Text("%04d: Some text", n);
ImGui::EndChild();
ImGui::End();
```
Result:
<br>![sample code output](https://raw.githubusercontent.com/wiki/ocornut/imgui/web/v160/code_sample_03_color.gif)
Dear ImGui allows you **create elaborate tools** as well as very short-lived ones. On the extreme side of short-liveness: using the Edit&Continue (hot code reload) feature of modern compilers you can add a few widgets to tweaks variables while your application is running, and remove the code a minute later! Dear ImGui is not just for tweaking values. You can use it to trace a running algorithm by just emitting text commands. You can use it along with your own reflection data to browse your dataset live. You can use it to expose the internals of a subsystem in your engine, to create a logger, an inspection tool, a profiler, a debugger, an entire game making editor/framework, etc.
### How it works
Check out the Wiki's [About the IMGUI paradigm](https://github.com/ocornut/imgui/wiki#About-the-IMGUI-paradigm) section if you want to understand the core principles behind the IMGUI paradigm. An IMGUI tries to minimize superfluous state duplication, state synchronization and state retention from the user's point of view. It is less error prone (less code and less bugs) than traditional retained-mode interfaces, and lends itself to create dynamic user interfaces.
Dear ImGui outputs vertex buffers and command lists that you can easily render in your application. The number of draw calls and state changes required to render them is fairly small. Because Dear ImGui doesn't know or touch graphics state directly, you can call its functions anywhere in your code (e.g. in the middle of a running algorithm, or in the middle of your own rendering process). Refer to the sample applications in the examples/ folder for instructions on how to integrate dear imgui with your existing codebase.
_A common misunderstanding is to mistake immediate mode gui for immediate mode rendering, which usually implies hammering your driver/GPU with a bunch of inefficient draw calls and state changes as the gui functions are called. This is NOT what Dear ImGui does. Dear ImGui outputs vertex buffers and a small list of draw calls batches. It never touches your GPU directly. The draw call batches are decently optimal and you can render them later, in your app or even remotely._
### Demo
Calling the `ImGui::ShowDemoWindow()` function will create a demo window showcasing variety of features and examples. The code is always available for reference in `imgui_demo.cpp`.
![screenshot demo](https://raw.githubusercontent.com/wiki/ocornut/imgui/web/v167/v167-misc.png)
You should be able to build the examples from sources (tested on Windows/Mac/Linux). If you don't, let me know! If you want to have a quick look at some Dear ImGui features, you can download Windows binaries of the demo app here:
- [imgui-demo-binaries-20190715.zip](http://www.dearimgui.org/binaries/imgui-demo-binaries-20190715.zip) (Windows binaries, 1.72 WIP, built 2019/07/15, master branch, 5 executables)
The demo applications are not DPI aware so expect some blurriness on a 4K screen. For DPI awareness in your application, you can load/reload your font at different scale, and scale your style with `style.ScaleAllSizes()`.
### Integration
On most platforms and when using C++, **you should be able to use a combination of the [imgui_impl_xxxx](https://github.com/ocornut/imgui/tree/master/examples) files without modification** (e.g. `imgui_impl_win32.cpp` + `imgui_impl_dx11.cpp`). If your engine supports multiple platforms, consider using more of the imgui_impl_xxxx files instead of rewriting them: this will be less work for you and you can get Dear ImGui running immediately. You can _later_ decide to rewrite a custom binding using your custom engine functions if you wish so.
Integrating Dear ImGui within your custom engine is a matter of 1) wiring mouse/keyboard/gamepad inputs 2) uploading one texture to your GPU/render engine 3) providing a render function that can bind textures and render textured triangles. The [examples/](https://github.com/ocornut/imgui/tree/master/examples) folder is populated with applications doing just that. If you are an experienced programmer at ease with those concepts, it should take you less than two hours to integrate Dear ImGui in your custom engine. **Make sure to spend time reading the [FAQ](https://www.dearimgui.org/faq), comments, and some of the examples/ application!**
Officially maintained bindings (in repository):
- Renderers: DirectX9, DirectX10, DirectX11, DirectX12, OpenGL (legacy), OpenGL3/ES/ES2 (modern), Vulkan, Metal.
- Platforms: GLFW, SDL2, Win32, Glut, OSX.
- Frameworks: Emscripten, Allegro5, Marmalade.
Third-party bindings (see [Bindings](https://github.com/ocornut/imgui/wiki/Bindings/) page):
- Languages: C, C#/.Net, ChaiScript, D, Go, Haxe/hxcpp, Java, JavaScript, Julia, Lua, Odin, Pascal, PureBasic, Python, Ruby, Rust, Swift...
- Frameworks: Amethyst, bsf, Cinder, Cocos2d-x, Diligent Engine, Flexium, GML/GameMakerStudio2, Irrlicht, Ogre, OpenFrameworks, OpenSceneGraph/OSG, ORX, px_render, LÖVE+Lua, Magnum, NanoRT, Qt, QtDirect3D, SFML, Software Rasterizers, Unreal Engine 4...
- Note that C bindings ([cimgui](https://github.com/cimgui/cimgui)) are auto-generated, you can use its json/lua output to generate bindings for other languages.
Also see [Wiki](https://github.com/ocornut/imgui/wiki) for more links and ideas.
### Upcoming Changes
Some of the goals for 2019+ are:
- Finish work on docking, tabs. (see [#2109](https://github.com/ocornut/imgui/issues/2109), in public [docking](https://github.com/ocornut/imgui/tree/docking) branch looking for feedback)
- Finish work on multiple viewports / multiple OS windows. (see [#1542](https://github.com/ocornut/imgui/issues/1542), in public [docking](https://github.com/ocornut/imgui/tree/docking) branch looking for feedback)
- Finish work on gamepad/keyboard controls. (see [#787](https://github.com/ocornut/imgui/issues/787))
- Add an automation and testing system, both to test the library and end-user apps. (see [#435](https://github.com/ocornut/imgui/issues/435))
- Make Columns better. They are currently pretty terrible! New Tables API coming Q4 2019!
- Make the examples look better, improve styles, improve font support, make the examples hi-DPI and multi-DPI aware.
### Gallery
For more user-submitted screenshots of projects using Dear ImGui, check out the [Gallery Threads](https://github.com/ocornut/imgui/issues/2847)!
Custom engine
[![screenshot game](https://raw.githubusercontent.com/wiki/ocornut/imgui/web/v149/gallery_TheDragonsTrap-01-thumb.jpg)](https://cloud.githubusercontent.com/assets/8225057/20628927/33e14cac-b329-11e6-80f6-9524e93b048a.png)
Custom engine
[![screenshot tool](https://raw.githubusercontent.com/wiki/ocornut/imgui/web/v160/editor_white_preview.jpg)](https://raw.githubusercontent.com/wiki/ocornut/imgui/web/v160/editor_white.png)
[Tracy Profiler](https://bitbucket.org/wolfpld/tracy)
![tracy profiler](https://raw.githubusercontent.com/wiki/ocornut/imgui/web/v173/tracy_profiler.jpg)
### Support, Frequently Asked Questions (FAQ)
Most common questions will be answered by the [Frequently Asked Questions (FAQ)](https://github.com/ocornut/imgui/blob/master/docs/FAQ.md) page.
See: [Wiki](https://github.com/ocornut/imgui/wiki) for many links, references, articles.
See: [Articles about the IMGUI paradigm](https://github.com/ocornut/imgui/wiki#Articles-about-the-IMGUI-paradigm) to read/learn about the Immediate Mode GUI paradigm.
If you are new to Dear ImGui and have issues with: compiling, linking, adding fonts, wiring inputs, running or displaying Dear ImGui: you can use [Discord server](http://discord.dearimgui.org).
Otherwise, for any other questions, bug reports, requests, feedback, you may post on https://github.com/ocornut/imgui/issues. Please read and fill the New Issue template carefully.
Paid private support is available for business customers (E-mail: _contact @ dearimgui dot org_).
**Which version should I get?**
I occasionally tag [Releases](https://github.com/ocornut/imgui/releases) but it is generally safe and recommended to sync to master/latest. The library is fairly stable and regressions tend to be fixed fast when reported.
You may also peak at the [Multi-Viewport](https://github.com/ocornut/imgui/issues/1542) and [Docking](https://github.com/ocornut/imgui/issues/2109) features in the `docking` branch. Many projects are using this branch and it is kept in sync with master regularly.
**Who uses Dear ImGui?**
See the [Quotes](https://github.com/ocornut/imgui/wiki/Quotes) and [Software using dear imgui](https://github.com/ocornut/imgui/wiki/Software-using-dear-imgui) Wiki pages for a list of games/software which are publicly known to use dear imgui. Please add yours if you can! Also see the [Gallery Threads](https://github.com/ocornut/imgui/issues/2847)!
How to help
-----------
**How can I help?**
- You may participate in the [Discord server](http://discord.dearimgui.org), [GitHub forum/issues](https://github.com/ocornut/imgui/issues).
- You may help with development and submit pull requests! Please understand that by submitting a PR you are also submitting a request for the maintainer to review your code and then take over its maintenance forever. PR should be crafted both in the interest in the end-users and also to ease the maintainer into understanding and accepting it.
- See [Help wanted](https://github.com/ocornut/imgui/wiki/Help-Wanted) on the [Wiki](https://github.com/ocornut/imgui/wiki/) for some more ideas.
- Have your company financially support this project.
**How can I help financing further development of Dear ImGui?**
Your contributions are keeping this project alive. The library is available under a free and permissive license, but continued maintenance and development are a full-time endeavor and I would like to grow the team. In addition to maintenance and stability there are many desirable features yet to be added. If your company is using dear imgui, please consider reaching out for invoiced technical support and maintenance contracts. If you are an individual using dear imgui, please consider supporting the project via Patreon or PayPal. Thank you!
Businesses: support continued development via invoiced technical support, maintenance, sponsoring contracts:
<br>&nbsp;&nbsp;_E-mail: contact @ dearimgui dot org_
Individuals/hobbyists: support continued maintenance and development via the monthly Patreon:
<br>&nbsp;&nbsp;[![Patreon](https://raw.githubusercontent.com/wiki/ocornut/imgui/web/patreon_02.png)](http://www.patreon.com/imgui)
Individuals/hobbyists: support continued maintenance and development via PayPal:
<br>&nbsp;&nbsp;[![PayPal](https://www.paypalobjects.com/en_US/i/btn/btn_donate_LG.gif)](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=WGHNC6MBFLZ2S)
### Sponsors
Ongoing Dear ImGui development is financially supported by users and private sponsors, recently:
*Platinum-chocolate sponsors*
- Blizzard Entertainment
- Google
*Double-chocolate sponsors*
- Media Molecule, Mobigame, Aras Pranckevičius, Greggman, DotEmu, Nadeo, Supercell, Runner, Aiden Koss, Kylotonn.
*Salty caramel supporters*
- Remedy Entertainment, Next Level Games, Recognition Robotics, ikrima, Geoffrey Evans, Mercury Labs, Singularity Demo Group, Lionel Landwerlin, Ron Gilbert, Brandon Townsend, G3DVu, Cort Stratton, drudru, Harfang 3D, Jeff Roberts, Rainway inc, Ondra Voves, Mesh Consultants, Unit 2 Games, Neil Bickford, Bill Six, Graham Manders.
*Caramel supporters*
- Jerome Lanquetot, Daniel Collin, Ctrl Alt Ninja, Neil Henning, Neil Blakey-Milner, Aleksei, NeiloGD, Eric, Game Atelier, Vincent Hamm, Morten Skaaning, Colin Riley, Sergio Gonzales, Andrew Berridge, Roy Eltham, Game Preservation Society, Josh Faust, Martin Donlon, Codecat, Doug McNabb, Emmanuel Julien, Guillaume Chereau, Jeffrey Slutter, Jeremiah Deckard, r-lyeh, Nekith, Joshua Fisher, Malte Hoffmann, Mustafa Karaalioglu, Merlyn Morgan-Graham, Per Vognsen, Fabian Giesen, Jan Staubach, Matt Hargett, John Shearer, Jesse Chounard, kingcoopa, Jonas Bernemann, Johan Andersson, Michael Labbe, Tomasz Golebiowski, Louis Schnellbach, Jimmy Andrews, Bojan Endrovski, Robin Berg Pettersen, Rachel Crawford, Andrew Johnson, Sean Hunter, Jordan Mellow, Nefarius Software Solutions, Laura Wieme, Robert Nix, Mick Honey, Steven Kah Hien Wong, Bartosz Bielecki, Oscar Penas, A M, Liam Moynihan, Artometa, Mark Lee, Dimitri Diakopoulos, Pete Goodwin, Johnathan Roatch, nyu lea, Oswald Hurlem, Semyon Smelyanskiy, Le Bach, Jeong MyeongSoo, Chris Matthews, Astrofra, Frederik De Bleser, Anticrisis, Matt Reyer.
And all other past and present supporters; THANK YOU!
(Please contact me if you would like to be added or removed from this list)
Dear ImGui is using software and services kindly provided free of charge for open source projects:
- [PVS-Studio](https://www.viva64.com/en/b/0570/) for static analysis.
- [GitHub actions](https://github.com/features/actions) for continuous integration systems.
Credits
-------
Developed by [Omar Cornut](http://www.miracleworld.net) and every direct or indirect contributors to the GitHub. The early version of this library was developed with the support of [Media Molecule](http://www.mediamolecule.com) and first used internally on the game [Tearaway](http://tearaway.mediamolecule.com) (Vita).
I first discovered the IMGUI paradigm at [Q-Games](http://www.q-games.com) where Atman Binstock had dropped his own simple implementation in the codebase, which I spent quite some time improving and thinking about. It turned out that Atman was exposed to the concept directly by working with Casey. When I moved to Media Molecule I rewrote a new library trying to overcome the flaws and limitations of the first one I've worked with. It became this library and since then I have spent an unreasonable amount of time iterating and improving it.
Embeds [ProggyClean.ttf](http://upperbounds.net) font by Tristan Grimmer (MIT license).
Embeds [stb_textedit.h, stb_truetype.h, stb_rect_pack.h](https://github.com/nothings/stb/) by Sean Barrett (public domain).
Inspiration, feedback, and testing for early versions: Casey Muratori, Atman Binstock, Mikko Mononen, Emmanuel Briney, Stefan Kamoda, Anton Mikhailov, Matt Willis. And everybody posting feedback, questions and patches on the GitHub.
License
-------
Dear ImGui is licensed under the MIT License, see [LICENSE.txt](https://github.com/ocornut/imgui/blob/master/LICENSE.txt) for more information.

View File

@ -0,0 +1,381 @@
dear imgui
ISSUES & TODO LIST
Issue numbers (#) refer to github issues listed at https://github.com/ocornut/imgui/issues/XXXX
The list below consist mostly of ideas noted down before they are requested/discussed by users (at which point they usually exist on the github issue tracker).
It's mostly a bunch of personal notes, probably incomplete. Feel free to query if you have any questions.
- doc/test: add a proper documentation+regression testing system (#435)
- doc/test: checklist app to verify binding/integration of imgui (test inputs, rendering, callback, etc.).
- doc/tips: tips of the day: website? applet in imgui_club?
- window: preserve/restore relative focus ordering (persistent or not) (#2304) -> also see docking reference to same #.
- window: calling SetNextWindowSize() every frame with <= 0 doesn't do anything, may be useful to allow (particularly when used for a single axis). (#690)
- window: add a way for very transient windows (non-saved, temporary overlay over hundreds of objects) to "clean" up from the global window list. perhaps a lightweight explicit cleanup pass.
- window: auto-fit feedback loop when user relies on any dynamic layout (window width multiplier, column) appears weird to end-user. clarify.
- window: allow resizing of child windows (possibly given min/max for each axis?.)
- window: background options for child windows, border option (disable rounding).
- window: begin with *p_open == false could return false.
- window: get size/pos helpers given names (see discussion in #249)
- window: a collapsed window can be stuck behind the main menu bar?
- window: when window is very small, prioritize resize button over close button.
- window: detect extra End() call that pop the "Debug" window out and assert at End() call site instead of at end of frame.
- window: increase minimum size of a window with menus or fix the menu rendering so that it doesn't look odd.
- window: double-clicking on title bar to minimize isn't consistent, perhaps move to single-click on left-most collapse icon?
- window: expose contents size. (#1045)
- window: using SetWindowPos() inside Begin() and moving the window with the mouse reacts a very ugly glitch. We should just defer the SetWindowPos() call.
- window: GetWindowSize() returns (0,0) when not calculated? (#1045)
- window: investigate better auto-positioning for new windows.
- window: top most window flag? (#2574)
- window/opt: freeze window flag: if not focused/hovered, return false, render with previous ImDrawList. and/or reduce refresh rate. -> this may require enforcing that it is illegal to submit contents if Begin returns false.
- window/child: the first draw command of a child window could be moved into the current draw command of the parent window (unless child+tooltip?).
- window/child: border could be emitted in parent as well.
- window/child: allow SetNextWindowContentSize() to work on child windows.
- window/clipping: some form of clipping when DisplaySize (or corresponding viewport) is zero.
- window/tab: add a way to signify that a window or docked window requires attention (e.g. blinking title bar).
! scrolling: exposing horizontal scrolling with Shift+Wheel even when scrollbar is disabled expose lots of issues (#2424, #1463)
- scrolling: while holding down a scrollbar, try to keep the same contents visible (at least while not moving mouse)
- scrolling: allow immediately effective change of scroll after Begin() if we haven't appended items yet.
- scrolling/clipping: separator on the initial position of a window is not visible (cursorpos.y <= clippos.y). (2017-08-20: can't repro)
- scrolling/style: shadows on scrollable areas to denote that there is more contents
- drawdata: make it easy to clone (or swap?) a full ImDrawData so user can easily save that data if they use threaded rendering. (e.g. #2646)
! drawlist: add calctextsize func to facilitate consistent code from user pov (currently need to use ImGui or ImFont alternatives!)
- drawlist: end-user probably can't call Clear() directly because we expect a texture to be pushed in the stack.
- drawlist: maintaining bounding box per command would allow to merge draw command when clipping isn't relied on (typical non-scrolling window or non-overflowing column would merge with previous command).
- drawlist: primitives/helpers to manipulate vertices post submission, so e.g. a quad/rect can be resized to fit later submitted content, _without_ using the ChannelSplit api
- drawlist: make it easier to toggle AA per primitive, so we can use e.g. non-AA fill + AA borders more naturally
- drawlist: non-AA strokes have gaps between points (#593, #288), glitch especially on RenderCheckmark() and ColorPicker4().
- drawlist: would be good to be able to deep copy of ImDrawData (we have a deep copy of ImDrawList now).
- drawlist: rendering: provide a way for imgui to output to a single/global vertex buffer, re-order indices only at the end of the frame (ref: https://gist.github.com/floooh/10388a0afbe08fce9e617d8aefa7d302)
- drawlist: callback: add an extra void* in ImDrawCallback to allow passing render-local data to the callback (would break API).
- drawlist: AddRect vs AddLine position confusing (#2441)
- drawlist: channel splitter should be external helper and not stored in ImDrawList.
- drawlist/opt: store rounded corners in texture to use 1 quad per corner (filled and wireframe) to lower the cost of rounding. (#1962)
- drawlist/opt: AddRect() axis aligned pixel aligned (no-aa) could use 8 triangles instead of 16 and no normal calculation.
- drawlist/opt: thick AA line could be doable in same number of triangles as 1.0 AA line by storing gradient+full color in atlas.
- main: find a way to preserve relative orders of multiple reappearing windows (so an app toggling between "modes" e.g. fullscreen vs all tools) won't lose relative ordering.
- main: IsItemHovered() make it more consistent for various type of widgets, widgets with multiple components, etc. also effectively IsHovered() region sometimes differs from hot region, e.g tree nodes
- main: IsItemHovered() info stored in a stack? so that 'if TreeNode() { Text; TreePop; } if IsHovered' return the hover state of the TreeNode?
- main: rename the main "Debug" window to avoid ID collision with user who may want to use "Debug" with specific flags.
- widgets: display mode: widget-label, label-widget (aligned on column or using fixed size), label-newline-tab-widget etc. (#395)
- widgets: clean up widgets internal toward exposing everything and stabilizing imgui_internals.h.
- widgets: add visuals for Disabled/ReadOnly mode and expose publicly (#211)
- widgets: add always-allow-overlap mode. This should perhaps be the default? one problem is that highlight after mouse-wheel scrolling gets deferred, makes scrolling more flickery.
- widgets: start exposing PushItemFlag() and ImGuiItemFlags
- widgets: alignment options in style (e.g. center Selectable, Right-Align within Button, etc.) #1260
- widgets: activate by identifier (trigger button, focus given id)
- widgets: a way to represent "mixed" values, so e.g. all values replaced with *, including check-boxes, colors, etc. with support for multi-components widgets (e.g. SliderFloat3, make only "Y" mixed) (#2644)
- widgets: selectable: generic BeginSelectable()/EndSelectable() mechanism.
- widgets: selectable: a way to visualize partial/mixed selection (e.g. parent tree node has children with mixed selection)
- widgets: checkbox: checkbox with custom glyph inside frame.
- widgets: coloredit: keep reporting as active when picker is on?
- widgets: group/scalarn functions: expose more per-component information. e.g. store NextItemData.ComponentIdx set by scalarn function, groups can expose them back somehow.
- input text: clean up the mess caused by converting UTF-8 <> wchar. the code is rather inefficient right now and super fragile.
- input text: reorganize event handling, allow CharFilter to modify buffers, allow multiple events? (#541)
- input text: expose CursorPos in char filter event (#816)
- input text: access public fields via a non-callback API e.g. InputTextGetState("xxx") that may return NULL if not active.
- input text: flag to disable live update of the user buffer (also applies to float/int text input) (#701)
- input text: hover tooltip could show unclamped text
- input text: option to Tab after an Enter validation.
- input text: add ImGuiInputTextFlags_EnterToApply? (off #218)
- input text: easier ways to update buffer (from source char*) while owned. preserve some sort of cursor position for multi-line text.
- input text: add discard flag (e.g. ImGuiInputTextFlags_DiscardActiveBuffer) or make it easier to clear active focus for text replacement during edition (#725)
- input text: display bug when clicking a drag/slider after an input text in a different window has all-selected text (order dependent). actually a very old bug but no one appears to have noticed it.
- input text: allow centering/positioning text so that ctrl+clicking Drag or Slider keeps the textual value at the same pixel position.
- input text: decorrelate layout from inputs - e.g. what's the easiest way to implement a nice IP/Mac address input editor?
- input text: global callback system so user can plug in an expression evaluator easily. (#1691)
- input text: force scroll to end or scroll to a given line/contents (so user can implement a log or a search feature)
- input text: a way to preview completion (e.g. disabled text completing from the cursor)
- input text: a side bar that could e.g. preview where errors are. probably left to the user to draw but we'd need to give them the info there.
- input text: a way for the user to provide syntax coloring.
- input text: Shift+TAB with ImGuiInputTextFlags_AllowTabInput could eat preceding blanks, up to tab_count.
- input text: facilitate patterns like if (InputText(..., obj.get_string_ref()) { obj.set_string(...); } relying on internally held buffer.
- input text multi-line: don't directly call AddText() which does an unnecessary vertex reserve for character count prior to clipping. and/or more line-based clipping to AddText(). and/or reorganize TextUnformatted/RenderText for more efficiency for large text (e.g TextUnformatted could clip and log separately, etc).
- input text multi-line: support for cut/paste without selection (cut/paste the current line)
- input text multi-line: line numbers? status bar? (follow up on #200)
- input text multi-line: behave better when user changes input buffer while editing is active (even though it is illegal behavior). namely, the change of buffer can create a scrollbar glitch (#725)
- input text multi-line: better horizontal scrolling support (#383, #1224)
- input text multi-line: single call to AddText() should be coarse clipped on InputTextEx() end.
- input number: optional range min/max for Input*() functions
- input number: holding [-]/[+] buttons could increase the step speed non-linearly (or user-controlled)
- input number: use mouse wheel to step up/down
- input number: applying arithmetics ops (+,-,*,/) messes up with text edit undo stack.
- layout: helper or a way to express ImGui::SameLine(ImGui::GetCursorStartPos().x + ImGui::CalcItemWidth() + ImGui::GetStyle().ItemInnerSpacing.x); in a simpler manner.
- layout: generalization of the above: a concept equivalent to word processor ruler tab stop ~ mini columns (position in X, no clipping implied) (vaguely relate to #267, #395, also what is used internally for menu items)
- layout: horizontal layout helper (#97)
- layout: horizontal flow until no space left (#404)
- layout: more generic alignment state (left/right/centered) for single items?
- layout: clean up the InputFloatN/SliderFloatN/ColorEdit4 layout code. item width should include frame padding.
- layout: vertical alignment of mixed height items (e.g. buttons) within a same line (#1284)
- layout: null layout mode were items are not rendered but user can query GetItemRectMin()/Max/Size.
- layout: (R&D) local multi-pass layout mode.
- layout: (R&D) bind authored layout data (created by an off-line tool), items fetch their pos/size at submission, self-optimize data structures to stable linear access.
- group: BeginGroup() needs a border option. (~#1496)
- group: IsHovered() after EndGroup() covers whole aabb rather than the intersection of individual items. Is that desirable?
- group: merge deactivation/activation within same group (fwd WasEdited flag). (#2550)
- columns: sizing policy (e.g. for each column: fixed size, %, fill, distribute default size among fills) (#513, #125)
- columns: add a conditional parameter to SetColumnOffset() (#513, #125)
- columns: headers. re-orderable. (#513, #125)
- columns: optional sorting modifiers (up/down), sort list so sorting can be done multi-criteria. notify user when sort order changed.
- columns: option to alternate background colors on odd/even scanlines.
- columns: allow columns to recurse.
- columns: allow a same columns set to be interrupted by e.g. CollapsingHeader and resume with columns in sync when moving them.
- columns: sizing is lossy when columns width is very small (default width may turn negative etc.)
- columns: separator function or parameter that works within the column (currently Separator() bypass all columns) (#125)
- columns: flag to add horizontal separator above/below?
- columns/layout: setup minimum line height (equivalent of automatically calling AlignFirstTextHeightToWidgets)
!- color: the color conversion helpers/types are a mess and needs sorting out.
- color: (api breaking) ImGui::ColorConvertXXX functions should be loose ImColorConvertXX to match imgui_internals.h
- plot: full featured plot/graph api w/ scrolling, zooming etc. all bell & whistle. why not!
- plot: PlotLines() should use the polygon-stroke facilities, less vertices (currently issues with averaging normals)
- plot: make it easier for user to draw extra stuff into the graph (e.g: draw basis, highlight certain points, 2d plots, multiple plots)
- plot: "smooth" automatic scale over time, user give an input 0.0(full user scale) 1.0(full derived from value)
- plot: option/feature: draw the zero line
- plot: option/feature: draw grid, vertical markers
- plot: option/feature: draw unit
- plot: add a helper e.g. Plot(char* label, float value, float time_span=2.0f) that stores values and Plot them for you - probably another function name. and/or automatically allow to plot ANY displayed value (more reliance on stable ID)
- clipper: ability to force display 1 item in the list would be convenient (for patterns where we need to set active id etc.)
- clipper: ability to disable the clipping through a simple flag/bool.
- clipper: ability to run without knowing full count in advance.
- clipper: horizontal clipping support. (#2580)
- separator: expose flags (#759)
- separator: width, thickness, centering (#1643)
- splitter: formalize the splitter idiom into an official api (we want to handle n-way split) (#319)
- dock: merge docking branch (#2109)
- dock: dock out from a collapsing header? would work nicely but need emitting window to keep submitting the code.
- tabs: make EndTabBar fail if users doesn't respect BeginTabBar return value, for consistency/future-proofing.
- tabs: persistent order/focus in BeginTabBar() api (#261, #351)
- image/image button: misalignment on padded/bordered button?
- image/image button: parameters are confusing, image() has tint_col,border_col whereas imagebutton() has bg_col/tint_col. Even thou they are different parameters ordering could be more consistent. can we fix that?
- image button: not taking an explicit id can be problematic. (#2464, #1390)
- button: provide a button that looks framed. (?)
- slider/drag: ctrl+click when format doesn't include a % character.. disable? display underlying value in default format? (see TempInputTextScalar)
- slider: allow using the [-]/[+] buttons used by InputFloat()/InputInt()
- slider: initial absolute click is imprecise. change to relative movement slider (same as scrollbar). (#1946)
- slider: add dragging-based widgets to edit values with mouse (on 2 axises), saving screen real-estate.
- slider: tint background based on value (e.g. v_min -> v_max, or use 0.0f either side of the sign)
- slider: relative dragging? + precision dragging
- slider: step option (#1183)
- slider style: fill % of the bar instead of positioning a drag.
- knob: rotating knob widget (#942)
- drag float: power/logarithmic slider and drags are weird. (#1316)
- drag float: up/down axis
- drag float: power != 0.0f with current value being outside the range keeps the value stuck.
- drag float: added leeway on edge (e.g. a few invisible steps past the clamp limits)
- combo: use clipper: make it easier to disable clipper with a single flag.
- combo: flag for BeginCombo to not return true when unchanged (#1182)
- combo: a way/helper to customize the combo preview (#1658)
- combo/listbox: keyboard control. need InputText-like non-active focus + key handling. considering keyboard for custom listbox (pr #203)
- listbox: refactor and clean the begin/end api
- listbox: multiple selection.
- listbox: unselect option (#1208)
- listbox: make it easier/more natural to implement range-select (need some sort of info/ref about the last clicked/focused item that user can translate to an index?) (wip stash)
- listbox: user may want to initial scroll to focus on the one selected value?
- listbox: expose hovered item for a basic ListBox
- listbox: keyboard navigation.
- listbox: disable capturing mouse wheel if the listbox has no scrolling. (#1681)
- listbox: scrolling should track modified selection.
- listbox: future api should allow to enable horizontal scrolling (#2510)
!- popups/menus: clarify usage of popups id, how MenuItem/Selectable closing parent popups affects the ID, etc. this is quite fishy needs improvement! (#331, #402)
- popups/modal: make modal title bar blink when trying to click outside the modal
- popups: reopening context menu at new position should be the behavior by default? (equivalent to internal OpenPopupEx() with reopen_existing=true) (~#1497)
- popups: if the popup functions took explicit ImGuiID it would allow the user to manage the scope of those ID. (#331)
- popups: clicking outside (to close popup) and holding shouldn't drag window below.
- popups: add variant using global identifier similar to Begin/End (#402)
- popups: border options. richer api like BeginChild() perhaps? (#197)
- tooltip: drag and drop with tooltip near monitor edges lose/changes its last direction instead of locking one. The drag and drop tooltip should always follow without changing direction.
- tooltip: tooltip that doesn't fit in entire screen seems to lose their "last preferred direction" and may teleport when moving mouse.
- tooltip: allow to set the width of a tooltip to allow TextWrapped() etc. while keeping the height automatic.
- tooltip: tooltips with delay timers? or general timer policy? (instantaneous vs timed): IsItemHovered() with timer + implicit aabb-id for items with no ID. (#1485)
- menus: calling BeginMenu() twice with a same name doesn't append as Begin() does for regular windows (#1207)
- menus: menu bars inside modal windows are acting weird.
- status-bar: add a per-window status bar helper similar to what menu-bar does.
- shortcuts: local-style shortcut api, e.g. parse "&Save"
- shortcuts,menus: global-style shortcut api e.g. "Save (CTRL+S)" -> explicit flag for recursing into closed menu
- shortcuts: programmatically access shortcuts "Focus("&Save"))
- menus: menu-bar: main menu-bar could affect clamping of windows position (~ akin to modifying DisplayMin)
- menus: hovering from menu to menu on a menu-bar has 1 frame without any menu, which is a little annoying. ideally either 0 either longer.
- menus: could merge draw call in most cases (how about storing an optional aabb in ImDrawCmd to move the burden of merging in a single spot).
- text: selectable text (for copy) as a generic feature (ItemFlags?)
- text: proper alignment options in imgui_internal.h
- text: it's currently impossible to have a window title with "##". perhaps an official workaround would be nice. \ style inhibitor? non-visible ascii code to insert between #?
- text: provided a framed text helper, e.g. https://pastebin.com/1Laxy8bT
- text: refactor TextUnformatted (or underlying function) to more explicitly request if we need width measurement or not
- text link/url button: underlined. should api expose an ID or use text contents as ID? which colors enum to use?
- text/wrapped: should be a more first-class citizen, e.g. wrapped text within a Selectable with known width
- text/wrapped: figure out better way to use TextWrapped() in an always auto-resize context (tooltip, etc.) (#249)
- tree node: add treenode/treepush int variants? not there because (void*) cast from int warns on some platforms/settings?
- tree node: try to apply scrolling at time of TreePop() if node was just opened and end of node is past scrolling limits?
- tree node / selectable render mismatch which is visible if you use them both next to each other (e.g. cf. property viewer)
- tree node: tweak color scheme to distinguish headers from selected tree node (#581)
- tree node: leaf/non-leaf highlight mismatch.
- tree node: _NoIndentOnOpen flag? would require to store a per-depth bit mask to store info for pop (or whatever is cheaper)
- tree node/opt: could avoid formatting when clipped (flag assuming we don't care about width/height, assume single line height?)
- settings: write more decent code to allow saving/loading new fields: columns, selected tree nodes?
- settings: api for per-tool simple persistent data (bool,int,float,columns sizes,etc.) in .ini file (#437)
- settings/persistence: helpers to make TreeNodeBehavior persist (even during dev!) - may need to store some semantic and/or data type in ImGuiStoragePair
- style: better default styles. (#707)
- style: add a highlighted text color (for headers, etc.)
- style: border types: out-screen, in-screen, etc. (#447)
- style: add window shadow (fading away from the window. Paint-style calculation of vertices alpha after drawlist would be easier)
- style: a concept of "compact style" that the end-user can easily rely on (e.g. PushStyleCompact()?) that maps to other settings? avoid implementing duplicate helpers such as SmallCheckbox(), etc.
- style: try to make PushStyleVar() more robust to incorrect parameters (to be more friendly to edit & continues situation).
- style: global scale setting.
- style: FramePadding could be different for up vs down (#584)
- style: WindowPadding needs to be EVEN as the 0.5 multiplier used on this value probably have a subtle effect on clip rectangle
- style: have a more global HSV setter (e.g. alter hue on all elements). consider replacing active/hovered by offset in HSV space? (#438, #707, #1223)
- style: gradients fill (#1223) ~ 2 bg colors for each fill? tricky with rounded shapes and using textures for corners.
- style editor: color child window height expressed in multiple of line height.
- log: have more control over the log scope (e.g. stop logging when leaving current tree node scope)
- log: be able to log anything (e.g. right-click on a window/tree-node, shows context menu? log into tty/file/clipboard)
- log: let user copy any window content to clipboard easily (CTRL+C on windows? while moving it? context menu?). code is commented because it fails with multiple Begin/End pairs.
- log: obsolete LogButtons() all together.
- log: LogButtons() options for specifying depth and/or hiding depth slider
- filters: set a current filter that tree node can automatically query to hide themselves
- filters: handle wild-cards (with implicit leading/trailing *), reg-exprs
- filters: fuzzy matches (may use code at blog.forrestthewoods.com/4cffeed33fdb)
- drag and drop: drag tooltip hovering over source widget with IsItemHovered/SetTooltip flickers.
- drag and drop: fix/support/options for overlapping drag sources.
- drag and drop: releasing a drop shows the "..." tooltip for one frame - since e13e598 (#1725)
- drag and drop: drag source on a group object (would need e.g. an invisible button covering group in EndGroup) https://twitter.com/paniq/status/1121446364909535233
- drag and drop: have some way to know when a drag begin from BeginDragDropSource() pov. (see 2018/01/11 post in #143)
- drag and drop: allow preview tooltip to be submitted from a different place than the drag source. (#1725)
- drag and drop: allow using with other mouse buttons (where activeid won't be set). (#1637)
- drag and drop: make it easier and provide a demo to have tooltip both are source and target site, with a more detailed one on target site (tooltip ordering problem)
- drag and drop: demo with reordering nodes (in a list, or a tree node). (#143)
- drag and drop: test integrating with os drag and drop (make it easy to do a naive WM_DROPFILE integration)
- drag and drop: allow for multiple payload types. (#143)
- drag and drop: make payload optional? payload promise? (see 2018/01/11 post in #143)
- drag and drop: (#143) "both an in-process pointer and a promise to generate a serialized version, for whether the drag ends inside or outside the same process"
- drag and drop: feedback when hovering a region blocked by modal (mouse cursor "NO"?)
- node/graph editor (#306)
- pie menus patterns (#434)
- markup: simple markup language for color change? (#902)
- font: MergeMode: flags to select overwriting or not (this is now very easy with refactored ImFontAtlasBuildWithStbTruetype)
- font: free the Alpha buffer if user only requested RGBA.
!- font: better CalcTextSizeA() API, at least for simple use cases. current one is horrible (perhaps have simple vs extended versions).
- font: for the purpose of RenderTextEllipsis(), it might be useful that CalcTextSizeA() can ignore the trailing padding?
- font: a CalcTextHeight() helper could run faster than CalcTextSize().y
- font: enforce monospace through ImFontConfig (for icons?) + create dual ImFont output from same input, reusing rasterized data but with different glyphs/AdvanceX
- font: finish CustomRectRegister() to allow mapping Unicode codepoint to custom texture data
- font: make it easier to submit own bitmap font (same texture, another texture?). (#2127, #2575)
- font: PushFontSize API (#1018)
- font: MemoryTTF taking ownership confusing/not obvious, maybe default should be opposite?
- font: storing MinAdvanceX per font would allow us to skip calculating line width (under a threshold of character count) in loops looking for block width
- font/demo: add tools to show glyphs used by a text blob, display U16 value, list missing glyphs.
- font/demo: demonstrate use of ImFontGlyphRangesBuilder.
- font/atlas: add a missing Glyphs.reserve()
- font/atlas: incremental updates
- font/atlas: dynamic font atlas to avoid baking huge ranges into bitmap and make scaling easier.
- font/draw: vertical and/or rotated text renderer (#705) - vertical is easier clipping wise
- font/draw: need to be able to specify wrap start position.
- font/draw: better reserve policy for large horizontal block of text (shouldn't reserve for all clipped lines)
- font/draw: underline, squiggle line rendering helpers.
- font: optimization: for monospace font (like the default one) we can trim IndexXAdvance as long as trailing value is == FallbackXAdvance (need to make sure TAB is still correct), would save on cache line.
- font: add support for kerning, probably optional. A) perhaps default to (32..128)^2 matrix ~ 9K entries = 36KB, then hash for non-ascii?. B) or sparse lookup into per-char list?
- font: add a simpler CalcTextSizeA() api? current one ok but not welcome if user needs to call it directly (without going through ImGui::CalcTextSize)
- font: fix AddRemapChar() to work before atlas has been built.
- font: what would it take to support codepoint higher than 0xFFFF? (smileys, etc.) (#2538, #2541)
- font: (api breaking) remove "TTF" from symbol names. also because it now supports OTF.
- font/opt: Considering storing standalone AdvanceX table as 16-bit fixed point integer?
- font/opt: Glyph currently 40 bytes (2+9*4). Consider storing UV as 16 bits integer? (->32 bytes). X0/Y0/X1/Y1 as 16 fixed-point integers? Or X0/Y0 as float and X1/Y1 as fixed8_8?
- nav: some features such as PageUp/Down/Home/End should probably work without ImGuiConfigFlags_NavEnableKeyboard? (where do we draw the line?)
- nav: configuration flag to disable global shortcuts (currently only CTRL-Tab) ?
- nav: Home/End behavior when navigable item is not fully visible at the edge of scrolling? should be backtrack to keep item into view?
- nav: NavScrollToBringItemIntoView() with item bigger than view should focus top-right? Repro: using Nav in "About Window"
- nav: wrap around logic to allow e.g. grid based layout (pressing NavRight on the right-most element would go to the next row, etc.). see internal's NavMoveRequestTryWrapping().
- nav: patterns to make it possible for arrows key to update selection
- nav: restore/find nearest NavId when current one disappear (e.g. pressed a button that disappear, or perhaps auto restoring when current button change name)
- nav: SetItemDefaultFocus() level of priority, so widget like Selectable when inside a popup could claim a low-priority default focus on the first selected iem
- nav: ESC within a menu of a child window seems to exit the child window.
- nav: NavFlattened: ESC on a flattened child should select something.
- nav: NavFlattened: broken: in typical usage scenario, the items of a fully clipped child are currently not considered to enter into a NavFlattened child.
- nav: NavFlattened: init request doesn't select items that are part of a NavFlattened child
- nav: NavFlattened: cannot access menu-bar of a flattened child window with Alt/menu key (not a very common use case..).
- nav: Left within a tree node block as a fallback (ImGuiTreeNodeFlags_NavLeftJumpsBackHere by default?)
- nav/menus: pressing left-right on a vertically clipped menu bar tends to jump to the collapse/close buttons.
- nav/menus: allow pressing Menu to leave a sub-menu.
- nav/menus: a way to access the main menu bar with Alt? (currently needs CTRL+TAB)
- nav/menus: when using the main menu bar, even though we restore focus after, the underlying window loses its title bar highlight during menu manipulation. could we prevent it?
- nav/menus: main menu bar currently cannot restore a NULL focus. Could save NavWindow at the time of being focused, similarly to what popup do?
- nav: simulate right-click or context activation? (SHIFT+F10)
- nav: tabs should go through most/all widgets (in submission order?).
- nav: when CTRL-Tab/windowing is active, the HoveredWindow detection doesn't take account of the window display re-ordering.
- nav: esc/enter default behavior for popups, e.g. be able to mark an "ok" or "cancel" button that would get triggered by those keys.
- nav: when activating a button that changes label (without a static ID) or disappear, can we somehow automatically recover into a nearest highlight item?
- nav: there's currently no way to completely clear focus with the keyboard. depending on patterns used by the application to dispatch inputs, it may be desirable.
- focus: preserve ActiveId/focus stack state, e.g. when opening a menu and close it, previously selected InputText() focus gets restored (#622)
- focus: SetKeyboardFocusHere() on with >= 0 offset could be done on same frame (else latch and modulate on beginning of next frame)
- focus: unable to use SetKeyboardFocusHere() on clipped widgets. (#787)
- inputs: we need an explicit flag about whether the imgui window is focused, to be able to distinguish focused key releases vs alt-tabbing all release behaviors.
- inputs: rework IO system to be able to pass actual ordered/timestamped events. use an event queue? (~#335, #71)
- inputs: support track pad style scrolling & slider edit.
- inputs/io: backspace and arrows in the context of a text input could use system repeat rate.
- inputs/io: clarify/standardize/expose repeat rate and repeat delays (#1808)
- inputs: add mouse cursor for unavailable/no? IDC_NO/SDL_SYSTEM_CURSOR_NO.
- inputs/scrolling: support for smooth scrolling (#2462, #2569)
- misc: idle: expose "woken up" boolean (set by inputs) and/or animation time (for cursor blink) for back-end to be able stop refreshing easily.
- misc: idle: if cursor blink if the _only_ visible animation, core imgui could rewrite vertex alpha to avoid CPU pass on ImGui:: calls.
- misc: idle: if cursor blink if the _only_ visible animation, could even expose a dirty rectangle that optionally can be leverage by some app to render in a smaller viewport, getting rid of much pixel shading cost.
- misc: make the ImGuiCond values linear (non-power-of-two). internal storage for ImGuiWindow can use integers to combine into flags (Why?)
- misc: provide a way to compile out the entire implementation while providing a dummy API (e.g. #define IMGUI_DUMMY_IMPL)
- misc: PushItemFlag(): add a flag to disable keyboard capture when used with mouse? (#1682)
- misc: use more size_t in public api?
- misc: possible compile-time support for string view/range instead of char* would e.g. facilitate usage with Rust (#683)
- misc: possible compile-time support for wchar_t instead of char*?
- backend: bgfx? https://gist.github.com/RichardGale/6e2b74bc42b3005e08397236e4be0fd0
- emscriptem: with refactored examples, we could provide a direct imgui_impl_emscripten platform layer (see eg. https://github.com/floooh/sokol-samples/blob/master/html5/imgui-emsc.cc#L42)
- remote: make a system like RemoteImGui first-class citizen/project (#75)
- demo: find a way to demonstrate textures in the examples application, as it such a common issue for new users.
- demo: demonstrate using PushStyleVar() in more details.
- demo: add vertical separator demo
- demo: add virtual scrolling example?
- demo: demonstrate Plot offset
- demo: window size constraint: square demo is broken when resizing from edges (#1975), would need to rework the callback system to solve this
- examples: window minimize, maximize (#583)
- examples: provide a zero frame-rate/idle example.
- examples: apple: example_apple should be using modern GL3.
- examples: glfw: could go idle when minimized? if (glfwGetWindowAttrib(window, GLFW_ICONIFIED)) { glfwWaitEvents(); continue; } // issue: DeltaTime will be super high on resume, perhaps provide a way to let impl know (#440)
- examples: opengl: rename imgui_impl_opengl2 to impl_opengl_legacy and imgui_impl_opengl3 to imgui_impl_opengl? (#1900)
- examples: opengl: could use a single vertex buffer and glBufferSubData for uploads?
- examples: opengl: explicitly disable GL_STENCIL_TEST in bindings.
- examples: vulkan: viewport: support for synchronized swapping of multiple swap chains.
- optimization: replace vsnprintf with stb_printf? or enable the defines/infrastructure to allow it (#1038)
- optimization: add clipping for multi-component widgets (SliderFloatX, ColorEditX, etc.). one problem is that nav branch can't easily clip parent group when there is a move request.
- optimization: add a flag to disable most of rendering, for the case where the user expect to skip it (#335)
- optimization: fully covered window (covered by another with non-translucent bg + WindowRounding worth of padding) may want to clip rendering.
- optimization: use another hash function than crc32, e.g. FNV1a
- optimization/render: merge command-lists with same clip-rect into one even if they aren't sequential? (as long as in-between clip rectangle don't overlap)?
- optimization: turn some the various stack vectors into statically-sized arrays

View File

@ -0,0 +1,13 @@
using UnrealBuildTool;
public class ImGuiLibrary : ModuleRules
{
#if WITH_FORWARDED_MODULE_RULES_CTOR
public ImGuiLibrary(ReadOnlyTargetRules Target) : base(Target)
#else
public ImGuiLibrary(TargetInfo Target)
#endif
{
Type = ModuleType.External;
}
}

View File

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<TpsData xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<Notification>
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.
</Notification>
</TpsData>

View File

@ -0,0 +1,94 @@
//-----------------------------------------------------------------------------
// COMPILE-TIME OPTIONS FOR DEAR IMGUI
// Runtime options (clipboard callbacks, enabling various features, etc.) can generally be set via the ImGuiIO structure.
// You can use ImGui::SetAllocatorFunctions() before calling ImGui::CreateContext() to rewire memory allocation functions.
//-----------------------------------------------------------------------------
// A) You may edit imconfig.h (and not overwrite it when updating Dear ImGui, or maintain a patch/branch with your modifications to imconfig.h)
// B) or add configuration directives in your own file and compile with #define IMGUI_USER_CONFIG "myfilename.h"
// If you do so you need to make sure that configuration settings are defined consistently _everywhere_ Dear ImGui is used, which include
// the imgui*.cpp files but also _any_ of your code that uses Dear ImGui. This is because some compile-time options have an affect on data structures.
// Defining those options in imconfig.h will ensure every compilation unit gets to see the same data structure layouts.
// 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.
//-----------------------------------------------------------------------------
#pragma once
//---- Define assertion handler. Defaults to calling assert().
//#define IM_ASSERT(_EXPR) MyAssert(_EXPR)
//#define IM_ASSERT(_EXPR) ((void)(_EXPR)) // Disable asserts
//---- Define attributes of all API symbols declarations, e.g. for DLL under Windows
// 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.
//#define IMGUI_API __declspec( dllexport )
//#define IMGUI_API __declspec( dllimport )
//---- Don't define obsolete functions/enums names. Consider enabling from time to time after updating to avoid using soon-to-be obsolete function/names.
//#define IMGUI_DISABLE_OBSOLETE_FUNCTIONS
//---- Don't implement demo windows functionality (ShowDemoWindow()/ShowStyleEditor()/ShowUserGuide() methods will be empty)
// It is very strongly recommended to NOT disable the demo windows during development. Please read the comments in imgui_demo.cpp.
//#define IMGUI_DISABLE_DEMO_WINDOWS
//#define IMGUI_DISABLE_METRICS_WINDOW
//---- Don't implement some functions to reduce linkage requirements.
//#define IMGUI_DISABLE_WIN32_DEFAULT_CLIPBOARD_FUNCTIONS // [Win32] Don't implement default clipboard handler. Won't use and link with OpenClipboard/GetClipboardData/CloseClipboard etc.
//#define IMGUI_DISABLE_WIN32_DEFAULT_IME_FUNCTIONS // [Win32] Don't implement default IME handler. Won't use and link with ImmGetContext/ImmSetCompositionWindow.
//#define IMGUI_DISABLE_WIN32_FUNCTIONS // [Win32] Won't use and link with any Win32 function (clipboard, ime).
//#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).
//#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)
//#define IMGUI_DISABLE_DEFAULT_MATH_FUNCTIONS // Don't implement ImFabs/ImSqrt/ImPow/ImFmod/ImCos/ImSin/ImAcos/ImAtan2 so you can implement them yourself.
//#define IMGUI_DISABLE_DEFAULT_FILE_FUNCTIONS // Don't implement ImFileOpen/ImFileClose/ImFileRead/ImFileWrite 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.
//#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().
//---- Include imgui_user.h at the end of imgui.h as a convenience
//#define IMGUI_INCLUDE_IMGUI_USER_H
//---- Pack colors to BGRA8 instead of RGBA8 (to avoid converting from one to another)
//#define IMGUI_USE_BGRA_PACKED_COLOR
//---- Avoid multiple STB libraries implementations, or redefine path/filenames to prioritize another version
// By default the embedded implementations are declared static and not available outside of imgui cpp files.
//#define IMGUI_STB_TRUETYPE_FILENAME "my_folder/stb_truetype.h"
//#define IMGUI_STB_RECT_PACK_FILENAME "my_folder/stb_rect_pack.h"
//#define IMGUI_DISABLE_STB_TRUETYPE_IMPLEMENTATION
//#define IMGUI_DISABLE_STB_RECT_PACK_IMPLEMENTATION
//---- Define constructor and implicit cast operators to convert back<>forth between your math types and ImVec2/ImVec4.
// This will be inlined as part of ImVec2 and ImVec4 class declarations.
/*
#define IM_VEC2_CLASS_EXTRA \
ImVec2(const MyVec2& f) { x = f.x; y = f.y; } \
operator MyVec2() const { return MyVec2(x,y); }
#define IM_VEC4_CLASS_EXTRA \
ImVec4(const MyVec4& f) { x = f.x; y = f.y; z = f.z; w = f.w; } \
operator MyVec4() const { return MyVec4(x,y,z,w); }
*/
//---- Use 32-bit vertex indices (default is 16-bit) is one way to allow large meshes with more than 64K vertices.
// Your renderer back-end will need to support it (most example renderer back-ends support both 16/32-bit indices).
// Another way to allow large meshes while keeping 16-bit indices is to handle ImDrawCmd::VtxOffset in your renderer.
// Read about ImGuiBackendFlags_RendererHasVtxOffset for details.
//#define ImDrawIdx unsigned int
//---- Override ImDrawCallback signature (will need to modify renderer back-ends accordingly)
//struct ImDrawList;
//struct ImDrawCmd;
//typedef void (*MyImDrawCallback)(const ImDrawList* draw_list, const ImDrawCmd* cmd, void* my_renderer_user_data);
//#define ImDrawCallback MyImDrawCallback
//---- Debug Tools
// Use 'Metrics->Tools->Item Picker' to pick widgets with the mouse and break into them for easy debugging.
//#define IM_DEBUG_BREAK IM_ASSERT(0)
//#define IM_DEBUG_BREAK __debugbreak()
// Have the Item Picker break in the ItemAdd() function instead of ItemHoverable() - which is earlier in the code, will catch a few extra items, allow picking items other than Hovered one.
// This adds a small runtime cost which is why it is not enabled by default.
//#define IMGUI_DEBUG_TOOL_ITEM_PICKER_EX
//---- Tip: You can add extra functions within the ImGui:: namespace, here or in your own headers files.
/*
namespace ImGui
{
void MyFunction(const char* name, const MyMatrix44& v);
}
*/

File diff suppressed because it is too large Load Diff

Some files were not shown because too many files have changed in this diff Show More