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
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
1"""hods - home directory synchronization.
3Copyright (C) 2016-2020 Mathias Stelzer <knoppo@rolln.de>
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.
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.
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
21class FocusMap(urwid.AttrMap):
22 """A `urwid.AttrMap` that adds a focus map."""
24 def __init__(self, widget, attr):
25 """Initilaize attr_map with focus."""
26 super().__init__(widget, attr, '{} focus'.format(attr))
29class DescriptionListBox(urwid.ListBox):
30 """A properly aligned description list in a window."""
32 def __init__(self, items, space=1):
33 """Initialize widget.
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
43 self.walker = urwid.SimpleFocusListWalker(list(self.get_widgets()))
44 super().__init__(self.walker)
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
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
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)
72 if key_len > key_width:
73 key_width = key_len
75 value_len = len(value)
76 if value_len > value_width:
77 value_width = value_len
78 return key_width, value_width
80 def get_widgets(self):
81 """Calculate width, wrap the rows and return them.
83 :return: `list` - rows
84 """
85 for key, value in self.items:
86 yield self.get_row(key, value)
88 def _resolve_field(self, field):
89 attrs = None
90 if isinstance(field, tuple):
91 attrs = list(field)
92 field = attrs.pop(0)
94 if isinstance(field, str): # pragma: no branch
95 field = urwid.Text(field)
97 if attrs:
98 field = urwid.AttrMap(field, *attrs)
100 return field
102 def get_row(self, key, value=None):
103 """Build and return a row.
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)
114 if value is None:
115 return key
117 value = self._resolve_field(value)
119 return urwid.Columns(
120 [
121 (self.key_width, key),
122 value,
123 ],
124 dividechars=self.space,
125 )