|  |  | @ -277,8 +277,12 @@ void BinaryViewModel::refresh() { | 
			
		
	
		
		
			
				
					
					|  |  |  |         } |  |  |  |         } | 
			
		
	
		
		
			
				
					
					|  |  |  |         if (j == start) sig->is_little_endian ? items[idx].is_lsb = true : items[idx].is_msb = true; |  |  |  |         if (j == start) sig->is_little_endian ? items[idx].is_lsb = true : items[idx].is_msb = true; | 
			
		
	
		
		
			
				
					
					|  |  |  |         if (j == end) sig->is_little_endian ? items[idx].is_msb = true : items[idx].is_lsb = true; |  |  |  |         if (j == end) sig->is_little_endian ? items[idx].is_msb = true : items[idx].is_lsb = true; | 
			
		
	
		
		
			
				
					
					|  |  |  |         items[idx].bg_color = getColor(sig); |  |  |  | 
 | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |         items[idx].sigs.push_back(sig); |  |  |  |         auto &sigs = items[idx].sigs; | 
			
				
				
			
		
	
		
		
	
		
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |         sigs.push_back(sig); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |         if (sigs.size() > 1) { | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |           std::sort(sigs.begin(), sigs.end(), [](auto l, auto r) { return l->size > r->size; }); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |         } | 
			
		
	
		
		
			
				
					
					|  |  |  |       } |  |  |  |       } | 
			
		
	
		
		
			
				
					
					|  |  |  |     } |  |  |  |     } | 
			
		
	
		
		
			
				
					
					|  |  |  |   } else { |  |  |  |   } else { | 
			
		
	
	
		
		
			
				
					|  |  | @ -353,15 +357,11 @@ BinaryItemDelegate::BinaryItemDelegate(QObject *parent) : QStyledItemDelegate(pa | 
			
		
	
		
		
			
				
					
					|  |  |  |   hex_font.setBold(true); |  |  |  |   hex_font.setBold(true); | 
			
		
	
		
		
			
				
					
					|  |  |  | } |  |  |  | } | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  | bool BinaryItemDelegate::isSameColor(const QModelIndex &index, int dx, int dy) const { |  |  |  | bool BinaryItemDelegate::hasSignal(const QModelIndex &index, int dx, int dy, const cabana::Signal *sig) const { | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |   QModelIndex index2 = index.sibling(index.row() + dy, index.column() + dx); |  |  |  |   if (!index.isValid()) return false; | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |   if (!index2.isValid()) { |  |  |  |   auto model = (const BinaryViewModel*)(index.model()); | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |     return false; |  |  |  |   int idx = (index.row() + dy) * model->columnCount() + index.column() + dx; | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |   } |  |  |  |   return (idx >=0 && idx < model->items.size()) ? model->items[idx].sigs.contains(sig) : false; | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |   auto color1 = ((const BinaryViewModel::Item *)index.internalPointer())->bg_color; |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |   auto color2 = ((const BinaryViewModel::Item *)index2.internalPointer())->bg_color; |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |   // Ignore alpha
 |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |   return (color1.red() == color2.red()) && (color2.green() == color2.green()) && (color1.blue() == color2.blue()); |  |  |  |  | 
			
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
			
				
					
					|  |  |  | } |  |  |  | } | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  | void BinaryItemDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const { |  |  |  | void BinaryItemDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const { | 
			
		
	
	
		
		
			
				
					|  |  | @ -370,28 +370,32 @@ void BinaryItemDelegate::paint(QPainter *painter, const QStyleOptionViewItem &op | 
			
		
	
		
		
			
				
					
					|  |  |  |   painter->save(); |  |  |  |   painter->save(); | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |   if (index.column() == 8) { |  |  |  |   if (index.column() == 8) { | 
			
		
	
		
		
			
				
					
					|  |  |  |     painter->setFont(hex_font); |  |  |  |     if (item->valid) { | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |     painter->fillRect(option.rect, item->bg_color); |  |  |  |       painter->setFont(hex_font); | 
			
				
				
			
		
	
		
		
	
		
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |       painter->fillRect(option.rect, item->bg_color); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     } | 
			
		
	
		
		
			
				
					
					|  |  |  |   } else if (option.state & QStyle::State_Selected) { |  |  |  |   } else if (option.state & QStyle::State_Selected) { | 
			
		
	
		
		
			
				
					
					|  |  |  |     painter->fillRect(option.rect, selection_color); |  |  |  |     painter->fillRect(option.rect, selection_color); | 
			
		
	
		
		
			
				
					
					|  |  |  |     painter->setPen(option.palette.color(QPalette::BrightText)); |  |  |  |     painter->setPen(option.palette.color(QPalette::BrightText)); | 
			
		
	
		
		
			
				
					
					|  |  |  |   } else if (!bin_view->selectionModel()->hasSelection() || !item->sigs.contains(bin_view->resize_sig)) { // not resizing
 |  |  |  |   } else if (!bin_view->selectionModel()->hasSelection() || !item->sigs.contains(bin_view->resize_sig)) {  // not resizing
 | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |     QColor bg = item->bg_color; |  |  |  |     if (item->sigs.size() > 0) { | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |     if (bin_view->hovered_sig && item->sigs.contains(bin_view->hovered_sig)) { |  |  |  |       for (auto &s : item->sigs) { | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |       bg.setAlpha(255); |  |  |  |         if (s == bin_view->hovered_sig) { | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |       painter->fillRect(option.rect, bg.darker(125));  // 4/5x brightness
 |  |  |  |           painter->fillRect(option.rect, getColor(bin_view->hovered_sig).darker(125));  // 4/5x brightness
 | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |       painter->setPen(option.palette.color(QPalette::BrightText)); |  |  |  |         } else { | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |     } else { |  |  |  |           drawSignalCell(painter, option, index, s); | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |       if (item->sigs.size() > 0) { |  |  |  |         } | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |         drawBorder(painter, option, index); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |         bg.setAlpha(std::max(50, bg.alpha())); |  |  |  |  | 
			
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
			
				
					
					|  |  |  |       } |  |  |  |       } | 
			
		
	
		
		
			
				
					
					|  |  |  |       painter->fillRect(option.rect, bg); |  |  |  |     } else if (item->valid) { | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |       painter->setPen(option.palette.color(QPalette::Text)); |  |  |  |       painter->fillRect(option.rect, item->bg_color); | 
			
				
				
			
		
	
		
		
	
		
		
	
		
		
			
				
					
					|  |  |  |     } |  |  |  |     } | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     auto color_role = item->sigs.contains(bin_view->hovered_sig) ? QPalette::BrightText : QPalette::Text; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     painter->setPen(option.palette.color(color_role)); | 
			
		
	
		
		
			
				
					
					|  |  |  |   } |  |  |  |   } | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |   if (!item->valid) { |  |  |  |   if (item->sigs.size() > 1) { | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     painter->fillRect(option.rect, QBrush(Qt::darkGray, Qt::Dense7Pattern)); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |   } else if (!item->valid) { | 
			
		
	
		
		
			
				
					
					|  |  |  |     painter->fillRect(option.rect, QBrush(Qt::darkGray, Qt::BDiagPattern)); |  |  |  |     painter->fillRect(option.rect, QBrush(Qt::darkGray, Qt::BDiagPattern)); | 
			
		
	
		
		
			
				
					
					|  |  |  |   } |  |  |  |   } | 
			
		
	
		
		
			
				
					
					|  |  |  |   painter->drawText(option.rect, Qt::AlignCenter, item->val); |  |  |  |   painter->drawText(option.rect, Qt::AlignCenter, item->val); | 
			
		
	
	
		
		
			
				
					|  |  | @ -403,44 +407,49 @@ void BinaryItemDelegate::paint(QPainter *painter, const QStyleOptionViewItem &op | 
			
		
	
		
		
			
				
					
					|  |  |  | } |  |  |  | } | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  | // Draw border on edge of signal
 |  |  |  | // Draw border on edge of signal
 | 
			
		
	
		
		
			
				
					
					|  |  |  | void BinaryItemDelegate::drawBorder(QPainter* painter, const QStyleOptionViewItem &option, const QModelIndex &index) const { |  |  |  | void BinaryItemDelegate::drawSignalCell(QPainter *painter, const QStyleOptionViewItem &option, | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |   auto item = (const BinaryViewModel::Item *)index.internalPointer(); |  |  |  |                                         const QModelIndex &index, const cabana::Signal *sig) const { | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |   QColor border_color = item->bg_color; |  |  |  |   bool draw_left = !hasSignal(index, -1, 0, sig); | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |   border_color.setAlphaF(1.0); |  |  |  |   bool draw_top = !hasSignal(index, 0, -1, sig); | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  |   bool draw_right = !hasSignal(index, 1, 0, sig); | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |   bool draw_left = !isSameColor(index, -1, 0); |  |  |  |   bool draw_bottom = !hasSignal(index, 0, 1, sig); | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |   bool draw_top = !isSameColor(index, 0, -1); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |   bool draw_right = !isSameColor(index, 1, 0); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |   bool draw_bottom = !isSameColor(index, 0, 1); |  |  |  |  | 
			
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |   const int spacing = 2; |  |  |  |   const int spacing = 2; | 
			
		
	
		
		
			
				
					
					|  |  |  |   QRect rc = option.rect.adjusted(draw_left * 3, draw_top * spacing, draw_right * -3, draw_bottom * -spacing); |  |  |  |   QRect rc = option.rect.adjusted(draw_left * 3, draw_top * spacing, draw_right * -3, draw_bottom * -spacing); | 
			
		
	
		
		
			
				
					
					|  |  |  |   QRegion subtract; |  |  |  |   QRegion subtract; | 
			
		
	
		
		
			
				
					
					|  |  |  |   if (!draw_top) { |  |  |  |   if (!draw_top) { | 
			
		
	
		
		
			
				
					
					|  |  |  |     if (!draw_left && !isSameColor(index, -1, -1)) { |  |  |  |     if (!draw_left && !hasSignal(index, -1, -1, sig)) { | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |       subtract += QRect{rc.left(), rc.top(), 3, spacing}; |  |  |  |       subtract += QRect{rc.left(), rc.top(), 3, spacing}; | 
			
		
	
		
		
			
				
					
					|  |  |  |     } else if (!draw_right && !isSameColor(index, 1, -1)) { |  |  |  |     } else if (!draw_right && !hasSignal(index, 1, -1, sig)) { | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |       subtract += QRect{rc.right() - 2, rc.top(), 3, spacing}; |  |  |  |       subtract += QRect{rc.right() - 2, rc.top(), 3, spacing}; | 
			
		
	
		
		
			
				
					
					|  |  |  |     } |  |  |  |     } | 
			
		
	
		
		
			
				
					
					|  |  |  |   } |  |  |  |   } | 
			
		
	
		
		
			
				
					
					|  |  |  |   if (!draw_bottom) { |  |  |  |   if (!draw_bottom) { | 
			
		
	
		
		
			
				
					
					|  |  |  |     if (!draw_left && !isSameColor(index, -1, 1)) { |  |  |  |     if (!draw_left && !hasSignal(index, -1, 1, sig)) { | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |       subtract += QRect{rc.left(), rc.bottom() - (spacing - 1), 3, spacing}; |  |  |  |       subtract += QRect{rc.left(), rc.bottom() - (spacing - 1), 3, spacing}; | 
			
		
	
		
		
			
				
					
					|  |  |  |     } else if (!draw_right && !isSameColor(index, 1, 1)) { |  |  |  |     } else if (!draw_right && !hasSignal(index, 1, 1, sig)) { | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |       subtract += QRect{rc.right() - 2, rc.bottom() - (spacing - 1), 3, spacing}; |  |  |  |       subtract += QRect{rc.right() - 2, rc.bottom() - (spacing - 1), 3, spacing}; | 
			
		
	
		
		
			
				
					
					|  |  |  |     } |  |  |  |     } | 
			
		
	
		
		
			
				
					
					|  |  |  |   } |  |  |  |   } | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |   painter->setClipRegion(QRegion(rc).subtracted(subtract)); | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |   painter->setPen(QPen(border_color, 1)); |  |  |  |   auto item = (const BinaryViewModel::Item *)index.internalPointer(); | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |   auto sig_color = getColor(sig); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |   QColor color = sig_color; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |   color.setAlpha(item->bg_color.alpha()); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |   painter->fillRect(rc, Qt::white); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |   painter->fillRect(rc, color); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |   color = sig_color.darker(125); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |   painter->setPen(QPen(color, 1)); | 
			
		
	
		
		
			
				
					
					|  |  |  |   if (draw_left) painter->drawLine(rc.topLeft(), rc.bottomLeft()); |  |  |  |   if (draw_left) painter->drawLine(rc.topLeft(), rc.bottomLeft()); | 
			
		
	
		
		
			
				
					
					|  |  |  |   if (draw_right) painter->drawLine(rc.topRight(), rc.bottomRight()); |  |  |  |   if (draw_right) painter->drawLine(rc.topRight(), rc.bottomRight()); | 
			
		
	
		
		
			
				
					
					|  |  |  |   if (draw_bottom) painter->drawLine(rc.bottomLeft(), rc.bottomRight()); |  |  |  |   if (draw_bottom) painter->drawLine(rc.bottomLeft(), rc.bottomRight()); | 
			
		
	
		
		
			
				
					
					|  |  |  |   if (draw_top) painter->drawLine(rc.topLeft(), rc.topRight()); |  |  |  |   if (draw_top) painter->drawLine(rc.topLeft(), rc.topRight()); | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |   painter->setClipRegion(QRegion(rc).subtracted(subtract)); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |   if (!subtract.isEmpty()) { |  |  |  |   if (!subtract.isEmpty()) { | 
			
		
	
		
		
			
				
					
					|  |  |  |     // fill gaps inside corners.
 |  |  |  |     // fill gaps inside corners.
 | 
			
		
	
		
		
			
				
					
					|  |  |  |     painter->setPen(QPen(border_color, 2, Qt::SolidLine, Qt::SquareCap, Qt::MiterJoin)); |  |  |  |     painter->setPen(QPen(color, 2, Qt::SolidLine, Qt::SquareCap, Qt::MiterJoin)); | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |     for (auto &r : subtract) { |  |  |  |     for (auto &r : subtract) { | 
			
		
	
		
		
			
				
					
					|  |  |  |       painter->drawRect(r); |  |  |  |       painter->drawRect(r); | 
			
		
	
		
		
			
				
					
					|  |  |  |     } |  |  |  |     } | 
			
		
	
	
		
		
			
				
					|  |  | 
 |