]> git.saurik.com Git - wxWidgets.git/blame - wxPython/src/_core_ex.py
use wxEventType instead of enum
[wxWidgets.git] / wxPython / src / _core_ex.py
CommitLineData
d14a1e28
RD
1#----------------------------------------------------------------------------
2
322913ce 3# Use Python's bool constants if available, make some if not
d14a1e28
RD
4try:
5 True
6except NameError:
322913ce
RD
7 __builtins__.True = 1==1
8 __builtins__.False = 1==0
c19bd0a3
RD
9 def bool(value): return not not value
10 __builtins__.bool = bool
d14a1e28 11
d14a1e28
RD
12
13
14# workarounds for bad wxRTTI names
15__wxPyPtrTypeMap['wxGauge95'] = 'wxGauge'
16__wxPyPtrTypeMap['wxSlider95'] = 'wxSlider'
17__wxPyPtrTypeMap['wxStatusBar95'] = 'wxStatusBar'
18
19
20#----------------------------------------------------------------------------
21# Load version numbers from __version__... Ensure that major and minor
611190df 22# versions are the same for both wxPython and wxWidgets.
d14a1e28
RD
23
24from __version__ import *
25__version__ = VERSION_STRING
26
611190df
RD
27assert MAJOR_VERSION == _core_.MAJOR_VERSION, "wxPython/wxWidgets version mismatch"
28assert MINOR_VERSION == _core_.MINOR_VERSION, "wxPython/wxWidgets version mismatch"
54f9ee45 29if RELEASE_VERSION != _core_.RELEASE_VERSION:
d14a1e28 30 import warnings
611190df 31 warnings.warn("wxPython/wxWidgets release number mismatch")
d14a1e28
RD
32
33#----------------------------------------------------------------------------
34
669e06d7
RD
35# Set the default string<-->unicode conversion encoding from the
36# locale. This encoding is used when string or unicode objects need
37# to be converted in order to pass them to wxWidgets. Please be aware
38# that the default encoding within the same locale may be slightly
39# different on different platforms. For example, please see
40# http://www.alanwood.net/demos/charsetdiffs.html for differences
41# between the common latin/roman encodings.
4293f847 42import locale
0d5b83dc 43import codecs
061d64dd
RD
44try:
45 default = locale.getdefaultlocale()[1]
0d5b83dc
RD
46 codecs.lookup(default)
47except (ValueError, LookupError):
48 default = _sys.getdefaultencoding()
4293f847
RD
49if default:
50 wx.SetDefaultPyEncoding(default)
51del default
52del locale
0d5b83dc 53del codecs
4293f847
RD
54
55#----------------------------------------------------------------------------
56
d14a1e28
RD
57class PyDeadObjectError(AttributeError):
58 pass
59
d14a1e28
RD
60class _wxPyDeadObject(object):
61 """
62 Instances of wx objects that are OOR capable will have their __class__
63 changed to this class when the C++ object is deleted. This should help
64 prevent crashes due to referencing a bogus C++ pointer.
65 """
66 reprStr = "wxPython wrapper for DELETED %s object! (The C++ object no longer exists.)"
67 attrStr = "The C++ part of the %s object has been deleted, attribute access no longer allowed."
68
9e58eb56 69 def __repr__(self):
d14a1e28
RD
70 if not hasattr(self, "_name"):
71 self._name = "[unknown]"
72 return self.reprStr % self._name
73
9e58eb56 74 def __getattr__(self, *args):
d14a1e28
RD
75 if not hasattr(self, "_name"):
76 self._name = "[unknown]"
9e58eb56
RD
77 raise PyDeadObjectError(self.attrStr % self._name)
78
79 def __nonzero__(self):
80 return 0
81
82
83
84class PyUnbornObjectError(AttributeError):
85 pass
86
87class _wxPyUnbornObject(object):
88 """
54f9ee45 89 Some stock objects are created when the wx._core module is
9e58eb56
RD
90 imported, but their C++ instance is not created until the wx.App
91 object is created and initialized. These object instances will
92 temporarily have their __class__ changed to this class so an
93 exception will be raised if they are used before the C++ instance
94 is ready.
95 """
96
97 reprStr = "wxPython wrapper for UNBORN object! (The C++ object is not initialized yet.)"
98 attrStr = "The C++ part of this object has not been initialized, attribute access not allowed."
99
100 def __repr__(self):
101 #if not hasattr(self, "_name"):
102 # self._name = "[unknown]"
103 return self.reprStr #% self._name
104
105 def __getattr__(self, *args):
106 #if not hasattr(self, "_name"):
107 # self._name = "[unknown]"
108 raise PyUnbornObjectError(self.attrStr) # % self._name )
d14a1e28
RD
109
110 def __nonzero__(self):
111 return 0
112
113
114#----------------------------------------------------------------------------
d14a1e28
RD
115
116def CallAfter(callable, *args, **kw):
117 """
118 Call the specified function after the current and pending event
119 handlers have been completed. This is also good for making GUI
61863841
RD
120 method calls from non-GUI threads. Any extra positional or
121 keyword args are passed on to the callable when it is called.
122
123 :see: `wx.FutureCall`
d14a1e28
RD
124 """
125 app = wx.GetApp()
2148e701 126 assert app is not None, 'No wx.App created yet'
d14a1e28 127
b0cafb91
RD
128 if not hasattr(app, "_CallAfterId"):
129 app._CallAfterId = wx.NewEventType()
130 app.Connect(-1, -1, app._CallAfterId,
131 lambda event: event.callable(*event.args, **event.kw) )
d14a1e28 132 evt = wx.PyEvent()
b0cafb91 133 evt.SetEventType(app._CallAfterId)
d14a1e28
RD
134 evt.callable = callable
135 evt.args = args
136 evt.kw = kw
137 wx.PostEvent(app, evt)
138
d14a1e28
RD
139#----------------------------------------------------------------------------
140
141
142class FutureCall:
143 """
a3c9f064 144 A convenience class for `wx.Timer`, that calls the given callable
d14a1e28
RD
145 object once after the given amount of milliseconds, passing any
146 positional or keyword args. The return value of the callable is
61863841 147 availbale after it has been run with the `GetResult` method.
d14a1e28
RD
148
149 If you don't need to get the return value or restart the timer
150 then there is no need to hold a reference to this object. It will
151 hold a reference to itself while the timer is running (the timer
152 has a reference to self.Notify) but the cycle will be broken when
153 the timer completes, automatically cleaning up the wx.FutureCall
154 object.
61863841
RD
155
156 :see: `wx.CallAfter`
d14a1e28
RD
157 """
158 def __init__(self, millis, callable, *args, **kwargs):
159 self.millis = millis
160 self.callable = callable
161 self.SetArgs(*args, **kwargs)
162 self.runCount = 0
66065839 163 self.running = False
d14a1e28
RD
164 self.hasRun = False
165 self.result = None
166 self.timer = None
167 self.Start()
168
169 def __del__(self):
170 self.Stop()
171
172
173 def Start(self, millis=None, *args, **kwargs):
174 """
175 (Re)start the timer
176 """
177 self.hasRun = False
178 if millis is not None:
179 self.millis = millis
180 if args or kwargs:
181 self.SetArgs(*args, **kwargs)
182 self.Stop()
183 self.timer = wx.PyTimer(self.Notify)
184 self.timer.Start(self.millis, wx.TIMER_ONE_SHOT)
66065839 185 self.running = True
d14a1e28
RD
186 Restart = Start
187
188
189 def Stop(self):
190 """
191 Stop and destroy the timer.
192 """
193 if self.timer is not None:
194 self.timer.Stop()
195 self.timer = None
196
197
198 def GetInterval(self):
199 if self.timer is not None:
200 return self.timer.GetInterval()
201 else:
202 return 0
203
204
205 def IsRunning(self):
206 return self.timer is not None and self.timer.IsRunning()
207
208
209 def SetArgs(self, *args, **kwargs):
210 """
211 (Re)set the args passed to the callable object. This is
212 useful in conjunction with Restart if you want to schedule a
213 new call to the same callable object but with different
214 parameters.
215 """
216 self.args = args
217 self.kwargs = kwargs
218
219
220 def HasRun(self):
221 return self.hasRun
222
223 def GetResult(self):
224 return self.result
225
226 def Notify(self):
227 """
228 The timer has expired so call the callable.
229 """
230 if self.callable and getattr(self.callable, 'im_self', True):
231 self.runCount += 1
66065839 232 self.running = False
d14a1e28
RD
233 self.result = self.callable(*self.args, **self.kwargs)
234 self.hasRun = True
66065839
RD
235 if not self.running:
236 # if it wasn't restarted, then cleanup
237 wx.CallAfter(self.Stop)
d14a1e28
RD
238
239
5b29df3f
RD
240
241#----------------------------------------------------------------------------
242# Control which items in this module should be documented by epydoc.
243# We allow only classes and functions, which will help reduce the size
244# of the docs by filtering out the zillions of constants, EVT objects,
245# and etc that don't make much sense by themselves, but are instead
246# documented (or will be) as part of the classes/functions/methods
247# where they should be used.
248
99109c0f
RD
249class __DocFilter:
250 """
251 A filter for epydoc that only allows non-Ptr classes and
252 fucntions, in order to reduce the clutter in the API docs.
253 """
254 def __init__(self, globals):
255 self._globals = globals
256
257 def __call__(self, name):
258 import types
259 obj = self._globals.get(name, None)
260 if type(obj) not in [type, types.ClassType, types.FunctionType, types.BuiltinFunctionType]:
261 return False
262 if name.startswith('_') or name.endswith('Ptr') or name.startswith('EVT'):
263 return False
264 return True
5b29df3f 265
d14a1e28
RD
266#----------------------------------------------------------------------------
267#----------------------------------------------------------------------------
268
269# Import other modules in this package that should show up in the
270# "core" wx namespace
54f9ee45
RD
271from _gdi import *
272from _windows import *
273from _controls import *
274from _misc import *
d14a1e28 275
9e58eb56
RD
276
277# Fixup the stock objects since they can't be used yet. (They will be
278# restored in wx.PyApp.OnInit.)
54f9ee45 279_core_._wxPyFixStockObjects()
9e58eb56 280
d14a1e28
RD
281#----------------------------------------------------------------------------
282#----------------------------------------------------------------------------