diff --git a/Source/GUI/MemViewer/MemViewer.cpp b/Source/GUI/MemViewer/MemViewer.cpp old mode 100755 new mode 100644 index 616b25de..0666db06 --- a/Source/GUI/MemViewer/MemViewer.cpp +++ b/Source/GUI/MemViewer/MemViewer.cpp @@ -6,6 +6,7 @@ #include #include +#include #include #include #include @@ -17,13 +18,13 @@ MemViewer::MemViewer(QWidget* parent) : QAbstractScrollArea(parent) { initialise(); - std::fill(m_memoryMsElapsedLastChange, m_memoryMsElapsedLastChange + 16 * 16, 0); + std::fill(m_memoryMsElapsedLastChange, m_memoryMsElapsedLastChange + m_numCells, 0); updateMemoryData(); - std::memcpy(m_lastRawMemoryData, m_updatedRawMemoryData, 16 * 16); + std::memcpy(m_lastRawMemoryData, m_updatedRawMemoryData, m_numCells); setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn); - verticalScrollBar()->setRange(0, ((m_memViewEnd - m_memViewStart) / 16) - 1); - verticalScrollBar()->setPageStep(16); + changeMemoryRegion(false); + verticalScrollBar()->setPageStep(m_numRows); m_elapsedTimer.start(); @@ -39,26 +40,11 @@ MemViewer::~MemViewer() void MemViewer::initialise() { -#ifdef __linux__ - setFont(QFont("Monospace", 15)); -#elif _WIN32 - setFont(QFont("Courier New", 15)); -#endif - - m_hexKeyList = QList({Qt::Key_0, Qt::Key_1, Qt::Key_2, Qt::Key_3, Qt::Key_4, Qt::Key_5, - Qt::Key_6, Qt::Key_7, Qt::Key_8, Qt::Key_9, Qt::Key_A, Qt::Key_B, - Qt::Key_C, Qt::Key_D, Qt::Key_E, Qt::Key_F}); - m_charWidthEm = fontMetrics().width(QLatin1Char('M')); - m_charHeight = fontMetrics().height(); - m_hexAreaWidth = 16 * (m_charWidthEm * 2 + m_charWidthEm / 2); - m_hexAreaHeight = 16 * m_charHeight; - m_rowHeaderWidth = m_charWidthEm * (sizeof(u32) * 2 + 1) + m_charWidthEm / 2; - m_hexAsciiSeparatorPosX = m_rowHeaderWidth + m_hexAreaWidth; - m_columnHeaderHeight = m_charHeight + m_charWidthEm / 2; + updateFontSize(m_memoryFontSize); m_curosrRect = new QRect(); - m_updatedRawMemoryData = new char[16 * 16]; - m_lastRawMemoryData = new char[16 * 16]; - m_memoryMsElapsedLastChange = new int[16 * 16]; + m_updatedRawMemoryData = new char[m_numCells]; + m_lastRawMemoryData = new char[m_numCells]; + m_memoryMsElapsedLastChange = new int[m_numCells]; m_memViewStart = Common::MEM1_START; m_memViewEnd = Common::MEM1_END; m_currentFirstAddress = m_memViewStart; @@ -84,7 +70,7 @@ void MemViewer::updateMemoryData() (DolphinComm::DolphinAccessor::updateRAMCache() == Common::MemOperationReturnCode::OK); if (DolphinComm::DolphinAccessor::isValidConsoleAddress(m_currentFirstAddress)) DolphinComm::DolphinAccessor::copyRawMemoryFromCache(m_updatedRawMemoryData, - m_currentFirstAddress, 16 * 16); + m_currentFirstAddress, m_numCells); if (!m_validMemory) emit memErrorOccured(); } @@ -112,15 +98,15 @@ void MemViewer::jumpToAddress(const u32 address) else if (address >= Common::MEM2_START && m_memViewStart != Common::MEM2_START) changeMemoryRegion(true); - if (m_currentFirstAddress > m_memViewEnd - 16 * 16) - m_currentFirstAddress = m_memViewEnd - 16 * 16; - std::fill(m_memoryMsElapsedLastChange, m_memoryMsElapsedLastChange + 16 * 16, 0); + if (m_currentFirstAddress > m_memViewEnd - m_numCells) + m_currentFirstAddress = m_memViewEnd - m_numCells; + std::fill(m_memoryMsElapsedLastChange, m_memoryMsElapsedLastChange + m_numCells, 0); updateMemoryData(); - std::memcpy(m_lastRawMemoryData, m_updatedRawMemoryData, 16 * 16); + std::memcpy(m_lastRawMemoryData, m_updatedRawMemoryData, m_numCells); m_carretBetweenHex = false; m_disableScrollContentEvent = true; - verticalScrollBar()->setValue(((address & 0xFFFFFFF0) - m_memViewStart) / 16); + verticalScrollBar()->setValue(((address & 0xFFFFFFF0) - m_memViewStart) / m_numColumns); m_disableScrollContentEvent = false; viewport()->update(); @@ -131,25 +117,97 @@ void MemViewer::changeMemoryRegion(const bool isMEM2) { m_memViewStart = isMEM2 ? Common::MEM2_START : Common::MEM1_START; m_memViewEnd = isMEM2 ? Common::MEM2_END : Common::MEM1_END; - verticalScrollBar()->setRange(0, ((m_memViewEnd - m_memViewStart) / 16) - 1); + verticalScrollBar()->setRange(0, ((m_memViewEnd - m_memViewStart) / m_numColumns) - m_numRows); } void MemViewer::mousePressEvent(QMouseEvent* event) { + // Only handle left-click events + if (event->button() != Qt::MouseButton::LeftButton) + return; + int x = event->pos().x(); int y = event->pos().y(); - if (x >= m_rowHeaderWidth && x <= m_rowHeaderWidth + m_hexAreaWidth && y >= m_columnHeaderHeight) + + const bool wasEditingHex = m_editingHex; + const int spacing = m_charWidthEm / 2; + const int hexCellWidth = m_charWidthEm * 2 + spacing; + const int hexAreaLeft = m_rowHeaderWidth - spacing / 2; + const int asciiAreaLeft = m_hexAsciiSeparatorPosX + spacing; + const int areaTop = m_columnHeaderHeight + m_charHeight - fontMetrics().overlinePos(); + QRect hexArea(hexAreaLeft, areaTop, m_hexAreaWidth, m_charHeight * m_numRows); + QRect asciiArea(asciiAreaLeft, areaTop, m_charWidthEm * m_numColumns, m_charHeight * m_numRows); + + // Transform x and y to indices for column and row + if (hexArea.contains(x, y, false)) { - int oldSelectedPosX = m_byteSelectedPosX; - int oldSelectedPosY = m_byteSelectedPosY; - m_byteSelectedPosX = (x - m_rowHeaderWidth) / (m_charWidthEm / 2 + m_charWidthEm * 2); - m_byteSelectedPosY = (y - m_columnHeaderHeight) / m_charHeight; - if (oldSelectedPosX == m_byteSelectedPosX && oldSelectedPosY == m_byteSelectedPosY) - m_carretBetweenHex = !m_carretBetweenHex; - else - m_carretBetweenHex = false; + x = (x - hexAreaLeft) / hexCellWidth; + m_editingHex = true; + } + else if (asciiArea.contains(x, y, false)) + { + x = (x - asciiAreaLeft) / m_charWidthEm; + m_editingHex = false; + } + else + { + return; + } + y = (y - areaTop) / m_charHeight; + + // Toggle carrot-between-hex when the same byte is clicked twice from the hex table + m_carretBetweenHex = (m_editingHex && wasEditingHex && !m_carretBetweenHex && + m_byteSelectedPosX == x && m_byteSelectedPosY == y); + + m_byteSelectedPosX = x; + m_byteSelectedPosY = y; + + viewport()->update(); +} + +void MemViewer::wheelEvent(QWheelEvent* event) +{ + if (event->modifiers().testFlag(Qt::ControlModifier)) + { + if (event->delta() < 0 && m_memoryFontSize > 5) + updateFontSize(m_memoryFontSize - 1); + else if (event->delta() > 0) + updateFontSize(m_memoryFontSize + 1); + viewport()->update(); } + else + { + QAbstractScrollArea::wheelEvent(event); + } +} + +void MemViewer::updateFontSize(int newSize) +{ + m_memoryFontSize = newSize; + +#ifdef __linux__ + setFont(QFont("Monospace", m_memoryFontSize)); +#elif _WIN32 + setFont(QFont("Courier New", m_memoryFontSize)); +#endif + + m_charWidthEm = fontMetrics().width(QLatin1Char('M')); + m_charHeight = fontMetrics().height(); + m_hexAreaWidth = m_numColumns * (m_charWidthEm * 2 + m_charWidthEm / 2); + m_hexAreaHeight = m_numRows * m_charHeight; + m_rowHeaderWidth = m_charWidthEm * (sizeof(u32) * 2 + 1) + m_charWidthEm / 2; + m_hexAsciiSeparatorPosX = m_rowHeaderWidth + m_hexAreaWidth; + m_columnHeaderHeight = m_charHeight + m_charWidthEm / 2; +} + +void MemViewer::scrollToSelection() +{ + if (m_byteSelectedPosY < 0) + scrollContentsBy(0, -m_byteSelectedPosY); + else if (m_byteSelectedPosY >= m_numRows) + scrollContentsBy(0, m_numRows - m_byteSelectedPosY - 1); + viewport()->update(); } bool MemViewer::handleNaviguationKey(const int key) @@ -157,160 +215,169 @@ bool MemViewer::handleNaviguationKey(const int key) switch (key) { case Qt::Key_Up: - if (m_byteSelectedPosY != 0) - { - m_byteSelectedPosY--; - viewport()->update(); - } + if (verticalScrollBar()->value() + m_byteSelectedPosY <= verticalScrollBar()->minimum()) + QApplication::beep(); else - { - scrollContentsBy(0, 1); - } - return true; + m_byteSelectedPosY--; + scrollToSelection(); + break; case Qt::Key_Down: - if (m_byteSelectedPosY != 15) - { - m_byteSelectedPosY++; - viewport()->update(); - } + if (verticalScrollBar()->value() + m_byteSelectedPosY >= verticalScrollBar()->maximum()) + QApplication::beep(); else - { - scrollContentsBy(0, -1); - } - return true; + m_byteSelectedPosY++; + scrollToSelection(); + break; case Qt::Key_Left: - if (m_byteSelectedPosX != 0) + if (m_byteSelectedPosX <= 0 && m_byteSelectedPosY <= 0 && + verticalScrollBar()->value() == verticalScrollBar()->minimum()) { - m_byteSelectedPosX--; - viewport()->update(); - } - else if (m_byteSelectedPosY != 0) - { - m_byteSelectedPosX = 15; - m_byteSelectedPosY--; - viewport()->update(); + QApplication::beep(); } else { - m_byteSelectedPosX = 15; - m_byteSelectedPosY = 15; - scrollContentsBy(0, 1); + m_byteSelectedPosX--; + if (m_byteSelectedPosX < 0) + { + m_byteSelectedPosX += m_numColumns; + m_byteSelectedPosY--; + } + scrollToSelection(); } - return true; + break; case Qt::Key_Right: - if (m_byteSelectedPosX != 15) + if (m_byteSelectedPosX >= m_numColumns - 1 && m_byteSelectedPosY >= m_numRows - 1 && + verticalScrollBar()->value() == verticalScrollBar()->maximum()) { - m_byteSelectedPosX++; - viewport()->update(); - } - else if (m_byteSelectedPosY != 15) - { - m_byteSelectedPosX = 0; - m_byteSelectedPosY++; - viewport()->update(); + QApplication::beep(); } else { - m_byteSelectedPosX = 0; - m_byteSelectedPosY = 0; - scrollContentsBy(0, -1); + m_byteSelectedPosX++; + if (m_byteSelectedPosX >= m_numColumns) + { + m_byteSelectedPosX -= m_numColumns; + m_byteSelectedPosY++; + } + scrollToSelection(); } - return true; + break; case Qt::Key_PageUp: - scrollContentsBy(0, verticalScrollBar()->pageStep()); - return true; + scrollContentsBy(0, std::min(verticalScrollBar()->pageStep(), verticalScrollBar()->value())); + break; case Qt::Key_PageDown: - scrollContentsBy(0, -verticalScrollBar()->pageStep()); - return true; + scrollContentsBy(0, std::max(-verticalScrollBar()->pageStep(), + verticalScrollBar()->value() - verticalScrollBar()->maximum())); + break; case Qt::Key_Home: verticalScrollBar()->setValue(0); - return true; + m_byteSelectedPosX = 0; + m_byteSelectedPosY = 0; + viewport()->update(); + break; case Qt::Key_End: - verticalScrollBar()->setValue((m_memViewEnd - m_memViewStart) / 16 - 1); - return true; + verticalScrollBar()->setValue(verticalScrollBar()->maximum()); + m_byteSelectedPosX = m_numColumns - 1; + m_byteSelectedPosY = m_numRows - 1; + viewport()->update(); + break; default: return false; } + + // Always set the carrot at the start of a byte after navigating + m_carretBetweenHex = false; + return true; } -bool MemViewer::writeHexCharacterToSelectedMemory(const std::string hexCharToWrite) +bool MemViewer::writeCharacterToSelectedMemory(char byteToWrite) { - std::string editedByteStr = Common::formatMemoryToString( - m_updatedRawMemoryData + ((m_byteSelectedPosY * 16) + m_byteSelectedPosX), - Common::MemType::type_byteArray, 1, Common::MemBase::base_none, true); - if (m_carretBetweenHex) - editedByteStr[1] = hexCharToWrite[0]; - else - editedByteStr[0] = hexCharToWrite[0]; - - std::stringstream ss(editedByteStr); - unsigned int editedByteData = 0; - ss >> std::hex >> editedByteData; - char byteToWrite = static_cast(editedByteData); - u32 offsetToWrite = Common::dolphinAddrToOffset(m_currentFirstAddress + - (m_byteSelectedPosY * 16 + m_byteSelectedPosX)); + const size_t memoryOffset = ((m_byteSelectedPosY * m_numColumns) + m_byteSelectedPosX); + if (m_editingHex) + { + // Convert ascii to actual value + if (byteToWrite >= 'A') + byteToWrite -= 'A' - 10; + else if (byteToWrite >= '0') + byteToWrite -= '0'; + + const char selectedMemoryValue = *(m_updatedRawMemoryData + memoryOffset); + if (m_carretBetweenHex) + byteToWrite = selectedMemoryValue & 0xF0 | byteToWrite; + else + byteToWrite = selectedMemoryValue & 0x0F | (byteToWrite << 4); + } + + u32 offsetToWrite = Common::dolphinAddrToOffset(m_currentFirstAddress + (u32)memoryOffset); return DolphinComm::DolphinAccessor::writeToRAM(offsetToWrite, &byteToWrite, 1, false); } void MemViewer::keyPressEvent(QKeyEvent* event) { - if (m_validMemory) + if (!m_validMemory) { - if (!m_hexKeyList.contains(event->key())) - { - if (!handleNaviguationKey(event->key())) - event->ignore(); - } - else + event->ignore(); + return; + } + + QString text = event->text(); + + if (text.isEmpty()) + { + if (!handleNaviguationKey(event->key())) + event->ignore(); + return; + } + + bool success = false; + if (m_editingHex) + { + // Beep when entering a non-valid value + const std::string hexChar = event->text().toUpper().toStdString(); + const char value = hexChar[0]; + if (!(value >= '0' && value <= '9') && !(value >= 'A' && value <= 'F')) { - if (!writeHexCharacterToSelectedMemory(event->text().toUpper().toStdString())) - { - m_validMemory = false; - viewport()->update(); - emit memErrorOccured(); - } - else - { - if (!m_carretBetweenHex) - { - m_carretBetweenHex = true; - } - else - { - m_carretBetweenHex = false; - if (m_byteSelectedPosX == 15) - { - if (m_byteSelectedPosY != 15) - { - m_byteSelectedPosX = 0; - m_byteSelectedPosY++; - } - } - else - { - m_byteSelectedPosX++; - } - } - updateMemoryData(); - viewport()->update(); - } + QApplication::beep(); + return; } + + success = writeCharacterToSelectedMemory(value); + m_carretBetweenHex = !m_carretBetweenHex; } else { - event->ignore(); + std::string str = text.toStdString(); + success = writeCharacterToSelectedMemory(str[0]); } + + if (!success) + { + m_validMemory = false; + viewport()->update(); + emit memErrorOccured(); + return; + } + + if (!m_carretBetweenHex || !m_editingHex) + handleNaviguationKey(Qt::Key::Key_Right); + + updateMemoryData(); + viewport()->update(); } void MemViewer::scrollContentsBy(int dx, int dy) { if (!m_disableScrollContentEvent && m_validMemory) { - u32 newAddress = m_currentFirstAddress + 16 * (-dy); + u32 newAddress = m_currentFirstAddress + m_numColumns * (-dy); + + // Move selection + m_byteSelectedPosY += dy; + if (newAddress < m_memViewStart) newAddress = m_memViewStart; - else if (newAddress > m_memViewEnd - 16 * 16) - newAddress = m_memViewEnd - 16 * 16; + else if (newAddress > m_memViewEnd - m_numCells) + newAddress = m_memViewEnd - m_numCells; if (newAddress != m_currentFirstAddress) { @@ -333,23 +400,15 @@ void MemViewer::renderColumnsHeaderText(QPainter& painter) { painter.drawText(m_charWidthEm / 2, m_charHeight, " Address"); int posXHeaderText = m_rowHeaderWidth; - int i = m_currentFirstAddress & 0xF; - do + for (int i = 0; i < m_numColumns; i++) { - if (i >= 16) - { - i = 0; - } - else - { - std::stringstream ss; - ss << std::hex << std::uppercase << i; - std::string headerText = "." + ss.str(); - painter.drawText(posXHeaderText, m_charHeight, QString::fromStdString(headerText)); - posXHeaderText += m_charWidthEm * 2 + m_charWidthEm / 2; - i++; - } - } while (i != (m_currentFirstAddress & 0xF)); + std::stringstream ss; + int byte = (m_currentFirstAddress + i) & 0xF; + ss << std::hex << std::uppercase << byte; + std::string headerText = "." + ss.str(); + painter.drawText(posXHeaderText, m_charHeight, QString::fromStdString(headerText)); + posXHeaderText += m_charWidthEm * 2 + m_charWidthEm / 2; + } painter.drawText(m_hexAsciiSeparatorPosX + m_charWidthEm / 2, m_charHeight, " Text (ASCII) "); } @@ -358,9 +417,10 @@ void MemViewer::renderRowHeaderText(QPainter& painter, const int rowIndex) { std::stringstream ss; ss << std::setfill('0') << std::setw(sizeof(u32) * 2) << std::hex << std::uppercase - << m_currentFirstAddress + 16 * rowIndex; - painter.drawText(m_charWidthEm / 2, (rowIndex + 1) * m_charHeight + m_columnHeaderHeight, - QString::fromStdString(ss.str())); + << m_currentFirstAddress + m_numColumns * rowIndex; + int x = m_charWidthEm / 2; + int y = (rowIndex + 1) * m_charHeight + m_columnHeaderHeight; + painter.drawText(x, y, QString::fromStdString(ss.str())); } void MemViewer::renderCarret(QPainter& painter, const int rowIndex, const int columnIndex) @@ -374,7 +434,7 @@ void MemViewer::renderCarret(QPainter& painter, const int rowIndex, const int co m_columnHeaderHeight, carretPosX, rowIndex * m_charHeight + (m_charHeight - fontMetrics().overlinePos()) + - m_columnHeaderHeight + m_charHeight); + m_columnHeaderHeight + m_charHeight - 1); painter.setPen(oldPenColor); } @@ -389,21 +449,23 @@ void MemViewer::determineMemoryTextRenderProperties(const int rowIndex, const in drawCarret = true; } // If the byte changed since the last data update - else if (m_lastRawMemoryData[rowIndex * 16 + columnIndex] != - m_updatedRawMemoryData[rowIndex * 16 + columnIndex]) + else if (m_lastRawMemoryData[rowIndex * m_numColumns + columnIndex] != + m_updatedRawMemoryData[rowIndex * m_numColumns + columnIndex]) { - m_memoryMsElapsedLastChange[rowIndex * 16 + columnIndex] = m_elapsedTimer.elapsed(); + m_memoryMsElapsedLastChange[rowIndex * m_numColumns + columnIndex] = m_elapsedTimer.elapsed(); bgColor = QColor(Qt::red); } // If the last changes is less than a second old - else if (m_memoryMsElapsedLastChange[rowIndex * 16 + columnIndex] != 0 && - m_elapsedTimer.elapsed() - m_memoryMsElapsedLastChange[rowIndex * 16 + columnIndex] < + else if (m_memoryMsElapsedLastChange[rowIndex * m_numColumns + columnIndex] != 0 && + m_elapsedTimer.elapsed() - + m_memoryMsElapsedLastChange[rowIndex * m_numColumns + columnIndex] < 1000) { QColor baseColor = QColor(Qt::red); - float alphaPercentage = (1000 - (m_elapsedTimer.elapsed() - - m_memoryMsElapsedLastChange[rowIndex * 16 + columnIndex])) / - (1000 / 100); + float alphaPercentage = + (1000 - (m_elapsedTimer.elapsed() - + m_memoryMsElapsedLastChange[rowIndex * m_numColumns + columnIndex])) / + (1000 / 100); int newAlpha = std::trunc(baseColor.alpha() * (alphaPercentage / 100)); bgColor = QColor(baseColor.red(), baseColor.green(), baseColor.blue(), newAlpha); } @@ -414,8 +476,8 @@ void MemViewer::renderHexByte(QPainter& painter, const int rowIndex, const int c { int posXHex = m_rowHeaderWidth + (m_charWidthEm * 2 + m_charWidthEm / 2) * columnIndex; std::string hexByte = Common::formatMemoryToString( - m_updatedRawMemoryData + ((rowIndex * 16) + columnIndex), Common::MemType::type_byteArray, 1, - Common::MemBase::base_none, true); + m_updatedRawMemoryData + ((rowIndex * m_numColumns) + columnIndex), + Common::MemType::type_byteArray, 1, Common::MemBase::base_none, true); QRect* currentByteRect = new QRect(posXHex, m_columnHeaderHeight + rowIndex * m_charHeight + (m_charHeight - fontMetrics().overlinePos()), @@ -435,8 +497,8 @@ void MemViewer::renderASCIIText(QPainter& painter, const int rowIndex, const int QColor& bgColor, QColor& fgColor) { std::string asciiStr = Common::formatMemoryToString( - m_updatedRawMemoryData + ((rowIndex * 16) + columnIndex), Common::MemType::type_string, 1, - Common::MemBase::base_none, true); + m_updatedRawMemoryData + ((rowIndex * m_numColumns) + columnIndex), + Common::MemType::type_string, 1, Common::MemBase::base_none, true); int asciiByte = (int)asciiStr[0]; if (asciiByte > 0x7E || asciiByte < 0x20) asciiStr = "."; @@ -455,10 +517,10 @@ void MemViewer::renderMemory(QPainter& painter, const int rowIndex, const int co { QColor oldPenColor = painter.pen().color(); int posXHex = m_rowHeaderWidth + (m_charWidthEm * 2 + m_charWidthEm / 2) * columnIndex; - if (!(m_currentFirstAddress + (16 * rowIndex + columnIndex) >= m_memViewStart && - m_currentFirstAddress + (16 * rowIndex + columnIndex) < m_memViewEnd) || - !DolphinComm::DolphinAccessor::isValidConsoleAddress(m_currentFirstAddress + - (16 * rowIndex + columnIndex)) || + if (!(m_currentFirstAddress + (m_numColumns * rowIndex + columnIndex) >= m_memViewStart && + m_currentFirstAddress + (m_numColumns * rowIndex + columnIndex) < m_memViewEnd) || + !DolphinComm::DolphinAccessor::isValidConsoleAddress( + m_currentFirstAddress + (m_numColumns * rowIndex + columnIndex)) || !m_validMemory) { painter.drawText(posXHex, (rowIndex + 1) * m_charHeight + m_columnHeaderHeight, "??"); @@ -487,10 +549,10 @@ void MemViewer::paintEvent(QPaintEvent* event) renderSeparatorLines(painter); renderColumnsHeaderText(painter); - for (int i = 0; i < 16; ++i) + for (int i = 0; i < m_numRows; ++i) { renderRowHeaderText(painter, i); - for (int j = 0; j < 16; ++j) + for (int j = 0; j < m_numColumns; ++j) { renderMemory(painter, i, j); } diff --git a/Source/GUI/MemViewer/MemViewer.h b/Source/GUI/MemViewer/MemViewer.h index 980a446b..1a369012 100644 --- a/Source/GUI/MemViewer/MemViewer.h +++ b/Source/GUI/MemViewer/MemViewer.h @@ -19,6 +19,7 @@ class MemViewer : public QAbstractScrollArea ~MemViewer(); QSize sizeHint() const override; void mousePressEvent(QMouseEvent* event) override; + void wheelEvent(QWheelEvent* event) override; void keyPressEvent(QKeyEvent* event) override; void paintEvent(QPaintEvent* event) override; void scrollContentsBy(int dx, int dy) override; @@ -33,8 +34,10 @@ class MemViewer : public QAbstractScrollArea private: void initialise(); + void updateFontSize(int newSize); + void scrollToSelection(); bool handleNaviguationKey(const int key); - bool writeHexCharacterToSelectedMemory(const std::string hexCharToWrite); + bool writeCharacterToSelectedMemory(char byteToWrite); void updateMemoryData(); void changeMemoryRegion(const bool isMEM2); void renderColumnsHeaderText(QPainter& painter); @@ -49,6 +52,10 @@ class MemViewer : public QAbstractScrollArea void determineMemoryTextRenderProperties(const int rowIndex, const int columnIndex, bool& drawCarret, QColor& bgColor, QColor& fgColor); + const int m_numRows = 16; + const int m_numColumns = 16; // Should be a multiple of 16, or the header doesn't make much sense + const int m_numCells = m_numRows * m_numColumns; + int m_memoryFontSize = 15; int m_byteSelectedPosX = -1; int m_byteSelectedPosY = -1; int m_charWidthEm = 0; @@ -61,6 +68,7 @@ class MemViewer : public QAbstractScrollArea char* m_updatedRawMemoryData = nullptr; char* m_lastRawMemoryData = nullptr; int* m_memoryMsElapsedLastChange = nullptr; + bool m_editingHex = false; bool m_carretBetweenHex = false; bool m_disableScrollContentEvent = false; bool m_validMemory = false; @@ -68,6 +76,5 @@ class MemViewer : public QAbstractScrollArea u32 m_memViewStart = 0; u32 m_memViewEnd = 0; QRect* m_curosrRect; - QList m_hexKeyList; QElapsedTimer m_elapsedTimer; };