mirror of
https://github.com/wpilibsuite/allwpilib
synced 2026-06-19 00:41:43 +00:00
[upstream_utils] Update imgui and implot (#8762)
Not updating GLFW yet due to a likely future move to SDL.
This commit is contained in:
@@ -177,53 +177,35 @@ void gui::SetCurrentContext(Context* context) {
|
||||
gContext = context;
|
||||
}
|
||||
|
||||
ImFont* Context::FontMaker::GetFont() const {
|
||||
if (!font) {
|
||||
auto& io = ImGui::GetIO();
|
||||
|
||||
ImFontConfig cfg;
|
||||
std::snprintf(cfg.Name, sizeof(cfg.Name), "%s", name.c_str());
|
||||
font = func(io, 0, &cfg);
|
||||
|
||||
// Merge font awesome solid
|
||||
ImFontConfig icons_cfg;
|
||||
icons_cfg.MergeMode = true;
|
||||
icons_cfg.PixelSnapH = true;
|
||||
ImGui::AddFontFontAwesomeSolid(io, 0, &icons_cfg);
|
||||
}
|
||||
return font;
|
||||
}
|
||||
|
||||
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;
|
||||
for (auto&& makeFont : gContext->makeFonts) {
|
||||
if (makeFont.func) {
|
||||
ImFontConfig cfg;
|
||||
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);
|
||||
}
|
||||
}
|
||||
float fontScale = gContext->userScale / 100.0 * windowScale;
|
||||
if (fontScale < 0.5) {
|
||||
fontScale = 0.5;
|
||||
}
|
||||
ImGui::GetStyle().FontSizeBase = 13;
|
||||
ImGui::GetStyle().FontScaleDpi = fontScale;
|
||||
}
|
||||
|
||||
bool gui::Initialize(const char* title, int width, int height,
|
||||
@@ -382,8 +364,6 @@ bool gui::Initialize(const char* title, int width, int height,
|
||||
|
||||
// Load Fonts
|
||||
UpdateFontScale();
|
||||
ReloadFonts();
|
||||
gContext->reloadFonts = false; // init renderer will do this
|
||||
|
||||
if (!PlatformInitRenderer()) {
|
||||
return false;
|
||||
@@ -401,10 +381,6 @@ void gui::Main() {
|
||||
glfwPollEvents();
|
||||
gContext->isPlatformRendering = true;
|
||||
UpdateFontScale();
|
||||
if (gContext->reloadFonts) {
|
||||
ReloadFonts();
|
||||
// PlatformRenderFrame() will clear reloadFonts flag
|
||||
}
|
||||
PlatformRenderFrame();
|
||||
gContext->isPlatformRendering = false;
|
||||
|
||||
@@ -527,22 +503,12 @@ bool gui::AddIcon(const unsigned char* data, int len) {
|
||||
return true;
|
||||
}
|
||||
|
||||
int gui::AddFont(
|
||||
const char* name,
|
||||
std::function<ImFont*(ImGuiIO& io, float size, const ImFontConfig* cfg)>
|
||||
makeFont) {
|
||||
if (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));
|
||||
gContext->makeFonts.emplace_back(name, std::move(makeFont));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -708,19 +674,20 @@ void gui::EmitViewMenu() {
|
||||
|
||||
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;
|
||||
auto& name = makeFont.GetName();
|
||||
bool selected = gContext->defaultFontName == name;
|
||||
if (ImGui::MenuItem(name.c_str(), nullptr, &selected)) {
|
||||
ImGui::GetIO().FontDefault = makeFont.GetFont();
|
||||
gContext->defaultFontName = name;
|
||||
}
|
||||
}
|
||||
ImGui::EndMenu();
|
||||
}
|
||||
|
||||
if (ImGui::BeginMenu("Zoom")) {
|
||||
for (int i = 0; i < kFontScaledLevels && (25 * (i + 2)) <= 200; ++i) {
|
||||
for (int i = 50; i <= 200; i += 25) {
|
||||
char label[20];
|
||||
std::snprintf(label, sizeof(label), "%d%%", 25 * (i + 2));
|
||||
std::snprintf(label, sizeof(label), "%d%%", i);
|
||||
bool selected = gContext->userScale == i;
|
||||
if (ImGui::MenuItem(label, nullptr, &selected)) {
|
||||
gContext->userScale = i;
|
||||
@@ -764,12 +731,12 @@ bool gui::UpdateTextureFromImage(ImTextureID* texture, int width, int height,
|
||||
int height2 = 0;
|
||||
unsigned char* imgData =
|
||||
stbi_load_from_memory(data, len, &width2, &height2, nullptr, 4);
|
||||
if (!data) {
|
||||
if (!imgData) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (width2 == width && height2 == height) {
|
||||
UpdateTexture(texture, kPixelRGBA, width2, height2, imgData);
|
||||
UpdateTexture(*texture, kPixelRGBA, width2, height2, imgData);
|
||||
} else {
|
||||
*texture = CreateTexture(kPixelRGBA, width2, height2, imgData);
|
||||
}
|
||||
|
||||
@@ -133,11 +133,6 @@ bool gui::PlatformInitRenderer() {
|
||||
}
|
||||
|
||||
void gui::PlatformRenderFrame() {
|
||||
if (gContext->reloadFonts) {
|
||||
ImGui_ImplDX11_InvalidateDeviceObjects();
|
||||
ImGui_ImplDX11_CreateDeviceObjects();
|
||||
gContext->reloadFonts = false;
|
||||
}
|
||||
ImGui_ImplDX11_NewFrame();
|
||||
|
||||
CommonRenderFrame();
|
||||
@@ -181,7 +176,7 @@ static inline DXGI_FORMAT DXPixelFormat(PixelFormat format) {
|
||||
ImTextureID gui::CreateTexture(PixelFormat format, int width, int height,
|
||||
const unsigned char* data) {
|
||||
if (!gPlatformValid) {
|
||||
return nullptr;
|
||||
return ImTextureID_Invalid;
|
||||
}
|
||||
|
||||
// Create texture
|
||||
@@ -216,7 +211,7 @@ ImTextureID gui::CreateTexture(PixelFormat format, int width, int height,
|
||||
&srv);
|
||||
pTexture->Release();
|
||||
|
||||
return srv;
|
||||
return reinterpret_cast<uintptr_t>(srv);
|
||||
}
|
||||
|
||||
void gui::UpdateTexture(ImTextureID texture, PixelFormat, int width, int height,
|
||||
@@ -234,7 +229,7 @@ void gui::UpdateTexture(ImTextureID texture, PixelFormat, int width, int height,
|
||||
box.bottom = height;
|
||||
|
||||
ID3D11Resource* resource = nullptr;
|
||||
static_cast<ID3D11ShaderResourceView*>(texture)->GetResource(&resource);
|
||||
reinterpret_cast<ID3D11ShaderResourceView*>(texture)->GetResource(&resource);
|
||||
|
||||
if (resource) {
|
||||
gPlatformContext->pd3dDeviceContext->UpdateSubresource(
|
||||
@@ -249,7 +244,7 @@ void gui::DeleteTexture(ImTextureID texture) {
|
||||
return;
|
||||
}
|
||||
if (texture) {
|
||||
static_cast<ID3D11ShaderResourceView*>(texture)->Release();
|
||||
reinterpret_cast<ID3D11ShaderResourceView*>(texture)->Release();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -148,24 +148,8 @@ inline bool AddIcon(std::string_view data) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a font to the GUI. The passed function is called during
|
||||
* initialization as many times as necessary to create a range of sizes.
|
||||
*
|
||||
* @param name font name
|
||||
* @param makeFont font creation / loader function
|
||||
* @return Font index for later use with GetFont()
|
||||
*/
|
||||
int AddFont(
|
||||
const char* name,
|
||||
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).
|
||||
* Adds a default font option. This is the font used for menus, etc. If not
|
||||
* selected, the font is not loaded.
|
||||
*
|
||||
* @param name font name
|
||||
* @param makeFont font creation / loader function
|
||||
@@ -175,15 +159,6 @@ void AddDefaultFont(
|
||||
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.
|
||||
*
|
||||
* @param font font index returned by AddFont()
|
||||
* @return Font pointer
|
||||
*/
|
||||
ImFont* GetFont(int font);
|
||||
|
||||
enum Style { kStyleClassic = 0, kStyleDark, kStyleLight, kStyleDeepDark };
|
||||
|
||||
/**
|
||||
@@ -339,7 +314,7 @@ class Texture {
|
||||
m_format{oth.m_format},
|
||||
m_width{oth.m_width},
|
||||
m_height{oth.m_height} {
|
||||
oth.m_texture = 0; // NOLINT
|
||||
oth.m_texture = ImTextureID_Invalid;
|
||||
}
|
||||
|
||||
Texture& operator=(const Texture&) = delete;
|
||||
@@ -348,7 +323,7 @@ class Texture {
|
||||
DeleteTexture(m_texture);
|
||||
}
|
||||
m_texture = oth.m_texture;
|
||||
oth.m_texture = 0; // NOLINT
|
||||
oth.m_texture = ImTextureID_Invalid;
|
||||
m_format = oth.m_format;
|
||||
m_width = oth.m_width;
|
||||
m_height = oth.m_height;
|
||||
@@ -364,13 +339,18 @@ class Texture {
|
||||
/**
|
||||
* Evaluates to true if the texture is valid.
|
||||
*/
|
||||
explicit operator bool() const { return m_texture; }
|
||||
explicit operator bool() const { return m_texture != ImTextureID_Invalid; }
|
||||
|
||||
/**
|
||||
* Implicit conversion to ImTextureID.
|
||||
*/
|
||||
operator ImTextureID() const { return m_texture; } // NOLINT
|
||||
|
||||
/**
|
||||
* Implicit conversion to ImTextureRef.
|
||||
*/
|
||||
operator ImTextureRef() const { return ImTextureRef{m_texture}; } // NOLINT
|
||||
|
||||
/**
|
||||
* Gets the texture pixel format.
|
||||
*
|
||||
@@ -452,7 +432,7 @@ class Texture {
|
||||
}
|
||||
|
||||
private:
|
||||
ImTextureID m_texture = nullptr;
|
||||
ImTextureID m_texture = ImTextureID_Invalid;
|
||||
PixelFormat m_format = kPixelRGBA;
|
||||
int m_width = 0;
|
||||
int m_height = 0;
|
||||
|
||||
@@ -22,14 +22,12 @@ struct SavedSettings {
|
||||
bool maximized = false;
|
||||
int xPos = -1;
|
||||
int yPos = -1;
|
||||
int userScale = 2;
|
||||
int userScale = 100;
|
||||
int style = 0;
|
||||
int fps = 120;
|
||||
std::string defaultFontName = "Proggy Dotted";
|
||||
};
|
||||
|
||||
constexpr int kFontScaledLevels = 9;
|
||||
|
||||
struct Context : public SavedSettings {
|
||||
std::atomic_bool exit{false};
|
||||
|
||||
@@ -45,17 +43,20 @@ struct Context : public SavedSettings {
|
||||
std::function<void(bool exiting)> saveSettings;
|
||||
std::vector<std::function<void()>> initializers;
|
||||
std::vector<std::function<void(float scale)>> windowScalers;
|
||||
struct FontMaker {
|
||||
class FontMaker {
|
||||
public:
|
||||
FontMaker(
|
||||
std::string name, bool defaultOnly,
|
||||
std::string name,
|
||||
std::function<ImFont*(ImGuiIO& io, float size, const ImFontConfig* cfg)>
|
||||
func)
|
||||
: name{std::move(name)},
|
||||
defaultOnly{defaultOnly},
|
||||
func{std::move(func)} {}
|
||||
: name{std::move(name)}, func{std::move(func)} {}
|
||||
|
||||
const std::string& GetName() const { return name; }
|
||||
ImFont* GetFont() const;
|
||||
|
||||
private:
|
||||
std::string name;
|
||||
bool defaultOnly;
|
||||
mutable ImFont* font = nullptr;
|
||||
std::function<ImFont*(ImGuiIO& io, float size, const ImFontConfig* cfg)>
|
||||
func;
|
||||
};
|
||||
@@ -65,15 +66,10 @@ struct Context : public SavedSettings {
|
||||
std::vector<std::function<void()>> earlyExecutors;
|
||||
std::vector<std::function<void()>> lateExecutors;
|
||||
|
||||
int fontScale = 2; // updated by main loop
|
||||
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,12 +84,6 @@ 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);
|
||||
|
||||
@@ -125,7 +119,7 @@ static inline MTLPixelFormat MetalPixelFormat(PixelFormat format) {
|
||||
|
||||
ImTextureID gui::CreateTexture(PixelFormat format, int width, int height,
|
||||
const unsigned char* data) {
|
||||
if (!gPlatformValid) return nullptr;
|
||||
if (!gPlatformValid) return ImTextureID_Invalid;
|
||||
|
||||
MTLPixelFormat fmt = MetalPixelFormat(format);
|
||||
MTLTextureDescriptor *textureDescriptor = [MTLTextureDescriptor texture2DDescriptorWithPixelFormat:fmt width:width height:height mipmapped:NO];
|
||||
@@ -138,19 +132,19 @@ ImTextureID gui::CreateTexture(PixelFormat format, int width, int height,
|
||||
id <MTLTexture> texture = [gPlatformContext->layer.device newTextureWithDescriptor:textureDescriptor];
|
||||
[texture replaceRegion:MTLRegionMake2D(0, 0, width, height) mipmapLevel:0 withBytes:data bytesPerRow:width * 4];
|
||||
|
||||
return (__bridge_retained void *)texture;
|
||||
return (ImTextureID)(intptr_t)(__bridge_retained void *)texture;
|
||||
}
|
||||
|
||||
void gui::UpdateTexture(ImTextureID texture, PixelFormat, int width,
|
||||
int height, const unsigned char* data) {
|
||||
if (!texture) return;
|
||||
id <MTLTexture> mtlTexture = (__bridge id <MTLTexture>)texture;
|
||||
id <MTLTexture> mtlTexture = (__bridge id <MTLTexture>)(void*)(intptr_t)texture;
|
||||
[mtlTexture replaceRegion:MTLRegionMake2D(0, 0, width, height) mipmapLevel:0 withBytes:data bytesPerRow:width * 4];
|
||||
}
|
||||
|
||||
void gui::DeleteTexture(ImTextureID texture) {
|
||||
if (!gPlatformValid || !texture) return;
|
||||
id <MTLTexture> mtlTexture = (__bridge_transfer id <MTLTexture>)texture;
|
||||
id <MTLTexture> mtlTexture = (__bridge_transfer id <MTLTexture>)(void*)(intptr_t)texture;
|
||||
(void)mtlTexture;
|
||||
}
|
||||
|
||||
|
||||
@@ -51,11 +51,6 @@ bool gui::PlatformInitRenderer() {
|
||||
}
|
||||
|
||||
void gui::PlatformRenderFrame() {
|
||||
if (gContext->reloadFonts) {
|
||||
ImGui_ImplOpenGL2_DestroyFontsTexture();
|
||||
ImGui_ImplOpenGL2_CreateFontsTexture();
|
||||
gContext->reloadFonts = false;
|
||||
}
|
||||
ImGui_ImplOpenGL2_NewFrame();
|
||||
|
||||
CommonRenderFrame();
|
||||
@@ -92,7 +87,7 @@ static inline GLenum GLPixelFormat(PixelFormat format) {
|
||||
ImTextureID gui::CreateTexture(PixelFormat format, int width, int height,
|
||||
const unsigned char* data) {
|
||||
if (!gPlatformValid) {
|
||||
return nullptr;
|
||||
return ImTextureID_Invalid;
|
||||
}
|
||||
|
||||
// Create a OpenGL texture identifier
|
||||
@@ -109,12 +104,12 @@ ImTextureID gui::CreateTexture(PixelFormat format, int width, int height,
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0,
|
||||
GLPixelFormat(format), GL_UNSIGNED_BYTE, data);
|
||||
|
||||
return reinterpret_cast<ImTextureID>(static_cast<uintptr_t>(texture));
|
||||
return texture;
|
||||
}
|
||||
|
||||
void gui::UpdateTexture(ImTextureID texture, PixelFormat format, int width,
|
||||
int height, const unsigned char* data) {
|
||||
GLuint glTexture = static_cast<GLuint>(reinterpret_cast<uintptr_t>(texture));
|
||||
GLuint glTexture = texture;
|
||||
if (glTexture == 0) {
|
||||
return;
|
||||
}
|
||||
@@ -127,7 +122,7 @@ void gui::DeleteTexture(ImTextureID texture) {
|
||||
if (!gPlatformValid) {
|
||||
return;
|
||||
}
|
||||
GLuint glTexture = static_cast<GLuint>(reinterpret_cast<uintptr_t>(texture));
|
||||
GLuint glTexture = texture;
|
||||
if (glTexture != 0) {
|
||||
glDeleteTextures(1, &glTexture);
|
||||
}
|
||||
|
||||
@@ -76,11 +76,6 @@ bool gui::PlatformInitRenderer() {
|
||||
}
|
||||
|
||||
void gui::PlatformRenderFrame() {
|
||||
if (gContext->reloadFonts) {
|
||||
ImGui_ImplOpenGL3_DestroyFontsTexture();
|
||||
ImGui_ImplOpenGL3_CreateFontsTexture();
|
||||
gContext->reloadFonts = false;
|
||||
}
|
||||
ImGui_ImplOpenGL3_NewFrame();
|
||||
|
||||
CommonRenderFrame();
|
||||
@@ -117,7 +112,7 @@ static inline GLenum GLPixelFormat(PixelFormat format) {
|
||||
ImTextureID gui::CreateTexture(PixelFormat format, int width, int height,
|
||||
const unsigned char* data) {
|
||||
if (!gPlatformValid) {
|
||||
return nullptr;
|
||||
return ImTextureID_Invalid;
|
||||
}
|
||||
|
||||
// Create a OpenGL texture identifier
|
||||
@@ -134,12 +129,12 @@ ImTextureID gui::CreateTexture(PixelFormat format, int width, int height,
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0,
|
||||
GLPixelFormat(format), GL_UNSIGNED_BYTE, data);
|
||||
|
||||
return reinterpret_cast<ImTextureID>(static_cast<uintptr_t>(texture));
|
||||
return texture;
|
||||
}
|
||||
|
||||
void gui::UpdateTexture(ImTextureID texture, PixelFormat format, int width,
|
||||
int height, const unsigned char* data) {
|
||||
GLuint glTexture = static_cast<GLuint>(reinterpret_cast<uintptr_t>(texture));
|
||||
GLuint glTexture = static_cast<GLuint>(texture);
|
||||
if (glTexture == 0) {
|
||||
return;
|
||||
}
|
||||
@@ -152,7 +147,7 @@ void gui::DeleteTexture(ImTextureID texture) {
|
||||
if (!gPlatformValid) {
|
||||
return;
|
||||
}
|
||||
GLuint glTexture = static_cast<GLuint>(reinterpret_cast<uintptr_t>(texture));
|
||||
GLuint glTexture = static_cast<GLuint>(texture);
|
||||
if (glTexture != 0) {
|
||||
glDeleteTextures(1, &glTexture);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user