147 lines
4.9 KiB
Haskell
147 lines
4.9 KiB
Haskell
module Dodge.Menu.Option where
|
|
|
|
import Dodge.ListDisplayParams
|
|
import Control.Applicative
|
|
import Data.Maybe
|
|
import Dodge.Data.SelectionList
|
|
import Dodge.Data.Universe
|
|
import Dodge.Default.SelectionList
|
|
import Dodge.SelectionList
|
|
import LensHelp
|
|
import Padding
|
|
import Picture.Base
|
|
|
|
initializeOptionMenu :: String -> [MenuOption] -> EscapeMenuOption -> Universe -> ScreenLayer
|
|
initializeOptionMenu title ops pmo u =
|
|
OptionScreen
|
|
{ _scTitle = title
|
|
, _scOptions = ops
|
|
, _scOffset = 0
|
|
, _scPositionedMenuOption = pmo
|
|
, _scOptionFlag = NormalOptions
|
|
, _scSelectionList = makeOptionsSelectionList 10 (Just 0) u ops pmo
|
|
, _scAvailableLines = getAvailableListLines optionListDisplayParams (u ^. uvConfig)
|
|
, _scListDisplayParams = optionListDisplayParams
|
|
, _scDisplayTime = 0
|
|
}
|
|
|
|
-- BO = Bottom Option
|
|
initializeOptionMenuBO :: String -> [MenuOption] -> String -> (Universe -> Universe) -> Universe -> ScreenLayer
|
|
initializeOptionMenuBO title ops str eff = initializeOptionMenu title ops pmo
|
|
where
|
|
pmo = BottomEscapeMenuOption $ (Toggle eff . const . MODString) str
|
|
|
|
refreshOptionsSelectionList :: Universe -> Universe
|
|
refreshOptionsSelectionList u = u & uvScreenLayers . ix 0 %~ f
|
|
where
|
|
f sl = case sl of
|
|
OptionScreen
|
|
{ _scOptions = mops
|
|
, _scPositionedMenuOption = pmo
|
|
, _scAvailableLines = maxlines
|
|
} ->
|
|
sl & scSelectionList . slItems .~ optionsToSelections maxlines u mops pmo
|
|
_ -> sl
|
|
|
|
makeOptionsSelectionList ::
|
|
Int ->
|
|
Maybe Int ->
|
|
Universe ->
|
|
[MenuOption] ->
|
|
EscapeMenuOption ->
|
|
SelectionList (Universe -> Universe, Universe -> Universe)
|
|
makeOptionsSelectionList maxlines mselpos u mos pmo =
|
|
defaultSelectionList
|
|
{ _slItems = optionsToSelections maxlines u mos pmo
|
|
, _slSelPos = mselpos
|
|
}
|
|
|
|
optionsToSelections ::
|
|
Int ->
|
|
Universe ->
|
|
[MenuOption] ->
|
|
EscapeMenuOption ->
|
|
[SelectionItem (Universe -> Universe, Universe -> Universe)]
|
|
optionsToSelections maxlines u allops pmo = case pmo of
|
|
NoEscapeMenuOption -> map (menuOptionToSelectionItem u maxOptionLength) ops
|
|
TopEscapeMenuOption mo -> map (menuOptionToSelectionItem u maxOptionLength) (mo : ops)
|
|
BottomEscapeMenuOption mo -> map (menuOptionToSelectionItem u maxOptionLength) (ops ++ [mo])
|
|
where
|
|
offset = fromMaybe 0 $ u ^? uvScreenLayers . _head . scOffset
|
|
ops
|
|
| maxlines >= length allops = allops
|
|
| otherwise = take (maxlines - 2) (drop offset allops ++ repeat dummyMenuOption) ++ [cycleOptionsOption]
|
|
maxOptionLength = 3 + maximum (0 : map (optionValueOffset u) ops)
|
|
cycleOptionsOption = Toggle cycleOptions
|
|
(const (MODString ("MORE OPTIONS " ++ show n ++ "/" ++ show m)))
|
|
l = length allops
|
|
m = div (l - 1) (max 1 (maxlines - 2)) + 1
|
|
n = div (offset + 1) (max 1 (maxlines - 2)) + 1
|
|
|
|
dummyMenuOption :: MenuOption
|
|
dummyMenuOption = Toggle id (const $ MODBlockedString "")
|
|
|
|
cycleOptions :: Universe -> Universe
|
|
cycleOptions u = fromMaybe u $ do
|
|
screen <- u ^? uvScreenLayers . _head
|
|
maxlines <- screen ^? scAvailableLines
|
|
numoptions <- fmap length $ screen ^? scOptions
|
|
return $ u & uvScreenLayers . _head . scOffset %~ f numoptions (maxlines - 2)
|
|
where
|
|
f n l curoff
|
|
| l + curoff >= n = 0
|
|
| otherwise = l + curoff
|
|
|
|
colStrToSelItem :: (Color, String) -> SelectionItem (Universe -> Universe)
|
|
colStrToSelItem (col, str) =
|
|
SelectionItem
|
|
{ _siPictures = [str]
|
|
, _siHeight = 1
|
|
, _siIsSelectable = True
|
|
, _siColor = col
|
|
, _siOffX = 0
|
|
, _siPayload = id
|
|
}
|
|
|
|
optionValueOffset :: Universe -> MenuOption -> Int
|
|
optionValueOffset u mo = case _moString mo u of
|
|
MODStringOption s _ -> length s
|
|
_ -> 0
|
|
|
|
menuOptionToSelectionItem ::
|
|
Universe ->
|
|
Int ->
|
|
MenuOption ->
|
|
SelectionItem (Universe -> Universe, Universe -> Universe)
|
|
menuOptionToSelectionItem w padAmount mo =
|
|
SelectionItem
|
|
{ _siPictures = [optionText]
|
|
, _siHeight = 1
|
|
, _siIsSelectable = isselectable
|
|
, _siColor = thecol
|
|
, _siOffX = 0
|
|
, _siPayload = (f, g)
|
|
}
|
|
where
|
|
isselectable = case _moString mo w of
|
|
MODBlockedString{} -> False
|
|
_ -> True
|
|
f = fromMaybe id $ mo ^? moEff <|> mo ^? moEff1
|
|
g = fromMaybe id $ mo ^? moEff2
|
|
thecol = case _moString mo w of
|
|
MODBlockedString{} -> greyN 0.5
|
|
_ -> white
|
|
optionText = case _moString mo w of
|
|
MODStringOption s t -> rightPad padAmount '.' s ++ t
|
|
x -> _modString x
|
|
|
|
menuOptionToString :: Universe -> Int -> MenuOption -> (Color, String)
|
|
menuOptionToString w padAmount mo = (thecol, optionText)
|
|
where
|
|
thecol = case _moString mo w of
|
|
MODBlockedString{} -> greyN 0.5
|
|
_ -> white
|
|
optionText = case _moString mo w of
|
|
MODStringOption s t -> rightPad padAmount '.' s ++ t
|
|
x -> _modString x
|