#!/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)