|
1 """ |
|
2 BufferedCanvas -- flicker-free canvas widget |
|
3 Copyright (C) 2005, 2006 Daniel Keep, 2011 Duane Johnson |
|
4 |
|
5 To use this widget, just override or replace the draw method. |
|
6 This will be called whenever the widget size changes, or when |
|
7 the update method is explicitly called. |
|
8 |
|
9 Please submit any improvements/bugfixes/ideas to the following |
|
10 url: |
|
11 |
|
12 http://wiki.wxpython.org/index.cgi/BufferedCanvas |
|
13 |
|
14 2006-04-29: Added bugfix for a crash on Mac provided by Marc Jans. |
|
15 """ |
|
16 |
|
17 # Hint: try removing '.sp4msux0rz' |
|
18 __author__ = 'Daniel Keep <daniel.keep.sp4msux0rz@gmail.com>' |
|
19 |
|
20 __license__ = """ |
|
21 This file is part of the Printrun suite. |
|
22 |
|
23 Printrun is free software: you can redistribute it and/or modify |
|
24 it under the terms of the GNU General Public License as published by |
|
25 the Free Software Foundation, either version 3 of the License, or |
|
26 (at your option) any later version. |
|
27 |
|
28 Printrun is distributed in the hope that it will be useful, |
|
29 but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
30 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
31 GNU General Public License for more details. |
|
32 |
|
33 You should have received a copy of the GNU General Public License |
|
34 along with Printrun. If not, see <http://www.gnu.org/licenses/>. |
|
35 """ |
|
36 |
|
37 __all__ = ['BufferedCanvas'] |
|
38 |
|
39 import wx |
|
40 |
|
41 class BufferedCanvas(wx.Panel): |
|
42 """ |
|
43 Implements a flicker-free canvas widget. |
|
44 |
|
45 Standard usage is to subclass this class, and override the |
|
46 draw method. The draw method is passed a device context, which |
|
47 should be used to do your drawing. |
|
48 |
|
49 If you want to force a redraw (for whatever reason), you should |
|
50 call the update method. This is because the draw method is never |
|
51 called as a result of an EVT_PAINT event. |
|
52 """ |
|
53 |
|
54 # These are our two buffers. Just be aware that when the buffers |
|
55 # are flipped, the REFERENCES are swapped. So I wouldn't want to |
|
56 # try holding onto explicit references to one or the other ;) |
|
57 buffer = None |
|
58 backbuffer = None |
|
59 |
|
60 def __init__(self, |
|
61 parent, |
|
62 ID=-1, |
|
63 pos = wx.DefaultPosition, |
|
64 size = wx.DefaultSize, |
|
65 style = wx.NO_FULL_REPAINT_ON_RESIZE | wx.WANTS_CHARS): |
|
66 wx.Panel.__init__(self, parent, ID, pos, size, style) |
|
67 |
|
68 # Bind events |
|
69 self.Bind(wx.EVT_PAINT, self.onPaint) |
|
70 |
|
71 # Disable background erasing (flicker-licious) |
|
72 def disable_event(*pargs, **kwargs): |
|
73 pass # the sauce, please |
|
74 self.Bind(wx.EVT_ERASE_BACKGROUND, disable_event) |
|
75 |
|
76 # |
|
77 # General methods |
|
78 # |
|
79 |
|
80 def draw(self, dc, w, h): |
|
81 """ |
|
82 Stub: called when the canvas needs to be re-drawn. |
|
83 """ |
|
84 pass |
|
85 |
|
86 def update(self): |
|
87 """ |
|
88 Causes the canvas to be updated. |
|
89 """ |
|
90 self.Refresh() |
|
91 |
|
92 def getWidthHeight(self): |
|
93 width, height = self.GetClientSizeTuple() |
|
94 if width == 0: |
|
95 width = 1 |
|
96 if height == 0: |
|
97 height = 1 |
|
98 return (width, height) |
|
99 |
|
100 # |
|
101 # Event handlers |
|
102 # |
|
103 |
|
104 def onPaint(self, event): |
|
105 # Blit the front buffer to the screen |
|
106 w, h = self.GetClientSizeTuple() |
|
107 if not w or not h: |
|
108 return |
|
109 else: |
|
110 dc = wx.BufferedPaintDC(self) |
|
111 self.draw(dc, w, h) |