Skip to content

Commit

Permalink
[wpigui] Add font selector
Browse files Browse the repository at this point in the history
  • Loading branch information
PeterJohnson committed Sep 28, 2024
1 parent eab93f4 commit d21f718
Show file tree
Hide file tree
Showing 3 changed files with 86 additions and 24 deletions.
75 changes: 55 additions & 20 deletions wpigui/src/main/native/cpp/wpigui.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@
#include <GLFW/glfw3.h>
#include <IconsFontAwesome6.h>
#include <imgui.h>
#include <imgui_DroidSans.h>
#include <imgui_FiraCodeRetina.h>
#include <imgui_FontAwesomeSolid.h>
#include <imgui_ProggyDotted.h>
#include <imgui_impl_glfw.h>
Expand Down Expand Up @@ -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;
}
Expand All @@ -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();
}

Expand Down Expand Up @@ -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);
}
}
}
Expand Down Expand Up @@ -479,11 +494,20 @@ int gui::AddFont(
std::function<ImFont*(ImGuiIO& io, float size, const ImFontConfig* cfg)>
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<ImFont*(ImGuiIO& io, float size, const ImFontConfig* cfg)>
makeFont) {
if (makeFont) {
gContext->makeFonts.emplace_back(name, true, std::move(makeFont));
}
}

void gui::SetStyle(Style style) {
gContext->style = static_cast<int>(style);
switch (style) {
Expand Down Expand Up @@ -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];
Expand Down
15 changes: 15 additions & 0 deletions wpigui/src/main/native/include/wpigui.h
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,21 @@ int AddFont(
std::function<ImFont*(ImGuiIO& io, float size, const ImFontConfig* cfg)>
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<ImFont*(ImGuiIO& io, float size, const ImFontConfig* cfg)>
makeFont);

/**
* Gets a font added with AddFont() with the appropriate font size for
* the current scaling of the GUI.
Expand Down
20 changes: 16 additions & 4 deletions wpigui/src/main/native/include/wpigui_internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ struct SavedSettings {
int userScale = 2;
int style = 0;
int fps = 120;
std::string defaultFontName = "Proggy Dotted";
};

constexpr int kFontScaledLevels = 9;
Expand All @@ -44,10 +45,21 @@ struct Context : public SavedSettings {
std::function<void(bool exiting)> saveSettings;
std::vector<std::function<void()>> initializers;
std::vector<std::function<void(float scale)>> windowScalers;
std::vector<std::pair<
const char*,
std::function<ImFont*(ImGuiIO& io, float size, const ImFontConfig* cfg)>>>
makeFonts;
struct FontMaker {
FontMaker(
std::string name, bool defaultOnly,
std::function<ImFont*(ImGuiIO& io, float size, const ImFontConfig* cfg)>
func)
: name{std::move(name)},
defaultOnly{defaultOnly},
func{std::move(func)} {}

std::string name;
bool defaultOnly;
std::function<ImFont*(ImGuiIO& io, float size, const ImFontConfig* cfg)>
func;
};
std::vector<FontMaker> makeFonts;

ImVec4 clearColor = ImVec4(0.45f, 0.55f, 0.60f, 1.00f);
std::vector<std::function<void()>> earlyExecutors;
Expand Down

0 comments on commit d21f718

Please sign in to comment.