Beispiel #1
0
 def __init__(self, text, color, x, y, width):
     win_width, win_height = get_size()
     self.batch = Batch()
     self._doc = pyglet.text.document.UnformattedDocument(text)
     self._doc.set_style(
         0, len(self._doc.text),
         dict(color=(255, 255, 255, 255), font_name='minecraftia'))
     font = self._doc.get_font()
     height = font.ascent - font.descent
     pad = 2
     self._outline = Rectangle(x - pad,
                               y - pad,
                               width + pad,
                               height + pad,
                               color=color[:3])
     self._outline.opacity = color[-1]
     self._layout = IncrementalTextLayout(self._doc,
                                          width,
                                          height,
                                          multiline=False,
                                          batch=self.batch)
     self._caret = Caret(self._layout, color=(255, 255, 255))
     self._caret.visible = False
     self._layout.x = x
     self._layout.y = y
     self._focus = False
     self._press = False
     super().__init__(x, y, width, height)
     self.last_char = ''
Beispiel #2
0
 def __init__(self, text, color, x, y, width, pad=3):
     win_width, win_height = get_size()
     self.batch = Batch()
     self._doc = pyglet.text.document.UnformattedDocument(text)
     self._doc.set_style(0, len(self._doc.text),
                         dict(color=(255, 255, 255, 255)))
     font = self._doc.get_font()
     self.text_height = font.ascent - font.descent
     self.pad = pad
     self._outline = BorderedRectangle(x - self.pad,
                                       win_height - y - self.pad,
                                       width + self.pad,
                                       self.text_height + self.pad,
                                       color=color[:3],
                                       border_color=(100, 100, 100))
     self._outline.opacity = color[-1]
     self._layout = IncrementalTextLayout(width,
                                          self.text_height,
                                          multiline=False,
                                          batch=self.batch)
     self._caret = Caret(self._layout, color=(255, 255, 255))
     self._caret.visible = False
     self._layout.x = x
     self._layout.y = win_height - y
     self._focus = False
     self._press = False
     super().__init__(x, win_height - y, width, height)
Beispiel #3
0
 def __init__(self):
     win_width, win_height = get_size()
     self.batch = Batch()
     self._doc = pyglet.text.document.UnformattedDocument('')
     self._doc.set_style(0, len(self._doc.text),
                         dict(color=(255, 255, 255, 255)))
     font = self._doc.get_font()
     self.text_height = font.ascent - font.descent
     self.pad = 2
     self._outline = Rectangle(5,
                               5 + self.pad,
                               get_size()[0] - self.pad - 10,
                               self.text_height + self.pad,
                               color=(0, 0, 0))
     self._outline.opacity = 150
     self._layout = IncrementalTextLayout(self._doc,
                                          get_size()[0] - 14,
                                          self.text_height,
                                          multiline=False,
                                          batch=self.batch)
     self._caret = Caret(self._layout, color=(255, 255, 255))
     self._caret.visible = False
     self._layout.x = 5
     self._layout.y = 5 + self.pad
     self._focus = False
     self._press = False
     self.last_press = [0, 0]
     super().__init__(5, 5 + self.pad,
                      get_size()[0] - self.pad - 10,
                      self.text_height + self.pad)
Beispiel #4
0
 def __init__(self):
     super(Editor, self).__init__()
     
     self.doc = FormattedDocument('<b>testing</b> testing testing')
     self.doc.set_style(0, 1000, {'font_name': 'ProggySquareTT'})  
     
     self.itlo = IncrementalTextLayout(self.doc, 1024, 750, multiline=True, batch=self.batch)
     self.itlo.x = 0
     self.itlo.y = 750
     caret = Caret(self.itlo)
     caret.visible = True
     caret.color = (100, 255, 0)
     
     director.window.push_handlers(caret)
Beispiel #5
0
 def __init__(self, value="", x=0, y=0, width=125, height=30, padding=(0,0), wrap=True, id=None, **kwargs):
     """ An editable text box.
         When clicked, it has the focus and can receive keyboard events.
         With wrap=True, several lines of text will wrap around the width.
         Optional parameters can include fill, font, fontsize, fontweight.
     """
     txt = Text(value or " ", **{
            "fill" : _popdefault(kwargs, "fill", Color(0,0.9)),
            "font" : _popdefault(kwargs, "font", theme["fontname"]),
        "fontsize" : _popdefault(kwargs, "fontsize", theme["fontsize"]),
      "fontweight" : _popdefault(kwargs, "fontweight", theme["fontweight"]),
      "lineheight" : _popdefault(kwargs, "lineheight", 1),
           "align" : LEFT
     })
     kwargs["width"]  = width
     kwargs["height"] = height
     Control.__init__(self, x=x, y=y, id=id, **kwargs)
     self.reserved = kwargs.get("reserved", [ENTER, TAB])
     self._padding = padding
     self._i       = 0     # Index of character on which the mouse is pressed.
     self._empty   = value == "" and True or False
     self._editor  = IncrementalTextLayout(txt._label.document, width, height, multiline=wrap)
     self._editor.content_valign = wrap and "top" or "center"
     self._editor.selection_background_color = (170, 200, 230, 255)
     self._editor.selection_color = txt._label.color
     self._editor.caret = Caret(self._editor)
     self._editor.caret.visible = False
     self._editing = False # When True, cursor is blinking and text can be edited.
     Editable._pack(self)  # On init, call Editable._pack(), not the derived Field._pack().
Beispiel #6
0
    def __init__(self,
                 text,
                 x,
                 y,
                 width,
                 color=(255, 255, 255, 255),
                 batch=None,
                 group=None):
        self._doc = pyglet.text.document.UnformattedDocument(text)
        self._doc.set_style(0, len(self._doc.text), dict(color=(0, 0, 0, 255)))
        font = self._doc.get_font()
        height = font.ascent - font.descent

        self._user_group = group
        bg_group = OrderedGroup(0, parent=group)
        fg_group = OrderedGroup(1, parent=group)

        # Rectangular outline:
        pad = 2
        x1 = x - pad
        y1 = y - pad
        x2 = x + width + pad
        y2 = y + height + pad
        self._outline = batch.add(4, pyglet.gl.GL_QUADS, bg_group,
                                  ('v2i', [x1, y1, x2, y1, x2, y2, x1, y2]),
                                  ('c4B', color * 4))
        # Text and Caret:
        self._layout = IncrementalTextLayout(self._doc,
                                             width,
                                             height,
                                             multiline=False,
                                             batch=batch,
                                             group=fg_group)
        self._caret = Caret(self._layout)
        self._caret.visible = False

        self._layout.x = x
        self._layout.y = y

        self._focus = False

        super().__init__(x, y, width, height)
Beispiel #7
0
    def __init__(self,
                 text,
                 x,
                 y,
                 width,
                 color=(255, 255, 255, 255),
                 batch=None,
                 group=None):
        self._doc = pyglet.text.document.UnformattedDocument(text)
        self._doc.set_style(0, len(self._doc.text), dict(color=(0, 0, 0, 255)))
        font = self._doc.get_font()
        height = font.ascent - font.descent

        self._user_group = group
        bg_group = Group(order=0, parent=group)
        fg_group = Group(order=1, parent=group)

        # Rectangular outline with 2-pixel pad:
        p = 2
        self._outline = pyglet.shapes.Rectangle(x - p, y - p, width + p + p,
                                                height + p + p, color[:3],
                                                batch, bg_group)
        self._outline.opacity = color[3]

        # Text and Caret:
        self._layout = IncrementalTextLayout(self._doc,
                                             width,
                                             height,
                                             multiline=False,
                                             batch=batch,
                                             group=fg_group)
        self._layout.x = x
        self._layout.y = y
        self._caret = Caret(self._layout)
        self._caret.visible = False

        self._focus = False

        super().__init__(x, y, width, height)
Beispiel #8
0
class TextEntry(WidgetBase):
    def __init__(self,
                 text,
                 x,
                 y,
                 width,
                 color=(255, 255, 255, 255),
                 batch=None,
                 group=None):
        self._doc = pyglet.text.document.UnformattedDocument(text)
        self._doc.set_style(0, len(self._doc.text), dict(color=(0, 0, 0, 255)))
        font = self._doc.get_font()
        height = font.ascent - font.descent

        self._user_group = group
        bg_group = Group(order=0, parent=group)
        fg_group = Group(order=1, parent=group)

        # Rectangular outline with 2-pixel pad:
        p = 2
        self._outline = pyglet.shapes.Rectangle(x - p, y - p, width + p + p,
                                                height + p + p, color[:3],
                                                batch, bg_group)
        self._outline.opacity = color[3]

        # Text and Caret:
        self._layout = IncrementalTextLayout(self._doc,
                                             width,
                                             height,
                                             multiline=False,
                                             batch=batch,
                                             group=fg_group)
        self._layout.x = x
        self._layout.y = y
        self._caret = Caret(self._layout)
        self._caret.visible = False

        self._focus = False

        super().__init__(x, y, width, height)

    def _check_hit(self, x, y):
        return self._x < x < self._x + self._width and self._y < y < self._y + self._height

    def _set_focus(self, value):
        self._focus = value
        self._caret.visible = value

    def update_groups(self, order):
        self._outline.group = Group(order=order + 1, parent=self._user_group)
        self._layout.group = Group(order=order + 2, parent=self._user_group)

    def on_mouse_motion(self, x, y, dx, dy):
        if not self._check_hit(x, y):
            self._set_focus(False)

    def on_mouse_drag(self, x, y, dx, dy, buttons, modifiers):
        if self._focus:
            self._caret.on_mouse_drag(x, y, dx, dy, buttons, modifiers)

    def on_mouse_press(self, x, y, buttons, modifiers):
        if self._check_hit(x, y):
            self._set_focus(True)
            self._caret.on_mouse_press(x, y, buttons, modifiers)

    def on_text(self, text):
        if self._focus:
            if text in ('\r', '\n'):
                self.dispatch_event('on_commit', self._layout.document.text)
                self._set_focus(False)
                return
            self._caret.on_text(text)

    def on_text_motion(self, motion):
        if self._focus:
            self._caret.on_text_motion(motion)

    def on_text_motion_select(self, motion):
        if self._focus:
            self._caret.on_text_motion_select(motion)

    def on_commit(self, text):
        """Text has been commited via Enter/Return key."""
class Menu(GameObject):
    """Provides menus for the game. Both main menu with highscores and a menu to input name for highscore.

    Which menu is shown depends on add_score. If it's None then main menu is shown."""
    def __init__(self,
                 *,
                 highscores,
                 ui_batch,
                 cb_start_game=None,
                 cb_add_highscore=None,
                 add_score=None):
        super().__init__()

        # Make sure we can handle events
        self.event_handlers = [self]

        # Store callbacks, the ui batch and our optional score3
        self.cb_start_game = cb_start_game
        self.cb_add_highscore = cb_add_highscore
        self.ui_batch = ui_batch
        self.add_score = add_score

        # We need to keep track of our children so we can remove them in self.delete()
        self.children = []

        # Show title
        self.children.append(
            Label('WELCOME TO',
                  font_name='m5x7',
                  font_size=128,
                  x=WIDTH / 2,
                  y=HEIGHT - 16,
                  anchor_x='center',
                  anchor_y='top',
                  batch=self.ui_batch))
        self.children.append(
            Label('HELL',
                  font_name='m5x7',
                  font_size=512,
                  x=WIDTH / 2 + 50,
                  y=HEIGHT,
                  anchor_x='center',
                  anchor_y='top',
                  batch=self.ui_batch))

        # If we need to add a score
        if add_score is not None:
            # Make sure that self.continue_label exists so we don't crash in self.tick()
            self.continue_label = None

            # Show some text
            self.children.append(
                Label('Your score was:',
                      font_name='m5x7',
                      font_size=48,
                      x=WIDTH / 2,
                      y=400,
                      align='center',
                      anchor_x='center',
                      anchor_y='bottom',
                      batch=self.ui_batch))
            self.children.append(
                Label(f'{add_score}',
                      font_name='m5x7',
                      font_size=128,
                      x=WIDTH / 2,
                      y=280,
                      align='center',
                      anchor_x='center',
                      anchor_y='bottom',
                      batch=self.ui_batch))
            self.children.append(
                Label('Enter name for highscore:',
                      font_name='m5x7',
                      font_size=32,
                      x=WIDTH / 2,
                      y=200,
                      align='center',
                      anchor_x='center',
                      anchor_y='bottom',
                      batch=self.ui_batch))

            # Prepare a document with styling
            self.document = UnformattedDocument()
            self.document.set_style(
                0, 1, {
                    'font_name': 'm5x7',
                    'font_size': 64,
                    'color': (255, 255, 255, 255),
                    'align': 'center'
                })
            # Find the height of the font
            font = self.document.get_font()
            height = font.ascent - font.descent
            # Make a TextLayout that handles dynamically adding text
            # Make it multiline even though we don't want multiple lines because otherwise align=center doesn't work
            self.layout = IncrementalTextLayout(self.document,
                                                WIDTH / 3,
                                                height,
                                                multiline=True,
                                                batch=self.ui_batch)
            self.layout.anchor_y = 'top'
            self.layout.anchor_x = 'center'
            self.layout.x = WIDTH / 2
            self.layout.y = 200
            # Add a carat (cursor)
            self.caret = Caret(self.layout,
                               batch=self.ui_batch,
                               color=(255, 255, 255))
            # Type q and then backspace
            # This ensures that the carat is visible as it only shows up after something has been typed
            self.caret.on_text('q')
            self.caret.on_text_motion(key.MOTION_BACKSPACE)
            # Make sure we can delete layout and carat in self.delete()
            self.children.append(self.layout)
            self.children.append(self.caret)
        else:
            # If we have some highscores to show
            if highscores:
                # Show a title
                self.children.append(
                    Label('Highscores:',
                          font_name='m5x7',
                          font_size=48,
                          x=WIDTH / 2,
                          y=420,
                          align='center',
                          anchor_x='center',
                          anchor_y='bottom',
                          batch=self.ui_batch))
                # ... followed by each highscore
                for i, highscore in enumerate(highscores):
                    self.children.append(
                        Label(f'{highscore.name} - {highscore.score}',
                              font_name='m5x7',
                              font_size=32,
                              x=WIDTH / 2,
                              y=380 - i * 32,
                              align='center',
                              anchor_x='center',
                              anchor_y='bottom',
                              batch=self.ui_batch))

            # Show continue label, and make sure to have it below highscores if any
            self.continue_label = Label('Press SPACE to start game...',
                                        font_name='m5x7',
                                        font_size=48,
                                        x=WIDTH / 2,
                                        y=32 if highscores else HEIGHT / 4,
                                        align='center',
                                        anchor_x='center',
                                        anchor_y='bottom',
                                        batch=self.ui_batch)
            # Timer for blinking
            self.continue_timer = 0

            self.children.append(self.continue_label)

    def tick(self, dt: float):
        # If we have a continue label then blink it
        if self.continue_label:
            self.continue_timer += dt
            if self.continue_timer > 2:
                self.continue_timer = 0
            self.continue_label.color = blink(self.continue_timer,
                                              pytweening.easeInCubic,
                                              pytweening.easeOutCubic, 2,
                                              (255, 255, 255))

    def delete(self):
        # Make sure to also delete our children
        for child in self.children:
            child.delete()
        super().delete()

    def on_key_release(self, symbol, modifier):
        if self.add_score is None:
            # If we are not adding a score then if space was pressed, start the game
            if symbol == key.SPACE:
                self.cb_start_game()
        else:
            # If we are adding a score then when enter is pressed, submit
            # that highscore (which will then also go to next menu screen)
            if symbol == key.ENTER:
                self.cb_add_highscore(self.document.text, self.add_score)

    def on_text(self, text):
        if self.add_score is not None:
            # Make sure we don't add any newlines (layout is multiline but we never want more than 1 line)
            text = text.replace('\r', '\n')
            if text != '\n':
                # Add the text to the caret
                self.caret.on_text(text)
                # If the text is too long then send a backspace to delete last char
                if self.layout.lines[0].width + 20 > self.layout.width:
                    self.caret.on_text_motion(key.MOTION_BACKSPACE)

    def on_text_motion(self, motion, select=False):
        if self.add_score is not None:
            # Forward text motions to the caret
            self.caret.on_text_motion(motion, select)
Beispiel #10
0
class TextEntry(WidgetBase):
    def __init__(self,
                 text,
                 x,
                 y,
                 width,
                 color=(255, 255, 255, 255),
                 batch=None,
                 group=None):
        self._doc = pyglet.text.document.UnformattedDocument(text)
        self._doc.set_style(0, len(self._doc.text), dict(color=(0, 0, 0, 255)))
        font = self._doc.get_font()
        height = font.ascent - font.descent

        self._user_group = group
        bg_group = OrderedGroup(0, parent=group)
        fg_group = OrderedGroup(1, parent=group)

        # Rectangular outline:
        pad = 2
        x1 = x - pad
        y1 = y - pad
        x2 = x + width + pad
        y2 = y + height + pad
        self._outline = batch.add(4, pyglet.gl.GL_QUADS, bg_group,
                                  ('v2i', [x1, y1, x2, y1, x2, y2, x1, y2]),
                                  ('c4B', color * 4))
        # Text and Caret:
        self._layout = IncrementalTextLayout(self._doc,
                                             width,
                                             height,
                                             multiline=False,
                                             batch=batch,
                                             group=fg_group)
        self._caret = Caret(self._layout)
        self._caret.visible = False

        self._layout.x = x
        self._layout.y = y

        self._focus = False

        super().__init__(x, y, width, height)

    def _check_hit(self, x, y):
        return self._x < x < self._x + self._width and self._y < y < self._y + self._height

    def _set_focus(self, value):
        self._focus = value
        self._caret.visible = value

    def update_groups(self, order):
        self._outline.group = OrderedGroup(order + 1, self._user_group)
        self._layout.group = OrderedGroup(order + 2, self._user_group)

    def on_mouse_motion(self, x, y, dx, dy):
        if not self._check_hit(x, y):
            self._set_focus(False)

    def on_mouse_drag(self, x, y, dx, dy, buttons, modifiers):
        if self._focus:
            self._caret.on_mouse_drag(x, y, dx, dy, buttons, modifiers)

    def on_mouse_press(self, x, y, buttons, modifiers):
        if self._check_hit(x, y):
            self._set_focus(True)
            self._caret.on_mouse_press(x, y, buttons, modifiers)

    def on_text(self, text):
        if self._focus:
            if text in ('\r', '\n'):
                self.dispatch_event('on_commit', self._layout.document.text)
                self._set_focus(False)
                return
            self._caret.on_text(text)

    def on_text_motion(self, motion):
        if self._focus:
            self._caret.on_text_motion(motion)

    def on_text_motion_select(self, motion):
        if self._focus:
            self._caret.on_text_motion_select(motion)

    def on_commit(self, text):
        """Text has been commited via Enter/Return key."""
Beispiel #11
0
class DialogueEntry(Widget):

    def __init__(self):
        win_width, win_height = get_size()
        self.batch = Batch()
        self._doc = pyglet.text.document.UnformattedDocument('')
        self._doc.set_style(0, len(self._doc.text), dict(color=(255, 255, 255, 255)))
        font = self._doc.get_font()
        self.text_height = font.ascent - font.descent
        self.pad = 2
        self._outline = Rectangle(5 - self.pad, 20 - self.pad,
                get_size()[0] + self.pad - 5, self.text_height + self.pad, color=(0, 0, 0))
        self._outline.opacity = 150
        self._layout = IncrementalTextLayout(self._doc, get_size()[0] + self.pad - 5, self.text_height,
                multiline=False, batch=self.batch)
        self._caret = Caret(self._layout, color=(255, 255, 255))
        self._caret.visible = False
        self._layout.x = 5
        self._layout.y = 20
        self._focus = False
        self._press = False
        self.last_char = ''
        super().__init__(5, 20, get_size()[0] + self.pad - 5, self.text_height)

    def draw(self):
        self._outline.draw()
        self.batch.draw()

    def text(self, text):
        self._doc.text = text

    def _set_focus(self, value):
        self._focus = value
        self._caret.visible = value

    def on_mouse_drag(self, x, y, dx, dy, buttons, modifiers):
        if self._focus:
            self._caret.on_mouse_drag(x, y, dx, dy, buttons, modifiers)

    def on_mouse_motion(self, x, y, dx, dy):
        if self.check_hit(x, y):
            get_game().set_cursor('text')
        else:
            get_game().set_cursor()

    def on_mouse_press(self, x, y, buttons, modifiers):
        if self.check_hit(x, y):
            self._press = True
            self._set_focus(True)
            self._caret.on_mouse_press(x, y, buttons, modifiers)
        else:
            self._set_focus(False)

    def on_mouse_release(self, x, y, buttons, modifiers):
        if self._press:
            self._press = False

    def on_resize(self, width, height):
        self.width = width - self.pad - 5
        self._outline.width = width - self.pad - 5
        self._layout.width = width - self.pad - 5

    def on_text(self, text):
        if text == self.last_char:
            self.last_char = ''
            return
        else:
            self.last_char = text
        if self._focus:
            if text in ('\r', '\n'):
                self.dispatch_event('on_commit', self._layout.document.text)
                self._set_focus(False)
                return
            self._caret.on_text(text)

    def on_text_motion(self, motion):
        if self._focus:
            self._caret.on_text_motion(motion)

    def on_text_motion_select(self, motion):
        if self._focus:
            self._caret.on_text_motion_select(motion)

    def on_commit(self, text):
        pass
Beispiel #12
0
    def __init__(self, window,
                 x=0, y=0, width=100, height=100,
                 anchor_x='left', anchor_y='bottom',
                 style = Default['terminal'], prompt = '> ', banner = ''):
        '''Create a new console.

        :Parameters:
            `window` : pyglet.window.Window
                Window this console will be embedded in.
            `x` : int
                X coordinate of the console.
            `y` : int
                Y coordinate of the console.
            `width` : int
                Width of the console in pixels, or None
            `height` : int
                Height of the console in pixels, or None
            `anchor_x` : str
                Anchor point of the X coordinate: one of ``"left"``,
                ``"center"`` or ``"right"``.
            `anchor_y` : str
                Anchor point of the Y coordinate: one of ``"bottom"``,
                ``"center"`` or ``"top"``.
            `style` : dict
                Style dictionnary describing element styles
            `prompt` : str
                Console prompt
            `banner` : str
                Text to be displayed prior to any input.
        '''

        super(Console, self).__init__()
        self._window = window
        self._style = style
        self._prompt = prompt
        self._prompt_start, self._prompt_end = 0, 0
        batch = pyglet.graphics.Batch()
        document = Document()
        margin = self._style['margin']
        layout = Layout(document,
                        width=width-2*margin, height=height-2*margin,
                        multiline=True, batch=batch)
        layout.anchor_x = anchor_x
        layout.anchor_y = anchor_y
        layout.x = int(margin)
        layout.y = int(margin)
        layout.view_y = 0
        layout.selection_color = self._style['selection_fg']
        layout.selection_background_color = self._style['selection_bg']
        caret = Caret(layout)
        caret.position = 0
        caret.visible = True
        r,g,b,a = self._style['text_fg']
        caret.color = (r,g,b)
        self._batch = batch
        self._document = document
        self._layout = layout
        self._caret = caret
        x,y,z = int(layout.x-margin), int(layout.y-margin), -.5
        w,h = layout.width+2*margin, layout.height+2*margin
        self._background = batch.add(
            4, pyglet.gl.GL_QUADS, None,
            ('v3f', (x,y,z, x+w,y,z, x+w,y+h,z,  x,y+h,z)),
            ('c4B', self._style['text_bg']*4))
        z += .1
        self._border = batch.add(
            4, pyglet.gl.GL_LINE_LOOP, None,
            ('v3f', (x,y,z, x+w,y,z, x+w,y+h,z,  x,y+h,z)),
            ('c4B', self._style['border_fg']*4))
        if banner:
            self.write(banner)
        if window:
            self._cursor = window.get_system_mouse_cursor('text')
        else:
            self._cursor = None
        self.resize(width,height)
Beispiel #13
0
class TextEntry(Widget):

    def __init__(self, text, color, x, y, width, pad=3):
        win_width, win_height = get_size()
        self.batch = Batch()
        self._doc = pyglet.text.document.UnformattedDocument(text)
        self._doc.set_style(0, len(self._doc.text), dict(color=(255, 255, 255, 255)))
        font = self._doc.get_font()
        self.text_height = font.ascent - font.descent
        self.pad = pad
        self._outline = BorderedRectangle(x - self.pad, win_height - y - self.pad,
                width + self.pad, self.text_height + self.pad, color=color[:3], border_color=(100, 100, 100))
        self._outline.opacity = color[-1]
        self._layout = IncrementalTextLayout(width, self.text_height,
                multiline=False, batch=self.batch)
        self._caret = Caret(self._layout, color=(255, 255, 255))
        self._caret.visible = False
        self._layout.x = x
        self._layout.y = win_height - y
        self._focus = False
        self._press = False
        self.last_char = ''
        super().__init__(x, win_height - y, width, height)

    def draw(self):
        self._outline.draw()
        self.batch.draw()

    def text(self, text):
        self._doc.text = text

    def _set_focus(self, value):
        self._focus = value
        self._caret.visible = value

    def on_mouse_drag(self, x, y, dx, dy, buttons, modifiers):
        if self._focus:
            self._caret.on_mouse_drag(x, y, dx, dy, buttons, modifiers)

    def on_mouse_motion(self, x, y, dx, dy):
        if self.check_hit(x, y):
            get_game().set_cursor('text')
        else:
            get_game().set_cursor()

    def on_mouse_press(self, x, y, buttons, modifiers):
        if self.check_hit(x, y):
            self._press = True
            self._set_focus(True)
            self._caret.on_mouse_press(x, y, buttons, modifiers)
        else:
            self._set_focus(False)

    def on_mouse_release(self, x, y, buttons, modifiers):
        if self._press:
            self._press = False

    def on_text(self, text):
        if text == self.last_char:
            self.last_char = ''
            return
        else:
            self.last_char = text
        if self._focus:
            if text in ('\r', '\n'):
                self.dispatch_event('on_commit', self._layout.document.text)
                self._set_focus(False)
                return
            self._caret.on_text(text)

    def on_text_motion(self, motion):
        if self._focus:
            self._caret.on_text_motion(motion)

    def on_text_motion_select(self, motion):
        if self._focus:
            self._caret.on_text_motion_select(motion)

    def on_commit(self, text):
        pass
    def __init__(self,
                 *,
                 highscores,
                 ui_batch,
                 cb_start_game=None,
                 cb_add_highscore=None,
                 add_score=None):
        super().__init__()

        # Make sure we can handle events
        self.event_handlers = [self]

        # Store callbacks, the ui batch and our optional score3
        self.cb_start_game = cb_start_game
        self.cb_add_highscore = cb_add_highscore
        self.ui_batch = ui_batch
        self.add_score = add_score

        # We need to keep track of our children so we can remove them in self.delete()
        self.children = []

        # Show title
        self.children.append(
            Label('WELCOME TO',
                  font_name='m5x7',
                  font_size=128,
                  x=WIDTH / 2,
                  y=HEIGHT - 16,
                  anchor_x='center',
                  anchor_y='top',
                  batch=self.ui_batch))
        self.children.append(
            Label('HELL',
                  font_name='m5x7',
                  font_size=512,
                  x=WIDTH / 2 + 50,
                  y=HEIGHT,
                  anchor_x='center',
                  anchor_y='top',
                  batch=self.ui_batch))

        # If we need to add a score
        if add_score is not None:
            # Make sure that self.continue_label exists so we don't crash in self.tick()
            self.continue_label = None

            # Show some text
            self.children.append(
                Label('Your score was:',
                      font_name='m5x7',
                      font_size=48,
                      x=WIDTH / 2,
                      y=400,
                      align='center',
                      anchor_x='center',
                      anchor_y='bottom',
                      batch=self.ui_batch))
            self.children.append(
                Label(f'{add_score}',
                      font_name='m5x7',
                      font_size=128,
                      x=WIDTH / 2,
                      y=280,
                      align='center',
                      anchor_x='center',
                      anchor_y='bottom',
                      batch=self.ui_batch))
            self.children.append(
                Label('Enter name for highscore:',
                      font_name='m5x7',
                      font_size=32,
                      x=WIDTH / 2,
                      y=200,
                      align='center',
                      anchor_x='center',
                      anchor_y='bottom',
                      batch=self.ui_batch))

            # Prepare a document with styling
            self.document = UnformattedDocument()
            self.document.set_style(
                0, 1, {
                    'font_name': 'm5x7',
                    'font_size': 64,
                    'color': (255, 255, 255, 255),
                    'align': 'center'
                })
            # Find the height of the font
            font = self.document.get_font()
            height = font.ascent - font.descent
            # Make a TextLayout that handles dynamically adding text
            # Make it multiline even though we don't want multiple lines because otherwise align=center doesn't work
            self.layout = IncrementalTextLayout(self.document,
                                                WIDTH / 3,
                                                height,
                                                multiline=True,
                                                batch=self.ui_batch)
            self.layout.anchor_y = 'top'
            self.layout.anchor_x = 'center'
            self.layout.x = WIDTH / 2
            self.layout.y = 200
            # Add a carat (cursor)
            self.caret = Caret(self.layout,
                               batch=self.ui_batch,
                               color=(255, 255, 255))
            # Type q and then backspace
            # This ensures that the carat is visible as it only shows up after something has been typed
            self.caret.on_text('q')
            self.caret.on_text_motion(key.MOTION_BACKSPACE)
            # Make sure we can delete layout and carat in self.delete()
            self.children.append(self.layout)
            self.children.append(self.caret)
        else:
            # If we have some highscores to show
            if highscores:
                # Show a title
                self.children.append(
                    Label('Highscores:',
                          font_name='m5x7',
                          font_size=48,
                          x=WIDTH / 2,
                          y=420,
                          align='center',
                          anchor_x='center',
                          anchor_y='bottom',
                          batch=self.ui_batch))
                # ... followed by each highscore
                for i, highscore in enumerate(highscores):
                    self.children.append(
                        Label(f'{highscore.name} - {highscore.score}',
                              font_name='m5x7',
                              font_size=32,
                              x=WIDTH / 2,
                              y=380 - i * 32,
                              align='center',
                              anchor_x='center',
                              anchor_y='bottom',
                              batch=self.ui_batch))

            # Show continue label, and make sure to have it below highscores if any
            self.continue_label = Label('Press SPACE to start game...',
                                        font_name='m5x7',
                                        font_size=48,
                                        x=WIDTH / 2,
                                        y=32 if highscores else HEIGHT / 4,
                                        align='center',
                                        anchor_x='center',
                                        anchor_y='bottom',
                                        batch=self.ui_batch)
            # Timer for blinking
            self.continue_timer = 0

            self.children.append(self.continue_label)
class TextEntry(WidgetBase):
    """Instance of a text entry widget.

    Allows the user to enter and submit text.
    """
    def __init__(self,
                 text,
                 x,
                 y,
                 width,
                 color=(255, 255, 255, 255),
                 text_color=(0, 0, 0, 255),
                 caret_color=(0, 0, 0),
                 batch=None,
                 group=None):
        """Create a text entry widget.

        :Parameters:
            `text` : str
                Initial text to display.
            `x` : int
                X coordinate of the text entry widget.
            `y` : int
                Y coordinate of the text entry widget.
            `width` : int
                The width of the text entry widget.
            `color` : (int, int, int, int)
                The color of the outline box in RGBA format.
            `text_color` : (int, int, int, int)
                The color of the text in RGBA format.
            `text_color` : (int, int, int)
                The color of the caret in RGB format.
            `batch` : `~pyglet.graphics.Batch`
                Optional batch to add the text entry widget to.
            `group` : `~pyglet.graphics.Group`
                Optional parent group of text entry widget.
        """
        self._doc = pyglet.text.document.UnformattedDocument(text)
        self._doc.set_style(0, len(self._doc.text), dict(color=text_color))
        font = self._doc.get_font()
        height = font.ascent - font.descent

        self._user_group = group
        bg_group = Group(order=0, parent=group)
        fg_group = Group(order=1, parent=group)

        # Rectangular outline with 2-pixel pad:
        self._pad = p = 2
        self._outline = pyglet.shapes.Rectangle(x - p, y - p, width + p + p,
                                                height + p + p, color[:3],
                                                batch, bg_group)
        self._outline.opacity = color[3]

        # Text and Caret:
        self._layout = IncrementalTextLayout(self._doc,
                                             width,
                                             height,
                                             multiline=False,
                                             batch=batch,
                                             group=fg_group)
        self._layout.x = x
        self._layout.y = y
        self._caret = Caret(self._layout, color=caret_color)
        self._caret.visible = False

        self._focus = False

        super().__init__(x, y, width, height)

    def _update_position(self):
        self._layout.position = self._x, self._y
        self._outline.position = self._x - self._pad, self._y - self._pad

    @property
    def value(self):
        return self._doc.text

    @value.setter
    def value(self, value):
        assert type(value) is str, "This Widget's value must be a string."
        self._doc.text = value

    def _check_hit(self, x, y):
        return self._x < x < self._x + self._width and self._y < y < self._y + self._height

    def _set_focus(self, value):
        self._focus = value
        self._caret.visible = value

    def update_groups(self, order):
        self._outline.group = Group(order=order + 1, parent=self._user_group)
        self._layout.group = Group(order=order + 2, parent=self._user_group)

    def on_mouse_motion(self, x, y, dx, dy):
        if not self.enabled:
            return
        if not self._check_hit(x, y):
            self._set_focus(False)

    def on_mouse_drag(self, x, y, dx, dy, buttons, modifiers):
        if not self.enabled:
            return
        if self._focus:
            self._caret.on_mouse_drag(x, y, dx, dy, buttons, modifiers)

    def on_mouse_press(self, x, y, buttons, modifiers):
        if not self.enabled:
            return
        if self._check_hit(x, y):
            self._set_focus(True)
            self._caret.on_mouse_press(x, y, buttons, modifiers)

    def on_text(self, text):
        if not self.enabled:
            return
        if self._focus:
            if text in ('\r', '\n'):
                self.dispatch_event('on_commit', self._layout.document.text)
                self._set_focus(False)
                return
            self._caret.on_text(text)

    def on_text_motion(self, motion):
        if not self.enabled:
            return
        if self._focus:
            self._caret.on_text_motion(motion)

    def on_text_motion_select(self, motion):
        if not self.enabled:
            return
        if self._focus:
            self._caret.on_text_motion_select(motion)

    def on_commit(self, text):
        if not self.enabled:
            return
        """Text has been commited via Enter/Return key."""
Beispiel #16
0
class DialogueEntry(Widget):
    def __init__(self):
        win_width, win_height = get_size()
        self.batch = Batch()
        self._doc = pyglet.text.document.UnformattedDocument('')
        self._doc.set_style(0, len(self._doc.text),
                            dict(color=(255, 255, 255, 255)))
        font = self._doc.get_font()
        self.text_height = font.ascent - font.descent
        self.pad = 2
        self._outline = Rectangle(5,
                                  5 + self.pad,
                                  get_size()[0] - self.pad - 10,
                                  self.text_height + self.pad,
                                  color=(0, 0, 0))
        self._outline.opacity = 150
        self._layout = IncrementalTextLayout(self._doc,
                                             get_size()[0] - 14,
                                             self.text_height,
                                             multiline=False,
                                             batch=self.batch)
        self._caret = Caret(self._layout, color=(255, 255, 255))
        self._caret.visible = False
        self._layout.x = 5
        self._layout.y = 5 + self.pad
        self._focus = False
        self._press = False
        self.last_press = [0, 0]
        super().__init__(5, 5 + self.pad,
                         get_size()[0] - self.pad - 10,
                         self.text_height + self.pad)

    def draw(self):
        self._outline.draw()
        self.batch.draw()

    def text(self, text):
        self._doc.text = text

    def _set_focus(self, value):
        self._focus = value
        self._caret.visible = value

    def on_key_press(self, symbol, modifiers):
        if symbol == key.PAGEUP:
            if self.last_press[0] == 1:
                self.last_press[0] = 0
                return
            else:
                self.last_press[0] = 1
                self.text('')
                self.text(
                    get_game().dialogue.history[get_game().dialogue.pointer])
                if get_game().dialogue.pointer != 0:
                    get_game().dialogue.pointer -= 1
        elif symbol == key.PAGEDOWN:
            if self.last_press[1] == 1:
                self.last_press[1] = 0
                return
            else:
                self.last_press[1] = 1
                if get_game().dialogue.pointer != len(
                        get_game().dialogue.history) - 1:
                    get_game().dialogue.pointer += 1
                    self.text('')
                    self.text(get_game().dialogue.history[
                        get_game().dialogue.pointer])
                else:
                    self.text('')

    def on_mouse_drag(self, x, y, dx, dy, buttons, modifiers):
        if self._focus:
            self._caret.on_mouse_drag(x, y, dx, dy, buttons, modifiers)

    def on_mouse_motion(self, x, y, dx, dy):
        if self.check_hit(x, y):
            get_game().set_cursor('text')
        else:
            get_game().set_cursor()

    def on_mouse_press(self, x, y, buttons, modifiers):
        if self.check_hit(x, y):
            self._press = True
            self._set_focus(True)
            self._caret.on_mouse_press(x, y, buttons, modifiers)
        else:
            self._set_focus(False)

    def on_mouse_release(self, x, y, buttons, modifiers):
        if self._press:
            self._press = False

    def on_resize(self, width, height):
        self.width = width - self.pad - 10
        self._outline.width = width - self.pad - 10
        self._layout.width = width - self.pad - 10

    def on_text(self, text):
        if self._focus:
            if text in ('\r', '\n'):
                self.dispatch_event('on_commit', self._layout.document.text)
                self._set_focus(False)
                return
            self._caret.on_text(text)

    def on_text_motion(self, motion):
        if self._focus:
            self._caret.on_text_motion(motion)

    def on_text_motion_select(self, motion):
        if self._focus:
            self._caret.on_text_motion_select(motion)

    def on_commit(self, text):
        pass
    def __init__(self,
                 text,
                 x,
                 y,
                 width,
                 color=(255, 255, 255, 255),
                 text_color=(0, 0, 0, 255),
                 caret_color=(0, 0, 0),
                 batch=None,
                 group=None):
        """Create a text entry widget.

        :Parameters:
            `text` : str
                Initial text to display.
            `x` : int
                X coordinate of the text entry widget.
            `y` : int
                Y coordinate of the text entry widget.
            `width` : int
                The width of the text entry widget.
            `color` : (int, int, int, int)
                The color of the outline box in RGBA format.
            `text_color` : (int, int, int, int)
                The color of the text in RGBA format.
            `text_color` : (int, int, int)
                The color of the caret in RGB format.
            `batch` : `~pyglet.graphics.Batch`
                Optional batch to add the text entry widget to.
            `group` : `~pyglet.graphics.Group`
                Optional parent group of text entry widget.
        """
        self._doc = pyglet.text.document.UnformattedDocument(text)
        self._doc.set_style(0, len(self._doc.text), dict(color=text_color))
        font = self._doc.get_font()
        height = font.ascent - font.descent

        self._user_group = group
        bg_group = Group(order=0, parent=group)
        fg_group = Group(order=1, parent=group)

        # Rectangular outline with 2-pixel pad:
        self._pad = p = 2
        self._outline = pyglet.shapes.Rectangle(x - p, y - p, width + p + p,
                                                height + p + p, color[:3],
                                                batch, bg_group)
        self._outline.opacity = color[3]

        # Text and Caret:
        self._layout = IncrementalTextLayout(self._doc,
                                             width,
                                             height,
                                             multiline=False,
                                             batch=batch,
                                             group=fg_group)
        self._layout.x = x
        self._layout.y = y
        self._caret = Caret(self._layout, color=caret_color)
        self._caret.visible = False

        self._focus = False

        super().__init__(x, y, width, height)