ggerganov / imtui

ImTui: Immediate Mode Text-based User Interface C++ Library
https://imtui.ggerganov.com
MIT License
3.04k stars 127 forks source link

Help using imtui in personal project #42

Closed kiteloopdesign closed 2 years ago

kiteloopdesign commented 2 years ago

First of all apologies for this newbie question, but I am struggling with too many things at the same time: imtui, c++, cmakefiles, static vs dynamic libraries, etc. so I am not sure where the error may be, or whether my approach may not be the better one.

Let me try to break out my problem in parts to make it easier for you to understand and advice

First of all, what I actually want to do I want to create a dummy hello-world imtui example from scratch, and build it in my own ~/projects/imtui-hello folder, with as minimal cmake/dependencies as possible. This is, ideally I'd like to have a hello-imtui.cpp file so I can do something like g++ -Wall [-I SOME_INCLUDE -DSOME_OPTION -SOMETHING_ELSE] ./imtui.cpp.

Can I do a simple build like that or do I actually need to use a CMakeFileLists.txt? Do I need to have the imgui forked dependency cloned on my hello-world folder (i.e. as in imtui/third-party/imgui? What if I install (make install) the (forked) imgui on its own to my system so I do not need to have a cloned imgui for each dummy folder I want to experiment with?

Now, I know there is an examples/ncurses0 but I want to do something much more minimal (dummy box with "hello world" text) than this. Additionally, I am also totally getting lost with the amount of CMake stuff that I do not know how to "re-use" it for this bare minimum experimentation folder

What I have done I've properly build imtui, and ran the examples that are generated on bin folder. I have also installed imtui by issuing a make install. This is, imtui is working and, in theory, properly installed.

I am on Fedora 35 if that's of any help


Again, apologies if I am missing something basic here...

ggerganov commented 2 years ago

Thank you for the question! Admittedly, I haven't done a very good job of making ImTui easy to integrate in other projects, so it is not surprising that you have trouble making this simple example. But I think I have a solution that should work for you.

First, I just pushed a small change to the CMake files that is necessary to make this work. Below are instructions that you can try to follow:

# Clone ImTui somewhere on your disk
# We will build it once and make it re-usable for other projects

cd ~/projects
git clone https://github.com/ggerganov/imtui --recursive
cd imtui
mkdir build
cd build
cmake -DCMAKE_INSTALL_PREFIX=dist ..
make -j4
make install

# The above commands build the ImTui libraries and install the headers and the libs in ~/projects/imtui/build/dist
# You have to do this only once.
# If you want, you can change the destination be modifying the CMAKE_INSTALL_PREFIX variable

# Now, lets compile a simple hello-imtui.cpp program without using Make or CMake:

cd ~/projects/imtui-hello
g++ imtui-hello.cpp -I ~/projects/imtui/build/dist/include/ -I ~/projects/imtui/buid/dist/include/imgui-for-imtui/ -L ~/projects/imtui/buid/dist/lib/ -limtui -limtui-ncurses -limgui-for-imtui -lncurses

# And start it:
./a.out

Here is a sample imtui-hello.cpp that you can use:

#include "imtui/imtui.h"

#include "imtui/imtui-impl-ncurses.h"

int main() {
    IMGUI_CHECKVERSION();
    ImGui::CreateContext();

    auto screen = ImTui_ImplNcurses_Init(true);
    ImTui_ImplText_Init();

    int nframes = 0;
    float fval = 1.23f;

    while (true) {
        ImTui_ImplNcurses_NewFrame();
        ImTui_ImplText_NewFrame();

        ImGui::NewFrame();

        ImGui::SetNextWindowPos(ImVec2(4, 27), ImGuiCond_Once);
        ImGui::SetNextWindowSize(ImVec2(50.0, 10.0), ImGuiCond_Once);
        ImGui::Begin("Hello, world!");
        ImGui::Text("NFrames = %d", nframes++);
        ImGui::Text("Mouse Pos : x = %g, y = %g", ImGui::GetIO().MousePos.x, ImGui::GetIO().MousePos.y);
        ImGui::Text("Time per frame %.3f ms/frame (%.1f FPS)", 1000.0f / ImGui::GetIO().Framerate, ImGui::GetIO().Framerate);
        ImGui::Text("Float:");
        ImGui::SameLine();
        ImGui::SliderFloat("##float", &fval, 0.0f, 10.0f);

        ImGui::End();

        ImGui::Render();

        ImTui_ImplText_RenderDrawData(ImGui::GetDrawData(), screen);
        ImTui_ImplNcurses_DrawScreen();
    }

    ImTui_ImplText_Shutdown();
    ImTui_ImplNcurses_Shutdown();

    return 0;
}

Hope this helps -- let me know if you encounter any issues.

kiteloopdesign commented 2 years ago

Thanks so much for the prompt reply. I got it working with following command:

g++ imtui-hello.cpp -I ./imtui/build/dist/include/ -I ./imtui/build/dist/include/imgui-for-imtui/ -L ./imtui/build/dist/lib64/ -limtui -limtui-ncurses -limgui-for-imtui -lncurses

(there was a typo on "build". Also Fedora seems to use "lib64" instead of "lib")