def generate_file_chooser(self, option, path=None): """Generate a file chooser button to select a file.""" option_name = option['option'] label = Label(option['label']) file_chooser = Gtk.FileChooserButton("Choose a file for %s" % label) file_chooser.set_size_request(200, 30) if 'default_path' in option: config_key = option['default_path'] default_path = self.lutris_config.system_config.get(config_key) if default_path and os.path.exists(default_path): file_chooser.set_current_folder(default_path) file_chooser.set_action(Gtk.FileChooserAction.OPEN) file_chooser.connect("file-set", self.on_chooser_file_set, option_name) if path: # If path is relative, complete with game dir if not os.path.isabs(path): path = os.path.join(self.game.directory, path) file_chooser.unselect_all() file_chooser.select_filename(path) label.set_alignment(0.5, 0.5) file_chooser.set_valign(Gtk.Align.CENTER) self.wrapper.pack_start(label, False, False, 0) self.wrapper.pack_start(file_chooser, True, True, 0) self.option_widget = file_chooser
def generate_file_chooser(self, option, path=None): """Generate a file chooser button to select a file.""" option_name = option['option'] label = Label(option['label']) file_chooser = FileChooserEntry( title='Select file', action=Gtk.FileChooserAction.OPEN, default_path=path # reverse_expanduser(path) ) file_chooser.set_size_request(200, 30) if 'default_path' in option: config_key = option['default_path'] default_path = self.lutris_config.system_config.get(config_key) if default_path and os.path.exists(default_path): file_chooser.entry.set_text(default_path) if path: # If path is relative, complete with game dir if not os.path.isabs(path): path = os.path.expanduser(path) file_chooser.entry.set_text(path) file_chooser.set_valign(Gtk.Align.CENTER) label.set_alignment(0.5, 0.5) self.wrapper.pack_start(label, False, False, 0) self.wrapper.pack_start(file_chooser, True, True, 0) self.option_widget = file_chooser file_chooser.entry.connect('changed', self._on_chooser_file_set, option_name)
def on_query_tooltip(widget, x, y, keybmode, tooltip, text): """Prepare a custom tooltip with a fixed width""" label = Label(text) label.set_use_markup(True) label.set_max_width_chars(60) hbox = Gtk.Box() hbox.pack_start(label, False, False, 0) hbox.show_all() tooltip.set_custom(hbox) return True
def generate_entry(self, option_name, label, value=None): """Generate an entry box.""" label = Label(label) entry = Gtk.Entry() if value: entry.set_text(value) entry.connect("changed", self.entry_changed, option_name) label.set_alignment(0.5, 0.5) self.wrapper.pack_start(label, False, False, 0) self.wrapper.pack_start(entry, True, True, 0) self.option_widget = entry
def generate_editable_grid(self, option_name, label, value=None): value = value or {} value = list(value.items()) label = Label(label) label.set_alignment(0.5, 0) grid = EditableGrid(value, columns=["Key", "Value"]) grid.connect('changed', self.on_grid_changed, option_name) self.wrapper.pack_start(label, False, False, 0) self.wrapper.pack_start(grid, True, True, 0) self.option_widget = grid
def generate_directory_chooser(self, option_name, label_text, value=None): """Generate a file chooser button to select a directory.""" label = Label(label_text) directory_chooser = FileChooserEntry( title='Select folder', action=Gtk.FileChooserAction.SELECT_FOLDER, default_path=reverse_expanduser(value)) directory_chooser.entry.connect('changed', self.on_chooser_dir_set, option_name) directory_chooser.set_valign(Gtk.Align.CENTER) label.set_alignment(0.5, 0.5) self.wrapper.pack_start(label, False, False, 0) self.wrapper.pack_start(directory_chooser, True, True, 0) self.option_widget = directory_chooser
def generate_label(self, text): """Generate a simple label.""" label = Label(text) label.set_use_markup(True) label.set_halign(Gtk.Align.START) label.set_valign(Gtk.Align.CENTER) self.wrapper.pack_start(label, True, True, 0)
def generate_range(self, option_name, min_val, max_val, label, value=None): """Generate a ranged spin button.""" adjustment = Gtk.Adjustment(float(min_val), float(min_val), float(max_val), 1, 0, 0) spin_button = Gtk.SpinButton() spin_button.set_adjustment(adjustment) if value: spin_button.set_value(value) spin_button.connect('changed', self.on_spin_button_changed, option_name) label = Label(label) label.set_alignment(0.5, 0.5) self.wrapper.pack_start(label, False, False, 0) self.wrapper.pack_start(spin_button, True, True, 0) self.option_widget = spin_button
def generate_directory_chooser(self, option_name, label_text, value=None): """Generate a file chooser button to select a directory.""" label = Label(label_text) directory_chooser = FileChooserEntry( title='Select folder', action=Gtk.FileChooserAction.SELECT_FOLDER, default_path=reverse_expanduser(value) ) directory_chooser.entry.connect('changed', self.on_chooser_dir_set, option_name) directory_chooser.set_valign(Gtk.Align.CENTER) label.set_alignment(0.5, 0.5) self.wrapper.pack_start(label, False, False, 0) self.wrapper.pack_start(directory_chooser, True, True, 0) self.option_widget = directory_chooser
def generate_searchable_combobox(self, option_name, choice_func, label, value, default): """Generate a searchable combo box""" combobox = SearchableCombobox(choice_func, value or default) combobox.connect("changed", self.on_searchable_entry_changed, option_name) self.wrapper.pack_start(Label(label), False, False, 0) self.wrapper.pack_start(combobox, True, True, 0) self.option_widget = combobox
def _get_banner_box(self): banner_box = Gtk.Box(spacing=12, margin_right=12, margin_left=12) label = Label("") banner_box.pack_start(label, False, False, 0) self.banner_button = Gtk.Button() self._set_image(ImageType.banner) self.banner_button.connect("clicked", self.on_custom_image_select, ImageType.banner) banner_box.pack_start(self.banner_button, False, False, 0) reset_banner_button = Gtk.Button.new_from_icon_name("edit-clear", Gtk.IconSize.MENU) reset_banner_button.set_relief(Gtk.ReliefStyle.NONE) reset_banner_button.set_tooltip_text(_("Remove custom banner")) reset_banner_button.connect("clicked", self.on_custom_image_reset_clicked, ImageType.banner) banner_box.pack_start(reset_banner_button, False, False, 0) self.icon_button = Gtk.Button() self._set_image(ImageType.icon) self.icon_button.connect("clicked", self.on_custom_image_select, ImageType.icon) banner_box.pack_start(self.icon_button, False, False, 0) reset_icon_button = Gtk.Button.new_from_icon_name("edit-clear", Gtk.IconSize.MENU) reset_icon_button.set_relief(Gtk.ReliefStyle.NONE) reset_icon_button.set_tooltip_text(_("Remove custom icon")) reset_icon_button.connect("clicked", self.on_custom_image_reset_clicked, ImageType.icon) banner_box.pack_start(reset_icon_button, False, False, 0) return banner_box
def generate_file_chooser(self, option, path=None): """Generate a file chooser button to select a file.""" option_name = option["option"] label = Label(option["label"]) default_path = option.get("default_path") or (self.runner.default_path if self.runner else "") file_chooser = FileChooserEntry(title=_("Select file"), action=Gtk.FileChooserAction.OPEN, path=path, default_path=default_path) file_chooser.set_size_request(200, 30) if "default_path" in option: default_path = self.lutris_config.system_config.get( option["default_path"]) if default_path and os.path.exists(default_path): file_chooser.entry.set_text(default_path) if path: # If path is relative, complete with game dir if not os.path.isabs(path): path = os.path.expanduser(path) if not os.path.isabs(path): if self.game and self.game.directory: path = os.path.join(self.game.directory, path) file_chooser.entry.set_text(path) file_chooser.set_valign(Gtk.Align.CENTER) self.wrapper.pack_start(label, False, False, 0) self.wrapper.pack_start(file_chooser, True, True, 0) self.option_widget = file_chooser file_chooser.entry.connect("changed", self._on_chooser_file_set, option_name)
def generate_combobox( self, option_name, choices, label, value=None, default=None, has_entry=False ): """Generate a combobox (drop-down menu).""" liststore = Gtk.ListStore(str, str) self._populate_combobox_choices(liststore, choices, default) # With entry ("choice_with_entry" type) if has_entry: combobox = Gtk.ComboBox.new_with_model_and_entry(liststore) combobox.set_entry_text_column(0) if value: combobox.get_child().set_text(value) # No entry ("choice" type) else: combobox = Gtk.ComboBox.new_with_model(liststore) cell = Gtk.CellRendererText() combobox.pack_start(cell, True) combobox.add_attribute(cell, "text", 0) combobox.set_id_column(1) choices = list(v for k, v in choices) if value in choices: combobox.set_active_id(value) else: combobox.set_active_id(default) combobox.connect("changed", self.on_combobox_change, option_name) combobox.connect("scroll-event", self._on_combobox_scroll) label = Label(label) combobox.set_valign(Gtk.Align.CENTER) self.wrapper.pack_start(label, False, False, 0) self.wrapper.pack_start(combobox, True, True, 0) self.option_widget = combobox
def generate_combobox(self, option_name, choices, label, value=None, default=None, has_entry=False): """Generate a combobox (drop-down menu).""" liststore = Gtk.ListStore(str, str) for choice in choices: if type(choice) is str: choice = [choice, choice] if choice[1] == default and not has_entry: # Do not add default label to editable dropdowns since this gets # added to the actual value. liststore.append([choice[0] + " (default)", default]) self.tooltip_default = choice[0] else: liststore.append(choice) # With entry ("choice_with_entry" type) if has_entry: combobox = Gtk.ComboBox.new_with_model_and_entry(liststore) combobox.set_entry_text_column(0) if value: combobox.get_child().set_text(value) # No entry ("choice" type) else: combobox = Gtk.ComboBox.new_with_model(liststore) cell = Gtk.CellRendererText() combobox.pack_start(cell, True) combobox.add_attribute(cell, 'text', 0) combobox.set_id_column(1) choices = list(v for k, v in choices) if value in choices: combobox.set_active_id(value) else: combobox.set_active_id(default) combobox.connect('changed', self.on_combobox_change, option_name) combobox.connect('scroll-event', self.on_combobox_scroll) label = Label(label) label.set_alignment(0.5, 0.5) combobox.set_valign(Gtk.Align.CENTER) self.wrapper.pack_start(label, False, False, 0) self.wrapper.pack_start(combobox, True, True, 0) self.option_widget = combobox
def _get_name_box(self): box = Gtk.Box(spacing=12, margin_right=12, margin_left=12) label = Label(_("Name")) box.pack_start(label, False, False, 0) self.name_entry = Gtk.Entry() if self.game: self.name_entry.set_text(self.game.name) box.pack_start(self.name_entry, True, True, 0) return box
def _get_runner_box(self): runner_box = Gtk.Box(spacing=12, margin_right=12, margin_left=12) runner_label = Label(_("Runner")) runner_box.pack_start(runner_label, False, False, 0) self.runner_dropdown = self._get_runner_dropdown() runner_box.pack_start(self.runner_dropdown, True, True, 0) return runner_box
def generate_entry(self, option_name, label, value=None, option_size=None): """Generate an entry box.""" label = Label(label) self.wrapper.pack_start(label, False, False, 0) entry = Gtk.Entry() if value: entry.set_text(value) entry.connect("changed", self.entry_changed, option_name) expand = option_size != "small" self.wrapper.pack_start(entry, expand, expand, 0) self.option_widget = entry
def _get_year_box(self): box = Gtk.Box(spacing=12, margin_right=12, margin_left=12) label = Label(_("Release year")) box.pack_start(label, False, False, 0) self.year_entry = NumberEntry() if self.game: self.year_entry.set_text(str(self.game.year or "")) box.pack_start(self.year_entry, True, True, 0) return box
def _get_game_cache_box(self): box = Gtk.Box(spacing=12, margin_right=12, margin_left=12) label = Label("Cache path") box.pack_start(label, False, False, 0) cache_path = get_cache_path() path_chooser = FileChooserEntry( title="Set the folder for the cache path", action=Gtk.FileChooserAction.SELECT_FOLDER, path=cache_path) path_chooser.entry.connect("changed", self._on_cache_path_set) box.pack_start(path_chooser, True, True, 0) return box
def generate_combobox(self, option_name, choices, label, value=None, default=None, has_entry=False): """Generate a combobox (drop-down menu).""" liststore = Gtk.ListStore(str, str) for choice in choices: if type(choice) is str: choice = [choice, choice] if choice[1] == default: liststore.append([choice[0] + " (default)", default]) self.tooltip_default = choice[0] else: liststore.append(choice) # With entry ("choice_with_entry" type) if has_entry: combobox = Gtk.ComboBox.new_with_model_and_entry(liststore) combobox.set_entry_text_column(1) if value: combobox.get_child().set_text(value) # No entry ("choice" type) else: combobox = Gtk.ComboBox.new_with_model(liststore) cell = Gtk.CellRendererText() combobox.pack_start(cell, True) combobox.add_attribute(cell, 'text', 0) combobox.set_id_column(1) choices = list(v for k, v in choices) if value in choices: combobox.set_active_id(value) else: combobox.set_active_id(default) combobox.connect('changed', self.on_combobox_change, option_name) label = Label(label) label.set_alignment(0.5, 0.5) combobox.set_valign(Gtk.Align.CENTER) self.wrapper.pack_start(label, False, False, 0) self.wrapper.pack_start(combobox, True, True, 0) self.option_widget = combobox
def generate_multiple_file_chooser(self, option_name, label, value=None): """Generate a multiple file selector.""" vbox = Gtk.Box(orientation=Gtk.Orientation.VERTICAL) label = Label(label + ":") label.set_halign(Gtk.Align.START) button = Gtk.Button(_("Add files")) button.connect("clicked", self.on_add_files_clicked, option_name, value) button.set_margin_left(10) vbox.pack_start(label, False, False, 5) vbox.pack_end(button, False, False, 0) if value: if isinstance(value, str): self.files = [value] else: self.files = value else: self.files = [] self.files_list_store = Gtk.ListStore(str) for filename in self.files: self.files_list_store.append([filename]) cell_renderer = Gtk.CellRendererText() files_treeview = Gtk.TreeView(self.files_list_store) files_column = Gtk.TreeViewColumn(_("Files"), cell_renderer, text=0) files_treeview.append_column(files_column) files_treeview.connect("key-press-event", self.on_files_treeview_keypress, option_name) treeview_scroll = Gtk.ScrolledWindow() treeview_scroll.set_min_content_height(130) treeview_scroll.set_margin_left(10) treeview_scroll.set_shadow_type(Gtk.ShadowType.ETCHED_IN) treeview_scroll.set_policy(Gtk.PolicyType.AUTOMATIC, Gtk.PolicyType.AUTOMATIC) treeview_scroll.add(files_treeview) vbox.pack_start(treeview_scroll, True, True, 0) self.wrapper.pack_start(vbox, True, True, 0) self.option_widget = self.files_list_store
def generate_multiple_file_chooser(self, option_name, label, value=None): """Generate a multiple file selector.""" vbox = Gtk.VBox() label = Label(label + ':') label.set_halign(Gtk.Align.START) button = Gtk.Button('Add files') button.connect('clicked', self.on_add_files_clicked, option_name, value) button.set_margin_left(10) vbox.pack_start(label, False, False, 5) vbox.pack_end(button, False, False, 0) if value: if type(value) == str: self.files = [value] else: self.files = value else: self.files = [] self.files_list_store = Gtk.ListStore(str) for filename in self.files: self.files_list_store.append([filename]) cell_renderer = Gtk.CellRendererText() files_treeview = Gtk.TreeView(self.files_list_store) files_column = Gtk.TreeViewColumn("Files", cell_renderer, text=0) files_treeview.append_column(files_column) files_treeview.connect('key-press-event', self.on_files_treeview_keypress, option_name) treeview_scroll = Gtk.ScrolledWindow() treeview_scroll.set_min_content_height(130) treeview_scroll.set_margin_left(10) treeview_scroll.set_shadow_type(Gtk.ShadowType.ETCHED_IN) treeview_scroll.set_policy(Gtk.PolicyType.AUTOMATIC, Gtk.PolicyType.AUTOMATIC) treeview_scroll.add(files_treeview) vbox.pack_start(treeview_scroll, True, True, 0) self.wrapper.pack_start(vbox, True, True, 0) self.option_widget = self.files_list_store
def generate_checkbox(self, option, value=None): """Generate a checkbox.""" label = Label(option["label"]) self.wrapper.pack_start(label, False, False, 0) switch = Gtk.Switch() if value is True: switch.set_active(value) switch.connect("notify::active", self.checkbox_toggle, option["option"]) switch.set_valign(Gtk.Align.CENTER) self.wrapper.pack_start(switch, False, False, 0) self.option_widget = switch
def _get_directory_box(self): """Return widget displaying the location of the game and allowing to move it""" box = Gtk.Box(spacing=12, margin_right=12, margin_left=12, visible=True) label = Label(_("Directory")) box.pack_start(label, False, False, 0) self.directory_entry = Gtk.Entry(visible=True) self.directory_entry.set_text(self.game.directory) self.directory_entry.set_sensitive(False) box.pack_start(self.directory_entry, True, True, 0) move_button = Gtk.Button(_("Move"), visible=True) move_button.connect("clicked", self.on_move_clicked) box.pack_start(move_button, False, False, 0) return box
def _get_runner_box(self): runner_box = Gtk.Box(spacing=12, margin_right=12, margin_left=12) runner_label = Label(_("Runner")) runner_box.pack_start(runner_label, False, False, 0) self.runner_dropdown = self._get_runner_dropdown() runner_box.pack_start(self.runner_dropdown, True, True, 0) install_runners_btn = Gtk.Button(_("Install runners")) install_runners_btn.connect("clicked", self.on_install_runners_clicked) runner_box.pack_start(install_runners_btn, True, True, 0) return runner_box
def generate_directory_chooser(self, option, path=None): """Generate a file chooser button to select a directory.""" label = Label(option["label"]) option_name = option["option"] default_path = None if not path and self.game and self.game.runner: default_path = self.game.runner.working_dir directory_chooser = FileChooserEntry( title=_("Select folder"), action=Gtk.FileChooserAction.SELECT_FOLDER, path=path, default_path=default_path ) directory_chooser.entry.connect("changed", self._on_chooser_dir_set, option_name) directory_chooser.set_valign(Gtk.Align.CENTER) self.wrapper.pack_start(label, False, False, 0) self.wrapper.pack_start(directory_chooser, True, True, 0) self.option_widget = directory_chooser
def generate_checkbox_with_callback(self, option, value=None): """Generate a checkbox. With callback""" label = Label(option["label"]) self.wrapper.pack_start(label, False, False, 0) checkbox = Gtk.Switch() checkbox.set_sensitive(option["active"] is True) if value is True: checkbox.set_active(value) checkbox.connect("notify::active", self._on_toggle_with_callback, option) checkbox.set_valign(Gtk.Align.CENTER) self.wrapper.pack_start(checkbox, False, False, 0) self.option_widget = checkbox
def on_query_tooltip(_widget, x, y, keybmode, tooltip, text): # pylint: disable=unused-argument """Prepare a custom tooltip with a fixed width""" label = Label(text) label.set_use_markup(True) label.set_max_width_chars(60) hbox = Gtk.Box() hbox.pack_start(label, False, False, 0) hbox.show_all() tooltip.set_custom(hbox) return True
def generate_editable_grid(self, option_name, label, value=None): """Adds an editable grid widget""" value = value or {} try: value = list(value.items()) except AttributeError: logger.error("Invalid value of type %s passed to grid widget: %s", type(value), value) value = {} label = Label(label) grid = EditableGrid(value, columns=["Key", "Value"]) grid.connect("changed", self._on_grid_changed, option_name) self.wrapper.pack_start(label, False, False, 0) self.wrapper.pack_start(grid, True, True, 0) self.option_widget = grid return grid
def _get_slug_box(self): slug_box = Gtk.Box(spacing=12, margin_right=12, margin_left=12) label = Label(_("Identifier")) slug_box.pack_start(label, False, False, 0) self.slug_entry = SlugEntry() self.slug_entry.set_text(self.game.slug) self.slug_entry.set_sensitive(False) self.slug_entry.connect("activate", self.on_slug_entry_activate) slug_box.pack_start(self.slug_entry, True, True, 0) self.slug_change_button = Gtk.Button(_("Change")) self.slug_change_button.connect("clicked", self.on_slug_change_clicked) slug_box.pack_start(self.slug_change_button, False, False, 0) return slug_box
def generate_widgets(self, config_section): # noqa: C901 # pylint: disable=too-many-branches,too-many-statements """Parse the config dict and generates widget accordingly.""" if not self.options: no_options_label = Label(_("No options available")) no_options_label.set_halign(Gtk.Align.CENTER) no_options_label.set_valign(Gtk.Align.CENTER) self.pack_start(no_options_label, True, True, 0) return # Select config section. if config_section == "game": self.config = self.lutris_config.game_config self.raw_config = self.lutris_config.raw_game_config elif config_section == "runner": self.config = self.lutris_config.runner_config self.raw_config = self.lutris_config.raw_runner_config elif config_section == "system": self.config = self.lutris_config.system_config self.raw_config = self.lutris_config.raw_system_config # Go thru all options. for option in self.options: if "scope" in option: if config_section not in option["scope"]: continue option_key = option["option"] value = self.config.get(option_key) default = option.get("default") if callable(option.get( "choices")) and option["type"] != "choice_with_search": option["choices"] = option["choices"]() if callable(option.get("condition")): option["condition"] = option["condition"]() self.wrapper = Gtk.Box() self.wrapper.set_spacing(12) self.wrapper.set_margin_bottom(6) # Set tooltip's "Default" part default = option.get("default") self.tooltip_default = default if isinstance(default, str) else None # Generate option widget self.option_widget = None self.call_widget_generator(option, option_key, value, default) # Reset button reset_btn = Gtk.Button.new_from_icon_name("edit-clear", Gtk.IconSize.MENU) reset_btn.set_relief(Gtk.ReliefStyle.NONE) reset_btn.set_tooltip_text( _("Reset option to global or default config")) reset_btn.connect( "clicked", self.on_reset_button_clicked, option, self.option_widget, self.wrapper, ) placeholder = Gtk.Box() placeholder.set_size_request(32, 32) if option_key not in self.raw_config: reset_btn.set_visible(False) reset_btn.set_no_show_all(True) placeholder.pack_start(reset_btn, False, False, 0) # Tooltip helptext = option.get("help") if isinstance(self.tooltip_default, str): helptext = helptext + "\n\n" if helptext else "" helptext += _("<b>Default</b>: ") + _(self.tooltip_default) if value != default and option_key not in self.raw_config: helptext = helptext + "\n\n" if helptext else "" helptext += _("<i>(Italic indicates that this option is " "modified in a lower configuration level.)</i>") if helptext: self.wrapper.props.has_tooltip = True self.wrapper.connect("query-tooltip", self.on_query_tooltip, helptext) hbox = Gtk.Box() hbox.set_margin_left(18) hbox.pack_end(placeholder, False, False, 5) # Grey out option if condition unmet if "condition" in option and not option["condition"]: hbox.set_sensitive(False) # Hide if advanced if option.get("advanced"): hbox.get_style_context().add_class("advanced") show_advanced = settings.read_setting("show_advanced_options") if not show_advanced == "True": hbox.set_no_show_all(True) hbox.pack_start(self.wrapper, True, True, 0) self.pack_start(hbox, False, False, 0)
def generate_widgets(self, config_section): """Parse the config dict and generates widget accordingly.""" if not self.options: label = Label("No options available") label.set_halign(Gtk.Align.CENTER) label.set_valign(Gtk.Align.CENTER) self.pack_start(label, True, True, 0) return # Select config section. if config_section == 'game': self.config = self.lutris_config.game_config self.raw_config = self.lutris_config.raw_game_config elif config_section == 'runner': self.config = self.lutris_config.runner_config self.raw_config = self.lutris_config.raw_runner_config elif config_section == 'system': self.config = self.lutris_config.system_config self.raw_config = self.lutris_config.raw_system_config # Go thru all options. for option in self.options: if 'scope' in option: if config_section not in option['scope']: continue option_key = option['option'] value = self.config.get(option_key) default = option.get('default') if callable(option.get('choices')): option['choices'] = option['choices']() if callable(option.get('condition')): option['condition'] = option['condition']() hbox = Gtk.HBox() hbox.set_margin_left(20) self.wrapper = Gtk.HBox() self.wrapper.set_spacing(20) placeholder = Gtk.HBox() placeholder.set_size_request(32, 32) hbox.pack_end(placeholder, False, False, 5) # Set tooltip's "Default" part default = option.get('default') self.tooltip_default = default if type(default) is str else None # Generate option widget self.option_widget = None self.call_widget_generator(option, option_key, value, default) # Reset button reset_btn = Gtk.Button.new_from_icon_name('edit-clear', Gtk.IconSize.MENU) reset_btn.set_relief(Gtk.ReliefStyle.NONE) reset_btn.set_tooltip_text("Reset option to global or " "default config") reset_btn.connect('clicked', self.on_reset_button_clicked, option, self.option_widget, self.wrapper) if option_key not in self.raw_config: reset_btn.set_visible(False) reset_btn.set_no_show_all(True) placeholder.pack_start(reset_btn, False, False, 0) # Tooltip helptext = option.get("help") if type(self.tooltip_default) is str: helptext = helptext + '\n\n' if helptext else '' helptext += "<b>Default</b>: " + self.tooltip_default if value != default and option_key not in self.raw_config: helptext = helptext + '\n\n' if helptext else '' helptext += ("<i>(Italic indicates that this option is " "modified in a lower configuration level.)</i>") if helptext: self.wrapper.props.has_tooltip = True self.wrapper.connect('query-tooltip', self.on_query_tooltip, helptext) # Grey out option if condition unmet if 'condition' in option and not option['condition']: hbox.set_sensitive(False) # Hide if advanced if option.get('advanced'): hbox.get_style_context().add_class('advanced') show_advanced = settings.read_setting('show_advanced_options') if not show_advanced == 'True': hbox.set_no_show_all(True) hbox.pack_start(self.wrapper, True, True, 0) self.pack_start(hbox, False, False, 5)
def generate_widgets(self, config_section): """Parse the config dict and generates widget accordingly.""" if not self.options: no_options_label = Label("No options available") no_options_label.set_halign(Gtk.Align.CENTER) no_options_label.set_valign(Gtk.Align.CENTER) self.pack_start(no_options_label, True, True, 0) return # Select config section. if config_section == "game": self.config = self.lutris_config.game_config self.raw_config = self.lutris_config.raw_game_config elif config_section == "runner": self.config = self.lutris_config.runner_config self.raw_config = self.lutris_config.raw_runner_config elif config_section == "system": self.config = self.lutris_config.system_config self.raw_config = self.lutris_config.raw_system_config # Go thru all options. for option in self.options: if "scope" in option: if config_section not in option["scope"]: continue option_key = option["option"] value = self.config.get(option_key) default = option.get("default") if callable(option.get("choices")): option["choices"] = option["choices"]() if callable(option.get("condition")): option["condition"] = option["condition"]() self.wrapper = Gtk.Box() self.wrapper.set_spacing(12) self.wrapper.set_margin_bottom(6) # Set tooltip's "Default" part default = option.get("default") self.tooltip_default = default if isinstance(default, str) else None # Generate option widget self.option_widget = None self.call_widget_generator(option, option_key, value, default) # Reset button reset_btn = Gtk.Button.new_from_icon_name("edit-clear", Gtk.IconSize.MENU) reset_btn.set_relief(Gtk.ReliefStyle.NONE) reset_btn.set_tooltip_text("Reset option to global or " "default config") reset_btn.connect( "clicked", self.on_reset_button_clicked, option, self.option_widget, self.wrapper, ) placeholder = Gtk.Box() placeholder.set_size_request(32, 32) if option_key not in self.raw_config: reset_btn.set_visible(False) reset_btn.set_no_show_all(True) placeholder.pack_start(reset_btn, False, False, 0) # Tooltip helptext = option.get("help") if isinstance(self.tooltip_default, str): helptext = helptext + "\n\n" if helptext else "" helptext += "<b>Default</b>: " + self.tooltip_default if value != default and option_key not in self.raw_config: helptext = helptext + "\n\n" if helptext else "" helptext += ( "<i>(Italic indicates that this option is " "modified in a lower configuration level.)</i>" ) if helptext: self.wrapper.props.has_tooltip = True self.wrapper.connect("query-tooltip", self.on_query_tooltip, helptext) hbox = Gtk.Box() hbox.set_margin_left(18) hbox.pack_end(placeholder, False, False, 5) # Grey out option if condition unmet if "condition" in option and not option["condition"]: hbox.set_sensitive(False) # Hide if advanced if option.get("advanced"): hbox.get_style_context().add_class("advanced") show_advanced = settings.read_setting("show_advanced_options") if not show_advanced == "True": hbox.set_no_show_all(True) hbox.pack_start(self.wrapper, True, True, 0) self.pack_start(hbox, False, False, 0)