@@ -76,9 +76,10 @@ module DearImGui
76
76
)
77
77
where
78
78
79
+ import Control.Monad ( when )
80
+ import Control.Monad.IO.Class ( MonadIO , liftIO )
79
81
import Data.Bool
80
82
import Data.StateVar
81
- import Control.Monad ( when )
82
83
import Foreign
83
84
import Foreign.C
84
85
import qualified Language.C.Inline as C
@@ -103,37 +104,40 @@ newtype Context = Context (Ptr ())
103
104
104
105
105
106
-- | Wraps @ImGui::CreateContext()@.
106
- createContext :: IO Context
107
- createContext =
107
+ createContext :: MonadIO m => m Context
108
+ createContext = liftIO do
108
109
Context <$> [C. exp | void* { CreateContext() } |]
109
110
110
111
111
112
-- | Wraps @ImGui::DestroyContext()@.
112
- destroyContext :: Context -> IO ()
113
- destroyContext (Context contextPtr) =
113
+ destroyContext :: MonadIO m => Context -> m ()
114
+ destroyContext (Context contextPtr) = liftIO do
114
115
[C. exp | void { DestroyContext((ImGuiContext*)$(void* contextPtr)); } |]
115
116
116
117
117
118
-- | Start a new Dear ImGui frame, you can submit any command from this point
118
119
-- until 'render'/'endFrame'.
119
120
--
120
121
-- 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(); } |]
123
125
124
126
125
127
-- | Ends the Dear ImGui frame. automatically called by 'render'. If you don't
126
128
-- need to render data (skipping rendering) you may call 'endFrame' without
127
129
-- 'render'... but you'll have wasted CPU already! If you don't need to render,
128
130
-- 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(); } |]
131
134
132
135
133
136
-- | Ends the Dear ImGui frame, finalize the draw data. You can then get call
134
137
-- '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(); } |]
137
141
138
142
139
143
-- | Wraps @ImDrawData*@.
@@ -142,121 +146,136 @@ newtype DrawData = DrawData (Ptr ())
142
146
143
147
-- | Valid after 'render' and until the next call to 'newFrame'. This is what
144
148
-- 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() } |]
147
152
148
153
149
154
-- | Wraps @IMGUI_CHECKVERSION()@
150
- checkVersion :: IO ()
151
- checkVersion =
155
+ checkVersion :: MonadIO m => m ()
156
+ checkVersion = liftIO do
152
157
[C. exp | void { IMGUI_CHECKVERSION(); } |]
153
158
154
159
155
160
-- | 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
158
163
[C. exp | void { ImGui_ImplSDL2_InitForOpenGL((SDL_Window*)$(void* windowPtr), $(void* glContextPtr)); } |]
159
164
where
160
165
glContextPtr :: Ptr ()
161
166
glContextPtr = unsafeCoerce glContext
162
167
163
168
164
169
-- | Wraps @ImGui_ImplSDL2_NewFrame@.
165
- sdl2NewFrame :: Window -> IO ()
166
- sdl2NewFrame (Window windowPtr) =
170
+ sdl2NewFrame :: MonadIO m => Window -> m ()
171
+ sdl2NewFrame (Window windowPtr) = liftIO do
167
172
[C. exp | void { ImGui_ImplSDL2_NewFrame((SDL_Window*)($(void* windowPtr))); } |]
168
173
169
174
170
175
-- | 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(); } |]
173
179
174
180
175
181
-- | Call the SDL2 'pollEvent' function, while also dispatching the event to
176
182
-- 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
180
187
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
183
190
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')) } |]
187
194
188
- pollEvent
195
+ pollEvent
189
196
190
197
191
198
-- | 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(); } |]
194
202
195
203
196
204
-- | 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(); } |]
199
208
200
209
201
210
-- | 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(); } |]
204
214
205
215
206
216
-- | 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 )) } |]
209
220
210
221
211
222
-- | Create demo window. Demonstrate most ImGui features. Call this to learn
212
223
-- 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(); } |]
215
227
216
228
217
229
-- | Create Metrics/Debugger window. Display Dear ImGui internals: windows, draw
218
230
-- 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(); } |]
221
234
222
235
223
236
-- | Create About window. display Dear ImGui version, credits and build/system
224
237
-- information.
225
- showAboutWindow :: IO ()
226
- showAboutWindow = [C. exp | void { ShowAboutWindow(); } |]
238
+ showAboutWindow :: MonadIO m => m ()
239
+ showAboutWindow = liftIO do
240
+ [C. exp | void { ShowAboutWindow(); } |]
227
241
228
242
229
243
-- | Add basic help/info block (not a window): how to manipulate ImGui as a
230
244
-- 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() } |]
233
248
234
249
235
250
-- | Get the compiled version string e.g. "1.80 WIP" (essentially the value for
236
251
-- @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() } |]
239
255
240
256
241
257
-- | New, recommended style (default).
242
258
--
243
259
-- 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(); } |]
246
263
247
264
248
265
-- | Best used with borders and a custom, thicker font.
249
266
--
250
267
-- 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(); } |]
253
271
254
272
255
273
-- | Classic ImGui style.
256
274
--
257
275
-- 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(); } |]
260
279
261
280
262
281
-- | Push window to the stack and start appending to it.
@@ -266,53 +285,59 @@ styleColorsClassic = [C.exp| void { StyleColorsClassic(); } |]
266
285
-- matching 'end' for each 'begin' call, regardless of its return value!
267
286
--
268
287
-- 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)) } |]
272
292
273
293
274
294
-- | Pop window from the stack.
275
295
--
276
296
-- 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(); } |]
279
300
280
301
281
302
-- | Formatted text.
282
303
--
283
304
-- 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)) } |]
287
309
288
310
289
311
-- | A button. Returns 'True' when clicked.
290
312
--
291
313
-- 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)) } |]
295
318
296
319
297
320
-- | Button with @FramePadding=(0,0)@ to easily embed within text.
298
321
--
299
322
-- 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)) } |]
303
327
304
328
305
329
-- | Square button with an arrow shape.
306
330
--
307
331
-- 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)) } |]
311
336
312
337
313
338
-- | 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
316
341
currentValue <- get ref
317
342
with (bool 0 1 currentValue :: CBool ) \ boolPtr -> do
318
343
changed <- withCString label \ labelPtr ->
@@ -324,18 +349,20 @@ checkbox label ref = do
324
349
return changed
325
350
326
351
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)) } |]
330
356
where
331
357
c'progress :: CFloat
332
358
c'progress = realToFrac progress
333
359
334
360
335
361
-- | Draw a small circle + keep the cursor on the same line. Advance cursor x
336
362
-- 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() } |]
339
366
340
367
341
368
-- | Begin creating a combo box with a given label and preview value.
@@ -344,8 +371,8 @@ bullet = [C.exp| void { Bullet() } |]
344
371
-- the contents of the combo box - for example, by calling 'selectable'.
345
372
--
346
373
-- 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 $
349
376
withCString label \ labelPtr ->
350
377
withCString previewValue \ previewValuePtr ->
351
378
(1 == ) <$> [C. exp | bool { BeginCombo($(char* labelPtr), $(char* previewValuePtr)) } |]
@@ -354,14 +381,16 @@ beginCombo label previewValue =
354
381
-- | Only call 'endCombo' if 'beginCombon' returns 'True'!
355
382
--
356
383
-- 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() } |]
359
387
360
388
361
389
-- | 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)) } |]
365
394
366
395
367
396
-- | A cardinal direction.
0 commit comments