Skip to content

Commit

Permalink
WIP - Launchers
Browse files Browse the repository at this point in the history
env.linux: allow AppLauncher to run .exes for consistency; add type hints

Launchers tab in settings is very chaotic but working (ish). Still need to:
- Make buttons display the correct text (reset/remove etc)
- Make the status bar update when a launcher is changed/added/removed
- Find a way to deal with different definitions of what a launcher is depending on whether it's preconfigured or custom
- Test thoroughly
- Lots of other things I haven't thought of
  • Loading branch information
BGazotti committed Feb 8, 2024
1 parent 7ae3ae5 commit ad6c266
Show file tree
Hide file tree
Showing 6 changed files with 51 additions and 22 deletions.
5 changes: 3 additions & 2 deletions Mopy/bash/basher/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -2158,8 +2158,9 @@ class SaveList(UIList):
}
#--Labels
labels = {**_common_labels,
'PlayTime': lambda self, p: f'{(playMinutes := self.data_store[
p].header.gameTicks // 60000) // 60}:{playMinutes % 60:02d}',
'PlayTime': lambda self, p:
f'{(playMinutes := self.data_store[p].header.gameTicks // 60000) // 60}'
f':{playMinutes % 60:02d}',
'Player': _ask_info('header.pcName'),
'Cell': _ask_info('header.pcLocation'),
}
Expand Down
2 changes: 1 addition & 1 deletion Mopy/bash/basher/app_buttons.py
Original file line number Diff line number Diff line change
Expand Up @@ -161,7 +161,7 @@ class AppButton(AppLauncher, StatusBarButton):
"""Launch an application."""
_obseTip = None

def __init__(self, launcher_path, images, tip, uid, cli_args=(),
def __init__(self, launcher_path: bolt.Path, images, tip, uid, cli_args=(),
canHide=True, display_launcher=True):
"""images: [16x16,24x24,32x32] images"""
super().__init__(launcher_path, cli_args, display_launcher, uid,
Expand Down
31 changes: 20 additions & 11 deletions Mopy/bash/basher/links_init.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@
from .. import bass, bush
from ..balt import BashStatusBar, MenuLink, SeparatorLink, UIList_Delete, \
UIList_Hide, UIList_OpenItems, UIList_OpenStore, UIList_Rename
from ..bolt import os_name
from ..bolt import GPath, os_name
from ..env import init_app_links
from ..game import MergeabilityCheck
from ..game.patch_game import PatchGame
Expand Down Expand Up @@ -142,17 +142,26 @@ def _tool_args(app_key, app_path_data, clazz=AppButton, **kwargs):
'ShowAudioToolLaunchers']) for at in audio_tools.items())
all_links.extend(_tool_args(*mt) for mt in misc_tools.items())
#--Custom Apps
for pth, img_path, shortcut_descr in init_app_links(
bass.dirs['mopy'].join('Apps')):
if img_path is None:
imgs = badIcons # use the 'x' icon
else:
imgs = [__fp(p, GuiImage.img_types['.ico'], x) for x, p in
zip((16, 24, 32), img_path)]
#retrieve launchers
#find an icon
#get app_key -> what is this????
# add AppButton to all_links.
for launcher_name in bass.settings['bash.launchers']:
launcher_path, launcher_args = bass.settings['bash.launchers'][launcher_name]
all_links.append(AppButton(GPath(launcher_path), badIcons,
_(f'Run {launcher_name}'), launcher_name,cli_args=shlex.split(launcher_args), canHide=False))

#for pth, img_path, shortcut_descr in init_app_links(
# bass.dirs['mopy'].join('Apps')):
#if img_path is None:
# imgs = badIcons # use the 'x' icon
#else:
# imgs = [__fp(p, GuiImage.img_types['.ico'], x) for x, p in
# zip((16, 24, 32), img_path)]
#target.stail would keep the id on renaming the .lnk but this is unique
app_key = pth.stail.lower()
all_links.append(LnkButton(pth, imgs, shortcut_descr, app_key,
canHide=False))
#app_key = pth.stail.lower()
#all_links.append(LnkButton(pth, imgs, shortcut_descr, app_key,
# canHide=False))
#--Final couple
all_links.append(DocBrowserButton('DocBrowser'))
all_links.append(PluginCheckerButton('ModChecker'))
Expand Down
29 changes: 22 additions & 7 deletions Mopy/bash/basher/settings_dialog.py
Original file line number Diff line number Diff line change
Expand Up @@ -1546,6 +1546,14 @@ def should_appear():
class LaunchersPage(_AFixedPage):
"""Create, delete and toggle app launchers."""

# this might be useful to separate preconfigured
# from custom launchers - though I'm seriously
# considering treating them all the same and allow
# editing for everything. If people want to break their
# shortcuts I wouldn't get in their way especially since
# doing so means more work
default_launchers = list()

def __init__(self, parent, page_desc):
super(LaunchersPage, self).__init__(parent, page_desc)

Expand Down Expand Up @@ -1632,7 +1640,7 @@ def _handle_launcher_selected(self, index: int, selected_str):
# make name and args not editable;
# change remove to reset which will restore the default path

if selected_str in BashStatusBar.all_sb_links: #TODO diff stock/custom
if selected_str not in bass.settings['bash.launchers']: #TODO diff stock/custom
self._launcher_name_txt.editable = False
self._launcher_args_txt.editable = False
self._remove_launcher_btn.button_label = _('Reset')
Expand All @@ -1645,9 +1653,15 @@ def _handle_launcher_selected(self, index: int, selected_str):

# copy launcher details to textfields
self._launcher_name_txt.text_content = selected_str
# TODO fix custom launchers being just tuples and not having app_path
self._launcher_path_txt.text_content= selected_launcher.app_path.s
self._launcher_args_txt.text_content = shlex.join(selected_launcher.app_cli(()))
# FIXME unify launchers
if path_obj := getattr(selected_launcher, 'app_path',None):
# has a Path(TM)
self._launcher_path_txt.text_content = path_obj.s
self._launcher_args_txt.text_content = shlex.join(
selected_launcher.app_cli(()))
else:
(self._launcher_path_txt.text_content,
self._launcher_args_txt.text_content) = selected_launcher

def _reset_textfields(self):
self._launcher_path_txt.text_content = _('Path to application')
Expand Down Expand Up @@ -1709,9 +1723,10 @@ def _remove_or_cancel(self):
# user canceled in confirm dialog
return
launcher_name = self._launcher_name_txt.text_content
if launcher_name in (_(u'<New...>'), u''): # again, can't do that
return
del bass.settings['bash.launchers'][launcher_name]
try:
del bass.settings['bash.launchers'][launcher_name]
except KeyError:
pass # FIXME exception-oriented crap
self._clear_textfields()
self._populate_launcher_listbox()

Expand Down
1 change: 1 addition & 0 deletions Mopy/bash/bass.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@
inisettings = {}

# settings dictionary - belongs to a dedicated settings module below bolt - WIP !
# bash.launchers: dict[name: str][path, args: str]
settings = None # bolt.Settings !

# restarting info
Expand Down
5 changes: 4 additions & 1 deletion Mopy/bash/env/linux.py
Original file line number Diff line number Diff line change
Expand Up @@ -335,8 +335,11 @@ def __init__(self, title, heading, content, tsk_buttons=(),
raise EnvError(u'TaskDialog')

class AppLauncher(_AppLauncher):
def launch_app(self, exe_path, exe_args):
def launch_app(self, exe_path: _Path, exe_args):
kw = dict(close_fds=True, env=os.environ.copy())
if exe_path.cext == '.exe': # win exec, run with wine/proton
return subprocess.Popen([_WINEPATH, exe_path.s, *exe_args],
close_fds=True, env=os.environ.copy())
if os.access(exe_path, mode=os.X_OK):
# we could run this if we tried so let's do it
return subprocess.Popen([exe_path.s, *exe_args], **kw)
Expand Down

0 comments on commit ad6c266

Please sign in to comment.