wiRedPanda
Logic Circuit Simulator
Loading...
Searching...
No Matches
GraphicElement.h
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
7
8#pragma once
9
10#include <memory>
11#include <utility>
12
13#include <QBitArray>
14#include <QGraphicsItem>
15#include <QKeySequence>
16#include <QList>
17
18#include "App/Core/Enums.h"
19#include "App/Core/ItemWithId.h"
26
29
30class GraphicElement;
31class InputPort;
32class OutputPort;
33class Port;
34class QPainter;
35class QStyleOptionGraphicsItem;
36class QSvgRenderer;
37class QWidget;
38
58class GraphicElement : public QGraphicsObject, public ItemWithId
59{
60 Q_OBJECT
61public:
62 // --- Type Info ---
63
64 enum { Type = QGraphicsItem::UserType + 3 };
65
67 int type() const override { return Type; }
68
69 // --- Lifecycle ---
70
72 explicit GraphicElement(ElementType type, QGraphicsItem *parent = nullptr);
73
75 ~GraphicElement() override;
76
77signals:
83
84public:
85 // --- External file dependencies ---
86
89 virtual QStringList externalFiles() const;
90
91 // --- Serialization ---
92
96 virtual void save(QDataStream &stream, SerializationOptions options) const;
97
103 virtual void load(QDataStream &stream, SerializationContext &context);
104
105 // --- Port Management ---
106
114 virtual void updatePortsProperties();
115
122 virtual WirelessMode wirelessMode() const;
123
129 virtual bool hasWirelessMode() const;
130
131 // --- Element Type & Identity ---
132
135
137 ElementType elementType() const;
138
139 // --- Port Access ---
140
142 InputPort *inputPort(const int index = 0) const;
143
145 OutputPort *outputPort(const int index = 0) const;
146
148 const QVector<InputPort *> &inputs() const;
149
151 const QVector<OutputPort *> &outputs() const;
152
154 QVector<Port *> allPorts() const;
155
157 int inputSize() const;
158
160 int outputSize() const;
161
162 // --- Port Size Constraints ---
163
165 int maxInputSize() const;
166
168 int minInputSize() const;
169
171 int maxOutputSize() const;
172
174 int minOutputSize() const;
175
176 // --- Labeling ---
177
179 QString label() const;
180
182 void setLabel(const QString &label);
183
185 void updateLabel();
186
188 bool hasLabel() const;
189
193 QRectF labelSceneBoundingRect() const;
194
195 // --- Embedded IC ---
196
198 virtual bool isEmbedded() const { return false; }
199
201 virtual const QString &blobName() const { static const QString empty; return empty; }
202
203 // --- Trigger Control ---
204
206 QKeySequence trigger() const;
207
209 void setTrigger(const QKeySequence &trigger);
210
212 bool hasTrigger() const;
213
214 // --- Audio Properties ---
215
217 virtual QString audio() const;
218
220 virtual void setAudio(const QString &audio);
221
223 bool hasAudio() const;
224
226 bool hasAudioBox() const;
227
229 bool hasVolume() const;
230
232 virtual float volume() const;
233
235 virtual void setVolume(float vol);
236
237 // --- Color Properties ---
238
240 virtual QString color() const;
241
243 virtual void setColor(const QString &color);
244
246 bool hasColors() const;
247
249 static int colorNameToIndex(const QString &color);
250
252 QString nextColor() const;
253
255 QString previousColor() const;
256
257 // --- Frequency & Delay ---
258
260 virtual double frequency() const;
261
263 virtual double delay() const;
264
266 bool hasFrequency() const;
267
269 bool hasDelay() const;
270
272 virtual void setFrequency(const double freq);
273
275 virtual void setDelay(const double delay);
276
282 QList<PropertyDescriptor> editableProperties() const;
283
284 // --- Appearance Management ---
285
287 bool canChangeAppearance() const;
288
294 virtual void setAppearance(const bool defaultAppearance, const QString &fileName);
295
301 void setAppearanceAt(const int index, const QString &fileName);
302
308 virtual QList<std::pair<int, QString>> appearanceStates() const;
309
311 QPixmap appearancePreviewPixmap(const int index, const QSize &size) const;
312
314 void setPixmap(const QString &pixmapPath);
315
317 void setPixmap(const int index);
318
319 // --- Truth Table ---
320
322 bool hasTruthTable() const;
323
324 // --- Rotation ---
325
327 qreal rotation() const;
328
330 void setRotation(const qreal angle);
331
334 bool rotatesGraphic() const;
335
338 void rotatePorts();
339
344 void reapplyAppearanceOrientation() { m_appearance.applyOrientation(); updateLabelOrientation(); }
345
346 // --- Flip / Mirror ---
347
349 bool isFlippedX() const { return m_orientation.isFlippedX(); }
350
352 bool isFlippedY() const { return m_orientation.isFlippedY(); }
353
355 void setFlippedX(bool flipped);
356
358 void setFlippedY(bool flipped);
359
360 // --- Geometric Properties ---
361
363 QPointF pixmapCenter() const;
364
366 QRectF boundingRect() const override;
367
368 // --- State Queries ---
369
371 bool isValid();
372
373 // --- Direct Simulation Interface ---
374
379 virtual void updateLogic();
380
388 virtual void resetSimState();
389
399 virtual void resettleCombinational() { updateLogic(); }
400
410 virtual void saveSimState(QVector<Status> &out) const;
411
414 virtual void restoreSimState(const QVector<Status> &in, int &cursor);
415
417 inline Status outputValue(const int index = 0) const { return m_sim.outputValue(index); }
418
420 qsizetype simOutputSize() const { return m_sim.outputSize(); }
421
423 inline void setOutputValue(const int index, const Status value) { m_sim.setOutputValue(index, value); }
424
426 inline void setOutputValue(const Status value) { m_sim.setOutputValue(0, value); }
427
429 void setOutputValue(const int index, const bool value) { m_sim.setOutputValue(index, value ? Status::Active : Status::Inactive); }
430
432 void setOutputValue(const bool value) { m_sim.setOutputValue(0, value ? Status::Active : Status::Inactive); }
433
435 void connectPredecessor(const int inputIndex, GraphicElement *source, const int outputPort);
436
439 bool outputChanged() const { return m_sim.outputChanged(); }
440
442 void clearOutputChanged() { m_sim.clearOutputChanged(); }
443
446 void beginDeferredCommit() { m_sim.beginDeferredCommit(); }
447
450 void commitDeferredOutputs() { m_sim.commitDeferredOutputs(); }
451
453 void initSimulationVectors(const int inputCount, const int outputCount);
454
456 virtual void loadFromDrop(const QString &fileName, const QString &contextDir);
457
458 // --- Virtual Methods ---
459
461 virtual QString genericProperties();
462
464 virtual void refresh();
465
466 // --- Qt Graphics & Display ---
467
476 void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) override;
477
483 void retranslate();
484
485 // --- Setters (Port & Logic Configuration) ---
486
488 virtual void setInputSize(const int size);
489
491 virtual void setOutputSize(const int size);
492
494 void setInputs(const QVector<InputPort *> &inputs);
495
497 void setPortName(const QString &name);
498
500 const QVector<Status> &simInputs() const { return m_sim.inputs(); }
501
503 const QVector<Status> &simOutputs() const { return m_sim.outputs(); }
504
505 // --- Theme ---
506
508 virtual void updateTheme();
509
510protected:
511 // --- Graphics & Rendering ---
512
514 QPixmap pixmap() const;
515
522 QRectF portsBoundingRect() const;
523
532 QRectF renderBodyBounds() const;
533
538 void setLabelAnchor(const QPointF &pos);
539
542 virtual void labelContentChanged() {}
543
544 // --- Qt Event Handling ---
545
557 QVariant itemChange(GraphicsItemChange change, const QVariant &value) override;
558
566 void mouseDoubleClickEvent(QGraphicsSceneMouseEvent *event) override;
567
575 bool sceneEvent(QEvent *event) override;
576
577 // --- Capability Setters ---
578
580 void setHasColors(const bool hasColors);
581
582 // --- Port Size Constraint Setters ---
583
585 void setMaxInputSize(const int maxInputSize);
586
588 void setMinInputSize(const int minInputSize);
589
591 void setMaxOutputSize(const int maxOutputSize);
592
594 void setMinOutputSize(const int minOutputSize);
595
599
603
604 QGraphicsSimpleTextItem *m_label = new QGraphicsSimpleTextItem(this);
606
607 // --- Members: Metadata ---
608
609 QString m_titleText;
611
612 // --- Direct Simulation Helpers ---
613
625 bool simUpdateInputs() { return m_sim.updateInputs(false, m_ports.inputs()); }
626
634 bool simUpdateInputsAllowUnknown() { return m_sim.updateInputs(true, m_ports.inputs()); }
635
643 int decodeSelectValue(int offset, int count) const { return m_sim.decodeSelectValue(offset, count); }
644
645private:
646 Q_DISABLE_COPY_MOVE(GraphicElement)
647
648
651
655 friend class ElementAppearance;
656
661 friend class TestGraphicElement;
662
668 void invalidateRenderCache();
669
670 // --- Port Management Helpers ---
671
674 void setPortSize(const int size, const bool isInput);
675
676 // --- Display & Interaction ---
677
684 void highlight(const bool isSelected);
685
689 void updateLabelOrientation();
690
691 // --- Members: Element Type & Identity ---
692
693 ElementGroup m_elementGroup = ElementGroup::Unknown;
694 ElementType m_elementType = ElementType::Unknown;
695
699 const ElementMetadata &m_metadata;
700
701 // --- Members: Direct Simulation ---
702
705 ElementSimState m_sim;
706
707 // --- Members: Trigger & Label ---
708
709 QKeySequence m_trigger;
710 QString m_labelText;
711
712 // --- Members: Capabilities & Display State ---
713
714 bool m_hasColors = false;
715 bool m_selected = false;
716
720 ElementOrientation m_orientation{this};
721
722 // --- Members: Port Size Constraints ---
723
724 quint64 m_minInputSize = 0;
725 quint64 m_maxInputSize = 0;
726 quint64 m_minOutputSize = 0;
727 quint64 m_maxOutputSize = 0;
728};
Owns a GraphicElement's pixmap / SVG appearance, appearance list, and selection paint.
Element metadata struct and global registry for compile-time element registration.
Owns a GraphicElement's rotation angle and flip (mirror) state.
Owns a GraphicElement's input/output port vectors and their creation/resize lifecycle.
Per-element simulation runtime state (input/output values and the connection graph).
Central enumeration types for element types, groups, and signal status.
Enums::ElementType ElementType
Definition Enums.h:107
Enums::Status Status
Definition Enums.h:106
Enums::WirelessMode WirelessMode
Definition Enums.h:109
Enums::ElementGroup ElementGroup
Definition Enums.h:108
Defines ItemWithId, the base class for all uniquely identified circuit items.
PropertyDescriptor struct for describing editable element properties.
@ Unknown
Undefined (Status::Unknown): drawn mid-level in the canvas's "unknown" grey.
Owns the rotation angle and flip flags of a GraphicElement, and the transform math that applies them ...
Owns the input and output Port vectors of a GraphicElement and the primitives that create,...
Owns a GraphicElement's simulation runtime state, decoupled from its graphics.
Abstract base class for all graphical circuit elements in wiRedPanda.
void setOutputValue(const bool value)
Convenience overload — converts bool to Active/Inactive for port 0.
virtual void updateLogic()
Computes this element's output values from its current inputs.
QPointF pixmapCenter() const
Returns the centre point of the element's pixmap in local coordinates.
GraphicElement(ElementType type, QGraphicsItem *parent=nullptr)
Constructs a graphic element of the given type, fetching all properties from the metadata registry.
const QVector< Status > & simInputs() const
Read-only view of the cached simulation input values.
virtual void updateTheme()
Updates the element's visual theme according to the current dark/light palette.
void setFlippedY(bool flipped)
Sets the vertical mirror state and updates the item transform.
Status outputValue(const int index=0) const
Returns the four-state signal value on simulation output port index.
QPixmap appearancePreviewPixmap(const int index, const QSize &size) const
Returns a small preview pixmap for the appearance at index (see appearanceStates()).
QString m_translatedName
Translated element name used as tooltip and port object name.
virtual WirelessMode wirelessMode() const
Returns the wireless routing mode for this element.
virtual void setFrequency(const double freq)
Sets the clock frequency to freq (overridden by clock elements).
ElementType elementType() const
Returns the type identifier for this element.
int decodeSelectValue(int offset, int count) const
Decodes count select-line statuses from simInputs() into a binary index.
void setHasColors(const bool hasColors)
Sets whether this element type supports color selection.
void setFlippedX(bool flipped)
Sets the horizontal mirror state and updates the item transform.
bool hasDelay() const
Returns true if this element type exposes a configurable clock phase delay.
void clearOutputChanged()
Clears the simulation output-changed flag.
void commitDeferredOutputs()
virtual void setColor(const QString &color)
Sets the element color to color and refreshes the pixmap.
virtual QStringList externalFiles() const
ElementAppearance m_appearance
bool hasVolume() const
Returns true if this element type supports volume control.
virtual void setAudio(const QString &audio)
Sets the audio file associated with this element to audio.
virtual void resettleCombinational()
Re-evaluates combinational outputs after the synchronous sequential commit, propagating just-committe...
int inputSize() const
Returns the current number of input ports.
QList< PropertyDescriptor > editableProperties() const
Returns the list of editable properties this element exposes in the ElementEditor.
bool hasTruthTable() const
Returns true if this element type has an editable truth table.
qsizetype simOutputSize() const
Returns the number of simulation output slots.
bool hasAudioBox() const
Returns true if this element type shows an audio selection box.
void retranslate()
Updates the translated display name, tooltip, and port object name after a locale change.
qreal rotation() const
Returns the current rotation angle of this element in degrees.
void setRotation(const qreal angle)
Rotates the element to angle degrees and updates port positions.
bool isFlippedY() const
Returns true if this element is mirrored along the Y axis (vertical flip).
QRectF portsBoundingRect() const
Returns the bounding rectangle that encompasses all child ports.
QVector< Port * > allPorts() const
Returns a combined list of all input and output ports as Port pointers.
void setLabelAnchor(const QPointF &pos)
void inlineEditRequested(GraphicElement *element)
QPixmap pixmap() const
Returns the pixmap currently displayed by this element.
bool simUpdateInputsAllowUnknown()
Like simUpdateInputs(), but allows Unknown/Error values through.
bool outputChanged() const
void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) override
Paints the element onto the scene.
void setOutputValue(const int index, const Status value)
Sets simulation output port index to value.
QRectF renderBodyBounds() const
Footprint of a "procedural render body" (IC/Mux/Demux/TruthTable): the nominal 64x64 body unioned wit...
QString label() const
Returns the user-visible label text for this element.
int maxOutputSize() const
Returns the maximum allowed number of output ports.
virtual QList< std::pair< int, QString > > appearanceStates() const
Returns the list of editable appearance states for this element. Each pair is (appearance list index,...
virtual void load(QDataStream &stream, SerializationContext &context)
Loads the graphic element through a binary data stream.
void setTrigger(const QKeySequence &trigger)
Sets the keyboard shortcut to trigger and updates the label.
InputPort * inputPort(const int index=0) const
Returns the input port at index (default 0).
virtual bool isEmbedded() const
Returns true if this element is an embedded IC (not file-backed). Base returns false.
virtual void loadFromDrop(const QString &fileName, const QString &contextDir)
Polymorphic interface for drag-drop initialization (replaces elementType() == IC checks).
void mouseDoubleClickEvent(QGraphicsSceneMouseEvent *event) override
Requests inline label editing on double-click.
void setAppearanceAt(const int index, const QString &fileName)
Sets a custom appearance at a specific index in the appearance list.
int minInputSize() const
Returns the minimum allowed number of input ports.
void setInputs(const QVector< InputPort * > &inputs)
Replaces the input port vector with inputs.
friend class GraphicElementSerializer
virtual QString audio() const
Returns the name of the audio file currently associated with this element.
bool hasLabel() const
Returns true if this element type supports a user-editable label.
friend class TestGraphicElement
virtual double delay() const
Returns the clock phase delay in seconds (overridden by Clock; returns 0 for other elements).
virtual void setInputSize(const int size)
Adjusts the number of input ports to size, adding or removing ports as needed.
virtual void saveSimState(QVector< Status > &out) const
Appends this element's full simulation state to out.
void setOutputValue(const Status value)
Sets simulation output port 0 to value.
virtual double frequency() const
Returns the clock frequency in Hz (overridden by Clock; returns 0 for other elements).
~GraphicElement() override
Out-of-line so the unique_ptr to the forward-declared QSvgRenderer can be destroyed.
QKeySequence trigger() const
Returns the keyboard shortcut that activates this element.
friend class ElementAppearance
void setLabel(const QString &label)
Sets the label text to label and refreshes the display.
void updateLabel()
Repositions and updates the label child item to reflect current state.
virtual QString color() const
Returns the name of the color currently applied to this element.
int outputSize() const
Returns the current number of output ports.
void beginDeferredCommit()
void initSimulationVectors(const int inputCount, const int outputCount)
Allocates simulation I/O vectors with inputs inputs and outputs outputs.
QGraphicsSimpleTextItem * m_label
Child text item that displays the label and optional trigger shortcut.
void setOutputValue(const int index, const bool value)
Convenience overload — converts bool to Active/Inactive for port index.
QRectF labelSceneBoundingRect() const
void reapplyAppearanceOrientation()
void setPortName(const QString &name)
Sets the object name of all ports to name for identification.
OutputPort * outputPort(const int index=0) const
Returns the output port at index (default 0).
QString m_titleText
Translated title text shown in UI panels (from metadata).
bool hasFrequency() const
Returns true if this element type exposes a configurable clock frequency.
QString nextColor() const
Returns the name of the next color in the element's color list.
static int colorNameToIndex(const QString &color)
Maps a color name ("White","Red","Green","Blue","Purple") to indices 0–4.
bool hasColors() const
Returns true if this element type supports color selection.
ElementGroup elementGroup() const
Returns the group this element belongs to.
bool simUpdateInputs()
Snapshots each predecessor's output into the simulation input cache.
int maxInputSize() const
Returns the maximum allowed number of input ports.
virtual void save(QDataStream &stream, SerializationOptions options) const
void setMaxInputSize(const int maxInputSize)
Sets the maximum number of input ports to maxInputSize.
QPointF m_labelAnchor
The label's intended anchor point in the element's un-rotated local frame; see setLabelAnchor().
const QVector< Status > & simOutputs() const
Read-only view of the current simulation output values.
virtual void setDelay(const double delay)
Sets the clock phase delay to delay (overridden by clock elements).
void setMaxOutputSize(const int maxOutputSize)
Sets the maximum number of output ports to maxOutputSize.
void setPixmap(const QString &pixmapPath)
Loads and applies the pixmap located at pixmapPath.
bool canChangeAppearance() const
Returns true if the user is allowed to choose a custom appearance for this element.
virtual void setAppearance(const bool defaultAppearance, const QString &fileName)
Switches the element's appearance.
int minOutputSize() const
Returns the minimum allowed number of output ports.
void connectPredecessor(const int inputIndex, GraphicElement *source, const int outputPort)
Connects simulation input inputIndex to output outputPort of source element.
bool isFlippedX() const
Returns true if this element is mirrored along the X axis (horizontal flip).
ElementPorts m_ports
virtual void resetSimState()
Resets all simulation-visible state to power-on defaults.
virtual QString genericProperties()
Returns a string encoding element-specific properties for serialization or display.
bool isValid()
Returns true if the element is fully initialised and connected correctly.
int type() const override
Returns the custom type identifier for this item.
virtual void setVolume(float vol)
Sets the audio playback volume to vol (0.0–1.0).
void setMinInputSize(const int minInputSize)
Sets the minimum number of input ports to minInputSize.
QRectF boundingRect() const override
Returns the bounding rectangle of this element in local coordinates.
const QVector< OutputPort * > & outputs() const
Returns a const reference to the vector of all output ports.
virtual void labelContentChanged()
virtual bool hasWirelessMode() const
Returns true if this element supports a configurable wireless routing mode.
virtual void restoreSimState(const QVector< Status > &in, int &cursor)
virtual const QString & blobName() const
Returns the blob name for embedded ICs, empty string otherwise. Base returns empty.
virtual float volume() const
Returns the audio playback volume (0.0–1.0).
virtual void setOutputSize(const int size)
Adjusts the number of output ports to size, adding or removing ports as needed.
void setMinOutputSize(const int minOutputSize)
Sets the minimum number of output ports to minOutputSize.
QString previousColor() const
Returns the name of the previous color in the element's color list.
bool hasAudio() const
Returns true if this element type supports audio output.
bool sceneEvent(QEvent *event) override
Intercepts mouse-press and mouse-release events to handle Ctrl+click.
bool rotatesGraphic() const
virtual void updatePortsProperties()
Repositions and reconfigures all ports after the port count changes.
virtual void refresh()
Forces a visual refresh of the element's pixmap and ports.
bool hasTrigger() const
Returns true if this element type supports a keyboard trigger.
QVariant itemChange(GraphicsItemChange change, const QVariant &value) override
Handles item state changes such as position, rotation, and selection.
const QVector< InputPort * > & inputs() const
Returns a const reference to the vector of all input ports.
A port that receives a signal (the destination end of a wire).
Definition Port.h:234
ItemWithId()=default
Constructs a new ItemWithId with an unassigned ID of -1.
A port that drives a signal (the source end of a wire).
Definition Port.h:266
Abstract base class for circuit element ports (connection endpoints).
Definition Port.h:39
Compile-time-registered properties for one element type.
Bundles all per-deserialization state so that load() overrides receive it through one explicit parame...
Options passed to GraphicElement::save() (and friends); the save-side counterpart of SerializationCon...