import copy from pygame import * class Gui: def __init__(self,size = (854, 480), font="Roboto-Bold.ttf", font_size=12, obj_color="#333333", txt_color="#ffffff"): self.font = font self.font_size = font_size self.txt_color = txt_color self.obj_color = obj_color self.objects = {} self.layers = {'layer0': []} self.layer_order = ['layer0'] self.layer_count = 0 self.size = size self.surface = Surface(size) self.events = None self.mouse_pos = [0,0] def get_font(self): return font.Font('fonts/' + self.font, self.font_size) def get_text_color(self): return self.txt_color def get_obj_color(self): return self.obj_color def set_text_color(self, color): self.txt_color = color def set_obj_color(self, color): self.obj_color = color def add_layer(self): self.layer_count += 1 name = 'layer' + str(self.layer_count) self.layers[name] = [] self.layer_order.append(name) return name def del_layer(self, layer): del self.layers[layer] del self.layer_order[self.layer_order.index(layer)] def layer_to_top(self, layer): del self.layer_order[self.layer_order.index(layer)] self.layer_order.append(layer) def move_layer(self, layer, index): del self.layer_order[self.layer_order.index(layer)] self.layer_order.insert(index, layer) def add_object(self, obj, layer = 'layer0'): obj.layer = layer obj.index = len(self.layers[layer]) self.layers[layer].append(obj) def del_object(self, obj): del self.layers[obj.layer][obj.index] def draw(self): for i in copy.copy(self.layer_order): l = copy.copy(self.layers[i]) for o in l: o.draw() def update(self,events,screen_offset=[None,None]): self.events = copy.copy(events) mouse_on_objs = [] if screen_offset != [None,None]: mouse_pos = screen_offset else: mouse_pos = mouse.get_pos() self.mouse_pos = mouse_pos for n in range(len(self.layer_order)): i = self.layer_order[n] l = self.layers[i] for o in l: if o.rect: if o.rect.collidepoint(mouse_pos): mouse_on_objs.append([o, n]) elif o.hovering: o.hovering = False o.on_mouse_leave() hn = -1 objs = [] for o in mouse_on_objs: if o[1] > hn: objs = [o[0]] elif o[1] == hn: objs.append(o[0]) for o in objs: if not o.hovering: o.on_mouse_enter() o.hovering = True o.on_hover() for e in events: if e.type == KEYDOWN: self.focused.on_key_pressed(e) if e.type == KEYUP: self.focused.on_key_up(e) if e.type == MOUSEBUTTONDOWN: for o in objs: self.focused = o o.on_clicked(e) if e.type == MOUSEBUTTONUP: for o in objs: o.on_released(e) if e.type == QUIT: global running running = False class Widget: def __init__(self, gui): self.gui = gui self.pos = None self.text = ' ' self.font = gui.get_font() self.txt_color = Color(self.gui.txt_color) self.obj_color = Color(self.gui.obj_color) self.padding = [4, 4, 6, 6] self.hovering = False self.index = 0 self.layer = '' self.size = [self.font.size(self.text)[0], self.font.size(self.text)[1]] self.width = self.size[0] + self.padding[2] + self.padding[3] self.height = self.size[1] + self.padding[0] + self.padding[1] self.rect = None return def on_clicked(self, e): return False def on_released(self, e): return False def on_hover(self): return False def on_mouse_enter(self): return False def on_mouse_leave(self): return False def on_key_pressed(self, e): return False def on_key_up(self, e): return False def draw(self): return False class Button(Widget): def __init__(self, gui, text, pos, func): Widget.__init__(self, gui) self.text = text self.pos = pos self.clicked = func def on_mouse_enter(self): if self.obj_color.r <= 200 and self.obj_color.g <= 200 and self.obj_color.b <= 200: self.obj_color.r += 55 self.obj_color.g += 55 self.obj_color.b += 55 def on_mouse_leave(self): if self.obj_color.r >= 55 and self.obj_color.g >= 55 and self.obj_color.b >= 55: self.obj_color.r -= 55 self.obj_color.g -= 55 self.obj_color.b -= 55 def on_clicked(self, e): self.clicked(self) def draw(self): self.size = self.font.size(self.text) self.width = self.size[0] + self.padding[2] + self.padding[3] self.height = self.size[1] + self.padding[0] + self.padding[1] self.rect = Rect(self.pos, (self.width, self.height)) draw.rect(self.gui.surface, self.obj_color, self.rect) txt_surf = self.font.render(self.text, True, self.txt_color) txt_pos = (self.pos[0] + self.padding[2], self.pos[1] + self.padding[0]) self.gui.surface.blit(txt_surf, txt_pos) class Textbox(Widget): def __init__(self, gui, text, pos): Widget.__init__(self, gui) self.text = text self.size = [ i for i in self.font.size("J") ] self.size[0] = self.size[0] * 15 self.pos = pos self.cur = len(self.text) def on_mouse_enter(self): if self.obj_color.r < 200 and self.obj_color.g < 200 and self.obj_color.b < 200: self.obj_color.r += 55 self.obj_color.g += 55 self.obj_color.b += 55 def on_mouse_leave(self): if self.obj_color.r > 55 and self.obj_color.g > 55 and self.obj_color.b > 55: self.obj_color.r -= 55 self.obj_color.g -= 55 self.obj_color.b -= 55 def on_key_pressed(self, e): if e.key != K_BACKSPACE: if e.key == K_RIGHT: if self.cur < len(self.text): self.cur += 1 elif e.key == K_LEFT: if self.cur > 0: self.cur -= 1 else: self.text = self.text[:self.cur] + e.unicode + self.text[self.cur:] self.cur += 1 elif self.cur > 0: self.text = self.text[:self.cur - 1] + self.text[self.cur:-1] self.cur -= 1 def draw(self): self.width = self.size[0] + self.padding[2] + self.padding[3] self.height = self.size[1] + self.padding[0] + self.padding[1] self.rect = Rect(self.pos, (self.width, self.height)) draw.rect(self.gui.surface, self.obj_color, self.rect) if self.font.size(self.text[:self.cur]+'|') > self.size[0] and self.cur > 15: rend_text = self.text[self.cur - 15:self.cur] + '|' else: rend_text = self.text[:self.cur] + '|' + self.text[self.cur:15] txt_surf = self.font.render(rend_text, True, self.txt_color) txt_pos = (self.pos[0] + self.padding[2], self.pos[1] + self.padding[0]) self.gui.surface.blit(txt_surf, txt_pos) class Image(Widget): def __init__(self, gui, surf, pos): Widget.__init__(self, gui) self.img = surf self.pos = pos self.size = [surf.get_width(), surf.get_height()] def draw(self): self.rect = Rect(self.pos, self.size) self.gui.surface.blit(self.img, self.pos) class Text(Widget): def __init__(self, gui, text, pos, font_size): Widget.__init__(self, gui) self.pos = pos self.text = text self.font = font.Font('fonts/' + self.gui.font, font_size) self.size = self.font.size('J') def draw(self): temp_text = self.text.split('\n') pos = [self.pos[0], self.pos[1]] for t in temp_text: rend = self.font.render(t, True, self.txt_color) self.gui.surface.blit(rend, pos) pos[1] += self.size[1] + self.size[1] * 0.4 class Drag_and_drop(Widget): def __init__(self, gui, pos, size, bgcolor): Widget.__init__(self, gui) self.objects = [] self.pos = pos self.bgcolor = Color(bgcolor) self.size = size self.rect = Rect(self.pos, self.size) self.layer = self.gui.add_layer() self.moffx = 0 self.moffy = 0 self.dragging = False def add_object(self, obj, pos): obj.gui = self.gui self.gui.add_object(obj, self.layer) self.objects.append([obj, pos]) def on_clicked(self, e): self.dragging = True self.moffx = self.gui.mouse_pos[0] - self.pos[0] self.moffy = self.gui.mouse_pos[1] - self.pos[1] self.gui.layer_to_top(self.layer) def on_released(self, e): self.dragging = False self.gui.layer_to_top(self.layer) def draw(self): self.rect = Rect(self.pos, self.size) draw.rect(self.gui.surface, self.bgcolor, self.rect) if self.dragging: self.pos[0] = self.gui.mouse_pos[0] - self.moffx self.pos[1] = self.gui.mouse_pos[1] - self.moffy for i in self.objects: i[0].pos = (i[1][0] + self.pos[0], i[1][1] + self.pos[1]) class Container(Widget): def __init__(self,ogui, pos, size, bgcolor): Widget.__init__(self, Gui(size)) self.ogui = ogui self.objects = [] self.pos = pos self.bgcolor = Color(bgcolor) self.size = size self.rect = Rect(self.pos, self.size) self.layer = self.gui.add_layer() def add_object(self, obj): obj.gui = self.gui self.gui.add_object(obj, self.layer) self.objects.append([obj]) def draw(self): self.rect = Rect(self.pos, self.size) self.gui.surface.fill(self.bgcolor) ## for i in self.objects: ## i[0].pos = (i[1][0] + self.pos[0], i[1][1] + self.pos[1]) self.gui.update(self.ogui.events,[self.ogui.mouse_pos[0]-self.pos[0],self.ogui.mouse_pos[1]-self.pos[1]]) self.gui.draw() #self.gui.surface.update() self.ogui.surface.blit(self.gui.surface,(self.pos))