You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
211 lines
5.5 KiB
211 lines
5.5 KiB
// This file is part of libigl, a simple c++ geometry processing library.
|
|
//
|
|
// Copyright (C) 2022 Alec Jacobson <alecjacobson@gmail.com>
|
|
// Copyright (C) 2018 Jérémie Dumas <jeremie.dumas@ens-lyon.org>
|
|
//
|
|
// This Source Code Form is subject to the terms of the Mozilla Public License
|
|
// v. 2.0. If a copy of the MPL was not distributed with this file, You can
|
|
// obtain one at http://mozilla.org/MPL/2.0/.
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
#include "ImGuiPlugin.h"
|
|
#include "ImGuiHelpers.h"
|
|
#include <igl/project.h>
|
|
#include <backends/imgui_impl_glfw.h>
|
|
#include <backends/imgui_impl_opengl3.h>
|
|
#include <imgui.h>
|
|
#include <imgui_fonts_droid_sans.h>
|
|
#include <GLFW/glfw3.h>
|
|
#include <iostream>
|
|
|
|
namespace igl
|
|
{
|
|
namespace opengl
|
|
{
|
|
namespace glfw
|
|
{
|
|
namespace imgui
|
|
{
|
|
|
|
IGL_INLINE void ImGuiPlugin::init(igl::opengl::glfw::Viewer *_viewer)
|
|
{
|
|
ViewerPlugin::init(_viewer);
|
|
// Setup ImGui binding
|
|
if (_viewer)
|
|
{
|
|
IMGUI_CHECKVERSION();
|
|
if (!context_)
|
|
{
|
|
// Single global context by default, but can be overridden by the user
|
|
static ImGuiContext * __global_context = ImGui::CreateContext();
|
|
context_ = __global_context;
|
|
}
|
|
const char* glsl_version = "#version 150";
|
|
ImGui_ImplGlfw_InitForOpenGL(viewer->window, false);
|
|
ImGui_ImplOpenGL3_Init(glsl_version);
|
|
ImGui::GetIO().IniFilename = nullptr;
|
|
ImGui::StyleColorsDark();
|
|
ImGuiStyle& style = ImGui::GetStyle();
|
|
style.FrameRounding = 5.0f;
|
|
reload_font();
|
|
}
|
|
init_widgets();
|
|
}
|
|
|
|
IGL_INLINE void ImGuiPlugin::init_widgets()
|
|
{
|
|
// Init all widgets
|
|
for(auto & widget : widgets) { widget->init(viewer, this); }
|
|
}
|
|
IGL_INLINE void ImGuiPlugin::reload_font(int font_size)
|
|
{
|
|
hidpi_scaling_ = hidpi_scaling();
|
|
pixel_ratio_ = pixel_ratio();
|
|
ImGuiIO& io = ImGui::GetIO();
|
|
io.Fonts->Clear();
|
|
io.Fonts->AddFontFromMemoryCompressedTTF(droid_sans_compressed_data,
|
|
droid_sans_compressed_size, font_size * hidpi_scaling_);
|
|
io.FontGlobalScale = 1.0 / pixel_ratio_;
|
|
}
|
|
|
|
IGL_INLINE void ImGuiPlugin::shutdown()
|
|
{
|
|
// Cleanup
|
|
ImGui_ImplOpenGL3_Shutdown();
|
|
ImGui_ImplGlfw_Shutdown();
|
|
// User is responsible for destroying context if a custom context is given
|
|
// ImGui::DestroyContext(*context_);
|
|
}
|
|
|
|
IGL_INLINE bool ImGuiPlugin::pre_draw()
|
|
{
|
|
glfwPollEvents();
|
|
|
|
// Check whether window dpi has changed
|
|
float scaling = hidpi_scaling();
|
|
if (std::abs(scaling - hidpi_scaling_) > 1e-5)
|
|
{
|
|
reload_font();
|
|
ImGui_ImplOpenGL3_DestroyDeviceObjects();
|
|
}
|
|
|
|
ImGui_ImplOpenGL3_NewFrame();
|
|
ImGui_ImplGlfw_NewFrame();
|
|
ImGui::NewFrame();
|
|
return false;
|
|
}
|
|
|
|
IGL_INLINE bool ImGuiPlugin::post_draw()
|
|
{
|
|
for(auto & widget : widgets){ widget->draw(); }
|
|
ImGui::Render();
|
|
ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData());
|
|
return false;
|
|
}
|
|
|
|
IGL_INLINE void ImGuiPlugin::post_resize(int width, int height)
|
|
{
|
|
if (context_)
|
|
{
|
|
ImGui::GetIO().DisplaySize.x = float(width);
|
|
ImGui::GetIO().DisplaySize.y = float(height);
|
|
}
|
|
}
|
|
|
|
// Mouse IO
|
|
IGL_INLINE bool ImGuiPlugin::mouse_down(int button, int modifier)
|
|
{
|
|
ImGui_ImplGlfw_MouseButtonCallback(viewer->window, button, GLFW_PRESS, modifier);
|
|
if(ImGui::GetIO().WantCaptureMouse){ return true; }
|
|
for( auto & widget : widgets)
|
|
{
|
|
if(widget->mouse_down(button, modifier)) { return true; }
|
|
}
|
|
return false;
|
|
}
|
|
|
|
IGL_INLINE bool ImGuiPlugin::mouse_up(int button, int modifier)
|
|
{
|
|
//return ImGui::GetIO().WantCaptureMouse;
|
|
// !! Should not steal mouse up
|
|
for( auto & widget : widgets)
|
|
{
|
|
widget->mouse_up(button, modifier);
|
|
}
|
|
return false;
|
|
}
|
|
|
|
IGL_INLINE bool ImGuiPlugin::mouse_move(int mouse_x, int mouse_y)
|
|
{
|
|
if(ImGui::GetIO().WantCaptureMouse){ return true; }
|
|
for( auto & widget : widgets)
|
|
{
|
|
if(widget->mouse_move(mouse_x, mouse_y)) { return true; }
|
|
}
|
|
return false;
|
|
}
|
|
|
|
IGL_INLINE bool ImGuiPlugin::mouse_scroll(float delta_y)
|
|
{
|
|
ImGui_ImplGlfw_ScrollCallback(viewer->window, 0.f, delta_y);
|
|
return ImGui::GetIO().WantCaptureMouse;
|
|
}
|
|
|
|
// Keyboard IO
|
|
IGL_INLINE bool ImGuiPlugin::key_pressed(unsigned int key, int modifiers)
|
|
{
|
|
ImGui_ImplGlfw_CharCallback(nullptr, key);
|
|
if(ImGui::GetIO().WantCaptureKeyboard) { return true; }
|
|
for(auto & widget : widgets)
|
|
{
|
|
if(widget->key_pressed(key,modifiers)) {return true; }
|
|
}
|
|
return false;
|
|
}
|
|
|
|
IGL_INLINE bool ImGuiPlugin::key_down(int key, int modifiers)
|
|
{
|
|
ImGui_ImplGlfw_KeyCallback(viewer->window, key, 0, GLFW_PRESS, modifiers);
|
|
if(ImGui::GetIO().WantCaptureKeyboard) { return true; }
|
|
for(auto & widget : widgets)
|
|
{
|
|
if(widget->key_down(key,modifiers)) {return true; }
|
|
}
|
|
return false;
|
|
}
|
|
|
|
IGL_INLINE bool ImGuiPlugin::key_up(int key, int modifiers)
|
|
{
|
|
ImGui_ImplGlfw_KeyCallback(viewer->window, key, 0, GLFW_RELEASE, modifiers);
|
|
if(ImGui::GetIO().WantCaptureKeyboard) { return true; }
|
|
for(auto & widget : widgets)
|
|
{
|
|
if(widget->key_up(key,modifiers)) { return true; }
|
|
}
|
|
return false;
|
|
}
|
|
|
|
IGL_INLINE float ImGuiPlugin::pixel_ratio()
|
|
{
|
|
// Computes pixel ratio for hidpi devices
|
|
int buf_size[2];
|
|
int win_size[2];
|
|
GLFWwindow* window = glfwGetCurrentContext();
|
|
glfwGetFramebufferSize(window, &buf_size[0], &buf_size[1]);
|
|
glfwGetWindowSize(window, &win_size[0], &win_size[1]);
|
|
return (float) buf_size[0] / (float) win_size[0];
|
|
}
|
|
|
|
IGL_INLINE float ImGuiPlugin::hidpi_scaling()
|
|
{
|
|
// Computes scaling factor for hidpi devices
|
|
float xscale, yscale;
|
|
GLFWwindow* window = glfwGetCurrentContext();
|
|
glfwGetWindowContentScale(window, &xscale, &yscale);
|
|
return 0.5 * (xscale + yscale);
|
|
}
|
|
|
|
} // end namespace
|
|
} // end namespace
|
|
} // end namespace
|
|
} // end namespace
|
|
|
|
|