mirror of
https://github.com/SunsetMkt/Akebi-GC.git
synced 2025-09-19 03:56:05 +08:00
minor changes
improvement `ImGui::BeginGroupPanel` fix typos fix warnings anti-debug bypass changes (implementation is private for now)
This commit is contained in:
@ -53,8 +53,8 @@ void PipeTransfer::ReadBytes(void* buffer, size_t size)
|
||||
if (size == 0 || !IsPipeOpened()) return;
|
||||
|
||||
DWORD readCount = 0;
|
||||
auto result = ReadFile(m_Pipe, buffer, size, &readCount, nullptr);
|
||||
if (!result || readCount < size)
|
||||
auto result = ReadFile(m_Pipe, buffer, static_cast<DWORD>(size), &readCount, nullptr);
|
||||
if (!result || static_cast<size_t>(readCount) < size)
|
||||
{
|
||||
LOG_LAST_ERROR("Failed read from pipe.");
|
||||
CloseHandle(m_Pipe);
|
||||
@ -67,8 +67,8 @@ void PipeTransfer::WriteBytes(void* buffer, size_t size)
|
||||
if (size == 0 || !IsPipeOpened()) return;
|
||||
|
||||
DWORD writenCount = 0;
|
||||
auto result = WriteFile(m_Pipe, buffer, size, &writenCount, nullptr);
|
||||
if (!result || writenCount < size)
|
||||
auto result = WriteFile(m_Pipe, buffer, static_cast<DWORD>(size), &writenCount, nullptr);
|
||||
if (!result || static_cast<size_t>(writenCount) < size)
|
||||
{
|
||||
LOG_LAST_ERROR("Failed write to pipe.");
|
||||
CloseHandle(m_Pipe);
|
||||
|
@ -113,7 +113,7 @@ namespace cheat
|
||||
void CheatManagerBase::DrawMenuSection(const std::string& sectionName, const std::vector<Feature*>& features) const
|
||||
{
|
||||
if (!sectionName.empty())
|
||||
BeginGroupPanel(sectionName.c_str(), ImVec2(-1, 0));
|
||||
ImGui::BeginGroupPanel(sectionName.c_str());
|
||||
|
||||
for (auto& feature : features)
|
||||
{
|
||||
@ -123,7 +123,7 @@ namespace cheat
|
||||
}
|
||||
|
||||
if (!sectionName.empty())
|
||||
EndGroupPanel();
|
||||
ImGui::EndGroupPanel();
|
||||
}
|
||||
|
||||
void CheatManagerBase::DrawProfileGlobalActivities()
|
||||
@ -350,7 +350,7 @@ namespace cheat
|
||||
if (!moduleShowAny)
|
||||
continue;
|
||||
|
||||
BeginGroupPanel(moduleName.c_str(), ImVec2(-1, 0));
|
||||
ImGui::BeginGroupPanel(moduleName.c_str());
|
||||
|
||||
for (auto& [sectionName, features] : sections)
|
||||
{
|
||||
@ -365,7 +365,7 @@ namespace cheat
|
||||
}
|
||||
}
|
||||
|
||||
EndGroupPanel();
|
||||
ImGui::EndGroupPanel();
|
||||
}
|
||||
|
||||
ImGui::End();
|
||||
|
@ -31,7 +31,7 @@ namespace cheat::feature
|
||||
NF(f_HotkeyExit, "Hotkeys", "General::FastExit", Hotkey(VK_F12))
|
||||
|
||||
{
|
||||
renderer::SetGlobalFontSize(f_FontSize);
|
||||
renderer::SetGlobalFontSize(static_cast<float>(f_FontSize));
|
||||
f_HotkeyExit.value().PressedEvent += MY_METHOD_HANDLER(Settings::OnExitKeyPressed);
|
||||
}
|
||||
|
||||
@ -44,7 +44,7 @@ namespace cheat::feature
|
||||
void Settings::DrawMain()
|
||||
{
|
||||
|
||||
BeginGroupPanel("General", ImVec2(-1, 0));
|
||||
ImGui::BeginGroupPanel("General");
|
||||
{
|
||||
ConfigWidget(f_MenuKey, false,
|
||||
"Key to toggle main menu visibility. Cannot be empty.\n"\
|
||||
@ -53,12 +53,12 @@ namespace cheat::feature
|
||||
if (ConfigWidget(f_FontSize, 1, 8, 64, "Font size for cheat interface."))
|
||||
{
|
||||
f_FontSize = std::clamp(f_FontSize.value(), 8, 64);
|
||||
renderer::SetGlobalFontSize(f_FontSize);
|
||||
renderer::SetGlobalFontSize(static_cast<float>(f_FontSize));
|
||||
}
|
||||
}
|
||||
EndGroupPanel();
|
||||
ImGui::EndGroupPanel();
|
||||
|
||||
BeginGroupPanel("Logging", ImVec2(-1, 0));
|
||||
ImGui::BeginGroupPanel("Logging");
|
||||
{
|
||||
bool consoleChanged = ConfigWidget(f_ConsoleLogging,
|
||||
"Enable console for logging information (changes will take effect after relaunch)");
|
||||
@ -75,37 +75,37 @@ namespace cheat::feature
|
||||
Logger::SetLevel(Logger::Level::None, Logger::LoggerType::FileLogger);
|
||||
}
|
||||
}
|
||||
EndGroupPanel();
|
||||
ImGui::EndGroupPanel();
|
||||
|
||||
BeginGroupPanel("Status Window", ImVec2(-1, 0));
|
||||
ImGui::BeginGroupPanel("Status Window");
|
||||
{
|
||||
ConfigWidget(f_StatusShow);
|
||||
ConfigWidget(f_StatusMove, "Allow moving of 'Status' window.");
|
||||
}
|
||||
EndGroupPanel();
|
||||
ImGui::EndGroupPanel();
|
||||
|
||||
BeginGroupPanel("Info Window", ImVec2(-1, 0));
|
||||
ImGui::BeginGroupPanel("Info Window");
|
||||
{
|
||||
ConfigWidget(f_InfoShow);
|
||||
ConfigWidget(f_InfoMove, "Allow moving of 'Info' window.");
|
||||
}
|
||||
EndGroupPanel();
|
||||
ImGui::EndGroupPanel();
|
||||
|
||||
BeginGroupPanel("FPS indicator", ImVec2(-1, 0));
|
||||
ImGui::BeginGroupPanel("FPS indicator");
|
||||
{
|
||||
ConfigWidget(f_FpsShow);
|
||||
ConfigWidget(f_FpsMove, "Allow moving of 'FPS Indicator' window.");
|
||||
}
|
||||
EndGroupPanel();
|
||||
ImGui::EndGroupPanel();
|
||||
|
||||
BeginGroupPanel("Show Notifications", ImVec2(-1, 0));
|
||||
ImGui::BeginGroupPanel("Show Notifications");
|
||||
{
|
||||
ConfigWidget(f_NotificationsShow, "Notifications on the bottom-right corner of the window will be displayed.");
|
||||
ConfigWidget(f_NotificationsDelay, 1,1,10000, "Delay in milliseconds between notifications.");
|
||||
}
|
||||
EndGroupPanel();
|
||||
ImGui::EndGroupPanel();
|
||||
|
||||
BeginGroupPanel("Fast Exit", ImVec2(-1, 0));
|
||||
ImGui::BeginGroupPanel("Fast Exit");
|
||||
{
|
||||
ConfigWidget("Enabled",
|
||||
f_FastExitEnable,
|
||||
@ -120,7 +120,7 @@ namespace cheat::feature
|
||||
if (!f_FastExitEnable)
|
||||
ImGui::EndDisabled();
|
||||
}
|
||||
EndGroupPanel();
|
||||
ImGui::EndGroupPanel();
|
||||
}
|
||||
|
||||
Settings& Settings::GetInstance()
|
||||
|
@ -2,23 +2,48 @@
|
||||
|
||||
#include "FieldEntry.h"
|
||||
#include "FieldSerialize.h"
|
||||
#include <cheat-base/events/event.hpp>
|
||||
#include <cheat-base/events/handlers/methodeventhandler.hpp>
|
||||
|
||||
namespace config::internal
|
||||
{
|
||||
template<typename T>
|
||||
class FieldBase
|
||||
{
|
||||
using _FieldBaseT = FieldBase<T>;
|
||||
public:
|
||||
using _ValueType = T;
|
||||
|
||||
explicit FieldBase() : p_Container(nullptr) {}
|
||||
explicit FieldBase() : p_Container(nullptr), FieldChangedEvent(m_FieldChangedEvent) {}
|
||||
|
||||
explicit FieldBase(FieldSerialize<T>* serializeFieldPtr) : p_Container(serializeFieldPtr) { }
|
||||
explicit FieldBase(FieldSerialize<T>* serializeFieldPtr) : p_Container(serializeFieldPtr), FieldChangedEvent(m_FieldChangedEvent)
|
||||
{
|
||||
p_Container->ChangedEvent += MY_METHOD_HANDLER(_FieldBaseT::OnFieldChanged);
|
||||
}
|
||||
|
||||
explicit FieldBase(const std::shared_ptr<FieldSerialize<T>>& serializeField) : p_Container(serializeField) { }
|
||||
explicit FieldBase(const std::shared_ptr<FieldSerialize<T>>& serializeField) : p_Container(serializeField), FieldChangedEvent(m_FieldChangedEvent)
|
||||
{
|
||||
p_Container->ChangedEvent += MY_METHOD_HANDLER(_FieldBaseT::OnFieldChanged);
|
||||
}
|
||||
|
||||
explicit FieldBase(const std::string friendlyName, const std::string name, const std::string section, T defaultValue, bool multiProfile = false)
|
||||
: p_Container(std::make_shared<FieldSerialize<T>>(friendlyName, name, section, defaultValue, multiProfile)) { }
|
||||
: p_Container(std::make_shared<FieldSerialize<T>>(friendlyName, name, section, defaultValue, multiProfile)), FieldChangedEvent(m_FieldChangedEvent)
|
||||
{
|
||||
p_Container->ChangedEvent += MY_METHOD_HANDLER(_FieldBaseT::OnFieldChanged);
|
||||
}
|
||||
|
||||
explicit FieldBase(const FieldBase<T>& field) :
|
||||
p_Container(field.p_Container),
|
||||
m_FieldChangedEvent(), FieldChangedEvent(m_FieldChangedEvent)
|
||||
{
|
||||
p_Container->ChangedEvent += MY_METHOD_HANDLER(FieldBase<T>::OnFieldChanged);
|
||||
}
|
||||
|
||||
~FieldBase()
|
||||
{
|
||||
if (p_Container.get() != nullptr)
|
||||
p_Container->ChangedEvent -= MY_METHOD_HANDLER(FieldBase<T>::OnFieldChanged);
|
||||
}
|
||||
|
||||
std::string name() const
|
||||
{
|
||||
@ -89,17 +114,39 @@ namespace config::internal
|
||||
|
||||
FieldBase<T>& operator=(std::shared_ptr<FieldSerialize<T>>& other)
|
||||
{
|
||||
p_Container->ChangedEvent -= MY_METHOD_HANDLER(FieldBase<T>::OnFieldChanged);
|
||||
|
||||
p_Container = other;
|
||||
p_Container->ChangedEvent += MY_METHOD_HANDLER(FieldBase<T>::OnFieldChanged);
|
||||
return *this;
|
||||
}
|
||||
|
||||
FieldBase<T>& operator=(FieldSerialize<T>* other)
|
||||
{
|
||||
p_Container->ChangedEvent -= MY_METHOD_HANDLER(FieldBase<T>::OnFieldChanged);
|
||||
|
||||
p_Container = std::make_shared<FieldSerialize<T>>(other);
|
||||
p_Container->ChangedEvent += MY_METHOD_HANDLER(FieldBase<T>::OnFieldChanged);
|
||||
return *this;
|
||||
}
|
||||
|
||||
FieldBase<T>& operator=(const FieldBase<T>& other)
|
||||
{
|
||||
p_Container = other.p_Container;
|
||||
p_Container->ChangedEvent += MY_METHOD_HANDLER(FieldBase<T>::OnFieldChanged);
|
||||
return *this;
|
||||
}
|
||||
|
||||
IEvent<T&>& FieldChangedEvent;
|
||||
|
||||
protected:
|
||||
TEvent<T&> m_FieldChangedEvent;
|
||||
|
||||
std::shared_ptr<FieldSerialize<T>> p_Container;
|
||||
void OnFieldChanged(FieldEntry* entry)
|
||||
{
|
||||
m_FieldChangedEvent(value());
|
||||
}
|
||||
|
||||
};
|
||||
}
|
@ -47,8 +47,8 @@ std::optional<ImageLoader::ImageData> ImageLoader::GetImage(const std::string& i
|
||||
return {};
|
||||
}
|
||||
|
||||
imageData.size.x = width;
|
||||
imageData.size.y = height;
|
||||
imageData.size.x = static_cast<float>(width);
|
||||
imageData.size.y = static_cast<float>(height);
|
||||
s_Textures[imageName] = imageData;
|
||||
return imageData;
|
||||
}
|
@ -214,256 +214,7 @@ bool ConfigWidget(config::Field<config::Toggle<Hotkey>>& field, const char* desc
|
||||
|
||||
#undef ShowDesc
|
||||
|
||||
// https://github.com/ocornut/imgui/issues/1496#issuecomment-655048353
|
||||
|
||||
struct GroupPanelInfo
|
||||
{
|
||||
ImRect labelRect;
|
||||
ImRect selectRect;
|
||||
};
|
||||
static ImVector<GroupPanelInfo> s_GroupPanelLabelStack;
|
||||
|
||||
bool GroupPanelIsOpen(ImGuiID id)
|
||||
{
|
||||
ImGuiContext& g = *GImGui;
|
||||
ImGuiWindow* window = g.CurrentWindow;
|
||||
ImGuiStorage* storage = window->DC.StateStorage;
|
||||
|
||||
return storage->GetInt(id, 1) != 0;
|
||||
}
|
||||
|
||||
void GroupPanelSetOpen(ImGuiID id, bool open)
|
||||
{
|
||||
ImGuiContext& g = *GImGui;
|
||||
ImGuiWindow* window = g.CurrentWindow;
|
||||
ImGuiStorage* storage = window->DC.StateStorage;
|
||||
|
||||
storage->SetInt(id, open ? 1 : 0);
|
||||
}
|
||||
|
||||
bool BeginGroupPanel(const char* name, const ImVec2& size, bool node, SelectData* selectData)
|
||||
{
|
||||
ImGuiContext& g = *GImGui;
|
||||
ImGuiWindow* window = g.CurrentWindow;
|
||||
|
||||
ImGui::PushID(name);
|
||||
ImGui::BeginGroup();
|
||||
auto cursorPos = ImGui::GetCursorScreenPos();
|
||||
|
||||
auto itemSpacing = ImGui::GetStyle().ItemSpacing;
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(0.0f, 0.0f));
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(0.0f, 0.0f));
|
||||
|
||||
auto frameHeight = ImGui::GetFrameHeight();
|
||||
ImGui::BeginGroup();
|
||||
|
||||
ImVec2 effectiveSize = size;
|
||||
if (size.x < 0.0f)
|
||||
effectiveSize.x = ImGui::GetContentRegionAvail().x;
|
||||
else
|
||||
effectiveSize.x = size.x;
|
||||
ImGui::Dummy(ImVec2(effectiveSize.x, 0.0f));
|
||||
|
||||
ImVec2 startPos = window->DC.CursorPos;
|
||||
ImGui::Dummy(ImVec2(frameHeight * 0.5f, 0.0f));
|
||||
ImGui::SameLine(0.0f, 0.0f);
|
||||
ImGui::BeginGroup();
|
||||
ImGui::Dummy(ImVec2(frameHeight * 0.5f, 0.0f));
|
||||
ImGui::SameLine(0.0f, 0.0f);
|
||||
ImGui::TextUnformatted(name);
|
||||
|
||||
auto labelMin = ImGui::GetItemRectMin();
|
||||
auto labelMax = ImGui::GetItemRectMax();
|
||||
ImGui::SameLine(0.0f, 0.0f);
|
||||
|
||||
ImVec2 selectMin = {};
|
||||
ImVec2 selectMax = {};
|
||||
if (selectData != nullptr)
|
||||
{
|
||||
bool useText = true;
|
||||
const char* selectAll = "Select all";
|
||||
auto textSize = ImGui::CalcTextSize(selectAll);
|
||||
auto spaceSize = ImVec2(effectiveSize.x - textSize.x - 35.0f - labelMax.x + startPos.x, 0.0f);
|
||||
if (spaceSize.x <= 0)
|
||||
{
|
||||
spaceSize = ImVec2(effectiveSize.x - 35.0f - labelMax.x + startPos.x, 0.0f);
|
||||
useText = false;
|
||||
}
|
||||
ImGui::Dummy(spaceSize);
|
||||
ImGui::SameLine(0.0f, 0.0f);
|
||||
|
||||
selectData->changed = ImGui::Checkbox(useText ? selectAll : "", &selectData->toggle);
|
||||
|
||||
selectMin = ImGui::GetItemRectMin();
|
||||
selectMax = ImGui::GetItemRectMax();
|
||||
}
|
||||
|
||||
ImGui::SameLine(0.0f, 0.0f);
|
||||
ImGui::Dummy(ImVec2(0.0, frameHeight + itemSpacing.y));
|
||||
|
||||
if (node)
|
||||
{
|
||||
labelMin.x = startPos.x;
|
||||
|
||||
const ImVec2 text_size = ImGui::CalcTextSize(name);
|
||||
const ImGuiID id = window->GetID(name);
|
||||
|
||||
bool isOpen = GroupPanelIsOpen(id);
|
||||
|
||||
bool hovered;
|
||||
bool toggled = ImGui::ButtonBehavior({ labelMin, labelMax }, id, &hovered, nullptr, ImGuiButtonFlags_PressedOnClick);
|
||||
if (toggled)
|
||||
{
|
||||
isOpen = !isOpen;
|
||||
GroupPanelSetOpen(id, isOpen);
|
||||
}
|
||||
|
||||
const ImU32 text_col = ImGui::GetColorU32(ImGuiCol_Text);
|
||||
ImGui::RenderArrow(window->DrawList, { cursorPos.x, cursorPos.y + text_size.y * 0.15f }, text_col,
|
||||
isOpen ? ImGuiDir_Down : ImGuiDir_Right, 0.7f);
|
||||
|
||||
if (!isOpen)
|
||||
{
|
||||
ImGui::PopStyleVar(2);
|
||||
ImGui::EndGroup();
|
||||
ImGui::EndGroup();
|
||||
ImGui::EndGroup();
|
||||
ImGui::PopID();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
ImGui::BeginGroup();
|
||||
|
||||
//ImGui::GetWindowDrawList()->AddRect(labelMin, labelMax, IM_COL32(255, 0, 255, 255));
|
||||
|
||||
ImGui::PopStyleVar(2);
|
||||
|
||||
#if IMGUI_VERSION_NUM >= 17301
|
||||
ImGui::GetCurrentWindow()->ContentRegionRect.Max.x -= frameHeight * 0.5f;
|
||||
ImGui::GetCurrentWindow()->WorkRect.Max.x -= frameHeight * 0.5f;
|
||||
ImGui::GetCurrentWindow()->InnerRect.Max.x -= frameHeight * 0.5f;
|
||||
#else
|
||||
ImGui::GetCurrentWindow()->ContentsRegionRect.Max.x -= frameHeight * 0.5f;
|
||||
#endif
|
||||
ImGui::GetCurrentWindow()->Size.x -= frameHeight;
|
||||
|
||||
auto itemWidth = ImGui::CalcItemWidth();
|
||||
ImGui::PushItemWidth(ImMax(0.0f, itemWidth - frameHeight));
|
||||
|
||||
s_GroupPanelLabelStack.push_back({ ImRect(labelMin, labelMax) , ImRect(selectMin, selectMax)});
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void EndGroupPanel()
|
||||
{
|
||||
ImGui::PopItemWidth();
|
||||
|
||||
auto itemSpacing = ImGui::GetStyle().ItemSpacing;
|
||||
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(0.0f, 0.0f));
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(0.0f, 0.0f));
|
||||
|
||||
auto frameHeight = ImGui::GetFrameHeight();
|
||||
|
||||
ImGui::EndGroup();
|
||||
|
||||
//ImGui::GetWindowDrawList()->AddRectFilled(ImGui::GetItemRectMin(), ImGui::GetItemRectMax(), IM_COL32(0, 255, 0, 64), 4.0f);
|
||||
|
||||
ImGui::EndGroup();
|
||||
|
||||
ImGui::SameLine(0.0f, 0.0f);
|
||||
ImGui::Dummy(ImVec2(frameHeight * 0.5f, 0.0f));
|
||||
ImGui::Dummy(ImVec2(0.0, frameHeight - frameHeight * 0.5f - itemSpacing.y));
|
||||
|
||||
ImGui::EndGroup();
|
||||
|
||||
auto itemMin = ImGui::GetItemRectMin();
|
||||
auto itemMax = ImGui::GetItemRectMax();
|
||||
//ImGui::GetWindowDrawList()->AddRectFilled(itemMin, itemMax, IM_COL32(255, 0, 0, 64), 4.0f);
|
||||
|
||||
auto& info = s_GroupPanelLabelStack.back();
|
||||
s_GroupPanelLabelStack.pop_back();
|
||||
|
||||
ImVec2 halfFrame = ImVec2(frameHeight * 0.25f, frameHeight) * 0.5f;
|
||||
ImRect frameRect = ImRect(itemMin + halfFrame, itemMax - ImVec2(halfFrame.x, 0.0f));
|
||||
|
||||
auto& labelRect = info.labelRect;
|
||||
labelRect.Min.x -= itemSpacing.x;
|
||||
labelRect.Max.x += itemSpacing.x;
|
||||
|
||||
bool hasSelect = info.selectRect.Min.x != 0;
|
||||
|
||||
if (!hasSelect)
|
||||
{
|
||||
for (int i = 0; i < 3; ++i)
|
||||
{
|
||||
switch (i)
|
||||
{
|
||||
// left half-plane
|
||||
case 0: ImGui::PushClipRect(ImVec2(-FLT_MAX, -FLT_MAX), ImVec2(labelRect.Min.x, FLT_MAX), true); break;
|
||||
// right half-plane
|
||||
case 1: ImGui::PushClipRect(ImVec2(labelRect.Max.x, -FLT_MAX), ImVec2(FLT_MAX, FLT_MAX), true); break;
|
||||
// bottom
|
||||
case 2: ImGui::PushClipRect(ImVec2(labelRect.Min.x, labelRect.Max.y), ImVec2(labelRect.Max.x, FLT_MAX), true); break;
|
||||
}
|
||||
|
||||
ImGui::GetWindowDrawList()->AddRect(
|
||||
frameRect.Min, frameRect.Max,
|
||||
ImColor(ImGui::GetStyleColorVec4(ImGuiCol_Border)),
|
||||
halfFrame.x);
|
||||
|
||||
ImGui::PopClipRect();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
auto& selectRect = info.selectRect;
|
||||
selectRect.Min.x -= itemSpacing.x;
|
||||
selectRect.Max.x += itemSpacing.x;
|
||||
for (int i = 0; i < 5; ++i)
|
||||
{
|
||||
switch (i)
|
||||
{
|
||||
// left half-plane
|
||||
case 0: ImGui::PushClipRect(ImVec2(-FLT_MAX, -FLT_MAX), ImVec2(labelRect.Min.x, FLT_MAX), true); break;
|
||||
// label - select
|
||||
case 1: ImGui::PushClipRect(ImVec2(labelRect.Max.x, -FLT_MAX), ImVec2(selectRect.Min.x, FLT_MAX), true); break;
|
||||
// bottom label
|
||||
case 2: ImGui::PushClipRect(ImVec2(labelRect.Min.x, labelRect.Max.y), ImVec2(labelRect.Max.x, FLT_MAX), true); break;
|
||||
// bottom select
|
||||
case 3: ImGui::PushClipRect(ImVec2(selectRect.Min.x, selectRect.Max.y), ImVec2(selectRect.Max.x, FLT_MAX), true); break;
|
||||
// right hand-plane
|
||||
case 4: ImGui::PushClipRect(ImVec2(selectRect.Max.x, -FLT_MAX), ImVec2(FLT_MAX, FLT_MAX), true); break;
|
||||
}
|
||||
|
||||
ImGui::GetWindowDrawList()->AddRect(
|
||||
frameRect.Min, frameRect.Max,
|
||||
ImColor(ImGui::GetStyleColorVec4(ImGuiCol_Border)),
|
||||
halfFrame.x);
|
||||
|
||||
ImGui::PopClipRect();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
ImGui::PopStyleVar(2);
|
||||
|
||||
#if IMGUI_VERSION_NUM >= 17301
|
||||
ImGui::GetCurrentWindow()->ContentRegionRect.Max.x += frameHeight * 0.5f;
|
||||
ImGui::GetCurrentWindow()->WorkRect.Max.x += frameHeight * 0.5f;
|
||||
ImGui::GetCurrentWindow()->InnerRect.Max.x += frameHeight * 0.5f;
|
||||
#else
|
||||
ImGui::GetCurrentWindow()->ContentsRegionRect.Max.x += frameHeight * 0.5f;
|
||||
#endif
|
||||
ImGui::GetCurrentWindow()->Size.x += frameHeight;
|
||||
|
||||
ImGui::Dummy(ImVec2(0.0f, 0.0f));
|
||||
|
||||
ImGui::EndGroup();
|
||||
ImGui::PopID();
|
||||
}
|
||||
|
||||
void AddUnderLine(ImColor col_)
|
||||
{
|
||||
@ -663,8 +414,8 @@ float ImGui::CalcContrastRatio(const ImU32& backgroundColor, const ImU32& foreGr
|
||||
float lumFG = 0.2126 * colFG.x + 0.7152 * colFG.y + 0.0722 * colFG.z;
|
||||
return (ImMax(lumBG, lumFG) + 0.05) / (ImMin(lumBG, lumFG) + 0.05);*/
|
||||
|
||||
float sa0 = ((backgroundColor >> IM_COL32_A_SHIFT) & 0xFF);
|
||||
float sa1 = ((foreGroundColor >> IM_COL32_A_SHIFT) & 0xFF);
|
||||
float sa0 = static_cast<float>((backgroundColor >> IM_COL32_A_SHIFT) & 0xFF);
|
||||
float sa1 = static_cast<float>((foreGroundColor >> IM_COL32_A_SHIFT) & 0xFF);
|
||||
static float sr = 0.2126f / 255.0f;
|
||||
static float sg = 0.7152f / 255.0f;
|
||||
static float sb = 0.0722f / 255.0f;
|
||||
@ -738,3 +489,264 @@ bool ImGui::DrawRenamePopup(std::string& out)
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
namespace ImGui
|
||||
{
|
||||
struct GroupPanelHeaderBounds
|
||||
{
|
||||
ImRect left;
|
||||
ImRect right;
|
||||
bool collapsed;
|
||||
};
|
||||
|
||||
static ImVector<GroupPanelHeaderBounds> _groupPanelStack;
|
||||
|
||||
static bool GroupPanelIsOpen(ImGuiID id)
|
||||
{
|
||||
ImGuiContext& g = *GImGui;
|
||||
ImGuiWindow* window = g.CurrentWindow;
|
||||
ImGuiStorage* storage = window->DC.StateStorage;
|
||||
|
||||
return storage->GetInt(id, 1) != 0;
|
||||
}
|
||||
|
||||
static void GroupPanelSetOpen(ImGuiID id, bool open)
|
||||
{
|
||||
ImGuiContext& g = *GImGui;
|
||||
ImGuiWindow* window = g.CurrentWindow;
|
||||
ImGuiStorage* storage = window->DC.StateStorage;
|
||||
|
||||
storage->SetInt(id, open ? 1 : 0);
|
||||
}
|
||||
|
||||
// Modified version of: https://github.com/ocornut/imgui/issues/1496#issuecomment-655048353
|
||||
|
||||
bool BeginGroupPanel(const char* label, bool node, const ImVec2& size)
|
||||
{
|
||||
ImGuiContext& g = *GImGui;
|
||||
ImGuiWindow* window = g.CurrentWindow;
|
||||
|
||||
const ImGuiID id = window->GetID(label);
|
||||
ImGui::PushID(id);
|
||||
|
||||
auto groupPanelPos = window->DC.CursorPos;
|
||||
auto itemSpacing = ImGui::GetStyle().ItemSpacing;
|
||||
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(0.0f, 0.0f));
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(0.0f, 0.0f));
|
||||
|
||||
ImGui::BeginGroup(); // Outer group
|
||||
|
||||
ImVec2 effectiveSize = size;
|
||||
if (size.x < 0.0f)
|
||||
effectiveSize.x = ImGui::GetContentRegionAvail().x;
|
||||
else
|
||||
effectiveSize.x = size.x;
|
||||
|
||||
ImGui::Dummy(ImVec2(effectiveSize.x, 0.0f)); // Adjusting group x size
|
||||
|
||||
auto frameHeight = ImGui::GetFrameHeight();
|
||||
ImGui::Dummy(ImVec2(frameHeight * 0.5f, 0.0f)); ImGui::SameLine(0.0f, 0.0f); // Inner group spacing
|
||||
ImGui::BeginGroup(); // Inner group
|
||||
|
||||
ImGui::Dummy(ImVec2(frameHeight * 0.5f, 0.0f)); ImGui::SameLine(0.0f, 0.0f); // Name text spacing
|
||||
ImGui::TextUnformatted(label);
|
||||
|
||||
ImRect leftRect = { ImGui::GetItemRectMin(), ImGui::GetItemRectMax() };
|
||||
ImVec2 rightMax = ImVec2(groupPanelPos.x + effectiveSize.x - frameHeight, leftRect.Max.y);
|
||||
ImRect rightRect = { { rightMax.x, leftRect.Min.x }, rightMax };
|
||||
ImGui::SameLine(0.0f, 0.0f);
|
||||
|
||||
ImGui::Dummy(ImVec2(0.0, frameHeight + itemSpacing.y));
|
||||
|
||||
if (node)
|
||||
{
|
||||
leftRect.Min.x = groupPanelPos.x;
|
||||
|
||||
const ImVec2 text_size = ImGui::CalcTextSize(label);
|
||||
bool isOpen = GroupPanelIsOpen(id);
|
||||
|
||||
bool hovered;
|
||||
bool toggled = ImGui::ButtonBehavior(leftRect, id, &hovered, nullptr, ImGuiButtonFlags_PressedOnClick);
|
||||
if (toggled)
|
||||
{
|
||||
isOpen = !isOpen;
|
||||
GroupPanelSetOpen(id, isOpen);
|
||||
}
|
||||
|
||||
const ImU32 text_col = ImGui::GetColorU32(ImGuiCol_Text);
|
||||
ImGui::RenderArrow(window->DrawList, { groupPanelPos.x, groupPanelPos.y + text_size.y * 0.15f }, text_col,
|
||||
isOpen ? ImGuiDir_Down : ImGuiDir_Right, 0.7f);
|
||||
|
||||
if (!isOpen)
|
||||
{
|
||||
ImGui::PopStyleVar(2);
|
||||
ImGui::EndGroup();
|
||||
ImGui::EndGroup();
|
||||
ImGui::PopID();
|
||||
|
||||
_groupPanelStack.push_back({ leftRect, rightRect, true });
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
ImGui::PopStyleVar(2);
|
||||
|
||||
ImGui::GetCurrentWindow()->ContentRegionRect.Max.x -= frameHeight * 0.5f;
|
||||
ImGui::GetCurrentWindow()->WorkRect.Max.x -= frameHeight * 0.5f;
|
||||
ImGui::GetCurrentWindow()->InnerRect.Max.x -= frameHeight * 0.5f;
|
||||
ImGui::GetCurrentWindow()->Size.x -= frameHeight;
|
||||
|
||||
auto itemWidth = ImGui::CalcItemWidth();
|
||||
ImGui::PushItemWidth(ImMax(0.0f, itemWidth - frameHeight));
|
||||
|
||||
_groupPanelStack.push_back({ leftRect, rightRect, false });
|
||||
return true;
|
||||
}
|
||||
|
||||
void EndGroupPanel()
|
||||
{
|
||||
IM_ASSERT(_groupPanelStack.Size > 0); // Mismatched BeginGroupPanel()/EndGroupPanel() calls
|
||||
auto& info = _groupPanelStack.back();
|
||||
_groupPanelStack.pop_back();
|
||||
|
||||
if (info.collapsed)
|
||||
return;
|
||||
|
||||
ImGui::PopItemWidth();
|
||||
|
||||
auto itemSpacing = ImGui::GetStyle().ItemSpacing;
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(0.0f, 0.0f));
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(0.0f, 0.0f));
|
||||
|
||||
ImGui::EndGroup(); // Inner group
|
||||
|
||||
auto frameHeight = ImGui::GetFrameHeight();
|
||||
ImGui::SameLine(0.0f, 0.0f);
|
||||
ImGui::Dummy(ImVec2(frameHeight * 0.5f, 0.0f));
|
||||
ImGui::Dummy(ImVec2(0.0, frameHeight - frameHeight * 0.5f - itemSpacing.y));
|
||||
|
||||
ImGui::EndGroup(); // Outer group
|
||||
|
||||
// Outer group rect
|
||||
auto itemMin = ImGui::GetItemRectMin();
|
||||
auto itemMax = ImGui::GetItemRectMax();
|
||||
|
||||
ImVec2 halfFrame = ImVec2(frameHeight * 0.25f, frameHeight) * 0.5f;
|
||||
ImRect frameRect = ImRect(itemMin + halfFrame, itemMax - ImVec2(halfFrame.x, 0.0f));
|
||||
|
||||
auto& leftRect = info.left;
|
||||
leftRect.Min.x -= itemSpacing.x;
|
||||
leftRect.Max.x += itemSpacing.x;
|
||||
|
||||
bool hasRightPart = info.right.Min.x != info.right.Max.x;
|
||||
auto& rightRect = info.right;
|
||||
|
||||
if (hasRightPart)
|
||||
{
|
||||
rightRect.Min.x -= itemSpacing.x;
|
||||
rightRect.Max.x += itemSpacing.x;
|
||||
}
|
||||
|
||||
// Drawing rectangle
|
||||
for (int i = 0; i < (hasRightPart ? 5 : 3); ++i)
|
||||
{
|
||||
switch (i)
|
||||
{
|
||||
// left half-plane
|
||||
case 0: ImGui::PushClipRect(ImVec2(-FLT_MAX, -FLT_MAX), ImVec2(leftRect.Min.x, FLT_MAX), true); break;
|
||||
// right half-plane
|
||||
case 1: ImGui::PushClipRect(ImVec2(leftRect.Max.x, -FLT_MAX), ImVec2(hasRightPart ? rightRect.Min.x : FLT_MAX, FLT_MAX), true); break;
|
||||
// bottom
|
||||
case 2: ImGui::PushClipRect(ImVec2(leftRect.Min.x, leftRect.Max.y), ImVec2(leftRect.Max.x, FLT_MAX), true); break;
|
||||
// bottom select
|
||||
case 3: ImGui::PushClipRect(ImVec2(rightRect.Min.x, rightRect.Max.y), ImVec2(rightRect.Max.x, FLT_MAX), true); break;
|
||||
// right hand-plane
|
||||
case 4: ImGui::PushClipRect(ImVec2(rightRect.Max.x, -FLT_MAX), ImVec2(FLT_MAX, FLT_MAX), true); break;
|
||||
}
|
||||
|
||||
ImGui::GetWindowDrawList()->AddRect(
|
||||
frameRect.Min, frameRect.Max,
|
||||
ImColor(ImGui::GetStyleColorVec4(ImGuiCol_Border)),
|
||||
halfFrame.x);
|
||||
|
||||
ImGui::PopClipRect();
|
||||
}
|
||||
|
||||
|
||||
ImGui::PopStyleVar(2);
|
||||
|
||||
// Restore content region
|
||||
ImGui::GetCurrentWindow()->ContentRegionRect.Max.x += frameHeight * 0.5f;
|
||||
ImGui::GetCurrentWindow()->WorkRect.Max.x += frameHeight * 0.5f;
|
||||
ImGui::GetCurrentWindow()->InnerRect.Max.x += frameHeight * 0.5f;
|
||||
ImGui::GetCurrentWindow()->Size.x += frameHeight;
|
||||
|
||||
// Add vertical spacing
|
||||
ImGui::Dummy(ImVec2(0.0f, 0.0f));
|
||||
|
||||
ImGui::PopID();
|
||||
}
|
||||
|
||||
void NextGroupPanelHeaderItem(const ImVec2& size, bool rightAlign)
|
||||
{
|
||||
IM_ASSERT(size.x > 0.0f); // Size should be specified
|
||||
IM_ASSERT(_groupPanelStack.Size > 0); // Mismatched BeginGroupPanel()/EndGroupPanel() calls
|
||||
auto& info = _groupPanelStack.back();
|
||||
|
||||
ImGuiContext& g = *GImGui;
|
||||
ImGuiWindow* window = g.CurrentWindow;
|
||||
|
||||
if (rightAlign)
|
||||
{
|
||||
if (info.right.Min.x != info.right.Max.x)
|
||||
info.right.Min.x -= g.Style.ItemSpacing.x;
|
||||
|
||||
info.right.Min.x -= size.x;
|
||||
}
|
||||
else
|
||||
info.left.Max.x += g.Style.ItemSpacing.x;
|
||||
|
||||
window->DC.CursorPos.x = rightAlign ? info.right.Min.x : info.left.Max.x;
|
||||
window->DC.CursorPos.y = info.left.Min.y - (size.y - ImGui::GetFrameHeight() + g.Style.FramePadding.y) / 2;
|
||||
|
||||
if (!rightAlign)
|
||||
info.left.Max.x += size.x;
|
||||
}
|
||||
|
||||
bool BeginSelectableGroupPanel(const char* label, bool& value, bool& changed, bool node, const ImVec2& size, const char* selectLabel)
|
||||
{
|
||||
bool opened = BeginGroupPanel(label, node, size);
|
||||
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(0.0f, 0.0f));
|
||||
|
||||
ImGuiContext& g = *GImGui;
|
||||
const ImGuiStyle& style = g.Style;
|
||||
|
||||
const ImVec2 label_size = CalcTextSize(selectLabel, NULL, true);
|
||||
const float square_sz = GetFrameHeight();
|
||||
const ImVec2 checkbox_size = ImVec2(square_sz + (label_size.x > 0.0f ? style.ItemInnerSpacing.x + label_size.x : 0.0f), label_size.y + style.FramePadding.y * 2.0f);
|
||||
|
||||
NextGroupPanelHeaderItem(checkbox_size, true);
|
||||
changed = Checkbox(selectLabel, &value);
|
||||
|
||||
ImGui::PopStyleVar();
|
||||
return opened;
|
||||
}
|
||||
|
||||
void EndSelectableGroupPanel()
|
||||
{
|
||||
EndGroupPanel();
|
||||
}
|
||||
|
||||
ImVec2 CalcButtonSize(const char* label)
|
||||
{
|
||||
const ImVec2 label_size = CalcTextSize(label, NULL, true);
|
||||
|
||||
ImGuiContext& g = *GImGui;
|
||||
const ImGuiStyle& style = g.Style;
|
||||
ImVec2 size = CalcItemSize({}, label_size.x + style.FramePadding.x * 2.0f, label_size.y + style.FramePadding.y * 2.0f);
|
||||
return size;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -81,16 +81,6 @@ void DrawTextWithOutline(ImDrawList* drawList, ImFont* font, float fontSize, con
|
||||
void DrawTextWithOutline(ImDrawList* drawList, const ImVec2& screenPos, const char* text, const ImColor& textColor,
|
||||
float outlineThickness = 0.0f, OutlineSide sides = OutlineSide::All, const ImColor& outlineColor = ImColor(0.0f, 0.0f, 0.0f));
|
||||
|
||||
|
||||
struct SelectData
|
||||
{
|
||||
bool toggle;
|
||||
bool changed;
|
||||
};
|
||||
|
||||
bool BeginGroupPanel(const char* name, const ImVec2& size = ImVec2(-1, 0), bool node = false, SelectData* selectData = nullptr);
|
||||
void EndGroupPanel();
|
||||
|
||||
namespace ImGui
|
||||
{
|
||||
bool HotkeyWidget(const char* label, Hotkey& hotkey, const ImVec2& size = ImVec2(0, 0));
|
||||
@ -102,6 +92,16 @@ namespace ImGui
|
||||
void OpenRenamePopup(const std::string& initName);
|
||||
bool IsRenamePopupOpened();
|
||||
bool DrawRenamePopup(std::string& out);
|
||||
|
||||
bool BeginGroupPanel(const char* label, bool node = false, const ImVec2& size = ImVec2(-1.0f, 0.0f));
|
||||
void EndGroupPanel();
|
||||
|
||||
bool BeginSelectableGroupPanel(const char* label, bool& value, bool& changed, bool node = false, const ImVec2& size = ImVec2(-1.0f, 0.0f), const char* selectLabel = "Select");
|
||||
void EndSelectableGroupPanel();
|
||||
|
||||
void NextGroupPanelHeaderItem(const ImVec2& size, bool rightAlign = false);
|
||||
|
||||
ImVec2 CalcButtonSize(const char* label);
|
||||
}
|
||||
|
||||
float CalcWidth(const std::string_view& view);
|
||||
@ -116,18 +116,29 @@ float GetMaxEnumWidth()
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
bool ComboEnum(const char* label, T* currentValue)
|
||||
bool ComboEnum(const char* label, T* currentValue, std::vector<T>* whitelist = nullptr)
|
||||
{
|
||||
auto name = magic_enum::enum_name(*currentValue);
|
||||
auto& current = *currentValue;
|
||||
bool result = false;
|
||||
static auto width = GetMaxEnumWidth<T>();
|
||||
|
||||
std::unordered_set<T> whiteSet;
|
||||
if (whitelist != nullptr)
|
||||
{
|
||||
for (auto& value : *whitelist)
|
||||
{
|
||||
whiteSet.insert(value);
|
||||
}
|
||||
}
|
||||
ImGui::SetNextItemWidth(width);
|
||||
if (ImGui::BeginCombo(label, name.data()))
|
||||
{
|
||||
for (auto& entry : magic_enum::enum_entries<T>())
|
||||
{
|
||||
if (whitelist != nullptr && whiteSet.count(entry.first) == 0)
|
||||
continue;
|
||||
|
||||
bool is_selected = (name == entry.second);
|
||||
if (ImGui::Selectable(entry.second.data(), is_selected))
|
||||
{
|
||||
|
@ -122,7 +122,7 @@ namespace renderer
|
||||
for (int i = 0; i < _fontsCount; i++)
|
||||
{
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
auto newFont = io.Fonts->AddFontFromMemoryTTF(_customFontData.data, _customFontData.size, (i + 1) * _fontSizeStep);
|
||||
auto newFont = io.Fonts->AddFontFromMemoryTTF(_customFontData.data, _customFontData.size, static_cast<float>((i + 1) * _fontSizeStep));
|
||||
if (newFont == nullptr)
|
||||
return;
|
||||
|
||||
@ -185,8 +185,8 @@ namespace renderer
|
||||
POINT mPos;
|
||||
GetCursorPos(&mPos);
|
||||
ScreenToClient(hWnd, &mPos);
|
||||
ImGui::GetIO().MousePos.x = mPos.x;
|
||||
ImGui::GetIO().MousePos.y = mPos.y;
|
||||
ImGui::GetIO().MousePos.x = static_cast<float>(mPos.x);
|
||||
ImGui::GetIO().MousePos.y = static_cast<float>(mPos.y);
|
||||
|
||||
ImGui_ImplWin32_WndProcHandler(hWnd, uMsg, wParam, lParam);
|
||||
|
||||
@ -210,7 +210,7 @@ namespace renderer
|
||||
key = GET_XBUTTON_WPARAM(wParam);
|
||||
break;
|
||||
case WM_KEYUP:
|
||||
key = wParam;
|
||||
key = static_cast<short>(wParam);
|
||||
break;
|
||||
default:
|
||||
keyUpEvent = false;
|
||||
|
@ -222,7 +222,7 @@ namespace util
|
||||
}
|
||||
|
||||
std::vector<BYTE> base64_decode(std::string const& encoded_string) {
|
||||
int in_len = encoded_string.size();
|
||||
size_t in_len = encoded_string.size();
|
||||
int i = 0;
|
||||
int j = 0;
|
||||
int in_ = 0;
|
||||
@ -233,7 +233,7 @@ namespace util
|
||||
char_array_4[i++] = encoded_string[in_]; in_++;
|
||||
if (i == 4) {
|
||||
for (i = 0; i < 4; i++)
|
||||
char_array_4[i] = base64_chars.find(char_array_4[i]);
|
||||
char_array_4[i] = static_cast<BYTE>(base64_chars.find(char_array_4[i])); // base64_chars len < 255
|
||||
|
||||
char_array_3[0] = (char_array_4[0] << 2) + ((char_array_4[1] & 0x30) >> 4);
|
||||
char_array_3[1] = ((char_array_4[1] & 0xf) << 4) + ((char_array_4[2] & 0x3c) >> 2);
|
||||
@ -250,7 +250,7 @@ namespace util
|
||||
char_array_4[j] = 0;
|
||||
|
||||
for (j = 0; j < 4; j++)
|
||||
char_array_4[j] = base64_chars.find(char_array_4[j]);
|
||||
char_array_4[j] = static_cast<BYTE>(base64_chars.find(char_array_4[j]));
|
||||
|
||||
char_array_3[0] = (char_array_4[0] << 2) + ((char_array_4[1] & 0x30) >> 4);
|
||||
char_array_3[1] = ((char_array_4[1] & 0xf) << 4) + ((char_array_4[2] & 0x3c) >> 2);
|
||||
@ -261,4 +261,13 @@ namespace util
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int64_t GetTimezoneBias()
|
||||
{
|
||||
_TIME_ZONE_INFORMATION timezoneInfo{};
|
||||
if (GetTimeZoneInformation(&timezoneInfo) == TIME_ZONE_ID_INVALID)
|
||||
LOG_LAST_ERROR("Failed to get timezone.");
|
||||
|
||||
return static_cast<int64_t>(timezoneInfo.Bias) * 60;
|
||||
}
|
||||
}
|
@ -42,6 +42,8 @@ namespace util
|
||||
std::string base64_encode(BYTE const* buf, unsigned int bufLen);
|
||||
std::vector<BYTE> base64_decode(std::string const&);
|
||||
|
||||
int64_t GetTimezoneBias();
|
||||
|
||||
|
||||
template<typename ... Args>
|
||||
std::string string_format(const std::string& format, Args ... args)
|
||||
|
2
cheat-base/vendor/imgui
vendored
2
cheat-base/vendor/imgui
vendored
Submodule cheat-base/vendor/imgui updated: af916cdf1a...47fb633e73
Reference in New Issue
Block a user