设为首页 加入收藏

TOP

ImGui界面优化:使用图标字体、隐藏主窗口标题栏(一)
2023-08-26 21:10:31 】 浏览:128
Tags:ImGui


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

使用图标字体

下载IconFontCppHeaders里的IconsFontAwesome6.h文件引入到项目,然后下载fa-solid-900.ttf放到项目根目录,把系统字体目录下的msyh.ttc也移到根目录。项目文件如下:
image

参考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");

示例中所有图标都已经列出来了方便使用时查看(示例源码见文章末尾的项目链接),如下图所示:
image

扩展:内存加载字体

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

把需要加载的字体文件(如msyh.ttc)和上面的exe放到同一目录:
image

在命令行窗口通过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

image

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

把生成的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;
    //程序是
首页 上一页 1 2 下一页 尾页 1/2/2
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
上一篇5.10 汇编语言:汇编过程与结构 下一篇【Qt6】工具提示以及调色板设置

最新文章

热门文章

Hot 文章

Python

C 语言

C++基础

大数据基础

linux编程基础

C/C++面试题目