Qt: Memory view selection
Jeffrey Pfau jeffrey@endrift.com
Fri, 01 May 2015 00:53:25 -0700
2 files changed,
77 insertions(+),
14 deletions(-)
M
src/platform/qt/MemoryModel.cpp
→
src/platform/qt/MemoryModel.cpp
@@ -24,6 +24,8 @@ : QAbstractScrollArea(parent)
, m_cpu(nullptr) , m_top(0) , m_align(1) + , m_selection(0, 0) + , m_selectionAnchor(0) { m_font.setFamily("Source Code Pro"); m_font.setStyleHint(QFont::Monospace);@@ -50,7 +52,8 @@ }
setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn); - m_margins = QMargins(metrics.width("0FFFFFF0 ") + 4, m_cellHeight + 1, metrics.width(" AAAAAAAAAAAAAAAA") + 3, 0); + m_margins = QMargins(metrics.width("0FFFFFF0 ") + 3, m_cellHeight + 1, metrics.width(" AAAAAAAAAAAAAAAA") + 3, 0); + m_cellSize = QSizeF((viewport()->size().width() - (m_margins.left() + m_margins.right())) / 16.0, m_cellHeight); connect(verticalScrollBar(), &QSlider::sliderMoved, [this](int position) { m_top = position;@@ -104,6 +107,7 @@ verticalScrollBar()->setValue(m_top);
} void MemoryModel::resizeEvent(QResizeEvent*) { + m_cellSize = QSizeF((viewport()->size().width() - (m_margins.left() + m_margins.right())) / 16.0, m_cellHeight); verticalScrollBar()->setRange(0, (m_size >> 4) + 1 - viewport()->size().height() / m_cellHeight); boundsCheck(); }@@ -112,12 +116,11 @@ void MemoryModel::paintEvent(QPaintEvent* event) {
QPainter painter(viewport()); painter.setFont(m_font); QChar c0('0'); - QSizeF cellSize = QSizeF((viewport()->size().width() - (m_margins.left() + m_margins.right())) / 16.f, m_cellHeight); QSizeF letterSize = QSizeF(m_letterWidth, m_cellHeight); painter.drawStaticText(QPointF((m_margins.left() - m_regionName.size().width() - 1) / 2.0, 0), m_regionName); painter.drawText(QRect(QPoint(viewport()->size().width() - m_margins.right(), 0), QSize(m_margins.right(), m_margins.top())), Qt::AlignHCenter, tr("ASCII")); for (int x = 0; x < 16; ++x) { - painter.drawText(QRectF(QPointF(cellSize.width() * x + m_margins.left(), 0), cellSize), Qt::AlignHCenter, QString::number(x, 16).toUpper()); + painter.drawText(QRectF(QPointF(m_cellSize.width() * x + m_margins.left(), 0), m_cellSize), Qt::AlignHCenter, QString::number(x, 16).toUpper()); } int height = (viewport()->size().height() - m_cellHeight) / m_cellHeight; for (int y = 0; y < height; ++y) {@@ -127,25 +130,37 @@ painter.drawText(QRectF(QPointF(0, yp), QSizeF(m_margins.left(), m_cellHeight)), Qt::AlignHCenter, data);
switch (m_align) { case 2: for (int x = 0; x < 16; x += 2) { - uint16_t b = m_cpu->memory.load16(m_cpu, (y + m_top) * 16 + x + m_base, nullptr); - painter.drawStaticText(QPointF(cellSize.width() * (x + 1.0) - 2 * m_letterWidth + m_margins.left(), yp), m_staticNumbers[(b >> 8) & 0xFF]); - painter.drawStaticText(QPointF(cellSize.width() * (x + 1.0) + m_margins.left(), yp), m_staticNumbers[b & 0xFF]); + uint32_t address = (y + m_top) * 16 + x + m_base; + if (isInSelection(address)) { + painter.fillRect(QRectF(QPointF(m_cellSize.width() * x + m_margins.left(), yp), QSizeF(m_cellSize.width() * 2, m_cellSize.height())), Qt::lightGray); + } + uint16_t b = m_cpu->memory.load16(m_cpu, address, nullptr); + painter.drawStaticText(QPointF(m_cellSize.width() * (x + 1.0) - 2 * m_letterWidth + m_margins.left(), yp), m_staticNumbers[(b >> 8) & 0xFF]); + painter.drawStaticText(QPointF(m_cellSize.width() * (x + 1.0) + m_margins.left(), yp), m_staticNumbers[b & 0xFF]); } break; case 4: for (int x = 0; x < 16; x += 4) { - uint32_t b = m_cpu->memory.load32(m_cpu, (y + m_top) * 16 + x + m_base, nullptr); - painter.drawStaticText(QPointF(cellSize.width() * (x + 2.0) - 4 * m_letterWidth + m_margins.left(), yp), m_staticNumbers[(b >> 24) & 0xFF]); - painter.drawStaticText(QPointF(cellSize.width() * (x + 2.0) - 2 * m_letterWidth + m_margins.left(), yp), m_staticNumbers[(b >> 16) & 0xFF]); - painter.drawStaticText(QPointF(cellSize.width() * (x + 2.0) + m_margins.left(), yp), m_staticNumbers[(b >> 8) & 0xFF]); - painter.drawStaticText(QPointF(cellSize.width() * (x + 2.0) + 2 * m_letterWidth + m_margins.left(), yp), m_staticNumbers[b & 0xFF]); + uint32_t address = (y + m_top) * 16 + x + m_base; + if (isInSelection(address)) { + painter.fillRect(QRectF(QPointF(m_cellSize.width() * x + m_margins.left(), yp), QSizeF(m_cellSize.width() * 4, m_cellSize.height())), Qt::lightGray); + } + uint32_t b = m_cpu->memory.load32(m_cpu, address, nullptr); + painter.drawStaticText(QPointF(m_cellSize.width() * (x + 2.0) - 4 * m_letterWidth + m_margins.left(), yp), m_staticNumbers[(b >> 24) & 0xFF]); + painter.drawStaticText(QPointF(m_cellSize.width() * (x + 2.0) - 2 * m_letterWidth + m_margins.left(), yp), m_staticNumbers[(b >> 16) & 0xFF]); + painter.drawStaticText(QPointF(m_cellSize.width() * (x + 2.0) + m_margins.left(), yp), m_staticNumbers[(b >> 8) & 0xFF]); + painter.drawStaticText(QPointF(m_cellSize.width() * (x + 2.0) + 2 * m_letterWidth + m_margins.left(), yp), m_staticNumbers[b & 0xFF]); } break; case 1: default: for (int x = 0; x < 16; ++x) { - uint8_t b = m_cpu->memory.load8(m_cpu, (y + m_top) * 16 + x + m_base, nullptr); - painter.drawStaticText(QPointF(cellSize.width() * (x + 0.5) - m_letterWidth + m_margins.left(), yp), m_staticNumbers[b]); + uint32_t address = (y + m_top) * 16 + x + m_base; + if (isInSelection(address)) { + painter.fillRect(QRectF(QPointF(m_cellSize.width() * x + m_margins.left(), yp), m_cellSize), Qt::lightGray); + } + uint8_t b = m_cpu->memory.load8(m_cpu, address, nullptr); + painter.drawStaticText(QPointF(m_cellSize.width() * (x + 0.5) - m_letterWidth + m_margins.left(), yp), m_staticNumbers[b]); } break; }@@ -154,7 +169,7 @@ uint8_t b = m_cpu->memory.load8(m_cpu, (y + m_top) * 16 + x + m_base, nullptr);
painter.drawStaticText(QPointF(viewport()->size().width() - (16 - x) * m_margins.right() / 17.0 - m_letterWidth * 0.5, yp), b < 0x80 ? m_staticAscii[b] : m_staticAscii[0]); } } - painter.drawLine(m_margins.left() - 2, 0, m_margins.left() - 2, viewport()->size().height()); + painter.drawLine(m_margins.left(), 0, m_margins.left(), viewport()->size().height()); painter.drawLine(viewport()->size().width() - m_margins.right(), 0, viewport()->size().width() - m_margins.right(), viewport()->size().height()); painter.drawLine(0, m_margins.top(), viewport()->size().width(), m_margins.top()); }@@ -167,6 +182,34 @@ verticalScrollBar()->setValue(m_top);
update(); } +void MemoryModel::mousePressEvent(QMouseEvent* event) { + if (event->x() < m_margins.left() || event->y() < m_margins.top() || event->x() > size().width() - m_margins.right()) { + m_selection = qMakePair(0, 0); + return; + } + + QPoint position(event->pos() - QPoint(m_margins.left(), m_margins.top())); + uint32_t address = int(position.x() / m_cellSize.width()) + (int(position.y() / m_cellSize.height()) + m_top) * 16 + m_base; + m_selectionAnchor = address & ~(m_align - 1); + m_selection = qMakePair(m_selectionAnchor, m_selectionAnchor + m_align); + viewport()->update(); +} + +void MemoryModel::mouseMoveEvent(QMouseEvent* event) { + if (event->x() < m_margins.left() || event->y() < m_margins.top() || event->x() > size().width() - m_margins.right()) { + return; + } + + QPoint position(event->pos() - QPoint(m_margins.left(), m_margins.top())); + uint32_t address = int(position.x() / m_cellSize.width()) + (int(position.y() / m_cellSize.height()) + m_top) * 16 + m_base; + if ((address & ~(m_align - 1)) < m_selectionAnchor) { + m_selection = qMakePair(address & ~(m_align - 1), m_selectionAnchor + m_align); + } else { + m_selection = qMakePair(m_selectionAnchor, (address & ~(m_align - 1)) + m_align); + } + viewport()->update(); +} + void MemoryModel::boundsCheck() { if (m_top < 0) { m_top = 0;@@ -174,3 +217,16 @@ } else if (m_top > (m_size >> 4) + 1 - viewport()->size().height() / m_cellHeight) {
m_top = (m_size >> 4) + 1 - viewport()->size().height() / m_cellHeight; } } + +bool MemoryModel::isInSelection(uint32_t address) { + if (m_selection.first == m_selection.second) { + return false; + } + if (m_selection.second <= (address | (m_align - 1))) { + return false; + } + if (m_selection.first <= (address & ~(m_align - 1))) { + return true; + } + return false; +}
M
src/platform/qt/MemoryModel.h
→
src/platform/qt/MemoryModel.h
@@ -37,9 +37,13 @@ protected:
void resizeEvent(QResizeEvent*) override; void paintEvent(QPaintEvent*) override; void wheelEvent(QWheelEvent*) override; + void mousePressEvent(QMouseEvent*) override; + void mouseMoveEvent(QMouseEvent*) override; private: void boundsCheck(); + + bool isInSelection(uint32_t address); ARMCore* m_cpu; QFont m_font;@@ -53,6 +57,9 @@ QMargins m_margins;
QVector<QStaticText> m_staticNumbers; QVector<QStaticText> m_staticAscii; QStaticText m_regionName; + QSizeF m_cellSize; + QPair<uint32_t, uint32_t> m_selection; + uint32_t m_selectionAnchor; }; }