wiRedPanda
Logic Circuit Simulator
Loading...
Searching...
No Matches
Display14.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 <QSvgRenderer>
8
14#include "App/IO/VersionInfo.h"
15#include "App/Wiring/Port.h"
16
17template<>
20 .type = ElementType::Display14,
21 .group = ElementGroup::Output,
22 .minInputSize = 15,
23 .maxInputSize = 15,
24 .canChangeAppearance = true,
25 .hasColors = true,
26 .hasLabel = true,
27 .rotatesGraphic = false,
28 };
29 static_assert(validate(constraints));
30
32 {
34 meta.pixmapPath = []{ return QStringLiteral(":/Components/Output/Counter/counter_14_on.svg"); };
35 meta.titleText = QT_TRANSLATE_NOOP("Display14", "14-SEGMENT DISPLAY");
36 meta.translatedName = QT_TRANSLATE_NOOP("Display14", "14-Segment Display");
37 meta.trContext = "Display14";
38 meta.defaultAppearances = QStringList({
39 ":/Components/Output/Counter/counter_14_off.svg",
40 ":/Components/Output/Counter/counter_a.svg",
41 ":/Components/Output/Counter/counter_b.svg",
42 ":/Components/Output/Counter/counter_c.svg",
43 ":/Components/Output/Counter/counter_d.svg",
44 ":/Components/Output/Counter/counter_e.svg",
45 ":/Components/Output/Counter/counter_f.svg",
46 ":/Components/Output/Counter/counter_g1.svg",
47 ":/Components/Output/Counter/counter_g2.svg",
48 ":/Components/Output/Counter/counter_h.svg",
49 ":/Components/Output/Counter/counter_j.svg",
50 ":/Components/Output/Counter/counter_k.svg",
51 ":/Components/Output/Counter/counter_l.svg",
52 ":/Components/Output/Counter/counter_m.svg",
53 ":/Components/Output/Counter/counter_n.svg",
54 ":/Components/Output/Counter/counter_dp.svg",
55 });
56 return meta;
57 }
58
59 static inline const bool registered = []() {
61 ElementFactory::registerCreator(constraints.type, [] { return new Display14(); });
62 return true;
63 }();
64};
65
66Display14::Display14(QGraphicsItem *parent)
68{
69 a = Display7::cachedSegmentRenderers(m_appearance.defaultAppearances().at(1));
70 b = Display7::cachedSegmentRenderers(m_appearance.defaultAppearances().at(2));
71 c = Display7::cachedSegmentRenderers(m_appearance.defaultAppearances().at(3));
72 d = Display7::cachedSegmentRenderers(m_appearance.defaultAppearances().at(4));
73 e = Display7::cachedSegmentRenderers(m_appearance.defaultAppearances().at(5));
74 f = Display7::cachedSegmentRenderers(m_appearance.defaultAppearances().at(6));
75 g1 = Display7::cachedSegmentRenderers(m_appearance.defaultAppearances().at(7));
76 g2 = Display7::cachedSegmentRenderers(m_appearance.defaultAppearances().at(8));
77 h = Display7::cachedSegmentRenderers(m_appearance.defaultAppearances().at(9));
78 j = Display7::cachedSegmentRenderers(m_appearance.defaultAppearances().at(10));
79 k = Display7::cachedSegmentRenderers(m_appearance.defaultAppearances().at(11));
80 l = Display7::cachedSegmentRenderers(m_appearance.defaultAppearances().at(12));
81 m = Display7::cachedSegmentRenderers(m_appearance.defaultAppearances().at(13));
82 n = Display7::cachedSegmentRenderers(m_appearance.defaultAppearances().at(14));
83 dp = Display7::cachedSegmentRenderers(m_appearance.defaultAppearances().at(15));
84
86}
87
89{
90 update();
91}
92
94{
95 // Left-side ports (x=0): G1, F, E, D (outer horizontal/vertical) + G2, H, J (diagonals/center)
96 // Right-side ports (x=64): A, B, DP, C + K, L, M, N
97 // This two-column layout mirrors the physical dual-inline-package pin arrangement.
98 inputPort( 0)->setPos( 0, -8); inputPort(0)->setName("G1 (" + tr("middle left horizontal") + ")");
99 inputPort( 1)->setPos( 0, 8); inputPort(1)->setName("F (" + tr("upper left vertical") + ")");
100 inputPort( 2)->setPos( 0, 24); inputPort(2)->setName("E (" + tr("lower left vertical") + ")");
101 inputPort( 3)->setPos( 0, 40); inputPort(3)->setName("D (" + tr("bottom") + ")");
102 inputPort( 4)->setPos(64, -8); inputPort(4)->setName("A (" + tr("top") + ")");
103 inputPort( 5)->setPos(64, 8); inputPort(5)->setName("B (" + tr("upper right vertical") + ")");
104 inputPort( 6)->setPos(64, 24); inputPort(6)->setName("DP (" + tr("dot") + ")");
105 inputPort( 7)->setPos(64, 40); inputPort(7)->setName("C (" + tr("lower right vertical") + ")");
106 inputPort( 8)->setPos( 0, 56); inputPort(8)->setName("G2 (" + tr("middle right horizontal") + ")");
107 inputPort( 9)->setPos( 0, 72); inputPort(9)->setName("H (" + tr("upper left diagonal") + ")");
108 inputPort(10)->setPos( 0, 88); inputPort(10)->setName("J (" + tr("upper center vertical") + ")");
109 inputPort(11)->setPos(64, 56); inputPort(11)->setName("K (" + tr("upper right diagonal") + ")");
110 inputPort(12)->setPos(64, 72); inputPort(12)->setName("L (" + tr("lower right diagonal") + ")");
111 inputPort(13)->setPos(64, 88); inputPort(13)->setName("M (" + tr("lower center vertical") + ")");
112 inputPort(14)->setPos(64, 104); inputPort(14)->setName("N (" + tr("lower left diagonal") + ")");
113
114 for (auto *port : inputs()) {
115 port->setRequired(false);
116 port->setDefaultStatus(Status::Inactive);
117 }
118
119 // This override doesn't chain to the base updatePortsProperties(), so re-apply the current
120 // rotation/flip orientation to the freshly-positioned ports (keeps flip working on displays).
121 rotatePorts();
122}
123
124void Display14::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
125{
126 // Base class paints the off-state background; active segments are overlaid as vector
127 // renders on top, crisp at any zoom.
128 GraphicElement::paint(painter, option, widget);
129
130 const QRectF body(0, 0, 64, 64);
131 if (inputPort(0)->status() == Status::Active) { g1.at(m_colorNumber)->render(painter, body); }
132 if (inputPort(1)->status() == Status::Active) { f.at(m_colorNumber)->render(painter, body); }
133 if (inputPort(2)->status() == Status::Active) { e.at(m_colorNumber)->render(painter, body); }
134 if (inputPort(3)->status() == Status::Active) { d.at(m_colorNumber)->render(painter, body); }
135 if (inputPort(4)->status() == Status::Active) { a.at(m_colorNumber)->render(painter, body); }
136 if (inputPort(5)->status() == Status::Active) { b.at(m_colorNumber)->render(painter, body); }
137 if (inputPort(6)->status() == Status::Active) { dp.at(m_colorNumber)->render(painter, body); }
138 if (inputPort(7)->status() == Status::Active) { c.at(m_colorNumber)->render(painter, body); }
139 if (inputPort(8)->status() == Status::Active) { g2.at(m_colorNumber)->render(painter, body); }
140 if (inputPort(9)->status() == Status::Active) { h.at(m_colorNumber)->render(painter, body); }
141 if (inputPort(10)->status() == Status::Active) { j.at(m_colorNumber)->render(painter, body); }
142 if (inputPort(11)->status() == Status::Active) { k.at(m_colorNumber)->render(painter, body); }
143 if (inputPort(12)->status() == Status::Active) { l.at(m_colorNumber)->render(painter, body); }
144 if (inputPort(13)->status() == Status::Active) { m.at(m_colorNumber)->render(painter, body); }
145 if (inputPort(14)->status() == Status::Active) { n.at(m_colorNumber)->render(painter, body); }
146}
147
148void Display14::setColor(const QString &color)
149{
150 m_color = color;
151 m_colorNumber = colorNameToIndex(color);
152}
153
154QString Display14::color() const
155{
156 return m_color;
157}
158
159void Display14::save(QDataStream &stream, SerializationOptions options) const
160{
161 GraphicElement::save(stream, options);
162
163 QMap<QString, QVariant> map;
164 // PortableFile streams omit the default; fresh-loaded elements start there
165 // anyway. Snapshots write unconditionally (reloaded into live elements).
167 map.insert("color", color());
168 }
169
170 stream << map;
171}
172
173void Display14::load(QDataStream &stream, SerializationContext &context)
174{
175 GraphicElement::load(stream, context);
176
178 // v3.1–4.0 stored color as a bare QString
179 const QString color_ = Serialization::readBoundedString(stream);
180 setColor(color_);
181 }
182
183 if (VersionInfo::hasQMapFormat(context.version)) {
184 // v4.1+ uses a key-value map
185 QMap<QString, QVariant> map = Serialization::readBoundedMetadata(stream);
186
187 if (map.contains("color")) {
188 setColor(map.value("color").toString());
189 }
190 }
191}
Graphic element for the 14-segment LED display.
Graphic element for the 7-segment LED display.
Singleton factory for all circuit element types.
Self-registering element trait template and compile-time constraint validation.
ElementMetadata metadataFromConstraints(const ElementConstraints &c)
Converts ElementConstraints to an ElementMetadata with all constraint-derived fields set.
Definition ElementInfo.h:80
constexpr bool validate(const ElementConstraints &c)
Validates element constraints at compile time.
Definition ElementInfo.h:48
Enums::ElementType ElementType
Definition Enums.h:107
Port classes: Port (base), InputPort, and OutputPort.
Deserialization/serialization context structs passed through load()/save() call chains.
Circuit and waveform file serialization/deserialization utilities.
Named version predicates for file-format compatibility checks.
14-segment LED display output element (14 segments + decimal point = 15 inputs).
Definition Display14.h:24
void save(QDataStream &stream, SerializationOptions options) const override
Serializes the color selection to stream.
void refresh() override
Refreshes the displayed segments based on current input states.
Definition Display14.cpp:88
static constexpr const char * kDefaultColor
Definition Display14.h:30
void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) override
Display14(QGraphicsItem *parent=nullptr)
Constructs the element with optional parent.
Definition Display14.cpp:66
void load(QDataStream &stream, SerializationContext &context) override
QString color() const override
Returns the current display color name.
void updatePortsProperties() override
Updates port positions (fixed at 15 inputs).
Definition Display14.cpp:93
void setColor(const QString &color) override
Sets the display color.
static QVector< std::shared_ptr< QSvgRenderer > > cachedSegmentRenderers(const QString &resourcePath)
Definition Display7.cpp:94
static void registerCreator(ElementType type, std::function< GraphicElement *()> creator)
Registers a creator lambda for type, used by buildElement().
static void registerMetadata(const ElementMetadata &meta)
Registers meta in the global map (called once per element type at startup).
GraphicElement(ElementType type, QGraphicsItem *parent=nullptr)
Constructs a graphic element of the given type, fetching all properties from the metadata registry.
ElementAppearance m_appearance
void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) override
Paints the element onto the scene.
virtual void load(QDataStream &stream, SerializationContext &context)
Loads the graphic element through a binary data stream.
InputPort * inputPort(const int index=0) const
Returns the input port at index (default 0).
static int colorNameToIndex(const QString &color)
Maps a color name ("White","Red","Green","Blue","Purple") to indices 0–4.
virtual void save(QDataStream &stream, SerializationOptions options) const
const QVector< InputPort * > & inputs() const
Returns a const reference to the vector of all input ports.
void setName(const QString &name)
Sets the label text shown next to the port.
Definition Port.cpp:166
static QString readBoundedString(QDataStream &stream)
Reads a QString from stream, refusing to allocate more bytes than remain in the stream (prevents OOM ...
static QMap< QString, QVariant > readBoundedMetadata(QDataStream &stream)
Reads the file-level metadata QMap<QString,QVariant> from stream without calling QList::reserve() wit...
bool hasLockState(const QVersionNumber &v)
V3.1: Lock state for input elements; color for some display/button types.
Definition VersionInfo.h:51
bool hasQMapFormat(const QVersionNumber &v)
V4.1: Format changed from flat binary to keyed QMap; port serial IDs; rotation fix.
Definition VersionInfo.h:60
Compile-time-validatable subset of ElementMetadata.
Definition ElementInfo.h:21
static const bool registered
Definition Display14.cpp:59
static ElementMetadata metadata()
Definition Display14.cpp:31
static constexpr ElementConstraints constraints
Definition Display14.cpp:19
Self-registering element information trait.
Compile-time-registered properties for one element type.
Bundles all per-deserialization state so that load() overrides receive it through one explicit parame...
QVersionNumber version
File-format version read from the stream header.
Options passed to GraphicElement::save() (and friends); the save-side counterpart of SerializationCon...
SerializationPurpose purpose
What this serialization is for; see SerializationPurpose. Mandatory, no default.