class IconEntry(BaseEntry): class Item(SimpleEnum): priority = 0 # (value, just_label) => (label, tooltip) update = None # (old_value) => str or None ask = None # Associated menu item menuitem = None def __init__(self, widgets): super().__init__(widgets) self._value = None self._image = widgets['image'] self._button = widgets['button'] self._button.props.popup = Gtk.Menu() self._widgets_to_disable.append(self._button) self._icon_dialog = None self._path_dialog = None self._current_item = None self._items = [] for priority, (update, ask) in self._get_items(): item = self.Item(priority=priority, update=update, ask=ask) item.menuitem = Gtk.MenuItem() item.menuitem.props.visible = True item.menuitem.props.label = item.update(None, True)[0] item.menuitem.connect('activate', self._on_item_clicked, item) self._button.props.popup.append(item.menuitem) self._items.append(item) self._items.sort(key=lambda i: i.priority) def _get_value(self): return self._value def _set_value(self, value): applied_item = None tooltip = None for item in self._items: if applied_item: label, __ = item.update(None, True) else: label, tooltip = item.update(value, False) if tooltip: applied_item = item item.menuitem.get_child().set_markup(label) if not applied_item: tooltip = C_('option-entry|icon', 'Unrecognized value: {value}').format(value=value) self._button.set_tooltip_markup(tooltip) self._value = value self._current_item = applied_item self._emit_changed() def _get_items(self): return ((0, (self._update_icon, self._ask_icon)), (100, (self._update_image, self._ask_image))) def _on_item_clicked(self, menuitem, item): value = item.ask(self._value if item == self._current_item else None) if value is not None: self._set_value(value) def _update_icon(self, value, just_label=False): if just_label or value is None or not value.startswith('#'): return C_('option-entry|icon', 'Select icon name...'), None name = value[1:] label = C_('option-entry|icon', '<b>Icon: {icon}</b>').format(icon=name) tooltip = label self._image.set_from_icon_name(name, Gtk.IconSize.DIALOG) return label, tooltip def _ask_icon(self, oldvalue): if not self._icon_dialog: self._icon_dialog = IconChooserDialog() self._icon_dialog.props.transient_for = self._image.get_toplevel() if oldvalue: self._icon_dialog.select_icon(oldvalue[1:]) value = None if self._icon_dialog.run() == Gtk.ResponseType.OK: value = '#' + self._icon_dialog.get_selected_icon() self._icon_dialog.hide() return value def _update_image(self, value, just_label=False): if just_label or value is None: return C_('option-entry|icon', 'Select file...'), None if set_image_from_path(self._image, value): label = C_('option-entry|icon', '<b>File: {path}</b>') else: label = C_('option-entry|icon', '<b>File: {path}</b> (failed to load)') return (label.format(path=os.path.basename(value)), label.format(path=value)) def _ask_image(self, oldvalue): if not self._path_dialog: builder = Gtk.Builder() builder.add_from_file(get_data_path('ImageChooserDialog.ui')) self._path_dialog = builder.get_object('dialog') self._path_dialog.props.transient_for = self._image.get_toplevel() self._path_dialog.connect('update-preview', self._on_update_path_preview) preview_size = self._image.props.pixel_size preview = self._path_dialog.props.preview_widget preview.props.pixel_size = preview_size preview.set_size_request(preview_size, preview_size) if oldvalue is not None: self._path_dialog.select_filename(self._value) value = None if self._path_dialog.run() == Gtk.ResponseType.OK: value = self._path_dialog.get_filename() self._path_dialog.hide() return value def _on_update_path_preview(self, chooser): set_image_from_path(chooser.props.preview_widget, chooser.get_filename())
class IconEntry(BaseEntry): class Item(SimpleEnum): priority = 0 # (value, just_label) => (label, tooltip) update = None # (old_value) => str or None ask = None # Associated menu item menuitem = None def __init__(self, widgets): super().__init__(widgets) self._value = None self._image = widgets['image'] self._button = widgets['button'] self._button.props.popup = Gtk.Menu() self._icon_dialog = None self._path_dialog = None self._current_item = None self._add_controlled_by_state_widget(self._button) self._items = [] for priority, (update, ask) in self._get_items(): item = self.Item(priority=priority, update=update, ask=ask) item.menuitem = Gtk.MenuItem() item.menuitem.props.visible = True item.menuitem.props.label = item.update(None, True)[0] item.menuitem.connect('activate', self._on_item_clicked, item) self._button.props.popup.append(item.menuitem) self._items.append(item) self._items.sort(key=lambda i: i.priority) def _get_value(self): return self._value def _set_value(self, value): applied_item = None tooltip = None for item in self._items: if applied_item: label, __ = item.update(None, True) else: label, tooltip = item.update(value, False) if tooltip: applied_item = item item.menuitem.get_child().set_markup(label) if not applied_item: tooltip = C_('option-entry|icon', 'Unrecognized value: {value}').format(value=value) self._button.set_tooltip_markup(tooltip) self._value = value self._current_item = applied_item self._emit_changed() def _get_items(self): return ((0, (self._update_icon, self._ask_icon)), (100, (self._update_image, self._ask_image))) def _on_item_clicked(self, menuitem, item): value = item.ask(self._value if item == self._current_item else None) if value is not None: self._set_value(value) def _update_icon(self, value, just_label=False): if just_label or value is None or not value.startswith('#'): return C_('option-entry|icon', 'Select icon name...'), None name = value[1:] label = C_('option-entry|icon', '<b>Icon: {icon}</b>').format(icon=name) tooltip = label self._image.set_from_icon_name(name, Gtk.IconSize.DIALOG) return label, tooltip def _ask_icon(self, oldvalue): if not self._icon_dialog: self._icon_dialog = IconChooserDialog() self._icon_dialog.props.transient_for = self._image.get_toplevel() if oldvalue: self._icon_dialog.select_icon(oldvalue[1:]) value = None if self._icon_dialog.run() == Gtk.ResponseType.OK: value = '#' + self._icon_dialog.get_selected_icon() self._icon_dialog.hide() return value def _update_image(self, value, just_label=False): if just_label or value is None: return C_('option-entry|icon', 'Select file...'), None if set_image_from_path(self._image, value): label = C_('option-entry|icon', '<b>File: {path}</b>') else: label = C_('option-entry|icon', '<b>File: {path}</b> (failed to load)') return (label.format(path=os.path.basename(value)), label.format(path=value)) def _ask_image(self, oldvalue): if not self._path_dialog: builder = Gtk.Builder() builder.add_from_file(get_data_path('ImageChooserDialog.ui')) self._path_dialog = builder.get_object('dialog') self._path_dialog.props.transient_for = self._image.get_toplevel() self._path_dialog.connect('update-preview', self._on_update_path_preview) preview_size = self._image.props.pixel_size preview = self._path_dialog.props.preview_widget preview.props.pixel_size = preview_size preview.set_size_request(preview_size, preview_size) if oldvalue is not None: self._path_dialog.select_filename(self._value) value = None if self._path_dialog.run() == Gtk.ResponseType.OK: value = self._path_dialog.get_filename() self._path_dialog.hide() return value def _on_update_path_preview(self, chooser): set_image_from_path(chooser.props.preview_widget, chooser.get_filename())