ofxImGui icon indicating copy to clipboard operation
ofxImGui copied to clipboard

ofKeyEventArgs.codepoint not right when use IME input

Open Geistyp opened this issue 9 years ago • 9 comments

according to https://github.com/ocornut/imgui/blob/master/examples/opengl3_example/imgui_impl_glfw_gl3.cpp

we should use glfwSetCharCallback(window, ImGui_ImplGlfwGL3_CharCallback) to AddInputCharacter()

since like ofKeyEventArgs.codepoint is not the right unicode char, maybe this is a oF core bug.

so I comment all AddInputCharacter in KeyPressed and KeyReleased

void BaseEngine::onKeyPressed(ofKeyEventArgs& event)
{
    int key = event.keycode;
    io->KeysDown[key] = true;
    //io->AddInputCharacter((unsigned short)event.codepoint);
}
void EngineGLFW::onKeyReleased(ofKeyEventArgs& event)
{
    int key = event.keycode;
    io->KeysDown[key] = false;

    io->KeyCtrl  = io->KeysDown[GLFW_KEY_LEFT_CONTROL] || io->KeysDown[GLFW_KEY_RIGHT_CONTROL];
    io->KeyShift = io->KeysDown[GLFW_KEY_LEFT_SHIFT]   || io->KeysDown[GLFW_KEY_RIGHT_SHIFT];
    io->KeyAlt   = io->KeysDown[GLFW_KEY_LEFT_ALT]     || io->KeysDown[GLFW_KEY_RIGHT_ALT];
    if(key < GLFW_KEY_ESCAPE)
    {
        //io->AddInputCharacter((unsigned short)event.codepoint);
    }
}

And add CharCallback then all works

void ImGui_ImplGlfwGL3_CharCallback(GLFWwindow*, unsigned int c)
{
    ImGuiIO& io = ImGui::GetIO();
    if (c > 0 && c < 0x10000)
        io.AddInputCharacter((unsigned short)c);
}
void EngineGLFW::setup(ImGuiIO* io_)
{
    ......
    ofAddListener(ofEvents().keyReleased, this, &EngineGLFW::onKeyReleased);

    ofAddListener(ofEvents().keyPressed, (BaseEngine*)this, &BaseEngine::onKeyPressed);
    ofAddListener(ofEvents().mousePressed, (BaseEngine*)this, &BaseEngine::onMousePressed);
    ofAddListener(ofEvents().mouseReleased, (BaseEngine*)this, &BaseEngine::onMouseReleased);
    ofAddListener(ofEvents().mouseScrolled, (BaseEngine*)this, &BaseEngine::onMouseScrolled);
    ofAddListener(ofEvents().windowResized, (BaseEngine*)this, &BaseEngine::onWindowResized);

    auto ptr = static_cast<ofAppGLFWWindow*>(ofGetWindowPtr());
    glfwSetCharCallback(ptr->getGLFWWindow(), ImGui_ImplGlfwGL3_CharCallback);
}

oF not use this CallBack in glfw setting, so it's fine we use here.

Geistyp avatar Jan 05 '16 10:01 Geistyp

I think there may be some Unicode/UTF-8 in OF 0.9.0

Take a look at this and see if it may help http://blog.openframeworks.cc/post/133404738514/openframeworks-090-ofthreadchannel-utf-8-and

Especially the section about ofAppendUTF8(str,key)

jvcleave avatar Jan 05 '16 10:01 jvcleave

Yes, but ImGui combine key code to string and parse to utf8, we just use AddInputCharacter to add key code.

https://github.com/arturoc/glfw/blob/feature-keysUnicode/src/win32_window.c#L320

        case WM_SYSKEYDOWN:
        {
            const int scancode = (lParam >> 16) & 0x1ff;
            const int key = translateKey(wParam, lParam);
            if (key == _GLFW_KEY_INVALID)
                                break;
                        const int unicode = translateToUnicode(wParam,scancode);

                        _glfwInputKey(window, key, scancode, unicode, GLFW_PRESS, getKeyMods());
            break;
        }

        case WM_CHAR:
        {
            _glfwInputChar(window, (unsigned int) wParam, getKeyMods(), GL_TRUE);
            return 0;
        }

        case WM_SYSCHAR:
        {
            _glfwInputChar(window, (unsigned int) wParam, getKeyMods(), GL_FALSE);
            return 0;
        }

        case WM_UNICHAR:
        {
            // This message is not sent by Windows, but is sent by some
            // third-party input method engines

            if (wParam == UNICODE_NOCHAR)
            {
                // Returning TRUE here announces support for this message
                return TRUE;
            }

            _glfwInputChar(window, (unsigned int) wParam, getKeyMods(), GL_TRUE);
            return FALSE;
        }

oF already translate char to unicode, but ImGui input just need (unsigned int) wParam

There is no different change to use glfwSetCharCallback(), but add features to support IME input.

Geistyp avatar Jan 05 '16 15:01 Geistyp

ok - I think I understand. I will take a look

jvcleave avatar Jan 05 '16 19:01 jvcleave

@Geistyp

static char buf[256] = "";
        bool isinput = ImGui::InputText(ofLocaleToUtf8("输入中文").c_str(), buf, IM_ARRAYSIZE(buf));
        if (isinput)
        {
            ofLogNotice(  ofToString(buf) );
        }

display Garbled

o2co2 avatar Jan 07 '16 07:01 o2co2

@Geistyp How to convert static char buf[256]

o2co2 avatar Jan 10 '16 01:01 o2co2

@o2co2 what do you mean? Is that "输入中文" garbled? or your IME input garbled?

Geistyp avatar Jan 11 '16 09:01 Geistyp

@Geistyp see the picture file-list

o2co2 avatar Jan 13 '16 03:01 o2co2

@o2co2 console output chinese? try setlocale(LC_ALL, "chs");

Geistyp avatar Jan 14 '16 08:01 Geistyp

@Geistyp Thank you

static char buf[256] = "";
bool isinput = ImGui::InputText(ofLocaleToUtf8("输入中文").c_str(), buf, IM_ARRAYSIZE(buf));
if (isinput)
{
      std::wstring sw = UTF8ToUnicode(ofToString(buf));
      std::string uToa = UnicodeToANSI(sw);
      ofLogNotice(uToa.c_str());
}

o2co2 avatar Jan 14 '16 11:01 o2co2