2024-01-10 06:14:59 +00:00
|
|
|
{-# LANGUAGE CPP #-}
|
|
|
|
{-# LANGUAGE DataKinds #-}
|
|
|
|
{-# LANGUAGE FlexibleContexts #-}
|
|
|
|
{-# LANGUAGE OverloadedStrings #-}
|
|
|
|
{-# LANGUAGE TypeApplications #-}
|
|
|
|
{-# LANGUAGE RankNTypes #-}
|
|
|
|
{-# LANGUAGE ViewPatterns #-}
|
|
|
|
{-# OPTIONS_GHC -Wno-unused-record-wildcards #-}
|
|
|
|
{-# OPTIONS_GHC -Wno-unused-matches #-}
|
|
|
|
{-# OPTIONS_GHC -Wno-missing-signatures #-}
|
|
|
|
{-# LANGUAGE FlexibleInstances #-}
|
|
|
|
{-# LANGUAGE MultiParamTypeClasses #-}
|
|
|
|
{-# LANGUAGE TemplateHaskell #-}
|
|
|
|
{-# LANGUAGE BangPatterns #-}
|
|
|
|
{-# LANGUAGE InstanceSigs #-}
|
2024-02-27 18:19:00 +00:00
|
|
|
{-# LANGUAGE PatternSynonyms #-}
|
2024-01-10 06:14:59 +00:00
|
|
|
|
|
|
|
{-
|
|
|
|
This module contains common values used across the library. Crucially it contains two important types for the brick app:
|
|
|
|
|
|
|
|
- Name: List all resources (widgets) used by the app. see https://github.com/jtdaugherty/brick/blob/master/docs/guide.rst#resource-names
|
|
|
|
- Mode: Use to dispatch events and drawings. see: https://github.com/jtdaugherty/brick/issues/476#issuecomment-1629151920
|
|
|
|
|
|
|
|
-}
|
|
|
|
|
2024-02-28 16:01:54 +00:00
|
|
|
module GHCup.Brick.Common (
|
|
|
|
installedSign,
|
|
|
|
setSign,
|
|
|
|
notInstalledSign,
|
|
|
|
showKey,
|
|
|
|
showMod,
|
|
|
|
keyToWidget,
|
|
|
|
separator,
|
|
|
|
frontwardLayer,
|
|
|
|
zoom,
|
|
|
|
defaultAppSettings,
|
|
|
|
lr,
|
|
|
|
showAllVersions,
|
|
|
|
Name(..),
|
|
|
|
Mode(..),
|
|
|
|
BrickData(..),
|
|
|
|
BrickSettings(..),
|
|
|
|
ResourceId (
|
|
|
|
UrlEditBox, SetCheckBox, IsolateEditBox, ForceCheckBox, AdditionalEditBox
|
|
|
|
, TargetGhcEditBox, BootstrapGhcEditBox, JobsEditBox, BuildConfigEditBox
|
|
|
|
, PatchesEditBox, CrossTargetEditBox, AddConfArgsEditBox, OvewrwiteVerEditBox
|
|
|
|
, BuildFlavourEditBox, BuildSystemEditBox, OkButton, AdvanceInstallButton
|
2024-03-04 16:32:22 +00:00
|
|
|
, CompileGHCButton, CompileHLSButton, CabalProjectEditBox
|
|
|
|
, CabalProjectLocalEditBox, UpdateCabalCheckBox
|
2024-02-28 16:01:54 +00:00
|
|
|
) ) where
|
2024-01-10 06:14:59 +00:00
|
|
|
|
|
|
|
import GHCup.List ( ListResult )
|
2024-02-15 07:12:00 +00:00
|
|
|
import GHCup.Types ( Tool, KeyCombination (KeyCombination) )
|
|
|
|
import Data.List (intercalate)
|
2024-01-10 06:14:59 +00:00
|
|
|
import Prelude hiding ( appendFile )
|
|
|
|
import qualified Graphics.Vty as Vty
|
|
|
|
import Optics.TH (makeLenses)
|
|
|
|
import Optics.Lens (toLensVL)
|
|
|
|
import qualified Brick
|
2024-02-15 07:12:00 +00:00
|
|
|
import qualified Brick.Widgets.Border as Border
|
|
|
|
import Brick ((<+>))
|
2024-02-27 18:19:00 +00:00
|
|
|
import qualified Data.Text as T
|
|
|
|
import qualified Brick.Widgets.Center as Brick
|
|
|
|
import qualified Brick.Widgets.Border.Style as Border
|
|
|
|
|
|
|
|
-- We could use regular ADTs but different menus share the same options.
|
|
|
|
-- example: all of ghcup compile ghc, ghcup compile hls, ghcup install cabal, etc...
|
|
|
|
-- all have a --set, --force, etc... common arguments. If we went for the ADT we'd end up
|
|
|
|
-- with SetCompileHLSOption, SetCompileGHCOption, SetInstallCabalOption, etc...
|
|
|
|
-- which isn't terrible, but verbose enough to reject it.
|
|
|
|
|
|
|
|
-- | A newtype for labeling resources in menus. It is bundled along with pattern synonyms
|
|
|
|
newtype ResourceId = ResourceId Int deriving (Eq, Ord, Show)
|
|
|
|
|
2024-02-28 16:01:54 +00:00
|
|
|
pattern OkButton :: ResourceId
|
2024-02-27 18:19:00 +00:00
|
|
|
pattern OkButton = ResourceId 0
|
2024-02-28 16:01:54 +00:00
|
|
|
pattern AdvanceInstallButton :: ResourceId
|
2024-02-27 18:19:00 +00:00
|
|
|
pattern AdvanceInstallButton = ResourceId 100
|
2024-03-04 16:32:22 +00:00
|
|
|
pattern CompileGHCButton :: ResourceId
|
|
|
|
pattern CompileGHCButton = ResourceId 101
|
|
|
|
pattern CompileHLSButton :: ResourceId
|
|
|
|
pattern CompileHLSButton = ResourceId 102
|
2024-01-10 06:14:59 +00:00
|
|
|
|
2024-02-28 16:01:54 +00:00
|
|
|
pattern UrlEditBox :: ResourceId
|
2024-02-28 09:29:39 +00:00
|
|
|
pattern UrlEditBox = ResourceId 1
|
2024-02-28 16:01:54 +00:00
|
|
|
pattern SetCheckBox :: ResourceId
|
2024-02-28 09:29:39 +00:00
|
|
|
pattern SetCheckBox = ResourceId 2
|
2024-02-28 16:01:54 +00:00
|
|
|
pattern IsolateEditBox :: ResourceId
|
2024-02-28 09:29:39 +00:00
|
|
|
pattern IsolateEditBox = ResourceId 3
|
2024-02-28 16:01:54 +00:00
|
|
|
pattern ForceCheckBox :: ResourceId
|
2024-02-28 09:29:39 +00:00
|
|
|
pattern ForceCheckBox = ResourceId 4
|
2024-02-28 16:01:54 +00:00
|
|
|
pattern AdditionalEditBox :: ResourceId
|
2024-02-28 09:29:39 +00:00
|
|
|
pattern AdditionalEditBox = ResourceId 5
|
2024-01-10 06:14:59 +00:00
|
|
|
|
2024-02-28 16:01:54 +00:00
|
|
|
pattern TargetGhcEditBox :: ResourceId
|
|
|
|
pattern TargetGhcEditBox = ResourceId 6
|
|
|
|
pattern BootstrapGhcEditBox :: ResourceId
|
|
|
|
pattern BootstrapGhcEditBox = ResourceId 7
|
|
|
|
pattern JobsEditBox :: ResourceId
|
|
|
|
pattern JobsEditBox = ResourceId 8
|
|
|
|
pattern BuildConfigEditBox :: ResourceId
|
|
|
|
pattern BuildConfigEditBox = ResourceId 9
|
|
|
|
pattern PatchesEditBox :: ResourceId
|
|
|
|
pattern PatchesEditBox = ResourceId 10
|
|
|
|
pattern CrossTargetEditBox :: ResourceId
|
|
|
|
pattern CrossTargetEditBox = ResourceId 11
|
|
|
|
pattern AddConfArgsEditBox :: ResourceId
|
|
|
|
pattern AddConfArgsEditBox = ResourceId 12
|
|
|
|
pattern OvewrwiteVerEditBox :: ResourceId
|
|
|
|
pattern OvewrwiteVerEditBox = ResourceId 13
|
|
|
|
pattern BuildFlavourEditBox :: ResourceId
|
|
|
|
pattern BuildFlavourEditBox = ResourceId 14
|
|
|
|
pattern BuildSystemEditBox :: ResourceId
|
|
|
|
pattern BuildSystemEditBox = ResourceId 15
|
|
|
|
|
2024-03-04 16:32:22 +00:00
|
|
|
pattern CabalProjectEditBox :: ResourceId
|
|
|
|
pattern CabalProjectEditBox = ResourceId 16
|
|
|
|
pattern CabalProjectLocalEditBox :: ResourceId
|
|
|
|
pattern CabalProjectLocalEditBox = ResourceId 17
|
|
|
|
pattern UpdateCabalCheckBox :: ResourceId
|
|
|
|
pattern UpdateCabalCheckBox = ResourceId 18
|
|
|
|
|
|
|
|
|
2024-01-10 06:14:59 +00:00
|
|
|
-- | Name data type. Uniquely identifies each widget in the TUI.
|
|
|
|
-- some constructors might end up unused, but still is a good practise
|
|
|
|
-- to have all of them defined, just in case
|
2024-02-28 09:29:39 +00:00
|
|
|
data Name = AllTools -- ^ The main list widget
|
|
|
|
| Singular Tool -- ^ The particular list for each tool
|
|
|
|
| KeyInfoBox -- ^ The text box widget with action informacion
|
|
|
|
| TutorialBox -- ^ The tutorial widget
|
2024-02-28 16:01:54 +00:00
|
|
|
| ContextBox -- ^ The resource for Context Menu
|
|
|
|
| CompileGHCBox -- ^ The resource for CompileGHC Menu
|
|
|
|
| AdvanceInstallBox -- ^ The resource for AdvanceInstall Menu
|
2024-02-28 09:29:39 +00:00
|
|
|
| MenuElement ResourceId -- ^ Each element in a Menu. Resources must not be share for visible
|
|
|
|
-- Menus, but MenuA and MenuB can share resources if they both are
|
|
|
|
-- invisible, or just one of them is visible.
|
|
|
|
|
2024-01-10 06:14:59 +00:00
|
|
|
deriving (Eq, Ord, Show)
|
|
|
|
|
|
|
|
-- | Mode type. It helps to dispatch events to different handlers.
|
2024-02-28 09:29:39 +00:00
|
|
|
data Mode = Navigation
|
|
|
|
| KeyInfo
|
|
|
|
| Tutorial
|
|
|
|
| ContextPanel
|
|
|
|
| AdvanceInstallPanel
|
2024-02-28 16:01:54 +00:00
|
|
|
| CompileGHCPanel
|
2024-03-04 16:32:22 +00:00
|
|
|
| CompileHLSPanel
|
2024-02-28 09:29:39 +00:00
|
|
|
deriving (Eq, Show, Ord)
|
2024-01-10 06:14:59 +00:00
|
|
|
|
|
|
|
installedSign :: String
|
|
|
|
#if IS_WINDOWS
|
|
|
|
installedSign = "I "
|
|
|
|
#else
|
|
|
|
installedSign = "✓ "
|
|
|
|
#endif
|
|
|
|
|
|
|
|
setSign :: String
|
|
|
|
#if IS_WINDOWS
|
|
|
|
setSign = "IS"
|
|
|
|
#else
|
|
|
|
setSign = "✔✔"
|
|
|
|
#endif
|
|
|
|
|
|
|
|
notInstalledSign :: String
|
|
|
|
#if IS_WINDOWS
|
|
|
|
notInstalledSign = "X "
|
|
|
|
#else
|
|
|
|
notInstalledSign = "✗ "
|
|
|
|
#endif
|
|
|
|
|
2024-02-28 09:29:39 +00:00
|
|
|
|
2024-01-10 06:14:59 +00:00
|
|
|
showKey :: Vty.Key -> String
|
|
|
|
showKey (Vty.KChar c) = [c]
|
|
|
|
showKey Vty.KUp = "↑"
|
|
|
|
showKey Vty.KDown = "↓"
|
|
|
|
showKey key = tail (show key)
|
|
|
|
|
|
|
|
showMod :: Vty.Modifier -> String
|
|
|
|
showMod = tail . show
|
|
|
|
|
2024-02-15 07:12:00 +00:00
|
|
|
-- | Given a KeyComb, produces a string widget with and user friendly text
|
|
|
|
keyToWidget :: KeyCombination -> Brick.Widget n
|
|
|
|
keyToWidget (KeyCombination key mods) = Brick.str $ intercalate "+" (showKey key : (showMod <$> mods))
|
|
|
|
|
|
|
|
-- | A section separator with max width. Looks like this: -------- o --------
|
|
|
|
separator :: Brick.Widget n
|
|
|
|
separator = Border.hBorder <+> Brick.str " o " <+> Border.hBorder
|
2024-01-10 06:14:59 +00:00
|
|
|
|
2024-02-27 18:19:00 +00:00
|
|
|
-- | Used to create a layer on top of the main navigation widget (tutorial, info, menus...)
|
|
|
|
frontwardLayer :: T.Text -> Brick.Widget n -> Brick.Widget n
|
2024-02-28 09:29:39 +00:00
|
|
|
frontwardLayer layer_name =
|
|
|
|
Brick.centerLayer
|
2024-02-27 18:19:00 +00:00
|
|
|
. Brick.hLimitPercent 75
|
|
|
|
. Brick.vLimitPercent 50
|
|
|
|
. Brick.withBorderStyle Border.unicode
|
|
|
|
. Border.borderWithLabel (Brick.txt layer_name)
|
|
|
|
|
2024-01-10 06:14:59 +00:00
|
|
|
-- I refuse to give this a type signature.
|
|
|
|
|
|
|
|
-- | Given a lens, zoom on it. It is needed because Brick uses microlens but GHCup uses optics.
|
|
|
|
zoom l = Brick.zoom (toLensVL l)
|
|
|
|
|
|
|
|
data BrickData = BrickData
|
|
|
|
{ _lr :: [ListResult]
|
|
|
|
}
|
|
|
|
deriving Show
|
|
|
|
|
|
|
|
makeLenses ''BrickData
|
|
|
|
|
|
|
|
data BrickSettings = BrickSettings { _showAllVersions :: Bool}
|
|
|
|
--deriving Show
|
|
|
|
|
|
|
|
makeLenses ''BrickSettings
|
|
|
|
|
|
|
|
defaultAppSettings :: BrickSettings
|
2024-02-28 09:29:39 +00:00
|
|
|
defaultAppSettings = BrickSettings False
|