CodeGraphic: Improve cursor rendering performance (#191)

* CodeGraphic: Improve cursor rendering performance
* GraphicsBar: Don't jump to invalid addresses
This commit is contained in:
Thomas (nezza-_-) Roth 2017-12-08 13:21:24 +01:00 committed by xarkes
parent 8e0deeb115
commit 3f357fbbc3
2 changed files with 57 additions and 25 deletions

View File

@ -87,6 +87,7 @@ void GraphicsBar::fetchData()
void GraphicsBar::fillData() void GraphicsBar::fillData()
{ {
qDeleteAll(graphicsScene->items()); qDeleteAll(graphicsScene->items());
cursorGraphicsItem = nullptr;
int from = blockMaps.first()["from"].toInt(); int from = blockMaps.first()["from"].toInt();
int to = blockMaps.first()["to"].toInt(); int to = blockMaps.first()["to"].toInt();
@ -110,10 +111,6 @@ void GraphicsBar::fillData()
xToAddress.clear(); xToAddress.clear();
double x_start = 0.0; double x_start = 0.0;
bool draw_cursor = false;
double cursor_x = 0.0;
for(int i=0; i < sections.length(); i++) for(int i=0; i < sections.length(); i++)
{ {
SectionDescription section = sections[i]; SectionDescription section = sections[i];
@ -194,27 +191,32 @@ void GraphicsBar::fillData()
graphicsScene->addItem(rect); 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; counter += 1;
} }
x_start = x_end; 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) drawCursor();
if(draw_cursor) }
void GraphicsBar::drawCursor()
{
RVA offset = Core()->getOffset();
double cursor_x = addressToLocalX(offset);
if (cursorGraphicsItem != nullptr)
{ {
QGraphicsRectItem *rect = new QGraphicsRectItem(cursor_x, 0, 2, h); graphicsScene->removeItem(cursorGraphicsItem);
rect->setPen(Qt::NoPen); delete cursorGraphicsItem;
rect->setBrush(QBrush(QColor(255, 0, 0)));
graphicsScene->addItem(rect);
} }
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<QString, QVariant> map) QString GraphicsBar::generateTooltip(QString section_name, QMap<QString, QVariant> map)
@ -237,7 +239,7 @@ void GraphicsBar::on_seekChanged(RVA addr)
{ {
Q_UNUSED(addr); Q_UNUSED(addr);
// Re-paint, which will also update the cursor. // Re-paint, which will also update the cursor.
this->fillData(); this->drawCursor();
} }
void GraphicsBar::mousePressEvent(QMouseEvent *event) void GraphicsBar::mousePressEvent(QMouseEvent *event)
@ -245,14 +247,37 @@ void GraphicsBar::mousePressEvent(QMouseEvent *event)
event->accept(); event->accept();
// Convert the local X coordinate to an address. // Convert the local X coordinate to an address.
qreal x = event->localPos().x(); qreal x = event->localPos().x();
RVA address = localXToAddress(x);
if(address != 0)
{
Core()->seek(address);
}
}
RVA GraphicsBar::localXToAddress(double x)
{
for(auto x2a : xToAddress) for(auto x2a : xToAddress)
{ {
if ((x2a.x_start <= x) && (x <= x2a.x_end)) if ((x2a.x_start <= x) && (x <= x2a.x_end))
{ {
double offset = (x - x2a.x_start) / (x2a.x_end - x2a.x_start); double offset = (x - x2a.x_start) / (x2a.x_end - x2a.x_start);
double size = x2a.address_to - x2a.address_from; double size = x2a.address_to - x2a.address_from;
Core()->seek(x2a.address_from + (offset * size)); return x2a.address_from + (offset * size);
break;
} }
} }
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("");
} }

View File

@ -30,20 +30,27 @@ private slots:
void fetchAndPaintData(); void fetchAndPaintData();
void fetchData(); void fetchData();
void fillData(); void fillData();
void drawCursor();
void on_seekChanged(RVA addr); void on_seekChanged(RVA addr);
private: private:
QGraphicsView *codeGraphic; QGraphicsView *codeGraphic;
QGraphicsScene *graphicsScene; QGraphicsScene *graphicsScene;
QGraphicsRectItem *cursorGraphicsItem;
MainWindow *main; MainWindow *main;
RVA totalSectionsSize; RVA totalSectionsSize;
QList<SectionDescription> sections; QList<SectionDescription> sections;
QList<QVariantMap> blockMaps; QList<QVariantMap> blockMaps;
QList<struct xToAddress> xToAddress; QList<struct xToAddress> xToAddress;
QString generateTooltip(QString section_name, QMap<QString, QVariant> map);
// Used to check whether the width changed. If yes we need to re-initialize the scene (slow) // Used to check whether the width changed. If yes we need to re-initialize the scene (slow)
int previousWidth; int previousWidth;
QString generateTooltip(QString section_name, QMap<QString, QVariant> map);
RVA localXToAddress(double x);
double addressToLocalX(RVA address);
void mousePressEvent(QMouseEvent *event) override; void mousePressEvent(QMouseEvent *event) override;
}; };