diff --git a/src/Camera.cpp b/src/Camera.cpp index d5422ee..05dbc45 100644 --- a/src/Camera.cpp +++ b/src/Camera.cpp @@ -269,6 +269,70 @@ void Camera::animateToPlaneView(int plane) animGroup->start(QAbstractAnimation::DeleteWhenStopped); } +void Camera::animateToHomeView() +{ + auto* animGroup = new QParallelAnimationGroup(this); + + const float full_circle = 360.0f * 16.0f; + + float currentXRot = xRotation(); + float targetXRot = 30 * 16; + float diffX = targetXRot - currentXRot; + diffX = fmod(diffX, full_circle); + if (diffX > full_circle / 2.0f) { + diffX -= full_circle; + } else if (diffX < -full_circle / 2.0f) { + diffX += full_circle; + } + + auto* xRotAnim = new QPropertyAnimation(this, "xRotation"); + xRotAnim->setDuration(300); + xRotAnim->setStartValue(currentXRot); + xRotAnim->setEndValue(currentXRot + diffX); + xRotAnim->setEasingCurve(QEasingCurve::InOutQuad); + animGroup->addAnimation(xRotAnim); + + float currentYRot = yRotation(); + float targetYRot = -45 * 16; + float diffY = targetYRot - currentYRot; + diffY = fmod(diffY, full_circle); + if (diffY > full_circle / 2.0f) { + diffY -= full_circle; + } else if (diffY < -full_circle / 2.0f) { + diffY += full_circle; + } + + auto* yRotAnim = new QPropertyAnimation(this, "yRotation"); + yRotAnim->setDuration(300); + yRotAnim->setStartValue(currentYRot); + yRotAnim->setEndValue(currentYRot + diffY); + yRotAnim->setEasingCurve(QEasingCurve::InOutQuad); + animGroup->addAnimation(yRotAnim); + + auto* panXAnim = new QPropertyAnimation(this, "panX"); + panXAnim->setDuration(300); + panXAnim->setStartValue(panX()); + panXAnim->setEndValue(0.0f); + panXAnim->setEasingCurve(QEasingCurve::InOutQuad); + animGroup->addAnimation(panXAnim); + + auto* panYAnim = new QPropertyAnimation(this, "panY"); + panYAnim->setDuration(300); + panYAnim->setStartValue(panY()); + panYAnim->setEndValue(0.0f); + panYAnim->setEasingCurve(QEasingCurve::InOutQuad); + animGroup->addAnimation(panYAnim); + + auto* zoomAnim = new QPropertyAnimation(this, "zoom"); + zoomAnim->setDuration(300); + zoomAnim->setStartValue(zoom()); + zoomAnim->setEndValue(-20.0f); + zoomAnim->setEasingCurve(QEasingCurve::InOutQuad); + animGroup->addAnimation(zoomAnim); + + animGroup->start(QAbstractAnimation::DeleteWhenStopped); +} + void Camera::startRotation(const QVector3D& pivot) { m_rotationPivot = pivot; diff --git a/src/Camera.h b/src/Camera.h index 953cb2c..0b962d0 100644 --- a/src/Camera.h +++ b/src/Camera.h @@ -41,6 +41,7 @@ public: void animateToPlaneView(int plane); void animateRestoreState(); + void animateToHomeView(); void startRotation(const QVector3D& pivot); void stopRotation(); diff --git a/src/ViewCube.cpp b/src/ViewCube.cpp index 18f3c64..144c360 100644 --- a/src/ViewCube.cpp +++ b/src/ViewCube.cpp @@ -5,10 +5,12 @@ #include #include #include +#include #include ViewCube::ViewCube() { + m_homeButtonRenderer = new QSvgRenderer(QString(":/icons/rectangle.svg")); for (int i = 0; i < 6; ++i) { m_faceTextures[i] = nullptr; } @@ -20,6 +22,7 @@ ViewCube::~ViewCube() delete m_faceTextures[i]; } delete m_textureShaderProgram; + delete m_homeButtonRenderer; m_cubeVbo.destroy(); m_cubeVao.destroy(); m_axesVbo.destroy(); @@ -42,10 +45,9 @@ void ViewCube::paintGL(QOpenGLShaderProgram* simpleShader, int simpleShaderColor QRect viewCubeRect(width - viewCubeSize, 0, viewCubeSize, viewCubeSize); QPoint physicalMousePos = mousePos * QGuiApplication::primaryScreen()->devicePixelRatio(); - float opacity = 0.5f; - if (viewCubeRect.contains(physicalMousePos)) { - opacity = 1.0f; - } + m_isHovered = viewCubeRect.contains(physicalMousePos); + + float opacity = m_isHovered ? 1.0f : 0.5f; glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); @@ -210,3 +212,39 @@ void ViewCube::drawAxes(QOpenGLShaderProgram* simpleShader, int colorLoc, const glLineWidth(1.0f); } + +void ViewCube::paint2D(QPainter& painter, int widgetWidth, int widgetHeight) +{ + if (!m_isHovered) { + return; + } + + int viewCubeSize = 150; // logical pixels + int buttonSize = 24; + int buttonMargin = 8; + + int viewCubeX = widgetWidth - viewCubeSize; + int viewCubeY = 0; + + m_homeButtonRect = QRect(viewCubeX - buttonMargin - buttonSize, viewCubeY, buttonSize, buttonSize); + + if (m_homeButtonRenderer && m_homeButtonRenderer->isValid()) { + m_homeButtonRenderer->render(&painter, m_homeButtonRect); + } +} + +bool ViewCube::handleMousePress(const QPoint& pos, int widgetWidth, int widgetHeight) +{ + if (!m_isHovered) { + return false; + } + + int viewCubeSize = 150; + int buttonSize = 24; + int buttonMargin = 8; + int viewCubeX = widgetWidth - viewCubeSize; + int viewCubeY = 0; + QRect homeButtonRect(viewCubeX - buttonMargin - buttonSize, viewCubeY, buttonSize, buttonSize); + + return homeButtonRect.contains(pos); +} diff --git a/src/ViewCube.h b/src/ViewCube.h index f635ae8..db1ba61 100644 --- a/src/ViewCube.h +++ b/src/ViewCube.h @@ -9,6 +9,8 @@ class QOpenGLShaderProgram; class QOpenGLTexture; +class QPainter; +class QSvgRenderer; class ViewCube : protected QOpenGLFunctions { @@ -18,6 +20,8 @@ public: void initializeGL(); void paintGL(QOpenGLShaderProgram* simpleShader, int simpleShaderColorLoc, const QMatrix4x4& viewMatrix, int width, int height, const QPoint& mousePos); + void paint2D(QPainter& painter, int widgetWidth, int widgetHeight); + bool handleMousePress(const QPoint& pos, int widgetWidth, int widgetHeight); private: void createFaceTextures(); @@ -26,6 +30,10 @@ private: void drawViewCube(const QMatrix4x4& projection, const QMatrix4x4& view, float opacity); void drawAxes(QOpenGLShaderProgram* simpleShader, int colorLoc, const QMatrix4x4& projection, const QMatrix4x4& view); + bool m_isHovered = false; + QRect m_homeButtonRect; + QSvgRenderer* m_homeButtonRenderer = nullptr; + QOpenGLTexture* m_faceTextures[6]; QOpenGLShaderProgram* m_textureShaderProgram = nullptr; diff --git a/src/ViewportWidget.cpp b/src/ViewportWidget.cpp index e42af83..0774467 100644 --- a/src/ViewportWidget.cpp +++ b/src/ViewportWidget.cpp @@ -202,6 +202,7 @@ void ViewportWidget::paintGL() m_sketchGrid->paintAxisLabels(painter, static_cast(m_currentPlane), model, projection); } m_featureBrowser->paint(painter, width(), height()); + m_viewCube->paint2D(painter, width(), height()); if (m_activeSketchTool) { @@ -230,6 +231,12 @@ void ViewportWidget::mousePressEvent(QMouseEvent *event) } if (event->button() == Qt::LeftButton) { + if (m_viewCube->handleMousePress(event->pos(), width(), height())) { + m_camera->animateToHomeView(); + update(); + return; + } + if (m_isSelectingPlane) { if (m_highlightedPlane != SketchPlane::NONE) { emit planeSelected(m_highlightedPlane);