diff --git a/ryven-editor/ryven/example_nodes/inspector_example/__init__.py b/ryven-editor/ryven/example_nodes/inspector_example/__init__.py
new file mode 100644
index 00000000..e69de29b
diff --git a/ryven-editor/ryven/example_nodes/inspector_example/gui.py b/ryven-editor/ryven/example_nodes/inspector_example/gui.py
new file mode 100644
index 00000000..5f68ebc4
--- /dev/null
+++ b/ryven-editor/ryven/example_nodes/inspector_example/gui.py
@@ -0,0 +1,22 @@
+from ryven.gui_env import *
+from qtpy.QtWidgets import (
+ QWidget,
+ QVBoxLayout,
+ QLabel,
+)
+from .nodes import MyNode
+
+
+class MyNodeInspector(NodeInspectorWidget, QWidget):
+ def __init__(self, params):
+ NodeInspectorWidget.__init__(self, params)
+ QWidget.__init__(self)
+
+ self.setLayout(QVBoxLayout())
+ self.layout().addWidget(QLabel('This is a custom inspector for MyNode.'))
+
+
+@node_gui(MyNode)
+class MyNodeGui(NodeGUI):
+ inspector_widget_class = MyNodeInspector
+ wrap_inspector_in_default = True
diff --git a/ryven-editor/ryven/example_nodes/inspector_example/nodes.py b/ryven-editor/ryven/example_nodes/inspector_example/nodes.py
new file mode 100644
index 00000000..a41d3868
--- /dev/null
+++ b/ryven-editor/ryven/example_nodes/inspector_example/nodes.py
@@ -0,0 +1,14 @@
+from ryven.node_env import *
+
+
+class MyNode(Node):
+ title = 'My Node'
+
+
+export_nodes(
+ [MyNode],
+)
+
+@on_gui_load
+def on_load():
+ from . import gui
diff --git a/ryven-editor/ryven/gui/flow_ui.py b/ryven-editor/ryven/gui/flow_ui.py
index ee9f61c8..43201fca 100644
--- a/ryven-editor/ryven/gui/flow_ui.py
+++ b/ryven-editor/ryven/gui/flow_ui.py
@@ -19,7 +19,7 @@
from ryven.gui.code_editor.CodePreviewWidget import CodePreviewWidget
from ryven.gui.uic.ui_flow_window import Ui_FlowWindow
from ryvencore_qt.src.flows.FlowView import FlowView
-from ryvencore_qt.src.flows.nodes.InspectorGUI import BaseNodeInspector, InspectorWidget
+from ryvencore_qt.src.flows.nodes.NodeInspector import InspectorView
from typing import List
@@ -94,7 +94,7 @@ def __init__(self, main_window, flow: Flow, flow_view: FlowView):
self.ui.source_dock.setWidget(self.code_preview_widget)
# inspector widget
- self.inspector_widget = InspectorWidget(self.flow_view)
+ self.inspector_widget = InspectorView(self.flow_view)
self.ui.inspector_dock.setWidget(self.inspector_widget)
#undo history widget
diff --git a/ryven-editor/ryven/main/packages/gui_env.py b/ryven-editor/ryven/main/packages/gui_env.py
index ce3e2368..db107940 100644
--- a/ryven-editor/ryven/main/packages/gui_env.py
+++ b/ryven-editor/ryven/main/packages/gui_env.py
@@ -2,19 +2,18 @@
This module automatically imports all requirements for Gui definitions of a nodes package.
"""
-import inspect
from typing import Type
-import ryven.gui.std_input_widgets as inp_widgets
-
-from ryvencore_qt import NodeInputWidget, NodeMainWidget, NodeGUI, BaseNodeInspector
-
from ryvencore import Data, Node, serialize, deserialize
from ryvencore.InfoMsgs import InfoMsgs
+
+from ryvencore_qt import NodeInputWidget, NodeMainWidget, NodeGUI, NodeInspectorWidget
+
+import ryven.gui.std_input_widgets as inp_widgets
from ryven.main.utils import in_gui_mode
+
__explicit_nodes: set = set() # for protection against setting the gui twice on the same node
-__explicit_inspectors: set = set() # same as above
def init_node_guis_env():
pass
@@ -63,24 +62,3 @@ def register_gui(gui_cls: Type[NodeGUI]):
return gui_cls
return register_gui
-
-
-
-def inspector_gui(node_cls: Type[Node]):
- """
- Registers an inspector for a node class.
- """
- if not issubclass(node_cls, Node):
- raise Exception(f"{node_cls} is not of type {Node}")
-
- def register_inspector(inspect_cls: Type[BaseNodeInspector]):
- if node_cls in __explicit_inspectors:
- InfoMsgs.write(f'{node_cls.__name__} has defined an explicit inspector {node_cls.inspector.__name__}')
- return
-
- node_cls.inspector = inspect_cls
- __explicit_inspectors.add(inspect_cls)
- InfoMsgs.write(f"Registered node inspector: {node_cls} for {inspect_cls}")
- return inspect_cls
-
- return register_inspector
\ No newline at end of file
diff --git a/ryvencore-qt/ryvencore_qt/__init__.py b/ryvencore-qt/ryvencore_qt/__init__.py
index 1854d7cf..c5f38e06 100644
--- a/ryvencore-qt/ryvencore_qt/__init__.py
+++ b/ryvencore-qt/ryvencore_qt/__init__.py
@@ -11,11 +11,10 @@
from .src.SessionGUI import SessionGUI
from .src.flows.nodes.NodeGUI import NodeGUI
-from .src.flows.nodes.InspectorGUI import BaseNodeInspector, NodeInspector
# customer base classes
from ryvencore import Node
-from .src.flows.nodes.WidgetBaseClasses import NodeMainWidget, NodeInputWidget
+from .src.flows.nodes.WidgetBaseClasses import NodeMainWidget, NodeInputWidget, NodeInspectorWidget
# gui classes
from .src.widgets import *
diff --git a/ryvencore-qt/ryvencore_qt/src/flows/FlowCommands.py b/ryvencore-qt/ryvencore_qt/src/flows/FlowCommands.py
index 46bf036e..ea0d9da0 100644
--- a/ryvencore-qt/ryvencore_qt/src/flows/FlowCommands.py
+++ b/ryvencore-qt/ryvencore_qt/src/flows/FlowCommands.py
@@ -2,15 +2,15 @@
This file contains the implementations of undoable actions for FlowView.
"""
+from typing import Tuple
from qtpy.QtCore import QObject, QPointF
from qtpy.QtWidgets import QUndoCommand
+from ryvencore.Flow import Flow
+
from .drawings.DrawingObject import DrawingObject
from .nodes.NodeItem import NodeItem
-from typing import Tuple
-from ryvencore.NodePort import NodePort, NodeInput, NodeOutput
-from ryvencore.Flow import Flow
from .connections.ConnectionItem import ConnectionItem
def undo_text_multi(items:list, command: str, get_text=None):
diff --git a/ryvencore-qt/ryvencore_qt/src/flows/nodes/InspectorGUI.py b/ryvencore-qt/ryvencore_qt/src/flows/nodes/InspectorGUI.py
deleted file mode 100644
index 2dee349b..00000000
--- a/ryvencore-qt/ryvencore_qt/src/flows/nodes/InspectorGUI.py
+++ /dev/null
@@ -1,172 +0,0 @@
-from abc import ABC, abstractmethod
-from qtpy.QtWidgets import QWidget, QVBoxLayout, QLabel, QTextEdit, QScrollArea
-from ryvencore import Node
-from typing import Union
-from ryvencore_qt.src.flows.FlowView import FlowView
-from ryvencore_qt.src.flows.nodes.NodeItem import NodeItem
-from typing import Type, List
-
-
-class InspectorWidget(QWidget):
- """The widget that handles the inspecting"""
-
- def __init__(self, flow_view: FlowView, parent: QWidget = None):
- super().__init__(parent=parent)
- self.node: Node = None
- self.inspector: BaseNodeInspector = None
- self.flow_view = flow_view
-
- self.setup_ui()
- self.flow_view.nodes_selection_changed.connect(self.set_selected_nodes)
-
- def setup_ui(self):
- self.setLayout(QVBoxLayout())
-
- def set_selected_nodes(self, nodes: List[Node]):
- if len(nodes) == 0:
- self.set_node(None)
- else:
- self.set_node(nodes[-1])
-
- def set_node(self, node: Node):
- """Sets a node for inspection, if it exists. Otherwise clears the inspector"""
- if self.node == node:
- return
-
- if self.inspector:
- self.inspector.unload()
- self.node = None
- self.inspector = None
- self.clear()
-
- node_cls = type(node)
- if not node:
- return
-
- self.node = node
- if hasattr(node_cls, 'inspector'):
- inspect_cls: Type[BaseNodeInspector] = node_cls.inspector
- self.inspector = inspect_cls(node, self.flow_view)
- else:
- self.inspector = NodeInspector(node, self.flow_view)
-
- inspect_gui = self.inspector.create_inspector(self)
- if inspect_gui:
- self.layout().addWidget(inspect_gui)
-
- def clear(self):
- """
- A typical method for clearing a layout. This does not
- delete the widgets. This is left to the InspectorGUI.
- Ideally, one would want to handle the removal there as
- well, if the widget is not deleted.
- """
- layout = self.layout()
- while layout.count():
- item = layout.takeAt(0)
- widget = item.widget()
- if widget:
- widget.setParent(None)
- else:
- layout.removeItem(item)
-
-
-class BaseNodeInspector(ABC):
- """Abstract class for an inspector. Requires the node."""
-
- def __init__(self, node: Node, flow_view: FlowView):
- self.node: Node = node
- self.flow_view: FlowView = flow_view
-
- @abstractmethod
- def create_inspector(
- self, parent: QWidget
- ) -> Union[QWidget, None]: # should be QWidget | None in 3.10+
- """
- Creates the inspector. The parent is also provided. If the
- function returns None, it means parenting has been applied
- here. Otherwise, it must be applied externally within the
- corresponding application.
-
- The implementation is left for the user
- """
- pass
-
- def unload(self):
- """
- VIRTUAL
- This is called when the inspector widget changes the internal
- GUI. Should be used for clearing up any Widgets in order to
- free up memory.
- """
- pass
-
- def node_item(self):
- return self.flow_view.node_items__cache.get(self.node)
-
-
-class NodeInspector(BaseNodeInspector):
- """
- This is a basic implementation. Will be used if there is no inspector
- provided. Can also be subclassed for easier inspector building.
- """
-
- def __init__(self, node: Node, flow_view: FlowView):
- super().__init__(node, flow_view)
- self.inspection_widget = NodeInspectorWidget()
- self.inspection_widget.populate(node, self.node_item())
-
- def create_inspector(self, parent: QWidget):
- parent.layout().addWidget(self.inspection_widget)
- self.attach_inspector(self.inspection_widget.inspect_area)
-
- def attach_inspector(self, parent: QScrollArea):
- pass
-
- def unload(self):
- self.inspection_widget.deleteLater()
- pass
-
-
-class NodeInspectorWidget(QWidget):
- """The basic implementation widget"""
-
- @staticmethod
- def __big_bold_text(txt: str):
- return f'