Package _Framework :: Module PhysicalDisplayElement
[hide private]
[frames] | no frames]

Source Code for Module _Framework.PhysicalDisplayElement

  1  #Embedded file name: /Users/versonator/Hudson/live/Projects/AppLive/Resources/MIDI Remote Scripts/_Framework/PhysicalDisplayElement.py 
  2  from ControlElement import ControlElement 
  3  from LogicalDisplaySegment import LogicalDisplaySegment, adjust_string 
  4  from Util import in_range 
  5  import Task 
6 7 -class PhysicalDisplayElement(ControlElement):
8 """ 9 Class representing a display on the controller 10 """ 11 _ascii_translations = {'0': 48, 12 '1': 49, 13 '2': 50, 14 '3': 51, 15 '4': 52, 16 '5': 53, 17 '6': 54, 18 '7': 55, 19 '8': 56, 20 '9': 57, 21 'A': 65, 22 'B': 66, 23 'C': 67, 24 'D': 68, 25 'E': 69, 26 'F': 70, 27 'G': 71, 28 'H': 72, 29 'I': 73, 30 'J': 74, 31 'K': 75, 32 'L': 76, 33 'M': 77, 34 'N': 78, 35 'O': 79, 36 'P': 80, 37 'Q': 81, 38 'R': 82, 39 'S': 83, 40 'T': 84, 41 'U': 85, 42 'V': 86, 43 'W': 87, 44 'X': 88, 45 'Y': 89, 46 'Z': 90, 47 'a': 97, 48 'b': 98, 49 'c': 99, 50 'd': 100, 51 'e': 101, 52 'f': 102, 53 'g': 103, 54 'h': 104, 55 'i': 105, 56 'j': 106, 57 'k': 107, 58 'l': 108, 59 'm': 109, 60 'n': 110, 61 'o': 111, 62 'p': 112, 63 'q': 113, 64 'r': 114, 65 's': 115, 66 't': 116, 67 'u': 117, 68 'v': 118, 69 'w': 119, 70 'x': 120, 71 'y': 121, 72 'z': 122, 73 '@': 64, 74 ' ': 32, 75 '!': 33, 76 '"': 34, 77 '.': 46, 78 ',': 44, 79 ':': 58, 80 ';': 59, 81 '?': 63, 82 '<': 60, 83 '>': 62, 84 '[': 91, 85 ']': 93, 86 '_': 95, 87 '-': 45, 88 '|': 124, 89 '&': 38, 90 '^': 94, 91 '~': 126, 92 '`': 96, 93 "'": 39, 94 '%': 37, 95 '(': 40, 96 ')': 41, 97 '/': 47, 98 '\\': 92, 99 '*': 42, 100 '+': 43} 101
102 - def __init__(self, width_in_chars = None, num_segments = 1, *a, **k):
103 super(PhysicalDisplayElement, self).__init__(*a, **k) 104 raise width_in_chars is not None or AssertionError 105 raise num_segments is not None or AssertionError 106 self._width = width_in_chars 107 self._logical_segments = [] 108 self._translation_table = self._ascii_translations 109 self.set_num_segments(num_segments) 110 self._message_header = None 111 self._message_tail = None 112 self._message_part_delimiter = None 113 self._message_clear_all = None 114 self._message_to_send = None 115 self._last_sent_message = None 116 self._block_messages = False 117 self._send_message_task = self._tasks.add(Task.run(self._send_message)) 118 self._send_message_task.kill()
119
120 - def disconnect(self):
123
124 - def _disconnect_segments(self):
125 for segment in self._logical_segments: 126 segment.disconnect()
127 128 @property
129 - def num_segments(self):
130 return len(self._logical_segments)
131
132 - def set_num_segments(self, num_segments, use_delimiters = True):
133 if not in_range(num_segments, 1, self._width - num_segments + 1): 134 raise AssertionError 135 if num_segments != len(self._logical_segments): 136 self._disconnect_segments() 137 width_without_delimiters = use_delimiters and self._width - num_segments + 1 138 else: 139 width_without_delimiters = self._width 140 width_per_segment = int(width_without_delimiters / num_segments) 141 self._logical_segments = [ LogicalDisplaySegment(width_per_segment, self.update) for _ in xrange(num_segments) ]
142
143 - def set_data_sources(self, sources):
144 """ 145 Given a sequences of data sources, divides the display into 146 the number of segments neded to accomodate them and connects 147 the logical segments to the data sources. 148 """ 149 if not sources: 150 self.set_num_segments(1) 151 self.reset() 152 else: 153 self.set_num_segments(len(sources)) 154 for segment, source in zip(self._logical_segments, sources): 155 segment.set_data_source(source)
156
157 - def set_translation_table(self, translation_table):
158 raise '?' in translation_table['?'] or AssertionError 159 self._translation_table = translation_table
160
161 - def set_message_parts(self, header, tail, delimiter = tuple()):
162 """ 163 Takes message parts as tuples containing the sysex bytes for 164 each part of the message. 165 """ 166 self._message_header = header 167 self._message_tail = tail 168 self._message_part_delimiter = delimiter
169
170 - def set_clear_all_message(self, message):
171 self._message_clear_all = message
172
173 - def set_block_messages(self, block):
174 if block != self._block_messages: 175 self._block_messages = block 176 self.clear_send_cache()
177
178 - def segment(self, index):
179 return self._logical_segments[index]
180
181 - def update(self):
182 if not self._message_header is not None: 183 raise AssertionError 184 self._message_to_send = len(self._logical_segments) > 0 and not self._block_messages and None 185 self._request_send_message()
186
187 - def display_message(self, message):
188 if not self._block_messages: 189 message = adjust_string(message, self._width) 190 self._message_to_send = self._message_header + self._translate_string(message) + self._message_tail 191 self._request_send_message()
192
193 - def reset(self):
194 if not (self._message_clear_all is not None or self._message_header is not None): 195 raise AssertionError 196 for segment in self._logical_segments: 197 segment.set_data_source(None) 198 199 if not self._block_messages: 200 self._message_to_send = self._message_clear_all != None and self._message_clear_all 201 else: 202 self._message_to_send = self._message_header + self._translate_string(' ' * self._width) + self._message_tail 203 self._request_send_message()
204
205 - def send_midi(self, midi_bytes):
206 if midi_bytes != self._last_sent_message: 207 ControlElement.send_midi(self, midi_bytes) 208 self._last_sent_message = midi_bytes
209
210 - def clear_send_cache(self):
211 self._last_sent_message = None 212 self._request_send_message()
213
214 - def _request_send_message(self):
215 self._send_message_task.restart()
216
217 - def _send_message(self):
218 if not self._block_messages: 219 if self._message_to_send is None: 220 self._build_message_from_segments() 221 self.send_midi(self._message_to_send)
222
223 - def _translate_char(self, char_to_translate):
224 result = 63 225 if char_to_translate in self._translation_table.keys(): 226 result = self._translation_table[char_to_translate] 227 else: 228 result = self._translation_table['?'] 229 return result
230
231 - def _translate_string(self, string):
232 return tuple([ self._translate_char(c) for c in string ])
233
235 message = self._message_header 236 for segment in self._logical_segments: 237 message += segment.position_identifier() 238 message += self._translate_string(segment.display_string()) 239 if self._message_part_delimiter != None and segment != self._logical_segments[-1]: 240 message += self._message_part_delimiter 241 242 message += self._message_tail 243 self._message_to_send = message
244