This repository has been archived on 2024-11-13. You can view files and clone it, but cannot push or open issues or pull requests.
PyKanban/src/tui.py

182 lines
5.6 KiB
Python

from textual.app import App, ComposeResult
from textual.widgets import Static, Label, ListItem, ListView, TextArea, Input
from textual.containers import Horizontal, Vertical
from textual.screen import Screen
from textual.binding import Binding
from board import Board
class TaskList(ListView):
"""
Inherited widget from Listview to use as the kanban board columns
"""
# Keybinds
BINDINGS = [
Binding("k", "cursor_up", "Cursor Up", show=False, priority=True),
Binding("j", "cursor_down", "Cursor Down", show=False, priority=True),
]
class EditScreen(Screen):
"""
This is a screen used to edit the name of a task
"""
CSS="""
Label{
width:50%;
}
Input{
width:50%;
}
"""
BINDINGS = [
Binding('enter', 'save', 'Save Changes', priority=True)
]
def __init__(self,text):
"""
Initialize the screen
"""
super().__init__()
self.text = text
def compose(self):
"""
Compose the widgets on the screen, this screen doesn't need dynamic layout changes
"""
yield Label('Task Name:')
yield Input(value=self.text)
def action_save(self):
query = self.query(selector=Input)
self.dismiss(query.nodes[0].value)
class KanbanForm(App):
CSS_PATH = 'layout.tcss'
BINDINGS = [
Binding("l", "fnext", "Focus Next", show=False, ),
Binding("a", "new_task", "Add New Task", show=False, ),
Binding("h", "fprev", "Focus Prev", show=False, ),
Binding("L", "move_up", "Focus Next", show=False),
Binding("H", "move_down", "Focus Prev", show=False),
Binding("e", "edit_task", "Edit Task", show=False,),
Binding('q', 'exit', "Exit")
]
def compose(self):
"""
Initialization function for form
"""
# Initialize our board class
self.board = Board(file = '.board.md')
self.cols = list()
self.col_widgets = list()
with Horizontal():
for i,col in enumerate(self.board.get_columns()):
if i < len(self.board.get_columns())-1:
col_class = 'column'
else:
col_class = 'last-column'
with Vertical(classes=col_class):
yield Static(col, classes='header')
yield TaskList(
*[ListItem(Label(task)) for task in self.board.get_tasks()[i]])
# Now make all TaskLists except the first have no highlights
def action_fnext(self):
""" Focus next column"""
self.children[0].focus_next()
def action_move_up(self):
icol, itask = self.get_col_task()
text = self.board.get_task(icol, itask)
moved = self.board.move_task(icol, itask, 1)
if moved:
query = self.query(selector=TaskList)
self.focused.highlighted_child.remove()
query.nodes[icol+1].append(ListItem(Label(text)))
self.focused.action_cursor_down()
self.action_fnext()
self.focused.action_cursor_down()
def action_fprev(self):
""" Focus previous column """
self.children[0].focus_previous()
def action_move_down(self):
icol, itask = self.get_col_task()
text = self.board.get_task(icol, itask)
moved = self.board.move_task(icol, itask, -1)
if moved:
query = self.query(selector=TaskList)
self.focused.highlighted_child.remove()
query.nodes[icol-1].append(ListItem(Label(text)))
self.focused.action_cursor_down()
self.action_fprev()
self.focused.action_cursor_down()
def action_edit_task(self):
icol, itask = self.get_col_task()
task = self.board.get_task(icol, itask)
self.push_screen(EditScreen(task), self.update_task)
def action_new_task(self):
self.push_screen(EditScreen(""), self.new_task)
def action_exit(self):
""" Exit the application """
self.board.write_md()
self.exit()
def get_col_task(self):
"""
This function gets the relevant column and task from the Board object for the current
selected item in the tui.
"""
focused_col = self.focused
query = self.query(selector=TaskList)
# First get the column index
for i, child in enumerate(query.nodes):
if focused_col == child:
col_index = i
# Now get the indext of the item in the list
to_move = focused_col.highlighted_child
for i, child in enumerate(focused_col.children):
if to_move == child:
task_index = i
return col_index, task_index
def update_task(self, text):
""" This function gets the text inputted in the edit screen and updates the underlying
task and the board class
"""
icol, itask = self.get_col_task()
self.focused.highlighted_child.children[0].update(text)
self.board.update_task(icol, itask, text)
def new_task(self, text):
""" This function adds a new task to our board
"""
icol,_ = self.get_col_task()
self.focused.mount(ListItem(Label(text)))
self.board.add_task(icol, text)
self.focused.highlighted_child
# def on_key(self):
# with open('log','a') as f:
# f.write("{}".format(self.children[0].focus_next))
if __name__ == "__main__":
kb = KanbanForm()
kb.run()