1
0
mirror of https://github.com/lutris/lutris synced 2024-07-05 08:28:41 +00:00

Add "input_menu" installer directive

Read the installers.rst changes for a full description.
A test installer is available at https://lutris.net/games/test/
This commit is contained in:
Xodetaetl 2015-02-07 19:36:30 +01:00
parent e2689b80ee
commit a488bd9543
2 changed files with 96 additions and 1 deletions

View File

@ -299,6 +299,40 @@ Currently, the following tasks are implemented:
prefix: $GAMEDIR
filename: myregfile
Displaying a drop-down menu with options
----------------------------------------
Request input from the user by displaying a menu filled with options to choose
from with the ``input_menu`` directive.
The ``description`` parameter holds the message to the user, ``options`` is an
indented list of ``value: label`` lines where "value" is the text that will be
stored and "label" is the text displayed (), and the optional ``preselect``
parameter is the value to preselect for the user.
The result of the last input directive is available with the ``$INPUT`` alias.
If need be, you can add an ``id`` parameter to the directive which will make the
selected value available with ``$INPUT_<id>`` with "<id>" obviously being the
id you specified. The id must contain only numbers, letters and underscores.
Example:
::
- input_menu:
description: Choose the game's language:
id: LANG
options:
- en: English
- bf: Brainfuck
- "value and": "label can be anything, surround them with quotes to avoid issues"
preselect: lah
In this example, English would be preselected. If the option eventually
selected is Brainfuck, the "$INPUT_LANG" alias would be available in
following directives and would correspond to "bf". "$INPUT" would work as well,
up until the next input directive.
Trying the installer locally
============================

View File

@ -93,6 +93,7 @@ class ScriptInterpreter(object):
self.game_slug = None
self.game_files = {}
self.game_disc = None
self.user_inputs = []
self.steam_data = {}
self.script = script
if not self.script:
@ -420,10 +421,20 @@ class ScriptInterpreter(object):
"HOME": os.path.expanduser("~"),
"DISC": self.game_disc,
"USER": os.getenv('USER'),
"INPUT": self._get_last_user_input(),
}
# Add 'INPUT_<id>' replacements for user inputs with an id
for input_data in self.user_inputs:
alias = input_data['alias']
if alias:
replacements[alias] = input_data['value']
replacements.update(self.game_files)
return system.substitute(template_string, replacements)
def _get_last_user_input(self):
return self.user_inputs[-1]['value'] if self.user_inputs else ''
def _get_move_paths(self, params):
""" Validate and converts raw data passed to 'move' """
for required_param in ('dst', 'src'):
@ -477,6 +488,27 @@ class ScriptInterpreter(object):
if _hash != data['value']:
raise ScriptingError("MD5 checksum mismatch", data)
def input_menu(self, data):
"""Display an input request as a dropdown menu with options."""
identifier = data.get('id')
alias = 'INPUT_%s' % identifier if identifier else None
has_entry = data.get('entry')
options = data.get('options')
preselect = self._substitute(data.get('preselect', ''))
self.parent.input_menu(alias, options, preselect, has_entry,
self._on_input_menu_validated)
return 'STOP'
def _on_input_menu_validated(self, widget, *args):
alias = args[0]
menu = args[1]
choosen_option = menu.get_active_id()
if choosen_option:
self.user_inputs.append({'alias': alias,
'value': choosen_option})
self.parent.continue_button.hide()
self._iter_commands()
def insert_disc(self, data):
requires = data.get('requires')
message = data.get(
@ -900,7 +932,7 @@ class InstallerDialog(Gtk.Window):
self.show_non_empty_warning()
def on_install_clicked(self, button):
button.set_sensitive(False)
button.hide()
self.interpreter.iter_game_files()
def ask_user_for_file(self, message):
@ -958,6 +990,35 @@ class InstallerDialog(Gtk.Window):
self.widget_box.add(button)
button.show()
def input_menu(self, alias, options, preselect, has_entry, callback):
"""Display an input request as a dropdown menu with options."""
time.sleep(0.3)
self.clean_widgets()
model = Gtk.ListStore(str, str)
for option in options:
key, label = option.popitem()
model.append([key, label])
combobox = Gtk.ComboBox.new_with_model(model)
renderer_text = Gtk.CellRendererText()
combobox.pack_start(renderer_text, True)
combobox.add_attribute(renderer_text, "text", 1)
combobox.set_id_column(0)
combobox.set_active_id(preselect)
self.widget_box.pack_start(combobox, True, False, 100)
combobox.connect("changed", self.on_input_menu_changed)
combobox.show()
self.continue_handler = self.continue_button.connect(
'clicked', callback, alias, combobox)
if not preselect:
self.continue_button.set_sensitive(False)
self.continue_button.show()
def on_input_menu_changed(self, widget):
if widget.get_active_id():
self.continue_button.set_sensitive(True)
def download_complete(self, widget, data, more_data=None):
"""Action called on a completed download"""
self.interpreter.iter_game_files()