diff options
Diffstat (limited to 'turtlewidget.py')
-rw-r--r-- | turtlewidget.py | 134 |
1 files changed, 134 insertions, 0 deletions
diff --git a/turtlewidget.py b/turtlewidget.py new file mode 100644 index 0000000..4bcf0eb --- /dev/null +++ b/turtlewidget.py @@ -0,0 +1,134 @@ +""" +TurtleWidget is defined in this module, see its documentation. +""" + +import time +import Queue +import math + +from gi.repository import Gtk, Gdk, GObject +import cairo + +from vector import Vector +from my_turtle import * +import misc.dumpqueue as dumpqueue +from misc.fromresourcefolder import from_resource_folder + +BITMAP_X = 1200 +BITMAP_Y = 900 + +class TurtleWidget(Gtk.DrawingArea): + """ + A Gtk Drawing Area widget to display the turtle and all the drawings that + it made. + """ + def __init__(self,turtle_queue): + Gtk.DrawingArea.__init__(self) + + #self.BACKGROUND_COLOR = wx.Colour(212,208,200) + self.TURTLE_IMAGE = cairo.ImageSurface.create_from_png(from_resource_folder("turtle.png")) + self.turtle_w = self.TURTLE_IMAGE.get_width() + self.turtle_h = self.TURTLE_IMAGE.get_height() + self.turtle = Turtle() + + self.count = 0 + #bitmap=self.bitmap=wx.EmptyBitmapRGBA(2000,1200,BACKGROUND_COLOR[0],BACKGROUND_COLOR[1],BACKGROUND_COLOR[2],255) # todo: Change to something smarter? + #self.bitmap = wx.EmptyBitmap(*BITMAP_SIZE) + self.bitmap = cairo.ImageSurface(cairo.FORMAT_RGB24, BITMAP_X, BITMAP_Y) + self.connect("draw", self.on_paint) + GObject.timeout_add(30, self.on_idle) + #GObject.idle_add(self.on_idle) + + #self.Bind(wx.EVT_SIZE,self.on_size) + + self.turtle_queue = turtle_queue + + self.idle_block = False + + def on_paint(self, widget, cr): + """ + Paint event handler. Reads the turtle reports and draws graphics + accordingly. + """ + # Translate to (0, 0) is in the center + w = self.get_allocation().width + h = self.get_allocation().height + + cxt = cairo.Context(self.bitmap) # The drawing context for the bitmap + cxt.translate(w/2, h/2) + + turtle_reports=dumpqueue.dump_queue(self.turtle_queue) + for turtle_report in turtle_reports: + if turtle_report.pen_down is True: + cxt.set_source_rgb(*self.turtle.rgb_color) + cxt.set_line_width(self.turtle.width) + cxt.move_to(*(-self.turtle.pos)) + cxt.line_to(*(-turtle_report.pos)) + #if turtle_report.clear is True: + # brush=wx.Brush("black") + # dc.SetBackground(brush) + # dc.Clear() + self.turtle = turtle_report + cxt.stroke() + + if len(turtle_reports) > 0: + pass + #self.queue_draw() + + # Draw the bitmap + cr.set_source_surface(self.bitmap, 0, 0) + cr.paint() + + if self.turtle.visible: + p = -self.turtle.pos + x = p[0] + w/2 + y = p[1] + h/2 + cr.translate(x, y) + cr.rotate(math.radians(self.turtle.orientation - 180)) + cr.translate(-x, -y) + cr.set_source_surface(self.TURTLE_IMAGE, x - self.turtle_w/2, y - self.turtle_h/2) + cr.paint() + + + # Draw the turtle: + #if self.turtle.visible: + # new_pos = top_left_corner + from_my_pos(self.turtle.pos) + # draw_bitmap_to_dc_rotated(dc, self.TURTLE_IMAGE, from_my_angle(self.turtle.orientation), new_pos) + #dc.Destroy() + + + + def on_idle(self,e=None): + """ + Idle event handler. Checks whether there are any + pending turtle reports, and if there are tells the widget + to process them. + """ + if self.idle_block==True: return True + + if not self.turtle_queue.empty(): self.queue_draw() + return True + #wx.CallLater(30,self._clear_idle_block_and_do) # Should make the delay customizable? + #self.idle_block=True + + + def _clear_idle_block_and_do(self): + self.idle_block=False + event=wx.PyEvent() + event.SetEventType(wx.wxEVT_IDLE) + wx.PostEvent(self,event) + + def on_size(self,e=None): + self.Refresh() + + + +def draw_bitmap_to_dc_rotated( dc, bitmap, angle , point): + """ + Rotate a bitmap and write it to the supplied device context. + """ + img = bitmap.ConvertToImage() + img_centre = wx.Point( img.GetWidth()/2.0, img.GetHeight()/2.0 ) + img = img.Rotate( angle, img_centre , interpolating=True) + new_point=Vector(point)-Vector(img.GetSize())/2 + dc.DrawBitmapPoint( img.ConvertToBitmap(), new_point,useMask=True ) |