1 import Views, Events, Logger, Bindings, Actions
2 from Views import EventWidget
3 import time, os, struct, curses
5 class View(Views.WidgetView):
7 def __init__(self, context, label, numeric_switches, alpha_switches, x, y, dx=0, size=11):
9 dx = max(dx,size*numeric_switches+3)
10 delta = dx - size*numeric_switches - 3
12 delta = dx - size*numeric_switches - 2*shift
13 Views.WidgetView.__init__(self, context, label, x, y, dx, 7)
15 split = numeric_switches // 2
16 for i in range(split):
17 self.add( EventWidget(i,str(i+1)[-1:],size*i+1+shift,4,size) )
18 for i in range(split,numeric_switches):
19 self.add( EventWidget(i,str(i+1)[-1:],size*i+shift+delta,4,size) )
20 split = max(0,alpha_switches-(numeric_switches-split))
21 offset = size//2+(numeric_switches-alpha_switches-1)*size
22 for i in range(split):
23 self.add( EventWidget(i+numeric_switches, chr(ord('A')+i), size*i+1+offset+shift,1,size) )
24 for i in range(split, alpha_switches):
25 self.add( EventWidget(i+numeric_switches, chr(ord('A')+i), size*i+delta+offset+shift,1,size) )
31 STRUCT_len = struct.calcsize(STRUCT)
37 def __init__(self, data):
38 self.time, self.value, self.type, self.number = struct.unpack(self.STRUCT,data)
41 return "%s(time=%d, value=%d,type=%d (%s)), number=%d)" % (
42 str(self.__class__),self.time, self.value, self.type, self.decode_type(), self.number)
44 def decode_type(self):
45 return ('','INIT|')[(self.type & self.TYPE_INIT) and 1 or 0] \
46 + ('','BUTTON','AXIS')[self.type & ~self.TYPE_INIT]
48 def readFrom(klass,f):
49 return klass(os.read(f.fileno(),klass.STRUCT_len))
50 readFrom=classmethod(readFrom)
52 def readMultipleFrom(klass,f,maxevents=256):
53 data = os.read(f.fileno(),maxevents*klass.STRUCT_len)
56 rv.append(klass(data[:klass.STRUCT_len]))
57 data = data[klass.STRUCT_len:]
59 readMultipleFrom=classmethod(readMultipleFrom)
62 class Source(Events.EventSource):
64 def __init__(self, joydev, context, bits=None, mindelay=100):
65 Events.EventSource.__init__(self, file(joydev), context)
68 self._mindelay = mindelay
69 self._controllers = {}
76 jsevents = JSEvent.readMultipleFrom(self.fd())
77 for event in jsevents:
78 if event.type == JSEvent.TYPE_AXIS:
79 return self._controller(event.number, event.value)
80 if event.type == JSEvent.TYPE_BUTTON and event.value == 1:
81 self._lastevent = event.time
82 if event.time - lev < self._mindelay : return []
83 n = n | self._bits[event.number]
87 event = JSEvent.readFrom(self.fd())
88 if event.type == JSEvent.TYPE_AXIS:
89 return self._controller(event.number, event.value)
90 if event.type == JSEvent.TYPE_BUTTON and event.value == 1:
91 self._lastevent = event.time
92 if event.time - lev < self._mindelay : return []
96 return [Events.Event(self.context(), n)]
98 def registerController(self, controller, low, high):
99 self._controllers[controller] = { 'low': low, 'high': high }
101 def _controller(self, number, value):
102 controller = self._controllers.get(number)
104 value = (value - controller['low']) * 1000 / (controller['high']-controller['low'])
105 value = max(min(value,1000),0)
106 return [Events.ControlEvent(self.context(), 'p%d' % number, value)]
110 class Controller(Views.View):
112 def __init__(self, context, name, x, y, dx, dy, keylist, dispatcher,
113 controller, source, low, high):
114 Views.View.__init__(self, context, name, x, y, dx, dy)
115 self._valueEvent = None
116 self._setCommand = None
117 self._valueCommand = None
118 self._parameter = None
119 self._keylist = keylist
120 self._keymap = Bindings.KeyMap()
122 self._keymap.add( Bindings.Binding(Events.Event(source.context(), 'p%d' % controller), '',
123 Actions.Command('controllerChanged',
124 self._controllerChanged)) )
125 self._keylist.prepend(self._keymap)
127 source.registerController(controller, low, high)
128 self._dispatcher = dispatcher
133 self._controlValue = None
135 def updateView(self, bindings):
139 Views.View.init(self)
142 def assign(self, parameter, setCommand, valueCommand, valueEvent, min, max, stops=[]):
143 self._keylist.removeMap(self._keymap)
144 if self._valueEvent is not None:
145 self._keymap.unbind(self._valueEvent)
146 self._parameter = parameter
147 self._valueEvent = valueEvent
148 self._setCommand = setCommand
149 self._valueCommand = valueCommand
154 self._keymap.add( Bindings.Binding( self._valueEvent, '',
155 Actions.Command('updateValue',
156 self._updateValue)) )
157 self._keylist.prepend(self._keymap)
162 self._value = self._valueCommand()
165 def _updateValue(self, binding):
166 event = self._dispatcher.currentEvent()
167 self._value = event.value
170 def _controllerChanged(self, binding):
171 event = self._dispatcher.currentEvent()
172 Logger.log('ctl',"value = %d" % event.value)
173 self._controlValue = event.value
174 if self._controlValue >= 999 or self._controlValue <= 1:
175 self._dispatcher.setIdleCallback(self._changeValue,75)
176 elif self._controlValue >= 700 or self._controlValue <= 200:
177 self._dispatcher.setIdleCallback(self._changeValue,200)
179 self._dispatcher.unsetIdleCallback()
180 self._redrawController()
182 def _changeValue(self):
183 if self._value is None: return
184 if self._controlValue > 500:
189 def stepValue(self, direction):
191 newValue = self._value + (self._max - self._min) / (3000/50)
192 crossed = [ x for x in self._stops if x > self._value*1.0001 and x <= newValue ]
194 newValue = self._value - (self._max - self._min) / (3000/50)
195 crossed = [ x for x in self._stops if x < self._value/1.0001 and x >= newValue ]
196 if newValue >= self._max:
197 crossed = [ self._max ]
198 elif newValue <= self._min:
199 crossed = [ self._min ]
201 newValue = crossed[0]
202 self._dispatcher.unsetIdleCallback()
203 self._setCommand(newValue)
204 # Hmm ... why does value_command not work sometimes ??
205 self._value = newValue
208 self._setCommand(newValue)
212 self._value = self._valueCommand()
216 height, width = self.win().getmaxyx()
217 if self._parameter is not None:
218 self.win().addstr(1,2,self._parameter[:width-4].ljust(width-4), curses.A_BOLD)
219 self._redrawValue(False)
220 self._redrawController()
222 def _flt(self, value, width):
223 return ('%.3f' % value)[:width].ljust(width)
225 def _redrawValue(self, refresh=True):
226 height, width = self.win().getmaxyx()
228 if self._value is not None:
229 pos = height - 3 - int( (self._value - self._min) * (height-6)
230 / (self._max - self._min) + .5 )
231 if self._max is not None:
232 self.win().addstr(2,2, self._flt(self._max,width-7))
233 if pos is not None and pos == 3:
234 self.win().addstr(pos, 5, self._flt(self._value,width-7), curses.A_BOLD)
236 self.win().addstr(3, 5, "".ljust(width-7))
237 for row in range(4,height-3):
238 if pos is not None and row == pos:
239 self.win().addch(pos,3,curses.ACS_PLUS)
240 self.win().addstr(pos, 5, self._flt(self._value,width-7), curses.A_BOLD)
242 self.win().addch(row,3,curses.ACS_VLINE)
243 self.win().addstr(row, 5, "".ljust(width-7))
244 if pos is not None and pos == height-3:
245 self.win().addstr(pos, 5, self._flt(self._value,width-7), curses.A_BOLD)
247 self.win().addstr(height-3, 5, "".ljust(width-7))
248 if self._min is not None:
249 self.win().addstr(height-2,2,self._flt(self._min,width-7))
254 def _redrawController(self, refresh=True):
255 height, width = self.win().getmaxyx()
256 if self._controlValue is not None and self._controlValue >= 700:
257 self.win().addch(3,3,curses.ACS_UARROW)
259 self.win().addch(3,3,curses.ACS_TTEE)
260 if self._controlValue is not None and self._controlValue <= 200:
261 self.win().addch(height-3,3,curses.ACS_DARROW)
263 self.win().addch(height-3,3,curses.ACS_BTEE)
269 class StepController(Actions.Action):
271 def __init__(self, name, controller, direction):
272 Actions.Action.__init__(self, name)
273 self._controller = controller
274 self._direction = direction
276 def __call__(self, binding):
277 self._controller.stepValue(self._direction)
280 def register( viewmanager,
293 viewmanager.registerView( View(context, label, numeric_switches, alpha_switches, x, y, dx, size) )
295 if device is not None:
296 source = Source(device, context, bits)
297 dispatcher.registerSource( source )
300 def registerController( viewmanager, dispatcher, keylist, source, context, name, x, y, dx, dy,
301 controller, low, high ):
302 controller = Controller(context, name, x, y, dx, dy, keylist, dispatcher,
303 controller, source, low, high)
304 viewmanager.registerView( controller )