X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/7114b9fa28654f7a9c118f6574f7c8e15fa5d302..e393c3fb102d565111b5cf280136a6e8b50bab85:/wxPython/samples/doodle/doodle.py diff --git a/wxPython/samples/doodle/doodle.py b/wxPython/samples/doodle/doodle.py index dbfa8b39c6..47e01d9e6d 100644 --- a/wxPython/samples/doodle/doodle.py +++ b/wxPython/samples/doodle/doodle.py @@ -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()