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