diff --git a/bindings/imgui_bundle/doc/Readme.adoc b/bindings/imgui_bundle/doc/Readme.adoc index a9c97c4e..e533fe94 100644 --- a/bindings/imgui_bundle/doc/Readme.adoc +++ b/bindings/imgui_bundle/doc/Readme.adoc @@ -1415,10 +1415,11 @@ It demonstrates how to: - use the status bar - use default menus (App and view menu), and how to customize them - display a log window -- load additional fonts +- load additional fonts, possibly colored, and with emojis - use a specific application state (instead of using static variables) - save some additional user settings within imgui ini file -*/ +- use borderless windows, that are movable and resizable + */ #include "hello_imgui/hello_imgui.h" #include "imgui.h" @@ -1428,6 +1429,21 @@ It demonstrates how to: #include +// Poor man's fix for C++ late arrival in the unicode party: +// - C++17: u8"my string" is of type const char* +// - C++20: u8"my string" is of type const char8_t* +// However, ImGui text functions expect const char*. +#ifdef __cpp_char8_t +#define U8_TO_CHAR(x) reinterpret_cast(x) +#else +#define U8_TO_CHAR(x) x +#endif +// And then, we need to tell gcc to stop validating format string (it gets confused by the u8"" string) +#ifdef __GNUC__ +#pragma GCC diagnostic ignored "-Wformat" +#endif + + ////////////////////////////////////////////////////////////////////////// // Our Application State ////////////////////////////////////////////////////////////////////////// @@ -1453,19 +1469,30 @@ struct AppState RocketState rocket_state = RocketState::Init; MyAppSettings myAppSettings; // This values will be stored in the application settings + ImFont* TitleFont = nullptr; + ImFont* ColorFont = nullptr; + ImFont* EmojiFont = nullptr; }; ////////////////////////////////////////////////////////////////////////// // Additional fonts handling ////////////////////////////////////////////////////////////////////////// -ImFont * gTitleFont; -void LoadFonts() // This is called by runnerParams.callbacks.LoadAdditionalFonts +void LoadFonts(AppState& appState) // This is called by runnerParams.callbacks.LoadAdditionalFonts { // First, load the default font (the default font should be loaded first) HelloImGui::ImGuiDefaultSettings::LoadDefaultFont_WithFontAwesomeIcons(); // Then load the title font - gTitleFont = HelloImGui::LoadFontTTF("fonts/DroidSans.ttf", 18.f); + appState.TitleFont = HelloImGui::LoadFont("fonts/DroidSans.ttf", 18.f); + + HelloImGui::FontLoadingParams fontLoadingParamsEmoji; + fontLoadingParamsEmoji.useFullGlyphRange = true; + appState.EmojiFont = HelloImGui::LoadFont("fonts/NotoEmoji-Regular.ttf", 24.f, fontLoadingParamsEmoji); +#ifdef IMGUI_ENABLE_FREETYPE + HelloImGui::FontLoadingParams fontLoadingParamsColor; + fontLoadingParamsColor.loadColor = true; + appState.ColorFont = HelloImGui::LoadFont("fonts/Playbox/Playbox-FREE.otf", 24.f, fontLoadingParamsColor); +#endif } @@ -1510,17 +1537,17 @@ void SaveMyAppSettings(const AppState& appState) ////////////////////////////////////////////////////////////////////////// // Display a button that will hide the application window -void DemoHideWindow() +void DemoHideWindow(AppState& appState) { - ImGui::PushFont(gTitleFont); ImGui::Text("Hide app window"); ImGui::PopFont(); - ImGui::TextWrapped("By clicking the button below, you can hide the window for 3 seconds."); - + ImGui::PushFont(appState.TitleFont); ImGui::Text("Hide app window"); ImGui::PopFont(); static double lastHideTime = -1.; if (ImGui::Button("Hide")) { lastHideTime = ImGui::GetTime(); HelloImGui::GetRunnerParams()->appWindowParams.hidden = true; } + if (ImGui::IsItemHovered()) + ImGui::SetTooltip("By clicking this button, you can hide the window for 3 seconds."); if (lastHideTime > 0.) { double now = ImGui::GetTime(); @@ -1533,7 +1560,7 @@ void DemoHideWindow() } // Display a button that will show an additional window -void DemoShowAdditionalWindow() +void DemoShowAdditionalWindow(AppState& appState) { // Notes: // - it is *not* possible to modify the content of the vector runnerParams.dockingParams.dockableWindows @@ -1542,7 +1569,7 @@ void DemoShowAdditionalWindow() // * either make them initially invisible, and exclude them from the view menu (such as shown here) // * or modify runnerParams.dockingParams.dockableWindows inside the callback RunnerCallbacks.PreNewFrame const char* windowName = "Additional Window"; - ImGui::PushFont(gTitleFont); ImGui::Text("Dynamically add window"); ImGui::PopFont(); + ImGui::PushFont(appState.TitleFont); ImGui::Text("Dynamically add window"); ImGui::PopFont(); if (ImGui::Button("Show additional window")) { auto additionalWindowPtr = HelloImGui::GetRunnerParams()->dockingParams.dockableWindowOfName(windowName); @@ -1552,14 +1579,15 @@ void DemoShowAdditionalWindow() additionalWindowPtr->isVisible = true; } } + if (ImGui::IsItemHovered()) + ImGui::SetTooltip("By clicking this button, you can show an additional window"); } - -void DemoBasicWidgets(AppState& appState) +void DemoLogs(AppState& appState) { - ImGui::PushFont(gTitleFont); ImGui::Text("Basic widgets demo"); ImGui::PopFont(); - ImGui::TextWrapped("The widgets below will interact with the log window"); + ImGui::PushFont(appState.TitleFont); ImGui::Text("Log Demo"); ImGui::PopFont(); + ImGui::BeginGroup(); // Edit a float using a slider from 0.0f to 1.0f bool changed = ImGui::SliderFloat("float", &appState.f, 0.0f, 1.0f); if (changed) @@ -1574,22 +1602,28 @@ void DemoBasicWidgets(AppState& appState) ImGui::SameLine(); ImGui::Text("counter = %d", appState.counter); + ImGui::EndGroup(); + if (ImGui::IsItemHovered()) + ImGui::SetTooltip("These widgets will interact with the log window"); } void DemoUserSettings(AppState& appState) { - ImGui::PushFont(gTitleFont); ImGui::Text("User settings"); ImGui::PopFont(); - ImGui::TextWrapped("The values below are stored in the application settings ini file and restored at startup"); + ImGui::PushFont(appState.TitleFont); ImGui::Text("User settings"); ImGui::PopFont(); + ImGui::BeginGroup(); ImGui::SetNextItemWidth(HelloImGui::EmSize(7.f)); ImGui::InputText("Name", &appState.myAppSettings.name); ImGui::SetNextItemWidth(HelloImGui::EmSize(7.f)); ImGui::SliderInt("Value", &appState.myAppSettings.value, 0, 100); + ImGui::EndGroup(); + if (ImGui::IsItemHovered()) + ImGui::SetTooltip("The values below are stored in the application settings ini file and restored at startup"); } void DemoRocket(AppState& appState) { - ImGui::PushFont(gTitleFont); ImGui::Text("Rocket demo"); ImGui::PopFont(); - ImGui::TextWrapped("How to show a progress bar in the status bar"); + ImGui::PushFont(appState.TitleFont); ImGui::Text("Status Bar Demo"); ImGui::PopFont(); + ImGui::BeginGroup(); if (appState.rocket_state == AppState::RocketState::Init) { if (ImGui::Button(ICON_FA_ROCKET" Launch rocket")) @@ -1618,11 +1652,14 @@ void DemoRocket(AppState& appState) appState.rocket_progress = 0.f; } } + ImGui::EndGroup(); + if (ImGui::IsItemHovered()) + ImGui::SetTooltip("Look at the status bar after clicking"); } -void DemoDockingFlags() +void DemoDockingFlags(AppState& appState) { - ImGui::PushFont(gTitleFont); ImGui::Text("Main dock space node flags"); ImGui::PopFont(); + ImGui::PushFont(appState.TitleFont); ImGui::Text("Main dock space node flags"); ImGui::PopFont(); ImGui::TextWrapped(R"( This will edit the ImGuiDockNodeFlags for "MainDockSpace". Most flags are inherited by children dock spaces. @@ -1644,7 +1681,7 @@ Most flags are inherited by children dock spaces. // {ImGuiDockNodeFlags_PassthruCentralNode, "PassthruCentralNode", "advanced"}, }; auto & mainDockSpaceNodeFlags = HelloImGui::GetRunnerParams()->dockingParams.mainDockSpaceNodeFlags; - for (auto flag: all_flags) + for (const auto& flag: all_flags) { ImGui::CheckboxFlags(flag.label.c_str(), &mainDockSpaceNodeFlags, flag.flag); if (ImGui::IsItemHovered()) @@ -1652,41 +1689,122 @@ Most flags are inherited by children dock spaces. } } -void GuiWindowLayoutCustomization() +void GuiWindowLayoutCustomization(AppState& appState) { - ImGui::PushFont(gTitleFont); ImGui::Text("Switch between layouts"); ImGui::PopFont(); + ImGui::PushFont(appState.TitleFont); ImGui::Text("Switch between layouts"); ImGui::PopFont(); ImGui::Text("with the menu \"View/Layouts\""); if (ImGui::IsItemHovered()) ImGui::SetTooltip("Each layout remembers separately the modifications applied by the user, \nand the selected layout is restored at startup"); ImGui::Separator(); - ImGui::PushFont(gTitleFont); ImGui::Text("Change the theme"); ImGui::PopFont(); + ImGui::PushFont(appState.TitleFont); ImGui::Text("Change the theme"); ImGui::PopFont(); ImGui::Text("with the menu \"View/Theme\""); if (ImGui::IsItemHovered()) ImGui::SetTooltip("The selected theme is remembered and restored at startup"); ImGui::Separator(); - DemoDockingFlags(); + DemoDockingFlags(appState); ImGui::Separator(); } -void DemoAssets() +void DemoAssets(AppState& appState) +{ + ImGui::PushFont(appState.TitleFont); ImGui::Text("Image From Asset"); ImGui::PopFont(); + HelloImGui::BeginGroupColumn(); + ImGui::Dummy(HelloImGui::EmToVec2(0.f, 0.45f)); + ImGui::Text("Hello"); + HelloImGui::EndGroupColumn(); + HelloImGui::ImageFromAsset("images/world.png", HelloImGui::EmToVec2(2.5f, 2.5f)); +} + +void DemoFonts(AppState& appState) +{ + ImGui::PushFont(appState.TitleFont); ImGui::Text("Fonts"); ImGui::PopFont(); + + ImGui::TextWrapped("Mix icons " ICON_FA_SMILE " and text " ICON_FA_ROCKET ""); + if (ImGui::IsItemHovered()) + ImGui::SetTooltip("Example with Font Awesome Icons"); + + ImGui::Text("Emojis"); + + ImGui::BeginGroup(); + { + ImGui::PushFont(appState.EmojiFont); + // ✌️ (Victory Hand Emoji) + ImGui::Text(U8_TO_CHAR(u8"\U0000270C\U0000FE0F")); + ImGui::SameLine(); + + // ❤️ (Red Heart Emoji) + ImGui::Text(U8_TO_CHAR(u8"\U00002764\U0000FE0F")); + ImGui::SameLine(); + +#ifdef IMGUI_USE_WCHAR32 + // 🌴 (Palm Tree Emoji) + ImGui::Text(U8_TO_CHAR(u8"\U0001F334")); + ImGui::SameLine(); + + // 🚀 (Rocket Emoji) + ImGui::Text(U8_TO_CHAR(u8"\U0001F680")); + ImGui::SameLine(); +#endif + + ImGui::PopFont(); + } + ImGui::EndGroup(); + if (ImGui::IsItemHovered()) + ImGui::SetTooltip("Example with NotoEmoji font"); + +#ifdef IMGUI_ENABLE_FREETYPE + ImGui::Text("Colored Fonts"); + ImGui::PushFont(appState.ColorFont); + ImGui::Text("C O L O R !"); + ImGui::PopFont(); + if (ImGui::IsItemHovered()) + ImGui::SetTooltip("Example with Playbox-FREE.otf font"); +#endif +} + +void DemoThemes(AppState& appState) { - ImGui::PushFont(gTitleFont); ImGui::Text("Hello"); ImGui::PopFont(); - HelloImGui::ImageFromAsset("images/world.png", HelloImGui::EmToVec2(3.f, 3.f)); + ImGui::PushFont(appState.TitleFont); ImGui::Text("Themes"); ImGui::PopFont(); + auto& tweakedTheme = HelloImGui::GetRunnerParams()->imGuiWindowParams.tweakedTheme; + + ImGui::BeginGroup(); + ImVec2 buttonSize = HelloImGui::EmToVec2(7.f, 0.f); + if (ImGui::Button("Cherry", buttonSize)) + { + tweakedTheme.Theme = ImGuiTheme::ImGuiTheme_Cherry; + ImGuiTheme::ApplyTweakedTheme(tweakedTheme); + } + if (ImGui::Button("DarculaDarker", buttonSize)) + { + tweakedTheme.Theme = ImGuiTheme::ImGuiTheme_DarculaDarker; + ImGuiTheme::ApplyTweakedTheme(tweakedTheme); + } + ImGui::EndGroup(); + if (ImGui::IsItemHovered()) + ImGui::SetTooltip( + "There are lots of other themes: look at the menu View/Theme\n" + "The selected theme is remembered and restored at startup" + ); } +// The Gui of the demo feature window void GuiWindowDemoFeatures(AppState& appState) { - DemoAssets(); + DemoFonts(appState); ImGui::Separator(); - DemoBasicWidgets(appState); + DemoAssets(appState); + ImGui::Separator(); + DemoLogs(appState); ImGui::Separator(); DemoRocket(appState); ImGui::Separator(); DemoUserSettings(appState); ImGui::Separator(); - DemoHideWindow(); + DemoHideWindow(appState); + ImGui::Separator(); + DemoShowAdditionalWindow(appState); ImGui::Separator(); - DemoShowAdditionalWindow(); + DemoThemes(appState); ImGui::Separator(); } @@ -1815,7 +1933,7 @@ std::vector CreateDockableWindows(AppState& appState HelloImGui::DockableWindow layoutCustomizationWindow; layoutCustomizationWindow.label = "Layout customization"; layoutCustomizationWindow.dockSpaceName = "MainDockSpace"; - layoutCustomizationWindow.GuiFunction = GuiWindowLayoutCustomization; + layoutCustomizationWindow.GuiFunction = [&appState]() { GuiWindowLayoutCustomization(appState); }; // A Log window named "Logs" will be placed in "MiscSpace". It uses the HelloImGui logger gui HelloImGui::DockableWindow logsWindow; @@ -1827,6 +1945,7 @@ std::vector CreateDockableWindows(AppState& appState HelloImGui::DockableWindow dearImGuiDemoWindow; dearImGuiDemoWindow.label = "Dear ImGui Demo"; dearImGuiDemoWindow.dockSpaceName = "MainDockSpace"; + dearImGuiDemoWindow.imGuiWindowFlags = ImGuiWindowFlags_MenuBar; dearImGuiDemoWindow.GuiFunction = [] { ImGui::ShowDemoWindow(); }; // additionalWindow is initially not visible (and not mentioned in the view menu). @@ -1847,7 +1966,7 @@ std::vector CreateDockableWindows(AppState& appState additionalWindow, }; return dockableWindows; -}; +} // // 3. Define the layouts: @@ -1882,7 +2001,7 @@ std::vector CreateAlternativeLayouts(AppState& appSta tabsLayout.dockingSplits = {}; } return {alternativeLayout, tabsLayout}; -}; +} ////////////////////////////////////////////////////////////////////////// @@ -1902,13 +2021,17 @@ int main(int, char**) // Hello ImGui params (they hold the settings as well as the Gui callbacks) HelloImGui::RunnerParams runnerParams; - runnerParams.appWindowParams.windowTitle = "Docking demo"; - runnerParams.imGuiWindowParams.menuAppTitle = "Docking demo"; + runnerParams.appWindowParams.windowTitle = "Docking Demo"; + runnerParams.imGuiWindowParams.menuAppTitle = "Docking Demo"; runnerParams.appWindowParams.windowGeometry.size = {1000, 900}; runnerParams.appWindowParams.restorePreviousGeometry = true; + runnerParams.appWindowParams.borderless = true; + runnerParams.appWindowParams.borderlessMovable = true; + runnerParams.appWindowParams.borderlessResizable = true; + runnerParams.appWindowParams.borderlessClosable = true; // Set LoadAdditionalFonts callback - runnerParams.callbacks.LoadAdditionalFonts = LoadFonts; + runnerParams.callbacks.LoadAdditionalFonts = [&appState]() { LoadFonts(appState); }; // // Status bar @@ -2011,17 +2134,19 @@ Python: # # It demonstrates how to: # - set up a complex docking layouts (with several possible layouts): +# - load additional fonts, possibly colored, and with emojis +# - display a log window # - use the status bar # - use default menus (App and view menu), and how to customize them -# - display a log window -# - load additional fonts # - use a specific application state (instead of using static variables) # - save some additional user settings within imgui ini file +# - use borderless windows, that are movable and resizable + from enum import Enum import time -from imgui_bundle import hello_imgui, icons_fontawesome, imgui, immapp +from imgui_bundle import hello_imgui, icons_fontawesome, imgui, immapp, imgui_ctx from imgui_bundle.demos_python import demo_utils from typing import List @@ -2049,6 +2174,10 @@ class AppState: rocket_state: RocketState rocket_launch_time: float + title_font: imgui.ImFont + color_font: imgui.ImFont + emoji_font: imgui.ImFont + def __init__(self): self.f = 0 self.counter = 0 @@ -2061,17 +2190,19 @@ class AppState: ########################################################################## # Additional fonts handling ########################################################################## - -TITLE_FONT: imgui.ImFont - - -def load_fonts(): # This is called by runnerParams.callbacks.LoadAdditionalFonts - global TITLE_FONT +def load_fonts(app_state: AppState): # This is called by runnerParams.callbacks.LoadAdditionalFonts # First, load the default font (the default font should be loaded first) hello_imgui.imgui_default_settings.load_default_font_with_font_awesome_icons() # Then load the title font - TITLE_FONT = hello_imgui.load_font_ttf("fonts/DroidSans.ttf", 18.0) + app_state.title_font = hello_imgui.load_font("fonts/DroidSans.ttf", 18.0) + + font_loading_params_emoji = hello_imgui.FontLoadingParams() + font_loading_params_emoji.use_full_glyph_range = True + app_state.emoji_font = hello_imgui.load_font("fonts/NotoEmoji-Regular.ttf", 24., font_loading_params_emoji) + font_loading_params_color = hello_imgui.FontLoadingParams() + font_loading_params_color.load_color = True + app_state.color_font = hello_imgui.load_font("fonts/Playbox/Playbox-FREE.otf", 24., font_loading_params_color) ########################################################################## # Save additional settings in the ini file @@ -2116,19 +2247,17 @@ def save_my_app_settings(app_state: AppState): # Gui functions used in this demo ########################################################################## @immapp.static(last_hide_time=1) -def demo_hide_window(): +def demo_hide_window(app_state: AppState): # Display a button that will hide the application window - imgui.push_font(TITLE_FONT) + imgui.push_font(app_state.title_font) imgui.text("Hide app window") imgui.pop_font() - imgui.text_wrapped( - "By clicking the button below, you can hide the window for 3 seconds." - ) if imgui.button("Hide"): demo_hide_window.last_hide_time = time.time() hello_imgui.get_runner_params().app_window_params.hidden = True - + if imgui.is_item_hovered(): + imgui.set_tooltip("By clicking this button, you can hide the window for 3 seconds.") if demo_hide_window.last_hide_time > 0.0: now = time.time() if now - demo_hide_window.last_hide_time > 3.0: @@ -2137,7 +2266,7 @@ def demo_hide_window(): # Display a button that will show an additional window -def demo_show_additional_window(): +def demo_show_additional_window(app_state: AppState): # Notes: # - it is *not* possible to modify the content of the vector runnerParams.dockingParams.dockableWindows # from the code inside a window's `GuiFunction` (since this GuiFunction will be called while iterating @@ -2147,7 +2276,7 @@ def demo_show_additional_window(): # * or modify runnerParams.dockingParams.dockableWindows inside the callback RunnerCallbacks.PreNewFrame window_name = "Additional Window" - imgui.push_font(TITLE_FONT) + imgui.push_font(app_state.title_font) imgui.text("Dynamically add window") imgui.pop_font() @@ -2159,14 +2288,16 @@ def demo_show_additional_window(): if additional_window_ptr: # additional_window_ptr.include_in_view_menu = True additional_window_ptr.is_visible = True + if imgui.is_item_hovered(): + imgui.set_tooltip("By clicking this button, you can show an additional window") def demo_basic_widgets(app_state: AppState): - imgui.push_font(TITLE_FONT) + imgui.push_font(app_state.title_font) imgui.text("Basic widgets demo") imgui.pop_font() - imgui.text_wrapped("The widgets below will interact with the log window") + imgui.begin_group() # Edit a float using a slider from 0.0 to 1.0 changed, app_state.f = imgui.slider_float("float", app_state.f, 0.0, 1.0) if changed: @@ -2180,15 +2311,18 @@ def demo_basic_widgets(app_state: AppState): hello_imgui.log(hello_imgui.LogLevel.info, "Button was pressed") imgui.same_line() imgui.text(f"counter = {app_state.counter}") + imgui.end_group() + + if imgui.is_item_hovered(): + imgui.set_tooltip("These widgets will interact with the log window") def demo_user_settings(app_state: AppState): - imgui.push_font(TITLE_FONT) + imgui.push_font(app_state.title_font) imgui.text("User settings") imgui.pop_font() - imgui.text_wrapped( - "The values below are stored in the application settings ini file and restored at startup" - ) + + imgui.begin_group() imgui.set_next_item_width(hello_imgui.em_size(7.0)) _, app_state.my_app_settings.name = imgui.input_text( "Name", app_state.my_app_settings.name @@ -2197,13 +2331,17 @@ def demo_user_settings(app_state: AppState): _, app_state.my_app_settings.value = imgui.slider_int( "Value", app_state.my_app_settings.value, 0, 100 ) + imgui.end_group() + if imgui.is_item_hovered(): + imgui.set_tooltip("The values below are stored in the application settings ini file and restored at startup") def demo_rocket(app_state: AppState): - imgui.push_font(TITLE_FONT) + imgui.push_font(app_state.title_font) imgui.text("Rocket demo") imgui.pop_font() - imgui.text_wrapped("How to show a progress bar in the status bar") + + imgui.begin_group() if app_state.rocket_state == RocketState.Init: if imgui.button(f"{icons_fontawesome.ICON_FA_ROCKET} Launch rocket"): app_state.rocket_launch_time = time.time() @@ -2220,10 +2358,13 @@ def demo_rocket(app_state: AppState): if imgui.button("Reset Rocket"): app_state.rocket_state = RocketState.Init app_state.rocket_progress = 0.0 + imgui.end_group() + if imgui.is_item_hovered(): + imgui.set_tooltip("Look at the status bar after clicking") -def demo_docking_flags(): - imgui.push_font(TITLE_FONT) +def demo_docking_flags(app_state: AppState): + imgui.push_font(app_state.title_font) imgui.text("Main dock space node flags") imgui.pop_font() imgui.text_wrapped( @@ -2279,8 +2420,8 @@ Most flags are inherited by children dock spaces. ) -def gui_window_layout_customization(): - imgui.push_font(TITLE_FONT) +def gui_window_layout_customization(app_state: AppState): + imgui.push_font(app_state.title_font) imgui.text("Switch between layouts") imgui.pop_font() imgui.text('with the menu "View/Layouts"') @@ -2292,7 +2433,7 @@ def gui_window_layout_customization(): imgui.separator() - imgui.push_font(TITLE_FONT) + imgui.push_font(app_state.title_font) imgui.text("Change the theme") imgui.pop_font() imgui.text('with the menu "View/Theme"') @@ -2300,19 +2441,88 @@ def gui_window_layout_customization(): imgui.set_tooltip("The selected theme is remembered and restored at startup") imgui.separator() - demo_docking_flags() + demo_docking_flags(app_state) imgui.separator() -def demo_assets(): - imgui.push_font(TITLE_FONT) +def demo_assets(app_state: AppState): + imgui.push_font(app_state.title_font) + imgui.text("Image From Assets") + imgui.pop_font() + hello_imgui.begin_group_column() + imgui.dummy(hello_imgui.em_to_vec2(0.0, 0.45)) imgui.text("Hello") + hello_imgui.end_group_column() + hello_imgui.image_from_asset("images/world.png", hello_imgui.em_to_vec2(2.5, 2.5)) + + +def demo_fonts(app_state: AppState): + imgui.push_font(app_state.title_font) + imgui.text("Fonts") + imgui.pop_font() + + imgui.text_wrapped("Mix icons " + icons_fontawesome.ICON_FA_SMILE + " and text " + icons_fontawesome.ICON_FA_ROCKET) + if imgui.is_item_hovered(): + imgui.set_tooltip("Example with Font Awesome Icons") + + imgui.text("Emojis") + + with imgui_ctx.begin_group(): + imgui.push_font(app_state.emoji_font) + # ✌️ (Victory Hand Emoji) + imgui.text("\U0000270C\U0000FE0F") + imgui.same_line() + + # ❤️ (Red Heart Emoji) + imgui.text("\U00002764\U0000FE0F") + imgui.same_line() + + # 🌴 (Palm Tree Emoji) + imgui.text("\U0001F334") + imgui.same_line() + + # 🚀 (Rocket Emoji) + imgui.text("\U0001F680") + imgui.pop_font() + + if imgui.is_item_hovered(): + imgui.set_tooltip("Example with NotoEmoji font") + + imgui.text("Colored Fonts") + imgui.push_font(app_state.color_font) + imgui.text("C O L O R !") + imgui.pop_font() + if imgui.is_item_hovered(): + imgui.set_tooltip("Example with Playbox-FREE.otf font") + + +def demo_themes(app_state: AppState): + imgui.push_font(app_state.title_font) + imgui.text("Themes") imgui.pop_font() - hello_imgui.image_from_asset("images/world.png", hello_imgui.em_to_vec2(3.0, 3.0)) + + tweaked_theme = hello_imgui.get_runner_params().imgui_window_params.tweaked_theme + + imgui.begin_group() + button_size = hello_imgui.em_to_vec2(7.0, 0.0) + if imgui.button("Cherry", button_size): + tweaked_theme.theme = hello_imgui.ImGuiTheme_.cherry + hello_imgui.apply_tweaked_theme(tweaked_theme) + if imgui.button("DarculaDarker", button_size): + tweaked_theme.theme = hello_imgui.ImGuiTheme_.darcula_darker + hello_imgui.apply_tweaked_theme(tweaked_theme) + imgui.end_group() + if imgui.is_item_hovered(): + imgui.set_tooltip( + "There are lots of other themes: look at the menu View/Theme\n" + "The selected theme is remembered and restored at startup" + ) def gui_window_demo_features(app_state: AppState): - demo_assets() + demo_fonts(app_state) + imgui.separator() + demo_assets(app_state) imgui.separator() demo_basic_widgets(app_state) imgui.separator() @@ -2320,9 +2530,11 @@ def gui_window_demo_features(app_state: AppState): imgui.separator() demo_user_settings(app_state) imgui.separator() - demo_hide_window() + demo_hide_window(app_state) + imgui.separator() + demo_show_additional_window(app_state) imgui.separator() - demo_show_additional_window() + demo_themes(app_state) imgui.separator() @@ -2442,7 +2654,7 @@ def create_dockable_windows(app_state: AppState) -> List[hello_imgui.DockableWin layout_customization_window = hello_imgui.DockableWindow() layout_customization_window.label = "Layout customization" layout_customization_window.dock_space_name = "MainDockSpace" - layout_customization_window.gui_function = gui_window_layout_customization + layout_customization_window.gui_function = lambda: gui_window_layout_customization(app_state) # A Log window named "Logs" will be placed in "MiscSpace". It uses the HelloImGui logger gui logs_window = hello_imgui.DockableWindow() @@ -2454,6 +2666,7 @@ def create_dockable_windows(app_state: AppState) -> List[hello_imgui.DockableWin dear_imgui_demo_window = hello_imgui.DockableWindow() dear_imgui_demo_window.label = "Dear ImGui Demo" dear_imgui_demo_window.dock_space_name = "MainDockSpace" + dear_imgui_demo_window.imgui_window_flags = imgui.WindowFlags_.menu_bar dear_imgui_demo_window.gui_function = imgui.show_demo_window # type: ignore # additional_window is initially not visible (and not mentioned in the view menu). @@ -2530,13 +2743,17 @@ def main(): # Hello ImGui params (they hold the settings as well as the Gui callbacks) runner_params = hello_imgui.RunnerParams() - runner_params.app_window_params.window_title = "Docking demo" - runner_params.imgui_window_params.menu_app_title = "Docking demo" + runner_params.app_window_params.window_title = "Docking Demo" + runner_params.imgui_window_params.menu_app_title = "Docking Demo" runner_params.app_window_params.window_geometry.size = (1000, 900) runner_params.app_window_params.restore_previous_geometry = True + runner_params.app_window_params.borderless = True + runner_params.app_window_params.borderless_movable = True + runner_params.app_window_params.borderless_resizable = True + runner_params.app_window_params.borderless_closable = True # Set LoadAdditionalFonts callback - runner_params.callbacks.load_additional_fonts = load_fonts + runner_params.callbacks.load_additional_fonts = lambda: load_fonts(app_state) # # Status bar @@ -4859,24 +5076,40 @@ image::{url-doc-images}/immediate_gui_example.png[] Dear ImGui Bundle includes https://github.com/pthom/hello_imgui[Hello ImGui], which is itself based on ImGui. "Hello ImGui" can be compared to a starter pack that enables to easily write cross-platform Gui apps for Windows, macOS, Linux, iOS, and https://en.wikipedia.org/wiki/Emscripten[emscripten]. -==== API +==== API & Usage -See the "Hello ImGui" https://github.com/pthom/hello_imgui/blob/master/src/hello_imgui/hello_imgui_api.md[API doc]. Also consult the doc on how to build {url-himgui-master-tree}/src/hello_imgui/dpi_aware.h[DPI aware] applications. +See the "Hello ImGui" https://pthom.github.io/hello_imgui/book/doc_api.html[API doc] and https://pthom.github.io/hello_imgui/book/doc_params.html[Application parameter doc]. ==== Features -* Full multiplatform support: Windows, Linux, OSX, iOS, Emscripten, Android (poorly supported). See demo https://traineq.org/HelloImGui_6_Platforms.mp4[video] -* Advanced layout handling -* Power Save mode: reduce FPS when application is idle (see https://github.com/pthom/hello_imgui/blob/master/src/hello_imgui/runner_params.h[RunnerParams.fpsIdle]) -* {url-himgui-master-tree}/src/hello_imgui/dpi_aware.h[DPI aware] applications (widget placement, window size, font loading and scaling) -* Theme tweaking (see https://www.youtube.com/watch?v=4f_-3DDcAZk[demo video], and https://github.com/pthom/hello_imgui/blob/master/src/hello_imgui/imgui_theme.h[API] ) -* Window geometry utilities: autosize, restore window position, full screen, etc. (see https://github.com/pthom/hello_imgui/blob/master/src/hello_imgui/app_window_params.h[WindowGeometry]) -* Multiplatform https://github.com/pthom/hello_imgui/blob/master/src/hello_imgui/hello_imgui_assets.h[assets embedding] -* Switch between Glfw or Sdl backend (see https://github.com/pthom/hello_imgui/blob/master/src/hello_imgui/runner_params.h[RunnerParams.backendType]) +**Multiplatform utilities** + +* Truly multiplatform: Linux, Windows, macOS, iOS, Android, emscripten (with 4 lines of CMake code) +* Easily embed assets on all platforms (no code required) +* Customize app settings (icon and app name for mobile platforms, etc.- no code required) +* Customize application icon on all platforms (including mobile and macOS - no code required) + +**Dear ImGui Tweaks** + +* Power Save mode: reduce FPS when idling +* High DPI support: scale UI according to DPI, whatever the platform +* Advanced layout handling: dockable windows, multiple layouts +* Window geometry utilities: autosize application window, restore app window position +* Theme tweaking: extensive list of additional themes +* Support for movable and resizable borderless windows +* Advanced font support: icons, emojis and colored fonts +* Integration with ImGui Test Engine: automate and test your apps +* Save user settings: window position, layout, opened windows, theme, user defined custom settings +* Easily add a custom 3D background to your app + +**Backends** + +* Available platform backends: SDL2, Glfw3 +* Available rendering backends: OpenGL3, Metal, Vulkan, DirectX NOTE: The usage of `Hello ImGui` is optional. You can also build an imgui application from scratch, in {cpp} or in python (see link:{url-bindings-bundle}/demos_python/demos_immapp/imgui_example_glfw_opengl3.py[python example]) -TIP: HelloImGui is fully configurable by POD (plain old data) structures. See link:https://github.com/pthom/hello_imgui/blob/master/src/hello_imgui/hello_imgui_api.md[their description] +TIP: HelloImGui is fully configurable by POD (plain old data) structures. See link:https://pthom.github.io/hello_imgui/book/doc_params.html[their description] ==== Advanced layout and theming with Hello ImGui: diff --git a/bindings/imgui_bundle/doc/doc_parts/manual_himgui.adoc b/bindings/imgui_bundle/doc/doc_parts/manual_himgui.adoc index b87ab217..f9a9a334 100644 --- a/bindings/imgui_bundle/doc/doc_parts/manual_himgui.adoc +++ b/bindings/imgui_bundle/doc/doc_parts/manual_himgui.adoc @@ -4,24 +4,40 @@ include::_utils.adoc[] Dear ImGui Bundle includes https://github.com/pthom/hello_imgui[Hello ImGui], which is itself based on ImGui. "Hello ImGui" can be compared to a starter pack that enables to easily write cross-platform Gui apps for Windows, macOS, Linux, iOS, and https://en.wikipedia.org/wiki/Emscripten[emscripten]. -==== API +==== API & Usage -See the "Hello ImGui" https://github.com/pthom/hello_imgui/blob/master/src/hello_imgui/hello_imgui_api.md[API doc]. Also consult the doc on how to build {url-himgui-master-tree}/src/hello_imgui/dpi_aware.h[DPI aware] applications. +See the "Hello ImGui" https://pthom.github.io/hello_imgui/book/doc_api.html[API doc] and https://pthom.github.io/hello_imgui/book/doc_params.html[Application parameter doc]. ==== Features -* Full multiplatform support: Windows, Linux, OSX, iOS, Emscripten, Android (poorly supported). See demo https://traineq.org/HelloImGui_6_Platforms.mp4[video] -* Advanced layout handling -* Power Save mode: reduce FPS when application is idle (see https://github.com/pthom/hello_imgui/blob/master/src/hello_imgui/runner_params.h[RunnerParams.fpsIdle]) -* {url-himgui-master-tree}/src/hello_imgui/dpi_aware.h[DPI aware] applications (widget placement, window size, font loading and scaling) -* Theme tweaking (see https://www.youtube.com/watch?v=4f_-3DDcAZk[demo video], and https://github.com/pthom/hello_imgui/blob/master/src/hello_imgui/imgui_theme.h[API] ) -* Window geometry utilities: autosize, restore window position, full screen, etc. (see https://github.com/pthom/hello_imgui/blob/master/src/hello_imgui/app_window_params.h[WindowGeometry]) -* Multiplatform https://github.com/pthom/hello_imgui/blob/master/src/hello_imgui/hello_imgui_assets.h[assets embedding] -* Switch between Glfw or Sdl backend (see https://github.com/pthom/hello_imgui/blob/master/src/hello_imgui/runner_params.h[RunnerParams.backendType]) +**Multiplatform utilities** + +* Truly multiplatform: Linux, Windows, macOS, iOS, Android, emscripten (with 4 lines of CMake code) +* Easily embed assets on all platforms (no code required) +* Customize app settings (icon and app name for mobile platforms, etc.- no code required) +* Customize application icon on all platforms (including mobile and macOS - no code required) + +**Dear ImGui Tweaks** + +* Power Save mode: reduce FPS when idling +* High DPI support: scale UI according to DPI, whatever the platform +* Advanced layout handling: dockable windows, multiple layouts +* Window geometry utilities: autosize application window, restore app window position +* Theme tweaking: extensive list of additional themes +* Support for movable and resizable borderless windows +* Advanced font support: icons, emojis and colored fonts +* Integration with ImGui Test Engine: automate and test your apps +* Save user settings: window position, layout, opened windows, theme, user defined custom settings +* Easily add a custom 3D background to your app + +**Backends** + +* Available platform backends: SDL2, Glfw3 +* Available rendering backends: OpenGL3, Metal, Vulkan, DirectX NOTE: The usage of `Hello ImGui` is optional. You can also build an imgui application from scratch, in {cpp} or in python (see link:{url-bindings-bundle}/demos_python/demos_immapp/imgui_example_glfw_opengl3.py[python example]) -TIP: HelloImGui is fully configurable by POD (plain old data) structures. See link:https://github.com/pthom/hello_imgui/blob/master/src/hello_imgui/hello_imgui_api.md[their description] +TIP: HelloImGui is fully configurable by POD (plain old data) structures. See link:https://pthom.github.io/hello_imgui/book/doc_params.html[their description] ==== Advanced layout and theming with Hello ImGui: diff --git a/bindings/imgui_bundle/hello_imgui.pyi b/bindings/imgui_bundle/hello_imgui.pyi index 37d558ab..6efc84eb 100644 --- a/bindings/imgui_bundle/hello_imgui.pyi +++ b/bindings/imgui_bundle/hello_imgui.pyi @@ -70,91 +70,47 @@ def EmptyEventCallback() -> AnyEventCallback: # ////////////////////////////////////////////////////////////////////////////////////////////////////////////// # * -# @@md#Dpi +# @@md#DocEmToVec2 # # Special care must be taken in order to correctly handle screen with high DPI (for example, almost all recent laptops screens). -# Otherwise, widgets might be misplaced or too small, and font rendering might be blurry or too small. # -#### How to position widgets on a window in a Dpi independent way +# Using ImVec2 with fixed values is *almost always a bad idea* if you intend your application to be used on high DPI screens! +# Otherwise, widgets might be misplaced or too small on different screens and/or OSes. # -# Using ImVec2 with fixed values is *almost always a bad idea* if you intend your application to be used on high DPI screens. -# Instead you can: -# * either multiply those values by ImGui::GetFontSize() -# * or use `HelloImGui::EmToVec2(x, y)` which will do this multiplication for you. Em stand for the `em` measurements, -# as used in CSS: 1em simply correspond to the current font height. +# Instead you should use scale your widgets and windows relatively to the font size, as is done +# with the [em CSS Unit](https://lyty.dev/css/css-unit.html). # -# -#### How to load fonts for a crisp font rendering and a correct size -# -# HelloImGui provides `HelloImGui::DpiFontLoadingFactor()` which corresponds to: -# `DpiWindowSizeFactor() * 1. / ImGui::GetIO().FontGlobalScale` -# where DpiWindowSizeFactor() is equal to `CurrentScreenPixelPerInch / 96` under windows and linux, 1 under macOS -# -# ==> When loading fonts, multiply their size by this factor! -# -#### More details on DPI handling with different OS and backends -# -# Let's consider screen whose physical pixel resolution is 3600x2000, but which will displayed with a scaling factor of 200%, -# so that widgets do not look too small on it. -# -# The way it is handled depends on the OS: -# - On MacOS, the screen will be seen as having a resolution of 1800x1000, and the OS handles the resizing by itself. -# - On Linux, and on Windows if the application is DPI aware, the screen will be seen as having a resolution of 3600x2000. -# - On Windows if the application is not DPI aware, the screen will be seen as having a resolution of 1800x1000 -# -# By default, if using the glfw backend, applications will be Dpi aware under windows. -# Sdl applications are normally not Dpi aware. However HelloImGui makes them Dpi aware when using the sdl backend. -# -# -#### HelloImGui Dpi aware C++ API -# -# `HelloImGui::EmSize()` (C++) and `hello_imgui.em_size()` (Python) return the visible font size on the screen. -# For reproducible results, even on HighDPI screens, always scale your widgets and windows relatively to this size. -# It is somewhat comparable to the [em CSS Unit](https://lyty.dev/css/css-unit.html). -# -# `HelloImGui::EmToVec2(x, y)` (C++) and `hello_imgui.em_to_vec2(x,y)` (Python) return an ImVec2 that you can use -# to size or place your widgets in a DPI independent way. -# -# `HelloImGui::EmSize(nbLines)` (C++) and `hello_imgui.em_size(nb_lines)` (Python) return a size corresponding to nbLines text lines -# -# `HelloImGui::DpiFontLoadingFactor()` (C++) and `hello_imgui.dpi_font_loading_factor()` (Python) return a factor by -# which you shall multiply your font sizes when loading fonts manually with _ImGui::GetIO().Fonts->AddFont..._ -# HelloImGui::LoadFontTTF does this by default. -# -# `HelloImGui::ImGuiDefaultFontGlobalScale()` (C++) and `hello_imgui.imgui_default_font_global_scale()` (Python) returns the -# default value that should be stored inside `ImGui::GetIO().FontGlobalScale`. -# Under windows and linux, this is always 1: no rescaling should be done by ImGui. Under macOS and emscripten, -# this can be < 1 (for example it will be 0.5 if the dpi scaling is 200%) # @@md -# +# * -# float EmSize(); /* original C++ signature */ +# @@md#EmToVec2 +# __HelloImGui::EmToVec2()__ returns an ImVec2 that you can use to size +# or place your widgets in a DPI independent way. +# Values are in multiples of the font size (i.e. as in the em CSS unit). +# ImVec2 EmToVec2(float x, float y); /* original C++ signature */ @overload -def em_size() -> float: - """__HelloImGui::EmSize()__ returns the visible font size on the screen. For good results on HighDPI screens, always scale your - widgets and windows relatively to this size. - It is somewhat comparable to the [em CSS Unit](https://lyty.dev/css/css-unit.html). - EmSize() = ImGui::GetFontSize() - """ +def em_to_vec2(x: float, y: float) -> ImVec2: pass -# float EmSize(float nbLines); /* original C++ signature */ +# ImVec2 EmToVec2(ImVec2 v); /* original C++ signature */ @overload -def em_size(nb_lines: float) -> float: - """__HelloImGui::EmSize(nbLines)__ returns a size corresponding to nbLines text lines""" +def em_to_vec2(v: ImVec2) -> ImVec2: pass -# __HelloImGui::EmToVec2()__ returns an ImVec2 that you can use to size or place your widgets in a DPI independent way -# ImVec2 EmToVec2(float x, float y); /* original C++ signature */ +# float EmSize(); /* original C++ signature */ @overload -def em_to_vec2(x: float, y: float) -> ImVec2: +def em_size() -> float: + """__HelloImGui::EmSize()__ returns the visible font size on the screen.""" pass -# ImVec2 EmToVec2(ImVec2 v); /* original C++ signature */ +# float EmSize(float nbLines); /* original C++ signature */ @overload -def em_to_vec2(v: ImVec2) -> ImVec2: +def em_size(nb_lines: float) -> float: + """__HelloImGui::EmSize(nbLines)__ returns a size corresponding to nbLines text lines""" pass +# @@md + # float DpiFontLoadingFactor(); /* original C++ signature */ def dpi_font_loading_factor() -> float: """Multiply font sizes by this factor when loading fonts manually with ImGui::GetIO().Fonts->AddFont... @@ -175,6 +131,8 @@ def imgui_default_font_global_scale() -> float: """returns the default value that should be stored inside `ImGui::GetIO().FontGlobalScale`""" pass +# namespace HelloImGui + # * # @@md#AssetsStructure # @@ -567,7 +525,12 @@ def darcula( # ////////////////////////////////////////////////////////////////////////////////////////////////////////////// class FontLoadingParams: - """Font loading parameters: several options are available (color, merging, range, ...)""" + """@@md#Fonts + + When loading fonts, use HelloImGui::LoadFont(fontFilename, fontSize, fontLoadingParams) + + Font loading parameters: several options are available (color, merging, range, ...) + """ # bool adjustSizeToDpi = true; /* original C++ signature */ # if True, the font size will be adjusted automatically to account for HighDPI @@ -577,8 +540,9 @@ class FontLoadingParams: # if True, the font will be loaded with the full glyph range use_full_glyph_range: bool = False # bool reduceMemoryUsageIfFullGlyphRange = true; /* original C++ signature */ - # if set, fontConfig.GlyphRanges, and fontConfig.OversampleH / fontConfig.OversampleV will be set to 1 - # when useFullGlyphRange is True (this is useful to save memory) + # if set, fontConfig.GlyphRanges, and + # fontConfig.OversampleH / fontConfig.OversampleV will be set to 1 + # when useFullGlyphRange is True (this is useful to save memory) reduce_memory_usage_if_full_glyph_range: bool = True # bool mergeToLastFont = false; /* original C++ signature */ @@ -586,17 +550,20 @@ class FontLoadingParams: merge_to_last_font: bool = False # bool loadColor = false; /* original C++ signature */ - # if True, the font will be loaded using colors (requires freetype, enabled by IMGUI_ENABLE_FREETYPE) + # if True, the font will be loaded using colors + # (requires freetype, enabled by IMGUI_ENABLE_FREETYPE) load_color: bool = False # bool insideAssets = true; /* original C++ signature */ - # if True, the font will be loaded using HelloImGui asset system. Otherwise, it will be loaded from the filesystem + # if True, the font will be loaded using HelloImGui asset system. + # Otherwise, it will be loaded from the filesystem inside_assets: bool = True # std::vector glyphRanges = {}; /* original C++ signature */ # the ranges of glyphs to load: # - if empty, the default glyph range will be used # - you can specify several ranges + # - intervals bounds are inclusive # (will be translated and stored as a static ImWChar* inside fontConfig) glyph_ranges: List[ImWcharPair] = List[ImWcharPair]() @@ -627,7 +594,8 @@ class FontLoadingParams: """Auto-generated default constructor with named params""" pass -# ImFont* LoadFont(const std::string & fontFilename, float fontSize, const FontLoadingParams & params = __srcmlcpp_brace_init__()); /* original C++ signature */ +# ImFont* LoadFont(const std::string & fontFilename, float fontSize, /* original C++ signature */ +# const FontLoadingParams & params = __srcmlcpp_brace_init__()); def load_font( font_filename: str, font_size: float, @@ -635,6 +603,8 @@ def load_font( ) -> ImFont: pass +# @@md + # # Deprecated API below, kept for compatibility (uses LoadFont internally) # @@ -855,8 +825,7 @@ class WindowGeometry: // Will resize the app window at next displayed frame HelloImGui::GetRunnerParams()->appWindowParams.windowGeometry.resizeAppWindowAtNextFrame = True; ``` - - :::Note: this flag is intended to be used during execution, not at startup (use sizeAuto at startup)::: + Note: this flag is intended to be used during execution, not at startup (use sizeAuto at startup). @@md * """ @@ -1438,7 +1407,7 @@ class RunnerCallbacks: # #![demo docking](https://traineq.org/ImGuiBundle/HelloImGuiLayout.gif) # -# * Source for this example: [src/hello_imgui_demos/hello_imgui_demodocking](../../src/hello_imgui_demos/hello_imgui_demodocking) +# * Source for this example: [src/hello_imgui_demos/hello_imgui_demodocking](https://github.com/pthom/hello_imgui/tree/master/src/hello_imgui_demos/hello_imgui_demodocking) # * [Video explanation on YouTube](https://www.youtube.com/watch?v=XKxmz__F4ow) (5 minutes) # # @@ -1930,19 +1899,19 @@ class RunnerParams: **RunnerParams** is a struct that contains all the settings and callbacks needed to run an application. Members: - * `callbacks`: _see [runner_callbacks.h](runner_callbacks.h)_. + * `callbacks`: _see runner_callbacks.h_ callbacks.ShowGui() will render the gui, ShowMenus() will show the menus, etc. - * `appWindowParams`: _see [app_window_params.h](app_window_params.h)_. + * `appWindowParams`: _see app_window_params.h_ application Window Params (position, size, title) - * `imGuiWindowParams`: _see [imgui_window_params.h](imgui_window_params.h)_. + * `imGuiWindowParams`: _see imgui_window_params.h_ imgui window params (use docking, showMenuBar, ProvideFullScreenWindow, etc) - * `dockingParams`: _see [docking_params.h](docking_params.h)_. + * `dockingParams`: _see docking_params.h_ dockable windows content and layout * `alternativeDockingLayouts`: _vector, default=empty_ List of possible additional layout for the applications. Only used in advanced cases when several layouts are available. * `rememberSelectedAlternativeLayout`: _bool, default=true_ Shall the application remember the last selected layout. Only used in advanced cases when several layouts are available. - * `backendPointers`: _see [backend_pointers.h](backend_pointers.h)_. + * `backendPointers`: _see backend_pointers.h_ A struct that contains optional pointers to the backend implementations. These pointers will be filled when the application starts * `backendType`: _enum BackendType, default=BackendType::FirstAvailable_ @@ -2148,18 +2117,6 @@ def run(runner_params: RunnerParams) -> None: Runs an application, using simpler params. * `HelloImGui::Run(guiFunction, windowTitle, windowSize, windowSizeAuto=False, restoreLastWindowGeometry=False, fpsIdle=10)` - - - __Other utilities:__ - - * `HelloImGui::GetRunnerParams()`: - a convenience function that will return the runnerParams of the current application - - * `FrameRate(durationForMean = 0.5)`: Returns the current FrameRate. - May differ from ImGui::GetIO().FrameRate, since one can choose the duration for the calculation of the mean value of the fps - - * `ImGuiTestEngine* GetImGuiTestEngine()`: returns a pointer to the global instance of ImGuiTestEngine that was - initialized by HelloImGui (iif ImGui Test Engine is active). @@md """ @@ -2191,6 +2148,20 @@ def run( # RunnerParams *GetRunnerParams(); /* original C++ signature */ def get_runner_params() -> RunnerParams: + """* + @@md#GetRunnerParams + + * `HelloImGui::GetRunnerParams()`: + a convenience function that will return the runnerParams of the current application + + * `FrameRate(durationForMean = 0.5)`: Returns the current FrameRate. + May differ from ImGui::GetIO().FrameRate, since one can choose the duration for the calculation of the mean value of the fps + + * `ImGuiTestEngine* GetImGuiTestEngine()`: returns a pointer to the global instance of ImGuiTestEngine that was + initialized by HelloImGui (iif ImGui Test Engine is active). + @@md + * + """ pass # float FrameRate(float durationForMean = 0.5f); /* original C++ signature */ @@ -2209,7 +2180,7 @@ def get_imgui_test_engine() -> ImGuiTestEngine: # @@md#HelloImGui::Layouts # # In advanced cases when several layouts are available, you can switch between layouts. -# (see demo inside [hello_imgui_demodocking.main.cpp](../hello_imgui_demos/hello_imgui_demodocking/hello_imgui_demodocking.main.cpp)) +# (see demo inside [hello_imgui_demodocking.main.cpp](https://github.com/pthom/hello_imgui/tree/master/src/hello_imgui_demos/hello_imgui_demodocking/hello_imgui_demodocking.main.cpp)) # # * `SwitchLayout(layoutName)` # Changes the application current layout. Only used in advanced cases when several layouts are available, diff --git a/docs/devel_docs.html b/docs/devel_docs.html index 9d82366b..46e73cc5 100644 --- a/docs/devel_docs.html +++ b/docs/devel_docs.html @@ -484,7 +484,7 @@

Developer docs

diff --git a/docs/faq.html b/docs/faq.html index 51043dba..03001b7f 100644 --- a/docs/faq.html +++ b/docs/faq.html @@ -813,7 +813,7 @@

diff --git a/docs/folders.html b/docs/folders.html index 3e590563..eaeb6808 100644 --- a/docs/folders.html +++ b/docs/folders.html @@ -653,7 +653,7 @@

Repository folders structure

diff --git a/docs/index.html b/docs/index.html index bbbe5e96..5848cf7e 100644 --- a/docs/index.html +++ b/docs/index.html @@ -536,7 +536,7 @@

Dear ImGui Bundle documentation

diff --git a/docs/install-instructions.html b/docs/install-instructions.html index 6c79e5a1..6c4f159b 100644 --- a/docs/install-instructions.html +++ b/docs/install-instructions.html @@ -698,7 +698,7 @@

Run the C++ demo

diff --git a/docs/introduction.html b/docs/introduction.html index 6f94dd43..a9eba183 100644 --- a/docs/introduction.html +++ b/docs/introduction.html @@ -812,7 +812,7 @@

Easily port your code betwe diff --git a/docs/manual.html b/docs/manual.html index 0848676b..4c610f72 100644 --- a/docs/manual.html +++ b/docs/manual.html @@ -675,38 +675,79 @@

Hello ImGui - Starter pack

Dear ImGui Bundle includes Hello ImGui, which is itself based on ImGui. "Hello ImGui" can be compared to a starter pack that enables to easily write cross-platform Gui apps for Windows, macOS, Linux, iOS, and emscripten.

-

API

+

API & Usage

-

See the "Hello ImGui" API doc. Also consult the doc on how to build DPI aware applications.

+

See the "Hello ImGui" API doc and Application parameter doc.

Features

+
+

Multiplatform utilities

+
+
+
    +
  • +

    Truly multiplatform: Linux, Windows, macOS, iOS, Android, emscripten (with 4 lines of CMake code)

    +
  • +
  • +

    Easily embed assets on all platforms (no code required)

    +
  • +
  • +

    Customize app settings (icon and app name for mobile platforms, etc.- no code required)

    +
  • +
  • +

    Customize application icon on all platforms (including mobile and macOS - no code required)

    +
  • +
+
+
+

Dear ImGui Tweaks

+
  • -

    Full multiplatform support: Windows, Linux, OSX, iOS, Emscripten, Android (poorly supported). See demo video

    +

    Power Save mode: reduce FPS when idling

    +
  • +
  • +

    High DPI support: scale UI according to DPI, whatever the platform

    +
  • +
  • +

    Advanced layout handling: dockable windows, multiple layouts

    +
  • +
  • +

    Window geometry utilities: autosize application window, restore app window position

    +
  • +
  • +

    Theme tweaking: extensive list of additional themes

  • -

    Advanced layout handling

    +

    Support for movable and resizable borderless windows

  • -

    Power Save mode: reduce FPS when application is idle (see RunnerParams.fpsIdle)

    +

    Advanced font support: icons, emojis and colored fonts

  • -

    DPI aware applications (widget placement, window size, font loading and scaling)

    +

    Integration with ImGui Test Engine: automate and test your apps

  • -

    Theme tweaking (see demo video, and API )

    +

    Save user settings: window position, layout, opened windows, theme, user defined custom settings

  • -

    Window geometry utilities: autosize, restore window position, full screen, etc. (see WindowGeometry)

    +

    Easily add a custom 3D background to your app

  • +
+
+
+

Backends

+
+
+
  • -

    Multiplatform assets embedding

    +

    Available platform backends: SDL2, Glfw3

  • -

    Switch between Glfw or Sdl backend (see RunnerParams.backendType)

    +

    Available rendering backends: OpenGL3, Metal, Vulkan, DirectX

@@ -729,7 +770,7 @@

Features

Tip
-HelloImGui is fully configurable by POD (plain old data) structures. See their description +HelloImGui is fully configurable by POD (plain old data) structures. See their description @@ -786,7 +827,7 @@

ImmApp - Immediate App

ImGui Bundle includes a library named ImmApp (which stands for Immediate App). ImmApp is a thin extension of HelloImGui that enables to easily initialize the ImGuiBundle addons that require additional setup at startup

-

API

+

API

@@ -1359,7 +1400,7 @@

Usage withing jupyter notebook

40 seconds demo video on Youtube

-

API:

+

API:

@@ -1373,7 +1414,7 @@

API:

diff --git a/docs/porting.html b/docs/porting.html index 2c4df3e5..3f25a3cc 100644 --- a/docs/porting.html +++ b/docs/porting.html @@ -824,7 +824,7 @@

Debug native C++ in python sc diff --git a/docs/quickstart.html b/docs/quickstart.html index 8b99b12e..f716486c 100644 --- a/docs/quickstart.html +++ b/docs/quickstart.html @@ -1497,10 +1497,11 @@

Complex layouts with docking wind - use the status bar - use default menus (App and view menu), and how to customize them - display a log window -- load additional fonts +- load additional fonts, possibly colored, and with emojis - use a specific application state (instead of using static variables) - save some additional user settings within imgui ini file -*/ +- use borderless windows, that are movable and resizable + */ #include "hello_imgui/hello_imgui.h" #include "imgui.h" @@ -1510,6 +1511,21 @@

Complex layouts with docking wind #include <sstream> +// Poor man's fix for C++ late arrival in the unicode party: +// - C++17: u8"my string" is of type const char* +// - C++20: u8"my string" is of type const char8_t* +// However, ImGui text functions expect const char*. +#ifdef __cpp_char8_t +#define U8_TO_CHAR(x) reinterpret_cast<const char*>(x) +#else +#define U8_TO_CHAR(x) x +#endif +// And then, we need to tell gcc to stop validating format string (it gets confused by the u8"" string) +#ifdef __GNUC__ +#pragma GCC diagnostic ignored "-Wformat" +#endif + + ////////////////////////////////////////////////////////////////////////// // Our Application State ////////////////////////////////////////////////////////////////////////// @@ -1535,19 +1551,30 @@

Complex layouts with docking wind RocketState rocket_state = RocketState::Init; MyAppSettings myAppSettings; // This values will be stored in the application settings + ImFont* TitleFont = nullptr; + ImFont* ColorFont = nullptr; + ImFont* EmojiFont = nullptr; }; ////////////////////////////////////////////////////////////////////////// // Additional fonts handling ////////////////////////////////////////////////////////////////////////// -ImFont * gTitleFont; -void LoadFonts() // This is called by runnerParams.callbacks.LoadAdditionalFonts +void LoadFonts(AppState& appState) // This is called by runnerParams.callbacks.LoadAdditionalFonts { // First, load the default font (the default font should be loaded first) HelloImGui::ImGuiDefaultSettings::LoadDefaultFont_WithFontAwesomeIcons(); // Then load the title font - gTitleFont = HelloImGui::LoadFontTTF("fonts/DroidSans.ttf", 18.f); + appState.TitleFont = HelloImGui::LoadFont("fonts/DroidSans.ttf", 18.f); + + HelloImGui::FontLoadingParams fontLoadingParamsEmoji; + fontLoadingParamsEmoji.useFullGlyphRange = true; + appState.EmojiFont = HelloImGui::LoadFont("fonts/NotoEmoji-Regular.ttf", 24.f, fontLoadingParamsEmoji); +#ifdef IMGUI_ENABLE_FREETYPE + HelloImGui::FontLoadingParams fontLoadingParamsColor; + fontLoadingParamsColor.loadColor = true; + appState.ColorFont = HelloImGui::LoadFont("fonts/Playbox/Playbox-FREE.otf", 24.f, fontLoadingParamsColor); +#endif } @@ -1592,17 +1619,17 @@

Complex layouts with docking wind ////////////////////////////////////////////////////////////////////////// // Display a button that will hide the application window -void DemoHideWindow() +void DemoHideWindow(AppState& appState) { - ImGui::PushFont(gTitleFont); ImGui::Text("Hide app window"); ImGui::PopFont(); - ImGui::TextWrapped("By clicking the button below, you can hide the window for 3 seconds."); - + ImGui::PushFont(appState.TitleFont); ImGui::Text("Hide app window"); ImGui::PopFont(); static double lastHideTime = -1.; if (ImGui::Button("Hide")) { lastHideTime = ImGui::GetTime(); HelloImGui::GetRunnerParams()->appWindowParams.hidden = true; } + if (ImGui::IsItemHovered()) + ImGui::SetTooltip("By clicking this button, you can hide the window for 3 seconds."); if (lastHideTime > 0.) { double now = ImGui::GetTime(); @@ -1615,7 +1642,7 @@

Complex layouts with docking wind } // Display a button that will show an additional window -void DemoShowAdditionalWindow() +void DemoShowAdditionalWindow(AppState& appState) { // Notes: // - it is *not* possible to modify the content of the vector runnerParams.dockingParams.dockableWindows @@ -1624,7 +1651,7 @@

Complex layouts with docking wind // * either make them initially invisible, and exclude them from the view menu (such as shown here) // * or modify runnerParams.dockingParams.dockableWindows inside the callback RunnerCallbacks.PreNewFrame const char* windowName = "Additional Window"; - ImGui::PushFont(gTitleFont); ImGui::Text("Dynamically add window"); ImGui::PopFont(); + ImGui::PushFont(appState.TitleFont); ImGui::Text("Dynamically add window"); ImGui::PopFont(); if (ImGui::Button("Show additional window")) { auto additionalWindowPtr = HelloImGui::GetRunnerParams()->dockingParams.dockableWindowOfName(windowName); @@ -1634,14 +1661,15 @@

Complex layouts with docking wind additionalWindowPtr->isVisible = true; } } + if (ImGui::IsItemHovered()) + ImGui::SetTooltip("By clicking this button, you can show an additional window"); } - -void DemoBasicWidgets(AppState& appState) +void DemoLogs(AppState& appState) { - ImGui::PushFont(gTitleFont); ImGui::Text("Basic widgets demo"); ImGui::PopFont(); - ImGui::TextWrapped("The widgets below will interact with the log window"); + ImGui::PushFont(appState.TitleFont); ImGui::Text("Log Demo"); ImGui::PopFont(); + ImGui::BeginGroup(); // Edit a float using a slider from 0.0f to 1.0f bool changed = ImGui::SliderFloat("float", &appState.f, 0.0f, 1.0f); if (changed) @@ -1656,22 +1684,28 @@

Complex layouts with docking wind ImGui::SameLine(); ImGui::Text("counter = %d", appState.counter); + ImGui::EndGroup(); + if (ImGui::IsItemHovered()) + ImGui::SetTooltip("These widgets will interact with the log window"); } void DemoUserSettings(AppState& appState) { - ImGui::PushFont(gTitleFont); ImGui::Text("User settings"); ImGui::PopFont(); - ImGui::TextWrapped("The values below are stored in the application settings ini file and restored at startup"); + ImGui::PushFont(appState.TitleFont); ImGui::Text("User settings"); ImGui::PopFont(); + ImGui::BeginGroup(); ImGui::SetNextItemWidth(HelloImGui::EmSize(7.f)); ImGui::InputText("Name", &appState.myAppSettings.name); ImGui::SetNextItemWidth(HelloImGui::EmSize(7.f)); ImGui::SliderInt("Value", &appState.myAppSettings.value, 0, 100); + ImGui::EndGroup(); + if (ImGui::IsItemHovered()) + ImGui::SetTooltip("The values below are stored in the application settings ini file and restored at startup"); } void DemoRocket(AppState& appState) { - ImGui::PushFont(gTitleFont); ImGui::Text("Rocket demo"); ImGui::PopFont(); - ImGui::TextWrapped("How to show a progress bar in the status bar"); + ImGui::PushFont(appState.TitleFont); ImGui::Text("Status Bar Demo"); ImGui::PopFont(); + ImGui::BeginGroup(); if (appState.rocket_state == AppState::RocketState::Init) { if (ImGui::Button(ICON_FA_ROCKET" Launch rocket")) @@ -1700,11 +1734,14 @@

Complex layouts with docking wind appState.rocket_progress = 0.f; } } + ImGui::EndGroup(); + if (ImGui::IsItemHovered()) + ImGui::SetTooltip("Look at the status bar after clicking"); } -void DemoDockingFlags() +void DemoDockingFlags(AppState& appState) { - ImGui::PushFont(gTitleFont); ImGui::Text("Main dock space node flags"); ImGui::PopFont(); + ImGui::PushFont(appState.TitleFont); ImGui::Text("Main dock space node flags"); ImGui::PopFont(); ImGui::TextWrapped(R"( This will edit the ImGuiDockNodeFlags for "MainDockSpace". Most flags are inherited by children dock spaces. @@ -1726,7 +1763,7 @@

Complex layouts with docking wind // {ImGuiDockNodeFlags_PassthruCentralNode, "PassthruCentralNode", "advanced"}, }; auto & mainDockSpaceNodeFlags = HelloImGui::GetRunnerParams()->dockingParams.mainDockSpaceNodeFlags; - for (auto flag: all_flags) + for (const auto& flag: all_flags) { ImGui::CheckboxFlags(flag.label.c_str(), &mainDockSpaceNodeFlags, flag.flag); if (ImGui::IsItemHovered()) @@ -1734,41 +1771,122 @@

Complex layouts with docking wind } } -void GuiWindowLayoutCustomization() +void GuiWindowLayoutCustomization(AppState& appState) { - ImGui::PushFont(gTitleFont); ImGui::Text("Switch between layouts"); ImGui::PopFont(); + ImGui::PushFont(appState.TitleFont); ImGui::Text("Switch between layouts"); ImGui::PopFont(); ImGui::Text("with the menu \"View/Layouts\""); if (ImGui::IsItemHovered()) ImGui::SetTooltip("Each layout remembers separately the modifications applied by the user, \nand the selected layout is restored at startup"); ImGui::Separator(); - ImGui::PushFont(gTitleFont); ImGui::Text("Change the theme"); ImGui::PopFont(); + ImGui::PushFont(appState.TitleFont); ImGui::Text("Change the theme"); ImGui::PopFont(); ImGui::Text("with the menu \"View/Theme\""); if (ImGui::IsItemHovered()) ImGui::SetTooltip("The selected theme is remembered and restored at startup"); ImGui::Separator(); - DemoDockingFlags(); + DemoDockingFlags(appState); ImGui::Separator(); } -void DemoAssets() +void DemoAssets(AppState& appState) { - ImGui::PushFont(gTitleFont); ImGui::Text("Hello"); ImGui::PopFont(); - HelloImGui::ImageFromAsset("images/world.png", HelloImGui::EmToVec2(3.f, 3.f)); + ImGui::PushFont(appState.TitleFont); ImGui::Text("Image From Asset"); ImGui::PopFont(); + HelloImGui::BeginGroupColumn(); + ImGui::Dummy(HelloImGui::EmToVec2(0.f, 0.45f)); + ImGui::Text("Hello"); + HelloImGui::EndGroupColumn(); + HelloImGui::ImageFromAsset("images/world.png", HelloImGui::EmToVec2(2.5f, 2.5f)); } +void DemoFonts(AppState& appState) +{ + ImGui::PushFont(appState.TitleFont); ImGui::Text("Fonts"); ImGui::PopFont(); + + ImGui::TextWrapped("Mix icons " ICON_FA_SMILE " and text " ICON_FA_ROCKET ""); + if (ImGui::IsItemHovered()) + ImGui::SetTooltip("Example with Font Awesome Icons"); + + ImGui::Text("Emojis"); + + ImGui::BeginGroup(); + { + ImGui::PushFont(appState.EmojiFont); + // ✌️ (Victory Hand Emoji) + ImGui::Text(U8_TO_CHAR(u8"\U0000270C\U0000FE0F")); + ImGui::SameLine(); + + // ❤️ (Red Heart Emoji) + ImGui::Text(U8_TO_CHAR(u8"\U00002764\U0000FE0F")); + ImGui::SameLine(); + +#ifdef IMGUI_USE_WCHAR32 + // 🌴 (Palm Tree Emoji) + ImGui::Text(U8_TO_CHAR(u8"\U0001F334")); + ImGui::SameLine(); + + // 🚀 (Rocket Emoji) + ImGui::Text(U8_TO_CHAR(u8"\U0001F680")); + ImGui::SameLine(); +#endif + + ImGui::PopFont(); + } + ImGui::EndGroup(); + if (ImGui::IsItemHovered()) + ImGui::SetTooltip("Example with NotoEmoji font"); + +#ifdef IMGUI_ENABLE_FREETYPE + ImGui::Text("Colored Fonts"); + ImGui::PushFont(appState.ColorFont); + ImGui::Text("C O L O R !"); + ImGui::PopFont(); + if (ImGui::IsItemHovered()) + ImGui::SetTooltip("Example with Playbox-FREE.otf font"); +#endif +} + +void DemoThemes(AppState& appState) +{ + ImGui::PushFont(appState.TitleFont); ImGui::Text("Themes"); ImGui::PopFont(); + auto& tweakedTheme = HelloImGui::GetRunnerParams()->imGuiWindowParams.tweakedTheme; + + ImGui::BeginGroup(); + ImVec2 buttonSize = HelloImGui::EmToVec2(7.f, 0.f); + if (ImGui::Button("Cherry", buttonSize)) + { + tweakedTheme.Theme = ImGuiTheme::ImGuiTheme_Cherry; + ImGuiTheme::ApplyTweakedTheme(tweakedTheme); + } + if (ImGui::Button("DarculaDarker", buttonSize)) + { + tweakedTheme.Theme = ImGuiTheme::ImGuiTheme_DarculaDarker; + ImGuiTheme::ApplyTweakedTheme(tweakedTheme); + } + ImGui::EndGroup(); + if (ImGui::IsItemHovered()) + ImGui::SetTooltip( + "There are lots of other themes: look at the menu View/Theme\n" + "The selected theme is remembered and restored at startup" + ); +} + +// The Gui of the demo feature window void GuiWindowDemoFeatures(AppState& appState) { - DemoAssets(); + DemoFonts(appState); + ImGui::Separator(); + DemoAssets(appState); ImGui::Separator(); - DemoBasicWidgets(appState); + DemoLogs(appState); ImGui::Separator(); DemoRocket(appState); ImGui::Separator(); DemoUserSettings(appState); ImGui::Separator(); - DemoHideWindow(); + DemoHideWindow(appState); ImGui::Separator(); - DemoShowAdditionalWindow(); + DemoShowAdditionalWindow(appState); + ImGui::Separator(); + DemoThemes(appState); ImGui::Separator(); } @@ -1897,7 +2015,7 @@

Complex layouts with docking wind HelloImGui::DockableWindow layoutCustomizationWindow; layoutCustomizationWindow.label = "Layout customization"; layoutCustomizationWindow.dockSpaceName = "MainDockSpace"; - layoutCustomizationWindow.GuiFunction = GuiWindowLayoutCustomization; + layoutCustomizationWindow.GuiFunction = [&appState]() { GuiWindowLayoutCustomization(appState); }; // A Log window named "Logs" will be placed in "MiscSpace". It uses the HelloImGui logger gui HelloImGui::DockableWindow logsWindow; @@ -1909,6 +2027,7 @@

Complex layouts with docking wind HelloImGui::DockableWindow dearImGuiDemoWindow; dearImGuiDemoWindow.label = "Dear ImGui Demo"; dearImGuiDemoWindow.dockSpaceName = "MainDockSpace"; + dearImGuiDemoWindow.imGuiWindowFlags = ImGuiWindowFlags_MenuBar; dearImGuiDemoWindow.GuiFunction = [] { ImGui::ShowDemoWindow(); }; // additionalWindow is initially not visible (and not mentioned in the view menu). @@ -1929,14 +2048,14 @@

Complex layouts with docking wind additionalWindow, }; return dockableWindows; -}; +} // // 3. Define the layouts: // A layout is stored inside DockingParams, and stores the splits + the dockable windows. // Here, we provide the default layout, and two alternative layouts. // -HelloImGui::DockingParams CreateDefaultLayout(AppState& appState) +HelloImGui::DockingParams CreateDefaultLayout(AppState& appState) { HelloImGui::DockingParams dockingParams; // dockingParams.layoutName = "Default"; // By default, the layout name is already "Default" @@ -1964,13 +2083,13 @@

Complex layouts with docking wind tabsLayout.dockingSplits = {}; } return {alternativeLayout, tabsLayout}; -}; +} ////////////////////////////////////////////////////////////////////////// // main(): here, we simply fill RunnerParams, then run the application ////////////////////////////////////////////////////////////////////////// -int main(int, char**) +int main(int, char**) { ChdirBesideAssetsFolder(); @@ -1984,13 +2103,17 @@

Complex layouts with docking wind // Hello ImGui params (they hold the settings as well as the Gui callbacks) HelloImGui::RunnerParams runnerParams; - runnerParams.appWindowParams.windowTitle = "Docking demo"; - runnerParams.imGuiWindowParams.menuAppTitle = "Docking demo"; + runnerParams.appWindowParams.windowTitle = "Docking Demo"; + runnerParams.imGuiWindowParams.menuAppTitle = "Docking Demo"; runnerParams.appWindowParams.windowGeometry.size = {1000, 900}; runnerParams.appWindowParams.restorePreviousGeometry = true; + runnerParams.appWindowParams.borderless = true; + runnerParams.appWindowParams.borderlessMovable = true; + runnerParams.appWindowParams.borderlessResizable = true; + runnerParams.appWindowParams.borderlessClosable = true; // Set LoadAdditionalFonts callback - runnerParams.callbacks.LoadAdditionalFonts = LoadFonts; + runnerParams.callbacks.LoadAdditionalFonts = [&appState]() { LoadFonts(appState); }; // // Status bar @@ -2094,17 +2217,19 @@

Complex layouts with docking wind # # It demonstrates how to: # - set up a complex docking layouts (with several possible layouts): +# - load additional fonts, possibly colored, and with emojis +# - display a log window # - use the status bar # - use default menus (App and view menu), and how to customize them -# - display a log window -# - load additional fonts # - use a specific application state (instead of using static variables) # - save some additional user settings within imgui ini file +# - use borderless windows, that are movable and resizable + from enum import Enum import time -from imgui_bundle import hello_imgui, icons_fontawesome, imgui, immapp +from imgui_bundle import hello_imgui, icons_fontawesome, imgui, immapp, imgui_ctx from imgui_bundle.demos_python import demo_utils from typing import List @@ -2132,6 +2257,10 @@

Complex layouts with docking wind rocket_state: RocketState rocket_launch_time: float + title_font: imgui.ImFont + color_font: imgui.ImFont + emoji_font: imgui.ImFont + def __init__(self): self.f = 0 self.counter = 0 @@ -2144,17 +2273,19 @@

Complex layouts with docking wind ########################################################################## # Additional fonts handling ########################################################################## - -TITLE_FONT: imgui.ImFont - - -def load_fonts(): # This is called by runnerParams.callbacks.LoadAdditionalFonts - global TITLE_FONT +def load_fonts(app_state: AppState): # This is called by runnerParams.callbacks.LoadAdditionalFonts # First, load the default font (the default font should be loaded first) hello_imgui.imgui_default_settings.load_default_font_with_font_awesome_icons() # Then load the title font - TITLE_FONT = hello_imgui.load_font_ttf("fonts/DroidSans.ttf", 18.0) + app_state.title_font = hello_imgui.load_font("fonts/DroidSans.ttf", 18.0) + font_loading_params_emoji = hello_imgui.FontLoadingParams() + font_loading_params_emoji.use_full_glyph_range = True + app_state.emoji_font = hello_imgui.load_font("fonts/NotoEmoji-Regular.ttf", 24., font_loading_params_emoji) + + font_loading_params_color = hello_imgui.FontLoadingParams() + font_loading_params_color.load_color = True + app_state.color_font = hello_imgui.load_font("fonts/Playbox/Playbox-FREE.otf", 24., font_loading_params_color) ########################################################################## # Save additional settings in the ini file @@ -2199,19 +2330,17 @@

Complex layouts with docking wind # Gui functions used in this demo ########################################################################## @immapp.static(last_hide_time=1) -def demo_hide_window(): +def demo_hide_window(app_state: AppState): # Display a button that will hide the application window - imgui.push_font(TITLE_FONT) + imgui.push_font(app_state.title_font) imgui.text("Hide app window") imgui.pop_font() - imgui.text_wrapped( - "By clicking the button below, you can hide the window for 3 seconds." - ) if imgui.button("Hide"): demo_hide_window.last_hide_time = time.time() hello_imgui.get_runner_params().app_window_params.hidden = True - + if imgui.is_item_hovered(): + imgui.set_tooltip("By clicking this button, you can hide the window for 3 seconds.") if demo_hide_window.last_hide_time > 0.0: now = time.time() if now - demo_hide_window.last_hide_time > 3.0: @@ -2220,7 +2349,7 @@

Complex layouts with docking wind # Display a button that will show an additional window -def demo_show_additional_window(): +def demo_show_additional_window(app_state: AppState): # Notes: # - it is *not* possible to modify the content of the vector runnerParams.dockingParams.dockableWindows # from the code inside a window's `GuiFunction` (since this GuiFunction will be called while iterating @@ -2230,7 +2359,7 @@

Complex layouts with docking wind # * or modify runnerParams.dockingParams.dockableWindows inside the callback RunnerCallbacks.PreNewFrame window_name = "Additional Window" - imgui.push_font(TITLE_FONT) + imgui.push_font(app_state.title_font) imgui.text("Dynamically add window") imgui.pop_font() @@ -2242,14 +2371,16 @@

Complex layouts with docking wind if additional_window_ptr: # additional_window_ptr.include_in_view_menu = True additional_window_ptr.is_visible = True + if imgui.is_item_hovered(): + imgui.set_tooltip("By clicking this button, you can show an additional window") def demo_basic_widgets(app_state: AppState): - imgui.push_font(TITLE_FONT) + imgui.push_font(app_state.title_font) imgui.text("Basic widgets demo") imgui.pop_font() - imgui.text_wrapped("The widgets below will interact with the log window") + imgui.begin_group() # Edit a float using a slider from 0.0 to 1.0 changed, app_state.f = imgui.slider_float("float", app_state.f, 0.0, 1.0) if changed: @@ -2263,15 +2394,18 @@

Complex layouts with docking wind hello_imgui.log(hello_imgui.LogLevel.info, "Button was pressed") imgui.same_line() imgui.text(f"counter = {app_state.counter}") + imgui.end_group() + + if imgui.is_item_hovered(): + imgui.set_tooltip("These widgets will interact with the log window") def demo_user_settings(app_state: AppState): - imgui.push_font(TITLE_FONT) + imgui.push_font(app_state.title_font) imgui.text("User settings") imgui.pop_font() - imgui.text_wrapped( - "The values below are stored in the application settings ini file and restored at startup" - ) + + imgui.begin_group() imgui.set_next_item_width(hello_imgui.em_size(7.0)) _, app_state.my_app_settings.name = imgui.input_text( "Name", app_state.my_app_settings.name @@ -2280,13 +2414,17 @@

Complex layouts with docking wind _, app_state.my_app_settings.value = imgui.slider_int( "Value", app_state.my_app_settings.value, 0, 100 ) + imgui.end_group() + if imgui.is_item_hovered(): + imgui.set_tooltip("The values below are stored in the application settings ini file and restored at startup") def demo_rocket(app_state: AppState): - imgui.push_font(TITLE_FONT) + imgui.push_font(app_state.title_font) imgui.text("Rocket demo") imgui.pop_font() - imgui.text_wrapped("How to show a progress bar in the status bar") + + imgui.begin_group() if app_state.rocket_state == RocketState.Init: if imgui.button(f"{icons_fontawesome.ICON_FA_ROCKET} Launch rocket"): app_state.rocket_launch_time = time.time() @@ -2303,10 +2441,13 @@

Complex layouts with docking wind if imgui.button("Reset Rocket"): app_state.rocket_state = RocketState.Init app_state.rocket_progress = 0.0 + imgui.end_group() + if imgui.is_item_hovered(): + imgui.set_tooltip("Look at the status bar after clicking") -def demo_docking_flags(): - imgui.push_font(TITLE_FONT) +def demo_docking_flags(app_state: AppState): + imgui.push_font(app_state.title_font) imgui.text("Main dock space node flags") imgui.pop_font() imgui.text_wrapped( @@ -2362,8 +2503,8 @@

Complex layouts with docking wind ) -def gui_window_layout_customization(): - imgui.push_font(TITLE_FONT) +def gui_window_layout_customization(app_state: AppState): + imgui.push_font(app_state.title_font) imgui.text("Switch between layouts") imgui.pop_font() imgui.text('with the menu "View/Layouts"') @@ -2375,7 +2516,7 @@

Complex layouts with docking wind imgui.separator() - imgui.push_font(TITLE_FONT) + imgui.push_font(app_state.title_font) imgui.text("Change the theme") imgui.pop_font() imgui.text('with the menu "View/Theme"') @@ -2383,19 +2524,88 @@

Complex layouts with docking wind imgui.set_tooltip("The selected theme is remembered and restored at startup") imgui.separator() - demo_docking_flags() + demo_docking_flags(app_state) imgui.separator() -def demo_assets(): - imgui.push_font(TITLE_FONT) +def demo_assets(app_state: AppState): + imgui.push_font(app_state.title_font) + imgui.text("Image From Assets") + imgui.pop_font() + hello_imgui.begin_group_column() + imgui.dummy(hello_imgui.em_to_vec2(0.0, 0.45)) imgui.text("Hello") + hello_imgui.end_group_column() + hello_imgui.image_from_asset("images/world.png", hello_imgui.em_to_vec2(2.5, 2.5)) + + +def demo_fonts(app_state: AppState): + imgui.push_font(app_state.title_font) + imgui.text("Fonts") + imgui.pop_font() + + imgui.text_wrapped("Mix icons " + icons_fontawesome.ICON_FA_SMILE + " and text " + icons_fontawesome.ICON_FA_ROCKET) + if imgui.is_item_hovered(): + imgui.set_tooltip("Example with Font Awesome Icons") + + imgui.text("Emojis") + + with imgui_ctx.begin_group(): + imgui.push_font(app_state.emoji_font) + # ✌️ (Victory Hand Emoji) + imgui.text("\U0000270C\U0000FE0F") + imgui.same_line() + + # ❤️ (Red Heart Emoji) + imgui.text("\U00002764\U0000FE0F") + imgui.same_line() + + # 🌴 (Palm Tree Emoji) + imgui.text("\U0001F334") + imgui.same_line() + + # 🚀 (Rocket Emoji) + imgui.text("\U0001F680") + imgui.pop_font() + + if imgui.is_item_hovered(): + imgui.set_tooltip("Example with NotoEmoji font") + + imgui.text("Colored Fonts") + imgui.push_font(app_state.color_font) + imgui.text("C O L O R !") + imgui.pop_font() + if imgui.is_item_hovered(): + imgui.set_tooltip("Example with Playbox-FREE.otf font") + + +def demo_themes(app_state: AppState): + imgui.push_font(app_state.title_font) + imgui.text("Themes") imgui.pop_font() - hello_imgui.image_from_asset("images/world.png", hello_imgui.em_to_vec2(3.0, 3.0)) + + tweaked_theme = hello_imgui.get_runner_params().imgui_window_params.tweaked_theme + + imgui.begin_group() + button_size = hello_imgui.em_to_vec2(7.0, 0.0) + if imgui.button("Cherry", button_size): + tweaked_theme.theme = hello_imgui.ImGuiTheme_.cherry + hello_imgui.apply_tweaked_theme(tweaked_theme) + if imgui.button("DarculaDarker", button_size): + tweaked_theme.theme = hello_imgui.ImGuiTheme_.darcula_darker + hello_imgui.apply_tweaked_theme(tweaked_theme) + imgui.end_group() + if imgui.is_item_hovered(): + imgui.set_tooltip( + "There are lots of other themes: look at the menu View/Theme\n" + "The selected theme is remembered and restored at startup" + ) def gui_window_demo_features(app_state: AppState): - demo_assets() + demo_fonts(app_state) + imgui.separator() + demo_assets(app_state) imgui.separator() demo_basic_widgets(app_state) imgui.separator() @@ -2403,9 +2613,11 @@

Complex layouts with docking wind imgui.separator() demo_user_settings(app_state) imgui.separator() - demo_hide_window() + demo_hide_window(app_state) + imgui.separator() + demo_show_additional_window(app_state) imgui.separator() - demo_show_additional_window() + demo_themes(app_state) imgui.separator() @@ -2525,7 +2737,7 @@

Complex layouts with docking wind layout_customization_window = hello_imgui.DockableWindow() layout_customization_window.label = "Layout customization" layout_customization_window.dock_space_name = "MainDockSpace" - layout_customization_window.gui_function = gui_window_layout_customization + layout_customization_window.gui_function = lambda: gui_window_layout_customization(app_state) # A Log window named "Logs" will be placed in "MiscSpace". It uses the HelloImGui logger gui logs_window = hello_imgui.DockableWindow() @@ -2537,6 +2749,7 @@

Complex layouts with docking wind dear_imgui_demo_window = hello_imgui.DockableWindow() dear_imgui_demo_window.label = "Dear ImGui Demo" dear_imgui_demo_window.dock_space_name = "MainDockSpace" + dear_imgui_demo_window.imgui_window_flags = imgui.WindowFlags_.menu_bar dear_imgui_demo_window.gui_function = imgui.show_demo_window # type: ignore # additional_window is initially not visible (and not mentioned in the view menu). @@ -2613,13 +2826,17 @@

Complex layouts with docking wind # Hello ImGui params (they hold the settings as well as the Gui callbacks) runner_params = hello_imgui.RunnerParams() - runner_params.app_window_params.window_title = "Docking demo" - runner_params.imgui_window_params.menu_app_title = "Docking demo" + runner_params.app_window_params.window_title = "Docking Demo" + runner_params.imgui_window_params.menu_app_title = "Docking Demo" runner_params.app_window_params.window_geometry.size = (1000, 900) runner_params.app_window_params.restore_previous_geometry = True + runner_params.app_window_params.borderless = True + runner_params.app_window_params.borderless_movable = True + runner_params.app_window_params.borderless_resizable = True + runner_params.app_window_params.borderless_closable = True # Set LoadAdditionalFonts callback - runner_params.callbacks.load_additional_fonts = load_fonts + runner_params.callbacks.load_additional_fonts = lambda: load_fonts(app_state) # # Status bar @@ -4918,7 +5135,7 @@

And many more!

diff --git a/docs/words_author.html b/docs/words_author.html index 54a3f468..35d97d96 100644 --- a/docs/words_author.html +++ b/docs/words_author.html @@ -646,7 +646,7 @@

History

diff --git a/external/hello_imgui/bindings/hello_imgui_amalgamation.h b/external/hello_imgui/bindings/hello_imgui_amalgamation.h index 3501b40e..2a2e0e04 100644 --- a/external/hello_imgui/bindings/hello_imgui_amalgamation.h +++ b/external/hello_imgui/bindings/hello_imgui_amalgamation.h @@ -15,91 +15,53 @@ ////////////////////////////////////////////////////////////////////////////////////////////////////////////////// #include "imgui.h" +namespace HelloImGui +{ /** -@@md#Dpi +@@md#DocEmToVec2 Special care must be taken in order to correctly handle screen with high DPI (for example, almost all recent laptops screens). -Otherwise, widgets might be misplaced or too small, and font rendering might be blurry or too small. - -### How to position widgets on a window in a Dpi independent way - -Using ImVec2 with fixed values is *almost always a bad idea* if you intend your application to be used on high DPI screens. -Instead you can: -* either multiply those values by ImGui::GetFontSize() -* or use `HelloImGui::EmToVec2(x, y)` which will do this multiplication for you. Em stand for the `em` measurements, - as used in CSS: 1em simply correspond to the current font height. - - -### How to load fonts for a crisp font rendering and a correct size - -HelloImGui provides `HelloImGui::DpiFontLoadingFactor()` which corresponds to: - `DpiWindowSizeFactor() * 1.f / ImGui::GetIO().FontGlobalScale` - where DpiWindowSizeFactor() is equal to `CurrentScreenPixelPerInch / 96` under windows and linux, 1 under macOS -==> When loading fonts, multiply their size by this factor! +Using ImVec2 with fixed values is *almost always a bad idea* if you intend your application to be used on high DPI screens! + Otherwise, widgets might be misplaced or too small on different screens and/or OSes. -### More details on DPI handling with different OS and backends +Instead you should use scale your widgets and windows relatively to the font size, as is done +with the [em CSS Unit](https://lyty.dev/css/css-unit.html). -Let's consider screen whose physical pixel resolution is 3600x2000, but which will displayed with a scaling factor of 200%, - so that widgets do not look too small on it. - -The way it is handled depends on the OS: -- On MacOS, the screen will be seen as having a resolution of 1800x1000, and the OS handles the resizing by itself. -- On Linux, and on Windows if the application is DPI aware, the screen will be seen as having a resolution of 3600x2000. -- On Windows if the application is not DPI aware, the screen will be seen as having a resolution of 1800x1000 - -By default, if using the glfw backend, applications will be Dpi aware under windows. -Sdl applications are normally not Dpi aware. However HelloImGui makes them Dpi aware when using the sdl backend. - - -### HelloImGui Dpi aware C++ API - -`HelloImGui::EmSize()` (C++) and `hello_imgui.em_size()` (Python) return the visible font size on the screen. -For reproducible results, even on HighDPI screens, always scale your widgets and windows relatively to this size. - It is somewhat comparable to the [em CSS Unit](https://lyty.dev/css/css-unit.html). +@@md +**/ -`HelloImGui::EmToVec2(x, y)` (C++) and `hello_imgui.em_to_vec2(x,y)` (Python) return an ImVec2 that you can use - to size or place your widgets in a DPI independent way. +// @@md#EmToVec2 +// __HelloImGui::EmToVec2()__ returns an ImVec2 that you can use to size +// or place your widgets in a DPI independent way. +// Values are in multiples of the font size (i.e. as in the em CSS unit). +ImVec2 EmToVec2(float x, float y); +ImVec2 EmToVec2(ImVec2 v); -`HelloImGui::EmSize(nbLines)` (C++) and `hello_imgui.em_size(nb_lines)` (Python) return a size corresponding to nbLines text lines +// __HelloImGui::EmSize()__ returns the visible font size on the screen. +float EmSize(); +// __HelloImGui::EmSize(nbLines)__ returns a size corresponding to nbLines text lines +float EmSize(float nbLines); +// @@md -`HelloImGui::DpiFontLoadingFactor()` (C++) and `hello_imgui.dpi_font_loading_factor()` (Python) return a factor by - which you shall multiply your font sizes when loading fonts manually with _ImGui::GetIO().Fonts->AddFont..._ - HelloImGui::LoadFontTTF does this by default. +} // namespace HelloImGui -`HelloImGui::ImGuiDefaultFontGlobalScale()` (C++) and `hello_imgui.imgui_default_font_global_scale()` (Python) returns the - default value that should be stored inside `ImGui::GetIO().FontGlobalScale`. - Under windows and linux, this is always 1: no rescaling should be done by ImGui. Under macOS and emscripten, - this can be < 1 (for example it will be 0.5 if the dpi scaling is 200%) -@@md -*/ namespace HelloImGui { - // __HelloImGui::EmSize()__ returns the visible font size on the screen. For good results on HighDPI screens, always scale your - // widgets and windows relatively to this size. - // It is somewhat comparable to the [em CSS Unit](https://lyty.dev/css/css-unit.html). - // EmSize() = ImGui::GetFontSize() - float EmSize(); - - // __HelloImGui::EmSize(nbLines)__ returns a size corresponding to nbLines text lines - float EmSize(float nbLines); +// Multiply font sizes by this factor when loading fonts manually with ImGui::GetIO().Fonts->AddFont... +// (HelloImGui::LoadFontTTF does this by default) +float DpiFontLoadingFactor(); - // __HelloImGui::EmToVec2()__ returns an ImVec2 that you can use to size or place your widgets in a DPI independent way - ImVec2 EmToVec2(float x, float y); - ImVec2 EmToVec2(ImVec2 v); +// DpiWindowSizeFactor() is the factor by which window size should be multiplied to get a similar visible size on different OSes. +// It returns ApplicationScreenPixelPerInch / 96 under windows and linux. Under macOS, it will return 1. +float DpiWindowSizeFactor(); - // Multiply font sizes by this factor when loading fonts manually with ImGui::GetIO().Fonts->AddFont... - // (HelloImGui::LoadFontTTF does this by default) - float DpiFontLoadingFactor(); +// returns the default value that should be stored inside `ImGui::GetIO().FontGlobalScale` +float ImGuiDefaultFontGlobalScale(); +} // namespace HelloImGui - // DpiWindowSizeFactor() is the factor by which window size should be multiplied to get a similar visible size on different OSes. - // It returns ApplicationScreenPixelPerInch / 96 under windows and linux. Under macOS, it will return 1. - float DpiWindowSizeFactor(); - // returns the default value that should be stored inside `ImGui::GetIO().FontGlobalScale` - float ImGuiDefaultFontGlobalScale(); -} ////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // hello_imgui/hello_imgui_assets.h included by hello_imgui.h // ////////////////////////////////////////////////////////////////////////////////////////////////////////////////// @@ -1384,6 +1346,10 @@ namespace HelloImGui { using ImWcharPair = std::array; + // @@md#Fonts + // + // When loading fonts, use HelloImGui::LoadFont(fontFilename, fontSize, fontLoadingParams) + // // Font loading parameters: several options are available (color, merging, range, ...) struct FontLoadingParams { @@ -1392,22 +1358,26 @@ namespace HelloImGui // if true, the font will be loaded with the full glyph range bool useFullGlyphRange = false; - // if set, fontConfig.GlyphRanges, and fontConfig.OversampleH / fontConfig.OversampleV will be set to 1 - // when useFullGlyphRange is true (this is useful to save memory) + // if set, fontConfig.GlyphRanges, and + // fontConfig.OversampleH / fontConfig.OversampleV will be set to 1 + // when useFullGlyphRange is true (this is useful to save memory) bool reduceMemoryUsageIfFullGlyphRange = true; // if true, the font will be merged to the last font bool mergeToLastFont = false; - // if true, the font will be loaded using colors (requires freetype, enabled by IMGUI_ENABLE_FREETYPE) + // if true, the font will be loaded using colors + // (requires freetype, enabled by IMGUI_ENABLE_FREETYPE) bool loadColor = false; - // if true, the font will be loaded using HelloImGui asset system. Otherwise, it will be loaded from the filesystem + // if true, the font will be loaded using HelloImGui asset system. + // Otherwise, it will be loaded from the filesystem bool insideAssets = true; // the ranges of glyphs to load: // - if empty, the default glyph range will be used // - you can specify several ranges + // - intervals bounds are inclusive // (will be translated and stored as a static ImWChar* inside fontConfig) std::vector glyphRanges = {}; @@ -1420,8 +1390,17 @@ namespace HelloImGui ImFontConfig fontConfigFontAwesome = ImFontConfig(); }; - // Generic font loading function, with many options: see FontLoadingParams and ImFontConfig - ImFont* LoadFont(const std::string & fontFilename, float fontSize, const FontLoadingParams & params = {}); + // When loading fonts, use HelloImGui::LoadFont(FontLoadingParams) + // =============================================================== + // instead of ImGui::GetIO().Fonts->AddFontFromFileTTF(), because it will + // automatically adjust the font size to account for HighDPI, and will spare + // you headaches when trying to get consistent font size across different OSes. + // see FontLoadingParams and ImFontConfig + ImFont* LoadFont(const std::string & fontFilename, float fontSize, + const FontLoadingParams & params = {}); + + + // @@md // @@ -1609,8 +1588,7 @@ __WindowGeometry__ is a struct that defines the window geometry. // Will resize the app window at next displayed frame HelloImGui::GetRunnerParams()->appWindowParams.windowGeometry.resizeAppWindowAtNextFrame = true; ``` - - :::Note: this flag is intended to be used during execution, not at startup (use sizeAuto at startup)::: + Note: this flag is intended to be used during execution, not at startup (use sizeAuto at startup). @@md **/ struct WindowGeometry @@ -2055,7 +2033,7 @@ HelloImGui will then provide a "View" menu with options to show/hide the dockabl ![demo docking](https://traineq.org/ImGuiBundle/HelloImGuiLayout.gif) -* Source for this example: [src/hello_imgui_demos/hello_imgui_demodocking](../../src/hello_imgui_demos/hello_imgui_demodocking) +* Source for this example: [src/hello_imgui_demos/hello_imgui_demodocking](https://github.com/pthom/hello_imgui/tree/master/src/hello_imgui_demos/hello_imgui_demodocking) * [Video explanation on YouTube](https://www.youtube.com/watch?v=XKxmz__F4ow) (5 minutes) @@ -2466,19 +2444,19 @@ struct FpsIdling **RunnerParams** is a struct that contains all the settings and callbacks needed to run an application. Members: -* `callbacks`: _see [runner_callbacks.h](runner_callbacks.h)_. +* `callbacks`: _see runner_callbacks.h_ callbacks.ShowGui() will render the gui, ShowMenus() will show the menus, etc. -* `appWindowParams`: _see [app_window_params.h](app_window_params.h)_. +* `appWindowParams`: _see app_window_params.h_ application Window Params (position, size, title) -* `imGuiWindowParams`: _see [imgui_window_params.h](imgui_window_params.h)_. +* `imGuiWindowParams`: _see imgui_window_params.h_ imgui window params (use docking, showMenuBar, ProvideFullScreenWindow, etc) -* `dockingParams`: _see [docking_params.h](docking_params.h)_. +* `dockingParams`: _see docking_params.h_ dockable windows content and layout * `alternativeDockingLayouts`: _vector, default=empty_ List of possible additional layout for the applications. Only used in advanced cases when several layouts are available. * `rememberSelectedAlternativeLayout`: _bool, default=true_ Shall the application remember the last selected layout. Only used in advanced cases when several layouts are available. -* `backendPointers`: _see [backend_pointers.h](backend_pointers.h)_. +* `backendPointers`: _see backend_pointers.h_ A struct that contains optional pointers to the backend implementations. These pointers will be filled when the application starts * `backendType`: _enum BackendType, default=BackendType::FirstAvailable_ @@ -2647,18 +2625,6 @@ Three signatures are provided: Runs an application, using simpler params. * `HelloImGui::Run(guiFunction, windowTitle, windowSize, windowSizeAuto=false, restoreLastWindowGeometry=false, fpsIdle=10)` - - -__Other utilities:__ - -* `HelloImGui::GetRunnerParams()`: - a convenience function that will return the runnerParams of the current application - -* `FrameRate(durationForMean = 0.5)`: Returns the current FrameRate. - May differ from ImGui::GetIO().FrameRate, since one can choose the duration for the calculation of the mean value of the fps - -* `ImGuiTestEngine* GetImGuiTestEngine()`: returns a pointer to the global instance of ImGuiTestEngine that was - initialized by HelloImGui (iif ImGui Test Engine is active). @@md */ void Run(RunnerParams &runnerParams); @@ -2674,6 +2640,20 @@ __Other utilities:__ float fpsIdle = 10.f ); + +/** +@@md#GetRunnerParams + +* `HelloImGui::GetRunnerParams()`: + a convenience function that will return the runnerParams of the current application + +* `FrameRate(durationForMean = 0.5)`: Returns the current FrameRate. + May differ from ImGui::GetIO().FrameRate, since one can choose the duration for the calculation of the mean value of the fps + +* `ImGuiTestEngine* GetImGuiTestEngine()`: returns a pointer to the global instance of ImGuiTestEngine that was + initialized by HelloImGui (iif ImGui Test Engine is active). +@@md +**/ RunnerParams *GetRunnerParams(); // Returns the current FrameRate. May differ from ImGui::GetIO().FrameRate, @@ -2687,7 +2667,7 @@ __Other utilities:__ @@md#HelloImGui::Layouts In advanced cases when several layouts are available, you can switch between layouts. -(see demo inside [hello_imgui_demodocking.main.cpp](../hello_imgui_demos/hello_imgui_demodocking/hello_imgui_demodocking.main.cpp)) +(see demo inside [hello_imgui_demodocking.main.cpp](https://github.com/pthom/hello_imgui/tree/master/src/hello_imgui_demos/hello_imgui_demodocking/hello_imgui_demodocking.main.cpp)) * `SwitchLayout(layoutName)` Changes the application current layout. Only used in advanced cases when several layouts are available, diff --git a/external/hello_imgui/bindings/pybind_hello_imgui.cpp b/external/hello_imgui/bindings/pybind_hello_imgui.cpp index bce8d065..397c001c 100644 --- a/external/hello_imgui/bindings/pybind_hello_imgui.cpp +++ b/external/hello_imgui/bindings/pybind_hello_imgui.cpp @@ -64,19 +64,20 @@ void py_init_module_hello_imgui(py::module& m) // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! AUTOGENERATED CODE !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! // // Autogenerated code below! Do not edit! //////////////////// //////////////////// + m.def("em_to_vec2", + py::overload_cast(HelloImGui::EmToVec2), py::arg("x"), py::arg("y")); + + m.def("em_to_vec2", + py::overload_cast(HelloImGui::EmToVec2), py::arg("v")); + m.def("em_size", - py::overload_cast<>(HelloImGui::EmSize), " __HelloImGui::EmSize()__ returns the visible font size on the screen. For good results on HighDPI screens, always scale your\n widgets and windows relatively to this size.\n It is somewhat comparable to the [em CSS Unit](https://lyty.dev/css/css-unit.html).\n EmSize() = ImGui::GetFontSize()"); + py::overload_cast<>(HelloImGui::EmSize), "__HelloImGui::EmSize()__ returns the visible font size on the screen."); m.def("em_size", py::overload_cast(HelloImGui::EmSize), py::arg("nb_lines"), "__HelloImGui::EmSize(nbLines)__ returns a size corresponding to nbLines text lines"); - m.def("em_to_vec2", - py::overload_cast(HelloImGui::EmToVec2), py::arg("x"), py::arg("y")); - - m.def("em_to_vec2", - py::overload_cast(HelloImGui::EmToVec2), py::arg("v")); m.def("dpi_font_loading_factor", HelloImGui::DpiFontLoadingFactor, " Multiply font sizes by this factor when loading fonts manually with ImGui::GetIO().Fonts->AddFont...\n (HelloImGui::LoadFontTTF does this by default)"); @@ -270,7 +271,7 @@ void py_init_module_hello_imgui(py::module& m) auto pyClassFontLoadingParams = py::class_ - (m, "FontLoadingParams", "Font loading parameters: several options are available (color, merging, range, ...)") + (m, "FontLoadingParams", " @@md#Fonts\n\n When loading fonts, use HelloImGui::LoadFont(fontFilename, fontSize, fontLoadingParams)\n\n Font loading parameters: several options are available (color, merging, range, ...)") .def(py::init<>([]( bool adjustSizeToDpi = true, bool useFullGlyphRange = false, bool reduceMemoryUsageIfFullGlyphRange = true, bool mergeToLastFont = false, bool loadColor = false, bool insideAssets = true, std::vector glyphRanges = {}, ImFontConfig fontConfig = ImFontConfig(), bool mergeFontAwesome = false, ImFontConfig fontConfigFontAwesome = ImFontConfig()) { @@ -291,11 +292,11 @@ void py_init_module_hello_imgui(py::module& m) ) .def_readwrite("adjust_size_to_dpi", &FontLoadingParams::adjustSizeToDpi, "if True, the font size will be adjusted automatically to account for HighDPI") .def_readwrite("use_full_glyph_range", &FontLoadingParams::useFullGlyphRange, "if True, the font will be loaded with the full glyph range") - .def_readwrite("reduce_memory_usage_if_full_glyph_range", &FontLoadingParams::reduceMemoryUsageIfFullGlyphRange, " if set, fontConfig.GlyphRanges, and fontConfig.OversampleH / fontConfig.OversampleV will be set to 1\n when useFullGlyphRange is True (this is useful to save memory)") + .def_readwrite("reduce_memory_usage_if_full_glyph_range", &FontLoadingParams::reduceMemoryUsageIfFullGlyphRange, " if set, fontConfig.GlyphRanges, and\n fontConfig.OversampleH / fontConfig.OversampleV will be set to 1\n when useFullGlyphRange is True (this is useful to save memory)") .def_readwrite("merge_to_last_font", &FontLoadingParams::mergeToLastFont, "if True, the font will be merged to the last font") - .def_readwrite("load_color", &FontLoadingParams::loadColor, "if True, the font will be loaded using colors (requires freetype, enabled by IMGUI_ENABLE_FREETYPE)") - .def_readwrite("inside_assets", &FontLoadingParams::insideAssets, "if True, the font will be loaded using HelloImGui asset system. Otherwise, it will be loaded from the filesystem") - .def_readwrite("glyph_ranges", &FontLoadingParams::glyphRanges, " the ranges of glyphs to load:\n - if empty, the default glyph range will be used\n - you can specify several ranges\n (will be translated and stored as a static ImWChar* inside fontConfig)") + .def_readwrite("load_color", &FontLoadingParams::loadColor, " if True, the font will be loaded using colors\n (requires freetype, enabled by IMGUI_ENABLE_FREETYPE)") + .def_readwrite("inside_assets", &FontLoadingParams::insideAssets, " if True, the font will be loaded using HelloImGui asset system.\n Otherwise, it will be loaded from the filesystem") + .def_readwrite("glyph_ranges", &FontLoadingParams::glyphRanges, " the ranges of glyphs to load:\n - if empty, the default glyph range will be used\n - you can specify several ranges\n - intervals bounds are inclusive\n (will be translated and stored as a static ImWChar* inside fontConfig)") .def_readwrite("font_config", &FontLoadingParams::fontConfig, "ImGui native font config to use") .def_readwrite("merge_font_awesome", &FontLoadingParams::mergeFontAwesome, "") .def_readwrite("font_config_font_awesome", &FontLoadingParams::fontConfigFontAwesome, "") @@ -386,7 +387,7 @@ void py_init_module_hello_imgui(py::module& m) auto pyClassWindowGeometry = py::class_ - (m, "WindowGeometry", "*\n@@md#WindowGeometry\n\n__WindowGeometry__ is a struct that defines the window geometry.\n\nMembers:\n* `size`: _int[2], default=\"{800, 600}\"_. Size of the application window\n used if fullScreenMode==NoFullScreen and sizeAuto==False\n* `sizeAuto`: _bool, default=false_\n If True, adapt the app window size to the presented widgets.\n After the first frame was displayed, HelloImGui will measure its size,\n and the backend application window will be resized. As a consequence, the application window size may\n vary between the first and the second frame.\n\n* `fullScreenMode`: _FullScreenMode, default=NoFullScreen_.\n You can choose between several full screen modes:\n ```cpp\n NoFullScreen,\n FullScreen, // Full screen with specified resolution\n FullScreenDesktopResolution, // Full screen with current desktop mode & resolution\n FullMonitorWorkArea // Fake full screen, maximized window on the selected monitor\n ```\n* `positionMode`: _WindowPositionMode, default = OsDefault_.\n You can choose between several window position modes:\n ```cpp\n OsDefault,\n MonitorCenter,\n FromCoords,\n ```\n* `monitorIdx`: _int, default = 0_.\n used if positionMode==MonitorCenter or if fullScreenMode!=NoFullScreen\n* `windowSizeState`: _WindowSizeState, default=Standard_\n You can choose between several window size states:\n ```cpp\n Standard,\n Minimized,\n Maximized\n ```\n* `windowSizeMeasureMode`: _WindowSizeMeasureMode_, default=RelativeTo96Ppi\n how the window size is specified:\n * RelativeTo96Ppi enables to give screen size that are independant from the screen density.\n For example, a window size expressed as 800x600 will correspond to a size\n - 800x600 (in screen coords) if the monitor dpi is 96\n - 1600x120 (in screen coords) if the monitor dpi is 192\n (this works with Glfw. With SDL, it only works under windows)\n * ScreenCoords: measure window size in screen coords\n (Note: screen coordinates might differ from real pixels on high dpi screen)\n\n* `resizeAppWindowAtNextFrame`: _bool_, default=False;\n If you set this to flag to True at any point during the execution, the application window\n will then try to resize based on its content on the next displayed frame,\n and this flag will subsequently be set to False.\n Example:\n ```cpp\n // Will resize the app window at next displayed frame\n HelloImGui::GetRunnerParams()->appWindowParams.windowGeometry.resizeAppWindowAtNextFrame = True;\n ```\n\n :::Note: this flag is intended to be used during execution, not at startup (use sizeAuto at startup):::\n@@md\n*") + (m, "WindowGeometry", "*\n@@md#WindowGeometry\n\n__WindowGeometry__ is a struct that defines the window geometry.\n\nMembers:\n* `size`: _int[2], default=\"{800, 600}\"_. Size of the application window\n used if fullScreenMode==NoFullScreen and sizeAuto==False\n* `sizeAuto`: _bool, default=false_\n If True, adapt the app window size to the presented widgets.\n After the first frame was displayed, HelloImGui will measure its size,\n and the backend application window will be resized. As a consequence, the application window size may\n vary between the first and the second frame.\n\n* `fullScreenMode`: _FullScreenMode, default=NoFullScreen_.\n You can choose between several full screen modes:\n ```cpp\n NoFullScreen,\n FullScreen, // Full screen with specified resolution\n FullScreenDesktopResolution, // Full screen with current desktop mode & resolution\n FullMonitorWorkArea // Fake full screen, maximized window on the selected monitor\n ```\n* `positionMode`: _WindowPositionMode, default = OsDefault_.\n You can choose between several window position modes:\n ```cpp\n OsDefault,\n MonitorCenter,\n FromCoords,\n ```\n* `monitorIdx`: _int, default = 0_.\n used if positionMode==MonitorCenter or if fullScreenMode!=NoFullScreen\n* `windowSizeState`: _WindowSizeState, default=Standard_\n You can choose between several window size states:\n ```cpp\n Standard,\n Minimized,\n Maximized\n ```\n* `windowSizeMeasureMode`: _WindowSizeMeasureMode_, default=RelativeTo96Ppi\n how the window size is specified:\n * RelativeTo96Ppi enables to give screen size that are independant from the screen density.\n For example, a window size expressed as 800x600 will correspond to a size\n - 800x600 (in screen coords) if the monitor dpi is 96\n - 1600x120 (in screen coords) if the monitor dpi is 192\n (this works with Glfw. With SDL, it only works under windows)\n * ScreenCoords: measure window size in screen coords\n (Note: screen coordinates might differ from real pixels on high dpi screen)\n\n* `resizeAppWindowAtNextFrame`: _bool_, default=False;\n If you set this to flag to True at any point during the execution, the application window\n will then try to resize based on its content on the next displayed frame,\n and this flag will subsequently be set to False.\n Example:\n ```cpp\n // Will resize the app window at next displayed frame\n HelloImGui::GetRunnerParams()->appWindowParams.windowGeometry.resizeAppWindowAtNextFrame = True;\n ```\n Note: this flag is intended to be used during execution, not at startup (use sizeAuto at startup).\n@@md\n*") .def(py::init<>([]( ScreenSize size = HelloImGui::DefaultWindowSize, bool sizeAuto = false, HelloImGui::FullScreenMode fullScreenMode = HelloImGui::FullScreenMode::NoFullScreen, HelloImGui::WindowPositionMode positionMode = HelloImGui::WindowPositionMode::OsDefault, ScreenPosition position = HelloImGui::DefaultScreenPosition, int monitorIdx = 0, HelloImGui::WindowSizeState windowSizeState = HelloImGui::WindowSizeState::Standard, HelloImGui::WindowSizeMeasureMode windowSizeMeasureMode = HelloImGui::WindowSizeMeasureMode::RelativeTo96Ppi, bool resizeAppWindowAtNextFrame = false) { @@ -734,7 +735,7 @@ void py_init_module_hello_imgui(py::module& m) auto pyClassRunnerParams = py::class_ - (m, "RunnerParams", "*\n @@md#RunnerParams\n\n**RunnerParams** is a struct that contains all the settings and callbacks needed to run an application.\n\n Members:\n* `callbacks`: _see [runner_callbacks.h](runner_callbacks.h)_.\n callbacks.ShowGui() will render the gui, ShowMenus() will show the menus, etc.\n* `appWindowParams`: _see [app_window_params.h](app_window_params.h)_.\n application Window Params (position, size, title)\n* `imGuiWindowParams`: _see [imgui_window_params.h](imgui_window_params.h)_.\n imgui window params (use docking, showMenuBar, ProvideFullScreenWindow, etc)\n* `dockingParams`: _see [docking_params.h](docking_params.h)_.\n dockable windows content and layout\n* `alternativeDockingLayouts`: _vector, default=empty_\n List of possible additional layout for the applications. Only used in advanced cases when several layouts are available.\n* `rememberSelectedAlternativeLayout`: _bool, default=true_\n Shall the application remember the last selected layout. Only used in advanced cases when several layouts are available.\n* `backendPointers`: _see [backend_pointers.h](backend_pointers.h)_.\n A struct that contains optional pointers to the backend implementations. These pointers will be filled\n when the application starts\n* `backendType`: _enum BackendType, default=BackendType::FirstAvailable_\n Select the wanted platform backend type between `Sdl`, `Glfw`. Only useful when multiple backend are compiled\n and available.\n* `fpsIdling`: _FpsIdling_. Idling parameters (set fpsIdling.enableIdling to False to disable Idling)\n* `useImGuiTestEngine`: _bool, default=false_.\n Set this to True if you intend to use imgui_test_engine (please read note below)\n\n* `iniFolderType`: _IniFolderType, default = IniFolderType::CurrentFolder_\n Sets the folder where imgui will save its params.\n (possible values are: CurrentFolder, AppUserConfigFolder, DocumentsFolder, HomeFolder, TempFolder, AppExecutableFolder)\n AppUserConfigFolder is [Home]/AppData/Roaming under Windows, ~/.config under Linux, ~/Library/Application Support\"\n under macOS)\n* `iniFilename`: _string, default = \"\"_\n Sets the ini filename under which imgui will save its params. Its path is relative to the path given by iniFolderType,\n and can include a subfolder (which will be created if needed).\n If iniFilename empty, then it will be derived from appWindowParams.windowTitle (if both are empty, the ini filename will be imgui.ini).\n* `iniFilename_useAppWindowTitle`: _bool, default = true_.\n Shall the iniFilename be derived from appWindowParams.windowTitle (if not empty)\n\n * `appShallExit`: _bool, default=false_.\n During execution, set this to True to exit the app.\n _Note: 'appShallExit' has no effect on Mobile Devices (iOS, Android) and under emscripten, since these apps\n shall not exit._\n* `emscripten_fps`: _int, default = 0_.\n Set the application refresh rate (only used on emscripten: 0 stands for \"let the app or the browser decide\")\n\nNotes about the use of [Dear ImGui Test & Automation Engine](https://github.com/ocornut/imgui_test_engine):\n* HelloImGui must be compiled with the option HELLOIMGUI_WITH_TEST_ENGINE (-DHELLOIMGUI_WITH_TEST_ENGINE=ON)\n* See demo in src/hello_imgui_demos/hello_imgui_demo_test_engine.\n* imgui_test_engine is subject to a [specific license](https://github.com/ocornut/imgui_test_engine/blob/main/imgui_test_engine/LICENSE.txt)\n (TL;DR: free for individuals, educational, open-source and small businesses uses. Paid for larger businesses.)\n\n@@md\n") + (m, "RunnerParams", "*\n @@md#RunnerParams\n\n**RunnerParams** is a struct that contains all the settings and callbacks needed to run an application.\n\n Members:\n* `callbacks`: _see runner_callbacks.h_\n callbacks.ShowGui() will render the gui, ShowMenus() will show the menus, etc.\n* `appWindowParams`: _see app_window_params.h_\n application Window Params (position, size, title)\n* `imGuiWindowParams`: _see imgui_window_params.h_\n imgui window params (use docking, showMenuBar, ProvideFullScreenWindow, etc)\n* `dockingParams`: _see docking_params.h_\n dockable windows content and layout\n* `alternativeDockingLayouts`: _vector, default=empty_\n List of possible additional layout for the applications. Only used in advanced cases when several layouts are available.\n* `rememberSelectedAlternativeLayout`: _bool, default=true_\n Shall the application remember the last selected layout. Only used in advanced cases when several layouts are available.\n* `backendPointers`: _see backend_pointers.h_\n A struct that contains optional pointers to the backend implementations. These pointers will be filled\n when the application starts\n* `backendType`: _enum BackendType, default=BackendType::FirstAvailable_\n Select the wanted platform backend type between `Sdl`, `Glfw`. Only useful when multiple backend are compiled\n and available.\n* `fpsIdling`: _FpsIdling_. Idling parameters (set fpsIdling.enableIdling to False to disable Idling)\n* `useImGuiTestEngine`: _bool, default=false_.\n Set this to True if you intend to use imgui_test_engine (please read note below)\n\n* `iniFolderType`: _IniFolderType, default = IniFolderType::CurrentFolder_\n Sets the folder where imgui will save its params.\n (possible values are: CurrentFolder, AppUserConfigFolder, DocumentsFolder, HomeFolder, TempFolder, AppExecutableFolder)\n AppUserConfigFolder is [Home]/AppData/Roaming under Windows, ~/.config under Linux, ~/Library/Application Support\"\n under macOS)\n* `iniFilename`: _string, default = \"\"_\n Sets the ini filename under which imgui will save its params. Its path is relative to the path given by iniFolderType,\n and can include a subfolder (which will be created if needed).\n If iniFilename empty, then it will be derived from appWindowParams.windowTitle (if both are empty, the ini filename will be imgui.ini).\n* `iniFilename_useAppWindowTitle`: _bool, default = true_.\n Shall the iniFilename be derived from appWindowParams.windowTitle (if not empty)\n\n * `appShallExit`: _bool, default=false_.\n During execution, set this to True to exit the app.\n _Note: 'appShallExit' has no effect on Mobile Devices (iOS, Android) and under emscripten, since these apps\n shall not exit._\n* `emscripten_fps`: _int, default = 0_.\n Set the application refresh rate (only used on emscripten: 0 stands for \"let the app or the browser decide\")\n\nNotes about the use of [Dear ImGui Test & Automation Engine](https://github.com/ocornut/imgui_test_engine):\n* HelloImGui must be compiled with the option HELLOIMGUI_WITH_TEST_ENGINE (-DHELLOIMGUI_WITH_TEST_ENGINE=ON)\n* See demo in src/hello_imgui_demos/hello_imgui_demo_test_engine.\n* imgui_test_engine is subject to a [specific license](https://github.com/ocornut/imgui_test_engine/blob/main/imgui_test_engine/LICENSE.txt)\n (TL;DR: free for individuals, educational, open-source and small businesses uses. Paid for larger businesses.)\n\n@@md\n") .def(py::init<>([]( RunnerCallbacks callbacks = RunnerCallbacks(), AppWindowParams appWindowParams = AppWindowParams(), ImGuiWindowParams imGuiWindowParams = ImGuiWindowParams(), DockingParams dockingParams = DockingParams(), std::vector alternativeDockingLayouts = std::vector(), bool rememberSelectedAlternativeLayout = true, BackendPointers backendPointers = BackendPointers(), HelloImGui::BackendType backendType = HelloImGui::BackendType::FirstAvailable, FpsIdling fpsIdling = FpsIdling(), bool useImGuiTestEngine = false, HelloImGui::IniFolderType iniFolderType = HelloImGui::IniFolderType::CurrentFolder, std::string iniFilename = "", bool iniFilename_useAppWindowTitle = true, bool appShallExit = false, int emscripten_fps = 0) { @@ -816,7 +817,7 @@ void py_init_module_hello_imgui(py::module& m) m.def("run", py::overload_cast(HelloImGui::Run), py::arg("runner_params"), - "*\n@@md#HelloImGui::Run\n\n__HelloImGui::Run()__ will run an application with a single call.\n\nThree signatures are provided:\n\n* `HelloImGui::Run(RunnerParams &)`: full signature, the most customizable version.\n Runs an application whose params and Gui are provided by runnerParams.\n\n* `HelloImGui::Run(const SimpleRunnerParams&)`:\n Runs an application, using simpler params.\n\n* `HelloImGui::Run(guiFunction, windowTitle, windowSize, windowSizeAuto=False, restoreLastWindowGeometry=False, fpsIdle=10)`\n\n\n__Other utilities:__\n\n* `HelloImGui::GetRunnerParams()`:\n a convenience function that will return the runnerParams of the current application\n\n* `FrameRate(durationForMean = 0.5)`: Returns the current FrameRate.\n May differ from ImGui::GetIO().FrameRate, since one can choose the duration for the calculation of the mean value of the fps\n\n* `ImGuiTestEngine* GetImGuiTestEngine()`: returns a pointer to the global instance of ImGuiTestEngine that was\n initialized by HelloImGui (iif ImGui Test Engine is active).\n@@md\n"); + "*\n@@md#HelloImGui::Run\n\n__HelloImGui::Run()__ will run an application with a single call.\n\nThree signatures are provided:\n\n* `HelloImGui::Run(RunnerParams &)`: full signature, the most customizable version.\n Runs an application whose params and Gui are provided by runnerParams.\n\n* `HelloImGui::Run(const SimpleRunnerParams&)`:\n Runs an application, using simpler params.\n\n* `HelloImGui::Run(guiFunction, windowTitle, windowSize, windowSizeAuto=False, restoreLastWindowGeometry=False, fpsIdle=10)`\n@@md\n"); m.def("run", py::overload_cast(HelloImGui::Run), py::arg("simple_params")); @@ -825,7 +826,9 @@ void py_init_module_hello_imgui(py::module& m) py::overload_cast(HelloImGui::Run), py::arg("gui_function"), py::arg("window_title") = "", py::arg("window_size_auto") = false, py::arg("window_restore_previous_geometry") = false, py::arg("window_size") = HelloImGui::DefaultWindowSize, py::arg("fps_idle") = 10.f); m.def("get_runner_params", - HelloImGui::GetRunnerParams, pybind11::return_value_policy::reference); + HelloImGui::GetRunnerParams, + "*\n@@md#GetRunnerParams\n\n* `HelloImGui::GetRunnerParams()`:\n a convenience function that will return the runnerParams of the current application\n\n* `FrameRate(durationForMean = 0.5)`: Returns the current FrameRate.\n May differ from ImGui::GetIO().FrameRate, since one can choose the duration for the calculation of the mean value of the fps\n\n* `ImGuiTestEngine* GetImGuiTestEngine()`: returns a pointer to the global instance of ImGuiTestEngine that was\n initialized by HelloImGui (iif ImGui Test Engine is active).\n@@md\n*", + pybind11::return_value_policy::reference); m.def("frame_rate", HelloImGui::FrameRate, diff --git a/external/hello_imgui/hello_imgui b/external/hello_imgui/hello_imgui index 38537307..6194f424 160000 --- a/external/hello_imgui/hello_imgui +++ b/external/hello_imgui/hello_imgui @@ -1 +1 @@ -Subproject commit 38537307b25fbea6b030a4e89c22b50562c213b5 +Subproject commit 6194f424306995db7fb5f48594a2d42d7c538b01