msspec_python3/msspec/msspecgui/datafloweditor/operatorwidget.py

120 lines
4.7 KiB
Python

# import wx.lib.wxcairo
# import math
import msspecgui
from msspecgui import scenegraph2d
from .widget import Widget
# from msspecgui import datafloweditor
# from numpy.distutils.misc_util import cxx_ext_match
class OperatorWidget(Widget):
'''
The widget representing a node in the dataflow
'''
_g_last_id = 0
def __init__(self, operator, data_flow_view):
"""
:param operator: the dataflow operator that this widget graphically represents
:type operator: msspecgui.dataflow.Operator
:param data_flow_view: the dataflowview to which this operator belongs
:type data_flow_view: msspecgui.datafloweditor.DataflowView
"""
super(OperatorWidget, self).__init__(data_flow_view)
self._operator = operator
self._id = OperatorWidget.get_new_id()
self.is_selected = False
self.widget_background = None
self.main_shape_node = scenegraph2d.Group()
self.plug_to_widget = {} # an associative array that gives the widget associated to each plug name
for side in ['input', 'output']:
plugs = {'input': self._operator.get_input_plugs(),
'output': self._operator.get_output_plugs()}[side]
# plug_index = 0
for plug in plugs:
if plug.is_pluggable:
plug_widget = msspecgui.datafloweditor.PlugWidget(plug, self, data_flow_view)
self.plug_to_widget[plug.name] = plug_widget
# plug_index += 1
@classmethod
def get_new_id(cls):
OperatorWidget._g_last_id += 1
return OperatorWidget._g_last_id
def get_id(self):
return self._id
@property
def operator(self):
return self._operator
def update_appearance(self):
for plug_widget in self.plug_to_widget.itervalues():
plug_widget.update_appearance(mouse_is_above=False) # FIXME : handle the case where the mouse is over the plug widget
def get_plug_widget(self, plug):
"""
Returns the plug widget associated with the given plug
:type plug: Plug
:rtype: PlugWidget
"""
plug_widget = self.plug_to_widget[plug.name]
return plug_widget
def set_selected_state(self, is_selected):
self.is_selected = is_selected
self.widget_background.fill = {False: scenegraph2d.Color(128, 128, 128), True: scenegraph2d.Color(192, 192, 128)}[self.is_selected]
def set_position(self, x, y):
self.main_shape_node.parent.transform = [msspecgui.scenegraph2d.Translate(x, y)]
assert self.operator is not None
for wire in self.operator.wires:
if wire in self._data_flow_view.wire_to_widget: # while load the dataflow, wires are not guaranteed to have a widget yet
wire_widget = self._data_flow_view.wire_to_widget[wire]
wire_widget.update_position()
def render_to_scene_graph(self, scenegraph_group):
"""
:param scenegraph_group: the group node that contains the drawing of this element
:type scenegraph_group: scenegraph.Group
"""
rect = scenegraph2d.Rectangle()
rect.width = 70.0
rect.height = 70.0
rect.x = -35.0
rect.y = -35.0
rect.fill = scenegraph2d.Color(128, 128, 128)
self.widget_background = rect
self.main_shape_node.add_child(rect)
title = "%s (%d)" % (self._operator.creator.get_operator_type_id().split('.')[-1], self.get_id())
# import my.source.module
# c = my.source.module.Color()
title_text = scenegraph2d.Text(title)
title_text.fill = scenegraph2d.Color.black
title_text.text_anchor = "middle"
self.main_shape_node.add_child(title_text)
for side in ['input', 'output']:
(cx, plugs) = {'input': (-25.0, self._operator.get_input_plugs()),
'output': (25.0, self._operator.get_output_plugs())}[side]
plug_index = 0
for p in plugs:
if p.is_pluggable:
plug_group = scenegraph2d.Group()
plug_group.x = cx
plug_group.y = -25.0 + 10.0 * plug_index
self.main_shape_node.add_child(plug_group)
plug_widget = self.plug_to_widget[p.name]
plug_widget.render_to_scene_graph(plug_group)
plug_index += 1
self.scenegraph_group = scenegraph_group
self.scenegraph_group.add_child(self.main_shape_node)
def remove_from_scene_graph(self):
parent = self.main_shape_node.parent
parent.remove_child(self.main_shape_node)