From 556cdf2d27560b6b9aeb4dac0f98ad8da2a937c0 Mon Sep 17 00:00:00 2001 From: jmpc Date: Wed, 28 Oct 2009 04:37:58 +0000 Subject: Agregados los eventos de expose y button_press al widget Cake. --- diff --git a/cake.py b/cake.py index b68db41..f2e14a3 100755 --- a/cake.py +++ b/cake.py @@ -12,95 +12,117 @@ import gtk import cairo +WIDTH = 500 +HEIGHT = 500 +RADIUS = 220 WRADIUS = 0.44 -def draw_grid(context, N): - context.set_source_rgb(0, 0, 0) - context.arc(250, 250, 500*WRADIUS, 0, 2 * math.pi) - context.stroke() - for i in xrange(N): - angle = 2 * math.pi * i / N - context.move_to(250, 250) - context.line_to( - 250 + 500*WRADIUS*math.cos(angle), - 250 + 500*WRADIUS*math.sin(angle) - ) - context.stroke() - - -def mask_image(context, selected, image): - context.set_source_surface(image, 0, 0) - context.paint() - - class Cake(gtk.DrawingArea): + """Widget que dibuja una torta y permite seleccionar trozos de ella""" + def __init__(self, N): gtk.DrawingArea.__init__(self) self.connect("expose_event", self.expose) - #self.N = N - #self.selected = N * [0] - self.N = 5 - self.selected = [0, 0, 1, 1, 1] + self.connect("button_press_event", self.button_press) + # Los eventos del raton no estan activados para el DrawingArea + self.add_events(gtk.gdk.BUTTON_PRESS_MASK) + self.N = N + self.selected = N * [0] def expose(self, widget, event): + """Manejador del evento expose_event""" context = widget.window.cairo_create() - # set a clip region for the expose event + # Elegimos solo la region expuesta al evento context.rectangle(event.area.x, event.area.y, event.area.width, event.area.height) context.clip() - self.draw_image(context) - return False + self.draw(context) + def button_press(self, widget, event): + """Manejador del evento button_press_event""" + x, y = event.get_coords() + if self.select(x, y): + self.draw(widget.window.cairo_create()) + + def draw(self, context): - rect = self.get_allocation() - x = rect.x + rect.width / 2 - y = rect.y + rect.height / 2 - radius = min(rect.width / 2, rect.height / 2) - 5 - context.arc(x, y, radius, 0, 2 * math.pi) - context.set_source_rgb(1, 1, 1) - context.fill_preserve() - context.set_source_rgb(0, 0, 0) - context.stroke() - - - def draw_image(self, context): - # Load images + """Dibuja el contenido del widget""" + + def draw_grid(context, N): + """Dibuja la rejilla de la torta y sus subdivisiones""" + context.set_source_rgb(0, 0, 0) + context.arc(WIDTH/2, HEIGHT/2, RADIUS, 0, 2 * math.pi) + context.stroke() + for i in xrange(N): + angle = 2 * math.pi * i / N + context.move_to(WIDTH/2, HEIGHT/2) + context.line_to( + WIDTH/2 + RADIUS*math.cos(angle), + HEIGHT/2 + RADIUS*math.sin(angle) + ) + context.stroke() + + + def mask_image(context, selected, image): + """Enmascara la imagen de la torta y dibuja solo los trozos que no + fueron seleccionados + """ + N = len(selected) + image_ctx = cairo.Context(image) + image_ctx.set_operator(cairo.OPERATOR_CLEAR) + for sector in xrange(N): + if selected[sector]: + angle_start = 2 * math.pi * sector / N + angle_end = 2 * math.pi * (sector + 1) / N + image_ctx.move_to(WIDTH/2, HEIGHT/2) + image_ctx.line_to( + WIDTH/2 + RADIUS*math.cos(angle_start), + HEIGHT/2 + RADIUS*math.sin(angle_start) + ) + image_ctx.arc(WIDTH/2, HEIGHT/2, RADIUS, angle_start, + angle_end) + image_ctx.close_path() + image_ctx.fill() + context.set_source_surface(image) + context.paint() + + + # Carga imagenes image_bg = cairo.ImageSurface.create_from_png("bg.png") image_fg = cairo.ImageSurface.create_from_png("fg.png") - # Scale the surface + # Escala la imagen al tamaƱo de la superficie rect = self.get_allocation() context.save() context.scale( - #float(rect.width) / float(image.get_width()), - #float(rect.height) / float(image.get_height()) - rect.width / 500.0, - rect.height / 500.0, + float(rect.width) / WIDTH, + float(rect.height) / HEIGHT ) - # Draw the background + # Dibuja el fondo context.set_source_surface(image_bg, 0, 0) context.paint() - # Draw the foreground + # Dibuja el frente mask_image(context, self.selected, image_fg) - # Draw the grid + # Dibuja la rejilla draw_grid(context, self.N) context.restore() def select(self, ux, uy): - """ - Si x, y esta dentro de la torta cambiamos el sector. - - """ - # Transformamos las coordenadas del usuario al rango 0.0, 1.0. + """Selecciona un trozo de la torta. Devuelve True si un objeto fue + seleccionado, False en caso contrario.""" + # Transformamos las coordenadas del usuario a coordenadas reales (0-1) rect = self.get_allocation() wx = float(ux - rect.x) / float(rect.width) wy = float(uy - rect.y) / float(rect.height) + # Centramos + wx -= 0.5 + wy -= 0.5 if math.pow(wx, 2) + math.pow(wy, 2) > math.pow(WRADIUS, 2): return False angle = math.atan2(wy, wx) @@ -112,16 +134,11 @@ class Cake(gtk.DrawingArea): return True -def main(): +if __name__ == "__main__": + # Probamos el nuevo widget Cake window = gtk.Window() cake = Cake(6) - window.add(cake) window.connect("destroy", gtk.main_quit) window.show_all() - gtk.main() - - -if __name__ == "__main__": - main() -- cgit v0.9.1