1 {-# LANGUAGE FlexibleContexts, MultiParamTypeClasses #-}
3 module RMCA.GUI.MultiBoard where
6 import Control.Concurrent.MVar
8 import Control.Monad.IO.Class
10 import qualified Data.Map as M
12 import Data.ReactiveValue
13 import Graphics.UI.Gtk
14 import Graphics.UI.Gtk.Board.BoardLink
15 import Graphics.UI.Gtk.Board.TiledBoard hiding (Board)
16 import Graphics.UI.Gtk.Layout.BackgroundContainer
17 import Graphics.UI.Gtk.Reactive.Gtk2
20 import RMCA.Layer.Layer
24 -- In GTk, a “thing with tabs” has the I think very confusing name
27 createNotebook :: ( ReactiveValueRead addLayer () IO
28 , ReactiveValueRead rmLayer () IO
35 , ReactiveFieldReadWrite IO
36 (M.Map Int ( ReactiveFieldRead IO Board
37 , Array Pos (ReactiveFieldWrite IO GUICell)
38 , ReactiveFieldWrite IO [PlayHead])
40 , ReactiveFieldReadWrite IO Int
42 createNotebook addLayerRV rmLayerRV layerMCBMVar guiCellMCBMVar = do
44 let curPageRV = ReactiveFieldReadWrite setter getter notifier
45 (ReactiveFieldRead getter notifier) = notebookGetCurrentPagePassive n
46 (ReactiveFieldWrite setter) = notebookSetCurrentPageReactive n
47 ------------------------------------------------------------------------------
49 ------------------------------------------------------------------------------
51 chanMapRV <- newCBMVarRW M.empty
52 guiCellHidMVar <- newEmptyMVar
53 let clickHandler ioBoard = do
57 postGUIAsync $ void $ tryPutMVar state iPos
60 boardOnRelease ioBoard
63 liftIO $ postGUIAsync $ do
64 mp <- boardGetPiece fPos ioBoard
65 mstate <- tryTakeMVar state
66 when (fPos `elem` validArea && isJust mp) $ do
67 let piece = snd $ fromJust mp
68 when (button == RightButton && maybe False (== fPos) mstate) $
69 boardSetPiece fPos (second rotateGUICell (Player,piece)) ioBoard
70 nmp <- boardGetPiece fPos ioBoard
71 when (button == LeftButton && isJust nmp) $ do
72 let nCell = snd $ fromJust nmp
73 reactiveValueWrite guiCellMCBMVar nCell
74 mOHid <- tryTakeMVar guiCellHidMVar
76 removeCallbackMCBMVar guiCellMCBMVar $ fromJust mOHid
77 nHid <- installCallbackMCBMVar guiCellMCBMVar $ do
78 cp <- reactiveValueRead curPageRV
79 guiVal <- reactiveValueRead guiCellMCBMVar
80 mChanRV <- M.lookup cp <$> reactiveValueRead chanMapRV
81 when (isNothing mChanRV) $ error "Can't get piece array!"
82 let (_,pieceArrRV,_) = fromJust mChanRV
83 reactiveValueWrite (pieceArrRV ! fPos) guiVal
84 putMVar guiCellHidMVar nHid
88 boardCont <- backgroundContainerNew
89 guiBoard <- attachGameRules =<< initGame
91 centerBoard <- alignmentNew 0.5 0.5 0 0
92 containerAdd centerBoard guiBoard
93 containerAdd boardCont centerBoard
95 fstP <- notebookPrependPage n boardCont "Lol first"
96 notebookPageNumber <- newCBMVarRW 1
98 initBoardRV guiBoard >>=
99 \(boardRV, pieceArrRV, phRV) -> reactiveValueRead chanMapRV >>=
100 reactiveValueWrite chanMapRV . M.insert fstP (boardRV,pieceArrRV,phRV)
102 layerMapRV <- newCBMVarRW $ M.insert fstP defaultLayer M.empty
104 let updateLayer cp = do
105 nLayer <- reactiveValueRead layerMCBMVar
106 reactiveValueRead layerMapRV >>=
107 reactiveValueWrite layerMapRV . M.insert cp nLayer
109 layerHidMVar <- newEmptyMVar
111 installCallbackMCBMVar layerMCBMVar
112 (reactiveValueRead curPageRV >>= updateLayer) >>= putMVar layerHidMVar
114 ------------------------------------------------------------------------------
116 ------------------------------------------------------------------------------
118 reactiveValueOnCanRead addLayerRV $ postGUIAsync $ do
119 np <- reactiveValueRead notebookPageNumber
120 unless (np >= 16) $ do
121 reactiveValueWrite notebookPageNumber (np + 1)
122 nBoardCont <- backgroundContainerNew
124 nGuiBoard <- attachGameRules =<< initGame
125 clickHandler nGuiBoard
126 centerBoard <- alignmentNew 0.5 0.5 0 0
127 containerAdd centerBoard nGuiBoard
128 containerAdd nBoardCont centerBoard
130 newP <- notebookAppendPage n boardCont "sdlkfhd"
131 (nBoardRV, nPieceArrRV, nPhRV) <- initBoardRV nGuiBoard
133 reactiveValueRead chanMapRV >>=
134 reactiveValueWrite chanMapRV . M.insert newP (nBoardRV,nPieceArrRV,nPhRV)
136 reactiveValueWrite curPageRV newP
140 reactiveValueOnCanRead rmLayerRV $ postGUIAsync $ do
141 np <- reactiveValueRead notebookPageNumber
143 cp <- notebookGetCurrentPage n
144 notebookRemovePage n cp
146 reactiveValueRead notebookPageNumber >>=
147 reactiveValueWrite notebookPageNumber . subtract 1
149 reactiveValueRead chanMapRV >>=
150 reactiveValueWrite chanMapRV . M.delete cp
151 reactiveValueRead layerMapRV >>=
152 reactiveValueWrite layerMapRV . M.delete cp
157 reactiveValueOnCanRead curPageRV $ do
158 takeMVar layerHidMVar >>= removeCallbackMCBMVar layerMCBMVar
159 cp <- reactiveValueRead curPageRV
160 layerMap <- reactiveValueRead layerMapRV
161 let mSelLayer = M.lookup cp layerMap
162 when (isNothing mSelLayer) $ error "Not found selected layer!"
163 let selLayer = fromJust mSelLayer
164 reactiveValueWrite layerMCBMVar selLayer
165 installCallbackMCBMVar layerMCBMVar (updateLayer cp) >>= putMVar layerHidMVar
168 ------------------------------------------------------------------------------
170 ------------------------------------------------------------------------------
176 ------------------------------------------------------------------------------
178 ------------------------------------------------------------------------------
179 return (n, chanMapRV, curPageRV)