1#!/usr/bin/env python 2 3"""Demonstrates basic use of IncrementalTextLayout and Caret. 4 5A simple widget-like system is created in this example supporting keyboard and 6mouse focus. 7""" 8 9__docformat__ = 'restructuredtext' 10__version__ = '$Id: $' 11 12import pyglet 13 14 15class Rectangle: 16 """Draws a rectangle into a batch.""" 17 def __init__(self, x1, y1, x2, y2, batch): 18 self.vertex_list = batch.add(4, pyglet.gl.GL_QUADS, None, 19 ('v2i', [x1, y1, x2, y1, x2, y2, x1, y2]), 20 ('c4B', [200, 200, 220, 255] * 4)) 21 22 23class TextWidget: 24 def __init__(self, text, x, y, width, batch): 25 self.document = pyglet.text.document.UnformattedDocument(text) 26 self.document.set_style(0, len(self.document.text), dict(color=(0, 0, 0, 255))) 27 font = self.document.get_font() 28 height = font.ascent - font.descent 29 30 self.layout = pyglet.text.layout.IncrementalTextLayout( 31 self.document, width, height, multiline=False, batch=batch) 32 self.caret = pyglet.text.caret.Caret(self.layout) 33 34 self.layout.x = x 35 self.layout.y = y 36 37 # Rectangular outline 38 pad = 2 39 self.rectangle = Rectangle(x - pad, y - pad, 40 x + width + pad, y + height + pad, batch) 41 42 def hit_test(self, x, y): 43 return (0 < x - self.layout.x < self.layout.width and 44 0 < y - self.layout.y < self.layout.height) 45 46 47class Window(pyglet.window.Window): 48 def __init__(self, *args, **kwargs): 49 super(Window, self).__init__(400, 140, caption='Text entry') 50 51 self.batch = pyglet.graphics.Batch() 52 self.labels = [ 53 pyglet.text.Label('Name', x=10, y=100, anchor_y='bottom', 54 color=(0, 0, 0, 255), batch=self.batch), 55 pyglet.text.Label('Species', x=10, y=60, anchor_y='bottom', 56 color=(0, 0, 0, 255), batch=self.batch), 57 pyglet.text.Label('Special abilities', x=10, y=20, 58 anchor_y='bottom', color=(0, 0, 0, 255), 59 batch=self.batch) 60 ] 61 self.widgets = [ 62 TextWidget('', 200, 100, self.width - 210, self.batch), 63 TextWidget('', 200, 60, self.width - 210, self.batch), 64 TextWidget('', 200, 20, self.width - 210, self.batch) 65 ] 66 self.text_cursor = self.get_system_mouse_cursor('text') 67 68 self.focus = None 69 self.set_focus(self.widgets[0]) 70 71 def on_resize(self, width, height): 72 super(Window, self).on_resize(width, height) 73 for widget in self.widgets: 74 widget.width = width - 110 75 76 def on_draw(self): 77 pyglet.gl.glClearColor(1, 1, 1, 1) 78 self.clear() 79 self.batch.draw() 80 81 def on_mouse_motion(self, x, y, dx, dy): 82 for widget in self.widgets: 83 if widget.hit_test(x, y): 84 self.set_mouse_cursor(self.text_cursor) 85 break 86 else: 87 self.set_mouse_cursor(None) 88 89 def on_mouse_press(self, x, y, button, modifiers): 90 for widget in self.widgets: 91 if widget.hit_test(x, y): 92 self.set_focus(widget) 93 break 94 else: 95 self.set_focus(None) 96 97 if self.focus: 98 self.focus.caret.on_mouse_press(x, y, button, modifiers) 99 100 def on_mouse_drag(self, x, y, dx, dy, buttons, modifiers): 101 if self.focus: 102 self.focus.caret.on_mouse_drag(x, y, dx, dy, buttons, modifiers) 103 104 def on_text(self, text): 105 if self.focus: 106 self.focus.caret.on_text(text) 107 108 def on_text_motion(self, motion): 109 if self.focus: 110 self.focus.caret.on_text_motion(motion) 111 112 def on_text_motion_select(self, motion): 113 if self.focus: 114 self.focus.caret.on_text_motion_select(motion) 115 116 def on_key_press(self, symbol, modifiers): 117 if symbol == pyglet.window.key.TAB: 118 if modifiers & pyglet.window.key.MOD_SHIFT: 119 direction = -1 120 else: 121 direction = 1 122 123 if self.focus in self.widgets: 124 i = self.widgets.index(self.focus) 125 else: 126 i = 0 127 direction = 0 128 129 self.set_focus(self.widgets[(i + direction) % len(self.widgets)]) 130 131 elif symbol == pyglet.window.key.ESCAPE: 132 pyglet.app.exit() 133 134 def set_focus(self, focus): 135 if focus is self.focus: 136 return 137 138 if self.focus: 139 self.focus.caret.visible = False 140 self.focus.caret.mark = self.focus.caret.position = 0 141 142 self.focus = focus 143 if self.focus: 144 self.focus.caret.visible = True 145 146 147window = Window(resizable=True) 148pyglet.app.run() 149