{-# LANGUAGE MultiWayIf #-} {-# LANGUAGE TupleSections #-} {-# LANGUAGE OverloadedStrings #-} module App ( application , mkInitialState ) where import qualified Graphics.Vty as V import qualified Data.Vector as Vec import qualified Data.Map as M import Lens.Micro.Platform import Brick import Brick.BChan (BChan) import Brick.Focus import Brick.Widgets.Edit (editor) import Types import Events import UI import Theme import Tart.Canvas defaultPalette :: Vec.Vector (Maybe V.Color) defaultPalette = Vec.fromList [ Nothing -- default attribute , Just V.white , Just V.brightWhite , Just V.black , Just V.brightBlack , Just V.blue , Just V.brightBlue , Just V.red , Just V.brightRed , Just V.magenta , Just V.brightMagenta , Just V.green , Just V.brightGreen , Just V.cyan , Just V.brightCyan , Just V.yellow , Just V.brightYellow ] initialCanvasSize :: (Int, Int) initialCanvasSize = (40, 17) mkInitialState :: BChan AppEvent -> Maybe (Maybe FilePath, [Canvas], [Int], [String]) -> IO AppState mkInitialState chan mc = do (cs, order, names, fp) <- case mc of Nothing -> do c <- newCanvas initialCanvasSize return ([c], [0], ["default"], Nothing) Just (fp, cs, order, names) -> return (cs, order, names, fp) let sz = canvasSize $ cs !! 0 overlay <- newCanvas sz return $ AppState { _layers = M.fromList $ zip [0..] cs , _layerInfo = M.fromList $ zip [0..] (LayerInfo <$> names <*> pure True) , _layerOrder = order , _drawingOverlay = overlay , _layerListVisible = True , _selectedLayerIndex = head order , _modes = [Main] , _tool = Freehand , _appCanvasSize = sz , _drawCharacter = '*' , _drawFgPaletteIndex = 0 , _drawBgPaletteIndex = 0 , _palette = defaultPalette , _fgPaletteSelectorExtent = Nothing , _bgPaletteSelectorExtent = Nothing , _toolSelectorExtent = Nothing , _boxStyleSelectorExtent = Nothing , _styleSelectorExtent = Nothing , _canvasExtent = Nothing , _dragging = Nothing , _layerNameEditor = editor LayerNameEditor (Just 1) "" , _canvasSizeWidthEdit = editor CanvasSizeWidthEdit (Just 1) "" , _canvasSizeHeightEdit = editor CanvasSizeHeightEdit (Just 1) "" , _canvasSizeFocus = focusRing [ CanvasSizeWidthEdit , CanvasSizeHeightEdit ] , _canvasOffset = Location $ sz & each %~ (`div` 2) , _canvasPath = fp , _canvasDirty = False , _askToSaveFilenameEdit = editor AskToSaveFilenameEdit (Just 1) "" , _saveError = Nothing , _appEventChannel = chan , _textEntered = mempty , _textEntryStart = (0, 0) , _boxStyleIndex = 0 , _eraserSize = 1 , _repaintSize = 1 , _restyleSize = 1 , _undoStack = [] , _redoStack = [] , _drawStyle = noStyle } application :: App AppState AppEvent Name application = App { appDraw = drawUI , appChooseCursor = \s locs -> let isSaving = any isSavingMode isSavingMode (AskForSaveFilename _) = True isSavingMode _ = False in if | CanvasSizePrompt `elem` s^.modes -> do cur <- focusGetCurrent (s^.canvasSizeFocus) showCursorNamed cur locs | isSaving (s^.modes) -> showCursorNamed AskToSaveFilenameEdit locs | TextEntry `elem` s^.modes -> showCursorNamed TextEntryCursor locs | RenameLayer `elem` s^.modes -> showCursorNamed LayerNameEditor locs | otherwise -> Nothing , appHandleEvent = handleEvent , appStartEvent = \s -> do vty <- getVtyHandle V.setMode (V.outputIface vty) V.Mouse True V.setMode (V.outputIface vty) V.BracketedPaste True return s , appAttrMap = const theme }