def display(self):
self.panel.top()
self.panel.show()
self.window.clear()
while True:
self.window.refresh()
curses.doupdate()
for index, item in enumerate(self.items):
if index == self.position:
mode = curses.A_REVERSE
else:
mode = curses.A_NORMAL
msg = '%d. %s' % (index, item[0])
self.window.addstr(1+index, 1, msg, mode)
key = self.window.getch()
if key in [curses.KEY_ENTER, ord('\n')]:
# Handle exit from menu
if self.position == len(self.items)-1 or str(self.items[self.position][1]) == "exit":
break
else:
if self.rootmenu.set_selection(self.items[self.position][1]):
break
elif key == curses.KEY_UP:
self.navigate(-1)
elif key == curses.KEY_DOWN:
self.navigate(1)
self.window.clear()
self.panel.hide()
panel.update_panels()
curses.doupdate()
python类KEY_ENTER的实例源码
def run_main_loop(self):
self.draw_ui()
while 1:
c = self.window.getch()
if curses.keyname(c) in [b'h', b'H']:
self.show_help()
elif curses.keyname(c) in [b'p', b'P']:
self.play()
elif curses.keyname(c) in [b'q', b'Q']:
return None
elif c == 27:
self.returnString = self.dir.get_current_path()
return self.returnString
elif c == curses.KEY_ENTER or c == 10:
self.returnString = self.dir.get_current_path()
return self.returnString
elif c == curses.KEY_UP:
if self.selected_index > 0:
self.selected_index -= 1
self.draw_ui()
elif c == curses.KEY_DOWN:
if self.selected_index < self.dir.max_entries_on_level()-1:
self.selected_index += 1
self.draw_ui()
elif c == curses.KEY_LEFT:
self.leave_dir()
self.draw_ui()
elif c == curses.KEY_RIGHT:
self.enter_dir()
self.draw_ui()
elif c == curses.KEY_RESIZE:
self.draw_ui()
def __init__(self, log, stdscr, title, subtitle=None, items=[]):
self.log = log
self.stdscr = stdscr
self.title = title
self.subtitle = subtitle
self.items = items
self.num_selects = (
[ord(str(n)) for n in range(len(self.items)) if n < 10])
self.enter_selects = [curses.KEY_ENTER, ord('\n')]
curses.curs_set(0)
self.cursor_pos = 0
def get_key(self):
code = self.win.getch()
if code > 0:
# Accept newline and carriage return as enter key
if code == curses.ascii.NL or code == curses.ascii.CR:
code = curses.KEY_ENTER
# Accept newline and carriage return as enter key
if code == curses.ascii.BS:
code = curses.KEY_BACKSPACE
return code
def on_key(self, ch):
if ch == curses.KEY_ENTER:
self.state.set_scene("Main")
def on_key(self, ch):
if ch == curses.KEY_ENTER:
self.press()
return True
return False
def on_key(self, ch):
if not self.active:
return
if self.selected:
if ch in (curses.ascii.ESC, curses.KEY_BACKSPACE):
self.cancel_selection()
elif ch == curses.KEY_LEFT:
if self.selection > 0 and self.selection < 4 or self.selection > 4:
self.set_selection(self.selection - 1)
elif ch == curses.KEY_RIGHT:
if self.selection < 3 or self.selection > 3 and self.selection < 7:
self.set_selection(self.selection + 1)
elif ch == curses.KEY_UP:
if self.selection > 3:
self.set_selection(self.selection - 4)
elif ch == curses.KEY_DOWN:
if self.selection < 4 and self.selected_source == 'hand':
self.set_selection(self.selection + 4)
elif ch in (curses.KEY_ENTER, curses.ascii.SP):
self.confirm_selection()
else:
if ch == curses.KEY_LEFT:
if self.selection > 0:
self.set_selection(self.selection - 1)
elif ch == curses.KEY_RIGHT:
if self.selection + 1 < len(self.selectable_sources):
self.set_selection(self.selection + 1)
elif ch in (curses.KEY_ENTER, curses.ascii.SP):
self.confirm_selection()
def poll_event(self):
"""
Checks if an event happens and returns a string related to the event.
Returns -1 if nothing happened during self.screen.timeout milliseconds.
If the event is a normal (letter) key press,
the letter is returned (case sensitive)
:return: Event type
"""
self.mutex.acquire()
ch = self.screen.getch()
self.mutex.release()
if ch == -1:
return EVENT_SKIP
elif ch == 27:
return EVENT_ESC
elif ch == curses.KEY_RESIZE:
return EVENT_RESIZE
elif ch == 10 or ch == curses.KEY_ENTER:
return EVENT_ENTER
elif ch == 127 or ch == curses.KEY_BACKSPACE:
return EVENT_BACKSPACE
elif ch == curses.KEY_UP:
return EVENT_UP
elif ch == curses.KEY_DOWN:
return EVENT_DOWN
elif ch == curses.KEY_LEFT:
return EVENT_LEFT
elif ch == curses.KEY_RIGHT:
return EVENT_RIGHT
elif ch == 3:
return EVENT_CTRL_C
elif ch == 409:
return EVENT_CLICK
elif 0 <= ch < 256:
return chr(ch)
else:
return EVENT_UNHANDLED
def open_menu(stdscr, items):
"""Opens a menu containing items and returns the selected item.
Blocks until the user selected an item.
"""
width = max(map(len, items)) + 20
height = len(items*2)-1 + 4 # +2 for frame, +2 for padding
curses.curs_set(False)
selected = 0
while True:
center = (curses.COLS//2, curses.LINES//2)
menu_rect = Rect(center[0]-width//2, center[1]-height//2, width, height)
menu_rect = draw_frame(stdscr, menu_rect, thick_border=True)
for i, item in enumerate(items):
attr = curses.A_NORMAL
if i == selected:
attr = curses.A_STANDOUT
stdscr.addstr(menu_rect.y + 1 + i*2, center[0] - len(item)//2, item, attr)
c = stdscr.getch()
if c == curses.KEY_UP:
selected -= 1
if c == curses.KEY_DOWN:
selected += 1
if c == curses.KEY_ENTER or c == 10:
break
selected = clamp(selected, 0, len(items)-1)
curses.curs_set(True)
return items[selected]
def _create_pocket(self):
pocket_name = ""
while True:
self.screen.clear()
self._draw_tab_bar()
self.screen.addstr(2, 2, "Pocket name:")
self.screen.addstr(4, 4, pocket_name)
c = self.screen.getch()
if c == 27:
self._status = "Cancelled"
break
elif c == curses.KEY_ENTER or c == 10 or c == 13:
ec = await api.Pocket.create(self._ws, pocket_name)
if ec:
self._status = ec.name
else:
self._status = "Created"
break
elif c == curses.KEY_BACKSPACE:
pocket_name = pocket_name[:-1]
elif c == curses.KEY_LEFT or c == curses.KEY_RIGHT:
pass
else:
pocket_name += chr(c)
def _enter_password_tab2(self):
password = ""
while True:
self.screen.clear()
self._draw_tab_bar()
self.screen.addstr(2, 2, "Password:")
self.screen.addstr(4, 2, "*" * len(password))
c = self.screen.getch()
if c == curses.KEY_BACKSPACE:
password = password[:-1]
elif c == curses.KEY_ENTER or c == 10 or c == 13:
return password
elif c == curses.KEY_LEFT:
self._current_tab -= 1
if self._current_tab < 0:
self._current_tab = len(self._account_names) - 1
await self._activate_account()
return None
elif c == curses.KEY_RIGHT:
self._current_tab += 1
if self._current_tab >= len(self._account_names):
self._current_tab = 0
await self._activate_account()
return None
else:
password += chr(c)
def _select_account(self):
row_len = 20
selected = 0
while True:
self.screen.clear()
self.screen.addstr(1, 2, "Select an account:")
rows = self._account_names + ["New account"]
for i, account in enumerate(rows):
row_string = " %s" % account
row_string += " " * (row_len - len(row_string))
if i == selected:
color = self._active_account_color()
else:
color = self._inactive_account_color()
self.screen.addstr(i + 3, 2, row_string, color)
self._display_status()
self.screen.refresh()
c = self.screen.getch()
if c == curses.KEY_UP:
selected -= 1
if selected < 0:
selected = len(rows) - 1
elif c == curses.KEY_DOWN:
selected += 1
if selected >= len(rows):
selected = 0
elif c == curses.KEY_ENTER or c == 10 or c == 13:
if selected == len(rows) - 1:
await self._new_account()
break
else:
account_name = rows[selected]
password = self._enter_password()
ec = await api.Account.set(self._ws, account_name, password)
if ec:
self.screen.addstr(10, 2, "Error: %s" % ec.name)
else:
return
def _enter_password(self):
password = ""
while True:
self.screen.clear()
self.screen.addstr(1, 2, "Enter a password:")
self.screen.addstr(3, 2, "*" * len(password))
c = self.screen.getch()
if c == curses.KEY_BACKSPACE:
password = password[:-1]
elif c == curses.KEY_ENTER or c == 10 or c == 13:
return password
else:
password += chr(c)
def display(self):
self.window.clear()
self.showdetail()
while True:
self.has_focus = True
self.next_window.has_focus = False
self.window.refresh()
curses.doupdate()
self.update()
key = self.window.getch()
if key in [curses.KEY_ENTER, ord('\n')]:
return self.position
if key == curses.KEY_UP:
if self.position == 0:
self.navigate(self.last_item_index)
else:
self.navigate(-1)
elif key == curses.KEY_DOWN:
self.navigate(1)
elif key == curses.KEY_RIGHT or key == curses.KEY_LEFT:
self.has_focus = False
self.update()
self.next_window.display()
def display(self):
self.window.clear()
self.showdetail()
while True:
self.has_focus = True
self.next_window.has_focus = False
self.window.refresh()
curses.doupdate()
self.update()
key = self.window.getch()
if key in [curses.KEY_ENTER, ord('\n')]:
self.action()
return
if key == curses.KEY_UP:
if self.position == 0:
self.navigate(self.last_item_index)
else:
self.navigate(-1)
elif key == curses.KEY_DOWN:
self.navigate(1)
elif key == curses.KEY_RIGHT or key == curses.KEY_LEFT:
self.has_focus = False
self.update()
return
# TODO: scrolling this
def display(self):
self.window.clear()
while True:
self.window.refresh()
curses.doupdate()
for index, item in enumerate(self.items):
if index == self.position:
mode = curses.A_REVERSE
else:
mode = curses.A_NORMAL
msg = '- %s\n (Features: %s, Design: %s)' % (item, item.features, item.design_need)
self.window.addstr(1+index*2, 2, msg, mode)
key = self.window.getch()
if key in [curses.KEY_ENTER, ord('\n')]:
if self.position == len(self.items)-1:
return None
else:
return self.position
if key == curses.KEY_UP:
self.navigate(-1)
elif key == curses.KEY_DOWN:
self.navigate(1)
def keys_init(self):
"""Define methods for each key.
"""
self.keys = {
curses.KEY_BACKSPACE: self.backspace,
CTRL('h'): self.backspace,
curses.ascii.BS: self.backspace,
curses.ascii.DEL: self.backspace,
curses.ascii.ETX: self.close,
curses.KEY_DC: self.del_char,
CTRL('d'): self.del_char,
CTRL('u'): self.del_to_bol,
CTRL('k'): self.del_to_eol,
curses.KEY_DOWN: self.down,
CTRL('n'): self.down,
curses.KEY_END: self.end,
CTRL('e'): self.end,
curses.KEY_F1: self.help,
curses.KEY_HOME: self.home,
CTRL('a'): self.home,
curses.KEY_ENTER: self.insert_line_or_quit,
curses.ascii.NL: self.insert_line_or_quit,
curses.ascii.LF: self.insert_line_or_quit,
"\n": self.insert_line_or_quit,
curses.KEY_LEFT: self.left,
CTRL('b'): self.left,
curses.KEY_NPAGE: self.page_down,
curses.KEY_PPAGE: self.page_up,
CTRL('v'): self.paste,
CTRL('x'): self.quit,
curses.KEY_F2: self.quit,
curses.KEY_F3: self.quit_nosave,
curses.ascii.ESC: self.quit_nosave,
curses.KEY_RESIZE: self.resize,
-1: self.resize,
curses.KEY_RIGHT: self.right,
CTRL('f'): self.right,
curses.KEY_UP: self.up,
CTRL('p'): self.up,
}
def keypress(self, char):
# right arrow select a user/group to chat with
if char == curses.KEY_RIGHT:
self.refresh_body()
self.update_chat()
self.showing = self.selection
current_id = self.slack_client.active[self.showing].id
current_name = self.slack_client.active[self.showing].name
for m in self.slack_client.last_messages(current_id):
self.push_chat(m['user'], m['text'])
return
# moves to the user/group below current selection
elif char == curses.KEY_DOWN:
if self.selection < len(self.slack_client.active) - 1:
self.set_body_selection(self.selection + 1)
self.refresh_body()
return
# move cursor one position up
elif char == curses.KEY_UP:
if self.selection > 0:
self.set_body_selection(self.selection - 1)
self.refresh_body()
return
# send the content on the textbox
elif char == curses.KEY_ENTER or chr(char) == "\n":
# Fixme: send message as 'me', should be username
self.push_chat('me', self.text)
self.send_text()
return
# delete a character
elif chr(char) == self.del_char or chr(char) == "\x7f":
self.backspace()
return
# send the char to textbox area
else:
self.text += chr(char)
self.refresh_textarea(char)
return
# This method is callable for testing porpuses only
def on_key(self, ch):
if not self.items:
return False
if ch == curses.KEY_UP:
if self.selected == 0:
return False
self.selected -= 1
# Selection is outside view, scroll up
if self.selected - self.offset < 0:
self.offset = self.selected
elif ch == curses.KEY_DOWN:
if self.selected == len(self.items) - 1:
return False
self.selected += 1
# Selection is outside view, scroll down
if self.selected - self.offset >= self.h:
self.offset = self.selected - self.h + 1
elif ch == curses.KEY_HOME:
self.selected = 0
self.offset = 0
elif ch == curses.KEY_END:
self.selected = len(self.items) - 1
self.offset = max(0, self.selected - self.h + 1)
elif ch == curses.KEY_ENTER:
key, title, action = self.items[self.selected]
self.select(key)
return True # no update necessary
else:
return False
self.update()
return True
def on_key(self, ch):
if not self.active or self.disabled:
return
if not self.active.on_key(ch):
y, x = self.position(self.active)
if ch == curses.KEY_UP:
if y > 0:
self.set_active(self.rows[y - 1][self.defaults[y - 1]])
elif ch in (curses.KEY_DOWN, curses.KEY_ENTER):
if y < len(self.rows) - 1:
self.set_active(self.rows[y + 1][self.defaults[y + 1]])
elif ch == curses.KEY_LEFT:
if x > 0:
self.set_active(self.rows[y][x - 1])
elif ch == curses.KEY_RIGHT:
if x < len(self.rows[y]) - 1:
self.set_active(self.rows[y][x + 1])
elif ch == curses.ascii.TAB:
# Right
if x < len(self.rows[y]) - 1:
self.set_active(self.rows[y][x + 1])
# Down, ignoring defaults
elif y < len(self.rows) - 1:
self.set_active(self.rows[y + 1][0])
else:
self.set_active(self.rows[0][0])
elif ch == curses.KEY_BTAB:
# Left
if x > 0:
self.set_active(self.rows[y][x - 1])
# Up
elif y > 0:
col = len(self.rows[y - 1]) - 1
self.set_active(self.rows[y - 1][col])
else:
row = len(self.rows) - 1
col = len(self.rows[row]) - 1
self.set_active(self.rows[row][col])
def game_loop(stdscr, columns, rows, num_mines):
game = minesweeper.Game.create_random(columns, rows, num_mines)
Point = namedtuple('Point', ['x', 'y'], verbose=True)
cursor_pos = Point(0, 0)
while True:
stdscr.clear()
game_rect = draw_screen(stdscr, game)
# restrict cursor to the game field
cursor_pos = Point(
clamp(cursor_pos.x, game_rect.x, game_rect.x+game_rect.width-1),
clamp(cursor_pos.y, game_rect.y, game_rect.y+game_rect.height-1)
)
stdscr.move(cursor_pos.y, cursor_pos.x)
stdscr.refresh()
c = stdscr.getch()
if c == curses.KEY_LEFT:
cursor_pos = Point(cursor_pos.x-2, cursor_pos.y)
if c == curses.KEY_RIGHT:
cursor_pos = Point(cursor_pos.x+2, cursor_pos.y)
if c == curses.KEY_UP:
cursor_pos = Point(cursor_pos.x, cursor_pos.y-1)
if c == curses.KEY_DOWN:
cursor_pos = Point(cursor_pos.x, cursor_pos.y+1)
if c == curses.KEY_ENTER or c == 10:
game.toggle_mark(*cursor_to_index(cursor_pos, game_rect))
if c == " " or c == 32:
game.reveal(*cursor_to_index(cursor_pos, game_rect))
if c == 27: # Escape
selected = open_menu(stdscr, ["Continue", "New Game", "Exit"])
if selected == "Exit":
return
elif selected == "New Game":
columns, rows, num_mines = open_difficulty_menu(stdscr)
return game_loop(stdscr, columns, rows, num_mines)
if game.is_lost() or game.is_solved():
# reveal the complete solution
game.reveal_all()
stdscr.clear()
draw_screen(stdscr, game)
# wait for user to press any key
curses.curs_set(False)
c = stdscr.getch()
curses.curs_set(True)
break
def start(self):
self._status = ""
self._active_account = None
self._active_pocket = None
while True:
self._active_account, self._account_names = \
await api.Account.list(self._ws)
if self._active_account is not None:
break
await self._select_account()
self._current_tab = self._account_names.index(self._active_account)
self._current_pocket = 0
while True:
await self.display_main_window()
c = self.screen.getch()
if c == curses.KEY_RIGHT and len(self._account_names) > 1:
self._current_tab += 1
if self._current_tab >= len(self._account_names):
self._current_tab = 0
await self._activate_account()
elif c == curses.KEY_LEFT and len(self._account_names) > 1:
self._current_tab -= 1
if self._current_tab < 0:
self._current_tab = len(self._account_names) - 1
await self._activate_account()
elif c == curses.KEY_DOWN:
self._current_pocket += 1
if self._current_pocket > len(self._pockets) + 1:
self._current_pocket = 0
elif c == curses.KEY_UP:
self._current_pocket -= 1
if self._current_pocket < 0:
self._current_pocket = len(self._pockets) + 1
elif c == curses.KEY_ENTER or c == 10 or c == 13:
if self._current_pocket == len(self._pockets) + 1:
await self._create_pocket()
else:
await self._send_screen()
def _send_screen(self):
ec, self._history = await api.Wallet.history(self._ws,
self._active_pocket)
self._send_fields = ["", "", "", ""]
self._selected_send_item = 0
while True:
await self._display_history()
c = self.screen.getch()
if c == curses.KEY_UP:
self._selected_send_item -= 1
if self._selected_send_item < 0:
self._selected_send_item = 3
elif c == curses.KEY_DOWN:
self._selected_send_item += 1
if self._selected_send_item > 3:
self._selected_send_item = 0
elif c == curses.KEY_ENTER or c == 10 or c == 13:
if self._selected_send_item == 0:
break
_, addr, amount, fee = self._send_fields
try:
decimal.Decimal(amount)
except decimal.InvalidOperation:
self._status = "Invalid amount"
break
try:
decimal.Decimal(fee)
except decimal.InvalidOperation:
self._status = "Invalid fee"
break
addr_type = await api.Daemon.validate_address(self._ws,
addr)
if addr_type == "invalid":
self._status = "Invalid address"
break
dests = [(addr, amount)]
ec, tx_hash = await api.Wallet.send(self._ws, dests, fee=fee,
pocket=self._active_pocket)
if ec:
self._status = ec.name
else:
self._status = "Sent %s" % tx_hash
break
elif c == curses.KEY_BACKSPACE:
self._send_fields[self._selected_send_item] = \
self._send_fields[self._selected_send_item][:-1]
elif c == curses.KEY_LEFT or c == curses.KEY_RIGHT:
pass
else:
self._send_fields[self._selected_send_item] += chr(c)