Code Monkey home page Code Monkey logo

Comments (10)

ocornut avatar ocornut commented on June 28, 2024

Why don’t you simply use resizable child windows?

from imgui.

thewoz avatar thewoz commented on June 28, 2024

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

from imgui.

ocornut avatar ocornut commented on June 28, 2024

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.

from imgui.

thewoz avatar thewoz commented on June 28, 2024

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.

Screen.Recording.2024-06-18.at.17.31.11.mov

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

  • the different size of the splitters between the vertical one and the horizontal one;
  • the fact that I can't resize using the splitters under the blue part

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;
  
}

from imgui.

GamingMinds-DanielC avatar GamingMinds-DanielC commented on June 28, 2024

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.

from imgui.

thewoz avatar thewoz commented on June 28, 2024

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

from imgui.

thewoz avatar thewoz commented on June 28, 2024

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

bb.mov

this is whit the ImGuiChildFlags_FrameStyle flag

aa.mov

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.

from imgui.

thewoz avatar thewoz commented on June 28, 2024

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

test.mov
#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;
  
}

from imgui.

ocornut avatar ocornut commented on June 28, 2024

(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 #7631 (comment) may work.

from imgui.

ocornut avatar ocornut commented on June 28, 2024

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 :)

from imgui.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.