Add mouse support

This commit is contained in:
Digital Studium 2024-04-25 22:53:13 +03:00
parent d41bc5d8ab
commit 08f6849b62
1 changed files with 40 additions and 0 deletions

40
kls
View File

@ -16,6 +16,8 @@ TOP_API_RESOURCES = ["pods", "services", "configmaps", "secrets", "persistentvol
HELP_TEXT = "Esc: exit filter mode or exit kls, 1: get yaml, 2: describe, 3: edit, 4: pod logs, arrows/TAB: navigation" HELP_TEXT = "Esc: exit filter mode or exit kls, 1: get yaml, 2: describe, 3: edit, 4: pod logs, arrows/TAB: navigation"
MOUSE = True
class Menu: class Menu:
def __init__(self, title: str, rows: list, begin_x: int, width: int): def __init__(self, title: str, rows: list, begin_x: int, width: int):
@ -32,6 +34,8 @@ class Menu:
self.__visible_row_index = lambda: self.filtered_row_index - self.__start_index() # index of the selected visible row self.__visible_row_index = lambda: self.filtered_row_index - self.__start_index() # index of the selected visible row
# selected row from visible rows # selected row from visible rows
self.selected_row = lambda: self.visible_rows()[self.__visible_row_index()] if self.visible_rows() else None self.selected_row = lambda: self.visible_rows()[self.__visible_row_index()] if self.visible_rows() else None
self.width = width
self.begin_x = begin_x
self.win = curses.newwin(curses.LINES - 3, width, 0, begin_x) self.win = curses.newwin(curses.LINES - 3, width, 0, begin_x)
@ -68,6 +72,8 @@ def run_command(key: str):
subprocess.call(command, shell=True) subprocess.call(command, shell=True)
curses.reset_prog_mode() # restore the previous terminal state curses.reset_prog_mode() # restore the previous terminal state
SCREEN.refresh() SCREEN.refresh()
curses.mousemask(curses.REPORT_MOUSE_POSITION) # mouse tracking
print('\033[?1003h') # enable mouse tracking with the XTERM API. That's the magic
def handle_filter_state(key: str, menu: Menu): def handle_filter_state(key: str, menu: Menu):
@ -85,6 +91,35 @@ def handle_filter_state(key: str, menu: Menu):
MENUS[2].filtered_row_index = 0 # reset the selected row index of third menu before redrawing MENUS[2].filtered_row_index = 0 # reset the selected row index of third menu before redrawing
def handle_mouse(mouse_info: tuple, menu: Menu):
row_number = mouse_info[2] - 3
column_number = mouse_info[1]
next_menu = None
if column_number > (menu.begin_x + menu.width):
next_menu = MENUS[(MENUS.index(menu) + 1) % 3]
if column_number > (next_menu.begin_x + next_menu.width):
next_menu = MENUS[(MENUS.index(next_menu) + 1) % 3]
globals().update(SELECTED_MENU=next_menu)
elif column_number < menu.begin_x:
next_menu = MENUS[(MENUS.index(menu) - 1) % 3]
if column_number < next_menu.begin_x:
next_menu = MENUS[(MENUS.index(next_menu) - 1) % 3]
globals().update(SELECTED_MENU=next_menu)
if next_menu:
draw_row(menu.win, menu.title, 1, 2, selected=False) # remove selection from the current menu title
draw_row(next_menu.win, next_menu.title, 1, 2, selected=True) # and select the new menu title
menu = next_menu
char_int = menu.win.inch(mouse_info[2], column_number - menu.begin_x - 1) # get char from current mouse position
char_str = chr(char_int & 0xFF)
if not char_str or ord(char_str) > 127 or ' ' in char_str:
return
if 0 <= row_number < len(menu.visible_rows()):
menu.filtered_row_index = row_number
draw_rows(menu) # this will change selected row in menu
if menu != MENUS[2]:
MENUS[2].filtered_row_index = 0 # reset the selected row index of third menu before redrawing
def catch_input(menu: Menu): def catch_input(menu: Menu):
while True: # refresh third menu until key pressed while True: # refresh third menu until key pressed
try: try:
@ -105,6 +140,9 @@ def catch_input(menu: Menu):
draw_rows(menu) # this will change selected row in menu draw_rows(menu) # this will change selected row in menu
if menu != MENUS[2]: if menu != MENUS[2]:
MENUS[2].filtered_row_index = 0 # reset the selected row index of third menu before redrawing MENUS[2].filtered_row_index = 0 # reset the selected row index of third menu before redrawing
elif key == "KEY_MOUSE" and MOUSE:
mouse_info = curses.getmouse()
handle_mouse(mouse_info, menu)
elif key in KEY_BINDINGS.keys() and MENUS[2].selected_row(): elif key in KEY_BINDINGS.keys() and MENUS[2].selected_row():
run_command(key) run_command(key)
elif key == "\x1b" and not menu.filter: elif key == "\x1b" and not menu.filter:
@ -139,6 +177,8 @@ def main(screen):
curses.curs_set(0) # make the cursor invisible curses.curs_set(0) # make the cursor invisible
curses.use_default_colors() # don't change the terminal color curses.use_default_colors() # don't change the terminal color
curses.noecho() # don't output characters at the top curses.noecho() # don't output characters at the top
curses.mousemask(curses.REPORT_MOUSE_POSITION) # mouse tracking
print('\033[?1003h') # enable mouse tracking with the XTERM API. That's the magic
for menu in MENUS: # draw the main windows for menu in MENUS: # draw the main windows
draw_menu(menu) draw_menu(menu)
draw_row(curses.newwin(3, curses.COLS, curses.LINES - 3, 0), HELP_TEXT, 1, 2) # and the help window draw_row(curses.newwin(3, curses.COLS, curses.LINES - 3, 0), HELP_TEXT, 1, 2) # and the help window