Beispiel #1
0
class Canvas(HorizontalPanel):
    def __init__(self, SW, SH):
        HorizontalPanel.__init__(self)
        self.SW = SW
        self.SH = SH
        self.context = GWTCanvas(SW, SH, SW, SH)
        self.context.addStyleName("gwt-canvas")
        self.add(self.context)

    def draw(self, game):
        self.context.fillStyle = "#00AA00"
        self.context.fillRect(0, 0, SW, SH)
Beispiel #2
0
class MainWidget(HorizontalPanel):
    def __init__(self, SW, SH):
        HorizontalPanel.__init__(self)
        self.SW = SW
        self.SH = SH
        self.context = GWTCanvas(SW, SH, SW, SH)
        self.context.addStyleName("gwt-canvas")
        self.add(self.context)

    def draw(self, game=None):
        self.context.setFillStyle(Color.Color("#00AA00"))
        self.context.fillRect(0, 0, self.SW, self.SH)

        SP = self.SW // 8

        for x in range(0, self.SW, SP):
            self.context.beginPath()
            self.context.setStrokeStyle(Color.BLACK)
            self.context.setLineWidth(1)
            self.context.moveTo(x, 0)
            self.context.lineTo(x, self.SH)
            self.context.closePath()
            self.context.stroke()
        for y in range(0, self.SH, SP):
            self.context.beginPath()
            self.context.setStrokeStyle(Color.BLACK)
            self.context.setLineWidth(1)
            self.context.moveTo(0, y)
            self.context.lineTo(self.SW, y)
            self.context.closePath()
            self.context.stroke()

        # Draw pieces
        for (x, y) in [(x, y) for x in range(8) for y in range(8)]:
            if game.state[x][y] != Game.NONE:
                if game.state[x][y] == Game.BLACK:
                    self.context.setFillStyle(Color.BLACK)
                elif game.state[x][y] == Game.WHITE:
                    self.context.setFillStyle(Color.WHITE)
                self.context.beginPath()
                self.context.arc(x * SP + SP // 2, y * SP + SP // 2, SP // 2, 0, 2 * pi)
                self.context.closePath()
                self.context.fill()
    
        # Draw liberties
        for (x, y) in Game.liberties(game.current_player, game.state):
            self.context.setFillStyle(Color.WHITE)
            self.context.beginPath()
            self.context.arc(x * SP + SP // 2, y * SP + SP // 2, 4, 0, 2 * pi)
            self.context.closePath()
            self.context.fill()
Beispiel #3
0
class CanvasTest(object):
   def __init__(self):
      self.canvas = GWTCanvas(coordX = 400, coordY= 400, pixelX = 400, pixelY = 400)
      self.canvas.addStyleName("gwt-canvas")
      DOM.sinkEvents(self.canvas.getElement(), Event.MOUSEEVENTS)
      #DOM.setEventListener(self.canvas.getElement(), self)

      self.canvas.setFillStyle(Color.Color(255, 0, 0))
      self.canvas.fillRect(4,4,10,10)

      self._dragging = False
      #Register for canvas mouse events


      RootPanel().add(self.canvas)

   def onBrowserEvent(self, event):
      print "Event happened"
      kind = DOM.eventGetType(event)
      x = DOM.eventGetClientX(event) - DOM.getAbsoluteLeft(self.canvas.getElement())
      y = DOM.eventGetClientY(event) - DOM.getAbsoluteTop(self.canvas.getElement())
      print "Type of event: %s" % (kind)
      if kind == "mousedown":
         self._dragging = True
         self.onMouseDown(x,y)
      elif kind == "mousemove" and self._dragging:
         self.onMouseDrag(x,y)
      elif (kind == "mouseup" or kind == "mouseout") and self._dragging:
         self._dragging = False
         self.onMouseUp(x,y)

   def onMousedown(self, x, y):
      print "Mousedown"

   def onMouseDrag(self, x, y):
      print "Mouse dragging"

   def onMouseUp(self, x, y):
      print "Mouseup"
Beispiel #4
0
class MainPanel(VerticalPanel):
    CANVAS_WIDTH = 900
    CANVAS_HEIGHT = 700
    def __init__(self, owner):
        super(VerticalPanel, self).__init__()
        self.edgequeue = list()
        self.owner = owner
        self.InitialiseScreen()
        StaticObjectsTask(self.Draw).schedule(5000) #Poll every five seconds

    def EdgeListener(self, edge):
        self.edgequeue.append(edge.asDict())
        EdgePoster(self.edgequeue).schedule(1) #Schedule in the future so edges are sent in bulk

    def InitialiseScreen(self):
        hpanel = HorizontalPanel()
        self.add(hpanel)
        vpanelMenu = VerticalPanel()
        hpanel.add(vpanelMenu)
        self.addbutton = Button("Add Triangle")
        vpanelMenu.add(self.addbutton)
        self.addbutton.addClickListener(getattr(self, "addtriangle"))
        self.canvas = GWTCanvas(self.CANVAS_WIDTH, self.CANVAS_HEIGHT)
        vpanelCanvas = VerticalPanel()
        self.canvas.setWidth(self.CANVAS_WIDTH)
        self.canvas.setHeight(self.CANVAS_HEIGHT)
        hpanel.add(vpanelCanvas)
        vpanelCanvas.add(self.canvas)
        self.canvas.addMouseListener(self)
        self.selecteditem = None
        self.selectedhandle = None
        self.mouseisdown = False
        dc = DocumentCollection.documentcollection
        DocumentCollection.documentcollection.edgelistener = self.EdgeListener
        if len(dc.documentsbyclass[model.Drawing.__name__]) == 0:
            drawing = model.Drawing(None)
            dc.AddDocumentObject(drawing)
            EdgePoster([a.asDict() for a in drawing.history.GetAllEdges()])
        else:
            for k,v in dc.documentsbyclass[model.Drawing.__name__].iteritems():
                drawing = v
        self.drawingid = drawing.id
        self.Draw()

    def GetDrawing(self):
        return DocumentCollection.documentcollection.objectsbyid[self.drawingid]

    def sortfn(self, t1, t2):
        return cmp(t1.z_order, t2.z_order)

    def GetTrianglesAsList(self):
        #Return the triangles as an ordinary python list
        #triangles = [self.drawing.triangles.GetDocument().documentobjects[objid] for objid in self.drawing.triangles]
        triangles = list()
        for triangle in self.GetDrawing().triangles:
            #triangles = self.drawing.GetDocument().documentobjects[objid]
            triangles.append(triangle)
        if len(triangles) > 0:
            triangles.sort(self.sortfn)
        return triangles

    def DrawHandle(self,x,y):
        self.canvas.setFillStyle(Color.RED)
        self.canvas.beginPath()
        self.canvas.arc(x, y, 5, 0,  math.pi * 2, False)
        self.canvas.fill()

    def Draw(self):
        self.canvas.setFillStyle(Color.WHITE)
        self.canvas.fillRect(0, 0, self.CANVAS_WIDTH, self.CANVAS_HEIGHT)
        for t in self.GetTrianglesAsList():
            self.canvas.setFillStyle(Color.BLUE)
            self.canvas.setLineWidth(5)
            self.canvas.setStrokeStyle(Color.BLACK)
            self.canvas.setLineWidth(2)
            self.canvas.beginPath()
            self.canvas.moveTo(t.x1, t.y1)
            self.canvas.lineTo(t.x2, t.y2)
            self.canvas.lineTo(t.x3, t.y3)
            self.canvas.lineTo(t.x1, t.y1)
            self.canvas.fill()
            self.canvas.stroke()

            if self.selecteditem == t:
                self.canvas.setLineWidth(1)
                self.canvas.setStrokeStyle(Color.RED)
                self.canvas.beginPath()
                self.canvas.moveTo(t.x1, t.y1)
                self.canvas.lineTo(t.x2, t.y2)
                self.canvas.lineTo(t.x3, t.y3)
                self.canvas.lineTo(t.x1, t.y1)
                self.canvas.stroke()
            
                self.DrawHandle(t.x1, t.y1)
                self.DrawHandle(t.x2, t.y2)
                self.DrawHandle(t.x3, t.y3)

    def addtriangle(self, sender):
        left_margin = 50
        triangle_spacing = 150
        drawing = self.GetDrawing()
        c = len(drawing.triangles)
        posx = left_margin + c % ((self.CANVAS_WIDTH - left_margin) // triangle_spacing) * triangle_spacing
        posy = c // ((self.CANVAS_WIDTH - left_margin) // triangle_spacing) * triangle_spacing
        t = model.Triangle(None)
        drawing.triangles.add(t)
        t.z_order = c
        setattr(t, 'x1', posx)
        setattr(t, 'y1', posy + 50)
        setattr(t, 'x2', posx + 100)
        setattr(t, 'y2', posy + 100)
        setattr(t, 'x3', posx + 50)
        setattr(t, 'y3', posy + 150)
        self.Draw()
    

    def onMouseDown(self, sender, x, y):
        self.mouseisdown = True
        if self.selecteditem is not None:
            self.selectedhandle = None
            if HandleSelected(x,y, self.selecteditem.x1, self.selecteditem.y1):
                self.selectedhandle = 1
            elif HandleSelected(x,y, self.selecteditem.x2, self.selecteditem.y2):
                self.selectedhandle = 2
            elif HandleSelected(x,y, self.selecteditem.x3, self.selecteditem.y3):
                self.selectedhandle = 3
        if self.selectedhandle is None:
            self.selecteditem = self.FindTriangle(x,y)
        if self.selecteditem is None and self.selectedhandle is None:
            self.selectedhandle = None
        if self.selecteditem is not None:
            self.selecteditem.changessuspended = True
        self.Draw()
        self.lastx = x
        self.lasty = y

    def onMouseMove(self, sender, x, y):
        if self.selecteditem is not None and self.mouseisdown:
            diffx = x - self.lastx
            diffy = y - self.lasty
            t = self.selecteditem
            if self.selectedhandle is None:
                setattr(t, 'x1', t.x1 + diffx)
                setattr(t, 'y1', t.y1 + diffy)
                setattr(t, 'x2', t.x2 + diffx)
                setattr(t, 'y2', t.y2 + diffy)
                setattr(t, 'x3', t.x3 + diffx)
                setattr(t, 'y3', t.y3 + diffy)
            elif self.selectedhandle == 1:
                setattr(t, 'x1', t.x1 + diffx)
                setattr(t, 'y1', t.y1 + diffy)
            elif self.selectedhandle == 2:
                setattr(t, 'x2', t.x2 + diffx)
                setattr(t, 'y2', t.y2 + diffy)
            elif self.selectedhandle == 3:
                setattr(t, 'x3', t.x3 + diffx)
                setattr(t, 'y3', t.y3 + diffy)
            self.lastx = x
            self.lasty = y
            self.Draw()

    def onMouseUp(self, sender,x, y):
        if self.mouseisdown and self.selecteditem:
            t = self.selecteditem
            self.selecteditem.changessuspended = False
            setattr(t, 'x1', t.x1)
            setattr(t, 'y1', t.y1)
            setattr(t, 'x2', t.x2)
            setattr(t, 'y2', t.y2)
            setattr(t, 'x3', t.x3)
            setattr(t, 'y3', t.y3)
        self.mouseisdown = False

    def onMouseEnter(self, sender, x, y):
        pass

    def onMouseLeave(self, sender, x, y):
        pass

    def FindTriangle(self, x, y):
        pt = Point(x, y)
        for t in self.GetTrianglesAsList():
            if PointInTriangle(pt, t):
                return t
        return None
Beispiel #5
0
class HangDude(HorizontalPanel):
    def __init__(self):
        HorizontalPanel.__init__(self)
        self.context = GWTCanvas(300,300,300,300)
        self.context.addStyleName("gwt-canvas")
        self.add(self.context)

    def clear(self):
        self.context.clear()

    def draw(self, guesses):
        self.context.fillStyle = '#000'
        self.context.lineWidth = 2 
        if guesses == 1:
            self.context.fillRect(20, 280, 200,10)
        elif guesses == 2:
            self.context.fillRect(40, 20, 10, 260)
        elif guesses == 3:
            self.context.fillRect(20, 20, 160,10)
        elif guesses == 4:
            self.context.saveContext()
            self.context.translate(80,30)
            self.context.rotate(130 * math.pi / 180)
            self.context.fillRect(0,0, 50,10)
            self.context.restoreContext()
        elif guesses == 5:
            self.context.fillRect(140, 20, 10, 50)
        elif guesses == 6:
            self.context.beginPath()
            self.context.arc(145, 100, 30, 0, math.pi * 2, True)
            self.context.closePath()
            self.context.stroke()
        elif guesses == 7:
            self.context.fillRect(145, 130, 2, 80)
        elif guesses == 8:
            self.context.saveContext()
            self.context.translate(147,160)
            self.context.rotate(130 * math.pi / 180)
            self.context.fillRect(0,0, 50,2)
            self.context.restoreContext()
        elif guesses == 9:
            self.context.saveContext()
            self.context.translate(147,160)
            self.context.rotate(45 * math.pi / 180)
            self.context.fillRect(0,0, 50,2)
            self.context.restoreContext()
        elif guesses == 10:
            self.context.saveContext()
            self.context.translate(147,210)
            self.context.rotate(130 * math.pi / 180)
            self.context.fillRect(0,0, 60,2)
            self.context.restoreContext()
        elif guesses == 11:
            self.context.saveContext()
            self.context.translate(147,210)
            self.context.rotate(45 * math.pi / 180)
            self.context.fillRect(0,0, 60,2)
            self.context.restoreContext()
        self.context.restoreContext()
Beispiel #6
0
class HangDude(HorizontalPanel):
    def __init__(self):
        HorizontalPanel.__init__(self)
        self.context = GWTCanvas(300,300,300,300)
        self.context.addStyleName("gwt-canvas")
        self.add(self.context)

    def clear(self):
        self.context.clear()

    def draw(self, guesses):
        self.context.fillStyle = '#000'
        self.context.lineWidth = 2 
        if guesses == 1:
            self.context.fillRect(20, 280, 200,10)
        elif guesses == 2:
            self.context.fillRect(40, 20, 10, 260)
        elif guesses == 3:
            self.context.fillRect(20, 20, 160,10)
        elif guesses == 4:
            self.context.saveContext()
            self.context.translate(80,30)
            self.context.rotate(130 * math.pi / 180)
            self.context.fillRect(0,0, 50,10)
            self.context.restoreContext()
        elif guesses == 5:
            self.context.fillRect(140, 20, 10, 50)
        elif guesses == 6:
            self.context.beginPath()
            self.context.arc(145, 100, 30, 0, math.pi * 2, True)
            self.context.closePath()
            self.context.stroke()
        elif guesses == 7:
            self.context.fillRect(145, 130, 2, 80)
        elif guesses == 8:
            self.context.saveContext()
            self.context.translate(147,160)
            self.context.rotate(130 * math.pi / 180)
            self.context.fillRect(0,0, 50,2)
            self.context.restoreContext()
        elif guesses == 9:
            self.context.saveContext()
            self.context.translate(147,160)
            self.context.rotate(45 * math.pi / 180)
            self.context.fillRect(0,0, 50,2)
            self.context.restoreContext()
        elif guesses == 10:
            self.context.saveContext()
            self.context.translate(147,210)
            self.context.rotate(130 * math.pi / 180)
            self.context.fillRect(0,0, 60,2)
            self.context.restoreContext()
        elif guesses == 11:
            self.context.saveContext()
            self.context.translate(147,210)
            self.context.rotate(45 * math.pi / 180)
            self.context.fillRect(0,0, 60,2)
            self.context.restoreContext()
        self.context.restoreContext()
Beispiel #7
0
class MainPanel(VerticalPanel):
    CANVAS_WIDTH = 900
    CANVAS_HEIGHT = 700

    def __init__(self, owner):
        super(VerticalPanel, self).__init__()
        self.edgequeue = list()
        self.owner = owner
        self.InitialiseScreen()
        StaticObjectsTask(self.Draw).schedule(5000)  #Poll every five seconds

    def EdgeListener(self, edge):
        self.edgequeue.append(edge.asDict())
        EdgePoster(self.edgequeue).schedule(
            1)  #Schedule in the future so edges are sent in bulk

    def InitialiseScreen(self):
        hpanel = HorizontalPanel()
        self.add(hpanel)
        vpanelMenu = VerticalPanel()
        hpanel.add(vpanelMenu)
        self.addbutton = Button("Add Triangle")
        vpanelMenu.add(self.addbutton)
        self.addbutton.addClickListener(getattr(self, "addtriangle"))
        self.canvas = GWTCanvas(self.CANVAS_WIDTH, self.CANVAS_HEIGHT)
        vpanelCanvas = VerticalPanel()
        self.canvas.setWidth(self.CANVAS_WIDTH)
        self.canvas.setHeight(self.CANVAS_HEIGHT)
        hpanel.add(vpanelCanvas)
        vpanelCanvas.add(self.canvas)
        self.canvas.addMouseListener(self)
        self.selecteditem = None
        self.selectedhandle = None
        self.mouseisdown = False
        dc = DocumentCollection.documentcollection
        DocumentCollection.documentcollection.edgelistener = self.EdgeListener
        if len(dc.documentsbyclass[model.Drawing.__name__]) == 0:
            drawing = model.Drawing(None)
            dc.AddDocumentObject(drawing)
            EdgePoster([a.asDict() for a in drawing.history.GetAllEdges()])
        else:
            for k, v in dc.documentsbyclass[
                    model.Drawing.__name__].iteritems():
                drawing = v
        self.drawingid = drawing.id
        self.Draw()

    def GetDrawing(self):
        return DocumentCollection.documentcollection.objectsbyid[
            self.drawingid]

    def sortfn(self, t1, t2):
        return cmp(t1.z_order, t2.z_order)

    def GetTrianglesAsList(self):
        #Return the triangles as an ordinary python list
        #triangles = [self.drawing.triangles.GetDocument().documentobjects[objid] for objid in self.drawing.triangles]
        triangles = list()
        for triangle in self.GetDrawing().triangles:
            #triangles = self.drawing.GetDocument().documentobjects[objid]
            triangles.append(triangle)
        if len(triangles) > 0:
            triangles.sort(self.sortfn)
        return triangles

    def DrawHandle(self, x, y):
        self.canvas.setFillStyle(Color.RED)
        self.canvas.beginPath()
        self.canvas.arc(x, y, 5, 0, math.pi * 2, False)
        self.canvas.fill()

    def Draw(self):
        self.canvas.setFillStyle(Color.WHITE)
        self.canvas.fillRect(0, 0, self.CANVAS_WIDTH, self.CANVAS_HEIGHT)
        for t in self.GetTrianglesAsList():
            self.canvas.setFillStyle(Color.BLUE)
            self.canvas.setLineWidth(5)
            self.canvas.setStrokeStyle(Color.BLACK)
            self.canvas.setLineWidth(2)
            self.canvas.beginPath()
            self.canvas.moveTo(t.x1, t.y1)
            self.canvas.lineTo(t.x2, t.y2)
            self.canvas.lineTo(t.x3, t.y3)
            self.canvas.lineTo(t.x1, t.y1)
            self.canvas.fill()
            self.canvas.stroke()

            if self.selecteditem == t:
                self.canvas.setLineWidth(1)
                self.canvas.setStrokeStyle(Color.RED)
                self.canvas.beginPath()
                self.canvas.moveTo(t.x1, t.y1)
                self.canvas.lineTo(t.x2, t.y2)
                self.canvas.lineTo(t.x3, t.y3)
                self.canvas.lineTo(t.x1, t.y1)
                self.canvas.stroke()

                self.DrawHandle(t.x1, t.y1)
                self.DrawHandle(t.x2, t.y2)
                self.DrawHandle(t.x3, t.y3)

    def addtriangle(self, sender):
        left_margin = 50
        triangle_spacing = 150
        drawing = self.GetDrawing()
        c = len(drawing.triangles)
        posx = left_margin + c % ((self.CANVAS_WIDTH - left_margin) //
                                  triangle_spacing) * triangle_spacing
        posy = c // ((self.CANVAS_WIDTH - left_margin) //
                     triangle_spacing) * triangle_spacing
        t = model.Triangle(None)
        drawing.triangles.add(t)
        t.z_order = c
        setattr(t, 'x1', posx)
        setattr(t, 'y1', posy + 50)
        setattr(t, 'x2', posx + 100)
        setattr(t, 'y2', posy + 100)
        setattr(t, 'x3', posx + 50)
        setattr(t, 'y3', posy + 150)
        self.Draw()

    def onMouseDown(self, sender, x, y):
        self.mouseisdown = True
        if self.selecteditem is not None:
            self.selectedhandle = None
            if HandleSelected(x, y, self.selecteditem.x1,
                              self.selecteditem.y1):
                self.selectedhandle = 1
            elif HandleSelected(x, y, self.selecteditem.x2,
                                self.selecteditem.y2):
                self.selectedhandle = 2
            elif HandleSelected(x, y, self.selecteditem.x3,
                                self.selecteditem.y3):
                self.selectedhandle = 3
        if self.selectedhandle is None:
            self.selecteditem = self.FindTriangle(x, y)
        if self.selecteditem is None and self.selectedhandle is None:
            self.selectedhandle = None
        if self.selecteditem is not None:
            self.selecteditem.changessuspended = True
        self.Draw()
        self.lastx = x
        self.lasty = y

    def onMouseMove(self, sender, x, y):
        if self.selecteditem is not None and self.mouseisdown:
            diffx = x - self.lastx
            diffy = y - self.lasty
            t = self.selecteditem
            if self.selectedhandle is None:
                setattr(t, 'x1', t.x1 + diffx)
                setattr(t, 'y1', t.y1 + diffy)
                setattr(t, 'x2', t.x2 + diffx)
                setattr(t, 'y2', t.y2 + diffy)
                setattr(t, 'x3', t.x3 + diffx)
                setattr(t, 'y3', t.y3 + diffy)
            elif self.selectedhandle == 1:
                setattr(t, 'x1', t.x1 + diffx)
                setattr(t, 'y1', t.y1 + diffy)
            elif self.selectedhandle == 2:
                setattr(t, 'x2', t.x2 + diffx)
                setattr(t, 'y2', t.y2 + diffy)
            elif self.selectedhandle == 3:
                setattr(t, 'x3', t.x3 + diffx)
                setattr(t, 'y3', t.y3 + diffy)
            self.lastx = x
            self.lasty = y
            self.Draw()

    def onMouseUp(self, sender, x, y):
        if self.mouseisdown and self.selecteditem:
            t = self.selecteditem
            self.selecteditem.changessuspended = False
            setattr(t, 'x1', t.x1)
            setattr(t, 'y1', t.y1)
            setattr(t, 'x2', t.x2)
            setattr(t, 'y2', t.y2)
            setattr(t, 'x3', t.x3)
            setattr(t, 'y3', t.y3)
        self.mouseisdown = False

    def onMouseEnter(self, sender, x, y):
        pass

    def onMouseLeave(self, sender, x, y):
        pass

    def FindTriangle(self, x, y):
        pt = Point(x, y)
        for t in self.GetTrianglesAsList():
            if PointInTriangle(pt, t):
                return t
        return None
Beispiel #8
0
class Dash:

    def __init__(self):

        self.p = VerticalPanel(Width="700px", Height="700px",
                               StyleName="dashpanel")
        RootPanel().add(self.p)
        self.log = HTML("log", Width="500px", Height="100px")

        self.cwidth = 700.0
        self.cheight = 700.0
        self.canvas = GWTCanvas(self.cwidth, self.cheight)
        self.canvas.resize(self.cwidth, self.cheight)
        self.p.add(self.canvas)
        self.p.add(self.log)
        self.cwidth = 700.0
        self.cheight = 700.0
        #self.offset_x = 423.0-233#240.0
        #self.offset_y = 153.0-220#-100.0
        self.offset_x = 0.0
        self.offset_y = 0.0
        self.scale = 1.0
        self.target_scale = 1.0
        self.move_allowed = False

        w2 = self.cwidth / 2.0
        h2 = self.cheight / 2.0

        self.word_chain = get_test_letters()
        # TODO: make a fake "top level" LetterNode, which these are added to
        self.letters = self.get_more_letters()
        self.root_node = self.letters

        self.cur_time = time()
        self.mouse_pos_x = w2
        self.mouse_pos_y = h2

        self.redraw_required = True
        #self.draw()

        Timer(50, self)

        self.canvas.addMouseListener(self)

    def new_mouse_pos(self, x, y):
        el = self.canvas.getElement()
        self.mouse_pos_x = x - DOM.getAbsoluteLeft(el)
        self.mouse_pos_y = y - DOM.getAbsoluteTop(el)

    def onMouseDown(self, sender, x, y):
        self.move_allowed = True
        self.new_mouse_pos(x, y)

    def onMouseUp(self, sender, x, y):
        self.move_allowed = False
        self.new_mouse_pos(x, y)

    def onMouseMove(self, sender, x, y):
        self.new_mouse_pos(x, y)

    def onMouseEnter(self, sender):
        pass

    def onMouseLeave(self, sender):
        self.move_allowed = False

    def onTimer(self, timer):
        
        new_time = time()
        diff_time = new_time - self.cur_time
        self.cur_time = new_time

        self.log_txt = "time: %.2f<br/>test<br/>" % self.cur_time

        scale = diff_time / (self.scale)

        #print self.move_allowed, "%.3f" % diff_time, self.mouse_pos_x, self.mouse_pos_y

        scale_diff = math.log10(self.target_scale) - math.log10(self.scale)
        scale_diff = scale_diff * diff_time * 2
        self.scale = math.pow(10, math.log10(self.scale) + scale_diff)

        if self.move_allowed:
            w2 = self.cwidth / 2.0
            h2 = self.cheight / 2.0
            x_vel = scale * (self.mouse_pos_x - w2)
            y_vel = scale * (self.mouse_pos_y - h2)

            self.offset_x += x_vel
            self.offset_y += y_vel
            self.redraw_required = True

        elif abs(scale_diff) > 1e-15:
            self.redraw_required = True

        if self.redraw_required:
            self.draw()

        self.log.setHTML(self.log_txt)

        Timer(50, self)

    def draw(self):

        self.canvas.resize(self.cwidth, self.cheight)
        self.redraw_required = False

        w2 = self.cwidth / 2.0
        h2 = self.cheight / 2.0

        self.closest = [None, None]

        self.get_closest(0.0, 0.0, self.cwidth, self.cheight,
                                self.root_node)

        #print self.closest

        scale = calc_scale(self.closest[0], self.closest[1],
                                  self.offset_x,
                                    self.offset_y+h2,
                                    self.cheight)
        self.target_scale = scale

        self.log_txt += "scale: %f<br/>" % self.scale
        self.log_txt += "targetscale: %f<br/>" % self.target_scale

        #print "scale:", self.scale, self.target_scale

        x1 = self.offset_x + (self.cwidth / self.scale)
        y1 = self.offset_y + (self.cheight / self.scale)

        #print "redbox", self.offset_x, self.offset_y, x1, y1

        self.canvas.saveContext()
        self.canvas.clear()

        #self.canvas.setFillStyle(Color("#888"))
        #self.canvas.setLineWidth(1)
        #self.canvas.fillRect(0, 0, self.cwidth, self.cheight)

        self.display_letters(None, 0.0, 0.0, self.cwidth, self.cheight,
                                self.root_node, 0)

        self.canvas.restoreContext()

        #print self.closest

    def sr(self, x, y, w, h):
        #sw = (self.cwidth/2/self.scale)
        #sh = (self.cheight/2/self.scale)
        sw = self.cwidth/2.0
        sh = self.cheight/2.0
        rect = (-sw*self.scale+(x+(-self.offset_x+sw/self.scale))*self.scale,
                -sh*self.scale+(y+(-self.offset_y+sh/self.scale))*self.scale,
                w*self.scale,
                h*self.scale)
        #print "rect", x,y,w,h, rect
        return rect

    def check_closest(self, letter, x, y):
        """ this function gets the two closest letters to the current cursor.
        """
        #print self.closest
        if self.closest[0] is None:
            #print "none"
            self.closest[0] = letter
        else:
            #print x, y, letter.x, letter.y
            if _check_closest(self.closest[0], letter, x, y):
                return
            self.closest[1] = self.closest[0]
            self.closest[0] = letter

    def get_closest(self, px, py, pwidth, pheight, letters):

        if not letters:
            return

        length = len(letters)
        amount_use = 1.0
        oy = 0.0 # pheight * (1.0-amount_use) / 2.0
        for i, letter in enumerate(letters):
            height = letter.weight * pheight 
            width  = letter.weight * pwidth
            letter.x = px+(pwidth - width) #+ height * 0.1
            letter.y = py+oy
            letter.box_width = width
            letter.box_height = height * amount_use

            cursor_x = self.offset_x + (self.cwidth/2.0)
            cursor_y = self.offset_y + (self.cheight/2.0)

            if _inside(letter, cursor_x, cursor_y):
                self.inside_letter = letter

            self.get_closest(letter.x, letter.y,
                                 letter.box_width, letter.box_height,
                                 letter)
            self.check_closest(letter, cursor_x, cursor_y)

            oy += letter.box_height

    def get_more_letters(self, letter=None):
        res = []
        if letter is None or letter.word_ptr is None or \
           len(letter.word_ptr) == 0:
            chain = self.word_chain
        else:
            chain = letter.word_ptr
        for l in chain:
            ln = LetterNode(l.letter, l.weight, parent=l.parent)
            ln.word_ptr = l
            res.append(ln)
        #print "letter", letter
        #pprint_letters(res)
        return res

    def display_letters(self, ch, px, py, pwidth, pheight, letters, colouridx):

        if colouridx == 0:
            col = Color("#ccf")
            altcol = Color("#88f")
        elif colouridx == 1:
            col = Color("#fcc")
            altcol = Color("#f88")
        else:
            col = Color("#cfc")
            altcol = Color("#8f8")

        self.canvas.setLineWidth(1)
        x, y, w, h = self.sr(px, py, pwidth, pheight)

        if y + h < 0:
            return
        if y > self.cheight:
            return
        if x + w < 0:
            return
        if x > self.cwidth:
            return

        self.canvas.fillRect(x, y, w, h)

        if ch:
            self.canvas.setFillStyle(Color("#000"))
            self.canvas.fillText(ch, x, y + h)

        if h < 20:
            return

        if not letters:
            more = self.get_more_letters(letters)
            self.redraw_required = True
            return more

        if not letters:
            return

        newidx = (colouridx+1) % 3
        length = len(letters)
        oy = 0
        for i, letter in enumerate(letters):
            height = letter.box_width
            width  = letter.box_height
            if i % 2 == 0:
                self.canvas.setFillStyle(col)
            else:
                self.canvas.setFillStyle(altcol)
            more = self.display_letters(letter.letter, letter.x, letter.y,
                                 width, height,
                                 letter, newidx)
            if more:
                for l in more:
                    letter.append(l)
            oy += height