]> git.saurik.com Git - wxWidgets.git/blob - wxPython/demo/ScrolledWindow.py
The great wxVScrolledWindow refactoring: allow using it both horizontal and
[wxWidgets.git] / wxPython / demo / ScrolledWindow.py
1
2 import wx
3 import images
4
5 BUFFERED = 1
6
7 #---------------------------------------------------------------------------
8
9 class MyCanvas(wx.ScrolledWindow):
10 def __init__(self, parent, id = -1, size = wx.DefaultSize):
11 wx.ScrolledWindow.__init__(self, parent, id, (0, 0), size=size, style=wx.SUNKEN_BORDER)
12
13 self.lines = []
14 self.maxWidth = 1000
15 self.maxHeight = 1000
16 self.x = self.y = 0
17 self.curLine = []
18 self.drawing = False
19
20 self.SetBackgroundColour("WHITE")
21 self.SetCursor(wx.StockCursor(wx.CURSOR_PENCIL))
22 bmp = images.getTest2Bitmap()
23 mask = wx.Mask(bmp, wx.BLUE)
24 bmp.SetMask(mask)
25 self.bmp = bmp
26
27 self.SetVirtualSize((self.maxWidth, self.maxHeight))
28 self.SetScrollRate(20,20)
29
30 if BUFFERED:
31 # Initialize the buffer bitmap. No real DC is needed at this point.
32 self.buffer = wx.EmptyBitmap(self.maxWidth, self.maxHeight)
33 dc = wx.BufferedDC(None, self.buffer)
34 dc.SetBackground(wx.Brush(self.GetBackgroundColour()))
35 dc.Clear()
36 self.DoDrawing(dc)
37
38 self.Bind(wx.EVT_LEFT_DOWN, self.OnLeftButtonEvent)
39 self.Bind(wx.EVT_LEFT_UP, self.OnLeftButtonEvent)
40 self.Bind(wx.EVT_MOTION, self.OnLeftButtonEvent)
41 self.Bind(wx.EVT_PAINT, self.OnPaint)
42
43
44 def getWidth(self):
45 return self.maxWidth
46
47 def getHeight(self):
48 return self.maxHeight
49
50
51 def OnPaint(self, event):
52 if BUFFERED:
53 # Create a buffered paint DC. It will create the real
54 # wx.PaintDC and then blit the bitmap to it when dc is
55 # deleted. Since we don't need to draw anything else
56 # here that's all there is to it.
57 dc = wx.BufferedPaintDC(self, self.buffer, wx.BUFFER_VIRTUAL_AREA)
58 else:
59 dc = wx.PaintDC(self)
60 self.PrepareDC(dc)
61 # since we're not buffering in this case, we have to
62 # paint the whole window, potentially very time consuming.
63 self.DoDrawing(dc)
64
65
66 def DoDrawing(self, dc, printing=False):
67 dc.BeginDrawing()
68 dc.SetPen(wx.Pen('RED'))
69 dc.DrawRectangle(5, 5, 50, 50)
70
71 dc.SetBrush(wx.LIGHT_GREY_BRUSH)
72 dc.SetPen(wx.Pen('BLUE', 4))
73 dc.DrawRectangle(15, 15, 50, 50)
74
75 dc.SetFont(wx.Font(14, wx.SWISS, wx.NORMAL, wx.NORMAL))
76 dc.SetTextForeground(wx.Colour(0xFF, 0x20, 0xFF))
77 te = dc.GetTextExtent("Hello World")
78 dc.DrawText("Hello World", 60, 65)
79
80 dc.SetPen(wx.Pen('VIOLET', 4))
81 dc.DrawLine(5, 65+te[1], 60+te[0], 65+te[1])
82
83 lst = [(100,110), (150,110), (150,160), (100,160)]
84 dc.DrawLines(lst, -60)
85 dc.SetPen(wx.GREY_PEN)
86 dc.DrawPolygon(lst, 75)
87 dc.SetPen(wx.GREEN_PEN)
88 dc.DrawSpline(lst+[(100,100)])
89
90 dc.DrawBitmap(self.bmp, 200, 20, True)
91 dc.SetTextForeground(wx.Colour(0, 0xFF, 0x80))
92 dc.DrawText("a bitmap", 200, 85)
93
94 ## dc.SetFont(wx.Font(14, wx.SWISS, wx.NORMAL, wx.NORMAL))
95 ## dc.SetTextForeground("BLACK")
96 ## dc.DrawText("TEST this STRING", 10, 200)
97 ## print dc.GetFullTextExtent("TEST this STRING")
98
99 font = wx.Font(20, wx.SWISS, wx.NORMAL, wx.NORMAL)
100 dc.SetFont(font)
101 dc.SetTextForeground(wx.BLACK)
102
103 for a in range(0, 360, 45):
104 dc.DrawRotatedText("Rotated text...", 300, 300, a)
105
106 dc.SetPen(wx.TRANSPARENT_PEN)
107 dc.SetBrush(wx.BLUE_BRUSH)
108 dc.DrawRectangle(50,500, 50,50)
109 dc.DrawRectangle(100,500, 50,50)
110
111 dc.SetPen(wx.Pen('RED'))
112 dc.DrawEllipticArc(200,500, 50,75, 0, 90)
113
114 if not printing:
115 # This has troubles when used on a print preview in wxGTK,
116 # probably something to do with the pen styles and the scaling
117 # it does...
118 y = 20
119
120 for style in [wx.DOT, wx.LONG_DASH, wx.SHORT_DASH, wx.DOT_DASH, wx.USER_DASH]:
121 pen = wx.Pen("DARK ORCHID", 1, style)
122 if style == wx.USER_DASH:
123 pen.SetCap(wx.CAP_BUTT)
124 pen.SetDashes([1,2])
125 pen.SetColour("RED")
126 dc.SetPen(pen)
127 dc.DrawLine(300,y, 400,y)
128 y = y + 10
129
130 dc.SetBrush(wx.TRANSPARENT_BRUSH)
131 dc.SetPen(wx.Pen(wx.Colour(0xFF, 0x20, 0xFF), 1, wx.SOLID))
132 dc.DrawRectangle(450,50, 100,100)
133 old_pen = dc.GetPen()
134 new_pen = wx.Pen("BLACK", 5)
135 dc.SetPen(new_pen)
136 dc.DrawRectangle(470,70, 60,60)
137 dc.SetPen(old_pen)
138 dc.DrawRectangle(490,90, 20,20)
139
140 dc.GradientFillLinear((20, 260, 50, 50),
141 "red", "blue")
142 dc.GradientFillConcentric((20, 325, 50, 50),
143 "red", "blue", (25,25))
144 self.DrawSavedLines(dc)
145 dc.EndDrawing()
146
147
148 def DrawSavedLines(self, dc):
149 dc.SetPen(wx.Pen('MEDIUM FOREST GREEN', 4))
150
151 for line in self.lines:
152 for coords in line:
153 apply(dc.DrawLine, coords)
154
155
156 def SetXY(self, event):
157 self.x, self.y = self.ConvertEventCoords(event)
158
159 def ConvertEventCoords(self, event):
160 newpos = self.CalcUnscrolledPosition(event.GetX(), event.GetY())
161 return newpos
162
163 def OnLeftButtonEvent(self, event):
164 if event.LeftDown():
165 self.SetFocus()
166 self.SetXY(event)
167 self.curLine = []
168 self.CaptureMouse()
169 self.drawing = True
170
171 elif event.Dragging() and self.drawing:
172 if BUFFERED:
173 # If doing buffered drawing we'll just update the
174 # buffer here and then refresh that portion of the
175 # window, then that portion of the buffer will be
176 # redrawn in the EVT_PAINT handler.
177 dc = wx.BufferedDC(None, self.buffer)
178 else:
179 # otherwise we'll draw directly to a wx.ClientDC
180 dc = wx.ClientDC(self)
181 self.PrepareDC(dc)
182
183 dc.SetPen(wx.Pen('MEDIUM FOREST GREEN', 4))
184 coords = (self.x, self.y) + self.ConvertEventCoords(event)
185 self.curLine.append(coords)
186 dc.DrawLine(*coords)
187 self.SetXY(event)
188
189 if BUFFERED:
190 # figure out what part of the window to refresh
191 x1,y1, x2,y2 = dc.GetBoundingBox()
192 x1,y1 = self.CalcScrolledPosition(x1, y1)
193 x2,y2 = self.CalcScrolledPosition(x2, y2)
194 # make a rectangle
195 rect = wx.Rect()
196 rect.SetTopLeft((x1,y1))
197 rect.SetBottomRight((x2,y2))
198 rect.Inflate(2,2)
199 # refresh it
200 self.RefreshRect(rect)
201
202 elif event.LeftUp() and self.drawing:
203 self.lines.append(self.curLine)
204 self.curLine = []
205 self.ReleaseMouse()
206 self.drawing = False
207
208
209 ## This is an example of what to do for the EVT_MOUSEWHEEL event,
210 ## but since wx.ScrolledWindow does this already it's not
211 ## necessary to do it ourselves. You would need to add an event table
212 ## entry to __init__() to direct wheelmouse events to this handler.
213
214 ## wheelScroll = 0
215 ## def OnWheel(self, evt):
216 ## delta = evt.GetWheelDelta()
217 ## rot = evt.GetWheelRotation()
218 ## linesPer = evt.GetLinesPerAction()
219 ## print delta, rot, linesPer
220 ## ws = self.wheelScroll
221 ## ws = ws + rot
222 ## lines = ws / delta
223 ## ws = ws - lines * delta
224 ## self.wheelScroll = ws
225 ## if lines != 0:
226 ## lines = lines * linesPer
227 ## vsx, vsy = self.GetViewStart()
228 ## scrollTo = vsy - lines
229 ## self.Scroll(-1, scrollTo)
230
231 #---------------------------------------------------------------------------
232
233 def runTest(frame, nb, log):
234 win = MyCanvas(nb)
235 return win
236
237 #---------------------------------------------------------------------------
238
239
240
241 overview = """
242 <html>
243 <body>
244 The wx.ScrolledWindow class manages scrolling for its client area, transforming the
245 coordinates according to the scrollbar positions, and setting the scroll positions,
246 thumb sizes and ranges according to the area in view.
247 </body>
248 </html>
249 """
250
251
252 if __name__ == '__main__':
253 import sys,os
254 import run
255 run.main(['', os.path.basename(sys.argv[0])] + sys.argv[1:])
256