def __init__(self): super(AccelMapEditor, self).__init__() self.ui_manager = None self.connect("show", self._show_cb) store = Gtk.ListStore(*self._COLUMN_TYPES) self._store = store self._action_labels = {} self._accel_labels = {} scrolls = Gtk.ScrolledWindow() scrolls.set_shadow_type(Gtk.ShadowType.IN) view = Gtk.TreeView() view.set_model(store) view.set_size_request(480, 320) view.set_hexpand(True) view.set_vexpand(True) scrolls.add(view) self.attach(scrolls, 0, 0, 1, 1) view.set_headers_clickable(True) view.set_enable_search(True) view.set_search_column(self._SEARCH_TEXT_COLUMN) view.set_search_equal_func(self._view_search_equal_cb) self._view = view cell = Gtk.CellRendererText() cell.set_property("ellipsize", Pango.EllipsizeMode.END) cell.set_property("editable", False) cell.set_property("ypad", 8) cell.set_property("xpad", 8) col = Gtk.TreeViewColumn(_("Action"), cell) col.add_attribute(cell, "markup", self._ACTION_LABEL_COLUMN) col.set_expand(True) col.set_resizable(True) col.set_min_width(200) col.set_sort_column_id(self._ACTION_LABEL_SORT_COLUMN) view.append_column(col) cell = Gtk.CellRendererText() cell.set_property("ellipsize", Pango.EllipsizeMode.END) cell.set_property("editable", True) cell.set_property("ypad", 8) cell.set_property("xpad", 8) cell.connect("edited", self._accel_edited_cb) cell.connect("editing-started", self._accel_editing_started_cb) # TRANSLATORS: Refers to a keyboard key combination, such as "Ctrl+G". # TRANSLATORS: Second column label in the keybinding preferences tab. col = Gtk.TreeViewColumn(_("Key combination"), cell) col.add_attribute(cell, "markup", self._ACCEL_LABEL_COLUMN) col.set_expand(False) col.set_resizable(True) col.set_min_width(75) col.set_sort_column_id(self._ACCEL_LABEL_SORT_COLUMN) view.append_column(col) store.set_sort_column_id( self._ACTION_LABEL_SORT_COLUMN, Gtk.SortType.ASCENDING, )
def __init__(self, app): self.app = app combo = Gtk.ComboBox() store = Gtk.ListStore() store.set_column_types((str, str)) for k, v in _FILE_OPEN_OPTIONS: store.append((k, v)) combo.set_model(store) combo.set_active(0) cell = Gtk.CellRendererText() combo.pack_start(cell, True) combo.add_attribute(cell, 'text', 1) combo_label = Gtk.Label( # TRANSLATORS: This is a label for a dropdown menu in the # TRANSLATORS: file chooser dialog when loading .ora files. label=C_("File Load Compat Options", "Compatibility mode:")) hbox = Gtk.HBox() hbox.set_spacing(6) hbox.pack_start(combo_label, False, False, 0) hbox.pack_start(combo, False, False, 0) hbox.show_all() hbox.set_visible(False) self._compat_override = None self._combo = combo combo.connect('changed', self._combo_changed_cb) self._widget = hbox
def __init__(self, combobox, prefs): self.combo = combobox self.prefs = prefs options_store = Gtk.ListStore() options_store.set_column_types((str, str)) for option in self._OPTIONS: options_store.append((option, self._LABELS[option])) combobox.set_model(options_store) cell = Gtk.CellRendererText() combobox.pack_start(cell, True) combobox.add_attribute(cell, 'text', 1) self.update_ui() combobox.connect('changed', self.changed_cb)
def new_blend_mode_combo(modes, mode_strings): """Create and return a new blend mode combo box """ store = Gtk.ListStore(int, str, bool, float) for mode in modes: label, desc = mode_strings.get(mode) sensitive = True scale = 1 / 1.2 # PANGO_SCALE_SMALL store.append([mode, label, sensitive, scale]) combo = Gtk.ComboBox() combo.set_model(store) combo.set_hexpand(True) combo.set_vexpand(False) cell = Gtk.CellRendererText() combo.pack_start(cell, True) combo.add_attribute(cell, "text", 1) combo.add_attribute(cell, "sensitive", 2) combo.add_attribute(cell, "scale", 3) combo.set_wrap_width(2) combo.set_app_paintable(True) return combo
def __init__(self, monitor=None): """Initialize :param Monitor monitor: monitor instance (for testing) By default, the central app's `device_monitor` is used to permit parameterless construction. """ super(SettingsEditor, self).__init__() if monitor is None: app = gui.application.get_app() monitor = app.device_monitor self._monitor = monitor self._devices_store = Gtk.ListStore(object) self._devices_view = Gtk.TreeView(model=self._devices_store) col = Gtk.TreeViewColumn( C_( "prefs: devices table: column header", # TRANSLATORS: Column's data is the device's name "Device", )) col.set_min_width(200) col.set_expand(True) col.set_sizing(Gtk.TreeViewColumnSizing.AUTOSIZE) self._devices_view.append_column(col) cell = Gtk.CellRendererText() cell.set_property("ellipsize", Pango.EllipsizeMode.MIDDLE) col.pack_start(cell, True) col.set_cell_data_func(cell, self._device_name_datafunc) col = Gtk.TreeViewColumn( C_( "prefs: devices table: column header", # TRANSLATORS: Column's data is the number of axes (an integer) "Axes", )) col.set_min_width(30) col.set_resizable(True) col.set_expand(False) col.set_sizing(Gtk.TreeViewColumnSizing.AUTOSIZE) self._devices_view.append_column(col) cell = Gtk.CellRendererText() col.pack_start(cell, True) col.set_cell_data_func(cell, self._device_axes_datafunc) col = Gtk.TreeViewColumn( C_( "prefs: devices table: column header", # TRANSLATORS: Column shows type labels ("Touchscreen", "Pen" etc.) "Type", )) col.set_min_width(120) col.set_resizable(True) col.set_expand(False) col.set_sizing(Gtk.TreeViewColumnSizing.AUTOSIZE) self._devices_view.append_column(col) cell = Gtk.CellRendererText() cell.set_property("ellipsize", Pango.EllipsizeMode.END) col.pack_start(cell, True) col.set_cell_data_func(cell, self._device_type_datafunc) # Usage config value => string store (dropdowns) store = Gtk.ListStore(str, str) for conf_val in AllowedUsage.VALUES: string = AllowedUsage.DISPLAY_STRING[conf_val] store.append([conf_val, string]) self._usage_store = store col = Gtk.TreeViewColumn( C_( "prefs: devices table: column header", # TRANSLATORS: Column's data is a dropdown allowing the allowed # TRANSLATORS: tasks for the row's device to be configured. u"Use for…", )) col.set_min_width(100) col.set_resizable(True) col.set_expand(False) self._devices_view.append_column(col) cell = Gtk.CellRendererCombo() cell.set_property("model", self._usage_store) cell.set_property("text-column", self._USAGE_STRING_COL) cell.set_property("mode", Gtk.CellRendererMode.EDITABLE) cell.set_property("editable", True) cell.set_property("has-entry", False) cell.set_property("ellipsize", Pango.EllipsizeMode.END) cell.connect("changed", self._usage_cell_changed_cb) col.pack_start(cell, True) col.set_cell_data_func(cell, self._device_usage_datafunc) # Scroll action config value => string store (dropdowns) store = Gtk.ListStore(str, str) for conf_val in ScrollAction.VALUES: string = ScrollAction.DISPLAY_STRING[conf_val] store.append([conf_val, string]) self._scroll_store = store col = Gtk.TreeViewColumn( C_( "prefs: devices table: column header", # TRANSLATORS: Column's data is a dropdown for how the device's # TRANSLATORS: scroll wheel or scroll-gesture events are to be # TRANSLATORS: interpreted normally. u"Scroll…", )) col.set_min_width(100) col.set_resizable(True) col.set_expand(False) self._devices_view.append_column(col) cell = Gtk.CellRendererCombo() cell.set_property("model", self._scroll_store) cell.set_property("text-column", self._USAGE_STRING_COL) cell.set_property("mode", Gtk.CellRendererMode.EDITABLE) cell.set_property("editable", True) cell.set_property("has-entry", False) cell.set_property("ellipsize", Pango.EllipsizeMode.END) cell.connect("changed", self._scroll_cell_changed_cb) col.pack_start(cell, True) col.set_cell_data_func(cell, self._device_scroll_datafunc) # Pretty borders view_scroll = Gtk.ScrolledWindow() view_scroll.set_shadow_type(Gtk.ShadowType.ETCHED_IN) pol = Gtk.PolicyType.AUTOMATIC view_scroll.set_policy(pol, pol) view_scroll.add(self._devices_view) view_scroll.set_hexpand(True) view_scroll.set_vexpand(True) self.attach(view_scroll, 0, 0, 1, 1) self._update_devices_store() self._monitor.devices_updated += self._update_devices_store
def __init__(self, content_type, specific_file=False): Gtk.Dialog.__init__(self) self.set_title(_(u"Open With…")) self.add_button(Gtk.STOCK_CANCEL, Gtk.ResponseType.CANCEL) self.add_button(Gtk.STOCK_OK, Gtk.ResponseType.OK) self.set_default_response(Gtk.ResponseType.CANCEL) self.set_response_sensitive(Gtk.ResponseType.OK, False) self.connect("show", self._show_cb) content_box = self.get_content_area() content_box.set_border_width(12) content_box.set_spacing(12) msg_template = self.GENERIC_MSG if specific_file: msg_template = self.SPECIFIC_FILE_MSG msg_text = msg_template.format( content_type=content_type, type_name=Gio.content_type_get_description(content_type), ) msg_label = Gtk.Label(label=msg_text) msg_label.set_single_line_mode(False) msg_label.set_line_wrap(True) msg_label.set_alignment(0.0, 0.5) content_box.pack_start(msg_label, False, False, 0) default_app = Gio.AppInfo.get_default_for_type(content_type, False) default_iter = None app_list_store = Gtk.ListStore(object) apps = Gio.AppInfo.get_all_for_type(content_type) for app in apps: if not app.should_show(): continue row_iter = app_list_store.append([app]) if default_iter is not None: continue if default_app and Gio.AppInfo.equal(app, default_app): default_iter = row_iter # TreeView to show available apps for this content type view = Gtk.TreeView() view.set_model(app_list_store) view.set_headers_clickable(False) view.set_headers_visible(False) view.connect("row-activated", self._row_activated_cb) view_scrolls = Gtk.ScrolledWindow() view_scrolls.set_shadow_type(Gtk.ShadowType.IN) view_scrolls.add(view) view_scrolls.set_size_request(375, 225) content_box.pack_start(view_scrolls, True, True, 0) # Column 0: application icon cell = Gtk.CellRendererPixbuf() col = Gtk.TreeViewColumn(_("Icon"), cell) col.set_cell_data_func(cell, self._app_icon_datafunc) icon_size_ok, icon_w, icon_h = Gtk.icon_size_lookup(self.ICON_SIZE) if icon_size_ok: col.set_min_width(icon_w) col.set_expand(False) col.set_resizable(False) view.append_column(col) # Column 1: application name cell = Gtk.CellRendererText() cell.set_property("ellipsize", Pango.EllipsizeMode.END) cell.set_property("editable", False) col = Gtk.TreeViewColumn(_("Name"), cell) col.set_cell_data_func(cell, self._app_name_datafunc) col.set_expand(True) col.set_min_width(150) view.append_column(col) # Selection: mode and initial value selection = view.get_selection() selection.set_mode(Gtk.SelectionMode.SINGLE) if default_iter: selection.select_iter(default_iter) self.set_default_response(Gtk.ResponseType.OK) self.set_response_sensitive(Gtk.ResponseType.OK, True) selection.connect("changed", self._selection_changed_cb) # Results go here self.selected_appinfo = default_app #: The app the user chose
def setup_locale_combobox(locale_combo): # Set up locales liststore locale_liststore = Gtk.ListStore() default_loc = C_( "Language preferences menu - default option", # TRANSLATORS: This option means that MyPaint will try to use # TRANSLATORS: the language the system tells it to use. "System Language" ) # Default value - use the system locale locale_liststore.set_column_types((str, str, str)) locale_liststore.append((None, default_loc, default_loc)) loc_names = lib.localecodes.LOCALE_DICT # Base language - US english base_locale = "en_US" locale_liststore.append((base_locale, loc_names[base_locale][0], "")) # Separator locale_liststore.append((None, None, None)) supported_locales = lib.config.supported_locales def tuplify(loc): if loc in loc_names: name_en, name_native = loc_names[loc] return loc, name_en, name_native else: logger.warning("Locale name not found: (%s)", loc) return loc, loc, loc # Sort alphabetically on english name of language for i in sorted(map(tuplify, supported_locales), key=lambda a: a[1]): locale_liststore.append(i) def sep_func(model, it): return model[it][1] is None def render_language_names(_, name_cell, model, it): locale, lang_en, lang_nat = model[it][:3] # Mark default with bold font if locale is None: name_cell.set_property( "markup", "<b>{lang_en}</b>".format(lang_en=lang_en) ) # If a language does not have its native spelling # available, only show its name in english. elif lang_en == lang_nat or lang_nat == "": name_cell.set_property( "text", lang_en ) else: name_cell.set_property( "text", C_( "Prefs Dialog|View|Interface - menu entries", # TRANSLATORS: lang_en is the english name of the language # TRANSLATORS: lang_nat is the native name of the language # TRANSLATORS: in that _same language_. # TRANSLATORS: This can just be copied most of the time. "{lang_en} - ({lang_nat})" ).format( lang_en=lang_en, lang_nat=lang_nat ) ) # Remove the existing cell renderer locale_combo.clear() locale_combo.set_row_separator_func(sep_func) cell = Gtk.CellRendererText() locale_combo.pack_start(cell, True) locale_combo.set_cell_data_func(cell, render_language_names) locale_combo.set_model(locale_liststore)
def __init__(self): Gtk.Grid.__init__(self) self.set_row_spacing(6) self.set_column_spacing(6) from gui.application import get_app self.app = get_app() prefs = self.app.preferences row = 0 label = Gtk.Label() label.set_markup( C_( "fill options: numeric value that determines whether tested pixels" " will be included in the fill, based on color difference", u"Tolerance:")) label.set_tooltip_text( C_( "fill options: Tolerance (tooltip) " "Note: 'the start' refers to the color of " "the starting point (pixel) of the fill", u"How much pixel colors are allowed to vary from the start\n" u"before Flood Fill will refuse to fill them")) label.set_alignment(1.0, 0.5) label.set_hexpand(False) self.attach(label, 0, row, 1, 1) value = prefs.get(self.TOLERANCE_PREF, self.DEFAULT_TOLERANCE) value = float(value) adj = Gtk.Adjustment(value=value, lower=0.0, upper=1.0, step_increment=0.05, page_increment=0.05, page_size=0) adj.connect("value-changed", self._tolerance_changed_cb) self._tolerance_adj = adj scale = Gtk.Scale() scale.set_hexpand(True) scale.set_adjustment(adj) scale.set_draw_value(False) self.attach(scale, 1, row, 1, 1) row += 1 label = Gtk.Label() label.set_markup( C_( "fill options: option category (label) " "Options under this category relate to what the fill is" "based on, not where the actual fill ends up.", u"Source:")) label.set_tooltip_text( C_("fill options: 'Source:' category (tooltip)", u"The input that the fill will be based on")) label.set_alignment(1.0, 0.5) label.set_hexpand(False) self.attach(label, 0, row, 1, 1) # Selection independent fill-basis root = self.app.doc.model.layer_stack src_list = FlatLayerList(root) self.src_list = src_list combo = Gtk.ComboBox.new_with_model(src_list) cell = Gtk.CellRendererText() cell.set_property("ellipsize", Pango.EllipsizeMode.END) combo.pack_start(cell, True) def layer_name_render(_, name_cell, model, it): """ Display layer groups in italics and child layers indented with two spaces per level """ name, path, layer = model[it][:3] if name is None: name = "Layer" if layer is None: name_cell.set_property("markup", "( <i>{text}</i> )".format(text=name)) return indented = " " * (len(path) - 1) + name if isinstance(layer, lib.layer.LayerStack): name_cell.set_property("markup", "<i>{text}</i>".format(text=indented)) else: name_cell.set_property("text", indented) def sep_func(model, it): return model[it][0] is None combo.set_row_separator_func(sep_func) combo.set_cell_data_func(cell, layer_name_render) combo.set_tooltip_text( C_("fill options: 'Source' category: Layer dropdown (tooltip)", u"Select a specific layer you want the fill to be based on")) combo.set_active(0) self._prev_src_layer = None root.layer_inserted += self._layer_inserted_cb self._src_combo_cb_id = combo.connect("changed", self._src_combo_changed_cb) self._src_combo = combo self.attach(combo, 1, row, 2, 1) row += 1 text = C_( "fill options: 'Source:' category: toggle (label)\n" "When this option is enabled, the fill is based\n" "on the combination of all visible layers", u"Sample Merged") checkbut = Gtk.CheckButton.new_with_label(text) checkbut.set_tooltip_text( C_( "fill options: Sample Merged (tooltip)", u"When considering which area to fill, use a\n" u"temporary merge of all the visible layers\n" u"underneath the current layer")) self.attach(checkbut, 1, row, 1, 1) active = bool( prefs.get(self.SAMPLE_MERGED_PREF, self.DEFAULT_SAMPLE_MERGED)) checkbut.set_active(active) checkbut.connect("toggled", self._sample_merged_toggled_cb) self._sample_merged_toggle = checkbut self._src_combo.set_sensitive(not active) row += 1 text = C_( "fill options: toggle whether the fill will be limited " "by the viewport", u"Limit to View") checkbut = Gtk.CheckButton.new_with_label(text) checkbut.set_tooltip_text( C_( "fill options: Limit to View (tooltip)\n" "Note: 'that can fit the view' is equivalent to: " "'in which the entire visible part of the canvas can fit", u"Limit the area that can be filled, based on the viewport.\n" u"If the view is rotated, the fill will be limited to the\n" u"smallest canvas-aligned rectangle that can fit the view.")) self.attach(checkbut, 1, row, 1, 1) active = bool( prefs.get(self.LIM_TO_VIEW_PREF, self.DEFAULT_LIM_TO_VIEW)) checkbut.set_active(active) checkbut.connect("toggled", self._limit_to_view_toggled_cb) self._limit_to_view_toggle = checkbut row += 1 label = Gtk.Label() label.set_markup( C_( "fill options: option category (label)\n" "Options under this category relate to where the fill " "will end up (default: the active layer) and how it " "will be combined with that layer.", u"Target:")) label.set_tooltip_text( C_("fill options: 'Target:' category (tooltip)", u"Where the output should go")) label.set_alignment(1.0, 0.5) label.set_hexpand(False) self.attach(label, 0, row, 1, 1) text = C_( "fill options: Target | toggle (label)\n" "When this option is enabled, the fill will be placed on a new\n" "layer above the active layer. Option resets after each fill.", u"New Layer (once)") checkbut = Gtk.CheckButton.new_with_label(text) checkbut.set_tooltip_text( C_( "fill options: Target | New Layer (tooltip)", u"Create a new layer with the results of the fill.\n" u"This is turned off automatically after use.")) self.attach(checkbut, 1, row, 1, 1) active = self.DEFAULT_MAKE_NEW_LAYER checkbut.set_active(active) self._make_new_layer_toggle = checkbut row += 1 label = Gtk.Label() label.set_markup(u"<b>\u26a0</b>") # unicode warning sign label.set_tooltip_text( C_("fill options: Target | Blend Mode dropdown - warning text", u"This mode does nothing when alpha locking is enabled!")) label.set_alignment(1.0, 0.5) label.set_hexpand(False) self._warning_shown = False # Not attached here, warning label is only shown for no-op combinations self._bm_warning_label = (label, 0, row, 1, 1) modes = list(lib.modes.STANDARD_MODES) modes.remove(lib.mypaintlib.CombineSpectralWGM) modes.insert(0, lib.mypaintlib.CombineSpectralWGM) combo = gui.layers.new_blend_mode_combo(modes, lib.modes.MODE_STRINGS) combo.set_tooltip_text( C_("fill options: Target | Blend Mode dropdown (tooltip)", u"Blend mode used when filling")) # Reinstate the last _mode id_ independent of mode-list order mode_type = prefs.get(self.BLEND_MODE_PREF, self.DEFAULT_BLEND_MODE) mode_dict = {mode: index for index, mode, in enumerate(modes)} # Fallback is only necessary for compat. if a mode is ever removed active = mode_dict.get(int(mode_type), self.DEFAULT_BLEND_MODE) combo.set_active(active) combo.connect("changed", self._bm_combo_changed_cb) self._blend_mode_combo = combo self.attach(combo, 1, row, 2, 1) row += 1 label = Gtk.Label() label.set_markup(_(u"Opacity:")) label.set_tooltip_text( C_("fill options: Opacity slider (tooltip)", u"Opacity of the fill")) label.set_alignment(1.0, 0.5) label.set_hexpand(False) self.attach(label, 0, row, 1, 1) value = prefs.get(self.OPACITY_PREF, self.DEFAULT_OPACITY) adj = Gtk.Adjustment(value=value, lower=0.0, upper=1.0, step_increment=0.05, page_increment=0.05, page_size=0) adj.connect("value-changed", self._opacity_changed_cb) self._opacity_adj = adj scale = Gtk.Scale() scale.set_hexpand(True) scale.set_adjustment(adj) scale.set_draw_value(False) self.attach(scale, 1, row, 1, 1) row += 1 self.attach(Gtk.Separator(), 0, row, 2, 1) row += 1 label = Gtk.Label() label.set_markup( C_("fill options: numeric option - grow/shrink fill (label)", u"Offset:")) label.set_alignment(1.0, 0.5) label.set_hexpand(False) self.attach(label, 0, row, 1, 1) TILE_SIZE = lib.floodfill.TILE_SIZE value = prefs.get(self.OFFSET_PREF, self.DEFAULT_OFFSET) adj = Gtk.Adjustment(value=value, lower=-TILE_SIZE, upper=TILE_SIZE, step_increment=1, page_increment=4) adj.connect("value-changed", self._offset_changed_cb) self._offset_adj = adj spinbut = Gtk.SpinButton() spinbut.set_tooltip_text( C_("fill options: Offset (tooltip)", u"The distance in pixels to grow or shrink the fill")) spinbut.set_hexpand(True) spinbut.set_adjustment(adj) spinbut.set_numeric(True) self.attach(spinbut, 1, row, 1, 1) row += 1 label = Gtk.Label() label.set_markup( C_("fill options: numeric option for blurring fill (label)", u"Feather:")) label.set_alignment(1.0, 0.5) label.set_hexpand(False) self.attach(label, 0, row, 1, 1) value = prefs.get(self.FEATHER_PREF, self.DEFAULT_FEATHER) adj = Gtk.Adjustment(value=value, lower=0, upper=TILE_SIZE, step_increment=1, page_increment=4) adj.connect("value-changed", self._feather_changed_cb) self._feather_adj = adj spinbut = Gtk.SpinButton() spinbut.set_tooltip_text( C_("fill options: Feather (tooltip)", u"The amount of blur to apply to the fill")) spinbut.set_hexpand(True) spinbut.set_adjustment(adj) spinbut.set_numeric(True) self.attach(spinbut, 1, row, 1, 1) row += 1 self.attach(Gtk.Separator(), 0, row, 2, 1) row += 1 gap_closing_params = Gtk.Grid() self._gap_closing_grid = gap_closing_params text = C_("fill options: gap detection toggle (label)", u'Use Gap Detection') checkbut = Gtk.CheckButton.new_with_label(text) checkbut.set_tooltip_text( C_( "fill options: Use Gap Detection (tooltip)", u"Try to detect gaps and not fill past them.\n" u"Note: This can be a lot slower than the regular fill, " u"only enable when you need it.")) self._gap_closing_toggle = checkbut checkbut.connect("toggled", self._gap_closing_toggled_cb) active = prefs.get(self.GAP_CLOSING_PREF, self.DEFAULT_GAP_CLOSING) checkbut.set_active(active) gap_closing_params.set_sensitive(active) self.attach(checkbut, 0, row, 2, 1) row += 1 self.attach(gap_closing_params, 0, row, 2, 1) gcp_row = 0 label = Gtk.Label() label.set_markup( C_( "fill options: gap-detection sub-option, numeric setting (label)", u"Max Gap Size:")) label.set_alignment(1.0, 0.5) label.set_hexpand(False) gap_closing_params.attach(label, 0, gcp_row, 1, 1) value = prefs.get(self.GAP_SIZE_PREF, self.DEFAULT_GAP_SIZE) adj = Gtk.Adjustment(value=value, lower=1, upper=int(TILE_SIZE / 2), step_increment=1, page_increment=4) adj.connect("value-changed", self._max_gap_size_changed_cb) self._max_gap_adj = adj spinbut = Gtk.SpinButton() spinbut.set_tooltip_text( C_( "fill options: Max Gap Size (tooltip)", u"The size of the largest gaps that can be detected.\n" u"Using large values can make the fill run a lot slower.")) spinbut.set_hexpand(True) spinbut.set_adjustment(adj) spinbut.set_numeric(True) gap_closing_params.attach(spinbut, 1, gcp_row, 1, 1) gcp_row += 1 text = C_( "fill options: on/off sub-option, numeric (label)\n" "When enabled, if the fill stops after going past a detected gap, " "it 'pulls' the fill back out of the gap to the other side of it.", u"Prevent seeping") checkbut = Gtk.CheckButton.new_with_label(text) active = prefs.get(self.RETRACT_SEEPS_PREF, self.DEFAULT_RETRACT_SEEPS) checkbut.set_active(active) checkbut.set_tooltip_text( C_( "fill options: Prevent seeping (tooltip)", u"Try to prevent the fill from seeping into the gaps.\n" u"If a fill starts in a detected gap, this option will do nothing." )) checkbut.connect("toggled", self._retract_seeps_toggled_cb) self._retract_seeps_toggle = checkbut gap_closing_params.attach(checkbut, 1, gcp_row, 1, 1) row += 1 align = Gtk.Alignment.new(0.5, 1.0, 1.0, 0.0) align.set_vexpand(True) button = Gtk.Button(label=_("Reset")) button.connect("clicked", self._reset_clicked_cb) button.set_tooltip_text( C_("fill options: Reset button (tooltip)", "Reset options to their defaults")) align.add(button) self.attach(align, 0, row, 2, 1) # Set up blend modifier callbacks self.bm = self.get_blend_modes() self.bm.mode_changed += self.update_blend_mode
def _init_ui(self): app = self.app # Dialog for showing and editing the axis value directly buttons = (Gtk.STOCK_OK, Gtk.ResponseType.ACCEPT) dialog = gui.windowing.Dialog( app, C_( "symmetry axis options panel: " "axis position dialog: window title", u"X axis Position", ), app.drawWindow, buttons=buttons, ) dialog.connect('response', self._axis_pos_dialog_response_cb) grid = Gtk.Grid() grid.set_border_width(gui.widgets.SPACING_LOOSE) grid.set_column_spacing(gui.widgets.SPACING) grid.set_row_spacing(gui.widgets.SPACING) label = Gtk.Label(label=self._POSITION_LABEL_X_TEXT) label.set_hexpand(False) label.set_vexpand(False) grid.attach(label, 0, 0, 1, 1) entry = Gtk.SpinButton( adjustment=self._axis_pos_adj_x, climb_rate=0.25, digits=0 ) entry.set_hexpand(True) entry.set_vexpand(False) grid.attach(entry, 1, 0, 1, 1) dialog_content_box = dialog.get_content_area() dialog_content_box.pack_start(grid, True, True, 0) self._axis_pos_x_dialog = dialog # Dialog for showing and editing the axis value directly buttons = (Gtk.STOCK_OK, Gtk.ResponseType.ACCEPT) dialog = gui.windowing.Dialog( app, C_( "symmetry axis options panel: " "axis position dialog: window title", u"Y axis Position", ), app.drawWindow, buttons=buttons, ) dialog.connect('response', self._axis_pos_dialog_response_cb) grid = Gtk.Grid() grid.set_border_width(gui.widgets.SPACING_LOOSE) grid.set_column_spacing(gui.widgets.SPACING) grid.set_row_spacing(gui.widgets.SPACING) label = Gtk.Label(label=self._POSITION_LABEL_Y_TEXT) label.set_hexpand(False) label.set_vexpand(False) grid.attach(label, 0, 0, 1, 1) entry = Gtk.SpinButton( adjustment=self._axis_pos_adj_y, climb_rate=0.25, digits=0 ) entry.set_hexpand(True) entry.set_vexpand(False) grid.attach(entry, 1, 0, 1, 1) dialog_content_box = dialog.get_content_area() dialog_content_box.pack_start(grid, True, True, 0) self._axis_pos_y_dialog = dialog # Layout grid row = 0 grid = Gtk.Grid() grid.set_border_width(gui.widgets.SPACING_CRAMPED) grid.set_row_spacing(gui.widgets.SPACING_CRAMPED) grid.set_column_spacing(gui.widgets.SPACING_CRAMPED) self.add(grid) row += 1 label = Gtk.Label(label=self._ALPHA_LABEL_TEXT) label.set_hexpand(False) label.set_halign(Gtk.Align.START) grid.attach(label, 0, row, 1, 1) scale = Gtk.Scale.new_with_range( orientation = Gtk.Orientation.HORIZONTAL, min = 0, max = 1, step = 0.1, ) scale.set_draw_value(False) line_alpha = self.app.preferences.get(_ALPHA_PREFS_KEY, _DEFAULT_ALPHA) scale.set_value(line_alpha) scale.set_hexpand(True) scale.set_vexpand(False) scale.connect("value-changed", self._scale_value_changed_cb) grid.attach(scale, 1, row, 1, 1) row += 1 store = Gtk.ListStore(int, str) sym_types = lib.tiledsurface.SYMMETRY_TYPES active_idx = 0 rootstack = self.app.doc.model.layer_stack starts_with_rotate = ( rootstack.symmetry_type in { lib.mypaintlib.SymmetryRotational, lib.mypaintlib.SymmetrySnowflake, } ) for i, sym_type in enumerate(sym_types): label = lib.tiledsurface.SYMMETRY_STRINGS.get(sym_type) store.append([sym_type, label]) if sym_type == rootstack.symmetry_type: active_idx = i self._symmetry_type_combo = Gtk.ComboBox() self._symmetry_type_combo.set_model(store) self._symmetry_type_combo.set_active(active_idx) self._symmetry_type_combo.set_hexpand(True) cell = Gtk.CellRendererText() self._symmetry_type_combo.pack_start(cell, True) self._symmetry_type_combo.add_attribute(cell, "text", 1) self._symmetry_type_combo.connect( 'changed', self._symmetry_type_combo_changed_cb ) label = Gtk.Label(label=self._SYMMETRY_TYPE_TEXT) label.set_hexpand(False) label.set_halign(Gtk.Align.START) grid.attach(label, 0, row, 1, 1) grid.attach(self._symmetry_type_combo, 1, row, 1, 1) row += 1 label = Gtk.Label(label=self._SYMMETRY_ROT_LINES_TEXT) label.set_hexpand(False) label.set_halign(Gtk.Align.START) self._axis_rot_sym_lines_entry = Gtk.SpinButton( adjustment=self._axis_rot_symmetry_lines, climb_rate=0.25 ) grid.attach(label, 0, row, 1, 1) grid.attach(self._axis_rot_sym_lines_entry, 1, row, 1, 1) row += 1 label = Gtk.Label(label=self._POSITION_LABEL_X_TEXT) label.set_hexpand(False) label.set_halign(Gtk.Align.START) button = Gtk.Button(label=self._POSITION_BUTTON_TEXT_INACTIVE) button.set_vexpand(False) button.connect("clicked", self._axis_pos_x_button_clicked_cb) button.set_hexpand(True) button.set_vexpand(False) grid.attach(label, 0, row, 1, 1) grid.attach(button, 1, row, 1, 1) self._axis_pos_x_button = button row += 1 label = Gtk.Label(label=self._POSITION_LABEL_Y_TEXT) label.set_hexpand(False) label.set_halign(Gtk.Align.START) button = Gtk.Button(label=self._POSITION_BUTTON_TEXT_INACTIVE) button.set_vexpand(False) button.connect("clicked", self._axis_pos_y_button_clicked_cb) button.set_hexpand(True) button.set_vexpand(False) grid.attach(label, 0, row, 1, 1) grid.attach(button, 1, row, 1, 1) self._axis_pos_y_button = button row += 1 button = Gtk.CheckButton() toggle_action = self.app.find_action("SymmetryActive") button.set_related_action(toggle_action) button.set_label(C_( "symmetry axis options panel: axis active checkbox", u'Enabled', )) button.set_hexpand(True) button.set_vexpand(False) grid.attach(button, 1, row, 2, 1) self._axis_active_button = button
def __init__(self): """Initialise. """ super(ButtonMappingEditor, self).__init__() import gui.application self.app = gui.application.get_app() self.actions = set() self.default_action = None self.bindings = None #: dict of bindings being edited self.vbox = Gtk.VBox() self.add(self.vbox) # Display strings for action names self.action_labels = dict() # Model: combo cellrenderer's liststore ls = Gtk.ListStore(GObject.TYPE_STRING, GObject.TYPE_STRING) self.action_liststore = ls self.action_liststore_value_column = 0 self.action_liststore_display_column = 1 # Model: main list's liststore # This is reflected into self.bindings when it changes column_types = [GObject.TYPE_STRING] * 3 ls = Gtk.ListStore(*column_types) self.action_column = 0 self.bp_column = 1 self.bpd_column = 2 for sig in ("row-changed", "row-deleted", "row_inserted"): ls.connect(sig, self._liststore_updated_cb) self.liststore = ls # Bindings hash observers, external interface self.bindings_observers = [] #: List of cb(editor) callbacks # View: treeview scrolledwin = Gtk.ScrolledWindow() scrolledwin.set_shadow_type(Gtk.ShadowType.IN) tv = Gtk.TreeView() tv.set_model(ls) scrolledwin.add(tv) self.vbox.pack_start(scrolledwin, True, True, 0) tv.set_size_request(480, 320) tv.set_headers_clickable(True) self.treeview = tv self.selection = tv.get_selection() self.selection.connect("changed", self._selection_changed_cb) # Column 0: action name cell = Gtk.CellRendererCombo() cell.set_property("model", self.action_liststore) cell.set_property("text-column", self.action_liststore_display_column) cell.set_property("mode", Gtk.CellRendererMode.EDITABLE) cell.set_property("editable", True) cell.set_property("has-entry", False) cell.connect("changed", self._action_cell_changed_cb) # TRANSLATORS: Name of first column in the button map preferences. # TRANSLATORS: Refers to an action bound to a mod+button combination. col = Gtk.TreeViewColumn(_("Action"), cell) col.set_cell_data_func(cell, self._liststore_action_datafunc) col.set_min_width(150) col.set_resizable(False) col.set_expand(False) col.set_sort_column_id(self.action_column) tv.append_column(col) # Column 1: button press cell = Gtk.CellRendererText() cell.set_property("ellipsize", Pango.EllipsizeMode.END) cell.set_property("mode", Gtk.CellRendererMode.EDITABLE) cell.set_property("editable", True) cell.connect("edited", self._bp_cell_edited_cb) cell.connect("editing-started", self._bp_cell_editing_started_cb) # TRANSLATORS: Name of second column in the button map preferences. # TRANSLATORS: Column lists mod+button combinations (bound to actions) # TRANSLATORS: E.g. Button1 or Ctrl+Button2 or Alt+Button3 col = Gtk.TreeViewColumn(_("Button press"), cell) col.add_attribute(cell, "text", self.bpd_column) col.set_expand(True) col.set_resizable(True) col.set_min_width(200) col.set_sort_column_id(self.bpd_column) tv.append_column(col) # List editor toolbar list_tools = Gtk.Toolbar() list_tools.set_style(Gtk.ToolbarStyle.ICONS) list_tools.set_icon_size(widgets.ICON_SIZE_LARGE) context = list_tools.get_style_context() context.add_class("inline-toolbar") self.vbox.pack_start(list_tools, False, False, 0) # Add binding btn = Gtk.ToolButton() btn.set_tooltip_text(_("Add a new binding")) btn.set_icon_name("mypaint-add-symbolic") btn.connect("clicked", self._add_button_clicked_cb) list_tools.add(btn) # Remove (inactive if list is empty) btn = Gtk.ToolButton() btn.set_icon_name("mypaint-remove-symbolic") btn.set_tooltip_text(_("Remove the current binding")) btn.connect("clicked", self._remove_button_clicked_cb) list_tools.add(btn) self.remove_button = btn self._updating_model = False
def __init__(self, docmodel): super(RootStackTreeView, self).__init__() self._docmodel = docmodel treemodel = RootStackTreeModelWrapper(docmodel) self.set_model(treemodel) target1 = Gtk.TargetEntry.new( target="GTK_TREE_MODEL_ROW", flags=Gtk.TargetFlags.SAME_WIDGET, info=1, ) self.drag_source_set( start_button_mask=Gdk.ModifierType.BUTTON1_MASK, targets=[target1], actions=Gdk.DragAction.MOVE, ) self.drag_dest_set( flags=Gtk.DestDefaults.MOTION | Gtk.DestDefaults.DROP, targets=[target1], actions=Gdk.DragAction.MOVE, ) self.connect("button-press-event", self._button_press_cb) # Override the default key event handlers. Unless proper handling of # these events (e.g. navigating the layers list w. the arrow keys) is # implemented, the events should neither be acted upon, nor consumed. GObject.signal_override_class_closure( GObject.signal_lookup("key-press-event", Gtk.Widget), RootStackTreeView, self._key_event_cb) GObject.signal_override_class_closure( GObject.signal_lookup("key-release-event", Gtk.Widget), RootStackTreeView, self._key_event_cb) # Motion and modifier keys during drag self.connect("drag-begin", self._drag_begin_cb) self.connect("drag-motion", self._drag_motion_cb) self.connect("drag-leave", self._drag_leave_cb) self.connect("drag-drop", self._drag_drop_cb) self.connect("drag-end", self._drag_end_cb) # Track updates from the model self._processing_model_updates = False root = docmodel.layer_stack root.current_path_updated += self._current_path_updated_cb root.expand_layer += self._expand_layer_cb root.collapse_layer += self._collapse_layer_cb root.layer_content_changed += self._layer_content_changed_cb root.current_layer_solo_changed += lambda *a: self.queue_draw() # View behaviour and appearance self.set_headers_visible(False) selection = self.get_selection() selection.set_mode(Gtk.SelectionMode.BROWSE) self.set_size_request(150, 200) # Visibility flag column col = Gtk.TreeViewColumn(_("Visible")) col.set_sizing(Gtk.TreeViewColumnSizing.FIXED) self._flags1_col = col # Visibility cell cell = Gtk.CellRendererPixbuf() col.pack_start(cell, False) datafunc = self._layer_visible_pixbuf_datafunc col.set_cell_data_func(cell, datafunc) # Name and preview column: will be indented col = Gtk.TreeViewColumn(_("Name")) col.set_sizing(Gtk.TreeViewColumnSizing.GROW_ONLY) self._name_col = col # Preview cell cell = Gtk.CellRendererPixbuf() col.pack_start(cell, False) datafunc = self._layer_preview_pixbuf_datafunc col.set_cell_data_func(cell, datafunc) self._preview_cell = cell # Name cell cell = Gtk.CellRendererText() cell.set_property("ellipsize", Pango.EllipsizeMode.END) col.pack_start(cell, True) datafunc = self._layer_name_text_datafunc col.set_cell_data_func(cell, datafunc) col.set_expand(True) col.set_min_width(48) # Other flags column col = Gtk.TreeViewColumn(_("Flags")) col.set_sizing(Gtk.TreeViewColumnSizing.GROW_ONLY) area = col.get_property("cell-area") area.set_orientation(Gtk.Orientation.VERTICAL) self._flags2_col = col # Locked cell cell = Gtk.CellRendererPixbuf() col.pack_end(cell, False) datafunc = self._layer_locked_pixbuf_datafunc col.set_cell_data_func(cell, datafunc) # Column order on screen self._columns = [ self._flags1_col, self._name_col, self._flags2_col, ] for col in self._columns: self.append_column(col) # View appearance self.set_show_expanders(True) self.set_enable_tree_lines(True) self.set_expander_column(self._name_col) self.connect_after("show", self._post_show_cb)
def _init_ui(self): # Layout grid row = 0 grid = Gtk.Grid() grid.set_border_width(gui.widgets.SPACING_CRAMPED) grid.set_row_spacing(gui.widgets.SPACING_CRAMPED) grid.set_column_spacing(gui.widgets.SPACING_CRAMPED) self.add(grid) row += 1 label = Gtk.Label(label=self._ALPHA_LABEL_TEXT) label.set_hexpand(False) label.set_halign(Gtk.Align.START) grid.attach(label, 0, row, 1, 1) scale = InputSlider() scale.set_range(0, 1) scale.set_round_digits(1) scale.set_draw_value(False) line_alpha = self.app.preferences.get(_ALPHA_PREFS_KEY, _DEFAULT_ALPHA) scale.set_value(line_alpha) scale.set_hexpand(True) scale.set_vexpand(False) scale.scale.connect("value-changed", self._scale_value_changed_cb) grid.attach(scale, 1, row, 1, 1) row += 1 store = Gtk.ListStore(int, str) rootstack = self.app.doc.model.layer_stack for _type in lib.tiledsurface.SYMMETRY_TYPES: store.append([_type, lib.tiledsurface.SYMMETRY_STRINGS[_type]]) self._symmetry_type_combo = Gtk.ComboBox() self._symmetry_type_combo.set_model(store) self._symmetry_type_combo.set_active(rootstack.symmetry_type) self._symmetry_type_combo.set_hexpand(True) cell = Gtk.CellRendererText() self._symmetry_type_combo.pack_start(cell, True) self._symmetry_type_combo.add_attribute(cell, "text", 1) self._type_cb_id = self._symmetry_type_combo.connect( 'changed', self._symmetry_type_combo_changed_cb ) label = Gtk.Label(label=self._SYMMETRY_TYPE_TEXT) label.set_hexpand(False) label.set_halign(Gtk.Align.START) grid.attach(label, 0, row, 1, 1) grid.attach(self._symmetry_type_combo, 1, row, 1, 1) row += 1 label = Gtk.Label(label=self._SYMMETRY_ROT_LINES_TEXT) label.set_hexpand(False) label.set_halign(Gtk.Align.START) self._axis_sym_lines_entry = Gtk.SpinButton( adjustment=self._axis_symmetry_lines, climb_rate=0.25 ) self._update_num_lines_sensitivity(rootstack.symmetry_type) grid.attach(label, 0, row, 1, 1) grid.attach(self._axis_sym_lines_entry, 1, row, 1, 1) row += 1 label = Gtk.Label(label=self._POSITION_LABEL_X_TEXT) label.set_hexpand(False) label.set_halign(Gtk.Align.START) entry = Gtk.SpinButton( adjustment=self._axis_pos_adj_x, climb_rate=0.25, digits=0 ) entry.set_hexpand(True) entry.set_vexpand(False) grid.attach(label, 0, row, 1, 1) grid.attach(entry, 1, row, 1, 1) row += 1 label = Gtk.Label(label=self._POSITION_LABEL_Y_TEXT) label.set_hexpand(False) label.set_halign(Gtk.Align.START) entry = Gtk.SpinButton( adjustment=self._axis_pos_adj_y, climb_rate=0.25, digits=0 ) entry.set_hexpand(True) entry.set_vexpand(False) grid.attach(label, 0, row, 1, 1) grid.attach(entry, 1, row, 1, 1) row += 1 label = Gtk.Label() label.set_hexpand(False) label.set_halign(Gtk.Align.START) self._angle_label = label self._update_angle_label() grid.attach(label, 0, row, 1, 1) scale = InputSlider(self._axis_angle) scale.set_draw_value(False) scale.set_hexpand(True) scale.set_vexpand(False) grid.attach(scale, 1, row, 1, 1) row += 1 button = Gtk.CheckButton() toggle_action = self.app.find_action("SymmetryActive") button.set_related_action(toggle_action) button.set_label(C_( "symmetry axis options panel: axis active checkbox", u'Enabled', )) button.set_hexpand(True) button.set_vexpand(False) grid.attach(button, 1, row, 2, 1)