1 {-# LANGUAGE FlexibleContexts, MultiParamTypeClasses, ScopedTypeVariables,
4 module RMCA.GUI.NoteSettings where
12 import Data.ReactiveValue
15 import Graphics.UI.Gtk hiding (Action)
16 import Graphics.UI.Gtk.Reactive
22 toJust :: a -> Maybe a
25 getSplit :: Action -> Maybe Action
26 getSplit (Split na ds) = Just (Split na ds)
29 setSplitDir :: [Int] -> Action -> Action
30 setSplitDir ds (Split na _) = Split na ds
33 getSplitDir :: Action -> Maybe [Int]
34 getSplitDir (Split _ ds) = Just ds
35 getSplitDir _ = Nothing
37 setNAttr :: NoteAttr -> Action -> Action
38 setNAttr _ Inert = Inert
39 setNAttr _ Absorb = Absorb
40 setNAttr na (Stop _) = Stop na
41 setNAttr na (ChDir b _ dir) = ChDir b na dir
42 setNAttr na (Split _ ds) = Split na ds
44 getNAttr :: Action -> Maybe NoteAttr
45 getNAttr Inert = Nothing
46 getNAttr Absorb = Nothing
47 getNAttr (Stop na) = Just na
48 getNAttr (ChDir _ na _) = Just na
49 getNAttr (Split na _) = Just na
51 symbolString :: [(Duration,String)]
52 symbolString = map (\(_,y,z) -> (z,y)) noteSymbList
54 noteList :: [(String,Duration)]
55 noteList = map (\(x,_,y) -> (x,y)) noteSymbList
57 noteList' :: [(String,Duration)]
58 noteList' = map (\(x,y,z) -> (x ++ " " ++ y,z)) noteSymbList
60 noteSymbList :: [(String, String, Duration)]
61 noteSymbList = sortBy (comparing (\(_,_,x) -> x))
63 , ("♩", "Quarter note", 1 % 4)
64 , ("♪", "Eighth note ", 1 % 8)
65 , ("𝅗𝅥", "Half note", 1 % 2)
66 , ("𝅘𝅥𝅯", "Sixteenth note", 1 % 16)
67 , ("𝅝", "Whole note", 1)
70 comboBoxIndexRV :: (ComboBoxClass box) =>
71 box -> ReactiveFieldReadWrite IO Int
72 comboBoxIndexRV box = ReactiveFieldReadWrite setter getter notifier
73 where getter = comboBoxGetActive box
74 setter = comboBoxSetActive box
75 notifier = void . on box changed
77 noteSettingsBox :: IO (VBox, MCBMVar GUICell)
79 pieceBox <- vBoxNew False 5
80 naBox <- vBoxNew False 5
81 boxPackStart pieceBox naBox PackNatural 0
86 artCombo <- comboBoxNewText
87 artIndex <- mapM (\art -> do i <- comboBoxAppendText artCombo
88 (fromString $ show art)
89 return (art,i)) [NoAccent ..]
90 comboBoxSetActive artCombo 0
91 boxPackStart naBox artCombo PackNatural 0
93 fromMaybe (error "In indexToArt: failed \
94 \to find the selected \
95 \articulation.") $ lookup i $ map swap artIndex
96 artToIndex a = fromMaybe (error "In artToIndex: failed \
97 \to find the correct index \
99 \articulation.") $ lookup a artIndex
100 artComboRV = bijection (indexToArt,artToIndex) `liftRW`
101 comboBoxIndexRV artCombo
104 slideCombo <- comboBoxNewText
105 slideIndex <- mapM (\sli -> do i <- comboBoxAppendText slideCombo
106 (fromString $ show sli)
107 return (sli,i)) [NoSlide ..]
108 comboBoxSetActive slideCombo 0
109 boxPackStart naBox slideCombo PackNatural 0
111 fromMaybe (error "In indexToSlide: failed \
112 \to find the correct slide \
114 \index.") $ lookup i $ map swap slideIndex
116 fromMaybe (error "In slideToIndex: failed \
119 \for the slide.") $ lookup s slideIndex
120 slideComboRV = bijection (indexToSlide,slideToIndex) `liftRW`
121 comboBoxIndexRV slideCombo
124 noteDurBox <- hBoxNew False 10
125 noteDurCombo <- comboBoxNewText
126 noteDurIndex <- mapM (\(str,dur) -> do i <- comboBoxAppendText noteDurCombo
128 return (dur,i)) noteList
129 comboBoxSetActive noteDurCombo 0
131 fromMaybe (error "In indexToDur: failed \
132 \to find the correct \
134 \selected index.") $ lookup i $ map swap noteDurIndex
136 fromMaybe (error "In durToIndex: \
139 \for the duration.") $ lookup d noteDurIndex
140 noteDurRV = bijection (indexToDur, durToIndex) `liftRW`
141 comboBoxIndexRV noteDurCombo
142 noteDurLabel <- labelNew =<< fmap (`lookup` symbolString)
143 (reactiveValueRead noteDurRV)
144 let noteDurLabelRV = labelTextReactive noteDurLabel
145 boxPackStart naBox noteDurBox PackNatural 0
146 boxPackStart noteDurBox noteDurCombo PackNatural 0
147 boxPackStart noteDurBox noteDurLabel PackNatural 0
149 -- Split direction box
150 splitDirBox <- hBoxNew False 10
151 splitDirCombo <- comboBoxNewText
152 splitDirIndex <- mapM (\(str, dir) -> do i <- comboBoxAppendText splitDirCombo
154 return (dir, i)) dirList
155 comboBoxSetActive splitDirCombo 0
157 fromMaybe (error "In indexToDir: failed \
158 \to find the correct \
159 \ direction for the \
160 \selected index.") $ lookup i $ map swap splitDirIndex
162 fromMaybe (error "In dirToIndex: \
165 \for the direction.") $ lookup ds' splitDirIndex where
166 ds' = fst $ fromProto ds
168 splitDirRV = bijection (indexToDir, dirToIndex) `liftRW`
169 comboBoxIndexRV splitDirCombo
170 splitDirLabel <- labelNew =<< return (Just "")
171 let splitDirLabelRV = labelTextReactive splitDirLabel
172 boxPackStart naBox splitDirBox PackNatural 0
173 boxPackStart splitDirBox splitDirCombo PackNatural 0
174 boxPackStart splitDirBox splitDirLabel PackNatural 0
177 rCountAdj <- adjustmentNew 1 0 100 1 1 0
178 rCount <- spinButtonNew rCountAdj 1 0
179 boxPackStart pieceBox rCount PackNatural 0
180 let rCountRV = spinButtonValueIntReactive rCount
183 -- Carries the index of the tile to display and what to display.
184 setRV <- newMCBMVar inertCell
186 reactiveValueOnCanRead splitDirRV $ do
187 cDir <- reactiveValueRead splitDirRV
188 oCell <- reactiveValueRead setRV
190 nCa = cellAction oCell
192 nCell = if isJust $ getSplit nCa
193 then oCell { cellAction =
194 setSplitDir cDir nCa }
196 reactiveValueWriteOnNotEq setRV nCell
199 reactiveValueOnCanRead noteDurRV $ do
200 nDur <- reactiveValueRead noteDurRV
201 oCell <- reactiveValueRead setRV
202 let nCa :: Maybe NoteAttr
203 nCa = fmap (\na -> na { naDur = nDur }) (getNAttr (cellAction oCell))
205 nCell = if isJust nCa
206 then oCell { cellAction =
207 setNAttr (fromJust nCa) (cellAction oCell) }
209 reactiveValueWriteOnNotEq setRV nCell
210 fromMaybeM_ $ fmap (reactiveValueWrite noteDurLabelRV)
211 (lookup nDur symbolString)
214 reactiveValueOnCanRead rCountRV $ do
215 nRCount <- reactiveValueRead rCountRV
216 oCell <- reactiveValueRead setRV
217 let nCell = oCell { repeatCount = nRCount }
218 reactiveValueWrite setRV nCell
220 reactiveValueOnCanRead slideComboRV $ do
221 nSlide <- reactiveValueRead slideComboRV
222 oCell <- reactiveValueRead setRV
223 let nCa :: Maybe NoteAttr
224 nCa = fmap (\na -> na { naOrn = (naOrn na) { ornSlide = nSlide } })
225 (getNAttr (cellAction oCell))
227 nCell = if isJust nCa
228 then oCell { cellAction =
229 setNAttr (fromJust nCa) (cellAction oCell)
232 reactiveValueWrite setRV nCell
234 reactiveValueOnCanRead artComboRV $ do
235 nArt <- reactiveValueRead artComboRV
236 oCell <- reactiveValueRead setRV
237 let nCa :: Maybe NoteAttr
238 nCa = fmap (\na -> na { naArt = nArt }) (getNAttr (cellAction oCell))
240 nCell = if isJust nCa
241 then oCell { cellAction =
242 setNAttr (fromJust nCa) (cellAction oCell) }
244 reactiveValueWrite setRV nCell
247 hideNa = do widgetHide slideCombo
250 widgetHideAll noteDurBox
251 widgetHideAll splitDirBox
253 showNa = do widgetShow slideCombo
256 widgetShowAll noteDurBox
257 widgetHideAll splitDirBox
259 showDir = widgetShowAll splitDirBox
261 updateNaBox :: GUICell -> IO ()
262 updateNaBox GUICell { cellAction = act } = case act of
265 Split _ _ -> showNa >> showDir
268 reactiveValueOnCanRead setRV $ postGUIAsync $ do
269 nCell <- reactiveValueRead setRV
270 fromMaybeM_ (fmap (reactiveValueWriteOnNotEq splitDirRV)
271 (getSplitDir $ cellAction nCell))
272 fromMaybeM_ (fmap (reactiveValueWriteOnNotEq splitDirLabelRV . show . snd . fromProto)
273 (getSplitDir $ cellAction nCell))
274 fromMaybeM_ (fmap (reactiveValueWriteOnNotEq artComboRV . naArt)
275 (getNAttr (cellAction nCell)))
276 fromMaybeM_ (fmap (reactiveValueWriteOnNotEq slideComboRV . ornSlide . naOrn)
277 (getNAttr (cellAction nCell)))
278 reactiveValueWriteOnNotEq rCountRV $ repeatCount nCell
279 fromMaybeM_ (fmap (reactiveValueWriteOnNotEq noteDurRV . naDur)
280 (getNAttr (cellAction nCell)))
285 return (pieceBox,setRV)