Coverage for src/hods/tui/base/widgets.py: 100.00%

Shortcuts on this page

r m x p   toggle line displays

j k   next/prev highlighted chunk

0   (zero) top of page

1   (one) first highlighted chunk

49 statements  

1"""hods - home directory synchronization. 

2 

3Copyright (C) 2016-2020 Mathias Stelzer <knoppo@rolln.de> 

4 

5hods is free software: you can redistribute it and/or modify 

6it under the terms of the GNU General Public License as published by 

7the Free Software Foundation, either version 3 of the License, or 

8(at your option) any later version. 

9 

10hods is distributed in the hope that it will be useful, 

11but WITHOUT ANY WARRANTY; without even the implied warranty of 

12MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 

13GNU General Public License for more details. 

14 

15You should have received a copy of the GNU General Public License 

16along with this program. If not, see <http://www.gnu.org/licenses/>. 

17""" 

18import urwid 

19 

20 

21class FocusMap(urwid.AttrMap): 

22 """A `urwid.AttrMap` that adds a focus map.""" 

23 

24 def __init__(self, widget, attr): 

25 """Initilaize attr_map with focus.""" 

26 super().__init__(widget, attr, '{} focus'.format(attr)) 

27 

28 

29class DescriptionListBox(urwid.ListBox): 

30 """A properly aligned description list in a window.""" 

31 

32 def __init__(self, items, space=1): 

33 """Initialize widget. 

34 

35 :param items: Dictionary or list of pairs to display. 

36 :param space: Additional space between left and right columns. 

37 """ 

38 self.space = space 

39 self.items = list(self.flatten_items(items)) 

40 self.key_width, self.value_width = self.get_widths() 

41 self.width = self.key_width + self.value_width + space 

42 

43 self.walker = urwid.SimpleFocusListWalker(list(self.get_widgets())) 

44 super().__init__(self.walker) 

45 

46 def flatten_items(self, items): 

47 """Replace non-tuples with tuples using ``None`` as the value.""" 

48 for item in items: 

49 if isinstance(item, tuple): 

50 yield item 

51 else: 

52 if not item: 

53 yield item, None # pragma: no cover 

54 else: 

55 yield (item, 'frame header'), None 

56 

57 def get_widths(self): 

58 """Calculate the width for the key column.""" 

59 key_width, value_width = 1, 1 

60 for key, value in self.items: 

61 if value is None: 

62 continue 

63 

64 if isinstance(key, tuple): # pragma: no cover 

65 if isinstance(key[0], int): 

66 key_len = key[0] 

67 else: 

68 key_len = len(key[0]) 

69 else: 

70 key_len = len(key) 

71 

72 if key_len > key_width: 

73 key_width = key_len 

74 

75 value_len = len(value) 

76 if value_len > value_width: 

77 value_width = value_len 

78 return key_width, value_width 

79 

80 def get_widgets(self): 

81 """Calculate width, wrap the rows and return them. 

82 

83 :return: `list` - rows 

84 """ 

85 for key, value in self.items: 

86 yield self.get_row(key, value) 

87 

88 def _resolve_field(self, field): 

89 attrs = None 

90 if isinstance(field, tuple): 

91 attrs = list(field) 

92 field = attrs.pop(0) 

93 

94 if isinstance(field, str): # pragma: no branch 

95 field = urwid.Text(field) 

96 

97 if attrs: 

98 field = urwid.AttrMap(field, *attrs) 

99 

100 return field 

101 

102 def get_row(self, key, value=None): 

103 """Build and return a row. 

104 

105 :param key: `str` or widget - The Keyword/Label for the row. 

106 (Left column) 

107 :param value: `str`, `str` or widget - Description for 

108 the given key. (Right column) 

109 If ``None`` the key gets the full width. 

110 :return: `urwid.Columns` - Row widget 

111 """ 

112 key = self._resolve_field(key) 

113 

114 if value is None: 

115 return key 

116 

117 value = self._resolve_field(value) 

118 

119 return urwid.Columns( 

120 [ 

121 (self.key_width, key), 

122 value, 

123 ], 

124 dividechars=self.space, 

125 )