From 3f357fbbc37ae801fdd9015392d4f83bfe939290 Mon Sep 17 00:00:00 2001 From: "Thomas (nezza-_-) Roth" Date: Fri, 8 Dec 2017 13:21:24 +0100 Subject: [PATCH] CodeGraphic: Improve cursor rendering performance (#191) * CodeGraphic: Improve cursor rendering performance * GraphicsBar: Don't jump to invalid addresses --- src/widgets/CodeGraphic.cpp | 67 +++++++++++++++++++++++++------------ src/widgets/CodeGraphic.h | 15 ++++++--- 2 files changed, 57 insertions(+), 25 deletions(-) diff --git a/src/widgets/CodeGraphic.cpp b/src/widgets/CodeGraphic.cpp index 1627e6fc..bf9c721c 100644 --- a/src/widgets/CodeGraphic.cpp +++ b/src/widgets/CodeGraphic.cpp @@ -87,6 +87,7 @@ void GraphicsBar::fetchData() void GraphicsBar::fillData() { qDeleteAll(graphicsScene->items()); + cursorGraphicsItem = nullptr; int from = blockMaps.first()["from"].toInt(); int to = blockMaps.first()["to"].toInt(); @@ -110,10 +111,6 @@ void GraphicsBar::fillData() xToAddress.clear(); double x_start = 0.0; - - bool draw_cursor = false; - double cursor_x = 0.0; - for(int i=0; i < sections.length(); i++) { SectionDescription section = sections[i]; @@ -194,27 +191,32 @@ void GraphicsBar::fillData() graphicsScene->addItem(rect); } - // Check whether this block contains the current address. - if ((x2a.address_from <= current_address) && (current_address < x2a.address_to)) - { - draw_cursor = true; - RVA cursor_offset = (double)(current_address - x2a.address_from) * width_per_byte; - cursor_x = block_x_start + cursor_offset; - } - counter += 1; } x_start = x_end; } - // Draw the red cursor that shows where we are in the file (if we are in one of the rendered sections) - if(draw_cursor) + drawCursor(); +} + +void GraphicsBar::drawCursor() +{ + RVA offset = Core()->getOffset(); + double cursor_x = addressToLocalX(offset); + if (cursorGraphicsItem != nullptr) { - QGraphicsRectItem *rect = new QGraphicsRectItem(cursor_x, 0, 2, h); - rect->setPen(Qt::NoPen); - rect->setBrush(QBrush(QColor(255, 0, 0))); - graphicsScene->addItem(rect); + graphicsScene->removeItem(cursorGraphicsItem); + delete cursorGraphicsItem; } + if (cursor_x == nan("")) + { + return; + } + int h = this->codeGraphic->height(); + cursorGraphicsItem = new QGraphicsRectItem(cursor_x, 0, 2, h); + cursorGraphicsItem->setPen(Qt::NoPen); + cursorGraphicsItem->setBrush(QBrush(QColor(255, 0, 0))); + graphicsScene->addItem(cursorGraphicsItem); } QString GraphicsBar::generateTooltip(QString section_name, QMap map) @@ -237,7 +239,7 @@ void GraphicsBar::on_seekChanged(RVA addr) { Q_UNUSED(addr); // Re-paint, which will also update the cursor. - this->fillData(); + this->drawCursor(); } void GraphicsBar::mousePressEvent(QMouseEvent *event) @@ -245,14 +247,37 @@ void GraphicsBar::mousePressEvent(QMouseEvent *event) event->accept(); // Convert the local X coordinate to an address. qreal x = event->localPos().x(); + RVA address = localXToAddress(x); + if(address != 0) + { + Core()->seek(address); + } +} + +RVA GraphicsBar::localXToAddress(double x) +{ for(auto x2a : xToAddress) { if ((x2a.x_start <= x) && (x <= x2a.x_end)) { double offset = (x - x2a.x_start) / (x2a.x_end - x2a.x_start); double size = x2a.address_to - x2a.address_from; - Core()->seek(x2a.address_from + (offset * size)); - break; + return x2a.address_from + (offset * size); } } + return 0; +} + +double GraphicsBar::addressToLocalX(RVA address) +{ + for(auto x2a : xToAddress) + { + if ((x2a.address_from <= address) && (address < x2a.address_to)) + { + double offset = (double)(address - x2a.address_from) / (double)(x2a.address_to - x2a.address_from); + double size = x2a.x_end - x2a.x_start; + return x2a.x_start + (offset * size); + } + } + return nan(""); } diff --git a/src/widgets/CodeGraphic.h b/src/widgets/CodeGraphic.h index fd162a06..ee95e9da 100644 --- a/src/widgets/CodeGraphic.h +++ b/src/widgets/CodeGraphic.h @@ -30,20 +30,27 @@ private slots: void fetchAndPaintData(); void fetchData(); void fillData(); + void drawCursor(); void on_seekChanged(RVA addr); private: - QGraphicsView *codeGraphic; - QGraphicsScene *graphicsScene; - MainWindow *main; + QGraphicsView *codeGraphic; + QGraphicsScene *graphicsScene; + QGraphicsRectItem *cursorGraphicsItem; + MainWindow *main; RVA totalSectionsSize; QList sections; QList blockMaps; QList xToAddress; - QString generateTooltip(QString section_name, QMap map); // Used to check whether the width changed. If yes we need to re-initialize the scene (slow) int previousWidth; + + QString generateTooltip(QString section_name, QMap map); + + RVA localXToAddress(double x); + double addressToLocalX(RVA address); + void mousePressEvent(QMouseEvent *event) override; };