mirror of
https://github.com/Drezil/dear-imgui.hs.git
synced 2024-11-25 18:17:00 +00:00
3c1d381c14
Shave a few allocations and pointer-chasing due to conversion.
142 lines
3.5 KiB
Haskell
142 lines
3.5 KiB
Haskell
{-# language BlockArguments #-}
|
|
{-# language LambdaCase #-}
|
|
{-# language OverloadedStrings #-}
|
|
{-# language RecordWildCards #-}
|
|
|
|
module Main ( main ) where
|
|
|
|
import Control.Exception
|
|
import Control.Monad
|
|
import Control.Monad.IO.Class
|
|
import Control.Monad.Managed
|
|
import Data.Bits ((.|.))
|
|
import Data.IORef
|
|
import Data.List (sortBy)
|
|
import Data.Foldable (traverse_)
|
|
import Data.Text (Text, pack)
|
|
|
|
import DearImGui
|
|
import DearImGui.OpenGL2
|
|
import DearImGui.GLFW
|
|
import DearImGui.GLFW.OpenGL
|
|
import Graphics.GL
|
|
import Graphics.UI.GLFW (Window)
|
|
import qualified Graphics.UI.GLFW as GLFW
|
|
|
|
main :: IO ()
|
|
main = do
|
|
initialised <- GLFW.init
|
|
unless initialised $ error "GLFW init failed"
|
|
|
|
runManaged $ do
|
|
mwin <- managed $ bracket
|
|
(GLFW.createWindow 800 600 "Hello, Dear ImGui!" Nothing Nothing)
|
|
(maybe (return ()) GLFW.destroyWindow)
|
|
case mwin of
|
|
Just win -> do
|
|
liftIO $ do
|
|
GLFW.makeContextCurrent (Just win)
|
|
GLFW.swapInterval 1
|
|
|
|
-- Create an ImGui context
|
|
_ <- managed $ bracket createContext destroyContext
|
|
|
|
-- Initialize ImGui's GLFW backend
|
|
_ <- managed_ $ bracket_ (glfwInitForOpenGL win True) glfwShutdown
|
|
|
|
-- Initialize ImGui's OpenGL backend
|
|
_ <- managed_ $ bracket_ openGL2Init openGL2Shutdown
|
|
|
|
tableRef <- liftIO $ newIORef
|
|
[ (1, "foo")
|
|
, (2, "bar")
|
|
, (3, "baz")
|
|
, (10, "spam")
|
|
, (11, "spam")
|
|
, (12, "spam")
|
|
]
|
|
|
|
liftIO $ mainLoop win tableRef
|
|
Nothing -> do
|
|
error "GLFW createWindow failed"
|
|
|
|
GLFW.terminate
|
|
|
|
mainLoop :: Window -> IORef [(Integer, Text)] -> IO ()
|
|
mainLoop win tableRef = do
|
|
-- Process the event loop
|
|
GLFW.pollEvents
|
|
close <- GLFW.windowShouldClose win
|
|
unless close do
|
|
|
|
-- Tell ImGui we're starting a new frame
|
|
openGL2NewFrame
|
|
glfwNewFrame
|
|
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
|
|
clicking <- button "Clickety Click"
|
|
when clicking $
|
|
putStrLn "Ow!"
|
|
itemContextPopup do
|
|
text "pop!"
|
|
button "ok" >>= \clicked ->
|
|
when clicked $
|
|
closeCurrentPopup
|
|
|
|
newLine
|
|
|
|
mkTable tableRef
|
|
|
|
-- Render
|
|
glClear GL_COLOR_BUFFER_BIT
|
|
|
|
render
|
|
openGL2RenderDrawData =<< getDrawData
|
|
|
|
GLFW.swapBuffers win
|
|
|
|
mainLoop win tableRef
|
|
|
|
mkTable :: IORef [(Integer, Text)] -> IO ()
|
|
mkTable tableRef =
|
|
withTableOpen sortable "MyTable" 3 $ do
|
|
tableSetupColumn "Hello"
|
|
tableSetupColumnWith defTableColumnOptions "World"
|
|
|
|
withSortableTable \isDirty sortSpecs ->
|
|
when (isDirty && not (null sortSpecs)) do
|
|
-- XXX: do your sorting & cache it. Dont sort every frame.
|
|
putStrLn "So dirty!"
|
|
print sortSpecs
|
|
modifyIORef' tableRef . sortBy $
|
|
foldMap mkCompare sortSpecs
|
|
|
|
tableHeadersRow
|
|
readIORef tableRef >>=
|
|
traverse_ \(ix, title) -> do
|
|
tableNextRow
|
|
tableNextColumn $ text (pack $ show ix)
|
|
tableNextColumn $ text title
|
|
tableNextColumn $ void (button "♥")
|
|
where
|
|
mkCompare TableSortingSpecs{..} a b =
|
|
let
|
|
dir = if tableSortingReverse then flip else id
|
|
in
|
|
case tableSortingColumn of
|
|
0 -> dir compare (fst a) (fst b)
|
|
1 -> dir compare (snd a) (snd b)
|
|
_ -> EQ
|
|
|
|
sortable = defTableOptions
|
|
{ tableFlags =
|
|
ImGuiTableFlags_Sortable .|.
|
|
ImGuiTableFlags_SortMulti
|
|
}
|