Added a copy of SGC
This commit is contained in:
parent
90ff7ceba8
commit
52eb18994d
22 changed files with 3283 additions and 0 deletions
162
sgc/widgets/button.py
Normal file
162
sgc/widgets/button.py
Normal file
|
@ -0,0 +1,162 @@
|
|||
#!/usr/bin/env python
|
||||
|
||||
# Copyright (C) 2010-2012 Sam Bull
|
||||
|
||||
"""
|
||||
Button widget, allows input from the user clicking the button.
|
||||
|
||||
"""
|
||||
|
||||
import pygame
|
||||
from pygame.locals import *
|
||||
|
||||
from _locals import *
|
||||
from base_widget import Simple
|
||||
|
||||
class Button(Simple):
|
||||
|
||||
"""
|
||||
A clickable button.
|
||||
|
||||
Images:
|
||||
'image': The default button state.
|
||||
'over': The image used when the cursor is hovering over the button.
|
||||
'down': The image used when the user is clicking down on the button.
|
||||
|
||||
"""
|
||||
|
||||
_can_focus = True
|
||||
_default_size = (110, 50)
|
||||
_available_images = ("over", "down")
|
||||
_settings_default = {"label": ("",), "col": (127, 127, 169),
|
||||
"label_col": Font.col}
|
||||
|
||||
_state = None
|
||||
_draw_rect = False
|
||||
|
||||
def _config(self, **kwargs):
|
||||
"""
|
||||
label: ``str`` Text to display on the button.
|
||||
col: ``tuple`` (r,g,b) The central colour used if no image is
|
||||
provided. If you want to avoid the colours saturating keep the
|
||||
RGB values below 200.
|
||||
label_col: ``tuple`` (r,g,b) The text colour for the button's label.
|
||||
|
||||
"""
|
||||
# Label in middle of button
|
||||
if "label" in kwargs:
|
||||
# Save string as first argument
|
||||
self._settings["label"] = [kwargs["label"]]
|
||||
self._draw_label()
|
||||
if "col" in kwargs:
|
||||
self._settings["col"] = kwargs["col"]
|
||||
if "label_col" in kwargs:
|
||||
self._settings["label_col"] = kwargs["label_col"]
|
||||
self._draw_label()
|
||||
|
||||
def _draw_label(self):
|
||||
# Clear previous renderings
|
||||
del self._settings["label"][1:]
|
||||
label = self._settings["label"][0].split("\n")
|
||||
for count, line in enumerate(label):
|
||||
lbl = Simple(Font["widget"].render(line, True,
|
||||
self._settings["label_col"]))
|
||||
self._settings["label"].append(lbl)
|
||||
y = (self.rect.h - (lbl.rect.h * len(label))) / 2 + \
|
||||
(lbl.rect.h * count)
|
||||
lbl.rect.midtop = (self.rect.w/2, y)
|
||||
|
||||
def _draw(self, draw):
|
||||
# Frames around edge of button
|
||||
x = min(self.image.get_size()) / 8
|
||||
self._frame_lt = ((0,0), (self.rect.w,0), (self.rect.w-x,x),
|
||||
(x,x), (x,self.rect.h-x), (0,self.rect.h))
|
||||
self._frame_rb = ((self.rect.w,self.rect.h),
|
||||
(0,self.rect.h), (x,self.rect.h-x),
|
||||
(self.rect.w-x,self.rect.h-x),
|
||||
(self.rect.w-x,x), (self.rect.w,0))
|
||||
cols = {}
|
||||
cols["image"] = self._settings["col"]
|
||||
cols["over"] = [min(c*1.1, 255) for c in self._settings["col"]]
|
||||
cols["down"] = [c*0.8 for c in self._settings["col"]]
|
||||
for img in cols:
|
||||
if not self._custom_image:
|
||||
self._images[img].fill(cols[img])
|
||||
# Draw a frame around the edges of the button
|
||||
frame_lt_c = [min(c*1.3,255) for c in cols[img]]
|
||||
frame_rb_c = [c*0.8 for c in cols[img]]
|
||||
draw.polygon(self._images[img], frame_lt_c, self._frame_lt)
|
||||
draw.polygon(self._images[img], frame_rb_c, self._frame_rb)
|
||||
# Blit label onto button
|
||||
for line in self._settings["label"][1:]:
|
||||
self._images[img].blit(line.image, line.pos)
|
||||
self._draw_button()
|
||||
|
||||
def activate(self):
|
||||
"""
|
||||
Called when the button is activated.
|
||||
|
||||
Emits an event with attribute 'gui_type' == "activate".
|
||||
|
||||
Override this function to use as a callback handler.
|
||||
|
||||
"""
|
||||
ev = pygame.event.Event(GUI, {"gui_type": "activate",
|
||||
"widget_type": self.__class__,
|
||||
"widget":self})
|
||||
pygame.event.post(ev)
|
||||
|
||||
def update(self, time):
|
||||
"""Update the button each frame."""
|
||||
if self.rect_abs.collidepoint(pygame.mouse.get_pos()):
|
||||
if self._state not in ("over","down"):
|
||||
# Draw over state
|
||||
self._state = "over"
|
||||
self._draw_button()
|
||||
elif self._state not in ("off","down"):
|
||||
# Draw normal state
|
||||
self._state = "off"
|
||||
self._draw_button()
|
||||
|
||||
def _event(self, event):
|
||||
"""Respond to events."""
|
||||
if event.type == MOUSEBUTTONDOWN and event.button == 1:
|
||||
# Draw down state
|
||||
self._state = "down"
|
||||
self._draw_button()
|
||||
elif event.type == MOUSEBUTTONUP and event.button == 1:
|
||||
self._state = None
|
||||
# If releasing mouse on button, call function
|
||||
if self.rect_abs.collidepoint(event.pos):
|
||||
self.activate()
|
||||
elif event.type == KEYDOWN:
|
||||
if event.key in (K_SPACE, K_RETURN):
|
||||
self._state = "down"
|
||||
self._draw_button()
|
||||
self.activate()
|
||||
elif event.type == KEYUP:
|
||||
if event.key in (K_SPACE, K_RETURN):
|
||||
self._state = None
|
||||
|
||||
def _focus_enter(self, focus):
|
||||
"""Draw rectangle when focus is gained from keyboard."""
|
||||
if focus == 1:
|
||||
self._draw_rect = True
|
||||
self._draw_button()
|
||||
|
||||
def _focus_exit(self):
|
||||
"""Stop drawing rectangle when focus is lost."""
|
||||
self._draw_rect = False
|
||||
self._draw_button()
|
||||
|
||||
def _draw_button(self):
|
||||
"""Draw the button."""
|
||||
if self._state == "off":
|
||||
self.image = self._images["image"].copy()
|
||||
elif self._state == "over":
|
||||
self.image = self._images["over"].copy()
|
||||
elif self._state == "down":
|
||||
self.image = self._images["down"].copy()
|
||||
# Draw dotted rectangle to show keyboard focus
|
||||
if self._draw_rect:
|
||||
self._dotted_rect()
|
Loading…
Add table
Add a link
Reference in a new issue