pthom / hello_imgui

Hello, Dear ImGui: unleash your creativity in app development and prototyping
https://pthom.github.io/hello_imgui
MIT License
606 stars 91 forks source link

More FontAwesome options #12

Closed codecat closed 3 years ago

codecat commented 3 years ago

The FontAwesome feature could use a couple new features.

A locked glyph size will allow for menu items to align nicely in vertical menus, giving icons all the same width. Here's an example I use in one of my projects:

config.GlyphMinAdvanceX = 18;
config.GlyphMaxAdvanceX = 18;

Also, exposing MergeFontAwesomeToLastFont to the public API will allow using a custom font size, which can in some times be beneficial. For example, in my case, having the icon font be 1 pixel smaller fixes an issue in multi-line text fields where icons will blend into each other if they're right underneath other icons on the next line. (And they kinda align better in menu bars if they're 1 pixel smaller than the main font.)

pthom commented 3 years ago

Hello,

There are lots of possible customizations that users might desire when it comes to fonts (glyph range, glyph layout options, additional icon fonts other than font awesome, etc).

Thus, at the moment, the user is given the possibility to completely override the font loading function (simply by setting runnerParams.callbacks.LoadAdditionalFonts. I suspect you know this already)). This gives the maximum level of customization, and keeps the API simple.

For example, in src/hello_imgui_demos/hello_imgui_demodocking/hello_imgui_demodocking.main.cpp, we have this:

void MyLoadFonts()
{
    // First, we load the default fonts (the font that was loaded first is the default font)
    HelloImGui::ImGuiDefaultSettings::LoadDefaultFont_WithFontAwesomeIcons();

    // Then we load a second font from
    // Since this font is in a local assets/ folder, it was embedded automatically
    std::string fontFilename = "fonts/Akronim-Regular.ttf";
    gAkronimFont = HelloImGui::LoadFontTTF_WithFontAwesomeIcons(fontFilename, 40.f);
}

...

    // Custom load fonts
    runnerParams.callbacks.LoadAdditionalFonts = MyLoadFonts;

I think it could be possible to update the available functions inside src/hello_imgui/imgui_default_settings.h (these functions enable users to build their own font loading function). You seem to know more than me about font configurations. Would you like to work on a PR related to this?

codecat commented 3 years ago

Sure! After taking a quick look, it seems there might already have been an attempt at adding customization to font configurations in HelloImGui::LoadFontTTF? There's a makeFontConfig lambda which I don't think has to be a lambda right now, so I suspect it was going to be some kind of default for a parameter.

Do you think lambda's for font configurations is a good idea? Perhaps something like this could work:

LoadFontTTF("fonts/DroidSans.ttf", 12.0f, [](ImFontConfig& config) {
  // modify the config here
  config.GlyphMinAdvanceX = 18;
  config.GlyphMaxAdvanceX = 18;
});

And then probably exposing MergeFontAwesomeToLastFont with the same kind of lambda function.

pthom commented 3 years ago

I don't know if a lambda is the most appropriate. The important thing to know is that the ImFontConfig instance has to live during the whole application lifecycle (imgui only takes a pointer to it, which should not be dangling).

This is why I added this static container:

 static std::map<std::string, ImFontConfig> allFontConfigs;
    allFontConfigs[fontFilename] = makeFontConfig();
    auto& fontConfig = allFontConfigs.at(fontFilename);
codecat commented 3 years ago

If you look at the code of AddFontFromMemoryTTF, it doesn't actually keep the pointer around at all:

https://github.com/ocornut/imgui/blob/5f45047fb67c2147c6a1b1798b98d401e7998b51/imgui_draw.cpp#L2133

So it's safe to just keep it on the stack, which will simplify a lot of this code.

I'll do a pull request shortly!

pthom commented 3 years ago

More options were added in this PR