Files
AirlockTools/TUI/Screens/policyselectorscreen.py

110 lines
3.4 KiB
Python

# Copyright (C) 2025 James Brotosky, Brandon Wickline
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as published
# by the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.
"""
Policy Selector Screen Module
Provides a Textual Screen wrapper for the PolicySelector widget that manages
the policy selection workflow.
"""
import logging
from textual.app import ComposeResult
from textual.binding import Binding
from textual.screen import Screen
from textual.widgets import Footer, Header
from TUI.Widgets.policyselector import PolicySelector
logger = logging.getLogger(__name__)
class PolicySelectorScreen(Screen):
"""
A Textual Screen for policy selection in agent move operations.
This screen wraps the PolicySelector widget and manages the workflow
of selecting a target policy for bulk agent movements.
Attributes:
policies: List of available policies (Policy objects or DataFrame).
agent_move_operations: Reference to the parent AgentMoveOperations widget.
"""
BINDINGS = [
Binding("escape", "go_back", "Back"),
Binding("q", "main_menu", "Main Menu"),
]
CSS = """
Screen {
layout: vertical;
background: $surface;
}
"""
def __init__(
self,
policies,
agent_move_operations=None,
):
"""
Initialize the PolicySelectorScreen.
Args:
policies: List of available policies to display.
agent_move_operations: Reference to parent AgentMoveOperations widget.
Used to call back when policy selection is confirmed.
"""
super().__init__()
self.policies = policies
self.agent_move_operations = agent_move_operations
def compose(self) -> ComposeResult:
"""Create the PolicySelector widget."""
yield Header(show_clock=True)
yield PolicySelector(self.policies)
yield Footer()
def action_go_back(self) -> None:
"""Handle escape key to go back one screen."""
self.app.pop_screen()
def action_main_menu(self) -> None:
"""Handle q key to go back to main menu."""
while len(self.app.screen_stack) > 2:
self.app.pop_screen()
def on_policy_selector_policy_selected(
self, message: PolicySelector.PolicySelected
) -> None:
"""
Handle policy selection from the PolicySelector widget.
When a policy is selected, this handler:
1. Closes the selector screen
2. Calls the parent AgentMoveOperations to execute the move
Args:
message (PolicySelector.PolicySelected): Contains the selected policy.
"""
# Pop this screen to return to AgentMoveOperations
self.app.pop_screen()
# Call parent widget's method to execute the move
if self.agent_move_operations:
self.agent_move_operations._execute_move_to_policy(message.policy)