[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