[PATCH 03/13] Create the base classes for TUI Hub and Spoke model

Martin Sivak msivak at redhat.com
Wed Aug 8 08:52:41 UTC 2012


---
 pyanaconda/ui/tui/__init__.py        |  116 ++++++++++++++++++++++++++++++++++
 pyanaconda/ui/tui/common/__init__.py |   26 ++++++++
 pyanaconda/ui/tui/hubs/__init__.py   |   47 ++++++++++++++
 pyanaconda/ui/tui/spokes/__init__.py |   36 +++++++++++
 4 files changed, 225 insertions(+)
 create mode 100644 pyanaconda/ui/tui/__init__.py
 create mode 100644 pyanaconda/ui/tui/common/__init__.py
 create mode 100644 pyanaconda/ui/tui/hubs/__init__.py
 create mode 100644 pyanaconda/ui/tui/spokes/__init__.py

diff --git a/pyanaconda/ui/tui/__init__.py b/pyanaconda/ui/tui/__init__.py
new file mode 100644
index 0000000..ba6f515
--- /dev/null
+++ b/pyanaconda/ui/tui/__init__.py
@@ -0,0 +1,116 @@
+from pyanaconda import ui
+import simpleline as tui
+
+from hubs.summary import SummaryHub
+from hubs.progress import ProgressHub
+from spokes import StandaloneSpoke
+
+class ErrorDialog(tui.UIScreen):
+    title = u"Error"
+
+    def __init__(self, data, message):
+        self._message = message
+
+    def refresh(self, args = None):
+        tui.UIScreen.refresh(self, args)
+        text = tui.TextWidget(self._message)
+        self.window.append(tui.CenterWidget(text))
+
+    def input(self, key):
+        self.close()
+
+class YesNoDialog(tui.UIScreen):
+    title = u"Question"
+
+    def __init__(self, data, message):
+        self._message = message
+        self._response = None
+
+    def refresh(self, args = None):
+        tui.UIScreen.refresh(self, args)
+        text = tui.TextWidget(self._message)
+        self.window.append(tui.CenterWidget(text))
+        self.window.append(u"")
+
+    def prompt(self):
+        return u"Please respond 'yes' or 'no': "
+
+    def input(self, key):
+        if key == "yes":
+            self._response = True
+            self.close()
+            return None
+
+        elif key == "no":
+            self._response = False
+            self.close()
+            return None
+
+        else:
+            return key
+
+class TextUserInterface(ui.UserInterface):
+
+    def __init__(self, storage, payload, instclass):
+        ui.UserInterface.__init__(self, storage, payload, instclass)
+        self._app = None
+        self._hubs = []
+
+    def setup(self, data):
+        """Construct all the objects required to implement this interface.
+           This method must be provided by all subclasses.
+        """
+        self._app = tui.App(u"Anaconda", yes_or_no_question = YesNoDialog)
+        self._hubs = []
+
+        # First, grab a list of all the standalone spokes.
+        path = os.path.join(os.path.dirname(__file__), "spokes")
+        actionClasses = self.getActionClasses("pyanaconda.ui.tui.spokes.%s", path, self._hubs, StandaloneSpoke)
+
+        for klass in actionClasses:
+            obj = klass(data, self.storage, self.payload, self.instclass)
+
+            # If we are doing a kickstart install, some standalone spokes
+            # could already be filled out.  In taht case, we do not want
+            # to display them.
+            if isinstance(obj, StandaloneSpoke) and obj.completed:
+                del(obj)
+                continue
+
+            self._app.schedule_window(obj)
+
+    def run(self):
+        """Run the interface.  This should do little more than just pass
+           through to something else's run method, but is provided here in
+           case more is needed.  This method must be provided by all subclasses.
+        """
+        self._app.run()
+
+    ###
+    ### MESSAGE HANDLING METHODS
+    ###
+    def showError(self, message):
+        """Display an error dialog with the given message.  After this dialog
+           is displayed, anaconda will quit.  There is no return value.  This
+           method must be implemented by all UserInterface subclasses.
+
+           In the code, this method should be used sparingly and only for
+           critical errors that anaconda cannot figure out how to recover from.
+        """
+        error_window = ErrorDialog(message)
+        self._app.switch_window(error_window)
+
+    def showYesNoQuestion(self, message):
+        """Display a dialog with the given message that presents the user a yes
+           or no choice.  This method returns True if the yes choice is selected,
+           and False if the no choice is selected.  From here, anaconda can
+           figure out what to do next.  This method must be implemented by all
+           UserInterface subclasses.
+
+           In the code, this method should be used sparingly and only for those
+           times where anaconda cannot make a reasonable decision.  We don't
+           want to overwhelm the user with choices.
+        """
+        question_window = YesNoDialog(message)
+        self._app.switch_window_modal(question_window)
+        return question_window.answer
diff --git a/pyanaconda/ui/tui/common/__init__.py b/pyanaconda/ui/tui/common/__init__.py
new file mode 100644
index 0000000..c616d9f
--- /dev/null
+++ b/pyanaconda/ui/tui/common/__init__.py
@@ -0,0 +1,26 @@
+from .. import simpleline as tui
+
+class UIObject(tui.UIScreen):
+    title = u"Default title"
+
+    def __init__(self, app, data):
+        tui.UIScreen.__init__(self, app, data)
+
+    @property
+    def showable(self):
+        return True
+
+    def teardown(self):
+        pass
+
+    def initialize(self):
+        pass
+
+    def refresh(self):
+        """Put everything to display into self.window list."""
+        pass
+
+    def retranslate(self):
+        # do retranslation stuff
+        # redraw
+        self.app.switch_screen(self)
diff --git a/pyanaconda/ui/tui/hubs/__init__.py b/pyanaconda/ui/tui/hubs/__init__.py
new file mode 100644
index 0000000..2cb081c
--- /dev/null
+++ b/pyanaconda/ui/tui/hubs/__init__.py
@@ -0,0 +1,47 @@
+from .. import simpleline as tui
+from .. import common
+
+class TUIHub(common.UIObject):
+    spokes = []
+    title = "Default HUB title"
+
+    def __init__(self, app, data):
+        tui.UIScreen.__init__(self, app, data)
+        self._spokes = {}
+        self._spoke_count = 0
+
+        for s in self.spokes:
+            spoke = s(app, data)
+            spoke.initialize()
+
+            if not spoke.showable:
+                spoke.teardown()
+                del spoke
+                continue
+
+            self._spoke_count += 1
+            self._spokes[self._spoke_count] = spoke
+
+    def refresh(self, args = None):
+        common.UIObject.refresh(self, args)
+
+        def _prep(i, w):
+            number = tui.TextWidget("%2d)" % i)
+            return tui.ColumnWidget([(3, [number]), (None, [w])], 1)
+
+        left = [_prep(i, w) for i,w in self._spokes.iteritems() if i % 2 == 1]
+        right = [_prep(i, w) for i,w in self._spokes.iteritems() if i % 2 == 0]
+
+        c = tui.ColumnWidget([(39, left), (39, right)], 2)
+        self._window.append(c)
+
+        return True
+
+    def input(self, key):
+        try:
+            number = int(key)
+            self.app.switch_screen_with_return(self._spokes[number])
+            return None
+
+        except (ValueError, KeyError):
+            return key
diff --git a/pyanaconda/ui/tui/spokes/__init__.py b/pyanaconda/ui/tui/spokes/__init__.py
new file mode 100644
index 0000000..8e6075a
--- /dev/null
+++ b/pyanaconda/ui/tui/spokes/__init__.py
@@ -0,0 +1,36 @@
+from .. import simpleline as tui
+from .. import common
+
+class TUISpoke(common.UIObject, tui.Widget):
+    title = u"Default spoke title"
+
+    def __init__(self, app, data):
+        common.UIObject.__init__(self, app, data)
+        tui.Widget.__init__(self)
+
+    @property
+    def status(self):
+        return "testing status..."
+
+    @property
+    def completed(self):
+        return True
+
+    def refresh(self, args = None):
+        common.UIObject.refresh(self, args)
+
+        return True
+
+    def input(self, key):
+        return key
+
+    def render(self, width):
+        tui.Widget.render(self, width)
+        c = tui.CheckboxWidget(completed = self.completed, title = self.title, text = self.status)
+        c.render(width)
+        self.draw(c)
+
+class StandaloneTUISpoke(TUISpoke):
+    preForHub = False
+    postForHub = False
+    title = "Standalone spoke title"
-- 
1.7.10.4



More information about the anaconda-patches mailing list