feat: add keyboard navigation with Cursor and Input classes

This commit is contained in:
lohhiiccc 2026-07-01 00:37:07 +02:00
parent e53058ecb9
commit d1b65c5c54
5 changed files with 54 additions and 8 deletions

View file

@ -0,0 +1,25 @@
from __future__ import annotations
from typing import TYPE_CHECKING
if TYPE_CHECKING:
from .App import App
class Input:
def __init__(self, app: App) -> None:
self._app = app
def handle(self, key: str) -> bool:
if 'q' == key:
return False
elif key in ('j', 'KEY_DOWN'):
self.app.cursor.down(len(self.app.items))
elif key in ('k', 'KEY_UP'):
self.app.cursor.up()
return True
@property
def app(self) -> App:
return self._app

View file

@ -15,7 +15,7 @@ class UI:
def _get_attr(self, item: any, i: int) -> str: def _get_attr(self, item: any, i: int) -> str:
attr = curses.color_pair(item.color_pair) attr = curses.color_pair(item.color_pair)
if i == self.app.cursor: if i == self.app.cursor.pos:
attr |= curses.A_REVERSE attr |= curses.A_REVERSE
return attr return attr
@ -38,7 +38,7 @@ class UI:
if type(item) is Symlink: if type(item) is Symlink:
attr_arrow = curses.color_pair(0) attr_arrow = curses.color_pair(0)
attr_target = curses.color_pair(Symlink.target_color(item.point_to)) attr_target = curses.color_pair(Symlink.target_color(item.point_to))
if i == self.app.cursor: if i == self.app.cursor.pos:
attr_arrow |= curses.A_REVERSE attr_arrow |= curses.A_REVERSE
attr_target |= curses.A_REVERSE attr_target |= curses.A_REVERSE
stdscr.addstr(i, name_len, self.ARROW, attr_arrow) stdscr.addstr(i, name_len, self.ARROW, attr_arrow)

View file

@ -1,6 +1,8 @@
from .items.Folder import Folder from ..items.Folder import Folder
from pathlib import Path from pathlib import Path
from .IO.UI import UI from ..IO.UI import UI
from ..IO.Input import Input
from .Cursor import Cursor
import curses import curses
@ -16,7 +18,8 @@ class App():
self._current = Folder(path) self._current = Folder(path)
self._items = self.current.children() self._items = self.current.children()
self._UI = UI(self) self._UI = UI(self)
self._cursor = 2 self._input = Input(self)
self._cursor = Cursor()
def _run(self, stdscr: curses.window) -> None: def _run(self, stdscr: curses.window) -> None:
curses.curs_set(0) curses.curs_set(0)
@ -37,7 +40,7 @@ class App():
stdscr.refresh() stdscr.refresh()
key = stdscr.getkey() key = stdscr.getkey()
self._items = self.current.children() self._items = self.current.children()
if 'q' == key: if False == self.input.handle(key):
break break
def run(self) -> None: def run(self) -> None:
@ -60,5 +63,9 @@ class App():
return self._UI return self._UI
@property @property
def cursor(self) -> int: def input(self) -> Input:
return self._input
@property
def cursor(self) -> Cursor:
return self._cursor return self._cursor

14
src/core/Cursor.py Normal file
View file

@ -0,0 +1,14 @@
class Cursor:
def __init__(self) -> None:
self._pos = 0
def up(self) -> None:
self._pos -= 1 if self.pos >= 1 else 0
def down(self, max: int) -> None:
self._pos = min(self.pos + 1, max - 1)
@property
def pos(self) -> int:
return self._pos

View file

@ -1,4 +1,4 @@
from .App import App from .core.App import App
from pathlib import Path from pathlib import Path
import sys import sys