美文网首页
IMGUI的设计

IMGUI的设计

作者: golden_age | 来源:发表于2020-02-27 23:24 被阅读0次

(按:
web领域,GUI编程有着学习曲线,
琐碎,平凡的GUI,为什么需要复杂的学习呢,
我希望可以设计实现一个简单,能立即上手的GUI框架)

我曾经在预研工作中实现过一版IMGUI,作为用户扩展的GUI,
模拟器 API文档

IMGUI明显的好处是,用户不需要熟悉GUI的概念,比如html / xml / css或其它的 GUI 领域特定语言(DSL),只需要有一般脚本编程技能就可以了,

const button = Button.create({text: 'click me'});
if (button.click) {
    console.log(’i am clicked, dont stop‘)
}

一目了然,是吧

IMGUI的问题

问题来了,那为什么大多数GUI框架,未选择IMGUI?

首先,这问题不成立,在早期C编程时代,大家写的GUI都是IMGUI,因为那时,大家写UI本来就是即时绘制

// 每祯循环,所以叫做“即时”模式
void onUpdate() {
  // 绘制 button
  drawButton("click me", "thisButtonID");
  Event clickEvent;
  // 过滤是否有点击消息
  filterEvent(&clickEvent);
  if(clickEvent.valid) {
    // 是否点击在button区域中 
    if( getRec("thisButtonID").include(clickEvent.point) ) {
        printf("i am clicked")
    }
  }
}

然后,这问题很有价值,

GUI思想一直在发展,从早期绘制,到GUI编程成为一个相对独立的编程,出现了面向对象编程,将
GUI关注于 对象事件,Button作为控件对象

const btClickMe = new Button(...)  
btClickMe.on('click', ()=>{
   console.log('i am clicked')
})

更近一步地,因为GUI相当关心排版问题,即需要组织一颗GUI树,出现了GUI排版描述语言, 即一般的XML/HTML/JSON表示

const GUIDesc = {
    type: "layout", // 是排版容器节点
    direction: "vertical", // 竖直排版
    align : {
        longtitude: "begin", // 径度对齐,begin即向上对齐
        latitude: "begin", // 纬度对齐,begin即向左对齐
    },
     
    children : [
        {
            type: 'button', // 一个button组件
            text: 'click me',
            onClick: ()=>{ // 点击回调
                console.log('i am clicked');
            },
            children: [...]
        }
    ]
}
 
const gui = createGUI(GUIDesc);

这看起来有点像HTML了,是不?
这种方式对于良好组织复杂GUI有好处,但对于制作,比如说一个面板,简单的工具界面,反而显得复杂。

另外,
IMGUI一般被人认为影响效率, 它的实现经常每次事件都会有两次执行,一遍逻辑,再一遍layout输出,但也许有巧妙的设计可以避免效率上的开销;
IMGUI 混合逻辑和渲染,—— 有时是缺点,它影响大型GUI的整体设计,但在用户扩展里,经常是优点,而且,运用组件化实践,它可以做到通用化的GUI编程;

IMGUI的需求

需求来自两方面,

GUI编程的学习成本开始变高(你需要学习一个描述型语言,学习框架用法才能产生一个简单GUI),不能满足立即上手的需求(很多人不需要成为专家),这块先不表,

另一方面,现代的GUI越来越有动态性,传统上,XML/HTML擅长表达静态页面,如果兼容做动态页面,则需要和代码结合的一种表示方法,比如说 react 的 jsx文件,vue的 嵌入表达式。

如果有这样一个需求,如果上有一个按钮(打开/收起),下面是一张图,随着按钮点击,图会展开和收起,
IMGUI是这样做的

const button = Button.create({text: 'click me'});
if(button.click){
    isPicShown = !isPicShown; // toggle state       
}
let pic = null;
if(isPicShown) {
      pic = Image.create('xxx.jpg')
}

可以看到, 做高交互性的GUI,是 排版和逻辑的混合,很适合直接用代码表达,这里IMGUI是相当有价值的

IMGUI的改进

之前说过,GUI的思想在发展,而我想的是,大大加强IMGUI,让之能适应大多数情况的GUI设计,

关键的几个设计点,

  1. 每个GUI对象有构造,内部状态,外部属性
  2. 在渲染更新函数里,渲染,事件,生命周期都写在一起
GUIDefine("Button") {
  arguments:{ // 这里构造属性,比如 Button.create(...arguments) 这里的表示
      ...
  },
  states: { // 这里是内部持久状态
      ...
  },
  export: { // 这里是外部属性, 比如说 button.isClick == true
      ...
  }
  onUpdate: (event) => {
      if(event.afterAttach) { // 生命周期事件
           
      } else if (event.beforeDetach) {

      }
      rect = Rect.create(...)
      clickEvt = event.system.click
      if(rect.include(clickEvt.position) ) { // 比如这里处理系统点击事件,但真实并不会这样做,请思考为什么?
          triggerEvent(this.isClick, true) // 这样就可以if(button.isClick) 了
      }
  }
}
  1. 用样式模板+属性覆盖,做为theme方案
// theme 是UI模板
GUI.setTheme('defaultTheme');
// ...
Button.create({Theme="xxx", text:"click me", color:0x000}); // color 已经包含在

  1. 如何定义UI模板(theme)
// 对所有组件,给予一个默认的属性
UITemplate("defaultTheme") {
Button = {
 color:0xbbb;
 ...
};
panel = {
 background:...,
}
}


// 第二种方式可以在组件里,加入几种theme的本组件属性
GUIDefine("Button") {
// ...
ThemeOf("defaultTheme", {
  color:"xxx";
},
ThemeOf("deepinTheme", {
  color:"xxx";
}
}

// 第一种适合实现在UI库,整体的theme定义
// 第二种特别适合用在 用户自定义组件里

相关文章

  • IMGUI的设计

    (按:web领域,GUI编程有着学习曲线,琐碎,平凡的GUI,为什么需要复杂的学习呢,我希望可以设计实现一个简单,...

  • Dear imgui & igl

    Introduction Gmm++ Library Dear imgui Dear ImGUI 在线演示 ImG...

  • Unity IMGUI Controls(Automatic l

    前言:Unity原生实现的GUI系统在调试中还是比较方便的,所以这里从官方文档里提取出一些常用的操作,方便自己日后...

  • Unity IMGUI Controls(fixed layou

    前言:Unity原生实现的GUI系统在调试中还是比较方便的,所以这里从官方文档里提取出一些常用的操作,方便自己日后...

  • Python DearPyGui 基础

    Dear PyGui 库用于开发跨平台的 GUI 应用程序,于2020年9月发布,通过对 Dear ImGui[h...

  • example-00-helloworld

    include 头文件包含了bx覆写的基础库及example工程特有的util, logo 二进制数据和imgui...

  • 关于2D渲染的一些小想法

    原文地址 概述 .这个项目最初的目的是为了尝试解析现有的UI编辑器(MyGUI)导出的UI布局信息,通过ImGUI...

  • Dragon Engine:GUI

    这一节介绍GUI的实现。我们这里使用开源库ImGui。 首先我们将GUI分离为一个单独的层,创建ImGuiLaye...

  • 通知视图更新机制

    视图监听具体模型的变化。 模型变化通知相关视图进行更新 IMGUI的做法,不需要监听,每帧取值重算,即每帧全量更新...

  • 写了个给Processing用的IMGUI库

    Processing[http://www.processing.org]是给业余编程爱好者使用的图形编程环境,画...

网友评论

      本文标题:IMGUI的设计

      本文链接:https://www.haomeiwen.com/subject/vgtqhhtx.html