Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 23 additions & 10 deletions opencodeblocks/graphics/pyeditor.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

from typing import TYPE_CHECKING, List
from PyQt5.QtCore import QThreadPool, Qt
from PyQt5.QtGui import QFocusEvent, QFont, QFontMetrics, QColor
from PyQt5.QtGui import QFocusEvent, QFont, QFontMetrics, QColor, QMouseEvent, QWheelEvent
from PyQt5.Qsci import QsciScintilla, QsciLexerPython
from opencodeblocks.graphics.theme_manager import theme_manager

Expand All @@ -31,6 +31,7 @@ def __init__(self, block: OCBBlock):

"""
super().__init__(None)
self._mode = "NOOP"
self.block = block
self.kernel = kernel
self.threadpool = threadpool
Expand Down Expand Up @@ -90,19 +91,31 @@ def views(self) -> List['OCBView']:
""" Get the views in which the python_editor is present. """
return self.block.scene().views()

def set_views_mode(self, mode: str):
""" Set the views in which the python_editor is present to editing mode. """
def wheelEvent(self, event: QWheelEvent) -> None:
""" How PythonEditor handles wheel events """
if self.mode == "EDITING" and event.angleDelta().x() == 0:
event.accept()
return super().wheelEvent(event)

@property
def mode(self) -> int:
""" PythonEditor current mode """
return self._mode

@mode.setter
def mode(self, value: str):
self._mode = value
for view in self.views():
if mode == "MODE_EDITING" or view.is_mode("MODE_EDITING"):
view.set_mode(mode)
view.set_mode(value)

def focusInEvent(self, event: QFocusEvent):
""" PythonEditor reaction to PyQt focusIn events. """
self.set_views_mode("MODE_EDITING")
return super().focusInEvent(event)
def mousePressEvent(self, event: QMouseEvent) -> None:
""" PythonEditor reaction to PyQt mousePressEvent events. """
if event.buttons() & Qt.MouseButton.LeftButton:
self.mode = "EDITING"
return super().mousePressEvent(event)

def focusOutEvent(self, event: QFocusEvent):
""" PythonEditor reaction to PyQt focusOut events. """
self.set_views_mode("MODE_NOOP")
self.mode = "NOOP"
self.block.source = self.text()
return super().focusOutEvent(event)
49 changes: 27 additions & 22 deletions opencodeblocks/graphics/view.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,25 +18,25 @@
from opencodeblocks.graphics.edge import OCBEdge
from opencodeblocks.graphics.blocks import OCBBlock

MODE_NOOP = 0
MODE_EDGE_DRAG = 1
MODE_EDITING = 2

MODES = {
'MODE_NOOP': MODE_NOOP,
'MODE_EDGE_DRAG': MODE_EDGE_DRAG,
'MODE_EDITING': MODE_EDITING,
}


class OCBView(QGraphicsView):

""" View for the OCB Window. """

MODE_NOOP = 0
MODE_EDGE_DRAG = 1
MODE_EDITING = 2

MODES = {
'NOOP': MODE_NOOP,
'EDGE_DRAG': MODE_EDGE_DRAG,
'EDITING': MODE_EDITING,
}

def __init__(self, scene: OCBScene, parent=None,
zoom_step: float = 1.25, zoom_min: float = 0.2, zoom_max: float = 5):
super().__init__(parent=parent)
self.mode = MODE_NOOP
self.mode = self.MODE_NOOP
self.zoom = 1
self.zoom_step, self.zoom_min, self.zoom_max = zoom_step, zoom_min, zoom_max

Expand Down Expand Up @@ -125,7 +125,8 @@ def leftMouseButtonRelease(self, event: QMouseEvent):

def middleMouseButtonPress(self, event: QMouseEvent):
""" OCBView reaction to middleMouseButtonPress event. """
event = self.drag_scene(event, "press")
if self.itemAt(event.pos()) is None:
event = self.drag_scene(event, "press")
super().mousePressEvent(event)

def middleMouseButtonRelease(self, event: QMouseEvent):
Expand All @@ -135,6 +136,7 @@ def middleMouseButtonRelease(self, event: QMouseEvent):
self.setDragMode(QGraphicsView.DragMode.RubberBandDrag)

def retreiveBlockTypes(self) -> List[Tuple[str]]:
""" Retreive the list of stored blocks. """
block_type_files = os.listdir("blocks")
block_types = []
for b in block_type_files:
Expand All @@ -144,7 +146,10 @@ def retreiveBlockTypes(self) -> List[Tuple[str]]:
title = "New Block"
if "title" in data:
title = f"New {data['title']} Block"
block_types.append((filepath, title))
if data['title'] == "Empty":
block_types[:0] = [(filepath, title)]
else:
block_types.append((filepath, title))
return block_types

def contextMenuEvent(self, event: QContextMenuEvent):
Expand Down Expand Up @@ -219,17 +224,17 @@ def drag_edge(self, event: QMouseEvent, action="press"):
scene = self.scene()
if action == "press":
if isinstance(item_at_click, OCBSocket) \
and self.mode != MODE_EDGE_DRAG\
and self.mode != self.MODE_EDGE_DRAG\
and item_at_click.socket_type != 'input':
self.mode = MODE_EDGE_DRAG
self.mode = self.MODE_EDGE_DRAG
self.edge_drag = OCBEdge(
source_socket=item_at_click,
destination=self.mapToScene(event.pos())
)
scene.addItem(self.edge_drag)
return
elif action == "release":
if self.mode == MODE_EDGE_DRAG:
if self.mode == self.MODE_EDGE_DRAG:
if isinstance(item_at_click, OCBSocket) \
and item_at_click is not self.edge_drag.source_socket \
and item_at_click.socket_type != 'output':
Expand All @@ -239,26 +244,26 @@ def drag_edge(self, event: QMouseEvent, action="press"):
else:
self.edge_drag.remove()
self.edge_drag = None
self.mode = MODE_NOOP
self.mode = self.MODE_NOOP
elif action == "move":
if self.mode == MODE_EDGE_DRAG:
if self.mode == self.MODE_EDGE_DRAG:
self.edge_drag.destination = self.mapToScene(event.pos())
return event

def set_mode(self, mode: str):
""" Change the view mode.

Args:
mode: Mode key to change to, must in present in knowed MODES.
mode: Mode key to change to, must in present in MODES.

"""
self.mode = MODES[mode]
self.mode = self.MODES[mode]

def is_mode(self, mode: str):
""" Return True if the view is in the given mode.

Args:
mode: Mode key to compare to, must in present in knowed MODES.
mode: Mode key to compare to, must in present in MODES.

"""
return self.mode == MODES[mode]
return self.mode == self.MODES[mode]
19 changes: 11 additions & 8 deletions opencodeblocks/graphics/window.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,6 @@
from PyQt5.QtWidgets import QDockWidget, QListWidget, QWidget, QAction, QFileDialog, QMainWindow,\
QMessageBox, QMdiArea

from opencodeblocks import __appname__ as application_name
from opencodeblocks.graphics.view import MODE_EDITING
from opencodeblocks.graphics.widget import OCBWidget
from opencodeblocks.graphics.theme_manager import theme_manager

Expand Down Expand Up @@ -269,40 +267,45 @@ def onFileSaveAs(self) -> bool:
return True
return False

@staticmethod
def is_not_editing(current_window: OCBWidget):
""" True if current_window exists and is not in editing mode. """
return current_window is not None and not current_window.view.is_mode('EDITING')

def onEditUndo(self):
""" Undo last operation if not in edit mode. """
current_window = self.activeMdiChild()
if current_window is not None and current_window.view.mode != MODE_EDITING:
if self.is_not_editing(current_window):
current_window.scene.history.undo()

def onEditRedo(self):
""" Redo last operation if not in edit mode. """
current_window = self.activeMdiChild()
if current_window is not None and current_window.view.mode != MODE_EDITING:
if self.is_not_editing(current_window):
current_window.scene.history.redo()

def onEditCut(self):
""" Cut the selected items if not in edit mode. """
current_window = self.activeMdiChild()
if current_window is not None and current_window.view.mode != MODE_EDITING:
if self.is_not_editing(current_window):
current_window.scene.clipboard.cut()

def onEditCopy(self):
""" Copy the selected items if not in edit mode. """
current_window = self.activeMdiChild()
if current_window is not None and current_window.view.mode != MODE_EDITING:
if self.is_not_editing(current_window):
current_window.scene.clipboard.copy()

def onEditPaste(self):
""" Paste the selected items if not in edit mode. """
current_window = self.activeMdiChild()
if current_window is not None and current_window.view.mode != MODE_EDITING:
if self.is_not_editing(current_window):
current_window.scene.clipboard.paste()

def onEditDelete(self):
""" Delete the selected items if not in edit mode. """
current_window = self.activeMdiChild()
if current_window is not None and current_window.view.mode != MODE_EDITING:
if self.is_not_editing(current_window):
current_window.view.deleteSelected()

# def closeEvent(self, event:QEvent):
Expand Down