First Submit

This commit is contained in:
Arnaud Jamin
2023-10-02 01:32:41 -04:00
parent c34574e841
commit 1aabdb5c4e
445 changed files with 93851 additions and 0 deletions
@@ -0,0 +1,49 @@
using UnrealBuildTool;
public class CogWindow : ModuleRules
{
public CogWindow(ReadOnlyTargetRules Target) : base(Target)
{
PCHUsage = ModuleRules.PCHUsageMode.UseExplicitOrSharedPCHs;
PublicIncludePaths.AddRange(
new string[] {
}
);
PrivateIncludePaths.AddRange(
new string[] {
}
);
PublicDependencyModuleNames.AddRange(
new string[]
{
"Core",
"CogImgui",
"CogDebug",
}
);
PrivateDependencyModuleNames.AddRange(
new string[]
{
"CoreUObject",
"Engine",
"Slate",
"SlateCore",
"NetCore",
}
);
DynamicallyLoadedModuleNames.AddRange(
new string[]
{
}
);
}
}
@@ -0,0 +1,152 @@
#include "CogWindow.h"
#include "CogDebugDraw.h"
#include "CogDebugSettings.h"
#include "CogWindowManager.h"
#include "CogWindowWidgets.h"
#include "Engine/World.h"
#include "imgui_internal.h"
//--------------------------------------------------------------------------------------------------------------------------
void UCogWindow::SetFullName(const FString& InFullName)
{
FullName = InFullName;
TArray<FString> Path;
int CharIndex = 0;
if (FullName.FindLastChar(TEXT('.'), CharIndex))
{
Name = FullName.RightChop(CharIndex + 1);
}
else
{
Name = FullName;
}
ID = ImHashStr(TCHAR_TO_ANSI(*FullName));
}
//--------------------------------------------------------------------------------------------------------------------------
bool UCogWindow::CheckEditorVisibility()
{
const UWorld* World = GetWorld();
if (World == nullptr)
{
return false;
}
if (World->WorldType != EWorldType::Game)
{
return false;
}
if (World->WorldType == EWorldType::PIE)
{
return false;
}
return true;
}
//--------------------------------------------------------------------------------------------------------------------------
void UCogWindow::Render(float DeltaTime)
{
ImGuiWindowFlags WindowFlags = 0;
PreRender(WindowFlags);
if (ImGui::Begin(TCHAR_TO_ANSI(*GetTitle()), &bIsVisible, WindowFlags))
{
RenderContent();
ImGui::End();
}
}
//--------------------------------------------------------------------------------------------------------------------------
void UCogWindow::RenderTick(float DeltaTime)
{
SetSelection(FCogDebugSettings::GetSelection());
}
//--------------------------------------------------------------------------------------------------------------------------
void UCogWindow::GameTick(float DeltaTime)
{
}
//--------------------------------------------------------------------------------------------------------------------------
void UCogWindow::DrawMenuItem(const FString& MenuItemName)
{
if (bShowInsideMenu && bIsVisible == false)
{
static const ImVec2 TEXT_BASE_SIZE = ImGui::CalcTextSize("A");
ImGui::SetNextWindowSizeConstraints(ImVec2(TEXT_BASE_SIZE.x * 40, TEXT_BASE_SIZE.y * 1),
ImVec2(TEXT_BASE_SIZE.x * 50, TEXT_BASE_SIZE.y * 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)
{
if (CurrentSelection == NewSelection)
{
return;
}
AActor* OldActor = CurrentSelection.Get();
CurrentSelection = NewSelection;
OnSelectionChanged(OldActor, NewSelection);
}
//--------------------------------------------------------------------------------------------------------------------------
APawn* UCogWindow::GetLocalPlayerPawn()
{
APlayerController* LocalPlayerController = GetLocalPlayerController();
if (LocalPlayerController == nullptr)
{
return nullptr;
}
APawn* Pawn = LocalPlayerController->GetPawn();
return Pawn;
}
//--------------------------------------------------------------------------------------------------------------------------
APlayerController* UCogWindow::GetLocalPlayerController()
{
ULocalPlayer* LocalPlayer = GetLocalPlayer();
if (LocalPlayer == nullptr)
{
return nullptr;
}
return LocalPlayer->PlayerController;
}
//--------------------------------------------------------------------------------------------------------------------------
ULocalPlayer* UCogWindow::GetLocalPlayer()
{
const UWorld* World = GetWorld();
if (World == nullptr)
{
return nullptr;
}
return World->GetFirstLocalPlayerFromController();
}
@@ -0,0 +1,381 @@
#include "CogWindowManager.h"
#include "CogImguiModule.h"
#include "CogImguiWidget.h"
#include "CogWindowWidgets.h"
#include "Engine/Engine.h"
#include "imgui_internal.h"
//--------------------------------------------------------------------------------------------------------------------------
UCogWindowManager::UCogWindowManager()
{
}
//--------------------------------------------------------------------------------------------------------------------------
void UCogWindowManager::Initialize(UWorld* InWorld, TSharedPtr<SCogImguiWidget> InImGuiWidget)
{
World = InWorld;
ImGuiWidget = InImGuiWidget;
ImGuiSettingsHandler IniHandler;
IniHandler.TypeName = "Cog";
IniHandler.TypeHash = ImHashStr("Cog");
IniHandler.ClearAllFn = UCogWindowManager::SettingsHandler_ClearAll;
IniHandler.ReadOpenFn = UCogWindowManager::SettingsHandler_ReadOpen;
IniHandler.ReadLineFn = UCogWindowManager::SettingsHandler_ReadLine;
IniHandler.ApplyAllFn = UCogWindowManager::SettingsHandler_ApplyAll;
IniHandler.WriteAllFn = UCogWindowManager::SettingsHandler_WriteAll;
IniHandler.UserData = this;
ImGui::AddSettingsHandler(&IniHandler);
}
//--------------------------------------------------------------------------------------------------------------------------
void UCogWindowManager::Shutdown()
{
for (UCogWindow* Window : Windows)
{
Window->Shutdown();
Window->SaveConfig();
}
SaveConfig();
}
//--------------------------------------------------------------------------------------------------------------------------
void UCogWindowManager::Tick(float DeltaTime)
{
if (LayoutToLoad != -1)
{
FString Filename = FCogImguiHelper::GetIniFilePath(FString::Printf(TEXT("ImGui_Layout_%d"), LayoutToLoad));
ImGui::LoadIniSettingsFromDisk(TCHAR_TO_ANSI(*Filename));
LayoutToLoad = -1;
}
if (bRefreshDPIScale)
{
RefreshDPIScale();
bRefreshDPIScale = false;
}
for (UCogWindow* Window : Windows)
{
Window->GameTick(DeltaTime);
}
}
//--------------------------------------------------------------------------------------------------------------------------
void UCogWindowManager::Render(float DeltaTime)
{
FCogWindowWidgets::TextBaseWidth = ImGui::CalcTextSize("A").x;
FCogWindowWidgets::TextBaseHeight = ImGui::GetTextLineHeightWithSpacing();
ImGui::DockSpaceOverViewport(0, ImGuiDockNodeFlags_PassthruCentralNode | ImGuiDockNodeFlags_NoDockingInCentralNode);
bool bCompactSaved = bCompactMode;
if (bCompactSaved)
{
FCogWindowWidgets::PushStyleCompact();
}
if (bHideAllWindows == false)
{
if (FCogImguiModule::Get().GetEnableInput())
{
DrawMainMenu();
}
}
for (UCogWindow* Window : Windows)
{
Window->RenderTick(DeltaTime);
if (Window->GetIsVisible() && bHideAllWindows == false)
{
if (bTransparentMode)
{
ImGui::SetNextWindowBgAlpha(0.35f);
}
Window->Render(DeltaTime);
}
}
if (bCompactSaved)
{
FCogWindowWidgets::PopStyleCompact();
}
TickDPI();
}
//--------------------------------------------------------------------------------------------------------------------------
void UCogWindowManager::AddWindow(UCogWindow* Window)
{
Window->SetOwner(this);
Windows.Add(Window);
}
//--------------------------------------------------------------------------------------------------------------------------
void UCogWindowManager::AddMainMenuWidget(UCogWindow* Window)
{
Window->SetOwner(this);
MainMenuWidgets.Add(Window);
}
//--------------------------------------------------------------------------------------------------------------------------
UCogWindow* UCogWindowManager::FindWindowByID(ImGuiID ID)
{
for (UCogWindow* Window : Windows)
{
if (Window->GetID() == ID)
{
return Window;
}
}
return nullptr;
}
//--------------------------------------------------------------------------------------------------------------------------
void UCogWindowManager::SetHideAllWindows(bool Value)
{
HideAllWindowsCounter = FMath::Max(HideAllWindowsCounter + (Value ? +1 : -1), 0);
bHideAllWindows = HideAllWindowsCounter > 0;
}
//--------------------------------------------------------------------------------------------------------------------------
void UCogWindowManager::CloseAllWindows()
{
for (UCogWindow* Window : Windows)
{
Window->SetIsVisible(false);
}
}
//--------------------------------------------------------------------------------------------------------------------------
void UCogWindowManager::LoadLayout(int LayoutIndex)
{
for (UCogWindow* Window : Windows)
{
Window->SetIsVisible(false);
}
LayoutToLoad = LayoutIndex;
}
//--------------------------------------------------------------------------------------------------------------------------
void UCogWindowManager::SaveLayout(int LayoutIndex)
{
FString Filename = *FCogImguiHelper::GetIniFilePath(FString::Printf(TEXT("imgui_layout_%d"), LayoutIndex));
ImGui::SaveIniSettingsToDisk(TCHAR_TO_ANSI(*Filename));
}
//--------------------------------------------------------------------------------------------------------------------------
void UCogWindowManager::RebuildMenu()
{
MainMenu.SubMenus.Empty();
for (UCogWindow* Window : Windows)
{
check(Window);
FMenu* NewMenu = AddMenu(Window->GetFullName());
NewMenu->Window = Window;
}
}
//--------------------------------------------------------------------------------------------------------------------------
UCogWindowManager::FMenu* UCogWindowManager::AddMenu(const FString& Name)
{
TArray<FString> Path;
Name.ParseIntoArray(Path, TEXT("."));
UCogWindowManager::FMenu* CurrentMenu = &MainMenu;
for (int i = 0; i < Path.Num(); ++i)
{
FString MenuName = Path[i];
int SubMenuIndex = CurrentMenu->SubMenus.IndexOfByPredicate([&](const UCogWindowManager::FMenu& Menu) { return Menu.Name == MenuName; });
if (SubMenuIndex != -1)
{
CurrentMenu = &CurrentMenu->SubMenus[SubMenuIndex];
}
else
{
CurrentMenu = &CurrentMenu->SubMenus.AddDefaulted_GetRef();
CurrentMenu->Name = MenuName;
}
}
return CurrentMenu;
}
//--------------------------------------------------------------------------------------------------------------------------
void UCogWindowManager::DrawMainMenu()
{
if (ImGui::BeginMainMenuBar())
{
for (UCogWindowManager::FMenu& Menu : MainMenu.SubMenus)
{
DrawMenu(Menu);
}
if (ImGui::BeginMenu("Window"))
{
if (ImGui::BeginMenu("Load Layout"))
{
for (int32 i = 1; i <= 4; ++i)
{
if (ImGui::MenuItem(TCHAR_TO_ANSI(*FString::Printf(TEXT("Load Layout %d"), i))))
{
LoadLayout(i);
}
}
ImGui::EndMenu();
}
if (ImGui::BeginMenu("Save Layout"))
{
for (int32 i = 1; i <= 4; ++i)
{
if (ImGui::MenuItem(TCHAR_TO_ANSI(*FString::Printf(TEXT("Save Layout %d"), i))))
{
SaveLayout(i);
}
}
ImGui::EndMenu();
}
ImGui::Separator();
if (ImGui::MenuItem("Close All"))
{
CloseAllWindows();
}
ImGui::MenuItem("Transparent Mode", nullptr, &bTransparentMode);
ImGui::MenuItem("Compact Mode", nullptr, &bCompactMode);
ImGui::Text("DPI Scale");
ImGui::SameLine();
FCogWindowWidgets::PushStyleCompact();
ImGui::SliderFloat("", &DPIScale, 0.5f, 2.0f, "%.1f");
if (ImGui::IsItemDeactivatedAfterEdit())
{
bRefreshDPIScale = true;
}
FCogWindowWidgets::PopStyleCompact();
ImGui::EndMenu();
}
float CursorX = ImGui::GetWindowWidth();
for (UCogWindow* Window : MainMenuWidgets)
{
float Width = 0.0f;
Window->DrawMainMenuWidget(false, Width);
CursorX -= Width;
ImGui::SetCursorPosX(CursorX);
Window->DrawMainMenuWidget(true, Width);
CursorX -= ImGui::GetStyle().ItemSpacing.x;
}
ImGui::EndMainMenuBar();
}
}
//--------------------------------------------------------------------------------------------------------------------------
void UCogWindowManager::DrawMenu(UCogWindowManager::FMenu& Menu)
{
if (Menu.Window != nullptr)
{
Menu.Window->DrawMenuItem(Menu.Name);
}
else
{
if (ImGui::BeginMenu(TCHAR_TO_ANSI(*Menu.Name)))
{
for (UCogWindowManager::FMenu& SubMenu : Menu.SubMenus)
{
DrawMenu(SubMenu);
}
ImGui::EndMenu();
}
}
}
//--------------------------------------------------------------------------------------------------------------------------
void UCogWindowManager::TickDPI()
{
const float MouseWheel = ImGui::GetIO().MouseWheel;
const bool IsControlDown = ImGui::GetIO().KeyCtrl;
if (IsControlDown && MouseWheel != 0)
{
DPIScale = FMath::Clamp(DPIScale + (MouseWheel > 0 ? 0.05f : -0.05f), 0.1f, 2.0f);
bRefreshDPIScale = true;
}
const bool IsMiddleMouseClicked = ImGui::GetIO().MouseClicked[2];
if (IsControlDown && IsMiddleMouseClicked)
{
DPIScale = 1.0f;
bRefreshDPIScale = true;
}
}
//--------------------------------------------------------------------------------------------------------------------------
void UCogWindowManager::RefreshDPIScale()
{
if (SCogImguiWidget* Widget = ImGuiWidget.Get())
{
Widget->SetDPIScale(DPIScale);
}
}
//--------------------------------------------------------------------------------------------------------------------------
void UCogWindowManager::SettingsHandler_ClearAll(ImGuiContext* Context, ImGuiSettingsHandler* Handler)
{
}
//--------------------------------------------------------------------------------------------------------------------------
void UCogWindowManager::SettingsHandler_ApplyAll(ImGuiContext* Context, ImGuiSettingsHandler* Handler)
{
}
//--------------------------------------------------------------------------------------------------------------------------
void* UCogWindowManager::SettingsHandler_ReadOpen(ImGuiContext* Context, ImGuiSettingsHandler* Handler, const char* Name)
{
return (void*)1;
}
//--------------------------------------------------------------------------------------------------------------------------
void UCogWindowManager::SettingsHandler_ReadLine(ImGuiContext* Context, ImGuiSettingsHandler* Handler, void* Entry, const char* Line)
{
ImGuiID Id;
if (sscanf_s(Line, "0x%08X", &Id) == 1)
{
UCogWindowManager* Manager = (UCogWindowManager*)Handler->UserData;
if (UCogWindow* Window = Manager->FindWindowByID(Id))
{
Window->SetIsVisible(true);
}
}
}
//--------------------------------------------------------------------------------------------------------------------------
void UCogWindowManager::SettingsHandler_WriteAll(ImGuiContext* Context, ImGuiSettingsHandler* Handler, ImGuiTextBuffer* Buffer)
{
const UCogWindowManager* Manager = (UCogWindowManager*)Handler->UserData;
Buffer->appendf("[%s][Windows]\n", Handler->TypeName);
for (UCogWindow* Window : Manager->Windows)
{
if (Window->GetIsVisible())
{
Buffer->appendf("0x%08X\n", Window->GetID());
}
}
}
@@ -0,0 +1,17 @@
#include "CogWindowModule.h"
#define LOCTEXT_NAMESPACE "FCogWindowModule"
//--------------------------------------------------------------------------------------------------------------------------
void FCogWindowModule::StartupModule()
{
}
//--------------------------------------------------------------------------------------------------------------------------
void FCogWindowModule::ShutdownModule()
{
}
#undef LOCTEXT_NAMESPACE
IMPLEMENT_MODULE(FCogWindowModule, CogWindow)
@@ -0,0 +1,181 @@
#include "CogWindowWidgets.h"
#include "CogImguiHelper.h"
#include "Kismet/KismetMathLibrary.h"
#include "imgui.h"
#include "imgui_internal.h"
//--------------------------------------------------------------------------------------------------------------------------
float FCogWindowWidgets::TextBaseWidth = 0.0f;
float FCogWindowWidgets::TextBaseHeight = 0.0f;
//--------------------------------------------------------------------------------------------------------------------------
void FCogWindowWidgets::BeginTableTooltip()
{
ImGui::PushStyleVar(ImGuiStyleVar_CellPadding, ImVec2(4, 4));
ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(0, 0));
ImGui::PushStyleColor(ImGuiCol_PopupBg, IM_COL32(29, 42, 62, 240));
ImGui::BeginTooltip();
}
//--------------------------------------------------------------------------------------------------------------------------
void FCogWindowWidgets::EndTableTooltip()
{
ImGui::EndTooltip();
ImGui::PopStyleColor();
ImGui::PopStyleVar(2);
}
//--------------------------------------------------------------------------------------------------------------------------
void FCogWindowWidgets::ProgressBarCentered(float Fraction, const ImVec2& Size, const char* Overlay)
{
ImGuiWindow* window = FCogImguiHelper::GetCurrentWindow();
if (window->SkipItems)
return;
ImGuiContext& g = *ImGui::GetCurrentContext();
const ImGuiStyle& style = g.Style;
ImVec2 pos = window->DC.CursorPos;
ImVec2 size = ImGui::CalcItemSize(Size, ImGui::CalcItemWidth(), g.FontSize + style.FramePadding.y * 2.0f);
ImRect bb(pos, pos + size);
ImGui::ItemSize(size, style.FramePadding.y);
if (!ImGui::ItemAdd(bb, 0))
return;
// Render
Fraction = ImSaturate(Fraction);
ImGui::RenderFrame(bb.Min, bb.Max, ImGui::GetColorU32(ImGuiCol_FrameBg), true, style.FrameRounding);
bb.Expand(ImVec2(-style.FrameBorderSize, -style.FrameBorderSize));
const ImVec2 fill_br = ImVec2(ImLerp(bb.Min.x, bb.Max.x, Fraction), bb.Max.y);
ImGui::RenderRectFilledRangeH(window->DrawList, bb, ImGui::GetColorU32(ImGuiCol_PlotHistogram), 0.0f, Fraction, style.FrameRounding);
// Default displaying the fraction as percentage string, but user can override it
char overlay_buf[32];
if (!Overlay)
{
ImFormatString(overlay_buf, IM_ARRAYSIZE(overlay_buf), "%.0f%%", Fraction * 100 + 0.01f);
Overlay = overlay_buf;
}
ImVec2 overlay_size = ImGui::CalcTextSize(Overlay, NULL);
if (overlay_size.x > 0.0f)
{
ImVec2 pos1(ImClamp(bb.Min.x + (bb.Max.x - bb.Min.x) * 0.5f - overlay_size.x * 0.5f + style.ItemSpacing.x, bb.Min.x, bb.Max.x - style.ItemInnerSpacing.x), bb.Min.y - 1);
ImVec2 pos2(pos1.x + 1, pos1.y + 1);
ImGui::PushStyleColor(ImGuiCol_Text, IM_COL32(0, 0, 0, 255));
ImGui::RenderTextClipped(pos2, bb.Max, Overlay, NULL, &overlay_size, ImVec2(0.0f, 0.5f), &bb);
ImGui::PopStyleColor();
ImGui::RenderTextClipped(pos1, bb.Max, Overlay, NULL, &overlay_size, ImVec2(0.0f, 0.5f), &bb);
}
}
//--------------------------------------------------------------------------------------------------------------------------
void FCogWindowWidgets::ToggleButton(bool* Value, const char* TextTrue, const char* TextFalse, const ImVec4& TrueColor, const ImVec4& FalseColor, const ImVec2& Size)
{
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))
{
*Value = false;
}
ImGui::PopStyleColor(3);
}
else
{
ImGui::PushStyleColor(ImGuiCol_Button, ImVec4(FalseColor.x, FalseColor.y, FalseColor.z, FalseColor.w * 0.6f));
ImGui::PushStyleColor(ImGuiCol_ButtonHovered, ImVec4(FalseColor.x, FalseColor.y, FalseColor.z, FalseColor.w * 0.8f));
ImGui::PushStyleColor(ImGuiCol_ButtonActive, ImVec4(FalseColor.x, FalseColor.y, FalseColor.z, FalseColor.w * 1.0f));
if (ImGui::Button(TextFalse, Size))
{
*Value = true;
}
ImGui::PopStyleColor(3);
}
}
//--------------------------------------------------------------------------------------------------------------------------
void FCogWindowWidgets::SliderWithReset(const char* Name, float* Value, float Min, float Max, const float& ResetValue, const char* Format)
{
ImGui::SliderFloat(Name, Value, Min, Max, Format);
if (ImGui::BeginPopupContextItem(Name))
{
if (ImGui::Button("Reset"))
{
*Value = ResetValue;
if (ImGuiWindow* Window = FCogImguiHelper::GetCurrentWindow())
{
const ImGuiID id = Window->GetID(Name);
ImGui::MarkItemEdited(id);
}
}
ImGui::EndPopup();
}
}
//--------------------------------------------------------------------------------------------------------------------------
void FCogWindowWidgets::HelpMarker(const char* Text)
{
ImGui::TextDisabled("(?)");
if (ImGui::IsItemHovered())
{
ImGui::BeginTooltip();
ImGui::PushTextWrapPos(ImGui::GetFontSize() * 35.0f);
ImGui::TextUnformatted(Text);
ImGui::PopTextWrapPos();
ImGui::EndTooltip();
}
}
//--------------------------------------------------------------------------------------------------------------------------
void FCogWindowWidgets::PushStyleCompact()
{
ImGuiStyle& style = ImGui::GetStyle();
ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(style.WindowPadding.x * 0.60f, (float)(int)(style.WindowPadding.y * 0.60f)));
ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(style.FramePadding.x * 0.60f, (float)(int)(style.FramePadding.y * 0.60f)));
ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(style.ItemSpacing.x * 0.60f, (float)(int)(style.ItemSpacing.y * 0.60f)));
}
//--------------------------------------------------------------------------------------------------------------------------
void FCogWindowWidgets::PopStyleCompact()
{
ImGui::PopStyleVar(3);
}
//--------------------------------------------------------------------------------------------------------------------------
void FCogWindowWidgets::AddTextWithShadow(ImDrawList* DrawList, const ImVec2& Position, ImU32 Color, const char* TextBegin, const char* TextEnd /*= NULL*/)
{
float Alpha = ImGui::ColorConvertU32ToFloat4(Color).w;
DrawList->AddText(Position + ImVec2(1.0f, 1.0f), ImGui::ColorConvertFloat4ToU32(ImVec4(0, 0, 0, Alpha)), TextBegin, TextEnd);
DrawList->AddText(Position, Color, TextBegin, TextEnd);
}
//--------------------------------------------------------------------------------------------------------------------------
void FCogWindowWidgets::MenuSearchBar(ImGuiTextFilter& Filter)
{
ImGui::SameLine();
const float Pos1 = ImGui::GetCursorPosX();
Filter.Draw("", -1);
const float Pos2 = ImGui::GetCursorPosX();
if (ImGui::IsItemActive() == false && Filter.Filters.empty())
{
ImGui::SetCursorPosX(Pos1 + 3);
ImGui::TextDisabled("Search");
}
ImGui::SetCursorPosX(Pos2);
}
@@ -0,0 +1,93 @@
#pragma once
#include "CoreMinimal.h"
#include "imgui.h"
#include "CogWindow.generated.h"
class UCogWindowManager;
class APawn;
class APlayerController;
UCLASS(Config = Cog)
class COGWINDOW_API UCogWindow : public UObject
{
GENERATED_BODY()
public:
virtual void Initialize() {}
virtual void Shutdown() {}
/** Called every frame with a valid imgui context if the window is visible. */
virtual void Render(float DeltaTime);
/** Called every frame with a valid imgui context even if the window is hidden. */
virtual void RenderTick(float DeltaTime);
/** 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; }
/** The full name of the window, that contains the path in the main menu. For example "Gameplay.Character.Effect" */
const FString& GetFullName() const { return FullName; }
void SetFullName(const FString& InFullName);
/** The short name of the window. "Effect" if the window full name is "Gameplay.Character.Effect" */
const FString& GetName() const { return Name; }
AActor* GetSelection() { return CurrentSelection.Get(); }
void SetSelection(AActor* Actor);
bool GetIsVisible() const { return bIsVisible; }
void SetIsVisible(bool Value) { bIsVisible = Value; }
void SetOwner(UCogWindowManager* InOwner) { Owner = InOwner; }
UCogWindowManager* GetOwner() const { return Owner; }
protected:
virtual const FString& GetTitle() const { return Name; }
virtual void PreRender(ImGuiWindowFlags& WindowFlags) {}
virtual void RenderContent() {}
virtual bool CheckEditorVisibility();
virtual void OnSelectionChanged(AActor* OldSelection, AActor* NewSelection) {}
APawn* GetLocalPlayerPawn();
APlayerController* GetLocalPlayerController();
ULocalPlayer* GetLocalPlayer();
private:
bool bIsVisible = false;
bool bShowInsideMenu = true;
ImGuiID ID;
FString FullName;
FString Name;
UCogWindowManager* Owner = nullptr;
TWeakObjectPtr<AActor> CurrentSelection;
TWeakObjectPtr<AActor> OverridenSelection;
};
@@ -0,0 +1,108 @@
#pragma once
#include "CoreMinimal.h"
#include "CogWindow.h"
#include "imgui.h"
#include "CogWindowManager.generated.h"
class UCogWindow;
class UWorld;
class SCogImguiWidget;
struct ImGuiSettingsHandler;
struct ImGuiTextBuffer;
UCLASS(Config = Cog)
class COGWINDOW_API UCogWindowManager : public UObject
{
GENERATED_BODY()
public:
UCogWindowManager();
void Initialize(UWorld* World, TSharedPtr<SCogImguiWidget> InImGuiWidget);
void Shutdown();
void RebuildMenu();
void Render(float DeltaTime);
void Tick(float DeltaTime);
template<class T>
T* CreateWindow(const FString& Name)
{
T* Window = NewObject<T>(this);
Window->SetFullName(Name);
Window->Initialize();
AddWindow(Window);
return Window;
}
void AddWindow(UCogWindow* Window);
void AddMainMenuWidget(UCogWindow* Window);
UCogWindow* FindWindowByID(ImGuiID ID);
void CloseAllWindows();
void LoadLayout(int LayoutIndex);
void SaveLayout(int LayoutIndex);
bool GetHideAllWindows() const { return bHideAllWindows; }
void SetHideAllWindows(bool Value);
bool GetCompactMode() const { return bCompactMode; }
private:
struct FMenu
{
FString Name;
UCogWindow* Window = nullptr;
TArray<FMenu> SubMenus;
};
void RefreshDPIScale();
void DrawMainMenu();
FMenu* AddMenu(const FString& Name);
void DrawMenu(FMenu& Menu);
static void SettingsHandler_ClearAll(ImGuiContext* ctx, ImGuiSettingsHandler*);
static void SettingsHandler_ApplyAll(ImGuiContext* ctx, ImGuiSettingsHandler*);
static void* SettingsHandler_ReadOpen(ImGuiContext*, ImGuiSettingsHandler*, const char* name);
static void SettingsHandler_ReadLine(ImGuiContext*, ImGuiSettingsHandler*, void* entry, const char* line);
static void SettingsHandler_WriteAll(ImGuiContext* ctx, ImGuiSettingsHandler* handler, ImGuiTextBuffer* buf);
void TickDPI();
UPROPERTY()
TArray<UCogWindow*> Windows;
UPROPERTY()
TArray<UCogWindow*> MainMenuWidgets;
UPROPERTY(Config)
bool bCompactMode = false;
UPROPERTY(Config)
bool bTransparentMode = false;
UPROPERTY(Config)
float DPIScale = 1.0f;
TSharedPtr<SCogImguiWidget> ImGuiWidget;
TWeakObjectPtr<UWorld> World;
FMenu MainMenu;
int32 LayoutToLoad = -1;
int32 HideAllWindowsCounter = 0;
bool bHideAllWindows = false;
bool bRefreshDPIScale;
};
@@ -0,0 +1,17 @@
#pragma once
#include "CoreMinimal.h"
#include "Modules/ModuleManager.h"
class COGWINDOW_API FCogWindowModule : public IModuleInterface
{
public:
static inline FCogWindowModule& Get() { return FModuleManager::LoadModuleChecked<FCogWindowModule>("CogWindow"); }
virtual void StartupModule() override;
virtual void ShutdownModule() override;
private:
};
@@ -0,0 +1,33 @@
#pragma once
#include "CoreMinimal.h"
#include "imgui.h"
class COGWINDOW_API FCogWindowWidgets
{
public:
static void BeginTableTooltip();
static void EndTableTooltip();
static void ProgressBarCentered(float Fraction, const ImVec2& Size, const char* Overlay);
static void ToggleButton(bool* Value, const char* TextTrue, const char* TextFalse, const ImVec4& TrueColor, const ImVec4& FalseColor, const ImVec2& Size = ImVec2(0, 0));
static void SliderWithReset(const char* Name, float* Value, float Min, float Max, const float& ResetValue, const char* Format);
static void HelpMarker(const char* Text);
static void PushStyleCompact();
static void PopStyleCompact();
static void AddTextWithShadow(ImDrawList* DrawList, const ImVec2& Position, ImU32 Color, const char* TextBegin, const char* TextEnd = NULL);
static float TextBaseWidth;
static float TextBaseHeight;
static void MenuSearchBar(ImGuiTextFilter& Filter);
};