1 {-# LANGUAGE MultiParamTypeClasses, ScopedTypeVariables #-}
5 import Control.Concurrent
6 import Data.ReactiveValue
9 import Graphics.UI.Gtk.Board.BoardLink
10 import Graphics.UI.Gtk.Layout.BackgroundContainer
11 import Graphics.UI.Gtk.Reactive
13 import RMCA.Auxiliary.RV
15 import RMCA.GUI.Buttons
16 import RMCA.GUI.MainSettings
17 import RMCA.GUI.NoteSettings
18 import RMCA.Layer.Board
19 import RMCA.Layer.Layer
21 import RMCA.Translator.Jack
23 floatConv :: (ReactiveValueReadWrite a b m,
24 Real c, Real b, Fractional c, Fractional b) =>
25 a -> ReactiveFieldReadWrite m c
26 floatConv = liftRW $ bijection (realToFrac, realToFrac)
34 mainBox <- hBoxNew False 10
35 set window [ windowTitle := "Reactogon"
36 --, windowDefaultWidth := 250
37 --, windowDefaultHeight := 500
38 , containerChild := mainBox
39 , containerBorderWidth := 10
43 settingsBox <- vBoxNew False 0
44 boxPackEnd mainBox settingsBox PackNatural 0
45 (globalSettingsBox, tempoRV) <- globalSettings
46 boxPackStart settingsBox globalSettingsBox PackNatural 0
47 globalSep <- hSeparatorNew
48 boxPackStart settingsBox globalSep PackNatural 0
50 layerSettingsBox <- hBoxNew True 10
51 boxPackStart settingsBox layerSettingsBox PackNatural 0
53 layTempoBox <- hBoxNew False 10
54 boxPackStart layerSettingsBox layTempoBox PackNatural 0
55 layTempoLabel <- labelNew (Just "Layer tempo")
56 labelSetAngle layTempoLabel 90
57 boxPackStart layTempoBox layTempoLabel PackNatural 0
58 layTempoAdj <- adjustmentNew 1 0 2 1 1 1
59 layTempoScale <- vScaleNew layTempoAdj
60 boxPackStart layTempoBox layTempoScale PackNatural 0
61 laySep <- hSeparatorNew
63 strBox <- hBoxNew False 10
64 boxPackStart layerSettingsBox strBox PackNatural 0
65 strLabel <- labelNew (Just "Strength")
66 labelSetAngle strLabel 90
67 boxPackStart strBox strLabel PackNatural 0
68 strAdj <- adjustmentNew 1 0 1 0.01 0.01 0
69 layStrengthScale <- vScaleNew strAdj
70 boxPackStart strBox layStrengthScale PackNatural 0
72 bpbBox <- vBoxNew False 10
73 boxPackStart layerSettingsBox bpbBox PackNatural 0
74 bpbLabel <- labelNew (Just "Beat per bar")
75 labelSetLineWrap bpbLabel True
76 boxPackStart bpbBox bpbLabel PackNatural 0
77 bpbAdj <- adjustmentNew 4 1 16 1 1 0
78 bpbButton <- spinButtonNew bpbAdj 1 0
79 boxPackStart bpbBox bpbButton PackNatural 0
81 boxPackStart settingsBox laySep PackNatural 0
83 layPitchRV <- newCBMVarRW 1
84 let layTempoRV = floatConv $ scaleValueReactive layTempoScale
85 strengthRV = floatConv $ scaleValueReactive layStrengthScale
86 bpbRV = spinButtonValueIntReactive bpbButton
87 f1 Layer { relTempo = d
92 f2 (d,p,s,bpb) = Layer { relTempo = d
98 liftRW4 (bijection (f1,f2)) layTempoRV layPitchRV strengthRV bpbRV
100 buttonBox <- hBoxNew True 10
101 boxPackEnd settingsBox buttonBox PackNatural 0
102 buttonPlay <- buttonNewFromStock gtkMediaPlay
103 let playRV = buttonActivateField buttonPlay
104 boxPackStart buttonBox buttonPlay PackRepel 0
105 buttonPause <- buttonNewFromStock gtkMediaPause
106 boxPackStart buttonBox buttonPause PackRepel 0
107 buttonStop <- buttonNewFromStock gtkMediaStop
108 let stopRV = buttonActivateField buttonStop
109 boxPackStart buttonBox buttonStop PackRepel 0
110 buttonRecord <- buttonNewFromStock gtkMediaRecord
111 boxPackStart buttonBox buttonRecord PackRepel 0
114 boardCont <- backgroundContainerNew
116 guiBoard <- attachGameRules game
117 centerBoard <- alignmentNew 0.5 0.5 0 0
118 containerAdd centerBoard guiBoard
119 containerAdd boardCont centerBoard
120 boxPackStart mainBox boardCont PackNatural 0
121 --boxPackStart mainBox boardCont PackNatural 0
122 ------------------------------------------------------------------------------
123 boardQueue <- newCBMVarRW []
125 layer <- reactiveValueRead layerRV
126 tempo <- reactiveValueRead tempoRV
127 (boardRV, pieceArrRV, phRV) <- initBoardRV guiBoard
128 reactiveValueOnCanRead playRV
129 (reactiveValueRead boardRV >>= reactiveValueWrite phRV . startHeads)
130 reactiveValueOnCanRead stopRV $ reactiveValueWrite phRV []
131 board <- reactiveValueRead boardRV
132 ph <- reactiveValueRead phRV
133 (inBoard, outBoard) <- yampaReactiveDual (board, layer, ph, tempo) boardSF
135 boardRV layerRV phRV tempoRV
136 --let inRV = onTick clock inRV
138 reactiveValueOnCanRead outBoard $ do
139 bq <- reactiveValueRead boardQueue
140 ob <- reactiveValueRead $ liftR (event [] id <<< snd <<< splitE) outBoard
141 reactiveValueWrite boardQueue (bq ++ ob)
142 -- This needs to be set last otherwise phRV is written to, so
143 -- inBoard is written to and the notes don't get played. There
144 -- supposedly is no guaranty of order but apparently there is…
145 (fst <$>) <^> outBoard >:> phRV
146 putStrLn "Board started."
148 forkIO $ jackSetup tempoRV (constR 0) boardQueue
150 pieceBox <- clickHandling pieceArrRV guiBoard =<< vBoxNew False 10
151 -- Piece characteristic
152 --pieceBox <- pieceButtons pieceArrRV guiBoard =<< vBoxNew False 10
153 ------------------------------------------------------------
155 boxPackStart settingsBox pieceBox PackNatural 10
156 onDestroy window mainQuit