11#include < cocos2d.h>
22#include < Geode/modify/CCTouchDispatcher.hpp>
33#include < Geode/modify/CCMouseDispatcher.hpp>
4+ #include < Geode/modify/CCKeyboardDispatcher.hpp>
45#include < Geode/modify/CCIMEDispatcher.hpp>
6+ #include " Geode/cocos/text_input_node/CCIMEDelegate.h"
7+ #include " Geode/platform/cplatform.h"
58#include " platform/platform.hpp"
69#include " DevTools.hpp"
710#include " ImGui.hpp"
@@ -66,6 +69,65 @@ void DevTools::setupPlatform() {
6669 #endif
6770}
6871
72+ #ifdef GEODE_IS_MOBILE
73+
74+ class DevToolsIMEDelegate : public CCIMEDelegate {
75+ protected:
76+ bool m_attached = false ;
77+ std::string m_text;
78+ public:
79+ bool attachWithIME () override {
80+ if (CCIMEDelegate::attachWithIME ()) {
81+ // being anywhere but end of line ends up messing up the text, so this sends it to the end of the line
82+ #ifdef GEODE_IS_ANDROID
83+ ImGui::GetIO ().AddKeyEvent (ImGuiKey_End, true );
84+ ImGui::GetIO ().AddKeyEvent (ImGuiKey_End, false );
85+ #endif
86+ m_attached = true ;
87+ CCEGLView::get ()->setIMEKeyboardState (true );
88+ return true ;
89+ }
90+ return false ;
91+ }
92+
93+ bool detachWithIME () override {
94+ if (CCIMEDelegate::detachWithIME ()) {
95+ m_attached = false ;
96+ CCEGLView::get ()->setIMEKeyboardState (false );
97+ ImGui::ClearActiveID ();
98+ return true ;
99+ }
100+ return false ;
101+ }
102+
103+ bool canAttachWithIME () override {
104+ return true ;
105+ }
106+
107+ bool canDetachWithIME () override {
108+ return true ;
109+ }
110+
111+ char const * getContentText () override {
112+ m_text = " " ;
113+ for (auto str : ImGui::GetInputTextState (ImGui::GetFocusID ())->TextA ) {
114+ m_text += str;
115+ }
116+ return m_text.c_str ();
117+ }
118+
119+ bool isAttached () {
120+ return m_attached;
121+ }
122+
123+ static DevToolsIMEDelegate* get () {
124+ static DevToolsIMEDelegate* instance = new DevToolsIMEDelegate ();
125+ return instance;
126+ }
127+ };
128+
129+ #endif
130+
69131void DevTools::newFrame () {
70132 auto & io = ImGui::GetIO ();
71133
@@ -94,6 +156,15 @@ void DevTools::newFrame() {
94156 io.KeyAlt = kb->getAltKeyPressed () || kb->getCommandKeyPressed (); // look
95157 io.KeyCtrl = kb->getControlKeyPressed ();
96158 io.KeyShift = kb->getShiftKeyPressed ();
159+
160+ #ifdef GEODE_IS_MOBILE
161+ auto ime = DevToolsIMEDelegate::get ();
162+ if (io.WantTextInput && !ime->isAttached ()) {
163+ ime->attachWithIME ();
164+ } else if (!io.WantTextInput && ime->isAttached ()) {
165+ ime->detachWithIME ();
166+ }
167+ #endif
97168}
98169
99170void DevTools::render (GLRenderCtx* ctx) {
@@ -278,6 +349,18 @@ class $modify(CCMouseDispatcher) {
278349#endif
279350
280351class $modify(CCTouchDispatcher) {
352+ static void onModify (auto & self) {
353+ /*
354+ * some mods hook this instead of using normal touch delegates for some reason
355+ * for example QOLMod, even in the rewrite
356+ * so i added hook priority
357+ */
358+ Result<> res = self.setHookPriorityPre (" cocos2d::CCTouchDispatcher::touches" , Priority::First);
359+ if (!res) {
360+ geode::log::warn (" Failed to set hook priority for CCTouchDispatcher::touches: {}" , res.unwrapErr ());
361+ }
362+ }
363+
281364 void touches (CCSet* touches, CCEvent* event, unsigned int type) {
282365 auto & io = ImGui::GetIO ();
283366 auto * touch = static_cast <CCTouch*>(touches->anyObject ());
@@ -290,6 +373,7 @@ class $modify(CCTouchDispatcher) {
290373 }
291374
292375 const auto pos = toVec2 (touch->getLocation ());
376+ GEODE_MOBILE (io.AddMouseSourceEvent (ImGuiMouseSource_TouchScreen);)
293377 io.AddMousePosEvent (pos.x , pos.y );
294378 if (io.WantCaptureMouse ) {
295379 bool didGDSwallow = false ;
@@ -306,7 +390,12 @@ class $modify(CCTouchDispatcher) {
306390 auto y = (1 .f - relativePos.y / gdRect.GetHeight ()) * win.y ;
307391
308392 auto pos = toCocos (ImVec2 (x, y));
309- touch->setTouchInfo (touch->getID (), pos.x , pos.y );
393+ // setTouchInfo messes up the previous location (causes issues like texturer loader's draggable nodes breaking)
394+ touch->m_point = pos;
395+ if (type == CCTOUCHBEGAN) {
396+ // makes the start location in the touch correct
397+ touch->m_startPoint = pos;
398+ }
310399 CCTouchDispatcher::touches (touches, event, type);
311400
312401 ImGui::SetWindowFocus (" Geometry Dash" );
@@ -318,6 +407,7 @@ class $modify(CCTouchDispatcher) {
318407 // TODO: dragging out of gd makes it click in imgui
319408 if (!didGDSwallow) {
320409 if (type == CCTOUCHBEGAN || type == CCTOUCHMOVED) {
410+ GEODE_MOBILE (io.AddMouseSourceEvent (ImGuiMouseSource_TouchScreen);)
321411 io.AddMouseButtonEvent (0 , true );
322412 }
323413 else {
@@ -356,3 +446,103 @@ class $modify(CCIMEDispatcher) {
356446 io.AddKeyEvent (ImGuiKey_Backspace, false );
357447 }
358448};
449+
450+ ImGuiKey cocosToImGuiKey (cocos2d::enumKeyCodes key) {
451+ if (key >= KEY_A && key <= KEY_Z) {
452+ return static_cast <ImGuiKey>(ImGuiKey_A + (key - KEY_A));
453+ }
454+ if (key >= KEY_Zero && key <= KEY_Nine) {
455+ return static_cast <ImGuiKey>(ImGuiKey_0 + (key - KEY_Zero));
456+ }
457+ switch (key) {
458+ case KEY_Up: return ImGuiKey_UpArrow;
459+ case KEY_Down: return ImGuiKey_DownArrow;
460+ case KEY_Left: return ImGuiKey_LeftArrow;
461+ case KEY_Right: return ImGuiKey_RightArrow;
462+
463+ case KEY_Control: return ImGuiKey_ModCtrl;
464+ case KEY_LeftWindowsKey: return ImGuiKey_ModSuper;
465+ case KEY_Shift: return ImGuiKey_ModShift;
466+ case KEY_Alt: return ImGuiKey_ModAlt;
467+ case KEY_Enter: return ImGuiKey_Enter;
468+
469+ case KEY_Home: return ImGuiKey_Home;
470+ case KEY_End: return ImGuiKey_End;
471+ // macos uses delete instead of backspace for some reason
472+ #ifndef GEODE_IS_MACOS
473+ case KEY_Delete: return ImGuiKey_Delete;
474+ #endif
475+ case KEY_Escape: return ImGuiKey_Escape;
476+
477+ // KEY_Control and KEY_Shift aren't called on android like windows or mac
478+ #ifdef GEODE_IS_ANDROID
479+ case KEY_LeftControl: return ImGuiKey_ModCtrl;
480+ case KEY_RightContol: return ImGuiKey_ModCtrl;
481+ case KEY_LeftShift: return ImGuiKey_ModShift;
482+ case KEY_RightShift: return ImGuiKey_ModShift;
483+ #endif
484+
485+ default : return ImGuiKey_None;
486+ }
487+ }
488+
489+ class $modify(CCKeyboardDispatcher) {
490+ bool dispatchKeyboardMSG (enumKeyCodes key, bool down, bool repeat) {
491+ auto & io = ImGui::GetIO ();
492+ const auto imKey = cocosToImGuiKey (key);
493+ if (imKey != ImGuiKey_None) {
494+ io.AddKeyEvent (imKey, down);
495+ }
496+
497+ // CCIMEDispatcher stuff only gets called on mobile if the virtual keyboard would be up.
498+ // Similarly, CCKeyboardDispatcher doesn't get called if the virtual keyboard would be up.
499+ #ifdef GEODE_IS_MOBILE
500+ if (down) {
501+ char c = 0 ;
502+ if (key >= KEY_A && key <= KEY_Z) {
503+ c = static_cast <char >(key);
504+ if (!io.KeyShift ) {
505+ c = static_cast <char >(tolower (c));
506+ }
507+ } else if (key >= KEY_Zero && key <= KEY_Nine) {
508+ c = static_cast <char >(' 0' + (key - KEY_Zero));
509+ } else if (key == KEY_Space) {
510+ c = ' ' ;
511+ }
512+
513+ if (c != 0 ) {
514+ std::string str (1 , c);
515+ io.AddInputCharactersUTF8 (str.c_str ());
516+ }
517+ }
518+ if (key == KEY_Backspace) {
519+ io.AddKeyEvent (ImGuiKey_Backspace, true );
520+ io.AddKeyEvent (ImGuiKey_Backspace, false );
521+ }
522+ #endif
523+
524+ if (io.WantCaptureKeyboard ) {
525+ return false ;
526+ } else {
527+ return CCKeyboardDispatcher::dispatchKeyboardMSG (key, down, repeat);
528+ }
529+ }
530+
531+ #if defined(GEODE_IS_MACOS) || defined(GEODE_IS_IOS)
532+ static void onModify (auto & self) {
533+ Result<> res = self.setHookPriorityBeforePre (" CCKeyboardDispatcher::updateModifierKeys" , " geode.custom-keybinds" );
534+ if (!res) {
535+ geode::log::warn (" Failed to set hook priority for CCKeyboardDispatcher::updateModifierKeys: {}" , res.unwrapErr ());
536+ }
537+ }
538+
539+ void updateModifierKeys (bool shft, bool ctrl, bool alt, bool cmd) {
540+ auto & io = ImGui::GetIO ();
541+ io.AddKeyEvent (ImGuiKey_ModShift, shft);
542+ io.AddKeyEvent (ImGuiKey_ModCtrl, ctrl);
543+ io.AddKeyEvent (ImGuiKey_ModAlt, alt);
544+ io.AddKeyEvent (ImGuiKey_ModSuper, cmd);
545+ CCKeyboardDispatcher::updateModifierKeys (shft, ctrl, alt, cmd);
546+ }
547+ #endif
548+ };
0 commit comments