Make imgui scale factor aware

Closes #74
This commit is contained in:
falkTX 2022-01-01 23:44:20 +00:00
parent 65257f0494
commit 0ddd5afa43
5 changed files with 144 additions and 65 deletions

View file

@ -125,7 +125,7 @@ static void ImGui_ImplOpenGL2_SetupRenderState(ImDrawData* draw_data, int fb_wid
glShadeModel(GL_SMOOTH); glShadeModel(GL_SMOOTH);
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
#ifndef IMGUI_DPF_BACKEND #if 0 // ndef IMGUI_DPF_BACKEND
// If you are using this code with non-legacy OpenGL header/contexts (which you should not, prefer using imgui_impl_opengl3.cpp!!), // If you are using this code with non-legacy OpenGL header/contexts (which you should not, prefer using imgui_impl_opengl3.cpp!!),
// you may need to backup/reset/restore other state, e.g. for current shader using the commented lines below. // you may need to backup/reset/restore other state, e.g. for current shader using the commented lines below.
// (DO NOT MODIFY THIS FILE! Add the code in your calling function) // (DO NOT MODIFY THIS FILE! Add the code in your calling function)

View file

@ -1267,16 +1267,17 @@ struct IldaeilWidget : ImGuiWidget, IdleCallback, Thread {
void drawError(const bool open) void drawError(const bool open)
{ {
const float scaleFactor = getScaleFactor();
ImGui::SetNextWindowPos(ImVec2(0, 0)); ImGui::SetNextWindowPos(ImVec2(0, 0));
ImGui::SetNextWindowSize(ImVec2(box.size.x, box.size.y)); ImGui::SetNextWindowSize(ImVec2(box.size.x * scaleFactor, box.size.y * scaleFactor));
const int flags = ImGuiWindowFlags_NoSavedSettings const int flags = ImGuiWindowFlags_NoSavedSettings
| ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoTitleBar
| ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoResize
| ImGuiWindowFlags_NoCollapse | ImGuiWindowFlags_NoCollapse
| ImGuiWindowFlags_NoScrollbar | ImGuiWindowFlags_NoScrollbar
| ImGuiWindowFlags_NoScrollWithMouse | ImGuiWindowFlags_NoScrollWithMouse;
| ImGuiWindowFlags_NoCollapse;
if (ImGui::Begin("Error Window", nullptr, flags)) if (ImGui::Begin("Error Window", nullptr, flags))
{ {
@ -1288,7 +1289,6 @@ struct IldaeilWidget : ImGuiWidget, IdleCallback, Thread {
| ImGuiWindowFlags_NoCollapse | ImGuiWindowFlags_NoCollapse
| ImGuiWindowFlags_NoScrollbar | ImGuiWindowFlags_NoScrollbar
| ImGuiWindowFlags_NoScrollWithMouse | ImGuiWindowFlags_NoScrollWithMouse
| ImGuiWindowFlags_NoCollapse
| ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_AlwaysAutoResize
| ImGuiWindowFlags_AlwaysUseWindowPadding; | ImGuiWindowFlags_AlwaysUseWindowPadding;
@ -1304,18 +1304,18 @@ struct IldaeilWidget : ImGuiWidget, IdleCallback, Thread {
void drawTopBar() void drawTopBar()
{ {
const float scaleFactor = getScaleFactor();
const float padding = ImGui::GetStyle().WindowPadding.y * 2; const float padding = ImGui::GetStyle().WindowPadding.y * 2;
ImGui::SetNextWindowPos(ImVec2(0, 0)); ImGui::SetNextWindowPos(ImVec2(0, 0));
ImGui::SetNextWindowSize(ImVec2(box.size.x, kButtonHeight + padding)); ImGui::SetNextWindowSize(ImVec2(box.size.x * scaleFactor, kButtonHeight * scaleFactor + padding));
const int flags = ImGuiWindowFlags_NoSavedSettings const int flags = ImGuiWindowFlags_NoSavedSettings
| ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoTitleBar
| ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoResize
| ImGuiWindowFlags_NoCollapse | ImGuiWindowFlags_NoCollapse
| ImGuiWindowFlags_NoScrollbar | ImGuiWindowFlags_NoScrollbar
| ImGuiWindowFlags_NoScrollWithMouse | ImGuiWindowFlags_NoScrollWithMouse;
| ImGuiWindowFlags_NoCollapse;
if (ImGui::Begin("Current Plugin", nullptr, flags)) if (ImGui::Begin("Current Plugin", nullptr, flags))
{ {
@ -1344,17 +1344,20 @@ struct IldaeilWidget : ImGuiWidget, IdleCallback, Thread {
void setupMainWindowPos() void setupMainWindowPos()
{ {
const float scaleFactor = getScaleFactor();
float y = 0; float y = 0;
float height = box.size.y; float width = box.size.x * scaleFactor;
float height = box.size.y * scaleFactor;
if (fDrawingState == kDrawingPluginGenericUI) if (fDrawingState == kDrawingPluginGenericUI)
{ {
y = kButtonHeight + ImGui::GetStyle().WindowPadding.y * 2 - 1; y = kButtonHeight * scaleFactor + ImGui::GetStyle().WindowPadding.y * 2 - scaleFactor;
height -= y; height -= y;
} }
ImGui::SetNextWindowPos(ImVec2(0, y)); ImGui::SetNextWindowPos(ImVec2(0, y));
ImGui::SetNextWindowSize(ImVec2(box.size.x, height)); ImGui::SetNextWindowSize(ImVec2(width, height));
} }
void drawGenericUI() void drawGenericUI()
@ -1364,9 +1367,12 @@ struct IldaeilWidget : ImGuiWidget, IdleCallback, Thread {
PluginGenericUI* const ui = fPluginGenericUI; PluginGenericUI* const ui = fPluginGenericUI;
DISTRHO_SAFE_ASSERT_RETURN(ui != nullptr,); DISTRHO_SAFE_ASSERT_RETURN(ui != nullptr,);
// ImGui::SetNextWindowFocus(); const int pflags = ImGuiWindowFlags_NoSavedSettings
| ImGuiWindowFlags_NoResize
| ImGuiWindowFlags_NoCollapse
| ImGuiWindowFlags_AlwaysAutoResize;
if (ImGui::Begin(ui->title, nullptr, ImGuiWindowFlags_NoResize|ImGuiWindowFlags_NoCollapse)) if (ImGui::Begin(ui->title, nullptr, pflags))
{ {
const CarlaHostHandle handle = module->fCarlaHostHandle; const CarlaHostHandle handle = module->fCarlaHostHandle;
@ -1452,9 +1458,7 @@ struct IldaeilWidget : ImGuiWidget, IdleCallback, Thread {
| ImGuiWindowFlags_NoCollapse | ImGuiWindowFlags_NoCollapse
| ImGuiWindowFlags_NoScrollbar | ImGuiWindowFlags_NoScrollbar
| ImGuiWindowFlags_NoScrollWithMouse | ImGuiWindowFlags_NoScrollWithMouse
| ImGuiWindowFlags_NoCollapse | ImGuiWindowFlags_AlwaysAutoResize;
| ImGuiWindowFlags_AlwaysAutoResize
| ImGuiWindowFlags_AlwaysUseWindowPadding;
if (ImGui::BeginPopupModal("Plugin Error", nullptr, pflags)) if (ImGui::BeginPopupModal("Plugin Error", nullptr, pflags))
{ {
@ -1643,8 +1647,8 @@ struct IldaeilModuleWidget : ModuleWidget {
if (module != nullptr && module->pcontext != nullptr) if (module != nullptr && module->pcontext != nullptr)
{ {
ildaeilWidget = new IldaeilWidget(module); ildaeilWidget = new IldaeilWidget(module);
ildaeilWidget->box.pos = Vec(2 * RACK_GRID_WIDTH, 0); ildaeilWidget->box.pos = Vec(2 * RACK_GRID_WIDTH, 1);
ildaeilWidget->box.size = Vec(box.size.x - 2 * RACK_GRID_WIDTH, box.size.y); ildaeilWidget->box.size = Vec(box.size.x - 2 * RACK_GRID_WIDTH - 1, box.size.y - 2);
addChild(ildaeilWidget); addChild(ildaeilWidget);
} }

View file

@ -131,8 +131,10 @@ std::string ImGuiTextEditor::getCurrentLineText()const
void ImGuiTextEditor::drawImGui() void ImGuiTextEditor::drawImGui()
{ {
const float scaleFactor = getScaleFactor();
ImGui::SetNextWindowPos(ImVec2(0, 0)); ImGui::SetNextWindowPos(ImVec2(0, 0));
ImGui::SetNextWindowSize(ImVec2(box.size.x, box.size.y)); ImGui::SetNextWindowSize(ImVec2(box.size.x * scaleFactor, box.size.y * scaleFactor));
if (ImGui::Begin("TextEdit", nullptr, ImGuiWindowFlags_NoTitleBar|ImGuiWindowFlags_NoResize)) if (ImGui::Begin("TextEdit", nullptr, ImGuiWindowFlags_NoTitleBar|ImGuiWindowFlags_NoResize))
{ {

View file

@ -27,8 +27,11 @@
struct ImGuiWidget::PrivateData { struct ImGuiWidget::PrivateData {
ImGuiContext* context = nullptr; ImGuiContext* context = nullptr;
bool created = false; bool created = false;
bool fontGenerated = false;
float originalScaleFactor = 0.0f;
float scaleFactor = 0.0f;
PrivateData(const double scaleFactor = 1.0) PrivateData()
{ {
IMGUI_CHECKVERSION(); IMGUI_CHECKVERSION();
context = ImGui::CreateContext(); context = ImGui::CreateContext();
@ -38,45 +41,6 @@ struct ImGuiWidget::PrivateData {
io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard;
io.IniFilename = nullptr; io.IniFilename = nullptr;
ImGuiStyle& style(ImGui::GetStyle());
style.FrameRounding = 4;
/*
style.ScaleAllSizes(scaleFactor);
*/
const ImVec4 color_Cardinal(0.76f, 0.11f, 0.22f, 1.00f);
const ImVec4 color_DimCardinal(171.0 / 255.0, 54.0 / 255.0, 73.0 / 255.0, 1.00f);
ImVec4* const colors = style.Colors;
colors[ImGuiCol_Text] = ImVec4(1.00f, 1.00f, 1.00f, 1.00f);
colors[ImGuiCol_TextDisabled] = ImVec4(0.50f, 0.50f, 0.50f, 1.00f);
colors[ImGuiCol_WindowBg] = ImVec4(0.101f, 0.101f, 0.101f, 0.94f);
colors[ImGuiCol_FrameBg] = ImVec4(0.20f, 0.21f, 0.22f, 0.54f);
colors[ImGuiCol_FrameBgHovered] = ImVec4(0.40f, 0.40f, 0.40f, 0.40f);
colors[ImGuiCol_FrameBgActive] = ImVec4(0.18f, 0.18f, 0.18f, 0.67f);
colors[ImGuiCol_TitleBgActive] = ImVec4(0.29f, 0.29f, 0.29f, 1.00f);
colors[ImGuiCol_CheckMark] = color_Cardinal;
colors[ImGuiCol_SliderGrab] = color_DimCardinal;
colors[ImGuiCol_SliderGrabActive] = color_Cardinal;
colors[ImGuiCol_Button] = color_DimCardinal;
colors[ImGuiCol_ButtonHovered] = color_Cardinal;
colors[ImGuiCol_ButtonActive] = color_Cardinal;
colors[ImGuiCol_TextSelectedBg] = ImVec4(0.87f, 0.87f, 0.87f, 0.35f);
colors[ImGuiCol_Header] = ImVec4(0.44f, 0.44f, 0.44f, 0.40f);
colors[ImGuiCol_HeaderHovered] = color_DimCardinal;
colors[ImGuiCol_HeaderActive] = color_Cardinal;
#ifndef DGL_NO_SHARED_RESOURCES
using namespace dpf_resources;
ImFontConfig fc;
fc.FontDataOwnedByAtlas = false;
fc.OversampleH = 1;
fc.OversampleV = 1;
fc.PixelSnapH = true;
io.Fonts->AddFontFromMemoryTTF((void*)dejavusans_ttf, dejavusans_ttf_size, 13.0f * scaleFactor, &fc);
io.Fonts->Build();
#endif
io.KeyMap[ImGuiKey_Tab] = GLFW_KEY_TAB; io.KeyMap[ImGuiKey_Tab] = GLFW_KEY_TAB;
io.KeyMap[ImGuiKey_LeftArrow] = GLFW_KEY_LEFT; io.KeyMap[ImGuiKey_LeftArrow] = GLFW_KEY_LEFT;
io.KeyMap[ImGuiKey_RightArrow] = GLFW_KEY_RIGHT; io.KeyMap[ImGuiKey_RightArrow] = GLFW_KEY_RIGHT;
@ -112,6 +76,58 @@ struct ImGuiWidget::PrivateData {
ImGui::DestroyContext(context); ImGui::DestroyContext(context);
} }
void generateFontIfNeeded()
{
if (fontGenerated)
return;
DISTRHO_SAFE_ASSERT_RETURN(scaleFactor != 0.0f,);
fontGenerated = true;
#ifndef DGL_NO_SHARED_RESOURCES
ImGuiIO& io(ImGui::GetIO());
using namespace dpf_resources;
ImFontConfig fc;
fc.FontDataOwnedByAtlas = false;
fc.OversampleH = 1;
fc.OversampleV = 1;
fc.PixelSnapH = true;
io.Fonts->AddFontFromMemoryTTF((void*)dejavusans_ttf, dejavusans_ttf_size, 13.0f * scaleFactor, &fc);
io.Fonts->Build();
#endif
}
void resetStyle()
{
ImGuiStyle& style(ImGui::GetStyle());
style.FrameRounding = 4;
style.ScaleAllSizes(scaleFactor);
const ImVec4 color_Cardinal(0.76f, 0.11f, 0.22f, 1.00f);
const ImVec4 color_DimCardinal(171.0 / 255.0, 54.0 / 255.0, 73.0 / 255.0, 1.00f);
ImVec4* const colors = style.Colors;
colors[ImGuiCol_Text] = ImVec4(1.00f, 1.00f, 1.00f, 1.00f);
colors[ImGuiCol_TextDisabled] = ImVec4(0.50f, 0.50f, 0.50f, 1.00f);
colors[ImGuiCol_WindowBg] = ImVec4(0.101f, 0.101f, 0.101f, 0.94f);
colors[ImGuiCol_FrameBg] = ImVec4(0.20f, 0.21f, 0.22f, 0.54f);
colors[ImGuiCol_FrameBgHovered] = ImVec4(0.40f, 0.40f, 0.40f, 0.40f);
colors[ImGuiCol_FrameBgActive] = ImVec4(0.18f, 0.18f, 0.18f, 0.67f);
colors[ImGuiCol_TitleBgActive] = ImVec4(0.29f, 0.29f, 0.29f, 1.00f);
colors[ImGuiCol_CheckMark] = color_Cardinal;
colors[ImGuiCol_SliderGrab] = color_DimCardinal;
colors[ImGuiCol_SliderGrabActive] = color_Cardinal;
colors[ImGuiCol_Button] = color_DimCardinal;
colors[ImGuiCol_ButtonHovered] = color_Cardinal;
colors[ImGuiCol_ButtonActive] = color_Cardinal;
colors[ImGuiCol_TextSelectedBg] = ImVec4(0.87f, 0.87f, 0.87f, 0.35f);
colors[ImGuiCol_Header] = ImVec4(0.44f, 0.44f, 0.44f, 0.40f);
colors[ImGuiCol_HeaderHovered] = color_DimCardinal;
colors[ImGuiCol_HeaderActive] = color_Cardinal;
}
}; };
ImGuiWidget::ImGuiWidget() ImGuiWidget::ImGuiWidget()
@ -122,6 +138,11 @@ ImGuiWidget::~ImGuiWidget()
delete imData; delete imData;
} }
float ImGuiWidget::getScaleFactor() const noexcept
{
return imData->scaleFactor;
}
void ImGuiWidget::onContextCreate(const ContextCreateEvent& e) void ImGuiWidget::onContextCreate(const ContextCreateEvent& e)
{ {
OpenGlWidget::onContextCreate(e); OpenGlWidget::onContextCreate(e);
@ -146,13 +167,42 @@ void ImGuiWidget::onContextDestroy(const ContextDestroyEvent& e)
void ImGuiWidget::drawFramebuffer() void ImGuiWidget::drawFramebuffer()
{ {
const math::Vec fbSize = getFramebufferSize();
ImGui::SetCurrentContext(imData->context); ImGui::SetCurrentContext(imData->context);
ImGuiIO& io(ImGui::GetIO()); ImGuiIO& io(ImGui::GetIO());
io.DisplayFramebufferScale = ImVec2(fbSize.x / box.size.x, fbSize.y / box.size.y); const math::Vec fbSize = getFramebufferSize();
io.DisplaySize = ImVec2(box.size.x, box.size.y); const float scaleFactor = APP->window->pixelRatio;
if (d_isNotEqual(imData->scaleFactor, scaleFactor))
{
imData->scaleFactor = scaleFactor;
ImGuiStyle& style(ImGui::GetStyle());
new(&style)ImGuiStyle();
imData->resetStyle();
if (! imData->fontGenerated)
{
imData->originalScaleFactor = scaleFactor;
imData->generateFontIfNeeded();
}
else
{
io.FontGlobalScale = scaleFactor / imData->originalScaleFactor;
}
}
glMatrixMode(GL_PROJECTION);
glPushMatrix();
glLoadIdentity();
glOrtho(0.0, box.size.x * scaleFactor, box.size.y * scaleFactor, 0.0, -1.0, 1.0);
glViewport(0.0, 0.0, fbSize.x, fbSize.y);
glMatrixMode(GL_MODELVIEW);
glPushMatrix();
glLoadIdentity();
io.DisplaySize = ImVec2(box.size.x * scaleFactor, box.size.y * scaleFactor);
io.DisplayFramebufferScale = ImVec2(fbSize.x / (box.size.x * scaleFactor), fbSize.y / (box.size.y * scaleFactor));
if (!imData->created) if (!imData->created)
{ {
@ -180,6 +230,12 @@ void ImGuiWidget::onHover(const HoverEvent& e)
ImGuiIO& io(ImGui::GetIO()); ImGuiIO& io(ImGui::GetIO());
io.MousePos.x = e.pos.x + e.mouseDelta.x; io.MousePos.x = e.pos.x + e.mouseDelta.x;
io.MousePos.y = e.pos.y + e.mouseDelta.y; io.MousePos.y = e.pos.y + e.mouseDelta.y;
if (d_isNotEqual(imData->scaleFactor, 1.0f))
{
io.MousePos.x *= imData->scaleFactor;
io.MousePos.y *= imData->scaleFactor;
}
} }
void ImGuiWidget::onDragHover(const DragHoverEvent& e) void ImGuiWidget::onDragHover(const DragHoverEvent& e)
@ -189,6 +245,12 @@ void ImGuiWidget::onDragHover(const DragHoverEvent& e)
ImGuiIO& io(ImGui::GetIO()); ImGuiIO& io(ImGui::GetIO());
io.MousePos.x = e.pos.x + e.mouseDelta.x; io.MousePos.x = e.pos.x + e.mouseDelta.x;
io.MousePos.y = e.pos.y + e.mouseDelta.y; io.MousePos.y = e.pos.y + e.mouseDelta.y;
if (d_isNotEqual(imData->scaleFactor, 1.0f))
{
io.MousePos.x *= imData->scaleFactor;
io.MousePos.y *= imData->scaleFactor;
}
} }
void ImGuiWidget::onDragLeave(const DragLeaveEvent& e) void ImGuiWidget::onDragLeave(const DragLeaveEvent& e)
@ -207,9 +269,18 @@ void ImGuiWidget::onHoverScroll(const HoverScrollEvent& e)
{ {
ImGui::SetCurrentContext(imData->context); ImGui::SetCurrentContext(imData->context);
float deltaX = e.scrollDelta.x;
float deltaY = e.scrollDelta.y;
if (d_isNotEqual(imData->scaleFactor, 1.0f))
{
deltaX *= imData->scaleFactor;
deltaY *= imData->scaleFactor;
}
ImGuiIO& io(ImGui::GetIO()); ImGuiIO& io(ImGui::GetIO());
io.MouseWheel += e.scrollDelta.y * 0.01f; io.MouseWheel += deltaY * 0.01f;
io.MouseWheelH += e.scrollDelta.x * 0.01f; io.MouseWheelH += deltaX * 0.01f;
if (io.WantCaptureMouse) if (io.WantCaptureMouse)
e.consume(this); e.consume(this);

View file

@ -34,6 +34,8 @@ struct ImGuiWidget : OpenGlWidget {
ImGui::ShowDemoWindow(); ImGui::ShowDemoWindow();
} }
float getScaleFactor() const noexcept;
protected: protected:
void onContextCreate(const ContextCreateEvent& e) override; void onContextCreate(const ContextCreateEvent& e) override;
void onContextDestroy(const ContextDestroyEvent& e) override; void onContextDestroy(const ContextDestroyEvent& e) override;