Newer
Older
Contains the scheduler-gui GraphicsGraphEvent class containing event filters and handlers for GraphicsGraphItem objects.
"""
import os
import sys
from typing import Any, Optional
from pprint import pprint
from typing import Any, Union, Optional, overload, Final, final, List
# from typing_extensions import Self, Final, Literal, LiteralString, TypeAlias, final
import numpy as np
from copy import deepcopy
from itertools import combinations
import qtpy
from qtpy import QtCore
from qtpy import QtGui
from qtpy import QtWidgets
# QGraphics and QPainter imports
from qtpy.QtCore import (
Qt, QObject, QRect, QRectF, QPoint, QSize, QSizeF, QByteArray, Slot, QEvent)
from qtpy.QtGui import (
QPaintEvent, QPainter, QPainterPath, QColor, QBrush, QPen, QFont, QPolygon, QIcon, QPixmap,
from qtpy.QtWidgets import (
QGraphicsView, QGraphicsScene, QGraphicsWidget,
QGraphicsLayout, QGraphicsLinearLayout, QGraphicsGridLayout, QGraphicsLayoutItem, QGraphicsAnchorLayout,
QGraphicsItem, QGraphicsItemGroup, QGraphicsPathItem, QGraphicsLineItem, QGraphicsRectItem,
QStyleOptionGraphicsItem, QWidget,
QGraphicsObject, QGraphicsSceneMouseEvent, QGraphicsSceneHoverEvent, QGraphicsSceneContextMenuEvent,
QGraphicsSceneDragDropEvent, QGraphicsSceneWheelEvent)
from graphics_component_item import GraphicsComponentItem
from graphics_axes_item import GraphicsAxesItem
from graphics_timeline_item import GraphicsTimelineItem
#################
#### Filters ####
#################
@overload
def installSceneEventFilters(self, filterItems: QGraphicsItem) -> None: ...
@overload
def installSceneEventFilters(self, filterItems: List[QGraphicsItem]) -> None: ...
def installSceneEventFilters(self, filterItems) -> None:
"""Installs an event filter for 'filterItems' on 'self', causing all events
for 'filterItems' to first pass through 'self's sceneEventFilter()
function. 'filterItems' can be one object or a list of objects."""
@overload
def removeSceneEventFilters(self, filterItems: QGraphicsItem) -> None: ...
@overload
def removeSceneEventFilters(self, filterItems: List[QGraphicsItem]) -> None: ...
def removeSceneEventFilters(self, filterItems) -> None:
"""Removes an event filter on 'filterItems' from 'self'. 'filterItems' can
be one object or a list of objects."""
def sceneEventFilter(self, item: QGraphicsItem, event: QEvent) -> bool:
"""Returns true if the event was filtered (i.e. stopped), otherwise false.
If false is returned, the event is forwarded to the appropriate child in
the event chain."""
if isinstance(item, GraphicsComponentItem): # one component
QEvent.FocusIn: self.comp_focusInEvent,
QEvent.GraphicsSceneContextMenu: self.comp_contextMenuEvent,
QEvent.GraphicsSceneDragEnter: self.comp_dragEnterEvent,
QEvent.GraphicsSceneDragMove: self.comp_dragMoveEvent,
QEvent.GraphicsSceneDragLeave: self.comp_dragLeaveEvent,
QEvent.GraphicsSceneDrop: self.comp_dropEvent,
QEvent.GraphicsSceneHoverEnter: self.comp_hoverEnterEvent,
QEvent.GraphicsSceneHoverMove: self.comp_hoverMoveEvent,
QEvent.GraphicsSceneHoverLeave: self.comp_hoverLeaveEvent,
QEvent.GraphicsSceneMouseMove: self.comp_mouseMoveEvent,
QEvent.GraphicsSceneMousePress: self.comp_mousePressEvent,
QEvent.GraphicsSceneMouseRelease: self.comp_mouseReleaseEvent,
QEvent.GraphicsSceneMouseDoubleClick: self.comp_mouseDoubleClickEvent,
QEvent.GraphicsSceneWheel: self.comp_wheelEvent
elif isinstance(item, GraphicsTimelineItem): # the timeline
print(f'{type(item).__name__} received {event.type()}')
switch = {
QEvent.GraphicsSceneHoverEnter: self.timeline_hoverEnterEvent,
QEvent.GraphicsSceneHoverLeave: self.timeline_hoverLeaveEvent,
QEvent.GraphicsSceneMouseMove: self.timeline_mouseMoveEvent,
QEvent.GraphicsSceneMousePress: self.timeline_mousePressEvent,
QEvent.GraphicsSceneMouseRelease: self.timeline_mouseReleaseEvent,
}
handler = switch.get(event.type())
raise TypeError(f"Received an unexpected event '{event.type()}' "
f"from an '{type(item).__name__}' object.")
return False # returns False if event is ignored and pass through event to its child
# def sceneEvent(self, event: QEvent) -> bool:
# print(f'sceneEvent() --> {event.type()}')
# # event.accept()
# # QApplication.sendEvent(self.scene(), event)
# return False
###############################################
#### Event Handlers: GraphicsComponentItem ####
###############################################
def comp_focusInEvent(self, event: QFocusEvent) -> None: ...
def comp_contextMenuEvent(self, event: QGraphicsSceneContextMenuEvent) -> None: ...
def comp_dragEnterEvent(self, event: QGraphicsSceneDragDropEvent) -> None: ...
def comp_dragMoveEvent(self, event: QGraphicsSceneDragDropEvent) -> None: ...
def comp_dragLeaveEvent(self, event: QGraphicsSceneDragDropEvent) -> None: ...
def comp_dropEvent(self, event: QGraphicsSceneDragDropEvent) -> None: ...
def comp_hoverEnterEvent(self, event: QGraphicsSceneHoverEvent) -> None:
"""Changes the cursor to OpenHandCursor when hovering an object."""
self.setCursor(QCursor(Qt.OpenHandCursor))
def comp_hoverMoveEvent(self, event: QGraphicsSceneHoverEvent) -> None: ...
def comp_hoverLeaveEvent(self, event: QGraphicsSceneHoverEvent) -> None:
"""Unsets the cursor to default cursor."""
self.unsetCursor()
def comp_mouseMoveEvent(self, event: QGraphicsSceneMouseEvent) -> None:
"""Set the position of the graphical element in the graphic scene,
translate coordinates of the cursor within the graphic element in the
coordinate system of the parent object. The object can only move
horizontally in x-axis scale steps."""
# Qt.DragMoveCursor
# button = event.button()
item = self.scene().mouseGrabberItem()
dx = (item.mapToParent(event.pos()) - self._current_pos).x()
if self.is_component_valid_pos(pos):
# self.prepareGeometryChange()
self._current_pos.setX(self._current_pos.x() + 1.0)
elif dx < -0.505:
pos = item.x() - 1.0
if self.is_component_valid_pos(pos):
# self.prepareGeometryChange()
def comp_mousePressEvent(self, event: QGraphicsSceneMouseEvent) -> None:
"""Changes the cursor to ClosedHandCursor when grabbing an object and
stores the current position in item's parent coordinates. 'event' will
by default be accepted, and this item is then the mouse grabber. This
allows the item to receive future move, release and double-click events."""
item: GraphicsComponentItem = self.scene().mouseGrabberItem()
# op = self.schedule.sfg.find_by_id(item.op_id)
# emit fill_info_table_component(op)
def comp_mouseReleaseEvent(self, event: QGraphicsSceneMouseEvent) -> None:
"""Changes the cursor to OpenHandCursor when releasing an object."""
def comp_mouseDoubleClickEvent(self, event: QGraphicsSceneMouseEvent) -> None: ...
def comp_wheelEvent(self, event: QGraphicsSceneWheelEvent) -> None: ...
def timeline_hoverEnterEvent(self, event: QGraphicsSceneHoverEvent) -> None:
"""Changes the cursor to SizeHorCursor when hovering an object."""
self.setCursor(QCursor(Qt.SizeHorCursor))
def timeline_hoverLeaveEvent(self, event: QGraphicsSceneHoverEvent) -> None:
"""Unsets the cursor to default cursor."""
self.unsetCursor()
def timeline_mouseMoveEvent(self, event: QGraphicsSceneMouseEvent) -> None:
"""Set the position of the graphical element in the graphic scene,
translate coordinates of the cursor within the graphic element in the
coordinate system of the parent object. The object can only move
horizontally in x-axis scale steps."""
# Qt.DragMoveCursor
# button = event.button()
item: GraphicsTimelineItem = self.scene().mouseGrabberItem()
dx = (item.mapToParent(event.pos()) - self._current_pos).x()
if dx > 0.505:
pos = item.x() + 1.0
if self.is_valid_delta_time(self._delta_time + 1):
# self.prepareGeometryChange()
item.setX(pos)
self._current_pos.setX(self._current_pos.x() + 1.0)
self._delta_time += 1
elif dx < -0.505:
pos = item.x() - 1.0
if self.is_valid_delta_time(self._delta_time - 1):
# self.prepareGeometryChange()
item.setX(pos)
self._current_pos.setX(self._current_pos.x() - 1.0)
self._delta_time -= 1
def timeline_mousePressEvent(self, event: QGraphicsSceneMouseEvent) -> None:
"""Stores the current position in item's parent coordinates. 'event' will
by default be accepted, and this item is then the mouse grabber. This
allows the item to receive future move, release and double-click events."""
item: GraphicsTimelineItem = self.scene().mouseGrabberItem()
item.set_text(self._delta_time)
item.show_label()
self._current_pos = item.mapToParent(event.pos())
event.accept()
def timeline_mouseReleaseEvent(self, event: QGraphicsSceneMouseEvent) -> None:
"""Updates the schedule time."""
item: GraphicsTimelineItem = self.scene().mouseGrabberItem()
item.hide_label()
if self._delta_time != 0:
self.set_schedule_time(self._delta_time)