mirror of
https://github.com/rizinorg/cutter.git
synced 2025-01-30 16:25:04 +00:00
DisassemblerGraphView zooming fix (#1354)
* Zooming of DisassemblerGraphView now works to cursor instead of top left corner. * formatting fix. * Fix refactor bug.
This commit is contained in:
parent
f59dce1727
commit
e096f3ee4a
@ -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();
|
||||
}
|
||||
|
||||
|
@ -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 {
|
||||
|
@ -104,6 +104,7 @@ public:
|
||||
int getWidth() { return width; }
|
||||
int getHeight() { return height; }
|
||||
std::unordered_map<ut64, GraphBlock> 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();
|
||||
|
@ -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();
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user