mirror of
https://github.com/Yvee1/hascard.git
synced 2024-11-22 12:51:58 +03:00
Fully functional (pun not intended) open questions
This commit is contained in:
parent
2e5982b87d
commit
a97109f800
@ -10,6 +10,6 @@ intrinsically photosensitive Retinal Ganglion Cell
|
||||
|
||||
---
|
||||
# Retina
|
||||
Part of the eye that turns light into _electrical neural impulses_.
|
||||
Part of the eye that turns _light_ into _electrical neural impulses_.
|
||||
|
||||
---
|
@ -26,6 +26,7 @@ data CardState =
|
||||
| OpenQuestionState
|
||||
{ _gapInput :: Map Int String
|
||||
, _selectedGap :: Int
|
||||
, _nGaps :: Int
|
||||
}
|
||||
deriving Show
|
||||
|
||||
@ -43,13 +44,13 @@ makeLenses ''State
|
||||
defaultCardState :: Card -> CardState
|
||||
defaultCardState Definition{} = DefinitionState { _flipped = False }
|
||||
defaultCardState (MultipleChoice _ _ ics) = MultipleChoiceState { _selected = 0, _nChoices = length ics + 1, _tried = M.fromList [(i, False) | i <- [0..length ics]]}
|
||||
defaultCardState (OpenQuestion _ perforated) = OpenQuestionState { _gapInput = M.empty, _selectedGap = 0 }
|
||||
defaultCardState (OpenQuestion _ perforated) = OpenQuestionState { _gapInput = M.empty, _selectedGap = 0, _nGaps = nGapsInPerforated perforated }
|
||||
|
||||
|
||||
app :: App State Event Name
|
||||
app = App
|
||||
{ appDraw = drawUI
|
||||
, appChooseCursor = neverShowCursor
|
||||
, appChooseCursor = showFirstCursor
|
||||
, appHandleEvent = handleEvent
|
||||
, appStartEvent = return
|
||||
, appAttrMap = const theMap
|
||||
@ -120,15 +121,14 @@ drawOptions s options = case s ^. cardState of
|
||||
drawPerforated :: State -> Perforated -> Widget Name
|
||||
drawPerforated s p = drawSentence s $ perforatedToSentence p
|
||||
|
||||
perforatedToSentence :: Perforated -> Sentence
|
||||
perforatedToSentence (P pre gap sentence) = Perforated pre gap sentence
|
||||
|
||||
drawSentence :: State -> Sentence -> Widget Name
|
||||
drawSentence = drawSentence' 0
|
||||
drawSentence' i s (Normal text) = str text
|
||||
drawSentence' i s (Perforated pre gap post) = case s ^. cardState of
|
||||
OpenQuestionState {_gapInput = kvs } -> str pre <+> str gap <+> drawSentence' (i+1) s post
|
||||
where gap = M.findWithDefault "default" i kvs
|
||||
OpenQuestionState {_gapInput = kvs, _selectedGap=j } -> str pre <+> cursor (str gap) <+> drawSentence' (i+1) s post
|
||||
where gap = M.findWithDefault "" i kvs
|
||||
cursor :: Widget Name -> Widget Name
|
||||
cursor = if i == j then showCursor () (Location (length gap, 0)) else id
|
||||
_ -> error "impossible"
|
||||
|
||||
drawCardBox :: Widget Name -> Widget Name
|
||||
@ -169,11 +169,23 @@ handleEvent s (VtyEvent ev) = case ev of
|
||||
else continue $ s & cardState.flipped %~ not
|
||||
_ -> continue s
|
||||
|
||||
OpenQuestionState {_selectedGap = i} ->
|
||||
OpenQuestionState {_selectedGap = i, _nGaps = n, _gapInput = kvs} ->
|
||||
case ev of
|
||||
V.EvKey (V.KChar '\t') [] -> continue $
|
||||
if i < n - 1
|
||||
then s & (cardState.selectedGap) +~ 1
|
||||
else s & (cardState.selectedGap) .~ 0
|
||||
V.EvKey (V.KChar c) [] -> continue $
|
||||
s & cardState.gapInput.at i.non "" %~ (++[c]) -- should prob. use snoc list for better efficiency
|
||||
V.EvKey V.KEnter [] -> error (show (s^.cardState))
|
||||
V.EvKey V.KEnter [] -> case s ^. currentCard of
|
||||
OpenQuestion _ perforated -> if correct then next s else continue s
|
||||
where correct :: Bool
|
||||
correct = foldSentenceIndex sent perf sentence
|
||||
sentence = perforatedToSentence perforated
|
||||
sent _ _ = True
|
||||
perf _ gap acc i = acc && gap == M.findWithDefault "" i kvs
|
||||
|
||||
_ -> error "impossible"
|
||||
V.EvKey V.KBS [] -> continue $ s & cardState.gapInput.ix i %~ backspace
|
||||
where backspace "" = ""
|
||||
backspace xs = init xs
|
||||
@ -217,7 +229,7 @@ runCardUI input = do
|
||||
next :: State -> EventM Name (Next State)
|
||||
next s
|
||||
| s ^. index + 1 < length (s ^. cards) = continue . updateState $ s & index +~ 1
|
||||
| otherwise = continue s
|
||||
| otherwise = halt s
|
||||
|
||||
previous :: State -> EventM Name (Next State)
|
||||
previous s | s ^. index > 0 = continue . updateState $ s & index -~ 1
|
||||
|
@ -53,15 +53,22 @@ drawList s = hLimit 11 $
|
||||
L.renderList drawListElement True s
|
||||
|
||||
drawListElement :: Bool -> String -> Widget Name
|
||||
drawListElement selected text = str text
|
||||
drawListElement selected text =
|
||||
hCenter $
|
||||
attr $
|
||||
str text
|
||||
where attr = if selected then withAttr selectedAttr else id
|
||||
|
||||
titleAttr :: AttrName
|
||||
titleAttr = attrName "title"
|
||||
|
||||
selectedAttr :: AttrName
|
||||
selectedAttr = attrName "selected"
|
||||
|
||||
theMap :: AttrMap
|
||||
theMap = attrMap V.defAttr
|
||||
[ (L.listAttr, V.defAttr)
|
||||
, (L.listSelectedAttr, fg V.white `V.withStyle` V.underline)
|
||||
, (selectedAttr, fg V.white `V.withStyle` V.underline)
|
||||
, (titleAttr, fg V.yellow) ]
|
||||
|
||||
handleEvent :: State -> BrickEvent Name Event -> EventM Name (Next State)
|
||||
|
@ -16,9 +16,31 @@ data Answer = Answer Type String
|
||||
data Sentence = Perforated String String Sentence
|
||||
| Normal String
|
||||
deriving Show
|
||||
|
||||
nGapsInSentence :: Sentence -> Int
|
||||
nGapsInSentence = nGapsInSentence' 0
|
||||
nGapsInSentence' acc (Normal s) = acc
|
||||
nGapsInSentence' acc (Perforated pre gap post) = nGapsInSentence' (1+acc) post
|
||||
|
||||
foldSentence :: (String -> a) -> (String -> String -> a -> a) -> Sentence -> a
|
||||
foldSentence norm perf = f where
|
||||
f (Normal text) = norm text
|
||||
f (Perforated pre post sent) = perf pre post (f sent)
|
||||
|
||||
foldSentenceIndex :: (String -> Int -> a) -> (String -> String -> a -> Int -> a) -> Sentence -> a
|
||||
foldSentenceIndex norm perf = f 0 where
|
||||
f i (Normal text) = norm text i
|
||||
f i (Perforated pre post sent) = perf pre post (f (i+1) sent) i
|
||||
|
||||
data Perforated = P String String Sentence
|
||||
deriving Show
|
||||
|
||||
perforatedToSentence :: Perforated -> Sentence
|
||||
perforatedToSentence (P pre gap sentence) = Perforated pre gap sentence
|
||||
|
||||
nGapsInPerforated :: Perforated -> Int
|
||||
nGapsInPerforated = nGapsInSentence . perforatedToSentence
|
||||
|
||||
-- Word Description
|
||||
data Card = Definition String String
|
||||
| OpenQuestion String Perforated
|
||||
|
Loading…
Reference in New Issue
Block a user