pygo/sgc/widgets/dialog.py
2012-04-14 18:38:47 -04:00

126 lines
4.7 KiB
Python

#!/usr/bin/env python
# Copyright (C) 2010-2012 Sam Bull
"""
Dialog window, creates a popup window.
"""
import pygame.mouse
from pygame.locals import *
from _locals import *
from base_widget import Simple
class Dialog(Simple):
"""
Dialog Window
If ``surf`` is not given, window will be large enough to fit the
given widget.
"""
_can_focus = True
_modal = True
_layered = True
_settings_default = {"title": None, "widget": None, "col_bg": (240,240,240),
"col_border": (50,40,90)}
_drag = _over = False
def _config(self, **kwargs):
"""
widget: Widget that should be displayed in the dialog window.
title: ``str`` Text to display in the title bar.
col_border: ``tuple`` (r,g,b) Window decoration colour.
col_bg: ``tuple`` (r,g,b) Background colour.
modal: ``bool`` ``True`` if window should be modal.
Defaults to ``True``.
"""
if "widget" in kwargs:
self._settings["widget"] = kwargs["widget"]
self._settings["widget"]._parent = self
self._settings["widget"].pos = (2, 20)
if not hasattr(self, "image"):
r = self._settings["widget"].rect
self._create_base_images((r.w + 4, r.h + 22))
if "title" in kwargs:
self._settings["title"] = kwargs["title"]
if "col_border" in kwargs:
self._settings["col_border"] = kwargs["col_border"]
if "col_bg" in kwargs:
self._settings["col_bg"] = kwargs["col_bg"]
if "modal" in kwargs:
self._modal = kwargs["modal"]
def _draw(self, draw):
# Draw window
inner_rect = Rect((2,20), (self.rect.w-4,self.rect.h-22))
self._images["image"].fill(self._settings["col_border"])
self._images["image"].fill(self._settings["col_bg"], inner_rect)
if self._settings["title"]:
t = Simple(Font["widget"].render(
self._settings["title"], True, Font.col), pos = (22,0))
self._images["image"].blit(t.image, t.pos)
# Close button
self._close_off = Simple((16,16), parent=self)
self._close_off.image.fill(self._settings["col_border"])
draw.circle(self._close_off.image, (140,6,15), (8,8), 8)
draw.line(self._close_off.image, (0,0,1), (5,5), (11,11), 3)
draw.line(self._close_off.image, (0,0,1), (5,11), (11,5), 3)
self._close_over = Simple((16,16), parent=self)
self._close_over.image.fill(self._settings["col_border"])
draw.circle(self._close_over.image, (234,14,50), (8,8), 8)
draw.line(self._close_over.image, (0,0,1), (5,5), (11,11), 5)
draw.line(self._close_over.image, (0,0,1), (5,11), (11,5), 5)
self._close_off.pos = self._close_over.pos = (1,1)
self.image = self._images["image"].copy()
self.image.blit(self._close_off.image, self._close_off.pos)
def update(self, time):
"""Update dialog window each frame."""
r = self._close_off.rect_abs
if not self._over and r.collidepoint(pygame.mouse.get_pos()):
# Display over button
self.image = self._images["image"].copy()
self.image.blit(self._close_over.image, self._close_over.pos)
self._over = True
elif self._over and not r.collidepoint(pygame.mouse.get_pos()):
# Display normal button
self.image = self._images["image"].copy()
self.image.blit(self._close_off.image, self._close_off.pos)
self._over = False
self._settings["widget"].update(time)
self.image.blit(self._settings["widget"].image,
self._settings["widget"].pos)
def _event(self, event):
"""Respond to events."""
minus_pos = lambda p1, p2: (p1[0] - p2[0], p1[1] - p2[1])
if event.type == MOUSEBUTTONDOWN and event.button == 1 and \
self.rect.collidepoint(event.pos) and event.pos[1] < self.rect.y + 20:
# Clicking title bar of window
if self._close_off.rect_abs.collidepoint(event.pos):
# Close button
self.remove()
else:
# Initialise window drag
self._offset = minus_pos(event.pos, self.pos)
self._drag = True
elif event.type == MOUSEMOTION and self._drag:
# Move window
self.pos = minus_pos(event.pos, self._offset)
elif event.type == MOUSEBUTTONUP and event.button == 1 and self._drag:
# Stop moving window
self.pos = minus_pos(event.pos, self._offset)
self._drag = False
else:
self._settings["widget"]._event(event)