1717
1818static constexpr char hexChars[] = " 0123456789ABCDEF" ;
1919
20+ namespace Layout {
21+ // Layout constants
22+ static constexpr int MIN_OFFSET_DIGITS = 4 ;
23+ static constexpr int OFFSET_SUFFIX_CHARS = 2 ; // ": "
24+ static constexpr int HEX_CHARS_PER_BYTE = 3 ; // "XX "
25+ static constexpr int HEX_MIDDLE_EXTRA_SPACE = 1 ; // Extra space after byte 7
26+ static constexpr int HEX_ASCII_SEPARATOR_CHARS = 2 ; // The separator is technically " | ",
27+ // but we get the space on the left by default due to it being included with every byte via HEX_CHARS_PER_BYTE
28+ static constexpr int LEFT_MARGIN_PIXELS = 2 ;
29+ static constexpr int TEXT_HORIZONTAL_MARGIN_CHARS = 2 ;
30+ }
31+
2032CLightningFastViewerWidget::CLightningFastViewerWidget (QWidget* parent)
2133 : QAbstractScrollArea(parent)
2234{
@@ -383,15 +395,15 @@ void CLightningFastViewerWidget::calculateHexLayout()
383395{
384396 // Calculate nDigits once and cache it
385397 _nDigits = static_cast <int >(qCeil (::log10 (static_cast <double >(_data.size () + 1 ))));
386- _nDigits = qMax (4 , _nDigits); // Minimum 4 digits
387- const int offsetWidth = _charWidth /* left margin */ + _nDigits + 2 /* colon + space */ ;
398+ _nDigits = qMax (Layout::MIN_OFFSET_DIGITS , _nDigits);
399+ const int offsetWidth = _charWidth * ( _nDigits + Layout::OFFSET_SUFFIX_CHARS) + Layout::LEFT_MARGIN_PIXELS ;
388400
389401 // Hex area starts after offset
390402 _hexStart = offsetWidth;
391403
392404 // ASCII area starts after hex (16 bytes * 3 chars + extra space at middle)
393- const int hexWidth = _charWidth * (_bytesPerLine * 3 + 1 );
394- _asciiStart = _hexStart + hexWidth + _charWidth * 3 ; // " | "
405+ const int hexWidth = _charWidth * (_bytesPerLine * Layout::HEX_CHARS_PER_BYTE + Layout::HEX_MIDDLE_EXTRA_SPACE );
406+ _asciiStart = _hexStart + hexWidth + _charWidth * Layout::HEX_ASCII_SEPARATOR_CHARS;
395407}
396408
397409void CLightningFastViewerWidget::calculateTextLayout ()
@@ -411,7 +423,7 @@ void CLightningFastViewerWidget::drawHexLine(QPainter& painter, qsizetype offset
411423 const QString offsetStr = QStringLiteral (" %1:" ).arg (offset, _nDigits, 10 , QChar (' 0' ));
412424
413425 painter.setPen (palette ().color (QPalette::Disabled, QPalette::Text));
414- painter.drawText (_charWidth - hScroll, y + fm.ascent (), offsetStr);
426+ painter.drawText (Layout::LEFT_MARGIN_PIXELS - hScroll, y + fm.ascent (), offsetStr);
415427
416428 painter.setPen (palette ().color (QPalette::Text));
417429
@@ -442,18 +454,18 @@ void CLightningFastViewerWidget::drawHexLine(QPainter& painter, qsizetype offset
442454 hexByte += QChar (hexChars[byte & 0x0F ]);
443455
444456 painter.drawText (x - hScroll, y + fm.ascent (), hexByte);
445- x += _charWidth * 3 ; // 2 chars + space
457+ x += _charWidth * Layout::HEX_CHARS_PER_BYTE;
446458
447459 if (i == 7 )
448460 {
449- x += _charWidth; // Extra space in middle
461+ x += _charWidth * Layout::HEX_MIDDLE_EXTRA_SPACE;
450462 }
451463 }
452464 }
453465
454466 // Draw separator
455467 painter.setPen (palette ().color (QPalette::Disabled, QPalette::Text));
456- painter.drawText (_asciiStart - _charWidth * 2 - hScroll, y + fm.ascent (), QChar (' |' ));
468+ painter.drawText (_asciiStart - _charWidth * Layout::HEX_ASCII_SEPARATOR_CHARS - hScroll, y + fm.ascent (), QChar (' |' ));
457469
458470 // Draw ASCII
459471 x = _asciiStart;
@@ -491,7 +503,7 @@ void CLightningFastViewerWidget::drawTextLine(QPainter& painter, int lineIndex,
491503 QString lineText = _text.mid (lineStart, lineLen);
492504
493505 // Draw the line character by character to handle selection
494- int x = _charWidth - hScroll;
506+ int x = Layout::LEFT_MARGIN_PIXELS - hScroll;
495507 for (int i = 0 ; i < lineText.length (); ++i)
496508 {
497509 qsizetype charOffset = lineStart + i;
@@ -528,7 +540,7 @@ void CLightningFastViewerWidget::updateScrollBars()
528540 // Horizontal scrollbar
529541 if (_mode == HEX)
530542 {
531- const int totalWidth = _asciiStart + _charWidth * _bytesPerLine + _charWidth * 2 ;
543+ const int totalWidth = _asciiStart + _charWidth * _bytesPerLine + _charWidth * Layout::TEXT_HORIZONTAL_MARGIN_CHARS ;
532544 horizontalScrollBar ()->setRange (0 , qMax (0 , totalWidth - viewport ()->width ()));
533545 }
534546 else
@@ -542,7 +554,7 @@ void CLightningFastViewerWidget::updateScrollBars()
542554 int width = fm.horizontalAdvance (lineText);
543555 maxWidth = qMax (maxWidth, width);
544556 }
545- horizontalScrollBar ()->setRange (0 , qMax (0 , maxWidth - viewport ()->width () + _charWidth * 2 ));
557+ horizontalScrollBar ()->setRange (0 , qMax (0 , maxWidth - viewport ()->width () + _charWidth * Layout::TEXT_HORIZONTAL_MARGIN_CHARS ));
546558 }
547559 horizontalScrollBar ()->setPageStep (viewport ()->width ());
548560}
@@ -552,7 +564,7 @@ CLightningFastViewerWidget::Region CLightningFastViewerWidget::regionAtPos(const
552564 int x = pos.x () + horizontalScrollBar ()->value ();
553565
554566 if (x < _hexStart) return REGION_OFFSET;
555- if (x < _asciiStart - _charWidth * 3 ) return REGION_HEX;
567+ if (x < _asciiStart - _charWidth * Layout::HEX_ASCII_SEPARATOR_CHARS ) return REGION_HEX;
556568 if (x >= _asciiStart) return REGION_ASCII;
557569 return REGION_NONE;
558570}
@@ -573,13 +585,13 @@ qsizetype CLightningFastViewerWidget::hexPosToOffset(const QPoint& pos) const
573585 if (region == REGION_HEX)
574586 {
575587 int relX = x - _hexStart;
576- byteInLine = relX / (_charWidth * 3 );
588+ byteInLine = relX / (_charWidth * Layout::HEX_CHARS_PER_BYTE );
577589
578590 // Account for extra space at position 8
579591 if (byteInLine >= 8 )
580592 {
581- relX -= _charWidth;
582- byteInLine = relX / (_charWidth * 3 );
593+ relX -= _charWidth * Layout::HEX_MIDDLE_EXTRA_SPACE ;
594+ byteInLine = relX / (_charWidth * Layout::HEX_CHARS_PER_BYTE );
583595 }
584596
585597 byteInLine = qBound (0 , byteInLine, _bytesPerLine - 1 );
@@ -615,7 +627,7 @@ qsizetype CLightningFastViewerWidget::textPosToOffset(const QPoint& pos) const
615627
616628 // Find character at position
617629 QFontMetrics fm (font ());
618- int currentX = _charWidth ;
630+ int currentX = Layout::LEFT_MARGIN_PIXELS ;
619631
620632 for (int i = 0 ; i < lineText.length (); ++i)
621633 {
@@ -748,7 +760,7 @@ void CLightningFastViewerWidget::wrapTextIfNeeded()
748760 const auto elapsed = timer.elapsed ();
749761 if (elapsed > 2 )
750762 qInfo () << " wrap text:" << timer.elapsed ();
751- });
763+ });
752764
753765 if (!_wordWrap && _lineOffsets.empty ())
754766 {
@@ -782,7 +794,7 @@ void CLightningFastViewerWidget::wrapTextIfNeeded()
782794 clearWrappingData ();
783795 _wordWrapParamsHash = hashKey;
784796
785- const int viewportWidth = viewport ()->width () - _charWidth * 2 ; // Margins
797+ const int viewportWidth = viewport ()->width () - _charWidth * Layout::TEXT_HORIZONTAL_MARGIN_CHARS;
786798 QFontMetrics fm (font ());
787799 int currentLineStart = 0 ;
788800 int currentWidth = 0 ;
@@ -871,4 +883,4 @@ void CLightningFastViewerWidget::updateFontMetrics()
871883 QFontMetrics fm (font ());
872884 _lineHeight = fm.height ();
873885 _charWidth = fm.horizontalAdvance (' 0' );
874- }
886+ }
0 commit comments