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) =>
35 chan -> board -> IO (VBox, ReactiveFieldReadWrite IO Layer)
36 layerSettings chanRV boardQueue = do
37 layerSettingsVBox <- vBoxNew False 10
38 layerSettingsBox <- hBoxNew True 10
39 boxPackStart layerSettingsVBox layerSettingsBox PackNatural 0
41 layVolumeAdj <- adjustmentNew 100 0 100 1 1 1
42 (layVolumeBox,layVolumeScale) <- mkVScale "Volume" layVolumeAdj
43 boxPackStart layerSettingsBox layVolumeBox PackNatural 0
44 scaleSetDigits layVolumeScale 0
47 layTempoAdj <- adjustmentNew 1 0 2 0.1 0.1 1
48 (layTempoBox, layTempoScale) <- mkVScale "Layer tempo" layTempoAdj
49 boxPackStart layerSettingsBox layTempoBox PackNatural 0
51 strAdj <- adjustmentNew 0.8 0 2 0.1 0.1 0
52 (strBox, layStrengthScale) <- mkVScale "Strength" strAdj
53 boxPackStart layerSettingsBox strBox PackNatural 0
55 bpbBox <- vBoxNew False 10
56 boxPackStart layerSettingsBox bpbBox PackNatural 0
57 bpbLabel <- labelNew (Just "Beat per bar")
58 labelSetLineWrap bpbLabel True
59 boxPackStart bpbBox bpbLabel PackNatural 0
60 bpbAdj <- adjustmentNew 4 1 16 1 1 0
61 bpbButton <- spinButtonNew bpbAdj 1 0
62 boxPackStart bpbBox bpbButton PackNatural 0
64 instrumentCombo <- comboBoxNewText
65 instrumentIndex <- mapM (\(ind,ins) ->
66 do i <- comboBoxAppendText instrumentCombo $
68 return (i, ind)) instrumentList
69 comboBoxSetActive instrumentCombo 0
70 boxPackStart layerSettingsVBox instrumentCombo PackNatural 10
71 let indexToInstr i = fromMaybe (error "Can't get the selected instrument.") $
72 lookup i instrumentIndex
74 fromMaybe (error "Can't retrieve the index for the instrument.") $
75 lookup ins $ map swap instrumentIndex
76 instrumentComboRV = bijection (indexToInstr, instrToIndex) `liftRW`
77 comboBoxIndexRV instrumentCombo
80 ins <- reactiveValueRead instrumentComboRV
81 chan <- reactiveValueRead chanRV
82 reactiveValueAppend boardQueue
83 ([],[Instrument (mkChannel chan) (mkProgram ins)])
85 reactiveValueOnCanRead instrumentComboRV changeInst
87 layPitchRV <- newCBMVarRW 1
88 let layTempoRV = floatConv $ scaleValueReactive layTempoScale
89 strengthRV = floatConv $ scaleValueReactive layStrengthScale
90 bpbRV = spinButtonValueIntReactive bpbButton
91 layVolumeRV = liftRW (bijection (floor, fromIntegral)) $
92 scaleValueReactive layVolumeScale
93 f1 Layer { relTempo = d
99 f2 (d,p,s,bpb,v) = Layer { relTempo = d
105 layerRV = liftRW5 (bijection (f1,f2))
106 layTempoRV layPitchRV strengthRV bpbRV layVolumeRV
108 reactiveValueOnCanRead layVolumeRV $ do
109 vol <- reactiveValueRead layVolumeRV
110 chan <- reactiveValueRead chanRV
111 let vol' = floor ((fromIntegral vol / 100) * 127)
112 reactiveValueAppend boardQueue ([],[Volume (mkChannel chan) vol'])
113 return (layerSettingsVBox, layerRV)