Haskell bindings to Dear ImGui, an immediate mode GUI toolkit
Go to file
2021-01-25 16:47:56 +00:00
examples Update the README with the demo window and a screenshot 2021-01-25 09:18:13 +00:00
imgui@58075c4414 Initial work 2021-01-24 15:27:03 +00:00
nix Add Haskell.nix and use it to provide a shell.nix (#3) 2021-01-25 16:47:56 +00:00
src add string formatter 2021-01-25 13:39:23 +00:00
.gitignore Initial commit 2021-01-24 15:25:52 +00:00
.gitmodules Initial work 2021-01-24 15:27:03 +00:00
cabal.project Add Haskell.nix and use it to provide a shell.nix (#3) 2021-01-25 16:47:56 +00:00
dear-imgui.cabal Fixes to make Darwin work (#7) 2021-01-25 16:42:31 +00:00
default.nix Add Haskell.nix and use it to provide a shell.nix (#3) 2021-01-25 16:47:56 +00:00
Example.png Update the README with the demo window and a screenshot 2021-01-25 09:18:13 +00:00
LICENSE Initial commit 2021-01-24 15:25:52 +00:00
Main.hs Wrap @ImGui::ColorPicker3()@ 2021-01-25 09:11:46 +00:00
README.md Update the README with the demo window and a screenshot 2021-01-25 09:18:13 +00:00
shell.nix Add Haskell.nix and use it to provide a shell.nix (#3) 2021-01-25 16:47:56 +00:00

Dear ImGui.hs

Dear ImGui is a bloat-free graphical user interface library for C++. It outputs optimized vertex buffers that you can render anytime in your 3D-pipeline enabled application. It is fast, portable, renderer agnostic and self-contained (no external dependencies).

This project contains Haskell bindings to the ImGui project. This allows you to rapidly put together graphical user interfaces in Haskell, with a particular focus to games and graphics intensive applications.

Getting Started

To get started, we'll build the following:

dear-imgui.hs can be used like a normal Haskell library. If you use Cabal, simply add dear-imgui to your build-depends. ImGui supports a variety of backends, and you will need to choose your backend at configuration time. Backends can be enabled using Cabal flags, and these can be set through the cabal.project file. For example, if you want to use a combination of SDL and OpenGL:

package dear-imgui
  flags: +sdl +opengl

With this done, the following module is the "Hello, World!" of ImGui:

{-# language BlockArguments #-}
{-# language LambdaCase #-}
{-# language OverloadedStrings #-}

module Main ( main ) where

import Control.Exception
import Control.Monad.IO.Class
import Control.Monad.Managed
import DearImGui
import DearImGui.OpenGL
import DearImGui.SDL
import DearImGui.SDL.OpenGL
import Graphics.GL
import SDL

main :: IO ()
main = do
  -- Initialize SDL
  initializeAll

  runManaged do
    -- Create a window using SDL. As we're using OpenGL, we need to enable OpenGL too.
    w <- do
      let title = "Hello, Dear ImGui!"
      let config = defaultWindow { windowGraphicsContext = OpenGLContext defaultOpenGL }
      managed $ bracket (createWindow title config) destroyWindow

    -- Create an OpenGL context
    glContext <- managed $ bracket (glCreateContext w) glDeleteContext

    -- Create an ImGui context
    _ <- managed $ bracket createContext destroyContext

    -- Initialize ImGui's SDL2 backend
    _ <- managed_ $ bracket_ (sdl2InitForOpenGL w glContext) sdl2Shutdown

    -- Initialize ImGui's OpenGL backend
    _ <- managed_ $ bracket_ openGL2Init openGL2Shutdown

    liftIO $ mainLoop w


mainLoop :: Window -> IO ()
mainLoop w = do
  -- Process the event loop
  untilNothingM pollEventWithImGui

  -- Tell ImGui we're starting a new frame
  openGL2NewFrame
  sdl2NewFrame w
  newFrame

  -- Build the GUI
  bracket_ (begin "Hello, ImGui!") end do
    -- Add a text widget
    text "Hello, ImGui!"

    -- Add a button widget, and call 'putStrLn' when it's clicked
    button "Clickety Click" >>= \case
      False -> return ()
      True  -> putStrLn "Ow!"

  -- Show the ImGui demo window
  showDemoWindow

  -- Render
  glClear GL_COLOR_BUFFER_BIT

  render
  openGL2RenderDrawData =<< getDrawData

  glSwapWindow w

  mainLoop w

  where
    untilNothingM m = m >>= maybe (return ()) (\_ -> untilNothingM m)