1#!/usr/local/bin/python3.8
2# coding: utf-8
3
4from gi.repository import Gtk
5
6import status
7
8class FocusNavigator:
9    """
10    FocusNavigator helps with tab navigation between
11    widgets in our status.focusWidgets list.
12
13    Since we handle most user events ourselves, we also
14    need to handle Tab events correctly.
15    """
16    def __init__(self, widgets=[]):
17        status.focusWidgets = widgets
18
19    def _get_focus_index(self):
20        widgets = status.focusWidgets
21        focus_index = -1
22        for widget in widgets:
23            if widget.has_focus():
24                focus_index = widgets.index(widget)
25                break
26
27        return focus_index
28
29    def _focus_first_possible(self):
30        widgets = status.focusWidgets
31
32        for widget in widgets:
33            if widget.get_sensitive():
34                widget.grab_focus()
35                widget.grab_default()
36                break
37
38    def _focus_next(self, current):
39        widgets = status.focusWidgets
40        new = current + 1
41
42        if new >= len(widgets):
43            new = 0
44
45        if not widgets[new].get_sensitive():
46            self._focus_next(new)
47            return
48
49        widgets[new].grab_focus()
50        widgets[new].grab_default()
51
52    def _focus_previous(self, current):
53        widgets = status.focusWidgets
54        new = current - 1
55
56        if new < 0:
57            new = len(widgets) - 1
58
59        if not widgets[new].get_sensitive():
60            self._focus_previous(new)
61            return
62
63        widgets[new].grab_focus()
64        widgets[new].grab_default()
65
66    def navigate(self, reverse):
67        current_index = self._get_focus_index()
68
69        if current_index == -1:
70            self._focus_first_possible()
71        if reverse:
72            self._focus_previous(current_index)
73        else:
74            self._focus_next(current_index)
75
76    def activate_focus(self):
77        widgets = status.focusWidgets
78
79        focus_index = self._get_focus_index()
80
81        if focus_index == -1:
82            return
83
84        widget = widgets[focus_index]
85
86        if isinstance(widget, Gtk.Button):
87            widget.clicked()
88        elif isinstance(widget, Gtk.Entry):
89            widget.activate()
90
91    def get_focused_widget(self):
92        widgets = status.focusWidgets
93
94        focus_index = self._get_focus_index()
95
96        if focus_index == -1:
97            return None
98
99        return widgets[focus_index]
100