summaryrefslogtreecommitdiff
path: root/poezio/windows/data_forms.py
diff options
context:
space:
mode:
Diffstat (limited to 'poezio/windows/data_forms.py')
-rw-r--r--poezio/windows/data_forms.py159
1 files changed, 98 insertions, 61 deletions
diff --git a/poezio/windows/data_forms.py b/poezio/windows/data_forms.py
index a14418d7..c600273e 100644
--- a/poezio/windows/data_forms.py
+++ b/poezio/windows/data_forms.py
@@ -12,12 +12,14 @@ from poezio.windows.inputs import Input
from poezio.theming import to_curses_attr, get_theme
+
class FieldInput(object):
"""
All input types in a data form should inherit this class,
in addition with windows.Input or any relevant class from the
'windows' library.
"""
+
def __init__(self, field):
self._field = field
self.color = get_theme().COLOR_NORMAL_TEXT
@@ -25,7 +27,6 @@ class FieldInput(object):
def update_field_value(self, value):
raise NotImplementedError
-
def is_dummy(self):
return False
@@ -42,8 +43,10 @@ class FieldInput(object):
"""
return ''
+
class FieldInputMixin(FieldInput, Win):
"Mix both FieldInput and Win"
+
def __init__(self, field):
FieldInput.__init__(self, field)
Win.__init__(self)
@@ -81,6 +84,7 @@ class DummyInput(FieldInputMixin):
"""
Used for fields that do not require any input ('fixed')
"""
+
def __init__(self, field):
FieldInputMixin.__init__(self, field)
@@ -93,6 +97,7 @@ class DummyInput(FieldInputMixin):
def is_dummy(self):
return True
+
class BooleanWin(FieldInputMixin):
def __init__(self, field):
FieldInputMixin.__init__(self, field)
@@ -108,8 +113,8 @@ class BooleanWin(FieldInputMixin):
def refresh(self):
self._win.erase()
self._win.attron(to_curses_attr(self.color))
- self.addnstr(0, 0, ' '*(8), self.width)
- self.addstr(0, 2, "%s"%self.value)
+ self.addnstr(0, 0, ' ' * (8), self.width)
+ self.addstr(0, 2, "%s" % self.value)
self.addstr(0, 8, '→')
self.addstr(0, 0, '←')
if self.last_key == 'KEY_RIGHT':
@@ -126,6 +131,7 @@ class BooleanWin(FieldInputMixin):
def get_help_message(self):
return '← and →: change the value between True and False'
+
class TextMultiWin(FieldInputMixin):
def __init__(self, field):
FieldInputMixin.__init__(self, field)
@@ -149,20 +155,22 @@ class TextMultiWin(FieldInputMixin):
if self.val_pos > 0:
self.val_pos -= 1
elif key == 'KEY_RIGHT':
- if self.val_pos < len(self.options)-1:
+ if self.val_pos < len(self.options) - 1:
self.val_pos += 1
elif key == '^M':
self.edition_input = Input()
self.edition_input.color = self.color
- self.edition_input.resize(self.height, self.width, self.y, self.x)
+ self.edition_input.resize(self.height, self.width, self.y,
+ self.x)
self.edition_input.text = self.options[self.val_pos]
self.edition_input.key_end()
else:
if key == '^M':
self.options[self.val_pos] = self.edition_input.get_text()
- if not self.options[self.val_pos] and self.val_pos != len(self.options) -1:
+ if not self.options[self.val_pos] and self.val_pos != len(
+ self.options) - 1:
del self.options[self.val_pos]
- if self.val_pos == len(self.options) -1:
+ if self.val_pos == len(self.options) - 1:
self.val_pos -= 1
self.edition_input = None
if not self.options or self.options[-1] != '':
@@ -175,13 +183,13 @@ class TextMultiWin(FieldInputMixin):
if not self.edition_input:
self._win.erase()
self._win.attron(to_curses_attr(self.color))
- self.addnstr(0, 0, ' '*self.width, self.width)
+ self.addnstr(0, 0, ' ' * self.width, self.width)
option = self.options[self.val_pos]
- self.addstr(0, self.width//2-len(option)//2, option)
+ self.addstr(0, self.width // 2 - len(option) // 2, option)
if self.val_pos > 0:
self.addstr(0, 0, '←')
- if self.val_pos < len(self.options)-1:
- self.addstr(0, self.width-1, '→')
+ if self.val_pos < len(self.options) - 1:
+ self.addstr(0, self.width - 1, '→')
self._win.attroff(to_curses_attr(self.color))
self._refresh()
else:
@@ -194,7 +202,7 @@ class TextMultiWin(FieldInputMixin):
def get_help_message(self):
if not self.edition_input:
help_msg = '← and →: browse the available entries. '
- if self.val_pos == len(self.options)-1:
+ if self.val_pos == len(self.options) - 1:
help_msg += 'Enter: add an entry'
else:
help_msg += 'Enter: edit this entry'
@@ -202,6 +210,7 @@ class TextMultiWin(FieldInputMixin):
help_msg = 'Enter: finish editing this entry.'
return help_msg
+
class ListMultiWin(FieldInputMixin):
def __init__(self, field):
FieldInputMixin.__init__(self, field)
@@ -215,7 +224,7 @@ class ListMultiWin(FieldInputMixin):
if self.val_pos > 0:
self.val_pos -= 1
elif key == 'KEY_RIGHT':
- if self.val_pos < len(self.options)-1:
+ if self.val_pos < len(self.options) - 1:
self.val_pos += 1
elif key == ' ':
self.options[self.val_pos][1] = not self.options[self.val_pos][1]
@@ -226,14 +235,15 @@ class ListMultiWin(FieldInputMixin):
def refresh(self):
self._win.erase()
self._win.attron(to_curses_attr(self.color))
- self.addnstr(0, 0, ' '*self.width, self.width)
+ self.addnstr(0, 0, ' ' * self.width, self.width)
if self.val_pos > 0:
self.addstr(0, 0, '←')
- if self.val_pos < len(self.options)-1:
- self.addstr(0, self.width-1, '→')
+ if self.val_pos < len(self.options) - 1:
+ self.addstr(0, self.width - 1, '→')
if self.options:
option = self.options[self.val_pos]
- self.addstr(0, self.width//2-len(option)//2, option[0]['label'])
+ self.addstr(0, self.width // 2 - len(option) // 2,
+ option[0]['label'])
self.addstr(0, 2, '✔' if option[1] else '☐')
self._win.attroff(to_curses_attr(self.color))
self._refresh()
@@ -241,12 +251,15 @@ class ListMultiWin(FieldInputMixin):
def reply(self):
self._field['label'] = ''
self._field.delOptions()
- values = [option[0]['value'] for option in self.options if option[1] is True]
+ values = [
+ option[0]['value'] for option in self.options if option[1] is True
+ ]
self._field.set_answer(values)
def get_help_message(self):
return '←, →: Switch between the value. Space: select or unselect a value'
+
class ListSingleWin(FieldInputMixin):
def __init__(self, field):
FieldInputMixin.__init__(self, field)
@@ -263,7 +276,7 @@ class ListSingleWin(FieldInputMixin):
if self.val_pos > 0:
self.val_pos -= 1
elif key == 'KEY_RIGHT':
- if self.val_pos < len(self.options)-1:
+ if self.val_pos < len(self.options) - 1:
self.val_pos += 1
else:
return
@@ -272,14 +285,14 @@ class ListSingleWin(FieldInputMixin):
def refresh(self):
self._win.erase()
self._win.attron(to_curses_attr(self.color))
- self.addnstr(0, 0, ' '*self.width, self.width)
+ self.addnstr(0, 0, ' ' * self.width, self.width)
if self.val_pos > 0:
self.addstr(0, 0, '←')
- if self.val_pos < len(self.options)-1:
- self.addstr(0, self.width-1, '→')
+ if self.val_pos < len(self.options) - 1:
+ self.addstr(0, self.width - 1, '→')
if self.options:
option = self.options[self.val_pos]['label']
- self.addstr(0, self.width//2-len(option)//2, option)
+ self.addstr(0, self.width // 2 - len(option) // 2, option)
self._win.attroff(to_curses_attr(self.color))
self._refresh()
@@ -291,6 +304,7 @@ class ListSingleWin(FieldInputMixin):
def get_help_message(self):
return '←, →: Select a value amongst the others'
+
class TextSingleWin(FieldInputMixin, Input):
def __init__(self, field):
FieldInputMixin.__init__(self, field)
@@ -307,6 +321,7 @@ class TextSingleWin(FieldInputMixin, Input):
def get_help_message(self):
return 'Edit the text'
+
class TextPrivateWin(TextSingleWin):
def __init__(self, field):
TextSingleWin.__init__(self, field)
@@ -315,11 +330,12 @@ class TextPrivateWin(TextSingleWin):
self._win.erase()
if self.color:
self._win.attron(to_curses_attr(self.color))
- self.addstr('*'*len(self.text[self.view_pos:self.view_pos+self.width-1]))
+ self.addstr(
+ '*' * len(self.text[self.view_pos:self.view_pos + self.width - 1]))
if self.color:
(y, x) = self._win.getyx()
- size = self.width-x
- self.addnstr(' '*size, size, to_curses_attr(self.color))
+ size = self.width - x
+ self.addnstr(' ' * size, size, to_curses_attr(self.color))
self.addstr(0, self.pos, '')
if self.color:
self._win.attroff(to_curses_attr(self.color))
@@ -328,6 +344,7 @@ class TextPrivateWin(TextSingleWin):
def get_help_message(self):
return 'Edit the secret text'
+
class FormWin(object):
"""
A window, with some subwins (the various inputs).
@@ -335,22 +352,24 @@ class FormWin(object):
On resize, move and resize all the subwin and define how the text will be written
On refresh, write all the text, and refresh all the subwins
"""
- input_classes = {'boolean': BooleanWin,
- 'fixed': DummyInput,
- 'jid-multi': TextMultiWin,
- 'jid-single': TextSingleWin,
- 'list-multi': ListMultiWin,
- 'list-single': ListSingleWin,
- 'text-multi': TextMultiWin,
- 'text-private': TextPrivateWin,
- 'text-single': TextSingleWin,
- }
+ input_classes = {
+ 'boolean': BooleanWin,
+ 'fixed': DummyInput,
+ 'jid-multi': TextMultiWin,
+ 'jid-single': TextSingleWin,
+ 'list-multi': ListMultiWin,
+ 'list-single': ListSingleWin,
+ 'text-multi': TextMultiWin,
+ 'text-private': TextPrivateWin,
+ 'text-single': TextSingleWin,
+ }
+
def __init__(self, form, height, width, y, x):
self._form = form
self._win = base_wins.TAB_WIN.derwin(height, width, y, x)
self.scroll_pos = 0
self.current_input = 0
- self.inputs = [] # dict list
+ self.inputs = [] # dict list
for (name, field) in self._form.getFields().items():
if field['type'] == 'hidden':
continue
@@ -363,9 +382,11 @@ class FormWin(object):
if field['type'] == 'fixed':
label = field.get_value()
inp = input_class(field)
- self.inputs.append({'label':ColoredLabel(label),
- 'description': desc,
- 'input':inp})
+ self.inputs.append({
+ 'label': ColoredLabel(label),
+ 'description': desc,
+ 'input': inp
+ })
def resize(self, height, width, y, x):
self.height = height
@@ -373,7 +394,7 @@ class FormWin(object):
self._win = base_wins.TAB_WIN.derwin(height, width, y, x)
# Adjust the scroll position, if resizing made the window too small
# for the cursor to be visible
- while self.current_input - self.scroll_pos > self.height-1:
+ while self.current_input - self.scroll_pos > self.height - 1:
self.scroll_pos += 1
def reply(self):
@@ -394,13 +415,17 @@ class FormWin(object):
return
if self.current_input == len(self.inputs) - 1:
return
- self.inputs[self.current_input]['input'].set_color(get_theme().COLOR_NORMAL_TEXT)
- self.inputs[self.current_input]['label'].set_color(get_theme().COLOR_NORMAL_TEXT)
+ self.inputs[self.current_input]['input'].set_color(
+ get_theme().COLOR_NORMAL_TEXT)
+ self.inputs[self.current_input]['label'].set_color(
+ get_theme().COLOR_NORMAL_TEXT)
self.current_input += 1
jump = 0
- while self.current_input+jump != len(self.inputs) - 1 and self.inputs[self.current_input+jump]['input'].is_dummy():
+ while self.current_input + jump != len(
+ self.inputs) - 1 and self.inputs[self.current_input
+ + jump]['input'].is_dummy():
jump += 1
- if self.inputs[self.current_input+jump]['input'].is_dummy():
+ if self.inputs[self.current_input + jump]['input'].is_dummy():
return
self.current_input += jump
# If moving made the current input out of the visible screen, we
@@ -408,24 +433,31 @@ class FormWin(object):
# call refresh() if this is not the case, because
# refresh_current_input() is always called anyway, so this is not
# needed
- if self.current_input - self.scroll_pos > self.height-1:
+ if self.current_input - self.scroll_pos > self.height - 1:
self.scroll_pos += 1
self.refresh()
- self.inputs[self.current_input]['input'].set_color(get_theme().COLOR_SELECTED_ROW)
- self.inputs[self.current_input]['label'].set_color(get_theme().COLOR_SELECTED_ROW)
+ self.inputs[self.current_input]['input'].set_color(
+ get_theme().COLOR_SELECTED_ROW)
+ self.inputs[self.current_input]['label'].set_color(
+ get_theme().COLOR_SELECTED_ROW)
def go_to_previous_input(self):
if not self.inputs:
return
if self.current_input == 0:
return
- self.inputs[self.current_input]['input'].set_color(get_theme().COLOR_NORMAL_TEXT)
- self.inputs[self.current_input]['label'].set_color(get_theme().COLOR_NORMAL_TEXT)
+ self.inputs[self.current_input]['input'].set_color(
+ get_theme().COLOR_NORMAL_TEXT)
+ self.inputs[self.current_input]['label'].set_color(
+ get_theme().COLOR_NORMAL_TEXT)
self.current_input -= 1
jump = 0
- while self.current_input-jump > 0 and self.inputs[self.current_input+jump]['input'].is_dummy():
+ while self.current_input - jump > 0 and self.inputs[self.current_input
+ +
+ jump]['input'].is_dummy(
+ ):
jump += 1
- if self.inputs[self.current_input+jump]['input'].is_dummy():
+ if self.inputs[self.current_input + jump]['input'].is_dummy():
return
# Adjust the scroll position if the current_input would be outside
# of the visible area
@@ -433,8 +465,10 @@ class FormWin(object):
self.scroll_pos = self.current_input
self.refresh()
self.current_input -= jump
- self.inputs[self.current_input]['input'].set_color(get_theme().COLOR_SELECTED_ROW)
- self.inputs[self.current_input]['label'].set_color(get_theme().COLOR_SELECTED_ROW)
+ self.inputs[self.current_input]['input'].set_color(
+ get_theme().COLOR_SELECTED_ROW)
+ self.inputs[self.current_input]['label'].set_color(
+ get_theme().COLOR_SELECTED_ROW)
def on_input(self, key, raw=False):
if not self.inputs:
@@ -448,8 +482,9 @@ class FormWin(object):
for name, field in self._form.getFields().items():
if field['type'] == 'hidden':
continue
- self.inputs[i]['label'].resize(1, self.width//2, y + 1, 0)
- self.inputs[i]['input'].resize(1, self.width//2, y+1, self.width//2)
+ self.inputs[i]['label'].resize(1, self.width // 2, y + 1, 0)
+ self.inputs[i]['input'].resize(1, self.width // 2, y + 1,
+ self.width // 2)
# TODO: display the field description
y += 1
i += 1
@@ -462,17 +497,19 @@ class FormWin(object):
inp['label'].refresh()
inp['input'].refresh()
inp['label'].refresh()
- if self.inputs and self.current_input < self.height-1:
- self.inputs[self.current_input]['input'].set_color(get_theme().COLOR_SELECTED_ROW)
+ if self.inputs and self.current_input < self.height - 1:
+ self.inputs[self.current_input]['input'].set_color(
+ get_theme().COLOR_SELECTED_ROW)
self.inputs[self.current_input]['input'].refresh()
- self.inputs[self.current_input]['label'].set_color(get_theme().COLOR_SELECTED_ROW)
+ self.inputs[self.current_input]['label'].set_color(
+ get_theme().COLOR_SELECTED_ROW)
self.inputs[self.current_input]['label'].refresh()
def refresh_current_input(self):
self.inputs[self.current_input]['input'].refresh()
def get_help_message(self):
- if self.inputs and self.current_input < self.height-1 and self.inputs[self.current_input]['input']:
+ if self.inputs and self.current_input < self.height - 1 and self.inputs[self.
+ current_input]['input']:
return self.inputs[self.current_input]['input'].get_help_message()
return ''
-