]> git.saurik.com Git - wxWidgets.git/blobdiff - wxPython/samples/doodle/doodle.py
docstring update
[wxWidgets.git] / wxPython / samples / doodle / doodle.py
index dbfa8b39c63953119f6934ed4e27f28ed5d64431..47e01d9e6d82ee7d3c0df041cc770c7f782a3ff3 100644 (file)
@@ -6,11 +6,11 @@ can do simple drawings upon.
 """
 
 
-from wxPython.wx import *
+import wx                  # This module uses the new wx namespace
 
 #----------------------------------------------------------------------
 
-class DoodleWindow(wxWindow):
+class DoodleWindow(wx.Window):
     menuColours = { 100 : 'Black',
                     101 : 'Yellow',
                     102 : 'Red',
@@ -32,40 +32,64 @@ class DoodleWindow(wxWindow):
 
 
     def __init__(self, parent, ID):
-        wxWindow.__init__(self, parent, ID)
-        self.SetBackgroundColour(wxWHITE)
+        wx.Window.__init__(self, parent, ID, style=wx.NO_FULL_REPAINT_ON_RESIZE)
+        self.SetBackgroundColour("WHITE")
         self.listeners = []
         self.thickness = 1
         self.SetColour("Black")
         self.lines = []
-        self.x = self.y = 0
+        self.pos = wx.Point(0,0)
         self.MakeMenu()
 
+        self.InitBuffer()
+
+        self.SetCursor(wx.StockCursor(wx.CURSOR_PENCIL))
+
         # hook some mouse events
-        EVT_LEFT_DOWN(self, self.OnLeftDown)
-        EVT_LEFT_UP(self, self.OnLeftUp)
-        EVT_RIGHT_UP(self, self.OnRightUp)
-        EVT_MOTION(self, self.OnMotion)
+        self.Bind(wx.EVT_LEFT_DOWN, self.OnLeftDown)
+        self.Bind(wx.EVT_LEFT_UP, self.OnLeftUp)
+        self.Bind(wx.EVT_RIGHT_UP, self.OnRightUp)
+        self.Bind(wx.EVT_MOTION, self.OnMotion)
+
+        # the window resize event and idle events for managing the buffer
+        self.Bind(wx.EVT_SIZE, self.OnSize)
+        self.Bind(wx.EVT_IDLE, self.OnIdle)
 
         # and the refresh event
-        EVT_PAINT(self, self.OnPaint)
+        self.Bind(wx.EVT_PAINT, self.OnPaint)
+
+        # When the window is destroyed, clean up resources.
+        self.Bind(wx.EVT_WINDOW_DESTROY, self.Cleanup)
+
+
+    def Cleanup(self, evt):
+        if hasattr(self, "menu"):
+            self.menu.Destroy()
+            del self.menu
 
 
-    def __del__(self):
-        self.menu.Destroy()
+    def InitBuffer(self):
+        """Initialize the bitmap used for buffering the display."""
+        size = self.GetClientSize()
+        self.buffer = wx.EmptyBitmap(max(1,size.width), max(1,size.height))
+        dc = wx.BufferedDC(None, self.buffer)
+        dc.SetBackground(wx.Brush(self.GetBackgroundColour()))
+        dc.Clear()
+        self.DrawLines(dc)
+        self.reInitBuffer = False
 
 
     def SetColour(self, colour):
         """Set a new colour and make a matching pen"""
         self.colour = colour
-        self.pen = wxPen(wxNamedColour(self.colour), self.thickness, wxSOLID)
+        self.pen = wx.Pen(self.colour, self.thickness, wx.SOLID)
         self.Notify()
 
 
     def SetThickness(self, num):
         """Set a new line thickness and make a matching pen"""
         self.thickness = num
-        self.pen = wxPen(wxNamedColour(self.colour), self.thickness, wxSOLID)
+        self.pen = wx.Pen(self.colour, self.thickness, wx.SOLID)
         self.Notify()
 
 
@@ -75,25 +99,27 @@ class DoodleWindow(wxWindow):
 
     def SetLinesData(self, lines):
         self.lines = lines[:]
+        self.InitBuffer()
         self.Refresh()
 
 
     def MakeMenu(self):
         """Make a menu that can be popped up later"""
-        menu = wxMenu()
+        menu = wx.Menu()
         keys = self.menuColours.keys()
         keys.sort()
         for k in keys:
             text = self.menuColours[k]
-            menu.Append(k, text, checkable=true)
-        EVT_MENU_RANGE(self, 100, 200, self.OnMenuSetColour)
-        EVT_UPDATE_UI_RANGE(self, 100, 200, self.OnCheckMenuColours)
+            menu.Append(k, text, kind=wx.ITEM_CHECK)
+        self.Bind(wx.EVT_MENU_RANGE, self.OnMenuSetColour, id=100, id2=200)
+        self.Bind(wx.EVT_UPDATE_UI_RANGE, self.OnCheckMenuColours, id=100, id2=200)
         menu.Break()
 
         for x in range(1, self.maxThickness+1):
-            menu.Append(x, str(x), checkable=true)
-        EVT_MENU_RANGE(self, 1, self.maxThickness, self.OnMenuSetThickness)
-        EVT_UPDATE_UI_RANGE(self, 1, self.maxThickness, self.OnCheckMenuThickness)
+            menu.Append(x, str(x), kind=wx.ITEM_CHECK)
+
+        self.Bind(wx.EVT_MENU_RANGE, self.OnMenuSetThickness, id=1, id2=self.maxThickness)
+        self.Bind(wx.EVT_UPDATE_UI_RANGE, self.OnCheckMenuThickness, id=1, id2=self.maxThickness)
         self.menu = menu
 
 
@@ -102,28 +128,32 @@ class DoodleWindow(wxWindow):
     def OnCheckMenuColours(self, event):
         text = self.menuColours[event.GetId()]
         if text == self.colour:
-            event.Check(true)
+            event.Check(True)
+            event.SetText(text.upper())
         else:
-            event.Check(false)
+            event.Check(False)
+            event.SetText(text)
+
     def OnCheckMenuThickness(self, event):
         if event.GetId() == self.thickness:
-            event.Check(true)
+            event.Check(True)
         else:
-            event.Check(false)
+            event.Check(False)
 
 
     def OnLeftDown(self, event):
         """called when the left mouse button is pressed"""
         self.curLine = []
-        self.x, self.y = event.GetPositionTuple()
+        self.pos = event.GetPosition()
         self.CaptureMouse()
 
 
     def OnLeftUp(self, event):
         """called when the left mouse button is released"""
-        self.lines.append( (self.colour, self.thickness, self.curLine) )
-        self.curLine = []
-        self.ReleaseMouse()
+        if self.HasCapture():
+            self.lines.append( (self.colour, self.thickness, self.curLine) )
+            self.curLine = []
+            self.ReleaseMouse()
 
 
     def OnRightUp(self, event):
@@ -140,29 +170,58 @@ class DoodleWindow(wxWindow):
         current one.  Save the coordinants for redraws.
         """
         if event.Dragging() and event.LeftIsDown():
-            dc = wxClientDC(self)
+            dc = wx.BufferedDC(wx.ClientDC(self), self.buffer)
             dc.BeginDrawing()
             dc.SetPen(self.pen)
-            pos = event.GetPositionTuple()
-            coords = (self.x, self.y) + pos
+            pos = event.GetPosition()
+            coords = (self.pos.x, self.pos.y, pos.x, pos.y)
             self.curLine.append(coords)
-            dc.DrawLine(self.x, self.y, pos[0], pos[1])
-            self.x, self.y = pos
+            dc.DrawLine(*coords)
+            self.pos = pos
             dc.EndDrawing()
 
 
+    def OnSize(self, event):
+        """
+        Called when the window is resized.  We set a flag so the idle
+        handler will resize the buffer.
+        """
+        self.reInitBuffer = True
+
+
+    def OnIdle(self, event):
+        """
+        If the size was changed then resize the bitmap used for double
+        buffering to match the window size.  We do it in Idle time so
+        there is only one refresh after resizing is done, not lots while
+        it is happening.
+        """
+        if self.reInitBuffer:
+            self.InitBuffer()
+            self.Refresh(False)
+
+
     def OnPaint(self, event):
         """
-        Called when the window is exposed.  Redraws all the lines that have
-        been drawn already.
+        Called when the window is exposed.
+        """
+        # Create a buffered paint DC.  It will create the real
+        # wx.PaintDC and then blit the bitmap to it when dc is
+        # deleted.  Since we don't need to draw anything else
+        # here that's all there is to it.
+        dc = wx.BufferedPaintDC(self, self.buffer)
+
+
+    def DrawLines(self, dc):
+        """
+        Redraws all the lines that have been drawn already.
         """
-        dc = wxPaintDC(self)
         dc.BeginDrawing()
         for colour, thickness, line in self.lines:
-            pen = wxPen(wxNamedColour(colour), thickness, wxSOLID)
+            pen = wx.Pen(colour, thickness, wx.SOLID)
             dc.SetPen(pen)
             for coords in line:
-                apply(dc.DrawLine, coords)
+                dc.DrawLine(*coords)
         dc.EndDrawing()
 
 
@@ -187,17 +246,17 @@ class DoodleWindow(wxWindow):
 
 #----------------------------------------------------------------------
 
-class DoodleFrame(wxFrame):
+class DoodleFrame(wx.Frame):
     def __init__(self, parent):
-        wxFrame.__init__(self, parent, -1, "Doodle Frame", size=(800,600))
-        self.doodle = DoodleWindow(self, -1)
-
+        wx.Frame.__init__(self, parent, -1, "Doodle Frame", size=(800,600),
+                         style=wx.DEFAULT_FRAME_STYLE | wx.NO_FULL_REPAINT_ON_RESIZE)
+        doodle = DoodleWindow(self, -1)
 
 #----------------------------------------------------------------------
 
 if __name__ == '__main__':
-    app = wxPySimpleApp()
+    app = wx.PySimpleApp()
     frame = DoodleFrame(None)
-    frame.Show(true)
+    frame.Show(True)
     app.MainLoop()