2019-04-30

## 背景

   编辑器是IDE的重要组成部分。可视化编辑器比文本编辑器更能体现IDE工具降低开发成本,提高开发效率的目的。另外对于功能完整,交互体验,内存占用与性能(一般都是连续使用很久)有一定要求。

### 编辑器的数据设计

![编辑器数据流向图](https://raw.githubusercontent.com/weiweiwei256/basics-learn/master/docs/resource/editor-data-flow.png)

   上图,还是比较清晰地描述了这一过程。编辑器在打开和关闭/保存是会进行实际文件的操作。而在编辑器运行时,都是对结构化的运行

数据对象进行操作。所以组件的数据结构设计,以及良好的API,对于后续的研发至关重要。如果可视化编辑框架采用第三方开源框架(例如:[mxgraph](https://github.com/jgraph/mxgraph)),还需将运行时数据对象与框架标准数据进行转化,因为往往公司已有的数据结构是自己定制的不会和框架一致,也不会为了使用框架而修改。:grimacing:

   索引是基于结构化数据,针对文件内容快速检索的功能。就像针对文件可检索的数据库。基于索引可进行组件使用统计。文件结构校验等功能。

### 可视化编辑器的组成

- #### 可视化编辑区

    - 组件选中

       选中是整个可视化编辑的基础。用户的操作行为发生在视图上(View),当View上监听到click事件后需快速映射到对应的数据对象(model)。当属性性修改后,数据对象发生改变,又需要快速更新渲染视图。所以负责桥接视图和数据的部分称为控制器(Control),这就是MVC模式的典型使用场景。最后将选中组件的数据向外传递,其他辅助模块如:属性,大纲就可以正产工作了。当然别忘了凸现下当前选中的组件。

    - 拖拽调整组件位置

       鼠标拖动过程中,如果悬浮的拖动目标组件对与当前拖动的元素有影响的话,例如:存在容器类组件,普通组件,普通组件无法容纳普通组件,而容器可以容纳。则需要实时获取鼠标下方的组件,并快速获取组件的配置信息以校验后续的布局策略。所以需要View -> model -> 组件配置 -> 产生拖动策略 的逻辑足够快的执行。当拖拽完成时,产生移动命令(下面有详细说明)修改model更新view.

    - 拖拽添加组件

       拖拽新增类似于拖拽移动。只是需要产生创建命令。

    - 拖拽回显(拖拽完成前的辅助线或模拟组件放置后的效果)

       拖拽辅助线应绘制在独立的上方图层,可在拖动开始时,初始化可辅助的位置。校验条件放宽些,达到吸附的效果。

- #### 组件选择区

    - 配置化组件

       丰富的组件与可视化编辑器的能力息息相关。组件新增和修改是开发比重较大且持续的部分。可通过配置化的方式完成。例如:组件的唯一标志,组件图标,组件名称,组件类型,组件属性(组件属性的编辑方式)等等,提取成相似的配置。

    - 个性化组件(进阶)

       编辑器提供的标准组件可完成大部分的场景开发,但是有些个性化的场景却受限于标准组件功能无法实现。但采用标准组件扩展的方式不仅增加编辑器的研发负担,还增加组件的复杂度。(例如 :组件的某个属性只会在特性场景使用)。所有如果支持用户自己高度定制自己的组件,自定义组件与标准组件库分离,独立维护,会是更好的方式。但这也对组件的配置化设计,自定义组件功能实现者提出更高要求。

    - 组件分级

       上面描述了两级,进一步推演下去。一些良好的个性化组件可以被编辑器吸收,由编辑器默认提供,于是就出现了三级分化。标准组件,公共自定义组件,自定义个性化组件。从业务角度来看,也是业务程度不断增加的过程。

- #### 命令机制:

       用户所有的编辑行为(新增,删除,修改)规范成统一的命令对象,称为命令。命令可以被正向或反向执行(undo,redo),并且命令执行后并不销毁而是保存到命令堆栈中。命令机制可实现用户触发相应的正反向执行,并提供文件状态,为文件保存提供准确时机。

    ![命令机制图](https://raw.githubusercontent.com/weiweiwei256/basics-learn/master/docs/resource/command-design.png)

    1. 当用户新增一个组件时,一个创建的命令产生,并正向执行。

    2. 将命令放入undoStack

    3. 更新相关状态 由于undoStack.length>0 所以undo菜单可点击;由于undoStack不为空,说明用户产生了修改,所以更新文件的编辑状态为:产生了修改(dirty)

    4. 如果用户触发的undo,则取出undoStack的最上层的命令,反向执行命令逻辑(创建的命令的反向执行逻辑是删除创建的组件),于是组件被删除。

    5.  将命令放置的redoStack

    6. 更新状态:由于undoStack,redoStack的变化更新undo菜单为不可点击,redo菜单为可点击,文件状态为未编辑(no dirty)

    ps:

    1. 如果用户连续操作,只是队列深浅的变化,不影响效果

    2. 这只是一个简单的设计,未考虑用户连续保存,redo后又正常编辑等复杂情况。

- #### 热键机制

    1. 编辑器全局热键的监听

    2. 热键触发逻辑的配置化

       由于热键本身并不固定,新增,修改的情况比较多,另外良好的编辑器可以支持用户自定热键,甚至自定义热键逻辑。所以配置的方式会提供便利。

- #### 属性编辑区

    1. 根据组件配置信息与用户选中的组件,及时更新组件属性的编辑域,并提供良好的编辑交互。用户产生修改行为后,产生相应的修改命令。

- #### 大纲区

    1. 根据结构化数据生成结构树,方便用户查看文件结构,选中组件,删除组件,具有一定辅助的功能。

### 结束语

   架构上参考一部分Eclipse插件开发中的GEF框架,有些自己设计实现了,有些自己YY的。可能有后续相关博客。。。有啥意见建议及时交流哈:smile:

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 简介 前端路由简单的说,就是业内的跳转 进行不同组件之间的切换 使用 导入包 创建一个路由对象,当导入包之后,就有...
    coderymy阅读 349评论 0 0
  • Day44: Nginx是目前最流行的静态Web服务软件 1.nginx介绍 Nginx (“engine x”)...
    E的彼岸阅读 160评论 0 0
  • 报名了一个游泳课。 都说一对一学习会更好,我倒喜欢人多。我们是八个人的小组,有伴多好啊。 上次买的游泳衣,是在酒店...
    牧田麻麻阅读 214评论 0 0
  • 第一次发现原来还有这么个网站,可以容我放任思绪,释放堵在脑海里的文字。 犹如读书时流行的博客,但即便写了,也不会有...
    9e5fd2b34ba6阅读 567评论 0 0
  • 这一天真是太有意思了。 上午扫楼第一次被抓,为了弥补被抓的忐忑,取了两朵花花安抚一下,心情就美丽了许多。下午出去收...
    小小Ulianyoga阅读 87评论 0 0