Skip to content

Commit

Permalink
Integrate new curses menu (#2663)
Browse files Browse the repository at this point in the history
* Edit text menu

* Fix alignment

* Scroll functionality

* Fix flake8

* Migrate locales menu

* Fix language translation

* Fix interrupt

* Fix flake8

* Edit mode preset

* Convert print to tui prints

* Fix mypy

* Fix cycling through long menu

* Fix profile view

* Fix scrolling

* Fix scrolling

* Fix mypy

* Fix swiss script

* Display asterisk for passwords

* Corrected a variable usage in the local mirror parsing

* Made sure that curses menu selection on mirrors use url object from mirror.url instead of the class instance

* Fixed mypy type on mirror list

---------

Co-authored-by: Torxed <[email protected]>
  • Loading branch information
svartkanin and Torxed authored Nov 15, 2024
1 parent 591b831 commit 88b91ae
Show file tree
Hide file tree
Showing 71 changed files with 3,564 additions and 3,232 deletions.
4 changes: 2 additions & 2 deletions .github/ISSUE_TEMPLATE/01_bug.yml
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ body:
- type: textarea
id: bug-report
attributes:
label: The installation log
label: The installation log
description: 'note: located at `/var/log/archinstall/install.log`'
placeholder: |
Hardware model detected: Dell Inc. Precision 7670; UEFI mode: True
Expand Down Expand Up @@ -82,4 +82,4 @@ body:
**Note**: Feel free to modify the textarea above as you wish.
But it will grately help us in testing if we can generate the specific qemu command line,
for instance via:
`sudo virsh domxml-to-native qemu-argv --domain my-arch-machine`
`sudo virsh domxml-to-native qemu-argv --domain my-arch-machine`
2 changes: 1 addition & 1 deletion .github/ISSUE_TEMPLATE/02_feature.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,4 +14,4 @@ body:
description: >
Feel free to write any feature you think others might benefit from:
validations:
required: true
required: true
2 changes: 1 addition & 1 deletion .github/workflows/mypy.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -20,4 +20,4 @@ jobs:
- run: python --version
- run: mypy --version
- name: run mypy
run: mypy
run: mypy --config-file pyproject.toml
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -38,4 +38,4 @@ venv
requirements.txt
/.gitconfig
/actions-runner
/cmd_output.txt
/cmd_output.txt
3 changes: 3 additions & 0 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,9 @@ repos:
rev: v1.13.0
hooks:
- id: mypy
args: [
'--config-file=pyproject.toml'
]
fail_fast: true
additional_dependencies:
- pydantic
Expand Down
2 changes: 1 addition & 1 deletion .pypirc
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,4 @@ index-servers =
pypi

[pypi]
repository = https://upload.pypi.org/legacy/
repository = https://upload.pypi.org/legacy/
2 changes: 1 addition & 1 deletion .readthedocs.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,4 @@ sphinx:
build:
os: "ubuntu-22.04"
tools:
python: "3.11"
python: "3.11"
22 changes: 2 additions & 20 deletions archinstall/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@
from typing import TYPE_CHECKING, Any, Dict, Union

from .lib import disk
from .lib import menu
from .lib import models
from .lib import packages
from .lib import exceptions
Expand All @@ -32,6 +31,7 @@
from .lib.translationhandler import TranslationHandler, Language, DeferredTranslation
from .lib.plugins import plugins, load_plugin
from .lib.configuration import ConfigurationOutput
from .tui import Tui

from .lib.general import (
generate_password, locate_binary, clear_vt100_escape_codes,
Expand Down Expand Up @@ -330,24 +330,6 @@ def main() -> None:
importlib.import_module(mod_name)


def _shutdown_curses() -> None:
try:
curses.nocbreak()

try:
from archinstall.tui.curses_menu import tui
tui.screen.keypad(False)
except Exception:
pass

curses.echo()
curses.curs_set(True)
curses.endwin()
except Exception:
# this may happen when curses has not been initialized
pass


def run_as_a_module() -> None:
exc = None

Expand All @@ -357,7 +339,7 @@ def run_as_a_module() -> None:
exc = e
finally:
# restore the terminal to the original state
_shutdown_curses()
Tui.shutdown()

if exc:
err = ''.join(traceback.format_exception(exc))
Expand Down
44 changes: 31 additions & 13 deletions archinstall/default_profiles/desktop.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,14 @@
from typing import Any, TYPE_CHECKING, List, Optional, Dict

from archinstall.lib import menu
from archinstall.lib.output import info
from archinstall.lib.profile.profiles_handler import profile_handler
from archinstall.default_profiles.profile import Profile, ProfileType, SelectResult, GreeterType

from archinstall.tui import (
MenuItemGroup, MenuItem, SelectMenu,
FrameProperties, ResultType, PreviewStyle
)

if TYPE_CHECKING:
from archinstall.lib.installer import Installer
_: Any
Expand Down Expand Up @@ -52,22 +56,36 @@ def _do_on_select_profiles(self) -> None:
for profile in self.current_selection:
profile.do_on_select()

def do_on_select(self) -> SelectResult:
choice = profile_handler.select_profile(
profile_handler.get_desktop_profiles(),
self.current_selection,
title=str(_('Select your desired desktop environment')),
multi=True
)
def do_on_select(self) -> Optional[SelectResult]:
items = [
MenuItem(
p.name,
value=p,
preview_action=lambda x: x.value.preview_text()
) for p in profile_handler.get_desktop_profiles()
]

match choice.type_:
case menu.MenuSelectionType.Selection:
self.current_selection = choice.value # type: ignore
group = MenuItemGroup(items, sort_items=True)
group.set_selected_by_value(self.current_selection)

result = SelectMenu(
group,
multi=True,
allow_reset=True,
allow_skip=True,
preview_style=PreviewStyle.RIGHT,
preview_size='auto',
preview_frame=FrameProperties.max('Info')
).run()

match result.type_:
case ResultType.Selection:
self.current_selection = result.get_values()
self._do_on_select_profiles()
return SelectResult.NewSelection
case menu.MenuSelectionType.Skip:
case ResultType.Skip:
return SelectResult.SameSelection
case menu.MenuSelectionType.Reset:
case ResultType.Reset:
return SelectResult.ResetCurrent

def post_install(self, install_session: 'Installer') -> None:
Expand Down
35 changes: 24 additions & 11 deletions archinstall/default_profiles/desktops/hyprland.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
from enum import Enum
from typing import List, Optional, TYPE_CHECKING, Any

from archinstall.default_profiles.profile import ProfileType, GreeterType
from archinstall.default_profiles.profile import ProfileType, GreeterType, SelectResult
from archinstall.default_profiles.xorg import XorgProfile
from archinstall.lib.menu import Menu
from archinstall.tui import (
MenuItemGroup, MenuItem, SelectMenu,
FrameProperties, ResultType, Alignment
)

if TYPE_CHECKING:
from archinstall.lib.installer import Installer
Expand Down Expand Up @@ -49,20 +52,30 @@ def services(self) -> List[str]:

def _ask_seat_access(self) -> None:
# need to activate seat service and add to seat group
title = str(_('Hyprland needs access to your seat (collection of hardware devices i.e. keyboard, mouse, etc)'))
title += str(_('\n\nChoose an option to give Hyprland access to your hardware'))
header = str(_('Sway needs access to your seat (collection of hardware devices i.e. keyboard, mouse, etc)'))
header += '\n' + str(_('Choose an option to give Sway access to your hardware')) + '\n'

options = [e.value for e in SeatAccess]
default = None
items = [MenuItem(s.value, value=s) for s in SeatAccess]
group = MenuItemGroup(items, sort_items=True)

if seat := self.custom_settings.get('seat_access', None):
default = seat
default = self.custom_settings.get('seat_access', None)
group.set_default_by_value(default)

choice = Menu(title, options, skip=False, preset_values=default).run()
self.custom_settings['seat_access'] = choice.single_value
result = SelectMenu(
group,
header=header,
allow_skip=False,
frame=FrameProperties.min(str(_('Seat access'))),
alignment=Alignment.CENTER
).run()

def do_on_select(self):
if result.type_ == ResultType.Selection:
if result.item() is not None:
self.custom_settings['seat_access'] = result.get_value()

def do_on_select(self) -> Optional[SelectResult]:
self._ask_seat_access()
return None

def install(self, install_session: 'Installer') -> None:
super().install(install_session)
36 changes: 25 additions & 11 deletions archinstall/default_profiles/desktops/sway.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,13 @@
from enum import Enum
from typing import List, Optional, TYPE_CHECKING, Any

from archinstall.default_profiles.profile import ProfileType, GreeterType
from archinstall.default_profiles.profile import ProfileType, GreeterType, SelectResult
from archinstall.default_profiles.xorg import XorgProfile
from archinstall.lib.menu import Menu

from archinstall.tui import (
MenuItemGroup, MenuItem, SelectMenu,
FrameProperties, Alignment, ResultType
)

if TYPE_CHECKING:
from archinstall.lib.installer import Installer
Expand Down Expand Up @@ -58,20 +62,30 @@ def services(self) -> List[str]:

def _ask_seat_access(self) -> None:
# need to activate seat service and add to seat group
title = str(_('Sway needs access to your seat (collection of hardware devices i.e. keyboard, mouse, etc)'))
title += str(_('\n\nChoose an option to give Sway access to your hardware'))
header = str(_('Sway needs access to your seat (collection of hardware devices i.e. keyboard, mouse, etc)'))
header += '\n' + str(_('Choose an option to give Sway access to your hardware')) + '\n'

options = [e.value for e in SeatAccess]
default = None
items = [MenuItem(s.value, value=s) for s in SeatAccess]
group = MenuItemGroup(items, sort_items=True)

if seat := self.custom_settings.get('seat_access', None):
default = seat
default = self.custom_settings.get('seat_access', None)
group.set_default_by_value(default)

result = SelectMenu(
group,
header=header,
allow_skip=False,
frame=FrameProperties.min(str(_('Seat access'))),
alignment=Alignment.CENTER
).run()

choice = Menu(title, options, skip=False, preset_values=default).run()
self.custom_settings['seat_access'] = choice.single_value
if result.type_ == ResultType.Selection:
if result.item() is not None:
self.custom_settings['seat_access'] = result.get_value()

def do_on_select(self):
def do_on_select(self) -> Optional[SelectResult]:
self._ask_seat_access()
return None

def install(self, install_session: 'Installer') -> None:
super().install(install_session)
27 changes: 11 additions & 16 deletions archinstall/default_profiles/profile.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
from enum import Enum, auto
from typing import List, Optional, Any, Dict, TYPE_CHECKING

from ..lib.utils.util import format_cols
from ..lib.storage import storage

if TYPE_CHECKING:
Expand Down Expand Up @@ -126,7 +125,7 @@ def json(self) -> Dict:
"""
return {}

def do_on_select(self) -> SelectResult:
def do_on_select(self) -> Optional[SelectResult]:
"""
Hook that will be called when a profile is selected
"""
Expand Down Expand Up @@ -187,24 +186,20 @@ def preview_text(self) -> Optional[str]:
"""
return self.packages_text()

def packages_text(self, include_sub_packages: bool = False) -> Optional[str]:
header = str(_('Installed packages'))

text = ''
packages = []
def packages_text(self, include_sub_packages: bool = False) -> str:
packages = set()

if self.packages:
packages = self.packages
packages = set(self.packages)

if include_sub_packages:
for p in self.current_selection:
if p.packages:
packages += p.packages
for sub_profile in self.current_selection:
if sub_profile.packages:
packages.update(sub_profile.packages)

text += format_cols(sorted(set(packages)))
text = str(_('Installed packages')) + ':\n'

if text:
text = f'{header}: \n{text}'
return text
for pkg in sorted(packages):
text += f'\t- {pkg}\n'

return None
return text
Loading

0 comments on commit 88b91ae

Please sign in to comment.