diff --git a/.gitignore b/.gitignore index 104fea3..7ab3d63 100644 --- a/.gitignore +++ b/.gitignore @@ -20,4 +20,6 @@ imgui/** imgui **/.DS_Store -.cache/ \ No newline at end of file +.cache/ +/CMakeSettings.json +/.vs diff --git a/CMakeLists.txt b/CMakeLists.txt index 908ecd9..913b40f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -29,7 +29,7 @@ endif() add_subdirectory($ENV{GEODE_SDK} ${CMAKE_CURRENT_BINARY_DIR}/geode) -CPMAddPackage("gh:ocornut/imgui@1.91.0-docking") +CPMAddPackage("gh:ocornut/imgui@1.92.4-docking") target_include_directories(${PROJECT_NAME} PRIVATE ${imgui_SOURCE_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/include) diff --git a/src/DevTools.cpp b/src/DevTools.cpp index d821618..bbc46a6 100644 --- a/src/DevTools.cpp +++ b/src/DevTools.cpp @@ -106,9 +106,36 @@ void DevTools::addCustomCallback(std::function callback) { m_customCallbacks.push_back(std::move(callback)); } +// Scroll when dragging empty space +void mobileScrollBehavior() { + auto* ctx = ImGui::GetCurrentContext(); + auto* window = ctx->CurrentWindow; + if (!window) return; + + bool hovered = false; + bool held = false; + ImGuiID id = window->GetID("##scroll_dragging_overlay"); + ImGui::KeepAliveID(id); + // If nothing hovered so far in the frame (not same as IsAnyItemHovered()!) + if (ctx->HoveredId == 0) { + ImGui::ButtonBehavior(window->Rect(), id, &hovered, &held, ImGuiButtonFlags_MouseButtonLeft); + } + if (held) { + ImVec2 delta = ImGui::GetIO().MouseDownDuration[0] > 0.1 ? -ImGui::GetIO().MouseDelta : ImVec2(0, 0); + if (std::abs(delta.x) >= 0.1f || std::abs(delta.y) >= 0.1f) { + ImGui::SetScrollX(window, window->Scroll.x + delta.x); + ImGui::SetScrollY(window, window->Scroll.y + delta.y); + } + } +} + void DevTools::drawPage(const char* name, void(DevTools::*pageFun)()) { if (ImGui::Begin(name, nullptr, ImGuiWindowFlags_HorizontalScrollbar)) { (this->*pageFun)(); + +#ifdef GEODE_IS_MOBILE + mobileScrollBehavior(); +#endif } ImGui::End(); } @@ -208,6 +235,10 @@ void DevTools::draw(GLRenderCtx* ctx) { if (this->shouldUseGDWindow()) this->drawGD(ctx); ImGui::PopFont(); } + +#ifdef GEODE_IS_WINDOWS + setMouseCursor(); +#endif } void DevTools::setupFonts() { @@ -301,4 +332,5 @@ void DevTools::sceneChanged() { bool DevTools::shouldUseGDWindow() const { return Mod::get()->getSettingValue("should-use-gd-window"); -} \ No newline at end of file + +} diff --git a/src/backend.cpp b/src/backend.cpp index 38a1210..d923be2 100644 --- a/src/backend.cpp +++ b/src/backend.cpp @@ -57,7 +57,7 @@ void DevTools::setupPlatform() { m_fontTexture->initWithData(pixels, kCCTexture2DPixelFormat_RGBA8888, width, height, CCSize(width, height)); m_fontTexture->retain(); - io.Fonts->SetTexID(reinterpret_cast(static_cast(m_fontTexture->getName()))); + io.Fonts->SetTexID(static_cast(m_fontTexture->getName())); // fixes getMousePos to be relative to the GD view #ifndef GEODE_IS_MOBILE @@ -219,7 +219,7 @@ void DevTools::renderDrawDataFallback(ImDrawData* draw_data) { auto* idxBuffer = list->IdxBuffer.Data; auto* vtxBuffer = list->VtxBuffer.Data; for (auto& cmd : list->CmdBuffer) { - ccGLBindTexture2D(static_cast(reinterpret_cast(cmd.GetTexID()))); + ccGLBindTexture2D(static_cast(cmd.GetTexID())); const auto rect = cmd.ClipRect; const auto orig = toCocos(ImVec2(rect.x, rect.y)); @@ -306,7 +306,7 @@ void DevTools::renderDrawData(ImDrawData* draw_data) { glBufferData(GL_ELEMENT_ARRAY_BUFFER, list->IdxBuffer.Size * sizeof(ImDrawIdx), list->IdxBuffer.Data, GL_STREAM_DRAW); for (auto& cmd : list->CmdBuffer) { - ccGLBindTexture2D(static_cast(reinterpret_cast(cmd.GetTexID()))); + ccGLBindTexture2D(static_cast(cmd.GetTexID())); const auto rect = cmd.ClipRect; const auto orig = toCocos(ImVec2(rect.x, rect.y)); diff --git a/src/platform/Win32.cpp b/src/platform/Win32.cpp index b16cb2b..94c337c 100644 --- a/src/platform/Win32.cpp +++ b/src/platform/Win32.cpp @@ -44,4 +44,53 @@ std::string formatAddressIntoOffsetImpl(uintptr_t addr, bool module) { return fmt::format("{:#x}", addr - reinterpret_cast(mod)); } -#endif \ No newline at end of file +// mostly copied from gd-imgui-cocos +void setMouseCursor() { + // Shows imgui's cursor instead of hidden cursor if out of GD Window + bool isCursorVisible = false; + CURSORINFO ci = { sizeof(ci) }; + if (GetCursorInfo(&ci)) { + isCursorVisible = (ci.flags & CURSOR_SHOWING) != 0; + } + // whether to draw a fake cursor + ImGui::GetIO().MouseDrawCursor = DevTools::get()->isVisible() && !isCursorVisible && !shouldPassEventsToGDButTransformed(); + + struct GLFWCursorData { + void* next = nullptr; + HCURSOR cursor; + }; + auto& cursorField = *reinterpret_cast(reinterpret_cast( + CCEGLView::get()->getWindow()) + 0x50); + + auto cursor = ImGui::GetIO().MouseDrawCursor ? ImGuiMouseCursor_None : ImGui::GetMouseCursor(); + static ImGuiMouseCursor lastCursor = ImGuiMouseCursor_COUNT; + if (cursor != lastCursor) { + lastCursor = cursor; + + auto winCursor = IDC_ARROW; + switch (cursor) { + case ImGuiMouseCursor_Arrow: winCursor = IDC_ARROW; break; + case ImGuiMouseCursor_TextInput: winCursor = IDC_IBEAM; break; + case ImGuiMouseCursor_ResizeAll: winCursor = IDC_SIZEALL; break; + case ImGuiMouseCursor_ResizeEW: winCursor = IDC_SIZEWE; break; + case ImGuiMouseCursor_ResizeNS: winCursor = IDC_SIZENS; break; + case ImGuiMouseCursor_ResizeNESW: winCursor = IDC_SIZENESW; break; + case ImGuiMouseCursor_ResizeNWSE: winCursor = IDC_SIZENWSE; break; + case ImGuiMouseCursor_Hand: winCursor = IDC_HAND; break; + case ImGuiMouseCursor_NotAllowed: winCursor = IDC_NO; break; + } + if (cursorField) { + cursorField->cursor = LoadCursor(NULL, winCursor); + } + else { + // must be heap allocated + cursorField = new GLFWCursorData { + .next = nullptr, + .cursor = LoadCursor(NULL, winCursor) + }; + } + } +} + +#endif + diff --git a/src/platform/platform.cpp b/src/platform/platform.cpp index 6088a7f..f045c38 100644 --- a/src/platform/platform.cpp +++ b/src/platform/platform.cpp @@ -43,7 +43,7 @@ void GLRenderCtx::cleanup() { GLRenderCtx::GLRenderCtx(ImVec2 const& size) : m_size(size) {} ImTextureID GLRenderCtx::texture() const { - return reinterpret_cast(static_cast(m_texture)); + return static_cast(m_texture); } ImVec2 GLRenderCtx::size() const { diff --git a/src/platform/platform.hpp b/src/platform/platform.hpp index 1e6e2f6..740cb78 100644 --- a/src/platform/platform.hpp +++ b/src/platform/platform.hpp @@ -8,6 +8,7 @@ #elif defined(GEODE_IS_IOS) #include #endif +#include ImRect& getGDWindowRect(); bool& shouldPassEventsToGDButTransformed(); @@ -35,3 +36,7 @@ class GLRenderCtx final { bool begin(); void end(); }; + +#ifdef GEODE_IS_WINDOWS +void setMouseCursor(); +#endif \ No newline at end of file diff --git a/src/themes.cpp b/src/themes.cpp index c194d6d..5943304 100644 --- a/src/themes.cpp +++ b/src/themes.cpp @@ -311,6 +311,10 @@ void applyCommon(ImGuiStyle& style) { // style.FrameRounding = 2.0f; // style.WindowPadding = { 3.f, 3.f }; // style.ColorButtonPosition = ImGuiDir_Left; + + //special sets for imgui 1.92.4 to keep old look of devtools + style.TabRounding = 0.f; + style.TabBarOverlineSize = 2.f; } ThemeDef getThemeDef(std::string const& name) {