X-Git-Url: https://git.stderr.nl/gitweb?p=matthijs%2Fupstream%2Fmobilegtd.git;a=blobdiff_plain;f=src%2Fgui%2Fgui.py;h=f03880854f2310bdccda1216bc322c4a60e1277a;hp=ec0a7cb6f04decbb502b0698fa242bd85ef22d8f;hb=90174cff443401af0ed99a7b7eb1203a1055b6fd;hpb=826cc2e9923c858d3c6a86c04f371cfb326e1728 diff --git a/src/gui/gui.py b/src/gui/gui.py index ec0a7cb..f038808 100644 --- a/src/gui/gui.py +++ b/src/gui/gui.py @@ -93,7 +93,6 @@ def save_gui(object): object.old_menu = appuifw.app.menu object.old_exit_key_handler = appuifw.app.exit_key_handler object.old_title=appuifw.app.title - object.lock = Ao_lock() def restore_gui(object): appuifw.app.body = object.old_gui @@ -101,19 +100,28 @@ def restore_gui(object): appuifw.app.exit_key_handler = object.old_exit_key_handler appuifw.app.title = object.old_title +class View(object): + def __init__(self): + self.title = None + self.view = None + self.lock = Ao_lock() + self.exit_flag = False + super(View, self).__init__() -class ListView(object): - def __init__(self,title): + def set_title(self, title): self.title = title - self.view = appuifw.Listbox(self.items(),self.change_entry) - - def change_entry(self): - pass - + + def set_view(self, view): + """ + Sets the main view to be displayed (e.g., an appuifw.Listbox + instance). + """ + self.view = view + def run(self): self.adjustment = None - appuifw.app.screen=COMMON_CONFIG['screen'].encode('utf-8') save_gui(self) + appuifw.app.screen=COMMON_CONFIG['screen'].encode('utf-8') appuifw.app.title=self.title appuifw.app.body=self.view appuifw.app.exit_key_handler=self.exit @@ -125,16 +133,47 @@ class ListView(object): except: pass restore_gui(self) + def exit(self): self.exit_flag = True self.lock.signal() def update(self,subject=None): - #logger.log(u'Updated %s'%repr(self)) + """ + Update the current view (e.g., make sure refresh is called). We + can't call it directly, since we're in another thread. + """ if self.lock: self.lock.signal() - #pass + def refresh(self): + """ + Called when the current view must be updated. Never call + directly. Subclasses should extend this method, not update. + """ + appuifw.app.menu=self.get_menu_entries() + + def get_menu_entries(self): + """ Returns a list of menu entries to display. Will be + automatically updated on each refresh. + + Each menu entry is a tuple of a title for the entry and a + function to call when the entry is selected. + """ + return [] + +class ListView(View): + def __init__(self): + super(ListView, self).__init__() + self.set_view(appuifw.Listbox(self.items(),self.entry_selected)) + + def entry_selected(self): + """ + This function is called when the user selects an an entry (e.g., + navigates to it and push the ok button). + """ + pass + def index_changed(self,adjustment=None): if adjustment: index = self.selected_index() + adjustment @@ -146,9 +185,6 @@ class ListView(object): index = 0 self.set_bindings_for_selection(index) - def refresh(self): - appuifw.app.menu=self.get_menu_entries() - def set_index(self,index): if index > len(self.widgets): index = len(self.widgets) @@ -159,12 +195,10 @@ class ListView(object): def selected_index(self): return self.view.current() - class WidgetBasedListView(ListView): - def __init__(self,title): + def __init__(self): self.widgets = self.generate_widgets() - super(WidgetBasedListView,self).__init__(title) - self.exit_flag = False + super(WidgetBasedListView,self).__init__() def run(self): self.refresh() @@ -190,9 +224,23 @@ class WidgetBasedListView(ListView): return self.widgets[self.selected_index()] -class KeyBindingView(object): +class KeyBindingView(View): - def __init__(self,binding_map): + def __init__(self): + self.binding_map = {} + super(KeyBindingView,self).__init__() + + def set_keybindings(self, binding_map): + """ + Set a new map of key bindings. This map maps method names to a + tuple of keyname and description. + + The method name refers to a method on the selected item, or the + current view. + + Example: { 'search_item' : ('0', 'Search item') } + + """ self.binding_map = binding_map def get_menu_entries(self): @@ -206,7 +254,8 @@ class KeyBindingView(object): description=' '+description menu_entries.append((description,function)) menu_entries.append((u'Exit', self.exit)) - return menu_entries + return menu_entries + super(KeyBindingView, self).get_menu_entries() + def set_bindings_for_selection(self,selected_index): self.remove_all_key_bindings() @@ -221,13 +270,26 @@ class KeyBindingView(object): self.view.bind(key,no_action) class SearchableListView(WidgetBasedListView): - def __init__(self,title,entry_filters): + def __init__(self): + self.current_entry_filter_index = -1 + self.entry_filters = [] + self.filtered_list = lambda:[] + self.lock = None + super(SearchableListView,self).__init__() + + def set_filters(self, entry_filters): + """ + Set the filters that could be applied to this list. Each filter + can be applied in turn by calling switch_entry_filter (for + example from a key binding). + + The entry_filters argument should be a list of filters. The + active filter is stored into self.filtered_list and should be + processed by generate_widgets in the subclass. + """ self.current_entry_filter_index = 0 self.entry_filters = entry_filters self.filtered_list = self.entry_filters[0] - self.lock = None - super(SearchableListView,self).__init__(title) - def search_item(self): selected_item = appuifw.selection_list(self.all_widget_texts(),search_field=1) @@ -235,6 +297,7 @@ class SearchableListView(WidgetBasedListView): selected_item = self.selected_index() self.view.set_list(self.items(),selected_item) self.set_bindings_for_selection(selected_item) + def switch_entry_filter(self): self.current_entry_filter_index += 1 self.filtered_list = self.entry_filters[self.current_entry_filter_index % len(self.entry_filters)] @@ -242,9 +305,8 @@ class SearchableListView(WidgetBasedListView): class EditableListView(SearchableListView,KeyBindingView): - def __init__(self,title,entry_filters,binding_map): - KeyBindingView.__init__(self,binding_map) - super(EditableListView, self).__init__(title,entry_filters) + def __init__(self): + super(EditableListView, self).__init__() def key_and_menu_bindings(self,selected_index): key_and_menu_bindings=[] @@ -255,7 +317,7 @@ class EditableListView(SearchableListView,KeyBindingView): key_and_menu_bindings.append((get_key(key),key,description,execute_and_update_function)) return key_and_menu_bindings - def change_entry(self): + def entry_selected(self): self.current_widget().change() self.refresh() def execute_and_update(self,function):