Redo the refreshing in Views, it is now more consistent.
authorMatthijs Kooijman <matthijs@stdin.nl>
Tue, 3 Nov 2009 14:54:18 +0000 (15:54 +0100)
committerMatthijs Kooijman <matthijs@stdin.nl>
Tue, 3 Nov 2009 14:54:42 +0000 (15:54 +0100)
View.refresh is the main method to do a complete refresh, subclasses
extend this method to call their own refresh_foo to refresh different
parts.

src/gui/gui.py

index 3d4e6fb9e605627ad789dcbe7ce00b4398c88b35..9f0175e66ed7761a17e4f25bc405ecaba5e41494 100644 (file)
@@ -137,7 +137,6 @@ class View(object):
         appuifw.app.body=self.view
         appuifw.app.exit_key_handler=self.exit
         try:
-            self.lock.wait()
             while not self.exit_flag:
                 self.refresh()
                 self.lock.wait()
@@ -164,7 +163,7 @@ class View(object):
         Called when the current view must be updated. Never call
         directly. Subclasses should extend this method, not update.
         """
-        pass
+        self.refresh_menu()
 
     def refresh_menu(self):
         """
@@ -205,7 +204,8 @@ class ListView(View):
     def __init__(self):
         super(ListView, self).__init__()
         self.current_index = None
-        self.set_view(appuifw.Listbox(self.items(),self.entry_selected))
+        self.items_cache = []
+        self.set_view(appuifw.Listbox([], self.entry_selected))
         self.view.bind(EKeyUpArrow,lambda: self.arrow_key_pressed(-1))
         self.view.bind(EKeyDownArrow,lambda: self.arrow_key_pressed(1))
 
@@ -223,6 +223,27 @@ class ListView(View):
         self.index_changed()
         self.current_index = None
 
+    def refresh(self):
+        self.refresh_list()
+        super(ListView, self).refresh()
+    
+    def refresh_list(self):
+        """ Reload the list items. Calls items() again. """
+        # Remember which item was selected
+        selected = self.selected_item()
+        # Refresh the list
+        self.items_cache = self.items()
+        try:
+            # Try to find the selected item in the new list (based on
+            # the display text).
+            selected_index = self.items_cache.index(selected)
+        except ValueError:
+            # If the selected item is no longer present, just keep the
+            # index the same (but be careful not to fall off the end).
+            selected_index = self.clip_index(self.selected_index())
+        # Update the items in the view
+        self.view.set_list(self.items_cache, selected_index)
+
     def run(self):
         self.index_changed()
         super(ListView, self).run()
@@ -249,7 +270,7 @@ class ListView(View):
 
     def set_index(self,index):
         """ Changes the currently selected item to index. """
-        self.view.set_list(self.items(),index % len(self.items()))
+        self.view.set_list(self.items_cache, self.clip_index(index))
 
     def selected_item(self):
         """ Returns the (title of the) currently selected list item. """
@@ -303,16 +324,19 @@ class WidgetBasedListView(ListView):
         self.refresh()
 
     def refresh(self):
-        self.widgets = self.generate_widgets()
-        self.redisplay_widgets()
+        self.refresh_widgets()
         super(WidgetBasedListView,self).refresh()
+    
+    def refresh_widgets(self):
+        """ Refresh the widget list. Calls generate_widgets(). """
+        self.widgets = self.generate_widgets()
 
     def redisplay_widgets(self):
         """
         Redisplay the widgets. Should be called if the widgets
         themselves have changed, does not call generate_widgets again.
         """
-        self.set_index(self.selected_index())
+        self.refresh_list()
 
     def items(self):
         # Let ListView show each widget's text.