changeset 433:8643893635e7

Seperate toolbar and gameboard
author Neil Muller <drnlmuller@gmail.com>
date Sat, 21 Nov 2009 16:59:49 +0000
parents d630465d7a84
children f2a55e5e24db
files gamelib/constants.py gamelib/gameboard.py gamelib/loadlevel.py gamelib/toolbar.py
diffstat 4 files changed, 247 insertions(+), 236 deletions(-) [+]
line wrap: on
line diff
--- a/gamelib/constants.py	Sat Nov 21 16:54:05 2009 +0000
+++ b/gamelib/constants.py	Sat Nov 21 16:59:49 2009 +0000
@@ -53,4 +53,5 @@
 
 NIGHT_LENGTH = 150
 
-
+TILE_DIMENSIONS = (20, 20)
+TOOLBAR_WIDTH = 140
--- a/gamelib/gameboard.py	Sat Nov 21 16:54:05 2009 +0000
+++ b/gamelib/gameboard.py	Sat Nov 21 16:59:49 2009 +0000
@@ -16,232 +16,7 @@
 import sprite_cursor
 import misc
 import engine
-
-class OpaqueLabel(gui.Label):
-    def __init__(self, value, **params):
-        gui.Label.__init__(self, value, **params)
-        if 'width' in params:
-            self._width = params['width']
-        if 'height' in params:
-            self._height = params['height']
-        self._set_size()
-
-    def _set_size(self):
-        width, height = self.font.size(self.value)
-        width = getattr(self, '_width', width)
-        height = getattr(self, '_height', height)
-        self.style.width, self.style.height = width, height
-
-    def paint(self, s):
-        s.fill(self.style.background)
-        if self.style.align > 0:
-            r = s.get_rect()
-            w, _ = self.font.size(self.value)
-            s = s.subsurface(r.move((r.w-w, 0)).clip(r))
-        gui.Label.paint(self, s)
-
-    def update_value(self, value):
-        self.value = value
-        self._set_size()
-        self.repaint()
-
-def mklabel(text="", **params):
-    params.setdefault('color', constants.FG_COLOR)
-    params.setdefault('width', GameBoard.TOOLBAR_WIDTH/2)
-    return OpaqueLabel(text, **params)
-
-def mkcountupdate(counter):
-    def update_counter(self, value):
-        getattr(self, counter).update_value("%s  " % value)
-        self.repaint()
-    return update_counter
-
-class ToolBar(gui.Table):
-    def __init__(self, gameboard, level, **params):
-        gui.Table.__init__(self, **params)
-        self.group = gui.Group(name='toolbar', value=None)
-        self._next_tool_value = 0
-        self.gameboard = gameboard
-        self.cash_counter = mklabel(align=1)
-        self.wood_counter = mklabel(align=1)
-        self.chicken_counter = mklabel(align=1)
-        self.egg_counter = mklabel(align=1)
-        self.day_counter = mklabel(align=1)
-        self.killed_foxes = mklabel(align=1)
-
-        self.tr()
-        self.td(gui.Spacer(self.rect.w/2, 0))
-        self.td(gui.Spacer(self.rect.w/2, 0))
-        self.add_counter(mklabel("Day:"), self.day_counter)
-        self.add_counter(mklabel("Groats:"), self.cash_counter)
-        self.add_counter(mklabel("Planks:"), self.wood_counter)
-        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(5)
-
-        self.add_tool_button("Move Hen", constants.TOOL_PLACE_ANIMALS,
-                None, cursors.cursors['select'])
-        self.add_spacer(5)
-
-        self.add_heading("Sell ...")
-        self.add_tool_button("Chicken", constants.TOOL_SELL_CHICKEN,
-                level.sell_price_chicken, cursors.cursors['sell'])
-        self.add_tool_button("Egg", constants.TOOL_SELL_EGG,
-                level.sell_price_egg, cursors.cursors['sell'])
-        self.add_tool_button("Building", constants.TOOL_SELL_BUILDING,
-                None, cursors.cursors['sell'])
-        self.add_tool_button("Equipment", constants.TOOL_SELL_EQUIPMENT,
-                None, cursors.cursors['sell'])
-        self.add_spacer(5)
-
-        self.add_heading("Buy ...")
-
-        for building_cls in buildings.BUILDINGS:
-            self.add_tool_button(building_cls.NAME.title(), building_cls,
-                    None, cursors.cursors.get('build', None))
-
-        for equipment_cls in equipment.EQUIPMENT:
-            self.add_tool_button(equipment_cls.NAME.title(),
-                    equipment_cls,
-                    equipment_cls.BUY_PRICE,
-                    cursors.cursors.get('buy', None))
-
-        self.add_spacer(5)
-        self.add_tool_button("Repair", constants.TOOL_REPAIR_BUILDING, None, cursors.cursors['repair'])
-
-        self.add_spacer(5)
-        self.add_tool("Price Reference", self.show_prices)
-
-        self.fin_tool = self.add_tool("Finished Day", self.day_done)
-
-        self.anim_clear_tool = False # Flag to clear the tool on an anim loop
-        # pgu's tool widget fiddling happens after the tool action, so calling
-        # clear_tool in the tool's action doesn't work, so we punt it to
-        # the anim loop
-
-    def day_done(self):
-        if self.gameboard.day:
-            pygame.event.post(engine.START_NIGHT)
-        else:
-            self.anim_clear_tool = True
-            pygame.event.post(engine.FAST_FORWARD)
-
-    def update_fin_tool(self, day):
-        if day:
-            self.fin_tool.widget = gui.basic.Label('Finished Day')
-            self.fin_tool.resize()
-        else:
-            self.fin_tool.widget = gui.basic.Label('Fast Forward')
-            self.fin_tool.resize()
-
-    def show_prices(self):
-        """Popup dialog of prices"""
-        def make_box(text):
-            style = {
-                    'border' : 1
-                    }
-            word = gui.Label(text, style=style)
-            return word
-
-        def fix_widths(doc):
-            """Loop through all the widgets in the doc, and set the
-               width of the labels to max + 10"""
-            # We need to do this because of possible font issues
-            max_width = 0
-            for thing in doc.widgets:
-                if hasattr(thing, 'style'):
-                    # A label
-                    if thing.style.width > max_width:
-                        max_width = thing.style.width
-            for thing in doc.widgets:
-                if hasattr(thing, 'style'):
-                    thing.style.width = max_width + 10
-
-        tbl = gui.Table()
-        tbl.tr()
-        doc = gui.Document(width=510)
-        space = doc.style.font.size(" ")
-        for header in ['Item', 'Buy Price', 'Sell Price', 'Repair Price']:
-            doc.add(make_box(header))
-        doc.br(space[1])
-        for building in buildings.BUILDINGS:
-            doc.add(make_box(building.NAME))
-            doc.add(make_box('%d' % building.BUY_PRICE))
-            doc.add(make_box('%d' % building.SELL_PRICE))
-            if building.BREAKABLE:
-                doc.add(make_box('%d' % building.REPAIR_PRICE))
-            else:
-                doc.add(make_box('N/A'))
-            doc.br(space[1])
-        for equip in equipment.EQUIPMENT:
-            doc.add(make_box(equip.NAME))
-            doc.add(make_box('%d' % equip.BUY_PRICE))
-            doc.add(make_box('%d' % equip.SELL_PRICE))
-            doc.add(make_box('N/A'))
-            doc.br(space[1])
-
-        fix_widths(doc)
-        for word in "Damaged equipment or buildings will be sold for" \
-                " less than the sell price.".split():
-            doc.add(gui.Label(word))
-            doc.space(space)
-        close_button = gui.Button("Close")
-        tbl.td(doc)
-        tbl.tr()
-        tbl.td(close_button, align=1)
-        dialog = gui.Dialog(gui.Label('Price Reference'), tbl)
-        close_button.connect(gui.CLICK, dialog.close)
-        dialog.open()
-        self.anim_clear_tool = True
-
-    update_cash_counter = mkcountupdate('cash_counter')
-    update_wood_counter = mkcountupdate('wood_counter')
-    update_fox_counter = mkcountupdate('killed_foxes')
-    update_chicken_counter = mkcountupdate('chicken_counter')
-    update_egg_counter = mkcountupdate('egg_counter')
-    update_day_counter = mkcountupdate('day_counter')
-
-    def add_spacer(self, height):
-        self.tr()
-        self.td(gui.Spacer(0, height), colspan=2)
-
-    def add_heading(self, text):
-        self.tr()
-        self.td(mklabel(text), colspan=2)
-
-    def add_tool_button(self, text, tool, price=None, cursor=None):
-        if price is not None:
-            text = "%s  (%s)" % (text, price)
-        self.add_tool(text, lambda: self.gameboard.set_selected_tool(tool,
-            cursor))
-
-    def add_tool(self, text, func):
-        label = gui.basic.Label(text)
-        value = self._next_tool_value
-        self._next_tool_value += 1
-        tool = gui.Tool(self.group, label, value, width=self.rect.w, style={"padding_left": 0})
-        tool.connect(gui.CLICK, func)
-        self.tr()
-        self.td(tool, align=-1, colspan=2)
-        return tool
-
-    def clear_tool(self):
-        self.group.value = None
-        for item in self.group.widgets:
-            item.pcls = ""
-        self.anim_clear_tool = False
-
-    def add_counter(self, icon, label):
-        self.tr()
-        self.td(icon, width=self.rect.w/2)
-        self.td(label, width=self.rect.w/2)
-
-    def resize(self, width=None, height=None):
-        width, height = gui.Table.resize(self, width, height)
-        width = GameBoard.TOOLBAR_WIDTH
-        return width, height
-
+import toolbar
 
 class VidWidget(gui.Widget):
     def __init__(self, gameboard, vid, **params):
@@ -266,8 +41,6 @@
             self.gameboard.update_sprite_cursor(e)
 
 class GameBoard(object):
-    TILE_DIMENSIONS = (20, 20)
-    TOOLBAR_WIDTH = 140
 
     GRASSLAND = tiles.REVERSE_TILE_MAP['grassland']
     FENCE = tiles.REVERSE_TILE_MAP['fence']
@@ -318,9 +91,9 @@
         width, height = self.disp.rect.w, self.disp.rect.h
         tbl = gui.Table()
         tbl.tr()
-        self.toolbar = ToolBar(self, self.level, width=self.TOOLBAR_WIDTH)
+        self.toolbar = toolbar.ToolBar(self, self.level, width=constants.TOOLBAR_WIDTH)
         tbl.td(self.toolbar, valign=-1)
-        self.tvw = VidWidget(self, self.tv, width=width-self.TOOLBAR_WIDTH, height=height)
+        self.tvw = VidWidget(self, self.tv, width=width-constants.TOOLBAR_WIDTH, height=height)
         tbl.td(self.tvw)
         self.top_widget = tbl
 
@@ -763,13 +536,13 @@
     def event(self, e):
         if e.type == KEYDOWN and e.key in [K_UP, K_DOWN, K_LEFT, K_RIGHT]:
             if e.key == K_UP:
-                self.tvw.move_view(0, -self.TILE_DIMENSIONS[1])
+                self.tvw.move_view(0, -constants.TILE_DIMENSIONS[1])
             if e.key == K_DOWN:
-                self.tvw.move_view(0, self.TILE_DIMENSIONS[1])
+                self.tvw.move_view(0, constants.TILE_DIMENSIONS[1])
             if e.key == K_LEFT:
-                self.tvw.move_view(-self.TILE_DIMENSIONS[0], 0)
+                self.tvw.move_view(-constants.TILE_DIMENSIONS[0], 0)
             if e.key == K_RIGHT:
-                self.tvw.move_view(self.TILE_DIMENSIONS[0], 0)
+                self.tvw.move_view(constants.TILE_DIMENSIONS[0], 0)
             return True
         return False
 
--- a/gamelib/loadlevel.py	Sat Nov 21 16:54:05 2009 +0000
+++ b/gamelib/loadlevel.py	Sat Nov 21 16:59:49 2009 +0000
@@ -8,6 +8,7 @@
 import data
 import imagecache
 import gameboard
+import constants
 
 def make_load_screen(level):
     """Create a screen for selecting the levels"""
@@ -100,7 +101,8 @@
         space = self.style.font.size(" ")
         w, h = board.tv.size
 
-        map_image = pygame.Surface((20*w, 20*h))
+        map_image = pygame.Surface((constants.TILE_DIMENSIONS[0] * w,
+            constants.TILE_DIMENSIONS[1] * h))
         board.tv.loop()
         board.tv.paint(map_image)
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/gamelib/toolbar.py	Sat Nov 21 16:59:49 2009 +0000
@@ -0,0 +1,235 @@
+import pygame
+from pgu import gui
+
+import icons
+import constants
+import buildings
+import equipment
+import cursors
+import engine
+
+class OpaqueLabel(gui.Label):
+    def __init__(self, value, **params):
+        gui.Label.__init__(self, value, **params)
+        if 'width' in params:
+            self._width = params['width']
+        if 'height' in params:
+            self._height = params['height']
+        self._set_size()
+
+    def _set_size(self):
+        width, height = self.font.size(self.value)
+        width = getattr(self, '_width', width)
+        height = getattr(self, '_height', height)
+        self.style.width, self.style.height = width, height
+
+    def paint(self, s):
+        s.fill(self.style.background)
+        if self.style.align > 0:
+            r = s.get_rect()
+            w, _ = self.font.size(self.value)
+            s = s.subsurface(r.move((r.w-w, 0)).clip(r))
+        gui.Label.paint(self, s)
+
+    def update_value(self, value):
+        self.value = value
+        self._set_size()
+        self.repaint()
+
+def mklabel(text="", **params):
+    params.setdefault('color', constants.FG_COLOR)
+    params.setdefault('width', constants.TOOLBAR_WIDTH/2)
+    return OpaqueLabel(text, **params)
+
+def mkcountupdate(counter):
+    def update_counter(self, value):
+        getattr(self, counter).update_value("%s  " % value)
+        self.repaint()
+    return update_counter
+
+class ToolBar(gui.Table):
+    def __init__(self, gameboard, level, **params):
+        gui.Table.__init__(self, **params)
+        self.group = gui.Group(name='toolbar', value=None)
+        self._next_tool_value = 0
+        self.gameboard = gameboard
+        self.cash_counter = mklabel(align=1)
+        self.wood_counter = mklabel(align=1)
+        self.chicken_counter = mklabel(align=1)
+        self.egg_counter = mklabel(align=1)
+        self.day_counter = mklabel(align=1)
+        self.killed_foxes = mklabel(align=1)
+
+        self.tr()
+        self.td(gui.Spacer(self.rect.w/2, 0))
+        self.td(gui.Spacer(self.rect.w/2, 0))
+        self.add_counter(mklabel("Day:"), self.day_counter)
+        self.add_counter(mklabel("Groats:"), self.cash_counter)
+        self.add_counter(mklabel("Planks:"), self.wood_counter)
+        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(5)
+
+        self.add_tool_button("Move Hen", constants.TOOL_PLACE_ANIMALS,
+                None, cursors.cursors['select'])
+        self.add_spacer(5)
+
+        self.add_heading("Sell ...")
+        self.add_tool_button("Chicken", constants.TOOL_SELL_CHICKEN,
+                level.sell_price_chicken, cursors.cursors['sell'])
+        self.add_tool_button("Egg", constants.TOOL_SELL_EGG,
+                level.sell_price_egg, cursors.cursors['sell'])
+        self.add_tool_button("Building", constants.TOOL_SELL_BUILDING,
+                None, cursors.cursors['sell'])
+        self.add_tool_button("Equipment", constants.TOOL_SELL_EQUIPMENT,
+                None, cursors.cursors['sell'])
+        self.add_spacer(5)
+
+        self.add_heading("Buy ...")
+
+        for building_cls in buildings.BUILDINGS:
+            self.add_tool_button(building_cls.NAME.title(), building_cls,
+                    None, cursors.cursors.get('build', None))
+
+        for equipment_cls in equipment.EQUIPMENT:
+            self.add_tool_button(equipment_cls.NAME.title(),
+                    equipment_cls,
+                    equipment_cls.BUY_PRICE,
+                    cursors.cursors.get('buy', None))
+
+        self.add_spacer(5)
+        self.add_tool_button("Repair", constants.TOOL_REPAIR_BUILDING, None, cursors.cursors['repair'])
+
+        self.add_spacer(5)
+        self.add_tool("Price Reference", self.show_prices)
+
+        self.fin_tool = self.add_tool("Finished Day", self.day_done)
+
+        self.anim_clear_tool = False # Flag to clear the tool on an anim loop
+        # pgu's tool widget fiddling happens after the tool action, so calling
+        # clear_tool in the tool's action doesn't work, so we punt it to
+        # the anim loop
+
+    def day_done(self):
+        if self.gameboard.day:
+            pygame.event.post(engine.START_NIGHT)
+        else:
+            self.anim_clear_tool = True
+            pygame.event.post(engine.FAST_FORWARD)
+
+    def update_fin_tool(self, day):
+        if day:
+            self.fin_tool.widget = gui.basic.Label('Finished Day')
+            self.fin_tool.resize()
+        else:
+            self.fin_tool.widget = gui.basic.Label('Fast Forward')
+            self.fin_tool.resize()
+
+    def show_prices(self):
+        """Popup dialog of prices"""
+        def make_box(text):
+            style = {
+                    'border' : 1
+                    }
+            word = gui.Label(text, style=style)
+            return word
+
+        def fix_widths(doc):
+            """Loop through all the widgets in the doc, and set the
+               width of the labels to max + 10"""
+            # We need to do this because of possible font issues
+            max_width = 0
+            for thing in doc.widgets:
+                if hasattr(thing, 'style'):
+                    # A label
+                    if thing.style.width > max_width:
+                        max_width = thing.style.width
+            for thing in doc.widgets:
+                if hasattr(thing, 'style'):
+                    thing.style.width = max_width + 10
+
+        tbl = gui.Table()
+        tbl.tr()
+        doc = gui.Document(width=510)
+        space = doc.style.font.size(" ")
+        for header in ['Item', 'Buy Price', 'Sell Price', 'Repair Price']:
+            doc.add(make_box(header))
+        doc.br(space[1])
+        for building in buildings.BUILDINGS:
+            doc.add(make_box(building.NAME))
+            doc.add(make_box('%d' % building.BUY_PRICE))
+            doc.add(make_box('%d' % building.SELL_PRICE))
+            if building.BREAKABLE:
+                doc.add(make_box('%d' % building.REPAIR_PRICE))
+            else:
+                doc.add(make_box('N/A'))
+            doc.br(space[1])
+        for equip in equipment.EQUIPMENT:
+            doc.add(make_box(equip.NAME))
+            doc.add(make_box('%d' % equip.BUY_PRICE))
+            doc.add(make_box('%d' % equip.SELL_PRICE))
+            doc.add(make_box('N/A'))
+            doc.br(space[1])
+
+        fix_widths(doc)
+        for word in "Damaged equipment or buildings will be sold for" \
+                " less than the sell price.".split():
+            doc.add(gui.Label(word))
+            doc.space(space)
+        close_button = gui.Button("Close")
+        tbl.td(doc)
+        tbl.tr()
+        tbl.td(close_button, align=1)
+        dialog = gui.Dialog(gui.Label('Price Reference'), tbl)
+        close_button.connect(gui.CLICK, dialog.close)
+        dialog.open()
+        self.anim_clear_tool = True
+
+    update_cash_counter = mkcountupdate('cash_counter')
+    update_wood_counter = mkcountupdate('wood_counter')
+    update_fox_counter = mkcountupdate('killed_foxes')
+    update_chicken_counter = mkcountupdate('chicken_counter')
+    update_egg_counter = mkcountupdate('egg_counter')
+    update_day_counter = mkcountupdate('day_counter')
+
+    def add_spacer(self, height):
+        self.tr()
+        self.td(gui.Spacer(0, height), colspan=2)
+
+    def add_heading(self, text):
+        self.tr()
+        self.td(mklabel(text), colspan=2)
+
+    def add_tool_button(self, text, tool, price=None, cursor=None):
+        if price is not None:
+            text = "%s  (%s)" % (text, price)
+        self.add_tool(text, lambda: self.gameboard.set_selected_tool(tool,
+            cursor))
+
+    def add_tool(self, text, func):
+        label = gui.basic.Label(text)
+        value = self._next_tool_value
+        self._next_tool_value += 1
+        tool = gui.Tool(self.group, label, value, width=self.rect.w, style={"padding_left": 0})
+        tool.connect(gui.CLICK, func)
+        self.tr()
+        self.td(tool, align=-1, colspan=2)
+        return tool
+
+    def clear_tool(self):
+        self.group.value = None
+        for item in self.group.widgets:
+            item.pcls = ""
+        self.anim_clear_tool = False
+
+    def add_counter(self, icon, label):
+        self.tr()
+        self.td(icon, width=self.rect.w/2)
+        self.td(label, width=self.rect.w/2)
+
+    def resize(self, width=None, height=None):
+        width, height = gui.Table.resize(self, width, height)
+        width = constants.TOOLBAR_WIDTH
+        return width, height
+