1 {-# LANGUAGE FlexibleContexts, MultiParamTypeClasses, TupleSections #-}
3 module RMCA.GUI.LayerSettings where
6 import Data.ReactiveValue
10 import Graphics.UI.Gtk.Reactive
12 import RMCA.GUI.NoteSettings
13 import RMCA.Layer.Layer
16 import RMCA.Translator.Instruments
17 import RMCA.Translator.Message
19 floatConv :: (ReactiveValueReadWrite a b m,
20 Real c, Real b, Fractional c, Fractional b) =>
21 a -> ReactiveFieldReadWrite m c
22 floatConv = liftRW $ bijection (realToFrac, realToFrac)
24 mkVScale :: String -> Adjustment -> IO (HBox,VScale)
26 hBox <- hBoxNew False 10
27 boxLabel <- labelNew (Just s)
28 labelSetAngle boxLabel 90
29 boxPackStart hBox boxLabel PackNatural 0
30 boxScale <- vScaleNew adj
31 boxPackStart hBox boxScale PackNatural 0
32 return (hBox,boxScale)
34 layerSettings :: (ReactiveValueReadWrite board ([Note],[Message]) IO) =>
39 layerSettings boardQueue = do
40 ------------------------------------------------------------------------------
42 ------------------------------------------------------------------------------
43 layerSettingsVBox <- vBoxNew False 10
44 layerSettingsBox <- hBoxNew True 10
45 boxPackStart layerSettingsVBox layerSettingsBox PackNatural 0
47 layVolumeAdj <- adjustmentNew 100 0 100 1 1 1
48 (layVolumeBox,layVolumeScale) <- mkVScale "Volume" layVolumeAdj
49 boxPackStart layerSettingsBox layVolumeBox PackNatural 0
50 scaleSetDigits layVolumeScale 0
52 layTempoAdj <- adjustmentNew 1 0 2 0.1 0.1 1
53 (layTempoBox, layTempoScale) <- mkVScale "Layer tempo" layTempoAdj
54 boxPackStart layerSettingsBox layTempoBox PackNatural 0
56 strAdj <- adjustmentNew 0.8 0 2 0.1 0.1 0
57 (strBox, layStrengthScale) <- mkVScale "Strength" strAdj
58 boxPackStart layerSettingsBox strBox PackNatural 0
60 bpbBox <- vBoxNew False 10
61 boxPackStart layerSettingsBox bpbBox PackNatural 0
62 bpbLabel <- labelNew (Just "Beat per bar")
63 labelSetLineWrap bpbLabel True
64 boxPackStart bpbBox bpbLabel PackNatural 0
65 bpbAdj <- adjustmentNew 4 1 16 1 1 0
66 bpbButton <- spinButtonNew bpbAdj 1 0
67 boxPackStart bpbBox bpbButton PackNatural 0
69 instrumentCombo <- comboBoxNewText
70 instrumentIndex <- mapM (\(ind,ins) ->
71 do i <- comboBoxAppendText instrumentCombo $
73 return (i, ind)) instrumentList
74 comboBoxSetActive instrumentCombo 0
75 boxPackStart layerSettingsVBox instrumentCombo PackNatural 10
77 ------------------------------------------------------------------------------
79 ------------------------------------------------------------------------------
80 let indexToInstr i = fromMaybe (error "Can't get the selected instrument.") $
81 lookup i instrumentIndex
83 fromMaybe (error "Can't retrieve the index for the instrument.") $
84 lookup ins $ map swap instrumentIndex
85 instrumentComboRV = bijection (indexToInstr, instrToIndex) `liftRW`
86 comboBoxIndexRV instrumentCombo
89 ins <- reactiveValueRead instrumentComboRV
90 chan <- reactiveValueRead chanRV
91 reactiveValueAppend boardQueue ([],[Instrument (mkChannel chan)
94 reactiveValueOnCanRead instrumentComboRV changeInst
96 layPitchRV <- newCBMVarRW 1
97 let layTempoRV = floatConv $ scaleValueReactive layTempoScale
98 strengthRV = floatConv $ scaleValueReactive layStrengthScale
99 bpbRV = spinButtonValueIntReactive bpbButton
100 layVolumeRV = liftRW (bijection (floor, fromIntegral)) $
101 scaleValueReactive layVolumeScale
102 f1 Layer { relTempo = d
108 f2 (d,p,s,bpb,v) = Layer { relTempo = d
114 layerRV = liftRW5 (bijection (f1,f2))
115 layTempoRV layPitchRV strengthRV bpbRV layVolumeRV
118 layerMMVar <- newMCBMVar =<< reactiveValueRead layerRV
119 reactiveValueOnCanRead layerRV $
120 reactiveValueRead layerRV >>= writeMCBMVar layerMMVar
121 installCallbackMCBMVar layerMMVar $
122 readMCBMVar layerMMVar >>= reactiveValueWrite layerRV
124 instrMMVar <- newMCBMVar =<< reactiveValueRead instrumentComboRV
125 reactiveValueOnCanRead instrumentComboRV $
126 reactiveValueRead instrumentComboRV >>= writeMCBMVar instrMMVar
127 installCallbackMCBMVar instrMMVar $
128 readMCBMVar instrMMVar >>= reactiveValueWrite instrumentComboRV
130 reactiveValueOnCanRead layVolumeRV $ do
131 vol <- reactiveValueRead layVolumeRV
132 chan <- reactiveValueRead chanRV
133 let vol' = floor ((fromIntegral vol / 100) * 127)
134 reactiveValueAppend boardQueue ([],[Volume (mkChannel chan) vol'])
136 return (layerSettingsVBox, layerMMVar, instrMMVar)