Example #1
0
class Scroller:
    def __init__(self):
        random.seed()
        self.width = 40
        self.height = 2
        self.timeoutmin = 20
        self.timeoutmax = 100
        self.wait_time = 40
        self.separator = ' +++ '
        self.paused = False
        self.paused_loop = 0
        self.busy = False
        self.busy_loop = 0
        self.elapsed = ''
        
        self.lines = []
        self.offset = []
        self.tag = []
        for i in range(self.height):
            self.lines.append('')
            self.offset.append(0)
            self.tag.append('')
            
        self.ascii_art = {}
        self.load_ascii_art()
        
        # 0   - animation running
        # > 0 - animation countdown
        # -1  - animation and countdown disabled
        self.easter_egg_countdown = -1
        
        self.animation_index = self.ascii_art.keys()[random.randrange(0, len(self.ascii_art))]
        self.animation_phase = 0

        self.lcd = Adafruit_CharLCD()
        self.lcd.begin(40, 2)
        self.lcd.define_char(1, [0, 0x10, 0x08, 0x04, 0x02, 0x01, 0, 0])
        self.lcd.define_char(2, [0, 31, 14, 4, 21, 10, 0, 0])
        self.current_lines = ["", ""]
    
    def tr(self, s):
        result = ''.encode('latin-1')
        for c in unicode(s, 'UTF-8'):
            #print(c, ord(c))
            if ord(c) == 92:
                result += u'\x01'.encode('latin-1')
            elif ord(c) < 128:
                result += c.encode('latin-1')
            elif ord(c) == 246:
                result += u'\xef'.encode('latin-1')
            elif ord(c) == 252:
                result += u'\xf5'.encode('latin-1')
            elif ord(c) == 228:
                result += u'\xe1'.encode('latin-1')
            elif ord(c) == 223:
                result += u'\xe2'.encode('latin-1')
            elif ord(c) == 169:
                result += '(c)'.encode('latin-1')
            else:
                pass
                #print(c)
                #print(ord(c))
        return result
            
    def load_ascii_art(self):
        with open('ascii-art.txt') as f:
            while True:
                tag = f.readline().strip()
                if len(tag) == 0:
                    break
                self.ascii_art[tag] = []
                while True:
                    line1 = f.readline().rstrip()
                    if len(line1) == 0:
                        break
                    line2 = f.readline().rstrip()
                    line1 = self.tr(line1)
                    line2 = self.tr(line2)
                    if len(line1) > len(line2):
                        line2 += ' ' * (len(line1) - len(line2))
                    if len(line2) > len(line1):
                        line1 += ' ' * (len(line2) - len(line1))
                    self.ascii_art[tag].append(line1)
                    self.ascii_art[tag].append(line2)

    def set_line(self, i, s = '', tag = ''):
        if s == None:
            s = ''
        if tag == self.tag[i]:
            if self.offset[i] > 0:
                return
        s = self.tr(s)
        if s != self.lines[i]:
            self.lines[i] = s
            self.offset[i] = -self.wait_time
        self.tag[i] = tag
        if self.lines[0] == '' and self.lines[1] == '':
            if self.easter_egg_countdown < 0:
                self.easter_egg_countdown = random.randrange(self.timeoutmin, self.timeoutmax)
                self.animation_index = self.ascii_art.keys()[random.randrange(0, len(self.ascii_art))]
                self.animation_phase = 0
        else:
            self.easter_egg_countdown = -1
        
    def set_paused(self, paused):
        self.paused = paused
        
    def set_busy(self, busy):
        self.busy = busy
        
    def set_elapsed(self, elapsed):
        self.elapsed = elapsed
            
    def render(self):
        result_lines = []
        
        if self.easter_egg_countdown > 0:
            self.easter_egg_countdown -= 1
            
        if self.easter_egg_countdown == 0:
            # animation
            
            for i in range(2):
                offset = -len(self.ascii_art[self.animation_index][i]) + self.animation_phase
                frames = len(self.ascii_art[self.animation_index]) / 2
                part = self.ascii_art[self.animation_index][i + (2 * (self.animation_phase % frames))]
                if offset < 0:
                    part = part[-offset:]
                else:
                    part = (' ' * offset) + part
                part += ' ' * self.width
                part = part[:self.width]
                result_lines.append(part)
                if (offset > self.width):
                    self.easter_egg_countdown = random.randrange(self.timeoutmin, self.timeoutmax)
                    self.animation_index = self.ascii_art.keys()[random.randrange(0, len(self.ascii_art))]
                    self.animation_phase = 0
                    
            self.animation_phase = self.animation_phase + 1
        else:
            # print lines
            for i in range(self.height):
                line = self.lines[i]
                cropped = line
                if len(line) > self.width:
                    cropped += self.separator
                    cropped += line
                offset = self.offset[i]
                if offset < 0:
                    offset = 0
                cropped += ' ' * self.width
                cropped = cropped[offset:(offset + self.width)]
                    
                if i == 0:
                    if self.busy:
                        cropped = cropped[:-2]
                        self.busy_loop = (self.busy_loop + 1) % 4
                        cropped += ' '
                        cropped += ('/-' + u'\x01'.encode('latin-1') + '|')[self.busy_loop]
                if i == 1:
                    if self.paused:
                        cropped = cropped[:-2]
                        self.paused_loop = (self.paused_loop + 1) % 4
                        cropped += ' '
                        cropped += '.oOo'[self.paused_loop]
                    #else:
                        #if self.elapsed != '':
                            #cropped = cropped[:-(len(self.elapsed) + 2)]
                            #cropped += "|%s" % self.elapsed

                if i == 0:
                    cropped = cropped[:-2]
                    cropped += ' '
                    cropped += '"'
                if i == 1:
                    cropped = cropped[:-2]
                    cropped += ' '
                    cropped += u'\x02'.encode('latin-1')

                result_lines.append(cropped)
        #os.system("clear")
        #self.lcd.clear()
        self.lcd.setCursor(0, 0)
        for index, cropped in enumerate(result_lines):
            #if cropped != self.current_lines[index]:
                self.current_lines[index] = cropped
                self.lcd.message(cropped)
                #print(cropped)
                #print(cropped)
        #print()
        
    def animate(self):
        for i in range(self.height):
            line = self.lines[i]
            if len(line) <= self.width:
                self.offset[i] = 0
            else:
                self.offset[i] += 1
                if self.offset[i] == len(line) + len(self.separator):
                    self.offset[i] = -self.wait_time
                    
    def clear(self):
        for i in range(self.height):
            self.set_line(i, '')