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

@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.

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