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

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 radio_buttons = [] 

33 for enum_value in enum_type: 

34 radio_buttons.append(enum_value.value.upper()) 

35 

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

37 

38 self.enum_type = enum_type 

39 self.default_value = default_value 

40 self.field_name = field_name 

41 self.is_different_state = True 

42 

43 # Clear any initial selection and add disabled appearance 

44 self._clear_selection() 

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

46 

47 # Set tooltip to explain the state 

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

49 

50 def _clear_selection(self) -> None: 

51 """Clear all radio button selections.""" 

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

53 button.value = False 

54 

55 

56 

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() 

62 

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 

67 

68 self.is_different_state = False 

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

70 

71 # Clear tooltip since we now have a value 

72 self.tooltip = "" 

73 

74 # Focus the radio set 

75 self.focus() 

76 

77 # Prevent the event from bubbling up 

78 event.stop() 

79 

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 

85 

86 # Restore tooltip 

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

88 

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() 

93 

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 

100 

101 self.is_different_state = False 

102 self.tooltip = "" 

103 

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" 

109 

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" 

117 

118 return "modified" 

119 

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