feat: Add animated home button to view cube to reset camera
Co-authored-by: aider (gemini/gemini-2.5-pro) <aider@aider.chat>
This commit is contained in:
@@ -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;
|
||||
|
||||
@@ -41,6 +41,7 @@ public:
|
||||
|
||||
void animateToPlaneView(int plane);
|
||||
void animateRestoreState();
|
||||
void animateToHomeView();
|
||||
|
||||
void startRotation(const QVector3D& pivot);
|
||||
void stopRotation();
|
||||
|
||||
@@ -5,10 +5,12 @@
|
||||
#include <QOpenGLShaderProgram>
|
||||
#include <QOpenGLTexture>
|
||||
#include <QScreen>
|
||||
#include <QSvgRenderer>
|
||||
#include <QVector>
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -202,6 +202,7 @@ void ViewportWidget::paintGL()
|
||||
m_sketchGrid->paintAxisLabels(painter, static_cast<SketchGrid::SketchPlane>(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);
|
||||
|
||||
Reference in New Issue
Block a user