Qt: Memory view selection

This commit is contained in:
Jeffrey Pfau 2015-05-01 00:53:25 -07:00
parent 21542034d3
commit ebece20a43
2 changed files with 77 additions and 14 deletions

View File

@ -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;
}

View File

@ -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<QStaticText> m_staticNumbers;
QVector<QStaticText> m_staticAscii;
QStaticText m_regionName;
QSizeF m_cellSize;
QPair<uint32_t, uint32_t> m_selection;
uint32_t m_selectionAnchor;
};
}