Open thewoz opened 2 weeks ago
Why don’t you simply use resizable child windows?
I am open to any solution. What do you mean exactly?
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.
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;
}
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.
It's my fault. I checked and saw that I was on on an old docking branch (1.89.5).
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.
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;
}
(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();
}
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.
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 :)
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();
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.
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:
Minimal, Complete and Verifiable Example code: