Fix some Quarter High DPI Display issues. Ported from code by Randall O'Reilly.

https://grey.colorado.edu/svn/coin3d/quarter/trunk/
This commit is contained in:
Mateusz Skowroński 2017-02-10 06:30:37 +01:00 committed by wmayer
parent bf66153f9c
commit 49a8705b1d
6 changed files with 91 additions and 3 deletions

View File

@ -48,6 +48,10 @@
#include <Quarter/devices/Keyboard.h>
#include <Quarter/devices/SpaceNavigatorDevice.h>
#if QT_VERSION >= 0x050000
#include <QGuiApplication>
#endif
namespace SIM { namespace Coin3D { namespace Quarter {
class EventFilterP {
@ -73,11 +77,17 @@ public:
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

View File

@ -48,6 +48,10 @@
#include <QtGui/QMouseEvent>
#include <QtGui/QWheelEvent>
#if QT_VERSION >= 0x050000
#include <QGuiApplication>
#endif
#include <Inventor/SbVec2s.h>
#include <Inventor/events/SoEvents.h>
#include <Inventor/errors/SoDebugError.h>
@ -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);

View File

@ -89,6 +89,12 @@
#include "QuarterWidgetP.h"
#include "QuarterP.h"
#if QT_VERSION >= 0x050000
#include <QWindow>
#include <QGuiApplication>
#endif
using namespace SIM::Coin3D::Quarter;
/*!
@ -488,6 +494,23 @@ QuarterWidget::stereoMode(void) const
return static_cast<StereoMode>(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<int>(dev_pix_ratio * event->size().width());
int height = static_cast<int>(dev_pix_ratio * event->size().height());
SbViewportRegion vp(width, height);
PRIVATE(this)->sorendermanager->setViewportRegion(vp);
PRIVATE(this)->soeventmanager->setViewportRegion(vp);
if (scene())

View File

@ -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 @@ public:
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:

View File

@ -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);

View File

@ -92,6 +92,7 @@ public:
bool processdelayqueue;
QUrl navigationModeFile;
SoScXMLStateMachine * currentStateMachine;
qreal device_pixel_ratio;
static void rendercb(void * userdata, SoRenderManager *);
static void prerendercb(void * userdata, SoRenderManager * manager);