Skip to content

Commit

Permalink
more type checking for ryvencore-qt
Browse files Browse the repository at this point in the history
  • Loading branch information
leon-thomm committed May 19, 2024
1 parent 982cfe3 commit a40ab40
Show file tree
Hide file tree
Showing 9 changed files with 156 additions and 91 deletions.
23 changes: 10 additions & 13 deletions ryvencore-qt/ryvencore_qt/src/Design.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import json
from typing import Optional
from typing import Optional, List, Tuple

from qtpy.QtCore import QObject, Signal
from qtpy.QtGui import QFontDatabase
Expand All @@ -18,22 +18,22 @@ class Design(QObject):
flow_theme_changed = Signal(str)
performance_mode_changed = Signal(str)

def __init__(self):
def __init__(self) -> None:
super().__init__()

self.flow_themes = flow_themes
self.flow_theme: FlowTheme = None
self.default_flow_size = None
self.performance_mode: str = None
self.node_item_shadows_enabled: bool = None
self.animations_enabled: bool = None
self.node_selection_stylesheet: str = None
self.flow_themes: List[FlowTheme] = flow_themes
self.flow_theme: FlowTheme
self.default_flow_size: Tuple[int, int]
self.performance_mode: str
self.node_item_shadows_enabled: bool
self.animations_enabled: bool
self.node_selection_stylesheet: str

# load standard default values
self._default_flow_theme = self.flow_themes[-1]
self.set_performance_mode('pretty')
self.set_animations_enabled(True)
self.default_flow_size = [1000, 700]
self.default_flow_size = (1000, 700)
self.set_flow_theme(self._default_flow_theme)

@staticmethod
Expand Down Expand Up @@ -94,9 +94,6 @@ def set_flow_theme(self, theme: Optional[FlowTheme] = None, name: str = ''):
self.flow_theme_changed.emit(self.flow_theme.name)

def set_performance_mode(self, new_mode: str):
if self.performance_mode == new_mode:
return

if new_mode == 'fast':
self.node_item_shadows_enabled = False
else:
Expand Down
12 changes: 9 additions & 3 deletions ryvencore-qt/ryvencore_qt/src/flows/FlowCommands.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,12 @@
This file contains the implementations of undoable actions for FlowView.
"""

# prevent cyclic imports
from __future__ import annotations
from typing import TYPE_CHECKING
if TYPE_CHECKING:
from .FlowView import FlowView

from typing import Tuple

from qtpy.QtCore import QObject, QPointF
Expand Down Expand Up @@ -35,10 +41,10 @@ class FlowUndoCommand(QObject, QUndoCommand):
# prevent recursive calls of redo() and undo()
_any_cmd_active = False

def __init__(self, flow_view):
self.flow_view = flow_view
def __init__(self, flow_view: FlowView) -> None:
self.flow_view: FlowView = flow_view
self.flow: Flow = flow_view.flow
self._activated = False
self._activated: bool = False

QObject.__init__(self)
QUndoCommand.__init__(self)
Expand Down
2 changes: 1 addition & 1 deletion ryvencore-qt/ryvencore_qt/src/flows/FlowTheme.py
Original file line number Diff line number Diff line change
Expand Up @@ -1619,7 +1619,7 @@ def draw_NI_small(self, node_gui, selected: bool, hovered: bool,
painter.drawRoundedRect(bounding_rect, 4, 4)


flow_themes = [
flow_themes: List[FlowTheme] = [
FlowTheme_Toy(),
FlowTheme_DarkTron(),
FlowTheme_Ghost(),
Expand Down
91 changes: 56 additions & 35 deletions ryvencore-qt/ryvencore_qt/src/flows/FlowView.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
# prevent cyclic imports
from __future__ import annotations
from typing import TYPE_CHECKING
if TYPE_CHECKING:
from ..SessionGUI import SessionGUI

import json

from typing import Tuple, Optional
Expand All @@ -19,6 +25,8 @@
QColor,
QKeySequence,
QTabletEvent,
QDropEvent,
QContextMenuEvent,
QImage,
QGuiApplication,
QFont,
Expand Down Expand Up @@ -106,7 +114,7 @@ class FlowView(GUIBase, QGraphicsView):

viewport_update_mode_changed = Signal(str)

def __init__(self, session_gui, flow, parent=None):
def __init__(self, session_gui: SessionGUI, flow: Flow, parent=None) -> None:
GUIBase.__init__(self, representing_component=flow)
QGraphicsView.__init__(self, parent=parent)

Expand All @@ -125,31 +133,31 @@ def __init__(self, session_gui, flow, parent=None):
self.design: Design = session_gui.design # type hinting and quicker access

self.flow: Flow = flow
self.node_items: dict = {} # {Node: NodeItem}
self.node_items__cache: dict = {}
self.connection_items: dict = {} # {Connection: ConnectionItem}
self.connection_items__cache: dict = {}
self.node_items: Dict = {} # {Node: NodeItem}
self.node_items__cache: Dict = {}
self.connection_items: Dict = {} # {Connection: ConnectionItem}
self.connection_items__cache: Dict = {}
self.selection_mode: _SelectionMode = _SelectionMode.UNDOABLE_CLICK

# PRIVATE FIELDS
self._loaded_state = None # h and v scrollbars are changed on import, so we need to defer
self._loaded_state: Optional[Dict] = None # h and v scrollbars are changed on import, so we need to defer
self._tmp_data = None
self._selected_pin: PortItemPin = None
self._selected_pin: Optional[PortItemPin] = None
self._dragging_connection = False
self._temp_connection_ports = None
self._temp_connection_ports: Optional[Tuple[NodeOutput, NodeInput]] = None
self._waiting_for_connection_request: bool = False
self.mouse_event_taken = False # for stylus - see tablet event
self._last_mouse_move_pos: QPointF = None
self._last_mouse_move_pos: Optional[QPointF] = None
self._node_place_pos = QPointF()
self._left_mouse_pressed_in_flow = False
self._right_mouse_pressed_in_flow = False
self._mouse_press_pos: QPointF = None
self._mouse_press_pos: Optional[QPointF] = None
self._multi_selection = False
self._current_selected = []
self._auto_connection_pin = None # stores the gate that we may try to auto connect to a newly placed NI
self._current_selected: List[QGraphicsItem] = []
self._auto_connection_pin: Optional[PortItemPin] = None # stores the gate that we may try to auto connect to a newly placed NI
self._panning = False
self._pan_last_x = None
self._pan_last_y = None
self._pan_last_x: Optional[int] = None
self._pan_last_y: Optional[int] = None
self._current_scale = 1
self._total_scale_div = 1
self._zoom_data = {
Expand Down Expand Up @@ -234,7 +242,7 @@ def init_proxy_widget(widget: QWidget, proxy: FlowViewProxyWidget):
self.stylus_mode = ''
self._current_drawing = None
self._drawing = False
self.drawings = []
self.drawings: List[DrawingObject] = []
self._stylus_modes_widget = FlowViewStylusModesWidget(self)
self._stylus_modes_proxy = init_proxy_widget(
self._stylus_modes_widget, FlowViewProxyWidget(self)
Expand Down Expand Up @@ -568,7 +576,7 @@ def viewportEvent(self, event: QEvent) -> bool:
else:
return super().viewportEvent(event)

def tabletEvent(self, event):
def tabletEvent(self, event: QTabletEvent) -> None:
"""tabletEvent gets called by stylus operations.
LeftButton: std, no button pressed
RightButton: upper button pressed"""
Expand All @@ -581,7 +589,9 @@ def tabletEvent(self, event):
):
return # let the mousePress/Move/Release-Events handle it

scaled_event_pos: QPointF = event.posF() / self._current_scale
scaled_event_pos: QPointF = event.posF()
scaled_event_pos /= self._current_scale # type: ignore
# mypy thinks the above results in a float, but it doesn't

if event.type() == QTabletEvent.TabletPress:
self.mouse_event_taken = True
Expand Down Expand Up @@ -615,6 +625,7 @@ def tabletEvent(self, event):
self.remove_drawing(i)
break
elif self.stylus_mode == 'comment' and self._drawing:
assert self._current_drawing is not None
if self._current_drawing.append_point(scaled_event_pos):
self._current_drawing.stroke_weights.append(
event.pressure() * self._stylus_modes_widget.pen_width()
Expand All @@ -626,6 +637,7 @@ def tabletEvent(self, event):
if self._panning:
self._panning = False
if self.stylus_mode == 'comment' and self._drawing:
assert self._current_drawing is not None
self._current_drawing.finish()
InfoMsgs.write('drawing finished')
self._current_drawing = None
Expand Down Expand Up @@ -655,24 +667,25 @@ def dragMoveEvent(self, event):
if event.mimeData().hasFormat('application/json'):
event.acceptProposedAction()

def dropEvent(self, event):
def dropEvent(self, event: QDropEvent):
try:
text = str(event.mimeData().data('application/json'), 'utf-8')
data: dict = json.loads(text)
data: Dict = json.loads(text)

if data['type'] == 'node':
self._node_place_pos = self.mapToScene(event.pos())
self.create_node__cmd(
node_from_identifier(
data['node identifier'], self.session_gui.core_session.nodes
data['node identifier'],
list(self.session_gui.core_session.nodes)
)
)
# without this keyPressed function isn't called if we don't click in the view
self.setFocus()
except Exception:
pass

def contextMenuEvent(self, event):
def contextMenuEvent(self, event: QCotextMenuEvent):
QGraphicsView.contextMenuEvent(self, event)
# in the case of the menu already being shown by a widget under the mouse, the event is accepted here
if event.isAccepted():
Expand Down Expand Up @@ -770,9 +783,11 @@ def get_viewport_img(self) -> QImage:

self.hide_proxies()
img = QImage(
self.viewport().rect().width(),
self.viewport().height(),
QImage.Format_ARGB32,
size=QSizeF(
self.viewport().rect().width(),
self.viewport().height(),
),
format=QImage.Format_ARGB32,
)
img.fill(Qt.transparent)

Expand All @@ -789,9 +804,11 @@ def get_whole_scene_img(self) -> QImage:

self.hide_proxies()
img = QImage(
self.sceneRect().width() / self._total_scale_div,
self.sceneRect().height() / self._total_scale_div,
QImage.Format_RGB32,
size=QSizeF(
self.sceneRect().width() / self._total_scale_div,
self.sceneRect().height() / self._total_scale_div,
),
format=QImage.Format_RGB32,
)
img.fill(Qt.transparent)

Expand Down Expand Up @@ -962,9 +979,9 @@ def zoom(self, p_abs, p_mapped, angle):
def create_node__cmd(self, node_class):
self.push_undo(PlaceNode_Command(self, node_class, self._node_place_pos))

def add_node(self, node):
def add_node(self, node: Node):
# create item
item: NodeItem = None
item: NodeItem

if node in self.node_items__cache.keys(): # load from cache
# print('using a cached item')
Expand Down Expand Up @@ -1041,16 +1058,20 @@ def connection_request_valid(self, valid: bool):
Triggered after the abstract flow evaluated validity of pending connect request.
This can also lead to a disconnect!
"""

# TODO: this stuff is too complicated, simplify

if self._waiting_for_connection_request:
self._waiting_for_connection_request = False
else:
return

assert self._temp_connection_ports is not None

if valid:
out: NodeOutput
inp: NodeInput
out, inp = self._temp_connection_ports
if out.io_pos == PortObjPos.INPUT:
out, inp = inp, out

if self.flow.graph_adj_rev[inp] not in (None, out): # out connected to something else
# remove existing connection
Expand Down Expand Up @@ -1139,7 +1160,7 @@ def create_drawing(self, data=None) -> DrawingObject:
new_drawing = DrawingObject(self, data)
return new_drawing

def add_drawing(self, drawing_obj, posF=None):
def add_drawing(self, drawing_obj: DrawingObject, posF=None):
"""Adds a DrawingObject to the scene."""

self._set_selection_mode(_SelectionMode.INSTANT)
Expand Down Expand Up @@ -1396,7 +1417,7 @@ def _paste(self): # ctrl+v
self.push_undo(Paste_Command(self, data, offset_for_middle_pos))

# DATA
def complete_data(self, data: dict):
def complete_data(self, data: Dict):
data['flow view'] = {
'drawings': self._get_drawings_data(self.drawings),
'view size': [
Expand Down Expand Up @@ -1444,7 +1465,7 @@ def save_state(self) -> dict:
'h_scroll': self.verticalScrollBar().value(),
}

def load(self, state: dict):
def load(self, state: Dict):
"""Load the state of the view"""
transform = QTransform(
state['m11'], state['m12'], state['m13'],
Expand All @@ -1459,6 +1480,6 @@ def load(self, state: dict):
self._loaded_state = state

def reload(self):
if self._loaded_state:
if self._loaded_state is not None:
self.load(self._loaded_state)

Loading

0 comments on commit a40ab40

Please sign in to comment.