Skip to content

main

Public entry point for launching the terminal UI.

run_app()

Entry point for launching the terminal UI.

Source code in src/awesome_os/frontend/main.py
def run_app() -> None:
    """Entry point for launching the terminal UI."""
    system, distro, info, packages = build_packages_for_os()
    info = f" info:{info}" if info else ""
    root = ttk.TTk()
    win = ttk.TTkWindow(
        parent=root,
        title="Awesome OS Setup",
        size=(150, 50),
        border=True,
        layout=ttk.TTkVBoxLayout(),
    )

    # header
    header = ttk.TTkFrame(parent=win, layout=ttk.TTkHBoxLayout())
    ttk.TTkLabel(
        parent=header,
        text=f"OS: {system} | Distro: {distro} | {info}",
        color=ttk.TTkColor.fg("#00ff00"),
        maxHeight=2,
    )

    # body — limit height so footer action buttons remain visible
    body = ttk.TTkFrame(parent=win, layout=ttk.TTkHBoxLayout(), maxHeight=25)

    # left: packages list (native TermTk list widget, multi-select)
    left = ttk.TTkFrame(parent=body, title=TTkString("Packages"), layout=ttk.TTkVBoxLayout())

    ttk.TTkLabel(parent=left, text="[ MultiSelect ]", maxHeight=1)
    package_list = ttk.TTkList(parent=left, selectionMode=ttk.TTkK.MultiSelection)

    # Map list labels back to PackageRef so we can install selections.
    label_to_pkg: dict[str, object] = {}
    for p in sorted(packages, key=lambda x: (x.category, x.manager, x.name)):
        label = f"[{p.category}] {p.name} ({p.manager})"
        package_list.addItem(label)
        label_to_pkg[label] = p

    def _get_selected_packages() -> list[object]:
        out: list[object] = []
        for l in package_list.selectedLabels():
            pkg = label_to_pkg.get(str(l))
            if pkg is not None:
                out.append(pkg)
        return out

    # right
    right = ttk.TTkFrame(parent=body, title=TTkString("Log"), layout=ttk.TTkVBoxLayout())
    log = ttk.TTkTextEdit(parent=right, readOnly=True)
    right.layout().addWidget(log)  # type: ignore[call-arg]

    # footer
    footer = ttk.TTkFrame(parent=win, layout=ttk.TTkVBoxLayout())

    # Display install button
    install_row = ttk.TTkFrame(parent=footer, layout=ttk.TTkHBoxLayout())
    install_btn = ttk.TTkButton(parent=install_row, text=TTkString("Install selected"))

    action_buttons: list[ttk.TTkButton] = []

    runner = JobRunner()
    runner.start()

    poll_timer = ttk.TTkTimer()

    controller = AppController(
        win=win,
        log=log,
        distro=distro,
        get_selected_packages=_get_selected_packages,  # type: ignore[arg-type]
        install_btn=install_btn,
        action_buttons=action_buttons,
        runner=runner,
        poll_timer=poll_timer,
    )

    install_btn.clicked.connect(controller.install_selected_clicked)

    if distro == "unknown":
        controller.ui_log("Unsupported OS")

    # Display actions buttons
    for section_name, actions in get_system_action_sections(
        system=system, distro=distro, info=info
    ):
        row = ttk.TTkFrame(parent=footer, layout=ttk.TTkHBoxLayout())
        ttk.TTkLabel(parent=row, text=f"{section_name}:", maxWidth=14)
        for action in actions:
            btn = ttk.TTkButton(parent=row, text=TTkString(action.label))
            action_buttons.append(btn)

            def _on_action_clicked(
                *_args: object, _action: SystemAction = action, _section_name: str = section_name
            ) -> None:
                controller.action_clicked(_action, _section_name)

            btn.clicked.connect(_on_action_clicked)

    poll_timer.timeout.connect(controller.on_poll)
    poll_timer.start(0.1)

    try:
        root.mainloop()
    finally:
        controller.shutdown()