Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(15)

Side by Side Diff: chrome/browser/resources/file_manager/js/image_editor/commands.js

Issue 12761002: Fixed multiple undo in the Files.app's image editor. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Fixed. Created 7 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 /** 5 /**
6 * Command queue is the only way to modify images. 6 * Command queue is the only way to modify images.
7 * Supports undo/redo. 7 * Supports undo/redo.
8 * Command execution is asynchronous (callback-based). 8 * Command execution is asynchronous (callback-based).
9 * 9 *
10 * @param {Document} document Document to create canvases in. 10 * @param {Document} document Document to create canvases in.
11 * @param {HTMLCanvasElement} canvas The canvas with the original image. 11 * @param {HTMLCanvasElement} canvas The canvas with the original image.
12 * @param {function(callback)} saveFunction Function to save the image. 12 * @param {function(callback)} saveFunction Function to save the image.
13 * @constructor 13 * @constructor
14 */ 14 */
15 function CommandQueue(document, canvas, saveFunction) { 15 function CommandQueue(document, canvas, saveFunction) {
16 this.document_ = document; 16 this.document_ = document;
17 this.undo_ = []; 17 this.undo_ = [];
18 this.redo_ = []; 18 this.redo_ = [];
19 this.subscribers_ = []; 19 this.subscribers_ = [];
20 20
21 this.baselineImage_ = canvas;
22 this.currentImage_ = canvas; 21 this.currentImage_ = canvas;
22
23 this.baselineImage_ = document.createElement('canvas');
24 this.baselineImage_.width = this.currentImage_.width;
25 this.baselineImage_.height = this.currentImage_.height;
26 var context = this.baselineImage_.getContext('2d');
27 context.drawImage(this.currentImage_, 0, 0);
28
23 this.previousImage_ = document.createElement('canvas'); 29 this.previousImage_ = document.createElement('canvas');
30 this.previousImageAvailable_ = false;
24 31
25 this.saveFunction_ = saveFunction; 32 this.saveFunction_ = saveFunction;
26 33
27 this.busy_ = false; 34 this.busy_ = false;
28 35
29 this.UIContext_ = {}; 36 this.UIContext_ = {};
30 } 37 }
31 38
32 /** 39 /**
33 * Attach the UI elements to the command queue. 40 * Attach the UI elements to the command queue.
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after
115 * @param {function} callback Completion callback. 122 * @param {function} callback Completion callback.
116 * @private 123 * @private
117 */ 124 */
118 CommandQueue.prototype.doExecute_ = function(command, uiContext, callback) { 125 CommandQueue.prototype.doExecute_ = function(command, uiContext, callback) {
119 if (!this.currentImage_) 126 if (!this.currentImage_)
120 throw new Error('Cannot operate on null image'); 127 throw new Error('Cannot operate on null image');
121 128
122 // Remember one previous image so that the first undo is as fast as possible. 129 // Remember one previous image so that the first undo is as fast as possible.
123 this.previousImage_.width = this.currentImage_.width; 130 this.previousImage_.width = this.currentImage_.width;
124 this.previousImage_.height = this.currentImage_.height; 131 this.previousImage_.height = this.currentImage_.height;
132 this.previousImageAvailable_ = true;
125 var context = this.previousImage_.getContext('2d'); 133 var context = this.previousImage_.getContext('2d');
126 context.drawImage(this.currentImage_, 0, 0); 134 context.drawImage(this.currentImage_, 0, 0);
127 135
128 command.execute( 136 command.execute(
129 this.document_, 137 this.document_,
130 this.currentImage_, 138 this.currentImage_,
131 function(result, opt_delay) { 139 function(result, opt_delay) {
132 this.currentImage_ = result; 140 this.currentImage_ = result;
133 callback(opt_delay); 141 callback(opt_delay);
134 }.bind(this), 142 }.bind(this),
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
172 this.redo_.push(command); 180 this.redo_.push(command);
173 181
174 var self = this; 182 var self = this;
175 183
176 function complete() { 184 function complete() {
177 var delay = command.revertView( 185 var delay = command.revertView(
178 self.currentImage_, self.UIContext_.imageView); 186 self.currentImage_, self.UIContext_.imageView);
179 self.commit_(delay); 187 self.commit_(delay);
180 } 188 }
181 189
182 if (this.previousImage_) { 190 if (this.previousImageAvailable_) {
183 // First undo after an execute call. 191 // First undo after an execute call.
184 this.currentImage_.width = this.previousImage_.width; 192 this.currentImage_.width = this.previousImage_.width;
185 this.currentImage_.height = this.previousImage_.height; 193 this.currentImage_.height = this.previousImage_.height;
186 var context = this.currentImage_.getContext('2d'); 194 var context = this.currentImage_.getContext('2d');
187 context.drawImage(this.previousImage_, 0, 0); 195 context.drawImage(this.previousImage_, 0, 0);
188 196
189 // Free memory. 197 // Free memory.
190 this.previousImage_.width = 0; 198 this.previousImage_.width = 0;
191 this.previousImage_.height = 0; 199 this.previousImage_.height = 0;
200 this.previousImageAvailable_ = false;
192 201
193 complete(); 202 complete();
194 // TODO(kaznacheev) Consider recalculating previousImage_ right here 203 // TODO(kaznacheev) Consider recalculating previousImage_ right here
195 // by replaying the commands in the background. 204 // by replaying the commands in the background.
196 } else { 205 } else {
197 this.currentImage_ = this.baselineImage_; 206 this.currentImage_.width = this.baselineImage_.width;
207 this.currentImage_.height = this.baselineImage_.height;
208 var context = this.currentImage_.getContext('2d');
209 context.drawImage(this.baselineImage_, 0, 0);
198 210
199 var replay = function(index) { 211 var replay = function(index) {
200 if (index < self.undo_.length) 212 if (index < self.undo_.length)
201 self.doExecute_(self.undo_[index], {}, replay.bind(null, index + 1)); 213 self.doExecute_(self.undo_[index], {}, replay.bind(null, index + 1));
202 else { 214 else {
203 complete(); 215 complete();
204 } 216 }
205 }; 217 };
206 218
207 replay(0); 219 replay(0);
(...skipping 18 matching lines...) Expand all
226 }; 238 };
227 239
228 /** 240 /**
229 * Closes internal buffers. Call to ensure, that internal buffers are freed 241 * Closes internal buffers. Call to ensure, that internal buffers are freed
230 * as soon as possible. 242 * as soon as possible.
231 */ 243 */
232 CommandQueue.prototype.close = function() { 244 CommandQueue.prototype.close = function() {
233 // Free memory used by the undo buffer. 245 // Free memory used by the undo buffer.
234 this.previousImage_.width = 0; 246 this.previousImage_.width = 0;
235 this.previousImage_.height = 0; 247 this.previousImage_.height = 0;
248 this.previousImageAvailable_ = false;
249
250 this.baselineImage_.width = 0;
251 this.baselineImage_.height = 0;
236 }; 252 };
237 253
238 /** 254 /**
239 * Command object encapsulates an operation on an image and a way to visualize 255 * Command object encapsulates an operation on an image and a way to visualize
240 * its result. 256 * its result.
241 * 257 *
242 * @param {string} name Command name. 258 * @param {string} name Command name.
243 * @constructor 259 * @constructor
244 */ 260 */
245 function Command(name) { 261 function Command(name) {
(...skipping 175 matching lines...) Expand 10 before | Expand all | Expand 10 after
421 437
422 function onProgressInvisible(updatedRow, rowCount) { 438 function onProgressInvisible(updatedRow, rowCount) {
423 if (updatedRow == rowCount) { 439 if (updatedRow == rowCount) {
424 callback(result); 440 callback(result);
425 } 441 }
426 } 442 }
427 443
428 filter.applyByStrips(result, srcCanvas, this.filter_, 444 filter.applyByStrips(result, srcCanvas, this.filter_,
429 uiContext.imageView ? onProgressVisible : onProgressInvisible); 445 uiContext.imageView ? onProgressVisible : onProgressInvisible);
430 }; 446 };
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698