Skip to content

Commit

Permalink
Added scrolling for menus longer than the terminal
Browse files Browse the repository at this point in the history
Fixes #2, fixes #13.
  • Loading branch information
pmbarrett314 committed Mar 3, 2016
1 parent 91204b6 commit f53160a
Showing 1 changed file with 22 additions and 6 deletions.
28 changes: 22 additions & 6 deletions cursesmenu/curses_menu.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ class CursesMenu(object):
is currently active (E.G. when switching between menus)
"""
currently_active_menu = None
stdscr = None

def __init__(self, title=None, subtitle=None, show_exit_option=True):
"""
Expand Down Expand Up @@ -95,6 +96,11 @@ def append_item(self, item):
self.items.append(item)
if did_remove:
self.add_exit()
if self.screen:
max_row, max_cols = self.screen.getmaxyx()
if max_row < 6 + len(self.items):
self.screen.resize(6 + len(self.items), max_cols)
self.draw()

def add_exit(self):
"""
Expand Down Expand Up @@ -126,7 +132,7 @@ def _wrap_start(self):
if self.parent is None:
curses.wrapper(self._main_loop)
else:
self._main_loop(curses.initscr())
self._main_loop(None)
CursesMenu.currently_active_menu = None
self.clear_screen()
clear_terminal()
Expand Down Expand Up @@ -174,9 +180,12 @@ def show(self, show_exit_option=None):
self.join()

def _main_loop(self, scr):
self.screen = scr
if scr is not None:
CursesMenu.stdscr = scr
self.screen = curses.newpad(len(self.items) + 6, CursesMenu.stdscr.getmaxyx()[1])
self._set_up_colors()
curses.curs_set(0)
CursesMenu.stdscr.refresh()
self.draw()
CursesMenu.currently_active_menu = self
self._running.set()
Expand All @@ -187,8 +196,6 @@ def draw(self):
"""
Redraws the menu and refreshes the screen. Should be called whenever something changes that needs to be redrawn.
"""
if self.screen.getmaxyx()[0] < 5 + len(self.items):
raise Exception("There are too many items to fit in your terminal")

self.screen.border(0)
if self.title is not None:
Expand All @@ -202,7 +209,16 @@ def draw(self):
else:
text_style = self.normal
self.screen.addstr(5 + index, 4, item.show(index), text_style)
self.screen.refresh()

screen_rows, screen_cols = CursesMenu.stdscr.getmaxyx()
top_row = 0
if 6 + len(self.items) > screen_rows:
if screen_rows + self.current_option < 6 + len(self.items):
top_row = self.current_option
else:
top_row = 6 + len(self.items) - screen_rows

self.screen.refresh(top_row, 0, 0, 0, screen_rows - 1, screen_cols - 1)

def is_running(self):
"""
Expand Down Expand Up @@ -253,7 +269,7 @@ def get_input(self):
:return: the ordinal value of a single character
:rtype: int
"""
return self.screen.getch()
return CursesMenu.stdscr.getch()

def process_user_input(self):
"""
Expand Down

0 comments on commit f53160a

Please sign in to comment.