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