126 lines
4.7 KiB
Python
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)
|