一篇用动态媒介写的文章
文章目录
如果嵌入和查看方法提供得足够好,作为媒介本身看待的计算机可以是所有其他媒介。 – Alan Kay
前言
近期重读 An Introduction to Morphic 的时候,发现 Morphic 中用于自动布局的类 AlignmentMorph
已经被弃用:
顺着类注释中的提示, 准备学习一下 layoutPolicy , 在 Squeak wiki 里读了几篇与此相关的词条:
也跟着做了不少例子:
Morphic 新的布局系统有点像 CSS 里的 Flexbox,但早了 20 多年。
在 Morphic 布局系统话题下,好几篇 Squeak wiki 词条都提到了 Ted kaehler 和 Andreas Raab 写的《Control Your Submorphs》一文。
由于 Ted kaehler 和 Andreas Raab 都是 Squeak 的核心开发者,所以我想好好读读这篇文章,看看能否学到一些关于布局的强大想法。
我最近在 Smalltalk 里弄懂了许多过去一知半解的概念,越来越喜欢和信任这个学习环境。在 Squeak 里,好像什么都能学会。正如 Alan Kay 承诺的那样,强大的系统能够增强学习者,帮助 Ta 更好的理解和学习复杂系统。我过去接触 HTML/CSS 时在排版布局问题上碰了很多壁,以至一直不愿再折腾它们。这次有点蠢蠢欲动,指不定 Squeak 能够帮助我,就像它曾帮助我理解了许多过去觉得困难的事情。
遇到困难
可是,始终无法在互联网上搜到《Control Your Submorphs》的电子版。
重新阅读 MorphLayoutArticle词条,发现它是一篇动态文章:
The dynamic essay MorphLayoutArticle describes how layout works in Morphic.
或许 Ted kaehler 和 Andreas Raab 完全在 Squeak 里写作,压根没有发布 PDF 和 HTML 版本!
这篇文章的格式是: MorphLayoutArticle.pr
.pr
是 Squeak/Etoys 项目文件的后缀名。 MorphLayoutArticle 提到 它在 Squeak 3.2 中加载良好。但若要将其加载到 Squeak 3.8.1 中,需要参考这些说明。
Squeak 3.2 发行于 2002 年, Squeak 3.8 则发行于 2005 年, 年代如此久远,在瞬息万变的计算机世界,仿佛远古时代的文物, 它们在我的 MacOS 12.3.1(M1) 都运行不了。
救星
突然想到之前换电脑之后,无法运行 Etoys 的经历,后来的解决方案是使用 SqueakJS 虚拟机来运行 Etoys 镜像(image) (Etoys Lively)。
SqueakJS 是由 Vanessa Freudenberg 使用纯 JavaScript 编写的 Squeak 虚拟机。
我想起 SqueakJS 适用于许多与 OpenSmalltalk 兼容的 image!指不定就包括 Squeak 3.2 或 Squeak 3.8。 果真,Squeak 3.8 可用!
加载动态文章
MorphLayoutArticle.pr 是在 Squeak 3.2 里写的,为了将其加载到 Squeak 3.8 里,需要 做些修改。
|
|
通过将 SmartRefStream 类的#initKnownRenames
方法,修改为上述内容. 然后将 MorphLayoutArticle.pr 文件拖入系统, 便可成功加载。
开始阅读
这篇文章篇幅很小,读来十份轻松。
不同于 Squeak wiki 里的文字和图片描述,这篇短文里,穿插了 6 个交互式的案例,作者每次在阐述一个控制布局的关键概念(参数)后,就让读者通过操控作者精心准备的交互案例,来把握这些参数。
这是我第一次感受到布局的乐趣,它是如此清晰、浅显而直观!短短几分钟,就毫不费劲地掌握了它们,我心里十份清楚,我并不只是理解了作者通过静态媒介(文字)所表达的东西,要比这更多。通过按照自己的意志操控这些布局元素,我仿佛变成了元素本身,亲身参与到了布局之中!
这就像 Seymour Papert 在《Mindstorms》里提到的童年的齿轮。
在 Squeak 上做实验
在最新的 Squeak 上(Squeak 6.0)。 “对 submorphs 的控制” 基本都可以在 morph 的 menu > layout
菜单里完成。 我的工作习惯是:
- 心智模型: 布局是 owner 的职责(控制submorphs)
- 从 table layout 开始 (正如动态文章里建议的)
- 指定 layoutInset(submorphs 与 owner 的间隔) 和 cellInset (submorph 之间的间隔)。
- 指定 wrap 方式(溢出时,如何换行来包住)
- 在 menu 中复制手动完成的布局属性,方便之后复用(复用代码如下)
|
|
以下是一个演示视频
解释控制参数
layoutInset
: 规定了 owner morph 的右下角以及左上角的间距。listDirection
定义排列的 “主要” 方向。 如果没有足够的空间让排列适合单个行或列, 则wrapDirection 定义排列的 “辅助” 方向,WrapDirection
还可以具有特殊值 #none,表示这种排列将是一维的并且永远不会换行。以下是listDirection
和wrapDirection
的影响:
- morph 具有控制其如何更改自身大小的属性(
hResizing:
和vResizing:
)
尾声
遗憾的是,计算机并没有像 Alan Kay 所期待的那样,作为一种动态媒介流行起来。今天计算机里边的内容主要是对旧媒介的模仿,它模仿书籍、电视、电影… 人们在计算机里写作,就像过去用纸笔写作。像 《Control Your Submorphs》 这样帮助读者更好地理解复杂事物的文章不仅不多见,而且连阅读它的工具都日渐式微,不易寻得。
近年情况有所好转,Jupyter 这几年在科学界很流行,尤其是物理学、生物学和数据科学/AI 领域,人们甚至直接在里头写论文 – 一篇可运行的论文,一篇读者可以与作者的论点进行交互的论文。
但相比于 Squeak,Jupyter 才刚刚起步,即使是 20 年前 的Squeak 也走得更远。
差距是愿景上的。
附录
导出文件到本地
当你在 SqueakJS 中导出文件时(诸如save morph in file
),文件只是被存储在了浏览器页面的 IndexedDB 里(这篇论文里有讨论 SqueakJS 的存储机制)。你需要 到这儿下载到本地。
参考
文章作者 种瓜
上次更新 2022-08-25