index : archinstall32 | |
Archlinux32 installer | gitolite user |
summaryrefslogtreecommitdiff |
-rw-r--r-- | archinstall/lib/profile/profile_menu.py | 218 |
diff --git a/archinstall/lib/profile/profile_menu.py b/archinstall/lib/profile/profile_menu.py new file mode 100644 index 00000000..aba75a88 --- /dev/null +++ b/archinstall/lib/profile/profile_menu.py @@ -0,0 +1,218 @@ +from __future__ import annotations + +from typing import TYPE_CHECKING, Any, Optional, Dict + +from archinstall.default_profiles.profile import Profile, GreeterType +from .profile_model import ProfileConfiguration +from ..menu import Menu, MenuSelectionType, AbstractSubMenu, Selector +from ..interactions.system_conf import select_driver +from ..hardware import GfxDriver + +if TYPE_CHECKING: + _: Any + + +class ProfileMenu(AbstractSubMenu): + def __init__( + self, + data_store: Dict[str, Any], + preset: Optional[ProfileConfiguration] = None + ): + if preset: + self._preset = preset + else: + self._preset = ProfileConfiguration() + + super().__init__(data_store=data_store) + + def setup_selection_menu_options(self): + self._menu_options['profile'] = Selector( + _('Type'), + lambda x: self._select_profile(x), + display_func=lambda x: x.name if x else None, + preview_func=self._preview_profile, + default=self._preset.profile, + enabled=True + ) + + self._menu_options['gfx_driver'] = Selector( + _('Graphics driver'), + lambda preset: self._select_gfx_driver(preset), + display_func=lambda x: x.value if x else None, + dependencies=['profile'], + preview_func=self._preview_gfx, + default=self._preset.gfx_driver if self._preset.profile and self._preset.profile.is_graphic_driver_supported() else None, + enabled=self._preset.profile.is_graphic_driver_supported() if self._preset.profile else False + ) + + self._menu_options['greeter'] = Selector( + _('Greeter'), + lambda preset: select_greeter(self._menu_options['profile'].current_selection, preset), + display_func=lambda x: x.value if x else None, + dependencies=['profile'], + default=self._preset.greeter if self._preset.profile and self._preset.profile.is_greeter_supported() else None, + enabled=self._preset.profile.is_greeter_supported() if self._preset.profile else False + ) + + def run(self, allow_reset: bool = True) -> Optional[ProfileConfiguration]: + super().run(allow_reset=allow_reset) + + if self._data_store.get('profile', None): + return ProfileConfiguration( + self._menu_options['profile'].current_selection, + self._menu_options['gfx_driver'].current_selection, + self._menu_options['greeter'].current_selection + ) + + return None + + def _select_profile(self, preset: Optional[Profile]) -> Optional[Profile]: + profile = select_profile(preset) + + if profile is not None: + if not profile.is_graphic_driver_supported(): + self._menu_options['gfx_driver'].set_enabled(False) + self._menu_options['gfx_driver'].set_current_selection(None) + else: + self._menu_options['gfx_driver'].set_enabled(True) + self._menu_options['gfx_driver'].set_current_selection(GfxDriver.AllOpenSource) + + if not profile.is_greeter_supported(): + self._menu_options['greeter'].set_enabled(False) + self._menu_options['greeter'].set_current_selection(None) + else: + self._menu_options['greeter'].set_enabled(True) + self._menu_options['greeter'].set_current_selection(profile.default_greeter_type) + else: + self._menu_options['gfx_driver'].set_current_selection(None) + self._menu_options['greeter'].set_current_selection(None) + + return profile + + def _select_gfx_driver(self, preset: Optional[GfxDriver] = None) -> Optional[GfxDriver]: + driver = preset + profile: Optional[Profile] = self._menu_options['profile'].current_selection + + if profile: + if profile.is_graphic_driver_supported(): + driver = select_driver(current_value=preset) + + if driver and 'Sway' in profile.current_selection_names(): + if driver.is_nvidia(): + prompt = str(_('The proprietary Nvidia driver is not supported by Sway. It is likely that you will run into issues, are you okay with that?')) + choice = Menu(prompt, Menu.yes_no(), default_option=Menu.no(), skip=False).run() + + if choice.value == Menu.no(): + return None + + return driver + + def _preview_gfx(self) -> Optional[str]: + driver: Optional[GfxDriver] = self._menu_options['gfx_driver'].current_selection + + if driver: + return driver.packages_text() + + return None + + def _preview_profile(self) -> Optional[str]: + profile: Optional[Profile] = self._menu_options['profile'].current_selection + text = '' + + if profile: + if (sub_profiles := profile.current_selection) is not None: + text += str(_('Selected profiles: ')) + text += ', '.join([p.name for p in sub_profiles]) + '\n' + + if packages := profile.packages_text(include_sub_packages=True): + text += f'{packages}' + + if text: + return text + + return None + + +def select_greeter( + profile: Optional[Profile] = None, + preset: Optional[GreeterType] = None +) -> Optional[GreeterType]: + if not profile or profile.is_greeter_supported(): + title = str(_('Please chose which greeter to install')) + greeter_options = [greeter.value for greeter in GreeterType] + + default: Optional[GreeterType] = None + + if preset is not None: + default = preset + elif profile is not None: + default_greeter = profile.default_greeter_type + default = default_greeter if default_greeter else None + + choice = Menu( + title, + greeter_options, + skip=True, + default_option=default.value if default else None + ).run() + + match choice.type_: + case MenuSelectionType.Skip: + return default + + return GreeterType(choice.single_value) + + return None + + +def select_profile( + current_profile: Optional[Profile] = None, + title: Optional[str] = None, + allow_reset: bool = True, + multi: bool = False +) -> Optional[Profile]: + from archinstall.lib.profile.profiles_handler import profile_handler + top_level_profiles = profile_handler.get_top_level_profiles() + + display_title = title + if not display_title: + display_title = str(_('This is a list of pre-programmed default_profiles')) + + choice = profile_handler.select_profile( + top_level_profiles, + current_profile=current_profile, + title=display_title, + allow_reset=allow_reset, + multi=multi + ) + + match choice.type_: + case MenuSelectionType.Selection: + profile_selection: Profile = choice.single_value + select_result = profile_selection.do_on_select() + + if not select_result: + return select_profile( + current_profile=current_profile, + title=title, + allow_reset=allow_reset, + multi=multi + ) + + # we're going to reset the currently selected profile(s) to avoid + # any stale data laying around + match select_result: + case select_result.NewSelection: + profile_handler.reset_top_level_profiles(exclude=[profile_selection]) + current_profile = profile_selection + case select_result.ResetCurrent: + profile_handler.reset_top_level_profiles() + current_profile = None + case select_result.SameSelection: + pass + + return current_profile + case MenuSelectionType.Reset: + return None + case MenuSelectionType.Skip: + return current_profile |