Merge remote-tracking branch 'origin/ui' into iqm
This commit is contained in:
		
							
								
								
									
										45
									
								
								src/Main.hs
									
									
									
									
									
								
							
							
						
						
									
										45
									
								
								src/Main.hs
									
									
									
									
									
								
							| @@ -14,7 +14,7 @@ import           Control.Lens                         ((^.), (.~), (%~)) | |||||||
| -- data consistency/conversion | -- data consistency/conversion | ||||||
| import           Control.Concurrent                   (threadDelay) | import           Control.Concurrent                   (threadDelay) | ||||||
| import           Control.Concurrent.STM               (TQueue, newTQueueIO, atomically) | import           Control.Concurrent.STM               (TQueue, newTQueueIO, atomically) | ||||||
| import           Control.Concurrent.STM.TVar          (newTVarIO, writeTVar, readTVar) | import           Control.Concurrent.STM.TVar          (newTVarIO, writeTVar, readTVar, readTVarIO) | ||||||
|  |  | ||||||
| import           Control.Monad.RWS.Strict             (ask, evalRWST, get, liftIO, modify) | import           Control.Monad.RWS.Strict             (ask, evalRWST, get, liftIO, modify) | ||||||
| import           Data.Functor                         ((<$>)) | import           Data.Functor                         ((<$>)) | ||||||
| @@ -89,7 +89,8 @@ main = do | |||||||
|         initRendering |         initRendering | ||||||
|         --generate map vertices |         --generate map vertices | ||||||
|         curMap <- exportedMap |         curMap <- exportedMap | ||||||
|         glMap' <- initMapShader 4 =<< getMapBufferObject curMap |         (glMap', tex) <- initMapShader 4 =<< getMapBufferObject curMap | ||||||
|  |         tex' <- newTVarIO tex | ||||||
|         eventQueue <- newTQueueIO :: IO (TQueue SDL.Event) |         eventQueue <- newTQueueIO :: IO (TQueue SDL.Event) | ||||||
|         now <- getCurrentTime |         now <- getCurrentTime | ||||||
|         --font <- TTF.openFont "fonts/ttf-04B_03B_/04B_03B_.TTF" 10 |         --font <- TTF.openFont "fonts/ttf-04B_03B_/04B_03B_.TTF" 10 | ||||||
| @@ -111,7 +112,7 @@ main = do | |||||||
|         game' <- newTVarIO GameState |         game' <- newTVarIO GameState | ||||||
|                         { _currentMap          = curMap |                         { _currentMap          = curMap | ||||||
|                         } |                         } | ||||||
|         camStack' <- newTVarIO Map.empty |         let camStack' = Map.empty | ||||||
|         glHud' <- initHud |         glHud' <- initHud | ||||||
|         let zDistClosest'  = 2 |         let zDistClosest'  = 2 | ||||||
|             zDistFarthest' = zDistClosest' + 10 |             zDistFarthest' = zDistClosest' + 10 | ||||||
| @@ -140,18 +141,8 @@ main = do | |||||||
|                         , _tessClockTime       = now |                         , _tessClockTime       = now | ||||||
|                         } |                         } | ||||||
|               , _camera              = cam' |               , _camera              = cam' | ||||||
|  |               , _mapTexture          = tex' | ||||||
|               , _camStack            = camStack' |               , _camStack            = camStack' | ||||||
|               , _mouse               = MouseState |  | ||||||
|                         { _isDragging          = False |  | ||||||
|                         , _dragStartX          = 0 |  | ||||||
|                         , _dragStartY          = 0 |  | ||||||
|                         , _dragStartXAngle     = 0 |  | ||||||
|                         , _dragStartYAngle     = 0 |  | ||||||
|                         , _mousePosition       = Types.Position |  | ||||||
|                                          { Types.__x  = 5 |  | ||||||
|                                          , Types.__y  = 5 |  | ||||||
|                                          } |  | ||||||
|                         } |  | ||||||
|               , _keyboard            = KeyboardState |               , _keyboard            = KeyboardState | ||||||
|                         { _arrowsPressed       = aks |                         { _arrowsPressed       = aks | ||||||
|                         } |                         } | ||||||
| @@ -188,28 +179,6 @@ run = do | |||||||
|     -- update State |     -- update State | ||||||
|  |  | ||||||
|     state <- get |     state <- get | ||||||
|     -- change in camera-angle |  | ||||||
|     when (state ^. mouse.isDragging) $ do |  | ||||||
|           let sodx  = state ^. mouse.dragStartX |  | ||||||
|               sody  = state ^. mouse.dragStartY |  | ||||||
|               sodxa = state ^. mouse.dragStartXAngle |  | ||||||
|               sodya = state ^. mouse.dragStartYAngle |  | ||||||
|               x'    = state ^. mouse.mousePosition._x |  | ||||||
|               y'    = state ^. mouse.mousePosition._y |  | ||||||
|               myrot = (x' - sodx) / 2 |  | ||||||
|               mxrot = (y' - sody) / 2 |  | ||||||
|               newXAngle  = curb (pi/12) (0.45*pi) newXAngle' |  | ||||||
|               newXAngle' = sodxa + mxrot/100 |  | ||||||
|               newYAngle |  | ||||||
|                   | newYAngle' > pi    = newYAngle' - 2 * pi |  | ||||||
|                   | newYAngle' < (-pi) = newYAngle' + 2 * pi |  | ||||||
|                   | otherwise          = newYAngle' |  | ||||||
|               newYAngle' = sodya + myrot/100 |  | ||||||
|  |  | ||||||
|           liftIO $ atomically $ do |  | ||||||
|               cam <- readTVar (state ^. camera) |  | ||||||
|               cam' <- return $ (xAngle .~ newXAngle) . (yAngle .~ newYAngle) $ cam |  | ||||||
|               writeTVar (state ^. camera) cam' |  | ||||||
|  |  | ||||||
|     -- get cursor-keys - if pressed |     -- get cursor-keys - if pressed | ||||||
|     --TODO: Add sin/cos from stateYAngle |     --TODO: Add sin/cos from stateYAngle | ||||||
| @@ -241,7 +210,7 @@ run = do | |||||||
|             targetFrametime = 1.0/targetFramerate |             targetFrametime = 1.0/targetFramerate | ||||||
|         --targetFrametimeμs = targetFrametime * 1000000.0 |         --targetFrametimeμs = targetFrametime * 1000000.0 | ||||||
|         now <- getCurrentTime |         now <- getCurrentTime | ||||||
|         let diff       = diffUTCTime now (state ^. io.clock) -- get time-diffs |         let diff       = max 0.001 $ diffUTCTime now (state ^. io.clock) -- get time-diffs | ||||||
|             updatediff = diffUTCTime now (state ^. io.tessClockTime) -- get diff to last update |             updatediff = diffUTCTime now (state ^. io.tessClockTime) -- get diff to last update | ||||||
|             title      = unwords ["Pioneers @ ",show ((round . double $ 1.0/diff)::Int),"fps"] |             title      = unwords ["Pioneers @ ",show ((round . double $ 1.0/diff)::Int),"fps"] | ||||||
|             ddiff      = double diff |             ddiff      = double diff | ||||||
| @@ -325,8 +294,8 @@ adjustWindow = do | |||||||
|  |  | ||||||
|  |  | ||||||
|                    let hudtexid = state ^. gl.glHud.hudTexture |                    let hudtexid = state ^. gl.glHud.hudTexture | ||||||
|                        maptexid = state ^. gl.glMap.renderedMapTexture |  | ||||||
|                        smaptexid = state ^. gl.glMap.shadowMapTexture |                        smaptexid = state ^. gl.glMap.shadowMapTexture | ||||||
|  |                    maptexid <- liftIO $ readTVarIO (state ^. mapTexture) | ||||||
|                    allocaBytes (fbWidth*fbHeight*4) $ \ptr -> do |                    allocaBytes (fbWidth*fbHeight*4) $ \ptr -> do | ||||||
|                                                                --default to ugly pink to see if |                                                                --default to ugly pink to see if | ||||||
|                                                                --somethings go wrong. |                                                                --somethings go wrong. | ||||||
|   | |||||||
| @@ -62,7 +62,7 @@ initBuffer varray = | |||||||
| initMapShader :: | initMapShader :: | ||||||
|                 Int                                -- ^ initial Tessallation-Factor |                 Int                                -- ^ initial Tessallation-Factor | ||||||
|                 -> (BufferObject,NumArrayIndices)  -- ^ Buffer with Data and DataDescriptor |                 -> (BufferObject,NumArrayIndices)  -- ^ Buffer with Data and DataDescriptor | ||||||
|                 -> IO GLMapState |                 -> IO (GLMapState, TextureObject) | ||||||
| initMapShader tessFac (buf, vertDes) = do | initMapShader tessFac (buf, vertDes) = do | ||||||
|    ! vertexSource <- B.readFile mapVertexShaderFile |    ! vertexSource <- B.readFile mapVertexShaderFile | ||||||
|    ! tessControlSource <- B.readFile mapTessControlShaderFile |    ! tessControlSource <- B.readFile mapTessControlShaderFile | ||||||
| @@ -210,11 +210,10 @@ initMapShader tessFac (buf, vertDes) = do | |||||||
|             , shdrMOTessOuterIndex = UniformLocation 0 --tessLevelOuter' |             , shdrMOTessOuterIndex = UniformLocation 0 --tessLevelOuter' | ||||||
|             } |             } | ||||||
|  |  | ||||||
|    return GLMapState |    return (GLMapState | ||||||
|         { _mapProgram         = program |         { _mapProgram         = program | ||||||
|         , _mapShaderData      = sdata |         , _mapShaderData      = sdata | ||||||
|         , _mapObjectShaderData = smodata |         , _mapObjectShaderData = smodata | ||||||
|         , _renderedMapTexture = tex |  | ||||||
|         , _stateTessellationFactor = tessFac |         , _stateTessellationFactor = tessFac | ||||||
|         , _stateMap           = buf |         , _stateMap           = buf | ||||||
|         , _mapVert            = vertDes |         , _mapVert            = vertDes | ||||||
| @@ -224,7 +223,7 @@ initMapShader tessFac (buf, vertDes) = do | |||||||
|         , _mapObjects         = objs |         , _mapObjects         = objs | ||||||
|         , _objectProgram      = objProgram |         , _objectProgram      = objProgram | ||||||
|         , _shadowMapProgram   = shadowProgram |         , _shadowMapProgram   = shadowProgram | ||||||
|         } |         }, tex) | ||||||
|  |  | ||||||
| initHud :: IO GLHud | initHud :: IO GLHud | ||||||
| initHud = do | initHud = do | ||||||
| @@ -445,12 +444,13 @@ render = do | |||||||
|  |  | ||||||
|         ---- RENDER MAP IN TEXTURE <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< |         ---- RENDER MAP IN TEXTURE <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< | ||||||
|         -- COLORMAP |         -- COLORMAP | ||||||
|         textureBinding Texture2D $= Just (state ^. gl.glMap.renderedMapTexture) |         tex <- liftIO $ readTVarIO (state ^. mapTexture) | ||||||
|  |         textureBinding Texture2D $= Just tex | ||||||
|         framebufferTexture2D |         framebufferTexture2D | ||||||
|                 Framebuffer |                 Framebuffer | ||||||
|                 (ColorAttachment 0) |                 (ColorAttachment 0) | ||||||
|                 Texture2D |                 Texture2D | ||||||
|                 (state ^. gl.glMap.renderedMapTexture) |                 tex | ||||||
|                 0 |                 0 | ||||||
|  |  | ||||||
|         -- Render to FrameBufferObject |         -- Render to FrameBufferObject | ||||||
| @@ -503,7 +503,8 @@ render = do | |||||||
|         uniform (hud ^. hudTexIndex) $= Index1 (0::GLint) |         uniform (hud ^. hudTexIndex) $= Index1 (0::GLint) | ||||||
|  |  | ||||||
|         activeTexture  $= TextureUnit 1 |         activeTexture  $= TextureUnit 1 | ||||||
|         textureBinding Texture2D $= Just (state ^. gl.glMap.renderedMapTexture) |         tex <- liftIO $ readTVarIO (state ^. mapTexture) | ||||||
|  |         textureBinding Texture2D $= Just tex | ||||||
|         uniform (hud ^. hudBackIndex) $= Index1 (1::GLint) |         uniform (hud ^. hudBackIndex) $= Index1 (1::GLint) | ||||||
|  |  | ||||||
|         bindBuffer ArrayBuffer $= Just (hud ^. hudVBO) |         bindBuffer ArrayBuffer $= Just (hud ^. hudVBO) | ||||||
|   | |||||||
							
								
								
									
										21
									
								
								src/Types.hs
									
									
									
									
									
								
							
							
						
						
									
										21
									
								
								src/Types.hs
									
									
									
									
									
								
							| @@ -11,7 +11,7 @@ import Linear.Matrix (M44) | |||||||
| import Linear (V3) | import Linear (V3) | ||||||
| import Control.Monad.RWS.Strict (RWST, liftIO, get) | import Control.Monad.RWS.Strict (RWST, liftIO, get) | ||||||
| import Control.Monad.Writer.Strict | import Control.Monad.Writer.Strict | ||||||
| import Control.Monad (when) | --import Control.Monad (when) | ||||||
| import Control.Lens | import Control.Lens | ||||||
| import Graphics.Rendering.OpenGL.GL.Texturing.Objects (TextureObject) | import Graphics.Rendering.OpenGL.GL.Texturing.Objects (TextureObject) | ||||||
| import Render.Types | import Render.Types | ||||||
| @@ -64,15 +64,6 @@ data GameState = GameState | |||||||
|     { _currentMap          :: !PlayMap |     { _currentMap          :: !PlayMap | ||||||
|     } |     } | ||||||
|  |  | ||||||
| data MouseState = MouseState |  | ||||||
|     { _isDragging          :: !Bool |  | ||||||
|     , _dragStartX          :: !Double |  | ||||||
|     , _dragStartY          :: !Double |  | ||||||
|     , _dragStartXAngle     :: !Double |  | ||||||
|     , _dragStartYAngle     :: !Double |  | ||||||
|     , _mousePosition       :: !Position --TODO: Get rid of mouse-prefix |  | ||||||
|     } |  | ||||||
|  |  | ||||||
| data ArrowKeyState = ArrowKeyState { | data ArrowKeyState = ArrowKeyState { | ||||||
|          _up      :: !Bool |          _up      :: !Bool | ||||||
|         ,_down    :: !Bool |         ,_down    :: !Bool | ||||||
| @@ -111,7 +102,6 @@ data GLMapState = GLMapState | |||||||
|     , _stateMap             :: !GL.BufferObject |     , _stateMap             :: !GL.BufferObject | ||||||
|     , _mapVert              :: !GL.NumArrayIndices |     , _mapVert              :: !GL.NumArrayIndices | ||||||
|     , _mapProgram           :: !GL.Program |     , _mapProgram           :: !GL.Program | ||||||
|     , _renderedMapTexture   :: !TextureObject --TODO: Probably move to UI? |  | ||||||
|     , _overviewTexture      :: !TextureObject |     , _overviewTexture      :: !TextureObject | ||||||
|     , _shadowMapTexture     :: !TextureObject |     , _shadowMapTexture     :: !TextureObject | ||||||
|     , _mapTextures          :: ![TextureObject] --TODO: Fix size on list? |     , _mapTextures          :: ![TextureObject] --TODO: Fix size on list? | ||||||
| @@ -174,8 +164,8 @@ data GLState = GLState | |||||||
|  |  | ||||||
| data UIState = UIState | data UIState = UIState | ||||||
|     { _uiHasChanged        :: !Bool |     { _uiHasChanged        :: !Bool | ||||||
|     , _uiMap               :: !(Map.HashMap UIId (GUIWidget Pioneers)) |     , _uiMap               :: Map.HashMap UIId (GUIWidget Pioneers) | ||||||
|     , _uiObserverEvents    :: !(Map.HashMap EventKey [EventHandler Pioneers]) |     , _uiObserverEvents    :: Map.HashMap EventKey [EventHandler Pioneers] | ||||||
|     , _uiRoots             :: !([UIId]) |     , _uiRoots             :: !([UIId]) | ||||||
|     , _uiButtonState       :: !UIButtonState |     , _uiButtonState       :: !UIButtonState | ||||||
|     } |     } | ||||||
| @@ -183,9 +173,9 @@ data UIState = UIState | |||||||
| data State = State | data State = State | ||||||
|     { _window              :: !WindowState |     { _window              :: !WindowState | ||||||
|     , _camera              :: TVar CameraState |     , _camera              :: TVar CameraState | ||||||
|     , _camStack            :: TVar (Map.HashMap UIId (CameraState, TextureObject)) |     , _mapTexture          :: TVar TextureObject | ||||||
|  |     , _camStack            :: (Map.HashMap UIId (TVar CameraState, TVar TextureObject)) | ||||||
|     , _io                  :: !IOState |     , _io                  :: !IOState | ||||||
|     , _mouse               :: !MouseState |  | ||||||
|     , _keyboard            :: !KeyboardState |     , _keyboard            :: !KeyboardState | ||||||
|     , _gl                  :: !GLState |     , _gl                  :: !GLState | ||||||
|     , _game                :: TVar GameState |     , _game                :: TVar GameState | ||||||
| @@ -208,7 +198,6 @@ $(makeLenses ''GLMapState) | |||||||
| $(makeLenses ''GLHud) | $(makeLenses ''GLHud) | ||||||
| $(makeLenses ''KeyboardState) | $(makeLenses ''KeyboardState) | ||||||
| $(makeLenses ''ArrowKeyState) | $(makeLenses ''ArrowKeyState) | ||||||
| $(makeLenses ''MouseState) |  | ||||||
| $(makeLenses ''GameState) | $(makeLenses ''GameState) | ||||||
| $(makeLenses ''IOState) | $(makeLenses ''IOState) | ||||||
| $(makeLenses ''CameraState) | $(makeLenses ''CameraState) | ||||||
|   | |||||||
| @@ -26,11 +26,12 @@ import UI.UIOperations | |||||||
| createGUI :: ScreenUnit -> ScreenUnit -> UIState | createGUI :: ScreenUnit -> ScreenUnit -> UIState | ||||||
| createGUI w h = UIState | createGUI w h = UIState | ||||||
|     { _uiHasChanged     = True |     { _uiHasChanged     = True | ||||||
|     , _uiMap            = Map.fromList [ (UIId 0, createViewport LeftButton (0, 0, w, h) [UIId 1, UIId 2] 0) -- TODO: automatic resize |     , _uiMap            = Map.fromList [ (UIId 0, createViewport (camera) LeftButton (0, 0, w, h) [UIId 1, UIId 2, UIId 5] 0) -- TODO: automatic resize | ||||||
|                                        , (UIId 1, createContainer (30, 215, 100, 80) [] 1) |                                        , (UIId 1, createContainer (30, 415, 100, 80) [] 1) | ||||||
|                                        , (UIId 2, createPanel (50, 40, 0, 0) [UIId 3, UIId 4] 3) |                                        , (UIId 2, createPanel (50, 240, 0, 0) [UIId 3, UIId 4] 3) | ||||||
|                                        , (UIId 3, createContainer (80, 15, 130, 90) [] 4 ) |                                        , (UIId 3, createContainer (80, 15, 130, 90) [] 4 ) | ||||||
|                                        , (UIId 4, createButton (10, 40, 60, 130) 2 testMessage) |                                        , (UIId 4, createButton (10, 40, 60, 130) 2 testMessage) | ||||||
|  |                                        , (UIId 5, createViewport (camera) LeftButton (10, 10, 300, 200) [] 5) -- TODO: wrong camera | ||||||
|                                        ] |                                        ] | ||||||
|     , _uiObserverEvents = Map.fromList [(WindowEvent, [resizeToScreenHandler (UIId 0)])] |     , _uiObserverEvents = Map.fromList [(WindowEvent, [resizeToScreenHandler (UIId 0)])] | ||||||
|     , _uiRoots          = [UIId 0] |     , _uiRoots          = [UIId 0] | ||||||
| @@ -311,6 +312,10 @@ copyGUI tex (vX, vY) widget = do | |||||||
|                                         (GL.TexturePosition2D (int (vX + xoff)) (int (vY + yoff))) |                                         (GL.TexturePosition2D (int (vX + xoff)) (int (vY + yoff))) | ||||||
|                                         (GL.TextureSize2D (int wWidth) (int wHeight)) |                                         (GL.TextureSize2D (int wWidth) (int wHeight)) | ||||||
|                                         (GL.PixelData GL.RGBA GL.UnsignedByte ptr) |                                         (GL.PixelData GL.RGBA GL.UnsignedByte ptr) | ||||||
|  |                         prio <- widget ^. baseProperties.priority | ||||||
|  |                         when (widget ^. baseProperties.shorthand == "VWP" && prio == 5) $ do | ||||||
|  |                           -- copy camera texture on screen | ||||||
|  |                           return () | ||||||
|                         nextChildrenIds <- widget ^. baseProperties.children |                         nextChildrenIds <- widget ^. baseProperties.children | ||||||
|                         mapM_ (copyGUI tex (vX+xoff, vY+yoff)) $ toGUIAnys hMap nextChildrenIds |                         mapM_ (copyGUI tex (vX+xoff, vY+yoff)) $ toGUIAnys hMap nextChildrenIds | ||||||
|  |  | ||||||
|   | |||||||
| @@ -63,7 +63,7 @@ instance Hashable MouseButton where -- TODO: generic deriving creates functions | |||||||
| --- widget state | --- widget state | ||||||
| --------------------------- | --------------------------- | ||||||
| -- |A key to reference a specific type of 'WidgetState'. | -- |A key to reference a specific type of 'WidgetState'. | ||||||
| data WidgetStateKey = MouseStateKey | data WidgetStateKey = MouseStateKey | ViewportStateKey | ||||||
|     deriving (Eq, Ord, Enum, Ix, Bounded, Generic, Show, Read) |     deriving (Eq, Ord, Enum, Ix, Bounded, Generic, Show, Read) | ||||||
|  |  | ||||||
| instance Hashable WidgetStateKey where -- TODO: generic deriving creates functions that run forever | instance Hashable WidgetStateKey where -- TODO: generic deriving creates functions that run forever | ||||||
| @@ -85,6 +85,7 @@ data MouseButtonState = MouseButtonState | |||||||
|     { _mouseIsDragging      :: Bool -- ^firing if pressed but not confirmed |     { _mouseIsDragging      :: Bool -- ^firing if pressed but not confirmed | ||||||
|     , _mouseIsDeferred      :: Bool |     , _mouseIsDeferred      :: Bool | ||||||
|       -- ^deferred if e. g. dragging but outside component |       -- ^deferred if e. g. dragging but outside component | ||||||
|  |     , _dragStart            :: (ScreenUnit, ScreenUnit) | ||||||
|     } deriving (Eq, Show) |     } deriving (Eq, Show) | ||||||
|   |   | ||||||
| -- |An applied state a widget may take, depending on its usage and event handlers. Corresponding Key: 'WidgetStateKey'. | -- |An applied state a widget may take, depending on its usage and event handlers. Corresponding Key: 'WidgetStateKey'. | ||||||
| @@ -95,6 +96,15 @@ data WidgetState = | |||||||
|         , _mouseIsReady  :: Bool -- ^ready if mouse is above component |         , _mouseIsReady  :: Bool -- ^ready if mouse is above component | ||||||
|         , _mousePixel :: Pixel -- ^current local position of the mouse, only updated if widget is the mouse-active component |         , _mousePixel :: Pixel -- ^current local position of the mouse, only updated if widget is the mouse-active component | ||||||
|         } |         } | ||||||
|  |     | | ||||||
|  |     -- |A position to store screen units. Referenced by 'ViewportStateKey'. | ||||||
|  |     ViewportState | ||||||
|  |         { _isDragging :: Bool | ||||||
|  |         , _dragStartX :: Double | ||||||
|  |         , _dragStartY :: Double | ||||||
|  |         , _dragAngleX :: Double | ||||||
|  |         , _dragAngleY :: Double | ||||||
|  |         } | ||||||
|     deriving (Eq, Show) |     deriving (Eq, Show) | ||||||
|  |  | ||||||
| --------------------------- | --------------------------- | ||||||
| @@ -255,9 +265,12 @@ $(makeLenses ''GUIWidget) | |||||||
| $(makeLenses ''GUIBaseProperties) | $(makeLenses ''GUIBaseProperties) | ||||||
| $(makeLenses ''GUIGraphics) | $(makeLenses ''GUIGraphics) | ||||||
|  |  | ||||||
|  | initialViewportState :: WidgetState | ||||||
|  | initialViewportState = ViewportState False 0 0 0 0 | ||||||
|  |  | ||||||
| -- |Creates a default @MouseButtonState@. | -- |Creates a default @MouseButtonState@. | ||||||
| initialButtonState :: MouseButtonState | initialButtonState :: MouseButtonState | ||||||
| initialButtonState = MouseButtonState False False | initialButtonState = MouseButtonState False False (0, 0) | ||||||
| {-# INLINE initialButtonState #-} | {-# INLINE initialButtonState #-} | ||||||
|  |  | ||||||
| -- |Creates a 'MouseState' its @_mouseStates@ are valid 'MouseButtonState's for any 'MouseButton'. | -- |Creates a 'MouseState' its @_mouseStates@ are valid 'MouseButtonState's for any 'MouseButton'. | ||||||
|   | |||||||
| @@ -2,8 +2,9 @@ | |||||||
|  |  | ||||||
| module UI.UIWidgets (module UI.UIWidgets, module UI.UIBase) where | module UI.UIWidgets (module UI.UIWidgets, module UI.UIBase) where | ||||||
|  |  | ||||||
| import           Control.Concurrent.STM.TVar          (readTVarIO) | import           Control.Concurrent.STM               (atomically) | ||||||
| import           Control.Lens                         ((^.), (.~), (%~), (&)) | import           Control.Concurrent.STM.TVar          (readTVarIO, writeTVar, TVar()) | ||||||
|  | import           Control.Lens                         ((^.), (.~), (%~), (&), (^?), at, Getting()) | ||||||
| import           Control.Monad | import           Control.Monad | ||||||
| import           Control.Monad.IO.Class               (liftIO) | import           Control.Monad.IO.Class               (liftIO) | ||||||
| import           Control.Monad.RWS.Strict             (get, modify) | import           Control.Monad.RWS.Strict             (get, modify) | ||||||
| @@ -12,6 +13,7 @@ import           Data.Maybe | |||||||
| import qualified Data.HashMap.Strict as Map | import qualified Data.HashMap.Strict as Map | ||||||
|  |  | ||||||
| import Types | import Types | ||||||
|  | import Render.Misc                          (curb) | ||||||
| import UI.UIBase | import UI.UIBase | ||||||
| import UI.UIOperations | import UI.UIOperations | ||||||
|  |  | ||||||
| @@ -46,39 +48,68 @@ createButton bnd prio action = Widget (rectangularBase bnd [] prio "BTN") | |||||||
|                                       (Map.fromList [(MouseStateKey, initialMouseState)]) -- widget states |                                       (Map.fromList [(MouseStateKey, initialMouseState)]) -- widget states | ||||||
|                                       (Map.fromList [(MouseEvent, buttonMouseActions action)]) -- event handlers |                                       (Map.fromList [(MouseEvent, buttonMouseActions action)]) -- event handlers | ||||||
|  |  | ||||||
| createViewport :: MouseButton -- ^ button to drag with | createViewport :: Getting (TVar CameraState) State (TVar CameraState) | ||||||
|  | --Setting (->) State State (TVar CameraState) (TVar CameraState) -- ^ lens to connected @TVar CameraState@ | ||||||
|  |                -> MouseButton -- ^ button to drag with | ||||||
|                -> (ScreenUnit, ScreenUnit, ScreenUnit, ScreenUnit) -> [UIId] -> Int -> GUIWidget Pioneers |                -> (ScreenUnit, ScreenUnit, ScreenUnit, ScreenUnit) -> [UIId] -> Int -> GUIWidget Pioneers | ||||||
| createViewport btn bnd chld prio = Widget (rectangularBase bnd chld prio "VWP") | createViewport thelens btn bnd chld prio = Widget (rectangularBase bnd chld prio "VWP") | ||||||
|                                     emptyGraphics |                                     emptyGraphics | ||||||
|                                     Map.empty -- widget states |                                     (Map.fromList [(ViewportStateKey, initialViewportState)]) -- widget states | ||||||
|                                     (Map.fromList [(MouseEvent, viewportMouseAction) |                                     (Map.fromList [(MouseEvent, viewportMouseAction) | ||||||
|                                                   ,(MouseMotionEvent, viewportMouseMotionAction)]) -- event handlers |                                                   ,(MouseMotionEvent, viewportMouseMotionAction)]) -- event handlers | ||||||
|   where |   where | ||||||
|  |     updateCamera :: Double -> Double -> Double -> Double -> Double -> Double -> CameraState -> CameraState | ||||||
|  |     updateCamera xStart' yStart' x y sodxa sodya cam = | ||||||
|  |         let myrot = (x - xStart') / 2 | ||||||
|  |             mxrot = (y - yStart') / 2 | ||||||
|  |             newXAngle' = sodxa + mxrot/100 | ||||||
|  |             newXAngle  = curb (pi/12) (0.45*pi) newXAngle' | ||||||
|  |             newYAngle' = sodya + myrot/100 | ||||||
|  |             newYAngle | ||||||
|  |                  | newYAngle' > pi    = newYAngle' - 2 * pi | ||||||
|  |                  | newYAngle' < (-pi) = newYAngle' + 2 * pi | ||||||
|  |                  | otherwise          = newYAngle' | ||||||
|  |         in cam & (xAngle .~ newXAngle) . (yAngle .~ newYAngle) | ||||||
|  |    | ||||||
|     viewportMouseAction :: WidgetEventHandler Pioneers |     viewportMouseAction :: WidgetEventHandler Pioneers | ||||||
|     viewportMouseAction = |     viewportMouseAction = | ||||||
|         let press btn' (x, y) _ w = |         let press btn' (x, y) _ w = | ||||||
|               do when (btn == btn') $ do |               do if (btn == btn')  | ||||||
|                      state <- get |                   then do state <- get | ||||||
|                      cam <- liftIO $ readTVarIO (state ^. camera) |                           let camT = state ^. thelens | ||||||
|                      modify $ mouse %~ (isDragging .~ True) |                           cam <- liftIO $ readTVarIO camT | ||||||
|                                      . (dragStartX .~ fromIntegral x) |                           let sodxa = cam ^. xAngle | ||||||
|                                      . (dragStartY .~ fromIntegral y) |                               sodya = cam ^. yAngle | ||||||
|                                      . (dragStartXAngle .~ (cam ^. xAngle)) |                           liftIO $ atomically $ writeTVar camT $ | ||||||
|                                      . (dragStartYAngle .~ (cam ^. yAngle)) |                             updateCamera (fromIntegral x) (fromIntegral y) (fromIntegral x) (fromIntegral y) sodxa sodya cam | ||||||
|                                      . (mousePosition.Types._x .~ fromIntegral x) |                           return $ w & widgetStates . at ViewportStateKey .~ | ||||||
|                                      . (mousePosition.Types._y .~ fromIntegral y) |                               Just (ViewportState True (fromIntegral x) (fromIntegral y) sodxa sodya) | ||||||
|                  return w |                   else return w | ||||||
|             release btn' _ _ w = do when (btn == btn') (modify $ mouse.isDragging .~ False) |             release btn' _ _ w = if (btn' == btn) | ||||||
|                                     return w |               then | ||||||
|  |                 -- modify ViewportState to "not dragging" or recreate ViewportState state if not present | ||||||
|  |                 return $ w & widgetStates . at ViewportStateKey %~ | ||||||
|  |                     maybe (Just $ initialViewportState) (\s -> Just (s & isDragging .~ False)) | ||||||
|  |               else return w | ||||||
|         in MouseHandler press release |         in MouseHandler press release | ||||||
|      |      | ||||||
|     viewportMouseMotionAction :: WidgetEventHandler Pioneers |     viewportMouseMotionAction :: WidgetEventHandler Pioneers | ||||||
|     viewportMouseMotionAction = |     viewportMouseMotionAction = | ||||||
|         let move (x, y) w = |         let move (x, y) w = | ||||||
|               do state <- get |               do let mbPosState = w ^. widgetStates.(at ViewportStateKey) | ||||||
|                  when (state ^. mouse.isDragging) $ |                  case mbPosState of | ||||||
|                         modify $ mouse %~ (mousePosition.Types._x .~ fromIntegral x) |                       Just posState -> | ||||||
|                                         . (mousePosition.Types._y .~ fromIntegral y) |                         when (maybe False id (posState ^? isDragging)) $ do | ||||||
|  |                           state <- get | ||||||
|  |                           let camT = state ^. thelens | ||||||
|  |                           cam <- liftIO $ readTVarIO camT | ||||||
|  |                           let xS = fromJust $ posState ^? dragStartX -- fromJust is safe | ||||||
|  |                               yS = fromJust $ posState ^? dragStartY -- fromJust is safe | ||||||
|  |                               sodxa = fromJust $ posState ^? dragAngleX -- fromJust is safe | ||||||
|  |                               sodya = fromJust $ posState ^? dragAngleY -- fromJust is safe | ||||||
|  |                           liftIO $ atomically $ writeTVar camT $ | ||||||
|  |                             updateCamera xS yS (fromIntegral x) (fromIntegral y) sodxa sodya cam | ||||||
|  |                       Nothing -> return () | ||||||
|                  return w |                  return w | ||||||
|         in emptyMouseMotionHandler & onMouseMove .~ move |         in emptyMouseMotionHandler & onMouseMove .~ move | ||||||
|          |          | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user