Exemplo n.º 1
0
    def __init__(self, parent, retry=True):

        QtWidgets.QDialog.__init__(self, parent)
        self.setModal(True)
        self.message = 'Apologies, but there was a plugin that failed to register:'
        self.error_text = ''
        self.error_traceback_text = ''

        layout = QtWidgets.QVBoxLayout()
        hlayout = box_row(layout)
        self.message_widget = QtWidgets.QWidget(self)
        self.traceback_widget = QtWidgets.QTextBrowser(self)
        self.traceback_widget.setMinimumWidth(300)
        self.setWindowTitle(self.message)
        hlayout.addWidget(self.message_widget)
        hlayout.addWidget(self.traceback_widget)
        mlayout = QtWidgets.QVBoxLayout()
        # self.message_header_label = QtWidgets.QLabel('', self.message_widget)
        self.message_error_label = QtWidgets.QLabel(self.error_text, self.message_widget)
        # mlayout.addWidget(self.message_header_label)
        mlayout.addWidget(self.message_error_label)
        self.message_widget.setLayout(mlayout)
        hlayout = box_row(layout)
        self.retry_button = None
        if retry:
            self.retry_button = QtWidgets.QPushButton(self)
            self.retry_button.setText('Try again, I fixed it')
            self.retry_button.clicked.connect(self.accept)
            hlayout.addWidget(self.retry_button)
        self.pass_button = QtWidgets.QPushButton(self)
        self.pass_button.setText('Disable plugin and continue')
        self.pass_button.setDefault(True)
        self.pass_button.clicked.connect(self.reject)
        hlayout.addWidget(self.pass_button)
        self.setLayout(layout)
Exemplo n.º 2
0
    def __init__(self, parent):
        UIEmbed.__init__(self, parent, None, 'Create new node')
        self.marker = None
        self.guess_mode = True
        layout = self.vlayout
        tt = 'Text for new node'
        smaller_font = qt_prefs.get_font(g.MAIN_FONT)
        big_font = QtGui.QFont(smaller_font)
        big_font.setPointSize(big_font.pointSize() * 2)
        self.input_line_edit = ExpandingLineEdit(self, tooltip=tt, big_font=big_font,
                                                 smaller_font=smaller_font, prefill='label',
                                                 on_edit=self.guess_type_for_input)
        layout.addWidget(self.input_line_edit)
        hlayout = box_row(layout)
        self.node_type_selector = SelectionBox(self)
        self.node_type_selector.currentIndexChanged.connect(self.changed_node_type)

        self.node_types = [(g.GUESS_FROM_INPUT, 'Guess from input')]
        for key in classes.node_types_order:
            add_action_name = f'add_{key}_node'
            add_action = add_action_name in ctrl.ui.actions and ctrl.ui.get_action(add_action_name)
            if add_action and add_action.enabler():
                node_class = classes.nodes.get(key, None)
                self.node_types.append((key, 'New %s' % node_class.display_name[0].lower()))
        self.node_type_selector.add_items(self.node_types)
        hlayout.addWidget(self.node_type_selector)
        hlayout.addStretch(0)
        # U+21A9 ↩
        self.enter_button = PushButtonBase(parent=self, text="Create ↩",
                                           action='create_new_node_from_text'
                                           ).to_layout(hlayout)
        self.assumed_width = 200
        self.assumed_height = 117
Exemplo n.º 3
0
    def __init__(self, name, default_position='bottom', parent=None, folded=False):
        """
        All of the panel constructors follow the same format so that the construction can be automated.
        :param name: Title of the panel and the key for accessing it
        :param default_position: 'bottom', 'right'...
        :param parent: self.main
        :param ui_manager: pass a dictionary where buttons from this panel will be added
        """
        Panel.__init__(self, name, default_position, parent, folded)
        inner = self.widget()
        self.preferred_size = QtCore.QSize(220, 40)
        inner.setAutoFillBackground(True)

        layout = self.vlayout
        hlayout = box_row(layout)

        self.selector = SelectionBox(inner, action='set_visualization').to_layout(hlayout)
        for key, item in []:
            self.selector.addItem('%s (%s)' % (key, item.shortcut), key)

        self.toggle_options = PanelButton(pixmap=qt_prefs.settings_pixmap,
                                          tooltip='Visualization settings',
                                          parent=inner, size=20,
                                          action='toggle_panel_%s' % g.VIS_OPTIONS
                                          ).to_layout(hlayout, align=QtCore.Qt.AlignRight)
        self.toggle_options.setFixedSize(26, 26)
        self.toggle_options.setCheckable(True)
        ctrl.main.forest_changed.connect(self.update_treeset_counter)
        self.finish_init()
Exemplo n.º 4
0
    def __init__(self, parent, edge):
        """ ArrowLabelEmbed is for editing arrow labels, but it takes Arrow as its host,
        because there may be problems if the host item is not subclass of Saved. Use self.label
        to get access to edge.label_item.
        :param parent:
        :param ui_manager:
        :param edge:
        :param ui_key:
        """

        UIEmbed.__init__(self, parent, edge, 'Edit edge text')
        self.marker = None
        self.label = edge.label_item
        layout = self.vlayout
        tt = 'Label for arrow'
        f = QtGui.QFont(qt_prefs.get_font(g.MAIN_FONT))
        f.setPointSize(f.pointSize() * 2)
        hlayout = box_row(layout)
        self.input_line_edit = KatajaLineEdit(self, tooltip=tt, font=f, prefill='label'
                                              ).to_layout(hlayout)
        # U+21A9 ↩
        self.enter_button = PushButtonBase(self, text="↩",
                                           action='edit_edge_label_enter_text'
                                           ).to_layout(hlayout)
        self.assumed_width = 200
        self.assumed_height = 37
        self.update_position()
Exemplo n.º 5
0
 def __init__(self, field_name, parent=None):
     QtWidgets.QWidget.__init__(self, parent)
     layout = QtWidgets.QVBoxLayout()
     self.preferred_width = 360
     if prefs.large_ui_text:
         self.preferred_width = 460
     self.scroll_area = QtWidgets.QScrollArea(self)
     self.inner_widget = self.prepare_plugins_selection_widget()
     self.scroll_area.setWidget(self.inner_widget)
     self.scroll_area.setMinimumWidth(self.preferred_width)
     self.scroll_area.setMaximumWidth(self.preferred_width)
     layout.addWidget(self.scroll_area)
     layout.addStretch(10)
     hlayout = box_row(layout)
     self.plugin_path = QtWidgets.QLabel(
         'Plugin path: %s' % (prefs.plugins_path or running_environment.plugins_path), self)
     self.plugin_path.setMaximumWidth(self.preferred_width - 80)
     self.plugin_path.setWordWrap(True)
     self.plugin_path.setMinimumHeight(self.plugin_path.sizeHint().height() + 20)
     hlayout.addWidget(self.plugin_path)
     plugin_path_select = QtWidgets.QPushButton("Select folder")
     plugin_path_select.setMaximumWidth(72)
     plugin_path_select.clicked.connect(self.open_plugin_path_dialog)
     hlayout.addWidget(plugin_path_select)
     refresh = QtWidgets.QPushButton('Refresh list', self)
     refresh.setMaximumWidth(80)
     refresh.clicked.connect(self.refresh_plugin_selection)
     layout.addWidget(refresh)
     self.setLayout(layout)
     self.field_name = field_name
     self.on_change_method = None
Exemplo n.º 6
0
    def __init__(self, name, default_position='right', parent=None, folded=True):
        """
        All of the panel constructors follow the same format so that the
        construction can be automated.
        :param name: Title of the panel and the key for accessing it
        :param default_position: 'bottom', 'right'...
        :param parent: self.main
        """

        NodePanel.__init__(self, name, g.COMMENT_NODE, default_position, parent, folded)
        hlayout = box_row(self.vlayout)
        widget = self.widget()
        label = KatajaInfoLabel('Edge',
                                tooltip=ctrl.ui.get_action('change_edge_shape').k_tooltip,
                                parent=widget)
        hlayout.addWidget(label)

        hlayout.addStretch(24)
        self.shape_selector = ShapeSelector(parent=widget,
                                            action='change_edge_shape_for_comments',
                                            for_edge_type=g.COMMENT_EDGE
                                            ).to_layout(hlayout, align=QtCore.Qt.AlignRight)
        self.edge_visible = EyeButton(action='toggle_comment_edge_visibility', height=22,
                                      width=24).to_layout(hlayout, align=QtCore.Qt.AlignRight)
        self.edge_options = PanelButton(parent=widget,
                                        pixmap=qt_prefs.settings_icon,
                                        action='open_line_options',
                                        ).to_layout(hlayout, align=QtCore.Qt.AlignRight)
        self.edge_options.data = self.node_type

        self.finish_init()
Exemplo n.º 7
0
    def __init__(self, name, default_position='right', parent=None, folded=False):
        """
        All of the panel constructors follow the same format so that the construction can be automated.
        :param name: Title of the panel and the key for accessing it
        :param default_position: 'bottom', 'right'...
        :param parent: self.main
        """
        Panel.__init__(self, name, default_position, parent, folded)
        inner = self.widget()
        self.preferred_size = QtCore.QSize(200, 70)
        inner.setAutoFillBackground(True)
        layout = self.vlayout
        hlayout = box_row(layout)

        self.selector = SelectionBox(inner, action='set_visualization').to_layout(hlayout)
        self.selector.add_items([(key, '%s (%s)' % (key, item.shortcut)) for key, item in
                                 VISUALIZATIONS.items()])

        self.toggle_options = PanelButton(pixmap=qt_prefs.settings_pixmap,
                                          action='toggle_panel',
                                          parent=inner,
                                          size=20).to_layout(hlayout, align=QtCore.Qt.AlignRight)
        self.toggle_options.setFixedSize(26, 26)
        self.toggle_options.setCheckable(True)
        self.toggle_options.data = 'VisualizationOptionsPanel'

        ctrl.main.visualisation_changed.connect(self.update_visualisation)
        self.finish_init()
Exemplo n.º 8
0
    def __init__(self, name, default_position='right', parent=None, folded=False):
        """
        All of the panel constructors follow the same format so that the construction can be
        automated.
        :param name: Title of the panel and the key for accessing it
        :param default_position: 'bottom', 'right'...
        :param parent: self.main
        """
        Panel.__init__(self, name, default_position, parent, folded)
        inner = QtWidgets.QWidget()
        #inner.preferred_size = QtCore.QSize(220, 130)
        inner.setMinimumSize(160, 130)
        inner.setMaximumSize(220, 400)
        inner.setMinimumWidth(160)

        layout = QtWidgets.QVBoxLayout()
        self.selector = SelectionBox(self)
        self.selector.add_items([(table_dict[item], item) for item in table_names])
        self.selector.activated.connect(self.change_symbol_set)
        self.selector.setFocusPolicy(QtCore.Qt.TabFocus)
        layout.addWidget(self.selector)
        self.symlist = QtWidgets.QListWidget()
        self.symlist.setSizePolicy(QtWidgets.QSizePolicy.Expanding,
         QtWidgets.QSizePolicy.Expanding)
        self.symlist.setSpacing(8)
        self.symlist.setMouseTracking(True)
        self.symlist.setFocusPolicy(QtCore.Qt.NoFocus)
        self.symlist.setViewMode(QtWidgets.QListWidget.IconMode)
        f = qt_prefs.get_font(g.MAIN_FONT)
        self.symlist.setStyleSheet('font-family: "%s"; font-size: %spx;' % (
            f.family(), int(f.pointSize() * 1.5)))
        self.symlist.itemEntered.connect(self.item_entered)
        self.symlist.itemClicked.connect(self.item_clicked)
        layout.addWidget(self.symlist)
        hlayout = box_row(layout)
        self.info = QtWidgets.QLabel('')
        hlayout.addWidget(self.info)
        self.resize_grip = QtWidgets.QSizeGrip(self)
        self.resize_grip.hide()
        hlayout.addWidget(self.resize_grip, 0, QtCore.Qt.AlignRight)
        inner.setLayout(layout)
        self.tables = {}
        keys = list(latex_to_unicode.keys())
        for name in table_names:
            self.tables[name] = []
        keys.sort()
        for key in keys:
            char, description, table_key = latex_to_unicode[key]
            self.tables[table_key].append(key)
        self.tables['greek'] = greek_letters
        self.tables['arrows'] = arrows
        self.tables['more arrows'] = more_arrows
        self.tables['common'] = common
        # self.tables['arrows'] = arrows
        self.prepare_symbols('common')
        self.setWidget(inner)
        self.finish_init()
Exemplo n.º 9
0
    def __init__(self, parent):
        UIEmbed.__init__(self, parent, None, 'Create new node')
        self.marker = None
        self.guess_mode = True
        layout = QtWidgets.QVBoxLayout()
        layout.addLayout(self.top_row_layout)
        hlayout = box_row(layout)
        ui = self.ui_manager
        self.new_arrow_button = icon_text_button(ui, hlayout, self, '', '',
                                                 " &Arrow", 'new_arrow', size=QtCore.QSize(48, 20),
                                                 draw_method=arrow)
        self.divider_button = icon_text_button(ui, hlayout, self, '', '',
                                               " &Divider", 'new_divider',
                                               size=QtCore.QSize(48, 20), draw_method=divider)
        self.new_arrow_button.setFlat(False)
        self.divider_button.setFlat(False)
        self.new_arrow_button.hide()
        self.divider_button.hide()
        tt = 'Text for new node'
        smaller_font = qt_prefs.get_font(g.MAIN_FONT)
        big_font = QtGui.QFont(smaller_font)
        big_font.setPointSize(big_font.pointSize() * 2)
        self.input_line_edit = ExpandingLineEdit(self,
                                                 tip=tt,
                                                 big_font=big_font,
                                                 smaller_font=smaller_font,
                                                 prefill='label',
                                                 on_edit=self.guess_type_for_input)
        layout.addWidget(self.input_line_edit)
        hlayout = QtWidgets.QHBoxLayout()
        self.node_type_selector = SelectionBox(self)
        self.node_type_selector.currentIndexChanged.connect(self.changed_node_type)

        self.node_types = [('Guess from input', g.GUESS_FROM_INPUT)]
        for key in classes.node_types_order:
            # we have dedicated buttons for arrows and dividers
            #if key not in (g.ARROW, g.DIVIDER):
            node_class = classes.nodes.get(key, None)
            if (not node_class) or node_class.is_syntactic and not ctrl.free_drawing_mode:
                continue
            self.node_types.append(('New %s' % node_class.display_name[0].lower(), key))
        self.node_types.append(('New arrow', g.ARROW))
        #self.node_types.append(('New divider', g.DIVIDER))
        self.node_type_selector.add_items(self.node_types)
        hlayout.addWidget(self.node_type_selector)
        hlayout.addStretch(0)
        self.enter_button = QtWidgets.QPushButton("Create ↩")  # U+21A9 ↩
        ui.connect_element_to_action(self.enter_button, 'create_new_node_from_text')

        hlayout.addWidget(self.enter_button)
        layout.addLayout(hlayout)
        self.setLayout(layout)
        self.assumed_width = 200
        self.assumed_height = 117
Exemplo n.º 10
0
    def __init__(self,
                 name,
                 default_position='float',
                 parent=None,
                 folded=False):
        """
        BUild all advanced line options. Then in update filter what to show based on the line type.

        All of the panel constructors follow the same format so that the construction can be automated:
        :param name: Title of the panel and the key for accessing it
        :param default_position: 'bottom', 'right'...
        :param parent: self.main
        """
        Panel.__init__(self, name, default_position, parent, folded)
        self.watchlist = ['view_mode_changed']
        inner = QtWidgets.QWidget(self)
        layout = QtWidgets.QVBoxLayout()
        layout.setSizeConstraint(QtWidgets.QLayout.SetMinimumSize)
        self.setSizePolicy(
            QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Minimum,
                                  QtWidgets.QSizePolicy.MinimumExpanding))
        self.setMaximumWidth(220)
        self.setMaximumHeight(140)

        hlayout = box_row(layout)
        layout.addLayout(hlayout)
        ui = self.ui_manager
        self.show_node_labels = checkbox(ui, inner, hlayout,
                                         'Show node labels',
                                         'toggle_show_node_label')
        grid = QtWidgets.QGridLayout()
        grid.setContentsMargins(0, 0, 0, 0)

        label(self, grid, 'Show projections', 0, 0)
        self.highlighter_button = checkbox(ui, inner, grid, 'with highlighter',
                                           'toggle_highlighter_projection', 1,
                                           0)
        self.strong_lines_button = checkbox(ui, inner, grid,
                                            'with stronger lines',
                                            'toggle_strong_lines_projection',
                                            1, 1)
        self.colorize_button = checkbox(ui, inner, grid,
                                        'with colorized lines',
                                        'toggle_colorized_projection', 1, 2)

        layout.addLayout(grid)
        inner.setLayout(layout)
        self.setWidget(inner)
        self.finish_init()
Exemplo n.º 11
0
    def __init__(self, name, default_position='float', parent=None, folded=False):
        """
        BUild all advanced line options. Then in update filter what to show based on the line type.

        All of the panel constructors follow the same format so that the construction can be automated:
        :param name: Title of the panel and the key for accessing it
        :param default_position: 'bottom', 'right'...
        :param parent: self.main
        """
        Panel.__init__(self, name, default_position, parent, folded)
        self.watchlist = ['view_mode_changed']
        inner = QtWidgets.QWidget(self)
        layout = QtWidgets.QVBoxLayout()
        layout.setSizeConstraint(QtWidgets.QLayout.SetMinimumSize)
        self.setSizePolicy(QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Minimum,
                                                 QtWidgets.QSizePolicy.MinimumExpanding))
        self.setMaximumWidth(220)
        self.setMaximumHeight(140)

        hlayout = box_row(layout)
        layout.addLayout(hlayout)
        ui = self.ui_manager
        self.show_node_labels = checkbox(ui, inner, hlayout, 'Show node labels',
                                         'toggle_show_node_label')
        grid = QtWidgets.QGridLayout()
        grid.setContentsMargins(0, 0, 0, 0)

        label(self, grid, 'Show projections', 0, 0)
        self.highlighter_button = checkbox(ui, inner, grid,
                                              'with highlighter',
                                              'toggle_highlighter_projection',
                                              1, 0)
        self.strong_lines_button = checkbox(ui, inner, grid,
                                               'with stronger lines',
                                               'toggle_strong_lines_projection',
                                               1, 1)
        self.colorize_button = checkbox(ui, inner, grid,
                                           'with colorized lines',
                                           'toggle_colorized_projection',
                                           1, 2)

        layout.addLayout(grid)
        inner.setLayout(layout)
        self.setWidget(inner)
        self.finish_init()
Exemplo n.º 12
0
def color_theme_fragment(panel, inner, layout):
    hlayout = box_row(layout)
    f = qt_prefs.get_font(g.MAIN_FONT)
    panel.selector = SelectionBox(parent=inner, action='set_active_color_theme').to_layout(hlayout)
    panel.selector.setMaximumWidth(120)
    panel.selector_items = ctrl.cm.list_available_themes()
    panel.selector.add_items(panel.selector_items)

    panel.randomise = RandomiseButton(parent=inner, text='', size=(40, 20),
                                      action='randomise_palette'
                                      ).to_layout(hlayout, align=QtCore.Qt.AlignRight)

    panel.remove_theme = TwoColorButton(parent=inner, text='Remove', action='remove_color_theme',
                                        ).to_layout(hlayout, align=QtCore.Qt.AlignRight)
    panel.remove_theme.hide()

    panel.store_favorite = UnicodeIconButton(parent=inner, text='★', size=(26, 20),
                                             action='remember_palette'
                                             ).to_layout(hlayout, align=QtCore.Qt.AlignRight)
    panel.store_favorite.setStyleSheet(
        'font-family: "%s"; font-size: %spx;' % (f.family(), f.pointSize()))
    panel.store_favorite.setEnabled(False)
    panel.store_favorite.setMaximumWidth(26)
Exemplo n.º 13
0
    def __init__(self, name, default_position='right', parent=None, folded=False):
        """
        All of the panel constructors follow the same format so that the
        construction can be automated.
        :param name: Title of the panel and the key for accessing it
        :param default_position: 'bottom', 'right'...
        :param parent: self.main
        """
        Panel.__init__(self, name, default_position, parent, folded)
        inner = QtWidgets.QWidget(self)
        self.setSizePolicy(QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Preferred)
        layout = QtWidgets.QVBoxLayout()
        self.setMaximumWidth(220)
        self.setMaximumHeight(140)
        self._nodes_in_selection = []
        self._edges_in_selection = []
        self.cached_node_types = set()

        self.watchlist = ['selection_changed', 'forest_changed']
        # Other items may be temporarily added, they are defined as
        # class.variables
        ui = self.ui_manager
        # hlayout = box_row(layout)
        #
        # styles_data = []
        # current_style_i = 0
        # for i, value in enumerate(prefs.available_styles):
        #     if value == ctrl.settings.get('style'):
        #         current_style_i = i
        #     styles_data.append((value, value))
        # self.overall_style_box = selector(ui, self, hlayout,
        #                                   data=styles_data,
        #                                   action='change_master_style')
        # self.overall_style_box.setCurrentIndex(current_style_i)
        # #self.custom_overall_style = text_button(ui, hlayout,
        # #                                        text='customize',
        # #                                        action='customize_master_style',
        # #                                        checkable=True)
        # self.overall_style_box.hide()
        self.style_widgets = QtWidgets.QWidget(inner)
        sw_layout = QtWidgets.QVBoxLayout()
        sw_layout.setContentsMargins(0, 0, 0, 0)
        hlayout = box_row(sw_layout)
        self.scope_selector = selector(ui, self.style_widgets, hlayout,
                                       data=[],
                                       action='style_scope',
                                       label='Style for')
        self.scope_selector.setMinimumWidth(96)
        vline = QtWidgets.QFrame()
        vline.setFrameShape(QtWidgets.QFrame.VLine)
        hlayout.addWidget(vline)
        self.style_reset = mini_button(ui, self.style_widgets, hlayout,
                                       text='reset',
                                       action='reset_style_in_scope')
        hlayout = box_row(sw_layout)

        self.node_color_selector = color_selector(ui, self.style_widgets, hlayout,
                                                  action='change_node_color', role='node',
                                                  label='Node color')
        self.font_selector = font_selector(ui, self.style_widgets, hlayout,
                                           action='select_font',
                                           label='font')

        hlayout = box_row(sw_layout)
        self.shape_selector = shape_selector(ui, self.style_widgets, hlayout,
                                             action='change_edge_shape',
                                             label='Edge style')

        self.edge_color_selector = color_selector(ui, self.style_widgets, hlayout,
                                                  action='change_edge_color', role='edge')

        self.edge_options = icon_button(ui, self.style_widgets, hlayout,
                                        icon=qt_prefs.settings_icon,
                                        text='More edge options',
                                        action='toggle_panel_LineOptionsPanel',
                                        checkable=True)

        self.style_widgets.setLayout(sw_layout)
        layout.addWidget(self.style_widgets)
        inner.setLayout(layout)
        inner.setBackgroundRole(QtGui.QPalette.AlternateBase)
        #self.style_widgets.hide()
        self.setWidget(inner)

        self.finish_init()
Exemplo n.º 14
0
    def __init__(self, name, default_position='float', parent=None, folded=False):
        """
        BUild all advanced line options. Then in update filter what to show based on the line type.

        All of the panel constructors follow the same format so that the construction can be automated:
        :param name: Title of the panel and the key for accessing it
        :param default_position: 'bottom', 'right'...
        :param parent: self.main
        """
        Panel.__init__(self, name, default_position, parent, folded)
        layout = self.vlayout
        widget = self.widget()
        self.active_node_type = g.CONSTITUENT_NODE
        self.shape_selector = None

        ctrl.main.selection_changed.connect(self.update_panel)
        ctrl.main.scope_changed.connect(self.update_panel)

        spac = 8
        hlayout = box_row(layout)

        self.edge_type_selector = SelectionBox(parent=widget, data=[],
                                               action='set_edge_type_for_editing'
                                           ).to_layout(hlayout, with_label='Style for')
        self.edge_type_selector.setFixedWidth(148)

        layout.addWidget(hdivider())
        layout.addSpacing(spac)

        hlayout = box_row(layout)
        self.shape_selector = ShapeSelector(parent=widget,
                                            action='change_edge_shape',
                                            ).to_layout(hlayout, with_label='Shape')
        self.shape_selector.for_edge_type = self.active_edge_type

        self.edge_color_selector = ColorSelector(parent=widget,
                                                 action='change_edge_color',
                                                 role='edge').to_layout(hlayout, with_label='Color')
        # Line thickness
        hlayout = box_row(layout)
        self.fill_button = KatajaCheckBox(parent=widget,
                                          action='edge_shape_fill'
                                          ).to_layout(hlayout, with_label='Fill')

        self.line_button = KatajaCheckBox(parent=widget,
                                          action='edge_shape_line'
                                          ).to_layout(hlayout, with_label='Outline')
        self.thickness_spinbox = KatajaDecimalSpinbox(parent=widget,
                                                      range_min=0.0,
                                                      range_max=10.0,
                                                      step=0.1,
                                                      action='edge_thickness',
                                                      suffix=' px'
                                                      ).to_layout(hlayout, with_label='Thickness')
        layout.addWidget(hdivider())
        layout.addSpacing(spac)

        hlayout = box_row(layout)
        self.arrowhead_start_button = KatajaCheckBox(parent=widget,
                                                     action='edge_arrowhead_start'
                                                     ).to_layout(hlayout,
                                                                 with_label='Arrowheads at start')
        self.arrowhead_end_button = KatajaCheckBox(parent=widget,
                                                   action='edge_arrowhead_end'
                                                   ).to_layout(hlayout, with_label='at end')
        layout.addWidget(hdivider())
        layout.addSpacing(spac)
        # Curvature
        hlayout = box_row(layout)
        hlayout.addWidget(QtWidgets.QLabel('Curvature'))
        hlayout.setAlignment(QtCore.Qt.AlignRight)
        self.arc_rel_dx_spinbox = KatajaSpinbox(parent=widget, range_min=-200, range_max=200,
                                                action='change_edge_relative_curvature_x',
                                                suffix='%'
                                                ).to_layout(hlayout, with_label='X')
        self.arc_rel_dy_spinbox = KatajaSpinbox(parent=widget, range_min=-200, range_max=200,
                                                action='change_edge_relative_curvature_y',
                                                suffix='%'
                                                ).to_layout(hlayout, with_label='Y')

        hlayout = box_row(layout)
        hlayout.setAlignment(QtCore.Qt.AlignRight)
        self.arc_fixed_dx_spinbox = KatajaSpinbox(parent=widget, range_min=-200, range_max=200,
                                                  action='change_edge_fixed_curvature_x',
                                                  suffix=' px'
                                                  ).to_layout(hlayout, with_label='X')

        self.arc_fixed_dy_spinbox = KatajaSpinbox(parent=widget, range_min=-200, range_max=200,
                                                  action='change_edge_fixed_curvature_y',
                                                  suffix=' px'
                                                  ).to_layout(hlayout, with_label='Y')

        # Leaf size
        hlayout = box_row(layout)
        self.leaf_x_spinbox = KatajaDecimalSpinbox(parent=widget,
                                                   range_min=-20.0,
                                                   range_max=20.0,
                                                   step=0.5,
                                                   action='leaf_shape_x',
                                                   suffix=' px'
                                                   ).to_layout(hlayout, with_label='Brush spread X')
        self.leaf_y_spinbox = KatajaDecimalSpinbox(parent=widget,
                                                   range_min=-20.0,
                                                   range_max=20.0,
                                                   step=0.5,
                                                   action='leaf_shape_y',
                                                   suffix=' px'
                                                   ).to_layout(hlayout, with_label='Y')
        layout.addWidget(hdivider())
        layout.addSpacing(spac)

        hlayout = box_row(layout)
        self.reset_all = PanelButton(parent=widget, text='Reset edge settings',
                                     action='reset_edge_settings').to_layout(hlayout)
        self.reset_all.setMaximumHeight(20)

        self.reset_adjustment = PanelButton(parent=widget,
                                            text='Reset curves',
                                            action='reset_control_points').to_layout(hlayout)
        self.reset_adjustment.setMaximumHeight(20)
        self.finish_init()
Exemplo n.º 15
0
    def __init__(self, name, default_position='right', parent=None, folded=False):
        """
        All of the panel constructors follow the same format so that the construction can be automated.
        :param name: Title of the panel and the key for accessing it
        :param default_position: 'bottom', 'right'...
        :param parent: self.main
        """
        Panel.__init__(self, name, default_position, parent, folded)
        self.selected_role = 'content1'
        self.selected_hsv = ctrl.cm.get(self.selected_role).getHsvF()[:3]
        self.match_contrast = 65
        ctrl.main.palette_changed.connect(self.update_themes_and_colors)
        ctrl.main.color_themes_changed.connect(self.update_themes_and_colors)
        self.try_to_match = True
        self._updating = True
        # ### Color wheel
        layout = self.vlayout
        widget = self.widget()
        self.preferred_size = QtCore.QSize(220, 300)
        # From ColorThemePanel
        color_theme_fragment(self, widget, layout)

        the_rest = [f'accent{i}' for i in range(1, 9)] + [f'custom{i}' for i in range(1, 10)]

        self.editable_colors = ['content1', 'background1'] + the_rest
        self.all_colors = ['content1', 'content2', 'content3', 'background1', 'background2'] + \
                          the_rest

        self.role_label = QtWidgets.QLabel("Picking color for role: ")
        self.role_selector = QtWidgets.QComboBox(parent=widget)
        self.role_selector.addItems(self.editable_colors)
        self.role_selector.currentTextChanged.connect(self.set_color_role)
        hlayout = box_row(layout)
        hlayout.addWidget(self.role_label)
        hlayout.addWidget(self.role_selector)

        self.color_name = QtWidgets.QLabel(ctrl.cm.get_color_name(self.selected_hsv), widget)
        layout.addWidget(self.color_name)

        self.color_wheel = ColorWheelInner(widget)
        self.color_wheel.suggested_size = 200
        layout.addWidget(self.color_wheel)

        layout.addSpacing(8)
        hlayout = box_row(layout)
        self.h_spinner = spinner(self, hlayout, self.h_changed, label='H:', vmax=360, wrapping=True)
        self.s_spinner = spinner(self, hlayout, self.s_changed, label='S:', vmax=255)
        self.v_spinner = spinner(self, hlayout, self.v_changed, label='V:', vmax=255)
        hlayout = box_row(layout)
        self.r_spinner = spinner(self, hlayout, self.r_changed, label='R:', vmax=255)
        self.g_spinner = spinner(self, hlayout, self.g_changed, label='G:', vmax=255)
        self.b_spinner = spinner(self, hlayout, self.b_changed, label='B:', vmax=255)

        hlayout = box_row(layout)
        match_help = "When adjusting 'content1' or 'background1', try to find contrasting colors " \
                     "for other roles."
        self.match_l = QtWidgets.QLabel("Auto-match palette:")
        self.match_l.setToolTip(match_help)
        self.match_l.setParent(self.widget())
        self.match_cb = KatajaCheckBox()
        self.match_cb.setToolTip(match_help)
        self.match_cb.setParent(widget)
        self.match_cb.setChecked(self.try_to_match)
        self.match_cb.stateChanged.connect(self.set_palette_matching)
        self.match_l.setBuddy(self.match_cb)
        hlayout.addWidget(self.match_l)
        hlayout.addWidget(self.match_cb)
        chelp = "Contrast for auto-matched palettes"
        self.contrast_label = QtWidgets.QLabel("Contrast:")
        self.contrast_label.setToolTip(chelp)
        self.contrast_label.setParent(widget)
        hlayout.addWidget(self.contrast_label)
        self.contrast_spin = spinner(self, hlayout, self.contrast_changed, vmin=30, vmax=99)
        self.contrast_spin.setToolTip(chelp)
        self.contrast_spin.setValue(self.match_contrast)
        self._updating = False
        self.finish_init()
Exemplo n.º 16
0
    def __init__(self, parent, node):
        nname = node.display_name[0].lower()
        UIEmbed.__init__(self, parent, node, 'Edit ' + nname)
        self.setMinimumWidth(220)
        self.editable = {}
        ui_p = self._palette
        ui_s = QtGui.QPalette(ui_p)
        ui_s.setColor(QtGui.QPalette.Text, ctrl.cm.secondary())
        smaller_font = qt_prefs.get_font(g.MAIN_FONT)
        big_font = QtGui.QFont(smaller_font)
        big_font.setPointSize(big_font.pointSize() * 2)
        self.prepare_template()
        sortable = [(item.get('order', 100), key) for key, item in self.editable.items()]
        sortable.sort()
        field_names = [key for order, key in sortable]
        self.fields = {}
        self.resize_target = None
        hlayout = None

        # Generate edit elements based on data, expand this as necessary
        for field_name in field_names:
            d = self.editable.get(field_name, {})
            # if d.get('hidden', False) or not self.host.check_conditions(d):
            #    continue
            tt = d.get('tooltip', '')
            itype = d.get('input_type', 'text')
            prefill = d.get('prefill', '')
            syntactic = d.get('syntactic', False)
            on_edit = d.get('on_edit', None)
            if on_edit and isinstance(on_edit, str):
                on_edit = getattr(node, on_edit, None)
            field_first = False
            if itype == 'text':
                width = d.get('width', 140)
                field = KatajaLineEdit(self, tooltip=tt, font=big_font, prefill=prefill,
                                       on_edit=on_edit)
                field.setMaximumWidth(width)
            elif itype == 'textarea':
                self._disable_effect = True
                template_width = d.get('width', 0)
                field = KatajaTextarea(self, tooltip=tt, font=smaller_font, prefill=prefill,
                                       on_edit=on_edit)
                max_w = 200
                if node.resizable and node.user_size:
                    w = node.user_size[0]
                elif template_width:
                    w = template_width
                else:
                    w = node.label_object.document().idealWidth()
                field.setFixedWidth(min(w, max_w))
                self.resize_target = field
            elif itype == 'expandingtext':
                field = ExpandingTextArea(self, tip=tt, font=smaller_font, prefill=prefill,
                                          on_edit=on_edit)
                template_width = d.get('width', 0)
                if template_width:
                    field.setFixedWidth(template_width)
                self.resize_target = field
            elif itype == 'checkbox':
                field = QtWidgets.QCheckBox(self)
            elif itype == 'preview':
                field = PreviewLabel(self, tip=tt, font=smaller_font)
            elif itype == 'spinbox':
                field = QtWidgets.QSpinBox(self)
                field.setMinimum(d.get('min', -1))
                field.setMaximum(d.get('max', 4))
            else:
                raise NotImplementedError

            if field:
                action = d.get('select_action')
                if action:
                    self.ui_manager.connect_element_to_action(field, action)
                if syntactic:
                    field.setPalette(ui_s)
                else:
                    field.setPalette(ui_p)

            align = d.get('align', 'newline')
            if align == 'newline':
                # new hlayout means new line, but before starting a new hlayout,
                # end the previous one.
                hlayout = box_row(self.vlayout)
            self.fields[field_name] = field
            if field_first:
                hlayout.addWidget(field)
            ui_name = d.get('name', field_name)
            if ui_name:
                if syntactic:
                    palette = ui_s
                else:
                    palette = ui_p
                make_label(ui_name, self, hlayout, tt, field, palette)
            if not field_first:
                hlayout.addWidget(field)
        hlayout = box_row(self.vlayout)
        hlayout.addStretch(0)
        # U+21A9 ↩
        self.enter_button = PushButtonBase(parent=self, text="Keep ↩",
                                           action='finish_editing_node')
        hlayout.addWidget(self.enter_button, 0, QtCore.Qt.AlignRight)
        if self.resize_target:
            self.resize_handle = ResizeHandle(self, self.resize_target)
            hlayout.addWidget(self.resize_handle, 0, QtCore.Qt.AlignRight)
        self.update_embed()
        self.update_position()
        self.hide()
Exemplo n.º 17
0
    def __init__(self,
                 name,
                 default_position='right',
                 parent=None,
                 folded=False):
        """
        All of the panel constructors follow the same format so that the
        construction can be automated.
        :param name: Title of the panel and the key for accessing it
        :param default_position: 'bottom', 'right'...
        :param parent: self.main
        """
        Panel.__init__(self, name, default_position, parent, folded)
        inner = QtWidgets.QWidget(self)
        self.setSizePolicy(QtWidgets.QSizePolicy.Minimum,
                           QtWidgets.QSizePolicy.Preferred)
        layout = QtWidgets.QVBoxLayout()
        self.setMaximumWidth(220)
        self.setMaximumHeight(140)
        self._nodes_in_selection = []
        self._edges_in_selection = []
        self.cached_node_types = set()

        self.watchlist = ['selection_changed', 'forest_changed']
        # Other items may be temporarily added, they are defined as
        # class.variables
        ui = self.ui_manager
        # hlayout = box_row(layout)
        #
        # styles_data = []
        # current_style_i = 0
        # for i, value in enumerate(prefs.available_styles):
        #     if value == ctrl.settings.get('style'):
        #         current_style_i = i
        #     styles_data.append((value, value))
        # self.overall_style_box = selector(ui, self, hlayout,
        #                                   data=styles_data,
        #                                   action='change_master_style')
        # self.overall_style_box.setCurrentIndex(current_style_i)
        # #self.custom_overall_style = text_button(ui, hlayout,
        # #                                        text='customize',
        # #                                        action='customize_master_style',
        # #                                        checkable=True)
        # self.overall_style_box.hide()
        self.style_widgets = QtWidgets.QWidget(inner)
        sw_layout = QtWidgets.QVBoxLayout()
        sw_layout.setContentsMargins(0, 0, 0, 0)
        hlayout = box_row(sw_layout)
        self.scope_selector = selector(ui,
                                       self.style_widgets,
                                       hlayout,
                                       data=[],
                                       action='style_scope',
                                       label='Style for')
        self.scope_selector.setMinimumWidth(96)
        vline = QtWidgets.QFrame()
        vline.setFrameShape(QtWidgets.QFrame.VLine)
        hlayout.addWidget(vline)
        self.style_reset = mini_button(ui,
                                       self.style_widgets,
                                       hlayout,
                                       text='reset',
                                       action='reset_style_in_scope')
        hlayout = box_row(sw_layout)

        self.node_color_selector = color_selector(ui,
                                                  self.style_widgets,
                                                  hlayout,
                                                  action='change_node_color',
                                                  role='node',
                                                  label='Node color')
        self.font_selector = font_selector(ui,
                                           self.style_widgets,
                                           hlayout,
                                           action='select_font',
                                           label='font')

        hlayout = box_row(sw_layout)
        self.shape_selector = shape_selector(ui,
                                             self.style_widgets,
                                             hlayout,
                                             action='change_edge_shape',
                                             label='Edge style')

        self.edge_color_selector = color_selector(ui,
                                                  self.style_widgets,
                                                  hlayout,
                                                  action='change_edge_color',
                                                  role='edge')

        self.edge_options = icon_button(ui,
                                        self.style_widgets,
                                        hlayout,
                                        icon=qt_prefs.settings_icon,
                                        text='More edge options',
                                        action='toggle_panel_LineOptionsPanel',
                                        checkable=True)

        self.style_widgets.setLayout(sw_layout)
        layout.addWidget(self.style_widgets)
        inner.setLayout(layout)
        inner.setBackgroundRole(QtGui.QPalette.AlternateBase)
        #self.style_widgets.hide()
        self.setWidget(inner)

        self.finish_init()
Exemplo n.º 18
0
    def __init__(self,
                 name,
                 default_position='float',
                 parent=None,
                 folded=False):
        """
        BUild all advanced line options. Then in update filter what to show based on the line type.

        All of the panel constructors follow the same format so that the construction can be automated:
        :param name: Title of the panel and the key for accessing it
        :param default_position: 'bottom', 'right'...
        :param parent: self.main
        """
        Panel.__init__(self, name, default_position, parent, folded)
        inner = QtWidgets.QWidget(self)
        layout = QtWidgets.QVBoxLayout()
        layout.setSizeConstraint(QtWidgets.QLayout.SetMinimumSize)
        self.setSizePolicy(
            QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Minimum,
                                  QtWidgets.QSizePolicy.MinimumExpanding))
        self.setMaximumWidth(220)
        self.setMaximumHeight(160)
        self.watchlist = ['scope_changed', 'selection_changed']

        spac = 8
        ui = self.ui_manager
        hlayout = box_row(layout)

        self.scope_selector = selector(ui,
                                       self,
                                       hlayout,
                                       data=[],
                                       action='style_scope',
                                       label='Style for')
        self.scope_selector.setMinimumWidth(96)

        layout.addWidget(hdivider())
        layout.addSpacing(spac)

        hlayout = box_row(layout)
        self.shape_selector = shape_selector(ui,
                                             self,
                                             hlayout,
                                             action='change_edge_shape',
                                             label='Shape')

        self.edge_color_selector = color_selector(ui,
                                                  self,
                                                  hlayout,
                                                  action='change_edge_color',
                                                  label='Color',
                                                  role='edge')

        # Line thickness
        hlayout = box_row(layout)
        self.fill_button = checkbox(ui,
                                    self,
                                    hlayout,
                                    label='Fill',
                                    action='edge_shape_fill')

        self.line_button = checkbox(ui,
                                    self,
                                    hlayout,
                                    label='Outline',
                                    action='edge_shape_line')
        self.thickness_spinbox = decimal_spinbox(ui,
                                                 self,
                                                 hlayout,
                                                 label='Thickness',
                                                 range_min=0.0,
                                                 range_max=10.0,
                                                 step=0.1,
                                                 action='edge_thickness',
                                                 suffix=' px')
        layout.addWidget(hdivider())
        layout.addSpacing(spac)

        hlayout = box_row(layout)
        self.arrowhead_start_button = checkbox(ui,
                                               self,
                                               hlayout,
                                               label='Arrowheads at start',
                                               action='edge_arrowhead_start')
        self.arrowhead_end_button = checkbox(ui,
                                             self,
                                             hlayout,
                                             label='at end',
                                             action='edge_arrowhead_end')
        layout.addWidget(hdivider())
        layout.addSpacing(spac)
        # Curvature

        hlayout = box_row(layout)
        curve_modes = QtWidgets.QButtonGroup()
        self.relative_arc_button = radiobutton(
            ui,
            self,
            hlayout,
            label='Relative curve',
            action='edge_curvature_relative',
            group=curve_modes)
        self.arc_rel_dx_spinbox = spinbox(
            ui,
            self,
            hlayout,
            label='X',
            range_min=-200,
            range_max=200,
            action='change_edge_relative_curvature_x',
            suffix='%')
        self.arc_rel_dy_spinbox = spinbox(
            ui,
            self,
            hlayout,
            label='Y',
            range_min=-200,
            range_max=200,
            action='change_edge_relative_curvature_y',
            suffix='%')

        hlayout = box_row(layout)
        self.fixed_arc_button = radiobutton(ui,
                                            self,
                                            hlayout,
                                            label='Fixed curve',
                                            action='edge_curvature_fixed',
                                            group=curve_modes)
        self.arc_fixed_dx_spinbox = spinbox(
            ui,
            self,
            hlayout,
            label='X',
            range_min=-200,
            range_max=200,
            action='change_edge_fixed_curvature_x',
            suffix=' px')
        self.arc_fixed_dy_spinbox = spinbox(
            ui,
            self,
            hlayout,
            label='Y',
            range_min=-200,
            range_max=200,
            action='change_edge_fixed_curvature_y',
            suffix=' px')
        self.arc_reference_buttons = QtWidgets.QButtonGroup(self)
        self.arc_reference_buttons.addButton(self.fixed_arc_button)
        self.arc_reference_buttons.addButton(self.relative_arc_button)

        # Leaf size
        hlayout = box_row(layout)
        self.leaf_x_spinbox = decimal_spinbox(ui,
                                              self,
                                              hlayout,
                                              label='Brush spread X',
                                              range_min=-20.0,
                                              range_max=20.0,
                                              step=0.5,
                                              action='leaf_shape_x',
                                              suffix=' px')
        self.leaf_y_spinbox = decimal_spinbox(ui,
                                              self,
                                              hlayout,
                                              label='Y',
                                              range_min=-20.0,
                                              range_max=20.0,
                                              step=0.5,
                                              action='leaf_shape_y',
                                              suffix=' px')
        layout.addWidget(hdivider())
        layout.addSpacing(spac)

        hlayout = box_row(layout)
        self.reset_all = mini_button(ui,
                                     self,
                                     hlayout,
                                     text='Reset edge settings',
                                     action='reset_edge_settings',
                                     width=-1)
        self.reset_adjustment = mini_button(ui,
                                            self,
                                            hlayout,
                                            text='Reset curves',
                                            action='reset_control_points',
                                            width=-1)
        inner.setLayout(layout)
        self.setWidget(inner)
        self.finish_init()
Exemplo n.º 19
0
    def __init__(self,
                 name,
                 default_position='right',
                 parent=None,
                 folded=False):
        """
        All of the panel constructors follow the same format so that the construction can be
        automated.
        :param name: Title of the panel and the key for accessing it
        :param default_position: 'bottom', 'right'...
        :param parent: self.main
        """
        Panel.__init__(self, name, default_position, parent, folded)
        inner = QtWidgets.QWidget()
        #inner.preferred_size = QtCore.QSize(220, 130)
        inner.setMinimumSize(160, 130)
        inner.setMaximumSize(220, 400)
        inner.setMinimumWidth(160)

        layout = QtWidgets.QVBoxLayout()
        self.selector = SelectionBox(self)
        self.selector.add_items([(table_dict[item], item)
                                 for item in table_names])
        self.selector.activated.connect(self.change_symbol_set)
        self.selector.setFocusPolicy(QtCore.Qt.TabFocus)
        layout.addWidget(self.selector)
        self.symlist = QtWidgets.QListWidget()
        self.symlist.setSizePolicy(QtWidgets.QSizePolicy.Expanding,
                                   QtWidgets.QSizePolicy.Expanding)
        self.symlist.setSpacing(8)
        self.symlist.setMouseTracking(True)
        self.symlist.setFocusPolicy(QtCore.Qt.NoFocus)
        self.symlist.setViewMode(QtWidgets.QListWidget.IconMode)
        f = qt_prefs.get_font(g.MAIN_FONT)
        self.symlist.setStyleSheet('font-family: "%s"; font-size: %spx;' %
                                   (f.family(), int(f.pointSize() * 1.5)))
        self.symlist.itemEntered.connect(self.item_entered)
        self.symlist.itemClicked.connect(self.item_clicked)
        layout.addWidget(self.symlist)
        hlayout = box_row(layout)
        self.info = QtWidgets.QLabel('')
        hlayout.addWidget(self.info)
        self.resize_grip = QtWidgets.QSizeGrip(self)
        self.resize_grip.hide()
        hlayout.addWidget(self.resize_grip, 0, QtCore.Qt.AlignRight)
        inner.setLayout(layout)
        self.tables = {}
        keys = list(latex_to_unicode.keys())
        for name in table_names:
            self.tables[name] = []
        keys.sort()
        for key in keys:
            char, description, table_key = latex_to_unicode[key]
            self.tables[table_key].append(key)
        self.tables['greek'] = greek_letters
        self.tables['arrows'] = arrows
        self.tables['more arrows'] = more_arrows
        self.tables['common'] = common
        # self.tables['arrows'] = arrows
        self.prepare_symbols('common')
        self.setWidget(inner)
        self.finish_init()
Exemplo n.º 20
0
    def __init__(self, name, default_position='float', parent=None, folded=False):
        """
        BUild all advanced line options. Then in update filter what to show based on the line type.

        All of the panel constructors follow the same format so that the construction can be automated:
        :param name: Title of the panel and the key for accessing it
        :param default_position: 'bottom', 'right'...
        :param parent: self.main
        """
        Panel.__init__(self, name, default_position, parent, folded)
        inner = QtWidgets.QWidget(self)
        layout = QtWidgets.QVBoxLayout()
        layout.setSizeConstraint(QtWidgets.QLayout.SetMinimumSize)
        self.setSizePolicy(QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Minimum,
                                                 QtWidgets.QSizePolicy.MinimumExpanding))
        self.setMaximumWidth(220)
        self.setMaximumHeight(160)
        self.watchlist = ['scope_changed', 'selection_changed']

        spac = 8
        ui = self.ui_manager
        hlayout = box_row(layout)

        self.scope_selector = selector(ui, self, hlayout,
                                       data=[],
                                       action='style_scope',
                                       label='Style for')
        self.scope_selector.setMinimumWidth(96)

        layout.addWidget(hdivider())
        layout.addSpacing(spac)

        hlayout = box_row(layout)
        self.shape_selector = shape_selector(ui, self, hlayout,
                                             action='change_edge_shape',
                                             label='Shape')

        self.edge_color_selector = color_selector(ui, self, hlayout,
                                                  action='change_edge_color',
                                                  label='Color', role='edge')

        # Line thickness
        hlayout = box_row(layout)
        self.fill_button = checkbox(ui, self, hlayout, label='Fill',
                                    action='edge_shape_fill')

        self.line_button = checkbox(ui, self, hlayout, label='Outline',
                                    action='edge_shape_line')
        self.thickness_spinbox = decimal_spinbox(ui, self, hlayout,
                                                 label='Thickness', range_min=0.0, range_max=10.0,
                                                 step=0.1, action='edge_thickness', suffix=' px')
        layout.addWidget(hdivider())
        layout.addSpacing(spac)

        hlayout = box_row(layout)
        self.arrowhead_start_button = checkbox(ui, self, hlayout, label='Arrowheads at start',
                                               action='edge_arrowhead_start')
        self.arrowhead_end_button = checkbox(ui, self, hlayout, label='at end',
                                             action='edge_arrowhead_end')
        layout.addWidget(hdivider())
        layout.addSpacing(spac)
        # Curvature

        hlayout = box_row(layout)
        curve_modes = QtWidgets.QButtonGroup()
        self.relative_arc_button = radiobutton(ui, self, hlayout, label='Relative curve',
                                               action='edge_curvature_relative', group=curve_modes)
        self.arc_rel_dx_spinbox = spinbox(ui, self, hlayout,
                                          label='X', range_min=-200, range_max=200,
                                          action='change_edge_relative_curvature_x',
                                          suffix='%')
        self.arc_rel_dy_spinbox = spinbox(ui, self, hlayout,
                                          label='Y', range_min=-200, range_max=200,
                                          action='change_edge_relative_curvature_y',
                                          suffix='%')

        hlayout = box_row(layout)
        self.fixed_arc_button = radiobutton(ui, self, hlayout, label='Fixed curve',
                                            action='edge_curvature_fixed', group=curve_modes)
        self.arc_fixed_dx_spinbox = spinbox(ui, self, hlayout,
                                            label='X', range_min=-200, range_max=200,
                                            action='change_edge_fixed_curvature_x',
                                            suffix=' px')
        self.arc_fixed_dy_spinbox = spinbox(ui, self, hlayout,
                                            label='Y', range_min=-200, range_max=200,
                                            action='change_edge_fixed_curvature_y',
                                            suffix=' px')
        self.arc_reference_buttons = QtWidgets.QButtonGroup(self)
        self.arc_reference_buttons.addButton(self.fixed_arc_button)
        self.arc_reference_buttons.addButton(self.relative_arc_button)


        # Leaf size
        hlayout = box_row(layout)
        self.leaf_x_spinbox = decimal_spinbox(ui, self, hlayout, label='Brush spread X',
                                              range_min=-20.0,
                                              range_max=20.0,
                                              step=0.5,
                                              action='leaf_shape_x', suffix=' px')
        self.leaf_y_spinbox = decimal_spinbox(ui, self, hlayout, label='Y',
                                              range_min=-20.0,
                                              range_max=20.0,
                                              step=0.5,
                                              action='leaf_shape_y', suffix=' px')
        layout.addWidget(hdivider())
        layout.addSpacing(spac)

        hlayout = box_row(layout)
        self.reset_all = mini_button(ui, self, hlayout, text='Reset edge settings',
                                     action='reset_edge_settings', width=-1)
        self.reset_adjustment = mini_button(ui, self, hlayout,
                                            text='Reset curves',
                                            action='reset_control_points', width=-1)
        inner.setLayout(layout)
        self.setWidget(inner)
        self.finish_init()