You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
921 lines
39 KiB
C++
921 lines
39 KiB
C++
/*
|
|
* Copyright (c) Contributors to the Open 3D Engine Project. For complete copyright and license terms please see the LICENSE at the root of this distribution.
|
|
*
|
|
* SPDX-License-Identifier: Apache-2.0 OR MIT
|
|
*
|
|
*/
|
|
|
|
#include "ImGui_precompiled.h"
|
|
#include "ImGuiManager.h"
|
|
#include <ImGuiContextScope.h>
|
|
#include <AzCore/PlatformIncl.h>
|
|
#include <OtherActiveImGuiBus.h>
|
|
|
|
#ifdef IMGUI_ENABLED
|
|
|
|
#include <AzCore/Interface/Interface.h>
|
|
#include <AzCore/Component/ComponentApplicationBus.h>
|
|
#include <AzFramework/Input/Buses/Requests/InputTextEntryRequestBus.h>
|
|
#include <AzFramework/Input/Devices/Mouse/InputDeviceMouse.h>
|
|
#include <AzFramework/Input/Devices/Keyboard/InputDeviceKeyboard.h>
|
|
#include <AzFramework/Input/Devices/Gamepad/InputDeviceGamepad.h>
|
|
#include <AzFramework/Input/Devices/Touch/InputDeviceTouch.h>
|
|
#include <AzFramework/Input/Devices/VirtualKeyboard/InputDeviceVirtualKeyboard.h>
|
|
#include <IConsole.h>
|
|
#include <ITimer.h>
|
|
#include <imgui/imgui_internal.h>
|
|
#include <sstream>
|
|
#include <string>
|
|
|
|
using namespace AzFramework;
|
|
using namespace ImGui;
|
|
|
|
// Wheel Delta const value.
|
|
const constexpr uint32_t IMGUI_WHEEL_DELTA = 120; // From WinUser.h, for Linux
|
|
|
|
// Typedef and local static map to hold LyInput->ImGui Nav mappings ( filled up in Initialize() )
|
|
typedef AZStd::pair<AzFramework::InputChannelId, ImGuiNavInput_> LyButtonImGuiNavIndexPair;
|
|
typedef AZStd::unordered_map<AzFramework::InputChannelId, ImGuiNavInput_> LyButtonImGuiNavIndexMap;
|
|
static LyButtonImGuiNavIndexMap s_lyInputToImGuiNavIndexMap;
|
|
|
|
/**
|
|
An anonymous namespace containing helper functions for interoperating with AzFrameworkInput.
|
|
*/
|
|
namespace
|
|
{
|
|
/**
|
|
Utility function to map an AzFrameworkInput device key to its integer index.
|
|
|
|
@param inputChannelId the ID for an AzFrameworkInput device key.
|
|
@return the index of the indicated key, or -1 if not found.
|
|
*/
|
|
unsigned int GetAzKeyIndex(const InputChannelId& inputChannelId)
|
|
{
|
|
const auto& keys = InputDeviceKeyboard::Key::All;
|
|
const auto& it = AZStd::find(keys.cbegin(), keys.cend(), inputChannelId);
|
|
return it != keys.cend() ? static_cast<unsigned int>(it - keys.cbegin()) : UINT_MAX;
|
|
}
|
|
|
|
/**
|
|
Utility function to map an AzFrameworkInput mouse device button to its integer index.
|
|
|
|
@param inputChannelId the ID for an AzFrameworkInput mouse device button.
|
|
@return the index of the indicated button, or -1 if not found.
|
|
*/
|
|
unsigned int GetAzMouseButtonIndex(const InputChannelId& inputChannelId)
|
|
{
|
|
const auto& buttons = InputDeviceMouse::Button::All;
|
|
const auto& it = AZStd::find(buttons.cbegin(), buttons.cend(), inputChannelId);
|
|
return it != buttons.cend() ? static_cast<unsigned int>(it - buttons.cbegin()) : UINT_MAX;
|
|
}
|
|
|
|
/**
|
|
Utility function to map an AzFrameworkInput touch input to its integer index.
|
|
|
|
@param inputChannelId the ID for an AzFrameworkInput touch input.
|
|
@return the index of the indicated touch, or -1 if not found.
|
|
*/
|
|
unsigned int GetAzTouchIndex(const InputChannelId& inputChannelId)
|
|
{
|
|
const auto& touches = InputDeviceTouch::Touch::All;
|
|
const auto& it = AZStd::find(touches.cbegin(), touches.cend(), inputChannelId);
|
|
return it != touches.cend() ? static_cast<unsigned int>(it - touches.cbegin()) : UINT_MAX;
|
|
}
|
|
|
|
/**
|
|
Utility function to map an AzFrameworkInput controller button to its integer index.
|
|
|
|
@param inputChannelId the ID for an AzFrameworkInput controller button.
|
|
@return the index of the indicated button, or -1 if not found.
|
|
*/
|
|
unsigned int GetAzControllerButtonIndex(const InputChannelId& inputChannelId)
|
|
{
|
|
const auto& buttons = InputDeviceGamepad::Button::All;
|
|
const auto& triggers = InputDeviceGamepad::Trigger::All;
|
|
const auto& it = AZStd::find(buttons.cbegin(), buttons.cend(), inputChannelId);
|
|
if (it != buttons.cend())
|
|
{
|
|
return static_cast<unsigned int>(it - buttons.cbegin());
|
|
}
|
|
else
|
|
{
|
|
const auto& it2 = AZStd::find(triggers.cbegin(), triggers.cend(), inputChannelId);
|
|
if (it2 != triggers.cend())
|
|
{
|
|
return static_cast<unsigned int>(it2 - triggers.cbegin()) + AZ_ARRAY_SIZE(InputDeviceGamepad::Button::All);
|
|
}
|
|
}
|
|
|
|
return UINT_MAX;
|
|
}
|
|
|
|
/**
|
|
Utility function to map an AzFrameworkInput thumbstick movement to its integer index.
|
|
|
|
@param inputChannelId the ID for an AzFrameworkInput thumbstick movement.
|
|
@return the index of the indicated button, or -1 if not found.
|
|
*/
|
|
unsigned int GetAzControllerThumbstickIndex(const InputChannelId& inputChannelId)
|
|
{
|
|
const auto& thumbstickMovements = InputDeviceGamepad::ThumbStickDirection::All;
|
|
const auto& it = AZStd::find(thumbstickMovements.cbegin(), thumbstickMovements.cend(), inputChannelId);
|
|
return it != thumbstickMovements.cend() ? static_cast<unsigned int>(it - thumbstickMovements.cbegin()) : UINT_MAX;
|
|
}
|
|
|
|
/**
|
|
Utility function to map an AzFrameworkInput thumbstick movement amountto its integer index.
|
|
|
|
@param inputChannelId the ID for an AzFrameworkInput thumbstick movement amount.
|
|
@return the index of the indicated button, or -1 if not found.
|
|
*/
|
|
unsigned int GetAzControllerThumbstickAmountIndex(const InputChannelId& inputChannelId)
|
|
{
|
|
const auto& thumbstickMovementAmounts = InputDeviceGamepad::ThumbStickAxis1D::All;
|
|
const auto& it = AZStd::find(thumbstickMovementAmounts.cbegin(), thumbstickMovementAmounts.cend(), inputChannelId);
|
|
return it != thumbstickMovementAmounts.cend() ? static_cast<unsigned int>(it - thumbstickMovementAmounts.cbegin()) : UINT_MAX;
|
|
}
|
|
}
|
|
|
|
void ImGuiManager::Initialize()
|
|
{
|
|
// Register for Buses
|
|
ImGuiManagerBus::Handler::BusConnect();
|
|
|
|
// Register for Input Notifications
|
|
InputChannelEventListener::Connect();
|
|
InputTextEventListener::Connect();
|
|
|
|
// Dynamically Load ImGui
|
|
#if defined(LOAD_IMGUI_LIB_DYNAMICALLY) && !defined(AZ_MONOLITHIC_BUILD)
|
|
|
|
AZ::OSString imgGuiLibPath = "imguilib";
|
|
|
|
// Let the application process the path
|
|
AZ::ComponentApplicationBus::Broadcast(&AZ::ComponentApplicationBus::Events::ResolveModulePath, imgGuiLibPath);
|
|
m_imgSharedLib = AZ::DynamicModuleHandle::Create(imgGuiLibPath.c_str());
|
|
if (!m_imgSharedLib->Load(false))
|
|
{
|
|
AZ_Warning("ImGuiManager", false, "%s %s", __func__, "Unable to load " AZ_DYNAMIC_LIBRARY_PREFIX "imguilib" AZ_DYNAMIC_LIBRARY_EXTENSION "-- Skipping ImGui Initialization.");
|
|
return;
|
|
}
|
|
|
|
#endif // defined(LOAD_IMGUI_LIB_DYNAMICALLY) && !defined(AZ_MONOLITHIC_BUILD)
|
|
|
|
// Create ImGui Context
|
|
m_imguiContext = ImGui::CreateContext();
|
|
ImGui::ImGuiContextScope contextScope(m_imguiContext);
|
|
|
|
// Set config file
|
|
ImGuiIO& io = ImGui::GetIO();
|
|
io.IniFilename = "imgui.ini";
|
|
|
|
// Enable Nav Keyboard by default and allow
|
|
io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard;
|
|
io.ConfigFlags |= ImGuiConfigFlags_NavEnableSetMousePos;
|
|
|
|
// Config Keyboard Mapping keys.
|
|
io.KeyMap[ImGuiKey_Tab] = GetAzKeyIndex(InputDeviceKeyboard::Key::EditTab);
|
|
io.KeyMap[ImGuiKey_LeftArrow] = GetAzKeyIndex(InputDeviceKeyboard::Key::NavigationArrowLeft);
|
|
io.KeyMap[ImGuiKey_RightArrow] = GetAzKeyIndex(InputDeviceKeyboard::Key::NavigationArrowRight);
|
|
io.KeyMap[ImGuiKey_UpArrow] = GetAzKeyIndex(InputDeviceKeyboard::Key::NavigationArrowUp);
|
|
io.KeyMap[ImGuiKey_DownArrow] = GetAzKeyIndex(InputDeviceKeyboard::Key::NavigationArrowDown);
|
|
io.KeyMap[ImGuiKey_PageUp] = GetAzKeyIndex(InputDeviceKeyboard::Key::NavigationPageUp);
|
|
io.KeyMap[ImGuiKey_PageDown] = GetAzKeyIndex(InputDeviceKeyboard::Key::NavigationPageDown);
|
|
io.KeyMap[ImGuiKey_Home] = GetAzKeyIndex(InputDeviceKeyboard::Key::NavigationHome);
|
|
io.KeyMap[ImGuiKey_End] = GetAzKeyIndex(InputDeviceKeyboard::Key::NavigationEnd);
|
|
io.KeyMap[ImGuiKey_Insert] = GetAzKeyIndex(InputDeviceKeyboard::Key::NavigationInsert);
|
|
io.KeyMap[ImGuiKey_Delete] = GetAzKeyIndex(InputDeviceKeyboard::Key::NavigationDelete);
|
|
io.KeyMap[ImGuiKey_Backspace] = GetAzKeyIndex(InputDeviceKeyboard::Key::EditBackspace);
|
|
io.KeyMap[ImGuiKey_Space] = GetAzKeyIndex(InputDeviceKeyboard::Key::EditSpace);
|
|
io.KeyMap[ImGuiKey_Enter] = GetAzKeyIndex(InputDeviceKeyboard::Key::EditEnter);
|
|
io.KeyMap[ImGuiKey_Escape] = GetAzKeyIndex(InputDeviceKeyboard::Key::Escape);
|
|
io.KeyMap[ImGuiKey_A] = GetAzKeyIndex(InputDeviceKeyboard::Key::AlphanumericA);
|
|
io.KeyMap[ImGuiKey_C] = GetAzKeyIndex(InputDeviceKeyboard::Key::AlphanumericC);
|
|
io.KeyMap[ImGuiKey_V] = GetAzKeyIndex(InputDeviceKeyboard::Key::AlphanumericV);
|
|
io.KeyMap[ImGuiKey_X] = GetAzKeyIndex(InputDeviceKeyboard::Key::AlphanumericX);
|
|
io.KeyMap[ImGuiKey_Y] = GetAzKeyIndex(InputDeviceKeyboard::Key::AlphanumericY);
|
|
io.KeyMap[ImGuiKey_Z] = GetAzKeyIndex(InputDeviceKeyboard::Key::AlphanumericZ);
|
|
|
|
// Initialize controller button mapping
|
|
s_lyInputToImGuiNavIndexMap.insert(LyButtonImGuiNavIndexPair(InputDeviceGamepad::Button::A, ImGuiNavInput_Activate));
|
|
s_lyInputToImGuiNavIndexMap.insert(LyButtonImGuiNavIndexPair(InputDeviceGamepad::Button::B, ImGuiNavInput_Cancel));
|
|
s_lyInputToImGuiNavIndexMap.insert(LyButtonImGuiNavIndexPair(InputDeviceGamepad::Button::X, ImGuiNavInput_Menu));
|
|
s_lyInputToImGuiNavIndexMap.insert(LyButtonImGuiNavIndexPair(InputDeviceGamepad::Button::Y, ImGuiNavInput_Input));
|
|
s_lyInputToImGuiNavIndexMap.insert(LyButtonImGuiNavIndexPair(InputDeviceGamepad::Button::DU, ImGuiNavInput_DpadUp));
|
|
s_lyInputToImGuiNavIndexMap.insert(LyButtonImGuiNavIndexPair(InputDeviceGamepad::Button::DD, ImGuiNavInput_DpadDown));
|
|
s_lyInputToImGuiNavIndexMap.insert(LyButtonImGuiNavIndexPair(InputDeviceGamepad::Button::DL, ImGuiNavInput_DpadLeft));
|
|
s_lyInputToImGuiNavIndexMap.insert(LyButtonImGuiNavIndexPair(InputDeviceGamepad::Button::DR, ImGuiNavInput_DpadRight));
|
|
s_lyInputToImGuiNavIndexMap.insert(LyButtonImGuiNavIndexPair(InputDeviceGamepad::Button::R1, ImGuiNavInput_FocusNext));
|
|
s_lyInputToImGuiNavIndexMap.insert(LyButtonImGuiNavIndexPair(InputDeviceGamepad::Button::L1, ImGuiNavInput_FocusPrev));
|
|
s_lyInputToImGuiNavIndexMap.insert(LyButtonImGuiNavIndexPair(InputDeviceGamepad::Trigger::L2, ImGuiNavInput_TweakSlow));
|
|
s_lyInputToImGuiNavIndexMap.insert(LyButtonImGuiNavIndexPair(InputDeviceGamepad::Trigger::R2, ImGuiNavInput_TweakFast));
|
|
s_lyInputToImGuiNavIndexMap.insert(LyButtonImGuiNavIndexPair(InputDeviceGamepad::ThumbStickDirection::LU, ImGuiNavInput_LStickUp));
|
|
s_lyInputToImGuiNavIndexMap.insert(LyButtonImGuiNavIndexPair(InputDeviceGamepad::ThumbStickDirection::LD, ImGuiNavInput_LStickDown));
|
|
s_lyInputToImGuiNavIndexMap.insert(LyButtonImGuiNavIndexPair(InputDeviceGamepad::ThumbStickDirection::LL, ImGuiNavInput_LStickLeft));
|
|
s_lyInputToImGuiNavIndexMap.insert(LyButtonImGuiNavIndexPair(InputDeviceGamepad::ThumbStickDirection::LR, ImGuiNavInput_LStickRight));
|
|
|
|
// Set the initial Display Size (gets updated each frame anyway)
|
|
io.DisplaySize.x = 1920;
|
|
io.DisplaySize.y = 1080;
|
|
|
|
// Create a default font
|
|
io.Fonts->AddFontDefault();
|
|
io.Fonts->Build();
|
|
|
|
// Broadcast ImGui Ready to Listeners
|
|
ImGuiUpdateListenerBus::Broadcast(&IImGuiUpdateListener::OnImGuiInitialize);
|
|
m_currentControllerIndex = -1;
|
|
m_button1Pressed = m_button2Pressed = false;
|
|
m_menuBarStatusChanged = false;
|
|
|
|
// See if a hardware mouse device is connected on startup, we will use it to help determine if we should draw the mouse cursor and turn on controller support by default if one is not found.
|
|
// Future work here could include responding to the mouse being connected and disconnected at run-time, but this is fine for now.
|
|
const AzFramework::InputDevice* mouseDevice = AzFramework::InputDeviceRequests::FindInputDevice(AzFramework::InputDeviceMouse::Id);
|
|
m_hardwardeMouseConnected = mouseDevice && mouseDevice->IsConnected();
|
|
|
|
AZ::Interface<ImGui::IImGuiManager>::Register(this);
|
|
}
|
|
|
|
void ImGuiManager::Shutdown()
|
|
{
|
|
AZ::Interface<ImGui::IImGuiManager>::Unregister(this);
|
|
|
|
if (!gEnv)
|
|
{
|
|
AZ_Warning("ImGuiManager", false, "%s %s", __func__, "gEnv Invalid -- Skipping ImGui Shutdown.");
|
|
return;
|
|
}
|
|
#if defined(LOAD_IMGUI_LIB_DYNAMICALLY) && !defined(AZ_MONOLITHIC_BUILD)
|
|
if (m_imgSharedLib->IsLoaded())
|
|
{
|
|
m_imgSharedLib->Unload();
|
|
}
|
|
#endif
|
|
|
|
// Unregister from Buses
|
|
ImGuiManagerBus::Handler::BusDisconnect();
|
|
InputChannelEventListener::Disconnect();
|
|
InputTextEventListener::Disconnect();
|
|
AzFramework::WindowNotificationBus::Handler::BusDisconnect();
|
|
|
|
// Finally, destroy the ImGui Context.
|
|
ImGui::DestroyContext(m_imguiContext);
|
|
}
|
|
|
|
void ImGui::ImGuiManager::OverrideRenderWindowSize(uint32_t width, uint32_t height)
|
|
{
|
|
m_windowSize.m_width = width;
|
|
m_windowSize.m_height = height;
|
|
m_overridingWindowSize = true;
|
|
// Don't listen for window updates if our window size is being overridden
|
|
AzFramework::WindowNotificationBus::Handler::BusDisconnect();
|
|
}
|
|
|
|
void ImGui::ImGuiManager::RestoreRenderWindowSizeToDefault()
|
|
{
|
|
m_overridingWindowSize = false;
|
|
InitWindowSize();
|
|
}
|
|
|
|
void ImGui::ImGuiManager::SetDpiScalingFactor(float dpiScalingFactor)
|
|
{
|
|
ImGuiIO& io = ImGui::GetIO();
|
|
// Set the global font scale to size our UI to the scaling factor
|
|
// Note: Currently we use the default, 13px fixed-size IMGUI font, so this can get somewhat blurry
|
|
io.FontGlobalScale = dpiScalingFactor;
|
|
}
|
|
|
|
float ImGui::ImGuiManager::GetDpiScalingFactor() const
|
|
{
|
|
ImGuiIO& io = ImGui::GetIO();
|
|
return io.FontGlobalScale;
|
|
}
|
|
|
|
void ImGuiManager::Render()
|
|
{
|
|
if (m_clientMenuBarState == DisplayState::Hidden && m_editorWindowState == DisplayState::Hidden)
|
|
{
|
|
return;
|
|
}
|
|
|
|
ImGui::ImGuiContextScope contextScope(m_imguiContext);
|
|
|
|
// Update Display Size
|
|
ImGuiIO& io = ImGui::GetIO();
|
|
io.DisplaySize = m_lastRenderResolution;
|
|
|
|
if ((m_clientMenuBarState == DisplayState::Visible) || (m_editorWindowState != DisplayState::Hidden))
|
|
{
|
|
if (IsControllerSupportModeEnabled(ImGuiControllerModeFlags::Mouse))
|
|
{
|
|
// Update Mouse Position from Stick Position
|
|
m_controllerMousePosition[0] = AZ::GetClamp(m_controllerMousePosition[0] + ((io.NavInputs[ImGuiNavInput_LStickRight] - io.NavInputs[ImGuiNavInput_LStickLeft]) * m_controllerMouseSensitivity), 0.0f, m_renderResolution.x);
|
|
m_controllerMousePosition[1] = AZ::GetClamp(m_controllerMousePosition[1] + ((io.NavInputs[ImGuiNavInput_LStickDown] - io.NavInputs[ImGuiNavInput_LStickUp]) * m_controllerMouseSensitivity), 0.0f, m_renderResolution.y);
|
|
io.MousePos.x = m_controllerMousePosition[0];
|
|
io.MousePos.y = m_controllerMousePosition[1];
|
|
io.MouseDown[0] = (io.NavInputs[ImGuiNavInput_Activate] > 0.1f);
|
|
io.MouseDown[1] = (io.NavInputs[ImGuiNavInput_Cancel] > 0.1f);
|
|
}
|
|
else if (m_useLastPrimaryTouchPosition)
|
|
{
|
|
io.MousePos.x = m_lastPrimaryTouchPosition[0];
|
|
io.MousePos.y = m_lastPrimaryTouchPosition[1];
|
|
m_controllerMousePosition[0] = io.MousePos.x;
|
|
m_controllerMousePosition[1] = io.MousePos.y;
|
|
m_useLastPrimaryTouchPosition = false;
|
|
}
|
|
else
|
|
{
|
|
AZ::Vector2 systemCursorPositionNormalized = AZ::Vector2::CreateZero();
|
|
InputSystemCursorRequestBus::EventResult(
|
|
systemCursorPositionNormalized,
|
|
InputDeviceMouse::Id,
|
|
&InputSystemCursorRequests::GetSystemCursorPositionNormalized);
|
|
|
|
io.MousePos.x = systemCursorPositionNormalized.GetX() * m_lastRenderResolution.x;
|
|
io.MousePos.y = systemCursorPositionNormalized.GetY() * m_lastRenderResolution.y;
|
|
m_controllerMousePosition[0] = io.MousePos.x;
|
|
m_controllerMousePosition[1] = io.MousePos.y;
|
|
}
|
|
|
|
// Clear NavInputs if either the mouse is explicitly enabled, or if the contextual controller is explicitly disabled
|
|
if (IsControllerSupportModeEnabled(ImGuiControllerModeFlags::Mouse) || !IsControllerSupportModeEnabled(ImGuiControllerModeFlags::Contextual))
|
|
{
|
|
memset(io.NavInputs, 0, sizeof(io.NavInputs));
|
|
}
|
|
}
|
|
|
|
// If no item and no window is focused, we should artificially add focus to the Main Menu Bar, to save 1 step when navigating with a controller.
|
|
if (!ImGui::IsAnyItemFocused() && !ImGui::IsWindowFocused(ImGuiFocusedFlags_AnyWindow))
|
|
{
|
|
ImGuiWindow* mainMenuWin = ImGui::FindWindowByName("##MainMenuBar");
|
|
if (mainMenuWin)
|
|
{
|
|
ImGui::GetCurrentContext()->NavLayer = ImGuiNavLayer_Menu;
|
|
ImGui::GetCurrentContext()->NavWindow = mainMenuWin;
|
|
ImGui::NavInitWindow(mainMenuWin, true);
|
|
}
|
|
}
|
|
|
|
// Show or hide the virtual keyboard as necessary
|
|
bool hasTextEntryStarted = false;
|
|
AzFramework::InputTextEntryRequestBus::EventResult(hasTextEntryStarted,
|
|
AzFramework::InputDeviceVirtualKeyboard::Id,
|
|
&AzFramework::InputTextEntryRequests::HasTextEntryStarted);
|
|
if (io.WantTextInput && !hasTextEntryStarted)
|
|
{
|
|
AzFramework::InputTextEntryRequests::VirtualKeyboardOptions options;
|
|
AzFramework::InputTextEntryRequestBus::Broadcast(&AzFramework::InputTextEntryRequests::TextEntryStart, options);
|
|
}
|
|
else if (!io.WantTextInput && hasTextEntryStarted)
|
|
{
|
|
AzFramework::InputTextEntryRequestBus::Broadcast(&AzFramework::InputTextEntryRequests::TextEntryStop);
|
|
io.KeysDown[GetAzKeyIndex(InputDeviceKeyboard::Key::EditEnter)] = false;
|
|
}
|
|
|
|
// Start New Frame
|
|
ImGui::NewFrame();
|
|
|
|
//// START FROM PREUPDATE
|
|
ICVar* consoleDisabled = gEnv->pConsole->GetCVar("sys_DeactivateConsole");
|
|
if (consoleDisabled && consoleDisabled->GetIVal() != 0)
|
|
{
|
|
m_clientMenuBarState = DisplayState::Hidden;
|
|
m_editorWindowState = DisplayState::Hidden;
|
|
}
|
|
|
|
// Advance ImGui by Elapsed Frame Time
|
|
io.DeltaTime = gEnv->pTimer->GetFrameTime();
|
|
//// END FROM PREUPDATE
|
|
|
|
AZ::u32 backBufferWidth = m_windowSize.m_width;
|
|
AZ::u32 backBufferHeight = m_windowSize.m_height;
|
|
|
|
// Find ImGui Render Resolution.
|
|
int renderRes[2];
|
|
switch (m_resolutionMode)
|
|
{
|
|
default:
|
|
break;
|
|
|
|
case ImGuiResolutionMode::LockToResolution:
|
|
renderRes[0] = static_cast<int>(m_renderResolution.x);
|
|
renderRes[1] = static_cast<int>(m_renderResolution.y);
|
|
break;
|
|
|
|
case ImGuiResolutionMode::MatchRenderResolution:
|
|
renderRes[0] = backBufferWidth;
|
|
renderRes[1] = backBufferHeight;
|
|
break;
|
|
|
|
case ImGuiResolutionMode::MatchToMaxRenderResolution:
|
|
if (backBufferWidth <= static_cast<int>(m_renderResolution.x))
|
|
{
|
|
renderRes[0] = backBufferWidth;
|
|
renderRes[1] = backBufferHeight;
|
|
}
|
|
else
|
|
{
|
|
renderRes[0] = static_cast<int>(m_renderResolution.x);
|
|
renderRes[1] = static_cast<int>(m_renderResolution.y);
|
|
}
|
|
break;
|
|
}
|
|
|
|
ImVec2 scaleRects( static_cast<float>(backBufferWidth) / static_cast<float>(renderRes[0]),
|
|
static_cast<float>(backBufferHeight / static_cast<float>(renderRes[1])));
|
|
|
|
// Save off the last render resolution for input
|
|
m_lastRenderResolution.x = static_cast<float>(renderRes[0]);
|
|
m_lastRenderResolution.y = static_cast<float>(renderRes[1]);
|
|
|
|
// Render!
|
|
RenderImGuiBuffers(scaleRects);
|
|
|
|
// Clear the simulated backspace key
|
|
if (m_simulateBackspaceKeyPressed)
|
|
{
|
|
io.KeysDown[GetAzKeyIndex(InputDeviceKeyboard::Key::EditBackspace)] = false;
|
|
m_simulateBackspaceKeyPressed = false;
|
|
}
|
|
}
|
|
|
|
/**
|
|
@return true if input should be consumed, false otherwise.
|
|
*/
|
|
bool ImGuiManager::OnInputChannelEventFiltered(const InputChannel& inputChannel)
|
|
{
|
|
ImGui::ImGuiContextScope contextScope(m_imguiContext);
|
|
|
|
ImGuiIO& io = ImGui::GetIO();
|
|
const InputChannelId& inputChannelId = inputChannel.GetInputChannelId();
|
|
const InputDeviceId& inputDeviceId = inputChannel.GetInputDevice().GetInputDeviceId();
|
|
|
|
// Handle Keyboard Hotkeys
|
|
if (inputDeviceId == InputDeviceKeyboard::Id && inputChannel.IsStateBegan())
|
|
{
|
|
// Cycle through ImGui Menu Bar States on Home button press
|
|
if (inputChannelId == InputDeviceKeyboard::Key::NavigationHome)
|
|
{
|
|
ToggleThroughImGuiVisibleState(-1);
|
|
}
|
|
|
|
// Cycle through Standalone Editor Window States
|
|
if (inputChannel.GetInputChannelId() == InputDeviceKeyboard::Key::NavigationEnd)
|
|
{
|
|
if (gEnv->IsEditor() && m_editorWindowState == DisplayState::Hidden)
|
|
{
|
|
ImGuiUpdateListenerBus::Broadcast(&IImGuiUpdateListener::OnOpenEditorWindow);
|
|
}
|
|
else
|
|
{
|
|
m_editorWindowState = m_editorWindowState == DisplayState::Visible
|
|
? DisplayState::VisibleNoMouse
|
|
: DisplayState::Visible;
|
|
}
|
|
}
|
|
}
|
|
|
|
// Handle Keyboard Modifier Keys
|
|
if (inputDeviceId == InputDeviceKeyboard::Id)
|
|
{
|
|
if (inputChannelId == InputDeviceKeyboard::Key::ModifierShiftL
|
|
|| inputChannelId == InputDeviceKeyboard::Key::ModifierShiftR)
|
|
{
|
|
io.KeyShift = inputChannel.IsActive();
|
|
}
|
|
else if (inputChannelId == InputDeviceKeyboard::Key::ModifierAltL
|
|
|| inputChannelId == InputDeviceKeyboard::Key::ModifierAltR)
|
|
{
|
|
io.KeyAlt = inputChannel.IsActive();
|
|
}
|
|
else if (inputChannelId == InputDeviceKeyboard::Key::ModifierCtrlL
|
|
|| inputChannelId == InputDeviceKeyboard::Key::ModifierCtrlR)
|
|
{
|
|
io.KeyCtrl = inputChannel.IsActive();
|
|
}
|
|
|
|
// Set Keydown Flag in ImGui Keys Array
|
|
const int keyIndex = GetAzKeyIndex(inputChannelId);
|
|
if (0 <= keyIndex && keyIndex < AZ_ARRAY_SIZE(io.KeysDown))
|
|
{
|
|
io.KeysDown[keyIndex] = inputChannel.IsActive();
|
|
}
|
|
}
|
|
|
|
// Handle Controller Inputs
|
|
int inputControllerIndex = -1;
|
|
bool controllerInput = false;
|
|
for (int i = 0; i < MaxControllerNumber; ++i)
|
|
{
|
|
//Allow only one controller navigating ImGui at the same time. After menu bar dismissed, other controllers could take over
|
|
if (inputDeviceId == InputDeviceGamepad::IdForIndexN(i))
|
|
{
|
|
inputControllerIndex = i;
|
|
controllerInput = true;
|
|
}
|
|
}
|
|
|
|
|
|
if (controllerInput)
|
|
{
|
|
// Only pipe in Controller Nav Inputs if we are the current Controller Index and at least 1 of the two controller modes are enabled.
|
|
if (m_currentControllerIndex == inputControllerIndex && m_controllerModeFlags)
|
|
{
|
|
const auto lyButtonToImGuiNav = s_lyInputToImGuiNavIndexMap.find(inputChannelId);
|
|
if (lyButtonToImGuiNav != s_lyInputToImGuiNavIndexMap.end())
|
|
{
|
|
const ImGuiNavInput_ imGuiNavInput = lyButtonToImGuiNav->second;
|
|
io.NavInputs[imGuiNavInput] = inputChannel.GetValue();
|
|
}
|
|
}
|
|
|
|
//Switch menu bar display only if two buttons are pressed at the same time
|
|
if (inputChannelId == InputDeviceGamepad::Button::L3)
|
|
{
|
|
if (inputChannel.IsStateBegan())
|
|
{
|
|
m_button1Pressed = true;
|
|
}
|
|
if (inputChannel.IsStateEnded())
|
|
{
|
|
m_button1Pressed = false;
|
|
m_menuBarStatusChanged = false;
|
|
}
|
|
}
|
|
if (inputChannelId == InputDeviceGamepad::Button::R3)
|
|
{
|
|
if (inputChannel.IsStateBegan())
|
|
{
|
|
m_button2Pressed = true;
|
|
}
|
|
if (inputChannel.IsStateEnded())
|
|
{
|
|
m_button2Pressed = false;
|
|
m_menuBarStatusChanged = false;
|
|
}
|
|
}
|
|
if (!m_menuBarStatusChanged && m_button1Pressed && m_button2Pressed)
|
|
{
|
|
ToggleThroughImGuiVisibleState(inputControllerIndex);
|
|
}
|
|
|
|
// If we have the Discrete Input Mode Enabled.. and we are in the Visible State, then consume input here
|
|
if (m_enableDiscreteInputMode && m_clientMenuBarState == DisplayState::Visible)
|
|
{
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
// Handle Mouse Inputs
|
|
if (inputDeviceId == InputDeviceMouse::Id)
|
|
{
|
|
const int mouseButtonIndex = GetAzMouseButtonIndex(inputChannelId);
|
|
if (0 <= mouseButtonIndex && mouseButtonIndex < AZ_ARRAY_SIZE(io.MouseDown))
|
|
{
|
|
io.MouseDown[mouseButtonIndex] = inputChannel.IsActive();
|
|
}
|
|
else if (inputChannelId == InputDeviceMouse::Movement::Z)
|
|
{
|
|
io.MouseWheel = inputChannel.GetValue() / static_cast<float>(IMGUI_WHEEL_DELTA);
|
|
}
|
|
}
|
|
|
|
// Handle Touch Inputs
|
|
if (inputDeviceId == InputDeviceTouch::Id)
|
|
{
|
|
const int touchIndex = GetAzTouchIndex(inputChannelId);
|
|
if (0 <= touchIndex && touchIndex < AZ_ARRAY_SIZE(io.MouseDown))
|
|
{
|
|
io.MouseDown[touchIndex] = inputChannel.IsActive();
|
|
}
|
|
|
|
if (touchIndex == 0)
|
|
{
|
|
const AzFramework::InputChannel::PositionData2D* positionData2D = inputChannel.GetCustomData<AzFramework::InputChannel::PositionData2D>();
|
|
if (positionData2D)
|
|
{
|
|
m_lastPrimaryTouchPosition[0] = positionData2D->m_normalizedPosition.GetX() * m_lastRenderResolution.x;
|
|
m_lastPrimaryTouchPosition[1] = positionData2D->m_normalizedPosition.GetY() * m_lastRenderResolution.y;
|
|
m_useLastPrimaryTouchPosition = true;
|
|
}
|
|
}
|
|
}
|
|
|
|
// Handle Virtual Keyboard Inputs
|
|
if (inputDeviceId == InputDeviceVirtualKeyboard::Id)
|
|
{
|
|
if (inputChannelId == AzFramework::InputDeviceVirtualKeyboard::Command::EditEnter)
|
|
{
|
|
// Simulate the enter key being pressed
|
|
io.KeysDown[GetAzKeyIndex(InputDeviceKeyboard::Key::EditEnter)] = true;
|
|
}
|
|
}
|
|
|
|
if (m_clientMenuBarState == DisplayState::Visible
|
|
|| m_editorWindowState == DisplayState::Visible)
|
|
{
|
|
// If we have the Discrete Input Mode Enabled.. then consume the input here.
|
|
if (m_enableDiscreteInputMode)
|
|
{
|
|
return true;
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
bool ImGuiManager::IsControllerSupportModeEnabled(ImGuiControllerModeFlags::FlagType controllerMode) const
|
|
{
|
|
return !!(m_controllerModeFlags & controllerMode);
|
|
}
|
|
|
|
void ImGuiManager::EnableControllerSupportMode(ImGuiControllerModeFlags::FlagType controllerMode, bool enable)
|
|
{
|
|
ImGui::ImGuiContextScope contextScope(m_imguiContext);
|
|
|
|
if (enable)
|
|
{
|
|
// Enable - Add flag by or'ing in.
|
|
m_controllerModeFlags |= controllerMode;
|
|
}
|
|
else
|
|
{
|
|
// Disable - Remove flag by and'ing the flag inverse
|
|
m_controllerModeFlags &= ~controllerMode;
|
|
}
|
|
|
|
const bool controllerMouseEnabled = IsControllerSupportModeEnabled(ImGuiControllerModeFlags::Mouse);
|
|
|
|
// Draw the ImGui Mouse cursor if either the hardware mouse is connected, or the controller mouse is enabled.
|
|
ImGui::GetIO().MouseDrawCursor = m_hardwardeMouseConnected || controllerMouseEnabled;
|
|
|
|
// Set or unset ImGui Config flags based on which modes are enabled.
|
|
if (controllerMouseEnabled)
|
|
{
|
|
ImGui::GetIO().ConfigFlags &= ~ImGuiConfigFlags_NavEnableGamepad;
|
|
ImGui::GetIO().ConfigFlags &= ~ImGuiConfigFlags_NavEnableKeyboard;
|
|
}
|
|
else if (IsControllerSupportModeEnabled(ImGuiControllerModeFlags::Contextual))
|
|
{
|
|
ImGui::GetIO().ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad;
|
|
ImGui::GetIO().ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard;
|
|
}
|
|
}
|
|
|
|
bool ImGuiManager::OnInputTextEventFiltered(const AZStd::string& textUTF8)
|
|
{
|
|
ImGui::ImGuiContextScope contextScope(m_imguiContext);
|
|
|
|
ImGuiIO& io = ImGui::GetIO();
|
|
io.AddInputCharactersUTF8(textUTF8.c_str());
|
|
|
|
if (textUTF8 == "\b" && !io.KeysDown[GetAzKeyIndex(InputDeviceKeyboard::Key::EditBackspace)])
|
|
{
|
|
// Simulate the backspace key being pressed
|
|
io.KeysDown[GetAzKeyIndex(InputDeviceKeyboard::Key::EditBackspace)] = true;
|
|
m_simulateBackspaceKeyPressed = true;
|
|
}
|
|
|
|
return io.WantTextInput && m_clientMenuBarState == DisplayState::Visible;;
|
|
}
|
|
|
|
void ImGuiManager::ToggleThroughImGuiVisibleState(int controllerIndex)
|
|
{
|
|
ImGui::ImGuiContextScope contextScope(m_imguiContext);
|
|
|
|
switch (m_clientMenuBarState)
|
|
{
|
|
case DisplayState::Hidden:
|
|
m_currentControllerIndex = controllerIndex;
|
|
m_clientMenuBarState = DisplayState::Visible;
|
|
|
|
// Draw the ImGui Mouse cursor if either the hardware mouse is connected, or the controller mouse is enabled.
|
|
ImGui::GetIO().MouseDrawCursor = m_hardwardeMouseConnected || IsControllerSupportModeEnabled(ImGuiControllerModeFlags::Mouse);
|
|
|
|
// Disable system cursor if it's in editor and it's not editor game mode
|
|
if (gEnv->IsEditor() && !gEnv->IsEditorGameMode())
|
|
{
|
|
// Constrain and hide the system cursor
|
|
AzFramework::InputSystemCursorRequestBus::Event(
|
|
AzFramework::InputDeviceMouse::Id, &AzFramework::InputSystemCursorRequests::SetSystemCursorState,
|
|
AzFramework::SystemCursorState::ConstrainedAndHidden);
|
|
|
|
// Disable discrete input mode
|
|
m_enableDiscreteInputMode = false;
|
|
}
|
|
|
|
// get window size if it wasn't initialized
|
|
InitWindowSize();
|
|
break;
|
|
|
|
case DisplayState::Visible:
|
|
m_clientMenuBarState = DisplayState::VisibleNoMouse;
|
|
ImGui::GetIO().MouseDrawCursor = false;
|
|
|
|
if (m_enableDiscreteInputMode)
|
|
{
|
|
// if we ARE Enabling the Discrete Input Mode, then we want to bail here, if not, we want to just fall below to the default case.
|
|
// no worries on setting m_clientMenuBarState twice..
|
|
break;
|
|
}
|
|
|
|
default:
|
|
m_clientMenuBarState = DisplayState::Hidden;
|
|
m_currentControllerIndex = -1;
|
|
|
|
// Enable system cursor if it's in editor and it's not editor game mode
|
|
if (gEnv->IsEditor() && !gEnv->IsEditorGameMode())
|
|
{
|
|
// unconstrain and show the system cursor
|
|
AzFramework::InputSystemCursorRequestBus::Event(
|
|
AzFramework::InputDeviceMouse::Id, &AzFramework::InputSystemCursorRequests::SetSystemCursorState,
|
|
AzFramework::SystemCursorState::UnconstrainedAndVisible);
|
|
}
|
|
break;
|
|
}
|
|
|
|
m_menuBarStatusChanged = true;
|
|
m_setEnabledEvent.Signal(m_clientMenuBarState == DisplayState::Hidden);
|
|
}
|
|
|
|
void ImGuiManager::ToggleThroughImGuiVisibleState()
|
|
{
|
|
ToggleThroughImGuiVisibleState(-1);
|
|
}
|
|
|
|
|
|
void ImGuiManager::RenderImGuiBuffers(const ImVec2& scaleRects)
|
|
{
|
|
ImGui::ImGuiContextScope contextScope(m_imguiContext);
|
|
|
|
// Trigger all listeners to run their updates
|
|
EBUS_EVENT(ImGuiUpdateListenerBus, OnImGuiUpdate);
|
|
|
|
// Run imgui's internal render and retrieve resulting draw data
|
|
ImGui::Render();
|
|
ImDrawData* drawData = ImGui::GetDrawData();
|
|
if (!drawData)
|
|
{
|
|
return;
|
|
}
|
|
|
|
// Supply Scale Rects
|
|
drawData->ScaleClipRects(scaleRects);
|
|
|
|
//@rky: Only render the main ImGui if it is visible
|
|
if (m_clientMenuBarState != DisplayState::Hidden)
|
|
{
|
|
OtherActiveImGuiRequestBus::Broadcast(&OtherActiveImGuiRequestBus::Events::RenderImGuiBuffers, *drawData);
|
|
}
|
|
}
|
|
|
|
void ImGuiManager::OnWindowResized(uint32_t width, uint32_t height)
|
|
{
|
|
m_windowSize.m_width = width;
|
|
m_windowSize.m_height = height;
|
|
}
|
|
|
|
void ImGuiManager::InitWindowSize()
|
|
{
|
|
// We only need to initialize the window size by querying the window the first time.
|
|
// After that we will get OnWindowResize notifications
|
|
if (!m_overridingWindowSize && !AzFramework::WindowNotificationBus::Handler::BusIsConnected())
|
|
{
|
|
AzFramework::NativeWindowHandle windowHandle = nullptr;
|
|
AzFramework::WindowSystemRequestBus::BroadcastResult(windowHandle, &AzFramework::WindowSystemRequestBus::Events::GetDefaultWindowHandle);
|
|
|
|
if (windowHandle)
|
|
{
|
|
AzFramework::WindowRequestBus::EventResult(m_windowSize, windowHandle, &AzFramework::WindowRequestBus::Events::GetClientAreaSize);
|
|
AzFramework::WindowNotificationBus::Handler::BusConnect(windowHandle);
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
////// IMGUI CVAR STUFF /////////
|
|
|
|
namespace ImGuiCVARNames
|
|
{
|
|
static const char* s_imgui_AutoEnableComponents_Name = "imgui_AutoEnableComponents";
|
|
static const char* s_imgui_DiscreteInputMode_Name = "imgui_DiscreteInputMode";
|
|
static const char* s_imgui_EnableAssetExplorer_Name = "imgui_EnableAssetExplorer";
|
|
static const char* s_imgui_EnableCameraMonitor_Name = "imgui_EnableCameraMonitor";
|
|
static const char* s_imgui_EnableEntityOutliner_Name = "imgui_EnableEntityOutliner";
|
|
static const char* s_imgui_EnableImGui_Name = "imgui_EnableImGui";
|
|
static const char* s_imgui_EnableController_Name = "imgui_EnableController";
|
|
static const char* s_imgui_EnableControllerMouse_Name = "imgui_EnableControllerMouse";
|
|
static const char* s_imgui_ControllerMouseSensitivity_Name = "imgui_ControllerMouseSensitivity";
|
|
}
|
|
|
|
void OnAutoEnableComponentsCBFunc(ICVar* pArgs)
|
|
{
|
|
std::string token;
|
|
std::istringstream tokenStream(pArgs->GetString());
|
|
while (std::getline(tokenStream, token, ','))
|
|
{
|
|
AZStd::string enableSearchString = token.c_str();
|
|
ImGui::ImGuiEntityOutlinerRequestBus::Broadcast(&ImGui::IImGuiEntityOutlinerRequests::AddAutoEnableSearchString, enableSearchString);
|
|
}
|
|
}
|
|
|
|
void OnEnableEntityOutlinerCBFunc(ICVar* pArgs)
|
|
{
|
|
ImGui::ImGuiEntityOutlinerRequestBus::Broadcast(&ImGui::IImGuiEntityOutlinerRequests::SetEnabled, pArgs->GetIVal() != 0);
|
|
}
|
|
|
|
void OnEnableAssetExplorerCBFunc(ICVar* pArgs)
|
|
{
|
|
ImGui::ImGuiAssetExplorerRequestBus::Broadcast(&ImGui::IImGuiAssetExplorerRequests::SetEnabled, pArgs->GetIVal() != 0);
|
|
}
|
|
|
|
void OnEnableCameraMonitorCBFunc(ICVar* pArgs)
|
|
{
|
|
ImGui::ImGuiCameraMonitorRequestBus::Broadcast(&ImGui::IImGuiCameraMonitorRequests::SetEnabled, pArgs->GetIVal() != 0);
|
|
}
|
|
|
|
void OnShowImGuiCBFunc(ICVar* pArgs)
|
|
{
|
|
ImGui::ImGuiManagerBus::Broadcast(&ImGui::IImGuiManager::SetClientMenuBarState, pArgs->GetIVal() != 0 ? ImGui::DisplayState::Visible : ImGui::DisplayState::Hidden);
|
|
}
|
|
|
|
void OnDiscreteInputModeCBFunc(ICVar* pArgs)
|
|
{
|
|
ImGui::ImGuiManagerBus::Broadcast(&ImGui::IImGuiManager::SetEnableDiscreteInputMode, pArgs->GetIVal() != 0 );
|
|
}
|
|
|
|
void OnEnableControllerCBFunc(ICVar* pArgs)
|
|
{
|
|
ImGui::ImGuiManagerBus::Broadcast(&ImGui::IImGuiManager::EnableControllerSupportMode, ImGuiControllerModeFlags::Contextual, (pArgs->GetIVal() != 0));
|
|
}
|
|
|
|
void OnEnableControllerMouseCBFunc(ICVar* pArgs)
|
|
{
|
|
ImGui::ImGuiManagerBus::Broadcast(&ImGui::IImGuiManager::EnableControllerSupportMode, ImGuiControllerModeFlags::Mouse, (pArgs->GetIVal() != 0));
|
|
}
|
|
|
|
void OnControllerMouseSensitivityCBFunc(ICVar* pArgs)
|
|
{
|
|
ImGui::ImGuiManagerBus::Broadcast(&ImGui::IImGuiManager::SetControllerMouseSensitivity, pArgs->GetFVal());
|
|
}
|
|
|
|
|
|
void ImGuiManager::RegisterImGuiCVARs()
|
|
{
|
|
// These are already checked before we enter this function, but lets make double sure and prevent crashes.
|
|
if (!gEnv || !gEnv->pConsole)
|
|
{
|
|
return;
|
|
}
|
|
|
|
// We should also just make sure we aren't registering these twice. Check by just checking the first one.
|
|
if (gEnv->pConsole->GetCVar(ImGuiCVARNames::s_imgui_EnableImGui_Name) != nullptr)
|
|
{
|
|
return;
|
|
}
|
|
|
|
// Register CVARs
|
|
gEnv->pConsole->RegisterString(ImGuiCVARNames::s_imgui_AutoEnableComponents_Name, 0, VF_DEV_ONLY, CVARHELP("Enable ImGui Components by search string, as they are added to the Scene. Comma delimited list."), OnAutoEnableComponentsCBFunc);
|
|
gEnv->pConsole->RegisterInt(ImGuiCVARNames::s_imgui_EnableImGui_Name, 0, VF_DEV_ONLY, CVARHELP("Enable ImGui on Startup"), OnShowImGuiCBFunc);
|
|
gEnv->pConsole->RegisterInt(ImGuiCVARNames::s_imgui_EnableEntityOutliner_Name, 0, VF_DEV_ONLY, CVARHELP("Enable ImGui Entity Outliner on Startup"), OnEnableEntityOutlinerCBFunc);
|
|
gEnv->pConsole->RegisterInt(ImGuiCVARNames::s_imgui_EnableCameraMonitor_Name, 0, VF_DEV_ONLY, CVARHELP("Enable ImGui Camera Monitor on Startup"), OnEnableCameraMonitorCBFunc);
|
|
gEnv->pConsole->RegisterInt(ImGuiCVARNames::s_imgui_EnableAssetExplorer_Name, 0, VF_DEV_ONLY, CVARHELP("Enable ImGui Asset Explorer on Startup"), OnEnableAssetExplorerCBFunc);
|
|
gEnv->pConsole->RegisterInt(ImGuiCVARNames::s_imgui_DiscreteInputMode_Name, 0, VF_DEV_ONLY, CVARHELP("Enable ImGui Discrete Input Mode, adds a 2nd Visibility Mode, with the 1st having input going toward ImGui and the 2nd having input going toward the game. If not set, Input will go to both ImGui and the game when ImGui is enabled."), OnDiscreteInputModeCBFunc);
|
|
// Enable the Contextual Controller support by default when the hardware mouse is not detected.
|
|
gEnv->pConsole->RegisterInt(ImGuiCVARNames::s_imgui_EnableController_Name, (m_hardwardeMouseConnected ? 0 : 1), VF_DEV_ONLY, CVARHELP("Enable ImGui Controller support. Default to Off on PC, On on Console."), OnEnableControllerCBFunc);
|
|
gEnv->pConsole->RegisterInt(ImGuiCVARNames::s_imgui_EnableControllerMouse_Name, 0, VF_DEV_ONLY, CVARHELP("Enable ImGui Controller Mouse support. Default to Off on PC, On on Console."), OnEnableControllerMouseCBFunc);
|
|
gEnv->pConsole->RegisterFloat(ImGuiCVARNames::s_imgui_ControllerMouseSensitivity_Name, 5.0f, VF_DEV_ONLY, CVARHELP("ImGui Controller Mouse Sensitivty. Frame Multiplier for stick mouse sensitivity"), OnControllerMouseSensitivityCBFunc);
|
|
|
|
// Init CVARs to current values
|
|
OnAutoEnableComponentsCBFunc(gEnv->pConsole->GetCVar(ImGuiCVARNames::s_imgui_AutoEnableComponents_Name));
|
|
OnShowImGuiCBFunc(gEnv->pConsole->GetCVar(ImGuiCVARNames::s_imgui_EnableImGui_Name));
|
|
OnEnableAssetExplorerCBFunc(gEnv->pConsole->GetCVar(ImGuiCVARNames::s_imgui_EnableAssetExplorer_Name));
|
|
OnEnableCameraMonitorCBFunc(gEnv->pConsole->GetCVar(ImGuiCVARNames::s_imgui_EnableCameraMonitor_Name));
|
|
OnEnableEntityOutlinerCBFunc(gEnv->pConsole->GetCVar(ImGuiCVARNames::s_imgui_EnableEntityOutliner_Name));
|
|
OnDiscreteInputModeCBFunc(gEnv->pConsole->GetCVar(ImGuiCVARNames::s_imgui_DiscreteInputMode_Name));
|
|
OnEnableControllerCBFunc(gEnv->pConsole->GetCVar(ImGuiCVARNames::s_imgui_EnableController_Name));
|
|
OnEnableControllerMouseCBFunc(gEnv->pConsole->GetCVar(ImGuiCVARNames::s_imgui_EnableControllerMouse_Name));
|
|
OnControllerMouseSensitivityCBFunc(gEnv->pConsole->GetCVar(ImGuiCVARNames::s_imgui_ControllerMouseSensitivity_Name));
|
|
}
|
|
////// IMGUI CVAR STUFF /////////
|
|
|
|
void AddMenuItemHelper(bool& control, const char* show, const char* hide)
|
|
{
|
|
if (control)
|
|
{
|
|
if (ImGui::MenuItem(hide))
|
|
{
|
|
control = false;
|
|
}
|
|
}
|
|
else if (ImGui::MenuItem(show))
|
|
{
|
|
control = true;
|
|
}
|
|
}
|
|
|
|
#endif // ~IMGUI_ENABLED
|