Clojure:如何构建桌面UI

Son*_*oth 11 model javafx cad clojure

我正在尝试为原理图,布局,绘图材料设计桌面UI.只是寻找实际软件设计师的高级建议.

假设一个内存中的"数据库",(所有用户数据的任意深度的clojure映射,以及可能的另一个用于应用程序首选项的等等),我正在研究如何在这些上执行模型 - 视图 - 控制器的事情,其中数据可以通过以下任何一个或多个来呈现和修改:

  1. 一个独立的文本字段,显示单个参数,例如框宽.
  2. "检查器"类型的视图,显示所选对象的多个参数,例如框宽,高度,颜色,复选框等.
  3. 表/电子表格类型的视图,显示多个对象的多个参数,可能是整个数据库
  4. 整个事物的图形渲染,例如原理图和布局视图.

修改其中任何一个应立即显示在每个其他活动视图中,包括文本和图形,而不是在单击"确定"后...因此不允许使用模式框.如果出于某种原因,表视图,检查器视图和图形渲染都在视图中,以图形方式拖动框的角应立即显示在文本中等.

有问题的平台是JavaFX,但我想在UI和其他所有内容之间进行清晰的分离,所以我想避免bind使用JFX,因为这会将我的设计数据与JFX Properties紧密联系起来,增加了模型的颗粒感,并迫使我在标准的clojure函数之外工作以处理数据,和/或大量处理整个getValue/ setValue世界.

我仍然假设至少有一些有状态/可变性,并使用内置的Clojure功能,例如add-watch对atom/var/ref 的能力,并让运行时信号依赖于函数.

特定于平台的交互将与实际的UI紧密相关,例如reifying ActionListeners和处理ObservableValues等,并将尝试最小化对JavaFX Property等实际应用程序数据的依赖.我不是为了这个而招待FRP.

我不介意扩展JFX接口或构建我自己的协议来使用特定于应用程序的协议defrecord,但我更喜欢将应用程序数据保留为直接的Clojure数据,而不受平台的影响.

问题是如何设置这一切,最接近不可变模型.我看到几个选项:

  1. 细粒度:每个参数值/基元(即Long,Double,Boolean或String)都是一个原子,每个视图都可以修改值"到达",只要它在数据库中需要更改值即可.这可能很糟糕,因为可能存在数千个单独的值(例如手绘曲线上的点),并且需要大量(deref...)垃圾.我相信这就是JFX想要这样做的方式,在叶子节点等处有巨大的Properties数组,感觉很臃肿.使用这种方法,它似乎没有比用Java/C++编写代码好多少.
  2. 中等粒度:数据库中的每个对象/记录都是Clojure映射的原子.当其中任何一个值发生变化时,将替换整个地图.处理的原子总数较少,并且允许例如用于各种事物的长序列数字.但是,当数据库中的某些对象需要比其他对象更多的嵌套时,这会变得复杂.
  3. 粗粒:只有一个原子:数据库.任何时候发生任何变化,都会替换整个数据库,并且每个视图都需要重新渲染其特定部分.这感觉有点像使用锤子拍打苍蝇,而天真的实施则需要一直重新渲染.但我仍然认为这是最好的权衡,因为任何原语都有一个来自根节点的清晰访问路径,无论是在每个原始级别还是每个记录级别访问.

我还需要能够多次实例化一个数据模板.因此,例如,如果用户更改在多个位置使用的符号或形状,则将在任何地方应用单个编辑.我相信这也需要某种类型的"指针"式行为.我想我可以将一个原子存储到模型中,然后根据需要进行实例化,并且它可以在任何上述粒度模型中工作.

还有其他方法吗?试图用函数式语言做一个类似GUI编辑器的工具只是愚蠢吗?谢谢

Rod*_*ada 5

我认为使用函数式语言来做类似GUI编辑器的工具并不愚蠢.但我不能声称对你的问题有答案.以下是一些可能对您的旅程有所帮助的链接:

  1. Stuart Sierra - 组件足够结构
  2. Chris Granger - Light Table:解释Light Table()的结构.
  3. Chris Granger - 作为价值的IDE:与上述视频相关的博客文章
  4. Conal Elliott - 有形功能编程:使用功能反应编程创建可组合UI,但他的代码在Haskell中.
  5. Nathan Herzing和Chris Shea - 用Pedestal,Datomic,Om和core.async帮助选民
  6. David Nolen - 比较文字编程:显示所有使用core.async来简化ClojureScript中的UI编程.这里的想法可以在桌面UI中使用.
  7. Rich Hickey - 系统语言:Clojure创建者对系统编程的惊人谈论.

Erik Meijer对功能与命令式代码有一个很好的引用:

......无论是Haskell,C#Java,F#,Scala,Python,PHP都想到了拥有大量与外部世界交互的命令式代码的想法,并且在那里有编写函数的纯代码岛一种纯粹的方式.但你必须决定这些岛屿的大小和海洋的大小.但答案绝不是只有岛屿或只有海洋.一个优秀的程序员确切地知道正确的平衡.