Scrollable text widgets.
authorSimon Cross <hodgestar@gmail.com>
Fri, 16 May 2014 22:28:20 +0000 (00:28 +0200)
committerSimon Cross <hodgestar@gmail.com>
Fri, 16 May 2014 22:28:49 +0000 (00:28 +0200)
naja/scenes/howto.py
naja/widgets/text.py

index 5114069eab361447b202b5b9e7765b4a7620a44e..d44483411d0c3b93a2a86adc983602849e6502c5 100644 (file)
@@ -21,7 +21,7 @@ class HowtoScene(Scene):
             (200, 4), 'How To Play the Game', fontsize=32,
             colour='white'))
         self.add(TextBoxWidget(
-            (0, 40), '\n'.join([
+            (10, 50), '\n'.join([
                 "You are a robot, frantically trying to set the correct "
                 "bits to gain points for reasons that are unlikely to "
                 "ever become clear.",
@@ -30,11 +30,15 @@ class HowtoScene(Scene):
                 "to unlock actions {RED,GREEN,BLUE} and the "
                 "last, the Most Significant Bit {MSB}, makes everything "
                 "work better.",
+                "",
                 "MOVEMENT",
+                "",
                 "During Movement, you can explore the board and learn about "
                 "the available tiles. Tiles you can legally move onto are "
                 "highlighted. It's always possible to stay in place.",
+                "",
                 "ACTIONS",
+                "",
                 "After moving, you must select an action. Some actions "
                 "require the correct bits to be set before they can be "
                 "selected. After the action, the tile will be replaced.",
@@ -45,7 +49,7 @@ class HowtoScene(Scene):
             ]), fontsize=32,
             colour='white', padding=1, border=1,
             bg_colour='black', border_colour='black',
-            box_width=400))
+            box_width=380, view_port=(780, 500)))
 
     def handle_scene_event(self, ev):
         from naja.scenes.menu import MenuScene
index 306841257ccaa090238743be176f680ed651a354..7c1039ff4d2ef517f019c7d52b71f8a75c0149ea 100644 (file)
@@ -1,6 +1,7 @@
 import pygame
+import pygame.locals as pgl
 
-from naja.constants import FONT, FONT_SIZE, EIGHT_BIT_SCALE, PALETTE
+from naja.constants import FONT, FONT_SIZE, EIGHT_BIT_SCALE, PALETTE, KEYS
 from naja.resources import resources
 from naja.resources.mutators import EIGHT_BIT, blender
 from naja.utils import convert_colour
@@ -36,9 +37,11 @@ class Glyph(object):
 
 class TextWidget(Widget):
 
-    def __init__(self, pos, text, size=None, fontname=None, fontsize=None,
-                 colour=None, unselectable_colour=None):
-        super(TextWidget, self).__init__(pos, size)
+    VIEW_PORT_DY = 50
+
+    def __init__(self, pos, text, fontname=None, fontsize=None,
+                 colour=None, unselectable_colour=None, view_port=None):
+        super(TextWidget, self).__init__(pos)
 
         self.text = text
         self.fontname = fontname or FONT
@@ -47,6 +50,8 @@ class TextWidget(Widget):
         if unselectable_colour is not None:
             unselectable_colour = convert_colour(unselectable_colour)
         self.unselectable_colour = unselectable_colour
+        self.view_port = (
+            pygame.Rect((0, 0), view_port) if view_port is not None else None)
 
     def render_line(self, text):
         colour = self.colour
@@ -58,13 +63,41 @@ class TextWidget(Widget):
             text_surf, (text_rect.width * EIGHT_BIT_SCALE,
                         text_rect.height * EIGHT_BIT_SCALE))
 
+    def update_size(self):
+        if self.view_port is not None:
+            self.size = self.view_port.size
+        else:
+            self.size = self.surface.get_rect().size
+
     def prepare(self):
         self.font = resources.get_font(self.fontname, self.fontsize)
         self.surface = self.render_line(self.text)
-        self.size = self.surface.get_rect().size
+        self.update_size()
+
+    def handle_event(self, ev):
+        if self.view_port is None:
+            return super(TextWidget, self).handle_event(ev)
+        if ev.type == pgl.KEYDOWN:
+            if ev.key in KEYS.DOWN:
+                self.view_port.move_ip(0, self.VIEW_PORT_DY)
+                if self.view_port.bottom > self.surface.get_rect().bottom:
+                    self.view_port.bottom = self.surface.get_rect().bottom
+                return True
+            elif ev.key in KEYS.UP:
+                self.view_port.move_ip(0, -self.VIEW_PORT_DY)
+                if self.view_port.top < 0:
+                    self.view_port.top = 0
+                return True
+        return super(TextWidget, self).handle_event(ev)
 
     def draw(self, surface):
-        surface.blit(self.surface, self.rect)
+        if self.view_port is None:
+            rect = self.rect
+            area = None
+        else:
+            rect = self.pos
+            area = self.view_port
+        surface.blit(self.surface, rect, area)
 
 
 class TextBoxWidget(TextWidget):
@@ -123,6 +156,11 @@ class TextBoxWidget(TextWidget):
 
         line_count = 0
         for line in self.text.splitlines():
+            line = line.strip()
+            if not line:
+                line_count += 1
+                yield line
+                continue
             current_words = []
             remaining_words = line.split()
             while remaining_words:
@@ -161,7 +199,7 @@ class TextBoxWidget(TextWidget):
         self.surface = pygame.surface.Surface((width, height),
                                               pygame.locals.SRCALPHA)
         self.surface.fill(self.bg_colour)
-        self.size = self.surface.get_rect().size
+        self.update_size()
 
         x, y = self.padding, self.padding
         for line_surface in rendered_lines: