Haskell bindings to Dear ImGui, an immediate mode GUI toolkit
Go to file
2024-02-20 19:20:46 +00:00
.github/workflows Update bound for ghc-9.6 (#174) 2023-05-07 17:44:13 +03:00
examples Update README (#194) 2024-02-04 18:24:06 +00:00
generator/DearImGui Upgrade imgui to v1.89.7 2023-07-17 19:13:23 +03:00
imgui@c6e0284ac5 V2.2.0 (#189) 2023-09-10 13:24:33 +00:00
nix Bump haskell.nix (#86) 2021-09-08 16:19:57 +00:00
src Add support for disabled blocks (#196) 2024-02-20 19:20:46 +00:00
.gitignore Ignore imgui.ini (#29) 2021-02-05 20:22:26 +00:00
.gitmodules Initial work 2021-01-24 15:27:03 +00:00
cabal.project Fix sdl flag in cabal.project (#163) 2022-11-30 17:08:06 +00:00
ChangeLog.md V2.2.0 (#189) 2023-09-10 13:24:33 +00:00
dear-imgui.cabal Add support for SDL2 Renderer backend (#193) 2023-12-15 15:31:04 +02:00
default.nix Nix upgrades (#102) 2021-09-14 01:58:39 +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 Fix TabItem flags type (#183) 2023-07-20 16:42:11 +00:00
README.md Update README (#194) 2024-02-04 18:24:06 +00:00
shell.nix Add haskell-language-server to the dev shell (#34) 2021-02-06 15:43:26 +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 +opengl3

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

{-# language OverloadedStrings #-}

module Main ( main ) where

import DearImGui
import DearImGui.OpenGL3
import DearImGui.SDL
import DearImGui.SDL.OpenGL

import Graphics.GL
import SDL

import Control.Monad.Managed
import Control.Monad.IO.Class ()
import Control.Monad (when, unless)
import Control.Exception (bracket, bracket_)

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

  runManaged $ do
    -- Create a window using SDL; as we're using OpenGL, we enable OpenGL too
    window <- 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 window) glDeleteContext
    -- Create an ImGui context
    _ <- managed $ bracket createContext destroyContext

    -- Initialize ImGui's SDL2 backend
    managed_ $ bracket_ (sdl2InitForOpenGL window glContext) sdl2Shutdown
    -- Initialize ImGui's OpenGL backend
    managed_ $ bracket_ openGL3Init openGL3Shutdown

    liftIO $ mainLoop window

mainLoop :: Window -> IO ()
mainLoop window = unlessQuit $ do
  -- Tell ImGui we're starting a new frame
  openGL3NewFrame
  sdl2NewFrame
  newFrame

  -- Build the GUI
  withWindowOpen "Hello, ImGui!" $ do
    -- Add a text widget
    text "Hello, ImGui!"

    -- Add a button widget, and call 'putStrLn' when it's clicked
    button "Clickety Click" >>= \clicked ->
      when clicked $ putStrLn "Ow!"

  -- Show the ImGui demo window
  showDemoWindow

  -- Render
  glClear GL_COLOR_BUFFER_BIT
  render
  openGL3RenderDrawData =<< getDrawData

  glSwapWindow window
  mainLoop window
  where
  -- Process the event loop
  unlessQuit action = do
    shouldQuit <- gotQuitEvent
    unless shouldQuit action

  gotQuitEvent = do
    ev <- pollEventWithImGui

    case ev of
      Nothing ->
        return False
      Just event ->
        (isQuit event ||) <$> gotQuitEvent

  isQuit event =
    eventPayload event == QuitEvent

Hacking

If you would like to help dear-imgui, here's how you can get started.

The best path to development is using Nix. Once you have Nix installed (either in your operating system, or by running NixOS), you can enter a development shell:

$ nix-shell

You should now be in a bash shell where you can run cabal build all, cabal run readme, etc.

If you experience any difficulties, please don't hesistate to raise an issue.

Getting Help

Feel free to raise bugs, questions and feature requests on the GitHub issue tracker.

We have a Matrix room at #dear-imgui.hs:ocharles.org.uk.