def init_bg(self, bg): if bg is not None: bg_surf = pygame.Surface((self.width, self.height), SRCALPHA, 32)\ .convert_alpha() if isinstance(bg, tuple) and len(bg) >= 3: bg_surf.fill(bg) else: fill_with_surface(bg_surf, bg) self.bg = Image(bg_surf) else: r = pygame.Rect(0, 0, self.width, self.height) self.bg = self.theme.draw_menu_bg(r)
def draw_unselected_tab(self, rect): DEFAULT_COLOR = transparency(DARKER_MAGENTA, 0.5) border = 2 internal_rect = pygame.Rect((rect.left + border, rect.top + border), (rect.w - 2 * border, rect.h - border)) surface = pygame.Surface((rect.width, rect.height), SRCALPHA, 32) pygame.draw.rect(surface, DEFAULT_COLOR, internal_rect) return Image(surface)
def draw_unselected_tab(self, rect): surface = pygame.Surface((rect.width, rect.height), SRCALPHA, 32) pygame.draw.rect(surface, self.border_color, rect) inner_rect = pygame.Rect( (rect.left + self.border, rect.top + self.border), (rect.width - 2 * self.border, rect.height - self.border)) pygame.draw.rect(surface, self.unselected_tab_color, inner_rect) return Image(surface)
def init_bg(self, bg): if bg is not None: bg_surf = pygame.Surface((self.width, self.height), SRCALPHA, 32)\ .convert_alpha() if isinstance(bg, tuple) and len(bg) >= 3: bg_surf.fill(bg) else: fill_with_surface(bg_surf, bg) self.bg = Image(bg_surf) else: r = pygame.Rect(0, 0, self.width, self.height) self.bg = self.theme.draw_menu_bg(r)
def draw_image(self, image): """ *Virtual.* Return an Image with how an ImageWidget should be rendered. *image* should be a pygame Surface with the ImageWidget's appearance. This can be overloaded to apply some filters to images used in ImageWidgets. """ return Image(image)
def get_icon(self): """ Returns an Image with the item's icon. """ loc = self.get_icon_location() if loc is None: return None if not hasattr(loc, '__len__') or len(loc) not in (2, 4): raise Exception('%s.get_icon_location() should return a 2-tuple' 'or a 4-tuple') image = pygame.image.load(loc[0]) icon_w = g_cfg.item_icon_width if len(loc) <= 2 else loc[2] icon_h = g_cfg.item_icon_height if len(loc) <= 3 else loc[3] sliced_img = SlicedImage(image, icon_w, icon_h) return Image(sliced_img.get_slice(loc[1]))
def draw(self): if self.image is None or self.changed: end = self.start + self.height_in_cells self.scroll_bar_img = self.theme.draw_scroll_bar(self.height, self.start, end, len(self)) r = pygame.Rect(0, 0, self.get_cells_width(), self.height) #self.scroll_area_img = self.theme.draw_scroll_area(r) surf = pygame.Surface((self.width, self.height), SRCALPHA, 32) #surf.blit(self.scroll_area_img.get_surface(), (0, 0)) surf.blit(self.scroll_bar_img, (r.w, 0)) self.image = Image(surf) self.changed = False Div.draw(self)
def __draw_multi_line(self, font): lines = build_lines(self.text, self.max_width, font) total_height = sum([e[0] for e in lines]) s = pygame.Surface((self.max_width, total_height), SRCALPHA, 32) y = 0 for w, h, line in lines: line_surface = font.render(line, self.theme.get_font_anti_alias(), self.color) if self.align == LEFT: x = 0 elif self.align == RIGHT: x = self.max_width - w elif self.align == CENTER: x = (self.max_width - w) / 2 s.blit(line_surface, (x, y)) y += h self.image = Image(s)
def draw_bar(self, rect, filled=1.0): surface = pygame.Surface((rect.width, rect.height), SRCALPHA, 32) surface.fill(TRANSPARENT) border = 0 if (rect.width < 4 or rect.height < 4) else 1 for i in xrange(border): border_rect = pygame.Rect( (rect.left + i, rect.top + i), (rect.width - 2 * i, rect.height - 2 * i)) pygame.draw.rect(surface, WHITE, border_rect, 1) width = rect.width - 2 * border vertical_lines = int(width * filled) for i in xrange(vertical_lines): green = (255.0 * (vertical_lines - i)) / width color = (255, green, 0, 255) pygame.draw.line( surface, color, (rect.left + i + border, rect.top + border), (rect.left + i + border, rect.bottom - 1 - border), 1) return Image(surface)
class Menu(Model, Div): """ A Menu is the outermost container for widgets, representing a whole menu ran by a MenuController. Menus provide all methods a Div does, most notably add_widget(), which is used to put any widgets or Divs on the Menu. *width* and *height* specify the dimensions of the menu in pixels. *x* and *y* specify the position at which the top left of the menu will be on the screen. *theme* is a MenuTheme that will be used to render that menu, and defaults to the default_theme in librpg.config.menu_config. *bg* can be a color or a pygame Surface that will be drawn as the menu's background. *mouse_control* can be Menu.MOUSE_OFF, Menu.MOUSE_STRICT or Menu.MOUSE_LOOSE. MOUSE_OFF will disable mouse control for the menu, MOUSE_STRICT will cause the cursor to move to widgets touched by the mouse pointer, and MOUSE_LOOSE will move it always to the nearest widget. """ MOUSE_OFF = 0 MOUSE_STRICT = 1 MOUSE_LOOSE = 2 def __init__(self, width, height, x=0, y=0, theme=None, bg=None, mouse_control=MOUSE_LOOSE, blocking=True): Model.__init__(self) Div.__init__(self, width, height, False, theme) self.x = x self.y = y self.cursor = None self.menu = self self.all_widgets = [] self.init_bg(bg) assert mouse_control in (Menu.MOUSE_OFF, Menu.MOUSE_STRICT, Menu.MOUSE_LOOSE),\ 'mouse_control must be 0, 1 or 2' self.mouse_control = mouse_control self.blocking = blocking self.should_close = False def init_bg(self, bg): if bg is not None: bg_surf = pygame.Surface((self.width, self.height), SRCALPHA, 32)\ .convert_alpha() if isinstance(bg, tuple) and len(bg) >= 3: bg_surf.fill(bg) else: fill_with_surface(bg_surf, bg) self.bg = Image(bg_surf) else: r = pygame.Rect(0, 0, self.width, self.height) self.bg = self.theme.draw_menu_bg(r) def draw(self): scr = get_screen() scr.blit(self.bg.get_surface(), (self.x, self.y)) Div.draw(self) Div.render(self, scr, self.x, self.y) if self.cursor is not None: self.cursor.draw() self.cursor.render(scr) # Use cursor.bind instead def add_cursor(self, cursor): if self.cursor is not None: return False else: self.cursor = cursor return True def remove_cursor(self): result = self.cursor self.cursor = None return result def register_widget(self, widget): self.all_widgets.append(widget) def unregister_widget(self, widget): self.all_widgets.remove(widget) if self.cursor is not None and self.cursor.widget is widget: self.cursor.move_to() def open(self): """ Open the menu. """ get_context_stack().stack_model(self) def close(self): """ Close the menu. """ self.should_close = True def activate(self): """ *Virtual.* """ pass def create_controller(self): return MenuController(self, self.controller_parent) def is_done(self): return self.controller.is_done() def update_input(self): cursor = self.menu.cursor if cursor is not None: w = cursor.widget while w.parent is not None: #print 'update_input %s' % w w.update_input() w = w.parent def reposition_cursor(self, pos): if self.menu.mouse_control == Menu.MOUSE_STRICT: self.menu.__reposition_cursor_strict(pos) else: self.menu.__reposition_cursor_loose(pos) def __reposition_cursor_strict(self, pos): cursor = self.cursor if cursor.widget.contains_point(pos): return for w in self.all_widgets: if w.focusable and w.contains_point(pos): cursor.move_to(w) return def __reposition_cursor_loose(self, pos): cursor = self.cursor best = (None, 999999) for w in self.all_widgets: if w.focusable: dist = w.distance_to_point(pos) if dist < best[1]: best = (w, dist) if best[0] is not None: cursor.move_to(best[0])
def draw_round_border_rect_image(self, rect, border_flags=(None, True, True, True, True)): surface = self.draw_round_border_rect(rect, border_flags) return Image(surface)
def __init__(self, filename, x_offset=0, y_offset=0): self.filename = filename self.x_offset = x_offset self.y_offset = y_offset self.image = Image(pygame.image.load(self.filename))
def draw_scroll_area(self, rect): DEFAULT_COLOR = transparency(DARK_RED, 0.5) surface = pygame.Surface((rect.width, rect.height), SRCALPHA, 32) pygame.draw.rect(surface, DEFAULT_COLOR, rect) return Image(surface)
def draw_panel(self, rect): DEFAULT_COLOR = transparency(PURPLE, 0.5) surface = pygame.Surface((rect.width, rect.height), SRCALPHA, 32) pygame.draw.rect(surface, DEFAULT_COLOR, rect) return Image(surface)
class Menu(Model, Div): """ A Menu is the outermost container for widgets, representing a whole menu ran by a MenuController. Menus provide all methods a Div does, most notably add_widget(), which is used to put any widgets or Divs on the Menu. *width* and *height* specify the dimensions of the menu in pixels. *x* and *y* specify the position at which the top left of the menu will be on the screen. *theme* is a MenuTheme that will be used to render that menu, and defaults to the default_theme in librpg.config.menu_config. *bg* can be a color or a pygame Surface that will be drawn as the menu's background. *mouse_control* can be Menu.MOUSE_OFF, Menu.MOUSE_STRICT or Menu.MOUSE_LOOSE. MOUSE_OFF will disable mouse control for the menu, MOUSE_STRICT will cause the cursor to move to widgets touched by the mouse pointer, and MOUSE_LOOSE will move it always to the nearest widget. """ MOUSE_OFF = 0 MOUSE_STRICT = 1 MOUSE_LOOSE = 2 def __init__(self, width, height, x=0, y=0, theme=None, bg=None, mouse_control=MOUSE_LOOSE, blocking=True): Model.__init__(self) Div.__init__(self, width, height, False, theme) self.x = x self.y = y self.cursor = None self.menu = self self.all_widgets = [] self.init_bg(bg) assert mouse_control in (Menu.MOUSE_OFF, Menu.MOUSE_STRICT, Menu.MOUSE_LOOSE),\ 'mouse_control must be 0, 1 or 2' self.mouse_control = mouse_control self.blocking = blocking self.should_close = False def init_bg(self, bg): if bg is not None: bg_surf = pygame.Surface((self.width, self.height), SRCALPHA, 32)\ .convert_alpha() if isinstance(bg, tuple) and len(bg) >= 3: bg_surf.fill(bg) else: fill_with_surface(bg_surf, bg) self.bg = Image(bg_surf) else: r = pygame.Rect(0, 0, self.width, self.height) self.bg = self.theme.draw_menu_bg(r) def draw(self): scr = get_screen() scr.blit(self.bg.get_surface(), (self.x, self.y)) Div.draw(self) Div.render(self, scr, self.x, self.y) if self.cursor is not None: self.cursor.draw() self.cursor.render(scr) # Use cursor.bind instead def add_cursor(self, cursor): if self.cursor is not None: return False else: self.cursor = cursor return True def remove_cursor(self): result = self.cursor self.cursor = None return result def register_widget(self, widget): self.all_widgets.append(widget) def unregister_widget(self, widget): self.all_widgets.remove(widget) if self.cursor is not None and self.cursor.widget is widget: self.cursor.move_to() def open(self): """ Open the menu. """ get_context_stack().stack_model(self) def close(self): """ Close the menu. """ self.should_close = True def activate(self): """ *Virtual.* """ pass def create_controller(self): return MenuController(self, self.controller_parent) def is_done(self): return self.controller.is_done() def update_input(self): cursor = self.menu.cursor if cursor is not None: w = cursor.widget while w.parent is not None: #print 'update_input %s' % w w.update_input() w = w.parent def reposition_cursor(self, pos): if self.menu.mouse_control == Menu.MOUSE_STRICT: self.menu.__reposition_cursor_strict(pos) else: self.menu.__reposition_cursor_loose(pos) def __reposition_cursor_strict(self, pos): cursor = self.cursor if cursor.widget.contains_point(pos): return for w in self.all_widgets: if w.focusable and w.contains_point(pos): cursor.move_to(w) return def __reposition_cursor_loose(self, pos): cursor = self.cursor best = (None, 999999) for w in self.all_widgets: if w.focusable: dist = w.distance_to_point(pos) if dist < best[1]: best = (w, dist) if best[0] is not None: cursor.move_to(best[0])
def __draw_one_line(self, font): self.image = Image(font.render(self._text, self.theme.get_font_anti_alias(), self.color))