From 49a8705b1d57d91e3395d42058b32dc29606ddf7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateusz=20Skowro=C5=84ski?= Date: Fri, 10 Feb 2017 06:30:37 +0100 Subject: [PATCH] Fix some Quarter High DPI Display issues. Ported from code by Randall O'Reilly. https://grey.colorado.edu/svn/coin3d/quarter/trunk/ --- src/Gui/Quarter/EventFilter.cpp | 10 ++++++ src/Gui/Quarter/Mouse.cpp | 16 +++++++++ src/Gui/Quarter/QuarterWidget.cpp | 55 +++++++++++++++++++++++++++++- src/Gui/Quarter/QuarterWidget.h | 9 ++++- src/Gui/Quarter/QuarterWidgetP.cpp | 3 +- src/Gui/Quarter/QuarterWidgetP.h | 1 + 6 files changed, 91 insertions(+), 3 deletions(-) diff --git a/src/Gui/Quarter/EventFilter.cpp b/src/Gui/Quarter/EventFilter.cpp index 1bf82a9ce9c6..f0bb794c20f7 100644 --- a/src/Gui/Quarter/EventFilter.cpp +++ b/src/Gui/Quarter/EventFilter.cpp @@ -48,6 +48,10 @@ #include #include +#if QT_VERSION >= 0x050000 +#include +#endif + namespace SIM { namespace Coin3D { namespace Quarter { class EventFilterP { @@ -73,11 +77,17 @@ class EventFilterP { this->globalmousepos = event->globalPos(); SbVec2s mousepos(event->pos().x(), this->windowsize[1] - event->pos().y() - 1); + // the following corrects for high-dpi displays (e.g. mac retina) +#if QT_VERSION >= 0x050000 + mousepos *= ((QGuiApplication*)QGuiApplication::instance())->devicePixelRatio(); +#endif foreach(InputDevice * device, this->devices) { device->setMousePosition(mousepos); } } +private: + qreal device_pixel_ratio = 1.0; }; #define PRIVATE(obj) obj->pimpl diff --git a/src/Gui/Quarter/Mouse.cpp b/src/Gui/Quarter/Mouse.cpp index e61673d92faa..bb02cb96ff96 100644 --- a/src/Gui/Quarter/Mouse.cpp +++ b/src/Gui/Quarter/Mouse.cpp @@ -48,6 +48,10 @@ #include #include +#if QT_VERSION >= 0x050000 +#include +#endif + #include #include #include @@ -136,6 +140,10 @@ MouseP::mouseMoveEvent(QMouseEvent * event) assert(this->windowsize[1] != -1); SbVec2s pos(event->pos().x(), this->windowsize[1] - event->pos().y() - 1); + // the following corrects for high-dpi displays (e.g. mac retina) +#if QT_VERSION >= 0x050000 + pos *= ((QGuiApplication*)QGuiApplication::instance())->devicePixelRatio(); +#endif this->location2->setPosition(pos); this->mousebutton->setPosition(pos); return this->location2; @@ -146,6 +154,10 @@ MouseP::mouseWheelEvent(QWheelEvent * event) { PUBLIC(this)->setModifiers(this->mousebutton, event); SbVec2s pos(event->pos().x(), PUBLIC(this)->windowsize[1] - event->pos().y() - 1); + // the following corrects for high-dpi displays (e.g. mac retina) +#if QT_VERSION >= 0x050000 + pos *= ((QGuiApplication*)QGuiApplication::instance())->devicePixelRatio(); +#endif this->location2->setPosition(pos); this->mousebutton->setPosition(pos); @@ -167,6 +179,10 @@ MouseP::mouseButtonEvent(QMouseEvent * event) { PUBLIC(this)->setModifiers(this->mousebutton, event); SbVec2s pos(event->pos().x(), PUBLIC(this)->windowsize[1] - event->pos().y() - 1); + // the following corrects for high-dpi displays (e.g. mac retina) +#if QT_VERSION >= 0x050000 + pos *= ((QGuiApplication*)QGuiApplication::instance())->devicePixelRatio(); +#endif this->location2->setPosition(pos); this->mousebutton->setPosition(pos); diff --git a/src/Gui/Quarter/QuarterWidget.cpp b/src/Gui/Quarter/QuarterWidget.cpp index 5e918d3b60d7..e83e0cd970b9 100644 --- a/src/Gui/Quarter/QuarterWidget.cpp +++ b/src/Gui/Quarter/QuarterWidget.cpp @@ -89,6 +89,12 @@ #include "QuarterWidgetP.h" #include "QuarterP.h" +#if QT_VERSION >= 0x050000 +#include +#include +#endif + + using namespace SIM::Coin3D::Quarter; /*! @@ -488,6 +494,23 @@ QuarterWidget::stereoMode(void) const return static_cast(PRIVATE(this)->sorendermanager->getStereoMode()); } +/*! + \property QuarterWidget::devicePixelRatio + + \copydetails QuarterWidget::devicePixelRatio +*/ + +/*! + The ratio between logical and physical pixel sizes -- obtained from the window that +the widget is located within, and updated whenver any change occurs, emitting a devicePixelRatioChanged signal. Only available for version Qt 5.6 and above (will be 1.0 for all previous versions) + */ + +qreal +QuarterWidget::devicePixelRatio(void) const +{ + return PRIVATE(this)->device_pixel_ratio; +} + /*! Sets the Inventor scenegraph to be rendered */ @@ -675,12 +698,42 @@ QuarterWidget::seek(void) } } } + +bool +QuarterWidget::updateDevicePixelRatio(void) { +#if QT_VERSION >= 0x050000 + qreal dev_pix_ratio = 1.0; + QWidget* winwidg = window(); + QWindow* win = NULL; + if(winwidg) { + win = winwidg->windowHandle(); + } + if(win) { + dev_pix_ratio = win->devicePixelRatio(); + } + else { + dev_pix_ratio = ((QGuiApplication*)QGuiApplication::instance())->devicePixelRatio(); + } + if(PRIVATE(this)->device_pixel_ratio != dev_pix_ratio) { + PRIVATE(this)->device_pixel_ratio = dev_pix_ratio; + emit devicePixelRatioChanged(dev_pix_ratio); + return true; + } +#endif + return false; +} + /*! Overridden from QGLWidget to resize the Coin scenegraph */ void QuarterWidget::resizeEvent(QResizeEvent* event) { - SbViewportRegion vp(event->size().width(), event->size().height()); + updateDevicePixelRatio(); + qreal dev_pix_ratio = devicePixelRatio(); + int width = static_cast(dev_pix_ratio * event->size().width()); + int height = static_cast(dev_pix_ratio * event->size().height()); + + SbViewportRegion vp(width, height); PRIVATE(this)->sorendermanager->setViewportRegion(vp); PRIVATE(this)->soeventmanager->setViewportRegion(vp); if (scene()) diff --git a/src/Gui/Quarter/QuarterWidget.h b/src/Gui/Quarter/QuarterWidget.h index bc8483f9444a..804298b53144 100644 --- a/src/Gui/Quarter/QuarterWidget.h +++ b/src/Gui/Quarter/QuarterWidget.h @@ -73,6 +73,7 @@ class QUARTER_DLL_API QuarterWidget : public QGraphicsView { Q_PROPERTY(TransparencyType transparencyType READ transparencyType WRITE setTransparencyType) Q_PROPERTY(RenderMode renderMode READ renderMode WRITE setRenderMode) Q_PROPERTY(StereoMode stereoMode READ stereoMode WRITE setStereoMode) + Q_PROPERTY(qreal devicePixelRatio READ devicePixelRatio NOTIFY devicePixelRatioChanged) Q_ENUMS(TransparencyType) Q_ENUMS(RenderMode) @@ -123,6 +124,8 @@ class QUARTER_DLL_API QuarterWidget : public QGraphicsView { void setBackgroundColor(const QColor & color); QColor backgroundColor(void) const; + qreal devicePixelRatio(void) const; + void resetNavigationModeFile(void); void setNavigationModeFile(const QUrl & url = QUrl(QString::fromLatin1(DEFAULT_NAVIGATIONFILE))); const QUrl & navigationModeFile(void) const; @@ -183,12 +186,16 @@ public Q_SLOTS: void setStereoMode(StereoMode mode); void setTransparencyType(TransparencyType type); +Q_SIGNALS: + void devicePixelRatioChanged(qreal dev_pixel_ratio); + protected: virtual void paintEvent(QPaintEvent*); virtual void resizeEvent(QResizeEvent*); virtual bool viewportEvent(QEvent* event); virtual void actualRedraw(void); - + virtual bool updateDevicePixelRatio(void); + double renderTime; private: diff --git a/src/Gui/Quarter/QuarterWidgetP.cpp b/src/Gui/Quarter/QuarterWidgetP.cpp index 9d0d5d5b93ee..70d9e91a7883 100644 --- a/src/Gui/Quarter/QuarterWidgetP.cpp +++ b/src/Gui/Quarter/QuarterWidgetP.cpp @@ -86,7 +86,8 @@ QuarterWidgetP::QuarterWidgetP(QuarterWidget * masterptr, const QGLWidget * shar clearzbuffer(true), clearwindow(true), addactions(true), - contextmenu(NULL) + contextmenu(NULL), + device_pixel_ratio(1.0) { this->cachecontext = findCacheContext(masterptr, sharewidget); diff --git a/src/Gui/Quarter/QuarterWidgetP.h b/src/Gui/Quarter/QuarterWidgetP.h index 1f6aeb0e6336..8bb746f52fe5 100644 --- a/src/Gui/Quarter/QuarterWidgetP.h +++ b/src/Gui/Quarter/QuarterWidgetP.h @@ -92,6 +92,7 @@ class QuarterWidgetP { bool processdelayqueue; QUrl navigationModeFile; SoScXMLStateMachine * currentStateMachine; + qreal device_pixel_ratio; static void rendercb(void * userdata, SoRenderManager *); static void prerendercb(void * userdata, SoRenderManager * manager);