diff --git a/wpigui/src/main/native/cpp/wpigui.cpp b/wpigui/src/main/native/cpp/wpigui.cpp index b50540ff6b5..1a277e37df4 100644 --- a/wpigui/src/main/native/cpp/wpigui.cpp +++ b/wpigui/src/main/native/cpp/wpigui.cpp @@ -17,6 +17,8 @@ #include #include #include +#include +#include #include #include #include @@ -94,6 +96,8 @@ static void IniReadLine(ImGuiContext* ctx, ImGuiSettingsHandler* handler, impl->userScale = num; } else if (std::strncmp(lineStr, "style=", 6) == 0) { impl->style = num; + } else if (std::strncmp(lineStr, "font=", 5) == 0) { + impl->defaultFontName = &lineStr[5]; } else if (std::strncmp(lineStr, "fps=", 4) == 0) { impl->fps = num; } @@ -106,23 +110,26 @@ static void IniWriteAll(ImGuiContext* ctx, ImGuiSettingsHandler* handler, } out_buf->appendf( "[MainWindow][GLOBAL]\nwidth=%d\nheight=%d\nmaximized=%d\n" - "xpos=%d\nypos=%d\nuserScale=%d\nstyle=%d\nfps=%d\n\n", + "xpos=%d\nypos=%d\nuserScale=%d\nstyle=%d\nfont=%s\nfps=%d\n\n", gContext->width, gContext->height, gContext->maximized ? 1 : 0, gContext->xPos, gContext->yPos, gContext->userScale, gContext->style, - gContext->fps); + gContext->defaultFontName.c_str(), gContext->fps); } void gui::CreateContext() { gContext = new Context; - AddFont("ProggyDotted", [](ImGuiIO& io, float size, const ImFontConfig* cfg) { - auto font = ImGui::AddFontProggyDotted(io, size, cfg); - static const ImWchar icons_ranges[] = {ICON_MIN_FA, ICON_MAX_16_FA, 0}; - ImFontConfig icons_cfg; - icons_cfg.MergeMode = true; - icons_cfg.PixelSnapH = true; - ImGui::AddFontFontAwesomeSolid(io, size, &icons_cfg, icons_ranges); - return font; - }); + AddDefaultFont("Proggy Dotted", + [](ImGuiIO& io, float size, const ImFontConfig* cfg) { + return ImGui::AddFontProggyDotted(io, size, cfg); + }); + AddDefaultFont("Droid Sans", + [](ImGuiIO& io, float size, const ImFontConfig* cfg) { + return ImGui::AddFontDroidSans(io, size, cfg); + }); + AddDefaultFont("Fira Code Retina", + [](ImGuiIO& io, float size, const ImFontConfig* cfg) { + return ImGui::AddFontFiraCodeRetina(io, size, cfg); + }); PlatformCreateContext(); } @@ -158,17 +165,25 @@ static void ReloadFonts() { io.Fonts->Clear(); gContext->fonts.clear(); float size = 7.0f + gContext->fontScale * 3.0f; - bool first = true; for (auto&& makeFont : gContext->makeFonts) { - if (makeFont.second) { + if (makeFont.func) { ImFontConfig cfg; - std::snprintf(cfg.Name, sizeof(cfg.Name), "%s", makeFont.first); - ImFont* font = makeFont.second(io, size, &cfg); - if (first) { - ImGui::GetIO().FontDefault = font; - first = false; + std::snprintf(cfg.Name, sizeof(cfg.Name), "%s", makeFont.name.c_str()); + bool isDefault = makeFont.name == gContext->defaultFontName; + if (!makeFont.defaultOnly || isDefault) { + ImFont* font = makeFont.func(io, size, &cfg); + if (isDefault) { + // Merge font awesome solid into default font + static const ImWchar icons_ranges[] = {ICON_MIN_FA, ICON_MAX_16_FA, + 0}; + ImFontConfig icons_cfg; + icons_cfg.MergeMode = true; + icons_cfg.PixelSnapH = true; + ImGui::AddFontFontAwesomeSolid(io, size, &icons_cfg, icons_ranges); + ImGui::GetIO().FontDefault = font; + } + gContext->fonts.emplace_back(font); } - gContext->fonts.emplace_back(font); } } } @@ -479,11 +494,20 @@ int gui::AddFont( std::function makeFont) { if (makeFont) { - gContext->makeFonts.emplace_back(name, std::move(makeFont)); + gContext->makeFonts.emplace_back(name, false, std::move(makeFont)); } return gContext->makeFonts.size() - 1; } +void gui::AddDefaultFont( + const char* name, + std::function + makeFont) { + if (makeFont) { + gContext->makeFonts.emplace_back(name, true, std::move(makeFont)); + } +} + void gui::SetStyle(Style style) { gContext->style = static_cast(style); switch (style) { @@ -553,6 +577,17 @@ void gui::EmitViewMenu() { ImGui::EndMenu(); } + if (ImGui::BeginMenu("Font")) { + for (auto&& makeFont : gContext->makeFonts) { + bool selected = gContext->defaultFontName == makeFont.name; + if (ImGui::MenuItem(makeFont.name.c_str(), nullptr, &selected)) { + gContext->defaultFontName = makeFont.name; + gContext->reloadFonts = true; + } + } + ImGui::EndMenu(); + } + if (ImGui::BeginMenu("Zoom")) { for (int i = 0; i < kFontScaledLevels && (25 * (i + 2)) <= 200; ++i) { char label[20]; diff --git a/wpigui/src/main/native/include/wpigui.h b/wpigui/src/main/native/include/wpigui.h index a745431825a..8bfa6a6b6cb 100644 --- a/wpigui/src/main/native/include/wpigui.h +++ b/wpigui/src/main/native/include/wpigui.h @@ -144,6 +144,21 @@ int AddFont( std::function makeFont); +/** + * Adds a default font option. This is the font used for menus, etc. If the + * font is selected by the user as the default font, the passed function is + * called during initialization as many times as necessary to create a range of + * sizes. If not selected, the font is not loaded (to always load a font, + * use AddFont() instead). + * + * @param name font name + * @param makeFont font creation / loader function + */ +void AddDefaultFont( + const char* name, + std::function + makeFont); + /** * Gets a font added with AddFont() with the appropriate font size for * the current scaling of the GUI. diff --git a/wpigui/src/main/native/include/wpigui_internal.h b/wpigui/src/main/native/include/wpigui_internal.h index e9735f6f897..747d82c25d5 100644 --- a/wpigui/src/main/native/include/wpigui_internal.h +++ b/wpigui/src/main/native/include/wpigui_internal.h @@ -25,6 +25,7 @@ struct SavedSettings { int userScale = 2; int style = 0; int fps = 120; + std::string defaultFontName = "Proggy Dotted"; }; constexpr int kFontScaledLevels = 9; @@ -44,10 +45,21 @@ struct Context : public SavedSettings { std::function saveSettings; std::vector> initializers; std::vector> windowScalers; - std::vector>> - makeFonts; + struct FontMaker { + FontMaker( + std::string name, bool defaultOnly, + std::function + func) + : name{std::move(name)}, + defaultOnly{defaultOnly}, + func{std::move(func)} {} + + std::string name; + bool defaultOnly; + std::function + func; + }; + std::vector makeFonts; ImVec4 clearColor = ImVec4(0.45f, 0.55f, 0.60f, 1.00f); std::vector> earlyExecutors;