Add some very basic task list interaction
This commit is contained in:
parent
b524441d9c
commit
902c23eb83
5 changed files with 108 additions and 14 deletions
|
|
@ -1,14 +1,15 @@
|
||||||
{-# LANGUAGE RecordWildCards #-}
|
|
||||||
|
|
||||||
module TaskMachine.UI where
|
module TaskMachine.UI where
|
||||||
|
|
||||||
--import Data.Monoid
|
--import Data.Monoid
|
||||||
--
|
--
|
||||||
import qualified Brick as B
|
import qualified Brick as B
|
||||||
|
import qualified Brick.Focus as B
|
||||||
import qualified Brick.Themes as B
|
import qualified Brick.Themes as B
|
||||||
import qualified Brick.Widgets.List as B
|
import qualified Graphics.Vty.Input.Events as VTY
|
||||||
|
|
||||||
|
import TaskMachine.UI.NewTask
|
||||||
import TaskMachine.UI.TaskList
|
import TaskMachine.UI.TaskList
|
||||||
|
import TaskMachine.UI.TopBar
|
||||||
import TaskMachine.UI.Types
|
import TaskMachine.UI.Types
|
||||||
--import qualified Database.SQLite.Simple as DB
|
--import qualified Database.SQLite.Simple as DB
|
||||||
--import qualified Brick.Themes as B
|
--import qualified Brick.Themes as B
|
||||||
|
|
@ -44,13 +45,33 @@ Edit _____________________________
|
||||||
-- [_] display loaded tasks in UI
|
-- [_] display loaded tasks in UI
|
||||||
|
|
||||||
drawUIState :: UIState -> [B.Widget RName]
|
drawUIState :: UIState -> [B.Widget RName]
|
||||||
drawUIState UIState{..} = [B.renderList (renderLTask taskEdit) True taskList]
|
drawUIState s =
|
||||||
|
let wTopBar = const placeholderTopBar
|
||||||
|
wTaskList = renderTaskList (taskList s) (taskEdit s)
|
||||||
|
wNewTask = const placeholderNewTask
|
||||||
|
in pure $ case B.focusGetCurrent (focus s) of
|
||||||
|
Nothing -> B.vBox [wTopBar False, wTaskList False, wNewTask False] -- should never happen
|
||||||
|
(Just BRTopBar) -> B.vBox [wTopBar True, wTaskList False, wNewTask False]
|
||||||
|
(Just BRTaskList) -> B.vBox [wTopBar False, wTaskList True, wNewTask False]
|
||||||
|
(Just BRNewTask) -> B.vBox [wTopBar False, wTaskList False, wNewTask True ]
|
||||||
|
|
||||||
|
updateUIState :: UIState -> B.BrickEvent RName () -> B.EventM RName (B.Next UIState)
|
||||||
|
updateUIState s e =
|
||||||
|
case B.focusGetCurrent (focus s) of
|
||||||
|
Nothing -> undefined
|
||||||
|
(Just BRTopBar) -> placeholderUpdate s e
|
||||||
|
(Just BRTaskList) -> updateTaskList s e
|
||||||
|
(Just BRNewTask) -> placeholderUpdate s e
|
||||||
|
|
||||||
|
placeholderUpdate :: UIState -> B.BrickEvent RName () -> B.EventM RName (B.Next UIState)
|
||||||
|
placeholderUpdate s (B.VtyEvent (VTY.EvKey VTY.KEsc [])) = B.halt s
|
||||||
|
placeholderUpdate s _ = B.continue s
|
||||||
|
|
||||||
myApp :: B.Theme -> B.App UIState () RName
|
myApp :: B.Theme -> B.App UIState () RName
|
||||||
myApp theme = B.App
|
myApp theme = B.App
|
||||||
{ B.appDraw = drawUIState
|
{ B.appDraw = drawUIState
|
||||||
, B.appChooseCursor = B.neverShowCursor
|
, B.appChooseCursor = B.showFirstCursor
|
||||||
, B.appHandleEvent = B.resizeOrQuit
|
, B.appHandleEvent = updateUIState
|
||||||
, B.appStartEvent = pure
|
, B.appStartEvent = pure
|
||||||
, B.appAttrMap = const attrMap
|
, B.appAttrMap = const attrMap
|
||||||
}
|
}
|
||||||
|
|
|
||||||
8
src/TaskMachine/UI/NewTask.hs
Normal file
8
src/TaskMachine/UI/NewTask.hs
Normal file
|
|
@ -0,0 +1,8 @@
|
||||||
|
module TaskMachine.UI.NewTask where
|
||||||
|
|
||||||
|
import qualified Brick as B
|
||||||
|
|
||||||
|
import TaskMachine.UI.Types
|
||||||
|
|
||||||
|
placeholderNewTask :: B.Widget RName
|
||||||
|
placeholderNewTask = B.str "New: " B.<+> B.vLimit 1 (B.fill '_')
|
||||||
|
|
@ -1,9 +1,12 @@
|
||||||
{-# LANGUAGE OverloadedStrings #-}
|
{-# LANGUAGE OverloadedStrings #-}
|
||||||
|
{-# LANGUAGE RecordWildCards #-}
|
||||||
|
|
||||||
module TaskMachine.UI.TaskList where
|
module TaskMachine.UI.TaskList where
|
||||||
|
|
||||||
import qualified Brick as B
|
import qualified Brick as B
|
||||||
import qualified Brick.Widgets.Edit as B
|
import qualified Brick.Widgets.Edit as B
|
||||||
|
import qualified Brick.Widgets.List as B
|
||||||
|
import qualified Graphics.Vty as VTY
|
||||||
|
|
||||||
import TaskMachine.LTask
|
import TaskMachine.LTask
|
||||||
import TaskMachine.Todotxt
|
import TaskMachine.Todotxt
|
||||||
|
|
@ -31,10 +34,49 @@ renderLTask highlight (LTask _ Task{..}) =
|
||||||
in B.hBox [wCompleted, wPriority, wDescription]
|
in B.hBox [wCompleted, wPriority, wDescription]
|
||||||
-}
|
-}
|
||||||
|
|
||||||
|
--type Editor = B.Editor String RName
|
||||||
|
--type TaskList = B.List RName LTask
|
||||||
|
|
||||||
|
{- Rendering -}
|
||||||
|
|
||||||
renderLTask :: Maybe (B.Editor String RName) -> Bool -> LTask -> B.Widget RName
|
renderLTask :: Maybe (B.Editor String RName) -> Bool -> LTask -> B.Widget RName
|
||||||
renderLTask _ False (LTask _ t) = B.withAttr normal $ B.str $ formatTask t
|
renderLTask _ False (LTask _ t) = B.withAttr "normal" $ B.str $ formatTask t
|
||||||
where normal = "normal" <> "priority"
|
renderLTask Nothing True (LTask _ t) = B.withAttr "highlight" $ B.str $ formatTask t
|
||||||
renderLTask Nothing True (LTask _ t) = B.withAttr highlight $ B.str $ formatTask t
|
renderLTask (Just edit) True _ = B.withAttr "highlight" $ B.renderEditor (B.str . unlines) True edit
|
||||||
where highlight = "highlight" <> "priority"
|
|
||||||
renderLTask (Just edit) True _ = B.withAttr highlight $ B.renderEditor (B.str . unlines) True edit
|
renderTaskList :: B.List RName LTask -> Maybe (B.Editor String RName) -> Bool -> B.Widget RName
|
||||||
where highlight = "highlight" <> "priority"
|
renderTaskList taskList edit focus = B.renderList (renderLTask edit) focus taskList
|
||||||
|
|
||||||
|
{- Updating state -}
|
||||||
|
|
||||||
|
updateTaskList :: UIState -> B.BrickEvent RName () -> B.EventM RName (B.Next UIState)
|
||||||
|
-- Exit application
|
||||||
|
updateTaskList s@UIState{taskEdit=Nothing} (B.VtyEvent (VTY.EvKey VTY.KEsc [])) = B.halt s
|
||||||
|
-- Scroll focus
|
||||||
|
updateTaskList s (B.VtyEvent (VTY.EvKey VTY.KBackTab [])) = B.continue $ bigFocusPrev s
|
||||||
|
updateTaskList s (B.VtyEvent (VTY.EvKey (VTY.KChar '\t') [])) = B.continue $ bigFocusNext s
|
||||||
|
-- Start editing the current task
|
||||||
|
updateTaskList s@UIState{taskEdit=Nothing} (B.VtyEvent (VTY.EvKey (VTY.KChar 'e') [])) =
|
||||||
|
case B.listSelectedElement (taskList s) of
|
||||||
|
Nothing -> B.continue s
|
||||||
|
Just (_, (LTask _ t)) ->
|
||||||
|
let edit = B.editor RTaskEdit (Just 1) ("- editor test -" ++ formatTask t)
|
||||||
|
in B.continue s{taskEdit=Just edit}
|
||||||
|
-- Update the task list
|
||||||
|
updateTaskList s@UIState{taskEdit=Nothing} (B.VtyEvent e) = do
|
||||||
|
newList <- B.handleListEventVi B.handleListEvent e (taskList s)
|
||||||
|
B.continue s{taskList=newList}
|
||||||
|
-- Exit the editor (losing all changes)
|
||||||
|
updateTaskList s@UIState{taskEdit=Just _} (B.VtyEvent (VTY.EvKey VTY.KEsc [])) = B.continue $ s{taskEdit=Nothing}
|
||||||
|
-- Exit the editor (keeping all changes)
|
||||||
|
updateTaskList s@UIState{taskEdit=Just _} (B.VtyEvent (VTY.EvKey VTY.KEnter [])) = do
|
||||||
|
let changeTask (LTask n t) = LTask n t{taskDescription="hehe, changed"}
|
||||||
|
newList = B.listModify changeTask (taskList s)
|
||||||
|
B.continue s{taskList=newList, taskEdit=Nothing}
|
||||||
|
-- Update the editor
|
||||||
|
updateTaskList s@UIState{taskEdit=Just edit} (B.VtyEvent e) = do
|
||||||
|
newEdit <- B.handleEditorEvent e edit
|
||||||
|
B.continue s{taskEdit=Just newEdit}
|
||||||
|
-- Catch everything else
|
||||||
|
updateTaskList s _ = B.halt s
|
||||||
|
--updateTaskList list (Just editor) (B.VtyEvent e) = (,) <$> const list <*> B.handleEditorEvent e editor
|
||||||
|
|
|
||||||
6
src/TaskMachine/UI/TopBar.hs
Normal file
6
src/TaskMachine/UI/TopBar.hs
Normal file
|
|
@ -0,0 +1,6 @@
|
||||||
|
module TaskMachine.UI.TopBar where
|
||||||
|
|
||||||
|
import qualified Brick as B
|
||||||
|
|
||||||
|
placeholderTopBar :: B.Widget n
|
||||||
|
placeholderTopBar = B.str "Prune | Reload | Search: " B.<+> B.vLimit 1 (B.fill '_')
|
||||||
|
|
@ -6,8 +6,12 @@
|
||||||
|
|
||||||
module TaskMachine.UI.Types
|
module TaskMachine.UI.Types
|
||||||
( RName(..)
|
( RName(..)
|
||||||
|
, BigRing(..)
|
||||||
|
, SmallRing(..)
|
||||||
, UIState(..)
|
, UIState(..)
|
||||||
, startUIState
|
, startUIState
|
||||||
|
, bigFocusNext, bigFocusPrev
|
||||||
|
, smallFocusNext, smallFocusPrev
|
||||||
, defaultTheme
|
, defaultTheme
|
||||||
) where
|
) where
|
||||||
|
|
||||||
|
|
@ -24,6 +28,7 @@ import TaskMachine.LTask
|
||||||
data RName
|
data RName
|
||||||
= RSearchEdit
|
= RSearchEdit
|
||||||
| RTaskList
|
| RTaskList
|
||||||
|
| RTaskEdit
|
||||||
| RNewEdit
|
| RNewEdit
|
||||||
deriving (Eq, Show, Ord)
|
deriving (Eq, Show, Ord)
|
||||||
|
|
||||||
|
|
@ -75,6 +80,18 @@ startUIState ltasks = UIState
|
||||||
, newEdit = B.editor RNewEdit (Just 1) ""
|
, newEdit = B.editor RNewEdit (Just 1) ""
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bigFocusNext :: UIState -> UIState
|
||||||
|
bigFocusNext s = s{focus=B.focusNext (focus s)}
|
||||||
|
|
||||||
|
bigFocusPrev :: UIState -> UIState
|
||||||
|
bigFocusPrev s = s{focus=B.focusPrev (focus s)}
|
||||||
|
|
||||||
|
smallFocusNext :: UIState -> UIState
|
||||||
|
smallFocusNext s = s{focusTopBar=B.focusNext (focusTopBar s)}
|
||||||
|
|
||||||
|
smallFocusPrev :: UIState -> UIState
|
||||||
|
smallFocusPrev s = s{focusTopBar=B.focusPrev (focusTopBar s)}
|
||||||
|
|
||||||
defaultTheme :: B.Theme
|
defaultTheme :: B.Theme
|
||||||
defaultTheme = B.newTheme VTY.defAttr
|
defaultTheme = B.newTheme VTY.defAttr
|
||||||
[ ("normal" , none)
|
[ ("normal" , none)
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue