diff options
author | estade@chromium.org <estade@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-05-09 22:16:22 +0000 |
---|---|---|
committer | estade@chromium.org <estade@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-05-09 22:16:22 +0000 |
commit | 6231de27788e6dbc5f88956e8c0d34918d57033c (patch) | |
tree | b85cd131667a469e78d80af8f5c5b5fd25610910 /chrome | |
parent | 062c625092d733875cc37706769b60c636f314ec (diff) | |
download | chromium_src-6231de27788e6dbc5f88956e8c0d34918d57033c.zip chromium_src-6231de27788e6dbc5f88956e8c0d34918d57033c.tar.gz chromium_src-6231de27788e6dbc5f88956e8c0d34918d57033c.tar.bz2 |
ntp4: Rework dragging to allow going between pages.
This patch is mostly concerned with drag appearance; since the backend isn't hooked up yet there's no updating of the actual model.
Also:
- get rid of excess doppleganger tiles
- switch pages on a delay when hovering over navigation dots with a drag
BUG=none
TEST=manual
Review URL: http://codereview.chromium.org/6932030
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@84700 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome')
-rw-r--r-- | chrome/browser/resources/ntp4/apps_page.css | 1 | ||||
-rw-r--r-- | chrome/browser/resources/ntp4/most_visited_page.js | 5 | ||||
-rw-r--r-- | chrome/browser/resources/ntp4/new_tab.css | 1 | ||||
-rw-r--r-- | chrome/browser/resources/ntp4/new_tab.js | 11 | ||||
-rw-r--r-- | chrome/browser/resources/ntp4/new_tab_theme.css | 31 | ||||
-rw-r--r-- | chrome/browser/resources/ntp4/tile_page.css | 8 | ||||
-rw-r--r-- | chrome/browser/resources/ntp4/tile_page.js | 145 |
7 files changed, 146 insertions, 56 deletions
diff --git a/chrome/browser/resources/ntp4/apps_page.css b/chrome/browser/resources/ntp4/apps_page.css index aa0c806..e3e3a8c 100644 --- a/chrome/browser/resources/ntp4/apps_page.css +++ b/chrome/browser/resources/ntp4/apps_page.css @@ -5,6 +5,7 @@ .app { position: absolute; + text-align: center; } .app span { diff --git a/chrome/browser/resources/ntp4/most_visited_page.js b/chrome/browser/resources/ntp4/most_visited_page.js index a01281a..838f9fa 100644 --- a/chrome/browser/resources/ntp4/most_visited_page.js +++ b/chrome/browser/resources/ntp4/most_visited_page.js @@ -273,6 +273,11 @@ cr.define('ntp4', function() { }, /** @inheritDoc */ + acceptOutsideDrags: function() { + return false; + }, + + /** @inheritDoc */ heightForWidth: heightForWidth, }; diff --git a/chrome/browser/resources/ntp4/new_tab.css b/chrome/browser/resources/ntp4/new_tab.css index 491114a..d649743 100644 --- a/chrome/browser/resources/ntp4/new_tab.css +++ b/chrome/browser/resources/ntp4/new_tab.css @@ -9,6 +9,7 @@ html { /* It's necessary to put this here instead of in body in order to get the background-size of 100% to work properly */ height: 100%; + overflow: hidden; } body { diff --git a/chrome/browser/resources/ntp4/new_tab.js b/chrome/browser/resources/ntp4/new_tab.js index c9dc65b..97bcfae 100644 --- a/chrome/browser/resources/ntp4/new_tab.js +++ b/chrome/browser/resources/ntp4/new_tab.js @@ -352,6 +352,13 @@ cr.define('ntp4', function() { dotList.appendChild(newDot); page.navigationDot = newDot; + newDot.showPage = function() { + cardSlider.selectCard(dotCount, true); + }; + function switchPage(e) { + newDot.showPage(); + e.stopPropagation(); + } // Add click handler to the dot to change the page. // TODO(rbyers): Perhaps this should be TouchHandler.START_EVENT_ (so we // don't rely on synthesized click events, and the change takes effect @@ -359,10 +366,6 @@ cr.define('ntp4', function() { // region outside the border, and a 10px box is too small to require touch // events to fall inside of. We could get around this by adding a box around // the dot for accepting the touch events. - function switchPage(e) { - cardSlider.selectCard(dotCount, true); - e.stopPropagation(); - } newDot.addEventListener('click', switchPage); // Change pages whenever an app is dragged over a dot. diff --git a/chrome/browser/resources/ntp4/new_tab_theme.css b/chrome/browser/resources/ntp4/new_tab_theme.css index c6935d7..bfa2c02 100644 --- a/chrome/browser/resources/ntp4/new_tab_theme.css +++ b/chrome/browser/resources/ntp4/new_tab_theme.css @@ -8,33 +8,12 @@ html, background-repeat: $5; } -html[bookmarkbarattached='true'], -html[bookmarkbarattached='true'] .section > h2 span, -html[bookmarkbarattached='true'] #most-visited-settings { - background-position: $4; -} - body { color: $8; /* COLOR_NTP_TEXT */ height: 100%; overflow: auto; } -/* TODO(aa): Is this still in use? The styling may be incorrect with M7 NTP - rework. */ -#notification.first-run { - background-color: $$1; /* COLOR_NTP_SECTION */ - border-color: $$2; /* COLOR_NTP_SECTION_BORDER */ -} - -#notification.first-run .link { - color: $$5; /* COLOR_NTP_LINK_UNDERLINE */ -} - -#notification.first-run .link-color { - color: $9; /* COLOR_NTP_LINK */ -} - #attribution { color: $9; /* COLOR_NTP_LINK */ } @@ -81,7 +60,7 @@ body { border-color-top: $$9; /* COLOR_NTP_SECTION_HEADER_RULE */ } -.app a { +.app span { color: $8; /* COLOR_NTP_TEXT */ } @@ -91,14 +70,6 @@ body { background-color: $$1; /* COLOR_NTP_SECTION */; } -#apps-promo-hide { - color: $9; /* COLOR_NTP_LINK */ -} - -#apps-promo-text2 { - color: $$$3; /* COLOR_NTP_TEXT_LIGHT */ -} - /* Footer *********************************************************************/ #footer-border { diff --git a/chrome/browser/resources/ntp4/tile_page.css b/chrome/browser/resources/ntp4/tile_page.css index 948a053..0871b66 100644 --- a/chrome/browser/resources/ntp4/tile_page.css +++ b/chrome/browser/resources/ntp4/tile_page.css @@ -37,8 +37,12 @@ } .tile.dragging { + opacity: 0; +} + +.tile.drag-representation { + pointer-events: none; z-index: 10; - -webkit-transition-duration: 0 !important; } .drag-target { @@ -46,6 +50,6 @@ } .animating-tile-page .tile, -.tile.placing { +.tile.drag-representation.placing { -webkit-transition: left 200ms, top 200ms; } diff --git a/chrome/browser/resources/ntp4/tile_page.js b/chrome/browser/resources/ntp4/tile_page.js index e1dcd43..4499684 100644 --- a/chrome/browser/resources/ntp4/tile_page.js +++ b/chrome/browser/resources/ntp4/tile_page.js @@ -32,13 +32,17 @@ cr.define('ntp4', function() { this.addEventListener('drag', this.onDragMove_); this.addEventListener('dragend', this.onDragEnd_); - this.addEventListener('webkitTransitionEnd', this.onTransitionEnd_); + this.eventTracker = new EventTracker(); }, get index() { return Array.prototype.indexOf.call(this.parentNode.children, this); }, + get tilePage() { + return findAncestorByClass(this, 'tile-page'); + }, + /** * Position the tile at |x, y|, and store this as the grid location, i.e. * where the tile 'belongs' when it's not being dragged. @@ -73,10 +77,20 @@ cr.define('ntp4', function() { // TODO(estade): fill this in. e.dataTransfer.setData('text/plain', 'foo'); - this.startScreenX = e.screenX; - this.startScreenY = e.screenY; + // The drag clone is the node we use as a representation during the drag. + // It's attached to the top level document element so that it floats above + // image masks. + this.dragClone = this.cloneNode(true); + this.dragClone.classList.add('drag-representation'); + this.ownerDocument.documentElement.appendChild(this.dragClone); + this.eventTracker.add(this.dragClone, 'webkitTransitionEnd', + this.onDragCloneTransitionEnd_.bind(this)); this.classList.add('dragging'); + this.dragOffsetX = e.pageX - this.offsetLeft; + this.dragOffsetY = e.pageY - this.offsetTop - this.parentNode.offsetTop; + + this.onDragMove_(e); }, /** @@ -85,9 +99,8 @@ cr.define('ntp4', function() { * @private */ onDragMove_: function(e) { - var diffX = e.screenX - this.startScreenX; - var diffY = e.screenY - this.startScreenY; - this.moveTo(this.gridX + diffX, this.gridY + diffY); + this.dragClone.style.left = (e.pageX - this.dragOffsetX) + 'px'; + this.dragClone.style.top = (e.pageY - this.dragOffsetY) + 'px'; }, /** @@ -97,10 +110,18 @@ cr.define('ntp4', function() { */ onDragEnd_: function(e) { TilePage.currentlyDraggingTile = null; - this.classList.remove('dragging'); - // This class is required for the tile to animate to its final position. - this.classList.add('placing'); this.tilePage.positionTile_(this.index); + + this.dragClone.classList.add('placing'); + // The tile's contents may have moved following the respositioning; adjust + // for that. + var contentDiffX = this.dragClone.firstChild.offsetLeft - + this.firstChild.offsetLeft; + var contentDiffY = this.dragClone.firstChild.offsetTop - + this.firstChild.offsetTop; + this.dragClone.style.left = (this.gridX - contentDiffX) + 'px'; + this.dragClone.style.top = + (this.gridY + this.parentNode.offsetTop - contentDiffY) + 'px'; }, /** @@ -141,13 +162,25 @@ cr.define('ntp4', function() { }, /** - * When a positioning transition ends, remove the 'placing' class so further - * positioning won't necessarily be animated. + * Returns status of doppleganger. + * @return {boolean} True if there is a doppleganger showing for |this|. + */ + hasDoppleganger: function() { + return !!this.doppleganger_; + }, + + /** + * Called when the drag representation node is done migrating to its final + * resting spot. * @param {Event} e The transition end event. */ - onTransitionEnd_: function(e) { - if (e.propertyName == 'top' || e.propertyName == 'left') - this.classList.remove('placing'); + onDragCloneTransitionEnd_: function(e) { + var clone = this.dragClone; + this.dragClone = null; + + clone.parentNode.removeChild(clone); + this.eventTracker.remove(clone, 'webkitTransitionEnd'); + this.classList.remove('dragging'); } }; @@ -276,11 +309,25 @@ cr.define('ntp4', function() { }, /** + * Gets/sets the navigation dot element. This is not part of the DOM + * hierarchy for the page (it is a child of the NTP footer). + */ + set navigationDot(dot) { + this.navigationDot_ = dot; + this.eventTracker.add(dot, 'dragenter', + this.onDragEnterDot_.bind(this)); + this.eventTracker.add(dot, 'dragleave', + this.onDragLeaveDot_.bind(this)); + }, + get navigationDot() { + return this.navigationDot_; + }, + + /** * @protected */ appendTile: function(tileElement) { var wrapperDiv = new Tile(tileElement); - wrapperDiv.tilePage = this; this.tileGrid_.appendChild(wrapperDiv); this.positionTile_(this.tileElements_.length - 1); @@ -292,6 +339,15 @@ cr.define('ntp4', function() { }, /** + * Controls whether this page will accept drags that originate from outside + * the page. + * @return {boolean} True if this page accepts drags from outside sources. + */ + acceptOutsideDrags: function() { + return true; + }, + + /** * Makes some calculations for tile layout. These calculations are shared * by |positionTile_| and |getWouldBeIndexforPoint_|. * @return {Object} Assorted layout pixel values. @@ -364,8 +420,9 @@ cr.define('ntp4', function() { // This code calculates whether the tile needs to show a clone of itself // wrapped around the other side of the tile grid. - var offTheRight = col - indexOffset == layout.numRowTiles - 1; - var offTheLeft = col - indexOffset == 0; + var offTheRight = col == layout.numRowTiles || + (col == layout.numRowTiles - 1 && tile.hasDoppleganger()); + var offTheLeft = col == -1 || (col == 0 && tile.hasDoppleganger()); if (this.dragEnters_ > 0 && (offTheRight || offTheLeft)) { var sign = offTheRight ? 1 : -1; tile.showDoppleganger(-layout.numRowTiles * layout.colWidth * sign, @@ -468,8 +525,14 @@ cr.define('ntp4', function() { if (++this.dragEnters_ > 1) return; + // TODO(estade): for now we only allow tile drags. + if (!TilePage.currentlyDraggingTile) + return; + this.classList.add('animating-tile-page'); - this.dragItemIndex_ = TilePage.currentlyDraggingTile.index; + this.withinPageDrag_ = isAncestor(this, TilePage.currentlyDraggingTile); + this.dragItemIndex_ = this.withinPageDrag_ ? + TilePage.currentlyDraggingTile.index : this.tileElements_.length; this.currentDropIndex_ = this.dragItemIndex_; }, @@ -502,7 +565,7 @@ cr.define('ntp4', function() { e.stopPropagation(); var index = this.currentDropIndex_; - if (index == this.dragItemIndex_) + if ((index == this.dragItemIndex_) && this.withinPageDrag_) return; var adjustment = index > this.dragItemIndex_ ? 1 : 0; @@ -529,13 +592,13 @@ cr.define('ntp4', function() { * @private */ cleanUpDrag_: function() { + this.classList.remove('animating-tile-page'); for (var i = 0; i < this.tileElements_.length; i++) { // The current drag tile will be positioned in its dragend handler. if (this.tileElements_[i] == this.currentlyDraggingTile) continue; this.positionTile_(i); } - this.classList.remove('animating-tile-page'); }, /** @@ -563,6 +626,48 @@ cr.define('ntp4', function() { } this.currentDropIndex_ = newDragIndex; }, + + /** + * This is equivalent to dragEnters_, but for drags over the navigation + * dot. + */ + dotDragEnters_: 0, + + /** + * A drag has entered the navigation dot. If the user hovers long enough, + * we will navigate to the relevant page. + * @param {Event} e The MouseOver event for the drag. + */ + onDragEnterDot_: function(e) { + if (++this.dotDragEnters_ > 1) + return; + + if (!TilePage.currentlyDraggingTile) + return; + if (!this.acceptOutsideDrags()) + return; + + var self = this; + function navPageClearTimeout() { + self.navigationDot.showPage(); + self.dotNavTimeout = null; + } + this.dotNavTimeout = window.setTimeout(navPageClearTimeout, 500); + }, + + /** + * The drag has left the navigation dot. + * @param {Event} e The MouseOver event for the drag. + */ + onDragLeaveDot_: function(e) { + if (--this.dotDragEnters_ > 0) + return; + + if (this.dotNavTimeout) { + window.clearTimeout(this.dotNavTimeout); + this.dotNavTimeout = null; + } + }, }; return { |