mirror of
https://github.com/wpilibsuite/allwpilib
synced 2026-07-03 03:01:44 +00:00
[wpigui] Reload fonts to scale rather than preloading (#4712)
This commit is contained in:
@@ -115,6 +115,47 @@ void gui::DestroyContext() {
|
||||
gContext = nullptr;
|
||||
}
|
||||
|
||||
static void UpdateFontScale() {
|
||||
// Scale based on OS window content scaling
|
||||
float windowScale = 1.0;
|
||||
#ifndef __APPLE__
|
||||
glfwGetWindowContentScale(gContext->window, &windowScale, nullptr);
|
||||
#endif
|
||||
// map to closest font size: 0 = 0.5x, 1 = 0.75x, 2 = 1.0x, 3 = 1.25x,
|
||||
// 4 = 1.5x, 5 = 1.75x, 6 = 2x
|
||||
int fontScale =
|
||||
gContext->userScale + static_cast<int>((windowScale - 1.0) * 4);
|
||||
if (fontScale < 0) {
|
||||
fontScale = 0;
|
||||
}
|
||||
if (gContext->fontScale != fontScale) {
|
||||
gContext->reloadFonts = true;
|
||||
gContext->fontScale = fontScale;
|
||||
}
|
||||
}
|
||||
|
||||
// the range is based on 13px being the "nominal" 100% size and going from
|
||||
// ~0.5x (7px) to ~2.0x (25px)
|
||||
static void ReloadFonts() {
|
||||
auto& io = ImGui::GetIO();
|
||||
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) {
|
||||
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;
|
||||
}
|
||||
gContext->fonts.emplace_back(font);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool gui::Initialize(const char* title, int width, int height,
|
||||
ImGuiConfigFlags configFlags) {
|
||||
gContext->title = title;
|
||||
@@ -268,20 +309,9 @@ bool gui::Initialize(const char* title, int width, int height,
|
||||
SetStyle(static_cast<Style>(gContext->style));
|
||||
|
||||
// Load Fonts
|
||||
// this range is based on 13px being the "nominal" 100% size and going from
|
||||
// ~0.5x (7px) to ~2.0x (25px)
|
||||
for (auto&& makeFont : gContext->makeFonts) {
|
||||
if (makeFont.second) {
|
||||
auto& font = gContext->fonts.emplace_back();
|
||||
for (int i = 0; i < Font::kScaledLevels; ++i) {
|
||||
float size = 7.0f + i * 3.0f;
|
||||
ImFontConfig cfg;
|
||||
std::snprintf(cfg.Name, sizeof(cfg.Name), "%s-%d", makeFont.first,
|
||||
static_cast<int>(size));
|
||||
font.scaled[i] = makeFont.second(io, size, &cfg);
|
||||
}
|
||||
}
|
||||
}
|
||||
UpdateFontScale();
|
||||
ReloadFonts();
|
||||
gContext->reloadFonts = false; // init renderer will do this
|
||||
|
||||
if (!PlatformInitRenderer()) {
|
||||
return false;
|
||||
@@ -296,6 +326,11 @@ void gui::Main() {
|
||||
// Poll and handle events (inputs, window resize, etc.)
|
||||
glfwPollEvents();
|
||||
gContext->isPlatformRendering = true;
|
||||
UpdateFontScale();
|
||||
if (gContext->reloadFonts) {
|
||||
ReloadFonts();
|
||||
// PlatformRenderFrame() will clear reloadFonts flag
|
||||
}
|
||||
PlatformRenderFrame();
|
||||
gContext->isPlatformRendering = false;
|
||||
|
||||
@@ -336,18 +371,6 @@ void gui::CommonRenderFrame() {
|
||||
// Start the Dear ImGui frame
|
||||
ImGui::NewFrame();
|
||||
|
||||
// Scale based on OS window content scaling
|
||||
float windowScale = 1.0;
|
||||
#ifndef __APPLE__
|
||||
glfwGetWindowContentScale(gContext->window, &windowScale, nullptr);
|
||||
#endif
|
||||
// map to closest font size: 0 = 0.5x, 1 = 0.75x, 2 = 1.0x, 3 = 1.25x,
|
||||
// 4 = 1.5x, 5 = 1.75x, 6 = 2x
|
||||
gContext->fontScale = std::clamp(
|
||||
gContext->userScale + static_cast<int>((windowScale - 1.0) * 4), 0,
|
||||
Font::kScaledLevels - 1);
|
||||
ImGui::GetIO().FontDefault = gContext->fonts[0].scaled[gContext->fontScale];
|
||||
|
||||
for (size_t i = 0; i < gContext->earlyExecutors.size(); ++i) {
|
||||
auto& execute = gContext->earlyExecutors[i];
|
||||
if (execute) {
|
||||
@@ -431,10 +454,6 @@ int gui::AddFont(
|
||||
return gContext->makeFonts.size() - 1;
|
||||
}
|
||||
|
||||
ImFont* gui::GetFont(int font) {
|
||||
return gContext->fonts[font].scaled[gContext->fontScale];
|
||||
}
|
||||
|
||||
void gui::SetStyle(Style style) {
|
||||
gContext->style = static_cast<int>(style);
|
||||
switch (style) {
|
||||
@@ -501,14 +520,11 @@ void gui::EmitViewMenu() {
|
||||
}
|
||||
|
||||
if (ImGui::BeginMenu("Zoom")) {
|
||||
for (int i = 0; i < Font::kScaledLevels && (25 * (i + 2)) <= 200; ++i) {
|
||||
for (int i = 0; i < kFontScaledLevels && (25 * (i + 2)) <= 200; ++i) {
|
||||
char label[20];
|
||||
std::snprintf(label, sizeof(label), "%d%%", 25 * (i + 2));
|
||||
bool selected = gContext->userScale == i;
|
||||
bool enabled = (gContext->fontScale - gContext->userScale + i) >= 0 &&
|
||||
(gContext->fontScale - gContext->userScale + i) <
|
||||
Font::kScaledLevels;
|
||||
if (ImGui::MenuItem(label, nullptr, &selected, enabled)) {
|
||||
if (ImGui::MenuItem(label, nullptr, &selected)) {
|
||||
gContext->userScale = i;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -134,6 +134,11 @@ bool gui::PlatformInitRenderer() {
|
||||
}
|
||||
|
||||
void gui::PlatformRenderFrame() {
|
||||
if (gContext->reloadFonts) {
|
||||
ImGui_ImplDX11_InvalidateDeviceObjects();
|
||||
ImGui_ImplDX11_CreateDeviceObjects();
|
||||
gContext->reloadFonts = false;
|
||||
}
|
||||
ImGui_ImplDX11_NewFrame();
|
||||
|
||||
CommonRenderFrame();
|
||||
|
||||
@@ -26,10 +26,7 @@ struct SavedSettings {
|
||||
int style = 0;
|
||||
};
|
||||
|
||||
struct Font {
|
||||
static constexpr int kScaledLevels = 9;
|
||||
ImFont* scaled[kScaledLevels];
|
||||
};
|
||||
constexpr int kFontScaledLevels = 9;
|
||||
|
||||
struct Context : public SavedSettings {
|
||||
std::atomic_bool exit{false};
|
||||
@@ -56,12 +53,14 @@ struct Context : public SavedSettings {
|
||||
std::vector<std::function<void()>> lateExecutors;
|
||||
|
||||
int fontScale = 2; // updated by main loop
|
||||
std::vector<Font> fonts;
|
||||
std::vector<ImFont*> fonts;
|
||||
|
||||
std::vector<GLFWimage> icons;
|
||||
|
||||
std::string iniPath = "imgui.ini";
|
||||
bool resetOnExit = false;
|
||||
|
||||
bool reloadFonts = false; // reload fonts in next PlatformRenderFrame()
|
||||
};
|
||||
|
||||
extern Context* gContext;
|
||||
|
||||
@@ -84,6 +84,12 @@ void gui::PlatformRenderFrame() {
|
||||
id <MTLRenderCommandEncoder> renderEncoder = [commandBuffer renderCommandEncoderWithDescriptor:renderPassDescriptor];
|
||||
[renderEncoder pushDebugGroup:@"WPI GUI"];
|
||||
|
||||
if (gContext->reloadFonts) {
|
||||
ImGui_ImplMetal_DestroyFontsTexture();
|
||||
ImGui_ImplMetal_CreateFontsTexture(gPlatformContext->layer.device);
|
||||
gContext->reloadFonts = false;
|
||||
}
|
||||
|
||||
// Start the Dear ImGui frame
|
||||
ImGui_ImplMetal_NewFrame(renderPassDescriptor);
|
||||
|
||||
|
||||
@@ -51,6 +51,11 @@ bool gui::PlatformInitRenderer() {
|
||||
}
|
||||
|
||||
void gui::PlatformRenderFrame() {
|
||||
if (gContext->reloadFonts) {
|
||||
ImGui_ImplOpenGL2_DestroyFontsTexture();
|
||||
ImGui_ImplOpenGL2_CreateFontsTexture();
|
||||
gContext->reloadFonts = false;
|
||||
}
|
||||
ImGui_ImplOpenGL2_NewFrame();
|
||||
|
||||
CommonRenderFrame();
|
||||
|
||||
@@ -76,6 +76,11 @@ bool gui::PlatformInitRenderer() {
|
||||
}
|
||||
|
||||
void gui::PlatformRenderFrame() {
|
||||
if (gContext->reloadFonts) {
|
||||
ImGui_ImplOpenGL3_DestroyFontsTexture();
|
||||
ImGui_ImplOpenGL3_CreateFontsTexture();
|
||||
gContext->reloadFonts = false;
|
||||
}
|
||||
ImGui_ImplOpenGL3_NewFrame();
|
||||
|
||||
CommonRenderFrame();
|
||||
|
||||
Reference in New Issue
Block a user