From eaed889e628192acc29891ccd5456a4ed3d05e86 Mon Sep 17 00:00:00 2001 From: baldurk Date: Fri, 30 Sep 2016 18:18:07 +0200 Subject: [PATCH] Implement zooming and scaling --- qrenderdoc/Widgets/CustomPaintWidget.cpp | 7 +- qrenderdoc/Widgets/CustomPaintWidget.h | 2 + qrenderdoc/Windows/TextureViewer.cpp | 146 ++++++++++++++++++++++- qrenderdoc/Windows/TextureViewer.h | 16 +++ qrenderdoc/Windows/TextureViewer.ui | 46 +++++-- 5 files changed, 206 insertions(+), 11 deletions(-) diff --git a/qrenderdoc/Widgets/CustomPaintWidget.cpp b/qrenderdoc/Widgets/CustomPaintWidget.cpp index 8087c0fec..d943ea422 100644 --- a/qrenderdoc/Widgets/CustomPaintWidget.cpp +++ b/qrenderdoc/Widgets/CustomPaintWidget.cpp @@ -24,6 +24,11 @@ void CustomPaintWidget::mouseMoveEvent(QMouseEvent *e) emit mouseMove(e); } +void CustomPaintWidget::wheelEvent(QWheelEvent *e) +{ + emit mouseWheel(e); +} + void CustomPaintWidget::resizeEvent(QResizeEvent *e) { emit resize(e); @@ -33,7 +38,7 @@ void CustomPaintWidget::paintEvent(QPaintEvent *e) { if(m_Output) { - m_Core->Renderer()->BlockInvoke([this](IReplayRenderer *r) { m_Output->Display(); }); + m_Core->Renderer()->AsyncInvoke([this](IReplayRenderer *r) { m_Output->Display(); }); } else { diff --git a/qrenderdoc/Widgets/CustomPaintWidget.h b/qrenderdoc/Widgets/CustomPaintWidget.h index 45dff6573..2ff7184a3 100644 --- a/qrenderdoc/Widgets/CustomPaintWidget.h +++ b/qrenderdoc/Widgets/CustomPaintWidget.h @@ -22,10 +22,12 @@ signals: void clicked(QMouseEvent *e); void mouseMove(QMouseEvent *e); void resize(QResizeEvent *e); + void mouseWheel(QWheelEvent *e); private slots: void mousePressEvent(QMouseEvent *e) override; void mouseMoveEvent(QMouseEvent *e) override; + void wheelEvent(QWheelEvent *e) override; void resizeEvent(QResizeEvent *e) override; public slots: diff --git a/qrenderdoc/Windows/TextureViewer.cpp b/qrenderdoc/Windows/TextureViewer.cpp index 91804bac9..884faa5cc 100644 --- a/qrenderdoc/Windows/TextureViewer.cpp +++ b/qrenderdoc/Windows/TextureViewer.cpp @@ -40,8 +40,13 @@ TextureViewer::TextureViewer(Core *core, QWidget *parent) QObject::connect(ui->render, &CustomPaintWidget::clicked, this, &TextureViewer::render_mouseClick); QObject::connect(ui->render, &CustomPaintWidget::mouseMove, this, &TextureViewer::render_mouseMove); + QObject::connect(ui->render, &CustomPaintWidget::mouseWheel, this, + &TextureViewer::render_mouseWheel); QObject::connect(ui->render, &CustomPaintWidget::resize, this, &TextureViewer::render_resize); + QObject::connect(ui->zoomOption->lineEdit(), &QLineEdit::returnPressed, this, + &TextureViewer::on_zoomOption_returnPressed); + ui->dockarea->addToolWindow(ui->renderContainer, ToolWindowManager::EmptySpace); ui->dockarea->setToolWindowProperties(renderContainer, ToolWindowManager::DisallowUserDocking | ToolWindowManager::HideCloseButton | @@ -150,6 +155,11 @@ TextureViewer::TextureViewer(Core *core, QWidget *parent) ui->statusbar->addWidget(statusflowWidget); + ui->zoomOption->addItems({"10%", "25%", "50%", "75%", "100%", "200%", "400%", "800%"}); + + ui->zoomOption->setCurrentText(""); + ui->fitToWindow->toggle(); + UI_UpdateTextureDetails(); } @@ -508,9 +518,24 @@ void TextureViewer::UI_UpdateTextureDetails() void TextureViewer::UI_OnTextureSelectionChanged(bool newdraw) { + UI_UpdateFittedScale(); UI_UpdateTextureDetails(); } +void TextureViewer::render_mouseWheel(QWheelEvent *e) +{ + QPoint cursorPos = e->pos(); + + setFitToWindow(false); + + // scroll in logarithmic scale + double logScale = logf(m_TexDisplay.scale); + logScale += e->delta() / 2500.0; + UI_SetScale((float)expf(logScale), cursorPos.x(), cursorPos.y()); + + e->accept(); +} + void TextureViewer::render_mouseMove(QMouseEvent *e) { m_CurHoverPixel.setX(int(((float)e->x() - m_TexDisplay.offx) / m_TexDisplay.scale)); @@ -586,7 +611,7 @@ void TextureViewer::render_mouseClick(QMouseEvent *e) void TextureViewer::render_resize(QResizeEvent *e) { - // UI_UpdateFittedScale(); + UI_UpdateFittedScale(); UI_CalcScrollbars(); m_Core->Renderer()->AsyncInvoke([this](IReplayRenderer *) { RT_UpdateAndDisplay(); }); @@ -623,8 +648,11 @@ QPoint TextureViewer::getScrollPosition() void TextureViewer::setScrollPosition(const QPoint &pos) { - m_TexDisplay.offx = qBound(CurMaxScrollX(), (float)pos.x(), 0.0f); - m_TexDisplay.offy = qBound(CurMaxScrollY(), (float)pos.y(), 0.0f); + m_TexDisplay.offx = qMax(CurMaxScrollX(), (float)pos.x()); + m_TexDisplay.offy = qMax(CurMaxScrollY(), (float)pos.y()); + + m_TexDisplay.offx = qMin(0.0f, m_TexDisplay.offx); + m_TexDisplay.offy = qMin(0.0f, m_TexDisplay.offy); if(ScrollUpdateScrollbars) { @@ -821,3 +849,115 @@ void TextureViewer::OnEventSelected(uint32_t eventID) // CurrentTexture.ID)) UI_OnTextureSelectionChanged(true); } + +float TextureViewer::GetFitScale() +{ + FetchTexture *texptr = m_Core->GetTexture(m_TexDisplay.texid); + + if(texptr == NULL) + return 1.0f; + + float xscale = (float)ui->render->width() / (float)texptr->width; + float yscale = (float)ui->render->height() / (float)texptr->height; + return qMin(xscale, yscale); +} + +void TextureViewer::UI_UpdateFittedScale() +{ + if(ui->fitToWindow->isChecked()) + UI_SetScale(1.0f); +} + +void TextureViewer::UI_SetScale(float s) +{ + UI_SetScale(s, ui->render->width() / 2, ui->render->height() / 2); +} + +void TextureViewer::UI_SetScale(float s, int x, int y) +{ + if(ui->fitToWindow->isChecked()) + s = GetFitScale(); + + float prevScale = m_TexDisplay.scale; + + m_TexDisplay.scale = qBound(0.1f, s, 256.0f); + + m_Core->Renderer()->AsyncInvoke([this](IReplayRenderer *) { RT_UpdateAndDisplay(); }); + + float scaleDelta = (m_TexDisplay.scale / prevScale); + + QPoint newPos = getScrollPosition(); + + newPos -= QPoint(x, y); + newPos = QPoint((int)(newPos.x() * scaleDelta), (int)(newPos.y() * scaleDelta)); + newPos += QPoint(x, y); + + setScrollPosition(newPos); + + setCurrentZoomValue(m_TexDisplay.scale); + + UI_CalcScrollbars(); +} + +void TextureViewer::setCurrentZoomValue(float zoom) +{ + ui->zoomOption->setCurrentText(QString::number(ceil(zoom * 100)) + "%"); +} + +float TextureViewer::getCurrentZoomValue() +{ + if(ui->fitToWindow->isChecked()) + return m_TexDisplay.scale; + + QString zoomText = ui->zoomOption->currentText().replace('%', ' '); + + bool ok = false; + int zoom = zoomText.toInt(&ok); + + if(!ok) + zoom = 100; + + return (float)(zoom) / 100.0f; +} + +void TextureViewer::setFitToWindow(bool checked) +{ + if(checked) + { + UI_UpdateFittedScale(); + ui->fitToWindow->setChecked(true); + } + else if(!checked) + { + ui->fitToWindow->setChecked(false); + float curScale = m_TexDisplay.scale; + ui->zoomOption->setCurrentText(""); + setCurrentZoomValue(curScale); + } +} + +void TextureViewer::on_fitToWindow_toggled(bool checked) +{ + UI_UpdateFittedScale(); +} + +void TextureViewer::on_zoomExactSize_clicked() +{ + ui->fitToWindow->setChecked(false); + UI_SetScale(1.0f); +} + +void TextureViewer::on_zoomOption_currentIndexChanged(int index) +{ + if(index >= 0) + { + setFitToWindow(false); + ui->zoomOption->setCurrentText(ui->zoomOption->itemText(index)); + UI_SetScale(getCurrentZoomValue()); + } +} + +void TextureViewer::on_zoomOption_returnPressed() +{ + UI_SetScale(getCurrentZoomValue()); +} diff --git a/qrenderdoc/Windows/TextureViewer.h b/qrenderdoc/Windows/TextureViewer.h index 788c98a2e..5361c1fc1 100644 --- a/qrenderdoc/Windows/TextureViewer.h +++ b/qrenderdoc/Windows/TextureViewer.h @@ -26,10 +26,17 @@ public: private slots: void render_mouseClick(QMouseEvent *e); void render_mouseMove(QMouseEvent *e); + void render_mouseWheel(QWheelEvent *e); void render_resize(QResizeEvent *e); + void on_renderHScroll_valueChanged(int position); void on_renderVScroll_valueChanged(int position); + void on_fitToWindow_toggled(bool checked); + void on_zoomExactSize_clicked(); + void on_zoomOption_currentIndexChanged(int index); + void on_zoomOption_returnPressed(); + private: void RT_FetchCurrentPixel(uint32_t x, uint32_t y, PixelValue &pickValue, PixelValue &realValue); void RT_PickPixelsAndUpdate(); @@ -40,14 +47,23 @@ private: void UI_UpdateTextureDetails(); void UI_OnTextureSelectionChanged(bool newdraw); + void setFitToWindow(bool checked); + + void setCurrentZoomValue(float zoom); + float getCurrentZoomValue(); + bool ScrollUpdateScrollbars = true; float CurMaxScrollX(); float CurMaxScrollY(); + float GetFitScale(); + QPoint getScrollPosition(); void setScrollPosition(const QPoint &pos); + void UI_UpdateFittedScale(); + void UI_SetScale(float s); void UI_SetScale(float s, int x, int y); void UI_CalcScrollbars(); diff --git a/qrenderdoc/Windows/TextureViewer.ui b/qrenderdoc/Windows/TextureViewer.ui index 0ece4c3ee..22a6bdd5b 100644 --- a/qrenderdoc/Windows/TextureViewer.ui +++ b/qrenderdoc/Windows/TextureViewer.ui @@ -187,8 +187,8 @@ - 200 - 145 + 240 + 140 129 28 @@ -238,7 +238,7 @@ 3 145 - 191 + 221 28 @@ -271,14 +271,39 @@ 2 - + Zoom - + + + true + + + 1:1 + + + false + + + false + + + Qt::ToolButtonTextBesideIcon + + + true + + + + + + + true + Fit @@ -301,10 +326,17 @@ - + + + true + + + QComboBox::NoInsert + + - +