Esempio n. 1
0
    async def wait_choice(self):
        #
        # Wait until a menu choice is picked; let them move around
        # the menu, keep redrawing it and so on.

        key = None

        # 5,8 have key-repeat, not others
        pr = PressRelease('790xy')

        while 1:
            self.show()

            key = await pr.wait()

            if not key:
                continue
            if key == '5':
                self.up()
            elif key == '8':
                self.down()
            elif key == '7':
                self.page(-1)       # maybe should back out of nested menus?
            elif key == '9':
                self.page(1)
            elif key == '0':
                # zip to top, no selection
                self.cursor = 0
                self.ypos = 0
            elif key in '1234':
                # jump down, based on screen postion
                self.goto_n(ord(key)-ord('1'))
            elif key == 'y':
                # selected
                return self.cursor
            elif key == 'x':
                # abort/nothing selected/back out?
                return None
Esempio n. 2
0
    async def interact(self):
        # Prompt for prefix and pin. Returns string or None if the abort.
        if self.randomize:
            self.shuffle_keys()

        self.show_pin(True)
        pr = PressRelease('y')
        while 1:
            ch = await pr.wait()

            if ch == 'x':
                if not self.pin and self.pin_prefix:
                    # cancel on empty 2nd-stage: start over
                    self.reset()
                    self.show_pin()
                    continue

                if not self.pin and not self.pin_prefix:
                    # X on blank first screen: stop
                    return None
                    
                # do a delete-one
                if self.pin:
                    self.pin = self.pin[:-1]
                    self.show_pin()

            elif ch == 'y':
                if len(self.pin) < MIN_PIN_PART_LEN:
                    # they haven't given enough yet
                    continue

                if self.pin_prefix:
                    # done!
                    return (self.pin_prefix + '-' + self.pin)

                self._show_words()

                nxt = await ux_wait_keyup('xy2' if self.offer_second else 'xy')
                if nxt == 'y' or nxt == '2':
                    self.pin_prefix = self.pin
                    self.pin = ''
                    self.is_secondary = (nxt == '2')

                    if self.randomize:
                        self.shuffle_keys()
                elif nxt == 'x':
                    self.reset()

                self.show_pin(True)

            else:
                #assert ch in '0123456789' or ch == ''

                if self.randomize and ch:
                    ch = self.randomize[int(ch)]

                if len(self.pin) == MAX_PIN_PART_LEN:
                    self.pin = self.pin[:-1] + ch
                else:
                    self.pin += ch

                self.show_pin()
Esempio n. 3
0
async def spinner_edit(pw):
    # Allow them to pick each digit using "D-pad"
    from main import dis
    from display import FontTiny, FontSmall

    # Should allow full unicode, NKDN
    # - but limited to what we can show in FontSmall
    # - so really just ascii; not even latin-1
    # - 8-bit codepoints only
    my_rng = range(32, 127)          # FontSmall.code_range
    symbols = b' !"#$%&\'()*+,-./:;<=>?@[\\]^_`{|}~'
    letters = b'abcdefghijklmnopqrstuvwxyz'
    Letters = b'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
    numbers = b'1234567890'
    #assert len(set(symbols+letters+Letters+numbers)) == len(my_rng)
    
    footer1 = "1=Letters  2=Numbers  3=Symbols"
    footer2 = "4=SwapCase  0=HELP"
    y = 20
    pw = bytearray(pw or 'A')

    pos = len(pw)-1       # which part being changed
    n_visible = const(9)
    scroll_x = max(pos - n_visible, 0)

    def cycle_set(which, direction=1):
        # pick next item in set of choices
        for n, s in enumerate(which):
            if pw[pos] == s:
                try:
                    pw[pos] = which[n+direction]
                except IndexError:
                    pw[pos] = which[0 if direction==1 else -1]
                return
        pw[pos] = which[0]

    def change(dx):
        # next/prev within the same subset of related chars
        ch = pw[pos]
        for subset in [symbols, letters, Letters, numbers]:
            if ch in subset:
                return cycle_set(subset, dx)

        # probably unreachable code: numeric up/down
        ch = pw[pos] + dx
        if ch not in my_rng:
            ch = (my_rng.stop-1) if dx < 0 else my_rng.start
            assert ch in my_rng
        pw[pos] = ch

    # no key-repeat on certain keys
    press = PressRelease('4xy')
    while 1:
        dis.clear()

        lr = pos - scroll_x     # left/right distance of cursor
        if lr < 4 and scroll_x:
            scroll_x -= 1
        elif lr < 0:
            scroll_x = pos
        elif lr >= (n_visible-1):
            # past right edge
            scroll_x += 1

        for i in range(n_visible):
            # calc abs position in string
            ax = scroll_x + i
            x = 4 + (13*i)
            try:
                ch = pw[ax]
            except IndexError:
                continue

            if ax == pos:
                # draw cursor
                if len(pw) < 2*n_visible:
                    dis.text(x-4, y-19, '0x%02X' % ch, FontTiny)
                dis.icon(x-2, y-10, 'spin')

            if ch == 0x20:
                dis.icon(x, y+11, 'space')
            else:
                dis.text(x, y, chr(ch) if ch in my_rng else chr(215), FontSmall)

        if scroll_x > 0:
            dis.text(2, y-14, str(pw, 'ascii')[0:scroll_x].replace(' ', '_'), FontTiny)
        if scroll_x + n_visible < len(pw):
            dis.text(-1, 1, "MORE>", FontTiny)

        if 0:
            wy = 6
            count = len(pw)
            dis.text(-8, wy-4, "%d" % count)


        dis.text(None, -10, footer1, FontTiny)
        dis.text(None, -1, footer2, FontTiny)
        dis.show()

        ch = await press.wait()
        if ch == 'y':
            return str(pw, 'ascii')
        elif ch == 'x':
            if len(pw) > 1:
                # delete current char
                pw = pw[0:pos] + pw[pos+1:]
                if pos >= len(pw):
                    pos = len(pw)-1
            else:
                pp = await ux_show_story("OK to leave without any changes? Or X to cancel leaving.")
                if pp == 'x': continue
                return None

        elif ch == '7':      # left
            pos -= 1
            if pos < 0: pos = 0
        elif ch == '9':      # right
            pos += 1
            if pos >= len(pw):
                if len(pw) < 100 and pw[-3:] != b'   ':
                    pw += ' '       # expand with spaces
                else:
                    pos -= 1        # abort addition

        elif ch == '5':     # up
            change(1)
        elif ch == '8':     # down
            change(-1)
        elif ch == '1':     # alpha
            cycle_set(b'Aa')
        elif ch == '4':     # toggle case
            if (pw[pos] & ~0x20) in range(65, 91):
                pw[pos] ^= 0x20
        elif ch == '2':     # numbers
            cycle_set(numbers)
        elif ch == '3':     # symbols (all of them)
            cycle_set(symbols)
        elif ch == '0':     # help
            await ux_show_story('''\
Use arrow keys (5789) to select letter and move around. 

1=Letters (Aa..)
2=Numbers (12..)
3=Symbols (!@#&*)
4=Swap Case (q/Q)
X=Delete char

To quit without changes, delete everything. \
Add more characters by moving past end (right side).
''')