Package fife :: Package extensions :: Package pychan :: Module tools
[hide private]
[frames] | no frames]

Source Code for Module fife.extensions.pychan.tools

  1  # -*- coding: utf-8 -*- 
  2   
  3  # #################################################################### 
  4  #  Copyright (C) 2005-2009 by the FIFE team 
  5  #  http://www.fifengine.de 
  6  #  This file is part of FIFE. 
  7  # 
  8  #  FIFE is free software; you can redistribute it and/or 
  9  #  modify it under the terms of the GNU Lesser General Public 
 10  #  License as published by the Free Software Foundation; either 
 11  #  version 2.1 of the License, or (at your option) any later version. 
 12  # 
 13  #  This library is distributed in the hope that it will be useful, 
 14  #  but WITHOUT ANY WARRANTY; without even the implied warranty of 
 15  #  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU 
 16  #  Lesser General Public License for more details. 
 17  # 
 18  #  You should have received a copy of the GNU Lesser General Public 
 19  #  License along with this library; if not, write to the 
 20  #  Free Software Foundation, Inc., 
 21  #  51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA 
 22  # #################################################################### 
 23   
 24  """ 
 25  Functional utilities designed for pychan use cases. 
 26  """ 
 27   
 28  import exceptions 
 29   
 30  ### Functools ### 
 31   
32 -def applyOnlySuitable(func,*args,**kwargs):
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]#ditch bound instance 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]#ditch bound instance 50 elif hasattr(func,'func_code'): 51 code = func.func_code 52 varnames = code.co_varnames[0:code.co_argcount] 53 54 #http://docs.python.org/lib/inspect-types.html 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
62 -def callbackWithArguments(callback,*args,**kwargs):
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
86 -def attrSetCallback(**kwargs):
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
135 -def chainCallbacks(*args):
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
153 -def repeatALot(n = 1000):
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
171 -def this_is_deprecated(func,message=None):
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