more work on routing controllers
Signed-off-by: Adam Stokes <adam.stokes@ubuntu.com>
This commit is contained in:
parent
dcb0337fdc
commit
c780386ceb
|
@ -20,6 +20,7 @@ import urwid
|
|||
import urwid.curses_display
|
||||
from subiquity.palette import STYLES, STYLES_MONO
|
||||
from subiquity.controllers.welcome import WelcomeController
|
||||
from subiquity.app import Application
|
||||
|
||||
|
||||
def parse_options(argv):
|
||||
|
@ -44,11 +45,7 @@ def main():
|
|||
screen.set_terminal_properties(256)
|
||||
screen.register_palette(STYLES)
|
||||
|
||||
def unhandled_input(key):
|
||||
if key in ('Q', 'q', 'esc'):
|
||||
raise urwid.ExitMainLoop()
|
||||
urwid.MainLoop(WelcomeController().show(), screen=screen,
|
||||
unhandled_input=unhandled_input).run()
|
||||
Application(screen, opts).start()
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
|
|
|
@ -0,0 +1,71 @@
|
|||
# Copyright 2015 Canonical, Ltd.
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Affero General Public License as
|
||||
# published by the Free Software Foundation, either version 3 of the
|
||||
# License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU Affero General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Affero General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
""" Application entry point """
|
||||
|
||||
import urwid
|
||||
from subiquity.routes import Routes
|
||||
|
||||
|
||||
class ApplicationError(Exception):
|
||||
""" Exception in Application Class """
|
||||
pass
|
||||
|
||||
|
||||
class Application:
|
||||
def __init__(self, screen, opts):
|
||||
self.screen = screen
|
||||
self.opts = opts
|
||||
self.initial_controller = Routes.first()
|
||||
|
||||
# Setup eventloop
|
||||
self.loop = self._build_loop()
|
||||
self.loop.set_alarm_in(2, self.update)
|
||||
|
||||
def _build_loop(self):
|
||||
""" Builds urwid eventloop, passing in itself to the controllers
|
||||
for further display manipulation
|
||||
"""
|
||||
return urwid.MainLoop(self.initial_controller(routes=Routes,
|
||||
application=self).show(),
|
||||
screen=self.screen,
|
||||
unhandled_input=self.unhandled_input)
|
||||
|
||||
def unhandled_input(self, key):
|
||||
if key in ('Q', 'q', 'esc'):
|
||||
raise urwid.ExitMainLoop()
|
||||
if key in ('r', 'R'):
|
||||
self.redraw_screen()
|
||||
|
||||
def redraw_screen(self):
|
||||
try:
|
||||
self.loop.draw_screen()
|
||||
except AssertionError as e:
|
||||
# self.log.exception("exception failure in redraw_screen")
|
||||
raise e
|
||||
|
||||
def set_alarm_in(self, interval, cb):
|
||||
self.loop.set_alarm_in(interval, cb)
|
||||
|
||||
def update(self, *args, **kwds):
|
||||
if self.loop is not None:
|
||||
self.redraw_screen()
|
||||
self.set_alarm_in(1, self.update)
|
||||
|
||||
def start(self):
|
||||
try:
|
||||
self.loop.run()
|
||||
except:
|
||||
raise ApplicationError("Exception in loop.run()")
|
|
@ -16,9 +16,21 @@
|
|||
from abc import ABCMeta, abstractmethod
|
||||
|
||||
|
||||
class BaseControllerError(Exception):
|
||||
""" Basecontroller exception """
|
||||
pass
|
||||
|
||||
|
||||
class BaseController(metaclass=ABCMeta):
|
||||
controller_name = None
|
||||
|
||||
def __init__(self, routes, application):
|
||||
""" Basecontroller
|
||||
:param :class:`subiquity.app.Application` application: App class
|
||||
"""
|
||||
self.application = application
|
||||
self.routes = routes
|
||||
|
||||
@classmethod
|
||||
def name(cls):
|
||||
if cls.controller_name:
|
||||
|
@ -41,3 +53,15 @@ class BaseController(metaclass=ABCMeta):
|
|||
to move to the next controller or end the install.
|
||||
"""
|
||||
pass
|
||||
|
||||
def next_controller(self, *args, **kwds):
|
||||
next_controller = self.routes.next()
|
||||
next_controller(routes=self.routes,
|
||||
application=self.application).show(*args, **kwds)
|
||||
self.application.redraw_screen()
|
||||
|
||||
def prev_controller(self, *args, **kwds):
|
||||
prev_controller = self.routes.prev()
|
||||
prev_controller(routes=self.routes,
|
||||
application=self.application).show(*args, **kwds)
|
||||
self.application.redraw_screen()
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
# You should have received a copy of the GNU Affero General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
from subiquity.controllers import BaseController
|
||||
from subiquity.controllers import BaseController, BaseControllerError
|
||||
from subiquity.views.installpath import InstallpathView
|
||||
from subiquity.models.installpath import InstallpathModel
|
||||
|
||||
|
@ -28,8 +28,9 @@ class InstallpathController(BaseController):
|
|||
|
||||
def finish(self, install_selection=None):
|
||||
if install_selection is None:
|
||||
self.prev_controller("WelcomeController")
|
||||
raise BaseControllerError("No install selection found")
|
||||
else:
|
||||
raise SystemExit("Install selection: {}".format(install_selection))
|
||||
raise BaseControllerError(
|
||||
"Install selection: {}".format(install_selection))
|
||||
|
||||
__controller_class__ = InstallpathController
|
||||
|
|
|
@ -32,7 +32,7 @@ class WelcomeController(BaseController):
|
|||
raise SystemExit("No language selected, exiting as there are no "
|
||||
"more previous controllers to render.")
|
||||
self.selected_language = language
|
||||
subprocess.check_call("/usr/local/bin/curtin_wrap.sh")
|
||||
return
|
||||
# subprocess.check_call("/usr/local/bin/curtin_wrap.sh")
|
||||
self.next_controller()
|
||||
|
||||
__controller_class__ = WelcomeController
|
||||
|
|
|
@ -0,0 +1,72 @@
|
|||
# Copyright 2015 Canonical, Ltd.
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Affero General Public License as
|
||||
# published by the Free Software Foundation, either version 3 of the
|
||||
# License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU Affero General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Affero General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
from subiquity.controllers.welcome import WelcomeController
|
||||
from subiquity.controllers.installpath import InstallpathController
|
||||
|
||||
|
||||
class RoutesError(Exception):
|
||||
""" Error in routes """
|
||||
pass
|
||||
|
||||
|
||||
class Routes:
|
||||
""" Defines application routes and maps to their controller
|
||||
|
||||
Routes are inserted top down from start to finish. Maintaining
|
||||
this order is required for routing to work.
|
||||
"""
|
||||
routes = [WelcomeController,
|
||||
InstallpathController]
|
||||
current_route_idx = 0
|
||||
|
||||
@classmethod
|
||||
def route(cls, idx):
|
||||
""" Include route listing in controllers """
|
||||
try:
|
||||
_route = cls.routes[idx]
|
||||
except IndexError:
|
||||
raise RoutesError("Failed to load Route at index: {}".format(idx))
|
||||
return _route
|
||||
|
||||
@classmethod
|
||||
def first(cls):
|
||||
""" first controller/start of install """
|
||||
return cls.route(0)
|
||||
|
||||
@classmethod
|
||||
def last(cls):
|
||||
""" end of install, last controller """
|
||||
return cls.route(-1)
|
||||
|
||||
@classmethod
|
||||
def go_to_beginning(cls):
|
||||
cls.current_route_idx = 0
|
||||
return cls.route(0)
|
||||
|
||||
@classmethod
|
||||
def go_to_end(cls):
|
||||
cls.current_route_idx = len(cls.routes) - 1
|
||||
return cls.route(-1)
|
||||
|
||||
@classmethod
|
||||
def next(cls):
|
||||
cls.current_route_idx = cls.current_route_idx + 1
|
||||
return cls.route(cls.current_route_idx)
|
||||
|
||||
@classmethod
|
||||
def prev(cls):
|
||||
cls.current_route_idx = cls.current_route_idx - 1
|
||||
return cls.route(cls.current_route_idx)
|
|
@ -30,8 +30,8 @@ class Header(WidgetWrap):
|
|||
excerpt = ""
|
||||
|
||||
def __init__(self):
|
||||
title_widget = Padding.push_10(Color.body(Text(self.title)))
|
||||
excerpt_widget = Padding.push_10(Color.body(Text(self.excerpt)))
|
||||
title_widget = Padding.center_79(Color.body(Text(self.title)))
|
||||
excerpt_widget = Padding.center_79(Color.body(Text(self.excerpt)))
|
||||
pile = Pile([Text(""),
|
||||
title_widget,
|
||||
Text(""),
|
||||
|
@ -51,7 +51,7 @@ class Footer(WidgetWrap):
|
|||
|
||||
def __init__(self):
|
||||
border = Text("")
|
||||
message_widget = Padding.push_10(Color.body(Text(self.message)))
|
||||
message_widget = Padding.center_79(Color.body(Text(self.message)))
|
||||
status = Pile([border, message_widget])
|
||||
super().__init__(status)
|
||||
|
||||
|
@ -59,8 +59,9 @@ class Footer(WidgetWrap):
|
|||
class Body(WidgetWrap):
|
||||
""" Body widget
|
||||
"""
|
||||
|
||||
body = Pile([Text("Welcome to the Ubuntu Server Installation",
|
||||
align="center")])
|
||||
|
||||
def __init__(self):
|
||||
self.text = [
|
||||
Text("Welcome to the Ubuntu Server Installation", align="center")
|
||||
]
|
||||
super().__init__(Pile(self.text))
|
||||
super().__init__(self.body)
|
||||
|
|
|
@ -19,9 +19,9 @@ from urwid import Frame, WidgetWrap
|
|||
from subiquity.ui.anchors import Header, Footer, Body
|
||||
|
||||
|
||||
class BaseFrame(WidgetWrap):
|
||||
class SubiquityUI(WidgetWrap):
|
||||
def __init__(self):
|
||||
_frame = Frame(Body(),
|
||||
Header(),
|
||||
Footer())
|
||||
super().__init__(_frame)
|
||||
self.frame = Frame(Body(),
|
||||
Header(),
|
||||
Footer())
|
||||
super().__init__(self._frame)
|
||||
|
|
|
@ -32,13 +32,13 @@ class InstallpathView(WidgetWrap):
|
|||
self.model = model
|
||||
self.cb = cb
|
||||
self.items = []
|
||||
self.layout = [
|
||||
self.body = [
|
||||
Header(),
|
||||
Padding.center_79(self._build_model_inputs()),
|
||||
Padding.pull_50(self._build_buttons()),
|
||||
Padding.center_20(self._build_buttons()),
|
||||
Footer()
|
||||
]
|
||||
super().__init__(ListBox(self.layout))
|
||||
super().__init__(ListBox(self.body))
|
||||
|
||||
def _build_buttons(self):
|
||||
self.buttons = [
|
||||
|
|
|
@ -29,13 +29,13 @@ class WelcomeView(WidgetWrap):
|
|||
self.model = model
|
||||
self.cb = cb
|
||||
self.items = []
|
||||
self.layout = [
|
||||
self.body = [
|
||||
Header(),
|
||||
Padding.center_79(self._build_model_inputs()),
|
||||
Padding.center_20(self._build_buttons()),
|
||||
Footer()
|
||||
]
|
||||
super().__init__(ListBox(self.layout))
|
||||
super().__init__(ListBox(self.body))
|
||||
|
||||
def _build_buttons(self):
|
||||
self.buttons = [
|
||||
|
|
Loading…
Reference in New Issue