From 7f70feb9f4a109ca1a151434e124371a85401652 Mon Sep 17 00:00:00 2001 From: Tim Ringenbach Date: Sat, 1 Mar 2025 20:41:56 -0600 Subject: [PATCH] Gui: HiDPI NaviCube fix --- src/Gui/NaviCube.cpp | 44 ++++++++++++++++++++++++++++++-------------- 1 file changed, 30 insertions(+), 14 deletions(-) diff --git a/src/Gui/NaviCube.cpp b/src/Gui/NaviCube.cpp index 2e25fc0440..2780fdc703 100644 --- a/src/Gui/NaviCube.cpp +++ b/src/Gui/NaviCube.cpp @@ -159,6 +159,7 @@ private: void drawNaviCube(bool picking, float opacity); SbRotation getNearestOrientation(PickId pickId); + qreal getPhysicalCubeWidgetSize(); public: @@ -197,6 +198,7 @@ private: SbVec2f m_RelPos = SbVec2f(1.0f,1.0f); SbVec2s m_PosAreaBase = SbVec2s(0,0); SbVec2s m_PosAreaSize = SbVec2s(0,0); + qreal m_DevicePixelRatio = 1.0; QOpenGLFramebufferObject* m_PickingFramebuffer; Gui::View3DInventorViewer* m_View3DInventorViewer; @@ -338,6 +340,11 @@ void NaviCube::setInactiveOpacity(float opacity) m_NaviCubeImplementation->m_InactiveOpacity = opacity; } +qreal NaviCubeImplementation::getPhysicalCubeWidgetSize() +{ + return m_CubeWidgetSize * m_DevicePixelRatio; +} + void NaviCubeImplementation::setLabels(const std::vector& labels) { m_LabelTextures[PickId::Front].label = labels[0]; @@ -703,19 +710,22 @@ void NaviCubeImplementation::prepare() addButtonFace(PickId::DotBackside, SbVec3f(0, 1, 0)); addButtonFace(PickId::ViewMenu); + qreal physicalCubeWidgetSize = getPhysicalCubeWidgetSize(); + if (m_PickingFramebuffer) delete m_PickingFramebuffer; m_PickingFramebuffer = - new QOpenGLFramebufferObject(2 * m_CubeWidgetSize, 2 * m_CubeWidgetSize, + new QOpenGLFramebufferObject(2 * physicalCubeWidgetSize, 2 * physicalCubeWidgetSize, QOpenGLFramebufferObject::CombinedDepthStencil); m_View3DInventorViewer->getSoRenderManager()->scheduleRedraw(); } void NaviCubeImplementation::drawNaviCube() { handleResize(); - int posX = (int)(m_RelPos[0] * m_PosAreaSize[0]) + m_PosAreaBase[0] - m_CubeWidgetSize / 2; - int posY = (int)(m_RelPos[1] * m_PosAreaSize[1]) + m_PosAreaBase[1] - m_CubeWidgetSize / 2; - glViewport(posX, posY, m_CubeWidgetSize, m_CubeWidgetSize); + qreal physicalCubeWidgetSize = getPhysicalCubeWidgetSize(); + int posX = (int)(m_RelPos[0] * m_PosAreaSize[0]) + m_PosAreaBase[0] - physicalCubeWidgetSize / 2; + int posY = (int)(m_RelPos[1] * m_PosAreaSize[1]) + m_PosAreaBase[1] - physicalCubeWidgetSize / 2; + glViewport(posX, posY, physicalCubeWidgetSize, physicalCubeWidgetSize); drawNaviCube(false, m_Hovering ? 1.f : m_InactiveOpacity); } @@ -731,10 +741,13 @@ void NaviCubeImplementation::createContextMenu(const std::vector& c } void NaviCubeImplementation::handleResize() { + qreal devicePixelRatio = m_View3DInventorViewer->devicePixelRatio(); SbVec2s viewSize = m_View3DInventorViewer->getSoRenderManager()->getSize(); - if (viewSize != m_ViewSize) { - m_PosAreaBase[0] = std::min((int)(m_PosOffset[0] + m_CubeWidgetSize * 0.55), viewSize[0] / 2); - m_PosAreaBase[1] = std::min((int)(m_PosOffset[1] + m_CubeWidgetSize * 0.55), viewSize[1] / 2); + if (viewSize != m_ViewSize || devicePixelRatio != m_DevicePixelRatio) { + m_DevicePixelRatio = devicePixelRatio; + qreal physicalCubeWidgetSize = getPhysicalCubeWidgetSize(); + m_PosAreaBase[0] = std::min((int)(m_PosOffset[0] + physicalCubeWidgetSize * 0.55), viewSize[0] / 2); + m_PosAreaBase[1] = std::min((int)(m_PosOffset[1] + physicalCubeWidgetSize * 0.55), viewSize[1] / 2); m_PosAreaSize[0] = viewSize[0] - 2 * m_PosAreaBase[0]; m_PosAreaSize[1] = viewSize[1] - 2 * m_PosAreaBase[1]; m_ViewSize = viewSize; @@ -934,18 +947,19 @@ void NaviCubeImplementation::drawNaviCube(bool pickMode, float opacity) } NaviCubeImplementation::PickId NaviCubeImplementation::pickFace(short x, short y) { + qreal physicalCubeWidgetSize = getPhysicalCubeWidgetSize(); GLubyte pixels[4] = {0}; - if (m_PickingFramebuffer && std::abs(x) <= m_CubeWidgetSize / 2 && - std::abs(y) <= m_CubeWidgetSize / 2) { + if (m_PickingFramebuffer && std::abs(x) <= physicalCubeWidgetSize / 2 && + std::abs(y) <= physicalCubeWidgetSize / 2) { static_cast(m_View3DInventorViewer->viewport())->makeCurrent(); m_PickingFramebuffer->bind(); - glViewport(0, 0, m_CubeWidgetSize * 2, m_CubeWidgetSize * 2); + glViewport(0, 0, physicalCubeWidgetSize * 2, physicalCubeWidgetSize * 2); drawNaviCube(true, 1.f); glFinish(); - glReadPixels(2 * x + m_CubeWidgetSize, 2 * y + m_CubeWidgetSize, 1, 1, + glReadPixels(2 * x + physicalCubeWidgetSize, 2 * y + physicalCubeWidgetSize, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, &pixels); m_PickingFramebuffer->release(); static_cast(m_View3DInventorViewer->viewport())->doneCurrent(); @@ -1131,13 +1145,15 @@ void NaviCubeImplementation::setHilite(PickId hilite) { } bool NaviCubeImplementation::inDragZone(short x, short y) { - int limit = m_CubeWidgetSize / 4; + qreal physicalCubeWidgetSize = getPhysicalCubeWidgetSize(); + int limit = physicalCubeWidgetSize / 4; return std::abs(x) < limit && std::abs(y) < limit; } bool NaviCubeImplementation::mouseMoved(short x, short y) { - bool hovering = std::abs(x) <= m_CubeWidgetSize / 2 && - std::abs(y) <= m_CubeWidgetSize / 2; + qreal physicalCubeWidgetSize = getPhysicalCubeWidgetSize(); + bool hovering = std::abs(x) <= physicalCubeWidgetSize / 2 && + std::abs(y) <= physicalCubeWidgetSize / 2; if (hovering != m_Hovering) { m_Hovering = hovering;