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 Data.IORef
import DearImGui import DearImGui
import DearImGui.OpenGL
import DearImGui.SDL
import DearImGui.SDL.OpenGL
import Control.Exception import Control.Exception
import Graphics.GL import Graphics.GL
import SDL import SDL

View File

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

View File

@ -6,6 +6,12 @@
{-# LANGUAGE QuasiQuotes #-} {-# LANGUAGE QuasiQuotes #-}
{-# LANGUAGE TemplateHaskell #-} {-# LANGUAGE TemplateHaskell #-}
{-|
Module: DearImGui
Main ImGui module, exporting the functions to create a GUI.
-}
module DearImGui module DearImGui
( -- * Context Creation and Access ( -- * Context Creation and Access
Context(..) Context(..)
@ -20,18 +26,6 @@ module DearImGui
, getDrawData , getDrawData
, checkVersion , checkVersion
-- ** SDL2
, sdl2InitForOpenGL
, sdl2NewFrame
, sdl2Shutdown
, pollEventWithImGui
-- ** OpenGL 2
, openGL2Init
, openGL2Shutdown
, openGL2NewFrame
, openGL2RenderDrawData
-- * Demo, Debug, Information -- * Demo, Debug, Information
, showDemoWindow , showDemoWindow
, showMetricsWindow , showMetricsWindow
@ -103,26 +97,28 @@ module DearImGui
) )
where where
import Control.Monad ( when ) -- base
import Control.Monad.IO.Class ( MonadIO, liftIO )
import Data.Bool import Data.Bool
import Data.StateVar
import Foreign import Foreign
import Foreign.C import Foreign.C
-- inline-c
import qualified Language.C.Inline as C import qualified Language.C.Inline as C
-- inline-c-cpp
import qualified Language.C.Inline.Cpp as Cpp import qualified Language.C.Inline.Cpp as Cpp
import SDL
import SDL.Internal.Types -- StateVar
import SDL.Raw.Enum as Raw import Data.StateVar
import qualified SDL.Raw.Event as Raw ( HasGetter(get), HasSetter, ($=!) )
import Unsafe.Coerce ( unsafeCoerce )
-- transformers
import Control.Monad.IO.Class
( MonadIO, liftIO )
C.context (Cpp.cppCtx <> C.bsCtx) C.context (Cpp.cppCtx <> C.bsCtx)
C.include "imgui.h" 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" Cpp.using "namespace ImGui"
@ -184,68 +180,6 @@ checkVersion = liftIO do
[C.exp| void { IMGUI_CHECKVERSION(); } |] [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 -- | Create demo window. Demonstrate most ImGui features. Call this to learn
-- about the library! Try to make it always available in your application! -- about the library! Try to make it always available in your application!
showDemoWindow :: MonadIO m => m () 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