Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Proposal fix for ImGui::TextWrapped() and ImGui::Separator(), ImGui::SliderXXX inside Nodes #298

Open
pthom opened this issue Jun 23, 2024 · 1 comment

Comments

@pthom
Copy link

pthom commented Jun 23, 2024

By default, ImGui::TextWrapped() and ImGui::Separator(), ImGui::SliderXXX
will not work in a Node because they will not respect the node's bounds.
Instead, they will use the bounds of the whole window.

I worked on a fix which changes the node below, which uses ImGui::Separator, Slider, and TextWrapped

from this:

image

to this:

image

You can find details on how I did it here:
pthom@44ee0e6

This implementation is not meant to be final, as it is implemented mainly as a workaround inside Dear ImGui Bundle. But it might be a source of inspiration. Please ping me if you are interested.

I studied a solution to fix: we have to fix several elements in the current window data:

  • WorkRect.Max.x: the maximum x value of the WorkRect
    (used by ImGui::Separator())
  • ContentRegionRect.Max.x: the maximum x value of the ContentRegionRect
    (used by ImGui::TextWrapped())
  • DC.ItemWidth: the width of the current item
    (used by SliderFloat, and all items that may require a prior call
    to ImGui::SetNextItemWidth())

Implementation note:

  • WorkRect.Max.x and ContentRegionRect.Max.x are set to:
    nodeSize.x + nodePos.x - ImGui::GetStyle().WindowPadding.x
  • DC_ItemWidth is set to:
    nodeSize.x - ImGui::GetStyle().WindowPadding.x * 2.f - largestLabelSize.x
    (where largestLabelSize is the size of the largest label we want to handle by default:
    it consists of 4 wide characters)
@pthom
Copy link
Author

pthom commented Jun 23, 2024

Here is the test code I used:

#include "imgui-node-editor/imgui_node_editor.h"
#include "imgui_internal.h"

// Specific to ImGui Bundle (replace this by another runner if desired)
#include "imgui_md_wrapper.h"
#include "immapp/immapp.h"

namespace ed = ax::NodeEditor;



int main()
{
   // Specific to ImGui Bundle (replace this by another runner if desired)
    HelloImGui::RunnerParams runnerParams;

    runnerParams.callbacks.ShowGui = [&]()
    {
       // This whole function is using only ImGui and ImGui Node editor
        ed::Begin("My Editor");

        ed::BeginNode(1);

        // Test ImGui::Separator: it should use the actual node width.
        ImGui::TextWrapped("Below is a separator and a separator text. They should use the actual node width.");
        ImGui::Separator();
        ImGui::SeparatorText("Hello");

        //
        // A dummy button, to artificially set the node width
        //
        static ImVec2 dummyButtonSize(100, 20);
        ImGui::SeparatorText("Dummy Button");
        ImGui::TextWrapped(R"(
This is a dummy button, to artificially set the node width.
Below it is a fixed width slider, which enables to set this button's width.
)");
        ImGui::Button("Dummy", dummyButtonSize);
        // With a fixed width slider, so that we can set the node width.
        ImGui::SetNextItemWidth(200.f);
        ImGui::SliderFloat("width", &dummyButtonSize.x, 0, 700);

        //
        // Test ImGui::TextWrapped: it should use the actual node width.
        //
        // Notes:
        // * If using the slider to make the node wider, the wrapped text with will adapt.
        // * After that if you try to reduce the node width, The wrapped text with will not reduce
        //   (This is because the node caches its previous size, and the wrapped text will use it.
        //   This is okay.)
        ImGui::SeparatorText("Test TextWrapped");
        ImGui::TextWrapped(R"(
Note:
    * If using the slider to make the node wider, the wrapped text with will adapt.
    * After that if you try to reduce the node width, The wrapped text with will not reduce (This is because the node caches its previous size, and the wrapped text will use it. This is okay.)
)");

        //
        // Test ImGui::SliderFloat: it should use the actual node width.
        //
        ImGui::SeparatorText("Slider with default width");
        ImGui::TextWrapped("Below is a slider using the default width. It should be the same width as the node (There is a hard code max label size, which corresponds to 4 wide characters)." );
        ImGui::TextWrapped("Move this slider to see the node width change." );
        ImGui::SliderFloat("width##2", &dummyButtonSize.x, 0, 700);

        ed::EndNode();

        ed::End();

    };

    // Specific to ImGui Bundle (replace this by another runner if desired)
    ImmApp::AddOnsParams addOnsParams;
    addOnsParams.withNodeEditor = true;

    // Change the node editor config to force ImGui to use the node width.
    addOnsParams.withNodeEditorConfig = ed::Config();
    addOnsParams.withNodeEditorConfig->ForceWindowContentWidthToNodeWidth = true;

    addOnsParams.withMarkdown = true;

    ImmApp::Run(runnerParams, addOnsParams);
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant