diff options
author | Joe Crayne <joe@jerkface.net> | 2019-04-17 14:18:12 -0400 |
---|---|---|
committer | Joe Crayne <joe@jerkface.net> | 2019-04-17 18:36:53 -0400 |
commit | 64f1a100fc887fb2a8bc87e2ac6975e872010ef5 (patch) | |
tree | 71e96856bf8a0ebcd14f7ab87124184cb15d868b /GLWidget.hs | |
parent | 3899b660b11bf1d3179965ac92a039b8d449306f (diff) |
Refactored spinning-logo demo.
Diffstat (limited to 'GLWidget.hs')
-rw-r--r-- | GLWidget.hs | 100 |
1 files changed, 100 insertions, 0 deletions
diff --git a/GLWidget.hs b/GLWidget.hs new file mode 100644 index 0000000..8a9d23e --- /dev/null +++ b/GLWidget.hs | |||
@@ -0,0 +1,100 @@ | |||
1 | {-# LANGUAGE LambdaCase #-} | ||
2 | {-# LANGUAGE OverloadedLabels #-} | ||
3 | {-# LANGUAGE OverloadedStrings #-} | ||
4 | module GLWidget where | ||
5 | |||
6 | import Control.Concurrent | ||
7 | import Data.Functor.Contravariant | ||
8 | import Data.Int | ||
9 | import Data.IORef | ||
10 | import qualified Data.Text as Text | ||
11 | ;import Data.Text (Text) | ||
12 | import Foreign.ForeignPtr | ||
13 | import Foreign.Ptr | ||
14 | import GI.Gdk.Objects (GLContext(..),windowCreateGlContext) | ||
15 | import qualified GI.Gtk as Gtk | ||
16 | ;import GI.Gtk as Gtk hiding (main) | ||
17 | import System.IO | ||
18 | |||
19 | data WidgetMethods st = WidgetMethods | ||
20 | { glUnrealize :: st -> IO () | ||
21 | , glRealize :: st -> IO () | ||
22 | , glResize :: st -> Int32 -> Int32 -> IO () | ||
23 | , glRender :: st -> GLContext -> IO Bool | ||
24 | , glCreateContext :: st -> IO (Maybe GLContext) | ||
25 | , glTitle :: Text | ||
26 | } | ||
27 | |||
28 | instance Contravariant WidgetMethods where | ||
29 | contramap f w = w | ||
30 | { glUnrealize = glUnrealize w . f | ||
31 | , glRealize = glRealize w . f | ||
32 | , glResize = glResize w . f | ||
33 | , glRender = glRender w . f | ||
34 | , glCreateContext = glCreateContext w . f | ||
35 | } | ||
36 | |||
37 | glmethods :: WidgetMethods GLArea | ||
38 | glmethods = WidgetMethods | ||
39 | { glUnrealize = \_ -> return () | ||
40 | , glRealize = \_ -> return () | ||
41 | , glRender = \_ gl -> return True | ||
42 | , glResize = \_ w h -> return () | ||
43 | , glCreateContext = | ||
44 | \st -> widgetGetWindow (st::GLArea) | ||
45 | >>= maybe (return Nothing) | ||
46 | (fmap Just . windowCreateGlContext) | ||
47 | , glTitle = "GL Area" | ||
48 | } | ||
49 | |||
50 | newGLWidget :: (GLArea -> IO st) -> WidgetMethods st -> IO st | ||
51 | newGLWidget mk w = do | ||
52 | g <- gLAreaNew | ||
53 | st <- mk g | ||
54 | _ <- on g #render $ glRender w st | ||
55 | _ <- on g #resize $ glResize w st | ||
56 | _ <- on g #realize $ withCurrentGL g (glRealize w st) | ||
57 | _ <- on g #unrealize $ glUnrealize w st | ||
58 | _ <- on g #createContext $ nullableContext (glCreateContext w st) | ||
59 | return st | ||
60 | |||
61 | withCurrentGL :: GLArea -> IO () -> IO () | ||
62 | withCurrentGL glarea action = do | ||
63 | gLAreaMakeCurrent glarea | ||
64 | e <- gLAreaGetError glarea | ||
65 | maybe action oopsG e | ||
66 | |||
67 | nullableContext :: IO (Maybe GLContext) -> IO GLContext | ||
68 | nullableContext mk = mk >>= maybe mknull return | ||
69 | where | ||
70 | mknull = do | ||
71 | oops "createContext: GLArea has no window." | ||
72 | fp <- newForeignPtr_ nullPtr | ||
73 | disown <- newIORef Nothing | ||
74 | return $ GLContext $ ManagedPtr fp disown | ||
75 | |||
76 | oopsG :: GError -> IO () | ||
77 | oopsG e = do | ||
78 | msg <- gerrorMessage e | ||
79 | oops (Text.unpack msg) | ||
80 | |||
81 | oops :: String -> IO () | ||
82 | oops s = hPutStrLn stderr s | ||
83 | |||
84 | runGLApp mk methods = do | ||
85 | _ <- Gtk.init Nothing | ||
86 | |||
87 | let mkChild = newGLWidget mk methods | ||
88 | |||
89 | window <- do | ||
90 | w <- windowNew WindowTypeToplevel | ||
91 | windowSetDefaultSize w 760 760 | ||
92 | windowSetTitle w (glTitle methods) | ||
93 | containerSetBorderWidth w 0 | ||
94 | _ <- on w #deleteEvent $ \_ -> mainQuit >> return True | ||
95 | child <- mkChild | ||
96 | containerAdd w child | ||
97 | return w | ||
98 | |||
99 | widgetShowAll window | ||
100 | Gtk.main | ||