“撤消打字”应该如何表现?


12

我正在实现一个包含撤消/重做堆栈的Java应用程序。我注意到有些应用程序(例如Mac OS X上的TextEdit)允许您在键入一些文本后从“编辑”菜单中选择“撤消键入”。我也想在我的应用程序中实现这种功能,但是我很难找到有关其行为方式的准则。

经过反复试验,关于TextEdit的“撤消键入”行为的最佳猜测是:

  • 当用户键入一个新字符(或键入删除键)时,如果一个字符位于“撤消”堆栈的顶部,则将其合并到上一个“撤消键入”项中,除非发生以下情况之一
  • 用户至少闲置15秒后继续输入内容,请务必创建新的“撤消键入”项目
  • 用户长时间输入并满足某些条件后,请务必创建一个新的“撤消键入”项目(无法确定这是基于时间还是基于字符计数)。
  • 选择任何文本然后删除或覆盖文本时,始终创建一个新的“撤消键入”项目(选择文本,不进行更改,然后返回到原始插入点并继续键入不会触发此操作)

在实践中,Apple的策略似乎行得通(至少在我键入时对我有效),但是正如最后一点所指出的那样,我实际上还无法弄清楚规则。另外,似乎其他程序遵循不同的规则,例如Microsoft Word。Google尚未为任何“撤消键入”实施提供明确的规则列表,而且我还没有遇到任何应如何操作的最佳实践。那么它应该如何表现呢?还是仅仅取决于程序员的想法?

编辑:只是为了澄清,我现在对实现细节不感兴趣。对于是否存在权威的参考文献(例如最佳实践或用户界面文档)进行描述或对如何在多种产品中实现的描述,我尤其感到好奇。


我的建议:将修改压缩到仍然可以从撤消信息中重建按键的确切顺序的地方,仅此而已。例如,这意味着如果用户键入某些内容并立即使用退格键将其删除,则它们之间应存在一个撤消点。
Ambroz Bizjak

也许每次用户创建新行时,或者每次输入字符后立即使用空格键,您都可以添加一个新的“撤消打字项目”。在新的“撤消打字项目”之前,IMO的等待时间为15秒,可能有点长,但这就是我自己。(我将花大约5秒钟的时间)
2013年

或者也许应该将“确切的按键顺序”放宽到“每次修改后的文本状态”。这样做的目的是防止任何文本因压缩而丢失。
Ambroz Bizjak

在我看来,如果不满足其他条件,TextEdit将合并空格并使用最后一个“撤消键入”项将其删除。因此124<delete>3,然后撤消和重做将导致123。我猜这的好处是,它会导致用户最终的文本状态,有点像上面的建议。
Thunderforge

您是否尝试过搜索专利?(规则通常在库层中编码,而不暴露给用户代码。)
Donal Fellows 2013年

Answers:


5

如果您正在寻找权威的资料,我认为最好的Mac相关资料可以在Apple 的Undo Architecture文档中找到。

不过,我认为您不会找到有关何时应该合并撤消事件的规则列表。对于一种应用程序来说正确的感觉不一定对另一种应用程序有意义。例如,在文本编辑器中合并击键是有意义的,因为用户可能会将键入段落视为单个操作而不是539个单独的操作,并且还因为您不希望用户为了获得操作而不得不撤消539次到他们键入该段落之前的地步。但是在绘图程序中对形状进行移动操作呢?还是对填充颜色进行顺序调整?根据程序的性质,您可以为是否合并这些程序提供很好的理由。

用户长时间输入并满足某些条件后,请务必创建一个新的“撤消键入”项目(无法确定这是基于时间还是基于字符计数)。

它基于自动保存。幸运的是,您可以使用TextEdit源代码并进行评论。我认为,如果您看一下它,将会对发生的事情和原因有一个更好的了解。例如:

- (void)saveToURL:(NSURL *)absoluteURL ofType:(NSString *)typeName forSaveOperation:(NSSaveOperationType)saveOperation completionHandler:(void (^)(NSError *error))handler {
    // Note that we do the breakUndoCoalescing call even during autosave, which 
    // means the user's undo of long typing will take them back to the last spot an 
    // autosave occured. This might seem confusing, and a more elaborate solution may 
    // be possible (cause an autosave without having to breakUndoCoalescing), but since 
    // this change is coming late in Leopard, we decided to go with the lower risk fix.
    [[self windowControllers] makeObjectsPerformSelector:@selector(breakUndoCoalescing)];
 ...

我知道您说您对实施细节不感兴趣,但是希望了解Apple实施TextEdit的方式可以为您为自己的应用程序做出决策提供依据。


1
我认为我将宣布这个最佳答案。感谢您提供Apple实现的链接以及我提供的特定示例的一些代码。但我认为您是对的,它通常基于应用程序的需求,没有人真正致力于标准化这些需求以及如何解决这些需求。
雷霆队

1

在键盘按下 ->代表您的空闲启动的计时器

在按键/计时器运行 ->重置计时器

在按下按键/不运行计时器 ->重新调整单元格块以准备随着位置更改而新的保留状态

空闲计时器耗尽 ->建立新的撤消状态

我不会跟踪按键身份。我将其分为多个文本单元格(按字符计数),使您可以按距最近单元格开始位置的偏移量来跟踪位置,因此不必每次空闲计时器耗尽时都无需保存托尔斯泰小说的整个状​​态。当在其他单元格之前的单元格被编辑时,重新调整这些偏移是棘手的部分。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.