add cabal flags for backend selection

This commit is contained in:
sheaf 2021-01-24 19:25:40 +01:00 committed by Ollie Charles
parent 3c3646a645
commit bbef66b202
6 changed files with 296 additions and 100 deletions

View File

@ -7,6 +7,9 @@ module Main (main) where
import Data.IORef
import DearImGui
import DearImGui.OpenGL
import DearImGui.SDL
import DearImGui.SDL.OpenGL
import Control.Exception
import Graphics.GL
import SDL

View File

@ -3,25 +3,79 @@ name: dear-imgui
version: 1.0.0
build-type: Simple
flag opengl
description:
Enable OpenGL backend.
default:
True
manual:
False
flag sdl
description:
Enable SDL backend.
default:
True
manual:
False
library
exposed-modules: DearImGui
hs-source-dirs: src
default-language: Haskell2010
ghc-options: -Wall
exposed-modules:
DearImGui
hs-source-dirs:
src
default-language:
Haskell2010
ghc-options:
-Wall
cxx-sources:
imgui/imgui.cpp
imgui/backends/imgui_impl_opengl2.cpp
imgui/backends/imgui_impl_sdl.cpp
imgui/imgui_demo.cpp
imgui/imgui_draw.cpp
imgui/imgui_tables.cpp
imgui/imgui_widgets.cpp
imgui/imgui_draw.cpp
imgui/imgui_demo.cpp
cxx-options: -std=c++11
extra-libraries: stdc++
pkgconfig-depends: sdl2
include-dirs: imgui
build-depends: base, inline-c, inline-c-cpp, sdl2, StateVar
extra-libraries: GL
cxx-options:
-std=c++11
extra-libraries:
stdc++
include-dirs:
imgui
build-depends:
base
, inline-c
, inline-c-cpp
, StateVar
if flag(opengl)
exposed-modules:
DearImGui.OpenGL
cxx-sources:
imgui/backends/imgui_impl_opengl2.cpp
if os(windows)
extra-libraries:
opengl32
else
extra-libraries:
GL
if flag(sdl)
exposed-modules:
DearImGui.SDL
build-depends:
sdl2
cxx-sources:
imgui/backends/imgui_impl_sdl.cpp
if os(windows) || os(darwin)
extra-libraries:
sdl2
else
pkgconfig-depends:
sdl2
if flag(opengl)
exposed-modules:
DearImGui.SDL.OpenGL
executable test

View File

@ -6,6 +6,12 @@
{-# LANGUAGE QuasiQuotes #-}
{-# LANGUAGE TemplateHaskell #-}
{-|
Module: DearImGui
Main ImGui module, exporting the functions to create a GUI.
-}
module DearImGui
( -- * Context Creation and Access
Context(..)
@ -20,18 +26,6 @@ module DearImGui
, getDrawData
, checkVersion
-- ** SDL2
, sdl2InitForOpenGL
, sdl2NewFrame
, sdl2Shutdown
, pollEventWithImGui
-- ** OpenGL 2
, openGL2Init
, openGL2Shutdown
, openGL2NewFrame
, openGL2RenderDrawData
-- * Demo, Debug, Information
, showDemoWindow
, showMetricsWindow
@ -103,26 +97,28 @@ module DearImGui
)
where
import Control.Monad ( when )
import Control.Monad.IO.Class ( MonadIO, liftIO )
-- base
import Data.Bool
import Data.StateVar
import Foreign
import Foreign.C
-- inline-c
import qualified Language.C.Inline as C
-- inline-c-cpp
import qualified Language.C.Inline.Cpp as Cpp
import SDL
import SDL.Internal.Types
import SDL.Raw.Enum as Raw
import qualified SDL.Raw.Event as Raw
import Unsafe.Coerce ( unsafeCoerce )
-- StateVar
import Data.StateVar
( HasGetter(get), HasSetter, ($=!) )
-- transformers
import Control.Monad.IO.Class
( MonadIO, liftIO )
C.context (Cpp.cppCtx <> C.bsCtx)
C.include "imgui.h"
C.include "backends/imgui_impl_opengl2.h"
C.include "backends/imgui_impl_sdl.h"
C.include "SDL.h"
C.include "SDL_opengl.h"
Cpp.using "namespace ImGui"
@ -184,68 +180,6 @@ checkVersion = liftIO do
[C.exp| void { IMGUI_CHECKVERSION(); } |]
-- | Wraps @ImGui_ImplSDL2_InitForOpenGL@.
sdl2InitForOpenGL :: MonadIO m => Window -> GLContext -> m ()
sdl2InitForOpenGL (Window windowPtr) glContext = liftIO do
[C.exp| void { ImGui_ImplSDL2_InitForOpenGL((SDL_Window*)$(void* windowPtr), $(void* glContextPtr)); } |]
where
glContextPtr :: Ptr ()
glContextPtr = unsafeCoerce glContext
-- | Wraps @ImGui_ImplSDL2_NewFrame@.
sdl2NewFrame :: MonadIO m => Window -> m ()
sdl2NewFrame (Window windowPtr) = liftIO do
[C.exp| void { ImGui_ImplSDL2_NewFrame((SDL_Window*)($(void* windowPtr))); } |]
-- | Wraps @ImGui_ImplSDL2_Shutdown@.
sdl2Shutdown :: MonadIO m => m ()
sdl2Shutdown = liftIO do
[C.exp| void { ImGui_ImplSDL2_Shutdown(); } |]
-- | Call the SDL2 'pollEvent' function, while also dispatching the event to
-- Dear ImGui. You should use this in your application instead of 'pollEvent'.
pollEventWithImGui :: MonadIO m => m (Maybe Event)
pollEventWithImGui = liftIO do
alloca \evPtr -> do
pumpEvents
-- We use NULL first to check if there's an event.
nEvents <- Raw.peepEvents evPtr 1 Raw.SDL_PEEKEVENT Raw.SDL_FIRSTEVENT Raw.SDL_LASTEVENT
when (nEvents > 0) do
let evPtr' = castPtr evPtr :: Ptr ()
[C.exp| void { ImGui_ImplSDL2_ProcessEvent((SDL_Event*) $(void* evPtr')) } |]
pollEvent
-- | Wraps @ImGui_ImplOpenGL2_Init@.
openGL2Init :: MonadIO m => m ()
openGL2Init = liftIO do
[C.exp| void { ImGui_ImplOpenGL2_Init(); } |]
-- | Wraps @ImGui_ImplOpenGL2_Shutdown@.
openGL2Shutdown :: MonadIO m => m ()
openGL2Shutdown = liftIO do
[C.exp| void { ImGui_ImplOpenGL2_Shutdown(); } |]
-- | Wraps @ImGui_ImplOpenGL2_NewFrame@.
openGL2NewFrame :: MonadIO m => m ()
openGL2NewFrame = liftIO do
[C.exp| void { ImGui_ImplOpenGL2_NewFrame(); } |]
-- | Wraps @ImGui_ImplOpenGL2_RenderDrawData@.
openGL2RenderDrawData :: MonadIO m => DrawData -> m ()
openGL2RenderDrawData (DrawData ptr) = liftIO do
[C.exp| void { ImGui_ImplOpenGL2_RenderDrawData((ImDrawData*) $( void* ptr )) } |]
-- | Create demo window. Demonstrate most ImGui features. Call this to learn
-- about the library! Try to make it always available in your application!
showDemoWindow :: MonadIO m => m ()

65
src/DearImGui/OpenGL.hs Normal file
View File

@ -0,0 +1,65 @@
{-# LANGUAGE BlockArguments #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE NamedFieldPuns #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE PatternSynonyms #-}
{-# LANGUAGE QuasiQuotes #-}
{-# LANGUAGE TemplateHaskell #-}
{-|
Module: DearImGui.OpenGL
OpenGL backend for Dear ImGui.
-}
module DearImGui.OpenGL
( openGL2Init
, openGL2Shutdown
, openGL2NewFrame
, openGL2RenderDrawData
)
where
-- inline-c
import qualified Language.C.Inline as C
-- inline-c-cpp
import qualified Language.C.Inline.Cpp as Cpp
-- transformers
import Control.Monad.IO.Class
( MonadIO, liftIO )
-- DearImGui
import DearImGui
( DrawData(..) )
C.context (Cpp.cppCtx <> C.bsCtx)
C.include "imgui.h"
C.include "backends/imgui_impl_opengl2.h"
Cpp.using "namespace ImGui"
-- | Wraps @ImGui_ImplOpenGL2_Init@.
openGL2Init :: MonadIO m => m ()
openGL2Init = liftIO do
[C.exp| void { ImGui_ImplOpenGL2_Init(); } |]
-- | Wraps @ImGui_ImplOpenGL2_Shutdown@.
openGL2Shutdown :: MonadIO m => m ()
openGL2Shutdown = liftIO do
[C.exp| void { ImGui_ImplOpenGL2_Shutdown(); } |]
-- | Wraps @ImGui_ImplOpenGL2_NewFrame@.
openGL2NewFrame :: MonadIO m => m ()
openGL2NewFrame = liftIO do
[C.exp| void { ImGui_ImplOpenGL2_NewFrame(); } |]
-- | Wraps @ImGui_ImplOpenGL2_RenderDrawData@.
openGL2RenderDrawData :: MonadIO m => DrawData -> m ()
openGL2RenderDrawData (DrawData ptr) = liftIO do
[C.exp| void { ImGui_ImplOpenGL2_RenderDrawData((ImDrawData*) $( void* ptr )) } |]

83
src/DearImGui/SDL.hs Normal file
View File

@ -0,0 +1,83 @@
{-# LANGUAGE BlockArguments #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE NamedFieldPuns #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE PatternSynonyms #-}
{-# LANGUAGE QuasiQuotes #-}
{-# LANGUAGE TemplateHaskell #-}
{-|
Module: DearImGui.SDL
SDL2 specific functions backend for Dear ImGui.
Modules for initialising a backend with SDL2 can be found under the corresponding backend,
e.g. "DearImGui.SDL.OpenGL".
-}
module DearImGui.SDL (
-- ** SDL2
sdl2NewFrame
, sdl2Shutdown
, pollEventWithImGui
)
where
-- base
import Control.Monad
( when )
import Foreign.Marshal.Alloc
( alloca )
import Foreign.Ptr
( Ptr, castPtr )
-- inline-c
import qualified Language.C.Inline as C
-- inline-c-cpp
import qualified Language.C.Inline.Cpp as Cpp
-- sdl2
import SDL
import SDL.Internal.Types
import SDL.Raw.Enum as Raw
import qualified SDL.Raw.Event as Raw
-- transformers
import Control.Monad.IO.Class
( MonadIO, liftIO )
C.context (Cpp.cppCtx <> C.bsCtx)
C.include "imgui.h"
C.include "backends/imgui_impl_sdl.h"
C.include "SDL.h"
Cpp.using "namespace ImGui"
-- | Wraps @ImGui_ImplSDL2_NewFrame@.
sdl2NewFrame :: MonadIO m => Window -> m ()
sdl2NewFrame (Window windowPtr) = liftIO do
[C.exp| void { ImGui_ImplSDL2_NewFrame((SDL_Window*)($(void* windowPtr))); } |]
-- | Wraps @ImGui_ImplSDL2_Shutdown@.
sdl2Shutdown :: MonadIO m => m ()
sdl2Shutdown = liftIO do
[C.exp| void { ImGui_ImplSDL2_Shutdown(); } |]
-- | Call the SDL2 'pollEvent' function, while also dispatching the event to
-- Dear ImGui. You should use this in your application instead of 'pollEvent'.
pollEventWithImGui :: MonadIO m => m (Maybe Event)
pollEventWithImGui = liftIO do
alloca \evPtr -> do
pumpEvents
-- We use NULL first to check if there's an event.
nEvents <- Raw.peepEvents evPtr 1 Raw.SDL_PEEKEVENT Raw.SDL_FIRSTEVENT Raw.SDL_LASTEVENT
when (nEvents > 0) do
let evPtr' = castPtr evPtr :: Ptr ()
[C.exp| void { ImGui_ImplSDL2_ProcessEvent((SDL_Event*) $(void* evPtr')) } |]
pollEvent

View File

@ -0,0 +1,57 @@
{-# LANGUAGE BlockArguments #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE NamedFieldPuns #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE PatternSynonyms #-}
{-# LANGUAGE QuasiQuotes #-}
{-# LANGUAGE TemplateHaskell #-}
{-|
Module: DearImGUI.SDL.OpenGL
Initialising the OpenGL backend for Dear ImGui using SDL2.
-}
module DearImGui.SDL.OpenGL
( sdl2InitForOpenGL )
where
-- base
import Foreign.Ptr
( Ptr )
import Unsafe.Coerce
( unsafeCoerce )
-- inline-c
import qualified Language.C.Inline as C
-- inline-c-cpp
import qualified Language.C.Inline.Cpp as Cpp
-- sdl2
import SDL
( GLContext )
import SDL.Internal.Types
( Window(..) )
-- transformers
import Control.Monad.IO.Class
( MonadIO, liftIO )
C.context (Cpp.cppCtx <> C.bsCtx)
C.include "imgui.h"
C.include "backends/imgui_impl_opengl2.h"
C.include "backends/imgui_impl_sdl.h"
C.include "SDL.h"
C.include "SDL_opengl.h"
Cpp.using "namespace ImGui"
-- | Wraps @ImGui_ImplSDL2_InitForOpenGL@.
sdl2InitForOpenGL :: MonadIO m => Window -> GLContext -> m ()
sdl2InitForOpenGL (Window windowPtr) glContext = liftIO do
[C.exp| void { ImGui_ImplSDL2_InitForOpenGL((SDL_Window*)$(void* windowPtr), $(void* glContextPtr)); } |]
where
glContextPtr :: Ptr ()
glContextPtr = unsafeCoerce glContext