Skip to content

Commit 4f9a552

Browse files
committed
Move everything to MonadIO
1 parent aa681fb commit 4f9a552

File tree

1 file changed

+114
-85
lines changed

1 file changed

+114
-85
lines changed

src/DearImGui.hs

Lines changed: 114 additions & 85 deletions
Original file line numberDiff line numberDiff line change
@@ -76,9 +76,10 @@ module DearImGui
7676
)
7777
where
7878

79+
import Control.Monad ( when )
80+
import Control.Monad.IO.Class ( MonadIO, liftIO )
7981
import Data.Bool
8082
import Data.StateVar
81-
import Control.Monad ( when )
8283
import Foreign
8384
import Foreign.C
8485
import qualified Language.C.Inline as C
@@ -103,37 +104,40 @@ newtype Context = Context (Ptr ())
103104

104105

105106
-- | Wraps @ImGui::CreateContext()@.
106-
createContext :: IO Context
107-
createContext =
107+
createContext :: MonadIO m => m Context
108+
createContext = liftIO do
108109
Context <$> [C.exp| void* { CreateContext() } |]
109110

110111

111112
-- | Wraps @ImGui::DestroyContext()@.
112-
destroyContext :: Context -> IO ()
113-
destroyContext (Context contextPtr) =
113+
destroyContext :: MonadIO m => Context -> m ()
114+
destroyContext (Context contextPtr) = liftIO do
114115
[C.exp| void { DestroyContext((ImGuiContext*)$(void* contextPtr)); } |]
115116

116117

117118
-- | Start a new Dear ImGui frame, you can submit any command from this point
118119
-- until 'render'/'endFrame'.
119120
--
120121
-- Wraps @ImGui::NewFrame()@.
121-
newFrame :: IO ()
122-
newFrame = [C.exp| void { ImGui::NewFrame(); } |]
122+
newFrame :: MonadIO m => m ()
123+
newFrame = liftIO do
124+
[C.exp| void { ImGui::NewFrame(); } |]
123125

124126

125127
-- | Ends the Dear ImGui frame. automatically called by 'render'. If you don't
126128
-- need to render data (skipping rendering) you may call 'endFrame' without
127129
-- 'render'... but you'll have wasted CPU already! If you don't need to render,
128130
-- better to not create any windows and not call 'newFrame' at all!
129-
endFrame :: IO ()
130-
endFrame = [C.exp| void { ImGui::EndFrame(); } |]
131+
endFrame :: MonadIO m => m ()
132+
endFrame = liftIO do
133+
[C.exp| void { ImGui::EndFrame(); } |]
131134

132135

133136
-- | Ends the Dear ImGui frame, finalize the draw data. You can then get call
134137
-- 'getDrawData'.
135-
render :: IO ()
136-
render = [C.exp| void { ImGui::Render(); } |]
138+
render :: MonadIO m => m ()
139+
render = liftIO do
140+
[C.exp| void { ImGui::Render(); } |]
137141

138142

139143
-- | Wraps @ImDrawData*@.
@@ -142,121 +146,136 @@ newtype DrawData = DrawData (Ptr ())
142146

143147
-- | Valid after 'render' and until the next call to 'newFrame'. This is what
144148
-- you have to render.
145-
getDrawData :: IO DrawData
146-
getDrawData = DrawData <$> [C.exp| void* { ImGui::GetDrawData() } |]
149+
getDrawData :: MonadIO m => m DrawData
150+
getDrawData = liftIO do
151+
DrawData <$> [C.exp| void* { ImGui::GetDrawData() } |]
147152

148153

149154
-- | Wraps @IMGUI_CHECKVERSION()@
150-
checkVersion :: IO ()
151-
checkVersion =
155+
checkVersion :: MonadIO m => m ()
156+
checkVersion = liftIO do
152157
[C.exp| void { IMGUI_CHECKVERSION(); } |]
153158

154159

155160
-- | Wraps @ImGui_ImplSDL2_InitForOpenGL@.
156-
sdl2InitForOpenGL :: Window -> GLContext -> IO ()
157-
sdl2InitForOpenGL (Window windowPtr) glContext =
161+
sdl2InitForOpenGL :: MonadIO m => Window -> GLContext -> m ()
162+
sdl2InitForOpenGL (Window windowPtr) glContext = liftIO do
158163
[C.exp| void { ImGui_ImplSDL2_InitForOpenGL((SDL_Window*)$(void* windowPtr), $(void* glContextPtr)); } |]
159164
where
160165
glContextPtr :: Ptr ()
161166
glContextPtr = unsafeCoerce glContext
162167

163168

164169
-- | Wraps @ImGui_ImplSDL2_NewFrame@.
165-
sdl2NewFrame :: Window -> IO ()
166-
sdl2NewFrame (Window windowPtr) =
170+
sdl2NewFrame :: MonadIO m => Window -> m ()
171+
sdl2NewFrame (Window windowPtr) = liftIO do
167172
[C.exp| void { ImGui_ImplSDL2_NewFrame((SDL_Window*)($(void* windowPtr))); } |]
168173

169174

170175
-- | Wraps @ImGui_ImplSDL2_Shutdown@.
171-
sdl2Shutdown :: IO ()
172-
sdl2Shutdown = [C.exp| void { ImGui_ImplSDL2_Shutdown(); } |]
176+
sdl2Shutdown :: MonadIO m => m ()
177+
sdl2Shutdown = liftIO do
178+
[C.exp| void { ImGui_ImplSDL2_Shutdown(); } |]
173179

174180

175181
-- | Call the SDL2 'pollEvent' function, while also dispatching the event to
176182
-- Dear ImGui. You should use this in your application instead of 'pollEvent'.
177-
pollEventWithImGui :: IO (Maybe Event)
178-
pollEventWithImGui = alloca \evPtr -> do
179-
pumpEvents
183+
pollEventWithImGui :: MonadIO m => m (Maybe Event)
184+
pollEventWithImGui = liftIO do
185+
alloca \evPtr -> do
186+
pumpEvents
180187

181-
-- We use NULL first to check if there's an event.
182-
nEvents <- Raw.peepEvents evPtr 1 Raw.SDL_PEEKEVENT Raw.SDL_FIRSTEVENT Raw.SDL_LASTEVENT
188+
-- We use NULL first to check if there's an event.
189+
nEvents <- Raw.peepEvents evPtr 1 Raw.SDL_PEEKEVENT Raw.SDL_FIRSTEVENT Raw.SDL_LASTEVENT
183190

184-
when (nEvents > 0) do
185-
let evPtr' = castPtr evPtr :: Ptr ()
186-
[C.exp| void { ImGui_ImplSDL2_ProcessEvent((SDL_Event*) $(void* evPtr')) } |]
191+
when (nEvents > 0) do
192+
let evPtr' = castPtr evPtr :: Ptr ()
193+
[C.exp| void { ImGui_ImplSDL2_ProcessEvent((SDL_Event*) $(void* evPtr')) } |]
187194

188-
pollEvent
195+
pollEvent
189196

190197

191198
-- | Wraps @ImGui_ImplOpenGL2_Init@.
192-
openGL2Init :: IO ()
193-
openGL2Init = [C.exp| void { ImGui_ImplOpenGL2_Init(); } |]
199+
openGL2Init :: MonadIO m => m ()
200+
openGL2Init = liftIO do
201+
[C.exp| void { ImGui_ImplOpenGL2_Init(); } |]
194202

195203

196204
-- | Wraps @ImGui_ImplOpenGL2_Shutdown@.
197-
openGL2Shutdown :: IO ()
198-
openGL2Shutdown = [C.exp| void { ImGui_ImplOpenGL2_Shutdown(); } |]
205+
openGL2Shutdown :: MonadIO m => m ()
206+
openGL2Shutdown = liftIO do
207+
[C.exp| void { ImGui_ImplOpenGL2_Shutdown(); } |]
199208

200209

201210
-- | Wraps @ImGui_ImplOpenGL2_NewFrame@.
202-
openGL2NewFrame :: IO ()
203-
openGL2NewFrame = [C.exp| void { ImGui_ImplOpenGL2_NewFrame(); } |]
211+
openGL2NewFrame :: MonadIO m => m ()
212+
openGL2NewFrame = liftIO do
213+
[C.exp| void { ImGui_ImplOpenGL2_NewFrame(); } |]
204214

205215

206216
-- | Wraps @ImGui_ImplOpenGL2_RenderDrawData@.
207-
openGL2RenderDrawData :: DrawData -> IO ()
208-
openGL2RenderDrawData (DrawData ptr) = [C.exp| void { ImGui_ImplOpenGL2_RenderDrawData((ImDrawData*) $( void* ptr )) } |]
217+
openGL2RenderDrawData :: MonadIO m => DrawData -> m ()
218+
openGL2RenderDrawData (DrawData ptr) = liftIO do
219+
[C.exp| void { ImGui_ImplOpenGL2_RenderDrawData((ImDrawData*) $( void* ptr )) } |]
209220

210221

211222
-- | Create demo window. Demonstrate most ImGui features. Call this to learn
212223
-- about the library! Try to make it always available in your application!
213-
showDemoWindow :: IO ()
214-
showDemoWindow = [C.exp| void { ImGui::ShowDemoWindow(); } |]
224+
showDemoWindow :: MonadIO m => m ()
225+
showDemoWindow = liftIO do
226+
[C.exp| void { ImGui::ShowDemoWindow(); } |]
215227

216228

217229
-- | Create Metrics/Debugger window. Display Dear ImGui internals: windows, draw
218230
-- commands, various internal state, etc.
219-
showMetricsWindow :: IO ()
220-
showMetricsWindow = [C.exp| void { ImGui::ShowMetricsWindow(); } |]
231+
showMetricsWindow :: MonadIO m => m ()
232+
showMetricsWindow = liftIO do
233+
[C.exp| void { ImGui::ShowMetricsWindow(); } |]
221234

222235

223236
-- | Create About window. display Dear ImGui version, credits and build/system
224237
-- information.
225-
showAboutWindow :: IO ()
226-
showAboutWindow = [C.exp| void { ShowAboutWindow(); } |]
238+
showAboutWindow :: MonadIO m => m ()
239+
showAboutWindow = liftIO do
240+
[C.exp| void { ShowAboutWindow(); } |]
227241

228242

229243
-- | Add basic help/info block (not a window): how to manipulate ImGui as a
230244
-- end-user (mouse/keyboard controls).
231-
showUserGuide :: IO ()
232-
showUserGuide = [C.exp| void { ShowUserGuide() } |]
245+
showUserGuide :: MonadIO m => m ()
246+
showUserGuide = liftIO do
247+
[C.exp| void { ShowUserGuide() } |]
233248

234249

235250
-- | Get the compiled version string e.g. "1.80 WIP" (essentially the value for
236251
-- @IMGUI_VERSION@ from the compiled version of @imgui.cpp@).
237-
getVersion :: IO String
238-
getVersion = peekCString =<< [C.exp| const char* { GetVersion() } |]
252+
getVersion :: MonadIO m => m String
253+
getVersion = liftIO do
254+
peekCString =<< [C.exp| const char* { GetVersion() } |]
239255

240256

241257
-- | New, recommended style (default).
242258
--
243259
-- Wraps @ImGui::StyleColorsDark()@.
244-
styleColorsDark :: IO ()
245-
styleColorsDark = [C.exp| void { StyleColorsDark(); } |]
260+
styleColorsDark :: MonadIO m => m ()
261+
styleColorsDark = liftIO do
262+
[C.exp| void { StyleColorsDark(); } |]
246263

247264

248265
-- | Best used with borders and a custom, thicker font.
249266
--
250267
-- Wraps @ImGui::StyleColorsLight()@.
251-
styleColorsLight :: IO ()
252-
styleColorsLight = [C.exp| void { StyleColorsLight(); } |]
268+
styleColorsLight :: MonadIO m => m ()
269+
styleColorsLight = liftIO do
270+
[C.exp| void { StyleColorsLight(); } |]
253271

254272

255273
-- | Classic ImGui style.
256274
--
257275
-- Wraps @ImGui::StyleColorsClasic()@.
258-
styleColorsClassic :: IO ()
259-
styleColorsClassic = [C.exp| void { StyleColorsClassic(); } |]
276+
styleColorsClassic :: MonadIO m => m ()
277+
styleColorsClassic = liftIO do
278+
[C.exp| void { StyleColorsClassic(); } |]
260279

261280

262281
-- | Push window to the stack and start appending to it.
@@ -266,53 +285,59 @@ styleColorsClassic = [C.exp| void { StyleColorsClassic(); } |]
266285
-- matching 'end' for each 'begin' call, regardless of its return value!
267286
--
268287
-- Wraps @ImGui::Begin()@.
269-
begin :: String -> IO Bool
270-
begin name = withCString name \namePtr ->
271-
(1 ==) <$> [C.exp| bool { ImGui::Begin($(char* namePtr)) } |]
288+
begin :: MonadIO m => String -> m Bool
289+
begin name = liftIO do
290+
withCString name \namePtr ->
291+
(1 ==) <$> [C.exp| bool { ImGui::Begin($(char* namePtr)) } |]
272292

273293

274294
-- | Pop window from the stack.
275295
--
276296
-- Wraps @ImGui::End()@.
277-
end :: IO ()
278-
end = [C.exp| void { ImGui::End(); } |]
297+
end :: MonadIO m => m ()
298+
end = liftIO do
299+
[C.exp| void { ImGui::End(); } |]
279300

280301

281302
-- | Formatted text.
282303
--
283304
-- Wraps @ImGui::Text()@.
284-
text :: String -> IO ()
285-
text t = withCString t \textPtr ->
286-
[C.exp| void { Text($(char* textPtr)) } |]
305+
text :: MonadIO m => String -> m ()
306+
text t = liftIO do
307+
withCString t \textPtr ->
308+
[C.exp| void { Text($(char* textPtr)) } |]
287309

288310

289311
-- | A button. Returns 'True' when clicked.
290312
--
291313
-- Wraps @ImGui::Button()@.
292-
button :: String -> IO Bool
293-
button label = withCString label \labelPtr ->
294-
(1 ==) <$> [C.exp| bool { Button($(char* labelPtr)) } |]
314+
button :: MonadIO m => String -> m Bool
315+
button label = liftIO do
316+
withCString label \labelPtr ->
317+
(1 ==) <$> [C.exp| bool { Button($(char* labelPtr)) } |]
295318

296319

297320
-- | Button with @FramePadding=(0,0)@ to easily embed within text.
298321
--
299322
-- Wraps @ImGui::SmallButton()@.
300-
smallButton :: String -> IO Bool
301-
smallButton label = withCString label \labelPtr ->
302-
(1 ==) <$> [C.exp| bool { SmallButton($(char* labelPtr)) } |]
323+
smallButton :: MonadIO m => String -> m Bool
324+
smallButton label = liftIO do
325+
withCString label \labelPtr ->
326+
(1 ==) <$> [C.exp| bool { SmallButton($(char* labelPtr)) } |]
303327

304328

305329
-- | Square button with an arrow shape.
306330
--
307331
-- Wraps @ImGui::ArrowButton()@.
308-
arrowButton :: String -> ImGuiDir -> IO Bool
309-
arrowButton strId (ImGuiDir dir) = withCString strId \strIdPtr ->
310-
(1 ==) <$> [C.exp| bool { ArrowButton($(char* strIdPtr), $(int dir)) } |]
332+
arrowButton :: MonadIO m => String -> ImGuiDir -> m Bool
333+
arrowButton strId (ImGuiDir dir) = liftIO do
334+
withCString strId \strIdPtr ->
335+
(1 ==) <$> [C.exp| bool { ArrowButton($(char* strIdPtr), $(int dir)) } |]
311336

312337

313338
-- | Wraps @ImGui::Checkbox()@.
314-
checkbox :: (HasSetter ref Bool, HasGetter ref Bool) => String -> ref -> IO Bool
315-
checkbox label ref = do
339+
checkbox :: (HasSetter ref Bool, HasGetter ref Bool, MonadIO m) => String -> ref -> m Bool
340+
checkbox label ref = liftIO do
316341
currentValue <- get ref
317342
with (bool 0 1 currentValue :: CBool) \boolPtr -> do
318343
changed <- withCString label \labelPtr ->
@@ -324,18 +349,20 @@ checkbox label ref = do
324349
return changed
325350

326351

327-
progressBar :: Float -> Maybe String -> IO ()
328-
progressBar progress overlay = withCStringOrNull overlay \overlayPtr ->
329-
[C.exp| void { ProgressBar($(float c'progress), ImVec2(-FLT_MIN, 0), $(char* overlayPtr)) } |]
352+
progressBar :: MonadIO m => Float -> Maybe String -> m ()
353+
progressBar progress overlay = liftIO do
354+
withCStringOrNull overlay \overlayPtr ->
355+
[C.exp| void { ProgressBar($(float c'progress), ImVec2(-FLT_MIN, 0), $(char* overlayPtr)) } |]
330356
where
331357
c'progress :: CFloat
332358
c'progress = realToFrac progress
333359

334360

335361
-- | Draw a small circle + keep the cursor on the same line. Advance cursor x
336362
-- position by 'getTreeNodeToLabelSpacing', same distance that 'treeNode' uses.
337-
bullet :: IO ()
338-
bullet = [C.exp| void { Bullet() } |]
363+
bullet :: MonadIO m => m ()
364+
bullet = liftIO do
365+
[C.exp| void { Bullet() } |]
339366

340367

341368
-- | Begin creating a combo box with a given label and preview value.
@@ -344,8 +371,8 @@ bullet = [C.exp| void { Bullet() } |]
344371
-- the contents of the combo box - for example, by calling 'selectable'.
345372
--
346373
-- Wraps @ImGui::BeginCombo()@.
347-
beginCombo :: String -> String -> IO Bool
348-
beginCombo label previewValue =
374+
beginCombo :: MonadIO m => String -> String -> m Bool
375+
beginCombo label previewValue = liftIO $
349376
withCString label \labelPtr ->
350377
withCString previewValue \previewValuePtr ->
351378
(1 ==) <$> [C.exp| bool { BeginCombo($(char* labelPtr), $(char* previewValuePtr)) } |]
@@ -354,14 +381,16 @@ beginCombo label previewValue =
354381
-- | Only call 'endCombo' if 'beginCombon' returns 'True'!
355382
--
356383
-- Wraps @ImGui::EndCombo()@.
357-
endCombo :: IO ()
358-
endCombo = [C.exp| void { EndCombo() } |]
384+
endCombo :: MonadIO m => m ()
385+
endCombo = liftIO do
386+
[C.exp| void { EndCombo() } |]
359387

360388

361389
-- | Wraps @ImGui::Selectable()@.
362-
selectable :: String -> IO Bool
363-
selectable label = withCString label \labelPtr ->
364-
(1 == ) <$> [C.exp| bool { Selectable($(char* labelPtr)) } |]
390+
selectable :: MonadIO m => String -> m Bool
391+
selectable label = liftIO do
392+
withCString label \labelPtr ->
393+
(1 == ) <$> [C.exp| bool { Selectable($(char* labelPtr)) } |]
365394

366395

367396
-- | A cardinal direction.

0 commit comments

Comments
 (0)