diff options
author | kaznacheev@chromium.org <kaznacheev@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-11-09 10:15:53 +0000 |
---|---|---|
committer | kaznacheev@chromium.org <kaznacheev@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-11-09 10:15:53 +0000 |
commit | 08971457ab053f93d8f5da96deec0f6fefc77fa7 (patch) | |
tree | 2d143bde1b7d957ee261d0e36bf5c3fbccf71338 | |
parent | 104d2c434c80c465d88af63119bf53a18079d010 (diff) | |
download | chromium_src-08971457ab053f93d8f5da96deec0f6fefc77fa7.zip chromium_src-08971457ab053f93d8f5da96deec0f6fefc77fa7.tar.gz chromium_src-08971457ab053f93d8f5da96deec0f6fefc77fa7.tar.bz2 |
Merge 106050 - [filebrowser] More intuitive Undo behavior in the Gallery
Also keeping the "Press enter when done" banner until the edit
is committed or cancelled.
BUG=chromium-os:21072,chromium-os:21416
TEST=
Review URL: http://codereview.chromium.org/8313022
TBR=kaznacheev@chromium.org
Review URL: http://codereview.chromium.org/8506006
git-svn-id: svn://svn.chromium.org/chrome/branches/912/src@109215 0039d316-1c4b-4281-b951-d872f2087c98
6 files changed, 131 insertions, 57 deletions
diff --git a/chrome/browser/resources/file_manager/js/image_editor/gallery.css b/chrome/browser/resources/file_manager/js/image_editor/gallery.css index a327676..741f8bb 100644 --- a/chrome/browser/resources/file_manager/js/image_editor/gallery.css +++ b/chrome/browser/resources/file_manager/js/image_editor/gallery.css @@ -24,18 +24,27 @@ body { position: absolute; right: 5px; top: 5px; - height: 20px; - width: 20px; - color: white; cursor: pointer; - opacity: 0.4; z-index: 200; +} + +/* The close icon is in a nested div so that its opacity can be manipulated + independently from its parent (which can be dimmed when the crop frame + overlaps it) */ +.gallery > .close div { + opacity: 0; + width: 20px; + height: 20px; background-image: url(../../images/gallery/close_x.png); background-repeat: no-repeat; background-position: center center; } -.gallery > .close:hover { +.gallery[tools] > .close div { + opacity: 0.4; +} + +.gallery[tools] > .close div:hover { opacity: 0.7; background-color: rgba(81,81,81,1); } @@ -154,12 +163,7 @@ body { } .gallery .arrow-box .arrow { - width: 105px; - height: 193px; - background-repeat: no-repeat; - background-position: center center; pointer-events: none; - opacity: 0; } .gallery .arrow-box .arrow-spacer { @@ -170,18 +174,32 @@ body { .gallery[tools] .arrow[active] { pointer-events: auto; cursor: pointer; +} + +/* The arrow icons are in nested divs so that their opacity can be manipulated + independently from their parent (which can be dimmed when the crop frame + overlaps it) */ +.gallery .arrow div{ + width: 105px; + height: 193px; + background-repeat: no-repeat; + background-position: center center; + opacity: 0; +} + +.gallery[tools] .arrow[active] div{ opacity: 0.17; } -.gallery[tools] .arrow[active]:hover { +.gallery[tools] .arrow[active] div:hover{ opacity: 1; } -.gallery .arrow-box .arrow.left { +.gallery .arrow.left div{ background-image: url(../../images/gallery/arrow_left.png); } -.gallery .arrow-box .arrow.right { +.gallery .arrow.right div{ background-image: url(../../images/gallery/arrow_right.png); } @@ -199,12 +217,12 @@ body { /* The editor marks elements with 'dimmed' attribute to get them out of the way of the crop frame */ -.gallery[tools][editing] > *[dimmed], -.gallery[tools][editing] > *[dimmed] * { +.gallery[tools][editing] *[dimmed], +.gallery[tools][editing] *[dimmed] * { pointer-events: none; } -.gallery[tools][editing] > *[dimmed] { +.gallery[tools][editing] *[dimmed] { opacity: 0.2; } @@ -608,6 +626,11 @@ body { -webkit-box-pack: center; } +.gallery .prompt-wrapper > div.dimmable { + opacity: 1; + -webkit-transition: opacity 220ms ease; +} + .gallery .prompt { font-size: 120%; height: 40px; diff --git a/chrome/browser/resources/file_manager/js/image_editor/gallery.js b/chrome/browser/resources/file_manager/js/image_editor/gallery.js index 82d36a8..c43be05 100644 --- a/chrome/browser/resources/file_manager/js/image_editor/gallery.js +++ b/chrome/browser/resources/file_manager/js/image_editor/gallery.js @@ -68,7 +68,8 @@ Gallery.prototype.initDom_ = function(shareActions) { doc.body.addEventListener('mousemove', window.galleryMouseMove); this.closeButton_ = doc.createElement('div'); - this.closeButton_.className = 'close'; + this.closeButton_.className = 'close tool dimmable'; + this.closeButton_.appendChild(doc.createElement('div')); this.closeButton_.addEventListener('click', this.onClose_.bind(this)); this.container_.appendChild(this.closeButton_); @@ -77,7 +78,7 @@ Gallery.prototype.initDom_ = function(shareActions) { this.container_.appendChild(this.imageContainer_); this.toolbar_ = doc.createElement('div'); - this.toolbar_.className = 'toolbar'; + this.toolbar_.className = 'toolbar tool dimmable'; this.container_.appendChild(this.toolbar_); this.ribbonSpacer_ = doc.createElement('div'); @@ -89,7 +90,8 @@ Gallery.prototype.initDom_ = function(shareActions) { this.container_.appendChild(this.arrowBox_); this.arrowLeft_ = this.document_.createElement('div'); - this.arrowLeft_.className = 'arrow left'; + this.arrowLeft_.className = 'arrow left tool dimmable'; + this.arrowLeft_.appendChild(doc.createElement('div')); this.arrowBox_.appendChild(this.arrowLeft_); this.arrowSpacer_ = this.document_.createElement('div'); @@ -97,7 +99,8 @@ Gallery.prototype.initDom_ = function(shareActions) { this.arrowBox_.appendChild(this.arrowSpacer_); this.arrowRight_ = this.document_.createElement('div'); - this.arrowRight_.className = 'arrow right'; + this.arrowRight_.className = 'arrow right tool dimmable'; + this.arrowRight_.appendChild(doc.createElement('div')); this.arrowBox_.appendChild(this.arrowRight_); this.ribbon_ = new Ribbon(this.ribbonSpacer_, this.onSelect_.bind(this), @@ -320,10 +323,7 @@ Gallery.prototype.onMouseMove_ = function(e) { this.mouseOverTool_ = false; for (var elem = e.target; elem != this.container_; elem = elem.parentNode) { - // TODO(kaznacheev): generalize, perhaps mark tools with a special class. - if (elem == this.toolbar_ || - elem == this.arrowLeft_ || - elem == this.arrowRight_) { + if (elem.classList.contains('tool')) { this.mouseOverTool_ = true; break; } @@ -484,13 +484,13 @@ Ribbon.prototype.redraw = function() { var lastIndex = firstIndex + fullItems - 1; if (this.selectedIndex_ <= firstIndex && firstIndex > 0) { - firstIndex = Math.max(0, this.selectedIndex_ - fullItems + 2); + firstIndex = Math.max(0, this.selectedIndex_ - (fullItems >> 1)); lastIndex = firstIndex + fullItems - 1; } if (this.selectedIndex_ >= lastIndex && lastIndex < this.items_.length - 1) { lastIndex = Math.min(this.items_.length - 1, - this.selectedIndex_ + fullItems - 2); + this.selectedIndex_ + (fullItems >> 1)); firstIndex = lastIndex - fullItems + 1; } diff --git a/chrome/browser/resources/file_manager/js/image_editor/image_adjust.js b/chrome/browser/resources/file_manager/js/image_editor/image_adjust.js index 326e27e..e5d5404 100644 --- a/chrome/browser/resources/file_manager/js/image_editor/image_adjust.js +++ b/chrome/browser/resources/file_manager/js/image_editor/image_adjust.js @@ -28,6 +28,10 @@ ImageEditor.Mode.Adjust.prototype.getCommand = function() { ImageEditor.Mode.Adjust.prototype.cleanUpUI = function() { ImageEditor.Mode.prototype.cleanUpUI.apply(this, arguments); + this.hidePreview(); +}; + +ImageEditor.Mode.Adjust.prototype.hidePreview = function() { if (this.canvas_) { this.canvas_.parentNode.removeChild(this.canvas_); this.canvas_ = null; @@ -39,6 +43,12 @@ ImageEditor.Mode.Adjust.prototype.cleanUpCaches = function() { this.previewImageData_ = null; }; +ImageEditor.Mode.Adjust.prototype.reset = function() { + ImageEditor.Mode.prototype.reset.call(this); + this.hidePreview(); + this.cleanUpCaches(); +}; + ImageEditor.Mode.Adjust.prototype.update = function(options) { ImageEditor.Mode.prototype.update.apply(this, arguments); @@ -103,21 +113,23 @@ ImageEditor.Mode.ColorFilter = function() { ImageEditor.Mode.ColorFilter.prototype = {__proto__: ImageEditor.Mode.Adjust.prototype}; -ImageEditor.Mode.ColorFilter.prototype.setUp = function() { - ImageEditor.Mode.Adjust.prototype.setUp.apply(this, arguments); - this.histogram_ = new ImageEditor.Mode.Histogram( - this.getViewport(), this.getImageView().getCanvas()); +ImageEditor.Mode.ColorFilter.prototype.getHistogram = function() { + if (!this.histogram_) { + this.histogram_ = new ImageEditor.Mode.Histogram( + this.getViewport(), this.getImageView().getCanvas()); + } + return this.histogram_; }; ImageEditor.Mode.ColorFilter.prototype.createFilter = function(options) { var filterFunc = ImageEditor.Mode.Adjust.prototype.createFilter.apply(this, arguments); - this.histogram_.update(filterFunc); + this.getHistogram().update(filterFunc); return filterFunc; }; -ImageEditor.Mode.ColorFilter.prototype.cleanUpUI = function() { - ImageEditor.Mode.Adjust.prototype.cleanUpUI.apply(this, arguments); +ImageEditor.Mode.ColorFilter.prototype.cleanUpCaches = function() { + ImageEditor.Mode.Adjust.prototype.cleanUpCaches.apply(this, arguments); this.histogram_ = null; }; @@ -242,7 +254,7 @@ ImageEditor.Mode.Autofix.prototype.createTools = function(toolbar) { }; ImageEditor.Mode.Autofix.prototype.apply = function() { - this.update({histogram: this.histogram_.getData()}); + this.update({histogram: this.getHistogram().getData()}); }; /** diff --git a/chrome/browser/resources/file_manager/js/image_editor/image_editor.js b/chrome/browser/resources/file_manager/js/image_editor/image_editor.js index 2b98721..ea56b52 100644 --- a/chrome/browser/resources/file_manager/js/image_editor/image_editor.js +++ b/chrome/browser/resources/file_manager/js/image_editor/image_editor.js @@ -126,6 +126,13 @@ ImageEditor.prototype.requestImage = function(callback) { ImageEditor.prototype.undo = function() { if (this.isLocked()) return; + + // First undo click should dismiss the uncommitted modifications. + if (this.currentMode_ && this.currentMode_.isUpdated()) { + this.currentMode_.reset(); + return; + } + this.getPrompt().hide(); this.leaveMode(false); this.commandQueue_.undo(); @@ -243,10 +250,19 @@ ImageEditor.Mode.prototype.update = function(options) { }; ImageEditor.Mode.prototype.markUpdated = function() { - this.editor_.getPrompt().hide(); this.updated_ = true; }; +ImageEditor.Mode.prototype.isUpdated= function() { return this.updated_ }; + +/** + * Resets the mode to a clean state. + */ +ImageEditor.Mode.prototype.reset = function() { + this.editor_.modeToolbar_.reset(); + this.updated_ = false; +}; + /** * One-click editor tool, requires no interaction, just executes the command. * @param {string} name @@ -374,14 +390,21 @@ ImageEditor.prototype.onKeyDown = function(event) { return false; }; -ImageEditor.prototype.hideOverlappingTools = function(rect) { - for (var element = this.rootContainer_.firstElementChild; - element; - element = element.nextElementSibling) { - if (element != this.container_) { - ImageUtil.setAttribute(element, 'dimmed', - rect && rect.intersects(element.getBoundingClientRect())); - } +/** + * Hide the tools that overlap the given rectangular frame. + * + * @param {Rect} frame Hide the tool that overlaps this rect. + * @param {Rect} transparent But do not hide the tool that is completely inside + * this rect. + */ +ImageEditor.prototype.hideOverlappingTools = function(frame, transparent) { + var tools = this.rootContainer_.ownerDocument.querySelectorAll('.dimmable'); + for (var i = 0; i != tools.length; i++) { + var tool = tools[i]; + var toolRect = tool.getBoundingClientRect(); + ImageUtil.setAttribute(tool, 'dimmed', + (frame && frame.intersects(toolRect)) && + !(transparent && transparent.contains(toolRect))); } }; @@ -769,7 +792,12 @@ ImageEditor.Prompt.prototype.show = function(text, timeout) { this.prompt_ = document.createElement('div'); this.prompt_.className = 'prompt'; - this.wrapper_.appendChild(this.prompt_); + + // Create an extra wrapper which opacity can be manipulated separately. + var tool = document.createElement('div'); + tool.className = 'dimmable'; + this.wrapper_.appendChild(tool); + tool.appendChild(this.prompt_); this.prompt_.textContent = this.displayStringFunction_(text); diff --git a/chrome/browser/resources/file_manager/js/image_editor/image_transform.js b/chrome/browser/resources/file_manager/js/image_editor/image_transform.js index 50d2bfb..a133a67 100644 --- a/chrome/browser/resources/file_manager/js/image_editor/image_transform.js +++ b/chrome/browser/resources/file_manager/js/image_editor/image_transform.js @@ -15,8 +15,6 @@ ImageEditor.Mode.Crop.prototype = {__proto__: ImageEditor.Mode.prototype}; ImageEditor.Mode.Crop.prototype.setUp = function() { ImageEditor.Mode.prototype.setUp.apply(this, arguments); - this.createDefaultCrop(); - var container = this.getImageView().container_; var doc = container.ownerDocument; @@ -64,40 +62,45 @@ ImageEditor.Mode.Crop.prototype.setUp = function() { addCropFrame('bottom horizontal'); addCropFrame('right bottom corner'); - this.positionDOM(); + this.createDefaultCrop(); +}; + +ImageEditor.Mode.Crop.prototype.reset = function() { + ImageEditor.Mode.prototype.reset.call(this); + this.createDefaultCrop(); }; ImageEditor.Mode.Crop.prototype.positionDOM = function() { var screenClipped = this.viewport_.getScreenClipped(); + var screenCrop = this.viewport_.imageToScreenRect(this.cropRect_.getRect()); this.editor_.hideOverlappingTools( - this.viewport_.imageToScreenRect(this.cropRect_.getRect())); + screenCrop.inflate(ImageEditor.Mode.Crop.GRAB_RADIUS, + ImageEditor.Mode.Crop.GRAB_RADIUS), + screenCrop.inflate(-ImageEditor.Mode.Crop.GRAB_RADIUS, + -ImageEditor.Mode.Crop.GRAB_RADIUS)); this.domOverlay_.style.left = screenClipped.left + 'px'; this.domOverlay_.style.top = screenClipped.top + 'px'; this.domOverlay_.style.width = screenClipped.width + 'px'; this.domOverlay_.style.height = screenClipped.height + 'px'; - this.shadowLeft_.style.width = - this.viewport_.imageToScreenX(this.cropRect_.getLeft()) - - screenClipped.left + 'px'; + this.shadowLeft_.style.width = screenCrop.left - screenClipped.left + 'px'; - this.shadowTop_.style.height = - this.viewport_.imageToScreenY(this.cropRect_.getTop()) - - screenClipped.top + 'px'; + this.shadowTop_.style.height = screenCrop.top - screenClipped.top + 'px'; this.shadowRight_.style.width = screenClipped.left + screenClipped.width - - this.viewport_.imageToScreenX(this.cropRect_.getRight()) + 'px'; + (screenCrop.left + screenCrop.width) + 'px'; this.shadowBottom_.style.height = screenClipped.top + screenClipped.height - - this.viewport_.imageToScreenY(this.cropRect_.getBottom()) + 'px'; + (screenCrop.top + screenCrop.height) + 'px'; }; ImageEditor.Mode.Crop.prototype.cleanUpUI = function() { ImageEditor.Mode.prototype.cleanUpUI.apply(this, arguments); this.domOverlay_.parentNode.removeChild(this.domOverlay_); this.domOverlay_ = null; - this.editor_.hideOverlappingTools(null); + this.editor_.hideOverlappingTools(); }; ImageEditor.Mode.Crop.GRAB_RADIUS = 6; @@ -114,6 +117,7 @@ ImageEditor.Mode.Crop.prototype.createDefaultCrop = function() { -Math.round(rect.width / 6), -Math.round(rect.height / 6)); this.cropRect_ = new DraggableRect( rect, this.getViewport(), ImageEditor.Mode.Crop.GRAB_RADIUS); + this.positionDOM(); }; ImageEditor.Mode.Crop.prototype.getCursorStyle = function(x, y, mouseDown) { diff --git a/chrome/browser/resources/file_manager/js/image_editor/image_util.js b/chrome/browser/resources/file_manager/js/image_editor/image_util.js index 1f39000..191ac90 100644 --- a/chrome/browser/resources/file_manager/js/image_editor/image_util.js +++ b/chrome/browser/resources/file_manager/js/image_editor/image_util.js @@ -159,6 +159,13 @@ Rect.prototype.intersects = function(rect) { (rect.top + rect.height) > this.top; }; +Rect.prototype.contains = function(rect) { + return (this.left <= rect.left) && + (rect.left + rect.width) <= (this.left + this.width) && + (this.top <= rect.top) && + (rect.top + rect.height) <= (this.top + this.height); +}; + /** * Clamp the rectangle to the bounds by moving it. * Decrease the size only if necessary. |