]> git.saurik.com Git - wxWidgets.git/blame - wxPython/samples/doodle/doodle.py
Bugfix for wxListCtrl::GetColumn. It wasn't checking the returned format correctly.
[wxWidgets.git] / wxPython / samples / doodle / doodle.py
CommitLineData
c12bc4de
RD
1# doodle.py
2
3"""
4This module contains the DoodleWindow class which is a window that you
5can do simple drawings upon.
6"""
7
8
9from wxPython.wx import *
10
11#----------------------------------------------------------------------
12
13class DoodleWindow(wxWindow):
14 menuColours = { 100 : 'Black',
15 101 : 'Yellow',
16 102 : 'Red',
17 103 : 'Green',
18 104 : 'Blue',
19 105 : 'Purple',
20 106 : 'Brown',
21 107 : 'Aquamarine',
22 108 : 'Forest Green',
23 109 : 'Light Blue',
24 110 : 'Goldenrod',
25 111 : 'Cyan',
26 112 : 'Orange',
27 113 : 'Navy',
28 114 : 'Dark Grey',
29 115 : 'Light Grey',
30 }
31 maxThickness = 16
32
33
34 def __init__(self, parent, ID):
9de06a79
RD
35 wxWindow.__init__(self, parent, ID, style=wxNO_FULL_REPAINT_ON_RESIZE)
36 self.SetBackgroundColour("WHITE")
c12bc4de
RD
37 self.listeners = []
38 self.thickness = 1
39 self.SetColour("Black")
40 self.lines = []
41 self.x = self.y = 0
42 self.MakeMenu()
43
9de06a79
RD
44 self.InitBuffer()
45
c12bc4de
RD
46 # hook some mouse events
47 EVT_LEFT_DOWN(self, self.OnLeftDown)
48 EVT_LEFT_UP(self, self.OnLeftUp)
49 EVT_RIGHT_UP(self, self.OnRightUp)
50 EVT_MOTION(self, self.OnMotion)
51
9de06a79
RD
52 # the window resize event and idle events for managing the buffer
53 EVT_SIZE(self, self.OnSize)
54 EVT_IDLE(self, self.OnIdle)
55
c12bc4de
RD
56 # and the refresh event
57 EVT_PAINT(self, self.OnPaint)
58
6d9022fe
RD
59 # When the window is destroyed, clean up resources.
60 EVT_WINDOW_DESTROY(self, self.Cleanup)
c12bc4de 61
9de06a79 62
6d9022fe 63 def Cleanup(self, evt):
9de06a79
RD
64 if hasattr(self, "menu"):
65 self.menu.Destroy()
66 del self.menu
67
68
69 def InitBuffer(self):
70 """Initialize the bitmap used for buffering the display."""
71 size = self.GetClientSize()
72 self.buffer = wxEmptyBitmap(size.width, size.height)
73 dc = wxBufferedDC(None, self.buffer)
74 dc.SetBackground(wxBrush(self.GetBackgroundColour()))
75 dc.Clear()
76 self.DrawLines(dc)
77 self.reInitBuffer = false
c12bc4de
RD
78
79
80 def SetColour(self, colour):
81 """Set a new colour and make a matching pen"""
82 self.colour = colour
83 self.pen = wxPen(wxNamedColour(self.colour), self.thickness, wxSOLID)
84 self.Notify()
85
86
87 def SetThickness(self, num):
88 """Set a new line thickness and make a matching pen"""
89 self.thickness = num
90 self.pen = wxPen(wxNamedColour(self.colour), self.thickness, wxSOLID)
91 self.Notify()
92
93
94 def GetLinesData(self):
95 return self.lines[:]
96
97
98 def SetLinesData(self, lines):
99 self.lines = lines[:]
9de06a79 100 self.InitBuffer()
c12bc4de
RD
101 self.Refresh()
102
103
104 def MakeMenu(self):
105 """Make a menu that can be popped up later"""
106 menu = wxMenu()
107 keys = self.menuColours.keys()
108 keys.sort()
109 for k in keys:
110 text = self.menuColours[k]
9de06a79 111 menu.Append(k, text, kind=wxITEM_CHECK)
c12bc4de
RD
112 EVT_MENU_RANGE(self, 100, 200, self.OnMenuSetColour)
113 EVT_UPDATE_UI_RANGE(self, 100, 200, self.OnCheckMenuColours)
114 menu.Break()
115
116 for x in range(1, self.maxThickness+1):
9de06a79 117 menu.Append(x, str(x), kind=wxITEM_CHECK)
c12bc4de
RD
118 EVT_MENU_RANGE(self, 1, self.maxThickness, self.OnMenuSetThickness)
119 EVT_UPDATE_UI_RANGE(self, 1, self.maxThickness, self.OnCheckMenuThickness)
120 self.menu = menu
121
122
123 # These two event handlers are called before the menu is displayed
124 # to determine which items should be checked.
125 def OnCheckMenuColours(self, event):
126 text = self.menuColours[event.GetId()]
127 if text == self.colour:
128 event.Check(true)
129 else:
130 event.Check(false)
131 def OnCheckMenuThickness(self, event):
132 if event.GetId() == self.thickness:
133 event.Check(true)
134 else:
135 event.Check(false)
136
137
138 def OnLeftDown(self, event):
139 """called when the left mouse button is pressed"""
140 self.curLine = []
141 self.x, self.y = event.GetPositionTuple()
142 self.CaptureMouse()
143
144
145 def OnLeftUp(self, event):
146 """called when the left mouse button is released"""
9de06a79
RD
147 if self.HasCapture():
148 self.lines.append( (self.colour, self.thickness, self.curLine) )
149 self.curLine = []
150 self.ReleaseMouse()
c12bc4de
RD
151
152
153 def OnRightUp(self, event):
154 """called when the right mouse button is released, will popup the menu"""
155 pt = event.GetPosition()
156 self.PopupMenu(self.menu, pt)
157
158
159
160 def OnMotion(self, event):
161 """
162 Called when the mouse is in motion. If the left button is
163 dragging then draw a line from the last event position to the
164 current one. Save the coordinants for redraws.
165 """
166 if event.Dragging() and event.LeftIsDown():
9de06a79 167 dc = wxBufferedDC(wxClientDC(self), self.buffer)
c12bc4de
RD
168 dc.BeginDrawing()
169 dc.SetPen(self.pen)
170 pos = event.GetPositionTuple()
171 coords = (self.x, self.y) + pos
172 self.curLine.append(coords)
173 dc.DrawLine(self.x, self.y, pos[0], pos[1])
174 self.x, self.y = pos
175 dc.EndDrawing()
176
177
9de06a79
RD
178 def OnSize(self, event):
179 """
180 Called when the window is resized. We set a flag so the idle
181 handler will resize the buffer.
182 """
183 self.reInitBuffer = true
184
185
186 def OnIdle(self, event):
187 """
188 If the size was changed then resize the bitmap used for double
189 buffering to match the window size. We do it in Idle time so
190 there is only one refresh after resizing is done, not lots while
191 it is happening.
192 """
193 if self.reInitBuffer:
194 self.InitBuffer()
195 self.Refresh(FALSE)
196
197
c12bc4de
RD
198 def OnPaint(self, event):
199 """
9de06a79
RD
200 Called when the window is exposed.
201 """
202 # Create a buffered paint DC. It will create the real
203 # wxPaintDC and then blit the bitmap to it when dc is
204 # deleted. Since we don't need to draw anything else
205 # here that's all there is to it.
206 dc = wxBufferedPaintDC(self, self.buffer)
207
208
209 def DrawLines(self, dc):
210 """
211 Redraws all the lines that have been drawn already.
c12bc4de 212 """
c12bc4de
RD
213 dc.BeginDrawing()
214 for colour, thickness, line in self.lines:
215 pen = wxPen(wxNamedColour(colour), thickness, wxSOLID)
216 dc.SetPen(pen)
217 for coords in line:
218 apply(dc.DrawLine, coords)
219 dc.EndDrawing()
220
221
222 # Event handlers for the popup menu, uses the event ID to determine
223 # the colour or the thickness to set.
224 def OnMenuSetColour(self, event):
225 self.SetColour(self.menuColours[event.GetId()])
226
227 def OnMenuSetThickness(self, event):
228 self.SetThickness(event.GetId())
229
230
231 # Observer pattern. Listeners are registered and then notified
232 # whenever doodle settings change.
233 def AddListener(self, listener):
234 self.listeners.append(listener)
235
236 def Notify(self):
237 for other in self.listeners:
238 other.Update(self.colour, self.thickness)
239
240
241#----------------------------------------------------------------------
242
243class DoodleFrame(wxFrame):
244 def __init__(self, parent):
9de06a79
RD
245 wxFrame.__init__(self, parent, -1, "Doodle Frame", size=(800,600),
246 style=wxDEFAULT_FRAME_STYLE | wxNO_FULL_REPAINT_ON_RESIZE)
247 doodle = DoodleWindow(self, -1)
c12bc4de 248
c12bc4de
RD
249#----------------------------------------------------------------------
250
251if __name__ == '__main__':
7114b9fa
RD
252 app = wxPySimpleApp()
253 frame = DoodleFrame(None)
254 frame.Show(true)
c12bc4de
RD
255 app.MainLoop()
256