Open saboTec opened 1 week ago
This workaround helped. i can use the finger ids to make the zoom and other options.
// Event handling and GUI rendering
runnerParams.callbacks.AnyBackendEventCallback = [&](void *pEvent) -> bool {
const auto event = static_cast<SDL_Event*>(pEvent);
ImGuiIO& io = ImGui::GetIO();
static ImPlotFlags plotFlags = ImPlotFlags_None;
return HandleTouchForPlotTools(*event, io, plotFlags);
};
runnerParams.callbacks.BeforeImGuiRender = [&]() {
// Declare and initialize plotFlags
SDL_Event event;
while (SDL_PollEvent(&event)) {
// Handle SDL events (e.g., mouse, touch, keyboard)
if (event.type == SDL_QUIT) {
exit(0); // Terminate application when the user closes the app
}
// Additional event handling (e.g., custom touch support) can go here
}
};
Hello,
I'm interested. Would you mind giving me more info about HandleTouchForPlotTools
, as I could not find info about it online.
Thanks!
Hello, it is just own method to work with the implot simulating mouse. But it is still buggy, like when i open the implot popup with flags then the event one finger just stays on the whole time. When i do it i will give an update. Thanks
bool HandleTouchForPlotTools(SDL_Event& event, ImGuiIO& io, ImPlotFlags& plotFlags) {
static bool twoFingerTouch = false;
static float initialDistance = 0.0f;
static float initialMouseWheel = 0.0f;
static std::map<SDL_FingerID, ImVec2> pressedFingers;
static auto clickCount = 0;
if (event.type == SDL_MULTIGESTURE) {
if (event.mgesture.numFingers == 2) {
// Two-finger touch detected
twoFingerTouch = true;
if (initialDistance == 0.0f) {
initialDistance = event.mgesture.dDist; // Initialize zoom distance
initialMouseWheel = io.MouseWheel;
} else {
// Handle zoom in/out
float delta = event.mgesture.dDist; // - initialDistance;
io.MouseWheel = initialMouseWheel + delta * 0.03f;
std::cout << "Delta: " << delta << ", wheel: " << io.MouseWheel << std::endl;
}
}
}
if (event.type == SDL_FINGERDOWN) {
const auto fingerId = event.tfinger.fingerId;
if(pressedFingers.find(fingerId) == pressedFingers.end()) {
pressedFingers[fingerId] = ImVec2(event.tfinger.x, event.tfinger.y);
std::cout << "Added finger " << fingerId << std::endl;
if(pressedFingers.size() == 3) {
io.MouseDown[1] = true;
}
}
} else if (event.type == SDL_FINGERUP) {
const auto fingerId = event.tfinger.fingerId;
if(pressedFingers.find(fingerId) != pressedFingers.end()) {
if(pressedFingers.size() == 3) {
io.MouseDown[1] = false;
}
pressedFingers.erase(fingerId);
std::cout << "Removed finger " << fingerId << std::endl;
}
}
std::cout << "Number of pressed fingers: " << pressedFingers.size() << ", event " << event.type << std::endl;
if(pressedFingers.size() == 2) {
return true;
}
return false;
}
Hum, interesting :-)
This could serve as a later inspiration for a possible patch to ImGui_ImplSDL2_ProcessEvent inside imgui itself.
That sounds good :) It would be great if implot would built this option for phones like it already has for a mouse.
If you do it in ImGui_ImplSDL2_ProcessEvent, you will have it everywhere (including ImPlot an all ImGui based libraries).
I did it there and works great. Now the finger is not stucked on the popup of the implot. Thanks a lot.
Could you share the diff or the patch you did in imgui_impl_sdl2.cpp ?
I did not do much, just copied the one method to it, and from the main.cpp i remove the event code and works great. When i have more time i will try to do it "cleaner"
bool ImGui_ImplSDL2_ProcessEvent(const SDL_Event event) { ImGui_ImplSDL2_Data bd = ImGui_ImplSDL2_GetBackendData(); IM_ASSERT(bd != nullptr && "Context or backend not initialized! Did you call ImGui_ImplSDL2_Init()?"); ImGuiIO& io = ImGui::GetIO();
// Static variables for multi-touch handling
static bool twoFingerTouch = false;
static float initialDistance = 0.0f;
static float initialMouseWheel = 0.0f;
static std::map<SDL_FingerID, ImVec2> pressedFingers;
switch (event->type)
{
case SDL_FINGERDOWN:
{
const auto fingerId = event->tfinger.fingerId;
if (pressedFingers.find(fingerId) == pressedFingers.end())
{
pressedFingers[fingerId] = ImVec2(event->tfinger.x, event->tfinger.y);
if (pressedFingers.size() == 3)
{
io.MouseDown[1] = true; // Simulate right-click on three fingers
}
}
return true;
}
case SDL_FINGERUP:
{
const auto fingerId = event->tfinger.fingerId;
if (pressedFingers.find(fingerId) != pressedFingers.end())
{
if (pressedFingers.size() == 3)
{
io.MouseDown[1] = false; // Release right-click on three fingers
}
pressedFingers.erase(fingerId);
}
return true;
}
case SDL_MULTIGESTURE:
{
if (event->mgesture.numFingers == 2)
{
// Two-finger gesture handling
twoFingerTouch = true;
if (initialDistance == 0.0f)
{
initialDistance = event->mgesture.dDist; // Initialize zoom distance
initialMouseWheel = io.MouseWheel;
}
else
{
// Handle zoom in/out
float delta = event->mgesture.dDist;
io.MouseWheel = initialMouseWheel + delta * 0.03f;
}
}
return true;
}
rest of the code is the same from the line case SDL_MOUSEMOTION:
Hello, i am using a implot and zooming and "right" click are very usefull for my case, however i did not find how can i use the 2 finger on phones or "second" click. Is there any option for it? Thanks a lot.