Ejemplo n.º 1
0
    def __init__(self, parent_node: Node, flow, config=None):
        super(NodeInstance, self).__init__()
        self.parent_node = parent_node
        self.flow = flow

        # general attributes
        self.inputs = []
        self.outputs = []
        self.main_widget = None
        self.main_widget_proxy: FlowProxyWidget = None
        self.default_actions = {
            'remove': {
                'method': self.action_remove,
                'data': 123
            },
            'compute shape': {
                'method': self.compute_content_positions
            }
        }  # holds information for context menus
        self.gen_data_on_request = False
        self.personal_logs = []
        self.special_actions = {
        }  # only gets written in custom NodeInstance-subclasses - dynamic
        self.width = -1
        self.height = -1
        self.display_name_font = QFont('Poppins', 15) if parent_node.design_style == 'extended' else \
                                 QFont('K2D', 20, QFont.Bold, True)
        self.display_name_FM = QFontMetricsF(self.display_name_font)
        # self.port_label_font = QFont("Source Code Pro", 10, QFont.Bold, True)

        # gets set to false a few lines below. needed for setup ports (to prevent shape updating stuff)
        self.initializing = True

        self.temp_state_data = None

        if self.parent_node.has_main_widget:
            self.main_widget = self.parent_node.main_widget_class(self)
            self.main_widget_proxy = FlowProxyWidget(self.flow, self)
            self.main_widget_proxy.setWidget(self.main_widget)

        if config:
            # self.setPos(config['position x'], config['position y'])
            self.setup_ports(config['inputs'], config['outputs'])
            if self.main_widget:
                try:
                    self.main_widget.set_data(config['main widget data'])
                except KeyError:
                    pass

            self.special_actions = self.set_special_actions_data(
                config['special actions'])
            self.temp_state_data = config['state data']
        else:
            self.setup_ports()

        # TOOLTIP
        self.setToolTip(self.parent_node.description)

        self.initializing = False
Ejemplo n.º 2
0
 def create_widget(self, configuration=None):
     if self.direction == 'input' and (self.type_ and self.type_ == 'data'
                                       or configuration
                                       and configuration['type'] == 'data'):
         if self.widget_type == 'None':  # no input widget
             return
         elif self.widget_type == 'std line edit':
             self.widget = StdLineEdit_PortInstanceWidget(
                 self, self.parent_node_instance)
         elif self.widget_type == 'std spin box':
             self.widget = StdSpinBox_PortInstanceWidget(
                 self, self.parent_node_instance)
         elif self.widget_type == 'custom widget':
             self.widget = self.get_input_widget_class(self.widget_name)(
                 self, self.parent_node_instance)
         self.proxy = FlowProxyWidget(self.parent_node_instance.flow,
                                      self.parent_node_instance)
         self.proxy.setWidget(self.widget)
Ejemplo n.º 3
0
 def create_widget(self, configuration=None):
     if self.type_ and self.type_ == 'data' or configuration and configuration[
             'type'] == 'data':
         if self.widget_name is None:  # no input widget
             return
         elif self.widget_name == 'std line edit s':
             self.widget = StdLineEdit_PortInstanceWidget(
                 self, self.parent_node_instance, size='small')
         elif self.widget_name == 'std line edit m' or self.widget_name == 'std line edit':
             self.widget = StdLineEdit_PortInstanceWidget(
                 self, self.parent_node_instance)
         elif self.widget_name == 'std line edit l':
             self.widget = StdLineEdit_PortInstanceWidget(
                 self, self.parent_node_instance, size='large')
         elif self.widget_name == 'std line edit s r':
             self.widget = StdLineEdit_PortInstanceWidget(
                 self, self.parent_node_instance, size='small', resize=True)
         elif self.widget_name == 'std line edit m r':
             self.widget = StdLineEdit_PortInstanceWidget(
                 self, self.parent_node_instance, resize=True)
         elif self.widget_name == 'std line edit l r':
             self.widget = StdLineEdit_PortInstanceWidget(
                 self, self.parent_node_instance, size='large', resize=True)
         elif self.widget_name == 'std line edit s r nb':
             self.widget = StdLineEdit_NoBorder_PortInstanceWidget(
                 self, self.parent_node_instance, size='small', resize=True)
         elif self.widget_name == 'std line edit m r nb':
             self.widget = StdLineEdit_NoBorder_PortInstanceWidget(
                 self, self.parent_node_instance, resize=True)
         elif self.widget_name == 'std line edit l r nb':
             self.widget = StdLineEdit_NoBorder_PortInstanceWidget(
                 self, self.parent_node_instance, size='large', resize=True)
         elif self.widget_name == 'std spin box':
             self.widget = StdSpinBox_PortInstanceWidget(
                 self, self.parent_node_instance)
         else:  # custom input widget
             self.widget = self.get_input_widget_class(self.widget_name)(
                 (self, self.parent_node_instance))
         self.proxy = FlowProxyWidget(self.parent_node_instance.flow,
                                      self.parent_node_instance)
         self.proxy.setWidget(self.widget)
Ejemplo n.º 4
0
    def __init__(self, main_window, parent_script, config=None):
        super(Flow, self).__init__()

        # SHORTCUTS
        place_new_node_shortcut = QShortcut(QKeySequence('Shift+P'), self)
        place_new_node_shortcut.activated.connect(
            self.place_new_node_by_shortcut)
        move_selected_nodes_left_shortcut = QShortcut(
            QKeySequence('Shift+Left'), self)
        move_selected_nodes_left_shortcut.activated.connect(
            self.move_selected_nodes_left)
        move_selected_nodes_up_shortcut = QShortcut(QKeySequence('Shift+Up'),
                                                    self)
        move_selected_nodes_up_shortcut.activated.connect(
            self.move_selected_nodes_up)
        move_selected_nodes_right_shortcut = QShortcut(
            QKeySequence('Shift+Right'), self)
        move_selected_nodes_right_shortcut.activated.connect(
            self.move_selected_nodes_right)
        move_selected_nodes_down_shortcut = QShortcut(
            QKeySequence('Shift+Down'), self)
        move_selected_nodes_down_shortcut.activated.connect(
            self.move_selected_nodes_down)
        select_all_shortcut = QShortcut(QKeySequence('Ctrl+A'), self)
        select_all_shortcut.activated.connect(self.select_all)
        copy_shortcut = QShortcut(QKeySequence.Copy, self)
        copy_shortcut.activated.connect(self.copy)
        cut_shortcut = QShortcut(QKeySequence.Cut, self)
        cut_shortcut.activated.connect(self.cut)
        paste_shortcut = QShortcut(QKeySequence.Paste, self)
        paste_shortcut.activated.connect(self.paste)

        # UNDO/REDO
        self.undo_stack = QUndoStack(self)
        self.undo_action = self.undo_stack.createUndoAction(self, 'undo')
        self.undo_action.setShortcuts(QKeySequence.Undo)
        self.redo_action = self.undo_stack.createRedoAction(self, 'redo')
        self.redo_action.setShortcuts(QKeySequence.Redo)

        undo_shortcut = QShortcut(QKeySequence.Undo, self)
        undo_shortcut.activated.connect(self.undo_activated)
        redo_shortcut = QShortcut(QKeySequence.Redo, self)
        redo_shortcut.activated.connect(self.redo_activated)

        # GENERAL ATTRIBUTES
        self.parent_script = parent_script
        self.all_node_instances: [NodeInstance] = []
        self.all_node_instance_classes = main_window.all_node_instance_classes  # ref
        self.all_nodes = main_window.all_nodes  # ref
        self.gate_selected: PortInstanceGate = None
        self.dragging_connection = False
        self.ignore_mouse_event = False  # for stylus - see tablet event
        self.last_mouse_move_pos: QPointF = None
        self.node_place_pos = QPointF()
        self.left_mouse_pressed_in_flow = False
        self.mouse_press_pos: QPointF = None
        self.tablet_press_pos: QPointF = None
        self.auto_connection_gate = 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.current_scale = 1
        self.total_scale_div = 1

        # SETTINGS
        self.algorithm_mode = Flow_AlgorithmMode()
        self.viewport_update_mode = Flow_ViewportUpdateMode()

        # CREATE UI
        scene = QGraphicsScene(self)
        scene.setItemIndexMethod(QGraphicsScene.NoIndex)
        scene.setSceneRect(0, 0, 10 * self.width(), 10 * self.height())

        self.setScene(scene)
        self.setCacheMode(QGraphicsView.CacheBackground)
        self.setViewportUpdateMode(QGraphicsView.BoundingRectViewportUpdate)
        self.setRenderHint(QPainter.Antialiasing)
        self.setTransformationAnchor(QGraphicsView.AnchorUnderMouse)
        self.setDragMode(QGraphicsView.RubberBandDrag)
        scene.selectionChanged.connect(self.selection_changed)
        self.setAcceptDrops(True)

        self.centerOn(
            QPointF(self.viewport().width() / 2,
                    self.viewport().height() / 2))

        # NODE CHOICE WIDGET
        self.node_choice_proxy = FlowProxyWidget(self)
        self.node_choice_proxy.setZValue(1000)
        self.node_choice_widget = NodeChoiceWidget(
            self, main_window.all_nodes)  # , main_window.node_images)
        self.node_choice_proxy.setWidget(self.node_choice_widget)
        self.scene().addItem(self.node_choice_proxy)
        self.hide_node_choice_widget()

        # ZOOM WIDGET
        self.zoom_proxy = FlowProxyWidget(self)
        self.zoom_proxy.setFlag(QGraphicsItem.ItemIgnoresTransformations, True)
        self.zoom_proxy.setZValue(1001)
        self.zoom_widget = FlowZoomWidget(self)
        self.zoom_proxy.setWidget(self.zoom_widget)
        self.scene().addItem(self.zoom_proxy)
        self.set_zoom_proxy_pos()

        # STYLUS
        self.stylus_mode = ''
        self.current_drawing = None
        self.drawing = False
        self.drawings = []
        self.stylus_modes_proxy = FlowProxyWidget(self)
        self.stylus_modes_proxy.setFlag(
            QGraphicsItem.ItemIgnoresTransformations, True)
        self.stylus_modes_proxy.setZValue(1001)
        self.stylus_modes_widget = FlowStylusModesWidget(self)
        self.stylus_modes_proxy.setWidget(self.stylus_modes_widget)
        self.scene().addItem(self.stylus_modes_proxy)
        self.set_stylus_proxy_pos()
        self.setAttribute(Qt.WA_TabletTracking)

        # DESIGN THEME
        Design.flow_theme_changed.connect(self.theme_changed)

        if config:
            config: dict

            # algorithm mode
            if config.keys().__contains__('algorithm mode'):
                if config['algorithm mode'] == 'data flow':
                    self.parent_script.widget.ui.algorithm_data_flow_radioButton.setChecked(
                        True)
                    self.algorithm_mode.mode_data_flow = True
                else:  # 'exec flow'
                    self.parent_script.widget.ui.algorithm_exec_flow_radioButton.setChecked(
                        True)
                    self.algorithm_mode.mode_data_flow = False

            # viewport update mode
            if config.keys().__contains__('viewport update mode'):
                if config['viewport update mode'] == 'sync':
                    self.parent_script.widget.ui.viewport_update_mode_sync_radioButton.setChecked(
                        True)
                    self.viewport_update_mode.sync = True
                else:  # 'async'
                    self.parent_script.widget.ui.viewport_update_mode_async_radioButton.setChecked(
                        True)
                    self.viewport_update_mode.sync = False

            node_instances = self.place_nodes_from_config(config['nodes'])
            self.connect_nodes_from_config(node_instances,
                                           config['connections'])
            if list(config.keys()).__contains__(
                    'drawings'
            ):  # not all (old) project files have drawings arr
                self.place_drawings_from_config(config['drawings'])
            self.undo_stack.clear()
Ejemplo n.º 5
0
    def __init__(self, params):
        super(NodeInstance, self).__init__()

        self.setFlags(QGraphicsItem.ItemIsSelectable
                      | QGraphicsItem.ItemIsMovable
                      | QGraphicsItem.ItemSendsScenePositionChanges)
        self.setAcceptHoverEvents(True)

        # GENERAL ATTRIBUTES

        # the constructor parameters are stored in a tuple to make the source code of custom NIs cleaner
        parent_node, flow, config = params

        self.parent_node = parent_node
        self.flow = flow
        self.movement_state = None
        self.movement_pos_from = None
        self.painted_once = False
        self.inputs = []
        self.outputs = []
        self.color = self.parent_node.color  # manipulated by self.animator
        # self.node_instance_painter = NodeInstancePainter(self)

        self.default_actions = {
            'remove': {
                'method': self.action_remove
            },
            'update shape': {
                'method': self.update_shape
            }
        }  # for context menus
        self.special_actions = {
        }  # only gets written in custom NodeInstance-subclasses
        self.personal_logs = []

        # 'initializing' will be set to False below. It's needed for the ports setup, to prevent shape updating stuff
        self.initializing = True

        self.temp_state_data = None
        self.init_config = config

        # UI
        self.shadow_effect = None
        self.width = -1
        self.height = -1

        self.title_label = TitleLabel(self)

        self.animator = NodeInstanceAnimator(self)  # needs self.title_label

        self.main_widget = None
        self.main_widget_proxy: FlowProxyWidget = None
        if self.parent_node.has_main_widget:
            self.main_widget = self.parent_node.main_widget_class(self)
            self.main_widget_proxy = FlowProxyWidget(self.flow)
            self.main_widget_proxy.setWidget(self.main_widget)

        # LOADING UI
        self.body_layout: QGraphicsLinearLayout = None
        self.inputs_layout: QGraphicsLinearLayout = None
        self.outputs_layout: QGraphicsLinearLayout = None
        self.layout: QGraphicsLinearLayout = self.setup_ui()
        self.widget = QGraphicsWidget(self)
        self.widget.setLayout(self.layout)

        # TOOLTIP
        if self.parent_node.description != '':
            self.setToolTip('<html><head/><body><p>' +
                            self.parent_node.description +
                            '</p></body></html>')
        self.setCursor(Qt.SizeAllCursor)

        # DESIGN THEME
        Design.flow_theme_changed.connect(self.theme_changed)
Ejemplo n.º 6
0
    def __init__(self, parent_node: Node, flow, config=None):
        super(NodeInstance, self).__init__()

        self.setFlags(QGraphicsItem.ItemIsSelectable | QGraphicsItem.ItemIsMovable |
                      QGraphicsItem.ItemSendsScenePositionChanges)
        self.setAcceptHoverEvents(True)

        # GENERAL ATTRIBUTES
        self.parent_node = parent_node
        self.flow = flow
        self.movement_state = None
        self.movement_pos_from = None
        self.inputs = []
        self.outputs = []

        self.default_actions = {'remove': {'method': self.action_remove,
                                           'data': 123},
                                'update shape': {'method': self.update_shape}}  # for context menus
        self.special_actions = {}  # only gets written in custom NodeInstance-subclasses
        self.personal_logs = []

        # 'initializing' will be set to False below. It's needed for the ports setup, to prevent shape updating stuff
        self.initializing = True

        self.temp_state_data = None


        # UI
        self.width = -1
        self.height = -1

        self.title_label = TitleLabel(self)

        self.main_widget = None
        self.main_widget_proxy: FlowProxyWidget = None
        if self.parent_node.has_main_widget:
            self.main_widget = self.parent_node.main_widget_class(self)
            self.main_widget_proxy = FlowProxyWidget(self.flow)
            self.main_widget_proxy.setWidget(self.main_widget)

        self.body_layout: QGraphicsLinearLayout = None
        self.inputs_layout: QGraphicsLinearLayout = None
        self.outputs_layout: QGraphicsLinearLayout = None
        self.layout: QGraphicsLinearLayout = self.setup_ui()
        self.widget = QGraphicsWidget(self)
        self.widget.setLayout(self.layout)



        # LOADING CONFIG
        if config:
            # self.setPos(config['position x'], config['position y'])
            self.setup_ports(config['inputs'], config['outputs'])
            if self.main_widget:
                try:
                    self.main_widget.set_data(config['main widget data'])
                except KeyError:
                    pass

            self.special_actions = self.set_special_actions_data(config['special actions'])
            self.temp_state_data = config['state data']
        else:
            self.setup_ports()


        # TOOLTIP
        if self.parent_node.description != '':
            self.setToolTip('<html><head/><body><p>'+self.parent_node.description+'</p></body></html>')
        self.setCursor(Qt.SizeAllCursor)

        self.initializing = False
Ejemplo n.º 7
0
    def __init__(self, parent_node: Node, flow, config=None):
        super(NodeInstance, self).__init__()

        self.setFlags(QGraphicsItem.ItemIsSelectable
                      | QGraphicsItem.ItemIsMovable
                      | QGraphicsItem.ItemSendsScenePositionChanges)
        self.setAcceptHoverEvents(True)

        # GENERAL ATTRIBUTES
        self.parent_node = parent_node
        self.flow = flow
        self.movement_state = None
        self.movement_pos_from = None
        self.inputs = []
        self.outputs = []
        self.main_widget = None
        self.main_widget_proxy: FlowProxyWidget = None
        self.default_actions = {
            'remove': {
                'method': self.action_remove,
                'data': 123
            },
            'compute shape': {
                'method': self.compute_content_positions
            }
        }  # for context menus
        self.gen_data_on_request = False
        self.personal_logs = []
        self.special_actions = {
        }  # only gets written in custom NodeInstance-subclasses - dynamic
        self.width = -1
        self.height = -1
        self.display_name_font = QFont('Poppins', 15) if parent_node.design_style == 'extended' else \
                                 QFont('K2D', 20, QFont.Bold, True)
        self.display_name_FM = QFontMetricsF(self.display_name_font)
        # self.port_label_font = QFont("Source Code Pro", 10, QFont.Bold, True)

        # 'initializing' will be set to False below. It's needed for the ports setup, to prevent shape updating stuff
        self.initializing = True

        self.temp_state_data = None

        if self.parent_node.has_main_widget:
            self.main_widget = self.parent_node.main_widget_class(self)
            self.main_widget_proxy = FlowProxyWidget(self.flow, self)
            self.main_widget_proxy.setWidget(self.main_widget)

        if config:
            # self.setPos(config['position x'], config['position y'])
            self.setup_ports(config['inputs'], config['outputs'])
            if self.main_widget:
                try:
                    self.main_widget.set_data(config['main widget data'])
                except KeyError:
                    pass

            self.special_actions = self.set_special_actions_data(
                config['special actions'])
            self.temp_state_data = config['state data']
        else:
            self.setup_ports()

        # TOOLTIP
        self.setToolTip(self.parent_node.description)
        self.setCursor(Qt.SizeAllCursor)

        self.initializing = False