module Taskell.UI.Draw.Main.List ( renderList ) where import ClassyPrelude import Control.Lens ((^.)) import Data.Char (chr, ord) import Data.Sequence (mapWithIndex) import Brick import Taskell.Data.List (List, tasks, title) import Taskell.Events.State.Types (current, mode) import Taskell.IO.Config.Layout (columnPadding, columnWidth) import Taskell.Types (ListIndex (ListIndex), TaskIndex (TaskIndex)) import Taskell.UI.Draw.Field (textField, widgetFromMaybe) import Taskell.UI.Draw.Mode import Taskell.UI.Draw.Task (renderTask) import Taskell.UI.Draw.Types (DSWidget, DrawState (..), ReaderDrawState) import Taskell.UI.Theme import Taskell.UI.Types (ResourceName (..)) -- | Gets the relevant column prefix - number in normal mode, letter in moveTo columnPrefix :: Int -> Int -> ReaderDrawState Text columnPrefix selectedList i = do m <- (^. mode) <$> asks dsState if moveTo m then do let col = chr (i + ord 'a') pure $ if i /= selectedList && i >= 0 && i <= 26 then singleton col <> ". " else "" else do let col = i + 1 pure $ if col >= 1 && col <= 9 then tshow col <> ". " else "" -- | Renders the title for a list renderTitle :: Int -> List -> DSWidget renderTitle listIndex list = do (ListIndex selectedList, TaskIndex selectedTask) <- (^. current) <$> asks dsState editing <- (selectedList == listIndex &&) . editingTitle . (^. mode) <$> asks dsState titleField <- getField . (^. mode) <$> asks dsState col <- txt <$> columnPrefix selectedList listIndex let text = list ^. title attr = if selectedList == listIndex then titleCurrentAttr else titleAttr widget = textField text widget' = widgetFromMaybe widget titleField title' = padBottom (Pad 1) . withAttr attr . (col <+>) $ if editing then widget' else widget pure $ if editing || selectedList /= listIndex || selectedTask == 0 then visible title' else title' -- | Renders a list renderList :: Int -> List -> DSWidget renderList listIndex list = do layout <- dsLayout <$> ask eTitle <- editingTitle . (^. mode) <$> asks dsState titleWidget <- renderTitle listIndex list (ListIndex currentList, _) <- (^. current) <$> asks dsState taskWidgets <- sequence $ renderTask (RNTask . (ListIndex listIndex, ) . TaskIndex) listIndex `mapWithIndex` (list ^. tasks) let widget = (if not eTitle then cached (RNList listIndex) else id) . padLeftRight (columnPadding layout) . hLimit (columnWidth layout) . viewport (RNList listIndex) Vertical . vBox . (titleWidget :) $ toList taskWidgets pure $ if currentList == listIndex then visible widget else widget