diff --git a/src/simudator/gui/cpu_graphics_scene.py b/src/simudator/gui/cpu_graphics_scene.py index 748870b4b8a9b060bdb02d9046f53d68b9147759..ea484092e2dc539f4212809db9905652c4736316 100644 --- a/src/simudator/gui/cpu_graphics_scene.py +++ b/src/simudator/gui/cpu_graphics_scene.py @@ -87,6 +87,7 @@ class CpuGraphicsScene(QGraphicsScene): port_1.toggled.connect(signal_w.toggleVisibility) port_2.toggled.connect(signal_w.toggleVisibility) + def getModulesGraphicsItems(self) -> list[ModuleGraphicsItem]: return list(self.module_graphics_items.values()) @@ -97,7 +98,8 @@ class CpuGraphicsScene(QGraphicsScene): return self.signal_graphics_items def mousePressEvent(self, event): - super().mousePressEvent(event) + event.ignore() + # super().mousePressEvent(event) def load_layout_from_file(self, file_path: str) -> None: file = open(file_path) diff --git a/src/simudator/gui/gui.py b/src/simudator/gui/gui.py index ffb693716a845678c2eb9eff5270c6deea1139ee..5fc96325cd93bbd42a2ce437d8c8b9ffb331ed0c 100644 --- a/src/simudator/gui/gui.py +++ b/src/simudator/gui/gui.py @@ -3,7 +3,7 @@ import json import sys from json import JSONDecodeError -from PyQt5 import QtCore +from PyQt5 import QtCore, QtWidgets from PyQt5.QtCore import QPointF, pyqtSignal, pyqtSlot from PyQt5.QtWidgets import ( QAction, @@ -34,6 +34,56 @@ from simudator.gui.run_continuously_thread import RunThread from simudator.gui.signal_graphics_item import SignalGraphicsItem +class View(QGraphicsView): + """ + This class views all QGraphicsItems for the user. It takes the + QGraphicsScene as input and inherits all funcitonality from the + QGraphicsView and overrides the wheelEvent function. + This allows the users to navigate the view with their trackpads + and zoom in/out with their trackpads + ctrl. + """ + def __init__(self, QGraphicsScene): + super().__init__(QGraphicsScene) + self.scene = QGraphicsScene + + def wheelEvent(self, event): + """ + Default behaviour if ctrl is not pressed, otherwise zoom in/out. + """ + modifiers = QtWidgets.QApplication.keyboardModifiers() + if modifiers == QtCore.Qt.ControlModifier: + + # Factor above 1 zooms in, below zooms out + factor = 1.03 + if event.angleDelta().y() < 0: + factor = 0.97 + + # If event got triggered due to the x axis, do nothing + if event.pixelDelta().x() != 0: + return + + view_pos = event.globalPosition() + scene_pos = self.mapToScene( + int(view_pos.x()), + int(view_pos.y()) + ) + + self.centerOn(scene_pos) + self.scale(factor, factor) + + old_mapToScene = self.mapToScene(int(view_pos.x()), int(view_pos.y())) + new_mapToScene = self.mapToScene(self.viewport().rect().center()) + + delta = old_mapToScene - new_mapToScene + + self.centerOn(scene_pos - delta) + + else: + + # Default behaviour + super().wheelEvent(event) + + class GUI(QMainWindow): """ This is the main class for the GUI. It handles creating the widnow for @@ -53,7 +103,7 @@ class GUI(QMainWindow): self.setWindowTitle("SimuDator") self.cpu_graphics_scene = CpuGraphicsScene(cpu) - self.graphics_view = QGraphicsView(self.cpu_graphics_scene) + self.graphics_view = View(self.cpu_graphics_scene) #self.graphics_view.setDragMode(True) self.moduleActions: dict[str, QAction] = {} @@ -88,6 +138,47 @@ class GUI(QMainWindow): #"QGraphicsItem { background-color: blue }") #self.setStyleSheet("background-color: yellow") + def abc(self, event): + """ + Zoom in/out while scrolling in the upper/lower + edge of the view. Ignores scrolls in the horizontal plane. + """ + print(123) + + # Only zoom when ctrl is pressed + modifiers = QtWidgets.QApplication.keyboardModifiers() + if modifiers == QtCore.Qt.ControlModifier: + + # Factor above 1 zooms in, below zooms out + factor = 1.02 + if event.pixelDelta().y() < 0: + factor = 0.98 + + # If event got triggered due to the x axis, do nothing + if event.pixelDelta().x() != 0: + return + + view_pos = event.globalPosition() + scene_pos = self.graphics_view.mapToScene( + int(view_pos.x()), + int(view_pos.y()) + ) + + self.graphics_view.centerOn(scene_pos) + self.graphics_view.scale(factor, factor) + + old_pos = self.graphics_view.mapToScene( + int(view_pos.x()), + int(view_pos.y()) + ) + new_pos = self.graphics_view.mapToScene( + self.graphics_view.viewport().rect().center() + ) + + delta = old_pos - new_pos + + self.graphics_view.centerOn(scene_pos - delta) + def createToolBar(self) -> None: """ Creates the toolbar containing the file, layout and toolbar