From c7a694bce8e5da73b93f10dbcd85edc55161f619 Mon Sep 17 00:00:00 2001 From: Alexander Bondarenko <486682+dpwiz@users.noreply.github.com> Date: Sun, 12 Sep 2021 13:28:48 +0300 Subject: [PATCH] Add remaining BeginChild arguments as required (#93) Old behaviour with all default arguments is a special case to run some action scoped to a different child window. This now handled by `beginChildContext`/`withChildContext`. --- Main.hs | 2 +- src/DearImGui.hs | 54 +++++++++++++++++++++++++++++++++----------- src/DearImGui/Raw.hs | 45 ++++++++++++++++++++++++++++++++---- 3 files changed, 83 insertions(+), 18 deletions(-) diff --git a/Main.hs b/Main.hs index 9ca33bd..7094595 100644 --- a/Main.hs +++ b/Main.hs @@ -120,7 +120,7 @@ loop window checked color slider r pos size' selected tab1Ref tab2Ref = do progressBar 0.314 (Just "Pi") - beginChild "Child" + beginChild "Child" (ImVec2 0 0) True ImGuiWindowFlags_None beginCombo "Label" "Preview" >>= whenTrue do selectable "Testing 1" diff --git a/src/DearImGui.hs b/src/DearImGui.hs index d1aaedd..a96b3b6 100644 --- a/src/DearImGui.hs +++ b/src/DearImGui.hs @@ -71,6 +71,7 @@ module DearImGui -- ** Child Windows , withChild , withChildOpen + , withChildContext , beginChild , Raw.endChild @@ -350,25 +351,52 @@ fullscreenFlags = foldl' (.|.) zeroBits , ImGuiWindowFlags_NoTitleBar ] --- | Wraps @ImGui::BeginChild()@. -beginChild :: MonadIO m => String -> m Bool -beginChild name = liftIO do - withCString name Raw.beginChild --- | Child windows used for self-contained independent scrolling/clipping regions --- within a host window. Child windows can embed their own child. +-- | Begin a self-contained independent scrolling/clipping regions within a host window. +-- +-- Child windows can embed their own child. +-- +-- For each independent axis of @size@: +-- * ==0.0f: use remaining host window size +-- * >0.0f: fixed size +-- * <0.0f: use remaining window size minus abs(size) +-- +-- Each axis can use a different mode, e.g. @ImVec2 0 400@. +-- +-- @BeginChild()@ returns `False` to indicate the window is collapsed or fully clipped, so you may early out and omit submitting anything to the window. +-- +-- Always call a matching `endChild` for each `beginChild` call, regardless of its return value. +-- +-- Wraps @ImGui::BeginChild()@. +beginChild :: MonadIO m => String -> ImVec2 -> Bool -> ImGuiWindowFlags -> m Bool +beginChild name size border flags = liftIO do + withCString name \namePtr -> + with size \sizePtr -> + Raw.beginChild namePtr sizePtr (bool 0 1 border) flags + +-- | Action wrapper for child windows. -- -- Action will get 'False' if the child region is collapsed or fully clipped. -withChild :: MonadUnliftIO m => String -> (Bool -> m a) -> m a -withChild name = bracket (beginChild name) (const Raw.endChild) +withChild :: MonadUnliftIO m => String -> ImVec2 -> Bool -> ImGuiWindowFlags -> (Bool -> m a) -> m a +withChild name size border flags = bracket (beginChild name size border flags) (const Raw.endChild) --- | Child windows used for self-contained independent scrolling/clipping regions --- within a host window. Child windows can embed their own child. +-- | Action-skipping wrapper for child windows. -- -- Action will be skipped if the child region is collapsed or fully clipped. -withChildOpen :: MonadUnliftIO m => String -> m () -> m () -withChildOpen name action = - withChild name (`when` action) +withChildOpen :: MonadUnliftIO m => String -> ImVec2 -> Bool -> ImGuiWindowFlags -> m () -> m () +withChildOpen name size border flags action = + withChild name size border flags (`when` action) + +-- | Action wrapper to run in a context of another child window addressed by its name. +-- +-- Action will get 'False' if the child region is collapsed or fully clipped. +withChildContext :: MonadUnliftIO m => String -> (Bool -> m a) -> m a +withChildContext name action = + bracket + (liftIO $ withCString name Raw.beginChildContext) + (const Raw.endChild) + action + -- | Plain text. text :: MonadIO m => String -> m () diff --git a/src/DearImGui/Raw.hs b/src/DearImGui/Raw.hs index 99ad177..93e49e0 100644 --- a/src/DearImGui/Raw.hs +++ b/src/DearImGui/Raw.hs @@ -66,6 +66,7 @@ module DearImGui.Raw -- ** Child Windows , beginChild + , beginChildContext , endChild -- * Parameter stacks @@ -390,11 +391,47 @@ end = liftIO do [C.exp| void { End(); } |] --- | Wraps @ImGui::BeginChild()@. -beginChild :: (MonadIO m) => CString -> m Bool -beginChild namePtr = liftIO do - (0 /=) <$> [C.exp| bool { BeginChild($(char* namePtr)) } |] +-- | Begin a self-contained independent scrolling/clipping regions within a host window. +-- +-- Child windows can embed their own child. +-- +-- For each independent axis of @size@: +-- * ==0.0f: use remaining host window size +-- * >0.0f: fixed size +-- * <0.0f: use remaining window size minus abs(size) +-- +-- Each axis can use a different mode, e.g. @ImVec2 0 400@. +-- +-- @BeginChild()@ returns `False` to indicate the window is collapsed or fully clipped, so you may early out and omit submitting anything to the window. +-- +-- Always call a matching `endChild` for each `beginChild` call, regardless of its return value. +-- +-- Wraps @ImGui::BeginChild()@. +beginChild :: (MonadIO m) => CString -> Ptr ImVec2 -> CBool -> ImGuiWindowFlags -> m Bool +beginChild namePtr sizePtr border flags = liftIO do + (0 /=) <$> [C.exp| + bool { + BeginChild( + $(char* namePtr), + *$(ImVec2* sizePtr), + $(bool border), + $(ImGuiWindowFlags flags) + ) + } + |] +-- | Switch context to another child window by its ID +-- +-- Wraps @ImGui::BeginChild()@. +beginChildContext :: (MonadIO m) => CString -> m Bool +beginChildContext namePtr = liftIO do + (0 /=) <$> [C.exp| + bool { + BeginChild( + $(char* namePtr) + ) + } + |] -- | Wraps @ImGui::EndChild()@. endChild :: (MonadIO m) => m ()