| 657 | } |
| 658 | |
| 659 | void RcxEditor::applyHoverHighlight() { |
| 660 | m_sci->markerDeleteAll(M_HOVER); |
| 661 | if (m_editState.active) return; |
| 662 | if (!m_hoverInside) return; |
| 663 | if (m_hoveredNodeId == 0) return; |
| 664 | |
| 665 | // Check if hovered line is a footer - footers highlight independently |
| 666 | bool hoveringFooter = (m_hoveredLine >= 0 && m_hoveredLine < m_meta.size() && |
| 667 | m_meta[m_hoveredLine].lineKind == LineKind::Footer); |
| 668 | |
| 669 | // Check if the hovered item is already selected (using appropriate ID) |
| 670 | uint64_t checkId = hoveringFooter ? (m_hoveredNodeId | kFooterIdBit) : m_hoveredNodeId; |
| 671 | if (m_currentSelIds.contains(checkId)) return; |
| 672 | |
| 673 | if (hoveringFooter) { |
| 674 | // Footer: only highlight this specific line |
| 675 | m_sci->markerAdd(m_hoveredLine, M_HOVER); |
| 676 | } else { |
| 677 | // Non-footer: highlight all matching lines except footers |
| 678 | for (int i = 0; i < m_meta.size(); i++) { |
| 679 | if (m_meta[i].nodeId == m_hoveredNodeId && |
| 680 | m_meta[i].lineKind != LineKind::Footer) |
| 681 | m_sci->markerAdd(i, M_HOVER); |
| 682 | } |
| 683 | } |
| 684 | } |
| 685 | |
| 686 | ViewState RcxEditor::saveViewState() const { |
| 687 | ViewState vs; |