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

Side by Side Diff: ui/file_manager/gallery/js/image_editor/image_editor.js

Issue 2727353004: Compile Image Editor in gyp v2 (Closed)
Patch Set: . Created 3 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
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 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 * ImageEditor is the top level object that holds together and connects 6 * ImageEditor is the top level object that holds together and connects
7 * everything needed for image editing. 7 * everything needed for image editing.
8 * 8 *
9 * @param {!Viewport} viewport The viewport. 9 * @param {!Viewport} viewport The viewport.
10 * @param {!ImageView} imageView The ImageView containing the images to edit. 10 * @param {!ImageView} imageView The ImageView containing the images to edit.
11 * @param {!ImageEditorPrompt} prompt Prompt instance. 11 * @param {!ImageEditorPrompt} prompt Prompt instance.
12 * @param {!Object} DOMContainers Various DOM containers required for the 12 * @param {!{image: !HTMLElement, root: !HTMLElement, toolbar: !HTMLElement,
13 * mode: !HTMLElement}} DOMContainers Various DOM containers required for the
13 * editor. 14 * editor.
14 * @param {!Array<!ImageEditor.Mode>} modes Available editor modes. 15 * @param {!Array<!ImageEditorMode>} modes Available editor modes.
15 * @param {function(string, ...string)} displayStringFunction String 16 * @param {function(string, ...string)} displayStringFunction String
16 * formatting function. 17 * formatting function.
17 * @constructor 18 * @constructor
18 * @extends {cr.EventTarget} 19 * @extends {cr.EventTarget}
19 * @struct 20 * @struct
20 * 21 *
21 * TODO(yawano): Remove displayStringFunction from arguments. 22 * TODO(yawano): Remove displayStringFunction from arguments.
22 */ 23 */
23 function ImageEditor( 24 function ImageEditor(
24 viewport, imageView, prompt, DOMContainers, modes, displayStringFunction) { 25 viewport, imageView, prompt, DOMContainers, modes, displayStringFunction) {
25 cr.EventTarget.call(this); 26 cr.EventTarget.call(this);
26 27
27 this.rootContainer_ = DOMContainers.root; 28 this.rootContainer_ = DOMContainers.root;
28 this.container_ = DOMContainers.image; 29 this.container_ = DOMContainers.image;
29 this.modes_ = modes; 30 this.modes_ = modes;
30 this.displayStringFunction_ = displayStringFunction; 31 this.displayStringFunction_ = displayStringFunction;
31 32
32 /** 33 /**
33 * @private {ImageEditor.Mode} 34 * @private {ImageEditorMode}
34 */ 35 */
35 this.currentMode_ = null; 36 this.currentMode_ = null;
36 37
37 /** 38 /**
38 * @private {HTMLElement} 39 * @private {HTMLElement}
39 */ 40 */
40 this.currentTool_ = null; 41 this.currentTool_ = null;
41 42
42 /** 43 /**
43 * @private {boolean} 44 * @private {boolean}
44 */ 45 */
45 this.settingUpNextMode_ = false; 46 this.settingUpNextMode_ = false;
46 47
47 ImageUtil.removeChildren(this.container_); 48 ImageUtil.removeChildren(this.container_);
48 49
49 this.viewport_ = viewport; 50 this.viewport_ = viewport;
50 51
51 this.imageView_ = imageView; 52 this.imageView_ = imageView;
52 53
53 this.buffer_ = new ImageBuffer(); 54 this.buffer_ = new ImageBuffer();
54 this.buffer_.addOverlay(this.imageView_); 55 this.buffer_.addOverlay(this.imageView_);
55 56
56 this.panControl_ = new ImageEditor.MouseControl( 57 this.panControl_ = new ImageEditor.MouseControl(
57 this.rootContainer_, this.container_, this.getBuffer()); 58 this.rootContainer_, this.container_, this.getBuffer());
58 this.panControl_.setDoubleTapCallback(this.onDoubleTap_.bind(this)); 59 this.panControl_.setDoubleTapCallback(this.onDoubleTap_.bind(this));
59 60
60 this.mainToolbar_ = new ImageEditor.Toolbar( 61 this.mainToolbar_ =
61 DOMContainers.toolbar, displayStringFunction); 62 new ImageEditorToolbar(DOMContainers.toolbar, displayStringFunction);
62 63
63 this.modeToolbar_ = new ImageEditor.Toolbar( 64 this.modeToolbar_ = new ImageEditorToolbar(
64 DOMContainers.mode, displayStringFunction, 65 DOMContainers.mode, displayStringFunction,
65 this.onOptionsChange.bind(this), true /* done button */); 66 this.onOptionsChange.bind(this), true /* done button */);
66 this.modeToolbar_.addEventListener( 67 this.modeToolbar_.addEventListener(
67 'done-clicked', this.onDoneClicked_.bind(this)); 68 'done-clicked', this.onDoneClicked_.bind(this));
68 this.modeToolbar_.addEventListener( 69 this.modeToolbar_.addEventListener(
69 'cancel-clicked', this.onCancelClicked_.bind(this)); 70 'cancel-clicked', this.onCancelClicked_.bind(this));
70 71
71 this.prompt_ = prompt; 72 this.prompt_ = prompt;
72 73
73 this.commandQueue_ = null; 74 this.commandQueue_ = null;
74 75
75 // ----------------------------------------------------------------- 76 // -----------------------------------------------------------------
76 // Populate the toolbar. 77 // Populate the toolbar.
77 78
78 /** 79 /**
79 * @type {!Array<string>} 80 * @type {!Array<string>}
80 * @private 81 * @private
81 */ 82 */
82 this.actionNames_ = []; 83 this.actionNames_ = [];
83 84
84 this.mainToolbar_.clear(); 85 this.mainToolbar_.clear();
85 86
86 // Create action buttons. 87 // Create action buttons.
87 for (var i = 0; i != this.modes_.length; i++) { 88 for (var i = 0; i != this.modes_.length; i++) {
88 var mode = this.modes_[i]; 89 var mode = this.modes_[i];
89 mode.bind(this, this.createToolButton_(mode.name, mode.title, 90 var button = this.createToolButton_(
90 this.enterMode.bind(this, mode), 91 mode.name, mode.title, this.enterMode.bind(this, mode), mode.instant);
91 mode.instant)); 92 mode.bind(
93 button, this.getBuffer(), this.getViewport(), this.getImageView());
94 this.registerAction_(mode.name);
92 } 95 }
93 96
94 /** 97 /**
95 * @type {!HTMLElement} 98 * @type {!HTMLElement}
96 * @private 99 * @private
97 */ 100 */
98 this.undoButton_ = this.createToolButton_('undo', 'GALLERY_UNDO', 101 this.undoButton_ = this.createToolButton_('undo', 'GALLERY_UNDO',
99 this.undo.bind(this), 102 this.undo.bind(this),
100 true /* instant */); 103 true /* instant */);
101 this.registerAction_('undo'); 104 this.registerAction_('undo');
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
141 * @param {string} title Button title. 144 * @param {string} title Button title.
142 * @param {function(Event)} handler onClick handler. 145 * @param {function(Event)} handler onClick handler.
143 * @param {boolean} isInstant True if this tool (mode) is instant. 146 * @param {boolean} isInstant True if this tool (mode) is instant.
144 * @return {!HTMLElement} A created button. 147 * @return {!HTMLElement} A created button.
145 * @private 148 * @private
146 */ 149 */
147 ImageEditor.prototype.createToolButton_ = function( 150 ImageEditor.prototype.createToolButton_ = function(
148 name, title, handler, isInstant) { 151 name, title, handler, isInstant) {
149 var button = this.mainToolbar_.addButton( 152 var button = this.mainToolbar_.addButton(
150 title, 153 title,
151 isInstant ? ImageEditor.Toolbar.ButtonType.ICON : 154 isInstant ? ImageEditorToolbar.ButtonType.ICON :
152 ImageEditor.Toolbar.ButtonType.ICON_TOGGLEABLE, 155 ImageEditorToolbar.ButtonType.ICON_TOGGLEABLE,
153 handler, 156 handler, name /* opt_className */);
154 name /* opt_className */);
155 return button; 157 return button;
156 }; 158 };
157 159
158 /** 160 /**
159 * @return {boolean} True if no user commands are to be accepted. 161 * @return {boolean} True if no user commands are to be accepted.
160 */ 162 */
161 ImageEditor.prototype.isLocked = function() { 163 ImageEditor.prototype.isLocked = function() {
162 return !this.commandQueue_ || this.commandQueue_.isBusy(); 164 return !this.commandQueue_ || this.commandQueue_.isBusy();
163 }; 165 };
164 166
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
217 219
218 var self = this; 220 var self = this;
219 this.imageView_.load( 221 this.imageView_.load(
220 item, effect, displayCallback, function(loadType, delay, error) { 222 item, effect, displayCallback, function(loadType, delay, error) {
221 self.lockUI(false); 223 self.lockUI(false);
222 224
223 // Always handle an item as original for new session. 225 // Always handle an item as original for new session.
224 item.setAsOriginal(); 226 item.setAsOriginal();
225 227
226 self.commandQueue_ = new CommandQueue( 228 self.commandQueue_ = new CommandQueue(
227 self.container_.ownerDocument, assert(self.imageView_.getImage()), 229 assert(self.container_.ownerDocument),
228 saveFunction); 230 assert(self.imageView_.getImage()), saveFunction);
229 self.commandQueue_.attachUI( 231 self.commandQueue_.attachUI(
230 self.getImageView(), self.getPrompt(), self.filesToast_, 232 self.getImageView(), self.getPrompt(), self.filesToast_,
231 self.updateUndoRedo.bind(self), self.lockUI.bind(self)); 233 self.updateUndoRedo.bind(self), self.lockUI.bind(self));
232 self.updateUndoRedo(); 234 self.updateUndoRedo();
233 loadCallback(loadType, delay, error); 235 loadCallback(loadType, delay, error);
234 }); 236 });
235 }; 237 };
236 238
237 /** 239 /**
238 * Close the current image editing session. 240 * Close the current image editing session.
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
286 288
287 /** 289 /**
288 * Undo the recently executed command. 290 * Undo the recently executed command.
289 */ 291 */
290 ImageEditor.prototype.undo = function() { 292 ImageEditor.prototype.undo = function() {
291 if (this.isLocked()) return; 293 if (this.isLocked()) return;
292 this.recordToolUse('undo'); 294 this.recordToolUse('undo');
293 295
294 // First undo click should dismiss the uncommitted modifications. 296 // First undo click should dismiss the uncommitted modifications.
295 if (this.currentMode_ && this.currentMode_.isUpdated()) { 297 if (this.currentMode_ && this.currentMode_.isUpdated()) {
298 this.modeToolbar_.reset();
296 this.currentMode_.reset(); 299 this.currentMode_.reset();
297 return; 300 return;
298 } 301 }
299 302
300 this.getPrompt().hide(); 303 this.getPrompt().hide();
301 this.leaveModeInternal_(false, false /* not to switch mode */); 304 this.leaveModeInternal_(false, false /* not to switch mode */);
302 this.commandQueue_.undo(); 305 this.commandQueue_.undo();
303 this.updateUndoRedo(); 306 this.updateUndoRedo();
304 this.calculateModeApplicativity_(); 307 this.calculateModeApplicativity_();
305 }; 308 };
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
360 */ 363 */
361 ImageEditor.prototype.onOptionsChange = function(options) { 364 ImageEditor.prototype.onOptionsChange = function(options) {
362 ImageUtil.trace.resetTimer('update'); 365 ImageUtil.trace.resetTimer('update');
363 if (this.currentMode_) { 366 if (this.currentMode_) {
364 this.currentMode_.update(options); 367 this.currentMode_.update(options);
365 } 368 }
366 ImageUtil.trace.reportTimer('update'); 369 ImageUtil.trace.reportTimer('update');
367 }; 370 };
368 371
369 /** 372 /**
370 * ImageEditor.Mode represents a modal state dedicated to a specific operation.
371 * Inherits from ImageBuffer. Overlay to simplify the drawing of mode-specific
372 * tools.
373 *
374 * @param {string} name The mode name.
375 * @param {string} title The mode title.
376 * @constructor
377 * @struct
378 * @extends {ImageBuffer.Overlay}
379 */
380 ImageEditor.Mode = function(name, title) {
381 this.name = name;
382 this.title = title;
383 this.message_ = 'GALLERY_ENTER_WHEN_DONE';
384
385 /**
386 * @type {boolean}
387 */
388 this.implicitCommit = false;
389
390 /**
391 * @type {boolean}
392 */
393 this.instant = false;
394
395 /**
396 * @type {number}
397 */
398 this.paddingTop = 0;
399
400 /**
401 * @type {number}
402 */
403 this.paddingBottom = 0;
404
405 /**
406 * @type {ImageEditor}
407 * @private
408 */
409 this.editor_ = null;
410
411 /**
412 * @type {Viewport}
413 * @private
414 */
415 this.viewport_ = null;
416
417 /**
418 * @type {HTMLElement}
419 * @private
420 */
421 this.button_ = null;
422
423 /**
424 * @type {boolean}
425 * @private
426 */
427 this.updated_ = false;
428
429 /**
430 * @type {ImageView}
431 * @private
432 */
433 this.imageView_ = null;
434 };
435
436 ImageEditor.Mode.prototype = { __proto__: ImageBuffer.Overlay.prototype };
437
438 /**
439 * @return {Viewport} Viewport instance.
440 */
441 ImageEditor.Mode.prototype.getViewport = function() { return this.viewport_; };
442
443 /**
444 * @return {ImageView} ImageView instance.
445 */
446 ImageEditor.Mode.prototype.getImageView = function() {
447 return this.imageView_;
448 };
449
450 /**
451 * @return {string} The mode-specific message to be displayed when entering.
452 */
453 ImageEditor.Mode.prototype.getMessage = function() { return this.message_; };
454
455 /**
456 * @return {boolean} True if the mode is applicable in the current context.
457 */
458 ImageEditor.Mode.prototype.isApplicable = function() { return true; };
459
460 /**
461 * Called once after creating the mode button.
462 *
463 * @param {!ImageEditor} editor The editor instance.
464 * @param {!HTMLElement} button The mode button.
465 */
466
467 ImageEditor.Mode.prototype.bind = function(editor, button) {
468 this.editor_ = editor;
469 this.editor_.registerAction_(this.name);
470 this.button_ = button;
471 this.viewport_ = editor.getViewport();
472 this.imageView_ = editor.getImageView();
473 };
474
475 /**
476 * Called before entering the mode.
477 */
478 ImageEditor.Mode.prototype.setUp = function() {
479 this.editor_.getBuffer().addOverlay(this);
480 this.updated_ = false;
481 };
482
483 /**
484 * Create mode-specific controls here.
485 * @param {!ImageEditor.Toolbar} toolbar The toolbar to populate.
486 */
487 ImageEditor.Mode.prototype.createTools = function(toolbar) {};
488
489 /**
490 * Called before exiting the mode.
491 */
492 ImageEditor.Mode.prototype.cleanUpUI = function() {
493 this.editor_.getBuffer().removeOverlay(this);
494 };
495
496 /**
497 * Called after exiting the mode.
498 */
499 ImageEditor.Mode.prototype.cleanUpCaches = function() {};
500
501 /**
502 * Called when any of the controls changed its value.
503 * @param {Object} options A map of options.
504 */
505 ImageEditor.Mode.prototype.update = function(options) {
506 this.markUpdated();
507 };
508
509 /**
510 * Mark the editor mode as updated.
511 */
512 ImageEditor.Mode.prototype.markUpdated = function() {
513 this.updated_ = true;
514 };
515
516 /**
517 * @return {boolean} True if the mode controls changed.
518 */
519 ImageEditor.Mode.prototype.isUpdated = function() { return this.updated_; };
520
521 /**
522 * @return {boolean} True if a key event should be consumed by the mode.
523 */
524 ImageEditor.Mode.prototype.isConsumingKeyEvents = function() { return false; };
525
526 /**
527 * Resets the mode to a clean state.
528 */
529 ImageEditor.Mode.prototype.reset = function() {
530 this.editor_.modeToolbar_.reset();
531 this.updated_ = false;
532 };
533
534 /**
535 * @return {Command} Command.
536 */
537 ImageEditor.Mode.prototype.getCommand = function() {
538 return null;
539 };
540
541 /**
542 * One-click editor tool, requires no interaction, just executes the command.
543 *
544 * @param {string} name The mode name.
545 * @param {string} title The mode title.
546 * @param {!Command} command The command to execute on click.
547 * @constructor
548 * @extends {ImageEditor.Mode}
549 * @struct
550 */
551 ImageEditor.Mode.OneClick = function(name, title, command) {
552 ImageEditor.Mode.call(this, name, title);
553 this.instant = true;
554 this.command_ = command;
555 };
556
557 ImageEditor.Mode.OneClick.prototype = {__proto__: ImageEditor.Mode.prototype};
558
559 /**
560 * @override
561 */
562 ImageEditor.Mode.OneClick.prototype.getCommand = function() {
563 return this.command_;
564 };
565
566 /**
567 * Register the action name. Required for metrics reporting. 373 * Register the action name. Required for metrics reporting.
568 * @param {string} name Button name. 374 * @param {string} name Button name.
569 * @private 375 * @private
570 */ 376 */
571 ImageEditor.prototype.registerAction_ = function(name) { 377 ImageEditor.prototype.registerAction_ = function(name) {
572 this.actionNames_.push(name); 378 this.actionNames_.push(name);
573 }; 379 };
574 380
575 /** 381 /**
576 * @return {ImageEditor.Mode} The current mode. 382 * @return {ImageEditorMode} The current mode.
577 */ 383 */
578 ImageEditor.prototype.getMode = function() { return this.currentMode_; }; 384 ImageEditor.prototype.getMode = function() { return this.currentMode_; };
579 385
580 /** 386 /**
581 * The user clicked on the mode button. 387 * The user clicked on the mode button.
582 * 388 *
583 * @param {!ImageEditor.Mode} mode The new mode. 389 * @param {!ImageEditorMode} mode The new mode.
584 */ 390 */
585 ImageEditor.prototype.enterMode = function(mode) { 391 ImageEditor.prototype.enterMode = function(mode) {
586 if (this.isLocked()) return; 392 if (this.isLocked()) return;
587 393
588 if (this.currentMode_ === mode) { 394 if (this.currentMode_ === mode) {
589 // Currently active editor tool clicked, commit if modified. 395 // Currently active editor tool clicked, commit if modified.
590 this.leaveModeInternal_( 396 this.leaveModeInternal_(
591 this.currentMode_.updated_, false /* not to switch mode */); 397 this.currentMode_.updated_, false /* not to switch mode */);
592 return; 398 return;
593 } 399 }
(...skipping 12 matching lines...) Expand all
606 // with the mode set up. 412 // with the mode set up.
607 this.commandQueue_.executeWhenReady(function() { 413 this.commandQueue_.executeWhenReady(function() {
608 this.setUpMode_(mode); 414 this.setUpMode_(mode);
609 this.settingUpNextMode_ = false; 415 this.settingUpNextMode_ = false;
610 }.bind(this)); 416 }.bind(this));
611 }; 417 };
612 418
613 /** 419 /**
614 * Set up the new editing mode. 420 * Set up the new editing mode.
615 * 421 *
616 * @param {!ImageEditor.Mode} mode The mode. 422 * @param {!ImageEditorMode} mode The mode.
617 * @private 423 * @private
618 */ 424 */
619 ImageEditor.prototype.setUpMode_ = function(mode) { 425 ImageEditor.prototype.setUpMode_ = function(mode) {
620 this.currentTool_ = mode.button_; 426 this.currentTool_ = mode.button_;
621 this.currentMode_ = mode; 427 this.currentMode_ = mode;
622 this.rootContainer_.setAttribute('editor-mode', mode.name); 428 this.rootContainer_.setAttribute('editor-mode', mode.name);
623 429
624 // Activate toggle ripple if button is toggleable. 430 // Activate toggle ripple if button is toggleable.
625 var filesToggleRipple = 431 var filesToggleRipple =
626 this.currentTool_.querySelector('files-toggle-ripple'); 432 this.currentTool_.querySelector('files-toggle-ripple');
627 if (filesToggleRipple) { 433 if (filesToggleRipple) {
628 // Current mode must NOT be instant for toggleable button. 434 // Current mode must NOT be instant for toggleable button.
629 assert(!this.currentMode_.instant); 435 assert(!this.currentMode_.instant);
630 filesToggleRipple.activated = true; 436 filesToggleRipple.activated = true;
631 } 437 }
632 438
633 // Scale the screen so that it doesn't overlap the toolbars. We should scale 439 // Scale the screen so that it doesn't overlap the toolbars. We should scale
634 // the screen before setup of current mode is called to make the current mode 440 // the screen before setup of current mode is called to make the current mode
635 // able to set up with new screen size. 441 // able to set up with new screen size.
636 if (!this.currentMode_.instant) { 442 if (!this.currentMode_.instant) {
637 this.getViewport().setScreenTop( 443 this.getViewport().setScreenTop(
638 ImageEditor.Toolbar.HEIGHT + mode.paddingTop); 444 ImageEditorToolbar.HEIGHT + mode.paddingTop);
639 this.getViewport().setScreenBottom( 445 this.getViewport().setScreenBottom(
640 ImageEditor.Toolbar.HEIGHT * 2 + mode.paddingBottom); 446 ImageEditorToolbar.HEIGHT * 2 + mode.paddingBottom);
641 this.getImageView().applyViewportChange(); 447 this.getImageView().applyViewportChange();
642 } 448 }
643 449
644 this.currentMode_.setUp(); 450 this.currentMode_.setUp();
645 451
646 this.calculateModeApplicativity_(); 452 this.calculateModeApplicativity_();
647 if (this.currentMode_.instant) { // Instant tool. 453 if (this.currentMode_.instant) { // Instant tool.
648 this.leaveModeInternal_(true, false /* not to switch mode */); 454 this.leaveModeInternal_(true, false /* not to switch mode */);
649 return; 455 return;
650 } 456 }
(...skipping 30 matching lines...) Expand all
681 * @param {boolean} leaveToSwitchMode True if it leaves to change mode. 487 * @param {boolean} leaveToSwitchMode True if it leaves to change mode.
682 * @private 488 * @private
683 */ 489 */
684 ImageEditor.prototype.leaveModeInternal_ = function(commit, leaveToSwitchMode) { 490 ImageEditor.prototype.leaveModeInternal_ = function(commit, leaveToSwitchMode) {
685 if (!this.currentMode_) 491 if (!this.currentMode_)
686 return; 492 return;
687 493
688 // If the current mode is 'Resize', and commit is required, 494 // If the current mode is 'Resize', and commit is required,
689 // leaving mode should be stopped when an input value is not valid. 495 // leaving mode should be stopped when an input value is not valid.
690 if(commit && this.currentMode_.name === 'resize') { 496 if(commit && this.currentMode_.name === 'resize') {
691 var resizeMode = /** @type {!ImageEditor.Mode.Resize} */ 497 var resizeMode = /** @type {!ImageEditorMode.Resize} */
692 (this.currentMode_); 498 (this.currentMode_);
693 if(!resizeMode.isInputValid()) { 499 if(!resizeMode.isInputValid()) {
694 resizeMode.showAlertDialog(); 500 resizeMode.showAlertDialog();
695 return; 501 return;
696 } 502 }
697 } 503 }
698 504
699 this.modeToolbar_.show(false); 505 this.modeToolbar_.show(false);
700 this.rootContainer_.removeAttribute('editor-mode'); 506 this.rootContainer_.removeAttribute('editor-mode');
701 507
702 // If it leaves to switch mode, do not restore screen size since the next mode 508 // If it leaves to switch mode, do not restore screen size since the next mode
703 // might change screen size. We should avoid to show intermediate animation 509 // might change screen size. We should avoid to show intermediate animation
704 // which tries to restore screen size. 510 // which tries to restore screen size.
705 if (!leaveToSwitchMode) { 511 if (!leaveToSwitchMode) {
706 this.getViewport().setScreenTop(ImageEditor.Toolbar.HEIGHT); 512 this.getViewport().setScreenTop(ImageEditorToolbar.HEIGHT);
707 this.getViewport().setScreenBottom(ImageEditor.Toolbar.HEIGHT); 513 this.getViewport().setScreenBottom(ImageEditorToolbar.HEIGHT);
708 this.getImageView().applyViewportChange(); 514 this.getImageView().applyViewportChange();
709 } 515 }
710 516
711 this.currentMode_.cleanUpUI(); 517 this.currentMode_.cleanUpUI();
712 518
713 if (commit) { 519 if (commit) {
714 var self = this; 520 var self = this;
715 var command = this.currentMode_.getCommand(); 521 var command = this.currentMode_.getCommand();
716 if (command) { // Could be null if the user did not do anything. 522 if (command) { // Could be null if the user did not do anything.
717 this.commandQueue_.execute(command); 523 this.commandQueue_.execute(command);
(...skipping 394 matching lines...) Expand 10 before | Expand all | Expand 10 after
1112 * @param {!Object} position An object holding x and y properties. 918 * @param {!Object} position An object holding x and y properties.
1113 * @private 919 * @private
1114 */ 920 */
1115 ImageEditor.MouseControl.prototype.updateCursor_ = function(position) { 921 ImageEditor.MouseControl.prototype.updateCursor_ = function(position) {
1116 var oldCursor = this.container_.getAttribute('cursor'); 922 var oldCursor = this.container_.getAttribute('cursor');
1117 var newCursor = this.buffer_.getCursorStyle( 923 var newCursor = this.buffer_.getCursorStyle(
1118 position.x, position.y, !!this.dragHandler_); 924 position.x, position.y, !!this.dragHandler_);
1119 if (newCursor != oldCursor) // Avoid flicker. 925 if (newCursor != oldCursor) // Avoid flicker.
1120 this.container_.setAttribute('cursor', newCursor); 926 this.container_.setAttribute('cursor', newCursor);
1121 }; 927 };
1122
1123 /**
1124 * A toolbar for the ImageEditor.
1125 * @param {!HTMLElement} parent The parent element.
1126 * @param {function(string)} displayStringFunction A string formatting function.
1127 * @param {function(Object)=} opt_updateCallback The callback called when
1128 * controls change.
1129 * @param {boolean=} opt_showActionButtons True to show action buttons.
1130 * @constructor
1131 * @extends {cr.EventTarget}
1132 * @struct
1133 */
1134 ImageEditor.Toolbar = function(
1135 parent, displayStringFunction, opt_updateCallback, opt_showActionButtons) {
1136 this.wrapper_ = parent;
1137 this.displayStringFunction_ = displayStringFunction;
1138
1139 /**
1140 * @type {?function(Object)}
1141 * @private
1142 */
1143 this.updateCallback_ = opt_updateCallback || null;
1144
1145 /**
1146 * @private {!HTMLElement}
1147 */
1148 this.container_ = /** @type {!HTMLElement} */ (document.createElement('div'));
1149 this.container_.classList.add('container');
1150 this.wrapper_.appendChild(this.container_);
1151
1152 // Create action buttons.
1153 if (opt_showActionButtons) {
1154 var actionButtonsLayer = document.createElement('div');
1155 actionButtonsLayer.classList.add('action-buttons');
1156
1157 this.cancelButton_ = ImageEditor.Toolbar.createButton_(
1158 'GALLERY_CANCEL_LABEL', ImageEditor.Toolbar.ButtonType.LABEL_UPPER_CASE,
1159 this.onCancelClicked_.bind(this), 'cancel');
1160 actionButtonsLayer.appendChild(this.cancelButton_);
1161
1162 this.doneButton_ = ImageEditor.Toolbar.createButton_(
1163 'GALLERY_DONE', ImageEditor.Toolbar.ButtonType.LABEL_UPPER_CASE,
1164 this.onDoneClicked_.bind(this), 'done');
1165 actionButtonsLayer.appendChild(this.doneButton_);
1166
1167 this.wrapper_.appendChild(actionButtonsLayer);
1168 }
1169 };
1170
1171 ImageEditor.Toolbar.prototype.__proto__ = cr.EventTarget.prototype;
1172
1173 /**
1174 * Height of the toolbar.
1175 * @const {number}
1176 */
1177 ImageEditor.Toolbar.HEIGHT = 48; // px
1178
1179 /**
1180 * Handles click event of done button.
1181 * @private
1182 */
1183 ImageEditor.Toolbar.prototype.onDoneClicked_ = function() {
1184 this.doneButton_.querySelector('paper-ripple').simulatedRipple();
1185
1186 var event = new Event('done-clicked');
1187 this.dispatchEvent(event);
1188 };
1189
1190 /**
1191 * Handles click event of cancel button.
1192 * @private
1193 */
1194 ImageEditor.Toolbar.prototype.onCancelClicked_ = function() {
1195 this.cancelButton_.querySelector('paper-ripple').simulatedRipple();
1196
1197 var event = new Event('cancel-clicked');
1198 this.dispatchEvent(event);
1199 };
1200
1201 /**
1202 * Returns the parent element.
1203 * @return {!HTMLElement}
1204 */
1205 ImageEditor.Toolbar.prototype.getElement = function() {
1206 return this.container_;
1207 };
1208
1209 /**
1210 * Clear the toolbar.
1211 */
1212 ImageEditor.Toolbar.prototype.clear = function() {
1213 ImageUtil.removeChildren(this.container_);
1214 };
1215
1216 /**
1217 * Add a control.
1218 * @param {!HTMLElement} element The control to add.
1219 * @return {!HTMLElement} The added element.
1220 */
1221 ImageEditor.Toolbar.prototype.add = function(element) {
1222 this.container_.appendChild(element);
1223 return element;
1224 };
1225
1226 /**
1227 * Button type.
1228 * @enum {string}
1229 */
1230 ImageEditor.Toolbar.ButtonType = {
1231 ICON: 'icon',
1232 ICON_TOGGLEABLE: 'icon_toggleable',
1233 LABEL: 'label',
1234 LABEL_UPPER_CASE: 'label_upper_case'
1235 };
1236
1237 /**
1238 * Create a button.
1239 *
1240 * @param {string} title String ID of button title.
1241 * @param {ImageEditor.Toolbar.ButtonType} type Button type.
1242 * @param {function(Event)} handler onClick handler.
1243 * @param {string=} opt_class Extra class name.
1244 * @return {!HTMLElement} The created button.
1245 * @private
1246 */
1247 ImageEditor.Toolbar.createButton_ = function(
1248 title, type, handler, opt_class) {
1249 var button = /** @type {!HTMLElement} */ (document.createElement('button'));
1250 if (opt_class)
1251 button.classList.add(opt_class);
1252 button.classList.add('edit-toolbar');
1253
1254 if (type === ImageEditor.Toolbar.ButtonType.ICON ||
1255 type === ImageEditor.Toolbar.ButtonType.ICON_TOGGLEABLE) {
1256 var icon = document.createElement('div');
1257 icon.classList.add('icon');
1258
1259 // Show tooltip for icon button.
1260 assertInstanceof(document.querySelector('files-tooltip'), FilesTooltip)
1261 .addTarget(button);
1262
1263 button.appendChild(icon);
1264
1265 if (type === ImageEditor.Toolbar.ButtonType.ICON) {
1266 var filesRipple = document.createElement('files-ripple');
1267 button.appendChild(filesRipple);
1268 } else {
1269 var filesToggleRipple = document.createElement('files-toggle-ripple');
1270 button.appendChild(filesToggleRipple);
1271 }
1272 } else if (type === ImageEditor.Toolbar.ButtonType.LABEL ||
1273 type === ImageEditor.Toolbar.ButtonType.LABEL_UPPER_CASE) {
1274 var label = document.createElement('span');
1275 label.classList.add('label');
1276 label.textContent =
1277 type === ImageEditor.Toolbar.ButtonType.LABEL_UPPER_CASE ?
1278 strf(title).toLocaleUpperCase() : strf(title);
1279
1280 button.appendChild(label);
1281
1282 var paperRipple = document.createElement('paper-ripple');
1283 button.appendChild(paperRipple);
1284 } else {
1285 assertNotReached();
1286 }
1287
1288 button.label = strf(title);
1289 button.setAttribute('aria-label', strf(title));
1290
1291 GalleryUtil.decorateMouseFocusHandling(button);
1292
1293 button.addEventListener('click', handler, false);
1294 button.addEventListener('keydown', function(event) {
1295 // Stop propagation of Enter key event to prevent it from being captured by
1296 // image editor.
1297 if (event.key === 'Enter')
1298 event.stopPropagation();
1299 });
1300
1301 return button;
1302 };
1303
1304 /**
1305 * Add a button.
1306 *
1307 * @param {string} title Button title.
1308 * @param {ImageEditor.Toolbar.ButtonType} type Button type.
1309 * @param {function(Event)} handler onClick handler.
1310 * @param {string=} opt_class Extra class name.
1311 * @return {!HTMLElement} The added button.
1312 */
1313 ImageEditor.Toolbar.prototype.addButton = function(
1314 title, type, handler, opt_class) {
1315 var button = ImageEditor.Toolbar.createButton_(
1316 title, type, handler, opt_class);
1317 this.add(button);
1318 return button;
1319 };
1320
1321 /**
1322 * Add a input field.
1323 *
1324 * @param {string} name Input name
1325 * @param {string} title Input title
1326 * @param {function(Event)} handler onInput and onChange handler
1327 * @param {string|number} value Default value
1328 * @param {string=} opt_unit Unit for an input field
1329 * @return {!HTMLElement} Input Element
1330 */
1331 ImageEditor.Toolbar.prototype.addInput = function(
1332 name, title, handler, value, opt_unit) {
1333
1334 var input = /** @type {!HTMLElement} */ (document.createElement('div'));
1335 input.classList.add('input', name);
1336
1337 var text = document.createElement('paper-input');
1338 text.setAttribute('label', strf(title));
1339 text.classList.add('text', name);
1340 text.value = value;
1341
1342 // We should listen to not only 'change' event, but also 'input' because we
1343 // want to update values as soon as the user types characters.
1344 text.addEventListener('input', handler, false);
1345 text.addEventListener('change', handler, false);
1346 input.appendChild(text);
1347
1348 if(opt_unit) {
1349 var unit_label = document.createElement('span');
1350 unit_label.textContent = opt_unit;
1351 unit_label.classList.add('unit_label');
1352 input.appendChild(unit_label);
1353 }
1354
1355 input.name = name;
1356 input.getValue = function(text) {
1357 return text.value;
1358 }.bind(this, text);
1359 input.setValue = function(text, value) {
1360 text.value = value;
1361 }.bind(this, text);
1362
1363 this.add(input);
1364
1365 return input;
1366 };
1367
1368 /**
1369 * Add a range control (scalar value picker).
1370 *
1371 * @param {string} name An option name.
1372 * @param {string} title An option title.
1373 * @param {number} min Min value of the option.
1374 * @param {number} value Default value of the option.
1375 * @param {number} max Max value of the options.
1376 * @param {number=} opt_scale A number to multiply by when setting
1377 * min/value/max in DOM.
1378 * @param {boolean=} opt_showNumeric True if numeric value should be displayed.
1379 * @return {!HTMLElement} Range element.
1380 */
1381 ImageEditor.Toolbar.prototype.addRange = function(
1382 name, title, min, value, max, opt_scale, opt_showNumeric) {
1383 var range = /** @type {!HTMLElement} */ (document.createElement('div'));
1384 range.classList.add('range', name);
1385
1386 var icon = document.createElement('icon');
1387 icon.classList.add('icon');
1388 range.appendChild(icon);
1389
1390 var label = document.createElement('span');
1391 label.textContent = strf(title);
1392 label.classList.add('label');
1393 range.appendChild(label);
1394
1395 var scale = opt_scale || 1;
1396 var slider = document.createElement('paper-slider');
1397 slider.min = Math.ceil(min * scale);
1398 slider.max = Math.floor(max * scale);
1399 slider.value = value * scale;
1400 slider.addEventListener('change', function(event) {
1401 if (this.updateCallback_)
1402 this.updateCallback_(this.getOptions());
1403 }.bind(this));
1404 range.appendChild(slider);
1405
1406 range.name = name;
1407 range.getValue = function(slider, scale) {
1408 return slider.value / scale;
1409 }.bind(this, slider, scale);
1410
1411 // Swallow the left and right keys, so they are not handled by other
1412 // listeners.
1413 range.addEventListener('keydown', function(e) {
1414 if (e.key === 'ArrowLeft' || e.key === 'ArrowRight')
1415 e.stopPropagation();
1416 });
1417
1418 this.add(range);
1419
1420 return range;
1421 };
1422
1423 /**
1424 * @return {!Object} options A map of options.
1425 */
1426 ImageEditor.Toolbar.prototype.getOptions = function() {
1427 var values = {};
1428
1429 for (var child = this.container_.firstChild;
1430 child;
1431 child = child.nextSibling) {
1432 if (child.name)
1433 values[child.name] = child.getValue();
1434 }
1435
1436 return values;
1437 };
1438
1439 /**
1440 * Reset the toolbar.
1441 */
1442 ImageEditor.Toolbar.prototype.reset = function() {
1443 for (var child = this.wrapper_.firstChild; child; child = child.nextSibling) {
1444 if (child.reset) child.reset();
1445 }
1446 };
1447
1448 /**
1449 * Show/hide the toolbar.
1450 * @param {boolean} on True if show.
1451 */
1452 ImageEditor.Toolbar.prototype.show = function(on) {
1453 if (!this.wrapper_.firstChild)
1454 return; // Do not show empty toolbar;
1455
1456 this.wrapper_.hidden = !on;
1457
1458 // Focus the first input on the toolbar.
1459 if (on) {
1460 var input = this.container_.querySelector(
1461 'button, paper-button, input, paper-input, paper-slider');
1462 if (input)
1463 input.focus();
1464 }
1465 };
OLDNEW
« no previous file with comments | « ui/file_manager/gallery/js/image_editor/image_adjust.js ('k') | ui/file_manager/gallery/js/image_editor/image_editor_mode.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698