wiRedPanda
Logic Circuit Simulator
Loading...
Searching...
No Matches
SelectionCapabilities.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 "App/Core/Enums.h"
9
10SelectionCapabilities computeCapabilities(const QList<GraphicElement *> &elements)
11{
13
14 if (elements.isEmpty()) {
15 return c;
16 }
17
18 auto *firstElement = elements.constFirst();
19 auto *firstInput = qobject_cast<GraphicElementInput *>(firstElement);
20
21 // Start all flags true; AND-reduce over the selection below.
22 c.hasAudioBox = c.hasAudio = c.hasColors = c.hasDelay = c.hasElements = true;
24 c.canChangeAppearance = c.canMorph = true;
25 c.isFileBacked = c.isEmbedded = (firstElement->elementType() == ElementType::IC);
29 c.sameCheckState = true;
30 // Start at a very high "infinity" so std::min finds the real maximum.
32 c.elementType = firstElement->elementType();
33
34 for (auto *elm : elements) {
35 const auto group = elm->elementGroup();
36 const auto firstGroup = firstElement->elementGroup();
37
38 c.hasTruthTable &= elm->hasTruthTable();
39 c.hasLabel &= elm->hasLabel();
40 c.canChangeAppearance &= elm->canChangeAppearance();
41 c.hasColors &= elm->hasColors();
42 c.hasAudio &= elm->hasAudio();
43 c.hasAudioBox &= elm->hasAudioBox();
44 c.hasFrequency &= elm->hasFrequency();
45 c.hasDelay &= elm->hasDelay();
46 c.minimumInputs = (std::max)(c.minimumInputs, elm->minInputSize());
47 c.maximumInputs = (std::min)(c.maximumInputs, elm->maxInputSize());
48 c.minimumOutputs = (std::max)(c.minimumOutputs, elm->minOutputSize());
49 c.maximumOutputs = (std::min)(c.maximumOutputs, elm->maxOutputSize());
50 c.hasVolume &= elm->hasVolume();
51 c.hasWirelessMode &= elm->hasWirelessMode();
52 c.hasTrigger &= elm->hasTrigger();
53
54 c.hasSameLabel &= (elm->label() == firstElement->label());
55 c.hasSameColors &= (elm->color() == firstElement->color());
56 c.hasSameFrequency &= qFuzzyCompare(elm->frequency(), firstElement->frequency());
57 c.hasSameDelay &= qFuzzyCompare(elm->delay(), firstElement->delay());
58 c.hasSameInputSize &= (elm->inputSize() == firstElement->inputSize());
59 c.hasSameOutputSize &= (elm->outputSize() == firstElement->outputSize());
60 c.maxCurrentOutputSize = (std::min)(c.maxCurrentOutputSize, elm->outputSize());
61
62 if (auto *elmInput = qobject_cast<GraphicElementInput *>(elm);
63 elmInput && (group == ElementGroup::Input) && (firstElement->elementGroup() == ElementGroup::Input)) {
64 c.hasSameOutputValue &= (elmInput->outputValue() == firstInput->outputValue());
65 c.sameCheckState &= (elmInput->isLocked() == firstInput->isLocked());
66 }
67
68 c.hasSameTrigger &= (elm->trigger() == firstElement->trigger());
69 c.hasSameType &= (elm->elementType() == firstElement->elementType());
70 c.hasSameAudio &= (elm->audio() == firstElement->audio());
71 c.hasSameVolume &= qFuzzyCompare(elm->volume(), firstElement->volume());
72
73 // Embedded IC flags: AND-reduced so both are true only when ALL selected
74 // elements are ICs that are embedded or file-backed respectively.
75 if (elm->elementType() != ElementType::IC) {
76 c.isFileBacked = false;
77 c.isEmbedded = false;
78 } else {
79 c.isFileBacked &= !elm->isEmbedded();
80 c.isEmbedded &= elm->isEmbedded();
81 }
82
83 // Static inputs (Vcc/Gnd) and regular inputs share morph compatibility
84 // because they occupy the same pin role in a circuit.
85 bool sameElementGroup = (group == firstGroup);
86 sameElementGroup |= (group == ElementGroup::Input && firstGroup == ElementGroup::StaticInput);
87 sameElementGroup |= (group == ElementGroup::StaticInput && firstGroup == ElementGroup::Input);
88 c.hasOnlyInputs &= (group == ElementGroup::Input);
89 c.hasLatchedValue &= (group == ElementGroup::Input) && (elm->elementType() != ElementType::InputButton);
90 c.canMorph &= sameElementGroup;
91 }
92
93 if (!c.hasSameType) {
94 c.elementType = ElementType::Unknown;
95 }
96
97 // A size combobox is only useful when there is a valid range of options.
99 // TruthTable output count is controlled by its own dialog, not this combobox.
101 // For Demux, input size is derived from output size — hide input combobox.
102 if (c.hasSameType && c.elementType == ElementType::Demux) {
103 c.canChangeInputSize = false;
104 }
105
106 return c;
107}
Central enumeration types for element types, groups, and signal status.
Abstract base class for user-controllable input elements.
Abstract base class for all graphical circuit elements.
SelectionCapabilities computeCapabilities(const QList< GraphicElement * > &elements)
Computes the SelectionCapabilities for a list of selected elements.
SelectionCapabilities struct and computeCapabilities() free function.
Computed capabilities and consensus state of the current element selection.