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