Giter Club home page Giter Club logo

Comments (4)

ocornut avatar ocornut commented on September 7, 2024

I would like to figure out how to automatically adjust the height of the window so that everything is flush.

That might be contradictory with making the bottom part a docking node, aka you cannot expect user to resize this section while making it automatically resizing at all time.

Suggestion 1: We don't have enough information about your setup, but if the setup use a Dockspace() currently you could technically change the vertical split to use BeginChild() with ImGuiChildFlags_ResizeY, however I realize that a rather annoying change as makes the code/logic change based on a seemingly innocuous behavior change.

Suggestion 2: It may be more natural that you directly poke into the dock node where that timeline is docked by finding the ImGuiDockNode* and writing to node->SizeRef.y preferably at the beginning of the frame.

(It's also expected that other constraints in place may prevent that exact value from being full-filed, namely if e.g. the total available height is too small, but that's probably something you'd want)

from imgui.

thewoz avatar thewoz commented on September 7, 2024

hi @ocornut
you are absolutely right!
I have not given enough information about the setup step and my request actually seems contradictory.

Sorry about that!

My setup, as in the attached photo, consists of three parts.

  • A central display part.
  • A column on the right with the list of program parameters
  • A Sequencer at the bottom for displaying keyframes.

Screenshot 2024-05-29 at 11 50 41

I also attach a small snippet of the code.

To be clearer, rather than automatically adjusting the height of the bottom part, I would like to put limits on its height. That is, that it cannot be larger than a certain amount. I.e., that it cannot be larger than the contents inside it.

Is there then a way me put these limits and to calculate the size of the content inside it?

    ImGui::Begin("MainWindow", NULL, window_flags);
    ImGui::PopStyleVar();

    float height = ImGui::GetFrameHeight();
    
    if(ImGui::BeginMenuBar()) {
      
      if(ImGui::BeginMenu("Menu")) {
        ImGui::MenuItem("Main menu bar", NULL, false, true);
        ImGui::EndMenu();
      }
      ImGui::EndMenuBar();
      
    }

    if(ImGui::BeginViewportSideBar("StatusBar", viewport, ImGuiDir_Down, height, window_flags)) {
        if (ImGui::BeginMenuBar()) {
            ImGui::Text("status bar");
            ImGui::EndMenuBar();
        }
        ImGui::End();
    }
    
    ImGuiID mainDockSpaceId = ImGui::GetID("MainDockSpace");
    const ImVec2 dockspace_size = ImGui::GetContentRegionAvail();
    ImGui::DockSpace(mainDockSpaceId, ImVec2(0.0f, 0.0f), dockspace_flags);

    ImGuiWindowClass window_class;
    window_class.DockNodeFlagsOverrideSet = ImGuiDockNodeFlags_NoTabBar;
    
    ImGui::SetNextWindowClass(&window_class);
    ImGui::Begin("Down", &show_another_window, ImGuiWindowFlags_NoCollapse | ImGuiWindowFlags_NoTitleBar);
    if(ImGui::BeginNeoSequencer("Sequencer", &currentFrame, &minFrame, &maxFrame)) {
      if(ImGui::BeginNeoGroup("A", &showKeyframes)) { ImGui::EndNeoGroup(); }
      if(ImGui::BeginNeoGroup("B", &showKeyframes)) { ImGui::EndNeoGroup(); }
      if(ImGui::BeginNeoGroup("C", &showKeyframes)) { ImGui::EndNeoGroup(); }
      if(ImGui::BeginNeoGroup("D", &showKeyframes)) { ImGui::EndNeoGroup(); }
      if(ImGui::BeginNeoGroup("E", &showKeyframes)) { ImGui::EndNeoGroup(); }
      ImGui::EndNeoSequencer();
    }
    ImGui::End();
    
    ImGui::SetNextWindowClass(&window_class);
    ImGui::Begin("Left", NULL, ImGuiWindowFlags_NoCollapse | ImGuiWindowFlags_NoTitleBar);
    GLuint texture;
    glGenTextures( 1, &texture );
    glBindTexture( GL_TEXTURE_2D, texture );
    glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
    glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
    glPixelStorei( GL_UNPACK_ROW_LENGTH, 0 );
    glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, image.cols, image.rows, 0, GL_RGBA, GL_UNSIGNED_BYTE, image.data );
    ImGui::Image( reinterpret_cast<void*>( static_cast<intptr_t>( texture ) ), ImVec2( image.cols, image.rows ) );
    ImGui::End();
    
    ImGui::SetNextWindowClass(&window_class);
    ImGui::Begin("Right", NULL, ImGuiWindowFlags_NoCollapse | ImGuiWindowFlags_NoTitleBar);
    if(ImGui::CollapsingHeader("A")){ }
    if(ImGui::CollapsingHeader("B")){ }
    if(ImGui::CollapsingHeader("C")){ }
    if(ImGui::CollapsingHeader("D")){ }
    if(ImGui::CollapsingHeader("E")){ }
    ImGui::End();
    
    static bool sFirstFrame = true;
    if(sFirstFrame) {
      
      sFirstFrame = false;
      
      ImGui::DockBuilderRemoveNode(mainDockSpaceId);
      ImGui::DockBuilderAddNode(mainDockSpaceId, ImGuiDockNodeFlags_None);
      ImGui::DockBuilderSetNodeSize(mainDockSpaceId, dockspace_size);

      ImGuiID dock_id_up;
      ImGuiID dock_id_down;
      
      ImGuiID dock_id_left;
      ImGuiID dock_id_right;

      ImGui::DockBuilderSplitNode(mainDockSpaceId, ImGuiDir_Up, 0.5f, &dock_id_up, &dock_id_down);

      ImGui::DockBuilderSplitNode(dock_id_up, ImGuiDir_Right, 0.5f, &dock_id_right, &dock_id_left);
      
      ImGui::DockBuilderDockWindow("Down", dock_id_down);
      ImGui::DockBuilderDockWindow("Left", dock_id_left);
      ImGui::DockBuilderDockWindow("Right", dock_id_right);
      
      ImGui::DockBuilderFinish(mainDockSpaceId);
      
    }

    ImGui::End();

    ImGui::Render();

from imgui.

ocornut avatar ocornut commented on September 7, 2024

To be clearer, rather than automatically adjusting the height of the bottom part, I would like to put limits on its height. That is, that it cannot be larger than a certain amount. I.e., that it cannot be larger than the contents inside it.

Sizing constraints are currently not supported for docking nodes (#4228, but also technically #6326, #2849).

Some early work I did for potential support for toolbars might help, see code #2648, namely those lines:

        node->WantLockSizeOnce = true;
        node->Size[toolbar_axis_perp] = node->SizeRef[toolbar_axis_perp] = TOOLBAR_SIZE_WHEN_DOCKED;

But generally I think this is not easy to achieve and currently not worth investigating further, considering your need doesn't seem that important (as user can resize).

As mentioned in my first message, another workaround would be to use a manual splitter #319 or two BeginChild() with the top one using ImGuiChildFlags_ResizeY and a constraint on the top window.

from imgui.

thewoz avatar thewoz commented on September 7, 2024

hi @ocornut ,
thanks for the support!

I thought that for my case the best thing is to use a manual splitter as you suggest.
I wrote some code (which I attach) but I can't fix two issues:

  • I can't completely remove the space/border in the top part. As you can see there is still some green.
  • When I press on the window the yellow part covers my status bar
test.mov

what am I doing wrong?
thank you very much

#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);
    return SplitterBehavior(bb, id, split_vertically ? ImGuiAxis_X : ImGuiAxis_Y, size1, size2, min_size1, min_size2, 0.0f);
}

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

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

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

  // Decide GL+GLSL versions
#if __APPLE__
  // GL 3.2 + GLSL 150
  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);  // 3.2+ only
  glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);            // Required on Mac
#else
  // GL 3.0 + GLSL 130
  const char* glsl_version = "#version 130";
  glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
  glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 0);
  //glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);  // 3.2+ only
  //glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);            // 3.0+ only
#endif

  //Set GLFW's error callback function
  glfwSetErrorCallback(glfwErrorCallback);

  //GLFW creates a window and its OpenGL context with the next function
  GLFWwindow * window = glfwCreateWindow(640, 480, "Idra", NULL, NULL);

  if(!window) {
    std::cerr << "GLFW failed to create a window and/or OpenGL context :(";
    glfwTerminate();
    exit(0);
  }

  //Window creation was successful. Continue
  glfwMakeContextCurrent(window);
  glfwSwapInterval(1); // Enable vsync

  if(!gladLoadGLLoader((GLADloadproc) glfwGetProcAddress)) {
    fprintf(stderr, "Failed to initialize GLAD\n");
    abort();
  }

  // Setup Dear ImGui context
  IMGUI_CHECKVERSION();
  ImGui::CreateContext();
  //ImGuiIO& io = ImGui::GetIO(); (void)io;
  ImGui::GetIO().ConfigFlags |= ImGuiConfigFlags_DockingEnable;

  ImGui_ImplGlfw_InitForOpenGL(window, true);
  ImGui_ImplOpenGL3_Init(glsl_version);
  
  ImGui::StyleColorsDark();

  ImVec4 clear_color = ImColor(60, 55, 15);

  //Set scale based on scale of monitor
  GLFWmonitor * monitor = glfwGetPrimaryMonitor();
  float scale = 2.f;
  glfwGetMonitorContentScale(monitor, &scale, nullptr);
  
  // The render loop
  while (!glfwWindowShouldClose(window)) {
    
    glfwPollEvents();
    
    ImGui_ImplOpenGL3_NewFrame();
    ImGui_ImplGlfw_NewFrame();
    ImGui::NewFrame();

    ImGuiViewport * viewport = ImGui::GetMainViewport();
    ImGui::SetNextWindowPos(viewport->Pos);
    ImGui::SetNextWindowSize(viewport->Size);
    ImGui::SetNextWindowViewport(viewport->ID);
    ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(0.0f, 0.0f));
    
    ImGuiWindowFlags window_flags = ImGuiWindowFlags_MenuBar | ImGuiWindowFlags_NoDocking | ImGuiWindowFlags_NoCollapse | ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoDecoration | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoNavFocus | ImGuiWindowFlags_NoMove;
    
    ImGui::Begin("MainWindow", NULL, window_flags);
    ImGui::PopStyleVar();

    float height = ImGui::GetFrameHeight();
    
    if(ImGui::BeginMenuBar()) {
      if(ImGui::BeginMenu("Menu")) {
        ImGui::MenuItem("Main menu bar", NULL, false, true);
        ImGui::EndMenu();
      }
      ImGui::EndMenuBar();
    }

    if(ImGui::BeginViewportSideBar("StatusBar", viewport, ImGuiDir_Down, height, window_flags)) {
        if (ImGui::BeginMenuBar()) {
            ImGui::Text("status bar");
            ImGui::EndMenuBar();
        }
        ImGui::End();
    }
    
    
    //float h = 200;
    static float h1 = 300;
    static float h2 = 300;
    static float w1 = 300;
    static float w2 = 300;
    
    // horizontal splitter
    Splitter(false, 4.0f, &h1, &h2, 50, 50);
    
    // 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, h1), true);
    ImGui::PopStyleVar();
    ImGui::PopStyleColor();
    
      // vertical splitter
      Splitter(true, 4.0f, &w1, &w2, 50, 50);
    
      // right part blue
      ImGui::PushStyleColor(ImGuiCol_ChildBg, ImColor(0,0,255).Value);
      ImGui::BeginChild("3", ImVec2(w1, 0), true);
      ImGui::PopStyleColor();
      ImGui::EndChild();
    
      ImGui::SameLine();
    
      // left part red
      ImGui::PushStyleColor(ImGuiCol_ChildBg, ImColor(255,0,0).Value);
      ImGui::BeginChild("4", ImVec2(0, 0), true);
      ImGui::PopStyleColor();
      ImGui::EndChild();
    
    
    ImGui::EndChild();
    
    // bottom part yellow
    ImGui::PushStyleColor(ImGuiCol_ChildBg, ImColor(255,255,0).Value);
    ImGui::BeginChild("2", ImVec2(0, h2), true);
    ImGui::PopStyleColor();

    ImGui::EndChild();

    ImGui::End();
    
    // Rendering
    ImGui::Render();
    int display_w, display_h;
    glfwGetFramebufferSize(window, &display_w, &display_h);
    glViewport(0, 0, display_w, display_h);
    glClearColor(clear_color.x, clear_color.y, clear_color.z, clear_color.w);
    glClear(GL_COLOR_BUFFER_BIT);
    ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData());

    glfwSwapBuffers(window);
    
  }

  // Cleanup
  ImGui_ImplOpenGL3_Shutdown();
  ImGui_ImplGlfw_Shutdown();
  ImGui::DestroyContext();
  
  glfwDestroyWindow(window);
  glfwTerminate();
  
  return 0;
  
}

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.