diff --git a/src/core/MainWindow.cpp b/src/core/MainWindow.cpp index 152ede3f..200fa2fd 100644 --- a/src/core/MainWindow.cpp +++ b/src/core/MainWindow.cpp @@ -392,10 +392,10 @@ void MainWindow::drawOverview() qreal baseScale = targetGraphDock->graphView->current_scale; qreal w = targetGraphDock->graphView->viewport()->width() * curScale / baseScale; qreal h = targetGraphDock->graphView->viewport()->height() * curScale / baseScale; - int graph_offset_x = targetGraphDock->graphView->offset_x; - int graph_offset_y = targetGraphDock->graphView->offset_y; - int overview_offset_x = overviewDock->graphView->offset_x; - int overview_offset_y = overviewDock->graphView->offset_y; + int graph_offset_x = targetGraphDock->graphView->offset.x(); + int graph_offset_y = targetGraphDock->graphView->offset.y(); + int overview_offset_x = overviewDock->graphView->offset.x(); + int overview_offset_y = overviewDock->graphView->offset.y(); int rangeRectX = graph_offset_x * curScale - overview_offset_x * curScale; int rangeRectY = graph_offset_y * curScale - overview_offset_y * curScale; @@ -413,10 +413,10 @@ void MainWindow::adjustGraph() qreal curScale = overviewDock->graphView->current_scale; int rectx = overviewDock->graphView->rangeRect.x(); int recty = overviewDock->graphView->rangeRect.y(); - int overview_offset_x = overviewDock->graphView->offset_x; - int overview_offset_y = overviewDock->graphView->offset_y; - targetGraphDock->graphView->offset_x = rectx /curScale + overview_offset_x; - targetGraphDock->graphView->offset_y = recty /curScale + overview_offset_y; + int overview_offset_x = overviewDock->graphView->offset.x(); + int overview_offset_y = overviewDock->graphView->offset.y(); + targetGraphDock->graphView->offset.rx() = rectx /curScale + overview_offset_x; + targetGraphDock->graphView->offset.ry() = recty /curScale + overview_offset_y; targetGraphDock->graphView->viewport()->update(); } diff --git a/src/widgets/DisassemblerGraphView.cpp b/src/widgets/DisassemblerGraphView.cpp index d8d5bc14..abe6f940 100644 --- a/src/widgets/DisassemblerGraphView.cpp +++ b/src/widgets/DisassemblerGraphView.cpp @@ -65,10 +65,10 @@ DisassemblerGraphView::DisassemblerGraphView(QWidget *parent) // Zoom shortcuts QShortcut *shortcut_zoom_in = new QShortcut(QKeySequence(Qt::Key_Plus), this); shortcut_zoom_in->setContext(Qt::WidgetShortcut); - connect(shortcut_zoom_in, SIGNAL(activated()), this, SLOT(zoomIn())); + connect(shortcut_zoom_in, &QShortcut::activated, this, std::bind(&DisassemblerGraphView::zoom, this, QPointF(0.5, 0.5), 1)); QShortcut *shortcut_zoom_out = new QShortcut(QKeySequence(Qt::Key_Minus), this); shortcut_zoom_out->setContext(Qt::WidgetShortcut); - connect(shortcut_zoom_out, SIGNAL(activated()), this, SLOT(zoomOut())); + connect(shortcut_zoom_out, &QShortcut::activated, this, std::bind(&DisassemblerGraphView::zoom, this, QPointF(0.5, 0.5), -1)); QShortcut *shortcut_zoom_reset = new QShortcut(QKeySequence(Qt::Key_Equal), this); shortcut_zoom_reset->setContext(Qt::WidgetShortcut); connect(shortcut_zoom_reset, SIGNAL(activated()), this, SLOT(zoomReset())); @@ -369,8 +369,8 @@ void DisassemblerGraphView::initFont() void DisassemblerGraphView::drawBlock(QPainter &p, GraphView::GraphBlock &block) { - int blockX = block.x - offset_x; - int blockY = block.y - offset_y; + int blockX = block.x - offset.x(); + int blockY = block.y - offset.y(); p.setPen(Qt::black); p.setBrush(Qt::gray); @@ -695,19 +695,21 @@ void DisassemblerGraphView::onSeekChanged(RVA addr) } } -void DisassemblerGraphView::zoomIn(QPoint mouse) +void DisassemblerGraphView::zoom(QPointF mouseRelativePos, double velocity) { - Q_UNUSED(mouse); - current_scale += 0.1; - viewport()->update(); - emit viewZoomed(); -} + mouseRelativePos.rx() *= size().width(); + mouseRelativePos.ry() *= size().height(); + mouseRelativePos /= current_scale; -void DisassemblerGraphView::zoomOut(QPoint mouse) -{ - Q_UNUSED(mouse); - current_scale -= 0.1; + auto globalMouse = mouseRelativePos + offset; + mouseRelativePos *= current_scale; + current_scale *= std::pow(1.25, velocity); current_scale = std::max(current_scale, 0.3); + mouseRelativePos /= current_scale; + + // Adjusting offset, so that zooming will be approaching to the cursor. + offset = globalMouse.toPoint() - mouseRelativePos.toPoint(); + viewport()->update(); emit viewZoomed(); } @@ -968,13 +970,13 @@ void DisassemblerGraphView::wheelEvent(QWheelEvent *event) if (Qt::ControlModifier == event->modifiers()) { const QPoint numDegrees = event->angleDelta() / 8; if (!numDegrees.isNull()) { - const QPoint numSteps = numDegrees / 15; - QPoint mouse = event->globalPos(); - if (numSteps.y() > 0) { - zoomIn(mouse); - } else if (numSteps.y() < 0) { - zoomOut(mouse); - } + int numSteps = numDegrees.y() / 15; + + QPointF relativeMousePos = event->pos(); + relativeMousePos.rx() /= size().width(); + relativeMousePos.ry() /= size().height(); + + zoom(relativeMousePos, numSteps); } event->accept(); } else { diff --git a/src/widgets/DisassemblerGraphView.h b/src/widgets/DisassemblerGraphView.h index c3783e16..aa2afe5d 100644 --- a/src/widgets/DisassemblerGraphView.h +++ b/src/widgets/DisassemblerGraphView.h @@ -104,6 +104,7 @@ public: int getWidth() { return width; } int getHeight() { return height; } std::unordered_map getBlocks() { return blocks; } + public slots: void refreshView(); void colorsUpdatedSlot(); @@ -111,8 +112,7 @@ public slots: void onSeekChanged(RVA addr); void toggleSync(); - void zoomIn(QPoint mouse = QPoint(0, 0)); - void zoomOut(QPoint mouse = QPoint(0, 0)); + void zoom(QPointF mouseRelativePos, double velocity); void zoomReset(); void takeTrue(); diff --git a/src/widgets/GraphView.cpp b/src/widgets/GraphView.cpp index c43edd31..9b1d9cb0 100644 --- a/src/widgets/GraphView.cpp +++ b/src/widgets/GraphView.cpp @@ -64,8 +64,8 @@ void GraphView::blockHelpEvent(GraphView::GraphBlock &block, QHelpEvent *event, bool GraphView::helpEvent(QHelpEvent *event) { - int x = event->pos().x() + offset_x; - int y = event->pos().y() - offset_y; + int x = event->pos().x() + offset.x(); + int y = event->pos().y() - offset.y(); for (auto &blockIt : blocks) { GraphBlock &block = blockIt.second; @@ -373,7 +373,7 @@ QPolygonF GraphView::recalculatePolygon(QPolygonF polygon) { QPolygonF ret; for (int i = 0; i < polygon.size(); i++) { - ret << QPointF(polygon[i].x() - offset_x, polygon[i].y() - offset_y); + ret << QPointF(polygon[i].x() - offset.x(), polygon[i].y() - offset.y()); } return ret; } @@ -409,10 +409,10 @@ void GraphView::paintEvent(QPaintEvent *event) qreal blockHeight = block.height * current_scale; // Check if block is visible by checking if block intersects with view area - if (offset_x * current_scale < blockX + blockWidth - && blockX < offset_x * current_scale + render_width - && offset_y * current_scale < blockY + blockHeight - && blockY < offset_y * current_scale + render_height) { + if (offset.x() * current_scale < blockX + blockWidth + && blockX < offset.x() * current_scale + render_width + && offset.y() * current_scale < blockY + blockHeight + && blockY < offset.y() * current_scale + render_height) { drawBlock(p, block); } @@ -696,14 +696,14 @@ void GraphView::center() void GraphView::centerX() { - offset_x = -((viewport()->width() - width * current_scale) / 2); - offset_x /= current_scale; + offset.rx() = -((viewport()->width() - width * current_scale) / 2); + offset.rx() /= current_scale; } void GraphView::centerY() { - offset_y = -((viewport()->height() - height * current_scale) / 2); - offset_y /= current_scale; + offset.ry() = -((viewport()->height() - height * current_scale) / 2); + offset.ry() /= current_scale; } void GraphView::showBlock(GraphBlock &block) @@ -717,12 +717,12 @@ void GraphView::showBlock(GraphBlock *block) centerX(); } else { int render_width = viewport()->width() / current_scale; - offset_x = block->x - ((render_width - block->width) / 2); + offset.rx() = block->x - ((render_width - block->width) / 2); } if (height * current_scale <= viewport()->height()) { centerY(); } else { - offset_y = block->y - 30; + offset.ry() = block->y - 30; } blockTransitionedTo(block); viewport()->update(); @@ -763,8 +763,8 @@ bool GraphView::checkPointClicked(QPointF &point, int x, int y, bool above_y) // Mouse events void GraphView::mousePressEvent(QMouseEvent *event) { - int x = event->pos().x() / current_scale + offset_x; - int y = event->pos().y() / current_scale + offset_y; + int x = event->pos().x() / current_scale + offset.x(); + int y = event->pos().y() / current_scale + offset.y(); // Check if a block was clicked for (auto &blockIt : blocks) { @@ -819,8 +819,8 @@ void GraphView::mousePressEvent(QMouseEvent *event) void GraphView::mouseMoveEvent(QMouseEvent *event) { if (scroll_mode) { - offset_x += (scroll_base_x - event->x()) / current_scale; - offset_y += (scroll_base_y - event->y()) / current_scale; + offset.rx() += (scroll_base_x - event->x()) / current_scale; + offset.ry() += (scroll_base_y - event->y()) / current_scale; scroll_base_x = event->x(); scroll_base_y = event->y(); viewport()->update(); @@ -829,8 +829,8 @@ void GraphView::mouseMoveEvent(QMouseEvent *event) void GraphView::mouseDoubleClickEvent(QMouseEvent *event) { - int x = event->pos().x() / current_scale + offset_x; - int y = event->pos().y() / current_scale + offset_y; + int x = event->pos().x() / current_scale + offset.x(); + int y = event->pos().y() / current_scale + offset.y(); // Check if a block was clicked for (auto &blockIt : blocks) { @@ -865,9 +865,11 @@ void GraphView::mouseReleaseEvent(QMouseEvent *event) void GraphView::wheelEvent(QWheelEvent *event) { - const QPoint delta = -event->angleDelta(); - offset_x += delta.x() / current_scale; - offset_y += delta.y() / current_scale; + QPoint delta = -event->angleDelta(); + + delta /= current_scale; + offset += delta; + viewport()->update(); event->accept(); } diff --git a/src/widgets/GraphView.h b/src/widgets/GraphView.h index ba81188c..1cfdb2c7 100644 --- a/src/widgets/GraphView.h +++ b/src/widgets/GraphView.h @@ -101,8 +101,7 @@ public: // Zoom data qreal current_scale = 1.0; - int offset_x = 0; - int offset_y = 0; + QPoint offset = QPoint(0, 0); /** * @brief flag to control if the cached pixmap should be used diff --git a/src/widgets/OverviewView.cpp b/src/widgets/OverviewView.cpp index b9f1fe75..d2db4915 100644 --- a/src/widgets/OverviewView.cpp +++ b/src/widgets/OverviewView.cpp @@ -44,8 +44,8 @@ void OverviewView::refreshView() void OverviewView::drawBlock(QPainter &p, GraphView::GraphBlock &block) { - int blockX = block.x - offset_x; - int blockY = block.y - offset_y; + int blockX = block.x - offset.x(); + int blockY = block.y - offset.y(); p.setPen(Qt::black); p.setBrush(Qt::gray);