summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorkaznacheev@chromium.org <kaznacheev@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-11-09 10:15:53 +0000
committerkaznacheev@chromium.org <kaznacheev@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-11-09 10:15:53 +0000
commit08971457ab053f93d8f5da96deec0f6fefc77fa7 (patch)
tree2d143bde1b7d957ee261d0e36bf5c3fbccf71338
parent104d2c434c80c465d88af63119bf53a18079d010 (diff)
downloadchromium_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
-rw-r--r--chrome/browser/resources/file_manager/js/image_editor/gallery.css55
-rw-r--r--chrome/browser/resources/file_manager/js/image_editor/gallery.js20
-rw-r--r--chrome/browser/resources/file_manager/js/image_editor/image_adjust.js28
-rw-r--r--chrome/browser/resources/file_manager/js/image_editor/image_editor.js48
-rw-r--r--chrome/browser/resources/file_manager/js/image_editor/image_transform.js30
-rw-r--r--chrome/browser/resources/file_manager/js/image_editor/image_util.js7
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.