Added a copy of SGC
This commit is contained in:
parent
90ff7ceba8
commit
52eb18994d
22 changed files with 3283 additions and 0 deletions
217
sgc/widgets/menu.py
Normal file
217
sgc/widgets/menu.py
Normal file
|
@ -0,0 +1,217 @@
|
|||
#!/usr/bin/env python
|
||||
|
||||
# Copyright (C) 2010-2012 Sam Bull
|
||||
|
||||
"""
|
||||
Menu widget. Creates a menu for a game.
|
||||
|
||||
"""
|
||||
|
||||
from _locals import *
|
||||
from boxes import VBox
|
||||
from scroll_box import ScrollBox
|
||||
from . import *
|
||||
|
||||
class Menu(Simple):
|
||||
|
||||
"""
|
||||
Menu
|
||||
|
||||
Can be indexed to access widgets by name.
|
||||
|
||||
Attributes:
|
||||
func_dict: Assign a lambda to return a dictionary of functions for
|
||||
config file to utilise.
|
||||
|
||||
"""
|
||||
|
||||
_modal = True
|
||||
_layered = True
|
||||
_settings_default = {"offset": (100, 50), "col": (0,0,1), "apply": False}
|
||||
|
||||
_menus = []
|
||||
_dict = {} # Dict for indexing widgets
|
||||
_old_menu = None
|
||||
_curr_menu = 0
|
||||
func_dict = lambda self: {}
|
||||
|
||||
def _config(self, **kwargs):
|
||||
"""
|
||||
menu: Either tuple containing menu data, to be documented.
|
||||
Or file object to read config data from, in the same format.
|
||||
apply: TODO ``bool`` True if an apply button should be added.
|
||||
col: ``tuple`` (r,g,b), Colour used for the background.
|
||||
offset: ``tuple`` (x,y) Contains position of menu widgets. y is
|
||||
added to bottom of title.
|
||||
|
||||
"""
|
||||
if "apply" in kwargs:
|
||||
self._settings["apply"] = kwargs["apply"]
|
||||
if "col" in kwargs:
|
||||
self._settings["col"] = kwargs["col"]
|
||||
if "offset" in kwargs:
|
||||
self._settings["offset"] = kwargs["offset"]
|
||||
if "menu" in kwargs:
|
||||
self._menus = [] # Remove previous menus
|
||||
self._dict = {}
|
||||
# Grab function dictionary
|
||||
self._funcs = self.func_dict()
|
||||
|
||||
# Set size to screen size
|
||||
if not hasattr(self, "image"):
|
||||
self._create_base_images(get_screen().rect.size)
|
||||
|
||||
menu = kwargs["menu"]
|
||||
# If file, read config tuple
|
||||
if isinstance(menu, file):
|
||||
menu_data = "".join(menu.readlines())
|
||||
menu = eval(menu_data)
|
||||
assert isinstance(menu, tuple)
|
||||
|
||||
menu_data = [(menu, None)] # (data, parent)
|
||||
# Create each submenu, by iterating through the menu data
|
||||
while menu_data:
|
||||
self._menus.append(_SubMenu(self.rect.size,
|
||||
col=self._settings["col"]))
|
||||
self._config_menu(menu_data, self._menus[-1])
|
||||
|
||||
def _config_menu(self, data_queue, menu):
|
||||
"""
|
||||
Configure the passed in menu, using the information from the first
|
||||
item in data_queue.
|
||||
|
||||
New sub-menus discovered in the data will be appended to the data_queue
|
||||
for later processing.
|
||||
|
||||
"""
|
||||
data, parent = data_queue.pop(0)
|
||||
widgets = []
|
||||
# Parse menu data
|
||||
for item in data:
|
||||
# Title
|
||||
if isinstance(item, str):
|
||||
menu._title = Simple(Font["title"].render(item[2:], True,
|
||||
Font.col))
|
||||
menu._title.rect.midtop = (self.rect.centerx, 40)
|
||||
# Sub-menu
|
||||
elif item[0].startswith("m:"):
|
||||
data_queue.append((item, len(self._menus)-1))
|
||||
surf = Font["widget"].render(item[0][2:], True, Font.col)
|
||||
widgets.append(Button(surf))
|
||||
# Change menu on button activate
|
||||
num = len(self._menus)-1 + len(data_queue)
|
||||
widgets[-1].activate = lambda n=num: self.change_menu(n)
|
||||
# Category/divider
|
||||
elif item[0].startswith("c:"):
|
||||
div = Simple(Font["widget"].render(item[0][2:], True,
|
||||
Font.col))
|
||||
self.get_draw().line(div.image, Font.col, (0, div.rect.h-1),
|
||||
(div.rect.w, div.rect.h-1))
|
||||
widgets.append(div)
|
||||
# Widget
|
||||
elif item[0].startswith("w:"):
|
||||
args = self._get_args(item[1:])
|
||||
name = args.pop("name")
|
||||
f = args.pop("func") if ("func" in args) else None
|
||||
if item[0].endswith("input_box"):
|
||||
widget = input_box.InputBox(**args)
|
||||
elif item[0].endswith("button"):
|
||||
for key in args:
|
||||
if key == "surf":
|
||||
args[key] = eval(args[key])
|
||||
widget = button.Button(**args)
|
||||
elif item[0].endswith("label"):
|
||||
widget = label.Label(**args)
|
||||
self._dict[name] = widget
|
||||
if f: widget.activate = self._funcs[f]
|
||||
widgets.append(widget)
|
||||
# Function
|
||||
elif item[0].startswith("f:"):
|
||||
surf = Font["widget"].render(item[1], True, Font.col)
|
||||
widgets.append(button.Button(surf=surf))
|
||||
widgets[-1].activate = self._funcs[item[0][2:]]
|
||||
|
||||
# Draw a back menu item
|
||||
if parent is not None:
|
||||
surf = Font["widget"].render("Back", True, Font.col)
|
||||
widgets.append(button.Button(surf=surf))
|
||||
widgets[-1].activate = lambda n=parent: self.change_menu(n)
|
||||
|
||||
menu._widgets = tuple(widgets)
|
||||
|
||||
def _draw(self, draw):
|
||||
for menu in self._menus:
|
||||
# Pack all widgets into a VBox
|
||||
box = VBox(widgets=menu._widgets, spacing=15)
|
||||
pos = (self._settings["offset"][0],
|
||||
self._settings["offset"][1] + menu._title.rect.bottom)
|
||||
box = ScrollBox((self.rect.w - pos[0], self.rect.h - pos[1]),
|
||||
widget=box, pos=pos)
|
||||
menu.config(col=self._settings["col"], menu=box)
|
||||
|
||||
def change_menu(self, menu_num):
|
||||
"""
|
||||
Change the currently displayed menu.
|
||||
|
||||
Args:
|
||||
menu_num: ``int`` The number representing the menu.
|
||||
|
||||
"""
|
||||
self._old_menu = self._curr_menu
|
||||
self._curr_menu = menu_num
|
||||
self._menus[self._curr_menu]._fade = 0
|
||||
|
||||
def update(self, time):
|
||||
menu = self._menus[self._curr_menu]
|
||||
menu.update(time)
|
||||
if self._old_menu is not None:
|
||||
self.image.blit(self._menus[self._old_menu].image, (0,0))
|
||||
menu.image.set_alpha(menu._fade)
|
||||
menu._fade += time / 3.
|
||||
if menu._fade >= 255:
|
||||
menu._fade = None
|
||||
self._old_menu = None
|
||||
menu.image.set_alpha(255)
|
||||
self.image.blit(menu.image, (0,0))
|
||||
|
||||
def _event(self, event):
|
||||
self._menus[self._curr_menu]._event(event)
|
||||
|
||||
def _get_args(self, args):
|
||||
"""Get the arguments passed in, saving them into a dictionary."""
|
||||
return {arg.split("=")[0]: arg.split("=")[1] for arg in args}
|
||||
|
||||
def __getitem__(self, key):
|
||||
"""Return widgets by name."""
|
||||
return self._dict[key]
|
||||
|
||||
class _SubMenu(Simple):
|
||||
|
||||
"""
|
||||
A single menu object to be created and managed by the Menu class.
|
||||
|
||||
"""
|
||||
_settings_default = {"col": (0,0,1), "menu": None}
|
||||
|
||||
_title = None
|
||||
_widgets = ()
|
||||
|
||||
def _config(self, **kwargs):
|
||||
if "col" in kwargs:
|
||||
self._settings["col"] = kwargs["col"]
|
||||
if "menu" in kwargs:
|
||||
self._settings["menu"] = kwargs["menu"]
|
||||
|
||||
def _draw(self, draw):
|
||||
self._images["image"].fill(self._settings["col"])
|
||||
if self._title:
|
||||
self._images["image"].blit(self._title.image, self._title.pos)
|
||||
|
||||
def update(self, time):
|
||||
self.image = self._images["image"].copy()
|
||||
self._settings["menu"].update(time)
|
||||
self.image.blit(self._settings["menu"].image,self._settings["menu"].pos)
|
||||
|
||||
def _event(self, event):
|
||||
"""Send events to container."""
|
||||
self._settings["menu"]._event(event)
|
Loading…
Add table
Add a link
Reference in a new issue