Преглед на файлове

make popups indicate if list is scrollable and improve pallete

Daniel Sheffield преди 3 години
родител
ревизия
5e4f2a0ee0
променени са 4 файла, в които са добавени 41 реда и са изтрити 8 реда
  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, '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([
                 urwid.Pile([
@@ -53,8 +53,8 @@ class NewProduct(urwid.Overlay):
         ), 'banner')
         super().__init__(urwid.AttrMap(body, 'bg'), under,
             align='center', width=('relative', 40),
-            valign='middle', height=('relative', 40),
-            min_width=20, min_height=12)
+            valign='middle', height=13,
+            min_width=20)
 
     @property
     def data(self):

+ 34 - 4
app/widgets.py

@@ -8,6 +8,7 @@ from decimal import Decimal
 from typing import Callable, Iterable, Union
 
 import urwid
+from additional_urwid_widgets import IndicativeListBox
 from urwid import numedit
 from urwid.wimp import PopUpLauncher
 
@@ -208,16 +209,40 @@ class FocusWidget(urwid.WidgetPlaceholder):
         self._set_focus_path(self.initial_focus)
 
 class AutoCompletePopUp(PopUpLauncher):
+    _default_pop_up_parameters = {
+        'left': 0,
+        'top': 1,
+        'overlay_width': 30,
+        'overlay_height': 15,
+    }
     def __init__(self,
         widget: Union[AutoCompleteEdit, AutoCompleteFloatEdit],
         apply_choice_cb: Callable[[str, str], None]
     ):
         super().__init__(widget)
+        self._pop_up_parameters = dict(**self._default_pop_up_parameters)
         self.apply_choice_cb = apply_choice_cb
         urwid.connect_signal(self._original_widget, 'open', lambda _, options: self._open_pop_up(options))
 
     def _open_pop_up(self, 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()
     
     def create_pop_up(self):
@@ -230,7 +255,7 @@ class AutoCompletePopUp(PopUpLauncher):
         return pop_up
 
     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):
     
@@ -247,10 +272,15 @@ class SuggestionPopup(urwid.WidgetWrap):
             button = urwid.Button(c)
             urwid.connect_signal(button, 'click', self.apply_cb, c)
             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)
-        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):
         if key == 'esc':

+ 3 - 1
grocery_transactions.py

@@ -41,6 +41,8 @@ except:
     from mock import *
 
 palette = [
+    ("popup_focus", "light red", "light gray"),
+    ('popup', 'light red', 'dark gray'),
     ('banner', 'light gray', 'dark red'),
     ('streak', 'light red', 'dark gray'),
     ('bg', 'light red', 'black'),
@@ -106,7 +108,7 @@ def _new_product_callback(
             txn.apply_changes,
             lambda product, category, group: _insert_new_product_callback(
                 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)
         )
     )

+ 1 - 0
requirements.txt

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