示例#1
0
 def addstr(self, xxx_todo_changeme6, string, color=None):
     (y, x) = xxx_todo_changeme6
     string = string.encode('ascii','ignore')
     try:
         if color:
             meta = curses.color_pair(color)
             self.__pad.addstr(y, x, string, meta)
         else:
             self.__pad.addstr(y, x, string)
     except curses.error as e:
         if y >= self.__h:
             raise curses.error('%s: %s' % (e.message, 'Y bounds exceeded'))
         if x + len(string) >= self.__w:
             raise curses.error('%s: %s' % (e.message, 'X bounds exceeded'))
示例#2
0
 def tparm(*args):
     raise curses.error("unexpected error in tparm()")
示例#3
0
 def tparm(*args):
     raise curses.error("tparm() returned NULL")
示例#4
0
def example(window):
    t0 = time()
    tot = 0
    mid, mx, my, mz, mbstate = 0, 0, 0, 0, 0
    ymax, xmax = window.getmaxyx()

    # Win1 Drawing text once
    win1 = window.subwin(0, 0)
    try:
        win1.addch(ymax-10, 24, curses.ACS_LARROW)
    except:
        win1.move(0, 0)
    win1.hline(ymax-10, 25, curses.ACS_HLINE, 10)
    win1.addstr(ymax-10, 36, "click this box, type, or press H, or Q")
    win1.vline(ymax-9, 54, curses.ACS_VLINE, 2)
    win1.addch(ymax-7, 54, curses.ACS_DARROW)

    # Window 2
    win2 = curses.newwin(12, 21, ymax-13, 1)
    win2.bkgd(' ', curses.A_BOLD | curses.A_REVERSE)
    win2_inv = True
    win2.box()
    win2.keypad(1)
    win2.nodelay(1)
    win2.border()
    win2.leaveok(0)
    win2.scrollok(0)

    # Window 3
    win3 = curses.newwin(3, 21, ymax-6, 36)
    win3.bkgd(' ', curses.A_BOLD)
    win3.box()
    win3.keypad(1)
    win3.nodelay(1)
    win3.border()
    win3.leaveok(0)
    win3.scrollok(0)
    win3_s = ''

    # Mainloop
    while True:
        t1 = time()
        tot += 1
        ups = tot/(t1-t0)
        x = randint(1, randint(1, xmax - 2))
        y = randint(1, randint(1, ymax - 2 - 12))
        c = ord('#')

        # window.erase() # IF YOU WANT TO REDRAW DON'T USE CLEAR!

        # Input
        getch = window.getch() 
        if getch == curses.KEY_MOUSE or getch == ord('H'):
            tmid, tmx, tmy, tmz, tmbstate = curses.getmouse()
            if getch == ord('H') or tmbstate == 2 and win2.enclose(tmy, tmx):
                mid, mx, my, mz, mbstate = tmid, tmx, tmy, tmz, tmbstate
                if win2_inv:
                    win2.bkgdset(' ', curses.A_BOLD)
                else:
                    win2.bkgdset(' ', curses.A_BOLD | curses.A_REVERSE)
                win2_inv = not win2_inv
        elif getch == ord('Q'):
            raise SystemExit(None)

        # Window 1
        try:
            win1.addch(y, x, c)  # Totally unbuffered print
        except:
            win1.move(0, 0)
        win1.noutrefresh()  # Mark for update

        # Window 2
        ylst, xlst = curses.getsyx()
        win2.addstr(12-11, 1, "tot   :%12i" % tot)
        win2.addstr(12-10, 1, "#/s   :%12.3f" % ups)
        win2.addstr(12-9,  1,  "t tot :%12.3f" % (t1-t0))
        win2.addstr(12-8,  1,  "y lst :%12i" % ylst)
        win2.addstr(12-7,  1,  "x lst :%12i" % xlst)
        win2.addstr(12-6,  1,  "m id  :%12i" % mid)
        win2.addstr(12-5,  1,  "m x   :%12i" % mx)
        win2.addstr(12-4,  1,  "m y   :%12i" % my)
        win2.addstr(12-3,  1,  "m z   :%12i" % mz)
        win2.addstr(12-2,  1,  "m st  :%12i" % mbstate)
        win2.noutrefresh()

        # Window 3
        ylst, xlst = curses.getsyx()
        if getch >= 0x20 and getch < 0x7f and chr(getch) not in uppercase:
            try:
                win3_s += chr(getch)
                win3.addstr(1, 1, win3_s)
                if len(win3_s) > 18:
                    raise curses.error('String too long')
            except:
                win3_s = chr(getch)
                win3.move(0, 0)
        win3.noutrefresh()

        sleep(MIN_SLEEP)
        curses.doupdate()  # Perform refreshes
示例#5
0
 def tparm(*args):
     raise curses.error("tparm() returned NULL")
示例#6
0
def main(stdscr):
    """Draw a simple TUI, grab keypresses and let the user manipulate the
    DSP parameters.
    """
    stdscr.clear()
    stdscr.nodelay(True)

    # Create small visual display
    stdscr.addstr(
        "======================\n"
        "Generate Tone Example.\n"
        "======================\n"
        "\n"
        "Press 1 to play a sine wave\n"
        "Press 2 to play a sqaure wave\n"
        "Press 3 to play a saw wave\n"
        "Press 4 to play a triangle wave\n"
        "Press SPACE to stop the channel\n"
        "Press q to quit\n"
        "Press k and j to change volume\n"
        "Press h and l to change frequency"
    )

    channel = None
    while True:
        if channel:
            playing = "playing" if channel.is_playing else "stopped"
            volume = channel.volume
            frequency = channel.frequency
        else:
            playing = "stopped"
            volume = 0
            frequency = 0

        stdscr.move(13, 0)
        stdscr.clrtoeol()
        stdscr.addstr(f"Channel is {playing}")

        stdscr.move(14, 0)
        stdscr.clrtoeol()
        stdscr.addstr(f"Volume {volume:.2f}")

        stdscr.move(15, 0)
        stdscr.clrtoeol()
        stdscr.addstr(f"Frequency {frequency}")

        # Listen to the user
        try:
            keypress = stdscr.getkey()
            if keypress == "1":
                if channel:
                    channel.stop()
                channel = system.play_dsp(dsp, paused=True)
                channel.volume = 0.5
                dsp.set_parameter_int(DSP_OSCILLATOR.TYPE, 0)
                channel.paused = False
            elif keypress == "2":
                if channel:
                    channel.stop()
                channel = system.play_dsp(dsp, paused=True)
                channel.volume = 0.125
                dsp.set_parameter_int(DSP_OSCILLATOR.TYPE, 1)
                channel.paused = False
            elif keypress == "3":
                if channel:
                    channel.stop()
                channel = system.play_dsp(dsp, paused=True)
                channel.volume = 0.125
                dsp.set_parameter_int(DSP_OSCILLATOR.TYPE, 2)
                channel.paused = False
            elif keypress == "4":
                if channel:
                    channel.stop()
                channel = system.play_dsp(dsp, paused=True)
                channel.volume = 0.5
                dsp.set_parameter_int(DSP_OSCILLATOR.TYPE, 4)
                channel.paused = False
            elif keypress == " ":
                if channel:
                    channel.stop()
                channel = None
            elif keypress == "q":
                break

            if not channel:
                raise curses.error("no input")

            if keypress == "h":
                channel.frequency = max(channel.frequency - 500, 0)
            elif keypress == "j":
                channel.volume = max(channel.volume - 0.1, 0)
            elif keypress == "k":
                channel.volume = min(channel.volume + 0.1, 1)
            elif keypress == "l":
                channel.frequency = channel.frequency + 500
        except curses.error as cerr:
            if cerr.args[0] != "no input":
                raise cerr

        system.update()
        time.sleep(50 / 1000)
示例#7
0
 def curses_error():
     raise curses.error()
示例#8
0
    def setup(self, stdscr):
        """
        Draw the menu and handle keyboard input.

        Parameters:
            stdscr (WindowObject): the screen; handled by curses.wrapper

        Returns:
            the string representing the currently selected row
        """

        # Initialize the WindowObject
        stdscr.clear()
        stdscr = curses.initscr()
        curses.noecho()
        curses.cbreak()

        # Start color support if supported
        if curses.has_colors():
            curses.start_color()

        # Initialize color pairs
        # Main window
        curses.init_pair(1, curses.COLOR_WHITE, curses.COLOR_BLUE)
        # Sub-windows
        curses.init_pair(2, curses.COLOR_BLACK, curses.COLOR_WHITE)

        # Verify this is a terminal that is at least both 80 columns and 24 lines
        if curses.LINES < 24 or curses.COLS < 80:
            raise curses.error(
                "Required minimum terminal dimensions of 80x24 > {}x{}.".
                format(curses.COLS, curses.LINES))

        main_window, screen, footer = self.draw_menu(stdscr)

        # Menu loop until item is chosen with the <enter> key or the user quits with "q"
        while True:
            # Get a character from the keyboard
            key = stdscr.getch()
            # Enter selects the highlighted item
            if key == ord("\n"):
                footer_selection = self.footer_items[self.current_column]
                if footer_selection == "Select":
                    if isinstance(self._items[self.current_row - 1],
                                  (ec2rlcore.menu_item.ExitItem,
                                   ec2rlcore.menu_item.RunItem)):
                        self._items[self.current_row - 1]()
                        self.current_row = 1
                        self.current_column = 0
                        self.current_page = 1
                        self.done = True
                        return
                    else:
                        self.current_column = 0
                        return self._items[self.current_row - 1]()
                elif footer_selection == "Exit":
                    self.current_row = 1
                    self.current_column = 0
                    self.current_page = 1
                    self.done = True
                    return
                elif footer_selection == "Help":
                    self.current_column = 0
                    return self.show_item_help(self._items[self.current_row -
                                                           1])
                elif footer_selection == "Clear":
                    if isinstance(self._items[self.current_row - 1],
                                  ec2rlcore.menu_item.TextEntryItem):
                        self._items[self.current_row - 1].row_right = ""
                else:
                    raise MenuUnsupportedFooterOptionError(footer_selection)
            elif key == ord(" "):
                if isinstance(self._items[self.current_row - 1],
                              ec2rlcore.menu_item.ToggleItem):
                    self._items[self.current_row - 1]()
            elif key in (78, "N"):
                # Select/deselect all ToggleItems in current menu
                for item in self._items:
                    if isinstance(item, ec2rlcore.menu_item.ToggleItem) \
                            and ((self.toggle_state and item.toggled) or (not self.toggle_state and not item.toggled)):
                        item()
                self.toggle_state = not self.toggle_state
            elif key in (260, curses.KEY_LEFT):
                if self.current_column > 0:
                    self.current_column -= 1
            # The right arrow key selects the footer option to the right of the currently selected item
            elif key in (261, curses.KEY_RIGHT):
                if self.current_column < self.num_columns - 1:
                    self.current_column += 1
            # The down arrow key selects the next option in the menu window and increments the page as needed
            elif key in (65, 258, curses.KEY_DOWN):
                if self.current_page == 1:
                    if self.current_row < self.max_displayed_rows and \
                                            self.current_row < self.num_rows:
                        self.current_row += 1
                    # Else + if num_pages > 1
                    elif self.num_pages > 1:
                        self.current_page += 1
                        self.current_row = 1 + (self.max_displayed_rows *
                                                (self.current_page - 1))
                elif self.current_page == self.num_pages:
                    if self.current_row < self.num_rows:
                        self.current_row += 1
                else:
                    if self.current_row < self.max_displayed_rows + \
                            (self.max_displayed_rows * (self.current_page - 1)):
                        self.current_row += 1
                    else:
                        self.current_page += 1
                        self.current_row = 1 + (self.max_displayed_rows *
                                                (self.current_page - 1))
            # The up arrow key selects the previous option in the menu window and decrements the page as needed
            elif key in (66, 259, curses.KEY_UP):
                if self.current_page == 1:
                    if self.current_row > 1:
                        self.current_row -= 1
                else:
                    if self.current_row > (1 + (self.max_displayed_rows *
                                                (self.current_page - 1))):
                        self.current_row -= 1
                    else:
                        self.current_page -= 1
                        self.current_row = \
                            self.max_displayed_rows + (self.max_displayed_rows * (self.current_page - 1))
            # The page down key increments the page  and selects the row in the same position in the menu on that page
            # or the first row if the next page doesn't have an equivalent row
            # Ignore page down key presses on the last page
            elif key in (338, curses.KEY_NPAGE
                         ) and self.current_page < self.num_pages:
                self.current_page += 1
                # Bounds check to ensure there are enough items on the next page to select an item in the same position
                # This will be true for all pages but the last page which will likely be a partial page of items
                if self.current_row + self.max_displayed_rows < self.num_rows:
                    self.current_row += self.max_displayed_rows
                # If the bounds check fails then select the first item on the next (last) page
                else:
                    self.current_row = (
                        (self.current_page - 1) * self.max_displayed_rows) + 1
            # The page up key decrements the page and selects the row in the same position in the menu on that page
            # Ignore page up key presses when on the first page
            elif key in (339, curses.KEY_PPAGE) and self.current_page > 1:
                self.current_page -= 1
                # Shift the currently selected row to the same place on the new page
                self.current_row -= self.max_displayed_rows
            elif key in (410, curses.KEY_RESIZE):
                # Get the new terminal dimensions and resize the terminal
                curses.resizeterm(*stdscr.getmaxyx())

                # Verify the terminal is still at least 80x24
                if curses.LINES < 24 or curses.COLS < 80:
                    raise curses.error(
                        "Required minimum terminal dimensions of 80x24 > {}x{}."
                        .format(curses.COLS, curses.LINES))

                # Initialize a new WindowObject
                stdscr = curses.initscr()
                curses.noecho()
                curses.cbreak()

                main_window, screen, footer = self.draw_menu(stdscr)

                # Recalculate the current page
                # current_selected_row - 1 is needed because the row in the window is offset by 1
                self.current_page = int(
                    math.ceil(self.current_row / self.max_displayed_rows))

                # For some reason, another getch() call is required to pull the KEY_RESIZE out of the buffer
                stdscr.getch()

            # Erase the screen so it can be cleanly redrawn
            screen.erase()
            screen.border(0)

            self._draw_menu(screen)

            # Draw the navigation items in the footer
            self._draw_footer(footer)

            # Draw the pieces of the overall screen (order matters)
            stdscr.noutrefresh()
            main_window.noutrefresh()
            screen.noutrefresh()
            footer.noutrefresh()
            curses.doupdate()