Start to implement input sharing (mouse not supported yet)

This commit is contained in:
Arnaud Jamin
2023-11-10 15:23:54 -05:00
parent 2babdf04c6
commit fca5b27fb9
15 changed files with 395 additions and 158 deletions
Binary file not shown.
@@ -136,8 +136,8 @@ void FCogEngineWindow_Selection::ToggleSelectionMode()
void FCogEngineWindow_Selection::ActivateSelectionMode()
{
bSelectionModeActive = true;
bImGuiHadInputBeforeEnteringSelectionMode = FCogImguiModule::Get().GetEnableInput();
FCogImguiModule::Get().SetEnableInput(true);
bIsInputEnabledBeforeEnteringSelectionMode = GetOwner()->GetImGuiWidget()->GetEnableInput();
GetOwner()->GetImGuiWidget()->SetEnableInput(true);
GetOwner()->SetHideAllWindows(true);
}
@@ -158,10 +158,7 @@ void FCogEngineWindow_Selection::DeactivateSelectionMode()
// When in selection mode we need imgui to have the input focus
// When leaving selection mode we want to leave it as is was before
//--------------------------------------------------------------------------------------------
if (bImGuiHadInputBeforeEnteringSelectionMode == false)
{
FCogImguiModule::Get().SetEnableInput(false);
}
GetOwner()->GetImGuiWidget()->SetEnableInput(bIsInputEnabledBeforeEnteringSelectionMode);
GetOwner()->SetHideAllWindows(false);
}
@@ -8,6 +8,7 @@
class IConsoleObject;
class UCogEngineConfig_Selection;
enum class ECogImGuiInputMode : uint8;
//--------------------------------------------------------------------------------------------------------------------------
class COGENGINE_API FCogEngineWindow_Selection : public FCogWindow
@@ -82,7 +83,7 @@ protected:
bool bSelectionModeActive = false;
bool bImGuiHadInputBeforeEnteringSelectionMode = false;
bool bIsInputEnabledBeforeEnteringSelectionMode;
int32 WaitInputReleased = 0;
@@ -47,22 +47,6 @@ UPlayerInput* FCogImguiInputHelper::GetPlayerInput(const UWorld& World)
//--------------------------------------------------------------------------------------------------------------------------
bool FCogImguiInputHelper::IsKeyEventHandled(UWorld* World, const FKeyEvent& KeyEvent)
{
//------------------------------------------------------------------------------------------------
// Do not handle the input if imgui input is disabled
//------------------------------------------------------------------------------------------------
if (FCogImguiModule::Get().GetEnableInput() == false)
{
return false;
}
//------------------------------------------------------------------------------------------------
// We want the user to control the character with its gamepad even when imgui has the input.
//------------------------------------------------------------------------------------------------
if (KeyEvent.GetKey().IsGamepadKey())
{
return false;
}
//------------------------------------------------------------------------------------------------
// We want the user to be able to open the console command when imgui has the input.
//------------------------------------------------------------------------------------------------
@@ -30,10 +30,7 @@ void SCogImguiWidget::Construct(const FArguments& InArgs)
FontAtlas = InArgs._FontAtlas;
Render = InArgs._Render;
if (FCogImguiModule::Get().GetEnableInput() == false)
{
SetVisibility(EVisibility::SelfHitTestInvisible);
}
RefreshVisibility();
ImGuiContext = ImGui::CreateContext(FontAtlas);
ImPlotContext = ImPlot::CreateContext();
@@ -139,23 +136,7 @@ void SCogImguiWidget::TickImGui(float InDeltaTime)
//--------------------------------------------------------------------------------------------------------------------------
void SCogImguiWidget::TickFocus()
{
FCogImguiModule& Module = FCogImguiModule::Get();
const bool bShouldEnableInput = Module.GetEnableInput();
if (bEnableInput != bShouldEnableInput)
{
bEnableInput = bShouldEnableInput;
if (bEnableInput)
{
TakeFocus();
}
else
{
ReturnFocus();
}
}
else if (bEnableInput)
if (bEnableInput)
{
const auto& ViewportWidget = GameViewport->GetGameViewportWidget();
if (!HasKeyboardFocus() && !IsConsoleOpened() && (ViewportWidget->HasKeyboardFocus() || ViewportWidget->HasFocusedDescendants()))
@@ -168,8 +149,6 @@ void SCogImguiWidget::TickFocus()
//--------------------------------------------------------------------------------------------------------------------------
void SCogImguiWidget::TakeFocus()
{
SetVisibility(EVisibility::Visible);
FSlateApplication& SlateApplication = FSlateApplication::Get();
PreviousUserFocusedWidget = SlateApplication.GetUserFocusedWidget(SlateApplication.GetUserIndexForKeyboard());
@@ -189,8 +168,6 @@ void SCogImguiWidget::TakeFocus()
//--------------------------------------------------------------------------------------------------------------------------
void SCogImguiWidget::ReturnFocus()
{
SetVisibility(EVisibility::SelfHitTestInvisible);
if (HasKeyboardFocus())
{
auto FocusWidgetPtr = PreviousUserFocusedWidget.IsValid()
@@ -299,7 +276,6 @@ FVector2D SCogImguiWidget::TransformScreenPointToImGui(const FGeometry& MyGeomet
return ImGuiToScreen.Inverse().TransformPoint(Point);
}
//--------------------------------------------------------------------------------------------------------------------------
bool SCogImguiWidget::IsConsoleOpened() const
{
@@ -318,16 +294,50 @@ void SCogImguiWidget::SetAsCurrentContext()
ImGui::SetCurrentContext(ImGuiContext);
}
//--------------------------------------------------------------------------------------------------------------------------
void SCogImguiWidget::SetDPIScale(float Scale)
void SCogImguiWidget::SetEnableInput(bool Value)
{
if (DpiScale == Scale)
if (bEnableInput == Value)
{
return;
}
DpiScale = Scale;
bEnableInput = Value;
if (bEnableInput)
{
TakeFocus();
}
else
{
ReturnFocus();
}
RefreshVisibility();
}
//--------------------------------------------------------------------------------------------------------------------------
void SCogImguiWidget::RefreshVisibility()
{
if (bEnableInput)
{
SetVisibility(EVisibility::Visible);
}
else
{
SetVisibility(EVisibility::SelfHitTestInvisible);
}
}
//--------------------------------------------------------------------------------------------------------------------------
void SCogImguiWidget::SetDPIScale(float Value)
{
if (DpiScale == Value)
{
return;
}
DpiScale = Value;
OnDpiChanged();
}
@@ -360,101 +370,141 @@ void SCogImguiWidget::OnDpiChanged()
//--------------------------------------------------------------------------------------------------------------------------
FReply SCogImguiWidget::OnKeyChar(const FGeometry& MyGeometry, const FCharacterEvent& CharacterEvent)
{
if (FCogImguiModule::Get().GetEnableInput())
if (bEnableInput == false)
{
ImGui::GetIO().AddInputCharacter(FCogImguiInputHelper::CastInputChar(CharacterEvent.GetCharacter()));
return FReply::Handled();
}
return FReply::Unhandled();
if (bShareKeyboard)
{
return FReply::Unhandled();
}
return FReply::Handled();
}
//--------------------------------------------------------------------------------------------------------------------------
FReply SCogImguiWidget::OnKeyDown(const FGeometry& MyGeometry, const FKeyEvent& KeyEvent)
{
if (FCogImguiInputHelper::IsKeyEventHandled(GameViewport->GetWorld(), KeyEvent) == false)
{
return FReply::Unhandled();
}
ImGuiIO& IO = ImGui::GetIO();
IO.AddKeyEvent(FCogImguiInputHelper::KeyEventToImGuiKey(KeyEvent), true);
IO.AddKeyEvent(ImGuiMod_Ctrl, KeyEvent.IsControlDown());
IO.AddKeyEvent(ImGuiMod_Shift, KeyEvent.IsShiftDown());
IO.AddKeyEvent(ImGuiMod_Alt, KeyEvent.IsAltDown());
IO.AddKeyEvent(ImGuiMod_Super, KeyEvent.IsCommandDown());
return FReply::Handled();
return HandleKeyEvent(MyGeometry, KeyEvent);
}
//--------------------------------------------------------------------------------------------------------------------------
FReply SCogImguiWidget::OnKeyUp(const FGeometry& MyGeometry, const FKeyEvent& KeyEvent)
{
if (FCogImguiInputHelper::IsKeyEventHandled(GameViewport->GetWorld(), KeyEvent) == false)
return HandleKeyEvent(MyGeometry, KeyEvent);
}
//--------------------------------------------------------------------------------------------------------------------------
FReply SCogImguiWidget::HandleKeyEvent(const FGeometry& MyGeometry, const FKeyEvent& KeyEvent)
{
if (bEnableInput == false)
{
return FReply::Unhandled();
}
ImGuiIO& IO = ImGui::GetIO();
IO.AddKeyEvent(FCogImguiInputHelper::KeyEventToImGuiKey(KeyEvent), false);
IO.AddKeyEvent(ImGuiMod_Ctrl, KeyEvent.IsControlDown());
IO.AddKeyEvent(ImGuiMod_Shift, KeyEvent.IsShiftDown());
IO.AddKeyEvent(ImGuiMod_Alt, KeyEvent.IsAltDown());
IO.AddKeyEvent(ImGuiMod_Super, KeyEvent.IsCommandDown());
if (KeyEvent.GetKey().IsGamepadKey())
{
if (bShareGamepad)
{
// TODO: handle imgui gamepad
return FReply::Unhandled();
}
}
else
{
if (FCogImguiInputHelper::IsKeyEventHandled(GameViewport->GetWorld(), KeyEvent) == false)
{
return FReply::Unhandled();
}
ImGuiIO& IO = ImGui::GetIO();
IO.AddKeyEvent(FCogImguiInputHelper::KeyEventToImGuiKey(KeyEvent), false);
IO.AddKeyEvent(ImGuiMod_Ctrl, KeyEvent.IsControlDown());
IO.AddKeyEvent(ImGuiMod_Shift, KeyEvent.IsShiftDown());
IO.AddKeyEvent(ImGuiMod_Alt, KeyEvent.IsAltDown());
IO.AddKeyEvent(ImGuiMod_Super, KeyEvent.IsCommandDown());
if (bShareKeyboard)
{
return FReply::Unhandled();
}
}
return FReply::Handled();
}
//--------------------------------------------------------------------------------------------------------------------------
FReply SCogImguiWidget::OnAnalogValueChanged(const FGeometry& MyGeometry, const FAnalogInputEvent& AnalogInputEvent)
{
if (AnalogInputEvent.GetKey().IsGamepadKey())
{
if (bShareGamepad)
{
// TODO: handle imgui gamepad
return FReply::Unhandled();
}
}
else
{
if (bShareKeyboard)
{
return FReply::Unhandled();
}
}
return FReply::Handled();
}
//--------------------------------------------------------------------------------------------------------------------------
FReply SCogImguiWidget::OnAnalogValueChanged(const FGeometry& MyGeometry, const FAnalogInputEvent& AnalogInputEvent)
{
return FReply::Unhandled();
}
//--------------------------------------------------------------------------------------------------------------------------
FReply SCogImguiWidget::OnMouseButtonDown(const FGeometry& MyGeometry, const FPointerEvent& MouseEvent)
{
if (FCogImguiModule::Get().GetEnableInput() == false)
if (bEnableInput == false)
{
return FReply::Unhandled();
}
const uint32 MouseButton = FCogImguiInputHelper::MouseButtonToImGuiMouseButton(MouseEvent.GetEffectingButton());
ImGui::GetIO().AddMouseSourceEvent(ImGuiMouseSource_Mouse);
ImGui::GetIO().AddMouseButtonEvent(FCogImguiInputHelper::MouseButtonToImGuiMouseButton(MouseEvent.GetEffectingButton()), true);
ImGui::GetIO().AddMouseButtonEvent(MouseButton, true);
return FReply::Handled();
}
//--------------------------------------------------------------------------------------------------------------------------
FReply SCogImguiWidget::OnMouseButtonUp(const FGeometry& MyGeometry, const FPointerEvent& MouseEvent)
{
if (FCogImguiModule::Get().GetEnableInput() == false)
if (bEnableInput == false)
{
return FReply::Unhandled();
}
const uint32 MouseButton = FCogImguiInputHelper::MouseButtonToImGuiMouseButton(MouseEvent.GetEffectingButton());
ImGui::GetIO().AddMouseSourceEvent(ImGuiMouseSource_Mouse);
ImGui::GetIO().AddMouseButtonEvent(FCogImguiInputHelper::MouseButtonToImGuiMouseButton(MouseEvent.GetEffectingButton()), false);
ImGui::GetIO().AddMouseButtonEvent(MouseButton, false);
return FReply::Handled();
}
//--------------------------------------------------------------------------------------------------------------------------
FReply SCogImguiWidget::OnMouseWheel(const FGeometry& MyGeometry, const FPointerEvent& MouseEvent)
{
if (FCogImguiModule::Get().GetEnableInput() == false)
if (bEnableInput == false)
{
return FReply::Unhandled();
}
ImGui::GetIO().AddMouseSourceEvent(ImGuiMouseSource_Mouse);
ImGui::GetIO().AddMouseWheelEvent(0, MouseEvent.GetWheelDelta());
return FReply::Handled();
}
//--------------------------------------------------------------------------------------------------------------------------
FReply SCogImguiWidget::OnMouseMove(const FGeometry& MyGeometry, const FPointerEvent& MouseEvent)
{
if (FCogImguiModule::Get().GetEnableInput() == false)
if (bEnableInput == false)
{
return FReply::Unhandled();
}
@@ -462,13 +512,14 @@ FReply SCogImguiWidget::OnMouseMove(const FGeometry& MyGeometry, const FPointerE
ImGui::GetIO().AddMouseSourceEvent(ImGuiMouseSource_Mouse);
const FVector2D Pos = TransformScreenPointToImGui(MyGeometry, MouseEvent.GetScreenSpacePosition());
ImGui::GetIO().AddMousePosEvent(Pos.X, Pos.Y);
return FReply::Handled();
}
//--------------------------------------------------------------------------------------------------------------------------
FReply SCogImguiWidget::OnFocusReceived(const FGeometry& MyGeometry, const FFocusEvent& FocusEvent)
{
if (FCogImguiModule::Get().GetEnableInput() == false)
if (bEnableInput == false)
{
return FReply::Unhandled();
}
@@ -31,12 +31,6 @@ public:
ImFontAtlas& GetDefaultFontAtlas() { return DefaultFontAtlas; }
bool GetEnableInput() const { return bEnabledInput; }
void SetEnableInput(bool Value) { bEnabledInput = Value; }
void ToggleEnableInput() { bEnabledInput = !bEnabledInput; }
private:
void Initialize();
@@ -45,7 +39,5 @@ private:
ImFontAtlas DefaultFontAtlas;
bool bEnabledInput = true;
bool bIsInitialized = false;
};
@@ -15,6 +15,15 @@ struct ImPlotContext;
using FCogImguiRenderFunction = TFunction<void(float DeltaTime)>;
//--------------------------------------------------------------------------------------------------------------------------
UENUM()
enum class ECogImGuiInputMode : uint8
{
Inactive,
Exclusive,
Shared
};
//--------------------------------------------------------------------------------------------------------------------------
class COGIMGUI_API SCogImguiWidget : public SCompoundWidget
{
@@ -36,30 +45,64 @@ public:
// SWidget overrides
//----------------------------------------------------------------------------------------------------
virtual void Tick(const FGeometry& AllottedGeometry, const double InCurrentTime, const float InDeltaTime) override;
virtual bool SupportsKeyboardFocus() const override { return true; }
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 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;
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 Scale) const override;
ULocalPlayer* GetLocalPlayer() const;
bool GetEnableInput() const { return bEnableInput; }
void SetEnableInput(bool Value);
bool GetShareGamepad() const { return bShareGamepad; }
void SetShareGamepad(bool Value) { bShareGamepad = Value; }
bool GetShareKeyboard() const { return bShareKeyboard; }
void SetShareKeyboard(bool Value) { bShareKeyboard= Value; }
bool GetShareMouse() const { return bShareMouse; }
void SetShareMouse(bool Value) { bShareMouse = Value; }
float GetDpiScale() const { return DpiScale; }
void SetDPIScale(float Scale);
void SetDPIScale(float Value);
bool IsCurrentContext() const;
@@ -85,16 +128,26 @@ protected:
virtual void OnDpiChanged();
bool IsConsoleOpened() const;
virtual void RefreshVisibility();
virtual bool IsConsoleOpened() const;
virtual FReply HandleKeyEvent(const FGeometry& MyGeometry, const FKeyEvent& KeyEvent);
TWeakObjectPtr<UGameViewportClient> GameViewport;
ImFontAtlas* FontAtlas;
ImFontAtlas* FontAtlas = nullptr;
TWeakPtr<SWidget> PreviousUserFocusedWidget;
bool bEnableInput = false;
bool bShareGamepad = true;
bool bShareKeyboard = false;
bool bShareMouse = false;
FSlateRenderTransform ImGuiRenderTransform;
mutable TArray<FSlateVertex> VertexBuffer;
@@ -3,7 +3,7 @@
#include "CogDebugDrawImGui.h"
#include "CogImguiInputHelper.h"
#include "CogImguiModule.h"
#include "CogImguiWidget.h"
#include "CogWindow_Inputs.h"
#include "CogWindow_Settings.h"
#include "CogWindow_Spacing.h"
#include "CogWindowConfig.h"
@@ -41,6 +41,10 @@ void UCogWindowManager::PostInitProperties()
void UCogWindowManager::InitializeInternal()
{
ImGuiWidget = FCogImguiModule::Get().CreateImGuiWidget(GEngine->GameViewport, [this](float DeltaTime) { Render(DeltaTime); });
ImGuiWidget->SetEnableInput(bEnableInput);
ImGuiWidget->SetShareGamepad(bShareGamepad);
ImGuiWidget->SetShareKeyboard(bShareKeyboard);
ImGuiWidget->SetShareMouse(bShareMouse);
ImGuiSettingsHandler IniHandler;
IniHandler.TypeName = "Cog";
@@ -58,12 +62,14 @@ void UCogWindowManager::InitializeInternal()
SpaceWindows.Add(AddWindow<FCogWindow_Spacing>("Spacing 3", false));
SpaceWindows.Add(AddWindow<FCogWindow_Spacing>("Spacing 4", false));
InputsWindow = AddWindow<FCogWindow_Inputs>("Window.Inputs", false);
SettingsWindow = AddWindow<FCogWindow_Settings>("Window.Settings", false);
ConsoleCommands.Add(IConsoleManager::Get().RegisterConsoleCommand(
*ToggleInputCommand,
TEXT("Toggle the input focus between the Game and ImGui"),
FConsoleCommandWithArgsDelegate::CreateLambda([](const TArray<FString>& Args) { FCogImguiModule::Get().ToggleEnableInput(); }),
FConsoleCommandWithArgsDelegate::CreateLambda([this](const TArray<FString>& Args) { ToggleInputMode(); }),
ECVF_Cheat));
ConsoleCommands.Add(IConsoleManager::Get().RegisterConsoleCommand(
@@ -89,6 +95,14 @@ void UCogWindowManager::InitializeInternal()
//--------------------------------------------------------------------------------------------------------------------------
void UCogWindowManager::Shutdown()
{
//------------------------------------------------------------
// To save the input mode for the next session
//------------------------------------------------------------
bEnableInput = ImGuiWidget->GetEnableInput();
bShareGamepad = ImGuiWidget->GetEnableInput();
bShareKeyboard = ImGuiWidget->GetEnableInput();
bShareMouse = ImGuiWidget->GetEnableInput();
//------------------------------------------------------------
// Destroy ImGui before destroying the windows to make sure
// imgui serialize their visibility state in imgui.ini
@@ -165,7 +179,7 @@ void UCogWindowManager::Render(float DeltaTime)
if (bHideAllWindows == false)
{
if (FCogImguiModule::Get().GetEnableInput())
if (ImGuiWidget->GetEnableInput() || bHideMainMenuOnGameInput == false)
{
RenderMainMenu();
}
@@ -335,13 +349,6 @@ void UCogWindowManager::RenderMainMenu()
if (ImGui::BeginMenu("Window"))
{
if (ImGui::MenuItem("Toggle Input", TCHAR_TO_ANSI(*FCogImguiInputHelper::CommandToString(PlayerInput, ToggleInputCommand))))
{
FCogImguiModule::Get().ToggleEnableInput();
}
ImGui::Separator();
if (ImGui::MenuItem("Close All Windows"))
{
CloseAllWindows();
@@ -425,7 +432,7 @@ void UCogWindowManager::RenderMainMenu()
ImGui::EndMenu();
}
ImGui::Separator();
RenderMenuItem(*InputsWindow, "Inputs");
RenderMenuItem(*SettingsWindow, "Settings");
@@ -823,4 +830,10 @@ const UObject* UCogWindowManager::GetAsset(const TSubclassOf<UObject> AssetClass
Assets.Add(Asset);
return Asset;
}
//--------------------------------------------------------------------------------------------------------------------------
void UCogWindowManager::ToggleInputMode()
{
ImGuiWidget->SetEnableInput(!ImGuiWidget->GetEnableInput());
}
@@ -73,8 +73,9 @@ void FCogWindowWidgets::ProgressBarCentered(float Fraction, const ImVec2& Size,
}
//--------------------------------------------------------------------------------------------------------------------------
void FCogWindowWidgets::ToggleMenuButton(bool* Value, const char* Text, const ImVec4& TrueColor)
bool FCogWindowWidgets::ToggleMenuButton(bool* Value, const char* Text, const ImVec4& TrueColor)
{
bool IsPressed = false;
bool IsTrue = *Value;
if (IsTrue)
{
@@ -87,7 +88,8 @@ void FCogWindowWidgets::ToggleMenuButton(bool* Value, const char* Text, const Im
ImGui::PushStyleColor(ImGuiCol_Button, ImVec4(0, 0, 0, 0));
}
if (ImGui::Button(Text))
IsPressed = ImGui::Button(Text);
if (IsPressed)
{
*Value = !*Value;
}
@@ -101,24 +103,27 @@ void FCogWindowWidgets::ToggleMenuButton(bool* Value, const char* Text, const Im
ImGui::PopStyleColor(1);
}
return IsPressed;
}
//--------------------------------------------------------------------------------------------------------------------------
void FCogWindowWidgets::ToggleButton(bool* Value, const char* Text, const ImVec4& TrueColor, const ImVec4& FalseColor, const ImVec2& Size)
bool FCogWindowWidgets::ToggleButton(bool* Value, const char* Text, const ImVec4& TrueColor, const ImVec4& FalseColor, const ImVec2& Size)
{
ToggleButton(Value, Text, Text, TrueColor, FalseColor, Size);
return ToggleButton(Value, Text, Text, TrueColor, FalseColor, Size);
}
//--------------------------------------------------------------------------------------------------------------------------
void FCogWindowWidgets::ToggleButton(bool* Value, const char* TextTrue, const char* TextFalse, const ImVec4& TrueColor, const ImVec4& FalseColor, const ImVec2& Size)
bool FCogWindowWidgets::ToggleButton(bool* Value, const char* TextTrue, const char* TextFalse, const ImVec4& TrueColor, const ImVec4& FalseColor, const ImVec2& Size)
{
bool IsPressed = false;
if (*Value)
{
ImGui::PushStyleColor(ImGuiCol_Button, ImVec4(TrueColor.x, TrueColor.y, TrueColor.z, TrueColor.w * 0.6f));
ImGui::PushStyleColor(ImGuiCol_ButtonHovered, ImVec4(TrueColor.x, TrueColor.y, TrueColor.z, TrueColor.w * 0.8f));
ImGui::PushStyleColor(ImGuiCol_ButtonActive, ImVec4(TrueColor.x, TrueColor.y, TrueColor.z, TrueColor.w * 1.0f));
if (ImGui::Button(TextTrue, Size))
IsPressed = ImGui::Button(TextTrue, Size);
if (IsPressed)
{
*Value = false;
}
@@ -138,6 +143,8 @@ void FCogWindowWidgets::ToggleButton(bool* Value, const char* TextTrue, const ch
ImGui::PopStyleColor(3);
}
return IsPressed;
}
//--------------------------------------------------------------------------------------------------------------------------
@@ -0,0 +1,73 @@
#include "CogWindow_Inputs.h"
#include "CogImguiInputHelper.h"
#include "CogImguiWidget.h"
#include "CogWindowManager.h"
#include "CogWindowWidgets.h"
#include "InputCoreTypes.h"
#include "imgui.h"
//--------------------------------------------------------------------------------------------------------------------------
void FCogWindow_Inputs::Initialize()
{
Super::Initialize();
bHasMenu = false;
}
//--------------------------------------------------------------------------------------------------------------------------
void FCogWindow_Inputs::RenderContent()
{
const UPlayerInput* PlayerInput = FCogImguiInputHelper::GetPlayerInput(*GetWorld());
if (PlayerInput == nullptr)
{
return;
}
SCogImguiWidget* ImGuiWidget = GetOwner()->GetImGuiWidget().Get();
if (ImGuiWidget == nullptr)
{
return;
}
bool bEnableInput = ImGuiWidget->GetEnableInput();
if (ImGui::Checkbox("Enable Input", &bEnableInput))
{
ImGuiWidget->SetEnableInput(bEnableInput);
}
const char* ShortcutText = TCHAR_TO_ANSI(*FCogImguiInputHelper::CommandToString(PlayerInput, UCogWindowManager::ToggleInputCommand));
const float ShortcutWidth = (ShortcutText && ShortcutText[0]) ? ImGui::CalcTextSize(ShortcutText, NULL).x : 0.0f;
if (ShortcutWidth > 0.0f)
{
ImGui::SameLine();
ImGui::SetCursorPosX(ImGui::GetWindowContentRegionMax().x - ShortcutWidth);
ImGui::PushStyleColor(ImGuiCol_Text, ImGui::GetStyle().Colors[ImGuiCol_TextDisabled]);
ImGui::Text(ShortcutText);
ImGui::PopStyleColor();
}
ImGui::Separator();
bool bShareGamepad = ImGuiWidget->GetShareGamepad();
if (ImGui::Checkbox("Share Gamepad", &bShareGamepad))
{
ImGuiWidget->SetShareGamepad(bShareGamepad);
}
bool bShareKeyboard = ImGuiWidget->GetShareKeyboard();
if (ImGui::Checkbox("Share Keyboard", &bShareKeyboard))
{
ImGuiWidget->SetShareKeyboard(bShareKeyboard);
}
bool bShareMouse = ImGuiWidget->GetShareMouse();
if (ImGui::Checkbox("Share Mouse", &bShareMouse))
{
//ImGuiWidget->SetShareMouse(bShareMouse);
}
if (ImGui::IsItemHovered())
{
ImGui::SetTooltip("Mouse sharing is currently not supported");
}
}
@@ -33,7 +33,9 @@ void FCogWindow_Settings::RenderContent()
ImGui::Checkbox("Compact Mode", &GetOwner()->bCompactMode);
ImGui::Checkbox("Show Windows In Main Menu", &GetOwner()->bShowWindowsInMainMenu);
ImGui::Checkbox("Hide Main Menu On Game Input", &GetOwner()->bHideMainMenuOnGameInput);
ImGui::Checkbox("Show Window Help", &GetOwner()->bShowHelp);
ImGui::Separator();
@@ -1,13 +1,14 @@
#pragma once
#include "CoreMinimal.h"
#include "CogImguiWidget.h"
#include "imgui.h"
#include "CogWindowManager.generated.h"
class IConsoleObject;
class SCogImguiWidget;
class FCogWindow;
class FCogWindow_Settings;
class IConsoleObject;
class SCogImguiWidget;
class UCogWindowConfig;
class UPlayerInput;
class UWorld;
@@ -21,11 +22,6 @@ class COGWINDOW_API UCogWindowManager : public UObject
public:
static FString ToggleInputCommand;
static FString LoadLayoutCommand;
static FString SaveLayoutCommand;
static FString ResetLayoutCommand;
UCogWindowManager();
virtual void PostInitProperties() override;
@@ -40,6 +36,9 @@ public:
virtual void AddWindow(FCogWindow* Window, const FString& Name, bool AddToMainMenu = true);
template<class T>
T* AddWindow(const FString& Name, bool AddToMainMenu = true);
virtual FCogWindow* FindWindowByID(ImGuiID ID);
virtual void CloseAllWindows();
@@ -73,39 +72,27 @@ public:
virtual void ResetAllWindowsConfig();
virtual bool RegisterDefaultCommands();
UCogWindowConfig* GetConfig(const TSubclassOf<UCogWindowConfig> ConfigClass);
template<class T>
T* GetConfig();
const UObject* GetAsset(const TSubclassOf<UObject> AssetClass);
template<typename T>
T* GetAsset();
TSharedPtr<SCogImguiWidget> GetImGuiWidget() const { return ImGuiWidget; }
static void AddCommand(UPlayerInput* PlayerInput, const FString& Command, const FKey& Key);
static void SortCommands(UPlayerInput* PlayerInput);
UCogWindowConfig* GetConfig(const TSubclassOf<UCogWindowConfig> ConfigClass);
const UObject* GetAsset(const TSubclassOf<UObject> AssetClass);
template<class T>
T* AddWindow(const FString& Name, bool AddToMainMenu = true)
{
T* Window = new T();
AddWindow(Window, Name, AddToMainMenu);
return Window;
}
template<class T>
T* GetConfig()
{
static_assert(TPointerIsConvertibleFromTo<T, const UCogWindowConfig>::Value);
return Cast<T>(&GetConfig(T::StaticClass()));
}
template<typename T>
static T* GetAsset()
{
return Cast<T>(GetAsset(T::StaticClass()));
}
protected:
friend class FCogWindow_Settings;
friend class FCogWindow_Inputs;
struct FMenu
{
@@ -132,6 +119,8 @@ protected:
virtual void TickDPI();
virtual void ToggleInputMode();
static void SettingsHandler_ClearAll(ImGuiContext* ctx, ImGuiSettingsHandler*);
static void SettingsHandler_ApplyAll(ImGuiContext* ctx, ImGuiSettingsHandler*);
@@ -141,7 +130,14 @@ protected:
static void SettingsHandler_ReadLine(ImGuiContext*, ImGuiSettingsHandler*, void* entry, const char* line);
static void SettingsHandler_WriteAll(ImGuiContext* ctx, ImGuiSettingsHandler* handler, ImGuiTextBuffer* buf);
static FString ToggleInputCommand;
static FString LoadLayoutCommand;
static FString SaveLayoutCommand;
static FString ResetLayoutCommand;
UPROPERTY()
mutable TArray<UCogWindowConfig*> Configs;
@@ -149,6 +145,18 @@ protected:
UPROPERTY()
mutable TArray<const UObject*> Assets;
UPROPERTY(Config)
bool bEnableInput = false;
UPROPERTY(Config)
bool bShareGamepad = true;
UPROPERTY(Config)
bool bShareKeyboard = false;
UPROPERTY(Config)
bool bShareMouse = false;
UPROPERTY(Config)
bool bCompactMode = false;
@@ -167,6 +175,18 @@ protected:
UPROPERTY(Config)
bool bRegisterDefaultCommands = true;
UPROPERTY(Config)
bool bAuthorizeInactiveInput = true;
UPROPERTY(Config)
bool bAuthorizeExclusiveInput = true;
UPROPERTY(Config)
bool bAuthorizeSharedInput = true;
UPROPERTY(Config)
bool bHideMainMenuOnGameInput = true;
TSharedPtr<SCogImguiWidget> ImGuiWidget = nullptr;
TArray<FCogWindow*> Windows;
@@ -177,6 +197,8 @@ protected:
TArray<FCogWindow*> SpaceWindows;
FCogWindow_Inputs* InputsWindow = nullptr;
FCogWindow_Settings* SettingsWindow = nullptr;
FMenu MainMenu;
@@ -191,3 +213,27 @@ protected:
TArray<IConsoleObject*> ConsoleCommands;
};
//--------------------------------------------------------------------------------------------------------------------------
template<class T>
T* UCogWindowManager::AddWindow(const FString& Name, bool AddToMainMenu)
{
T* Window = new T();
AddWindow(Window, Name, AddToMainMenu);
return Window;
}
//--------------------------------------------------------------------------------------------------------------------------
template<class T>
T* UCogWindowManager::GetConfig()
{
static_assert(TPointerIsConvertibleFromTo<T, const UCogWindowConfig>::Value);
return Cast<T>(&GetConfig(T::StaticClass()));
}
//--------------------------------------------------------------------------------------------------------------------------
template<typename T>
T* UCogWindowManager::GetAsset()
{
return Cast<T>(GetAsset(T::StaticClass()));
}
@@ -18,11 +18,11 @@ public:
static void ProgressBarCentered(float Fraction, const ImVec2& Size, const char* Overlay);
static void ToggleMenuButton(bool* Value, const char* Text, const ImVec4& TrueColor);
static bool ToggleMenuButton(bool* Value, const char* Text, const ImVec4& TrueColor);
static void ToggleButton(bool* Value, const char* Text, const ImVec4& TrueColor, const ImVec4& FalseColor, const ImVec2& Size = ImVec2(0, 0));
static bool ToggleButton(bool* Value, const char* Text, const ImVec4& TrueColor, const ImVec4& FalseColor, const ImVec2& Size = ImVec2(0, 0));
static void ToggleButton(bool* Value, const char* TextTrue, const char* TextFalse, const ImVec4& TrueColor, const ImVec4& FalseColor, const ImVec2& Size = ImVec2(0, 0));
static bool ToggleButton(bool* Value, const char* TextTrue, const char* TextFalse, const ImVec4& TrueColor, const ImVec4& FalseColor, const ImVec2& Size = ImVec2(0, 0));
static bool MultiChoiceButton(const char* Label, bool IsSelected, const ImVec2& Size = ImVec2(0, 0));
@@ -0,0 +1,18 @@
#pragma once
#include "CoreMinimal.h"
#include "CogWindow.h"
#include "CogImGuiKeyInfo.h"
class COGWINDOW_API FCogWindow_Inputs : public FCogWindow
{
typedef FCogWindow Super;
public:
virtual void Initialize() override;
protected:
virtual void RenderContent() override;
};
@@ -130,18 +130,18 @@ void FCogInputWindow_Actions::RenderContent()
const ImVec4 ActiveColor(1, 0.8f, 0, 1);
const ImVec4 InnactiveColor(0.3f, 0.3f, 0.3f, 1);
const ImVec2 ButtonWidth(FCogWindowWidgets::GetFontWidth() * 10, 0);
const ImVec2 ButtonSize(FCogWindowWidgets::GetFontWidth() * 10, 0);
ImGui::TableNextColumn();
ImGui::BeginDisabled();
bool Value = ActionValue.Get<bool>();
FCogWindowWidgets::ToggleButton(&Value, "Pressed##Value", "Released##Value", ActiveColor, InnactiveColor, ButtonWidth);
FCogWindowWidgets::ToggleButton(&Value, "Pressed##Value", "Released##Value", ActiveColor, InnactiveColor, ButtonSize);
ImGui::EndDisabled();
ImGui::TableNextColumn();
FCogWindowWidgets::ToggleButton(&ActionInfo.bPressed, "Pressed##Inject", "Released##Inject", ActiveColor, InnactiveColor, ButtonWidth);
FCogWindowWidgets::ToggleButton(&ActionInfo.bPressed, "Pressed##Inject", "Released##Inject", ActiveColor, InnactiveColor, ButtonSize);
ImGui::SameLine();
FCogWindowWidgets::ToggleButton(&ActionInfo.bRepeat, "Repeat", "Repeat", ActiveColor, InnactiveColor, ButtonWidth);
FCogWindowWidgets::ToggleButton(&ActionInfo.bRepeat, "Repeat", "Repeat", ActiveColor, InnactiveColor, ButtonSize);
break;
}