DuiMini: DirectUI for Humans™

badge1 badge2 badge3 badge4 badge5 badge6

DuiMini是一个快速、小巧的跨平台DirectUI库。

你还在忍受反人类的平台GUI差异?还在纠结于传统GUI的丑陋?试试DuiMini吧,仅需几分钟,你就会爱上它!

特点

  • 跨平台,一次编码,Windows/Linux/OSX 全平台支持。
  • 轻量级,即使全静态连接,不经过压缩也能保持10M内的大小。
  • 高效率,基于OpenGL,通过游戏级引擎(SFML)调用。

CMake选项

主要选项

主要选项和默认值如下:

选项名 默认值 备注
BUILD_SHARED_LIBS OFF TRUE为动态链接
CMAKE_BUILD_TYPE Release 默认生成类型
DUI_BUILD_TOOLS ON 生成DUI工具
DUI_BUILD_TESTS OFF 生成测试

警告

添加或修改高级选项可能导致生成文件体积变大等情况出现。

高级-SFML选项

SFML选项相比原版将 SFML_BUILD_NETWORKSFML_BUILD_AUDIO 默认值调整为 FALSE ,如有需要可以自行添加。

关于SFML选项具体细节参见:https://www.sfml-dev.org/tutorials/2.5/compile-with-cmake.php

高级-googletest选项

INSTALL_GTEST 默认值调整为 FALSEgtest_force_shared_crt 在VS中默认值调为 TRUE

编译环境

DuiMini支持跨平台,Windows/Linux/MacOS均可运行,cmake请使用3.8以上的版本。

由于时间原因,本地测试环境为:

  • Windows 10 with Visual Studio 2017, cmake 3.13.2
  • Ubuntu 18.04 with GCC 7.3.0, cmake 3.10.2
  • OSX 10.14 with Apple LLVM 10.0.0, cmake 3.13.4

CI环境:

  • Windows 10 with MSBuild 15.9.20, cmake 3.12.3
  • Ubuntu 16.04 with GCC 5.4.0, cmake 3.12.4
  • OSX 10.13 with Apple LLVM 9.1.0, cmake 3.11.4

警告

OSX系统动态链接需要 特殊设置

如果有兼容性问题请提交issue。

请使用现代编译器编译,编译器需支持C++11标准。相关版本支持情况请参阅 cppreference

config主配置文件

初始化

加载配置文件:

UIConfig::LoadConfig(path);

默认为 config.xml 文件。

重要

请保证 root 为唯一根节点。

DLG设置

每个dlg配置文件均需在这里注册。

<res type="dlg" name="main" file="xml/main.xml" />
  • name:唯一,dlg注册名
  • file:xml文件名

皮肤设置

每套皮肤均需在这里注册,分为系统皮肤和一般皮肤,系统皮肤在更换皮肤后依然保持原样,一般皮肤之间可以任意更换。

<style type="skin" name="default" value="skin/default" default="1" />
<style type="skin" name="testskin" value="skin/testskin" />
<style type="skin" name="system" value="skin/system" system="1" />
  • name:唯一,皮肤注册名
  • value:皮肤目录路径
  • system:默认为0,为1则为系统皮肤(更换皮肤后依然生效,可不唯一)
  • default:默认为0,为1则是默认皮肤(请保留唯一一条作为默认配置

注解

system 属性为 1default 属性将被强制设为 0

语言设置

危险

请保证语言设置在字体设置之前!否则字体设置时找不到语言将会报错!

DuiMini支持多语言,每种语言均需在这里注册语言文件。

<res type="lang" lang="zh-cn" file="string/zh-CN.xml" default="1" />
<res type="lang" lang="en-us" file="string/en-US.xml" />
  • name:唯一,语言注册名(建议使用语言代码)
  • file:xml文件名
  • default:默认为0,为1则是默认语言(请保留唯一一条作为默认配置

字体设置

可为每种语言设置不同的字体。

<style type="font" lang="zh-cn" name="default" file="font/yahei.ttc" size="12" default="1" />
<style type="font" lang="en-us" name="default" file="font/segoe.ttc" size="12" default="1" />
  • lang:对应语言注册名
  • name:同一语言内唯一,字体注册名
  • file:字体文件路径
  • size:像素值
  • default:默认为0,为1则是 当前语言 下的默认字体(请为 每个语言 保留唯一一条作为默认配置)
字号参考
中文字号 磅数 像素值
八号 5 6
七号 5.5 7
小六 6.5 8
六号 7.5 10
小五 9 12
五号 10.5 14
小四 12 16
四号 14 18
小三 15 20
三号 16 21
小二 18 24
二号 22 29
小一 24 32
一号 26 34
小初 36 48
初号 42 56

异常处理

DuiMini提供了一个异常处理类 UIException ,处理和UI库有关的错误。

重要

UI库不处理STL异常,如有需要可以自行捕获。

危险

UI库函数均保证基本异常安全,但在 kEL_Error 级别错误发生后将不再保证安全。

错误级别

名称 说明
kEL_Normal 无错误
kEL_Warning 警告
kEL_Error 错误(结束进程)

注解

kEL_Error 级别错误因为无法保证程序安全性或无法继续执行,将会自动以1的返回码退出。

如何使用

小技巧

错误信息列表每次调用都会清空之前的错误信息。

  • 设置异常: UISetError

  • 获取错误信息列表: UIGetErrorMsgList

  • 设置自定义处理函数: UIException::SetExtraFunc

    函数原型(返回true代表已经处理完异常,无需进行其他处理):

    typedef std::function<bool(int level, const char* msg)> ExtraFunc;
    

资源加载

警告

目前32位平台编译的程序可能不支持2G以上文件加载。

设定资源文件

DuiMini目前支持3种资源加载方式,默认不加载资源:

普通文件

加载普通文件,参数为资源文件根目录。

UIResource::SetResMode(kRT_File, "uires");
  • 设定当前目录下的 uires 目录为资源文件根目录。
  • 文件解析时路径为相对根目录路径,如 uires/1.txt 只需传入 1.txt 即可。
打包文件

可以将所有资源文件打包为zip格式的压缩包加载。

UIResource::SetResMode(kRT_Package, "res.zip");
  • 加载当前目录下的 res.zip 文件。
  • 文件解析时路径为压缩包内的路径,如 res.zipuires/1.txt 只需传入 uires/1.txt 即可。
内存加载

可以将资源文件打包进可执行文件形成单文件,请使用 ResPacker 打包文件。

UIResource::SetResMode(kRT_Raw, "Demo.exe");
  • 加载 Demo.exe (自身)中打包的资源文件。
  • 文件解析时路径和 打包文件 相同

解析文件

解析文件需要通过资源解析器获取,您可自定义资源解析器,只需继承自 IUILoadFile 类即可。

危险

资源加载返回智能指针,系统释放时会调用特定函数,请不要手动释放!

普通文件解析
auto res = UIResource::LoadRes<UIRawLoader>("1.txt");
res->GetFile();         // 文件数据指针
test->GetFileSize();    // 文件大小
自定义解析器
class CustomLoader : public IUILoadFile {
public:
    bool LoadFile(const void* buffer, long size) override {
        // do something, DO NOT free buffer!
        return true;    // true for success
    }
};

使用:

auto res = UIResource::LoadRes<CustomLoader>("1.txt");

消息事件

所有控件、窗口行为均通过消息事件触发响应。

消息事件通过 UIEvent 类传递,其中 Event 枚举定义了支持的消息类型,部分附带了一些参数:

类型名 备注
kEVT_MouseEnter 鼠标进入
kEVT_MouseLeave 鼠标离开
kEVT_MouseMove 鼠标移动
kEVT_LButtonDown 左键按下
kEVT_LButtonUp 左键抬起
kEVT_LButtonClick 左键点击
kEVT_LButtonDBClick 左键双击
kEVT_RButtonDown 右键按下
kEVT_RButtonUp 右键抬起
kEVT_RButtonClick 右键点击
kEVT_RButtonDBClick 右键双击
kEVT_Disable 控件被禁用
kEVT_Active 控件被激活
kEVT_Invisible 控件不可见
kEVT_Visible 控件可见
kEVT_SkinChange 皮肤被改变
kEVT_LangChange 语言被改变

注解

kEVT_ActivekEVT_Visible 在窗口初始化时依然会被传递(除非设置相应初值为0)。

注意

当控件被禁用或不可见时类似 kEVT_MouseEnter 的部分事件会被发送给控件,但是响应函数不会被执行,如有特殊需求请自行截获。

kEVT_MouseMove

  • 参数:鼠标位置

  • API:

    void SetPos(Point v_pt)
    Point GetPos() const
    

kEVT_LButtonDown

kEVT_LButtonUp

kEVT_LButtonClick

kEVT_LButtonDBClick

kEVT_RButtonDown

kEVT_RButtonUp

kEVT_RButtonClick

kEVT_RButtonDBClick

kEVT_SkinChange

  • 参数:新旧资源ID

  • API:

    void SetRes(ResChangeEvent res)
    ResChangeEvent GetRes() const
    

kEVT_LangChange

ResPacker

文件打包工具,用于整合资源文件和可执行文件,生成单文件程序。

CLI参数:

ResPacker [OPTION...] [exefile] [zipfile]
-h, --help 打印帮助
--nobackup 不生成备份文件
-u, --unpack 解压模式

警告

由于数据长度在不同平台中定义可能有所差别,因此请务必保证打包平台和发行平台一致,否则可能出现读取错误。

文件整合

  1. 打包需要整合的资源文件为一个zip压缩包。
  2. 主程序中使用 内存加载 的方法加载资源。
  3. 使用命令 ResPacker exefile_path zipfile_path 打包文件(因为不同平台需要重新编译,因此也需要重新打包),会自动生成源程序备份文件。

文件拆分

  1. 使用命令 ResPacker -u exefile_path 即可拆分打包好的文件(需保证打包平台和拆分平台一致)
  2. 拆分后的可执行文件为 源文件.src ,zip压缩包为 源文件.zip

实现原理

通过在可执行文件末端附加内容的方式,将zip文件附加在可执行文件末尾(不会对可执行文件造成影响),读取时加载到内存即可。

文件格式:

[可执行文件段]
[固定识别编码"UI"] 0x55, 0x49
[zip文件段大小] 4/8字节
[zip文件段]
[可执行文件段大小] 4/8字节

读取时先读取最后的可执行文件段大小,然后跳到可执行文件段尾,验证识别编码,获得zip文件大小并读取。

开发环境需求

DuiMini

  • git
  • cmake
  • Visual Studio/Visual Studio Code/Other editors

DuiMini-doc

  • git
  • sphinx-doc
  • sphinx_rtd_theme
  • Visual Studio Code/Other editors

相关规范

文件规范

  • 文件编码统一使用UTF-8并请确保不出现非ASCII字符。
  • 文件换行使用LF格式,git可以配置 autocrlf = true 自动实现。

代码风格

  • 主要风格参见 Google 开源项目风格指南
  • 代码格式化使用clang format,VS较高版本可以开启 Enable ClangFormat support 选项,VSC可以使用插件设置。
  • 代码注释使用 Doxygen风格,便于后期文档生成。

异常处理

  • 除第三方库以外,禁用C++异常处理。
  • 请采用 UIException 类处理异常,具体请参考头文件实现。

跨平台相关

  • 请尽量减少平台相关代码或做分别处理。
  • 时刻注意数据类型长度(包括但不限于long等)

注释规范

  • 代码注释统一使用英文,防止乱码等其他问题。
  • 文件开头需添加版权信息和作者等(参考已有文件)。

文档更新

  • 功能修改后需更新本文档,但代码注释优先级更高。

第三方库

  • 使用第三方库需注意尽量挑选轻量级、单一功能的库以免造成体积膨胀(如禁用boost库)。
  • 第三方库不能采用GPL等不允许商业/闭源的许可证。
  • 由于DuiMini是跨平台的,所以请确保第三方库也是跨平台的。
  • 请采用cmake管理第三方库以做到自动化编译。

第三方库

cxxopts

Copyright (c) 2014 Jarryd Beck

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

googletest

Copyright 2008, Google Inc.

All rights reserved.

Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:

  • Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
  • Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
  • Neither the name of Google Inc. nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

miniz

Copyright 2013-2014 RAD Game Tools and Valve Software

Copyright 2010-2014 Rich Geldreich and Tenacious Software LLC

All Rights Reserved.

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

pugixml

pugixml 1.9 - an XML processing library

Copyright (C) 2006-2018, by Arseny Kapoulkine (arseny.kapoulkine@gmail.com) Report bugs and download new versions at http://pugixml.org/

This is the distribution of pugixml, which is a C++ XML processing library, which consists of a DOM-like interface with rich traversal/modification capabilities, an extremely fast XML parser which constructs the DOM tree from an XML file/buffer, and an XPath 1.0 implementation for complex data-driven tree queries. Full Unicode support is also available, with Unicode interface variants and conversions between different Unicode encodings (which happen automatically during parsing/saving).

The distribution contains the following folders:

contrib/ - various contributions to pugixml
docs/ - documentation
    docs/samples - pugixml usage examples
    docs/quickstart.html - quick start guide
    docs/manual.html - complete manual
scripts/ - project files for IDE/build systems
src/ - header and source files
readme.txt - this file.

This library is distributed under the MIT License:

Copyright (c) 2006-2018 Arseny Kapoulkine

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

SFML

SFML - Copyright (C) 2007-2018 Laurent Gomila - laurent@sfml-dev.org

This software is provided ‘as-is’, without any express or implied warranty. In no event will the authors be held liable for any damages arising from the use of this software.

Permission is granted to anyone to use this software for any purpose, including commercial applications, and to alter it and redistribute it freely, subject to the following restrictions:

  1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
  2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
  3. This notice may not be removed or altered from any source distribution.
External libraries used by SFML
  • OpenAL-Soft is under the LGPL license
  • stb_image and stb_image_write are public domain
  • freetype is under the FreeType license or the GPL license
  • libogg is under the BSD license
  • libvorbis is under the BSD license
  • libflac is under the BSD license

DuiMini在开发的过程中,参考了许多优秀开源项目,在此表示感谢。目前我们使用的第三方库及版本有:

第三方库 版本 协议
cxxopts 2.1.2 MIT
googletest 1.8.1 BSD-3-Clause
miniz 2.0.8 MIT
pugixml 1.9 MIT
SFML 2.5.1 zlib