mirror of
https://github.com/lutris/lutris
synced 2024-09-05 07:23:32 +00:00
Break out a base class for game actions, and use it for service games.
We want a real service games menu, but this blocks access to inappropriate commands at least.
This commit is contained in:
parent
2f69520f03
commit
e0e741c1b8
|
@ -28,29 +28,91 @@ from lutris.util.system import path_exists
|
||||||
from lutris.util.wine.shader_cache import update_shader_cache
|
from lutris.util.wine.shader_cache import update_shader_cache
|
||||||
|
|
||||||
|
|
||||||
class GameActions:
|
def get_game_actions(game, window, application=None):
|
||||||
"""Regroup a list of callbacks for a game"""
|
if game.is_db_stored:
|
||||||
|
return GameActions(game, window, application)
|
||||||
|
else:
|
||||||
|
return BaseGameActions(game, window, application)
|
||||||
|
|
||||||
|
|
||||||
|
class BaseGameActions:
|
||||||
def __init__(self, game, window, application=None):
|
def __init__(self, game, window, application=None):
|
||||||
self.application = application or Gio.Application.get_default()
|
self.application = application or Gio.Application.get_default()
|
||||||
self.window = window # also used as a LaunchUIDelegate
|
self.window = window # also used as a LaunchUIDelegate
|
||||||
self.game = game
|
self.game = game
|
||||||
|
|
||||||
|
def get_game_actions(self):
|
||||||
|
"""Return a list of game actions and their callbacks"""
|
||||||
|
return []
|
||||||
|
|
||||||
|
def get_displayed_entries(self):
|
||||||
|
"""Return a dictionary of actions that should be shown for a game"""
|
||||||
|
return {}
|
||||||
|
|
||||||
|
@property
|
||||||
|
def is_game_launchable(self):
|
||||||
|
return False
|
||||||
|
|
||||||
|
def on_game_launch(self, *_args):
|
||||||
|
"""Launch a game"""
|
||||||
|
pass
|
||||||
|
|
||||||
|
@property
|
||||||
|
def is_game_running(self):
|
||||||
|
return False
|
||||||
|
|
||||||
|
def on_game_stop(self, *_args):
|
||||||
|
"""Stops the game"""
|
||||||
|
pass
|
||||||
|
|
||||||
|
@property
|
||||||
|
def is_installable(self):
|
||||||
|
return False
|
||||||
|
|
||||||
|
def on_install_clicked(self, *_args):
|
||||||
|
"""Install a game"""
|
||||||
|
pass
|
||||||
|
|
||||||
|
def on_locate_installed_game(self, _button, game):
|
||||||
|
"""Show the user a dialog to import an existing install to a DRM free service
|
||||||
|
|
||||||
|
Params:
|
||||||
|
game (Game): Game instance without a database ID, populated with a fields the service can provides
|
||||||
|
"""
|
||||||
|
AddGameDialog(self.window, game=game)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def is_game_removable(self):
|
||||||
|
return False
|
||||||
|
|
||||||
|
def on_remove_game(self, *_args):
|
||||||
|
"""Callback that present the uninstall dialog to the user"""
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class GameActions(BaseGameActions):
|
||||||
|
"""Regroup a list of callbacks for a game"""
|
||||||
|
|
||||||
|
def __init__(self, game, window, application=None):
|
||||||
|
super().__init__(game, window, application)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def is_game_launchable(self):
|
||||||
|
return self.game and self.game.is_installed and not self.is_game_running
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def is_game_running(self):
|
def is_game_running(self):
|
||||||
return self.game and self.game.is_db_stored and bool(self.application.get_running_game_by_id(self.game.id))
|
return self.game and self.game.is_db_stored and bool(self.application.get_running_game_by_id(self.game.id))
|
||||||
|
|
||||||
|
@property
|
||||||
|
def is_installable(self):
|
||||||
|
return not self.game.is_installed
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def is_game_removable(self):
|
def is_game_removable(self):
|
||||||
return self.game and (self.game.is_installed or self.game.is_db_stored)
|
return self.game and (self.game.is_installed or self.game.is_db_stored)
|
||||||
|
|
||||||
def on_game_state_changed(self, game):
|
|
||||||
"""Handler called when the game has changed state"""
|
|
||||||
if self.game and game.id == self.game.get_safe_id():
|
|
||||||
self.game = game
|
|
||||||
|
|
||||||
def get_game_actions(self):
|
def get_game_actions(self):
|
||||||
"""Return a list of game actions and their callbacks"""
|
|
||||||
return [
|
return [
|
||||||
("play", _("Play"), self.on_game_launch),
|
("play", _("Play"), self.on_game_launch),
|
||||||
("stop", _("Stop"), self.on_game_stop),
|
("stop", _("Stop"), self.on_game_stop),
|
||||||
|
@ -94,8 +156,8 @@ class GameActions:
|
||||||
return {
|
return {
|
||||||
"add": not self.game.is_installed,
|
"add": not self.game.is_installed,
|
||||||
"duplicate": self.game.is_installed,
|
"duplicate": self.game.is_installed,
|
||||||
"install": not self.game.is_installed,
|
"install": self.is_installable,
|
||||||
"play": self.game.is_installed and not self.is_game_running,
|
"play": self.is_game_launchable,
|
||||||
"update": self.game.is_updatable,
|
"update": self.game.is_updatable,
|
||||||
"update-shader-cache": self.game.is_cache_managed,
|
"update-shader-cache": self.game.is_cache_managed,
|
||||||
"install_dlcs": self.game.is_updatable,
|
"install_dlcs": self.game.is_updatable,
|
||||||
|
@ -190,14 +252,6 @@ class GameActions:
|
||||||
def on_update_shader_cache(self, _widget):
|
def on_update_shader_cache(self, _widget):
|
||||||
update_shader_cache(self.game)
|
update_shader_cache(self.game)
|
||||||
|
|
||||||
def on_locate_installed_game(self, _button, game):
|
|
||||||
"""Show the user a dialog to import an existing install to a DRM free service
|
|
||||||
|
|
||||||
Params:
|
|
||||||
game (Game): Game instance without a database ID, populated with a fields the service can provides
|
|
||||||
"""
|
|
||||||
AddGameDialog(self.window, game=game)
|
|
||||||
|
|
||||||
def on_add_manually(self, _widget, *_args):
|
def on_add_manually(self, _widget, *_args):
|
||||||
"""Callback that presents the Add game dialog"""
|
"""Callback that presents the Add game dialog"""
|
||||||
return AddGameDialog(self.window, game=self.game, runner=self.game.runner_name)
|
return AddGameDialog(self.window, game=self.game, runner=self.game.runner_name)
|
||||||
|
|
|
@ -3,7 +3,7 @@ from gi.repository import Gdk, Gio, GObject, Gtk
|
||||||
from lutris.database.games import get_game_for_service
|
from lutris.database.games import get_game_for_service
|
||||||
from lutris.database.services import ServiceGameCollection
|
from lutris.database.services import ServiceGameCollection
|
||||||
from lutris.game import Game
|
from lutris.game import Game
|
||||||
from lutris.game_actions import GameActions
|
from lutris.game_actions import GameActions, get_game_actions
|
||||||
from lutris.gui.views import COL_ID
|
from lutris.gui.views import COL_ID
|
||||||
from lutris.gui.widgets.contextual_menu import ContextualMenu
|
from lutris.gui.widgets.contextual_menu import ContextualMenu
|
||||||
|
|
||||||
|
@ -56,7 +56,7 @@ class GameView:
|
||||||
else:
|
else:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
return GameActions(game, window=self.get_toplevel())
|
return get_game_actions(game, window=self.get_toplevel())
|
||||||
|
|
||||||
def get_game_by_id(self, game_id):
|
def get_game_by_id(self, game_id):
|
||||||
application = Gio.Application.get_default()
|
application = Gio.Application.get_default()
|
||||||
|
|
|
@ -7,7 +7,7 @@ from lutris import runners, services
|
||||||
from lutris.database.games import get_game_for_service
|
from lutris.database.games import get_game_for_service
|
||||||
from lutris.exceptions import watch_errors
|
from lutris.exceptions import watch_errors
|
||||||
from lutris.game import Game
|
from lutris.game import Game
|
||||||
from lutris.game_actions import GameActions
|
from lutris.game_actions import GameActions, get_game_actions
|
||||||
from lutris.gui.dialogs import ErrorDialog
|
from lutris.gui.dialogs import ErrorDialog
|
||||||
from lutris.gui.widgets.contextual_menu import update_action_widget_visibility
|
from lutris.gui.widgets.contextual_menu import update_action_widget_visibility
|
||||||
from lutris.util.strings import gtk_safe
|
from lutris.util.strings import gtk_safe
|
||||||
|
@ -74,7 +74,7 @@ class GameBar(Gtk.Box):
|
||||||
|
|
||||||
def update_view(self):
|
def update_view(self):
|
||||||
"""Populate the view with widgets"""
|
"""Populate the view with widgets"""
|
||||||
game_actions = GameActions(self.game, window=self.window, application=self.application)
|
game_actions = get_game_actions(self.game, window=self.window, application=self.application)
|
||||||
|
|
||||||
game_label = self.get_game_name_label()
|
game_label = self.get_game_name_label()
|
||||||
game_label.set_halign(Gtk.Align.START)
|
game_label.set_halign(Gtk.Align.START)
|
||||||
|
@ -212,15 +212,18 @@ class GameBar(Gtk.Box):
|
||||||
if self.game.state == self.game.STATE_STOPPED:
|
if self.game.state == self.game.STATE_STOPPED:
|
||||||
button.set_label(_("Play"))
|
button.set_label(_("Play"))
|
||||||
button.connect("clicked", game_actions.on_game_launch)
|
button.connect("clicked", game_actions.on_game_launch)
|
||||||
|
button.set_sensitive(game_actions.is_game_launchable)
|
||||||
elif self.game.state == self.game.STATE_LAUNCHING:
|
elif self.game.state == self.game.STATE_LAUNCHING:
|
||||||
button.set_label(_("Launching"))
|
button.set_label(_("Launching"))
|
||||||
button.set_sensitive(False)
|
button.set_sensitive(False)
|
||||||
else:
|
else:
|
||||||
button.set_label(_("Stop"))
|
button.set_label(_("Stop"))
|
||||||
button.connect("clicked", game_actions.on_game_stop)
|
button.connect("clicked", game_actions.on_game_stop)
|
||||||
|
button.set_sensitive(game_actions.is_game_running)
|
||||||
else:
|
else:
|
||||||
button.set_label(_("Install"))
|
button.set_label(_("Install"))
|
||||||
button.connect("clicked", game_actions.on_install_clicked)
|
button.connect("clicked", game_actions.on_install_clicked)
|
||||||
|
button.set_sensitive(game_actions.is_installable)
|
||||||
if self.service:
|
if self.service:
|
||||||
if self.service.local:
|
if self.service.local:
|
||||||
# Local services don't show an install dialog, they can be launched directly
|
# Local services don't show an install dialog, they can be launched directly
|
||||||
|
|
Loading…
Reference in a new issue