Skip to content

Instantly share code, notes, and snippets.

@robertpfeiffer
Created March 3, 2020 18:11
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save robertpfeiffer/63f4e5f754c92a2df2dc2c59c955b186 to your computer and use it in GitHub Desktop.
Save robertpfeiffer/63f4e5f754c92a2df2dc2c59c955b186 to your computer and use it in GitHub Desktop.
# Copyright (c) 2020 Robert Pfeiffer
# Terminal simulator
import pygame
pygame.init()
screen=pygame.display.set_mode((640,480), pygame.SCALED)
clock=pygame.time.Clock()
class Terminal(object):
def __init__(self, size):
self.w, self.h = self.size = size
self.scrollback = []
self.buffer = []
self.fontsize = 16
self.font = pygame.font.Font("Inconsolata.otf", self.fontsize)
self.cursor= 0,0
pygame.display.set_caption("Terminal")
def _scroll_up(self):
screen.scroll(0, -self.fontsize)
pygame.draw.rect(screen, (0,0,0),
pygame.Rect(0,(self.h-1)*self.fontsize,
screen.get_width(), self.fontsize))
self.buffer.pop(0)
def _print_inner_slow(self, string):
clock.tick(30)
pygame.event.pump()
if len(self.buffer)==self.h:
self._scroll_up()
i=0
for char in string:
clock.tick(30)
pygame.event.pump()
glyph=self.font.render(char, 0, (255,255,255), (0,0,0))
screen.blit(glyph, (glyph.get_width()*i, len(self.buffer)*self.fontsize))
i+=1
pygame.display.flip()
self.buffer.append(string)
self.cursor=len(self.buffer[-1]),len(self.buffer)-1
def _print_inner(self, string):
clock.tick(30)
pygame.event.pump()
if len(self.buffer)==self.h:
self._scroll_up()
line_buf=self.font.render(string, 0, (255,255,255), (0,0,0))
screen.blit(line_buf, (0, len(self.buffer)*self.fontsize))
self.buffer.append(string)
self.cursor=len(self.buffer[-1]),len(self.buffer)-1
pygame.display.flip()
def println(self, string):
self.scrollback.append(string)
while len(string) > self.w:
self._print_inner_slow(string[:self.w])
string=string[self.w:]
self._print_inner_slow(string)
def print(self, string):
for line in string.split("\n"):
self.println(line)
def clear(self):
clock.tick(30)
pygame.event.pump()
self.buffer = []
self.cursor= 0,0
screen.fill(0)
pygame.display.flip()
def input(self):
input_str=""
starting_cursor=self.cursor
try:
pygame.key.start_text_input()
i=0
while True:
clock.tick(30)
blink_cursor=" "
i+=1
if i>30:
i=0
if i>20:
blink_cursor="_"
blink=self.font.render(blink_cursor, 0, (255,255,255), (0,0,0))
screen.blit(blink, (self.cursor[0]*blink.get_width(),self.fontsize*self.cursor[1]))
events=pygame.event.get()
for e in events:
if e.type==pygame.QUIT:
sys.exit()
elif e.type==pygame.VIDEORESIZE:
pygame.display.resize_event(e)
elif e.type==pygame.KEYDOWN and (e.key==pygame.K_ESCAPE
or e.key==1073742094):
return None
elif e.type==pygame.KEYDOWN and (e.key==pygame.K_BACKSPACE):
if len(input_str)>0:
input_str=input_str[:-1]
self.cursor = max(0, self.cursor[0]-1), self.cursor[1]
elif e.type==pygame.KEYDOWN and (e.key==pygame.K_RETURN):
blink=self.font.render(" ", 0, (255,255,255), (0,0,0))
screen.blit(blink, (self.cursor[0]*blink.get_width(),self.fontsize*self.cursor[1]))
return input_str
elif e.type==pygame.TEXTINPUT:
char=self.font.render(e.text, 0, (255,255,255), (0,0,0))
screen.blit(char, (self.cursor[0]*blink.get_width(),self.fontsize*self.cursor[1]))
self.buffer[-1]+=(e.text)
self.cursor = self.cursor[0]+1, self.cursor[1]
if self.cursor[0]==self.w:
if len(self.buffer)==self.h:
self._scroll_up()
self.buffer.append("")
self.cursor = 0, self.cursor[1]
else:
self.buffer.append("")
self.cursor = 0, self.cursor[1]+1
input_str+=e.text
pygame.display.flip()
finally:
pygame.key.stop_text_input()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment