From 9e40dcbad6c53bdb0ef404caea1d40e8b49045e5 Mon Sep 17 00:00:00 2001 From: Michael Hudson-Doyle Date: Thu, 15 Aug 2019 16:11:09 +1200 Subject: [PATCH] Make the outermost widget an instance of Pile rather than Frame Current plans involve putting a focusable widget (a help button) in the footer, and Pile's behaviour is much more what we want than Frame for this. --- console_conf/controllers/identity.py | 2 +- subiquity/controllers/filesystem.py | 14 ++++++------ subiquity/controllers/ssh.py | 8 +++---- subiquitycore/controllers/network.py | 12 +++++------ subiquitycore/ui/frame.py | 32 +++++++++++++++++----------- 5 files changed, 38 insertions(+), 30 deletions(-) diff --git a/console_conf/controllers/identity.py b/console_conf/controllers/identity.py index f2d82c86..128c7e8b 100644 --- a/console_conf/controllers/identity.py +++ b/console_conf/controllers/identity.py @@ -227,7 +227,7 @@ class IdentityController(BaseController): ["snap", "create-user", "--sudoer", "--json", email]) self.ui.set_footer("") if cp.returncode != 0: - self.ui.frame.body.error.set_text( + self.ui.body.error.set_text( "Creating user failed:\n" + cp.stderr) return else: diff --git a/subiquity/controllers/filesystem.py b/subiquity/controllers/filesystem.py index 528b0de2..99a15d01 100644 --- a/subiquity/controllers/filesystem.py +++ b/subiquity/controllers/filesystem.py @@ -194,11 +194,11 @@ class FilesystemController(BaseController): if 'obj' in action: obj = self._action_get(action['obj']) meth = getattr( - self.ui.frame.body.avail_list, + self.ui.body.avail_list, "_{}_{}".format(obj.type, action['action'])) meth(obj) yield - body = self.ui.frame.body._w + body = self.ui.body._w if not isinstance(body, StretchyOverlay): return if isinstance(body.stretchy, ConfirmDeleteStretchy): @@ -210,25 +210,25 @@ class FilesystemController(BaseController): action['data'], action.get("submit", True)) elif action['action'] == 'create-raid': - self.ui.frame.body.create_raid() + self.ui.body.create_raid() yield - body = self.ui.frame.body._w + body = self.ui.body._w yield from self._enter_form_data( body.stretchy.form, action['data'], action.get("submit", True), clean_suffix='raid') elif action['action'] == 'create-vg': - self.ui.frame.body.create_vg() + self.ui.body.create_vg() yield - body = self.ui.frame.body._w + body = self.ui.body._w yield from self._enter_form_data( body.stretchy.form, action['data'], action.get("submit", True), clean_suffix='vg') elif action['action'] == 'done': - if not self.ui.frame.body.done.enabled: + if not self.ui.body.done.enabled: raise Exception("answers did not provide complete fs config") self.finish() else: diff --git a/subiquity/controllers/ssh.py b/subiquity/controllers/ssh.py index f1c3f194..a4f42d44 100644 --- a/subiquity/controllers/ssh.py +++ b/subiquity/controllers/ssh.py @@ -89,18 +89,18 @@ class SSHController(BaseController): return user_spec, ssh_import_id, key_material, fingerprints def _fetched_ssh_keys(self, fut): - if not isinstance(self.ui.frame.body, SSHView): + if not isinstance(self.ui.body, SSHView): # This can happen if curtin failed while the keys where being # fetched and we jump to the log view. log.debug( "view is now an instance of %s, not SSHView", - type(self.ui.frame.body)) + type(self.ui.body)) return try: result = fut.result() except FetchSSHKeysFailure as e: log.debug("fetching ssh keys failed %s", e) - self.ui.frame.body.fetching_ssh_keys_failed(e.message, e.output) + self.ui.body.fetching_ssh_keys_failed(e.message, e.output) else: log.debug("_fetched_ssh_keys %s", result) if result is None: @@ -112,7 +112,7 @@ class SSHController(BaseController): self.loop.set_alarm_in(0.0, lambda loop, ud: self.done(user_spec)) else: - self.ui.frame.body.confirm_ssh_keys( + self.ui.body.confirm_ssh_keys( user_spec, ssh_import_id, key_material, fingerprints) def fetch_ssh_keys(self, user_spec, ssh_import_id): diff --git a/subiquitycore/controllers/network.py b/subiquitycore/controllers/network.py index 82dbb4d4..bcaa2fab 100644 --- a/subiquitycore/controllers/network.py +++ b/subiquitycore/controllers/network.py @@ -236,7 +236,7 @@ class NetworkController(BaseController): self.loop.set_alarm_in(0.1, lambda loop, ud: self.start_watching()) return self.observer.data_ready(fd) - v = self.ui.frame.body + v = self.ui.body if hasattr(v, 'refresh_model_inputs'): v.refresh_model_inputs() @@ -281,11 +281,11 @@ class NetworkController(BaseController): if 'obj' in action: obj = self._action_get(action['obj']) meth = getattr( - self.ui.frame.body, + self.ui.body, "_action_{}".format(action['action'])) meth(obj) yield - body = self.ui.frame.body._w + body = self.ui.body._w if not isinstance(body, StretchyOverlay): return for k, v in action.items(): @@ -302,15 +302,15 @@ class NetworkController(BaseController): v, action.get(submit_key, True)) elif action['action'] == 'create-bond': - self.ui.frame.body._create_bond() + self.ui.body._create_bond() yield - body = self.ui.frame.body._w + body = self.ui.body._w yield from self._enter_form_data( body.stretchy.form, action['data'], action.get("submit", True)) elif action['action'] == 'done': - self.ui.frame.body.done() + self.ui.body.done() else: raise Exception("could not process action {}".format(action)) diff --git a/subiquitycore/ui/frame.py b/subiquitycore/ui/frame.py index 4568091d..b691a2a7 100644 --- a/subiquitycore/ui/frame.py +++ b/subiquitycore/ui/frame.py @@ -15,17 +15,18 @@ """ Base Frame Widget """ +import logging + from urwid import ( - Frame, Text, ) from subiquitycore.ui.anchors import Header, Footer from subiquitycore.ui.container import ( ListBox, + Pile, WidgetWrap, ) from subiquitycore.ui.utils import Color -import logging log = logging.getLogger('subiquitycore.ui.frame') @@ -36,28 +37,35 @@ class SubiquityUI(WidgetWrap): def __init__(self): self.header = Header("") self.footer = Footer("", 0, 1) - self.frame = Frame( - ListBox([Text("")]), - header=self.header, footer=self.footer) self.progress_current = 0 self.progress_completion = 0 # After the install starts, we want to stop setting the footer # from the body view. self.auto_footer = True - super().__init__(Color.body(self.frame)) + self.pile = Pile([ + ('pack', self.header), + ListBox([Text("")]), + ('pack', self.footer), + ]) + super().__init__(Color.body(self.pile)) - def keypress(self, size, key): - return super().keypress(size, key) + def _assign_contents(self, i, w): + self.pile.contents[i] = (w, self.pile.contents[i][1]) def set_header(self, title=None): - self.frame.header = Header(title) + self._assign_contents(0, Header(title)) def set_footer(self, message): - self.frame.footer = Footer(message, self.progress_current, - self.progress_completion) + self._assign_contents( + 2, + Footer(message, self.progress_current, self.progress_completion)) + + @property + def body(self): + return self.pile.contents[1][0] def set_body(self, widget): self.set_header(_(widget.title)) - self.frame.body = widget + self._assign_contents(1, widget) if self.auto_footer: self.set_footer(_(widget.footer))