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