digsim-logic-simulator 0.12.0__tar.gz → 0.13.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of digsim-logic-simulator might be problematic. Click here for more details.
- {digsim_logic_simulator-0.12.0/src/digsim_logic_simulator.egg-info → digsim_logic_simulator-0.13.0}/PKG-INFO +1 -1
- {digsim_logic_simulator-0.12.0 → digsim_logic_simulator-0.13.0}/pyproject.toml +1 -1
- {digsim_logic_simulator-0.12.0 → digsim_logic_simulator-0.13.0}/src/digsim/app/__main__.py +16 -12
- {digsim_logic_simulator-0.12.0 → digsim_logic_simulator-0.13.0}/src/digsim/app/gui/_circuit_area.py +32 -21
- {digsim_logic_simulator-0.12.0 → digsim_logic_simulator-0.13.0}/src/digsim/app/gui/_component_selection.py +2 -0
- {digsim_logic_simulator-0.12.0 → digsim_logic_simulator-0.13.0}/src/digsim/app/gui_objects/__init__.py +1 -1
- {digsim_logic_simulator-0.12.0 → digsim_logic_simulator-0.13.0}/src/digsim/app/gui_objects/_buzzer_object.py +6 -6
- {digsim_logic_simulator-0.12.0 → digsim_logic_simulator-0.13.0}/src/digsim/app/gui_objects/_component_context_menu.py +1 -1
- {digsim_logic_simulator-0.12.0 → digsim_logic_simulator-0.13.0}/src/digsim/app/gui_objects/_component_object.py +10 -9
- {digsim_logic_simulator-0.12.0 → digsim_logic_simulator-0.13.0}/src/digsim/app/gui_objects/_component_port_item.py +0 -2
- {digsim_logic_simulator-0.12.0 → digsim_logic_simulator-0.13.0}/src/digsim/app/gui_objects/_dip_switch_object.py +5 -4
- {digsim_logic_simulator-0.12.0 → digsim_logic_simulator-0.13.0}/src/digsim/app/gui_objects/_gui_note_object.py +10 -11
- {digsim_logic_simulator-0.12.0 → digsim_logic_simulator-0.13.0}/src/digsim/app/gui_objects/_gui_object_factory.py +1 -1
- {digsim_logic_simulator-0.12.0 → digsim_logic_simulator-0.13.0}/src/digsim/app/gui_objects/_image_objects.py +7 -5
- {digsim_logic_simulator-0.12.0 → digsim_logic_simulator-0.13.0}/src/digsim/app/gui_objects/_label_object.py +3 -2
- {digsim_logic_simulator-0.12.0 → digsim_logic_simulator-0.13.0}/src/digsim/app/gui_objects/_logic_analyzer_object.py +18 -9
- {digsim_logic_simulator-0.12.0 → digsim_logic_simulator-0.13.0}/src/digsim/app/gui_objects/_seven_segment_object.py +10 -3
- {digsim_logic_simulator-0.12.0 → digsim_logic_simulator-0.13.0}/src/digsim/app/gui_objects/_shortcut_objects.py +3 -2
- {digsim_logic_simulator-0.12.0 → digsim_logic_simulator-0.13.0}/src/digsim/app/model/_model.py +7 -3
- {digsim_logic_simulator-0.12.0 → digsim_logic_simulator-0.13.0}/src/digsim/app/model/_model_components.py +1 -4
- {digsim_logic_simulator-0.12.0 → digsim_logic_simulator-0.13.0}/src/digsim/app/model/_model_new_wire.py +2 -1
- {digsim_logic_simulator-0.12.0 → digsim_logic_simulator-0.13.0}/src/digsim/app/model/_model_objects.py +1 -5
- {digsim_logic_simulator-0.12.0 → digsim_logic_simulator-0.13.0}/src/digsim/app/model/_model_settings.py +1 -1
- {digsim_logic_simulator-0.12.0 → digsim_logic_simulator-0.13.0}/src/digsim/app/model/_model_shortcuts.py +0 -14
- {digsim_logic_simulator-0.12.0 → digsim_logic_simulator-0.13.0}/src/digsim/app/settings/_component_settings.py +1 -1
- {digsim_logic_simulator-0.12.0 → digsim_logic_simulator-0.13.0}/src/digsim/app/settings/_shortcut_dialog.py +3 -4
- {digsim_logic_simulator-0.12.0 → digsim_logic_simulator-0.13.0}/src/digsim/circuit/_circuit.py +52 -38
- {digsim_logic_simulator-0.12.0 → digsim_logic_simulator-0.13.0}/src/digsim/circuit/components/_button.py +1 -5
- {digsim_logic_simulator-0.12.0 → digsim_logic_simulator-0.13.0}/src/digsim/circuit/components/_yosys_component.py +1 -1
- {digsim_logic_simulator-0.12.0 → digsim_logic_simulator-0.13.0}/src/digsim/circuit/components/atoms/__init__.py +1 -0
- {digsim_logic_simulator-0.12.0 → digsim_logic_simulator-0.13.0}/src/digsim/circuit/components/atoms/_component.py +14 -4
- {digsim_logic_simulator-0.12.0 → digsim_logic_simulator-0.13.0}/src/digsim/circuit/components/atoms/_port.py +45 -29
- {digsim_logic_simulator-0.12.0 → digsim_logic_simulator-0.13.0}/src/digsim/storage_model/_app.py +7 -2
- {digsim_logic_simulator-0.12.0 → digsim_logic_simulator-0.13.0}/src/digsim/storage_model/_circuit.py +15 -7
- {digsim_logic_simulator-0.12.0 → digsim_logic_simulator-0.13.0}/src/digsim/synth/__main__.py +2 -2
- {digsim_logic_simulator-0.12.0 → digsim_logic_simulator-0.13.0}/src/digsim/synth/_synthesis.py +4 -1
- {digsim_logic_simulator-0.12.0 → digsim_logic_simulator-0.13.0}/src/digsim/utils/_yosys_netlist.py +9 -3
- {digsim_logic_simulator-0.12.0 → digsim_logic_simulator-0.13.0/src/digsim_logic_simulator.egg-info}/PKG-INFO +1 -1
- {digsim_logic_simulator-0.12.0 → digsim_logic_simulator-0.13.0}/tests/test_yosys_synth.py +1 -2
- {digsim_logic_simulator-0.12.0 → digsim_logic_simulator-0.13.0}/LICENSE.md +0 -0
- {digsim_logic_simulator-0.12.0 → digsim_logic_simulator-0.13.0}/MANIFEST.in +0 -0
- {digsim_logic_simulator-0.12.0 → digsim_logic_simulator-0.13.0}/README.md +0 -0
- {digsim_logic_simulator-0.12.0 → digsim_logic_simulator-0.13.0}/setup.cfg +0 -0
- {digsim_logic_simulator-0.12.0 → digsim_logic_simulator-0.13.0}/src/digsim/__init__.py +0 -0
- {digsim_logic_simulator-0.12.0 → digsim_logic_simulator-0.13.0}/src/digsim/app/gui/__init__.py +0 -0
- {digsim_logic_simulator-0.12.0 → digsim_logic_simulator-0.13.0}/src/digsim/app/gui/_main_window.py +0 -0
- {digsim_logic_simulator-0.12.0 → digsim_logic_simulator-0.13.0}/src/digsim/app/gui/_top_bar.py +0 -0
- {digsim_logic_simulator-0.12.0 → digsim_logic_simulator-0.13.0}/src/digsim/app/gui/_utils.py +0 -0
- {digsim_logic_simulator-0.12.0 → digsim_logic_simulator-0.13.0}/src/digsim/app/gui/_warning_dialog.py +0 -0
- {digsim_logic_simulator-0.12.0 → digsim_logic_simulator-0.13.0}/src/digsim/app/gui_objects/_bus_bit_object.py +0 -0
- {digsim_logic_simulator-0.12.0 → digsim_logic_simulator-0.13.0}/src/digsim/app/gui_objects/_hexdigit_object.py +0 -0
- {digsim_logic_simulator-0.12.0 → digsim_logic_simulator-0.13.0}/src/digsim/app/gui_objects/_yosys_object.py +0 -0
- {digsim_logic_simulator-0.12.0 → digsim_logic_simulator-0.13.0}/src/digsim/app/gui_objects/images/AND.png +0 -0
- {digsim_logic_simulator-0.12.0 → digsim_logic_simulator-0.13.0}/src/digsim/app/gui_objects/images/Analyzer.png +0 -0
- {digsim_logic_simulator-0.12.0 → digsim_logic_simulator-0.13.0}/src/digsim/app/gui_objects/images/BUF.png +0 -0
- {digsim_logic_simulator-0.12.0 → digsim_logic_simulator-0.13.0}/src/digsim/app/gui_objects/images/Buzzer.png +0 -0
- {digsim_logic_simulator-0.12.0 → digsim_logic_simulator-0.13.0}/src/digsim/app/gui_objects/images/Clock.png +0 -0
- {digsim_logic_simulator-0.12.0 → digsim_logic_simulator-0.13.0}/src/digsim/app/gui_objects/images/DFF.png +0 -0
- {digsim_logic_simulator-0.12.0 → digsim_logic_simulator-0.13.0}/src/digsim/app/gui_objects/images/DIP_SWITCH.png +0 -0
- {digsim_logic_simulator-0.12.0 → digsim_logic_simulator-0.13.0}/src/digsim/app/gui_objects/images/FlipFlop.png +0 -0
- {digsim_logic_simulator-0.12.0 → digsim_logic_simulator-0.13.0}/src/digsim/app/gui_objects/images/IC.png +0 -0
- {digsim_logic_simulator-0.12.0 → digsim_logic_simulator-0.13.0}/src/digsim/app/gui_objects/images/LED_OFF.png +0 -0
- {digsim_logic_simulator-0.12.0 → digsim_logic_simulator-0.13.0}/src/digsim/app/gui_objects/images/LED_ON.png +0 -0
- {digsim_logic_simulator-0.12.0 → digsim_logic_simulator-0.13.0}/src/digsim/app/gui_objects/images/MUX.png +0 -0
- {digsim_logic_simulator-0.12.0 → digsim_logic_simulator-0.13.0}/src/digsim/app/gui_objects/images/NAND.png +0 -0
- {digsim_logic_simulator-0.12.0 → digsim_logic_simulator-0.13.0}/src/digsim/app/gui_objects/images/NOR.png +0 -0
- {digsim_logic_simulator-0.12.0 → digsim_logic_simulator-0.13.0}/src/digsim/app/gui_objects/images/NOT.png +0 -0
- {digsim_logic_simulator-0.12.0 → digsim_logic_simulator-0.13.0}/src/digsim/app/gui_objects/images/ONE.png +0 -0
- {digsim_logic_simulator-0.12.0 → digsim_logic_simulator-0.13.0}/src/digsim/app/gui_objects/images/OR.png +0 -0
- {digsim_logic_simulator-0.12.0 → digsim_logic_simulator-0.13.0}/src/digsim/app/gui_objects/images/PB.png +0 -0
- {digsim_logic_simulator-0.12.0 → digsim_logic_simulator-0.13.0}/src/digsim/app/gui_objects/images/Switch_OFF.png +0 -0
- {digsim_logic_simulator-0.12.0 → digsim_logic_simulator-0.13.0}/src/digsim/app/gui_objects/images/Switch_ON.png +0 -0
- {digsim_logic_simulator-0.12.0 → digsim_logic_simulator-0.13.0}/src/digsim/app/gui_objects/images/XNOR.png +0 -0
- {digsim_logic_simulator-0.12.0 → digsim_logic_simulator-0.13.0}/src/digsim/app/gui_objects/images/XOR.png +0 -0
- {digsim_logic_simulator-0.12.0 → digsim_logic_simulator-0.13.0}/src/digsim/app/gui_objects/images/YOSYS.png +0 -0
- {digsim_logic_simulator-0.12.0 → digsim_logic_simulator-0.13.0}/src/digsim/app/gui_objects/images/ZERO.png +0 -0
- {digsim_logic_simulator-0.12.0 → digsim_logic_simulator-0.13.0}/src/digsim/app/images/app_icon.png +0 -0
- {digsim_logic_simulator-0.12.0 → digsim_logic_simulator-0.13.0}/src/digsim/app/model/__init__.py +0 -0
- {digsim_logic_simulator-0.12.0 → digsim_logic_simulator-0.13.0}/src/digsim/app/settings/__init__.py +0 -0
- {digsim_logic_simulator-0.12.0 → digsim_logic_simulator-0.13.0}/src/digsim/app/settings/_gui_settings.py +0 -0
- {digsim_logic_simulator-0.12.0 → digsim_logic_simulator-0.13.0}/src/digsim/circuit/__init__.py +0 -0
- {digsim_logic_simulator-0.12.0 → digsim_logic_simulator-0.13.0}/src/digsim/circuit/_waves_writer.py +0 -0
- {digsim_logic_simulator-0.12.0 → digsim_logic_simulator-0.13.0}/src/digsim/circuit/components/__init__.py +0 -0
- {digsim_logic_simulator-0.12.0 → digsim_logic_simulator-0.13.0}/src/digsim/circuit/components/_bus_bits.py +0 -0
- {digsim_logic_simulator-0.12.0 → digsim_logic_simulator-0.13.0}/src/digsim/circuit/components/_buzzer.py +0 -0
- {digsim_logic_simulator-0.12.0 → digsim_logic_simulator-0.13.0}/src/digsim/circuit/components/_clock.py +0 -0
- {digsim_logic_simulator-0.12.0 → digsim_logic_simulator-0.13.0}/src/digsim/circuit/components/_dip_switch.py +0 -0
- {digsim_logic_simulator-0.12.0 → digsim_logic_simulator-0.13.0}/src/digsim/circuit/components/_flip_flops.py +0 -0
- {digsim_logic_simulator-0.12.0 → digsim_logic_simulator-0.13.0}/src/digsim/circuit/components/_gates.py +0 -0
- {digsim_logic_simulator-0.12.0 → digsim_logic_simulator-0.13.0}/src/digsim/circuit/components/_hexdigit.py +0 -0
- {digsim_logic_simulator-0.12.0 → digsim_logic_simulator-0.13.0}/src/digsim/circuit/components/_ic.py +0 -0
- {digsim_logic_simulator-0.12.0 → digsim_logic_simulator-0.13.0}/src/digsim/circuit/components/_label_wire.py +0 -0
- {digsim_logic_simulator-0.12.0 → digsim_logic_simulator-0.13.0}/src/digsim/circuit/components/_led.py +0 -0
- {digsim_logic_simulator-0.12.0 → digsim_logic_simulator-0.13.0}/src/digsim/circuit/components/_logic_analyzer.py +0 -0
- {digsim_logic_simulator-0.12.0 → digsim_logic_simulator-0.13.0}/src/digsim/circuit/components/_mem64kbyte.py +0 -0
- {digsim_logic_simulator-0.12.0 → digsim_logic_simulator-0.13.0}/src/digsim/circuit/components/_memstdout.py +0 -0
- {digsim_logic_simulator-0.12.0 → digsim_logic_simulator-0.13.0}/src/digsim/circuit/components/_note.py +0 -0
- {digsim_logic_simulator-0.12.0 → digsim_logic_simulator-0.13.0}/src/digsim/circuit/components/_on_off_switch.py +0 -0
- {digsim_logic_simulator-0.12.0 → digsim_logic_simulator-0.13.0}/src/digsim/circuit/components/_seven_segment.py +0 -0
- {digsim_logic_simulator-0.12.0 → digsim_logic_simulator-0.13.0}/src/digsim/circuit/components/_static_level.py +0 -0
- {digsim_logic_simulator-0.12.0 → digsim_logic_simulator-0.13.0}/src/digsim/circuit/components/_static_value.py +0 -0
- {digsim_logic_simulator-0.12.0 → digsim_logic_simulator-0.13.0}/src/digsim/circuit/components/_yosys_atoms.py +0 -0
- {digsim_logic_simulator-0.12.0 → digsim_logic_simulator-0.13.0}/src/digsim/circuit/components/atoms/_digsim_exception.py +0 -0
- {digsim_logic_simulator-0.12.0 → digsim_logic_simulator-0.13.0}/src/digsim/circuit/components/ic/74162.json +0 -0
- {digsim_logic_simulator-0.12.0 → digsim_logic_simulator-0.13.0}/src/digsim/circuit/components/ic/7448.json +0 -0
- {digsim_logic_simulator-0.12.0 → digsim_logic_simulator-0.13.0}/src/digsim/storage_model/__init__.py +0 -0
- {digsim_logic_simulator-0.12.0 → digsim_logic_simulator-0.13.0}/src/digsim/synth/__init__.py +0 -0
- {digsim_logic_simulator-0.12.0 → digsim_logic_simulator-0.13.0}/src/digsim/utils/__init__.py +0 -0
- {digsim_logic_simulator-0.12.0 → digsim_logic_simulator-0.13.0}/src/digsim_logic_simulator.egg-info/SOURCES.txt +0 -0
- {digsim_logic_simulator-0.12.0 → digsim_logic_simulator-0.13.0}/src/digsim_logic_simulator.egg-info/dependency_links.txt +0 -0
- {digsim_logic_simulator-0.12.0 → digsim_logic_simulator-0.13.0}/src/digsim_logic_simulator.egg-info/requires.txt +0 -0
- {digsim_logic_simulator-0.12.0 → digsim_logic_simulator-0.13.0}/src/digsim_logic_simulator.egg-info/top_level.txt +0 -0
- {digsim_logic_simulator-0.12.0 → digsim_logic_simulator-0.13.0}/tests/test_gates.py +0 -0
- {digsim_logic_simulator-0.12.0 → digsim_logic_simulator-0.13.0}/tests/test_yosys_aldff.py +0 -0
- {digsim_logic_simulator-0.12.0 → digsim_logic_simulator-0.13.0}/tests/test_yosys_dff.py +0 -0
- {digsim_logic_simulator-0.12.0 → digsim_logic_simulator-0.13.0}/tests/test_yosys_dlatch.py +0 -0
- {digsim_logic_simulator-0.12.0 → digsim_logic_simulator-0.13.0}/tests/test_yosys_gates.py +0 -0
- {digsim_logic_simulator-0.12.0 → digsim_logic_simulator-0.13.0}/tests/test_yosys_latch.py +0 -0
- {digsim_logic_simulator-0.12.0 → digsim_logic_simulator-0.13.0}/tests/test_yosys_netlist.py +0 -0
- {digsim_logic_simulator-0.12.0 → digsim_logic_simulator-0.13.0}/tests/test_yosys_sdff.py +0 -0
- {digsim_logic_simulator-0.12.0 → digsim_logic_simulator-0.13.0}/tests/test_yosys_sr.py +0 -0
|
@@ -5,7 +5,7 @@ build-backend = "setuptools.build_meta"
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "digsim-logic-simulator"
|
|
7
7
|
description = "Interactive Digital Logic Simulator"
|
|
8
|
-
version = "0.
|
|
8
|
+
version = "0.13.0"
|
|
9
9
|
authors = [{name = "Fredrik Andersson", email = "freand@gmail.com"}]
|
|
10
10
|
maintainers = [{name = "Fredrik Andersson", email = "freand@gmail.com"}]
|
|
11
11
|
readme = "README.md"
|
|
@@ -16,21 +16,25 @@ from digsim.app.model import AppModel
|
|
|
16
16
|
|
|
17
17
|
|
|
18
18
|
if __name__ == "__main__":
|
|
19
|
+
|
|
20
|
+
def _create_app_icon(image_path: Path) -> QIcon:
|
|
21
|
+
image_pixmap = QPixmap(image_path)
|
|
22
|
+
size = max(image_pixmap.size().height(), image_pixmap.size().width())
|
|
23
|
+
icon_pixmap = QPixmap(size, size)
|
|
24
|
+
icon_pixmap.fill(Qt.transparent)
|
|
25
|
+
painter = QPainter(icon_pixmap)
|
|
26
|
+
painter.drawPixmap(
|
|
27
|
+
(icon_pixmap.size().width() - image_pixmap.size().width()) // 2,
|
|
28
|
+
(icon_pixmap.size().height() - image_pixmap.size().height()) // 2,
|
|
29
|
+
image_pixmap,
|
|
30
|
+
)
|
|
31
|
+
painter.end()
|
|
32
|
+
return QIcon(icon_pixmap)
|
|
33
|
+
|
|
19
34
|
app = QApplication(sys.argv)
|
|
20
35
|
main_path = Path(__file__).parent
|
|
21
36
|
image_path = main_path / "images/app_icon.png"
|
|
22
|
-
|
|
23
|
-
size = max(image_pixmap.size().height(), image_pixmap.size().width())
|
|
24
|
-
icon_pixmap = QPixmap(size, size)
|
|
25
|
-
icon_pixmap.fill(Qt.transparent)
|
|
26
|
-
painter = QPainter(icon_pixmap)
|
|
27
|
-
painter.drawPixmap(
|
|
28
|
-
(icon_pixmap.size().width() - image_pixmap.size().width()) // 2,
|
|
29
|
-
(icon_pixmap.size().height() - image_pixmap.size().height()) // 2,
|
|
30
|
-
image_pixmap,
|
|
31
|
-
)
|
|
32
|
-
painter.end()
|
|
33
|
-
icon = QIcon(icon_pixmap)
|
|
37
|
+
icon = _create_app_icon(image_path)
|
|
34
38
|
app.setWindowIcon(icon)
|
|
35
39
|
app_model = AppModel()
|
|
36
40
|
window = MainWindow(app_model)
|
{digsim_logic_simulator-0.12.0 → digsim_logic_simulator-0.13.0}/src/digsim/app/gui/_circuit_area.py
RENAMED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
from functools import partial
|
|
7
7
|
|
|
8
8
|
from PySide6.QtCore import QPoint, QPointF, QRect, QRectF, Qt, QTimer
|
|
9
|
-
from PySide6.QtGui import QBrush, QPainterPath, QPen
|
|
9
|
+
from PySide6.QtGui import QBrush, QColor, QPainterPath, QPen
|
|
10
10
|
from PySide6.QtWidgets import (
|
|
11
11
|
QGraphicsItem,
|
|
12
12
|
QGraphicsPathItem,
|
|
@@ -52,6 +52,19 @@ class WirePartGraphicsItem(QGraphicsRectItem):
|
|
|
52
52
|
self._parent.select(self.isSelected())
|
|
53
53
|
return super().itemChange(change, value)
|
|
54
54
|
|
|
55
|
+
def _get_wire_color(self, port_value, bus_width):
|
|
56
|
+
if port_value == "X":
|
|
57
|
+
return Qt.red
|
|
58
|
+
if port_value == 0:
|
|
59
|
+
return Qt.darkGray
|
|
60
|
+
|
|
61
|
+
max_value = 2**bus_width - 1
|
|
62
|
+
# Start with dark gray
|
|
63
|
+
green = 128
|
|
64
|
+
# Calculate the green component, ranging from 128 to 255
|
|
65
|
+
green += int(127 * port_value / max_value)
|
|
66
|
+
return QColor(128, green, 128)
|
|
67
|
+
|
|
55
68
|
def paint(self, painter, option, widget=None):
|
|
56
69
|
"""QT function"""
|
|
57
70
|
pen = QPen(Qt.darkGray)
|
|
@@ -60,20 +73,13 @@ class WirePartGraphicsItem(QGraphicsRectItem):
|
|
|
60
73
|
pen.setWidth(4)
|
|
61
74
|
else:
|
|
62
75
|
pen.setWidth(2)
|
|
76
|
+
|
|
63
77
|
if not self._app_model.is_running and self._selected:
|
|
64
78
|
pen.setColor(Qt.black)
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
pen.setColor(Qt.red)
|
|
70
|
-
elif port_value != 0:
|
|
71
|
-
max_value = 2**bus_width - 1
|
|
72
|
-
color = pen.color()
|
|
73
|
-
green = color.green()
|
|
74
|
-
full_range = 255 - green
|
|
75
|
-
color.setGreen(green + (full_range * port_value / max_value))
|
|
76
|
-
pen.setColor(color)
|
|
79
|
+
elif self._app_model.settings.get("color_wires"):
|
|
80
|
+
port_value = self._src_port.value
|
|
81
|
+
pen.setColor(self._get_wire_color(port_value, bus_width))
|
|
82
|
+
|
|
77
83
|
painter.setPen(pen)
|
|
78
84
|
painter.drawLine(self._start, self._end)
|
|
79
85
|
|
|
@@ -82,6 +88,7 @@ class WireGraphicsItem(QGraphicsPathItem):
|
|
|
82
88
|
"""A wire graphics item"""
|
|
83
89
|
|
|
84
90
|
WIRE_TO_COMPONENT_DIST = 5
|
|
91
|
+
X_OFFSET = 10
|
|
85
92
|
|
|
86
93
|
def __init__(self, app_model, connection, src_port_item, dst_port_item):
|
|
87
94
|
super().__init__()
|
|
@@ -116,14 +123,14 @@ class WireGraphicsItem(QGraphicsPathItem):
|
|
|
116
123
|
def create_points(cls, source, dest, rect):
|
|
117
124
|
"""Create a wire path"""
|
|
118
125
|
points = []
|
|
119
|
-
|
|
120
126
|
points.append(source)
|
|
127
|
+
|
|
121
128
|
if source.x() < dest.x():
|
|
122
129
|
half_dist_x = (dest.x() - source.x()) / 2
|
|
123
130
|
points.append(QPointF(source.x() + half_dist_x, source.y()))
|
|
124
131
|
points.append(QPointF(source.x() + half_dist_x, dest.y()))
|
|
125
132
|
else:
|
|
126
|
-
half_dist_y =
|
|
133
|
+
half_dist_y = (source.y() + dest.y()) / 2
|
|
127
134
|
if dest.y() < source.y():
|
|
128
135
|
comp_top = rect.y() - cls.WIRE_TO_COMPONENT_DIST
|
|
129
136
|
y_mid = min(comp_top, half_dist_y)
|
|
@@ -131,10 +138,11 @@ class WireGraphicsItem(QGraphicsPathItem):
|
|
|
131
138
|
comp_bottom = rect.y() + rect.height() + cls.WIRE_TO_COMPONENT_DIST
|
|
132
139
|
y_mid = max(comp_bottom, half_dist_y)
|
|
133
140
|
|
|
134
|
-
points.append(QPointF(source.x() +
|
|
135
|
-
points.append(QPointF(source.x() +
|
|
136
|
-
points.append(QPointF(dest.x() -
|
|
137
|
-
points.append(QPointF(dest.x() -
|
|
141
|
+
points.append(QPointF(source.x() + cls.X_OFFSET, source.y()))
|
|
142
|
+
points.append(QPointF(source.x() + cls.X_OFFSET, y_mid))
|
|
143
|
+
points.append(QPointF(dest.x() - cls.X_OFFSET, y_mid))
|
|
144
|
+
points.append(QPointF(dest.x() - cls.X_OFFSET, dest.y()))
|
|
145
|
+
|
|
138
146
|
points.append(dest)
|
|
139
147
|
return points
|
|
140
148
|
|
|
@@ -315,6 +323,9 @@ class _CircuitAreaScene(QGraphicsScene):
|
|
|
315
323
|
class CircuitArea(QGraphicsView):
|
|
316
324
|
"""The circuit area graphics view"""
|
|
317
325
|
|
|
326
|
+
ZOOM_IN_FACTOR = 1.25
|
|
327
|
+
ZOOM_OUT_FACTOR = 0.8
|
|
328
|
+
|
|
318
329
|
def __init__(self, app_model, parent):
|
|
319
330
|
super().__init__(parent=parent)
|
|
320
331
|
self._app_model = app_model
|
|
@@ -333,10 +344,10 @@ class CircuitArea(QGraphicsView):
|
|
|
333
344
|
return len(self._scene.selectedItems()) > 0
|
|
334
345
|
|
|
335
346
|
def _zoom_in(self):
|
|
336
|
-
self.scale(
|
|
347
|
+
self.scale(self.ZOOM_IN_FACTOR, self.ZOOM_IN_FACTOR)
|
|
337
348
|
|
|
338
349
|
def _zoom_out(self):
|
|
339
|
-
self.scale(
|
|
350
|
+
self.scale(self.ZOOM_OUT_FACTOR, self.ZOOM_OUT_FACTOR)
|
|
340
351
|
|
|
341
352
|
def _repaint(self):
|
|
342
353
|
"""Make scene repaint for component update"""
|
|
@@ -40,6 +40,8 @@ class SelectableComponentWidget(QPushButton):
|
|
|
40
40
|
mime.setText(self._name)
|
|
41
41
|
drag.setMimeData(mime)
|
|
42
42
|
drag.setHotSpot(event.pos() - self.rect().topLeft())
|
|
43
|
+
# Create a square pixmap for dragging, using the widget's width for both dimensions.
|
|
44
|
+
# This is intentional to maintain a consistent visual representation during drag operations.
|
|
43
45
|
pixmap = QPixmap(self.size().width(), self.size().width())
|
|
44
46
|
self.render(pixmap)
|
|
45
47
|
drag.setPixmap(pixmap)
|
|
@@ -87,11 +87,11 @@ class BuzzerObject(ImageObjectWithActiveRect):
|
|
|
87
87
|
if self.device is None:
|
|
88
88
|
return
|
|
89
89
|
if active:
|
|
90
|
-
self.audio_sink
|
|
91
|
-
|
|
90
|
+
if self.audio_sink is None:
|
|
91
|
+
self.audio_sink = QAudioSink(self.device, self.audio_format)
|
|
92
|
+
self.audio_sink.setVolume(0.1)
|
|
92
93
|
self.audio_sink.start(self.audio_output)
|
|
93
94
|
else:
|
|
94
|
-
if self.audio_sink is None:
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
self.audio_sink = None
|
|
95
|
+
if self.audio_sink is not None:
|
|
96
|
+
self.audio_sink.stop()
|
|
97
|
+
self.audio_sink = None
|
|
@@ -18,7 +18,7 @@ class ComponentContextMenu(QMenu):
|
|
|
18
18
|
self._app_model = app_model
|
|
19
19
|
self._component_object = component_object
|
|
20
20
|
self._component = self._component_object.component
|
|
21
|
-
self._reconfigurable_parameters =
|
|
21
|
+
self._reconfigurable_parameters = {}
|
|
22
22
|
# Title
|
|
23
23
|
titleAction = QAction(self._component.display_name(), self)
|
|
24
24
|
titleAction.setEnabled(False)
|
|
@@ -25,6 +25,10 @@ class ComponentObject(QGraphicsRectItem):
|
|
|
25
25
|
PORT_SIDE = 8
|
|
26
26
|
DEFAULT_PORT_TO_PORT_DISTANCE = 20
|
|
27
27
|
|
|
28
|
+
_COMPONENT_NAME_FONT = QFont("Arial", 10)
|
|
29
|
+
_PORT_NAME_FONT = QFont("Arial", 8)
|
|
30
|
+
_SELECTABLE_COMPONENT_NAME_FONT = QFont("Arial", 8)
|
|
31
|
+
|
|
28
32
|
def __init__(
|
|
29
33
|
self, app_model, component, xpos, ypos, port_distance=DEFAULT_PORT_TO_PORT_DISTANCE
|
|
30
34
|
):
|
|
@@ -237,9 +241,8 @@ class ComponentObject(QGraphicsRectItem):
|
|
|
237
241
|
|
|
238
242
|
def paint_component_name(self, painter):
|
|
239
243
|
"""Paint the component name"""
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
fm = QFontMetrics(font)
|
|
244
|
+
painter.setFont(self._COMPONENT_NAME_FONT)
|
|
245
|
+
fm = QFontMetrics(self._COMPONENT_NAME_FONT)
|
|
243
246
|
display_name_str = self._component.display_name()
|
|
244
247
|
str_pixels_w = fm.horizontalAdvance(display_name_str)
|
|
245
248
|
str_pixels_h = fm.height()
|
|
@@ -278,11 +281,10 @@ class ComponentObject(QGraphicsRectItem):
|
|
|
278
281
|
@classmethod
|
|
279
282
|
def paint_selectable_component_name(cls, painter, point, size, name):
|
|
280
283
|
"""Paint the name for the selectable component"""
|
|
281
|
-
|
|
282
|
-
fm = QFontMetrics(
|
|
284
|
+
painter.setFont(cls._SELECTABLE_COMPONENT_NAME_FONT)
|
|
285
|
+
fm = QFontMetrics(cls._SELECTABLE_COMPONENT_NAME_FONT)
|
|
283
286
|
str_pixels_w = fm.horizontalAdvance(name)
|
|
284
287
|
str_pixels_h = fm.height()
|
|
285
|
-
painter.setFont(font)
|
|
286
288
|
painter.setPen(Qt.black)
|
|
287
289
|
painter.drawText(
|
|
288
290
|
point.x() + size.width() / 2 - str_pixels_w / 2,
|
|
@@ -297,12 +299,11 @@ class ComponentObject(QGraphicsRectItem):
|
|
|
297
299
|
def paint_portnames(self, painter, color=Qt.black):
|
|
298
300
|
"""Paint component ports"""
|
|
299
301
|
painter.setPen(color)
|
|
300
|
-
|
|
301
|
-
painter.setFont(font)
|
|
302
|
+
painter.setFont(self._PORT_NAME_FONT)
|
|
302
303
|
for port in self._component.ports:
|
|
303
304
|
rect = self.get_port_item(port).rect()
|
|
304
305
|
port_str = self._port_dict[port]["name"]
|
|
305
|
-
str_pixels_w, str_pixels_h = self.get_string_metrics(port_str,
|
|
306
|
+
str_pixels_w, str_pixels_h = self.get_string_metrics(port_str, self._PORT_NAME_FONT)
|
|
306
307
|
text_y = rect.y() + str_pixels_h - self.PORT_SIDE / 2
|
|
307
308
|
if rect.x() < self.object_pos.x():
|
|
308
309
|
text_pos = QPoint(rect.x() + self.inport_x_pos(), text_y)
|
|
@@ -44,7 +44,6 @@ class PortGraphicsItem(QGraphicsRectItem):
|
|
|
44
44
|
return
|
|
45
45
|
self.setBrush(QBrush(Qt.black))
|
|
46
46
|
self.setCursor(Qt.CrossCursor)
|
|
47
|
-
self._repaint()
|
|
48
47
|
|
|
49
48
|
def hoverLeaveEvent(self, _):
|
|
50
49
|
"""QT event callback function"""
|
|
@@ -52,7 +51,6 @@ class PortGraphicsItem(QGraphicsRectItem):
|
|
|
52
51
|
return
|
|
53
52
|
self.setBrush(QBrush(Qt.gray))
|
|
54
53
|
self.setCursor(Qt.ArrowCursor)
|
|
55
|
-
self._repaint()
|
|
56
54
|
|
|
57
55
|
def portParentRect(self):
|
|
58
56
|
"""return the parent rect"""
|
|
@@ -16,6 +16,8 @@ class DipSwitchObject(ImageObject):
|
|
|
16
16
|
DIP_SWITCH_WIDTH = 20
|
|
17
17
|
DIP_SWITCH_HEIGHT = 10
|
|
18
18
|
|
|
19
|
+
_DIP_SWITCH_FONT = QFont("Arial", 8)
|
|
20
|
+
|
|
19
21
|
def __init__(self, app_model, component, xpos, ypos):
|
|
20
22
|
super().__init__(app_model, component, xpos, ypos, port_distance=self.DIP_SWITCH_HEIGHT)
|
|
21
23
|
self.width = 2.5 * self.DIP_SWITCH_WIDTH
|
|
@@ -77,17 +79,16 @@ class DipSwitchObject(ImageObject):
|
|
|
77
79
|
painter.drawRect(
|
|
78
80
|
rect.x() + 1, rect.y() + 1, rect.width() / 2 - 2, rect.height() - 2
|
|
79
81
|
)
|
|
80
|
-
|
|
81
|
-
painter.setFont(font)
|
|
82
|
+
painter.setFont(self._DIP_SWITCH_FONT)
|
|
82
83
|
painter.setPen(Qt.white)
|
|
83
84
|
for idx, rect in enumerate(self._rects):
|
|
84
85
|
port_str = f"{idx + 1}"
|
|
85
|
-
str_pixels_w, _ = self.get_string_metrics(port_str,
|
|
86
|
+
str_pixels_w, _ = self.get_string_metrics(port_str, self._DIP_SWITCH_FONT)
|
|
86
87
|
painter.drawText(
|
|
87
88
|
QPoint(rect.x() - str_pixels_w - 4, rect.y() + rect.height() - 1), port_str
|
|
88
89
|
)
|
|
89
90
|
|
|
90
|
-
_, str_h = self.get_string_metrics("ON",
|
|
91
|
+
_, str_h = self.get_string_metrics("ON", self._DIP_SWITCH_FONT)
|
|
91
92
|
painter.drawText(
|
|
92
93
|
self.rect().x() + self.rect().width() / 2,
|
|
93
94
|
self.rect().y() + self.BORDER_TO_PORT - str_h,
|
|
@@ -16,16 +16,18 @@ class GuiNoteObject(ComponentObject):
|
|
|
16
16
|
NOTE_MINIMUM_WIDTH = 50
|
|
17
17
|
NOTE_MINIMUM_HEIGHT = 20
|
|
18
18
|
|
|
19
|
+
_NOTE_FONT = QFont("Arial", 8)
|
|
20
|
+
_NOTE_PEN = QPen(Qt.black)
|
|
21
|
+
|
|
19
22
|
def __init__(self, app_model, component, xpos, ypos):
|
|
20
23
|
super().__init__(app_model, component, xpos, ypos)
|
|
21
|
-
self._font = QFont("Arial", 8)
|
|
22
24
|
self.update_size()
|
|
23
25
|
|
|
24
26
|
def _get_lines(self):
|
|
25
27
|
return self.component.parameter_get("text").split("\n")
|
|
26
28
|
|
|
27
29
|
def update_size(self):
|
|
28
|
-
fm = QFontMetrics(self.
|
|
30
|
+
fm = QFontMetrics(self._NOTE_FONT)
|
|
29
31
|
width = self.NOTE_MINIMUM_WIDTH
|
|
30
32
|
lines = self._get_lines()
|
|
31
33
|
for line in lines:
|
|
@@ -39,19 +41,18 @@ class GuiNoteObject(ComponentObject):
|
|
|
39
41
|
|
|
40
42
|
def paint_component(self, painter):
|
|
41
43
|
"""Paint note rectangle"""
|
|
42
|
-
fm = QFontMetrics(self.
|
|
44
|
+
fm = QFontMetrics(self._NOTE_FONT)
|
|
43
45
|
lines = self._get_lines()
|
|
44
|
-
pen =
|
|
46
|
+
pen = self._NOTE_PEN
|
|
45
47
|
if self.selected:
|
|
46
48
|
pen.setWidth(4)
|
|
47
49
|
else:
|
|
48
50
|
pen.setWidth(1)
|
|
49
|
-
pen.setColor(Qt.black)
|
|
50
51
|
painter.setPen(pen)
|
|
51
52
|
painter.setBrush(Qt.SolidPattern)
|
|
52
53
|
painter.setBrush(Qt.yellow)
|
|
53
54
|
painter.drawRect(self.rect())
|
|
54
|
-
painter.setFont(self.
|
|
55
|
+
painter.setFont(self._NOTE_FONT)
|
|
55
56
|
for idx, line in enumerate(lines):
|
|
56
57
|
painter.drawText(
|
|
57
58
|
self.object_pos.x() + self.NOTE_BORDER,
|
|
@@ -67,15 +68,13 @@ class GuiNoteObject(ComponentObject):
|
|
|
67
68
|
size.width() - 2 * cls.NOTE_BORDER,
|
|
68
69
|
size.width() - 2 * cls.NOTE_BORDER,
|
|
69
70
|
)
|
|
70
|
-
pen =
|
|
71
|
+
pen = cls._NOTE_PEN
|
|
71
72
|
pen.setWidth(1)
|
|
72
|
-
pen.setColor(Qt.black)
|
|
73
73
|
painter.setPen(pen)
|
|
74
74
|
painter.setBrush(Qt.SolidPattern)
|
|
75
75
|
painter.setBrush(Qt.yellow)
|
|
76
76
|
painter.drawRect(note_rect)
|
|
77
|
-
|
|
78
|
-
fm = QFontMetrics(
|
|
79
|
-
painter.setFont(font)
|
|
77
|
+
painter.setFont(cls._NOTE_FONT)
|
|
78
|
+
fm = QFontMetrics(cls._NOTE_FONT)
|
|
80
79
|
painter.drawText(2 * cls.NOTE_BORDER, 2 * cls.NOTE_BORDER + fm.height(), "abc..")
|
|
81
80
|
cls.paint_selectable_component_name(painter, QPoint(0, 0), size, name)
|
|
@@ -70,7 +70,7 @@ CLASS_NAME_TO_COMPONENT_OBJECT = {
|
|
|
70
70
|
}
|
|
71
71
|
|
|
72
72
|
|
|
73
|
-
def
|
|
73
|
+
def class_factory(component_class_name):
|
|
74
74
|
"""A function that returns the GUI for a component class (str or class)"""
|
|
75
75
|
|
|
76
76
|
if component_class_name in CLASS_NAME_TO_COMPONENT_OBJECT:
|
|
@@ -165,6 +165,8 @@ class ImageObjectStaticValue(ImageObject):
|
|
|
165
165
|
IMAGE_FILENAME = "images/ZERO.png"
|
|
166
166
|
ACTIVE_IMAGE_FILENAME = "images/ONE.png"
|
|
167
167
|
|
|
168
|
+
_STATIC_VALUE_FONT = QFont("Arial", 16)
|
|
169
|
+
|
|
168
170
|
def __init__(self, app_model, component, xpos, ypos):
|
|
169
171
|
super().__init__(app_model, component, xpos, ypos)
|
|
170
172
|
self.show_name(False)
|
|
@@ -174,10 +176,9 @@ class ImageObjectStaticValue(ImageObject):
|
|
|
174
176
|
super().paint_component(painter)
|
|
175
177
|
else:
|
|
176
178
|
self.paint_component_base(painter)
|
|
177
|
-
font = QFont("Arial", 16)
|
|
178
179
|
value_str = f"{self.component.parameter_get('value')}"
|
|
179
|
-
str_w, str_h = self.get_string_metrics(value_str, font=
|
|
180
|
-
painter.setFont(
|
|
180
|
+
str_w, str_h = self.get_string_metrics(value_str, font=self._STATIC_VALUE_FONT)
|
|
181
|
+
painter.setFont(self._STATIC_VALUE_FONT)
|
|
181
182
|
painter.drawText(
|
|
182
183
|
self.rect().x() + self.rect().width() / 2 - str_w / 2,
|
|
183
184
|
self.rect().y() + str_h,
|
|
@@ -213,6 +214,8 @@ class ImageObjectWithActiveRect(ImageObject):
|
|
|
213
214
|
When active the image will have a green border painted around it.
|
|
214
215
|
"""
|
|
215
216
|
|
|
217
|
+
_ACTIVE_RECT_PEN = QPen(Qt.green)
|
|
218
|
+
|
|
216
219
|
def __init__(self, app_model, component, xpos, ypos):
|
|
217
220
|
super().__init__(app_model, component, xpos, ypos)
|
|
218
221
|
self.show_name(False)
|
|
@@ -223,9 +226,8 @@ class ImageObjectWithActiveRect(ImageObject):
|
|
|
223
226
|
if self.component.active:
|
|
224
227
|
xpos = self.object_pos.x() + self.size.width() / 2 - self._pixmap.width() / 2
|
|
225
228
|
ypos = self.object_pos.y() + self.size.height() / 2 - self._pixmap.height() / 2
|
|
226
|
-
pen =
|
|
229
|
+
pen = self._ACTIVE_RECT_PEN
|
|
227
230
|
pen.setWidth(4)
|
|
228
|
-
pen.setColor(Qt.green)
|
|
229
231
|
painter.setPen(pen)
|
|
230
232
|
painter.setBrush(Qt.NoBrush)
|
|
231
233
|
painter.drawRoundedRect(xpos, ypos, self._pixmap.width(), self._pixmap.height(), 5, 5)
|
|
@@ -12,6 +12,8 @@ from ._component_object import ComponentObject
|
|
|
12
12
|
class LabelObject(ComponentObject):
|
|
13
13
|
"""The class for a bus/bit component placed in the GUI"""
|
|
14
14
|
|
|
15
|
+
_LABEL_PEN = QPen(Qt.black)
|
|
16
|
+
|
|
15
17
|
def __init__(self, app_model, component, xpos, ypos):
|
|
16
18
|
super().__init__(app_model, component, xpos, ypos)
|
|
17
19
|
label = component.label()
|
|
@@ -35,12 +37,11 @@ class LabelObject(ComponentObject):
|
|
|
35
37
|
|
|
36
38
|
@classmethod
|
|
37
39
|
def _paint_label(cls, painter, comp_rect, name, selected=False):
|
|
38
|
-
pen =
|
|
40
|
+
pen = cls._LABEL_PEN
|
|
39
41
|
if selected:
|
|
40
42
|
pen.setWidth(4)
|
|
41
43
|
else:
|
|
42
44
|
pen.setWidth(1)
|
|
43
|
-
pen.setColor(Qt.black)
|
|
44
45
|
painter.setPen(pen)
|
|
45
46
|
painter.setBrush(Qt.SolidPattern)
|
|
46
47
|
painter.setBrush(Qt.gray)
|
|
@@ -17,6 +17,10 @@ class LogicAnalyzerObject(ImageObject):
|
|
|
17
17
|
SIGNAL_NAME_WIDTH = 40
|
|
18
18
|
ANALYZER_DISPLAY_WIDTH = 200
|
|
19
19
|
|
|
20
|
+
_ANALYZER_PEN = QPen(Qt.green)
|
|
21
|
+
_SIGNAL_VERTICAL_SCALE = 10
|
|
22
|
+
_SIGNAL_HORIZONTAL_SCALE = 2
|
|
23
|
+
|
|
20
24
|
def __init__(self, app_model, component, xpos, ypos):
|
|
21
25
|
super().__init__(app_model, component, xpos, ypos)
|
|
22
26
|
self.width = self.SIGNAL_NAME_WIDTH + self.ANALYZER_DISPLAY_WIDTH + 2 * self.RECT_TO_BORDER
|
|
@@ -37,8 +41,7 @@ class LogicAnalyzerObject(ImageObject):
|
|
|
37
41
|
5,
|
|
38
42
|
)
|
|
39
43
|
|
|
40
|
-
pen =
|
|
41
|
-
pen.setColor(Qt.green)
|
|
44
|
+
pen = self._ANALYZER_PEN
|
|
42
45
|
pen.setWidth(2)
|
|
43
46
|
painter.setPen(pen)
|
|
44
47
|
signal_data_dict = self.component.signal_data()
|
|
@@ -48,7 +51,7 @@ class LogicAnalyzerObject(ImageObject):
|
|
|
48
51
|
path = QPainterPath(
|
|
49
52
|
QPoint(
|
|
50
53
|
self.object_pos.x() + self.SIGNAL_NAME_WIDTH,
|
|
51
|
-
port_pos.y() - signal_data[0] *
|
|
54
|
+
port_pos.y() - signal_data[0] * self._SIGNAL_VERTICAL_SCALE,
|
|
52
55
|
)
|
|
53
56
|
)
|
|
54
57
|
last_level = signal_data[0]
|
|
@@ -57,21 +60,27 @@ class LogicAnalyzerObject(ImageObject):
|
|
|
57
60
|
continue
|
|
58
61
|
path.lineTo(
|
|
59
62
|
QPoint(
|
|
60
|
-
self.object_pos.x()
|
|
61
|
-
|
|
63
|
+
self.object_pos.x()
|
|
64
|
+
+ self.SIGNAL_NAME_WIDTH
|
|
65
|
+
+ (idx + 1) * self._SIGNAL_HORIZONTAL_SCALE,
|
|
66
|
+
port_pos.y() - last_level * self._SIGNAL_VERTICAL_SCALE,
|
|
62
67
|
)
|
|
63
68
|
)
|
|
64
69
|
path.lineTo(
|
|
65
70
|
QPoint(
|
|
66
|
-
self.object_pos.x()
|
|
67
|
-
|
|
71
|
+
self.object_pos.x()
|
|
72
|
+
+ self.SIGNAL_NAME_WIDTH
|
|
73
|
+
+ (idx + 1) * self._SIGNAL_HORIZONTAL_SCALE,
|
|
74
|
+
port_pos.y() - level * self._SIGNAL_VERTICAL_SCALE,
|
|
68
75
|
)
|
|
69
76
|
)
|
|
70
77
|
last_level = level
|
|
71
78
|
path.lineTo(
|
|
72
79
|
QPoint(
|
|
73
|
-
self.object_pos.x()
|
|
74
|
-
|
|
80
|
+
self.object_pos.x()
|
|
81
|
+
+ self.SIGNAL_NAME_WIDTH
|
|
82
|
+
+ len(signal_data) * self._SIGNAL_HORIZONTAL_SCALE,
|
|
83
|
+
port_pos.y() - last_level * self._SIGNAL_VERTICAL_SCALE,
|
|
75
84
|
)
|
|
76
85
|
)
|
|
77
86
|
painter.drawPath(path)
|
|
@@ -47,6 +47,10 @@ class SevenSegmentObject(ComponentObject):
|
|
|
47
47
|
DIGIT_WIDTH = 54
|
|
48
48
|
DIGIT_HEIGHT = 80
|
|
49
49
|
|
|
50
|
+
DOT_OFFSET_X = 40
|
|
51
|
+
DOT_OFFSET_Y = 60
|
|
52
|
+
DOT_RADIUS = 3
|
|
53
|
+
|
|
50
54
|
def __init__(self, app_model, component, xpos, ypos, port_distance=10):
|
|
51
55
|
super().__init__(app_model, component, xpos, ypos, port_distance=port_distance)
|
|
52
56
|
self.setup_size()
|
|
@@ -89,7 +93,6 @@ class SevenSegmentObject(ComponentObject):
|
|
|
89
93
|
"""Paint the digit background"""
|
|
90
94
|
painter.setBrush(Qt.SolidPattern)
|
|
91
95
|
painter.setPen(Qt.black)
|
|
92
|
-
painter.setBrush(Qt.black)
|
|
93
96
|
painter.drawRoundedRect(xpos, ypos, cls.DIGIT_WIDTH * digits, cls.DIGIT_HEIGHT, 4, 4)
|
|
94
97
|
|
|
95
98
|
@classmethod
|
|
@@ -114,11 +117,15 @@ class SevenSegmentObject(ComponentObject):
|
|
|
114
117
|
path.closeSubpath()
|
|
115
118
|
painter.drawPath(path)
|
|
116
119
|
|
|
120
|
+
DOT_OFFSET_X = 40
|
|
121
|
+
DOT_OFFSET_Y = 60
|
|
122
|
+
DOT_RADIUS = 3
|
|
123
|
+
|
|
117
124
|
if "." in active_segments:
|
|
118
125
|
painter.setPen(Qt.red)
|
|
119
126
|
painter.setBrush(Qt.red)
|
|
120
127
|
else:
|
|
121
128
|
painter.setPen(Qt.darkRed)
|
|
122
129
|
painter.setBrush(Qt.darkRed)
|
|
123
|
-
dotPoint = QPoint(
|
|
124
|
-
painter.drawEllipse(dotPoint,
|
|
130
|
+
dotPoint = QPoint(DOT_OFFSET_X, DOT_OFFSET_Y) + start_point
|
|
131
|
+
painter.drawEllipse(dotPoint, DOT_RADIUS, DOT_RADIUS)
|
|
@@ -37,6 +37,8 @@ class ButtonObject(ImageObject):
|
|
|
37
37
|
IMAGE_FILENAME = "images/PB.png"
|
|
38
38
|
BUTTON_RADIUS = 35
|
|
39
39
|
|
|
40
|
+
_BUTTON_ACTIVE_PEN = QPen(Qt.green)
|
|
41
|
+
|
|
40
42
|
def __init__(self, app_model, component, xpos, ypos):
|
|
41
43
|
super().__init__(app_model, component, xpos, ypos)
|
|
42
44
|
self.show_name(False)
|
|
@@ -45,9 +47,8 @@ class ButtonObject(ImageObject):
|
|
|
45
47
|
def paint_component(self, painter):
|
|
46
48
|
super().paint_component(painter)
|
|
47
49
|
if self.component.active:
|
|
48
|
-
pen =
|
|
50
|
+
pen = self._BUTTON_ACTIVE_PEN
|
|
49
51
|
pen.setWidth(4)
|
|
50
|
-
pen.setColor(Qt.green)
|
|
51
52
|
painter.setPen(pen)
|
|
52
53
|
painter.setBrush(Qt.NoBrush)
|
|
53
54
|
painter.drawEllipse(
|
{digsim_logic_simulator-0.12.0 → digsim_logic_simulator-0.13.0}/src/digsim/app/model/_model.py
RENAMED
|
@@ -37,15 +37,18 @@ class AppModel(QThread):
|
|
|
37
37
|
|
|
38
38
|
def __init__(self):
|
|
39
39
|
super().__init__()
|
|
40
|
-
self.
|
|
41
|
-
self._model_shortcuts = ModelShortcuts(self)
|
|
42
|
-
self._model_settings = ModelSettings(self)
|
|
40
|
+
self._setup_model_components()
|
|
43
41
|
self._started = False
|
|
44
42
|
self._single_step = False
|
|
45
43
|
self._changed = False
|
|
46
44
|
self._gui_event_queue = queue.Queue()
|
|
47
45
|
self._multi_select = False
|
|
48
46
|
|
|
47
|
+
def _setup_model_components(self):
|
|
48
|
+
self._model_objects = ModelObjects(self)
|
|
49
|
+
self._model_shortcuts = ModelShortcuts(self)
|
|
50
|
+
self._model_settings = ModelSettings(self)
|
|
51
|
+
|
|
49
52
|
@property
|
|
50
53
|
def objects(self):
|
|
51
54
|
"""return the model objects"""
|
|
@@ -100,6 +103,7 @@ class AppModel(QThread):
|
|
|
100
103
|
def model_stop(self):
|
|
101
104
|
"""Stop model simulation thread"""
|
|
102
105
|
self._started = False
|
|
106
|
+
self.wait()
|
|
103
107
|
|
|
104
108
|
def model_reset(self):
|
|
105
109
|
"""Reset model simulation"""
|
|
@@ -125,10 +125,7 @@ class ModelComponents:
|
|
|
125
125
|
|
|
126
126
|
def get_object_list(self):
|
|
127
127
|
"""Get list of component objects"""
|
|
128
|
-
|
|
129
|
-
for _, comp in self._component_objects.items():
|
|
130
|
-
component_objects.append(comp)
|
|
131
|
-
return component_objects
|
|
128
|
+
return list(self._component_objects.values())
|
|
132
129
|
|
|
133
130
|
def update_settings(self, component_object, settings):
|
|
134
131
|
"""Update settings for a component"""
|
|
@@ -29,11 +29,12 @@ class NewWire:
|
|
|
29
29
|
|
|
30
30
|
def end(self, component, portname):
|
|
31
31
|
"""End new wire object"""
|
|
32
|
-
self._app_model.objects.push_undo_state()
|
|
33
32
|
end_port = component.port(portname)
|
|
34
33
|
if self._start_port.is_output() and end_port.is_input():
|
|
34
|
+
self._app_model.objects.push_undo_state()
|
|
35
35
|
self._start_port.wire = end_port
|
|
36
36
|
elif self._start_port.is_input() and end_port.is_output():
|
|
37
|
+
self._app_model.objects.push_undo_state()
|
|
37
38
|
end_port.wire = self._start_port
|
|
38
39
|
else:
|
|
39
40
|
raise PortConnectionError("Cannot connect to port of same type")
|
|
@@ -53,11 +53,7 @@ class ModelObjects:
|
|
|
53
53
|
|
|
54
54
|
def get_selected(self):
|
|
55
55
|
"""Get selected objects"""
|
|
56
|
-
|
|
57
|
-
for obj in self.get_list():
|
|
58
|
-
if obj.selected:
|
|
59
|
-
objects.append(obj)
|
|
60
|
-
return objects
|
|
56
|
+
return [obj for obj in self.get_list() if obj.selected]
|
|
61
57
|
|
|
62
58
|
def _delete(self, selected_objects):
|
|
63
59
|
for obj in selected_objects:
|