1import urwid
2
3
4class Tab(urwid.WidgetWrap):
5
6    def __init__(self, offset, content, attr, onclick):
7        """
8            onclick is called on click with the tab offset as argument
9        """
10        p = urwid.Text(content, align="center")
11        p = urwid.Padding(p, align="center", width=("relative", 100))
12        p = urwid.AttrWrap(p, attr)
13        urwid.WidgetWrap.__init__(self, p)
14        self.offset = offset
15        self.onclick = onclick
16
17    def mouse_event(self, size, event, button, col, row, focus):
18        if event == "mouse press" and button == 1:
19            self.onclick(self.offset)
20            return True
21
22
23class Tabs(urwid.WidgetWrap):
24
25    def __init__(self, tabs, tab_offset=0):
26        super().__init__("")
27        self.tab_offset = tab_offset
28        self.tabs = tabs
29        self.show()
30        self._w = urwid.Pile([])
31
32    def change_tab(self, offset):
33        self.tab_offset = offset
34        self.show()
35
36    def keypress(self, size, key):
37        n = len(self.tabs)
38        if key == "m_next":
39            self.change_tab((self.tab_offset + 1) % n)
40        elif key == "right":
41            self.change_tab((self.tab_offset + 1) % n)
42        elif key == "left":
43            self.change_tab((self.tab_offset - 1) % n)
44        return self._w.keypress(size, key)
45
46    def show(self):
47        if not self.tabs:
48            return
49
50        headers = []
51        for i in range(len(self.tabs)):
52            txt = self.tabs[i][0]()
53            if i == self.tab_offset % len(self.tabs):
54                headers.append(
55                    Tab(
56                        i,
57                        txt,
58                        "heading",
59                        self.change_tab
60                    )
61                )
62            else:
63                headers.append(
64                    Tab(
65                        i,
66                        txt,
67                        "heading_inactive",
68                        self.change_tab
69                    )
70                )
71        headers = urwid.Columns(headers, dividechars=1)
72        self._w = urwid.Frame(
73            body = self.tabs[self.tab_offset % len(self.tabs)][1](),
74            header = headers
75        )
76        self._w.set_focus("body")
77