From ebece20a4323c337c902a5b086b1c024f99c5912 Mon Sep 17 00:00:00 2001 From: Jeffrey Pfau Date: Fri, 1 May 2015 00:53:25 -0700 Subject: [PATCH] Qt: Memory view selection --- src/platform/qt/MemoryModel.cpp | 84 +++++++++++++++++++++++++++------ src/platform/qt/MemoryModel.h | 7 +++ 2 files changed, 77 insertions(+), 14 deletions(-) diff --git a/src/platform/qt/MemoryModel.cpp b/src/platform/qt/MemoryModel.cpp index 46dc86a86..0aa0a7c69 100644 --- a/src/platform/qt/MemoryModel.cpp +++ b/src/platform/qt/MemoryModel.cpp @@ -24,6 +24,8 @@ MemoryModel::MemoryModel(QWidget* 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 @@ MemoryModel::MemoryModel(QWidget* parent) 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 @@ void MemoryModel::jumpToAddress(uint32_t address) { } 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 @@ void MemoryModel::paintEvent(QPaintEvent* event) { 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 @@ void MemoryModel::paintEvent(QPaintEvent* event) { 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 @@ void MemoryModel::wheelEvent(QWheelEvent* event) { 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 @@ void MemoryModel::boundsCheck() { 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; +} diff --git a/src/platform/qt/MemoryModel.h b/src/platform/qt/MemoryModel.h index 304fbba92..a1efac6ec 100644 --- a/src/platform/qt/MemoryModel.h +++ b/src/platform/qt/MemoryModel.h @@ -37,10 +37,14 @@ 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; int m_cellHeight; @@ -53,6 +57,9 @@ private: QVector m_staticNumbers; QVector m_staticAscii; QStaticText m_regionName; + QSizeF m_cellSize; + QPair m_selection; + uint32_t m_selectionAnchor; }; }