Coverage for openhcs/textual_tui/widgets/different_values_radio_set.py: 0.0%
66 statements
« prev ^ index » next coverage.py v7.10.3, created at 2025-08-14 05:57 +0000
« prev ^ index » next coverage.py v7.10.3, created at 2025-08-14 05:57 +0000
1"""Simple radio set widget for handling different values across multiple configurations."""
3from typing import Any, Type
4from enum import Enum
5from textual.widgets import RadioSet, RadioButton
6from textual.events import Click
9class DifferentValuesRadioSet(RadioSet):
10 """Simple radio set that shows no selection for different values.
12 This widget appears with no radio button selected when values differ
13 across configurations. Click sets it to the default value.
14 """
16 def __init__(
17 self,
18 enum_type: Type[Enum],
19 default_value: Enum,
20 field_name: str = "",
21 **kwargs
22 ):
23 """Initialize the DifferentValuesRadioSet widget.
25 Args:
26 enum_type: The enum type for the radio options
27 default_value: The default value to use when clicked
28 field_name: Name of the field (for debugging/logging)
29 **kwargs: Additional arguments passed to RadioSet
30 """
31 # Create radio buttons for each enum value
32 radio_buttons = []
33 for enum_value in enum_type:
34 radio_buttons.append(enum_value.value.upper())
36 super().__init__(*radio_buttons, **kwargs)
38 self.enum_type = enum_type
39 self.default_value = default_value
40 self.field_name = field_name
41 self.is_different_state = True
43 # Clear any initial selection and add disabled appearance
44 self._clear_selection()
45 self.add_class("different-values-disabled")
47 # Set tooltip to explain the state
48 self.tooltip = f"DIFFERENT VALUES - Click to set to default: {self.default_value.value}"
50 def _clear_selection(self) -> None:
51 """Clear all radio button selections."""
52 for button in self.query('RadioButton'):
53 button.value = False
57 def on_click(self, event: Click) -> None:
58 """Message handler for Click events - set to default value if in different state."""
59 if self.is_different_state:
60 # Set to default value by finding and selecting the matching button
61 default_label = self.default_value.value.upper()
63 for button in self.query('RadioButton'):
64 if hasattr(button, 'label') and str(button.label).upper() == default_label:
65 button.value = True
66 break
68 self.is_different_state = False
69 self.remove_class("different-values-disabled")
71 # Clear tooltip since we now have a value
72 self.tooltip = ""
74 # Focus the radio set
75 self.focus()
77 # Prevent the event from bubbling up
78 event.stop()
80 def reset_to_different(self) -> None:
81 """Reset the radio set back to 'DIFFERENT VALUES' state."""
82 self._clear_selection()
83 self.add_class("different-values-disabled")
84 self.is_different_state = True
86 # Restore tooltip
87 self.tooltip = f"DIFFERENT VALUES - Click to set to default: {self.default_value.value}"
89 def set_value(self, value: Enum) -> None:
90 """Set a specific value (not from click-to-default)."""
91 # Clear current selection
92 self._clear_selection()
94 # Set the new value
95 target_label = value.value.upper()
96 for button in self.query('RadioButton'):
97 if hasattr(button, 'label') and str(button.label).upper() == target_label:
98 button.value = True
99 break
101 self.is_different_state = False
102 self.tooltip = ""
104 @property
105 def current_state(self) -> str:
106 """Get the current state of the widget."""
107 if self.is_different_state:
108 return "different"
110 # Check if current selection matches default
111 pressed_button = self.pressed_button
112 if pressed_button and hasattr(pressed_button, 'label'):
113 current_label = str(pressed_button.label).upper()
114 default_label = self.default_value.value.upper()
115 if current_label == default_label:
116 return "default"
118 return "modified"
120 @property
121 def selected_enum_value(self) -> Enum:
122 """Get the currently selected enum value."""
123 pressed_button = self.pressed_button
124 if pressed_button and hasattr(pressed_button, 'label'):
125 label = str(pressed_button.label).upper()
126 # Find matching enum value
127 for enum_value in self.enum_type:
128 if enum_value.value.upper() == label:
129 return enum_value
130 return None