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])) == "": 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()