1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24 """
25 Functional utilities designed for pychan use cases.
26 """
27
28 import exceptions
29
30
31
33 """
34 This nifty little function takes another function and applies it to a dictionary of
35 keyword arguments. If the supplied function does not expect one or more of the
36 keyword arguments, these are silently discarded. The result of the application is returned.
37 This is useful to pass information to callbacks without enforcing a particular signature.
38 """
39 if hasattr(func,'im_func'):
40 code = func.im_func.func_code
41 varnames = code.co_varnames[1:code.co_argcount]
42 elif hasattr(func,'func_code'):
43 code = func.func_code
44 varnames = code.co_varnames[0:code.co_argcount]
45 elif hasattr(func,'__call__'):
46 func = func.__call__
47 if hasattr(func,'im_func'):
48 code = func.im_func.func_code
49 varnames = code.co_varnames[1:code.co_argcount]
50 elif hasattr(func,'func_code'):
51 code = func.func_code
52 varnames = code.co_varnames[0:code.co_argcount]
53
54
55 if code.co_flags & 8:
56 return func(*args,**kwargs)
57 for name,value in kwargs.items():
58 if name not in varnames:
59 del kwargs[name]
60 return func(*args,**kwargs)
61
63 """
64 Curries a function with extra arguments to
65 create a suitable callback.
66
67 If you don't know what this means, don't worry.
68 It is designed for the case where you need
69 different buttons to execute basically the same code
70 with different argumnets.
71
72 Usage::
73 # The target callback
74 def printStuff(text):
75 print text
76 # Mapping the events
77 gui.mapEvents({
78 'buttonHello' : callbackWithArguments(printStuff,"Hello"),
79 'buttonBye' : callbackWithArguments(printStuff,"Adieu")
80 })
81 """
82 def real_callback():
83 callback(*args,**kwargs)
84 return real_callback
85
87 """
88 Generates an event callback that sets attributes on the widget
89 it is called on. This is especially useful for mouseEntered/Exited
90 events - to create hover effects.
91
92 It takes a set of keyword arguments. The keys are treated as attribute names,
93 which are then set to the corresponding value when the callback is called.
94 Some key names are treated special - see below.
95
96 Usage - Example adapted from demo application::
97 eventMap = {
98 'creditsLink' : showCreditsCallback,
99 'creditsLink/mouseEntered' : attrSetCallback(
100 text = "Show credits!",
101 background_color = (255,255,0,255),
102 do__adaptLayout=True),
103 'creditsLink/mouseExited' : attrSetCallback(text = "Credits"),
104 gui.mapEvents(eventMap)
105
106 Now when the mouse enters the creditsLink (a Label in our case), the following code will be executed::
107 #widget is the creditsLink - given to the event callback.
108 widget.text = "Show credits!"
109 widget.background_color = (255,255,0,255)
110 widget.adaptLayout()
111
112 The C{do__adaptLayout} argument causes the method C{adaptLayout} to be called.
113 In fact any key starting with C{do__} results in such a method call. The order
114 of execution of such calls is undefined.
115
116 Keys starting with an underscore raise a L{execptions.PrivateFunctionalityError}.
117 """
118 do_calls = []
119
120 for name in kwargs.keys():
121 if name.startswith("_"):
122 raise exceptions.PrivateFunctionalityError(name)
123 if name.startswith("do__"):
124 do_calls.append(name[4:])
125 del kwargs[name]
126
127 def attrSet_callback(widget=None):
128 for name,value in kwargs.items():
129 setattr(widget,name,value)
130 for method_name in do_calls:
131 method = getattr(widget,method_name)
132 method()
133 return attrSet_callback
134
136 """
137 Chains callbacks to be called one after the other.
138
139 Example Usage::
140 def print_event(event=0):
141 print event
142 def print_widget(widget=0):
143 print widget
144 callback = tools.chainCallbacks(doSomethingUseful, print_event, print_widget)
145 guiElement.capture(callback)
146 """
147 callbacks = args
148 def chain_callback(event=0,widget=0):
149 for callback in callbacks:
150 applyOnlySuitable(callback, event=event, widget=widget)
151 return chain_callback
152
154 """
155 Internal decorator used to profile some pychan functions.
156 Only use with functions without side-effect.
157
158 Usage::
159 @repeatALot(n=10000)
160 def findChild(self,**kwargs):
161 ...
162 """
163 def wrap_f(f):
164 def new_f(*args,**kwargs):
165 for i in xrange(n):
166 f(*args,**kwargs)
167 return f(*args,**kwargs)
168 return new_f
169 return wrap_f
170
172 if message is None:
173 message = repr(func)
174 def wrapped_func(*args,**kwargs):
175 print "PyChan: You are using the DEPRECATED functionality: %s" % message
176 return func(*args,**kwargs)
177 return wrapped_func
178