keid-ui-dearimgui-0.1.5.0: src/Render/ImGui/Widget.hs
module Render.ImGui.Widget
( separator
, sliderFloat
, sliderFloat2
, sliderAngle
, sliderUVec2
, button
, text
, render_
) where
import RIO
-- import Engine.Types (HKD)
-- import Data.These (These(..))
-- import Data.These.Combinators (justHere, justThere)
import DearImGui.Internal.Text (withCString)
import DearImGui.Raw qualified
import Engine.ReactiveBanana.Widget (Widget(..), Widget', draw_)
import Foreign (withForeignPtr, mallocForeignPtr)
import Foreign qualified
import Foreign.C.Types (CFloat(..))
import Geomancy (Vec2, UVec2)
import Reactive.Banana qualified as RB
import Reactive.Banana.Frameworks qualified as RBF
import DearImGui qualified
separator :: Widget Void ()
separator = draw_ DearImGui.Raw.separator
sliderFloat
:: MonadIO m
=> Text
-> Float
-> (Float, Float) -- TODO: use Behavior somehow
-> m (Widget' Float)
sliderFloat label initial (start, end) = liftIO do
(ah, fire) <- RBF.newAddHandler
ref <- mallocForeignPtr
withForeignPtr ref \ptr ->
Foreign.poke ptr (CFloat initial)
pure Widget
{ plug = do
event <- RBF.fromAddHandler ah
beh <- RB.stepper initial event
pure (event, beh)
, draw =
withCString label \labelPtr -> -- FIXME: make this static
withForeignPtr ref \refPtr -> do
changed <- DearImGui.Raw.sliderFloat
labelPtr
refPtr
(CFloat start)
(CFloat end)
Foreign.nullPtr
when changed do
CFloat current <- Foreign.peek refPtr
fire current
}
sliderFloat2
:: MonadIO m
=> Text
-> Vec2
-> (Float, Float)
-> m (Widget' Vec2)
sliderFloat2 label initial (start, end) = liftIO do
(ah, fire) <- RBF.newAddHandler
ref <- mallocForeignPtr
withForeignPtr ref \ptr ->
Foreign.poke ptr initial
pure Widget
{ plug = do
event <- RBF.fromAddHandler ah
beh <- RB.stepper initial event
pure (event, beh)
, draw =
withCString label \labelPtr -> -- FIXME: make this static
withForeignPtr ref \refPtr -> do
changed <- DearImGui.Raw.sliderFloat2
labelPtr
(Foreign.castPtr refPtr)
(CFloat start)
(CFloat end)
Foreign.nullPtr
when changed do
current <- Foreign.peek refPtr
fire current
}
sliderAngle
:: MonadIO m
=> Text
-> Float
-> (Float, Float)
-> m (Widget' Float)
sliderAngle label initial (start, end) = liftIO do
(ah, fire) <- RBF.newAddHandler
ref <- mallocForeignPtr
withForeignPtr ref \ptr ->
Foreign.poke ptr (CFloat initial)
pure Widget
{ plug = do
event <- RBF.fromAddHandler ah
beh <- RB.stepper initial event
pure (event, beh)
, draw =
withCString label \labelPtr -> -- FIXME: make this static
withForeignPtr ref \refPtr -> do
changed <- DearImGui.Raw.sliderAngle
labelPtr
refPtr
(CFloat start)
(CFloat end)
Foreign.nullPtr
DearImGui.Raw.ImGuiSliderFlags_None
when changed do
CFloat current <- Foreign.peek refPtr
fire current
}
sliderUVec2
:: MonadIO m
=> Text
-> UVec2
-> (Word32, Word32)
-> m (Widget' UVec2)
sliderUVec2 label initial (start, end) = liftIO do
(ah, fire) <- RBF.newAddHandler
ref <- mallocForeignPtr
withForeignPtr ref \ptr ->
Foreign.poke ptr initial
pure Widget
{ plug = do
event <- RBF.fromAddHandler ah
beh <- RB.stepper initial event
pure (event, beh)
, draw =
withCString label \labelPtr -> -- FIXME: make this static
withForeignPtr ref \refPtr -> do
changed <- DearImGui.Raw.sliderInt2
labelPtr
(Foreign.castPtr refPtr)
(fromIntegral start)
(fromIntegral end)
Foreign.nullPtr
DearImGui.Raw.ImGuiSliderFlags_None
when changed do
current <- Foreign.peek refPtr
fire current
}
button
:: MonadIO m
=> Text
-> m (Widget' ())
button label = liftIO do
(ah, fire) <- RBF.newAddHandler
pure Widget
{ plug = do
event <- RBF.fromAddHandler ah
pure (event, pure ())
, draw =
withCString label \labelPtr -> do
clicked <- DearImGui.Raw.button labelPtr
when clicked do
fire ()
}
text :: RB.Event Text -> RBF.MomentIO (Widget Void ())
text bodyE = render_ bodyE DearImGui.text
-- | Lift rendering fuction into 'Event' handler and wrap in a 'Widget'.
render_ :: RB.Event a -> (a -> IO ()) -> RBF.MomentIO (Widget Void ())
render_ srcE f = do
drawer <- newIORef $ pure ()
RBF.reactimate $ srcE <&> writeIORef drawer . f
pure $ draw_ (join $ readIORef drawer)