1 {-# LANGUAGE ScopedTypeVariables #-}
5 import Control.Concurrent
6 import Data.ReactiveValue
9 import Graphics.UI.Gtk.Reactive
11 import RMCA.Auxiliary.Concurrent
12 import RMCA.Auxiliary.RV
13 import RMCA.Global.Clock
14 import RMCA.GUI.Buttons
15 import RMCA.Layer.Board
16 import RMCA.Layer.Layer
18 import RMCA.Translator.Jack
19 import RMCA.Translator.Message
20 import RMCA.Translator.Translator
21 import Graphics.UI.Gtk.Layout.BackgroundContainer
23 import Graphics.UI.Gtk.Board.BoardLink
28 floatConv :: (ReactiveValueReadWrite a b m,
29 Real c, Real b, Fractional c, Fractional b) =>
30 a -> ReactiveFieldReadWrite m c
31 floatConv = liftRW $ bijection (realToFrac, realToFrac)
33 boardRVIO = newCBMVarRW $
34 makeBoard [((0,0), mkCell (ChDir True na1 NE)),
35 ((1,1), mkCellRpt (ChDir False na1 NW) 3),
36 ((0,1), mkCell (ChDir False na1 S))]
37 {-makeBoard [((0,0), mkCell (ChDir True na1 N)),
38 ((0,2), mkCellRpt (ChDir False na2 SE) 3),
39 ((2,1), mkCell (ChDir False na1 SW)),
40 ((1,1), mkCellRpt (ChDir False na1 N) 0) {- Skipped! -},
41 ((0,4), mkCellRpt (ChDir True na1 N) (-1)) {- Rpt indef. -},
42 ((0, -6), mkCell (ChDir True na1 N)),
43 ((0, -2), mkCell (ChDir False na3 S) {- Silent -})]-}
48 naOrn = Ornaments Nothing [] NoSlide
54 naOrn = Ornaments Nothing [(10, MIDICVRnd)] SlideUp
60 naOrn = Ornaments Nothing [] NoSlide
67 newTempoRV :: IO (ReactiveFieldReadWrite IO Tempo)
68 newTempoRV = newCBMVarRW 200
76 mainBox <- hBoxNew True 0
77 set window [ windowTitle := "Reactogon"
78 --, windowDefaultWidth := 250
79 --, windowDefaultHeight := 500
80 , containerChild := mainBox
81 , containerBorderWidth := 10
85 settingsBox <- vBoxNew False 0
86 boxPackEnd mainBox settingsBox PackNatural 0
87 globalSettingsBox <- vBoxNew False 10
88 boxPackStart settingsBox globalSettingsBox PackNatural 0
89 tempoAdj <- adjustmentNew 96 0 200 1 1 1
90 tempoLabel <- labelNew (Just "Tempo")
91 boxPackStart globalSettingsBox tempoLabel PackNatural 0
92 tempoScale <- hScaleNew tempoAdj
93 boxPackStart globalSettingsBox tempoScale PackNatural 0
94 scaleSetDigits tempoScale 0
96 bijection (floor, fromIntegral) `liftRW` scaleValueReactive tempoScale
97 globalSep <- hSeparatorNew
98 boxPackStart settingsBox globalSep PackNatural 0
100 layerSettingsBox <- hBoxNew True 10
101 boxPackStart settingsBox layerSettingsBox PackNatural 0
103 layTempoBox <- hBoxNew False 10
104 boxPackStart layerSettingsBox layTempoBox PackNatural 0
105 layTempoLabel <- labelNew (Just "Layer tempo")
106 labelSetAngle layTempoLabel 90
107 boxPackStart layTempoBox layTempoLabel PackNatural 0
108 layTempoScale <- vScaleNewWithRange 0 1 0.01
109 boxPackStart layTempoBox layTempoScale PackNatural 0
110 laySep <- hSeparatorNew
112 strBox <- hBoxNew False 10
113 boxPackStart layerSettingsBox strBox PackNatural 0
114 strLabel <- labelNew (Just "Strength")
115 labelSetAngle strLabel 90
116 boxPackStart strBox strLabel PackNatural 0
117 strAdj <- adjustmentNew 1 0 1 0.01 0.01 0
118 layStrengthScale <- vScaleNew strAdj
119 boxPackStart strBox layStrengthScale PackNatural 0
121 bpbBox <- vBoxNew False 10
122 boxPackStart layerSettingsBox bpbBox PackNatural 0
123 bpbLabel <- labelNew (Just "Beat per bar")
124 labelSetLineWrap bpbLabel True
125 boxPackStart bpbBox bpbLabel PackNatural 0
126 bpbAdj <- adjustmentNew 4 1 16 1 1 0
127 bpbButton <- spinButtonNew bpbAdj 1 0
128 boxPackStart bpbBox bpbButton PackNatural 0
130 boxPackStart settingsBox laySep PackNatural 0
132 layPitchRV <- newCBMVarRW 1
133 let layTempoRV = floatConv $ scaleValueReactive layTempoScale
134 strengthRV = floatConv $ scaleValueReactive layStrengthScale
135 bpbRV = spinButtonValueIntReactive bpbButton
136 f1 Layer { relTempo = d
141 f2 (d,p,s,bpb) = Layer { relTempo = d
147 liftRW4 (bijection (f1,f2)) layTempoRV layPitchRV strengthRV bpbRV
150 buttonBox <- hBoxNew True 10
151 boxPackEnd settingsBox buttonBox PackNatural 0
152 buttonPlay <- buttonNewFromStock gtkMediaPlay
153 boxPackStart buttonBox buttonPlay PackRepel 0
154 buttonPause <- buttonNewFromStock gtkMediaPause
155 boxPackStart buttonBox buttonPause PackRepel 0
156 buttonStop <- buttonNewFromStock gtkMediaStop
157 boxPackStart buttonBox buttonStop PackRepel 0
158 buttonRecord <- buttonNewFromStock gtkMediaRecord
159 boxPackStart buttonBox buttonRecord PackRepel 0
162 boardCont <- backgroundContainerNew
164 board <- attachGameRules game
165 --centerBoard <- alignmentNew 0.5 0.5 0 0
166 containerAdd boardCont board
167 --containerAdd boardCont centerBoard
168 boxPackStart mainBox boardCont PackNatural 0
169 --boxPackStart mainBox boardCont PackNatural 0
170 ------------------------------------------------------------------------------
171 boardQueue <- newCBMVarRW []
173 layer <- reactiveValueRead layerRV
174 tempo <- reactiveValueRead tempoRV
176 board <- reactiveValueRead boardRV
177 (inBoard, outBoard) <- yampaReactiveDual (board, layer, tempo)
178 (boardSF $ startHeads board)
179 let inRV = liftRW2 (bijection (\(x,y,z) -> (x,(y,z)), \(x,(y,z)) -> (x,y,z)))
180 boardRV $ pairRW layerRV tempoRV
181 clock <- mkClockRV 100
184 --reactiveValueOnCanRead outBoard (reactiveValueRead outBoard >>= print . ("Board out " ++) . show)
185 reactiveValueOnCanRead outBoard $ do
186 bq <- reactiveValueRead boardQueue
187 ob <- reactiveValueRead $ liftR (event [] id) outBoard
188 reactiveValueWrite boardQueue (bq ++ ob)
189 -- /!\ To be removed.
190 --reactiveValueOnCanRead outBoard (reactiveValueRead outBoard >>= print)
191 putStrLn "Board started."
193 forkIO $ jackSetup tempoRV (constR 0) boardQueue
195 onDestroy window mainQuit