def drawTokenTag(self, br: QRectF, painter: 'QPainter'):
        """
		This is a helper function for the paint function.
		It renders "Token Tags" in the corners of the GUI Components displayed in the TGUIM View.
		Token Tags show how many Tokens are associated with the associated component.

		:param br: The bounding rectangle of the component.
		:type br: QRectF
		:param painter: A QPainter object.
		:type painter: QPainter
		:return: None
		:rtype: NoneType
		"""
        if br.width() >= ComponentGraphics.TITLEBAR_H:
            token_count = str(self.getNumberOfTokens())

            ttX = br.x() + br.width() - ComponentGraphics.TITLEBAR_H
            ttY = br.y()
            ttWidth = ComponentGraphics.TITLEBAR_H
            ttHeight = ComponentGraphics.TITLEBAR_H

            rectBox = QRectF(ttX, ttY, ttWidth, ttHeight)
            tokenTagFont = QFont("Times", 10)
            painter.setFont(tokenTagFont)
            painter.setBrush(QColor(255, 0, 0, 127))
            #painter.drawRect(rectBox)
            painter.drawEllipse(rectBox.center(), ttWidth / 2 - 1,
                                ttHeight / 2 - 1)
            painter.setBrush(QColor(100, 200, 255))
            fm = QFontMetricsF(tokenTagFont)
            pixelsWide = fm.width(token_count)
            pixelsHigh = fm.height()
            painter.drawText(ttX + ttWidth / 2 - pixelsWide / 2,
                             ttY + ttHeight / 2 + pixelsHigh / 4, token_count)
Esempio n. 2
0
    def styleChange(self):
        super().styleChange()
        style = self.style()

        # Text item ----------------------------------------------------------------------------------------------------
        self._text_item.setFont(style.font(Style.MessageTextFont))
        self._text_item.setMaximumWidth(style.pixelMetric(Style.MessageTextLength))

        # Position
        text_metrics = QFontMetricsF(self._text_item.font())
        icon_size = style.pixelMetric(Style.MessageIconSize)
        margin = style.pixelMetric(Style.MessageIconTextMargin)

        self._text_item.setPos(icon_size + margin, 0)
        self._text_item.moveBy(0, text_metrics.capHeight() / 2)
        self._text_item.moveBy(0, icon_size / 2)

        # Icon item ----------------------------------------------------------------------------------------------------
        icon_renderer = self._icon_item.renderer()
        if icon_renderer is None:  # No icon set
            scale = 1
        else:
            scale = icon_size / icon_renderer.defaultSize().width()

        self._icon_item.setScale(scale)
Esempio n. 3
0
    def adjust(self):
        """Adjust the item's geometry in response to changes."""
        metrics = QFontMetricsF(self.font())

        # Get bounding rectangle for full text
        self._bounding_rect = metrics.boundingRect(self.text())

        # Constrain by maximum width
        if self.maximumWidth() is not None:
            self._bounding_rect.setWidth(self.maximumWidth())

        # Compute elided text
        self._elided_text = metrics.elidedText(self.text(), self.elideMode(),
                                               self.boundingRect().width())

        # Get bounding rectangle for elided text
        self._bounding_rect = metrics.boundingRect(self.elidedText())
        # It seems that for small characters like "..." the bounding rect returned is too small. Adjust it by a small
        # value.
        metrics_correction = px(1 / 72)
        self._bounding_rect.adjust(-metrics_correction, 0, metrics_correction,
                                   0)

        # Move origin point according to the alignment
        if self.alignMode() & Qt.AlignLeft:
            self._bounding_rect.moveLeft(0)
        elif self.alignMode() & Qt.AlignRight:
            self._bounding_rect.moveRight(0)
        else:
            self._bounding_rect.moveLeft(-self._bounding_rect.width() / 2)

        # Set background rect
        self.background.setRect(self.boundingRect())
Esempio n. 4
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
Esempio n. 5
0
    def _manage_font_cache(real_font, font, metrics, height, width, ascent):
        if real_font == font:
            return font, metrics, height, width, ascent

        metrics = QFontMetricsF(real_font)
        height = metrics.height()
        width = metrics.width('A')
        ascent = metrics.ascent()
        return real_font, metrics, height, width, ascent
	def __init__(self, parent):
		QItemDelegate.__init__(self, parent)

		self.font = binaryninjaui.getMonospaceFont(parent)
		self.font.setKerning(False)
		self.baseline = QFontMetricsF(self.font).ascent()
		self.char_width = binaryninjaui.getFontWidthAndAdjustSpacing(self.font)[0]
		self.char_height = QFontMetricsF(self.font).height()
		self.char_offset = binaryninjaui.getFontVerticalOffset()

		self.expected_char_widths = [10, 32]
    def styleChange(self):
        super().styleChange()
        self.prepareGeometryChange()
        style = self.style()

        margin = style.pixelMetric(Style.ConnectionStemTextMargin)
        metrics = QFontMetricsF(self._text_item.font())

        self._stem_item.setLine(QLineF(self.stemRoot(), self.stemTip()))
        self._text_item.setPos(self.stemTip().x() + margin,
                               metrics.capHeight() / 2)
Esempio n. 8
0
    def __init__(self, parent_port_instance, parent_node_instance):
        super(PortInstanceLabel, self).__init__(parent_node_instance)
        self.parent_port_instance = parent_port_instance
        self.parent_node_instance = parent_node_instance

        self.font = QFont("Source Code Pro", 10, QFont.Bold)
        font_metrics = QFontMetricsF(self.font)
        self.width = font_metrics.width(
            get_longest_line(self.parent_port_instance.label_str))
        self.height = font_metrics.height() * (
            self.parent_port_instance.label_str.count('\n') + 1)
        self.port_local_pos = None
    def init_font_config(self):
        self.disasm_font = QFont("DejaVu Sans Mono", 10)
        font_metrics = QFontMetricsF(self.disasm_font)
        self.disasm_font_height = font_metrics.height()
        self.disasm_font_width = font_metrics.width('A')
        self.disasm_font_ascent = font_metrics.ascent()

        self.symexec_font = QFont("DejaVu Sans Mono", 10)
        font_metrics = QFontMetricsF(self.symexec_font)
        self.symexec_font_height = font_metrics.height()
        self.symexec_font_width = font_metrics.width('A')
        self.symexec_font_ascent = font_metrics.ascent()
Esempio n. 10
0
    def __init__(self, parent_port_instance, parent_node_instance):
        super(PortInstanceLabel, self).__init__(parent_node_instance)
        self.setGraphicsItem(self)

        self.parent_port_instance = parent_port_instance
        self.parent_node_instance = parent_node_instance

        self.font = QFont("Source Code Pro", 10, QFont.Bold)
        font_metrics = QFontMetricsF(
            self.font)  # approximately! the designs can use different fonts
        self.width = font_metrics.width(
            get_longest_line(self.parent_port_instance.label_str))
        self.height = font_metrics.height() * (
            self.parent_port_instance.label_str.count('\n') + 1)
        self.port_local_pos = None
Esempio n. 11
0
    def __init__(self, parent_port_instance, parent_node_instance):
        super(PortInstanceLabel, self).__init__(parent_node_instance)
        self.setGraphicsItem(self)

        self.parent_port_instance = parent_port_instance
        self.parent_node_instance = parent_node_instance

        self.font = QFont("Source Code Pro", 10, QFont.Bold)
        font_metrics = QFontMetricsF(self.font)
        self.width = font_metrics.width(
            get_longest_line(self.parent_port_instance.label_str))
        self.height = font_metrics.height() * (
            self.parent_port_instance.label_str.count('\n') + 1)
        # print('self.height:', self.height)
        # self.setSizePolicy(QSizePolicy.Minimum, QSizePolicy.Minimum)
        self.port_local_pos = None
Esempio n. 12
0
    def drawText(self, painter: QPainter) -> None:
        painter.save()
        painter.setPen(Qt.NoPen)

        font: QFont = QFont()
        font.setBold(True)
        font.setPointSize(10)
        painter.setFont(font)

        now: QDateTime = QDateTime.currentDateTime()
        fm: QFontMetricsF = QFontMetricsF(font)
        textList: List[AnyStr] = [
            now.toString("MM月dd日yyyy"),
            now.toString("hh:mm:ss.zzz")
        ]

        # 绘制文本路径
        textPath: QPainterPath = QPainterPath()
        textPath.addText(-fm.width(textList[0]) / 2.0, -fm.lineSpacing() / 2.0,
                         font, textList[0])
        textPath.addText(-fm.width(textList[1]) / 2.0,
                         fm.lineSpacing() / 2.0, font, textList[1])

        strokeColor: QColor = self.__textColor.light(80)
        strokeColor.setAlphaF(0.2)
        painter.strokePath(
            textPath,
            QPen(strokeColor, self.__shadowWidth, Qt.SolidLine, Qt.RoundCap,
                 Qt.RoundJoin))
        painter.setBrush(self.__textColor)
        painter.drawPath(textPath)

        painter.restore()
Esempio n. 13
0
 def __call__(self, point_size):
     qt_font = font_db.font(self.name, "Roman", point_size)
     return Font(
         qt_font,
         QFontMetricsF(qt_font, self.renderer.writer),
         self.renderer.writer.resolution(),
     )
Esempio n. 14
0
    def __init__(self, parent_node_instance):
        super(TitleLabel, self).__init__(parent_node_instance)

        self.setGraphicsItem(self)

        self.parent_node_instance: NodeInstance = parent_node_instance
        self.title_str = self.parent_node_instance.parent_node.title
        self.font = QFont('Poppins', 15) if self.parent_node_instance.parent_node.design_style == 'extended' else \
                                 QFont('K2D', 20, QFont.Bold, True)
        self.fm = QFontMetricsF(self.font)

        self.width = self.fm.width(get_longest_line(self.title_str))
        self.height = self.fm.height() * 0.7 * (self.title_str.count('\n') + 1)

        self.color = QColor(30, 43, 48)
        self.pen_width = 1.5
        self.hovering = False  # whether the mouse is hovering over the parent NI (!)
Esempio n. 15
0
    def styleChange(self):
        self.prepareGeometryChange()
        style = self.style()

        # Size and Frame
        frame_width = style.pixelMetric(Style.NodeWidth)
        self._size.setWidth(frame_width)
        self._body_item.setPen(style.framePen(self.palette()))

        path = QPainterPath()
        path.addRoundedRect(QRectF(QPointF(), self.size()),
                            style.pixelMetric(Style.NodeFrameCornerRadius),
                            style.pixelMetric(Style.NodeFrameCornerRadius))
        self._body_item.setPath(path)

        # Title item
        title_font = style.font(Style.NodeTitleFont)
        title_metrics = QFontMetricsF(title_font)

        padding = style.pixelMetric(Style.NodeFrameTextPadding)

        self._title_item.setFont(title_font)
        self._title_item.setPos(padding, padding)
        self._title_item.moveBy(0, title_metrics.capHeight())
        self._title_item.setMaximumWidth(frame_width - padding * 2)

        # Divider item
        div_margin = style.pixelMetric(Style.NodeDividerTextMargin)
        div_voffset = padding + title_metrics.capHeight(
        ) + title_metrics.descent() + div_margin

        self._divider.setLine(0, div_voffset, frame_width, div_voffset)
        self._divider.setPen(style.framePen(self.palette()))

        # Description item
        self._description_item.setFont(style.font(Style.NodeDescriptionFont))
        self._description_item.setPos(padding, div_voffset + div_margin)
        self._description_item.setFrame(
            QRectF(
                QPointF(0, 0),
                QSizeF(
                    px(frame_width) - padding * 2,
                    (px(self.size().height()) - padding) -
                    (div_voffset + padding))))
Esempio n. 16
0
    def __init__(self, parent_node_instance):
        super(TitleLabel, self).__init__(parent_node_instance)

        self.setGraphicsItem(self)

        self.parent_node_instance = parent_node_instance
        self.title_str = self.parent_node_instance.parent_node.title
        font = QFont('Poppins', 15) if self.parent_node_instance.parent_node.design_style == 'extended' else \
            QFont('K2D', 20, QFont.Bold, True)  # should be quite similar to every specific font chosen by the painter
        fm = QFontMetricsF(font)

        # approximately!
        self.width = fm.width(get_longest_line(self.title_str) + '___')
        self.height = fm.height() * 0.7 * (self.title_str.count('\n') + 1)

        self.color = QColor(30, 43, 48)
        self.pen_width = 1.5
        self.hovering = False  # whether the mouse is hovering over the parent NI (!)

        # Design.flow_theme_changed.connect(self.theme_changed)
        self.update_design()
    def paint(self, painter: QPainter, option: QStyleOptionGraphicsItem,
              index: QWidget) -> None:
        """
		Paint the graphics of the action wrapper including action name, number, and ports.

		:param painter: This draws the widget.
		:type painter: QPainter
		:param option: Option for the style of graphic.
		:type option: QStyleOptionGraphicsItem
		:param index: Index for the painted graphic.
		:type index: QWidget
		:return: None
		:rtype: NoneType
		"""
        ActionGraphics.paint(self, painter, option, index)

        # Get dimensions of the action
        x, y, width, height = self.getActionRect(self._action.getInputPorts(),
                                                 self._action.getOutputPorts())

        # Draw the number tag.
        number = str(
            self._action.getParent().getActions().index(self._action) + 1)
        offset = 5
        radius = 15
        size = ActionGraphics.H_SPACE / 2 - offset * 2
        painter.setBrush(QColor(29, 110, 37))
        painter.drawRoundedRect(QRectF(x + offset, y + offset, size, size),
                                radius, radius)
        painter.setPen(ActionWrapperGraphics.TAG_TEXT_COLOR)
        painter.setBrush(ActionWrapperGraphics.TAG_TEXT_COLOR)
        painter.setFont(ActionWrapperGraphics.TAG_FONT)
        fm = QFontMetricsF(ActionWrapperGraphics.TAG_FONT)
        pixelsWide = fm.width(number)
        pixelsHigh = fm.height()
        # TODO: fix text positioning - font metrics aren't working well
        painter.drawText(x + offset + size / 2 - pixelsWide,
                         y + offset + size / 2 + pixelsHigh / 2, number)

        # Draw the name of the action
        painter.setPen(ActionWrapperGraphics.NAME_TEXT_COLOR)
        painter.setBrush(ActionWrapperGraphics.NAME_TEXT_COLOR)
        painter.setFont(ActionWrapperGraphics.NAME_FONT)
        fm = QFontMetricsF(ActionWrapperGraphics.NAME_FONT)
        br = fm.boundingRect(self._action.getName())
        # TODO: fix text positioning - font metrics aren't working well
        t = fm.elidedText(self._action.getName(), Qt.ElideRight,
                          self._width - offset * 2)
        painter.drawText(x + offset, br.height(), t)
Esempio n. 18
0
    def paintEvent(self, ev):
        """
        Manually implemented paint event

        :param ev: the QT paint event
        :return:
        """
        h = self.height()
        w = self.width()
        p = QPainter(self)
        p.setClipRect(ev.region().boundingRect())
        pen = QPen(QColor(0, 0, 0))
        pen.setWidth(4)
        ls = QFontMetricsF(p.font()).lineSpacing()
        for idx, t in enumerate(sorted(list(self._loadData.keys()))):
            y = 10 + idx * ls
            pen.setColor(ThreadToColor.singleton.get(t))
            p.setPen(pen)
            p.drawLine(QLineF(15, y, 15 + 15, y))
            pen.setColor(QColor(0, 0, 0))
            p.setPen(pen)
            p.drawText(QPointF(35, y), t)

        if len(self._loadData) > 0:
            right = max([
                polygon[polygon.count() - 1].x()
                for _, polygon in self._loadData.items()
            ])
        else:
            right = 0.0
        p.translate(w - 10 - right * 20, h - 10)
        p.scale(
            20, -(h - 20)
        )  # x direction: 20 pixels per second, y direction: spread between 10 and h-10
        topleft = p.transform().inverted()[0].map(QPointF(10, 10))
        pen.setWidthF(0)
        pen.setCosmetic(True)
        left = topleft.x()
        p.setRenderHint(QPainter.Antialiasing, True)
        p.setPen(pen)
        p.drawLine(QLineF(left, 0, right, 0))
        p.drawLine(QLineF(left, 0, left, 1))
        idx = 0
        for t, polygon in self._loadData.items():
            pen.setColor(ThreadToColor.singleton.get(t))
            p.setPen(pen)
            p.drawPolyline(polygon)
        p.end()
Esempio n. 19
0
    def _init_font_interface(cls):
        '''
        static init interface, font family and font size have to be
        set first. This function does not have to be called.
        '''

        # should move to main
        # workaround
        if cls._app is None:
            try:
                cls._app = QApplication(sys.argv)
            except RuntimeError:
                cls._app = False

        if (cls.font_size is not None and cls.font_family is not None):
            cls.font = QFont(cls.font_family, cls.font_size)
            cls.font_metrics = QFontMetricsF(cls.font, QSvgGenerator())
Esempio n. 20
0
    def __init__(self, parent, name):
        QWidget.__init__(self, parent)
        DockContextHandler.__init__(self, self, name)
        self.actionHandler = UIActionHandler()
        self.actionHandler.setupActionHandler(self)

        font = getMonospaceFont(self)
        fm = QFontMetricsF(font)

        table_layout = QVBoxLayout()
        self.table = QTableView()
        self.table.setFont(font)
        self.table.setSelectionBehavior(QAbstractItemView.SelectRows)
        self.table.verticalHeader().hide()
        self.table.verticalHeader().setSectionResizeMode(QHeaderView.Fixed)
        self.table.horizontalHeader().setSectionResizeMode(QHeaderView.Stretch)

        # sorting
        self.table.setSortingEnabled(True)
        self.table.horizontalHeader().setSortIndicator(0, QtCore.Qt.AscendingOrder)

        data = []
        self.model = TableModel(data)
        self.table.setModel(self.model)
        table_layout.addWidget(self.table)

        layout = QVBoxLayout()
        layout.addLayout(table_layout)
        self.setLayout(layout)

        # init double click action
        self.table.doubleClicked.connect(self._ui_entry_double_click)
        # init right click menu
        self.ctx_menu = QMenu()
        self._action_patch = QAction("Invert Branch", None)
        self.ctx_menu.addAction(self._action_patch)
        self.setContextMenuPolicy(Qt.CustomContextMenu)
        self.customContextMenuRequested.connect(self._ui_table_ctx_menu_handler)

        self.bv = None
        self.filename = None
        self.do_sync = True
Esempio n. 21
0
    def __init__(self,
                 port: 'Port',
                 parent: QGraphicsItem = None,
                 menuEnabled: bool = True):
        """
		Constructs a portGraphics object for the given Port object.
		
		:param port: The port for which this graphics item represents.
		:type port: Port
		:param parent: A QGraphicsItem (probably an actionGraphics object)
		:type parent: QGraphicsItem
		:param menuEnabled: If true, a context menu will be shown on right-click.
		:type menuEnabled: bool
		"""
        QGraphicsItem.__init__(self, parent)
        self.setAcceptDrops(True)
        self.setFlag(QGraphicsItem.ItemIsSelectable)
        self._port = port
        self._menuEnabled = menuEnabled
        self.menu = PortMenu()

        # If port is required and it's an input, make the border thicker
        if not self._port.isOptional() and self._port in self._port.getAction(
        ).getInputPorts():
            self.borderWidth = PortGraphics.REQUIRED_PEN_WIDTH
        else:
            self.borderWidth = PortGraphics.OPTIONAL_PEN_WIDTH

        # show port name and type
        if self._menuEnabled:
            fm = QFontMetricsF(PortGraphics.NAME_FONT)
            name = fm.elidedText(self._port.getName(), Qt.ElideRight,
                                 PortGraphics.SIDE_HEIGHT)
            self.nameItem = QGraphicsTextItem(name, self)
            self.nameItem.setFont(PortGraphics.NAME_FONT)
            self.nameItem.setRotation(90)
            self.nameItem.setPos(PortGraphics.WIDTH / 2 + 5,
                                 -PortGraphics.TOTAL_HEIGHT / 2)

            fm = QFontMetricsF(PortGraphics.TYPE_FONT)
            t = fm.elidedText(self._port.getDataType().__name__, Qt.ElideRight,
                              PortGraphics.SIDE_HEIGHT)
            self.typeItem = QGraphicsTextItem(t, self)
            self.typeItem.setFont(PortGraphics.TYPE_FONT)
            self.typeItem.setRotation(90)
            self.typeItem.setPos(5, -PortGraphics.TOTAL_HEIGHT / 2)
Esempio n. 22
0
	def __init__(self):
		ptrs.append(self)
		self.windowMain = wrapInstance(long(OpenMayaUI_v1.MQtUtil.mainWindow()), QMainWindow)
		super(ToolSeq_Formula, self).__init__(self.windowMain)

		self.window = ToolSeq_Formula.qUiLoader.load(ToolSeq_Formula.userScriptDir + 'ToolSeq_Formula.ui', self)
		self.window.destroyed.connect(lambda: ptrs_remove(self))
		self.window.setWindowFlags(self.window.windowFlags() & ~Qt.WindowMinMaxButtonsHint)
		self.window.setAttribute(Qt.WA_DeleteOnClose)
		for qComboBox in self.window.findChildren(QComboBox):
			qComboBox.setItemDelegate(QStyledItemDelegate(qComboBox))
		with open(ToolSeq_Formula.userScriptDir + 'ToolSeq.qss', 'r') as fileStyleSheet:
			self.window.setStyleSheet(fileStyleSheet.read())

		font = QFont('Consolas', 9)
		font.setStyleHint(QFont.Monospace)
		self.window.Text_PreFormula.setFont(font)
		self.window.Text_Formula.setFont(font)
		fontTab = QFontMetricsF(font).horizontalAdvance(' ') * 4
		self.window.Text_PreFormula.setTabStopDistance(fontTab)
		self.window.Text_Formula.setTabStopDistance(fontTab)

		self.window.Text_PreFormula.setPlainText(ToolSeq_Formula.preFormulas[11])
		self.window.Text_Formula.setPlainText(ToolSeq_Formula.formulas[11])

		self.window.Widget_Shape.installEventFilter(self)
		self.window.Check_VariableN.toggled.connect(self.Event_VariableN)
		self.window.Button_Fill.installEventFilter(self)
		self.window.Button_Formulate.installEventFilter(self)

		self.window.show()
		wMax = max(self.window.Label_1.width(), self.window.Label_2.width())
		self.window.Label_1.setFixedWidth(wMax)
		self.window.Label_2.setFixedWidth(wMax)

		maya_cmds.loadPlugin('ToolSeq_Formula.py', quiet=True)
Esempio n. 23
0
    def init_font_config(self):
        self.ui_default_font = QGuiApplication.font()

        self.disasm_font = QFont("DejaVu Sans Mono", 10)
        self.disasm_font_metrics = QFontMetricsF(self.disasm_font)
        self.disasm_font_height = self.disasm_font_metrics.height()
        self.disasm_font_width = self.disasm_font_metrics.width('A')
        self.disasm_font_ascent = self.disasm_font_metrics.ascent()

        self.symexec_font = QFont("DejaVu Sans Mono", 10)
        self.symexec_font_metrics = QFontMetricsF(self.symexec_font)
        self.symexec_font_height = self.symexec_font_metrics.height()
        self.symexec_font_width = self.symexec_font_metrics.width('A')
        self.symexec_font_ascent = self.symexec_font_metrics.ascent()

        self.code_font = QFont("Source Code Pro", 10)
        self.code_font_metrics = QFontMetricsF(self.code_font)
        self.code_font_height = self.code_font_metrics.height()
        self.code_font_width = self.code_font_metrics.width('A')
        self.code_font_ascent = self.code_font_metrics.ascent()
class TitleLabel(QGraphicsWidget):
    def __init__(self, parent_node_instance):
        super(TitleLabel, self).__init__(parent_node_instance)

        self.setGraphicsItem(self)

        self.parent_node_instance = parent_node_instance
        self.title_str = self.parent_node_instance.parent_node.title
        self.font = QFont('Poppins', 15) if self.parent_node_instance.parent_node.design_style == 'extended' else \
            QFont('K2D', 20, QFont.Bold, True)
        self.fm = QFontMetricsF(self.font)

        self.width = self.fm.width(get_longest_line(self.title_str)+'___')
        self.height = self.fm.height() * 0.7 * (self.title_str.count('\n') + 1)

        self.color = QColor(30, 43, 48)
        self.pen_width = 1.5
        self.hovering = False  # whether the mouse is hovering over the parent NI (!)

        # Design.flow_theme_changed.connect(self.theme_changed)
        self.update_design()

    def boundingRect(self):
        return QRectF(QPointF(0, 0), self.geometry().size())

    def setGeometry(self, rect):
        self.prepareGeometryChange()
        QGraphicsLayoutItem.setGeometry(self, rect)
        self.setPos(rect.topLeft())

    def sizeHint(self, which, constraint=...):
        return QSizeF(self.width, self.height)

    def paint(self, painter, option, widget=None):
        pen = QPen(self.color)
        pen.setWidth(self.pen_width)

        painter.setPen(pen)
        painter.setFont(self.font)

        text_rect = self.boundingRect()
        text_rect.setTop(text_rect.top()-7)

        if self.design_style() == 'extended':
            painter.drawText(text_rect, Qt.AlignTop, self.title_str)
        elif self.design_style() == 'minimalistic':
            painter.drawText(text_rect, Qt.AlignTop | Qt.AlignHCenter, self.title_str)

    def design_style(self):
        return self.parent_node_instance.parent_node.design_style

    def set_NI_hover_state(self, hovering: bool):
        self.hovering = hovering
        self.update_design()
    
    def theme_changed(self, new_theme):
        """Gets called from the parent node instance because the order of the different updates matters.""" # not working yet
        self.update_design()

    def update_design(self):
        theme = Design.flow_theme

        if self.design_style() == 'extended':
            if theme == 'dark std':
                if self.hovering:
                    self.color = self.parent_node_instance.color.lighter()
                    self.pen_width = 2
                else:
                    self.color = QColor(30, 43, 48)
                    self.pen_width = 1.5
            elif theme == 'dark tron' or theme == 'ghostly':
                if self.hovering:
                    self.color = self.parent_node_instance.color.lighter()
                else:
                    self.color = self.parent_node_instance.color
                self.pen_width = 2
            elif theme == 'blender':
                self.color = QColor('#ffffff')
        elif self.design_style() == 'minimalistic':
            if theme == 'dark std':
                if self.hovering:
                    self.color = self.parent_node_instance.color.lighter()
                    self.pen_width = 1.5
                else:
                    self.color = QColor(30, 43, 48)
                    self.pen_width = 1.5
            elif theme == 'dark tron' or theme == 'ghostly' or theme == 'blender':
                self.color = self.parent_node_instance.color
                self.pen_width = 2

        self.update()


    # ANIMATION STUFF
    def get_color(self):
        return self.color

    def set_color(self, val):
        self.color = val
        QGraphicsItem.update(self)

    p_color = Property(QColor, get_color, set_color)
Esempio n. 25
0
 def setUp(self):
     super(QFontMetricsFTest, self).setUp()
     self.font = QFont()
     self.metrics = QFontMetricsF(self.font)
Esempio n. 26
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
Esempio n. 27
0
class TitleLabel(QGraphicsWidget):
    def __init__(self, parent_node_instance):
        super(TitleLabel, self).__init__(parent_node_instance)

        self.setGraphicsItem(self)

        self.parent_node_instance: NodeInstance = parent_node_instance
        self.title_str = self.parent_node_instance.parent_node.title
        self.font = QFont('Poppins', 15) if self.parent_node_instance.parent_node.design_style == 'extended' else \
                                 QFont('K2D', 20, QFont.Bold, True)
        self.fm = QFontMetricsF(self.font)

        self.width = self.fm.width(get_longest_line(self.title_str))
        self.height = self.fm.height() * 0.7 * (self.title_str.count('\n') + 1)

        self.color = QColor(30, 43, 48)
        self.pen_width = 1.5
        self.hovering = False  # whether the mouse is hovering over the parent NI (!)


    def boundingRect(self):
        return QRectF(QPointF(0, 0), self.geometry().size())

    def setGeometry(self, rect):
        self.prepareGeometryChange()
        QGraphicsLayoutItem.setGeometry(self, rect)
        self.setPos(rect.topLeft())

    def sizeHint(self, which, constraint=...):
        return QSizeF(self.width, self.height)

    def paint(self, painter, option, widget=None):
        self.set_design()
        
        pen = QPen(self.color)
        pen.setWidth(self.pen_width)

        painter.setPen(pen)
        painter.setFont(self.font)

        text_rect = self.boundingRect()
        text_rect.setTop(text_rect.top()-7)

        painter.drawText(text_rect, Qt.AlignTop, self.title_str)

    def design_style(self):
        return self.parent_node_instance.parent_node.design_style

    def set_NI_hover_state(self, hovering: bool):
        self.hovering = hovering
        self.update()

    def set_design(self):
        if self.design_style() == 'extended':
            if Design.flow_style == 'dark std':
                if self.hovering:
                    self.color = self.parent_node_instance.parent_node.color.lighter()
                    self.pen_width = 2
                else:
                    self.color = QColor(30, 43, 48)
                    self.pen_width = 1.5
            elif Design.flow_style == 'dark tron':
                if self.hovering:
                    self.color = self.parent_node_instance.parent_node.color.lighter()
                else:
                    self.color = self.parent_node_instance.parent_node.color
                self.pen_width = 2
        elif self.design_style() == 'minimalistic':
            if Design.flow_style == 'dark std':
                if self.hovering:
                    self.color = self.parent_node_instance.parent_node.color.lighter()
                    self.pen_width = 1.5
                else:
                    self.color = QColor(30, 43, 48)
                    self.pen_width = 1.5
            elif Design.flow_style == 'dark tron':
                self.color = self.parent_node_instance.parent_node.color
                self.pen_width = 2
Esempio n. 28
0
File: main.py Progetto: ddjokic/DAVE
    def __init__(self, scene, splash=None, app=None):

        if app is None:

            if QtWidgets.QApplication.instance() is not None:
                self.app = QtWidgets.QApplication.instance()
            else:
                self.app = QtWidgets.QApplication()
        else:
            self.app = app
        self.app.aboutToQuit.connect(self.onClose)

        if splash is None:
            splash = QtWidgets.QSplashScreen()
            splash.setPixmap(QPixmap(":/icons/splashscreen.png"))
            splash.show()

        # Main Window
        self.MainWindow = QtWidgets.QMainWindow()
        self.ui = Ui_MainWindow()
        self.ui.setupUi(self.MainWindow)

        # ============== private properties ================
        self._codelog = []

        self._animation_start_time = time.time()
        """Time at start of the simulation in seconds (system-time)"""

        self._animation_length = 0
        """The length of the animation in seconds"""

        self._animation_loop = False
        """Animation is a loop"""

        self._animation_final_dofs = None
        """DOFS at termination of the animation"""

        self._animation_keyframe_interpolation_object = None
        """Object that can be called with a time and yields the dofs at that time. t should be [0..._animation_length] """

        self._animation_paused = False
        """Animation paused"""

        self._animation_available = False
        """Animation available"""

        self._animation_speed = 1.0

        # ================= Create globally available properties =======
        self.selected_nodes = []
        """A list of selected nodes (if any)"""

        self.scene = scene
        """Reference to a scene"""

        # ======================== Create 3D viewpower ====================
        self.visual = Viewport(scene)
        """Reference to a viewport"""

        self.visual.create_visuals(recreate=True)
        self.visual.mouseLeftEvent = self.view3d_select_element

        self.visual.show_embedded(self.ui.frame3d)
        self.visual.position_visuals()
        self.visual.update_visibility()

        # right-click event for
        self.ui.frame3d.setContextMenuPolicy(Qt.CustomContextMenu)
        self.ui.frame3d.customContextMenuRequested.connect(
            self.rightClickViewport)

        self._timerid = None
        iren = self.visual.renwin.GetInteractor()
        iren.AddObserver('TimerEvent', self.timerEvent)

        # ------ key-presses -----

        self.visual.onEscapeKey = self.escPressed

        # ------ viewport buttons ------

        self.ui.btnWater.pressed.connect(self.toggle_show_global)
        self.ui.btnBlender.pressed.connect(self.to_blender)

        # ------ animation buttons ------

        self.ui.frameAni.setVisible(False)
        self.ui.btnStopAnimation.pressed.connect(
            lambda: self.animation_terminate(False))
        self.ui.btnPauseAnimation.pressed.connect(
            self.animation_pause_or_continue_click)
        self.ui.aniSlider.valueChanged.connect(self.animation_change_time)
        self.ui.sbPlaybackspeed.valueChanged.connect(
            self.animation_speed_change)

        # ======================== Main Menu entries :: visuals ======

        self.ui.actionNew.triggered.connect(self.clear)
        self.ui.actionOpen.triggered.connect(self.open)
        self.ui.actionSave_scene.triggered.connect(self.menu_save)
        self.ui.actionSave_actions_as.triggered.connect(self.menu_save_actions)
        self.ui.actionImport_sub_scene.triggered.connect(self.menu_import)
        self.ui.actionImport_browser.triggered.connect(self.import_browser)

        # --- buttons
        self.ui.pbExecute.pressed.connect(self.run_code_in_teCode)
        self.ui.pbCopyOutput.pressed.connect(self.feedback_copy)
        self.ui.pbCopyHistory.pressed.connect(self.history_copy)
        self.ui.pbGenerateSceneCode.pressed.connect(self.generate_scene_code)
        self.ui.pbClearCode.pressed.connect(self.clear_code)

        #
        self.ui.btnSolveStatics.clicked.connect(self.solve_statics)
        self.ui.btnUndoStatics.clicked.connect(self.undo_solve_statics)

        # -- visuals
        self.ui.actionShow_water_plane.triggered.connect(
            self.toggle_show_global_from_menu)
        self.ui.actionShow_visuals.triggered.connect(self.toggle_show_visuals)
        self.ui.actionShow_Geometry_elements.triggered.connect(
            self.toggle_show_geometry)
        self.ui.actionShow_force_applyting_element.triggered.connect(
            self.toggle_show_force)

        self.ui.actionHorizontal_camera.triggered.connect(
            self.visual.level_camera)
        self.ui.actionAdd_light.triggered.connect(self.visual.make_lighter)
        self.ui.actionDark_mode.triggered.connect(self.visual.make_darker)
        self.ui.action2D_mode.triggered.connect(self.visual.toggle_2D)

        self.ui.actionX.triggered.connect(lambda: self.camera_set_direction(
            (1, 0, 0)))
        self.ui.action_x.triggered.connect(lambda: self.camera_set_direction(
            (-1, 0, 0)))
        self.ui.actionY.triggered.connect(lambda: self.camera_set_direction(
            (0, 1, 0)))
        self.ui.action_Y.triggered.connect(lambda: self.camera_set_direction(
            (0, -1, 0)))
        self.ui.actionZ.triggered.connect(lambda: self.camera_set_direction(
            (0, 0, -1)))
        self.ui.action_Z.triggered.connect(lambda: self.camera_set_direction(
            (0, 0, 1)))
        self.ui.actionCamera_reset.triggered.connect(self.camera_reset)

        #

        def normalize_force():
            self.run_code(
                'self.visual.force_do_normalize = not self.visual.force_do_normalize',
                guiEventType.VIEWER_SETTINGS_UPDATE)

        self.ui.actionShow_all_forces_at_same_size.triggered.connect(
            normalize_force)

        def increase_force_size():
            self.run_code(
                'self.visual.force_scale = 1.1*self.visual.force_scale',
                guiEventType.VIEWER_SETTINGS_UPDATE)

        self.ui.actionIncrease_force_size.triggered.connect(
            increase_force_size)

        def decrease_force_size():
            self.run_code(
                'self.visual.force_scale = 0.9*self.visual.force_scale',
                guiEventType.VIEWER_SETTINGS_UPDATE)

        self.ui.actionDecrease_force_size.triggered.connect(
            decrease_force_size)

        def increase_geo_size():
            self.run_code(
                'self.visual.geometry_scale = 1.1*self.visual.geometry_scale',
                guiEventType.VIEWER_SETTINGS_UPDATE)

        self.ui.actionIncrease_Geometry_size.triggered.connect(
            increase_geo_size)

        def decrease_geo_size():
            self.run_code(
                'self.visual.geometry_scale = 0.9*self.visual.geometry_scale',
                guiEventType.VIEWER_SETTINGS_UPDATE)

        self.ui.actionDecrease_Geometry_size.triggered.connect(
            decrease_geo_size)

        # ======================= Code-highlighter ==============

        font = QFont()
        font.setPointSize(10)
        font.setFamily('Consolas')
        self.ui.teCode.setFont(font)
        self.ui.teCode.setTabStopDistance(
            QFontMetricsF(self.ui.teCode.font()).width(' ') * 4)

        self.highlight = PythonHighlighter(self.ui.teCode.document())

        self.eventFilter = CtrlEnterKeyPressFilter()
        self.eventFilter.callback = self.run_code_in_teCode
        self.ui.teCode.installEventFilter(self.eventFilter)

        # ======================== Docks ====================
        self.guiWidgets = dict()
        """Dictionary of all created guiWidgets (dock-widgets)"""

        def set_pb_style(pb):
            pb.setFlat(True)
            pb.setCheckable(True)
            pb.setAutoExclusive(True)
            self.ui.toolBar.addWidget(pb)

        # Workspace buttons
        btnConstruct = QtWidgets.QPushButton()
        btnConstruct.setText('&0. Library')
        btnConstruct.clicked.connect(self.import_browser)
        btnConstruct.setFlat(True)
        self.ui.toolBar.addWidget(btnConstruct)

        btnConstruct = QtWidgets.QPushButton()
        btnConstruct.setText('&1. Construct')
        btnConstruct.clicked.connect(
            lambda: self.activate_workspace("CONSTRUCT"))
        set_pb_style(btnConstruct)
        btnConstruct.setChecked(True)

        btnConstruct = QtWidgets.QPushButton()
        btnConstruct.setText('&2. Explore')
        btnConstruct.clicked.connect(
            lambda: self.activate_workspace("EXPLORE"))
        set_pb_style(btnConstruct)

        btnConstruct = QtWidgets.QPushButton()
        btnConstruct.setText('&3. Ballast')
        btnConstruct.clicked.connect(
            lambda: self.activate_workspace("BALLAST"))
        set_pb_style(btnConstruct)

        btnConstruct = QtWidgets.QPushButton()
        btnConstruct.setText('&4. Stability')
        btnConstruct.clicked.connect(
            lambda: self.activate_workspace("STABILITY"))
        set_pb_style(btnConstruct)

        btnConstruct = QtWidgets.QPushButton()
        btnConstruct.setText('&5. Mode Shapes')
        btnConstruct.clicked.connect(
            lambda: self.activate_workspace("DYNAMICS"))
        set_pb_style(btnConstruct)

        btnConstruct = QtWidgets.QPushButton()
        btnConstruct.setText('&6. Airy')
        btnConstruct.clicked.connect(lambda: self.activate_workspace("AIRY"))
        set_pb_style(btnConstruct)

        space = QtWidgets.QWidget()
        space.setSizePolicy(QtWidgets.QSizePolicy.Expanding,
                            QtWidgets.QSizePolicy.Preferred)
        self.ui.toolBar.addWidget(space)

        self.activate_workspace('CONSTRUCT')

        # ======================== Finalize ========================
        splash.finish(self.MainWindow)
        self.MainWindow.show()
        self.app.exec_()
Esempio n. 29
0
    def compute_size_and_positions(self):
        """Very ugly: manually computes the geometry. Should get removed later when implemented using
        QGraphicsLayouts!"""

        self.width = 0
        self.height = 0

        gate_label_buffer = 10  # adds space between the gate and the label (vertical)
        label_widget_buffer = 10

        label_FM = QFontMetricsF(self.label.font)

        self.width = self.gate.width + self.label.width + gate_label_buffer
        self.height = self.gate.height if self.gate.height > self.label.height else self.label.height
        self.height *= 1.3

        if self.direction == 'input':
            if self.widget:
                widget_width = self.widget.width()
                widget_height = self.widget.height()
                if self.widget_pos == 'under':
                    self.width = widget_width if widget_width > self.width else self.width
                    self.height += widget_height
                    upper_row_height = self.gate.height if self.gate.height > self.label.height else self.label.height
                    self.widget.port_local_pos = QPointF(
                        -self.width / 2 + self.widget.width() / 2,
                        -self.height / 2 + upper_row_height +
                        self.widget.height() / 2)
                    self.gate.port_local_pos = QPointF(
                        -self.width / 2 + self.gate.width / 2,
                        -self.height / 2 + upper_row_height / 2)
                    self.label.port_local_pos = QPointF(
                        -self.width / 2 + self.gate.width + gate_label_buffer +
                        self.label.width / 2,
                        -self.height / 2 + upper_row_height / 2)
                elif self.widget_pos == 'besides':
                    self.width += label_widget_buffer + widget_width
                    self.height = self.height if self.height > self.widget.height(
                    ) else self.widget.height()
                    self.widget.port_local_pos = QPointF(
                        -self.width / 2 + self.gate.width + gate_label_buffer +
                        self.label.width + label_widget_buffer +
                        self.widget.width() / 2, 0)
                    self.gate.port_local_pos = QPointF(
                        -self.width / 2 + self.gate.width / 2, 0)
                    self.label.port_local_pos = QPointF(
                        -self.width / 2 + self.gate.width + gate_label_buffer +
                        self.label.width / 2, 0)
                if self.widget.width() > self.width:
                    self.width = self.widget.width()

            else:
                self.gate.port_local_pos = QPointF(
                    -self.width / 2 + self.gate.width / 2, 0)
                self.label.port_local_pos = QPointF(
                    -self.width / 2 + self.gate.width + gate_label_buffer +
                    self.label.width / 2, 0)
        elif self.direction == 'output':
            self.gate.port_local_pos = QPointF(
                +self.width / 2 - self.gate.width / 2, 0)
            self.label.port_local_pos = QPointF(
                +self.width / 2 - self.gate.width - gate_label_buffer -
                self.label.width / 2, 0)
Esempio n. 30
0
class ConfigurationManager:

    __slots__ = ['_entries']

    def __init__(self, entries=None):

        if entries is None:
            self._entries = {}

            for entry in ENTRIES:
                self._entries[entry.name] = entry.copy()
        else:
            self._entries = entries

    def init_font_config(self):
        self.ui_default_font = QGuiApplication.font()

        self.disasm_font = QFont("DejaVu Sans Mono", 10)
        self.disasm_font_metrics = QFontMetricsF(self.disasm_font)
        self.disasm_font_height = self.disasm_font_metrics.height()
        self.disasm_font_width = self.disasm_font_metrics.width('A')
        self.disasm_font_ascent = self.disasm_font_metrics.ascent()

        self.symexec_font = QFont("DejaVu Sans Mono", 10)
        self.symexec_font_metrics = QFontMetricsF(self.symexec_font)
        self.symexec_font_height = self.symexec_font_metrics.height()
        self.symexec_font_width = self.symexec_font_metrics.width('A')
        self.symexec_font_ascent = self.symexec_font_metrics.ascent()

        self.code_font = QFont("Source Code Pro", 10)
        self.code_font_metrics = QFontMetricsF(self.code_font)
        self.code_font_height = self.code_font_metrics.height()
        self.code_font_width = self.code_font_metrics.width('A')
        self.code_font_ascent = self.code_font_metrics.ascent()

    def __getattr__(self, item):

        if item in self.__slots__:
            raise AttributeError()

        if item in self._entries:
            return self._entries[item].value

        raise AttributeError(item)

    def __setattr__(self, key, value):

        if key in self.__slots__:
            super(ConfigurationManager, self).__setattr__(key, value)
            return

        if key in self._entries:
            self._entries[key].value = value
            return

        raise AttributeError(key)

    def __dir__(self):
        return list(super().__dir__()) + list(self._entries)

    @classmethod
    def parse(cls, f):
        entry_map = {}
        for entry in ENTRIES:
            entry_map[entry.name] = entry.copy()

        try:
            loaded = toml.load(f)

            for k, v in loaded.items():
                if entry.type_ in data_constructors:
                    v = data_constructors[entry.type_](k, v)
                if k not in entry_map:
                    _l.warning(
                        'Unknown configuration option \'%s\'. Ignoring...', k)
                    continue
                entry = entry_map[k]
                if type(v) is not entry.type_:
                    _l.warning(
                        'Value \'%s\' for configuration option \'%s\' has type \'%s\', expected type \'%s\'. Ignoring...',
                        v, k, type(v), entry.type_)
                    continue
                entry.value = v
        except toml.TomlDecodeError as e:
            _l.error(
                'Failed to parse configuration file: \'%s\'. Continuing with default options...',
                e.msg)

        return cls(entry_map)