414 lines
15 KiB
Python
414 lines
15 KiB
Python
import pygame
|
|
# pylint: disable=E0611
|
|
from pygame.locals import KEYDOWN
|
|
# pylint: enable=E0611
|
|
|
|
from configfile import cfg
|
|
from utils import wrap_multi_line, image_from_data
|
|
|
|
# pylint: disable=E1121,R0902,R0903,R0912,R0913
|
|
|
|
WHITE = (255, 255, 255)
|
|
BLACK = (0, 0, 0)
|
|
|
|
|
|
class baseobject(object):
|
|
def __init__(self,
|
|
surface,
|
|
x,
|
|
y,
|
|
width,
|
|
height,
|
|
data,
|
|
font,
|
|
border=False,
|
|
fg=WHITE,
|
|
bg=BLACK,
|
|
name=None,
|
|
title=None):
|
|
self.surface = surface
|
|
self.x = x
|
|
self.y = y
|
|
self.width = width
|
|
self.height = height
|
|
self.font = font
|
|
self.border = border
|
|
self.fontheight = self.font.get_height()
|
|
self.fg = fg
|
|
self.bg = bg
|
|
self.data = data
|
|
self.name = name
|
|
self.title = title
|
|
|
|
if self.width < 1:
|
|
for item in self.data:
|
|
size = self.font.size(item)[0]
|
|
if size > self.width:
|
|
self.width = size
|
|
if self.width > self.surface.get_width():
|
|
self.surface.get_width()
|
|
if self.border:
|
|
self.width += 8
|
|
|
|
if self.height < 1:
|
|
self.height = self.fontheight * (len(self.data))
|
|
if self.border:
|
|
self.height += 8
|
|
if self.height > self.surface.get_height():
|
|
if self.border:
|
|
self.height = self.surface.get_height() - 8 - self.y
|
|
else:
|
|
self.height = self.surface.get_height - self.y
|
|
|
|
if self.x == -1:
|
|
self.x = int((self.surface.get_width() / 2) - (self.width / 2))
|
|
|
|
if self.y == -1:
|
|
self.y = int((self.surface.get_height() / 2) - (self.height / 2))
|
|
|
|
if self.border:
|
|
if not self.title:
|
|
self.textx = self.x + 4
|
|
self.texty = self.y + 4
|
|
self.textwidth = self.width - 8
|
|
self.textheight = self.height - 8
|
|
else:
|
|
self.textx = self.x + 4
|
|
self.texty = self.y + 4 + self.fontheight
|
|
self.textwidth = self.width - 8
|
|
self.textheight = self.height - 8 - self.fontheight
|
|
else:
|
|
if not self.title:
|
|
self.textx = self.x
|
|
self.texty = self.y
|
|
self.textwidth = self.width
|
|
self.textheight = self.height
|
|
else:
|
|
self.textx = self.x
|
|
self.texty = self.y + self.fontheight
|
|
self.textwidth = self.width
|
|
self.textheight = self.height - self.fontheight
|
|
|
|
|
|
class menu(baseobject):
|
|
def __init__(self,
|
|
surface,
|
|
x,
|
|
y,
|
|
width,
|
|
height,
|
|
data,
|
|
font,
|
|
border=False,
|
|
fg=WHITE,
|
|
bg=BLACK,
|
|
name=None,
|
|
startitem=0,
|
|
itemattop=0):
|
|
baseobject.__init__(self, surface, x, y, width, height, data, font,
|
|
border, fg, bg, name)
|
|
self.currentitem = startitem
|
|
self.itemattop = itemattop
|
|
self.itemsperpage = int(self.textheight / self.fontheight)
|
|
self.isrom = True
|
|
if str(type(self.data[0])) == "<class 'str'>":
|
|
self.isrom = False
|
|
|
|
def processevent(self, event): # pylint: disable=R0912
|
|
if event.type == KEYDOWN:
|
|
if event.key in cfg["KeyUp"] and self.currentitem > 0:
|
|
if self.currentitem == self.itemattop:
|
|
self.itemattop -= 1
|
|
self.currentitem -= 1
|
|
if event.key in cfg["KeyDown"] and self.currentitem < len(
|
|
self.data) - 1:
|
|
self.currentitem += 1
|
|
if self.itemattop + self.itemsperpage <= self.currentitem:
|
|
self.itemattop += 1
|
|
if event.key in cfg["KeyPgUp"] and self.currentitem > 0:
|
|
self.currentitem -= self.itemsperpage - 1
|
|
while self.itemattop > self.currentitem:
|
|
self.itemattop -= 1
|
|
if self.itemattop < 0:
|
|
self.itemattop = 0
|
|
self.currentitem = 0
|
|
if event.key in cfg["KeyPgDn"] and self.currentitem < len(
|
|
self.data) - 1:
|
|
self.currentitem += self.itemsperpage - 1
|
|
while self.currentitem - self.itemattop >= self.itemsperpage:
|
|
self.itemattop += 1
|
|
if self.itemattop + self.itemsperpage > len(self.data):
|
|
self.itemattop = len(self.data) - self.itemsperpage
|
|
self.currentitem = len(self.data) - 1
|
|
if event.key in cfg["KeyHome"] and self.currentitem > 0:
|
|
self.currentitem = 0
|
|
self.itemattop = 0
|
|
if event.key in cfg["KeyEnd"] and self.currentitem < len(
|
|
self.data) - 1:
|
|
self.currentitem = len(self.data) - 1
|
|
self.itemattop = self.currentitem - self.itemsperpage + 1
|
|
|
|
def render(self):
|
|
pygame.Surface.fill(
|
|
self.surface,
|
|
self.bg,
|
|
rect=pygame.Rect(self.x, self.y, self.width, self.height))
|
|
|
|
if self.border:
|
|
pygame.draw.rect(self.surface, self.fg,
|
|
pygame.Rect(self.x + 1, self.y + 1,
|
|
self.width - 2, self.height - 2), 1)
|
|
|
|
for i in range(0, self.itemsperpage):
|
|
if i > len(self.data) - 1:
|
|
t = pygame.Surface((self.textwidth, self.fontheight))
|
|
t.fill(self.bg)
|
|
self.surface.blit(t, (self.textx,
|
|
self.texty + i * self.fontheight))
|
|
continue
|
|
|
|
if self.isrom:
|
|
item = self.data[self.itemattop + i].description
|
|
else:
|
|
item = self.data[self.itemattop + i]
|
|
|
|
if self.itemattop + i == self.currentitem:
|
|
s = self.font.render(item, True, self.bg, self.fg)
|
|
t = pygame.Surface((self.textwidth, self.fontheight))
|
|
t.fill(self.fg)
|
|
t.blit(s, (0, 0))
|
|
self.surface.blit(t, (self.textx,
|
|
self.texty + i * self.fontheight))
|
|
else:
|
|
s = self.font.render(item, True, self.fg, self.bg)
|
|
t = pygame.Surface((self.textwidth, self.fontheight))
|
|
t.fill(self.bg)
|
|
t.blit(s, (0, 0))
|
|
self.surface.blit(t, (self.textx,
|
|
self.texty + i * self.fontheight))
|
|
|
|
|
|
class notepad(baseobject):
|
|
def __init__(self,
|
|
surface,
|
|
x,
|
|
y,
|
|
width,
|
|
height,
|
|
data,
|
|
font,
|
|
border=False,
|
|
fg=WHITE,
|
|
bg=BLACK,
|
|
name="None",
|
|
title=None):
|
|
baseobject.__init__(self, surface, x, y, width, height, data, font,
|
|
border, fg, bg, name, title)
|
|
self.data = wrap_multi_line(data, self.font, self.textwidth)
|
|
self.lineattop = 0
|
|
self.linesperpage = int(self.textheight / self.fontheight)
|
|
self.lasttopline = int(len(self.data) - self.linesperpage)
|
|
|
|
def processevent(self, event):
|
|
if event.type == KEYDOWN:
|
|
if event.key in cfg["KeyDown"] and self.lineattop < self.lasttopline:
|
|
self.lineattop += 1
|
|
elif event.key in cfg["KeyUp"] and self.lineattop > 0:
|
|
self.lineattop -= 1
|
|
elif event.key in cfg["KeyPgDn"] and self.lineattop < self.lasttopline:
|
|
self.lineattop += self.linesperpage
|
|
if self.lineattop > self.lasttopline:
|
|
self.lineattop = self.lasttopline
|
|
elif event.key in cfg["KeyPgUp"] and self.lineattop > 0:
|
|
self.lineattop -= self.linesperpage
|
|
if self.lineattop < 0:
|
|
self.lineattop = 0
|
|
elif event.key in cfg["KeyHome"] and self.lineattop > 0:
|
|
self.lineattop = 0
|
|
elif event.key in cfg["KeyEnd"] and self.lineattop < self.lasttopline:
|
|
self.lineattop = self.lasttopline
|
|
|
|
def render(self):
|
|
pygame.Surface.fill(
|
|
self.surface,
|
|
self.bg,
|
|
rect=pygame.Rect(self.x, self.y, self.width, self.height))
|
|
if self.border:
|
|
pygame.draw.rect(self.surface, self.fg,
|
|
pygame.Rect(self.x + 1, self.y + 1,
|
|
self.width - 2, self.height - 2), 1)
|
|
if self.title:
|
|
x = (self.textwidth / 2) - (
|
|
self.font.size('%s' % self.title)[0] / 2)
|
|
title_surface = pygame.Surface((self.textwidth,
|
|
self.fontheight))
|
|
title_surface.fill(self.fg)
|
|
title_surface.blit(
|
|
self.font.render('%s' % self.title, True, BLACK, self.fg),
|
|
(x, 0))
|
|
self.surface.blit(title_surface,
|
|
(self.textx, self.texty - self.fontheight))
|
|
for c in range(0, self.linesperpage):
|
|
try:
|
|
itemsurface = self.font.render(self.data[c + self.lineattop],
|
|
True, self.fg, self.bg)
|
|
self.surface.blit(itemsurface,
|
|
(self.textx,
|
|
self.texty + c * self.fontheight))
|
|
except:
|
|
pass
|
|
|
|
|
|
class image_notepad(baseobject):
|
|
def __init__(self,
|
|
surface,
|
|
x,
|
|
y,
|
|
width,
|
|
height,
|
|
data,
|
|
font,
|
|
border=False,
|
|
fg=WHITE,
|
|
bg=BLACK,
|
|
name="None",
|
|
title=None):
|
|
baseobject.__init__(self, surface, x, y, width, height, data, font,
|
|
border, fg, bg, name, title)
|
|
self.currentitem = 0
|
|
self.data = data
|
|
|
|
def processevent(self, event):
|
|
if event.type == KEYDOWN:
|
|
if event.key in cfg["KeyPgDn"]:
|
|
if self.currentitem < len(self.data) - 1:
|
|
self.currentitem += 1
|
|
elif event.key in cfg["KeyPgUp"]:
|
|
if self.currentitem > 0:
|
|
self.currentitem -= 1
|
|
|
|
def render(self):
|
|
pygame.Surface.fill(
|
|
self.surface,
|
|
self.bg,
|
|
rect=pygame.Rect(self.x, self.y, self.width, self.height))
|
|
if self.border:
|
|
pygame.draw.rect(self.surface, self.fg,
|
|
pygame.Rect(self.x + 1, self.y + 1,
|
|
self.width - 2, self.height - 2), 1)
|
|
x = (self.textwidth / 2) - (self.font.size('%s' % self.title)[0] / 2)
|
|
title_surface = pygame.Surface((self.textwidth, self.fontheight))
|
|
title_surface.fill(self.fg)
|
|
title_surface.blit(
|
|
self.font.render('%s' % self.data[self.currentitem][0], True,
|
|
BLACK, self.fg), (x, 0))
|
|
self.surface.blit(title_surface, (self.textx,
|
|
self.texty - self.fontheight))
|
|
|
|
image_surface = image_from_data(self.data[self.currentitem][1],
|
|
(self.textwidth, self.textheight))
|
|
|
|
w, h = image_surface.get_width(), image_surface.get_height()
|
|
|
|
x = (self.textwidth / 2) - (w / 2) + self.textx
|
|
y = (self.textheight / 2) - (h / 2) + self.texty
|
|
|
|
self.surface.blit(image_surface, (x, y))
|
|
|
|
|
|
class gui():
|
|
def __init__(self, surface):
|
|
self.surface = surface
|
|
self.objects = []
|
|
self.font = pygame.font.Font(
|
|
pygame.font.match_font(cfg["Font"], bold=True), cfg["FontSize"])
|
|
# self.fontheight = self.font.get_height()
|
|
self.currentobject = 0
|
|
|
|
def waitevent(self):
|
|
event = pygame.event.wait()
|
|
|
|
if self.objects:
|
|
self.objects[-1].processevent(event)
|
|
|
|
return event
|
|
|
|
def add_menu(self,
|
|
x,
|
|
y,
|
|
width,
|
|
height,
|
|
data,
|
|
border=False,
|
|
fg=WHITE,
|
|
bg=BLACK,
|
|
name="None",
|
|
startitem=0,
|
|
itemattop=0):
|
|
self.currentobject += 1
|
|
self.objects.append(
|
|
menu(self.surface, x, y, width, height, data, self.font, border,
|
|
fg, bg, name, startitem, itemattop))
|
|
|
|
def add_notepad(self,
|
|
x,
|
|
y,
|
|
width,
|
|
height,
|
|
data,
|
|
border=False,
|
|
fg=WHITE,
|
|
bg=BLACK,
|
|
name="None",
|
|
title=None):
|
|
self.currentobject += 1
|
|
self.objects.append(
|
|
notepad(self.surface, x, y, width, height, data, self.font, border,
|
|
fg, bg, name, title))
|
|
|
|
def add_image_notepad(self,
|
|
x,
|
|
y,
|
|
width,
|
|
height,
|
|
data,
|
|
border=False,
|
|
fg=WHITE,
|
|
bg=BLACK,
|
|
name="None",
|
|
title=None):
|
|
self.currentobject += 1
|
|
self.objects.append(
|
|
image_notepad(self.surface, x, y, width, height, data, self.font,
|
|
border, fg, bg, name, title))
|
|
|
|
def deletelastobject(self):
|
|
del self.objects[-1]
|
|
self.currentobject -= 1
|
|
|
|
def getmenuname(self):
|
|
return self.objects[-1].name
|
|
|
|
def deleteallmenus(self):
|
|
while self.currentobject > 1:
|
|
self.deletelastobject()
|
|
|
|
def getcurrentitem(self, objnum=None):
|
|
if objnum is None:
|
|
return self.objects[-1].currentitem
|
|
return self.objects[objnum].currentitem
|
|
|
|
def getitemattop(self):
|
|
return self.objects[-1].itemattop
|
|
|
|
# TODO: Fix me for itemattop on normal menus
|
|
def setcurrentitem(self, selected_item):
|
|
self.objects[-1].itemattop = selected_item
|
|
self.objects[-1].currentitem = selected_item
|
|
|
|
def render(self):
|
|
for t in self.objects:
|
|
t.render()
|
|
|
|
pygame.display.update()
|