Browse Source

make popups indicate if list is scrollable and improve pallete

Daniel Sheffield 3 years ago
parent
commit
5e4f2a0ee0
4 changed files with 41 additions and 8 deletions
  1. 3 3
      app/activities/NewProduct.py
  2. 34 4
      app/widgets.py
  3. 3 1
      grocery_transactions.py
  4. 1 0
      requirements.txt

+ 3 - 3
app/activities/NewProduct.py

@@ -33,7 +33,7 @@ class NewProduct(urwid.Overlay):
             urwid.connect_signal(w, 'change', lambda w, v: change_cb(w.name, v))
             urwid.connect_signal(w, 'change', lambda w, v: change_cb(w.name, v))
             urwid.connect_signal(w, 'apply', lambda w, name: autocomplete_cb(w, name, self.data))
             urwid.connect_signal(w, 'apply', lambda w, name: autocomplete_cb(w, name, self.data))
 
 
-        ok = urwid.Button('Done', on_press=lambda w: apply_cb(**self.data))
+        ok = urwid.Button('Done', on_press=lambda _: apply_cb(**self.data))
 
 
         body = urwid.AttrMap(urwid.ListBox(urwid.SimpleListWalker([
         body = urwid.AttrMap(urwid.ListBox(urwid.SimpleListWalker([
                 urwid.Pile([
                 urwid.Pile([
@@ -53,8 +53,8 @@ class NewProduct(urwid.Overlay):
         ), 'banner')
         ), 'banner')
         super().__init__(urwid.AttrMap(body, 'bg'), under,
         super().__init__(urwid.AttrMap(body, 'bg'), under,
             align='center', width=('relative', 40),
             align='center', width=('relative', 40),
-            valign='middle', height=('relative', 40),
-            min_width=20, min_height=12)
+            valign='middle', height=13,
+            min_width=20)
 
 
     @property
     @property
     def data(self):
     def data(self):

+ 34 - 4
app/widgets.py

@@ -8,6 +8,7 @@ from decimal import Decimal
 from typing import Callable, Iterable, Union
 from typing import Callable, Iterable, Union
 
 
 import urwid
 import urwid
+from additional_urwid_widgets import IndicativeListBox
 from urwid import numedit
 from urwid import numedit
 from urwid.wimp import PopUpLauncher
 from urwid.wimp import PopUpLauncher
 
 
@@ -208,16 +209,40 @@ class FocusWidget(urwid.WidgetPlaceholder):
         self._set_focus_path(self.initial_focus)
         self._set_focus_path(self.initial_focus)
 
 
 class AutoCompletePopUp(PopUpLauncher):
 class AutoCompletePopUp(PopUpLauncher):
+    _default_pop_up_parameters = {
+        'left': 0,
+        'top': 1,
+        'overlay_width': 30,
+        'overlay_height': 15,
+    }
     def __init__(self,
     def __init__(self,
         widget: Union[AutoCompleteEdit, AutoCompleteFloatEdit],
         widget: Union[AutoCompleteEdit, AutoCompleteFloatEdit],
         apply_choice_cb: Callable[[str, str], None]
         apply_choice_cb: Callable[[str, str], None]
     ):
     ):
         super().__init__(widget)
         super().__init__(widget)
+        self._pop_up_parameters = dict(**self._default_pop_up_parameters)
         self.apply_choice_cb = apply_choice_cb
         self.apply_choice_cb = apply_choice_cb
         urwid.connect_signal(self._original_widget, 'open', lambda _, options: self._open_pop_up(options))
         urwid.connect_signal(self._original_widget, 'open', lambda _, options: self._open_pop_up(options))
 
 
     def _open_pop_up(self, options):
     def _open_pop_up(self, options):
         self.options = options
         self.options = options
+        max_height = self._default_pop_up_parameters['overlay_height']
+        height = min(
+            len(options),
+            self._default_pop_up_parameters['overlay_height'],
+        )
+        if 0 < len(options) - height < max_height//3:
+            height = 4 * max_height // 6
+        
+        self._pop_up_parameters = dict(**self._default_pop_up_parameters)
+        self._pop_up_parameters.update({
+            'overlay_width': max(
+                self._original_widget._cache_maxcol,
+                self._default_pop_up_parameters['overlay_width'],
+            ),
+            # account for header and footer rows
+            'overlay_height': height+2,
+        })
         self.open_pop_up()
         self.open_pop_up()
     
     
     def create_pop_up(self):
     def create_pop_up(self):
@@ -230,7 +255,7 @@ class AutoCompletePopUp(PopUpLauncher):
         return pop_up
         return pop_up
 
 
     def get_pop_up_parameters(self):
     def get_pop_up_parameters(self):
-        return {'left':0, 'top':1, 'overlay_width':32, 'overlay_height': 10}
+        return self._pop_up_parameters
 
 
 class SuggestionPopup(urwid.WidgetWrap):
 class SuggestionPopup(urwid.WidgetWrap):
     
     
@@ -247,10 +272,15 @@ class SuggestionPopup(urwid.WidgetWrap):
             button = urwid.Button(c)
             button = urwid.Button(c)
             urwid.connect_signal(button, 'click', self.apply_cb, c)
             urwid.connect_signal(button, 'click', self.apply_cb, c)
             urwid.connect_signal(button, 'click', lambda _: self._emit("close"))
             urwid.connect_signal(button, 'click', lambda _: self._emit("close"))
-            body.append(urwid.AttrMap(button, None, focus_map='reversed'))
+            body.append(urwid.AttrMap(button, None, focus_map='popup_focus'))
         walker = urwid.SimpleFocusListWalker(body, wrap_around=False)
         walker = urwid.SimpleFocusListWalker(body, wrap_around=False)
-        listbox = urwid.ListBox(walker)
-        super().__init__(urwid.AttrWrap(listbox, 'banner'))
+        super().__init__(urwid.AttrWrap(IndicativeListBox(walker,
+            topBar_endExposed_prop=("───", None, None),
+            topBar_endCovered_prop=("▲ {} more ▲", None, None),
+            bottomBar_endCovered_prop=("▼ {} more ▼", None, None),
+            bottomBar_endExposed_prop=(f"─── {len(options)} ───", None, None),
+        ), 'popup'))
+            
         
         
     def keypress(self, size, key):
     def keypress(self, size, key):
         if key == 'esc':
         if key == 'esc':

+ 3 - 1
grocery_transactions.py

@@ -41,6 +41,8 @@ except:
     from mock import *
     from mock import *
 
 
 palette = [
 palette = [
+    ("popup_focus", "light red", "light gray"),
+    ('popup', 'light red', 'dark gray'),
     ('banner', 'light gray', 'dark red'),
     ('banner', 'light gray', 'dark red'),
     ('streak', 'light red', 'dark gray'),
     ('streak', 'light red', 'dark gray'),
     ('bg', 'light red', 'black'),
     ('bg', 'light red', 'black'),
@@ -106,7 +108,7 @@ def _new_product_callback(
             txn.apply_changes,
             txn.apply_changes,
             lambda product, category, group: _insert_new_product_callback(
             lambda product, category, group: _insert_new_product_callback(
                 activity_manager, query_manager, product, category, group),
                 activity_manager, query_manager, product, category, group),
-            lambda: activity_manager.show(cur),
+            lambda: activity_manager.show(cur.update()),
             lambda name, value: _apply_choice_callback(activity_manager, 'new_product', name, value)
             lambda name, value: _apply_choice_callback(activity_manager, 'new_product', name, value)
         )
         )
     )
     )

+ 1 - 0
requirements.txt

@@ -1,4 +1,5 @@
 #debian package libatlas3-base required on raspberrypi
 #debian package libatlas3-base required on raspberrypi
+additional-urwid-widgets
 urwid
 urwid
 psycopg2
 psycopg2
 faker
 faker