1 {-# LANGUAGE FlexibleContexts, MultiParamTypeClasses, ScopedTypeVariables,
4 module RMCA.GUI.NoteSettings where
11 import Data.ReactiveValue
14 import Graphics.UI.Gtk hiding (Action)
15 import Graphics.UI.Gtk.Reactive
21 setNAttr :: NoteAttr -> Action -> Action
22 setNAttr _ Inert = Inert
23 setNAttr _ Absorb = Absorb
24 setNAttr na (Stop _) = Stop na
25 setNAttr na (ChDir b _ dir) = ChDir b na dir
26 setNAttr na (Split _) = Split na
28 getNAttr :: Action -> Maybe NoteAttr
29 getNAttr Inert = Nothing
30 getNAttr Absorb = Nothing
31 getNAttr (Stop na) = Just na
32 getNAttr (ChDir _ na _) = Just na
33 getNAttr (Split na) = Just na
35 symbolString :: [(Duration,String)]
36 symbolString = map (\(_,y,z) -> (z,y)) noteSymbList
38 noteList :: [(String,Duration)]
39 noteList = map (\(x,_,y) -> (x,y)) noteSymbList
41 noteList' :: [(String,Duration)]
42 noteList' = map (\(x,y,z) -> (x ++ " " ++ y,z)) noteSymbList
44 noteSymbList :: [(String, String, Duration)]
45 noteSymbList = sortBy (comparing (\(_,_,x) -> x))
46 [ ("♩", "Quarter note", 1 % 4)
47 , ("♪", "Eighth note ", 1 % 8)
48 , ("𝅗𝅥", "Half note", 1 % 2)
49 , ("𝅘𝅥𝅯", "Sixteenth note", 1 % 16)
50 , ("𝅝", "Whole note", 1)
53 comboBoxIndexRV :: (ComboBoxClass box) =>
54 box -> ReactiveFieldReadWrite IO Int
55 comboBoxIndexRV box = ReactiveFieldReadWrite setter getter notifier
56 where getter = comboBoxGetActive box
57 setter = comboBoxSetActive box
58 notifier = void . on box changed
60 noteSettingsBox :: IO (VBox, MCBMVar GUICell)
62 pieceBox <- vBoxNew False 5
63 naBox <- vBoxNew False 5
64 boxPackStart pieceBox naBox PackNatural 0
67 artCombo <- comboBoxNewText
68 artIndex <- mapM (\art -> do i <- comboBoxAppendText artCombo
69 (fromString $ show art)
70 return (art,i)) [NoAccent ..]
71 comboBoxSetActive artCombo 0
72 boxPackStart naBox artCombo PackNatural 0
74 fromMaybe (error "In indexToArt: failed \
75 \to find the selected \
76 \articulation.") $ lookup i $ map swap artIndex
77 artToIndex a = fromMaybe (error "In artToIndex: failed \
78 \to find the correct index \
80 \articulation.") $ lookup a artIndex
81 artComboRV = bijection (indexToArt,artToIndex) `liftRW`
82 comboBoxIndexRV artCombo
85 slideCombo <- comboBoxNewText
86 slideIndex <- mapM (\sli -> do i <- comboBoxAppendText slideCombo
87 (fromString $ show sli)
88 return (sli,i)) [NoSlide ..]
89 comboBoxSetActive slideCombo 0
90 boxPackStart naBox slideCombo PackNatural 0
92 fromMaybe (error "In indexToSlide: failed \
93 \to find the correct slide \
95 \index.") $ lookup i $ map swap slideIndex
97 fromMaybe (error "In slideToIndex: failed \
100 \for the slide.") $ lookup s slideIndex
101 slideComboRV = bijection (indexToSlide,slideToIndex) `liftRW`
102 comboBoxIndexRV slideCombo
105 noteDurBox <- hBoxNew False 10
106 noteDurCombo <- comboBoxNewText
107 noteDurIndex <- mapM (\(str,dur) -> do i <- comboBoxAppendText noteDurCombo
109 return (dur,i)) noteList
110 comboBoxSetActive noteDurCombo 0
112 fromMaybe (error "In indexToDur: failed \
113 \to find the correct \
115 \selected index.") $ lookup i $ map swap noteDurIndex
117 fromMaybe (error "In durToIndex: \
120 \for the duration.") $ lookup d noteDurIndex
121 noteDurRV = bijection (indexToDur, durToIndex) `liftRW`
122 comboBoxIndexRV noteDurCombo
123 noteDurLabel <- labelNew =<< (`lookup` symbolString) <$> reactiveValueRead noteDurRV
124 let noteDurLabelRV = labelTextReactive noteDurLabel
125 boxPackStart naBox noteDurBox PackNatural 0
126 boxPackStart noteDurBox noteDurCombo PackNatural 0
127 boxPackStart noteDurBox noteDurLabel PackNatural 0
130 rCountAdj <- adjustmentNew 1 0 100 1 1 0
131 rCount <- spinButtonNew rCountAdj 1 0
132 boxPackStart pieceBox rCount PackNatural 0
133 let rCountRV = spinButtonValueIntReactive rCount
136 -- Carries the index of the tile to display and what to display.
137 setRV <- newMCBMVar inertCell
139 reactiveValueOnCanRead noteDurRV $ do
140 nDur <- reactiveValueRead noteDurRV
141 oCell <- reactiveValueRead setRV
142 let nCa :: Maybe NoteAttr
143 nCa = (\na -> na { naDur = nDur }) <$> getNAttr (cellAction oCell)
145 nCell = if isJust nCa
146 then oCell { cellAction =
147 setNAttr (fromJust nCa) (cellAction oCell) }
149 reactiveValueWriteOnNotEq setRV nCell
150 fromMaybeM_ $ reactiveValueWrite noteDurLabelRV <$> lookup nDur symbolString
153 reactiveValueOnCanRead rCountRV $ do
154 nRCount <- reactiveValueRead rCountRV
155 oCell <- reactiveValueRead setRV
156 let nCell = oCell { repeatCount = nRCount }
157 reactiveValueWrite setRV nCell
159 reactiveValueOnCanRead slideComboRV $ do
160 nSlide <- reactiveValueRead slideComboRV
161 oCell <- reactiveValueRead setRV
162 let nCa :: Maybe NoteAttr
163 nCa = (\na -> na { naOrn = (naOrn na) { ornSlide = nSlide } }) <$>
164 getNAttr (cellAction oCell)
166 nCell = if isJust nCa
167 then oCell { cellAction =
168 setNAttr (fromJust nCa) (cellAction oCell)
171 reactiveValueWrite setRV nCell
173 reactiveValueOnCanRead artComboRV $ do
174 nArt <- reactiveValueRead artComboRV
175 oCell <- reactiveValueRead setRV
176 let nCa :: Maybe NoteAttr
177 nCa = (\na -> na { naArt = nArt }) <$> getNAttr (cellAction oCell)
179 nCell = if isJust nCa
180 then oCell { cellAction =
181 setNAttr (fromJust nCa) (cellAction oCell) }
183 reactiveValueWrite setRV nCell
186 hideNa = do widgetHide slideCombo
189 widgetHideAll noteDurBox
191 showNa = do widgetShow slideCombo
194 widgetShowAll noteDurBox
195 updateNaBox :: GUICell -> IO ()
196 updateNaBox GUICell { cellAction = act } = case act of
201 reactiveValueOnCanRead setRV $ postGUIAsync $ do
202 nCell <- reactiveValueRead setRV
203 fromMaybeM_ (reactiveValueWriteOnNotEq artComboRV . naArt <$>
204 getNAttr (cellAction nCell))
205 fromMaybeM_ (reactiveValueWriteOnNotEq slideComboRV . ornSlide . naOrn <$>
206 getNAttr (cellAction nCell))
207 reactiveValueWriteOnNotEq rCountRV $ repeatCount nCell
208 fromMaybeM_ (reactiveValueWriteOnNotEq noteDurRV . naDur <$>
209 getNAttr (cellAction nCell))
214 return (pieceBox,setRV)