ocornut / imgui

Dear ImGui: Bloat-free Graphical User interface for C++ with minimal dependencies
MIT License
57.74k stars 9.9k forks source link

Splitters weird padding #7706

Open thewoz opened 2 weeks ago

thewoz commented 2 weeks ago

Version/Branch of Dear ImGui:

Version 1.90.5, Branch: docking

Back-ends:

ImGui_ImplGlfw ImGui_ImplOpenGL3

Compiler, OS:

macOS

Full config/build information:

No response

Details:

My Issue/Question:

Most likely I will ask the usual idiotic question. This issue is part of issue https://github.com/ocornut/imgui/issues/7631

Anyway I'm trying to implement an interface with splitters but I can't get the border around the splitter off. I tried playing with padding but couldn't get it off completely.

I started from the code found here: #319

Screenshots/Video:

Screenshot 2024-06-18 at 14 09 48

Minimal, Complete and Verifiable Example code:

#include <cstdio>
#include <cstdlib>

#include <iostream>

#include <glad/glad.h>

#include <GLFW/glfw3.h>

#define IMGUI_DEFINE_MATH_OPERATORS
#include <imgui/imgui.hpp>

bool Splitter(bool split_vertically, float thickness, float* size1, float* size2, float min_size1, float min_size2, float splitter_long_axis_size = -1.0f)
{
    using namespace ImGui;
    ImGuiContext& g = *GImGui;
    ImGuiWindow* window = g.CurrentWindow;
    ImGuiID id = window->GetID("##Splitter");
    ImRect bb;
    bb.Min = window->DC.CursorPos + (split_vertically ? ImVec2(*size1, 0.0f) : ImVec2(0.0f, *size1));
    bb.Max = bb.Min + CalcItemSize(split_vertically ? ImVec2(thickness, splitter_long_axis_size) : ImVec2(splitter_long_axis_size, thickness), 0.0f, 0.0f);

    bool status = SplitterBehavior(bb, id, split_vertically ? ImGuiAxis_X : ImGuiAxis_Y, size1, size2, min_size1, min_size2, 0.0f);

    return status;

}

static void glfwErrorCallback(int error, const char * description) {
    fprintf(stderr, "GLFW error (%d): %s\n", error, description);
}

int main(int argc, const char * argv[]) {

  if(!glfwInit()) {
    fprintf(stderr, "GLFW init error\n");
    exit(EXIT_FAILURE);
  }

#if __APPLE__
  const char* glsl_version = "#version 100";
  glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
  glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 2);
  glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
  glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);
#else
  const char* glsl_version = "#version 130";
  glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
  glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 0);
#endif

  glfwSetErrorCallback(glfwErrorCallback);

  GLFWwindow * window = glfwCreateWindow(640, 480, "ImGui", NULL, NULL);

  if(!window) {
    glfwTerminate();
    abort();
  }

  glfwMakeContextCurrent(window);

  glfwSwapInterval(1);

  if(!gladLoadGLLoader((GLADloadproc) glfwGetProcAddress)) abort();

  IMGUI_CHECKVERSION();
  ImGui::CreateContext();

  ImGui_ImplGlfw_InitForOpenGL(window, true);
  ImGui_ImplOpenGL3_Init(glsl_version);

  ImGui::StyleColorsDark();

  while(!glfwWindowShouldClose(window)) {

    glfwPollEvents();

    ImGui_ImplOpenGL3_NewFrame();
    ImGui_ImplGlfw_NewFrame();
    ImGui::NewFrame();

    ImGuiViewport * viewport = ImGui::GetMainViewport();
    ImGui::SetNextWindowPos(viewport->WorkPos);
    ImGui::SetNextWindowSize(viewport->WorkSize);
    ImGui::SetNextWindowViewport(viewport->ID);

     ImGuiWindowFlags windowFlags = ImGuiWindowFlags_NoDocking | ImGuiWindowFlags_NoCollapse | ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoDecoration | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoNavFocus | ImGuiWindowFlags_NoMove;

    ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(0.0f, 0.0f));
    ImGui::Begin("MainWindow", NULL, windowFlags);
    ImGui::PopStyleVar();

    if(ImGui::BeginMainMenuBar()) {
      if(ImGui::BeginMenu("File")) {
        ImGui::MenuItem("About", NULL, false, true);
        ImGui::EndMenu();
      }
      ImGui::EndMainMenuBar();
    }

    float heightSideBar = ImGui::GetFrameHeight();

    if(ImGui::BeginViewportSideBar("StatusBar", viewport, ImGuiDir_Down, heightSideBar, ImGuiWindowFlags_NoScrollbar | ImGuiWindowFlags_NoSavedSettings | ImGuiWindowFlags_MenuBar)) {
      if(ImGui::BeginMenuBar()) {
        ImGui::Text("Status Bar:");
        ImGui::EndMenuBar();
      }
      ImGui::End();
    }

    static float totalY = ImGui::GetContentRegionAvail().y - heightSideBar;
    static float totalX = ImGui::GetContentRegionAvail().x;

    static float w1 = totalX * 2 / 3.0;
    static float w2 = totalX - w1;

    // create top container green
    ImGui::PushStyleColor(ImGuiCol_ChildBg, ImColor(0,255,0).Value);
    ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(0.0f, 0.0f));
    ImGui::BeginChild("1", ImVec2(0, totalY), false);
    ImGui::PopStyleVar();
    ImGui::PopStyleColor();

    Splitter(true, 4.0f, &w1, &w2, 50, 50);

    // left part blue
    ImGui::PushStyleColor(ImGuiCol_ChildBg, ImColor(0,0,255).Value);
    ImGui::BeginChild("2", ImVec2(w1, 0), true);
    ImGui::PopStyleColor();
    ImGui::EndChild();

    ImGui::SameLine();

    // right part red
    ImGui::PushStyleColor(ImGuiCol_ChildBg, ImColor(255,0,0).Value);
    ImGui::BeginChild("3", ImVec2(0, 0), true);
    ImGui::PopStyleColor();
    ImGui::EndChild();

    ImGui::EndChild();

    ImGui::End();

    ImGui::Render();
    int displayW, displayH;
    glfwGetFramebufferSize(window, &displayW, &displayH);
    glViewport(0, 0, displayW, displayH);
    static ImVec4 clearColor = ImColor(60, 55, 15);
    glClearColor(clearColor.x, clearColor.y, clearColor.z, clearColor.w);
    glClear(GL_COLOR_BUFFER_BIT);
    ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData());

    glfwSwapBuffers(window);

  }

  ImGui_ImplOpenGL3_Shutdown();
  ImGui_ImplGlfw_Shutdown();
  ImGui::DestroyContext();

  glfwDestroyWindow(window);
  glfwTerminate();

  return 0;

}
ocornut commented 2 weeks ago

Why don’t you simply use resizable child windows?

thewoz commented 2 weeks ago

I am open to any solution. What do you mean exactly?

ocornut commented 2 weeks ago

See Demo>Layout>Child Windows See Demo>Examples>Simple Layout See list of ImGuiChildFlags values eg ImGuiChildFlags_ResizeX

In the previous topic I already suggested two times to use BeginChild() with resizing flags and you have not reacted to that.

thewoz commented 2 weeks ago

Hi, It's not that I didn't want to use ImGuiChildFlags_ResizeX and/or ImGuiChildFlags_ResizeY but being on the docking branch I realized that they are not defined. So I was stuck in solving the problem by looking for other solutions. Sorry about that.

Now I switched to the master branch so that I could give it a try.

Here I am putting the latest version of the code, which seems to me to be a very good end point.

https://github.com/ocornut/imgui/assets/907951/28b7318c-1e43-41f2-88df-6e24ea6c0f73

The only strange things that remain and that I see in the video are:

I hope I can solve the problem, but right now I'm stuck.

#include <cstdio>
#include <cstdlib>

#include <iostream>

#include <glad/glad.h>

#include <GLFW/glfw3.h>

#define IMGUI_DEFINE_MATH_OPERATORS
#include <imgui/imgui.hpp>

static void glfwErrorCallback(int error, const char * description) {
    fprintf(stderr, "GLFW error (%d): %s\n", error, description);
}

int main(int argc, const char * argv[]) {

  if(!glfwInit()) {
    fprintf(stderr, "GLFW init error\n");
    exit(EXIT_FAILURE);
  }

#if __APPLE__
  const char* glsl_version = "#version 100";
  glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
  glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 2);
  glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
  glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);
#else
  const char* glsl_version = "#version 130";
  glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
  glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 0);
#endif

  glfwSetErrorCallback(glfwErrorCallback);

  GLFWwindow * window = glfwCreateWindow(640, 480, "ImGui", NULL, NULL);

  if(!window) {
    glfwTerminate();
    abort();
  }

  glfwMakeContextCurrent(window);

  glfwSwapInterval(1);

  if(!gladLoadGLLoader((GLADloadproc) glfwGetProcAddress)) abort();

  IMGUI_CHECKVERSION();
  ImGui::CreateContext();

  ImGui_ImplGlfw_InitForOpenGL(window, true);
  ImGui_ImplOpenGL3_Init(glsl_version);

  ImGui::StyleColorsDark();

  while(!glfwWindowShouldClose(window)) {

    glfwPollEvents();

    ImGui_ImplOpenGL3_NewFrame();
    ImGui_ImplGlfw_NewFrame();
    ImGui::NewFrame();

    ImGuiViewport * viewport = ImGui::GetMainViewport();
    ImGui::SetNextWindowPos(viewport->WorkPos);
    ImGui::SetNextWindowSize(viewport->WorkSize);

    ImGuiWindowFlags windowFlags = ImGuiWindowFlags_NoCollapse | ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoDecoration | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoNavFocus | ImGuiWindowFlags_NoMove ;

    ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(0.0f, 0.0f));
    ImGui::Begin("MainWindow", NULL, windowFlags);
    ImGui::PopStyleVar();

    if(ImGui::BeginMainMenuBar()) {
      if(ImGui::BeginMenu("File")) {
        ImGui::MenuItem("About", NULL, false, true);
        ImGui::EndMenu();
      }
      ImGui::EndMainMenuBar();
    }

    float heightSideBar = ImGui::GetFrameHeight();

    if(ImGui::BeginViewportSideBar("StatusBar", viewport, ImGuiDir_Down, heightSideBar, ImGuiWindowFlags_NoScrollbar | ImGuiWindowFlags_NoSavedSettings | ImGuiWindowFlags_MenuBar)) {
      if(ImGui::BeginMenuBar()) {
        ImGui::Text("Status Bar:");
        ImGui::EndMenuBar();
      }
      ImGui::End();
    }

    static float totalX = ImGui::GetContentRegionAvail().x;
    static float totalY = ImGui::GetContentRegionAvail().y - heightSideBar;

    static float h1 = totalY * 2 / 3.0;
    static float w1 = totalX * 2 / 3.0;

    // container blue-red
    ImGui::BeginChild("container", ImVec2(0, h1), ImGuiChildFlags_ResizeY);

      // left part blue
      ImGui::PushStyleColor(ImGuiCol_ChildBg, ImColor(0,0,255).Value);
      ImGui::BeginChild("blue", ImVec2(w1, 0), ImGuiChildFlags_ResizeX);
      ImGui::PopStyleColor();
      ImGui::EndChild();

      ImGui::SameLine();

      // right part red
      ImGui::PushStyleColor(ImGuiCol_ChildBg, ImColor(255,0,0).Value);
      ImGui::BeginChild("red", ImVec2(0, 0));
      ImGui::PopStyleColor();
      ImGui::EndChild();

    ImGui::EndChild();

    // right part green
    ImGui::PushStyleColor(ImGuiCol_ChildBg, ImColor(0,255,0).Value);
    ImGui::BeginChild("green", ImVec2(0, 0));
    ImGui::PopStyleColor();
    ImGui::EndChild();

    ImGui::End();

    ImGui::Render();
    int displayW, displayH;
    glfwGetFramebufferSize(window, &displayW, &displayH);
    glViewport(0, 0, displayW, displayH);
    static ImVec4 clearColor = ImColor(60, 55, 15);
    glClearColor(clearColor.x, clearColor.y, clearColor.z, clearColor.w);
    glClear(GL_COLOR_BUFFER_BIT);
    ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData());

    glfwSwapBuffers(window);

  }

  ImGui_ImplOpenGL3_Shutdown();
  ImGui_ImplGlfw_Shutdown();
  ImGui::DestroyContext();

  glfwDestroyWindow(window);
  glfwTerminate();

  return 0;

}
GamingMinds-DanielC commented 2 weeks ago

Hi, It's not that I didn't want to use ImGuiChildFlags_ResizeX and/or ImGuiChildFlags_ResizeY but being on the docking branch I realized that they are not defined. So I was stuck in solving the problem by looking for other solutions. Sorry about that.

That's strange. These flags are in docking for quite some time now. They were introduced in master in 1.90.0 (8 months ago) and got merged into docking around the same time.

thewoz commented 2 weeks ago

It's my fault. I checked and saw that I was on on an old docking branch (1.89.5).

thewoz commented 1 week ago

I am continuing to try to understand the problem. I think it is related to the size of the border.

I see this issue #7541 I did tests with ImGuiChildFlags_Border and ImGuiChildFlags_FrameStyle Adding it here:

// container blue-red
 ImGui::BeginChild("container", ImVec2(0, h1), ImGuiChildFlags_ResizeY);

this is whit the ImGuiChildFlags_Border flag

https://github.com/ocornut/imgui/assets/907951/fff175e9-dba4-4a68-84a3-45c22b7dd508

this is whit the ImGuiChildFlags_FrameStyle flag

https://github.com/ocornut/imgui/assets/907951/de35f2c2-4ba7-45b8-88bf-d8e626b1a04a

In both cases I'm able to move the separator under the blue part (I couldn't do it before) However, in these solutions I have strange margins and strange glitch during resizing, plus the size of the vertical separator is still larger than the horizontal one.

thewoz commented 6 days ago

Hello everyone, I realized that I can control the thickness of the Splitters by adding this line of code.

ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(5.0f, 5.0f));

I still can't drag the Splitters from the blue side of the layout

https://github.com/ocornut/imgui/assets/907951/dac205b1-610d-4071-b9b4-5bef41bb6ba9

#include <cstdio>
#include <cstdlib>

#include <iostream>

#include <glad/glad.h>

#include <GLFW/glfw3.h>

#define IMGUI_DEFINE_MATH_OPERATORS
#include <imgui/imgui.hpp>

static void glfwErrorCallback(int error, const char * description) {
    fprintf(stderr, "GLFW error (%d): %s\n", error, description);
}

int main(int argc, const char * argv[]) {

  if(!glfwInit()) {
    fprintf(stderr, "GLFW init error\n");
    exit(EXIT_FAILURE);
  }

#if __APPLE__
  const char* glsl_version = "#version 100";
  glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
  glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 2);
  glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
  glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);
#else
  const char* glsl_version = "#version 130";
  glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
  glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 0);
#endif

  glfwSetErrorCallback(glfwErrorCallback);

  GLFWwindow * window = glfwCreateWindow(640, 480, "ImGui", NULL, NULL);

  if(!window) {
    glfwTerminate();
    abort();
  }

  glfwMakeContextCurrent(window);

  glfwSwapInterval(1);

  if(!gladLoadGLLoader((GLADloadproc) glfwGetProcAddress)) abort();

  IMGUI_CHECKVERSION();
  ImGui::CreateContext();

  ImGui_ImplGlfw_InitForOpenGL(window, true);
  ImGui_ImplOpenGL3_Init(glsl_version);

  ImGui::StyleColorsDark();

  while(!glfwWindowShouldClose(window)) {

    glfwPollEvents();

    ImGui_ImplOpenGL3_NewFrame();
    ImGui_ImplGlfw_NewFrame();
    ImGui::NewFrame();

    ImGuiViewport * viewport = ImGui::GetMainViewport();
    ImGui::SetNextWindowPos(viewport->WorkPos);
    ImGui::SetNextWindowSize(viewport->WorkSize);

    ImGuiWindowFlags windowFlags = ImGuiWindowFlags_NoCollapse | ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoDecoration | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoNavFocus | ImGuiWindowFlags_NoMove ;

    ImGui::PushStyleColor(ImGuiCol_WindowBg, ImColor(255,255,0).Value);
    ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(0.0f, 0.0f));
    ImGui::Begin("MainWindow", NULL, windowFlags);
    ImGui::PopStyleVar();

    ImGui::PopStyleColor();

    if(ImGui::BeginMainMenuBar()) {
      if(ImGui::BeginMenu("File")) {
        ImGui::MenuItem("About", NULL, false, true);
        ImGui::EndMenu();
      }
      ImGui::EndMainMenuBar();
    }

    float heightSideBar = ImGui::GetFrameHeight();

    if(ImGui::BeginViewportSideBar("StatusBar", viewport, ImGuiDir_Down, heightSideBar, ImGuiWindowFlags_NoScrollbar | ImGuiWindowFlags_NoSavedSettings | ImGuiWindowFlags_MenuBar)) {
      if(ImGui::BeginMenuBar()) {
        ImGui::Text("Status Bar:");
        ImGui::EndMenuBar();
      }
      ImGui::End();
    }

    float totalX = ImGui::GetContentRegionAvail().x;
    float totalY = ImGui::GetContentRegionAvail().y - heightSideBar;

    float w1 = (totalX / 3.0) * 2.0;
    float h1 = (totalY / 3.0) * 2.0;

    // container blue-red
    ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(5.0f, 5.0f));
    ImGui::PushStyleColor(ImGuiCol_ChildBg, ImColor(0,255,255).Value);
    ImGui::BeginChild("container", ImVec2(0, h1), ImGuiChildFlags_ResizeY);
    ImGui::PopStyleColor();

      // left part blue
      ImGui::PushStyleColor(ImGuiCol_ChildBg, ImColor(0,0,255).Value);
      ImGui::BeginChild("blue", ImVec2(w1, 0), ImGuiChildFlags_ResizeX);
      ImGui::PopStyleColor();
      ImGui::EndChild();

      ImGui::SameLine();

      // right part red
      ImGui::PushStyleColor(ImGuiCol_ChildBg, ImColor(255,0,0).Value);
      ImGui::BeginChild("red", ImVec2(0, 0));
      ImGui::PopStyleColor();
      ImGui::EndChild();

    ImGui::EndChild();
    ImGui::PopStyleVar();

    // right part green
    ImGui::PushStyleColor(ImGuiCol_ChildBg, ImColor(0,255,0).Value);
    ImGui::BeginChild("green", ImVec2(0, 0));
    ImGui::PopStyleColor();
    ImGui::EndChild();

    ImGui::End();

    ImGui::Render();
    int displayW, displayH;
    glfwGetFramebufferSize(window, &displayW, &displayH);
    glViewport(0, 0, displayW, displayH);
    static ImVec4 clearColor = ImColor(60, 55, 15);
    glClearColor(clearColor.x, clearColor.y, clearColor.z, clearColor.w);
    glClear(GL_COLOR_BUFFER_BIT);
    ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData());

    glfwSwapBuffers(window);

  }

  ImGui_ImplOpenGL3_Shutdown();
  ImGui_ImplGlfw_Shutdown();
  ImGui::DestroyContext();

  glfwDestroyWindow(window);
  glfwTerminate();

  return 0;

}
ocornut commented 6 days ago

(When pasting repro feel free to ignore the app init/closure, in that situation we only the middle part that I can past in any existing example.)

There seems to be various issues and this isn't as trivial as I expected it to be :( So maybe I mislead you suggesting to use child ResizeX/ResizeY feature here, I'm sorry:

If you move the bottom part to the top it's a more natural fit:

{
    ImGuiWindowFlags windowFlags = 0;

    ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(0.0f, 0.0f));
    ImGui::Begin("MainWindow", NULL, windowFlags);
    ImGui::PopStyleVar();

    ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(5.0f, 5.0f));

    // top part green
    ImGui::PushStyleColor(ImGuiCol_ChildBg, ImVec4(0.0f, 1.0f, 0.0f, 0.5f));
    ImGui::BeginChild("green", ImVec2(0, 0), ImGuiChildFlags_Border | ImGuiChildFlags_ResizeY);
    ImGui::PopStyleColor();
    ImGui::EndChild();

    // left part blue
    ImGui::PushStyleColor(ImGuiCol_ChildBg, ImVec4(0.0f, 0.0f, 1.0f, 0.5f));
    ImGui::BeginChild("blue", ImVec2(0, 0), ImGuiChildFlags_ResizeX | ImGuiChildFlags_Border);
    ImGui::PopStyleColor();
    ImGui::EndChild();

    ImGui::SameLine();

    // right part red
    ImGui::PushStyleColor(ImGuiCol_ChildBg, ImVec4(1.0f, 0.0f, 0.0f, 0.5f));
    ImGui::BeginChild("red", ImVec2(0, 0), ImGuiChildFlags_Border);
    ImGui::PopStyleColor();
    ImGui::EndChild();

    ImGui::PopStyleVar();

    ImGui::End();
}

image

However it bothers me that clicking on horizontal line creates a small glitch in upper part (investigating this now).

However this logic need an extra container (as you found out) if you move top to bottom:

{
    ImGuiWindowFlags windowFlags = 0;

    ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(0.0f, 0.0f));
    ImGui::Begin("MainWindow", NULL, windowFlags);
    ImGui::PopStyleVar();

    ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(5.0f, 0.0f));

    // container blue-red
    ImGui::PushStyleColor(ImGuiCol_ChildBg, ImVec4(0.0f, 1.0f, 1.0f, 0.5f));
    ImGui::BeginChild("container", ImVec2(0, 0), ImGuiChildFlags_ResizeY | ImGuiChildFlags_Border);
    ImGui::PopStyleColor();

    // left part blue
    ImGui::PushStyleColor(ImGuiCol_ChildBg, ImVec4(0.0f, 0.0f, 1.0f, 0.5f));
    ImGui::BeginChild("blue", ImVec2(0, 0), ImGuiChildFlags_ResizeX | ImGuiChildFlags_Border);
    ImGui::PopStyleColor();
    ImGui::EndChild();

    ImGui::SameLine();

    // right part red
    ImGui::PushStyleColor(ImGuiCol_ChildBg, ImVec4(1.0f, 0.0f, 0.0f, 0.5f));
    ImGui::BeginChild("red", ImVec2(0, 0), ImGuiChildFlags_Border);
    ImGui::PopStyleColor();
    ImGui::EndChild();

    ImGui::EndChild();
    ImGui::PopStyleVar();

    // bottom part green
    ImGui::PushStyleColor(ImGuiCol_ChildBg, ImVec4(0.0f, 1.0f, 0.0f, 0.5f));
    ImGui::BeginChild("green", ImVec2(0, 0), ImGuiChildFlags_Border);
    ImGui::PopStyleColor();
    ImGui::EndChild();

    ImGui::End();
}

I may investigate further but it may be more sane that you use DockBuilder as you did initially in #7631. The only thing that you cannot easily achieve is to automatically adjust the bottom node height to have a min or max (also I personally don't think that would be good user experience to do so). But https://github.com/ocornut/imgui/issues/7631#issuecomment-2137187654 may work.

ocornut commented 6 days ago

I have pushed a fix 77d582f for the glitch I mentioned. Just doing this would repro the glitch when clicking on the resizing border:

ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(0.0f, 0.0f));
ImGui::Begin("MainWindow");
ImGui::PopStyleVar();

ImGui::PushStyleColor(ImGuiCol_ChildBg, ImVec4(0.0f, 1.0f, 0.0f, 0.5f));
ImGui::BeginChild("green", ImVec2(0, 0), ImGuiChildFlags_Border | ImGuiChildFlags_ResizeY);
ImGui::PopStyleColor();
ImGui::EndChild();

ImGui::End();

This part at least is fixed :)

thewoz commented 5 days ago

Hi, @ocornut thanks for the reply and for the suggestions.

I include here the shortened version of the code.

    ImGuiWindowFlags windowFlags = ImGuiWindowFlags_NoCollapse | ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoDecoration | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoNavFocus | ImGuiWindowFlags_NoMove ;

    ImGui::PushStyleColor(ImGuiCol_WindowBg, ImColor(255,255,0).Value);
    ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(0.0f, 0.0f));
    ImGui::Begin("MainWindow", NULL, windowFlags);
    ImGui::PopStyleVar();
    ImGui::PopStyleColor();

    ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(5.0f, 5.0f));

    // container blue-red
    ImGui::PushStyleColor(ImGuiCol_ChildBg, ImColor(0,255,255).Value);
    ImGui::BeginChild("container", ImVec2(0, 0), ImGuiChildFlags_ResizeY | ImGuiChildFlags_Border);
    ImGui::PopStyleColor();

    // left part blue
    ImGui::PushStyleColor(ImGuiCol_ChildBg, ImColor(0,0,255).Value);
    ImGui::BeginChild("blue", ImVec2(0, 0), ImGuiChildFlags_ResizeX | ImGuiChildFlags_Border| ImGuiChildFlags_AlwaysUseWindowPadding);
    ImGui::PopStyleColor();
    ImGui::EndChild();

    ImGui::SameLine();

    // right part red
    ImGui::PushStyleColor(ImGuiCol_ChildBg, ImColor(255,0,0).Value);
    ImGui::BeginChild("red", ImVec2(0, 0), ImGuiChildFlags_Border| ImGuiChildFlags_AlwaysUseWindowPadding);
    ImGui::PopStyleColor();
    ImGui::EndChild();

    ImGui::EndChild();

    ImGui::PopStyleVar();

    // bottom part green
    ImGui::PushStyleColor(ImGuiCol_ChildBg, ImColor(0,255,0).Value);
    ImGui::BeginChild("green", ImVec2(0, 0), ImGuiChildFlags_Border| ImGuiChildFlags_AlwaysUseWindowPadding);
    ImGui::PopStyleColor();
    ImGui::EndChild();

    ImGui::End();

Screenshot 2024-06-28 at 15 32 05

This way everything works. The processing of drag the horizontal splitter is smooth. However if I try to remove the light blue margin by adjusting the padding in this way:

    // container blue-red
    ImGui::PushStyleColor(ImGuiCol_ChildBg, ImColor(0,255,255).Value);
    ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(0.0f, 0.0f));
    ImGui::BeginChild("container", ImVec2(0, 0), ImGuiChildFlags_ResizeY | ImGuiChildFlags_Border);
    ImGui::PopStyleColor();
    ImGui::PopStyleVar();

the drag of the splitter under the blue part stop to work.

https://github.com/ocornut/imgui/assets/907951/163a4972-b1cc-4ef5-bcc0-e92b43797616

If I change the border size in this way:

    // container blue-red
    ImGui::PushStyleColor(ImGuiCol_ChildBg, ImColor(0,255,255).Value);
    ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(0.0f, 0.0f));
    ImGui::PushStyleVar(ImGuiStyleVar_ChildBorderSize, 5);
    ImGui::BeginChild("container", ImVec2(0, 0), ImGuiChildFlags_ResizeY | ImGuiChildFlags_Border);
    ImGui::PopStyleColor();
    ImGui::PopStyleVar();
    ImGui::PopStyleVar();

the drag of the splitter starts working again but I end up with unwanted margins.

https://github.com/ocornut/imgui/assets/907951/2dafdc7d-9731-4f94-82c1-8e71924d3f7a

I try to figure out how to react.

I can think about going back to the docking branch. But on the one hand, I had gotten a kick out of trying to make this work.