Skip to content

Instantly share code, notes, and snippets.

@JeffM2501
Created April 21, 2021 15:14
Show Gist options
  • Save JeffM2501/4c3a7e8a85302f743f8bd9dc1aae00ae to your computer and use it in GitHub Desktop.
Save JeffM2501/4c3a7e8a85302f743f8bd9dc1aae00ae to your computer and use it in GitHub Desktop.
Example of how to do editor style docking in ImGui for raylib
/*******************************************************************************************
*
* raylib [core] example - Third Person Orbit Camera Example
*
* Welcome to raylib!
*
* To test examples, just press F6 and execute raylib_compile_execute script
* Note that compiled executable is placed in the same folder as .c file
*
* You can find all basic examples on C:\raylib\raylib\examples folder or
* raylib official webpage: www.raylib.com
*
* Enjoy using raylib. :)
*
* This example has been created using raylib 1.0 (www.raylib.com)
* raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details)
*
* Copyright (c) 2014 Ramon Santamaria (@raysan5)
*
********************************************************************************************/
#include "raylib.h"
#include "raymath.h"
#include "imgui.h"
#include "rlImGui.h"
int main(int argc, char* argv[])
{
// Initialization
//--------------------------------------------------------------------------------------
int screenWidth = 1900;
int screenHeight = 900;
SetConfigFlags(FLAG_MSAA_4X_HINT | FLAG_VSYNC_HINT | FLAG_WINDOW_RESIZABLE);
InitWindow(screenWidth, screenHeight, "raylib [ImGui] example - ImGui Demo");
SetTargetFPS(144);
SetupRLImGui(true);
// setup a background texture
Image img = GenImageChecked(64, 64, 16, 16, DARKGRAY, GRAY);
Texture bg = LoadTextureFromImage(img);
UnloadImage(img);
// flag so we can quit the game from the file menu
bool quit = false;
// Main game loop
while (!WindowShouldClose() && !quit) // Detect window close button or ESC key
{
BeginDrawing();
ClearBackground(DARKGRAY);
// fill the background with something interesting
DrawTextureRec(bg, Rectangle{ 0, 0, float(GetScreenWidth()), float(GetScreenHeight()) }, Vector2Zero(), WHITE);
DrawRectanglePro(Rectangle{ GetScreenWidth() * 0.5f, GetScreenHeight() * 0.5f,200,200 }, Vector2{ 100,100 }, float(GetTime()) * 45, ColorAlpha(RED,0.75f));
// start the GUI
BeginRLImGui();
// create an ImGui window that covers the entire viewport, so that we can have a menu bar at the top of the applications
ImGui::SetNextWindowPos(ImVec2(0, 0)); // always at the window origin
ImGui::SetNextWindowSize(ImVec2(float(GetScreenWidth()), float(GetScreenHeight()))); // always at the window size
ImGuiWindowFlags windowFlags = ImGuiWindowFlags_NoBringToFrontOnFocus | // we just want to use this window as a host for the menubar and docking
ImGuiWindowFlags_NoNavFocus | // so turn off everything that would make it act like a window
ImGuiWindowFlags_NoDocking |
ImGuiWindowFlags_NoTitleBar |
ImGuiWindowFlags_NoResize |
ImGuiWindowFlags_NoMove |
ImGuiWindowFlags_NoCollapse |
ImGuiWindowFlags_MenuBar |
ImGuiWindowFlags_NoBackground; // we want our game content to show through this window, so turn off the background.
ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(0, 0)); // we don't want any padding for windows docked to this window frame
bool show = (ImGui::Begin("Main", NULL, windowFlags)); // show the "window"
ImGui::PopStyleVar(); // restore the style so inner windows have fames
// create a docking space inside our inner window that lets prevents anything from docking in the central node (so we can see our game content)
ImGui::DockSpace(ImGui::GetID("Dockspace"), ImVec2(0.0f, 0.0f), ImGuiDockNodeFlags_PassthruCentralNode);
if (show)
{
// Do a menu bar with an exit menu
if (ImGui::BeginMenuBar())
{
if (ImGui::BeginMenu("File"))
{
if (ImGui::MenuItem("Exit"))
quit = true;
ImGui::EndMenu();
}
ImGui::EndMenuBar();
}
}
ImGui::End();
// show any other windows that we want to be dockable
ImGui::ShowDemoWindow(NULL);
// end ImGui
EndRLImGui();
// Finish drawing
DrawFPS(0, GetScreenHeight() - 20);
EndDrawing();
//----------------------------------------------------------------------------------
}
ShutdownRLImGui();
UnloadTexture(bg);
CloseWindow();
return 0;
}
@EVWTRENTINI
Copy link

I was following your tutorial to integrate imgui-docking with raylib https://github.com/JeffM2501/raylibExtras/wiki/Using-ImGui-Docking-Branch-with-rlImGui. It turns out that the rlImGui.cpp seems different from the version in your tutorial. Could you please update this tutorial? Thank you very much.

@EVWTRENTINI
Copy link

EVWTRENTINI commented May 10, 2024

I think I got it. In the rlImGui.cpp file, I changed the rlImGuiSetup function to the one below:

void rlImGuiSetup(bool dark)
{
    rlImGuiBeginInitImGui();
    ImGuiIO& io = ImGui::GetIO();
    io.ConfigFlags |= ImGuiConfigFlags_DockingEnable; // Enable Docking

    if (dark)
        ImGui::StyleColorsDark();
    else
        ImGui::StyleColorsLight();

    rlImGuiEndInitImGui();
}

And in your example, I had to change the names of some functions:

/*******************************************************************************************
*
*   raylib [core] example - Third Person Orbit Camera Example
*
*   Welcome to raylib!
*
*   To test examples, just press F6 and execute raylib_compile_execute script
*   Note that compiled executable is placed in the same folder as .c file
*
*   You can find all basic examples on C:\raylib\raylib\examples folder or
*   raylib official webpage: www.raylib.com
*
*   Enjoy using raylib. :)
*
*   This example has been created using raylib 1.0 (www.raylib.com)
*   raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details)
*
*   Copyright (c) 2014 Ramon Santamaria (@raysan5)
*
********************************************************************************************/

#include "raylib.h"
#include "raymath.h"

#include "imgui.h"
#include "rlImGui.h"

int main(int argc, char* argv[])
{
    // Initialization
    //--------------------------------------------------------------------------------------
    int screenWidth = 1900;
    int screenHeight = 900;

    SetConfigFlags(FLAG_MSAA_4X_HINT | FLAG_VSYNC_HINT | FLAG_WINDOW_RESIZABLE);
    InitWindow(screenWidth, screenHeight, "raylib [ImGui] example - ImGui Demo");
    SetTargetFPS(144);
    rlImGuiSetup(true);

    // setup a background texture
    Image img = GenImageChecked(64, 64, 16, 16, DARKGRAY, GRAY);
    Texture bg = LoadTextureFromImage(img);
    UnloadImage(img);

    // flag so we can quit the game from the file menu
    bool quit = false;
    // Main game loop
    while (!WindowShouldClose() && !quit)    // Detect window close button or ESC key
    {
        BeginDrawing();
        ClearBackground(DARKGRAY);

        // fill the background with something interesting
        DrawTextureRec(bg, Rectangle{ 0, 0, float(GetScreenWidth()), float(GetScreenHeight()) }, Vector2Zero(), WHITE);
        DrawRectanglePro(Rectangle{ GetScreenWidth() * 0.5f, GetScreenHeight() * 0.5f,200,200 }, Vector2{ 100,100 }, float(GetTime()) * 45, ColorAlpha(RED,0.75f));

        // start the GUI
        rlImGuiBegin();

        // create an ImGui window that covers the entire viewport, so that we can have a menu bar at the top of the applications
        ImGui::SetNextWindowPos(ImVec2(0, 0));                                                  // always at the window origin
        ImGui::SetNextWindowSize(ImVec2(float(GetScreenWidth()), float(GetScreenHeight())));    // always at the window size

        ImGuiWindowFlags windowFlags = ImGuiWindowFlags_NoBringToFrontOnFocus |                 // we just want to use this window as a host for the menubar and docking
            ImGuiWindowFlags_NoNavFocus |                                                      // so turn off everything that would make it act like a window
            ImGuiWindowFlags_NoDocking |
            ImGuiWindowFlags_NoTitleBar |
            ImGuiWindowFlags_NoResize |
            ImGuiWindowFlags_NoMove |
            ImGuiWindowFlags_NoCollapse |
            ImGuiWindowFlags_MenuBar |
            ImGuiWindowFlags_NoBackground;                                                      // we want our game content to show through this window, so turn off the background.

        ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(0, 0));                          // we don't want any padding for windows docked to this window frame

        bool show = (ImGui::Begin("Main", NULL, windowFlags));                                   // show the "window"
        ImGui::PopStyleVar();                                                                    // restore the style so inner windows have fames

        // create a docking space inside our inner window that lets prevents anything from docking in the central node (so we can see our game content)
        ImGui::DockSpace(ImGui::GetID("Dockspace"), ImVec2(0.0f, 0.0f),  ImGuiDockNodeFlags_PassthruCentralNode);
        if (show)
        {
            // Do a menu bar with an exit menu
            if (ImGui::BeginMenuBar())
            {
                if (ImGui::BeginMenu("File"))
                {
                    if (ImGui::MenuItem("Exit"))
                        quit = true;

                    ImGui::EndMenu();
                }
                ImGui::EndMenuBar();
            }
        }
        ImGui::End();

        // show any other windows that we want to be dockable
        ImGui::ShowDemoWindow(NULL);

        // end ImGui
        rlImGuiEnd();

        // Finish drawing
        DrawFPS(0, GetScreenHeight() - 20);
        EndDrawing();
        //----------------------------------------------------------------------------------
    }
    rlImGuiShutdown();
    UnloadTexture(bg);
    CloseWindow(); 

    return 0;
}

I am very new to C++ and I have no idea what I'm doing.

@JeffM2501
Copy link
Author

Yes, the rlImgui that is part of my personal repository is long dead. There is a more official version of rlImGui at
https://github.com/raylib-extras/rlImGui
just link against the docking branch and enable docking in the io flags after setup.

@JeffM2501
Copy link
Author

I have added a docking example to the proper rlImGui. It's much simpler than this old example. You just need to do two things, enable docking and set docking on the viewport.

https://github.com/raylib-extras/rlImGui/blob/main/examples/docking_example.cpp

@EVWTRENTINI
Copy link

EVWTRENTINI commented May 13, 2024

Thank you for your response, @JeffM2501. I managed to get it working here. Thanks.

@EVWTRENTINI
Copy link

EVWTRENTINI commented May 17, 2024

@JeffM2501 sorry to bother you again, but I was trying to make this simple example of a circle and a dockable ImGui window work together.

#include "raymath.h"

#include "imgui.h"
#include "rlImGui.h"

Color green = {173, 204, 96, 255};

int main(int argc, char* argv[])
{
	// Initialization
	//--------------------------------------------------------------------------------------
	int screenWidth = 1280;
	int screenHeight = 800;

	SetConfigFlags(FLAG_MSAA_4X_HINT | FLAG_VSYNC_HINT | FLAG_WINDOW_RESIZABLE);
	InitWindow(screenWidth, screenHeight, "teste");
	SetTargetFPS(60);
	rlImGuiSetup(false);

	bool run = true;


	ImGui::GetIO().ConfigFlags |= ImGuiConfigFlags_DockingEnable;

	while (!WindowShouldClose() && run)    // Detect window close button or ESC key, or a quit from the menu
	{
		BeginDrawing();
		ClearBackground(DARKGRAY);

		DrawCircle(screenWidth/2, screenHeight/2, 100, green);


		rlImGuiBegin();
		ImGui::DockSpaceOverViewport();

		// show some windows
		if (ImGui::Begin("Test Window"))
		{
			ImGui::TextUnformatted("Another window");
		}
		ImGui::End();

		// end ImGui Content
		rlImGuiEnd();



		EndDrawing();

	}
	rlImGuiShutdown();

	CloseWindow();


	return 0;
}

Depending on where I place the rlImGuiBegin(); ... rlImGuiEnd();, either the circle doesn't appear, or the ImGui doesn't appear. The only way I managed to get both to work together with the windows on top of the circle was by removing the ImGui::DockSpaceOverViewport(); and losing the docking capability. What am I doing wrong? Can you lend a hand?

I also tried to take that example of yours from the editor and make it dockable by adding ImGui::GetIO().ConfigFlags |= ImGuiConfigFlags_DockingEnable; after rlImGuiSetup(true); and ImGui::DockSpaceOverViewport(); after rlImGuiBegin(); and it doesn't compile. Could you post a version of this dockable example as well?
Thank you very much.

@hermesonbf
Copy link

Any update on this? I am having the same problem with the docking + drawing stuff with Raylib.

@EVWTRENTINI
Copy link

Any update on this? I am having the same problem with the docking + drawing stuff with Raylib.

No, I just abandoned docking.

@JeffM2501
Copy link
Author

Sorry, just saw this.
Your stuff is being drawn it's just drawn behind the dockspace central node that is created for the viewport.
You use specific flags to control that.
Set

ImGui::DockSpaceOverViewport(0,  NULL, ImGuiDockNodeFlags_PassthruCentralNode);

And that will remove the gray tint applied to the central node of the dockspace.
It works just fine.
image

Alternatively you can create an undecorated window with no background and attach a dockspace to it.

These are not issues with rlImGui, simply how docking branch works in ImGui.

@EVWTRENTINI
Copy link

Thanks for the answer @JeffM2501, I'll go back to using the docking branch now

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment