From f880392f332a784a786d09ea961e5e1357011b2d Mon Sep 17 00:00:00 2001 From: Jeremy Bullock Date: Jun 02 2017 05:48:45 +0000 Subject: Merge pull request #1206 from shun-iwasawa/fix_high_dpi Fix GUI glitches with high dpi monitors --- diff --git a/toonz/sources/include/tools/toolutils.h b/toonz/sources/include/tools/toolutils.h index d196f86..c17fad7 100644 --- a/toonz/sources/include/tools/toolutils.h +++ b/toonz/sources/include/tools/toolutils.h @@ -128,7 +128,7 @@ void drawBalloon( std::string text, // balloon text const TPixel32 &color, // ballon background color (text is black) TPoint delta, // text position (pixels; pos is the origin; y grows upward) - bool isPicking = false, + double pixelSize, bool isPicking = false, std::vector *otherBalloons = 0); // avoid other balloons positions; add the new ballons positions diff --git a/toonz/sources/include/toonzqt/planeviewer.h b/toonz/sources/include/toonzqt/planeviewer.h index c53fe07..a173cf2 100644 --- a/toonz/sources/include/toonzqt/planeviewer.h +++ b/toonz/sources/include/toonzqt/planeviewer.h @@ -8,6 +8,9 @@ #include "traster.h" #include "timage.h" +// TnzQt includes +#include "toonzqt/glwidget_for_highdpi.h" + // Qt includes #include @@ -57,7 +60,7 @@ shader fx for some unknown reasons. So I will reluctantly keep using the obsolete class until the shader fx being overhauled. 2016/6/22 Shun */ -class DVAPI PlaneViewer : public QGLWidget { +class DVAPI PlaneViewer : public GLWidgetForHighDpi { public: PlaneViewer(QWidget *parent); diff --git a/toonz/sources/tnztools/edittool.cpp b/toonz/sources/tnztools/edittool.cpp index 1f5749c..38dd0cb 100644 --- a/toonz/sources/tnztools/edittool.cpp +++ b/toonz/sources/tnztools/edittool.cpp @@ -30,6 +30,8 @@ #include #include +#include +#include //============================================================================= // Scale Constraints @@ -290,12 +292,13 @@ class DragSplinePositionTool final : public DragChannelTool { double m_tolerance; public: - DragSplinePositionTool(const TStroke *spline, bool globalKeyframesEnabled) + DragSplinePositionTool(const TStroke *spline, bool globalKeyframesEnabled, + double pixelSize) : DragChannelTool(TStageObject::T_Path, globalKeyframesEnabled) , m_spline(spline) , m_offset(0.0) , m_splineLength(0) - , m_tolerance(0) {} + , m_tolerance(pixelSize * 10.0) {} double getLengthAtPos(const TPointD &pos) const { assert(m_spline); @@ -322,7 +325,6 @@ else return 0.0; m_firstPos = pos; start(); assert(m_spline); - m_tolerance = sqrt(tglGetPixelSize2()) * 10; m_splineLength = m_spline->getLength(); m_lengthAtCPs.clear(); int n = m_spline->getControlPointCount(); @@ -929,8 +931,8 @@ void EditTool::leftButtonDown(const TPointD &ppos, const TMouseEvent &e) { case Translation: if (const TStroke *spline = getSpline()) - m_dragTool = - new DragSplinePositionTool(spline, m_globalKeyframes.getValue()); + m_dragTool = new DragSplinePositionTool( + spline, m_globalKeyframes.getValue(), getPixelSize()); else m_dragTool = new DragPositionTool(m_lockPositionX.getValue(), m_lockPositionY.getValue(), @@ -1157,7 +1159,7 @@ void EditTool::draw() { return; } - double unit = sqrt(tglGetPixelSize2()); + double unit = getPixelSize(); /*-- ObjectのCenter位置を取得 --*/ glPushMatrix(); diff --git a/toonz/sources/tnztools/edittoolgadgets.cpp b/toonz/sources/tnztools/edittoolgadgets.cpp index b3a545c..1effcb5 100644 --- a/toonz/sources/tnztools/edittoolgadgets.cpp +++ b/toonz/sources/tnztools/edittoolgadgets.cpp @@ -19,10 +19,20 @@ #include "historytypes.h" +#include +#include + using namespace EditToolGadgets; GLdouble FxGadget::m_selectedColor[3] = {0.2, 0.8, 0.1}; +namespace { +int getDevPixRatio() { + static int devPixRatio = QApplication::desktop()->devicePixelRatio(); + return devPixRatio; +} +} + //************************************************************************************* // FxGadgetUndo definition //************************************************************************************* @@ -172,13 +182,15 @@ void FxGadget::setValue(const TPointParamP ¶m, const TPointD &pos) { //--------------------------------------------------------------------------- -void FxGadget::setPixelSize() { setPixelSize(sqrt(tglGetPixelSize2())); } +void FxGadget::setPixelSize() { + setPixelSize(sqrt(tglGetPixelSize2()) * getDevPixRatio()); +} //--------------------------------------------------------------------------- void FxGadget::drawTooltip(const TPointD &tooltipPos, std::string tooltipPosText) { - double unit = sqrt(tglGetPixelSize2()); + double unit = sqrt(tglGetPixelSize2()) * getDevPixRatio(); glPushMatrix(); glTranslated(tooltipPos.x, tooltipPos.y, 0.0); double sc = unit * 1.6; @@ -482,7 +494,7 @@ void AngleFxGadget::draw(bool picking) { else glColor3d(0, 0, 1); glPushName(getId()); - double pixelSize = sqrt(tglGetPixelSize2()); + double pixelSize = sqrt(tglGetPixelSize2()) * getDevPixRatio(); double r = pixelSize * 40; double a = pixelSize * 10, b = pixelSize * 5; tglDrawCircle(m_pos, r); diff --git a/toonz/sources/tnztools/skeletontool.cpp b/toonz/sources/tnztools/skeletontool.cpp index 3f425c9..43949a7 100644 --- a/toonz/sources/tnztools/skeletontool.cpp +++ b/toonz/sources/tnztools/skeletontool.cpp @@ -1096,8 +1096,8 @@ qDebug(" color = TPixel32(200, 200, 10, 200); else if (code == m_device) color = TPixel32(185, 255, 255); - ToolUtils::drawBalloon(pos, hook.m_name, color, TPoint(20, 20), isPicking(), - &balloons); + ToolUtils::drawBalloon(pos, hook.m_name, color, TPoint(20, 20), + getPixelSize(), isPicking(), &balloons); glPopName(); } @@ -1202,7 +1202,8 @@ glPopMatrix(); 255 * (191 - ialfa) / alfa, alfa); ToolUtils::drawBalloon(otherColumnsHooks[j].m_pos, otherColumnsHooks[j].m_name, // getHandle(), - color, TPoint(20, 20), false, &balloons); + color, TPoint(20, 20), getPixelSize(), false, + &balloons); HookData baseHook = currentColumnHooks[0]; baseHook.m_pos = otherColumnsHooks[j].m_pos; @@ -1228,7 +1229,7 @@ glPopMatrix(); TPixel32 color(100, 255, 100, 100); if (code == m_device) color = TPixel32(185, 255, 255); ToolUtils::drawBalloon(magicLink.m_h0.m_pos, name, color, TPoint(20, -20), - isPicking(), &balloons); + getPixelSize(), isPicking(), &balloons); glPopName(); } } @@ -1416,7 +1417,7 @@ void SkeletonTool::draw() { if (m_label != "") ToolUtils::drawBalloon(m_labelPos, m_label, TPixel32::Red, TPoint(20, -20), - false); + getPixelSize(), false); bool ikEnabled = m_mode.getValue() == INVERSE_KINEMATICS; assert(glGetError() == GL_NO_ERROR); diff --git a/toonz/sources/tnztools/toolutils.cpp b/toonz/sources/tnztools/toolutils.cpp index 3717d96..f77ed0d 100644 --- a/toonz/sources/tnztools/toolutils.cpp +++ b/toonz/sources/tnztools/toolutils.cpp @@ -1479,10 +1479,12 @@ const double ToolUtils::ConeSubVolume::m_values[] = { //--------------------------------------------------------------------------------------------- void ToolUtils::drawBalloon(const TPointD &pos, std::string text, - const TPixel32 &color, TPoint delta, bool isPicking, + const TPixel32 &color, TPoint delta, + double pixelSize, bool isPicking, std::vector *otherBalloons) { QString qText = QString::fromStdString(text); - QFont font("Arial", 10); // ,QFont::Bold); + QFont font("Arial"); // ,QFont::Bold); + font.setPixelSize(13); QFontMetrics fm(font); QRect textRect = fm.boundingRect(qText); @@ -1491,7 +1493,6 @@ void ToolUtils::drawBalloon(const TPointD &pos, std::string text, // avoid other balloons if (otherBalloons) { - double pixelSize = sqrt(tglGetPixelSize2()); std::vector &balloons = *otherBalloons; int n = (int)balloons.size(); TDimensionD balloonSize(pixelSize * (textRect.width() + mrg * 2), @@ -1517,7 +1518,6 @@ void ToolUtils::drawBalloon(const TPointD &pos, std::string text, int y0 = textRect.top() - mrg; int y1 = textRect.bottom() + mrg; - double pixelSize = sqrt(tglGetPixelSize2()); if (isPicking) { TTool::Viewer *viewer = TTool::getApplication()->getCurrentTool()->getTool()->getViewer(); diff --git a/toonz/sources/toonz/flipbook.cpp b/toonz/sources/toonz/flipbook.cpp index e2d8f7d..5dfb01b 100644 --- a/toonz/sources/toonz/flipbook.cpp +++ b/toonz/sources/toonz/flipbook.cpp @@ -2078,7 +2078,9 @@ void FlipBook::onDoubleClick(QMouseEvent *me) { if (!img) return; TAffine toWidgetRef(m_imageViewer->getImgToWidgetAffine()); - TRectD pixGeomD(toWidgetRef * getImageBoundsD(img)); + TRectD pixGeomD(TScale(1.0 / (double)m_imageViewer->getDevPixRatio()) * + toWidgetRef * getImageBoundsD(img)); + // TRectD pixGeomD(toWidgetRef * getImageBoundsD(img)); TRect pixGeom(tceil(pixGeomD.x0), tceil(pixGeomD.y0), tfloor(pixGeomD.x1) - 1, tfloor(pixGeomD.y1) - 1); diff --git a/toonz/sources/toonz/imageviewer.cpp b/toonz/sources/toonz/imageviewer.cpp index 7d1aad0..1cc0edc 100644 --- a/toonz/sources/toonz/imageviewer.cpp +++ b/toonz/sources/toonz/imageviewer.cpp @@ -1103,7 +1103,8 @@ TAffine ImageViewer::getImgToWidgetAffine() const { TAffine ImageViewer::getImgToWidgetAffine(const TRectD &geom) const { TPointD geomCenter((geom.x0 + geom.x1) * 0.5, (geom.y0 + geom.y1) * 0.5); - QRect widGeom(geometry()); + QRect widGeom(rect()); + TPointD viewerCenter((widGeom.left() + widGeom.right() + 1) * 0.5, (widGeom.top() + widGeom.bottom() + 1) * 0.5); @@ -1117,7 +1118,7 @@ TAffine ImageViewer::getImgToWidgetAffine(const TRectD &geom) const { //! Adapts image viewer's affine to display the passed image rect at maximized //! ratio void ImageViewer::adaptView(const TRect &imgRect, const TRect &viewRect) { - QRect viewerRect(geometry()); + QRect viewerRect(rect()); double imageScale = std::min(viewerRect.width() / (double)viewRect.getLx(), viewerRect.height() / (double)viewRect.getLy()); diff --git a/toonz/sources/toonz/ruler.cpp b/toonz/sources/toonz/ruler.cpp index ab37199..7c5556a 100644 --- a/toonz/sources/toonz/ruler.cpp +++ b/toonz/sources/toonz/ruler.cpp @@ -102,10 +102,10 @@ double Ruler::getPan() const { if (m_viewer->is3DView()) // Vertical 3D return m_viewer->getPan3D().y; else // Vertical 2D - return aff.a23; + return aff.a23 / m_viewer->getDevPixRatio(); else if (m_viewer->is3DView()) // Horizontal 3D return m_viewer->getPan3D().x; - return aff.a13; // Horizontal 2D + return aff.a13 / m_viewer->getDevPixRatio(); // Horizontal 2D } //----------------------------------------------------------------------------- @@ -129,7 +129,7 @@ void Ruler::drawVertical(QPainter &p) { for (i = 0; i < count; i++) { QColor color = (m_moving && count - 1 == i ? QColor(0, 255, 255) : QColor(0, 0, 255)); - double v = guides[i]; + double v = guides[i] / (double)m_viewer->getDevPixRatio(); int y = (int)(origin - zoom * v); p.fillRect(QRect(x0, y - 1, x1 - x0, 2), QBrush(color)); } @@ -184,7 +184,7 @@ void Ruler::drawHorizontal(QPainter &p) { for (i = 0; i < count; i++) { QColor color = (m_moving && count - 1 == i ? QColor(0, 255, 255) : QColor(0, 0, 255)); - double v = guides[i]; + double v = guides[i] / (double)m_viewer->getDevPixRatio(); int x = (int)(origin + zoom * v); p.fillRect(QRect(x - 1, y0, 2, y1 - y0), QBrush(color)); } @@ -247,7 +247,7 @@ void Ruler::mousePressEvent(QMouseEvent *e) { int i; int count = guides.size(); for (i = 0; i < count; i++) { - double g = guides[i]; + double g = guides[i] / (double)m_viewer->getDevPixRatio(); double dist2 = (g - v) * (g - v); if (selected < 0 || dist2 < minDist2) { minDist2 = dist2; @@ -256,7 +256,7 @@ void Ruler::mousePressEvent(QMouseEvent *e) { } if (selected < 0 || minDist2 > 25) { // crea una nuova guida - guides.push_back(v); + guides.push_back(v * m_viewer->getDevPixRatio()); m_viewer->update(); // aggiorna sprop!!!! } else { @@ -275,7 +275,7 @@ void Ruler::mousePressEvent(QMouseEvent *e) { void Ruler::mouseMoveEvent(QMouseEvent *e) { if (m_moving) { m_hiding = m_vertical ? (e->pos().x() < 0) : (e->pos().y() < 0); - getGuides().back() = posToValue(e->pos()); + getGuides().back() = posToValue(e->pos()) * m_viewer->getDevPixRatio(); // aggiorna sprop!!!! update(); m_viewer->update(); @@ -290,7 +290,7 @@ void Ruler::mouseMoveEvent(QMouseEvent *e) { int i; int count = guides.size(); for (i = 0; i < count; i++) { - double g = guides[i]; + double g = guides[i] / (double)m_viewer->getDevPixRatio(); double dist2 = (g - v) * (g - v); if (dist2 < minDist2) setToolTip(tr("Click and drag to move guide")); diff --git a/toonz/sources/toonz/sceneviewer.cpp b/toonz/sources/toonz/sceneviewer.cpp index 714d804..9016ac6 100644 --- a/toonz/sources/toonz/sceneviewer.cpp +++ b/toonz/sources/toonz/sceneviewer.cpp @@ -1254,7 +1254,7 @@ void SceneViewer::drawOverlay() { else { glPushMatrix(); tglMultMatrix(m_drawCameraAff); - m_pixelSize = sqrt(tglGetPixelSize2()); + m_pixelSize = sqrt(tglGetPixelSize2()) * getDevPixRatio(); ViewerDraw::drawCamera(f, m_pixelSize); glPopMatrix(); } @@ -1352,7 +1352,7 @@ void SceneViewer::drawOverlay() { if (tool->getToolType() & TTool::LevelTool && !app->getCurrentObject()->isSpline()) glScaled(m_dpiScale.x, m_dpiScale.y, 1); - m_pixelSize = sqrt(tglGetPixelSize2()); + m_pixelSize = sqrt(tglGetPixelSize2()) * getDevPixRatio(); tool->draw(); glPopMatrix(); // Used (only in the T_RGBPicker tool) to notify and set the currentColor diff --git a/toonz/sources/toonz/viewerdraw.cpp b/toonz/sources/toonz/viewerdraw.cpp index 4ef96bc..f72e272 100644 --- a/toonz/sources/toonz/viewerdraw.cpp +++ b/toonz/sources/toonz/viewerdraw.cpp @@ -263,9 +263,11 @@ void ViewerDraw::drawGridAndGuides(SceneViewer *viewer, double sc, Ruler *vr, if (vr) vGuideCount = vr->getGuideCount(); if (hr) hGuideCount = hr->getGuideCount(); - int rectX1, rectx2, recty1, recty2; - viewer->geometry().getCoords(&rectX1, &rectx2, &recty1, &recty2); - TRect clipRect = TRect(rectX1 - 20, recty2 + 20, recty1 + 10, rectx2 - 10); + // int xp1, yp1, xp2, yp2; + // viewer->geometry().getCoords(&xp1, &yp1, &xp2, &yp2); + TRect clipRect = TRect(-20, -10, viewer->width() + 10, viewer->height() + 20); + // TRect clipRect = TRect(xp1- 20, yp2 + 20, xp2 + 10, yp1 - 10); + // viewer->rect().adjusted(-20, -10, 10, 20); clipRect -= TPoint((clipRect.x0 + clipRect.x1) / 2, (clipRect.y0 + clipRect.y1) / 2); diff --git a/toonz/sources/toonzqt/planeviewer.cpp b/toonz/sources/toonzqt/planeviewer.cpp index 76b28c8..a348e9a 100644 --- a/toonz/sources/toonzqt/planeviewer.cpp +++ b/toonz/sources/toonzqt/planeviewer.cpp @@ -55,7 +55,7 @@ bool PlaneViewerZoomer::zoom(bool zoomin, bool resetZoom) { //========================================================================================= PlaneViewer::PlaneViewer(QWidget *parent) - : QGLWidget(parent) + : GLWidgetForHighDpi(parent) , m_firstResize(true) , m_xpos(0) , m_ypos(0) @@ -160,22 +160,25 @@ void PlaneViewer::resizeGL(int width, int height) { //========================================================================================= void PlaneViewer::mouseMoveEvent(QMouseEvent *event) { + QPoint curPos = event->pos() * getDevPixRatio(); if (event->buttons() & Qt::MidButton) - moveView(event->x() - m_xpos, height() - event->y() - m_ypos); + moveView(curPos.x() - m_xpos, height() - curPos.y() - m_ypos); - m_xpos = event->x(), m_ypos = height() - event->y(); + m_xpos = curPos.x(), m_ypos = height() - curPos.y(); } //------------------------------------------------------ void PlaneViewer::mousePressEvent(QMouseEvent *event) { - m_xpos = event->x(), m_ypos = height() - event->y(); + m_xpos = event->x() * getDevPixRatio(); + m_ypos = height() - event->y() * getDevPixRatio(); } //------------------------------------------------------ void PlaneViewer::wheelEvent(QWheelEvent *event) { - TPointD pos(event->x(), height() - event->y()); + TPointD pos(event->x() * getDevPixRatio(), + height() - event->y() * getDevPixRatio()); double zoom_par = 1 + event->delta() * 0.001; zoomView(pos.x, pos.y, zoom_par);