Initial Commit

This commit is contained in:
NSasquatch 2016-11-10 18:51:57 +01:00
commit cc092fa01d
8 changed files with 367 additions and 0 deletions

Binary file not shown.

Binary file not shown.

151
eztext.py Normal file
View File

@ -0,0 +1,151 @@
# input lib
from pygame.locals import *
import pygame, string
from pygame.locals import *
class ConfigError(KeyError): pass
class Config:
""" A utility for configuration """
def __init__(self, options, *look_for):
assertions = []
for key in look_for:
if key[0] in options.keys(): exec('self.'+key[0]+' = options[\''+key[0]+'\']')
else: exec('self.'+key[0]+' = '+key[1])
assertions.append(key[0])
for key in options.keys():
if key not in assertions: raise ConfigError(key+' not expected as option')
class Input:
""" A text input for pygame apps """
def __init__(self, **options):
""" Options: x, y, font, color, restricted, maxlength, prompt """
self.options = Config(options, ['x', '0'], ['y', '0'], ['font', 'pygame.font.Font(None, 32)'],
['color', '(0,0,0)'], ['restricted', '\'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!"#$%&\\\'()*+,-./:;<=>?@[\]^_`{|}~\''],
['maxlength', '-1'], ['prompt', '\'\''])
self.x = self.options.x; self.y = self.options.y
self.font = self.options.font
self.color = self.options.color
self.restricted = self.options.restricted
self.maxlength = self.options.maxlength
self.prompt = self.options.prompt; self.value = ''
self.shifted = False
def set_pos(self, x, y):
""" Set the position to x, y """
self.x = x
self.y = y
def set_font(self, font):
""" Set the font for the input """
self.font = font
def draw(self, surface):
""" Draw the text input to a surface """
text = self.font.render(self.prompt+self.value, 1, self.color)
surface.blit(text, (self.x, self.y))
def update(self, events):
""" Update the input based on passed events """
for event in events:
if event.type == KEYUP:
if event.key == K_LSHIFT or event.key == K_RSHIFT: self.shifted = False
if event.type == KEYDOWN:
if event.key == K_BACKSPACE: self.value = self.value[:-1]
elif event.key == K_LSHIFT or event.key == K_RSHIFT: self.shifted = True
elif event.key == K_SPACE: self.value += ' '
if not self.shifted:
if event.key == K_a and 'a' in self.restricted: self.value += 'a'
elif event.key == K_b and 'b' in self.restricted: self.value += 'b'
elif event.key == K_c and 'c' in self.restricted: self.value += 'c'
elif event.key == K_d and 'd' in self.restricted: self.value += 'd'
elif event.key == K_e and 'e' in self.restricted: self.value += 'e'
elif event.key == K_f and 'f' in self.restricted: self.value += 'f'
elif event.key == K_g and 'g' in self.restricted: self.value += 'g'
elif event.key == K_h and 'h' in self.restricted: self.value += 'h'
elif event.key == K_i and 'i' in self.restricted: self.value += 'i'
elif event.key == K_j and 'j' in self.restricted: self.value += 'j'
elif event.key == K_k and 'k' in self.restricted: self.value += 'k'
elif event.key == K_l and 'l' in self.restricted: self.value += 'l'
elif event.key == K_m and 'm' in self.restricted: self.value += 'm'
elif event.key == K_n and 'n' in self.restricted: self.value += 'n'
elif event.key == K_o and 'o' in self.restricted: self.value += 'o'
elif event.key == K_p and 'p' in self.restricted: self.value += 'p'
elif event.key == K_q and 'q' in self.restricted: self.value += 'q'
elif event.key == K_r and 'r' in self.restricted: self.value += 'r'
elif event.key == K_s and 's' in self.restricted: self.value += 's'
elif event.key == K_t and 't' in self.restricted: self.value += 't'
elif event.key == K_u and 'u' in self.restricted: self.value += 'u'
elif event.key == K_v and 'v' in self.restricted: self.value += 'v'
elif event.key == K_w and 'w' in self.restricted: self.value += 'w'
elif event.key == K_x and 'x' in self.restricted: self.value += 'x'
elif event.key == K_y and 'y' in self.restricted: self.value += 'y'
elif event.key == K_z and 'z' in self.restricted: self.value += 'z'
elif event.key == K_0 and '0' in self.restricted: self.value += '0'
elif event.key == K_1 and '1' in self.restricted: self.value += '1'
elif event.key == K_2 and '2' in self.restricted: self.value += '2'
elif event.key == K_3 and '3' in self.restricted: self.value += '3'
elif event.key == K_4 and '4' in self.restricted: self.value += '4'
elif event.key == K_5 and '5' in self.restricted: self.value += '5'
elif event.key == K_6 and '6' in self.restricted: self.value += '6'
elif event.key == K_7 and '7' in self.restricted: self.value += '7'
elif event.key == K_8 and '8' in self.restricted: self.value += '8'
elif event.key == K_9 and '9' in self.restricted: self.value += '9'
elif event.key == K_BACKQUOTE and '`' in self.restricted: self.value += '`'
elif event.key == K_MINUS and '-' in self.restricted: self.value += '-'
elif event.key == K_EQUALS and '=' in self.restricted: self.value += '='
elif event.key == K_LEFTBRACKET and '[' in self.restricted: self.value += '['
elif event.key == K_RIGHTBRACKET and ']' in self.restricted: self.value += ']'
elif event.key == K_BACKSLASH and '\\' in self.restricted: self.value += '\\'
elif event.key == K_SEMICOLON and ';' in self.restricted: self.value += ';'
elif event.key == K_QUOTE and '\'' in self.restricted: self.value += '\''
elif event.key == K_COMMA and ',' in self.restricted: self.value += ','
elif event.key == K_PERIOD and '.' in self.restricted: self.value += '.'
elif event.key == K_SLASH and '/' in self.restricted: self.value += '/'
elif self.shifted:
if event.key == K_a and 'A' in self.restricted: self.value += 'A'
elif event.key == K_b and 'B' in self.restricted: self.value += 'B'
elif event.key == K_c and 'C' in self.restricted: self.value += 'C'
elif event.key == K_d and 'D' in self.restricted: self.value += 'D'
elif event.key == K_e and 'E' in self.restricted: self.value += 'E'
elif event.key == K_f and 'F' in self.restricted: self.value += 'F'
elif event.key == K_g and 'G' in self.restricted: self.value += 'G'
elif event.key == K_h and 'H' in self.restricted: self.value += 'H'
elif event.key == K_i and 'I' in self.restricted: self.value += 'I'
elif event.key == K_j and 'J' in self.restricted: self.value += 'J'
elif event.key == K_k and 'K' in self.restricted: self.value += 'K'
elif event.key == K_l and 'L' in self.restricted: self.value += 'L'
elif event.key == K_m and 'M' in self.restricted: self.value += 'M'
elif event.key == K_n and 'N' in self.restricted: self.value += 'N'
elif event.key == K_o and 'O' in self.restricted: self.value += 'O'
elif event.key == K_p and 'P' in self.restricted: self.value += 'P'
elif event.key == K_q and 'Q' in self.restricted: self.value += 'Q'
elif event.key == K_r and 'R' in self.restricted: self.value += 'R'
elif event.key == K_s and 'S' in self.restricted: self.value += 'S'
elif event.key == K_t and 'T' in self.restricted: self.value += 'T'
elif event.key == K_u and 'U' in self.restricted: self.value += 'U'
elif event.key == K_v and 'V' in self.restricted: self.value += 'V'
elif event.key == K_w and 'W' in self.restricted: self.value += 'W'
elif event.key == K_x and 'X' in self.restricted: self.value += 'X'
elif event.key == K_y and 'Y' in self.restricted: self.value += 'Y'
elif event.key == K_z and 'Z' in self.restricted: self.value += 'Z'
elif event.key == K_0 and ')' in self.restricted: self.value += ')'
elif event.key == K_1 and '!' in self.restricted: self.value += '!'
elif event.key == K_2 and '@' in self.restricted: self.value += '@'
elif event.key == K_3 and '#' in self.restricted: self.value += '#'
elif event.key == K_4 and '$' in self.restricted: self.value += '$'
elif event.key == K_5 and '%' in self.restricted: self.value += '%'
elif event.key == K_6 and '^' in self.restricted: self.value += '^'
elif event.key == K_7 and '&' in self.restricted: self.value += '&'
elif event.key == K_8 and '*' in self.restricted: self.value += '*'
elif event.key == K_9 and '(' in self.restricted: self.value += '('
elif event.key == K_BACKQUOTE and '~' in self.restricted: self.value += '~'
elif evelif event.key == K_RIGHTBRACKET and '}' in self.restricted: self.value += '}'
elif event.key == K_BACKSLASH and '|' in self.restricted: self.value += '|'
elif event.key == K_SEMICOLON and ':' in self.restricted: self.value += ':'
elif event.key == K_QUOTE and '"' in self.restricted: self.value += '"'
elif event.key == K_COMMA and '<' in self.restricted: self.value += '<'
elif event.key == K_PERIOD and '>' in self.restricted: self.value += '>'
elif event.key == K_SLASH and '?' in self.restricted: self.value += '?'
if len(self.value) > self.maxlength and self.maxlength >= 0: self.value = self.value[:-1]

BIN
eztext.pyc Normal file

Binary file not shown.

29
main.py Normal file
View File

@ -0,0 +1,29 @@
#!/usr/bin/python3
import textinput
import pygame
pygame.init()
textinput_obj = textinput.TextInput(font_family="Ubuntu")
screen = pygame.display.set_mode((1000, 200))
clock = pygame.time.Clock()
color_switch = True
while True:
screen.fill((225, 225, 225))
color_switch = not color_switch
events = pygame.event.get()
for event in events:
if event.type == pygame.QUIT:
exit()
# Space to do things
value = textinput_obj.update(events)
if value: print(value)
screen.blit(textinput_obj.get_surface(), (10, 10))
pygame.display.update()
clock.tick(30)

View File

@ -0,0 +1,35 @@
import pygame
# Font module of pygame must be initialized before it can be used:
pygame.font.init()
class InputHandler:
def __init__(self, surface_size, fontname=None, fontsize=12):
"""
(WIP DOCS)
* Removes all KEYDOWN events from the event queue
"""
self.text_array = []
self.font_object = pygame.font.Font(pygamge.font.match_font(fontname), fontsize)
self.rerender = False # If True the surface gets rerendered
self.text_color = 1, 1, 1
self.cursor_pos = 0 # pos in text_array
self.cursor_blinking_speed = 500 #ms
self.cursor_visible = False
self.cursor_time_counter = 0
self.cursor_surface = pygame.Surface(self.font_object.size("|"))
self.surface = pygame.Surface(surface_size)
def update(self, dt):
# Update visual representation of cursor:
self.cursor_time_counter += dt
if self.cursor_time_counter >= self.cursor_blinking_speed:
self.cursor_visible = not self.cursor_visible
self.rerender = True
for key in pygame.event.get(pygame.KEYDOWN):
key

View File

@ -0,0 +1,6 @@
import pygame
from pygame.locals import *
from InputHandler import *
__all__ = []

146
textinput.py Normal file
View File

@ -0,0 +1,146 @@
import pygame, string
import pygame.locals as pl
pygame.font.init()
class TextInput:
"""
This class lets the user input a piece of text, e.g. a name or a message.
This class let's the user input a short, one-lines piece of text at a blinking cursor
that can be moved using the arrow-keys.
"""
def __init__(self, font_family = "",
font_size = 35,
antialias=True,
text_color=(0, 0, 0),
cursor_color=(0, 0, 1),
repeat_keys_initial_ms=400,
repeat_keys_interval_ms=35):
"""
Args:
font_family: Name or path of the font that should be used. Default is pygame-font
font_size: Size of the font in pixels
antialias: (bool) Determines if antialias is used on fonts or not
text_color: Color of the text
repeat_keys_initial_ms: ms until the keydowns get repeated when a key is not released
repeat_keys_interval_ms: ms between to keydown-repeats if key is not released
"""
# Text related vars:
self.antialias = antialias
self.text_color = text_color
self.font_size = font_size
self.input_string = "" # Inputted text
self.font_object = pygame.font.Font(pygame.font.match_font(font_family), font_size)
# Text-surface will be created during the first update call:
self.surface = pygame.Surface((1, 1))
self.surface.set_alpha(0)
# Vars to make keydowns repeat after user pressed a key for some time:
self.keyrepeat_counters = {} # {event.key: (counter_int, event.unicode)} (look for "***")
self.keyrepeat_intial_interval_ms = repeat_keys_initial_ms
self.keyrepeat_interval_ms = repeat_keys_interval_ms
# Things cursor:
self.cursor_surface = pygame.Surface((int(self.font_size/20+1), self.font_size))
self.cursor_surface.fill(cursor_color)
self.cursor_position = 0 # Inside text
self.cursor_visible = True # Switches every self.cursor_switch_ms ms
self.cursor_switch_ms = 500 # /|\
self.cursor_ms_counter = 0
self.clock = pygame.time.Clock()
def update(self, events):
for event in events:
if event.type == pygame.KEYDOWN:
self.cursor_visible = True # To see better where we are:
# If none exist, create counter for that key:
if not event.key in self.keyrepeat_counters:
self.keyrepeat_counters[event.key] = [0, event.unicode]
if event.key == pl.K_BACKSPACE:
self.input_string = self.input_string[:self.cursor_position - 1] + \
self.input_string[self.cursor_position:]
self.cursor_position -= 1
elif event.key == pl.K_DELETE:
self.input_string = self.input_string[:self.cursor_position] + \
self.input_string[self.cursor_position + 1:]
elif event.key == pl.K_RETURN:
return self.input_string
elif event.key == pl.K_RIGHT:
# Add one to cursor_pos, but do not exceed len(input_string)
self.cursor_position = min(self.cursor_position + 1, len(self.input_string))
elif event.key == pl.K_LEFT:
# Subtract one from cursor_pos, but do not go below zero:
self.cursor_position = max(self.cursor_position - 1, 0)
elif event.key == pl.K_END:
self.cursor_position = len(self.input_string)
elif event.key == pl.K_HOME:
self.cursor_position = 0
else:
self.input_string = self.input_string[:self.cursor_position] + \
event.unicode + \
self.input_string[self.cursor_position:]
self.cursor_position += len(event.unicode) # Some are empty, e.g. K_UP
elif event.type == pl.KEYUP:
# *** Because KEYUP doesn't include event.unicode, this dict is stored in such a weird way
if event.key in self.keyrepeat_counters:
del self.keyrepeat_counters[event.key]
# Update key counters:
for key in self.keyrepeat_counters :
self.keyrepeat_counters[key][0] += self.clock.get_time() # Update clock
# Generate new key events if enough time has passed:
if self.keyrepeat_counters[key][0] >= self.keyrepeat_intial_interval_ms:
self.keyrepeat_counters[key][0] = self.keyrepeat_intial_interval_ms - \
self.keyrepeat_interval_ms
event_key, event_unicode = key, self.keyrepeat_counters[key][1]
pygame.event.post(pygame.event.Event(pl.KEYDOWN, key=event_key, unicode=event_unicode))
# Rerender text surface:
self.surface = self.font_object.render(self.input_string, self.antialias, self.text_color)
# Update self.cursor_visible
self.cursor_ms_counter += self.clock.get_time()
if self.cursor_ms_counter >= self.cursor_switch_ms:
self.cursor_ms_counter %= self.cursor_switch_ms
self.cursor_visible = not self.cursor_visible
# Render cursor
if self.cursor_visible:
cursor_y_pos = self.font_object.size(self.input_string[:self.cursor_position])[0]
# Without this, the cursor is invisible when self.cursor_position > 0:
if self.cursor_position > 0:
cursor_y_pos -= self.cursor_surface.get_width()
self.surface.blit(self.cursor_surface, (cursor_y_pos, 0))
self.clock.tick()
return False
def get_surface(self):
return self.surface
def get_text(self):
return self.input_string
def get_cursor_position(self):
return self.cursor_position
def set_text_color(self, color):
self.text_color = color
def set_cursor_color(self, color):
self.cursor_surface.fill(color)