Some recipes and notes on Dear ImGui v1.79

How to display control directly onto background, not in the window?

I don't think you can. The underlying window is always "Debug" so if you try to draw control on it it just appears in that window. The solution that worked for me was to create a new window that isn't visible and draw control onto that. The window title needs to be set at something other than empty string "" even though it isn't needed because it's hidden anyway. It crashes on Windows if set to empty string, but works fine on Linux.

bool show = true;
bool pressed = false;
auto flags_invisible_window =
    ImGuiWindowFlags_::ImGuiWindowFlags_NoBackground |
    ImGuiWindowFlags_::ImGuiWindowFlags_NoTitleBar |
    ImGuiWindowFlags_::ImGuiWindowFlags_NoResize;

// I don't need window title here, but if left empty it crashes on Windows
ImGui::Begin("_", &show, flags_invisible_window);

if (ImGui::Button(button_text.data()))
    pressed = true;

ImGui::End();

How to get the coordinates of the corners?

They key is ImGui::GetIO().DisplaySize which is a vector of two values, x and y. They will basically tell you the size of current screen, which changes with resize. Get corner coordinates from this. As usual with graphics, y increases down, x increases to the right.

How to change fonts or make them bigger?

You can't do it at the point of displaying the text, they need to be preloaded. This doesn't just go for the fonts, but for the sizes as well. Glyphs are pre-rendered and when the text is displayed it is assembled from the already rendered glyphs. You call one of the ImGui::GetIO().Fonts->AddFont-* family of functions to load the font, then ImGui::PushFont to start using it and ImGui::PopFont to stop using it. The first call to ImGui::GetIO().Fonts->AddFont-* loads the font that will be the default for all text everywhere.

// in the setup part of the app
ImFont* default_font = ImGui::GetIO().Fonts->AddFontDefault();
ImFont* font_droidsans_60 = ImGui::GetIO().Fonts->AddFontFromFileTTF("path/to/font/DroidSans.ttf", 60);

// when using the font
ImGui::Begin("Title of window in default font");
ImGui::PushFont(font_droidsans_60);
ImGui::Text("Huge text in droid sans, 60");
ImGui::PopFont();
ImGui::End();

How to use FontAwesome to get icons?

Font Awesome project (https://github.com/FortAwesome/Font-Awesome.git) uses Private Use Area of the font to store icons. This area needs to be merged with whatever font you're using. ImGui allows merging fonts when loading them. You need to merge Font Awesome to your font.

#include "IconsFontAwesome5.h"

// loading and merging with some other font
ImFont* default_font = ImGui::GetIO().Fonts->AddFontDefault();
static const ImWchar icons_ranges[] = { ICON_MIN_FA, ICON_MAX_FA, 0 };
ImFontConfig icons_config;
icons_config.MergeMode = true;
icons_config.PixelSnapH = true;
ImGui::GetIO().Fonts->AddFontFromFileTTF(
   "/path/to/Font-Awesome/otfs/Font Awesome 5 Free-Solid-900.otf", 
   13.0f, 
   &icons_config, 
   icons_ranges );

// works in window titles
ImGui::Begin(ICON_FA_PAINT_BRUSH " Hello, world!");
// works in texts, etc ...
ImGui::Text(ICON_FA_PAINT_BRUSH " Paint" );

The ICON_FA_PAINT_BRUSH macro is provided by IconFontCppHeaders project (https://github.com/juliettef/IconFontCppHeaders.git). That's where the IconsFontAwesome5.h header comes from. I suggest you use that because it would be a lot of work to figure out the utf8 codes for each icon.

So I can't change the font at the moment I need it. What if I preload all combinations then?

You probably can't. The size of storage is limited, so if you are thinking of a workaround where you just preload all 50 fonts you have in 50 different sizes for each you will create an empty screen with no hints as to what went wrong. You can reach this limit fairly quickly. On my machine if I do 8 fonts * 50 different sizes it already breaks. If you want to attach Font-Awesome to each loaded font it dies even quicker: 8 fonts * 2 sizes * Font-Awesome already broke on my machine. I could only afford to add Font-Awesome to 2 fonts * 2 sizes before my display went blank. These aren't exact measurements because the numbers will vary on your machine, just to illustrate you can reach the limit quickly enough to be a practical hindrance. I didn't try this yet, but you could probably reload fonts after a call to ImGui::Render() and before the next call to mGui::NewFrame(). I am sure this would mean you still couldn't mix the fonts loaded before with the fonts loaded after on the same screen.

How do I take focus?

I think it's a SDL2 problem rather than imgui problem. After I added flag SDL_WINDOW_ALWAYS_ON_TOP to SDL_CreateWindow it stayed on top.

How to detect a click on a window?

bool clicked = 
   ImGui::IsWindowHovered(ImGuiHoveredFlags_None) 
   && ImGui::IsMouseClicked(ImGuiPopupFlags_MouseButtonLeft));


Previous: Multiplatform cmake setup for date-tz