/Trunk/SharpMap.Demo.Wms/Scripts/ole/Editor/Control/UndoRedo.js

# · JavaScript · 188 lines · 74 code · 28 blank · 86 comment · 19 complexity · e3fb8c687f3c92f4a2b9c263f1e9efeb MD5 · raw file

  1. /**
  2. * @copyright 2011 geOps
  3. * @license https://github.com/geops/ole/blob/master/license.txt
  4. * @link https://github.com/geops/ole
  5. */
  6. /**
  7. *
  8. * Class: OpenLayers.Editor.Control.UndoRedo
  9. *
  10. * Inherits From:
  11. * - <OpenLayers.Control>
  12. */
  13. OpenLayers.Editor.Control.UndoRedo = OpenLayers.Class(OpenLayers.Control, {
  14. /**
  15. * Property: handler
  16. * {<OpenLayers.Handler.Keyboard>}
  17. */
  18. handler: null,
  19. /**
  20. * APIProperty: autoActivate
  21. * {Boolean} Activate the control when it is added to a map. Default is
  22. * true.
  23. */
  24. autoActivate: true,
  25. /**
  26. * Constant: KEY_Z
  27. * {int}
  28. */
  29. KEY_Z: 90,
  30. /**
  31. * Constant: KEY_Y
  32. * {int}
  33. */
  34. KEY_Y: 89,
  35. /**
  36. * APIMethod: onUndo
  37. *
  38. * Called after a successful undo, passing in the feature that was altered.
  39. */
  40. onUndo: function(){},
  41. /**
  42. * APIMethod: onRedo
  43. *
  44. * Called after a successful redo, passing in the feature that was altered.
  45. */
  46. onRedo: function(){},
  47. /**
  48. * APIMethod: onRemoveFeature
  49. *
  50. * Called when the Undo/Redo control is about to remove a feature from the layer. This call happens before the feature is removed.
  51. */
  52. onRemoveFeature: function(){},
  53. /**
  54. * Property: undoStack
  55. * {<Array>}
  56. *
  57. * A stack containing states of a feature that can be undone. Objects on this stack are hashes, of the form {feature: ..., :geometry ...}.
  58. */
  59. undoStack: null,
  60. /**
  61. * Property: redoStack
  62. * {<Array>}
  63. *
  64. * A stack containing states of a feature that can be redone. Objects on this stack are hashes, of the form {feature: ..., :geometry ...}.
  65. */
  66. redoStack: null,
  67. currentState: null,
  68. /**
  69. * Constructor: OpenLayers.Control.UndoRedo
  70. * Create a new Undo/Redo control. Does not take any parameters.
  71. */
  72. initialize: function() {
  73. OpenLayers.Control.prototype.initialize.apply(this, arguments);
  74. this.undoStack = new Array();
  75. this.redoStack = new Array();
  76. },
  77. /**
  78. * Method: draw
  79. * Activates the control.
  80. */
  81. draw: function() {
  82. this.handler = new OpenLayers.Handler.Keyboard( this, {
  83. "keydown": this.handleKeydown} );
  84. },
  85. /**
  86. * Method: handleKeydown
  87. * Called by the feature handler on keydown.
  88. *
  89. * Parameters:
  90. * {Integer} Key code corresponding to the keypress event.
  91. */
  92. handleKeydown: function(e) {
  93. if (e.keyCode === this.KEY_Z && e.ctrlKey === true && e.shiftKey === false) {
  94. this.undo();
  95. }
  96. else if (e.ctrlKey === true && ((e.keyCode === this.KEY_Y) || (e.keyCode === this.KEY_Z && e.shiftKey === true))) {
  97. this.redo();
  98. }
  99. },
  100. /**
  101. * APIMethod: undo
  102. * Causes an the Undo/Redo control to process an undo.
  103. */
  104. undo: function() {
  105. var feature = this.moveBetweenStacks(this.undoStack, this.redoStack, true);
  106. if (feature) this.onUndo(feature);
  107. },
  108. /**
  109. * APIMethod: redo
  110. * Causes an the Undo/Redo control to process an undo.
  111. */
  112. redo: function() {
  113. var feature = this.moveBetweenStacks(this.redoStack, this.undoStack, false);
  114. if (feature) this.onRedo(feature);
  115. },
  116. /**
  117. * Method: moveBetweenStacks
  118. * The "meat" of the Undo/Redo control -- it actually does the undoing/redoing. Although some idiosyncrasies exist, this function
  119. * handles moving states from the undo stack to the redo stack, and vice versa. It also handles adding and removing features from the map.
  120. *
  121. * Parameters: TODO
  122. */
  123. moveBetweenStacks: function(fromStack, toStack, undo) {
  124. if (fromStack.length > 0) {
  125. this.map.editor.editLayer.removeAllFeatures();
  126. var state = fromStack.pop();
  127. toStack.push(this.currentState);
  128. if (state) {
  129. var currentFeatures = new Array(len);
  130. var len = state.length;
  131. for(var i=0; i<len; ++i) {
  132. currentFeatures[i] = state[i].clone();
  133. }
  134. this.currentState = currentFeatures;
  135. this.map.editor.editLayer.addFeatures(state, {silent: true});
  136. } else {
  137. this.currentState = null;
  138. }
  139. }
  140. else if (this.currentState && undo) {
  141. toStack.push(this.currentState);
  142. this.map.editor.editLayer.removeAllFeatures();
  143. this.currentState = null;
  144. }
  145. },
  146. register: function() {
  147. var features = this.map.editor.editLayer.features;
  148. var len = features.length;
  149. var clonedFeatures = new Array(len);
  150. for(var i=0; i<len; ++i) {
  151. clonedFeatures[i] = features[i].clone();
  152. }
  153. if (this.currentState) {
  154. this.undoStack.push(this.currentState);
  155. }
  156. this.currentState = clonedFeatures;
  157. this.redoStack = new Array();
  158. },
  159. CLASS_NAME: "OpenLayers.Editor.Control.UndoRedo"
  160. });