mirror of
https://github.com/lutris/lutris
synced 2024-10-04 14:59:37 +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:
parent
e2689b80ee
commit
a488bd9543
|
@ -299,6 +299,40 @@ Currently, the following tasks are implemented:
|
||||||
prefix: $GAMEDIR
|
prefix: $GAMEDIR
|
||||||
filename: myregfile
|
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
|
Trying the installer locally
|
||||||
============================
|
============================
|
||||||
|
|
||||||
|
|
|
@ -93,6 +93,7 @@ class ScriptInterpreter(object):
|
||||||
self.game_slug = None
|
self.game_slug = None
|
||||||
self.game_files = {}
|
self.game_files = {}
|
||||||
self.game_disc = None
|
self.game_disc = None
|
||||||
|
self.user_inputs = []
|
||||||
self.steam_data = {}
|
self.steam_data = {}
|
||||||
self.script = script
|
self.script = script
|
||||||
if not self.script:
|
if not self.script:
|
||||||
|
@ -420,10 +421,20 @@ class ScriptInterpreter(object):
|
||||||
"HOME": os.path.expanduser("~"),
|
"HOME": os.path.expanduser("~"),
|
||||||
"DISC": self.game_disc,
|
"DISC": self.game_disc,
|
||||||
"USER": os.getenv('USER'),
|
"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)
|
replacements.update(self.game_files)
|
||||||
return system.substitute(template_string, replacements)
|
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):
|
def _get_move_paths(self, params):
|
||||||
""" Validate and converts raw data passed to 'move' """
|
""" Validate and converts raw data passed to 'move' """
|
||||||
for required_param in ('dst', 'src'):
|
for required_param in ('dst', 'src'):
|
||||||
|
@ -477,6 +488,27 @@ class ScriptInterpreter(object):
|
||||||
if _hash != data['value']:
|
if _hash != data['value']:
|
||||||
raise ScriptingError("MD5 checksum mismatch", data)
|
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):
|
def insert_disc(self, data):
|
||||||
requires = data.get('requires')
|
requires = data.get('requires')
|
||||||
message = data.get(
|
message = data.get(
|
||||||
|
@ -900,7 +932,7 @@ class InstallerDialog(Gtk.Window):
|
||||||
self.show_non_empty_warning()
|
self.show_non_empty_warning()
|
||||||
|
|
||||||
def on_install_clicked(self, button):
|
def on_install_clicked(self, button):
|
||||||
button.set_sensitive(False)
|
button.hide()
|
||||||
self.interpreter.iter_game_files()
|
self.interpreter.iter_game_files()
|
||||||
|
|
||||||
def ask_user_for_file(self, message):
|
def ask_user_for_file(self, message):
|
||||||
|
@ -958,6 +990,35 @@ class InstallerDialog(Gtk.Window):
|
||||||
self.widget_box.add(button)
|
self.widget_box.add(button)
|
||||||
button.show()
|
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):
|
def download_complete(self, widget, data, more_data=None):
|
||||||
"""Action called on a completed download"""
|
"""Action called on a completed download"""
|
||||||
self.interpreter.iter_game_files()
|
self.interpreter.iter_game_files()
|
||||||
|
|
Loading…
Reference in a new issue