]> git.saurik.com Git - wxWidgets.git/blob - wxPython/src/_core_ex.py
Add some ownerdraw methods to ListBox for MSW
[wxWidgets.git] / wxPython / src / _core_ex.py
1 #----------------------------------------------------------------------------
2
3 # Use Python's bool constants if available, make some if not
4 try:
5 True
6 except NameError:
7 __builtins__.True = 1==1
8 __builtins__.False = 1==0
9
10
11
12 # workarounds for bad wxRTTI names
13 __wxPyPtrTypeMap['wxGauge95'] = 'wxGauge'
14 __wxPyPtrTypeMap['wxSlider95'] = 'wxSlider'
15 __wxPyPtrTypeMap['wxStatusBar95'] = 'wxStatusBar'
16
17
18 #----------------------------------------------------------------------------
19 # Load version numbers from __version__... Ensure that major and minor
20 # versions are the same for both wxPython and wxWindows.
21
22 from __version__ import *
23 __version__ = VERSION_STRING
24
25 assert MAJOR_VERSION == _core.MAJOR_VERSION, "wxPython/wxWindows version mismatch"
26 assert MINOR_VERSION == _core.MINOR_VERSION, "wxPython/wxWindows version mismatch"
27 if RELEASE_VERSION != _core.RELEASE_VERSION:
28 import warnings
29 warnings.warn("wxPython/wxWindows release number mismatch")
30
31 #----------------------------------------------------------------------------
32
33 class PyDeadObjectError(AttributeError):
34 pass
35
36 class _wxPyDeadObject(object):
37 """
38 Instances of wx objects that are OOR capable will have their __class__
39 changed to this class when the C++ object is deleted. This should help
40 prevent crashes due to referencing a bogus C++ pointer.
41 """
42 reprStr = "wxPython wrapper for DELETED %s object! (The C++ object no longer exists.)"
43 attrStr = "The C++ part of the %s object has been deleted, attribute access no longer allowed."
44
45 def __repr__(self):
46 if not hasattr(self, "_name"):
47 self._name = "[unknown]"
48 return self.reprStr % self._name
49
50 def __getattr__(self, *args):
51 if not hasattr(self, "_name"):
52 self._name = "[unknown]"
53 raise PyDeadObjectError(self.attrStr % self._name)
54
55 def __nonzero__(self):
56 return 0
57
58
59
60 class PyUnbornObjectError(AttributeError):
61 pass
62
63 class _wxPyUnbornObject(object):
64 """
65 Some stock objects are created when the wx.core module is
66 imported, but their C++ instance is not created until the wx.App
67 object is created and initialized. These object instances will
68 temporarily have their __class__ changed to this class so an
69 exception will be raised if they are used before the C++ instance
70 is ready.
71 """
72
73 reprStr = "wxPython wrapper for UNBORN object! (The C++ object is not initialized yet.)"
74 attrStr = "The C++ part of this object has not been initialized, attribute access not allowed."
75
76 def __repr__(self):
77 #if not hasattr(self, "_name"):
78 # self._name = "[unknown]"
79 return self.reprStr #% self._name
80
81 def __getattr__(self, *args):
82 #if not hasattr(self, "_name"):
83 # self._name = "[unknown]"
84 raise PyUnbornObjectError(self.attrStr) # % self._name )
85
86 def __nonzero__(self):
87 return 0
88
89
90 #----------------------------------------------------------------------------
91 _wxPyCallAfterId = None
92
93 def CallAfter(callable, *args, **kw):
94 """
95 Call the specified function after the current and pending event
96 handlers have been completed. This is also good for making GUI
97 method calls from non-GUI threads.
98 """
99 app = wx.GetApp()
100 assert app, 'No wxApp created yet'
101
102 global _wxPyCallAfterId
103 if _wxPyCallAfterId is None:
104 _wxPyCallAfterId = wx.NewEventType()
105 app.Connect(-1, -1, _wxPyCallAfterId,
106 lambda event: event.callable(*event.args, **event.kw) )
107 evt = wx.PyEvent()
108 evt.SetEventType(_wxPyCallAfterId)
109 evt.callable = callable
110 evt.args = args
111 evt.kw = kw
112 wx.PostEvent(app, evt)
113
114
115 #----------------------------------------------------------------------------
116
117
118 class FutureCall:
119 """
120 A convenience class for wxTimer, that calls the given callable
121 object once after the given amount of milliseconds, passing any
122 positional or keyword args. The return value of the callable is
123 availbale after it has been run with the GetResult method.
124
125 If you don't need to get the return value or restart the timer
126 then there is no need to hold a reference to this object. It will
127 hold a reference to itself while the timer is running (the timer
128 has a reference to self.Notify) but the cycle will be broken when
129 the timer completes, automatically cleaning up the wx.FutureCall
130 object.
131 """
132 def __init__(self, millis, callable, *args, **kwargs):
133 self.millis = millis
134 self.callable = callable
135 self.SetArgs(*args, **kwargs)
136 self.runCount = 0
137 self.hasRun = False
138 self.result = None
139 self.timer = None
140 self.Start()
141
142 def __del__(self):
143 self.Stop()
144
145
146 def Start(self, millis=None, *args, **kwargs):
147 """
148 (Re)start the timer
149 """
150 self.hasRun = False
151 if millis is not None:
152 self.millis = millis
153 if args or kwargs:
154 self.SetArgs(*args, **kwargs)
155 self.Stop()
156 self.timer = wx.PyTimer(self.Notify)
157 self.timer.Start(self.millis, wx.TIMER_ONE_SHOT)
158 Restart = Start
159
160
161 def Stop(self):
162 """
163 Stop and destroy the timer.
164 """
165 if self.timer is not None:
166 self.timer.Stop()
167 self.timer = None
168
169
170 def GetInterval(self):
171 if self.timer is not None:
172 return self.timer.GetInterval()
173 else:
174 return 0
175
176
177 def IsRunning(self):
178 return self.timer is not None and self.timer.IsRunning()
179
180
181 def SetArgs(self, *args, **kwargs):
182 """
183 (Re)set the args passed to the callable object. This is
184 useful in conjunction with Restart if you want to schedule a
185 new call to the same callable object but with different
186 parameters.
187 """
188 self.args = args
189 self.kwargs = kwargs
190
191
192 def HasRun(self):
193 return self.hasRun
194
195 def GetResult(self):
196 return self.result
197
198 def Notify(self):
199 """
200 The timer has expired so call the callable.
201 """
202 if self.callable and getattr(self.callable, 'im_self', True):
203 self.runCount += 1
204 self.result = self.callable(*self.args, **self.kwargs)
205 self.hasRun = True
206 wx.CallAfter(self.Stop)
207
208
209 #----------------------------------------------------------------------------
210 #----------------------------------------------------------------------------
211
212 # Import other modules in this package that should show up in the
213 # "core" wx namespace
214 from gdi import *
215 from windows import *
216 from controls import *
217 from misc import *
218
219
220 # Fixup the stock objects since they can't be used yet. (They will be
221 # restored in wx.PyApp.OnInit.)
222 _core._wxPyFixStockObjects()
223
224 #----------------------------------------------------------------------------
225 #----------------------------------------------------------------------------