mirror of https://github.com/axmolengine/axmol.git
Fix to UI touch location and add keyboard support for ImGui on Android (#910)
* Committing genbindings changes * Fix for X position calculation not factoring in X origin. Reduce code duplication. * Add keyboard input support
This commit is contained in:
parent
34094038d5
commit
461e7cfee6
|
@ -6,6 +6,8 @@
|
|||
#include <android/input.h>
|
||||
#include <android/keycodes.h>
|
||||
#include <android/log.h>
|
||||
#include <imgui_internal.h>
|
||||
#include "base/CCIMEDelegate.h"
|
||||
|
||||
USING_NS_AX;
|
||||
using namespace backend;
|
||||
|
@ -20,7 +22,35 @@ using namespace backend;
|
|||
#endif
|
||||
#endif
|
||||
|
||||
// GLFW
|
||||
// Text handling
|
||||
class KeyboardInputDelegate : public IMEDelegate
|
||||
{
|
||||
protected:
|
||||
bool canAttachWithIME() override
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
bool canDetachWithIME() override
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
void controlKey(EventKeyboard::KeyCode keyCode) override
|
||||
{
|
||||
// Not handled at the moment
|
||||
}
|
||||
|
||||
void insertText(const char* text, size_t len) override
|
||||
{
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
for (int i = 0; i < len && text[i] != 0; ++i)
|
||||
{
|
||||
io.AddInputCharacter(text[i]);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
// Android data
|
||||
static char g_LogTag[] = "ImGuiAndroid";
|
||||
|
@ -80,6 +110,8 @@ struct ImGui_ImplAndroid_Data
|
|||
|
||||
SavedRenderStateData SavedRenderState{};
|
||||
Vec2 ViewResolution = Vec2(1920, 1080);
|
||||
|
||||
KeyboardInputDelegate KeyboardInputDelegate;
|
||||
};
|
||||
|
||||
// Backend data stored in io.BackendPlatformUserData to allow support for multiple Dear ImGui contexts
|
||||
|
@ -91,6 +123,17 @@ static ImGui_ImplAndroid_Data* ImGui_ImplAndroid_GetBackendData()
|
|||
// Forward Declarations
|
||||
static void ImGui_ImplAndroid_ShutdownPlatformInterface();
|
||||
|
||||
static ax::Vec2 convertToUICoordinates(const Vec2& pos)
|
||||
{
|
||||
auto* bd = ImGui_ImplAndroid_GetBackendData();
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
auto origin = bd->Window->getVisibleOrigin();
|
||||
auto uiX = ((pos.x - origin.x) * bd->Window->getScaleX()) / io.DisplayFramebufferScale.x;
|
||||
auto uiY = ((pos.y - origin.y) * bd->Window->getScaleY()) / io.DisplayFramebufferScale.y;
|
||||
|
||||
return Vec2(uiX, uiY);
|
||||
}
|
||||
|
||||
// Functions
|
||||
static bool ImGui_ImplAndroid_Init(GLView* window, bool install_callbacks)
|
||||
{
|
||||
|
@ -121,19 +164,20 @@ static bool ImGui_ImplAndroid_Init(GLView* window, bool install_callbacks)
|
|||
touchListener->retain();
|
||||
bd->TouchListener = touchListener;
|
||||
|
||||
touchListener->onTouchBegan = [](Touch* touch, Event* /*event*/) -> bool {
|
||||
touchListener->onTouchBegan = [](Touch* touch, Event* event) -> bool {
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
ImGui_ImplAndroid_Data* bd = ImGui_ImplAndroid_GetBackendData();
|
||||
auto location = touch->getLocationInView();
|
||||
auto origin = bd->Window->getVisibleOrigin();
|
||||
auto realX = location.x * bd->Window->getScaleX();
|
||||
auto realY = (location.y - origin.y) * bd->Window->getScaleY();
|
||||
realX /= io.DisplayFramebufferScale.x;
|
||||
realY /= io.DisplayFramebufferScale.y;
|
||||
io.AddMousePosEvent(realX, realY);
|
||||
bd->LastValidMousePos = ImVec2(realX, realY);
|
||||
auto location = convertToUICoordinates(touch->getLocationInView());
|
||||
io.AddMousePosEvent(location.x, location.y);
|
||||
bd->LastValidMousePos = ImVec2(location.x, location.y);
|
||||
io.AddMouseButtonEvent(0, true);
|
||||
|
||||
ImGui::UpdateHoveredWindowAndCaptureFlags();
|
||||
if (ImGui::GetIO().WantCaptureMouse)
|
||||
{
|
||||
event->stopPropagation();
|
||||
}
|
||||
|
||||
// We can't check if we're actually hovering over a ImGui element, since the
|
||||
// AddMousePosEvent is not instant, it's queued. So, just return true here
|
||||
// to indicate that we're handling this event.
|
||||
|
@ -143,41 +187,37 @@ static bool ImGui_ImplAndroid_Init(GLView* window, bool install_callbacks)
|
|||
touchListener->onTouchMoved = [](Touch* touch, Event* /*event*/) {
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
ImGui_ImplAndroid_Data* bd = ImGui_ImplAndroid_GetBackendData();
|
||||
auto location = touch->getLocationInView();
|
||||
auto origin = bd->Window->getVisibleOrigin();
|
||||
auto realX = location.x * bd->Window->getScaleX();
|
||||
auto realY = (location.y - origin.y) * bd->Window->getScaleY();
|
||||
realX /= io.DisplayFramebufferScale.x;
|
||||
realY /= io.DisplayFramebufferScale.y;
|
||||
io.AddMousePosEvent(realX, realY);
|
||||
bd->LastValidMousePos = ImVec2(realX, realY);;
|
||||
auto location = convertToUICoordinates(touch->getLocationInView());
|
||||
io.AddMousePosEvent(location.x, location.y);
|
||||
bd->LastValidMousePos = ImVec2(location.x, location.y);
|
||||
};
|
||||
|
||||
touchListener->onTouchEnded = [](Touch* touch, Event* /*event*/) {
|
||||
touchListener->onTouchEnded = [](Touch* touch, Event* event) {
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
ImGui_ImplAndroid_Data* bd = ImGui_ImplAndroid_GetBackendData();
|
||||
auto location = touch->getLocationInView();
|
||||
auto origin = bd->Window->getVisibleOrigin();
|
||||
auto realX = location.x * bd->Window->getScaleX();
|
||||
auto realY = (location.y - origin.y) * bd->Window->getScaleY();
|
||||
realX /= io.DisplayFramebufferScale.x;
|
||||
realY /= io.DisplayFramebufferScale.y;
|
||||
io.AddMousePosEvent(realX, realY);
|
||||
bd->LastValidMousePos = ImVec2(realX, realY);;
|
||||
auto location = convertToUICoordinates(touch->getLocationInView());
|
||||
io.AddMousePosEvent(location.x, location.y);
|
||||
bd->LastValidMousePos = ImVec2(location.x, location.y);
|
||||
io.AddMouseButtonEvent(0, false);
|
||||
|
||||
if (ImGui::GetIO().WantTextInput)
|
||||
{
|
||||
bd->KeyboardInputDelegate.attachWithIME();
|
||||
bd->Window->setIMEKeyboardState(true);
|
||||
}
|
||||
else
|
||||
{
|
||||
bd->KeyboardInputDelegate.detachWithIME();
|
||||
bd->Window->setIMEKeyboardState(false);
|
||||
}
|
||||
};
|
||||
|
||||
touchListener->onTouchCancelled = [](Touch* touch, Event* /*event*/) {
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
ImGui_ImplAndroid_Data* bd = ImGui_ImplAndroid_GetBackendData();
|
||||
auto location = touch->getLocationInView();
|
||||
auto origin = bd->Window->getVisibleOrigin();
|
||||
auto realX = location.x * bd->Window->getScaleX();
|
||||
auto realY = (location.y - origin.y) * bd->Window->getScaleY();
|
||||
realX /= io.DisplayFramebufferScale.x;
|
||||
realY /= io.DisplayFramebufferScale.y;
|
||||
io.AddMousePosEvent(realX, realY);
|
||||
bd->LastValidMousePos = ImVec2(realX, realY);
|
||||
auto location = convertToUICoordinates(touch->getLocationInView());
|
||||
io.AddMousePosEvent(location.x, location.y);
|
||||
bd->LastValidMousePos = ImVec2(location.x, location.y);
|
||||
io.AddMouseButtonEvent(0, false);
|
||||
};
|
||||
|
||||
|
|
Loading…
Reference in New Issue