ImGui界面优化:使用图标字体、隐藏主窗口标题栏

这篇具有很好参考价值的文章主要介绍了ImGui界面优化:使用图标字体、隐藏主窗口标题栏。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

目录
  • 使用图标字体
    • 扩展:内存加载字体
  • 隐藏主窗口标题栏
    • 增加程序退出
    • 改进HideTabBar
    • 窗口最大化
  • 总结

本文主要介绍ImGui应用中的一些界面优化方法,如果是第一次使用ImGui推荐从上一篇文章开始:使用C++界面框架ImGUI开发一个简单程序,最终的界面效果如下:
ImGui界面优化:使用图标字体、隐藏主窗口标题栏

使用图标字体

下载IconFontCppHeaders里的IconsFontAwesome6.h文件引入到项目,然后下载fa-solid-900.ttf放到项目根目录,把系统字体目录下的msyh.ttc也移到根目录。项目文件如下:
ImGui界面优化:使用图标字体、隐藏主窗口标题栏

参考IconFontCppHeaders的示例,字体加载的代码如下:

float baseFontSize = 30.0f;
ImFont* font = io.Fonts->AddFontFromFileTTF
(
    "msyh.ttc",
    baseFontSize,
    nullptr,
    io.Fonts->GetGlyphRangesChineseFull()
);
IM_ASSERT(font != nullptr);

// FontAwesome字体需要缩小2.0f/3.0f才能正确对齐
float iconFontSize = baseFontSize * 2.0f / 3.0f;
static const ImWchar icons_ranges[] = { ICON_MIN_FA, ICON_MAX_16_FA,0 };
ImFontConfig icons_config;
icons_config.MergeMode = true;
icons_config.PixelSnapH = true;
icons_config.GlyphMinAdvanceX = iconFontSize;
io.Fonts->AddFontFromFileTTF(FONT_ICON_FILE_NAME_FAS, iconFontSize, icons_config, icons_ranges);

使用方法:

ImGui::Text("%s ", ICON_FA_ALIGN_CENTER);
ImGui::Button(ICON_FA_ALIGN_CENTER " Search");

示例中所有图标都已经列出来了方便使用时查看(示例源码见文章末尾的项目链接),如下图所示:
ImGui界面优化:使用图标字体、隐藏主窗口标题栏

扩展:内存加载字体

先新建一个控制台项目,把ImGui项目misc\fonts路径下的binary_to_compressed_c.cpp文件添加到控制台项目,编译得到binary_to_compressed_c.exe

把需要加载的字体文件(如msyh.ttc)和上面的exe放到同一目录:
ImGui界面优化:使用图标字体、隐藏主窗口标题栏

在命令行窗口通过cd 命令导航到上面exe的目录,然后输入以下命令(任选一个):

//不压缩,使用C组,源代码大概50M
binary_to_compressed_c.exe -nocompress msyh.ttc msyh >font_msyh.c
//压缩,使用base85,源代码大概25M
binary_to_compressed_c.exe -base85 msyh.ttc msyh >font_msyh.c

ImGui界面优化:使用图标字体、隐藏主窗口标题栏

因为压缩的源代码编译时报堆栈空间不足,并且实际的数组会大一些,我选择的是不压缩的源代码。

把生成的font_msyh.c添加到自己的项目,在main文件引入字体的命名空间,然后加载字体:

#include "font_msyh.c"

ImFont* font = io.Fonts->AddFontFromMemoryTTF
(
    (void*)msyh_data,
    msyh_size,
    30,
    nullptr,
    io.Fonts->GetGlyphRangesChineseFull()
);
IM_ASSERT(font != nullptr);

注意msyh_data里面的msyh来自命令行的窗口,注意根据字体自己取一个名字。

结论:使用内存加载字体软件退出时会报错,暂时还解决不了,继续使用本地加载字体的方式 。

隐藏主窗口标题栏

主窗口的标题栏是后端自带的样式且不支持修改,不能自定义样式那就只能隐藏掉,眼不见为净。
本文使用的后端是 glfw+opengl3,ImGui 是 docking 分支,其它项目的实现方法可能会有所不同。

使用 glfw 创建一个 offscreen context ,在创建窗口前加入以下代码即可:

// 设置 offscreen context 的标志位
glfwWindowHint(GLFW_VISIBLE, GLFW_FALSE);

// Create window with graphics context
GLFWwindow* window = glfwCreateWindow(1280, 720, "演示程序", nullptr, nullptr);

还需要 io.ConfigViewportsNoAutoMerge = true; 开启,同时关闭ConfigViewportsNoTaskBarIcon(默认关闭)。代码如下:

ImGuiIO& io = ImGui::GetIO(); (void)io;
io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard;     // Enable Keyboard Controls
io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad;      // Enable Gamepad Controls
io.ConfigFlags |= ImGuiConfigFlags_DockingEnable;         // Enable Docking
io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable;       // Enable Multi-Viewport / Platform Windows
io.ConfigViewportsNoAutoMerge = true;
//io.ConfigViewportsNoTaskBarIcon = true;

注:如果不开启io.ConfigViewportsNoAutoMerge可能引起拖动窗口不小心拖动到隐藏的主窗口, 导致子窗口也隐藏的情况。

做完上面的步骤界面还是隐藏的,那是因为我们的停靠空间开启了填充标志,需要关闭:

void RenderUI()
{
   //...
   static bool opt_fullscreen = false;
   //...
}

参考链接:IMGUI如何去掉外面窗口?

隐藏窗口后会导致一系列问题,比如关闭窗口、最大化等,下面会逐一说明。

增加程序退出

主窗口隐藏后会遇到一个问题,程序该怎么退出?解决思路是显示停靠空间的关闭按钮,检测到关闭按钮点击后关闭主窗口。
Application.h增加GetMainShouldClose函数:

#pragma once
#include "imgui.h"
namespace App
{
    static bool MainOpen = true;
    //程序是否退出
    bool GetMainShouldClose();
    //主UI函数,放停靠空间的代码
    void RenderUI();

    //...其它代码
}

Application.cpp还需要改动RenderUI函数:

bool GetMainShouldClose()
{
    return !MainOpen;
}
void RenderUI()
{
    bool* p_open = &MainOpen;
    static bool opt_fullscreen = false;
    //...其它代码
    ImGui::Begin("演示程序", p_open, window_flags);
    //...其它代码
}

然后再main函数的 App::RenderUI() 后面判断是否退出程序:

//...
App::RenderUI();
if (App::GetMainShouldClose())
{
    //关闭窗口,也可以做一些退出确认操作
    glfwSetWindowShouldClose(window, GLFW_TRUE);
}
//...

改进HideTabBar

原本的HideTabBar有问题,如果有新窗口停靠到中心位置会导致新窗口被覆盖隐藏,只能通过重置布局恢复。所以标题栏最好不隐藏,只隐藏前面的三角符号,这样也能允许用户自己拖动窗口。
优化代码如下:

void HideTabBar()
{
    ImGuiWindowClass window_class;
    window_class.DockNodeFlagsOverrideSet = ImGuiDockNodeFlags_NoWindowMenuButton;
    //window_class.DockNodeFlagsOverrideSet = ImGuiDockNodeFlags_NoTabBar;
    ImGui::SetNextWindowClass(&window_class);
}

窗口最大化

窗口最大化需要知道屏幕的尺寸,这一步涉及到具体的后端代码,需要先在main文件中获取屏幕尺寸。

在main函数前实现GetScreenSize函数,代码如下:

static void GetScreenSize(int &width, int &height)
{
    //屏幕数量
    int monitorCount;
    GLFWmonitor** pMonitor = glfwGetMonitors(&monitorCount);
    int screen_x, screen_y;
    for (int i = 0; i < monitorCount; i++)
    {
        const GLFWvidmode* mode = glfwGetVideoMode(pMonitor[i]);
        //屏幕大小
        screen_x = mode->width;
        screen_y = mode->height;
    }
    width = screen_x;
    height = screen_y;
}

然后在main函数中将主窗口的大小设置为屏幕大小一致,代码如下:

 //获取屏幕尺寸
 int width, height;
 GetScreenSize(width, height);
 glfwWindowHint(GLFW_VISIBLE, GLFW_FALSE);
 // Create window with graphics context
 GLFWwindow* window = glfwCreateWindow(width, height, "演示程序", nullptr, nullptr);

在App::RenderUI函数中的停靠空间渲染前设置空间大小,并在主题切换代码后加上大小切换的代码,代码如下:

//...其它代码

//设置最大化、最小化
static bool IsMaximized = true;
static bool LastMaximized = true;
ImVec2 screenSize = ImGui::GetIO().DisplaySize;
if (IsMaximized)
{
    if (LastMaximized != IsMaximized)
    {
        LastMaximized = IsMaximized;
    }
    ImGui::SetNextWindowPos(ImVec2(0, 0));
    ImGui::SetNextWindowSize(screenSize);
    //隐藏标题栏
    //window_flags |= ImGuiWindowFlags_NoDecoration | ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoResize;
}
else
{
    if (LastMaximized != IsMaximized)
    {
        LastMaximized = IsMaximized;
        ImGui::SetNextWindowPos(ImVec2(screenSize[0]*0.1, screenSize[1] * 0.1));
        ImGui::SetNextWindowSize(ImVec2(screenSize[0] * 0.8, screenSize[1] * 0.8));
    }
}

ImGui::Begin(ICON_FA_ANCHOR "演示程序", p_open, window_flags);

//...其它代码

//增加主题切换
if (ImGui::BeginMenu(ICON_FA_THERMOMETER "主题(Other)"))
{
    if (ImGui::MenuItem("暗黑(Dark)")) { ImGui::StyleColorsDark(); }
    if (ImGui::MenuItem("明亮(Light)")) { ImGui::StyleColorsLight(); }
    if (ImGui::MenuItem("经典(Classic)")) { ImGui::StyleColorsClassic(); }

    ImGui::EndMenu();
}
//增加窗口切换
if (ImGui::BeginMenu(ICON_FA_TV "窗口(Windows)"))
{
    if (ImGui::MenuItem(ICON_FA_WINDOW_MAXIMIZE "最大(Max)")) { IsMaximized = true; }
    if (ImGui::MenuItem(ICON_FA_WINDOW_RESTORE "默认(Default)")) { IsMaximized = false; }

    ImGui::EndMenu();
}

总结

文中的主要的优化措施就是引入字体图标隐藏主窗口,结合前一篇的文章,ImGui基本的功能都已经涉及到了。

文中还有一些遗留问题,比如:

  • 全屏无法覆盖系统的任务栏
  • 标题栏没有自定义
  • 内存加载字体报错
  • 任务栏窗口图标自定义

目前的内容对于简单的项目来说基本够用,后面应该不会再继续更新ImGui相关的内容了,等项目中遇到问题再说。

项目源码链接:提取码: tv7n文章来源地址https://www.toymoban.com/news/detail-671379.html

到了这里,关于ImGui界面优化:使用图标字体、隐藏主窗口标题栏的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • [Qt学习笔记]Halcon窗口界面上显示文字的字体尺寸、样式修改

    养成良好的查资料习惯,可以实现事半功倍。 在Halcon12中,有set_font和set_display_font两个算子,其中set_display_font是本地函数形式,所以最终的实现算子为set_font. 按照不同的系统环境下,使用方法略有不同: 不同的系统下使用的方法不同,原本以为比较简单,直接按照文档的

    2024年03月20日
    浏览(42)
  • 使用C++界面框架ImGUI开发一个简单程序

    目录 简介 使用示例 下载示例 main文件 设置ImGui风格 设置字体 主循环 添加Application类 中文编码问题 界面设计 关于imgui_demo.cpp 创建停靠空间 创建页面 隐藏窗口标签栏 创建导航页面 创建内容页面 隐藏控制台窗口 打包程序 总结 待解决问题 开发优势 附件 ImGui 是一个用于C++的

    2024年02月13日
    浏览(30)
  • 什么是字体图标(Icon Font)?如何在网页中使用字体图标?

    前端入门之旅:探索Web开发的奇妙世界 记得点击上方或者右侧链接订阅本专栏哦 几何带你启航前端之旅 欢迎来到前端入门之旅!这个专栏是为那些对Web开发感兴趣、刚刚踏入前端领域的朋友们量身打造的。无论你是完全的新手还是有一些基础的开发者,这里都将为你提供一

    2024年02月11日
    浏览(34)
  • 微信小程序中使用字体图标,解决字体图标包过大的问题

    在微信小程序开发中,我们经常使用字体图标来美化界面和展示各种功能。然而,当我们的小程序主包大小超过2M时,可能会遇到一个问题:字体图标的文件很大,导致整个包的大小超出了限制。为了解决这个问题,我们可以使用wx.loadFontFace方法来远程加载字体图标。 步骤一

    2024年02月12日
    浏览(59)
  • 微信小程序使用字体图标——链接引入

    目录 1.下载字体图标  1.选择需要的图标加入购物车添加到项目 2.查看项目  3.生成在线链接   4.复制生成的链接 等下放到iconfont.json中​编辑 2.引入链接 1.下载  2.生成iconfont.json文件 3. 在iconfont.json中 放入生成的链接 4.需要重新编译小程序之后在终端执行 5.在app.json中引入字

    2024年02月16日
    浏览(71)
  • uni-app使用iconfont字体图标

    2024年02月07日
    浏览(41)
  • 三种方式在HTML使用阿里字体图标--iconfont阿里巴巴矢量图标库

    好久没用到阿里巴巴的图标,突然要用到就发现不会用了,只会导出png格式的图标png了= = 目录 1、字体图标 方法一、本地使用通过类名使用阿里矢量图标 1、把图标添加入库 2、把图标添加到项目  3、下载字体图标 4、使用文件 5、在对应的HTML页面上引入css 6、使用字体图标

    2024年02月16日
    浏览(65)
  • 原生微信小程序中使用-阿里字体图标-详解

    1、打开阿里巴巴矢量图标库 网址:iconfont-阿里巴巴矢量图标库 2、搜索字体图标,鼠标悬浮点击添加入库  3、按如下步骤添加到自己的项目   进入微信开发者工具 1、创建 fonts文件夹 iconfont.wxss 文件,将刚才的代码复制进去 2、在 app.wxss文件 中引入路径 3、在页面中使用  

    2024年02月04日
    浏览(45)
  • 在uni-app项目中简单使用iconfont字体图标

    1.1 减小打包体积,一些平台如微信小程序等在发布时有体积限制,大量使用静态资源会使得打包体积容易超出限制 1.2 字体图标是矢量的,缩放不失真、模糊 1.3 对比引用多个网络图标,字体图标只需一个css文件即可,因此减少了网络请求次数,同时比下载图片节约流量 2.1

    2024年02月05日
    浏览(43)
  • 【小程序】使用font-awesome字体图标的解决方案(图文)

    (1)、在项目根目录下建立一个文件夹,命名随意,我的文件夹名称是js。 (2)、再新建一个文件font-awesome.wxss (3)、把下载解压后的font-awesome中的css文件中的font-awesome.css内容复制到font-awesome.wxss中 注意:从 红框往下(从.fa{) 的内容开始复制,红框内的内容不复制   

    2024年02月07日
    浏览(42)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包