changeset 151:082868bea873

Refactor UI so that only a single gui.App is used. Pass all UI events via main_app. Change Toolbar table to use .td() everywhere. Move toolbar to top.
author Simon Cross <hodgestar@gmail.com>
date Thu, 03 Sep 2009 20:32:56 +0000
parents 89d2360d4350
children 702bc0eb2ac3
files gamelib/engine.py gamelib/gameboard.py gamelib/gameover.py gamelib/main.py gamelib/mainmenu.py
diffstat 5 files changed, 66 insertions(+), 64 deletions(-) [+]
line wrap: on
line diff
--- a/gamelib/engine.py	Thu Sep 03 20:24:37 2009 +0000
+++ b/gamelib/engine.py	Thu Sep 03 20:32:56 2009 +0000
@@ -14,21 +14,33 @@
     def __init__(self, main_app):
         self.main_app = main_app
         self.clock = pygame.time.Clock()
+        self.main_menu = mainmenu.make_main_menu()
+        self._open_window = None
 
     def tick(self):
         """Tic toc."""
         pygame.time.wait(10)
 
+    def open_window(self, window):
+        """Open a widget as the main window."""
+        if self._open_window is not None:
+            self.main_app.close(self._open_window)
+        self.main_app.open(window)
+        self._open_window = window
+
     def create_game_board(self):
-        self.gameboard = gameboard.GameBoard()
+        """Create and open a gameboard window."""
+        self.gameboard = gameboard.GameBoard(self.main_app)
+        self.open_window(self.gameboard.get_top_widget())
 
     def set_main_menu(self):
-        """Create the main menu"""
-        mainmenu.add_main_menu(self.main_app)
+        """Open the main menu"""
+        self.open_window(self.main_menu)
 
-    def generate_score(self):
-        """Create the Game Over state"""
-        gameover.add_game_over(self.main_app, self.gameboard)
+    def create_game_over(self):
+        """Create and open the Game Over window"""
+        game_over = gameover.create_game_over(self.gameboard)
+        self.open_window(game_over)
 
 class MainMenuState(State):
     def init(self):
@@ -74,20 +86,21 @@
         if events_equal(e, START_NIGHT):
             return NightState(self.game)
         elif e.type is KEYDOWN and e.key == K_ESCAPE:
-            return MainMenuState(self.game)
+            return GameOver(self.game)
         elif e.type is KEYDOWN and e.key == K_n:
             return pygame.event.post(START_NIGHT)
         elif events_equal(e, GO_MAIN_MENU):
             return MainMenuState(self.game)
         elif e.type is not QUIT:
-            self.game.gameboard.event(e)
+            self.game.main_app.event(e)
 
     def paint(self, screen):
-        self.game.gameboard.paint(screen)
+        self.game.main_app.paint(screen)
         pygame.display.flip()
 
     def update(self, screen):
-        update = self.game.gameboard.update(screen)
+        self.game.gameboard.update()
+        update = self.game.main_app.update(screen)
         pygame.display.update(update)
 
     def loop(self):
@@ -116,7 +129,7 @@
         elif e.type is KEYDOWN and e.key == K_d:
             return pygame.event.post(START_DAY)
         elif e.type is KEYDOWN and e.key == K_ESCAPE:
-            return MainMenuState(self.game)
+            return GameOver(self.game)
         elif e.type is MOVE_FOX_ID:
             self.cycle_count += 1
             if self.cycle_count > constants.NIGHT_LENGTH:
@@ -125,23 +138,24 @@
                 # All foxes are gone/safe, so dawn happens
                 return pygame.event.post(START_DAY)
         elif e.type is not QUIT:
-            self.game.gameboard.event(e)
+            self.game.main_app.event(e)
 
     def loop(self):
         self.game.gameboard.loop()
 
     def paint(self, screen):
-        self.game.gameboard.paint(screen)
+        self.game.main_app.paint(screen)
         pygame.display.flip()
 
     def update(self, screen):
-        update = self.game.gameboard.update(screen)
+        self.game.gameboard.update()
+        update = self.game.main_app.update(screen)
         pygame.display.update(update)
 
 class GameOver(State):
     def init(self):
         """Setup everything"""
-        self.game.generate_score()
+        self.game.create_game_over()
         pygame.time.set_timer(MOVE_FOX_ID, 0)
 
     def event(self, e):
--- a/gamelib/gameboard.py	Thu Sep 03 20:24:37 2009 +0000
+++ b/gamelib/gameboard.py	Thu Sep 03 20:32:56 2009 +0000
@@ -48,6 +48,7 @@
         self.add_counter(mklabel("Eggs:"), self.egg_counter)
         self.add_counter(icons.CHKN_ICON, self.chicken_counter)
         self.add_counter(icons.KILLED_FOX, self.killed_foxes)
+        self.add_spacer()
 
         self.add_tool_button("Move Animals", constants.TOOL_PLACE_ANIMALS)
         self.add_tool_button("Sell chicken", constants.TOOL_SELL_CHICKEN)
@@ -60,6 +61,7 @@
         for equipment_cls in equipment.EQUIPMENT:
             self.add_tool_button("Buy %s" % (equipment_cls.NAME,), equipment_cls)
         self.add_spacer()
+
         self.add_button("Finished Day", self.day_done)
 
     def day_done(self):
@@ -74,31 +76,28 @@
 
     def add_spacer(self, height=30):
         self.tr()
-        self.add(gui.Spacer(0, height))
+        self.td(gui.Spacer(0, height), colspan=2)
 
     def add_tool_button(self, text, tool):
         self.add_button(text, lambda: self.gameboard.set_selected_tool(tool))
 
     def add_button(self, text, func):
-        button = gui.Button(text)
+        button = gui.Button(text, width=self.rect.w)
         button.connect(gui.CLICK, func)
         self.tr()
-        self.add(button, colspan=2)
+        self.td(button, align=-1, colspan=2)
 
     def add_counter(self, icon, label):
         self.tr()
-        if icon:
-            self.td(icon, align=-1, width=self.rect.w/2)
-        self.add(label)
+        self.td(icon, align=-1, width=self.rect.w/2)
+        self.td(label, align=-1, width=self.rect.w/2)
 
 class VidWidget(gui.Widget):
     def __init__(self, gameboard, vid, **params):
         gui.Widget.__init__(self, **params)
         self.gameboard = gameboard
-        vid.bounds = pygame.Rect((0, 0), vid.tile_to_view(vid.size))
         self.vid = vid
-        self.width = params.get('width', 0)
-        self.height = params.get('height', 0)
+        self.vid.bounds = pygame.Rect((0, 0), vid.tile_to_view(vid.size))
 
     def paint(self, surface):
         self.vid.paint(surface)
@@ -106,13 +105,6 @@
     def update(self, surface):
         return self.vid.update(surface)
 
-    def resize(self, width=0, height=0):
-        if width is not None:
-            self.width = width
-        if height is not None:
-            self.height = height
-        return self.width, self.height
-
     def move_view(self, x, y):
         self.vid.view.move_ip((x, y))
 
@@ -130,12 +122,13 @@
     WOODLAND = tiles.REVERSE_TILE_MAP['woodland']
     BROKEN_FENCE = tiles.REVERSE_TILE_MAP['broken fence']
 
-    def __init__(self):
+    def __init__(self, main_app):
+        self.disp = main_app
         self.tv = tiles.FarmVid()
         self.tv.tga_load_tiles(data.filepath('tiles.tga'), self.TILE_DIMENSIONS)
         self.tv.png_folder_load_tiles(data.filepath('tiles'))
         self.tv.tga_load_level(data.filepath('level1.tga'))
-        self.create_disp()
+        self.create_display()
 
         self.selected_tool = None
         self.animal_to_place = None
@@ -152,24 +145,21 @@
 
         self.add_some_chickens()
 
-    def create_disp(self):
-        width, height = pygame.display.get_surface().get_size()
+    def get_top_widget(self):
+        return self.top_widget
+
+    def create_display(self):
+        width, height = self.disp.rect.w, self.disp.rect.h
         tbl = gui.Table()
         tbl.tr()
-        self.toolbar = ToolBar(self)
-        tbl.td(self.toolbar, width=self.TOOLBAR_WIDTH)
-        self.tvw = VidWidget(self, self.tv, width=width-self.TOOLBAR_WIDTH, height=height)
+        self.toolbar = ToolBar(self, width=self.TOOLBAR_WIDTH)
+        tbl.td(self.toolbar, valign=-1)
+        self.tvw = VidWidget(self, self.tv, width=width-self.TOOLBAR_WIDTH-19, height=height)
         tbl.td(self.tvw)
-        self.disp = gui.App()
-        self.disp.init(tbl)
+        self.top_widget = tbl
 
-    def paint(self, screen):
-        screen.fill(constants.BG_COLOR)
-        self.disp.paint(screen)
-
-    def update(self, screen):
+    def update(self):
         self.tvw.reupdate()
-        return self.disp.update(screen)
 
     def loop(self):
         self.tv.loop()
--- a/gamelib/gameover.py	Thu Sep 03 20:24:37 2009 +0000
+++ b/gamelib/gameover.py	Thu Sep 03 20:32:56 2009 +0000
@@ -7,16 +7,14 @@
 import constants
 import imagecache
 
-def add_game_over(app, gameboard):
-    """Add the game over menu to the app"""
-    for widget in app.widgets[:]:
-        app.remove(widget)
+def create_game_over(gameboard):
+    """Create a game over screen"""
     game_over = GameOver(gameboard)
 
     c = GameOverContainer(align=0, valign=0)
     c.add(game_over, 0, 0)
 
-    app.init(c)
+    return c
 
 class GameOverContainer(gui.Container):
     def paint(self, s):
--- a/gamelib/main.py	Thu Sep 03 20:24:37 2009 +0000
+++ b/gamelib/main.py	Thu Sep 03 20:32:56 2009 +0000
@@ -10,23 +10,26 @@
 from pgu import gui
 from pygame.locals import SWSURFACE
 
-from mainmenu import MenuContainer, MainMenu
-from engine import Engine, MainMenuState
+#from engine import Engine, MainMenuState
 from sound import init_sound
 import constants
 
-
-
-def create_app():
-    """Create the app."""
+def create_main_app(screen):
+    """Create an app with a background widget."""
     app = gui.App()
+    background = pygame.Surface(screen.get_size())
+    widget = gui.Image(background)
+    app.init(widget, screen)
     return app
 
 def main():
     """Main script."""
     init_sound()
     screen = pygame.display.set_mode(constants.SCREEN, SWSURFACE)
-    main_app = create_app()
+    main_app = create_main_app(screen)
+
+    from engine import Engine, MainMenuState
+
     engine = Engine(main_app)
     try:
         engine.run(MainMenuState(engine), screen)
--- a/gamelib/mainmenu.py	Thu Sep 03 20:24:37 2009 +0000
+++ b/gamelib/mainmenu.py	Thu Sep 03 20:32:56 2009 +0000
@@ -6,17 +6,14 @@
 import engine
 import imagecache
 
-def add_main_menu(app):
-    """Add the main menu to the app"""
-    for widget in app.widgets[:]:
-        app.remove(widget)
-
+def make_main_menu():
+    """Create a main menu"""
     main_menu = MainMenu()
 
     c = MenuContainer(align=0, valign=0)
     c.add(main_menu, 0, 0)
 
-    app.init(c)
+    return c
 
 class MenuContainer(gui.Container):
     def paint(self, s):