From 35988f2fd9df5f464266629a358082115c86171e Mon Sep 17 00:00:00 2001 From: Michael Hudson-Doyle Date: Thu, 5 Oct 2017 15:05:45 +1300 Subject: [PATCH] change form machinery to always have space for validation error and display help, if present, there by default --- subiquity/ui/views/filesystem/partition.py | 2 +- subiquitycore/ui/form.py | 46 +++++++++++----------- subiquitycore/ui/interactive.py | 28 ------------- 3 files changed, 24 insertions(+), 52 deletions(-) diff --git a/subiquity/ui/views/filesystem/partition.py b/subiquity/ui/views/filesystem/partition.py index b45396c6..ccaa5fb2 100644 --- a/subiquity/ui/views/filesystem/partition.py +++ b/subiquity/ui/views/filesystem/partition.py @@ -84,7 +84,7 @@ class PartitionForm(Form): self.size.widget.value = val sz = dehumanize_size(val) if sz > self.max_size: - self.size.show_extra(Color.info_minor(Text("Capped partition size at %s"%(self.size_str,), align="center"))) + self.size.show_extra(('info_minor', "Capped partition size at %s"%(self.size_str,))) self.size.widget.value = self.size_str return self.max_size return sz diff --git a/subiquitycore/ui/form.py b/subiquitycore/ui/form.py index 436a88b4..7a3d9cc1 100644 --- a/subiquitycore/ui/form.py +++ b/subiquitycore/ui/form.py @@ -29,7 +29,6 @@ from urwid import ( from subiquitycore.ui.buttons import cancel_btn, done_btn from subiquitycore.ui.container import Columns, Pile from subiquitycore.ui.interactive import ( - Help, PasswordEditor, IntegerEditor, StringEditor, @@ -134,28 +133,25 @@ class BoundFormField(object): return validator() def validate(self): - self.hide_extra() + # cleaning/validation can call show_extra to add an + # informative message. We record this by having show_extra to + # set showing_extra so we don't immediately replace this + # message with the widget's help in the case that validation + # succeeds. + self.showing_extra = False r = self._validate() if r is None: self.in_error = False + if not self.showing_extra: + self.help_text.set_text(self.help) else: self.in_error = True - extra = Color.info_error(Text(r, align="center")) - self.show_extra(extra) + self.show_extra(('info_error', r)) self.form.validated() - def hide_extra(self): - if self.showing_extra: - del self.pile.contents[1] - self.showing_extra = False - - def show_extra(self, extra): - t = (extra, self.pile.options('pack')) - if self.showing_extra: - self.pile.contents[1] = t - else: - self.pile.contents[1:1] = [t] + def show_extra(self, extra_markup): self.showing_extra = True + self.help_text.set_text(extra_markup) @property def value(self): @@ -169,12 +165,16 @@ class BoundFormField(object): def help(self): if self._help is not None: return self._help - else: + elif self.field.help is not None: return self.field.help + else: + return "" @help.setter def help(self, val): self._help = val + if self.pile is not None: + self.pile[1].set_text(val) @property def caption(self): @@ -193,14 +193,9 @@ class BoundFormField(object): input = Color.string_input(_Validator(self, self.widget)) else: input = self.widget - if self.help is not None: - help = Help(self.parent_view, self.help) - else: - help = Text("") cols = [ (self._longest_caption, text), - input, - (3, help), + input ] cols = Columns(cols, dividechars=2) if self._enabled: @@ -213,7 +208,12 @@ class BoundFormField(object): raise RuntimeError("do not call as_row more than once!") self.parent_view = view self._longest_caption = longest_caption - self.pile = Pile([self._cols()]) + self.help_text = Text(self.help, align="center") + cols = [ + (self._longest_caption, Text("")), + self.help_text, + ] + self.pile = Pile([self._cols(), Columns(cols, dividechars=2)]) return self.pile @property diff --git a/subiquitycore/ui/interactive.py b/subiquitycore/ui/interactive.py index 5c6e5b19..e1a64139 100644 --- a/subiquitycore/ui/interactive.py +++ b/subiquitycore/ui/interactive.py @@ -21,19 +21,12 @@ import logging import re from urwid import ( - ACTIVATE, Edit, IntEdit, - LineBox, - SelectableIcon, - Text, WidgetWrap, ) -from subiquitycore.ui.buttons import close_btn -from subiquitycore.ui.container import Pile from subiquitycore.ui.selector import Selector -from subiquitycore.ui.utils import Color, Padding, button_pile log = logging.getLogger("subiquitycore.ui.input") @@ -113,24 +106,3 @@ class YesNo(Selector): def __init__(self): opts = [_('Yes'), _('No')] super().__init__(opts) - - -class _HelpDisplay(WidgetWrap): - def __init__(self, closer, help_text): - self._closer = closer - buttons = [close_btn(on_press=lambda btn:self._closer())] - super().__init__(LineBox(Pile([Text(help_text), button_pile(buttons)]), title=_("Help"))) - - -class Help(WidgetWrap): - - def __init__(self, view, help_text): - self._view = view - self._help_text = help_text - self._button = Padding.fixed_3(Color.button(SelectableIcon("[?]", 1))) - super().__init__(self._button) - - def keypress(self, size, key): - if self._command_map[key] != ACTIVATE: - return key - self._view.show_overlay(_HelpDisplay(self._view.remove_overlay, self._help_text))