Răsfoiți Sursa

added UI but UI is not working

Daniel Sheffield 2 ani în urmă
părinte
comite
15b323141c
2 a modificat fișierele cu 165 adăugiri și 20 ștergeri
  1. 1 1
      app/activities/RecipeEditor.py
  2. 164 19
      app/activities/TransactionEditor.py

+ 1 - 1
app/activities/RecipeEditor.py

@@ -98,7 +98,7 @@ def unzip(iter: List[Tuple[AutoCompleteEdit, FloatEdit, AutoCompleteEdit]]) -> T
 ]:
     return zip(*iter)
 
-def extract_values(x: Union[List[AutoCompleteFloatEdit], List[FloatEdit]]) -> Iterable[str]:
+def extract_values(x: Union[List[AutoCompleteEdit], List[FloatEdit]]) -> Iterable[str]:
     if isinstance(x, list) or isinstance(x, tuple):
         if len(x) == 0:
             return []

+ 164 - 19
app/activities/TransactionEditor.py

@@ -9,13 +9,20 @@ from dateutil.parser import parse as parse_time
 from dateutil.parser._parser import ParserError
 from decimal import Decimal, InvalidOperation
 from itertools import chain
-from typing import Callable, Union
+from typing import (
+    Callable,
+    Union,
+    Tuple,
+    List,
+    Iterable,
+)
 from urwid import (
     connect_signal,
     AttrMap,
     Button,
     Columns,
     Divider,
+    Edit,
     Filler,
     LineBox,
     Padding,
@@ -37,6 +44,46 @@ from . import ActivityManager
 from .Rating import Rating
 from .NewProduct import NewProduct
 
+def to_numbered_field(x):
+    if len(x[0].split('#', 1)) > 1:
+        name, idx = x[0].split('#', 1)
+        idx = int(idx)
+    else:
+        name, idx = x[0], 0
+
+    return (name, int(idx)), x[1]
+
+def to_unnumbered_field(x):
+    return x[0][0], x[1]
+
+def in_same_row(name):
+    if len(name.split('#', 1)) > 1:
+        _, row = name.split('#', 1)
+    else:
+        row = 0
+    return lambda x: x[0][1] == int(row)
+
+def unzip(_iter: List[Tuple[AutoCompleteEdit, Edit]]) -> Tuple[
+    List[AutoCompleteEdit], List[Edit]
+]:
+    return zip(*_iter)
+
+def extract_values(x: Union[List[AutoCompleteEdit], List[Edit]]) -> Iterable[str]:
+    if isinstance(x, list) or isinstance(x, tuple):
+        if len(x) == 0:
+            return []
+        return ( v.get_edit_text() for v in x )
+    raise Exception(f"Unsupported type: {type(x)}")
+
+def to_named_value(name: str) -> Callable[[str], Tuple[str,str]]:
+    return lambda e: (f'{name}#{e[0]}', e[1])
+
+def blank_tags_row(idx: int) -> Tuple[AutoCompleteEdit, Edit]:
+    return (
+        AutoCompleteEdit(('bg', f'tags#{idx}')), Edit(('bg', f'descriptions#{idx}')),
+    )
+
+
 class TransactionEditor(FocusWidget):
 
     def keypress(self, size, key):
@@ -51,6 +98,8 @@ class TransactionEditor(FocusWidget):
         elif key == 'shift tab':
             self.advance_focus(reverse=True)
         elif key == 'ctrl delete':
+            print(self.data)
+            input()
             self.clear()
             self.focus_on(self.edit_fields['product'])
         elif key == 'insert':
@@ -62,12 +111,24 @@ class TransactionEditor(FocusWidget):
 
     def apply_choice(self, name, value):
         self.apply_changes(name, value)
-        for k,v in self.data.items():
-            if k == name or v:
+        data = dict(#filter(
+        #    in_same_row(name),
+            map(to_numbered_field, self.data.items())
+        )#)
+        for k,v in data.items():
+            if f'{k[0]}#{k[1]}' == name or v:
                 continue
-            options = self.query_manager.unique_suggestions(k, **self.data)
+
+            _data = dict(filter(
+                lambda x: x[0] not in ('tags','description'),
+                map(lambda x: (x[0][0], x[1]), data.items())
+            ))
+            print(_data)
+            input()
+            options = self.query_manager.unique_suggestions(k[0], **_data)
+
             if len(options) == 1 and k != 'ts':
-                self.apply_changes(k, list(options)[0])
+                self.apply_changes(f'{k[0]}#{k[1]}', list(options)[0])
 
     def apply_changes(self, name, value):
         self.data = {
@@ -80,7 +141,13 @@ class TransactionEditor(FocusWidget):
 
     @property
     def data(self):
+        zipped = zip(
+            ['tags',],
+            #['tags', 'descriptions'],
+            map(extract_values, unzip(self._tags)),
+        )
         ret = dict(itertools.chain(
+            *[ map(to_named_value(n), enumerate(l)) for n,l in zipped ],
             [(k, v.get_edit_text()) for k,v in self.edit_fields.items()],
             [(k, v.state) for k,v in self.checkboxes.items()]
         ))
@@ -93,8 +160,62 @@ class TransactionEditor(FocusWidget):
                 self.edit_fields[k].set_edit_text(v)
             if k in self.checkboxes and v != self.checkboxes[k].state:
                 self.checkboxes[k].set_state(v)
+            if len(k.split('#')) > 1:
+                name, idx = k.split('#', 1)
+                if name not in ['tags', 'descriptions']:
+                    continue
+                w = self._tags[int(idx)][ next(( pos for pos, n in zip(
+                    [0, 1],
+                    ['tags', 'descriptions']
+                ) if n == name ))]
+                w.set_edit_text(v)
+
+
+    def init_tags(self):
+        _tags = LineBox(Pile([tag[0]  for tag in self._tags]),
+            #AutoCompletePopUp(
+            #    tag[0],
+            #    self.apply_choice,
+            #    lambda: self.activity_manager.show(self.update())
+            #), 'streak') for tag in self._tags]),
+            title='Tags',
+            title_align='left'
+        )
+        gutter = Pile([
+            *[ Divider() for _ in itertools.product(
+                range(1), self._tags[:-1]
+            )],
+            Divider(),
+            Divider(),
+            self.buttons['add'],
+        ])
+        return _tags, gutter
+
+
+    def add_tag(self):
+        self._tags.append(
+            blank_tags_row(len(self._tags))
+        )
+        _tags, gutter = self.init_tags()
+        self.components['tags'].original_widget.contents = list(_tags.original_widget.contents)
+        self.components['gutter'][1].contents = list(gutter.contents)
+        for idx, widget in enumerate(self._tags):
+            connect_signal(widget[0], 'postchange', lambda w,_: self.update())
+            continue
+            connect_signal(widget[0], 'apply', lambda w, name: self.autocomplete_callback(
+                w, name, self.autocomplete_options(name, dict(map(
+                    to_unnumbered_field,
+                    #filter(
+                    #    in_same_row(name),
+                        map(to_numbered_field, self.data.items()
+                    #)
+                ))))
+            ))
+
 
     def clear(self):
+        self._tags = []
+        self.add_tag()
         for (k, ef) in self.edit_fields.items():
             if k in ('ts', 'store',):
                 continue
@@ -107,7 +228,7 @@ class TransactionEditor(FocusWidget):
         self.graph.set_data([],0)
         return self.update()
 
-    def update(self):
+    def update(self, w=None):
         data = self.data
         date, store = data['ts'], data['store']
         try:
@@ -223,11 +344,19 @@ class TransactionEditor(FocusWidget):
         activity_manager: ActivityManager,
         query_manager: QueryManager,
     ):
+        self.autocomplete_options = lambda name, data: self.query_manager.unique_suggestions(name.split('#', 1)[0], **data)
         self.activity_manager = activity_manager
         self.query_manager = query_manager
         self.buttons = {
             'done': Button(('streak', u'Done')),
             'clear': Button(('streak', u'Clear')),
+            'add': Button(('streak', 'Add')),
+        }
+        self._tags = []
+        _tags, gutter = self.init_tags()
+        self.components = {
+            'tags': _tags,
+            'gutter': gutter,
         }
         self.edit_fields = {
             'ts': AutoCompleteEdit(('bg', 'ts')),
@@ -295,7 +424,13 @@ class TransactionEditor(FocusWidget):
         for (k, ef) in self.edit_fields.items():
             connect_signal(ef, 'postchange', lambda *_: self.update())
             connect_signal(ef, 'apply', lambda w, name: self.autocomplete_callback(
-                w, name, query_manager.unique_suggestions(name, **self.data)
+                w, name, self.autocomplete_options(name, dict(map(
+                    to_unnumbered_field,
+                    #filter(
+                    #    in_same_row(name),
+                        map(to_numbered_field, self.data.items()
+                    #)
+                ))))
             ))
 
         _widgets.update(dict([
@@ -310,7 +445,7 @@ class TransactionEditor(FocusWidget):
         header = Text(u'Fill Transaction', 'center')
         _copyright = Text(COPYRIGHT, 'center')
 
-        components = {
+        self.components.update({
             'bottom_button_bar': Columns(
                 [(8, self.buttons['done']), Divider(), (9, self.buttons['clear'])]
             ),
@@ -318,16 +453,20 @@ class TransactionEditor(FocusWidget):
                 lambda x: _widgets[x] if x is not None else Divider,
                 badge
             )),
-        }
-        components.update({
+        })
+        self.components.update({
             'bottom_pane': Columns([
                 Pile(map(
                     lambda x: _widgets[x] if x is not None else Divider(),
                     bottom_pane
                 )),
+                #(17, Columns([
+                    #(10,self.components['tags']),
+                    #(7,self.components['gutter']),
+                #])),
                 (self.graph.total_width+2, Pile([
                     LineBox(
-                        AttrMap(components['badge'], 'badge'),
+                        AttrMap(self.components['badge'], 'badge'),
                         title="Current Price", title_align='left',
                     ),
                     LineBox(
@@ -339,6 +478,7 @@ class TransactionEditor(FocusWidget):
         })
         connect_signal(self.buttons['done'], 'click', lambda _: self.save_and_clear_callback())
         connect_signal(self.buttons['clear'], 'click', lambda _: self.clear())
+        connect_signal(self.buttons['add'], 'click', lambda _: self.add_tag())
 
         banner = Pile([
             Padding(header, 'center', width=('relative', 100)),
@@ -356,10 +496,10 @@ class TransactionEditor(FocusWidget):
             ], dividechars=2), title='Product', title_align='left')
         })
 
-        components['side_pane'] = (12, Pile([
+        self.components['side_pane'] = (12, Pile([
             _widgets[r] if r is not None else Divider() for r in side_pane
         ]))
-        components['main_pane'] = []
+        self.components['main_pane'] = []
         for _, r in enumerate(layout):
             col = []
             for c in r:
@@ -369,24 +509,28 @@ class TransactionEditor(FocusWidget):
                     col.append(_widgets[c])
                 else:
                     col.append(Divider())
-            components['main_pane'].append(Columns(col))
+            self.components['main_pane'].append(Columns(col))
 
-        components['main_pane'] = Pile(components['main_pane'])
+        self.components['main_pane'] = Pile(self.components['main_pane'])
 
         widget = Pile([
             banner,
             Divider(),
             Columns([
-                components['main_pane'], components['side_pane']
+                self.components['main_pane'],
+                self.components['side_pane'],
+                (12,self.components['tags']),
+                (8,self.components['gutter']),
             ], dividechars=2),
-            components['bottom_pane'],
+            self.components['bottom_pane'],
             Divider(),
-            components['bottom_button_bar']
+            self.components['bottom_button_bar']
         ])
         widget = Filler(widget, 'top')
         widget = AttrMap(widget, 'bg')
         super().__init__(widget, map(
             lambda x: next(w[1] for w in chain(
+                [('tags', self._tags[-1][0]),],
                 self.buttons.items(),
                 self.edit_fields.items(),
                 self.checkboxes.items()
@@ -394,8 +538,9 @@ class TransactionEditor(FocusWidget):
             [
                 'product', 'organic',
                 'unit', 'quantity', 'price',
-                'description',
+                'description', 'tags',# 'add',
                 'done', 'clear',
                 'category', 'group',
                 'ts', 'store'
             ]))
+        self.update()