Coverage for openhcs/textual_tui/widgets/different_values_radio_set.py: 0.0%

68 statements  

« prev     ^ index     » next       coverage.py v7.10.7, created at 2025-10-01 18:33 +0000

1"""Simple radio set widget for handling different values across multiple configurations.""" 

2 

3from typing import Any, Type 

4from enum import Enum 

5from textual.widgets import RadioSet, RadioButton 

6from textual.events import Click 

7 

8 

9class DifferentValuesRadioSet(RadioSet): 

10 """Simple radio set that shows no selection for different values. 

11  

12 This widget appears with no radio button selected when values differ 

13 across configurations. Click sets it to the default value. 

14 """ 

15 

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. 

24  

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 from openhcs.ui.shared.ui_utils import format_enum_display 

33 

34 radio_buttons = [] 

35 for enum_value in enum_type: 

36 radio_buttons.append(format_enum_display(enum_value)) 

37 

38 super().__init__(*radio_buttons, **kwargs) 

39 

40 self.enum_type = enum_type 

41 self.default_value = default_value 

42 self.field_name = field_name 

43 self.is_different_state = True 

44 

45 # Clear any initial selection and add disabled appearance 

46 self._clear_selection() 

47 self.add_class("different-values-disabled") 

48 

49 # Set tooltip to explain the state 

50 self.tooltip = f"DIFFERENT VALUES - Click to set to default: {self.default_value.value}" 

51 

52 def _clear_selection(self) -> None: 

53 """Clear all radio button selections.""" 

54 for button in self.query('RadioButton'): 

55 button.value = False 

56 

57 

58 

59 def on_click(self, event: Click) -> None: 

60 """Message handler for Click events - set to default value if in different state.""" 

61 if self.is_different_state: 

62 # Set to default value by finding and selecting the matching button 

63 default_label = self.default_value.value.upper() 

64 

65 for button in self.query('RadioButton'): 

66 if hasattr(button, 'label') and str(button.label).upper() == default_label: 

67 button.value = True 

68 break 

69 

70 self.is_different_state = False 

71 self.remove_class("different-values-disabled") 

72 

73 # Clear tooltip since we now have a value 

74 self.tooltip = "" 

75 

76 # Focus the radio set 

77 self.focus() 

78 

79 # Prevent the event from bubbling up 

80 event.stop() 

81 

82 def reset_to_different(self) -> None: 

83 """Reset the radio set back to 'DIFFERENT VALUES' state.""" 

84 self._clear_selection() 

85 self.add_class("different-values-disabled") 

86 self.is_different_state = True 

87 

88 # Restore tooltip 

89 self.tooltip = f"DIFFERENT VALUES - Click to set to default: {self.default_value.value}" 

90 

91 def set_value(self, value: Enum) -> None: 

92 """Set a specific value (not from click-to-default).""" 

93 from openhcs.ui.shared.enum_display_formatter import EnumDisplayFormatter 

94 

95 # Clear current selection 

96 self._clear_selection() 

97 

98 # Set the new value 

99 target_label = EnumDisplayFormatter.get_display_text(value) 

100 for button in self.query('RadioButton'): 

101 if hasattr(button, 'label') and str(button.label).upper() == target_label: 

102 button.value = True 

103 break 

104 

105 self.is_different_state = False 

106 self.tooltip = "" 

107 

108 @property 

109 def current_state(self) -> str: 

110 """Get the current state of the widget.""" 

111 if self.is_different_state: 

112 return "different" 

113 

114 # Check if current selection matches default 

115 pressed_button = self.pressed_button 

116 if pressed_button and hasattr(pressed_button, 'label'): 

117 current_label = str(pressed_button.label).upper() 

118 default_label = self.default_value.value.upper() 

119 if current_label == default_label: 

120 return "default" 

121 

122 return "modified" 

123 

124 @property 

125 def selected_enum_value(self) -> Enum: 

126 """Get the currently selected enum value.""" 

127 pressed_button = self.pressed_button 

128 if pressed_button and hasattr(pressed_button, 'label'): 

129 label = str(pressed_button.label).upper() 

130 # Find matching enum value 

131 for enum_value in self.enum_type: 

132 if enum_value.value.upper() == label: 

133 return enum_value 

134 return None