Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added back ImGui MKB Input functions, and added new "Overlay Hotkey" category (Issue #957) #958

Binary file added log.txt
Binary file not shown.
2 changes: 1 addition & 1 deletion src/VKBindings.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -677,7 +677,7 @@ void VKBindings::ExecuteRecording()
// binding state! only exception allowed is any CET bind
const auto& overlayToggleModBind = Bindings::GetOverlayToggleModBind();
const auto cetModBind = modBind.ModName == overlayToggleModBind.ModName;
if (!cetModBind && (!m_cpVm->IsInitialized() || CET::Get().GetOverlay().IsEnabled()))
if (!cetModBind && (!m_cpVm->IsInitialized() || CET::Get().GetOverlay().IsEnabled() != vkBind->m_isOverlayHotkey))
return;

// this handler is not for inputs! it should be used only on key up event for hotkeys!
Expand Down
1 change: 1 addition & 0 deletions src/VKBindings.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ struct VKBind
std::string DisplayName{};
std::variant<std::string, std::function<void()>> Description{};
std::variant<std::function<TVKBindHotkeyCallback>, std::function<TVKBindInputCallback>> Handler{};
bool m_isOverlayHotkey{false};

[[nodiscard]] std::function<void()> DelayedCall(const bool acIsDown) const;
void Call(const bool acIsDown) const;
Expand Down
66 changes: 47 additions & 19 deletions src/overlay/widgets/Bindings.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -234,15 +234,18 @@ void Bindings::Initialize()

// emplace CET internal settings
{
auto& [vkBindInfos, hotkeyCount] = m_vkBindInfos[s_overlayToggleModBind.ModName];
auto& [vkBindInfos, hotkeyCounts] = m_vkBindInfos[s_overlayToggleModBind.ModName];
auto& [hotkeyCount, overlayHotkeyCount] = hotkeyCounts;
vkBindInfos.emplace_back(s_overlayToggleBindInfo);
hotkeyCount = 1;
overlayHotkeyCount = 0;
}

// emplace mod bindings
for (const auto& modBindsIt : allModsBinds)
{
auto& [vkBindInfos, hotkeyCount] = m_vkBindInfos[modBindsIt.first];
auto& [vkBindInfos, hotkeyCounts] = m_vkBindInfos[modBindsIt.first];
auto& [hotkeyCount, overlayHotkeyCount] = hotkeyCounts;
hotkeyCount = 0;
for (const auto& vkBind : modBindsIt.second.get())
{
Expand All @@ -252,6 +255,8 @@ void Bindings::Initialize()

if (vkBind.IsHotkey())
++hotkeyCount;
if (vkBind.m_isOverlayHotkey)
++overlayHotkeyCount;
}
}

Expand Down Expand Up @@ -433,7 +438,7 @@ void Bindings::UpdateAndDrawBinding(const VKModBind& acModBind, VKBindInfo& aVKB
m_madeChanges |= aVKBindInfo.IsBinding || aVKBindInfo.CodeBind != aVKBindInfo.SavedCodeBind;
}

void Bindings::UpdateAndDrawModBindings(const std::string& acModName, TiltedPhoques::Vector<VKBindInfo>& aVKBindInfos, size_t aHotkeyCount, bool aSimplified)
void Bindings::UpdateAndDrawModBindings(const std::string& acModName, TiltedPhoques::Vector<VKBindInfo>& aVKBindInfos, std::pair<size_t, size_t> aHotkeyCounts, bool aSimplified)
{
if (aVKBindInfos.empty())
return;
Expand Down Expand Up @@ -467,31 +472,54 @@ void Bindings::UpdateAndDrawModBindings(const std::string& acModName, TiltedPhoq

ImGui::TreePush();

if (aHotkeyCount > 0)
if (aHotkeyCounts.first > 0)
{
if (!aSimplified)
{
ImGui::SetCursorPosX(ImGui::GetCursorPosX() + GetCenteredOffsetForText("Hotkeys"));
ImGui::TextUnformatted("Hotkeys");
if (ImGui::IsItemHovered(ImGuiHoveredFlags_AllowWhenDisabled))
ImGui::SetTooltip("Hotkeys react after assigned key combination has been pressed and subsequently "
"released. You can bind up to 4 key combination to them.");
ImGui::Separator();
}

if (ImGui::BeginTable(("##HOTKEYS_" + activeModName).c_str(), 2, ImGuiTableFlags_Sortable | ImGuiTableFlags_SizingStretchSame, ImVec2(-ImGui::GetStyle().IndentSpacing, 0)))
{
for (auto& binding : aVKBindInfos)
if (aHotkeyCounts.first - aHotkeyCounts.second > 0)
{
if (binding.Bind.IsHotkey())
UpdateAndDrawBinding({acModName, binding.Bind.ID}, binding);
ImGui::SetCursorPosX(ImGui::GetCursorPosX() + GetCenteredOffsetForText("Hotkeys"));
ImGui::TextUnformatted("Hotkeys");
if (ImGui::IsItemHovered(ImGuiHoveredFlags_AllowWhenDisabled))
ImGui::SetTooltip("Hotkeys react after assigned key combination has been pressed and subsequently "
"released. You can bind up to 4 key combination to them.");
ImGui::Separator();

if (ImGui::BeginTable(("##HOTKEYS_" + activeModName).c_str(), 2, ImGuiTableFlags_Sortable | ImGuiTableFlags_SizingStretchSame, ImVec2(-ImGui::GetStyle().IndentSpacing, 0)))
{
for (auto& binding : aVKBindInfos)
{
if (binding.Bind.IsHotkey() && !binding.Bind.m_isOverlayHotkey)
UpdateAndDrawBinding({acModName, binding.Bind.ID}, binding);
}

ImGui::EndTable();
}
}
if (aHotkeyCounts.second > 0)
{
ImGui::SetCursorPosX(ImGui::GetCursorPosX() + GetCenteredOffsetForText("Overlay Hotkeys"));
ImGui::TextUnformatted("Overlay Hotkeys");
if (ImGui::IsItemHovered(ImGuiHoveredFlags_AllowWhenDisabled))
ImGui::SetTooltip("Overlay Hotkeys react after assigned key combination has been pressed and subsequently "
"released. You can bind up to 4 key combination to them.\n Unlike regular Hotkeys, these only work while the CET Overlay is open");
ImGui::Separator();

if (ImGui::BeginTable(("##OVERLAY_HOTKEYS_" + activeModName).c_str(), 2, ImGuiTableFlags_Sortable | ImGuiTableFlags_SizingStretchSame, ImVec2(-ImGui::GetStyle().IndentSpacing, 0)))
{
for (auto& binding : aVKBindInfos)
{
if (binding.Bind.IsHotkey() && binding.Bind.m_isOverlayHotkey)
UpdateAndDrawBinding({acModName, binding.Bind.ID}, binding);
}

ImGui::EndTable();
ImGui::EndTable();
}
}
}
}

if (aHotkeyCount < aVKBindInfos.size())
if (aHotkeyCounts.first < aVKBindInfos.size())
{
if (!aSimplified)
{
Expand Down
4 changes: 2 additions & 2 deletions src/overlay/widgets/Bindings.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,9 +37,9 @@ struct Bindings : Widget
private:
void Initialize();
void UpdateAndDrawBinding(const VKModBind& acModBind, VKBindInfo& aVKBindInfo);
void UpdateAndDrawModBindings(const std::string& acModName, TiltedPhoques::Vector<VKBindInfo>& aVKBindInfos, size_t aHotkeyCount, bool aSimplified = false);
void UpdateAndDrawModBindings(const std::string& acModName, TiltedPhoques::Vector<VKBindInfo>& aVKBindInfos, std::pair<size_t, size_t> aHotkeyCounts, bool aSimplified = false);

TiltedPhoques::Map<std::string, std::pair<TiltedPhoques::Vector<VKBindInfo>, size_t>> m_vkBindInfos{};
TiltedPhoques::Map<std::string, std::pair<TiltedPhoques::Vector<VKBindInfo>, std::pair<size_t, size_t>>> m_vkBindInfos{};
VKBindings& m_bindings;
LuaVM& m_vm;

Expand Down
24 changes: 16 additions & 8 deletions src/scripting/ScriptContext.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ ScriptContext::ScriptContext(LuaSandbox& aLuaSandbox, const std::filesystem::pat

auto registerBinding = [this, &wrapHandler, &wrapDescription](
const std::string& acID, const std::string& acDisplayName, const std::variant<std::string, sol::function>& acDescription, sol::function aCallback,
const bool acIsHotkey)
const bool acIsHotkey, const bool acIsOverlayHotkey)
{
const auto inputTypeStr = acIsHotkey ? "hotkey" : "input";

Expand Down Expand Up @@ -146,22 +146,29 @@ ScriptContext::ScriptContext(LuaSandbox& aLuaSandbox, const std::filesystem::pat
return;
}

m_vkBinds.emplace_back(acID, acDisplayName, wrapDescription(acDescription), wrapHandler(aCallback, acIsHotkey));
m_vkBinds.emplace_back(acID, acDisplayName, wrapDescription(acDescription), wrapHandler(aCallback, acIsHotkey), acIsOverlayHotkey);
};

env["registerHotkey"] = sol::overload(
[&registerBinding](const std::string& acID, const std::string& acDisplayName, sol::function acDescriptionCallback, sol::function aCallback)
{ registerBinding(acID, acDisplayName, acDescriptionCallback, aCallback, true); },
{ registerBinding(acID, acDisplayName, acDescriptionCallback, aCallback, true, false); },
[&registerBinding](const std::string& acID, const std::string& acDisplayName, const std::string& acDescription, sol::function aCallback)
{ registerBinding(acID, acDisplayName, acDescription, aCallback, true); },
[&registerBinding](const std::string& acID, const std::string& acDescription, sol::function aCallback) { registerBinding(acID, acDescription, "", aCallback, true); });
{ registerBinding(acID, acDisplayName, acDescription, aCallback, true, false); },
[&registerBinding](const std::string& acID, const std::string& acDescription, sol::function aCallback) { registerBinding(acID, acDescription, "", aCallback, true, false); });

env["registerOverlayHotkey"] = sol::overload(
[&registerBinding](const std::string& acID, const std::string& acDisplayName, sol::function acDescriptionCallback, sol::function aCallback)
{ registerBinding(acID, acDisplayName, acDescriptionCallback, aCallback, true, true); },
[&registerBinding](const std::string& acID, const std::string& acDisplayName, const std::string& acDescription, sol::function aCallback)
{ registerBinding(acID, acDisplayName, acDescription, aCallback, true, true); },
[&registerBinding](const std::string& acID, const std::string& acDescription, sol::function aCallback) { registerBinding(acID, acDescription, "", aCallback, true, true); });

env["registerInput"] = sol::overload(
[&registerBinding](const std::string& acID, const std::string& acDisplayName, sol::function acDescriptionCallback, sol::function aCallback)
{ registerBinding(acID, acDisplayName, acDescriptionCallback, aCallback, false); },
{ registerBinding(acID, acDisplayName, acDescriptionCallback, aCallback, false, false); },
[&registerBinding](const std::string& acID, const std::string& acDisplayName, const std::string& acDescription, sol::function aCallback)
{ registerBinding(acID, acDisplayName, acDescription, aCallback, false); },
[registerBinding](const std::string& acID, const std::string& acDescription, sol::function aCallback) { registerBinding(acID, acDescription, "", aCallback, false); });
{ registerBinding(acID, acDisplayName, acDescription, aCallback, false, false); },
[registerBinding](const std::string& acID, const std::string& acDescription, sol::function aCallback) { registerBinding(acID, acDescription, "", aCallback, false, false); });

// TODO: proper exception handling!
try
Expand Down Expand Up @@ -193,6 +200,7 @@ ScriptContext::ScriptContext(LuaSandbox& aLuaSandbox, const std::filesystem::pat

env["registerForEvent"] = sol::nil;
env["registerHotkey"] = sol::nil;
env["registerOverlayHotkey"] = sol::nil;
env["registerInput"] = sol::nil;
}

Expand Down
107 changes: 107 additions & 0 deletions src/sol_imgui/sol_imgui.h
Original file line number Diff line number Diff line change
Expand Up @@ -2600,7 +2600,63 @@ inline std::tuple<float, float, float> ColorConvertHSVtoRGB(float h, float s, fl
return std::make_tuple(r, g, b);
}

// Inputs Utilities: Keyboard
inline int GetKeyIndex(int imgui_key)
{
return ImGui::GetKeyIndex(static_cast<ImGuiKey>(imgui_key));
}
inline bool IsKeyDown(int user_key_index)
{
return ImGui::IsKeyDown(user_key_index);
}
inline bool IsKeyPressed(int user_key_index)
{
return ImGui::IsKeyPressed(user_key_index);
}
inline bool IsKeyPressed(int user_key_index, bool repeat)
{
return ImGui::IsKeyPressed(user_key_index, repeat);
}
inline bool IsKeyReleased(int user_key_index)
{
return ImGui::IsKeyReleased(user_key_index);
}
inline int GetKeyPressedAmount(int key_index, float repeat_delay, float rate)
{
return ImGui::GetKeyPressedAmount(key_index, repeat_delay, rate);
}
inline void CaptureKeyboardFromApp()
{
ImGui::CaptureKeyboardFromApp();
}
inline void CaptureKeyboardFromApp(bool want_capture_keyboard_value)
{
ImGui::CaptureKeyboardFromApp(want_capture_keyboard_value);
}

// Inputs Utilities: Mouse

inline bool IsMouseDown(int button)
{
return ImGui::IsMouseDown(static_cast<ImGuiMouseButton>(button));
}
inline bool IsMouseClicked(int button)
{
return ImGui::IsMouseClicked(static_cast<ImGuiMouseButton>(button));
}
inline bool IsMouseClicked(int button, bool repeat)
{
return ImGui::IsMouseClicked(static_cast<ImGuiMouseButton>(button), repeat);
}
inline bool IsMouseReleased(int button)
{
return ImGui::IsMouseReleased(static_cast<ImGuiMouseButton>(button));
}
inline bool IsMouseDoubleClicked(int button)
{
return ImGui::IsMouseDoubleClicked(static_cast<ImGuiMouseButton>(button));
}

inline bool IsMouseHoveringRect(float min_x, float min_y, float max_x, float max_y)
{
return ImGui::IsMouseHoveringRect({min_x, min_y}, {max_x, max_y});
Expand All @@ -2609,6 +2665,10 @@ inline bool IsMouseHoveringRect(float min_x, float min_y, float max_x, float max
{
return ImGui::IsMouseHoveringRect({min_x, min_y}, {max_x, max_y}, clip);
}
inline bool IsAnyMouseDown()
{
return ImGui::IsAnyMouseDown();
}
inline std::tuple<float, float> GetMousePos()
{
const auto vec2{ImGui::GetMousePos()};
Expand Down Expand Up @@ -2650,6 +2710,22 @@ inline void ResetMouseDragDelta(int button)
{
ImGui::ResetMouseDragDelta(static_cast<ImGuiMouseButton>(button));
}
inline int GetMouseCursor()
{
return ImGui::GetMouseCursor();
}
inline void SetMouseCursor(int cursor_type)
{
ImGui::SetMouseCursor(static_cast<ImGuiMouseCursor>(cursor_type));
}
inline void CaptureMouseFromApp()
{
ImGui::CaptureMouseFromApp();
}
inline void CaptureMouseFromApp(bool want_capture_mouse_value)
{
ImGui::CaptureMouseFromApp(want_capture_mouse_value);
}

// Clipboard Utilities
inline std::string GetClipboardText()
Expand Down Expand Up @@ -3048,6 +3124,21 @@ inline void InitEnums(sol::table luaGlobals)
luaGlobals.new_enum("ImGuiMouseButton", "Left", ImGuiMouseButton_Left, "Right", ImGuiMouseButton_Right, "Middle", ImGuiMouseButton_Middle, "COUNT", ImGuiMouseButton_COUNT);
#pragma endregion MouseButton

#pragma region Key
luaGlobals.new_enum(
"ImGuiKey", "Tab", ImGuiKey_Tab, "LeftArrow", ImGuiKey_LeftArrow, "RightArrow", ImGuiKey_RightArrow, "UpArrow", ImGuiKey_UpArrow, "DownArrow", ImGuiKey_DownArrow, "PageUp",
ImGuiKey_PageUp, "PageDown", ImGuiKey_PageDown, "Home", ImGuiKey_Home, "End", ImGuiKey_End, "Insert", ImGuiKey_Insert, "Delete", ImGuiKey_Delete, "Backspace",
ImGuiKey_Backspace, "Space", ImGuiKey_Space, "Enter", ImGuiKey_Enter, "Escape", ImGuiKey_Escape, "KeyPadEnter", ImGuiKey_KeyPadEnter, "A", ImGuiKey_A, "C", ImGuiKey_C, "V",
ImGuiKey_V, "X", ImGuiKey_X, "Y", ImGuiKey_Y, "Z", ImGuiKey_Z, "COUNT", ImGuiKey_COUNT);
#pragma endregion Key

#pragma region MouseCursor
luaGlobals.new_enum(
"ImGuiMouseCursor", "None", ImGuiMouseCursor_None, "Arrow", ImGuiMouseCursor_Arrow, "TextInput", ImGuiMouseCursor_TextInput, "ResizeAll", ImGuiMouseCursor_ResizeAll,
"ResizeNS", ImGuiMouseCursor_ResizeNS, "ResizeEW", ImGuiMouseCursor_ResizeEW, "ResizeNESW", ImGuiMouseCursor_ResizeNESW, "ResizeNWSE", ImGuiMouseCursor_ResizeNWSE, "Hand",
ImGuiMouseCursor_Hand, "NotAllowed", ImGuiMouseCursor_NotAllowed, "COUNT", ImGuiMouseCursor_COUNT);
#pragma endregion MouseCursor

#pragma region ImDrawCorner Flags
luaGlobals.new_enum(
"ImDrawCornerFlags", "None", ImDrawCornerFlags_None, "TopLeft", ImDrawCornerFlags_TopLeft, "TopRight", ImDrawCornerFlags_TopRight, "BotLeft", ImDrawCornerFlags_BotLeft,
Expand Down Expand Up @@ -3684,10 +3775,23 @@ inline void InitBindings(sol::state& lua, sol::table luaGlobals)
ImGui.set_function("ColorConvertHSVtoRGB", ColorConvertHSVtoRGB);
#pragma endregion Color Utilities

#pragma region Inputs Utilities: Keyboard
ImGui.set_function("GetKeyIndex", GetKeyIndex);
ImGui.set_function("IsKeyDown", IsKeyDown);
ImGui.set_function("IsKeyPressed", sol::overload(sol::resolve<bool(int)>(IsKeyPressed), sol::resolve<bool(int, bool)>(IsKeyPressed)));
ImGui.set_function("IsKeyReleased", IsKeyReleased);
ImGui.set_function("CaptureKeyboardFromApp", sol::overload(sol::resolve<void()>(CaptureKeyboardFromApp), sol::resolve<void(bool)>(CaptureKeyboardFromApp)));
#pragma endregion Inputs Utilities : Keyboard

#pragma region Inputs Utilities : Mouse
ImGui.set_function("IsMouseDown", IsMouseDown);
ImGui.set_function("IsMouseClicked", sol::overload(sol::resolve<bool(int)>(IsMouseClicked), sol::resolve<bool(int, bool)>(IsMouseClicked)));
ImGui.set_function("IsMouseReleased", IsMouseReleased);
ImGui.set_function("IsMouseDoubleClicked", IsMouseDoubleClicked);
ImGui.set_function(
"IsMouseHoveringRect",
sol::overload(sol::resolve<bool(float, float, float, float)>(IsMouseHoveringRect), sol::resolve<bool(float, float, float, float, bool)>(IsMouseHoveringRect)));
ImGui.set_function("IsAnyMouseDown", IsAnyMouseDown);
ImGui.set_function("GetMousePos", GetMousePos);
ImGui.set_function("GetMousePosOnOpeningCurrentPopup", GetMousePosOnOpeningCurrentPopup);
ImGui.set_function("IsMouseDragging", sol::overload(sol::resolve<bool(int)>(IsMouseDragging), sol::resolve<bool(int, float)>(IsMouseDragging)));
Expand All @@ -3696,6 +3800,9 @@ inline void InitBindings(sol::state& lua, sol::table luaGlobals)
sol::resolve<std::tuple<float, float>()>(GetMouseDragDelta), sol::resolve<std::tuple<float, float>(int)>(GetMouseDragDelta),
sol::resolve<std::tuple<float, float>(int, float)>(GetMouseDragDelta)));
ImGui.set_function("ResetMouseDragDelta", sol::overload(sol::resolve<void()>(ResetMouseDragDelta), sol::resolve<void(int)>(ResetMouseDragDelta)));
ImGui.set_function("GetMouseCursor", GetMouseCursor);
ImGui.set_function("SetMouseCursor", SetMouseCursor);
ImGui.set_function("CaptureMouseFromApp", sol::overload(sol::resolve<void()>(CaptureMouseFromApp), sol::resolve<void(bool)>(CaptureMouseFromApp)));
#pragma endregion Inputs Utilities : Mouse

#pragma region Clipboard Utilities
Expand Down