window settings - imgui toggle input settings

This commit is contained in:
Arnaud Jamin
2023-10-11 14:34:18 -04:00
parent 18d82287aa
commit e90b097c1d
12 changed files with 310 additions and 77 deletions
@@ -85,16 +85,15 @@ bool FCogImguiInputHelper::WasKeyInfoJustPressed(APlayerController& PlayerContro
{
if (PlayerController.WasInputKeyJustPressed(KeyInfo.Key))
{
if (UPlayerInput* PlayerInput = PlayerController.PlayerInput.Get())
{
const bool MatchCtrl = IsCheckBoxStateMatchingValue(KeyInfo.Ctrl, PlayerInput->IsCtrlPressed());
const bool MatchAlt = IsCheckBoxStateMatchingValue(KeyInfo.Alt, PlayerInput->IsAltPressed());
const bool MatchShift = IsCheckBoxStateMatchingValue(KeyInfo.Shift, PlayerInput->IsShiftPressed());
const bool MatchCmd = IsCheckBoxStateMatchingValue(KeyInfo.Cmd, PlayerInput->IsCmdPressed());
const FModifierKeysState& ModifierKeys = FSlateApplication::Get().GetModifierKeys();
const bool Result = MatchCtrl && MatchAlt && MatchShift && MatchCmd;
return Result;
}
const bool MatchCtrl = IsCheckBoxStateMatchingValue(KeyInfo.Ctrl, ModifierKeys.IsControlDown());
const bool MatchAlt = IsCheckBoxStateMatchingValue(KeyInfo.Alt, ModifierKeys.IsAltDown());
const bool MatchShift = IsCheckBoxStateMatchingValue(KeyInfo.Shift, ModifierKeys.IsShiftDown());
const bool MatchCmd = IsCheckBoxStateMatchingValue(KeyInfo.Cmd, ModifierKeys.IsCommandDown());
const bool Result = MatchCtrl && MatchAlt && MatchShift && MatchCmd;
return Result;
}
return false;
@@ -5,7 +5,7 @@
#include "CogImGuiKeyInfo.generated.h"
USTRUCT()
struct FCogImGuiKeyInfo
struct COGIMGUI_API FCogImGuiKeyInfo
{
GENERATED_BODY()
@@ -31,6 +31,7 @@ public class CogWindow : ModuleRules
PrivateDependencyModuleNames.AddRange(
new string[]
{
"InputCore",
"CoreUObject",
"Engine",
"Slate",
@@ -116,31 +116,6 @@ void UCogWindow::GameTick(float DeltaTime)
{
}
//--------------------------------------------------------------------------------------------------------------------------
void UCogWindow::DrawMenuItem(const FString& MenuItemName)
{
if (bShowInsideMenu)
{
ImGui::SetNextWindowSizeConstraints(ImVec2(FCogWindowWidgets::GetFontWidth() * 40, ImGui::GetTextLineHeightWithSpacing() * 1),
ImVec2(FCogWindowWidgets::GetFontWidth() * 50, ImGui::GetTextLineHeightWithSpacing() * 60));
if (ImGui::BeginMenu(TCHAR_TO_ANSI(*MenuItemName)))
{
RenderContent();
ImGui::EndMenu();
}
if (ImGui::IsItemClicked(ImGuiMouseButton_Left))
{
bIsVisible = !bIsVisible;
}
}
else
{
ImGui::MenuItem(TCHAR_TO_ANSI(*MenuItemName), nullptr, &bIsVisible);
}
}
//--------------------------------------------------------------------------------------------------------------------------
void UCogWindow::SetSelection(AActor* NewSelection)
{
@@ -4,6 +4,7 @@
#include "CogImguiModule.h"
#include "CogImguiWidget.h"
#include "CogWindow_Spacing.h"
#include "CogWindow_Settings.h"
#include "CogWindowWidgets.h"
#include "Engine/Engine.h"
#include "imgui_internal.h"
@@ -33,6 +34,8 @@ void UCogWindowManager::InitializeInternal()
SpaceWindows.Add(CreateWindow<UCogWindow_Spacing>("Space 2", false));
SpaceWindows.Add(CreateWindow<UCogWindow_Spacing>("Space 3", false));
SpaceWindows.Add(CreateWindow<UCogWindow_Spacing>("Space 4", false));
SettingsWindow = CreateWindow<UCogWindow_Settings>("Window.Settings", false);
}
//--------------------------------------------------------------------------------------------------------------------------
@@ -314,36 +317,9 @@ void UCogWindowManager::DrawMainMenu()
ImGui::Separator();
ImGui::MenuItem("Compact Mode", nullptr, &bCompactMode);
ImGui::Text("DPI Scale");
ImGui::SameLine();
FCogWindowWidgets::PushStyleCompact();
FCogWindowWidgets::SetNextItemToShortWidth();
ImGui::SliderFloat("", &DPIScale, 0.5f, 2.0f, "%.2f");
if (ImGui::IsItemDeactivatedAfterEdit())
{
bRefreshDPIScale = true;
}
FCogWindowWidgets::PopStyleCompact();
if (ImGui::IsItemHovered())
{
ImGui::BeginTooltip();
ImGui::TextUnformatted("Change DPi Scale [Mouse Wheel]");
ImGui::TextUnformatted("Reset DPi Scale [Middle Mouse]");
ImGui::EndTooltip();
}
ImGui::Separator();
ImGui::MenuItem("Show Window Help", nullptr, &bShowHelp);
if (ImGui::IsItemHovered())
{
ImGui::BeginTooltip();
ImGui::TextUnformatted("Should some help be displayed when the mouse is over a window title ?");
ImGui::EndTooltip();
}
DrawMenuItem(*SettingsWindow, "Settings");
ImGui::EndMenu();
}
@@ -370,7 +346,7 @@ void UCogWindowManager::DrawMenu(UCogWindowManager::FMenu& Menu)
{
if (Menu.Window != nullptr)
{
Menu.Window->DrawMenuItem(Menu.Name);
DrawMenuItem(*Menu.Window, TCHAR_TO_ANSI(*Menu.Name));
}
else
{
@@ -385,6 +361,35 @@ void UCogWindowManager::DrawMenu(UCogWindowManager::FMenu& Menu)
}
}
//--------------------------------------------------------------------------------------------------------------------------
void UCogWindowManager::DrawMenuItem(UCogWindow& Window, const char* MenuItemName)
{
if (bShowWindowsInMainMenu)
{
ImGui::SetNextWindowSizeConstraints(ImVec2(FCogWindowWidgets::GetFontWidth() * 40, ImGui::GetTextLineHeightWithSpacing() * 1),
ImVec2(FCogWindowWidgets::GetFontWidth() * 50, ImGui::GetTextLineHeightWithSpacing() * 60));
if (ImGui::BeginMenu(MenuItemName))
{
Window.RenderContent();
ImGui::EndMenu();
}
if (ImGui::IsItemClicked(ImGuiMouseButton_Left))
{
Window.SetIsVisible(!Window.GetIsVisible());
}
}
else
{
bool bIsVisible = Window.GetIsVisible();
if (ImGui::MenuItem(MenuItemName, nullptr, &bIsVisible))
{
Window.SetIsVisible(bIsVisible);
}
}
}
//--------------------------------------------------------------------------------------------------------------------------
void UCogWindowManager::TickDPI()
{
@@ -392,15 +397,13 @@ void UCogWindowManager::TickDPI()
const bool IsControlDown = ImGui::GetIO().KeyCtrl;
if (IsControlDown && MouseWheel != 0)
{
DPIScale = FMath::Clamp(DPIScale + (MouseWheel > 0 ? 0.05f : -0.05f), 0.5f, 2.0f);
bRefreshDPIScale = true;
SetDPIScale(FMath::Clamp(DPIScale + (MouseWheel > 0 ? 0.1f : -0.1f), 0.5f, 2.0f));
}
const bool IsMiddleMouseClicked = ImGui::GetIO().MouseClicked[2];
if (IsControlDown && IsMiddleMouseClicked)
{
DPIScale = 1.0f;
bRefreshDPIScale = true;
SetDPIScale(1.0f);
}
}
@@ -456,4 +459,16 @@ void UCogWindowManager::SettingsHandler_WriteAll(ImGuiContext* Context, ImGuiSet
Buffer->appendf("0x%08X\n", Window->GetID());
}
}
}
}
//--------------------------------------------------------------------------------------------------------------------------
void UCogWindowManager::SetDPIScale(float Value)
{
if (DPIScale == Value)
{
return;
}
DPIScale = Value;
bRefreshDPIScale = true;
}
@@ -206,3 +206,72 @@ float FCogWindowWidgets::GetFontWidth()
return ImGui::GetFontSize() * 0.5f;
}
//--------------------------------------------------------------------------------------------------------------------------
bool FCogWindowWidgets::ComboboxEnum(const char* Label, UObject* Object, const char* FieldName, uint8* PointerToEnumValue)
{
const FEnumProperty* EnumProperty = CastField<FEnumProperty>(Object->GetClass()->FindPropertyByName(FName(FieldName)));
if (EnumProperty == nullptr)
{
return false;
}
return ComboboxEnum(Label, EnumProperty, PointerToEnumValue);
}
//--------------------------------------------------------------------------------------------------------------------------
bool FCogWindowWidgets::ComboboxEnum(const char* Label, const FEnumProperty* EnumProperty, uint8* PointerToValue)
{
bool HasChanged = false;
UEnum* Enum = EnumProperty->GetEnum();
int64 EnumValue = EnumProperty->GetUnderlyingProperty()->GetSignedIntPropertyValue(PointerToValue);
FString EnumValueName = Enum->GetNameStringByValue(EnumValue);
int64 NewValue;
if (ComboboxEnum(Label, Enum, EnumValue, NewValue))
{
EnumProperty->GetUnderlyingProperty()->SetIntPropertyValue(PointerToValue, NewValue);
}
return HasChanged;
}
//--------------------------------------------------------------------------------------------------------------------------
bool FCogWindowWidgets::ComboboxEnum(const char* Label, UEnum* Enum, int64 CurrentValue, int64& NewValue)
{
bool HasChanged = false;
FString CurrentEntryName = Enum->GetNameStringByValue(CurrentValue);
if (ImGui::BeginCombo(Label, TCHAR_TO_ANSI(*CurrentEntryName)))
{
for (int32 EnumIndex = 0; EnumIndex < Enum->NumEnums() - 1; ++EnumIndex)
{
#if WITH_EDITORONLY_DATA
bool bShouldBeHidden = Enum->HasMetaData(TEXT("Hidden"), EnumIndex) || Enum->HasMetaData(TEXT("Spacer"), EnumIndex);
if (bShouldBeHidden)
continue;
#endif //WITH_EDITORONLY_DATA
FString EnumEntryName = Enum->GetNameStringByIndex(EnumIndex);
int64 EnumEntryValue = Enum->GetValueByIndex(EnumIndex);
bool IsSelected = EnumEntryName == CurrentEntryName;
if (ImGui::Selectable(TCHAR_TO_ANSI(*EnumEntryName), IsSelected))
{
HasChanged = true;
NewValue = EnumEntryValue;
}
if (IsSelected)
{
ImGui::SetItemDefaultFocus();
}
}
ImGui::EndCombo();
}
return HasChanged;
}
@@ -0,0 +1,89 @@
#include "CogWindow_Settings.h"
#include "CogImguiModule.h"
#include "InputCoreTypes.h"
//--------------------------------------------------------------------------------------------------------------------------
UCogWindow_Settings::UCogWindow_Settings()
{
bHasMenu = false;
}
//--------------------------------------------------------------------------------------------------------------------------
void UCogWindow_Settings::PostInitProperties()
{
Super::PostInitProperties();
FCogImguiModule::Get().SetToggleInputKey(ToggleInputKey);
}
//--------------------------------------------------------------------------------------------------------------------------
void UCogWindow_Settings::RenderContent()
{
ImGui::Checkbox("Compact Mode", &GetOwner()->bCompactMode);
ImGui::Checkbox("Show Windows In Main Menu", &GetOwner()->bShowWindowsInMainMenu);
ImGui::Checkbox("Show Window Help", &GetOwner()->bShowHelp);
FCogWindowWidgets::SetNextItemToShortWidth();
ImGui::SliderFloat("DPI Scale", &GetOwner()->DPIScale, 0.5f, 2.0f, "%.1f");
if (ImGui::IsItemDeactivatedAfterEdit())
{
GetOwner()->bRefreshDPIScale = true;
}
if (ImGui::IsItemHovered())
{
ImGui::BeginTooltip();
ImGui::TextUnformatted("Change DPi Scale [Mouse Wheel]");
ImGui::TextUnformatted("Reset DPi Scale [Middle Mouse]");
ImGui::EndTooltip();
}
ImGui::Separator();
ImGui::Text("Toggle Input Key");
TArray<FKey> Keys;
EKeys::GetAllKeys(Keys);
bool HasKeyChanged = false;
FCogWindowWidgets::SetNextItemToShortWidth();
if (ImGui::BeginCombo("Key", TCHAR_TO_ANSI(*ToggleInputKey.Key.ToString())))
{
for (int32 i = 0; i < Keys.Num(); ++i)
{
const FKey Key = Keys[i];
if (Key.IsDigital() == false || Key.IsDeprecated())
{
continue;
}
bool IsSelected = ToggleInputKey.Key == Key;
if (ImGui::Selectable(TCHAR_TO_ANSI(*Key.ToString()), IsSelected))
{
ToggleInputKey.Key = Key;
HasKeyChanged = true;
}
}
ImGui::EndCombo();
}
FCogWindowWidgets::SetNextItemToShortWidth();
HasKeyChanged |= FCogWindowWidgets::ComboboxEnum("Ctrl", ToggleInputKey.Ctrl);
FCogWindowWidgets::SetNextItemToShortWidth();
HasKeyChanged |= FCogWindowWidgets::ComboboxEnum("Shift", ToggleInputKey.Shift);
FCogWindowWidgets::SetNextItemToShortWidth();
HasKeyChanged |= FCogWindowWidgets::ComboboxEnum("Alt", ToggleInputKey.Alt);
FCogWindowWidgets::SetNextItemToShortWidth();
HasKeyChanged |= FCogWindowWidgets::ComboboxEnum("Cmd", ToggleInputKey.Cmd);
if (HasKeyChanged)
{
FCogImguiModule::Get().SetToggleInputKey(ToggleInputKey);
}
}
@@ -28,9 +28,6 @@ public:
/** Called every frame without a valid imgui context (outside of the imgui NewFrame/EndFrame) even if the window is hidden. */
virtual void GameTick(float DeltaTime);
/** Draw the window menu item. Called when the menu item visible */
virtual void DrawMenuItem(const FString& MenuItemName);
virtual void DrawMainMenuWidget(bool Draw, float& Width) {}
ImGuiID GetID() const { return ID; }
@@ -56,6 +53,8 @@ public:
UCogWindowManager* GetOwner() const { return Owner; }
protected:
friend class UCogWindowManager;
virtual const FString& GetTitle() const { return Name; }
@@ -6,6 +6,7 @@
#include "CogWindowManager.generated.h"
class UCogWindow;
class UCogWindow_Settings;
class UWorld;
class SCogImguiWidget;
struct ImGuiSettingsHandler;
@@ -55,12 +56,26 @@ public:
void SetHideAllWindows(bool Value);
float GetDPIScale() const { return DPIScale; }
void SetDPIScale(float Value);
bool GetCompactMode() const { return bCompactMode; }
void SetCompactMode(bool Value) { bCompactMode = Value; }
bool GetShowHelp() const { return bShowHelp; }
void SetShowHelp(bool Value) { bShowHelp = Value; }
bool GetPreviewWindowsInMenu() const { return bShowWindowsInMainMenu; }
void SetPreviewWindowsInMenu(bool Value) { bShowWindowsInMainMenu = Value; }
protected:
friend class UCogWindow_Settings;
struct FMenu
{
FString Name;
@@ -78,6 +93,8 @@ protected:
void DrawMenu(FMenu& Menu);
void DrawMenuItem(UCogWindow& Window, const char* MenuItemName);
static void SettingsHandler_ClearAll(ImGuiContext* ctx, ImGuiSettingsHandler*);
static void SettingsHandler_ApplyAll(ImGuiContext* ctx, ImGuiSettingsHandler*);
@@ -96,6 +113,9 @@ protected:
UPROPERTY()
TArray<UCogWindow*> SpaceWindows;
UPROPERTY()
UCogWindow_Settings* SettingsWindow = nullptr;
UPROPERTY()
TArray<UCogWindow*> MainMenuWidgets;
@@ -111,7 +131,10 @@ protected:
UPROPERTY(Config)
bool bShowHelp = true;
TSharedPtr<SCogImguiWidget> ImGuiWidget;
UPROPERTY(Config)
bool bShowWindowsInMainMenu = true;
TSharedPtr<SCogImguiWidget> ImGuiWidget = nullptr;
FMenu MainMenu;
@@ -121,5 +144,5 @@ protected:
bool bHideAllWindows = false;
bool bRefreshDPIScale;
bool bRefreshDPIScale = false;
};
@@ -2,6 +2,10 @@
#include "CoreMinimal.h"
#include "imgui.h"
#include "UObject/ReflectedTypeAccessors.h"
class UEnum;
class FEnumProperty;
class COGWINDOW_API FCogWindowWidgets
{
@@ -34,4 +38,36 @@ public:
static void SetNextItemToShortWidth();
static float GetFontWidth();
template<typename EnumType>
static bool ComboboxEnum(const char* Label, const EnumType CurrentValue, EnumType& NewValue);
template<typename EnumType>
static bool ComboboxEnum(const char* Label, EnumType& Value);
static bool ComboboxEnum(const char* Label, UEnum* Enum, int64 CurrentValue, int64& NewValue);
static bool ComboboxEnum(const char* Label, UObject* Object, const char* FieldName, uint8* PointerToEnumValue);
static bool ComboboxEnum(const char* Label, const FEnumProperty* EnumProperty, uint8* PointerToEnumValue);
};
template<typename EnumType>
bool FCogWindowWidgets::ComboboxEnum(const char* Label, const EnumType CurrentValue, EnumType& NewValue)
{
int64 NewValueInt;
if (ComboboxEnum(Label, StaticEnum<EnumType>(), (int64)CurrentValue, NewValueInt))
{
NewValue = (EnumType)NewValueInt;
return true;
}
return false;
}
template<typename EnumType>
bool FCogWindowWidgets::ComboboxEnum(const char* Label, EnumType& Value)
{
return ComboboxEnum(Label, Value, Value);
}
@@ -0,0 +1,27 @@
#pragma once
#include "CoreMinimal.h"
#include "CogWindow.h"
#include "CogImGuiKeyInfo.h"
#include "CogWindow_Settings.generated.h"
UCLASS(Config = Cog)
class COGWINDOW_API UCogWindow_Settings : public UCogWindow
{
GENERATED_BODY()
public:
UCogWindow_Settings();
protected:
virtual void PostInitProperties() override;
virtual void RenderContent() override;
private:
UPROPERTY(Config)
FCogImGuiKeyInfo ToggleInputKey;
};
+1 -1
View File
@@ -117,7 +117,7 @@ void ACogSampleGameState::Tick(float DeltaSeconds)
//--------------------------------------------------------------------------------------------------------------------------
void ACogSampleGameState::InitializeCog()
{
FCogImguiModule::Get().SetToggleInputKey(FCogImGuiKeyInfo(EKeys::Insert));
FCogImguiModule::Get().SetToggleInputKey(FCogImGuiKeyInfo(EKeys::Tab));
RegisterCommand(TEXT("Cog.ToggleInput"), TEXT(""), FConsoleCommandWithArgsDelegate::CreateUObject(this, &ACogSampleGameState::CogToggleInput));
CogWindowManager = NewObject<UCogWindowManager>(this);