命令式redo/undo和鍵盤行為

來源:互聯網
上載者:User

幾個星期前在看前輩的redo/undo總結,這次終於可以自己試試這個命令式redo/undo的寫法了。

命令式redo/undo主要有三個部分;

1,ICommand;(命令作用的對象,excute,undo,redo,還有一些Undo,redo參數變數)

2,commandStack;(儲存命令的棧,undo和redo都在這棧裡面上下走)

3,通道,也可以說是觸發器,把命令放進commandStack裡面

 

這種方式其實和ACM的一些水題很類似,練習堆棧的操作。

其中注意幾點小問題:

1,當執行完undo/redo之後,再執行excute時,則_index之後的命令全部清除;以WPS或者WORD為例,都有這樣的操作。其實這裡面的思想很是奇特,如果我不清空後面的內容呢?就好象畫一個圓,畫到四分之三的時候,突然畫出得不好了,要重新從四分之三來畫,當畫完四分之一再執行一次Undo的時候,也就是還要再跑到那個畫得不好的地方然後再返回四分之三的地方,也就是那個不好的地方其實在undo的時候已經被定位為無用的資料,所以可以不要,所以才會在執行excute的時候大膽地把後面的資料不要。這個有點牽涉到人的使用心理。當人們會使用撤銷這個操作時,說明當前的資料已經為錯誤,無用的,所以當然是要放棄的。突然很是震撼這個功能,很是欽佩總結這個功能的人。

2,一個越界的問題。越界在這裡顯得尤為明顯。而且容易出錯。

插入棧的結點,可以實現一個操作實現多個命令

 

package mainframe.struct<br />{<br />import mainframe.IViewElement;<br />import mainframe.command.ICommand;</p><p>public class Node<br />{<br />public var command: Vector.<ICommand> = null;</p><p>public function Node()<br />{<br />command = new Vector.<ICommand>();<br />}</p><p>public function push(cmd: ICommand): void<br />{<br />if (!command)<br />command = new Vector.<ICommand>();<br />command.push(cmd);<br />}<br />}<br />}

 

邊界處理問題

package mainframe.implement<br />{</p><p>import mainframe.ICommandStack;<br />import mainframe.command.ICommand;<br />import mainframe.struct.Node;</p><p>public class CCommandStack implements ICommandStack<br />{<br />private var _commandPool: Vector.<Node> = null;<br />private var _index: int = 0;<br />private var _flag: int = 0;</p><p>public function CCommandStack()<br />{<br />commandStack();<br />}</p><p>// ---------------------------------------------------------<br />// ICommandStack<br />// ---------------------------------------------------------</p><p>public function commandStack(): Vector.<Node><br />{<br />if (!_commandPool)<br />_commandPool = new Vector.<Node>();<br />return _commandPool;<br />}</p><p>public function addCommand(com: Node): int<br />{<br />if (!com)<br />return 0;</p><p>if (_flag)<br />{<br />for (;_commandPool.length != _index;)<br />{<br />_commandPool.pop();<br />}<br />}<br />_commandPool.push(com);<br />_index = _commandPool.length;<br />trace("length " + _index);<br />_flag = 0;<br />return 1;<br />}</p><p>public function hasNext(): Boolean<br />{<br />if (_index < _commandPool.length)<br />return true;<br />else<br />return false;<br />}</p><p>public function hasLast(): Boolean<br />{<br />if (_index > 0)<br />return true;<br />else<br />return false;<br />}</p><p>public function reDo(): void<br />{<br />var node: Node = _commandPool[_index++];</p><p>var cmd: Vector.<ICommand> = node.command;<br />var size: int = cmd.length; </p><p>for (var i: int = 0; i < size; ++i)<br />cmd[i].reDo();<br />_flag = 1;<br />}</p><p>public function unDo(): void<br />{<br />var node: Node = _commandPool[--_index];<br />var cmd: Vector.<ICommand> = node.command;<br />var size: int = cmd.length;</p><p>for (var i: int = 0; i < size; ++i)<br />cmd[i].unDo();<br />_flag = 1;<br />}<br />}<br />}

 

 

3,鍵盤行為操作;

快速鍵這裡設定依據之前華哥架構裡面的滑鼠行為,思考了下ctrl+c/ctrl+v的行為,先是按下control然後再c/v,所以在keyup的時候判斷ctrl有沒有Up,沒有的話表示粘帖複製行為仍存在。所以加多個變數儲存ctril是否存在,這樣幾個訊息流程下來後就可以判斷這個行為了。很是精彩。。。。

 

  private function _unDoFun(e: KeyboardEvent): void<br />{<br />if (e.keyCode == Keyboard.ENTER && _pool == Keyboard.CONTROL)<br />{<br />if (_cmdStack.hasLast())<br />_cmdStack.unDo();<br />}<br />else if (e.keyCode == Keyboard.CONTROL)<br />_pool = Keyboard.CONTROL;<br />}</p><p>private function _reDoFun(e: KeyboardEvent): void<br />{<br />if (e.keyCode == Keyboard.BACKSPACE && _pool == Keyboard.CONTROL)<br />{<br />if (_cmdStack.hasNext())<br />_cmdStack.reDo();<br />}<br />else if (e.keyCode == Keyboard.CONTROL)<br />_pool = Keyboard.CONTROL;<br />}</p><p>private function _checkFun(e: KeyboardEvent): void<br />{<br />if (e.keyCode == Keyboard.CONTROL)<br />_pool = 0;<br />}

 

 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.