wiRedPanda
Logic Circuit Simulator
Loading...
Searching...
No Matches
SignalDelegate.cpp
Go to the documentation of this file.
1// Copyright 2015 - 2026, GIBIS-UNIFESP and the wiRedPanda contributors
2// SPDX-License-Identifier: GPL-3.0-or-later
3
5
6#include <QPainter>
7#include <QStyleOptionViewItem>
8
10
11namespace
12{
13// Waveform colors: green for output rows, blue for input rows.
14const QColor kOutputColor(0, 128, 0);
15const QColor kInputColor(0x75, 0x8e, 0xff);
16
17// Geometry, as fractions of the cell, decoded from the original 100x30 SVGs.
18constexpr double kLineThickness = 4.0 / 30.0;
19constexpr double kBarWidth = 4.0 / 100.0;
20constexpr double kHighTop = 8.0 / 30.0;
21constexpr double kLowTop = 20.0 / 30.0;
22constexpr double kHighBottom = 12.0 / 30.0;
23constexpr double kLowBottom = 24.0 / 30.0;
24} // namespace
25
27 : QItemDelegate(parent)
28{
29}
30
32{
33 m_plotType = plotType;
34}
35
36WaveSegment SignalDelegate::segmentFor(const int value, const bool hasPrev, const int prevValue)
37{
38 if (value == 0) {
39 return (hasPrev && (prevValue == 1)) ? WaveSegment::Falling : WaveSegment::Low;
40 }
41
42 return (hasPrev && (prevValue == 0)) ? WaveSegment::Rising : WaveSegment::High;
43}
44
45void SignalDelegate::drawWaveform(QPainter *painter, const QRectF &cell, const WaveSegment seg, const bool isInput) const
46{
47 const QColor color = isInput ? kInputColor : kOutputColor;
48 QColor bandColor = color;
49 bandColor.setAlpha(128); // 50% opacity translucent fill
50
51 const double x = cell.x();
52 const double y = cell.y();
53 const double w = cell.width();
54 const double h = cell.height();
55
56 // High plateau for High/Rising, low plateau for Low/Falling.
57 const bool high = (seg == WaveSegment::High) || (seg == WaveSegment::Rising);
58 const double lineTop = (high ? kHighTop : kLowTop) * h;
59 const double lineBottom = (high ? kHighBottom : kLowBottom) * h;
60 const double thickness = kLineThickness * h;
61
62 // Draw order matches the original SVGs: band, then plateau line, then edge bar.
63 painter->fillRect(QRectF(x, y + lineBottom, w, h - lineBottom), bandColor);
64 painter->fillRect(QRectF(x, y + lineTop, w, thickness), color);
65
66 if ((seg == WaveSegment::Rising) || (seg == WaveSegment::Falling)) {
67 // Vertical connector joining the high and low plateau levels at the cell's left edge.
68 const double barTop = kHighTop * h;
69 const double barBottom = kLowBottom * h;
70 painter->fillRect(QRectF(x, y + barTop, kBarWidth * w, barBottom - barTop), color);
71 }
72}
73
74void SignalDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
75{
76 // Number mode: render the "0"/"1" centered (no per-cell alignment role needed).
77 if (m_plotType == PlotType::Number) {
78 QStyleOptionViewItem opt(option);
79 opt.displayAlignment = Qt::AlignCenter;
80 QItemDelegate::paint(painter, opt, index);
81 return;
82 }
83
84 // Waveform mode: derive the segment from this cell's value and its left neighbour,
85 // and the input/output colour from the model's row partition — nothing is stored.
86 const int value = index.data().toInt();
87 const QModelIndex prev = index.siblingAtColumn(index.column() - 1);
88 const bool hasPrev = prev.isValid();
89 const WaveSegment seg = segmentFor(value, hasPrev, hasPrev ? prev.data().toInt() : 0);
90
91 bool isInput = true;
92 if (const auto *model = qobject_cast<const SignalModel *>(index.model())) {
93 isInput = model->isInputRow(index.row());
94 }
95
96 // Draw the selection highlight behind the waveform rather than over it
97 if (option.state & QStyle::State_Selected) {
98 painter->fillRect(option.rect, option.palette.highlight());
99 }
100
101 drawWaveform(painter, option.rect, seg, isInput);
102}
SignalDelegate: paints digital waveform graphics into table cells.
WaveSegment
Identifies which waveform segment a Line-mode cell draws.
@ Falling
High → low transition (low plateau + leading edge).
@ Low
Logic-low plateau (signal stays at 0).
@ Rising
Low → high transition (high plateau + leading edge).
@ High
Logic-high plateau (signal stays at 1).
PlotType
Controls how signal cells are rendered in the waveform table.
@ Number
Cells display the numeric value (0/1).
SignalModel for the beWavedDolphin waveform table.
void setPlotType(PlotType plotType)
Selects the cell rendering mode (waveform graphics vs. numeric text).
void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const override
PlotType plotType() const
Returns the current cell rendering mode.
static WaveSegment segmentFor(int value, bool hasPrev, int prevValue)
Returns the waveform segment a cell should draw.
SignalDelegate(QObject *parent=nullptr)
Constructs the delegate.