Skip to content

Commit 508ea9e

Browse files
committed
Improve highlighting in hex editor widget
1 parent 1ad32e5 commit 508ea9e

File tree

4 files changed

+75
-8
lines changed

4 files changed

+75
-8
lines changed

gui/qt/debugger.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2023,6 +2023,7 @@ HexWidget *MainWindow::gotoMemAddrNoRaise(uint32_t address) {
20232023
const int offset = static_cast<int>(address - edit->getBase());
20242024
if (offset < edit->getSize()) {
20252025
edit->setOffset(offset);
2026+
edit->setHighlight(static_cast<int>(address));
20262027
memWidget = edit;
20272028
didGoto = true;
20282029
break;
@@ -2037,6 +2038,8 @@ HexWidget *MainWindow::gotoMemAddrNoRaise(uint32_t address) {
20372038
}
20382039
if (memWidget != Q_NULLPTR && !didGoto) {
20392040
memGoto(memWidget, address);
2041+
} else if (memWidget != Q_NULLPTR) {
2042+
memWidget->setHighlight(static_cast<int>(address));
20402043
}
20412044
return memWidget;
20422045
}

gui/qt/debugger/hexwidget.cpp

Lines changed: 66 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,19 @@ void HexWidget::setOffset(int offset) {
131131
}
132132

133133
void HexWidget::setCursorOffset(int offset, bool selection) {
134+
setCursorOffset(offset, selection, true);
135+
}
136+
137+
void HexWidget::setHighlight(const int address) {
138+
const int normalized = address < 0 ? -1 : address;
139+
if (m_highlightedAddr == normalized) {
140+
return;
141+
}
142+
m_highlightedAddr = normalized;
143+
viewport()->update();
144+
}
145+
146+
void HexWidget::setCursorOffset(int offset, bool selection, bool clearHighlight) {
134147
if (offset > m_size * 2) {
135148
offset = m_size * 2;
136149
}
@@ -141,6 +154,10 @@ void HexWidget::setCursorOffset(int offset, bool selection) {
141154
resetSelection();
142155
}
143156

157+
if (clearHighlight) {
158+
m_highlightedAddr = -1;
159+
}
160+
144161
m_cursorOffset = offset;
145162
adjust();
146163
showCursor();
@@ -254,18 +271,19 @@ void HexWidget::setSelection(int addr) {
254271
addr = 0;
255272
}
256273

257-
if (m_selectStart == -1) {
258-
m_selectStart = addr;
259-
m_selectEnd = addr;
260-
m_selectLen = 0;
274+
if (m_selectAnchor == -1) {
275+
m_selectAnchor = addr;
261276
}
262-
if (addr > m_selectStart) {
277+
278+
if (addr >= m_selectAnchor) {
279+
m_selectStart = m_selectAnchor;
263280
m_selectEnd = addr;
264-
m_selectLen = addr - m_selectStart + 1;
265281
} else {
266282
m_selectStart = addr;
267-
m_selectLen = m_selectEnd - addr + 1;
283+
m_selectEnd = m_selectAnchor;
268284
}
285+
286+
m_selectLen = (m_selectStart == -1 || m_selectEnd == -1) ? 0 : (m_selectEnd - m_selectStart + 1);
269287
}
270288

271289
void HexWidget::undo() {
@@ -310,12 +328,27 @@ void HexWidget::paintEvent(QPaintEvent *event) {
310328
const QColor &cSelected = pal.color(QPalette::Highlight);
311329
const QColor cModified = QColor(Qt::blue).lighter(160);
312330
const QColor cBoth = QColor(Qt::green).lighter(160);
331+
const bool darkMode = isRunningInDarkMode();
332+
const QColor boxBorder = darkMode ? QColor(0xdb, 0xdb, 0xdb) : QColor(0x66, 0x66, 0x66);
333+
QColor boxFill = darkMode ? QColor(0x55, 0x55, 0x55) : QColor(0xd0, 0xd0, 0xd0);
334+
boxFill.setAlpha(140);
313335
const int xOffset = horizontalScrollBar()->value();
314336
const int xAddr = m_addrLoc - xOffset;
315337

316338
painter.setRenderHint(QPainter::Antialiasing);
317339
painter.fillRect(region, cBg);
318340

341+
const auto drawHighlightBox = [&](const QRect &rect) {
342+
if (!rect.isValid() || rect.isNull()) {
343+
return;
344+
}
345+
painter.save();
346+
painter.setPen(QPen(boxBorder, 1));
347+
painter.setBrush(boxFill);
348+
painter.drawRoundedRect(rect.adjusted(0, 0, -1, -1), 2, 2);
349+
painter.restore();
350+
};
351+
319352
painter.setPen(Qt::gray);
320353
painter.drawLine(m_dataLine - xOffset, region.top(), m_dataLine - xOffset, height());
321354
if (m_asciiArea) {
@@ -338,6 +371,22 @@ void HexWidget::paintEvent(QPaintEvent *event) {
338371
uint8_t flags = debug.addr[addr + m_base];
339372
bool selected = addr >= m_selectStart && addr <= m_selectEnd;
340373
bool modified = !m_modified.isEmpty() && m_modified[addr];
374+
const bool highlighted = m_highlightedAddr >= 0 && (m_base + addr) == m_highlightedAddr;
375+
const int xDataStart = xData;
376+
const int xAsciiStart = xAscii;
377+
QRect dataHighlightRect;
378+
QRect asciiHighlightRect;
379+
380+
if (highlighted) {
381+
if (!col) {
382+
dataHighlightRect.setRect(xDataStart, y - m_charHeight + m_margin, 2 * m_charWidth + 3, m_charHeight);
383+
} else {
384+
dataHighlightRect.setRect(xDataStart - m_charWidth, y - m_charHeight + m_margin, 3 * m_charWidth + 3, m_charHeight);
385+
}
386+
if (m_asciiArea) {
387+
asciiHighlightRect.setRect(xAsciiStart, y - m_charHeight + m_margin, m_charWidth + 1, m_charHeight);
388+
}
389+
}
341390

342391
QFont font = painter.font();
343392
const QFont fontorig = painter.font();
@@ -367,6 +416,10 @@ void HexWidget::paintEvent(QPaintEvent *event) {
367416
painter.fillRect(r, modified ? selected ? cBoth : cModified : cSelected);
368417
}
369418

419+
if (highlighted) {
420+
drawHighlightBox(dataHighlightRect);
421+
}
422+
370423
QString hex = int2hex(data, 2);
371424
if ((flags & DBG_MASK_READ) && (flags & DBG_MASK_WRITE)) {
372425
painter.setPen(Qt::darkGreen);
@@ -391,6 +444,9 @@ void HexWidget::paintEvent(QPaintEvent *event) {
391444
r.setRect(xAscii, y - m_charHeight + m_margin, m_charWidth, m_charHeight);
392445
painter.fillRect(r, modified ? selected ? cBoth : cModified : cSelected);
393446
}
447+
if (highlighted) {
448+
drawHighlightBox(asciiHighlightRect);
449+
}
394450
painter.drawText(xAscii, y, QChar(ch));
395451
xAscii += m_charWidth;
396452
}
@@ -421,6 +477,9 @@ void HexWidget::mousePressEvent(QMouseEvent *event) {
421477
int addr = getPosition(event->pos());
422478
if (addr >= 0) {
423479
setCursorOffset(addr, true);
480+
m_selectAnchor = addr / 2;
481+
m_selectStart = m_selectEnd = -1;
482+
m_selectLen = 0;
424483
}
425484
}
426485

gui/qt/debugger/hexwidget.h

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ class HexWidget : public QAbstractScrollArea {
1717
void setBytesPerLine(int bytes) { m_bytesPerLine = bytes; adjust(); }
1818
void setAsciiArea(bool area) { m_asciiArea = area; adjust(); }
1919
void setCursorOffset(int address, bool selection = true);
20+
void setHighlight(int address);
2021
void setScrollable(bool state) { m_scrollable = state; adjust(); }
2122
void setFont(const QFont &font) { QAbstractScrollArea::setFont(font); adjust(); }
2223
void setOffset(int addr);
@@ -52,11 +53,12 @@ private slots:
5253
void scroll(int value);
5354

5455
private:
56+
void setCursorOffset(int offset, bool selection, bool clearHighlight);
5557
void redo();
5658
void undo();
5759
void showCursor();
5860
void setSelection(int addr);
59-
void resetSelection() { m_selectStart = m_selectEnd = -1; }
61+
void resetSelection() { m_selectStart = m_selectEnd = -1; m_selectLen = 0; m_selectAnchor = -1; }
6062
bool isSelected() const { return m_selectStart != -1; }
6163
void setSelected(char n) { overwrite(m_selectStart * 2, QByteArray(m_selectLen, n)); }
6264
void overwrite(int pos, char c);
@@ -98,11 +100,13 @@ private slots:
98100
int m_selectStart;
99101
int m_selectEnd;
100102
int m_selectLen;
103+
int m_selectAnchor = -1;
101104

102105
bool m_scrollable = false; // fetch bytes from memory on scroll
103106
bool m_asciiArea = true; // show character representations
104107
bool m_scrolled = false; // scrolled while focused
105108
bool m_asciiEdit = false; // editing from the ascii side
109+
int m_highlightedAddr = -1; // Address to highlight with a box
106110

107111
QStack<stack_entry_t> m_stack;
108112
};

gui/qt/memorywidget.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -208,6 +208,7 @@ void MainWindow::memGoto(HexWidget *edit, uint32_t address) {
208208
edit->setBase(static_cast<int>(address));
209209
edit->setOffset(0);
210210
memUpdateEdit(edit, true);
211+
edit->setHighlight(static_cast<int>(address));
211212
}
212213

213214
void MainWindow::memGotoEdit(HexWidget *edit) {

0 commit comments

Comments
 (0)