1 {-# LANGUAGE FlexibleContexts, MultiParamTypeClasses, TupleSections #-}
3 module RMCA.GUI.LayerSettings where
6 import Data.ReactiveValue
10 import Graphics.UI.Gtk.Reactive
11 import RMCA.Auxiliary.RV
12 import RMCA.GUI.NoteSettings
13 import RMCA.Layer.Layer
15 import RMCA.Translator.Instruments
16 import RMCA.Translator.Message
18 floatConv :: (ReactiveValueReadWrite a b m,
19 Real c, Real b, Fractional c, Fractional b) =>
20 a -> ReactiveFieldReadWrite m c
21 floatConv = liftRW $ bijection (realToFrac, realToFrac)
23 mkVScale :: String -> Adjustment -> IO (HBox,VScale)
25 hBox <- hBoxNew False 10
26 boxLabel <- labelNew (Just s)
27 labelSetAngle boxLabel 90
28 boxPackStart hBox boxLabel PackNatural 0
29 boxScale <- vScaleNew adj
30 boxPackStart hBox boxScale PackNatural 0
31 return (hBox,boxScale)
33 layerSettings :: ( ReactiveValueReadWrite board ([Note],[Message]) IO
34 , ReactiveValueRead chan Int IO) =>
37 , ReactiveFieldReadWrite IO Layer
38 , ReactiveFieldReadWrite IO Int
40 layerSettings chanRV boardQueue = do
41 layerSettingsVBox <- vBoxNew False 10
42 layerSettingsBox <- hBoxNew True 10
43 boxPackStart layerSettingsVBox layerSettingsBox PackNatural 0
45 layVolumeAdj <- adjustmentNew 100 0 100 1 1 1
46 (layVolumeBox,layVolumeScale) <- mkVScale "Volume" layVolumeAdj
47 boxPackStart layerSettingsBox layVolumeBox PackNatural 0
48 scaleSetDigits layVolumeScale 0
51 layTempoAdj <- adjustmentNew 1 0 2 0.1 0.1 1
52 (layTempoBox, layTempoScale) <- mkVScale "Layer tempo" layTempoAdj
53 boxPackStart layerSettingsBox layTempoBox PackNatural 0
55 strAdj <- adjustmentNew 0.8 0 2 0.1 0.1 0
56 (strBox, layStrengthScale) <- mkVScale "Strength" strAdj
57 boxPackStart layerSettingsBox strBox PackNatural 0
59 bpbBox <- vBoxNew False 10
60 boxPackStart layerSettingsBox bpbBox PackNatural 0
61 bpbLabel <- labelNew (Just "Beat per bar")
62 labelSetLineWrap bpbLabel True
63 boxPackStart bpbBox bpbLabel PackNatural 0
64 bpbAdj <- adjustmentNew 4 1 16 1 1 0
65 bpbButton <- spinButtonNew bpbAdj 1 0
66 boxPackStart bpbBox bpbButton PackNatural 0
68 instrumentCombo <- comboBoxNewText
69 instrumentIndex <- mapM (\(ind,ins) ->
70 do i <- comboBoxAppendText instrumentCombo $
72 return (i, ind)) instrumentList
73 comboBoxSetActive instrumentCombo 0
74 boxPackStart layerSettingsVBox instrumentCombo PackNatural 10
75 let indexToInstr i = fromMaybe (error "Can't get the selected instrument.") $
76 lookup i instrumentIndex
78 fromMaybe (error "Can't retrieve the index for the instrument.") $
79 lookup ins $ map swap instrumentIndex
80 instrumentComboRV = bijection (indexToInstr, instrToIndex) `liftRW`
81 comboBoxIndexRV instrumentCombo
84 ins <- reactiveValueRead instrumentComboRV
85 chan <- reactiveValueRead chanRV
86 reactiveValueAppend boardQueue
87 ([],[Instrument (mkChannel chan) (mkProgram ins)])
89 reactiveValueOnCanRead instrumentComboRV changeInst
91 layPitchRV <- newCBMVarRW 1
92 let layTempoRV = floatConv $ scaleValueReactive layTempoScale
93 strengthRV = floatConv $ scaleValueReactive layStrengthScale
94 bpbRV = spinButtonValueIntReactive bpbButton
95 layVolumeRV = liftRW (bijection (floor, fromIntegral)) $
96 scaleValueReactive layVolumeScale
97 f1 Layer { relTempo = d
103 f2 (d,p,s,bpb,v) = Layer { relTempo = d
109 layerRV = liftRW5 (bijection (f1,f2))
110 layTempoRV layPitchRV strengthRV bpbRV layVolumeRV
112 reactiveValueOnCanRead layVolumeRV $ do
113 vol <- reactiveValueRead layVolumeRV
114 chan <- reactiveValueRead chanRV
115 let vol' = floor ((fromIntegral vol / 100) * 127)
116 reactiveValueAppend boardQueue ([],[Volume (mkChannel chan) vol'])
117 return (layerSettingsVBox, layerRV, instrumentComboRV)