Esempio n. 1
0
 def test_partition_helpers(self):
     test_in_exp = {
         'stuff.thing': 'stuff',
         'all/other/stuff.another': 'all/other/stuff',
         '/stuff/and/things': '/stuff/and/things'
     }
     for inp, exp in test_in_exp.items():
         result = nxt_path.node_path_from_attr_path(inp)
         self.assertEqual(exp, result)
     test_in_exp = {
         'stuff.thing': 'thing',
         'all/other/stuff.another': 'another',
         '/stuff/and/things': None
     }
     for inp, exp in test_in_exp.items():
         result = nxt_path.attr_name_from_attr_path(inp)
         self.assertEqual(exp, result)
     test_in_exp = {
         'all/other/stuff': 'stuff',
         '/stuff/and/things': 'things'
     }
     for inp, exp in test_in_exp.items():
         result = nxt_path.node_name_from_node_path(inp)
         self.assertEqual(exp, result)
     test_in_exp = {
         'all/other/stuff': 'all/other',
         '/stuff/and/things': '/stuff/and'
     }
     for inp, exp in test_in_exp.items():
         result = nxt_path.get_parent_path(inp)
         self.assertEqual(exp, result)
     test_in_exp = {
         '/all/other/stuff': '/all',
         '/stuff/and/things': '/stuff'
     }
     for inp, exp in test_in_exp.items():
         result = nxt_path.get_root_path(inp)
         self.assertEqual(exp, result)
    def update_from_model(self):
        """Sync the visible state of this node with the model."""
        # Shortened var names
        comp = self.model.comp_layer
        node_path = self.node_path
        # update position
        if nxt_path.get_parent_path(node_path) == nxt_path.WORLD:
            pos = self.model.get_node_pos(node_path)
            self.setPos(pos[0], pos[1])
        self.is_real = self.model.node_exists(node_path)
        self.is_proxy = self.model.get_node_is_proxy(node_path)
        self.collapse_state = self.model.get_node_collapse(
            self.node_path, comp)
        self.node_enabled = self.model.get_node_enabled(self.node_path)
        self.update_color()
        self.update_build_focus()
        self._update_collapse()
        self.error_list = self.model.get_node_error(node_path, comp)
        self.update_fonts()
        # update exec plugs
        # update attributes
        # 0 = no attributes
        # 1 = only local attributes
        # 2 = local and instanced attributes
        # 3 = local, instanced, and inherited attributes
        attr_display_state = self.model.get_attr_display_state(node_path)
        if attr_display_state == 1:
            attr_names = self.model.get_node_local_attr_names(node_path, comp)
        elif attr_display_state == 2:
            local_attr_names = self.model.get_node_local_attr_names(
                node_path, comp)
            inst_attrs = self.model.get_node_instanced_attr_names(
                node_path, comp)
            attr_names = set(local_attr_names + inst_attrs)
        elif attr_display_state == 3:
            attr_names = self.model.get_node_attr_names(node_path, comp)
        else:
            attr_names = []
        removed_attr_names = set(self.user_attr_names).difference(attr_names)
        self.user_attr_names = sorted(attr_names)

        for removed_name in removed_attr_names:
            if removed_name in self._attribute_draw_details:
                self._attribute_draw_details.pop(removed_name)
            if removed_name not in self._attr_plug_graphics:
                continue
            plug_grpahics = self._attr_plug_graphics.pop(removed_name)
            plug = plug_grpahics.get('in_plug')
            if plug:
                self.scene().removeItem(plug)
            plug = plug_grpahics.get('out_plug')
            if plug:
                self.scene().removeItem(plug)
        self.calculate_attribute_draw_details()
        for key, value in self._attribute_draw_details.items():
            in_plug = value.get('in_plug')
            if in_plug:
                in_plug.update()

            out_plug = value.get('out_plug')
            if out_plug:
                out_plug.update()

        self.is_break = self.model.get_is_node_breakpoint(node_path, comp)
        self.is_start = self.model.get_is_node_start(node_path, comp)
        sp_attr = INTERNAL_ATTRS.START_POINT
        self.start_color = self.model.get_node_attr_color(
            node_path, sp_attr, comp)

        if attr_display_state == 1:
            self.attr_dots = [True, False, False]
        elif attr_display_state == 2:
            self.attr_dots = [True, True, False]
        elif attr_display_state == 3:
            self.attr_dots = [True, True, True]
        else:
            self.attr_dots = [False, False, False]

        self.update()
    def draw_title(self, painter, lod=1.):
        """Draw title of the node. Called exclusively in paint.

        :param painter: painter from paint.
        :type painter: QtGui.QPainter
        """
        # draw bg
        painter.setPen(QtCore.Qt.NoPen)
        bg = painter.background()
        bgm = painter.backgroundMode()
        if self.error_item:
            self.scene().removeItem(self.error_item)
            self.error_item.deleteLater()
        self.error_item = None
        if self.is_real:
            painter.setBackgroundMode(QtCore.Qt.OpaqueMode)
        else:
            painter.setBackgroundMode(QtCore.Qt.TransparentMode)
            [c.setAlphaF(self.color_alpha) for c in self.colors]
        color_count = len(self.colors)
        color_band_width = 10
        for i in range(color_count):
            color = self.colors[i]
            if self.is_proxy:
                painter.setBackground(color.darker(self.dim_factor))
                brush = QtGui.QBrush(color.darker(self.dim_factor * 2),
                                     QtCore.Qt.FDiagPattern)
                painter.setBrush(brush)
            else:
                painter.setBrush(color.darker(self.dim_factor))
            # Top Opinion
            if i + 1 == color_count:
                remaining_width = self.max_width - (i * color_band_width)
                painter.drawRect(0, 0, remaining_width, self.title_rect_height)
            # Lower Opinions
            else:
                x_pos = self.max_width - (i + 1) * color_band_width
                painter.drawRect(x_pos, 0, color_band_width,
                                 self.title_rect_height)
        painter.setBackground(bg)
        painter.setBackgroundMode(bgm)
        # draw exec plugs
        exec_attr = nxt_node.INTERNAL_ATTRS.EXECUTE_IN
        exec_in_pos = self.get_attr_in_pos(exec_attr, scene=False)
        exec_radius = self.EXEC_PLUG_RADIUS
        if nxt_path.get_parent_path(self.node_path) == nxt_path.WORLD:
            if self.is_start:
                color = self.start_color
            elif self.is_break:
                color = QtCore.Qt.red
            else:
                color = QtCore.Qt.white
            if not self.exec_in_plug:
                is_break = self.is_break
                if self.is_start:
                    is_break = False
                self.exec_in_plug = NodeGraphicsPlug(pos=exec_in_pos,
                                                     radius=exec_radius,
                                                     color=color,
                                                     is_exec=True,
                                                     is_input=True,
                                                     is_break=is_break,
                                                     is_start=self.is_start)
                self.exec_in_plug.setParentItem(self)
            else:
                self.exec_in_plug.color = QtGui.QColor(color)
                self.exec_in_plug.is_break = self.is_break
                self.exec_in_plug.is_start = self.is_start
                self.exec_in_plug.setPos(exec_in_pos)
                self.exec_in_plug.update()

            out_pos = self.get_attr_out_pos(exec_attr, scene=False)
            if not self.exec_out_plug:
                self.exec_out_plug = NodeGraphicsPlug(pos=out_pos,
                                                      radius=exec_radius,
                                                      color=QtCore.Qt.white,
                                                      is_exec=True,
                                                      is_input=False)
                self.exec_out_plug.setParentItem(self)
            else:
                self.exec_out_plug.setPos(out_pos)
        else:
            if not self.exec_in_plug and self.is_break:
                self.exec_in_plug = NodeGraphicsPlug(pos=exec_in_pos,
                                                     radius=exec_radius,
                                                     color=QtCore.Qt.red,
                                                     is_exec=True,
                                                     is_input=True,
                                                     is_break=self.is_break)
                self.exec_in_plug.setParentItem(self)
            elif self.exec_in_plug and not self.is_break:
                self.scene().removeItem(self.exec_in_plug)
                self.exec_in_plug = None

            if self.exec_out_plug:
                self.scene().removeItem(self.exec_out_plug)
                self.exec_out_plug = None
        if lod > MIN_LOD:
            # draw attr dots
            offset = -6
            for fill in self.attr_dots:
                painter.setBrush(QtCore.Qt.white)
                if fill:
                    painter.setBrush(QtCore.Qt.white)
                else:
                    painter.setBrush(QtCore.Qt.NoBrush)
                dots_color = QtGui.QColor(QtCore.Qt.white).darker(
                    self.dim_factor)
                painter.setPen(QtGui.QPen(dots_color, 0.5))
                dot_x = self.max_width - 15
                dot_y = (self.title_rect_height / 2) + offset
                painter.drawEllipse(QtCore.QPointF(dot_x, dot_y), 2, 2)
                offset += 6

        # draw title

        painter.setFont(self.title_font)
        title_str = nxt_path.node_name_from_node_path(self.node_path)
        font_metrics = QtGui.QFontMetrics(self.title_font)
        width = self.max_width - 40
        if self.error_list:
            width -= 20
        if lod > MIN_LOD:
            painter.setPen(
                QtGui.QColor(QtCore.Qt.white).darker(self.dim_factor))
            if not self.node_enabled:
                painter.setPen(QtGui.QColor(QtCore.Qt.white).darker(150))
            title = font_metrics.elidedText(title_str, QtCore.Qt.ElideRight,
                                            width)
            painter.drawText(15, 0, self.max_width - 15,
                             self.title_rect_height, QtCore.Qt.AlignVCenter,
                             title)
        else:
            painter.setBrush(
                QtGui.QColor(QtCore.Qt.white).darker(self.dim_factor))
            if not self.node_enabled:
                painter.setBrush(QtGui.QColor(QtCore.Qt.white).darker(150))
            proxy_rect = font_metrics.boundingRect(title_str)
            r_width = proxy_rect.width() * .8
            height = proxy_rect.height()
            painter.drawRect(15, height * .8, min(r_width, width), height * .2)

        if lod > MIN_LOD:
            # draw error
            if self.error_list:
                pos = QtCore.QPointF(self.max_width - 45,
                                     self.title_rect_height / 4)
                error_item = ErrorItem(font=QtGui.QFont('Roboto', 16, 75),
                                       pos=pos,
                                       text='!')
                error_item.setParentItem(self)
                error_item.setZValue(50)
                self.error_item = error_item

        # draw collapse state arrow
        for arrow in self.collapse_arrows:
            self.scene().removeItem(arrow)
        if lod > MIN_LOD:
            self.collapse_arrows = []
            # TODO calculation needed arrows should be done outside drawing

            if self.collapse_state:
                des_colors = self.model.get_descendant_colors(self.node_path)
                filled = self.model.has_children(self.node_path)
                if not filled:
                    des_colors = [QtCore.Qt.white]
                elif not des_colors:
                    disp = self.model.comp_layer
                    des_colors = [
                        self.model.get_node_color(self.node_path, disp)
                    ]
                i = 0
                num = len(des_colors)
                for c in des_colors:
                    arrow = CollapseArrow(self, filled=filled, color=c)
                    arrow_width = arrow.width * 1.1
                    center_offset = (arrow_width * (num * .5) -
                                     arrow_width * .5)
                    cur_offset = (i * arrow_width)
                    pos = ((self.max_width * .5) + center_offset - cur_offset)
                    arrow.setPos(pos, self.boundingRect().height())
                    self.collapse_arrows += [arrow]
                    i += 1