Skip to content

Commit

Permalink
Support ImGui 1.91.5 and greater
Browse files Browse the repository at this point in the history
  • Loading branch information
jslee02 committed Nov 10, 2024
1 parent 1093809 commit 7c30a7f
Show file tree
Hide file tree
Showing 3 changed files with 688 additions and 588 deletions.
137 changes: 106 additions & 31 deletions dart/gui/osg/ImGuiHandler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -51,10 +51,11 @@ namespace dart {
namespace gui {
namespace osg {

//==============================================================================
#if IMGUI_VERSION_NUM < 19150

// Special keys that are usually greater than 512 in osgGA
//
// Imporant Note: Dear ImGui expects the control Keys indices not to be greater
// Important Note: Dear ImGui expects the control Keys indices not to be greater
// thant 511. It actually uses an array of 512 elements. However, OSG has
// indices greater than that. So here I do a conversion for special keys between
// ImGui and OSG.
Expand Down Expand Up @@ -83,14 +84,70 @@ enum ConvertedKey : int
ConvertedKey_RightSuper,
};

#endif

//==============================================================================
// Check for a special key and return the converted code (range [257, 511]) if
// so. Otherwise returns -1
int convertFromOSGKey(int key)
ImGuiKey convertFromOSGKey(int key)
{
using KeySymbol = osgGA::GUIEventAdapter::KeySymbol;

switch (key) {
#if IMGUI_VERSION_NUM >= 19150
case KeySymbol::KEY_Tab:
return ImGuiKey_Tab;
case KeySymbol::KEY_Left:
return ImGuiKey_LeftArrow;
case KeySymbol::KEY_Right:
return ImGuiKey_RightArrow;
case KeySymbol::KEY_Up:
return ImGuiKey_UpArrow;
case KeySymbol::KEY_Down:
return ImGuiKey_DownArrow;
case KeySymbol::KEY_Page_Up:
return ImGuiKey_PageUp;
case KeySymbol::KEY_Page_Down:
return ImGuiKey_PageDown;
case KeySymbol::KEY_Home:
return ImGuiKey_Home;
case KeySymbol::KEY_End:
return ImGuiKey_End;
case KeySymbol::KEY_Delete:
return ImGuiKey_Delete;
case KeySymbol::KEY_BackSpace:
return ImGuiKey_Backspace;
case KeySymbol::KEY_Return:
return ImGuiKey_Enter;
case KeySymbol::KEY_Escape:
return ImGuiKey_Escape;
case KeySymbol::KEY_Control_L:
case KeySymbol::KEY_Control_R:
return ImGuiKey_ModCtrl;
case KeySymbol::KEY_Shift_L:
case KeySymbol::KEY_Shift_R:
return ImGuiKey_ModShift;
case KeySymbol::KEY_Alt_L:
case KeySymbol::KEY_Alt_R:
return ImGuiKey_ModAlt;
case KeySymbol::KEY_Super_L:
case KeySymbol::KEY_Super_R:
return ImGuiKey_ModSuper;
case KeySymbol::KEY_A:
return ImGuiKey_A;
case KeySymbol::KEY_C:
return ImGuiKey_C;
case KeySymbol::KEY_V:
return ImGuiKey_V;
case KeySymbol::KEY_X:
return ImGuiKey_X;
case KeySymbol::KEY_Y:
return ImGuiKey_Y;
case KeySymbol::KEY_Z:
return ImGuiKey_Z;
default:
return ImGuiKey_None;
#else
case KeySymbol::KEY_Tab:
return ConvertedKey_Tab;
case KeySymbol::KEY_Left:
Expand Down Expand Up @@ -135,6 +192,7 @@ int convertFromOSGKey(int key)
return ConvertedKey_RightSuper;
default:
return -1;
#endif
}
}

Expand Down Expand Up @@ -182,6 +240,7 @@ ImGuiHandler::ImGuiHandler()

ImGui_ImplOpenGL2_Init();

#if IMGUI_VERSION_NUM < 19150
// Keyboard mapping. ImGui will use those indices to peek into the
// io.KeyDown[] array.
ImGuiIO& io = ImGui::GetIO();
Expand All @@ -204,6 +263,7 @@ ImGuiHandler::ImGuiHandler()
io.KeyMap[ImGuiKey_X] = osgGA::GUIEventAdapter::KeySymbol::KEY_X;
io.KeyMap[ImGuiKey_Y] = osgGA::GUIEventAdapter::KeySymbol::KEY_Y;
io.KeyMap[ImGuiKey_Z] = osgGA::GUIEventAdapter::KeySymbol::KEY_Z;
#endif
}

//==============================================================================
Expand Down Expand Up @@ -272,22 +332,30 @@ bool ImGuiHandler::handle(
::osg::Object* /*object*/,
::osg::NodeVisitor* /*nodeVisitor*/)
{
auto& io = ImGui::GetIO();
const auto wantCapureMouse = io.WantCaptureMouse;
const auto wantCapureKeyboard = io.WantCaptureKeyboard;
ImGuiIO& io = ImGui::GetIO();
const bool wantCaptureMouse = io.WantCaptureMouse;
const bool wantCaptureKeyboard = io.WantCaptureKeyboard;

switch (eventAdapter.getEventType()) {
case osgGA::GUIEventAdapter::KEYDOWN: {
const auto c = eventAdapter.getUnmodifiedKey();
const auto special_key = convertFromOSGKey(c);

if (special_key > 0) {
assert(special_key < 512 && "ImGui KeysDown is an array of 512");
const int key = eventAdapter.getUnmodifiedKey();
const ImGuiKey specialKey = convertFromOSGKey(key);

#if IMGUI_VERSION_NUM >= 19150
if (specialKey != ImGuiKey_None) {
io.AddKeyEvent(specialKey, true);
} else if (key != 0 && key < 0x10000) {
const ImWchar c = static_cast<ImWchar>(eventAdapter.getKey());
io.AddInputCharacter(c);
}
#else
if (specialKey > 0) {
assert(specialKey < 512 && "ImGui KeysDown is an array of 512");
assert(
special_key > 256
specialKey > 256
&& "ASCII stop at 127, but we use the range [257, 511]");

io.KeysDown[special_key] = true;
io.KeysDown[specialKey] = true;

io.KeyCtrl = io.KeysDown[ConvertedKey_LeftControl]
|| io.KeysDown[ConvertedKey_RightControl];
Expand All @@ -297,24 +365,30 @@ bool ImGuiHandler::handle(
|| io.KeysDown[ConvertedKey_RightAlt];
io.KeySuper = io.KeysDown[ConvertedKey_LeftSuper]
|| io.KeysDown[ConvertedKey_RightSuper];
} else if (0 < c && c < 0x10000) {
io.KeysDown[c] = true;
io.AddInputCharacter(static_cast<ImWchar>(c));
} else if (0 < key && key < 0x10000) {
io.KeysDown[key] = true;
io.AddInputCharacter(static_cast<ImWchar>(key));
}
#endif

return wantCapureKeyboard;
return wantCaptureKeyboard;
}
case osgGA::GUIEventAdapter::KEYUP: {
const auto c = eventAdapter.getUnmodifiedKey();
const auto special_key = convertFromOSGKey(c);
const int key = eventAdapter.getUnmodifiedKey();
const ImGuiKey specialKey = convertFromOSGKey(key);

if (special_key > 0) {
assert(special_key < 512 && "ImGui KeysDown is an array of 512");
#if IMGUI_VERSION_NUM >= 19150
if (specialKey != ImGuiKey_None) {
io.AddKeyEvent(specialKey, false);
}
#else
if (specialKey > 0) {
assert(specialKey < 512 && "ImGui KeysDown is an array of 512");
assert(
special_key > 256
specialKey > 256
&& "ASCII stop at 127, but we use the range [257, 511]");

io.KeysDown[special_key] = false;
io.KeysDown[specialKey] = false;

io.KeyCtrl = io.KeysDown[ConvertedKey_LeftControl]
|| io.KeysDown[ConvertedKey_RightControl];
Expand All @@ -324,12 +398,13 @@ bool ImGuiHandler::handle(
|| io.KeysDown[ConvertedKey_RightAlt];
io.KeySuper = io.KeysDown[ConvertedKey_LeftSuper]
|| io.KeysDown[ConvertedKey_RightSuper];
} else if (0 < c && c < 0x10000) {
io.KeysDown[c] = false;
io.AddInputCharacter(static_cast<ImWchar>(c));
} else if (0 < key && key < 0x10000) {
io.KeysDown[key] = false;
io.AddInputCharacter(static_cast<ImWchar>(key));
}
#endif

return wantCapureKeyboard;
return wantCaptureKeyboard;
}
case osgGA::GUIEventAdapter::PUSH: {
io.MousePos
Expand All @@ -351,14 +426,14 @@ bool ImGuiHandler::handle(
mMousePressed[0] = true;
}

return wantCapureMouse;
return wantCaptureMouse;
}
case osgGA::GUIEventAdapter::DRAG:
case osgGA::GUIEventAdapter::MOVE: {
io.MousePos
= ImVec2(eventAdapter.getX(), io.DisplaySize.y - eventAdapter.getY());

return wantCapureMouse;
return wantCaptureMouse;
}
case osgGA::GUIEventAdapter::RELEASE: {
// When a mouse button is released no button mask is set. So we mark all
Expand All @@ -367,7 +442,7 @@ bool ImGuiHandler::handle(
mMousePressed[1] = false;
mMousePressed[2] = false;

return wantCapureMouse;
return wantCaptureMouse;
}
case osgGA::GUIEventAdapter::SCROLL: {
constexpr float increment = 0.1f;
Expand All @@ -390,7 +465,7 @@ bool ImGuiHandler::handle(
break;
}

return wantCapureMouse;
return wantCaptureMouse;
}
default: {
return false;
Expand Down
Loading

0 comments on commit 7c30a7f

Please sign in to comment.